commit 101266ab72c52cb127e50aa3a7c8ab8444306d66 Author: Justin Marshall Date: Mon Apr 27 10:35:40 2026 -0700 Initial commit. diff --git a/APPFAT.CPP b/APPFAT.CPP new file mode 100644 index 0000000..cb2d4c9 --- /dev/null +++ b/APPFAT.CPP @@ -0,0 +1,785 @@ +//*********************************************************************** +// Assertion System +// +// Copyright (c) 1996 by Blizzard Entertainment. +// All rights reserved. +//*********************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include +#include "storm/h/storm.h" +#include "resource.h" + + +//*********************************************************************** +// Externals +//*********************************************************************** +void cleanup(BOOL bNormalExit); + + +//*********************************************************************** +//*********************************************************************** +/* +void DebugDump2(const char * pszFmt,va_list args) { + static FILE * f = NULL; + if (! f) f = fopen("c:\\hellfr__.dbg","wt"); + if (! f) return; + vfprintf(f,pszFmt,args); + fflush(f); +} +void __cdecl DebugDump(const char * pszFmt, ...) { + va_list args; + va_start(args,pszFmt); + DebugDump2(pszFmt,args); + va_end(args); +} +*/ + + +//*********************************************************************** +// WARNING: the code below ONLY works on x86 compatible systems +//*********************************************************************** +#ifdef _X86_ +#ifndef NDEBUG +static LONG WINAPI BreakExceptionHdlr(struct _EXCEPTION_POINTERS *pep) { + // if we got a breakpoint exception, we expected it -- keep running + PEXCEPTION_RECORD per = pep->ExceptionRecord; + if (per && per->ExceptionCode == EXCEPTION_BREAKPOINT) { + // in windows 95, the int3 instruction will already be + // skipped by the time we get here. In windows NT, the + // Eip will still point to the int3 instruction. Therefore + // look at the offending byte, and if it is int3 (0xcc) then + // skip over the instruction + BYTE * pInst = (BYTE *) pep->ContextRecord->Eip; + if (*pInst == 0xcc) pep->ContextRecord->Eip += 1; + + // continue execution + return EXCEPTION_CONTINUE_EXECUTION; + } + + return EXCEPTION_CONTINUE_SEARCH; +} +#endif +#endif + + +//*********************************************************************** +//*********************************************************************** +void myDebugBreak() { +#ifndef NDEBUG + // -- Save current exception handler and set it + // to a handler which expects a break to occur. + // -- If we are in the debugger, the debugger will + // override our exception handler, and we will + // drop into the debugger. + // -- If there is no debugger present, our exception + // handler will skip over the break instruction + // and allow normal execution of the program + LPTOP_LEVEL_EXCEPTION_FILTER lpLastHdlr; + lpLastHdlr = SetUnhandledExceptionFilter(BreakExceptionHdlr); + + // drop into the debugger + __asm int 3 + + // restore exception handler + SetUnhandledExceptionFilter(lpLastHdlr); +#endif +} + + +//*********************************************************************** +//*********************************************************************** +static void get_ddraw_error(HRESULT ddrval,TCHAR * pszBuf,DWORD dwMaxChars) { + const TCHAR * pszErr; + + // @@ eventually we should get these from our resource file + // so that they can be properly translated and so + // they don't have to stay loaded all the time + + switch (ddrval) { + case DD_OK: + pszErr = "DD_OK"; + break; + case DDERR_ALREADYINITIALIZED: + pszErr = "DDERR_ALREADYINITIALIZED"; + break; + case DDERR_BLTFASTCANTCLIP: + pszErr = "DDERR_BLTFASTCANTCLIP"; + break; + case DDERR_CANNOTATTACHSURFACE: + pszErr = "DDERR_CANNOTATTACHSURFACE"; + break; + case DDERR_CANNOTDETACHSURFACE: + pszErr = "DDERR_CANNOTDETACHSURFACE"; + break; + case DDERR_CANTCREATEDC: + pszErr = "DDERR_CANTCREATEDC"; + break; + case DDERR_CANTDUPLICATE: + pszErr = "DDERR_CANTDUPLICATE"; + break; + case DDERR_CLIPPERISUSINGHWND: + pszErr = "DDERR_CLIPPERISUSINGHWND"; + break; + case DDERR_COLORKEYNOTSET: + pszErr = "DDERR_COLORKEYNOTSET"; + break; + case DDERR_CURRENTLYNOTAVAIL: + pszErr = "DDERR_CURRENTLYNOTAVAIL"; + break; + case DDERR_DIRECTDRAWALREADYCREATED: + pszErr = "DDERR_DIRECTDRAWALREADYCREATED"; + break; + case DDERR_EXCEPTION: + pszErr = "DDERR_EXCEPTION"; + break; + case DDERR_EXCLUSIVEMODEALREADYSET: + pszErr = "DDERR_EXCLUSIVEMODEALREADYSET"; + break; + case DDERR_GENERIC: + pszErr = "DDERR_GENERIC"; + break; + case DDERR_HEIGHTALIGN: + pszErr = "DDERR_HEIGHTALIGN"; + break; + case DDERR_HWNDALREADYSET: + pszErr = "DDERR_HWNDALREADYSET"; + break; + case DDERR_HWNDSUBCLASSED: + pszErr = "DDERR_HWNDSUBCLASSED"; + break; + case DDERR_IMPLICITLYCREATED: + pszErr = "DDERR_IMPLICITLYCREATED"; + break; + case DDERR_INCOMPATIBLEPRIMARY: + pszErr = "DDERR_INCOMPATIBLEPRIMARY"; + break; + case DDERR_INVALIDCAPS: + pszErr = "DDERR_INVALIDCAPS"; + break; + case DDERR_INVALIDCLIPLIST: + pszErr = "DDERR_INVALIDCLIPLIST"; + break; + case DDERR_INVALIDDIRECTDRAWGUID: + pszErr = "DDERR_INVALIDDIRECTDRAWGUID"; + break; + case DDERR_INVALIDMODE: + pszErr = "DDERR_INVALIDMODE"; + break; + case DDERR_INVALIDOBJECT: + pszErr = "DDERR_INVALIDOBJECT"; + break; + case DDERR_INVALIDPARAMS: + pszErr = "DDERR_INVALIDPARAMS"; + break; + case DDERR_INVALIDPIXELFORMAT: + pszErr = "DDERR_INVALIDPIXELFORMAT"; + break; + case DDERR_INVALIDPOSITION: + pszErr = "DDERR_INVALIDPOSITION"; + break; + case DDERR_INVALIDRECT: + pszErr = "DDERR_INVALIDRECT"; + break; + case DDERR_LOCKEDSURFACES: + pszErr = "DDERR_LOCKEDSURFACES"; + break; + case DDERR_NO3D: + pszErr = "DDERR_NO3D"; + break; + case DDERR_NOALPHAHW: + pszErr = "DDERR_NOALPHAHW"; + break; + case DDERR_NOBLTHW: + pszErr = "DDERR_NOBLTHW"; + break; + case DDERR_NOCLIPLIST: + pszErr = "DDERR_NOCLIPLIST"; + break; + case DDERR_NOCLIPPERATTACHED: + pszErr = "DDERR_NOCLIPPERATTACHED"; + break; + case DDERR_NOCOLORCONVHW: + pszErr = "DDERR_NOCOLORCONVHW"; + break; + case DDERR_NOCOLORKEY: + pszErr = "DDERR_NOCOLORKEY"; + break; + case DDERR_NOCOLORKEYHW: + pszErr = "DDERR_NOCOLORKEYHW"; + break; + case DDERR_NOCOOPERATIVELEVELSET: + pszErr = "DDERR_NOCOOPERATIVELEVELSET"; + break; + case DDERR_NODC: + pszErr = "DDERR_NODC"; + break; + case DDERR_NODDROPSHW: + pszErr = "DDERR_NODDROPSHW"; + break; + case DDERR_NODIRECTDRAWHW: + pszErr = "DDERR_NODIRECTDRAWHW"; + break; + case DDERR_NOEMULATION: + pszErr = "DDERR_NOEMULATION"; + break; + case DDERR_NOEXCLUSIVEMODE: + pszErr = "DDERR_NOEXCLUSIVEMODE"; + break; + case DDERR_NOFLIPHW: + pszErr = "DDERR_NOFLIPHW"; + break; + case DDERR_NOGDI: + pszErr = "DDERR_NOGDI"; + break; + case DDERR_NOHWND: + pszErr = "DDERR_NOHWND"; + break; + case DDERR_NOMIRRORHW: + pszErr = "DDERR_NOMIRRORHW"; + break; + case DDERR_NOOVERLAYDEST: + pszErr = "DDERR_NOOVERLAYDEST"; + break; + case DDERR_NOOVERLAYHW: + pszErr = "DDERR_NOOVERLAYHW"; + break; + case DDERR_NOPALETTEATTACHED: + pszErr = "DDERR_NOPALETTEATTACHED"; + break; + case DDERR_NOPALETTEHW: + pszErr = "DDERR_NOPALETTEHW"; + break; + case DDERR_NORASTEROPHW: + pszErr = "DDERR_NORASTEROPHW"; + break; + case DDERR_NOROTATIONHW: + pszErr = "DDERR_NOROTATIONHW"; + break; + case DDERR_NOSTRETCHHW: + pszErr = "DDERR_NOSTRETCHHW"; + break; + case DDERR_NOT4BITCOLOR: + pszErr = "DDERR_NOT4BITCOLOR"; + break; + case DDERR_NOT4BITCOLORINDEX: + pszErr = "DDERR_NOT4BITCOLORINDEX"; + break; + case DDERR_NOT8BITCOLOR: + pszErr = "DDERR_NOT8BITCOLOR"; + break; + case DDERR_NOTAOVERLAYSURFACE: + pszErr = "DDERR_NOTAOVERLAYSURFACE"; + break; + case DDERR_NOTEXTUREHW: + pszErr = "DDERR_NOTEXTUREHW"; + break; + case DDERR_NOTFLIPPABLE: + pszErr = "DDERR_NOTFLIPPABLE"; + break; + case DDERR_NOTFOUND: + pszErr = "DDERR_NOTFOUND"; + break; + case DDERR_NOTLOCKED: + pszErr = "DDERR_NOTLOCKED"; + break; + case DDERR_NOTPALETTIZED: + pszErr = "DDERR_NOTPALETTIZED"; + break; + case DDERR_NOVSYNCHW: + pszErr = "DDERR_NOVSYNCHW"; + break; + case DDERR_NOZBUFFERHW: + pszErr = "DDERR_NOZBUFFERHW"; + break; + case DDERR_NOZOVERLAYHW: + pszErr = "DDERR_NOZOVERLAYHW"; + break; + case DDERR_OUTOFCAPS: + pszErr = "DDERR_OUTOFCAPS"; + break; + case DDERR_OUTOFMEMORY: + pszErr = "DDERR_OUTOFMEMORY"; + break; + case DDERR_OUTOFVIDEOMEMORY: + pszErr = "DDERR_OUTOFVIDEOMEMORY"; + break; + case DDERR_OVERLAYCANTCLIP: + pszErr = "DDERR_OVERLAYCANTCLIP"; + break; + case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: + pszErr = "DDERR_OVERLAYCOLORKEYONLYONEACTIVE"; + break; + case DDERR_OVERLAYNOTVISIBLE: + pszErr = "DDERR_OVERLAYNOTVISIBLE"; + break; + case DDERR_PALETTEBUSY: + pszErr = "DDERR_PALETTEBUSY"; + break; + case DDERR_PRIMARYSURFACEALREADYEXISTS: + pszErr = "DDERR_PRIMARYSURFACEALREADYEXISTS"; + break; + case DDERR_REGIONTOOSMALL: + pszErr = "DDERR_REGIONTOOSMALL"; + break; + case DDERR_SURFACEALREADYATTACHED: + pszErr = "DDERR_SURFACEALREADYATTACHED"; + break; + case DDERR_SURFACEALREADYDEPENDENT: + pszErr = "DDERR_SURFACEALREADYDEPENDENT"; + break; + case DDERR_SURFACEBUSY: + pszErr = "DDERR_SURFACEBUSY"; + break; + case DDERR_SURFACEISOBSCURED: + pszErr = "DDERR_SURFACEISOBSCURED"; + break; + case DDERR_SURFACELOST: + pszErr = "DDERR_SURFACELOST"; + break; + case DDERR_SURFACENOTATTACHED: + pszErr = "DDERR_SURFACENOTATTACHED"; + break; + case DDERR_TOOBIGHEIGHT: + pszErr = "DDERR_TOOBIGHEIGHT"; + break; + case DDERR_TOOBIGSIZE: + pszErr = "DDERR_TOOBIGSIZE"; + break; + case DDERR_TOOBIGWIDTH: + pszErr = "DDERR_TOOBIGWIDTH"; + break; + case DDERR_UNSUPPORTED: + pszErr = "DDERR_UNSUPPORTED"; + break; + case DDERR_UNSUPPORTEDFORMAT: + pszErr = "DDERR_UNSUPPORTEDFORMAT"; + break; + case DDERR_UNSUPPORTEDMASK: + pszErr = "DDERR_UNSUPPORTEDMASK"; + break; + case DDERR_VERTICALBLANKINPROGRESS: + pszErr = "DDERR_VERTICALBLANKINPROGRESS"; + break; + case DDERR_WASSTILLDRAWING: + pszErr = "DDERR_WASSTILLDRAWING"; + break; + case DDERR_WRONGMODE: + pszErr = "DDERR_WRONGMODE"; + break; + case DDERR_XALIGN: + pszErr = "DDERR_XALIGN"; + break; + case DDERR_CANTLOCKSURFACE: + pszErr = "DDERR_CANTLOCKSURFACE"; + break; + case DDERR_CANTPAGELOCK: + pszErr = "DDERR_CANTPAGELOCK"; + break; + case DDERR_CANTPAGEUNLOCK: + pszErr = "DDERR_CANTPAGEUNLOCK"; + break; + case DDERR_DCALREADYCREATED: + pszErr = "DDERR_DCALREADYCREATED"; + break; + case DDERR_INVALIDSURFACETYPE: + pszErr = "DDERR_INVALIDSURFACETYPE"; + break; + case DDERR_NOMIPMAPHW: + pszErr = "DDERR_NOMIPMAPHW"; + break; + case DDERR_NOTPAGELOCKED: + pszErr = "DDERR_NOTPAGELOCKED"; + break; + + default: + const TCHAR szUnknown[] = "DDERR unknown 0x%x"; + app_assert(dwMaxChars >= sizeof(szUnknown) + 10); + sprintf(pszBuf,szUnknown,ddrval); + return; + } + + _tcsncpy(pszBuf,pszErr,dwMaxChars); +} + + +//*********************************************************************** +//*********************************************************************** +static void get_dsound_error(HRESULT dsrval,TCHAR * pszBuf,DWORD dwMaxChars) { + const TCHAR * pszErr; + + // @@ eventually we should get these from our resource file + // so that they can be properly translated and so + // they don't have to stay loaded all the time + + switch(dsrval) { + case DS_OK: + pszErr = "DS_OK"; + break; + case DSERR_ALLOCATED: + pszErr = "DSERR_ALLOCATED"; + break; + case DSERR_ALREADYINITIALIZED: + pszErr = "DSERR_ALREADYINITIALIZED"; + break; + case DSERR_BADFORMAT: + pszErr = "DSERR_BADFORMAT"; + break; + case DSERR_BUFFERLOST: + pszErr = "DSERR_BUFFERLOST"; + break; + case DSERR_CONTROLUNAVAIL: + pszErr = "DSERR_CONTROLUNAVAIL"; + break; + case DSERR_INVALIDCALL: + pszErr = "DSERR_INVALIDCALL"; + break; + case DSERR_INVALIDPARAM: + pszErr = "DSERR_INVALIDPARAM"; + break; + case DSERR_NOAGGREGATION: + pszErr = "DSERR_NOAGGREGATION"; + break; + case DSERR_NODRIVER: + pszErr = "DSERR_NODRIVER"; + break; + case DSERR_OUTOFMEMORY: + pszErr = "DSERR_OUTOFMEMORY"; + break; + case DSERR_PRIOLEVELNEEDED: + pszErr = "DSERR_PRIOLEVELNEEDED"; + break; + case E_NOINTERFACE: + pszErr = "E_NOINTERFACE"; + break; + + default: + const TCHAR szUnknown[] = "DSERR unknown 0x%x"; + app_assert(dwMaxChars >= sizeof(szUnknown) + 10); + sprintf(pszBuf,szUnknown,dsrval); + return; + } + + _tcsncpy(pszBuf,pszErr,dwMaxChars); +} + + +//*********************************************************************** +//*********************************************************************** +// pjw.patch3.start -- changes due to STORM error handling +const TCHAR * strGetError(DWORD dwErr) { + static TCHAR szBuf[256]; + + if (HRESULT_FACILITY(dwErr) == _FACDS) { + get_dsound_error(dwErr,szBuf,sizeof(szBuf) / sizeof(szBuf[0])); + } + else if (HRESULT_FACILITY(dwErr) == _FACDD) { + get_ddraw_error(dwErr,szBuf,sizeof(szBuf) / sizeof(szBuf[0])); + } + else if (SErrGetErrorStr(dwErr,szBuf,sizeof(szBuf) / sizeof(szBuf[0]))) { + // got storm message + } + else if (!FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwErr, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + szBuf, + sizeof(szBuf) / sizeof(szBuf[0]), + NULL + )) { + wsprintf(szBuf,"unknown error 0x%08x",dwErr); + } + + // remove trailing newline crap + int nLen = strlen(szBuf); + char * pszTemp = szBuf + nLen - 1; + while (nLen-- > 0) { + pszTemp--; + if (*pszTemp == '\r' || *pszTemp == '\n') + *pszTemp = 0; + else + break; + } + + return szBuf; +} +// pjw.patch3.end + + +//*********************************************************************** +//*********************************************************************** +const TCHAR * strGetLastError() { + return strGetError(GetLastError()); +} + + +//*********************************************************************** +//*********************************************************************** +static void app_debug_msg(const char * pszFmt,va_list args) { + char szBuf[256]; + wvsprintf(szBuf,pszFmt,args); + + #ifdef _DEBUG + OutputDebugString(szBuf); + OutputDebugString(TEXT("\n")); + #endif + + // turn off "topmost" flag so that we don't stick above debugger + if (ghMainWnd) SetWindowPos(ghMainWnd, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + + + // can't use storm -- it might be dead + MessageBox(ghMainWnd,szBuf,"ERROR",MB_ICONERROR | MB_OK | MB_TASKMODAL); +} + + +//*********************************************************************** +//*********************************************************************** +static void pre_fatal_cleanup() { + // if we fatal from a subsidiary thread, it may kill + // off things which are needed by other threads, so + // if we are already fataling, give the other thread + // some time to die + static BOOL sbInFatal = 0; + static unsigned snThreadID = 0; + if (sbInFatal && snThreadID != GetCurrentThreadId()) + Sleep(20000); + sbInFatal = 1; + snThreadID = GetCurrentThreadId(); + + // kill off direct draw so that dialogs will be visible + void free_directx(); + free_directx(); + + // for multiplayer games, make sure our fatal + // handler doesn't cause other players to timeout + extern BYTE gbMaxPlayers; + if (gbMaxPlayers > 1) { + if (SNetLeaveGame(SNET_EXIT_AUTO_SHUTDOWN)) + Sleep(2000); + } + + // kill off network play + SNetDestroy(); + + // make sure cursor is visible for any dialog box we display + ShowCursor(TRUE); +} + + +//*********************************************************************** +//*********************************************************************** +void __cdecl app_fatal(const char * pszFmt,...) { + pre_fatal_cleanup(); + + // break into debugger + myDebugBreak(); + + if (pszFmt) { + va_list args; + va_start(args,pszFmt); + app_debug_msg(pszFmt,args); + va_end(args); + } + + cleanup(FALSE); + + exit(1); + ExitProcess(1); // just in case +} + + +//*********************************************************************** +//*********************************************************************** +void __cdecl app_warning(const char * pszFmt,...) { + app_assert(pszFmt); + + char szBuf[256]; + va_list args; + va_start(args,pszFmt); + wvsprintf(szBuf,pszFmt,args); + va_end(args); + SDrawMessageBox( + szBuf, + "Hellfire", + MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL + ); +} + + +//*********************************************************************** +//*********************************************************************** +#if EXTENDED_ASSERT +void assert_fail(int nLineNo, const char * pszFile, const char * pszFail) { + app_fatal("assertion failed (%d:%s)\n%s",nLineNo,pszFile,pszFail); +} +#else +void assert_fail(int nLineNo, const char * pszFile) { + app_fatal("assertion failed (%d:%s)",nLineNo,pszFile); +} +#endif + + +//*********************************************************************** +//*********************************************************************** +void ddraw_assert_fail(HRESULT ddrval, int nLineNo, const char * pszFile) { + if (ddrval == DD_OK) return; + app_fatal( + "Direct draw error (%s:%d)\n%s", + pszFile, + nLineNo, + strGetError(ddrval) + ); +} + + +//*********************************************************************** +//*********************************************************************** +void dsound_assert_fail(HRESULT dsrval, int nLineNo, const char * pszFile) { + if (dsrval == DS_OK) return; + app_fatal( + "Direct sound error (%s:%d)\n%s", + pszFile, + nLineNo, + strGetError(dsrval) + ); +} + + +//****************************************************************** +//****************************************************************** +void center_window(HWND hWnd) { + RECT r; + GetWindowRect(hWnd,&r); + int cxWnd = r.right - r.left; + int cyWnd = r.bottom - r.top; + + // get display limits + HDC hdc = GetDC(hWnd); + int cxScreen = GetDeviceCaps(hdc,HORZRES); + int cyScreen = GetDeviceCaps(hdc,VERTRES); + ReleaseDC(hWnd,hdc); + + // Calculate new X position, then adjust for screen + int xNew = (cxScreen - cxWnd) / 2; + if (! SetWindowPos( + hWnd, + NULL, + (cxScreen - cxWnd) / 2, + (cyScreen - cyWnd) / 2, + 0, + 0, + SWP_NOSIZE | SWP_NOZORDER + )) app_fatal("center_window: %s",strGetLastError()); +} + + +//****************************************************************** +//****************************************************************** +static void ErrorDlgInit(HWND hWnd,LPARAM lParam) { + center_window(hWnd); + if (lParam) SetDlgItemText(hWnd,IDC_ERROR_TAG,(LPCTSTR) lParam); +} + + +//****************************************************************** +//****************************************************************** +static BOOL CALLBACK ErrorDlgProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + switch (uMsg) { + case WM_INITDIALOG: + ErrorDlgInit(hWnd,lParam); + break; + + case WM_COMMAND: + if (IDOK == GET_WM_COMMAND_ID(wParam,lParam)) + EndDialog(hWnd,TRUE); + else if (IDCANCEL == GET_WM_COMMAND_ID(wParam,lParam)) + EndDialog(hWnd,FALSE); + break; + + default: + return FALSE; + } + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +void ErrorDlg(int nDlgId,DWORD dwErr,const char * pszFile,int nLine) { + pre_fatal_cleanup(); + char szBuf[512]; + const char * pszTemp = strrchr(pszFile,'\\'); + if (pszTemp) pszFile = pszTemp + 1; + wsprintf(szBuf,"%s\nat: %s line %d",strGetError(dwErr),pszFile,nLine); + + #ifdef _DEBUG + OutputDebugString(szBuf); + OutputDebugString(TEXT("\n")); + #endif + + if (-1 == DialogBoxParam( + ghInst, + MAKEINTRESOURCE(nDlgId), + ghMainWnd, + ErrorDlgProc, + (LPARAM) szBuf + )) app_fatal("ErrDlg: %d",nDlgId); + app_fatal(NULL); +} + + +//****************************************************************** +//****************************************************************** +void FileErrorDlg(const char * pszName) { + pre_fatal_cleanup(); + if (! pszName) pszName = ""; + + if (-1 == DialogBoxParam( + ghInst, + MAKEINTRESOURCE(IDD_FILE_ERR), + ghMainWnd, + ErrorDlgProc, + (LPARAM) pszName + )) app_fatal("FileErrDlg"); + app_fatal(NULL); +} + + +//****************************************************************** +//****************************************************************** +void DiskFreeErrorDlg(const char * pszDir) { + pre_fatal_cleanup(); + if (-1 == DialogBoxParam( + ghInst, + MAKEINTRESOURCE(IDD_DISKFREE_ERR), + ghMainWnd, + ErrorDlgProc, + (LPARAM) pszDir + )) app_fatal("DiskFreeDlg"); + app_fatal(NULL); +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start.1/13/97 +BOOL InsertCDDlg(void) { + ShowCursor(TRUE); + int nResult; + if (-1 == (nResult = DialogBoxParam( + ghInst, + MAKEINTRESOURCE(IDD_CDROM_ERR), + ghMainWnd, + ErrorDlgProc, + (LPARAM) "" + ))) app_fatal("InsertCDDlg"); + ShowCursor(FALSE); + return nResult == IDOK; +} +// pjw.patch1.end.1/13/97 diff --git a/AUTOMAP.CPP b/AUTOMAP.CPP new file mode 100644 index 0000000..1d6c0d5 --- /dev/null +++ b/AUTOMAP.CPP @@ -0,0 +1,839 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Automap file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/AUTOMAP.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "automap.h" +#include "engine.h" +#include "gendung.h" +#include "scrollrt.h" +#include "items.h" +#include "player.h" +#include "control.h" +#include "inv.h" +#include "quests.h" +#include "multi.h" +#include "setmaps.h" + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#define AUTOMAPMAX 200 +#define AUTOMAPMIN 50 +#define AUTOMAPADD 5 +#define AUTOMAPST ((AUTOMAPMAX-AUTOMAPMIN)/AUTOMAPADD)+1 + +#define MAXMEGA MAXTILES/4 + +#define AMDC 144 +#define AMLC 200 +#define AMPC 153 //129 + +#define AMS_DOORL 0x01 +#define AMS_DOORR 0x02 +#define AMS_ARCHL 0x04 +#define AMS_ARCHR 0x08 +#define AMS_GRATEL 0x10 +#define AMS_GRATER 0x20 +#define AMS_DIRT 0x40 +#define AMS_STAIRS 0x80 + +#define AMS_NONEL 0x15 +#define AMS_NONER 0x2a + +#define AMS_DIRT8 0x4000 // AMS_DIRT << 8 + +#define AMS_DIRTLR 0x4007 // Lower right dirt piece + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL automapflag; + +int automapscale; +int automaps1, automaps2, automaps3, automaps4, automaps5; +int automapx, automapy; +int amxadd, amyadd; + +char automapstbl[AUTOMAPST]; + +WORD automaptype[MAXMEGA]; + +BYTE automapview[AUTOMAPX][AUTOMAPY]; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitAutomapOnce() +{ + automapflag = FALSE; + automapscale = AUTOMAPMIN; + automaps1 = (automapscale << 6) / 100; + automaps2 = automaps1 >> 1; + automaps3 = automaps2 >> 1; + automaps4 = automaps3 >> 1; + automaps5 = automaps4 >> 1; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitAutomap() +{ + int i, j, a, v; + DWORD dwTiles; + byte *pAFile, *pTmp; + + a = AUTOMAPMIN; + for (i = 0; i < AUTOMAPST; i++) { + v = (a << 6) / 100; + automapstbl[i] = ((320 / v) << 1) + 1; + if ((320 % v) != 0) automapstbl[i]++; + if ((320 % v) >= ((a << 5) / 100)) automapstbl[i]++; + a += AUTOMAPADD; + } + + ZeroMemory(automaptype,sizeof(automaptype)); + + switch (leveltype) { + case 1: + if (currlevel < CRYPTSTART) + { + pAFile = LoadFileInMemSig("Levels\\L1Data\\L1.AMP",&dwTiles,'AMAP'); + dwTiles /= 2; + } + else + { + pAFile = LoadFileInMemSig("NLevels\\L5Data\\L5.AMP",&dwTiles,'AMAP'); + dwTiles /= 2; + } + + break; + + case 2: + pAFile = LoadFileInMemSig("Levels\\L2Data\\L2.AMP",&dwTiles,'AMAP'); + dwTiles /= 2; + break; + + case 3: + if (currlevel < HIVESTART) + { + pAFile = LoadFileInMemSig("Levels\\L3Data\\L3.AMP",&dwTiles,'AMAP'); + dwTiles /= 2; + } + else + { + pAFile = LoadFileInMemSig("NLevels\\L6Data\\L6.AMP",&dwTiles,'AMAP'); + dwTiles /= 2; + } + + break; + + case 4: + pAFile = LoadFileInMemSig("Levels\\L4Data\\L4.AMP",&dwTiles,'AMAP'); + dwTiles /= 2; + break; + default: + // get out! + return; + } + + pTmp = pAFile; + for (DWORD d = 1; d <= dwTiles; d++) { + byte b1 = *pTmp++; + byte b2 = *pTmp++; + automaptype[d] = b1 + (b2 << 8); + } + + DiabloFreePtr(pAFile); + + // Clear automap vision + ZeroMemory(automapview,sizeof(automapview)); + + // Get rid of any residue prevision calls + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) + dFlags[i][j] &= BFMASK_AUTOMAP; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void StartAutomap() +{ + amxadd = 0; + amyadd = 0; + automapflag = TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AutomapUp() +{ + amxadd--; + amyadd--; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AutomapDown() +{ + amxadd++; + amyadd++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AutomapLeft() +{ + amxadd--; + amyadd++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AutomapRight() +{ + amxadd++; + amyadd--; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AutomapZoomIn() +{ + if (automapscale < AUTOMAPMAX) { + automapscale += AUTOMAPADD; + automaps1 = (automapscale << 6) / 100; + automaps2 = automaps1 >> 1; + automaps3 = automaps2 >> 1; + automaps4 = automaps3 >> 1; + automaps5 = automaps4 >> 1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AutomapZoomOut() +{ + if (automapscale > AUTOMAPMIN) { + automapscale -= AUTOMAPADD; + automaps1 = (automapscale << 6) / 100; + automaps2 = automaps1 >> 1; + automaps3 = automaps2 >> 1; + automaps4 = automaps3 >> 1; + automaps5 = automaps4 >> 1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawAMSquare(int x, int y) +{ + int sx1, sy1, sx2, sy2; + + sx1 = x - automaps2; + sy1 = y - automaps3; + sx2 = sx1 + automaps1; + sy2 = sy1 + automaps2; + + DrawLine(x, sy1, sx1, y, 131); + DrawLine(x, sy1, sx2, y, 131); + DrawLine(x, sy2, sx1, y, 131); + DrawLine(x, sy2, sx2, y, 131); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DrawAMQuarterSquare(int x, int y, int color) +{ + int sx1, sy1, sx2, sy2; + + sx1 = x - (automaps2 / 2); + sy1 = y - (automaps3 / 2); + sx2 = sx1 + (automaps1 / 2); + sy2 = sy1 + (automaps2 / 2); + + DrawLine(x, sy1, sx1, y, color); + DrawLine(x, sy1, sx2, y, color); + DrawLine(x, sy2, sx1, y, color); + DrawLine(x, sy2, sx2, y, color); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawAMShape(int x, int y, WORD shape) +{ + int x1, y1, x2, y2; + BYTE f; + BOOL lwf, rwf, llwf, lrwf; + + //DrawAMSquare(x, y); + + f = (shape >> 8) & 0xff; + + if (f & AMS_DIRT) { + DrawPoint(x, y, AMLC); + DrawPoint(x - automaps4, y - automaps5, AMLC); + DrawPoint(x - automaps4, y + automaps5, AMLC); + DrawPoint(x + automaps4, y - automaps5, AMLC); + DrawPoint(x + automaps4, y + automaps5, AMLC); + DrawPoint(x - automaps3, y, AMLC); + DrawPoint(x + automaps3, y, AMLC); + DrawPoint(x, y - automaps4, AMLC); + DrawPoint(x, y + automaps4, AMLC); + + DrawPoint(x - automaps2 + automaps4, y + automaps5, AMLC); + DrawPoint(x + automaps2 - automaps4, y + automaps5, AMLC); + DrawPoint(x - automaps3, y + automaps4, AMLC); + DrawPoint(x + automaps3, y + automaps4, AMLC); + DrawPoint(x - automaps4, y + automaps3 - automaps5, AMLC); + DrawPoint(x + automaps4, y + automaps3 - automaps5, AMLC); + DrawPoint(x, y + automaps3, AMLC); + } + if (f & AMS_STAIRS) { + DrawLine(x-automaps4, y-automaps4-automaps5, x+automaps3+automaps4, y+automaps5, AMDC); + DrawLine(x-automaps3, y-automaps4, x+automaps3, y+automaps4, AMDC); + DrawLine(x-automaps3-automaps4, y-automaps5, x+automaps4, y+automaps4+automaps5, AMDC); + DrawLine(x-automaps2, y, x, y+automaps3, AMDC); + } + + lwf = FALSE; + rwf = FALSE; + llwf = FALSE; + lrwf = FALSE; + switch(shape & 0xf) { + case 1: + x1 = x - automaps3; // Column + y1 = y - automaps3; + x2 = x1 + automaps2; + y2 = y - automaps4; + DrawLine(x, y1, x1, y2, AMLC); + DrawLine(x, y1, x2, y2, AMLC); + DrawLine(x, y, x1, y2, AMLC); + DrawLine(x, y, x2, y2, AMLC); + break; + case 2: + case 5: + lwf = TRUE; + break; + case 3: + case 6: + rwf = TRUE; + break; + case 4: + lwf = TRUE; + rwf = TRUE; + break; + case 8: + lwf = TRUE; + llwf = TRUE; + break; + case 9: + rwf = TRUE; + lrwf = TRUE; + break; + case 10: + llwf = TRUE; + break; + case 11: + lrwf = TRUE; + break; + case 12: + llwf = TRUE; + lrwf = TRUE; + break; + } + if (lwf) { + if (f & AMS_DOORL) { + x1 = x - automaps2; + x2 = x - automaps3; + y1 = y - automaps3; + y2 = y - automaps4; + DrawLine(x, y1, x-automaps4, y1+automaps5, AMLC); + DrawLine(x1, y, x1+automaps4, y-automaps5, AMLC); + DrawLine(x2, y1, x1, y2, AMDC); + DrawLine(x2, y1, x, y2, AMDC); + DrawLine(x2, y, x1, y2, AMDC); + DrawLine(x2, y, x, y2, AMDC); + } + if (f & AMS_GRATEL) { + DrawLine(x-automaps3, y-automaps4, x-automaps2, y, AMLC); + f |= AMS_ARCHL; // Force arch square + } + if (f & AMS_ARCHL) { + x1 = x - automaps3; + y1 = y - automaps3; + x2 = x1 + automaps2; + y2 = y - automaps4; + DrawLine(x, y1, x1, y2, AMLC); + DrawLine(x, y1, x2, y2, AMLC); + DrawLine(x, y, x1, y2, AMLC); + DrawLine(x, y, x2, y2, AMLC); + } + if ((f & AMS_NONEL) == 0) DrawLine(x, y-automaps3, x-automaps2, y, AMLC); // Left wall + } + if (rwf) { + if (f & AMS_DOORR) { + x1 = x + automaps3; + x2 = x + automaps2; + y1 = y - automaps3; + y2 = y - automaps4; + DrawLine(x, y1, x+automaps4, y1+automaps5, AMLC); + DrawLine(x2, y, x2-automaps4, y-automaps5, AMLC); + DrawLine(x1, y1, x, y2, AMDC); + DrawLine(x1, y1, x2, y2, AMDC); + DrawLine(x1, y, x, y2, AMDC); + DrawLine(x1, y, x2, y2, AMDC); + } + if (f & AMS_GRATER) { + DrawLine(x+automaps3, y-automaps4, x+automaps2, y, AMLC); + f |= AMS_ARCHR; // Force arch square + } + if (f & AMS_ARCHR) { + x1 = x - automaps3; + y1 = y - automaps3; + x2 = x1 + automaps2; + y2 = y - automaps4; + DrawLine(x, y1, x1, y2, AMLC); + DrawLine(x, y1, x2, y2, AMLC); + DrawLine(x, y, x1, y2, AMLC); + DrawLine(x, y, x2, y2, AMLC); + } + if ((f & AMS_NONER) == 0) DrawLine(x, y-automaps3, x+automaps2, y, AMLC); // Right wall + } + if (llwf) { + if (f & AMS_DOORL) { + x1 = x - automaps2; + x2 = x - automaps3; + y1 = y + automaps3; + y2 = y + automaps4; + DrawLine(x, y1, x-automaps4, y1-automaps5, AMLC); + DrawLine(x1, y, x1+automaps4, y+automaps5, AMLC); + DrawLine(x2, y1, x1, y2, AMDC); + DrawLine(x2, y1, x, y2, AMDC); + DrawLine(x2, y, x1, y2, AMDC); + DrawLine(x2, y, x, y2, AMDC); + } else + DrawLine(x, y+automaps3, x-automaps2, y, AMLC); // Lower Left wall + } + if (lrwf) { + if (f & AMS_DOORR) { + x1 = x + automaps3; + x2 = x + automaps2; + y1 = y + automaps3; + y2 = y + automaps4; + DrawLine(x, y1, x+automaps4, y1-automaps5, AMLC); + DrawLine(x2, y, x2-automaps4, y+automaps5, AMLC); + DrawLine(x1, y1, x, y2, AMDC); + DrawLine(x1, y1, x2, y2, AMDC); + DrawLine(x1, y, x, y2, AMDC); + DrawLine(x1, y, x2, y2, AMDC); + } else + DrawLine(x, y+automaps3, x+automaps2, y, AMLC); // Lower Right wall + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawAllObjects() +{ + int px, py; + if (plr[myplr]._pmode == PM_WALK3) { + px = plr[myplr]._pfutx; + py = plr[myplr]._pfuty; + if (plr[myplr]._pdir == DIR_L) px++; + else py++; + } else { + px = plr[myplr]._px; + py = plr[myplr]._py; + } + + int beginx = px - 8; + if (beginx < 0) + beginx = 0; + else if (beginx > MAXDUNX) + beginx = MAXDUNX; + + int beginy = py - 8; + if (beginy < 0) + beginy = 0; + else if (beginy > MAXDUNY) + beginy = MAXDUNY; + + int endx = px + 8; + if (endx < 0) + endx = 0; + else if (endx > MAXDUNX) + endx = MAXDUNX; + + int endy = py + 8; + if (endy < 0) + endy = 0; + else if (endy > MAXDUNY) + endy = MAXDUNY; + + + for (int ix=beginx; ix < endx; ++ix) + { + for (int iy = beginy; iy < endy; ++iy) + { + if (dItem[ix][iy] != 0) + { + int dx = ix - ViewX - (amxadd << 1); + int dy = iy - ViewY - (amyadd << 1); + + int x = 384 + (dx * automaps3) - (dy * automaps3); + int y = 336 + (dx * automaps4) + (dy * automaps4); + + x += ((ScrollInfo._sxoff * automapscale) / 100) >> 1; + y += ((ScrollInfo._syoff * automapscale) / 100) >> 1; + + if (invflag || sbookflag) x -= 160; + if (chrflag || questlog) x += 160; + + y -= automaps4; + + DrawAMQuarterSquare(x,y, 129); + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawAutomapPlr() +{ + int px, py; + int dx, dy; + int x, y; + + if (plr[myplr]._pmode == PM_WALK3) { + px = plr[myplr]._pfutx; + py = plr[myplr]._pfuty; + if (plr[myplr]._pdir == DIR_L) px++; + else py++; + } else { + px = plr[myplr]._px; + py = plr[myplr]._py; + } + + dx = px - ViewX - (amxadd << 1); + dy = py - ViewY - (amyadd << 1); + + x = 384 + (dx * automaps3) - (dy * automaps3); + y = 336 + (dx * automaps4) + (dy * automaps4); + + x += ((plr[myplr]._pxoff * automapscale) / 100) >> 1; + y += ((plr[myplr]._pyoff * automapscale) / 100) >> 1; + + x += ((ScrollInfo._sxoff * automapscale) / 100) >> 1; + y += ((ScrollInfo._syoff * automapscale) / 100) >> 1; + + if (invflag || sbookflag) x -= 160; + if (chrflag || questlog) x += 160; + + y -= automaps4; + + switch (plr[myplr]._pdir) { + case DIR_U: + DrawLine(x, y, x, y-automaps3, AMPC); + DrawLine(x, y-automaps3, x-automaps5, y-automaps4, AMPC); + DrawLine(x, y-automaps3, x+automaps5, y-automaps4, AMPC); + break; + case DIR_UR: + DrawLine(x, y, x+automaps3, y-automaps4, AMPC); + DrawLine(x+automaps3, y-automaps4, x+automaps4, y-automaps4, AMPC); + DrawLine(x+automaps3, y-automaps4, x+automaps4+automaps5, y, AMPC); + break; + case DIR_R: + DrawLine(x, y, x+automaps3, y, AMPC); + DrawLine(x+automaps3, y, x+automaps4, y-automaps5, AMPC); + DrawLine(x+automaps3, y, x+automaps4, y+automaps5, AMPC); + break; + case DIR_DR: + DrawLine(x, y, x+automaps3, y+automaps4, AMPC); + DrawLine(x+automaps3, y+automaps4, x+automaps4+automaps5, y, AMPC); + DrawLine(x+automaps3, y+automaps4, x+automaps4, y+automaps4, AMPC); + break; + case DIR_D: + DrawLine(x, y, x, y+automaps3, AMPC); + DrawLine(x, y+automaps3, x+automaps5, y+automaps4, AMPC); + DrawLine(x, y+automaps3, x-automaps5, y+automaps4, AMPC); + break; + case DIR_DL: + DrawLine(x, y, x-automaps3, y+automaps4, AMPC); + DrawLine(x-automaps3, y+automaps4, x-automaps4-automaps5, y, AMPC); + DrawLine(x-automaps3, y+automaps4, x-automaps4, y+automaps4, AMPC); + break; + case DIR_L: + DrawLine(x, y, x-automaps3, y, AMPC); + DrawLine(x-automaps3, y, x-automaps4, y-automaps5, AMPC); + DrawLine(x-automaps3, y, x-automaps4, y+automaps5, AMPC); + break; + case DIR_UL: + DrawLine(x, y, x-automaps3, y-automaps4, AMPC); + DrawLine(x-automaps3, y-automaps4, x-automaps4, y-automaps4, AMPC); + DrawLine(x-automaps3, y-automaps4, x-automaps4-automaps5, y, AMPC); + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static WORD GetAutomapType(int x, int y, BOOL view) +{ + WORD rv, t; + + if ((view) && (x == -1) && (y >= 0) && (y < AUTOMAPY) && (automapview[0][y])) { + if (GetAutomapType(0, y, FALSE) & AMS_DIRT8) return(0); + else return(0x4000); + } + if ((view) && (y == -1) && (x >= 0) && (x < AUTOMAPX) && (automapview[x][0])) { + if (GetAutomapType(x, 0, FALSE) & AMS_DIRT8) return(0); + else return(0x4000); + } + if ((x < 0) || (x >= AUTOMAPX)) return(0); + if ((y < 0) || (y >= AUTOMAPY)) return(0); + if ((!automapview[x][y]) && (view)) return(0); + rv = automaptype[dungeon[x][y]]; + if (rv == 7) { + t = GetAutomapType(x-1,y,FALSE) >> 8; + if (t & AMS_ARCHR) { + t = GetAutomapType(x,y-1,FALSE) >> 8; + if (t & AMS_ARCHL) rv = 1; + } + } + return(rv); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +void DrawAutomapTest() +{ + int i, j, x, y; + + y = 336; + x = 384 - (automaps1 * 2); + for (i = 1; i < 5; i++) { + DrawAMShape(x, y, 0x0300 + i); + x += automaps1; + } +} +*/ + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void draw_game_info() { + #define LINE_HGT 15 + char szBuf[256]; + int y = 20; + if (gbMaxPlayers > 1) { + strcat(strcpy(szBuf,"game: "),gszGameName); + PrintStringXY(8,y,szBuf,ICOLOR_GOLD); + y += LINE_HGT; + if (gszGamePass[0]) { + strcat(strcpy(szBuf,"password: "),gszGamePass); + PrintStringXY(8,y,szBuf,ICOLOR_GOLD); + y += LINE_HGT; + } + } + + if (setlevel) { + PrintStringXY(8,y,SetLevelName[setlvlnum],ICOLOR_GOLD); + } + else if (currlevel) { + if (currlevel >= HIVESTART && currlevel <= HIVEEND) + sprintf(szBuf, "Level: Nest %i", currlevel - HIVESTART + 1); + else if (currlevel >= CRYPTSTART && currlevel <= CRYPTEND) + sprintf(szBuf, "Level: Crypt %i", currlevel - CRYPTSTART + 1); + else + sprintf(szBuf,"Level: %i", currlevel); + PrintStringXY(8,y,szBuf,ICOLOR_GOLD); + } + #undef LINE_HGT +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawAutomap() +{ + int i, j; + int x, y; + int xs, ys; + int mx, my; + int ams; + WORD s; + + if (leveltype == 0) { + draw_game_info(); + return; + } + + app_assert(gpBuffer); + glClipY = (long) gpBuffer + 393216; // (352 + 160) * 768 + + automapx = (ViewX - DIRTEDGED2) >> 1; + while ((automapx + amxadd) < 0) amxadd++; + while ((automapx + amxadd) >= AUTOMAPX) amxadd--; + automapx += amxadd; + automapy = (ViewY - DIRTEDGED2) >> 1; + while ((automapy + amyadd) < 0) amyadd++; + while ((automapy + amyadd) >= AUTOMAPY) amyadd--; + automapy += amyadd; + + ams = automapstbl[(automapscale - AUTOMAPMIN) / AUTOMAPADD]; + if ((ScrollInfo._sxoff + ScrollInfo._syoff) != 0) ams++; + + mx = automapx - ams; + my = automapy - 1; + if (ams & 1) { + xs = 384 - (automaps1 * ((ams-1) >> 1)); + ys = 336 - (automaps2 * ((ams+1) >> 1)); + } else { + xs = 384 - (automaps1 * (ams >> 1)) + automaps2; + ys = 336 - (automaps2 * (ams >> 1)) - automaps3; + } + if (ViewX & 1) { + xs -= automaps3; + ys -= automaps4; + } + if (ViewY & 1) { + xs += automaps3; + ys -= automaps4; + } + xs += ((ScrollInfo._sxoff * automapscale) / 100) >> 1; + ys += ((ScrollInfo._syoff * automapscale) / 100) >> 1; + + if (invflag || sbookflag) xs -= 160; + if (chrflag || questlog) xs += 160; + + for (j = 0; j <= (ams+1); j++) { + x = xs; + y = ys; + for (i = 0; i < ams; i++) { + s = GetAutomapType(mx+i,my-i,TRUE); + if (s != 0) DrawAMShape(x, y, s); + //else DrawAMSquare(x, y); + x += automaps1; + } + my++; + x = xs - automaps2; + y = ys + automaps3; + for (i = 0; i <= ams; i++) { + s = GetAutomapType(mx+i,my-i,TRUE); + if (s != 0) DrawAMShape(x, y, s); + //else DrawAMSquare(x, y); + x += automaps1; + } + mx++; + ys = ys + automaps2; + } + + DrawAutomapPlr(); + if (HighLightAllItems) + { + DrawAllObjects(); + } + draw_game_info(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetAutomapView(int x, int y) +{ + int xx, yy; + WORD s, d; + + xx = (x - DIRTEDGED2) >> 1; + yy = (y - DIRTEDGED2) >> 1; + if ((xx < 0) || (xx >= AUTOMAPX)) return; + if ((yy < 0) || (yy >= AUTOMAPY)) return; + automapview[xx][yy] = TRUE; + s = GetAutomapType(xx, yy, FALSE); + d = s & AMS_DIRT8; + s = s & 0xf; + switch (s) { + case 2: + if (d) { + if (GetAutomapType(xx, yy+1, FALSE) == AMS_DIRTLR) automapview[xx][yy+1] = TRUE; + } else { + if (GetAutomapType(xx-1, yy, FALSE) & AMS_DIRT8) automapview[xx-1][yy] = TRUE; + } + break; + case 3: + if (d) { + if (GetAutomapType(xx+1, yy, FALSE) == AMS_DIRTLR) automapview[xx+1][yy] = TRUE; + } else { + if (GetAutomapType(xx, yy-1, FALSE) & AMS_DIRT8) automapview[xx][yy-1] = TRUE; + } + break; + case 4: + if (d) { + if (GetAutomapType(xx, yy+1, FALSE) == AMS_DIRTLR) automapview[xx][yy+1] = TRUE; + if (GetAutomapType(xx+1, yy, FALSE) == AMS_DIRTLR) automapview[xx+1][yy] = TRUE; + } else { + if (GetAutomapType(xx-1, yy, FALSE) & AMS_DIRT8) automapview[xx-1][yy] = TRUE; + if (GetAutomapType(xx, yy-1, FALSE) & AMS_DIRT8) automapview[xx][yy-1] = TRUE; + if (GetAutomapType(xx-1, yy-1, FALSE) & AMS_DIRT8) automapview[xx-1][yy-1] = TRUE; + } + break; + case 5: + if (d) { + if (GetAutomapType(xx, yy-1, FALSE) & AMS_DIRT8) automapview[xx][yy-1] = TRUE; + if (GetAutomapType(xx, yy+1, FALSE) == AMS_DIRTLR) automapview[xx][yy+1] = TRUE; + } else { + if (GetAutomapType(xx-1, yy, FALSE) & AMS_DIRT8) automapview[xx-1][yy] = TRUE; + } + break; + case 6: + if (d) { + if (GetAutomapType(xx-1, yy, FALSE) & AMS_DIRT8) automapview[xx-1][yy] = TRUE; + if (GetAutomapType(xx+1, yy, FALSE) == AMS_DIRTLR) automapview[xx+1][yy] = TRUE; + } else { + if (GetAutomapType(xx, yy-1, FALSE) & AMS_DIRT8) automapview[xx][yy-1] = TRUE; + } + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SyncAutomap() +{ + automaps1 = (automapscale << 6) / 100; + automaps2 = automaps1 >> 1; + automaps3 = automaps2 >> 1; + automaps4 = automaps3 >> 1; + automaps5 = automaps4 >> 1; + amxadd = 0; + amyadd = 0; +} diff --git a/AUTOMAP.H b/AUTOMAP.H new file mode 100644 index 0000000..bcabd39 --- /dev/null +++ b/AUTOMAP.H @@ -0,0 +1,41 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/AUTOMAP.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ +#define AUTOMAPX 40 +#define AUTOMAPY 40 + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern BOOL automapflag; +extern BYTE automapview[AUTOMAPX][AUTOMAPY]; +extern int automapscale; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitAutomapOnce(); +void InitAutomap(); +void DrawAutomap(); + +void SetAutomapView(int, int); +void SyncAutomap(); + +void StartAutomap(); +void AutomapUp(); +void AutomapDown(); +void AutomapLeft(); +void AutomapRight(); +void AutomapZoomIn(); +void AutomapZoomOut(); diff --git a/AUTOPLAY.ICO b/AUTOPLAY.ICO new file mode 100644 index 0000000..b66a61e Binary files /dev/null and b/AUTOPLAY.ICO differ diff --git a/BUGS.TXT b/BUGS.TXT new file mode 100644 index 0000000..924bdbe --- /dev/null +++ b/BUGS.TXT @@ -0,0 +1,15 @@ +*) in MonsterStruct the field mArmorClass should be a short instead of a char. + Currently it overflows in HELL mode. + +*) Peril and Devastation can be on Bows but do nothing. Peril should be + removed from bows, Devastation damage should be added to the arrows. + +*) Items of Jester have a 0 to 600% damage, not 0-> to 500% either + change the text or the calculation. + +*) If you drop a weapon then pick it up (For a Barbarian anyway) half your + life pts come back. (Inventory bug) + +*) Doppelganger can clone a golem. (Should be prevented) + +*) Rage go to town, and back and you are in a permant rage. diff --git a/CAPTURE.CPP b/CAPTURE.CPP new file mode 100644 index 0000000..6b16f4b --- /dev/null +++ b/CAPTURE.CPP @@ -0,0 +1,263 @@ +//*************************************************************************** +// capture.c +// created 4.14.95 +// written by Patrick Wyatt +//*************************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include +#include +#include "engine.h" + + +//*************************************************************************** +// externs +//*************************************************************************** +void DrawAndBlit(); + + +//*************************************************************************** +// constants +//*************************************************************************** +#define PCX_HEADER 10 +#define PCX_VERSION 5 +#define PCX_ENCODE 1 + +#define PCX_MAX_REP 63 + +#define PCX_X_PAL 12 +#define PCX_COLORS 16 +#define X_PCX_COLORS 256 + + +//*************************************************************************** +// types +//*************************************************************************** +#pragma pack(push,1) +typedef struct PCXHeader { + BYTE nHeader; // 10 for valid PCX files + BYTE nVersion; // 5 for version 3.0 with palette + BYTE nEncode; // file encoding mode + BYTE nBits; // 8 for 256 color mode + WORD x1; + WORD y1; + WORD x2; + WORD y2; + WORD nScrWid; + WORD nScrHgt; +} PCXHeader; + +typedef struct PCXInfo { + BYTE nMode; // always 0 + BYTE nPlanes; // number of bit planes + WORD nLine; // bytes per line + BYTE unused[60]; // fill out to 128 bytes +} PCXInfo; + +typedef struct TPCX_RGB { + BYTE r; + BYTE g; + BYTE b; +} TPCX_RGB; + +typedef struct TPCX_XPal { + BYTE nPal; + TPCX_RGB rgb[X_PCX_COLORS]; +} TPCX_XPal; + +typedef struct TPCX { + PCXHeader Header; + TPCX_RGB Pal16[PCX_COLORS]; + PCXInfo Info; +} TPCX; +#pragma pack(pop) + + +//*************************************************************************** +//*************************************************************************** +static BOOL pcx_write_header(HANDLE hFile,WORD wWdt,WORD wHgt) { + TPCX pcx; + + ZeroMemory(&pcx,sizeof(pcx)); + + // initialize header + pcx.Header.nHeader = PCX_HEADER; + pcx.Header.nVersion = PCX_VERSION; + pcx.Header.nEncode = PCX_ENCODE; + pcx.Header.nBits = 8; + //pcx.Header.x1 = 0; + //pcx.Header.y1 = 0; + pcx.Header.x2 = wWdt - 1; + pcx.Header.y2 = wHgt - 1; + pcx.Header.nScrWid = wWdt; + pcx.Header.nScrHgt = wHgt; + + //pcx.Info.nMode = 0; + pcx.Info.nPlanes = 1; + pcx.Info.nLine = wWdt; + + DWORD dwBytes; + return WriteFile(hFile,&pcx,sizeof(pcx),&dwBytes,NULL) + && (dwBytes == sizeof(pcx)); +} + + +//*************************************************************************** +//*************************************************************************** +static BOOL pcx_write_pal(HANDLE hFile,const PALETTEENTRY pal[256]) { + // setup extended palette header + TPCX_XPal xpal; + xpal.nPal = PCX_X_PAL; + + // copy palette colors + for (int i = 0; i < X_PCX_COLORS; i++) { + xpal.rgb[i].r = pal[i].peRed; + xpal.rgb[i].g = pal[i].peGreen; + xpal.rgb[i].b = pal[i].peBlue; + } + + // write it + DWORD dwBytes; + return WriteFile(hFile,&xpal,sizeof(xpal),&dwBytes,NULL) + && (dwBytes == sizeof(xpal)); +} + + +//*************************************************************************** +//*************************************************************************** +static BYTE * pcx_compress_line(const BYTE * pSrc,BYTE * pDst,int nWdt) { + BYTE c; + int nCount; + + do { + // get next character + c = *pSrc++; + nCount = 1; + nWdt--; + + // see how long the sequence is + while ((c == *pSrc) && (nCount < PCX_MAX_REP) && nWdt) { + nCount++; + nWdt--; + pSrc++; + } + + // write repeat count (if needed) + if ((nCount > 1) || (c > 0xbf)) { + nCount |= 0xc0; + *pDst++ = (BYTE) nCount; + } + + *pDst++ = c; + } while (nWdt); + + return pDst; +} + + +//*************************************************************************** +//*************************************************************************** +static BOOL pcx_write_image(HANDLE hFile,WORD wDstWdt,WORD wDstHgt,WORD wSrcWdt,const BYTE * pSrc) { + BYTE * pDstEnd; + BYTE * pDstBase; + DWORD dwWrite; + DWORD dwBytes; + + // allocate line buffer -- line cannot be more than 2x larger + pDstBase = (BYTE *) DiabloAllocPtrSig(2 * wDstWdt,'CAPt'); + + while (wDstHgt--) { + pDstEnd = pcx_compress_line(pSrc,pDstBase,wDstWdt); + pSrc += wSrcWdt; + dwWrite = pDstEnd - pDstBase; + if (! WriteFile(hFile,pDstBase,dwWrite,&dwBytes,NULL)) return FALSE; + if (dwBytes != dwWrite) return FALSE; + } + + DiabloFreePtr(pDstBase); + return TRUE; +} + + +//*************************************************************************** +//*************************************************************************** +#define MAX_CAPTURE 100 +#define DIG_OFF 6 +static const char szCAPTURE[] = "screen??.PCX"; +static const char szCAPTUREfmt[] = "screen%02d.PCX"; +static HANDLE open_capture_file(char szFileName[MAX_PATH]) { + int nValue; + BYTE bUsedTbl[MAX_CAPTURE]; + + ZeroMemory(bUsedTbl,sizeof(bUsedTbl)); + struct _finddata_t ffblk; + long lHandle = _findfirst(szCAPTURE,&ffblk); + if (lHandle != -1) { + do { + if (! isdigit(ffblk.name[DIG_OFF+0])) + continue; + if (! isdigit(ffblk.name[DIG_OFF+1])) + continue; + + nValue = (ffblk.name[DIG_OFF + 0] - '0') * 10; + nValue += ffblk.name[DIG_OFF + 1] - '0'; + bUsedTbl[nValue] = 1; + } while (! _findnext(lHandle,&ffblk)); + } + + for (nValue = 0; nValue < MAX_CAPTURE; nValue++) { + if (bUsedTbl[nValue]) continue; + sprintf(szFileName,szCAPTUREfmt,nValue); + return CreateFile(szFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + } + + return INVALID_HANDLE_VALUE; +} + + +//*************************************************************************** +//*************************************************************************** +static void red_palette(const PALETTEENTRY src[256]) { + PALETTEENTRY dst[256]; + for (int i = 0; i < 256; i++) { + dst[i].peRed = src[i].peRed; + dst[i].peGreen = 0; + dst[i].peBlue = 0; + dst[i].peFlags = 0; + } + lpDDPal->SetEntries(0,0,256,dst); +} + + +//*************************************************************************** +//*************************************************************************** +void screen_capture(void) { + HANDLE hFile; + char szFileName[MAX_PATH]; + PALETTEENTRY pal[256]; + + if (INVALID_HANDLE_VALUE == (hFile = open_capture_file(szFileName))) + return; + + // get the current palette, then flash the screen red + DrawAndBlit(); + lpDDPal->GetEntries(0,0,256,pal); + red_palette(pal); + + lock_buf(2); + app_assert(gpBuffer); + BOOL bOK = pcx_write_header(hFile,TOTALX,TOTALY); + if (bOK) bOK = pcx_write_image(hFile,TOTALX,TOTALY,BUFFERX,gpBuffer + 122944); + if (bOK) bOK = pcx_write_pal(hFile,pal); + unlock_buf(2); + + CloseHandle(hFile); + if (! bOK) + DeleteFile(szFileName); + + // restore palette + Sleep(300); + lpDDPal->SetEntries(0,0,256,pal); +} diff --git a/CODEC.CPP b/CODEC.CPP new file mode 100644 index 0000000..ddea8b9 --- /dev/null +++ b/CODEC.CPP @@ -0,0 +1,317 @@ +//****************************************************************** +// codec.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "engine.h" + + +//****************************************************************** +// externs +//****************************************************************** +void DesDestroy (); +void DesEncrypt (int, const void *, void *); +void DesInitialize (int, BOOL, const void *); +void IdeaDestroy (); +void IdeaEncrypt (int, const void *, void *); +void IdeaInitialize (int, BOOL, const void *); +void ShaDestroy (); +void ShaGetLastHash (int, void *); +void ShaHash (int, const void *, void *); +void ShaInitialize (int); + + +//****************************************************************** +// set encryption methods +//****************************************************************** +#define IDEA 0 +#define DES 0 + + +//****************************************************************** +// private +//****************************************************************** +#define BLOCKSIZE 64 +#define VERSION 0 + +typedef struct _appendrec { + DWORD checkvalue; + BYTE version; + BYTE lastblocksize; + WORD reserved; +} appendrec, *appendptr; + +typedef struct _keyrec { + WORD ideakey[3][8]; + BYTE deskey[3][8]; + BYTE shainitvect[64]; +} keyrec, *keyptr; + + +//****************************************************************** +//****************************************************************** +static void DestroyKeys () { + #if DES + DesDestroy(); + #endif + #if IDEA + IdeaDestroy(); + #endif + ShaDestroy(); +} + + +//****************************************************************** +//****************************************************************** +static void InitializeKeys (BOOL encrypt, const char *password) { + keyrec keyset; + + // generate a key + srand(SAVE_GAME_KEY); + BYTE * pb = (BYTE *) &keyset; + for (int i = sizeof(keyset); i--; ) + *pb++ = (BYTE) rand(); + + // HASH THE PASSWORD AND MIX IT WITH THE KEY + { + BYTE originalpassword[64]; + BYTE hashedpassword[20]; + { + int passchar = 0; + for (int loop = 0; loop < 64; ++loop) { + if (!*(password+passchar)) + passchar = 0; + originalpassword[loop] = *(password+passchar++); + } + } + + ShaInitialize(0); + ShaHash(0,originalpassword,hashedpassword); + ShaDestroy(); + + { + LPBYTE keysptr = (LPBYTE)&keyset; + for (int loop = 0; loop < sizeof(keyset); ++loop) + *(keysptr+loop) ^= hashedpassword[loop % 20]; + } + + ZeroMemory(originalpassword, sizeof originalpassword); + ZeroMemory(hashedpassword, sizeof hashedpassword); + } + + // INITIALIZE THE ENCRYPTION ALGORITHMS + for (int loop = 0; loop < 3; ++loop) { + #if DES + DesInitialize(loop,encrypt,keyset.deskey[loop]); + #endif + #if IDEA + IdeaInitialize(loop,encrypt,keyset.ideakey[loop]); + #endif + ShaInitialize(loop); + ShaHash(loop,keyset.shainitvect,NULL); + } + + // WIPE OUT THE LOCAL COPY OF THE KEYS + ZeroMemory(&keyset,sizeof(keyrec)); +} + + +//****************************************************************** +//****************************************************************** +DWORD DecodeFile(BYTE * pbSrcDst,DWORD dwDstBytes,const char * pszPassword) { + app_assert(pbSrcDst); + app_assert(pszPassword); + + // initialize encryption keys + InitializeKeys(0,pszPassword); + + // make sure the length is correct + if (dwDstBytes <= sizeof(appendrec)) return 0; + dwDstBytes -= sizeof(appendrec); + if (dwDstBytes & (BLOCKSIZE-1)) return 0; + DWORD dwBytesLeft = dwDstBytes; + + // DECRYPT THE FILE BLOCK BY BLOCK + BYTE buffer[2][BLOCKSIZE]; + while (dwBytesLeft) { + + // get the next chunk + CopyMemory(&buffer[0][0],pbSrcDst,BLOCKSIZE); + + // DECRYPT THE BLOCK + { + BYTE hash[20]; + ShaGetLastHash(0,hash); + int loop; + + #if IDEA + for (loop = 0; loop < BLOCKSIZE; loop += 8) { + IdeaEncrypt(2,&buffer[0][loop],&buffer[1][loop]); + IdeaEncrypt(1,&buffer[1][loop],&buffer[0][loop]); + IdeaEncrypt(0,&buffer[0][loop],&buffer[1][loop]); + } + for (loop = 0; loop < BLOCKSIZE; loop++) + buffer[0][loop] = buffer[1][loop]-hash[(BLOCKSIZE-(loop+1)) % 20]; + #endif + + #if DES + for (loop = 0; loop < BLOCKSIZE; loop += 8) { + DesEncrypt(2,&buffer[0][loop],&buffer[1][loop]); + DesEncrypt(1,&buffer[1][loop],&buffer[0][loop]); + DesEncrypt(0,&buffer[0][loop],&buffer[1][loop]); + } + for (loop = 0; loop < BLOCKSIZE; loop++) + buffer[0][loop] = hash[loop % 20] ^ buffer[1][loop]; + #endif + + #if ! DES && ! IDEA + for (loop = 0; loop < BLOCKSIZE; loop++) + buffer[0][loop] = hash[loop % 20] ^ buffer[0][loop]; + #endif + + ShaHash(0,buffer[0],NULL); + ZeroMemory(hash,sizeof(hash)); + } + + + // WRITE THE BLOCK + CopyMemory(pbSrcDst,&buffer[0][0],BLOCKSIZE); + + // next block + pbSrcDst += BLOCKSIZE; + dwBytesLeft -= BLOCKSIZE; + } + + // hide buffer contents + ZeroMemory(buffer,sizeof(buffer)); + + // CHECK THE FILE TERMINATION RECORD + const appendrec * append = (const appendrec *) pbSrcDst; + + // CHECK THE ENCRYPTION VERSION + if (append->version > VERSION) + goto error; + + // CONFIRM THAT THE KEY AND PASSWORD WERE VALID + { + BYTE hash[20]; + ShaGetLastHash(0,hash); + if (append->checkvalue != * (LPDWORD) &hash[0]) { + ZeroMemory(hash,20); + goto error; + } + } + + // SET THE EXACT OUTPUT SIZE + dwDstBytes -= BLOCKSIZE - append->lastblocksize; + DestroyKeys(); + return dwDstBytes; + +error: + DestroyKeys(); + return 0; +} + + +//****************************************************************** +// CalcEncodeDstBytes() +// -- calculate the number of bytes required to hold the encoded +// file information including the append record +//****************************************************************** +DWORD CalcEncodeDstBytes(DWORD dwSrcBytes) { + app_assert(dwSrcBytes); + if (dwSrcBytes & (BLOCKSIZE-1)) + dwSrcBytes += BLOCKSIZE - (dwSrcBytes & (BLOCKSIZE-1)); + dwSrcBytes += sizeof(appendrec); + return dwSrcBytes; +} + + +//****************************************************************** +//****************************************************************** +void EncodeFile(BYTE * pbSrcDst,DWORD dwSrcBytes,DWORD dwDstBytes,const char * pszPassword) { + app_assert(pbSrcDst); + app_assert(pszPassword); + + // make sure the user allocated enough bytes for the destination + if (dwDstBytes != CalcEncodeDstBytes(dwSrcBytes)) + app_fatal("Invalid encode parameters"); + + // initialize encryption keys + InitializeKeys(1,pszPassword); + + // ENCRYPT THE FILE BLOCK BY BLOCK + DWORD lastblocksize = 0; + BYTE buffer[2][BLOCKSIZE]; + + while (dwSrcBytes) { + + // get the next src data chunk + DWORD blocksize = min(dwSrcBytes,BLOCKSIZE); + CopyMemory(&buffer[0][0],pbSrcDst,blocksize); + + // blank out any unused portion of the buffer + if (blocksize < BLOCKSIZE) + ZeroMemory(&buffer[0][blocksize],BLOCKSIZE - blocksize); + + // ENCRYPT THE BLOCK + { + BYTE hash[20]; + ShaGetLastHash(0,hash); + ShaHash(0,buffer[0],NULL); + int loop; + + #if ! DES && ! IDEA + for (loop = 0; loop < BLOCKSIZE; loop++) + buffer[0][loop] = hash[loop % 20] ^ buffer[0][loop]; + #endif + + #if DES + for (loop = 0; loop < BLOCKSIZE; loop++) + buffer[1][loop] = hash[loop % 20] ^ buffer[0][loop]; + for (loop = 0; loop < BLOCKSIZE; loop += 8) { + DesEncrypt(0,&buffer[1][loop],&buffer[0][loop]); + DesEncrypt(1,&buffer[0][loop],&buffer[1][loop]); + DesEncrypt(2,&buffer[1][loop],&buffer[0][loop]); + } + #endif + + #if IDEA + for (loop = 0; loop < BLOCKSIZE; loop++) + buffer[1][loop] = buffer[0][loop]+hash[(BLOCKSIZE-(loop+1)) % 20]; + for (loop = 0; loop < BLOCKSIZE; loop += 8) { + IdeaEncrypt(0,&buffer[1][loop],&buffer[0][loop]); + IdeaEncrypt(1,&buffer[0][loop],&buffer[1][loop]); + IdeaEncrypt(2,&buffer[1][loop],&buffer[0][loop]); + } + #endif + + // hide hash info + ZeroMemory(hash,sizeof(hash)); + } + + // write encrypted chunk to destination + CopyMemory(pbSrcDst,&buffer[0][0],BLOCKSIZE); + + // next block + pbSrcDst += BLOCKSIZE; + dwSrcBytes -= blocksize; + lastblocksize = blocksize; + } + + // hide buffer + ZeroMemory(buffer,sizeof(buffer)); + + // APPEND THE TERMINATION RECORD + BYTE hash[20]; + appendrec * append = (appendrec *) pbSrcDst; + ShaGetLastHash(0,hash); + append->checkvalue = * (LPDWORD) &hash[0]; + append->version = VERSION; + append->lastblocksize = (BYTE) lastblocksize; + append->reserved = 0; + + DestroyKeys(); +} diff --git a/CONTROL.CPP b/CONTROL.CPP new file mode 100644 index 0000000..a8a8dd8 --- /dev/null +++ b/CONTROL.CPP @@ -0,0 +1,2949 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Control panel file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/CONTROL.CPP 2 2/05/97 10:41a Dbrevik2 $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "engine.h" +#include "control.h" +#include "gendung.h" +#include "scrollrt.h" +#include "msg.h" + +#include "items.h" +#include "itemdat.h" +#include "player.h" +#include "monster.h" +#include "objects.h" +#include "cursor.h" +#include "spells.h" +#include "missiles.h" + +#include "town.h" +#include "towners.h" +#include "trigs.h" +#include "gamemenu.h" +#include "inv.h" +#include "minitext.h" +#include "lighting.h" +#include "stores.h" +#include "automap.h" +#include "quests.h" + +#include "multi.h" + +#include "error.h" +#include "spelldat.h" + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszRegSig5[REG_LEN] = "REGISTRATION_BLOCK"; + +/*-----------------------------------------------------------------------** +** Local defines +**-----------------------------------------------------------------------*/ + +#define MANABUFFSIZE 7744 // 88x88 +#define LIFEBUFFSIZE 7744 + +#define STRN_GOLD 0 +#define STRN_BLUE 1 +#define STRN_RED 2 +#define STRN_ORANGE 3 +#define STRN_GREY 4 + +// old version was 4/76 +#define NUMSPBKBTNS 5 +#define SPBKBTNWDTH 61 +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ + +BYTE *pBtmBuff; // Offscreen control panel buffer +BYTE *pStatusPanel; +BYTE *pPanelButtons; +BYTE *pPanelText; +BYTE *pManaBuff; +BYTE *pLifeBuff; +BYTE *pChrPanel; +BYTE *pChrButtons; +BYTE *pSpellCels; +BYTE *pGBoxBuff; + +char panelstr[4][64]; +int pstrjust[4]; +BOOL pinfoflag; +int pnumlines; + +char infostr[256]; +char infoclr; + +char tempstr[256]; + +int pentaspin; +int dropGoldValue; +int initialDropGoldValue; +int initialDropGoldIndex; + +const BYTE fonttrans[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 54, 44, 57, 58, 56, 55, 47, 40, 41, 59, 39, 50, 37, 51, 52, // 32-47 + 36, 27, 28, 29, 30, 31, 32, 33, 34, 35, 48, 49, 60, 38, 61, 53, // 48-63 + 62, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 64-79 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 63, 43, 64, 65, // 80-95 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 96-111 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 40, 66, 41, 67, 0 }; // 112-127 + +const BYTE fontkern[68] = { 8, // Space/Invalid + 10, 7, 9, 8, 7, 6, 8, 8, 3, 3, 8, 6, 11, 9, 10, 6, // a-p + 9, 9, 6, 9, 11, 10, 13, 10, 11, 7, // q-z + 5, 7, 7, 8, 7, 7, 7, 7, 7, 10, // 1-0 + 4, 5, 6, 3, 3, 4, 3, 6, 6, 3, 3, 3, 3, 3, 2, 7, 6, 3, 10, 10, 6, // misc + 6, 7, 4, 4, 9, 6, 6, 12, 3, 7 }; // misc + +static const long fontofs[5][5] = { + { 456433, 24576, 24576, 24576, 24756 }, + { 447217, 465649, 24576, 24576, 24576 }, + { 442609, 456433, 470257, 24576, 24576 }, + { 439537, 451057, 461809, 473329, 24576 }, + { 438001, 447217, 456433, 465649, 474097 } }; + +BOOL drawhpflag; +BOOL drawmanaflag; +BOOL chrflag; + +/*-----------------------------------------------------------------------*/ +typedef enum { + SI_INVALID, + SI_FIREBOLT, + SI_HEAL, + SI_LIGHTNING, + SI_FLASH, + SI_IDENTIFY, + SI_FIREWALL, + SI_TOWNPORTAL, + SI_STONECURSE, + SI_INFRAVISION, + SI_HEALOTHER, + SI_NOVA, + SI_FIREBALL, + SI_MANASHIELD, + SI_FLAMEWAVE, + SI_INFERNO, + SI_CHAINLIGHTNING, + SI_JABBERWOCK, // with eyes of flame... + SI_GUARDIAN, + SI_BLOODRITUAL, // unused, looks like Krull + SI_INVISIBILITY, + SI_GOLEM, + SI_ETHEREALIZE, + //SI_BLOODBOIL, // unused + SI_RAGE, // Replaced bloodboil. + SI_TELEPORT, + SI_APOCALYPSE, + SI_REPAIR, + SI_EMPTY, + SI_PHASE, + SI_RECHARGE, + SI_BONESPIRIT, + SI_REDSKULL, // unused + SI_PENTAGRAM, // unused + SI_FIRECLOUD, // unused + SI_LONGHORN, // unused + SI_PENTASTAR, // unused + SI_BLOODSTAR, + SI_DISARM, + SI_ELEMENTAL, + SI_CHARGEDBOLT, + SI_TELEKINESIS, + SI_RESURRECT, + SI_HOLYBOLT, + +#if 1 + // new icons + SI_WARP, + SI_SEARCH, + SI_REFLECT, + SI_LIGHTNINGWALL, + SI_IMMOLATION, + SI_BERSERK, + SI_RINGOFFIRE, + SI_JESTER, + SI_MANA, + + SI_LAST + +#else + // faked icons + SI_WARP = SI_PHASE, + SI_SEARCH = SI_INFRAVISION, + SI_REFLECT = SI_MANASHIELD, + SI_LIGHTNINGWALL = SI_FIREWALL, + SI_IMMOLATION = SI_NOVA, + SI_BERSERK = SI_REDSKULL, + SI_RINGOFFIRE = SI_PENTAGRAM, + SI_MANA = SI_BLOODRITUAL, + SI_JESTER = SI_ETHEREALIZE, + + SI_LAST = SI_HOLYBOLT+1 +#endif +} SPICONTYPE; + +BOOL spselflag = FALSE; +int pSpell, pSplType; +byte SpellTrans[256]; +static char SpellITbl[MAXSPELLS] = { + SI_EMPTY, // Invalid + SI_FIREBOLT, // SPL_FIREBOLT + SI_HEAL, // SPL_HEAL + SI_LIGHTNING, // SPL_LIGHTNING + SI_FLASH, // SPL_FLASH + SI_IDENTIFY, // SPL_IDENTIFY + SI_FIREWALL, // SPL_WALL + SI_TOWNPORTAL, // SPL_TOWN + SI_STONECURSE, // SPL_STONE + SI_INFRAVISION, // SPL_INFRA + SI_PHASE, // SPL_PHASE + SI_MANASHIELD, // SPL_MANASHLD + SI_FIREBALL, // SPL_FIREBALL + SI_GUARDIAN, // SPL_GUARDIAN + SI_CHAINLIGHTNING, // SPL_CHAIN + SI_FLAMEWAVE, // SPL_WAVE + SI_GUARDIAN, // SPL_DOOM + SI_BLOODRITUAL, // SPL_BLOODR + SI_NOVA, // SPL_NOVA + SI_INVISIBILITY, // SPL_INVIS + SI_INFERNO, // SPL_FLAME + SI_GOLEM, // SPL_GOLEM + //SI_BLOODBOIL, // SPL_BLOODB + SI_RAGE, // SPL_RAGE + SI_TELEPORT, // SPL_TELE + SI_APOCALYPSE, // SPL_APOCA + SI_ETHEREALIZE, // SPL_ETHER + SI_REPAIR, // SPL_REPAIR + SI_RECHARGE, // SPL_RECHARGE + SI_DISARM, // SPL_DISARM + SI_ELEMENTAL, // SPL_ELEMENT + SI_CHARGEDBOLT, // SPL_CBOLT + SI_HOLYBOLT, // SPL_HBOLT + SI_RESURRECT, // SPL_RESURRECT + SI_TELEKINESIS, // SPL_TELEKINESIS + SI_HEALOTHER, // SPL_HEALOTHER + SI_BLOODSTAR, // SPL_BSTAR + SI_BONESPIRIT, // SPL_BONESPIRT + SI_MANA, // SPL_MANA + SI_MANA, // SPL_FMANA + SI_JESTER, // SPL_RANDOM + SI_LIGHTNINGWALL, // SPL_LTWALL + SI_IMMOLATION, // SPL_IMMOLATION + SI_WARP, // SPL_TELESTAIRS + SI_REFLECT, // SPL_REFLECT + SI_BERSERK, // SPL_BERSERK + SI_RINGOFFIRE, // SPL_RINGOFFIRE + SI_SEARCH, // SPL_SHOWMAGITEMS + SI_PENTASTAR, // SPL_RUNEOFFIRE + SI_PENTASTAR, // SPL_RUNEOFLIGHT + SI_PENTASTAR, // SPL_RUNEOFNOVA + SI_PENTASTAR, // SPL_RUNEOFIMMOLATION + SI_PENTASTAR, // SPL_RUNEOFSTONE + +#if defined (HELLFIRE2) + SI_RINGOFFIRE, // SPL_RINGOFLIGHT + SI_REDSKULL, // SPL_AURA + SI_ETHERALIZE, // SPL_SPIRALFIREBALL +#endif + }; + +/*-----------------------------------------------------------------------*/ + +#define NUMPBTNS 8 +#define SINGLE_PBTNS 6 +#define MULTI_PBTNS NUMPBTNS + +#define PBTN_CHR 0 +#define PBTN_TPLR1 0 +#define PBTN_QUEST 1 +#define PBTN_AMAP 2 +#define PBTN_TPLR2 2 +#define PBTN_MENU 3 +#define PBTN_INV 4 +#define PBTN_TPLR3 4 +#define PBTN_SBOOK 5 +#define PBTN_TALK 6 +#define PBTN_ATTACK 7 + +// x1, y1, width, height, talk pushable +int PanBtnPos[NUMPBTNS][5] = { + { 9, 361, 71, 19, TRUE }, + { 9, 387, 71, 19, FALSE }, + { 9, 427, 71, 19, TRUE }, + { 9, 453, 71, 19, FALSE }, + { 560, 361, 71, 19, TRUE }, + { 560, 387, 71, 19, FALSE }, + { 87, 443, 33, 32, TRUE }, + { 527, 443, 33, 32, TRUE }, +}; + +char *PanBtnHotKey[NUMPBTNS] = { + "'c'", + "'q'", + "Tab", + "Esc", + "'i'", + "'b'", + "Enter", + NULL }; + +char *PanBtnStr[NUMPBTNS] = { + "Character Information", + "Quests log", + "Automap", + "Main Menu", + "Inventory", + "Spell book", + "Send Message", + "Player Attack" }; + +BOOL panbtn[NUMPBTNS]; +BOOL drawbtnflag, panbtndown; +BOOL panelflag; // panel info draw +int numpanbtns; + +BYTE *pDurIcons; + +BOOL drawdurflag; +BOOL dropGoldFlag; + +/*-----------------------------------------------------------------------*/ + +#define NUMCBTNS 4 + +#define CBTN_STR 0 +#define CBTN_MAG 1 +#define CBTN_DEX 2 +#define CBTN_VIT 3 + +// x1, y1, width, height +int ChrBtnPos[NUMCBTNS][4] = { + { 137, 138, 41, 22 }, + { 137, 166, 41, 22 }, + { 137, 195, 41, 22 }, + { 137, 223, 41, 22 } }; + +BOOL chrbtn[NUMCBTNS]; +BOOL chrbtndown; + +/*-----------------------------------------------------------------------*/ + +BOOL lvlbtndown; + +/*-----------------------------------------------------------------------*/ + +BYTE *pSpellBkCel; +BYTE *pSBkBtnCel; +BYTE *pSBkIconCels; + +int sbooktab; +BOOL sbookflag; + +// The first entry will be filled during init with the player types skill +int SpellPages[6][7] = { + { 0, SPL_FIREBOLT, SPL_CBOLT, SPL_HBOLT, SPL_HEAL, SPL_HEALOTHER, SPL_FLAME }, + { SPL_RESURRECT, SPL_WALL, SPL_TELEKINESIS, SPL_LIGHTNING, SPL_TOWN, SPL_FLASH, SPL_STONE }, + { SPL_PHASE, SPL_MANASHLD, SPL_ELEMENT, SPL_FIREBALL, SPL_WAVE, SPL_CHAIN, SPL_GUARDIAN}, + { SPL_NOVA, SPL_GOLEM, SPL_TELE, SPL_APOCA, SPL_BONESPIRIT, SPL_BSTAR, SPL_ETHER }, + { SPL_LTWALL, SPL_IMMOLATION, SPL_TELESTAIRS, SPL_REFLECT, SPL_BERSERK, SPL_RINGOFFIRE, SPL_SHOWMAGITEMS }, +#if defined (HELLFIRE2) + { SPL_RINGOFLIGHT, SPL_AURA, SPL_SPIRALFIREBALL, -1, -1, -1, -1 } +#else + { -1, -1, -1, -1, -1, -1, -1 } +#endif +}; + +/*-----------------------------------------------------------------------*/ +#define MAX_TALK_SAVES 8 // must be pow2 +BOOL talkflag; +static int tspin; +static long talkofs; +static char sgszTalkMsg[MAX_SEND_STR_LEN]; +static BYTE sgbTalkSavePos; +static BYTE sgbNextTalkSave; +static char sgszTalkSaveMsg[MAX_TALK_SAVES][MAX_SEND_STR_LEN]; +static BYTE sgbPlrTalkTbl[MAX_PLRS]; +static BYTE *pTalkPanel; +static BYTE *pMultiBtns; +static BYTE *pTalkBtns; +static BOOL talkbtndown[3]; + +void TalkStart(); +void TalkEnd(); +void PlrStringXY(int x1, int y, int x2,const char * pszStr,char col); + + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void SetPlrHandItem(ItemStruct *h, int idata); +void GetPlrHandSeed(ItemStruct *h); +void GetGoldSeed(int pnum, ItemStruct *h); +void SetSpellTrans(char); + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawSpellCel(long xp, long yp, BYTE *pCels, long nCel, long w) +{ + BYTE *pTo; + byte *ttbl; + long RLELen; + + ttbl = &SpellTrans[0]; + app_assert(gpBuffer); + pTo = gpBuffer + nBuffWTbl[yp] + xp; + __asm { + mov ebx,dword ptr [pCels] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + + mov esi,dword ptr [pCels] // Source + add esi,dword ptr [ebx] + + mov edi,dword ptr [pTo] // Dest + + mov eax,dword ptr [RLELen] + add eax,esi + mov dword ptr [RLELen],eax + + mov ebx,dword ptr [ttbl] + +_T1Lp1: mov edx,dword ptr [w] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + mov ecx,eax + shr ecx,1 + jnc _T1w + lodsb + xlatb + stosb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T1x +_T1Lp3: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T1Lp3 +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,768 + sub edi,dword ptr [w] + cmp esi,dword ptr [RLELen] + jnz _T1Lp1 + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetSpellTrans(char t) +{ + int i; + + if (t == STRN_GOLD) { + for (i = 0; i < 128; i++) SpellTrans[i] = i; + } + for (i = 128; i < 256; i++) SpellTrans[i] = i; + SpellTrans[255] = 0; + + switch (t) { + case STRN_BLUE : + SpellTrans[144] = 177; + SpellTrans[145] = 179; + SpellTrans[146] = 181; + for (i = 176; i < 192; i++) { + SpellTrans[i - 16] = i; // 160-175 + SpellTrans[i + 16] = i; // 192-207 + SpellTrans[i + 32] = i; // 208-223 + } + break; + case STRN_ORANGE : + SpellTrans[144] = 209; + SpellTrans[145] = 211; + SpellTrans[146] = 213; + for (i = 208; i < 224; i++) { + SpellTrans[i - 48] = i; // 160-175 + SpellTrans[i - 16] = i; // 192-207 + } + break; + case STRN_RED : + SpellTrans[144] = 161; + SpellTrans[145] = 163; + SpellTrans[146] = 165; + for (i = 160; i < 176; i++) { + SpellTrans[i + 32] = i; // 192-207 + SpellTrans[i + 48] = i; // 208-223 + } + break; + case STRN_GREY : + SpellTrans[144] = 241; + SpellTrans[145] = 243; + SpellTrans[146] = 245; + for (i = 240; i < 255; i++) { + SpellTrans[i - 80] = i; // 160-174 + SpellTrans[i - 48] = i; // 192-206 + SpellTrans[i - 32] = i; // 208-222 + } + SpellTrans[175] = 0; + SpellTrans[207] = 0; + SpellTrans[223] = 0; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawSpellIcon() { + char t, sn; + int sl; + + t = plr[myplr]._pRSplType; + sn = plr[myplr]._pRSpell; + sl = plr[myplr]._pSplLvl[sn] + plr[myplr]._pISplLvlAdd; + if ((t == SPT_MEMORIZED) && (sn != -1)) { + if (!CheckSpell(myplr, sn, t, TRUE)) t = STRN_GREY; + if (sl <= 0 ) t = STRN_GREY; + } + + if ((currlevel == 0) && (t != STRN_GREY) && (spelldata[sn].sTownSpell == FALSE)) t = STRN_GREY; + if (plr[myplr]._pRSpell < 0) t = STRN_GREY; + SetSpellTrans(t); + if (sn != -1) DrawSpellCel(629, 631, pSpellCels, SpellITbl[sn], 56); + else DrawSpellCel(629, 631, pSpellCels, 27, 56); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#define SPLICONSIZE 56 +#define SPLICONRIGHT 636 // (640 - (trunc(640 / 56) * 56)) / 2) + 640 + 64 - SPLICONSIZE +#define SPLICONLEFT 20 // SPLICONRIGHT - (trunc(640 / 56) * 56) - SPLICONSIZE + +#define SPELLICON_BLANK SI_LAST +#define SPELLICON_F5 (SI_LAST + 5) + +void DrawSpellList() +{ + int mx,my,x,y,i,j,t; + __int64 mask,spl; + int s,c,hk; + int v, selbox; + + x = SPLICONRIGHT; + y = 495; + + pSpell = -1; + infostr[0] = 0; + ClearPanel(); + for (j = 0; j < 4; j++) { + switch(j) { + case 0: + SetSpellTrans(STRN_GOLD); + spl = plr[myplr]._pAblSpells; + selbox = SPELLICON_BLANK + 3; + break; + case 1: + spl = plr[myplr]._pMemSpells; + selbox = SPELLICON_BLANK + 4; + break; + case 2: + SetSpellTrans(STRN_RED); + spl = plr[myplr]._pScrlSpells; + selbox = SPELLICON_BLANK + 1; + break; + case 3: + SetSpellTrans(STRN_ORANGE); + spl = plr[myplr]._pISpells; + selbox = SPELLICON_BLANK + 2; + break; + } + mask = 1; + for (i = 1; i < SPL_LAST; i++) { + if ((spl & mask) != 0) + { + if (j == 1) { + v = plr[myplr]._pSplLvl[i] + plr[myplr]._pISplLvlAdd; + if ( v < 0 ) v = 0; + if (v > 0) t = STRN_BLUE; + else t = STRN_GREY; + SetSpellTrans(t); + } + + if ((currlevel == 0) && (spelldata[i].sTownSpell == FALSE)) SetSpellTrans(STRN_GREY); + + DrawSpellCel(x, y, pSpellCels, SpellITbl[i], SPLICONSIZE); + mx = x - 64; + my = y - (160 + SPLICONSIZE); + if ((MouseX >= mx) && (MouseX < (mx+SPLICONSIZE)) && (MouseY >= my) && (MouseY < (my+SPLICONSIZE))) { + pSpell = i; + pSplType = j; + if (plr[myplr]._pClass == CLASS_MONK && i == SPL_SHOWMAGITEMS) + pSplType = 0; + DrawSpellCel(x, y, pSpellCels, selbox, SPLICONSIZE); + switch (pSplType) { + case 0: + sprintf(infostr, "%s Skill", spelldata[pSpell].sSkillText); + break; + case 1: + sprintf(infostr, "%s Spell", spelldata[pSpell].sNameText); + if (pSpell == SPL_HBOLT) { + sprintf(tempstr, "Damages undead only"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (v == 0) sprintf(tempstr, "Spell Level 0 - Unusable"); + else sprintf(tempstr, "Spell Level %i", v); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 2: + sprintf(infostr, "Scroll of %s", spelldata[pSpell].sNameText); + c = 0; + for (s = 0; s < plr[myplr]._pNumInv; s++) { + if ((plr[myplr].InvList[s]._itype != -1) && + ((plr[myplr].InvList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].InvList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].InvList[s]._iSpell == pSpell) c++; + } + } + for (s = 0; s < MAXSPD; s++) { + if ((plr[myplr].SpdList[s]._itype != -1) && + ((plr[myplr].SpdList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].SpdList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].SpdList[s]._iSpell == pSpell) c++; + } + } + if (c == 1) strcpy(tempstr, "1 Scroll"); + else sprintf(tempstr, "%i Scrolls", c); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 3: + sprintf(infostr, "Staff of %s", spelldata[pSpell].sNameText); + if (plr[myplr].Hand1Item._iCharges == 1) strcpy(tempstr, "1 Charge"); + else sprintf(tempstr, "%i Charges", plr[myplr].Hand1Item._iCharges); + AddPanelString(tempstr, TEXT_CENTER); + break; + } + for (hk = 0; hk < 4; hk++) { + if ((plr[myplr]._pSplHotKey[hk] == pSpell) && (plr[myplr]._pSplTHotKey[hk] == pSplType)) { + DrawSpellCel(x, y, pSpellCels, SPELLICON_F5+hk, SPLICONSIZE); + sprintf(tempstr, "Spell Hot Key #F%i", hk+5); + AddPanelString(tempstr, TEXT_CENTER); + } + } + } + x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } + mask = mask << 1; + } + if (spl && (x != SPLICONRIGHT)) x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void SetSpell() +{ + spselflag = FALSE; + if (pSpell != -1) { + ClearPanel(); + plr[myplr]._pRSpell = pSpell; + plr[myplr]._pRSplType = pSplType; + force_redraw = FULLDRAW; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetSpellHK(int hk) +{ + if (pSpell != -1) { + for (int i = 0; i < 4; i++) { + if ((plr[myplr]._pSplHotKey[i] == pSpell) && (plr[myplr]._pSplTHotKey[i] == pSplType)) + plr[myplr]._pSplHotKey[i] = -1; + } + plr[myplr]._pSplHotKey[hk] = pSpell; + plr[myplr]._pSplTHotKey[hk] = pSplType; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void GetSpellHK(int hk) +{ + __int64 spl; + + if (plr[myplr]._pSplHotKey[hk] == -1) return; + + switch(plr[myplr]._pSplTHotKey[hk]) { + case 0: + spl = plr[myplr]._pAblSpells; + break; + case 1: + spl = plr[myplr]._pMemSpells; + break; + case 2: + spl = plr[myplr]._pScrlSpells; + break; + case 3: + spl = plr[myplr]._pISpells; + break; + } + spl &= (((__int64)1) << (plr[myplr]._pSplHotKey[hk]-1)); + if (spl) { + plr[myplr]._pRSpell = plr[myplr]._pSplHotKey[hk]; + plr[myplr]._pRSplType = plr[myplr]._pSplTHotKey[hk]; + force_redraw = FULLDRAW; + } +} + +/*-----------------------------------------------------------------------** +** Draws a small font letter +**-----------------------------------------------------------------------*/ + +void DrawPanelFont (long poffset, long nCel, char clr) +{ + app_assert(gpBuffer); + __asm { + mov ebx,dword ptr [pPanelText] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + + mov edx,dword ptr [ebx+4] // Length + sub edx,dword ptr [ebx] + + mov esi,dword ptr [pPanelText] // Source + add esi,dword ptr [ebx] + + mov edi,dword ptr [gpBuffer] // Dest + add edi,dword ptr [poffset] + + mov ebx,edx + add ebx,esi + + xor edx,edx + mov dl,byte ptr [clr] + cmp edx,ICOLOR_WHITE + jz _T1Lp1 // Normal / White + cmp edx,ICOLOR_BLUE + jz _T2Lp1 // Blue + cmp edx,ICOLOR_RED + jz _T3Lp1 // Red + jmp _T4Lp1 // Gold + +/*- White ---------------------------------------------------------------*/ + +_T1Lp1: mov edx,13 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax // Draw + mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,781 + cmp ebx,esi + jnz _T1Lp1 + jmp _Done + +/*- Blue ----------------------------------------------------------------*/ + +_T2Lp1: mov edx,13 + +_T2Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T2J + + sub edx,eax // Draw + mov ecx,eax +_T2Lp3: lodsb + cmp al,253 + ja _T2F + cmp al,240 + jb _T2Sv + sub al,62 + jmp _T2Sv +_T2F: mov al,191 +_T2Sv: stosb + loop _T2Lp3 + or edx,edx + jz _T2Nxt + jmp _T2Lp2 + +_T2J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T2Lp2 +_T2Nxt: sub edi,781 + cmp ebx,esi + jnz _T2Lp1 + jmp _Done + +/*- Red -----------------------------------------------------------------*/ + +_T3Lp1: mov edx,13 + +_T3Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T3J + + sub edx,eax // Draw + mov ecx,eax +_T3Lp3: lodsb + cmp al,240 + jb _T3Sv + sub al,16 +_T3Sv: stosb + loop _T3Lp3 + or edx,edx + jz _T3Nxt + jmp _T3Lp2 + +_T3J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T3Lp2 +_T3Nxt: sub edi,781 + cmp ebx,esi + jnz _T3Lp1 + jmp _Done + +/*- Gold ----------------------------------------------------------------*/ + +_T4Lp1: mov edx,13 + +_T4Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T4J + + sub edx,eax // Draw + mov ecx,eax +_T4Lp3: lodsb + cmp al,240 + jb _T4Sv + cmp al,254 + jae _T4val + sub al,46 + jmp _T4Sv +_T4val: mov al,207 +_T4Sv: stosb + loop _T4Lp3 + or edx,edx + jz _T4Nxt + jmp _T4Lp2 + +_T4J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T4Lp2 +_T4Nxt: sub edi,781 + cmp ebx,esi + jnz _T4Lp1 + +/*-----------------------------------------------------------------------*/ + +_Done: + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddPanelString(const char * str, int just) +{ + strcpy(panelstr[pnumlines],str); + pstrjust[pnumlines] = just; + if (pnumlines < 4) pnumlines++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ClearPanel() +{ + pnumlines = 0; + pinfoflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CopyCtrlPan(int sx, int sy, int deltax, int deltay, int dx, int dy) +{ + long src, dest; + + app_assert(gpBuffer); + src = (sy * 640) + sx; + dest = (dy * 768) + dx; + __asm { + mov esi,dword ptr [pBtmBuff] + add esi,dword ptr [src] + mov edi,dword ptr [gpBuffer] + add edi,dword ptr [dest] + + xor ebx,ebx + mov bx,word ptr [deltax] + xor edx,edx + mov dx,word ptr [deltay] +_CLp: mov ecx,ebx + shr ecx,1 + jnc _Tw + movsb + jecxz _Tx +_Tw: shr ecx,1 + jnc _TLp + movsw + jecxz _Tx +_TLp: rep movsd +_Tx: add esi,640 + sub esi,ebx + add edi,768 + sub edi,ebx + dec edx + jnz _CLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitPanelStr() +{ + ClearPanel(); + //AddPanelString("Welcome to Diablo", TEXT_CENTER); // This was ok (pre Demo) now its not + //AddPanelString("Press F1 for help", TEXT_CENTER); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void BuffCopy(BYTE *pSrc, int y1, int y2, int dx, int dy) +{ + long srco, desto, deltay; + + app_assert(gpBuffer); + srco = y1 * 88; + desto = (dy * 768) + dx; + deltay = y2 - y1; + __asm { + mov esi,dword ptr [pSrc] + add esi,dword ptr [srco] + mov edi,dword ptr [gpBuffer] + add edi,dword ptr [desto] + + mov edx,dword ptr [deltay] +_YLp: mov ecx,22 + rep movsd + add edi,680 + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TransBuffCopy(BYTE *pSrc, long srcwidth, long srcoff, BYTE *pDest, long destoff, long dy) +{ + __asm { + mov esi,dword ptr [pSrc] + add esi,dword ptr [srcoff] + mov edi,dword ptr [pDest] + add edi,dword ptr [destoff] + + mov edx,dword ptr [dy] +_YLp: mov ecx,59 +_XLp: lodsb + or al,al + jz _Skip + mov byte ptr [edi],al +_Skip: inc edi + loop _XLp + add esi,dword ptr [srcwidth] + sub esi,59 + add edi,709 + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawHealthTop() +{ + double v; + int dv; + + if (plr[myplr]._pMaxHP <= 0) + v = 0.0; + else + v = ((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP) * 80; + dv = (int)v; + plr[myplr]._pHPPer = dv; + + + long dy; + + dy = 80 - plr[myplr]._pHPPer; + if (dy > 11) dy = 11; + dy += 2; + + app_assert(gpBuffer); + TransBuffCopy(pLifeBuff, 88, 277, gpBuffer, 383405, dy); + if (dy != 13) TransBuffCopy(pBtmBuff, 640, (dy * 640) + 2029, gpBuffer, (dy * 768) + 383405, 13 - dy); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawHealthBar() +{ + double v; + int dv; + + if (plr[myplr]._pMaxHP <= 0) + v = 0.0; + else + v = ((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP) * 80; + dv = (int)v; + plr[myplr]._pHPPer = dv; + + if (dv > 69) dv = 69; + if (dv != 69) BuffCopy(pLifeBuff, 16, 85-dv, 160, 512); + if (dv != 0) CopyCtrlPan(96, 85-dv, 88, dv, 160, 581-dv); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawManaTop() +{ + long dy; + + dy = 80 - plr[myplr]._pManaPer; + if (dy > 11) dy = 11; + dy += 2; + + app_assert(gpBuffer); + TransBuffCopy(pManaBuff, 88, 277, gpBuffer, 383771, dy); + if (dy != 13) TransBuffCopy(pBtmBuff, 640, (dy * 640) + 2395, gpBuffer, (dy * 768) + 383771, 13 - dy); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CalcInitBallPer() +{ + double v; + int dv; + long m,mm; + + mm = plr[myplr]._pMaxMana; + m = plr[myplr]._pMana; + if (mm < 0) mm = 0; + if (m < 0) m = 0; + if (mm == 0) dv = 0; + else { + v = ((double)m / (double)mm) * 80; + dv = (int)v; + } + plr[myplr]._pManaPer = dv; + v = ((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP) * 80; + dv = (int)v; + plr[myplr]._pHPPer = dv; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawManaBar() +{ + double v; + int dv; + long m,mm; + + mm = plr[myplr]._pMaxMana; + m = plr[myplr]._pMana; + if (mm < 0) mm = 0; + if (m < 0) m = 0; + if (mm == 0) dv = 0; + else { + v = ((double)m / (double)mm) * 80; + dv = (int)v; + } + plr[myplr]._pManaPer = dv; + + if (dv > 69) dv = 69; + if (dv != 69) BuffCopy(pManaBuff, 16, 85-dv, 528, 512); + if (dv != 0) CopyCtrlPan(464, 85-dv, 88, dv, 528, 581-dv); + + DrawSpellIcon(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitControlPan() +{ + int i; + + app_assert(! pBtmBuff); + if (gbMaxPlayers == 1) { + pBtmBuff = DiabloAllocPtrSig(BTMBUFFSIZE,'CTRL'); + ZeroMemory(pBtmBuff,BTMBUFFSIZE); + } else { + pBtmBuff = DiabloAllocPtrSig(BTMBUFFMULTISIZE,'CTRL'); + ZeroMemory(pBtmBuff,BTMBUFFMULTISIZE); + } + pManaBuff = DiabloAllocPtrSig(MANABUFFSIZE,'CTRL'); + ZeroMemory(pManaBuff,MANABUFFSIZE); + pLifeBuff = DiabloAllocPtrSig(LIFEBUFFSIZE,'CTRL'); + ZeroMemory(pLifeBuff,LIFEBUFFSIZE); + pPanelText = LoadFileInMemSig("CtrlPan\\SmalText.CEL",NULL,'CTRL'); + pChrPanel = LoadFileInMemSig("Data\\Char.CEL",NULL,'CTRL'); + pSpellCels = LoadFileInMemSig("Data\\SpelIcon.CEL",NULL,'CTRL'); // was in CtrlPan + SetSpellTrans(STRN_GOLD); + + // Init Control panel offscreen buffer + pStatusPanel = LoadFileInMemSig("CtrlPan\\Panel8.CEL",NULL,'CTRL'); + DrawBuffCel(pBtmBuff, 0, 143, BTMBUFFX, pStatusPanel, 1, 640); + DiabloFreePtr (pStatusPanel); + pStatusPanel = LoadFileInMemSig("CtrlPan\\P8Bulbs.CEL",NULL,'CTRL'); + DrawBuffCel(pLifeBuff, 0, 87, 88, pStatusPanel, 1, 88); + DrawBuffCel(pManaBuff, 0, 87, 88, pStatusPanel, 2, 88); + DiabloFreePtr (pStatusPanel); + talkflag = FALSE; + if (gbMaxPlayers != 1) { + pTalkPanel = LoadFileInMemSig("CtrlPan\\TalkPanl.CEL",NULL,'CTRL'); + DrawBuffCel(pBtmBuff, 0, 287, BTMBUFFX, pTalkPanel, 1, 640); + DiabloFreePtr (pTalkPanel); + pMultiBtns = LoadFileInMemSig("CtrlPan\\P8But2.CEL",NULL,'CTRL'); + pTalkBtns = LoadFileInMemSig("CtrlPan\\TalkButt.CEL",NULL,'CTRL'); + talkofs = 0; + sgszTalkMsg[0] = 0; + for (i = 0; i < MAX_PLRS; i++) sgbPlrTalkTbl[i] = TRUE; + for (i = 0; i < 3; i++) talkbtndown[i] = FALSE; + } + panelflag = FALSE; + + lvlbtndown = FALSE; + + pPanelButtons = LoadFileInMemSig("CtrlPan\\Panel8bu.CEL",NULL,'CTRL'); + for (i = 0; i < NUMPBTNS; i++) panbtn[i] = FALSE; + panbtndown = FALSE; + if (gbMaxPlayers == 1) numpanbtns = SINGLE_PBTNS; + else numpanbtns = MULTI_PBTNS; + + pChrButtons = LoadFileInMemSig("Data\\CharBut.CEL",NULL,'CTRL'); + for (i = 0; i < NUMCBTNS; i++) chrbtn[i] = FALSE; + chrbtndown = FALSE; + + pDurIcons = LoadFileInMemSig("Items\\DurIcons.CEL",NULL,'CTRL'); + + strcpy(infostr,""); + InitPanelStr(); + drawhpflag = TRUE; + drawmanaflag = TRUE; + chrflag = FALSE; + spselflag = FALSE; + + pSpellBkCel = LoadFileInMemSig("Data\\SpellBk.CEL",NULL,'CTRL'); + pSBkBtnCel = LoadFileInMemSig("Data\\SpellBkB.CEL",NULL,'CTRL'); + pSBkIconCels = LoadFileInMemSig("Data\\SpellI2.CEL",NULL,'CTRL'); + sbooktab = 0; + sbookflag = FALSE; + if (plr[myplr]._pClass == CLASS_WARRIOR) SpellPages[0][0] = SPL_REPAIR; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) SpellPages[0][0] = SPL_DISARM; + else if (plr[myplr]._pClass == CLASS_SORCEROR) SpellPages[0][0] = SPL_RECHARGE; + else if (plr[myplr]._pClass == CLASS_MONK) SpellPages[0][0] = SPL_SHOWMAGITEMS; + else if (plr[myplr]._pClass == CLASS_BARD) SpellPages[0][0] = SPL_IDENTIFY; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) SpellPages[0][0] = SPL_RAGE; + #endif + + pQLogCel = LoadFileInMemSig("Data\\Quest.CEL",NULL,'CTRL'); + + pGBoxBuff = LoadFileInMemSig("CtrlPan\\Golddrop.cel",NULL,'CTRL'); + // Initialize gold drop variables + dropGoldFlag = FALSE; + dropGoldValue = 0; + initialDropGoldValue = 0; + initialDropGoldIndex = 0; + pentaspin = 1; + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawCtrlPan() { + CopyCtrlPan(0, 16+talkofs, 640, 128, 64, 512); + DrawInfoBox(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawButtons() +{ + for (int i = 0; i < SINGLE_PBTNS; i++) { + if (!panbtn[i]) + CopyCtrlPan(PanBtnPos[i][0], PanBtnPos[i][1]-336, 71, 20, PanBtnPos[i][0] + 64, PanBtnPos[i][1] + 160); + else + DrawCel(PanBtnPos[i][0]+64, PanBtnPos[i][1]+178, pPanelButtons, i+1, 71); + } + + if (numpanbtns == MULTI_PBTNS) { + // Draw talk button + DrawCel(151, 634, pMultiBtns, 1+panbtn[PBTN_TALK], 33); + // Draw Friend or foe button + if (FriendlyMode) { + DrawCel(591, 634, pMultiBtns, 3+panbtn[PBTN_ATTACK], 33); + } else { + DrawCel(591, 634, pMultiBtns, 5+panbtn[PBTN_ATTACK], 33); + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetupSpellSel() +{ + int x,y,i,j; + __int64 mask,spl; + int cx, cy; + + spselflag = TRUE; + x = SPLICONRIGHT; + y = 495; + cx = x - (64 - (SPLICONSIZE >> 1)); + cy = y - (160 + (SPLICONSIZE >> 1)); + if (plr[myplr]._pRSpell != -1) { + for (j = 0; j < 4; j++) { + switch(j) { + case 0: + spl = plr[myplr]._pAblSpells; + break; + case 1: + spl = plr[myplr]._pMemSpells; + break; + case 2: + spl = plr[myplr]._pScrlSpells; + break; + case 3: + spl = plr[myplr]._pISpells; + break; + } + mask = 1; + for (i = 1; i < SPL_LAST; i++) { + if ((spl & mask) != 0) { + if ((i == plr[myplr]._pRSpell) && (j == plr[myplr]._pRSplType)) { + cx = x - (64 - (SPLICONSIZE >> 1)); + cy = y - (160 + (SPLICONSIZE >> 1)); + } + x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } + mask = mask << 1; + } + if (spl && (x != SPLICONRIGHT)) x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } + } + SetCursorPos(cx,cy); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckPanelBtns() +{ + for (int i = 0; i < numpanbtns; i++) { + int x2 = PanBtnPos[i][0] + PanBtnPos[i][2]; + int y2 = PanBtnPos[i][1] + PanBtnPos[i][3]; + if ((MouseX >= PanBtnPos[i][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[i][1]) && (MouseY <= y2)) { + panbtn[i] = TRUE; + drawbtnflag = TRUE; + panbtndown = TRUE; + } + } + + if (!spselflag) { + if (MouseX >= 565 && MouseX < 621 && MouseY >= 416 && MouseY < 472) { + SetupSpellSel(); + gamemenu_off(); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ActivatePanelBtn(int i) +{ + panbtn[i] = TRUE; + drawbtnflag = TRUE; + panbtndown = TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckDeadButtons() +{ + int x2, y2; + + x2 = PanBtnPos[PBTN_MENU][0] + PanBtnPos[PBTN_MENU][2]; + y2 = PanBtnPos[PBTN_MENU][1] + PanBtnPos[PBTN_MENU][3]; + if ((MouseX >= PanBtnPos[PBTN_MENU][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[PBTN_MENU][1]) && (MouseY <= y2)) + ActivatePanelBtn(PBTN_MENU); + x2 = PanBtnPos[PBTN_TALK][0] + PanBtnPos[PBTN_TALK][2]; + y2 = PanBtnPos[PBTN_TALK][1] + PanBtnPos[PBTN_TALK][3]; + if ((MouseX >= PanBtnPos[PBTN_TALK][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[PBTN_TALK][1]) && (MouseY <= y2)) + ActivatePanelBtn(PBTN_TALK); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DoAutoMap() { + // if we are multiplayer on the town level, DO NOT display + // the error message. Instead, the automap will show the + // game name and password + if (currlevel == 0 && gbMaxPlayers == 1) { + InitDiabloMsg(MSG_AMAPTWN); + return; + } + + // toggle automap + if (!automapflag) StartAutomap(); + else automapflag = FALSE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckPanelInfo() +{ + int i; + int x2, y2; + int pSpell, c, s; + int v; + + panelflag = FALSE; + ClearPanel(); + + for (i = 0; i < numpanbtns; i++) { + x2 = PanBtnPos[i][0] + PanBtnPos[i][2]; + y2 = PanBtnPos[i][1] + PanBtnPos[i][3]; + if ((MouseX >= PanBtnPos[i][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[i][1]) && (MouseY <= y2)) { + if (i != PBTN_ATTACK) + strcpy(infostr, PanBtnStr[i]); + else if (FriendlyMode) + strcpy(infostr, "Player friendly"); + else + strcpy(infostr, "Player attack"); + if (PanBtnHotKey[i] != NULL) { + sprintf(tempstr, "Hotkey : %s", PanBtnHotKey[i]); + AddPanelString(tempstr, TEXT_CENTER); + } + infoclr = ICOLOR_WHITE; + panelflag = TRUE; + pinfoflag = TRUE; + } + } + + if (!spselflag) { + if ((MouseX >= 565) && (MouseX < 621) && (MouseY >= 416) && (MouseY < 472)) { + strcpy(infostr, "Select current spell button"); + infoclr = ICOLOR_WHITE; + panelflag = TRUE; + pinfoflag = TRUE; + strcpy(tempstr, "Hotkey : 's'"); + AddPanelString(tempstr, TEXT_CENTER); + pSpell = plr[myplr]._pRSpell; + if (pSpell != -1) { + switch (plr[myplr]._pRSplType) { + case 0: + sprintf(tempstr, "%s Skill", spelldata[pSpell].sSkillText); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 1: + sprintf(tempstr, "%s Spell", spelldata[pSpell].sNameText); + AddPanelString(tempstr, TEXT_CENTER); + v = plr[myplr]._pSplLvl[pSpell]+plr[myplr]._pISplLvlAdd; + if ( v < 0 ) v = 0; + if (v == 0) sprintf(tempstr, "Spell Level 0 - Unusable"); + else sprintf(tempstr, "Spell Level %i", v); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 2: + sprintf(tempstr, "Scroll of %s", spelldata[pSpell].sNameText); + AddPanelString(tempstr, TEXT_CENTER); + c = 0; + for (s = 0; s < plr[myplr]._pNumInv; s++) { + if ((plr[myplr].InvList[s]._itype != -1) && + ((plr[myplr].InvList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].InvList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].InvList[s]._iSpell == pSpell) c++; + } + } + for (s = 0; s < MAXSPD; s++) { + if ((plr[myplr].SpdList[s]._itype != -1) && + ((plr[myplr].SpdList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].SpdList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].SpdList[s]._iSpell == pSpell) c++; + } + } + if (c == 1) strcpy(tempstr, "1 Scroll"); + else sprintf(tempstr, "%i Scrolls", c); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 3: + sprintf(tempstr, "Staff of %s", spelldata[pSpell].sNameText); + AddPanelString(tempstr, TEXT_CENTER); + if (plr[myplr].Hand1Item._iCharges == 1) strcpy(tempstr, "1 Charge"); + else sprintf(tempstr, "%i Charges", plr[myplr].Hand1Item._iCharges); + AddPanelString(tempstr, TEXT_CENTER); + break; + } + } + } + } + + if ((MouseX > 190) && (MouseX < 437) && (MouseY > 356) && (MouseY < 385)) + cursinvitem = CheckInvHLight(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ReleasePanelBtn() { + BYTE bMenuOff = TRUE; + + drawbtnflag = TRUE; + panbtndown = FALSE; + for (int i = 0; i < NUMPBTNS; i++) { + if (! panbtn[i]) continue; + panbtn[i] = FALSE; + + // was the mouseup in this button? + if (MouseX < PanBtnPos[i][0]) continue; + if (MouseX > PanBtnPos[i][0] + PanBtnPos[i][2]) continue; + if (MouseY < PanBtnPos[i][1]) continue; + if (MouseY > PanBtnPos[i][1] + PanBtnPos[i][3]) continue; + + switch(i) { + case PBTN_CHR : + questlog = FALSE; + chrflag = !chrflag; + break; + case PBTN_QUEST: + chrflag = FALSE; + if (!questlog) StartQuestlog(); + else questlog = FALSE; + break; + case PBTN_AMAP : + DoAutoMap(); + break; + case PBTN_MENU : + qtextflag = FALSE; + gamemenu_toggle(); + bMenuOff = FALSE; + break; + case PBTN_INV : + sbookflag = FALSE; + invflag = !invflag; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + break; + case PBTN_SBOOK : + invflag = FALSE; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + sbookflag = !sbookflag; + break; + case PBTN_TALK: + if (talkflag) TalkEnd(); + else TalkStart(); + break; + case PBTN_ATTACK: + FriendlyMode = !FriendlyMode; + break; + } + } + + if (bMenuOff) gamemenu_off(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FreeControlPan() +{ + DiabloFreePtr(pBtmBuff); + DiabloFreePtr(pManaBuff); + DiabloFreePtr(pLifeBuff); + DiabloFreePtr(pPanelText); + DiabloFreePtr(pChrPanel); + DiabloFreePtr(pSpellCels); + DiabloFreePtr(pPanelButtons); + DiabloFreePtr(pMultiBtns); + DiabloFreePtr(pTalkBtns); + DiabloFreePtr(pChrButtons); + DiabloFreePtr(pDurIcons); + DiabloFreePtr(pQLogCel); + DiabloFreePtr(pSpellBkCel); + DiabloFreePtr(pSBkBtnCel); + DiabloFreePtr(pSBkIconCels); + DiabloFreePtr(pGBoxBuff); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL InfoFit(const char * p) { + long tw = 0; + while (*p) { + BYTE c = char2print(*p++); + c = fonttrans[c]; + tw += fontkern[c]; + if (tw >= 125) return FALSE; + } + + return TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void CPrintString(int l,const char * pszStr, int just, int pnl) { + long boffset = fontofs[pnl][l]; + + int w = 0; + if (just == TEXT_CENTER) { + long tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + 2; + } + + if (tw < 288) w = (288 - tw) >> 1; + boffset += w; + } + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + 2; + if (c && (w < 288)) DrawPanelFont(boffset, c, infoclr); + boffset += fontkern[c] + 2; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PrintInfo() { + if (talkflag) return; + + int nOffset1 = 0; + int nOffset2 = 1; + if (infostr[0] != 0) { + CPrintString(0, infostr, TEXT_CENTER, pnumlines); + nOffset1 = 1; + nOffset2 = 0; + } + + for (int i = 0; i < pnumlines; i++) + CPrintString(i+nOffset1, panelstr[i], pstrjust[i], pnumlines-nOffset2); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawInfoBox() +{ + // Erase old box + CopyCtrlPan(177, 62, 288, 60, 241, 558); + + if ((!panelflag) && (!trigflag) && (cursinvitem == -1) && (!spselflag)) { + infostr[0] = 0; + infoclr = ICOLOR_WHITE; + ClearPanel(); + } + + if ((spselflag) || (trigflag)) { + infoclr = ICOLOR_WHITE; + } else { + if (curs >= ICSTART) { + if (plr[myplr].HoldItem._itype == IT_GOLD) { + int nGold = plr[myplr].HoldItem._ivalue; + const char * get_pieces_str(int nGold); + sprintf(infostr,"%i gold %s",nGold,get_pieces_str(nGold)); + } + else if (!plr[myplr].HoldItem._iStatFlag) { + ClearPanel(); + AddPanelString("Requirements not met", TEXT_CENTER); + pinfoflag = TRUE; + } + else { + if (plr[myplr].HoldItem._iIdentified) strcpy(infostr, plr[myplr].HoldItem._iIName); + else strcpy(infostr, plr[myplr].HoldItem._iName); + if (plr[myplr].HoldItem._iMagical == IMAGIC_MAGIC) infoclr = ICOLOR_BLUE; + if (plr[myplr].HoldItem._iMagical == IMAGIC_UNIQUE) infoclr = ICOLOR_GOLD; + } + } else { + // if cursinvitem != -1 then the string will already be in infostr + // if trigflag then the string will already be set as well + if (cursitem != -1) { + // @@@ drb debug +#if 0 + +int GetLDeltaItem(); + + ClearPanel(); + ItemStruct *pi = &item[cursitem]; + strcpy(infostr, pi->_iName); + sprintf(tempstr, "Delta # = %i", GetLDeltaItem()); + AddPanelString(tempstr, TEXT_CENTER); + //sprintf(tempstr, "seed = %i", pi->_iSeed); + //AddPanelString(tempstr, TEXT_CENTER); + // @@@ drb end debug +#else + GetItemStr(cursitem); +#endif + } + if (cursobj != -1) GetObjectStr(cursobj); + if (cursmonst != -1) { + if (leveltype != 0) { + infoclr = ICOLOR_WHITE; + strcpy(infostr, monster[cursmonst].mName); + ClearPanel(); +#if DISABLED_CHEATS + if (1) { + sprintf(tempstr, "HP: %08X/%08X", + monster[cursmonst]._mhitpoints, + monster[cursmonst]._mmaxhp); + AddPanelString(tempstr, TEXT_CENTER); + sprintf(tempstr, "Res: %02X", + monster[cursmonst].mMagicRes); + pinfoflag = TRUE; + } else +#endif + if (monster[cursmonst]._uniqtype != 0) { + infoclr = ICOLOR_GOLD; + void PrintUniqueHistory(); + PrintUniqueHistory(); + } else PrintMonstHistory(monster[cursmonst].MType->mtype); + } else strcpy(infostr, towner[cursmonst]._tName); + } + if (cursplr != -1) { + infoclr = ICOLOR_GOLD; + strcpy(infostr, plr[cursplr]._pName); + ClearPanel(); + sprintf(tempstr, "%s, Level : %i", ClassStrTbl[plr[cursplr]._pClass], plr[cursplr]._pLevel); + AddPanelString(tempstr, TEXT_CENTER); + sprintf(tempstr, "Hit Points %i of %i", (plr[cursplr]._pHitPoints >> HP_SHIFT), (plr[cursplr]._pMaxHP >> HP_SHIFT)); + AddPanelString(tempstr, TEXT_CENTER); + } + } + } + //if ((pinfoflag) && (cursmonst == -1) && (cursinvitem == -1) && (curs < ICSTART)) ClearPanel(); + if ((infostr[0] != 0) || (pnumlines != 0)) PrintInfo(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PlrStringXY(int x1, int y, int x2,const char * pszStr,char col) { + long boffset = nBuffWTbl[y + 160] + x1 + 64; + int aw = x2 - x1 + 1; + int w = 0; + + // calculate string width + int tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + 1; + } + + if (tw < aw) w = (aw - tw) >> 1; + boffset += w; + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + 1; + if (c && w < aw) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + 1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PrintStringXY(int x, int y,const char * pszStr, char col) { + long boffset = nBuffWTbl[y + 160] + x + 64; + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + if (c) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + 1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PlrStringXY2(int x1, int y, int x2,const char * pszStr,char col,int a) { + long boffset = nBuffWTbl[y + 160] + x1 + 64; + int aw = x2 - x1 + 1; + int w = 0; + + // calculate string width + int tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + a; + } + + if (tw < aw) w = (aw - tw) >> 1; + boffset += w; + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + a; + if (c && w < aw) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + a; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawChr() +{ + char c; + char chrstr[64]; + int pc; + long mind, maxd; + int hper, ac; + + DrawCel(64, 511, pChrPanel, 1, 320); + + PlrStringXY(20, 32, 151, plr[myplr]._pName, ICOLOR_WHITE); + + PlrStringXY(168, 32, 299, ClassStrTbl[plr[myplr]._pClass], ICOLOR_WHITE); + + #if 0 + if (plr[myplr]._pClass == CLASS_WARRIOR) PlrStringXY(168, 32, 299, "Warrior", ICOLOR_WHITE); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlrStringXY(168, 32, 299, "Rogue", ICOLOR_WHITE); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlrStringXY(168, 32, 299, "Sorceror", ICOLOR_WHITE); + else if (plr[myplr]._pClass == CLASS_MONK) PlrStringXY(168, 32, 299, "Monk", ICOLOR_WHITE); + else if (plr[myplr]._pClass == CLASS_BARD) PlrStringXY(168, 32, 299, "Bard", ICOLOR_WHITE); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlrStringXY(168, 32, 299, "Barbarian", ICOLOR_WHITE); + #endif + #endif + + sprintf(chrstr, "%i", plr[myplr]._pLevel); + PlrStringXY(66, 69, 109, chrstr, ICOLOR_WHITE); + + sprintf(chrstr, "%li", plr[myplr]._pExperience); + PlrStringXY(216, 69, 300, chrstr, ICOLOR_WHITE); + + if (plr[myplr]._pLevel == 50) { + strcpy(chrstr, "None"); + c = ICOLOR_GOLD; + } else { + sprintf(chrstr, "%li", plr[myplr]._pNextExper); + c = ICOLOR_WHITE; + } + PlrStringXY(216, 97, 300, chrstr, c); + + sprintf(chrstr, "%i", plr[myplr]._pGold); + PlrStringXY(216, 146, 300, chrstr, ICOLOR_WHITE); + + c = ICOLOR_WHITE; + if (plr[myplr]._pIBonusAC > 0) c = ICOLOR_BLUE; + if (plr[myplr]._pIBonusAC < 0) c = ICOLOR_RED; + // rjs ac = (byte)plr[myplr]._pArmorClass+plr[myplr]._pIAC+plr[myplr]._pIBonusAC; + ac = plr[myplr]._pIAC+plr[myplr]._pIBonusAC; + ac += (plr[myplr]._pDexterity / 5); + sprintf(chrstr, "%i", ac); + PlrStringXY(258, 183, 301, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pIBonusToHit > 0) c = ICOLOR_BLUE; + if (plr[myplr]._pIBonusToHit < 0) c = ICOLOR_RED; + hper = BASE_TO_HIT + (plr[myplr]._pDexterity >> 1) + plr[myplr]._pIBonusToHit; + sprintf(chrstr, "%i%%", hper); + PlrStringXY(258, 211, 301, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pIBonusDam > 0) c = ICOLOR_BLUE; + if (plr[myplr]._pIBonusDam < 0) c = ICOLOR_RED; + mind = plr[myplr]._pIMinDam; + mind += (mind * plr[myplr]._pIBonusDam) / 100; + mind += plr[myplr]._pIBonusDamMod; + if (plr[myplr].Hand1Item._itype == IT_BOW) { + if (plr[myplr]._pClass == CLASS_ROGUE) mind += plr[myplr]._pDamageMod; + else mind += (plr[myplr]._pDamageMod >> 1); + } else mind += plr[myplr]._pDamageMod; + maxd = plr[myplr]._pIMaxDam; + maxd += (maxd * plr[myplr]._pIBonusDam) / 100; + maxd += plr[myplr]._pIBonusDamMod; + if (plr[myplr].Hand1Item._itype == IT_BOW) { + if (plr[myplr]._pClass == CLASS_ROGUE) maxd += plr[myplr]._pDamageMod; + else maxd += (plr[myplr]._pDamageMod >> 1); + } else maxd += plr[myplr]._pDamageMod; + sprintf(chrstr, "%i-%i", mind, maxd); + if ((mind >= 100) || (maxd >= 100)) + PlrStringXY2(254, 239, 305, chrstr, c, -1); + else + PlrStringXY2(258, 239, 301, chrstr, c, 0); + + // Magic Resist + if (plr[myplr]._pMagResist == 0) c = ICOLOR_WHITE; + else c = ICOLOR_BLUE; + if (plr[myplr]._pMagResist < RESIST_MAX) sprintf(chrstr, "%i%%", plr[myplr]._pMagResist); + else { + c = ICOLOR_GOLD; + sprintf(chrstr, "MAX"); + } + PlrStringXY(257, 276, 300, chrstr, c); + + // Fire Resist + if (plr[myplr]._pFireResist == 0) c = ICOLOR_WHITE; + else c = ICOLOR_BLUE; + if (plr[myplr]._pFireResist < RESIST_MAX) sprintf(chrstr, "%i%%", plr[myplr]._pFireResist); + else { + c = ICOLOR_GOLD; + sprintf(chrstr, "MAX"); + } + PlrStringXY(257, 304, 300, chrstr, c); + + // Lightning Resist + if (plr[myplr]._pLghtResist == 0) c = ICOLOR_WHITE; + else c = ICOLOR_BLUE; + if (plr[myplr]._pLghtResist < RESIST_MAX) sprintf(chrstr, "%i%%", plr[myplr]._pLghtResist); + else { + c = ICOLOR_GOLD; + sprintf(chrstr, "MAX"); + } + PlrStringXY(257, 332, 300, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseStr); + if (MaxStats[plr[myplr]._pClass][0] == plr[myplr]._pBaseStr) c = ICOLOR_GOLD; + PlrStringXY( 95, 155, 126, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseMag); + if (MaxStats[plr[myplr]._pClass][1] == plr[myplr]._pBaseMag) c = ICOLOR_GOLD; + PlrStringXY( 95, 183, 126, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseDex); + if (MaxStats[plr[myplr]._pClass][2] == plr[myplr]._pBaseDex) c = ICOLOR_GOLD; + PlrStringXY( 95, 211, 126, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseVit); + if (MaxStats[plr[myplr]._pClass][3] == plr[myplr]._pBaseVit) c = ICOLOR_GOLD; + PlrStringXY( 95, 239, 126, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pStrength > plr[myplr]._pBaseStr) c = ICOLOR_BLUE; + if (plr[myplr]._pStrength < plr[myplr]._pBaseStr) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pStrength); + PlrStringXY(143, 155, 173, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pMagic > plr[myplr]._pBaseMag) c = ICOLOR_BLUE; + if (plr[myplr]._pMagic < plr[myplr]._pBaseMag) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pMagic); + PlrStringXY(143, 183, 173, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pDexterity > plr[myplr]._pBaseDex) c = ICOLOR_BLUE; + if (plr[myplr]._pDexterity < plr[myplr]._pBaseDex) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pDexterity); + PlrStringXY(143, 211, 173, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pVitality > plr[myplr]._pBaseVit) c = ICOLOR_BLUE; + if (plr[myplr]._pVitality < plr[myplr]._pBaseVit) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pVitality); + PlrStringXY(143, 239, 173, chrstr, c); + + // drb.patch1.start.2/05/97 + if (plr[myplr]._pStatPts > 0) { + int CalcStatDiff(int); + if (CalcStatDiff(myplr) < plr[myplr]._pStatPts) plr[myplr]._pStatPts = CalcStatDiff(myplr); + } + // drb.patch1.end.2/05/97 + // Points to distibute + if (plr[myplr]._pStatPts > 0) { + sprintf(chrstr, "%i", plr[myplr]._pStatPts); + PlrStringXY(95, 266, 126, chrstr, ICOLOR_RED);// check x y + pc = plr[myplr]._pClass; + if (plr[myplr]._pBaseStr < MaxStats[pc][0]) DrawCel(201, 319, pChrButtons, 2+chrbtn[0], 41); + if (plr[myplr]._pBaseMag < MaxStats[pc][1]) DrawCel(201, 347, pChrButtons, 4+chrbtn[1], 41); + if (plr[myplr]._pBaseDex < MaxStats[pc][2]) DrawCel(201, 376, pChrButtons, 6+chrbtn[2], 41); + if (plr[myplr]._pBaseVit < MaxStats[pc][3]) DrawCel(201, 404, pChrButtons, 8+chrbtn[3], 41); + } + + if (plr[myplr]._pMaxHP > plr[myplr]._pMaxHPBase) c = ICOLOR_BLUE; + else c = ICOLOR_WHITE; + sprintf(chrstr, "%i", (plr[myplr]._pMaxHP >> HP_SHIFT)); + PlrStringXY( 95, 304, 126, chrstr, c); + if (plr[myplr]._pHitPoints != plr[myplr]._pMaxHP) c = ICOLOR_RED; + sprintf(chrstr, "%i", (plr[myplr]._pHitPoints >> HP_SHIFT)); + PlrStringXY(143, 304, 174, chrstr, c); + + if (plr[myplr]._pMaxMana > plr[myplr]._pMaxManaBase) c = ICOLOR_BLUE; + else c = ICOLOR_WHITE; + sprintf(chrstr, "%i", (plr[myplr]._pMaxMana >> MANA_SHIFT)); + PlrStringXY( 95, 332, 126, chrstr, c); + if (plr[myplr]._pMana != plr[myplr]._pMaxMana) c = ICOLOR_RED; + sprintf(chrstr, "%i", (plr[myplr]._pMana >> MANA_SHIFT)); + PlrStringXY(143, 332, 174, chrstr, c); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void CheckLvlBtn() { + if (lvlbtndown) return; + if ((MouseX >= 40) && (MouseX <= 81) && (MouseY >= 313) && (MouseY <= 335)) + lvlbtndown = TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ReleaseLvlBtn() { + if ((MouseX >= 40) && (MouseX <= 81) && (MouseY >= 313) && (MouseY <= 335)) + chrflag = TRUE; + lvlbtndown = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawLevelUpIcon() { + int c; + + if (stextflag != STORE_NONE) return; + if (lvlbtndown) c = 3; + else c = 2; + PlrStringXY(0, 303, 120, "Level Up", ICOLOR_WHITE); + DrawCel(104, 495, pChrButtons, c, 41); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void CheckChrBtns() { + if (chrbtndown) return; + if (! plr[myplr]._pStatPts) return; + + int pc = plr[myplr]._pClass; + for (int i = 0; i < NUMCBTNS; i++) { + switch(i) { + case 0: + if (plr[myplr]._pBaseStr >= MaxStats[pc][i]) + continue; + break; + + case 1: + if (plr[myplr]._pBaseMag >= MaxStats[pc][i]) + continue; + break; + + case 2: + if (plr[myplr]._pBaseDex >= MaxStats[pc][i]) + continue; + break; + + case 3: + if (plr[myplr]._pBaseVit >= MaxStats[pc][i]) + continue; + break; + + default: + continue; + } + + int x2 = ChrBtnPos[i][0] + ChrBtnPos[i][2]; + int y2 = ChrBtnPos[i][1] + ChrBtnPos[i][3]; + if ((MouseX >= ChrBtnPos[i][0]) && (MouseX <= x2) && (MouseY >= ChrBtnPos[i][1]) && (MouseY <= y2)) { + chrbtn[i] = TRUE; + chrbtndown = TRUE; + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ReleaseChrBtn() { + chrbtndown = FALSE; + for (int i = 0; i < NUMCBTNS; i++) { + if (! chrbtn[i]) continue; + chrbtn[i] = FALSE; + + // was mouseup inside button? + if (MouseX < ChrBtnPos[i][0]) continue; + if (MouseX > ChrBtnPos[i][0] + ChrBtnPos[i][2]) continue; + if (MouseY < ChrBtnPos[i][1]) continue; + if (MouseY > ChrBtnPos[i][1] + ChrBtnPos[i][3]) continue; + + switch(i) { + case CBTN_STR : + NetSendCmdParam1(TRUE,CMD_ADDSTR,1); + plr[myplr]._pStatPts--; + break; + case CBTN_MAG : + NetSendCmdParam1(TRUE,CMD_ADDMAG,1); + plr[myplr]._pStatPts--; + break; + case CBTN_DEX : + NetSendCmdParam1(TRUE,CMD_ADDDEX,1); + plr[myplr]._pStatPts--; + break; + case CBTN_VIT : + NetSendCmdParam1(TRUE,CMD_ADDVIT,1); + plr[myplr]._pStatPts--; + break; + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int DrawDurIcon4Item(const ItemStruct * pItem, int x, int c) { + + // don't need to draw icon if there is no item + if (pItem->_itype == -1) return x; + + // don't need to draw icon if durability is high + if (pItem->_iDurability > 5) return x; + + if (c == 0) { + if (pItem->_iClass == IC_WEAP) switch(pItem->_itype) { + case IT_SWORD: + c = 2; + break; + case IT_AXE: + c = 6; + break; + case IT_BOW: + c = 7; + break; + case IT_MACE: + c = 5; + break; + case IT_STAFF: + c = 8; + break; + } + else { + c = 1; + } + } + + // choose cel to draw based on durability + if (pItem->_iDurability > 2) c += 8; + + // draw it + DrawCel(x, 495, pDurIcons, c, 32); + + // adjust position for next durability icon + return x - 40; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawDurIcon() { + if ((chrflag || questlog) && (invflag || sbookflag)) return; + + int x = 656; + if (invflag || sbookflag) x -= 320; + const PlayerStruct * p = &plr[myplr]; + x = DrawDurIcon4Item(&p->InvBody[INVLOC_HEAD],x,4); + x = DrawDurIcon4Item(&p->InvBody[INVLOC_BODY],x,3); + x = DrawDurIcon4Item(&p->InvBody[INVLOC_HAND1],x,0); + x = DrawDurIcon4Item(&p->InvBody[INVLOC_HAND2],x,0); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void RedBack() { + long ltaboff; + + if (light4flag) ltaboff = 1536; + else ltaboff = 4608; + + app_assert(gpBuffer); + if (leveltype != 4) { + __asm { + mov edi,dword ptr [gpBuffer] + add edi,122944 + + mov ebx,dword ptr [pLightTbl] + add ebx,dword ptr [ltaboff] + + mov edx,352 +_YLp: mov ecx,640 +_XLp: mov al,byte ptr [edi] + xlatb + stosb + loop _XLp + add edi,128 + dec edx + jnz _YLp + } + } else { + __asm { + mov edi,dword ptr [gpBuffer] + add edi,122944 + + mov ebx,dword ptr [pLightTbl] + add ebx,dword ptr [ltaboff] + + mov edx,352 +_YLp2: mov ecx,640 +_XLp2: mov al,byte ptr [edi] + cmp al,32 + jb _Skip + xlatb +_Skip: stosb + loop _XLp2 + add edi,128 + dec edx + jnz _YLp2 + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PrintSBookStr(int x, int y, BOOL cjustflag,const char * pszStr, char col) { + long boffset = nBuffWTbl[y] + x + 440; + int w = 0; + + if (cjustflag) { + int tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + 1; + } + + if (tw < 222) w = (222 - tw) >> 1; + boffset += w; + } + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + 1; + if (c && w <= 222) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + 1; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +char GetSBookTrans(int ii, BOOL townok) { + char st, sl; + + // hack hack hack + if (plr[myplr]._pClass == CLASS_MONK && ii == SPL_SHOWMAGITEMS) + return STRN_GOLD; + + st = STRN_BLUE; + if (plr[myplr]._pISpells & (((__int64)1) << (ii-1))) st = STRN_ORANGE; + if (plr[myplr]._pAblSpells & (((__int64)1) << (ii-1))) st = STRN_GOLD; + if (st == STRN_BLUE) { + if (!CheckSpell(myplr, ii, SPT_MEMORIZED, TRUE)) st = STRN_GREY; + sl = plr[myplr]._pSplLvl[ii] + plr[myplr]._pISplLvlAdd; + if (sl <= 0 ) st = STRN_GREY; + } + if ((townok) && (currlevel == 0) && (st != STRN_GREY) && (spelldata[ii].sTownSpell == FALSE)) st = STRN_GREY; + return(st); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawSpellBook() +{ + int i, ii, y, mind, maxd; + __int64 tspls; + char st; + int v; + + // Drawbackground + DrawCel(384, 511, pSpellBkCel, 1, 320); + + // Draw tab + //x = (sbooktab * 51) + 391; + //DrawCel(x, 508, pSBkBtnCel, 1 + sbooktab, 51); +// x = (sbooktab * 76) + 391; +// DrawCel(x, 508, pSBkBtnCel, 1 + sbooktab, 76); + + if (sbooktab < NUMSPBKBTNS) + { + long x = (sbooktab * SPBKBTNWDTH) + 391; + DrawCel(x, 508, pSBkBtnCel, sbooktab + 1, SPBKBTNWDTH); + } + + // Draw Spell Icons + y = 215; + tspls = plr[myplr]._pISpells | plr[myplr]._pMemSpells | plr[myplr]._pAblSpells; + for (i = 1; i < 8; i++) { + ii = SpellPages[sbooktab][i-1]; + if (ii != -1) { + if (tspls & (((__int64) 1) << (ii-1))) { + st = GetSBookTrans(ii, TRUE); + SetSpellTrans(st); + DrawSpellCel(395, y, pSBkIconCels, SpellITbl[ii], 37); + if ((ii == plr[myplr]._pRSpell) && (st == plr[myplr]._pRSplType)) { + SetSpellTrans(STRN_GOLD); + DrawSpellCel(395, y, pSBkIconCels, SI_LAST, 37); + } + PrintSBookStr(10, y-23, FALSE, spelldata[ii].sNameText, ICOLOR_WHITE); + st = GetSBookTrans(ii, FALSE); + switch (st) { + case STRN_GOLD: + strcpy(tempstr, "Skill"); + break; + case STRN_ORANGE: + sprintf(tempstr, "Staff (%i charges)", plr[myplr].Hand1Item._iCharges); + break; + default: + v = GetManaAmount(myplr, ii) >> MANA_SHIFT; + GetDamageAmt(ii, &mind, &maxd); + if (mind != -1) sprintf(tempstr, "Mana: %i Dam: %i - %i", v, mind, maxd); + else sprintf(tempstr, "Mana: %i Dam: n/a", v); + if (ii == SPL_BONESPIRIT) sprintf(tempstr, "Mana: %i Dam: 1/3 tgt hp", v); + PrintSBookStr(10, y-1, FALSE, tempstr, ICOLOR_WHITE); + + v = plr[myplr]._pSplLvl[ii]+plr[myplr]._pISplLvlAdd; + if ( v < 0 ) v = 0; + if (v == 0) sprintf(tempstr, "Spell Level 0 - Unusable"); + else sprintf(tempstr, "Spell Level %i", v); + break; + } + PrintSBookStr(10, y-12, FALSE, tempstr, ICOLOR_WHITE); + } + } + y += 43; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckSBook() +{ + int spl; + __int64 tspls; + char st; + + // Check spell icon + if ((MouseX >= 331) && (MouseX < 368) && (MouseY >= 18) && (MouseY < 314)) { + spl = (MouseY - 18) / 43; + spl = SpellPages[sbooktab][spl]; + tspls = plr[myplr]._pISpells | plr[myplr]._pMemSpells | plr[myplr]._pAblSpells; + if (spl != -1) { + if (tspls & (((__int64)1) << (spl-1))) { + st = SPT_MEMORIZED; + if (plr[myplr]._pISpells & (((__int64)1) << (spl-1))) st = SPT_ITEM; + if (plr[myplr]._pAblSpells & (((__int64)1) << (spl-1))) st = SPT_ABILITY; + + plr[myplr]._pRSpell = spl; + plr[myplr]._pRSplType = st; + force_redraw = FULLDRAW; + } + } + } + // Check spell tabs + if ((MouseX >= 327) && (MouseX < 327 + SPBKBTNWDTH * NUMSPBKBTNS) && + (MouseY >= 320) && (MouseY < 349)) + { + sbooktab = (MouseX - 327) / SPBKBTNWDTH; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* + +BOOL CheckSBookCast() +{ + int spl; + __int64 tspls; + char st; + BOOL okflag; + + if (currlevel == 0) return(FALSE); + // Check spell icon + if ((MouseX >= 327) && (MouseX < 368) && (MouseY >= 29) && (MouseY < 346)) { + spl = (MouseY - 29) / 46; + spl = SpellPages[sbooktab][spl]; + tspls = plr[myplr]._pISpells | plr[myplr]._pMemSpells | plr[myplr]._pAblSpells; + if (spl != -1) { + if (tspls & (1 << (spl-1))) { + st = SPT_MEMORIZED; + if (plr[myplr]._pISpells & (((__int64)1) << (spl-1))) st = SPT_ITEM; + if (plr[myplr]._pAblSpells & (1 << (spl-1))) st = SPT_ABILITY; + okflag = FALSE; + switch (st) { + case SPT_ABILITY : + case SPT_MEMORIZED : + okflag = CheckSpell(myplr, spl, st, FALSE); + break; + case SPT_ITEM: + okflag = UseStaffSBook(spl); + break; + } + if (okflag) { + if (spelldata[spl].sTargeted) { + plr[myplr]._pTSpell = spl; + plr[myplr]._pTSplType = st; + NewCursor(TARGET_CURS); + } + else { + plr[myplr]._pSBkSpell = spl; + plr[myplr]._pSBkSplType = st; + NetSendCmdParam1(TRUE,CMD_SBSPELL,plr[myplr]._pSBkSpell); + } + return(TRUE); + } + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +const char * get_pieces_str(int nGold) { + if (nGold == 1) return "piece"; + return "pieces"; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawGoldBox(int gold) +{ + int i; + long xOffset; + + // Initialize + xOffset = 0; + + // Draw the box + DrawCel(415, 338, pGBoxBuff, 1, 261); + // Output the strings + sprintf(tempstr, "You have %u gold",initialDropGoldValue); + PlrStringXY(366, 87, 600, tempstr, ICOLOR_GOLD); + sprintf(tempstr, "%s. How many do", get_pieces_str(initialDropGoldValue)); + PlrStringXY(366, 103, 600, tempstr, ICOLOR_GOLD); + PlrStringXY(366, 121, 600, "you want to remove?", ICOLOR_GOLD); + + if (gold > 0) { + sprintf(tempstr, "%u", gold); + PrintStringXY(388, 140, tempstr, ICOLOR_WHITE); + } + + // Get x offset for pentagram + if (gold > 0) { + for (i = 0; i < tempstr[i] != 0; i++) { + BYTE c = char2print(tempstr[i]); + c = fonttrans[c]; + xOffset += fontkern[c]+1; + } + xOffset += 452; + } else xOffset = 450; + + // Draw the pentagram + DrawCel(xOffset, 300, pSTextSpinCels, pentaspin, 12); + // Increment the pentagram spinner + pentaspin = (pentaspin & 0x7) + 1; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +// macro to convert char to int +#define ATON(c) (c - 0x30) +// keyboard constants +#define DG_CR 0x0d +#define DG_ESC 0x1b +#define DG_BACK 0x08 + +void DropGoldType(char c) //, int ivalue) +{ + char dGoldStr[6]; + + // Check if player is dead. This should prevent the multi player death frame + // gold cheat. + if ((plr[myplr]._pHitPoints >> HP_SHIFT) <= 0) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + return; + } + + // Clear the string + memset(dGoldStr, 0x00, sizeof(dGoldStr)); + // Convert number to string + _itoa(dropGoldValue, dGoldStr, 10); + + // Carriage Return was pressed so the player wants to drop some gold + if (c == DG_CR) { + if (dropGoldValue > 0) DropGold(myplr, initialDropGoldIndex); + dropGoldFlag = FALSE; + return; + } + // Escape was pressed so the player wants to quit w/out dropping gold + if (c == DG_ESC) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + return; + } + // Backspace was pressed so clear the last char in the string + if (c == DG_BACK) { + dGoldStr[strlen(dGoldStr)-1] = NULL; + dropGoldValue = atoi(dGoldStr); + return; + } + // Check to see if the player typed a number and if so update the string + if ((ATON(c) >= 0) && (ATON(c) <= 9)) { + if ((dropGoldValue == 0) && (atoi(dGoldStr) > initialDropGoldValue)) + dGoldStr[0] = c; + else { + dGoldStr[strlen(dGoldStr)] = c; + if ((atoi(dGoldStr) > initialDropGoldValue) || (strlen(dGoldStr) > strlen(dGoldStr))) + return; + } + dropGoldValue = atoi(dGoldStr); + return; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DropGold(int pnum, int cii) +{ + int c; + + if (cii <= 46) { + // Item is in the InvList + c = cii - 7; + plr[pnum].InvList[c]._ivalue -= dropGoldValue; + // Modify item cursor in the InvList + if (plr[pnum].InvList[c]._ivalue > 0) SetGoldCurs(pnum, c); + else RemoveInvItem(pnum, c); + } else { + // Item is in the SpdList + c = cii - 47; + plr[pnum].SpdList[c]._ivalue -= dropGoldValue; + // Modify item cursor in the SpdList + if (plr[pnum].SpdList[c]._ivalue > 0) SetSpdbarGoldCurs(pnum, c); + else RemoveSpdBarItem(pnum, c); + } + + // Initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + // Set hold item values + plr[pnum].HoldItem._ivalue = dropGoldValue; + plr[pnum].HoldItem._iStatFlag = TRUE; + // Set cursor arrow to gold + SetDropGoldCursor(pnum); + + // Recalculate players gold + plr[pnum]._pGold = CalculateGold(pnum); + + dropGoldValue = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetDropGoldCursor(int pnum) +{ + if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) + plr[pnum].HoldItem._iCurs = ITEM_5GOLD; + else { + if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) + plr[pnum].HoldItem._iCurs = ITEM_1GOLD; + else + plr[pnum].HoldItem._iCurs = ITEM_3GOLD; + } + + NewCursor(plr[pnum].HoldItem._iCurs + ICSTART); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +void WhiteCtrlPan(int sx, int sy, int deltax, int deltay, int dx, int dy) +{ + long dest; + + dest = (dy * 768) + dx; + __asm { + mov edi,dword ptr [pBuffer] + add edi,dword ptr [dest] + + xor ebx,ebx + mov bx,word ptr [deltax] + xor edx,edx + mov dx,word ptr [deltay] + mov eax, 0ffffffffh +_CLp: mov ecx,ebx + shr ecx,1 + jnc _Tw + stosb + jecxz _Tx +_Tw: shr ecx,1 + jnc _TLp + stosw + jecxz _Tx +_TLp: rep stosd +_Tx: add edi,768 + sub edi,ebx + dec edx + jnz _CLp + } +} +*/ + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static char * print_talk_string( + char * pszStr, + int x, + int y, + long * plOffset, + int color +) { + // move to top left of talk box + x += 264; + //y += 546; + y += 534; + + int w = x; + *plOffset = nBuffWTbl[y] + x; + while (*pszStr) { + // can we fit the next character on this row? + BYTE c = char2print(*pszStr); + c = fonttrans[c]; + w += fontkern[c] + 1; + if (w > 250+264) return pszStr; + pszStr++; + + // draw char + if (c != 0) DrawPanelFont(*plOffset, c, color); + *plOffset += fontkern[c] + 1; + } + + return NULL; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define TALK_ROW_HGT 13 +void DrawTalkBox() { + + if (!talkflag) return; + app_assert(gpBuffer); + + // erase old box + CopyCtrlPan(175, 20+talkofs, 294, 5, 239, 516); + for (int i = 0; i < 10; i++) + CopyCtrlPan(175+(i>>1), 25+i+talkofs, 293-i, 1, 239+(i>>1), 521+i); + CopyCtrlPan(185, 35+talkofs, 274, 30, 249, 531); + CopyCtrlPan(180, 65+talkofs, 284, 5, 244, 561); + for (i = 0; i < 10; i++) + CopyCtrlPan(180, 70+i+talkofs, 284+i, 1, 244, 566+i); + CopyCtrlPan(170, 80+talkofs, 310, 55, 234, 576); + + // 200,373-450,456 (screen coords) + long lOffset; + char * pszStr = sgszTalkMsg; + for (int row = 0; row < 3; row++) { + pszStr = print_talk_string(pszStr,0,row * TALK_ROW_HGT,&lOffset,ICOLOR_WHITE); + if (! pszStr) break; + } + + // don't allow string to be too long + if (pszStr) *pszStr = 0; + + // draw spinnies on last row + DrawCelP(gpBuffer + lOffset, pSTextSpinCels, tspin, 12); + tspin = (tspin & 0x7) + 1; + + // draw player names + row = 0; + for (i = 0; i < MAX_PLRS; i++) { + if (i == myplr) continue; + + // are we "talking" to this player + int nColor, nCel; + if (sgbPlrTalkTbl[i]) { + nColor = ICOLOR_GOLD; + if (talkbtndown[row]) { + if (row == 0) nCel = 3; + else nCel = 4; + DrawCel(236, 596 + (row * 18), pTalkBtns, nCel, 61); + } + } else { + nColor = ICOLOR_RED; + if (row == 0) nCel = 1; + else nCel = 2; + if (talkbtndown[row]) nCel += 4; + DrawCel(236, 596 + (row * 18), pTalkBtns, nCel, 61); + } + + if (plr[i].plractive) + print_talk_string(plr[i]._pName,46,60 + (row * 18),&lOffset,nColor); + row++; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define TALK_NAME_TOP 421 +#define TALK_NAME_LEFT 172 +#define TALK_NAME_WDT 61 +#define TALK_NAME_HGT (18*(MAX_PLRS-1)) + +BOOL talk_click() { + if (! talkflag) return FALSE; + + if (MouseX < TALK_NAME_LEFT) return FALSE; + if (MouseY < TALK_NAME_TOP) return FALSE; + if (MouseX > TALK_NAME_LEFT + TALK_NAME_WDT) return FALSE; + if (MouseY > TALK_NAME_TOP + TALK_NAME_HGT) return FALSE; + + for (int i = 0; i < 3; i++) talkbtndown[i] = FALSE; + talkbtndown[(MouseY - TALK_NAME_TOP) / 18] = TRUE; + + return TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void talk_release() { + if (! talkflag) return; + + for (int i = 0; i < 3; i++) talkbtndown[i] = FALSE; + + if (MouseX < TALK_NAME_LEFT) return; + if (MouseY < TALK_NAME_TOP) return; + if (MouseX > TALK_NAME_LEFT + TALK_NAME_WDT) return; + if (MouseY > TALK_NAME_TOP + TALK_NAME_HGT) return; + + int pnum = (MouseY - TALK_NAME_TOP) / 18; + for (i = 0; (i < MAX_PLRS) && (pnum != -1); i++) + //if ((i != myplr) && plr[i].plractive) pnum--; + if (i != myplr) pnum--; + if (i <= MAX_PLRS) sgbPlrTalkTbl[i - 1] = !sgbPlrTalkTbl[i - 1]; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void TalkStart() { + if (gbMaxPlayers == 1) return; + talkflag = TRUE; + talkofs = 144; + sgszTalkMsg[0] = 0; + tspin = 1; + for (int i = 0; i < 3; i++) talkbtndown[i] = FALSE; + force_redraw = FULLDRAW; + + // reset history position + sgbTalkSavePos = sgbNextTalkSave; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void TalkEnd() { + talkflag = FALSE; + talkofs = 0; + force_redraw = FULLDRAW; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void TalkSendMsg() { + + if (sgszTalkMsg[0] != 0) { + // send message to all players who have flag set + DWORD sendmask = 0; + for (int i = 0; i < MAX_PLRS; i++) + if (sgbPlrTalkTbl[i]) sendmask |= 1 << i; + NetSendString(sendmask,sgszTalkMsg); + + // save msg in history buffer if it is unique + for (i = 0; i < MAX_TALK_SAVES; i++) { + if (! strcmp(sgszTalkSaveMsg[i],sgszTalkMsg)) + break; + } + if (i >= MAX_TALK_SAVES) { + // string is unique -- save in history buffer + strcpy(sgszTalkSaveMsg[sgbNextTalkSave],sgszTalkMsg); + sgbNextTalkSave++; + sgbNextTalkSave &= MAX_TALK_SAVES - 1; + } + else { + // string is not unique -- swap curr string with non-unique + BYTE bTemp = sgbNextTalkSave - 1; + bTemp &= MAX_TALK_SAVES - 1; + if (i != bTemp) { + strcpy(sgszTalkSaveMsg[i],sgszTalkSaveMsg[bTemp]); + strcpy(sgszTalkSaveMsg[bTemp],sgszTalkMsg); + } + } + + // reset history position + sgbTalkSavePos = sgbNextTalkSave; + + // reset talk string + sgszTalkMsg[0] = 0; + } + + TalkEnd(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL Talk_wm_char(WPARAM wKey) { + if (gbMaxPlayers == 1) return FALSE; + if (! talkflag) return FALSE; + if (wKey < 32) return FALSE; + + int i = strlen(sgszTalkMsg); + if (i < (MAX_SEND_STR_LEN-2)) { + sgszTalkMsg[i] = (char) wKey; + sgszTalkMsg[i+1] = 0; + } + + return TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void talk_history(int nDelta) { + for (int i = 0; i < MAX_TALK_SAVES; i++) { + sgbTalkSavePos += nDelta; + sgbTalkSavePos &= MAX_TALK_SAVES - 1; + if (! sgszTalkSaveMsg[sgbTalkSavePos][0]) continue; + + // we found a string in the history + strcpy(sgszTalkMsg,sgszTalkSaveMsg[sgbTalkSavePos]); + break; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL Talk_wm_keydown(WPARAM wKey) { + // only in multiplayer + if (gbMaxPlayers == 1) return FALSE; + if (! talkflag) return FALSE; + + if (wKey == VK_SPACE) { + // grab keystroke so + // program doesn't get it + } + else if (wKey == VK_ESCAPE) { + TalkEnd(); + } + else if (wKey == VK_RETURN) { + TalkSendMsg(); + } + else if (wKey == VK_BACK) { + int i = strlen(sgszTalkMsg); + if (i > 0) sgszTalkMsg[i-1] = 0; + } + else if (wKey == VK_DOWN) { + talk_history(+1); + } + else if (wKey == VK_UP) { + talk_history(-1); + } + else { + return FALSE; + } + + return TRUE; +} + + +//****************************************************************** +// conversion table -- converts funky ANSI/OEM chars to ASCII +// NOTE: only '\0' is allowed to translate to zero +// map all other characters into range 32..127 +//****************************************************************** +const BYTE gbFontTransTbl[256] = { + // control characters + 0, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 0x07 + 1, 1, 1, 1, 1, 1, 1, 1, // 0x08 - 0x0f + 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 0x17 + 1, 1, 1, 1, 1, 1, 1, 1, // 0x18 - 0x1f + + // punctuation/digits + ' ', '!', '"', '#', '$', '%', '&', '\'',// 0x20 - 0x27 + '(', ')', '*', '+', ',', '-', '.', '/', // 0x28 - 0x2f + '0', '1', '2', '3', '4', '5', '6', '7', // 0x30 - 0x37 + '8', '9', ':', ';', '<', '=', '>', '?', // 0x38 - 0x3f + + // uppercase + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', // 0x40 - 0x47 + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', // 0x48 - 0x4f + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', // 0x50 - 0x57 + 'X', 'Y', 'Z', '[', '\\',']', '^', '_', // 0x58 - 0x5f + + // lowercase + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', // 0x60 - 0x67 + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', // 0x68 - 0x6f + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', // 0x70 - 0x77 + 'x', 'y', 'z', '{', '|', '}', '~', 1, // 0x78 - 0x7f + + 'C', 'u', 'e', 'a', 'a', 'a', 'a', 'c', // 0x80 - 0x87 + 'e', 'e', 'e', 'i', 'i', 'i', 'A', 'A', // 0x88 - 0x8f + 'E', 'a', 'A', 'o', 'o', 'o', 'u', 'u', // 0x90 - 0x97 + 'y', 'O', 'U', 'c', 'L', 'Y', 'P', 'f', // 0x98 - 0x9f + + 'a', 'i', 'o', 'u', 'n', 'N', 'a', 'o', // 0xa0 - 0xa7 + '?', 1, 1, 1, 1, '!', '<', '>', // 0xa8 - 0xaf + 'o', '+', '2', '3', '\'','u', 'P', '.', // 0xb0 - 0xb7 + ',', '1', '0', '>', 1, 1, 1, '?', // 0xb8 - 0xbf + + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'C', // 0xc0 - 0xc7 + 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', // 0xc8 - 0xcf + 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'X', // 0xd0 - 0xd7 + '0', 'U', 'U', 'U', 'U', 'Y', 'b', 'B', // 0xd8 - 0xdf + + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', // 0xe0 - 0xe7 + 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', // 0xe8 - 0xef + 'o', 'n', 'o', 'o', 'o', 'o', 'o', '/', // 0xf0 - 0xf7 + '0', 'u', 'u', 'u', 'u', 'y', 'b', 'y', // 0xf8 - 0xff +}; diff --git a/CONTROL.H b/CONTROL.H new file mode 100644 index 0000000..3532f8f --- /dev/null +++ b/CONTROL.H @@ -0,0 +1,149 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/CONTROL.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define SB1X1 121 +#define SB1X2 176 + +#define SB2X1 196 +#define SB2X2 251 + +#define SBY1 408 +#define SBY2 463 + +#define SBSY1 SBY1-55 +#define SBSY2 SBY2-55 + +#define TEXT_LEFT 0 +#define TEXT_CENTER 1 +#define TEXT_RIGHT 2 + +#define ICOLOR_WHITE 0 +#define ICOLOR_BLUE 1 +#define ICOLOR_RED 2 +#define ICOLOR_GOLD 3 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern BYTE *pBtmBuff; // Offscreen control panel buffer +extern BYTE *pStatusPanel; + +extern BYTE *pGBoxBuff; // Drop gold control panel buffer +extern BOOL dropGoldFlag; + +extern const BYTE fonttrans[]; +extern const BYTE fontkern[]; + +extern BOOL pinfoflag; + +extern char infostr[256]; +extern char infoclr; + +extern char tempstr[256]; + +extern BOOL drawhpflag; +extern BOOL drawmanaflag; + +extern BOOL chrflag; + +extern BOOL drawbtnflag, panbtndown; +extern BOOL panelflag; + +extern BOOL spselflag; + +extern BOOL chrbtndown; + +extern BOOL lvlbtndown; + +extern BOOL sbookflag; + +extern BOOL talkflag; + +extern int dropGoldValue; + +extern int initialDropGoldValue; + +extern int initialDropGoldIndex; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitControlPan(); +void CopyCtrlPan(int, int, int, int, int, int); +void DrawCtrlPan(); +void FreeControlPan(); + +void AddPanelString(const char *, int); +void ClearPanel(); + +void DrawHealthTop(); +void DrawHealthBar(); +void DrawManaTop(); +void DrawManaBar(); +void CalcInitBallPer(); + +BOOL InfoFit(const char *); +void DrawInfoBox(); + +void DrawSpellIcon(); +void DrawSpellList(); +void SetSpell(); +void SetupSpellSel(); +void SetSpellHK(int); +void GetSpellHK(int); + +void DrawChr(); + +void CheckLvlBtn(); +void ReleaseLvlBtn(); +void DrawLevelUpIcon(); + +void CheckPanelBtns(); +void ReleasePanelBtn(); +void DrawButtons(); +void CheckPanelInfo(); +void CheckDeadButtons(); + +void CheckChrBtns(); +void ReleaseChrBtn(); + +void DrawDurIcon(); + +void DrawPanelFont (long, long, char); + +void RedBack(); +void DrawPause(); + +void DrawSpellBook(); +void CheckSBook(); +//BOOL CheckSBookCast(); + +void TalkStart(); +void TalkEnd(); +BOOL Talk_wm_char(WPARAM wKey); +BOOL Talk_wm_keydown(WPARAM wKey); +void DrawTalkBox(); + +void PrintStringXY(int x, int y,const char * pszStr, char col); + +void DrawGoldBox(int gold); +void DropGoldType(char c); +void DropGold(int pnum, int cii); +void SetDropGoldCursor(int pnum); diff --git a/CURSOR.CPP b/CURSOR.CPP new file mode 100644 index 0000000..e9e00a5 --- /dev/null +++ b/CURSOR.CPP @@ -0,0 +1,746 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Cursor file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/CURSOR.CPP 4 2/12/97 10:48a Dbrevik2 $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "engine.h" +#include "gendung.h" +#include "control.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "objects.h" +#include "cursor.h" +#include "debug.h" +#include "scrollrt.h" +#include "inv.h" +#include "trigs.h" +#include "lighting.h" +#include "missiles.h" +#include "town.h" +#include "towners.h" +#include "quests.h" +#include "doom.h" + +/*-----------------------------------------------------------------------** +** externs +**-----------------------------------------------------------------------*/ +BOOL IsTracking(); +void savecrsr_reset(); + + +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ +int curs; +int cursW, cursH; +int icursW, icursH; +int icursW28, icursH28; +int cursmx, cursmy; +int cursmonst; +char cursobj; +char cursitem; +char cursinvitem; +char cursplr; +BYTE *pCursCels; +BYTE *pCursCels2; +static int oldcursmonst; + + +const int CursorWidth [ITEM_LAST_ID+12] = { + // Null, Glove Pointer, Identify, Repair, Recharge, Disarm, Oil, Telekenesis, Resurrect, Target, Heal Other, Watch + 0, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 23, + // Inv 1x1 + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + // Inv 1x2 + 28, 28, 28, 28, 28, 28, + // Inv 1x3 + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, + // Inv 2x2 + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, + // Inv 2x3 + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + + // New 1x1 + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + + // New 2x2 + 56, 56, + + // New 1x3 + 28, 28, 28, + + // New 2x3 + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, + + }; + +const int CursorHeight[ITEM_LAST_ID+12] = { + // Null, Glove Pointer, Identify, Repair, Recharge, Disarm, Oil, Telekenesis, Resurrect, Target, Heal Other, Watch + 0, 29, 32, 32, 32, 32, 32, 32, 32, 32, 32, 35, + // Inv 1x1 + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + // Inv 1x2 + 56, 56, 56, 56, 56, 56, + // Inv 1x3 + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, + // Inv 2x2 + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, + // Inv 2x3 + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + + 56, 56, + + 84, 84, 84, + + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, + + }; + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitCursor() { + app_assert(! pCursCels); + pCursCels = LoadFileInMemSig("Data\\Inv\\Objcurs.CEL",NULL,'CRSR'); + pCursCels2 = LoadFileInMemSig("Data\\Inv\\Objcurs2.CEL",NULL,'CRSR'); + savecrsr_reset(); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeCursor() { + DiabloFreePtr(pCursCels); + DiabloFreePtr(pCursCels2); + savecrsr_reset(); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetICursor(int i) { + icursW = CursorWidth[i]; + icursH = CursorHeight[i]; + icursW28 = icursW / 28; + icursH28 = icursH / 28; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetCursor(int i) { + curs = i; + cursW = CursorWidth[curs]; + cursH = CursorHeight[curs]; + SetICursor(i); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void NewCursor(int i) { + SetCursor(i); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitLevelCursor() { + SetCursor(GLOVE_CURS); + cursmx = ViewX; + cursmy = ViewY; + oldcursmonst = -1; + cursmonst = -1; + cursobj = -1; + cursitem = -1; + cursplr = -1; + savecrsr_reset(); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CheckTown() { + for (int i = 0; i < nummissiles; i++) { + int mx = missileactive[i]; + if (missile[mx]._mitype == MIT_TOWN) { + if (((cursmx == missile[mx]._mix - 1) && (cursmy == missile[mx]._miy)) || + ((cursmx == missile[mx]._mix) && (cursmy == missile[mx]._miy - 1)) || + ((cursmx == missile[mx]._mix - 1) && (cursmy == missile[mx]._miy - 1)) || + ((cursmx == missile[mx]._mix - 2) && (cursmy == missile[mx]._miy - 1)) || + ((cursmx == missile[mx]._mix - 2) && (cursmy == missile[mx]._miy - 2)) || + ((cursmx == missile[mx]._mix - 1) && (cursmy == missile[mx]._miy - 2)) || + ((cursmx == missile[mx]._mix) && (cursmy == missile[mx]._miy))) { + trigflag = TRUE; + ClearPanel(); + strcpy(infostr, "Town Portal"); + sprintf(tempstr, "from %s", plr[missile[mx]._misource]._pName); + AddPanelString(tempstr, TEXT_CENTER); + cursmx = missile[mx]._mix; + cursmy = missile[mx]._miy; + } + } + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckRportal() { + for (int i = 0; i < nummissiles; i++) { + int mx = missileactive[i]; + if (missile[mx]._mitype == MIT_RPORTAL) { + if (((cursmx == missile[mx]._mix - 1) && (cursmy == missile[mx]._miy)) || + ((cursmx == missile[mx]._mix) && (cursmy == missile[mx]._miy - 1)) || + ((cursmx == missile[mx]._mix - 1) && (cursmy == missile[mx]._miy - 1)) || + ((cursmx == missile[mx]._mix - 2) && (cursmy == missile[mx]._miy - 1)) || + ((cursmx == missile[mx]._mix - 2) && (cursmy == missile[mx]._miy - 2)) || + ((cursmx == missile[mx]._mix - 1) && (cursmy == missile[mx]._miy - 2)) || + ((cursmx == missile[mx]._mix) && (cursmy == missile[mx]._miy))) { + trigflag = TRUE; + ClearPanel(); + strcpy(infostr, "Portal to"); + if (!(setlevel)) strcpy(tempstr, "The Unholy Altar"); + else strcpy(tempstr, "level 15"); + AddPanelString(tempstr, TEXT_CENTER); + cursmx = missile[mx]._mix; + cursmy = missile[mx]._miy; + } + } + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckCursMove() { + int mx,my; + int offsetx,offsety,gridx,gridy; + char co,ci,cp; + int cm; + BOOL minusy, plusx; + BOOL lefthalf; + int newMouseX; + int newMouseY; + + int pvar6tmp, pvar7tmp; + long xo, yo; + + newMouseX = MouseX; + newMouseY = MouseY; + + // Convert screen point to map position + if (chrflag || questlog) { + if (newMouseX >= TOTALX/4) newMouseX -= TOTALX/4; + else newMouseX = 0; + } + else if (invflag || sbookflag) { + if (newMouseX <= TOTALX/2) newMouseX += TOTALX/4; + else newMouseX = 0; + } + + // if the mouse outside the gamemap area, but + // the mouse is in tracking mode, then pretend + // that the mouse is actually in the gamemap + if (newMouseY > 351 && IsTracking()) + newMouseY = 351; + + if (!svgamode) + { + newMouseX >>= 1; + newMouseY >>= 1; + } + + // Offset mouse position by the scroll offset, to align it with tile grid + newMouseX -= ScrollInfo._sxoff; + newMouseY -= ScrollInfo._syoff; + + // THIS IS A HACK + // Here, we predict the next scroll increment, so the mouse position is + // where it would be during the next frame. + // This is a fix -- without this, the following sometimes happens: + // The user holds down the mouse button, and the walk path alternates + // between two different directions, because the cursor is sampled just before + // player reaches his next square. + xo = plr[myplr]._pVar6 >> 8; + yo = plr[myplr]._pVar7 >> 8; + pvar6tmp = plr[myplr]._pVar6 + plr[myplr]._pxvel; + pvar7tmp = plr[myplr]._pVar7 + plr[myplr]._pyvel; + xo -= (pvar6tmp >> 8); + yo -= (pvar7tmp >> 8); + if ((myplr == myplr) && (ScrollInfo._sdir != SCRL_NONE)) { + newMouseX -= xo; + newMouseY -= yo; + } + + if (newMouseX < 0) + newMouseX = 0; + if (newMouseX >= TOTALX) + newMouseX = TOTALX; + if (newMouseY < 0) + newMouseY = 0; + if (newMouseY >= TOTALY) + newMouseY = TOTALY; + + // Calculate position in square grid + gridx = newMouseX >> 6; + gridy = newMouseY >> 5; + + // Calculate offset in that square + offsetx = newMouseX & 63; + offsety = newMouseY & 31; + + // Convert from square grid to diamond grid + mx = gridx + gridy + ViewX - (svgamode ? 10:5); + my = gridy - gridx + ViewY; + + if (minusy = (offsety < (offsetx >> 1))) { + my--; + } + if (plusx = (offsety >= (32 - (offsetx >> 1)))) { + mx++; + } + + if (mx < 0) mx = 0; + if (mx >= DMAXX) mx = DMAXX - 1; + if (my < 0) my = 0; + if (my >= DMAXY) my = DMAXY - 1; + + lefthalf = (minusy && plusx) || ((minusy || plusx) && offsetx < 32); + + oldcursmonst = cursmonst; + cursmonst = -1; + cursobj = -1; + cursitem = -1; + if (cursinvitem != -1) + drawsbarflag = TRUE; + cursinvitem = -1; + cursplr = -1; + uitemflag = FALSE; + panelflag = FALSE; + trigflag = FALSE; + + if (plr[myplr]._pInvincible) return; // Dead? + + // Skip if I have an item + if ((curs >= ICSTART) || (spselflag)) { + cursmx = mx; + cursmy = my; + return; + } + + if (MouseY > 352) { + CheckPanelInfo(); + return; + } + + if (drawmapofdoom) return; + + if ((invflag) && (MouseX > 320)) { + cursinvitem = CheckInvHLight(); + return; + } + if (sbookflag && (MouseX > 320)) + return; + + if ((chrflag || questlog) && (MouseX < 320)) return; + + if (leveltype != 0) { + if (oldcursmonst != -1) { + if (!lefthalf && (dMonster[mx+2][my+1] != 0) && (dFlags[mx+2][my+1] & BFLAG_VISIBLE)) { + if (dMonster[mx+2][my+1] > 0) cm = dMonster[mx+2][my+1] - 1; + else cm = -(dMonster[mx+2][my+1] + 1); + if (cm == oldcursmonst) { + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_TOP)) { + cursmx = mx + 1; + cursmy = my + 2; + cursmonst = cm; + } + } + } + if (lefthalf && (dMonster[mx+1][my+2] != 0) && (dFlags[mx+1][my+2] & BFLAG_VISIBLE)) { + if (dMonster[mx+1][my+2] > 0) cm = dMonster[mx+1][my+2] - 1; + else cm = -(dMonster[mx+1][my+2] + 1); + if (cm == oldcursmonst) { + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_TOP)) { + cursmx = mx + 1; + cursmy = my + 2; + cursmonst = cm; + } + } + } + if ((dMonster[mx+2][my+2] != 0) && (dFlags[mx+2][my+2] & BFLAG_VISIBLE)) { + if (dMonster[mx+2][my+2] > 0) cm = dMonster[mx+2][my+2] - 1; + else cm = -(dMonster[mx+2][my+2] + 1); + if (cm == oldcursmonst) { + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_TOP)) { + cursmx = mx + 2; + cursmy = my + 2; + cursmonst = cm; + } + } + } + if (!lefthalf && (dMonster[mx+1][my] != 0) && (dFlags[mx+1][my] & BFLAG_VISIBLE)) { + if (dMonster[mx+1][my] > 0) cm = dMonster[mx+1][my] - 1; + else cm = -(dMonster[mx+1][my] + 1); + if (cm == oldcursmonst) { + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_MID)) { + cursmx = mx + 1; + cursmy = my; + cursmonst = cm; + } + } + } + if (lefthalf && (dMonster[mx][my+1] != 0) && (dFlags[mx][my+1] & BFLAG_VISIBLE)) { + if (dMonster[mx][my+1] > 0) cm = dMonster[mx][my+1] - 1; + else cm = -(dMonster[mx][my+1] + 1); + if (cm == oldcursmonst) { + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_MID)) { + cursmx = mx; + cursmy = my + 1; + cursmonst = cm; + } + } + } + if ((dMonster[mx][my] != 0) && (dFlags[mx][my] & BFLAG_VISIBLE)) { + if (dMonster[mx][my] > 0) cm = dMonster[mx][my] - 1; + else cm = -(dMonster[mx][my] + 1); + if (cm == oldcursmonst) { + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_FLR)) { + cursmx = mx; + cursmy = my; + cursmonst = cm; + } + } + } + if ((dMonster[mx+1][my+1] != 0) && (dFlags[mx+1][my+1] & BFLAG_VISIBLE)) { + if (dMonster[mx+1][my+1] > 0) cm = dMonster[mx+1][my+1] - 1; + else cm = -(dMonster[mx+1][my+1] + 1); + if (cm == oldcursmonst) { + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_MID)) { + cursmx = mx + 1; + cursmy = my + 1; + cursmonst = cm; + } + } + } + if (cursmonst != -1) { + if (monster[cursmonst]._mFlags & MFLAG_INVISIBLE) { + cursmonst = -1; + cursmx = mx; + cursmy = my; + } + } + if ((cursmonst != -1) + && ((monster[cursmonst]._mFlags & MFLAG_MKILLER) != 0) + && ((monster[cursmonst]._mFlags & MFLAG_BERSERK) == 0) + ) cursmonst = -1; + + if (cursmonst != -1) return; + } + if (!lefthalf && (dMonster[mx+2][my+1] != 0) && (dFlags[mx+2][my+1] & BFLAG_VISIBLE)) { + if (dMonster[mx+2][my+1] > 0) cm = dMonster[mx+2][my+1] - 1; + else cm = -(dMonster[mx+2][my+1] + 1); + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_TOP)) { + cursmx = mx + 2; + cursmy = my + 1; + cursmonst = cm; + } + } + if (lefthalf && (dMonster[mx+1][my+2] != 0) && (dFlags[mx+1][my+2] & BFLAG_VISIBLE)) { + if (dMonster[mx+1][my+2] > 0) cm = dMonster[mx+1][my+2] - 1; + else cm = -(dMonster[mx+1][my+2] + 1); + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_TOP)) { + cursmx = mx + 1; + cursmy = my + 2; + cursmonst = cm; + } + } + if ((dMonster[mx+2][my+2] != 0) && (dFlags[mx+2][my+2] & BFLAG_VISIBLE)) { + if (dMonster[mx+2][my+2] > 0) cm = dMonster[mx+2][my+2] - 1; + else cm = -(dMonster[mx+2][my+2] + 1); + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_TOP)) { + cursmx = mx + 2; + cursmy = my + 2; + cursmonst = cm; + } + } + if (!lefthalf && (dMonster[mx+1][my] != 0) && (dFlags[mx+1][my] & BFLAG_VISIBLE)) { + if (dMonster[mx+1][my] > 0) cm = dMonster[mx+1][my] - 1; + else cm = -(dMonster[mx+1][my] + 1); + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_MID)) { + cursmx = mx + 1; + cursmy = my; + cursmonst = cm; + } + } + if (lefthalf && (dMonster[mx][my+1] != 0) && (dFlags[mx][my+1] & BFLAG_VISIBLE)) { + if (dMonster[mx][my+1] > 0) cm = dMonster[mx][my+1] - 1; + else cm = -(dMonster[mx][my+1] + 1); + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_MID)) { + cursmx = mx; + cursmy = my + 1; + cursmonst = cm; + } + } + if ((dMonster[mx][my] != 0) && (dFlags[mx][my] & BFLAG_VISIBLE)) { + if (dMonster[mx][my] > 0) cm = dMonster[mx][my] - 1; + else cm = -(dMonster[mx][my] + 1); + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_FLR)) { + cursmx = mx; + cursmy = my; + cursmonst = cm; + } + } + if ((dMonster[mx+1][my+1] != 0) && (dFlags[mx+1][my+1] & BFLAG_VISIBLE)) { + if (dMonster[mx+1][my+1] > 0) cm = dMonster[mx+1][my+1] - 1; + else cm = -(dMonster[mx+1][my+1] + 1); + if (((monster[cm]._mhitpoints >> HP_SHIFT) > 0) && (monster[cm].MData->mSelFlag & MSEL_MID)) { + cursmx = mx + 1; + cursmy = my + 1; + cursmonst = cm; + } + } + if (cursmonst != -1) { + if (monster[cursmonst]._mFlags & MFLAG_INVISIBLE) { + cursmonst = -1; + cursmx = mx; + cursmy = my; + } + } + if ((cursmonst != -1) + && ((monster[cursmonst]._mFlags & MFLAG_MKILLER) != 0) + && ((monster[cursmonst]._mFlags & MFLAG_BERSERK) == 0) + ) cursmonst = -1; + } else { + if (!lefthalf && (dMonster[mx+1][my] > 0)) { + cursmonst = dMonster[mx+1][my] - 1; + cursmx = mx + 1; + cursmy = my; + } + if (lefthalf && (dMonster[mx][my+1] > 0)) { + cursmonst = dMonster[mx][my+1] - 1; + cursmx = mx; + cursmy = my + 1; + } + if (dMonster[mx][my] > 0) { + cursmonst = dMonster[mx][my] - 1; + cursmx = mx; + cursmy = my; + } + if (dMonster[mx+1][my+1] > 0) { + cursmonst = dMonster[mx+1][my+1] - 1; + cursmx = mx + 1; + cursmy = my + 1; + } + if (!towner[cursmonst]._tSelFlag) cursmonst = -1; + } + + if (cursmonst == -1) { + if (!lefthalf && (dPlayer[mx+1][my] != 0)) { + if (dPlayer[mx+1][my] > 0) cp = dPlayer[mx+1][my] - 1; + else cp = -(dPlayer[mx+1][my] + 1); + if ((cp != myplr) && (plr[cp]._pHitPoints != 0)) { + cursmx = mx + 1; + cursmy = my; + cursplr = cp; + } + } + if (lefthalf && (dPlayer[mx][my+1] != 0)) { + if (dPlayer[mx][my+1] > 0) cp = dPlayer[mx][my+1] - 1; + else cp = -(dPlayer[mx][my+1] + 1); + if ((cp != myplr) && (plr[cp]._pHitPoints != 0)) { + cursmx = mx; + cursmy = my + 1; + cursplr = cp; + } + } + if (dPlayer[mx][my] != 0) { + if (dPlayer[mx][my] > 0) cp = dPlayer[mx][my] - 1; + else cp = -(dPlayer[mx][my] + 1); + if (cp != myplr) { + cursmx = mx; + cursmy = my; + cursplr = cp; + } + } + if (dFlags[mx][my] & BFLAG_DEADPLR) { + for (int i = 0; i < MAX_PLRS; i++) { + if ((plr[i]._px == mx) && (plr[i]._py == my) && (i != myplr)) { + cursmx = mx; + cursmy = my; + cursplr = i; + } + } + } + + if (curs == RESURRECT_CURS) { + for (int j = -1; j < 2; j++) { + for (int k = -1; k < 2; k++) { + if (dFlags[mx+j][my+k] & BFLAG_DEADPLR) { + for (int i = 0; i < MAX_PLRS; i++) { + if ((plr[i]._px == mx+j) && (plr[i]._py == my+k) && (i != myplr)) { + cursmx = mx+j; + cursmy = my+k; + cursplr = i; + } + } + } + } + } + } + + if (dPlayer[mx+1][my+1] != 0) { + if (dPlayer[mx+1][my+1] > 0) cp = dPlayer[mx+1][my+1] - 1; + else cp = -(dPlayer[mx+1][my+1] + 1); + if ((cp != myplr) && (plr[cp]._pHitPoints != 0)) { + cursmx = mx + 1; + cursmy = my + 1; + cursplr = cp; + } + } + } + + if ((cursmonst == -1) && (cursplr == -1)) { + if (!lefthalf && (dObject[mx+1][my] != 0)) { + if (dObject[mx+1][my] > 0) co = dObject[mx+1][my] - 1; + else co = -(dObject[mx+1][my] + 1); + if (object[co]._oSelFlag >= OSEL_TOP) { + cursmx = mx + 1; + cursmy = my; + cursobj = co; + } + } + if (lefthalf && (dObject[mx][my+1] != 0)) { + if (dObject[mx][my+1] > 0) co = dObject[mx][my+1] - 1; + else co = -(dObject[mx][my+1] + 1); + if (object[co]._oSelFlag >= OSEL_TOP) { + cursmx = mx; + cursmy = my + 1; + cursobj = co; + } + } + if (dObject[mx][my] != 0) { + if (dObject[mx][my] > 0) co = dObject[mx][my] - 1; + else co = -(dObject[mx][my] + 1); + if ((object[co]._oSelFlag == OSEL_FLR) || (object[co]._oSelFlag == OSEL_ALL)) { + cursmx = mx; + cursmy = my; + cursobj = co; + } + } + if (dObject[mx+1][my+1] != 0) { + if (dObject[mx+1][my+1] > 0) co = dObject[mx+1][my+1] - 1; + else co = -(dObject[mx+1][my+1] + 1); + if (object[co]._oSelFlag >= OSEL_TOP) { + cursmx = mx + 1; + cursmy = my + 1; + cursobj = co; + } + } + } + + if ((cursplr == -1) && (cursobj == -1) && (cursmonst == -1)) { + if (!lefthalf && (dItem[mx+1][my] > 0)) { + ci = dItem[mx+1][my] - 1; + if (item[ci]._iSelFlag >= ISEL_TOP) { + cursmx = mx + 1; + cursmy = my; + cursitem = ci; + } + } + if (lefthalf && (dItem[mx][my+1] > 0)) { + ci = dItem[mx][my+1] - 1; + if (item[ci]._iSelFlag >= ISEL_TOP) { + cursmx = mx; + cursmy = my + 1; + cursitem = ci; + } + } + if (dItem[mx][my] > 0) { + ci = dItem[mx][my] - 1; + if ((item[ci]._iSelFlag == ISEL_FLR) || (item[ci]._iSelFlag == ISEL_ALL)) { + cursmx = mx; + cursmy = my; + cursitem = ci; + } + } + if (dItem[mx+1][my+1] > 0) { + ci = dItem[mx+1][my+1] - 1; + if (item[ci]._iSelFlag >= ISEL_TOP) { + cursmx = mx + 1; + cursmy = my + 1; + cursitem = ci; + } + } + if (cursitem == -1) { + cursmx = mx; + cursmy = my; + CheckTrigForce(); + CheckTown(); + CheckRportal(); + } + } + if (curs == IDENTIFY_CURS) { + cursobj = -1; + cursmonst = -1; + cursitem = -1; + cursmx = mx; + cursmy = my; + } + + if ((cursmonst != -1) + && ((monster[cursmonst]._mFlags & MFLAG_MKILLER) != 0) + && ((monster[cursmonst]._mFlags & MFLAG_BERSERK) == 0) + ) cursmonst = -1; +} diff --git a/CURSOR.H b/CURSOR.H new file mode 100644 index 0000000..aa6cff4 --- /dev/null +++ b/CURSOR.H @@ -0,0 +1,68 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/CURSOR.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define NO_CURSOR 0 +#define VIEW_CURSOR 1 + +#define GLOVE_CURS 1 +#define IDENTIFY_CURS 2 +#define REPAIR_CURS 3 +#define RECHARGE_CURS 4 +#define DISARM_CURS 5 +#define OIL_CURS 6 +#define TELE_CURS 7 +#define RESURRECT_CURS 8 +#define TARGET_CURS 9 +#define HEALOTHER_CURS 10 +#define WATCH_CURS 11 +#define ICSTART 12 // Cursor where items start at +#define ICLAST 179 // last of the original cursors + +#define MSEL_NONE 0 // No selection (not used) +#define MSEL_FLR 1 // Floor / single square +#define MSEL_MID 2 // Square above monster base +#define MSEL_REG 3 // Normal floor + 1 square above +#define MSEL_TOP 4 // Square 2 above monster base +#define MSEL_FLY 6 // Square 1 and 2 above base (gargolye, bat) +#define MSEL_BIG 7 // Large monsters floor, 1, and 2 squares + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern int curs; +extern int cursW, cursH; +extern int icursW, icursH; +extern int icursW28, icursH28; +extern int cursmx, cursmy; +extern int cursmonst; +extern char cursobj; +extern char cursitem; +extern char cursinvitem; +extern char cursplr; +extern BYTE *pCursCels; +extern BYTE *pCursCels2; +extern const int CursorWidth[]; +extern const int CursorHeight[]; + + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void InitCursor(); +void InitLevelCursor(); +void CheckCursMove(); +void SetICursor(int i); +void SetCursor(int i); +void NewCursor(int i); diff --git a/D3DTYPES.H b/D3DTYPES.H new file mode 100644 index 0000000..81acb76 --- /dev/null +++ b/D3DTYPES.H @@ -0,0 +1,957 @@ +/*==========================================================================; + * + * Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved. + * + * File: d3dtypes.h + * Content: Direct3D types include file + * + ***************************************************************************/ + +#ifndef _D3DTYPES_H_ +#define _D3DTYPES_H_ + +// pjw commented out -- win32 out to be defined! +// #ifndef WIN32 +//#include "subwtype.h" +//#else +#include +//#endif + +#include "ddraw.h" + +#pragma pack(4) + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* D3DVALUE is the fundamental Direct3D fractional data type */ + +#define D3DVALP(val, prec) ((float)(val)) +#define D3DVAL(val) ((float)(val)) +typedef float D3DVALUE, *LPD3DVALUE; +#define D3DDivide(a, b) (float)((double) (a) / (double) (b)) +#define D3DMultiply(a, b) ((a) * (b)) + +typedef LONG D3DFIXED; + +#ifndef RGB_MAKE +/* + * Format of CI colors is + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | alpha | color index | fraction | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +#define CI_GETALPHA(ci) ((ci) >> 24) +#define CI_GETINDEX(ci) (((ci) >> 8) & 0xffff) +#define CI_GETFRACTION(ci) ((ci) & 0xff) +#define CI_ROUNDINDEX(ci) CI_GETINDEX((ci) + 0x80) +#define CI_MASKALPHA(ci) ((ci) & 0xffffff) +#define CI_MAKE(a, i, f) (((a) << 24) | ((i) << 8) | (f)) + +/* + * Format of RGBA colors is + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | alpha | red | green | blue | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +#define RGBA_GETALPHA(rgb) ((rgb) >> 24) +#define RGBA_GETRED(rgb) (((rgb) >> 16) & 0xff) +#define RGBA_GETGREEN(rgb) (((rgb) >> 8) & 0xff) +#define RGBA_GETBLUE(rgb) ((rgb) & 0xff) +#define RGBA_MAKE(r, g, b, a) ((D3DCOLOR) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))) + +/* D3DRGB and D3DRGBA may be used as initialisers for D3DCOLORs + * The float values must be in the range 0..1 + */ +#define D3DRGB(r, g, b) \ + (0xff000000L | ( ((long)((r) * 255)) << 16) | (((long)((g) * 255)) << 8) | (long)((b) * 255)) +#define D3DRGBA(r, g, b, a) \ + ( (((long)((a) * 255)) << 24) | (((long)((r) * 255)) << 16) \ + | (((long)((g) * 255)) << 8) | (long)((b) * 255) \ + ) + +/* + * Format of RGB colors is + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ignored | red | green | blue | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +#define RGB_GETRED(rgb) (((rgb) >> 16) & 0xff) +#define RGB_GETGREEN(rgb) (((rgb) >> 8) & 0xff) +#define RGB_GETBLUE(rgb) ((rgb) & 0xff) +#define RGBA_SETALPHA(rgba, x) (((x) << 24) | ((rgba) & 0x00ffffff)) +#define RGB_MAKE(r, g, b) ((D3DCOLOR) (((r) << 16) | ((g) << 8) | (b))) +#define RGBA_TORGB(rgba) ((D3DCOLOR) ((rgba) & 0xffffff)) +#define RGB_TORGBA(rgb) ((D3DCOLOR) ((rgb) | 0xff000000)) + +#endif + +/* + * Flags for Enumerate functions + */ + +/* + * Stop the enumeration + */ +#define D3DENUMRET_CANCEL DDENUMRET_CANCEL + +/* + * Continue the enumeration + */ +#define D3DENUMRET_OK DDENUMRET_OK + +typedef HRESULT (WINAPI* LPD3DVALIDATECALLBACK)(LPVOID lpUserArg, DWORD dwOffset); +typedef HRESULT (WINAPI* LPD3DENUMTEXTUREFORMATSCALLBACK)(LPDDSURFACEDESC lpDdsd, LPVOID lpContext); + +typedef DWORD D3DCOLOR, D3DCOLOR, *LPD3DCOLOR; + +typedef DWORD D3DMATERIALHANDLE, *LPD3DMATERIALHANDLE; +typedef DWORD D3DTEXTUREHANDLE, *LPD3DTEXTUREHANDLE; +typedef DWORD D3DMATRIXHANDLE, *LPD3DMATRIXHANDLE; + +typedef struct _D3DCOLORVALUE { + union { + D3DVALUE r; + D3DVALUE dvR; + }; + union { + D3DVALUE g; + D3DVALUE dvG; + }; + union { + D3DVALUE b; + D3DVALUE dvB; + }; + union { + D3DVALUE a; + D3DVALUE dvA; + }; +} D3DCOLORVALUE; + +typedef struct _D3DRECT { + union { + LONG x1; + LONG lX1; + }; + union { + LONG y1; + LONG lY1; + }; + union { + LONG x2; + LONG lX2; + }; + union { + LONG y2; + LONG lY2; + }; +} D3DRECT, *LPD3DRECT; + +typedef struct _D3DVECTOR { + union { + D3DVALUE x; + D3DVALUE dvX; + }; + union { + D3DVALUE y; + D3DVALUE dvY; + }; + union { + D3DVALUE z; + D3DVALUE dvZ; + }; +} D3DVECTOR, *LPD3DVECTOR; + + +/* + * Vertex data types supported in an ExecuteBuffer. + */ + +/* + * Homogeneous vertices + */ + +typedef struct _D3DHVERTEX { + DWORD dwFlags; /* Homogeneous clipping flags */ + union { + D3DVALUE hx; + D3DVALUE dvHX; + }; + union { + D3DVALUE hy; + D3DVALUE dvHY; + }; + union { + D3DVALUE hz; + D3DVALUE dvHZ; + }; +} D3DHVERTEX, *LPD3DHVERTEX; + +/* + * Transformed/lit vertices + */ +typedef struct _D3DTLVERTEX { + union { + D3DVALUE sx; /* Screen coordinates */ + D3DVALUE dvSX; + }; + union { + D3DVALUE sy; + D3DVALUE dvSY; + }; + union { + D3DVALUE sz; + D3DVALUE dvSZ; + }; + union { + D3DVALUE rhw; /* Reciprocal of homogeneous w */ + D3DVALUE dvRHW; + }; + union { + D3DCOLOR color; /* Vertex color */ + D3DCOLOR dcColor; + }; + union { + D3DCOLOR specular; /* Specular component of vertex */ + D3DCOLOR dcSpecular; + }; + union { + D3DVALUE tu; /* Texture coordinates */ + D3DVALUE dvTU; + }; + union { + D3DVALUE tv; + D3DVALUE dvTV; + }; +} D3DTLVERTEX, *LPD3DTLVERTEX; + +/* + * Untransformed/lit vertices + */ +typedef struct _D3DLVERTEX { + union { + D3DVALUE x; /* Homogeneous coordinates */ + D3DVALUE dvX; + }; + union { + D3DVALUE y; + D3DVALUE dvY; + }; + union { + D3DVALUE z; + D3DVALUE dvZ; + }; + DWORD dwReserved; + union { + D3DCOLOR color; /* Vertex color */ + D3DCOLOR dcColor; + }; + union { + D3DCOLOR specular; /* Specular component of vertex */ + D3DCOLOR dcSpecular; + }; + union { + D3DVALUE tu; /* Texture coordinates */ + D3DVALUE dvTU; + }; + union { + D3DVALUE tv; + D3DVALUE dvTV; + }; +} D3DLVERTEX, *LPD3DLVERTEX; + +/* + * Untransformed/unlit vertices + */ + +typedef struct _D3DVERTEX { + union { + D3DVALUE x; /* Homogeneous coordinates */ + D3DVALUE dvX; + }; + union { + D3DVALUE y; + D3DVALUE dvY; + }; + union { + D3DVALUE z; + D3DVALUE dvZ; + }; + union { + D3DVALUE nx; /* Normal */ + D3DVALUE dvNX; + }; + union { + D3DVALUE ny; + D3DVALUE dvNY; + }; + union { + D3DVALUE nz; + D3DVALUE dvNZ; + }; + union { + D3DVALUE tu; /* Texture coordinates */ + D3DVALUE dvTU; + }; + union { + D3DVALUE tv; + D3DVALUE dvTV; + }; +} D3DVERTEX, *LPD3DVERTEX; + +/* + * Matrix, viewport, and tranformation structures and definitions. + */ + +typedef struct _D3DMATRIX { + D3DVALUE _11, _12, _13, _14; + D3DVALUE _21, _22, _23, _24; + D3DVALUE _31, _32, _33, _34; + D3DVALUE _41, _42, _43, _44; +} D3DMATRIX, *LPD3DMATRIX; + +typedef struct _D3DVIEWPORT { + DWORD dwSize; + DWORD dwX; + DWORD dwY; /* Top left */ + DWORD dwWidth; + DWORD dwHeight; /* Dimensions */ + D3DVALUE dvScaleX; /* Scale homogeneous to screen */ + D3DVALUE dvScaleY; /* Scale homogeneous to screen */ + D3DVALUE dvMaxX; /* Min/max homogeneous x coord */ + D3DVALUE dvMaxY; /* Min/max homogeneous y coord */ + D3DVALUE dvMinZ; + D3DVALUE dvMaxZ; /* Min/max homogeneous z coord */ +} D3DVIEWPORT, *LPD3DVIEWPORT; + +/* + * Values for clip fields. + */ +#define D3DCLIP_LEFT 0x00000001L +#define D3DCLIP_RIGHT 0x00000002L +#define D3DCLIP_TOP 0x00000004L +#define D3DCLIP_BOTTOM 0x00000008L +#define D3DCLIP_FRONT 0x00000010L +#define D3DCLIP_BACK 0x00000020L +#define D3DCLIP_GEN0 0x00000040L +#define D3DCLIP_GEN1 0x00000080L +#define D3DCLIP_GEN2 0x00000100L +#define D3DCLIP_GEN3 0x00000200L +#define D3DCLIP_GEN4 0x00000400L +#define D3DCLIP_GEN5 0x00000800L + +/* + * Values for d3d status. + */ +#define D3DSTATUS_CLIPUNIONLEFT D3DCLIP_LEFT +#define D3DSTATUS_CLIPUNIONRIGHT D3DCLIP_RIGHT +#define D3DSTATUS_CLIPUNIONTOP D3DCLIP_TOP +#define D3DSTATUS_CLIPUNIONBOTTOM D3DCLIP_BOTTOM +#define D3DSTATUS_CLIPUNIONFRONT D3DCLIP_FRONT +#define D3DSTATUS_CLIPUNIONBACK D3DCLIP_BACK +#define D3DSTATUS_CLIPUNIONGEN0 D3DCLIP_GEN0 +#define D3DSTATUS_CLIPUNIONGEN1 D3DCLIP_GEN1 +#define D3DSTATUS_CLIPUNIONGEN2 D3DCLIP_GEN2 +#define D3DSTATUS_CLIPUNIONGEN3 D3DCLIP_GEN3 +#define D3DSTATUS_CLIPUNIONGEN4 D3DCLIP_GEN4 +#define D3DSTATUS_CLIPUNIONGEN5 D3DCLIP_GEN5 + +#define D3DSTATUS_CLIPINTERSECTIONLEFT 0x00001000L +#define D3DSTATUS_CLIPINTERSECTIONRIGHT 0x00002000L +#define D3DSTATUS_CLIPINTERSECTIONTOP 0x00004000L +#define D3DSTATUS_CLIPINTERSECTIONBOTTOM 0x00008000L +#define D3DSTATUS_CLIPINTERSECTIONFRONT 0x00010000L +#define D3DSTATUS_CLIPINTERSECTIONBACK 0x00020000L +#define D3DSTATUS_CLIPINTERSECTIONGEN0 0x00040000L +#define D3DSTATUS_CLIPINTERSECTIONGEN1 0x00080000L +#define D3DSTATUS_CLIPINTERSECTIONGEN2 0x00100000L +#define D3DSTATUS_CLIPINTERSECTIONGEN3 0x00200000L +#define D3DSTATUS_CLIPINTERSECTIONGEN4 0x00400000L +#define D3DSTATUS_CLIPINTERSECTIONGEN5 0x00800000L +#define D3DSTATUS_ZNOTVISIBLE 0x01000000L + +#define D3DSTATUS_CLIPUNIONALL ( \ + D3DSTATUS_CLIPUNIONLEFT | \ + D3DSTATUS_CLIPUNIONRIGHT | \ + D3DSTATUS_CLIPUNIONTOP | \ + D3DSTATUS_CLIPUNIONBOTTOM | \ + D3DSTATUS_CLIPUNIONFRONT | \ + D3DSTATUS_CLIPUNIONBACK | \ + D3DSTATUS_CLIPUNIONGEN0 | \ + D3DSTATUS_CLIPUNIONGEN1 | \ + D3DSTATUS_CLIPUNIONGEN2 | \ + D3DSTATUS_CLIPUNIONGEN3 | \ + D3DSTATUS_CLIPUNIONGEN4 | \ + D3DSTATUS_CLIPUNIONGEN5 \ + ) + +#define D3DSTATUS_CLIPINTERSECTIONALL ( \ + D3DSTATUS_CLIPINTERSECTIONLEFT | \ + D3DSTATUS_CLIPINTERSECTIONRIGHT | \ + D3DSTATUS_CLIPINTERSECTIONTOP | \ + D3DSTATUS_CLIPINTERSECTIONBOTTOM | \ + D3DSTATUS_CLIPINTERSECTIONFRONT | \ + D3DSTATUS_CLIPINTERSECTIONBACK | \ + D3DSTATUS_CLIPINTERSECTIONGEN0 | \ + D3DSTATUS_CLIPINTERSECTIONGEN1 | \ + D3DSTATUS_CLIPINTERSECTIONGEN2 | \ + D3DSTATUS_CLIPINTERSECTIONGEN3 | \ + D3DSTATUS_CLIPINTERSECTIONGEN4 | \ + D3DSTATUS_CLIPINTERSECTIONGEN5 \ + ) + +#define D3DSTATUS_DEFAULT ( \ + D3DSTATUS_CLIPINTERSECTIONALL | \ + D3DSTATUS_ZNOTVISIBLE) + + +/* + * Options for direct transform calls + */ +#define D3DTRANSFORM_CLIPPED 0x00000001l +#define D3DTRANSFORM_UNCLIPPED 0x00000002l + +typedef struct _D3DTRANSFORMDATA { + DWORD dwSize; + LPVOID lpIn; /* Input vertices */ + DWORD dwInSize; /* Stride of input vertices */ + LPVOID lpOut; /* Output vertices */ + DWORD dwOutSize; /* Stride of output vertices */ + LPD3DHVERTEX lpHOut; /* Output homogeneous vertices */ + DWORD dwClip; /* Clipping hint */ + DWORD dwClipIntersection; + DWORD dwClipUnion; /* Union of all clip flags */ + D3DRECT drExtent; /* Extent of transformed vertices */ +} D3DTRANSFORMDATA, *LPD3DTRANSFORMDATA; + +/* + * Structure defining position and direction properties for lighting. + */ +typedef struct _D3DLIGHTINGELEMENT { + D3DVECTOR dvPosition; /* Lightable point in model space */ + D3DVECTOR dvNormal; /* Normalised unit vector */ +} D3DLIGHTINGELEMENT, *LPD3DLIGHTINGELEMENT; + +/* + * Structure defining material properties for lighting. + */ +typedef struct _D3DMATERIAL { + DWORD dwSize; + union { + D3DCOLORVALUE diffuse; /* Diffuse color RGBA */ + D3DCOLORVALUE dcvDiffuse; + }; + union { + D3DCOLORVALUE ambient; /* Ambient color RGB */ + D3DCOLORVALUE dcvAmbient; + }; + union { + D3DCOLORVALUE specular; /* Specular 'shininess' */ + D3DCOLORVALUE dcvSpecular; + }; + union { + D3DCOLORVALUE emissive; /* Emissive color RGB */ + D3DCOLORVALUE dcvEmissive; + }; + union { + D3DVALUE power; /* Sharpness if specular highlight */ + D3DVALUE dvPower; + }; + D3DTEXTUREHANDLE hTexture; /* Handle to texture map */ + DWORD dwRampSize; +} D3DMATERIAL, *LPD3DMATERIAL; + +typedef enum _D3DLIGHTTYPE { + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + D3DLIGHT_PARALLELPOINT = 4, + D3DLIGHT_GLSPOT = 5, +} D3DLIGHTTYPE; + +/* + * Structure defining a light source and its properties. + */ +typedef struct _D3DLIGHT { + DWORD dwSize; + D3DLIGHTTYPE dltType; /* Type of light source */ + D3DCOLORVALUE dcvColor; /* Color of light */ + D3DVECTOR dvPosition; /* Position in world space */ + D3DVECTOR dvDirection; /* Direction in world space */ + D3DVALUE dvRange; /* Cutoff range */ + D3DVALUE dvFalloff; /* Falloff */ + D3DVALUE dvAttenuation0; /* Constant attenuation */ + D3DVALUE dvAttenuation1; /* Linear attenuation */ + D3DVALUE dvAttenuation2; /* Quadratic attenuation */ + D3DVALUE dvTheta; /* Inner angle of spotlight cone */ + D3DVALUE dvPhi; /* Outer angle of spotlight cone */ +} D3DLIGHT, *LPD3DLIGHT; + +typedef struct _D3DLIGHTDATA { + DWORD dwSize; + LPD3DLIGHTINGELEMENT lpIn; /* Input positions and normals */ + DWORD dwInSize; /* Stride of input elements */ + LPD3DTLVERTEX lpOut; /* Output colors */ + DWORD dwOutSize; /* Stride of output colors */ +} D3DLIGHTDATA, *LPD3DLIGHTDATA; + +typedef enum _D3DCOLORMODEL { + D3DCOLOR_MONO = 1, + D3DCOLOR_RGB = 2, +} D3DCOLORMODEL; + +/* + * Options for clearing + */ +#define D3DCLEAR_TARGET 0x00000001l /* Clear target surface */ +#define D3DCLEAR_ZBUFFER 0x00000002l /* Clear target z buffer */ + +/* + * Execute buffers are allocated via Direct3D. These buffers may then + * be filled by the application with instructions to execute along with + * vertex data. + */ + +/* + * Supported op codes for execute instructions. + */ +typedef enum _D3DOPCODE { + D3DOP_POINT = 1, + D3DOP_LINE = 2, + D3DOP_TRIANGLE = 3, + D3DOP_MATRIXLOAD = 4, + D3DOP_MATRIXMULTIPLY = 5, + D3DOP_STATETRANSFORM = 6, + D3DOP_STATELIGHT = 7, + D3DOP_STATERENDER = 8, + D3DOP_PROCESSVERTICES = 9, + D3DOP_TEXTURELOAD = 10, + D3DOP_EXIT = 11, + D3DOP_BRANCHFORWARD = 12, + D3DOP_SPAN = 13, + D3DOP_SETSTATUS = 14, +} D3DOPCODE; + +typedef struct _D3DINSTRUCTION { + BYTE bOpcode; /* Instruction opcode */ + BYTE bSize; /* Size of each instruction data unit */ + WORD wCount; /* Count of instruction data units to follow */ +} D3DINSTRUCTION, *LPD3DINSTRUCTION; + +/* + * Structure for texture loads + */ +typedef struct _D3DTEXTURELOAD { + D3DTEXTUREHANDLE hDestTexture; + D3DTEXTUREHANDLE hSrcTexture; +} D3DTEXTURELOAD, *LPD3DTEXTURELOAD; + +/* + * Structure for picking + */ +typedef struct _D3DPICKRECORD { + BYTE bOpcode; + BYTE bPad; + DWORD dwOffset; + D3DVALUE dvZ; +} D3DPICKRECORD, *LPD3DPICKRECORD; + +/* + * The following defines the rendering states which can be set in the + * execute buffer. + */ + +typedef enum _D3DSHADEMODE { + D3DSHADE_FLAT = 1, + D3DSHADE_GOURAUD = 2, + D3DSHADE_PHONG = 3, +} D3DSHADEMODE; + +typedef enum _D3DFILLMODE { + D3DFILL_POINT = 1, + D3DFILL_WIREFRAME = 2, + D3DFILL_SOLID = 3, +} D3DFILLMODE; + +typedef struct _D3DLINEPATTERN { + WORD wRepeatFactor; + WORD wLinePattern; +} D3DLINEPATTERN; + +typedef enum _D3DTEXTUREFILTER { + D3DFILTER_NEAREST = 1, + D3DFILTER_LINEAR = 2, + D3DFILTER_MIPNEAREST = 3, + D3DFILTER_MIPLINEAR = 4, + D3DFILTER_LINEARMIPNEAREST = 5, + D3DFILTER_LINEARMIPLINEAR = 6, +} D3DTEXTUREFILTER; + +typedef enum _D3DBLEND { + D3DBLEND_ZERO = 1, + D3DBLEND_ONE = 2, + D3DBLEND_SRCCOLOR = 3, + D3DBLEND_INVSRCCOLOR = 4, + D3DBLEND_SRCALPHA = 5, + D3DBLEND_INVSRCALPHA = 6, + D3DBLEND_DESTALPHA = 7, + D3DBLEND_INVDESTALPHA = 8, + D3DBLEND_DESTCOLOR = 9, + D3DBLEND_INVDESTCOLOR = 10, + D3DBLEND_SRCALPHASAT = 11, + D3DBLEND_BOTHSRCALPHA = 12, + D3DBLEND_BOTHINVSRCALPHA = 13, +} D3DBLEND; + +typedef enum _D3DTEXTUREBLEND { + D3DTBLEND_DECAL = 1, + D3DTBLEND_MODULATE = 2, + D3DTBLEND_DECALALPHA = 3, + D3DTBLEND_MODULATEALPHA = 4, + D3DTBLEND_DECALMASK = 5, + D3DTBLEND_MODULATEMASK = 6, + D3DTBLEND_COPY = 7, +} D3DTEXTUREBLEND; + +typedef enum _D3DTEXTUREADDRESS { + D3DTADDRESS_WRAP = 1, + D3DTADDRESS_MIRROR = 2, + D3DTADDRESS_CLAMP = 3, +} D3DTEXTUREADDRESS; + +typedef enum _D3DCULL { + D3DCULL_NONE = 1, + D3DCULL_CW = 2, + D3DCULL_CCW = 3, +} D3DCULL; + +typedef enum _D3DCMPFUNC { + D3DCMP_NEVER = 1, + D3DCMP_LESS = 2, + D3DCMP_EQUAL = 3, + D3DCMP_LESSEQUAL = 4, + D3DCMP_GREATER = 5, + D3DCMP_NOTEQUAL = 6, + D3DCMP_GREATEREQUAL = 7, + D3DCMP_ALWAYS = 8, +} D3DCMPFUNC; + +typedef enum _D3DFOGMODE { + D3DFOG_NONE = 0, + D3DFOG_EXP = 1, + D3DFOG_EXP2 = 2, + D3DFOG_LINEAR = 3 +} D3DFOGMODE; + +/* + * Amount to add to a state to generate the override for that state. + */ +#define D3DSTATE_OVERRIDE_BIAS 256 + +/* + * A state which sets the override flag for the specified state type. + */ +#define D3DSTATE_OVERRIDE(type) ((DWORD) (type) + D3DSTATE_OVERRIDE_BIAS) + +typedef enum _D3DTRANSFORMSTATETYPE { + D3DTRANSFORMSTATE_WORLD = 1, + D3DTRANSFORMSTATE_VIEW = 2, + D3DTRANSFORMSTATE_PROJECTION = 3, +} D3DTRANSFORMSTATETYPE; + +typedef enum _D3DLIGHTSTATETYPE { + D3DLIGHTSTATE_MATERIAL = 1, + D3DLIGHTSTATE_AMBIENT = 2, + D3DLIGHTSTATE_COLORMODEL = 3, + D3DLIGHTSTATE_FOGMODE = 4, + D3DLIGHTSTATE_FOGSTART = 5, + D3DLIGHTSTATE_FOGEND = 6, + D3DLIGHTSTATE_FOGDENSITY = 7, +} D3DLIGHTSTATETYPE; + +typedef enum _D3DRENDERSTATETYPE { + D3DRENDERSTATE_TEXTUREHANDLE = 1, /* Texture handle */ + D3DRENDERSTATE_ANTIALIAS = 2, /* Antialiasing prim edges */ + D3DRENDERSTATE_TEXTUREADDRESS = 3, /* D3DTEXTUREADDRESS */ + D3DRENDERSTATE_TEXTUREPERSPECTIVE = 4, /* TRUE for perspective correction */ + D3DRENDERSTATE_WRAPU = 5, /* TRUE for wrapping in u */ + D3DRENDERSTATE_WRAPV = 6, /* TRUE for wrapping in v */ + D3DRENDERSTATE_ZENABLE = 7, /* TRUE to enable z test */ + D3DRENDERSTATE_FILLMODE = 8, /* D3DFILL_MODE */ + D3DRENDERSTATE_SHADEMODE = 9, /* D3DSHADEMODE */ + D3DRENDERSTATE_LINEPATTERN = 10, /* D3DLINEPATTERN */ + D3DRENDERSTATE_MONOENABLE = 11, /* TRUE to enable mono rasterization */ + D3DRENDERSTATE_ROP2 = 12, /* ROP2 */ + D3DRENDERSTATE_PLANEMASK = 13, /* DWORD physical plane mask */ + D3DRENDERSTATE_ZWRITEENABLE = 14, /* TRUE to enable z writes */ + D3DRENDERSTATE_ALPHATESTENABLE = 15, /* TRUE to enable alpha tests */ + D3DRENDERSTATE_LASTPIXEL = 16, /* TRUE for last-pixel on lines */ + D3DRENDERSTATE_TEXTUREMAG = 17, /* D3DTEXTUREFILTER */ + D3DRENDERSTATE_TEXTUREMIN = 18, /* D3DTEXTUREFILTER */ + D3DRENDERSTATE_SRCBLEND = 19, /* D3DBLEND */ + D3DRENDERSTATE_DESTBLEND = 20, /* D3DBLEND */ + D3DRENDERSTATE_TEXTUREMAPBLEND = 21, /* D3DTEXTUREBLEND */ + D3DRENDERSTATE_CULLMODE = 22, /* D3DCULL */ + D3DRENDERSTATE_ZFUNC = 23, /* D3DCMPFUNC */ + D3DRENDERSTATE_ALPHAREF = 24, /* D3DFIXED */ + D3DRENDERSTATE_ALPHAFUNC = 25, /* D3DCMPFUNC */ + D3DRENDERSTATE_DITHERENABLE = 26, /* TRUE to enable dithering */ + D3DRENDERSTATE_BLENDENABLE = 27, /* TRUE to enable alpha blending */ + D3DRENDERSTATE_FOGENABLE = 28, /* TRUE to enable fog */ + D3DRENDERSTATE_SPECULARENABLE = 29, /* TRUE to enable specular */ + D3DRENDERSTATE_ZVISIBLE = 30, /* TRUE to enable z checking */ + D3DRENDERSTATE_SUBPIXEL = 31, /* TRUE to enable subpixel correction */ + D3DRENDERSTATE_SUBPIXELX = 32, /* TRUE to enable correction in X only */ + D3DRENDERSTATE_STIPPLEDALPHA = 33, /* TRUE to enable stippled alpha */ + D3DRENDERSTATE_FOGCOLOR = 34, /* D3DCOLOR */ + D3DRENDERSTATE_FOGTABLEMODE = 35, /* D3DFOGMODE */ + D3DRENDERSTATE_FOGTABLESTART = 36, /* Fog table start */ + D3DRENDERSTATE_FOGTABLEEND = 37, /* Fog table end */ + D3DRENDERSTATE_FOGTABLEDENSITY = 38, /* Fog table density */ + D3DRENDERSTATE_STIPPLEENABLE = 39, /* TRUE to enable stippling */ + D3DRENDERSTATE_STIPPLEPATTERN00 = 64, /* Stipple pattern 01... */ + D3DRENDERSTATE_STIPPLEPATTERN01 = 65, + D3DRENDERSTATE_STIPPLEPATTERN02 = 66, + D3DRENDERSTATE_STIPPLEPATTERN03 = 67, + D3DRENDERSTATE_STIPPLEPATTERN04 = 68, + D3DRENDERSTATE_STIPPLEPATTERN05 = 69, + D3DRENDERSTATE_STIPPLEPATTERN06 = 70, + D3DRENDERSTATE_STIPPLEPATTERN07 = 71, + D3DRENDERSTATE_STIPPLEPATTERN08 = 72, + D3DRENDERSTATE_STIPPLEPATTERN09 = 73, + D3DRENDERSTATE_STIPPLEPATTERN10 = 74, + D3DRENDERSTATE_STIPPLEPATTERN11 = 75, + D3DRENDERSTATE_STIPPLEPATTERN12 = 76, + D3DRENDERSTATE_STIPPLEPATTERN13 = 77, + D3DRENDERSTATE_STIPPLEPATTERN14 = 78, + D3DRENDERSTATE_STIPPLEPATTERN15 = 79, + D3DRENDERSTATE_STIPPLEPATTERN16 = 80, + D3DRENDERSTATE_STIPPLEPATTERN17 = 81, + D3DRENDERSTATE_STIPPLEPATTERN18 = 82, + D3DRENDERSTATE_STIPPLEPATTERN19 = 83, + D3DRENDERSTATE_STIPPLEPATTERN20 = 84, + D3DRENDERSTATE_STIPPLEPATTERN21 = 85, + D3DRENDERSTATE_STIPPLEPATTERN22 = 86, + D3DRENDERSTATE_STIPPLEPATTERN23 = 87, + D3DRENDERSTATE_STIPPLEPATTERN24 = 88, + D3DRENDERSTATE_STIPPLEPATTERN25 = 89, + D3DRENDERSTATE_STIPPLEPATTERN26 = 90, + D3DRENDERSTATE_STIPPLEPATTERN27 = 91, + D3DRENDERSTATE_STIPPLEPATTERN28 = 92, + D3DRENDERSTATE_STIPPLEPATTERN29 = 93, + D3DRENDERSTATE_STIPPLEPATTERN30 = 94, + D3DRENDERSTATE_STIPPLEPATTERN31 = 95, +} D3DRENDERSTATETYPE; + +#define D3DRENDERSTATE_STIPPLEPATTERN(y) (D3DRENDERSTATE_STIPPLEPATTERN00 + (y)) + +typedef struct _D3DSTATE { + union { + D3DTRANSFORMSTATETYPE dtstTransformStateType; + D3DLIGHTSTATETYPE dlstLightStateType; + D3DRENDERSTATETYPE drstRenderStateType; + }; + union { + DWORD dwArg[1]; + D3DVALUE dvArg[1]; + }; +} D3DSTATE, *LPD3DSTATE; + +/* + * Operation used to load matrices + * hDstMat = hSrcMat + */ +typedef struct _D3DMATRIXLOAD { + D3DMATRIXHANDLE hDestMatrix; /* Destination matrix */ + D3DMATRIXHANDLE hSrcMatrix; /* Source matrix */ +} D3DMATRIXLOAD, *LPD3DMATRIXLOAD; + +/* + * Operation used to multiply matrices + * hDstMat = hSrcMat1 * hSrcMat2 + */ +typedef struct _D3DMATRIXMULTIPLY { + D3DMATRIXHANDLE hDestMatrix; /* Destination matrix */ + D3DMATRIXHANDLE hSrcMatrix1; /* First source matrix */ + D3DMATRIXHANDLE hSrcMatrix2; /* Second source matrix */ +} D3DMATRIXMULTIPLY, *LPD3DMATRIXMULTIPLY; + +/* + * Operation used to transform and light vertices. + */ +typedef struct _D3DPROCESSVERTICES { + DWORD dwFlags; /* Do we transform or light or just copy? */ + WORD wStart; /* Index to first vertex in source */ + WORD wDest; /* Index to first vertex in local buffer */ + DWORD dwCount; /* Number of vertices to be processed */ + DWORD dwReserved; /* Must be zero */ +} D3DPROCESSVERTICES, *LPD3DPROCESSVERTICES; + +#define D3DPROCESSVERTICES_TRANSFORMLIGHT 0x00000000L +#define D3DPROCESSVERTICES_TRANSFORM 0x00000001L +#define D3DPROCESSVERTICES_COPY 0x00000002L +#define D3DPROCESSVERTICES_OPMASK 0x00000007L + +#define D3DPROCESSVERTICES_UPDATEEXTENTS 0x00000008L +#define D3DPROCESSVERTICES_NOCOLOR 0x00000010L + + +/* + * Triangle flags + */ + +/* + * Tri strip and fan flags. + * START loads all three vertices + * EVEN and ODD load just v3 with even or odd culling + * START_FLAT contains a count from 0 to 29 that allows the + * whole strip or fan to be culled in one hit. + * e.g. for a quad len = 1 + */ +#define D3DTRIFLAG_START 0x00000000L +#define D3DTRIFLAG_STARTFLAT(len) (len) /* 0 < len < 30 */ +#define D3DTRIFLAG_ODD 0x0000001eL +#define D3DTRIFLAG_EVEN 0x0000001fL + +/* + * Triangle edge flags + * enable edges for wireframe or antialiasing + */ +#define D3DTRIFLAG_EDGEENABLE1 0x00000100L /* v0-v1 edge */ +#define D3DTRIFLAG_EDGEENABLE2 0x00000200L /* v1-v2 edge */ +#define D3DTRIFLAG_EDGEENABLE3 0x00000400L /* v2-v0 edge */ +#define D3DTRIFLAG_EDGEENABLETRIANGLE \ + (D3DTRIFLAG_EDGEENABLE1 | D3DTRIFLAG_EDGEENABLE2 | D3DTRIFLAG_EDGEENABLE3) + +/* + * Primitive structures and related defines. Vertex offsets are to types + * D3DVERTEX, D3DLVERTEX, or D3DTLVERTEX. + */ + +/* + * Triangle list primitive structure + */ +typedef struct _D3DTRIANGLE { + union { + WORD v1; /* Vertex indices */ + WORD wV1; + }; + union { + WORD v2; + WORD wV2; + }; + union { + WORD v3; + WORD wV3; + }; + WORD wFlags; /* Edge (and other) flags */ +} D3DTRIANGLE, *LPD3DTRIANGLE; + +/* + * Line strip structure. + * The instruction count - 1 defines the number of line segments. + */ +typedef struct _D3DLINE { + union { + WORD v1; /* Vertex indices */ + WORD wV1; + }; + union { + WORD v2; + WORD wV2; + }; +} D3DLINE, *LPD3DLINE; + +/* + * Span structure + * Spans join a list of points with the same y value. + * If the y value changes, a new span is started. + */ +typedef struct _D3DSPAN { + WORD wCount; /* Number of spans */ + WORD wFirst; /* Index to first vertex */ +} D3DSPAN, *LPD3DSPAN; + +/* + * Point structure + */ +typedef struct _D3DPOINT { + WORD wCount; /* number of points */ + WORD wFirst; /* index to first vertex */ +} D3DPOINT, *LPD3DPOINT; + + +/* + * Forward branch structure. + * Mask is logically anded with the driver status mask + * if the result equals 'value', the branch is taken. + */ +typedef struct _D3DBRANCH { + DWORD dwMask; /* Bitmask against D3D status */ + DWORD dwValue; + BOOL bNegate; /* TRUE to negate comparison */ + DWORD dwOffset; /* How far to branch forward (0 for exit)*/ +} D3DBRANCH, *LPD3DBRANCH; + +/* + * Status used for set status instruction. + * The D3D status is initialised on device creation + * and is modified by all execute calls. + */ +typedef struct _D3DSTATUS { + DWORD dwFlags; /* Do we set extents or status */ + DWORD dwStatus; /* D3D status */ + D3DRECT drExtent; +} D3DSTATUS, *LPD3DSTATUS; + +#define D3DSETSTATUS_STATUS 0x00000001L +#define D3DSETSTATUS_EXTENTS 0x00000002L +#define D3DSETSTATUS_ALL (D3DSETSTATUS_STATUS | D3DSETSTATUS_EXTENTS) + +/* + * Statistics structure + */ +typedef struct _D3DSTATS { + DWORD dwSize; + DWORD dwTrianglesDrawn; + DWORD dwLinesDrawn; + DWORD dwPointsDrawn; + DWORD dwSpansDrawn; + DWORD dwVerticesProcessed; +} D3DSTATS, *LPD3DSTATS; + +/* + * Execute options. + * When calling using D3DEXECUTE_UNCLIPPED all the primitives + * inside the buffer must be contained within the viewport. + */ +#define D3DEXECUTE_CLIPPED 0x00000001l +#define D3DEXECUTE_UNCLIPPED 0x00000002l + +typedef struct _D3DEXECUTEDATA { + DWORD dwSize; + DWORD dwVertexOffset; + DWORD dwVertexCount; + DWORD dwInstructionOffset; + DWORD dwInstructionLength; + DWORD dwHVertexOffset; + D3DSTATUS dsStatus; /* Status after execute */ +} D3DEXECUTEDATA, *LPD3DEXECUTEDATA; + +/* + * Palette flags. + * This are or'ed with the peFlags in the PALETTEENTRYs passed to DirectDraw. + */ +#define D3DPAL_FREE 0x00 /* Renderer may use this entry freely */ +#define D3DPAL_READONLY 0x40 /* Renderer may not set this entry */ +#define D3DPAL_RESERVED 0x80 /* Renderer may not use this entry */ + +#if defined(__cplusplus) +}; +#endif + +#pragma pack() + +#endif /* _D3DTYPES_H_ */ diff --git a/D523BD.ZIP b/D523BD.ZIP new file mode 100644 index 0000000..22a144f Binary files /dev/null and b/D523BD.ZIP differ diff --git a/D523BF.ZIP b/D523BF.ZIP new file mode 100644 index 0000000..d44483f Binary files /dev/null and b/D523BF.ZIP differ diff --git a/DDRAW.H b/DDRAW.H new file mode 100644 index 0000000..abb9104 --- /dev/null +++ b/DDRAW.H @@ -0,0 +1,3102 @@ +/*==========================================================================; + * + * Copyright (C) 1994-1996 Microsoft Corporation. All Rights Reserved. + * + * File: ddraw.h + * Content: DirectDraw include file + * + ***************************************************************************/ + +#ifndef __DDRAW_INCLUDED__ +#define __DDRAW_INCLUDED__ +#if defined( _WIN32 ) && !defined( _NO_COM ) +#define COM_NO_WINDOWS_H +#include +#else +#define IUnknown void +#define CO_E_NOTINITIALIZED 0x800401F0L +#endif + +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * GUIDS used by DirectDraw objects + */ +#if defined( _WIN32 ) && !defined( _NO_COM ) +DEFINE_GUID( CLSID_DirectDraw, 0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 ); +DEFINE_GUID( CLSID_DirectDrawClipper, 0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw, 0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 ); + +DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawClipper, 0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); + +#endif + +/*============================================================================ + * + * DirectDraw Structures + * + * Various structures used to invoke DirectDraw. + * + *==========================================================================*/ + +struct IDirectDraw; +struct IDirectDrawSurface; +struct IDirectDrawPalette; +struct IDirectDrawClipper; + +typedef struct IDirectDraw FAR *LPDIRECTDRAW; +typedef struct IDirectDraw2 FAR *LPDIRECTDRAW2; +typedef struct IDirectDrawSurface FAR *LPDIRECTDRAWSURFACE; +typedef struct IDirectDrawSurface2 FAR *LPDIRECTDRAWSURFACE2; + +typedef struct IDirectDrawPalette FAR *LPDIRECTDRAWPALETTE; +typedef struct IDirectDrawClipper FAR *LPDIRECTDRAWCLIPPER; + +typedef struct _DDFXROP FAR *LPDDFXROP; +typedef struct _DDSURFACEDESC FAR *LPDDSURFACEDESC; + +/* + * API's + */ +#if (defined (WIN32) || defined( _WIN32 ) ) && !defined( _NO_COM ) +//#if defined( _WIN32 ) && !defined( _NO_ENUM ) + typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKA)(GUID FAR *, LPSTR, LPSTR, LPVOID); + typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKW)(GUID FAR *, LPWSTR, LPWSTR, LPVOID); + extern HRESULT WINAPI DirectDrawEnumerateW( LPDDENUMCALLBACKW lpCallback, LPVOID lpContext ); + extern HRESULT WINAPI DirectDrawEnumerateA( LPDDENUMCALLBACKA lpCallback, LPVOID lpContext ); + #ifdef UNICODE + typedef LPDDENUMCALLBACKW LPDDENUMCALLBACK; + #define DirectDrawEnumerate DirectDrawEnumerateW + #else + typedef LPDDENUMCALLBACKA LPDDENUMCALLBACK; + #define DirectDrawEnumerate DirectDrawEnumerateA + #endif + extern HRESULT WINAPI DirectDrawCreate( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter ); + extern HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, IUnknown FAR *pUnkOuter ); + #ifdef WINNT + //This is the user-mode entry stub to the kernel mode procedure. + extern HRESULT NtDirectDrawCreate( GUID FAR *lpGUID, HANDLE *lplpDD, IUnknown FAR *pUnkOuter ); + #endif +#endif + +#define REGSTR_KEY_DDHW_DESCRIPTION "Description" +#define REGSTR_KEY_DDHW_DRIVERNAME "DriverName" +#define REGSTR_PATH_DDHW "Hardware\\DirectDrawDrivers" + +#define DDCREATE_HARDWAREONLY 0x00000001l +#define DDCREATE_EMULATIONONLY 0x00000002l + +#ifdef WINNT +typedef long HRESULT; +#endif + +//#ifndef WINNT +typedef HRESULT (FAR PASCAL * LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID); +typedef HRESULT (FAR PASCAL * LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID); +//#endif +/* + * DDCOLORKEY + */ +typedef struct _DDCOLORKEY +{ + DWORD dwColorSpaceLowValue; // low boundary of color space that is to + // be treated as Color Key, inclusive + DWORD dwColorSpaceHighValue; // high boundary of color space that is + // to be treated as Color Key, inclusive +} DDCOLORKEY; + +typedef DDCOLORKEY FAR* LPDDCOLORKEY; + +/* + * DDBLTFX + * Used to pass override information to the DIRECTDRAWSURFACE callback Blt. + */ +typedef struct _DDBLTFX +{ + DWORD dwSize; // size of structure + DWORD dwDDFX; // FX operations + DWORD dwROP; // Win32 raster operations + DWORD dwDDROP; // Raster operations new for DirectDraw + DWORD dwRotationAngle; // Rotation angle for blt + DWORD dwZBufferOpCode; // ZBuffer compares + DWORD dwZBufferLow; // Low limit of Z buffer + DWORD dwZBufferHigh; // High limit of Z buffer + DWORD dwZBufferBaseDest; // Destination base value + DWORD dwZDestConstBitDepth; // Bit depth used to specify Z constant for destination + union + { + DWORD dwZDestConst; // Constant to use as Z buffer for dest + LPDIRECTDRAWSURFACE lpDDSZBufferDest; // Surface to use as Z buffer for dest + }; + DWORD dwZSrcConstBitDepth; // Bit depth used to specify Z constant for source + union + { + DWORD dwZSrcConst; // Constant to use as Z buffer for src + LPDIRECTDRAWSURFACE lpDDSZBufferSrc; // Surface to use as Z buffer for src + }; + DWORD dwAlphaEdgeBlendBitDepth; // Bit depth used to specify constant for alpha edge blend + DWORD dwAlphaEdgeBlend; // Alpha for edge blending + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; // Bit depth used to specify alpha constant for destination + union + { + DWORD dwAlphaDestConst; // Constant to use as Alpha Channel + LPDIRECTDRAWSURFACE lpDDSAlphaDest; // Surface to use as Alpha Channel + }; + DWORD dwAlphaSrcConstBitDepth; // Bit depth used to specify alpha constant for source + union + { + DWORD dwAlphaSrcConst; // Constant to use as Alpha Channel + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; // Surface to use as Alpha Channel + }; + union + { + DWORD dwFillColor; // color in RGB or Palettized + DWORD dwFillDepth; // depth value for z-buffer + LPDIRECTDRAWSURFACE lpDDSPattern; // Surface to use as pattern + }; + DDCOLORKEY ddckDestColorkey; // DestColorkey override + DDCOLORKEY ddckSrcColorkey; // SrcColorkey override +} DDBLTFX; + +typedef DDBLTFX FAR* LPDDBLTFX; + + +/* + * DDSCAPS + */ +typedef struct _DDSCAPS +{ + DWORD dwCaps; // capabilities of surface wanted +} DDSCAPS; + +typedef DDSCAPS FAR* LPDDSCAPS; + +/* + * DDCAPS + */ +#define DD_ROP_SPACE (256/32) // space required to store ROP array + +typedef struct _DDCAPS +{ + DWORD dwSize; // size of the DDDRIVERCAPS structure + DWORD dwCaps; // driver specific capabilities + DWORD dwCaps2; // more driver specific capabilites + DWORD dwCKeyCaps; // color key capabilities of the surface + DWORD dwFXCaps; // driver specific stretching and effects capabilites + DWORD dwFXAlphaCaps; // alpha driver specific capabilities + DWORD dwPalCaps; // palette capabilities + DWORD dwSVCaps; // stereo vision capabilities + DWORD dwAlphaBltConstBitDepths; // DDBD_2,4,8 + DWORD dwAlphaBltPixelBitDepths; // DDBD_1,2,4,8 + DWORD dwAlphaBltSurfaceBitDepths; // DDBD_1,2,4,8 + DWORD dwAlphaOverlayConstBitDepths; // DDBD_2,4,8 + DWORD dwAlphaOverlayPixelBitDepths; // DDBD_1,2,4,8 + DWORD dwAlphaOverlaySurfaceBitDepths; // DDBD_1,2,4,8 + DWORD dwZBufferBitDepths; // DDBD_8,16,24,32 + DWORD dwVidMemTotal; // total amount of video memory + DWORD dwVidMemFree; // amount of free video memory + DWORD dwMaxVisibleOverlays; // maximum number of visible overlays + DWORD dwCurrVisibleOverlays; // current number of visible overlays + DWORD dwNumFourCCCodes; // number of four cc codes + DWORD dwAlignBoundarySrc; // source rectangle alignment + DWORD dwAlignSizeSrc; // source rectangle byte size + DWORD dwAlignBoundaryDest; // dest rectangle alignment + DWORD dwAlignSizeDest; // dest rectangle byte size + DWORD dwAlignStrideAlign; // stride alignment + DWORD dwRops[DD_ROP_SPACE]; // ROPS supported + DDSCAPS ddsCaps; // DDSCAPS structure has all the general capabilities + DWORD dwMinOverlayStretch; // minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + DWORD dwMaxOverlayStretch; // maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + DWORD dwMinLiveVideoStretch; // minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + DWORD dwMaxLiveVideoStretch; // maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + DWORD dwMinHwCodecStretch; // minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + DWORD dwMaxHwCodecStretch; // maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + DWORD dwReserved1; // reserved + DWORD dwReserved2; // reserved + DWORD dwReserved3; // reserved + DWORD dwSVBCaps; // driver specific capabilities for System->Vmem blts + DWORD dwSVBCKeyCaps; // driver color key capabilities for System->Vmem blts + DWORD dwSVBFXCaps; // driver FX capabilities for System->Vmem blts + DWORD dwSVBRops[DD_ROP_SPACE];// ROPS supported for System->Vmem blts + DWORD dwVSBCaps; // driver specific capabilities for Vmem->System blts + DWORD dwVSBCKeyCaps; // driver color key capabilities for Vmem->System blts + DWORD dwVSBFXCaps; // driver FX capabilities for Vmem->System blts + DWORD dwVSBRops[DD_ROP_SPACE];// ROPS supported for Vmem->System blts + DWORD dwSSBCaps; // driver specific capabilities for System->System blts + DWORD dwSSBCKeyCaps; // driver color key capabilities for System->System blts + DWORD dwSSBFXCaps; // driver FX capabilities for System->System blts + DWORD dwSSBRops[DD_ROP_SPACE];// ROPS supported for System->System blts + DWORD dwReserved4; // reserved + DWORD dwReserved5; // reserved + DWORD dwReserved6; // reserved +} DDCAPS; + +typedef DDCAPS FAR* LPDDCAPS; + + + +/* + * DDPIXELFORMAT + */ +typedef struct _DDPIXELFORMAT +{ + DWORD dwSize; // size of structure + DWORD dwFlags; // pixel format flags + DWORD dwFourCC; // (FOURCC code) + union + { + DWORD dwRGBBitCount; // how many bits per pixel (BD_4,8,16,24,32) + DWORD dwYUVBitCount; // how many bits per pixel (BD_4,8,16,24,32) + DWORD dwZBufferBitDepth; // how many bits for z buffers (BD_8,16,24,32) + DWORD dwAlphaBitDepth; // how many bits for alpha channels (BD_1,2,4,8) + }; + union + { + DWORD dwRBitMask; // mask for red bit + DWORD dwYBitMask; // mask for Y bits + }; + union + { + DWORD dwGBitMask; // mask for green bits + DWORD dwUBitMask; // mask for U bits + }; + union + { + DWORD dwBBitMask; // mask for blue bits + DWORD dwVBitMask; // mask for V bits + }; + union + { + DWORD dwRGBAlphaBitMask; // mask for alpha channel + DWORD dwYUVAlphaBitMask; // mask for alpha channel + }; +} DDPIXELFORMAT; + +typedef DDPIXELFORMAT FAR* LPDDPIXELFORMAT; + +/* + * DDOVERLAYFX + */ +typedef struct _DDOVERLAYFX +{ + DWORD dwSize; // size of structure + DWORD dwAlphaEdgeBlendBitDepth; // Bit depth used to specify constant for alpha edge blend + DWORD dwAlphaEdgeBlend; // Constant to use as alpha for edge blend + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; // Bit depth used to specify alpha constant for destination + union + { + DWORD dwAlphaDestConst; // Constant to use as alpha channel for dest + LPDIRECTDRAWSURFACE lpDDSAlphaDest; // Surface to use as alpha channel for dest + }; + DWORD dwAlphaSrcConstBitDepth; // Bit depth used to specify alpha constant for source + union + { + DWORD dwAlphaSrcConst; // Constant to use as alpha channel for src + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; // Surface to use as alpha channel for src + }; + DDCOLORKEY dckDestColorkey; // DestColorkey override + DDCOLORKEY dckSrcColorkey; // DestColorkey override + DWORD dwDDFX; // Overlay FX + DWORD dwFlags; // flags +} DDOVERLAYFX; + +typedef DDOVERLAYFX FAR *LPDDOVERLAYFX; + +/* + * DDBLTBATCH: BltBatch entry structure + */ +typedef struct _DDBLTBATCH +{ + LPRECT lprDest; + LPDIRECTDRAWSURFACE lpDDSSrc; + LPRECT lprSrc; + DWORD dwFlags; + LPDDBLTFX lpDDBltFx; +} DDBLTBATCH; + +typedef DDBLTBATCH FAR * LPDDBLTBATCH; + +/* + * callbacks + */ +typedef DWORD (FAR PASCAL *LPCLIPPERCALLBACK)(LPDIRECTDRAWCLIPPER lpDDClipper, HWND hWnd, DWORD code, LPVOID lpContext ); +#ifdef STREAMING +typedef DWORD (FAR PASCAL *LPSURFACESTREAMINGCALLBACK)(DWORD); +#endif + + +/* + * INTERACES FOLLOW: + * IDirectDraw + * IDirectDrawClipper + * IDirectDrawPalette + * IDirectDrawSurface + */ + +/* + * IDirectDraw + */ +#if defined( _WIN32 ) && !defined( _NO_COM ) +#undef INTERFACE +#define INTERFACE IDirectDraw +DECLARE_INTERFACE_( IDirectDraw, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDraw methods ***/ + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectDraw_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) +#define IDirectDraw_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectDraw_Release(p) (p)->lpVtbl->Release(p) +#define IDirectDraw_Compact(p) (p)->lpVtbl->Compact(p) +#define IDirectDraw_CreateClipper(p, a, b, c) (p)->lpVtbl->CreateClipper(p, a, b, c) +#define IDirectDraw_CreatePalette(p, a, b, c, d) (p)->lpVtbl->CreatePalette(p, a, b, c, d) +#define IDirectDraw_CreateSurface(p, a, b, c) (p)->lpVtbl->CreateSurface(p, a, b, c) +#define IDirectDraw_DuplicateSurface(p, a, b) (p)->lpVtbl->DuplicateSurface(p, a, b) +#define IDirectDraw_EnumDisplayModes(p, a, b, c, d) (p)->lpVtbl->EnumDisplayModes(p, a, b, c, d) +#define IDirectDraw_EnumSurfaces(p, a, b, c, d) (p)->lpVtbl->EnumSurfaces(p, a, b, c, d) +#define IDirectDraw_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p) +#define IDirectDraw_GetCaps(p, a, b) (p)->lpVtbl->GetCaps(p, a, b) +#define IDirectDraw_GetDisplayMode(p, a) (p)->lpVtbl->GetDisplayMode(p, a) +#define IDirectDraw_GetFourCCCodes(p, a, b) (p)->lpVtbl->GetFourCCCodes(p, a, b) +#define IDirectDraw_GetGDISurface(p, a) (p)->lpVtbl->GetGDISurface(p, a) +#define IDirectDraw_GetMonitorFrequency(p, a) (p)->lpVtbl->GetMonitorFrequency(p, a) +#define IDirectDraw_GetScanLine(p, a) (p)->lpVtbl->GetScanLine(p, a) +#define IDirectDraw_GetVerticalBlankStatus(p, a) (p)->lpVtbl->GetVerticalBlankStatus(p, a) +#define IDirectDraw_Initialize(p, a) (p)->lpVtbl->Initialize(p, a) +#define IDirectDraw_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p) +#define IDirectDraw_SetCooperativeLevel(p, a, b) (p)->lpVtbl->SetCooperativeLevel(p, a, b) +#define IDirectDraw_SetDisplayMode(p, a, b, c) (p)->lpVtbl->SetDisplayMode(p, a, b, c) +#define IDirectDraw_WaitForVerticalBlank(p, a, b) (p)->lpVtbl->WaitForVerticalBlank(p, a, b) +#endif + +#endif + +#if defined( _WIN32 ) && !defined( _NO_COM ) +#undef INTERFACE +#define INTERFACE IDirectDraw2 +DECLARE_INTERFACE_( IDirectDraw2, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDraw methods ***/ + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; + /*** Added in the v2 interface ***/ + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS, LPDWORD, LPDWORD) PURE; +}; +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectDraw2_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) +#define IDirectDraw2_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectDraw2_Release(p) (p)->lpVtbl->Release(p) +#define IDirectDraw2_Compact(p) (p)->lpVtbl->Compact(p) +#define IDirectDraw2_CreateClipper(p, a, b, c) (p)->lpVtbl->CreateClipper(p, a, b, c) +#define IDirectDraw2_CreatePalette(p, a, b, c, d) (p)->lpVtbl->CreatePalette(p, a, b, c, d) +#define IDirectDraw2_CreateSurface(p, a, b, c) (p)->lpVtbl->CreateSurface(p, a, b, c) +#define IDirectDraw2_DuplicateSurface(p, a, b) (p)->lpVtbl->DuplicateSurface(p, a, b) +#define IDirectDraw2_EnumDisplayModes(p, a, b, c, d) (p)->lpVtbl->EnumDisplayModes(p, a, b, c, d) +#define IDirectDraw2_EnumSurfaces(p, a, b, c, d) (p)->lpVtbl->EnumSurfaces(p, a, b, c, d) +#define IDirectDraw2_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p) +#define IDirectDraw2_GetCaps(p, a, b) (p)->lpVtbl->GetCaps(p, a, b) +#define IDirectDraw2_GetDisplayMode(p, a) (p)->lpVtbl->GetDisplayMode(p, a) +#define IDirectDraw2_GetFourCCCodes(p, a, b) (p)->lpVtbl->GetFourCCCodes(p, a, b) +#define IDirectDraw2_GetGDISurface(p, a) (p)->lpVtbl->GetGDISurface(p, a) +#define IDirectDraw2_GetMonitorFrequency(p, a) (p)->lpVtbl->GetMonitorFrequency(p, a) +#define IDirectDraw2_GetScanLine(p, a) (p)->lpVtbl->GetScanLine(p, a) +#define IDirectDraw2_GetVerticalBlankStatus(p, a) (p)->lpVtbl->GetVerticalBlankStatus(p, a) +#define IDirectDraw2_Initialize(p, a) (p)->lpVtbl->Initialize(p, a) +#define IDirectDraw2_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p) +#define IDirectDraw2_SetCooperativeLevel(p, a, b) (p)->lpVtbl->SetCooperativeLevel(p, a, b) +#define IDirectDraw2_SetDisplayMode(p, a, b, c, d) (p)->lpVtbl->SetDisplayMode(p, a, b, c, d) +#define IDirectDraw2_WaitForVerticalBlank(p, a, b) (p)->lpVtbl->WaitForVerticalBlank(p, a, b) +#define IDirectDraw2_GetAvailableVidMem(p, a, b, c) (p)->lpVtbl->GetAvailableVidMem(p, a, b, c) +#endif + +#endif + +/* + * IDirectDrawPalette + */ +#if defined( _WIN32 ) && !defined( _NO_COM ) +#undef INTERFACE +#define INTERFACE IDirectDrawPalette +DECLARE_INTERFACE_( IDirectDrawPalette, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawPalette methods ***/ + STDMETHOD(GetCaps)(THIS_ LPDWORD) PURE; + STDMETHOD(GetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE; + STDMETHOD(SetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectDrawPalette_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) +#define IDirectDrawPalette_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectDrawPalette_Release(p) (p)->lpVtbl->Release(p) +#define IDirectDrawPalette_GetCaps(p, a) (p)->lpVtbl->GetCaps(p, a) +#define IDirectDrawPalette_GetEntries(p, a, b, c, d) (p)->lpVtbl->GetEntries(p, a, b, c, d) +#define IDirectDrawPalette_Initialize(p, a, b, c) (p)->lpVtbl->Initialize(p, a, b, c) +#define IDirectDrawPalette_SetEntries(p, a, b, c, d) (p)->lpVtbl->SetEntries(p, a, b, c, d) +#endif + +#endif + +/* + * IDirectDrawClipper + */ +#if defined( _WIN32 ) && !defined( _NO_COM ) +#undef INTERFACE +#define INTERFACE IDirectDrawClipper +DECLARE_INTERFACE_( IDirectDrawClipper, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawClipper methods ***/ + STDMETHOD(GetClipList)(THIS_ LPRECT, LPRGNDATA, LPDWORD) PURE; + STDMETHOD(GetHWnd)(THIS_ HWND FAR *) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD) PURE; + STDMETHOD(IsClipListChanged)(THIS_ BOOL FAR *) PURE; + STDMETHOD(SetClipList)(THIS_ LPRGNDATA,DWORD) PURE; + STDMETHOD(SetHWnd)(THIS_ DWORD, HWND ) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectDrawClipper_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b) +#define IDirectDrawClipper_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectDrawClipper_Release(p) (p)->lpVtbl->Release(p) +#define IDirectDrawClipper_GetClipList(p, a, b, c) (p)->lpVtbl->GetClipList(p, a, b, c) +#define IDirectDrawClipper_GetHWnd(p, a) (p)->lpVtbl->GetHWnd(p, a) +#define IDirectDrawClipper_Initialize(p, a, b) (p)->lpVtbl->Initialize(p, a, b) +#define IDirectDrawClipper_IsClipListChanged(p, a) (p)->lpVtbl->IsClipListChanged(p, a) +#define IDirectDrawClipper_SetClipList(p, a, b) (p)->lpVtbl->SetClipList(p, a, b) +#define IDirectDrawClipper_SetHWnd(p, a, b) (p)->lpVtbl->SetHWnd(p, a, b) +#endif + +#endif + +/* + * IDirectDrawSurface and related interfaces + */ +#if defined( _WIN32 ) && !defined( _NO_COM ) +#undef INTERFACE +#define INTERFACE IDirectDrawSurface +DECLARE_INTERFACE_( IDirectDrawSurface, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawSurface methods ***/ + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; + STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE, LPRECT,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE, LPRECT,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC,DWORD,HANDLE) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE,LPRECT,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectDrawSurface_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectDrawSurface_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectDrawSurface_Release(p) (p)->lpVtbl->Release(p) +#define IDirectDrawSurface_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a) +#define IDirectDrawSurface_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a) +#define IDirectDrawSurface_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e) +#define IDirectDrawSurface_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c) +#define IDirectDrawSurface_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e) +#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b) +#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b) +#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c) +#define IDirectDrawSurface_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b) +#define IDirectDrawSurface_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b) +#define IDirectDrawSurface_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a) +#define IDirectDrawSurface_GetCaps(p,b) (p)->lpVtbl->GetCaps(p,b) +#define IDirectDrawSurface_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a) +#define IDirectDrawSurface_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b) +#define IDirectDrawSurface_GetDC(p,a) (p)->lpVtbl->GetDC(p,a) +#define IDirectDrawSurface_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a) +#define IDirectDrawSurface_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b) +#define IDirectDrawSurface_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a) +#define IDirectDrawSurface_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a) +#define IDirectDrawSurface_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a) +#define IDirectDrawSurface_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectDrawSurface_IsLost(p) (p)->lpVtbl->IsLost(p) +#define IDirectDrawSurface_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirectDrawSurface_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a) +#define IDirectDrawSurface_Restore(p) (p)->lpVtbl->Restore(p) +#define IDirectDrawSurface_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a) +#define IDirectDrawSurface_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b) +#define IDirectDrawSurface_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b) +#define IDirectDrawSurface_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a) +#define IDirectDrawSurface_Unlock(p,b) (p)->lpVtbl->Unlock(p,b) +#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e) +#define IDirectDrawSurface_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a) +#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b) +#endif + +/* + * IDirectDrawSurface2 and related interfaces + */ +#undef INTERFACE +#define INTERFACE IDirectDrawSurface2 +DECLARE_INTERFACE_( IDirectDrawSurface2, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawSurface methods ***/ + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; + STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE2, LPRECT,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE2, LPRECT,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE2) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE2 FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC,DWORD,HANDLE) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE2) PURE; + /*** Added in the v2 interface ***/ + STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE; + STDMETHOD(PageLock)(THIS_ DWORD) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectDrawSurface2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectDrawSurface2_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectDrawSurface2_Release(p) (p)->lpVtbl->Release(p) +#define IDirectDrawSurface2_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a) +#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a) +#define IDirectDrawSurface2_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e) +#define IDirectDrawSurface2_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c) +#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e) +#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b) +#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b) +#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c) +#define IDirectDrawSurface2_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b) +#define IDirectDrawSurface2_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b) +#define IDirectDrawSurface2_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a) +#define IDirectDrawSurface2_GetCaps(p,b) (p)->lpVtbl->GetCaps(p,b) +#define IDirectDrawSurface2_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a) +#define IDirectDrawSurface2_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b) +#define IDirectDrawSurface2_GetDC(p,a) (p)->lpVtbl->GetDC(p,a) +#define IDirectDrawSurface2_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a) +#define IDirectDrawSurface2_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b) +#define IDirectDrawSurface2_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a) +#define IDirectDrawSurface2_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a) +#define IDirectDrawSurface2_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a) +#define IDirectDrawSurface2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectDrawSurface2_IsLost(p) (p)->lpVtbl->IsLost(p) +#define IDirectDrawSurface2_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirectDrawSurface2_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a) +#define IDirectDrawSurface2_Restore(p) (p)->lpVtbl->Restore(p) +#define IDirectDrawSurface2_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a) +#define IDirectDrawSurface2_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b) +#define IDirectDrawSurface2_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b) +#define IDirectDrawSurface2_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a) +#define IDirectDrawSurface2_Unlock(p,b) (p)->lpVtbl->Unlock(p,b) +#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e) +#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a) +#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b) +#define IDirectDrawSurface2_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a) +#define IDirectDrawSurface2_PageLock(p,a) (p)->lpVtbl->PageLock(p,a) +#define IDirectDrawSurface2_PageUnlock(p,a) (p)->lpVtbl->PageUnlock(p,a) +#endif + + +#endif + + +/* + * DDSURFACEDESC + */ +typedef struct _DDSURFACEDESC +{ + DWORD dwSize; // size of the DDSURFACEDESC structure + DWORD dwFlags; // determines what fields are valid + DWORD dwHeight; // height of surface to be created + DWORD dwWidth; // width of input surface + LONG lPitch; // distance to start of next line (return value only) + DWORD dwBackBufferCount; // number of back buffers requested + union + { + DWORD dwMipMapCount; // number of mip-map levels requested + DWORD dwZBufferBitDepth; // depth of Z buffer requested + DWORD dwRefreshRate; // refresh rate (used when display mode is described) + }; + DWORD dwAlphaBitDepth; // depth of alpha buffer requested + DWORD dwReserved; // reserved + LPVOID lpSurface; // pointer to the associated surface memory + DDCOLORKEY ddckCKDestOverlay; // color key for destination overlay use + DDCOLORKEY ddckCKDestBlt; // color key for destination blt use + DDCOLORKEY ddckCKSrcOverlay; // color key for source overlay use + DDCOLORKEY ddckCKSrcBlt; // color key for source blt use + DDPIXELFORMAT ddpfPixelFormat; // pixel format description of the surface + DDSCAPS ddsCaps; // direct draw surface capabilities +} DDSURFACEDESC; + +/* + * ddsCaps field is valid. + */ +#define DDSD_CAPS 0x00000001l // default + +/* + * dwHeight field is valid. + */ +#define DDSD_HEIGHT 0x00000002l + +/* + * dwWidth field is valid. + */ +#define DDSD_WIDTH 0x00000004l + +/* + * lPitch is valid. + */ +#define DDSD_PITCH 0x00000008l + +/* + * dwBackBufferCount is valid. + */ +#define DDSD_BACKBUFFERCOUNT 0x00000020l + +/* + * dwZBufferBitDepth is valid. + */ +#define DDSD_ZBUFFERBITDEPTH 0x00000040l + +/* + * dwAlphaBitDepth is valid. + */ +#define DDSD_ALPHABITDEPTH 0x00000080l + + + +/* + * ddpfPixelFormat is valid. + */ +#define DDSD_PIXELFORMAT 0x00001000l + +/* + * ddckCKDestOverlay is valid. + */ +#define DDSD_CKDESTOVERLAY 0x00002000l + +/* + * ddckCKDestBlt is valid. + */ +#define DDSD_CKDESTBLT 0x00004000l + +/* + * ddckCKSrcOverlay is valid. + */ +#define DDSD_CKSRCOVERLAY 0x00008000l + +/* + * ddckCKSrcBlt is valid. + */ +#define DDSD_CKSRCBLT 0x00010000l + +/* + * dwMipMapCount is valid. + */ +#define DDSD_MIPMAPCOUNT 0x00020000l + + /* + * dwRefreshRate is valid + */ +#define DDSD_REFRESHRATE 0x00040000l + + +/* + * All input fields are valid. + */ +#define DDSD_ALL 0x0007f9eel + + +/*============================================================================ + * + * Direct Draw Capability Flags + * + * These flags are used to describe the capabilities of a given Surface. + * All flags are bit flags. + * + *==========================================================================*/ + +/**************************************************************************** + * + * DIRECTDRAWSURFACE CAPABILITY FLAGS + * + ****************************************************************************/ +/* + * This bit currently has no meaning. + */ +#define DDSCAPS_3D 0x00000001l + +/* + * Indicates that this surface contains alpha information. The pixel + * format must be interrogated to determine whether this surface + * contains only alpha information or alpha information interlaced + * with pixel color data (e.g. RGBA or YUVA). + */ +#define DDSCAPS_ALPHA 0x00000002l + +/* + * Indicates that this surface is a backbuffer. It is generally + * set by CreateSurface when the DDSCAPS_FLIP capability bit is set. + * It indicates that this surface is THE back buffer of a surface + * flipping structure. DirectDraw supports N surfaces in a + * surface flipping structure. Only the surface that immediately + * precedeces the DDSCAPS_FRONTBUFFER has this capability bit set. + * The other surfaces are identified as back buffers by the presence + * of the DDSCAPS_FLIP capability, their attachment order, and the + * absence of the DDSCAPS_FRONTBUFFER and DDSCAPS_BACKBUFFER + * capabilities. The bit is sent to CreateSurface when a standalone + * back buffer is being created. This surface could be attached to + * a front buffer and/or back buffers to form a flipping surface + * structure after the CreateSurface call. See AddAttachments for + * a detailed description of the behaviors in this case. + */ +#define DDSCAPS_BACKBUFFER 0x00000004l + +/* + * Indicates a complex surface structure is being described. A + * complex surface structure results in the creation of more than + * one surface. The additional surfaces are attached to the root + * surface. The complex structure can only be destroyed by + * destroying the root. + */ +#define DDSCAPS_COMPLEX 0x00000008l + +/* + * Indicates that this surface is a part of a surface flipping structure. + * When it is passed to CreateSurface the DDSCAPS_FRONTBUFFER and + * DDSCAP_BACKBUFFER bits are not set. They are set by CreateSurface + * on the resulting creations. The dwBackBufferCount field in the + * DDSURFACEDESC structure must be set to at least 1 in order for + * the CreateSurface call to succeed. The DDSCAPS_COMPLEX capability + * must always be set with creating multiple surfaces through CreateSurface. + */ +#define DDSCAPS_FLIP 0x00000010l + +/* + * Indicates that this surface is THE front buffer of a surface flipping + * structure. It is generally set by CreateSurface when the DDSCAPS_FLIP + * capability bit is set. + * If this capability is sent to CreateSurface then a standalonw front buffer + * is created. This surface will not have the DDSCAPS_FLIP capability. + * It can be attached to other back buffers to form a flipping structure. + * See AddAttachments for a detailed description of the behaviors in this + * case. + */ +#define DDSCAPS_FRONTBUFFER 0x00000020l + +/* + * Indicates that this surface is any offscreen surface that is not an overlay, + * texture, zbuffer, front buffer, back buffer, or alpha surface. It is used + * to identify plain vanilla surfaces. + */ +#define DDSCAPS_OFFSCREENPLAIN 0x00000040l + +/* + * Indicates that this surface is an overlay. It may or may not be directly visible + * depending on whether or not it is currently being overlayed onto the primary + * surface. DDSCAPS_VISIBLE can be used to determine whether or not it is being + * overlayed at the moment. + */ +#define DDSCAPS_OVERLAY 0x00000080l + +/* + * Indicates that unique DirectDrawPalette objects can be created and + * attached to this surface. + */ +#define DDSCAPS_PALETTE 0x00000100l + +/* + * Indicates that this surface is the primary surface. The primary + * surface represents what the user is seeing at the moment. + */ +#define DDSCAPS_PRIMARYSURFACE 0x00000200l + +/* + * Indicates that this surface is the primary surface for the left eye. + * The primary surface for the left eye represents what the user is seeing + * at the moment with the users left eye. When this surface is created the + * DDSCAPS_PRIMARYSURFACE represents what the user is seeing with the users + * right eye. + */ +#define DDSCAPS_PRIMARYSURFACELEFT 0x00000400l + +/* + * Indicates that this surface memory was allocated in system memory + */ +#define DDSCAPS_SYSTEMMEMORY 0x00000800l + +/* + * Indicates that this surface can be used as a 3D texture. It does not + * indicate whether or not the surface is being used for that purpose. + */ +#define DDSCAPS_TEXTURE 0x00001000l + +/* + * Indicates that a surface may be a destination for 3D rendering. This + * bit must be set in order to query for a Direct3D Device Interface + * from this surface. + */ +#define DDSCAPS_3DDEVICE 0x00002000l + +/* + * Indicates that this surface exists in video memory. + */ +#define DDSCAPS_VIDEOMEMORY 0x00004000l + +/* + * Indicates that changes made to this surface are immediately visible. + * It is always set for the primary surface and is set for overlays while + * they are being overlayed and texture maps while they are being textured. + */ +#define DDSCAPS_VISIBLE 0x00008000l + +/* + * Indicates that only writes are permitted to the surface. Read accesses + * from the surface may or may not generate a protection fault, but the + * results of a read from this surface will not be meaningful. READ ONLY. + */ +#define DDSCAPS_WRITEONLY 0x00010000l + +/* + * Indicates that this surface is a z buffer. A z buffer does not contain + * displayable information. Instead it contains bit depth information that is + * used to determine which pixels are visible and which are obscured. + */ +#define DDSCAPS_ZBUFFER 0x00020000l + +/* + * Indicates surface will have a DC associated long term + */ +#define DDSCAPS_OWNDC 0x00040000l + +/* + * Indicates surface should be able to receive live video + */ +#define DDSCAPS_LIVEVIDEO 0x00080000l + +/* + * Indicates surface should be able to have a stream decompressed + * to it by the hardware. + */ +#define DDSCAPS_HWCODEC 0x00100000l + +/* + * Surface is a 320x200 or 320x240 ModeX surface + */ +#define DDSCAPS_MODEX 0x00200000l + +/* + * Indicates surface is one level of a mip-map. This surface will + * be attached to other DDSCAPS_MIPMAP surfaces to form the mip-map. + * This can be done explicitly, by creating a number of surfaces and + * attaching them with AddAttachedSurface or by implicitly by CreateSurface. + * If this bit is set then DDSCAPS_TEXTURE must also be set. + */ +#define DDSCAPS_MIPMAP 0x00400000l + + + +/* + * Indicates that memory for the surface is not allocated until the surface + * is loaded (via the Direct3D texture Load() function). + */ +#define DDSCAPS_ALLOCONLOAD 0x04000000l + + + + /**************************************************************************** + * + * DIRECTDRAW DRIVER CAPABILITY FLAGS + * + ****************************************************************************/ + +/* + * Display hardware has 3D acceleration. + */ +#define DDCAPS_3D 0x00000001l + +/* + * Indicates that DirectDraw will support only dest rectangles that are aligned + * on DIRECTDRAWCAPS.dwAlignBoundaryDest boundaries of the surface, respectively. + * READ ONLY. + */ +#define DDCAPS_ALIGNBOUNDARYDEST 0x00000002l + +/* + * Indicates that DirectDraw will support only source rectangles whose sizes in + * BYTEs are DIRECTDRAWCAPS.dwAlignSizeDest multiples, respectively. READ ONLY. + */ +#define DDCAPS_ALIGNSIZEDEST 0x00000004l +/* + * Indicates that DirectDraw will support only source rectangles that are aligned + * on DIRECTDRAWCAPS.dwAlignBoundarySrc boundaries of the surface, respectively. + * READ ONLY. + */ +#define DDCAPS_ALIGNBOUNDARYSRC 0x00000008l + +/* + * Indicates that DirectDraw will support only source rectangles whose sizes in + * BYTEs are DIRECTDRAWCAPS.dwAlignSizeSrc multiples, respectively. READ ONLY. + */ +#define DDCAPS_ALIGNSIZESRC 0x00000010l + +/* + * Indicates that DirectDraw will create video memory surfaces that have a stride + * alignment equal to DIRECTDRAWCAPS.dwAlignStride. READ ONLY. + */ +#define DDCAPS_ALIGNSTRIDE 0x00000020l + +/* + * Display hardware is capable of blt operations. + */ +#define DDCAPS_BLT 0x00000040l + +/* + * Display hardware is capable of asynchronous blt operations. + */ +#define DDCAPS_BLTQUEUE 0x00000080l + +/* + * Display hardware is capable of color space conversions during the blt operation. + */ +#define DDCAPS_BLTFOURCC 0x00000100l + +/* + * Display hardware is capable of stretching during blt operations. + */ +#define DDCAPS_BLTSTRETCH 0x00000200l + +/* + * Display hardware is shared with GDI. + */ +#define DDCAPS_GDI 0x00000400l + +/* + * Display hardware can overlay. + */ +#define DDCAPS_OVERLAY 0x00000800l + +/* + * Set if display hardware supports overlays but can not clip them. + */ +#define DDCAPS_OVERLAYCANTCLIP 0x00001000l + +/* + * Indicates that overlay hardware is capable of color space conversions during + * the overlay operation. + */ +#define DDCAPS_OVERLAYFOURCC 0x00002000l + +/* + * Indicates that stretching can be done by the overlay hardware. + */ +#define DDCAPS_OVERLAYSTRETCH 0x00004000l + +/* + * Indicates that unique DirectDrawPalettes can be created for DirectDrawSurfaces + * other than the primary surface. + */ +#define DDCAPS_PALETTE 0x00008000l + +/* + * Indicates that palette changes can be syncd with the veritcal refresh. + */ +#define DDCAPS_PALETTEVSYNC 0x00010000l + +/* + * Display hardware can return the current scan line. + */ +#define DDCAPS_READSCANLINE 0x00020000l + +/* + * Display hardware has stereo vision capabilities. DDSCAPS_PRIMARYSURFACELEFT + * can be created. + */ +#define DDCAPS_STEREOVIEW 0x00040000l + +/* + * Display hardware is capable of generating a vertical blank interrupt. + */ +#define DDCAPS_VBI 0x00080000l + +/* + * Supports the use of z buffers with blt operations. + */ +#define DDCAPS_ZBLTS 0x00100000l + +/* + * Supports Z Ordering of overlays. + */ +#define DDCAPS_ZOVERLAYS 0x00200000l + +/* + * Supports color key + */ +#define DDCAPS_COLORKEY 0x00400000l + +/* + * Supports alpha surfaces + */ +#define DDCAPS_ALPHA 0x00800000l + +/* + * colorkey is hardware assisted(DDCAPS_COLORKEY will also be set) + */ +#define DDCAPS_COLORKEYHWASSIST 0x01000000l + +/* + * no hardware support at all + */ +#define DDCAPS_NOHARDWARE 0x02000000l + +/* + * Display hardware is capable of color fill with bltter + */ +#define DDCAPS_BLTCOLORFILL 0x04000000l + +/* + * Display hardware is bank switched, and potentially very slow at + * random access to VRAM. + */ +#define DDCAPS_BANKSWITCHED 0x08000000l + +/* + * Display hardware is capable of depth filling Z-buffers with bltter + */ +#define DDCAPS_BLTDEPTHFILL 0x10000000l + +/* + * Display hardware is capable of clipping while bltting. + */ +#define DDCAPS_CANCLIP 0x20000000l + +/* + * Display hardware is capable of clipping while stretch bltting. + */ +#define DDCAPS_CANCLIPSTRETCHED 0x40000000l + +/* + * Display hardware is capable of bltting to or from system memory + */ +#define DDCAPS_CANBLTSYSMEM 0x80000000l + + + /**************************************************************************** + * + * MORE DIRECTDRAW DRIVER CAPABILITY FLAGS (dwCaps2) + * + ****************************************************************************/ + +/* + * Display hardware is certified + */ +#define DDCAPS2_CERTIFIED 0x00000001l + +/* + * Driver cannot interleave 2D operations (lock and blt) to surfaces with + * Direct3D rendering operations between calls to BeginScene() and EndScene() + */ +#define DDCAPS2_NO2DDURING3DSCENE 0x00000002l + +/**************************************************************************** + * + * DIRECTDRAW FX ALPHA CAPABILITY FLAGS + * + ****************************************************************************/ + +/* + * Supports alpha blending around the edge of a source color keyed surface. + * For Blt. + */ +#define DDFXALPHACAPS_BLTALPHAEDGEBLEND 0x00000001l + +/* + * Supports alpha information in the pixel format. The bit depth of alpha + * information in the pixel format can be 1,2,4, or 8. The alpha value becomes + * more opaque as the alpha value increases. (0 is transparent.) + * For Blt. + */ +#define DDFXALPHACAPS_BLTALPHAPIXELS 0x00000002l + +/* + * Supports alpha information in the pixel format. The bit depth of alpha + * information in the pixel format can be 1,2,4, or 8. The alpha value + * becomes more transparent as the alpha value increases. (0 is opaque.) + * This flag can only be set if DDCAPS_ALPHA is set. + * For Blt. + */ +#define DDFXALPHACAPS_BLTALPHAPIXELSNEG 0x00000004l + +/* + * Supports alpha only surfaces. The bit depth of an alpha only surface can be + * 1,2,4, or 8. The alpha value becomes more opaque as the alpha value increases. + * (0 is transparent.) + * For Blt. + */ +#define DDFXALPHACAPS_BLTALPHASURFACES 0x00000008l + +/* + * The depth of the alpha channel data can range can be 1,2,4, or 8. + * The NEG suffix indicates that this alpha channel becomes more transparent + * as the alpha value increases. (0 is opaque.) This flag can only be set if + * DDCAPS_ALPHA is set. + * For Blt. + */ +#define DDFXALPHACAPS_BLTALPHASURFACESNEG 0x00000010l + +/* + * Supports alpha blending around the edge of a source color keyed surface. + * For Overlays. + */ +#define DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND 0x00000020l + +/* + * Supports alpha information in the pixel format. The bit depth of alpha + * information in the pixel format can be 1,2,4, or 8. The alpha value becomes + * more opaque as the alpha value increases. (0 is transparent.) + * For Overlays. + */ +#define DDFXALPHACAPS_OVERLAYALPHAPIXELS 0x00000040l + +/* + * Supports alpha information in the pixel format. The bit depth of alpha + * information in the pixel format can be 1,2,4, or 8. The alpha value + * becomes more transparent as the alpha value increases. (0 is opaque.) + * This flag can only be set if DDCAPS_ALPHA is set. + * For Overlays. + */ +#define DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG 0x00000080l + +/* + * Supports alpha only surfaces. The bit depth of an alpha only surface can be + * 1,2,4, or 8. The alpha value becomes more opaque as the alpha value increases. + * (0 is transparent.) + * For Overlays. + */ +#define DDFXALPHACAPS_OVERLAYALPHASURFACES 0x00000100l + +/* + * The depth of the alpha channel data can range can be 1,2,4, or 8. + * The NEG suffix indicates that this alpha channel becomes more transparent + * as the alpha value increases. (0 is opaque.) This flag can only be set if + * DDCAPS_ALPHA is set. + * For Overlays. + */ +#define DDFXALPHACAPS_OVERLAYALPHASURFACESNEG 0x00000200l + +/**************************************************************************** + * + * DIRECTDRAW FX CAPABILITY FLAGS + * + ****************************************************************************/ + +/* + * Uses arithmetic operations to stretch and shrink surfaces during blt + * rather than pixel doubling techniques. Along the Y axis. + */ +#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020l + +/* + * Uses arithmetic operations to stretch during blt + * rather than pixel doubling techniques. Along the Y axis. Only + * works for x1, x2, etc. + */ +#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010l + +/* + * Supports mirroring left to right in blt. + */ +#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040l + +/* + * Supports mirroring top to bottom in blt. + */ +#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080l + +/* + * Supports arbitrary rotation for blts. + */ +#define DDFXCAPS_BLTROTATION 0x00000100l + +/* + * Supports 90 degree rotations for blts. + */ +#define DDFXCAPS_BLTROTATION90 0x00000200l + +/* + * DirectDraw supports arbitrary shrinking of a surface along the + * x axis (horizontal direction) for blts. + */ +#define DDFXCAPS_BLTSHRINKX 0x00000400l + +/* + * DirectDraw supports integer shrinking (1x,2x,) of a surface + * along the x axis (horizontal direction) for blts. + */ +#define DDFXCAPS_BLTSHRINKXN 0x00000800l + +/* + * DirectDraw supports arbitrary shrinking of a surface along the + * y axis (horizontal direction) for blts. + */ +#define DDFXCAPS_BLTSHRINKY 0x00001000l + +/* + * DirectDraw supports integer shrinking (1x,2x,) of a surface + * along the y axis (vertical direction) for blts. + */ +#define DDFXCAPS_BLTSHRINKYN 0x00002000l + +/* + * DirectDraw supports arbitrary stretching of a surface along the + * x axis (horizontal direction) for blts. + */ +#define DDFXCAPS_BLTSTRETCHX 0x00004000l + +/* + * DirectDraw supports integer stretching (1x,2x,) of a surface + * along the x axis (horizontal direction) for blts. + */ +#define DDFXCAPS_BLTSTRETCHXN 0x00008000l + +/* + * DirectDraw supports arbitrary stretching of a surface along the + * y axis (horizontal direction) for blts. + */ +#define DDFXCAPS_BLTSTRETCHY 0x00010000l + +/* + * DirectDraw supports integer stretching (1x,2x,) of a surface + * along the y axis (vertical direction) for blts. + */ +#define DDFXCAPS_BLTSTRETCHYN 0x00020000l + +/* + * Uses arithmetic operations to stretch and shrink surfaces during + * overlay rather than pixel doubling techniques. Along the Y axis + * for overlays. + */ +#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000l + +/* + * Uses arithmetic operations to stretch surfaces during + * overlay rather than pixel doubling techniques. Along the Y axis + * for overlays. Only works for x1, x2, etc. + */ +#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008l + +/* + * DirectDraw supports arbitrary shrinking of a surface along the + * x axis (horizontal direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSHRINKX 0x00080000l + +/* + * DirectDraw supports integer shrinking (1x,2x,) of a surface + * along the x axis (horizontal direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000l + +/* + * DirectDraw supports arbitrary shrinking of a surface along the + * y axis (horizontal direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSHRINKY 0x00200000l + +/* + * DirectDraw supports integer shrinking (1x,2x,) of a surface + * along the y axis (vertical direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000l + +/* + * DirectDraw supports arbitrary stretching of a surface along the + * x axis (horizontal direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000l + +/* + * DirectDraw supports integer stretching (1x,2x,) of a surface + * along the x axis (horizontal direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000l + +/* + * DirectDraw supports arbitrary stretching of a surface along the + * y axis (horizontal direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000l + +/* + * DirectDraw supports integer stretching (1x,2x,) of a surface + * along the y axis (vertical direction) for overlays. + */ +#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000l + +/* + * DirectDraw supports mirroring of overlays across the vertical axis + */ +#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000l + +/* + * DirectDraw supports mirroring of overlays across the horizontal axis + */ +#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000l + +/**************************************************************************** + * + * DIRECTDRAW STEREO VIEW CAPABILITIES + * + ****************************************************************************/ + +/* + * The stereo view is accomplished via enigma encoding. + */ +#define DDSVCAPS_ENIGMA 0x00000001l + +/* + * The stereo view is accomplished via high frequency flickering. + */ +#define DDSVCAPS_FLICKER 0x00000002l + +/* + * The stereo view is accomplished via red and blue filters applied + * to the left and right eyes. All images must adapt their colorspaces + * for this process. + */ +#define DDSVCAPS_REDBLUE 0x00000004l + +/* + * The stereo view is accomplished with split screen technology. + */ +#define DDSVCAPS_SPLIT 0x00000008l + +/**************************************************************************** + * + * DIRECTDRAWPALETTE CAPABILITIES + * + ****************************************************************************/ + +/* + * Index is 4 bits. There are sixteen color entries in the palette table. + */ +#define DDPCAPS_4BIT 0x00000001l + +/* + * Index is onto a 8 bit color index. This field is only valid with the + * DDPCAPS_1BIT, DDPCAPS_2BIT or DDPCAPS_4BIT capability and the target + * surface is in 8bpp. Each color entry is one byte long and is an index + * into destination surface's 8bpp palette. + */ +#define DDPCAPS_8BITENTRIES 0x00000002l + +/* + * Index is 8 bits. There are 256 color entries in the palette table. + */ +#define DDPCAPS_8BIT 0x00000004l + +/* + * Indicates that this DIRECTDRAWPALETTE should use the palette color array + * passed into the lpDDColorArray parameter to initialize the DIRECTDRAWPALETTE + * object. + */ +#define DDPCAPS_INITIALIZE 0x00000008l + +/* + * This palette is the one attached to the primary surface. Changing this + * table has immediate effect on the display unless DDPSETPAL_VSYNC is specified + * and supported. + */ +#define DDPCAPS_PRIMARYSURFACE 0x00000010l + +/* + * This palette is the one attached to the primary surface left. Changing + * this table has immediate effect on the display for the left eye unless + * DDPSETPAL_VSYNC is specified and supported. + */ +#define DDPCAPS_PRIMARYSURFACELEFT 0x00000020l + +/* + * This palette can have all 256 entries defined + */ +#define DDPCAPS_ALLOW256 0x00000040l + +/* + * This palette can have modifications to it synced with the monitors + * refresh rate. + */ +#define DDPCAPS_VSYNC 0x00000080l + +/* + * Index is 1 bit. There are two color entries in the palette table. + */ +#define DDPCAPS_1BIT 0x00000100l + +/* + * Index is 2 bit. There are four color entries in the palette table. + */ +#define DDPCAPS_2BIT 0x00000200l + + +/**************************************************************************** + * + * DIRECTDRAWPALETTE SETENTRY CONSTANTS + * + ****************************************************************************/ + + +/**************************************************************************** + * + * DIRECTDRAWPALETTE GETENTRY CONSTANTS + * + ****************************************************************************/ + +/* 0 is the only legal value */ + +/**************************************************************************** + * + * DIRECTDRAWSURFACE SETPALETTE CONSTANTS + * + ****************************************************************************/ + + +/**************************************************************************** + * + * DIRECTDRAW BITDEPTH CONSTANTS + * + * NOTE: These are only used to indicate supported bit depths. These + * are flags only, they are not to be used as an actual bit depth. The + * absolute numbers 1, 2, 4, 8, 16, 24 and 32 are used to indicate actual + * bit depths in a surface or for changing the display mode. + * + ****************************************************************************/ + +/* + * 1 bit per pixel. + */ +#define DDBD_1 0x00004000l + +/* + * 2 bits per pixel. + */ +#define DDBD_2 0x00002000l + +/* + * 4 bits per pixel. + */ +#define DDBD_4 0x00001000l + +/* + * 8 bits per pixel. + */ +#define DDBD_8 0x00000800l + +/* + * 16 bits per pixel. + */ +#define DDBD_16 0x00000400l + +/* + * 24 bits per pixel. + */ +#define DDBD_24 0X00000200l + +/* + * 32 bits per pixel. + */ +#define DDBD_32 0x00000100l + +/**************************************************************************** + * + * DIRECTDRAWSURFACE SET/GET COLOR KEY FLAGS + * + ****************************************************************************/ + +/* + * Set if the structure contains a color space. Not set if the structure + * contains a single color key. + */ +#define DDCKEY_COLORSPACE 0x00000001l + +/* + * Set if the structure specifies a color key or color space which is to be + * used as a destination color key for blt operations. + */ +#define DDCKEY_DESTBLT 0x00000002l + +/* + * Set if the structure specifies a color key or color space which is to be + * used as a destination color key for overlay operations. + */ +#define DDCKEY_DESTOVERLAY 0x00000004l + +/* + * Set if the structure specifies a color key or color space which is to be + * used as a source color key for blt operations. + */ +#define DDCKEY_SRCBLT 0x00000008l + +/* + * Set if the structure specifies a color key or color space which is to be + * used as a source color key for overlay operations. + */ +#define DDCKEY_SRCOVERLAY 0x00000010l + + +/**************************************************************************** + * + * DIRECTDRAW COLOR KEY CAPABILITY FLAGS + * + ****************************************************************************/ + +/* + * Supports transparent blting using a color key to identify the replaceable + * bits of the destination surface for RGB colors. + */ +#define DDCKEYCAPS_DESTBLT 0x00000001l + +/* + * Supports transparent blting using a color space to identify the replaceable + * bits of the destination surface for RGB colors. + */ +#define DDCKEYCAPS_DESTBLTCLRSPACE 0x00000002l + +/* + * Supports transparent blting using a color space to identify the replaceable + * bits of the destination surface for YUV colors. + */ +#define DDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004l + +/* + * Supports transparent blting using a color key to identify the replaceable + * bits of the destination surface for YUV colors. + */ +#define DDCKEYCAPS_DESTBLTYUV 0x00000008l + +/* + * Supports overlaying using colorkeying of the replaceable bits of the surface + * being overlayed for RGB colors. + */ +#define DDCKEYCAPS_DESTOVERLAY 0x00000010l + +/* + * Supports a color space as the color key for the destination for RGB colors. + */ +#define DDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020l + +/* + * Supports a color space as the color key for the destination for YUV colors. + */ +#define DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040l + +/* + * Supports only one active destination color key value for visible overlay + * surfaces. + */ +#define DDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080l + +/* + * Supports overlaying using colorkeying of the replaceable bits of the + * surface being overlayed for YUV colors. + */ +#define DDCKEYCAPS_DESTOVERLAYYUV 0x00000100l + +/* + * Supports transparent blting using the color key for the source with + * this surface for RGB colors. + */ +#define DDCKEYCAPS_SRCBLT 0x00000200l + +/* + * Supports transparent blting using a color space for the source with + * this surface for RGB colors. + */ +#define DDCKEYCAPS_SRCBLTCLRSPACE 0x00000400l + +/* + * Supports transparent blting using a color space for the source with + * this surface for YUV colors. + */ +#define DDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800l + +/* + * Supports transparent blting using the color key for the source with + * this surface for YUV colors. + */ +#define DDCKEYCAPS_SRCBLTYUV 0x00001000l + +/* + * Supports overlays using the color key for the source with this + * overlay surface for RGB colors. + */ +#define DDCKEYCAPS_SRCOVERLAY 0x00002000l + +/* + * Supports overlays using a color space as the source color key for + * the overlay surface for RGB colors. + */ +#define DDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000l + +/* + * Supports overlays using a color space as the source color key for + * the overlay surface for YUV colors. + */ +#define DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000l + +/* + * Supports only one active source color key value for visible + * overlay surfaces. + */ +#define DDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000l + +/* + * Supports overlays using the color key for the source with this + * overlay surface for YUV colors. + */ +#define DDCKEYCAPS_SRCOVERLAYYUV 0x00020000l + +/* + * there are no bandwidth trade-offs for using colorkey with an overlay + */ +#define DDCKEYCAPS_NOCOSTOVERLAY 0x00040000l + + +/**************************************************************************** + * + * DIRECTDRAW PIXELFORMAT FLAGS + * + ****************************************************************************/ + +/* + * The surface has alpha channel information in the pixel format. + */ +#define DDPF_ALPHAPIXELS 0x00000001l + +/* + * The pixel format contains alpha only information + */ +#define DDPF_ALPHA 0x00000002l + +/* + * The FourCC code is valid. + */ +#define DDPF_FOURCC 0x00000004l + +/* + * The surface is 4-bit color indexed. + */ +#define DDPF_PALETTEINDEXED4 0x00000008l + +/* + * The surface is indexed into a palette which stores indices + * into the destination surface's 8-bit palette. + */ +#define DDPF_PALETTEINDEXEDTO8 0x00000010l + +/* + * The surface is 8-bit color indexed. + */ +#define DDPF_PALETTEINDEXED8 0x00000020l + +/* + * The RGB data in the pixel format structure is valid. + */ +#define DDPF_RGB 0x00000040l + +/* + * The surface will accept pixel data in the format specified + * and compress it during the write. + */ +#define DDPF_COMPRESSED 0x00000080l + +/* + * The surface will accept RGB data and translate it during + * the write to YUV data. The format of the data to be written + * will be contained in the pixel format structure. The DDPF_RGB + * flag will be set. + */ +#define DDPF_RGBTOYUV 0x00000100l + +/* + * pixel format is YUV - YUV data in pixel format struct is valid + */ +#define DDPF_YUV 0x00000200l + +/* + * pixel format is a z buffer only surface + */ +#define DDPF_ZBUFFER 0x00000400l + +/* + * The surface is 1-bit color indexed. + */ +#define DDPF_PALETTEINDEXED1 0x00000800l + +/* + * The surface is 2-bit color indexed. + */ +#define DDPF_PALETTEINDEXED2 0x00001000l + +/*=========================================================================== + * + * + * DIRECTDRAW CALLBACK FLAGS + * + * + *==========================================================================*/ + +/**************************************************************************** + * + * DIRECTDRAW ENUMSURFACES FLAGS + * + ****************************************************************************/ + +/* + * Enumerate all of the surfaces that meet the search criterion. + */ +#define DDENUMSURFACES_ALL 0x00000001l + +/* + * A search hit is a surface that matches the surface description. + */ +#define DDENUMSURFACES_MATCH 0x00000002l + +/* + * A search hit is a surface that does not match the surface description. + */ +#define DDENUMSURFACES_NOMATCH 0x00000004l + +/* + * Enumerate the first surface that can be created which meets the search criterion. + */ +#define DDENUMSURFACES_CANBECREATED 0x00000008l + +/* + * Enumerate the surfaces that already exist that meet the search criterion. + */ +#define DDENUMSURFACES_DOESEXIST 0x00000010l + + +/**************************************************************************** + * + * DIRECTDRAW ENUMDISPLAYMODES FLAGS + * + ****************************************************************************/ + +/* + * Enumerate Modes with different refresh rates. EnumDisplayModes guarantees + * that a particular mode will be enumerated only once. This flag specifies whether + * the refresh rate is taken into account when determining if a mode is unique. + */ +#define DDEDM_REFRESHRATES 0x00000001l + + +/**************************************************************************** + * + * DIRECTDRAW SETCOOPERATIVELEVEL FLAGS + * + ****************************************************************************/ + +/* + * Exclusive mode owner will be responsible for the entire primary surface. + * GDI can be ignored. used with DD + */ +#define DDSCL_FULLSCREEN 0x00000001l + +/* + * allow CTRL_ALT_DEL to work while in fullscreen exclusive mode + */ +#define DDSCL_ALLOWREBOOT 0x00000002l + +/* + * prevents DDRAW from modifying the application window. + * prevents DDRAW from minimize/restore the application window on activation. + */ +#define DDSCL_NOWINDOWCHANGES 0x00000004l + +/* + * app wants to work as a regular Windows application + */ +#define DDSCL_NORMAL 0x00000008l + +/* + * app wants exclusive access + */ +#define DDSCL_EXCLUSIVE 0x00000010l + + +/* + * app can deal with non-windows display modes + */ +#define DDSCL_ALLOWMODEX 0x00000040l + + +/**************************************************************************** + * + * DIRECTDRAW BLT FLAGS + * + ****************************************************************************/ + +/* + * Use the alpha information in the pixel format or the alpha channel surface + * attached to the destination surface as the alpha channel for this blt. + */ +#define DDBLT_ALPHADEST 0x00000001l + +/* + * Use the dwConstAlphaDest field in the DDBLTFX structure as the alpha channel + * for the destination surface for this blt. + */ +#define DDBLT_ALPHADESTCONSTOVERRIDE 0x00000002l + +/* + * The NEG suffix indicates that the destination surface becomes more + * transparent as the alpha value increases. (0 is opaque) + */ +#define DDBLT_ALPHADESTNEG 0x00000004l + +/* + * Use the lpDDSAlphaDest field in the DDBLTFX structure as the alpha + * channel for the destination for this blt. + */ +#define DDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008l + +/* + * Use the dwAlphaEdgeBlend field in the DDBLTFX structure as the alpha channel + * for the edges of the image that border the color key colors. + */ +#define DDBLT_ALPHAEDGEBLEND 0x00000010l + +/* + * Use the alpha information in the pixel format or the alpha channel surface + * attached to the source surface as the alpha channel for this blt. + */ +#define DDBLT_ALPHASRC 0x00000020l + +/* + * Use the dwConstAlphaSrc field in the DDBLTFX structure as the alpha channel + * for the source for this blt. + */ +#define DDBLT_ALPHASRCCONSTOVERRIDE 0x00000040l + +/* + * The NEG suffix indicates that the source surface becomes more transparent + * as the alpha value increases. (0 is opaque) + */ +#define DDBLT_ALPHASRCNEG 0x00000080l + +/* + * Use the lpDDSAlphaSrc field in the DDBLTFX structure as the alpha channel + * for the source for this blt. + */ +#define DDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100l + +/* + * Do this blt asynchronously through the FIFO in the order received. If + * there is no room in the hardware FIFO fail the call. + */ +#define DDBLT_ASYNC 0x00000200l + +/* + * Uses the dwFillColor field in the DDBLTFX structure as the RGB color + * to fill the destination rectangle on the destination surface with. + */ +#define DDBLT_COLORFILL 0x00000400l + +/* + * Uses the dwDDFX field in the DDBLTFX structure to specify the effects + * to use for the blt. + */ +#define DDBLT_DDFX 0x00000800l + +/* + * Uses the dwDDROPS field in the DDBLTFX structure to specify the ROPS + * that are not part of the Win32 API. + */ +#define DDBLT_DDROPS 0x00001000l + +/* + * Use the color key associated with the destination surface. + */ +#define DDBLT_KEYDEST 0x00002000l + +/* + * Use the dckDestColorkey field in the DDBLTFX structure as the color key + * for the destination surface. + */ +#define DDBLT_KEYDESTOVERRIDE 0x00004000l + +/* + * Use the color key associated with the source surface. + */ +#define DDBLT_KEYSRC 0x00008000l + +/* + * Use the dckSrcColorkey field in the DDBLTFX structure as the color key + * for the source surface. + */ +#define DDBLT_KEYSRCOVERRIDE 0x00010000l + +/* + * Use the dwROP field in the DDBLTFX structure for the raster operation + * for this blt. These ROPs are the same as the ones defined in the Win32 API. + */ +#define DDBLT_ROP 0x00020000l + +/* + * Use the dwRotationAngle field in the DDBLTFX structure as the angle + * (specified in 1/100th of a degree) to rotate the surface. + */ +#define DDBLT_ROTATIONANGLE 0x00040000l + +/* + * Z-buffered blt using the z-buffers attached to the source and destination + * surfaces and the dwZBufferOpCode field in the DDBLTFX structure as the + * z-buffer opcode. + */ +#define DDBLT_ZBUFFER 0x00080000l + +/* + * Z-buffered blt using the dwConstDest Zfield and the dwZBufferOpCode field + * in the DDBLTFX structure as the z-buffer and z-buffer opcode respectively + * for the destination. + */ +#define DDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000l + +/* + * Z-buffered blt using the lpDDSDestZBuffer field and the dwZBufferOpCode + * field in the DDBLTFX structure as the z-buffer and z-buffer opcode + * respectively for the destination. + */ +#define DDBLT_ZBUFFERDESTOVERRIDE 0x00200000l + +/* + * Z-buffered blt using the dwConstSrcZ field and the dwZBufferOpCode field + * in the DDBLTFX structure as the z-buffer and z-buffer opcode respectively + * for the source. + */ +#define DDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000l + +/* + * Z-buffered blt using the lpDDSSrcZBuffer field and the dwZBufferOpCode + * field in the DDBLTFX structure as the z-buffer and z-buffer opcode + * respectively for the source. + */ +#define DDBLT_ZBUFFERSRCOVERRIDE 0x00800000l + +/* + * wait until the device is ready to handle the blt + * this will cause blt to not return DDERR_WASSTILLDRAWING + */ +#define DDBLT_WAIT 0x01000000l + +/* + * Uses the dwFillDepth field in the DDBLTFX structure as the depth value + * to fill the destination rectangle on the destination Z-buffer surface + * with. + */ +#define DDBLT_DEPTHFILL 0x02000000l + + +/**************************************************************************** + * + * BLTFAST FLAGS + * + ****************************************************************************/ + +#define DDBLTFAST_NOCOLORKEY 0x00000000 +#define DDBLTFAST_SRCCOLORKEY 0x00000001 +#define DDBLTFAST_DESTCOLORKEY 0x00000002 +#define DDBLTFAST_WAIT 0x00000010 + +/**************************************************************************** + * + * FLIP FLAGS + * + ****************************************************************************/ + +#define DDFLIP_WAIT 0x00000001l + + +/**************************************************************************** + * + * DIRECTDRAW SURFACE OVERLAY FLAGS + * + ****************************************************************************/ + +/* + * Use the alpha information in the pixel format or the alpha channel surface + * attached to the destination surface as the alpha channel for the + * destination overlay. + */ +#define DDOVER_ALPHADEST 0x00000001l + +/* + * Use the dwConstAlphaDest field in the DDOVERLAYFX structure as the + * destination alpha channel for this overlay. + */ +#define DDOVER_ALPHADESTCONSTOVERRIDE 0x00000002l + +/* + * The NEG suffix indicates that the destination surface becomes more + * transparent as the alpha value increases. + */ +#define DDOVER_ALPHADESTNEG 0x00000004l + +/* + * Use the lpDDSAlphaDest field in the DDOVERLAYFX structure as the alpha + * channel destination for this overlay. + */ +#define DDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008l + +/* + * Use the dwAlphaEdgeBlend field in the DDOVERLAYFX structure as the alpha + * channel for the edges of the image that border the color key colors. + */ +#define DDOVER_ALPHAEDGEBLEND 0x00000010l + +/* + * Use the alpha information in the pixel format or the alpha channel surface + * attached to the source surface as the source alpha channel for this overlay. + */ +#define DDOVER_ALPHASRC 0x00000020l + +/* + * Use the dwConstAlphaSrc field in the DDOVERLAYFX structure as the source + * alpha channel for this overlay. + */ +#define DDOVER_ALPHASRCCONSTOVERRIDE 0x00000040l + +/* + * The NEG suffix indicates that the source surface becomes more transparent + * as the alpha value increases. + */ +#define DDOVER_ALPHASRCNEG 0x00000080l + +/* + * Use the lpDDSAlphaSrc field in the DDOVERLAYFX structure as the alpha channel + * source for this overlay. + */ +#define DDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100l + +/* + * Turn this overlay off. + */ +#define DDOVER_HIDE 0x00000200l + +/* + * Use the color key associated with the destination surface. + */ +#define DDOVER_KEYDEST 0x00000400l + +/* + * Use the dckDestColorkey field in the DDOVERLAYFX structure as the color key + * for the destination surface + */ +#define DDOVER_KEYDESTOVERRIDE 0x00000800l + +/* + * Use the color key associated with the source surface. + */ +#define DDOVER_KEYSRC 0x00001000l + +/* + * Use the dckSrcColorkey field in the DDOVERLAYFX structure as the color key + * for the source surface. + */ +#define DDOVER_KEYSRCOVERRIDE 0x00002000l + +/* + * Turn this overlay on. + */ +#define DDOVER_SHOW 0x00004000l + +/* + * Add a dirty rect to an emulated overlayed surface. + */ +#define DDOVER_ADDDIRTYRECT 0x00008000l + +/* + * Redraw all dirty rects on an emulated overlayed surface. + */ +#define DDOVER_REFRESHDIRTYRECTS 0x00010000l + +/* + * Redraw the entire surface on an emulated overlayed surface. + */ +#define DDOVER_REFRESHALL 0x00020000l + + +/* + * Use the overlay FX flags to define special overlay FX + */ +#define DDOVER_DDFX 0x00080000l + + +/**************************************************************************** + * + * DIRECTDRAWSURFACE LOCK FLAGS + * + ****************************************************************************/ + +/* + * The default. Set to indicate that Lock should return a valid memory pointer + * to the top of the specified rectangle. If no rectangle is specified then a + * pointer to the top of the surface is returned. + */ +#define DDLOCK_SURFACEMEMORYPTR 0x00000000L // default + +/* + * Set to indicate that Lock should wait until it can obtain a valid memory + * pointer before returning. If this bit is set, Lock will never return + * DDERR_WASSTILLDRAWING. + */ +#define DDLOCK_WAIT 0x00000001L + +/* + * Set if an event handle is being passed to Lock. Lock will trigger the event + * when it can return the surface memory pointer requested. + */ +#define DDLOCK_EVENT 0x00000002L + +/* + * Indicates that the surface being locked will only be read from. + */ +#define DDLOCK_READONLY 0x00000010L + +/* + * Indicates that the surface being locked will only be written to + */ +#define DDLOCK_WRITEONLY 0x00000020L + + +/**************************************************************************** + * + * DIRECTDRAWSURFACE PAGELOCK FLAGS + * + ****************************************************************************/ + +/* + * No flags defined at present + */ + + +/**************************************************************************** + * + * DIRECTDRAWSURFACE PAGEUNLOCK FLAGS + * + ****************************************************************************/ + +/* + * No flags defined at present + */ + + +/**************************************************************************** + * + * DIRECTDRAWSURFACE BLT FX FLAGS + * + ****************************************************************************/ + +/* + * If stretching, use arithmetic stretching along the Y axis for this blt. + */ +#define DDBLTFX_ARITHSTRETCHY 0x00000001l + +/* + * Do this blt mirroring the surface left to right. Spin the + * surface around its y-axis. + */ +#define DDBLTFX_MIRRORLEFTRIGHT 0x00000002l + +/* + * Do this blt mirroring the surface up and down. Spin the surface + * around its x-axis. + */ +#define DDBLTFX_MIRRORUPDOWN 0x00000004l + +/* + * Schedule this blt to avoid tearing. + */ +#define DDBLTFX_NOTEARING 0x00000008l + +/* + * Do this blt rotating the surface one hundred and eighty degrees. + */ +#define DDBLTFX_ROTATE180 0x00000010l + +/* + * Do this blt rotating the surface two hundred and seventy degrees. + */ +#define DDBLTFX_ROTATE270 0x00000020l + +/* + * Do this blt rotating the surface ninety degrees. + */ +#define DDBLTFX_ROTATE90 0x00000040l + +/* + * Do this z blt using dwZBufferLow and dwZBufferHigh as range values + * specified to limit the bits copied from the source surface. + */ +#define DDBLTFX_ZBUFFERRANGE 0x00000080l + +/* + * Do this z blt adding the dwZBufferBaseDest to each of the sources z values + * before comparing it with the desting z values. + */ +#define DDBLTFX_ZBUFFERBASEDEST 0x00000100l + +/**************************************************************************** + * + * DIRECTDRAWSURFACE OVERLAY FX FLAGS + * + ****************************************************************************/ + +/* + * If stretching, use arithmetic stretching along the Y axis for this overlay. + */ +#define DDOVERFX_ARITHSTRETCHY 0x00000001l + +/* + * Mirror the overlay across the vertical axis + */ +#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002l + +/* + * Mirror the overlay across the horizontal axis + */ +#define DDOVERFX_MIRRORUPDOWN 0x00000004l + +/**************************************************************************** + * + * DIRECTDRAW WAITFORVERTICALBLANK FLAGS + * + ****************************************************************************/ + +/* + * return when the vertical blank interval begins + */ +#define DDWAITVB_BLOCKBEGIN 0x00000001l + +/* + * set up an event to trigger when the vertical blank begins + */ +#define DDWAITVB_BLOCKBEGINEVENT 0x00000002l + +/* + * return when the vertical blank interval ends and display begins + */ +#define DDWAITVB_BLOCKEND 0x00000004l + +/**************************************************************************** + * + * DIRECTDRAW GETFLIPSTATUS FLAGS + * + ****************************************************************************/ + +/* + * is it OK to flip now? + */ +#define DDGFS_CANFLIP 0x00000001l + +/* + * is the last flip finished? + */ +#define DDGFS_ISFLIPDONE 0x00000002l + +/**************************************************************************** + * + * DIRECTDRAW GETBLTSTATUS FLAGS + * + ****************************************************************************/ + +/* + * is it OK to blt now? + */ +#define DDGBS_CANBLT 0x00000001l + +/* + * is the blt to the surface finished? + */ +#define DDGBS_ISBLTDONE 0x00000002l + + +/**************************************************************************** + * + * DIRECTDRAW ENUMOVERLAYZORDER FLAGS + * + ****************************************************************************/ + +/* + * Enumerate overlays back to front. + */ +#define DDENUMOVERLAYZ_BACKTOFRONT 0x00000000l + +/* + * Enumerate overlays front to back + */ +#define DDENUMOVERLAYZ_FRONTTOBACK 0x00000001l + +/**************************************************************************** + * + * DIRECTDRAW UPDATEOVERLAYZORDER FLAGS + * + ****************************************************************************/ + +/* + * Send overlay to front + */ +#define DDOVERZ_SENDTOFRONT 0x00000000l + +/* + * Send overlay to back + */ +#define DDOVERZ_SENDTOBACK 0x00000001l + +/* + * Move Overlay forward + */ +#define DDOVERZ_MOVEFORWARD 0x00000002l + +/* + * Move Overlay backward + */ +#define DDOVERZ_MOVEBACKWARD 0x00000003l + +/* + * Move Overlay in front of relative surface + */ +#define DDOVERZ_INSERTINFRONTOF 0x00000004l + +/* + * Move Overlay in back of relative surface + */ +#define DDOVERZ_INSERTINBACKOF 0x00000005l + +/*=========================================================================== + * + * + * DIRECTDRAW RETURN CODES + * + * The return values from DirectDraw Commands and Surface that return an HRESULT + * are codes from DirectDraw concerning the results of the action + * requested by DirectDraw. + * + *==========================================================================*/ + +/* + * Status is OK + * + * Issued by: DirectDraw Commands and all callbacks + */ +#define DD_OK 0 + +/**************************************************************************** + * + * DIRECTDRAW ENUMCALLBACK RETURN VALUES + * + * EnumCallback returns are used to control the flow of the DIRECTDRAW and + * DIRECTDRAWSURFACE object enumerations. They can only be returned by + * enumeration callback routines. + * + ****************************************************************************/ + +/* + * stop the enumeration + */ +#define DDENUMRET_CANCEL 0 + +/* + * continue the enumeration + */ +#define DDENUMRET_OK 1 + +/**************************************************************************** + * + * DIRECTDRAW ERRORS + * + * Errors are represented by negative values and cannot be combined. + * + ****************************************************************************/ + +/* + * This object is already initialized + */ +#define DDERR_ALREADYINITIALIZED MAKE_DDHRESULT( 5 ) + +/* + * This surface can not be attached to the requested surface. + */ +#define DDERR_CANNOTATTACHSURFACE MAKE_DDHRESULT( 10 ) + +/* + * This surface can not be detached from the requested surface. + */ +#define DDERR_CANNOTDETACHSURFACE MAKE_DDHRESULT( 20 ) + +/* + * Support is currently not available. + */ +#define DDERR_CURRENTLYNOTAVAIL MAKE_DDHRESULT( 40 ) + +/* + * An exception was encountered while performing the requested operation + */ +#define DDERR_EXCEPTION MAKE_DDHRESULT( 55 ) + +/* + * Generic failure. + */ +#define DDERR_GENERIC E_FAIL + +/* + * Height of rectangle provided is not a multiple of reqd alignment + */ +#define DDERR_HEIGHTALIGN MAKE_DDHRESULT( 90 ) + +/* + * Unable to match primary surface creation request with existing + * primary surface. + */ +#define DDERR_INCOMPATIBLEPRIMARY MAKE_DDHRESULT( 95 ) + +/* + * One or more of the caps bits passed to the callback are incorrect. + */ +#define DDERR_INVALIDCAPS MAKE_DDHRESULT( 100 ) + +/* + * DirectDraw does not support provided Cliplist. + */ +#define DDERR_INVALIDCLIPLIST MAKE_DDHRESULT( 110 ) + +/* + * DirectDraw does not support the requested mode + */ +#define DDERR_INVALIDMODE MAKE_DDHRESULT( 120 ) + +/* + * DirectDraw received a pointer that was an invalid DIRECTDRAW object. + */ +#define DDERR_INVALIDOBJECT MAKE_DDHRESULT( 130 ) + +/* + * One or more of the parameters passed to the callback function are + * incorrect. + */ +#define DDERR_INVALIDPARAMS E_INVALIDARG + +/* + * pixel format was invalid as specified + */ +#define DDERR_INVALIDPIXELFORMAT MAKE_DDHRESULT( 145 ) + +/* + * Rectangle provided was invalid. + */ +#define DDERR_INVALIDRECT MAKE_DDHRESULT( 150 ) + +/* + * Operation could not be carried out because one or more surfaces are locked + */ +#define DDERR_LOCKEDSURFACES MAKE_DDHRESULT( 160 ) + +/* + * There is no 3D present. + */ +#define DDERR_NO3D MAKE_DDHRESULT( 170 ) + +/* + * Operation could not be carried out because there is no alpha accleration + * hardware present or available. + */ +#define DDERR_NOALPHAHW MAKE_DDHRESULT( 180 ) + + +/* + * no clip list available + */ +#define DDERR_NOCLIPLIST MAKE_DDHRESULT( 205 ) + +/* + * Operation could not be carried out because there is no color conversion + * hardware present or available. + */ +#define DDERR_NOCOLORCONVHW MAKE_DDHRESULT( 210 ) + +/* + * Create function called without DirectDraw object method SetCooperativeLevel + * being called. + */ +#define DDERR_NOCOOPERATIVELEVELSET MAKE_DDHRESULT( 212 ) + +/* + * Surface doesn't currently have a color key + */ +#define DDERR_NOCOLORKEY MAKE_DDHRESULT( 215 ) + +/* + * Operation could not be carried out because there is no hardware support + * of the dest color key. + */ +#define DDERR_NOCOLORKEYHW MAKE_DDHRESULT( 220 ) + +/* + * No DirectDraw support possible with current display driver + */ +#define DDERR_NODIRECTDRAWSUPPORT MAKE_DDHRESULT( 222 ) + +/* + * Operation requires the application to have exclusive mode but the + * application does not have exclusive mode. + */ +#define DDERR_NOEXCLUSIVEMODE MAKE_DDHRESULT( 225 ) + +/* + * Flipping visible surfaces is not supported. + */ +#define DDERR_NOFLIPHW MAKE_DDHRESULT( 230 ) + +/* + * There is no GDI present. + */ +#define DDERR_NOGDI MAKE_DDHRESULT( 240 ) + +/* + * Operation could not be carried out because there is no hardware present + * or available. + */ +#define DDERR_NOMIRRORHW MAKE_DDHRESULT( 250 ) + +/* + * Requested item was not found + */ +#define DDERR_NOTFOUND MAKE_DDHRESULT( 255 ) + +/* + * Operation could not be carried out because there is no overlay hardware + * present or available. + */ +#define DDERR_NOOVERLAYHW MAKE_DDHRESULT( 260 ) + +/* + * Operation could not be carried out because there is no appropriate raster + * op hardware present or available. + */ +#define DDERR_NORASTEROPHW MAKE_DDHRESULT( 280 ) + +/* + * Operation could not be carried out because there is no rotation hardware + * present or available. + */ +#define DDERR_NOROTATIONHW MAKE_DDHRESULT( 290 ) + +/* + * Operation could not be carried out because there is no hardware support + * for stretching + */ +#define DDERR_NOSTRETCHHW MAKE_DDHRESULT( 310 ) + +/* + * DirectDrawSurface is not in 4 bit color palette and the requested operation + * requires 4 bit color palette. + */ +#define DDERR_NOT4BITCOLOR MAKE_DDHRESULT( 316 ) + +/* + * DirectDrawSurface is not in 4 bit color index palette and the requested + * operation requires 4 bit color index palette. + */ +#define DDERR_NOT4BITCOLORINDEX MAKE_DDHRESULT( 317 ) + +/* + * DirectDraw Surface is not in 8 bit color mode and the requested operation + * requires 8 bit color. + */ +#define DDERR_NOT8BITCOLOR MAKE_DDHRESULT( 320 ) + +/* + * Operation could not be carried out because there is no texture mapping + * hardware present or available. + */ +#define DDERR_NOTEXTUREHW MAKE_DDHRESULT( 330 ) + +/* + * Operation could not be carried out because there is no hardware support + * for vertical blank synchronized operations. + */ +#define DDERR_NOVSYNCHW MAKE_DDHRESULT( 335 ) + +/* + * Operation could not be carried out because there is no hardware support + * for zbuffer blting. + */ +#define DDERR_NOZBUFFERHW MAKE_DDHRESULT( 340 ) + +/* + * Overlay surfaces could not be z layered based on their BltOrder because + * the hardware does not support z layering of overlays. + */ +#define DDERR_NOZOVERLAYHW MAKE_DDHRESULT( 350 ) + +/* + * The hardware needed for the requested operation has already been + * allocated. + */ +#define DDERR_OUTOFCAPS MAKE_DDHRESULT( 360 ) + +/* + * DirectDraw does not have enough memory to perform the operation. + */ +#define DDERR_OUTOFMEMORY E_OUTOFMEMORY + +/* + * DirectDraw does not have enough memory to perform the operation. + */ +#define DDERR_OUTOFVIDEOMEMORY MAKE_DDHRESULT( 380 ) + +/* + * hardware does not support clipped overlays + */ +#define DDERR_OVERLAYCANTCLIP MAKE_DDHRESULT( 382 ) + +/* + * Can only have ony color key active at one time for overlays + */ +#define DDERR_OVERLAYCOLORKEYONLYONEACTIVE MAKE_DDHRESULT( 384 ) + +/* + * Access to this palette is being refused because the palette is already + * locked by another thread. + */ +#define DDERR_PALETTEBUSY MAKE_DDHRESULT( 387 ) + +/* + * No src color key specified for this operation. + */ +#define DDERR_COLORKEYNOTSET MAKE_DDHRESULT( 400 ) + +/* + * This surface is already attached to the surface it is being attached to. + */ +#define DDERR_SURFACEALREADYATTACHED MAKE_DDHRESULT( 410 ) + +/* + * This surface is already a dependency of the surface it is being made a + * dependency of. + */ +#define DDERR_SURFACEALREADYDEPENDENT MAKE_DDHRESULT( 420 ) + +/* + * Access to this surface is being refused because the surface is already + * locked by another thread. + */ +#define DDERR_SURFACEBUSY MAKE_DDHRESULT( 430 ) + +/* + * Access to this surface is being refused because no driver exists + * which can supply a pointer to the surface. + * This is most likely to happen when attempting to lock the primary + * surface when no DCI provider is present. + */ +#define DDERR_CANTLOCKSURFACE MAKE_DDHRESULT( 435 ) + +/* + * Access to Surface refused because Surface is obscured. + */ +#define DDERR_SURFACEISOBSCURED MAKE_DDHRESULT( 440 ) + +/* + * Access to this surface is being refused because the surface is gone. + * The DIRECTDRAWSURFACE object representing this surface should + * have Restore called on it. + */ +#define DDERR_SURFACELOST MAKE_DDHRESULT( 450 ) + +/* + * The requested surface is not attached. + */ +#define DDERR_SURFACENOTATTACHED MAKE_DDHRESULT( 460 ) + +/* + * Height requested by DirectDraw is too large. + */ +#define DDERR_TOOBIGHEIGHT MAKE_DDHRESULT( 470 ) + +/* + * Size requested by DirectDraw is too large -- The individual height and + * width are OK. + */ +#define DDERR_TOOBIGSIZE MAKE_DDHRESULT( 480 ) + +/* + * Width requested by DirectDraw is too large. + */ +#define DDERR_TOOBIGWIDTH MAKE_DDHRESULT( 490 ) + +/* + * Action not supported. + */ +#define DDERR_UNSUPPORTED E_NOTIMPL + +/* + * FOURCC format requested is unsupported by DirectDraw + */ +#define DDERR_UNSUPPORTEDFORMAT MAKE_DDHRESULT( 510 ) + +/* + * Bitmask in the pixel format requested is unsupported by DirectDraw + */ +#define DDERR_UNSUPPORTEDMASK MAKE_DDHRESULT( 520 ) + +/* + * vertical blank is in progress + */ +#define DDERR_VERTICALBLANKINPROGRESS MAKE_DDHRESULT( 537 ) + +/* + * Informs DirectDraw that the previous Blt which is transfering information + * to or from this Surface is incomplete. + */ +#define DDERR_WASSTILLDRAWING MAKE_DDHRESULT( 540 ) + +/* + * Rectangle provided was not horizontally aligned on reqd. boundary + */ +#define DDERR_XALIGN MAKE_DDHRESULT( 560 ) + +/* + * The GUID passed to DirectDrawCreate is not a valid DirectDraw driver + * identifier. + */ +#define DDERR_INVALIDDIRECTDRAWGUID MAKE_DDHRESULT( 561 ) + +/* + * A DirectDraw object representing this driver has already been created + * for this process. + */ +#define DDERR_DIRECTDRAWALREADYCREATED MAKE_DDHRESULT( 562 ) + +/* + * A hardware only DirectDraw object creation was attempted but the driver + * did not support any hardware. + */ +#define DDERR_NODIRECTDRAWHW MAKE_DDHRESULT( 563 ) + +/* + * this process already has created a primary surface + */ +#define DDERR_PRIMARYSURFACEALREADYEXISTS MAKE_DDHRESULT( 564 ) + +/* + * software emulation not available. + */ +#define DDERR_NOEMULATION MAKE_DDHRESULT( 565 ) + +/* + * region passed to Clipper::GetClipList is too small. + */ +#define DDERR_REGIONTOOSMALL MAKE_DDHRESULT( 566 ) + +/* + * an attempt was made to set a clip list for a clipper objec that + * is already monitoring an hwnd. + */ +#define DDERR_CLIPPERISUSINGHWND MAKE_DDHRESULT( 567 ) + +/* + * No clipper object attached to surface object + */ +#define DDERR_NOCLIPPERATTACHED MAKE_DDHRESULT( 568 ) + +/* + * Clipper notification requires an HWND or + * no HWND has previously been set as the CooperativeLevel HWND. + */ +#define DDERR_NOHWND MAKE_DDHRESULT( 569 ) + +/* + * HWND used by DirectDraw CooperativeLevel has been subclassed, + * this prevents DirectDraw from restoring state. + */ +#define DDERR_HWNDSUBCLASSED MAKE_DDHRESULT( 570 ) + +/* + * The CooperativeLevel HWND has already been set. + * It can not be reset while the process has surfaces or palettes created. + */ +#define DDERR_HWNDALREADYSET MAKE_DDHRESULT( 571 ) + +/* + * No palette object attached to this surface. + */ +#define DDERR_NOPALETTEATTACHED MAKE_DDHRESULT( 572 ) + +/* + * No hardware support for 16 or 256 color palettes. + */ +#define DDERR_NOPALETTEHW MAKE_DDHRESULT( 573 ) + +/* + * If a clipper object is attached to the source surface passed into a + * BltFast call. + */ +#define DDERR_BLTFASTCANTCLIP MAKE_DDHRESULT( 574 ) + +/* + * No blter. + */ +#define DDERR_NOBLTHW MAKE_DDHRESULT( 575 ) + +/* + * No DirectDraw ROP hardware. + */ +#define DDERR_NODDROPSHW MAKE_DDHRESULT( 576 ) + +/* + * returned when GetOverlayPosition is called on a hidden overlay + */ +#define DDERR_OVERLAYNOTVISIBLE MAKE_DDHRESULT( 577 ) + +/* + * returned when GetOverlayPosition is called on a overlay that UpdateOverlay + * has never been called on to establish a destionation. + */ +#define DDERR_NOOVERLAYDEST MAKE_DDHRESULT( 578 ) + +/* + * returned when the position of the overlay on the destionation is no longer + * legal for that destionation. + */ +#define DDERR_INVALIDPOSITION MAKE_DDHRESULT( 579 ) + +/* + * returned when an overlay member is called for a non-overlay surface + */ +#define DDERR_NOTAOVERLAYSURFACE MAKE_DDHRESULT( 580 ) + +/* + * An attempt was made to set the cooperative level when it was already + * set to exclusive. + */ +#define DDERR_EXCLUSIVEMODEALREADYSET MAKE_DDHRESULT( 581 ) + +/* + * An attempt has been made to flip a surface that is not flippable. + */ +#define DDERR_NOTFLIPPABLE MAKE_DDHRESULT( 582 ) + +/* + * Can't duplicate primary & 3D surfaces, or surfaces that are implicitly + * created. + */ +#define DDERR_CANTDUPLICATE MAKE_DDHRESULT( 583 ) + +/* + * Surface was not locked. An attempt to unlock a surface that was not + * locked at all, or by this process, has been attempted. + */ +#define DDERR_NOTLOCKED MAKE_DDHRESULT( 584 ) + +/* + * Windows can not create any more DCs + */ +#define DDERR_CANTCREATEDC MAKE_DDHRESULT( 585 ) + +/* + * No DC was ever created for this surface. + */ +#define DDERR_NODC MAKE_DDHRESULT( 586 ) + +/* + * This surface can not be restored because it was created in a different + * mode. + */ +#define DDERR_WRONGMODE MAKE_DDHRESULT( 587 ) + +/* + * This surface can not be restored because it is an implicitly created + * surface. + */ +#define DDERR_IMPLICITLYCREATED MAKE_DDHRESULT( 588 ) + +/* + * The surface being used is not a palette-based surface + */ +#define DDERR_NOTPALETTIZED MAKE_DDHRESULT( 589 ) + + +/* + * The display is currently in an unsupported mode + */ +#define DDERR_UNSUPPORTEDMODE MAKE_DDHRESULT( 590 ) + +/* + * Operation could not be carried out because there is no mip-map + * texture mapping hardware present or available. + */ +#define DDERR_NOMIPMAPHW MAKE_DDHRESULT( 591 ) + +/* + * The requested action could not be performed because the surface was of + * the wrong type. + */ +#define DDERR_INVALIDSURFACETYPE MAKE_DDHRESULT( 592 ) + + + +/* + * A DC has already been returned for this surface. Only one DC can be + * retrieved per surface. + */ +#define DDERR_DCALREADYCREATED MAKE_DDHRESULT( 620 ) + +/* + * The attempt to page lock a surface failed. + */ +#define DDERR_CANTPAGELOCK MAKE_DDHRESULT( 640 ) + +/* + * The attempt to page unlock a surface failed. + */ +#define DDERR_CANTPAGEUNLOCK MAKE_DDHRESULT( 660 ) + +/* + * An attempt was made to page unlock a surface with no outstanding page locks. + */ +#define DDERR_NOTPAGELOCKED MAKE_DDHRESULT( 680 ) + +/* + * An attempt was made to invoke an interface member of a DirectDraw object + * created by CoCreateInstance() before it was initialized. + */ +#define DDERR_NOTINITIALIZED CO_E_NOTINITIALIZED + +/* Alpha bit depth constants */ + + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/DDRAW.LIB b/DDRAW.LIB new file mode 100644 index 0000000..7dbd0aa Binary files /dev/null and b/DDRAW.LIB differ diff --git a/DEAD.CPP b/DEAD.CPP new file mode 100644 index 0000000..cd33208 --- /dev/null +++ b/DEAD.CPP @@ -0,0 +1,123 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Dead file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DEAD.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "dead.h" +#include "monster.h" +#include "monstint.h" +#include "missiles.h" +#include "misdat.h" +#include "gendung.h" +#include "lighting.h" + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +DeadStruct dead[MAXDEAD]; +int spurtndx; +int stonendx; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitDead () +{ + int nd,i,j,mi; + int mtypes[MONSTERTYPES]; + + for (i = 0; i < MONSTERTYPES; i++) mtypes[i] = 0; + + nd = 0; + for (i = 0; i < nummtypes; i++) { + if (mtypes[Monsters[i].mtype] == 0) { + for (j = 0; j < 8; j++) dead[nd]._deadData[j] = Monsters[i].Anims[MA_DEATH].Cels[j]; + dead[nd]._deadFrame = Monsters[i].Anims[MA_DEATH].Frames; + dead[nd]._deadWidth = Monsters[i].mAnimWidth; + dead[nd]._deadWidth2 = Monsters[i].mAnimWidth2; + dead[nd]._deadtrans = 0; + Monsters[i].mdeadval = nd + 1; + mtypes[Monsters[i].mtype] = nd + 1; + nd++; + } + } + + // set blood burst dead frames + for (j = 0; j < 8; j++) dead[nd]._deadData[j] = misfiledata[MF_SPURT].mAnimData[0]; + dead[nd]._deadFrame = 8; + dead[nd]._deadWidth = 128; + dead[nd]._deadWidth2 = (128 - 64) >> 1; + dead[nd]._deadtrans = 0; + spurtndx = nd + 1; + nd++; + // set stone dead frames + for (j = 0; j < 8; j++) dead[nd]._deadData[j] = misfiledata[MF_STONE].mAnimData[0]; + dead[nd]._deadFrame = 12; + dead[nd]._deadWidth = 128; + dead[nd]._deadWidth2 = (128 - 64) >> 1; + dead[nd]._deadtrans = 0; + stonendx = nd + 1; + nd++; + + // set unique monster dead frames + for (i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + if (monster[mi]._uniqtype != 0) { + for (j = 0; j < 8; j++) dead[nd]._deadData[j] = monster[mi].MType->Anims[MA_DEATH].Cels[j]; + dead[nd]._deadFrame = monster[mi].MType->Anims[MA_DEATH].Frames; + dead[nd]._deadWidth = monster[mi].MType->mAnimWidth; + dead[nd]._deadWidth2 = monster[mi].MType->mAnimWidth2; + dead[nd]._deadtrans = LIGHT_U + monster[mi]._uniqtrans; + monster[mi]._udeadval = nd + 1; + nd++; + } + } + app_assert(nd <= MAXDEAD); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddDead(int dx, int dy, char dv, int ddir) +{ + char tdv; + + tdv = (dv & 0x1f) + ((ddir & 0x7) << 5); + dDead[dx][dy] = tdv; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncUniqDead() +{ + int i,mi; + int x,y; + + // See function InitDead() to understand what this is all about + + for (i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + if (monster[mi]._uniqtype != 0) { + + // Search dDead array for this dead type, and place a light source there + for(x=0; x < DMAXX; x++) + for(y=0; y < DMAXY; y++) + if((dDead[x][y] & 0x1f) == monster[mi]._udeadval) + ChangeLightXY(monster[mi].mlid, x, y); + } + } +} diff --git a/DEAD.H b/DEAD.H new file mode 100644 index 0000000..c1ed909 --- /dev/null +++ b/DEAD.H @@ -0,0 +1,43 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/DEAD.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXDEAD 31 // Always will be 31! + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + BYTE *_deadData[8]; // Data pointer to anim tables + int _deadFrame; // current dead frame + long _deadWidth; // width of dead + long _deadWidth2; // (width - 64) / 2 of dead for drawing + char _deadtrans; // translations for unique monsters +} DeadStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern DeadStruct dead[MAXDEAD]; +extern int spurtndx; +extern int stonendx; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitDead(); +void AddDead(int, int, char, int); +void SyncUniqDead(); diff --git a/DEBUG.CPP b/DEBUG.CPP new file mode 100644 index 0000000..bd01c00 --- /dev/null +++ b/DEBUG.CPP @@ -0,0 +1,350 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Debugging file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DEBUG.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "debug.h" +#include "engine.h" +#include "error.h" + +#include "items.h" +#include "gendung.h" +#include "player.h" + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BYTE *pSquareCel; + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitDebugGFX() { + app_assert(! pSquareCel); + if (visiondebug) + pSquareCel = LoadFileInMemSig("Data\\Square.CEL",NULL,'DBGS'); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FreeDebugGFX() { + DiabloFreePtr(pSquareCel); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define DEBUGSEEDS 4096 + +int debugseeds[DEBUGSEEDS]; +//int seedcnt, seedidx[17]; +int seedcnt, seedidx[NUMLEVELS+1]; // JKE to add crypt +BOOL seedflag = FALSE; + +void InitDebugSeeds() +{ + for (int i = 0; i < DEBUGSEEDS; i++) debugseeds[i] = -1; + seedcnt = 0; + for (i = 0; i < 17; i++) seedidx[i] = 0; +} + +void StartDebugSeeds() +{ + if (currlevel == 0) return; + seedcnt = seedidx[currlevel]; + seedflag = TRUE; +} + +void EndDebugSeeds() +{ + if (currlevel == 0) return; + seedidx[currlevel+1] = seedcnt; + seedflag = FALSE; +} + +void SaveDebugSeed(int s) +{ + if (!seedflag) return; + if (seedcnt == DEBUGSEEDS) return; + if (currlevel == 0) return; + if (debugseeds[seedcnt] == -1) { + debugseeds[seedcnt] = s; + } else { + if (debugseeds[seedcnt] != s) app_fatal("Seeds desynced"); + } + seedcnt++; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#if 0 +char davehold1[5][MAXDUNX][MAXDUNY]; +char davehold2[5][MAXDUNX][MAXDUNY]; +BOOL daveinited[5] = { FALSE, FALSE, FALSE, FALSE, FALSE }; + +#define LEVELCHECK 1 + +void DaveCheck() +{ + int xp, yp; + + //if (currlevel != LEVELCHECK) return; + if (currlevel == 0) return; + if (currlevel >= 5) return; + for (yp = 0; yp < MAXDUNY; yp++) { + for (xp = 0; xp < MAXDUNX; xp++) { + if (dMonster[xp][yp] != 0) app_fatal("Monsters not cleared"); + if (dPlayer[xp][yp] != 0) app_fatal("Players not cleared"); + if (daveinited[currlevel]) { + if (davehold1[currlevel][xp][yp] != (dFlags[xp][yp] & BFLAG_MONSTACTIVE)) + app_fatal("MonstActive not same"); + if (davehold2[currlevel][xp][yp] != (dFlags[xp][yp] & BFLAG_SETPC)) + app_fatal("Set Piece not same"); + } else { + davehold1[currlevel][xp][yp] = dFlags[xp][yp] & BFLAG_MONSTACTIVE; + davehold2[currlevel][xp][yp] = dFlags[xp][yp] & BFLAG_SETPC; + } + } + } + daveinited[currlevel] = TRUE; +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#if 1 +#include "msg.h" +int blipplr = 0; + +void BlipDebug(BOOL next) +{ + if (next) blipplr = (blipplr + 1) & 0x3; + + int i = blipplr; + char tempstr[128]; + + sprintf(tempstr, "Plr %i : Active = %i", i, plr[i].plractive); + NetSendString((1 << myplr), tempstr); + if (plr[i].plractive) { + sprintf(tempstr, " Plr %i is %s", i, plr[i]._pName); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, " Lvl = %i : Change = %i", plr[i].plrlevel, plr[i]._pLvlChanging); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, " x = %i, y = %i : tx = %i, ty = %i : fx = %i, fy = %i", + plr[i]._px, plr[i]._py, plr[i]._ptargx, plr[i]._ptargy, plr[i]._pfutx, plr[i]._pfuty); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, " mode = %i : daction = %i : walk[0] = %i", plr[i]._pmode, plr[i].destAction, plr[i].walkpath[0]); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, " inv = %i : hp = %i", plr[i]._pInvincible, plr[i]._pHitPoints); + NetSendString((1 << myplr), tempstr); + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#if 1 +#include "quests.h" +int currqdebug = 0; + +void PrintQuestDebug() +{ + char tempstr[128]; + + sprintf(tempstr, "Quest %i : Active = %i, Var1 = %i", currqdebug, quests[currqdebug]._qactive, quests[currqdebug]._qvar1); + NetSendString((1 << myplr),tempstr); + currqdebug++; + if (currqdebug == MAXQUESTS) currqdebug = 0; +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#if 1 +#include "monstint.h" +#include "themes.h" +#include "drlg_l4.h" +extern byte dung[L4DUNX][L4DUNY]; +extern byte L4dungeon[L4DX][L4DY]; + +char mphold1[NUMLEVELS+1][MAXDUNX][MAXDUNY]; +char mphold2[NUMLEVELS+1][MAXDUNX][MAXDUNY]; + +void DaveCheck2() +{ + int xp, yp; + + for (yp = 0; yp < MAXDUNY; yp++) { + for (xp = 0; xp < MAXDUNX; xp++) { + if (dMonster[xp][yp] != 0) app_fatal("Monsters not cleared"); + if (dPlayer[xp][yp] != 0) app_fatal("Players not cleared"); + mphold1[currlevel][xp][yp] = dFlags[xp][yp] & BFLAG_MONSTACTIVE; + mphold2[currlevel][xp][yp] = dFlags[xp][yp] & BFLAG_SETPC; + } + } +} + +/*-----------------------------------------------------------------------*/ + +void PrintDaveCheck2() +{ + int i, j, xp, yp, sum1, sum2, sum3; + long fv; + char tempstr[128]; + + sum1 = 0; + sum2 = 0; + for (yp = 0; yp < MAXDUNY; yp++) { + for (xp = 0; xp < MAXDUNX; xp++) { + sum1 += mphold1[currlevel][xp][yp]; + sum2 += mphold2[currlevel][xp][yp]; + } + } + sprintf(tempstr, "Level %i : Monst Active Sum = %i : dFlag sum = %i", currlevel, sum1, sum2); + NetSendString((1 << myplr),tempstr); + + sum1 = 0; + sum2 = 0; + for (i = 1; i <= MAXTILES; i++) { + if (nSolidTable[i]) { + sum1 += i; + sum2++; + } + } + + // Calc a volume of monsters + fv = 0; + for (i = DIRTEDGED2; i < (DMAXY - (DIRTEDGED2)); i++) { + for (j = DIRTEDGED2; j < (DMAXX - (DIRTEDGED2)); j++) { + if (!SolidLoc(i,j)) fv++; + } + } + + sum3 = 0; + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) sum3 += dungeon[i][j]; + } + + sprintf(tempstr, "Solid Sum = %i:%i : Monst Vol = %i : Dungeon Sum = %i", sum1, sum2, fv, sum3); + NetSendString((1 << myplr),tempstr); + + sum1 = 0; + for (j = 0; j < MAXDUNY; j++) { + for (i = 0; i < MAXDUNX; i++) { + sum1 += dTransVal[i][j]; + } + } + + sum2 = 0; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + sum2 += dPiece[i][j]; + } + } + + sprintf(tempstr, "Num themes = %i/%i : Trans Sum = %i : dPiece Sum = %i", numthemes, themeCount, sum1, sum2); + NetSendString((1 << myplr),tempstr); + + if (leveltype == 4) { + sum1 = 0; + for (j = 0; j < L4DUNY; j++) { + for (i = 0; i < L4DUNX; i++) sum1 += dung[i][j]; + } + sum2 = 0; + for (j = 0; j < L4DY; j++) { + for (i = 0; i < L4DX; i++) sum2 += L4dungeon[i][j]; + } + sprintf(tempstr, "dung sum = %i : L4Dungeon sum = %i", sum1, sum2); + } +} + +/*-----------------------------------------------------------------------*/ + +int dungdebugy = 0; + +void DaveDungDebug() +{ + int sum, i; + char tempstr[128]; + + sum = 0; + for (i = 0; i < MDMAXX; i++) sum += dungeon[i][dungdebugy]; + + sprintf(tempstr, "dungeon Y=%i sum = %i", dungdebugy, sum); + NetSendString((1 << myplr), tempstr); + + dungdebugy++; + if (dungdebugy == MDMAXY) dungdebugy = 0; +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#if 1 +#include "sound.h" +#include "monster.h" +#include "monstdat.h" +#include "cursor.h" + +int debugmonst = 0; + +void PrintDaveMonst(int m) +{ + char tempstr[128]; + int inlist, i; + + sprintf(tempstr, "Monster %i = %s", m, monster[m].mName); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "X = %i, Y = %i", monster[m]._mx, monster[m]._my); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "Enemy = %i, HP = %i", monster[m]._menemy, monster[m]._mhitpoints); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "Mode = %i, Var1 = %i", monster[m]._mmode, monster[m]._mVar1); + NetSendString((1 << myplr), tempstr); + inlist = 0; + for (i = 0; i < nummonsters; i++) { + if (monstactive[i] == m) inlist = 1; + } + sprintf(tempstr, "Active List = %i, Squelch = %i", inlist, monster[m]._msquelch); + NetSendString((1 << myplr), tempstr); +} + +void DaveDebugMonst() +{ + int cm; + + if (cursmonst == -1) { + if (dMonster[cursmx][cursmy] == 0) cm = debugmonst; + else { + if (dMonster[cursmx][cursmy] > 0) cm = dMonster[cursmx][cursmy] - 1; + else cm = -(dMonster[cursmx][cursmy] + 1); + } + } else cm = cursmonst; + + PrintDaveMonst(cm); +} + +void DaveDebugMonst2() +{ + char tempstr[128]; + debugmonst++; + if (debugmonst == MAXMONSTERS) debugmonst = 0; + sprintf(tempstr, "Current debug monster = %i", debugmonst); + NetSendString((1 << myplr), tempstr); +} + +#endif diff --git a/DEBUG.H b/DEBUG.H new file mode 100644 index 0000000..184af69 --- /dev/null +++ b/DEBUG.H @@ -0,0 +1,19 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/DEBUG.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern BYTE *pSquareCel; + +void InitDebugSeeds(); +void StartDebugSeeds(); +void EndDebugSeeds(); +void SaveDebugSeed(int s); diff --git a/DIABLO.APS b/DIABLO.APS new file mode 100644 index 0000000..3b2f209 Binary files /dev/null and b/DIABLO.APS differ diff --git a/DIABLO.BAK b/DIABLO.BAK new file mode 100644 index 0000000..3313b7c --- /dev/null +++ b/DIABLO.BAK @@ -0,0 +1,5342 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=Diablo - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Diablo - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Diablo - Win32 Release" && "$(CFG)" != "Diablo - Win32 Debug"\ + && "$(CFG)" != "Diablo - Win32 FinalFinal" && "$(CFG)" !=\ + "Diablo - Win32 Shareware FinalFinal" && "$(CFG)" !=\ + "Diablo - Win32 Shareware Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DIABLO.MAK" CFG="Diablo - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Diablo - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 FinalFinal" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Shareware FinalFinal" (based on\ + "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Shareware Release" (based on\ + "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Diablo - Win32 Debug" +CPP=cl.exe +RSC=rc.exe +MTL=mktyplib.exe + +!IF "$(CFG)" == "Diablo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : "$(OUTDIR)\DIABLO.exe" + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\scroll.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\DIABLO.exe" + -@erase "$(OUTDIR)\DIABLO.map" + -@erase "$(OUTDIR)\DIABLO.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +$(OUTDIR)/DIABLO.bsc : $(OUTDIR) $(BSC32_SBRS) +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /c +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D PROGRAM_VERSION=RETAIL /FAcs /YX /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG"\ + /D PROGRAM_VERSION=RETAIL /FAcs /Fa"$(INTDIR)/" /Fp"$(INTDIR)/DIABLO.pch" /YX\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\WinRel/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/DIABLO.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib +# SUBTRACT LINK32 /incremental:yes +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/DIABLO.pdb" /map:"$(INTDIR)/DIABLO.map" /debug\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)/DIABLO.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\Diabloui.lib" \ + ".\dsound.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\DIABLO.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : "$(OUTDIR)\DIABLO.exe" + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\scroll.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\DIABLO.exe" + -@erase "$(OUTDIR)\DIABLO.map" + -@erase "$(OUTDIR)\DIABLO.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +$(OUTDIR)/DIABLO.bsc : $(OUTDIR) $(BSC32_SBRS) +# ADD BASE CPP /nologo /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c +# ADD CPP /nologo /G5 /Gr /MT /W3 /Gm /Zi /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D PROGRAM_VERSION=RETAIL /FAcs /YX /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Gm /Zi /Od /D "WIN32" /D "_WINDOWS" /D\ + "_DEBUG" /D PROGRAM_VERSION=RETAIL /FAcs /Fa"$(INTDIR)/"\ + /Fp"$(INTDIR)/DIABLO.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\WinDebug/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/diablo.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/DIABLO.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /incremental:no /map /debug /machine:I386 /nodefaultlib +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/DIABLO.pdb" /map:"$(INTDIR)/DIABLO.map" /debug\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)/DIABLO.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\Diabloui.lib" \ + ".\dsound.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\DIABLO.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Diablo__" +# PROP BASE Intermediate_Dir "Diablo__" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinFinal" +# PROP Intermediate_Dir "WinFinal" +# PROP Target_Dir "" +OUTDIR=.\WinFinal +INTDIR=.\WinFinal + +ALL : "$(OUTDIR)\DIABLO.exe" + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\scroll.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\DIABLO.exe" + -@erase "$(OUTDIR)\DIABLO.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# SUBTRACT BASE CPP /Fr +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D PROGRAM_VERSION=RETAIL /FAcs /YX /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG"\ + /D PROGRAM_VERSION=RETAIL /FAcs /Fa"$(INTDIR)/" /Fp"$(INTDIR)/DIABLO.pch" /YX\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\WinFinal/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/DIABLO.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 winspool.lib libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /machine:I386 /nodefaultlib +# SUBTRACT LINK32 /incremental:yes +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/DIABLO.pdb" /map:"$(INTDIR)/DIABLO.map"\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)/DIABLO.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\Diabloui.lib" \ + ".\dsound.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\DIABLO.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Diablo__" +# PROP BASE Intermediate_Dir "Diablo__" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "SFinal" +# PROP Intermediate_Dir "SFinal" +# PROP Target_Dir "" +OUTDIR=.\SFinal +INTDIR=.\SFinal + +ALL : "$(OUTDIR)\DIABLO.exe" + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\scroll.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\DIABLO.exe" + -@erase "$(OUTDIR)\DIABLO.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /YX /c +# SUBTRACT BASE CPP /Fr +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D PROGRAM_VERSION=SHAREWARE /FAcs /YX /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG"\ + /D PROGRAM_VERSION=SHAREWARE /FAcs /Fa"$(INTDIR)/" /Fp"$(INTDIR)/DIABLO.pch"\ + /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\SFinal/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/DIABLO.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /machine:I386 /nodefaultlib +# SUBTRACT LINK32 /incremental:yes +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/DIABLO.pdb" /map:"$(INTDIR)/DIABLO.map"\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)/DIABLO.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\Diabloui.lib" \ + ".\dsound.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\DIABLO.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Diablo_0" +# PROP BASE Intermediate_Dir "Diablo_0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "SRel" +# PROP Intermediate_Dir "SRel" +# PROP Target_Dir "" +OUTDIR=.\SRel +INTDIR=.\SRel + +ALL : "$(OUTDIR)\DIABLO.exe" + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\scroll.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\DIABLO.exe" + -@erase "$(OUTDIR)\DIABLO.map" + -@erase "$(OUTDIR)\DIABLO.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /YX /c +# SUBTRACT BASE CPP /Fr +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D PROGRAM_VERSION=SHAREWARE /FAcs /YX /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG"\ + /D PROGRAM_VERSION=SHAREWARE /FAcs /Fa"$(INTDIR)/" /Fp"$(INTDIR)/DIABLO.pch"\ + /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\SRel/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/DIABLO.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib +# SUBTRACT LINK32 /incremental:yes +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/DIABLO.pdb" /map:"$(INTDIR)/DIABLO.map" /debug\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)/DIABLO.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\Diabloui.lib" \ + ".\dsound.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\DIABLO.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "Diablo - Win32 Release" +# Name "Diablo - Win32 Debug" +# Name "Diablo - Win32 FinalFinal" +# Name "Diablo - Win32 Shareware FinalFinal" +# Name "Diablo - Win32 Shareware Release" + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\TOWN.CPP +DEP_CPP_TOWN_=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\GENDUNG.CPP +DEP_CPP_GENDU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SCROLLRT.CPP +DEP_CPP_SCROL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sclass.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + ".\Town.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DEAD.CPP +DEP_CPP_DEAD_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Sound.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MISSILES.CPP +DEP_CPP_MISSI=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\OBJECTS.CPP +DEP_CPP_OBJEC=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MONSTER.CPP +DEP_CPP_MONST=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sclass.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LIGHTING.CPP +DEP_CPP_LIGHT=\ + ".\automap.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DRLG_L3.CPP +DEP_CPP_DRLG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l3.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DRLG_L2.CPP +DEP_CPP_DRLG_L=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l2.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DRLG_L1.CPP +DEP_CPP_DRLG_L1=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L1) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L1) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L1) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L1) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L1) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TRIGS.CPP +DEP_CPP_TRIGS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DEBUG.CPP +DEP_CPP_DEBUG=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\CURSOR.CPP +DEP_CPP_CURSO=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\PALETTE.CPP +DEP_CPP_PALET=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Palette.h"\ + ".\Sclass.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DIABLO.CPP +DEP_CPP_DIABL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\mainmenu.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sclass.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\PLAYER.CPP +DEP_CPP_PLAYE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ENGINE.CPP +DEP_CPP_ENGIN=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Palette.h"\ + ".\regconst.h"\ + ".\Sclass.h"\ + ".\Scrollrt.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\CONTROL.CPP +DEP_CPP_CONTR=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPELLS.CPP +DEP_CPP_SPELL=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOUND.CPP +DEP_CPP_SOUND=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MONSTDAT.CPP +DEP_CPP_MONSTD=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Sound.h"\ + ".\textdat.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONSTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONSTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONSTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONSTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONSTD) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ITEMS.CPP +DEP_CPP_ITEMS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\inv.cpp +DEP_CPP_INV_C=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Interfac.cpp +DEP_CPP_INTER=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sclass.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Storm.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\effects.cpp +DEP_CPP_EFFEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Quests.cpp +DEP_CPP_QUEST=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\GameMenu.cpp +DEP_CPP_GAMEM=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SetMaps.cpp +DEP_CPP_SETMA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\minitext.cpp +DEP_CPP_MINIT=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\textdat.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\objdat.cpp +DEP_CPP_OBJDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\itemdat.cpp +DEP_CPP_ITEMD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Spells.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\drlg_l4.cpp +DEP_CPP_DRLG_L4=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\themes.cpp +DEP_CPP_THEME=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\stores.cpp +DEP_CPP_STORE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\spelldat.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\help.cpp +DEP_CPP_HELP_=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\automap.cpp +DEP_CPP_AUTOM=\ + ".\automap.h"\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\diablo.rc +DEP_RSC_DIABLO=\ + ".\icon1.ico"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\diablo.res" : $(SOURCE) $(DEP_RSC_DIABLO) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\diablo.res" : $(SOURCE) $(DEP_RSC_DIABLO) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\diablo.res" : $(SOURCE) $(DEP_RSC_DIABLO) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\diablo.res" : $(SOURCE) $(DEP_RSC_DIABLO) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\diablo.res" : $(SOURCE) $(DEP_RSC_DIABLO) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Storm.lib + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\error.cpp +DEP_CPP_ERROR=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Items.h"\ + ".\Scrollrt.h"\ + ".\stores.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\multi.cpp +DEP_CPP_MULTI=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Spelldat.cpp +DEP_CPP_SPELLD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Missiles.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELLD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELLD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELLD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELLD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELLD) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\spelldat.h + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\misdat.h + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\misdat.cpp +DEP_CPP_MISDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\appfat.cpp +DEP_CPP_APPFA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Sclass.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\dsound.lib + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ddraw.lib + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\sync.cpp +DEP_CPP_SYNC_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\path.cpp +DEP_CPP_PATH_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\path.h"\ + ".\Player.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\msg.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\init.cpp +DEP_CPP_INIT_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\movie.cpp +DEP_CPP_MOVIE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Sclass.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Diabloui.lib + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\mainmenu.cpp +DEP_CPP_MAINM=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\pfile.cpp +DEP_CPP_PFILE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\mpqapi.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Sclass.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\packplr.cpp +DEP_CPP_PACKP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Sclass.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\nthread.cpp +DEP_CPP_NTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\capture.cpp +DEP_CPP_CAPTU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\encrypt.cpp +DEP_CPP_ENCRY=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\implode.h"\ + ".\mpqapi.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\mpqapi.cpp +DEP_CPP_MPQAP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\mpqapi.h"\ + ".\Sclass.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\track.cpp +DEP_CPP_TRACK=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Sclass.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\implode.lib + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Scroll.asm + +!IF "$(CFG)" == "Diablo - Win32 Release" + +# Begin Custom Build - scroll.asm +IntDir=.\WinRel +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +# End Custom Build + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +# Begin Custom Build - scroll.asm +IntDir=.\WinDebug +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +# End Custom Build + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +# Begin Custom Build - scroll.asm +IntDir=.\WinFinal +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +# End Custom Build + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +# Begin Custom Build - scroll.asm +IntDir=.\SFinal +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +# End Custom Build + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +# Begin Custom Build - scroll.asm +IntDir=.\SRel +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +# End Custom Build + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SHA.CPP +DEP_CPP_SHA_C=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\CODEC.CPP +DEP_CPP_CODEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\wave.cpp +DEP_CPP_WAVE_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\towners.cpp +DEP_CPP_TOWNE=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\plrmsg.cpp +DEP_CPP_PLRMS=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gmenu.cpp +DEP_CPP_GMENU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\loadsave.cpp +DEP_CPP_LOADS=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\Trigs.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\portal.cpp +DEP_CPP_PORTA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\portal.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\doom.cpp +DEP_CPP_DOOM_=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Textdat.cpp +DEP_CPP_TEXTD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\MiniText.h"\ + ".\textdat.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\dx.cpp +DEP_CPP_DX_CP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Sclass.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\dthread.cpp +DEP_CPP_DTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sclass.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\tmsg.cpp +DEP_CPP_TMSG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\except.cpp +DEP_CPP_EXCEP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +!IF "$(CFG)" == "Diablo - Win32 Release" + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/DIABLO.CPP b/DIABLO.CPP new file mode 100644 index 0000000..134477b --- /dev/null +++ b/DIABLO.CPP @@ -0,0 +1,3107 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Main file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DIABLO.CPP 16 3/29/97 9:09p Pwyatt $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "sound.h" +#include "mainmenu.h" +#include "interfac.h" +#include "inv.h" +#include "msg.h" +#include "multi.h" +#include "engine.h" +#include "palette.h" +#include "scrollrt.h" +#include "gendung.h" +#include "setmaps.h" +#include "debug.h" +#include "effects.h" + +#include "dead.h" +#include "lighting.h" +#include "control.h" +#include "gamemenu.h" + +#include "items.h" +#include "player.h" +#include "monster.h" +#include "objects.h" +#include "missiles.h" +#include "trigs.h" +#include "spelldat.h" +#include "spells.h" +#include "cursor.h" + +#include "town.h" +#include "towners.h" +#include "drlg_l1.h" +#include "drlg_l2.h" +#include "drlg_l3.h" +#include "drlg_l4.h" +#include "quests.h" +#include "minitext.h" +#include "themes.h" +#include "stores.h" +#include "packplr.h" +#include "portal.h" +#include "doom.h" + +#include "automap.h" +#include "help.h" +#include "error.h" +#include "diabloui.h" +#include "textdat.h" +// pjw.patch1.start +#include "mpqapi.h" +#include +// pjw.patch1.end + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszTblSig[TBL_LEN] = "REGISTRATION_TABLE"; + + +/*-----------------------------------------------------------------------** +** Global Variables +**-----------------------------------------------------------------------*/ +extern char gszProgKey[]; +BYTE gbDoEnding; +void DoEnding(); + +int StripPlayer(int pnum); + +DWORD glSeedTbl[NUMLEVELS]; +int gnLevelTypeTbl[NUMLEVELS]; + +// window vars +HWND ghMainWnd; +HINSTANCE ghInst; + +// video vars +BOOL fullscreen = TRUE; + + +// mouse +int MouseX, MouseY; + +// program vars +int force_redraw = NODRAW; + +BOOL svgamode; + +// Temp vars (delete all uses before final compile) +long gv1; +long gv2; +long gv3; +long gv4; +long gv5; + +#ifndef NDEBUG +// do not change this flag -- USE 'n' on the command line +static BOOL cineflag = TRUE; +#endif + +#if CHEATS +BOOL gbDumpDropLog = FALSE; +BOOL davedebug = FALSE; +BOOL cheatflag = FALSE; // Turn invincibility and all spells on/off +BOOL simplecheat = FALSE; // like cheatflag, but doesn't screw up game +BOOL gbNoDropInactive = FALSE; // don't drop players on timeout +int tstQMsgSpd; +int tstQMsgIndex = 0; +BOOL tstQMsgFlag = FALSE; +BOOL tstQMsgIndexFlag = FALSE; +BOOL itemcheat = FALSE; +BOOL uniqcheat = FALSE; +#endif + +BOOL visiondebug = FALSE; // Vision debugging +BOOL scrollflag = FALSE; // Scroll when at edge of screen with mouse +BOOL light4flag = FALSE; // 4 levels of light instead of 16 +BOOL leveldebug = FALSE; +BOOL monstdebug = FALSE; +BOOL trigdebug = FALSE; +int setseed = 0; + +int debugmonsttypes = 0; +int DebugMonsters[10]; + +BOOL PauseMode = FALSE; +BOOL FriendlyMode = TRUE; + +BOOL gbRunGame; +BOOL gbRunGameResult; +BOOL gbProcessPlayers; +BOOL gbGameLoopStartup; + +bool gbTheo = false; +bool gbCowsuit = false; +bool gbOurNest = false; +bool gbAllowBard = false; +bool gbAllowBarbarian = false; +bool gbAllowMultiPlayer = true; + +//int glEndSeed[17]; // @@@ drb temp +//int glMid1Seed[17]; +//int glMid2Seed[17]; +//int glMid3Seed[17]; + +int glEndSeed[NUMLEVELS+1]; // @@@ drb temp +int glMid1Seed[NUMLEVELS+1]; +int glMid2Seed[NUMLEVELS+1]; +int glMid3Seed[NUMLEVELS+1]; //JKE 7/30 adds new levels + +/*-----------------------------------------------------------------------** +** timeout cursor +**-----------------------------------------------------------------------*/ +#define TIMEOUT_CURSOR WATCH_CURS +static int sgnTimeoutCurs = NO_CURSOR; + +#define LMOUSE_DOWN 1 +#define RMOUSE_DOWN 2 +// drb.patch1.start.1/24/97 +// static BYTE sgbMouseDown = 0; +BYTE sgbMouseDown = 0; +// drb.patch1.end.1/24/97 + + +/*-----------------------------------------------------------------------** +** Function stubs +**-----------------------------------------------------------------------*/ +// pjw.patch1.start +// static void try_game_loop(BOOL bStartup); +static void alloc_plr(); +static void DoTimedEvents(); +static void game_loop(BOOL bStartup); +static void plr_encrypt(BOOL bEncrypt); +void InitializeHashSource(); +void Decrypt(LPDWORD data, DWORD bytes, DWORD key); +void Encrypt(LPDWORD data, DWORD bytes, DWORD key); +// pjw.patch1.end + + +void BlackPalette(); +void enable_frame_counter(); +void init_window(int nCmdShow); +void play_movie(const char * pszMovie,BOOL bAllowCancel); +void play_quotes(); +void play_quit(); +void FreeCursor(); +void InitDebugGFX(); +void FreeDebugGFX(); +void ShowProgress(UINT uMsg); +static LRESULT CALLBACK GM_Game(HWND, UINT, WPARAM, LPARAM); +void TrackInit(BOOL bMouseDown); +void TrackMouse(); +void run_delta_info(); +void toggle_frame_counter(); +WNDPROC my_SetWindowProc(WNDPROC wndProc); +void plrmsg_update(); +void screen_capture(); +void SavePaletteSettings(); +void menu_music(); +void NetStartTimeout(); +void menusnd_init(); +void InitLevels(); +void SyncInitPlrPos(int pnum); + +void OpenCloseAllDoors(); +void OpenNaKrul2(); + +//****************************************************************** +//****************************************************************** +void FlushMsgs() { + // turn tracking off + TrackInit(FALSE); + sgbMouseDown = FALSE; + ReleaseCapture(); + + // keep flushing messages until all key and mouse msgs are gone + BOOL bLoop = TRUE; + while (bLoop) { + bLoop = FALSE; + MSG msg; + while (PeekMessage(&msg,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE)) + bLoop = TRUE; + while (PeekMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE)) + bLoop = TRUE; + } +} + +//****************************************************************** +//****************************************************************** +static void CommandLine(const char * s) { + int val; + (val); + + while (*s) { + + // skip over any space characters + while (isspace(*s)) + s++; + + // check for direct draw emulation mode +// pjw.patch1.start.1/13/97 + static const char sszEmulate[] = "dd_emulate"; + if (! _strnicmp(sszEmulate,s,strlen(sszEmulate))) { + extern BYTE gbUseDDEmulation; + gbUseDDEmulation = TRUE; + s += strlen(sszEmulate); + continue; + } + + // check for direct draw offscreen buffer + static const char sszBackBuf[] = "dd_backbuf"; + if (! _strnicmp(sszBackBuf,s,strlen(sszBackBuf))) { + extern BYTE gbForceBackBuf; + gbForceBackBuf = TRUE; + s += strlen(sszBackBuf); + continue; + } + + static const char sszDupSound[] = "ds_noduplicates"; + if (! _strnicmp(sszDupSound,s,strlen(sszDupSound))) { + extern BYTE gbDupSounds; + gbDupSounds = FALSE; + s += strlen(sszDupSound); + continue; + } + + char const sszTheoFlag[] = "Theoquest"; + if (! _strnicmp(sszTheoFlag, s, strlen(sszTheoFlag))) { + gbTheo = true; + s += strlen(sszTheoFlag); + continue; + } + + char const sszCowQuestFlag[] = "Cowquest"; + if (!_strnicmp(sszCowQuestFlag, s, strlen(sszCowQuestFlag))) { + gbCowsuit = true; + s += strlen(sszCowQuestFlag); + continue; + } + + char const sszOurNestFlag[] = "NestArt"; + if (!_strnicmp(sszOurNestFlag, s, strlen(sszOurNestFlag))) { + gbOurNest = true; + s += strlen(sszOurNestFlag); + continue; + } + + char const sszAllowBardFlag[] = "Bardtest"; + if (!_strnicmp(sszAllowBardFlag, s, strlen(sszAllowBardFlag))) { + gbAllowBard = true; + s += strlen(sszAllowBardFlag); + continue; + } + + char sszAllowMultiPlayerFlag[] = "Multitest"; +#if defined(_MULTITEST) + sszAllowMultiPlayerFlag[5] = 'n'; + if (!_strnicmp(sszAllowMultiPlayerFlag, s, strlen(sszAllowMultiPlayerFlag))) { +#else + if (!_strnicmp(sszAllowMultiPlayerFlag, sszAllowBardFlag, strlen(sszAllowMultiPlayerFlag))) { +#endif + gbAllowMultiPlayer = true; + s += strlen(sszAllowMultiPlayerFlag); + continue; + } + + char const sszAllowBarbarianFlag[] = "Barbariantest"; + if (!_strnicmp(sszAllowBarbarianFlag, s, strlen(sszAllowBarbarianFlag))) { + gbAllowBarbarian = true; + s += strlen(sszAllowBarbarianFlag); + continue; + } + +// pjw.patch1.end.1/13/97 + + // extract next character -- do not do ++ inside macro + // some versions of C may have nasty side effects... + char c = tolower(*s); s++; + switch (c) { + #if CHEATS + case 'b': + gbDumpDropLog = TRUE; + break; + #endif + + #if CHEATS + case 'i': + gbNoDropInactive = TRUE; + break; + #endif + + #if CHEATS + // this cheat flag is for testing without having your + // character die every two seconds -- doesn't have + // all the nasty side effects of the cheat flag + case '$': + simplecheat = TRUE; + break; + #endif + + #if CHEATS + // this cheat flag is the do-everything cheat for programmers + // it has all sorts of nasty side effects which may hide bugs + case '^': + cheatflag = TRUE; + break; + #endif + + #if CHEATS + case 'd': + davedebug = TRUE; + cineflag = FALSE; + break; + #endif + + #if CHEATS + case 'w': + davecheat = TRUE; + break; + #endif + + #if CHEATS && !IS_VERSION(SHAREWARE) + case 'l': + leveldebug = TRUE; + setlevel = FALSE; + + // get level type + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + leveltype = val; + + // get level num + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + currlevel = val; + plr[0].plrlevel = val; + break; + #endif + + #if CHEATS + case 'm': + monstdebug = TRUE; + + // get monster number + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + DebugMonsters[debugmonsttypes++] = val; + break; + #endif + + #if CHEATS + case 'q': + // get quest number + while(isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + extern int questcheat; + questcheat = val; + break; + #endif + + #if CHEATS + case 'r': + while(isspace(*s)) + s++; + val = 0; + while(isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + setseed = val; + break; + #endif + + #if CHEATS + case 's': + scrollflag = TRUE; + break; + #endif + + #if CHEATS && !IS_VERSION(SHAREWARE) + case 't': + leveldebug = TRUE; + setlevel = TRUE; + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + setlvlnum = val; + break; + #endif + + #if CHEATS + case 'j': + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + trigdebug = val; + break; + #endif + + #if CHEATS + case 'v': + visiondebug = TRUE; + break; + #endif + + #ifndef NDEBUG + case 'f': + toggle_frame_counter(); + break; + #endif + + #ifndef NDEBUG + case 'x': + fullscreen = FALSE; + break; + #endif + + #ifndef NDEBUG + case 'n': + cineflag = FALSE; + break; + #endif + + #if CHEATS + case '7': + itemcheat = TRUE; + break; + + case '8': + uniqcheat = TRUE; + break; + #endif + } + + } +} + + +//****************************************************************** +//****************************************************************** +void FreeGameMem() { + music_stop(); + + DiabloFreePtr(pDungeonCels); + DiabloFreePtr(pMegaTiles); + DiabloFreePtr(pMiniTiles); + DiabloFreePtr(pSpecialCels); + DiabloFreePtr(pSpeedCels); + FreeMissileGFX(); + + FreeMonsterGFX(); + FreeObjectGFX(); + FreeMonsterSnd(); + FreeTownerGFX(); +} + + +//****************************************************************** +// stuff done every time a game is started/ended +//****************************************************************** +static void start_game(UINT uMsg) { + gbDoEnding = FALSE; + svgamode = TRUE; + InitCursor(); + InitLightTable(); + InitDebugGFX(); + app_assert(ghMainWnd); + music_stop(); + ShowProgress(uMsg); + gmenu_init(); + InitLevelCursor(); + sgnTimeoutCurs = NO_CURSOR; + sgbMouseDown = 0; + TrackInit(FALSE); +} +static void free_game() { + FreeControlPan(); + FreeInvGFX(); + gmenu_free(); + FreeQuestText(); + FreeStoreMem(); + for (int i = 0; i < MAX_PLRS; i++) + FreePlayerGFX(i); + FreeItemGFX(); + + FreeCursor(); + FreeLightTable(); + FreeDebugGFX(); + FreeGameMem(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void run_game_loop(UINT uMsg) { + nthread_perform_keepalive(TRUE); + start_game(uMsg); + app_assert(ghMainWnd); + WNDPROC saveProc = my_SetWindowProc(GM_Game); + CalcInitBallPer(); + // pjw.patch2.start + // nthread_perform_keepalive(FALSE); + // pjw.patch2.end + run_delta_info(); + + gbRunGame = TRUE; + gbProcessPlayers = TRUE; + gbRunGameResult = TRUE; + force_redraw = FULLDRAW; + DrawAndBlit(); + PaletteFadeIn(FADE_FAST); + force_redraw = FULLDRAW; + gbGameLoopStartup = TRUE; + + // pjw.patch2.start + nthread_perform_keepalive(FALSE); + // pjw.patch2.end + + +// pjw.patch1.start + MSG msg; + //plr_encrypt(TRUE); + while (gbRunGame) { + DoTimedEvents(); // palette cycling + + // pjw.patch2.start + // if there are any messages in the queue, process them all + if (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { + // bump thread priority to make sure that + // during peekmessage loop we are less likely + // to yield to another process + SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL); + //plr_encrypt(FALSE); + while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if (msg.message == WM_QUIT) { + gbRunGame = gbRunGameResult = FALSE; + break; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + BOOL bRun = gbRunGame && nthread_run_gameloop(FALSE); + //if (! bRun) plr_encrypt(TRUE); + SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL); + if (! bRun) continue; + } + else if (! nthread_run_gameloop(FALSE)) { + // not enough time has elapsed since last gameloop + continue; + } + // pjw.patch2.end + + // actual game logic + //plr_encrypt(FALSE); + NetReceivePackets(); + game_loop(gbGameLoopStartup); + gbGameLoopStartup = FALSE; + DrawAndBlit(); + //plr_encrypt(TRUE); + } + //plr_encrypt(FALSE); +// pjw.patch1.end + + // save character in multiplayer mode + if (gbMaxPlayers > 1) { + void UpdatePlayerFile(); + UpdatePlayerFile(); + } + void ReleasePlayerFile(); + ReleasePlayerFile(); + + PaletteFadeOut(FADE_FAST); + SetCursor(NO_CURSOR); + ClrDraw(); + force_redraw = FULLDRAW; + FullBlit(TRUE); + + // restore old window procedure + saveProc = my_SetWindowProc(saveProc); + app_assert(saveProc == GM_Game); + + free_game(); + + if (gbDoEnding) { + gbDoEnding = FALSE; + DoEnding(); + } +} + + +/*-----------------------------------------------------------------------** +// return FALSE to quit game +// return TRUE to continue game +**-----------------------------------------------------------------------*/ +BOOL StartGame(BOOL bNewGame, BOOL bSinglePlayer) { + + extern BYTE gbSelectProvider; + gbSelectProvider = TRUE; + + while (1) { + + // initialize network + BOOL fExitProgram = FALSE; + if (! NetInit(bSinglePlayer,&fExitProgram)) { + gbRunGameResult = !fExitProgram; + break; + } + + gbSelectProvider = FALSE; + + UINT uMsg; + if (bNewGame || !gbValidSaveFile) { + + InitLevels(); + InitQuests(); + InitPortals(); + InitDungMsgs(myplr); + if (!gbValidSaveFile && gbSaveFileExists) + { + // clear the items from the character's inventory + StripPlayer(myplr); + } + uMsg = WM_DIABNEWGAME; + } + else { + uMsg = WM_DIABLOADGAME; + } + + run_game_loop(uMsg); + NetClose(); + + // in single player mode, exit this loop + if (gbMaxPlayers == 1) break; + + // in multiplayer mode, only break out of the + // loop if the player wants to exit the game, otherwise + // the loop will be exited based on results from NetInit() + if (! gbRunGameResult) break; + } + + TRACE_FCN("SNetDestroy"); + SNetDestroy(); + TRACE_FCN(NULL); + + return gbRunGameResult; +} + + +//****************************************************************** +//****************************************************************** +static void InitOnce() { + MouseX = TOTALX >> 1; + MouseY = TOTALY >> 1; + + ScrollInfo._sdx = 0; + ScrollInfo._sdy = 0; + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = SCRL_NONE; + for (int i = 0; i < 1024; i++) + nBuffWTbl[i] = i * BUFFERX; + + // Init engine vars + ClrDiabloMsg(); +} + + +//****************************************************************** +//****************************************************************** +/* pjw.patch2.start +static const char sgszErrFile[] = "c:\\helfire_.err"; +static void write_exception(struct _EXCEPTION_POINTERS *pep) { + FILE * f = fopen(sgszErrFile,"wb"); + if (! f) return; + + PEXCEPTION_RECORD per = pep->ExceptionRecord; + while (per) { + fprintf( + f, + "exception: 0x%08x\r\ncode address: 0x%08x\r\n", + per->ExceptionCode, + per->ExceptionAddress + ); + + if (per->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { + if (per->ExceptionInformation[0]) + fprintf(f,"write access violation at 0x%08x\r\n",per->ExceptionInformation[1]); + else + fprintf(f,"read access violation at 0x%08x\r\n",per->ExceptionInformation[1]); + } + + per = per->ExceptionRecord; + } + + fclose(f); +} +pjw.patch2.end */ + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start +void cleanup(BOOL bNormalExit); +static LPTOP_LEVEL_EXCEPTION_FILTER sg_previousFilter; +static LONG WINAPI DiabloUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pep) { + void free_directx(); + free_directx(); + cleanup(FALSE); + // write_exception(pep); + if (sg_previousFilter) return sg_previousFilter(pep); + return EXCEPTION_CONTINUE_SEARCH; +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +BOOL grab_event() { + // NOTE: this event never gets cleaned up by our code + // we rely upon windows to clean up this event so that it + // occurs as late as possible in the program exit. This is + // a really nasty hack to make sure that SMACKER doesn't + // initialize improperly + SetLastError(0); + HANDLE hExtraEvent = CreateEvent(NULL,FALSE,FALSE,"DiabloEvent"); + HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,"HellfireEvent"); + return ERROR_ALREADY_EXISTS != GetLastError(); +} + + +//****************************************************************** +//****************************************************************** +static BOOL ActivatePreviousInstance(const char * pszAppClass) { + // find main application window + HWND hWnd; + HWND hWndTop; + HWND hWndPopup; + + // get parent window + if (NULL == (hWnd = FindWindow(pszAppClass,NULL))) + return FALSE; + + // get popup window (if any) + if (NULL != (hWndPopup = GetLastActivePopup(hWnd))) + hWnd = hWndPopup; + + // get topmost control window of topmost window + hWndTop = GetTopWindow(hWnd); + if (! hWndTop) hWndTop = hWnd; + + // bring to the front + SetForegroundWindow(hWnd); + SetFocus(hWndTop); + + return TRUE; +} + + +typedef struct _SHAREDDATA { + LONG status; + DWORD processid; +} SHAREDDATA, *SHAREDDATAPTR; + + +//=========================================================================== +// pjw.patch2.start +#ifdef NDEBUG +static void inline ReloadSelf (HINSTANCE instance) { + + // GET THE MODULE FILENAME + char filename[MAX_PATH] = ""; + GetModuleFileName((HMODULE)instance,filename,MAX_PATH); + + + // OPEN NAMED SHARED MEMORY + char name[MAX_PATH+16]; + wsprintf(name,"Reload-%s",filename); + for (LPSTR curr = name; *curr; ++curr) + if (*curr == '\\') + *curr = '/'; + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + DWORD bytes = max(4096,sysinfo.dwPageSize); + + + HANDLE map = CreateFileMapping((HANDLE)0xFFFFFFFF, + NULL, + PAGE_READWRITE | SEC_COMMIT, + 0, + bytes, + name); + BOOL first = (GetLastError() != ERROR_ALREADY_EXISTS); + if (!map) + return; + + // Open secondary named shared memory to fool Diablo into not autorunning + char tmpname[MAX_PATH+16]; + strcpy(tmpname,"Reload-Diablo"); + HANDLE tmpmap = CreateFileMapping((HANDLE)0xFFFFFFFF, + NULL, + PAGE_READWRITE | SEC_COMMIT, + 0, + bytes, + tmpname); + // end of hack + + LPVOID view = MapViewOfFile(map,FILE_MAP_ALL_ACCESS,0,0,bytes); + if (!view) + return; + SHAREDDATAPTR ptr = (SHAREDDATAPTR)view; + + // IF WE ARE THE FIRST INSTANCE, THEN RELOAD OURSELVES, WAIT FOR THE + // SECOND INSTANCE TO INITIALIZE, THEN QUIT + if (first) { + ptr->status = -1; + ptr->processid = 0; + STARTUPINFO startupinfo; + ZeroMemory(&startupinfo,sizeof(STARTUPINFO)); + startupinfo.cb = sizeof(STARTUPINFO); + PROCESS_INFORMATION processinfo; + CreateProcess(filename, + NULL, + NULL, + NULL, + FALSE, + CREATE_NEW_PROCESS_GROUP, + NULL, + NULL, + &startupinfo, + &processinfo); + WaitForInputIdle(processinfo.hProcess,INFINITE); + CloseHandle(processinfo.hThread); + CloseHandle(processinfo.hProcess); + while (ptr->status < 0) + Sleep(1000); + UnmapViewOfFile(view); + CloseHandle(map); + ExitProcess(0); + } + + // OTHERWISE, ALLOW ONE INSTANCE TO RUN, AND MAKE ANY ADDITIONAL + // INSTANCES JUST REACTIVATE THE RUNNING INSTANCE + if (!InterlockedIncrement(&ptr->status)) + ptr->processid = GetCurrentProcessId(); + else { + HWND window = GetForegroundWindow(); + HWND prev; + while ((prev = GetNextWindow(window,GW_HWNDPREV)) != (HWND)0) + window = prev; + do { + DWORD processid; + GetWindowThreadProcessId(window,&processid); + if (processid == ptr->processid) { + SetForegroundWindow(window); + break; + } + } while ((window = GetNextWindow(window,GW_HWNDNEXT)) != (HWND)0); + UnmapViewOfFile(view); + CloseHandle(map); + ExitProcess(0); + } +} +#endif +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow){ +// pjw.patch2.start + #ifdef NDEBUG + ReloadSelf(hInstance); + #endif +// pjw.patch2.end + + ghInst = hInstance; + ShowCursor(FALSE); + // pjw.patch1.start + srand(GetTickCount()); + InitializeHashSource(); + alloc_plr(); + // pjw.patch1.end + + // delete any previous error file created by exception + // handler and then install exception handler + // pjw.patch2.start + // DeleteFile(sgszErrFile); + sg_previousFilter = SetUnhandledExceptionFilter(DiabloUnhandledExceptionFilter); + // pjw.patch2.end + + // if another instance of Diablo is already running, + // then activate it and exit this instance + BOOL bGotEvent = grab_event(); + if (ActivatePreviousInstance("DIABLO")) // conflict with parent is bad + return FALSE; + if (ActivatePreviousInstance(gszAppName)) + return FALSE; + if (!bGotEvent) return FALSE; + + + #ifndef NDEBUG + SFileEnableDirectAccess(1); + #endif + + InitOnce(); + char cpCmdLine[255]; + if (!lpCmdLine[0]) { + cpCmdLine[0] = 0; + FILE * const fp = fopen("command.txt","r"); + if (fp) { + fgets(cpCmdLine, sizeof(cpCmdLine)/sizeof(char), fp); + lpCmdLine = cpCmdLine; + fclose(fp); + } + } + CommandLine(lpCmdLine); + init_window(nCmdShow); + + menusnd_init(); + UiInitialize(); + + #if IS_VERSION(SHAREWARE) + UiSetSpawned(TRUE); + #endif + + + // play logo + #ifndef NDEBUG + if (cineflag) play_movie("gendata\\logo.smk",TRUE); + #else + play_movie("gendata\\logo.smk",TRUE); + #endif + + // play magazine quotes + /* + #if IS_VERSION(SHAREWARE) + #ifndef NDEBUG + if (cineflag) play_quotes(); + #else + play_quotes(); + #endif + #endif + */ + + // play main intro + #if !IS_VERSION(SHAREWARE) + const char sgszMovie[] = "Intro"; + DWORD dwPlayMovie; + if (! SRegLoadValue(gszProgKey,sgszMovie,0,&dwPlayMovie)) + dwPlayMovie = 1; + //if (dwPlayMovie) + play_movie("gendata\\Hellfire.smk",TRUE); + SRegSaveValue(gszProgKey,sgszMovie,0,0); + #endif + + + // play title screen + #ifndef NDEBUG + if (cineflag) { + #endif + UiTitleDialog(7); // DKT this needs to change to ours + BlackPalette(); + #ifndef NDEBUG + } + #endif + + // play beta warning + #if IS_VERSION(BETA) + #ifndef NDEBUG + if (cineflag) { + #endif + UiBetaDisclaimer(5); + BlackPalette(); + #ifndef NDEBUG + } + #endif + #endif + + // main game menu (finally) + DiabloMenu(); + + // play "buy me" screens + /* + #if IS_VERSION(SHAREWARE) + #ifndef NDEBUG + if (cineflag) play_quit(); + #else + play_quit(); + #endif + #endif + */ + + UiDestroy(); + SavePaletteSettings(); + + if (ghMainWnd) { + // sleep before we destroy window so + // that SFX have time to finish before exit + Sleep(300); + DestroyWindow(ghMainWnd); + } + + return FALSE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL CheckPlrLBtn(BOOL ShiftDown) { + BOOL adjacent; + + app_assert(MouseY < 352); + if (leveltype == 0) { + // + // Town Level + // + ShiftDown = FALSE; // no attacking in town + if ((cursitem != -1) && (curs == GLOVE_CURS)) + NetSendCmdLocParam1(TRUE,invflag ? CMD_GOTOGETITEM : CMD_GOTOAGETITEM,cursmx,cursmy,cursitem); + if (cursmonst != -1) + NetSendCmdLocParam1(TRUE,CMD_TALKXY,cursmx,cursmy,cursmonst); + if ((cursitem == -1) && (cursmonst == -1) && (cursplr == -1)) + return TRUE; + } + else { + // + // NOT Town Level + // + adjacent = abs(plr[myplr]._px - cursmx) < 2 + && abs(plr[myplr]._py - cursmy) < 2; + if ((cursitem != -1) && (curs == GLOVE_CURS) && !ShiftDown) + NetSendCmdLocParam1(TRUE,invflag ? CMD_GOTOGETITEM : CMD_GOTOAGETITEM,cursmx,cursmy,cursitem); + else if ((cursobj != -1) + && (!ShiftDown // allow barrel busting even with shift key down + || (adjacent && object[cursobj]._oBreak == OBJ_BREAKABLE))) + NetSendCmdLocParam1(TRUE,(curs == DISARM_CURS) ? CMD_DISARMXY : CMD_OPOBJXY,cursmx,cursmy,cursobj); + + else if (plr[myplr]._pwtype == WEAP_RANGE) { + if (ShiftDown) + NetSendCmdLoc(TRUE,CMD_RATTACKXY, cursmx, cursmy); + else if (cursmonst != -1) { + if (CanTalkToMonst(cursmonst)) + // walk over to monster to talk to him + NetSendCmdParam1(TRUE,CMD_ATTACKID,cursmonst); + else + // Attack + NetSendCmdParam1(TRUE,CMD_RATTACKID,cursmonst); + } else if (cursplr != -1 && !FriendlyMode) + NetSendCmdParam1(TRUE,CMD_RATTACKPID, cursplr); + } + + else { // pwtype == WEAP_H2H + if (ShiftDown) { + if (cursmonst != -1) { + if (CanTalkToMonst(cursmonst)) + NetSendCmdParam1(TRUE,CMD_ATTACKID,cursmonst); + else + NetSendCmdLoc(TRUE,CMD_SATTACKXY, cursmx, cursmy); + } else + NetSendCmdLoc(TRUE,CMD_SATTACKXY, cursmx, cursmy); + } + else if (cursmonst != -1) + NetSendCmdParam1(TRUE,CMD_ATTACKID,cursmonst); + else if (cursplr != -1 && !FriendlyMode) + NetSendCmdParam1(TRUE,CMD_ATTACKPID,cursplr); + } + + if ((!ShiftDown) && (cursitem == -1) && (cursobj == -1) && (cursmonst == -1) && (cursplr == -1)) + return TRUE; + } + + return FALSE; +} + +/*-----------------------------------------------------------------------** +** Game message processing +**-----------------------------------------------------------------------*/ +static BOOL TryIconCurs() { + if (curs == RESURRECT_CURS) { + NetSendCmdParam1(TRUE,CMD_RESURRECT, cursplr); + return(TRUE); + } + + if (curs == HEALOTHER_CURS) { + NetSendCmdParam1(TRUE,CMD_HEALOTHER, cursplr); + return(TRUE); + } + + if (curs == TELE_CURS) { + DoTelekinesis(); + return(TRUE); + } + if (curs == IDENTIFY_CURS) { + if (cursinvitem != -1) + CheckIdentify(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + if (curs == REPAIR_CURS) { + if (cursinvitem != -1) + DoRepair(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + if (curs == RECHARGE_CURS) { + if (cursinvitem != -1) + DoRecharge(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + + if (curs == OIL_CURS) { + if (cursinvitem != -1) + DoOil(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + + if (curs == TARGET_CURS) { + if (cursmonst != -1) + NetSendCmdParam3(TRUE,CMD_TSPELLID,cursmonst,plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell)); + else if (cursplr != -1) + NetSendCmdParam3(TRUE,CMD_TSPELLPID,cursplr,plr[myplr]._pTSpell,GetSpellLevel(myplr, plr[myplr]._pTSpell)); + else + NetSendCmdLocParam2(TRUE,CMD_TSPELLXY,cursmx,cursmy,plr[myplr]._pTSpell,GetSpellLevel(myplr, plr[myplr]._pTSpell)); + NewCursor(GLOVE_CURS); + return(TRUE); + } + if ((curs == DISARM_CURS) && (cursobj == -1)) { + NewCursor(GLOVE_CURS); + return(TRUE); + } + return(FALSE); +} + + +//****************************************************************** +//****************************************************************** +static BOOL wm_lbuttondown(WPARAM wParam) { + if (gmenu_click(TRUE)) + return FALSE; + + BOOL talk_click(); + if (talk_click()) + return FALSE; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return FALSE; + + if (deathflag) { + CheckDeadButtons(); + return FALSE; + } + + if (PauseMode == 2) + return FALSE; + + if (drawmapofdoom) { + EndMapOfDoomView(); + return FALSE; + } + + if (spselflag) { + SetSpell(); + return FALSE; + } + + if (stextflag != STORE_NONE) { + CheckStoreBtn(); + return FALSE; + } + + if (MouseY < 352) { + if (gmenu_is_on()) + return FALSE; + + if (TryIconCurs()) + return FALSE; + + if (questlog) { + if ((MouseX > 32) && (MouseX < 288) && (MouseY > 32) && (MouseY < 308)) { + CheckQLogBtn(); + return FALSE; + } + } + + if (qtextflag) { + qtextflag = FALSE; + stream_stop(); + return FALSE; + } + + if ((chrflag) && (MouseX < 320)) { + CheckChrBtns(); + return FALSE; + } + else if ((invflag) && (MouseX > 320)) { + if (!dropGoldFlag) CheckInvScrn(); + return FALSE; + } + else if ((sbookflag) && (MouseX > 320)) { + CheckSBook(); + return FALSE; + } + else if (curs >= ICSTART) { + if (TryInvPut()) { + NetSendCmdPItem(TRUE,CMD_PUTITEM,cursmx,cursmy); + NewCursor(GLOVE_CURS); + } + return FALSE; + } + else { + if ((plr[myplr]._pStatPts != 0) && (!spselflag)) + CheckLvlBtn(); + if (!lvlbtndown) + return CheckPlrLBtn(wParam == (MK_LBUTTON | MK_SHIFT)); + } + } + else { + if (!talkflag && !dropGoldFlag && !gmenu_is_on()) + CheckSpdBar(); + CheckPanelBtns(); + if ((curs > GLOVE_CURS) && (curs < ICSTART)) + NewCursor(GLOVE_CURS); + } + + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +static void wm_lbuttonup() { + gmenu_click(FALSE); + void talk_release(); + talk_release(); + if (panbtndown) ReleasePanelBtn(); + if (chrbtndown) ReleaseChrBtn(); + if (lvlbtndown) ReleaseLvlBtn(); + if (stextflag != STORE_NONE) ReleaseStoreBtn(); +} + + +//****************************************************************** +//****************************************************************** +static void wm_rbuttondown() { + + // don't allow input while the menu is active + if (gmenu_is_on()) return; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return; + + if (PauseMode == 2) return; + + if (plr[myplr]._pInvincible) return; + + if (drawmapofdoom) { + EndMapOfDoomView(); + return; + } + + if (stextflag != STORE_NONE) return; + + if (spselflag) { + SetSpell(); + return; + } +// if (sbookflag && CheckSBookCast()) +// return; + if (sbookflag && MouseX > 320) return; + + if (MouseY < 352) { + if (TryIconCurs()) + return; + if (cursinvitem != -1 && UseInvItem(myplr, cursinvitem)) + return; + } + if (curs == GLOVE_CURS) { + if (cursinvitem != -1 && UseInvItem(myplr, cursinvitem)) + return; +// else if (cursitem != -1 && (wParam & WM_SHIFT)) +// UseGroundItem(cursitem); + else + CheckPlrSpell(); + } + else if ((curs > GLOVE_CURS) && (curs < ICSTART)) NewCursor(GLOVE_CURS); +} + + +//****************************************************************** +//****************************************************************** +static void wm_mousemove() { + // check for menu sliders + if (gmenu_mousemove()) return; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) return; + + // do game mousemove here +} + + +//****************************************************************** +//****************************************************************** +static void TogglePause() { + // no pause in multiplayer + if (gbMaxPlayers > 1) return; + + if (PauseMode) { + PauseMode = 0; + } + else { + PauseMode = 2; + sound_stop(); + TrackInit(FALSE); + } + force_redraw = FULLDRAW; +} + + +//****************************************************************** +//****************************************************************** +static void SendTaunt(DWORD dwMsg) { + // don't send taunts in single player mode + if (gbMaxPlayers == 1) return; + + // get program directory + char szPath[MAX_PATH]; + if (! GetModuleFileName(ghInst,szPath,MAX_PATH)) + app_fatal("Can't get program name"); + char * pszName = strrchr(szPath,'\\'); + if (pszName) *pszName = 0; + strcat(szPath,"\\hellfire.ini"); + + static const char * spszMsgTbl[] = { + "I need help! Heal me!", + "Go through that door first.", + "Give me some gold please.", + "Look out behind you!", + }; + static const char * spszKeyTbl[] = { + "F9","F10","F11","F12" + }; + + char szBuf[MAX_SEND_STR_LEN]; + app_assert(dwMsg < sizeof(spszMsgTbl) / sizeof(spszMsgTbl[0])); + GetPrivateProfileString( + "NetMsg", // section name + spszKeyTbl[dwMsg], // key name + spszMsgTbl[dwMsg], // default string + szBuf, // dest buffer + sizeof(szBuf) / sizeof(szBuf[0]), + szPath + ); + + // send message to other players + NetSendString(SEND_ALL_MASK,szBuf); +} + + +//****************************************************************** +//****************************************************************** +static BOOL wm_syskeydown(WPARAM wKey) { + // don't allow input while the menu is active + if (gmenu_is_on()) + return FALSE; + + // note: this identical code is in the keydown case also, but + // F10 seems to come through as a system key sometimes... + if (wKey == VK_F10) { + SendTaunt(1); + return TRUE; + } + + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +static void wm_keyup(WPARAM wKey) { + // can't ever get keydown for snapshot, but we do get keyup + if (wKey == VK_SNAPSHOT) + screen_capture(); + + // if any more cases are added here, then make sure menu is not active + // if (gmenu_is_on()) return; +} + + +//****************************************************************** +//****************************************************************** +BOOL clear_windows() { + BOOL bResult = FALSE; + + if (drawmapofdoom) { + EndMapOfDoomView(); + bResult = TRUE; + } + if (helpflag) { + helpflag = FALSE; + bResult = TRUE; + } + if (qtextflag) { + qtextflag = FALSE; + stream_stop(); + #if CHEATS + if ((currlevel == 0) && (davecheat)) { + tstQMsgFlag = FALSE; + tstQMsgIndexFlag = TRUE; + } + #endif + bResult = TRUE; + } else + if (stextflag) { + STextESC(); + bResult = TRUE; + } + if (msgflag) { + msgdelay = 0; + bResult = TRUE; + } + if (talkflag) { + TalkEnd(); + bResult = TRUE; + } + if (dropGoldFlag) { + DropGoldType(VK_ESCAPE); + bResult = TRUE; + } + if (spselflag) { + spselflag = FALSE; + bResult = TRUE; + } + + return bResult; +} + + +//****************************************************************** +//****************************************************************** +static void wm_keydown(WPARAM wKey) { + // allow use of menu even when character is dead + if (gmenu_key(wKey)) + return; + + // allow user to finish current string even in timeout mode + if (Talk_wm_keydown(wKey)) + return; + + // don't allow dead player to do anything except turn on gamemenu + if (deathflag) { + // no input while in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) return; + if (wKey == VK_F9) SendTaunt(0); + if (wKey == VK_F10) SendTaunt(1); + if (wKey == VK_F11) SendTaunt(2); + if (wKey == VK_F12) SendTaunt(3); + if (wKey == VK_RETURN) TalkStart(); + if (wKey != VK_ESCAPE) return; + } + + if (wKey == VK_ESCAPE) { + if (! clear_windows()) { + TrackInit(FALSE); + gamemenu_on(); + } + #if CHEATS + if ((currlevel == 0) && (davecheat) && + ((tstQMsgFlag) || (tstQMsgIndexFlag))) { + tstQMsgFlag = FALSE; + tstQMsgIndexFlag = FALSE; + sprintf(tempstr, "STOP QUEST TEXT MODE"); + NetSendString((1 << myplr), tempstr); + return; + } + #endif + return; + } + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return; + + // Don't accept input when in drop gold mode + if (dropGoldFlag) + return; + + // in pause mode the only thing we can do is unpause + if (wKey == VK_PAUSE) { + TogglePause(); + return; + } + if (PauseMode == 2) return; + + if (wKey == VK_RETURN) { + if (stextflag) STextEnter(); + else if (questlog) QuestlogEnter(); + #if CHEATS + else if ((currlevel == 0) && (davecheat)) { + if (tstQMsgIndexFlag) { + tstQMsgIndexFlag = FALSE; + tstQMsgFlag = TRUE; + tstQMsgSpd = 5; + DaveQuestText(); + sprintf(tempstr, "Message Speed = %i", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } else if (tstQMsgFlag) { + sprintf(tempstr, "[ MESSAGE = %i ]", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "[ MESSAGE SPEED = %i ]", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } + } + #endif + else TalkStart(); + return; + } + + if (wKey == VK_F1) { + if (helpflag) { + helpflag = FALSE; + } + else if (stextflag != STORE_NONE) { + ClearPanel(); + AddPanelString("No help available", TEXT_CENTER); + AddPanelString("while in stores", TEXT_CENTER); + TrackInit(FALSE); + } + else { + invflag = FALSE; + chrflag = FALSE; + sbookflag = FALSE; + spselflag = FALSE; + if ((qtextflag) && (leveltype == 0)) { + qtextflag = FALSE; + stream_stop(); + } + questlog = FALSE; + automapflag = FALSE; + msgdelay = 0; + gamemenu_off(); + StartHelp(); + EndMapOfDoomView(); + } + return; + } + + #if CHEATS + if (wKey == VK_F2) { + void PrintDaveCheck2(); + PrintDaveCheck2(); + } + +/* if (wKey == VK_F3) { + extern BOOL syncdebug; + syncdebug = !syncdebug; + if (syncdebug) + strcpy(tempstr, "Item drop debug on"); + else + strcpy(tempstr, "Item drop debug off"); + NetSendString((1 << myplr), tempstr); + }*/ + if (wKey == VK_F3) { + if (cursitem != -1) { + sprintf(tempstr, "IDX = %i : Seed = %i : CF = %i", item[cursitem].IDidx, item[cursitem]._iSeed, item[cursitem]._iCreateInfo); + NetSendString((1 << myplr), tempstr); + } + sprintf(tempstr, "Numitems : %i", numitems); + NetSendString((1 << myplr), tempstr); + } + + if (wKey == VK_F4) { + void PrintQuestDebug(); + PrintQuestDebug(); + return; + } + #endif + +/* #if CHEATS + if (wKey == VK_F4) { + if (cheatflag) toggle_frame_counter(); + return; + } + #endif*/ + + if (wKey == VK_F5) { + if (spselflag) SetSpellHK(0); + else GetSpellHK(0); + return; + } + if (wKey == VK_F6) { + if (spselflag) SetSpellHK(1); + else GetSpellHK(1); + return; + } + if (wKey == VK_F7) { + if (spselflag) SetSpellHK(2); + else GetSpellHK(2); + return; + } + if (wKey == VK_F8) { + if (spselflag) SetSpellHK(3); + else GetSpellHK(3); + return; + } + + if (wKey == VK_F9) { + SendTaunt(0); + return; + } + if (wKey == VK_F10) { + SendTaunt(1); + return; + } + if (wKey == VK_F11) { + SendTaunt(2); + return; + } + if (wKey == VK_F12) { + SendTaunt(3); + return; + } + + if (wKey == VK_UP) { + if (stextflag) STextUp(); + else if (questlog) QuestlogUp(); + else if (helpflag) HelpScrollUp(); + else if (automapflag) AutomapUp(); + return; + } + + if (wKey == VK_DOWN) { + if (stextflag) STextDown(); + else if (questlog) QuestlogDown(); + else if (helpflag) HelpScrollDown(); + else if (automapflag) AutomapDown(); + return; + } + + if (wKey == VK_PRIOR) { + if (stextflag) STextPgUp(); + return; + } + + if (wKey == VK_NEXT) { + if (stextflag) STextPgDown(); + return; + } + + if (wKey == VK_LEFT) { + if (automapflag && !talkflag) AutomapLeft(); + return; + } + if (wKey == VK_RIGHT) { + if (automapflag && !talkflag) AutomapRight(); + return; + } + + if (wKey == VK_TAB) { + void DoAutoMap(); + DoAutoMap(); + return; + } + +/* if (wKey == VK_CAPITAL) { + FriendlyMode = !FriendlyMode; + drawbtnflag = TRUE; + return; + }*/ + + if (wKey == VK_SPACE) { + if ((!chrflag) && (invflag) && (MouseX < 480) && (MouseY < 352)) SetCursorPos(MouseX+160,MouseY); + if ((!invflag) && (chrflag) && (MouseX > 160) && (MouseY < 352)) SetCursorPos(MouseX-160,MouseY); + helpflag = FALSE; + invflag = FALSE; + chrflag = FALSE; + sbookflag = FALSE; + spselflag = FALSE; + if ((qtextflag) && (leveltype == 0)) { + qtextflag = FALSE; + stream_stop(); + } + questlog = FALSE; + automapflag = FALSE; + msgdelay = 0; + gamemenu_off(); + EndMapOfDoomView(); +//Never clear the cursor, else we lose a scroll or a staff charge +//for a spell we've cast. +// if ((curs != GLOVE_CURS) && (curs < ICSTART)) NewCursor(GLOVE_CURS); + return; + } +} + + +//****************************************************************** +//****************************************************************** +static void wm_char(WPARAM wKey) { + #ifdef _DEBUG + BOOL is_pat_debug_cmd(WPARAM wKey); + if (is_pat_debug_cmd(wKey)) + return; + #endif + + // don't allow input while the menu is active + if (gmenu_is_on()) + return; + + if (Talk_wm_char(wKey)) + return; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return; + + // dead players can't perform input + if (deathflag) + return; + + // in pause mode the only thing we can do is unpause + if ((TCHAR) wKey == 'p' || (TCHAR) wKey == 'P') { + TogglePause(); + return; + } + if (PauseMode == 2) return; + + if (drawmapofdoom) { + EndMapOfDoomView(); + return; + } + + if (dropGoldFlag) { + DropGoldType((char) wKey); + return; + } + + switch(wKey) { + case 'g': + case 'G': + GammaDown(); + return; + + case 'f': + case 'F': + GammaUp(); + return; + + case 'i': + case 'I': + if (stextflag != STORE_NONE) return; + sbookflag = FALSE; + invflag = !invflag; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + if (invflag && !chrflag) { + if (MouseX > 160 && MouseY < 352) SetCursorPos(MouseX-160,MouseY); + } + else { + if (MouseX < 480 && MouseY < 352) SetCursorPos(MouseX+160, MouseY); + } + return; + + case 'c': + case 'C': + if (stextflag != STORE_NONE) return; + questlog = FALSE; + chrflag = !chrflag; + if (chrflag && !invflag) { + if (MouseX < 480 && MouseY < 352) SetCursorPos(MouseX+160,MouseY); + } + else { + if (MouseX > 160 && MouseY < 352) SetCursorPos(MouseX-160, MouseY); + } + return; + + #ifndef NDEBUG + case 'r': + case 'R': + sprintf(tempstr, "seed = %i", glSeedTbl[currlevel]); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "Mid1 = %i : Mid2 = %i : Mid3 = %i", + glMid1Seed[currlevel], glMid2Seed[currlevel], glMid3Seed[currlevel]); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "End = %i", glEndSeed[currlevel]); + NetSendString((1 << myplr), tempstr); + return; + #endif + + #if CHEATS + case 'A': + if (cheatflag) { + sprintf(tempstr, "Mid: %i", dMonster[cursmx][cursmy] - 1); + NetSendString((1 << myplr), tempstr); + if (dMonster[cursmx][cursmy] > 0) { + monster[(dMonster[cursmx][cursmy] - 1)]._mFlags |= MFLAG_MKILLER; + void M_Enemy(int); + M_Enemy((dMonster[cursmx][cursmy] - 1)); + } + } + return; + case 'a': + if (cheatflag) { + plr[myplr]._pSplLvl[(plr[myplr]._pSpell)]++; + spelldata[SPL_TELE].sTownSpell = TRUE; + } + return; + #endif + + #if CHEATS + case ')': + case '0': + if (cheatflag) { + if (gv1 > 2) gv1 = 0; + if (gv1 == 0) { + plr[myplr]._pIFlags &= ~IAF_FIREARROW; + plr[myplr]._pIFlags &= ~IAF_LARROW; + } + if (gv1 == 1) plr[myplr]._pIFlags |= IAF_FIREARROW; + if (gv1 == 2) plr[myplr]._pIFlags |= IAF_LARROW; + gv1++; + } + return; + #endif + + #if CHEATS + case 'l': + case 'L': + if (cheatflag) ToggleLight(); + return; + #endif + + #if CHEATS + case 't': + case 'T': + if (cheatflag) { + sprintf(tempstr, "PX = %i PY = %i", plr[myplr]._px, plr[myplr]._py); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "CX = %i CY = %i DP = %i", cursmx, cursmy, dungeon[cursmx][cursmy]); + NetSendString((1 << myplr), tempstr); + } + return; + #endif + + #ifndef NDEBUG + case 'D': + void BlipDebug(BOOL); + BlipDebug(TRUE); + return; + case 'd': + BlipDebug(FALSE); + return; + #endif + + #if CHEATS + case 'e': + if (davedebug) { + sprintf(tempstr, "EFlag = %i", plr[myplr]._peflag); + NetSendString((1 << myplr), tempstr); + } + return; + #endif + + #ifndef NDEBUG + case 'm': + void DaveDebugMonst(); + DaveDebugMonst(); + return; + case 'M': + void DaveDebugMonst2(); + DaveDebugMonst2(); + return; + #endif + + #if CHEATS + case '|': + if ((currlevel == 0) && (davecheat)) DaveGold(); + return; + #endif + + #if CHEATS + case '~': + if ((currlevel == 0) && (davecheat)) DaveNewPremium(); + return; + #endif + + #if CHEATS + case '[': + if ((currlevel == 0) && (davecheat)) DaveCleanUp(); + return; + #endif + + #if CHEATS + case ']': + if ((currlevel == 0) && (davecheat)) DaveSpells(); + return; + #endif + + #if CHEATS + case ':': + if ((currlevel == 0) && (davecheat)) DaveSpells2(); + return; + #endif + + #if CHEATS + case '.': + void DaveDungDebug(); + DaveDungDebug(); + return; + #endif + + #if CHEATS + case '?': + if ((currlevel == 0) && (davecheat)) { + tstQMsgFlag = FALSE; + tstQMsgIndexFlag = TRUE; + sprintf(tempstr, "START QUEST TEXT MODE"); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "Message = %i", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + } + return; + #endif + + case 'q': + case 'Q': + if (stextflag != STORE_NONE) return; + chrflag = FALSE; + if (!questlog) StartQuestlog(); + else questlog = FALSE; + return; + + case 'z': + case 'Z': + svgamode = !svgamode; + return; + + case 's': + case 'S': + if (stextflag != STORE_NONE) return; + invflag = FALSE; + if (!spselflag) SetupSpellSel(); + else spselflag = FALSE; + TrackInit(FALSE); + return; + + case 'b': + case 'B': + if (stextflag != STORE_NONE) return; + invflag = FALSE; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + sbookflag = !sbookflag; + return; + + case '+': + case '=': + if (automapflag) AutomapZoomIn(); + #if CHEATS + else if ((currlevel == 0) && (davecheat)) { + if (tstQMsgIndexFlag) { + tstQMsgIndex++; + if (tstQMsgIndex > (int)(gdwAllTextEntries-1)) tstQMsgIndex = 0; + sprintf(tempstr, "Message = %i", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + } else if (tstQMsgFlag) { + tstQMsgSpd++; + if (tstQMsgSpd > 9) tstQMsgSpd = 9; + qtextSpd = qtextDelaySpd[tstQMsgSpd-1]; + qtextflag = FALSE; + stream_stop(); + DaveQuestText(); + sprintf(tempstr, "Message Speed = %i", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } + } + #endif + return; + + case '_': + case '-': + if (automapflag) AutomapZoomOut(); + #if CHEATS + else if ((currlevel == 0) && (davecheat)) { + if (tstQMsgIndexFlag) { + tstQMsgIndex--; + if (tstQMsgIndex < 0) tstQMsgIndex = (int)(gdwAllTextEntries-1); + sprintf(tempstr, "Message = %i", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + } else if (tstQMsgFlag){ + tstQMsgSpd--; + if (tstQMsgSpd < 1) tstQMsgSpd = 1; + qtextSpd = qtextDelaySpd[tstQMsgSpd-1]; + qtextflag = FALSE; + stream_stop(); + DaveQuestText(); + sprintf(tempstr, "Message Speed = %i", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } + } + #endif + return; + + case 'v': + extern char gszPrintVersion[]; + { + char *pszaDif[] = {"Normal", "Nightmare", "Hell"}; + char tmpbuf[120]; + sprintf(tmpbuf, "%s, mode = %s", gszPrintVersion, + pszaDif[gnDifficulty]); + NetSendString((1 << myplr), tmpbuf); + } +// NetSendString((1 << myplr), gszPrintVersion); + break; + + case 'V': + extern char gszVersionNumber[]; + NetSendString((1 << myplr), gszVersionNumber); + return; + + case '!': + case '1': + if ((plr[myplr].SpdList[0]._itype != -1) && + (plr[myplr].SpdList[0]._itype != IT_GOLD)) UseInvItem(myplr, 47); + return; + + case '@': + case '2': + if ((plr[myplr].SpdList[1]._itype != -1) && + (plr[myplr].SpdList[1]._itype != IT_GOLD)) UseInvItem(myplr, 48); + return; + + case '#': + case '3': + if ((plr[myplr].SpdList[2]._itype != -1) && + (plr[myplr].SpdList[2]._itype != IT_GOLD)) UseInvItem(myplr, 49); + return; + + case '$': + case '4': + if ((plr[myplr].SpdList[3]._itype != -1) && + (plr[myplr].SpdList[3]._itype != IT_GOLD)) UseInvItem(myplr, 50); + return; + + case '%': + case '5': + if ((plr[myplr].SpdList[4]._itype != -1) && + (plr[myplr].SpdList[4]._itype != IT_GOLD)) UseInvItem(myplr, 51); + return; + + case '^': + case '6': + if ((plr[myplr].SpdList[5]._itype != -1) && + (plr[myplr].SpdList[5]._itype != IT_GOLD)) UseInvItem(myplr, 52); + return; + + case '&': + case '7': + if ((plr[myplr].SpdList[6]._itype != -1) && + (plr[myplr].SpdList[6]._itype != IT_GOLD)) UseInvItem(myplr, 53); + return; + + case '*': + case '8': + #if CHEATS + if (cheatflag || davecheat) { + NetSendCmd(TRUE,CMD_CHEAT_EXPERIENCE); + return; + } + #endif + if ((plr[myplr].SpdList[7]._itype != -1) && + (plr[myplr].SpdList[7]._itype != IT_GOLD)) UseInvItem(myplr, 54); + return; +/* + // testing diablo death + case 'k': +#define MT_DIABLO 110 + for (int i = 0; i < nummonsters; i++) { + int mi = monstactive[i]; + if (monster[mi].MType->mtype == MT_DIABLO) + M_StartKill(mi, myplr); + } + return; +*/ + } +} + + +//****************************************************************** +//****************************************************************** +LRESULT CALLBACK DisableInputWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + switch (uMsg) { + // don't let input go to game window proc + case WM_SYSKEYDOWN: + case WM_SYSCOMMAND: + case WM_KEYUP: + case WM_KEYDOWN: + case WM_CHAR: + case WM_MOUSEMOVE: + return 0; + + case WM_LBUTTONDOWN: + if (sgbMouseDown) return 0; + sgbMouseDown = LMOUSE_DOWN; + SetCapture(hWnd); + return 0; + + case WM_LBUTTONUP: + if (sgbMouseDown != LMOUSE_DOWN) return 0; + sgbMouseDown = 0; + ReleaseCapture(); + return 0; + + case WM_RBUTTONDOWN: + if (sgbMouseDown) return 0; + sgbMouseDown = RMOUSE_DOWN; + SetCapture(hWnd); + return 0; + + case WM_RBUTTONUP: + if (sgbMouseDown != RMOUSE_DOWN) return 0; + sgbMouseDown = 0; + ReleaseCapture(); + return 0; + + case WM_CAPTURECHANGED: + if (hWnd != (HWND) lParam) + sgbMouseDown = 0; + return 0; + } + + return DiabloDefProc(hWnd,uMsg,wParam,lParam); +} + + +//****************************************************************** +//****************************************************************** +static LRESULT CALLBACK GM_Game(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + switch (uMsg) { + case WM_SYSKEYDOWN: + if (wm_syskeydown(wParam)) return 0; + break; + + case WM_KEYUP: + wm_keyup(wParam); + return 0; + + case WM_KEYDOWN: + wm_keydown(wParam); + return 0; + + case WM_CHAR: + wm_char(wParam); + return 0; + + case WM_MOUSEMOVE: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + wm_mousemove(); + return 0; + + case WM_LBUTTONDOWN: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // if the mouse is already down, wait for mouse up + if (sgbMouseDown) return 0; + sgbMouseDown = LMOUSE_DOWN; + SetCapture(hWnd); + + TrackInit(wm_lbuttondown(wParam)); + return 0; + + case WM_LBUTTONUP: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // don't accept mouse up unless it went down in our window + if (sgbMouseDown != LMOUSE_DOWN) return 0; + sgbMouseDown = 0; + + wm_lbuttonup(); + TrackInit(FALSE); + ReleaseCapture(); + return 0; + + case WM_RBUTTONDOWN: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // if the mouse is already down, wait for mouse up + if (sgbMouseDown) return 0; + sgbMouseDown = RMOUSE_DOWN; + SetCapture(hWnd); + + wm_rbuttondown(); + return 0; + + case WM_RBUTTONUP: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // don't accept mouse up unless it went down in our window + if (sgbMouseDown != RMOUSE_DOWN) return 0; + sgbMouseDown = 0; + ReleaseCapture(); + return 0; + + case WM_CAPTURECHANGED: + if (hWnd != (HWND) lParam) { + sgbMouseDown = 0; + TrackInit(FALSE); + } + break; + + case WM_DIABNEXTLVL: + case WM_DIABPREVLVL: + case WM_DIABSETLVL: + case WM_DIABRTNLVL: + case WM_DIABWARPLVL: + case WM_DIABTOWNWARP: + case WM_DIABTWARPUP: + case WM_DIABRETOWN: + // save character in multiplayer mode + if (gbMaxPlayers > 1) { + void UpdatePlayerFile(); + UpdatePlayerFile(); + } + nthread_perform_keepalive(TRUE); + PaletteFadeOut(FADE_FAST); + sound_stop(); + music_stop(); + TrackInit(FALSE); + sgbMouseDown = FALSE; + ReleaseCapture(); + ShowProgress(uMsg); + force_redraw = FULLDRAW; + DrawAndBlit(); + if (gbRunGame) PaletteFadeIn(FADE_FAST); + nthread_perform_keepalive(FALSE); + gbGameLoopStartup = TRUE; + return 0; + + case WM_SYSCOMMAND: + if (wParam == SC_CLOSE) { + gbRunGame = FALSE; + gbRunGameResult = FALSE; + return 0; + } + break; + } + + return DiabloDefProc(hWnd, uMsg, wParam, lParam); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LoadLvlGFX() { + app_assert(! pDungeonCels); + switch (leveltype) { + case 0: + pDungeonCels = LoadFileInMemSig("NLevels\\TownData\\Town.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("NLevels\\TownData\\Town.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("NLevels\\TownData\\Town.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\TownData\\TownS.CEL",NULL,'TILE'); + break; + + case 1: +/* pDungeonCels = LoadFileInMemSig("Levels\\L1Data\\L1.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L1Data\\L1.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L1Data\\L1.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + break;*/ + if (currlevel < CRYPTSTART) + { + pDungeonCels = LoadFileInMemSig("Levels\\L1Data\\L1.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L1Data\\L1.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L1Data\\L1.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + } + else + { + pDungeonCels = LoadFileInMemSig("NLevels\\L5Data\\L5.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("NLevels\\L5Data\\L5.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("NLevels\\L5Data\\L5.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("NLevels\\L5Data\\L5S.CEL",NULL,'TILE'); + } + break; + + #if IS_VERSION(RETAIL) || IS_VERSION(BETA) + case 2: + pDungeonCels = LoadFileInMemSig("Levels\\L2Data\\L2.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L2Data\\L2.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L2Data\\L2.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L2Data\\L2S.CEL",NULL,'TILE'); + break; + #endif + + #if IS_VERSION(RETAIL) + case 3: + if (currlevel < HIVESTART) + { + pDungeonCels = LoadFileInMemSig("Levels\\L3Data\\L3.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L3Data\\L3.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L3Data\\L3.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + } + else + { + pDungeonCels = LoadFileInMemSig("NLevels\\L6Data\\L6.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("NLevels\\L6Data\\L6.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("NLevels\\L6Data\\L6.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + } + break; + #endif + + #if IS_VERSION(RETAIL) + case 4: + pDungeonCels = LoadFileInMemSig("Levels\\L4Data\\L4.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L4Data\\L4.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L4Data\\L4.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L2Data\\L2S.CEL",NULL,'TILE'); + break; + #endif + + default: + app_fatal("LoadLvlGFX"); + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void LoadAllGFX() +{ + app_assert(! pSpeedCels); + pSpeedCels = DiabloAllocPtrSig(SPEEDSIZE,'SPED'); +// InitMonsterGFX(); + IntCheck(); +// InitMonsterSND(); + IntCheck(); + InitObjectGFX(); + IntCheck(); + InitMissileGFX(); + IntCheck(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CreateLevel(int lvldir) +{ + switch (leveltype) { + case 0: + CreateTown(lvldir); + InitTownTriggers(); + LoadRndLvlPal(0); + break; + + case 1: + CreateL5Dungeon(glSeedTbl[currlevel], lvldir); + InitL1Triggers(); + Freeupstairs(); + if (currlevel < CRYPTSTART) // JKE load correct pallet + LoadRndLvlPal(1); + else + LoadRndLvlPal(5); + break; + + #if IS_VERSION(RETAIL) || IS_VERSION(BETA) + case 2: + CreateL2Dungeon(glSeedTbl[currlevel], lvldir); + InitL2Triggers(); + Freeupstairs(); + LoadRndLvlPal(2); + break; + #endif + + #if IS_VERSION(RETAIL) + case 3: + CreateL3Dungeon(glSeedTbl[currlevel], lvldir); + InitL3Triggers(); + Freeupstairs(); + if (currlevel < HIVESTART) + LoadRndLvlPal(3); + else + LoadRndLvlPal(6); + break; + #endif + + #if IS_VERSION(RETAIL) + case 4: + CreateL4Dungeon(glSeedTbl[currlevel], lvldir); + InitL4Triggers(); + Freeupstairs(); + LoadRndLvlPal(4); + break; + #endif + + default: + app_fatal("CreateLevel"); + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void LoadGameLevel(BOOL firstflag, int lvldir) +{ + int i,j; + + if (setseed) + glSeedTbl[currlevel] = setseed; + + music_stop(); + SetCursor(GLOVE_CURS); + SetRndSeed(glSeedTbl[currlevel]); + IntCheck(); + + MakeLightTable(); + LoadLvlGFX(); + IntCheck(); + + if (firstflag) { + InitInv(); + InitItemGFX(); + InitQuestText(); + for (i = 0; i < gbMaxPlayers; i++) + InitPlrGFXMem(i); + InitStores(); + InitAutomapOnce(); + InitHelpSys(); + } + + SetRndSeed(glSeedTbl[currlevel]); + if (leveltype == 0) SetupTownStores(); + IntCheck(); + + InitAutomap(); + + if ((leveltype != 0) && (lvldir != LVL_NODIR)) { + InitLighting(); + InitVision(); + } + InitLevelMonsters(); + IntCheck(); + + if (!setlevel) { + CreateLevel(lvldir); + IntCheck(); + + // Open Tiles file + FillSolidBlockTbls(); + + SetRndSeed(glSeedTbl[currlevel]); + + if (leveltype != 0) { + GetLevelMTypes(); + InitThemes(); + LoadAllGFX(); + } else { + InitMissileGFX(); + } + IntCheck(); + + if (lvldir == LVL_RTN) GetReturnLvlPos(); + if (lvldir == LVL_WARP) GetPortalLvlPos(); + IntCheck(); + + // Init Player info + for (i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (currlevel != plr[i].plrlevel) continue; + InitPlayerGFX(i); + if (lvldir != LVL_NODIR) InitPlayer(i, firstflag); + } + + PlayDungMsgs(); + InitMultiView(); + IntCheck(); + + BOOL visited = FALSE; + for (i = 0; i < gbMaxPlayers; i++) + if (plr[i].plractive) visited = visited || plr[i]._pLvlVisited[currlevel]; + + // Resync after level changing bug + // This bug occurs when 2 players change levels one after the other. The first player + // down thinks the other player is one level above, because the change level msg has + // not been processed during loading. The second player knows that they are both + // on the same level, so more players get inited, and randoms desync. + SetRndSeed(glSeedTbl[currlevel]); + + if (leveltype != 0) { + if (!firstflag && (lvldir != LVL_NODIR) && plr[myplr]._pLvlVisited[currlevel] && (gbMaxPlayers == 1)) { + // Init monsters so uniques are loaded + InitMonsters (); + // Init missiles + InitMissiles(); + // Init dead info, not dungeon layout though + InitDead(); + IntCheck (); + // Load where things were + LoadLevel(); + IntCheck (); + } else { + // Save theme room areas + HoldThemeRooms(); + glMid1Seed[currlevel] = GetRndSeed(); // @@@ drb temp + // Init monsters into dungeon + InitMonsters (); + glMid2Seed[currlevel] = GetRndSeed(); // @@@ drb temp + // Init objects + InitObjects(); + // Init items + InitItems(); + // Fill theme rooms + if (currlevel < HIVESTART) CreateThemeRooms(); // Temp hack for failure JKE +// CreateThemeRooms(); + glMid3Seed[currlevel] = GetRndSeed(); // @@@ drb temp + // Init missiles + InitMissiles(); + // Init dead info, not dungeon layout though + InitDead(); + glEndSeed[currlevel] = GetRndSeed(); // @@@ drb temp + // if multiplayer resync level + if (gbMaxPlayers != 1) DeltaLoadLevel(); + IntCheck(); + SavePreLighting(); + } + } else { + // Make everything visible + for (i = 0; i < DMAXX; i++) + for (j = 0; j < DMAXY; j++) + dFlags[i][j] |= BFLAG_VISIBLE; + // Init town people + InitTowners(); + // Init items + InitItems(); + // Init missiles + InitMissiles(); + IntCheck(); + + // Load items + if (!firstflag && (lvldir != LVL_NODIR) && plr[myplr]._pLvlVisited[currlevel] && (gbMaxPlayers == 1)) + LoadLevel(); + if (gbMaxPlayers != 1) DeltaLoadLevel(); + IntCheck (); + } + if (gbMaxPlayers == 1) + ResyncQuests(); + else + ResyncMPQuests(); + + } +#if !IS_VERSION(SHAREWARE) + else { + // Preset levels + app_assert(! pSpeedCels); + pSpeedCels = DiabloAllocPtrSig(SPEEDSIZE,'SPED'); + + LoadSetMap(); + IntCheck(); + + GetLevelMTypes(); + + InitMonsters(); + + //SetDungeonMicros(); + + InitMissileGFX(); + + // Init dead info, not dungeon layout though + InitDead(); + + // Open Tiles file + FillSolidBlockTbls (); + IntCheck(); + + if (lvldir == LVL_WARP) GetPortalLvlPos(); + + // Init Player info + for (i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (currlevel != plr[i].plrlevel) continue; + InitPlayerGFX(i); + if (lvldir != LVL_NODIR) InitPlayer(i, firstflag); + } + + InitMultiView(); + IntCheck(); + + if ((!firstflag) && (lvldir != LVL_NODIR) && (plr[myplr]._pSLvlVisited[setlvlnum])) { + // Load where things were + LoadLevel(); + } else { + // Init items + InitItems(); + SavePreLighting(); + } + // Init missiles + InitMissiles(); + IntCheck(); + } +#endif + + SyncPortals(); + + for (i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (plr[i].plrlevel != currlevel) continue; + if (plr[i]._pLvlChanging && (i != myplr)) continue; + if (plr[i]._pHitPoints > 0) { + if (gbMaxPlayers == 1) + dPlayer[plr[i]._px][plr[i]._py] = i + 1; + else + SyncInitPlrPos(i); + } else + dFlags[plr[i]._px][plr[i]._py] |= BFLAG_DEADPLR; + } + + if (leveltype != 0) { + SetDungeonMicros(); + } + + InitLightMax(); // Set up 4 or 16 level lighting + IntCheck(); + +/* + if ((leveltype != 0) && (lvldir != LVL_NODIR)) { + SavePreLighting(); + } +*/ + IntCheck(); + + if (firstflag) { + // Get Control panel graphics and decompress panel to BtmBuff + // Has to be after init player because of bars/spells/equipment etc. + InitControlPan(); + IntCheck(); + } + + if (leveltype != 0) { + ProcessLightList(); + ProcessVisionList(); + } + if (currlevel >= CRYPTSTART) + { +// OpenCloseAllDoors(); // JKE Stupid!!! + if (currlevel == CORNERSTONE_LEVEL) + CornerstoneRestore(CornerStone.x, CornerStone.y); + if ((quests[Q_NA_KRUL]._qactive == QUEST_DONE)&&(currlevel == NA_KRUL_LEVEL)) + OpenNaKrul2(); + + } + + // start appropriate sound track + if (currlevel >= HIVESTART) // fix this later JKE + { + music_start((currlevel > HIVEEND)? 5 : 6); + } + else + music_start(leveltype); + + // finish progress bar + while (! IntCheck()) + NULL; + + #if !IS_VERSION(SHAREWARE) + if ((setlevel) && (setlvlnum == SL_SKELKING) && (quests[Q_SKELKING]._qactive == QUEST_NOTDONE)) + PlaySFX(USFX_SKING1); + #endif +} + + +//****************************************************************** +//****************************************************************** +// this parameter is the maximum number of game loops which can be run +// in a row without redrawing the screen +#define MAX_CONSECUTIVE_LOOPS 3 + + +//****************************************************************** +//****************************************************************** +static void game_logic() { + if (PauseMode == 2) return; + if (PauseMode == 1) PauseMode = 2; + + // pause when menu is active in single player mode + if (gbMaxPlayers == 1 && gmenu_is_on()) { + force_redraw |= VIEWDRAW; + return; + } + + if (! gmenu_is_on() && (sgnTimeoutCurs == NO_CURSOR)) { + CheckCursMove(); + TrackMouse(); + } + + if (gbProcessPlayers) + ProcessPlayers(); + if (leveltype) { + ProcessMonsters(); + ProcessObjects(); + ProcessMissiles(); + ProcessItems(); + ProcessLightList(); + ProcessVisionList(); + } + else { + ProcessTowners(); + ProcessItems(); + ProcessMissiles(); + } + + #if CHEATS + if ((cheatflag) && ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0)) + CheckForScroll(); + #endif + + sound_update(); + plrmsg_update(); + CheckTriggers(); + CheckQuests(); + force_redraw |= VIEWDRAW; + + void TimedUpdatePlayerFile(BOOL bForce); + TimedUpdatePlayerFile(FALSE); +} + + +//****************************************************************** +//****************************************************************** +static void timeout_cursor(BOOL bTimeout) { + if (bTimeout) { + // if we weren't in a timeout state, set timeout + if (sgnTimeoutCurs == NO_CURSOR && ! sgbMouseDown) { + sgnTimeoutCurs = curs; + + NetStartTimeout(); + + // display timeout error + ClearPanel(); + AddPanelString("-- Network timeout --", TEXT_CENTER); + AddPanelString("-- Waiting for players --", TEXT_CENTER); + + // fix up the cursor + NewCursor(TIMEOUT_CURSOR); + + // we probably made a mess of the screen + force_redraw = FULLDRAW; + } + + FullBlit(TRUE); + } + else if (sgnTimeoutCurs != NO_CURSOR) { + // ending timeout + SetCursor(sgnTimeoutCurs); + sgnTimeoutCurs = NO_CURSOR; + ClearPanel(); + force_redraw = FULLDRAW; + } +} + + +//****************************************************************** +//****************************************************************** +static void game_loop(BOOL bStartup) { + int nMaxLoops = bStartup ? GAME_FRAMES_PER_SECOND * 3 : MAX_CONSECUTIVE_LOOPS; + while (nMaxLoops--) { + // wait for synchronous network message + if (! NetEndSendCycle()) { + timeout_cursor(TRUE); + break; + } + timeout_cursor(FALSE); + + // run logic at GAME_FRAMES_PER_SECOND + game_logic(); + + // if the game mode changed, then don't continue loop + if (! gbRunGame) + break; + + // don't run multiple loops in single player mode + if (gbMaxPlayers == 1) + break; + + // have we been in the loop too long? + if (! nthread_run_gameloop(TRUE)) + break; + + #if CHEATS + static DWORD sdwSkips = 0; + sdwSkips++; + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr == DD_OK) { + char szBuf[16]; + wsprintf(szBuf,"%u",sdwSkips); + TextOut(hDC,5,370,szBuf,strlen(szBuf)); + lpDDSPrimary->ReleaseDC(hDC); + } + #endif + } +} + + +//****************************************************************** +//****************************************************************** +static void DoTimedEvents() { + static DWORD sdwCurrTime = 0; + DWORD dwCurrTime = GetTickCount(); + if (dwCurrTime - sdwCurrTime < 1000/GAME_FRAMES_PER_SECOND) + return; + sdwCurrTime = dwCurrTime; + + if (leveltype == 4) + BloodCycle(); + else if (currlevel >= CRYPTSTART) + TwinCycleCrypt(); + else if (currlevel >= HIVESTART) + TwinCycleNest(); + else if (leveltype == 3 && fullscreen) + LavaCycle(); +} + + +//****************************************************************** +//****************************************************************** +/* pjw.patch1.start +static void try_game_loop(BOOL bStartup) { + DoTimedEvents(); + NetReceivePackets(); + + if (! nthread_run_gameloop(FALSE)) + return; + + // run game loop + game_loop(bStartup); + + // redraw the screen if necessary + DrawAndBlit(); +} +pjw.patch1.end */ + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +#define RAND_MASK (32*1024-1) +#define PLR_BYTES (sizeof(PlayerStruct) * MAX_PLRS) +static PlayerStruct * alloc_plr_chunk(PlayerStruct * p1) { + + // make sure p2 ends up in different locations + LPVOID pTemp = malloc(rand() & RAND_MASK); + PlayerStruct * p2 = (PlayerStruct *) malloc(PLR_BYTES); + if (pTemp) free(pTemp); + + if (! p2) return p1; + if (p1) { + CopyMemory(p2,p1,PLR_BYTES); + free(p1); + } + return p2; +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +static void alloc_plr() { + if (NULL == (plr = alloc_plr_chunk(NULL))) + app_fatal("Unable to initialize memory"); + ZeroMemory(plr,PLR_BYTES); +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +#pragma intrinsic(_rotl) +static DWORD calc_checksum(LPVOID lpMem,DWORD dwBytes,DWORD dwSum) { + LPDWORD lpDW = (LPDWORD) lpMem; + dwBytes /= sizeof(DWORD); + while (dwBytes--) { + dwSum ^= *lpDW++; + dwSum = _rotl(dwSum,3); + } + return dwSum; +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +static void CRASH() { +#if 0 // !!! @@@ !!! fix in final + static BYTE sgbCheating = FALSE; + if (! sgbCheating) { + sgbCheating = TRUE; + app_warning("Cheating detected"); + void myDebugBreak(); + myDebugBreak(); + } +#else + LPDWORD pFrame = (LPDWORD) plr[myplr]._pAnimData; + pFrame[plr[myplr]._pAnimFrame + 1] ^= 0x3fffffff; +#endif + FullBlit(TRUE); +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +typedef void (* TCrypt)(LPDWORD,DWORD,DWORD); +static void encrypt_aux(TCrypt fnCrypt) { + for (int i = 0; i < MAX_PLRS; i++) { + // SLOW encrypt the important part of the character + fnCrypt((LPDWORD)&plr[i],offsetof(PlayerStruct,_pGFXLoad),HASH_ENCRYPTKEY); + + // FAST encrypt the inventory -- takes too long otherwise + LPDWORD lpInv = (LPDWORD) &plr[i].InvBody; + for (int j = sizeof(ItemStruct) * NUM_INVLOC / sizeof(DWORD); j--; ) + *lpInv++ ^= 0xf0638142; + + // pjw.patch2.start -- commented out -- still taking too long + #if 0 + lpInv = (LPDWORD) &plr[i].InvList; + for (j = sizeof(ItemStruct) * MAXINV / sizeof(DWORD); j--; ) + *lpInv++ ^= 0x23484862; + #endif + // pjw.patch2.end + } +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +#if 0 +// pjw.patch1.start +static void plr_encrypt(BOOL bEncrypt) { + static BOOL sbEncrypt = FALSE; + static BOOL sbCrash = FALSE; + static DWORD sdwCheckSum = 0; + static DWORD sdwCheckStart = 0; + if (sbEncrypt == bEncrypt) return; + sbEncrypt = bEncrypt; + +// pjw.patch2.start -- added for debugging only! +#if 0 + static DWORD sgdwEncryptCount = 0; + sgdwEncryptCount++; + static DWORD sgdwLastTime = 0; + if (GetTickCount() - sgdwLastTime >= 1000) { + sgdwLastTime = GetTickCount(); + do { + char szBuf[32]; + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr != DD_OK) break; + COLORREF oldTextColor = SetTextColor(hDC,RGB(0xff,0xff,0)); + COLORREF oldBkColor = SetBkColor(hDC,RGB(0,0,0)); + int oldBkMode = SetBkMode(hDC,OPAQUE); + sprintf(szBuf,"%u ",sgdwEncryptCount); + sgdwEncryptCount = 0; + TextOut(hDC,5,385,szBuf,strlen(szBuf)); + SetTextColor(hDC,oldTextColor); + SetBkColor(hDC,oldBkColor); + SetBkMode(hDC,oldBkMode); + lpDDSPrimary->ReleaseDC(hDC); + } while (0); + } +#endif +// pjw.patch2.end + + if (sbCrash) { + CRASH(); + } + else if (bEncrypt) { + sdwCheckStart = rand(); + sdwCheckSum = calc_checksum(plr,PLR_BYTES,sdwCheckStart); + encrypt_aux(Encrypt); + } + else { + encrypt_aux(Decrypt); + if (sdwCheckSum != calc_checksum(plr,PLR_BYTES,sdwCheckStart)) { + CRASH(); + sbCrash = 1; + } + } + + if ((rand() & 0x0f) == 0x0f) + plr = alloc_plr_chunk(plr); +} +#endif +// pjw.patch1.end diff --git a/DIABLO.DSP b/DIABLO.DSP new file mode 100644 index 0000000..d53c019 --- /dev/null +++ b/DIABLO.DSP @@ -0,0 +1,763 @@ +# Microsoft Developer Studio Project File - Name="Diablo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=Diablo - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Diablo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Diablo.mak" CFG="Diablo - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Diablo - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 FinalFinal" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Shareware FinalFinal" (based on\ + "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Shareware Release" (based on\ + "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Diablo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\WinRel" +# PROP BASE Intermediate_Dir ".\WinRel" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\WinRel" +# PROP Intermediate_Dir ".\WinRel" +# PROP Ignore_Export_Lib 0 +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /c +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D PROGRAM_VERSION=RETAIL /FAcs /Fr /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /machine:I386 /nodefaultlib /out:".\WinRel/hellfire.exe" +# SUBTRACT LINK32 /incremental:yes /debug + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\WinDebug" +# PROP BASE Intermediate_Dir ".\WinDebug" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\WinDebug" +# PROP Intermediate_Dir ".\WinDebug" +# PROP Ignore_Export_Lib 0 +# ADD BASE CPP /nologo /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c +# ADD CPP /nologo /G5 /Gr /MTd /W3 /Gm /GR /GX /Zi /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D PROGRAM_VERSION=RETAIL /D "DEBUG_MEM" /D "_MULTITEST" /FAcs /Fr /YX /FD /c +# SUBTRACT CPP /Gy +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /profile /map /debug /machine:I386 /nodefaultlib /out:".\WinDebug/Hellfire.exe" +# SUBTRACT LINK32 /force + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Diablo__" +# PROP BASE Intermediate_Dir ".\Diablo__" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\WinFinal" +# PROP Intermediate_Dir ".\WinFinal" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# SUBTRACT BASE CPP /Fr +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D PROGRAM_VERSION=RETAIL /D "_MULTITEST" /FAcs /YX /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 winspool.lib libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /machine:I386 /nodefaultlib /out:".\WinFinal/Hellfire.exe" +# SUBTRACT LINK32 /incremental:yes + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Diablo__" +# PROP BASE Intermediate_Dir ".\Diablo__" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\SFinal" +# PROP Intermediate_Dir ".\SFinal" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /YX /c +# SUBTRACT BASE CPP /Fr +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D PROGRAM_VERSION=SHAREWARE /FAcs /YX /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /machine:I386 /nodefaultlib +# SUBTRACT LINK32 /incremental:yes + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Diablo_0" +# PROP BASE Intermediate_Dir ".\Diablo_0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\SRel" +# PROP Intermediate_Dir ".\SRel" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /YX /c +# SUBTRACT BASE CPP /Fr +# ADD CPP /nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D PROGRAM_VERSION=SHAREWARE /FAcs /YX /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib +# ADD LINK32 libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib +# SUBTRACT LINK32 /incremental:yes + +!ENDIF + +# Begin Target + +# Name "Diablo - Win32 Release" +# Name "Diablo - Win32 Debug" +# Name "Diablo - Win32 FinalFinal" +# Name "Diablo - Win32 Shareware FinalFinal" +# Name "Diablo - Win32 Shareware Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\appfat.cpp +# End Source File +# Begin Source File + +SOURCE=.\automap.cpp +# End Source File +# Begin Source File + +SOURCE=.\capture.cpp +# End Source File +# Begin Source File + +SOURCE=.\CODEC.CPP +# End Source File +# Begin Source File + +SOURCE=.\CONTROL.CPP +# End Source File +# Begin Source File + +SOURCE=.\CURSOR.CPP +# End Source File +# Begin Source File + +SOURCE=.\ddraw.lib +# End Source File +# Begin Source File + +SOURCE=.\DEAD.CPP +# End Source File +# Begin Source File + +SOURCE=.\DEBUG.CPP +# End Source File +# Begin Source File + +SOURCE=.\DIABLO.CPP +# End Source File +# Begin Source File + +SOURCE=.\diablo.rc + +!IF "$(CFG)" == "Diablo - Win32 Release" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\doom.cpp +# End Source File +# Begin Source File + +SOURCE=.\DRLG_L1.CPP +# End Source File +# Begin Source File + +SOURCE=.\DRLG_L2.CPP +# End Source File +# Begin Source File + +SOURCE=.\DRLG_L3.CPP +# End Source File +# Begin Source File + +SOURCE=.\drlg_l4.cpp +# End Source File +# Begin Source File + +SOURCE=.\dsound.lib +# End Source File +# Begin Source File + +SOURCE=.\dthread.cpp +# End Source File +# Begin Source File + +SOURCE=.\dx.cpp +# End Source File +# Begin Source File + +SOURCE=.\effects.cpp +# End Source File +# Begin Source File + +SOURCE=.\encrypt.cpp +# End Source File +# Begin Source File + +SOURCE=.\ENGINE.CPP +# End Source File +# Begin Source File + +SOURCE=.\error.cpp +# End Source File +# Begin Source File + +SOURCE=.\except.cpp +# End Source File +# Begin Source File + +SOURCE=.\GameMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\GENDUNG.CPP +# End Source File +# Begin Source File + +SOURCE=.\gmenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\WinDebug\hellfrui.lib +# End Source File +# Begin Source File + +SOURCE=.\help.cpp +# End Source File +# Begin Source File + +SOURCE=.\implode.lib +# End Source File +# Begin Source File + +SOURCE=.\init.cpp +# End Source File +# Begin Source File + +SOURCE=.\Interfac.cpp +# End Source File +# Begin Source File + +SOURCE=.\inv.cpp +# End Source File +# Begin Source File + +SOURCE=.\itemdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\ITEMS.CPP +# End Source File +# Begin Source File + +SOURCE=.\LIGHTING.CPP +# End Source File +# Begin Source File + +SOURCE=.\loadsave.cpp +# End Source File +# Begin Source File + +SOURCE=.\mainmenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\minitext.cpp +# End Source File +# Begin Source File + +SOURCE=.\misdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\misdat.h +# End Source File +# Begin Source File + +SOURCE=.\MISSILES.CPP +# End Source File +# Begin Source File + +SOURCE=.\Mono.cpp +# End Source File +# Begin Source File + +SOURCE=.\MONSTDAT.CPP +# End Source File +# Begin Source File + +SOURCE=.\MONSTER.CPP +# End Source File +# Begin Source File + +SOURCE=.\movie.cpp +# End Source File +# Begin Source File + +SOURCE=.\mpqapi.cpp +# End Source File +# Begin Source File + +SOURCE=.\msg.cpp +# End Source File +# Begin Source File + +SOURCE=.\multi.cpp +# End Source File +# Begin Source File + +SOURCE=.\nthread.cpp +# End Source File +# Begin Source File + +SOURCE=.\objdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\OBJECTS.CPP +# End Source File +# Begin Source File + +SOURCE=.\packplr.cpp +# End Source File +# Begin Source File + +SOURCE=.\PALETTE.CPP +# End Source File +# Begin Source File + +SOURCE=.\path.cpp +# End Source File +# Begin Source File + +SOURCE=.\pfile.cpp +# End Source File +# Begin Source File + +SOURCE=.\PLAYER.CPP +# End Source File +# Begin Source File + +SOURCE=.\plrmsg.cpp +# End Source File +# Begin Source File + +SOURCE=.\portal.cpp +# End Source File +# Begin Source File + +SOURCE=.\Quests.cpp +# End Source File +# Begin Source File + +SOURCE=.\SCROLLRT.CPP +# End Source File +# Begin Source File + +SOURCE=.\SetMaps.cpp +# End Source File +# Begin Source File + +SOURCE=.\SHA.CPP +# End Source File +# Begin Source File + +SOURCE=.\SOUND.CPP +# End Source File +# Begin Source File + +SOURCE=.\Spelldat.cpp +# End Source File +# Begin Source File + +SOURCE=.\SPELLS.CPP +# End Source File +# Begin Source File + +SOURCE=.\stores.cpp +# End Source File +# Begin Source File + +SOURCE=.\WinDebug\storm.lib +# End Source File +# Begin Source File + +SOURCE=.\sync.cpp +# End Source File +# Begin Source File + +SOURCE=.\Textdat.cpp +# End Source File +# Begin Source File + +SOURCE=.\themes.cpp +# End Source File +# Begin Source File + +SOURCE=.\tmsg.cpp +# End Source File +# Begin Source File + +SOURCE=.\TOWN.CPP +# End Source File +# Begin Source File + +SOURCE=.\towners.cpp +# End Source File +# Begin Source File + +SOURCE=.\track.cpp +# End Source File +# Begin Source File + +SOURCE=.\TRIGS.CPP +# End Source File +# Begin Source File + +SOURCE=.\wave.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\automap.h +# End Source File +# Begin Source File + +SOURCE=.\Control.h +# End Source File +# Begin Source File + +SOURCE=.\Cursor.h +# End Source File +# Begin Source File + +SOURCE=.\d3dtypes.h +# End Source File +# Begin Source File + +SOURCE=.\Ddraw.h +# End Source File +# Begin Source File + +SOURCE=.\Dead.h +# End Source File +# Begin Source File + +SOURCE=.\Debug.h +# End Source File +# Begin Source File + +SOURCE=.\Diablo.h +# End Source File +# Begin Source File + +SOURCE=.\Diabloui.h +# End Source File +# Begin Source File + +SOURCE=.\doom.h +# End Source File +# Begin Source File + +SOURCE=.\Drlg_l1.h +# End Source File +# Begin Source File + +SOURCE=.\Drlg_l2.h +# End Source File +# Begin Source File + +SOURCE=.\Drlg_l3.h +# End Source File +# Begin Source File + +SOURCE=.\Drlg_l4.h +# End Source File +# Begin Source File + +SOURCE=.\Dsound.h +# End Source File +# Begin Source File + +SOURCE=.\Effects.h +# End Source File +# Begin Source File + +SOURCE=.\Engine.h +# End Source File +# Begin Source File + +SOURCE=.\error.h +# End Source File +# Begin Source File + +SOURCE=.\Gamemenu.h +# End Source File +# Begin Source File + +SOURCE=.\Gendung.h +# End Source File +# Begin Source File + +SOURCE=.\help.h +# End Source File +# Begin Source File + +SOURCE=.\implode.h +# End Source File +# Begin Source File + +SOURCE=.\Interfac.h +# End Source File +# Begin Source File + +SOURCE=.\Inv.h +# End Source File +# Begin Source File + +SOURCE=.\itemdat.h +# End Source File +# Begin Source File + +SOURCE=.\Items.h +# End Source File +# Begin Source File + +SOURCE=.\Lighting.h +# End Source File +# Begin Source File + +SOURCE=.\mainmenu.h +# End Source File +# Begin Source File + +SOURCE=.\MiniText.h +# End Source File +# Begin Source File + +SOURCE=.\Missiles.h +# End Source File +# Begin Source File + +SOURCE=.\Mono.h +# End Source File +# Begin Source File + +SOURCE=.\Monstdat.h +# End Source File +# Begin Source File + +SOURCE=.\Monster.h +# End Source File +# Begin Source File + +SOURCE=.\monstint.h +# End Source File +# Begin Source File + +SOURCE=.\mpqapi.h +# End Source File +# Begin Source File + +SOURCE=.\msg.h +# End Source File +# Begin Source File + +SOURCE=.\Multi.h +# End Source File +# Begin Source File + +SOURCE=.\objdat.h +# End Source File +# Begin Source File + +SOURCE=.\Objects.h +# End Source File +# Begin Source File + +SOURCE=.\packplr.h +# End Source File +# Begin Source File + +SOURCE=.\Palette.h +# End Source File +# Begin Source File + +SOURCE=.\path.h +# End Source File +# Begin Source File + +SOURCE=.\Player.h +# End Source File +# Begin Source File + +SOURCE=.\portal.h +# End Source File +# Begin Source File + +SOURCE=.\Quests.h +# End Source File +# Begin Source File + +SOURCE=.\regconst.h +# End Source File +# Begin Source File + +SOURCE=.\Sclass.h +# End Source File +# Begin Source File + +SOURCE=.\scrlasm.h +# End Source File +# Begin Source File + +SOURCE=.\Scrollrt.h +# End Source File +# Begin Source File + +SOURCE=.\Setmaps.h +# End Source File +# Begin Source File + +SOURCE=.\Sound.h +# End Source File +# Begin Source File + +SOURCE=.\spelldat.h +# End Source File +# Begin Source File + +SOURCE=.\Spells.h +# End Source File +# Begin Source File + +SOURCE=.\stores.h +# End Source File +# Begin Source File + +SOURCE=.\Storm.h +# End Source File +# Begin Source File + +SOURCE=.\textdat.h +# End Source File +# Begin Source File + +SOURCE=.\themes.h +# End Source File +# Begin Source File + +SOURCE=.\Town.h +# End Source File +# Begin Source File + +SOURCE=.\towners.h +# End Source File +# Begin Source File + +SOURCE=.\Trigs.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\icon1.ico +# End Source File +# End Group +# Begin Source File + +SOURCE=.\WinRel\Scroll.obj +# End Source File +# End Target +# End Project diff --git a/DIABLO.DSW b/DIABLO.DSW new file mode 100644 index 0000000..2062bc1 --- /dev/null +++ b/DIABLO.DSW @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Diablo"=.\Diablo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "ui"=.\UISRC\UI\ui.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/DIABLO.H b/DIABLO.H new file mode 100644 index 0000000..f7fef8e --- /dev/null +++ b/DIABLO.H @@ -0,0 +1,316 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/DIABLO.H 4 2/10/97 6:22p Dbrevik2 $ +**-----------------------------------------------------------------------*/ + + +//****************************************************************** +// SOFTWARE VERSIONING +//****************************************************************** +// version constants +#define SHAREWARE 1 +#define BETA 2 +#define RETAIL 3 +#define IS_VERSION(x) (PROGRAM_VERSION == x) + +// make sure valid PROGRAM_VERSION is defined +#ifndef PROGRAM_VERSION +#error PROGRAM_VERSION should be defined in Build.Settings.C/C++.Preprocessor +#elif IS_VERSION(SHAREWARE) +//#pragma message("*building shareware") +#elif IS_VERSION(BETA) +//#pragma message("*building beta") +#elif IS_VERSION(RETAIL) +//#pragma message("*building retail") +#else +#error PROGRAM_VERSION is invalid +#endif + + + +// collin's new RLE draw code -- must have +// reprocessed .CL2 files for this to work +#define RLE_DRAW 1 // 1 in final + + +// cheats compile flag 0 == off, 1 == on +#define CHEATS 1 // 0 in final +#ifdef NDEBUG +#undef CHEATS +#define CHEATS 0 +#endif + +// misc 0 == testing, 1 == normal +#define RELEASE 1 // 1 in final +#ifdef NDEBUG +#undef RELEASE +#define RELEASE 1 +#endif + +// 1 = allow debugging, 0 = release +#define ALLOW_WINDOWED_MODE 1 // 0 in final +#ifdef NDEBUG +#undef ALLOW_WINDOWED_MODE +#define ALLOW_WINDOWED_MODE 0 +#endif + +// 1 = show network debugging info +#define TRACEOUT 1 // 0 in final +#ifdef NDEBUG +#undef TRACEOUT +#define TRACEOUT 0 +#endif + + +// 1 = show current trace function, 0 = release +#define ALLOW_TRACE_FCN 0 // 0 in final +#ifdef NDEBUG +#undef ALLOW_TRACE_FCN +#define ALLOW_TRACE_FCN 0 +#endif + +#if ALLOW_TRACE_FCN +void trace_fcn(const char * pszFcn); +#define TRACE_FCN(x) trace_fcn(x) +#else +#define TRACE_FCN(x) NULL +#endif + + +// save file "version" +// so we don't have version number conflicts: +// - EVEN number if RETAIL/SHAREWARE version +// - ODD number if BETA version +#define SAVE_GAME_KEY 0x7058 +#if IS_VERSION(RETAIL) && ((SAVE_GAME_KEY & 1) != 0) + #error -- SAVE_GAME_KEY must be EVEN for RETAIL version +#endif +#if IS_VERSION(BETA) && ((SAVE_GAME_KEY & 1) == 0) + #error -- SAVE_GAME_KEY must be ODD for BETA version +#endif + + +// EVEN version ID = retail version +// ODD version ID = beta version +#define VERSIONID 34 +#if IS_VERSION(RETAIL) && ((VERSIONID & 1) != 0) + #error -- VERSIONID must be EVEN for RETAIL version +#endif +#if IS_VERSION(BETA) && ((VERSIONID & 1) == 0) + #error -- VERSIONID must be ODD for BETA version +#endif + + +#ifndef PROGRAM_VERSION +#error PROGRAM_VERSION not defined +#elif IS_VERSION(RETAIL) +//#define PROGRAMID 'DRTL' +#define PROGRAMID 'HRTL' +#elif IS_VERSION(SHAREWARE) +#define PROGRAMID 'DSHR' +#elif IS_VERSION(BETA) +#define PROGRAMID 'DIAB' +#else +#error -- VERSION NOT DEFINED +#endif + + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ +#define MAX_PLRS 4 + +// frame rate +#define GAME_FRAMES_PER_SECOND 20 + +// Our messages +#define WM_DIABNEXTLVL WM_USER+2 +#define WM_DIABPREVLVL WM_USER+3 +#define WM_DIABRTNLVL WM_USER+4 +#define WM_DIABSETLVL WM_USER+5 +#define WM_DIABWARPLVL WM_USER+6 +#define WM_DIABTOWNWARP WM_USER+7 +#define WM_DIABTWARPUP WM_USER+8 +#define WM_DIABRETOWN WM_USER+9 +#define WM_DIABNEWGAME WM_USER+10 +#define WM_DIABLOADGAME WM_USER+11 + + +// Screen size +#define TOTALX 640 +#define TOTALY 480 + +// Size of control panel +#define CTRLPANY 128 + +// Size of game play area +#define GAMEY 352 + +// Offscreen buffer size +#define BUFFERX 768 +#define BUFFERY 656 +#define BUFFERSIZE BUFFERX*BUFFERY + +#define BTMBUFFX 640 +#define BTMBUFFY 144 +#define BTMBUFFSIZE BTMBUFFX*BTMBUFFY +#define BTMBUFFMULTISIZE BTMBUFFX*BTMBUFFY*2 + +// Used in processing players, monsters, objects etc. +#define RUN_DONE 0 +#define RUN_AGAIN 1 + +#define MAX_LEVELS 24 +#define DIABLO_LEVEL 16 +#define SLAIN_HERO_LEVEL 9 +#define STORY_BOOK1_LEVEL 4 +#define STORY_BOOK2_LEVEL 8 +#define STORY_BOOK3_LEVEL 12 + +// JKE STORY BOOKS FOR HELLFIRE +#define SKULKEN_BOOK1_LEVEL 21 +#define SKULKEN_BOOK2_LEVEL 22 +#define SKULKEN_BOOK3_LEVEL 23 + +/*-----------------------------------------------------------------------** +** Included files +**-----------------------------------------------------------------------*/ +#define STRICT +#include +#include +#include +#include +#include +#include +#include "ddraw.h" +#include "dsound.h" +#include +#include +#include + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern HWND ghMainWnd; +extern HINSTANCE ghInst; +extern const char gszAppName[]; + +// DO NOT USE gbFontTransTbl directly -- use the macro +// to prevent sign extension problems with characters!!! +extern const BYTE gbFontTransTbl[]; +#define char2print(c) gbFontTransTbl[(BYTE) (c)]; + + +// video vars +extern LPDIRECTDRAW lpDD; +extern LPDIRECTDRAWSURFACE lpDDSPrimary; +extern LPDIRECTDRAWPALETTE lpDDPal; +extern BOOL fullscreen; +extern BOOL bActive; + +// these variables are only valid if lock_buf() has been called +extern BYTE * gpBuffer; +extern "C" long glClipY; +void lock_buf(BYTE bFcn); +void unlock_buf(BYTE bFcn); + +// program vars +extern BOOL svgamode; +extern int MouseX, MouseY; +extern int force_redraw; + + +// Temp vars (delete all uses before final compile) +extern long gv1; +extern long gv2; +extern long gv3; +extern long gv4; +extern long gv5; + + +// General flags +extern BOOL PauseMode; +extern BOOL gbProcessPlayers; +extern BOOL FriendlyMode; +#if CHEATS +extern BOOL davedebug; +extern BOOL cheatflag; +extern BOOL simplecheat; +#endif +extern BOOL visiondebug; +extern BOOL light4flag; +extern BOOL leveldebug; +extern BOOL monstdebug; +extern int debugmonsttypes; +extern int DebugMonsters[10]; + + +/*----------------------------------------------------------*/ +// HELLFIRE FLAGS +/*----------------------------------------------------------*/ + +extern bool gbTheo; +extern bool gbCowsuit; +extern bool gbOurNest; +extern bool gbAllowBard; +extern bool gbAllowBarbarian; +extern bool gbAllowMultiPlayer; +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +LRESULT CALLBACK DiabloDefProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); +void LoadGameLevel(BOOL, int); +void FreeGameMem(); +void SetupSaveBasePath(); + + +#if TRACEOUT +void __cdecl TraceOut(const char * pszFmt, ...); +#endif + + +/*-----------------------------------------------------------------------** +** Assertion System +**-----------------------------------------------------------------------*/ +#define EXTENDED_ASSERT 1 // 0 in final +#ifdef NDEBUG +#undef EXTENDED_ASSERT +#define EXTENDED_ASSERT 0 +#endif + +const TCHAR * strGetLastError(); +const TCHAR * strGetError(DWORD dwErr); + +void __cdecl app_fatal(const char * pszFmt,...); +void __cdecl app_warning(const char * pszFmt,...); + +void app_assert(int); +#if EXTENDED_ASSERT && !defined(NDEBUG) +void assert_fail(int nLineNo, const char * pszFile, const char * pszFail); +#define app_assert(x) ((x) ? NULL : assert_fail(__LINE__,__FILE__,#x)) +#elif !defined(NDEBUG) +void assert_fail(int nLineNo, const char * pszFile); +#define app_assert(x) ((x) ? NULL : assert_fail(__LINE__,__FILE__)) +#else +#define app_assert(x) (x) // in case of side effects +#endif + +void ddraw_assert(int); +void ddraw_assert_fail(HRESULT ddrval, int nLineNo, const char * pszFile); +#define ddraw_assert(x) (((x) == DD_OK) ? NULL : ddraw_assert_fail((x),__LINE__,__FILE__)) + +void dsound_assert(int); +void dsound_assert_fail(HRESULT dsrval, int nLineNo, const char * pszFile); +#define dsound_assert(x) (((x) == DS_OK) ? NULL : dsound_assert_fail((x),__LINE__,__FILE__)) + +// jcm.patch1.start.1/14/97 +#ifdef NDEBUG +#define GRACEFUL_EXIT +#endif +// jcm.patch1.end.1/14/97 diff --git a/DIABLO.MAK b/DIABLO.MAK new file mode 100644 index 0000000..fbb93fd --- /dev/null +++ b/DIABLO.MAK @@ -0,0 +1,9974 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on Diablo.dsp +!IF "$(CFG)" == "" +CFG=Diablo - Win32 Release +!MESSAGE No configuration specified. Defaulting to Diablo - Win32 Release. +!ENDIF + +!IF "$(CFG)" != "Diablo - Win32 Release" && "$(CFG)" != "Diablo - Win32 Debug"\ + && "$(CFG)" != "Diablo - Win32 FinalFinal" && "$(CFG)" !=\ + "Diablo - Win32 Shareware FinalFinal" && "$(CFG)" !=\ + "Diablo - Win32 Shareware Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Diablo.mak" CFG="Diablo - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Diablo - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 FinalFinal" (based on "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Shareware FinalFinal" (based on\ + "Win32 (x86) Application") +!MESSAGE "Diablo - Win32 Shareware Release" (based on\ + "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "Diablo - Win32 Release" + +OUTDIR=.\WinRel +INTDIR=.\WinRel +# Begin Custom Macros +OutDir=.\.\WinRel +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Diablo.exe" "$(OUTDIR)\Diablo.bsc" + +!ELSE + +ALL : "$(OUTDIR)\Diablo.exe" "$(OUTDIR)\Diablo.bsc" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\appfat.sbr" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\automap.sbr" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\capture.sbr" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CODEC.SBR" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CONTROL.SBR" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\CURSOR.SBR" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEAD.SBR" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DEBUG.SBR" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\DIABLO.SBR" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\doom.sbr" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L1.SBR" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L2.SBR" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\DRLG_L3.SBR" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\drlg_l4.sbr" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dthread.sbr" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\dx.sbr" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\effects.sbr" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\encrypt.sbr" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\ENGINE.SBR" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\error.sbr" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\except.sbr" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GameMenu.sbr" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\GENDUNG.SBR" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\gmenu.sbr" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\help.sbr" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\init.sbr" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\Interfac.sbr" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\inv.sbr" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\itemdat.sbr" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\ITEMS.SBR" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\LIGHTING.SBR" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\loadsave.sbr" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\mainmenu.sbr" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\minitext.sbr" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\misdat.sbr" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MISSILES.SBR" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTDAT.SBR" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\MONSTER.SBR" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\movie.sbr" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\mpqapi.sbr" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\msg.sbr" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\multi.sbr" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\nthread.sbr" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\objdat.sbr" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\OBJECTS.SBR" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\packplr.sbr" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\PALETTE.SBR" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\path.sbr" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\pfile.sbr" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\PLAYER.SBR" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\plrmsg.sbr" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\portal.sbr" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\Quests.sbr" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SCROLLRT.SBR" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SetMaps.sbr" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SHA.SBR" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\SOUND.SBR" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\Spelldat.sbr" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\SPELLS.SBR" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\stores.sbr" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\sync.sbr" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\Textdat.sbr" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\themes.sbr" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\tmsg.sbr" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\TOWN.SBR" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\towners.sbr" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\track.sbr" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\TRIGS.SBR" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(INTDIR)\wave.sbr" + -@erase "$(OUTDIR)\Diablo.bsc" + -@erase "$(OUTDIR)\Diablo.exe" + -@erase "$(OUTDIR)\Diablo.map" + -@erase "$(OUTDIR)\Diablo.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG"\ + /D PROGRAM_VERSION=RETAIL /FAcs /Fa"$(INTDIR)\\" /Fr"$(INTDIR)\\"\ + /Fp"$(INTDIR)\Diablo.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\WinRel/ +CPP_SBRS=.\WinRel/ + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Diablo.bsc" +BSC32_SBRS= \ + "$(INTDIR)\appfat.sbr" \ + "$(INTDIR)\automap.sbr" \ + "$(INTDIR)\capture.sbr" \ + "$(INTDIR)\CODEC.SBR" \ + "$(INTDIR)\CONTROL.SBR" \ + "$(INTDIR)\CURSOR.SBR" \ + "$(INTDIR)\DEAD.SBR" \ + "$(INTDIR)\DEBUG.SBR" \ + "$(INTDIR)\DIABLO.SBR" \ + "$(INTDIR)\doom.sbr" \ + "$(INTDIR)\DRLG_L1.SBR" \ + "$(INTDIR)\DRLG_L2.SBR" \ + "$(INTDIR)\DRLG_L3.SBR" \ + "$(INTDIR)\drlg_l4.sbr" \ + "$(INTDIR)\dthread.sbr" \ + "$(INTDIR)\dx.sbr" \ + "$(INTDIR)\effects.sbr" \ + "$(INTDIR)\encrypt.sbr" \ + "$(INTDIR)\ENGINE.SBR" \ + "$(INTDIR)\error.sbr" \ + "$(INTDIR)\except.sbr" \ + "$(INTDIR)\GameMenu.sbr" \ + "$(INTDIR)\GENDUNG.SBR" \ + "$(INTDIR)\gmenu.sbr" \ + "$(INTDIR)\help.sbr" \ + "$(INTDIR)\init.sbr" \ + "$(INTDIR)\Interfac.sbr" \ + "$(INTDIR)\inv.sbr" \ + "$(INTDIR)\itemdat.sbr" \ + "$(INTDIR)\ITEMS.SBR" \ + "$(INTDIR)\LIGHTING.SBR" \ + "$(INTDIR)\loadsave.sbr" \ + "$(INTDIR)\mainmenu.sbr" \ + "$(INTDIR)\minitext.sbr" \ + "$(INTDIR)\misdat.sbr" \ + "$(INTDIR)\MISSILES.SBR" \ + "$(INTDIR)\MONSTDAT.SBR" \ + "$(INTDIR)\MONSTER.SBR" \ + "$(INTDIR)\movie.sbr" \ + "$(INTDIR)\mpqapi.sbr" \ + "$(INTDIR)\msg.sbr" \ + "$(INTDIR)\multi.sbr" \ + "$(INTDIR)\nthread.sbr" \ + "$(INTDIR)\objdat.sbr" \ + "$(INTDIR)\OBJECTS.SBR" \ + "$(INTDIR)\packplr.sbr" \ + "$(INTDIR)\PALETTE.SBR" \ + "$(INTDIR)\path.sbr" \ + "$(INTDIR)\pfile.sbr" \ + "$(INTDIR)\PLAYER.SBR" \ + "$(INTDIR)\plrmsg.sbr" \ + "$(INTDIR)\portal.sbr" \ + "$(INTDIR)\Quests.sbr" \ + "$(INTDIR)\SCROLLRT.SBR" \ + "$(INTDIR)\SetMaps.sbr" \ + "$(INTDIR)\SHA.SBR" \ + "$(INTDIR)\SOUND.SBR" \ + "$(INTDIR)\Spelldat.sbr" \ + "$(INTDIR)\SPELLS.SBR" \ + "$(INTDIR)\stores.sbr" \ + "$(INTDIR)\sync.sbr" \ + "$(INTDIR)\Textdat.sbr" \ + "$(INTDIR)\themes.sbr" \ + "$(INTDIR)\tmsg.sbr" \ + "$(INTDIR)\TOWN.SBR" \ + "$(INTDIR)\towners.sbr" \ + "$(INTDIR)\track.sbr" \ + "$(INTDIR)\TRIGS.SBR" \ + "$(INTDIR)\wave.sbr" + +"$(OUTDIR)\Diablo.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\Diablo.pdb" /map:"$(INTDIR)\Diablo.map" /debug\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)\Diablo.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\dsound.lib" \ + ".\Hellfrui.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\Diablo.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +OUTDIR=.\WinDebug +INTDIR=.\WinDebug +# Begin Custom Macros +OutDir=.\.\WinDebug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Diablo.exe" + +!ELSE + +ALL : "$(OUTDIR)\Diablo.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\Diablo.exe" + -@erase "$(OUTDIR)\Diablo.map" + -@erase "$(OUTDIR)\Diablo.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Gm /Zi /Od /D "WIN32" /D "_WINDOWS" /D\ + "_DEBUG" /D PROGRAM_VERSION=RETAIL /FAcs /Fa"$(INTDIR)\\"\ + /Fp"$(INTDIR)\Diablo.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\WinDebug/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\diablo.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Diablo.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\Diablo.pdb" /map:"$(INTDIR)\Diablo.map" /debug\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)\Diablo.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\dsound.lib" \ + ".\Hellfrui.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\Diablo.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +OUTDIR=.\WinFinal +INTDIR=.\WinFinal +# Begin Custom Macros +OutDir=.\.\WinFinal +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Diablo.exe" + +!ELSE + +ALL : "$(OUTDIR)\Diablo.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\Diablo.exe" + -@erase "$(OUTDIR)\Diablo.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG"\ + /D PROGRAM_VERSION=RETAIL /FAcs /Fa"$(INTDIR)\\" /Fp"$(INTDIR)\Diablo.pch" /YX\ + /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\WinFinal/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Diablo.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\Diablo.pdb" /map:"$(INTDIR)\Diablo.map"\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)\Diablo.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\dsound.lib" \ + ".\Hellfrui.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\Diablo.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +OUTDIR=.\SFinal +INTDIR=.\SFinal +# Begin Custom Macros +OutDir=.\.\SFinal +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Diablo.exe" + +!ELSE + +ALL : "$(OUTDIR)\Diablo.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\Diablo.exe" + -@erase "$(OUTDIR)\Diablo.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "NDEBUG"\ + /D PROGRAM_VERSION=SHAREWARE /FAcs /Fa"$(INTDIR)\\" /Fp"$(INTDIR)\Diablo.pch"\ + /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\SFinal/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Diablo.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\Diablo.pdb" /map:"$(INTDIR)\Diablo.map"\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)\Diablo.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\dsound.lib" \ + ".\Hellfrui.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\Diablo.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +OUTDIR=.\SRel +INTDIR=.\SRel +# Begin Custom Macros +OutDir=.\.\SRel +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Diablo.exe" + +!ELSE + +ALL : "$(OUTDIR)\Diablo.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\appfat.obj" + -@erase "$(INTDIR)\automap.obj" + -@erase "$(INTDIR)\capture.obj" + -@erase "$(INTDIR)\CODEC.OBJ" + -@erase "$(INTDIR)\CONTROL.OBJ" + -@erase "$(INTDIR)\CURSOR.OBJ" + -@erase "$(INTDIR)\DEAD.OBJ" + -@erase "$(INTDIR)\DEBUG.OBJ" + -@erase "$(INTDIR)\DIABLO.OBJ" + -@erase "$(INTDIR)\diablo.res" + -@erase "$(INTDIR)\doom.obj" + -@erase "$(INTDIR)\DRLG_L1.OBJ" + -@erase "$(INTDIR)\DRLG_L2.OBJ" + -@erase "$(INTDIR)\DRLG_L3.OBJ" + -@erase "$(INTDIR)\drlg_l4.obj" + -@erase "$(INTDIR)\dthread.obj" + -@erase "$(INTDIR)\dx.obj" + -@erase "$(INTDIR)\effects.obj" + -@erase "$(INTDIR)\encrypt.obj" + -@erase "$(INTDIR)\ENGINE.OBJ" + -@erase "$(INTDIR)\error.obj" + -@erase "$(INTDIR)\except.obj" + -@erase "$(INTDIR)\GameMenu.obj" + -@erase "$(INTDIR)\GENDUNG.OBJ" + -@erase "$(INTDIR)\gmenu.obj" + -@erase "$(INTDIR)\help.obj" + -@erase "$(INTDIR)\init.obj" + -@erase "$(INTDIR)\Interfac.obj" + -@erase "$(INTDIR)\inv.obj" + -@erase "$(INTDIR)\itemdat.obj" + -@erase "$(INTDIR)\ITEMS.OBJ" + -@erase "$(INTDIR)\LIGHTING.OBJ" + -@erase "$(INTDIR)\loadsave.obj" + -@erase "$(INTDIR)\mainmenu.obj" + -@erase "$(INTDIR)\minitext.obj" + -@erase "$(INTDIR)\misdat.obj" + -@erase "$(INTDIR)\MISSILES.OBJ" + -@erase "$(INTDIR)\MONSTDAT.OBJ" + -@erase "$(INTDIR)\MONSTER.OBJ" + -@erase "$(INTDIR)\movie.obj" + -@erase "$(INTDIR)\mpqapi.obj" + -@erase "$(INTDIR)\msg.obj" + -@erase "$(INTDIR)\multi.obj" + -@erase "$(INTDIR)\nthread.obj" + -@erase "$(INTDIR)\objdat.obj" + -@erase "$(INTDIR)\OBJECTS.OBJ" + -@erase "$(INTDIR)\packplr.obj" + -@erase "$(INTDIR)\PALETTE.OBJ" + -@erase "$(INTDIR)\path.obj" + -@erase "$(INTDIR)\pfile.obj" + -@erase "$(INTDIR)\PLAYER.OBJ" + -@erase "$(INTDIR)\plrmsg.obj" + -@erase "$(INTDIR)\portal.obj" + -@erase "$(INTDIR)\Quests.obj" + -@erase "$(INTDIR)\SCROLLRT.OBJ" + -@erase "$(INTDIR)\SetMaps.obj" + -@erase "$(INTDIR)\SHA.OBJ" + -@erase "$(INTDIR)\SOUND.OBJ" + -@erase "$(INTDIR)\Spelldat.obj" + -@erase "$(INTDIR)\SPELLS.OBJ" + -@erase "$(INTDIR)\stores.obj" + -@erase "$(INTDIR)\sync.obj" + -@erase "$(INTDIR)\Textdat.obj" + -@erase "$(INTDIR)\themes.obj" + -@erase "$(INTDIR)\tmsg.obj" + -@erase "$(INTDIR)\TOWN.OBJ" + -@erase "$(INTDIR)\towners.obj" + -@erase "$(INTDIR)\track.obj" + -@erase "$(INTDIR)\TRIGS.OBJ" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(INTDIR)\wave.obj" + -@erase "$(OUTDIR)\Diablo.exe" + -@erase "$(OUTDIR)\Diablo.map" + -@erase "$(OUTDIR)\Diablo.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /G5 /Gr /MT /W3 /Zi /O1 /D "WIN32" /D "_WINDOWS" /D "_DEBUG"\ + /D PROGRAM_VERSION=SHAREWARE /FAcs /Fa"$(INTDIR)\\" /Fp"$(INTDIR)\Diablo.pch"\ + /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\SRel/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\diablo.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Diablo.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=libcmt.lib winmm.lib kernel32.lib user32.lib gdi32.lib\ + comdlg32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\Diablo.pdb" /map:"$(INTDIR)\Diablo.map" /debug\ + /machine:I386 /nodefaultlib /out:"$(OUTDIR)\Diablo.exe" +LINK32_OBJS= \ + "$(INTDIR)\appfat.obj" \ + "$(INTDIR)\automap.obj" \ + "$(INTDIR)\capture.obj" \ + "$(INTDIR)\CODEC.OBJ" \ + "$(INTDIR)\CONTROL.OBJ" \ + "$(INTDIR)\CURSOR.OBJ" \ + "$(INTDIR)\DEAD.OBJ" \ + "$(INTDIR)\DEBUG.OBJ" \ + "$(INTDIR)\DIABLO.OBJ" \ + "$(INTDIR)\diablo.res" \ + "$(INTDIR)\doom.obj" \ + "$(INTDIR)\DRLG_L1.OBJ" \ + "$(INTDIR)\DRLG_L2.OBJ" \ + "$(INTDIR)\DRLG_L3.OBJ" \ + "$(INTDIR)\drlg_l4.obj" \ + "$(INTDIR)\dthread.obj" \ + "$(INTDIR)\dx.obj" \ + "$(INTDIR)\effects.obj" \ + "$(INTDIR)\encrypt.obj" \ + "$(INTDIR)\ENGINE.OBJ" \ + "$(INTDIR)\error.obj" \ + "$(INTDIR)\except.obj" \ + "$(INTDIR)\GameMenu.obj" \ + "$(INTDIR)\GENDUNG.OBJ" \ + "$(INTDIR)\gmenu.obj" \ + "$(INTDIR)\help.obj" \ + "$(INTDIR)\init.obj" \ + "$(INTDIR)\Interfac.obj" \ + "$(INTDIR)\inv.obj" \ + "$(INTDIR)\itemdat.obj" \ + "$(INTDIR)\ITEMS.OBJ" \ + "$(INTDIR)\LIGHTING.OBJ" \ + "$(INTDIR)\loadsave.obj" \ + "$(INTDIR)\mainmenu.obj" \ + "$(INTDIR)\minitext.obj" \ + "$(INTDIR)\misdat.obj" \ + "$(INTDIR)\MISSILES.OBJ" \ + "$(INTDIR)\MONSTDAT.OBJ" \ + "$(INTDIR)\MONSTER.OBJ" \ + "$(INTDIR)\movie.obj" \ + "$(INTDIR)\mpqapi.obj" \ + "$(INTDIR)\msg.obj" \ + "$(INTDIR)\multi.obj" \ + "$(INTDIR)\nthread.obj" \ + "$(INTDIR)\objdat.obj" \ + "$(INTDIR)\OBJECTS.OBJ" \ + "$(INTDIR)\packplr.obj" \ + "$(INTDIR)\PALETTE.OBJ" \ + "$(INTDIR)\path.obj" \ + "$(INTDIR)\pfile.obj" \ + "$(INTDIR)\PLAYER.OBJ" \ + "$(INTDIR)\plrmsg.obj" \ + "$(INTDIR)\portal.obj" \ + "$(INTDIR)\Quests.obj" \ + "$(INTDIR)\scroll.obj" \ + "$(INTDIR)\SCROLLRT.OBJ" \ + "$(INTDIR)\SetMaps.obj" \ + "$(INTDIR)\SHA.OBJ" \ + "$(INTDIR)\SOUND.OBJ" \ + "$(INTDIR)\Spelldat.obj" \ + "$(INTDIR)\SPELLS.OBJ" \ + "$(INTDIR)\stores.obj" \ + "$(INTDIR)\sync.obj" \ + "$(INTDIR)\Textdat.obj" \ + "$(INTDIR)\themes.obj" \ + "$(INTDIR)\tmsg.obj" \ + "$(INTDIR)\TOWN.OBJ" \ + "$(INTDIR)\towners.obj" \ + "$(INTDIR)\track.obj" \ + "$(INTDIR)\TRIGS.OBJ" \ + "$(INTDIR)\wave.obj" \ + ".\ddraw.lib" \ + ".\dsound.lib" \ + ".\Hellfrui.lib" \ + ".\implode.lib" \ + ".\Storm.lib" + +"$(OUTDIR)\Diablo.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(CFG)" == "Diablo - Win32 Release" || "$(CFG)" == "Diablo - Win32 Debug"\ + || "$(CFG)" == "Diablo - Win32 FinalFinal" || "$(CFG)" ==\ + "Diablo - Win32 Shareware FinalFinal" || "$(CFG)" ==\ + "Diablo - Win32 Shareware Release" +SOURCE=.\appfat.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_APPFA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\appfat.obj" "$(INTDIR)\appfat.sbr" : $(SOURCE) $(DEP_CPP_APPFA)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_APPFA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_APPFA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_APPFA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_APPFA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\appfat.obj" : $(SOURCE) $(DEP_CPP_APPFA) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\automap.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_AUTOM=\ + ".\automap.h"\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + + +"$(INTDIR)\automap.obj" "$(INTDIR)\automap.sbr" : $(SOURCE) $(DEP_CPP_AUTOM)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_AUTOM=\ + ".\automap.h"\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_AUTOM=\ + ".\automap.h"\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_AUTOM=\ + ".\automap.h"\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_AUTOM=\ + ".\automap.h"\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + + +"$(INTDIR)\automap.obj" : $(SOURCE) $(DEP_CPP_AUTOM) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\capture.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_CAPTU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\capture.obj" "$(INTDIR)\capture.sbr" : $(SOURCE) $(DEP_CPP_CAPTU)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_CAPTU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_CAPTU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_CAPTU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_CAPTU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\capture.obj" : $(SOURCE) $(DEP_CPP_CAPTU) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\CODEC.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_CODEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\CODEC.OBJ" "$(INTDIR)\CODEC.SBR" : $(SOURCE) $(DEP_CPP_CODEC)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_CODEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_CODEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_CODEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_CODEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\CODEC.OBJ" : $(SOURCE) $(DEP_CPP_CODEC) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\CONTROL.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_CONTR=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CONTROL.OBJ" "$(INTDIR)\CONTROL.SBR" : $(SOURCE) $(DEP_CPP_CONTR)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_CONTR=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_CONTR=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_CONTR=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_CONTR=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CONTROL.OBJ" : $(SOURCE) $(DEP_CPP_CONTR) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\CURSOR.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_CURSO=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CURSOR.OBJ" "$(INTDIR)\CURSOR.SBR" : $(SOURCE) $(DEP_CPP_CURSO)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_CURSO=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_CURSO=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_CURSO=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_CURSO=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\CURSOR.OBJ" : $(SOURCE) $(DEP_CPP_CURSO) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\DEAD.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DEAD_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\DEAD.OBJ" "$(INTDIR)\DEAD.SBR" : $(SOURCE) $(DEP_CPP_DEAD_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DEAD_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DEAD_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DEAD_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DEAD_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\DEAD.OBJ" : $(SOURCE) $(DEP_CPP_DEAD_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\DEBUG.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DEBUG=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + + +"$(INTDIR)\DEBUG.OBJ" "$(INTDIR)\DEBUG.SBR" : $(SOURCE) $(DEP_CPP_DEBUG)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DEBUG=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DEBUG=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DEBUG=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DEBUG=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + + +"$(INTDIR)\DEBUG.OBJ" : $(SOURCE) $(DEP_CPP_DEBUG) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\DIABLO.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DIABL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\mainmenu.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\mpqapi.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DIABLO.OBJ" "$(INTDIR)\DIABLO.SBR" : $(SOURCE) $(DEP_CPP_DIABL)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DIABL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\mainmenu.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\mpqapi.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DIABL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\mainmenu.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\mpqapi.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DIABL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\mainmenu.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\mpqapi.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DIABL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\mainmenu.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\mpqapi.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DIABLO.OBJ" : $(SOURCE) $(DEP_CPP_DIABL) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\diablo.rc +DEP_RSC_DIABLO=\ + ".\icon1.ico"\ + + +"$(INTDIR)\diablo.res" : $(SOURCE) $(DEP_RSC_DIABLO) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\doom.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DOOM_=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\doom.obj" "$(INTDIR)\doom.sbr" : $(SOURCE) $(DEP_CPP_DOOM_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DOOM_=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DOOM_=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DOOM_=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DOOM_=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\doom.obj" : $(SOURCE) $(DEP_CPP_DOOM_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\DRLG_L1.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DRLG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L1.OBJ" "$(INTDIR)\DRLG_L1.SBR" : $(SOURCE) $(DEP_CPP_DRLG_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DRLG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DRLG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DRLG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DRLG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L1.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\DRLG_L2.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DRLG_L=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l2.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L2.OBJ" "$(INTDIR)\DRLG_L2.SBR" : $(SOURCE) $(DEP_CPP_DRLG_L)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DRLG_L=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l2.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DRLG_L=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l2.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DRLG_L=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l2.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DRLG_L=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l2.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L2.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\DRLG_L3.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DRLG_L3=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l3.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L3.OBJ" "$(INTDIR)\DRLG_L3.SBR" : $(SOURCE) $(DEP_CPP_DRLG_L3)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DRLG_L3=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l3.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L3) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DRLG_L3=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l3.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L3) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DRLG_L3=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l3.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L3) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DRLG_L3=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l3.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\DRLG_L3.OBJ" : $(SOURCE) $(DEP_CPP_DRLG_L3) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\drlg_l4.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DRLG_L4=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\drlg_l4.obj" "$(INTDIR)\drlg_l4.sbr" : $(SOURCE) $(DEP_CPP_DRLG_L4)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DRLG_L4=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DRLG_L4=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DRLG_L4=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DRLG_L4=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\drlg_l4.obj" : $(SOURCE) $(DEP_CPP_DRLG_L4) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\dthread.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dthread.obj" "$(INTDIR)\dthread.sbr" : $(SOURCE) $(DEP_CPP_DTHRE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dthread.obj" : $(SOURCE) $(DEP_CPP_DTHRE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\dx.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_DX_CP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dx.obj" "$(INTDIR)\dx.sbr" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_DX_CP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_DX_CP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_DX_CP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_DX_CP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\dx.obj" : $(SOURCE) $(DEP_CPP_DX_CP) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\effects.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_EFFEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\effects.obj" "$(INTDIR)\effects.sbr" : $(SOURCE) $(DEP_CPP_EFFEC)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_EFFEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_EFFEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_EFFEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_EFFEC=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\effects.obj" : $(SOURCE) $(DEP_CPP_EFFEC) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\encrypt.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_ENCRY=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\implode.h"\ + ".\mpqapi.h"\ + + +"$(INTDIR)\encrypt.obj" "$(INTDIR)\encrypt.sbr" : $(SOURCE) $(DEP_CPP_ENCRY)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_ENCRY=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\implode.h"\ + ".\mpqapi.h"\ + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_ENCRY=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\implode.h"\ + ".\mpqapi.h"\ + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_ENCRY=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\implode.h"\ + ".\mpqapi.h"\ + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_ENCRY=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\implode.h"\ + ".\mpqapi.h"\ + + +"$(INTDIR)\encrypt.obj" : $(SOURCE) $(DEP_CPP_ENCRY) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\ENGINE.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_ENGIN=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Palette.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ENGINE.OBJ" "$(INTDIR)\ENGINE.SBR" : $(SOURCE) $(DEP_CPP_ENGIN)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_ENGIN=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Palette.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_ENGIN=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Palette.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_ENGIN=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Palette.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_ENGIN=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Palette.h"\ + ".\regconst.h"\ + ".\Scrollrt.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ENGINE.OBJ" : $(SOURCE) $(DEP_CPP_ENGIN) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\error.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_ERROR=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Items.h"\ + ".\Scrollrt.h"\ + ".\stores.h"\ + + +"$(INTDIR)\error.obj" "$(INTDIR)\error.sbr" : $(SOURCE) $(DEP_CPP_ERROR)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_ERROR=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Items.h"\ + ".\Scrollrt.h"\ + ".\stores.h"\ + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_ERROR=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Items.h"\ + ".\Scrollrt.h"\ + ".\stores.h"\ + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_ERROR=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Items.h"\ + ".\Scrollrt.h"\ + ".\stores.h"\ + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_ERROR=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Items.h"\ + ".\Scrollrt.h"\ + ".\stores.h"\ + + +"$(INTDIR)\error.obj" : $(SOURCE) $(DEP_CPP_ERROR) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\except.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_EXCEP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\except.obj" "$(INTDIR)\except.sbr" : $(SOURCE) $(DEP_CPP_EXCEP)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_EXCEP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_EXCEP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_EXCEP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_EXCEP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\except.obj" : $(SOURCE) $(DEP_CPP_EXCEP) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\GameMenu.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_GAMEM=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\GameMenu.obj" "$(INTDIR)\GameMenu.sbr" : $(SOURCE) $(DEP_CPP_GAMEM)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_GAMEM=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_GAMEM=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_GAMEM=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_GAMEM=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\GameMenu.obj" : $(SOURCE) $(DEP_CPP_GAMEM) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\GENDUNG.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_GENDU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\GENDUNG.OBJ" "$(INTDIR)\GENDUNG.SBR" : $(SOURCE) $(DEP_CPP_GENDU)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_GENDU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_GENDU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_GENDU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_GENDU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\GENDUNG.OBJ" : $(SOURCE) $(DEP_CPP_GENDU) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\gmenu.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_GMENU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\gmenu.obj" "$(INTDIR)\gmenu.sbr" : $(SOURCE) $(DEP_CPP_GMENU)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_GMENU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_GMENU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_GMENU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_GMENU=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\gmenu.obj" : $(SOURCE) $(DEP_CPP_GMENU) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\help.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_HELP_=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + + +"$(INTDIR)\help.obj" "$(INTDIR)\help.sbr" : $(SOURCE) $(DEP_CPP_HELP_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_HELP_=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_HELP_=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_HELP_=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_HELP_=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Objects.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + + +"$(INTDIR)\help.obj" : $(SOURCE) $(DEP_CPP_HELP_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\init.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_INIT_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\init.obj" "$(INTDIR)\init.sbr" : $(SOURCE) $(DEP_CPP_INIT_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_INIT_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_INIT_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_INIT_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_INIT_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Lighting.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\init.obj" : $(SOURCE) $(DEP_CPP_INIT_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\Interfac.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_INTER=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Storm.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Interfac.obj" "$(INTDIR)\Interfac.sbr" : $(SOURCE) $(DEP_CPP_INTER)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_INTER=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Storm.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_INTER=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Storm.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_INTER=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Storm.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_INTER=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Storm.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Interfac.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\inv.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_INV_C=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + + +"$(INTDIR)\inv.obj" "$(INTDIR)\inv.sbr" : $(SOURCE) $(DEP_CPP_INV_C)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_INV_C=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_INV_C=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_INV_C=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_INV_C=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + + +"$(INTDIR)\inv.obj" : $(SOURCE) $(DEP_CPP_INV_C) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\itemdat.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_ITEMD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\itemdat.obj" "$(INTDIR)\itemdat.sbr" : $(SOURCE) $(DEP_CPP_ITEMD)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_ITEMD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_ITEMD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_ITEMD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_ITEMD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\itemdat.obj" : $(SOURCE) $(DEP_CPP_ITEMD) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\ITEMS.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_ITEMS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ITEMS.OBJ" "$(INTDIR)\ITEMS.SBR" : $(SOURCE) $(DEP_CPP_ITEMS)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_ITEMS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_ITEMS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_ITEMS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_ITEMS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\ITEMS.OBJ" : $(SOURCE) $(DEP_CPP_ITEMS) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\LIGHTING.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_LIGHT=\ + ".\automap.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\LIGHTING.OBJ" "$(INTDIR)\LIGHTING.SBR" : $(SOURCE) $(DEP_CPP_LIGHT)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_LIGHT=\ + ".\automap.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_LIGHT=\ + ".\automap.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_LIGHT=\ + ".\automap.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_LIGHT=\ + ".\automap.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\LIGHTING.OBJ" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\loadsave.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_LOADS=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\loadsave.obj" "$(INTDIR)\loadsave.sbr" : $(SOURCE) $(DEP_CPP_LOADS)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_LOADS=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_LOADS=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_LOADS=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_LOADS=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Interfac.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\loadsave.obj" : $(SOURCE) $(DEP_CPP_LOADS) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\mainmenu.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MAINM=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mainmenu.obj" "$(INTDIR)\mainmenu.sbr" : $(SOURCE) $(DEP_CPP_MAINM)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MAINM=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MAINM=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MAINM=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MAINM=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mainmenu.obj" : $(SOURCE) $(DEP_CPP_MAINM) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\minitext.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MINIT=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\minitext.obj" "$(INTDIR)\minitext.sbr" : $(SOURCE) $(DEP_CPP_MINIT)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MINIT=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MINIT=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MINIT=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MINIT=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\minitext.obj" : $(SOURCE) $(DEP_CPP_MINIT) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\misdat.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MISDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + + +"$(INTDIR)\misdat.obj" "$(INTDIR)\misdat.sbr" : $(SOURCE) $(DEP_CPP_MISDA)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MISDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MISDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MISDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MISDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + + +"$(INTDIR)\misdat.obj" : $(SOURCE) $(DEP_CPP_MISDA) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\MISSILES.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MISSI=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\mono.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MISSILES.OBJ" "$(INTDIR)\MISSILES.SBR" : $(SOURCE) $(DEP_CPP_MISSI)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MISSI=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\mono.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MISSI=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\mono.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MISSI=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\mono.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MISSI=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\mono.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MISSILES.OBJ" : $(SOURCE) $(DEP_CPP_MISSI) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\MONSTDAT.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MONST=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Sound.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\MONSTDAT.OBJ" "$(INTDIR)\MONSTDAT.SBR" : $(SOURCE) $(DEP_CPP_MONST)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MONST=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Sound.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MONST=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Sound.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MONST=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Sound.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MONST=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\Sound.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\MONSTDAT.OBJ" : $(SOURCE) $(DEP_CPP_MONST) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\MONSTER.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MONSTE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MONSTER.OBJ" "$(INTDIR)\MONSTER.SBR" : $(SOURCE) $(DEP_CPP_MONSTE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MONSTE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONSTE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MONSTE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONSTE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MONSTE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONSTE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MONSTE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\MONSTER.OBJ" : $(SOURCE) $(DEP_CPP_MONSTE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\movie.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MOVIE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\movie.obj" "$(INTDIR)\movie.sbr" : $(SOURCE) $(DEP_CPP_MOVIE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MOVIE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MOVIE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MOVIE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MOVIE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Palette.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\movie.obj" : $(SOURCE) $(DEP_CPP_MOVIE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\mpqapi.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MPQAP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\mpqapi.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mpqapi.obj" "$(INTDIR)\mpqapi.sbr" : $(SOURCE) $(DEP_CPP_MPQAP)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MPQAP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\mpqapi.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MPQAP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\mpqapi.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MPQAP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\mpqapi.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MPQAP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\mpqapi.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\mpqapi.obj" : $(SOURCE) $(DEP_CPP_MPQAP) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\msg.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" "$(INTDIR)\msg.sbr" : $(SOURCE) $(DEP_CPP_MSG_C)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MSG_C=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\msg.obj" : $(SOURCE) $(DEP_CPP_MSG_C) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\multi.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_MULTI=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\multi.obj" "$(INTDIR)\multi.sbr" : $(SOURCE) $(DEP_CPP_MULTI)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_MULTI=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_MULTI=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_MULTI=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_MULTI=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\multi.obj" : $(SOURCE) $(DEP_CPP_MULTI) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\nthread.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_NTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\nthread.obj" "$(INTDIR)\nthread.sbr" : $(SOURCE) $(DEP_CPP_NTHRE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_NTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_NTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_NTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_NTHRE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\nthread.obj" : $(SOURCE) $(DEP_CPP_NTHRE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\objdat.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_OBJDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + + +"$(INTDIR)\objdat.obj" "$(INTDIR)\objdat.sbr" : $(SOURCE) $(DEP_CPP_OBJDA)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_OBJDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_OBJDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_OBJDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_OBJDA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + + +"$(INTDIR)\objdat.obj" : $(SOURCE) $(DEP_CPP_OBJDA) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\OBJECTS.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_OBJEC=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + + +"$(INTDIR)\OBJECTS.OBJ" "$(INTDIR)\OBJECTS.SBR" : $(SOURCE) $(DEP_CPP_OBJEC)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_OBJEC=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_OBJEC=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_OBJEC=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_OBJEC=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\towners.h"\ + + +"$(INTDIR)\OBJECTS.OBJ" : $(SOURCE) $(DEP_CPP_OBJEC) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\packplr.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_PACKP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\packplr.obj" "$(INTDIR)\packplr.sbr" : $(SOURCE) $(DEP_CPP_PACKP)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_PACKP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_PACKP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_PACKP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_PACKP=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\packplr.obj" : $(SOURCE) $(DEP_CPP_PACKP) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\PALETTE.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_PALET=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\PALETTE.OBJ" "$(INTDIR)\PALETTE.SBR" : $(SOURCE) $(DEP_CPP_PALET)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_PALET=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_PALET=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_PALET=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_PALET=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Palette.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\PALETTE.OBJ" : $(SOURCE) $(DEP_CPP_PALET) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\path.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_PATH_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\path.h"\ + ".\Player.h"\ + + +"$(INTDIR)\path.obj" "$(INTDIR)\path.sbr" : $(SOURCE) $(DEP_CPP_PATH_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_PATH_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\path.h"\ + ".\Player.h"\ + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_PATH_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\path.h"\ + ".\Player.h"\ + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_PATH_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\path.h"\ + ".\Player.h"\ + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_PATH_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\path.h"\ + ".\Player.h"\ + + +"$(INTDIR)\path.obj" : $(SOURCE) $(DEP_CPP_PATH_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\pfile.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_PFILE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\mpqapi.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\pfile.obj" "$(INTDIR)\pfile.sbr" : $(SOURCE) $(DEP_CPP_PFILE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_PFILE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\mpqapi.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_PFILE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\mpqapi.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_PFILE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\mpqapi.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_PFILE=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Diabloui.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\mpqapi.h"\ + ".\Multi.h"\ + ".\packplr.h"\ + ".\Player.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\pfile.obj" : $(SOURCE) $(DEP_CPP_PFILE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\PLAYER.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_PLAYE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\PLAYER.OBJ" "$(INTDIR)\PLAYER.SBR" : $(SOURCE) $(DEP_CPP_PLAYE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_PLAYE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_PLAYE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_PLAYE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_PLAYE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\path.h"\ + ".\Player.h"\ + ".\portal.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + ".\stores.h"\ + ".\Storm.h"\ + ".\textdat.h"\ + ".\themes.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\PLAYER.OBJ" : $(SOURCE) $(DEP_CPP_PLAYE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\plrmsg.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_PLRMS=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + + +"$(INTDIR)\plrmsg.obj" "$(INTDIR)\plrmsg.sbr" : $(SOURCE) $(DEP_CPP_PLRMS)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_PLRMS=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_PLRMS=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_PLRMS=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_PLRMS=\ + ".\Control.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + + +"$(INTDIR)\plrmsg.obj" : $(SOURCE) $(DEP_CPP_PLRMS) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\portal.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_PORTA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\portal.h"\ + + +"$(INTDIR)\portal.obj" "$(INTDIR)\portal.sbr" : $(SOURCE) $(DEP_CPP_PORTA)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_PORTA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\portal.h"\ + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_PORTA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\portal.h"\ + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_PORTA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\portal.h"\ + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_PORTA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\portal.h"\ + + +"$(INTDIR)\portal.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\Quests.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_QUEST=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Quests.obj" "$(INTDIR)\Quests.sbr" : $(SOURCE) $(DEP_CPP_QUEST)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_QUEST=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_QUEST=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_QUEST=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_QUEST=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Drlg_l1.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Missiles.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\Setmaps.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\Quests.obj" : $(SOURCE) $(DEP_CPP_QUEST) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\Scroll.asm + +!IF "$(CFG)" == "Diablo - Win32 Release" + +IntDir=.\.\WinRel +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +IntDir=.\.\WinDebug +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +IntDir=.\.\WinFinal +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +IntDir=.\.\SFinal +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +IntDir=.\.\SRel +InputPath=.\Scroll.asm +InputName=Scroll + +"$(IntDir)\scroll.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + tasm /t /m5 /ml /w2 /zn $(InputName) $(IntDir)\scroll.obj + +!ENDIF + +SOURCE=.\SCROLLRT.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_SCROL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + ".\Town.h"\ + + +"$(INTDIR)\SCROLLRT.OBJ" "$(INTDIR)\SCROLLRT.SBR" : $(SOURCE) $(DEP_CPP_SCROL)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_SCROL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + ".\Town.h"\ + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_SCROL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + ".\Town.h"\ + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_SCROL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + ".\Town.h"\ + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_SCROL=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Dead.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Lighting.h"\ + ".\MiniText.h"\ + ".\misdat.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\Multi.h"\ + ".\Objects.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\regconst.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\Spells.h"\ + ".\Storm.h"\ + ".\Town.h"\ + + +"$(INTDIR)\SCROLLRT.OBJ" : $(SOURCE) $(DEP_CPP_SCROL) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\SetMaps.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_SETMA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\SetMaps.obj" "$(INTDIR)\SetMaps.sbr" : $(SOURCE) $(DEP_CPP_SETMA)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_SETMA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_SETMA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_SETMA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_SETMA=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Drlg_l1.h"\ + ".\Drlg_l2.h"\ + ".\Drlg_l3.h"\ + ".\Drlg_l4.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Objects.h"\ + ".\Palette.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\SetMaps.obj" : $(SOURCE) $(DEP_CPP_SETMA) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\SHA.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_SHA_C=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\SHA.OBJ" "$(INTDIR)\SHA.SBR" : $(SOURCE) $(DEP_CPP_SHA_C)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_SHA_C=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_SHA_C=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_SHA_C=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_SHA_C=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + + +"$(INTDIR)\SHA.OBJ" : $(SOURCE) $(DEP_CPP_SHA_C) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\SOUND.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_SOUND=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\SOUND.OBJ" "$(INTDIR)\SOUND.SBR" : $(SOURCE) $(DEP_CPP_SOUND)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_SOUND=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_SOUND=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_SOUND=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_SOUND=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\SOUND.OBJ" : $(SOURCE) $(DEP_CPP_SOUND) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\Spelldat.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_SPELL=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Missiles.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\Spelldat.obj" "$(INTDIR)\Spelldat.sbr" : $(SOURCE) $(DEP_CPP_SPELL)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_SPELL=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Missiles.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_SPELL=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Missiles.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_SPELL=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Missiles.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_SPELL=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Missiles.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\Spelldat.obj" : $(SOURCE) $(DEP_CPP_SPELL) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\SPELLS.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_SPELLS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\SPELLS.OBJ" "$(INTDIR)\SPELLS.SBR" : $(SOURCE) $(DEP_CPP_SPELLS)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_SPELLS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELLS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_SPELLS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELLS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_SPELLS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELLS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_SPELLS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Missiles.h"\ + ".\Monster.h"\ + ".\Player.h"\ + ".\Sound.h"\ + ".\spelldat.h"\ + ".\Spells.h"\ + + +"$(INTDIR)\SPELLS.OBJ" : $(SOURCE) $(DEP_CPP_SPELLS) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\stores.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_STORE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\spelldat.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + + +"$(INTDIR)\stores.obj" "$(INTDIR)\stores.sbr" : $(SOURCE) $(DEP_CPP_STORE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_STORE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\spelldat.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_STORE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\spelldat.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_STORE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\spelldat.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_STORE=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Scrollrt.h"\ + ".\spelldat.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\towners.h"\ + + +"$(INTDIR)\stores.obj" : $(SOURCE) $(DEP_CPP_STORE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\sync.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_SYNC_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\sync.obj" "$(INTDIR)\sync.sbr" : $(SOURCE) $(DEP_CPP_SYNC_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_SYNC_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_SYNC_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_SYNC_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_SYNC_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Debug.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\Monster.h"\ + ".\monstint.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Sound.h"\ + + +"$(INTDIR)\sync.obj" : $(SOURCE) $(DEP_CPP_SYNC_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\Textdat.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_TEXTD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\MiniText.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\Textdat.obj" "$(INTDIR)\Textdat.sbr" : $(SOURCE) $(DEP_CPP_TEXTD)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_TEXTD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\MiniText.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_TEXTD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\MiniText.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_TEXTD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\MiniText.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_TEXTD=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\MiniText.h"\ + ".\textdat.h"\ + + +"$(INTDIR)\Textdat.obj" : $(SOURCE) $(DEP_CPP_TEXTD) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\themes.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_THEME=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\themes.obj" "$(INTDIR)\themes.sbr" : $(SOURCE) $(DEP_CPP_THEME)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_THEME=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_THEME=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_THEME=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_THEME=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\Monstdat.h"\ + ".\Monster.h"\ + ".\objdat.h"\ + ".\Objects.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\themes.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\themes.obj" : $(SOURCE) $(DEP_CPP_THEME) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\tmsg.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_TMSG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\tmsg.obj" "$(INTDIR)\tmsg.sbr" : $(SOURCE) $(DEP_CPP_TMSG_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_TMSG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_TMSG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_TMSG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_TMSG_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + + +"$(INTDIR)\tmsg.obj" : $(SOURCE) $(DEP_CPP_TMSG_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\TOWN.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_TOWN_=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TOWN.OBJ" "$(INTDIR)\TOWN.SBR" : $(SOURCE) $(DEP_CPP_TOWN_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_TOWN_=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_TOWN_=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_TOWN_=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_TOWN_=\ + ".\automap.h"\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\doom.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\error.h"\ + ".\Gamemenu.h"\ + ".\Gendung.h"\ + ".\help.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\Multi.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\scrlasm.h"\ + ".\Scrollrt.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\Town.h"\ + ".\towners.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TOWN.OBJ" : $(SOURCE) $(DEP_CPP_TOWN_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\towners.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_TOWNE=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\towners.obj" "$(INTDIR)\towners.sbr" : $(SOURCE) $(DEP_CPP_TOWNE)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_TOWNE=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_TOWNE=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_TOWNE=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_TOWNE=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\Engine.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\itemdat.h"\ + ".\Items.h"\ + ".\MiniText.h"\ + ".\Monster.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Sound.h"\ + ".\stores.h"\ + ".\textdat.h"\ + ".\Town.h"\ + ".\towners.h"\ + + +"$(INTDIR)\towners.obj" : $(SOURCE) $(DEP_CPP_TOWNE) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\track.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_TRACK=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\track.obj" "$(INTDIR)\track.sbr" : $(SOURCE) $(DEP_CPP_TRACK)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_TRACK=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_TRACK=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_TRACK=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_TRACK=\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Gendung.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Player.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\track.obj" : $(SOURCE) $(DEP_CPP_TRACK) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\TRIGS.CPP + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_TRIGS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TRIGS.OBJ" "$(INTDIR)\TRIGS.SBR" : $(SOURCE) $(DEP_CPP_TRIGS)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_TRIGS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_TRIGS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_TRIGS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_TRIGS=\ + ".\Control.h"\ + ".\Cursor.h"\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Effects.h"\ + ".\error.h"\ + ".\Gendung.h"\ + ".\Inv.h"\ + ".\Items.h"\ + ".\msg.h"\ + ".\Multi.h"\ + ".\Palette.h"\ + ".\Player.h"\ + ".\Quests.h"\ + ".\Setmaps.h"\ + ".\Trigs.h"\ + + +"$(INTDIR)\TRIGS.OBJ" : $(SOURCE) $(DEP_CPP_TRIGS) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\wave.cpp + +!IF "$(CFG)" == "Diablo - Win32 Release" + +DEP_CPP_WAVE_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\wave.obj" "$(INTDIR)\wave.sbr" : $(SOURCE) $(DEP_CPP_WAVE_)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" + +DEP_CPP_WAVE_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 FinalFinal" + +DEP_CPP_WAVE_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware FinalFinal" + +DEP_CPP_WAVE_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Diablo - Win32 Shareware Release" + +DEP_CPP_WAVE_=\ + ".\d3dtypes.h"\ + ".\Ddraw.h"\ + ".\Diablo.h"\ + ".\Dsound.h"\ + ".\Engine.h"\ + ".\Sound.h"\ + ".\Storm.h"\ + + +"$(INTDIR)\wave.obj" : $(SOURCE) $(DEP_CPP_WAVE_) "$(INTDIR)" + + +!ENDIF + + +!ENDIF + diff --git a/DIABLO.MDP b/DIABLO.MDP new file mode 100644 index 0000000..3750354 Binary files /dev/null and b/DIABLO.MDP differ diff --git a/DIABLO.OPT b/DIABLO.OPT new file mode 100644 index 0000000..fa6a7ac Binary files /dev/null and b/DIABLO.OPT differ diff --git a/DIABLO.PLG b/DIABLO.PLG new file mode 100644 index 0000000..e69de29 diff --git a/DIABLO.RC b/DIABLO.RC new file mode 100644 index 0000000..c1b53e0 --- /dev/null +++ b/DIABLO.RC @@ -0,0 +1,325 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "icon1.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 97,5,23,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Synergistic Software\0" + VALUE "FileDescription", "Hellfire\0" + VALUE "FileVersion", "1, 0, 1, 0\0" + VALUE "InternalName", "Hellfire\0" + VALUE "LegalCopyright", "Copyright © 1997\0" + VALUE "OriginalFilename", "hellfire.exe\0" + VALUE "ProductName", "Synergistic Software Hellfire\0" + VALUE "ProductVersion", "98, 1, 13, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DDRAW_ERR DIALOG DISCARDABLE 0, 0, 250, 241 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Draw Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,193,220,50,14 + LTEXT "Hellfire was unable to properly initialize your video card using DirectX. Please try the following solutions to correct the problem:", + IDC_STATIC,7,7,236,18 + LTEXT "Use the Diablo setup program ""SETUP.EXE"" provided on the Diablo CD-ROM to install DirectX 3.0.", + IDC_STATIC,19,26,210,18 + LTEXT "Install the most recent DirectX video drivers provided by the manufacturer of your video card. A list of video card manufactuers can be found at: http://www.sierracom", + IDC_STATIC,19,48,210,27 + LTEXT "The error encountered while trying to initialize the video card was:", + IDC_STATIC,7,175,236,9 + LTEXT "unknown error",IDC_ERROR_TAG,19,186,210,27 + LTEXT "If you continue to have problems, we have also included Microsoft DirectX 2.0 drivers on the Diablo CD-ROM. This older version of DirectX may work in cases where DirectX 3.0 does not.", + IDC_STATIC,7,79,236,27 + LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", + IDC_STATIC,19,137,210,27 + LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", + IDC_STATIC,7,116,236,18 +END + +IDD_MEM_ERR DIALOG DISCARDABLE 0, 0, 250, 213 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Out of Memory Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,193,192,50,14 + LTEXT "Hellfire has exhausted all the memory on your system. This problem can likely be corrected by changing the virtual memory settings for Windows. Ensure that your system has at least 10 megabytes of free disk space, then check your virtual memory settings:", + IDC_STATIC,7,7,236,36 + LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""System"" control panel applet\nSelect the ""Performance"" tab, and press ""Virtual Memory""\nUse the ""Let Windows manage my virtual memory..."" option", + IDC_STATIC,23,54,197,36 + LTEXT "The error encountered was:",IDC_STATIC,7,146,236,11 + LTEXT "unknown location",IDC_ERROR_TAG,20,157,210,27 + LTEXT "For Windows 95:",IDC_STATIC,7,45,236,9 + LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""System"" control panel applet\nSelect the ""Performance"" tab\nPress ""Change"" in ""Virtual Memory"" settings\nEnsure that the virtual memory file is at least 32 megabytes", + IDC_STATIC,17,98,197,45 + LTEXT "For Windows NT:",IDC_STATIC,7,89,236,9 +END + +IDD_FILE_ERR DIALOG DISCARDABLE 0, 0, 265, 114 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Data File Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,208,93,50,14 + LTEXT "Hellfire was unable to open a required file. Please ensure that the Diablo disc is in the CDROM drive. If this problem persists, try uninstalling and reinstalling Hellfire using the program ""SETUP.EXE"" on the Hellfire CD-ROM.", + -1,7,7,251,36 + LTEXT "The problem occurred while trying to load a file",-1,7, + 48,232,9 + LTEXT "unknown file",IDC_ERROR_TAG,20,59,210,27 +END + +IDD_DDRAW_DLL_ERR DIALOG DISCARDABLE 0, 0, 250, 161 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Draw Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,193,140,50,14 + LTEXT "Hellfire was unable to find the file ""ddraw.dll"", which is a component of Microsoft DirectX. Please run the program ""SETUP.EXE"" on the Diablo CD-ROM and install Microsoft DirectX.", + -1,7,7,236,27 + LTEXT "The error encountered while trying to initialize DirectX was:", + -1,7,95,236,9 + LTEXT "unknown error",IDC_ERROR_TAG,19,106,210,29 + LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", + -1,19,60,210,27 + LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", + -1,7,39,236,18 +END + +IDD_DSOUND_DLL_ERR DIALOG DISCARDABLE 0, 0, 250, 161 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Sound Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,193,140,50,14 + LTEXT "Hellfire was unable to find the file ""dsound.dll"", which is a component of Microsoft DirectX. Please run the program ""SETUP.EXE"" on the Diablo CD-ROM and install Microsoft DirectX.", + -1,7,7,236,27 + LTEXT "The error encountered while trying to initialize DirectX was:", + -1,7,95,236,9 + LTEXT "unknown error",IDC_ERROR_TAG,19,106,210,27 + LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", + -1,19,60,210,27 + LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", + -1,7,39,236,18 +END + +IDD_DISKFREE_ERR DIALOG DISCARDABLE 0, 0, 250, 100 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Out of Disk Space" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,193,79,50,14 + LTEXT "Hellfire requires at least 10 megabytes of free disk space to run properly. The disk:", + -1,7,7,236,18 + LTEXT "",-1,7,43,232,9 + LTEXT "unknown drive",IDC_ERROR_TAG,7,33,210,9 + LTEXT "has less than 10 megabytes of free space left. Please free some space on your drive and run Hellfire again.", + -1,7,52,236,18 +END + +IDD_DDRAW_PAL_ERR DIALOG DISCARDABLE 0, 0, 250, 161 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Direct Draw Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,193,140,50,14 + LTEXT "Hellfire was unable to switch video modes. This is a common problem for computers with more than one video card. To correct this problem, please set your video resolution to 640 x 480 and try running Hellfire again.", + IDC_STATIC,7,7,236,27 + LTEXT "The error encountered while trying to switch video modes was:", + IDC_STATIC,7,95,236,9 + LTEXT "unknown error",IDC_ERROR_TAG,19,106,210,27 + LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""Display"" control panel applet\nSelect the ""Settings"" tab\nSet the ""Desktop Area"" to ""640 x 480 pixels""", + IDC_STATIC,23,50,197,36 + LTEXT "For Windows 95 and Windows NT",IDC_STATIC,7,41,236,9 +END + +IDD_CDROM_ERR DIALOG DISCARDABLE 0, 0, 250, 92 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Data File Error" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,136,71,50,14 + LTEXT "Hellfire cannot read a required data file. Your Diablo CD may not be in the CDROM drive. Please ensure that the Diablo disc is in the CDROM drive and press OK. To leave the program, press Exit.", + -1,7,7,236,27 + LTEXT "unknown file",IDC_ERROR_TAG,20,37,210,27 + PUSHBUTTON "Exit",IDCANCEL,193,71,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DDRAW_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 234 + END + + IDD_MEM_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 206 + END + + IDD_FILE_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 258 + TOPMARGIN, 7 + BOTTOMMARGIN, 107 + END + + IDD_DDRAW_DLL_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 154 + END + + IDD_DSOUND_DLL_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 154 + END + + IDD_DISKFREE_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 93 + END + + IDD_DDRAW_PAL_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 154 + END + + IDD_CDROM_ERR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 85 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/DIABLO.SAV b/DIABLO.SAV new file mode 100644 index 0000000..d113ab5 --- /dev/null +++ b/DIABLO.SAV @@ -0,0 +1,3097 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Main file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DIABLO.CPP 16 3/29/97 9:09p Pwyatt $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm.h" +#include "sound.h" +#include "mainmenu.h" +#include "interfac.h" +#include "inv.h" +#include "msg.h" +#include "multi.h" +#include "engine.h" +#include "palette.h" +#include "scrollrt.h" +#include "gendung.h" +#include "setmaps.h" +#include "debug.h" +#include "effects.h" + +#include "dead.h" +#include "lighting.h" +#include "control.h" +#include "gamemenu.h" + +#include "items.h" +#include "player.h" +#include "monster.h" +#include "objects.h" +#include "missiles.h" +#include "trigs.h" +#include "spelldat.h" +#include "spells.h" +#include "cursor.h" + +#include "town.h" +#include "towners.h" +#include "drlg_l1.h" +#include "drlg_l2.h" +#include "drlg_l3.h" +#include "drlg_l4.h" +#include "quests.h" +#include "minitext.h" +#include "themes.h" +#include "stores.h" +#include "packplr.h" +#include "portal.h" +#include "doom.h" + +#include "automap.h" +#include "help.h" +#include "error.h" +#include "diabloui.h" +#include "textdat.h" +// pjw.patch1.start +#include "mpqapi.h" +#include +// pjw.patch1.end +#include "mono.h" + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszTblSig[TBL_LEN] = "REGISTRATION_TABLE"; + + +/*-----------------------------------------------------------------------** +** Global Variables +**-----------------------------------------------------------------------*/ +extern char gszProgKey[]; +BYTE gbDoEnding; +void DoEnding(); + +int StripPlayer(int pnum); + +DWORD glSeedTbl[NUMLEVELS]; +int gnLevelTypeTbl[NUMLEVELS]; + +// window vars +HWND ghMainWnd; +HINSTANCE ghInst; + +// video vars +BOOL fullscreen = TRUE; + + +// mouse +int MouseX, MouseY; + +// program vars +int force_redraw = NODRAW; + +BOOL svgamode; + +// Temp vars (delete all uses before final compile) +long gv1; +long gv2; +long gv3; +long gv4; +long gv5; + +#ifndef NDEBUG +// do not change this flag -- USE 'n' on the command line +static BOOL cineflag = TRUE; +#endif + +#if CHEATS +BOOL gbDumpDropLog = FALSE; +BOOL davedebug = FALSE; +BOOL cheatflag = FALSE; // Turn invincibility and all spells on/off +BOOL simplecheat = FALSE; // like cheatflag, but doesn't screw up game +BOOL gbNoDropInactive = FALSE; // don't drop players on timeout +int tstQMsgSpd; +int tstQMsgIndex = 0; +BOOL tstQMsgFlag = FALSE; +BOOL tstQMsgIndexFlag = FALSE; +BOOL itemcheat = FALSE; +BOOL uniqcheat = FALSE; +#endif + +BOOL visiondebug = FALSE; // Vision debugging +BOOL scrollflag = FALSE; // Scroll when at edge of screen with mouse +BOOL light4flag = FALSE; // 4 levels of light instead of 16 +BOOL leveldebug = FALSE; +BOOL monstdebug = FALSE; +BOOL trigdebug = FALSE; +int setseed = 0; + +int debugmonsttypes = 0; +int DebugMonsters[10]; + +BOOL PauseMode = FALSE; +BOOL FriendlyMode = TRUE; + +BOOL gbRunGame; +BOOL gbRunGameResult; +BOOL gbProcessPlayers; +BOOL gbGameLoopStartup; + +bool gbTheo = false; +bool gbCowsuit = false; +bool gbOurNest = false; +bool gbAllowBard = false; +bool gbAllowMultiPlayer = false; + +//int glEndSeed[17]; // @@@ drb temp +//int glMid1Seed[17]; +//int glMid2Seed[17]; +//int glMid3Seed[17]; + +int glEndSeed[NUMLEVELS+1]; // @@@ drb temp +int glMid1Seed[NUMLEVELS+1]; +int glMid2Seed[NUMLEVELS+1]; +int glMid3Seed[NUMLEVELS+1]; //JKE 7/30 adds new levels + +/*-----------------------------------------------------------------------** +** timeout cursor +**-----------------------------------------------------------------------*/ +#define TIMEOUT_CURSOR WATCH_CURS +static int sgnTimeoutCurs = NO_CURSOR; + +#define LMOUSE_DOWN 1 +#define RMOUSE_DOWN 2 +// drb.patch1.start.1/24/97 +// static BYTE sgbMouseDown = 0; +BYTE sgbMouseDown = 0; +// drb.patch1.end.1/24/97 + + +/*-----------------------------------------------------------------------** +** Function stubs +**-----------------------------------------------------------------------*/ +// pjw.patch1.start +// static void try_game_loop(BOOL bStartup); +static void alloc_plr(); +static void DoTimedEvents(); +static void game_loop(BOOL bStartup); +static void plr_encrypt(BOOL bEncrypt); +void InitializeHashSource(); +void Decrypt(LPDWORD data, DWORD bytes, DWORD key); +void Encrypt(LPDWORD data, DWORD bytes, DWORD key); +// pjw.patch1.end + + +void BlackPalette(); +void enable_frame_counter(); +void init_window(int nCmdShow); +void play_movie(const char * pszMovie,BOOL bAllowCancel); +void play_quotes(); +void play_quit(); +void FreeCursor(); +void InitDebugGFX(); +void FreeDebugGFX(); +void ShowProgress(UINT uMsg); +static LRESULT CALLBACK GM_Game(HWND, UINT, WPARAM, LPARAM); +void TrackInit(BOOL bMouseDown); +void TrackMouse(); +void run_delta_info(); +void toggle_frame_counter(); +WNDPROC my_SetWindowProc(WNDPROC wndProc); +void plrmsg_update(); +void screen_capture(); +void SavePaletteSettings(); +void menu_music(); +void NetStartTimeout(); +void menusnd_init(); +void InitLevels(); +void SyncInitPlrPos(int pnum); + +void OpenCloseAllDoors(); +void OpenNaKrul(); + +//****************************************************************** +//****************************************************************** +void FlushMsgs() { + // turn tracking off + TrackInit(FALSE); + sgbMouseDown = FALSE; + ReleaseCapture(); + + // keep flushing messages until all key and mouse msgs are gone + BOOL bLoop = TRUE; + while (bLoop) { + bLoop = FALSE; + MSG msg; + while (PeekMessage(&msg,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE)) + bLoop = TRUE; + while (PeekMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE)) + bLoop = TRUE; + } +} + +//****************************************************************** +//****************************************************************** +static void CommandLine(const char * s) { + int val; + (val); + + while (*s) { + + // skip over any space characters + while (isspace(*s)) + s++; + + // check for direct draw emulation mode +// pjw.patch1.start.1/13/97 + static const char sszEmulate[] = "dd_emulate"; + if (! _strnicmp(sszEmulate,s,strlen(sszEmulate))) { + extern BYTE gbUseDDEmulation; + gbUseDDEmulation = TRUE; + s += strlen(sszEmulate); + continue; + } + + // check for direct draw offscreen buffer + static const char sszBackBuf[] = "dd_backbuf"; + if (! _strnicmp(sszBackBuf,s,strlen(sszBackBuf))) { + extern BYTE gbForceBackBuf; + gbForceBackBuf = TRUE; + s += strlen(sszBackBuf); + continue; + } + + static const char sszDupSound[] = "ds_noduplicates"; + if (! _strnicmp(sszDupSound,s,strlen(sszDupSound))) { + extern BYTE gbDupSounds; + gbDupSounds = FALSE; + s += strlen(sszDupSound); + continue; + } + + char const sszTheoFlag[] = "Theoquest"; + if (! _strnicmp(sszTheoFlag, s, strlen(sszTheoFlag))) { + gbTheo = true; + s += strlen(sszTheoFlag); + continue; + } + + char const sszCowQuestFlag[] = "Cowquest"; + if (!_strnicmp(sszCowQuestFlag, s, strlen(sszCowQuestFlag))) { + gbCowsuit = true; + s += strlen(sszCowQuestFlag); + continue; + } + + char const sszOurNestFlag[] = "NestArt"; + if (!_strnicmp(sszOurNestFlag, s, strlen(sszOurNestFlag))) { + gbOurNest = true; + s += strlen(sszOurNestFlag); + continue; + } + + char const sszAllowBardFlag[] = "Bardtest"; + if (!_strnicmp(sszAllowBardFlag, s, strlen(sszAllowBardFlag))) { + gbAllowBard = true; + s += strlen(sszAllowBardFlag); + continue; + } + + char const sszAllowMultiPlayerFlag[] = "Multitest"; + if (!_strnicmp(sszAllowMultiPlayerFlag, s, strlen(sszAllowMultiPlayerFlag))) { + gbAllowMultiPlayer = true; + s += strlen(sszAllowMultiPlayerFlag); + continue; + } + +// pjw.patch1.end.1/13/97 + + // extract next character -- do not do ++ inside macro + // some versions of C may have nasty side effects... + char c = tolower(*s); s++; + switch (c) { + #if CHEATS + case 'b': + gbDumpDropLog = TRUE; + break; + #endif + + #if CHEATS + case 'i': + gbNoDropInactive = TRUE; + break; + #endif + + #if CHEATS + // this cheat flag is for testing without having your + // character die every two seconds -- doesn't have + // all the nasty side effects of the cheat flag + case '$': + simplecheat = TRUE; + break; + #endif + + #if CHEATS + // this cheat flag is the do-everything cheat for programmers + // it has all sorts of nasty side effects which may hide bugs + case '^': + cheatflag = TRUE; + break; + #endif + + #if CHEATS + case 'd': + davedebug = TRUE; + cineflag = FALSE; + break; + #endif + + #if CHEATS + case 'w': + davecheat = TRUE; + break; + #endif + + #if CHEATS && !IS_VERSION(SHAREWARE) + case 'l': + leveldebug = TRUE; + setlevel = FALSE; + + // get level type + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + leveltype = val; + + // get level num + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + currlevel = val; + plr[0].plrlevel = val; + break; + #endif + + #if CHEATS + case 'm': + monstdebug = TRUE; + + // get monster number + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + DebugMonsters[debugmonsttypes++] = val; + break; + #endif + + #if CHEATS + case 'q': + // get quest number + while(isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + extern int questcheat; + questcheat = val; + break; + #endif + + #if CHEATS + case 'r': + while(isspace(*s)) + s++; + val = 0; + while(isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + setseed = val; + break; + #endif + + #if CHEATS + case 's': + scrollflag = TRUE; + break; + #endif + + #if CHEATS && !IS_VERSION(SHAREWARE) + case 't': + leveldebug = TRUE; + setlevel = TRUE; + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + setlvlnum = val; + break; + #endif + + #if CHEATS + case 'j': + while (isspace(*s)) + s++; + val = 0; + while (isdigit(*s)) { + val *= 10; + val += *s - '0'; + s++; + } + trigdebug = val; + break; + #endif + + #if CHEATS + case 'v': + visiondebug = TRUE; + break; + #endif + + #ifndef NDEBUG + case 'f': + toggle_frame_counter(); + break; + #endif + + #ifndef NDEBUG + case 'x': + fullscreen = FALSE; + break; + #endif + + #ifndef NDEBUG + case 'n': + cineflag = FALSE; + break; + #endif + + #if CHEATS + case '7': + itemcheat = TRUE; + break; + + case '8': + uniqcheat = TRUE; + break; + #endif + } + + } +} + + +//****************************************************************** +//****************************************************************** +void FreeGameMem() { + music_stop(); + + DiabloFreePtr(pDungeonCels); + DiabloFreePtr(pMegaTiles); + DiabloFreePtr(pMiniTiles); + DiabloFreePtr(pSpecialCels); + DiabloFreePtr(pSpeedCels); + FreeMissileGFX(); + + FreeMonsterGFX(); + FreeObjectGFX(); + FreeMonsterSnd(); + FreeTownerGFX(); +} + + +//****************************************************************** +// stuff done every time a game is started/ended +//****************************************************************** +static void start_game(UINT uMsg) { + gbDoEnding = FALSE; + svgamode = TRUE; + InitCursor(); + InitLightTable(); + InitDebugGFX(); + app_assert(ghMainWnd); + music_stop(); + ShowProgress(uMsg); + gmenu_init(); + InitLevelCursor(); + sgnTimeoutCurs = NO_CURSOR; + sgbMouseDown = 0; + TrackInit(FALSE); +} +static void free_game() { + FreeControlPan(); + FreeInvGFX(); + gmenu_free(); + FreeQuestText(); + FreeStoreMem(); + for (int i = 0; i < MAX_PLRS; i++) + FreePlayerGFX(i); + FreeItemGFX(); + + FreeCursor(); + FreeLightTable(); + FreeDebugGFX(); + FreeGameMem(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void run_game_loop(UINT uMsg) { + nthread_perform_keepalive(TRUE); + start_game(uMsg); + app_assert(ghMainWnd); + WNDPROC saveProc = my_SetWindowProc(GM_Game); + CalcInitBallPer(); + // pjw.patch2.start + // nthread_perform_keepalive(FALSE); + // pjw.patch2.end + run_delta_info(); + + gbRunGame = TRUE; + gbProcessPlayers = TRUE; + gbRunGameResult = TRUE; + force_redraw = FULLDRAW; + DrawAndBlit(); + PaletteFadeIn(FADE_FAST); + force_redraw = FULLDRAW; + gbGameLoopStartup = TRUE; + + // pjw.patch2.start + nthread_perform_keepalive(FALSE); + // pjw.patch2.end + + +// pjw.patch1.start + MSG msg; + plr_encrypt(TRUE); + while (gbRunGame) { + DoTimedEvents(); // palette cycling + + // pjw.patch2.start + // if there are any messages in the queue, process them all + if (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { + // bump thread priority to make sure that + // during peekmessage loop we are less likely + // to yield to another process + SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL); + plr_encrypt(FALSE); + while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if (msg.message == WM_QUIT) { + gbRunGame = gbRunGameResult = FALSE; + break; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + BOOL bRun = gbRunGame && nthread_run_gameloop(FALSE); + if (! bRun) plr_encrypt(TRUE); + SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL); + if (! bRun) continue; + } + else if (! nthread_run_gameloop(FALSE)) { + // not enough time has elapsed since last gameloop + continue; + } + // pjw.patch2.end + + // actual game logic + plr_encrypt(FALSE); + NetReceivePackets(); + game_loop(gbGameLoopStartup); + gbGameLoopStartup = FALSE; + DrawAndBlit(); + plr_encrypt(TRUE); + } + plr_encrypt(FALSE); +// pjw.patch1.end + + // save character in multiplayer mode + if (gbMaxPlayers > 1) { + void UpdatePlayerFile(); + UpdatePlayerFile(); + } + void ReleasePlayerFile(); + ReleasePlayerFile(); + + PaletteFadeOut(FADE_FAST); + SetCursor(NO_CURSOR); + ClrDraw(); + force_redraw = FULLDRAW; + FullBlit(TRUE); + + // restore old window procedure + saveProc = my_SetWindowProc(saveProc); + app_assert(saveProc == GM_Game); + + free_game(); + + if (gbDoEnding) { + gbDoEnding = FALSE; + DoEnding(); + } +} + + +/*-----------------------------------------------------------------------** +// return FALSE to quit game +// return TRUE to continue game +**-----------------------------------------------------------------------*/ +BOOL StartGame(BOOL bNewGame, BOOL bSinglePlayer) { + + extern BYTE gbSelectProvider; + gbSelectProvider = TRUE; + + while (1) { + + // initialize network + BOOL fExitProgram = FALSE; + if (! NetInit(bSinglePlayer,&fExitProgram)) { + gbRunGameResult = !fExitProgram; + break; + } + + gbSelectProvider = FALSE; + + UINT uMsg; + if (bNewGame || !gbValidSaveFile) { + + InitLevels(); + InitQuests(); + InitPortals(); + InitDungMsgs(myplr); + if (!gbValidSaveFile && gbSaveFileExists) + { + // clear the items from the character's inventory + StripPlayer(myplr); + } + uMsg = WM_DIABNEWGAME; + } + else { + uMsg = WM_DIABLOADGAME; + } + + run_game_loop(uMsg); + NetClose(); + + // in single player mode, exit this loop + if (gbMaxPlayers == 1) break; + + // in multiplayer mode, only break out of the + // loop if the player wants to exit the game, otherwise + // the loop will be exited based on results from NetInit() + if (! gbRunGameResult) break; + } + + TRACE_FCN("SNetDestroy"); + SNetDestroy(); + TRACE_FCN(NULL); + + return gbRunGameResult; +} + + +//****************************************************************** +//****************************************************************** +static void InitOnce() { + MouseX = TOTALX >> 1; + MouseY = TOTALY >> 1; + + ScrollInfo._sdx = 0; + ScrollInfo._sdy = 0; + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = SCRL_NONE; + for (int i = 0; i < 1024; i++) + nBuffWTbl[i] = i * BUFFERX; + + // Init engine vars + ClrDiabloMsg(); +} + + +//****************************************************************** +//****************************************************************** +/* pjw.patch2.start +static const char sgszErrFile[] = "c:\\helfire_.err"; +static void write_exception(struct _EXCEPTION_POINTERS *pep) { + FILE * f = fopen(sgszErrFile,"wb"); + if (! f) return; + + PEXCEPTION_RECORD per = pep->ExceptionRecord; + while (per) { + fprintf( + f, + "exception: 0x%08x\r\ncode address: 0x%08x\r\n", + per->ExceptionCode, + per->ExceptionAddress + ); + + if (per->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { + if (per->ExceptionInformation[0]) + fprintf(f,"write access violation at 0x%08x\r\n",per->ExceptionInformation[1]); + else + fprintf(f,"read access violation at 0x%08x\r\n",per->ExceptionInformation[1]); + } + + per = per->ExceptionRecord; + } + + fclose(f); +} +pjw.patch2.end */ + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start +void cleanup(BOOL bNormalExit); +static LPTOP_LEVEL_EXCEPTION_FILTER sg_previousFilter; +static LONG WINAPI DiabloUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pep) { + void free_directx(); + free_directx(); + cleanup(FALSE); + // write_exception(pep); + if (sg_previousFilter) return sg_previousFilter(pep); + return EXCEPTION_CONTINUE_SEARCH; +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +BOOL grab_event() { + // NOTE: this event never gets cleaned up by our code + // we rely upon windows to clean up this event so that it + // occurs as late as possible in the program exit. This is + // a really nasty hack to make sure that SMACKER doesn't + // initialize improperly + SetLastError(0); + HANDLE hExtraEvent = CreateEvent(NULL,FALSE,FALSE,"DiabloEvent"); + HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,"HellfireEvent"); + return ERROR_ALREADY_EXISTS != GetLastError(); +} + + +//****************************************************************** +//****************************************************************** +static BOOL ActivatePreviousInstance(const char * pszAppClass) { + // find main application window + HWND hWnd; + HWND hWndTop; + HWND hWndPopup; + + // get parent window + if (NULL == (hWnd = FindWindow(pszAppClass,NULL))) + return FALSE; + + // get popup window (if any) + if (NULL != (hWndPopup = GetLastActivePopup(hWnd))) + hWnd = hWndPopup; + + // get topmost control window of topmost window + hWndTop = GetTopWindow(hWnd); + if (! hWndTop) hWndTop = hWnd; + + // bring to the front + SetForegroundWindow(hWnd); + SetFocus(hWndTop); + + return TRUE; +} + + +typedef struct _SHAREDDATA { + LONG status; + DWORD processid; +} SHAREDDATA, *SHAREDDATAPTR; + + +//=========================================================================== +// pjw.patch2.start +#ifdef NDEBUG +static void inline ReloadSelf (HINSTANCE instance) { + + // GET THE MODULE FILENAME + char filename[MAX_PATH] = ""; + GetModuleFileName((HMODULE)instance,filename,MAX_PATH); + + + // OPEN NAMED SHARED MEMORY + char name[MAX_PATH+16]; + wsprintf(name,"Reload-%s",filename); + for (LPSTR curr = name; *curr; ++curr) + if (*curr == '\\') + *curr = '/'; + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + DWORD bytes = max(4096,sysinfo.dwPageSize); + + + HANDLE map = CreateFileMapping((HANDLE)0xFFFFFFFF, + NULL, + PAGE_READWRITE | SEC_COMMIT, + 0, + bytes, + name); + BOOL first = (GetLastError() != ERROR_ALREADY_EXISTS); + if (!map) + return; + + // Open secondary named shared memory to fool Diablo into not autorunning + char tmpname[MAX_PATH+16]; + strcpy(tmpname,"Reload-Diablo"); + HANDLE tmpmap = CreateFileMapping((HANDLE)0xFFFFFFFF, + NULL, + PAGE_READWRITE | SEC_COMMIT, + 0, + bytes, + tmpname); + // end of hack + + LPVOID view = MapViewOfFile(map,FILE_MAP_ALL_ACCESS,0,0,bytes); + if (!view) + return; + SHAREDDATAPTR ptr = (SHAREDDATAPTR)view; + + // IF WE ARE THE FIRST INSTANCE, THEN RELOAD OURSELVES, WAIT FOR THE + // SECOND INSTANCE TO INITIALIZE, THEN QUIT + if (first) { + ptr->status = -1; + ptr->processid = 0; + STARTUPINFO startupinfo; + ZeroMemory(&startupinfo,sizeof(STARTUPINFO)); + startupinfo.cb = sizeof(STARTUPINFO); + PROCESS_INFORMATION processinfo; + CreateProcess(filename, + NULL, + NULL, + NULL, + FALSE, + CREATE_NEW_PROCESS_GROUP, + NULL, + NULL, + &startupinfo, + &processinfo); + WaitForInputIdle(processinfo.hProcess,INFINITE); + CloseHandle(processinfo.hThread); + CloseHandle(processinfo.hProcess); + while (ptr->status < 0) + Sleep(1000); + UnmapViewOfFile(view); + CloseHandle(map); + ExitProcess(0); + } + + // OTHERWISE, ALLOW ONE INSTANCE TO RUN, AND MAKE ANY ADDITIONAL + // INSTANCES JUST REACTIVATE THE RUNNING INSTANCE + if (!InterlockedIncrement(&ptr->status)) + ptr->processid = GetCurrentProcessId(); + else { + HWND window = GetForegroundWindow(); + HWND prev; + while ((prev = GetNextWindow(window,GW_HWNDPREV)) != (HWND)0) + window = prev; + do { + DWORD processid; + GetWindowThreadProcessId(window,&processid); + if (processid == ptr->processid) { + SetForegroundWindow(window); + break; + } + } while ((window = GetNextWindow(window,GW_HWNDNEXT)) != (HWND)0); + UnmapViewOfFile(view); + CloseHandle(map); + ExitProcess(0); + } +} +#endif +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow){ +// pjw.patch2.start + #ifdef NDEBUG + ReloadSelf(hInstance); + #endif +// pjw.patch2.end + + MonoDevice::Printf("Command line: %s", lpCmdLine); + ghInst = hInstance; + ShowCursor(FALSE); + // pjw.patch1.start + srand(GetTickCount()); + InitializeHashSource(); + alloc_plr(); + // pjw.patch1.end + + // delete any previous error file created by exception + // handler and then install exception handler + // pjw.patch2.start + // DeleteFile(sgszErrFile); + sg_previousFilter = SetUnhandledExceptionFilter(DiabloUnhandledExceptionFilter); + // pjw.patch2.end + + // if another instance of Diablo is already running, + // then activate it and exit this instance + BOOL bGotEvent = grab_event(); + if (ActivatePreviousInstance("DIABLO")) // conflict with parent is bad + return FALSE; + if (ActivatePreviousInstance(gszAppName)) + return FALSE; + if (!bGotEvent) return FALSE; + + + #ifndef NDEBUG + SFileEnableDirectAccess(1); + #endif + + InitOnce(); + char cpCmdLine[255]; + if (!lpCmdLine[0]) { + cpCmdLine[0] = 0; + FILE * const fp = fopen("command.txt","r"); + if (fp) { + fgets(cpCmdLine, sizeof(cpCmdLine)/sizeof(char), fp); + lpCmdLine = cpCmdLine; + fclose(fp); + } + } + CommandLine(lpCmdLine); + init_window(nCmdShow); + + menusnd_init(); + UiInitialize(); + + #if IS_VERSION(SHAREWARE) + UiSetSpawned(TRUE); + #endif + + + // play logo + #ifndef NDEBUG + if (cineflag) play_movie("gendata\\logo.smk",TRUE); + #else + play_movie("gendata\\logo.smk",TRUE); + #endif + + // play magazine quotes + /* + #if IS_VERSION(SHAREWARE) + #ifndef NDEBUG + if (cineflag) play_quotes(); + #else + play_quotes(); + #endif + #endif + */ + + // play main intro + #if !IS_VERSION(SHAREWARE) + const char sgszMovie[] = "Intro"; + DWORD dwPlayMovie; + if (! SRegLoadValue(gszProgKey,sgszMovie,0,&dwPlayMovie)) + dwPlayMovie = 1; + //if (dwPlayMovie) + play_movie("gendata\\Hellfire.smk",TRUE); + SRegSaveValue(gszProgKey,sgszMovie,0,0); + #endif + + + // play title screen + #ifndef NDEBUG + if (cineflag) { + #endif + UiTitleDialog(7); // DKT this needs to change to ours + BlackPalette(); + #ifndef NDEBUG + } + #endif + + // play beta warning + #if IS_VERSION(BETA) + #ifndef NDEBUG + if (cineflag) { + #endif + UiBetaDisclaimer(5); + BlackPalette(); + #ifndef NDEBUG + } + #endif + #endif + + // main game menu (finally) + DiabloMenu(); + + // play "buy me" screens + /* + #if IS_VERSION(SHAREWARE) + #ifndef NDEBUG + if (cineflag) play_quit(); + #else + play_quit(); + #endif + #endif + */ + + UiDestroy(); + SavePaletteSettings(); + + if (ghMainWnd) { + // sleep before we destroy window so + // that SFX have time to finish before exit + Sleep(300); + DestroyWindow(ghMainWnd); + } + + return FALSE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL CheckPlrLBtn(BOOL ShiftDown) { + BOOL adjacent; + + app_assert(MouseY < 352); + if (leveltype == 0) { + // + // Town Level + // + ShiftDown = FALSE; // no attacking in town + if ((cursitem != -1) && (curs == GLOVE_CURS)) + NetSendCmdLocParam1(TRUE,invflag ? CMD_GOTOGETITEM : CMD_GOTOAGETITEM,cursmx,cursmy,cursitem); + if (cursmonst != -1) + NetSendCmdLocParam1(TRUE,CMD_TALKXY,cursmx,cursmy,cursmonst); + if ((cursitem == -1) && (cursmonst == -1) && (cursplr == -1)) + return TRUE; + } + else { + // + // NOT Town Level + // + adjacent = abs(plr[myplr]._px - cursmx) < 2 + && abs(plr[myplr]._py - cursmy) < 2; + if ((cursitem != -1) && (curs == GLOVE_CURS) && !ShiftDown) + NetSendCmdLocParam1(TRUE,invflag ? CMD_GOTOGETITEM : CMD_GOTOAGETITEM,cursmx,cursmy,cursitem); + else if ((cursobj != -1) + && (!ShiftDown // allow barrel busting even with shift key down + || (adjacent && object[cursobj]._oBreak == OBJ_BREAKABLE))) + NetSendCmdLocParam1(TRUE,(curs == DISARM_CURS) ? CMD_DISARMXY : CMD_OPOBJXY,cursmx,cursmy,cursobj); + + else if (plr[myplr]._pwtype == WEAP_RANGE) { + if (ShiftDown) + NetSendCmdLoc(TRUE,CMD_RATTACKXY, cursmx, cursmy); + else if (cursmonst != -1) { + if (CanTalkToMonst(cursmonst)) + // walk over to monster to talk to him + NetSendCmdParam1(TRUE,CMD_ATTACKID,cursmonst); + else + // Attack + NetSendCmdParam1(TRUE,CMD_RATTACKID,cursmonst); + } else if (cursplr != -1 && !FriendlyMode) + NetSendCmdParam1(TRUE,CMD_RATTACKPID, cursplr); + } + + else { // pwtype == WEAP_H2H + if (ShiftDown) { + if (cursmonst != -1) { + if (CanTalkToMonst(cursmonst)) + NetSendCmdParam1(TRUE,CMD_ATTACKID,cursmonst); + else + NetSendCmdLoc(TRUE,CMD_SATTACKXY, cursmx, cursmy); + } else + NetSendCmdLoc(TRUE,CMD_SATTACKXY, cursmx, cursmy); + } + else if (cursmonst != -1) + NetSendCmdParam1(TRUE,CMD_ATTACKID,cursmonst); + else if (cursplr != -1 && !FriendlyMode) + NetSendCmdParam1(TRUE,CMD_ATTACKPID,cursplr); + } + + if ((!ShiftDown) && (cursitem == -1) && (cursobj == -1) && (cursmonst == -1) && (cursplr == -1)) + return TRUE; + } + + return FALSE; +} + +/*-----------------------------------------------------------------------** +** Game message processing +**-----------------------------------------------------------------------*/ +static BOOL TryIconCurs() { + if (curs == RESURRECT_CURS) { + NetSendCmdParam1(TRUE,CMD_RESURRECT, cursplr); + return(TRUE); + } + + if (curs == HEALOTHER_CURS) { + NetSendCmdParam1(TRUE,CMD_HEALOTHER, cursplr); + return(TRUE); + } + + if (curs == TELE_CURS) { + DoTelekinesis(); + return(TRUE); + } + if (curs == IDENTIFY_CURS) { + if (cursinvitem != -1) + CheckIdentify(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + if (curs == REPAIR_CURS) { + if (cursinvitem != -1) + DoRepair(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + if (curs == RECHARGE_CURS) { + if (cursinvitem != -1) + DoRecharge(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + + if (curs == OIL_CURS) { + if (cursinvitem != -1) + DoOil(myplr, cursinvitem); + else + NewCursor(GLOVE_CURS); + return(TRUE); + } + + if (curs == TARGET_CURS) { + if (cursmonst != -1) + NetSendCmdParam3(TRUE,CMD_TSPELLID,cursmonst,plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell)); + else if (cursplr != -1) + NetSendCmdParam3(TRUE,CMD_TSPELLPID,cursplr,plr[myplr]._pTSpell,GetSpellLevel(myplr, plr[myplr]._pTSpell)); + else + NetSendCmdLocParam2(TRUE,CMD_TSPELLXY,cursmx,cursmy,plr[myplr]._pTSpell,GetSpellLevel(myplr, plr[myplr]._pTSpell)); + NewCursor(GLOVE_CURS); + return(TRUE); + } + if ((curs == DISARM_CURS) && (cursobj == -1)) { + NewCursor(GLOVE_CURS); + return(TRUE); + } + return(FALSE); +} + + +//****************************************************************** +//****************************************************************** +static BOOL wm_lbuttondown(WPARAM wParam) { + if (gmenu_click(TRUE)) + return FALSE; + + BOOL talk_click(); + if (talk_click()) + return FALSE; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return FALSE; + + if (deathflag) { + CheckDeadButtons(); + return FALSE; + } + + if (PauseMode == 2) + return FALSE; + + if (drawmapofdoom) { + EndMapOfDoomView(); + return FALSE; + } + + if (spselflag) { + SetSpell(); + return FALSE; + } + + if (stextflag != STORE_NONE) { + CheckStoreBtn(); + return FALSE; + } + + if (MouseY < 352) { + if (gmenu_is_on()) + return FALSE; + + if (TryIconCurs()) + return FALSE; + + if (questlog) { + if ((MouseX > 32) && (MouseX < 288) && (MouseY > 32) && (MouseY < 308)) { + CheckQLogBtn(); + return FALSE; + } + } + + if (qtextflag) { + qtextflag = FALSE; + stream_stop(); + return FALSE; + } + + if ((chrflag) && (MouseX < 320)) { + CheckChrBtns(); + return FALSE; + } + else if ((invflag) && (MouseX > 320)) { + if (!dropGoldFlag) CheckInvScrn(); + return FALSE; + } + else if ((sbookflag) && (MouseX > 320)) { + CheckSBook(); + return FALSE; + } + else if (curs >= ICSTART) { + if (TryInvPut()) { + NetSendCmdPItem(TRUE,CMD_PUTITEM,cursmx,cursmy); + NewCursor(GLOVE_CURS); + } + return FALSE; + } + else { + if ((plr[myplr]._pStatPts != 0) && (!spselflag)) + CheckLvlBtn(); + if (!lvlbtndown) + return CheckPlrLBtn(wParam == (MK_LBUTTON | MK_SHIFT)); + } + } + else { + if (!talkflag && !dropGoldFlag && !gmenu_is_on()) + CheckSpdBar(); + CheckPanelBtns(); + if ((curs > GLOVE_CURS) && (curs < ICSTART)) + NewCursor(GLOVE_CURS); + } + + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +static void wm_lbuttonup() { + gmenu_click(FALSE); + void talk_release(); + talk_release(); + if (panbtndown) ReleasePanelBtn(); + if (chrbtndown) ReleaseChrBtn(); + if (lvlbtndown) ReleaseLvlBtn(); + if (stextflag != STORE_NONE) ReleaseStoreBtn(); +} + + +//****************************************************************** +//****************************************************************** +static void wm_rbuttondown() { + + // don't allow input while the menu is active + if (gmenu_is_on()) return; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return; + + if (PauseMode == 2) return; + + if (plr[myplr]._pInvincible) return; + + if (drawmapofdoom) { + EndMapOfDoomView(); + return; + } + + if (stextflag != STORE_NONE) return; + + if (spselflag) { + SetSpell(); + return; + } +// if (sbookflag && CheckSBookCast()) +// return; + if (sbookflag && MouseX > 320) return; + + if (MouseY < 352) { + if (TryIconCurs()) + return; + if (cursinvitem != -1 && UseInvItem(myplr, cursinvitem)) + return; + } + if (curs == GLOVE_CURS) { + if (cursinvitem != -1 && UseInvItem(myplr, cursinvitem)) + return; +// else if (cursitem != -1 && (wParam & WM_SHIFT)) +// UseGroundItem(cursitem); + else + CheckPlrSpell(); + } + else if ((curs > GLOVE_CURS) && (curs < ICSTART)) NewCursor(GLOVE_CURS); +} + + +//****************************************************************** +//****************************************************************** +static void wm_mousemove() { + // check for menu sliders + if (gmenu_mousemove()) return; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) return; + + // do game mousemove here +} + + +//****************************************************************** +//****************************************************************** +static void TogglePause() { + // no pause in multiplayer + if (gbMaxPlayers > 1) return; + + if (PauseMode) { + PauseMode = 0; + } + else { + PauseMode = 2; + sound_stop(); + TrackInit(FALSE); + } + force_redraw = FULLDRAW; +} + + +//****************************************************************** +//****************************************************************** +static void SendTaunt(DWORD dwMsg) { + // don't send taunts in single player mode + if (gbMaxPlayers == 1) return; + + // get program directory + char szPath[MAX_PATH]; + if (! GetModuleFileName(ghInst,szPath,MAX_PATH)) + app_fatal("Can't get program name"); + char * pszName = strrchr(szPath,'\\'); + if (pszName) *pszName = 0; + strcat(szPath,"\\hellfire.ini"); + + static const char * spszMsgTbl[] = { + "I need help! Heal me!", + "Go through that door first.", + "Give me some gold please.", + "Look out behind you!", + }; + static const char * spszKeyTbl[] = { + "F9","F10","F11","F12" + }; + + char szBuf[MAX_SEND_STR_LEN]; + app_assert(dwMsg < sizeof(spszMsgTbl) / sizeof(spszMsgTbl[0])); + GetPrivateProfileString( + "NetMsg", // section name + spszKeyTbl[dwMsg], // key name + spszMsgTbl[dwMsg], // default string + szBuf, // dest buffer + sizeof(szBuf) / sizeof(szBuf[0]), + szPath + ); + + // send message to other players + NetSendString(SEND_ALL_MASK,szBuf); +} + + +//****************************************************************** +//****************************************************************** +static BOOL wm_syskeydown(WPARAM wKey) { + // don't allow input while the menu is active + if (gmenu_is_on()) + return FALSE; + + // note: this identical code is in the keydown case also, but + // F10 seems to come through as a system key sometimes... + if (wKey == VK_F10) { + SendTaunt(1); + return TRUE; + } + + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +static void wm_keyup(WPARAM wKey) { + // can't ever get keydown for snapshot, but we do get keyup + if (wKey == VK_SNAPSHOT) + screen_capture(); + + // if any more cases are added here, then make sure menu is not active + // if (gmenu_is_on()) return; +} + + +//****************************************************************** +//****************************************************************** +BOOL clear_windows() { + BOOL bResult = FALSE; + + if (drawmapofdoom) { + EndMapOfDoomView(); + bResult = TRUE; + } + if (helpflag) { + helpflag = FALSE; + bResult = TRUE; + } + if (qtextflag) { + qtextflag = FALSE; + stream_stop(); + #if CHEATS + if ((currlevel == 0) && (davecheat)) { + tstQMsgFlag = FALSE; + tstQMsgIndexFlag = TRUE; + } + #endif + bResult = TRUE; + } else + if (stextflag) { + STextESC(); + bResult = TRUE; + } + if (msgflag) { + msgdelay = 0; + bResult = TRUE; + } + if (talkflag) { + TalkEnd(); + bResult = TRUE; + } + if (dropGoldFlag) { + DropGoldType(VK_ESCAPE); + bResult = TRUE; + } + if (spselflag) { + spselflag = FALSE; + bResult = TRUE; + } + + return bResult; +} + + +//****************************************************************** +//****************************************************************** +static void wm_keydown(WPARAM wKey) { + // allow use of menu even when character is dead + if (gmenu_key(wKey)) + return; + + // allow user to finish current string even in timeout mode + if (Talk_wm_keydown(wKey)) + return; + + // don't allow dead player to do anything except turn on gamemenu + if (deathflag) { + // no input while in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) return; + if (wKey == VK_F9) SendTaunt(0); + if (wKey == VK_F10) SendTaunt(1); + if (wKey == VK_F11) SendTaunt(2); + if (wKey == VK_F12) SendTaunt(3); + if (wKey == VK_RETURN) TalkStart(); + if (wKey != VK_ESCAPE) return; + } + + if (wKey == VK_ESCAPE) { + if (! clear_windows()) { + TrackInit(FALSE); + gamemenu_on(); + } + #if CHEATS + if ((currlevel == 0) && (davecheat) && + ((tstQMsgFlag) || (tstQMsgIndexFlag))) { + tstQMsgFlag = FALSE; + tstQMsgIndexFlag = FALSE; + sprintf(tempstr, "STOP QUEST TEXT MODE"); + NetSendString((1 << myplr), tempstr); + return; + } + #endif + return; + } + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return; + + // Don't accept input when in drop gold mode + if (dropGoldFlag) + return; + + // in pause mode the only thing we can do is unpause + if (wKey == VK_PAUSE) { + TogglePause(); + return; + } + if (PauseMode == 2) return; + + if (wKey == VK_RETURN) { + if (stextflag) STextEnter(); + else if (questlog) QuestlogEnter(); + #if CHEATS + else if ((currlevel == 0) && (davecheat)) { + if (tstQMsgIndexFlag) { + tstQMsgIndexFlag = FALSE; + tstQMsgFlag = TRUE; + tstQMsgSpd = 5; + DaveQuestText(); + sprintf(tempstr, "Message Speed = %i", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } else if (tstQMsgFlag) { + sprintf(tempstr, "[ MESSAGE = %i ]", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "[ MESSAGE SPEED = %i ]", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } + } + #endif + else TalkStart(); + return; + } + + if (wKey == VK_F1) { + if (helpflag) { + helpflag = FALSE; + } + else if (stextflag != STORE_NONE) { + ClearPanel(); + AddPanelString("No help available", TEXT_CENTER); + AddPanelString("while in stores", TEXT_CENTER); + TrackInit(FALSE); + } + else { + invflag = FALSE; + chrflag = FALSE; + sbookflag = FALSE; + spselflag = FALSE; + if ((qtextflag) && (leveltype == 0)) { + qtextflag = FALSE; + stream_stop(); + } + questlog = FALSE; + automapflag = FALSE; + msgdelay = 0; + gamemenu_off(); + StartHelp(); + EndMapOfDoomView(); + } + return; + } + + #if CHEATS + if (wKey == VK_F2) { + void PrintDaveCheck2(); + PrintDaveCheck2(); + } + +/* if (wKey == VK_F3) { + extern BOOL syncdebug; + syncdebug = !syncdebug; + if (syncdebug) + strcpy(tempstr, "Item drop debug on"); + else + strcpy(tempstr, "Item drop debug off"); + NetSendString((1 << myplr), tempstr); + }*/ + if (wKey == VK_F3) { + if (cursitem != -1) { + sprintf(tempstr, "IDX = %i : Seed = %i : CF = %i", item[cursitem].IDidx, item[cursitem]._iSeed, item[cursitem]._iCreateInfo); + NetSendString((1 << myplr), tempstr); + } + sprintf(tempstr, "Numitems : %i", numitems); + NetSendString((1 << myplr), tempstr); + } + + if (wKey == VK_F4) { + void PrintQuestDebug(); + PrintQuestDebug(); + return; + } + #endif + +/* #if CHEATS + if (wKey == VK_F4) { + if (cheatflag) toggle_frame_counter(); + return; + } + #endif*/ + + if (wKey == VK_F5) { + if (spselflag) SetSpellHK(0); + else GetSpellHK(0); + return; + } + if (wKey == VK_F6) { + if (spselflag) SetSpellHK(1); + else GetSpellHK(1); + return; + } + if (wKey == VK_F7) { + if (spselflag) SetSpellHK(2); + else GetSpellHK(2); + return; + } + if (wKey == VK_F8) { + if (spselflag) SetSpellHK(3); + else GetSpellHK(3); + return; + } + + if (wKey == VK_F9) { + SendTaunt(0); + return; + } + if (wKey == VK_F10) { + SendTaunt(1); + return; + } + if (wKey == VK_F11) { + SendTaunt(2); + return; + } + if (wKey == VK_F12) { + SendTaunt(3); + return; + } + + if (wKey == VK_UP) { + if (stextflag) STextUp(); + else if (questlog) QuestlogUp(); + else if (helpflag) HelpScrollUp(); + else if (automapflag) AutomapUp(); + return; + } + + if (wKey == VK_DOWN) { + if (stextflag) STextDown(); + else if (questlog) QuestlogDown(); + else if (helpflag) HelpScrollDown(); + else if (automapflag) AutomapDown(); + return; + } + + if (wKey == VK_PRIOR) { + if (stextflag) STextPgUp(); + return; + } + + if (wKey == VK_NEXT) { + if (stextflag) STextPgDown(); + return; + } + + if (wKey == VK_LEFT) { + if (automapflag && !talkflag) AutomapLeft(); + return; + } + if (wKey == VK_RIGHT) { + if (automapflag && !talkflag) AutomapRight(); + return; + } + + if (wKey == VK_TAB) { + void DoAutoMap(); + DoAutoMap(); + return; + } + +/* if (wKey == VK_CAPITAL) { + FriendlyMode = !FriendlyMode; + drawbtnflag = TRUE; + return; + }*/ + + if (wKey == VK_SPACE) { + if ((!chrflag) && (invflag) && (MouseX < 480) && (MouseY < 352)) SetCursorPos(MouseX+160,MouseY); + if ((!invflag) && (chrflag) && (MouseX > 160) && (MouseY < 352)) SetCursorPos(MouseX-160,MouseY); + helpflag = FALSE; + invflag = FALSE; + chrflag = FALSE; + sbookflag = FALSE; + spselflag = FALSE; + if ((qtextflag) && (leveltype == 0)) { + qtextflag = FALSE; + stream_stop(); + } + questlog = FALSE; + automapflag = FALSE; + msgdelay = 0; + gamemenu_off(); + EndMapOfDoomView(); +//Never clear the cursor, else we lose a scroll or a staff charge +//for a spell we've cast. +// if ((curs != GLOVE_CURS) && (curs < ICSTART)) NewCursor(GLOVE_CURS); + return; + } +} + + +//****************************************************************** +//****************************************************************** +static void wm_char(WPARAM wKey) { + #ifdef _DEBUG + BOOL is_pat_debug_cmd(WPARAM wKey); + if (is_pat_debug_cmd(wKey)) + return; + #endif + + // don't allow input while the menu is active + if (gmenu_is_on()) + return; + + if (Talk_wm_char(wKey)) + return; + + // don't accept input in timeout mode + if (sgnTimeoutCurs != NO_CURSOR) + return; + + // dead players can't perform input + if (deathflag) + return; + + // in pause mode the only thing we can do is unpause + if ((TCHAR) wKey == 'p' || (TCHAR) wKey == 'P') { + TogglePause(); + return; + } + if (PauseMode == 2) return; + + if (drawmapofdoom) { + EndMapOfDoomView(); + return; + } + + if (dropGoldFlag) { + DropGoldType((char) wKey); + return; + } + + switch(wKey) { + case 'g': + case 'G': + GammaDown(); + return; + + case 'f': + case 'F': + GammaUp(); + return; + + case 'i': + case 'I': + if (stextflag != STORE_NONE) return; + sbookflag = FALSE; + invflag = !invflag; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + if (invflag && !chrflag) { + if (MouseX > 160 && MouseY < 352) SetCursorPos(MouseX-160,MouseY); + } + else { + if (MouseX < 480 && MouseY < 352) SetCursorPos(MouseX+160, MouseY); + } + return; + + case 'c': + case 'C': + if (stextflag != STORE_NONE) return; + questlog = FALSE; + chrflag = !chrflag; + if (chrflag && !invflag) { + if (MouseX < 480 && MouseY < 352) SetCursorPos(MouseX+160,MouseY); + } + else { + if (MouseX > 160 && MouseY < 352) SetCursorPos(MouseX-160, MouseY); + } + return; + + #ifndef NDEBUG + case 'r': + case 'R': + sprintf(tempstr, "seed = %i", glSeedTbl[currlevel]); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "Mid1 = %i : Mid2 = %i : Mid3 = %i", + glMid1Seed[currlevel], glMid2Seed[currlevel], glMid3Seed[currlevel]); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "End = %i", glEndSeed[currlevel]); + NetSendString((1 << myplr), tempstr); + return; + #endif + + #if CHEATS + case 'A': + if (cheatflag) { + sprintf(tempstr, "Mid: %i", dMonster[cursmx][cursmy] - 1); + NetSendString((1 << myplr), tempstr); + if (dMonster[cursmx][cursmy] > 0) { + monster[(dMonster[cursmx][cursmy] - 1)]._mFlags |= MFLAG_MKILLER; + void M_Enemy(int); + M_Enemy((dMonster[cursmx][cursmy] - 1)); + } + } + return; + case 'a': + if (cheatflag) { + plr[myplr]._pSplLvl[(plr[myplr]._pSpell)]++; + spelldata[SPL_TELE].sTownSpell = TRUE; + } + return; + #endif + + #if CHEATS + case ')': + case '0': + if (cheatflag) { + if (gv1 > 2) gv1 = 0; + if (gv1 == 0) { + plr[myplr]._pIFlags &= ~IAF_FIREARROW; + plr[myplr]._pIFlags &= ~IAF_LARROW; + } + if (gv1 == 1) plr[myplr]._pIFlags |= IAF_FIREARROW; + if (gv1 == 2) plr[myplr]._pIFlags |= IAF_LARROW; + gv1++; + } + return; + #endif + + #if CHEATS + case 'l': + case 'L': + if (cheatflag) ToggleLight(); + return; + #endif + + #if CHEATS + case 't': + case 'T': + if (cheatflag) { + sprintf(tempstr, "PX = %i PY = %i", plr[myplr]._px, plr[myplr]._py); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "CX = %i CY = %i DP = %i", cursmx, cursmy, dungeon[cursmx][cursmy]); + NetSendString((1 << myplr), tempstr); + } + return; + #endif + + #ifndef NDEBUG + case 'D': + void BlipDebug(BOOL); + BlipDebug(TRUE); + return; + case 'd': + BlipDebug(FALSE); + return; + #endif + + #if CHEATS + case 'e': + if (davedebug) { + sprintf(tempstr, "EFlag = %i", plr[myplr]._peflag); + NetSendString((1 << myplr), tempstr); + } + return; + #endif + + #ifndef NDEBUG + case 'm': + void DaveDebugMonst(); + DaveDebugMonst(); + return; + case 'M': + void DaveDebugMonst2(); + DaveDebugMonst2(); + return; + #endif + + #if CHEATS + case '|': + if ((currlevel == 0) && (davecheat)) DaveGold(); + return; + #endif + + #if CHEATS + case '~': + if ((currlevel == 0) && (davecheat)) DaveNewPremium(); + return; + #endif + + #if CHEATS + case '[': + if ((currlevel == 0) && (davecheat)) DaveCleanUp(); + return; + #endif + + #if CHEATS + case ']': + if ((currlevel == 0) && (davecheat)) DaveSpells(); + return; + #endif + + #if CHEATS + case ':': + if ((currlevel == 0) && (davecheat)) DaveSpells2(); + return; + #endif + + #if CHEATS + case '.': + void DaveDungDebug(); + DaveDungDebug(); + return; + #endif + + #if CHEATS + case '?': + if ((currlevel == 0) && (davecheat)) { + tstQMsgFlag = FALSE; + tstQMsgIndexFlag = TRUE; + sprintf(tempstr, "START QUEST TEXT MODE"); + NetSendString((1 << myplr), tempstr); + sprintf(tempstr, "Message = %i", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + } + return; + #endif + + case 'q': + case 'Q': + if (stextflag != STORE_NONE) return; + chrflag = FALSE; + if (!questlog) StartQuestlog(); + else questlog = FALSE; + return; + + case 'z': + case 'Z': + svgamode = !svgamode; + return; + + case 's': + case 'S': + if (stextflag != STORE_NONE) return; + invflag = FALSE; + if (!spselflag) SetupSpellSel(); + else spselflag = FALSE; + TrackInit(FALSE); + return; + + case 'b': + case 'B': + if (stextflag != STORE_NONE) return; + invflag = FALSE; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + sbookflag = !sbookflag; + return; + + case '+': + case '=': + if (automapflag) AutomapZoomIn(); + #if CHEATS + else if ((currlevel == 0) && (davecheat)) { + if (tstQMsgIndexFlag) { + tstQMsgIndex++; + if (tstQMsgIndex > (int)(gdwAllTextEntries-1)) tstQMsgIndex = 0; + sprintf(tempstr, "Message = %i", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + } else if (tstQMsgFlag) { + tstQMsgSpd++; + if (tstQMsgSpd > 9) tstQMsgSpd = 9; + qtextSpd = qtextDelaySpd[tstQMsgSpd-1]; + qtextflag = FALSE; + stream_stop(); + DaveQuestText(); + sprintf(tempstr, "Message Speed = %i", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } + } + #endif + return; + + case '_': + case '-': + if (automapflag) AutomapZoomOut(); + #if CHEATS + else if ((currlevel == 0) && (davecheat)) { + if (tstQMsgIndexFlag) { + tstQMsgIndex--; + if (tstQMsgIndex < 0) tstQMsgIndex = (int)(gdwAllTextEntries-1); + sprintf(tempstr, "Message = %i", tstQMsgIndex); + NetSendString((1 << myplr), tempstr); + } else if (tstQMsgFlag){ + tstQMsgSpd--; + if (tstQMsgSpd < 1) tstQMsgSpd = 1; + qtextSpd = qtextDelaySpd[tstQMsgSpd-1]; + qtextflag = FALSE; + stream_stop(); + DaveQuestText(); + sprintf(tempstr, "Message Speed = %i", tstQMsgSpd); + NetSendString((1 << myplr), tempstr); + } + } + #endif + return; + + case 'v': + extern char gszPrintVersion[]; + { + char *pszaDif[] = {"Normal", "Nightmare", "Hell"}; + char tmpbuf[120]; + sprintf(tmpbuf, "%s, mode = %s", gszPrintVersion, + pszaDif[gnDifficulty]); + NetSendString((1 << myplr), tmpbuf); + } +// NetSendString((1 << myplr), gszPrintVersion); + break; + + case 'V': + extern char gszVersionNumber[]; + NetSendString((1 << myplr), gszVersionNumber); + return; + + case '!': + case '1': + if ((plr[myplr].SpdList[0]._itype != -1) && + (plr[myplr].SpdList[0]._itype != IT_GOLD)) UseInvItem(myplr, 47); + return; + + case '@': + case '2': + if ((plr[myplr].SpdList[1]._itype != -1) && + (plr[myplr].SpdList[1]._itype != IT_GOLD)) UseInvItem(myplr, 48); + return; + + case '#': + case '3': + if ((plr[myplr].SpdList[2]._itype != -1) && + (plr[myplr].SpdList[2]._itype != IT_GOLD)) UseInvItem(myplr, 49); + return; + + case '$': + case '4': + if ((plr[myplr].SpdList[3]._itype != -1) && + (plr[myplr].SpdList[3]._itype != IT_GOLD)) UseInvItem(myplr, 50); + return; + + case '%': + case '5': + if ((plr[myplr].SpdList[4]._itype != -1) && + (plr[myplr].SpdList[4]._itype != IT_GOLD)) UseInvItem(myplr, 51); + return; + + case '^': + case '6': + if ((plr[myplr].SpdList[5]._itype != -1) && + (plr[myplr].SpdList[5]._itype != IT_GOLD)) UseInvItem(myplr, 52); + return; + + case '&': + case '7': + if ((plr[myplr].SpdList[6]._itype != -1) && + (plr[myplr].SpdList[6]._itype != IT_GOLD)) UseInvItem(myplr, 53); + return; + + case '*': + case '8': + #if CHEATS + if (cheatflag || davecheat) { + NetSendCmd(TRUE,CMD_CHEAT_EXPERIENCE); + return; + } + #endif + if ((plr[myplr].SpdList[7]._itype != -1) && + (plr[myplr].SpdList[7]._itype != IT_GOLD)) UseInvItem(myplr, 54); + return; +/* + // testing diablo death + case 'k': +#define MT_DIABLO 110 + for (int i = 0; i < nummonsters; i++) { + int mi = monstactive[i]; + if (monster[mi].MType->mtype == MT_DIABLO) + M_StartKill(mi, myplr); + } + return; +*/ + } +} + + +//****************************************************************** +//****************************************************************** +LRESULT CALLBACK DisableInputWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + switch (uMsg) { + // don't let input go to game window proc + case WM_SYSKEYDOWN: + case WM_SYSCOMMAND: + case WM_KEYUP: + case WM_KEYDOWN: + case WM_CHAR: + case WM_MOUSEMOVE: + return 0; + + case WM_LBUTTONDOWN: + if (sgbMouseDown) return 0; + sgbMouseDown = LMOUSE_DOWN; + SetCapture(hWnd); + return 0; + + case WM_LBUTTONUP: + if (sgbMouseDown != LMOUSE_DOWN) return 0; + sgbMouseDown = 0; + ReleaseCapture(); + return 0; + + case WM_RBUTTONDOWN: + if (sgbMouseDown) return 0; + sgbMouseDown = RMOUSE_DOWN; + SetCapture(hWnd); + return 0; + + case WM_RBUTTONUP: + if (sgbMouseDown != RMOUSE_DOWN) return 0; + sgbMouseDown = 0; + ReleaseCapture(); + return 0; + + case WM_CAPTURECHANGED: + if (hWnd != (HWND) lParam) + sgbMouseDown = 0; + return 0; + } + + return DiabloDefProc(hWnd,uMsg,wParam,lParam); +} + + +//****************************************************************** +//****************************************************************** +static LRESULT CALLBACK GM_Game(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + switch (uMsg) { + case WM_SYSKEYDOWN: + if (wm_syskeydown(wParam)) return 0; + break; + + case WM_KEYUP: + wm_keyup(wParam); + return 0; + + case WM_KEYDOWN: + wm_keydown(wParam); + return 0; + + case WM_CHAR: + wm_char(wParam); + return 0; + + case WM_MOUSEMOVE: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + wm_mousemove(); + return 0; + + case WM_LBUTTONDOWN: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // if the mouse is already down, wait for mouse up + if (sgbMouseDown) return 0; + sgbMouseDown = LMOUSE_DOWN; + SetCapture(hWnd); + + TrackInit(wm_lbuttondown(wParam)); + return 0; + + case WM_LBUTTONUP: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // don't accept mouse up unless it went down in our window + if (sgbMouseDown != LMOUSE_DOWN) return 0; + sgbMouseDown = 0; + + wm_lbuttonup(); + TrackInit(FALSE); + ReleaseCapture(); + return 0; + + case WM_RBUTTONDOWN: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // if the mouse is already down, wait for mouse up + if (sgbMouseDown) return 0; + sgbMouseDown = RMOUSE_DOWN; + SetCapture(hWnd); + + wm_rbuttondown(); + return 0; + + case WM_RBUTTONUP: + MouseX = LOWORD(lParam); + MouseY = HIWORD(lParam); + + // don't accept mouse up unless it went down in our window + if (sgbMouseDown != RMOUSE_DOWN) return 0; + sgbMouseDown = 0; + ReleaseCapture(); + return 0; + + case WM_CAPTURECHANGED: + if (hWnd != (HWND) lParam) { + sgbMouseDown = 0; + TrackInit(FALSE); + } + break; + + case WM_DIABNEXTLVL: + case WM_DIABPREVLVL: + case WM_DIABSETLVL: + case WM_DIABRTNLVL: + case WM_DIABWARPLVL: + case WM_DIABTOWNWARP: + case WM_DIABTWARPUP: + case WM_DIABRETOWN: + // save character in multiplayer mode + if (gbMaxPlayers > 1) { + void UpdatePlayerFile(); + UpdatePlayerFile(); + } + nthread_perform_keepalive(TRUE); + PaletteFadeOut(FADE_FAST); + sound_stop(); + music_stop(); + TrackInit(FALSE); + sgbMouseDown = FALSE; + ReleaseCapture(); + ShowProgress(uMsg); + force_redraw = FULLDRAW; + DrawAndBlit(); + if (gbRunGame) PaletteFadeIn(FADE_FAST); + nthread_perform_keepalive(FALSE); + gbGameLoopStartup = TRUE; + return 0; + + case WM_SYSCOMMAND: + if (wParam == SC_CLOSE) { + gbRunGame = FALSE; + gbRunGameResult = FALSE; + return 0; + } + break; + } + + return DiabloDefProc(hWnd, uMsg, wParam, lParam); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LoadLvlGFX() { + app_assert(! pDungeonCels); + switch (leveltype) { + case 0: + pDungeonCels = LoadFileInMemSig("NLevels\\TownData\\Town.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("NLevels\\TownData\\Town.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("NLevels\\TownData\\Town.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\TownData\\TownS.CEL",NULL,'TILE'); + break; + + case 1: +/* pDungeonCels = LoadFileInMemSig("Levels\\L1Data\\L1.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L1Data\\L1.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L1Data\\L1.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + break;*/ + if (currlevel < CRYPTSTART) + { + pDungeonCels = LoadFileInMemSig("Levels\\L1Data\\L1.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L1Data\\L1.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L1Data\\L1.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + } + else + { + pDungeonCels = LoadFileInMemSig("NLevels\\L5Data\\L5.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("NLevels\\L5Data\\L5.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("NLevels\\L5Data\\L5.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("NLevels\\L5Data\\L5S.CEL",NULL,'TILE'); + } + break; + + #if IS_VERSION(RETAIL) || IS_VERSION(BETA) + case 2: + pDungeonCels = LoadFileInMemSig("Levels\\L2Data\\L2.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L2Data\\L2.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L2Data\\L2.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L2Data\\L2S.CEL",NULL,'TILE'); + break; + #endif + + #if IS_VERSION(RETAIL) + case 3: + if (currlevel < HIVESTART) + { + pDungeonCels = LoadFileInMemSig("Levels\\L3Data\\L3.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L3Data\\L3.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L3Data\\L3.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + } + else + { + pDungeonCels = LoadFileInMemSig("NLevels\\L6Data\\L6.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("NLevels\\L6Data\\L6.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("NLevels\\L6Data\\L6.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L1Data\\L1S.CEL",NULL,'TILE'); + } + break; + #endif + + #if IS_VERSION(RETAIL) + case 4: + pDungeonCels = LoadFileInMemSig("Levels\\L4Data\\L4.CEL",NULL,'TILE'); + pMegaTiles = LoadFileInMemSig("Levels\\L4Data\\L4.TIL",NULL,'TILE'); + pMiniTiles = LoadFileInMemSig("Levels\\L4Data\\L4.MIN",NULL,'TILE'); + pSpecialCels = LoadFileInMemSig("Levels\\L2Data\\L2S.CEL",NULL,'TILE'); + break; + #endif + + default: + app_fatal("LoadLvlGFX"); + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void LoadAllGFX() +{ + app_assert(! pSpeedCels); + pSpeedCels = DiabloAllocPtrSig(SPEEDSIZE,'SPED'); +// InitMonsterGFX(); + IntCheck(); +// InitMonsterSND(); + IntCheck(); + InitObjectGFX(); + IntCheck(); + InitMissileGFX(); + IntCheck(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CreateLevel(int lvldir) +{ + switch (leveltype) { + case 0: + CreateTown(lvldir); + InitTownTriggers(); + LoadRndLvlPal(0); + break; + + case 1: + CreateL5Dungeon(glSeedTbl[currlevel], lvldir); + InitL1Triggers(); + Freeupstairs(); + if (currlevel < CRYPTSTART) // JKE load correct pallet + LoadRndLvlPal(1); + else + LoadRndLvlPal(5); + break; + + #if IS_VERSION(RETAIL) || IS_VERSION(BETA) + case 2: + CreateL2Dungeon(glSeedTbl[currlevel], lvldir); + InitL2Triggers(); + Freeupstairs(); + LoadRndLvlPal(2); + break; + #endif + + #if IS_VERSION(RETAIL) + case 3: + CreateL3Dungeon(glSeedTbl[currlevel], lvldir); + InitL3Triggers(); + Freeupstairs(); + if (currlevel < HIVESTART) + LoadRndLvlPal(3); + else + LoadRndLvlPal(6); + break; + #endif + + #if IS_VERSION(RETAIL) + case 4: + CreateL4Dungeon(glSeedTbl[currlevel], lvldir); + InitL4Triggers(); + Freeupstairs(); + LoadRndLvlPal(4); + break; + #endif + + default: + app_fatal("CreateLevel"); + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void LoadGameLevel(BOOL firstflag, int lvldir) +{ + int i,j; + + if (setseed) + glSeedTbl[currlevel] = setseed; + + music_stop(); + SetCursor(GLOVE_CURS); + SetRndSeed(glSeedTbl[currlevel]); + IntCheck(); + + MakeLightTable(); + LoadLvlGFX(); + IntCheck(); + + if (firstflag) { + InitInv(); + InitItemGFX(); + InitQuestText(); + for (i = 0; i < gbMaxPlayers; i++) + InitPlrGFXMem(i); + InitStores(); + InitAutomapOnce(); + InitHelpSys(); + } + + SetRndSeed(glSeedTbl[currlevel]); + if (leveltype == 0) SetupTownStores(); + IntCheck(); + + InitAutomap(); + + if ((leveltype != 0) && (lvldir != LVL_NODIR)) { + InitLighting(); + InitVision(); + } + InitLevelMonsters(); + IntCheck(); + + if (!setlevel) { + CreateLevel(lvldir); + IntCheck(); + + // Open Tiles file + FillSolidBlockTbls(); + + SetRndSeed(glSeedTbl[currlevel]); + + if (leveltype != 0) { + GetLevelMTypes(); + InitThemes(); + LoadAllGFX(); + } else { + InitMissileGFX(); + } + IntCheck(); + + if (lvldir == LVL_RTN) GetReturnLvlPos(); + if (lvldir == LVL_WARP) GetPortalLvlPos(); + IntCheck(); + + // Init Player info + for (i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (currlevel != plr[i].plrlevel) continue; + InitPlayerGFX(i); + if (lvldir != LVL_NODIR) InitPlayer(i, firstflag); + } + + PlayDungMsgs(); + InitMultiView(); + IntCheck(); + + BOOL visited = FALSE; + for (i = 0; i < gbMaxPlayers; i++) + if (plr[i].plractive) visited = visited || plr[i]._pLvlVisited[currlevel]; + + // Resync after level changing bug + // This bug occurs when 2 players change levels one after the other. The first player + // down thinks the other player is one level above, because the change level msg has + // not been processed during loading. The second player knows that they are both + // on the same level, so more players get inited, and randoms desync. + SetRndSeed(glSeedTbl[currlevel]); + + if (leveltype != 0) { + if (!firstflag && (lvldir != LVL_NODIR) && plr[myplr]._pLvlVisited[currlevel] && (gbMaxPlayers == 1)) { + // Init monsters so uniques are loaded + InitMonsters (); + // Init missiles + InitMissiles(); + // Init dead info, not dungeon layout though + InitDead(); + IntCheck (); + // Load where things were + LoadLevel(); + IntCheck (); + } else { + // Save theme room areas + HoldThemeRooms(); + glMid1Seed[currlevel] = GetRndSeed(); // @@@ drb temp + // Init monsters into dungeon +// if (currlevel < HIVESTART) InitMonsters (); // temp hack to test failure JKE + InitMonsters (); + glMid2Seed[currlevel] = GetRndSeed(); // @@@ drb temp + // Init objects +// if (currlevel < CRYPTSTART) InitObjects(); // temp hack to test failure JKE + InitObjects(); + // Init items +// if (currlevel < HIVESTART) InitItems(); // Temp hack to test failure JKE + InitItems(); + // Fill theme rooms + if (currlevel < HIVESTART) CreateThemeRooms(); // Temp hack for failure JKE +// CreateThemeRooms(); + glMid3Seed[currlevel] = GetRndSeed(); // @@@ drb temp + // Init missiles + InitMissiles(); + // Init dead info, not dungeon layout though + InitDead(); + glEndSeed[currlevel] = GetRndSeed(); // @@@ drb temp + // if multiplayer resync level + if (gbMaxPlayers != 1) DeltaLoadLevel(); + IntCheck(); + SavePreLighting(); + } + } else { + // Make everything visible + for (i = 0; i < DMAXX; i++) + for (j = 0; j < DMAXY; j++) + dFlags[i][j] |= BFLAG_VISIBLE; + // Init town people + InitTowners(); + // Init items + InitItems(); + // Init missiles + InitMissiles(); + IntCheck(); + + // Load items + if (!firstflag && (lvldir != LVL_NODIR) && plr[myplr]._pLvlVisited[currlevel] && (gbMaxPlayers == 1)) + LoadLevel(); + if (gbMaxPlayers != 1) DeltaLoadLevel(); + IntCheck (); + } + if (gbMaxPlayers == 1) + ResyncQuests(); + else + ResyncMPQuests(); + + } +#if !IS_VERSION(SHAREWARE) + else { + // Preset levels + app_assert(! pSpeedCels); + pSpeedCels = DiabloAllocPtrSig(SPEEDSIZE,'SPED'); + + LoadSetMap(); + IntCheck(); + + GetLevelMTypes(); + + InitMonsters(); + + //SetDungeonMicros(); + + InitMissileGFX(); + + // Init dead info, not dungeon layout though + InitDead(); + + // Open Tiles file + FillSolidBlockTbls (); + IntCheck(); + + if (lvldir == LVL_WARP) GetPortalLvlPos(); + + // Init Player info + for (i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (currlevel != plr[i].plrlevel) continue; + InitPlayerGFX(i); + if (lvldir != LVL_NODIR) InitPlayer(i, firstflag); + } + + InitMultiView(); + IntCheck(); + + if ((!firstflag) && (lvldir != LVL_NODIR) && (plr[myplr]._pSLvlVisited[setlvlnum])) { + // Load where things were + LoadLevel(); + } else { + // Init items + InitItems(); + SavePreLighting(); + } + // Init missiles + InitMissiles(); + IntCheck(); + } +#endif + + SyncPortals(); + + for (i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (plr[i].plrlevel != currlevel) continue; + if (plr[i]._pLvlChanging && (i != myplr)) continue; + if (plr[i]._pHitPoints > 0) { + if (gbMaxPlayers == 1) + dPlayer[plr[i]._px][plr[i]._py] = i + 1; + else + SyncInitPlrPos(i); + } else + dFlags[plr[i]._px][plr[i]._py] |= BFLAG_DEADPLR; + } + + if (leveltype != 0) { + SetDungeonMicros(); + } + + InitLightMax(); // Set up 4 or 16 level lighting + IntCheck(); + +/* + if ((leveltype != 0) && (lvldir != LVL_NODIR)) { + SavePreLighting(); + } +*/ + IntCheck(); + + if (firstflag) { + // Get Control panel graphics and decompress panel to BtmBuff + // Has to be after init player because of bars/spells/equipment etc. + InitControlPan(); + IntCheck(); + } + + if (leveltype != 0) { + ProcessLightList(); + ProcessVisionList(); + } + if (currlevel >= CRYPTSTART) + { +// OpenCloseAllDoors(); // JKE Stupid!!! + if (currlevel == CORNERSTONE_LEVEL) + CornerstoneRestore(CornerStone.x, CornerStone.y); + if ((quests[Q_NA_KRUL]._qactive == QUEST_DONE)&&(currlevel == NA_KRUL_LEVEL)) + OpenNaKrul(); + + } + + // start appropriate sound track + if (currlevel >= HIVESTART) // fix this later JKE + { + music_start((currlevel > HIVEEND)? 5 : 6); + } + else + music_start(leveltype); + + // finish progress bar + while (! IntCheck()) + NULL; + + #if !IS_VERSION(SHAREWARE) + if ((setlevel) && (setlvlnum == SL_SKELKING) && (quests[Q_SKELKING]._qactive == QUEST_NOTDONE)) + PlaySFX(USFX_SKING1); + #endif +} + + +//****************************************************************** +//****************************************************************** +// this parameter is the maximum number of game loops which can be run +// in a row without redrawing the screen +#define MAX_CONSECUTIVE_LOOPS 3 + + +//****************************************************************** +//****************************************************************** +static void game_logic() { + if (PauseMode == 2) return; + if (PauseMode == 1) PauseMode = 2; + + // pause when menu is active in single player mode + if (gbMaxPlayers == 1 && gmenu_is_on()) { + force_redraw |= VIEWDRAW; + return; + } + + if (! gmenu_is_on() && (sgnTimeoutCurs == NO_CURSOR)) { + CheckCursMove(); + TrackMouse(); + } + + if (gbProcessPlayers) + ProcessPlayers(); + if (leveltype) { + ProcessMonsters(); + ProcessObjects(); + ProcessMissiles(); + ProcessItems(); + ProcessLightList(); + ProcessVisionList(); + } + else { + ProcessTowners(); + ProcessItems(); + ProcessMissiles(); + } + + #if CHEATS + if ((cheatflag) && ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0)) + CheckForScroll(); + #endif + + sound_update(); + plrmsg_update(); + CheckTriggers(); + CheckQuests(); + force_redraw |= VIEWDRAW; + + void TimedUpdatePlayerFile(BOOL bForce); + TimedUpdatePlayerFile(FALSE); +} + + +//****************************************************************** +//****************************************************************** +static void timeout_cursor(BOOL bTimeout) { + if (bTimeout) { + // if we weren't in a timeout state, set timeout + if (sgnTimeoutCurs == NO_CURSOR && ! sgbMouseDown) { + sgnTimeoutCurs = curs; + + NetStartTimeout(); + + // display timeout error + ClearPanel(); + AddPanelString("-- Network timeout --", TEXT_CENTER); + AddPanelString("-- Waiting for players --", TEXT_CENTER); + + // fix up the cursor + NewCursor(TIMEOUT_CURSOR); + + // we probably made a mess of the screen + force_redraw = FULLDRAW; + } + + FullBlit(TRUE); + } + else if (sgnTimeoutCurs != NO_CURSOR) { + // ending timeout + SetCursor(sgnTimeoutCurs); + sgnTimeoutCurs = NO_CURSOR; + ClearPanel(); + force_redraw = FULLDRAW; + } +} + + +//****************************************************************** +//****************************************************************** +static void game_loop(BOOL bStartup) { + int nMaxLoops = bStartup ? GAME_FRAMES_PER_SECOND * 3 : MAX_CONSECUTIVE_LOOPS; + while (nMaxLoops--) { + // wait for synchronous network message + if (! NetEndSendCycle()) { + timeout_cursor(TRUE); + break; + } + timeout_cursor(FALSE); + + // run logic at GAME_FRAMES_PER_SECOND + game_logic(); + + // if the game mode changed, then don't continue loop + if (! gbRunGame) + break; + + // don't run multiple loops in single player mode + if (gbMaxPlayers == 1) + break; + + // have we been in the loop too long? + if (! nthread_run_gameloop(TRUE)) + break; + + #if CHEATS + static DWORD sdwSkips = 0; + sdwSkips++; + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr == DD_OK) { + char szBuf[16]; + wsprintf(szBuf,"%u",sdwSkips); + TextOut(hDC,5,370,szBuf,strlen(szBuf)); + lpDDSPrimary->ReleaseDC(hDC); + } + #endif + } +} + + +//****************************************************************** +//****************************************************************** +static void DoTimedEvents() { + static DWORD sdwCurrTime = 0; + DWORD dwCurrTime = GetTickCount(); + if (dwCurrTime - sdwCurrTime < 1000/GAME_FRAMES_PER_SECOND) + return; + sdwCurrTime = dwCurrTime; + + if (leveltype == 4) + BloodCycle(); + else if (currlevel >= CRYPTSTART) + TwinCycleCrypt(); + else if (currlevel >= HIVESTART) + TwinCycleNest(); + else if (leveltype == 3 && fullscreen) + LavaCycle(); +} + + +//****************************************************************** +//****************************************************************** +/* pjw.patch1.start +static void try_game_loop(BOOL bStartup) { + DoTimedEvents(); + NetReceivePackets(); + + if (! nthread_run_gameloop(FALSE)) + return; + + // run game loop + game_loop(bStartup); + + // redraw the screen if necessary + DrawAndBlit(); +} +pjw.patch1.end */ + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +#define RAND_MASK (32*1024-1) +#define PLR_BYTES (sizeof(PlayerStruct) * MAX_PLRS) +static PlayerStruct * alloc_plr_chunk(PlayerStruct * p1) { + + // make sure p2 ends up in different locations + LPVOID pTemp = malloc(rand() & RAND_MASK); + PlayerStruct * p2 = (PlayerStruct *) malloc(PLR_BYTES); + if (pTemp) free(pTemp); + + if (! p2) return p1; + if (p1) { + CopyMemory(p2,p1,PLR_BYTES); + free(p1); + } + return p2; +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +static void alloc_plr() { + if (NULL == (plr = alloc_plr_chunk(NULL))) + app_fatal("Unable to initialize memory"); + ZeroMemory(plr,PLR_BYTES); +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +#pragma intrinsic(_rotl) +static DWORD calc_checksum(LPVOID lpMem,DWORD dwBytes,DWORD dwSum) { + LPDWORD lpDW = (LPDWORD) lpMem; + dwBytes /= sizeof(DWORD); + while (dwBytes--) { + dwSum ^= *lpDW++; + dwSum = _rotl(dwSum,3); + } + return dwSum; +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +static void CRASH() { +#if 0 // !!! @@@ !!! fix in final + static BYTE sgbCheating = FALSE; + if (! sgbCheating) { + sgbCheating = TRUE; + app_warning("Cheating detected"); + void myDebugBreak(); + myDebugBreak(); + } +#else + LPDWORD pFrame = (LPDWORD) plr[myplr]._pAnimData; + pFrame[plr[myplr]._pAnimFrame + 1] ^= 0x3fffffff; +#endif + FullBlit(TRUE); +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +typedef void (* TCrypt)(LPDWORD,DWORD,DWORD); +static void encrypt_aux(TCrypt fnCrypt) { + for (int i = 0; i < MAX_PLRS; i++) { + // SLOW encrypt the important part of the character + fnCrypt((LPDWORD)&plr[i],offsetof(PlayerStruct,_pGFXLoad),HASH_ENCRYPTKEY); + + // FAST encrypt the inventory -- takes too long otherwise + LPDWORD lpInv = (LPDWORD) &plr[i].InvBody; + for (int j = sizeof(ItemStruct) * NUM_INVLOC / sizeof(DWORD); j--; ) + *lpInv++ ^= 0xf0638142; + + // pjw.patch2.start -- commented out -- still taking too long + #if 0 + lpInv = (LPDWORD) &plr[i].InvList; + for (j = sizeof(ItemStruct) * MAXINV / sizeof(DWORD); j--; ) + *lpInv++ ^= 0x23484862; + #endif + // pjw.patch2.end + } +} +// pjw.patch1.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start +static void plr_encrypt(BOOL bEncrypt) { + static BOOL sbEncrypt = FALSE; + static BOOL sbCrash = FALSE; + static DWORD sdwCheckSum = 0; + static DWORD sdwCheckStart = 0; + if (sbEncrypt == bEncrypt) return; + sbEncrypt = bEncrypt; + +// pjw.patch2.start -- added for debugging only! +#if 0 + static DWORD sgdwEncryptCount = 0; + sgdwEncryptCount++; + static DWORD sgdwLastTime = 0; + if (GetTickCount() - sgdwLastTime >= 1000) { + sgdwLastTime = GetTickCount(); + do { + char szBuf[32]; + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr != DD_OK) break; + COLORREF oldTextColor = SetTextColor(hDC,RGB(0xff,0xff,0)); + COLORREF oldBkColor = SetBkColor(hDC,RGB(0,0,0)); + int oldBkMode = SetBkMode(hDC,OPAQUE); + sprintf(szBuf,"%u ",sgdwEncryptCount); + sgdwEncryptCount = 0; + TextOut(hDC,5,385,szBuf,strlen(szBuf)); + SetTextColor(hDC,oldTextColor); + SetBkColor(hDC,oldBkColor); + SetBkMode(hDC,oldBkMode); + lpDDSPrimary->ReleaseDC(hDC); + } while (0); + } +#endif +// pjw.patch2.end + + if (sbCrash) { + CRASH(); + } + else if (bEncrypt) { + sdwCheckStart = rand(); + sdwCheckSum = calc_checksum(plr,PLR_BYTES,sdwCheckStart); + encrypt_aux(Encrypt); + } + else { + encrypt_aux(Decrypt); + if (sdwCheckSum != calc_checksum(plr,PLR_BYTES,sdwCheckStart)) { + CRASH(); + sbCrash = 1; + } + } + + if ((rand() & 0x0f) == 0x0f) + plr = alloc_plr_chunk(plr); +} +// pjw.patch1.end diff --git a/DIABLO.ncb b/DIABLO.ncb new file mode 100644 index 0000000..5ec466a Binary files /dev/null and b/DIABLO.ncb differ diff --git a/DIABLO.sln b/DIABLO.sln new file mode 100644 index 0000000..ca6a297 --- /dev/null +++ b/DIABLO.sln @@ -0,0 +1,93 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.3.11512.155 d18.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Diablo", "Diablo.vcxproj", "{9FCF8C06-5066-4B84-87E9-64036028A392}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ui", "Uisrc\UI\ui.vcxproj", "{9B22CB13-A1A2-4701-80F8-718408AF0348}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Game", "Game", "{65ACC43A-86ED-46F0-B7CB-6F4C723EE7BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stormdll", "Storm\stormdll.vcxproj", "{43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Snp", "Snp", "{8C143F7A-F6CD-453B-85E9-DD977ACE5527}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Battle", "Storm\SOURCE\BATTLE\battle.vcxproj", "{B4E1FEBB-C3BF-3A04-7233-143B85E3413E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Standard", "Storm\SOURCE\STANDARD\Standard.vcxproj", "{AB148FBE-6646-95E7-67E4-1C1A8173D447}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + FinalFinal|Win32 = FinalFinal|Win32 + Release|Win32 = Release|Win32 + Shareware FinalFinal|Win32 = Shareware FinalFinal|Win32 + Shareware Release|Win32 = Shareware Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9FCF8C06-5066-4B84-87E9-64036028A392}.Debug|Win32.ActiveCfg = Debug|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.Debug|Win32.Build.0 = Debug|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.FinalFinal|Win32.ActiveCfg = FinalFinal|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.FinalFinal|Win32.Build.0 = FinalFinal|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.Release|Win32.ActiveCfg = Release|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.Release|Win32.Build.0 = Release|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.Shareware FinalFinal|Win32.ActiveCfg = Shareware FinalFinal|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.Shareware FinalFinal|Win32.Build.0 = Shareware FinalFinal|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.Shareware Release|Win32.ActiveCfg = Shareware Release|Win32 + {9FCF8C06-5066-4B84-87E9-64036028A392}.Shareware Release|Win32.Build.0 = Shareware Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Debug|Win32.ActiveCfg = Debug|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Debug|Win32.Build.0 = Debug|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.FinalFinal|Win32.ActiveCfg = Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.FinalFinal|Win32.Build.0 = Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Release|Win32.ActiveCfg = Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Release|Win32.Build.0 = Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Shareware FinalFinal|Win32.ActiveCfg = Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Shareware FinalFinal|Win32.Build.0 = Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Shareware Release|Win32.ActiveCfg = Release|Win32 + {9B22CB13-A1A2-4701-80F8-718408AF0348}.Shareware Release|Win32.Build.0 = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Debug|Win32.ActiveCfg = Debug|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Debug|Win32.Build.0 = Debug|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.FinalFinal|Win32.ActiveCfg = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.FinalFinal|Win32.Build.0 = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Release|Win32.ActiveCfg = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Release|Win32.Build.0 = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Shareware FinalFinal|Win32.ActiveCfg = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Shareware FinalFinal|Win32.Build.0 = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Shareware Release|Win32.ActiveCfg = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Shareware Release|Win32.Build.0 = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Debug|Win32.ActiveCfg = Debug|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Debug|Win32.Build.0 = Debug|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.FinalFinal|Win32.ActiveCfg = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.FinalFinal|Win32.Build.0 = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Release|Win32.ActiveCfg = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Release|Win32.Build.0 = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Shareware FinalFinal|Win32.ActiveCfg = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Shareware FinalFinal|Win32.Build.0 = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Shareware Release|Win32.ActiveCfg = Release|Win32 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E}.Shareware Release|Win32.Build.0 = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Debug|Win32.ActiveCfg = Debug|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Debug|Win32.Build.0 = Debug|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.FinalFinal|Win32.ActiveCfg = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.FinalFinal|Win32.Build.0 = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Release|Win32.ActiveCfg = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Release|Win32.Build.0 = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Shareware FinalFinal|Win32.ActiveCfg = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Shareware FinalFinal|Win32.Build.0 = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Shareware Release|Win32.ActiveCfg = Release|Win32 + {AB148FBE-6646-95E7-67E4-1C1A8173D447}.Shareware Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {9FCF8C06-5066-4B84-87E9-64036028A392} = {65ACC43A-86ED-46F0-B7CB-6F4C723EE7BB} + {9B22CB13-A1A2-4701-80F8-718408AF0348} = {65ACC43A-86ED-46F0-B7CB-6F4C723EE7BB} + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A} = {65ACC43A-86ED-46F0-B7CB-6F4C723EE7BB} + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E} = {8C143F7A-F6CD-453B-85E9-DD977ACE5527} + {AB148FBE-6646-95E7-67E4-1C1A8173D447} = {8C143F7A-F6CD-453B-85E9-DD977ACE5527} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B728F729-B8E0-40CD-88C5-CA1D77F12469} + EndGlobalSection +EndGlobal diff --git a/DIABLO.suo b/DIABLO.suo new file mode 100644 index 0000000..6aa12b7 Binary files /dev/null and b/DIABLO.suo differ diff --git a/DIABLOUI.H b/DIABLOUI.H new file mode 100644 index 0000000..eb7c2f4 --- /dev/null +++ b/DIABLOUI.H @@ -0,0 +1,265 @@ +//*************************************************************************** +// DiabloUI.h +// created 9.13.96 +//*************************************************************************** + + +//*************************************************************************** +extern "C" void APIENTRY UiInitialize(void); +extern "C" void APIENTRY UiSetSpawned(BOOL bSpawned); +extern "C" void APIENTRY UiDestroy(); +extern "C" void APIENTRY UiAppActivate(BOOL activating); + + +//*************************************************************************** +extern "C" BOOL CALLBACK UiCreateGameCallback (SNETCREATEDATAPTR createdata, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); + +extern "C" BOOL CALLBACK UiArtCallback (DWORD providerid, + DWORD artid, + LPPALETTEENTRY pe, + LPBYTE buffer, + DWORD buffersize, + int *width, + int *height, + int *bitdepth); + +extern "C" BOOL CALLBACK UiSoundCallback(DWORD providerid, DWORD soundid, DWORD flags); + +extern "C" BOOL CALLBACK UiDrawDescCallback (DWORD providerid, + DWORD itemtype, + LPCSTR itemname, + LPCSTR itemdescription, + DWORD itemflags, + DWORD drawflags, + DWORD time, + LPDRAWITEMSTRUCT lpdis); + +extern "C" BOOL CALLBACK UiMessageBoxCallback(HWND hWnd, + LPCTSTR lpText, + LPCTSTR lpCaption, + UINT uType); + +extern "C" BOOL CALLBACK UiAuthCallback(DWORD dwItemType, LPCSTR szName, LPCSTR szDesc, DWORD dwUserFlags, LPCSTR szItem, LPSTR szErrorBuf, DWORD dwErrorBufSize); +extern "C" BOOL CALLBACK UiGetDataCallback(DWORD providerid, DWORD dataid, LPVOID buffer, DWORD buffersize, DWORD *bytesused); + +extern "C" BOOL CALLBACK UiCategoryCallback( + BOOL userinitiated, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD * categorybits, + DWORD * categorymask); + +//*************************************************************************** +enum _ui_classes { + UI_WARRIOR = 0, + UI_ROGUE, + UI_SORCERER, + UI_MONK, + UI_BARD, + UI_BARBARIAN, + UI_NUM_CLASSES +}; + +//*************************************************************************** +extern "C" BOOL APIENTRY UiTitleDialog (UINT timeoutseconds); +extern "C" BOOL APIENTRY UiBetaDisclaimer (UINT timeoutseconds); +extern "C" BOOL APIENTRY UiCreditsDialog (UINT pixelspersec); +extern "C" BOOL APIENTRY UiSupportDialog (UINT pixelspersec); + +//*************************************************************************** +enum _copyprot_results { + COPYPROT_OK = 1, + COPYPROT_CANCEL +}; +extern "C" BOOL APIENTRY UiCopyProtError (DWORD *result); + +//*************************************************************************** +#define DEFAULT_ATTRACT_TIMEOUT 30 +typedef void (CALLBACK *PLAYSND)(LPCSTR); +enum _mainmenu_selections { + MAINMENU_SINGLE_PLAYER = 1, + MAINMENU_MULTIPLAYER, + MAINMENU_REPLAY_INTRO, + MAINMENU_SUPPORT, + MAINMENU_SHOW_CREDITS, + MAINMENU_EXIT_DIABLO, + MAINMENU_ATTRACT_MODE +}; +extern "C" BOOL APIENTRY UiMainMenuDialog(LPCTSTR registration, + DWORD * selection, + bool allowMultiPlayer, + PLAYSND sndfcn = NULL, + UINT attracttimeoutseconds = DEFAULT_ATTRACT_TIMEOUT); + +//*************************************************************************** +#define MAX_GAME_LEN 32 +#define MAX_PASSWORD_LEN 32 + +enum _difficulty { + DIFF_NORMAL, + DIFF_NIGHTMARE, + DIFF_HELL, + NUM_DIFFICULTIES +}; + + +typedef struct _gamedata TGAMEDATA; +struct _gamedata { + DWORD dwSeed; + BYTE bDiff; // Use enum's from _difficulty settings +}; + + +//*************************************************************************** +//*************************************************************************** +// all the functions and structures for selecting/creating/deleting heros +//*************************************************************************** +//*************************************************************************** +#define MAX_NAME_LEN 16 // including terminting char +#define MAX_CLASS_LEN 16 // including terminting char + +typedef struct _uiheroinfo TUIHEROINFO; +typedef TUIHEROINFO *TPUIHEROINFO; + +typedef struct _uidefaultstats { + WORD strength; + WORD magic; + WORD dexterity; + WORD vitality; +} TUIDEFSTATS, *TPUIDEFSTATS; + +struct _uiheroinfo { + TPUIHEROINFO next; + char name[MAX_NAME_LEN]; // eg "Frasier" + + WORD level; + BYTE heroclass; // UI_WARRIOR, etc. + BYTE herorank; // # of times hero has killed Diablo (range = 0..NUM_DIFFICULTIES) + + WORD strength; + WORD magic; + WORD dexterity; + WORD vitality; + + DWORD gold; + BOOL hassaved; + BOOL spawned; +}; + +//*************************************************************************** + +#define UI_DESC_MAXLENGTH 128 + +// The following routines output a null terminated string to the provided preallocated +// pointers. The maximum length of the string is defined by the above constant. +extern "C" BOOL APIENTRY UiCreatePlayerDescription(TPUIHEROINFO pHeroInfo, DWORD dwProgramId, LPSTR pPlayerDesc); + +// Call this routine to generate a query string used by Battle.net to sort games in the +// JoinGame list. Returns the number of bytes written out to szQuery. +extern "C" int APIENTRY UiCreateGameCriteria(TPUIHEROINFO pHeroInfo, LPSTR pszQuery); + +//*************************************************************************** + +typedef BOOL (CALLBACK *ENUMHEROPROC)(TPUIHEROINFO); +typedef BOOL (CALLBACK *ENUMHEROS)(ENUMHEROPROC); +typedef BOOL (CALLBACK *CREATEHERO)(TPUIHEROINFO); +typedef BOOL (CALLBACK *DELETEHERO)(TPUIHEROINFO); +typedef BOOL (CALLBACK *GETDEFHERO)(int, TPUIDEFSTATS); + +enum _selhero_selections { + SELHERO_NEW_DUNGEON = 1, + SELHERO_CONTINUE, + SELHERO_CONNECT, + SELHERO_PREVIOUS +}; +extern "C" BOOL APIENTRY UiSelHeroSingDialog( + ENUMHEROS enumfcn, + CREATEHERO createfcn, + DELETEHERO deletefcn, + GETDEFHERO getstatsfcn, + DWORD *selection, + LPSTR heroname, + int *difficulty, + bool allowBard, + bool allowBarbarian + ); +extern "C" BOOL APIENTRY UiSelHeroMultDialog( + ENUMHEROS enumfcn, + CREATEHERO createfcn, + DELETEHERO deletefcn, + GETDEFHERO getstatsfcn, + DWORD *selection, + LPSTR heroname, + bool allowBard, + bool allowBarbarian + ); + +// if the default starting statistics for a character class change +// then Diablo.exe will have to provide this function +extern "C" BOOL CALLBACK UiGetDefaultStats(int heroclass, TPUIDEFSTATS defaultstats); + +//*************************************************************************** +extern "C" BOOL APIENTRY UiLogonDialog(HWND parent, + DWORD *selection, + LPSTR logonname, + UINT maxnamelen, + LPSTR logonpassword, + UINT maxpasswordlen); + +//*************************************************************************** +typedef int (CALLBACK *PROGRESSFCN)(void); +extern "C" BOOL APIENTRY UiProgressDialog(HWND parent, + LPCSTR progresstext, + BOOL abortable, + PROGRESSFCN progressfcn, + DWORD callspersec); + +//*************************************************************************** +extern "C" void APIENTRY UiOnPaint (LPPARAMS params); +extern "C" BOOL APIENTRY UiSetBackgroundBitmap (HWND window, + LPPALETTEENTRY palette, + LPBYTE bitmapbits, + int width, + int height); + +//*************************************************************************** +//*************************************************************************** +extern "C" BOOL APIENTRY UiSelectProvider (SNETCAPSPTR mincaps, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *providerid); +extern "C" BOOL APIENTRY UiSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); + + +//*************************************************************************** +//*************************************************************************** + #define DEVNAME_LEN SNETSPI_MAXSTRINGLENGTH + #define DEVDESC_LEN SNETSPI_MAXSTRINGLENGTH + #define MAX_DIAL_LEN 32 + enum _dialmodes { + MODE_ANSWER = (IDCANCEL + 1), + MODE_DIALOLD, + MODE_DIALNEW + }; + typedef struct _modeminfo TMODEM; + typedef TMODEM *TPMODEM; + struct _modeminfo { + TPMODEM next; + DWORD deviceid; + TCHAR devicename[DEVNAME_LEN]; + TCHAR devicedesc[DEVDESC_LEN]; + }; diff --git a/DIABLOUI.LIB b/DIABLOUI.LIB new file mode 100644 index 0000000..8c108d7 Binary files /dev/null and b/DIABLOUI.LIB differ diff --git a/DIABLOUI.LSV b/DIABLOUI.LSV new file mode 100644 index 0000000..2c45a68 Binary files /dev/null and b/DIABLOUI.LSV differ diff --git a/DIABLO~1.BCE b/DIABLO~1.BCE new file mode 100644 index 0000000..2e47a50 Binary files /dev/null and b/DIABLO~1.BCE differ diff --git a/DOOM.CPP b/DOOM.CPP new file mode 100644 index 0000000..6d88bf4 --- /dev/null +++ b/DOOM.CPP @@ -0,0 +1,162 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Map of Doom file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DOOM.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "doom.h" +#include "engine.h" +#include "control.h" +#include "gendung.h" + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +#define DOOM_NUMFRAMES 30 +#define DOOM_ENDFRAME 31 +#define DOOM_TICK 1200 // Every 20*60 (1 min) frames is next doom map cycle +#define DOOM_TOTAL (DOOM_NUMFRAMES*DOOM_TICK)+1 +#define DOOM_ANIMSPD 5 + +bool drawmapofdoom = false; +static BYTE *pDoomCel = 0; +int doomtime = 0; +static int currdoom = 0; +static int animdoomdelay = 0; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitMapOfDoomTime() +{ + if (doomtime > 0) return; + doomtime = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DoMapOfDoomTime() +{ + if (doomtime < DOOM_TOTAL) { + doomtime++; + if (doomtime == DOOM_TOTAL) { + #if !IS_VERSION(SHAREWARE) + PlayInGameMovie("gendata\\doom.smk"); + #endif + doomtime++; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +int CheckMapOfDoomTime() +{ + if (doomtime == DOOM_TOTAL) return(DOOM_ENDFRAME); + return(doomtime / DOOM_TICK); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void FreeDoomMem() +{ + if (pDoomCel != NULL) + { + DiabloFreePtr(pDoomCel); + pDoomCel = NULL; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static bool GetDoomMem() +{ + FreeDoomMem(); + pDoomCel = DiabloAllocPtrSig((227 + 1) * 1024,'DOOM'); + return (pDoomCel != 0); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static bool LoadDoomFrame() +{ + bool result = false; + +// if (currlevel < HIVESTART) +// { +// if (currdoom == DOOM_ENDFRAME) { +// strcpy(tempstr, "Items\\Map\\MapZDoom.CEL"); +// } +// else if (currdoom < 10) { +// sprintf (tempstr, "Items\\Map\\MapZ000%i.CEL", currdoom); +// } +// else sprintf (tempstr, "Items\\Map\\MapZ00%i.CEL", currdoom); +// LoadFileWithMem(tempstr, pDoomCel); +// } +// else + { + strcpy(tempstr, "Items\\Map\\MapZtown.CEL"); + if (LoadFileWithMem(tempstr, pDoomCel)) { + result = true; + } + } + return result; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitMapOfDoomView() +{ + if (GetDoomMem()) { + if (CheckMapOfDoomTime() == DOOM_ENDFRAME) currdoom = DOOM_ENDFRAME; + else currdoom = 0; + if (LoadDoomFrame()) + drawmapofdoom = true; + else + EndMapOfDoomView(); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void EndMapOfDoomView() +{ + //if (!drawmapofdoom) return; + drawmapofdoom = false; + FreeDoomMem(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawMapOfDoom() +{ + if (!drawmapofdoom) return; + +// if (currdoom != DOOM_ENDFRAME) { +// animdoomdelay++; +// if (animdoomdelay >= DOOM_ANIMSPD) { +// animdoomdelay = 0; +// currdoom++; +// if (currdoom > CheckMapOfDoomTime()) currdoom = 0; +// LoadDoomFrame(); +// } +// } + DrawCel(64, 511, pDoomCel, 1, 640); +} diff --git a/DOOM.H b/DOOM.H new file mode 100644 index 0000000..9643f05 --- /dev/null +++ b/DOOM.H @@ -0,0 +1,26 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/DOOM.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** externs +**-----------------------------------------------------------------------*/ + +extern bool drawmapofdoom; +extern int doomtime; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitMapOfDoomTime(); +void DoMapOfDoomTime(); +void InitMapOfDoomView(); +void EndMapOfDoomView(); +void DrawMapOfDoom(); diff --git a/DRLG_L1.CPP b/DRLG_L1.CPP new file mode 100644 index 0000000..5fb18aa --- /dev/null +++ b/DRLG_L1.CPP @@ -0,0 +1,3584 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Dungeon file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L1.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +** CreateL1Dungeon +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "drlg_l1.h" +#include "gendung.h" +#include "engine.h" +#include "trigs.h" +#include "lighting.h" +#include "monster.h" +#include "objects.h" +#include "quests.h" +#include "multi.h" +#include "Items.h" + +// LEVEL 1 + +#define L1NGRATE 10 // cannot be higher than 100 or less than 0 + +#define L1BGRATE 5 +#define L1RFLOOR 20 + +#define L1BWALL1 30 +#define L1BWALL2 15 +#define L1BWALL3 5 + +#define L1STATUE 10 + + +// LEVEL 2 + +#define L2NGRATE 10 // cannot be higher than 100 or less than 0 + +#define L2BGRATE 10 +#define L2RFLOOR 20 + +#define L2BWALL1 30 +#define L2BWALL2 20 +#define L2BWALL3 10 + +#define L2STATUE 10 + + +// LEVEL 3 + +#define L3NGRATE 10 // cannot be higher than 100 or less than 0 + +#define L3BGRATE 15 +#define L3RFLOOR 30 + +#define L3BWALL1 30 +#define L3BWALL2 20 +#define L3BWALL3 15 + +#define L3STATUE 10 + + +// LEVEL 4 + +#define L4NGRATE 10 // cannot be higher than 100 or less than 0 + +#define L4BGRATE 20 +#define L4RFLOOR 30 + +#define L4BWALL1 30 +#define L4BWALL2 20 +#define L4BWALL3 20 + +#define L4STATUE 10 + + +Na_Krul_Struct Na_Krul; // Info for Na-Kruls room JKE + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszRegSig2[REG_LEN] = "REGISTRATION_BLOCK"; + + +/*-----------------------------------------------------------------------** +** File Variables +**-----------------------------------------------------------------------*/ +static byte dflags[MDMAXX][MDMAXY]; +static byte* pSetPiece; +static BOOL setloadflag; + + +/*-----------------------------------------------------------------------** +** Constant arrays +**-----------------------------------------------------------------------*/ +/* +DPatsStruct DPAT[NUMDPATS] = { { 8, 4, 1, 4, 0 }, + { 8, 1, 1, 4, 0 }, + { 4, 5, 0, 4, 0 }, + { 4, 1, 1, 4, 0 }, + { 2, 5, 1, 0, 0 }, + { 2, 4, 1, 4, 0 }, + { 1, 5, 1, 0, 0 }, + { 1, 1, 1, 4, 0 }, + { 15, 5, 1, 4, 0 } }; +*/ + +static const ShadowStruct SPATS[NUMSPATS] = { + { 7, 13, 0, 13, _S6, 0, _S4 }, + { 16, 13, 0, 13, _S6, 0, _S4 }, + { 15, 13, 0, 13, _S7, 0, _S4 }, + { 5, 13, 13, 13, _S14, _S2, _S1 }, + { 5, 13, 1, 13, _S5, _S8, _S1 }, + { 5, 13, 13, 2, _S5, _S2, _S10 }, + { 5, 0, 1, 2, 0, _S8, _S10 }, + { 5, 13, 11, 13, _S5, _S9, _S1 }, + { 5, 13, 13, 12, _S5, _S2, _S11 }, + { 5, 13, 11, 12, _S12, _S9, _S11 }, + { 5, 13, 1, 12, _S5, _S8, _S11 }, + { 5, 13, 11, 2, _S5, _S9, _S10 }, + { 9, 13, 13, 13, _S6, _S2, _S4 }, + { 9, 13, 1, 13, _S6, _S8, _S4 }, + { 9, 13, 11, 13, _S13, _S9, _S4 }, + { 8, 13, 0, 13, _S6, 0, _S1 }, + { 8, 13, 0, 12, _S5, 0, _S11 }, + { 8, 0, 0, 2, 0, 0, _S10 }, + { 11, 0, 0, 13, 0, 0, _S1 }, + { 11, 13, 0, 13, _S1, 0, _S1 }, + { 11, 2, 0, 13, _S10, 0, _S1 }, + { 11, 12, 0, 13, _S11, 0, _S1 }, + { 11, 13, 11, 12, _S1, 0, _S11 }, + { 14, 0, 0, 13, 0, 0, _S1 }, + { 14, 13, 0, 13, _S1, 0, _S1 }, + { 14, 2, 0, 13, _S10, 0, _S1 }, + { 14, 12, 0, 13, _S11, 0, _S1 }, + { 14, 13, 11, 12, _S1, 0, _S11 }, + { 10, 0, 13, 0, 0, _S2, 0 }, + { 10, 13, 13, 0, _S2, _S2, 0 }, + { 10, 0, 1, 0, 0, _S8, 0 }, + { 10, 13, 11, 0, _S2, _S9, 0 }, + { 12, 0, 13, 0, 0, _S2, 0 }, + { 12, 13, 13, 0, _S2, _S2, 0 }, + { 12, 0, 1, 0, 0, _S8, 0 }, + { 12, 13, 11, 0, _S2, _S9, 0 }, + { 3, 13, 11, 12, _S12, 0, 0 } }; + +// Types for tile substitution +/* +static const byte BTYPES[NUMBLOCKS] = { 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, // L1Base + 0, 0, 0, 0, 0, 0, 0, // L1Dirt + 25, 26, 4, 28, 4, 30, 31, 6, 7, 41, 1, 2, 4, 10, 43, 40, 41, 42, 43, 14, // L1Doors + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1Big + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 80, 0, 82, 0, 0, 0, 0, 0, 0, 79, 0, 80, 0, 0, 79, 80, 0, // L1Plain + 2, 2, 2, 1, 1, 11, 25, 13, 13, 13, // L1Blood + 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 12, 0, 0, 11, 1, 11, 1, // L1Misc + 13, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1Shadow + 0, 0, 0, 0, 0, 0, 0, 0, // L1New + 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1Massac + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1DrOpen + 0, 0, 0, 0, 0, 0, 0, 0, // L1Secret + 0, 0, 0, 0, 0, 0, 0 }; // L1Dirt +*/ + +// Types for shadow pass +static const byte BSTYPES[NUMBLOCKS] = { 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, // L1Base + 0, 0, 0, 0, 0, 0, 0, // L1Dirt + 1, 2, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 5, 14, 10, 4, 14, 4, 5, // L1Doors + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1Big + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 1, 6, 7, 16, 17, 2, 1, 1, 2, 2, 1, 1, 2, 2, // L1Plain + 2, 2, 2, 1, 1, 11, 1, 13, 13, 13, // L1Blood + 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 12, 0, 0, 11, 1, 11, 1, // L1Misc + 13, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 1, 11, 2, 12, 13, 13, 13, 12, 2, 1, 2, 2, // L1Shadow + 4, 14, 4, 10, 13, 13, 4, 4, // L1New + 1, 1, 4, 2, 2, 13, 13, 13, 13, // L1Massac + 25, 26, 28, 30, 31, 41, 43, 40, 41, 42, 43, 25, 41, 43, 28, 28, // L1DrOpen + 1, 2, 25, 26, 22, 22, 25, 26, // L1Secret + 0, 0, 0, 0, 0, 0, 0 }; // L1Dirt + +// Types for tile substitution +static const byte L5BTYPES[NUMBLOCKS] = { 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, // L1Base + 0, 0, 0, 0, 0, 0, 0, // L1Dirt + 25, 26, 0, 28, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 42, 43, 0, // L1Doors + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1Big + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 80, 0, 82, 0, 0, 0, 0, 0, 0, 79, 0, 80, 0, 0, 79, 80, 0, // L1Plain + 2, 2, 2, 1, 1, 11, 25, 13, 13, 13, // L1Blood + 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 12, 0, 0, 11, 1, 11, 1, // L1Misc + 13, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1Shadow + 0, 0, 0, 0, 0, 0, 0, 0, // L1New + 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1Massac + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L1DrOpen + 0, 0, 0, 0, 0, 0, 0, 0, // L1Secret + 0, 0, 0, 0, 0, 0, 0 }; // L1Dirt + +/*-----------------------------------------------------------------------** +** Manditory mini set pieces +**-----------------------------------------------------------------------*/ +static const byte STAIRSUP[] = { 4, 4, // X size, Y size + + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_HWALL, D_HWALL, D_HWALL, D_HWALL, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + + 0, 66, 6, 0, // Pattern to sub + 63, 64, 65, 0, + 0, 67, 68, 0, + 0, 0, 0, 0 }; + +static const byte L5STAIRSUP[] = { 4, 5, // X size, Y size + + D_DIRT, D_DIRT, D_DIRT, D_DIRT, // Pattern to look for + D_DIRT, D_DIRT, D_DIRT, D_DIRT, + D_HWALL, D_HWALL, D_HWALL, D_HWALL, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + + 0, 54, 23, 0, + 0, 53, 18, 0, // Pattern to sub + 55, 56, 57, 0, + 58, 59, 60, 0, + 0, 0, 0, 0 }; + +static const byte STAIRSDOWN[] = { 4, 3, // X size, Y size + + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + + 62, 57, 58, 0, // Pattern to sub + 61, 59, 60, 0, + 0, 0, 0, 0 }; + +static const byte L5STAIRSDOWN[] = { 4, 5, + + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + + 0, 0, 52, 0, // Pattern to sub + 0, 48, 51, 0, + 0, 47, 50, 0, + 45, 46, 49, 0, + 0, 0, 0, 0 }; + + + +// Temp borrow to get this to work. JKE +static const byte WARPSTAIRS[] = { 4, 5, // X size, Y size + + D_DIRT, D_DIRT, D_DIRT, D_DIRT, // Pattern to look for + D_DIRT, D_DIRT, D_DIRT, D_DIRT, + D_HWALL, D_HWALL, D_HWALL, D_HWALL, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, + + 0, 62, 23, 0, + 0, 61, 18, 0, // Pattern to sub + 63, 64, 65, 0, + 66, 67, 68, 0, + 0, 0, 0, 0 }; + +static const byte LAMPS[] = { 2, 2, // X size, Y size + + D_FLOOR, 0, // Pattern to look for + D_FLOOR, D_FLOOR, + + 129, 0, // Pattern to sub + 130, 128 }; + + +static const byte PWATERIN[] = { 6, 6, // X size, Y size + + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + + 0, 0, 0, 0, 0, 0, // Pattern to sub + 0, 202, 200, 200, 84, 0, // Pattern to sub + 0, 199, 203, 203, 83, 0, // Pattern to sub + 0, 85, 206, 80, 81, 0, // Pattern to sub + 0, 0, 134, 135, 0, 0, // Pattern to sub + 0, 0, 0, 0, 0, 0 }; // Pattern to sub + + +//JKE Enter new swap tiles here then call placerndset() +/* +static const byte TEMPLATE[] = { 3, 3, // X size, Y size + + D_FLOOR, D_FLOOR, D_FLOOR, // Pattern to look for + D_FLOOR, D_FLOOR, D_FLOOR, + D_FLOOR, D_FLOOR, D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0, 0, 0, + 0, 0, 0}; +*/ + +// NORMAL GRATE SUBS +static const byte ARCHLEFT[] = { 1, 1, // X size, Y size + + D_AVW, // Pattern to look for + + 95 }; // Pattern to sub + +static const byte ARCHRIGHT[] = { 1, 1, // X size, Y size + + D_AHW, // Pattern to look for + + 96 }; // Pattern to sub + +static const byte GRATELEFT[] = { 1, 3, // X size, Y size + + D_VWALL, // Pattern to look for + D_VWALL, + D_VWALL, + + 91, // Pattern to sub + 90, + 89 }; + +static const byte GRATERIGHT[] = { 3, 1, // X size, Y size + + D_HWALL,D_HWALL,D_HWALL, // Pattern to look for + + 94,93,92 }; // Pattern to sub + +static const byte FLOOR1[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 97 }; // Pattern to sub + +static const byte FLOOR2[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 98 }; // Pattern to sub + +static const byte FLOOR3[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 99 }; // Pattern to sub + +static const byte FLOOR4[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 100 }; // Pattern to sub + +static const byte BIGFLOOR[] = { 3, 3, // X size, Y size + + D_FLOOR,D_FLOOR,D_FLOOR, // Pattern to look for + D_FLOOR,D_FLOOR,D_FLOOR, + D_FLOOR,D_FLOOR,D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0,101, 0, + 0, 0, 0 }; + + +// BROKEN GRATE SUBS +static const byte ARCHLEFT1A[] = { 1, 1, // X size, Y size + + D_AVW, // Pattern to look for + + 185 }; // Pattern to sub + +static const byte ARCHLEFT1B[] = { 1, 1, // X size, Y size + + D_AVW, // Pattern to look for + + 186 }; // Pattern to sub + +static const byte ARCHRIGHT1A[] = { 1, 1, // X size, Y size + + D_AHW, // Pattern to look for + + 187 }; // Pattern to sub + +static const byte ARCHRIGHT1B[] = { 1, 1, // X size, Y size + + D_AHW, // Pattern to look for + + 188 }; // Pattern to sub + +static const byte GRATELEFT1BA[] = { 1, 1, // X size, Y size + + 89, // Pattern to look for + + 173 }; // Pattern to sub + +static const byte GRATELEFT1BB[] = { 1, 1, // X size, Y size + + 89, // Pattern to look for + + 174 }; // Pattern to sub + +static const byte GRATELEFT1MA[] = { 1, 1, // X size, Y size + + 90, // Pattern to look for + + 175 }; // Pattern to sub + +static const byte GRATELEFT1MB[] = { 1, 1, // X size, Y size + + 90, // Pattern to look for + + 176 }; // Pattern to sub + +static const byte GRATELEFT1TA[] = { 1, 1, // X size, Y size + + 91, // Pattern to look for + + 177 }; // Pattern to sub + +static const byte GRATELEFT1TB[] = { 1, 1, // X size, Y size + + 91, // Pattern to look for + + 178 }; // Pattern to sub + +static const byte GRATERIGHT1RA[] = { 1, 1, // X size, Y size + + 92, // Pattern to look for + + 179 }; // Pattern to sub + +static const byte GRATERIGHT1RB[] = { 1, 1, // X size, Y size + + 92, // Pattern to look for + + 180 }; // Pattern to sub + +static const byte GRATERIGHT1MA[] = { 1, 1, // X size, Y size + + 92, // Pattern to look for + + 181 }; // Pattern to sub + +static const byte GRATERIGHT1MB[] = { 1, 1, // X size, Y size + + 92, // Pattern to look for + + 182 }; // Pattern to sub + +static const byte GRATERIGHT1LA[] = { 1, 1, // X size, Y size + + 92, // Pattern to look for + + 183 }; // Pattern to sub + +static const byte GRATERIGHT1LB[] = { 1, 1, // X size, Y size + + 92, // Pattern to look for + + 184 }; // Pattern to sub + +static const byte FLOOR1B1[] = { 1, 1, // X size, Y size + + 98, // Pattern to look for + + 189 }; // Pattern to sub + +static const byte FLOOR2B1[] = { 1, 1, // X size, Y size + + 98, // Pattern to look for + + 190 }; // Pattern to sub + +static const byte FLOOR3B1[] = { 1, 1, // X size, Y size + + 97, // Pattern to look for + + 191 }; // Pattern to sub + +static const byte FLOOR4B1[] = { 1, 1, // X size, Y size + + D_COL, // Pattern to look for + + 192 }; // Pattern to sub + +static const byte FLOOR5B1[] = { 1, 1, // X size, Y size + + 99, // Pattern to look for + + 193 }; // Pattern to sub + +static const byte FLOOR6B1[] = { 1, 1, // X size, Y size + + 99, // Pattern to look for + + 194 }; // Pattern to sub + +static const byte FLOOR7B1[] = { 1, 1, // X size, Y size + + 100, // Pattern to look for + + 195 }; // Pattern to sub + +static const byte BIGFLOORB1[] = { 1, 1, // X size, Y size + + 101, // Pattern to look for + + 196 }; + +static const byte BIGFLOORB2[] = { 1, 1, // X size, Y size + + 101, + + 197 }; + +static const byte BIGFLOORB3[] = { 1, 1, // X size, Y size + + 101, // Pattern to look for + + 198 }; + + + +// GENERAL FLOOR RUBBLE + +static const byte BIGFLOORR1[] = { 3, 3, // X size, Y size + + D_FLOOR,D_FLOOR,D_FLOOR, // Pattern to look for + D_FLOOR,D_FLOOR,D_FLOOR, + D_FLOOR,D_FLOOR,D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0,167, 0, + 0, 0, 0 }; + +static const byte BIGFLOORR2[] = { 3, 3, // X size, Y size + + D_FLOOR,D_FLOOR,D_FLOOR, // Pattern to look for + D_FLOOR,D_FLOOR,D_FLOOR, + D_FLOOR,D_FLOOR,D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0,168, 0, + 0, 0, 0 }; + +static const byte BIGFLOORR3[] = { 3, 3, // X size, Y size + + D_FLOOR,D_FLOOR,D_FLOOR, // Pattern to look for + D_FLOOR,D_FLOOR,D_FLOOR, + D_FLOOR,D_FLOOR,D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0,169, 0, + 0, 0, 0 }; + +static const byte BIGFLOORR4[] = { 3, 3, // X size, Y size + + D_FLOOR,D_FLOOR,D_FLOOR, // Pattern to look for + D_FLOOR,D_FLOOR,D_FLOOR, + D_FLOOR,D_FLOOR,D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0,170, 0, + 0, 0, 0 }; + +static const byte BIGFLOORR5[] = { 3, 3, // X size, Y size + + D_FLOOR,D_FLOOR,D_FLOOR, // Pattern to look for + D_FLOOR,D_FLOOR,D_FLOOR, + D_FLOOR,D_FLOOR,D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0,171, 0, + 0, 0, 0 }; + +static const byte BIGFLOORR6[] = { 3, 3, // X size, Y size + + D_FLOOR,D_FLOOR,D_FLOOR, // Pattern to look for + D_FLOOR,D_FLOOR,D_FLOOR, + D_FLOOR,D_FLOOR,D_FLOOR, + + 0, 0, 0, // Pattern to sub + 0,172, 0, + 0, 0, 0 }; + +static const byte FLOORR1[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 163 }; // Pattern to sub + +static const byte FLOORR2[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 164 }; // Pattern to sub + +static const byte FLOORR3[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 165 }; // Pattern to sub + +static const byte FLOORR4[] = { 1, 1, // X size, Y size + + D_FLOOR, // Pattern to look for + + 166 }; // Pattern to sub + + +// BROKEN WALL 1 +static const byte BROKEN_VWALL1[] = { 1, 1, + + D_VWALL, + + 112 }; + +static const byte BROKEN_HWALL1[] = { 1, 1, + + D_HWALL, + + 113 }; + +static const byte BROKEN_LRC1[] = { 1, 1, + + D_LRC, + + 114 }; + +static const byte BROKEN_ULC1[] = { 1, 1, + + D_ULC, + + 115 }; + +static const byte BROKEN_AULC1[] = { 1, 1, + + D_AULC, + + 116 }; + +static const byte BROKEN_URC1[] = { 1, 1, + + D_URC, + + 117 }; + +static const byte BROKEN_LLC1[] = { 1, 1, + + D_LLC, + + 118 }; + +static const byte BROKEN_AURC1[] = { 1, 1, + + D_AURC, + + 119 }; + +static const byte BROKEN_ALLC1[] = { 1, 1, + + D_ALLC, + + 120 }; + +static const byte BROKEN_TULC11[] = { 1, 1, + + D_TULC1, + + 121 }; + +static const byte BROKEN_AVW1[] = { 1, 1, + + D_AVW, + + 122 }; + +static const byte BROKEN_AHW1[] = { 1, 1, + + D_AHW, + + 123 }; + +static const byte BROKEN_FLOOR1[] = { 1, 1, + + D_FLOOR, + + 124 }; + +static const byte BROKEN_TULC21[] = { 1, 1, + + D_TULC2, + + 125 }; + +static const byte BROKEN_COL1[] = { 1, 1, + + D_COL, + + 126 }; + +static const byte BROKEN_BCAP1[] = { 1, 1, + + D_BCAP, + + 127 }; + +static const byte BROKEN_RCAP1[] = { 1, 1, + + D_RCAP, + + 128 }; + +// BROKEN WALL 2 +static const byte BROKEN_VWALL2[] = { 1, 1, + + D_VWALL, + + 129 }; + +static const byte BROKEN_HWALL2[] = { 1, 1, + + D_HWALL, + + 130 }; + +static const byte BROKEN_LRC2[] = { 1, 1, + + D_LRC, + + 131 }; + +static const byte BROKEN_ULC2[] = { 1, 1, + + D_ULC, + + 132 }; + +static const byte BROKEN_AULC2[] = { 1, 1, + + D_AULC, + + 133 }; + +static const byte BROKEN_URC2[] = { 1, 1, + + D_URC, + + 134 }; + +static const byte BROKEN_LLC2[] = { 1, 1, + + D_LLC, + + 135 }; + +static const byte BROKEN_AURC2[] = { 1, 1, + + D_AURC, + + 136 }; + +static const byte BROKEN_ALLC2[] = { 1, 1, + + D_ALLC, + + 137 }; + +static const byte BROKEN_TULC12[] = { 1, 1, + + D_TULC1, + + 138 }; + +static const byte BROKEN_AVW2[] = { 1, 1, + + D_AVW, + + 139 }; + +static const byte BROKEN_AHW2[] = { 1, 1, + + D_AHW, + + 140 }; + +static const byte BROKEN_FLOOR2[] = { 1, 1, + + D_FLOOR, + + 141 }; + +static const byte BROKEN_TULC22[] = { 1, 1, + + D_TULC2, + + 142 }; + +static const byte BROKEN_COL2[] = { 1, 1, + + D_COL, + + 143 }; + +static const byte BROKEN_BCAP2[] = { 1, 1, + + D_BCAP, + + 144 }; + +static const byte BROKEN_RCAP2[] = { 1, 1, + + D_RCAP, + + 145 }; + +// BROKEN WALL 3 +static const byte BROKEN_VWALL3[] = { 1, 1, + + D_VWALL, + + 146 }; + +static const byte BROKEN_HWALL3[] = { 1, 1, + + D_HWALL, + + 147 }; + +static const byte BROKEN_LRC3[] = { 1, 1, + + D_LRC, + + 148 }; + +static const byte BROKEN_ULC3[] = { 1, 1, + + D_ULC, + + 149 }; + +static const byte BROKEN_AULC3[] = { 1, 1, + + D_AULC, + + 150 }; + +static const byte BROKEN_URC3[] = { 1, 1, + + D_URC, + + 151 }; + +static const byte BROKEN_LLC3[] = { 1, 1, + + D_LLC, + + 152 }; + +static const byte BROKEN_AURC3[] = { 1, 1, + + D_AURC, + + 153 }; + +static const byte BROKEN_ALLC3[] = { 1, 1, + + D_ALLC, + + 154 }; + +static const byte BROKEN_TULC13[] = { 1, 1, + + D_TULC1, + + 155 }; + +static const byte BROKEN_AVW3[] = { 1, 1, + + D_AVW, + + 156 }; + +static const byte BROKEN_AHW3[] = { 1, 1, + + D_AHW, + + 157 }; + +static const byte BROKEN_FLOOR3[] = { 1, 1, + + D_FLOOR, + + 158 }; + +static const byte BROKEN_TULC23[] = { 1, 1, + + D_TULC2, + + 159 }; + +static const byte BROKEN_COL3[] = { 1, 1, + + D_COL, + + 160 }; + +static const byte BROKEN_BCAP3[] = { 1, 1, + + D_BCAP, + + 161 }; + +static const byte BROKEN_RCAP3[] = { 1, 1, + + D_RCAP, + + 162 }; + +// STATUES + +static const byte STATUE_LEFTA[] = { 1, 1, + + D_VWALL, + + 199 }; + +static const byte STATUE_LEFTB[] = { 1, 1, + + D_VWALL, + + 201 }; + +static const byte STATUE_RIGHTA[] = { 1, 1, + + D_HWALL, + + 200 }; + +static const byte STATUE_RIGHTB[] = { 1, 1, + + D_HWALL, + + 202 }; + + +// QUEST ROOMS +static byte NA_KRULS_ROOM[] = { 4, 6, // Dimensions of the room + + 115,130, 6,D_FLOOR, // Define the room + 129,108, 1,D_FLOOR, + 1,107,103,D_FLOOR, + 146,106,102,D_FLOOR, + 129,168, 1,D_FLOOR, + 7, 2, 3,D_FLOOR }; + +static byte CORNERSTONE[] = { 5, 5, + + 4, 2, 2, 2, 6, // Define the room + 1,111,172, 0, 1, + 1,172, 0, 0,25, + 1, 0, 0, 0, 1, + 7, 2, 2, 2, 3 }; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +static void DRLG_CheckDoor(int x, int y) +{ + byte mf, c; + + mf = 0; + if ((dflags[x][y] & HDOOR) == HDOOR) { + c = dungeon[x+1][y]; + if (c == D_VWALL) mf = 1; + if (c == D_ULC) mf = 1; + if (c == D_URC) mf = 1; + if (c == D_TULC1) mf = 1; + if (c == D_DH) mf = 1; + if (c == D_DURC) mf = 1; + if (mf == 1) { + dflags[x][y] ^= HDOOR; + dflags[x-1][y] |= HDOOR; + } + } + if ((dflags[x][y] & VDOOR) == VDOOR) { + c = dungeon[x][y+1]; + if (c == D_HWALL) mf = 1; + if (c == D_ULC) mf = 1; + if (c == D_LLC) mf = 1; + if (c == D_TULC2) mf = 1; + if (c == D_DV) mf = 1; + if (c == D_DLLC) mf = 1; + if (mf == 1) { + dflags[x][y] ^= VDOOR; + dflags[x][y-1] |= VDOOR; + } + } +} +*/ + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_PlaceDoor(int x, int y) +{ + byte c, df; + + if ((dflags[x][y] & SETP_BIT) == 0) { + //dungeon[x][y] = D_COL; + //dflags[x][y] = SETP_BIT; + //return; + df = dflags[x][y] & SETP_MASK; + c = dungeon[x][y]; + if (df == HDOOR) { + if ((y != 1) && (c == D_HWALL)) dungeon[x][y] = D_DRH; + if ((y != 1) && (c == D_LLC)) dungeon[x][y] = D_DRLLC; + if ((y != 1) && (c == D_TULC2)) dungeon[x][y] = D_DRHT2; + if ((y != 1) && (c == D_ULC)) dungeon[x][y] = D_DRHULC; + if ((x != 1) && (c == D_VWALL)) dungeon[x][y] = D_DRV; + if ((x != 1) && (c == D_TULC1)) dungeon[x][y] = D_DRVT1; + if ((x != 1) && (c == D_URC)) dungeon[x][y] = D_DRURC; + } + if (df == VDOOR) { + if ((x != 1) && (c == D_VWALL)) dungeon[x][y] = D_DRV; + if ((x != 1) && (c == D_URC)) dungeon[x][y] = D_DRURC; + if ((x != 1) && (c == D_TULC1)) dungeon[x][y] = D_DRVT1; + if ((x != 1) && (c == D_ULC)) dungeon[x][y] = D_DRVULC; + if ((y != 1) && (c == D_HWALL)) dungeon[x][y] = D_DRH; + if ((y != 1) && (c == D_TULC2)) dungeon[x][y] = D_DRHT2; + if ((y != 1) && (c == D_LLC)) dungeon[x][y] = D_DRLLC; + } + if (df == DDOOR) { + if ((x != 1) && (y != 1) && (c == D_ULC)) dungeon[x][y] = D_DDULC; + if ((x != 1) && (c == D_TULC1)) dungeon[x][y] = D_DRVT1; + if ((y != 1) && (c == D_TULC2)) dungeon[x][y] = D_DRHT2; + if ((y != 1) && (c == D_HWALL)) dungeon[x][y] = D_DRH; + if ((x != 1) && (c == D_VWALL)) dungeon[x][y] = D_DRV; + if ((y != 1) && (c == D_LLC)) dungeon[x][y] = D_DRLLC; + if ((x != 1) && (c == D_URC)) dungeon[x][y] = D_DRURC; + } + } + dflags[x][y] = SETP_BIT; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +static int DRLG_SubInitDoor(int v1, int v2) +{ + int rv; + + rv = random(0, 3); + if (rv == 0) rv = v1; + else if (rv == 1) rv = v2; + else if (rv == 2) rv = v1 | v2; + return(rv); +} +*/ +static void DRLG_L5Shadows() +{ + int x, y; + + for (y = 1; y < MDMAXY; y++) + { + for (x = 1; x < MDMAXX; x++) + { + switch (dungeon[x][y]) + { + case 5: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 7: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 8: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 9: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 10: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 11: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 12: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 14: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 15: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 17: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 95: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 96: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 208; + break; + + case 116: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 118: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 119: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 120: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 121: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 122: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 211; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 212; + break; + + case 123: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 125: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 126: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 128: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 133: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 135: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 136: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 137: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 213; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 214; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 138: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 139: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 215; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 216; + break; + + case 140: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 217; + break; + + case 142: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 143: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 213; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 214; + break; + + case 145: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 213; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 214; + break; + + case 150: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 217; + break; + + case 152: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 153: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 154: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 155: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 205; + break; + + case 156: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 157: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 217; + break; + + case 159: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 160: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 206; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 207; + break; + + case 162: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 209; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 210; + break; + + case 167: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 209; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 210; + break; + + case 187: + if (dungeon[x][y - 1] == D_FLOOR) + dungeon[x][y - 1] = 208; + break; + + case 185: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 186: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 203; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 204; + break; + + case 192: + if (dungeon[x - 1][y] == D_FLOOR) + dungeon[x - 1][y] = 209; + if (dungeon[x - 1][y - 1] == D_FLOOR) + dungeon[x - 1][y - 1] = 210; + break; + + + } + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L1Shadows() +{ + int x, y, i, patflag; + byte sd[2][2]; + byte tnv3; + + for (y = 1; y < MDMAXY; y++) { + for (x = 1; x < MDMAXX; x++) { + if ((x == 60) && (y == 21)) + patflag = 1; + sd[0][0] = BSTYPES[dungeon[x][y]]; + sd[1][0] = BSTYPES[dungeon[x - 1][y]]; + sd[0][1] = BSTYPES[dungeon[x][y - 1]]; + sd[1][1] = BSTYPES[dungeon[x - 1][y - 1]]; + for (i = 0; i < NUMSPATS; i++) { + if (SPATS[i].strig == sd[0][0]) { + patflag = 1; + if ((SPATS[i].s1 != 0) && (SPATS[i].s1 != sd[1][1])) patflag = 0; + if ((SPATS[i].s2 != 0) && (SPATS[i].s2 != sd[0][1])) patflag = 0; + if ((SPATS[i].s3 != 0) && (SPATS[i].s3 != sd[1][0])) patflag = 0; + if (patflag == 1) { + if ((SPATS[i].nv1 != 0) && (dflags[x - 1][y - 1] == 0)) dungeon[x - 1][y - 1] = SPATS[i].nv1; + if ((SPATS[i].nv2 != 0) && (dflags[x][y - 1] == 0)) dungeon[x][y - 1] = SPATS[i].nv2; + if ((SPATS[i].nv3 != 0) && (dflags[x - 1][y] == 0)) dungeon[x - 1][y] = SPATS[i].nv3; + } + } + + } + } + } + + // Fix grates + for (y = 1; y < MDMAXY; y++) { + for (x = 1; x < MDMAXX; x++) { + if ((dungeon[x - 1][y] == _S1) && (dflags[x - 1][y] == 0)) { + tnv3 = _S1; + if (dungeon[x][y] == 29) tnv3 = _S3; + if (dungeon[x][y] == 32) tnv3 = _S3; + if (dungeon[x][y] == 35) tnv3 = _S3; + if (dungeon[x][y] == 37) tnv3 = _S3; + if (dungeon[x][y] == 38) tnv3 = _S3; + if (dungeon[x][y] == 39) tnv3 = _S3; + dungeon[x - 1][y] = tnv3; + } + if ((dungeon[x - 1][y] == _S11) && (dflags[x - 1][y] == 0)) { + tnv3 = _S11; + if (dungeon[x][y] == 29) tnv3 = _S15; + if (dungeon[x][y] == 32) tnv3 = _S15; + if (dungeon[x][y] == 35) tnv3 = _S15; + if (dungeon[x][y] == 37) tnv3 = _S15; + if (dungeon[x][y] == 38) tnv3 = _S15; + if (dungeon[x][y] == 39) tnv3 = _S15; + dungeon[x - 1][y] = tnv3; + } + if ((dungeon[x - 1][y] == _S10) && (dflags[x - 1][y] == 0)) { + tnv3 = _S10; + if (dungeon[x][y] == 29) tnv3 = _S16; + if (dungeon[x][y] == 32) tnv3 = _S16; + if (dungeon[x][y] == 35) tnv3 = _S16; + if (dungeon[x][y] == 37) tnv3 = _S16; + if (dungeon[x][y] == 38) tnv3 = _S16; + if (dungeon[x][y] == 39) tnv3 = _S16; + dungeon[x - 1][y] = tnv3; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int DRLG_PlaceMiniSet(const byte miniset[], int tmin, int tmax, int cx, int cy, int setview, int noquad, int ldir) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int i, ii, numt; + int found; + int abort; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Number of pieces to place + if ((tmax - tmin) == 0) numt = 1; + else numt = random(0, tmax - tmin) + tmin; + + for (i = 0; i < numt; i++) { + // Random starting pos + sx = random(0, MDMAXX - sw); + sy = random(0, MDMAXY - sh); + + // Find a location for the mini set piece + found = 0; + abort = 0; + while (found == 0) { + found = 1; + if ((cx != -1) && (sx >= (cx - sw)) && (sx <= (cx + 12))) { + sx++; + //sx = random(0, MDMAXX-sw); + //sy = random(0, MDMAXY-sh); + found = 0; + } + if ((cy != -1) && (sy >= (cy - sh)) && (sy <= (cy + 12))) { + sy++; + //sx = random(0, MDMAXX-sw); + //sy = random(0, MDMAXY-sh); + found = 0; + } + switch (noquad) { + case 0: + if ((sx < cx) && (sy < cy)) found = 0; + break; + case 1: + if ((sx > cx) && (sy < cy)) found = 0; + break; + case 2: + if ((sx < cx) && (sy > cy)) found = 0; + break; + case 3: + if ((sx > cx) && (sy > cy)) found = 0; + break; + } + ii = 2; + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx + xx][sy + yy] != miniset[ii])) found = 0; + if (dflags[sx + xx][sy + yy] != 0) found = 0; + ii++; + } + } + if (found == 0) { + sx++; + if (sx == (MDMAXX - sw)) { + sx = 0; + sy++; + if (sy == (MDMAXY - sh)) sy = 0; + } + abort++; + if (abort > 4000) return(-1); + } + } + + // Place mini set piece + ii = (sh * sw) + 2; + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[ii] != 0) dungeon[sx + xx][sy + yy] = miniset[ii]; + ii++; + } + } + } + + if (miniset == PWATERIN) { + i = TransVal; + TransVal = 0; + DRLG_MRectTrans(sx + 0, sy + 2, sx + 5, sy + 4); + TransVal = i; + quests[Q_PWATER]._qtx = (sx << 1) + 5 + DIRTEDGED2; + quests[Q_PWATER]._qty = (sy << 1) + 6 + DIRTEDGED2; + } + + if (setview == 1) { + ViewX = (sx << 1) + 3 + (DIRTEDGED2); + ViewY = (sy << 1) + 4 + (DIRTEDGED2); + } + + if (ldir == LVL_DOWN) { + LvlViewX = (sx << 1) + 3 + (DIRTEDGED2); + LvlViewY = (sy << 1) + 4 + (DIRTEDGED2); + } + + if ((sx < cx) && (sy < cy)) return(0); + if ((sx > cx) && (sy < cy)) return(1); + if ((sx < cx) && (sy > cy)) return(2); + return(3); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +static void DRLG_PlaceRndSet(byte miniset[], int rndper) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int ii; + int found; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Find a location for the mini set piece + for (sy = 0; sy < (MDMAXY - sh); sy++) { + for (sx = 0; sx < (MDMAXX - sw); sx++) { + found = 1; + ii = 2; + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx+xx][sy+yy] != miniset[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + if ((found == 1) && (random(0, 100) < rndper)) { + // Place mini set piece + ii = (sh * sw) + 2; + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[ii] != 0) dungeon[sx+xx][sy+yy] = miniset[ii]; + ii++; + } + } + } + } + } +} +*/ + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L1Floor() +{ + int i, j; + long rv; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dflags[i][j] == 0) && (dungeon[i][j] == D_FLOOR)) { + rv = random(0, 3); + if (rv == 1) dungeon[i][j] = 162; + if (rv == 2) dungeon[i][j] = 163; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L1Pass3() +{ + int i, j, xx, yy; + long v1, v2, v3, v4, lv; + + // Init dungeon to dirt + lv = D_DIRT - 1; + __asm { + mov esi, dword ptr[pMegaTiles] + mov eax, dword ptr[lv]; + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov dword ptr[v1], eax + lodsw + inc eax + mov dword ptr[v2], eax + lodsw + inc eax + mov dword ptr[v3], eax + lodsw + inc eax + mov dword ptr[v4], eax + } + for (yy = 0; yy < DMAXY; yy += 2) { + for (xx = 0; xx < DMAXX; xx += 2) { + dPiece[xx][yy] = (int)v1; + dPiece[xx + 1][yy] = (int)v2; + dPiece[xx][yy + 1] = (int)v3; + dPiece[xx + 1][yy + 1] = (int)v4; + } + } + + // Convert dungeon mega tiles to mini tiles + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + lv = ((long)dungeon[i][j]) - 1; + app_assert(lv >= 0); + __asm { + mov esi, dword ptr[pMegaTiles] + mov eax, dword ptr[lv]; + shl eax, 3 + add esi, eax + xor eax, eax + lodsw + inc eax + mov dword ptr[v1], eax + lodsw + inc eax + mov dword ptr[v2], eax + lodsw + inc eax + mov dword ptr[v3], eax + lodsw + inc eax + mov dword ptr[v4], eax + } + dPiece[xx][yy] = (int)v1; + dPiece[xx + 1][yy] = (int)v2; + dPiece[xx][yy + 1] = (int)v3; + dPiece[xx + 1][yy + 1] = (int)v4; + xx += 2; + } + yy += 2; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_LoadL1SP() +{ + setloadflag = FALSE; + if (QuestStatus(Q_BUTCHER)) { + pSetPiece = LoadFileInMemSig("Levels\\L1Data\\rnd6.DUN", NULL, 'STPC'); + setloadflag = TRUE; + } + if (QuestStatus(Q_SKELKING) && (gbMaxPlayers == 1)) { + pSetPiece = LoadFileInMemSig("Levels\\L1Data\\SKngDO.DUN", NULL, 'STPC'); + setloadflag = TRUE; + } + if (QuestStatus(Q_LTBANNER)) { + pSetPiece = LoadFileInMemSig("Levels\\L1Data\\Banner2.DUN", NULL, 'STPC'); + setloadflag = TRUE; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_FreeL1SP() { + DiabloFreePtr(pSetPiece); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DRLG_Init_Globals() { + ZeroMemory(dFlags, sizeof(dFlags)); + ZeroMemory(dPlayer, sizeof(dPlayer)); + ZeroMemory(dMonster, sizeof(dMonster)); + ZeroMemory(dDead, sizeof(dDead)); + ZeroMemory(dObject, sizeof(dObject)); + ZeroMemory(dItem, sizeof(dItem)); + ZeroMemory(dMissile, sizeof(dMissile)); + ZeroMemory(dSpecial, sizeof(dSpecial)); + + // Init the light values for each piece + char cLight; + if (lightflag == 0) { + if (light4flag) cLight = 3; + else cLight = 15; + } + else { + cLight = 0; + } + FillMemory(dLight, sizeof(dLight), cLight); +} + + +static void DRLG_L5Doors() //JKE +{ + + for (int j = 0; j < DMAXY; j++) { + for (int i = 0; i < DMAXX; i++) { + // place tops of arches + int nPiece = dPiece[i][j]; + if (nPiece == 77) nPiece = 1; + else if (nPiece == 80) nPiece = 2; + else continue; + + dSpecial[i][j] = nPiece; + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_InitL1Vals() { + + for (int j = 0; j < DMAXY; j++) { + for (int i = 0; i < DMAXX; i++) { + // place tops of arches + int nPiece = dPiece[i][j]; + if (nPiece == 12) nPiece = 1; + else if (nPiece == 11) nPiece = 2; + else if (nPiece == 71) nPiece = 1; + else if (nPiece == 259) nPiece = 5; + else if (nPiece == 249) nPiece = 2; + else if (nPiece == 325) nPiece = 2; + else if (nPiece == 321) nPiece = 1; + else if (nPiece == 255) nPiece = 4; + else if (nPiece == 211) nPiece = 1; + else if (nPiece == 344) nPiece = 2; + else if (nPiece == 341) nPiece = 1; + else if (nPiece == 331) nPiece = 2; + else if (nPiece == 418) nPiece = 1; + else if (nPiece == 421) nPiece = 2; + else continue; + + dSpecial[i][j] = nPiece; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LoadL1Dungeon(char sFileName[], int vx, int vy) +{ + int i, j, rw, rh; + byte* pLevelMap, * lm; + + dminx = DIRTEDGED2; + dminy = DIRTEDGED2; + dmaxx = DMAXX - (DIRTEDGED2); + dmaxy = DMAXY - (DIRTEDGED2); + + DRLG_InitTrans(); + + // Load map + pLevelMap = LoadFileInMemSig(sFileName, NULL, 'LMPt'); + lm = pLevelMap; + + // Fill with dirt + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + dungeon[i][j] = D_DIRT; + dflags[i][j] = NODOOR; + } + } + + // Put map in dungeon + rw = *lm; + + lm += 2; + rh = *lm; + lm += 2; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*lm != 0) { + dungeon[i][j] = *lm; + dflags[i][j] |= SETP_BIT; // Don't go changin' + } + else dungeon[i][j] = D_FLOOR; + lm += 2; + } + } + + // Floor subs + DRLG_L1Floor(); + + ViewX = vx; + ViewY = vy; + + // Convert to minis + DRLG_L1Pass3(); + + DRLG_Init_Globals(); + if (currlevel < HIVESTART) // JKE NO TOPS!!! + DRLG_InitL1Vals(); + + SetMapMonsters(pLevelMap, 0, 0); + SetMapObjects(pLevelMap, 0, 0); + //SetMapItems(pLevelMap); + + // Free map + DiabloFreePtr(pLevelMap); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LoadPreL1Dungeon(char sFileName[], int vx, int vy) +{ + int i, j, rw, rh; + byte* pLevelMap, * lm; + + dminx = DIRTEDGED2; + dminy = DIRTEDGED2; + dmaxx = DMAXX - (DIRTEDGED2); + dmaxy = DMAXY - (DIRTEDGED2); + + // Load map + pLevelMap = LoadFileInMemSig(sFileName, NULL, 'LMPt'); + lm = pLevelMap; + + // Fill with dirt + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + dungeon[i][j] = D_DIRT; + dflags[i][j] = NODOOR; + } + } + + // Put map in dungeon + rw = *lm; + lm += 2; + rh = *lm; + lm += 2; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*lm != 0) { + dungeon[i][j] = *lm; + dflags[i][j] |= SETP_BIT; // Don't go changin' + } + else dungeon[i][j] = D_FLOOR; + lm += 2; + } + } + + // Floor subs + DRLG_L1Floor(); + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } + + // Free map + DiabloFreePtr(pLevelMap); +} + +/*------------------------------------------------------------------------* +** +** DRLG (5) +** drlg1 - test +** +*-------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------* +** Defines +**------------------------------------------------------------------------*/ + +#define L5DIR_HORIZ 0 +#define L5DIR_VERT 1 + +#define L5ROOM_MIN 2 +#define L5ROOM_MAX 6 + +#define L5DUNX 40 +#define L5DUNY 40 + +#define L5MIN_AREA ((L5DUNX*L5DUNY)/3) + ((L5DUNX*L5DUNY)/7) + +#define L5DX 80 +#define L5DY 80 + +byte L5dungeon[L5DX][L5DY]; +byte L5ConvTbl[16] = { 22, 13, 1, 13, 2, 13, 13, 13, 4, 13, 1, 13, 2, 13, 16, 13 }; + +/*------------------------------------------------------------------------* +** Global variables +**------------------------------------------------------------------------*/ +static BOOL HR1, HR2, HR3; +static BOOL VR1, VR2, VR3; + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static void InitL5Dungeon() +{ + int i, j; + + for (j = 0; j < L5DUNY; j++) { + for (i = 0; i < L5DUNX; i++) { + dungeon[i][j] = 0; + dflags[i][j] = NODOOR; + } + } +} + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static void L5ClearFlags() +{ + int i, j; + + for (j = 0; j < L5DUNY; j++) { + for (i = 0; i < L5DUNX; i++) dflags[i][j] &= SETP_TMASK; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void L5drawRoom(int x, int y, int w, int h) +{ + int i, j; + + + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + dungeon[i + x][j + y] = 1; + } + } +} + +/*---------------------------------------------------------------------* +** Check limits of 40 X 40 +**---------------------------------------------------------------------*/ +static BOOL L5checkRoom(int x, int y, int width, int height) +{ + int i, j; + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + if ((x + i < 0) || (x + i >= L5DUNX) || (y + j < 0) || (y + j >= L5DUNY)) return(FALSE); + if (dungeon[x + i][y + j] != 0) return(FALSE); + } + } + return(TRUE); +} + +/*---------------------------------------------------------------------** +** Generate left and right, up and down rooms +**---------------------------------------------------------------------*/ +static void L5roomGen(int x, int y, int w, int h, int dir) +{ + int rx, ry, rx2, ry2; + int height, width; + int cx1, cy1, cw, ch; + int num; + int dirProb; + int ran; + BOOL c, d; + + ran = random(0, 4); + if (dir == L5DIR_VERT) { + if (ran == 0) dirProb = L5DIR_HORIZ; + else dirProb = L5DIR_VERT; + } + else { + if (ran == 0) dirProb = L5DIR_VERT; + else dirProb = L5DIR_HORIZ; + } + switch (dirProb) { + case L5DIR_HORIZ: // left/right + // left room + num = 0; + do { + width = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1; + height = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1; + ry = y + (h / 2) - (height / 2); + rx = x - width; + cx1 = rx - 1; + cy1 = ry - 1; + cw = height + 2; + ch = width + 1; + c = L5checkRoom(cx1, cy1, cw, ch); + num++; + } while ((c == FALSE) && (num < 20)); + if (c == TRUE) L5drawRoom(rx, ry, width, height); + + // right room + rx2 = x + w; + cx1 = rx2; + cy1 = ry - 1; + ch = height + 2; + cw = width + 1; + d = L5checkRoom(cx1, cy1, cw, ch); + if (d == TRUE) L5drawRoom(rx2, ry, width, height); + if (c == TRUE) L5roomGen(rx, ry, width, height, L5DIR_VERT); + if (d == TRUE) L5roomGen(rx2, ry, width, height, L5DIR_VERT); + break; + + case L5DIR_VERT: // top/bottom + // top room + num = 0; + do { + width = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1; + height = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1; + rx = x + (w / 2) - (width / 2); + ry = y - height; + cx1 = rx - 1; + cy1 = ry - 1; + ch = height + 1; + cw = width + 2; + c = L5checkRoom(cx1, cy1, cw, ch); + num++; + + } while ((c == FALSE) && (num < 20)); + if (c == TRUE) L5drawRoom(rx, ry, width, height); + + // bottom room + ry2 = y + h; + cx1 = rx - 1; + cy1 = ry2; + ch = height + 1; + cw = width + 2; + d = L5checkRoom(cx1, cy1, cw, ch); + if (d == TRUE) L5drawRoom(rx, ry2, width, height); + if (c == TRUE) L5roomGen(rx, ry, width, height, L5DIR_HORIZ); + if (d == TRUE) L5roomGen(rx, ry2, width, height, L5DIR_HORIZ); + break; + } +} + +/*-----------------------------------------------------------------------* +** DRLG_GChamber(int sx, int sy, int topflag, int bottomflag, int leftflag, int rightflag) +**-----------------------------------------------------------------------*/ +static void L5firstRoom() +{ + int x, y; + int xs, xe, ys, ye; + + if (random(0, 2) == 0) { // vertical + ys = 1; + ye = L5DUNY - 1; + VR1 = random(0, 2); + VR2 = random(0, 2); + VR3 = random(0, 2); + if ((VR1 + VR3) <= 1) VR2 = 1; + if (VR1) L5drawRoom(15, 1, 10, 10); + else ys += 17; + if (VR2) L5drawRoom(15, 15, 10, 10); + if (VR3) L5drawRoom(15, 29, 10, 10); + else ye -= 17; + for (y = ys; y < ye; y++) { + dungeon[17][y] = 1; + dungeon[18][y] = 1; + dungeon[19][y] = 1; + dungeon[20][y] = 1; + dungeon[21][y] = 1; + dungeon[22][y] = 1; + } + if (VR1) L5roomGen(15, 1, 10, 10, L5DIR_HORIZ); + if (VR2) L5roomGen(15, 15, 10, 10, L5DIR_HORIZ); + if (VR3) L5roomGen(15, 29, 10, 10, L5DIR_HORIZ); + HR1 = HR2 = HR3 = FALSE; + } + else { // horizontal + xs = 1; + xe = L5DUNX - 1; + HR1 = random(0, 2); + HR2 = random(0, 2); + HR3 = random(0, 2); + if ((HR1 + HR3) <= 1) HR2 = 1; + if (HR1) L5drawRoom(1, 15, 10, 10); + else xs += 17; + if (HR2) L5drawRoom(15, 15, 10, 10); + if (HR3) L5drawRoom(29, 15, 10, 10); + else xe -= 17; + for (x = xs; x < xe; x++) { + dungeon[x][17] = 1; + dungeon[x][18] = 1; + dungeon[x][19] = 1; + dungeon[x][20] = 1; + dungeon[x][21] = 1; + dungeon[x][22] = 1; + } + if (HR1) L5roomGen(1, 15, 10, 10, L5DIR_VERT); + if (HR2) L5roomGen(15, 15, 10, 10, L5DIR_VERT); + if (HR3) L5roomGen(29, 15, 10, 10, L5DIR_VERT); + VR1 = VR2 = VR3 = FALSE; + } +} + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static long L5GetArea() +{ + int i, j; + long rv; + + rv = 0; + for (j = 0; j < L5DUNY; j++) { + for (i = 0; i < L5DUNX; i++) { + if (dungeon[i][j] == 1) rv++; + } + } + return(rv); +} + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static void L5makeDungeon() +{ + int i, j; + int k, l; + + for (j = 0; j < L5DUNY; j++) { + for (i = 0; i < L5DUNX; i++) { + k = i << 1; + l = j << 1; + L5dungeon[k][l] = dungeon[i][j]; + L5dungeon[k][l + 1] = dungeon[i][j]; + L5dungeon[k + 1][l] = dungeon[i][j]; + L5dungeon[k + 1][l + 1] = dungeon[i][j]; + } + } +} + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static void L5makeDmt() +{ + int i, j; + int idx; + int val; + int dmtx, dmty; + + for (j = 0; j < L5DUNY; j++) + for (i = 0; i < L5DUNX; i++) dungeon[i][j] = D_DIRT; + + dmty = 0; + for (j = 1; j <= 77; j += 2) { + dmtx = 0; + for (i = 1; i <= 77; i += 2) { + idx = L5dungeon[i][j] + (L5dungeon[i + 1][j] << 1) + + (L5dungeon[i][j + 1] << 2) + (L5dungeon[i + 1][j + 1] << 3); + + val = L5ConvTbl[idx]; + dungeon[dmtx][dmty] = val; + dmtx++; + } + dmty++; + } + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int L5HWallOk(int i, int j) +{ + int x; + BOOL wallok; + + x = 1; + while ((dungeon[i + x][j] == 13) && + (dungeon[i + x][j - 1] == 13) && + (dungeon[i + x][j + 1] == 13) && + (dflags[i + x][j] == NODOOR)) x++; + wallok = FALSE; + if ((dungeon[i + x][j] >= 3) && (dungeon[i + x][j] <= 7)) wallok = TRUE; + if ((dungeon[i + x][j] >= 16) && (dungeon[i + x][j] <= 24)) wallok = TRUE; + if (dungeon[i + x][j] == 22) wallok = FALSE; + if (x == 1) wallok = FALSE; + if (wallok) return(x); + else return(-1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int L5VWallOk(int i, int j) +{ + int y; + BOOL wallok; + + y = 1; + while ((dungeon[i][j + y] == 13) && + (dungeon[i - 1][j + y] == 13) && + (dungeon[i + 1][j + y] == 13) && + (dflags[i][j + y] == NODOOR)) y++; + wallok = FALSE; + if ((dungeon[i][j + y] >= 3) && (dungeon[i][j + y] <= 7)) wallok = TRUE; + if ((dungeon[i][j + y] >= 16) && (dungeon[i][j + y] <= 24)) wallok = TRUE; + if (dungeon[i][j + y] == 22) wallok = FALSE; + if (y == 1) wallok = FALSE; + if (wallok) return(y); + else return(-1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void L5HorizWall(int i, int j, char p, int dx) +{ + int xx; + char wt, dt; + + switch (random(0, 4)) { + case 0: + case 1: + wt = 2; // Normal solid wall + break; + case 2: + wt = 12; // Arch wall + if (p == 2) p = 12; + if (p == 4) p = 10; + break; + case 3: + wt = 36; // Grate wall + if (p == 2) p = 36; + if (p == 4) p = 27; + break; + } + + if (random(0, 6) == 5) dt = 12; // Arch + else dt = 26; // Door + + if (wt == 12) dt = 12; // If arch wall, force arch door + + dungeon[i][j] = p; + for (xx = 1; xx < dx; xx++) dungeon[i + xx][j] = wt; + xx = random(0, dx - 1) + 1; + if (dt == 12) dungeon[i + xx][j] = dt; + else { + dungeon[i + xx][j] = 2; + dflags[i + xx][j] |= HDOOR; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void L5VertWall(int i, int j, char p, int dy) +{ + int yy; + char wt, dt; + + switch (random(0, 4)) { + case 0: + case 1: + wt = 1; // Normal solid wall + break; + case 2: + wt = 11; // Arch wall + if (p == 1) p = 11; + if (p == 4) p = 14; + break; + case 3: + wt = 35; // Grate wall + if (p == 1) p = 35; + if (p == 4) p = 37; + break; + } + + if (random(0, 6) == 5) dt = 11; // Arch + else dt = 25; // Door + + if (wt == 11) dt = 11; // If arch wall, force arch door + + dungeon[i][j] = p; + for (yy = 1; yy < dy; yy++) dungeon[i][j + yy] = wt; + yy = random(0, dy - 1) + 1; + if (dt == 11) dungeon[i][j + yy] = dt; + else { + dungeon[i][j + yy] = 1; + dflags[i][j + yy] |= VDOOR; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define WALLRND 100 +static void L5AddWall() +{ + int i, j; + int x, y; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if (dflags[i][j] == 0) { + if ((dungeon[i][j] == 3) && (random(0, 100) < WALLRND)) { + x = L5HWallOk(i, j); + if (x != -1) L5HorizWall(i, j, 2, x); + } + if ((dungeon[i][j] == 3) && (random(0, 100) < WALLRND)) { + y = L5VWallOk(i, j); + if (y != -1) L5VertWall(i, j, 1, y); + } + if ((dungeon[i][j] == 6) && (random(0, 100) < WALLRND)) { + x = L5HWallOk(i, j); + if (x != -1) L5HorizWall(i, j, 4, x); + } + if ((dungeon[i][j] == 7) && (random(0, 100) < WALLRND)) { + y = L5VWallOk(i, j); + if (y != -1) L5VertWall(i, j, 4, y); + } + if ((dungeon[i][j] == 2) && (random(0, 100) < WALLRND)) { + x = L5HWallOk(i, j); + if (x != -1) L5HorizWall(i, j, 2, x); + } + if ((dungeon[i][j] == 1) && (random(0, 100) < WALLRND)) { + y = L5VWallOk(i, j); + if (y != -1) L5VertWall(i, j, 1, y); + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L5GChamber(int sx, int sy, int topflag, int bottomflag, int leftflag, int rightflag) +{ + int i, j; + + if (topflag == 1) { + // Place top row tiles + dungeon[sx + 2][sy] = D_AHW; + dungeon[sx + 3][sy] = D_AHW; + dungeon[sx + 4][sy] = D_LRC; + dungeon[sx + 7][sy] = D_ALLC; + dungeon[sx + 8][sy] = D_AHW; + dungeon[sx + 9][sy] = D_HWALL; + } + if (bottomflag == 1) { + // Place bottom row tiles + sy += 11; + dungeon[sx + 2][sy] = D_TULC1; + dungeon[sx + 3][sy] = D_AHW; + dungeon[sx + 4][sy] = D_AURC; + dungeon[sx + 7][sy] = D_AULC; + dungeon[sx + 8][sy] = D_AHW; + if (dungeon[sx + 9][sy] != D_ULC) dungeon[sx + 9][sy] = D_DULC; + sy -= 11; + } + + if (leftflag == 1) { + // Place left column tiles + dungeon[sx][sy + 2] = D_AVW; + dungeon[sx][sy + 3] = D_AVW; + dungeon[sx][sy + 4] = D_LRC; + dungeon[sx][sy + 7] = D_AURC; + dungeon[sx][sy + 8] = D_AVW; + dungeon[sx][sy + 9] = D_VWALL; + } + if (rightflag == 1) { + // Place right column tiles + sx += 11; + dungeon[sx][sy + 2] = D_TULC2; + dungeon[sx][sy + 3] = D_AVW; + dungeon[sx][sy + 4] = D_ALLC; + dungeon[sx][sy + 7] = D_AULC; + dungeon[sx][sy + 8] = D_AVW; + if (dungeon[sx][sy + 9] != D_ULC) dungeon[sx][sy + 9] = D_DULC; + sx -= 11; + } + + for (j = 1; j < 11; j++) { + for (i = 1; i < 11; i++) { + dungeon[sx + i][sy + j] = D_FLOOR; + dflags[sx + i][sy + j] |= SETP_TEMP; + } + } + dungeon[sx + 4][sy + 4] = D_COL; + dungeon[sx + 7][sy + 4] = D_COL; + dungeon[sx + 4][sy + 7] = D_COL; + dungeon[sx + 7][sy + 7] = D_COL; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DRLG_L5GHall(int x1, int y1, int x2, int y2) +{ + int i; + + // Horiz or vert? + if (y1 == y2) { + // Horiz + for (i = x1; i < x2; i++) { + dungeon[i][y1] = D_AHW; + dungeon[i][y1 + 3] = D_AHW; + } + } + else { + // Vert + for (i = y1; i < y2; i++) { + dungeon[x1][i] = D_AVW; + dungeon[x1 + 3][i] = D_AVW; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void L5tileFix() +{ + int i, j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 2) && (dungeon[i + 1][j] == 22)) dungeon[i + 1][j] = 23; + if ((dungeon[i][j] == 13) && (dungeon[i + 1][j] == 22)) dungeon[i + 1][j] = 18; + if ((dungeon[i][j] == 13) && (dungeon[i + 1][j] == 2)) dungeon[i + 1][j] = 7; + + if ((dungeon[i][j] == 6) && (dungeon[i + 1][j] == 22)) dungeon[i + 1][j] = 24; + + if ((dungeon[i][j] == 1) && (dungeon[i][j + 1] == 22)) dungeon[i][j + 1] = 24; + if ((dungeon[i][j] == 13) && (dungeon[i][j + 1] == 1)) dungeon[i][j + 1] = 6; + if ((dungeon[i][j] == 13) && (dungeon[i][j + 1] == 22)) dungeon[i][j + 1] = 19; + } + } + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 13) && (dungeon[i + 1][j] == 19)) dungeon[i + 1][j] = 21; + if ((dungeon[i][j] == 13) && (dungeon[i + 1][j] == 22)) dungeon[i + 1][j] = 20; + if ((dungeon[i][j] == 7) && (dungeon[i + 1][j] == 22)) dungeon[i + 1][j] = 23; + if ((dungeon[i][j] == 13) && (dungeon[i + 1][j] == 24)) dungeon[i + 1][j] = 21; + if ((dungeon[i][j] == 19) && (dungeon[i + 1][j] == 22)) dungeon[i + 1][j] = 20; + if ((dungeon[i][j] == 2) && (dungeon[i + 1][j] == 19)) dungeon[i + 1][j] = 21; + if ((dungeon[i][j] == 19) && (dungeon[i + 1][j] == 1)) dungeon[i + 1][j] = 6; + if ((dungeon[i][j] == 7) && (dungeon[i + 1][j] == 19)) dungeon[i + 1][j] = 21; + if ((dungeon[i][j] == 2) && (dungeon[i + 1][j] == 1)) dungeon[i + 1][j] = 6; + if ((dungeon[i][j] == 3) && (dungeon[i + 1][j] == 22)) dungeon[i + 1][j] = 24; + if ((dungeon[i][j] == 21) && (dungeon[i + 1][j] == 1)) dungeon[i + 1][j] = 6; + if ((dungeon[i][j] == 7) && (dungeon[i + 1][j] == 1)) dungeon[i + 1][j] = 6; + if ((dungeon[i][j] == 7) && (dungeon[i + 1][j] == 24)) dungeon[i + 1][j] = 21; + if ((dungeon[i][j] == 4) && (dungeon[i + 1][j] == 16)) dungeon[i + 1][j] = 17; + if ((dungeon[i][j] == 7) && (dungeon[i + 1][j] == 13)) dungeon[i + 1][j] = 17; + if ((dungeon[i][j] == 2) && (dungeon[i + 1][j] == 24)) dungeon[i + 1][j] = 21; + if ((dungeon[i][j] == 2) && (dungeon[i + 1][j] == 13)) dungeon[i + 1][j] = 17; + + if ((dungeon[i][j] == 23) && (dungeon[i - 1][j] == 22)) dungeon[i - 1][j] = 19; + if ((dungeon[i][j] == 19) && (dungeon[i - 1][j] == 23)) dungeon[i - 1][j] = 21; + if ((dungeon[i][j] == 6) && (dungeon[i - 1][j] == 22)) dungeon[i - 1][j] = 24; + if ((dungeon[i][j] == 6) && (dungeon[i - 1][j] == 23)) dungeon[i - 1][j] = 21; + + if ((dungeon[i][j] == 1) && (dungeon[i][j + 1] == 2)) dungeon[i][j + 1] = 7; + if ((dungeon[i][j] == 6) && (dungeon[i][j + 1] == 18)) dungeon[i][j + 1] = 21; + if ((dungeon[i][j] == 18) && (dungeon[i][j + 1] == 2)) dungeon[i][j + 1] = 7; + if ((dungeon[i][j] == 6) && (dungeon[i][j + 1] == 2)) dungeon[i][j + 1] = 7; + if ((dungeon[i][j] == 21) && (dungeon[i][j + 1] == 2)) dungeon[i][j + 1] = 7; + if ((dungeon[i][j] == 6) && (dungeon[i][j + 1] == 22)) dungeon[i][j + 1] = 24; + if ((dungeon[i][j] == 6) && (dungeon[i][j + 1] == 13)) dungeon[i][j + 1] = 16; + if ((dungeon[i][j] == 1) && (dungeon[i][j + 1] == 13)) dungeon[i][j + 1] = 16; + if ((dungeon[i][j] == 13) && (dungeon[i][j + 1] == 16)) dungeon[i][j + 1] = 17; + + if ((dungeon[i][j] == 6) && (dungeon[i][j - 1] == 22)) dungeon[i][j - 1] = 7; + if ((dungeon[i][j] == 6) && (dungeon[i][j - 1] == 22)) dungeon[i][j - 1] = 24; + if ((dungeon[i][j] == 7) && (dungeon[i][j - 1] == 24)) dungeon[i][j - 1] = 21; + if ((dungeon[i][j] == 18) && (dungeon[i][j - 1] == 24)) dungeon[i][j - 1] = 21; + } + } + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 4) && (dungeon[i][j + 1] == 2)) dungeon[i][j + 1] = 7; + if ((dungeon[i][j] == 2) && (dungeon[i + 1][j] == 19)) dungeon[i + 1][j] = 21; + if ((dungeon[i][j] == 18) && (dungeon[i][j + 1] == 22)) dungeon[i][j + 1] = 20; + } + } +} + +static void DRLG_L5PlaceRndSet(const byte miniset[], int rndper) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int ii, kk; + int found; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Find a location for the mini set piece + for (sy = 0; sy < (MDMAXY - sh); sy++) { + for (sx = 0; sx < (MDMAXX - sw); sx++) { + found = 1; + ii = 2; + + // if (((sx >= SP3x1) && (sx <= SP3x2)) && ((sy >= SP3y1) && (sy <= SP3y2))) found = 0; + + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx + xx][sy + yy] != miniset[ii])) found = 0; + if (dflags[sx + xx][sy + yy] != 0) found = 0; + ii++; + } + } + + kk = (sh * sw) + 2; + if (miniset[kk] >= 84 && miniset[kk] <= 100 && found == 1) { + if (dungeon[sx - 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) found = 0; + if (dungeon[sx + 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) found = 0; + if (dungeon[sx][sy + 1] >= 84 && dungeon[sx - 1][sy] <= 100) found = 0; + if (dungeon[sx][sy - 1] >= 84 && dungeon[sx - 1][sy] <= 100) found = 0; + } + + if ((found == 1) && (random(0, 100) < rndper)) { + // Place mini set piece + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[kk] != 0) dungeon[sx + xx][sy + yy] = miniset[kk]; + kk++; + } + } + } + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L5Subs() +{ + int x, y, i, rv; + byte c; + + for (y = 0; y < MDMAXY; y++) { + for (x = 0; x < MDMAXX; x++) { + rv = random(0, 4); + if (rv == 0) { + c = dungeon[x][y]; + c = L5BTYPES[c]; + if ((c != 0) && (dflags[x][y] == 0)) { + rv = random(0, 16); + i = -1; + while (rv >= 0) { + i++; + if (i == NUMBLOCKS) i = 0; + if (c == L5BTYPES[i]) rv--; + } + if (i == 89) { + c = dungeon[x][y - 1]; + if ((L5BTYPES[c] == 79) && (dflags[x][y - 1] == 0)) { + dungeon[x][y - 1] = 90; + } + else i = 79; + } + if (i == 91) { + c = dungeon[x + 1][y]; + if ((L5BTYPES[c] == 80) && (dflags[x + 1][y] == 0)) { + dungeon[x + 1][y] = 92; + } + else i = 80; + } + dungeon[x][y] = i; + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DRLG_L5SetRoom(int rx1, int ry1) +{ + int rw, rh; + int i, j; + byte* sp; + + sp = pSetPiece; + rw = *sp; + sp += 2; + rh = *sp; + sp += 2; + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = rw; + setpc_h = rh; + + //DRLG_MRectTrans(rx1, ry1, rx2, ry2); + //DRLG_MRectTrans(rx1+2, ry1+2, rx2-2, ry2-2); + + sp = pSetPiece + 4; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp != 0) { + dungeon[rx1 + i][ry1 + j] = *sp; + dflags[rx1 + i][ry1 + j] |= SETP_BIT; + } + else dungeon[rx1 + i][ry1 + j] = D_FLOOR; + sp += 2; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void HRLG_L5SetRoom(int rx1, int ry1) +{ + int rw; + int i, j; + + // Don't know what these do. JKE + setpc_x = rx1; + setpc_y = ry1; + setpc_w = NA_KRULS_ROOM[0]; + setpc_h = NA_KRULS_ROOM[1]; + + Na_Krul.x = ((rx1 + 3) * 2); + Na_Krul.y = ((ry1 + 4) * 2); + Na_Krul.Books = FALSE; + Na_Krul.Open = FALSE; + Na_Krul.Lever_Thrown = FALSE; + + + rw = 2; + for (j = 0; j < NA_KRULS_ROOM[1]; j++) { + for (i = 0; i < NA_KRULS_ROOM[0]; i++) { + if (NA_KRULS_ROOM[rw] != 0) { + dungeon[rx1 + i][ry1 + j] = NA_KRULS_ROOM[rw]; + dflags[rx1 + i][ry1 + j] |= SETP_BIT; + } + else dungeon[rx1 + i][ry1 + j] = D_FLOOR; + ++rw; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void CRLG_L5SetRoom(int rx1, int ry1) +{ + int rw; + int i, j; + + // Don't know what these do. JKE + setpc_x = rx1; + setpc_y = ry1; + setpc_w = CORNERSTONE[0]; + setpc_h = CORNERSTONE[1]; + + + rw = 2; + for (j = 0; j < CORNERSTONE[1]; j++) { + for (i = 0; i < CORNERSTONE[0]; i++) { + if (CORNERSTONE[rw] != 0) { + dungeon[rx1 + i][ry1 + j] = CORNERSTONE[rw]; + dflags[rx1 + i][ry1 + j] |= SETP_BIT; + } + else dungeon[rx1 + i][ry1 + j] = D_FLOOR; + ++rw; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void L5FillChambers() +{ + int c; + + if (HR1) DRLG_L5GChamber(0, 14, 0, 0, 0, 1); + if (HR2) { + if ((HR1) && (!HR3)) DRLG_L5GChamber(14, 14, 0, 0, 1, 0); + if ((!HR1) && (HR3)) DRLG_L5GChamber(14, 14, 0, 0, 0, 1); + if ((HR1) && (HR3)) DRLG_L5GChamber(14, 14, 0, 0, 1, 1); + if ((!HR1) && (!HR3)) DRLG_L5GChamber(14, 14, 0, 0, 0, 0); + } + if (HR3) DRLG_L5GChamber(28, 14, 0, 0, 1, 0); + if ((HR1) && (HR2)) DRLG_L5GHall(12, 18, 14, 18); + if ((HR2) && (HR3)) DRLG_L5GHall(26, 18, 28, 18); + if ((HR1) && (!HR2) && (HR3)) DRLG_L5GHall(12, 18, 28, 18); + + if (VR1) DRLG_L5GChamber(14, 0, 0, 1, 0, 0); + if (VR2) { + if ((VR1) && (!VR3)) DRLG_L5GChamber(14, 14, 1, 0, 0, 0); + if ((!VR1) && (VR3)) DRLG_L5GChamber(14, 14, 0, 1, 0, 0); + if ((VR1) && (VR3)) DRLG_L5GChamber(14, 14, 1, 1, 0, 0); + if ((!VR1) && (!VR3)) DRLG_L5GChamber(14, 14, 0, 0, 0, 0); + } + if (VR3) DRLG_L5GChamber(14, 28, 1, 0, 0, 0); + if ((VR1) && (VR2)) DRLG_L5GHall(18, 12, 18, 14); + if ((VR2) && (VR3)) DRLG_L5GHall(18, 26, 18, 28); + if ((VR1) && (!VR2) && (VR3)) DRLG_L5GHall(18, 12, 18, 28); + + if (currlevel == NA_KRUL_LEVEL) + { + if ((!VR1) && (!VR2) && (!VR3)) { + // Horizontal + c = 1; // Middle room + if ((!HR1) && (HR2) && (HR3)) { + if (random(0, 2)) c = 2; + } + if ((HR1) && (HR2) && (!HR3)) { + if (random(0, 2)) c = 0; + } + if ((HR1) && (!HR2) && (HR3)) { + if (random(0, 2)) c = 0; + else c = 2; + } + if ((HR1) && (HR2) && (HR3)) c = random(0, 3); + switch (c) { + case 0: + HRLG_L5SetRoom(2, 16); + break; + case 1: + HRLG_L5SetRoom(16, 16); + break; + case 2: + HRLG_L5SetRoom(30, 16); + break; + } + } + else { + // Vertical + c = 1; // Middle room + if ((!VR1) && (VR2) && (VR3)) { + if (random(0, 2)) c = 2; + } + if ((VR1) && (VR2) && (!VR3)) { + if (random(0, 2)) c = 0; + } + if ((VR1) && (!VR2) && (VR3)) { + if (random(0, 2)) c = 0; + else c = 2; + } + if ((VR1) && (VR2) && (VR3)) c = random(0, 3); + switch (c) { + case 0: + HRLG_L5SetRoom(16, 2); + break; + case 1: + HRLG_L5SetRoom(16, 16); + break; + case 2: + HRLG_L5SetRoom(16, 30); + break; + } + } + } + if (currlevel == CORNERSTONE_LEVEL) + { + if ((!VR1) && (!VR2) && (!VR3)) { + // Horizontal + c = 1; // Middle room + if ((!HR1) && (HR2) && (HR3)) { + if (random(0, 2)) c = 2; + } + if ((HR1) && (HR2) && (!HR3)) { + if (random(0, 2)) c = 0; + } + if ((HR1) && (!HR2) && (HR3)) { + if (random(0, 2)) c = 0; + else c = 2; + } + if ((HR1) && (HR2) && (HR3)) c = random(0, 3); + switch (c) { + case 0: + CRLG_L5SetRoom(2, 16); + break; + case 1: + CRLG_L5SetRoom(16, 16); + break; + case 2: + CRLG_L5SetRoom(30, 16); + break; + } + } + else { + // Vertical + c = 1; // Middle room + if ((!VR1) && (VR2) && (VR3)) { + if (random(0, 2)) c = 2; + } + if ((VR1) && (VR2) && (!VR3)) { + if (random(0, 2)) c = 0; + } + if ((VR1) && (!VR2) && (VR3)) { + if (random(0, 2)) c = 0; + else c = 2; + } + if ((VR1) && (VR2) && (VR3)) c = random(0, 3); + switch (c) { + case 0: + CRLG_L5SetRoom(16, 2); + break; + case 1: + CRLG_L5SetRoom(16, 16); + break; + case 2: + CRLG_L5SetRoom(16, 30); + break; + } + } + } + if (setloadflag) { + if ((!VR1) && (!VR2) && (!VR3)) { + // Horizontal + c = 1; // Middle room + if ((!HR1) && (HR2) && (HR3)) { + if (random(0, 2)) c = 2; + } + if ((HR1) && (HR2) && (!HR3)) { + if (random(0, 2)) c = 0; + } + if ((HR1) && (!HR2) && (HR3)) { + if (random(0, 2)) c = 0; + else c = 2; + } + if ((HR1) && (HR2) && (HR3)) c = random(0, 3); + switch (c) { + case 0: + DRLG_L5SetRoom(2, 16); + break; + case 1: + DRLG_L5SetRoom(16, 16); + break; + case 2: + DRLG_L5SetRoom(30, 16); + break; + } + } + else { + // Vertical + c = 1; // Middle room + if ((!VR1) && (VR2) && (VR3)) { + if (random(0, 2)) c = 2; + } + if ((VR1) && (VR2) && (!VR3)) { + if (random(0, 2)) c = 0; + } + if ((VR1) && (!VR2) && (VR3)) { + if (random(0, 2)) c = 0; + else c = 2; + } + if ((VR1) && (VR2) && (VR3)) c = random(0, 3); + switch (c) { + case 0: + DRLG_L5SetRoom(16, 2); + break; + case 1: + DRLG_L5SetRoom(16, 16); + break; + case 2: + DRLG_L5SetRoom(16, 30); + break; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L5FTVR(int i, int j, int x, int y, int d) +{ + if ((dTransVal[x][y] == 0) && (dungeon[i][j] == D_FLOOR)) { + dTransVal[x][y] = TransVal; + dTransVal[x + 1][y] = TransVal; + dTransVal[x][y + 1] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + DRLG_L5FTVR(i + 1, j, x + 2, y, 1); + DRLG_L5FTVR(i - 1, j, x - 2, y, 2); + DRLG_L5FTVR(i, j + 1, x, y + 2, 3); + DRLG_L5FTVR(i, j - 1, x, y - 2, 4); + + DRLG_L5FTVR(i - 1, j - 1, x - 2, y - 2, 5); + DRLG_L5FTVR(i + 1, j - 1, x + 2, y - 2, 6); + DRLG_L5FTVR(i - 1, j + 1, x - 2, y + 2, 7); + DRLG_L5FTVR(i + 1, j + 1, x + 2, y + 2, 8); + } + else { + if (d == 1) { + dTransVal[x][y] = TransVal; + dTransVal[x][y + 1] = TransVal; + } + if (d == 2) { + dTransVal[x + 1][y] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + } + if (d == 3) { + dTransVal[x][y] = TransVal; + dTransVal[x + 1][y] = TransVal; + } + if (d == 4) { + dTransVal[x][y + 1] = TransVal; + dTransVal[x + 1][y + 1] = TransVal; + } + if (d == 5) dTransVal[x + 1][y + 1] = TransVal; + if (d == 6) dTransVal[x][y + 1] = TransVal; + if (d == 7) dTransVal[x + 1][y] = TransVal; + if (d == 8) dTransVal[x][y] = TransVal; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L5FloodTVal() +{ + int i, j; + int xx, yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == D_FLOOR) && (dTransVal[xx][yy] == 0)) { + DRLG_L5FTVR(i, j, xx, yy, 0); + TransVal++; + } + xx += 2; + } + yy += 2; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L5TransFix() +{ + int i, j; + int xx, yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == D_DURC) && (dungeon[i][j - 1] == D_DV)) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if ((dungeon[i][j] == D_DLLC) && (dungeon[i + 1][j] == D_DH)) { + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == D_DV) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == D_DH) { + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == D_DLRC) { + dTransVal[xx + 1][yy] = dTransVal[xx][yy]; + dTransVal[xx][yy + 1] = dTransVal[xx][yy]; + dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy]; + } + xx += 2; + } + yy += 2; + } +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DRLG_L5DirtFix() +{ + int i, j; + + if (currlevel < CRYPTSTART) + { + for (j = 0; j < MDMAXY - 1; j++) { + for (i = 0; i < MDMAXX - 1; i++) { + if ((dungeon[i][j] == 21) && (dungeon[i + 1][j] != 19)) dungeon[i][j] = 202; + if ((dungeon[i][j] == 19) && (dungeon[i + 1][j] != 19)) dungeon[i][j] = 200; + if ((dungeon[i][j] == 24) && (dungeon[i + 1][j] != 19)) dungeon[i][j] = 205; + + if ((dungeon[i][j] == 18) && (dungeon[i][j + 1] != 18)) dungeon[i][j] = 199; + if ((dungeon[i][j] == 21) && (dungeon[i][j + 1] != 18)) dungeon[i][j] = 202; + if ((dungeon[i][j] == 23) && (dungeon[i][j + 1] != 18)) dungeon[i][j] = 204; + } + } + } + else + { + for (j = 0; j < MDMAXY - 1; j++) { + for (i = 0; i < MDMAXX - 1; i++) { + // if ((dungeon[i][j] == 21) && (dungeon[i+1][j] != 19)) + // dungeon[i][j] = 85; + // if ((dungeon[i][j] == 19) && (dungeon[i+1][j] != 19)) + // dungeon[i][j] = 83; + // if ((dungeon[i][j] == 24) && (dungeon[i+1][j] != 19)) + // dungeon[i][j] = 88; + + // if ((dungeon[i][j] == 18) && (dungeon[i][j+1] != 18)) + // dungeon[i][j] = 82; + // if ((dungeon[i][j] == 21) && (dungeon[i][j+1] != 18)) + // dungeon[i][j] = 85; + // if ((dungeon[i][j] == 23) && (dungeon[i][j+1] != 18)) + if (dungeon[i][j] == 19) + dungeon[i][j] = 83; + if (dungeon[i][j] == 21) + dungeon[i][j] = 85; + if (dungeon[i][j] == 23) + dungeon[i][j] = 87; + if (dungeon[i][j] == 24) + dungeon[i][j] = 88; + if (dungeon[i][j] == 18) + dungeon[i][j] = 82; + + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void DRLG_L5CornerFix() +{ + int i, j; + + for (j = 1; j < MDMAXY - 1; j++) { + for (i = 1; i < MDMAXX - 1; i++) { + if (!(dflags[i][j] & SETP_BIT)) { + if ((dungeon[i][j] == 17) && (dungeon[i - 1][j] == 13) && (dungeon[i][j - 1] == 1)) { + dungeon[i][j] = 16; + dflags[i][j - 1] &= SETP_BIT; + } + } + if ((dungeon[i][j] == 202) && (dungeon[i + 1][j] == 13) && (dungeon[i][j + 1] == 1)) { + dungeon[i][j] = 8; + } + } + } +} + + +static void Statues(int chance) +{ + DRLG_L5PlaceRndSet(STATUE_LEFTA, chance); + DRLG_L5PlaceRndSet(STATUE_LEFTB, chance); + + DRLG_L5PlaceRndSet(STATUE_RIGHTA, chance); + DRLG_L5PlaceRndSet(STATUE_RIGHTB, chance); +} + +static void BrokenWall1(int chance) +{ + DRLG_L5PlaceRndSet(BROKEN_VWALL1, chance); + DRLG_L5PlaceRndSet(BROKEN_HWALL1, chance); + DRLG_L5PlaceRndSet(BROKEN_LRC1, chance); + DRLG_L5PlaceRndSet(BROKEN_ULC1, chance); + DRLG_L5PlaceRndSet(BROKEN_AULC1, chance); + DRLG_L5PlaceRndSet(BROKEN_URC1, chance); + DRLG_L5PlaceRndSet(BROKEN_LLC1, chance); + DRLG_L5PlaceRndSet(BROKEN_AURC1, chance); + DRLG_L5PlaceRndSet(BROKEN_ALLC1, chance); + DRLG_L5PlaceRndSet(BROKEN_TULC11, chance); + DRLG_L5PlaceRndSet(BROKEN_AVW1, chance); + DRLG_L5PlaceRndSet(BROKEN_AHW1, chance); + DRLG_L5PlaceRndSet(BROKEN_FLOOR1, chance); + DRLG_L5PlaceRndSet(BROKEN_TULC21, chance); + DRLG_L5PlaceRndSet(BROKEN_COL1, chance); + DRLG_L5PlaceRndSet(BROKEN_BCAP1, chance); + DRLG_L5PlaceRndSet(BROKEN_RCAP1, chance); +} + +static void BrokenWall2(int chance) +{ + DRLG_L5PlaceRndSet(BROKEN_VWALL2, chance); + DRLG_L5PlaceRndSet(BROKEN_HWALL2, chance); + DRLG_L5PlaceRndSet(BROKEN_LRC2, chance); + DRLG_L5PlaceRndSet(BROKEN_ULC2, chance); + DRLG_L5PlaceRndSet(BROKEN_AULC2, chance); + DRLG_L5PlaceRndSet(BROKEN_URC2, chance); + DRLG_L5PlaceRndSet(BROKEN_LLC2, chance); + DRLG_L5PlaceRndSet(BROKEN_AURC2, chance); + DRLG_L5PlaceRndSet(BROKEN_ALLC2, chance); + DRLG_L5PlaceRndSet(BROKEN_TULC12, chance); + DRLG_L5PlaceRndSet(BROKEN_AVW2, chance); + DRLG_L5PlaceRndSet(BROKEN_AHW2, chance); + DRLG_L5PlaceRndSet(BROKEN_FLOOR2, chance); + DRLG_L5PlaceRndSet(BROKEN_TULC22, chance); + DRLG_L5PlaceRndSet(BROKEN_COL2, chance); + DRLG_L5PlaceRndSet(BROKEN_BCAP2, chance); + DRLG_L5PlaceRndSet(BROKEN_RCAP2, chance); +} + +static void BrokenWall3(int chance) +{ + DRLG_L5PlaceRndSet(BROKEN_VWALL3, chance); + DRLG_L5PlaceRndSet(BROKEN_HWALL3, chance); + DRLG_L5PlaceRndSet(BROKEN_LRC3, chance); + DRLG_L5PlaceRndSet(BROKEN_ULC3, chance); + DRLG_L5PlaceRndSet(BROKEN_AULC3, chance); + DRLG_L5PlaceRndSet(BROKEN_URC3, chance); + DRLG_L5PlaceRndSet(BROKEN_LLC3, chance); + DRLG_L5PlaceRndSet(BROKEN_AURC3, chance); + DRLG_L5PlaceRndSet(BROKEN_ALLC3, chance); + DRLG_L5PlaceRndSet(BROKEN_TULC13, chance); + DRLG_L5PlaceRndSet(BROKEN_AVW3, chance); + DRLG_L5PlaceRndSet(BROKEN_AHW3, chance); + DRLG_L5PlaceRndSet(BROKEN_FLOOR3, chance); + DRLG_L5PlaceRndSet(BROKEN_TULC23, chance); + DRLG_L5PlaceRndSet(BROKEN_COL3, chance); + DRLG_L5PlaceRndSet(BROKEN_BCAP3, chance); + DRLG_L5PlaceRndSet(BROKEN_RCAP3, chance); +} + + + +static void FloorRubble(int chance) +{ + DRLG_L5PlaceRndSet(BIGFLOORR1, chance); + DRLG_L5PlaceRndSet(BIGFLOORR2, chance); + DRLG_L5PlaceRndSet(BIGFLOORR3, chance); + DRLG_L5PlaceRndSet(BIGFLOORR4, chance); + DRLG_L5PlaceRndSet(BIGFLOORR5, chance); + DRLG_L5PlaceRndSet(BIGFLOORR6, chance); + + DRLG_L5PlaceRndSet(FLOORR1, chance); + DRLG_L5PlaceRndSet(FLOORR2, chance); + DRLG_L5PlaceRndSet(FLOORR3, chance); + DRLG_L5PlaceRndSet(FLOORR4, chance); + +} + + + +static void BrokenGrate(int chance) +{ + DRLG_L5PlaceRndSet(ARCHLEFT1A, chance); + DRLG_L5PlaceRndSet(ARCHRIGHT1A, chance); + + DRLG_L5PlaceRndSet(ARCHLEFT1B, chance); + DRLG_L5PlaceRndSet(ARCHRIGHT1B, chance); + + + DRLG_L5PlaceRndSet(GRATELEFT1BA, chance); + DRLG_L5PlaceRndSet(GRATELEFT1BB, chance); + + DRLG_L5PlaceRndSet(GRATELEFT1MA, chance); + DRLG_L5PlaceRndSet(GRATELEFT1MB, chance); + + DRLG_L5PlaceRndSet(GRATELEFT1TA, chance); + DRLG_L5PlaceRndSet(GRATELEFT1TB, chance); + + DRLG_L5PlaceRndSet(GRATERIGHT1RA, chance); + DRLG_L5PlaceRndSet(GRATERIGHT1RB, chance); + + DRLG_L5PlaceRndSet(GRATERIGHT1MA, chance); + DRLG_L5PlaceRndSet(GRATERIGHT1MB, chance); + + DRLG_L5PlaceRndSet(GRATERIGHT1LA, chance); + DRLG_L5PlaceRndSet(GRATERIGHT1LB, chance); + + DRLG_L5PlaceRndSet(FLOOR1B1, chance); + DRLG_L5PlaceRndSet(FLOOR2B1, chance); + DRLG_L5PlaceRndSet(FLOOR3B1, chance); + DRLG_L5PlaceRndSet(FLOOR4B1, chance); + DRLG_L5PlaceRndSet(FLOOR5B1, chance); + DRLG_L5PlaceRndSet(FLOOR6B1, chance); + DRLG_L5PlaceRndSet(FLOOR7B1, chance); + + DRLG_L5PlaceRndSet(BIGFLOORB1, chance); + DRLG_L5PlaceRndSet(BIGFLOORB2, chance); + DRLG_L5PlaceRndSet(BIGFLOORB3, chance); + + +} + +static void NormalGrate(int chance) +{ + DRLG_L5PlaceRndSet(FLOOR1, chance); + DRLG_L5PlaceRndSet(FLOOR2, chance); + DRLG_L5PlaceRndSet(FLOOR3, chance); + DRLG_L5PlaceRndSet(FLOOR4, chance); +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DRLG_L5(int entry) +{ + long area, minarea; + BOOL doneflag; + int i, j; + int xx, yy; + + doneflag = FALSE; + + switch (currlevel) { + case 1: + minarea = 533; //(L5DUNX*L5DUNY)/3; + break; + case 2: + minarea = 693; //((L5DUNX*L5DUNY)/3) + ((L5DUNX*L5DUNY)/10); + break; + case 3: + case 4: + minarea = 761; //((L5DUNX*L5DUNY)/3) + ((L5DUNX*L5DUNY)/7); + break; + default: + minarea = 761; // Crypt levels + } + while (!doneflag) { + DRLG_InitTrans(); + do { + InitL5Dungeon(); + L5firstRoom(); + area = L5GetArea(); + } while (area < minarea); + L5makeDungeon(); + //if (currlevel < CRYPTSTART) + L5makeDmt(); + L5FillChambers(); + //if (currlevel < CRYPTSTART) + L5tileFix(); + + L5AddWall(); + L5ClearFlags(); + DRLG_L5FloodTVal(); + + doneflag = TRUE; + + + + if (QuestStatus(Q_PWATER)) { + if (entry == LVL_DOWN) { + if (DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, 1, -1, LVL_DOWN) < 0) doneflag = FALSE; + } + else { + if (DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, 0, -1, LVL_DOWN) < 0) doneflag = FALSE; + ViewY--; + } + } + + if (QuestStatus(Q_LTBANNER)) { //JKE This might prove a problem if the quest comes up. + if (entry == LVL_DOWN) { + if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 1, -1, LVL_DOWN) < 0) doneflag = FALSE; + } + else { + if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 0, -1, LVL_DOWN) < 0) doneflag = FALSE; + if (entry == LVL_UP) { + ViewX = (setpc_x << 1) + 4 + DIRTEDGED2; + ViewY = (setpc_y << 1) + 12 + DIRTEDGED2; + } + else + ViewY--; + } + } + else { + if (entry == LVL_DOWN) + { + if (currlevel < CRYPTSTART) + { + if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 1, -1, LVL_DOWN) < 0) doneflag = FALSE; + if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, 0, -1, LVL_UP) < 0) doneflag = FALSE; + } + else + { + if (currlevel == CRYPTSTART) // JKE set town warp up + { + if (DRLG_PlaceMiniSet(WARPSTAIRS, 1, 1, 0, 0, 0, -1, LVL_TWARPDN) < 0) doneflag = FALSE; + if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, 0, -1, LVL_UP) < 0) doneflag = FALSE; + } + else + { + + if (DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, 1, -1, LVL_DOWN) < 0) doneflag = FALSE; + if (currlevel != CRYPTEND) // no stairs down on level 20 JKE + if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, 0, -1, LVL_UP) < 0) doneflag = FALSE; + } + ++ViewY; + } + } + else { + if (entry == LVL_UP) { + if (currlevel < CRYPTSTART) + { + if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 0, -1, LVL_DOWN) < 0) doneflag = FALSE; + if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, 1, -1, LVL_UP) < 0) doneflag = FALSE; + ViewY--; + } + else + { + if (currlevel == CRYPTSTART) // JKE set town warp up + { + if (DRLG_PlaceMiniSet(WARPSTAIRS, 1, 1, 0, 0, 0, -1, LVL_TWARPDN) < 0) doneflag = FALSE; + if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, 1, -1, LVL_UP) < 0) doneflag = FALSE; + } + else + { + if (DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, 1, -1, LVL_DOWN) < 0) doneflag = FALSE; + if (currlevel != CRYPTEND) // no stairs down on level 20 JKE + if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, 1, -1, LVL_UP) < 0) doneflag = FALSE; + } + ViewY += 3; + } + } + else { + if (currlevel < CRYPTSTART) + { + if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 0, -1, LVL_DOWN) < 0) doneflag = FALSE; + if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, 0, -1, LVL_UP) < 0) doneflag = FALSE; + } + else + { + if (currlevel == CRYPTSTART) // JKE set town warp up + { + if (DRLG_PlaceMiniSet(WARPSTAIRS, 1, 1, 0, 0, 1, -1, LVL_TWARPDN) < 0) doneflag = FALSE; + if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, 0, -1, LVL_UP) < 0) doneflag = FALSE; + } + else + { + if (DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, 1, -1, LVL_DOWN) < 0) doneflag = FALSE; + if (currlevel != CRYPTEND) // no stairs down on level 20 JKE + if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, 0, -1, LVL_UP) < 0) doneflag = FALSE; + } + } + } + } + + // if (currlevel == NA_KRUL_LEVEL) + // if (DRLG_PlaceMiniSet(NA_KRULS_ROOM, 1, 1, 0, 0, 0, -1, LVL_DOWN) < 0) + // doneflag = FALSE; + } + } + + + + // Fix stair trans + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if (dungeon[i][j] == 64) { + xx = (i << 1) + DIRTEDGED2; + yy = (j << 1) + DIRTEDGED2; + DRLG_CopyTrans(xx, yy + 1, xx, yy); + DRLG_CopyTrans(xx + 1, yy + 1, xx + 1, yy); + } + } + } + + // Finish/fix trans +// if (currlevel < CRYPTSTART) + DRLG_L5TransFix(); + + // Fix dirt transparency floor corners +// if (currlevel < CRYPTSTART) + DRLG_L5DirtFix(); + + // if (currlevel < CRYPTSTART) + DRLG_L5CornerFix(); + + // Put in doors +// if (currlevel < CRYPTSTART) JKE Turn off crypt doors + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) + if ((dflags[i][j] & SETP_MASK) != NODOOR) DRLG_PlaceDoor(i, j); + } + + // Random subs + if (currlevel < CRYPTSTART) // These are to turn off stuff in the crypt JKE + DRLG_L5Subs(); + else + { + + Statues(L1STATUE); + + DRLG_L5PlaceRndSet(ARCHLEFT, 95); + DRLG_L5PlaceRndSet(ARCHRIGHT, 95); + DRLG_L5PlaceRndSet(GRATELEFT, 100); + DRLG_L5PlaceRndSet(GRATERIGHT, 100); + DRLG_L5PlaceRndSet(BIGFLOOR, 60); + + DRLG_L5Shadows(); + + switch (currlevel) + { + case CRYPTSTART: + BrokenWall1(L1BWALL1); + BrokenWall2(L1BWALL2); + BrokenWall3(L1BWALL3); + DRLG_L5Shadows(); + NormalGrate(L1NGRATE); + BrokenGrate(L1BGRATE); + FloorRubble(L1RFLOOR); + break; + case CRYPTSTART + 1: + NormalGrate(L2NGRATE); + BrokenGrate(L2BGRATE); + FloorRubble(L2RFLOOR); + BrokenWall1(L2BWALL1); + BrokenWall2(L2BWALL2); + BrokenWall3(L2BWALL3); + DRLG_L5Shadows(); + break; + case CRYPTSTART + 2: + NormalGrate(L3NGRATE); + BrokenGrate(L3BGRATE); + FloorRubble(L3RFLOOR); + BrokenWall1(L3BWALL1); + BrokenWall2(L3BWALL2); + BrokenWall3(L3BWALL3); + DRLG_L5Shadows(); + break; + default: + NormalGrate(L4NGRATE); + BrokenGrate(L4BGRATE); + FloorRubble(L4RFLOOR); + BrokenWall1(L4BWALL1); + BrokenWall2(L4BWALL2); + BrokenWall3(L4BWALL3); + DRLG_L5Shadows(); + break; + } + + } + + + // Create shadows + if (currlevel < CRYPTSTART) + DRLG_L1Shadows(); + // else + // DRLG_L5Shadows(); + + // Create mini set pieces + if (currlevel < CRYPTSTART) + DRLG_PlaceMiniSet(LAMPS, 5, 10, 0, 0, 0, -1, LVL_NODIR); + + // Floor subs + if (currlevel < CRYPTSTART) + DRLG_L1Floor(); + + // if (currlevel >= CRYPTSTART) // Place all our specifics here JKE + // { + // DRLG_L5Doors(); + // } + + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } + + DRLG_Init_Globals(); + // Check for any mini quest pieces + DRLG_CheckQuests(setpc_x, setpc_y); + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +byte L5TileType(int t) +{ + return(BTYPES[t]); +} +*/ + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +void CreateL5Dungeon(unsigned int rseed, int entry) +{ + int x, y; + + SetRndSeed(rseed); + + dminx = DIRTEDGED2; + dminy = DIRTEDGED2; + dmaxx = DMAXX - (DIRTEDGED2); + dmaxy = DMAXY - (DIRTEDGED2); + + Na_Krul.x = 0; + Na_Krul.y = 0; + Na_Krul.Books = FALSE; + Na_Krul.Open = FALSE; + Na_Krul.LeverX = 0; + Na_Krul.LeverY = 0; + Na_Krul.Lever_Thrown = FALSE; + Na_Krul.MIndex = 0; + + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_LoadL1SP(); + DRLG_L5(entry); + DRLG_L1Pass3(); + DRLG_FreeL1SP(); + if (currlevel < HIVESTART) // JKE NO TOPS!!!!! + DRLG_InitL1Vals(); + else + DRLG_L5Doors(); + DRLG_SetPC(); + + for (y = dminy; y < dmaxy; ++y) + { + for (x = dminx; x < dmaxx; ++x) + { + if (dPiece[x][y] == 290) + { + Na_Krul.x = x; + Na_Krul.y = y; + } + if (dPiece[x][y] == 317) + { + CornerStone.x = x; + CornerStone.y = y; + } + } + } +} diff --git a/DRLG_L1.H b/DRLG_L1.H new file mode 100644 index 0000000..5ab0fe2 --- /dev/null +++ b/DRLG_L1.H @@ -0,0 +1,135 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L1.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXCHRS 17 + +#define D_NULL 0 // Unused/empty space +#define D_VWALL 1 // Vertical wall +#define D_HWALL 2 // Horizontal wall +#define D_LRC 3 // Lower right corner +#define D_ULC 4 // Upper left corner +#define D_AULC 5 // Archway upper left corner +#define D_URC 6 // Upper right corner +#define D_LLC 7 // Lower left corner +#define D_AURC 8 // Archway upper right corner +#define D_ALLC 9 // Archway lower left corner +#define D_TULC1 10 // Transition piece #1 upper left corner +#define D_AVW 11 // Archway veritcal wall +#define D_AHW 12 // Archway horizontal wall +#define D_FLOOR 13 // Floor +#define D_TULC2 14 // Transition piece #2 upper left corner +#define D_COL 15 // Column +#define D_BCAP 16 // Bottom cap +#define D_RCAP 17 // Right cap + +#define D_DV 18 // Dirt with vertical edge +#define D_DH 19 // Dirt with horizontal edge +#define D_DLRC 20 // Dirt lower right corner +#define D_DULC 21 // Dirt upper left corner +#define D_DIRT 22 // Normal Dirt piece +#define D_DURC 23 // Dirt upper right corner +#define D_DLLC 24 // Dirt lower left corener + +#define D_DRV 25 // Door on a vertical wall +#define D_DRH 26 // Door on a horizontal wall +#define D_DDULC 28 // Double door upper left corner +#define D_DRURC 30 // Door on upper right corner +#define D_DRLLC 31 // Door on lower left corner +#define D_DRVT1 40 // Vertical door on transition 1 +#define D_DRVULC 41 // Vertical door on upper left corner +#define D_DRHT2 42 // Horizontal door on transition 2 +#define D_DRHULC 43 // Horizontal door on upper left corner + +#define AREAMIN 4 +#define AREAMAX 12 + +#define NODOOR 0x00 // No door flag +#define HDOOR 0x01 // Horizontal door +#define VDOOR 0x02 // Vertical door +#define DDOOR 0x03 // Double door (both dirs) +//#define SETP_BIT 0x80 // Non changeable set piece bit (defined in gendung.h) +#define SETP_MASK 0x7f +#define SETP_TEMP 0x40 // Temp non changeable set piece bit +#define SETP_TMASK 0xbf + +#define NUMDPATS 9 + +#define NUMSPATS 37 +#define _S1 139 +#define _S2 140 +#define _S3 141 +#define _S4 142 +#define _S5 143 +#define _S6 144 +#define _S7 145 +#define _S8 146 +#define _S9 147 +#define _S10 148 +#define _S11 149 +#define _S12 150 +#define _S13 151 +#define _S14 152 +#define _S15 153 +#define _S16 154 +#define _S17 155 +#define _S18 156 +#define _S19 157 + +#define NUMBLOCKS 206 + +#define NUMSETPIECES 4 + +#define NA_KRUL_LEVEL 24 // change to 24 for real game JKE +#define CORNERSTONE_LEVEL 21 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + int qpat; + int d1; + int d2; + int d3; + int d4; +} DPatsStruct; + +//JKE +typedef struct +{ + int x,y; //location of lower center door mini tile + BOOL Open; // is the place open? + BOOL Books; // were the books used to open? + + int LeverX, LeverY; + BOOL Lever_Thrown; + + int MIndex; + +} Na_Krul_Struct; + +extern Na_Krul_Struct Na_Krul; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +//void CreateL1Dungeon(unsigned int, int); +void LoadL1Dungeon(char [], int, int); +void LoadPreL1Dungeon(char [], int, int); +//void InitL1DirtQuads(); +//void DRLG_L1FloodTVal(); + +byte L5TileType(int t); +void CreateL5Dungeon(unsigned int, int); diff --git a/DRLG_L2.CPP b/DRLG_L2.CPP new file mode 100644 index 0000000..24dd70f --- /dev/null +++ b/DRLG_L2.CPP @@ -0,0 +1,3050 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Dungeon file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L2.CPP 2 1/30/97 2:43p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +** CreateL2Dungeon +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "drlg_l2.h" +#include "gendung.h" +#include "engine.h" +#include "trigs.h" +#include "lighting.h" +#include "monster.h" +#include "objects.h" +#include "quests.h" +#include "themes.h" + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszRegSig3[REG_LEN] = "REGISTRATION_BLOCK"; + +/*-----------------------------------------------------------------------** +** File Variables +**-----------------------------------------------------------------------*/ + +int Area_Min = AREA_MIN; +int Room_Max = ROOM_MAX; +//int Room_Min = ROOM_MIN; +int Room_Min = 4; + +HALLNODE * pHallList; +ROOMNODE RoomList [MAX_ROOMS + 1]; +BYTE predungeon[MDMAXX][MDMAXY]; +int Dir_Xadd[5] = {0, 0, 1, 0, -1}; +int Dir_Yadd[5] = {0, -1, 0, 1, 0}; +int nRoomCnt; +int nSx1, nSy1, nSx2, nSy2; + +ShadowStruct SPATSL2[L2_NUMSPATS] = { + { 6, 3, 0, 3, 48, 0, 50 }, + { 9, 3, 0, 3, 48, 0, 50 } +}; + +// Types for tile substitution +byte BTYPESL2[L2_NUMBLOCKS] = { 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, // L2Base + 0, 0, 0, 0, 0, 0, 0, // L2Dirt + 17, 18, // L2Tops + 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 8, // L2Misc + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L2Archs + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L2Skel + 1, 1, 1, 0, 0, 2, 2, 2, 0, 0, 0, 1, // L2Blood + 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, // L2Ruins + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 3, 0, 3, // L2Flats + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L2Big + 0, 0, 0, 0, 0, 0, + 0, 0, 0, // L2New + 0, 0, 0, 0, 0, 0, 0, // L2Dirt2 + 0, 0, 0, 0, 0, 0, 0, 0, // L2NewDrs + 0, 0, 0 }; // L2Stair2 + +byte BSTYPESL2[L2_NUMBLOCKS] = { 0, + 1, 2, 3, 0, 0, 6, 0, 0, 9, // L2Base + 0, 0, 0, 0, 0, 0, 0, // L2Dirt + 0, 0, // L2Tops + 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, // L2Misc + 6, 6, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L2Archs + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // L2Skel + 1, 1, 1, 0, 0, 2, 2, 2, 0, 0, 0, 1, // L2Blood + 1, 1, 1, 6, 2, 2, 2, 0, 3, 3, 3, 3, // L2Ruins + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, // L2Flats + 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, 3, 3, 1, 1, // L2Big + 3, 3, 2, 2, 3, 3, + 0, 0, 0, // L2New + 0, 0, 0, 0, 0, 0, 0, // L2Dirt2 + 0, 0, 0, 0, 0, 0, 0, 0, // L2NewDrs + 0, 0, 0 }; // L2Stair2 + +byte VARCH1[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, URWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH2[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, ULWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH3[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, LRWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH4[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, LLWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH5[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DURWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH6[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DULWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH7[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DLRWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH8[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DLLWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; + +byte VARCH9[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, URWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH10[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, ULWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH11[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, LRWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH12[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, LLWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH13[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DURWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH14[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DULWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH15[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DLRWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH16[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DLLWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; + +byte VARCH17[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, URWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; +byte VARCH18[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, ULWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; +byte VARCH19[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, LRWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; +byte VARCH20[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, LLWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; + +byte VARCH21[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, DURWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; +byte VARCH22[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, DULWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; +byte VARCH23[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, DLRWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; +byte VARCH24[] = { 2, 3, // X size, Y size + + HWALL_PIECE, URWALL_PIECE, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + 0, DLLWALL_PIECE, + + 141, 39, // Pattern to sub + 47, 44, + 0, 0}; + +byte VARCH25[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, URWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH26[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, ULWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH27[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, LRWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH28[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, LLWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; + +byte VARCH29[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, DURWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH30[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, DULWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH31[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, DLRWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; +byte VARCH32[] = { 2, 4, // X size, Y size + + FLOOR_PIECE, 0, // Pattern to look for + FLOOR_PIECE, VDOOR_PIECE, + FLOOR_PIECE, VWALL_PIECE, + 0, DLLWALL_PIECE, + + 48, 0, // Pattern to sub + 51, 39, + 47, 44, + 0, 0}; + +byte VARCH33[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, URWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH34[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, ULWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH35[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, LRWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH36[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, LLWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH37[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DURWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH38[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DULWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH39[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DLRWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; +byte VARCH40[] = { 2, 4, // X size, Y size + + HWALL_PIECE, 0, // Pattern to look for + FLOOR_PIECE, ULWALL_PIECE, + FLOOR_PIECE, VDOOR_PIECE, + 0, DLLWALL_PIECE, + + 142, 0, // Pattern to sub + 51, 42, + 47, 44, + 0, 0}; + + +byte HARCH1[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, LLWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH2[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, LRWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH3[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, ULWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH4[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, URWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH5[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, DLLWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH6[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, DLRWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH7[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, DULWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH8[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HWALL_PIECE, HDOOR_PIECE, DURWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; + +byte HARCH9[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, LLWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH10[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, LRWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH11[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, ULWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH12[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, URWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH13[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DLLWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH14[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DLRWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH15[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DULWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH16[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DURWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 43, 45, 0}; + +byte HARCH17[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, LLWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH18[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, LRWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH19[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, ULWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH20[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, URWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH21[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DLLWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH22[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DLRWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH23[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DULWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; +byte HARCH24[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + ULWALL_PIECE, HDOOR_PIECE, DURWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 43, 45, 0}; + +byte HARCH25[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, LLWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH26[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, LRWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH27[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, ULWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH28[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, URWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH29[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, DLLWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH30[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, DLRWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH31[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, DULWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH32[] = { 3, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, 0, // Pattern to look for + HDOOR_PIECE, HWALL_PIECE, DURWALL_PIECE, + + 49, 46, 0, // Pattern to sub + 40, 45, 0}; + +byte HARCH33[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, LLWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH34[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, LRWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH35[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, ULWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH36[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, URWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH37[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, DLLWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH38[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, DLRWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH39[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, DULWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; +byte HARCH40[] = { 3, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, 0, // Pattern to look for + LLWALL_PIECE, HDOOR_PIECE, DURWALL_PIECE, + + 140, 46, 0, // Pattern to sub + 40, 45, 0}; + +/*byte USTAIRS[] = { 6, 6, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, 0, 0, 0, // Pattern to sub + 0, 0, 0, 0, 0, 0, + 0, 0, 72, 77, 0, 0, + 0, 0, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0}; + +byte DSTAIRS[] = { 6, 6, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, 0, 0, 0, // Pattern to sub + 0, 0, 0, 0, 0, 0, + 0, 0, 48, 71, 0, 0, + 0, 0, 50, 78, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0}; */ + +byte USTAIRS[] = { 4, 4, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, 0, + 0, 72, 77, 0, + 0, 76, 0, 0, + 0, 0, 0, 0}; + +byte DSTAIRS[] = { 4, 4, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, 0, + 0, 48, 71, 0, + 0, 50, 78, 0, + 0, 0, 0, 0}; + +// add to prevent confusion with lvl1 JKE +static byte WARPSTAIRS[] = { 4, 4, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, 0, + 0, 158, 160, 0, + 0, 159, 0, 0, + 0, 0, 0, 0}; + +byte CRUSHCOL[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + HWALL_PIECE, LRWALL_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, // Pattern to sub + 0, 83, 0, + 0, 0, 0}; + +byte BIG1[] = { 2, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, + + 113, 0, // Pattern to sub + 112, 0}; + +byte BIG2[] = { 2, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, + + 114, 115, // Pattern to sub + 0, 0}; + +byte BIG3[] = { 1, 2, // X size, Y size + + VWALL_PIECE, // Pattern to look for + VWALL_PIECE, + + 117, // Pattern to sub + 116}; + +byte BIG4[] = { 2, 1, // X size, Y size + + HWALL_PIECE, HWALL_PIECE, // Pattern to look for + + 118, 119}; // Pattern to sub + +byte BIG5[] = { 2, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, + + 120, 122, // Pattern to sub + 121, 123}; + +byte BIG6[] = { 1, 2, // X size, Y size + + VWALL_PIECE, // Pattern to look for + VWALL_PIECE, + + 125, // Pattern to sub + 124}; + +byte BIG7[] = { 2, 1, // X size, Y size + + HWALL_PIECE, HWALL_PIECE, // Pattern to look for + + 126, 127}; // Pattern to sub + +byte BIG8[] = { 2, 2, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, + + 128, 130, // Pattern to sub + 129, 131}; + +byte BIG9[] = { 2, 2, // X size, Y size + + VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + VWALL_PIECE, FLOOR_PIECE, + + 133, 135, // Pattern to sub + 132, 134}; + +byte BIG10[] = { 2, 2, // X size, Y size + + HWALL_PIECE, HWALL_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, + + 136, 137, // Pattern to sub + 3, 3}; +// 138, 139}; + +byte RUINS1[] = { 1, 1, // X size, Y size + + VWALL_PIECE, // Pattern to look for + + 80}; // Pattern to sub +byte RUINS2[] = { 1, 1, // X size, Y size + + VWALL_PIECE, // Pattern to look for + + 81}; // Pattern to sub +byte RUINS3[] = { 1, 1, // X size, Y size + + VWALL_PIECE, // Pattern to look for + + 82}; // Pattern to sub + +byte RUINS4[] = { 1, 1, // X size, Y size + + HWALL_PIECE, // Pattern to look for + + 84}; // Pattern to sub +byte RUINS5[] = { 1, 1, // X size, Y size + + HWALL_PIECE, // Pattern to look for + + 85}; // Pattern to sub +byte RUINS6[] = { 1, 1, // X size, Y size + + HWALL_PIECE, // Pattern to look for + + 86}; // Pattern to sub +byte RUINS7[] = { 1, 1, // X size, Y size + + ULWALL_PIECE, // Pattern to look for + + 87}; // Pattern to sub + +byte PANCREAS1[] = { 5, 3, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, 0, 0, // Pattern to sub + 0, 0, 108, 0, 0, + 0, 0, 0, 0, 0}; + +byte PANCREAS2[] = { 5, 3, // X size, Y size + + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, // Pattern to look for + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, FLOOR_PIECE, + + 0, 0, 0, 0, 0, // Pattern to sub + 0, 0, 110, 0, 0, + 0, 0, 0, 0, 0}; + +byte CTRDOOR1[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, LLWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; +byte CTRDOOR2[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, ULWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; +byte CTRDOOR3[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, LRWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; +byte CTRDOOR4[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, URWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; +byte CTRDOOR5[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, DLLWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; +byte CTRDOOR6[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, DULWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; +byte CTRDOOR7[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, DLRWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; +byte CTRDOOR8[] = { 3, 3, // X size, Y size + + FLOOR_PIECE, VWALL_PIECE, FLOOR_PIECE, // Pattern to look for + 0, VDOOR_PIECE, 0, + 0, DURWALL_PIECE, 0, + + 0, 4, 0, // Pattern to sub + 0, 1, 0, + 0, 0, 0}; + +int Patterns[100][10] = { + {0,0,0,0,0,0,0,0,0,FLOOR_PIECE}, // catch all + + {0,0,0,0,CFLOOR,0,0,0,0,FLOOR_PIECE}, // fl + {0,CEoF,0,0,CWALL,0,0,CDoF,0,HWALL_PIECE}, // thw + {0,CDoF,0,0,CWALL,0,0,CEoF,0,HWALL_PIECE}, // bhw + {0,0,0,CEoF,CWALL,CDoF,0,0,0,VWALL_PIECE}, // lvw + {0,0,0,CDoF,CWALL,CEoF,0,0,0,VWALL_PIECE}, // rvw + {0,CWALL,0,0,CDOOR,0,0,CWALL,0,VDOOR_PIECE}, // vd + {0,0,0,CWALL,CDOOR,CWALL,0,0,0,HDOOR_PIECE}, // hd + + {0,CDoW,0,CDoW,CWALL,0,0,0,0,LRWALL_PIECE}, // lr + {0,CDoW,0,0,CWALL,CDoW,0,0,0,LLWALL_PIECE}, // ll + {0,0,0,CDoW,CWALL,0,0,CDoW,0,URWALL_PIECE}, // ur + {0,0,0,0,CWALL,CDoW,0,CDoW,0,ULWALL_PIECE}, // ul + + {0,CDoW,0,CDoW,CDoW,0,CDoWoF,CDoW,0,URWALL_PIECE}, // tint points l + {0,CDoW,CDoWoF,CDoW,CDoW,CDoW,0,0,0,LLWALL_PIECE}, // tint points u + {0,CDoW,0,0,CDoW,CDoW,0,CDoW,CDoWoF,ULWALL_PIECE}, // tint points r + + {CDoW,CDoW,CDoW,CDoW,CDoW,CDoW,0,CDoW,0,ULWALL_PIECE}, // tint points d + {CFLOOR,CDoW,CDoW,CDoW,CDoW,CDoW,0,CDoW,0,ULWALL_PIECE}, // tint points d + {CEoF,CEoF,CEoF,CDoW,CDoW,CDoW,0,CDoW,0,ULWALL_PIECE}, // tint points d + {CDoW,CDoW,CFLOOR,CDoW,CDoW,CDoW,0,CDoW,0,ULWALL_PIECE}, // tint points d + {CDoW,CFLOOR,CDoW,CDoW,CDoW,CDoW,0,CDoW,0,ULWALL_PIECE}, // tint points d + {CFLOOR,CDoW,CDoW,CDoW,CDoW,CDoW,0,CDoW,0,ULWALL_PIECE}, // tint points d + {CDoW,CEoF,CEoF,CDoW,CDoW,CDoW,0,CDoW,0,ULWALL_PIECE}, // tint points d + {CEMPTY,CEMPTY,CDoW,CDoW,CDoW,CDoW,CFLOOR,CDoW,CFLOOR,ULWALL_PIECE}, // tint points d + + {CFLOOR,CFLOOR,CFLOOR,CFLOOR,CDoW,CFLOOR,CFLOOR,CDoW,CFLOOR,URWALL_PIECE}, // line of walls topend + {CFLOOR,CFLOOR,CFLOOR,CFLOOR,CDoW,CFLOOR,CDoW,CDoW,CDoW,URWALL_PIECE}, // line of walls topend + {CFLOOR,CFLOOR,CDoW,CFLOOR,CDoW,CDoW,CFLOOR,CFLOOR,CDoW,LLWALL_PIECE}, // line of walls topend + {CFLOOR,CDoW,CFLOOR,CFLOOR,CDoW,CFLOOR,CFLOOR,CFLOOR,CFLOOR,LRWALL_PIECE}, // line of walls bottomend + {CFLOOR,CFLOOR,CFLOOR,CFLOOR,CDoW,CDoW,CFLOOR,CFLOOR,CFLOOR,LLWALL_PIECE}, // line of walls bottomend + {CFLOOR,CFLOOR,CFLOOR,CDoW,CDoW,CFLOOR,CFLOOR,CFLOOR,CFLOOR,LRWALL_PIECE}, // line of walls bottomend + {CFLOOR,CFLOOR,0,CFLOOR,CDoW,CDoW,CFLOOR,CFLOOR,0,LLWALL_PIECE}, // line of walls bottomend + + {0,0,0,0,CEMPTY,0,0,0,0,DFLOOR_PIECE}, // mt + + {0,CWALL,0,0,CWALL,CEMPTY,0,CWALL,0,DVWALL_PIECE}, // dvw + {0,0,0,CWALL,CWALL,CWALL,0,CEMPTY,0,DHWALL_PIECE}, // dhw + {0,0,0,CDoW,CWALL,CEMPTY,0,CWALL,0,DURWALL_PIECE}, // dur + {0,CDoW,0,CWALL,CWALL,0,0,CEMPTY,0,DLRWALL_PIECE}, // dlr + {0,CDoW,0,0,CWALL,CWALL,0,CEMPTY,0,DLLWALL_PIECE}, // dll + {0,0,0,0,CWALL,CWALL,0,CWALL,CEMPTY,DULWALL_PIECE}, // dul + + {CDoWoF,CDoWoF,CDoWoF,CDoWoF,CWALL,CWALL,0,CWALL,CWALL,DULWALL_PIECE}, // double hwall start + {CDoWoF,CDoWoF,CEMPTY,CDoWoF,CWALL,CWALL,0,CWALL,CWALL,DVWALL_PIECE}, // double hwall start + {0,0,0,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,DHWALL_PIECE}, // double hwall cont1 + {CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CFLOOR,CFLOOR,CDoWoF,HWALL_PIECE}, // double hwall cont2 + {0,CWALL,0,CWALL,CWALL,CEMPTY,CWALL,CWALL,0,DLRWALL_PIECE}, // double hwall end1 + {0,0,0,CWALL,CWALL,CWALL,CWALL,CWALL,CEMPTY,DHWALL_PIECE}, // double hwall end2 + {CWALL,CWALL,CEMPTY,CWALL,CWALL,CWALL,0,CFLOOR,CFLOOR,HWALL_PIECE}, // double hwall end3 + {CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CDoW,CFLOOR,CDoW,HWALL_PIECE}, // double hwall end4 + {CEMPTY,CWALL,CWALL,CWALL,CWALL,CWALL,CDoW,CFLOOR,CDoW,HWALL_PIECE}, // double hwall end5 + {CFLOOR,CFLOOR,CFLOOR,CWALL,CWALL,CWALL,CEMPTY,CWALL,CWALL,DHWALL_PIECE}, // double hwall end6 + {CEMPTY,CWALL,CWALL,CWALL,CWALL,CWALL,CFLOOR,CFLOOR,CFLOOR,HWALL_PIECE}, // double hwall end7 + {CWALL,CWALL,CEMPTY,CWALL,CWALL,CWALL,CFLOOR,CFLOOR,CWALL,HWALL_PIECE}, // double hwall end8 + {CEMPTY,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CFLOOR,CFLOOR,HWALL_PIECE}, // double hwall end9 + {CFLOOR,CFLOOR,CDoW,CWALL,CWALL,CWALL,CEMPTY,CWALL,CWALL,DHWALL_PIECE}, // double hwall end10 + {CEMPTY,CWALL,CWALL,CWALL,CWALL,CWALL,CFLOOR,CFLOOR,CDoW,HWALL_PIECE}, // double hwall end11 + {CWALL,CFLOOR,CFLOOR,CWALL,CWALL,CWALL,CEMPTY,CWALL,CWALL,DHWALL_PIECE}, // double hwall end12 + + {0,CWALL,CWALL,0,CWALL,CWALL,0,CWALL,CWALL,DVWALL_PIECE}, // double vwall cont1 + {CFLOOR,CWALL,CWALL,CDOOR,CWALL,CWALL,CFLOOR,CWALL,CWALL,DURWALL_PIECE}, // double vwall cont 1a + {CWALL,CWALL,0,CWALL,CWALL,CFLOOR,CWALL,CWALL,0,VWALL_PIECE}, // double vwall cont2 + {0,CEMPTY,0,CWALL,CWALL,CWALL,0,CWALL,CWALL,DURWALL_PIECE}, // double vwall end1 + {CEMPTY,CWALL,0,CWALL,CWALL,0,CWALL,CWALL,0,VWALL_PIECE}, // double vwall end2 + {0,CWALL,0,CEMPTY,CWALL,CWALL,0,CWALL,CWALL,DLLWALL_PIECE}, // double vwall end3 + {CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,0,CFLOOR,CFLOOR,HWALL_PIECE}, // double vwall end4 + {0,CWALL,CWALL,CFLOOR,CWALL,CWALL,CFLOOR,CWALL,CEMPTY,DVWALL_PIECE}, // double vwall end5 + {CFLOOR,CWALL,CWALL,CWALL,CWALL,CWALL,0,CEMPTY,0,DLRWALL_PIECE}, // double vwall end6 + {CWALL,CWALL,CEMPTY,CWALL,CWALL,CFLOOR,0,CWALL,CFLOOR,VWALL_PIECE}, // double vwall end7 + {CFLOOR,CWALL,CWALL,CFLOOR,CWALL,CWALL,CWALL,CWALL,CEMPTY,DVWALL_PIECE}, // double vwall end8 + {CWALL,CWALL,CFLOOR,CWALL,CWALL,CFLOOR,CEMPTY,CWALL,CDoWoF,VWALL_PIECE}, // double vwall end9 + {CFLOOR,CWALL,CEMPTY,CWALL,CWALL,CWALL,CEMPTY,CEMPTY,CWALL,DLRWALL_PIECE}, // double vwall end10 + + {CFLOOR,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,DLRWALL_PIECE}, // 2doubles LR connect + {CWALL,CWALL,CFLOOR,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,DLLWALL_PIECE}, // 2doubles LL connect + {CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CFLOOR,CWALL,CWALL,DURWALL_PIECE}, // 2doubles UR connect + {CEMPTY,CWALL,CWALL,CWALL,CWALL,CWALL,CFLOOR,CWALL,CWALL,DURWALL_PIECE}, // 2doubles UR connect + {CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CWALL,CFLOOR,ULWALL_PIECE}, // 2doubles UL connect + + {0,0,0,0,255,0,0,0,0,0} // end +}; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static BOOL DRLG_L2PlaceMiniSet(byte miniset[], int tmin, int tmax, int cx, int cy, int setview, int ldir) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int i, ii, numt; + int found, bailcnt; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Number of pieces to place + if ((tmax - tmin) == 0) numt = 1; + else numt = random(0, tmax - tmin) + tmin; + + for (i = 0; i < numt; i++) { + // Random starting pos + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + + // Find a location for the mini set piece + found = 0; + bailcnt = 0; + while ((found == 0) && (bailcnt < 200)) { + found = 1; + + if (((sx >= nSx1) && (sx <= nSx2)) && ((sy >= nSy1) && (sy <= nSy2))) found = 0; + + if ((cx != -1) && (sx >= (cx - sw)) && (sx <= (cx + 12))) { + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + found = 0; + } + if ((cy != -1) && (sy >= (cy - sh)) && (sy <= (cy + 12))) { + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + found = 0; + } + ii = 2; + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx+xx][sy+yy] != miniset[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + if (found == 0) { + sx++; + if (sx == (MDMAXX - sw)) { + sx = 0; + sy++; + if (sy == (MDMAXY - sh)) sy = 0; + } + } + bailcnt++; + } + + if (bailcnt >= 200) return(FALSE); + + // Place mini set piece + ii = (sh * sw) + 2; + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[ii] != 0) dungeon[sx+xx][sy+yy] = miniset[ii]; + ii++; + } + } + } + + if (setview == 1) { + ViewX = (sx << 1) + 3 + (DIRTEDGED2) + 2; + ViewY = (sy << 1) + 4 + (DIRTEDGED2) + 2; + } + + if (ldir == LVL_DOWN) { + LvlViewX = (sx << 1) + 3 + (DIRTEDGED2) + 2; + LvlViewY = (sy << 1) + 4 + (DIRTEDGED2) + 2; + } + + if (ldir == LVL_TWARPDN) { + LvlViewX = (sx << 1) + 3 + (DIRTEDGED2) + 2; + LvlViewY = (sy << 1) + 4 + (DIRTEDGED2) + 2; + } + + return(TRUE); +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2PlaceRndSet(byte miniset[], int rndper) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int ii, jj, kk; + int found; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Find a location for the mini set piece + for (sy = 0; sy < (MDMAXY - sh); sy++) { + for (sx = 0; sx < (MDMAXX - sw); sx++) { + found = 1; + ii = 2; + + if (((sx >= nSx1) && (sx <= nSx2)) && ((sy >= nSy1) && (sy <= nSy2))) found = 0; + + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx+xx][sy+yy] != miniset[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + + kk = (sh * sw) + 2; + + if (found == 1) { + for (ii = sy - sh; ((ii < (sy + (sh << 1))) && (found == 1)); ii ++) { + for (jj = sx - sw; jj < sx + (sw << 1); jj ++) + if (dungeon[jj][ii] == miniset[kk]) found = 0; + } + } + + if ((found == 1) && (random(0, 100) < rndper)) { + // Place mini set piece + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[kk] != 0) dungeon[sx+xx][sy+yy] = miniset[kk]; + kk++; + } + } + } + } + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2Subs() +{ + int x, y, i, j, k, rv; + byte c; + + for (y = 0; y < MDMAXY; y++) { + for (x = 0; x < MDMAXX; x++) { + if (((x < nSx1) || (x > nSx2)) && ((y < nSy1) || (y > nSy2))) { + rv = random(0, 4); + if (rv == 0) { + c = dungeon[x][y]; + c = BTYPESL2[c]; + if (c != 0) { + rv = random(0, 16); + i = -1; + while (rv >= 0) { + i++; + if (i == L2_NUMBLOCKS) i = 0; + if (c == BTYPESL2[i]) rv--; + } + + for (j = y - 2; j < y + 2; j++) { + for (k = x - 2; k < x + 2; k++) { + if (dungeon[k][j] == i) { + j = y + 3; // indicate a hit + k = x + 2; + } + } + } + if (j < y + 3) dungeon[x][y] = i; + } + } + } + } + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2Shadows() +{ + int x, y, i, patflag; + byte sd[2][2]; + + for (y = 1; y < MDMAXY; y++) { + for (x = 1; x < MDMAXX; x++) { + if ((x == 60) && (y == 21)) patflag = 1; + sd[0][0] = BSTYPESL2[dungeon[x][y]]; + sd[1][0] = BSTYPESL2[dungeon[x-1][y]]; + sd[0][1] = BSTYPESL2[dungeon[x][y-1]]; + sd[1][1] = BSTYPESL2[dungeon[x-1][y-1]]; + for (i = 0; i < L2_NUMSPATS; i++) { + if (SPATSL2[i].strig == sd[0][0]) { + patflag = 1; + if ((SPATSL2[i].s1 != 0) && (SPATSL2[i].s1 != sd[1][1])) patflag = 0; + if ((SPATSL2[i].s2 != 0) && (SPATSL2[i].s2 != sd[0][1])) patflag = 0; + if ((SPATSL2[i].s3 != 0) && (SPATSL2[i].s3 != sd[1][0])) patflag = 0; + if (patflag == 1) { + if (SPATSL2[i].nv1 != 0) dungeon[x-1][y-1] = SPATSL2[i].nv1; + if (SPATSL2[i].nv2 != 0) dungeon[x][y-1] = SPATSL2[i].nv2; + if (SPATSL2[i].nv3 != 0) dungeon[x-1][y] = SPATSL2[i].nv3; + } + } + } + } + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitDungeon() +{ + int i, j; + + for (i = 0; i < MDMAXY; i++) { + + for (j = 0; j < MDMAXX; j++) { + predungeon[j][i] = NO_CHAR; + dflags[j][i] = 0; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_LoadL2SP() +{ + setloadflag = FALSE; + if (QuestStatus(Q_BLIND)) { + pSetPiece = LoadFileInMemSig("Levels\\L2Data\\Blind2.DUN",NULL,'STPC'); + setloadflag = TRUE; + } + else if (QuestStatus(Q_BLOOD)) { + pSetPiece = LoadFileInMemSig("Levels\\L2Data\\Blood1.DUN",NULL,'STPC'); + setloadflag = TRUE; + } + else if (QuestStatus(Q_SCHAMB)) { + pSetPiece = LoadFileInMemSig("Levels\\L2Data\\Bonestr2.DUN",NULL,'STPC'); + setloadflag = TRUE; + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_FreeL2SP() { + DiabloFreePtr(pSetPiece); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2SetRoom(int rx1, int ry1) +{ + int rw,rh; + int i,j; + byte *sp; + + sp = pSetPiece; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = rw; + setpc_h = rh; + + //DRLG_MRectTrans(rx1, ry1, rx2, ry2); + //DRLG_MRectTrans(rx1+2, ry1+2, rx2-2, ry2-2); + + sp = pSetPiece+4; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp != 0) { + dungeon[rx1+i][ry1+j] = *sp; + dflags[rx1+i][ry1+j] |= SETP_BIT; + } else dungeon[rx1+i][ry1+j] = 3; + sp+=2; + } + } + } +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DefineRoom(int nX1, int nY1, int nX2, int nY2, int ForceHW) +{ + int i, j; + BYTE ft; + + // Four corners + predungeon[nX1][nY1] = ULWALL_CHAR; + predungeon[nX1][nY2] = LLWALL_CHAR; + predungeon[nX2][nY1] = URWALL_CHAR; + predungeon[nX2][nY2] = LRWALL_CHAR; + + nRoomCnt++; + + RoomList[nRoomCnt].nRoomx1 = nX1; + RoomList[nRoomCnt].nRoomx2 = nX2; + + RoomList[nRoomCnt].nRoomy1 = nY1; + RoomList[nRoomCnt].nRoomy2 = nY2; + if (ForceHW ==1) { + for (i = nX1; i < nX2;i++) { + for (j = nY1; i < nY2; i++) { + dflags[i][j] |= SETP_BIT; + } + } + } + // Horizontal top of room + for (i = nX1 + 1; i <= nX2 - 1; i++) { + predungeon[i][nY1] = WALL_CHAR; + predungeon[i][nY2] = WALL_CHAR; + } + + nY1++; + nY2--; + ft = FLOOR_CHAR; + + for (i = nY1; i <= nY2; i++) { + predungeon[nX1][i] = WALL_CHAR; + predungeon[nX2][i] = WALL_CHAR; + j = nX1 + 1; + + while (j < nX2) { + predungeon[j][i] = ft; + j++; + } + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void CreateDoorType(int nX, int nY) +{ + char dt; + BOOL fDoneflag; + + fDoneflag = FALSE; + + dt = predungeon[nX - 1][nY]; + if (dt == DOOR_CHAR) fDoneflag = TRUE; + + dt = predungeon[nX + 1][nY]; + if (dt == DOOR_CHAR) fDoneflag = TRUE; + + dt = predungeon[nX][nY - 1]; + if (dt == DOOR_CHAR) fDoneflag = TRUE; + + dt = predungeon[nX][nY + 1]; + if (dt == DOOR_CHAR) fDoneflag = TRUE; + + if (predungeon[nX][nY] == URWALL_CHAR || predungeon[nX][nY] == ULWALL_CHAR || + predungeon[nX][nY] == LRWALL_CHAR || predungeon[nX][nY] == LLWALL_CHAR) + fDoneflag = TRUE; + + if (!fDoneflag) predungeon[nX][nY] = DOOR_CHAR; +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void PlaceHallExt(int nX, int nY) +{ + if (predungeon[nX][nY] == NO_CHAR) + predungeon[nX][nY] = HALL_CHAR; +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void AddHall(int nX1, int nY1, int nX2, int nY2, int nHd) +{ + HALLNODE * p1; + HALLNODE * p2; + + if (pHallList == NULL) { + pHallList = (HALLNODE *) DiabloAllocPtrSig(sizeof HALLNODE,'HALL'); + pHallList->nHallx1 = nX1; + pHallList->nHally1 = nY1; + pHallList->nHallx2 = nX2; + pHallList->nHally2 = nY2; + pHallList->nHalldir = nHd; + pHallList->pNext = NULL; + } + else { + p2 = (HALLNODE *) DiabloAllocPtrSig(sizeof HALLNODE,'HALL'); + p2->nHallx1 = nX1; + p2->nHally1 = nY1; + p2->nHallx2 = nX2; + p2->nHally2 = nY2; + p2->nHalldir = nHd; + p2->pNext = NULL; + p1 = pHallList; + + while (p1->pNext != NULL) + p1 = p1->pNext; + p1->pNext = p2; + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, int ForceHW, int nH, int nW) +{ + int nAw, nAh; + int nRw, nRh; + int nRx1, nRy1, nRx2, nRy2; + int nHx1, nHy1, nHx2, nHy2; + int nRid; + + if (nRoomCnt >= MAX_ROOMS) return; + + nAw = nX2 - nX1; + nAh = nY2 - nY1; + + if ((nAw >= Area_Min) && (nAh >= Area_Min)) { + if ((nAw > Room_Max)) + nRw = random(0, Room_Max - Room_Min) + Room_Min; + else { + if (nAw > Room_Min) + nRw = random(0, nAw - Room_Min) + Room_Min; + else + nRw = nAw; + } + + if (nAh > Room_Max) + nRh = random(0, Room_Max - Room_Min) + Room_Min; + else { + if (nAh > Room_Min) + nRh = random(0, nAh - Room_Min) + Room_Min; + else + nRh = nAh; + } + + if (ForceHW == 1) { + nRw = nW; + nRh = nH; + } + + nRx1 = random(0, nX2 - nX1) + nX1; + nRy1 = random(0, nY2 - nY1) + nY1; + nRx2 = nRx1 + nRw; + nRy2 = nRy1 + nRh; + + if (nRx2 > nX2) { + nRx2 = nX2; + nRx1 = nRx2 - nRw; + } + + if (nRy2 > nY2) { + nRy2 = nY2; + nRy1 = nRy2 - nRh; + } + + if (nRx1 >= MDMAXX - 2) nRx1 = MDMAXX - 2; + if (nRy1 >= MDMAXY - 2) nRy1 = MDMAXY - 2; + if (nRx1 <= 1) nRx1 = 1; + if (nRy1 <= 1) nRy1 = 1; + if (nRx2 >= MDMAXX - 2) nRx2 = MDMAXX - 2; + if (nRy2 >= MDMAXY - 2) nRy2 = MDMAXY - 2; + if (nRx2 <= 1) nRx2 = 1; + if (nRy2 <= 1) nRy2 = 1; + + DefineRoom(nRx1, nRy1, nRx2, nRy2, ForceHW); + if (ForceHW == 1) { + nSx1 = nRx1 + 2; + nSy1 = nRy1 + 2; + nSx2 = nRx2; + nSy2 = nRy2; + } + + + nRid = nRoomCnt; + RoomList[nRid].nRoomDest = nRDest; + + if (nRDest != 0) { + if (nHDir == DIR_NORTH) { + nHx1 = random(0, nRx2 - nRx1 - 2) + nRx1 + 1; + nHy1 = nRy1; + nHx2 = RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2; + nHx2 = random(0, nHx2) + RoomList[nRDest].nRoomx1 + 1; + nHy2 = RoomList[nRDest].nRoomy2; + } + if (nHDir == DIR_SOUTH) { + nHx1 = random(0, nRx2 - nRx1 - 2) + nRx1 + 1; + nHy1 = nRy2; + nHx2 = RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2; + nHx2 = random(0, nHx2) + RoomList[nRDest].nRoomx1 + 1; + nHy2 = RoomList[nRDest].nRoomy1; + } + if (nHDir == DIR_EAST) { + nHx1 = nRx2; + nHy1 = random(0, nRy2 - nRy1 - 2) + nRy1 + 1; + nHx2 = RoomList[nRDest].nRoomx1; + nHy2 = RoomList[nRDest].nRoomy2 - RoomList[nRDest].nRoomy1 - 2; + nHy2 = random(0, nHy2) + RoomList[nRDest].nRoomy1 + 1; + } + if (nHDir == DIR_WEST) { + nHx1 = nRx1; + nHy1 = random(0, nRy2 - nRy1 - 2) + nRy1 + 1; + nHx2 = RoomList[nRDest].nRoomx2; + nHy2 = RoomList[nRDest].nRoomy2 - RoomList[nRDest].nRoomy1 - 2; + nHy2 = random(0, nHy2) + RoomList[nRDest].nRoomy1 + 1; + } + AddHall(nHx1, nHy1, nHx2, nHy2, nHDir); + } + + if (nRh > nRw) { + CreateRoom(nX1 + SNUM2, nY1 + SNUM2, nRx1 - SNUM1, nRy2 - SNUM1, nRid, DIR_EAST, 0, 0, 0); + CreateRoom(nRx2 + SNUM1, nRy1 + SNUM1, nX2 - SNUM2, nY2 - SNUM2, nRid, DIR_WEST, 0, 0, 0); + CreateRoom(nX1 + SNUM2, nRy2 + SNUM1, nRx2 - SNUM1, nY2 - SNUM2, nRid, DIR_NORTH, 0, 0, 0); + CreateRoom(nRx1 + SNUM1, nY1 + SNUM2, nX2 - SNUM2, nRy1 - SNUM1, nRid, DIR_SOUTH, 0, 0, 0); + } + else { + CreateRoom(nX1 + SNUM2, nY1 + SNUM2, nRx2 - SNUM1, nRy1 - SNUM1, nRid, DIR_SOUTH, 0, 0, 0); + CreateRoom(nRx1 + SNUM1, nRy2 + SNUM1, nX2 - SNUM2, nY2 - SNUM2, nRid, DIR_NORTH, 0, 0, 0); + CreateRoom(nX1 + SNUM2, nRy1 + SNUM1, nRx1 - SNUM1, nY2 - SNUM2, nRid, DIR_EAST, 0, 0, 0); + CreateRoom(nRx2 + SNUM1, nY1 + SNUM2, nX2 - SNUM2, nRy2 - SNUM1, nRid, DIR_WEST, 0, 0, 0); + } + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void GetHall(int * nX1, int * nY1, int * nX2, int * nY2, int * nHd) +{ + HALLNODE * p1; + + p1 = pHallList->pNext; + *nX1 = pHallList->nHallx1; + *nY1 = pHallList->nHally1; + *nX2 = pHallList->nHallx2; + *nY2 = pHallList->nHally2; + *nHd = pHallList->nHalldir; + DiabloFreePtr (pHallList); + pHallList = p1; +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void ConnectHall(int nX1, int nY1, int nX2, int nY2, int nHd) +{ + BOOL fDoneflag, fInroom; + int nCurrd, nDx, nDy, nRp; + int nOrigX1, nOrigY1; + int fMinusFlag, fPlusFlag; + + fDoneflag = FALSE; + fMinusFlag = random(0, 100); + fPlusFlag = random(0, 100); + nOrigX1 = nX1; + nOrigY1 = nY1; + + CreateDoorType(nX1, nY1); + CreateDoorType(nX2, nY2); + + nDx = abs(nX2 - nX1); + nDy = abs(nY2 - nY1); + + nCurrd = nHd; + nX2 = nX2 - Dir_Xadd[nCurrd]; + nY2 = nY2 - Dir_Yadd[nCurrd]; + predungeon[nX2][nY2] = HALL_CHAR; + fInroom = FALSE; + + while (!fDoneflag) { + if (nX1 >= MDMAXX - 2 && nCurrd == 2) nCurrd = 4; + if (nY1 >= MDMAXY - 2 && nCurrd == 3) nCurrd = 1; + if (nX1 <= 1 && nCurrd == 4) nCurrd = 2; + if (nY1 <= 1 && nCurrd == 1) nCurrd = 3; + + if (predungeon[nX1][nY1] == ULWALL_CHAR && (nCurrd == 1 || nCurrd == 4)) + nCurrd = 2; + if (predungeon[nX1][nY1] == URWALL_CHAR && (nCurrd == 1 || nCurrd == 2)) + nCurrd = 3; + if (predungeon[nX1][nY1] == LLWALL_CHAR && (nCurrd == 4 || nCurrd == 3)) + nCurrd = 1; + if (predungeon[nX1][nY1] == LRWALL_CHAR && (nCurrd == 2 || nCurrd == 3)) + nCurrd = 4; + + nX1 = nX1 + Dir_Xadd[nCurrd]; + nY1 = nY1 + Dir_Yadd[nCurrd]; + + if (predungeon[nX1][nY1] == NO_CHAR) { + if (fInroom) + CreateDoorType(nX1 - Dir_Xadd[nCurrd], nY1 - Dir_Yadd[nCurrd]); + else { + if (fMinusFlag < 50) { + if (nCurrd == 1 || nCurrd == 3) + PlaceHallExt(nX1 - 1, nY1); + else + PlaceHallExt(nX1, nY1 - 1); + } + if (fPlusFlag < 50) { + if (nCurrd == 1 || nCurrd == 3) + PlaceHallExt(nX1 + 1, nY1); + else + PlaceHallExt(nX1, nY1 + 1); + } + } + predungeon[nX1][nY1] = HALL_CHAR; + fInroom = FALSE; + } + else { + if (!fInroom && predungeon[nX1][nY1] == WALL_CHAR) CreateDoorType(nX1,nY1); + if (predungeon[nX1][nY1] != HALL_CHAR) fInroom = TRUE; + } + + nDx = abs(nX2 - nX1); + nDy = abs(nY2 - nY1); + + if (nDx > nDy) { + nRp = nDx * 2; + if (nRp > 30) nRp = 30; + if (random(0, 100) < nRp) { + if ((nX2 > nX1) && (nX1 < MDMAXX)) + nCurrd = 2; + else + nCurrd = 4; + } + } + else { + nRp = nDy * 5; + if (nRp > 80) nRp = 80; + if (random(0, 100) < nRp) { + if ((nY2 > nY1) && (nY1 < MDMAXY)) + nCurrd = 3; + else + nCurrd = 1; + } + } + + if (nDy < 10) { + if ((nX1 == nX2) && ((nCurrd == DIR_EAST) || (nCurrd == DIR_WEST))) { + if ((nY2 > nY1) && (nY1 < MDMAXY)) + nCurrd = 3; + else + nCurrd = 1; + } + } + + if (nDx < 10) { + if ((nY1 == nY2) && ((nCurrd == DIR_NORTH) || (nCurrd == DIR_SOUTH))) { + if ((nX2 > nX1) && (nX1 < MDMAXX)) + nCurrd = 2; + else + nCurrd = 4; + } + } + + if (nDy == 1 && nDx > 1 && (nCurrd == DIR_NORTH || nCurrd == DIR_SOUTH)) { + if ((nX2 > nX1) && (nX1 < MDMAXX)) + nCurrd = 2; + else + nCurrd = 4; + } + + if (nDx == 1 && nDy > 1 && (nCurrd == DIR_EAST || nCurrd == DIR_WEST)) { + if ((nY2 > nY1) && (nX1 < MDMAXY)) + nCurrd = 3; + else + nCurrd = 1; + } + + if (nDx == 0 && predungeon[nX1][nY1] != NO_CHAR && (nCurrd == DIR_EAST || nCurrd == DIR_WEST)) { + if ((nX2 > nOrigX1) && (nX1 < MDMAXX)) + nCurrd = 3; + else + nCurrd = 1; + } + + if (nDy == 0 && predungeon[nX1][nY1] != NO_CHAR && (nCurrd == DIR_NORTH || nCurrd == DIR_SOUTH)) { + if ((nY2 > nOrigY1) && (nY1 < MDMAXY)) + nCurrd = 2; + else + nCurrd = 4; + } + + if ((nX1 == nX2) && (nY1 == nY2)) fDoneflag = TRUE; + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DoPatternCheck(int i, int j) +{ + int k, l; + int x, y; + int nOk; + + for (k = 0; Patterns[k][4] != 255; k++) { + x = i - 1; + y = j - 1; + nOk = OK; + + for (l = 0; l < 9 && nOk == OK; l ++) { + nOk = NOTOK; + if (l == 3 || l == 6) { + y ++; + x = i - 1; + } + + if (x < 0 || x >= MDMAXX || y < 0 || y >= MDMAXY) + nOk = OK; + else { + switch (Patterns[k][l]) { + case CNO: + nOk = OK; + break; + case CWALL: + if (predungeon[x][y] == WALL_CHAR) + nOk = OK; + break; + case CFLOOR: + if (predungeon[x][y] == FLOOR_CHAR) + nOk = OK; + break; + case CEMPTY: + if (predungeon[x][y] == NO_CHAR) + nOk = OK; + break; + case CDOOR: + if (predungeon[x][y] == DOOR_CHAR) + nOk = OK; + break; + case CDoF: + if (predungeon[x][y] == DOOR_CHAR || predungeon[x][y] == FLOOR_CHAR) + nOk = OK; + break; + case CDoW: + if (predungeon[x][y] == DOOR_CHAR || predungeon[x][y] == WALL_CHAR) + nOk = OK; + break; + case CEoF: + if (predungeon[x][y] == NO_CHAR || predungeon[x][y] == FLOOR_CHAR) + nOk = OK; + break; + case CDoWoF: + if (predungeon[x][y] == DOOR_CHAR || predungeon[x][y] == WALL_CHAR || + predungeon[x][y] == FLOOR_CHAR) + nOk = OK; + break; + } + } + x ++; + } + if (nOk == OK) + dungeon[i][j] = (BYTE) Patterns[k][9]; + else + nOk = NOTOK; + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void L2TileFix() +{ + int i, j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 3)) dungeon[i][j+1] = 1; + if ((dungeon[i][j] == 3) && (dungeon[i][j+1] == 1)) dungeon[i][j+1] = 3; + + if ((dungeon[i][j] == 3) && (dungeon[i+1][j] == 7)) dungeon[i+1][j] = 3; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 3)) dungeon[i+1][j] = 2; + if ((dungeon[i][j] == 11) && (dungeon[i+1][j] == 14)) dungeon[i+1][j] = 16; + } + } +} +#endif + +#define L2_CONT 0 +#define L2_BOUNDS 1 +#define L2_WALL 2 + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static BOOL DL2_Cont(BOOL x1f, BOOL y1f, BOOL x2f, BOOL y2f) +{ + if (x1f && x2f && y1f && y2f) return(FALSE); + if (x1f && x2f && (y1f || y2f)) return(TRUE); + if (y1f && y2f && (x1f || x2f)) return(TRUE); + return(FALSE); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static int DL2_NumNoChar() +{ + int t = 0; + int ii, jj; + for (jj = 0; jj < MDMAXY; jj++) + for (ii = 0; ii < MDMAXX; ii++) + if (predungeon[ii][jj] == NO_CHAR) t++; + return(t); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DL2_DrawRoom(int x1, int y1, int x2, int y2) +{ + int ii, jj; + + for (jj = y1; jj <= y2; jj++) { + for (ii = x1; ii <= x2; ii++) predungeon[ii][jj] = FLOOR_CHAR; + } + for (jj = y1; jj <= y2; jj++) { + predungeon[x1][jj] = WALL_CHAR; + predungeon[x2][jj] = WALL_CHAR; + } + for (ii = x1; ii <= x2; ii++) { + predungeon[ii][y1] = WALL_CHAR; + predungeon[ii][y2] = WALL_CHAR; + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DL2_KnockWalls(int x1, int y1, int x2, int y2) +{ + int ii, jj; + + for (ii = x1+1; ii < x2; ii++) { + if ((predungeon[ii][y1-1] == FLOOR_CHAR) && (predungeon[ii][y1+1] == FLOOR_CHAR)) predungeon[ii][y1] = FLOOR_CHAR; + if ((predungeon[ii][y2-1] == FLOOR_CHAR) && (predungeon[ii][y2+1] == FLOOR_CHAR)) predungeon[ii][y2] = FLOOR_CHAR; + if (predungeon[ii][y1-1] == DOOR_CHAR) predungeon[ii][y1-1] = FLOOR_CHAR; + if (predungeon[ii][y2+1] == DOOR_CHAR) predungeon[ii][y2+1] = FLOOR_CHAR; + } + for (jj = y1+1; jj < y2; jj++) { + if ((predungeon[x1-1][jj] == FLOOR_CHAR) && (predungeon[x1+1][jj] == FLOOR_CHAR)) predungeon[x1][jj] = FLOOR_CHAR; + if ((predungeon[x2-1][jj] == FLOOR_CHAR) && (predungeon[x2+1][jj] == FLOOR_CHAR)) predungeon[x2][jj] = FLOOR_CHAR; + if (predungeon[x1-1][jj] == DOOR_CHAR) predungeon[x1-1][jj] = FLOOR_CHAR; + if (predungeon[x2+1][jj] == DOOR_CHAR) predungeon[x2+1][jj] = FLOOR_CHAR; + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/* +static void DL2_DoorOrEmptyX(int x, int yy, int y1, int y2) +{ + int sy1, sy2, ry; + + sy1 = sy2 = yy; + while (((predungeon[x-1][sy1-1] == FLOOR_CHAR) && (predungeon[x+1][sy1-1] == FLOOR_CHAR)) && (sy1 > y1)) sy1--; + while (((predungeon[x-1][sy2+1] == FLOOR_CHAR) && (predungeon[x+1][sy2+1] == FLOOR_CHAR)) && (sy2 < y2)) sy2++; + if (random(0, 3) && ((sy2-sy1) > 1)) { + ry = random(0, sy2 - sy1 - 1) + sy1 + 1; + predungeon[x][ry] = DOOR_CHAR; + } else { + for (ry = sy1; ry <= sy2; ry++) predungeon[x][ry] = FLOOR_CHAR; + } +} +*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/* +static void DL2_DoorOrEmptyY(int y, int xx, int x1, int x2) +{ + int sx1, sx2, rx; + + sx1 = sx2 = xx; + while (((predungeon[sx1-1][y-1] == FLOOR_CHAR) && (predungeon[sx1-1][y+1] == FLOOR_CHAR)) && (sx1 > x1)) sx1--; + while (((predungeon[sx2+1][y-1] == FLOOR_CHAR) && (predungeon[sx2+1][y+1] == FLOOR_CHAR)) && (sx2 < x2)) sx2++; + if (random(0, 3) && ((sx2-sx1) > 1)) { + rx = random(0, sx2 - sx1 - 1) + sx1 + 1; + predungeon[rx][y] = DOOR_CHAR; + } else { + for (rx = sx1; rx <= sx2; rx++) predungeon[rx][y] = FLOOR_CHAR; + } +} +*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static BOOL DL2_FillVoids() +{ + int ii, jj, xx, yy; + int x1, x2, y1, y2; + BOOL xf1, xf2, yf1, yf2; + + int to = 0; + while ((DL2_NumNoChar() > 700) && (to < 100)) { + xx = random(0, MDMAXX-2) + 1; + yy = random(0, MDMAXY-2) + 1; + if (predungeon[xx][yy] == WALL_CHAR) { + xf1 = xf2 = yf1 = yf2 = FALSE; + if ((predungeon[xx-1][yy] == NO_CHAR) && (predungeon[xx+1][yy] == FLOOR_CHAR)) { + if ((predungeon[xx+1][yy-1] == FLOOR_CHAR) && (predungeon[xx+1][yy+1] == FLOOR_CHAR) && + (predungeon[xx-1][yy-1] == NO_CHAR) && (predungeon[xx-1][yy+1] == NO_CHAR)) + xf1 = yf1 = yf2 = TRUE; + } else + if ((predungeon[xx+1][yy] == NO_CHAR) && (predungeon[xx-1][yy] == FLOOR_CHAR)) { + if ((predungeon[xx-1][yy-1] == FLOOR_CHAR) && (predungeon[xx-1][yy+1] == FLOOR_CHAR) && + (predungeon[xx+1][yy-1] == NO_CHAR) && (predungeon[xx+1][yy+1] == NO_CHAR)) + xf2 = yf1 = yf2 = TRUE; + } else + if ((predungeon[xx][yy-1] == NO_CHAR) && (predungeon[xx][yy+1] == FLOOR_CHAR)) { + if ((predungeon[xx-1][yy+1] == FLOOR_CHAR) && (predungeon[xx+1][yy+1] == FLOOR_CHAR) && + (predungeon[xx-1][yy-1] == NO_CHAR) && (predungeon[xx+1][yy-1] == NO_CHAR)) + yf1 = xf1 = xf2 = TRUE; + } else + if ((predungeon[xx][yy+1] == NO_CHAR) && (predungeon[xx][yy-1] == FLOOR_CHAR)) { + if ((predungeon[xx-1][yy-1] == FLOOR_CHAR) && (predungeon[xx+1][yy-1] == FLOOR_CHAR) && + (predungeon[xx-1][yy+1] == NO_CHAR) && (predungeon[xx+1][yy+1] == NO_CHAR)) + yf2 = xf1 = xf2 = TRUE; + } + if (DL2_Cont(xf1,yf1,xf2,yf2)) { + if (xf1) x1 = xx-1; + else x1 = xx; + if (xf2) x2 = xx+1; + else x2 = xx; + if (yf1) y1 = yy-1; + else y1 = yy; + if (yf2) y2 = yy+1; + else y2 = yy; + if (!xf1) { + while (yf1 || yf2) { + if (y1 == 0) yf1 = FALSE; + if (y2 == MDMAXY-1) yf2 = FALSE; + if ((y2 - y1) >= ROOM_MAX+4) { + yf1 = FALSE; + yf2 = FALSE; + } + if (yf1) y1--; + if (yf2) y2++; + if (predungeon[x2][y1] != NO_CHAR) yf1 = FALSE; + if (predungeon[x2][y2] != NO_CHAR) yf2 = FALSE; + } + y1 += 2; + y2 -= 2; + if ((y2 - y1) > 5) { + while (xf2) { + if (x2 == MDMAXX-1) xf2 = FALSE; + if ((x2 - x1) >= ROOM_MAX+2) xf2 = FALSE; + for (jj = y1; jj <= y2; jj++) + if (predungeon[x2][jj] != NO_CHAR) xf2 = FALSE; + if (xf2) x2++; + } + x2 -= 2; + if ((x2 - x1) > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + //DL2_DoorOrEmptyX(x1, yy, y1, y2); + } + } + } else + if (!xf2) { + while (yf1 || yf2) { + if (y1 == 0) yf1 = FALSE; + if (y2 == MDMAXY-1) yf2 = FALSE; + if ((y2 - y1) >= ROOM_MAX+4) { + yf1 = FALSE; + yf2 = FALSE; + } + if (yf1) y1--; + if (yf2) y2++; + if (predungeon[x1][y1] != NO_CHAR) yf1 = FALSE; + if (predungeon[x1][y2] != NO_CHAR) yf2 = FALSE; + } + y1 += 2; + y2 -= 2; + if ((y2 - y1) > 5) { + while (xf1) { + if (x1 == 0) xf1 = FALSE; + if ((x2 - x1) >= ROOM_MAX+2) xf1 = FALSE; + for (jj = y1; jj <= y2; jj++) + if (predungeon[x1][jj] != NO_CHAR) xf1 = FALSE; + if (xf1) x1--; + } + x1 += 2; + if ((x2 - x1) > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + //DL2_DoorOrEmptyX(x2, yy, y1, y2); + } + } + } else + if (!yf1) { + while (xf1 || xf2) { + if (x1 == 0) xf1 = FALSE; + if (x2 == MDMAXX-1) xf2 = FALSE; + if ((x2 - x1) >= ROOM_MAX+4) { + xf1 = FALSE; + xf2 = FALSE; + } + if (xf1) x1--; + if (xf2) x2++; + if (predungeon[x1][y2] != NO_CHAR) xf1 = FALSE; + if (predungeon[x2][y2] != NO_CHAR) xf2 = FALSE; + } + x1 += 2; + x2 -= 2; + if ((x2 - x1) > 5) { + while (yf2) { + if (y2 == MDMAXY-1) yf2 = FALSE; + if ((y2 - y1) >= ROOM_MAX+2) yf2 = FALSE; + for (ii = x1; ii <= x2; ii++) + if (predungeon[ii][y2] != NO_CHAR) yf2 = FALSE; + if (yf2) y2++; + } + y2 -= 2; + if ((y2 - y1) > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + //DL2_DoorOrEmptyY(y1, xx, x1, x2); + } + } + } else + if (!yf2) { + while (xf1 || xf2) { + if (x1 == 0) xf1 = FALSE; + if (x2 == MDMAXX-1) xf2 = FALSE; + if ((x2 - x1) >= ROOM_MAX+4) { + xf1 = FALSE; + xf2 = FALSE; + } + if (xf1) x1--; + if (xf2) x2++; + if (predungeon[x1][y1] != NO_CHAR) xf1 = FALSE; + if (predungeon[x2][y1] != NO_CHAR) xf2 = FALSE; + } + x1 += 2; + x2 -= 2; + if ((x2 - x1) > 5) { + while (yf1) { + if (y1 == 0) yf1 = FALSE; + if ((y2 - y1) >= ROOM_MAX+2) yf1 = FALSE; + for (ii = x1; ii <= x2; ii++) + if (predungeon[ii][y1] != NO_CHAR) yf1 = FALSE; + if (yf1) y1--; + } + y1 += 2; + if ((y2 - y1) > 5) { + DL2_DrawRoom(x1, y1, x2, y2); + DL2_KnockWalls(x1, y1, x2, y2); + //DL2_DoorOrEmptyY(y2, xx, x1, x2); + } + } + } + } + to++; + } + } + if (DL2_NumNoChar() > 700) return(FALSE); + return(TRUE); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static BOOL CreateDungeon() +{ + int i, j; + int nHx1, nHy1, nHx2, nHy2, nHd; + int ForceH,ForceW,ForceHW; + + ForceHW = ForceH = ForceW = 0; + + switch(currlevel) { + case 5 : + if (quests[Q_BLOOD]._qactive != QUEST_NOTAVAIL) { + ForceHW = 1; + ForceH = 20; + ForceW = 14; + } + break; + case 6 : + if (quests[Q_SCHAMB]._qactive != QUEST_NOTAVAIL) { + ForceHW = 1; + ForceH = ForceW = 10; + } + break; + case 7 : + if(quests[Q_BLIND]._qactive != QUEST_NOTAVAIL) { + ForceHW = 1; + ForceH = ForceW = 15; + } + break; + case 8 : + break; + default: + break; // to use level 2 for crypt + } + + CreateRoom(2, 2, MDMAXX - 1, MDMAXY - 1, 0, DIR_NONE, ForceHW, ForceH, ForceW); + + while (pHallList != NULL) { + GetHall(&nHx1, &nHy1, &nHx2, &nHy2, &nHd); + ConnectHall(nHx1, nHy1, nHx2, nHy2, nHd); + } + + for (j = 0; j <= MDMAXY; j++) { + for (i = 0; i <= MDMAXX; i++) { + if (predungeon[i][j] == ULWALL_CHAR) predungeon[i][j] = WALL_CHAR; + if (predungeon[i][j] == URWALL_CHAR) predungeon[i][j] = WALL_CHAR; + if (predungeon[i][j] == LLWALL_CHAR) predungeon[i][j] = WALL_CHAR; + if (predungeon[i][j] == LRWALL_CHAR) predungeon[i][j] = WALL_CHAR; + if (predungeon[i][j] == HALL_CHAR) { + predungeon[i][j] = FLOOR_CHAR; + if (predungeon[i - 1][j - 1] == NO_CHAR) predungeon[i - 1][j - 1] = WALL_CHAR; + if (predungeon[i - 1][j - 0] == NO_CHAR) predungeon[i - 1][j - 0] = WALL_CHAR; + if (predungeon[i - 1][j + 1] == NO_CHAR) predungeon[i - 1][j + 1] = WALL_CHAR; + if (predungeon[i + 1][j - 1] == NO_CHAR) predungeon[i + 1][j - 1] = WALL_CHAR; + if (predungeon[i + 1][j - 0] == NO_CHAR) predungeon[i + 1][j - 0] = WALL_CHAR; + if (predungeon[i + 1][j + 1] == NO_CHAR) predungeon[i + 1][j + 1] = WALL_CHAR; + if (predungeon[i - 0][j - 1] == NO_CHAR) predungeon[i - 0][j - 1] = WALL_CHAR; + if (predungeon[i - 0][j + 1] == NO_CHAR) predungeon[i - 0][j + 1] = WALL_CHAR; + } + } + } + + // New Dave code 10/11 + if (!DL2_FillVoids()) return(FALSE); + // End new Dave code + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) + DoPatternCheck(i, j); + } + return(TRUE); +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2Pass3() +{ + int i,j,xx,yy; + long v1,v2,v3,v4,lv; + + // Init dungeon to dirt + lv = 11; // 12 - 1 + __asm { + mov esi,dword ptr [pMegaTiles] + mov eax,dword ptr [lv]; + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + } + for (yy = 0; yy < DMAXY; yy+=2) { + for (xx = 0; xx < DMAXX; xx+=2) { + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; + } + } + + // Convert dungeon mega tiles to mini tiles + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + lv = ((long)dungeon[i][j]) - 1; + __asm { + mov esi,dword ptr [pMegaTiles] + mov eax,dword ptr [lv]; + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + } + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; + xx += 2; + } + yy += 2; + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2FTVR(int i, int j, int x, int y, int d) +{ + if ((dTransVal[x][y] == 0) && (dungeon[i][j] == FLOOR_PIECE)) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + DRLG_L2FTVR(i+1,j, x+2,y, 1); + DRLG_L2FTVR(i-1,j, x-2,y, 2); + DRLG_L2FTVR(i,j+1, x,y+2, 3); + DRLG_L2FTVR(i,j-1, x,y-2, 4); + + DRLG_L2FTVR(i-1,j-1, x-2,y-2, 5); + DRLG_L2FTVR(i+1,j-1, x+2,y-2, 6); + DRLG_L2FTVR(i-1,j+1, x-2,y+2, 7); + DRLG_L2FTVR(i+1,j+1, x+2,y+2, 8); + } else { + if (d == 1) { + dTransVal[x][y] = TransVal; + dTransVal[x][y+1] = TransVal; + } + if (d == 2) { + dTransVal[x+1][y] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 3) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + } + if (d == 4) { + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 5) dTransVal[x+1][y+1] = TransVal; + if (d == 6) dTransVal[x][y+1] = TransVal; + if (d == 7) dTransVal[x+1][y] = TransVal; + if (d == 8) dTransVal[x][y] = TransVal; + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2FloodTVal() +{ + int i, j; + int xx,yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == FLOOR_PIECE) && (dTransVal[xx][yy] == 0)) { + DRLG_L2FTVR(i,j,xx,yy,0); + TransVal++; + } + xx += 2; + } + yy += 2; + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2TransFix() +{ + int i, j; + int xx,yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == DURWALL_PIECE) && (dungeon[i][j-1] == DVWALL_PIECE)) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if ((dungeon[i][j] == DLLWALL_PIECE) && (dungeon[i+1][j] == DHWALL_PIECE)) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == DVWALL_PIECE) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == DHWALL_PIECE) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == DLRWALL_PIECE) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + xx += 2; + } + yy += 2; + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void L2DirtFix() +{ + int i, j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 13) && (dungeon[i+1][j] != 11)) dungeon[i][j] = 146; + if ((dungeon[i][j] == 11) && (dungeon[i+1][j] != 11)) dungeon[i][j] = 144; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] != 11)) dungeon[i][j] = 148; + + if ((dungeon[i][j] == 10) && (dungeon[i][j+1] != 10)) dungeon[i][j] = 143; + if ((dungeon[i][j] == 13) && (dungeon[i][j+1] != 10)) dungeon[i][j] = 146; + if ((dungeon[i][j] == 14) && (dungeon[i][j+1] != 15)) dungeon[i][j] = 147; + } + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void L2LockoutFix() +{ + int i, j; + BOOL doorok; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 4) && (dungeon[i-1][j] != 3)) dungeon[i][j] = 1; + if ((dungeon[i][j] == 5) && (dungeon[i][j-1] != 3)) dungeon[i][j] = 2; + } + } + + for (j = 1; j < MDMAXY-1; j++) { + for (i = 1; i < MDMAXX-1; i++) { + if (!(dflags[i][j] & SETP_BIT)) { + if (((dungeon[i][j] == 2) || (dungeon[i][j] == 5)) && (dungeon[i][j-1] == 3) && (dungeon[i][j+1] == 3)) { + doorok = FALSE; + while (((dungeon[i][j] == 2) || (dungeon[i][j] == 5)) && (dungeon[i][j-1] == 3) && (dungeon[i][j+1] == 3)) { + if (dungeon[i][j] == 5) doorok = TRUE; + i++; + } + if (!doorok && !(dflags[i-1][j] & SETP_BIT)) { + dungeon[i-1][j] = 5; + } + } + } + } + } + for (i = 1; i < MDMAXX-1; i++) { + for (j = 1; j < MDMAXY-1; j++) { + if (!(dflags[i][j] & SETP_BIT)) { + if (((dungeon[i][j] == 1) || (dungeon[i][j] == 4)) && (dungeon[i-1][j] == 3) && (dungeon[i+1][j] == 3)) { + doorok = FALSE; + while (((dungeon[i][j] == 1) || (dungeon[i][j] == 4)) && (dungeon[i-1][j] == 3) && (dungeon[i+1][j] == 3)) { + if (dungeon[i][j] == 4) doorok = TRUE; + j++; + } + if (!doorok && !(dflags[i][j-1] & SETP_BIT)) { + dungeon[i][j-1] = 4; + } + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void L2DoorFix() +{ + int i, j; + + for (j = 1; j < MDMAXY; j++) { + for (i = 1; i < MDMAXX; i++) { + if ((dungeon[i][j] == 4) && (dungeon[i][j-1] == 3)) + dungeon[i][j] = 7; + if ((dungeon[i][j] == 5) && (dungeon[i-1][j] == 3)) + dungeon[i][j] = 9; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_L2(int entry) +{ + int i,j; + BOOL doneflag; + + doneflag = FALSE; + while (!doneflag) { + nRoomCnt = 0; + InitDungeon(); + DRLG_InitTrans(); + + if (CreateDungeon()) { + L2TileFix(); + + if (setloadflag) { + DRLG_L2SetRoom(nSx1,nSy1); + } + DRLG_L2FloodTVal(); + DRLG_L2TransFix(); + + if (entry == LVL_DOWN) { + doneflag = DRLG_L2PlaceMiniSet(USTAIRS, 1, 1, -1, -1, 1, LVL_DOWN); + + #if IS_VERSION(RETAIL) + if (doneflag) doneflag = DRLG_L2PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, 0, LVL_UP); + #endif + + if ((doneflag) && (currlevel == 5)) doneflag = DRLG_L2PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, 0, LVL_TWARPDN); + + ViewY -= 2; + } else { + if (entry == LVL_UP) { + doneflag = DRLG_L2PlaceMiniSet(USTAIRS, 1, 1, -1, -1, 0, LVL_DOWN); + #if IS_VERSION(RETAIL) + if (doneflag) doneflag = DRLG_L2PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, 1, LVL_UP); + #endif + if ((doneflag) && (currlevel == 5)) doneflag = DRLG_L2PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, 0, LVL_TWARPDN); + ViewX--; + } else { + doneflag = DRLG_L2PlaceMiniSet(USTAIRS, 1, 1, -1, -1, 0, LVL_DOWN); + #if IS_VERSION(RETAIL) + if (doneflag) doneflag = DRLG_L2PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, 0, LVL_UP); + #endif + if ((doneflag) && (currlevel == 5)) doneflag = DRLG_L2PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, 1, LVL_TWARPDN); + ViewY -= 2; + } + } + } + } + + L2LockoutFix(); + + L2DoorFix(); + + L2DirtFix(); + + if (doneflag) DRLG_PlaceThemeRooms(6, 10, FLOOR_PIECE, 0, FALSE); + + DRLG_L2PlaceRndSet(CTRDOOR1, 100); + DRLG_L2PlaceRndSet(CTRDOOR2, 100); + DRLG_L2PlaceRndSet(CTRDOOR3, 100); + DRLG_L2PlaceRndSet(CTRDOOR4, 100); + DRLG_L2PlaceRndSet(CTRDOOR5, 100); + DRLG_L2PlaceRndSet(CTRDOOR6, 100); + DRLG_L2PlaceRndSet(CTRDOOR7, 100); + DRLG_L2PlaceRndSet(CTRDOOR8, 100); + + DRLG_L2PlaceRndSet(VARCH33, 100); + DRLG_L2PlaceRndSet(VARCH34, 100); + DRLG_L2PlaceRndSet(VARCH35, 100); + DRLG_L2PlaceRndSet(VARCH36, 100); + DRLG_L2PlaceRndSet(VARCH37, 100); + DRLG_L2PlaceRndSet(VARCH38, 100); + DRLG_L2PlaceRndSet(VARCH39, 100); + DRLG_L2PlaceRndSet(VARCH40, 100); + + DRLG_L2PlaceRndSet(VARCH1, 100); + DRLG_L2PlaceRndSet(VARCH2, 100); + DRLG_L2PlaceRndSet(VARCH3, 100); + DRLG_L2PlaceRndSet(VARCH4, 100); + DRLG_L2PlaceRndSet(VARCH5, 100); + DRLG_L2PlaceRndSet(VARCH6, 100); + DRLG_L2PlaceRndSet(VARCH7, 100); + DRLG_L2PlaceRndSet(VARCH8, 100); + + DRLG_L2PlaceRndSet(VARCH9, 100); + DRLG_L2PlaceRndSet(VARCH10, 100); + DRLG_L2PlaceRndSet(VARCH11, 100); + DRLG_L2PlaceRndSet(VARCH12, 100); + DRLG_L2PlaceRndSet(VARCH13, 100); + DRLG_L2PlaceRndSet(VARCH14, 100); + DRLG_L2PlaceRndSet(VARCH15, 100); + DRLG_L2PlaceRndSet(VARCH16, 100); + + DRLG_L2PlaceRndSet(VARCH17, 100); + DRLG_L2PlaceRndSet(VARCH18, 100); + DRLG_L2PlaceRndSet(VARCH19, 100); + DRLG_L2PlaceRndSet(VARCH20, 100); + DRLG_L2PlaceRndSet(VARCH21, 100); + DRLG_L2PlaceRndSet(VARCH22, 100); + DRLG_L2PlaceRndSet(VARCH23, 100); + DRLG_L2PlaceRndSet(VARCH24, 100); + + DRLG_L2PlaceRndSet(VARCH25, 100); + DRLG_L2PlaceRndSet(VARCH26, 100); + DRLG_L2PlaceRndSet(VARCH27, 100); + DRLG_L2PlaceRndSet(VARCH28, 100); + DRLG_L2PlaceRndSet(VARCH29, 100); + DRLG_L2PlaceRndSet(VARCH30, 100); + DRLG_L2PlaceRndSet(VARCH31, 100); + DRLG_L2PlaceRndSet(VARCH32, 100); + + DRLG_L2PlaceRndSet(HARCH1, 100); + DRLG_L2PlaceRndSet(HARCH2, 100); + DRLG_L2PlaceRndSet(HARCH3, 100); + DRLG_L2PlaceRndSet(HARCH4, 100); + DRLG_L2PlaceRndSet(HARCH5, 100); + DRLG_L2PlaceRndSet(HARCH6, 100); + DRLG_L2PlaceRndSet(HARCH7, 100); + DRLG_L2PlaceRndSet(HARCH8, 100); + DRLG_L2PlaceRndSet(HARCH9, 100); + DRLG_L2PlaceRndSet(HARCH10, 100); + DRLG_L2PlaceRndSet(HARCH11, 100); + DRLG_L2PlaceRndSet(HARCH12, 100); + DRLG_L2PlaceRndSet(HARCH13, 100); + DRLG_L2PlaceRndSet(HARCH14, 100); + DRLG_L2PlaceRndSet(HARCH15, 100); + DRLG_L2PlaceRndSet(HARCH16, 100); + DRLG_L2PlaceRndSet(HARCH17, 100); + DRLG_L2PlaceRndSet(HARCH18, 100); + DRLG_L2PlaceRndSet(HARCH19, 100); + DRLG_L2PlaceRndSet(HARCH20, 100); + DRLG_L2PlaceRndSet(HARCH21, 100); + DRLG_L2PlaceRndSet(HARCH22, 100); + DRLG_L2PlaceRndSet(HARCH23, 100); + DRLG_L2PlaceRndSet(HARCH24, 100); + + DRLG_L2PlaceRndSet(HARCH25, 100); + DRLG_L2PlaceRndSet(HARCH26, 100); + DRLG_L2PlaceRndSet(HARCH27, 100); + DRLG_L2PlaceRndSet(HARCH28, 100); + DRLG_L2PlaceRndSet(HARCH29, 100); + DRLG_L2PlaceRndSet(HARCH30, 100); + DRLG_L2PlaceRndSet(HARCH31, 100); + DRLG_L2PlaceRndSet(HARCH32, 100); + + DRLG_L2PlaceRndSet(HARCH33, 100); + DRLG_L2PlaceRndSet(HARCH34, 100); + DRLG_L2PlaceRndSet(HARCH35, 100); + DRLG_L2PlaceRndSet(HARCH36, 100); + DRLG_L2PlaceRndSet(HARCH37, 100); + DRLG_L2PlaceRndSet(HARCH38, 100); + DRLG_L2PlaceRndSet(HARCH39, 100); + DRLG_L2PlaceRndSet(HARCH40, 100); + + DRLG_L2PlaceRndSet(CRUSHCOL, 99); + + DRLG_L2PlaceRndSet(RUINS1, 10); + DRLG_L2PlaceRndSet(RUINS2, 10); + DRLG_L2PlaceRndSet(RUINS3, 10); + DRLG_L2PlaceRndSet(RUINS4, 10); + DRLG_L2PlaceRndSet(RUINS5, 10); + DRLG_L2PlaceRndSet(RUINS6, 10); + DRLG_L2PlaceRndSet(RUINS7, 50); + + DRLG_L2PlaceRndSet(PANCREAS1, 1); + DRLG_L2PlaceRndSet(PANCREAS2, 1); + + DRLG_L2PlaceRndSet(BIG1, 3); // 1x2 water + DRLG_L2PlaceRndSet(BIG2, 3); // 2x1 water + DRLG_L2PlaceRndSet(BIG3, 3); // 1x2 ruined box + DRLG_L2PlaceRndSet(BIG4, 3); // 2x1 ruined box + DRLG_L2PlaceRndSet(BIG5, 3); // 2x2 water + DRLG_L2PlaceRndSet(BIG6, 20); // 1x2 wall water + DRLG_L2PlaceRndSet(BIG7, 20); // 2x1 wall water + DRLG_L2PlaceRndSet(BIG8, 3); // 2x2 rubble pile + DRLG_L2PlaceRndSet(BIG9, 20); // 2x2 vwall ruins + DRLG_L2PlaceRndSet(BIG10, 20); // 2x2 hwall ruins + + DRLG_L2Subs(); + DRLG_L2Shadows(); + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } + + extern void DRLG_Init_Globals(); + DRLG_Init_Globals(); + // Check for any mini quest pieces + DRLG_CheckQuests(nSx1, nSy1); + +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +static void DRLG_InitL2Vals() +{ + int i,j; + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + // place tops of arches + int nPiece = dPiece[i][j]; + if (nPiece == 541) nPiece = 5; + else if (nPiece == 178) nPiece = 5; + else if (nPiece == 551) nPiece = 5; + else if (nPiece == 542) nPiece = 6; + else if (nPiece == 553) nPiece = 6; + else if (nPiece == 13) nPiece = 5; + else if (nPiece == 17) nPiece = 6; + else continue; + + dSpecial[i][j] = nPiece; + } + } + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 132) { + dSpecial[i][j+1] = 2; + dSpecial[i][j+2] = 1; + } + else if ((dPiece[i][j] == 135) || (dPiece[i][j] == 139)) { + dSpecial[i+1][j] = 3; + dSpecial[i+2][j] = 4; + } + } + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +void LoadL2Dungeon(char sFileName[], int vx, int vy) +{ + int i, j, rw, rh; + byte *pLevelMap, *lm; + + InitDungeon(); + DRLG_InitTrans(); + + pLevelMap = LoadFileInMemSig(sFileName,NULL,'LMPt'); + lm = pLevelMap; + + // Fill with dirt + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + dungeon[i][j] = DFLOOR_PIECE; + dflags[i][j] = 0; + } + } + + rw = *lm; + lm+=2; + rh = *lm; + lm+=2; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*lm != 0) { + dungeon[i][j] = *lm; + dflags[i][j] |= SETP_BIT; + } else dungeon[i][j] = FLOOR_PIECE; + lm+=2; + } + } + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if (dungeon[i][j] == 0) + dungeon[i][j] = DFLOOR_PIECE; + } + } + + DRLG_L2Pass3(); + + extern void DRLG_Init_Globals(); + DRLG_Init_Globals(); + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + int nPiece = dPiece[i][j]; + int top = 0; + if (nPiece == 541) top = 5; + if (nPiece == 178) top = 5; + if (nPiece == 551) top = 5; + if (nPiece == 542) top = 6; + if (nPiece == 553) top = 6; + if (nPiece == 13) top = 5; + if (nPiece == 17) top = 6; + dSpecial[i][j] = top; + } + } + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 132) { + dSpecial[i][j+1] = 2; + dSpecial[i][j+2] = 1; + } + else if ((dPiece[i][j] == 135) || (dPiece[i][j] == 139)) { + dSpecial[i+1][j] = 3; + dSpecial[i+2][j] = 4; + } + } + } + + ViewX = vx; + ViewY = vy; + + SetMapMonsters(pLevelMap, 0, 0); + SetMapObjects(pLevelMap, 0, 0); + //SetMapItems(pLevelMap); + + DiabloFreePtr(pLevelMap); +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +void LoadPreL2Dungeon(char sFileName[], int vx, int vy) +{ + int i, j, rw, rh; + byte *pLevelMap, *lm; + + InitDungeon(); + DRLG_InitTrans(); + + pLevelMap = LoadFileInMemSig(sFileName,NULL,'LMPt'); + lm = pLevelMap; + + // Fill with dirt + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + dungeon[i][j] = DFLOOR_PIECE; + dflags[i][j] = 0; + } + } + + rw = *lm; + lm+=2; + rh = *lm; + lm+=2; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*lm != 0) { + dungeon[i][j] = *lm; + dflags[i][j] |= SETP_BIT; + } else dungeon[i][j] = FLOOR_PIECE; + lm+=2; + } + } + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) + if (dungeon[i][j] == 0) dungeon[i][j] = DFLOOR_PIECE; + } + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } + + DiabloFreePtr(pLevelMap); +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) +void CreateL2Dungeon(unsigned int rseed, int entry) +{ +// dig.patch1.start.1/30/97 + + // The variables nSx1,nSx2,nSy1,nSy2 weren't getting initialized for level 8, + // nor for level 7 when the Q_BLIND quest is not chosen. + // The result of not setting those variables is that those levels + // differ slightly when they are loaded versus when they are generated. + + // Fix: In the above mentioned cases (level 8, and level 7 without Q_BLIND) + // we need to generate values for nSx1 etc. that are identical to how they + // were set when the levels were generated. The way to do that is to figure + // out which was the last level which set those variables, and temporarily + // recreate that level. + // Level 6 always generates values for the variables. + // Level 7 generates values only if (quests[Q_BLIND]._qactive != QUEST_NOTAVAIL) + + extern DWORD glSeedTbl[NUMLEVELS]; + extern BYTE gbMaxPlayers; + if (gbMaxPlayers == 1) { + if (currlevel == 7 && quests[Q_BLIND]._qactive == QUEST_NOTAVAIL) { + currlevel = 6; + CreateL2Dungeon(glSeedTbl[6], LVL_NODIR); + currlevel = 7; + } + if (currlevel == 8) { + if (quests[Q_BLIND]._qactive == QUEST_NOTAVAIL) { + currlevel = 6; + CreateL2Dungeon(glSeedTbl[6], LVL_NODIR); + currlevel = 8; + } + else { + currlevel = 7; + CreateL2Dungeon(glSeedTbl[7], LVL_NODIR); + currlevel = 8; + } + } + } +// dig.patch1.end.1/30/97 + + SetRndSeed(rseed); + + dminx = DIRTEDGED2; + dminy = DIRTEDGED2; + dmaxx = DMAXX - (DIRTEDGED2); + dmaxy = DMAXY - (DIRTEDGED2); + + DRLG_InitTrans(); + DRLG_InitSetPC(); + DRLG_LoadL2SP(); + DRLG_L2(entry); + DRLG_L2Pass3(); + DRLG_FreeL2SP(); + DRLG_InitL2Vals(); + DRLG_SetPC(); +} +#endif diff --git a/DRLG_L2.H b/DRLG_L2.H new file mode 100644 index 0000000..f4b4810 --- /dev/null +++ b/DRLG_L2.H @@ -0,0 +1,109 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L2.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define DIR_NONE 0 +#define DIR_NORTH 1 +#define DIR_EAST 2 +#define DIR_SOUTH 3 +#define DIR_WEST 4 + +#define AREA_MIN 2 + +#define MAX_DOORS 7 +#define MAX_ROOMS 80 + +#define ROOM_MAX 10 +#define ROOM_MIN 6 + +#define VWALL_PIECE 1 +#define HWALL_PIECE 2 +#define FLOOR_PIECE 3 +#define VDOOR_PIECE 4 +#define HDOOR_PIECE 5 +#define LRWALL_PIECE 6 +#define URWALL_PIECE 7 +#define ULWALL_PIECE 8 +#define LLWALL_PIECE 9 + +#define DVWALL_PIECE 10 +#define DHWALL_PIECE 11 +#define DFLOOR_PIECE 12 +#define DULWALL_PIECE 13 +#define DURWALL_PIECE 14 +#define DLLWALL_PIECE 15 +#define DLRWALL_PIECE 16 + +#define THEME_PIECE 252 + +#define NO_CHAR ' ' +#define WALL_CHAR '#' +#define FLOOR_CHAR '.' +#define HALL_CHAR ',' +#define DOOR_CHAR 'D' +#define LRWALL_CHAR 'A' +#define URWALL_CHAR 'B' +#define ULWALL_CHAR 'C' +#define LLWALL_CHAR 'E' + +#define L2_NUMBLOCKS 161 +#define L2_NUMSPATS 2 + +#define NOTOK 255 +#define OK 254 + +#define CNO 0 +#define CWALL 1 +#define CFLOOR 2 +#define CDOOR 3 +#define CEMPTY 4 +#define CDoF 5 +#define CDoW 6 +#define CEoF 7 +#define CDoWoF 8 + +#define SNUM1 2 +#define SNUM2 2 + +#define SETP_BIT 0x80 // Non changeable set piece bit + + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct NODE { + int nHallx1; + int nHally1; + int nHallx2; + int nHally2; + int nHalldir; + struct NODE * pNext; +} HALLNODE; + +typedef struct { + int nRoomx1; + int nRoomy1; + int nRoomx2; + int nRoomy2; + int nRoomDest; +} ROOMNODE; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void CreateL2Dungeon(unsigned int, int); +void LoadL2Dungeon(char [], int, int); +void LoadPreL2Dungeon(char [], int, int); + diff --git a/DRLG_L3.CPP b/DRLG_L3.CPP new file mode 100644 index 0000000..3beafba --- /dev/null +++ b/DRLG_L3.CPP @@ -0,0 +1,2842 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Dungeon file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L3.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +** CreateL1Dungeon +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "drlg_l3.h" +#include "gendung.h" +#include "scrollrt.h" +#include "engine.h" +#include "trigs.h" +#include "lighting.h" +#include "monster.h" +#include "objects.h" +#include "quests.h" + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszRegSig4[REG_LEN] = "REGISTRATION_BLOCK"; +//int SP3x1, SP3y1, SP3x2, SP3y2; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static const byte L3ConvTbl[16] = { 8, 11, 3, 10, 1, 9, 12, 12, 6, 13, 4, 13, 2, 14, 5, 7 }; + +static const byte L3UP[] = { 3, 3, // X size, Y size + + FILL, FILL, 0, // Pattern to look for + TOP_WALL, TOP_WALL, 0, + FLOOR, FLOOR, 0, + + 51, 50, 0, // Pattern to sub + 48, 49, 0, + 0, 0, 0}; + +//JKE level 6 stuff +static const byte L6UP[] = { 3, 3, // X size, Y size + + FILL, FILL, 0, // Pattern to look for + TOP_WALL, TOP_WALL, 0, + FLOOR, FLOOR, 0, + + 20, 19, 0, // Pattern to sub + 17, 18, 0, + 0, 0, 0}; + +static const byte L3DOWN[] = { 3, 3, // X size, Y size + + FILL, LEFT_WALL, FLOOR, // Pattern to look for + FILL, LEFT_WALL, FLOOR, + 0, 0, 0, + + 0, 47, 0, // Pattern to sub + 0, 46, 0, + 0, 0, 0}; + +// JKE level 6 stuff +static const byte L6DOWN[] = { 3, 3, // X size, Y size + + FILL, LEFT_WALL, FLOOR, // Pattern to look for + FILL, LEFT_WALL, FLOOR, + 0, 0, 0, + + 0, 16, 0, // Pattern to sub + 0, 15, 0, + 0, 0, 0}; + +static const byte L3HOLDWARP[] = { 3, 3, // X size, Y size + + FILL, FILL, 0, // Pattern to look for + TOP_WALL, TOP_WALL, 0, + FLOOR, FLOOR, 0, + + 125, 125, 0, // Pattern to sub + 125, 125, 0, + 0, 0, 0}; + +// JKE level 6 stuff +static const byte L6HOLDWARP[] = { 3, 3, // X size, Y size + + FILL, FILL, 0, // Pattern to look for + TOP_WALL, TOP_WALL, 0, + FLOOR, FLOOR, 0, + + 24, 23, 0, // Pattern to sub + 21, 22, 0, + 0, 0, 0}; + +static const byte L3TITE1[] = { 4, 4, // X size, Y size + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 0, 0, 0, 0, // Pattern to sub + 0, 57, 58, 0, + 0, 56, 55, 0, + 0, 0, 0, 0}; + +static const byte L3TITE2[] = { 4, 4, // X size, Y size + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 0, 0, 0, 0, // Pattern to sub + 0, 61, 62, 0, + 0, 60, 59, 0, + 0, 0, 0, 0}; + +static const byte L3TITE3[] = { 4, 4, // X size, Y size + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 0, 0, 0, 0, // Pattern to sub + 0, 65, 66, 0, + 0, 64, 63, 0, + 0, 0, 0, 0}; + +static const byte L3TITE4[] = { 4, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 0, 0, 0, 0, // Pattern to sub + 0, 70, 71, 0, + 0, 0, 0, 0}; + +static const byte L3TITE5[] = { 3, 4, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 0, 0, 0, // Pattern to sub + 0, 73, 0, + 0, 72, 0, + 0, 0, 0}; + +static const byte L3TITE6[] = { 5, 4, // X size, Y size + + FLOOR, FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, 0, FLOOR, + FLOOR, FLOOR, FLOOR, 0, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, FLOOR, + + 0, 0, 0, 0, 0, // Pattern to sub + 0, 77, 78, 0, 0, + 0, 76, 74, 75, 0, + 0, 0, 0, 0, 0}; + +static const byte L3TITE7[] = { 4, 5, // X size, Y size + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, 0, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 0, 0, 0, 0, // Pattern to sub + 0, 83, 0, 0, + 0, 82, 80, 0, + 0, 81, 79, 0, + 0, 0, 0, 0}; + +static const byte L3TITE8[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 0, 0, 0, // Pattern to sub + 0, 52, 0, + 0, 0, 0}; + +static const byte L3TITE9[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 0, 0, 0, // Pattern to sub + 0, 53, 0, + 0, 0, 0}; + +static const byte L3TITE10[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 0, 0, 0, // Pattern to sub + 0, 54, 0, + 0, 0, 0}; + +static const byte L3TITE11[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 0, 0, 0, // Pattern to sub + 0, 67, 0, + 0, 0, 0}; + +static const byte L3TITE12[] = { 2, 1, // X size, Y size + + LEFT_WALL, FLOOR, // Pattern to look for + + 68, 0}; // Pattern to sub + +static const byte L3TITE13[] = { 1, 2, // X size, Y size + + TOP_WALL, // Pattern to look for + FLOOR, + + 69, // Pattern to sub + 0}; + +static const byte L3CREV1[] = { 2, 1, // X size, Y size + + FILL, FLOOR, // Pattern to look for + + 84, 85}; // Pattern to sub + +static const byte L3CREV2[] = { 2, 1, // X size, Y size + + FILL, UL_WALL, // Pattern to look for + + 86, 87}; // Pattern to sub + +static const byte L3CREV3[] = { 1, 2, // X size, Y size + + FILL, // Pattern to look for + TOP_WALL, + + 89, // Pattern to sub + 88}; + +static const byte L3CREV4[] = { 2, 1, // X size, Y size + + FILL, FLOOR, // Pattern to look for + + 90, 91}; // Pattern to sub + +static const byte L3CREV5[] = { 1, 2, // X size, Y size + + FILL, // Pattern to look for + UL_WALL, + + 92, // Pattern to sub + 93}; + +static const byte L3CREV6[] = { 1, 2, // X size, Y size + + FILL, // Pattern to look for + TOP_WALL, + + 95, // Pattern to sub + 94}; + +static const byte L3CREV7[] = { 2, 1, // X size, Y size + + FILL, FLOOR, // Pattern to look for + + 96, 101}; // Pattern to sub + +static const byte L3CREV8[] = { 1, 2, // X size, Y size + + BOTTOM_WALL, // Pattern to look for + FILL, + + 102, // Pattern to sub + 97}; + +static const byte L3CREV9[] = { 2, 1, // X size, Y size + + UR_WALL, FILL, // Pattern to look for + + 103, 98}; // Pattern to sub + +static const byte L3CREV10[] = { 2, 1, // X size, Y size + + RIGHT_WALL, FILL, // Pattern to look for + + 104, 99}; // Pattern to sub + +static const byte L3CREV11[] = { 1, 2, // X size, Y size + + LR_WALL, // Pattern to look for + FILL, + + 105, // Pattern to sub + 100}; + +static const byte L3ISLE1[] = { 2, 3, // X size, Y size + + UL_ISLE, UR_ISLE, // Pattern to look for + RIGHT_WALL, LEFT_WALL, + LL_ISLE, LR_ISLE, + + 7, 7, // Pattern to sub + 7, 7, + 7, 7}; + +static const byte L3ISLE2[] = { 3, 2, // X size, Y size + + UL_ISLE, BOTTOM_WALL, UR_ISLE, // Pattern to look for + LL_ISLE, TOP_WALL, LR_ISLE, + + 7, 7, 7, // Pattern to sub + 7, 7, 7}; + +static const byte L3ISLE3[] = { 2, 3, // X size, Y size + + UL_ISLE, UR_ISLE, // Pattern to look for + RIGHT_WALL, LEFT_WALL, + LL_ISLE, LR_ISLE, + + 29, 30, // Pattern to sub + 25, 28, + 31, 32}; + +static const byte L3ISLE4[] = { 3, 2, // X size, Y size + + UL_ISLE, BOTTOM_WALL, UR_ISLE, // Pattern to look for + LL_ISLE, TOP_WALL, LR_ISLE, + + 29, 26, 30, // Pattern to sub + 31, 27, 32}; + +static const byte L3ISLE5[] = { 2, 2, // X size, Y size + + UL_ISLE, UR_ISLE, // Pattern to look for + LL_ISLE, LR_ISLE, + + 7, 7, // Pattern to sub + 7, 7}; + +static const byte L3XTRA1[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 106}; // Pattern to sub + +static const byte L3XTRA2[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 107}; // Pattern to sub + +static const byte L3XTRA3[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 108}; // Pattern to sub + +static const byte L3XTRA4[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 109}; // Pattern to sub + +static const byte L3XTRA5[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 110}; // Pattern to sub + +static const byte L3ANVIL[] = { 11, 11, + + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 29, 26, 26, 26, 26, 26, 30, 0, 0, + 0, 29, 34, 33, 33, 37, 36, 33, 35, 30, 0, + 0, 25, 33, 37, 27, 32, 31, 36, 33, 28, 0, + 0, 25, 37, 32, 7, 7, 7, 31, 27, 32, 0, + 0, 25, 28, 7, 7, 7, 7, BOTTOM_WALL, BOTTOM_WALL, BOTTOM_WALL, 0, + 0, 25, 35, 30, 7, 7, 7, 29, 26, 30, 0, + 0, 25, 33, 35, 26, 30, 29, 34, 33, 28, 0, + 0, 31, 36, 33, 33, 35, 34, 33, 37, 32, 0, + 0, 0, 31, 27, 27, 27, 27, 27, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +// JKE begin L6 extras +static const byte L6FILL1[] = { 1, 1, // X size, Y size + + FILL, // Pattern to look for + + 25}; // Pattern to sub +static const byte L6FILL2[] = { 1, 1, // X size, Y size + + FILL, // Pattern to look for + + 26}; // Pattern to sub +static const byte L6FILL3[] = { 1, 1, // X size, Y size + + FILL, // Pattern to look for + + 27}; // Pattern to sub +static const byte L6FILL4[] = { 1, 1, // X size, Y size + + FILL, // Pattern to look for + + 28}; // Pattern to sub +static const byte L6FLOOR1[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 29}; // Pattern to sub +static const byte L6FLOOR2[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 30}; // Pattern to sub +static const byte L6FLOOR3[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 31}; // Pattern to sub +static const byte L6FLOOR4[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 32}; // Pattern to sub +static const byte L6FLOOR5[] = { 3, 3, // X size, Y size + + FLOOR,FLOOR,FLOOR, // Pattern to look for + FLOOR,FLOOR,FLOOR, + FLOOR,FLOOR,FLOOR, + + 0, 0 ,0, + 0,126,0, + 0, 0 ,0}; // Pattern to sub +static const byte L6FLOOR6[] = { 3, 3, // X size, Y size + + FLOOR,FLOOR,FLOOR, // Pattern to look for + FLOOR,FLOOR,FLOOR, + FLOOR,FLOOR,FLOOR, + + 0, 0 ,0, + 0,124,0, + 0, 0 ,0}; // Pattern to sub +static const byte L6WALL1[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 33}; // Pattern to sub +static const byte L6WALL2[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 34}; // Pattern to sub +static const byte L6WALL3[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 35}; // Pattern to sub +static const byte L6WALL4[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 36}; // Pattern to sub +static const byte L6WALL5[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 37}; // Pattern to sub +static const byte L6CORNER1[] = { 1, 1, // X size, Y size + + UL_WALL, // Pattern to look for + + 38}; // Pattern to sub +static const byte L6WALL6[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 39}; // Pattern to sub +static const byte L6WALL7[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 40}; // Pattern to sub +static const byte L6WALL8[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 41}; // Pattern to sub +static const byte L6WALL9[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 42}; // Pattern to sub +static const byte L6WALL10[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 43}; // Pattern to sub +static const byte L6CORNER2[] = { 1, 1, // X size, Y size + + UL_WALL, // Pattern to look for + + 44}; // Pattern to sub +static const byte L6WALL11[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 45}; // Pattern to sub +static const byte L6WALL12[] = { 1, 1, // X size, Y size + + LEFT_WALL, // Pattern to look for + + 46}; // Pattern to sub +static const byte L6WALL13[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 47}; // Pattern to sub +static const byte L6WALL14[] = { 1, 1, // X size, Y size + + TOP_WALL, // Pattern to look for + + 48}; // Pattern to sub +static const byte L6CORNER3[] = { 1, 1, // X size, Y size + + UL_WALL, // Pattern to look for + + 49}; // Pattern to sub +static const byte L6CORNER4[] = { 1, 1, // X size, Y size + + UL_WALL, // Pattern to look for + + 50}; // Pattern to sub +//======================================================================================= +// Stalagmites +//======================================================================================= + +static const byte L6TITE1[] = { 3, 3, // X size, Y size + + FLOOR,FLOOR, FLOOR, // Pattern to look for + FLOOR,FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 67, 0, 0, // Pattern to sub + 66,51, 0, + 0, 0, 0}; + +static const byte L6TITE2[] = { 3,3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 69, 0, 0, // Pattern to sub + 68, 52,0, + 0, 0, 0}; + +static const byte L6TITE3[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 70, 0, 0, // Pattern to sub + 71, 53, 0, + 0, 0, 0}; +static const byte L6TITE4[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 73, 0, 0, // Pattern to sub + 72, 54, 0, + 0, 0, 0}; +static const byte L6TITE5[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 75, 0, 0, // Pattern to sub + 74, 55, 0, + 0, 0, 0}; +static const byte L6TITE6[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 77, 0, 0, // Pattern to sub + 76, 56, 0, + 0, 0, 0}; +static const byte L6TITE7[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 79, 0, 0, // Pattern to sub + 78, 57, 0, + 0, 0, 0}; +static const byte L6TITE8[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 81, 0, 0, // Pattern to sub + 80, 58, 0, + 0, 0, 0}; +static const byte L6TITE9[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 83, 0, 0, // Pattern to sub + 82, 59, 0, + 0, 0, 0}; +static const byte L6TITE10[] = { 3, 3, // X size, Y size + + FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, + + 84, 0, 0, // Pattern to sub + 85, 60, 0, + 0, 0, 0}; + +static const byte ACIDISLE1[] = { 2, 3, // X size, Y size + + UL_ISLE, UR_ISLE, // Pattern to look for + RIGHT_WALL, LEFT_WALL, + LL_ISLE, LR_ISLE, + + 7, 7, // Pattern to sub + 7, 7, + 7, 7}; + +static const byte ACIDISLE2[] = { 3, 2, // X size, Y size + + UL_ISLE, BOTTOM_WALL, UR_ISLE, // Pattern to look for + LL_ISLE, TOP_WALL, LR_ISLE, + + 7, 7, 7, // Pattern to sub + 7, 7, 7}; + +static const byte ACIDISLE3[] = { 2, 3, // X size, Y size + + UL_ISLE, UR_ISLE, // Pattern to look for + RIGHT_WALL, LEFT_WALL, + LL_ISLE, LR_ISLE, + + 107, 115, // Pattern to sub + 119, 122, + 131, 123}; + +static const byte ACIDISLE4[] = { 3, 2, // X size, Y size + + UL_ISLE, BOTTOM_WALL, UR_ISLE, // Pattern to look for + LL_ISLE, TOP_WALL, LR_ISLE, + + 107, 120, 115, // Pattern to sub + 131, 121, 123}; + +static const byte ACIDISLE5[] = { 2, 2, // X size, Y size + + UL_ISLE, UR_ISLE, // Pattern to look for + LL_ISLE, LR_ISLE, + + 7, 7, // Pattern to sub + 7, 7}; + +static const byte L6ACIDTEST[] = { 1, 1, // X size, Y size + + FLOOR, // Pattern to look for + + 131}; // Pattern to sub + +static const byte L6ACID1[] = { 4, 4, + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 7, 7 , 7 ,7, + 7,107,115,7, + 7,131,123,7, + 7, 7 , 7 ,7}; + +static const byte L6ACID2[] = { 4, 4, + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 7, 7 , 7 ,7, + 7, 7 ,108,7, + 7,109,112,7, + 7, 7 , 7 ,7}; + +static const byte L6ACID3[] = { 4, 5, + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 7, 7 , 7 ,7, + 7,107,115,7, + 7,119,122,7, + 7,131,123,7, + 7, 7 , 7 ,7}; + +static const byte L6ACID4[] = { 4, 5, + + FLOOR, FLOOR, FLOOR, FLOOR, // Pattern to look for + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + FLOOR, FLOOR, FLOOR, FLOOR, + + 7, 7 , 7 ,7, + 7,126,108,7, + 7, 7 ,117,7, + 7,109,112,7, + 7, 7 , 7 ,7}; + +static int abyssx; +static BYTE lavapool; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void InitL3Dungeon() { + ZeroMemory(dungeon,sizeof(dungeon)); + int i, j; + + for (i = 0; i < MDMAXY; i++) { + + for (j = 0; j < MDMAXX; j++) { + dungeon[j][i] = D3_NULL; + dflags[j][i] = 0; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* + +void DRLG_LoadL3SP() +{ + setloadflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* +void DRLG_FreeL3SP() { + DiabloFreePtr(pSetPiece); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +void DRLG_L3SetRoom(int rx1, int ry1) +{ + int rw,rh; + int i,j; + byte *sp; + + sp = pSetPiece; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = rw; + setpc_h = rh; + + sp = pSetPiece+4; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp != 0) { + dungeon[rx1+i][ry1+j] = *sp; + dflags[rx1+i][ry1+j] |= SETP_BIT; + } else dungeon[rx1+i][ry1+j] = FLOOR; + sp+=2; + } + } + + } + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static int DRLG_L3FillRoom(int x1, int y1, int x2, int y2) +{ + int i,j,v,rv,rf; + + if ((x1 > 1) && (x2 < (MDMAXX-6)) && (y1 > 1) && (y2 < (MDMAXY-2))) { + v = 0; + for (j = y1; j <= y2; j++) { + for (i = x1; i <= x2; i++) v += dungeon[i][j]; + } + if (v == 0) { + for (j = (y1+1); j < y2; j++) { + for (i = (x1+1); i < x2; i++) dungeon[i][j] = 1; + } + for (j = y1; j <= y2; j++) { + rf = random(0, 2); + if (rf != 0) dungeon[x1][j] = 1; + rf = random(0, 2); + if (rf != 0) dungeon[x2][j] = 1; + } + for (i = x1; i <= x2; i++) { + rf = random(0, 2); + if (rf != 0) dungeon[i][y1] = 1; + rf = random(0, 2); + if (rf != 0) dungeon[i][y2] = 1; + } + rv = FR_TRUE; + } else rv = FR_FALSE; + } else rv = FR_FALSE; + return (rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DRLG_L3CreateBlock(int x, int y, int obs, int dir) +{ + int blksizex, blksizey, cbd; + int x1,y1,x2,y2; + int contflag; + + blksizex = random(0, 2) + 3; // 3-5 width and height + blksizey = random(0, 2) + 3; + + if (dir == BLK_U) { + y2 = y - 1; + y1 = y2 - blksizey; + if (blksizex < obs) x1 = random(0, blksizex) + x; + if (blksizex == obs) x1 = x; + if (blksizex > obs) x1 = x - random(0, blksizex); + x2 = x1 + blksizex; + } + if (dir == BLK_L) { + x2 = x - 1; + x1 = x2 - blksizex; + if (blksizey < obs) y1 = random(0, blksizey) + y; + if (blksizey == obs) y1 = y; + if (blksizey > obs) y1 = y - random(0, blksizey); + y2 = y1 + blksizey; + } + if (dir == BLK_D) { + y1 = y + 1; + y2 = y1 + blksizey; + if (blksizex < obs) x1 = random(0, blksizex) + x; + if (blksizex == obs) x1 = x; + if (blksizex > obs) x1 = x - random(0, blksizex); + x2 = x1 + blksizex; + } + if (dir == BLK_R) { + x1 = x + 1; + x2 = x1 + blksizex; + if (blksizey < obs) y1 = random(0, blksizey) + y; + if (blksizey == obs) y1 = y; + if (blksizey > obs) y1 = y - random(0, blksizey); + y2 = y1 + blksizey; + } + contflag = DRLG_L3FillRoom(x1,y1,x2,y2); + if (contflag == FR_TRUE) { + cbd = random(0, 4); + if ((cbd != 0) && (dir != BLK_D)) DRLG_L3CreateBlock(x1,y1,blksizey,BLK_U); + if ((cbd != 0) && (dir != BLK_L)) DRLG_L3CreateBlock(x2,y1,blksizex,BLK_R); + if ((cbd != 0) && (dir != BLK_U)) DRLG_L3CreateBlock(x1,y2,blksizey,BLK_D); + if ((cbd != 0) && (dir != BLK_R)) DRLG_L3CreateBlock(x1,y1,blksizex,BLK_L); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DRLG_L3FloorArea(int x1, int y1, int x2, int y2) +{ + int i,j; + + for (j = y1; j <= y2; j++) { + for (i = x1; i <= x2; i++) dungeon[i][j] = 1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3FillDiags() +{ + int i,j,v,rv; + + for (j = 0; j < (MDMAXY-1); j++) { + for (i = 0; i < (MDMAXX-1); i++) { + v = dungeon[i][j] << 3; // x8 + v += dungeon[i+1][j] << 2; // x4 + v += dungeon[i][j+1] << 1; // x2 + v += dungeon[i+1][j+1]; + if (v == 6) { + rv = random(0, 2); + if (rv == 0) dungeon[i][j] = 1; + else dungeon[i+1][j+1] = 1; + } + if (v == 9) { + rv = random(0, 2); + if (rv == 0) dungeon[i+1][j] = 1; + else dungeon[i][j+1] = 1; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3FillSingles() +{ + int i,j,v; + + for (j = 1; j < (MDMAXY-1); j++) { + for (i = 1; i < (MDMAXX-1); i++) { + if (dungeon[i][j] == 0) { + v = dungeon[i-1][j-1] + dungeon[i][j-1] + dungeon[i+1][j-1]; + if (v == 3) { + v = dungeon[i-1][j] + dungeon[i+1][j]; + if (v == 2) { + v = dungeon[i-1][j+1] + dungeon[i][j+1] + dungeon[i+1][j+1]; + if (v == 3) dungeon[i][j] = 1; + } + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3FillStraights() +{ + int i,j; + int xc,xs; + int yc,ys; + int k,rv; + + for (j = 0; j < (MDMAXY-1); j++) { + xc = 0; + for (i = 0; i < (MDMAXX-3); i++) { + if ((dungeon[i][j] == 0) && (dungeon[i][j+1] == 1)) { + if (xc == 0) xs = i; + xc++; + } else { + if ((xc > 3) && (random(0, 2))) { + for (k = xs; k < i; k++) { + rv = random(0, 2); + dungeon[k][j] = rv; + } + } + xc = 0; + } + } + } + for (j = 0; j < (MDMAXY-1); j++) { + xc = 0; + for (i = 0; i < (MDMAXX-3); i++) { + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 0)) { + if (xc == 0) xs = i; + xc++; + } else { + if ((xc > 3) && (random(0, 2))) { + for (k = xs; k < i; k++) { + rv = random(0, 2); + dungeon[k][j+1] = rv; + } + } + xc = 0; + } + } + } + for (i = 0; i < (MDMAXX-1); i++) { + yc = 0; + for (j = 0; j < (MDMAXY-3); j++) { + if ((dungeon[i][j] == 0) && (dungeon[i+1][j] == 1)) { + if (yc == 0) ys = j; + yc++; + } else { + if ((yc > 3) && (random(0, 2))) { + for (k = ys; k < j; k++) { + rv = random(0, 2); + dungeon[i][k] = rv; + } + } + yc = 0; + } + } + } + for (i = 0; i < (MDMAXX-1); i++) { + yc = 0; + for (j = 0; j < (MDMAXY-3); j++) { + if ((dungeon[i][j] == 1) && (dungeon[i+1][j] == 0)) { + if (yc == 0) ys = j; + yc++; + } else { + if ((yc > 3) && (random(0, 2))) { + for (k = ys; k < j; k++) { + rv = random(0, 2); + dungeon[i+1][k] = rv; + } + } + yc = 0; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3Edges() +{ + int i,j; + + for (j = 0; j < MDMAXY; j++) dungeon[MDMAXX-1][j] = 0; + for (i = 0; i < MDMAXX; i++) dungeon[i][MDMAXY-1] = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static int DRLG_L3GetFloorArea() +{ + int i,j,gfa; + + gfa = 0; + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) gfa += dungeon[i][j]; + } + return(gfa); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3MakeMegas() +{ + int i,j,k,v; + + for (j = 0; j < (MDMAXY-1); j++) { + for (i = 0; i < (MDMAXX-1); i++) { + v = dungeon[i][j] << 3; + v += dungeon[i+1][j] << 2; + v += dungeon[i][j+1] << 1; + v += dungeon[i+1][j+1]; + if (v == 6) { + k = random(0, 2); + if (k == 0) v = 12; + else v = 5; + } + if (v == 9) { + k = random(0, 2); + if (k == 0) v = 13; + else v = 14; + } + dungeon[i][j] = L3ConvTbl[v]; + } + dungeon[MDMAXX-1][j] = L3_DIRT; + } + for (i = 0; i < MDMAXX; i++) dungeon[i][MDMAXY-1] = L3_DIRT; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3River() +{ + int rx, ry, px, py; + int dir, pdir, nodir, nodir2, dircheck; + int river[3][100], rivercnt, riveramt; + int i, j; + int trys, found, bridge, lpcnt, bail; + + riveramt = 0; + found = 0; + trys = 0; + + while (trys < 200 && riveramt < 4) { + found = 0; + + while (found == 0 && trys < 200) { + rivercnt = 0; + trys++; + + rx = 0; + ry = 0; + bail = 0; + while ((dungeon[rx][ry] < 25 || dungeon[rx][ry] > 28) && (bail < 100)) { + rx = random(0, MDMAXX); + ry = random(0, MDMAXY); + bail++; + while ((dungeon[rx][ry] < 25 || dungeon[rx][ry] > 28) && (ry < MDMAXY)) { + rx ++; + if (rx >= MDMAXX) { + rx = 0; + ry++; + } + } + } + + if (bail >= 100) return; + + switch (dungeon[rx][ry]) { + case 25: + dir = WEST; + nodir = EAST; + river[2][rivercnt] = 40; + break; + case 26: + dir = NORTH; + nodir = SOUTH; + river[2][rivercnt] = 38; + break; + case 27: + dir = SOUTH; + nodir = NORTH; + river[2][rivercnt] = 41; + break; + case 28: + dir = EAST; + nodir = WEST; + river[2][rivercnt] = 39; + break; + } + river[0][rivercnt] = rx; + river[1][rivercnt] = ry; + rivercnt++; + + nodir2 = 4; + dircheck = 0; + while (dircheck < 4 && rivercnt < 100) { + + px = rx; + py = ry; + + if (dircheck == 0) dir = random(0, 4); + else dir = (dir + 1) & 3; + dircheck++; + + while (dir == nodir || dir == nodir2) { + dir = (dir + 1) & 3; + dircheck++; + } + + if (dir == NORTH && ry > 0) ry--; + if (dir == SOUTH && ry < MDMAXY) ry++; + if (dir == EAST && rx < MDMAXX) rx++; + if (dir == WEST && rx > 0) rx--; + + if (dungeon[rx][ry] == 7) { + dircheck = 0; + if (dir < EAST) river[2][rivercnt] = 17 + (BYTE)random(0, 2); + if (dir > SOUTH) river[2][rivercnt] = 15 + (BYTE)random(0, 2); + river[0][rivercnt] = rx; + river[1][rivercnt] = ry; + rivercnt++; + + if ((dir == NORTH && pdir == EAST) || (dir == WEST && pdir == SOUTH)) { + if (rivercnt > 2) river[2][rivercnt-2] = 22; + if (dir == NORTH) nodir2 = SOUTH; + else nodir2 = EAST; + } + if ((dir == NORTH && pdir == WEST) || (dir == EAST && pdir == SOUTH)) { + if (rivercnt > 2) river[2][rivercnt-2] = 21; + if (dir == NORTH) nodir2 = SOUTH; + else nodir2 = WEST; + } + if ((dir == SOUTH && pdir == EAST) || (dir == WEST && pdir == NORTH)) { + if (rivercnt > 2) river[2][rivercnt-2] = 20; + if (dir == SOUTH) nodir2 = NORTH; + else nodir2 = EAST; + } + if ((dir == SOUTH && pdir == WEST) || (dir == EAST && pdir == NORTH)) { + if (rivercnt > 2) river[2][rivercnt-2] = 19; + if (dir == SOUTH) nodir2 = NORTH; + else nodir2 = WEST; + } + + pdir = dir; + } + else { + rx = px; + ry = py; + } + } + + if (dir == NORTH && dungeon[rx][ry-1] == 10 && dungeon[rx][ry-2] == 8) { + river[0][rivercnt] = rx; + river[1][rivercnt] = ry-1; + river[2][rivercnt] = 24; + if (pdir == EAST) river[2][rivercnt-1] = 22; + if (pdir == WEST) river[2][rivercnt-1] = 21; + found = 1; + } + if (dir == SOUTH && dungeon[rx][ry+1] == 2 && dungeon[rx][ry+2] == 8) { + river[0][rivercnt] = rx; + river[1][rivercnt] = ry+1; + river[2][rivercnt] = 42; + if (pdir == EAST) river[2][rivercnt-1] = 20; + if (pdir == WEST) river[2][rivercnt-1] = 19; + found = 1; + } + if (dir == EAST && dungeon[rx+1][ry] == 4 && dungeon[rx+2][ry] == 8) { + river[0][rivercnt] = rx+1; + river[1][rivercnt] = ry; + river[2][rivercnt] = 43; + if (pdir == NORTH) river[2][rivercnt-1] = 19; + if (pdir == SOUTH) river[2][rivercnt-1] = 21; + found = 1; + } + if (dir == WEST && dungeon[rx-1][ry] == 9 && dungeon[rx-2][ry] == 8) { + river[0][rivercnt] = rx-1; + river[1][rivercnt] = ry; + river[2][rivercnt] = 23; + if (pdir == NORTH) river[2][rivercnt-1] = 20; + if (pdir == SOUTH) river[2][rivercnt-1] = 22; + found = 1; + } + } + + if (found == 1 && rivercnt < 7) found = 0; + + if (found == 1) { + + bridge = 0; + lpcnt = 0; + while (bridge == 0 && lpcnt < 30) { + lpcnt++; + i = random(0, rivercnt); + if (((river[2][i] == 15) || (river[2][i] == 16)) && + (dungeon[(river[0][i])][(river[1][i])-1] == 7) && (dungeon[(river[0][i])][(river[1][i])+1] == 7)) + bridge = 1; + if (((river[2][i] == 17) || (river[2][i] == 18)) && + (dungeon[(river[0][i])-1][(river[1][i])] == 7) && (dungeon[(river[0][i])+1][(river[1][i])] == 7)) + bridge = 2; + + for (j = 0; j < rivercnt && bridge != 0; j++) { + if ((bridge == 1) && ((river[1][i] - 1 == river[1][j]) || (river[1][i] + 1 == river[1][j])) && + (river[0][i] == river[0][j])) bridge = 0; + if ((bridge == 2) && ((river[0][i] - 1 == river[0][j]) || (river[0][i] + 1 == river[0][j])) && + (river[1][i] == river[1][j])) bridge = 0; + } + } + + if (bridge != 0) { + if (bridge == 1) river[2][i] = 44; + else river[2][i] = 45; + riveramt++; + for (i = 0; i <= rivercnt; i++) dungeon[(river[0][i])][(river[1][i])] = river[2][i]; + } + else found = 0; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int DRLG_L3SpawnEdge(int x, int y, int * totarea) +{ + BYTE i; + static const BYTE spawntable[] = {0x00,0x0a,0x43,0x05,0x2c,0x06,0x09,0x00,0x00,0x1c,0x83,0x06,0x09,0x0a,0x05}; + + if ((*totarea) > 40) return 1; + if (x < 0 || y < 0 || x >= MDMAXX || y >= MDMAXY) return 1; + + if ((dungeon[x][y] & 0x80) != 0) return 0; + if (dungeon[x][y] > 15) return 1; + + i = dungeon[x][y]; + dungeon[x][y] |= 0x80; + (*totarea)++; + + if (((spawntable[i] & 0x08) != 0) && ((DRLG_L3SpawnEdge (x, y-1, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x04) != 0) && ((DRLG_L3SpawnEdge (x, y+1, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x02) != 0) && ((DRLG_L3SpawnEdge (x+1, y, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x01) != 0) && ((DRLG_L3SpawnEdge (x-1, y, totarea)) == 1)) return 1; + + if (((spawntable[i] & 0x80) != 0) && ((DRLG_L3Spawn (x, y-1, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x40) != 0) && ((DRLG_L3Spawn (x, y+1, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x20) != 0) && ((DRLG_L3Spawn (x+1, y, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x10) != 0) && ((DRLG_L3Spawn (x-1, y, totarea)) == 1)) return 1; + + return 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int DRLG_L3Spawn(int x, int y, int * totarea) +{ + BYTE i; + static const BYTE spawntable[] = {0x00,0x0a,0x03,0x05,0x0c,0x06,0x09,0x00,0x00,0x0c,0x03,0x06,0x09,0x0a,0x05}; + + if ((*totarea) > 40) return 1; + if (x < 0 || y < 0 || x >= MDMAXX || y >= MDMAXY) return 1; + + if ((dungeon[x][y] & 0x80) != 0) return 0; + if (dungeon[x][y] > 15) return 1; + + i = dungeon[x][y]; + dungeon[x][y] |= 0x80; + (*totarea)++; + + if (i != 8) { + + if (((spawntable[i] & 0x08) != 0) && ((DRLG_L3SpawnEdge (x, y-1, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x04) != 0) && ((DRLG_L3SpawnEdge (x, y+1, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x02) != 0) && ((DRLG_L3SpawnEdge (x+1, y, totarea)) == 1)) return 1; + if (((spawntable[i] & 0x01) != 0) && ((DRLG_L3SpawnEdge (x-1, y, totarea)) == 1)) return 1; + } + else { + + if ((DRLG_L3Spawn (x+1, y, totarea)) == 1) return 1; + if ((DRLG_L3Spawn (x-1, y, totarea)) == 1) return 1; + if ((DRLG_L3Spawn (x, y+1, totarea)) == 1) return 1; + if ((DRLG_L3Spawn (x, y-1, totarea)) == 1) return 1; + } + + return 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3Pool() +{ + int i, j, found; + int dunx, duny; + int totarea, poolchance; + BYTE k; + static const BYTE poolsub[] = {0,35,26,36,25,29,34,7,33,28,27,37,32,31,30}; + + for (duny = 0; duny < MDMAXY; duny++) { + for (dunx = 0; dunx < MDMAXX; dunx++) { + + if (dungeon[dunx][duny] == 8) { + + dungeon[dunx][duny] |= 0x80; + totarea = 1; + found = 0; + + if (dunx+1 < MDMAXX && found == 0) found = DRLG_L3Spawn (dunx+1, duny, &totarea); + else found = 1; + if (dunx-1 > 0 && found == 0) found = DRLG_L3Spawn (dunx-1, duny, &totarea); + else found = 1; + if (duny+1 < MDMAXY && found == 0) found = DRLG_L3Spawn (dunx, duny+1, &totarea); + else found = 1; + if (duny-1 > 0 && found == 0) found = DRLG_L3Spawn (dunx, duny-1, &totarea); + else found = 1; + + poolchance = random(0, 100); + for (i = duny-totarea; i < duny+totarea; i++) { + for (j = dunx-totarea; j < dunx+totarea; j++) { + + if ((dungeon[j][i] & 0x80) != 0 && i >= 0 && i < MDMAXY && j >= 0 && j < MDMAXX) { + + dungeon[j][i] &= 0x7f; + + if (totarea > 4 && poolchance < 25 && found == 0) { + k = poolsub[(dungeon[j][i])]; + if (k != 0 && k <= 37) + dungeon[j][i] = k; + lavapool = TRUE; + } + } + } + } + } + } + } +} +static void AcidPool() +{ + int i, j, found; + int dunx, duny; + int totarea, poolchance; + BYTE k; + static const BYTE poolsub[] = {0,133,120,125,119,107,132,7,134,122,121,118,123,131,115}; + + for (duny = 0; duny < MDMAXY; duny++) { + for (dunx = 0; dunx < MDMAXX; dunx++) { + + if (dungeon[dunx][duny] == 8) { + + dungeon[dunx][duny] |= 0x80; + totarea = 1; + found = 0; + + if (dunx+1 < MDMAXX && found == 0) found = DRLG_L3Spawn (dunx+1, duny, &totarea); + else found = 1; + if (dunx-1 > 0 && found == 0) found = DRLG_L3Spawn (dunx-1, duny, &totarea); + else found = 1; + if (duny+1 < MDMAXY && found == 0) found = DRLG_L3Spawn (dunx, duny+1, &totarea); + else found = 1; + if (duny-1 > 0 && found == 0) found = DRLG_L3Spawn (dunx, duny-1, &totarea); + else found = 1; + + poolchance = random(0, 100); + for (i = duny-totarea; i < duny+totarea; i++) { + for (j = dunx-totarea; j < dunx+totarea; j++) { + + if ((dungeon[j][i] & 0x80) != 0 && i >= 0 && i < MDMAXY && j >= 0 && j < MDMAXX) { + + dungeon[j][i] &= 0x7f; + + if (totarea > 4 && poolchance < 25 && found == 0) { + k = poolsub[(dungeon[j][i])]; + if (k != 0 && k <= 131) + dungeon[j][i] = k; + lavapool = TRUE; + } + } + } + } + } + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3PoolFix() +{ + int dunx, duny; + + for (duny = 0; duny < MDMAXY; duny++) { + for (dunx = 0; dunx < MDMAXX; dunx++) { + if ((dungeon[dunx][duny] == 8) && + ((dungeon[dunx-1][duny-1] >= 25 && dungeon[dunx-1][duny-1] <= 41) && + (dungeon[dunx-1][duny] >= 25 && dungeon[dunx-1][duny] <= 41) && + (dungeon[dunx-1][duny+1] >= 25 && dungeon[dunx-1][duny+1] <= 41) && + (dungeon[dunx][duny-1] >= 25 && dungeon[dunx][duny-1] <= 41) && + //(dungeon[dunx][duny] >= 25 && dungeon[dunx][duny+1] <= 41) && + (dungeon[dunx][duny+1] >= 25 && dungeon[dunx][duny+1] <= 41) && + (dungeon[dunx+1][duny-1] >= 25 && dungeon[dunx+1][duny-1] <= 41) && + (dungeon[dunx+1][duny] >= 25 && dungeon[dunx+1][duny] <= 41) && + (dungeon[dunx+1][duny+1] >= 25 && dungeon[dunx+1][duny+1] <= 41))) + + dungeon[dunx][duny] = 33; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void AcidPoolFix() +{ + int dunx, duny; + + for (duny = 0; duny < MDMAXY; duny++) { + for (dunx = 0; dunx < MDMAXX; dunx++) + { + if ((dungeon[dunx][duny] == 8) && + ((dungeon[dunx-1][duny-1] >= 107 && dungeon[dunx-1][duny-1] <= 135) || + (dungeon[dunx-1][duny] >= 107 && dungeon[dunx-1][duny] <= 135) || + (dungeon[dunx-1][duny+1] >= 107 && dungeon[dunx-1][duny+1] <= 135) || + (dungeon[dunx][duny-1] >= 107 && dungeon[dunx][duny-1] <= 135) || + //(dungeon[dunx][duny] >= 25 && dungeon[dunx][duny+1] <= 41) && + (dungeon[dunx][duny+1] >= 107 && dungeon[dunx][duny+1] <= 135) || + (dungeon[dunx+1][duny-1] >= 107 && dungeon[dunx+1][duny-1] <= 135) || + (dungeon[dunx+1][duny] >= 107 && dungeon[dunx+1][duny] <= 135) || + (dungeon[dunx+1][duny+1] >= 107 && dungeon[dunx+1][duny+1] <= 135))) + + dungeon[dunx][duny] = 134; + + if ((dungeon[dunx][duny] < 7) && + ((dungeon[dunx+1][duny] >= 107 && dungeon[dunx+1][duny] <= 135) || + (dungeon[dunx][duny-1] >= 107 && dungeon[dunx][duny-1] <= 135))) + + dungeon[dunx][duny] = 131; + + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int DRLG_L3PlaceMiniSet(const byte miniset[], int tmin, int tmax, int cx, int cy, int setview, int ldir) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int i, ii, numt; + int found, trys; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Number of pieces to place + if ((tmax - tmin) == 0) numt = 1; + else numt = random(0, tmax - tmin) + tmin; + + for (i = 0; i < numt; i++) { + // Random starting pos + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + + // Find a location for the mini set piece + found = 0; + trys = 0; + while ((found == 0) && (trys < 200)) { + trys++; + found = 1; + +// if (((sx >= SP3x1) && (sx <= SP3x2)) && ((sy >= SP3y1) && (sy <= SP3y2))) found = 0; + + if ((cx != -1) && (sx >= (cx - sw)) && (sx <= (cx + 12))) { + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + found = 0; + } + if ((cy != -1) && (sy >= (cy - sh)) && (sy <= (cy + 12))) { + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + found = 0; + } + ii = 2; + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx+xx][sy+yy] != miniset[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + if (found == 0) { + sx++; + if (sx == (MDMAXX - sw)) { + sx = 0; + sy++; + if (sy == (MDMAXY - sh)) sy = 0; + } + } + } + + if (trys >= 200) return 1; + + // Place mini set piece + ii = (sh * sw) + 2; + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[ii] != 0) dungeon[sx+xx][sy+yy] = miniset[ii]; + ii++; + } + } + } + + if (setview == 1) { + ViewX = (sx << 1) + (DIRTEDGED2) + 1; + ViewY = (sy << 1) + (DIRTEDGED2) + 3; + } + + if (ldir == LVL_DOWN) { + LvlViewX = (sx << 1) + (DIRTEDGED2) + 1; + LvlViewY = (sy << 1) + (DIRTEDGED2) + 3; + } + + return 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3PlaceRndSet(const byte miniset[], int rndper) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int ii, kk; + int found; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Find a location for the mini set piece + for (sy = 0; sy < (MDMAXY - sh); sy++) { + for (sx = 0; sx < (MDMAXX - sw); sx++) { + found = 1; + ii = 2; + +// if (((sx >= SP3x1) && (sx <= SP3x2)) && ((sy >= SP3y1) && (sy <= SP3y2))) found = 0; + + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx+xx][sy+yy] != miniset[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + + kk = (sh * sw) + 2; + if (miniset[kk] >= 84 && miniset[kk] <=100 && found == 1) { + if (dungeon[sx-1][sy] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + if (dungeon[sx+1][sy] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + if (dungeon[sx][sy+1] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + if (dungeon[sx][sy-1] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + } + + if ((found == 1) && (random(0, 100) < rndper)) { + // Place mini set piece + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[kk] != 0) dungeon[sx+xx][sy+yy] = miniset[kk]; + kk++; + } + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static unsigned char DRLG_L3PlaceAcidPool(const byte miniset[], int rndper) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int ii, kk; + int found; + unsigned char made = 0; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Find a location for the mini set piece + for (sy = 0; sy < (MDMAXY - sh); sy++) { + for (sx = 0; sx < (MDMAXX - sw); sx++) { + found = 1; + ii = 2; + +// if (((sx >= SP3x1) && (sx <= SP3x2)) && ((sy >= SP3y1) && (sy <= SP3y2))) found = 0; + + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx+xx][sy+yy] != miniset[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + + kk = (sh * sw) + 2; + if (miniset[kk] >= 84 && miniset[kk] <=100 && found == 1) { + if (dungeon[sx-1][sy] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + if (dungeon[sx+1][sy] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + if (dungeon[sx][sy+1] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + if (dungeon[sx][sy-1] >= 84 && dungeon[sx-1][sy] <= 100) found = 0; + } + + if ((found == 1) && (random(0, 100) < rndper)) { + // Place mini set piece + made = 1; + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[kk] != 0) dungeon[sx+xx][sy+yy] = miniset[kk]; + kk++; + } + } + } + } + } + return made; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3Abyss() +{ + int ax, sf, j; + + ax = MDMAXX - 1; + sf = 0; + while (sf == 0) { + for (j = 0; (j < MDMAXY) && (sf == 0); j++) + if (dungeon[ax][j] != 8) sf = 1; + if (sf == 0) ax--; + } + + abyssx = (ax << 1) + (DIRTEDGED2); + + for (j = 0; j < MDMAXY; j++) { + if (dungeon[ax][j] == 8) dungeon[ax][j] = 111; + if (dungeon[ax][j] == 2 || dungeon[ax][j] == 6) dungeon[ax][j] = 120; + if (dungeon[ax][j] == 3 || dungeon[ax][j] == 10) dungeon[ax][j] = 112; + if (dungeon[ax][j] < 111) dungeon[ax][j] = 7; + + if ((j & 0x0001) == 0) dungeon[ax+1][j] = 114; + else dungeon[ax+1][j] = 113; + if ((j & 0x0001) == 0) dungeon[ax+2][j] = 115; + else dungeon[ax+2][j] = 116; + if ((j & 0x0001) == 0) dungeon[ax+3][j] = 118; + else dungeon[ax+3][j] = 117; + } + + for (ax += 4; ax < MDMAXX; ax++) + for (j = 0; j < MDMAXY; j++) dungeon[ax][j] = 119; + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL WoodVertU(int i, int y) +{ + if ((dungeon[i+1][y] > 152 || dungeon[i+1][y] < 130) && + (dungeon[i-1][y] > 152 || dungeon[i-1][y] < 130)) + { + if (dungeon[i][y] == 7) return TRUE; + if (dungeon[i][y] == 10) return TRUE; + if (dungeon[i][y] == 126) return TRUE; + if (dungeon[i][y] == 129) return TRUE; + if (dungeon[i][y] == 134) return TRUE; + if (dungeon[i][y] == 136) return TRUE; + } + return FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL WoodVertD(int i, int y) +{ + if ((dungeon[i+1][y] > 152 || dungeon[i+1][y] < 130) && + (dungeon[i-1][y] > 152 || dungeon[i-1][y] < 130)) + { + if (dungeon[i][y] == 7) return TRUE; + if (dungeon[i][y] == 2) return TRUE; + if (dungeon[i][y] == 134) return TRUE; + if (dungeon[i][y] == 136) return TRUE; + } + return FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL WoodHorizL(int x, int j) +{ + if ((dungeon[x][j+1] > 152 || dungeon[x][j+1] < 130) && + (dungeon[x][j-1] > 152 || dungeon[x][j-1] < 130)) + { + if (dungeon[x][j] == 7) return TRUE; + if (dungeon[x][j] == 9) return TRUE; + if (dungeon[x][j] == 121) return TRUE; + if (dungeon[x][j] == 124) return TRUE; + if (dungeon[x][j] == 135) return TRUE; + if (dungeon[x][j] == 137) return TRUE; + } + return FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL WoodHorizR(int x, int j) +{ + if ((dungeon[x][j+1] > 152 || dungeon[x][j+1] < 130) && + (dungeon[x][j-1] > 152 || dungeon[x][j-1] < 130)) + { + if (dungeon[x][j] == 7) return TRUE; + if (dungeon[x][j] == 4) return TRUE; + if (dungeon[x][j] == 135) return TRUE; + if (dungeon[x][j] == 137) return TRUE; + } + return FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddFenceDoors(void) +/*-----------------------------------------------------------------------** +** DESCRIPTION: Adds doors to open spaces in fence lines +** INPUT: None +** RETURN: None +/*-----------------------------------------------------------------------*/ +{ + int i, j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + //Add horizontal doors + if (dungeon[i][j] == FLOOR && + ((dungeon[i-1][j] <= 152 && dungeon[i-1][j] >= 130) && + (dungeon[i+1][j] <= 152 && dungeon[i+1][j] >= 130))) + dungeon[i][j] = WOOD_HORIZGATE; + //Add vertical doors + else if (dungeon[i][j] == FLOOR && + ((dungeon[i][j-1] <= 152 && dungeon[i][j-1] >= 130) && + (dungeon[i][j+1] <= 152 && dungeon[i][j+1] >= 130))) + dungeon[i][j] = WOOD_VERTGATE; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void FenceDoorFix(void) +/*-----------------------------------------------------------------------** +** DESCRIPTION: Fixes any free standing doors. This removes any doors which +** are not attached to a fence line. +** INPUT: None +** RETURN: None +/*-----------------------------------------------------------------------*/ +{ + int i, j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if (dungeon[i][j] == WOOD_HORIZGATE && + ((dungeon[i+1][j] > 152 || dungeon[i+1][j] < 130) || + (dungeon[i-1][j] > 152 || dungeon[i-1][j] < 130))) + dungeon[i][j] = FLOOR; + else if (dungeon[i][j] == WOOD_HORIZGATE && + dungeon[i+1][j] != 130 && dungeon[i-1][j] != 130 && + dungeon[i+1][j] != 132 && dungeon[i-1][j] != 132 && + dungeon[i+1][j] != 133 && dungeon[i-1][j] != 133 && + dungeon[i+1][j] != 134 && dungeon[i-1][j] != 134 && + dungeon[i+1][j] != 136 && dungeon[i-1][j] != 136 && + dungeon[i+1][j] != 138 && dungeon[i-1][j] != 138 && + dungeon[i+1][j] != 140 && dungeon[i-1][j] != 140) + dungeon[i][j] = FLOOR; + else if (dungeon[i][j] == WOOD_VERTGATE && + ((dungeon[i][j+1] > 152 || dungeon[i][j+1] < 130) || + (dungeon[i][j-1] > 152 || dungeon[i][j-1] < 130))) + dungeon[i][j] = FLOOR; + else if (dungeon[i][j] == WOOD_VERTGATE && + dungeon[i][j+1] != 131 && dungeon[i][j-1] != 131 && + dungeon[i][j+1] != 132 && dungeon[i][j-1] != 132 && + dungeon[i][j+1] != 133 && dungeon[i][j-1] != 133 && + dungeon[i][j+1] != 135 && dungeon[i][j-1] != 135 && + dungeon[i][j+1] != 137 && dungeon[i][j-1] != 137 && + dungeon[i][j+1] != 138 && dungeon[i][j-1] != 138 && + dungeon[i][j+1] != 139 && dungeon[i][j-1] != 139) + dungeon[i][j] = FLOOR; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3Wood() +{ + int i,j; + int x,y; + int xx,yy; + int rt, rp, skip; + int x1,y1,x2,y2; + + // Put wood in walls/corners + for (j = 0; j < MDMAXY-1; j++) { + for (i = 0; i < MDMAXX-1; i++) { + if ((dungeon[i][j] == 10) && (random(0, 2))) { + x = i; + while (dungeon[x][j] == 10) x++; + x--; + if ((x - i) > 0) { + dungeon[i][j] = 127; + for (xx = i+1; xx < x; xx++) { + if (random(0, 2)) dungeon[xx][j] = 126; + else dungeon[xx][j] = 129; + } + dungeon[x][j] = 128; + } + } + if ((dungeon[i][j] == 9) && (random(0, 2))) { + y = j; + while (dungeon[i][y] == 9) y++; + y--; + if ((y - j) > 0) { + dungeon[i][j] = 123; + for (yy = j+1; yy < y; yy++) { + if (random(0, 2)) dungeon[i][yy] = 121; + else dungeon[i][yy] = 124; + } + dungeon[i][y] = 122; + } + } + if ((dungeon[i][j] == 11) && (dungeon[i+1][j] == 10) && (dungeon[i][j+1] == 9) && (random(0, 2))) { + dungeon[i][j] = 125; + x = i+1; + while (dungeon[x][j] == 10) x++; + x--; + for (xx = i+1; xx < x; xx++) { + if (random(0, 2)) dungeon[xx][j] = 126; + else dungeon[xx][j] = 129; + } + dungeon[x][j] = 128; + y = j+1; + while (dungeon[i][y] == 9) y++; + y--; + for (yy = j+1; yy < y; yy++) { + if (random(0, 2)) dungeon[i][yy] = 121; + else dungeon[i][yy] = 124; + } + dungeon[i][y] = 122; + } + } + } + + // Put wood lines in + for (j = 0; j < MDMAXY; j++) + { + for (i = 0; i < MDMAXX; i++) + { + if ((dungeon[i][j] == FLOOR) && (random(0, 1) == 0) && + (SkipThemeRoom(i, j))) + { + rt = random(0, 2); + x1 = 0; + y1 = 0; + //Create vertical fence + if (rt == 0) { + y1 = j; + while (WoodVertU(i,y1)) y1--; + y1++; + y2 = j; + while (WoodVertD(i,y2)) y2++; + y2--; + rp = 1; + if (dungeon[i][y1] == FLOOR) rp = 0; + if (dungeon[i][y2] == FLOOR) rp = 0; + if (((y2 - y1) > 1) && (rp != 0)) { + skip = random(0, y2 - y1 - 1) + y1 + 1; + for (y = y1; y <= y2; y++) { + if (y != skip) { + if (dungeon[i][y] == FLOOR) { + if (random(0, 2)) dungeon[i][y] = 135; + else dungeon[i][y] = 137; + } + if (dungeon[i][y] == 10) dungeon[i][y] = 131; + if (dungeon[i][y] == 126) dungeon[i][y] = 133; + if (dungeon[i][y] == 129) dungeon[i][y] = 133; + if (dungeon[i][y] == 2) dungeon[i][y] = 139; + if (dungeon[i][y] == 134) dungeon[i][y] = 138; + if (dungeon[i][y] == 136) dungeon[i][y] = 138; + } + } + } + } + //Create horizontal fence + if (rt == 1) { + x1 = i; + while (WoodHorizL(x1,j)) x1--; + x1++; + x2 = i; + while (WoodHorizR(x2,j)) x2++; + x2--; + rp = 1; + if (dungeon[x1][j] == FLOOR) rp = 0; + if (dungeon[x2][j] == FLOOR) rp = 0; + if (((x2 - x1) > 1) && (rp != 0)) { + skip = random(0, x2 - x1 - 1) + x1 + 1; + for (x = x1; x <= x2; x++) { + if (x != skip) { + if (dungeon[x][j] == FLOOR) { + if (random(0, 2)) dungeon[x][j] = 134; + else dungeon[x][j] = 136; + } + if (dungeon[x][j] == 9) dungeon[x][j] = 130; + if (dungeon[x][j] == 121) dungeon[x][j] = 132; + if (dungeon[x][j] == 124) dungeon[x][j] = 132; + if (dungeon[x][j] == 4) dungeon[x][j] = 140; + if (dungeon[x][j] == 135) dungeon[x][j] = 138; + if (dungeon[x][j] == 137) dungeon[x][j] = 138; + } + } + } + } + } + } + } + + //Add doors to fences + AddFenceDoors(); + FenceDoorFix(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* + +void DRLG_L3FTVR(int i, int j, int x, int y, int d) +{ + if ((dTransVal[x][y] == 0) && (dungeon[i][j] == FLOOR)) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + DRLG_L3FTVR(i+1,j, x+2,y, 1); + DRLG_L3FTVR(i-1,j, x-2,y, 2); + DRLG_L3FTVR(i,j+1, x,y+2, 3); + DRLG_L3FTVR(i,j-1, x,y-2, 4); + + DRLG_L3FTVR(i-1,j-1, x-2,y-2, 5); + DRLG_L3FTVR(i+1,j-1, x+2,y-2, 6); + DRLG_L3FTVR(i-1,j+1, x-2,y+2, 7); + DRLG_L3FTVR(i+1,j+1, x+2,y+2, 8); + } else { + if (d == 1) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 2) { + dTransVal[x+1][y] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 3) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 4) { + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 5) dTransVal[x+1][y+1] = TransVal; + if (d == 6) dTransVal[x][y+1] = TransVal; + if (d == 7) dTransVal[x+1][y] = TransVal; + if (d == 8) dTransVal[x][y] = TransVal; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* + +void DRLG_L3FloodTVal() +{ + int i, j; + int xx,yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == FLOOR) && (dTransVal[xx][yy] == 0)) { + DRLG_L3FTVR(i,j,xx,yy,0); + TransVal++; + } + xx += 2; + } + yy += 2; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* + +void DRLG_L3TransFix() +{ + int i, j; + int xx,yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == UR_WALL) && (dungeon[i][j-1] == LEFT_WALL)) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if ((dungeon[i][j] == LL_WALL) && (dungeon[i+1][j] == TOP_WALL)) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == LEFT_WALL) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == TOP_WALL) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == LR_WALL) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + xx += 2; + } + yy += 2; + } + + yy = DMAXY - DIRTEDGED2 - 2; + for (j = 0; j < MDMAXY; j++) { + xx = DMAXX - DIRTEDGED2 - 2; + for (i = 0; i < MDMAXX; i++) { + if ((dTransVal[xx-1][yy] != 0) || + (dTransVal[xx][yy-1] != 0) || + (dTransVal[xx-1][yy-1] != 0)) { + dTransVal[xx][yy] = 1; + dTransVal[xx+1][yy] = 1; + dTransVal[xx][yy+1] = 1; + dTransVal[xx+1][yy+1] = 1; + } + xx -= 2; + } + yy -= 2; + } + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dTransVal[i][j] != 0) dTransVal[i][j] = 1; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +int DRLG_L3Anvil() +{ + int sx, sy; + int sw, sh; + int xx, yy; + int ii; + int found, trys; + + // Width and height of the mini set piece + sw = L3ANVIL[0]; + sh = L3ANVIL[1]; + + // Random starting pos + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + + // Find a location for the mini set piece + found = 0; + trys = 0; + while ((found == 0) && (trys < 200)) { + trys++; + found = 1; + +// if (((sx >= SP3x1) && (sx <= SP3x2)) && ((sy >= SP3y1) && (sy <= SP3y2))) found = 0; + + ii = 2; + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((L3ANVIL[ii] != 0) && (dungeon[sx+xx][sy+yy] != L3ANVIL[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + if (found == 0) { + sx++; + if (sx == (MDMAXX - sw)) { + sx = 0; + sy++; + if (sy == (MDMAXY - sh)) sy = 0; + } + } + } + + if (trys >= 200) return 1; + + // Place mini set piece + ii = (sh * sw) + 2; + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (L3ANVIL[ii] != 0) dungeon[sx+xx][sy+yy] = L3ANVIL[ii]; + dflags[sx+xx][sy+yy] |= SETP_BIT; + ii++; + } + } + + setpc_x = sx; + setpc_y = sy; + setpc_w = sw; + setpc_h = sh; + + return 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void FixL3Warp() +{ + int i, j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 125) && + (dungeon[i+1][j] == 125) && + (dungeon[i][j+1] == 125) && + (dungeon[i+1][j+1] == 125)) { + dungeon[i][j] = 156; + dungeon[i+1][j] = 155; + dungeon[i][j+1] = 153; + dungeon[i+1][j+1] = 154; + return; + } + if ((dungeon[i][j] == 5) && (dungeon[i+1][j+1] == 7)) + dungeon[i][j] = 7; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void FixL3HallofHeroes() +{ + int i, j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 5) && (dungeon[i+1][j+1] == 7)) + dungeon[i][j] = 7; + } + } + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 5) && (dungeon[i+1][j+1] == 12) && (dungeon[i+1][j] == 7)) { + dungeon[i][j] = 7; + dungeon[i][j+1] = 7; + dungeon[i+1][j+1] = 7; + } + if ((dungeon[i][j] == 5) && (dungeon[i+1][j+1] == 12) && (dungeon[i][j+1] == 7)) { + dungeon[i][j] = 7; + dungeon[i+1][j] = 7; + dungeon[i+1][j+1] = 7; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +byte lockout[MDMAXX][MDMAXY]; +int lockoutcnt; + +void DRLG_L3LockRec(int x, int y) +{ + if (lockout[x][y] != 0) { + lockout[x][y] = 0; + lockoutcnt++; + DRLG_L3LockRec(x, y-1); + DRLG_L3LockRec(x, y+1); + DRLG_L3LockRec(x-1, y); + DRLG_L3LockRec(x+1, y); + } +} + +BOOL DRLG_L3Lockout() +{ + int i,j,t; + int fx,fy; + + t = 0; + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if (dungeon[i][j] != 0) { + lockout[i][j] = 1; + fx = i; + fy = j; + t++; + } else lockout[i][j] = 0; + } + } + lockoutcnt = 0; + DRLG_L3LockRec(fx, fy); + if (t == lockoutcnt) return(TRUE); + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DRLG_L3(int entry) +{ + int x1, y1, x2, y2, sx1, sy1; + int i, j; + int found; + BOOL genok; + + lavapool = FALSE; + do { + do { + do { // do this till MIN AREA is met. + InitL3Dungeon(); // fill dungeon with fill + + x1 = random(0, MDMAXX >> 1) + (MDMAXX >> 2); // random number 0-30 + y1 = random(0, MDMAXY >> 1) + (MDMAXY >> 2); + x2 = x1 + 2; + y2 = y1 + 2; + DRLG_L3FillRoom(x1,y1,x2,y2); // if empty, randomly fill dungeon with 1s + DRLG_L3CreateBlock(x1,y1,2,BLK_U); // recursively add blocks at random directions + DRLG_L3CreateBlock(x2,y1,2,BLK_R); // starting with the direction listed at the + DRLG_L3CreateBlock(x1,y2,2,BLK_D); // end of the function + DRLG_L3CreateBlock(x1,y1,2,BLK_L); + + if (QuestStatus(Q_ANVIL)) { // force this whole area to be a floor + sx1 = random(0, MDMAXX >> 2) + (MDMAXX >> 2); + sy1 = random(0, MDMAXY >> 2) + (MDMAXY >> 2); + DRLG_L3FloorArea(sx1, sy1, sx1+12, sy1+12); + } + + DRLG_L3FillDiags(); + DRLG_L3FillSingles(); + DRLG_L3FillStraights(); + DRLG_L3FillDiags(); + DRLG_L3Edges(); + if (DRLG_L3GetFloorArea() >= MINFAREA) { + genok = DRLG_L3Lockout(); + } else genok = FALSE; + } while (! genok); + DRLG_L3MakeMegas(); + +//************************************************************* +// Place stairs +//************************************************************* + + if (entry == LVL_DOWN) { + if (currlevel < HIVESTART) + found = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 1, LVL_DOWN); + else // place stairs down. On first level have town warp stairs + { + if (currlevel != HIVESTART) + found = DRLG_L3PlaceMiniSet(L6UP, 1, 1, -1, -1, 1, LVL_DOWN); + else + found = DRLG_L3PlaceMiniSet(L6HOLDWARP, 1, 1, -1, -1, 1, LVL_TWARPDN); // JKE add hive + } + + if (found == 0) // Place stairs down + { + if (currlevel < HIVESTART) + found = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 0, LVL_UP); + else + if (currlevel != HIVEEND) // no stairs down on last level + found = DRLG_L3PlaceMiniSet(L6DOWN, 1, 1, -1, -1, 0, LVL_UP); + } + + if ((found == 0) && (currlevel == 9)) + { + if (currlevel < HIVESTART) + found = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, 0, LVL_TWARPDN); // add hive level JKE + } + } else { + if (entry == LVL_UP) { + if (currlevel < HIVESTART) + found = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 0, LVL_DOWN); + else + { + if (currlevel != HIVESTART) + found = DRLG_L3PlaceMiniSet(L6UP, 1, 1, -1, -1, 0, LVL_DOWN); + else + found = DRLG_L3PlaceMiniSet(L6HOLDWARP, 1, 1, -1, -1, 0, LVL_TWARPDN); // JKE add hive + } + if (found == 0) { + if (currlevel < HIVESTART) + { + found = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 1, LVL_UP); + ViewX += 2; + ViewY -= 2; + } + else + { + if (currlevel != HIVEEND) + { + found = DRLG_L3PlaceMiniSet(L6DOWN, 1, 1, -1, -1, 1, LVL_UP); + ViewX += 2; + ViewY -= 2; + } + } + + if ((found == 0) && (currlevel == 9)) + if (currlevel < HIVESTART) + found = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, 0, LVL_TWARPDN); // JKE add hive + } + } else { + if (currlevel < HIVESTART) + found = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 0, LVL_DOWN); + else + { + if (currlevel != HIVESTART) + found = DRLG_L3PlaceMiniSet(L6UP, 1, 1, -1, -1, 0, LVL_DOWN); + else + found = DRLG_L3PlaceMiniSet(L6HOLDWARP, 1, 1, -1, -1, 1, LVL_TWARPDN); // JKE add hive + } + if (found == 0) + if (currlevel < HIVESTART) + found = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 0, LVL_UP); + else + if (currlevel != HIVEEND) + found = DRLG_L3PlaceMiniSet(L6DOWN, 1, 1, -1, -1, 0, LVL_UP); + + if ((found == 0) && (currlevel == 9)) + found = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, 1, LVL_TWARPDN); // JKE add hive + } + } + + if ((found == 0) && QuestStatus(Q_ANVIL)) + found = DRLG_L3Anvil(); + + } while (found == 1); + +// if (currlevel < HIVESTART) +// DRLG_L3Abyss(); +// JKE temp hack remove lava + if (currlevel < HIVESTART) + DRLG_L3Pool(); + else + { +// lavapool = TRUE; + lavapool += DRLG_L3PlaceAcidPool(L6ACID3, 30); + lavapool += DRLG_L3PlaceAcidPool(L6ACID4, 40); + lavapool += DRLG_L3PlaceAcidPool(L6ACID1, 50); + lavapool += DRLG_L3PlaceAcidPool(L6ACID2, 60); + + if (lavapool < 3) + lavapool = FALSE; + } +// AcidPool(); + + } while (!lavapool); + +// JKE temp hack remove lava + if (currlevel < HIVESTART) + DRLG_L3PoolFix(); +// else +// AcidPoolFix(); + + if (currlevel < HIVESTART) + FixL3Warp(); +// JKE temp hack remove lava + if (currlevel < HIVESTART) + { + DRLG_L3PlaceRndSet(L3ISLE1, 70); + DRLG_L3PlaceRndSet(L3ISLE2, 70); + DRLG_L3PlaceRndSet(L3ISLE3, 30); + DRLG_L3PlaceRndSet(L3ISLE4, 30); + DRLG_L3PlaceRndSet(L3ISLE1, 100); + DRLG_L3PlaceRndSet(L3ISLE2, 100); + DRLG_L3PlaceRndSet(L3ISLE5, 90); + } + else + { + DRLG_L3PlaceRndSet(ACIDISLE1, 70); + DRLG_L3PlaceRndSet(ACIDISLE2, 70); + DRLG_L3PlaceRndSet(ACIDISLE3, 30); + DRLG_L3PlaceRndSet(ACIDISLE4, 30); + DRLG_L3PlaceRndSet(ACIDISLE1, 100); + DRLG_L3PlaceRndSet(ACIDISLE2, 100); + DRLG_L3PlaceRndSet(ACIDISLE5, 90); + } + + if (currlevel < HIVESTART) + FixL3HallofHeroes(); + +// temp hack JKE remove lava + if (currlevel < HIVESTART) + DRLG_L3River(); + + // this may make other lockouts - (only on lvl10 with anvil quest). . . . + // this is a kludgy fix for anvil quest - the bridge to the anvil was sometimes getting + // blocked by river, this makes the "fake" walls back into the bridge - rjs + if (QuestStatus(Q_ANVIL)) { + dungeon[setpc_x + 7][setpc_y + 5] = 7; + dungeon[setpc_x + 8][setpc_y + 5] = 7; + dungeon[setpc_x + 9][setpc_y + 5] = 7; + if ((dungeon[setpc_x + 10][setpc_y + 5] == 17) || + (dungeon[setpc_x + 10][setpc_y + 5] == 18)) dungeon[setpc_x + 10][setpc_y + 5] = 45; + } + + if (currlevel < HIVESTART) + DRLG_PlaceThemeRooms(5, 10, FLOOR, 0, FALSE); +// temp hack JKE remove most + if (currlevel < HIVESTART) + { + DRLG_L3Wood(); + + DRLG_L3PlaceRndSet(L3TITE1, 10); + DRLG_L3PlaceRndSet(L3TITE2, 10); + DRLG_L3PlaceRndSet(L3TITE3, 10); + DRLG_L3PlaceRndSet(L3TITE6, 20); + DRLG_L3PlaceRndSet(L3TITE7, 20); + //DRLG_L3PlaceRndSet(L3TITE4, 10); + //DRLG_L3PlaceRndSet(L3TITE5, 10); + DRLG_L3PlaceRndSet(L3TITE8, 20); + DRLG_L3PlaceRndSet(L3TITE9, 20); + DRLG_L3PlaceRndSet(L3TITE10,20); + DRLG_L3PlaceRndSet(L3TITE11,30); + DRLG_L3PlaceRndSet(L3TITE12,20); + DRLG_L3PlaceRndSet(L3TITE13,20); + + DRLG_L3PlaceRndSet(L3CREV1, 30); + DRLG_L3PlaceRndSet(L3CREV2, 30); + DRLG_L3PlaceRndSet(L3CREV3, 30); + DRLG_L3PlaceRndSet(L3CREV4, 30); + DRLG_L3PlaceRndSet(L3CREV5, 30); + DRLG_L3PlaceRndSet(L3CREV6, 30); + DRLG_L3PlaceRndSet(L3CREV7, 30); + DRLG_L3PlaceRndSet(L3CREV8, 30); + DRLG_L3PlaceRndSet(L3CREV9, 30); + DRLG_L3PlaceRndSet(L3CREV10,30); + DRLG_L3PlaceRndSet(L3CREV11,30); + + DRLG_L3PlaceRndSet(L3XTRA1,25); + DRLG_L3PlaceRndSet(L3XTRA2,25); + DRLG_L3PlaceRndSet(L3XTRA3,25); + DRLG_L3PlaceRndSet(L3XTRA4,25); + DRLG_L3PlaceRndSet(L3XTRA5,25); + } + else // JKE Place our tiles here. + { +// DRLG_L3PlaceRndSet(L6ACIDTEST,25); + DRLG_L3PlaceRndSet(L6FILL1,20); // JKE Tile to sub, and % to exchange. + DRLG_L3PlaceRndSet(L6FILL2,20); + DRLG_L3PlaceRndSet(L6FILL3,20); + DRLG_L3PlaceRndSet(L6FILL4,20); + + DRLG_L3PlaceRndSet(L6TITE1,10); + DRLG_L3PlaceRndSet(L6TITE2,15); + DRLG_L3PlaceRndSet(L6TITE3,20); + DRLG_L3PlaceRndSet(L6TITE4,25); + DRLG_L3PlaceRndSet(L6TITE5,30); + DRLG_L3PlaceRndSet(L6TITE6,35); + DRLG_L3PlaceRndSet(L6TITE7,40); + DRLG_L3PlaceRndSet(L6TITE8,45); + DRLG_L3PlaceRndSet(L6TITE9,50); + DRLG_L3PlaceRndSet(L6TITE10,55); + + DRLG_L3PlaceRndSet(L6TITE10,10); + DRLG_L3PlaceRndSet(L6TITE9,15); + DRLG_L3PlaceRndSet(L6TITE8,20); + DRLG_L3PlaceRndSet(L6TITE7,25); + DRLG_L3PlaceRndSet(L6TITE6,30); + DRLG_L3PlaceRndSet(L6TITE5,35); + DRLG_L3PlaceRndSet(L6TITE4,40); + DRLG_L3PlaceRndSet(L6TITE3,45); + DRLG_L3PlaceRndSet(L6TITE2,50); + DRLG_L3PlaceRndSet(L6TITE1,55); + + DRLG_L3PlaceRndSet(L6FLOOR5,40); + DRLG_L3PlaceRndSet(L6FLOOR6,45); + + DRLG_L3PlaceRndSet(L6FLOOR1,25); + DRLG_L3PlaceRndSet(L6FLOOR2,25); + DRLG_L3PlaceRndSet(L6FLOOR3,25); + DRLG_L3PlaceRndSet(L6FLOOR4,25); + DRLG_L3PlaceRndSet(L6WALL1,25); + DRLG_L3PlaceRndSet(L6WALL2,25); + DRLG_L3PlaceRndSet(L6WALL3,25); + DRLG_L3PlaceRndSet(L6WALL4,25); + DRLG_L3PlaceRndSet(L6WALL5,25); + DRLG_L3PlaceRndSet(L6WALL6,25); + DRLG_L3PlaceRndSet(L6WALL7,25); + DRLG_L3PlaceRndSet(L6WALL8,25); + DRLG_L3PlaceRndSet(L6WALL9,25); + DRLG_L3PlaceRndSet(L6WALL10,25); + DRLG_L3PlaceRndSet(L6WALL11,25); + DRLG_L3PlaceRndSet(L6WALL12,25); + DRLG_L3PlaceRndSet(L6WALL13,25); + DRLG_L3PlaceRndSet(L6WALL14,25); + DRLG_L3PlaceRndSet(L6CORNER1,25); + DRLG_L3PlaceRndSet(L6CORNER2,25); + DRLG_L3PlaceRndSet(L6CORNER3,25); + DRLG_L3PlaceRndSet(L6CORNER4,25); + + } + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } + + extern void DRLG_Init_Globals(); + DRLG_Init_Globals(); + +// DRLG_CheckQuests(SP3x1,SP3y1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L3Pass3() +{ + int i,j,xx,yy; + long v1,v2,v3,v4,lv; + + // Init dungeon to dirt + lv = L3_DIRT - 1; + __asm { + mov esi,dword ptr [pMegaTiles] + mov eax,dword ptr [lv]; + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + } + + for (yy = 0; yy < DMAXY; yy+=2) { + for (xx = 0; xx < DMAXX; xx+=2) { //DMAXX = abyssx for abyss + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; + } + } + + // Convert dungeon mega tiles to mini tiles + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + lv = ((long)dungeon[i][j]) - 1; + if (lv >= 0) { + __asm { + mov esi,dword ptr [pMegaTiles] + mov eax,dword ptr [lv]; + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + } + } else { + v1 = 0; + v2 = 0; + v3 = 0; + v4 = 0; + } + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; + xx += 2; + } + yy += 2; + } + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#if IS_VERSION(RETAIL) +void CreateL3Dungeon(unsigned int rseed, int entry) +{ + int i,j; + + SetRndSeed(rseed); + + dminx = DIRTEDGED2; + dminy = DIRTEDGED2; + dmaxx = DMAXX - (DIRTEDGED2); + dmaxy = DMAXY - (DIRTEDGED2); + + //DRLG_LoadL3SP(); + DRLG_InitTrans(); // initialize transparent values + DRLG_InitSetPC(); // ? sets 4 pc values to 0 + DRLG_L3(entry); + DRLG_L3Pass3(); + //DRLG_FreeL3SP(); + + // Special lava lighting!!! JKE + if (currlevel < HIVESTART) + { + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if ((dPiece[i][j] >= 56) && (dPiece[i][j] <= 147)) DoLighting (i, j, 7, -1); + else if ((dPiece[i][j] >= 154) && (dPiece[i][j] <= 161)) DoLighting (i, j, 7, -1); + else if (dPiece[i][j] == 150) DoLighting (i, j, 7, -1); + else if (dPiece[i][j] == 152) DoLighting (i, j, 7, -1); + } + } + } + else + { + for (j = 0; j < DMAXY; j++) + for (i = 0; i < DMAXX; i++) + if ((dPiece[i][j] >= 382) && (dPiece[i][j] <= 457)) + DoLighting (i, j, 9, -1); + //dLight[i][j] = 1; + } + + DRLG_SetPC(); +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void LoadL3Dungeon(char sFileName[], int vx, int vy) +{ + int i, j, rw, rh; + byte *pLevelMap, *lm; + + InitL3Dungeon(); + + dminx = DIRTEDGED2; + dminy = DIRTEDGED2; + dmaxx = DMAXX - (DIRTEDGED2); + dmaxy = DMAXY - (DIRTEDGED2); + + DRLG_InitTrans(); + + pLevelMap = LoadFileInMemSig(sFileName,NULL,'LMPt'); + lm = pLevelMap; + + rw = *lm; + lm+=2; + rh = *lm; + lm+=2; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*lm != 0) { + dungeon[i][j] = *lm; + } else dungeon[i][j] = FLOOR; + lm+=2; + } + } + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) + if (dungeon[i][j] == 0) dungeon[i][j] = L3_DIRT; + } + + abyssx = DMAXX; + DRLG_L3Pass3(); + + extern void DRLG_Init_Globals(); + DRLG_Init_Globals(); + + ViewX = 31; + ViewY = 83; + + SetMapMonsters(pLevelMap, 0, 0); + SetMapObjects(pLevelMap, 0, 0); + + // Special lava lighting!!! + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if ((dPiece[i][j] >= 56) && (dPiece[i][j] <= 147)) DoLighting (i, j, 7, -1); + else if ((dPiece[i][j] >= 154) && (dPiece[i][j] <= 161)) DoLighting (i, j, 7, -1); + else if (dPiece[i][j] == 150) DoLighting (i, j, 7, -1); + else if (dPiece[i][j] == 152) DoLighting (i, j, 7, -1); + } + } + + DiabloFreePtr(pLevelMap); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LoadPreL3Dungeon(char sFileName[], int vx, int vy) +{ + int i, j, rw, rh; + byte *pLevelMap, *lm; + + InitL3Dungeon(); + + DRLG_InitTrans(); + + pLevelMap = LoadFileInMemSig(sFileName,NULL,'LMPt'); + lm = pLevelMap; + + rw = *lm; + lm+=2; + rh = *lm; + lm+=2; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*lm != 0) { + dungeon[i][j] = *lm; + } else dungeon[i][j] = FLOOR; + lm+=2; + } + } + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) + if (dungeon[i][j] == 0) dungeon[i][j] = L3_DIRT; + } + + CopyMemory(pdungeon,dungeon,sizeof(pdungeon)); + + DiabloFreePtr(pLevelMap); +} diff --git a/DRLG_L3.H b/DRLG_L3.H new file mode 100644 index 0000000..b58d496 --- /dev/null +++ b/DRLG_L3.H @@ -0,0 +1,68 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L3.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define BLK_U 0 +#define BLK_R 1 +#define BLK_D 2 +#define BLK_L 3 + +#define L3_DIRT 8 + +//#define MINFAREA 1536 +#define MINFAREA 600 + +#define FR_FALSE 0 +#define FR_TRUE 1 + +#define UR_ISLE 14 +#define LL_ISLE 13 +#define LR_ISLE 12 +#define UL_WALL 11 +#define TOP_WALL 10 +#define LEFT_WALL 9 +#define FILL 8 +#define FLOOR 7 +#define LR_WALL 6 +#define UL_ISLE 5 +#define RIGHT_WALL 4 +#define UR_WALL 3 +#define BOTTOM_WALL 2 +#define LL_WALL 1 +#define D3_NULL 0 + +#define L3_NUMBLOCKS 124 + +#define NORTH 0 +#define SOUTH 1 +#define EAST 2 +#define WEST 3 + +#define WOOD_HORIZWALL 134 +#define WOOD_VERTWALL 137 +#define WOOD_LRCORNER 138 +#define WOOD_HORIZGATE 146 +#define WOOD_VERTGATE 147 +#define WOOD_ULCORNER 150 +#define WOOD_URCORNER 151 +#define WOOD_LLCORNER 152 + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void CreateL3Dungeon(unsigned int, int); +void LoadPreL3Dungeon(char [], int, int); +void LoadL3Dungeon(char [], int, int); +int DRLG_L3Spawn(int, int, int *); +BOOL SkipThemeRoom( int x, int y ); diff --git a/DRLG_L4.CPP b/DRLG_L4.CPP new file mode 100644 index 0000000..9083e2f --- /dev/null +++ b/DRLG_L4.CPP @@ -0,0 +1,1668 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Dungeon file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L4.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +** CreateL1Dungeon +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "drlg_l4.h" +#include "gendung.h" +#include "scrollrt.h" +#include "engine.h" +#include "trigs.h" +#include "lighting.h" +#include "quests.h" +#include "multi.h" + +/*-----------------------------------------------------------------------* +** Diablo quads +**-----------------------------------------------------------------------*/ + +#define DIABSIZE 14 + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +byte dung[L4DUNX][L4DUNY]; +BOOL hallok[L4DUNY]; +byte L4dungeon[L4DX][L4DY]; +static const byte L4ConvTbl[16] = { 30, 6, 1, 6, 2, 6, 6, 6, 9, 6, 1, 6, 2, 6, 3, 6 }; +int SP4x1, SP4y1, SP4x2, SP4y2; +int l4holdx,l4holdy; + +int diabquad1x, diabquad2x, diabquad3x, diabquad4x; +int diabquad1y, diabquad2y, diabquad3y, diabquad4y; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static const byte L4USTAIRS[] = { 4, 5, // X size, Y size + + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + + 0, 0, 0, 0, + 36, 38, 35, 0, + 37, 34, 33, 32, + 0, 0, 31, 0, + 0, 0, 0, 0}; + +static const byte L4TWARP[] = { 4, 5, // X size, Y size + + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + + 0, 0, 0, 0, + 134, 136, 133, 0, + 135, 132, 131, 130, + 0, 0, 129, 0, + 0, 0, 0, 0}; + +static const byte L4DSTAIRS[] = { 5, 5, // X size, Y size + + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + + 0, 0, 0, 0, 0, + 0, 0, 45, 41, 0, + 0, 44, 43, 40, 0, + 0, 46, 42, 39, 0, + 0, 0, 0, 0, 0}; + +static const byte L4PENTA[] = { 5, 5, // X size, Y size + + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + + 0, 0, 0, 0, 0, + 0, 98, 100, 103, 0, + 0, 99, 102, 105, 0, + 0, 101, 104, 106, 0, + 0, 0, 0, 0, 0}; + +static const byte L4PENTA2[] = { 5, 5, // X size, Y size + + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, FLOOR_PIC, + + 0, 0, 0, 0, 0, + 0, 107, 109, 112, 0, + 0, 108, 111, 114, 0, + 0, 110, 113, 115, 0, + 0, 0, 0, 0, 0}; + +// Types for tile substitution +static const byte L4BTYPES[NUMBBLOCKS] = { 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, // L4Base + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30 // L4Dirt + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//46 // L4Stairs + 0, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,//60 // L4Shadow + 1, 2, 1, 2, 1, 2, 1, 1, 2, 2,//70 // L4Misc + 0, 0, 0, 0, 0, 0, 15, 16, 9, 12, 4, 5, 7, //83 // L4Misc2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//97 // L4Floor + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//115 // L4Penta + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//128 // L4Dirt2 + 0, 0, 0, 0, 0, 0, 0, 0}; // L4Stair2 + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4Shadows() +{ + int x,y; + BOOL okflag; + + for (y = 1; y < MDMAXY; y++) { + for (x = 1; x < MDMAXX; x++) { + okflag = FALSE; + if (dungeon[x][y] == 3) okflag = TRUE; + if (dungeon[x][y] == 4) okflag = TRUE; + if (dungeon[x][y] == 8) okflag = TRUE; + if (dungeon[x][y] == 15) okflag = TRUE; + if (okflag) { + if (dungeon[x-1][y] == 6) dungeon[x-1][y] = 47; + if (dungeon[x-1][y-1] == 6) dungeon[x-1][y-1] = 48; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void InitL4Dungeon() +{ + ZeroMemory(dung,sizeof(dung)); + ZeroMemory(L4dungeon,sizeof(L4dungeon)); + + for (int j = 0; j < MDMAXY; j++) { + for (int i = 0; i < MDMAXX; i++) { + dungeon[i][j] = 30; //L4_DIRT;DIRT_PIC + dflags[i][j] = 0; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DRLG_LoadL4SP() +{ + setloadflag = FALSE; + if (QuestStatus(Q_WARLORD)) { + app_assert(gbMaxPlayers == 1); + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\Warlord.DUN",NULL,'STPC'); + setloadflag = TRUE; + } + if ((currlevel == 15) && (gbMaxPlayers != 1)) { + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\Vile1.DUN", NULL, 'STPC'); + setloadflag = TRUE; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DRLG_FreeL4SP() { + DiabloFreePtr(pSetPiece); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DRLG_L4SetSPRoom(int rx1, int ry1) +{ + int rw,rh; + int i,j; + byte *sp; + + sp = pSetPiece; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = rw; + setpc_h = rh; + + sp = pSetPiece+4; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp != 0) { + dungeon[rx1+i][ry1+j] = *sp; + dflags[rx1+i][ry1+j] |= SETP_BIT; + } else dungeon[rx1+i][ry1+j] = FLOOR_PIC; + sp+=2; + } + } + + } + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static void L4makeDmt() +{ + int i, j; + int idx; + int val; + int dmtx, dmty; + + dmty = 0; + for (j = 1; j <= 77; j+=2) { + dmtx = 0; + for (i = 1; i <= 77; i+=2) { + idx = L4dungeon[i][j] + (L4dungeon[i+1][j]<<1) + + (L4dungeon[i][j+1]<<2) + (L4dungeon[i+1][j+1]<<3); + val = L4ConvTbl[idx]; + dungeon[dmtx][dmty] = val; + dmtx++; + } + dmty++; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int L4HWallOk(int i, int j) +{ + int x; + BOOL wallok; + + x = 1; + while ((dungeon[i+x][j] == 6) && + (dflags[i+x][j] == 0) && + (dungeon[i+x][j-1] == 6) && + (dungeon[i+x][j+1] == 6)) x++; + wallok = FALSE; + if (dungeon[i+x][j] == 10) wallok = TRUE; + if (dungeon[i+x][j] == 12) wallok = TRUE; + if (dungeon[i+x][j] == 13) wallok = TRUE; + if (dungeon[i+x][j] == 15) wallok = TRUE; + if (dungeon[i+x][j] == 16) wallok = TRUE; + if (dungeon[i+x][j] == 21) wallok = TRUE; + if (dungeon[i+x][j] == 22) wallok = TRUE; + if (x <= 3) wallok = FALSE; + if (wallok) return(x); + else return(-1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int L4VWallOk(int i, int j) +{ + int y; + BOOL wallok; + + y = 1; + while ((dungeon[i][j+y] == 6) && + (dflags[i][j+y] == 0) && + (dungeon[i-1][j+y] == 6) && + (dungeon[i+1][j+y] == 6)) y++; + wallok = FALSE; + if (dungeon[i][j+y] == 8) wallok = TRUE; + if (dungeon[i][j+y] == 9) wallok = TRUE; + if (dungeon[i][j+y] == 11) wallok = TRUE; + if (dungeon[i][j+y] == 14) wallok = TRUE; + if (dungeon[i][j+y] == 15) wallok = TRUE; + if (dungeon[i][j+y] == 16) wallok = TRUE; + if (dungeon[i][j+y] == 21) wallok = TRUE; + if (dungeon[i][j+y] == 23) wallok = TRUE; + if (y <= 3) wallok = FALSE; + if (wallok) return(y); + else return(-1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void L4HorizWall(int i, int j, int dx) +{ + int xx; + + // Left side connector + if (dungeon[i][j] == 13) dungeon[i][j] = 17; + if (dungeon[i][j] == 16) dungeon[i][j] = 11; + if (dungeon[i][j] == 12) dungeon[i][j] = 14; + // Middle fill + for (xx = 1; xx < dx; xx++) dungeon[i+xx][j] = 2; + // Right side connector + if (dungeon[i+dx][j] == 15) dungeon[i+dx][j] = 14; + if (dungeon[i+dx][j] == 10) dungeon[i+dx][j] = 17; + if (dungeon[i+dx][j] == 21) dungeon[i+dx][j] = 23; + if (dungeon[i+dx][j] == 22) dungeon[i+dx][j] = 29; + // Put in arch + xx = random(0, dx-3) + 1; + dungeon[i+xx][j] = 57; + dungeon[i+xx+2][j] = 56; + // Arch shadows + dungeon[i+xx+1][j] = 60; + if (dungeon[i+xx][j-1] == 6) dungeon[i+xx][j-1] = 58; + if (dungeon[i+xx+1][j-1] == 6) dungeon[i+xx+1][j-1] = 59; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void L4VertWall(int i, int j, int dy) +{ + int yy; + + //Up side connector; + if (dungeon[i][j] == 14) dungeon[i][j] = 17; + if (dungeon[i][j] == 8) dungeon[i][j] = 9; + if (dungeon[i][j] == 15) dungeon[i][j] = 10; + //Middle fill + for (yy = 1; yy < dy; yy++) dungeon[i][j+yy] = 1; + //Down side connector + if (dungeon[i][j+dy] == 11) dungeon[i][j+dy] = 17; + if (dungeon[i][j+dy] == 9) dungeon[i][j+dy] = 10; + if (dungeon[i][j+dy] == 16) dungeon[i][j+dy] = 13; + if (dungeon[i][j+dy] == 21) dungeon[i][j+dy] = 22; + if (dungeon[i][j+dy] == 23) dungeon[i][j+dy] = 29; + // Put in arch + yy = random(0, dy-3) + 1; + dungeon[i][j+yy] = 53; + dungeon[i][j+yy+2] = 52; + // Arch shadows + dungeon[i][j+yy+1] = 6; + if (dungeon[i-1][j+yy] == 6) dungeon[i-1][j+yy] = 54; + if (dungeon[i-1][j+yy-1] == 6) dungeon[i-1][j+yy-1] = 55; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define WALLRND 100 +static void L4AddWall() +{ + int i, j; + int x, y; + + for (j = 0; j < MDMAXY ; j++) { + for (i = 0; i < MDMAXX; i++) { + if (dflags[i][j] == 0) { + // Horizontal + if ((dungeon[i][j] == 10) && (random(0, 100) < WALLRND)) { + x = L4HWallOk(i, j); + if (x != -1) L4HorizWall(i, j, x); + } + if ((dungeon[i][j] == 12) && (random(0, 100) < WALLRND)) { + x = L4HWallOk(i, j); + if (x != -1) L4HorizWall(i, j, x); + } + if ((dungeon[i][j] == 13) && (random(0, 100) < WALLRND)) { + x = L4HWallOk(i, j); + if (x != -1) L4HorizWall(i, j, x); + } + if ((dungeon[i][j] == 15) && (random(0, 100) < WALLRND)) { + x = L4HWallOk(i, j); + if (x != -1) L4HorizWall(i, j, x); + } + if ((dungeon[i][j] == 16) && (random(0, 100) < WALLRND)) { + x = L4HWallOk(i, j); + if (x != -1) L4HorizWall(i, j, x); + } + if ((dungeon[i][j] == 21) && (random(0, 100) < WALLRND)) { + x = L4HWallOk(i, j); + if (x != -1) L4HorizWall(i, j, x); + } + if ((dungeon[i][j] == 22) && (random(0, 100) < WALLRND)) { + x = L4HWallOk(i, j); + if (x != -1) L4HorizWall(i, j, x); + } + // Vertical + if ((dungeon[i][j] == 8) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + if ((dungeon[i][j] == 9) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + if ((dungeon[i][j] == 11) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + if ((dungeon[i][j] == 14) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + if ((dungeon[i][j] == 15) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + if ((dungeon[i][j] == 16) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + if ((dungeon[i][j] == 21) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + if ((dungeon[i][j] == 23) && (random(0, 100) < WALLRND)) { + y = L4VWallOk(i, j); + if (y != -1) L4VertWall(i, j, y); + } + } + } + } +} + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static void L4tileFix() +{ + int i, j; + // tiles in middle of dungeon + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 6)) dungeon[i+1][j] = 5; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 13; + + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 14; + } + } + + // tiles in middle of dungeon + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 6)) dungeon[i+1][j] = 2; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 9)) dungeon[i+1][j] = 11; + if ((dungeon[i][j] == 9) && (dungeon[i+1][j] == 6)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 13; + if ((dungeon[i][j] == 6) && (dungeon[i+1][j] == 14)) dungeon[i+1][j] = 15; + + if ((dungeon[i][j] == 6) && (dungeon[i][j+1] == 13)) dungeon[i][j+1] = 16; + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 10; + + if ((dungeon[i][j] == 6) && (dungeon[i][j-1] == 1)) dungeon[i][j-1] = 1; + } + } + + // around edges + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 13) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 27; + + if ((dungeon[i][j] == 27) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 27; + if ((dungeon[i][j] == 27) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 27)) dungeon[i+1][j] = 26; + if ((dungeon[i][j] == 27) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 15)) dungeon[i+1][j] = 14; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 15)) dungeon[i+1][j] = 14; + if ((dungeon[i][j] == 22) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 27) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 6) && (dungeon[i+1][j] == 27) && (dungeon[i+1][j+1])) dungeon[i+1][j] = 22; + if ((dungeon[i][j] == 22) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 1) && (dungeon[i+1][j-1] == 1)) dungeon[i+1][j] = 13; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 30) && (dungeon[i][j+1] == 6)) dungeon[i+1][j] = 28; + + if ((dungeon[i][j] == 16) && (dungeon[i+1][j] == 6) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 27; + if ((dungeon[i][j] == 16) && (dungeon[i][j+1] == 30) && (dungeon[i+1][j+1] == 30)) dungeon[i][j+1] = 27; + if ((dungeon[i][j] == 6) && (dungeon[i+1][j] == 30) && (dungeon[i+1][j-1] == 6)) dungeon[i+1][j] = 21; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 27) && (dungeon[i+1][j+1] == 9)) dungeon[i+1][j] = 29; + if ((dungeon[i][j] == 9) && (dungeon[i+1][j] == 15)) dungeon[i+1][j] = 14; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 27) && (dungeon[i+1][j+1] == 2)) dungeon[i+1][j] = 29; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 18)) dungeon[i+1][j] = 24; + if ((dungeon[i][j] == 9) && (dungeon[i+1][j] == 15)) dungeon[i+1][j] = 14; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 19) && (dungeon[i+1][j-1] == 30)) dungeon[i+1][j] = 24; + if ((dungeon[i][j] == 24) && (dungeon[i][j-1] == 30) && (dungeon[i][j-2] == 6)) dungeon[i][j-1] = 21; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 28; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 28; + if ((dungeon[i][j] == 28) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + if ((dungeon[i][j] == 28) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + + if ((dungeon[i][j] == 19) && (dungeon[i+2][j] == 2) && (dungeon[i+1][j-1] == 18) && (dungeon[i+1][j+1] == 1)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 19) && (dungeon[i+2][j] == 2) && (dungeon[i+1][j-1] == 22) && (dungeon[i+1][j+1] == 1)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 19) && (dungeon[i+2][j] == 2) && (dungeon[i+1][j-1] == 18) && (dungeon[i+1][j+1] == 13)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 21) && (dungeon[i+2][j] == 2) && (dungeon[i+1][j-1] == 18) && (dungeon[i+1][j+1] == 1)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j+1] == 1) && (dungeon[i+1][j-1] == 22) && (dungeon[i+2][j] == 3)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 28) && (dungeon[i+2][j] == 30) && (dungeon[i+1][j-1] == 6)) dungeon[i+1][j] = 23; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 28) && (dungeon[i+2][j] == 1)) dungeon[i+1][j] = 23; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 27) && (dungeon[i+1][j+1] == 30)) dungeon[i+1][j] = 29; + if ((dungeon[i][j] == 28) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j-1] == 21)) dungeon[i+1][j] = 24; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 27) && (dungeon[i+1][j+1] == 30)) dungeon[i+1][j] = 29; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 18)) dungeon[i+1][j] = 25; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 9) && (dungeon[i+2][j] == 2)) dungeon[i+1][j] = 11; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 10)) dungeon[i+1][j] = 17; + + if ((dungeon[i][j] == 15) && (dungeon[i][j+1] == 3)) dungeon[i][j+1] = 4; + + if ((dungeon[i][j] == 22) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 18) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + if ((dungeon[i][j] == 24) && (dungeon[i-1][j] == 30)) dungeon[i-1][j] = 19; + if ((dungeon[i][j] == 21) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 21) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 10; + if ((dungeon[i][j] == 22) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + if ((dungeon[i][j] == 21) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + if ((dungeon[i][j] == 16) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 13) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 22) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 18) && (dungeon[i+2][j] == 30)) dungeon[i+1][j] = 24; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 9) && (dungeon[i+1][j+1] == 1)) dungeon[i+1][j] = 16; + + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 27) && (dungeon[i+1][j+1] == 2)) dungeon[i+1][j] = 29; + if ((dungeon[i][j] == 23) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 23) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 25) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 22) && (dungeon[i+1][j] == 9)) dungeon[i+1][j] = 11; + if ((dungeon[i][j] == 23) && (dungeon[i+1][j] == 9)) dungeon[i+1][j] = 11; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 11) && (dungeon[i+1][j] == 15)) dungeon[i+1][j] = 14; + if ((dungeon[i][j] == 23) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 27)) dungeon[i+1][j] = 26; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 18)) dungeon[i+1][j] = 24; + if ((dungeon[i][j] == 26) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 29) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 29) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 1) && (dungeon[i][j-1] == 15)) dungeon[i][j-1] = 10; + if ((dungeon[i][j] == 18) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 23) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + if ((dungeon[i][j] == 18) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 10; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 30) && (dungeon[i+1][j+1] == 30)) dungeon[i+1][j] = 23; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 28) && (dungeon[i+1][j-1] == 6)) dungeon[i+1][j] = 23; + if ((dungeon[i][j] == 23) && (dungeon[i+1][j] == 18) && (dungeon[i][j-1] == 6)) dungeon[i+1][j] = 24; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 23) && (dungeon[i+2][j] == 30)) dungeon[i+1][j] = 28; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 28) && (dungeon[i+2][j] == 30) && (dungeon[i+1][j-1] == 6)) dungeon[i+1][j] = 23; + + // fill in blood around edges + if ((dungeon[i][j] == 23) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 29) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 29) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 26) && (dungeon[i+1][j] == 30)) dungeon[i+1][j] = 19; + if ((dungeon[i][j] == 16) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + + if ((dungeon[i][j] == 13) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 10; + if ((dungeon[i][j] == 25) && (dungeon[i][j+1] == 30)) dungeon[i][j+1] = 18; + if ((dungeon[i][j] == 18) && (dungeon[i][j+1] == 2)) dungeon[i][j+1] = 15; + if ((dungeon[i][j] == 11) && (dungeon[i+1][j] == 3)) dungeon[i+1][j] = 5; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 9)) dungeon[i+1][j] = 11; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 13; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 13) && (dungeon[i+1][j-1] == 6)) dungeon[i+1][j] = 16; + } + } + + // tiles in middle of dungeon + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 21) && (dungeon[i][j+1] == 24) && (dungeon[i][j+2] == 1)) dungeon[i][j+1] = 17; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j+1] == 9) && (dungeon[i+1][j-1] == 1) && (dungeon[i+2][j] == 16)) dungeon[i+1][j] = 29; + if ((dungeon[i][j] == 2) && (dungeon[i-1][j] == 6)) dungeon[i-1][j] = 8; + if ((dungeon[i][j] == 1) && (dungeon[i][j-1] == 6)) dungeon[i][j-1] = 7; + + if ((dungeon[i][j] == 6) && (dungeon[i+1][j] == 15) && (dungeon[i+1][j+1] == 4)) dungeon[i+1][j] = 10; + + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 3)) dungeon[i][j+1] = 4; + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 6)) dungeon[i][j+1] = 4; + if ((dungeon[i][j] == 9) && (dungeon[i][j+1] == 3)) dungeon[i][j+1] = 4; + if ((dungeon[i][j] == 10) && (dungeon[i][j+1] == 3)) dungeon[i][j+1] = 4; + if ((dungeon[i][j] == 13) && (dungeon[i][j+1] == 3)) dungeon[i][j+1] = 4; + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 5)) dungeon[i][j+1] = 12; + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 16)) dungeon[i][j+1] = 13; + if ((dungeon[i][j] == 6) && (dungeon[i][j+1] == 13)) dungeon[i][j+1] = 16; + if ((dungeon[i][j] == 25) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 10; + if ((dungeon[i][j] == 13) && (dungeon[i][j+1] == 5)) dungeon[i][j+1] = 12; + + if ((dungeon[i][j] == 28) && (dungeon[i][j-1] == 6) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 23; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 10)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 9)) dungeon[i+1][j] = 11; + if ((dungeon[i][j] == 11) && (dungeon[i+1][j] == 3)) dungeon[i+1][j] = 5; + if ((dungeon[i][j] == 10) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 27) && (dungeon[i+1][j] == 9)) dungeon[i+1][j] = 11; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 1)) dungeon[i+1][j] = 16; + if ((dungeon[i][j] == 11) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 3)) dungeon[i+1][j] = 5; + if ((dungeon[i][j] == 9) && (dungeon[i+1][j] == 3)) dungeon[i+1][j] = 5; + if ((dungeon[i][j] == 14) && (dungeon[i+1][j] == 3)) dungeon[i+1][j] = 5; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 3)) dungeon[i+1][j] = 5; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 5) && (dungeon[i+1][j-1] == 16)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 2) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 9) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + + if ((dungeon[i][j] == 1) && (dungeon[i][j-1] == 8)) dungeon[i][j-1] = 9; + if ((dungeon[i][j] == 28) && (dungeon[i+1][j] == 23) && (dungeon[i+1][j+1] == 3)) dungeon[i+1][j] = 16; + } + } + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 10)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 17) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 10) && (dungeon[i+1][j] == 4)) dungeon[i+1][j] = 12; + + if ((dungeon[i][j] == 17) && (dungeon[i][j+1] == 5)) dungeon[i][j+1] = 12; + if ((dungeon[i][j] == 29) && (dungeon[i][j+1] == 9)) dungeon[i][j+1] = 10; + if ((dungeon[i][j] == 13) && (dungeon[i][j+1] == 5)) dungeon[i][j+1] = 12; + if ((dungeon[i][j] == 9) && (dungeon[i][j+1] == 16)) dungeon[i][j+1] = 13; + if ((dungeon[i][j] == 10) && (dungeon[i][j+1] == 16)) dungeon[i][j+1] = 13; + if ((dungeon[i][j] == 16) && (dungeon[i][j+1] == 3)) dungeon[i][j+1] = 4; + if ((dungeon[i][j] == 11) && (dungeon[i][j+1] == 5)) dungeon[i][j+1] = 12; + if ((dungeon[i][j] == 10) && (dungeon[i+1][j] == 3) && (dungeon[i+1][j-1] == 16)) dungeon[i+1][j] = 12; + if ((dungeon[i][j] == 16) && (dungeon[i][j+1] == 5)) dungeon[i][j+1] = 12; + if ((dungeon[i][j] == 1) && (dungeon[i][j+1] == 6)) dungeon[i][j+1] = 4; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j] == 13) && (dungeon[i][j+1] == 10)) dungeon[i+1][j+1] = 12; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 10)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 22) && (dungeon[i][j+1] == 11)) dungeon[i][j+1] = 17; + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 28) && (dungeon[i+2][j] == 16)) dungeon[i+1][j] = 23; + if ((dungeon[i][j] == 28) && (dungeon[i+1][j] == 23) && (dungeon[i+1][j+1] == 1) && (dungeon[i+2][j] == 6)) dungeon[i+1][j] = 16; + } + } + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == 15) && (dungeon[i+1][j] == 28) && (dungeon[i+2][j] == 16)) dungeon[i+1][j] = 23; + if ((dungeon[i][j] == 21) && (dungeon[i+1][j-1] == 21) && (dungeon[i+1][j+1] == 13) && (dungeon[i+2][j] == 2)) dungeon[i+1][j] = 17; + if ((dungeon[i][j] == 19) && (dungeon[i+1][j] == 15) && (dungeon[i+1][j+1] == 12)) dungeon[i+1][j] = 17; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4Subs() +{ + int x,y,i,rv; + byte c; + + for (y = 0; y < MDMAXY; y++) { + for (x = 0; x < MDMAXX; x++) { + rv = random(0, 3); + if (rv == 0) { + c = dungeon[x][y]; + c = L4BTYPES[c]; + if ((c != 0) && (dflags[x][y] == 0)) { + rv = random(0, 16); + i = -1; + while (rv >= 0) { + i++; + if (i == NUMBBLOCKS) i = 0; + if (c == L4BTYPES[i]) rv--; + } + dungeon[x][y] = i; + } + } + } + } + for (y = 0; y < MDMAXY; y++) { + for (x = 0; x < MDMAXX; x++) { + rv = random(0, 10); + if (rv == 0) { + c = dungeon[x][y]; + c = L4BTYPES[c]; + if ((c == 6) && (dflags[x][y] == 0)) + dungeon[x][y] = random(0, 3) + 95; + } + } + } +} + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static void L4makeDungeon() +{ + int i, j; + int k, l; + + // top left + for (j = 0; j < L4DUNY; j++) { + for(i = 0; i < L4DUNX; i++) { + k = i<<1; + l = j<<1; + L4dungeon[k][l] = dung[i][j]; + L4dungeon[k][l+1] = dung[i][j]; + L4dungeon[k+1][l] = dung[i][j]; + L4dungeon[k+1][l+1] = dung[i][j]; + } + } + // bottom left + for (j = 0; j < L4DUNY; j++) { + for(i = 0; i < L4DUNX; i++) { + k = i<<1; + l = j<<1; + L4dungeon[k][L4DUNY*2+l] = dung[i][L4DUNY - 1 - j]; + L4dungeon[k][L4DUNY*2+l+1] = dung[i][L4DUNY - 1 - j]; + L4dungeon[k+1][L4DUNY*2+l] = dung[i][L4DUNY - 1 - j]; + L4dungeon[k+1][L4DUNY*2+l+1] = dung[i][L4DUNY - 1 - j]; + } + } + // top right + for (j = 0; j < L4DUNY; j++) { + for(i = 0; i < L4DUNX; i++) { + k = i<<1; + l = j<<1; + L4dungeon[k+L4DUNX*2][l] = dung[L4DUNX - 1 - i][j]; + L4dungeon[k+L4DUNX*2][l+1] = dung[L4DUNX - 1 - i][j]; + L4dungeon[k+L4DUNX*2+1][l] = dung[L4DUNX - 1 - i][j]; + L4dungeon[k+L4DUNX*2+1][l+1] = dung[L4DUNX - 1 - i][j]; + } + } + // bottom right + for (j = 0; j < L4DUNY; j++) { + for(i = 0; i < L4DUNX; i++) { + k = i<<1; + l = j<<1; + L4dungeon[L4DUNX*2+k][L4DUNY*2+l] = dung[L4DUNX - 1 - i][L4DUNY - 1 - j]; + L4dungeon[L4DUNX*2+k][L4DUNY*2+l+1] = dung[L4DUNX - 1 - i][L4DUNY - 1 - j]; + L4dungeon[L4DUNX*2+k+1][L4DUNY*2+l] = dung[L4DUNX - 1 - i][L4DUNY - 1 - j]; + L4dungeon[L4DUNX*2+k+1][L4DUNY*2+l+1] = dung[L4DUNX - 1 - i][L4DUNY - 1 - j]; + } + } +} + +/*------------------------------------------------------------------------* +** Connecting the boxes to make U +**------------------------------------------------------------------------*/ +static void uShape() +{ + int j, i; + int rv; + + for (j = 19; j >= 0; j--) { + for (i = 19; i >= 0; i--) { + if (dung[i][j] != 1) hallok[j] = FALSE; + if (dung[i][j] == 1) { + if ((dung[i][j+1] == 1) && (dung[i+1][j+1] == 0)) { + hallok[j] = TRUE; + } + else hallok[j] = FALSE; + i = 0; // abort out of loop + } + } + } + rv = random(0, 19) + 1; + do{ + if (hallok[rv]) { + for (i = 19; i >= 0; i--) { + if (dung[i][rv] == 1) { + i = -1; + rv = 0; + } else { + dung[i][rv] = 1; + dung[i][rv+1] = 1; + } + + } + } else { + rv++; + if (rv == 20) rv = 1; + } + } while (rv != 0); + + for (i = 19; i >= 0; i--) { + for (j = 19; j >= 0; j--) { + if (dung[i][j] != 1) hallok[i] = FALSE; + if (dung[i][j] == 1) { + if ((dung[i+1][j] == 1) && (dung[i+1][j+1] == 0)) { + hallok[i] = TRUE; + } + else hallok[i] = FALSE; + j = 0; // abort out of loop + } + } + } + rv = random(0, 19) + 1; + do{ + if (hallok[rv]) { + for (j = 19; j >= 0; j--) { + if (dung[rv][j] == 1) { + j = -1; + rv = 0; + } else { + dung[rv][j] = 1; + dung[rv+1][j] = 1; + } + + } + } else { + rv++; + if (rv == 20) rv = 1; + } + } while (rv != 0); +} + +/*------------------------------------------------------------------------* +**------------------------------------------------------------------------*/ +static long GetArea() +{ + int i,j; + long rv; + + rv = 0; + for (j = 0; j < L4DUNY; j++) { + for (i = 0; i < L4DUNX; i++) { + if (dung[i][j] == 1) rv++; + } + } + return(rv); +} + +/*----------------------------------------------------------------------* +**----------------------------------------------------------------------*/ +static void L4drawRoom(int x, int y, int width, int height) +{ + int i, j; + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + dung[x+i][y+j] = 1; + } + } +} + +/*---------------------------------------------------------------------* +** Check limits of 20 X 20 +**---------------------------------------------------------------------*/ +static BOOL L4checkRoom(int x, int y, int width, int height) +{ + int i, j; + + if (( x <= 0 ) || (y <= 0)) return(FALSE); + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + if ((x+i < 0) || (x+i >= L4DUNX) || (y+j < 0) || (y+j >= L4DUNY)) return(FALSE); + if (dung[x+i][y+j] != 0) return(FALSE); + } + } + return(TRUE); +} + +/*---------------------------------------------------------------------** +** Generate left and right, up and down rooms +**---------------------------------------------------------------------*/ +static void L4roomGen(int x, int y, int w, int h, int dir) +{ + int rx, ry, rx2, ry2; + int height, width; + int cx1, cy1, cw, ch; + int num; + int dirProb; + int ran; + BOOL c, d; + + ran = random(0, 4); + if (dir == L4DIR_VERT) { + if (ran == 0) dirProb = L4DIR_HORIZ; + else dirProb = L4DIR_VERT; + } else { + if (ran == 0) dirProb = L4DIR_VERT; + else dirProb = L4DIR_HORIZ; + } + switch(dirProb) { + case L4DIR_HORIZ : // left/right + // left room + num = 0; + do { + width = ((random(0, L4ROOM_MAX-L4ROOM_MIN+1) + L4ROOM_MIN) >> 1) << 1; + height = ((random(0, L4ROOM_MAX-L4ROOM_MIN+1) + L4ROOM_MIN) >> 1) << 1; + ry = y + (h/2) - (height/2); + rx = x - width; + cx1 = rx - 1; + cy1 = ry - 1; + cw = height + 2; + ch = width + 1; + c = L4checkRoom(cx1, cy1, cw, ch); + num++; + } while ((c == FALSE) && (num < 20)); + if (c == TRUE) L4drawRoom(rx, ry, width, height); + + // right room + rx2 = x + w; + cx1 = rx2; + cy1 = ry - 1; + ch = height + 2; + cw = width + 1; + d = L4checkRoom(cx1, cy1, cw, ch); + if (d == TRUE) L4drawRoom(rx2, ry, width, height); + if (c == TRUE) L4roomGen(rx, ry, width, height, L4DIR_VERT); + if (d == TRUE) L4roomGen(rx2, ry, width, height, L4DIR_VERT); + break; + + case L4DIR_VERT : // top/bottom + // top room + num = 0; + do { + width = ((random(0, L4ROOM_MAX-L4ROOM_MIN+1) + L4ROOM_MIN) >> 1) << 1; + height = ((random(0, L4ROOM_MAX-L4ROOM_MIN+1) + L4ROOM_MIN) >> 1) << 1; + rx = x + (w/2) - (width/2); + ry = y - height; + cx1 = rx - 1; + cy1 = ry - 1; + ch = height + 1; + cw = width + 2; + c = L4checkRoom(cx1, cy1, cw, ch); + num++; + + } while ((c == FALSE) && (num < 20)); + if (c == TRUE) L4drawRoom(rx, ry, width, height); + + // bottom room + ry2 = y + h; + cx1 = rx - 1; + cy1 = ry2; + ch = height + 1; + cw = width + 2; + d = L4checkRoom(cx1, cy1, cw, ch); + if (d == TRUE) L4drawRoom(rx, ry2, width, height); + if (c == TRUE) L4roomGen(rx, ry, width, height, L4DIR_HORIZ); + if (d == TRUE) L4roomGen(rx, ry2, width, height, L4DIR_HORIZ); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void L4firstRoom() +{ + int x,y,w,h; + int xstor, ystor; + int rndx, rndy; + int xmin, xmax, ymin, ymax; + + if (currlevel != 16) { + if ((currlevel == quests[Q_WARLORD]._qlevel) && (quests[Q_WARLORD]._qactive != QUEST_NOTAVAIL)) { + app_assert(gbMaxPlayers == 1); + w = 11; + h = 11; + } + else if ((currlevel == quests[Q_BETRAYER]._qlevel) && (gbMaxPlayers != 1)) { + w = 11; + h = 11; + } + else { + w = ((random(0, L4ROOM_MAX-L4ROOM_MIN+1) + L4ROOM_MIN)); + h = ((random(0, L4ROOM_MAX-L4ROOM_MIN+1) + L4ROOM_MIN)); + } + } else { + w = DIABSIZE; + h = DIABSIZE; + } + + + xmin = ((20 - w) >>1); + xmax = (19 - w); + rndx = random(0, xmax - xmin + 1) + xmin; + if ((w + rndx) > 19) { + xstor = (w + rndx) - 19; + x = (rndx - xstor) + 1; + } + else x = rndx; + + ymin = ((20 - h) >>1); + ymax = (19 - h); + rndy = random(0, ymax - ymin + 1) + ymin; + if ((h + rndy) > 19) { + ystor = (h + rndy) - 19; + y = (rndy - ystor) + 1; + } + else y = rndy; + + if (currlevel == 16) { + l4holdx = x; + l4holdy = y; + } + if (QuestStatus(Q_WARLORD) + || ((currlevel == quests[Q_BETRAYER]._qlevel) && (gbMaxPlayers != 1))) { + SP4x1 = x + 1; + SP4y1 = y + 1; + SP4x2 = SP4x1 + w; + SP4y2 = SP4y1 + h; + } else { + SP4x1 = 0; + SP4y1 = 0; + SP4x2 = 0; + SP4y2 = 0; + } + + L4drawRoom(x, y, w, h); + L4roomGen(x, y, w, h, random(0, 2)); +} + +/*-----------------------------------------------------------------------** +** Save 4 quads for diablo level +**-----------------------------------------------------------------------*/ + +void L4SaveQuads() +{ + int i,j,x,y; + + x = l4holdx; + y = l4holdy; + for (j = 0; j < DIABSIZE; j++) { + for (i = 0; i < DIABSIZE; i++) { + dflags[x+i][y+j] = 1; + dflags[39-x-i][y+j] = 1; + dflags[x+i][39-y-j] = 1; + dflags[39-x-i][39-y-j] = 1; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DRLG_L4SetRoom(BYTE *pSetPiece, int rx1, int ry1) +{ + int rw,rh; + int i,j; + byte *sp; + + sp = pSetPiece; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + sp = pSetPiece+4; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp != 0) { + dungeon[rx1+i][ry1+j] = *sp; + dflags[rx1+i][ry1+j] |= SETP_BIT; + } else dungeon[rx1+i][ry1+j] = 6; + sp+=2; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DRLG_LoadDiabQuads(BOOL preflag) +{ + BYTE *pSetPiece; + + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab1.DUN",NULL,'STPC'); + diabquad1x = l4holdx + ((DIABSIZE - 6) >> 1); + diabquad1y = l4holdy + ((DIABSIZE - 6) >> 1); + DRLG_L4SetRoom(pSetPiece, diabquad1x, diabquad1y); + DiabloFreePtr(pSetPiece); + + if (preflag) pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab2b.DUN",NULL,'STPC'); + else pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab2a.DUN",NULL,'STPC'); + diabquad2x = 39 - 11 - l4holdx - ((DIABSIZE - 11) >> 1); + diabquad2y = l4holdy + ((DIABSIZE - 12) >> 1); + DRLG_L4SetRoom(pSetPiece, diabquad2x, diabquad2y); + DiabloFreePtr(pSetPiece); + + if (preflag) pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab3b.DUN",NULL,'STPC'); + else pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab3a.DUN",NULL,'STPC'); + diabquad3x = l4holdx + ((DIABSIZE - 11) >> 1); + diabquad3y = 39 - 11 - l4holdy - ((DIABSIZE - 11) >> 1); + DRLG_L4SetRoom(pSetPiece, diabquad3x, diabquad3y); + DiabloFreePtr(pSetPiece); + + if (preflag) pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab4b.DUN",NULL,'STPC'); + else pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab4a.DUN",NULL,'STPC'); + diabquad4x = 39 - 9 - l4holdx - ((DIABSIZE - 9) >> 1); + diabquad4y = 39 - 9 - l4holdy - ((DIABSIZE - 9) >> 1); + DRLG_L4SetRoom(pSetPiece, diabquad4x, diabquad4y); + DiabloFreePtr(pSetPiece); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL DRLG_L4PlaceMiniSet(const byte miniset[], int tmin, int tmax, int cx, int cy, int setview, int ldir) +{ + int sx, sy; + int sw, sh; + int xx, yy; + int i, ii, numt; + int found, bailcnt; + + // Width and height of the mini set piece + sw = miniset[0]; + sh = miniset[1]; + + // Number of pieces to place + if ((tmax - tmin) == 0) numt = 1; + else numt = random(0, tmax - tmin) + tmin; + + for (i = 0; i < numt; i++) { + // Random starting pos + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + + // Find a location for the mini set piece + found = 0; + bailcnt = 0; + while ((found == 0) && (bailcnt < 200)) { + found = 1; + + if (((sx >= SP4x1) && (sx <= SP4x2)) && ((sy >= SP4y1) && (sy <= SP4y2))) found = 0; + + if ((cx != -1) && (sx >= (cx - sw)) && (sx <= (cx + 12))) { + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + found = 0; + } + if ((cy != -1) && (sy >= (cy - sh)) && (sy <= (cy + 12))) { + sx = random(0, MDMAXX-sw); + sy = random(0, MDMAXY-sh); + found = 0; + } + ii = 2; + for (yy = 0; ((yy < sh) && (found == 1)); yy++) { + for (xx = 0; ((xx < sw) && (found == 1)); xx++) { + if ((miniset[ii] != 0) && (dungeon[sx+xx][sy+yy] != miniset[ii])) found = 0; + if (dflags[sx+xx][sy+yy] != 0) found = 0; + ii++; + } + } + if (found == 0) { + sx++; + if (sx == (MDMAXX - sw)) { + sx = 0; + sy++; + if (sy == (MDMAXY - sh)) sy = 0; + } + + } + bailcnt++; + } + + if (bailcnt >= 200) return(FALSE); + + // Place mini set piece + ii = (sh * sw) + 2; + for (yy = 0; yy < sh; yy++) { + for (xx = 0; xx < sw; xx++) { + if (miniset[ii] != 0) { + dungeon[sx+xx][sy+yy] = miniset[ii]; + dflags[sx+xx][sy+yy] |= BFLAG_SETPC; + } + ii++; + } + } + } + if (currlevel == 15) // Don't take this out + { + quests[Q_BETRAYER]._qtx = sx+1 ; + quests[Q_BETRAYER]._qty = sy+1; + } + + if (setview == 1) { + ViewX = (sx << 1) + 3 + (DIRTEDGED2) + 2; + ViewY = (sy << 1) + 4 + (DIRTEDGED2) + 2; + } + + if (ldir == LVL_DOWN) { + LvlViewX = (sx << 1) + 3 + (DIRTEDGED2) + 2; + LvlViewY = (sy << 1) + 4 + (DIRTEDGED2) + 2; + } + + return(TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4FTVR(int i, int j, int x, int y, int d) +{ + if ((dTransVal[x][y] == 0) && (dungeon[i][j] == FLOOR_PIC)) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + DRLG_L4FTVR(i+1,j, x+2,y, 1); + DRLG_L4FTVR(i-1,j, x-2,y, 2); + DRLG_L4FTVR(i,j+1, x,y+2, 3); + DRLG_L4FTVR(i,j-1, x,y-2, 4); + + DRLG_L4FTVR(i-1,j-1, x-2,y-2, 5); + DRLG_L4FTVR(i+1,j-1, x+2,y-2, 6); + DRLG_L4FTVR(i-1,j+1, x-2,y+2, 7); + DRLG_L4FTVR(i+1,j+1, x+2,y+2, 8); + } else { + if (d == 1) { + dTransVal[x][y] = TransVal; + dTransVal[x][y+1] = TransVal; + } + if (d == 2) { + dTransVal[x+1][y] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 3) { + dTransVal[x][y] = TransVal; + dTransVal[x+1][y] = TransVal; + } + if (d == 4) { + dTransVal[x][y+1] = TransVal; + dTransVal[x+1][y+1] = TransVal; + } + if (d == 5) dTransVal[x+1][y+1] = TransVal; + if (d == 6) dTransVal[x][y+1] = TransVal; + if (d == 7) dTransVal[x+1][y] = TransVal; + if (d == 8) dTransVal[x][y] = TransVal; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4FloodTVal() +{ + int i, j; + int xx,yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if ((dungeon[i][j] == FLOOR_PIC) && (dTransVal[xx][yy] == 0)) { + DRLG_L4FTVR(i,j,xx,yy,0); + TransVal++; + } + xx += 2; + } + yy += 2; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL IsDURWall(char d) +{ + if (d == DURWALL_PIC) return(TRUE); + if (d == DURWALL2_PIC) return(TRUE); + if (d == DURWALL3_PIC) return(TRUE); + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL IsDLLWall(char dd) +{ + if (dd == DLLWALL_PIC) return(TRUE); + if (dd == DLLWALL2_PIC) return(TRUE); + if (dd == DLLWALL3_PIC) return(TRUE); + return(FALSE); +} +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4TransFix() +{ + int i, j; + int xx,yy; + + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + if (((IsDURWall(dungeon[i][j])) && (dungeon[i][j-1] == DVWALL_PIC))) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (((IsDLLWall(dungeon[i][j])) && (dungeon[i+1][j] == DHWALL_PIC))) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == DVWALL_PIC) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == DHWALL_PIC) { + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == DLRWALL_PIC) { + dTransVal[xx+1][yy] = dTransVal[xx][yy]; + dTransVal[xx][yy+1] = dTransVal[xx][yy]; + dTransVal[xx+1][yy+1] = dTransVal[xx][yy]; + } + if (dungeon[i][j] == XARCHWALL_PIC) { + dTransVal[xx-1][yy] = dTransVal[xx][yy+1]; + dTransVal[xx][yy] = dTransVal[xx][yy+1]; + } + if (dungeon[i][j] == YARCHWALL_PIC) { + dTransVal[xx][yy-1] = dTransVal[xx+1][yy]; + dTransVal[xx][yy] = dTransVal[xx+1][yy]; + } + + xx += 2; + } + yy += 2; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4Corners() +{ + int i,j; + + for (j = 1; j < MDMAXY-1; j++) { + for (i = 1; i < MDMAXX-1; i++) { + if ((dungeon[i][j] >= 18) && (dungeon[i][j] <= 30)) { + if (dungeon[i+1][j] < 18) { + dungeon[i][j] += 98; + } else + if (dungeon[i][j+1] < 18) dungeon[i][j] += 98; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void L4FixRim() +{ + for (int i = 0; i < 20; i++) dung[i][0] = 0; + for (int j = 0; j < 20; j++) dung[0][j] = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DRLG_L4GeneralFix() +{ + int i,j; + + for (j = 0; j < MDMAXY-1; j++) { + for (i = 0; i < MDMAXX-1; i++) { + if ((dungeon[i][j] == 24) || (dungeon[i][j] == 122)) { + if ((dungeon[i+1][j] == 2) && (dungeon[i][j+1] == 5)) dungeon[i][j] = 17; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4(int entry) +{ + long area; + int t; + BOOL doneflag; + int i, j; + int spi, spj; + + doneflag = FALSE; + while (!doneflag) { + + DRLG_InitTrans(); + t = 0; + + do { + InitL4Dungeon(); + L4firstRoom(); + L4FixRim(); + area = GetArea(); + if (area >= L4MIN_AREA) uShape(); + t++; + }while (area < L4MIN_AREA); + L4makeDungeon(); + L4makeDmt(); + L4tileFix(); + + if (currlevel == 16) L4SaveQuads(); + if (QuestStatus(Q_WARLORD) || ((currlevel == quests[Q_BETRAYER]._qlevel) && (gbMaxPlayers != 1))) { + for (spi = SP4x1; spi < SP4x2;spi++) { + for (spj = SP4y1; spj < SP4y2; spj++) + dflags[spi][spj] = 1; + } + } + + L4AddWall(); + DRLG_L4FloodTVal(); + DRLG_L4TransFix(); + + if (setloadflag) { + DRLG_L4SetSPRoom(SP4x1,SP4y1); + } + + if (currlevel == 16) { + DRLG_LoadDiabQuads(TRUE); + } + + if (QuestStatus(Q_WARLORD)) { + if (entry == LVL_DOWN) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, LVL_DOWN); + if ((doneflag) && (currlevel == 13)) doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, LVL_TWARPDN); + ViewX++; + } else { + if (entry == LVL_UP) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, LVL_DOWN); + if ((doneflag) && (currlevel == 13)) doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, LVL_TWARPDN); + ViewX = (setpc_x << 1) + 6 + DIRTEDGED2; + ViewY = (setpc_y << 1) + 6 + DIRTEDGED2; + } else { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, LVL_DOWN); + if ((doneflag) && (currlevel == 13)) doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 1, LVL_TWARPDN); + ViewX++; + } + } + } else if (currlevel != 15) { + if (entry == LVL_DOWN) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, LVL_DOWN); + if ((doneflag) && (currlevel != 16)) doneflag = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, LVL_UP); + if ((doneflag) && (currlevel == 13)) doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, LVL_TWARPDN); + ViewX++; + } else { + if (entry == LVL_UP) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, LVL_DOWN); + if ((doneflag) && (currlevel != 16)) doneflag = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 1, LVL_UP); + if ((doneflag) && (currlevel == 13)) doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, LVL_TWARPDN); + ViewY++; + } else { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, LVL_DOWN); + if ((doneflag) && (currlevel != 16)) doneflag = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, LVL_UP); + if ((doneflag) && (currlevel == 13)) doneflag = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 1, LVL_TWARPDN); + ViewX++; + } + } + } else { + if (entry == LVL_DOWN) { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, LVL_DOWN); + if (doneflag) { + if ((gbMaxPlayers != 1) || (quests[Q_DIABLO]._qactive == QUEST_NOTDONE)) + doneflag = DRLG_L4PlaceMiniSet(L4PENTA2, 1, 1, -1, -1, 0, LVL_UP); + else + doneflag = DRLG_L4PlaceMiniSet(L4PENTA, 1, 1, -1, -1, 0, LVL_UP); + } + ViewX++; + } else { + doneflag = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, LVL_DOWN); + if (doneflag) { + if ((gbMaxPlayers != 1) || (quests[Q_DIABLO]._qactive == QUEST_NOTDONE)) + doneflag = DRLG_L4PlaceMiniSet(L4PENTA2, 1, 1, -1, -1, 1, LVL_UP); + else + doneflag = DRLG_L4PlaceMiniSet(L4PENTA, 1, 1, -1, -1, 1, LVL_UP); + } + ViewY++; + } + } + } + + DRLG_L4GeneralFix(); + + if (currlevel != 16) DRLG_PlaceThemeRooms(7, 10, FLOOR_PIC, 8, TRUE); + + // Create shadows + DRLG_L4Shadows(); + + DRLG_L4Corners(); + + DRLG_L4Subs(); + + extern void DRLG_Init_Globals(); + DRLG_Init_Globals(); + + // for warlord quest + if (QuestStatus(Q_WARLORD)) { + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } + } + DRLG_CheckQuests(SP4x1,SP4y1); + + // make sure nothing is placed on the pentagrams + if (currlevel == 15) { + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + if (dungeon[i][j] == 98) Make_SetPC(i-1, j-1, 5, 5); + if (dungeon[i][j] == 107) Make_SetPC(i-1, j-1, 5, 5); + } + } + } + + // for diablo level, we need to save the current state so we can use the switches + if (currlevel == 16) { + // Save the layout for the switches + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } + + // set the current layout + DRLG_LoadDiabQuads(FALSE); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DRLG_L4Pass3() +{ + int i,j,xx,yy; + long v1,v2,v3,v4,lv; + + // Init dungeon to dirt + lv = 30 - 1; + __asm { + mov esi,dword ptr [pMegaTiles] + mov eax,dword ptr [lv]; + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + } + for (yy = 0; yy < DMAXY; yy+=2) { + for (xx = 0; xx < DMAXX; xx+=2) { + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; + } + } + + // Convert dungeon mega tiles to mini tiles + yy = DIRTEDGED2; + for (j = 0; j < MDMAXY; j++) { + xx = DIRTEDGED2; + for (i = 0; i < MDMAXX; i++) { + lv = ((long)dungeon[i][j]) - 1; + if (lv >= 0) { + __asm { + mov esi,dword ptr [pMegaTiles] + mov eax,dword ptr [lv]; + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + } + } else { + v1 = 0; + v2 = 0; + v3 = 0; + v4 = 0; + } + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; + xx += 2; + } + yy += 2; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if IS_VERSION(RETAIL) +void CreateL4Dungeon(unsigned int rseed, int entry) +{ + SetRndSeed(rseed); + + dminx = DIRTEDGED2; + dminy = DIRTEDGED2; + dmaxx = DMAXX - (DIRTEDGED2); + dmaxy = DMAXY - (DIRTEDGED2); + + ViewX = 40; + ViewY = 40; + + DRLG_InitSetPC(); + DRLG_LoadL4SP(); + DRLG_L4(entry); + DRLG_L4Pass3(); + DRLG_FreeL4SP(); + + // Init the light values for each piece +/* + for (int j = 0; j < DMAXY; j++) { + for (int i = 0; i < DMAXX; i++) { + // Tops of doors + //if (dPiece[i][j] == 13) dSpecial[i][j] = 5; + //if (dPiece[i][j] == 17) dSpecial[i][j] = 6; + } + } +*/ + DRLG_SetPC(); +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void L4DrawDung() +{ + byte *p, *p2; + + p = &dungeon[0][0]; + p2 = &dflags[0][0]; + app_assert(gpBuffer); + __asm { + // draw dung + mov esi,dword ptr [p] + mov edi,dword ptr [gpBuffer] + add edi,135248 + mov edx,40 +_YLp: push edi + mov ecx,40 +_XLp: lodsb + cmp al,0 + jz _Save + mov al,229 +_Save: mov byte ptr [edi],al + add edi,768 + loop _XLp + pop edi + inc edi + dec edx + jnz _YLp + + // Draw dflags + mov esi,dword ptr [p2] + mov edi,dword ptr [gpBuffer] + add edi,135248 + mov edx,40 +_YLp2: push edi + mov ecx,40 +_XLp2: lodsb + cmp al,0 + jz _Skip + mov al,146 + mov byte ptr [edi],al +_Skip: add edi,768 + loop _XLp2 + pop edi + inc edi + dec edx + jnz _YLp2 + } +} diff --git a/DRLG_L4.H b/DRLG_L4.H new file mode 100644 index 0000000..63f1fc9 --- /dev/null +++ b/DRLG_L4.H @@ -0,0 +1,86 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/DRLG_L4.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define L4DIR_HORIZ 0 +#define L4DIR_VERT 1 + +#define L4ROOM_MIN 2 +#define L4ROOM_MAX 6 + +#define L4DUNX 20 +#define L4DUNY 20 + +#define L4MIN_AREA ((L4DUNX*L4DUNY)/3) + ((L4DUNX*L4DUNY)/10) + +#define L4DX 80 +#define L4DY 80 +#define L4_DIRT 12 + +#define NUMBBLOCKS 140 + +// PIC == PIECE +#define VWALL_PIC 1 +#define HWALL_PIC 2 +#define LRWALL_PIC 12 +#define FLOOR_PIC 6 +#define URWALL_PIC 16 +#define ULWALL_PIC 9 +#define LLWALL_PIC 15 + +#define DVWALL_PIC 18 +#define DHWALL_PIC 19 +#define DFLOOR_PIC 20 +#define DULWALL_PIC 21 + +#define DURWALL_PIC 25 +#define DURWALL2_PIC 28 +#define DURWALL3_PIC 23 + +#define DLLWALL_PIC 27 +#define DLLWALL2_PIC 26 +#define DLLWALL3_PIC 22 + +#define DLRWALL_PIC 24 +#define DIRT_PIC 30 +//Arches +#define YARCHWALL_PIC 53 +#define XARCHWALL_PIC 57 + +#define NUMSPATS 37 +#define _1S 47 +#define _2S 48 +#define _3S 49 +#define _4S 50 +#define _5S 51 +#define _6S 54 +#define _7S 55 +#define _8S 58 +#define _9S 59 +#define _10S 60 + + +/*-----------------------------------------------------------------------** +** externs +**-----------------------------------------------------------------------*/ + +extern int diabquad1x, diabquad2x, diabquad3x, diabquad4x; +extern int diabquad1y, diabquad2y, diabquad3y, diabquad4y; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void CreateL4Dungeon(unsigned int, int); +//int DRLG_L4Spawn(int, int, int *); diff --git a/DSOUND.H b/DSOUND.H new file mode 100644 index 0000000..28a5766 --- /dev/null +++ b/DSOUND.H @@ -0,0 +1,605 @@ +/*==========================================================================; + * + * Copyright (C) 1995,1996 Microsoft Corporation. All Rights Reserved. + * + * File: dsound.h + * Content: DirectSound include file + * + ***************************************************************************/ + +#ifndef __DSOUND_INCLUDED__ +#define __DSOUND_INCLUDED__ + +#include "d3dtypes.h" + +#ifdef _WIN32 +#define COM_NO_WINDOWS_H +#include +#endif + +#define _FACDS 0x878 +#define MAKE_DSHRESULT( code ) MAKE_HRESULT( 1, _FACDS, code ) + +#ifdef __cplusplus +extern "C" { +#endif + +// Direct Sound Component GUID {47D4D946-62E8-11cf-93BC-444553540000} +DEFINE_GUID(CLSID_DirectSound, +0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0); + +// DirectSound 279afa83-4981-11ce-a521-0020af0be560 +DEFINE_GUID(IID_IDirectSound,0x279AFA83,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); +// DirectSoundBuffer 279afa85-4981-11ce-a521-0020af0be560 +DEFINE_GUID(IID_IDirectSoundBuffer,0x279AFA85,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); + +//DirectSound3DListener 279afa84-4981-11ce-a521-0020af0be560 +DEFINE_GUID(IID_IDirectSound3DListener,0x279AFA84,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); +//DirectSound3DBuffer 279afa86-4981-11ce-a521-0020af0be560 +DEFINE_GUID(IID_IDirectSound3DBuffer,0x279AFA86,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); + + +//==========================================================================; +// +// Structures... +// +//==========================================================================; +#ifdef __cplusplus +/* 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined */ +struct IDirectSound; +struct IDirectSoundBuffer; +struct IDirectSound3DListener; +struct IDirectSound3DBuffer; +#endif + +typedef struct IDirectSound *LPDIRECTSOUND; +typedef struct IDirectSoundBuffer *LPDIRECTSOUNDBUFFER; +typedef struct IDirectSoundBuffer **LPLPDIRECTSOUNDBUFFER; +typedef struct IDirectSound3DListener *LPDIRECTSOUND3DLISTENER; +typedef struct IDirectSound3DBuffer *LPDIRECTSOUND3DBUFFER; + + +typedef struct _DSCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwMinSecondarySampleRate; + DWORD dwMaxSecondarySampleRate; + DWORD dwPrimaryBuffers; + DWORD dwMaxHwMixingAllBuffers; + DWORD dwMaxHwMixingStaticBuffers; + DWORD dwMaxHwMixingStreamingBuffers; + DWORD dwFreeHwMixingAllBuffers; + DWORD dwFreeHwMixingStaticBuffers; + DWORD dwFreeHwMixingStreamingBuffers; + DWORD dwMaxHw3DAllBuffers; + DWORD dwMaxHw3DStaticBuffers; + DWORD dwMaxHw3DStreamingBuffers; + DWORD dwFreeHw3DAllBuffers; + DWORD dwFreeHw3DStaticBuffers; + DWORD dwFreeHw3DStreamingBuffers; + DWORD dwTotalHwMemBytes; + DWORD dwFreeHwMemBytes; + DWORD dwMaxContigFreeHwMemBytes; + DWORD dwUnlockTransferRateHwBuffers; + DWORD dwPlayCpuOverheadSwBuffers; + DWORD dwReserved1; + DWORD dwReserved2; +} DSCAPS, *LPDSCAPS; + +typedef struct _DSBCAPS +{ + + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwUnlockTransferRate; + DWORD dwPlayCpuOverhead; +} DSBCAPS, *LPDSBCAPS; + +typedef struct _DSBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSBUFFERDESC, *LPDSBUFFERDESC; + +typedef struct _DS3DBUFFER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + DWORD dwInsideConeAngle; + DWORD dwOutsideConeAngle; + D3DVECTOR vConeOrientation; + LONG lConeOutsideVolume; + D3DVALUE flMinDistance; + D3DVALUE flMaxDistance; + DWORD dwMode; +} DS3DBUFFER, *LPDS3DBUFFER; + +typedef struct _DS3DLISTENER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + D3DVECTOR vOrientFront; + D3DVECTOR vOrientTop; + D3DVALUE flDistanceFactor; + D3DVALUE flRolloffFactor; + D3DVALUE flDopplerFactor; +} DS3DLISTENER, *LPDS3DLISTENER; + + + +typedef LPVOID* LPLPVOID; + + +typedef BOOL (FAR PASCAL * LPDSENUMCALLBACKW)(const GUID FAR *, LPWSTR, LPWSTR, LPVOID); +typedef BOOL (FAR PASCAL * LPDSENUMCALLBACKA)(const GUID FAR *, LPSTR, LPSTR, LPVOID); + +extern HRESULT WINAPI DirectSoundCreate(const GUID * lpGUID, LPDIRECTSOUND * ppDS, IUnknown FAR *pUnkOuter ); +extern HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW lpCallback, LPVOID lpContext ); +extern HRESULT WINAPI DirectSoundEnumerateA(LPDSENUMCALLBACKA lpCallback, LPVOID lpContext ); + +#ifdef UNICODE +#define LPDSENUMCALLBACK LPDSENUMCALLBACKW +#define DirectSoundEnumerate DirectSoundEnumerateW +#else +#define LPDSENUMCALLBACK LPDSENUMCALLBACKA +#define DirectSoundEnumerate DirectSoundEnumerateA +#endif + +// +// IDirectSound +// +#undef INTERFACE +#define INTERFACE IDirectSound +#ifdef _WIN32 +DECLARE_INTERFACE_( IDirectSound, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectSound methods ***/ + + STDMETHOD( CreateSoundBuffer)(THIS_ LPDSBUFFERDESC, LPLPDIRECTSOUNDBUFFER, IUnknown FAR *) PURE; + STDMETHOD( GetCaps)(THIS_ LPDSCAPS ) PURE; + STDMETHOD( DuplicateSoundBuffer)(THIS_ LPDIRECTSOUNDBUFFER, LPLPDIRECTSOUNDBUFFER ) PURE; + STDMETHOD( SetCooperativeLevel)(THIS_ HWND, DWORD ) PURE; + STDMETHOD( Compact)(THIS ) PURE; + STDMETHOD( GetSpeakerConfig)(THIS_ LPDWORD ) PURE; + STDMETHOD( SetSpeakerConfig)(THIS_ DWORD ) PURE; + STDMETHOD( Initialize)(THIS_ const GUID * ) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSound_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSound_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->lpVtbl->CreateSoundBuffer(p,a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->lpVtbl->DuplicateSoundBuffer(p,a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectSound_Compact(p) (p)->lpVtbl->Compact(p) +#define IDirectSound_GetSpeakerConfig(p,a) (p)->lpVtbl->GetSpeakerConfig(p,a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->lpVtbl->SetSpeakerConfig(p,b) +#define IDirectSound_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) +#else +#define IDirectSound_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSound_AddRef(p) (p)->AddRef() +#define IDirectSound_Release(p) (p)->Release() +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->CreateSoundBuffer(a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->DuplicateSoundBuffer(a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectSound_Compact(p) (p)->Compact() +#define IDirectSound_GetSpeakerConfig(p,a) (p)->GetSpeakerConfig(a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->SetSpeakerConfig(b) +#define IDirectSound_Initialize(p,a) (p)->Initialize(a) +#endif + +#endif + +// +// IDirectSoundBuffer +// +#undef INTERFACE +#define INTERFACE IDirectSoundBuffer +#ifdef _WIN32 +DECLARE_INTERFACE_( IDirectSoundBuffer, IUnknown ) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectSoundBuffer methods ***/ + + STDMETHOD( GetCaps)(THIS_ LPDSBCAPS ) PURE; + STDMETHOD(GetCurrentPosition)(THIS_ LPDWORD,LPDWORD ) PURE; + STDMETHOD( GetFormat)(THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) PURE; + STDMETHOD( GetVolume)(THIS_ LPLONG ) PURE; + STDMETHOD( GetPan)(THIS_ LPLONG ) PURE; + STDMETHOD( GetFrequency)(THIS_ LPDWORD ) PURE; + STDMETHOD( GetStatus)(THIS_ LPDWORD ) PURE; + STDMETHOD( Initialize)(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC ) PURE; + STDMETHOD( Lock)(THIS_ DWORD,DWORD,LPVOID,LPDWORD,LPVOID,LPDWORD,DWORD ) PURE; + STDMETHOD( Play)(THIS_ DWORD,DWORD,DWORD ) PURE; + STDMETHOD(SetCurrentPosition)(THIS_ DWORD ) PURE; + STDMETHOD( SetFormat)(THIS_ LPWAVEFORMATEX ) PURE; + STDMETHOD( SetVolume)(THIS_ LONG ) PURE; + STDMETHOD( SetPan)(THIS_ LONG ) PURE; + STDMETHOD( SetFrequency)(THIS_ DWORD ) PURE; + STDMETHOD( Stop)(THIS ) PURE; + STDMETHOD( Unlock)(THIS_ LPVOID,DWORD,LPVOID,DWORD ) PURE; + STDMETHOD( Restore)(THIS ) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSoundBuffer_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSoundBuffer_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSoundBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->lpVtbl->GetVolume(p,a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->lpVtbl->GetPan(p,a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->lpVtbl->GetFrequency(p,a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->lpVtbl->Play(p,a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->lpVtbl->SetCurrentPosition(p,a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->lpVtbl->SetVolume(p,a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->lpVtbl->SetPan(p,a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->lpVtbl->SetFrequency(p,a) +#define IDirectSoundBuffer_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->lpVtbl->Restore(p) +#else +#define IDirectSoundBuffer_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSoundBuffer_AddRef(p) (p)->AddRef() +#define IDirectSoundBuffer_Release(p) (p)->Release() +#define IDirectSoundBuffer_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->GetCurrentPosition(a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->GetFormat(a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->GetVolume(a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->GetPan(a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->GetFrequency(a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->GetStatus(a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->Lock(a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->Play(a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->SetCurrentPosition(a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->SetFormat(a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->SetVolume(a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->SetPan(a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->SetFrequency(a) +#define IDirectSoundBuffer_Stop(p) (p)->Stop() +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->Unlock(a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->Restore() +#endif + +#endif + +// +// IDirectSound3DListener +// +#undef INTERFACE +#define INTERFACE IDirectSound3DListener +#ifdef _WIN32 +DECLARE_INTERFACE_(IDirectSound3DListener, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IDirectSound3D methods ***/ + STDMETHOD(GetAllParameters)(THIS_ LPDS3DLISTENER) PURE; + STDMETHOD(GetDistanceFactor)(THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetDopplerFactor)(THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetOrientation)(THIS_ LPD3DVECTOR, LPD3DVECTOR) PURE; + STDMETHOD(GetPosition)(THIS_ LPD3DVECTOR) PURE; + STDMETHOD(GetRolloffFactor)(THIS_ LPD3DVALUE ) PURE; + STDMETHOD(GetVelocity)(THIS_ LPD3DVECTOR) PURE; + STDMETHOD(SetAllParameters)(THIS_ LPDS3DLISTENER, DWORD) PURE; + STDMETHOD(SetDistanceFactor)(THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetDopplerFactor)(THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetOrientation)(THIS_ D3DVALUE, D3DVALUE, D3DVALUE, D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetPosition)(THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetRolloffFactor)(THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetVelocity)(THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(CommitDeferredSettings)(THIS) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DListener_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSound3DListener_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSound3DListener_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->lpVtbl->GetDistanceFactor(p,a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->lpVtbl->GetDopplerFactor(p,a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->lpVtbl->GetOrientation(p,a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->lpVtbl->GetRolloffFactor(p,a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->lpVtbl->SetDistanceFactor(p,a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->lpVtbl->SetDopplerFactor(p,a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->lpVtbl->SetOrientation(p,a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->lpVtbl->SetRolloffFactor(p,a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->lpVtbl->CommitDeferredSettings(p) +#else +#define IDirectSound3DListener_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSound3DListener_AddRef(p) (p)->AddRef() +#define IDirectSound3DListener_Release(p) (p)->Release() +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->GetDistanceFactor(a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->GetDopplerFactor(a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->GetOrientation(a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->GetRolloffFactor(a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->SetDistanceFactor(a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->SetDopplerFactor(a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->SetOrientation(a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->SetRolloffFactor(a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->CommitDeferredSettings() +#endif + +#endif + +// +// IDirectSound3DBuffer +// +#undef INTERFACE +#define INTERFACE IDirectSound3DBuffer +#ifdef _WIN32 +DECLARE_INTERFACE_(IDirectSound3DBuffer, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IDirectSoundBuffer3D methods ***/ + STDMETHOD(GetAllParameters)(THIS_ LPDS3DBUFFER) PURE; + STDMETHOD(GetConeAngles)(THIS_ LPDWORD, LPDWORD) PURE; + STDMETHOD(GetConeOrientation)(THIS_ LPD3DVECTOR) PURE; + STDMETHOD(GetConeOutsideVolume)(THIS_ LPLONG) PURE; + STDMETHOD(GetMaxDistance)(THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetMinDistance)(THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetMode)(THIS_ LPDWORD) PURE; + STDMETHOD(GetPosition)(THIS_ LPD3DVECTOR) PURE; + STDMETHOD(GetVelocity)(THIS_ LPD3DVECTOR) PURE; + STDMETHOD(SetAllParameters)(THIS_ LPDS3DBUFFER, DWORD) PURE; + STDMETHOD(SetConeAngles)(THIS_ DWORD, DWORD, DWORD) PURE; + STDMETHOD(SetConeOrientation)(THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetConeOutsideVolume)(THIS_ LONG, DWORD) PURE; + STDMETHOD(SetMaxDistance)(THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetMinDistance)(THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetMode)(THIS_ DWORD, DWORD) PURE; + STDMETHOD(SetPosition)(THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetVelocity)(THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSound3DBuffer_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSound3DBuffer_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->lpVtbl->GetConeAngles(p,a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->lpVtbl->GetConeOrientation(p,a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->lpVtbl->GetConeOutsideVolume(p,a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->lpVtbl->GetMinDistance(p,a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->lpVtbl->GetMaxDistance(p,a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->lpVtbl->GetMode(p,a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->lpVtbl->SetConeAngles(p,a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->lpVtbl->SetConeOrientation(p,a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b)(p)->lpVtbl->SetConeOutsideVolume(p,a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->lpVtbl->SetMinDistance(p,a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->lpVtbl->SetMaxDistance(p,a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->lpVtbl->SetMode(p,a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#else +#define IDirectSound3DBuffer_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSound3DBuffer_AddRef(p) (p)->AddRef() +#define IDirectSound3DBuffer_Release(p) (p)->Release() +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->GetConeAngles(a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->GetConeOrientation(a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->GetConeOutsideVolume(a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->GetMinDistance(a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->GetMaxDistance(a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->GetMode(a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->SetConeAngles(a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->SetConeOrientation(a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b)(p)->SetConeOutsideVolume(a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->SetMinDistance(a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->SetMaxDistance(a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->SetMode(a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#endif + +#endif + + +/* + * Return Codes + */ + +#define DS_OK 0 + +/* + * The call failed because resources (such as a priority level) + * were already being used by another caller. + */ +#define DSERR_ALLOCATED MAKE_DSHRESULT( 10 ) +/* + * The control (vol,pan,etc.) requested by the caller is not available. + */ +#define DSERR_CONTROLUNAVAIL MAKE_DSHRESULT( 30 ) +/* + * An invalid parameter was passed to the returning function + */ +#define DSERR_INVALIDPARAM E_INVALIDARG +/* + * This call is not valid for the current state of this object + */ +#define DSERR_INVALIDCALL MAKE_DSHRESULT( 50 ) +/* + * An undetermined error occured inside the DSound subsystem + */ +#define DSERR_GENERIC E_FAIL +/* + * The caller does not have the priority level required for the function to + * succeed. + */ +#define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT( 70 ) +/* + * The DSound subsystem couldn't allocate sufficient memory to complete the + * caller's request. + */ +#define DSERR_OUTOFMEMORY E_OUTOFMEMORY +/* + * The specified WAVE format is not supported + */ +#define DSERR_BADFORMAT MAKE_DSHRESULT( 100 ) +/* + * The function called is not supported at this time + */ +#define DSERR_UNSUPPORTED E_NOTIMPL +/* + * No sound driver is available for use + */ +#define DSERR_NODRIVER MAKE_DSHRESULT( 120 ) +/* + * This object is already initialized + */ +#define DSERR_ALREADYINITIALIZED MAKE_DSHRESULT( 130 ) +/* + * This object does not support aggregation + */ +#define DSERR_NOAGGREGATION CLASS_E_NOAGGREGATION +/* + * The buffer memory has been lost, and must be Restored. + */ +#define DSERR_BUFFERLOST MAKE_DSHRESULT( 150 ) +/* + * Another app has a higher priority level, preventing this call from + * succeeding. + */ +#define DSERR_OTHERAPPHASPRIO MAKE_DSHRESULT( 160 ) +/* + * The Initialize() member on the Direct Sound Object has not been + * called or called successfully before calls to other members. + */ +#define DSERR_UNINITIALIZED MAKE_DSHRESULT( 170 ) + + + + +//==========================================================================; +// +// Flags... +// +//==========================================================================; + +#define DSCAPS_PRIMARYMONO 0x00000001 +#define DSCAPS_PRIMARYSTEREO 0x00000002 +#define DSCAPS_PRIMARY8BIT 0x00000004 +#define DSCAPS_PRIMARY16BIT 0x00000008 +#define DSCAPS_CONTINUOUSRATE 0x00000010 +#define DSCAPS_EMULDRIVER 0x00000020 +#define DSCAPS_CERTIFIED 0x00000040 +#define DSCAPS_SECONDARYMONO 0x00000100 +#define DSCAPS_SECONDARYSTEREO 0x00000200 +#define DSCAPS_SECONDARY8BIT 0x00000400 +#define DSCAPS_SECONDARY16BIT 0x00000800 + + + +#define DSBPLAY_LOOPING 0x00000001 + + +#define DSBSTATUS_PLAYING 0x00000001 +#define DSBSTATUS_BUFFERLOST 0x00000002 +#define DSBSTATUS_LOOPING 0x00000004 + + +#define DSBLOCK_FROMWRITECURSOR 0x00000001 + + + +#define DSSCL_NORMAL 1 +#define DSSCL_PRIORITY 2 +#define DSSCL_EXCLUSIVE 3 +#define DSSCL_WRITEPRIMARY 4 + + + +// flags for IDirectSound3DBuffer::SetMode +#define DS3DMODE_NORMAL 0 // default must be 0 +#define DS3DMODE_HEADRELATIVE 1 +#define DS3DMODE_DISABLE 2 + +// flags for dwApply parameter of some 3D functions +#define DS3D_IMMEDIATE 0 +#define DS3D_DEFERRED 1 + +// default values for 3d factors +#define DS3D_DEFAULTDISTANCEFACTOR 1.0f +#define DS3D_DEFAULTROLLOFFFACTOR 1.0f +#define DS3D_DEFAULTDOPPLERFACTOR 1.0f + +#define DSBCAPS_PRIMARYBUFFER 0x00000001 +#define DSBCAPS_STATIC 0x00000002 +#define DSBCAPS_LOCHARDWARE 0x00000004 +#define DSBCAPS_LOCSOFTWARE 0x00000008 +#define DSBCAPS_CTRL3D 0x00000010 +#define DSBCAPS_CTRLFREQUENCY 0x00000020 +#define DSBCAPS_CTRLPAN 0x00000040 +#define DSBCAPS_CTRLVOLUME 0x00000080 +#define DSBCAPS_CTRLDEFAULT 0x000000E0 // Pan + volume + frequency. +#define DSBCAPS_CTRLALL 0x000000F0 // All control capabilities +#define DSBCAPS_STICKYFOCUS 0x00004000 +#define DSBCAPS_GLOBALFOCUS 0x00008000 +#define DSBCAPS_GETCURRENTPOSITION2 0x00010000 // More accurate play cursor under emulation + + + + +#define DSSPEAKER_HEADPHONE 1 +#define DSSPEAKER_MONO 2 +#define DSSPEAKER_QUAD 3 +#define DSSPEAKER_STEREO 4 +#define DSSPEAKER_SURROUND 5 + + + + + + +#ifdef __cplusplus +}; +#endif + +#endif /* __DSOUND_INCLUDED__ */ diff --git a/DSOUND.LIB b/DSOUND.LIB new file mode 100644 index 0000000..dae02aa Binary files /dev/null and b/DSOUND.LIB differ diff --git a/DTHREAD.CPP b/DTHREAD.CPP new file mode 100644 index 0000000..741b8ed --- /dev/null +++ b/DTHREAD.CPP @@ -0,0 +1,214 @@ +//****************************************************************** +// dthread.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include +#include "msg.h" +#include "multi.h" +#include "gendung.h" +#include "sound.h" +#include "storm/h/storm.h" +#include "items.h" +#include "player.h" +#include "engine.h" + + +//****************************************************************** +// extern +//****************************************************************** +extern DWORD gdwDeltaBytesSec; +void SendPlayerInfoChunk(int pnum,BYTE bCmd,const BYTE * pbSrc,DWORD dwLen); + + +//****************************************************************** +// private +//****************************************************************** +typedef struct TInfo { + struct TInfo * pNext; + int pnum; + BYTE bCmd; + DWORD dwLen; + BYTE bData[1]; +} TInfo; + +// linked list and critical section to protect it +static TInfo * sgpInfoHead; +static CCritSect sgInfoCrit; + +// thread and synchronization objects +static BYTE sgbRunThread = FALSE; +static HANDLE sghThread = INVALID_HANDLE_VALUE; +static HANDLE sghWorkToDoEvent = NULL; +static unsigned sgThreadID; + + +//****************************************************************** +//****************************************************************** +static unsigned __stdcall dthread_proc(void *) { + TInfo * pInfo; + + while (sgbRunThread) { + // sleep until there is work to do + if (! sgpInfoHead && WAIT_FAILED == WaitForSingleObject(sghWorkToDoEvent,INFINITE)) + app_fatal(TEXT("dthread4:\n%s"),strGetLastError()); + + // pull one item off the list + sgInfoCrit.Enter(); + pInfo = sgpInfoHead; + if (sgpInfoHead) sgpInfoHead = sgpInfoHead->pNext; + else ResetEvent(sghWorkToDoEvent); + sgInfoCrit.Leave(); + if (! pInfo) continue; + + // send the item if it still has a valid destination + if (pInfo->pnum != MAX_PLRS) { + SendPlayerInfoChunk( + pInfo->pnum, + pInfo->bCmd, + &pInfo->bData[0], + pInfo->dwLen + ); + } + + // (bytes * 1000 ms/sec) / (bytes/sec) = ms sleep time + app_assert(gdwDeltaBytesSec); + DWORD dwSleepTime = pInfo->dwLen * 1000 / gdwDeltaBytesSec; + dwSleepTime = min(dwSleepTime,1); + + // free item + DiabloFreePtr(pInfo); + + // wait for output queue to empty before sending again + if (dwSleepTime) Sleep(dwSleepTime); + + // pjw.patch2.start + #if CHEATS + static DWORD sdwSkips = 0; + sdwSkips++; + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr == DD_OK) { + char szBuf[16]; + wsprintf(szBuf,"d:%u",sdwSkips); + TextOut(hDC,5,460,szBuf,strlen(szBuf)); + lpDDSPrimary->ReleaseDC(hDC); + } + #endif + // pjw.patch2.end + + } + + return 0; +} + + +//****************************************************************** +//****************************************************************** +void dthread_remove_player(int pnum) { + sgInfoCrit.Enter(); + for (TInfo * pInfo = sgpInfoHead; pInfo; pInfo = pInfo->pNext) + if (pInfo->pnum == pnum) pInfo->pnum = MAX_PLRS; + sgInfoCrit.Leave(); +} + + +//****************************************************************** +//****************************************************************** +void dthread_SendPlayerInfoChunk(int pnum,BYTE bCmd,const BYTE * pbSrc,DWORD dwLen) { +// pjw.patch2.start +// app_assert((DWORD) pnum < MAX_PLRS); + if (gbMaxPlayers == 1) return; +// pjw.patch2.end + app_assert(pnum != myplr); + app_assert(pbSrc); + app_assert(dwLen); + + // create a block of memory for the player info + TInfo * pInfo = (TInfo *) DiabloAllocPtrSig(sizeof(TInfo) + dwLen,'DLTA'); + pInfo->pNext = NULL; + pInfo->pnum = pnum; + pInfo->bCmd = bCmd; + pInfo->dwLen = dwLen; + CopyMemory(pInfo->bData,pbSrc,dwLen); + + // link to tail of list + sgInfoCrit.Enter(); + TInfo ** ppInfo = &sgpInfoHead; + while (*ppInfo) ppInfo = &(*ppInfo)->pNext; + *ppInfo = pInfo; + + // wake up thread if necessary -- inside crit section + SetEvent(sghWorkToDoEvent); + + sgInfoCrit.Leave(); +} + + +//****************************************************************** +//****************************************************************** +void dthread_init() { + // we don't have to send delta info in single + // player mode, so don't bother initializing thread + app_assert(sghThread == INVALID_HANDLE_VALUE); + if (gbMaxPlayers == 1) return; + + // make sure linked list is properly initialized + app_assert(! sgpInfoHead); + + // create synchronization object for thread + app_assert(! sghWorkToDoEvent); + if (NULL == (sghWorkToDoEvent = CreateEvent( + NULL, // security info + TRUE, // manual reset + FALSE, // initial state + NULL // name + ))) app_fatal("dthread:1\n%s",strGetLastError()); + + // create worker thread + sgbRunThread = TRUE; + app_assert(sghThread == INVALID_HANDLE_VALUE); + if (INVALID_HANDLE_VALUE == (sghThread = (HANDLE) _beginthreadex( + NULL, // no security info + 0, // stack size + dthread_proc, // start address + NULL, // argument list + 0, // initial state + &sgThreadID // sgThreadID + ))) app_fatal(TEXT("dthread2:\n%s"),strGetLastError()); +} + + +//****************************************************************** +//****************************************************************** +void dthread_free() { + // if the event was never initialized, the thread cannot be running + if (! sghWorkToDoEvent) return; + + // kill off the loader thread + sgbRunThread = FALSE; + SetEvent(sghWorkToDoEvent); + + // wait til the thread is done + if (sghThread != INVALID_HANDLE_VALUE) { + if (sgThreadID != GetCurrentThreadId()) { + if (WAIT_FAILED == WaitForSingleObject(sghThread,INFINITE)) + app_fatal("dthread3:\n(%s)",strGetLastError()); + CloseHandle(sghThread); + sghThread = INVALID_HANDLE_VALUE; + } + } + + // clean up event + CloseHandle(sghWorkToDoEvent); + sghWorkToDoEvent = NULL; + + // clean up linked list + while (sgpInfoHead) { + TInfo * pNext = sgpInfoHead->pNext; + DiabloFreePtr(sgpInfoHead); + sgpInfoHead = pNext; + } +} diff --git a/DX.CPP b/DX.CPP new file mode 100644 index 0000000..225ba0d --- /dev/null +++ b/DX.CPP @@ -0,0 +1,367 @@ +//****************************************************************** +// dx.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "palette.h" +#include "engine.h" +#include "resource.h" +#include "gendung.h" + + +//****************************************************************** +// extern +//****************************************************************** +void myDebugBreak(); +void ErrorDlg(int nDlgId,DWORD dwErr,const char * pszFile,int nLine); + + +//****************************************************************** +// public +//****************************************************************** +BYTE * gpBuffer; +LPDIRECTDRAW lpDD; // DirectDraw object +LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface +LPDIRECTDRAWSURFACE lpDDSBackBuf; // optional back buffer +LPDIRECTDRAWPALETTE lpDDPal; // DirectDraw palette +BYTE gbForceBackBuf = FALSE; +BYTE gbUseDDEmulation = FALSE; + + +//****************************************************************** +// private +//****************************************************************** +static DWORD sgdwLockCount; +static CCritSect sgDrawCrit; +static BYTE * sgpBackBuf; +static HINSTANCE sghDDlib = NULL; + +#ifndef NDEBUG +static DWORD sgdwLockTbl[256]; +#endif + + +//****************************************************************** +//****************************************************************** +static void init_backbuf() { + app_assert(! gpBuffer); + app_assert(! sgdwLockCount); + app_assert(! sgpBackBuf); + + // can we lock the primary surface? + DDSCAPS caps; + DDSURFACEDESC ddsd; + app_assert(lpDDSPrimary); + HRESULT ddrval = lpDDSPrimary->GetCaps(&caps); + ddraw_assert(ddrval); + app_assert(caps.dwCaps & DDSCAPS_PRIMARYSURFACE); + + // is this a lockable surface? + extern BYTE gbForceBackBuf; + if (! gbForceBackBuf) { + ddsd.dwSize = sizeof(ddsd); + ddrval = lpDDSPrimary->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_WRITEONLY,NULL); + if (ddrval == DD_OK) { + ddrval = lpDDSPrimary->Unlock(NULL); + // pjw.patch1.start.1/13/97 + // commented out -- in NT it is possible to + // lose a video surface while it is locked + // ddraw_assert(ddrval); + // pjw.patch1.end.1/13/97 + + // surface is lockable, just create an offscreen memory buffer + sgpBackBuf = DiabloAllocPtrSig(BUFFERSIZE,'OFFS'); + return; + } + // non-lockable surface? + if (ddrval != DDERR_CANTLOCKSURFACE) + ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); + } + + // create a secondary surface and lock it permanently + ZeroMemory(&ddsd,sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsd.dwHeight = BUFFERY; + ddsd.dwWidth = BUFFERX; + ddsd.lPitch = BUFFERX; + ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); + ddrval = lpDDSPrimary->GetPixelFormat(&ddsd.ddpfPixelFormat); + if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); + ddrval = lpDD->CreateSurface(&ddsd,&lpDDSBackBuf,NULL); + if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); +} + + +//****************************************************************** +//****************************************************************** +static void init_primary() { + DDSURFACEDESC ddsd; + ZeroMemory(&ddsd, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + HRESULT ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL); + if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); +} + + +//****************************************************************** +//****************************************************************** +static HRESULT InDirectDrawCreate( + GUID * lpGUID, + LPDIRECTDRAW * lplpDD, + IUnknown * pUnkOuter +) { + // bind to DirectDrawCreate + typedef HRESULT (WINAPI * DDCREATETYPE)(GUID *,LPDIRECTDRAW *,IUnknown *); + DDCREATETYPE ddcreatefunc = (DDCREATETYPE)SDirectDrawCreate; + if (! ddcreatefunc) ErrorDlg(IDD_DDRAW_DLL_ERR,GetLastError(),__FILE__,__LINE__); + + // call DirectDrawCreate + return ddcreatefunc(lpGUID,lplpDD,pUnkOuter); +} + + +//****************************************************************** +//****************************************************************** +void init_directx(HWND hWnd) { + HRESULT ddrval; + app_assert(! gpBuffer); + app_assert(! sgdwLockCount); + app_assert(! sgpBackBuf); + + SetFocus(hWnd); + ShowWindow(hWnd,SW_SHOWNORMAL); + + extern BYTE gbUseDDEmulation; + GUID * lpGUID = NULL; + if (gbUseDDEmulation) lpGUID = (GUID *) DDCREATE_EMULATIONONLY; + ddrval = InDirectDrawCreate(lpGUID,&lpDD,NULL); + if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); + + #if !ALLOW_WINDOWED_MODE + fullscreen = TRUE; + #endif + + #if ALLOW_WINDOWED_MODE + if (!fullscreen) { + ddrval = lpDD->SetCooperativeLevel(hWnd,DDSCL_NORMAL | DDSCL_ALLOWREBOOT); + if (ddrval == DDERR_EXCLUSIVEMODEALREADYSET) myDebugBreak(); + else if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); + + // turn off "topmost" flag so that we don't stick above debugger + SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + } + else { + #endif + // Get exclusive mode + ddrval = lpDD->SetCooperativeLevel(hWnd,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT); + if (ddrval == DDERR_EXCLUSIVEMODEALREADYSET) myDebugBreak(); + else if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); + + // Set the video mode to 640x480x8 + ddrval = lpDD->SetDisplayMode( 640, 480, 8); + // pjw.patch1.start.1/13/97 + // some notebook computers can't switch resolutions -- but + // we should be able to switch the color depth to 256 ??? + if (ddrval != DD_OK) { + int nWdt = GetSystemMetrics(SM_CXSCREEN); + int nHgt = GetSystemMetrics(SM_CYSCREEN); + ddrval = lpDD->SetDisplayMode(nWdt, nHgt, 8); + } + // pjw.patch1.end.1/13/97 + if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_ERR,ddrval,__FILE__,__LINE__); + + #if ALLOW_WINDOWED_MODE + } + #endif + + init_primary(); + + CreatePalette(); + + // Do not allow gdi batching + GdiSetBatchLimit(1); + + // Get the full offscreen buffer including edges + init_backbuf(); + + // inform STORM library of our DirectDraw objects + BOOL bSuccess = SDrawManualInitialize( + hWnd, // window + lpDD, // direct draw + lpDDSPrimary, // primary + NULL, // secondary + NULL, // system + lpDDSBackBuf, // temporary + lpDDPal, // palette + NULL // gdi palette + ); + app_assert(bSuccess); +} + + +//****************************************************************** +//****************************************************************** +static void lock_buf_priv() { + // don't allow any other threads access to the draw + // buffer while we have it locked + sgDrawCrit.Enter(); + + if (sgpBackBuf) { + gpBuffer = sgpBackBuf; + } + else if (! lpDDSBackBuf) { + // if the back buffer was destroyed by another thread + // it is because it is fataling...give it a chance to + // shut down the system before performing our own fatal + Sleep(20000); + app_fatal("lock_buf_priv"); + } + else if (! sgdwLockCount) { + DDSURFACEDESC ddsd; + ddsd.dwSize = sizeof(ddsd); + HRESULT ddrval = lpDDSBackBuf->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + ddraw_assert(ddrval); + gpBuffer = (BYTE *) ddsd.lpSurface; + app_assert(gpBuffer); + glClipY += (long) gpBuffer; + } + + // increment lock count + sgdwLockCount++; +} + + +//****************************************************************** +//****************************************************************** +void lock_buf(BYTE bFcn) { + // for debugging -- make sure no lock count over/underflow + #ifndef NDEBUG + sgdwLockTbl[bFcn]++; + #endif + + lock_buf_priv(); +} + + +//****************************************************************** +//****************************************************************** +static void unlock_buf_priv() { + if (! sgdwLockCount) app_fatal("draw main unlock error"); + if (! gpBuffer) app_fatal("draw consistency error"); + if (! sgpBackBuf) app_assert(lpDDSBackBuf); + + // decrement lock count + sgdwLockCount--; + + if (! sgdwLockCount) { + glClipY -= (long) gpBuffer; + gpBuffer = NULL; + if (! sgpBackBuf) { + HRESULT ddrval = lpDDSBackBuf->Unlock(NULL); + ddraw_assert(ddrval); + } + } + + sgDrawCrit.Leave(); +} + + +//****************************************************************** +//****************************************************************** +void unlock_buf(BYTE bFcn) { + // for debugging -- make sure no lock count over/underflow + #ifndef NDEBUG + if (! sgdwLockTbl[bFcn]) app_fatal("Draw lock underflow: 0x%x",bFcn); + sgdwLockTbl[bFcn]--; + #endif + + unlock_buf_priv(); +} + + +//****************************************************************** +// THIS FUNCTION MAY BE CALLED FROM ANY THREAD IN THE PROGRAM +// ALL OTHER PUBLIC FUNCTIONS IN THIS MODULE MAY ONLY BE CALLED +// FROM THE MAIN APPLICATION THREAD! +//****************************************************************** +void free_directx() { + if (ghMainWnd) ShowWindow(ghMainWnd,SW_HIDE); + + // tell SDraw that we're about to kill off direct draw + // so it doesn't try to re-use freed objects + SDrawDestroy(); + + sgDrawCrit.Enter(); + if (sgpBackBuf) { + app_assert(! lpDDSBackBuf); + DiabloFreePtr(sgpBackBuf); + } + else if (lpDDSBackBuf) { + lpDDSBackBuf->Release(); + lpDDSBackBuf = NULL; + } + sgdwLockCount = 0; + gpBuffer = NULL; + sgDrawCrit.Leave(); + + if (lpDDSPrimary) { + lpDDSPrimary->Release(); + lpDDSPrimary = NULL; + } + if (lpDDPal) { + lpDDPal->Release(); + lpDDPal = NULL; + } + if (lpDD) { + lpDD->Release(); + lpDD = NULL; + } + +// cannot free library now, still may be in use +// by directX window procedure... +/* + if (sghDDlib) { + FreeLibrary(sghDDlib); + sghDDlib = NULL; + } +*/ +} + + +//****************************************************************** +//****************************************************************** +void ddraw_switch_modes() { + sgDrawCrit.Enter(); + app_assert(ghMainWnd); + + void savecrsr_reset(); + savecrsr_reset(); + + // remove any locks this thread has on buffer + DWORD dwSaveCount = sgdwLockCount; + while (sgdwLockCount) unlock_buf_priv(); + + free_directx(); + force_redraw = FULLDRAW; + init_directx(ghMainWnd); + + // restore locks + while (dwSaveCount--) lock_buf_priv(); + + sgDrawCrit.Leave(); +} + + +//****************************************************************** +//****************************************************************** +void ddraw_reinit() { + ddraw_switch_modes(); +} diff --git a/Diablo.vcproj b/Diablo.vcproj new file mode 100644 index 0000000..f01657b --- /dev/null +++ b/Diablo.vcproj @@ -0,0 +1,3934 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Diablo.vcproj.DESKTOP-B2JDPBG.Justin.user b/Diablo.vcproj.DESKTOP-B2JDPBG.Justin.user new file mode 100644 index 0000000..73b1191 --- /dev/null +++ b/Diablo.vcproj.DESKTOP-B2JDPBG.Justin.user @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Diablo.vcxproj b/Diablo.vcxproj new file mode 100644 index 0000000..e144ad8 --- /dev/null +++ b/Diablo.vcxproj @@ -0,0 +1,529 @@ + + + + + Debug + Win32 + + + FinalFinal + Win32 + + + Release + Win32 + + + Shareware FinalFinal + Win32 + + + Shareware Release + Win32 + + + + 18.0 + {9FCF8C06-5066-4B84-87E9-64036028A392} + + + + Application + v145 + false + + + Application + v145 + false + + + Application + v145 + false + + + Application + v145 + false + + + Application + v145 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>18.0.11512.103 + + + .\SRel\ + .\SRel\ + false + + + .\WinDebug\ + .\WinDebug\ + true + + + .\WinFinal\ + .\WinFinal\ + false + + + .\WinRel\ + .\WinRel\ + false + + + .\SFinal\ + .\SFinal\ + false + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\SRel/Diablo.tlb + + + + MinSpace + OnlyExplicitInline + WIN32;_WINDOWS;_DEBUG;PROGRAM_VERSION=SHAREWARE;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\SRel/Diablo.pch + All + .\SRel/ + .\SRel/ + .\SRel/ + Level3 + true + ProgramDatabase + FastCall + false + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + libcmt.lib;winmm.lib;version.lib;%(AdditionalDependencies) + .\SRel/Diablo.exe + true + false + true + .\SRel/Diablo.pdb + true + .\SRel/Diablo.map + Windows + MachineX86 + false + libc.lib; + + + true + .\SRel/Diablo.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\WinDebug/Diablo.tlb + + + + Disabled + WIN32;_WINDOWS;_DEBUG;PROGRAM_VERSION=RETAIL;DEBUG_MEM;_MULTITEST;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + .\WinDebug/Diablo.pch + All + .\WinDebug/ + .\WinDebug/ + .\WinDebug/ + true + .\WinDebug/ + Level3 + true + EditAndContinue + FastCall + false + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + libcmt.lib;winmm.lib;version.lib;%(AdditionalDependencies) + ./bin/Hellfire.exe + true + false + true + .\WinDebug/Hellfire.pdb + true + .\WinDebug/Hellfire.map + Windows + MachineX86 + false + libc.lib; + false + + + true + .\WinDebug/Diablo.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\WinFinal/Diablo.tlb + + + + MinSpace + OnlyExplicitInline + WIN32;_WINDOWS;NDEBUG;PROGRAM_VERSION=RETAIL;_MULTITEST;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\WinFinal/Diablo.pch + All + .\WinFinal/ + .\WinFinal/ + .\WinFinal/ + Level3 + true + ProgramDatabase + FastCall + false + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + libcmt.lib;winmm.lib;version.lib;%(AdditionalDependencies) + .\WinFinal/Hellfire.exe + true + false + .\WinFinal/Hellfire.pdb + true + .\WinFinal/Hellfire.map + Windows + MachineX86 + false + libc.lib; + + + true + .\WinFinal/Diablo.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\WinRel/Diablo.tlb + + + + MinSpace + OnlyExplicitInline + WIN32;_WINDOWS;_DEBUG;PROGRAM_VERSION=RETAIL;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\WinRel/Diablo.pch + All + .\WinRel/ + .\WinRel/ + .\WinRel/ + true + .\WinRel/ + Level3 + true + ProgramDatabase + FastCall + false + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + libcmt.lib;winmm.lib;version.lib;%(AdditionalDependencies) + .\WinRel/hellfire.exe + true + false + .\WinRel/hellfire.pdb + true + .\WinRel/hellfire.map + Windows + MachineX86 + false + libc.lib; + + + true + .\WinRel/Diablo.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\SFinal/Diablo.tlb + + + + MinSpace + OnlyExplicitInline + WIN32;_WINDOWS;NDEBUG;PROGRAM_VERSION=SHAREWARE;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\SFinal/Diablo.pch + All + .\SFinal/ + .\SFinal/ + .\SFinal/ + Level3 + true + ProgramDatabase + FastCall + false + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + libcmt.lib;winmm.lib;version.lib;%(AdditionalDependencies) + .\SFinal/Diablo.exe + true + false + .\SFinal/Diablo.pdb + true + .\SFinal/Diablo.map + Windows + MachineX86 + false + libc.lib; + + + true + .\SFinal/Diablo.bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {b4e1febb-c3bf-3a04-7233-143b85e3413e} + + + {ab148fbe-6646-95e7-67e4-1c1a8173d447} + + + {43dd7e96-bf0f-4e3b-85f4-1eeafa46583a} + + + {9b22cb13-a1a2-4701-80f8-718408af0348} + + + + + + \ No newline at end of file diff --git a/Diablo.vcxproj.filters b/Diablo.vcxproj.filters new file mode 100644 index 0000000..37b6a69 --- /dev/null +++ b/Diablo.vcxproj.filters @@ -0,0 +1,444 @@ + + + + + {2413cebf-405b-4df3-9d37-e58f6e124cd8} + cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90 + + + {45ef023c-9782-4dbd-a75a-fe9bed767db8} + h;hpp;hxx;hm;inl;fi;fd + + + {d731d199-8659-414d-b22d-53f7bf5718f6} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/Diablo.vcxproj.user b/Diablo.vcxproj.user new file mode 100644 index 0000000..de3123f --- /dev/null +++ b/Diablo.vcxproj.user @@ -0,0 +1,8 @@ + + + + D:\projects\Hellfire\bin + WindowsLocalDebugger + D:\projects\Hellfire\bin\hellfire.exe + + \ No newline at end of file diff --git a/EFFECTS.CPP b/EFFECTS.CPP new file mode 100644 index 0000000..ac5e5c1 --- /dev/null +++ b/EFFECTS.CPP @@ -0,0 +1,595 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Sound sgpSFX +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/EFFECTS.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------**/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "sound.h" +#include "monster.h" +#include "monstdat.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "engine.h" +#include "effects.h" +#include "multi.h" + + +//****************************************************************** +// debugging +//****************************************************************** +#define DEBUG_STREAM 1 // 0 in final +#ifdef NDEBUG +#undef DEBUG_STREAM +#define DEBUG_STREAM 0 +#endif + + +//****************************************************************** +// extern +//****************************************************************** +void snd_update(BOOL bStopAll); + + +//****************************************************************** +// public +//****************************************************************** +int sfxdelay, sfxdnum; + + +//****************************************************************** +// private +//****************************************************************** +// sound constants +#define sfx_STREAM 0x01 // streaming sound effect +#define sfx_ALLOWMULTIPLE 0x02 // only valid for non-streamed sounds +#define sfx_MENU 0x04 // menu sound +#define sfx_MONK 0x08 // only needed for the monk +#define sfx_ROGUE 0x10 // only needed for the rogue +#define sfx_WARRIOR 0x20 // only needed for the warrior +#define sfx_SORCEROR 0x40 // only needed for the sorceror +#define sfx_BARD 0x10 // reuse the rogue +#define sfx_BARBARIAN 0x20 // reuse the warrior +#define sfx_DEBUG_STREAM 0x80 // for debugging when streaming is off + +#define sfx_CHAR_MASK (sfx_MONK|sfx_ROGUE|sfx_WARRIOR|sfx_SORCEROR) + +// sound structure +#pragma pack(push,1) +typedef struct TSFX { + BYTE bFlags; + char * pszName; + TSnd * pSnd; +} TSFX; +#pragma pack(pop) + + +// build sound data table +#define EFFECTS_DATA +#include "effects.h" +#undef EFFECTS_DATA +#define NUM_SFX (sizeof(sgSFX) / sizeof(sgSFX[0])) + + +static HSFILE sghStream = NULL; +static TSFX * sgpStreamSFX = NULL; + + +//****************************************************************** +//****************************************************************** +BOOL effect_is_playing(int nSFX) { + app_assert(nSFX < NUM_SFX); + TSFX * pSFX = &sgSFX[nSFX]; + + // if a sound buffer is allocated, then just return play status + if (pSFX->pSnd) return snd_playing(pSFX->pSnd); + + // if this is a streamed sound, is it the current stream? + if (pSFX->bFlags & sfx_STREAM) + return (pSFX == sgpStreamSFX); + + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +#if DEBUG_STREAM +static void debug_stream_update(BOOL bStop) { + // if sound isn't initialized, we don't have to do any work + if (! gbSndInited) return; + + TSFX * pSFX = sgSFX; + for (DWORD d = NUM_SFX; d--; pSFX++) { + if (! (pSFX->bFlags & sfx_DEBUG_STREAM)) continue; + if (! pSFX->pSnd) continue; + if (!bStop && snd_playing(pSFX->pSnd)) continue; + pSFX->bFlags &= ~sfx_DEBUG_STREAM; + snd_free_snd(pSFX->pSnd); + pSFX->pSnd = NULL; + } +} +#endif + + +//****************************************************************** +//****************************************************************** +void stream_stop() { + if (sghStream) { + SFileDdaEnd(sghStream); + SFileCloseFile(sghStream); + sghStream = NULL; + sgpStreamSFX = NULL; + } + + #if DEBUG_STREAM + debug_stream_update(TRUE); + #endif +} + + +//****************************************************************** +//****************************************************************** +#if DEBUG_STREAM +static void debug_stream(TSFX * pSFX,LONG lVolume,LONG lPan) { + // OK, the streaming stuff failed, just load + // it into memory and play it, then free it + if (pSFX->pSnd) return; + if (NULL == (pSFX->pSnd = snd_load_snd(pSFX->pszName))) + return; + pSFX->bFlags |= sfx_DEBUG_STREAM; + snd_play_snd(pSFX->pSnd,lVolume,lPan); +} +#endif + + +//****************************************************************** +//****************************************************************** +static void stream_play(TSFX * pSFX,LONG lVolume,LONG lPan) { + app_assert(pSFX); + app_assert(pSFX->bFlags & sfx_STREAM); + stream_stop(); + + // adjust volume by global volume amount + lVolume += sound_volume(VOLUME_READ); + if (lVolume < VOLUME_MIN) return; + else if (lVolume > VOLUME_MAX) lVolume = VOLUME_MAX; + + // open stream file + #ifndef NDEBUG + SFileEnableDirectAccess(0); + #endif + BOOL bResult = SFileOpenFile(pSFX->pszName,&sghStream); + #ifndef NDEBUG + SFileEnableDirectAccess(1); + #endif + if (! bResult) { + sghStream = NULL; + #if DEBUG_STREAM + debug_stream(pSFX,lVolume,lPan); + #endif + return; + } + + // play it + if (! SFileDdaBeginEx(sghStream,DDA_BUF_SIZE,0,0,lVolume,lPan,0)) { + stream_stop(); + #if DEBUG_STREAM + debug_stream(pSFX,lVolume,lPan); + #endif + return; + } + + sgpStreamSFX = pSFX; +} + + +//****************************************************************** +//****************************************************************** +static void stream_update() { + // is there a stream playing? + if (! sghStream) return; + + // get current stream position + DWORD nPosition,nMaxPosition; + if (! SFileDdaGetPos(sghStream,&nPosition,&nMaxPosition)) + return; + + // if it hasn't finished playing, let it run + if (nPosition < nMaxPosition) + return; + + stream_stop(); +} + + +//****************************************************************** +//****************************************************************** +static void sfx_stop() { + TSFX * pSFX = sgSFX; + for (DWORD d = NUM_SFX; d--; pSFX++) { + if (! pSFX->pSnd) continue; + snd_stop_snd(pSFX->pSnd); + } +} + + +//****************************************************************** +//****************************************************************** +void InitMonsterSND(int monst) { + + // if sound isn't initialized, we don't have to do any work + if (! gbSndInited) return; + + static const char sndletter[MAX_MS + 1] = "ahds"; + int mtype = Monsters[monst].mtype; + for (int snd = 0; snd < MAX_MS; snd++) { + // if this is the "special" sound, and monster doesn't have + // a special sound then we don't need to load the sound + if (sndletter[snd] == 's' && !monsterdata[mtype].snd_special) + continue; + + for (int i = 0; i < 2; i++) { + // derive path for sound effect + char szTemp[MAX_PATH]; + sprintf(szTemp,monsterdata[mtype].sndfile,sndletter[snd],i+1); + char * pszBuf = (char *) DiabloAllocPtrSig(strlen(szTemp) + 1,'SNDN'); + strcpy(pszBuf,szTemp); + + // load sound effect + // leave ptr active + TSnd * pSnd = snd_load_snd(pszBuf); + Monsters[monst].Snds[snd].effect[i] = pSnd; + + // if the sound was never allocated, free the file name buffer + if (! pSnd) DiabloFreePtr(pszBuf); + } + } +} + + +//****************************************************************** +//****************************************************************** +void FreeMonsterSnd() { + for (int monst = 0;monst < nummtypes; monst++) { + int mtype = Monsters[monst].mtype; + for (int snd = 0; snd < MAX_MS; snd++) { + for (int i = 0; i < 2; i++) { + TSnd * pSnd = Monsters[monst].Snds[snd].effect[i]; + if (! pSnd) continue; + Monsters[monst].Snds[snd].effect[i] = NULL; + + // save ptr to sound effect name + char * pszBuf = (char *) pSnd->pszName; + pSnd->pszName = NULL; + + // free sound + snd_free_snd(pSnd); + + // free sound name + DiabloFreePtr(pszBuf); + } + } + } +} + + +//****************************************************************** +//****************************************************************** +static BOOL calc_snd_position(int x,int y,LONG * plVolume,LONG * plPan) { + // calc position relative to player + x -= plr[myplr]._px; + y -= plr[myplr]._py; + + // calc pan + *plPan = (x - y) * 256; + if (abs(*plPan) > 6400) return FALSE; + + // calc volume + *plVolume = max(abs(x),abs(y)) * 64; + if (*plVolume >= 6400) return FALSE; + *plVolume = - *plVolume; + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static void PlaySFX_priv(TSFX * pSFX,BOOL loc,int x, int y) { + + // Don't play sfx if in just onto level + if ((plr[myplr].pLvlLoad) && (gbMaxPlayers != 1)) return; + + // if sound isn't initialized, we don't have to do any work + if (! gbSndInited) return; + if (! gbSoundOn) return; + + // this is the lowest level location to intercept game sound + // effects. If we are in some buffering mode (either because + // we're receiving or parsing information prior to starting a + // level) then we don't want to play any sound effects because + // the player is not in a position to interact with anything yet. + if (gbBufferMsgs != BUFFER_OFF) return; + + // check for sound buffer duplication + if (pSFX->bFlags & sfx_STREAM) { + // streams sounds are always allowed to play + // as they will shut off any previous stream + } + else if (pSFX->bFlags & sfx_ALLOWMULTIPLE) { + // we allow this sound to use multiple buffers + } + else if (pSFX->pSnd && snd_playing(pSFX->pSnd)) { + // this sound is already playing -- skip + return; + } + + // calculate volume and panning, and clip sound if necessary + LONG lPan = 0; + LONG lVolume = 0; + if (loc && !calc_snd_position(x,y,&lVolume,&lPan)) + return; + + if (pSFX->bFlags & sfx_STREAM) { + stream_play(pSFX,lVolume,lPan); + } + else { + if (! pSFX->pSnd) pSFX->pSnd = snd_load_snd(pSFX->pszName); + if (pSFX->pSnd) snd_play_snd(pSFX->pSnd,lVolume,lPan); + } +} + + +//****************************************************************** +// Plays a monster sound effect +// i = monster# to player for +// mode = which sfx to play (attack, hit, death, etc) +//****************************************************************** +void PlayEffect(int i, int mode) { + + // Don't play sfx if in just onto level + if (plr[myplr].pLvlLoad) return; + + // choose which of the two rnd sfx to play + // always perform random() function even if + // sound is off so that random generators stay synced + int nr = random(164, 2); + + // return *after* the random call so that all systems are synced + if (! gbSndInited) return; + if (! gbSoundOn) return; + + // this is the lowest level location to intercept game sound + // effects. If we are in some buffering mode (either because + // we're receiving or parsing information prior to starting a + // level) then we don't want to play any sound effects because + // the player is not in a position to interact with anything yet. + if (gbBufferMsgs != BUFFER_OFF) return; + + // monster type index (0 - nummtypes) + int mi = monster[i]._mMTidx; + + // validate sound effect + TSnd * pSnd = Monsters[mi].Snds[mode].effect[nr]; + if (! pSnd) { + #ifndef NDEBUG // don't fatal out in release version + app_fatal("Monster sound problem\n:%s playing %i", Monsters[mi].MData->mName, mode); + #endif + return; + } + + // don't allow duplication multiple monster effects + if (snd_playing(pSnd)) return; + + // calculate volume and panning, and clip sound if necessary + LONG lPan; + LONG lVolume; + if (!calc_snd_position(monster[i]._mx,monster[i]._my,&lVolume,&lPan)) + return; + + snd_play_snd(pSnd,lVolume,lPan); +} + + +//****************************************************************** +// Determine random sfx to play +//****************************************************************** +static int RndSFX(int psfx) { + int nRand; + if (psfx == PS_WARR69) nRand = 2; + else if (psfx == PS_WARR14) nRand = 3; + else if (psfx == PS_WARR15) nRand = 3; + else if (psfx == PS_WARR16) nRand = 3; +#if !IS_VERSION(SHAREWARE) + else if (psfx == PS_MAGE69) nRand = 2; + else if (psfx == PS_ROGUE69) nRand = 2; + else if (psfx == PS_MONK69) nRand = 2; + else if (psfx == PS_BARD69) nRand = 2; +#endif + else if (psfx == PS_SWING) nRand = 2; + else if (psfx == LS_ACID) nRand = 2; + else if (psfx == IS_FMAG) nRand = 2; + else if (psfx == IS_MAGIC) nRand = 2; + else if (psfx == IS_BHIT) nRand = 2; +// else if (psfx == PS_WALK1) nRand = 4; +#if !IS_VERSION(SHAREWARE) + else if (psfx == PS_WARR2) nRand = 3; +#endif + else return psfx; + + return psfx + random(165,nRand); +} + + +//****************************************************************** +// If player has hit something, play the hit sfx from the player +// (sword hitting metal, bone, etc) +//****************************************************************** +void PlaySFX(int psfx) { + psfx = RndSFX(psfx); + app_assert(psfx < NUM_SFX); + PlaySFX_priv(&sgSFX[psfx],FALSE,0,0); +} + + +//****************************************************************** +// Like PlaySFX, but with a dungeon location +//****************************************************************** +void PlaySfxLoc(int psfx, int x, int y) { + psfx = RndSFX(psfx); + app_assert(psfx < NUM_SFX); + + // don't let walk sounds get clipped! + if (psfx >= PS_WALK1 && psfx <= PS_WALK4) { + TSnd * pSnd = sgSFX[psfx].pSnd; + if (pSnd) pSnd->dwLastPlayTime = 0; + } + + PlaySFX_priv(&sgSFX[psfx],TRUE,x,y); +} + + +//****************************************************************** +//****************************************************************** +void sound_stop() { + snd_update(TRUE); + stream_stop(); + sfx_stop(); + + // stop all monster sounds + int mi, mode, nr; + for (mi = 0; mi < nummtypes; mi++) { + for (mode = 0; mode < MAX_MS; mode++) { + for (nr = 0; nr < 2; nr++) { + TSnd * pSnd = Monsters[mi].Snds[mode].effect[nr]; + snd_stop_snd(pSnd); + } + } + } +} + + +//****************************************************************** +//****************************************************************** +void sound_update() { + // if sound isn't initialized, we don't have to do any work + if (! gbSndInited) return; + + snd_update(FALSE); + stream_update(); + + #if DEBUG_STREAM + debug_stream_update(FALSE); + #endif +} + + +//****************************************************************** +//****************************************************************** +void sound_exit() { + sound_stop(); + for (DWORD d = 0; d < NUM_SFX; d++) { + if (! sgSFX[d].pSnd) continue; + + #if DEBUG_STREAM + sgSFX[d].bFlags &= ~sfx_DEBUG_STREAM; + #endif + + snd_free_snd(sgSFX[d].pSnd); + sgSFX[d].pSnd = NULL; + } +} + + +//****************************************************************** +//****************************************************************** +static void priv_sound_init(BYTE bLoadMask) { + // if sound manager isn't initialized, we don't have to do any work + if (! gbSndInited) return; + + // save character load flags + BYTE bCharMask = bLoadMask & sfx_CHAR_MASK; + + // load mask excludes character mask + bLoadMask ^= bCharMask; + + // load sounds + for (DWORD d = 0; d < NUM_SFX; d++) { + // is it already loaded? + if (sgSFX[d].pSnd) continue; + + // don't load streamed sounds + if (sgSFX[d].bFlags & sfx_STREAM) continue; + + // if load mask is non-zero, only load sound effect if + // it has a flag which is set in the load mask + if (bLoadMask && !(sgSFX[d].bFlags & bLoadMask)) continue; + + // is this a character sound that we don't need? + if (sgSFX[d].bFlags & sfx_CHAR_MASK) { + if (! (sgSFX[d].bFlags & bCharMask)) + continue; + } + + // load it + sgSFX[d].pSnd = snd_load_snd(sgSFX[d].pszName); + } +} + + +//****************************************************************** +//****************************************************************** +void sound_init() { + BYTE bLoadMask = 0; + if (gbMaxPlayers > 1) + bLoadMask = sfx_CHAR_MASK; + else if (plr[myplr]._pClass == CLASS_WARRIOR) + bLoadMask = sfx_WARRIOR; + else if (plr[myplr]._pClass == CLASS_ROGUE) + bLoadMask = sfx_ROGUE; + else if (plr[myplr]._pClass == CLASS_SORCEROR) + bLoadMask = sfx_SORCEROR; + else if (plr[myplr]._pClass == CLASS_MONK) + bLoadMask = sfx_MONK; + else if (plr[myplr]._pClass == CLASS_BARD) + bLoadMask = sfx_BARD; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) + bLoadMask = sfx_BARBARIAN; + else + app_fatal("effects:1"); + priv_sound_init(bLoadMask); +} + + +//****************************************************************** +//****************************************************************** +void menusnd_init() { + priv_sound_init(sfx_MENU); +} + + +//****************************************************************** +//****************************************************************** +void CALLBACK menusnd_play(LPCSTR pszName) { + // sound initialized? + if (! gbSndInited) return; + if (! gbSoundOn) return; + + for (DWORD d = 0; d < NUM_SFX; d++) { + if (_stricmp(sgSFX[d].pszName,pszName)) continue; + if (! sgSFX[d].pSnd) continue; + if (snd_playing(sgSFX[d].pSnd)) break; + snd_play_snd(sgSFX[d].pSnd,0,0); + break; + } +} + diff --git a/EFFECTS.H b/EFFECTS.H new file mode 100644 index 0000000..67afb36 --- /dev/null +++ b/EFFECTS.H @@ -0,0 +1,1440 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/EFFECTS.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +//****************************************************************** +// Defines +//****************************************************************** +// monster sfx +#define MS_ATTACK 0 +#define MS_GOTHIT 1 +#define MS_DEATH 2 +#define MS_SATTACK 3 +#define MAX_MS 4 + + +//****************************************************************** +// externs +//****************************************************************** +extern int sfxdelay, sfxdnum; + + +//****************************************************************** +// public functions +//****************************************************************** +void sound_init(); +void sound_exit(); +void sound_update(); +void sound_stop(); +void stream_stop(); + +void PlrTryHitSnd(); +void PlaySFX(int); +void PlaySfxLoc(int psfx, int x, int y); + +void InitMonsterSND(); +void PlayEffect(int, int); +void FreeMonsterSnd(); + + +//****************************************************************** +// sound effects data +//****************************************************************** +#ifdef EFFECTS_DATA + #define SFX(a,b,c) { a, b, NULL } + #define rSFX(a,b,c) { a | sfx_ROGUE, b, NULL } + #define wSFX(a,b,c) { a | sfx_WARRIOR, b, NULL } + #define sSFX(a,b,c) { a | sfx_SORCEROR, b, NULL } + #define mSFX(a,b,c) { a | sfx_MONK, b, NULL } +#else + #define SFX(a,b,c) c + #define rSFX(a,b,c) c + #define wSFX(a,b,c) c + #define sSFX(a,b,c) c + #define mSFX(a,b,c) c +#endif + + +// build data table or header enum +#ifdef EFFECTS_DATA +static TSFX sgSFX[] = { +#else +enum { +#endif +// NOTE NOTE NOTE NOTE NOTE +// do not put any sound effects before these effects +// DirectSound loads sound effects into hardware on +// a first-come, first-served basis, so we want the +// most common sounds to come first so they end up +// in hardware. + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Walk1.wav", PS_WALK1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Walk2.wav", PS_WALK2), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Walk3.wav", PS_WALK3), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Walk4.wav", PS_WALK4), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\BFire.wav", PS_BFIRE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Fmag.wav", PS_FMAG), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Tmag.wav", PS_TMAG), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Lghit.wav", PS_LGHIT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Lghit1.wav", PS_LGHIT1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Swing.wav", PS_SWING), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Swing2.wav", PS_SWING2), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Dead.wav", PS_DEAD), + +// SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\NewBFire.wav", PS_NEW_BFIRE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Sting1.wav", PS_NEW_BFIRE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\FBallBow.wav", PS_FB_BFIRE), + // Quests SoundEffects + SFX(sfx_STREAM, "Sfx\\Misc\\Questdon.wav", IS_QUESTDN), + + // Item SoundEffects + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Armrfkd.wav", IS_ARMRFKD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Barlfire.wav", IS_BARLFIRE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Barrel.wav", IS_BARREL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\PodPop8.wav", IS_PODFIRE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\PodPop5.wav", IS_POD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\UrnPop3.wav", IS_URNFIRE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\UrnPop2.wav", IS_URN), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Bhit.wav", IS_BHIT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Bhit1.wav", IS_BHIT1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Chest.wav", IS_CHEST), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Doorclos.wav", IS_DOORCLOS), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Dooropen.wav", IS_DOOROPEN), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipanvl.wav", IS_FANVL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipaxe.wav", IS_FAXE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipblst.wav", IS_FBLST), // ear + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipbody.wav", IS_FBODY), // ear + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipbook.wav", IS_FBOOK), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipbow.wav", IS_FBOW), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipcap.wav", IS_FCAP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipharm.wav", IS_FHARM), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Fliplarm.wav", IS_FLARM), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipmag.wav", IS_FMAG), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipmag1.wav", IS_FMAG1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipmush.wav", IS_FMUSH), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flippot.wav", IS_FPOT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipring.wav", IS_FRING), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Fliprock.wav", IS_FROCK), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipscrl.wav", IS_FSCRL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipshld.wav", IS_FSHLD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipsign.wav", IS_FSIGN), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipstaf.wav", IS_FSTAF), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Flipswor.wav", IS_FSWOR), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Gold.wav", IS_GOLD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Hlmtfkd.wav", IS_HLMTFKD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invanvl.wav", IS_IANVL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invaxe.wav", IS_IAXE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invblst.wav", IS_IBLST), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invbody.wav", IS_IBODY), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invbook.wav", IS_IBOOK), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invbow.wav", IS_IBOW), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invcap.wav", IS_ICAP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invgrab.wav", IS_IGRAB), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invharm.wav", IS_IHARM), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invlarm.wav", IS_ILARM), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invmush.wav", IS_IMUSH), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invpot.wav", IS_IPOT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invring.wav", IS_IRING), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invrock.wav", IS_IROCK), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invscrol.wav", IS_ISCROL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invshiel.wav", IS_ISHIEL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invsign.wav", IS_ISIGN), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invstaf.wav", IS_ISTAF), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Invsword.wav", IS_ISWORD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Lever.wav", IS_LEVER), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Magic.wav", IS_MAGIC), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Magic1.wav", IS_MAGIC1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Readbook.wav", IS_RBOOK), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Sarc.wav", IS_SARC), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Shielfkd.wav", IS_SHLDFKD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Swrdfkd.wav", IS_SWRDFKD), + SFX(sfx_MENU, "Sfx\\Items\\Titlemov.wav", IS_TITLEMOV), + SFX(sfx_MENU, "Sfx\\Items\\Titlslct.wav", IS_TITLSLCT), + SFX(sfx_MENU, "Sfx\\Misc\\blank.wav", SFX_SILENCE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Trap.wav", IS_TRAP), + + // Cast + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast1.wav", IS_CAST1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast10.wav", IS_CAST10), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast12.wav", IS_CAST12), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast2.wav", IS_CAST2), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast3.wav", IS_CAST3), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast4.wav", IS_CAST4), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast5.wav", IS_CAST5), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast6.wav", IS_CAST6), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast7.wav", IS_CAST7), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast8.wav", IS_CAST8), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cast9.wav", IS_CAST9), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Healing.wav", LS_HEALING), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Repair.wav", IS_REPAIR), + + // Launch and impact sounds + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Acids1.wav", LS_ACID), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Acids2.wav", LS_ACIDS), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Apoc.wav", LS_APOC), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Arrowall.wav", LS_ARROWALL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Bldboil.wav", LS_BLODBOIL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Blodstar.wav", LS_BLODSTAR), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Blsimpt.wav", LS_BLSIMPT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Bonesp.wav", LS_BONESP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Bsimpct.wav", LS_BSIMPCT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Caldron.wav", LS_CALDRON), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Cbolt.wav", LS_CBOLT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Chltning.wav", LS_CHLTNING), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\DSerp.wav", LS_DSERP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Elecimp1.wav", LS_ELECIMP1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Elementl.wav", LS_ELEMENTL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Ethereal.wav", LS_ETHEREAL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Fball.wav", LS_FBALL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Fbolt1.wav", LS_FBOLT1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Fbolt2.wav", LS_FBOLT2), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Firimp1.wav", LS_FIRIMP1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Firimp2.wav", LS_FIRIMP2), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Flamwave.wav", LS_FLAMWAVE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Flash.wav", LS_FLASH), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Fountain.wav", LS_FOUNTAIN), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Golum.wav", LS_GOLUM), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Golumded.wav", LS_GOLUMDED), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Gshrine.wav", LS_GSHRINE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Guard.wav", LS_GUARD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Grdlanch.wav", LS_GUARDLAN), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Holybolt.wav", LS_HOLYBOLT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Hyper.wav", LS_HYPER), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Infravis.wav", LS_INFRAVIS), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Invisibl.wav", LS_INVISIBL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Invpot.wav", LS_INVPOT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Lning1.wav", LS_LNING1), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Ltning.wav", LS_LTNING), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Mshield.wav", LS_MSHIELD), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\NestXpld.wav", LS_BIGEXP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Nova.wav", LS_NOVA), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Portal.wav", LS_PORTAL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Puddle.wav", LS_PUDDLE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Resur.wav", LS_RESUR), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Scurse.wav", LS_SCURSE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Scurimp.wav", LS_SCURIMP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Sentinel.wav", LS_SENTINEL), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Shatter.wav", LS_SHATTER), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Soulfire.wav", LS_SOULFIRE), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Spoutlop.wav", LS_SPOUTLOP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Spoutstr.wav", LS_SPOUTSTR), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Storm.wav", LS_STORM), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Trapdis.wav", LS_TRAPDIS), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Teleport.wav", LS_TELEPORT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Vtheft.wav", LS_VTHEFT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Wallloop.wav", LS_WALLLOOP), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\Wallstrt.wav", LS_WALLSTRT), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Misc\\LMag.wav", LS_LMAG), + + // town sounds +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid01.wav", TSFX_BMAID1), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid02.wav", TSFX_BMAID2), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid03.wav", TSFX_BMAID3), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid04.wav", TSFX_BMAID4), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid05.wav", TSFX_BMAID5), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid06.wav", TSFX_BMAID6), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid07.wav", TSFX_BMAID7), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid08.wav", TSFX_BMAID8), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid09.wav", TSFX_BMAID9), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid10.wav", TSFX_BMAID10), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid11.wav", TSFX_BMAID11), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid12.wav", TSFX_BMAID12), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid13.wav", TSFX_BMAID13), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid14.wav", TSFX_BMAID14), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid15.wav", TSFX_BMAID15), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid16.wav", TSFX_BMAID16), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid17.wav", TSFX_BMAID17), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid18.wav", TSFX_BMAID18), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid19.wav", TSFX_BMAID19), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid20.wav", TSFX_BMAID20), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid21.wav", TSFX_BMAID21), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid22.wav", TSFX_BMAID22), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid23.wav", TSFX_BMAID23), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid24.wav", TSFX_BMAID24), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid25.wav", TSFX_BMAID25), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid26.wav", TSFX_BMAID26), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid27.wav", TSFX_BMAID27), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid28.wav", TSFX_BMAID28), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid29.wav", TSFX_BMAID29), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid30.wav", TSFX_BMAID30), +#endif + // greeting -- good day... + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid31.wav", TSFX_BMAID31), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid32.wav", TSFX_BMAID32), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid33.wav", TSFX_BMAID33), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid34.wav", TSFX_BMAID34), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid35.wav", TSFX_BMAID35), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid36.wav", TSFX_BMAID36), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid37.wav", TSFX_BMAID37), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid38.wav", TSFX_BMAID38), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid39.wav", TSFX_BMAID39), + SFX(sfx_STREAM, "Sfx\\Towners\\Bmaid40.wav", TSFX_BMAID40), +#endif + + // BlackSmith +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith01.wav", TSFX_SMITH1), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith02.wav", TSFX_SMITH2), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith03.wav", TSFX_SMITH3), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith04.wav", TSFX_SMITH4), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith05.wav", TSFX_SMITH5), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith06.wav", TSFX_SMITH6), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith07.wav", TSFX_SMITH7), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith08.wav", TSFX_SMITH8), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith09.wav", TSFX_SMITH9), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith10.wav", TSFX_SMITH10), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith11.wav", TSFX_SMITH11), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith12.wav", TSFX_SMITH12), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith13.wav", TSFX_SMITH13), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith14.wav", TSFX_SMITH14), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith15.wav", TSFX_SMITH15), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith16.wav", TSFX_SMITH16), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith17.wav", TSFX_SMITH17), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith18.wav", TSFX_SMITH18), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith19.wav", TSFX_SMITH19), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith20.wav", TSFX_SMITH20), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith21.wav", TSFX_SMITH21), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith22.wav", TSFX_SMITH22), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith23.wav", TSFX_SMITH23), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith24.wav", TSFX_SMITH24), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith25.wav", TSFX_SMITH25), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith26.wav", TSFX_SMITH26), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith27.wav", TSFX_SMITH27), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith28.wav", TSFX_SMITH28), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith29.wav", TSFX_SMITH29), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith30.wav", TSFX_SMITH30), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith31.wav", TSFX_SMITH31), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith32.wav", TSFX_SMITH32), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith33.wav", TSFX_SMITH33), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith34.wav", TSFX_SMITH34), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith35.wav", TSFX_SMITH35), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith36.wav", TSFX_SMITH36), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith37.wav", TSFX_SMITH37), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith38.wav", TSFX_SMITH38), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith39.wav", TSFX_SMITH39), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith40.wav", TSFX_SMITH40), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith41.wav", TSFX_SMITH41), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith42.wav", TSFX_SMITH42), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith43.wav", TSFX_SMITH43), +#endif + // greeting -- well, what can I do for you? + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith44.wav", TSFX_SMITH44), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith45.wav", TSFX_SMITH45), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith46.wav", TSFX_SMITH46), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith47.wav", TSFX_SMITH47), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith48.wav", TSFX_SMITH48), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith49.wav", TSFX_SMITH49), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith50.wav", TSFX_SMITH50), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith51.wav", TSFX_SMITH51), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith52.wav", TSFX_SMITH52), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith53.wav", TSFX_SMITH53), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith54.wav", TSFX_SMITH54), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith55.wav", TSFX_SMITH55), + SFX(sfx_STREAM, "Sfx\\Towners\\Bsmith56.wav", TSFX_SMITH56), +#endif + + SFX(0, "Sfx\\Towners\\Cow1.wav", TSFX_COW1), + SFX(0, "Sfx\\Towners\\Cow2.wav", TSFX_COW2), + +#if 0 + SFX(sfx_STREAM, "Sfx\\Towners\\Cow3.wav", TSFX_COW3), + SFX(sfx_STREAM, "Sfx\\Towners\\Cow4.wav", TSFX_COW4), + SFX(sfx_STREAM, "Sfx\\Towners\\Cow5.wav", TSFX_COW5), + SFX(sfx_STREAM, "Sfx\\Towners\\Cow6.wav", TSFX_COW6), +#endif + SFX(sfx_STREAM, "Sfx\\Towners\\Cow7.wav", TSFX_COW7), + SFX(sfx_STREAM, "Sfx\\Towners\\Cow8.wav", TSFX_COW8), + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Deadguy2.wav", TSFX_DEADGUY), +#endif + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk01.wav", TSFX_DRUNK1), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk02.wav", TSFX_DRUNK2), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk03.wav", TSFX_DRUNK3), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk04.wav", TSFX_DRUNK4), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk05.wav", TSFX_DRUNK5), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk06.wav", TSFX_DRUNK6), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk07.wav", TSFX_DRUNK7), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk08.wav", TSFX_DRUNK8), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk09.wav", TSFX_DRUNK9), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk10.wav", TSFX_DRUNK10), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk11.wav", TSFX_DRUNK11), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk12.wav", TSFX_DRUNK12), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk13.wav", TSFX_DRUNK13), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk14.wav", TSFX_DRUNK14), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk15.wav", TSFX_DRUNK15), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk16.wav", TSFX_DRUNK16), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk17.wav", TSFX_DRUNK17), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk18.wav", TSFX_DRUNK18), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk19.wav", TSFX_DRUNK19), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk20.wav", TSFX_DRUNK20), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk21.wav", TSFX_DRUNK21), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk22.wav", TSFX_DRUNK22), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk23.wav", TSFX_DRUNK23), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk24.wav", TSFX_DRUNK24), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk25.wav", TSFX_DRUNK25), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk26.wav", TSFX_DRUNK26), +#endif + // greeting -- can't a fellow drink in peace? + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk27.wav", TSFX_DRUNK27), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk28.wav", TSFX_DRUNK28), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk29.wav", TSFX_DRUNK29), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk30.wav", TSFX_DRUNK30), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk31.wav", TSFX_DRUNK31), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk32.wav", TSFX_DRUNK32), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk33.wav", TSFX_DRUNK33), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk34.wav", TSFX_DRUNK34), + SFX(sfx_STREAM, "Sfx\\Towners\\Drunk35.wav", TSFX_DRUNK35), +#endif + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Healer01.wav", TSFX_HEALER1), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer02.wav", TSFX_HEALER2), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer03.wav", TSFX_HEALER3), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer04.wav", TSFX_HEALER4), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer05.wav", TSFX_HEALER5), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer06.wav", TSFX_HEALER6), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer07.wav", TSFX_HEALER7), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer08.wav", TSFX_HEALER8), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer09.wav", TSFX_HEALER9), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer10.wav", TSFX_HEALER10), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer11.wav", TSFX_HEALER11), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer12.wav", TSFX_HEALER12), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer13.wav", TSFX_HEALER13), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer14.wav", TSFX_HEALER14), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer15.wav", TSFX_HEALER15), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer16.wav", TSFX_HEALER16), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer17.wav", TSFX_HEALER17), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer18.wav", TSFX_HEALER18), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer19.wav", TSFX_HEALER19), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer20.wav", TSFX_HEALER20), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer21.wav", TSFX_HEALER21), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer22.wav", TSFX_HEALER22), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer23.wav", TSFX_HEALER23), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer24.wav", TSFX_HEALER24), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer25.wav", TSFX_HEALER25), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer26.wav", TSFX_HEALER26), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer27.wav", TSFX_HEALER27), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer28.wav", TSFX_HEALER28), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer29.wav", TSFX_HEALER29), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer30.wav", TSFX_HEALER30), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer31.wav", TSFX_HEALER31), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer32.wav", TSFX_HEALER32), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer33.wav", TSFX_HEALER33), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer34.wav", TSFX_HEALER34), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer35.wav", TSFX_HEALER35), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer36.wav", TSFX_HEALER36), +#endif + // greeting -- what ails you my friend? + SFX(sfx_STREAM, "Sfx\\Towners\\Healer37.wav", TSFX_HEALER37), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Healer38.wav", TSFX_HEALER38), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer39.wav", TSFX_HEALER39), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer40.wav", TSFX_HEALER40), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer41.wav", TSFX_HEALER41), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer42.wav", TSFX_HEALER42), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer43.wav", TSFX_HEALER43), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer44.wav", TSFX_HEALER44), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer45.wav", TSFX_HEALER45), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer46.wav", TSFX_HEALER46), + SFX(sfx_STREAM, "Sfx\\Towners\\Healer47.wav", TSFX_HEALER47), +#endif + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy01.wav", TSFX_PEGBOY1), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy02.wav", TSFX_PEGBOY2), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy03.wav", TSFX_PEGBOY3), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy04.wav", TSFX_PEGBOY4), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy05.wav", TSFX_PEGBOY5), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy06.wav", TSFX_PEGBOY6), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy07.wav", TSFX_PEGBOY7), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy08.wav", TSFX_PEGBOY8), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy09.wav", TSFX_PEGBOY9), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy10.wav", TSFX_PEGBOY10), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy11.wav", TSFX_PEGBOY11), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy12.wav", TSFX_PEGBOY12), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy13.wav", TSFX_PEGBOY13), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy14.wav", TSFX_PEGBOY14), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy15.wav", TSFX_PEGBOY15), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy16.wav", TSFX_PEGBOY16), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy17.wav", TSFX_PEGBOY17), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy18.wav", TSFX_PEGBOY18), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy19.wav", TSFX_PEGBOY19), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy20.wav", TSFX_PEGBOY20), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy21.wav", TSFX_PEGBOY21), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy22.wav", TSFX_PEGBOY22), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy23.wav", TSFX_PEGBOY23), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy24.wav", TSFX_PEGBOY24), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy25.wav", TSFX_PEGBOY25), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy26.wav", TSFX_PEGBOY26), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy27.wav", TSFX_PEGBOY27), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy28.wav", TSFX_PEGBOY28), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy29.wav", TSFX_PEGBOY29), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy30.wav", TSFX_PEGBOY30), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy31.wav", TSFX_PEGBOY31), +#endif + // greeting -- psst, over here... + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy32.wav", TSFX_PEGBOY32), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy33.wav", TSFX_PEGBOY33), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy34.wav", TSFX_PEGBOY34), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy35.wav", TSFX_PEGBOY35), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy36.wav", TSFX_PEGBOY36), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy37.wav", TSFX_PEGBOY37), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy38.wav", TSFX_PEGBOY38), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy39.wav", TSFX_PEGBOY39), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy40.wav", TSFX_PEGBOY40), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy41.wav", TSFX_PEGBOY41), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy42.wav", TSFX_PEGBOY42), + SFX(sfx_STREAM, "Sfx\\Towners\\Pegboy43.wav", TSFX_PEGBOY43), +#endif + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Priest00.wav", TSFX_PRIEST0), + SFX(sfx_STREAM, "Sfx\\Towners\\Priest01.wav", TSFX_PRIEST1), + SFX(sfx_STREAM, "Sfx\\Towners\\Priest02.wav", TSFX_PRIEST2), + SFX(sfx_STREAM, "Sfx\\Towners\\Priest03.wav", TSFX_PRIEST3), + SFX(sfx_STREAM, "Sfx\\Towners\\Priest04.wav", TSFX_PRIEST4), + SFX(sfx_STREAM, "Sfx\\Towners\\Priest05.wav", TSFX_PRIEST5), + SFX(sfx_STREAM, "Sfx\\Towners\\Priest06.wav", TSFX_PRIEST6), + SFX(sfx_STREAM, "Sfx\\Towners\\Priest07.wav", TSFX_PRIEST7), +#endif + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt00.wav", TSFX_STORY0), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt01.wav", TSFX_STORY1), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt02.wav", TSFX_STORY2), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt03.wav", TSFX_STORY3), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt04.wav", TSFX_STORY4), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt05.wav", TSFX_STORY5), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt06.wav", TSFX_STORY6), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt07.wav", TSFX_STORY7), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt08.wav", TSFX_STORY8), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt09.wav", TSFX_STORY9), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt10.wav", TSFX_STORY10), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt11.wav", TSFX_STORY11), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt12.wav", TSFX_STORY12), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt13.wav", TSFX_STORY13), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt14.wav", TSFX_STORY14), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt15.wav", TSFX_STORY15), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt16.wav", TSFX_STORY16), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt17.wav", TSFX_STORY17), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt18.wav", TSFX_STORY18), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt19.wav", TSFX_STORY19), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt20.wav", TSFX_STORY20), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt21.wav", TSFX_STORY21), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt22.wav", TSFX_STORY22), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt23.wav", TSFX_STORY23), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt24.wav", TSFX_STORY24), +#endif + // greeting -- hello my friend... + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt25.wav", TSFX_STORY25), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt26.wav", TSFX_STORY26), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt27.wav", TSFX_STORY27), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt28.wav", TSFX_STORY28), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt29.wav", TSFX_STORY29), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt30.wav", TSFX_STORY30), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt31.wav", TSFX_STORY31), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt32.wav", TSFX_STORY32), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt33.wav", TSFX_STORY33), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt34.wav", TSFX_STORY34), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt35.wav", TSFX_STORY35), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt36.wav", TSFX_STORY36), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt37.wav", TSFX_STORY37), + SFX(sfx_STREAM, "Sfx\\Towners\\Storyt38.wav", TSFX_STORY38), +#endif + + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown00.wav", TSFX_TAVERN0), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown01.wav", TSFX_TAVERN1), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown02.wav", TSFX_TAVERN2), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown03.wav", TSFX_TAVERN3), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown04.wav", TSFX_TAVERN4), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown05.wav", TSFX_TAVERN5), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown06.wav", TSFX_TAVERN6), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown07.wav", TSFX_TAVERN7), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown08.wav", TSFX_TAVERN8), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown09.wav", TSFX_TAVERN9), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown10.wav", TSFX_TAVERN10), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown11.wav", TSFX_TAVERN11), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown12.wav", TSFX_TAVERN12), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown13.wav", TSFX_TAVERN13), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown14.wav", TSFX_TAVERN14), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown15.wav", TSFX_TAVERN15), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown16.wav", TSFX_TAVERN16), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown17.wav", TSFX_TAVERN17), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown18.wav", TSFX_TAVERN18), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown19.wav", TSFX_TAVERN19), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown20.wav", TSFX_TAVERN20), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown21.wav", TSFX_TAVERN21), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown22.wav", TSFX_TAVERN22), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown23.wav", TSFX_TAVERN23), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown24.wav", TSFX_TAVERN24), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown25.wav", TSFX_TAVERN25), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown26.wav", TSFX_TAVERN26), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown27.wav", TSFX_TAVERN27), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown28.wav", TSFX_TAVERN28), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown29.wav", TSFX_TAVERN29), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown30.wav", TSFX_TAVERN30), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown31.wav", TSFX_TAVERN31), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown32.wav", TSFX_TAVERN32), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown33.wav", TSFX_TAVERN33), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown34.wav", TSFX_TAVERN34), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown35.wav", TSFX_TAVERN35), +#endif + // greeting -- greetings good master... + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown36.wav", TSFX_TAVERN36), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown37.wav", TSFX_TAVERN37), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown38.wav", TSFX_TAVERN38), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown39.wav", TSFX_TAVERN39), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown40.wav", TSFX_TAVERN40), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown41.wav", TSFX_TAVERN41), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown42.wav", TSFX_TAVERN42), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown43.wav", TSFX_TAVERN43), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown44.wav", TSFX_TAVERN44), + SFX(sfx_STREAM, "Sfx\\Towners\\Tavown45.wav", TSFX_TAVERN45), +#endif + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Witch01.wav", TSFX_WITCH1), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch02.wav", TSFX_WITCH2), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch03.wav", TSFX_WITCH3), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch04.wav", TSFX_WITCH4), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch05.wav", TSFX_WITCH5), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch06.wav", TSFX_WITCH6), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch07.wav", TSFX_WITCH7), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch08.wav", TSFX_WITCH8), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch09.wav", TSFX_WITCH9), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch10.wav", TSFX_WITCH10), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch11.wav", TSFX_WITCH11), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch12.wav", TSFX_WITCH12), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch13.wav", TSFX_WITCH13), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch14.wav", TSFX_WITCH14), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch15.wav", TSFX_WITCH15), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch16.wav", TSFX_WITCH16), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch17.wav", TSFX_WITCH17), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch18.wav", TSFX_WITCH18), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch19.wav", TSFX_WITCH19), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch20.wav", TSFX_WITCH20), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch21.wav", TSFX_WITCH21), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch22.wav", TSFX_WITCH22), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch23.wav", TSFX_WITCH23), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch24.wav", TSFX_WITCH24), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch25.wav", TSFX_WITCH25), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch26.wav", TSFX_WITCH26), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch27.wav", TSFX_WITCH27), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch28.wav", TSFX_WITCH28), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch29.wav", TSFX_WITCH29), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch30.wav", TSFX_WITCH30), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch31.wav", TSFX_WITCH31), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch32.wav", TSFX_WITCH32), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch33.wav", TSFX_WITCH33), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch34.wav", TSFX_WITCH34), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch35.wav", TSFX_WITCH35), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch36.wav", TSFX_WITCH36), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch37.wav", TSFX_WITCH37), +#endif + // greeting -- I sense a soul in search of answers + SFX(sfx_STREAM, "Sfx\\Towners\\Witch38.wav", TSFX_WITCH38), +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Witch39.wav", TSFX_WITCH39), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch40.wav", TSFX_WITCH40), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch41.wav", TSFX_WITCH41), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch42.wav", TSFX_WITCH42), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch43.wav", TSFX_WITCH43), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch44.wav", TSFX_WITCH44), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch45.wav", TSFX_WITCH45), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch46.wav", TSFX_WITCH46), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch47.wav", TSFX_WITCH47), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch48.wav", TSFX_WITCH48), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch49.wav", TSFX_WITCH49), + SFX(sfx_STREAM, "Sfx\\Towners\\Witch50.wav", TSFX_WITCH50), +#endif + +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Towners\\Wound01.wav", TSFX_WOUND), +#endif + + // Mage +#if !IS_VERSION(SHAREWARE) + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage01.wav", PS_MAGE1), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage02.wav", PS_MAGE2), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage03.wav", PS_MAGE3), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage04.wav", PS_MAGE4), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage05.wav", PS_MAGE5), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage06.wav", PS_MAGE6), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage07.wav", PS_MAGE7), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage08.wav", PS_MAGE8), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage09.wav", PS_MAGE9), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage10.wav", PS_MAGE10), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage11.wav", PS_MAGE11), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage12.wav", PS_MAGE12), + sSFX(0, "Sfx\\Sorceror\\Mage13.wav", PS_MAGE13), + sSFX(0, "Sfx\\Sorceror\\Mage14.wav", PS_MAGE14), + sSFX(0, "Sfx\\Sorceror\\Mage15.wav", PS_MAGE15), + sSFX(0, "Sfx\\Sorceror\\Mage16.wav", PS_MAGE16), + sSFX(0, "Sfx\\Sorceror\\Mage17.wav", PS_MAGE17), + sSFX(0, "Sfx\\Sorceror\\Mage18.wav", PS_MAGE18), + sSFX(0, "Sfx\\Sorceror\\Mage19.wav", PS_MAGE19), + sSFX(0, "Sfx\\Sorceror\\Mage20.wav", PS_MAGE20), + sSFX(0, "Sfx\\Sorceror\\Mage21.wav", PS_MAGE21), + sSFX(0, "Sfx\\Sorceror\\Mage22.wav", PS_MAGE22), + sSFX(0, "Sfx\\Sorceror\\Mage23.wav", PS_MAGE23), + sSFX(0, "Sfx\\Sorceror\\Mage24.wav", PS_MAGE24), + sSFX(0, "Sfx\\Sorceror\\Mage25.wav", PS_MAGE25), + sSFX(0, "Sfx\\Sorceror\\Mage26.wav", PS_MAGE26), + sSFX(0, "Sfx\\Sorceror\\Mage27.wav", PS_MAGE27), + sSFX(0, "Sfx\\Sorceror\\Mage28.wav", PS_MAGE28), + sSFX(0, "Sfx\\Sorceror\\Mage29.wav", PS_MAGE29), + sSFX(0, "Sfx\\Sorceror\\Mage30.wav", PS_MAGE30), + sSFX(0, "Sfx\\Sorceror\\Mage31.wav", PS_MAGE31), + sSFX(0, "Sfx\\Sorceror\\Mage32.wav", PS_MAGE32), + sSFX(0, "Sfx\\Sorceror\\Mage33.wav", PS_MAGE33), + sSFX(0, "Sfx\\Sorceror\\Mage34.wav", PS_MAGE34), + sSFX(0, "Sfx\\Sorceror\\Mage35.wav", PS_MAGE35), + sSFX(0, "Sfx\\Sorceror\\Mage36.wav", PS_MAGE36), + sSFX(0, "Sfx\\Sorceror\\Mage37.wav", PS_MAGE37), + sSFX(0, "Sfx\\Sorceror\\Mage38.wav", PS_MAGE38), + sSFX(0, "Sfx\\Sorceror\\Mage39.wav", PS_MAGE39), + sSFX(0, "Sfx\\Sorceror\\Mage40.wav", PS_MAGE40), + sSFX(0, "Sfx\\Sorceror\\Mage41.wav", PS_MAGE41), + sSFX(0, "Sfx\\Sorceror\\Mage42.wav", PS_MAGE42), + sSFX(0, "Sfx\\Sorceror\\Mage43.wav", PS_MAGE43), + sSFX(0, "Sfx\\Sorceror\\Mage44.wav", PS_MAGE44), + sSFX(0, "Sfx\\Sorceror\\Mage45.wav", PS_MAGE45), + sSFX(0, "Sfx\\Sorceror\\Mage46.wav", PS_MAGE46), + sSFX(0, "Sfx\\Sorceror\\Mage47.wav", PS_MAGE47), + sSFX(0, "Sfx\\Sorceror\\Mage48.wav", PS_MAGE48), + sSFX(0, "Sfx\\Sorceror\\Mage49.wav", PS_MAGE49), + sSFX(0, "Sfx\\Sorceror\\Mage50.wav", PS_MAGE50), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage51.wav", PS_MAGE51), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage52.wav", PS_MAGE52), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage53.wav", PS_MAGE53), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage54.wav", PS_MAGE54), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage55.wav", PS_MAGE55), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage56.wav", PS_MAGE56), + sSFX(0, "Sfx\\Sorceror\\Mage57.wav", PS_MAGE57), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage58.wav", PS_MAGE58), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage59.wav", PS_MAGE59), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage60.wav", PS_MAGE60), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage61.wav", PS_MAGE61), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage62.wav", PS_MAGE62), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage63.wav", PS_MAGE63), + sSFX(0, "Sfx\\Sorceror\\Mage64.wav", PS_MAGE64), + sSFX(0, "Sfx\\Sorceror\\Mage65.wav", PS_MAGE65), + sSFX(0, "Sfx\\Sorceror\\Mage66.wav", PS_MAGE66), + sSFX(0, "Sfx\\Sorceror\\Mage67.wav", PS_MAGE67), + sSFX(0, "Sfx\\Sorceror\\Mage68.wav", PS_MAGE68), + sSFX(0, "Sfx\\Sorceror\\Mage69.wav", PS_MAGE69), + sSFX(0, "Sfx\\Sorceror\\Mage69b.wav", PS_MAGE69B), + sSFX(0, "Sfx\\Sorceror\\Mage70.wav", PS_MAGE70), + sSFX(0, "Sfx\\Sorceror\\Mage71.wav", PS_MAGE71), + sSFX(0, "Sfx\\Sorceror\\Mage72.wav", PS_MAGE72), + sSFX(0, "Sfx\\Sorceror\\Mage73.wav", PS_MAGE73), + sSFX(0, "Sfx\\Sorceror\\Mage74.wav", PS_MAGE74), + sSFX(0, "Sfx\\Sorceror\\Mage75.wav", PS_MAGE75), + sSFX(0, "Sfx\\Sorceror\\Mage76.wav", PS_MAGE76), + sSFX(0, "Sfx\\Sorceror\\Mage77.wav", PS_MAGE77), + sSFX(0, "Sfx\\Sorceror\\Mage78.wav", PS_MAGE78), + sSFX(0, "Sfx\\Sorceror\\Mage79.wav", PS_MAGE79), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage80.wav", PS_MAGE80), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage81.wav", PS_MAGE81), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage82.wav", PS_MAGE82), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage83.wav", PS_MAGE83), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage84.wav", PS_MAGE84), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage85.wav", PS_MAGE85), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage86.wav", PS_MAGE86), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage87.wav", PS_MAGE87), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage88.wav", PS_MAGE88), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage89.wav", PS_MAGE89), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage90.wav", PS_MAGE90), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage91.wav", PS_MAGE91), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage92.wav", PS_MAGE92), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage93.wav", PS_MAGE93), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage94.wav", PS_MAGE94), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage95.wav", PS_MAGE95), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage96.wav", PS_MAGE96), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage97.wav", PS_MAGE97), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage98.wav", PS_MAGE98), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage99.wav", PS_MAGE99), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage100.wav", PS_MAGE100), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage101.wav", PS_MAGE101), + sSFX(sfx_STREAM, "Sfx\\Sorceror\\Mage102.wav", PS_MAGE102), +#endif + + // Rogue +#if !IS_VERSION(SHAREWARE) + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue01.wav", PS_ROGUE1), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue02.wav", PS_ROGUE2), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue03.wav", PS_ROGUE3), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue04.wav", PS_ROGUE4), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue05.wav", PS_ROGUE5), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue06.wav", PS_ROGUE6), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue07.wav", PS_ROGUE7), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue08.wav", PS_ROGUE8), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue09.wav", PS_ROGUE9), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue10.wav", PS_ROGUE10), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue11.wav", PS_ROGUE11), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue12.wav", PS_ROGUE12), + rSFX(0, "Sfx\\Rogue\\Rogue13.wav", PS_ROGUE13), + rSFX(0, "Sfx\\Rogue\\Rogue14.wav", PS_ROGUE14), + rSFX(0, "Sfx\\Rogue\\Rogue15.wav", PS_ROGUE15), + rSFX(0, "Sfx\\Rogue\\Rogue16.wav", PS_ROGUE16), + rSFX(0, "Sfx\\Rogue\\Rogue17.wav", PS_ROGUE17), + rSFX(0, "Sfx\\Rogue\\Rogue18.wav", PS_ROGUE18), + rSFX(0, "Sfx\\Rogue\\Rogue19.wav", PS_ROGUE19), + rSFX(0, "Sfx\\Rogue\\Rogue20.wav", PS_ROGUE20), + rSFX(0, "Sfx\\Rogue\\Rogue21.wav", PS_ROGUE21), + rSFX(0, "Sfx\\Rogue\\Rogue22.wav", PS_ROGUE22), + rSFX(0, "Sfx\\Rogue\\Rogue23.wav", PS_ROGUE23), + rSFX(0, "Sfx\\Rogue\\Rogue24.wav", PS_ROGUE24), + rSFX(0, "Sfx\\Rogue\\Rogue25.wav", PS_ROGUE25), + rSFX(0, "Sfx\\Rogue\\Rogue26.wav", PS_ROGUE26), + rSFX(0, "Sfx\\Rogue\\Rogue27.wav", PS_ROGUE27), + rSFX(0, "Sfx\\Rogue\\Rogue28.wav", PS_ROGUE28), + rSFX(0, "Sfx\\Rogue\\Rogue29.wav", PS_ROGUE29), + rSFX(0, "Sfx\\Rogue\\Rogue30.wav", PS_ROGUE30), + rSFX(0, "Sfx\\Rogue\\Rogue31.wav", PS_ROGUE31), + rSFX(0, "Sfx\\Rogue\\Rogue32.wav", PS_ROGUE32), + rSFX(0, "Sfx\\Rogue\\Rogue33.wav", PS_ROGUE33), + rSFX(0, "Sfx\\Rogue\\Rogue34.wav", PS_ROGUE34), + rSFX(0, "Sfx\\Rogue\\Rogue35.wav", PS_ROGUE35), + rSFX(0, "Sfx\\Rogue\\Rogue36.wav", PS_ROGUE36), + rSFX(0, "Sfx\\Rogue\\Rogue37.wav", PS_ROGUE37), + rSFX(0, "Sfx\\Rogue\\Rogue38.wav", PS_ROGUE38), + rSFX(0, "Sfx\\Rogue\\Rogue39.wav", PS_ROGUE39), + rSFX(0, "Sfx\\Rogue\\Rogue40.wav", PS_ROGUE40), + rSFX(0, "Sfx\\Rogue\\Rogue41.wav", PS_ROGUE41), + rSFX(0, "Sfx\\Rogue\\Rogue42.wav", PS_ROGUE42), + rSFX(0, "Sfx\\Rogue\\Rogue43.wav", PS_ROGUE43), + rSFX(0, "Sfx\\Rogue\\Rogue44.wav", PS_ROGUE44), + rSFX(0, "Sfx\\Rogue\\Rogue45.wav", PS_ROGUE45), + rSFX(0, "Sfx\\Rogue\\Rogue46.wav", PS_ROGUE46), + rSFX(0, "Sfx\\Rogue\\Rogue47.wav", PS_ROGUE47), + rSFX(0, "Sfx\\Rogue\\Rogue48.wav", PS_ROGUE48), + rSFX(0, "Sfx\\Rogue\\Rogue49.wav", PS_ROGUE49), + rSFX(0, "Sfx\\Rogue\\Rogue50.wav", PS_ROGUE50), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue51.wav", PS_ROGUE51), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue52.wav", PS_ROGUE52), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue53.wav", PS_ROGUE53), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue54.wav", PS_ROGUE54), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue55.wav", PS_ROGUE55), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue56.wav", PS_ROGUE56), + rSFX(0, "Sfx\\Rogue\\Rogue57.wav", PS_ROGUE57), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue58.wav", PS_ROGUE58), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue59.wav", PS_ROGUE59), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue60.wav", PS_ROGUE60), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue61.wav", PS_ROGUE61), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue62.wav", PS_ROGUE62), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue63.wav", PS_ROGUE63), + rSFX(0, "Sfx\\Rogue\\Rogue64.wav", PS_ROGUE64), + rSFX(0, "Sfx\\Rogue\\Rogue65.wav", PS_ROGUE65), + rSFX(0, "Sfx\\Rogue\\Rogue66.wav", PS_ROGUE66), + rSFX(0, "Sfx\\Rogue\\Rogue67.wav", PS_ROGUE67), + rSFX(0, "Sfx\\Rogue\\Rogue68.wav", PS_ROGUE68), + rSFX(0, "Sfx\\Rogue\\Rogue69.wav", PS_ROGUE69), + rSFX(0, "Sfx\\Rogue\\Rogue69b.wav", PS_ROGUE69B), + rSFX(0, "Sfx\\Rogue\\Rogue70.wav", PS_ROGUE70), + rSFX(0, "Sfx\\Rogue\\Rogue71.wav", PS_ROGUE71), + rSFX(0, "Sfx\\Rogue\\Rogue72.wav", PS_ROGUE72), + rSFX(0, "Sfx\\Rogue\\Rogue73.wav", PS_ROGUE73), + rSFX(0, "Sfx\\Rogue\\Rogue74.wav", PS_ROGUE74), + rSFX(0, "Sfx\\Rogue\\Rogue75.wav", PS_ROGUE75), + rSFX(0, "Sfx\\Rogue\\Rogue76.wav", PS_ROGUE76), + rSFX(0, "Sfx\\Rogue\\Rogue77.wav", PS_ROGUE77), + rSFX(0, "Sfx\\Rogue\\Rogue78.wav", PS_ROGUE78), + rSFX(0, "Sfx\\Rogue\\Rogue79.wav", PS_ROGUE79), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue80.wav", PS_ROGUE80), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue81.wav", PS_ROGUE81), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue82.wav", PS_ROGUE82), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue83.wav", PS_ROGUE83), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue84.wav", PS_ROGUE84), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue85.wav", PS_ROGUE85), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue86.wav", PS_ROGUE86), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue87.wav", PS_ROGUE87), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue88.wav", PS_ROGUE88), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue89.wav", PS_ROGUE89), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue90.wav", PS_ROGUE90), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue91.wav", PS_ROGUE91), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue92.wav", PS_ROGUE92), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue93.wav", PS_ROGUE93), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue94.wav", PS_ROGUE94), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue95.wav", PS_ROGUE95), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue96.wav", PS_ROGUE96), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue97.wav", PS_ROGUE97), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue98.wav", PS_ROGUE98), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue99.wav", PS_ROGUE99), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue100.wav", PS_ROGUE100), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue101.wav", PS_ROGUE101), + rSFX(sfx_STREAM, "Sfx\\Rogue\\Rogue102.wav", PS_ROGUE102), +#endif + + // Warrior +#if !IS_VERSION(SHAREWARE) + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior01.wav", PS_WARR1), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior02.wav", PS_WARR2), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior03.wav", PS_WARR3), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior04.wav", PS_WARR4), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior05.wav", PS_WARR5), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior06.wav", PS_WARR6), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior07.wav", PS_WARR7), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior08.wav", PS_WARR8), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior09.wav", PS_WARR9), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior10.wav", PS_WARR10), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior11.wav", PS_WARR11), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior12.wav", PS_WARR12), +#endif + wSFX(0, "Sfx\\Warrior\\Warior13.wav", PS_WARR13), + wSFX(0, "Sfx\\Warrior\\Warior14.wav", PS_WARR14), + wSFX(0, "Sfx\\Warrior\\Wario14b.wav", PS_WARR14B), + wSFX(0, "Sfx\\Warrior\\Wario14c.wav", PS_WARR14C), + wSFX(0, "Sfx\\Warrior\\Warior15.wav", PS_WARR15), + wSFX(0, "Sfx\\Warrior\\Wario15b.wav", PS_WARR15B), + wSFX(0, "Sfx\\Warrior\\Wario15c.wav", PS_WARR15C), + wSFX(0, "Sfx\\Warrior\\Warior16.wav", PS_WARR16), + wSFX(0, "Sfx\\Warrior\\Wario16b.wav", PS_WARR16B), + wSFX(0, "Sfx\\Warrior\\Wario16c.wav", PS_WARR16C), + wSFX(0, "Sfx\\Warrior\\Warior17.wav", PS_WARR17), + wSFX(0, "Sfx\\Warrior\\Warior18.wav", PS_WARR18), + wSFX(0, "Sfx\\Warrior\\Warior19.wav", PS_WARR19), + wSFX(0, "Sfx\\Warrior\\Warior20.wav", PS_WARR20), + wSFX(0, "Sfx\\Warrior\\Warior21.wav", PS_WARR21), + wSFX(0, "Sfx\\Warrior\\Warior22.wav", PS_WARR22), + wSFX(0, "Sfx\\Warrior\\Warior23.wav", PS_WARR23), + wSFX(0, "Sfx\\Warrior\\Warior24.wav", PS_WARR24), + wSFX(0, "Sfx\\Warrior\\Warior25.wav", PS_WARR25), + wSFX(0, "Sfx\\Warrior\\Warior26.wav", PS_WARR26), + wSFX(0, "Sfx\\Warrior\\Warior27.wav", PS_WARR27), + wSFX(0, "Sfx\\Warrior\\Warior28.wav", PS_WARR28), + wSFX(0, "Sfx\\Warrior\\Warior29.wav", PS_WARR29), + wSFX(0, "Sfx\\Warrior\\Warior30.wav", PS_WARR30), + wSFX(0, "Sfx\\Warrior\\Warior31.wav", PS_WARR31), + wSFX(0, "Sfx\\Warrior\\Warior32.wav", PS_WARR32), + wSFX(0, "Sfx\\Warrior\\Warior33.wav", PS_WARR33), + wSFX(0, "Sfx\\Warrior\\Warior34.wav", PS_WARR34), + wSFX(0, "Sfx\\Warrior\\Warior35.wav", PS_WARR35), + wSFX(0, "Sfx\\Warrior\\Warior36.wav", PS_WARR36), + wSFX(0, "Sfx\\Warrior\\Warior37.wav", PS_WARR37), + wSFX(0, "Sfx\\Warrior\\Warior38.wav", PS_WARR38), + wSFX(0, "Sfx\\Warrior\\Warior39.wav", PS_WARR39), + wSFX(0, "Sfx\\Warrior\\Warior40.wav", PS_WARR40), + wSFX(0, "Sfx\\Warrior\\Warior41.wav", PS_WARR41), + wSFX(0, "Sfx\\Warrior\\Warior42.wav", PS_WARR42), + wSFX(0, "Sfx\\Warrior\\Warior43.wav", PS_WARR43), + wSFX(0, "Sfx\\Warrior\\Warior44.wav", PS_WARR44), + wSFX(0, "Sfx\\Warrior\\Warior45.wav", PS_WARR45), + wSFX(0, "Sfx\\Warrior\\Warior46.wav", PS_WARR46), + wSFX(0, "Sfx\\Warrior\\Warior47.wav", PS_WARR47), + wSFX(0, "Sfx\\Warrior\\Warior48.wav", PS_WARR48), + wSFX(0, "Sfx\\Warrior\\Warior49.wav", PS_WARR49), + wSFX(0, "Sfx\\Warrior\\Warior50.wav", PS_WARR50), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior51.wav", PS_WARR51), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior52.wav", PS_WARR52), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior53.wav", PS_WARR53), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior54.wav", PS_WARR54), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior55.wav", PS_WARR55), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior56.wav", PS_WARR56), + wSFX(0, "Sfx\\Warrior\\Warior57.wav", PS_WARR57), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior58.wav", PS_WARR58), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior59.wav", PS_WARR59), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior60.wav", PS_WARR60), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior61.wav", PS_WARR61), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior62.wav", PS_WARR62), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior63.wav", PS_WARR63), + wSFX(0, "Sfx\\Warrior\\Warior64.wav", PS_WARR64), + wSFX(0, "Sfx\\Warrior\\Warior65.wav", PS_WARR65), + wSFX(0, "Sfx\\Warrior\\Warior66.wav", PS_WARR66), + wSFX(0, "Sfx\\Warrior\\Warior67.wav", PS_WARR67), + wSFX(0, "Sfx\\Warrior\\Warior68.wav", PS_WARR68), + wSFX(0, "Sfx\\Warrior\\Warior69.wav", PS_WARR69), + wSFX(0, "Sfx\\Warrior\\Wario69b.wav", PS_WARR69B), + wSFX(0, "Sfx\\Warrior\\Warior70.wav", PS_WARR70), + wSFX(0, "Sfx\\Warrior\\Warior71.wav", PS_WARR71), + wSFX(0, "Sfx\\Warrior\\Warior72.wav", PS_WARR72), + wSFX(0, "Sfx\\Warrior\\Warior73.wav", PS_WARR73), + wSFX(0, "Sfx\\Warrior\\Warior74.wav", PS_WARR74), + wSFX(0, "Sfx\\Warrior\\Warior75.wav", PS_WARR75), + wSFX(0, "Sfx\\Warrior\\Warior76.wav", PS_WARR76), + wSFX(0, "Sfx\\Warrior\\Warior77.wav", PS_WARR77), + wSFX(0, "Sfx\\Warrior\\Warior78.wav", PS_WARR78), + wSFX(0, "Sfx\\Warrior\\Warior79.wav", PS_WARR79), +#if !IS_VERSION(SHAREWARE) + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior80.wav", PS_WARR80), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior81.wav", PS_WARR81), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior82.wav", PS_WARR82), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior83.wav", PS_WARR83), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior84.wav", PS_WARR84), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior85.wav", PS_WARR85), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior86.wav", PS_WARR86), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior87.wav", PS_WARR87), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior88.wav", PS_WARR88), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior89.wav", PS_WARR89), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior90.wav", PS_WARR90), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior91.wav", PS_WARR91), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior92.wav", PS_WARR92), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior93.wav", PS_WARR93), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior94.wav", PS_WARR94), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior95.wav", PS_WARR95), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario95b.wav", PS_WARR95B), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario95c.wav", PS_WARR95C), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario95d.wav", PS_WARR95D), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario95e.wav", PS_WARR95E), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario95f.wav", PS_WARR95F), + // unused wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior96.wav", PS_WARR96), +#endif + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario96b.wav", PS_WARR96B), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario97.wav", PS_WARR97), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario98.wav", PS_WARR98), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Warior99.wav", PS_WARR99), +#if !IS_VERSION(SHAREWARE) + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario100.wav", PS_WARR100), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario101.wav", PS_WARR101), + wSFX(sfx_STREAM, "Sfx\\Warrior\\Wario102.wav", PS_WARR102), +#endif + +// Silence "Sfx\\Misc\\blank.wav" + // GWP Fix this: New sounds! + // Monk +#if !IS_VERSION(SHAREWARE) + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk01.wav", PS_MONK1), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK2), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK3), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK4), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK5), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK6), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK7), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk08.wav", PS_MONK8), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk09.wav", PS_MONK9), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk10.wav", PS_MONK10), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk11.wav", PS_MONK11), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk12.wav", PS_MONK12), + mSFX(0, "Sfx\\Monk\\Monk13.wav", PS_MONK13), + mSFX(0, "Sfx\\Monk\\Monk14.wav", PS_MONK14), + mSFX(0, "Sfx\\Monk\\Monk15.wav", PS_MONK15), + mSFX(0, "Sfx\\Monk\\Monk16.wav", PS_MONK16), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK17), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK18), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK19), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK20), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK21), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK22), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK23), + mSFX(0, "Sfx\\Monk\\Monk24.wav", PS_MONK24), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK25), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK26), + mSFX(0, "Sfx\\Monk\\Monk27.wav", PS_MONK27), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK28), + mSFX(0, "Sfx\\Monk\\Monk29.wav", PS_MONK29), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK30), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK31), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK32), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK33), + mSFX(0, "Sfx\\Monk\\Monk34.wav", PS_MONK34), + mSFX(0, "Sfx\\Monk\\Monk35.wav", PS_MONK35), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK36), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK37), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK38), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK39), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK40), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK41), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK42), + mSFX(0, "Sfx\\Monk\\Monk43.wav", PS_MONK43), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK44), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK45), + mSFX(0, "Sfx\\Monk\\Monk46.wav", PS_MONK46), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK47), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK48), + mSFX(0, "Sfx\\Monk\\Monk49.wav", PS_MONK49), + mSFX(0, "Sfx\\Monk\\Monk50.wav", PS_MONK50), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK51), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk52.wav", PS_MONK52), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK53), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk54.wav", PS_MONK54), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk55.wav", PS_MONK55), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk56.wav", PS_MONK56), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK57), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK58), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK59), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK60), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk61.wav", PS_MONK61), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk62.wav", PS_MONK62), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK63), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK64), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK65), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK66), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK67), + mSFX(0, "Sfx\\Monk\\Monk68.wav", PS_MONK68), + mSFX(0, "Sfx\\Monk\\Monk69.wav", PS_MONK69), + mSFX(0, "Sfx\\Monk\\Monk69b.wav", PS_MONK69B), + mSFX(0, "Sfx\\Monk\\Monk70.wav", PS_MONK70), + mSFX(0, "Sfx\\Monk\\Monk71.wav", PS_MONK71), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK72), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK73), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK74), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK75), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK76), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK77), + mSFX(0, "Sfx\\Misc\\blank.wav", PS_MONK78), + mSFX(0, "Sfx\\Monk\\Monk79.wav", PS_MONK79), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk80.wav", PS_MONK80), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK81), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk82.wav", PS_MONK82), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk83.wav", PS_MONK83), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK84), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK85), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK86), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk87.wav", PS_MONK87), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk88.wav", PS_MONK88), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk89.wav", PS_MONK89), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK90), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk91.wav", PS_MONK91), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk92.wav", PS_MONK92), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK93), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk94.wav", PS_MONK94), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk95.wav", PS_MONK95), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk96.wav", PS_MONK96), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk97.wav", PS_MONK97), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk98.wav", PS_MONK98), + mSFX(sfx_STREAM, "Sfx\\Monk\\Monk99.wav", PS_MONK99), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK100), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK101), + mSFX(sfx_STREAM, "Sfx\\Misc\\blank.wav", PS_MONK102), +#endif + + // Narrator +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar01.wav", PS_NAR1), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar02.wav", PS_NAR2), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar03.wav", PS_NAR3), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar04.wav", PS_NAR4), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar05.wav", PS_NAR5), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar06.wav", PS_NAR6), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar07.wav", PS_NAR7), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar08.wav", PS_NAR8), + SFX(sfx_STREAM, "Sfx\\Narrator\\Nar09.wav", PS_NAR9), + + // Level 16 intro + SFX(sfx_STREAM, "Sfx\\Misc\\Lvl16int.wav", PS_DIABLVLINT), + +#endif + + // unique monster sounds +#if !IS_VERSION(SHAREWARE) + SFX(sfx_STREAM, "Sfx\\Monsters\\Butcher.wav", USFX_CLEAVER), + SFX(sfx_STREAM, "Sfx\\Monsters\\Garbud01.wav", USFX_GARBUD1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Garbud02.wav", USFX_GARBUD2), + SFX(sfx_STREAM, "Sfx\\Monsters\\Garbud03.wav", USFX_GARBUD3), + SFX(sfx_STREAM, "Sfx\\Monsters\\Garbud04.wav", USFX_GARBUD4), + SFX(sfx_STREAM, "Sfx\\Monsters\\Izual01.wav", USFX_IZUAL1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Lach01.wav", USFX_LACH1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Lach02.wav", USFX_LACH2), + SFX(sfx_STREAM, "Sfx\\Monsters\\Lach03.wav", USFX_LACH3), + SFX(sfx_STREAM, "Sfx\\Monsters\\Laz01.wav", USFX_LAZ1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Laz02.wav", USFX_LAZ2), + SFX(sfx_STREAM, "Sfx\\Monsters\\Sking01.wav", USFX_SKING1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Snot01.wav", USFX_SNOT1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Snot02.wav", USFX_SNOT2), + SFX(sfx_STREAM, "Sfx\\Monsters\\Snot03.wav", USFX_SNOT3), + SFX(sfx_STREAM, "Sfx\\Monsters\\Warlrd01.wav", USFX_WARLRD1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Wlock01.wav", USFX_WLOCK1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Zhar01.wav", USFX_ZHAR1), + SFX(sfx_STREAM, "Sfx\\Monsters\\Zhar02.wav", USFX_ZHAR2), + SFX(sfx_STREAM, "Sfx\\Monsters\\DiabloD.wav", USFX_DIABLOD), + +// JKEQUEST Enter new sound cues here + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer1.wav", HSFX_FARMER1), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer2.wav", HSFX_FARMER2), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer2A.wav", HSFX_FARMER2A), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer3.wav", HSFX_FARMER3), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer4.wav", HSFX_FARMER4), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer5.wav", HSFX_FARMER5), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer6.wav", HSFX_FARMER6), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer7.wav", HSFX_FARMER7), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer8.wav", HSFX_FARMER8), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Farmer9.wav", HSFX_FARMER9), + + SFX(sfx_STREAM, "Sfx\\Hellfire\\TEDDYBR1.wav", HSFX_THEO1), + SFX(sfx_STREAM, "Sfx\\Hellfire\\TEDDYBR2.wav", HSFX_THEO2), + SFX(sfx_STREAM, "Sfx\\Hellfire\\TEDDYBR3.wav", HSFX_THEO3), + SFX(sfx_STREAM, "Sfx\\Hellfire\\TEDDYBR4.wav", HSFX_THEO4), + + SFX(sfx_STREAM, "Sfx\\Hellfire\\DEFILER1.wav", HSFX_DEFILER1), + SFX(sfx_STREAM, "Sfx\\Hellfire\\DEFILER2.wav", HSFX_DEFILER2), + SFX(sfx_STREAM, "Sfx\\Hellfire\\DEFILER3.wav", HSFX_DEFILER3), + SFX(sfx_STREAM, "Sfx\\Hellfire\\DEFILER4.wav", HSFX_DEFILER4), + SFX(sfx_STREAM, "Sfx\\Hellfire\\DEFILER8.wav", HSFX_DEFILER5), + SFX(sfx_STREAM, "Sfx\\Hellfire\\DEFILER6.wav", HSFX_DEFILER6), + SFX(sfx_STREAM, "Sfx\\Hellfire\\DEFILER7.wav", HSFX_DEFILER7), + + SFX(sfx_STREAM, "Sfx\\Hellfire\\NAKRUL1.wav", HSFX_NA_KRUL1), + SFX(sfx_STREAM, "Sfx\\Hellfire\\NAKRUL2.wav", HSFX_NA_KRUL2), + SFX(sfx_STREAM, "Sfx\\Hellfire\\NAKRUL3.wav", HSFX_NA_KRUL3), + SFX(sfx_STREAM, "Sfx\\Hellfire\\NAKRUL4.wav", HSFX_NA_KRUL4), + SFX(sfx_STREAM, "Sfx\\Hellfire\\NAKRUL5.wav", HSFX_NA_KRUL5), + SFX(sfx_STREAM, "Sfx\\Hellfire\\NAKRUL6.wav", HSFX_NA_KRUL6), + + SFX(sfx_STREAM, "Sfx\\Hellfire\\NARATR3.wav", HSFX_CORNERSTONE1), + + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT1.wav", HSFX_COWSUIT1), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT2.wav", HSFX_COWSUIT2), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT3.wav", HSFX_COWSUIT3), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT4.wav", HSFX_COWSUIT4), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT4A.wav", HSFX_COWSUIT4A), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT5.wav", HSFX_COWSUIT5), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT6.wav", HSFX_COWSUIT6), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT7.wav", HSFX_COWSUIT7), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT8.wav", HSFX_COWSUIT8), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT9.wav", HSFX_COWSUIT9), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT10.wav", HSFX_COWSUIT10), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT11.wav", HSFX_COWSUIT11), + SFX(sfx_STREAM, "Sfx\\Hellfire\\COWSUT12.wav", HSFX_COWSUIT12), + + SFX(sfx_STREAM, "Sfx\\Hellfire\\Skljrn1.wav", HSFX_SKULLJRNL1), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Naratr6.wav", HSFX_SKULLJRNL2), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Naratr7.wav", HSFX_SKULLJRNL3), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Naratr8.wav", HSFX_SKULLJRNL4), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Naratr5.wav", HSFX_SKULLJRNL5), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Naratr9.wav", HSFX_SKULLJRNL6), + SFX(sfx_STREAM, "Sfx\\Hellfire\\Naratr4.wav", HSFX_SKULLJRNL7), + + SFX(sfx_STREAM, "Sfx\\Hellfire\\TRADER1.wav", HSFX_TRADER1), + + + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Cropen.wav", CR_DOOROPEN), + SFX(sfx_ALLOWMULTIPLE, "Sfx\\Items\\Crclos.wav", CR_DOORCLOS), + + + +#endif +}; + +// Until there are actual sounds, don't hog the memory by loading duplicates. +#if !IS_VERSION(SHAREWARE) +#define PS_BARD1 PS_ROGUE1 +#define PS_BARD2 PS_ROGUE2 +#define PS_BARD3 PS_ROGUE3 +#define PS_BARD4 PS_ROGUE4 +#define PS_BARD5 PS_ROGUE5 +#define PS_BARD6 PS_ROGUE6 +#define PS_BARD7 PS_ROGUE7 +#define PS_BARD8 PS_ROGUE8 +#define PS_BARD9 PS_ROGUE9 +#define PS_BARD10 PS_ROGUE10 +#define PS_BARD11 PS_ROGUE11 +#define PS_BARD12 PS_ROGUE12 +#define PS_BARD13 PS_ROGUE13 +#define PS_BARD14 PS_ROGUE14 +#define PS_BARD15 PS_ROGUE15 +#define PS_BARD16 PS_ROGUE16 +#define PS_BARD17 PS_ROGUE17 +#define PS_BARD18 PS_ROGUE18 +#define PS_BARD19 PS_ROGUE19 +#define PS_BARD20 PS_ROGUE20 +#define PS_BARD21 PS_ROGUE21 +#define PS_BARD22 PS_ROGUE22 +#define PS_BARD23 PS_ROGUE23 +#define PS_BARD24 PS_ROGUE24 +#define PS_BARD25 PS_ROGUE25 +#define PS_BARD26 PS_ROGUE26 +#define PS_BARD27 PS_ROGUE27 +#define PS_BARD28 PS_ROGUE28 +#define PS_BARD29 PS_ROGUE29 +#define PS_BARD30 PS_ROGUE30 +#define PS_BARD31 PS_ROGUE31 +#define PS_BARD32 PS_ROGUE32 +#define PS_BARD33 PS_ROGUE33 +#define PS_BARD34 PS_ROGUE34 +#define PS_BARD35 PS_ROGUE35 +#define PS_BARD36 PS_ROGUE36 +#define PS_BARD37 PS_ROGUE37 +#define PS_BARD38 PS_ROGUE38 +#define PS_BARD39 PS_ROGUE39 +#define PS_BARD40 PS_ROGUE40 +#define PS_BARD41 PS_ROGUE41 +#define PS_BARD42 PS_ROGUE42 +#define PS_BARD43 PS_ROGUE43 +#define PS_BARD44 PS_ROGUE44 +#define PS_BARD45 PS_ROGUE45 +#define PS_BARD46 PS_ROGUE46 +#define PS_BARD47 PS_ROGUE47 +#define PS_BARD48 PS_ROGUE48 +#define PS_BARD49 PS_ROGUE49 +#define PS_BARD50 PS_ROGUE50 +#define PS_BARD51 PS_ROGUE51 +#define PS_BARD52 PS_ROGUE52 +#define PS_BARD53 PS_ROGUE53 +#define PS_BARD54 PS_ROGUE54 +#define PS_BARD55 PS_ROGUE55 +#define PS_BARD56 PS_ROGUE56 +#define PS_BARD57 PS_ROGUE57 +#define PS_BARD58 PS_ROGUE58 +#define PS_BARD59 PS_ROGUE59 +#define PS_BARD60 PS_ROGUE60 +#define PS_BARD61 PS_ROGUE61 +#define PS_BARD62 PS_ROGUE62 +#define PS_BARD63 PS_ROGUE63 +#define PS_BARD64 PS_ROGUE64 +#define PS_BARD65 PS_ROGUE65 +#define PS_BARD66 PS_ROGUE66 +#define PS_BARD67 PS_ROGUE67 +#define PS_BARD68 PS_ROGUE68 +#define PS_BARD69 PS_ROGUE69 +#define PS_BARD69B PS_ROGUE69B +#define PS_BARD70 PS_ROGUE70 +#define PS_BARD71 PS_ROGUE71 +#define PS_BARD72 PS_ROGUE72 +#define PS_BARD73 PS_ROGUE73 +#define PS_BARD74 PS_ROGUE74 +#define PS_BARD75 PS_ROGUE75 +#define PS_BARD76 PS_ROGUE76 +#define PS_BARD77 PS_ROGUE77 +#define PS_BARD78 PS_ROGUE78 +#define PS_BARD79 PS_ROGUE79 +#define PS_BARD80 PS_ROGUE80 +#define PS_BARD81 PS_ROGUE81 +#define PS_BARD82 PS_ROGUE82 +#define PS_BARD83 PS_ROGUE83 +#define PS_BARD84 PS_ROGUE84 +#define PS_BARD85 PS_ROGUE85 +#define PS_BARD86 PS_ROGUE86 +#define PS_BARD87 PS_ROGUE87 +#define PS_BARD88 PS_ROGUE88 +#define PS_BARD89 PS_ROGUE89 +#define PS_BARD90 PS_ROGUE90 +#define PS_BARD91 PS_ROGUE91 +#define PS_BARD92 PS_ROGUE92 +#define PS_BARD93 PS_ROGUE93 +#define PS_BARD94 PS_ROGUE94 +#define PS_BARD95 PS_ROGUE95 +#define PS_BARD96 PS_ROGUE96 +#define PS_BARD97 PS_ROGUE97 +#define PS_BARD98 PS_ROGUE98 +#define PS_BARD99 PS_ROGUE99 +#define PS_BARD100 PS_ROGUE100 +#define PS_BARD101 PS_ROGUE101 +#define PS_BARD102 PS_ROGUE102 + +#define PS_BARBARIAN1 PS_WARR1 +#define PS_BARBARIAN2 PS_WARR2 +#define PS_BARBARIAN3 PS_WARR3 +#define PS_BARBARIAN4 PS_WARR4 +#define PS_BARBARIAN5 PS_WARR5 +#define PS_BARBARIAN6 PS_WARR6 +#define PS_BARBARIAN7 PS_WARR7 +#define PS_BARBARIAN8 PS_WARR8 +#define PS_BARBARIAN9 PS_WARR9 +#define PS_BARBARIAN10 PS_WARR10 +#define PS_BARBARIAN11 PS_WARR11 +#define PS_BARBARIAN12 PS_WARR12 +#define PS_BARBARIAN13 PS_WARR13 +#define PS_BARBARIAN14 PS_WARR14 +#define PS_BARBARIAN15 PS_WARR15 +#define PS_BARBARIAN16 PS_WARR16 +#define PS_BARBARIAN17 PS_WARR17 +#define PS_BARBARIAN18 PS_WARR18 +#define PS_BARBARIAN19 PS_WARR19 +#define PS_BARBARIAN20 PS_WARR20 +#define PS_BARBARIAN21 PS_WARR21 +#define PS_BARBARIAN22 PS_WARR22 +#define PS_BARBARIAN23 PS_WARR23 +#define PS_BARBARIAN24 PS_WARR24 +#define PS_BARBARIAN25 PS_WARR25 +#define PS_BARBARIAN26 PS_WARR26 +#define PS_BARBARIAN27 PS_WARR27 +#define PS_BARBARIAN28 PS_WARR28 +#define PS_BARBARIAN29 PS_WARR29 +#define PS_BARBARIAN30 PS_WARR30 +#define PS_BARBARIAN31 PS_WARR31 +#define PS_BARBARIAN32 PS_WARR32 +#define PS_BARBARIAN33 PS_WARR33 +#define PS_BARBARIAN34 PS_WARR34 +#define PS_BARBARIAN35 PS_WARR35 +#define PS_BARBARIAN36 PS_WARR36 +#define PS_BARBARIAN37 PS_WARR37 +#define PS_BARBARIAN38 PS_WARR38 +#define PS_BARBARIAN39 PS_WARR39 +#define PS_BARBARIAN40 PS_WARR40 +#define PS_BARBARIAN41 PS_WARR41 +#define PS_BARBARIAN42 PS_WARR42 +#define PS_BARBARIAN43 PS_WARR43 +#define PS_BARBARIAN44 PS_WARR44 +#define PS_BARBARIAN45 PS_WARR45 +#define PS_BARBARIAN46 PS_WARR46 +#define PS_BARBARIAN47 PS_WARR47 +#define PS_BARBARIAN48 PS_WARR48 +#define PS_BARBARIAN49 PS_WARR49 +#define PS_BARBARIAN50 PS_WARR50 +#define PS_BARBARIAN51 PS_WARR51 +#define PS_BARBARIAN52 PS_WARR52 +#define PS_BARBARIAN53 PS_WARR53 +#define PS_BARBARIAN54 PS_WARR54 +#define PS_BARBARIAN55 PS_WARR55 +#define PS_BARBARIAN56 PS_WARR56 +#define PS_BARBARIAN57 PS_WARR57 +#define PS_BARBARIAN58 PS_WARR58 +#define PS_BARBARIAN59 PS_WARR59 +#define PS_BARBARIAN60 PS_WARR60 +#define PS_BARBARIAN61 PS_WARR61 +#define PS_BARBARIAN62 PS_WARR62 +#define PS_BARBARIAN63 PS_WARR63 +#define PS_BARBARIAN64 PS_WARR64 +#define PS_BARBARIAN65 PS_WARR65 +#define PS_BARBARIAN66 PS_WARR66 +#define PS_BARBARIAN67 PS_WARR67 +#define PS_BARBARIAN68 PS_WARR68 +#define PS_BARBARIAN69 PS_WARR69 +#define PS_BARBARIAN69B PS_WARR69B +#define PS_BARBARIAN70 PS_WARR70 +#define PS_BARBARIAN71 PS_WARR71 +#define PS_BARBARIAN72 PS_WARR72 +#define PS_BARBARIAN73 PS_WARR73 +#define PS_BARBARIAN74 PS_WARR74 +#define PS_BARBARIAN75 PS_WARR75 +#define PS_BARBARIAN76 PS_WARR76 +#define PS_BARBARIAN77 PS_WARR77 +#define PS_BARBARIAN78 PS_WARR78 +#define PS_BARBARIAN79 PS_WARR79 +#define PS_BARBARIAN80 PS_WARR80 +#define PS_BARBARIAN81 PS_WARR81 +#define PS_BARBARIAN82 PS_WARR82 +#define PS_BARBARIAN83 PS_WARR83 +#define PS_BARBARIAN84 PS_WARR84 +#define PS_BARBARIAN85 PS_WARR85 +#define PS_BARBARIAN86 PS_WARR86 +#define PS_BARBARIAN87 PS_WARR87 +#define PS_BARBARIAN88 PS_WARR88 +#define PS_BARBARIAN89 PS_WARR89 +#define PS_BARBARIAN90 PS_WARR90 +#define PS_BARBARIAN91 PS_WARR91 +#define PS_BARBARIAN92 PS_WARR92 +#define PS_BARBARIAN93 PS_WARR93 +#define PS_BARBARIAN94 PS_WARR94 +#define PS_BARBARIAN95 PS_WARR95 +#define PS_BARBARIAN96 PS_WARR96B +#define PS_BARBARIAN97 PS_WARR97 +#define PS_BARBARIAN98 PS_WARR98 +#define PS_BARBARIAN99 PS_WARR99 +#define PS_BARBARIAN100 PS_WARR100 +#define PS_BARBARIAN101 PS_WARR101 +#define PS_BARBARIAN102 PS_WARR102 + +#endif // SHAREWARE + +#undef SFX +#undef rSFX +#undef wSFX +#undef sSFX +#undef mSFX diff --git a/ENCRYPT.CPP b/ENCRYPT.CPP new file mode 100644 index 0000000..b1bc388 --- /dev/null +++ b/ENCRYPT.CPP @@ -0,0 +1,165 @@ +//****************************************************************** +// ENCRYPT.CPP +// File pack utility +// By Michael O'Brien (6/1/96) && Patrick Wyatt (6/24/96) +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "engine.h" +#include "mpqapi.h" +#include "implode.h" + + +//****************************************************************** +// private +//****************************************************************** + typedef struct _COMPRESSIONINFO { + LPVOID sourcebuffer; + DWORD sourceoffset; + LPVOID destbuffer; + DWORD destoffset; + DWORD bytes; + } COMPRESSIONINFO, *COMPRESSIONPTR; + + static DWORD hashsource[5][256]; + + +//****************************************************************** +//****************************************************************** +void Decrypt(LPDWORD data, DWORD bytes, DWORD key) { + DWORD adjust = 0xEEEEEEEE; + DWORD iter = bytes >> 2; + while (iter--) { + adjust += hashsource[HASH_ENCRYPTDATA][key & 0xFF]; + adjust += (*data++ ^= adjust+key)+(adjust << 5)+3; + key = (key >> 11) | ((key << 21) ^ 0xFFE00000)+0x11111111; + } +} + + +//****************************************************************** +//****************************************************************** +void Encrypt(LPDWORD data, DWORD bytes, DWORD key) { + DWORD adjust = 0xEEEEEEEE; + DWORD iter = bytes >> 2; + while (iter--) { + DWORD origdata = *data; + adjust += hashsource[HASH_ENCRYPTDATA][key & 0xFF]; + *data++ = origdata ^ (adjust+key); + adjust += origdata + (adjust << 5)+3; + key = (key >> 11) | ((key << 21) ^ 0xFFE00000)+0x11111111; + } +} + + +//****************************************************************** +//****************************************************************** +DWORD Hash(const char *filename, int hashtype) { + DWORD result = 0x7FED7FED; + DWORD adjust = 0xEEEEEEEE; + while (filename && *filename) { + char origchar = toupper(*filename++); + result = (result+adjust) ^ hashsource[hashtype][origchar]; + adjust += origchar+result+(adjust << 5)+3; + } + + return result; +} + + +//****************************************************************** +//****************************************************************** +void InitializeHashSource() { + DWORD seed = 0x100001; + for (int loop1 = 0; loop1 < 256; ++loop1) { + for (int loop2 = 0; loop2 < 5; ++loop2) { + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand1 = seed & 0xFFFF; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand2 = seed & 0xFFFF; + hashsource[loop2][loop1] = (rand1 << 16) | rand2; + } + } +} + + +//****************************************************************** +//****************************************************************** +static UINT __cdecl CompBufferRead(LPSTR buffer, UINT *size, LPVOID param) { + COMPRESSIONPTR infoptr = (COMPRESSIONPTR) param; + UINT bytes = min(*size,infoptr->bytes-infoptr->sourceoffset); + CopyMemory(buffer,(LPSTR)infoptr->sourcebuffer+infoptr->sourceoffset,bytes); + infoptr->sourceoffset += bytes; + return bytes; +} + + +//****************************************************************** +//****************************************************************** +static void __cdecl CompBufferWrite(LPSTR buffer, UINT *size, LPVOID param) { + COMPRESSIONPTR infoptr = (COMPRESSIONPTR)param; + CopyMemory((LPSTR)infoptr->destbuffer+infoptr->destoffset,buffer,*size); + infoptr->destoffset += *size; +} + + +//****************************************************************** +//****************************************************************** +DWORD Compress(LPBYTE data, DWORD bytes) { + // ALLOCATE COMPRESSION BUFFERS + LPVOID implodebuffer = DiabloAllocPtrSig(CMP_BUFFER_SIZE,'CMPt'); + LPVOID destbuffer = DiabloAllocPtrSig(max(SECTORSIZE*2,bytes*2),'CMPt'); + + // CREATE AN INFORMATION RECORD + COMPRESSIONINFO info; + info.sourcebuffer = data; + info.sourceoffset = 0; + info.destbuffer = destbuffer; + info.destoffset = 0; + info.bytes = bytes; + + // PERFORM THE COMPRESSION + UINT comptype = CMP_BINARY; + UINT dictsize = max(512,min(4096,SECTORSIZE)); + implode(CompBufferRead,CompBufferWrite,(LPSTR)implodebuffer,&info,&comptype,&dictsize); + + // IF THE DATA WAS NOT COMPRESSABLE, RETURN THE SOURCE DATA + // OTHERWISE, RETURN THE COMPRESSED DATA + if (info.destoffset < bytes) { + CopyMemory(data,destbuffer,info.destoffset); + bytes = info.destoffset; + } + + DiabloFreePtr(implodebuffer); + DiabloFreePtr(destbuffer); + return bytes; +} + + +//****************************************************************** +//****************************************************************** +void Expand(LPBYTE data, DWORD bytes, DWORD dwMaxBytes) { + // ALLOCATE COMPRESSION BUFFERS + LPVOID implodebuffer = DiabloAllocPtrSig(CMP_BUFFER_SIZE,'CMPt'); + LPVOID destbuffer = DiabloAllocPtrSig(dwMaxBytes,'CMPt'); + + // CREATE AN INFORMATION RECORD + COMPRESSIONINFO info; + info.sourcebuffer = data; + info.sourceoffset = 0; + info.destbuffer = destbuffer; + info.destoffset = 0; + info.bytes = bytes; + + // PERFORM THE DECOMPRESSION + explode(CompBufferRead,CompBufferWrite,(LPSTR)implodebuffer,&info); + app_assert(info.destoffset <= dwMaxBytes); + + // copy back into the original buffer + CopyMemory(data,destbuffer,info.destoffset); + + DiabloFreePtr(implodebuffer); + DiabloFreePtr(destbuffer); +} diff --git a/ENGINE.CPP b/ENGINE.CPP new file mode 100644 index 0000000..8170d56 --- /dev/null +++ b/ENGINE.CPP @@ -0,0 +1,3500 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Engine file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/ENGINE.CPP 2 1/22/97 2:32p Dgartner $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "resource.h" +#include "storm/h/storm.h" +#include "engine.h" +#include "lighting.h" +#include "scrollrt.h" +#include "debug.h" +#include "gendung.h" +#include "palette.h" + +//****************************************************************** +// extern +//****************************************************************** +void ErrorDlg(int nDlgId,DWORD dwErr,const char * pszFile,int nLine); + + +//****************************************************************** +// Registration info +//****************************************************************** +#include "regconst.h" +char sgszRegSig1[REG_LEN] = "REGISTRATION_BLOCK"; + + +//****************************************************************** +// random numbers +//****************************************************************** + static long sglGameSeed; + + +/*-----------------------------------------------------------------------** +** Decode RLE data without lighting +**-----------------------------------------------------------------------*/ +void DecodeFullCel (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth) +{ + long nBufferW; + app_assert(pDecodeTo != NULL); + app_assert(pRLEBytes != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDecodeTo == NULL || pRLEBytes == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + + __asm { + mov esi,dword ptr [pRLEBytes] // Source + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nWidth] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [lRLECount] + add ebx,esi + +_T1Lp1: mov edx,dword ptr [nWidth] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +**-----------------------------------------------------------------------*/ +void DrawCel (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DecodeFullCel (pTo, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +**-----------------------------------------------------------------------*/ +void DrawCelP (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW) +{ + BYTE *pFrom; + long RLELen; + + app_assert(pCelBuff != NULL); + app_assert(pBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL || pBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + DecodeFullCel (pBuff, pFrom, RLELen, nCelW); +} + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +**-----------------------------------------------------------------------*/ +void DrawSlabCel (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + DecodeFullCel(pTo, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +**-----------------------------------------------------------------------*/ +void DrawSlabCelP (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + app_assert(pBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL || pBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + DecodeFullCel(pBuff, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Decode RLE data with light translation +**-----------------------------------------------------------------------*/ +void DecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth) +{ + long nBufferW, nL; + app_assert(pDecodeTo != NULL); + app_assert(pRLEBytes != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDecodeTo == NULL || pRLEBytes == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + + __asm { + mov eax,dword ptr [nLVal]; + shl eax,8 + add eax,dword ptr [pLightTbl]; + mov dword ptr [nL],eax + + mov esi,dword ptr [pRLEBytes] // Source + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nWidth] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [lRLECount] + add ebx,esi + +_T1Lp1: mov edx,dword ptr [nWidth] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + push ebx + mov ebx,dword ptr [nL] + sub edx,eax + mov ecx,eax + + push edx + call xbytes + pop edx + + pop ebx + or edx,edx + jnz _T1Lp2 + jmp _T1Nxt + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + + jmp _done +xbytes: + + shr cl,1 + jnc xwords + + mov dl, [esi] + mov dl, [ebx+edx] + mov [edi],dl + + add esi,1 + add edi,1 + +xwords: + shr cl,1 + jnc xquads + + mov dl, [esi] + mov ch, [ebx+edx] + + mov [edi],ch + mov dl, [esi+1] + + mov ch, [ebx+edx] + mov [edi+1],ch + + add esi,2 + add edi,2 + +xquads: + test cl,cl + jz _xend + +xnext: + mov eax, [esi] + add esi,4 + + mov dl,al + mov ch,[ebx+edx] + + mov dl,ah + ror eax,16 + mov [edi],ch + + mov ch,[ebx+edx] + + mov dl,al + mov [edi+1],ch + + mov ch,[ebx+edx] + + mov dl,ah + mov [edi+2],ch + + mov ch,[ebx+edx] + mov [edi+3],ch + + add edi,4 + + dec cl + jnz xnext + +_xend: + ret + +_done: + } // end of asm block +} + +/*-----------------------------------------------------------------------** +** Decode RLE data with light translation and transparency +**-----------------------------------------------------------------------*/ +void TDecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth) +{ + long nBufferW, nL, LineVal; + app_assert(pDecodeTo != NULL); + app_assert(pRLEBytes != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDecodeTo == NULL || pRLEBytes == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + + __asm { + mov eax,dword ptr [nLVal]; + shl eax,8 + add eax,dword ptr [pLightTbl]; + mov dword ptr [nL],eax + + mov esi,dword ptr [pRLEBytes] // Source + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nWidth] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [lRLECount] + add ebx,esi + + mov eax,edi + and eax,1 + mov dword ptr [LineVal],eax + +_T1Lp1: mov edx,dword ptr [nWidth] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + push ebx + mov ebx,dword ptr [nL] + sub edx,eax + mov ecx,eax + mov eax,edi + and eax,1 + cmp eax,dword ptr [LineVal] + jnz _T1Od + shr ecx,1 + jnc _T1w + inc esi + inc edi + jecxz _T1x + jmp _T1w2 +_T1w: shr ecx,1 + jnc _T1Lp3 + inc esi + inc edi + lodsb + xlatb + stosb + jecxz _T1x +_T1Lp3: lodsd + inc edi + ror eax,8 + xlatb + stosb + ror eax,16 + inc edi + xlatb + stosb + loop _T1Lp3 + jmp _T1x + +_T1Od: shr ecx,1 + jnc _T1w2 + lodsb + xlatb + stosb + jecxz _T1x + jmp _T1w +_T1w2: shr ecx,1 + jnc _T1Lp4 + lodsb + xlatb + stosb + inc esi + inc edi + jecxz _T1x +_T1Lp4: lodsd + xlatb + stosb + inc edi + ror eax,16 + xlatb + stosb + inc edi + loop _T1Lp4 + +_T1x: pop ebx + or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + mov eax,dword ptr [LineVal] + inc eax + and eax,1 + mov dword ptr [LineVal],eax + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block +} + +/*-----------------------------------------------------------------------** +** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void DrawCelL (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + pTo = gpBuffer + nBuffWTbl[yp] + xp; + if (nLVal) + DecodeFullCelL (pTo, pFrom, RLELen, nCelW); + else + DecodeFullCel (pTo, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +/* +void DrawCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW) +{ + BYTE *pFrom; + long RLELen; + + app_assert(pCelBuff != NULL); + app_assert(pBuff != NULL); + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + if (nLVal) + DecodeFullCelL (pBuff, pFrom, RLELen, nCelW); + else + DecodeFullCel (pBuff, pFrom, RLELen, nCelW); +} +*/ + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void DrawSlabCelL (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + if (nLVal) + DecodeFullCelL (pTo, pFrom, RLELen, nCelW); + else + DecodeFullCel (pTo, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +/* +void DrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + app_assert(pBuff != NULL); + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + if (nLVal) + DecodeFullCelL (pBuff, pFrom, RLELen, nCelW); + else + DecodeFullCel (pBuff, pFrom, RLELen, nCelW); +} +*/ + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. with transparency +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void TDrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + app_assert(pBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL || pBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + if (nTrans) + TDecodeFullCelL (pBuff, pFrom, RLELen, nCelW); + else if (nLVal) + DecodeFullCelL (pBuff, pFrom, RLELen, nCelW); + else + DecodeFullCel (pBuff, pFrom, RLELen, nCelW); +} + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. With infared vision +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void DrawSlabCelI (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + long nBufferW, nL, ltaboff; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + ltaboff = light4flag ? 1024 : 4096; + if (loff == LIGHT_STONE) + ltaboff += 256; + if (loff >= LIGHT_U) + ltaboff += ((loff - LIGHT_U) << 8) + 768; + __asm { + mov eax,dword ptr [pLightTbl] + add eax,dword ptr [ltaboff] + mov dword ptr [nL],eax + + mov esi,dword ptr [pFrom] // Source + mov edi,dword ptr [pTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nCelW] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [RLELen] + add ebx,esi +_T1Lp1: + mov edx,dword ptr [nCelW] +_T1Lp2: + xor eax,eax // Load control byte + mov al,[esi] + inc esi + test al,al + js _T1J + + push ebx + mov ebx,dword ptr [nL] + sub edx,eax + mov ecx,eax +Bytes: + mov al,[esi] + inc esi + mov al,[ebx+eax] + mov [edi],al + dec ecx + lea edi,[edi+1] + jnz Bytes + + pop ebx + test edx,edx + jz _T1Nxt + jmp _T1Lp2 +_T1J: + neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: + sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Decode RLE data without lighting, with clipping +**-----------------------------------------------------------------------*/ +void CDecodeFullCel (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth) +{ + long nBufferW; + app_assert(pDecodeTo != NULL); + app_assert(pRLEBytes != NULL); + app_assert(gpBuffer); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDecodeTo == NULL || pRLEBytes == NULL || gpBuffer == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + + __asm { + mov esi,dword ptr [pRLEBytes] // Source + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nWidth] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [lRLECount] + add ebx,esi + +_T1Lp1: mov edx,dword ptr [nWidth] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [glClipY] + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block +} + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +**-----------------------------------------------------------------------*/ +void CDrawSlabCel (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + CDecodeFullCel(pTo, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +**-----------------------------------------------------------------------*/ +void CDrawSlabCelP (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + app_assert(pBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL || pBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = *(WORD*)(pFrom + oend); + if (oend == 8) + offval2 = 0; + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + CDecodeFullCel (pBuff, pFrom, RLELen, nCelW); +} + +/*-----------------------------------------------------------------------** +** Decode RLE data with light translation and with clipping +**-----------------------------------------------------------------------*/ +void CDecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth) +{ + long nBufferW, nL; + app_assert(pDecodeTo != NULL); + app_assert(pRLEBytes != NULL); + + app_assert(gpBuffer); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDecodeTo == NULL || pRLEBytes == NULL || gpBuffer == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + __asm { + mov eax,dword ptr [nLVal]; + shl eax,8 + add eax,dword ptr [pLightTbl]; + mov dword ptr [nL],eax + + mov esi,dword ptr [pRLEBytes] // Source + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nWidth] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [lRLECount] + add ebx,esi + +_T1Lp1: mov edx,dword ptr [nWidth] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + push ebx + mov ebx,dword ptr [nL] + sub edx,eax + cmp edi,dword ptr [glClipY] + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: mov ecx,eax + + push edx + call xbytes + pop edx + +_T1x: pop ebx + or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + + jmp _done + +xbytes: + + shr cl,1 + jnc xwords + + mov dl, [esi] + mov dl, [ebx+edx] + mov [edi],dl + + add esi,1 + add edi,1 + +xwords: + shr cl,1 + jnc xquads + + mov dl, [esi] + mov ch, [ebx+edx] + + mov [edi],ch + mov dl, [esi+1] + + mov ch, [ebx+edx] + mov [edi+1],ch + + add esi,2 + add edi,2 + +xquads: + test cl,cl + jz _xend + +xnext: + mov eax, [esi] + add esi,4 + + mov dl,al + mov ch,[ebx+edx] + + mov dl,ah + ror eax,16 + mov [edi],ch + + mov ch,[ebx+edx] + + mov dl,al + mov [edi+1],ch + + mov ch,[ebx+edx] + + mov dl,ah + mov [edi+2],ch + + mov ch,[ebx+edx] + mov [edi+3],ch + + add edi,4 + + dec cl + jnz xnext + +_xend: + ret +_done: + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Decode RLE data with light translation and with clipping and transparency +**-----------------------------------------------------------------------*/ +void TCDecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth) +{ + long nBufferW, nL, LineVal; + app_assert(pDecodeTo != NULL); + app_assert(pRLEBytes != NULL); + + app_assert(gpBuffer); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDecodeTo == NULL || pRLEBytes == NULL || gpBuffer == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + __asm { + mov eax,dword ptr [nLVal]; + shl eax,8 + add eax,dword ptr [pLightTbl]; + mov dword ptr [nL],eax + + mov esi,dword ptr [pRLEBytes] // Source + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nWidth] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [lRLECount] + add ebx,esi + + mov eax,edi + and eax,1 + mov dword ptr [LineVal],eax + +_T1Lp1: mov edx,dword ptr [nWidth] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + push ebx + mov ebx,dword ptr [nL] + sub edx,eax + cmp edi,dword ptr [glClipY] + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: mov ecx,eax + mov eax,edi + and eax,1 + cmp eax,dword ptr [LineVal] + jnz _T1Od + shr ecx,1 + jnc _T1w + inc esi + inc edi + jecxz _T1x + jmp _T1w2 +_T1w: shr ecx,1 + jnc _T1Lp3 + inc esi + inc edi + lodsb + xlatb + stosb + jecxz _T1x +_T1Lp3: lodsd + inc edi + ror eax,8 + xlatb + stosb + ror eax,16 + inc edi + xlatb + stosb + loop _T1Lp3 + jmp _T1x + +_T1Od: shr ecx,1 + jnc _T1w2 + lodsb + xlatb + stosb + jecxz _T1x + jmp _T1w +_T1w2: shr ecx,1 + jnc _T1Lp4 + lodsb + xlatb + stosb + inc esi + inc edi + jecxz _T1x +_T1Lp4: lodsd + xlatb + stosb + inc edi + ror eax,16 + xlatb + stosb + inc edi + loop _T1Lp4 + +_T1x: pop ebx + or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + mov eax,dword ptr [LineVal] + inc eax + and eax,1 + mov dword ptr [LineVal],eax + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void CDrawSlabCelL (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = *(WORD*)(pFrom + oend); + if (oend == 8) + offval2 = 0; + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + if (nLVal) + CDecodeFullCelL(pTo, pFrom, RLELen, nCelW); + else + CDecodeFullCel(pTo, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +/* +void CDrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = *(WORD*)(pFrom + oend); + if (oend == 8) + offval2 = 0; + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + if (nLVal) + CDecodeFullCelL (pBuff, pFrom, RLELen, nCelW); + else + CDecodeFullCel (pBuff, pFrom, RLELen, nCelW); +} +*/ + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. +** +** *pBuff = pointer to destination x,y in offscreen buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void TCDrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pFrom; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = *(WORD*)(pFrom + oend); + if (oend == 8) + offval2 = 0; + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + if (nTrans) + TCDecodeFullCelL (pBuff, pFrom, RLELen, nCelW); + else if (nLVal) + CDecodeFullCelL (pBuff, pFrom, RLELen, nCelW); + else + CDecodeFullCel (pBuff, pFrom, RLELen, nCelW); +} + + +/*-----------------------------------------------------------------------** +** Draws a 5 offset slab cel in a cel file RAM buffer. With infared vision and clipping +** +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void CDrawSlabCelI (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + long nBufferW, nL, ltaboff; + + app_assert(gpBuffer); + app_assert(pCelBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel); + offval = *(WORD*)(pFrom + ostart); + if (!offval) + return; + RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel); + offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend); + RLELen = offval2 ? offval2 - offval : RLELen - offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + ltaboff = light4flag ? 1024 : 4096; + if (loff == LIGHT_STONE) + ltaboff += 256; + if (loff >= LIGHT_U) + ltaboff += ((loff - LIGHT_U) << 8) + 768; + nL = (long)(pLightTbl + ltaboff); + nBufferW = 768 + nCelW; // Increase width + __asm { + mov esi,[pFrom] // Source + mov edi,[pTo] // Dest + + mov ecx,[RLELen] + add ecx,esi +_T1Lp1: + push ecx + mov edx,[nCelW] + xor ecx,ecx +_T1Lp2: + xor eax,eax // Load control byte + mov al,[esi] + inc esi + test al,al + js _T1J + + mov ebx,[nL] + sub edx,eax + cmp edi,[glClipY] + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: + mov cl,[esi] + inc esi + mov cl,[ebx+ecx] + mov [edi],cl + dec eax + lea edi,[edi+1] + jnz _T1C1 +_T1x: + test edx,edx + jz _T1Nxt + jmp _T1Lp2 +_T1J: + neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: + pop ecx + sub edi,dword ptr [nBufferW] + cmp ecx,esi + jnz _T1Lp1 + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel +** +** pBuff = Buffer to draw in +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** nBuffW = Width of the buffer +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +**-----------------------------------------------------------------------*/ +void DrawBuffCel(BYTE *pBuff, long xp, long yp, long nBuffW, BYTE *pCelBuff, long nCel, long nCelW) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen; + app_assert(pCelBuff != NULL); + app_assert(pBuff != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL || pBuff == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + + __asm { + mov ebx,dword ptr [pCelBuff] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + mov eax,dword ptr [pCelBuff] + add eax,dword ptr [ebx] + mov dword ptr [pFrom],eax + } + pTo = pBuff + (nBuffW * yp) + xp; + __asm { + mov esi,dword ptr [pFrom] // Source + mov edi,dword ptr [pTo] // Dest + + mov eax,dword ptr [nBuffW] // Increase width + add eax,dword ptr [nCelW] + mov dword ptr [nBuffW],eax + + mov ebx,dword ptr [RLELen] + add ebx,esi + +_T1Lp1: mov edx,dword ptr [nCelW] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBuffW] + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Makes a mask outline of a 5 offset slab cel in a cel file RAM buffer +** +** ocolor = Color to outline object with +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void OutlineSlabCel(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + long nBufferW; + app_assert(pCelBuff != NULL); + app_assert(gpBuffer); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL || gpBuffer == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + + __asm { + mov ebx,dword ptr [pCelBuff] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + mov edx,dword ptr [pCelBuff] + add edx,dword ptr [ebx] + mov dword ptr [pFrom],edx + add edx,dword ptr [ostart] + xor eax,eax + mov ax,word ptr [edx] + mov dword ptr [offval],eax + mov edx,dword ptr [pFrom] + add edx,dword ptr [oend] + mov ax,word ptr [edx] + mov dword ptr [offval2],eax + } + if (offval != 0) { + if (oend == 8) offval2 = 0; + if (offval2 != 0) RLELen = offval2 - offval; + else RLELen -= offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + __asm { + mov esi,dword ptr [pFrom] // Source + mov edi,dword ptr [pTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nCelW] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [RLELen] + add ebx,esi + +_T1Lp1: mov edx,dword ptr [nCelW] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + mov ecx,eax + mov ah,byte ptr [ocolor] +_T1Lp3: lodsb + or al,al + jz _T1Skip + mov byte ptr [edi-768],ah + mov byte ptr [edi-1],ah + mov byte ptr [edi+1],ah + mov byte ptr [edi+768],ah +_T1Skip: inc edi + loop _T1Lp3 + or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block + } +} + +/*-----------------------------------------------------------------------** +** Makes a mask outline of a 5 offset slab cel in a cel file RAM buffer. With clipping +** +** ocolor = Color to outline object with +** xp = Left X pixel position in offscreen buffer to draw to +** yp = Bottom Y pixel position in offscreen buffer to draw to +** *pCelBuff = pointer to cel file RAM buffer +** nCel = Cel number to draw in cel file (start with 1!!!!) +** nCelW = width of cel to draw +** nLVal = light value +**-----------------------------------------------------------------------*/ +void COutlineSlabCel(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE *pTo; + BYTE *pFrom; + long RLELen, offval, offval2; + long nBufferW; + app_assert(pCelBuff != NULL); + app_assert(gpBuffer); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pCelBuff == NULL || gpBuffer == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + + __asm { + mov ebx,dword ptr [pCelBuff] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + mov edx,dword ptr [pCelBuff] + add edx,dword ptr [ebx] + mov dword ptr [pFrom],edx + add edx,dword ptr [ostart] + xor eax,eax + mov ax,word ptr [edx] + mov dword ptr [offval],eax + mov edx,dword ptr [pFrom] + add edx,dword ptr [oend] + mov ax,word ptr [edx] + mov dword ptr [offval2],eax + } + if (offval != 0) { + if (oend == 8) offval2 = 0; + if (offval2 != 0) RLELen = offval2 - offval; + else RLELen -= offval; + pFrom += offval; + pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + __asm { + mov esi,dword ptr [pFrom] // Source + mov edi,dword ptr [pTo] // Dest + + mov eax,768 // Increase width + add eax,dword ptr [nCelW] + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [RLELen] + add ebx,esi + +_T1Lp1: mov edx,dword ptr [nCelW] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + mov ecx,dword ptr [glClipY] + cmp edi,ecx + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: sub ecx,768 + cmp edi,ecx + jae _T1C2 + mov ecx,eax + mov ah,byte ptr [ocolor] +_T1Lp3: lodsb + or al,al + jz _T1Skip + mov byte ptr [edi-768],ah + mov byte ptr [edi-1],ah + mov byte ptr [edi+1],ah + mov byte ptr [edi+768],ah +_T1Skip: inc edi + loop _T1Lp3 + jmp _T1x + +_T1C2: mov ecx,eax + mov ah,byte ptr [ocolor] +_T1Lp4: lodsb + or al,al + jz _T1Skip2 + mov byte ptr [edi-768],ah + mov byte ptr [edi-1],ah + mov byte ptr [edi+1],ah +_T1Skip2: inc edi + loop _T1Lp4 + +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + } // end of asm block + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +void TranslateCels(byte *p, byte *ttbl, int nf) + +{ + int j; + app_assert(p != NULL); + app_assert(ttbl != NULL); + + for (j = 1; j <= nf; j++) { + __asm { + mov ebx,dword ptr [p] + mov eax,dword ptr [j] + shl eax,2 + add ebx,eax + mov esi,dword ptr [p] + add esi,dword ptr [ebx] + add esi,10 // Source + + mov edx,dword ptr [ebx+4] // Size + sub edx,dword ptr [ebx] + sub edx,10 + + mov edi,esi // Dest + + mov ebx,dword ptr [ttbl] // Color conversion table + +_TLp1: xor eax,eax // Load control byte + lodsb + stosb + dec edx + jz _TNxt + or al,al + js _TLp1 + + sub edx,eax + mov ecx,eax +_TLp2: lodsb + xlatb + stosb + loop _TLp2 + or edx,edx + jnz _TLp1 + +_TNxt: nop + } + } +} +#endif + + +/*-----------------------------------------------------------------------** +** Plot a point +**-----------------------------------------------------------------------*/ +void DrawPoint(int x, int y, byte c) +{ + BYTE *pTo; + + app_assert(gpBuffer); + if ((y < 0) || (y >= 640)) return; + if ((x < 64) || (x >= 704)) return; + pTo = gpBuffer + nBuffWTbl[y] + x; + __asm { + mov edi, dword ptr [pTo]; + cmp edi, dword ptr [glClipY] + jae _NoD + mov al, byte ptr [c] + mov byte ptr [edi], al +_NoD: + } +} + +/*-----------------------------------------------------------------------** +** For line drawing +**-----------------------------------------------------------------------*/ +#define dlswap(a,b) { a^=b; b^=a; a^=b; } +#define absolute(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1))) + +int dlreverse; +byte dlcolor; +BOOL dlclipflag; + + +/*-----------------------------------------------------------------------** +** plot for line drawing (temp probably, will write in asm) +**-----------------------------------------------------------------------*/ +void plot(int x, int y) +{ + BYTE *pTo; + + app_assert(gpBuffer); + if (dlreverse) { + if (dlclipflag) { + if ((x < 0) || (x >= 640)) return; + if ((y < 64) || (y >= 704)) return; + } + pTo = gpBuffer + nBuffWTbl[x] + y; + } else { + if (dlclipflag) { + if ((y < 0) || (y >= 640)) return; + if ((x < 64) || (x >= 704)) return; + } + pTo = gpBuffer + nBuffWTbl[y] + x; + } + __asm { + mov edi, dword ptr [pTo]; + cmp edi,dword ptr [glClipY] + jae _NoD + mov al,byte ptr [dlcolor] + mov byte ptr [edi],al +_NoD: + } +} + + +/*-----------------------------------------------------------------------** +** line drawing ctrl (temp probably, will write in asm) +**-----------------------------------------------------------------------*/ +void DrawLine(int a1, int b1, int a2, int b2, byte clr) +{ + int dx, dy, incr1, incr2, D, x, y, _xend, c, pixels_left; + int x1, y1; + int sign_x, sign_y, step, i; + + dlcolor = clr; + + // Test clipping bounds to see if we even need to test on the pixel level + dlclipflag = FALSE; + if ((a1 < 64) || (a1 >= 704)) dlclipflag = TRUE; + if ((a2 < 64) || (a2 >= 704)) dlclipflag = TRUE; + if ((b1 < 160) || (b1 >= 512)) dlclipflag = TRUE; + if ((b2 < 160) || (b2 >= 512)) dlclipflag = TRUE; + + dx = absolute(a2, a1, sign_x); + dy = absolute(b2, b1, sign_y); + + if (sign_x == sign_y) + step = 1; + else + step = -1; + + if (dy > dx) { + dlswap(a1, b1); + dlswap(a2, b2); + dlswap(dx, dy); + dlreverse = 1; + } else + dlreverse = 0; + + if (a1 > a2) { + x = a2; + y = b2; + x1 = a1; + y1 = b1; + } else { + x = a1; + y = b1; + x1 = a2; + y1 = b2; + } + + _xend = (dx - 1) / 4; + pixels_left = (dx - 1) % 4; + + plot(x, y); + plot(x1, y1); + incr2 = 4 * dy - 2 * dx; + if (incr2 < 0) { + c = 2 * dy; + incr1 = 2 * c; + D = incr1 - dx; + + for (i = 0; i < _xend; i++) { + ++x; + --x1; + if (D < 0) { + plot(x, y); + plot(++x, y); + plot(x1, y1); + plot(--x1, y1); + D += incr1; + } else { + if (D < c) { + plot(x, y); + plot(++x, y += step); + plot(x1, y1); + plot(--x1, y1 -= step); + } else { + plot(x, y += step); + plot(++x, y); + plot(x1, y1 -= step); + plot(--x1, y1); + } + D += incr2; + } + } + + if (pixels_left) { + if (D < 0) { + plot(++x, y); + if (pixels_left > 1) + plot(++x, y); + if (pixels_left > 2) + plot(--x1, y1); + } else { + if (D < c) { + plot(++x, y); + if (pixels_left > 1) + plot(++x, y += step); + if (pixels_left > 2) + plot(--x1, y1); + } else { + plot(++x, y += step); + if (pixels_left > 1) + plot(++x, y); + if (pixels_left > 2) + plot(--x1, y1 -= step); + } + } + } + } else { + c = 2 * (dy - dx); + incr1 = 2 * c; + D = incr1 + dx; + for (i = 0; i < _xend; i++) { + ++x; + --x1; + if (D > 0) { + plot(x, y += step); + plot(++x, y += step); + plot(x1, y1 -= step); + plot(--x1, y1 -= step); + D += incr1; + } else { + if (D < c) { + plot(x, y); + plot(++x, y += step); + plot(x1, y1); + plot(--x1, y1 -= step); + } else { + plot(x, y += step); + plot(++x, y); + plot(x1, y1 -= step); + plot(--x1, y1); + } + D += incr2; + } + } + + if (pixels_left) { + if (D > 0) { + plot(++x, y += step); + if (pixels_left > 1) + plot(++x, y += step); + if (pixels_left > 2) + plot(--x1, y1 -= step); + } else { + if (D < c) { + plot(++x, y); + if (pixels_left > 1) + plot(++x, y += step); + if (pixels_left > 2) + plot(--x1, y1); + } else { + plot(++x, y += step); + if (pixels_left > 1) + plot(++x, y); + if (pixels_left > 2) { + if (D > c) + plot(--x1, y1 -= step); + else + plot(--x1, y1); + } + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +int GetDirection(int x1, int y1, int x2, int y2) +{ + int mx, my, md; + + mx = x2-x1; + my = y2-y1; + if (mx >= 0) { + if (my >= 0) { + md = 0; + if ((mx << 1) < my) md = 1; + if ((my << 1) < mx) md = 7; + } else { + md = 6; + my = -my; + if ((mx << 1) < my) md = 5; + if ((my << 1) < mx) md = 7; + } + } else { + if (my >= 0) { + md = 2; + mx = -mx; + if ((mx << 1) < my) md = 1; + if ((my << 1) < mx) md = 3; + } else { + md = 4; + mx = -mx; + my = -my; + if ((mx << 1) < my) md = 5; + if ((my << 1) < mx) md = 3; + } + } + return (md); +} + +int SeedCount; +long orgseed; + +//*************************************************************************** +//*************************************************************************** +void SetRndSeed(long s) { + sglGameSeed = s; + orgseed = s; //debug + SeedCount = 0; +} + +//*************************************************************************** +//*************************************************************************** +long GetRndSeed() { + SeedCount++; + static const DWORD INCREMENT = 1; + static const DWORD MULTIPLIER = 0x015a4e35L; + sglGameSeed = MULTIPLIER * sglGameSeed + INCREMENT; + return abs(sglGameSeed); +} + + +//*************************************************************************** +//*************************************************************************** +long random(byte idx,long v) { + if (v <= 0) return 0; + + // high order bits are more "random" than low order bits + if (v < 0x0ffff) return (GetRndSeed() >> 16) % v; + + return GetRndSeed() % v; +} + + +//****************************************************************** +// memory manager vars +//****************************************************************** +#define TRACK_MEM_BLOCKS 1 // 0 in final +#if DEBUG_MEM +#define DUMP_MEM_BLOCKS 1 // 0 in final +#else +#define DUMP_MEM_BLOCKS 0 // 0 in final +#endif +#ifdef NDEBUG +#undef TRACK_MEM_BLOCKS +#undef DUMP_MEM_BLOCKS +#define TRACK_MEM_BLOCKS 0 +#define DUMP_MEM_BLOCKS 0 +#endif + +#if DEBUG_MEM && TRACK_MEM_BLOCKS +typedef struct TMemType { + struct TMemType * pNext; + DWORD dwSig; + + // current amount of memory allocated with this signature + DWORD dwCurrAmount; + + // maximum amount ever allocated for this signature + DWORD dwMostEver; + + // amount of memory allocated to this signature when the + // program had its maximum memory allocated + DWORD dwAmountAtMax; +} TMemType; + +typedef union TPrintSig { + DWORD dwSig; + char szSig[sizeof(DWORD) + 1]; +} TPrintSig; + +static DWORD sgdwCurrAllocated = 0; +static DWORD sgdwHighestAllocated = 0; +static TMemType * sgpMemTypeHead = NULL; + +typedef struct TMemBlockHdr { + DWORD dwBytes; + DWORD dwSig; + DWORD dwCheck1; + DWORD dwCheck2; +} TMemBlockHdr; +typedef struct TMemBlockFtr { + DWORD dwCheck3; + DWORD dwCheck4; +} TMemBlockFtr; + +#define MEM_CHECK1 0x497208ab +#define MEM_CHECK2 0x127834dc +#define MEM_CHECK3 0x023481a9 +#define MEM_CHECK4 0xfcb87147 + +#endif + +// serialize access to memory manager -- according to Mike O'Brien, +// malloc does not serialize access in all cases in NT 4.0 even +// when using LIBCMT.LIB. Therefore, don't trust *any* memory munger +static CCritSect sgMemCrit; + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM && TRACK_MEM_BLOCKS +static const char * sig_to_string(DWORD dwSig,TPrintSig * pSig) { + __asm mov eax, dwSig + __asm bswap eax + __asm mov dwSig, eax + pSig->dwSig = dwSig; + pSig->szSig[sizeof(DWORD)] = 0; + return pSig->szSig; + +} +#endif + + +//****************************************************************** +//****************************************************************** +void mem_cleanup(BOOL bNormalExit) { +#if DEBUG_MEM && TRACK_MEM_BLOCKS + // serialize access to memory manager -- according to Mike O'Brien, + // malloc does not serialize access in all cases in NT 4.0 even + // when using LIBCMT.LIB. Therefore, don't trust *any* memory munger + sgMemCrit.Enter(); + + FILE * f = NULL; + + #if DUMP_MEM_BLOCKS + if (bNormalExit) f = fopen("c:\\memdump.txt","wb"); + #endif + + if (f) { + fprintf( + f, + "sig most ever amount at max at end of game\r\n" + "------------------------------------------------------\r\n" + ); + } + + TMemType * pNext = NULL; + for (TMemType * pType = sgpMemTypeHead; pType; pType = pNext) { + if (f) { + TPrintSig sig; + fprintf( + f, + "%4s 0x%08x 0x%08x %8dk %8d\r\n", + sig_to_string(pType->dwSig,&sig), + pType->dwMostEver, + pType->dwAmountAtMax, + pType->dwAmountAtMax / 1024, + pType->dwCurrAmount + ); + } + + pNext = pType->pNext; + SMemFree(pType,__FILE__,__LINE__); + } + + if (f) { + fprintf( + f, + "------------------------------------------------\r\n" + "max allocated 0x%08x %8dk\r\n", + sgdwHighestAllocated, + sgdwHighestAllocated / 1024 + ); + fclose(f); + } + + sgMemCrit.Leave(); +#endif +} + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM && TRACK_MEM_BLOCKS +static TMemType * find_mem_type_by_sig(DWORD dwSig) { + // find existing block with signature + for (TMemType * pType = sgpMemTypeHead; pType; pType = pType->pNext) + if (pType->dwSig == dwSig) return pType; + + // create a new signature block + pType = (TMemType *) SMemAlloc(sizeof(TMemType),__FILE__,__LINE__); + ZeroMemory(pType,sizeof TMemType); + pType->dwSig = dwSig; + + // link to list + pType->pNext = sgpMemTypeHead; + sgpMemTypeHead = pType; + + // return new signature block + return pType; +} +#endif + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM && TRACK_MEM_BLOCKS +static void mem_addto_type(TMemType * pType,DWORD dwBytes) { + // fixup memory for this type + pType->dwCurrAmount += dwBytes; + if (pType->dwMostEver < pType->dwCurrAmount) + pType->dwMostEver = pType->dwCurrAmount; + + // fixup memory for all types + sgdwCurrAllocated += dwBytes; + if (sgdwHighestAllocated < sgdwCurrAllocated) { + sgdwHighestAllocated = sgdwCurrAllocated; + for (TMemType * pHigh = sgpMemTypeHead; pHigh; pHigh = pHigh->pNext) + pHigh->dwAmountAtMax = pHigh->dwCurrAmount; + } +} +#endif + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM && TRACK_MEM_BLOCKS +static const char * mem_freefrom_type(TMemType * pType,DWORD dwBytes) { + // fixup memory for this type + DWORD dwTemp = pType->dwCurrAmount; + pType->dwCurrAmount -= dwBytes; + if (pType->dwCurrAmount > dwTemp) + return "memory block signature underflow: %s"; + + // fixup global memory indicator + dwTemp = sgdwCurrAllocated; + sgdwCurrAllocated -= dwBytes; + if (sgdwCurrAllocated > dwTemp) + return "memory free underflow"; + + return NULL; +} +#endif + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM +void mem_use_sig(DWORD dwSig,DWORD dwBytes) { +#if TRACK_MEM_BLOCKS + TMemType * pType = find_mem_type_by_sig(dwSig); + if (! pType) ErrorDlg(IDD_MEM_ERR,GetLastError(),__FILE__,__LINE__); + + mem_addto_type(pType,dwBytes); +#endif +} + + +//****************************************************************** +//****************************************************************** +void mem_unuse_sig(DWORD dwSig,DWORD dwBytes) { +#if TRACK_MEM_BLOCKS + const char * pszErr_s; + TMemType * pType = find_mem_type_by_sig(dwSig); + if (pType) + pszErr_s = mem_freefrom_type(pType,dwBytes); + else + pszErr_s = "Bad signature unused: %s"; + + TPrintSig sig; + if (pszErr_s) app_fatal(pszErr_s,sig_to_string(dwSig,&sig)); +#endif +} +#endif + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM +BYTE * mem_malloc_dbg(DWORD dwBytes,DWORD dwSig,DWORD dwLine,const TCHAR * pszFile) +#else +BYTE * DiabloAllocPtr(DWORD dwBytes) +#endif +{ + // serialize access to memory manager -- according to Mike O'Brien, + // malloc does not serialize access in all cases in NT 4.0 even + // when using LIBCMT.LIB. Therefore, don't trust *any* memory munger + sgMemCrit.Enter(); + + // allocate memory block + #if DEBUG_MEM && TRACK_MEM_BLOCKS + DWORD dwAlloc = dwBytes + sizeof(TMemBlockHdr) + sizeof(TMemBlockFtr); + + BYTE * rv = (BYTE *) SMemAlloc(dwAlloc,pszFile,dwLine); + #elif DEBUG_MEM + BYTE * rv = (BYTE *) SMemAlloc(dwBytes,pszFile,dwLine); + #else + BYTE * rv = (BYTE *) SMemAlloc(dwBytes,__FILE__,__LINE__); + #endif + + #if DEBUG_MEM && TRACK_MEM_BLOCKS + if (rv) { + TMemType * pType = find_mem_type_by_sig(dwSig); + if (pType) { + mem_addto_type(pType,dwBytes); + + TMemBlockHdr * pHdr = (TMemBlockHdr *) rv; + rv += sizeof(TMemBlockHdr); + TMemBlockFtr * pFtr = (TMemBlockFtr *) (rv + dwBytes); + + pHdr->dwSig = dwSig; + pHdr->dwBytes = dwBytes; + pHdr->dwCheck1 = MEM_CHECK1; + pHdr->dwCheck2 = MEM_CHECK2; + + pFtr->dwCheck3 = MEM_CHECK3; + pFtr->dwCheck4 = MEM_CHECK4; + } + else { + SMemFree(rv,__FILE__,__LINE__); + rv = NULL; + } + } + #endif + + sgMemCrit.Leave(); + + #if DEBUG_MEM + if (! rv) ErrorDlg(IDD_MEM_ERR,GetLastError(),pszFile,dwLine); + #else + if (! rv) ErrorDlg(IDD_MEM_ERR,GetLastError(),__FILE__,__LINE__); + #endif + + return rv; +} + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM +void mem_free_dbg(void * p,DWORD dwLine,const TCHAR * pszFile) +#else +void mem_free_dbg(void * p) +#endif +{ + if (! p) return; + + // serialize access to memory manager -- according to Mike O'Brien, + // malloc does not serialize access in all cases in NT 4.0 even + // when using LIBCMT.LIB. Therefore, don't trust *any* memory munger + sgMemCrit.Enter(); + + // free memory block +#if DEBUG_MEM && TRACK_MEM_BLOCKS + const char * pszErr_s = NULL; + TMemBlockHdr * pHdr = (TMemBlockHdr *) ((BYTE *) p - sizeof(TMemBlockHdr)); + DWORD dwSig = pHdr->dwSig; // assume signature is valid + if (pHdr->dwCheck1 != MEM_CHECK1 || pHdr->dwCheck2 != MEM_CHECK2) + pszErr_s = "Memory block header corruption: %s"; + else { + // Now change it so if there is duplicate free we'll catch it. + pHdr->dwCheck1 = 0xDEADC0DE; + pHdr->dwCheck2 = 0xDEADC0DE; + } + + if (! pszErr_s) { + TMemBlockFtr * pFtr = (TMemBlockFtr *) ((BYTE *) p + pHdr->dwBytes); + if (pFtr->dwCheck3 != MEM_CHECK3 || pFtr->dwCheck4 != MEM_CHECK4) + pszErr_s = "Memory block footer corruption: %s"; + else { + // Now change it so if there is duplicate free we'll catch it. + pFtr->dwCheck3 = 0xDEADC0DE; + pFtr->dwCheck4 = 0xDEADC0DE; + } + } + if (! pszErr_s) { + TMemType * pType = find_mem_type_by_sig(dwSig); + if (pType) + pszErr_s = mem_freefrom_type(pType,pHdr->dwBytes); + else + pszErr_s = "Attempt to free memory with unknown signature %s"; + } + + p = (void *) pHdr; + SMemFree(p,pszFile,dwLine); +#elif DEBUG_MEM + SMemFree(p,pszFile,dwLine); +#else + SMemFree(p,__FILE__,__LINE__); +#endif + + sgMemCrit.Leave(); + + // display any error which occurred -- outside critical section + #if DEBUG_MEM && TRACK_MEM_BLOCKS + if (pszErr_s) { + TPrintSig sig; + app_fatal(pszErr_s,sig_to_string(dwSig,&sig)); + } + #endif +} + + +//****************************************************************** +//****************************************************************** +#if DEBUG_MEM +BYTE * load_file_dbg(const char * pszName,DWORD * pdwFileLen,DWORD dwSig,DWORD dwLine,const TCHAR * pszFile) +#else +BYTE * LoadFileInMem(const char * pszName,DWORD * pdwFileLen) +#endif +{ + HSFILE hFile; + + #if DEBUG_MEM + if (! pszName) app_fatal("LoadFileInMem: %s:%d",pszFile,dwLine); + #else + app_assert(pszName); + #endif + + patSFileOpenFile(pszName,&hFile); + DWORD dwFileLen = patSFileGetFileSize(hFile,NULL); + if (pdwFileLen) *pdwFileLen = dwFileLen; + if (! dwFileLen) app_fatal("Zero length SFILE:\n%s",pszName); + + #if DEBUG_MEM + BYTE * pbMem = mem_malloc_dbg(dwFileLen,dwSig,dwLine,pszFile); + #else + BYTE * pbMem = DiabloAllocPtr(dwFileLen); + #endif + + patSFileReadFile(hFile,pbMem,dwFileLen); + patSFileCloseFile(hFile); + return pbMem; +} + + +//****************************************************************** +//****************************************************************** +DWORD LoadFileWithMem(const char * pszName,BYTE * pbMem) { + HSFILE hFile; + + app_assert(pszName); + if (! pbMem) app_fatal("LoadFileWithMem(NULL):\n%s",pszName); + + patSFileOpenFile(pszName,&hFile); + DWORD dwFileLen = patSFileGetFileSize(hFile,NULL); + if (! dwFileLen) app_fatal("Zero length SFILE:\n%s",pszName); + patSFileReadFile(hFile,pbMem,dwFileLen); + patSFileCloseFile(hFile); + return dwFileLen; +} + + +//************************************************************* +// RLE Unitdraw Code +//************************************************************* +#if RLE_DRAW + #define MAX_RLE_COPY 65 + static int sgnWidth; //used in both RLEDrawLitUnit f'cns +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void TranslateCels(BYTE *p, BYTE *ttbl, int nFrames) +{ + app_assert(p != NULL); + app_assert(ttbl != NULL); + + int nDataSize; + BYTE * pImage; + char bBlock; + for (int j = 1; j <= nFrames; j++) { + pImage = p + ((DWORD*)p)[j] + sizeof(WORD)*5; + nDataSize = ((DWORD*)p)[j+1] - ((DWORD*)p)[j] - sizeof(WORD)*5; + while (nDataSize) { + bBlock = *pImage++; + nDataSize--; + app_assert(nDataSize >= 0); + //check for skip + if (bBlock >= 0) + continue; + bBlock = -bBlock; + //check for run + if (bBlock > MAX_RLE_COPY) { + bBlock -= MAX_RLE_COPY; + nDataSize--; + app_assert(nDataSize >= 0); + *pImage = ttbl[*pImage++]; + continue; + } + //do copy + nDataSize -= bBlock; + app_assert(nDataSize >= 0); + while (bBlock--) + *pImage = ttbl[*pImage++]; + } + } +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +static void RLEDrawUnit(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth) { + _asm { + //**** Assumes _fastcall convention!! **** + push ebx + push esi + push edi + + //eax - copy/run/skip block size + //ebx - pixels left to draw this line + //ecx - bytes of RLE data left + //edx - scratch + //esi - source RLE data + //edi - destination buffer + + mov esi, edx + mov edi, ecx + + xor eax, eax + mov ebx, [nWidth] + mov ecx, [nDataSize] + +Loop1: + mov al,[esi] + inc esi + dec ecx + + //negative packets are copy/runs, nonnegative are skips + test al,al + jns SkipLoop + + neg al + //packets larger than MAX_RLE_COPY are runs, rest are copies + cmp al,MAX_RLE_COPY + jle Copy + + //get size of run + sub al,MAX_RLE_COPY + dec ecx + + //write out run packet + mov dl,[esi] + inc esi + sub ebx,eax +RunMemset: + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz RunMemset + jmp EOLTest + +Copy: + //write out copy packet + sub ecx,eax + sub ebx,eax +CopyMemcpy: + mov dl,[esi] + inc esi + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz CopyMemcpy + +EOLTest: + //if at end of line, move dst and reset linecounter + test ebx,ebx + jnz NextBlock + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx + jmp NextBlock + +SkipLoop: + //does skip extend past end of this line? + cmp eax,ebx + jle SingleLineSkip + mov edx,ebx + add edi,ebx + sub eax,ebx + jmp SkipMem +SingleLineSkip: + mov edx,eax + add edi,eax + xor eax,eax +SkipMem: + //if at end of line, move dst and reset linecounter + sub ebx,edx + jnz SkipNotEOL + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx +SkipNotEOL: + //have we finished off this block? (skips may span multiple lines) + test eax,eax + jnz SkipLoop + +NextBlock: + test ecx,ecx + jnz Loop1 + + pop edi + pop esi + pop ebx + } +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +static void RLEDrawOutline(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE bOutLineColor) { + _asm { + //**** Assumes _fastcall convention!! **** + push ebx + push esi + push edi + + //eax - copy/run/skip block size + //ebx - pixels left to draw this line + //ecx - bytes of RLE data left + //dl - outline color + //dh - scratch + //esi - source RLE data + //edi - destination buffer + + mov esi,edx + mov edi,ecx + + xor eax,eax + mov ebx,[nWidth] + xor edx,edx + mov ecx,[nDataSize] + mov dl, [bOutLineColor] + +Loop1: + mov al,[esi] + inc esi + dec ecx + + //negative packets are copy/runs, nonnegative are skips + test al,al + jns SkipLoop + + neg al + //packets larger than MAX_RLE_COPY are runs, rest are copies + cmp al,MAX_RLE_COPY + jle Copy + + //get size of run + sub al,MAX_RLE_COPY + dec ecx + + //no outline for color zero (shadows) + mov dh,[esi] + inc esi + test dh,dh + jz SkipLoop + + //write outline for run packet + mov [edi-1],dl //outline pixel left + sub ebx,eax + mov [edi+eax],dl //and right of run +RunMemset: + mov [edi-BUFFERX],dl //outline above + mov [edi+BUFFERX],dl //and below run + dec eax + lea edi,[edi+1] + jnz RunMemset + jmp EOLCheck + +Copy: + sub ecx,eax + sub ebx,eax +CopyMemcpy: + mov dh,[esi] + inc esi + //don't draw outline for shadow pixels + test dh,dh + jz SkipPixel + + mov [edi-1],dl //outline pixel left + mov [edi+1],dl //and right of copy + mov [edi-BUFFERX],dl //outline above + mov [edi+BUFFERX],dl //and below copy +SkipPixel: + dec eax + lea edi,[edi+1] + jnz CopyMemcpy + +EOLCheck: + //if at end of line, move dst and reset linecounter + test ebx,ebx + jnz NextBlock + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx + jmp NextBlock + +SkipLoop: + cmp eax,ebx + jle SingleLineSkip + mov edx,ebx + add edi,ebx + sub eax,ebx + jmp SkipMem +SingleLineSkip: + mov edx,eax + add edi,eax + xor eax,eax +SkipMem: + //if at end of line, move dst and reset linecounter + sub ebx,edx + jnz SkipNotEOL + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx +SkipNotEOL: + //have we finished off this block? + test eax,eax + jnz SkipLoop + mov dl, [bOutLineColor] + +NextBlock: + test ecx,ecx + jnz Loop1 + + pop edi + pop esi + pop ebx + } +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +static void RLEDrawLitUnit(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE * pLightTable) { + _asm { + //**** Assumes _fastcall convention!! **** + push ebx + push esi + push edi + + //eax - copy/run/skip block size + //ebx - pixels left to draw this line + //ecx - bytes of RLE data left + //edx - scratch + //ebp - light table pointer + //esi - source RLE data + //edi - destination buffer + + mov esi, edx + mov edi, ecx + + mov ebx, [nWidth] + mov ecx, [nDataSize] + mov edx, [pLightTable] + push ebp + mov [sgnWidth],ebx //cheesy way to avoid using ebp + mov ebp,edx + xor eax,eax + xor edx,edx + +Loop1: + mov al,[esi] + inc esi + dec ecx + + //negative packets are copy/runs, nonnegative are skips + test al,al + jns SkipLoop + + neg al + //packets larger than MAX_RLE_COPY are runs, rest are copies + cmp al,MAX_RLE_COPY + jle Copy + + //get size of run + sub al,MAX_RLE_COPY + dec ecx + + //write run packet + sub ebx,eax + mov dl,[esi] + inc esi + mov dl,[ebp+edx] +RunMemset: + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz RunMemset + jmp EOLCheck + +Copy: + //write copy packet + sub ecx,eax + sub ebx,eax +CopyMemcpy: + mov dl,[esi] + inc esi + mov dl,[ebp+edx] + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz CopyMemcpy + +EOLCheck: + //if at end of line, move dst and reset linecounter + test ebx,ebx + jnz NextBlock + mov ebx,[sgnWidth] + sub edi,BUFFERX + sub edi,ebx + jmp NextBlock + +SkipLoop: + cmp eax,ebx + jle SingleLineSkip + mov edx,ebx + add edi,ebx + sub eax,ebx + jmp SkipMem +SingleLineSkip: + mov edx,eax + add edi,eax + xor eax,eax +SkipMem: + //if at end of line, move dst and reset linecounter + sub ebx,edx + jnz SkipNotEOL + mov ebx,[sgnWidth] + sub edi,BUFFERX + sub edi,ebx +SkipNotEOL: + //have we finished off this block? + test eax,eax + jnz SkipLoop + +NextBlock: + test ecx,ecx + jnz Loop1 + + pop ebp + + pop edi + pop esi + pop ebx + } +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +static void RLEDrawUnitClipped(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth) { + _asm { + //**** Assumes _fastcall convention!! **** + push ebx + push esi + push edi + + //eax - copy/run/skip block size + //ebx - pixels left to draw this line + //ecx - bytes of RLE data left + //edx - scratch + //esi - source RLE data + //edi - destination buffer + + mov esi, edx + mov edi, ecx + + xor eax, eax + mov ebx, [nWidth] + mov ecx, [nDataSize] + +Loop1: + mov al,[esi] + inc esi + dec ecx + + //negative packets are copy/runs, nonnegative are skips + test al,al + jns SkipLoop + + neg al + //packets larger than MAX_RLE_COPY are runs, rest are copies + cmp al,MAX_RLE_COPY + jle Copy + + //get size of run + sub al,MAX_RLE_COPY + dec ecx + + //prepare to write out run packet + mov dl,[esi] + inc esi + + //off end of buffer? + cmp edi,[glClipY] + jge SkipLoop + + sub ebx,eax +RunMemset: + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz RunMemset + jmp EOLTest + +Copy: + //prepare to write out copy packet + sub ecx,eax + + //off end of buffer? + cmp edi,[glClipY] + jl PreCopyMemcpy + add esi,eax + jmp SkipLoop + +PreCopyMemcpy: + sub ebx,eax +CopyMemcpy: + mov dl,[esi] + inc esi + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz CopyMemcpy + +EOLTest: + //if at end of line, move dst and reset linecounter + test ebx,ebx + jnz NextBlock + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx + jmp NextBlock + +SkipLoop: + //does skip extend past end of this line? + cmp eax,ebx + jle SingleLineSkip + mov edx,ebx + add edi,ebx + sub eax,ebx + jmp SkipMem +SingleLineSkip: + mov edx,eax + add edi,eax + xor eax,eax +SkipMem: + //if at end of line, move dst and reset linecounter + sub ebx,edx + jnz SkipNotEOL + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx +SkipNotEOL: + //have we finished off this block? (skips may span multiple lines) + test eax,eax + jnz SkipLoop + +NextBlock: + test ecx,ecx + jnz Loop1 + + pop edi + pop esi + pop ebx + } +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +static void RLEDrawOutlineClipped(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE bOutLineColor) { + _asm { + //**** Assumes _fastcall convention!! **** + push ebx + push esi + push edi + + //eax - copy/run/skip block size + //ebx - pixels left to draw this line + //ecx - bytes of RLE data left + //dl - outline color + //dh - scratch + //esi - source RLE data + //edi - destination buffer + + mov esi,edx + mov edi,ecx + + xor eax,eax + mov ebx,[nWidth] + xor edx,edx + mov ecx,[nDataSize] + mov dl, [bOutLineColor] + +Loop1: + mov al,[esi] + inc esi + dec ecx + + //negative packets are copy/runs, nonnegative are skips + test al,al + jns SkipLoop + + neg al + //packets larger than MAX_RLE_COPY are runs, rest are copies + cmp al,MAX_RLE_COPY + jle Copy + + //get size of run + sub al,MAX_RLE_COPY + dec ecx + + //no outline for color zero (shadows) + mov dh,[esi] + inc esi + test dh,dh + jz SkipLoop + + //off end of buffer? + cmp edi,[glClipY] + jge SkipLoop + + //write outline for run packet + mov [edi-1],dl //outline pixel left + sub ebx,eax + mov [edi+eax],dl //and right of run +RunMemset: + mov [edi-BUFFERX],dl //outline above + mov [edi+BUFFERX],dl //and below run + dec eax + lea edi,[edi+1] + jnz RunMemset + jmp EOLCheck + +Copy: + sub ecx,eax + + //off end of buffer? + cmp edi,[glClipY] + jl PreCopyMemcpy + add esi,eax + jmp SkipLoop + +PreCopyMemcpy: + sub ebx,eax +CopyMemcpy: + mov dh,[esi] + inc esi + //don't draw outline for shadow pixels + test dh,dh + jz SkipPixel + + mov [edi-1],dl //outline pixel left + mov [edi+1],dl //and right of copy + mov [edi-BUFFERX],dl //outline above + mov [edi+BUFFERX],dl //and below copy +SkipPixel: + dec eax + lea edi,[edi+1] + jnz CopyMemcpy + +EOLCheck: + //if at end of line, move dst and reset linecounter + test ebx,ebx + jnz NextBlock + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx + jmp NextBlock + +SkipLoop: + cmp eax,ebx + jle SingleLineSkip + mov edx,ebx + add edi,ebx + sub eax,ebx + jmp SkipMem +SingleLineSkip: + mov edx,eax + add edi,eax + xor eax,eax +SkipMem: + //if at end of line, move dst and reset linecounter + sub ebx,edx + jnz SkipNotEOL + mov ebx,[nWidth] + sub edi,BUFFERX + sub edi,ebx +SkipNotEOL: + //have we finished off this block? + test eax,eax + jnz SkipLoop + mov dl, [bOutLineColor] + +NextBlock: + test ecx,ecx + jnz Loop1 + + pop edi + pop esi + pop ebx + } +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +static void RLEDrawLitUnitClipped(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE * pLightTable) { + _asm { + //**** Assumes _fastcall convention!! **** + push ebx + push esi + push edi + + //eax - copy/run/skip block size + //ebx - pixels left to draw this line + //ecx - bytes of RLE data left + //edx - scratch + //ebp - light table pointer + //esi - source RLE data + //edi - destination buffer + + mov esi, edx + mov edi, ecx + + mov ebx, [nWidth] + mov ecx, [nDataSize] + mov edx, [pLightTable] + push ebp + mov [sgnWidth],ebx //cheesy way to avoid using ebp + mov ebp,edx + xor eax,eax + xor edx,edx + +Loop1: + mov al,[esi] + inc esi + dec ecx + + //negative packets are copy/runs, nonnegative are skips + test al,al + jns SkipLoop + + neg al + //packets larger than MAX_RLE_COPY are runs, rest are copies + cmp al,MAX_RLE_COPY + jle Copy + + //get size of run + sub al,MAX_RLE_COPY + dec ecx + + //prepare to write run packet + mov dl,[esi] + inc esi + mov dl,[ebp+edx] + + //off end of buffer? + cmp edi,[glClipY] + jge SkipLoop + + sub ebx,eax +RunMemset: + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz RunMemset + jmp EOLCheck + +Copy: + //write copy packet + sub ecx,eax + + //off end of buffer? + cmp edi,[glClipY] + jl PreCopyMemcpy + add esi,eax + jmp SkipLoop + +PreCopyMemcpy: + sub ebx,eax +CopyMemcpy: + mov dl,[esi] + inc esi + mov dl,[ebp+edx] + mov [edi],dl + dec eax + lea edi,[edi+1] + jnz CopyMemcpy + +EOLCheck: + //if at end of line, move dst and reset linecounter + test ebx,ebx + jnz NextBlock + mov ebx,[sgnWidth] + sub edi,BUFFERX + sub edi,ebx + jmp NextBlock + +SkipLoop: + cmp eax,ebx + jle SingleLineSkip + mov edx,ebx + add edi,ebx + sub eax,ebx + jmp SkipMem +SingleLineSkip: + mov edx,eax + add edi,eax + xor eax,eax +SkipMem: + //if at end of line, move dst and reset linecounter + sub ebx,edx + jnz SkipNotEOL + mov ebx,[sgnWidth] + sub edi,BUFFERX + sub edi,ebx +SkipNotEOL: + //have we finished off this block? + test eax,eax + jnz SkipLoop + +NextBlock: + test ecx,ecx + jnz Loop1 + + pop ebp + + pop edi + pop esi + pop ebx + } +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawUnit (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend) +{ + BYTE *pDst, *pSrc; + DWORD * pFrameTable; + long RLELen, nFrameStart, nFrameEnd; + + app_assert(gpBuffer != NULL); + app_assert(pCelBuff != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + nFrameStart = *(WORD*)(pSrc + ostart); + if (!nFrameStart) + return; + nFrameEnd = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (nFrameEnd ? nFrameEnd : pFrameTable[nCel+1] - pFrameTable[nCel]) - nFrameStart; + pSrc += nFrameStart; + pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp; + RLEDrawUnit(pDst, pSrc, RLELen, nCelW); +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawUnitOutline(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE * pDst, * pSrc; + DWORD * pFrameTable; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + app_assert(gpBuffer != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + offval = *(WORD*)(pSrc + ostart); + if (!offval) + return; + offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval; + pSrc += offval; + pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp; + RLEDrawOutline(pDst,pSrc,RLELen,nCelW,ocolor); +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawInfraUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff) +{ + BYTE * pDst, * pSrc; + DWORD * pFrameTable; + long RLELen, offval, offval2, ltaboff; + + app_assert(gpBuffer != NULL); + app_assert(pCelBuff != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + offval = *(WORD*)(pSrc + ostart); + if (!offval) + return; + offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval; + pSrc += offval; + pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp; + ltaboff = light4flag ? 1024 : 4096; + if (loff == LIGHT_STONE) + ltaboff += 256; + if (loff >= LIGHT_U) + ltaboff += ((loff - LIGHT_U) << 8) + 768; + RLEDrawLitUnit(pDst,pSrc,RLELen,nCelW,pLightTbl+ltaboff); +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawLitUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE * pDst, * pSrc; + DWORD * pFrameTable; + long RLELen, offval, offval2; + + app_assert(gpBuffer != NULL); + app_assert(pCelBuff != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + offval = *(WORD*)(pSrc + ostart); + if (!offval) + return; + offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval; + pSrc += offval; + pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp; + if (nLVal) + RLEDrawLitUnit(pDst,pSrc,RLELen,nCelW,pLightTbl + (nLVal << 8)); + else + RLEDrawUnit(pDst,pSrc,RLELen,nCelW); +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawUnitClipped (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend) +{ + BYTE * pDst, * pSrc; + DWORD * pFrameTable; + long RLELen, offval, offval2; + + app_assert(gpBuffer != NULL); + app_assert(pCelBuff != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + offval = *(WORD*)(pSrc + ostart); + if (!offval) + return; + offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval; + pSrc += offval; + pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp; + RLEDrawUnitClipped(pDst, pSrc, RLELen, nCelW); +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawUnitOutlineClipped(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE * pDst, * pSrc; + DWORD * pFrameTable; + long RLELen, offval, offval2; + + app_assert(pCelBuff != NULL); + app_assert(gpBuffer != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + offval = *(WORD*)(pSrc + ostart); + if (!offval) + return; + offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval; + pSrc += offval; + pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp; + glClipY -= BUFFERX; + RLEDrawOutlineClipped(pDst,pSrc,RLELen,nCelW,ocolor); + glClipY += BUFFERX; +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawInfraUnitClipped( + long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff) +{ + BYTE * pDst, * pSrc; + DWORD * pFrameTable; + long RLELen, offval, offval2, ltaboff; + + app_assert(gpBuffer != NULL); + app_assert(pCelBuff != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + offval = *(WORD*)(pSrc + ostart); + if (!offval) + return; + offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval; + pSrc += offval; + pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp; + ltaboff = light4flag ? 1024 : 4096; + if (loff == LIGHT_STONE) + ltaboff += 256; + if (loff >= LIGHT_U) + ltaboff += ((loff - LIGHT_U) << 8) + 768; + RLEDrawLitUnitClipped(pDst,pSrc,RLELen,nCelW,pLightTbl + ltaboff); +} +#endif + + +//************************************************************************* +//************************************************************************* +#if RLE_DRAW +void DrawLitUnitClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + BYTE * pDst, * pSrc; + DWORD * pFrameTable; + long RLELen, offval, offval2; + + app_assert(gpBuffer != NULL); + app_assert(pCelBuff != NULL); + app_assert(nCel > 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0) + return; + #endif + // jcm.patch1.end.1/14/97 + + pFrameTable = (DWORD*)pCelBuff; + app_assert(nCel <= (int) pFrameTable[0]); + pSrc = pCelBuff + pFrameTable[nCel]; + offval = *(WORD*)(pSrc + ostart); + if (!offval) + return; + offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend); + RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval; + pSrc += offval; + pDst = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp; + if (nLVal) + RLEDrawLitUnitClipped(pDst,pSrc,RLELen,nCelW,pLightTbl + (nLVal << 8)); + else + RLEDrawUnitClipped(pDst,pSrc,RLELen,nCelW); +} +#endif + + +//************************************************************************* +//************************************************************************* +void play_movie(const char * pszMovie,BOOL bAllowCancel); +void PlayInGameMovie(const char * pszMovie) { + PaletteFadeOut(FADE_FAST); + play_movie(pszMovie,FALSE); + ClrDraw(); + force_redraw = FULLDRAW; + FullBlit(TRUE); + PaletteFadeIn(FADE_FAST); + force_redraw = FULLDRAW; +} diff --git a/ENGINE.H b/ENGINE.H new file mode 100644 index 0000000..aa08fda --- /dev/null +++ b/ENGINE.H @@ -0,0 +1,142 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/ENGINE.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void DrawCel (long, long, BYTE *, long, long); +void DrawCelP (BYTE *, BYTE *, long, long); +void DrawSlabCel (long, long, BYTE *, long, long, long, long); +void DrawSlabCelP (BYTE *, BYTE *, long, long, long, long); + +void DrawCelL (long, long, BYTE *, long, long); +void DrawCelPL (BYTE *, BYTE *, long, long); +void DrawSlabCelL (long, long, BYTE *, long, long, long, long); +void DrawSlabCelPL (BYTE *, BYTE *, long, long, long, long); +void TDrawSlabCelPL (BYTE *, BYTE *, long, long, long, long); + +void CDrawSlabCel (long, long, BYTE *, long, long, long, long); +void CDrawSlabCelP (BYTE *, BYTE *, long, long, long, long); +void CDrawSlabCelL (long, long, BYTE *, long, long, long, long); +void CDrawSlabCelPL (BYTE *, BYTE *, long, long, long, long); +void TCDrawSlabCelPL (BYTE *, BYTE *, long, long, long, long); + +void DrawSlabCelI(long, long, BYTE *, long, long, long, long, char); +void CDrawSlabCelI(long, long, BYTE *, long, long, long, long, char); + +void OutlineSlabCel(byte, long, long, BYTE *, long, long, long, long); +void COutlineSlabCel(byte, long, long, BYTE *, long, long, long, long); + +void DrawBuffCel(BYTE *, long, long, long, BYTE *, long, long); + +void DecodeFullCel (BYTE *, BYTE *, long, long); +void DecodeFullCelL (BYTE *, BYTE *, long, long); + +void CDecodeFullCel (BYTE *, BYTE *, long, long); +void CDecodeFullCelL (BYTE *, BYTE *, long, long); + +void TranslateCels(byte *, byte *, int); + +int GetDirection(int, int, int, int); + +long GetRndSeed(); +void SetRndSeed(long); +long random(byte, long); + +void DrawLine(int, int, int, int, byte); +void DrawPoint(int, int, byte); + +void PlayInGameMovie(const char * pszMovie); + +//****************************************************************** +// memory management +//****************************************************************** +#define DEBUG_MEM 1 // 0 in final +#ifdef NDEBUG +#undef DEBUG_MEM +#define DEBUG_MEM 0 +#endif + +// public memory management functions +BYTE * DiabloAllocPtr(DWORD dwBytes); +BYTE * DiabloAllocPtrSig(DWORD dwBytes,DWORD dwSig); + +// NOTE: DiabloFreePtr behavior +// +// p MUST be an l-value +// +// if p is NULL: +// no memory is freed +// if p is NOT NULL: +// p is set to NULL before call to free, and then memory is freed +// GUARANTEES p == NULL immediately after DiabloFreePtr is called! +void DiabloFreePtr(void * p); + + +BYTE * LoadFileInMem(const char * pszName, DWORD * pdwFileLen); +BYTE * LoadFileInMemSig(const char * pszName, DWORD * pdwFileLen,DWORD dwSig); +DWORD LoadFileWithMem(const char * pszName, BYTE * pbMem); +void mem_cleanup(BOOL bNormalExit); + + +#if DEBUG_MEM + +// internal functions +void mem_use_sig(DWORD dwSig,DWORD dwBytes); +void mem_unuse_sig(DWORD dwSig,DWORD dwBytes); +BYTE * mem_malloc_dbg(DWORD dwBytes,DWORD dwSig,DWORD dwLine,const TCHAR * pszFile); +void mem_free_dbg(void * p,DWORD dwLine,const TCHAR * pszFile); +BYTE * load_file_dbg(const char * pszName,DWORD * pdwFileLen,DWORD dwSig,DWORD dwLine,const TCHAR * pszFile); + +// definitions of public functions +#define DiabloAllocPtr(dwBytes) mem_malloc_dbg(dwBytes,'NONE',__LINE__,__FILE__) +#define DiabloAllocPtrSig(dwBytes,dwSig) mem_malloc_dbg(dwBytes,dwSig,__LINE__,__FILE__) +#define LoadFileInMem(pszName,pdwFileLen) load_file_dbg(pszName,pdwFileLen,'NONE',__LINE__,__FILE__) +#define LoadFileInMemSig(pszName,pdwFileLen,dwSig) load_file_dbg(pszName,pdwFileLen,dwSig,__LINE__,__FILE__) + +// free function -- set pointer to NULL before real call to free +#define DiabloFreePtr(p) { \ + void * p__p = (void *) (p); \ + (p) = NULL; \ + mem_free_dbg(p__p,__LINE__,__FILE__); \ +} + + +#else + +// internal functions +void mem_free_dbg(void * p); + +// definitions of public functions +#define DiabloAllocPtrSig(dwBytes,dwSig) DiabloAllocPtr(dwBytes) +#define LoadFileInMemSig(pszName,pdwFileLen,dwSig) LoadFileInMem(pszName,pdwFileLen) + +// free function -- set pointer to NULL before real call to free +#define DiabloFreePtr(p) { \ + void * p__p = (void *) (p); \ + (p) = NULL; \ + mem_free_dbg(p__p); \ +} + + +#endif + + +//****************************************************************** +// file manager +//****************************************************************** +#ifdef _STORM_H_ +void patSFileCloseFile(HSFILE handle); +DWORD patSFileGetFileSize(HSFILE handle,LPDWORD filesizehigh = NULL); +BOOL patSFileOpenFile(LPCTSTR filename,HSFILE *handle,BOOL bCanFail = FALSE); +void patSFileReadFile(HSFILE handle,LPVOID buffer,DWORD bytestoread); +DWORD patSFileSetFilePointer(HSFILE handle,LONG distancetomove,PLONG distancetomovehigh,DWORD movemethod); +#endif diff --git a/ERROR.CPP b/ERROR.CPP new file mode 100644 index 0000000..7e4f22f --- /dev/null +++ b/ERROR.CPP @@ -0,0 +1,206 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Control panel file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/ERROR.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "error.h" +#include "engine.h" +#include "control.h" +#include "items.h" +#include "stores.h" +#include "scrollrt.h" + +/*-----------------------------------------------------------------------** +** Message strings +**-----------------------------------------------------------------------*/ + +char *MsgStrings[] = { +"", +"No automap available in town", +"No multiplayer functions in demo", +"Direct Sound Creation Failed", +"Not available in shareware version", +"Not enough space to save", +"No Pause in town", +"Copying to a hard disk is recommended", + +"Multiplayer sync problem", +"No pause in multiplayer", +"Loading...", +"Saving...", + +//Shrine messages +"Some are weakened as one grows strong", //12 Mysterious +"New strength is forged through destruction", //13 Hidden +"Those who defend seldom attack", //14 Gloomy +"The sword of justice is swift and sharp", //15 Weird +"While the spirit is vigilant the body thrives", //16 Magical +"The powers of mana refocused renews", //17 Stone +"Time cannot diminish the power of steel", //18 Religious +"Magic is not always what it seems to be", //19 Enchanted +"What once was opened now is closed", //20 Thaumaturgic +"Intensity comes at the cost of wisdom", //21 Fascinating +"Arcane power brings destruction", //22 Cryptic +"That which cannot be held cannot be harmed", //23 Supernatural +"Crimson and Azure become as the sun", //24 Eldritch +"Knowledge and wisdom at the cost of self", //25 Eerie +"Drink and be refreshed", //26 Divine +"Wherever you go, there you are", //27 Holy +"Energy comes at the cost of wisdom", //28 Sacred +"Riches abound when least expected", //29 Spiritual +"Where avarice fails, patience gains reward", //30 Spooky +"Blessed by a benevolent companion!", //31 Spooky Multi +"The hands of men may be guided by fate", //32 Abandoned +"Strength is bolstered by heavenly faith", //33 Creepy +"The essence of life flows from within", //34 Quiet +"The way is made clear when viewed from above", //35 Secluded +"Salvation comes at the cost of wisdom", //36 Ornate +"Mysteries are revealed in the light of reason", //37 Glimmering +"Those who are last may yet be first", //38 Tainted +"Generosity brings its own rewards", //39 Tainted Multi + +//Shortcut messages +"You must be at least level 8 to use this.", //40 +"You must be at least level 13 to use this.", //41 +"You must be at least level 17 to use this.", //42 +"Arcane knowledge gained!", //43 + +// New Shrines +"That which does not kill you...", //44 Oily +"Knowledge is power.", //45 Glowing +"Give and you shall receive.", //46 Mendicants. +"Some experience is gained by touch.", //47 Edisons +"There's no place like home.", //48 Town +"Spirtual energy is restored.", //49 Energy +"You feel more agile.", //50 Time Morning +"You feel stronger.", //51 Time Afternoon. +"You feel wiser.", //52 Time Evening. +"You feel refreshed.", //53 Time Night. +"That which can break will.", //54 Murphy's +}; + +/*-----------------------------------------------------------------------** +** Local defines +**-----------------------------------------------------------------------*/ + +#define MSGCNT 70 + +char msgflag; +char msgdelay; +char msgtable[80]; +char msgcnt = 0; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitDiabloMsg(char e) +{ + int i; + + for (i = 0; i < msgcnt; i++) { + if (msgtable[i] == e) return; + } + + msgtable[msgcnt] = e; + if (msgcnt < 80) msgcnt++; + msgflag = msgtable[0]; + msgdelay = MSGCNT; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ClrDiabloMsg() +{ + for (int i = 0; i < 80; i++) msgtable[i] = MSG_NONE; + msgflag = MSG_NONE; + msgcnt = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawDiabloMsg() +{ + int i, x, y; + long boffset; + int sl,tw; + + // Draw error box + DrawCel(165, 318, pSTextSlidCels, 1, 12); + DrawCel(591, 318, pSTextSlidCels, 4, 12); + DrawCel(165, 366, pSTextSlidCels, 2, 12); + DrawCel(591, 366, pSTextSlidCels, 3, 12); + + x = 173; + for (i = 0; i < 35; i++) { + DrawCel(x, 318, pSTextSlidCels, 5, 12); + DrawCel(x, 366, pSTextSlidCels, 7, 12); + x += 12; + } + y = 330; + for (i = 0; i < 3; i++) { + DrawCel(165, y, pSTextSlidCels, 6, 12); + DrawCel(591, y, pSTextSlidCels, 8, 12); + y += 12; + } + + app_assert(gpBuffer); + __asm { + mov edi,dword ptr [gpBuffer] + add edi,278952 + + xor eax,eax + mov edx,27 +_YLp: mov ecx,216 // (width+6)/2 +_XLp1: stosb + inc edi + loop _XLp1 + sub edi,1200 // ((width+6)/2) + 768 + mov ecx,216 // (width+6)/2 +_XLp2: inc edi + stosb + loop _XLp2 + sub edi,1200 // ((width+6)/2) + 768 + dec edx + jnz _YLp + } + + strcpy(tempstr, MsgStrings[msgflag]); + + boffset = nBuffWTbl[342] + 165; + sl = strlen(tempstr); + tw = 0; + for (i = 0; i < sl; i++) { + BYTE c = char2print(tempstr[i]); + c = fonttrans[c]; + tw += fontkern[c]+1; + } + if (tw < 442) boffset += (442 - tw) >> 1; + for (i = 0; i < sl; i++) { + BYTE c = char2print(tempstr[i]); + c = fonttrans[c]; + if (c) DrawPanelFont(boffset, c, ICOLOR_GOLD); + boffset += fontkern[c]+1; + } + + if (msgdelay > 0) msgdelay--; + + if (msgdelay == 0) { + msgcnt--; + msgdelay = MSGCNT; + if (msgcnt == 0) msgflag = MSG_NONE; + else msgflag = msgtable[msgcnt]; + } +} diff --git a/ERROR.H b/ERROR.H new file mode 100644 index 0000000..3df66d3 --- /dev/null +++ b/ERROR.H @@ -0,0 +1,93 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/ERROR.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MSG_NONE 0 +#define MSG_AMAPTWN 1 +#define MSG_MULTIBTN 2 +#define MSG_SOUND 3 +#define MSG_SHAREWARE 4 +#define MSG_SAVESIZE 5 +#define MSG_NOPAUSE 6 +#define MSG_HDRIVE 7 + +#define MSG_SYNC 8 // Multi sync +#define MSG_MULTIPAUSE 9 // No multiplayer pause +#define MSG_LOADGAME 10 +#define MSG_SAVEGAME 11 + +#define SHRINE_1 12 // Mysterious +#define SHRINE_2 13 // Hidden +#define SHRINE_3 14 // Gloomy +#define SHRINE_4 15 // Weird +#define SHRINE_5 16 // Magical +#define SHRINE_6 17 // Stone +#define SHRINE_7 18 // Religious +#define SHRINE_8 19 // Enchanted +#define SHRINE_9 20 // Thaumaturgic +#define SHRINE_10 21 // Fascinating +#define SHRINE_11 22 // Cryptic +#define SHRINE_12 23 // Supernatural +#define SHRINE_13 24 // Eldritch +#define SHRINE_14 25 // Eerie +#define SHRINE_15 26 // Divine +#define SHRINE_16 27 // Holy +#define SHRINE_17 28 // Sacred +#define SHRINE_18 29 // Spiritual +#define SHRINE_19 30 // Spooky +#define SHRINE_19B 31 // Spooky for multiplayer +#define SHRINE_20 32 // Abandoned +#define SHRINE_21 33 // Creepy +#define SHRINE_22 34 // Quiet +#define SHRINE_23 35 // Secluded +#define SHRINE_24 36 // Ornate +#define SHRINE_25 37 // Glimmering +#define SHRINE_26 38 // Tainted +#define SHRINE_26B 39 // Tainted for mulitplayer +#define SHRINE_27 44 // Oily +#define SHRINE_28 45 // Glowing +#define SHRINE_29 46 // Mendicants +#define SHRINE_30 47 // Edisons +#define SHRINE_31 48 // Town +#define SHRINE_32 49 // Energy +#define SHRINE_33A 50 // Time Morning +#define SHRINE_33B 51 // Time Afternoon +#define SHRINE_33C 52 // Time Evening +#define SHRINE_33D 53 // Time Night +#define SHRINE_34 54 // Murphy's + +#define MSG_TRIG1 40 // Shortcut to catacombs +#define MSG_TRIG2 41 // Shortcut to caves +#define MSG_TRIG3 42 // Shortcut to hell + +#define MSG_INBONE 43 // Book with spell in Bone Chamber + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern char msgflag; +extern char msgdelay; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitDiabloMsg(char); +void ClrDiabloMsg(); +void DrawDiabloMsg(); + diff --git a/EXCEPT.CPP b/EXCEPT.CPP new file mode 100644 index 0000000..f0bf77d --- /dev/null +++ b/EXCEPT.CPP @@ -0,0 +1,286 @@ +//****************************************************************** +// except.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include + + +//****************************************************************** +// private +//****************************************************************** +class CExcept { +public: + CExcept(); + ~CExcept(); + +private: + // entry point where control comes on an unhandled exception + static LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo); + + // variables used by the class + static TCHAR m_szLogFileName[MAX_PATH]; + static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter; +}; + +TCHAR CExcept::m_szLogFileName[MAX_PATH]; +LPTOP_LEVEL_EXCEPTION_FILTER CExcept::m_previousFilter; +static CExcept g_CExcept; + + +//****************************************************************** +//****************************************************************** +static void __cdecl tprintf(HANDLE hFile,LPCTSTR pszFmt,...) { + va_list argptr; + DWORD cbWritten; + TCHAR szBuf[1024]; + va_start(argptr,pszFmt); + int nChars = wvsprintf(szBuf,pszFmt,argptr); + WriteFile(hFile,szBuf,nChars * sizeof(TCHAR),&cbWritten,0); + va_end(argptr); +} + + +//****************************************************************** +// Given a linear address,locates the module,section,and offset containing +// that address. +// +// Note: the szModule paramater buffer is an output buffer of length specified +// by the len parameter (in characters!) +//****************************************************************** +static BOOL GetLogicalAddress( + PVOID addr, + PTSTR szModule, + DWORD len, + DWORD *pdwSection, + DWORD *pdwOffset +) { + MEMORY_BASIC_INFORMATION mbi; + if (!VirtualQuery(addr,&mbi,sizeof(mbi))) + return FALSE; + + DWORD hMod = (DWORD)mbi.AllocationBase; + if (!GetModuleFileName((HMODULE)hMod,szModule,len)) + return FALSE; + + // Point to the DOS header in memory + PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod; + + // From the DOS header,find the NT (PE) header + PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew); + PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHdr); + DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address + + // Iterate through the section table,looking for the one that encompasses + // the linear address. + for ( + unsigned i = 0; + i < pNtHdr->FileHeader.NumberOfSections; + i++,pSection++ + ) { + DWORD sectionStart = pSection->VirtualAddress; + DWORD sectionEnd = sectionStart + + max(pSection->SizeOfRawData,pSection->Misc.VirtualSize); + + // Is the address in this section??? + if ((rva >= sectionStart) && (rva <= sectionEnd)) { + // Yes,address is in the section. Calculate section and offset + *pdwSection = i+1; + *pdwOffset = rva - sectionStart; + return TRUE; + } + } + + return FALSE; // Should never get here! +} + + +//****************************************************************** +//****************************************************************** +static void IntelStackWalk(HANDLE hFile,PCONTEXT pContext) { + tprintf(hFile,_T("\r\nCall stack:\r\n")); + tprintf(hFile,_T("Address Frame Logical addr Module\r\n")); + + DWORD pc = pContext->Eip; + PDWORD pFrame,pPrevFrame; + pFrame = (PDWORD)pContext->Ebp; + while (1) { + TCHAR szModule[MAX_PATH] = _T(""); + DWORD section = 0,offset = 0; + + GetLogicalAddress((PVOID)pc,szModule,sizeof(szModule),§ion,&offset); + tprintf(hFile,_T("%08X %08X %04X:%08X %s\r\n"), + pc,pFrame,section,offset,szModule); + + // precede to next higher frame on stack + pc = pFrame[1]; + pPrevFrame = pFrame; + pFrame = (PDWORD)pFrame[0]; + // Frame pointer must be aligned on a DWORD boundary + if ((DWORD)pFrame & 3) break; + if (pFrame <= pPrevFrame) break; + + // Can two DWORDs be read from the supposed frame address? + if (IsBadWritePtr(pFrame,sizeof(PVOID)*2)) break; + } +} + + +//****************************************************************** +//****************************************************************** +static LPTSTR GetExceptionString(DWORD dwCode) { + #define EXCEPTION(x) case EXCEPTION_##x: return _T(#x); + switch (dwCode) { + EXCEPTION(ACCESS_VIOLATION) + EXCEPTION(DATATYPE_MISALIGNMENT) + EXCEPTION(BREAKPOINT) + EXCEPTION(SINGLE_STEP) + EXCEPTION(ARRAY_BOUNDS_EXCEEDED) + EXCEPTION(FLT_DENORMAL_OPERAND) + EXCEPTION(FLT_DIVIDE_BY_ZERO) + EXCEPTION(FLT_INEXACT_RESULT) + EXCEPTION(FLT_INVALID_OPERATION) + EXCEPTION(FLT_OVERFLOW) + EXCEPTION(FLT_STACK_CHECK) + EXCEPTION(FLT_UNDERFLOW) + EXCEPTION(INT_DIVIDE_BY_ZERO) + EXCEPTION(INT_OVERFLOW) + EXCEPTION(PRIV_INSTRUCTION) + EXCEPTION(IN_PAGE_ERROR) + EXCEPTION(ILLEGAL_INSTRUCTION) + EXCEPTION(NONCONTINUABLE_EXCEPTION) + EXCEPTION(STACK_OVERFLOW) + EXCEPTION(INVALID_DISPOSITION) + EXCEPTION(GUARD_PAGE) + EXCEPTION(INVALID_HANDLE) + } + #undef EXCEPTION + + // If not one of the "known" exceptions, try to + // get the string from NTDLL.DLL's message table. + static TCHAR szBuf[512] = { 0 }; + FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, + GetModuleHandle(_T("NTDLL.DLL")), + dwCode,0,szBuf,sizeof(szBuf),0); + return szBuf; +} + + +//****************************************************************** +//****************************************************************** +static void GenerateExceptionReport(HANDLE hFile,PEXCEPTION_POINTERS pExceptionInfo) { + PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord; + + // First print information about the type of fault + tprintf(hFile,_T("Exception code: %08X %s\r\n"), + pExceptionRecord->ExceptionCode, + GetExceptionString(pExceptionRecord->ExceptionCode)); + + // Now print information about where the fault occured + TCHAR szFaultingModule[MAX_PATH]; + DWORD section,offset; + GetLogicalAddress(pExceptionRecord->ExceptionAddress, + szFaultingModule, + sizeof(szFaultingModule), + §ion,&offset); + + tprintf(hFile,_T("Fault address: %08X %02X:%08X %s\r\n"), + pExceptionRecord->ExceptionAddress, + section,offset,szFaultingModule); + + PCONTEXT pCtx = pExceptionInfo->ContextRecord; + + // Show the registers + #ifdef _M_IX86 // Intel Only! + tprintf(hFile,_T("\r\nRegisters:\r\n")); + + tprintf(hFile,_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n"), + pCtx->Eax,pCtx->Ebx,pCtx->Ecx,pCtx->Edx,pCtx->Esi,pCtx->Edi); + + tprintf(hFile,_T("CS:EIP:%04X:%08X\r\n"),pCtx->SegCs,pCtx->Eip); + tprintf(hFile,_T("SS:ESP:%04X:%08X EBP:%08X\r\n"), + pCtx->SegSs,pCtx->Esp,pCtx->Ebp); + tprintf(hFile,_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), + pCtx->SegDs,pCtx->SegEs,pCtx->SegFs,pCtx->SegGs); + tprintf(hFile,_T("Flags:%08X\r\n"),pCtx->EFlags); + + // Walk the stack using x86 specific code + IntelStackWalk(hFile,pCtx); + + #endif + + tprintf(hFile,_T("\r\n")); +} + + +//****************************************************************** +//****************************************************************** +LONG WINAPI CExcept::ExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo) { + + // try opening the error report file in the program directory + // if we can't open the file, it may be because the app + // is running from a CDROM drive -- try opening a file + // with the same name in c: + HANDLE hFile; + for (int i = 0; i < 2; i++) { + hFile = CreateFile( + m_szLogFileName, + GENERIC_WRITE, + 0, + 0, + OPEN_ALWAYS, + FILE_FLAG_WRITE_THROUGH, + 0 + ); + if (hFile != INVALID_HANDLE_VALUE) break; + + // extract the file name + LPTSTR lpFName = _tcsrchr(m_szLogFileName,_T('\\')); + if (! lpFName) break; + + // create full path to file in C: + TCHAR szTemp[MAX_PATH] = _T("c:\\"); + _tcscat(szTemp,lpFName); + _tcscpy(m_szLogFileName,szTemp); + } + + if (hFile != INVALID_HANDLE_VALUE) { + SetFilePointer(hFile,0,0,FILE_END); + GenerateExceptionReport(hFile,pExceptionInfo); + CloseHandle(hFile); + } + + if (m_previousFilter) return m_previousFilter(pExceptionInfo); + return EXCEPTION_CONTINUE_SEARCH; +} + + +//****************************************************************** +//****************************************************************** +CExcept::CExcept() { + // Install the unhandled exception filter function + m_previousFilter = SetUnhandledExceptionFilter(ExceptionFilter); + + // Figure out what the report file will be named,and store it away + GetModuleFileName(0,m_szLogFileName,MAX_PATH); + + // replace .EXE with .ERR + PTSTR pszDot = _tcsrchr(m_szLogFileName,_T('.')); + if (pszDot) { + pszDot++; + if (_tcslen(pszDot) >= 3) + _tcscpy(pszDot,_T("ERR")); + } + + // delete any old exception reports + DeleteFile(m_szLogFileName); +} + + +//****************************************************************** +//****************************************************************** +CExcept::~CExcept() { + SetUnhandledExceptionFilter(m_previousFilter); +} diff --git a/FIXES.TXT b/FIXES.TXT new file mode 100644 index 0000000..fb492d8 --- /dev/null +++ b/FIXES.TXT @@ -0,0 +1,25 @@ + +*) Fixed the bug where picking up gold when your inventory is full +duplicates the gold in your hand and fills your gold slot. + +*) Fixed the Berserk spell to prevent crashes. + +*) Fixed entering the new levels. + +*) Fixed to dropping and picking back up oiled items. + +*) Fixed generating spell books by Adria. + +*) Fixed placing of weapons for all player classes. + +*) Fixed generating rings of fire behind a wall. + + +Donald: + +*) Fixed Gosip. + +*) Fix to item changing between games. + +12/29/97 +*)Fix to gold cursor when full of gold in inventory. diff --git a/FUTURES.TXT b/FUTURES.TXT new file mode 100644 index 0000000..57f7e10 --- /dev/null +++ b/FUTURES.TXT @@ -0,0 +1,13 @@ +Bad Priest: + Low max strength: + Medium armor cuts spell level in half. + Full armor sets spell level to 1. + + Daggers and small swords are best. + + + Large weapons don't do full damage. (Priest is too weak) + + Benefit: mana cost is really low. Heal other in Multiplayer mode + + diff --git a/GAMEMENU.CPP b/GAMEMENU.CPP new file mode 100644 index 0000000..e75debb --- /dev/null +++ b/GAMEMENU.CPP @@ -0,0 +1,485 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Game Menu file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/GAMEMENU.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "gendung.h" +#include "sound.h" +#include "gamemenu.h" +#include "scrollrt.h" +#include "multi.h" +#include "cursor.h" +#include "items.h" +#include "player.h" +#include "error.h" +#include "palette.h" +#include "effects.h" +#include "msg.h" +#include "storm/h/storm.h" + + +//****************************************************************** +// extern +//****************************************************************** +extern BOOL gbRunGame; +extern BOOL gbRunGameResult; +extern BOOL deathflag; +void sound_stop(); +void GM_SaveGame(); +void GM_LoadGame(BOOL firstflag); +LRESULT CALLBACK DisableInputWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); +void interface_msg_pump(); +WNDPROC my_SetWindowProc(WNDPROC wndProc); +/*extern*/ DWORD gbWalkOn = TRUE; +extern char gszProgKey[]; + +void CornerstoneSave(); + +//****************************************************************** +// private +//****************************************************************** +// menu functions +static void fnNew(BOOL bActivate); +static void fnLoad(BOOL bActivate); +static void fnOptions(BOOL bActivate); +static void fnSave(BOOL bActivate); +static void fnQuit(BOOL bActivate); +static void fnRestart(BOOL bActivate); +static void fnMusic(BOOL bActivate); +static void fnSound(BOOL bActivate); +static void fnWalk(BOOL bActivate); +static void fnGamma(BOOL bActivate); +static void fnOptionPrevious(BOOL bActivate); +static void fnReturnToGame(BOOL bActivate); +static void fnSaveAndQuit(BOOL bActivate); + +// menus +#define OPTION_SINGLE_SAVE 0 +#define OPTION_SINGLE_LOAD 3 +static TMenuItem sgSingleMenu[] = { + { mf_ENABLED, "Save Game", fnSave }, + { mf_ENABLED, "Options", fnOptions }, + { mf_ENABLED, "New Game", fnNew }, + { mf_ENABLED, "Load Game", fnLoad }, + { mf_ENABLED, "Quit Hellfire", fnQuit }, + { mf_ENABLED, NULL, NULL } +}; + +#define OPTION_MULTI_RESTART 2 +static TMenuItem sgMultiMenu[] = { + { mf_ENABLED, "Options", fnOptions }, + { mf_ENABLED, "New Game", fnNew }, + { mf_ENABLED, "Restart In Town", fnRestart }, + { mf_ENABLED, "Quit Hellfire", fnQuit }, + { mf_ENABLED, NULL, NULL } +}; + +#define OPTION_MUSIC 0 +#define OPTION_SOUND 1 +#define OPTION_GAMMA 2 +#define OPTION_WALK 3 +static TMenuItem sgOptionsMenu[] = { + { mf_ENABLED | mf_SLIDER, NULL, fnMusic }, + { mf_ENABLED | mf_SLIDER, NULL, fnSound }, + { mf_ENABLED | mf_SLIDER, "Gamma", fnGamma }, + { mf_ENABLED | mf_SLIDER, NULL, fnWalk }, + { mf_ENABLED, "Previous Menu", fnOptionPrevious }, + { mf_ENABLED, NULL, NULL } +}; + +// strings for options menu +#define SM_ON 0 +#define SM_DISABLED 1 +static const char * sgszMusic[] = { + "Music", + "Music Disabled", +}; +static const char * sgszSound[] = { + "Sound", + "Sound Disabled", +}; +static const char * sgszWalk[] = { + "Jog", + "Walk", +}; +const char * sgszWalkId = "Fast Walk"; + + +//****************************************************************** +//****************************************************************** +static void gm_single_update(TMenuItem * pMenuItems) { + app_assert(pMenuItems == sgSingleMenu); + gmenu_set_enable(&sgSingleMenu[OPTION_SINGLE_LOAD],gbValidSaveFile); + gmenu_set_enable( + &sgSingleMenu[OPTION_SINGLE_SAVE], + plr[myplr]._pmode != PM_DEATH && !deathflag + ); +} + + +//****************************************************************** +//****************************************************************** +static void gm_multi_update(TMenuItem * pMenuItems) { + app_assert(pMenuItems == sgMultiMenu); + gmenu_set_enable(&sgMultiMenu[OPTION_MULTI_RESTART],deathflag); +} + + +//****************************************************************** +//****************************************************************** +void gamemenu_on() { + if (gbMaxPlayers == 1) + gmenu_set_menu(sgSingleMenu,gm_single_update); + else + gmenu_set_menu(sgMultiMenu,gm_multi_update); + + // remove all junky windows under the menu + extern BOOL clear_windows(); + clear_windows(); +} + + +//****************************************************************** +//****************************************************************** +void gamemenu_off() { + gmenu_set_menu(NULL,NULL); +} + + +//****************************************************************** +//****************************************************************** +void gamemenu_toggle() { + if (gmenu_is_on()) + gamemenu_off(); + else + gamemenu_on(); +} + + +//****************************************************************** +//****************************************************************** +static void fnOptionPrevious(BOOL bActivate) { + app_assert(bActivate); + gamemenu_on(); +} + + +//****************************************************************** +//****************************************************************** +static void fnNew(BOOL bActivate) { + app_assert(bActivate); + for (int i = 0; i < MAX_PLRS; i++) { + plr[i]._pmode = PM_QUIT; + plr[i]._pInvincible = TRUE; + } + + deathflag = FALSE; + force_redraw = FULLDRAW; + FullBlit(TRUE); + + CornerStone.Initted = FALSE; + // stop running game loop + gbRunGame = FALSE; + gamemenu_off(); +} + + +//****************************************************************** +//****************************************************************** +static void fnQuit(BOOL bActivate) { + app_assert(bActivate); + fnNew(bActivate); + gbRunGameResult = FALSE; +} + + +//****************************************************************** +//****************************************************************** +static void fnLoad(BOOL bActivate) { + app_assert(bActivate); + app_assert(gbMaxPlayers == 1); + app_assert(gbValidSaveFile); + + // set window proc to function which will ignore input + app_assert(ghMainWnd); + WNDPROC saveProc = my_SetWindowProc(DisableInputWndProc); + + gamemenu_off(); + SetCursor(NO_CURSOR); + InitDiabloMsg(MSG_LOADGAME); + force_redraw = FULLDRAW; + DrawAndBlit(); + GM_LoadGame(FALSE); + ClrDiabloMsg(); + + CornerStone.Initted = FALSE; + + PaletteFadeOut(FADE_FAST); + deathflag = FALSE; + force_redraw = FULLDRAW; + DrawAndBlit(); + PaletteFadeIn(FADE_FAST); + SetCursor(GLOVE_CURS); + + // flush out all the messages and restore old wndproc + interface_msg_pump(); + saveProc = my_SetWindowProc(saveProc); + app_assert(saveProc == DisableInputWndProc); +} + + +//****************************************************************** +//****************************************************************** +static void fnSave(BOOL bActivate) { + app_assert(bActivate); + app_assert(gbMaxPlayers == 1); + if (curs != GLOVE_CURS) { + // @@@ how bout an error msg + return; + } + + if (plr[myplr]._pmode == PM_DEATH || deathflag) { + gamemenu_off(); + return; + } + + // set window proc to function which will ignore input + app_assert(ghMainWnd); + WNDPROC saveProc = my_SetWindowProc(DisableInputWndProc); + + SetCursor(NO_CURSOR); + gamemenu_off(); + InitDiabloMsg(MSG_SAVEGAME); + force_redraw = FULLDRAW; + DrawAndBlit(); + GM_SaveGame(); + ClrDiabloMsg(); + force_redraw = FULLDRAW; + SetCursor(GLOVE_CURS); + + // update the Cornerstone of the World + if (CornerStone.Initted) + CornerstoneSave(); + + // flush out all the messages and restore old wndproc + interface_msg_pump(); + saveProc = my_SetWindowProc(saveProc); + app_assert(saveProc == DisableInputWndProc); +} + + +//****************************************************************** +//****************************************************************** +static void fnRestart(BOOL bActivate) { + app_assert(bActivate); + NetSendCmd(TRUE, CMD_RETOWN); +} + + +//****************************************************************** +//****************************************************************** +static void set_volume_item(const char ** ppStrs,TMenuItem * pItem,LONG lVolume) { + if (gbSndInited) { + pItem->dwFlags |= mf_ENABLED | mf_SLIDER; + pItem->pszStr = ppStrs[SM_ON]; + gmenu_set_slider_ticks(pItem,VOLUME_TICKS); + gmenu_set_slider(pItem,VOLUME_MIN,VOLUME_MAX,lVolume); + } + else { + pItem->dwFlags &= ~(mf_ENABLED | mf_SLIDER); + pItem->pszStr = ppStrs[SM_DISABLED]; + } +} + + +//****************************************************************** +//****************************************************************** +static LONG get_volume_item(const TMenuItem * pItem) { + return gmenu_get_slider(pItem,VOLUME_MIN,VOLUME_MAX); +} + + +//****************************************************************** +//****************************************************************** +static void set_music_item() { + set_volume_item(sgszMusic,&sgOptionsMenu[OPTION_MUSIC],music_volume(VOLUME_READ)); +} + + +//****************************************************************** +//****************************************************************** +static void set_sound_item() { + set_volume_item(sgszSound,&sgOptionsMenu[OPTION_SOUND],sound_volume(VOLUME_READ)); +} + +//****************************************************************** +//****************************************************************** +static void set_walk_item() { + gmenu_set_slider_ticks(&sgOptionsMenu[OPTION_WALK],2); + gmenu_set_slider( + &sgOptionsMenu[OPTION_WALK], 0, 1, gbWalkOn); + sgOptionsMenu[OPTION_WALK].pszStr = + sgszWalk[(gbWalkOn)?SM_ON:SM_DISABLED]; +} + +//****************************************************************** +//****************************************************************** +static void set_gamma_item() { + gmenu_set_slider_ticks(&sgOptionsMenu[OPTION_GAMMA],lGAMMA_TICKS); + gmenu_set_slider( + &sgOptionsMenu[OPTION_GAMMA], + lGAMMA_MIN, + lGAMMA_MAX, + GammaLevel(lGAMMA_READ) + ); +} + + +//****************************************************************** +//****************************************************************** +static LONG get_gamma_item() { + return gmenu_get_slider( + &sgOptionsMenu[OPTION_GAMMA], + lGAMMA_MIN, + lGAMMA_MAX + ); +} + + +//****************************************************************** +//****************************************************************** +static void fnOptions(BOOL bActivate) { + app_assert(bActivate); + set_music_item(); + set_sound_item(); + set_walk_item(); + set_gamma_item(); + gmenu_set_menu(sgOptionsMenu,NULL); +} + + +//****************************************************************** +//****************************************************************** +static void fnMusic(BOOL bActivate) { + if (bActivate) { + if (gbMusicOn) { + gbMusicOn = FALSE; + music_stop(); + music_volume(VOLUME_MIN); + } + else { + gbMusicOn = TRUE; + music_volume(VOLUME_MAX); + + if (currlevel >= HIVESTART) // fix this later JKE + { + music_start((currlevel > HIVEEND)? 5 : 6); + } + else + music_start(leveltype); + } + } + else { + LONG lVolume = get_volume_item(&sgOptionsMenu[OPTION_MUSIC]); + music_volume(lVolume); + + if (lVolume == VOLUME_MIN) { + if (gbMusicOn) { + gbMusicOn = FALSE; + music_stop(); + } + } + else { + if (! gbMusicOn) { + gbMusicOn = TRUE; + if (currlevel >= HIVESTART) // fix this later JKE + { + music_start((currlevel > HIVEEND)? 5 : 6); + } + else + music_start(leveltype); + } + } + } + + set_music_item(); +} + + +//****************************************************************** +//****************************************************************** +static void fnSound(BOOL bActivate) { + if (bActivate) { + if (gbSoundOn) { + gbSoundOn = FALSE; + sound_stop(); + sound_volume(VOLUME_MIN); + } + else { + gbSoundOn = TRUE; + sound_volume(VOLUME_MAX); + } + } + else { + LONG lVolume = get_volume_item(&sgOptionsMenu[OPTION_SOUND]); + sound_volume(lVolume); + + if (lVolume == VOLUME_MIN) { + if (gbSoundOn) { + gbSoundOn = FALSE; + sound_stop(); + } + } + else { + if (! gbSoundOn) { + gbSoundOn = TRUE; + } + } + } + + PlaySFX(IS_TITLEMOV); + set_sound_item(); +} + +static void fnWalk(BOOL bActivate) { + if (gbMaxPlayers != 1) // single-player only + return; + + if (gbWalkOn) { + gbWalkOn = FALSE; + } + else { + gbWalkOn = TRUE; + } + SRegSaveValue(gszProgKey,sgszWalkId,0,gbWalkOn); + + PlaySFX(IS_TITLEMOV); + set_walk_item(); +} + +//****************************************************************** +//****************************************************************** +static void fnGamma(BOOL bActivate) { + LONG lGamma; + if (bActivate) { + lGamma = GammaLevel(lGAMMA_READ); + if (lGamma == lGAMMA_MIN) + lGamma = lGAMMA_MAX; + else + lGamma = lGAMMA_MIN; + } + else { + lGamma = get_gamma_item(); + } + + GammaLevel(lGamma); + set_gamma_item(); +} diff --git a/GAMEMENU.H b/GAMEMENU.H new file mode 100644 index 0000000..f78e846 --- /dev/null +++ b/GAMEMENU.H @@ -0,0 +1,56 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/GAMEMENU.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + + +//****************************************************************** +//****************************************************************** +#define mf_ENABLED 0x80000000 +#define mf_SLIDER 0x40000000 +typedef void (* TMenuFcn)(BOOL bActivate); +typedef struct TMenuItem { + DWORD dwFlags; + const char * pszStr; + TMenuFcn fnMenu; +} TMenuItem; + +typedef void (* TMenuUpdateFcn)(TMenuItem * pMenuItems); + +//****************************************************************** +// menu functions +//****************************************************************** +void gmenu_init(); +void gmenu_free(); +void gmenu_draw(); +BOOL gmenu_is_on(); +BOOL gmenu_click(BOOL bMouseDown); +BOOL gmenu_mousemove(); +BOOL gmenu_key(WPARAM wKey); +void gmenu_set_menu(TMenuItem * pMenuItems,TMenuUpdateFcn fnUpdate); +void gmenu_set_enable(TMenuItem * pMenuItem,BOOL bEnable); + +void gmenu_set_slider(TMenuItem * pItem,LONG lMin,LONG lMax,LONG lVal); +LONG gmenu_get_slider(const TMenuItem * pItem,LONG lMin,LONG lMax); +void gmenu_set_slider_ticks(TMenuItem * pMenuItem,DWORD dwTicks); + + +//****************************************************************** +// gamemenu functions +//****************************************************************** +void gamemenu_toggle(); +void gamemenu_on(); +void gamemenu_off(); + + +//****************************************************************** +// other prototypes +//****************************************************************** +void GM_LoadGame(BOOL); +void SaveLevel(); +void LoadLevel(); diff --git a/GENDUNG.CPP b/GENDUNG.CPP new file mode 100644 index 0000000..c50bf6b --- /dev/null +++ b/GENDUNG.CPP @@ -0,0 +1,1209 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** General Dungeon file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/GENDUNG.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +** FillDungeonInfo +** DRLG +** MakeDungeonLayout +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "gendung.h" +#include "engine.h" +#include "lighting.h" +#include "palette.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "objects.h" +#include "missiles.h" +#include "spells.h" + +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ + +byte dungeon[MDMAXX][MDMAXY]; +byte pdungeon[MDMAXX][MDMAXY]; +byte dflags[MDMAXX][MDMAXY]; +int setpc_x, setpc_y, setpc_w, setpc_h; // Where the important set piece of a level is +byte *pSetPiece; +BOOL setloadflag; + +BYTE *pSpecialCels; +BYTE *pMegaTiles; +BYTE *pMiniTiles; +extern "C" { + BYTE *pDungeonCels; + BYTE *pSpeedCels; + long microoffset[MAXMREND][16]; + byte nWTypeTable[MAXTILES+1]; +} + +int mcount[MAXMICRO]; +int mlist[MAXMICRO]; +//WORD mtype[MAXMICRO]; +static WORD mtype[MAXMICRO]; // resolve ambiguity with monsters JKE 7/30 +int msize[MAXMICRO]; +int nummicros; + +BYTE nBlockTable[MAXTILES+1]; +BYTE nSolidTable[MAXTILES+1]; +BYTE nTransTable[MAXTILES+1]; +BYTE nMissileTable[MAXTILES+1]; +BYTE nTrapTable[MAXTILES+1]; + +int dminx, dminy, dmaxx, dmaxy; + +int gnDifficulty; + +BYTE leveltype; +BYTE currlevel; +BYTE setlevel; +BYTE setlvlnum; +BYTE setlvltype; + +int ViewX, ViewY; +int ViewDX, ViewDY; +int ViewBX, ViewBY; +ScrollStruct ScrollInfo; + +int LvlViewX, LvlViewY; + +int btmbx, btmby; +int btmdx, btmdy; + +int MicroTileLen; + +char TransVal; +BYTE TransList[256]; + +int dPiece[MAXDUNX][MAXDUNY]; // Tile # + +MICROS dMT[MAXDUNX][MAXDUNY]; // Micro Tiles +MICROS dMT2[(MAXDUNX)*(MAXDUNY)]; + +char dTransVal[MAXDUNX][MAXDUNY]; // Transparent active value +char dLight[MAXDUNX][MAXDUNY]; // Current light value +char dSaveLight[MAXDUNX][MAXDUNY]; // Static light value +char dFlags[MAXDUNX][MAXDUNY]; // Flags for Solid collision, etc. +char dPlayer[MAXDUNX][MAXDUNY]; // Player +int dMonster[MAXDUNX][MAXDUNY]; // Monster +char dDead[MAXDUNX][MAXDUNY]; // Dead plr/monster +char dObject[MAXDUNX][MAXDUNY]; // Objects +char dItem[MAXDUNX][MAXDUNY]; // Items +char dMissile[MAXDUNX][MAXDUNY]; // Missiles +char dSpecial[MAXDUNX][MAXDUNY]; // Second layer of tiling +int themeCount; // Theme room count +THEME_LOC themeLoc[50]; // Theme room array + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FillSolidBlockTbls() { + DWORD dwTiles; + BYTE *pSBFile; + + ZeroMemory(nBlockTable,sizeof(nBlockTable)); + ZeroMemory(nSolidTable,sizeof(nSolidTable)); + ZeroMemory(nTransTable,sizeof(nTransTable)); + ZeroMemory(nMissileTable,sizeof(nMissileTable)); + ZeroMemory(nTrapTable,sizeof(nTrapTable)); + + switch (leveltype) { + case 0: + pSBFile = LoadFileInMemSig("NLevels\\TownData\\Town.SOL",&dwTiles,'SOL '); + break; + case 1: + if (currlevel < 17) + pSBFile = LoadFileInMemSig("Levels\\L1Data\\L1.SOL",&dwTiles,'SOL '); + else + pSBFile = LoadFileInMemSig("NLevels\\L5Data\\L5.SOL",&dwTiles,'SOL '); //JKE Attributes loaded + + break; + case 2: + pSBFile = LoadFileInMemSig("Levels\\L2Data\\L2.SOL",&dwTiles,'SOL '); + break; + case 3: + if (currlevel < 17) + pSBFile = LoadFileInMemSig("Levels\\L3Data\\L3.SOL",&dwTiles,'SOL '); + else + pSBFile = LoadFileInMemSig("NLevels\\L6Data\\L6.SOL",&dwTiles,'SOL '); //JKE Attributes loaded + break; + case 4: + pSBFile = LoadFileInMemSig("Levels\\L4Data\\L4.SOL",&dwTiles,'SOL '); + break; + default: + app_fatal("FillSolidBlockTbls"); + break; + } + + BYTE * pTmp = pSBFile; + for (DWORD d = 1; d <= dwTiles; d++) { + BYTE bv = *pTmp++; + if ((bv & 0x01) != 0) nSolidTable[d] = TRUE; + if ((bv & 0x02) != 0) nBlockTable[d] = TRUE; + if ((bv & 0x04) != 0) nMissileTable[d] = TRUE; + if ((bv & 0x08) != 0) nTransTable[d] = TRUE; + if ((bv & 0x80) != 0) nTrapTable[d] = TRUE; + nWTypeTable[d] = (bv & 0x70) >> 4; + } + + DiabloFreePtr(pSBFile); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void bs_swap(int a, int b) { + int v; + + v = mcount[a]; + mcount[a] = mcount[b]; + mcount[b] = v; + v = mlist[a]; + mlist[a] = mlist[b]; + mlist[b] = v; + v = mtype[a]; + mtype[a] = mtype[b]; + mtype[b] = v; + v = msize[a]; + msize[a] = msize[b]; + msize[b] = v; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void bubblesort(int n) { + int j,k,sorted; + + k = n; + sorted = 0; + + while ((k > 0) && (sorted == 0)) { + sorted = 1; + for (j = 0; j < k; j++) { + if (mcount[j] < mcount[j+1]) { + bs_swap(j, j+1); + sorted = 0; + } + } + k--; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void PreRendMicros() +{ + long i,j,llvls; + WORD k; + long nPNum; + long tl, tms, total; + int numrend; + WORD *mt; + int t, tlen; + int ok2rend; + + for (i = 0; i < MAXMICRO; i++) { + mlist[i] = i; + mcount[i] = 0; + mtype[i] = 0; + } + + if (leveltype != 4) tlen = 10; + else tlen = 12; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + mt = &(dMT[i][j].mt[0]); + for(t = 0; t < tlen; t++) + { + nPNum = mt[t]; + if (nPNum) { + mcount[nPNum & 0xfff]++; + mtype[nPNum & 0xfff] = nPNum & 0x7000; + } + } + } + } + + __asm { + mov ebx,dword ptr [pDungeonCels] + mov eax,dword ptr [ebx] + mov dword ptr [tms],eax + } + nummicros = tms & 0xffff; + + for (i = 0; i < nummicros; i++) { + nPNum = i; + __asm { + mov ebx,dword ptr [pDungeonCels] + mov eax,dword ptr [nPNum] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] // Size + sub eax,dword ptr [ebx] + mov dword ptr [tms],eax + } + msize[i] = tms & 0xffff; + } + msize[0] = 0; // Zero doesn't exist + + + // On level type 4 we cycle the lava using the translation tables so it can't + // be prerendered + if (leveltype == 4) { + for (i = 0; i < nummicros; i++) { + nPNum = i; + ok2rend = 1; + if (mcount[i] == 0) continue; + if (mtype[i] != 0x1000) { + tl = msize[i]; + __asm { + mov ebx,dword ptr [pDungeonCels] + mov eax,dword ptr [nPNum] + shl eax,2 + add ebx,eax + mov esi,dword ptr [pDungeonCels] + add esi,dword ptr [ebx] // Source + + xor ebx,ebx + + mov ecx,dword ptr [tl] // Number of bytes to translate + jecxz _XSkip +_XLp1: lodsb + cmp al,0 + je _XOk1 + cmp al,32 + jae _XOk1 + mov dword ptr [ok2rend],ebx +_XOk1: loop _XLp1 +_XSkip: nop + } + } else { + __asm { + mov ebx,dword ptr [pDungeonCels] + mov eax,dword ptr [nPNum] + shl eax,2 + add ebx,eax + mov esi,dword ptr [pDungeonCels] + add esi,dword ptr [ebx] // Source + + xor ebx,ebx + + mov ecx,32 +_X1Lp1: push ecx + mov edx,32 +_X1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _X1J + + sub edx,eax + + mov ecx,eax +_X1Lp3: lodsb + cmp al,0 + je _XOk2 + cmp al,32 + jae _XOk2 + mov dword ptr [ok2rend],ebx +_XOk2: loop _X1Lp3 + or edx,edx + jz _X1Nxt + jmp _X1Lp2 + +_X1J: neg al // Do jump + sub edx,eax + jnz _X1Lp2 +_X1Nxt: pop ecx + loop _X1Lp1 + } + } + if (ok2rend == 0) mcount[i] = 0; + } + } + + bubblesort(MAXMICRO-1); + + total = 0; + numrend = 0; + if (light4flag) { + while (total < 1048576) { + total = total + ((long)msize[numrend] << 1); + numrend++; + } + } else { + while (total < 1048576) { + total = total + ((long)msize[numrend] << 4) - ((long)msize[numrend] << 1); + numrend++; + } + } + numrend--; + + if (numrend > MAXMREND) numrend = MAXMREND; + + // Pre render the most used + total = 0; + if (light4flag) llvls = 3; + else llvls = 15; + for (j = 0; j < numrend; j++) { + nPNum = mlist[j]; + microoffset[j][0] = nPNum; + if (mtype[j] != 0x1000) { + tl = msize[j]; + // Pre render for each light level + for (i = 1; i < llvls; i++) { + microoffset[j][i] = total; + __asm { + mov ebx,dword ptr [pDungeonCels] + mov eax,dword ptr [nPNum] + shl eax,2 + add ebx,eax + mov esi,dword ptr [pDungeonCels] + add esi,dword ptr [ebx] // Source + + mov edi,dword ptr [pSpeedCels] + add edi,dword ptr [total] + + mov ebx,dword ptr [i] // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl] + + mov ecx,dword ptr [tl] // Number of bytes to translate + jecxz _Skip + +_Lp1: lodsb + xlatb + stosb + loop _Lp1 +_Skip: nop + } + total += tl; + } + } else { + // Pre render for each light level + for (i = 1; i < llvls; i++) { + microoffset[j][i] = total; + __asm { + mov ebx,dword ptr [pDungeonCels] + mov eax,dword ptr [nPNum] + shl eax,2 + add ebx,eax + mov esi,dword ptr [pDungeonCels] + add esi,dword ptr [ebx] // Source + + mov edi,dword ptr [pSpeedCels] + add edi,dword ptr [total] + + mov ebx,dword ptr [i] // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl] + + mov ecx,32 +_T1Lp1: push ecx + mov edx,32 +_T1Lp2: xor eax,eax // Load control byte + lodsb + stosb + or al,al + js _T1J + + sub edx,eax + + mov ecx,eax +_T1Lp3: lodsb + xlatb + stosb + loop _T1Lp3 + or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + sub edx,eax + jnz _T1Lp2 +_T1Nxt: pop ecx + loop _T1Lp1 + } + total += msize[j]; + } + } + } + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] != 0) { + mt = &(dMT[i][j].mt[0]); + for(t = 0; t < tlen; t++) + { + if (mt[t]) { + for (k = 0; k < numrend; k++) { + if ((mt[t] & 0xfff) == mlist[k]) { + mt[t] = mtype[k] + 0x8000 + k; + k = numrend; + } + } + } + } + } + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +int CalcRot(int x, int y) +{ + int rot; + + if(x < DMAXX - y) + rot = ((y*y+y) + ((2*y + x + 3)*x))/2; + else + { + x = DMAXX - x - 1; + y = DMAXY - y - 1; + rot = (DMAXX)*(DMAXY)-(1 + ((y*y+y) + ((2*y + x + 3)*x))/2); + } + return rot; +} + +/*-----------------------------------------------------------------------** + * RotateMicros + * + * Rotates the dMT array by 45 degrees, so that when drawn to the screen, + * the elements are read sequentially. Previously, DrawHTileLine had to + * scan through dMT diagonally, which causes a lot of caching. +**-----------------------------------------------------------------------*/ + +void RotateMicros() +{ + int x,y; + + for(x = 0; x < DMAXX; x++) + { + for(y = 0; y < DMAXX; y++) + { + dMT2[CalcRot(x,y)] = dMT[x][y]; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetDungeonMicros() +{ + int wv; + int i,j; + WORD *mtsource; + int t; + WORD *mt; + int tlen; + + if (leveltype != 4) { + MicroTileLen = 10; + tlen = 10; + } else { + MicroTileLen = 12; + tlen = 16; + } + // Init the light values for each piece + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + wv = dPiece[i][j]; + mt = &(dMT[i][j].mt[0]); + if (wv != 0) { + wv--; + if (leveltype != 4) mtsource = (WORD *)(pMiniTiles + 20*wv); + else mtsource = (WORD *)(pMiniTiles + 32*wv); + for(t = 0; t < tlen; t++) + // MiniTiles array uses opposite y direction + // hence wierd index on next line + mt[t] = mtsource[(tlen-2)-(t&0xe)+(t&1)]; + } + else + { + for(t = 0; t < tlen; t++) + mt[t] = 0; + } + } + } + + PreRendMicros(); + + RotateMicros(); + + if (svgamode) { + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + } else { + ViewDX = 384; + ViewDY = 224; + ViewBX = 6; + ViewBY = 7; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DRLG_InitTrans() +{ + // Init the transparent values for each piece + ZeroMemory(dTransVal,sizeof(dTransVal)); + ZeroMemory(TransList,sizeof(TransList)); + // JKE TransVal = 1; + TransVal = 1; +} + +/*-----------------------------------------------------------------------** +** Do Transparent values on megatiles +**-----------------------------------------------------------------------*/ + +void DRLG_MRectTrans(int x1, int y1, int x2, int y2) +{ + int i,j; + + x1 = (x1 << 1) + DIRTEDGED2 + 1; + y1 = (y1 << 1) + DIRTEDGED2 + 1; + x2 = (x2 << 1) + DIRTEDGED2; + y2 = (y2 << 1) + DIRTEDGED2; + for (j = y1; j <= y2; j++) { + for (i = x1; i <= x2; i++) dTransVal[i][j] = TransVal; + } + TransVal++; +} + +/*-----------------------------------------------------------------------** +** Copy Transparent values on megatiles level with 4 flags for mini +**-----------------------------------------------------------------------*/ + +void DRLG_MCopyTrans(int sx, int sy, int dx, int dy, BOOL ul, BOOL ur, BOOL ll, BOOL lr) +{ + char v; + + sx = (sx << 1) + DIRTEDGED2; + sy = (sy << 1) + DIRTEDGED2; + v = dTransVal[sx][sy]; + dx = (dx << 1) + DIRTEDGED2; + dy = (dy << 1) + DIRTEDGED2; + if (ul) dTransVal[dx][dy] = v; + if (ur) dTransVal[dx+1][dy] = v; + if (ll) dTransVal[dx][dy+1] = v; + if (lr) dTransVal[dx+1][dy+1] = v; +} + +/*-----------------------------------------------------------------------** +** Do Transparent values on minitiles +**-----------------------------------------------------------------------*/ + +void DRLG_RectTrans(int x1, int y1, int x2, int y2) +{ + int i,j; + + for (j = y1; j <= y2; j++) { + for (i = x1; i <= x2; i++) dTransVal[i][j] = TransVal; + } + TransVal++; +} + +/*-----------------------------------------------------------------------** +** Copy Transparent values on minitile level +**-----------------------------------------------------------------------*/ + +void DRLG_CopyTrans(int sx, int sy, int dx, int dy) +{ + dTransVal[dx][dy] = dTransVal[sx][sy]; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DRLG_ListTrans(int num, byte *List) +{ + int i; + byte x1,y1,x2,y2; + + for (i = 0; i < num; i++) { + x1 = *List++; + y1 = *List++; + x2 = *List++; + y2 = *List++; + DRLG_RectTrans(x1, y1, x2, y2); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DRLG_AreaTrans(int num, byte *List) +{ + int i; + byte x1,y1,x2,y2; + + for (i = 0; i < num; i++) { + x1 = *List++; + y1 = *List++; + x2 = *List++; + y2 = *List++; + DRLG_RectTrans(x1, y1, x2, y2); + TransVal--; + } + TransVal++; +} + +/*-----------------------------------------------------------------------** +** Fuckin all problems solved with this routine +**-----------------------------------------------------------------------*/ + +void DRLG_InitSetPC() +{ + setpc_x = 0; + setpc_y = 0; + setpc_w = 0; + setpc_h = 0; +} + +/*-----------------------------------------------------------------------** +** Don't put rnd monsters, objects in set piece areas +**-----------------------------------------------------------------------*/ + +void DRLG_SetPC() +{ + int i,j; + int x,y,w,h; + + w = setpc_w << 1; + h = setpc_h << 1; + x = (setpc_x << 1) + DIRTEDGED2; + y = (setpc_y << 1) + DIRTEDGED2; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) dFlags[x+i][y+j] |= BFLAG_SETPC; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Make_SetPC(int x, int y, int w, int h) +{ + int i,j; + int dx, dy, dh, dw; + + dw = w << 1; + dh = h << 1; + dx = (x << 1) + DIRTEDGED2; + dy = (y << 1) + DIRTEDGED2; + for (j = 0; j < dh; j++) { + for (i = 0; i < dw; i++) dFlags[dx+i][dy+j] |= BFLAG_SETPC; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawDungMiniMap(unsigned char floor) +/*-----------------------------------------------------------------------** +** DESCRIPTION: Draws a mini map of the dungeon and player locations. +** INPUT: floor = The floor type to look for +** RETURN: None +/*-----------------------------------------------------------------------*/ +{ + int *p; + byte *d; + unsigned int pSize; + int pIndex, pXMega, pYMega, pX, pY; + + p = &plr[0]._px; + d = &dungeon[0][0]; + pSize = sizeof(PlayerStruct); + + //*NOTE* The x and y coords had to be swapped in the compares to ecx and edx + // to get the proper output coordinates for the players. + + app_assert(gpBuffer); + __asm { + mov esi,dword ptr [d] + mov edi,dword ptr [gpBuffer] + add edi,135248 + mov edx,MDMAXY +_YLp: + push edi + mov ecx,MDMAXX +_XLp: + lodsb //Read byte from dungeon array + +//Start Search for Player coords + push eax + push esi + push edi + mov esi,dword ptr [p] //PlayerStruct._px + mov edi,0 //Initialize plr array index +LoopThruPlayers: + lodsd //Get _px + mov pX,eax //Fill in pX + lodsd //Get _py + mov pY,eax //Fill in pY + add esi,pSize //Add sizeof(PlayerStruct) + sub esi,8 //Subtract 2 dwords read + cmp pX,0 //Ignore 0,0 coords + jnz PNotOrigin + cmp pY,0 //Ignore 0,0 coords + jz PNoX +PNotOrigin: + mov pIndex,edi //Save plr index + jmp PMiniToMega //Convert mini tiles to mega tiles +PMegaFound: + cmp edx,pXMega //Did we match a players x coord? + jnz PNoX + cmp ecx,pYMega //Did we match a players y coord? + jz Player +PNoX: + inc edi //Increment index + cmp edi,MAX_PLRS //Are we done with our for loop? + jl LoopThruPlayers + pop edi + pop esi + pop eax +//End Search for Player coords + + cmp al,floor //Did we find a floor piece? + jz NoSave //Let background show thru + jmp Other //We found a wall or something +Player: + pop edi + pop esi + pop eax + cmp pIndex,0 //Are we dealing with player 0? + jnz Player1 + mov al,240 //Set color to white + jmp Save +Player1: + cmp pIndex,1 //Are we dealing with player 1? + jnz Player2 + mov al,139 //Set color to red + jmp Save +Player2: + cmp pIndex,2 //Are we dealing with player 2? + jnz Player3 + mov al,154 //Set color to orange + jmp Save +Player3: //We are dealing with player 3 + mov al,147 //Set color to yellow + jmp Save +Other: + mov al,131 //Set color to blue +Save: + mov byte ptr [edi],al + mov byte ptr [edi+1],al + mov byte ptr [edi+768],al + mov byte ptr [edi+769],al +NoSave: + add edi,1536 + dec ecx + jnz _XLp + pop edi + add edi,2 + dec edx + jnz _YLp + jmp EndL2DrawDung + +//Start Convert player mini tiles to mega tiles +PMiniToMega: + push eax + push edx + mov eax,pX + sub eax,DIRTEDGED2 + shr eax,1 + mov edx,MDMAXX + sub edx,eax + mov pXMega,edx + mov eax,pY + sub eax,DIRTEDGED2 + shr eax,1 + mov edx,MDMAXY + sub edx,eax + mov pYMega,edx + pop edx + pop eax + jmp PMegaFound +//End Convert player mini tiles to mega tiles + +EndL2DrawDung: + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL DRLG_WillThemeRoomFit(int floor, + int x, + int y, + int minSize, + int maxSize, + int *width, + int *height) +/*-----------------------------------------------------------------------** +** DESCRIPTION: Checks if a theme room between minSize and maxSize will fit at +** (x, y). +** INPUT: floor = Floor value to look for +** x, y = Top left corner to start search from +** minSize = Min sized room to create. This will actually create a room of +** size (minSize - 2) to account for a hall, 1 megatile wide, +** around the room. +** maxSize = Max sized room to create. This will actually create a room of +** size (maxSize - 2) to account for a hall, 1 megatile wide, +** around the room. +** *width = Actual room width return value +** *height = Actual room height return value +** +** RETURN: FALSE = Could not fit a room with specified parameters +** TRUE = Room dimensions were found +/*-----------------------------------------------------------------------*/ +{ + int ii, xx, yy; + int xSmallest, ySmallest; + int xArray[20]; + int yArray[20]; + int xCount = 0; + int yCount = 0; + BOOL yFlag = TRUE; + BOOL xFlag = TRUE; + + //Check to see if we are within the bounds of the dungeon[40][40] array + if ((x > (MDMAXX - maxSize)) && (y > (MDMAXY - maxSize))) + return FALSE; + + //Skip any existing theme rooms + if (!SkipThemeRoom(x, y)) + return FALSE; + + //Intialize arrays + memset(xArray, 0x00, sizeof(xArray)); + memset(yArray, 0x00, sizeof(yArray)); + + //Find the lengths of each row and column + for (ii = 0; ii < maxSize; ii++) { + //Find the row lengths + if (xFlag) { + for (xx = x; xx < (x + maxSize); xx++) { + //We ran into a wall or something + if (dungeon[xx][y+ii] != floor) { + if (xx < minSize) xFlag = FALSE; + else break; + } else xCount++; + } + if (xFlag) { + xArray[ii] = xCount; + xCount = 0; + } + } + //Find the column lengths + if (yFlag) { + for (yy = y; yy < (y + maxSize); yy++) { + //We ran into a wall or something + if (dungeon[x+ii][yy] != floor) { + if (yy < minSize) yFlag = FALSE; + else break; + } else yCount++; + } + if (yFlag) { + yArray[ii] = yCount; + yCount = 0; + } + } + } + //Make sure we meet the minimum requirements + for (ii = 0; ii < minSize; ii++) { + if (xArray[ii] < minSize || yArray[ii] < minSize) return FALSE; + } + //Initialize + xSmallest = xArray[0]; + ySmallest = yArray[0]; + //Find the best x and y values + for (ii = 0; ii < maxSize; ii++) { + if (xArray[ii] >= minSize && yArray[ii] >= minSize) { + if (xArray[ii] < xSmallest) xSmallest = xArray[ii]; + if (yArray[ii] < ySmallest) ySmallest = yArray[ii]; + } else break; + } + //Set the room dimenions + *width = xSmallest - 2; //Subtract 2 to acount for hall around room + *height = ySmallest - 2; //Subtract 2 to acount for hall around room + + return TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DRLG_CreateThemeRoom(int themeIndex) +/*-----------------------------------------------------------------------** +** DESCRIPTION: Creates themeIndex theme room in the themeLoc array. +** INPUT: themeIndex = Index into themeLoc array +** RETURN: None +/*-----------------------------------------------------------------------*/ +{ + int xx; + int yy; + + //Add the walls + for (yy = themeLoc[themeIndex].y; yy < (themeLoc[themeIndex].y + themeLoc[themeIndex].height); yy++) { + for (xx = themeLoc[themeIndex].x; xx < (themeLoc[themeIndex].x + themeLoc[themeIndex].width); xx++) { + if (leveltype == 2) { + //TOP/BOTTOM WALLS + if ((yy == themeLoc[themeIndex].y && (xx >= themeLoc[themeIndex].x && (xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width))) || + ((yy == themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)) && (xx >= themeLoc[themeIndex].x && (xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width)))) + dungeon[xx][yy] = 2; //HWALL_PIECE + //RIGHT/LEFT WALLS + else if ((xx == themeLoc[themeIndex].x && (yy >= themeLoc[themeIndex].y && (yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height))) || + ((xx == themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)) && (yy >= themeLoc[themeIndex].y && (yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height)))) + dungeon[xx][yy] = 1; //VWALL_PIECE + //FLOOR PIECE + else dungeon[xx][yy] = 3; //FLOOR_PIECE + } + if (leveltype == 3) { + //UPPER/LOWER WALL + if ((yy == themeLoc[themeIndex].y && (xx >= themeLoc[themeIndex].x && (xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width))) || + ((yy == themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)) && (xx >= themeLoc[themeIndex].x && (xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width)))) + dungeon[xx][yy] = 134; //WOOD_HORIZWALL + //RIGHT/LEFT WALL + else if ((xx == themeLoc[themeIndex].x && (yy >= themeLoc[themeIndex].y && (yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height))) || + ((xx == themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)) && (yy >= themeLoc[themeIndex].y && (yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height)))) + dungeon[xx][yy] = 137; //WOOD_VERTWALL + //FLOOR PIECE + else dungeon[xx][yy] = 7; //FLOOR + } + if (leveltype == 4) { + //UPPER/LOWER WALL + if ((yy == themeLoc[themeIndex].y && (xx >= themeLoc[themeIndex].x && (xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width))) || + ((yy == themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)) && (xx >= themeLoc[themeIndex].x && (xx <= themeLoc[themeIndex].x + themeLoc[themeIndex].width)))) + dungeon[xx][yy] = 2; //HWALL_PIC + //RIGHT/LEFT WALL + else if ((xx == themeLoc[themeIndex].x && (yy >= themeLoc[themeIndex].y && (yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height))) || + ((xx == themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)) && (yy >= themeLoc[themeIndex].y && (yy <= themeLoc[themeIndex].y + themeLoc[themeIndex].height)))) + dungeon[xx][yy] = 1; //VWALL_PIC + //FLOOR PIECE + else dungeon[xx][yy] = 6; //FLOOR_PIC + } + } + } + + //Add the corners + if (leveltype == 2) { + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y] = 8; //ULWALL_PIECE + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y] = 7; //URWALL_PIECE + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 9; //LLWALL_PIECE + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 6; //LRWALL_PIECE + } + if (leveltype == 3) { + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y] = 150; //WOOD_ULCORNER + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y] = 151; //WOOD_URCORNER + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 152; //WOOD_LLCORNER + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 138; //WOOD_LRCORNER + } + if (leveltype == 4) { + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y] = 9; //ULWALL_PIC + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y] = 16; //URWALL_PIC + dungeon[themeLoc[themeIndex].x][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 15; //LLWALL_PIC + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 12; //LRWALL_PIC + } + + //Add the door to the east or south wall + if (leveltype == 2) { + switch(random(0, 2)) { + //East wall + case 0 : dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height / 2)] = 4; //VDOOR_PIECE + break; + //South wall + case 1 : dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width / 2)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 5; //HDOOR_PIECE + break; + } + } + if (leveltype == 3) { + switch(random(0, 2)) { + //East wall + case 0 : dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height / 2)] = 147; //WOOD_VERTGATE + break; + //South wall + case 1 : dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width / 2)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 146; //WOOD_HORIZGATE + break; + } + } + if (leveltype == 4) { + switch(random(0, 2)) { + //East wall + case 0 : dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][(themeLoc[themeIndex].y + (themeLoc[themeIndex].height / 2))-1] = 53; //VERT RIGHT + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height / 2)] = 6; //FLOOR_PIC + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-1)][(themeLoc[themeIndex].y + (themeLoc[themeIndex].height / 2))+1] = 52; //VERT LEFT + //Add Shadows + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width-2)][(themeLoc[themeIndex].y + (themeLoc[themeIndex].height / 2))-1] = 54; + break; + //South wall + case 1 : dungeon[(themeLoc[themeIndex].x + (themeLoc[themeIndex].width / 2))-1][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 57; //HORIZ LEFT + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width / 2)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 6; //FLOOR_PIC + dungeon[(themeLoc[themeIndex].x + (themeLoc[themeIndex].width / 2))+1][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-1)] = 56; //HORIZ RIGHT + //Add Shadows + dungeon[themeLoc[themeIndex].x + (themeLoc[themeIndex].width / 2)][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-2)] = 59; + dungeon[(themeLoc[themeIndex].x + (themeLoc[themeIndex].width / 2))-1][themeLoc[themeIndex].y + (themeLoc[themeIndex].height-2)] = 58; + break; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DRLG_PlaceThemeRooms(int minSize, + int maxSize, + int floor, + int freq, + BOOL rndSize) +/*-----------------------------------------------------------------------** +** DESCRIPTION: Places theme rooms in dungeon types 2,3 & 4. +** INPUT: minSize = The minimum sized room to create +** maxSize = The maximum sized room to create +** floor = The floor value to look for +** freq = The frequency to check for theme rooms. Set to 0 if you +** want to check everything. +** rndSize = If TRUE, then create rooms between max and min. If FALSE, +** then the largest theme rooms in an area will be created. +** RETURN: None +/*-----------------------------------------------------------------------*/ +{ + int i; + int j; + int themeW; + int themeH; + + //Initialize + themeCount = 0; + memset(themeLoc, 0x00, sizeof(THEME_LOC)); + + //Loop thru dungeon array + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) { + //Did we find a floor piece? + if ((dungeon[i][j] == floor) && (!random(0, freq))) { + //Check to see if theme room can fit + if (DRLG_WillThemeRoomFit(floor, i, j, minSize, maxSize, &themeW, &themeH)) { + //Do we want a random room size between max and min? + if (rndSize) { + int rv1, rv2, min, max; + min = minSize - 2; + max = maxSize - 2; + //Get a random width + rv1 = random(0, ((themeW-min)+1)); + rv2 = min + random(0, rv1); + if (rv2 < min || rv2 > max) themeW = min; + else themeW = rv2; + //Get a random height + rv1 = random(0, ((themeH-min)+1)); + rv2 = min + random(0, rv1); + if (rv2 < min || rv2 > max) themeH = min; + else themeH = rv2; + } + //Update the theme array + themeLoc[themeCount].x = i+1; + themeLoc[themeCount].y = j+1; + themeLoc[themeCount].width = themeW; + themeLoc[themeCount].height = themeH; + //Get transparency value + //Had to add special case in for L3 + if (leveltype == 3) { + DRLG_RectTrans( + ((i+2) << 1) + DIRTEDGED2, + ((j+2) << 1) + DIRTEDGED2, + (((i+themeW)-1) << 1) + DIRTEDGED2+1, + (((j+themeH)-1) << 1) + DIRTEDGED2+1); + } else DRLG_MRectTrans(i+1, j+1, (i+themeW), (j+themeH)); + themeLoc[themeCount].ttval = TransVal-1; + //Add the new theme room to the dungeon + DRLG_CreateThemeRoom(themeCount); + //Increment theme count + themeCount++; + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DRLG_HoldThemeRooms() +/*-----------------------------------------------------------------------** +** DESCRIPTION: Holds theme rooms created in dungeon types 2,3 & 4. +** INPUT: None +** RETURN: None +/*-----------------------------------------------------------------------*/ +{ + int i, x, y, xx, yy; + + if (themeCount > 0) { + for (i = 0; i < themeCount; i++) { + for (y = themeLoc[i].y; y < (themeLoc[i].y + themeLoc[i].height)-1; y++) { + for (x = themeLoc[i].x; x < (themeLoc[i].x + themeLoc[i].width)-1; x++) { + //Mega tiles to mini tiles + xx = (x << 1) + DIRTEDGED2; + yy = (y << 1) + DIRTEDGED2; + dFlags[xx][yy] |= BFLAG_SETPC; + dFlags[xx+1][yy] |= BFLAG_SETPC; + dFlags[xx][yy+1] |= BFLAG_SETPC; + dFlags[xx+1][yy+1] |= BFLAG_SETPC; + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL SkipThemeRoom( int x, int y ) +/*-----------------------------------------------------------------------** +** DESCRIPTION: Skips any existing theme rooms +** INPUT: None +** RETURN: TRUE = If not in a theme room +** FALSE = If in a theme room +/*-----------------------------------------------------------------------*/ +{ + int i; + + //Skip all L2, L3, & L4 themes rooms + for (i = 0; i < themeCount; i++) { + if ((x >= themeLoc[i].x-2 && x <= (themeLoc[i].x + themeLoc[i].width)+2) && + (y >= themeLoc[i].y-2 && y <= (themeLoc[i].y + themeLoc[i].height)+2)) + //We are inside a theme room + return FALSE; + } + + return TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitLevels() +{ + if (! leveldebug) { + currlevel = 0; + leveltype = 0; + setlevel = FALSE; + } +} + diff --git a/GENDUNG.H b/GENDUNG.H new file mode 100644 index 0000000..c866db4 --- /dev/null +++ b/GENDUNG.H @@ -0,0 +1,234 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/GENDUNG.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define LVLLENGTH 4 + +#define TLVL_START 0 +#define LVL1_START 1 +#define LVL2_START LVL1_START+LVLLENGTH +#define LVL3_START LVL2_START+LVLLENGTH +#define LVL4_START LVL3_START+LVLLENGTH +//HellFire JKE 7/29 +#define LVL5_START LVL4_START+LVLLENGTH +#define CRYPTSTART 21 +#define CRYPTEND 24 +#define HIVESTART 17 +#define HIVEEND 20 + +//#define NUMLEVELS ((4*LVLLENGTH)+1) +#define NUMLEVELS ((6*LVLLENGTH)+1) //HellFire JKE 7/29 +#define NUMSLEVELS 10 + +#define DIRTEDGE 32 +#define DIRTEDGED2 (DIRTEDGE/2) +#define DMAXX (80+DIRTEDGE) +#define DMAXY (80+DIRTEDGE) +#define MAXDUNX DMAXX +#define MAXDUNY DMAXY + +#define MDMAXX ((DMAXX-DIRTEDGE)/2) // Mega tile dungeon max (max div 2) +#define MDMAXY ((DMAXY-DIRTEDGE)/2) + +#define MAXTILES 2048 + +#define MAXMREND 128 + +#define NUMSPEEDCELS 64 +#define SPEEDSIZE NUMSPEEDCELS*16384 + +#define MAXMICRO 2048 + +#define MAXDIRT 32 + +#define NODRAW 0 +#define VIEWDRAW 1 +#define FULLDRAW 0xff + +#define SCRL_NONE 0 +#define SCRL_U 1 +#define SCRL_UR 2 +#define SCRL_R 3 +#define SCRL_DR 4 +#define SCRL_D 5 +#define SCRL_DL 6 +#define SCRL_L 7 +#define SCRL_UL 8 + +// bFlags bits +#define BFLAG_AUTOMAP 0x80 +#define BFLAG_VISIBLE 0x40 +#define BFLAG_PLRLR 0x20 +#define BFLAG_MONSTLR 0x10 +#define BFLAG_SETPC 0x08 +#define BFLAG_DEADPLR 0x04 + +// Set Piece bit used in all drlg's +#define SETP_BIT 0x80 // Non changeable set piece bit + +#define BFLAG_MONSTACTIVE 0x02 +#define BFLAG_MISSILE 0x01 + +#define BFMASK_AUTOMAP 0x7f +#define BFMASK_VISIBLE 0xbf +#define BFMASK_PLRLR 0xdf +#define BFMASK_MONSTLR 0xef +#define BFMASK_SETPC 0xf7 +//#define BFMASK_UNUSED 0xfb +//#define BFMASK_UNUSED 0xfd +#define BFMASK_MISSILE 0xfe + +#define WTYPE_NONE 0 +#define WTYPE_LEFT 1 +#define WTYPE_RIGHT 2 +#define WTYPE_ULC 3 +#define WTYPE_LRC 4 + +#define D_NORMAL 0 +#define D_NIGHTMARE 1 +#define D_HELL 2 + +/*-----------------------------------------------------------------------** +** Macros +**-----------------------------------------------------------------------*/ +#define MegaToMini(M) ((M << 1) + DIRTEDGED2) +#define MiniToMega(m) ((m - DIRTEDGED2) >> 1) + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + byte strig; + byte s1; + byte s2; + byte s3; + byte nv1; + byte nv2; + byte nv3; +} ShadowStruct; + +typedef struct { + int _sxoff; // Smooth scroll x,y offsets + int _syoff; + int _sdx; // Delta between plr and view x,y + int _sdy; + int _sdir; // Direction +} ScrollStruct; + +typedef struct THEME_LOC { + int x; //Upper left coord + int y; //Upper left coord + int ttval; //Transparency value + int width; //Room width + int height; //Room height +} THEME_LOC; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern byte dungeon[MDMAXX][MDMAXY]; +extern byte pdungeon[MDMAXX][MDMAXY]; +extern byte dflags[MDMAXX][MDMAXY]; + +extern int setpc_x, setpc_y, setpc_w, setpc_h; +extern byte *pSetPiece; +extern BOOL setloadflag; + +extern "C" { + extern BYTE *pDungeonCels; + extern BYTE *pSpeedCels; + extern long microoffset[MAXMREND][16]; + extern byte nWTypeTable[MAXTILES+1]; +} + +extern BYTE *pSpecialCels; +extern BYTE *pMegaTiles; +extern BYTE *pMiniTiles; + +extern BYTE nBlockTable[MAXTILES+1]; +extern BYTE nSolidTable[MAXTILES+1]; +extern BYTE nTransTable[MAXTILES+1]; +extern BYTE nMissileTable[MAXTILES+1]; +extern BYTE nTrapTable[MAXTILES+1]; + +extern int dminx, dminy, dmaxx, dmaxy; + +extern int gnDifficulty; + +extern BYTE currlevel; +extern BYTE leveltype; +extern BYTE setlevel; +extern BYTE setlvlnum; +extern BYTE setlvltype; + +extern int ViewX, ViewY; +extern int ViewDX, ViewDY; +extern int ViewBX, ViewBY; +extern ScrollStruct ScrollInfo; + +extern int LvlViewX, LvlViewY; + +extern int btmbx, btmby; +extern int btmdx, btmdy; + +extern int MicroTileLen; + +extern char TransVal; +extern BYTE TransList[256]; + +extern int dPiece[MAXDUNX][MAXDUNY]; // Tile # + +typedef struct { WORD mt[16]; } MICROS; +extern MICROS dMT[MAXDUNX][MAXDUNY]; // Micro Tiles +extern MICROS dMT2[MAXDUNX*MAXDUNY]; + +extern char dTransVal[MAXDUNX][MAXDUNY]; // Transparent active value +extern char dLight[MAXDUNX][MAXDUNY]; // Current light value +extern char dSaveLight[MAXDUNX][MAXDUNY]; // Static light value +extern char dFlags[MAXDUNX][MAXDUNY]; // Flags for Solid collision, etc. +extern char dPlayer[MAXDUNX][MAXDUNY]; // Player +extern int dMonster[MAXDUNX][MAXDUNY]; // Monster +extern char dDead[MAXDUNX][MAXDUNY]; // Dead plr/monster +extern char dObject[MAXDUNX][MAXDUNY]; // Objects +extern char dItem[MAXDUNX][MAXDUNY]; // Items +extern char dMissile[MAXDUNX][MAXDUNY]; // Missiles (0 = none, # = missile, -1 = two or more) +extern char dSpecial[MAXDUNX][MAXDUNY]; // Second layer of tiling +extern int themeCount; +extern THEME_LOC themeLoc[50]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +int CalcRot(int x, int y); +void SetDungeonMicros(); +void FillSolidBlockTbls (); + +void DRLG_InitTrans(); +void DRLG_MRectTrans(int, int, int, int); +void DRLG_MCopyTrans(int, int, int, int, BOOL, BOOL, BOOL, BOOL); +void DRLG_RectTrans(int, int, int, int); +void DRLG_CopyTrans(int, int, int, int); +void DRLG_ListTrans(int, byte *); +void DRLG_AreaTrans(int, byte *); +void DRLG_InitSetPC(); +void DRLG_SetPC(); +void Make_SetPC(int x, int y, int w, int h); +void DrawDungMiniMap(unsigned char floor); +BOOL DRLG_WillThemeRoomFit(int, int, int, int, int, int *, int *); +void DRLG_CreateThemeRoom(int); +void DRLG_PlaceThemeRooms(int, int, int, int, BOOL); +void DRLG_HoldThemeRooms(); +BOOL SkipThemeRoom(int, int); diff --git a/GMENU.CPP b/GMENU.CPP new file mode 100644 index 0000000..510df0e --- /dev/null +++ b/GMENU.CPP @@ -0,0 +1,527 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Game Menu file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/GMENU.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "gendung.h" +#include "gamemenu.h" +#include "scrollrt.h" +#include "engine.h" +#include "effects.h" + + +//****************************************************************** +// extern +//****************************************************************** +void RedBack(); + + +//****************************************************************** +// kerning +//****************************************************************** +#define KERNSPACE 2 +static const BYTE mfonttrans[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 37, 49, 38, 0, 39, 40, 47, 42, 43, 41, 45, 52, 44, 53, 55, // 32-47 + 36, 27, 28, 29, 30, 31, 32, 33, 34, 35, 51, 50, 0, 46, 0, 54, // 48-63 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 64-79 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 0, 43, 0, 0, // 80-95 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 96-111 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 20, 0, 21, 0, 0 // 112-127 +}; +static const BYTE mfontkern[56] = { 18, // Space/Invalid + 33, 21, 26, 28, 19, 19, 26, 25, 11, 12, 25, 19, 34, 28, 32, 20, // a-p + 32, 28, 20, 28, 36, 35, 46, 33, 33, 24, // q-z + 11, 23, 22, 22, 21, 22, 21, 21, 21, 32, // 1-0 + 10, 20, 36, 31, 17, 13, 12, 13, 18, 16, 11, 20, 21, 11, 10, 12, 11, 21, 23 // misc +}; + + +//****************************************************************** +// private data +//****************************************************************** +static BYTE sgbGameSpin; +static BYTE sgbTitleAnimate; +static BYTE * sgpLogo; +static BYTE * sgpSpinCels; +static BYTE * sgpMenuCels; +static BYTE * sgpSliderCels; +static BYTE * sgpBarCels; +static TMenuItem * sgpMenu; +static TMenuUpdateFcn sgfnMenuUpdateFcn; +static TMenuItem * sgpCurrItem; +static DWORD sgdwMenuItems; +static long sglSpinnerTime; +static long sglTitleTime; +static BYTE sgbTracking; + +#define MENU_STARTY 320 +#define MENU_CLICKY (MENU_STARTY - 203) +#define MENU_LINEHGT 45 +#define SLIDER_WDT 256 +#define SLIDER_ITEM_WDT 27 +#define SLIDER_TOTAL_WDT 490 + +#define ENABLE_LVAL 0 +#define DISABLE_LVAL 15 + +#define MIN_SLIDER_TICKS 2 +#define SLIDER_TICK_SHIFT 12 +#define MAX_SLIDER_TICKS 0xfff +#define mf_SLIDER_VAL_MASK 0x00000fff +#define mf_SLIDER_TICK_MASK 0x00fff000 + +#define SPINNER_TIME 25 // milliseconds +#define TITLE_TIME 25 // milliseconds + + +//****************************************************************** +//****************************************************************** +static void DrawBigFontXY(int x, int y,const char * pszStr) { + app_assert(pszStr); + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = mfonttrans[c]; + if (c != 0) DrawCelL(x, y, sgpMenuCels, c, 46); + x += mfontkern[c] + KERNSPACE; + } +} + + +//****************************************************************** +//****************************************************************** +void DrawPause() { + if (currlevel != 0) RedBack(); + if (! sgpMenu) { + nLVal = 0; // set light level + DrawBigFontXY(316, 336, "Pause"); + } +} + + +//****************************************************************** +//****************************************************************** +void gmenu_free() { + DiabloFreePtr(sgpLogo); + DiabloFreePtr(sgpMenuCels); + DiabloFreePtr(sgpSpinCels); + DiabloFreePtr(sgpSliderCels); + DiabloFreePtr(sgpBarCels); +} + + +//****************************************************************** +//****************************************************************** +void gmenu_init() { + sgbGameSpin = 1; + sgbTitleAnimate = 1; + sgpMenu = NULL; + sgpCurrItem = NULL; + sgfnMenuUpdateFcn = NULL; + sgdwMenuItems = 0; + sgbTracking = FALSE; + + app_assert(! sgpLogo); + //sgpLogo = LoadFileInMemSig("Data\\Diabsmal.CEL",NULL,'MENU'); + sgpLogo = LoadFileInMemSig("Data\\hf_logo3.CEL",NULL,'MENU'); + sgpMenuCels = LoadFileInMemSig("Data\\BigTGold.CEL",NULL,'MENU'); + sgpSpinCels = LoadFileInMemSig("Data\\PentSpin.CEL",NULL,'MENU'); + sgpSliderCels = LoadFileInMemSig("Data\\option.CEL",NULL,'MENU'); + sgpBarCels = LoadFileInMemSig("Data\\optbar.CEL",NULL,'MENU'); +} + + +//****************************************************************** +//****************************************************************** +BOOL gmenu_is_on() { + return sgpMenu != NULL; +} + + +//****************************************************************** +//****************************************************************** +static void gmenu_change(BOOL bNext) { + if (! sgpCurrItem) return; + sgbTracking = FALSE; + for (DWORD d = sgdwMenuItems; d--; ) { + if (bNext) { + // next item + sgpCurrItem++; + + // wrap at end of list + if (! sgpCurrItem->fnMenu) + sgpCurrItem = sgpMenu; + } + else { + // wrap at beginning of list + if (sgpCurrItem == sgpMenu) + sgpCurrItem = sgpMenu + sgdwMenuItems; + + // prev item + sgpCurrItem--; + } + + if (sgpCurrItem->dwFlags & mf_ENABLED) { + if (d) PlaySFX(IS_TITLEMOV); + break; + } + } +} + + +//****************************************************************** +//****************************************************************** +void gmenu_set_menu(TMenuItem * pMenuItems,TMenuUpdateFcn fnUpdate) { + PauseMode = 0; + + sgpMenu = pMenuItems; + sgbTracking = FALSE; + sgfnMenuUpdateFcn = fnUpdate; + if (sgfnMenuUpdateFcn) sgfnMenuUpdateFcn(sgpMenu); + + // calculate number of items in menu + sgdwMenuItems = 0; + if (sgpMenu) { + for (TMenuItem * pItem = sgpMenu; pItem->fnMenu; pItem++) + sgdwMenuItems++; + } + + // move to the first active item in the menu + sgpCurrItem = sgpMenu + sgdwMenuItems - 1; + gmenu_change(TRUE); +} + + +//****************************************************************** +//****************************************************************** +static void DrawBar(DWORD x,DWORD y,DWORD wdt,DWORD hgt) { + app_assert(gpBuffer); + BYTE * pbDst = gpBuffer + nBuffWTbl[y] + x; + while (hgt--) { + FillMemory(pbDst,wdt,0xcd); + pbDst -= 768; + } +} + + +//****************************************************************** +//****************************************************************** +static DWORD gmenu_calc_item_width(const TMenuItem * pItem) { + // hardcode the size of sliders so they all justify uniformly + // so that the slider bars line up vertically + if (pItem->dwFlags & mf_SLIDER) + return SLIDER_TOTAL_WDT; + + DWORD wdt = 0; + const char * pszStr = pItem->pszStr; + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = mfonttrans[c]; + wdt += mfontkern[c] + KERNSPACE; + } + wdt -= KERNSPACE; + return wdt; +} + + +//****************************************************************** +//****************************************************************** +static void gmenu_draw_item(const TMenuItem * pItem,int yPos) { + DWORD wdt = gmenu_calc_item_width(pItem); + + if (pItem->dwFlags & mf_SLIDER) { + int xPos = 640/2 + wdt/2 + 43 - SLIDER_WDT - SLIDER_ITEM_WDT; + DrawCel(xPos + 0,yPos - 10,sgpBarCels, 1, 287); + DWORD dwLen = pItem->dwFlags & mf_SLIDER_VAL_MASK; + + // scale 0..ticks to 0..SLIDER_WDT + DWORD dwTicks = pItem->dwFlags & mf_SLIDER_TICK_MASK; + dwTicks >>= SLIDER_TICK_SHIFT; + if (dwTicks < MIN_SLIDER_TICKS) dwTicks = MIN_SLIDER_TICKS; + dwLen *= SLIDER_WDT; + dwLen /= dwTicks; + + DrawBar(xPos + 2,yPos - 12,dwLen + SLIDER_ITEM_WDT/2,28); + xPos += dwLen; + DrawCel(xPos + 2,yPos - 12,sgpSliderCels, 1, 27); + } + + // draw string with lighting + int xPos = 640/2 - wdt/2 + 64; + nLVal = (pItem->dwFlags & mf_ENABLED) ? ENABLE_LVAL : DISABLE_LVAL; + DrawBigFontXY(xPos, yPos, pItem->pszStr); + + if (pItem == sgpCurrItem) { + DrawCel(xPos - 54, yPos + 1, sgpSpinCels, sgbGameSpin, 48); + DrawCel(xPos + wdt + 4, yPos + 1, sgpSpinCels, sgbGameSpin, 48); + } +} + + +//****************************************************************** +//****************************************************************** +void gmenu_draw() { + if (! sgpMenu) return; + if (sgfnMenuUpdateFcn) sgfnMenuUpdateFcn(sgpMenu); + + const TMenuItem * pItem; + long lCurrTime = (long) GetTickCount(); + //DrawCel(236, 262, sgpLogo, 1, 296); + if (lCurrTime - sglTitleTime > TITLE_TIME){ + ++sgbTitleAnimate; + if (sgbTitleAnimate > 16) sgbTitleAnimate = 1; + sglTitleTime = lCurrTime; + } + DrawCel(169, 262, sgpLogo, sgbTitleAnimate, 430); + + // draw items + DWORD yPos = MENU_STARTY; + for (pItem = sgpMenu; pItem->fnMenu; pItem++) { + gmenu_draw_item(pItem,yPos); + yPos += MENU_LINEHGT; + } + + // adjust spinner + if (lCurrTime - sglSpinnerTime > SPINNER_TIME) { + sgbGameSpin++; + if (sgbGameSpin == 9) sgbGameSpin = 1; + sglSpinnerTime = lCurrTime; + } +} + + +//****************************************************************** +//****************************************************************** +static void gmenu_slider(BOOL bNext) { + if (! (sgpCurrItem->dwFlags & mf_SLIDER)) return; + + LONG lVal = sgpCurrItem->dwFlags & mf_SLIDER_VAL_MASK; + LONG lTicks = sgpCurrItem->dwFlags & mf_SLIDER_TICK_MASK; + lTicks >>= SLIDER_TICK_SHIFT; + if (bNext) { + if (lVal == lTicks) return; + lVal++; + } + else { + if (! lVal) return; + lVal--; + } + + sgpCurrItem->dwFlags &= ~mf_SLIDER_VAL_MASK; + sgpCurrItem->dwFlags |= lVal; + sgpCurrItem->fnMenu(FALSE); +} + + +//****************************************************************** +//****************************************************************** +BOOL gmenu_key(WPARAM wKey) { + + if (! sgpMenu) return FALSE; + app_assert(sgpCurrItem); + + switch (wKey) { + case VK_SPACE: + // allow spacebar + return FALSE; + + case VK_LEFT: + gmenu_slider(FALSE); + break; + + case VK_RIGHT: + gmenu_slider(TRUE); + break; + + case VK_UP: + gmenu_change(FALSE); + break; + + case VK_DOWN: + gmenu_change(TRUE); + break; + + case VK_RETURN: + app_assert(sgpCurrItem); + if (sgpCurrItem->dwFlags & mf_ENABLED) { + PlaySFX(IS_TITLEMOV); + sgpCurrItem->fnMenu(TRUE); + } + break; + + case VK_ESCAPE: + PlaySFX(IS_TITLEMOV); + gmenu_set_menu(NULL,NULL); + break; + } + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static BYTE gmenu_mouse_in_slider(LONG * plOffset) { + app_assert(plOffset); + *plOffset = 640/2 + SLIDER_TOTAL_WDT/2 - SLIDER_WDT - SLIDER_ITEM_WDT; + if (MouseX < *plOffset) { + *plOffset = 0; + return FALSE; + } + else if (MouseX > *plOffset + SLIDER_WDT) { + *plOffset = SLIDER_WDT; + return FALSE; + } + + *plOffset = MouseX - *plOffset; + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +BOOL gmenu_mousemove() { + if (! sgbTracking) return FALSE; + app_assert(sgpCurrItem); + + // get position = 0..SLIDER_WDT + LONG lOffset; + gmenu_mouse_in_slider(&lOffset); + + // scale to 0..ticks + LONG lTicks = sgpCurrItem->dwFlags & mf_SLIDER_TICK_MASK; + lTicks >>= SLIDER_TICK_SHIFT; + lOffset *= lTicks; + lOffset /= SLIDER_WDT; + + // set item value + sgpCurrItem->dwFlags &= ~mf_SLIDER_VAL_MASK; + sgpCurrItem->dwFlags |= lOffset; + sgpCurrItem->fnMenu(FALSE); + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +BOOL gmenu_click(BOOL bMouseDown) { + // handle mouseup + if (! bMouseDown) { + if (! sgbTracking) return FALSE; + sgbTracking = FALSE; + return TRUE; + } + + if (! sgpMenu) return FALSE; + if (MouseY >= 352) return FALSE; + + int nItem = MouseY - MENU_CLICKY; + if (nItem < 0) return TRUE; + nItem /= MENU_LINEHGT; + if ((DWORD) nItem >= sgdwMenuItems) return TRUE; + + // only click menu item if it is enabled + TMenuItem * pItem = sgpMenu + nItem; + if (! (pItem->dwFlags & mf_ENABLED)) return TRUE; + + DWORD wdt = gmenu_calc_item_width(pItem); + if ((DWORD) MouseX < 640/2-wdt/2) return TRUE; + if ((DWORD) MouseX > 640/2+wdt/2) return TRUE; + + // set current item + sgpCurrItem = pItem; + PlaySFX(IS_TITLEMOV); + + if (pItem->dwFlags & mf_SLIDER) { + LONG lTemp; + sgbTracking = gmenu_mouse_in_slider(&lTemp); + gmenu_mousemove(); + } + else { + sgpCurrItem->fnMenu(TRUE); + } + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +void gmenu_set_enable(TMenuItem * pMenuItem,BOOL bEnable) { + app_assert(pMenuItem); + if (bEnable) + pMenuItem->dwFlags |= mf_ENABLED; + else + pMenuItem->dwFlags &= ~mf_ENABLED; +} + + +//****************************************************************** +//****************************************************************** +void gmenu_set_slider(TMenuItem * pItem,LONG lMin,LONG lMax,LONG lVal) { + app_assert(pItem); + + LONG lTicks = pItem->dwFlags & mf_SLIDER_TICK_MASK; + lTicks >>= SLIDER_TICK_SHIFT; + if (lTicks < MIN_SLIDER_TICKS) lTicks = MIN_SLIDER_TICKS; + + // make lVal zero-based + lVal -= lMin; + + // scale to slider + lVal *= lTicks; + lVal += (lMax - lMin - 1) / 2; + lVal /= lMax - lMin; + + // store into menu item + pItem->dwFlags &= ~mf_SLIDER_VAL_MASK; + pItem->dwFlags |= lVal; +} + + +//****************************************************************** +//****************************************************************** +LONG gmenu_get_slider(const TMenuItem * pItem,LONG lMin,LONG lMax) { + app_assert(pItem); + + // get value from menu item + LONG lVal = pItem->dwFlags & mf_SLIDER_VAL_MASK; + + LONG lTicks = pItem->dwFlags & mf_SLIDER_TICK_MASK; + lTicks >>= SLIDER_TICK_SHIFT; + if (lTicks < MIN_SLIDER_TICKS) lTicks = MIN_SLIDER_TICKS; + + // restore scale + lVal *= lMax - lMin; + lVal += (lTicks - 1) / 2; + lVal /= lTicks; + + // re-base + lVal += lMin; + + return lVal; +} + + +//****************************************************************** +//****************************************************************** +void gmenu_set_slider_ticks(TMenuItem * pItem,DWORD dwTicks) { + app_assert(pItem); + app_assert(dwTicks >= MIN_SLIDER_TICKS && dwTicks <= MAX_SLIDER_TICKS); + + pItem->dwFlags &= ~mf_SLIDER_TICK_MASK; + pItem->dwFlags |= mf_SLIDER_TICK_MASK & (dwTicks << SLIDER_TICK_SHIFT); +} diff --git a/HELLFRUI.LIB b/HELLFRUI.LIB new file mode 100644 index 0000000..984ab8a Binary files /dev/null and b/HELLFRUI.LIB differ diff --git a/HELP.CPP b/HELP.CPP new file mode 100644 index 0000000..29cc8d4 --- /dev/null +++ b/HELP.CPP @@ -0,0 +1,1106 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Help file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/HELP.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "help.h" +#include "engine.h" +#include "control.h" +#include "gendung.h" +#include "items.h" +#include "stores.h" +#include "minitext.h" +#include "cursor.h" +#include "control.h" +#include "scrollrt.h" + +#include "monster.h" +#include "objects.h" + +BOOL helpflag; // F1 help + +HelpStrStruct helpstr[MAXHELPSTRS]; +HelpLineStruct helpline[MAXHELPLINES]; + +int numhelpstrs; +int numhelplines; + +int helpx, helpy; + +int help_cy, help_end; + +/*-----------------------------------------------------------------------* +** Microsoft demo text +/*-----------------------------------------------------------------------* + +static const char helpdata[] = { +"Welcome mortals! Hellfire is real-time action in a dark, gothic role-playing game. " +"Prepare to be taken into the very depths of hell on your quest to destroy the Lord " +"of all Evil - Diablo.|" +"|" +"This Help section is designed to make your playing experience as easy as possible. " +"Let's get started...|" +"|" +"$Keyboard Shortcuts:|" +"Hellfire can be played exclusively by using the mouse controls. There are times, however, " +"when you may want to use shortcuts to some commands by using the keyboard. These " +"shortcuts are listed below:|" +"|" +"F1: Open the Help Screen|" +"Esc: Displays the main menu|" +"Tab: Displays the Auto-map|" +"Space: Removes all screens and map from the play area|" +"S: Opens Spell selection pop-up menu|" +"I: Opens the Inventory screen|" +"C: Opens the Character screen|" +"Z: Zooms the game screen in and out|" +"F: Reduces the brightness of the screen|" +"G: Increases the brightness of the screen|" +"Shift + Left Click: Fire any Bow without moving|" +"1,2,3: While the Spell selection pop-up menu is active, these keys will " +"set that number as a hot-key selection (pressing the number will " +"automatically ready that spell).|" +"|" +"$Movement:|" +"Movement is controlled by the mouse. The gauntlet on the screen is your cursor. " +"Use this to indicate the destination of your character and then left-click to move " +"to that area.|" +"|" +"$Selecting Items:|" +"What you can interact with within the game is easily identifiable. Simply move the " +"cursor over any object or creature. If the object can be picked up, attacked, activated " +"or used in any way, it will be immediately outlined and highlighted with a description of " +"the object appearing in the text area on the control panel.|" +"|" +"Example: If you select a door and then left-click the character will walk to the door and " +"open it. A second click closes the door. If you left-click on a selected weapon, the " +"character will walk over to it and put it in his inventory. If you left-click on a selected " +"creature....|" +"|" +"$Combat:|" +"Combat is initiated by left-clicking on a creature that has been selected. Left-clicking " +"on a creature that you are next to will cause your character to attack it immediately. " +"Left-clicking on a distant creature will cause the character to walk to the creature and " +"then attack. This will work if your character has a melee weapon (sword, mace, club, etc.), " +"just a shield or is unarmed.|" +"|" +"If your character is equipped with a bow, left-clicking will fire an arrow at a selected " +"creature. Holding down the shift key and then left-clicking allows the character to fire " +"the bow without accidentally moving.|" +"|" +"$Picking up Objects:|" +"If you left-click an item - such as a weapon, armor, scroll or book - your character will " +"move to that item and add it to his inventory automatically. If you do not have enough " +"room in your inventory for the item, it will fall from your grasp and you will receive a " +"message that more room is needed. Open your inventory screen and try re-arranging or " +"removing items to carry what you really want or need.|" +"|" +"$Inventory:|" +"You can toggle the Inventory screen on and off by clicking the INV> button on the control " +"panel. Items may be moved around in your inventory by selecting them and then left-clicking " +"to pick them up. When you pick up an item while in the inventory screen, your cursor " +"changes into the item. You can then place this item into empty spaces in your inventory, " +"swap them with other items in your inventory or equip them.|" +"|" +"If you have an item that you no longer wish to carry, simply grab the item from your " +"inventory and then left-click in the play area to drop it.|" +"|" +"$Equipping Items:|" +"Equipping items is done by picking up an item from your inventory and placing it in the " +"appropriate boxes on the figure in the Inventory screen. Weapons and shields go into the " +"large spaces to the right or left of the figure. Two-handed weapons such as bows and " +"axes preclude the use of a shield and will take up both of these large spaces.|" +"|" +"Cloaks, robes, capes and all other armor must go in the central torso slot of the figure.|" +"|" +"Helmets and caps go in the head box and rings go into the small boxes at the hands of " +"the figure.|" +"|" +"To change items that your character has equipped, pick up a new item and place it on top " +"of the item you wish to remove. Your character will automatically swap the items and the " +"cursor will now change into the item that was in that box.|" +"|" +"$Usable Items:|" +"Potions, elixirs, oils and books are classified as usable items. These items can be used " +"by right-clicking on them in the inventory screen. Any one item can also be 'readied' in " +"the same way as spells. To ready an item, left-click the 'select current item' button to " +"the left of the red health ball on the control panel. " +"A pop-up menu will activate that you can scroll through to choose an item to be readied. " +"Left-click when the desired item is selected and you will see that item displayed on the " +"button. To use a readied item, simply right-click on the 'select current item' button or " +"press the Enter key on your keyboard.|" +"|" +"$Item Information:|" +"All items in Hellfire share certain common attributes. These are damage, durability, charges " +"and minimum requirements.|" +"|" +"Damage: This is represented by a range that shows the minimum and maximum damage that item " +"can inflict. An sword that has a (2-6) after its name does a minimum of two damage and a " +"maximum of six when it hits. Damage can be modified by the quality of the weapon, the " +"characters strength and magic.|" +"|" +"Durability: This is how long an item can last before it is rendered useless. This is " +"represented by a ratio of current durability to maximum durability. A shield that has a " +"durability of 15/20 would have 15 points of damage it could take from use before it was " +"rendered useless. Maximum durability can be affected by the quality of the item, magic or " +"repairs upon the item. Minimum durability can be raised by repairing an item.|" +"When the durability of an item you are wearing or wielding drops to 5 points or below, " +"an icon of the image appears in the lower left corner above the control panel. These icons " +"warn the player that the item is about to break and needs to be repaired soon.|" +"|" +"Charges: Some items have charges associated with. These represent how many times that item " +"can be used to cast the spell or affect indicated in its description. Charges are " +"represented by a ratio of charges left to maximum charges. A staff that has charges of " +"2/5 could be used to cast 2 more spells before it was rendered powerless (it could still " +"be used to attack with physically). Maximum charges can be affected by the magic or " +"recharges cast upon the item. Minimum charges can be raised by recharging the item.|" +"|" +"Minimum Requirements: These are the minimum requirements that a character must meet to " +"wield the item. The more powerful an item is, the higher the minimum requirements will be. " +"If a character does not meet these requirements, he will be unable to equip the item and " +"its name and information will be displayed in red. The item artwork will also have a red " +"tint to it in the Inventory screen.|" +"|" +"There are also three classes of items in Hellfire. These are mundane, magic and Unique:|" +"|" +"Mundane items have no special attributes and their information is displayed in white text.|" +"|" +"Magic Items are represented by blue text descriptions. Use the Identify spell to determine " +"their exact properties and attributes.|" +"|" +"Unique items are fully identified when you obtain them. Information on these items is " +"displayed in gold.|" +"|" +"$Skills:|" +"Important Note - Skills do not work in the town in this pre-release demo. Left-clicking " +"on the 'select current spell' button will open a pop-up menu that will allow you to ready " +"a skill or spell for use. To use a readied skill or spell, simply right-click in the main " +"play area.|" +"|" +"Skills are the innate abilities of your character. These skills are different depending on " +"what class you choose and they require no mana to use.|" +"|" +"The Warrior starts the game with the Repair skill. The Repair Skill icon appears as the " +"'select current spell' button found next to the blue Mana sphere on the control panel. " +"When the skill is useable, the button will be gold in color. The game starts with the " +"button grayed out as you cannot repair or cast spells in the town.|" +"|" +"The Repair skill allows the Warrior to fix an item that has been worn by use or is damaged " +"in combat. To repair an item, have the Repair Skill selected (your character starts the " +"game this way) and right-click the mouse as if you were casting a spell. Your cursor will " +"change into a hammer shaped cursor that you will use to select the item to be repaired. " +"Repairing an item will decrease the maximum durability of that item, but can be done while " +"in the labyrinth.|" +"|" +"The Blacksmith can repair items, but it will cost you gold. When the Blacksmith repairs " +"an item, it does not decrease the maximum durability of the item.|" +"|" +"$Spells:|" +"Important Note - Spells do not work in the town in this pre-release demo.|" +"|" +"Spells are magical effects that can be cast from a scroll, a staff or memorized from a " +"book. Spells may or may not require mana to use and are available to all classes.|" +"|" +"Spells cast from an item (a scroll or staff) cost no mana to use, but are limited by " +"the number of charges available on the item. Scrolls always have one charge while staves " +"may have multiple charges. To use spells from a staff, you must equip the staff to cast " +"the spell. Spells that are cast from staves are represented by an orange icon button in " +"the 'select current spell' button area. Scrolls are represented by a red button.|" +"|" +"Memorized spells cost mana to cast, but they can be used as long as the character has " +"mana to power them. The Warrior starts the game with no memorized spells. If the " +"character finds a book in the labyrinth, he can memorize the spell written in that " +"book by opening the Inventory screen and right-clicking on the book. This will make " +"the spell always available to the character for casting. Memorized spells are denoted " +"by a blue button.|" +"|" +"While some spells affect the caster, some spells require a target. These targeted spells " +"are cast in the direction that you indicate with your cursor on the play area. If you " +"highlight a creature, you will cast that spell at that creature. Not all items within " +"the labyrinth can be targeted.|" +"|" +"Example: A fireball spell will travel at the creature or to the location you right-click " +"on. A Healing spell will simply add health to your character while diminishing his " +"available mana and requires no targeting.|" +"|" +"You can also set a spell or scroll as a Hot Key position for instant selection. Start " +"by opening the pop-up menu as described in the skill section above. Assign Hot Keys by " +"hitting the 1, 2 or 3 keys on your keyboard after scrolling through the available spells " +"and skills and stopping on the one you wish to assign.|" +"|" +"$Health and Mana:|" +"The two spheres in the control panel display your health and mana. Your health is a " +"measure of how much life force your character has. The red sphere of fluid on the left " +"side of the control panel represents the health of your character. When the fluid is " +"gone - your character is dead.|" +"|" +"The blue fluid on the right side of the control panel represents your character's " +"available mana. Mana is the magical force used by your character to cast spells. When " +"the liquid in the sphere is low or depleted, you may be unable to cast some (or all) of " +"your spells.|" +"|" +"$Control Panel:|" +"The control panel is how you receive detailed information in Hellfire and interact with " +"much of your surroundings. Here is a quick run-down of the control panel areas and their " +"use:|" +"|" +"INV: This button is used to access your Inventory screen|" +"CHAR: This button is used to access your Character Statistics screen|" +"Current Item: This is the item that has been readied for immediate use|" +"Current Spell: This is the spell that has been readied for immediate casting|" +"Health Sphere: This is the amount of health your character currently has|" +"Mana Sphere: This is the amount of mana your character currently has|" +"Automap: This button activates the mapping overlay|" +"Main Menu: This activates the main menu screen|" +"Multiplayer Message: Unavailable in the pre-release demo|" +"Message Filter: Unavailable in the pre-release demo|" +"Description Area: This is where any important information about creatures or items " +"you can interact with is displayed.|" +"|" +"Character Info:|" +"Toggle the Character Statistics Screen on and off by clicking the button on the control " +"panel. Items may be moved around in your inventory by selecting them and then left-clicking " +"to pick them up. When you pick up an item while in the inventory screen, your cursor " +"changes into the item. You can then place this item into empty spaces in your inventory, " +"swap them with other items in your inventory or equip them.|" +"|" +"If you have an item that you no longer wish to carry, simply grab the item from your " +"inventory and then left-click in the play area to drop it.|" +"|" +"$Equipping Items:|" +"To equip an item, open the inventory screen and pick up the desired item, either from " +"play or from your inventory, placing it in the appropriate box on the figure in the " +"inventory screen. Weapons and shields go into the large spaces to the right or left of " +"the figure. Two-handed weapons such as bows and axes preclude the use of a shield and " +"will take up both of these large spaces.|" +"|" +"Cloaks, robes, capes and all other armor must go in the central torso slot of the figure. |" +"|" +"Helmets and caps go in the box over the head of the character.|" +"|" +"Rings go into the small boxes at the hands of the figure.|" +"|" +"Amulets go into the small box at the next to the neck of the figure.|" +"|" +"To change items that your character has equipped, pick up a new item and place it on top " +"of the item you wish to remove. Your character will automatically swap the items and the " +"cursor will now change into the item that was in that box.|" +"|" +"$Usable Items:|" +"Potions, elixirs and books are classified as usable items. These items can be used by " +"right-clicking on them in the inventory screen. Books are too large to be placed in the " +"belt, but any potions or scrolls that are put there can also be used by pressing the " +"corresponding number on the keyboard.|" +"|" +"$Gold:|" +"You can select a specific amount of gold to drop by right clicking on a pile of gold in " +"your inventory. A dialog will appear that allows you to select a specific amount of gold " +"to take. When you have entered that number, your cursor will change into that amount of gold.|" +"|" +"$Item Information:|" +"Many items in Hellfire share certain common attributes. These are damage, durability, " +"charges and minimum requirements..|" +"|" +"Damage: This is represented by a range that indicates the minimum and maximum damage " +"that item can inflict. A short sword has a (2-6) after its name, meaning it inflicts a " +"minimum of two damage and a maximum of six when it hits. Damage can be modified by the " +"quality of the weapon, the character's strength and magical effects.|" +"|" +"Durability: This is the amount of damage that an item can take before it is rendered " +"useless. Durability is represented by a ratio of current durability to maximum " +"durability. A shield that has a durability of 15/20 would still have 15 points of " +"damage it could take from use before it was rendered useless. Maximum durability can " +"be affected by the quality of the item, enchantments or repairs made upon the item. " +"The minimum durability can be raised by repairing an item.|" +"|" +"Charges: Some items have charges associated with them. Charges indicate how many times " +"that item can be used to cast the spell or affect indicated in its description. Charges " +"are represented by a ratio of charges left to maximum charges. A staff that has charges " +"listed as 2/5 could be used to cast 2 more spells before it was rendered powerless. It " +"could still be used to attack with as a physical weapon, however. Maximum charges can " +"be affected by the magic or recharges cast upon the item. Minimum charges can be raised " +"by recharging the item.|" +"|" +"Minimum Requirements: These are the minimum requirements that a character must meet to " +"wield the item. The more powerful an item is, the higher the minimum requirements will " +"be. If a character does not meet these requirements, he will be unable to equip the " +"item and its name and information will be displayed in red. The item artwork will also " +"have a red tint in the Inventory screen.|" +"|" +"$Items Classes:|" +"There are three classes of items in Hellfire - Mundane, Magic and Unique:|" +"|" +"Mundane items have no special attributes. Their information is displayed in white text.|" +"|" +"Magic Items are represented by blue names and text descriptions. Use the Identify spell " +"or speak to Cain in town to determine their exact properties and attributes.|" +"|" +"Unique items are represented by gold names and text descriptions. Use the Identify spell " +"or speak to Cain in town to determine their exact properties and attributes.|" +"|" +"$Skills & Spells:|" +"You can access your list of skills and spells by left-clicking on the SPELLS button in " +"the interface bar. This 'Spellbook' contains all of the skills and spells that your " +"character knows. Spells available through staffs are also listed here. Left-clicking " +"on the Icon of the spell you wish to ready will place it in the 'select current spell' " +"icon/area and set it as the current readied spell. A readied spell may be cast by simply " +"right-clicking in the play area.|" +"|" +"Left-clicking on the 'select current spell' button will also open a 'Speedbook' menu " +"that also allows you to ready a skill or spell for use. To use a readied skill or " +"spell, simply right-click in the main play area.|" +"|" +"Skills are the innate abilities of your character. These skills are different depending " +"on what class you choose and require no mana to use.|" +"|" +"Warrior:|" +"The Warrior has the skill of Repair Items. This allows him to fix an item that has been " +"worn by use or is damaged in combat. To accomplish this, select the Repair Skill through " +"the Spellbook or Speedbook and right-click the mouse as if you were casting a spell. " +"Your cursor will change into a Hammer Icon that you will use to select the item to be " +"repaired. Although Repairing an item in this way will decrease the maximum durability " +"of that item, it can be done without leaving the labyrinth.|" +"|" +"The Blacksmith can also repair items for a price. When the Blacksmith performs this " +"service, it does decrease the maximum durability of the item.|" +"|" +"Rogue:|" +"The Rogue has the skill of Disarm Traps. This allows her to not only remove traps, but " +"also acts as a 'sixth sense' that warns her of where these trapped items are located. " +"To accomplish this, select the Disarm Trap skill through the Spellbook or Speedbook and " +"right-click the mouse as if you were casting a spell. Your cursor will change into a " +"Targeting Cursor that you will use to select the item to be disarmed. The success of " +"this attempt is based on the level of the Rogue and the expertise of whomever set the trap.|" +"|" +"Sorcerer:|" +"The Sorcerer has the skill of Recharge Staffs. This allows him to focus his mana into " +"an staff that has been drained of its magical energies. To accomplish this, select " +"the Recharge Staffs skill through the Spellbook or Speedbook and right-click the mouse " +"as if you were casting a spell. Your cursor will change into a Staff Icon that you will " +"use to select the item to be recharged. Although Recharging a staff in this way will " +"decrease its maximum charges, it can be done without leaving the labyrinth.|" +"|" +"The Witch can also recharge staffs for a price. When the Witch performs this service, it " +"does decrease the maximum charges of the item.|" +"|" +"Spells are magical effects that can be cast from a scroll, a staff or memorized from a " +"book. Spells may or may not require mana to use and are available to all classes.|" +"|" +"Spells cast from a scroll cost no mana to use, but are limited to only one charge. " +"Casting a spell from a scroll is accomplished by either right clicking on the scroll " +"or, if it is located in our belt, pressing the corresponding number on the keyboard. " +"Scrolls can also be readied in the Speedbook and are represented by a red icon/button " +"in the 'select current spell' area.|" +"|" +"Spells cast from staffs cost no mana to use, but are limited by the number of charges " +"available. To cast spells from a staff, it must first be equipped. The 'select current " +"spell' icon/button will change to indicate that the spell on the staff is currently ready " +"to cast. Scrolls can also be readied in the Spellbook or Speedbook and are represented " +"by an orange icon/button in the 'select current spell' area.|" +"|" +"Spells that are memorized cost mana to cast, but they can be used as long as the " +"character has mana to power them. The Warrior and Rogue start the game with no memorized " +"spells while the sorcerer begins with Firebolt. If the character finds a book in the " +"labyrinth, he can memorize the spell written in that book by opening the Inventory " +"screen and right-clicking on the book. This will make that spell always available to " +"the character for casting. Memorized spells can be readied through either the Spellbook " +"or Speedbook and are represented by a blue icon/button in the 'select current spell' area.|" +"|" +"$Important note on books:|" +"Reading more than one book increases your knowledge of that spell and gives you the " +"spell at a higher level. The higher the level of a spell the more effective it is.|" +"|" +"While some spells affect the caster, other spells require a target. These targeted spells " +"are cast in the direction that you indicate with your cursor on the play area. If you " +"highlight a creature, you will cast that spell at that creature. Not all items within " +"the labyrinth can be targeted.|" +"|" +"Example: A fireball spell will travel at the creature or to the location you right-click " +"on. A Healing spell will simply add health to your character while diminishing his " +"available mana and requires no targeting.|" +"|" +"You can also set a spell or scroll as a Hot Key position for instant selection. Start " +"by opening the pop-up menu as described in the skill section above. Assign Hot Keys by " +"hitting the F5, F6, F7 or F8 keys on your keyboard after scrolling through the available " +"spells and highlighting the one you wish to assign. |" +"|" +"$Health and Mana:|" +"The two orbs in the Information Bar display your life and mana. The red sphere of fluid " +"on the left side of the control panel represents the overall health of your character. " +"When the fluid is gone - your character is dead.|" +"|" +"The blue fluid on the right side of the control panel represents your character's " +"available mana. Mana is the magical force used by your character to cast spells. " +"When the liquid in the sphere is low or depleted, you may be unable to cast some " +"(or all) of your spells.|" +"|" +"$Information Bar:|" +"The Information Bar is where you receive detailed information in Hellfire and interact " +"with much of your surroundings. Here is a quick run-down of the control panel areas " +"and their use:|" +"|" +"CHAR: This button is used to access your Character Statistics screen|" +"INV: This button is used to access your Inventory screen|" +"Quest: This button displays your Quest Log (inactive in Shareware version)|" +"Automap: This button activates the mapping overlay|" +"Menu: This button activates the game menu screen|" +"Spells: This button is used to access your Spellbook|" +"Current Spell: This is the spell that has been readied for immediate casting|" +"Life Orb: This is the amount of health your character currently has|" +"Mana Orb: This is the amount of mana your character currently has|" +"Multiplayer Message: This activates the Message Area|" +"Description Area: This is where any important information about creatures or items you " +"can interact with is displayed. This is also where you will enter the text you wish to " +"send when sending multiplayer messages.|" +"|" +"$Character Info:|" +"Toggle the Character Statistics Screen on and off by clicking the button on the control " +"panel. Items may be moved around in your inventory by selecting them and then left-clicking " +"to pick them up. When you pick up an item while in the inventory screen, your cursor " +"changes into the item. You can then place this item into empty spaces in your inventory, " +"swap them with other items in your inventory or equip them.|" +"|" +"If you have an item that you no longer wish to carry, simply grab the item from your " +"inventory and then left-click in the play area to drop it.|" +"|" +"$Equipping Items:|" +"To equip an item, open the inventory screen and pick up the desired item, either from " +"play or from your inventory, placing it in the appropriate box on the figure in the " +"inventory screen. Weapons and shields go into the large spaces to the right or left of " +"the figure. Two-handed weapons such as bows and axes preclude the use of a shield and " +"will take up both of these large spaces.|" +"|" +"Cloaks, robes, capes and all other armor must go in the central torso slot of the figure. |" +"|" +"Helmets and caps go in the box over the head of the character.|" +"|" +"Rings go into the small boxes at the hands of the figure.|" +"|" +"Amulets go into the small box at the next to the neck of the figure.|" +"|" +"To change items that your character has equipped, pick up a new item and place it on top " +"of the item you wish to remove. Your character will automatically swap the items and the " +"cursor will now change into the item that was in that box.|" +"|" +"$Usable Items:|" +"Potions, elixirs and books are classified as usable items. These items can be used by " +"right-clicking on them in the inventory screen. Books are too large to be placed in the " +"belt, but any potions or scrolls that are put there can also be used by pressing the " +"corresponding number on the keyboard.|" +"|" +"$Gold:|" +"You can select a specific amount of gold to drop by right clicking on a pile of gold in " +"your inventory. A dialog will appear that allows you to select a specific amount of gold " +"to take. When you have entered that number, your cursor will change into that amount of gold.|" +"|" +"$Item Information:|" +"Many items in Hellfire share certain common attributes. These are damage, durability, " +"charges and minimum requirements..|" +"|" +"Damage: This is represented by a range that indicates the minimum and maximum damage " +"that item can inflict. A short sword has a (2-6) after its name, meaning it inflicts a " +"minimum of two damage and a maximum of six when it hits. Damage can be modified by the " +"quality of the weapon, the character's strength and magical effects.|" +"|" +"Durability: This is the amount of damage that an item can take before it is rendered " +"useless. Durability is represented by a ratio of current durability to maximum " +"durability. A shield that has a durability of 15/20 would still have 15 points of " +"damage it could take from use before it was rendered useless. Maximum durability can " +"be affected by the quality of the item, enchantments or repairs made upon the item. " +"The minimum durability can be raised by repairing an item.|" +"|" +"Charges: Some items have charges associated with them. Charges indicate how many times " +"that item can be used to cast the spell or affect indicated in its description. Charges " +"are represented by a ratio of charges left to maximum charges. A staff that has charges " +"listed as 2/5 could be used to cast 2 more spells before it was rendered powerless. It " +"could still be used to attack with as a physical weapon, however. Maximum charges can " +"be affected by the magic or recharges cast upon the item. Minimum charges can be raised " +"by recharging the item.|" +"|" +"Minimum Requirements: These are the minimum requirements that a character must meet to " +"wield the item. The more powerful an item is, the higher the minimum requirements will " +"be. If a character does not meet these requirements, he will be unable to equip the " +"item and its name and information will be displayed in red. The item artwork will also " +"have a red tint in the Inventory screen.|" +"|" +"$Items Classes:|" +"There are three classes of items in Hellfire - Mundane, Magic and Unique:|" +"|" +"Mundane items have no special attributes. Their information is displayed in white text.|" +"|" +"Magic Items are represented by blue names and text descriptions. Use the Identify spell " +"or speak to Cain in town to determine their exact properties and attributes.|" +"|" +"Unique items are represented by gold names and text descriptions. Use the Identify spell " +"or speak to Cain in town to determine their exact properties and attributes.|" +"|" +"$Skills & Spells:|" +"You can access your list of skills and spells by left-clicking on the SPELLS button in " +"the interface bar. This 'Spellbook' contains all of the skills and spells that your " +"character knows. Spells available through staffs are also listed here. Left-clicking " +"on the Icon of the spell you wish to ready will place it in the 'select current spell' " +"icon/area and set it as the current readied spell. A readied spell may be cast by simply " +"right-clicking in the play area.|" +"|" +"Left-clicking on the 'select current spell' button will also open a 'Speedbook' menu " +"that also allows you to ready a skill or spell for use. To use a readied skill or " +"spell, simply right-click in the main play area.|" +"|" +"$Skills:|" +"Important Note - Skills are non-functional in the town for this Battle.net Beta. |" +"|" +"Skills are the innate abilities of your character. These skills are different depending " +"on what class you choose and require no mana to use.|" +"|" +"Warrior:|" +"The Warrior has the skill of Repair Items. This allows him to fix an item that has been " +"worn by use or is damaged in combat. To accomplish this, select the Repair Skill through " +"the Spellbook or Speedbook and right-click the mouse as if you were casting a spell. " +"Your cursor will change into a Hammer Icon that you will use to select the item to be " +"repaired. Although Repairing an item in this way will decrease the maximum durability " +"of that item, it can be done without leaving the labyrinth.|" +"|" +"The Blacksmith can also repair items for a price. When the Blacksmith performs this " +"service, it does decrease the maximum durability of the item.|" +"|" +"Rogue:|" +"The Rogue has the skill of Disarm Traps. This allows her to not only remove traps, but " +"also acts as a 'sixth sense' that warns her of where these trapped items are located. " +"To accomplish this, select the Disarm Trap skill through the Spellbook or Speedbook and " +"right-click the mouse as if you were casting a spell. Your cursor will change into a " +"Targeting Cursor that you will use to select the item to be disarmed. The success of " +"this attempt is based on the level of the Rogue and the expertise of whomever set the trap.|" +"|" +"Sorcerer:|" +"The Sorcerer has the skill of Recharge Staffs. This allows him to focus his mana into " +"an staff that has been drained of its magical energies. To accomplish this, select " +"the Recharge Staffs skill through the Spellbook or Speedbook and right-click the mouse " +"as if you were casting a spell. Your cursor will change into a Staff Icon that you will " +"use to select the item to be recharged. Although Recharging a staff in this way will " +"decrease its maximum charges, it can be done without leaving the labyrinth.|" +"|" +"The Witch can also recharge staffs for a price. When the Witch performs this service, it " +"does decrease the maximum charges of the item.|" +"|" +"$Spells:|" +"Important note - Spells are non-functional in the town for this Battle.net Beta.|" +"|" +"Spells are magical effects that can be cast from a scroll, a staff or memorized from a " +"book. Spells may or may not require mana to use and are available to all classes.|" +"|" +"Spells cast from a scroll cost no mana to use, but are limited to only one charge. " +"Casting a spell from a scroll is accomplished by either right clicking on the scroll " +"or, if it is located in our belt, pressing the corresponding number on the keyboard. " +"Scrolls can also be readied in the Speedbook and are represented by a red icon/button " +"in the 'select current spell' area.|" +"|" +"Spells cast from staffs cost no mana to use, but are limited by the number of charges " +"available. To cast spells from a staff, it must first be equipped. The 'select current " +"spell' icon/button will change to indicate that the spell on the staff is currently ready " +"to cast. Scrolls can also be readied in the Spellbook or Speedbook and are represented " +"by an orange icon/button in the 'select current spell' area.|" +"|" +"Spells that are memorized cost mana to cast, but they can be used as long as the " +"character has mana to power them. The Warrior and Rogue start the game with no memorized " +"spells while the sorcerer begins with Firebolt. If the character finds a book in the " +"labyrinth, he can memorize the spell written in that book by opening the Inventory " +"screen and right-clicking on the book. This will make that spell always available to " +"the character for casting. Memorized spells can be readied through either the Spellbook " +"or Speedbook and are represented by a blue icon/button in the 'select current spell' area.|" +"|" +"$Important note on books:|" +"$Reading more than one book increases your knowledge of that spell and gives you the " +"spell at a higher level. The higher the level of a spell the more effective it is.|" +"|" +"While some spells affect the caster, other spells require a target. These targeted spells " +"are cast in the direction that you indicate with your cursor on the play area. If you " +"highlight a creature, you will cast that spell at that creature. Not all items within " +"the labyrinth can be targeted.|" +"|" +"Example: A fireball spell will travel at the creature or to the location you right-click " +"on. A Healing spell will simply add health to your character while diminishing his " +"available mana and requires no targeting.|" +"|" +"You can also set a spell or scroll as a Hot Key position for instant selection. Start " +"by opening the pop-up menu as described in the skill section above. Assign Hot Keys by " +"hitting the F5, F6, F7 or F8 keys on your keyboard after scrolling through the available " +"spells and highlighting the one you wish to assign. |" +"|" +"$Health and Mana:|" +"The two orbs in the Information Bar display your life and mana. The red sphere of fluid " +"on the left side of the control panel represents the overall health of your character. " +"When the fluid is gone - your character is dead.|" +"|" +"The blue fluid on the right side of the control panel represents your character's " +"available mana. Mana is the magical force used by your character to cast spells. " +"When the liquid in the sphere is low or depleted, you may be unable to cast some " +"(or all) of your spells.|" +"|" +"$Information Bar:|" +"The Information Bar is where you receive detailed information in Hellfire and interact " +"with much of your surroundings. Here is a quick run-down of the control panel areas " +"and their use:|" +"|" +"CHAR: This button is used to access your Character Statistics screen|" +"INV: This button is used to access your Inventory screen|" +"Quest: This button displays your Quest Log (inactive in this Beta)|" +"Automap: This button activates the mapping overlay|" +"Menu: This button activates the game menu screen|" +"Spells: This button is used to access your Spellbook|" +"Current Spell: This is the spell that has been readied for immediate casting|" +"Life Orb: This is the amount of health your character currently has|" +"Mana Orb: This is the amount of mana your character currently has|" +"Multiplayer Message: This activates the Message Area|" +"Description Area: This is where any important information about creatures or items you " +"can interact with is displayed. This is also where you will enter the text you wish to " +"send when sending multiplayer messages.|" +"|" +"$Character Info:|" +"Toggle the Character Statistics Screen on and off by clicking the = 577) { + while (tempstr[--t] != ' ') p--; + } + if (*p == '|') p++; + } + } + y = 7; + while (y < 22) { + t = 0; + w = 0; + while (*p == 0) p++; + if (*p == '$') { + p++; + lc = ICOLOR_RED; + } else lc = ICOLOR_WHITE; + if (*p == '&') help_end = help_cy; + else { + while ((*p != '|') && (w < 577)) { + while (*p == 0) p++; + tempstr[t] = *p; + BYTE c = char2print(tempstr[t]); + c = fonttrans[c]; + w += fontkern[c]+1; + t++; + p++; + } + if (w >= 577) { + while (tempstr[--t] != ' ') p--; + } + if (t != 0) { + tempstr[t] = 0; + PrintHelpStr(0, y, tempstr, lc); + } + if (*p == '|') p++; + } + y++; + } + PrintSString(0, 23, TRUE, "Press ESC to end or the arrow keys to scroll.", ICOLOR_GOLD, 0); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void StartHelp() +{ + helpflag = TRUE; + help_cy = 0; + help_end = 5000; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void HelpScrollUp() +{ + if (help_cy > 0) help_cy--; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void HelpScrollDown() +{ + if (help_cy < help_end) help_cy++; +} + diff --git a/HELP.H b/HELP.H new file mode 100644 index 0000000..23060fe --- /dev/null +++ b/HELP.H @@ -0,0 +1,54 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/HELP.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXHELPSTRS 8 +#define MAXHELPLINES 4 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + int hsx; + int hsy; + char hstr[128]; + byte hclr; +} HelpStrStruct; + +typedef struct { + int hlx1; + int hly1; + int hlx2; + int hly2; + byte hlclr; +} HelpLineStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern BOOL helpflag; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + + +void InitHelpSys(); + +void DrawHelp(); + +void StartHelp(); +void HelpScrollUp(); +void HelpScrollDown(); diff --git a/ICON1.ICO b/ICON1.ICO new file mode 100644 index 0000000..b66a61e Binary files /dev/null and b/ICON1.ICO differ diff --git a/IMPLODE.H b/IMPLODE.H new file mode 100644 index 0000000..c65ccc1 --- /dev/null +++ b/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int __cdecl implode( + unsigned int (__cdecl *read_buf)(char *buf, unsigned int *size, void *param), + void (__cdecl *write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int __cdecl explode( + unsigned int (__cdecl *read_buf)(char *buf, unsigned int *size, void *param), + void (__cdecl *write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long __cdecl crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/IMPLODE.LIB b/IMPLODE.LIB new file mode 100644 index 0000000..4cc55e1 Binary files /dev/null and b/IMPLODE.LIB differ diff --git a/INIT.CPP b/INIT.CPP new file mode 100644 index 0000000..f760121 --- /dev/null +++ b/INIT.CPP @@ -0,0 +1,804 @@ +//****************************************************************** +// init.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include +#include "storm/h/storm.h" +#include "palette.h" +#include "engine.h" +#include "gendung.h" +#include "lighting.h" +#include "multi.h" +#include "sound.h" +#include "effects.h" +#include "diabloui.h" +#include "resource.h" + + +//****************************************************************** +// debugging +//****************************************************************** +// minor version number -- as in 1.xx +// jmm.patch3 +#define MINOR_VERSION "04" +// jmm.endpatch3 + +// change to "01" when done with patch +#define HF_MINOR_VERSION "01" + + +#define DIRECT_FILE_ACCESS 1 // 0 in final +#ifdef NDEBUG +#undef DIRECT_FILE_ACCESS +#define DIRECT_FILE_ACCESS 0 +#endif + + +//****************************************************************** +// extern +//****************************************************************** +void init_directx(HWND hWnd); +void free_directx(); +void ddraw_switch_modes(); +void BlackPalette(); +void ReleasePlayerFile(); +void FileErrorDlg(const char * pszName); + + +//****************************************************************** +// public +//****************************************************************** +BOOL bActive; // is application active? +const char gszAppName[] = "HELLFIRE"; +const char gszDiabloName[] = "DIABLO"; +HSARCHIVE ghsMainArchive; +HSARCHIVE ghsHFBardArchive = NULL; +HSARCHIVE ghsHFBarbarianArchive = NULL; + + +// Version string --- NOTE: DO NOT CHANGE THIS VERSION +// NUMBER IN THE PROGRAM, CHANGE IT IN THE RESOURCE FILE! +char gszVersionNumber[MAX_PATH] = "internal version unknown"; +char gszPrintVersion[MAX_PATH] = "Hellfire v1." HF_MINOR_VERSION ; // " (from Diablo v1." MINOR_VERSION ")"; +SNETVERSIONDATA gVersion; +static char sgszProgramName[MAX_PATH]; +static char sgszMainArchiveName[MAX_PATH]; +static char sgszPatchArchiveName[MAX_PATH]; +static char sgszHFArchiveName[MAX_PATH]; +static char sgszHFMonkArchiveName[MAX_PATH]; +static char sgszHFBardArchiveName[MAX_PATH]; +static char sgszHFBarbarianArchiveName[MAX_PATH]; +static char sgszHFMusicArchiveName[MAX_PATH]; +static char sgszHFVoiceArchiveName[MAX_PATH]; +static char sgszHFOpt1ArchiveName[MAX_PATH]; +static char sgszHFOpt2ArchiveName[MAX_PATH]; + + +//****************************************************************** +// private +//****************************************************************** +static WNDPROC sgWndProc; +static LRESULT CALLBACK WndProc(HWND ,UINT ,WPARAM ,LPARAM ); +static HSARCHIVE sghsPatchArchive; +static HSARCHIVE sghsHFArchive; +static HSARCHIVE sghsHFMonkArchive; +static HSARCHIVE sghsHFMusicArchive; +static HSARCHIVE sghsHFVoiceArchive; +static HSARCHIVE sghsHFOpt1Archive; +static HSARCHIVE sghsHFOpt2Archive; + +static BOOL killedmom = 0; +#define MOMLINKNAME "Microsoft Office Shortcut Bar.lnk" + + +//****************************************************************** +//****************************************************************** +static void SearchDirectory(LPCSTR directory) { + char searchspec[MAX_PATH]; + strcpy(searchspec,directory); + if ((!searchspec[0]) ||(searchspec[strlen(searchspec)-1] != '\\')) + strcat(searchspec,"\\*"); + else + strcat(searchspec,"*"); + WIN32_FIND_DATA finddata; + HANDLE findhandle = FindFirstFile(searchspec,&finddata); + if (findhandle != INVALID_HANDLE_VALUE) { + do + if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (strcmp(finddata.cFileName,".") && strcmp(finddata.cFileName,"..")) { + char buffer[MAX_PATH] = ""; + if ((!directory[0]) ||(directory[strlen(directory)-1] != '\\')) + sprintf(buffer,"%s\\%s\\",directory,finddata.cFileName); + else + sprintf(buffer,"%s%s\\",directory,finddata.cFileName); + SearchDirectory(buffer); + } + } + else { + if (!_stricmp(finddata.cFileName,MOMLINKNAME)) + ShellExecute(GetDesktopWindow(),"open",finddata.cFileName,"",directory,SW_SHOWNORMAL); + } + while (FindNextFile(findhandle,&finddata)); + FindClose(findhandle); + } +} + + +//****************************************************************** +//****************************************************************** +static HWND find_mom_window() { + HWND hWnd = GetForegroundWindow(); + while (hWnd) { + char classname[256]; + GetClassName(hWnd,classname,255); + if (! _stricmp(classname,"MOM Parent")) break; + hWnd = GetNextWindow(hWnd,GW_HWNDNEXT); + } + + return hWnd; +} + +//****************************************************************** +//****************************************************************** +static void KillMom() { + HWND hWnd; + if (NULL != (hWnd = find_mom_window())) { + PostMessage(hWnd,WM_CLOSE,0,0); + killedmom = 1; + } +} + + +//****************************************************************** +//****************************************************************** +static void WaitMomDead() { + HWND hWnd; + DWORD dwCurrTime = GetTickCount(); + while (NULL != (hWnd = find_mom_window())) { + Sleep(250); + if (GetTickCount() - dwCurrTime > 4000) + break; + } +} + + +//****************************************************************** +//****************************************************************** +static void ResurrectMom() { + if (!killedmom) + return; + killedmom = 0; + char buffer[256] = ""; + LPITEMIDLIST idlist = NULL; + if (SHGetSpecialFolderLocation(GetDesktopWindow(),CSIDL_STARTMENU,&idlist) == NOERROR) { + SHGetPathFromIDList(idlist,buffer); + SearchDirectory(buffer); + } +} + + +//****************************************************************** +//****************************************************************** +static void disable_screen_saver(BYTE bDisable) { +// direct draw doesn't like the screen saver to be enabled, it +// will quit with a fatal error if the screen saver kicks in. +// Disable the screen saver while the program is running + HKEY hKey; + BYTE bNewState; + DWORD dwSuccess; + TCHAR szBuf[16]; + static BYTE sbState = FALSE; + static const TCHAR scszKey[] = TEXT("ScreenSaveActive"); + + // open master key + dwSuccess = RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("Control Panel\\Desktop"),0,KEY_READ | KEY_WRITE,&hKey); + if (dwSuccess != ERROR_SUCCESS) return; + + if (bDisable) { + // get current screen saver state + DWORD dwType; + DWORD dwSize = sizeof(szBuf); + dwSuccess = RegQueryValueEx(hKey,scszKey,NULL,&dwType,(LPBYTE) szBuf,&dwSize); + if (dwSuccess == ERROR_SUCCESS) sbState = szBuf[0] != TEXT('0'); + bNewState = 0; + } + else { + // restore old screen saver state + bNewState = sbState; + } + + // set the new state + szBuf[0] = bNewState ? TEXT('1') : TEXT('0'); + szBuf[1] = 0; + RegSetValueEx(hKey,scszKey,NULL,REG_SZ,(LPBYTE) szBuf,2 * sizeof(szBuf[0])); + + RegCloseKey(hKey); +} + + +//****************************************************************** +//****************************************************************** +/* +static void key_press(int key) +{ + // Simulate a key press + keybd_event( key, + 0x45, + KEYEVENTF_EXTENDEDKEY | 0, + 0 ); + + // Simulate a key release + keybd_event( VK_CAPITAL, + 0x45, + KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, + 0); +} +*/ + +//****************************************************************** +//****************************************************************** +/* +static void init_caps_lock(BOOL init) +{ + BYTE keyState[256]; + static BOOL capslocked; + + GetKeyboardState((LPBYTE)&keyState); + if(init) + { + capslocked = keyState[VK_CAPITAL] & 1; + // Set caps lock off initially + // NOTE: FriendlyMode is opposite polarity to caps_lock, i.e., it is originally ON + if(capslocked) + key_press(VK_CAPITAL); + } + else { // restore caps lock to originial state + if( (capslocked && !(keyState[VK_CAPITAL] & 1)) || + (!capslocked && (keyState[VK_CAPITAL] & 1)) ) + key_press(VK_CAPITAL); + } +} +*/ + + +//****************************************************************** +//****************************************************************** +void cleanup(BOOL bNormalExit) { + + ReleasePlayerFile(); + disable_screen_saver(FALSE); + // init_caps_lock(FALSE); + ResurrectMom(); + + if (ghsMainArchive) { + SFileCloseArchive(ghsMainArchive); + ghsMainArchive = NULL; + } + if (sghsPatchArchive) { + SFileCloseArchive(sghsPatchArchive); + sghsPatchArchive = NULL; + } + if (sghsHFArchive) { + SFileCloseArchive(sghsHFArchive); + sghsHFArchive = NULL; + } + if (sghsHFMonkArchive) { + SFileCloseArchive(sghsHFMonkArchive); + sghsHFMonkArchive = NULL; + } + if (ghsHFBardArchive) { + SFileCloseArchive(ghsHFBardArchive); + ghsHFBardArchive = NULL; + } + if (ghsHFBarbarianArchive) { + SFileCloseArchive(ghsHFBarbarianArchive); + ghsHFBarbarianArchive = NULL; + } + if (sghsHFMusicArchive) { + SFileCloseArchive(sghsHFMusicArchive); + sghsHFMusicArchive = NULL; + } + if (sghsHFVoiceArchive) { + SFileCloseArchive(sghsHFVoiceArchive); + sghsHFVoiceArchive = NULL; + } + if (sghsHFOpt1Archive) { + SFileCloseArchive(sghsHFOpt1Archive); + sghsHFOpt1Archive = NULL; + } + if (sghsHFOpt2Archive) { + SFileCloseArchive(sghsHFOpt2Archive); + sghsHFOpt2Archive = NULL; + } + + UiDestroy(); + sound_exit(); + snd_exit(); + NetClose(); + free_directx(); + mem_cleanup(bNormalExit); + StormDestroy(); + if (bNormalExit) ShowCursor(TRUE); +} + + +//****************************************************************** +//****************************************************************** +static void remove_trailing_bslash(char * pszPath) { + char * pszTemp = strrchr(pszPath,'\\'); + if (pszTemp && !pszTemp[1]) + *pszTemp = 0; +} + + +//****************************************************************** +//****************************************************************** +static BOOL FindCDArchive( + char szName[MAX_PATH], // saved full path + const char * pszArchName, // default archive name + DWORD dwPriority, // priority + HSARCHIVE * phsArchive // archive name +) { + // get a list of drives, and figure out which ones are CDROM + char szDriveList[MAX_PATH]; + DWORD dwLen = GetLogicalDriveStrings(MAX_PATH,szDriveList); + if (! dwLen) return FALSE; + if (dwLen > MAX_PATH) return FALSE; + + // skip over leading bslash in archive name + while (*pszArchName == '\\') pszArchName++; + + const char * pszDriveList = szDriveList; + while (*pszDriveList) { + // save current drive + const char * pszCurrDrive = pszDriveList; + + // skip over drive string and trailing NULL + while (*pszDriveList++) NULL; + + // is this a CDROM drive? + if (DRIVE_CDROM != GetDriveType(pszCurrDrive)) + continue; + + strcpy(szName,pszCurrDrive); + strcat(szName,pszArchName); + if (SFileOpenArchive(szName,dwPriority,TRUE,phsArchive)) + return TRUE; + } + + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +static HSARCHIVE open_1_archive( + char szName[MAX_PATH], // saved full path + const char * pszArchName, // default archive name + const char * pszArchPathRegKey, // registry key for directory + DWORD dwPriority, // priority + BOOL bCDOnly // TRUE => CD ROM only +) { + HSARCHIVE hArchive; + + // get current directory + char szCurrDir[MAX_PATH]; + if (! GetCurrentDirectory(MAX_PATH,szCurrDir)) + app_fatal("Can't get program path"); + remove_trailing_bslash(szCurrDir); + if (! SFileSetBasePath(szCurrDir)) + app_fatal("SFileSetBasePath"); + + // get program directory + char szProgDir[MAX_PATH]; + if (! GetModuleFileName(ghInst,szProgDir,MAX_PATH)) + app_fatal("Can't get program name"); + char * pszExeName = strrchr(szProgDir,'\\'); + if (pszExeName) *pszExeName = 0; + remove_trailing_bslash(szProgDir); + + // try the current directory + strcpy(szName,szCurrDir); + strcat(szName,pszArchName); + if (SFileOpenArchive( + szName, + dwPriority, + #if DIRECT_FILE_ACCESS + FALSE, + #else + bCDOnly, + #endif + &hArchive + )) return hArchive; + + // try the program directory + if (strcmp(szProgDir,szCurrDir)) { + strcpy(szName,szProgDir); + strcat(szName,pszArchName); + if (SFileOpenArchive( + szName, + dwPriority, + #if DIRECT_FILE_ACCESS + FALSE, + #else + bCDOnly, + #endif + &hArchive + )) return hArchive; + } + + // get CD directory + char szDataDir[MAX_PATH]; + szDataDir[0] = 0; + if (pszArchPathRegKey && SRegLoadString(TEXT("Archives"),pszArchPathRegKey,0,szDataDir,MAX_PATH)) { + // try the data directory + remove_trailing_bslash(szDataDir); + strcpy(szName,szDataDir); + strcat(szName,pszArchName); + if (SFileOpenArchive( + szName, + dwPriority, + #if DIRECT_FILE_ACCESS + FALSE, + #else + bCDOnly, + #endif + &hArchive + )) return hArchive; + } + + // if this file is to be found on a CDROM, search *all* CDROMs + // don't pass szName, because in case of failure by FindCDArchive, + // it already contains the name of the desired archive, which + // STORM wants + if (bCDOnly && FindCDArchive(szDataDir,pszArchName,dwPriority,&hArchive)) { + strcpy(szName,szDataDir); + return hArchive; + } + + // we couldn't open the file, but leave the szName variable + // filled in with the program directory + archive name + return NULL; +} + + +//****************************************************************** +//****************************************************************** +static void get_program_version_info() { + // get name of .EXE file + if (! GetModuleFileName(ghInst,sgszProgramName,MAX_PATH)) + return; + + // get sizeof version structure to allocate + DWORD dwUnused; + DWORD dwVerLen = GetFileVersionInfoSize(sgszProgramName,&dwUnused); + if (! dwVerLen) return; + + // get version info + LPVOID lpData = DiabloAllocPtrSig(dwVerLen,'VERS'); + if (! GetFileVersionInfo(sgszProgramName,0,dwVerLen,lpData)) + goto cleanup; + + UINT uBytes; + VS_FIXEDFILEINFO * pInfo; + if (! VerQueryValue(lpData,TEXT("\\"),(LPVOID *) &pInfo,&uBytes)) + goto cleanup; + app_assert(uBytes >= sizeof(VS_FIXEDFILEINFO)); + + sprintf( + gszVersionNumber, + "version %d.%d.%d.%d", + pInfo->dwProductVersionMS >> 16, + pInfo->dwProductVersionMS & 0x0ffff, + pInfo->dwProductVersionLS >> 16, + pInfo->dwProductVersionLS & 0x0ffff + ); + +cleanup: + DiabloFreePtr(lpData); +} + + +//****************************************************************** +//****************************************************************** +static void open_archives() { + // setup version info + ZeroMemory(&gVersion,sizeof(gVersion)); + gVersion.size = sizeof(gVersion); + gVersion.versionstring = gszVersionNumber; + gVersion.executablefile = sgszProgramName; + gVersion.originalarchivefile = sgszMainArchiveName; + gVersion.patcharchivefile = sgszPatchArchiveName; + + // fill in program name and version string + get_program_version_info(); + + while (1) { + // open main archive + ghsMainArchive = open_1_archive( + sgszMainArchiveName, // saved full path + #if IS_VERSION(SHAREWARE) + TEXT("\\spawn.mpq"), // default archive name + TEXT("DiabloSpawn"), // key for spawned directory + #else + TEXT("\\diabdat.mpq"), // default archive name + TEXT("DiabloCD"), // key for CDROM directory + #endif + 1000, // priority + #if IS_VERSION(SHAREWARE) + FALSE // TRUE == CD ROM only + #else + TRUE // TRUE == CD ROM only + #endif + ); + if (ghsMainArchive) break; + + #if DIRECT_FILE_ACCESS + // we're in debugging mode, so we can just exit + break; + #endif + + #if IS_VERSION(SHAREWARE) + // couldn't find spawn.mpq file + break; + #else + // tell the user to insert the CD + DWORD dwResult; + UiCopyProtError(&dwResult); + if (dwResult == COPYPROT_CANCEL) + FileErrorDlg("diabdat.mpq"); + #endif + } + + // make sure we have access to our data + HSFILE hsFile; + if (! patSFileOpenFile("ui_art\\title.pcx",&hsFile,TRUE)) { + #if IS_VERSION(SHAREWARE) + FileErrorDlg("Main program archive: spawn.mpq"); + #else + FileErrorDlg("Main program archive: diabdat.mpq"); + #endif + } + patSFileCloseFile(hsFile); + + // open patch file + sghsPatchArchive = open_1_archive( + sgszPatchArchiveName, // saved full path + #if IS_VERSION(SHAREWARE) + TEXT("\\patch_sh.mpq"), // default archive name + TEXT("DiabloSpawn"), // key for spawned directory + #else + TEXT("\\patch_rt.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + #endif + 2000, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire file + sghsHFArchive = open_1_archive( + sgszHFArchiveName, // saved full path + TEXT("\\hellfire.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8000, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire Character file + sghsHFMonkArchive = open_1_archive( + sgszHFMonkArchiveName, // saved full path + TEXT("\\hfmonk.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8100, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire Character file + ghsHFBardArchive = open_1_archive( + sgszHFBardArchiveName, // saved full path + TEXT("\\hfbard.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8110, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire Character file + ghsHFBarbarianArchive = open_1_archive( + sgszHFBarbarianArchiveName, // saved full path + TEXT("\\hfbarb.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8120, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire Music file + sghsHFMusicArchive = open_1_archive( + sgszHFMusicArchiveName, // saved full path + TEXT("\\hfmusic.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8200, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire Voice file + sghsHFVoiceArchive = open_1_archive( + sgszHFVoiceArchiveName, // saved full path + TEXT("\\hfvoice.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8500, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire Option file #1 + sghsHFOpt1Archive = open_1_archive( + sgszHFOpt1ArchiveName, // saved full path + TEXT("\\hfopt1.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8600, // priority + FALSE // TRUE == CD ROM only + ); + // open Hellfire Option file #2 + sghsHFOpt2Archive = open_1_archive( + sgszHFOpt2ArchiveName, // saved full path + TEXT("\\hfopt2.mpq"), // default archive name + TEXT("DiabloInstall"), // key for installed directory + 8610, // priority + FALSE // TRUE == CD ROM only + ); +} + + +//****************************************************************** +//****************************************************************** +void init_window(int nCmdShow) { + KillMom(); + + void check_disk_space(); + check_disk_space(); + + // set up and register window class + WNDCLASSEX wc; + ZeroMemory(&wc,sizeof(wc)); + wc.cbSize = sizeof(wc); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WndProc; + wc.hInstance = ghInst; + wc.hIcon = LoadIcon(ghInst,MAKEINTRESOURCE(IDI_ICON1)); + wc.hCursor = LoadCursor(NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = gszAppName; + // So the Diablo auto run won't. + wc.lpszClassName = gszDiabloName; //gszAppName; + wc.hIconSm = (HICON) LoadImage(ghInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,16,16,0); + if (! RegisterClassEx(&wc)) + app_fatal("Unable to register window class"); + +#if ALLOW_WINDOWED_MODE + int nWdt = 640; + int nHgt = 480; +#else + int nWdt = max(640,GetSystemMetrics(SM_CXSCREEN)); + int nHgt = max(480,GetSystemMetrics(SM_CYSCREEN)); +#endif + + // create main window + HWND hWnd = CreateWindow( + gszDiabloName, + gszAppName, + WS_POPUP, + 0, + 0, + nWdt, + nHgt, + NULL, + NULL, + ghInst, + NULL + ); + if (! hWnd) app_fatal("Unable to create main window"); + ShowWindow(hWnd,SW_SHOWNORMAL); + UpdateWindow(hWnd); + + WaitMomDead(); + init_directx(hWnd); + BlackPalette(); + snd_init(hWnd); + open_archives(); + disable_screen_saver(TRUE); + // init_caps_lock(TRUE); +} + + +//****************************************************************** +//****************************************************************** +static void app_activate(HWND hWnd,WPARAM wParam) { + bActive = wParam; + UiAppActivate(wParam); + + // make our 16x16 icon show up on the taskbar + // -- have to have WM_SYSMENU set for the icon to show up + // -- don't want WM_SYSMENU during fullscreen mode, otherwise + // menu will pop up during gameplay! + DWORD dwStyle = GetWindowLong(hWnd,GWL_STYLE); + if (bActive && fullscreen) + dwStyle &= ~WS_SYSMENU; + else + dwStyle |= WS_SYSMENU; + SetWindowLong(hWnd,GWL_STYLE,dwStyle); + + if (! bActive) return; + force_redraw = FULLDRAW; + ResetPal(); +} + + +//****************************************************************** +//****************************************************************** +LRESULT CALLBACK DiabloDefProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + switch(uMsg) { + #if ALLOW_WINDOWED_MODE + case WM_SYSKEYUP: + if (wParam == VK_RETURN) { + fullscreen = !fullscreen; + ddraw_switch_modes(); + return 0; + } + break; + #endif + + case WM_CLOSE: + return 0; + + case WM_ERASEBKGND: + // ignore erase messages + return 0; + + case WM_PAINT: + force_redraw = FULLDRAW; + break; + + case WM_ACTIVATEAPP: + app_activate(hWnd,wParam); + break; + + case WM_QUERYNEWPALETTE: + SDrawRealizePalette(); + return TRUE; + + case WM_PALETTECHANGED: + // pjw.patch1.start + // if (bActive && (HWND)wParam != hWnd) + if ((HWND)wParam != hWnd) + // pjw.patch1.end + SDrawRealizePalette(); + break; + + case WM_CREATE: + ghMainWnd = hWnd; + break; + + case WM_DESTROY: + cleanup(TRUE); + ghMainWnd = NULL; + PostQuitMessage(0); + break; + } + + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + + +//****************************************************************** +//****************************************************************** +static LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + if (sgWndProc) return sgWndProc(hWnd,uMsg,wParam,lParam); + return DiabloDefProc(hWnd,uMsg,wParam,lParam); +} + + +//****************************************************************** +//****************************************************************** +WNDPROC my_SetWindowProc(WNDPROC wndProc) { +// we can't use SetWindowLong, because DirectDraw won't properly support +// stuff like alt-tabbing if we override the funky stuff it does to the +// window procedure. + WNDPROC tempProc = sgWndProc; + sgWndProc = wndProc; + return tempProc; +} diff --git a/INTERFAC.CPP b/INTERFAC.CPP new file mode 100644 index 0000000..2958ef0 --- /dev/null +++ b/INTERFAC.CPP @@ -0,0 +1,544 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Menu interface processing +** +** (C)1996 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/INTERFAC.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "palette.h" +#include "engine.h" +#include "scrollrt.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "gamemenu.h" +#include "control.h" +#include "cursor.h" +#include "trigs.h" +#include "multi.h" +#include "msg.h" +#include "effects.h" +#include "portal.h" +#include "quests.h" +#include "setmaps.h" + + +//****************************************************************** +// extern +//****************************************************************** +extern BYTE gbSomebodyWonGameKludge; +WNDPROC my_SetWindowProc(WNDPROC wndProc); +void plrmsg_hold(BOOL bStart); +void BlackPalette(); +void DestroyTempSaves(); +LRESULT CALLBACK DisableInputWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); + + +//****************************************************************** +// private +//****************************************************************** +#define MAX_PROGRESS 534 +static BYTE *sgpBackCel; +static DWORD sgdwProgress, sgdwXY; + + +//****************************************************************** +//****************************************************************** +static void ProgressFree() { + DiabloFreePtr(sgpBackCel); +} + + +//****************************************************************** +//****************************************************************** +static void ProgressLoad(UINT uMsg) { + app_assert(! sgpBackCel); + switch (uMsg) { + case WM_DIABNEXTLVL : + switch (gnLevelTypeTbl[currlevel]) { + case 0: + sgpBackCel = LoadFileInMemSig("Gendata\\Cuttt.CEL",NULL,'PROG'); + LoadPalette("Gendata\\Cuttt.pal"); + sgdwXY = 1; + break; + case 1: + if (currlevel < HIVESTART) + { + sgpBackCel = LoadFileInMemSig("Gendata\\Cutl1d.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutl1d.pal"); + sgdwXY = 0; + break; + } + else + { + sgpBackCel = LoadFileInMemSig("Nlevels\\cutl5.CEL",NULL,'PROG'); + LoadPalette ("Nlevels\\cutl5.pal"); + sgdwXY = 1; + break; + } + + case 2: + sgpBackCel = LoadFileInMemSig("Gendata\\Cut2.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut2.pal"); + sgdwXY = 2; + break; + case 3: + if (currlevel < HIVESTART) + { + sgpBackCel = LoadFileInMemSig("Gendata\\Cut3.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut3.pal"); + sgdwXY = 1; + break; + } + else + { + sgpBackCel = LoadFileInMemSig("Nlevels\\cutl6.CEL",NULL,'PROG'); + LoadPalette ("Nlevels\\cutl6.pal"); + sgdwXY = 1; + break; + } + + case 4: + if (currlevel < 15) { + sgpBackCel = LoadFileInMemSig("Gendata\\Cut4.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut4.pal"); + sgdwXY = 1; + } else { + sgpBackCel = LoadFileInMemSig("Gendata\\Cutgate.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutgate.pal"); + sgdwXY = 1; + } + break; + default: + sgpBackCel = LoadFileInMemSig("Gendata\\Cutl1d.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutl1d.pal"); + sgdwXY = 0; + break; + } + break; + + case WM_DIABPREVLVL : + if (gnLevelTypeTbl[currlevel-1] == 0) { + sgpBackCel = LoadFileInMemSig("Gendata\\Cuttt.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cuttt.pal"); + sgdwXY = 1; + } else { + switch (gnLevelTypeTbl[currlevel]) { + case 0: + sgpBackCel = LoadFileInMemSig("Gendata\\Cuttt.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cuttt.pal"); + sgdwXY = 1; + break; + case 1: + if (currlevel < HIVESTART) + { + sgpBackCel = LoadFileInMemSig("Gendata\\Cutl1d.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutl1d.pal"); + sgdwXY = 0; + break; + } + else + { + sgpBackCel = LoadFileInMemSig("Nlevels\\cutl5.CEL",NULL,'PROG'); + LoadPalette ("Nlevels\\cutl5.pal"); + sgdwXY = 1; + break; + } + + case 2: + sgpBackCel = LoadFileInMemSig("Gendata\\Cut2.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut2.pal"); + sgdwXY = 2; + break; + case 3: + if (currlevel < HIVESTART) + { + sgpBackCel = LoadFileInMemSig("Gendata\\Cut3.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut3.pal"); + sgdwXY = 1; + break; + } + else + { + sgpBackCel = LoadFileInMemSig("Nlevels\\cutl6.CEL",NULL,'PROG'); + LoadPalette ("Nlevels\\cutl6.pal"); + sgdwXY = 1; + break; + } + case 4: + sgpBackCel = LoadFileInMemSig("Gendata\\Cut4.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut4.pal"); + sgdwXY = 1; + break; + default: + sgpBackCel = LoadFileInMemSig("Gendata\\Cutl1d.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutl1d.pal"); + sgdwXY = 0; + break; + } + } + break; + + case WM_DIABSETLVL : + if (setlvlnum == SL_BONECHAMB) { + sgpBackCel = LoadFileInMemSig("Gendata\\Cut2.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut2.pal"); + sgdwXY = 2; + } else if (setlvlnum == SL_VILEBETRAYER) { + sgpBackCel = LoadFileInMemSig("Gendata\\Cutportr.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutportr.pal"); + sgdwXY = 1; + } else { + sgpBackCel = LoadFileInMemSig("Gendata\\Cutl1d.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutl1d.pal"); + sgdwXY = 0; + } + break; + + case WM_DIABRTNLVL : + if (setlvlnum == SL_BONECHAMB) { // bone chamber + sgpBackCel = LoadFileInMemSig("Gendata\\Cut2.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut2.pal"); + sgdwXY = 2; + } else if (setlvlnum == SL_VILEBETRAYER) { // vile betrayer + sgpBackCel = LoadFileInMemSig("Gendata\\Cutportr.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutportr.pal"); + sgdwXY = 1; + } else { + sgpBackCel = LoadFileInMemSig("Gendata\\Cutl1d.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutl1d.pal"); + sgdwXY = 0; + } + break; + + case WM_DIABWARPLVL : + sgpBackCel = LoadFileInMemSig("Gendata\\Cutportl.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutportl.pal"); + sgdwXY = 1; + break; + + case WM_DIABLOADGAME : + sgpBackCel = LoadFileInMemSig("Gendata\\Cutstart.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutstart.pal"); + sgdwXY = 1; + break; + + case WM_DIABNEWGAME: + sgpBackCel = LoadFileInMemSig("Gendata\\Cutstart.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutstart.pal"); + sgdwXY = 1; + break; + + case WM_DIABTOWNWARP: + case WM_DIABTWARPUP: + switch (gnLevelTypeTbl[plr[myplr].plrlevel]) { + case 0: + sgpBackCel = LoadFileInMemSig("Gendata\\Cuttt.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cuttt.pal"); + sgdwXY = 1; + break; + case 1: // added to allow the crypt JKE + if (plr[myplr].plrlevel < HIVESTART) + { + sgpBackCel = LoadFileInMemSig("Gendata\\Cutl1d.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cutl1d.pal"); + sgdwXY = 0; + break; + } + else + { + sgpBackCel = LoadFileInMemSig("Nlevels\\Cutl5.CEL",NULL,'PROG'); + LoadPalette ("Nlevels\\Cutl5.pal"); + sgdwXY = 1; + break; + } + case 2: + sgpBackCel = LoadFileInMemSig("Gendata\\Cut2.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut2.pal"); + sgdwXY = 2; + break; + case 3: + if (plr[myplr].plrlevel < HIVESTART) + { + sgpBackCel = LoadFileInMemSig("Gendata\\Cut3.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut3.pal"); + sgdwXY = 1; + break; + } + else + { + sgpBackCel = LoadFileInMemSig("Nlevels\\Cutl6.CEL",NULL,'PROG'); + LoadPalette ("Nlevels\\Cutl6.pal"); + sgdwXY = 1; + break; + } + + case 4: + sgpBackCel = LoadFileInMemSig("Gendata\\Cut4.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cut4.pal"); + sgdwXY = 1; + break; + } + break; + + case WM_DIABRETOWN: + sgpBackCel = LoadFileInMemSig("Gendata\\Cuttt.CEL",NULL,'PROG'); + LoadPalette ("Gendata\\Cuttt.pal"); + sgdwXY = 1; + break; + + default: + app_fatal("Unknown progress mode"); + break; + } + + // Indicates time for the progress bar + sgdwProgress = 0; +} + + +//****************************************************************** +//****************************************************************** +static void DrawBarXY(int x, int y, int v2) { + app_assert(gpBuffer); + static const BYTE pixel[3] = { 0x8a, 0x2b, 0xfe }; + BYTE * pto = gpBuffer + nBuffWTbl[y] + x; + for (int i = 0; i < 22; i++) { + *pto = pixel[v2]; + pto = pto + 768; + } +} + + +//****************************************************************** +//****************************************************************** +static void ProgressIntDraw() { + static const int xytable[3][2] = { {53, 37}, {53, 421}, {53, 37} }; + + // draw background + lock_buf(1); + app_assert(sgpBackCel); + DrawCel(64, 639, sgpBackCel, 1, 640); + + // draw load/progress bar + for (DWORD i = 0; i < sgdwProgress; i++) + DrawBarXY (64 + xytable[sgdwXY][0] + i, xytable[sgdwXY][1] + 160, sgdwXY); + unlock_buf(1); + + // force a full blit + force_redraw = FULLDRAW; + FullBlit(FALSE); +} + + +//****************************************************************** +//****************************************************************** +void interface_msg_pump() { + MSG msg; + while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if (msg.message != WM_QUIT) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } +} + + +//****************************************************************** +//****************************************************************** +BOOL IntCheck() { + interface_msg_pump(); + + // make bar increase + sgdwProgress += 15; + if (sgdwProgress > MAX_PROGRESS) + sgdwProgress = MAX_PROGRESS; + + // redraw the screen + if (sgpBackCel) ProgressIntDraw(); + + // are we done? + return (sgdwProgress >= MAX_PROGRESS); +} + + +//****************************************************************** +//****************************************************************** +void ShowProgress(UINT uMsg) { + gbSomebodyWonGameKludge = FALSE; + plrmsg_hold(TRUE); + + app_assert(ghMainWnd); + WNDPROC saveProc = my_SetWindowProc(DisableInputWndProc); + interface_msg_pump(); + + // load progress background and fade in + ClrDraw(); + FullBlit(TRUE); + ProgressLoad(uMsg); + BlackPalette(); + ProgressIntDraw(); + PaletteFadeIn(FADE_FAST); + + IntCheck(); + sound_init(); + IntCheck(); + + switch (uMsg) { + case WM_DIABLOADGAME : + IntCheck(); + GM_LoadGame(TRUE); + IntCheck(); + break; + + case WM_DIABNEWGAME : + IntCheck(); + FreeGameMem(); + IntCheck(); + DestroyTempSaves(); + LoadGameLevel(TRUE, LVL_DOWN); + IntCheck(); + break; + + case WM_DIABNEXTLVL : + IntCheck(); + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + + FreeGameMem(); + currlevel++; + leveltype = gnLevelTypeTbl[currlevel]; + app_assert(plr[myplr].plrlevel == currlevel); + IntCheck(); + LoadGameLevel(FALSE, LVL_DOWN); + IntCheck(); + break; + + case WM_DIABPREVLVL : + IntCheck(); + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + + IntCheck(); + FreeGameMem(); + currlevel--; + leveltype = gnLevelTypeTbl[currlevel]; + app_assert(plr[myplr].plrlevel == currlevel); + IntCheck(); + LoadGameLevel(FALSE, LVL_UP); + IntCheck(); + break; + + case WM_DIABSETLVL : + SetReturnLvlPos(); + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + setlevel = TRUE; + leveltype = setlvltype; + FreeGameMem(); + IntCheck(); + LoadGameLevel(FALSE, LVL_SET); + IntCheck(); + break; + + case WM_DIABRTNLVL : + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + setlevel = FALSE; + FreeGameMem(); + IntCheck(); + GetReturnLvlPos(); + LoadGameLevel(FALSE, LVL_RTN); + IntCheck(); + break; + + case WM_DIABWARPLVL : + IntCheck(); + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + FreeGameMem(); + GetPortalLevel(); + IntCheck(); + + LoadGameLevel(FALSE, LVL_WARP); + IntCheck(); + break; + + case WM_DIABTOWNWARP: + IntCheck(); + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + app_assert(plr[myplr].plrlevel == currlevel); + IntCheck(); + LoadGameLevel(FALSE, LVL_TWARPDN); + IntCheck(); + break; + + case WM_DIABTWARPUP: + IntCheck(); + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + app_assert(plr[myplr].plrlevel == currlevel); + IntCheck(); + LoadGameLevel(FALSE, LVL_TWARPUP); + IntCheck(); + break; + + case WM_DIABRETOWN: + IntCheck(); + if (gbMaxPlayers == 1) SaveLevel(); + else DeltaSaveLevel(); + + FreeGameMem(); + currlevel = plr[myplr].plrlevel; + leveltype = gnLevelTypeTbl[currlevel]; + app_assert(plr[myplr].plrlevel == currlevel); + IntCheck(); + LoadGameLevel(FALSE, LVL_DOWN); + IntCheck(); + break; + + } + + // cleanup + app_assert(ghMainWnd); + PaletteFadeOut(FADE_FAST); + ProgressFree(); + + // restore window procedure + saveProc = my_SetWindowProc(saveProc); + app_assert(saveProc == DisableInputWndProc); + + NetSendCmdLocParam1( + TRUE, + CMD_PLAYER_JOINLEVEL, + plr[myplr]._px, + plr[myplr]._py, + plr[myplr].plrlevel + ); + + plrmsg_hold(FALSE); + ResetPal(); + + if (gbSomebodyWonGameKludge && plr[myplr].plrlevel == 16) { + // somebody killed diablo while we were on the stairs + void PrepDoEnding(); + PrepDoEnding(); + } + gbSomebodyWonGameKludge = FALSE; +} \ No newline at end of file diff --git a/INTERFAC.H b/INTERFAC.H new file mode 100644 index 0000000..82864fe --- /dev/null +++ b/INTERFAC.H @@ -0,0 +1,19 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1996 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/INTERFAC.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +BOOL IntCheck(); diff --git a/INV.CPP b/INV.CPP new file mode 100644 index 0000000..15e8fca --- /dev/null +++ b/INV.CPP @@ -0,0 +1,3086 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Invetory file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/INV.CPP 11 2/24/97 7:53p Jmcreynolds $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "gendung.h" //required for player.h +#include "items.h" +#include "itemdat.h" +#include "player.h" +#include "inv.h" +#include "engine.h" +#include "lighting.h" +#include "cursor.h" +#include "scrollrt.h" +#include "control.h" +#include "monster.h" +#include "effects.h" +#include "spelldat.h" +#include "spells.h" +#include "objects.h" +#include "quests.h" +#include "doom.h" +#include "msg.h" +#include "stores.h" +#include "missiles.h" +#include "minitext.h" +#include "textdat.h" +#include "multi.h" + +ItemStruct *PlrHasItem(int pnum, int item, int &i); +void SetupItem(int); + +void CheckItemStats(int pnum); +void DeleteItem(int ii, int i); +void OpenNest(); +void OpenCrypt(); +void InitTownTriggers(); + +// JMM.PATCH1.2.22.97 +void sysmsg_add_string(const char * pszMsg); +// END.JMM.PATCH1.2.22.97 + + +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ +BOOL invflag; +BOOL drawsbarflag; + +/*-----------------------------------------------------------------------** +** private +**-----------------------------------------------------------------------*/ +// Offscreen control panel buffer +static BYTE *pInvCels; + +int AP2x2Tbl[10] = { 8, 28, 6, 26, 4, 24, 2, 22, 0, 20 }; + +// InvRect defines lower-left corners of inventory screen rectangles +static const POINT InvRect[] = { + { 452, 31 },{ 480, 31 }, // Head (0-3) + { 452, 59 },{ 480, 59 }, + + { 365,205 }, // Ring 1 (4) + + { 567,205 }, // Ring 2 (5) + + { 524, 59 }, // Neck (6) + + { 337,104 },{ 366,104 }, // Left Hand (7-12) + { 337,132 },{ 366,132 }, + { 337,160 },{ 366,160 }, + + { 567,104 },{ 596,104 }, // Right Hand (13-18) + { 567,132 },{ 596,132 }, + { 567,160 },{ 596,160 }, + + { 452,104 },{ 480,104 }, // Body (19-24) + { 452,132 },{ 480,132 }, + { 452,160 },{ 480,160 }, + + // Inv (25-64) + { 337,250 },{ 366,250 },{ 394,250 },{ 423,250 },{ 451,250 },{ 480,250 },{ 509,250 },{ 538,250 },{ 567,250 },{ 596,250 }, + { 337,279 },{ 366,279 },{ 394,279 },{ 423,279 },{ 451,279 },{ 480,279 },{ 509,279 },{ 538,279 },{ 567,279 },{ 596,279 }, + { 337,308 },{ 366,308 },{ 394,308 },{ 423,308 },{ 451,308 },{ 480,308 },{ 509,308 },{ 538,308 },{ 567,308 },{ 596,308 }, + { 337,336 },{ 366,336 },{ 394,336 },{ 423,336 },{ 451,336 },{ 480,336 },{ 509,336 },{ 538,336 },{ 567,336 },{ 596,336 }, + + // Speed Bar(65-72) + { 205,385 },{ 234,385 },{ 263,385 },{ 292,385 },{ 321,385 },{ 350,385 },{ 379,385 },{ 408,385 } +}; +#define INVRECTS (sizeof(InvRect) / sizeof(InvRect[0])) + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FreeInvGFX() { + DiabloFreePtr (pInvCels); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitInv() { + app_assert(! pInvCels); + if (plr[myplr]._pClass == CLASS_WARRIOR) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv.CEL",NULL,'INVC'); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_rog.CEL",NULL,'INVC'); + else if (plr[myplr]._pClass == CLASS_SORCEROR) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_Sor.CEL",NULL,'INVC'); + else if (plr[myplr]._pClass == CLASS_MONK) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_Sor.CEL",NULL,'INVC'); // GWP Fix this + else if (plr[myplr]._pClass == CLASS_BARD) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_rog.CEL",NULL,'INVC'); // GWP Fix this + else if (plr[myplr]._pClass == CLASS_BARBARIAN) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv.CEL",NULL,'INVC'); // GWP Fix this + #endif + invflag = FALSE; + drawsbarflag = FALSE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ChangeBackground(int x, int y, int w, int h) +{ + BYTE *p; + + app_assert(gpBuffer); + p = gpBuffer + nBuffWTbl[y] + x; + __asm { + mov edi,dword ptr [p] + xor edx,edx + xor ebx,ebx + mov dx,word ptr [h] + mov bx,word ptr [w] + +_YLp: mov ecx,ebx +_XLp: mov al,byte ptr [edi] + cmp al,176 + jb _Skip2 + cmp al,191 + ja _Try2 + sub al,16 + jmp _Save +_Try2: cmp al,240 + jb _Skip2 + sub al,80 +_Save: mov byte ptr [edi],al +_Skip2: inc edi + loop _XLp + sub edi,768 + sub edi,ebx + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#define INVOCLR 197 +#define INVOMCLR 181 +#define INVOICLR 229 + +void DrawInv() +{ + int i, f, w, ii, xx, yy, oc; + BYTE *pB; + BOOL invtest[MAXINV]; // @@@@ Dave test + + app_assert(gpBuffer); + DrawCel(384, 511, pInvCels, 1, 320); + + if (plr[myplr].HeadItem._itype != -1) { + ChangeBackground(517, 219, 56, 56); + f = plr[myplr].HeadItem._iCurs + ICSTART; + w = CursorWidth[f]; + if (cursinvitem == INVLOC_HEAD) { + oc = INVOCLR; + if (plr[myplr].HeadItem._iMagical) oc = INVOMCLR; + if (!plr[myplr].HeadItem._iStatFlag) oc = INVOICLR; + + if (f <= ICLAST ) + OutlineSlabCel(oc, 517, 219, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, 517, 219, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].HeadItem._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(517, 219, pCursCels, f, w, 0, 8); + else + DrawSlabCel(517, 219, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(517, 219, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(517, 219, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + } + if (plr[myplr].Ring1Item._itype != -1) { + ChangeBackground(432, 365, 28, 28); + f = plr[myplr].Ring1Item._iCurs + ICSTART; + w = CursorWidth[f]; + if (cursinvitem == INVLOC_RING1) { + oc = INVOCLR; + if (plr[myplr].Ring1Item._iMagical) oc = INVOMCLR; + if (!plr[myplr].Ring1Item._iStatFlag) oc = INVOICLR; + + if (f <= ICLAST) + OutlineSlabCel(oc, 432, 365, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, 432, 365, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].Ring1Item._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(432, 365, pCursCels, f, w, 0, 8); + else + DrawSlabCel(432, 365, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(432, 365, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(432, 365, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + } + if (plr[myplr].Ring2Item._itype != -1) { + ChangeBackground(633, 365, 28, 28); + f = plr[myplr].Ring2Item._iCurs + ICSTART; + w = CursorWidth[f]; + if (cursinvitem == INVLOC_RING2) { + oc = INVOCLR; + if (plr[myplr].Ring2Item._iMagical) oc = INVOMCLR; + if (!plr[myplr].Ring2Item._iStatFlag) oc = INVOICLR; + if (f <= ICLAST) + OutlineSlabCel(oc, 633, 365, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, 633, 365, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].Ring2Item._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(633, 365, pCursCels, f, w, 0, 8); + else + DrawSlabCel(633, 365, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(633, 365, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(633, 365, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + } + if (plr[myplr].NeckItem._itype != -1) { + ChangeBackground(589, 220, 28, 28); + f = plr[myplr].NeckItem._iCurs + ICSTART; + w = CursorWidth[f]; + if (cursinvitem == INVLOC_NECK) { + oc = INVOCLR; + if (plr[myplr].NeckItem._iMagical) oc = INVOMCLR; + if (!plr[myplr].NeckItem._iStatFlag) oc = INVOICLR; + if (f <= ICLAST) + OutlineSlabCel(oc, 589, 220, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, 589, 220, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].NeckItem._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(589, 220, pCursCels, f, w, 0, 8); + else + DrawSlabCel(589, 220, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(589, 220, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(589, 220, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + } + if (plr[myplr].Hand1Item._itype != -1) { + ChangeBackground(401, 320, 56, 84); + f = plr[myplr].Hand1Item._iCurs + ICSTART; + w = CursorWidth[f]; + if (w == 28) xx = 415; + else xx = 401; + if (CursorHeight[f] == 84) yy = 320; + else yy = 306; + if (cursinvitem == INVLOC_HAND1) { + oc = INVOCLR; + if (plr[myplr].Hand1Item._iMagical) oc = INVOMCLR; + if (!plr[myplr].Hand1Item._iStatFlag) oc = INVOICLR; + if (f <= ICLAST) + OutlineSlabCel(oc, xx, yy, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, xx, yy, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].Hand1Item._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(xx, yy, pCursCels, f, w, 0, 8); + else + DrawSlabCel(xx, yy, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(xx, yy, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(xx, yy, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + if (plr[myplr].Hand1Item._iLoc == IL_2HAND + && !(plr[myplr]._pClass == CLASS_BARBARIAN + && (plr[myplr].Hand1Item._itype == IT_SWORD || + plr[myplr].Hand1Item._itype == IT_MACE) + ) + ) { + ChangeBackground(631, 320, 56, 84); + nLVal = 0; + nTrans = TRUE; + if (w == 28) pB = gpBuffer + 246405; + else pB = gpBuffer + 246391; + if (f <= ICLAST) + TDrawSlabCelPL (pB, pCursCels, f, w, 0, 8); + else + TDrawSlabCelPL (pB, pCursCels2, f - ICLAST, w, 0, 8); + nTrans = FALSE; + } + } + if (plr[myplr].Hand2Item._itype != -1) { + ChangeBackground(631, 320, 56, 84); + f = plr[myplr].Hand2Item._iCurs + ICSTART; + w = CursorWidth[f]; + if (w == 28) xx = 645; + else xx = 633; + if (CursorHeight[f] == 84) yy = 320; + else yy = 306; + if (cursinvitem == INVLOC_HAND2) { + oc = INVOCLR; + if (plr[myplr].Hand2Item._iMagical) oc = INVOMCLR; + if (!plr[myplr].Hand2Item._iStatFlag) oc = INVOICLR; + if (f <= ICLAST) + OutlineSlabCel(oc, xx, yy, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, xx, yy, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].Hand2Item._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(xx, yy, pCursCels, f, w, 0, 8); + else + DrawSlabCel(xx, yy, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(xx, yy, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(xx, yy, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + } + if (plr[myplr].BodyItem._itype != -1) { + ChangeBackground(517, 320, 56, 84); + f = plr[myplr].BodyItem._iCurs + ICSTART; + w = CursorWidth[f]; + if (cursinvitem == INVLOC_BODY) { + oc = INVOCLR; + if (plr[myplr].BodyItem._iMagical) oc = INVOMCLR; + if (!plr[myplr].BodyItem._iStatFlag) oc = INVOICLR; + if (f <= ICLAST) + OutlineSlabCel(oc, 517, 320, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, 517, 320, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].BodyItem._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(517, 320, pCursCels, f, w, 0, 8); + else + DrawSlabCel(517, 320, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(517, 320, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(517, 320, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + } + + for (i = 0; i < MAXINV; i++) { + invtest[i] = FALSE; + if (plr[myplr].InvGrid[i] != 0) + ChangeBackground(InvRect[i+25].x + 64, InvRect[i+25].y + 159, 28, 28); + } + + for (i = 0; i < MAXINV; i++) { + if (plr[myplr].InvGrid[i] > 0) { + app_assert(!invtest[i]); + invtest[i] = TRUE; + app_assert(plr[myplr].InvGrid[i] <= plr[myplr]._pNumInv); + ii = plr[myplr].InvGrid[i] - 1; + f = plr[myplr].InvList[ii]._iCurs + ICSTART; + w = CursorWidth[f]; + if (cursinvitem == (ii + NUM_INVLOC)) { + oc = INVOCLR; + if (plr[myplr].InvList[ii]._iMagical) oc = INVOMCLR; + if (!plr[myplr].InvList[ii]._iStatFlag) oc = INVOICLR; + if (f <= ICLAST) + OutlineSlabCel(oc, InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].InvList[ii]._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels, f, w, 0, 8); + else + DrawSlabCel(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawSpdBar() +{ + int i, f, w, oc, idata; + long poffset; + + if (talkflag) return; + CopyCtrlPan(205, 21, 232, 28, 269, 517); + for (i = 0; i < MAXSPD; i++) { + if (plr[myplr].SpdList[i]._itype != -1) { + ChangeBackground(InvRect[i+65].x + 64, InvRect[i+65].y + 159, 28, 28); + f = plr[myplr].SpdList[i]._iCurs + ICSTART; + w = CursorWidth[f]; + if (cursinvitem == (i + 47)) { + oc = INVOCLR; + if (plr[myplr].SpdList[i]._iMagical) oc = INVOMCLR; + if (!plr[myplr].SpdList[i]._iStatFlag) oc = INVOICLR; + if (f <= ICLAST) + OutlineSlabCel(oc, InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels, f, w, 0, 8); + else + OutlineSlabCel(oc, InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels2, f - ICLAST, w, 0, 8); + } + if (plr[myplr].SpdList[i]._iStatFlag) { + app_assert(pCursCels); + if (f <= ICLAST) + DrawSlabCel(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels, f, w, 0, 8); + else + DrawSlabCel(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels2, f - ICLAST, w, 0, 8); + } + else { + if (f <= ICLAST) + DrawSlabCelI(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels, f, w, 0, 8, LIGHT_INFRA); + else + DrawSlabCelI(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); + } + idata = plr[myplr].SpdList[i].IDidx; + if (AllItemsList[idata].iUsable && plr[myplr].SpdList[i]._iStatFlag && + (plr[myplr].SpdList[i]._itype != IT_GOLD)) + { + BYTE c = char2print(i + '1'); + c = fonttrans[c]; + poffset = nBuffWTbl[InvRect[i+65].y + 159] + InvRect[i+65].x + 92 - fontkern[c]; + DrawPanelFont(poffset, c, ICOLOR_WHITE); + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL AutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag) +{ + int i, j, xx, yy; + BOOL done; + + done = TRUE; + yy = (ii / 10) * 10; + if (yy < 0) yy = 0; + for (j = 0; (j < sy) && done; j++) { + if (yy >= 40) done = FALSE; + xx = (ii % 10); + if (xx < 0) xx = 0; + for (i = 0; (i < sx) && done; i++) { + if (xx >= 10) done = FALSE; + else done = (plr[pnum].InvGrid[xx+yy] == 0); + xx++; + } + yy+=10; + } + + if ((done) && (saveflag)) { + i = plr[pnum]._pNumInv; + plr[pnum].InvList[i] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + yy = (ii / 10) * 10; + if (yy < 0) yy = 0; + for (j = 0; j < sy; j++) { + xx = (ii % 10); + if (xx < 0) xx = 0; + for (i = 0; i < sx; i++) { + if ((i == 0) && (j == sy-1)) plr[pnum].InvGrid[xx+yy] = plr[pnum]._pNumInv; + else plr[pnum].InvGrid[xx+yy] = -plr[pnum]._pNumInv; + xx++; + } + yy+=10; + } + CalcPlrScrolls(pnum); + } + return(done); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL SpecialAutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag) +{ + int i, j, xx, yy; + BOOL done; + + //Check InvList + done = TRUE; + yy = (ii / 10) * 10; + if (yy < 0) yy = 0; + for (j = 0; (j < sy) && done; j++) { + if (yy >= 40) done = FALSE; + xx = (ii % 10); + if (xx < 0) xx = 0; + for (i = 0; (i < sx) && done; i++) { + if (xx >= 10) done = FALSE; + else done = (plr[pnum].InvGrid[xx+yy] == 0); + xx++; + } + yy+=10; + } + //Inventory is full so check SpdList + if (!done) { + if (sx > 1 || sy > 1) done = FALSE; + else { + for (i = 0; i < MAXSPD; i++) { + if (plr[pnum].SpdList[i]._itype == -1) { + done = TRUE; + break; + } + } + } + } + + if ((done) && (saveflag)) { + i = plr[pnum]._pNumInv; + plr[pnum].InvList[i] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + yy = (ii / 10) * 10; + if (yy < 0) yy = 0; + for (j = 0; j < sy; j++) { + xx = (ii % 10); + if (xx < 0) xx = 0; + for (i = 0; i < sx; i++) { + if ((i == 0) && (j == sy-1)) plr[pnum].InvGrid[xx+yy] = plr[pnum]._pNumInv; + else plr[pnum].InvGrid[xx+yy] = -plr[pnum]._pNumInv; + xx++; + } + yy+=10; + } + CalcPlrScrolls(pnum); + } + return(done); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL GoldAutoPlace(int pnum) +{ + int i, ii, xx, yy; + long gt; + BOOL done; + + // Check if it can be added on to a gold location + done = FALSE; + for (i = 0; (i < plr[pnum]._pNumInv) && (!done); i++) { + if (plr[pnum].InvList[i]._itype == IT_GOLD) { + gt = plr[pnum].HoldItem._ivalue + plr[pnum].InvList[i]._ivalue; + if (gt <= GOLD_VMAX) { + plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; + if (gt >= GOLD_VT2) { + plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; + } else { + if (gt <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; + else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; + } + plr[pnum]._pGold = CalculateGold(pnum); + plr[pnum].HoldItem._ivalue = 0; + done = TRUE; + } + else if (plr[pnum].InvList[i]._ivalue < GOLD_VMAX) { + // There's room, add to existing gold. + int const depositGold = GOLD_VMAX - plr[pnum].InvList[i]._ivalue; + plr[pnum].InvList[i]._ivalue = GOLD_VMAX; + plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; + + plr[pnum].HoldItem._ivalue -= depositGold; + // Just in case. + if (plr[pnum].HoldItem._ivalue < 0) + { + plr[pnum].HoldItem._ivalue = 0; + done = TRUE; + } + GetPlrHandSeed(&plr[pnum].HoldItem); + + SetDropGoldCursor(pnum); + plr[pnum]._pGold = CalculateGold(pnum); + } + } + } + + +#if 0 + // If there's still gold in my hand, try to place it in more empty slots + if (!done) { + for (i = 0; (i < plr[pnum]._pNumInv) && (!done); i++) { + if (plr[pnum].InvList[i]._itype == IT_GOLD) { + if (plr[pnum].InvList[i]._ivalue < GOLD_VMAX) { + gt = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue; + if (gt <= GOLD_VMAX) { + plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; + if (gt >= GOLD_VT2) { + plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; + } else { + if (gt <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; + else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; + } + plr[pnum]._pGold = CalculateGold(pnum); + done = TRUE; + } + } + } + } + } +#endif + + // Lastly check for any empty space to drop put gold into + if (!done) { + for (ii = MAXINV-1; (ii >= 0) && (!done); --ii) { + yy = (ii / 10) * 10; + xx = ii % 10; + if (plr[pnum].InvGrid[xx+yy] == 0) { + i = plr[pnum]._pNumInv; + plr[pnum].InvList[i] = plr[pnum].HoldItem; // struct copy. + plr[pnum]._pNumInv++; + plr[pnum].InvGrid[xx+yy] = plr[pnum]._pNumInv; + if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) { + plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; + } else { + if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; + else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; + } + if (plr[pnum].HoldItem._ivalue > GOLD_VMAX) { + plr[pnum].HoldItem._ivalue -= GOLD_VMAX; + GetPlrHandSeed(&plr[pnum].HoldItem); + // We have to set the inventory value because we did a struct copy above. + plr[pnum].InvList[i]._ivalue = GOLD_VMAX; + } else { + done = TRUE; + plr[pnum].HoldItem._ivalue = 0; + plr[pnum]._pGold = CalculateGold(pnum); + SetCursor(GLOVE_CURS); + } + } + } + } + return(done); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL WeaponAutoPlace(int pnum) +{ + if (plr[pnum]._pClass == CLASS_MONK) // Monks don't autoequip weapons + return FALSE; // (open-hand is often better) + + if (plr[pnum].HoldItem._iLoc == IL_2HAND + && !(plr[pnum]._pClass == CLASS_BARBARIAN + && (plr[pnum].HoldItem._itype == IT_SWORD || + plr[pnum].HoldItem._itype == IT_MACE) + ) + ) + { + if ((plr[pnum].Hand1Item._itype != -1) || (plr[pnum].Hand2Item._itype != -1)) return(FALSE); + NetSendCmdChItem(TRUE, INVLOC_HAND1); + plr[pnum].Hand1Item = plr[pnum].HoldItem; + return(TRUE); + } + else + { + if (plr[pnum]._pClass != CLASS_BARD) + { + if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iClass == IC_WEAP)) return(FALSE); + if ((plr[pnum].Hand2Item._itype != -1) && (plr[pnum].Hand2Item._iClass == IC_WEAP)) return(FALSE); + } + if (plr[pnum].Hand1Item._itype == -1) { + NetSendCmdChItem(TRUE, INVLOC_HAND1); + plr[pnum].Hand1Item = plr[pnum].HoldItem; + } else { + if ((plr[pnum].Hand2Item._itype == -1) && (plr[pnum].Hand1Item._iLoc != IL_2HAND)) { + NetSendCmdChItem(TRUE, INVLOC_HAND2); + plr[pnum].Hand2Item = plr[pnum].HoldItem; + } else return(FALSE); + } + return(TRUE); + } + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int SwapItem(ItemStruct *a, ItemStruct *b) +{ + ItemStruct h; + + h = *a; + *a = *b; + *b = h; + return(h._iCurs + ICSTART); +} + +/*-----------------------------------------------------------------------* +** Place cursor item into inventory window +**-----------------------------------------------------------------------*/ + +void CheckInvPaste(int pnum, int mx, int my) +{ + int r; + int i, j, xx, yy, ii; + int il, cn, it, iv, ig; + long gt; + ItemStruct tempitem; + + SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); + + int cx = mx + (icursW>>1); // center of cursor graphic + int cy = my + (icursH>>1); + int const sx = icursW28; // size of cursor, in 28x28 blocks + int const sy = icursH28; + + BOOL done = FALSE; + for (r = 0; (r < INVRECTS) && (!done); r++) { + if ((cx >= InvRect[r].x) && (cx < InvRect[r].x + 28) && (cy >= InvRect[r].y - 29) && (cy < InvRect[r].y)) { + done = TRUE; + r--; + } + // shift for inv grid + if (r == 24) { + if (!(sx & 1)) cx -= 14; + if (!(sy & 1)) cy -= 14; + } + // shift back y for spd bar + if (r == 64) { + if (!(sy & 1)) cy += 14; + } + } + + if (done) { + // Check if correct item location type + il = IL_INV; + if ((r >= 0) && (r <= 3)) il = IL_HEAD; + if ((r >= 4) && (r <= 5)) il = IL_RING; + if (r == 6) il = IL_NECK; + if ((r >= 7) && (r <= 18)) il = IL_HAND; + if ((r >= 19) && (r <= 24)) il = IL_BODY; + if ((r >= 65) && (r <= 72)) il = IL_SPD; + + done = FALSE; + if (plr[pnum].HoldItem._iLoc == il) done = TRUE; + if ((il == IL_HAND) && (plr[pnum].HoldItem._iLoc == IL_2HAND)) { + + // Hack so placement will work for a two handed weapon. + if (plr[pnum]._pClass == CLASS_BARBARIAN + && (plr[pnum].HoldItem._itype == IT_SWORD || + plr[pnum].HoldItem._itype == IT_MACE) + ) + { + il = IL_HAND; + } + else + { + il = IL_2HAND; + } + done = TRUE; + } + if ((plr[pnum].HoldItem._iLoc == IL_INV) && (il == IL_SPD) && (sx == 1) && (sy == 1)) { + done = TRUE; + if (!AllItemsList[plr[pnum].HoldItem.IDidx].iUsable) done = FALSE; + if (!plr[pnum].HoldItem._iStatFlag) done = FALSE; + if (plr[pnum].HoldItem._itype == IT_GOLD) done = FALSE; + } + + if (il == IL_INV) { + ii = r - 25; + iv = 0; + done = TRUE; + if (plr[pnum].HoldItem._itype == IT_GOLD) { + yy = (ii / 10) * 10; + xx = ii % 10; + if (plr[pnum].InvGrid[xx+yy] != 0) { + ig = plr[pnum].InvGrid[xx+yy]; + if (ig > 0) { + if (plr[pnum].InvList[ig-1]._itype != IT_GOLD) iv = ig; + } else iv = -ig; + } + } else { + yy = ((ii / 10) - ((sy - 1) >> 1)) * 10; + if (yy < 0) yy = 0; + for (j = 0; (j < sy) && done; j++) { + if (yy >= 40) done = FALSE; + xx = (ii % 10) - ((sx - 1) >> 1); + if (xx < 0) xx = 0; + for (i = 0; (i < sx) && done; i++) { + if (xx >= 10) done = FALSE; + else { + if (plr[pnum].InvGrid[xx+yy] != 0) { + ig = plr[pnum].InvGrid[xx+yy]; + if (ig < 0) ig = -ig; + if (iv != 0) { + if (iv != ig) done = FALSE; + } else iv = ig; + } + } + xx++; + } + yy+=10; + } + } + } + + // Do I have the min stats to place this item? + if ((done) && (il != IL_INV) && (il != IL_SPD) && (!plr[pnum].HoldItem._iStatFlag)) { + done = FALSE; + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR13); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE13); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE13); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySFX(PS_MONK13); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySFX(PS_BARD13); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN13); + #endif + } + + if (done) { + it = ItemCAnimTbl[plr[pnum].HoldItem._iCurs]; + if(pnum == myplr) + PlaySFX(ItemInvSnds[it]); + cn = GLOVE_CURS; // Go back to gaunts unless something else there + switch (il) { + case IL_HEAD : + NetSendCmdChItem(FALSE, INVLOC_HEAD); + if (plr[pnum].HeadItem._itype == -1) plr[pnum].HeadItem = plr[pnum].HoldItem; + else cn = SwapItem(&plr[pnum].HeadItem, &plr[pnum].HoldItem); + break; + case IL_RING : + if (r == 4) { + NetSendCmdChItem(FALSE, INVLOC_RING1); + if (plr[pnum].Ring1Item._itype == -1) plr[pnum].Ring1Item = plr[pnum].HoldItem; + else cn = SwapItem(&plr[pnum].Ring1Item, &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, INVLOC_RING2); + if (plr[pnum].Ring2Item._itype == -1) plr[pnum].Ring2Item = plr[pnum].HoldItem; + else cn = SwapItem(&plr[pnum].Ring2Item, &plr[pnum].HoldItem); + } + break; + case IL_NECK: + NetSendCmdChItem(FALSE, INVLOC_NECK); + if (plr[pnum].NeckItem._itype == -1) plr[pnum].NeckItem = plr[pnum].HoldItem; + else cn = SwapItem(&plr[pnum].NeckItem, &plr[pnum].HoldItem); + break; + case IL_HAND : + if (r <= 12) { + if (plr[pnum].Hand1Item._itype == -1) { + if ((plr[pnum].Hand2Item._itype != -1) + && (plr[pnum].Hand2Item._iClass == plr[pnum].HoldItem._iClass) + && !(plr[pnum]._pClass == CLASS_BARD + && plr[pnum].Hand2Item._iClass == IC_WEAP + && plr[pnum].HoldItem._iClass == IC_WEAP) + ) { + NetSendCmdChItem(FALSE, INVLOC_HAND2); + cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, INVLOC_HAND1); + plr[pnum].Hand1Item = plr[pnum].HoldItem; + } + } else { + if ((plr[pnum].Hand2Item._itype != -1) + && (plr[pnum].Hand2Item._iClass == plr[pnum].HoldItem._iClass) + && !(plr[pnum]._pClass == CLASS_BARD + && plr[pnum].Hand2Item._iClass == IC_WEAP + && plr[pnum].HoldItem._iClass == IC_WEAP) + ) { + NetSendCmdChItem(FALSE, INVLOC_HAND2); + cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, INVLOC_HAND1); + cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); + } + } + } else { + if (plr[pnum].Hand2Item._itype == -1) { + if ((plr[pnum].Hand1Item._itype != -1) + && (plr[pnum].Hand1Item._iLoc == IL_2HAND + && !(plr[pnum]._pClass == CLASS_BARBARIAN + && (plr[pnum].Hand1Item._itype == IT_SWORD || + plr[pnum].Hand1Item._itype == IT_MACE ) + ) + ) + ) { + NetSendCmdChItem(FALSE, INVLOC_HAND1); + SwapItem(&plr[pnum].Hand2Item, &plr[pnum].Hand1Item); + cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); + } else { + if ((plr[pnum].Hand1Item._itype != -1) + && (plr[pnum].Hand1Item._iClass == plr[pnum].HoldItem._iClass) + && !(plr[pnum]._pClass == CLASS_BARD + && plr[pnum].Hand1Item._iClass == IC_WEAP + && plr[pnum].HoldItem._iClass == IC_WEAP) + ) { + NetSendCmdChItem(FALSE, INVLOC_HAND1); + cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, INVLOC_HAND2); + plr[pnum].Hand2Item = plr[pnum].HoldItem; + } + } + } else { + if ((plr[pnum].Hand1Item._itype != -1) + && (plr[pnum].Hand1Item._iClass == plr[pnum].HoldItem._iClass + && !(plr[pnum]._pClass == CLASS_BARD + && plr[pnum].Hand1Item._iClass == IC_WEAP + && plr[pnum].HoldItem._iClass == IC_WEAP) + ) + ) { + NetSendCmdChItem(FALSE, INVLOC_HAND1); + cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); + } else { + NetSendCmdChItem(FALSE, INVLOC_HAND2); + cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); + } + } + } + break; + case IL_2HAND : + NetSendCmdDelItem(FALSE, INVLOC_HAND2); + if ((plr[pnum].Hand1Item._itype != -1) + && (plr[pnum].Hand2Item._itype != -1)) + { + tempitem = plr[pnum].HoldItem; + if (plr[pnum].Hand2Item._itype == IT_SHIELD) { + plr[pnum].HoldItem = plr[pnum].Hand2Item; + } else { + plr[pnum].HoldItem = plr[pnum].Hand1Item; + } + if (pnum == myplr) { + SetCursor(plr[pnum].HoldItem._iCurs + ICSTART); + } + else { + SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); + } + + BOOL done2h(FALSE); + + for (i = 0; (i < MAXINV) && (!done2h); ++i) { + done2h = AutoPlace(pnum, i, icursW28, icursH28, TRUE); + } + + plr[pnum].HoldItem = tempitem; + if (pnum == myplr) + SetCursor(plr[pnum].HoldItem._iCurs + ICSTART); + else + SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); + if (done2h) { + if (plr[pnum].Hand2Item._itype == IT_SHIELD) { + plr[pnum].Hand2Item._itype = -1; + } else { + plr[pnum].Hand1Item._itype = -1; + } + } else + return; + } + if ((plr[pnum].Hand1Item._itype == -1) + && (plr[pnum].Hand2Item._itype == -1)) { + NetSendCmdChItem(FALSE, INVLOC_HAND1); + plr[pnum].Hand1Item = plr[pnum].HoldItem; + } else { + NetSendCmdChItem(FALSE, INVLOC_HAND1); + if (plr[pnum].Hand1Item._itype == -1) SwapItem(&plr[pnum].Hand1Item, &plr[pnum].Hand2Item); + cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); + } + if (plr[pnum].Hand1Item._itype == IT_STAFF) { + if ((plr[pnum].Hand1Item._iSpell) && (plr[pnum].Hand1Item._iCharges > 0)) { + plr[pnum]._pRSpell = plr[pnum].Hand1Item._iSpell; + plr[pnum]._pRSplType = SPT_ITEM; + force_redraw = FULLDRAW; + } + } + break; + case IL_BODY : + NetSendCmdChItem(FALSE, INVLOC_BODY); + if (plr[pnum].BodyItem._itype == -1) plr[pnum].BodyItem = plr[pnum].HoldItem; + else cn = SwapItem(&plr[pnum].BodyItem, &plr[pnum].HoldItem); + break; + case IL_INV : + // Gold is stackable + if ((plr[pnum].HoldItem._itype == IT_GOLD) && (iv == 0)) { + ii = r - 25; + yy = (ii / 10) * 10; + xx = ii % 10; + // Empty (== 0) or gold (> 0) + if (plr[pnum].InvGrid[xx+yy] > 0) { + i = plr[pnum].InvGrid[xx+yy] - 1; + gt = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue; + // Gold total <= GOLD_VMAX then all done + if (gt <= GOLD_VMAX) { + plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + if (gt >= GOLD_VT2) { + plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; + } else { + if (gt <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; + else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; + } + } else { + // Fill as much as possible and keep holding extra + gt = GOLD_VMAX - plr[pnum].InvList[i]._ivalue; + plr[pnum]._pGold += gt; + plr[pnum].HoldItem._ivalue -= gt; + plr[pnum].InvList[i]._ivalue = GOLD_VMAX; + plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; + if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) cn = ITEM_5GOLD + ICSTART; + else { + if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) cn = ITEM_1GOLD + ICSTART; + else cn = ITEM_3GOLD + ICSTART; + } + } + } else { + // Place gold in empty spot + ii = plr[pnum]._pNumInv; + plr[pnum].InvList[ii] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + plr[pnum].InvGrid[xx+yy] = plr[pnum]._pNumInv; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + //Choose correct gold cursor + gt = plr[pnum].HoldItem._ivalue; + if (gt <= GOLD_VMAX) { + if (gt >= GOLD_VT2) { + plr[pnum].InvList[ii]._iCurs = ITEM_5GOLD; + } else { + if (gt <= GOLD_VT1) plr[pnum].InvList[ii]._iCurs = ITEM_1GOLD; + else plr[pnum].InvList[ii]._iCurs = ITEM_3GOLD; + } + } else { + plr[pnum].InvList[ii]._iCurs = ITEM_5GOLD; + } + } + } else { + // Item not gold + if (iv == 0) { + // No swaping item + ii = plr[pnum]._pNumInv; + plr[pnum].InvList[ii] = plr[pnum].HoldItem; + plr[pnum]._pNumInv++; + iv = plr[pnum]._pNumInv; + } else { + ii = iv-1; + if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + cn = SwapItem(&plr[pnum].InvList[ii], &plr[pnum].HoldItem); + if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold = CalculateGold(pnum); + for (i = 0; i < MAXINV; i++) { + if (plr[pnum].InvGrid[i] == iv) plr[pnum].InvGrid[i] = 0; + if (plr[pnum].InvGrid[i] == -iv) plr[pnum].InvGrid[i] = 0; + } + } + ii = r - 25; + yy = ((ii / 10) - ((sy - 1) >> 1)) * 10; + if (yy < 0) yy = 0; + for (j = 0; j < sy; j++) { + xx = (ii % 10) - ((sx - 1) >> 1); + if (xx < 0) xx = 0; + for (i = 0; i < sx; i++) { + if ((i == 0) && (j == sy-1)) plr[pnum].InvGrid[xx+yy] = iv; + else plr[pnum].InvGrid[xx+yy] = -iv; + xx++; + } + yy+=10; + } + } + break; + case IL_SPD: + ii = r - 65; + // Gold is stackable + if (plr[pnum].HoldItem._itype == IT_GOLD) { + // Check if something is already there + if (plr[pnum].SpdList[ii]._itype != -1) { + if (plr[pnum].SpdList[ii]._itype == IT_GOLD) { + gt = plr[pnum].SpdList[ii]._ivalue + plr[pnum].HoldItem._ivalue; + // Gold total <= GOLD_VMAX then all done + if (gt <= GOLD_VMAX) { + plr[pnum].SpdList[ii]._ivalue += plr[pnum].HoldItem._ivalue; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + if (gt >= GOLD_VT2) { + plr[pnum].SpdList[ii]._iCurs = ITEM_5GOLD; + } else { + if (gt <= GOLD_VT1) plr[pnum].SpdList[ii]._iCurs = ITEM_1GOLD; + else plr[pnum].SpdList[ii]._iCurs = ITEM_3GOLD; + } + } else { + // Fill as much as possible and keep holding extra + gt = GOLD_VMAX - plr[pnum].SpdList[ii]._ivalue; + plr[pnum]._pGold += gt; + plr[pnum].HoldItem._ivalue -= gt; + plr[pnum].SpdList[ii]._ivalue = GOLD_VMAX; + plr[pnum].SpdList[ii]._iCurs = ITEM_5GOLD; + if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) cn = ITEM_5GOLD + ICSTART; + else { + if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) cn = ITEM_1GOLD + ICSTART; + else cn = ITEM_3GOLD + ICSTART; + } + } + } else { + // Swap with non gold + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem); + } + } else { + // Place gold in empty spot + plr[pnum].SpdList[ii] = plr[pnum].HoldItem; + plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; + } + } else { + // Not gold. Place or swap + if (plr[pnum].SpdList[ii]._itype == -1) plr[pnum].SpdList[ii] = plr[pnum].HoldItem; + else { + cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem); + if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold = CalculateGold(pnum); + } + } + drawsbarflag = TRUE; + break; + } + + CalcPlrInv(pnum,TRUE); + if (pnum == myplr) { + if (cn == GLOVE_CURS) SetCursorPos(MouseX + (cursW>>1),MouseY + (cursH>>1)); + SetCursor(cn); + } + } + } +} + +/*-----------------------------------------------------------------------** +** Change items for another player +**-----------------------------------------------------------------------*/ +// drb.patch1.start.02/10/97 +//void SyncInvPaste(int pnum, BYTE bLoc, int idx, WORD icreateinfo, int iseed) +void SyncInvPaste(int pnum, BYTE bLoc, int idx, WORD icreateinfo, int iseed, BOOL Id) +// drb.patch1.end.02/10/97 +{ + // temp use the first slot to grab an item + RecreateItem(TEMPAVAIL, idx, icreateinfo, iseed, 0); + PlayerStruct * p = &plr[pnum]; + p->HoldItem = item[TEMPAVAIL]; + // drb.patch1.start.02/10/97 + if (Id) p->HoldItem._iIdentified = TRUE; + // drb.patch1.end.02/10/97 + + if (bLoc < NUM_INVLOC) { + p->InvBody[bLoc] = p->HoldItem; + if (bLoc == INVLOC_HAND1) { + if (p->HoldItem._iLoc == IL_2HAND) + p->Hand2Item._itype = -1; + } + else if (bLoc == INVLOC_HAND2) { + if (p->HoldItem._iLoc == IL_2HAND) + p->Hand1Item._itype = -1; + } + } + + CalcPlrInv(pnum,TRUE); +} + +/*-----------------------------------------------------------------------** +** Pick up items from inventory window and set cursor appropriately +**-----------------------------------------------------------------------*/ + +void CheckInvCut(int pnum, int mx, int my) +{ + int r; + BOOL done; + int ii,iv,i; + + if (plr[pnum]._pmode > PM_WALK3) return; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + + done = FALSE; + for (r = 0; (r < INVRECTS) && (!done); r++) { + if ((mx >= InvRect[r].x) && (mx < InvRect[r].x + 29) && (my >= InvRect[r].y - 29) && (my < InvRect[r].y)) { + done = TRUE; + r--; + } + } + if (done) { + plr[pnum].HoldItem._itype = -1; + if ((r >= 0) && (r <= 3) && (plr[pnum].HeadItem._itype != -1)) { + NetSendCmdDelItem(FALSE, INVLOC_HEAD); + plr[pnum].HoldItem = plr[pnum].HeadItem; + plr[pnum].HeadItem._itype = -1; + } + if ((r == 4) && (plr[pnum].Ring1Item._itype != -1)) { + NetSendCmdDelItem(FALSE, INVLOC_RING1); + plr[pnum].HoldItem = plr[pnum].Ring1Item; + plr[pnum].Ring1Item._itype = -1; + } + if ((r == 5) && (plr[pnum].Ring2Item._itype != -1)) { + NetSendCmdDelItem(FALSE, INVLOC_RING2); + plr[pnum].HoldItem = plr[pnum].Ring2Item; + plr[pnum].Ring2Item._itype = -1; + } + if ((r == 6) && (plr[pnum].NeckItem._itype != -1)) { + NetSendCmdDelItem(FALSE, INVLOC_NECK); + plr[pnum].HoldItem = plr[pnum].NeckItem; + plr[pnum].NeckItem._itype = -1; + } + if ((r >= 7) && (r <= 12) && (plr[pnum].Hand1Item._itype != -1)) { + NetSendCmdDelItem(FALSE, INVLOC_HAND1); + plr[pnum].HoldItem = plr[pnum].Hand1Item; + plr[pnum].Hand1Item._itype = -1; + } + if ((r >= 13) && (r <= 18) && (plr[pnum].Hand2Item._itype != -1)) { + NetSendCmdDelItem(FALSE, INVLOC_HAND2); + plr[pnum].HoldItem = plr[pnum].Hand2Item; + plr[pnum].Hand2Item._itype = -1; + } + if ((r >= 19) && (r <= 24) && (plr[pnum].BodyItem._itype != -1)) { + NetSendCmdDelItem(FALSE, INVLOC_BODY); + plr[pnum].HoldItem = plr[pnum].BodyItem; + plr[pnum].BodyItem._itype = -1; + } + + if ((r >= 25) && (r <= 64)) { + ii = r - 25; + if (plr[pnum].InvGrid[ii] != 0) { + if (plr[pnum].InvGrid[ii] > 0) iv = plr[pnum].InvGrid[ii]; + else iv = -plr[pnum].InvGrid[ii]; + for (i = 0; i < MAXINV; i++) { + if ((plr[pnum].InvGrid[i] == iv) || (plr[pnum].InvGrid[i] == -iv)) + plr[pnum].InvGrid[i] = 0; + } + iv--; + plr[pnum].HoldItem = plr[pnum].InvList[iv]; + plr[pnum]._pNumInv--; + if ((plr[pnum]._pNumInv > 0) && (plr[pnum]._pNumInv != iv)) { + plr[pnum].InvList[iv] = plr[pnum].InvList[plr[pnum]._pNumInv]; + for (i = 0; i < MAXINV; i++) { + if (plr[pnum].InvGrid[i] == plr[pnum]._pNumInv+1) plr[pnum].InvGrid[i] = iv+1; + if (plr[pnum].InvGrid[i] == -(plr[pnum]._pNumInv+1)) plr[pnum].InvGrid[i] = -(iv+1); + } + } + } + } + if (r >= 65) { + ii = r - 65; + if (plr[pnum].SpdList[ii]._itype != -1) { + plr[pnum].HoldItem = plr[pnum].SpdList[ii]; + plr[pnum].SpdList[ii]._itype = -1; + drawsbarflag = TRUE; + } + } + + if (plr[pnum].HoldItem._itype != -1) { + if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold = CalculateGold(pnum); + CalcPlrInv(pnum,TRUE); + CheckItemStats(pnum); + if (pnum == myplr) { + PlaySFX(IS_IGRAB); + SetCursor(plr[pnum].HoldItem._iCurs + ICSTART); + SetCursorPos(mx - (cursW>>1),MouseY - (cursH>>1)); + } + } + } +} + +/*-----------------------------------------------------------------------* +** Remove an item from another player +**-----------------------------------------------------------------------*/ +void SyncInvCut(int pnum, BYTE bLoc) { + if (bLoc < NUM_INVLOC) + plr[pnum].InvBody[bLoc]._itype = -1; + if (plr[pnum]._pmode != PM_DEATH) CalcPlrInv(pnum,TRUE); + else CalcPlrInv(pnum,FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RemoveInvItem(int pnum, int iv) +{ + int i; + + iv++; + for (i = 0; i < MAXINV; i++) { + if ((plr[pnum].InvGrid[i] == iv) || (plr[pnum].InvGrid[i] == -iv)) + plr[pnum].InvGrid[i] = 0; + } + iv--; + plr[pnum]._pNumInv--; + if ((plr[pnum]._pNumInv > 0) && (plr[pnum]._pNumInv != iv)) { + plr[pnum].InvList[iv] = plr[pnum].InvList[plr[pnum]._pNumInv]; + for (i = 0; i < MAXINV; i++) { + if (plr[pnum].InvGrid[i] == plr[pnum]._pNumInv+1) plr[pnum].InvGrid[i] = iv+1; + if (plr[pnum].InvGrid[i] == -(plr[pnum]._pNumInv+1)) plr[pnum].InvGrid[i] = -(iv+1); + } + } + + CalcPlrScrolls(pnum); + if ((plr[pnum]._pRSplType == SPT_SCROLL) && (plr[pnum]._pRSpell != -1)) { + if (!(plr[pnum]._pScrlSpells & (1 << plr[pnum]._pRSpell-1))) plr[pnum]._pRSpell = -1; + force_redraw = FULLDRAW; + } +} + +BOOL StripPlayer(int pnum) +{ + int i; + + // Give the plr no items in hands gfx + if (plr[pnum]._pgfxnum != PGFX_NGUY) { + plr[pnum]._pgfxnum = PGFX_NGUY; + plr[pnum]._pGFXLoad = 0; + SetPlrAnims(pnum); + } + + ItemStruct *pi = &plr[pnum].InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) + pi->_itype = -1; + + + int oldnum = plr[pnum]._pNumInv; + + ZeroMemory(plr[pnum].InvGrid,sizeof(plr[pnum].InvGrid)); + plr[pnum]._pNumInv = 0; + for (i = 0; i < oldnum; ++i) + { + pi = &plr[pnum].InvList[i]; + if (pi->_itype == IT_GOLD) + { + int num = plr[pnum]._pNumInv; + ItemStruct tmp = *pi; + + pi->_itype = -1; + plr[pnum].InvList[num] = tmp; + plr[pnum]._pNumInv++; + plr[pnum].InvGrid[i] = plr[pnum]._pNumInv; + } + else + pi->_itype = -1; + } + + // zero speedbar + pi = &plr[pnum].SpdList[0]; + for (i = MAXSPD; i--; pi++) + pi->_itype = -1; + + CalcPlrItemVals(pnum,FALSE); + return FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RemoveSpdBarItem(int pnum, int iv) +{ + plr[pnum].SpdList[iv]._itype = -1; + CalcPlrScrolls(pnum); + if ((plr[pnum]._pRSplType == SPT_SCROLL) && (plr[pnum]._pRSpell != -1)) { + if (!(plr[pnum]._pScrlSpells & (1 << plr[pnum]._pRSpell-1))) plr[pnum]._pRSpell = -1; + } + force_redraw = FULLDRAW; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckInvScrn() { + if (curs >= ICSTART) CheckInvPaste(myplr, MouseX, MouseY); + else CheckInvCut(myplr, MouseX, MouseY); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckSpdBar() { + if ((MouseX > 190) && (MouseX < 437) && (MouseY > 352) && (MouseY < 385)) + CheckInvScrn(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckItemStats(int pnum) { + PlayerStruct * p = &plr[pnum]; + ItemStruct * pi = &p->HoldItem; + + pi->_iStatFlag = FALSE; + if (p->_pStrength < pi->_iMinStr) return; + if (p->_pMagic < (byte)pi->_iMinMag) return; + if (p->_pDexterity < pi->_iMinDex) return; + pi->_iStatFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CheckBookLevel(int pnum) +{ + if (plr[pnum].HoldItem._iMiscId != IMID_BOOK) return; + plr[pnum].HoldItem._iMinMag = spelldata[plr[pnum].HoldItem._iSpell].sMinInt; + int slvl = plr[pnum]._pSplLvl[plr[pnum].HoldItem._iSpell]; + while (slvl != 0) { + plr[pnum].HoldItem._iMinMag += ((plr[pnum].HoldItem._iMinMag * 20) / 100); + slvl--; + if ((plr[pnum].HoldItem._iMinMag + ((plr[pnum].HoldItem._iMinMag * 20) / 100)) > 255) { + plr[pnum].HoldItem._iMinMag = 255; + slvl = 0; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CheckQuestItem(int pnum) +{ + if (plr[pnum].HoldItem.IDidx == IDI_OPTAMULET) quests[Q_BLIND]._qactive = QUEST_DONE; + if (plr[pnum].HoldItem.IDidx == IDI_MUSHROOM + && quests[Q_BKMUSHRM]._qactive == QUEST_NOTDONE + && quests[Q_BKMUSHRM]._qvar1 == QS_MUSHSPAWNED) { + // say "That is a big mushroom" + #if !IS_VERSION(SHAREWARE) + sfxdelay = 10; + if (plr[pnum]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR95; + else if (plr[pnum]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE95; + else if (plr[pnum]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE95; + else if (plr[pnum]._pClass == CLASS_MONK) sfxdnum = PS_MONK95; + else if (plr[pnum]._pClass == CLASS_BARD) sfxdnum = PS_BARD95; + else if (plr[pnum]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN95; + #endif + quests[Q_BKMUSHRM]._qvar1 = QS_MUSHPICKED; + } + if (plr[pnum].HoldItem.IDidx == IDI_ANVIL) { + if (quests[Q_ANVIL]._qactive == QUEST_NOTACTIVE) { + quests[Q_ANVIL]._qactive = QUEST_NOTDONE; + quests[Q_ANVIL]._qvar1 = 1; + } + if (quests[Q_ANVIL]._qlog == TRUE) { + #if !IS_VERSION(SHAREWARE) + sfxdelay = 10; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR89; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE89; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE89; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK89; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD89; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN89; + #endif + } + } + + if (plr[pnum].HoldItem.IDidx == IDI_GLDNELIX) { + #if !IS_VERSION(SHAREWARE) + sfxdelay = 30; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR88; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE88; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE88; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK88; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD88; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN88; + #endif + } + if (plr[pnum].HoldItem.IDidx == IDI_ROCK) { + if (quests[Q_ROCK]._qactive == QUEST_NOTACTIVE) { + quests[Q_ROCK]._qactive = QUEST_NOTDONE; + quests[Q_ROCK]._qvar1 = 1; + } + if (quests[Q_ROCK]._qlog == TRUE) { + #if !IS_VERSION(SHAREWARE) + sfxdelay = 10; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR87; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE87; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE87; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK87; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD87; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN87; + #endif + } + } + + if (plr[pnum].HoldItem.IDidx == IDI_ARMOFVAL) { + quests[Q_BLOOD]._qactive = QUEST_DONE; + #if !IS_VERSION(SHAREWARE) + sfxdelay = 20; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR91; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE91; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE91; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK91; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD91; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN91; + #endif + } + + // Add pick up item triggers here. JKE + if (plr[pnum].HoldItem.IDidx == IDI_MAPOFDOOM) { + quests[Q_CRYPTMAP]._qactive = QUEST_NOTDONE; + quests[Q_CRYPTMAP]._qvar1 = 1; + quests[Q_CRYPTMAP]._qlog = FALSE; + + #if !IS_VERSION(SHAREWARE) + sfxdelay = 10; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR79; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE79; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE79; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK79; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD79; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN79; + #endif + + } + + if ((plr[pnum].HoldItem.IDidx == IDI_NOTE1) || + (plr[pnum].HoldItem.IDidx == IDI_NOTE2) || + (plr[pnum].HoldItem.IDidx == IDI_NOTE3)) + { + #if !IS_VERSION(SHAREWARE) + + int noteflag = 0; + int idi = plr[pnum].HoldItem.IDidx; + int x1, x2, x3; + + if (PlrHasItem(pnum, IDI_NOTE1, x1) || idi == IDI_NOTE1) + noteflag |= 0x01; + + if (PlrHasItem(pnum, IDI_NOTE2, x2) || idi == IDI_NOTE2) + noteflag |= 0x02; + + if (PlrHasItem(pnum, IDI_NOTE3, x3) || idi == IDI_NOTE3) + noteflag |= 0x04; + + if (noteflag == 0x07) + { + // "Just what I was looking for" + sfxdelay = 10; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR46; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE46; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE46; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK46; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD46; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN46; + + // Put the items together + switch(idi) + { + case IDI_NOTE1: + PlrHasItem(pnum, IDI_NOTE2, x2); + RemoveInvItem(pnum, x2); + PlrHasItem(pnum, IDI_NOTE3, x3); + RemoveInvItem(pnum, x3); + break; + case IDI_NOTE2: + PlrHasItem(pnum, IDI_NOTE1, x1); + RemoveInvItem(pnum, x1); + PlrHasItem(pnum, IDI_NOTE3, x3); + RemoveInvItem(pnum, x3); + break; + case IDI_NOTE3: + PlrHasItem(pnum, IDI_NOTE1, x1); + RemoveInvItem(pnum, x1); + PlrHasItem(pnum, IDI_NOTE2, x2); + RemoveInvItem(pnum, x2); + break; + } + + int ii = itemavail[0]; // use this item slot temporarily + ItemStruct tmp = item[ii]; + + GetItemAttrs(ii, IDI_FULLNOTE, 16); + SetupItem(ii); + plr[pnum].HoldItem = item[ii]; + + item[ii] = tmp; + } + #endif + } + +} + +/*-----------------------------------------------------------------------* +** Processes CMD_GETITEM player command +**-----------------------------------------------------------------------*/ + +void InvGetItem(int pnum, int ii) +{ + + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + if (dItem[item[ii]._ix][item[ii]._iy] == 0) return; // Already picked up? + // Next line can happen in mulitplayer due to latecency + if ((myplr == pnum) && (curs >= ICSTART)) { + NetSendCmdPItem(TRUE,CMD_SYNCPUTITEM,plr[myplr]._px,plr[myplr]._py); + //InvPutItem(myplr,plr[myplr]._px,plr[myplr]._py); + } + + // once an item is picked up it is no longer a pregen item + if (item[ii]._iUid != 0) + item[ii]._iCreateInfo &= ICI_PREGENMASK; + plr[pnum].HoldItem = item[ii]; + CheckQuestItem(pnum); + CheckBookLevel(pnum); + CheckItemStats(pnum); + + // added 970911 by DKT + BOOL done = FALSE; + if (plr[pnum].HoldItem._itype == IT_GOLD) { + if (GoldAutoPlace(pnum)) + done = TRUE; + } + + // PATCH1.JMM + DROPLOG(" InvGetItem: deleting item %d.\n",ii); +// item[ii]._iDelFlag = TRUE; + // ENDPATCH1.JMM + + dItem[item[ii]._ix][item[ii]._iy] = 0; + if (currlevel == CRYPTSTART) + { + if (item[ii]._ix == CornerStone.x && + item[ii]._iy == CornerStone.y) + { + CornerStone.item.IDidx = -1; + CornerStone.item._itype = 0; + CornerStone.item._ix = 0; + CornerStone.item._iy = 0; + CornerStone.item._iAnimFlag = FALSE; + CornerStone.item._iSelFlag = ISEL_NONE; + CornerStone.item._iIdentified = FALSE; + CornerStone.item._iPostDraw = FALSE; + + } + } + + // PATCH1.JMM + int j; + int jj; + + #if _DEBUG + for(j = 0; j < numitems; j++) { + DROPLOG(" InvGetItem: itemactive[%2.2d]: %2.2d\n",j,itemactive[j]); + } + #endif + + j = 0; + while (j < numitems) { + jj = itemactive[j]; + + if (jj == ii) { + DROPLOG(" InvGetItem: Removing item index %d (struct %d,numitems %d) from item list!\n",j,jj,numitems); + DeleteItem(jj, j); + j = 0; + } + else { + j++; + } + + } + // ENDPATCH1.JMM + + cursitem = -1; + if (!done) + NewCursor(plr[pnum].HoldItem._iCurs + ICSTART); +} + +/*-----------------------------------------------------------------------* +** Processes CMD_AGETITEM player command +**-----------------------------------------------------------------------*/ + +void AutoGetItem(int pnum, int ii) +{ + int i, g, w, h, idx; + BOOL done; + + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + + // drb.patch1.start.02/15/97 + if (ii != TEMPAVAIL) { + // drb.patch1.end.02/15/97 + if (dItem[item[ii]._ix][item[ii]._iy] == 0) return; // Already picked up? + } + + done = FALSE; + // once an item is picked up it is no longer a pregen item + if (item[ii]._iUid != 0) + item[ii]._iCreateInfo &= ICI_PREGENMASK; + // Pick it up to get params for placing UID_OPTAMULET + plr[pnum].HoldItem = item[ii]; + CheckQuestItem(pnum); + CheckBookLevel(pnum); + CheckItemStats(pnum); + SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); + + // Try and fit it in + if (plr[pnum].HoldItem._itype == IT_GOLD) { + done = GoldAutoPlace(pnum); + + if (!done) + { + // If we only particially filled our inventory with gold. + // reduce the temp value by to the new amount we are holding. + item[ii]._ivalue = plr[pnum].HoldItem._ivalue; + } + } else { + done = FALSE; + g = plr[pnum]._pgfxnum & PGFX_MASK; + if (((g == PGFX_NGUY) || (g == PGFX_SGUY) || + (plr[pnum]._pClass == CLASS_BARD && (g == PGFX_ZGUY || g == PGFX_XGUY))) && + (plr[pnum]._pmode <= PM_WALK3) && + ((plr[pnum].HoldItem._iStatFlag) && (plr[pnum].HoldItem._iClass == IC_WEAP))) { + done = WeaponAutoPlace(pnum); + if (done) CalcPlrInv(pnum,TRUE); + } + if (!done) { + // all items are either 1x1, 1x2, 1x3, 2x2, or 2x3 + // the inv is 10x4 + w = icursW28; + h = icursH28; + if ((w == 1) && (h == 1)) { + // Check to see if speed bar available first + idx = plr[pnum].HoldItem.IDidx; + if ((plr[pnum].HoldItem._iStatFlag) && (AllItemsList[idx].iUsable)) { + for (i = 0; (i < MAXSPD) && (!done); i++) { + if (plr[pnum].SpdList[i]._itype == -1) { + plr[pnum].SpdList[i] = plr[pnum].HoldItem; + CalcPlrScrolls(pnum); + drawsbarflag = TRUE; + done = TRUE; + } + } + } + // Start in lower left and continue trying right then up a line + for (i = 30; (i <= 39) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 20; (i <= 29) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 10; (i <= 19) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 0; (i <= 9) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + } + if ((w == 1) && (h == 2)) { + // Try 3rd row, 1st row, and then 2nd row + for (i = 29; (i >= 20) && (!done); i--) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 9; (i >= 0) && (!done); i--) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 19; (i >= 10) && (!done); i--) done = AutoPlace(pnum, i, w, h, TRUE); + } + if ((w == 1) && (h == 3)) { + // Try 1st row then 2nd row + for (i = 0; (i < 20) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + } + if ((w == 2) && (h == 2)) { + // Try 1st and 3rd row starting right and moving left + for (i = 0; (i < 10) && (!done); i++) done = AutoPlace(pnum, AP2x2Tbl[i], w, h, TRUE); + // Try 3rd row, 1st row, and then 2nd row + for (i = 21; (i < 29) && (!done); i+=2) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 1; (i < 9) && (!done); i+=2) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 10; (i < 19) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + } + if ((w == 2) && (h == 3)) { + // Try 1st row then 2nd row + for (i = 0; (i < 9) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + for (i = 10; (i < 19) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); + } + } + } + + if (done) { + // PATCH1.JMM + DROPLOG(" AutoGetItem: set item[%d].iDelFlag = TRUE",ii); + //item[ii]._iDelFlag = TRUE; + dItem[item[ii]._ix][item[ii]._iy] = 0; + if (currlevel == CRYPTSTART) + { + if (item[ii]._ix == CornerStone.x && + item[ii]._iy == CornerStone.y) + { + CornerStone.item.IDidx = -1; + CornerStone.item._itype = 0; + CornerStone.item._ix = 0; + CornerStone.item._iy = 0; + CornerStone.item._iAnimFlag = FALSE; + CornerStone.item._iSelFlag = ISEL_NONE; + CornerStone.item._iIdentified = FALSE; + CornerStone.item._iPostDraw = FALSE; + } + } + + int j; + int jj; + + j = 0; + while (j < numitems) { + jj = itemactive[j]; + + if (jj == ii) { + DROPLOG(" AutogetItem: Removing item index %d (struct %d,numitems %d) from item list!\n",j,jj,numitems); + DeleteItem(jj, j); + j = 0; + } + else { + j++; + } + + } + // ENDPATCH1.JMM + + } else { + if (pnum == myplr) { + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR14+random(0,3)); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE14+random(0,3)); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE14+random(0,3)); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySFX(PS_MONK14+random(0,3)); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySFX(PS_BARD14+random(0,3)); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN14+random(0,3)); + #endif + } + plr[pnum].HoldItem = item[ii]; + DROPLOG("AutogetItem\n"); + RespawnItem(ii, TRUE); + NetSendCmdPItem(TRUE,CMD_RESPAWNITEM,item[ii]._ix,item[ii]._iy); + plr[pnum].HoldItem._itype = -1; + // we're going to drop the item so change the cursor back to a glove. + NewCursor(GLOVE_CURS); + } +} + +// PATCH1.JMM +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if _DEBUG +void VerifyItemActiveList( void ) +{ + int i, j; + UINT nItemIndex; + + int nCurrIndex; + WORD wCurrCI; + int dwCurrSeed; + BYTE x, y; + + for( i = 0; i < numitems; i++ ) { + nItemIndex = itemactive[i]; + + nCurrIndex = item[nItemIndex].IDidx; + wCurrCI = item[nItemIndex]._iCreateInfo; + dwCurrSeed = item[nItemIndex]._iSeed; + x = item[nItemIndex]._ix; + y = item[nItemIndex]._iy; + + for( j = i+1; j < numitems; j++ ) { + nItemIndex = itemactive[j]; + if((item[nItemIndex].IDidx == nCurrIndex) && (item[nItemIndex]._iSeed == dwCurrSeed) && (item[nItemIndex]._iCreateInfo == wCurrCI)) + DROPLOG(" VerifyItemActiveList: Duplicate item detected: itemactive[%d] = %d (%d %8.8x %4.4x)\n",j, nItemIndex, nCurrIndex, dwCurrSeed, wCurrCI); + +// app_assert(!((item[nItemIndex].IDidx == nCurrIndex) && (item[nItemIndex]._iSeed == dwCurrSeed) && (item[nItemIndex]._iCreateInfo == wCurrCI))); +// app_assert(!((item[nItemIndex]._ix == x) && (item[nItemIndex]._iy == y))); + } + } +} +#else + #define VerifyItemActiveList() +#endif +// ENDPATCH1.JMM + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int FindGetItem(int idx, WORD ci, int iseed) +{ + int i, ii; + + // PATCH1.JMM + VerifyItemActiveList(); + + for (i = 0; i < numitems; i++) { + ii = itemactive[i]; + if ((item[ii].IDidx == idx) && (item[ii]._iSeed == iseed) && (item[ii]._iCreateInfo == ci)) { + return (ii); + } + } + // ENDPATCH1.JMM + + return (-1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SyncGetItem(int x, int y, int idx, WORD ci, int iseed) +{ + int ii; + + // PATCH1.JMM + VerifyItemActiveList(); + + DROPLOG(" Doing SyncGetItem...\n"); + // try optimal location first + if (dItem[x][y] != 0) { + DROPLOG(" Attempting to find item by (x,y)\n"); + ii = dItem[x][y] - 1; + if ((item[ii].IDidx != idx) || (item[ii]._iSeed != iseed) || (item[ii]._iCreateInfo != ci)) { + ii = FindGetItem(idx, ci, iseed); + DROPLOG(" Bad (x,y). Did FindGetItem->%d.\n"); + } + else { + DROPLOG(" (x,y) said ii == %d, FindGetItem says ii == %d\n",ii,FindGetItem(idx,ci,iseed)); + } + } + else { + DROPLOG(" Nongood (x,y)\n"); + ii = FindGetItem(idx, ci, iseed); + } + + DROPLOG(" FindGetItem returned %d\n",ii); + + if (ii != -1) { + DROPLOG(" Removing item from map!\n"); + // remove from map + dItem[item[ii]._ix][item[ii]._iy] = 0; + + if (currlevel == CRYPTSTART) + { + if (item[ii]._ix == CornerStone.x && + item[ii]._iy == CornerStone.y) + { + CornerStone.item.IDidx = -1; + CornerStone.item._itype = 0; + CornerStone.item._ix = 0; + CornerStone.item._iy = 0; + CornerStone.item._iAnimFlag = FALSE; + CornerStone.item._iSelFlag = ISEL_NONE; + CornerStone.item._iIdentified = FALSE; + CornerStone.item._iPostDraw = FALSE; + } + } + // remove from list + int j = 0; + while (j < numitems) { + int jj = itemactive[j]; + + if (jj == ii) { + DROPLOG(" Removing item index %d (struct %d,numitems %d) from item list!\n",j,jj,numitems); + + DeleteItem(jj, j); + + jj = FindGetItem(idx,ci,iseed); + DROPLOG(" Item removed. FindGetItem->%d, numitems->%d\n", jj, numitems); + + j = 0; + } + else { + j++; + } + + } + + app_assert(FindGetItem(idx, ci, iseed) == -1); + DROPLOG(" Item is definitely removed!\n"); + } + // ENDPATCH1.JMM +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL CanPut(int i, int j) { + int oi; + + if (dItem[i][j]) return FALSE; + if (nSolidTable[dPiece[i][j]]) return FALSE; + + if (dObject[i][j] != 0) { + if (dObject[i][j] > 0) oi = dObject[i][j]-1; + else oi = -(dObject[i][j]+1); + if (object[oi]._oSolidFlag) return FALSE; + } + if (dObject[i+1][j+1] > 0) { + oi = dObject[i+1][j+1]-1; + if (object[oi]._oSelFlag != OSEL_NONE) return FALSE; + } + if (dObject[i+1][j+1] < 0) { + oi = -(dObject[i+1][j+1]+1); + if (object[oi]._oSelFlag != OSEL_NONE) return FALSE; + } + if ((dObject[i+1][j] > 0) && (dObject[i][j+1] > 0)) { + oi = dObject[i+1][j]-1; + if (object[oi]._oSelFlag != OSEL_NONE) { + oi = dObject[i][j+1]-1; + if (object[oi]._oSelFlag != OSEL_NONE) return FALSE; + } + } + + if (((currlevel == 0) && (dMonster[i][j] != 0)) || + ((currlevel == 0) && (dMonster[i+1][j+1] != 0))) + return FALSE; + + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL TryInvPut() { + // can't drop if too many items on floor already + if (numitems >= MAXITEMS) return FALSE; + + int d = GetDirection(plr[myplr]._px, plr[myplr]._py, cursmx, cursmy); + int x = plr[myplr]._px + offset_x[d]; + int y = plr[myplr]._py + offset_y[d]; + if (CanPut(x,y)) return TRUE; + + d = (d - 1) & 0x7; + x = plr[myplr]._px + offset_x[d]; + y = plr[myplr]._py + offset_y[d]; + if (CanPut(x,y)) return TRUE; + + d = (d + 2) & 0x7; + x = plr[myplr]._px + offset_x[d]; + y = plr[myplr]._py + offset_y[d]; + if (CanPut(x,y)) return TRUE; + return(CanPut(plr[myplr]._px, plr[myplr]._py)); +} + + +// PATCH1.JMM.2/24/97 +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define DUP_DISP_INTERVAL 5 +static DWORD sgdwLastTime = 0; + +void ShowDupString( LPCSTR lpszMessage ) { + DWORD dwCurrTime; + + dwCurrTime = GetTickCount( ); + + if((dwCurrTime - sgdwLastTime) < (DUP_DISP_INTERVAL*1000)) + return; + + sgdwLastTime = dwCurrTime; + + sysmsg_add_string( lpszMessage ); +} + + +// ENDPATCH1.JMM.2/24/97 + + +/*-----------------------------------------------------------------------* +** Processes CMD_PUTITEM player command from myself +**-----------------------------------------------------------------------*/ +int InvPutItem(int pnum, int x, int y) { + // can't drop if too many items on floor already + if (numitems >= MAXITEMS) { + DROPLOG("numitems >= MAXITEMS\n"); + return -1; + } + + // drb.patch1.start.02/18/97 + // already in list? + int ii = FindGetItem(plr[pnum].HoldItem.IDidx, + plr[pnum].HoldItem._iCreateInfo, plr[pnum].HoldItem._iSeed); + if (ii != -1) { + DROPLOG(" Duplicate item detected!\n"); + // JMM.PATCH1.2.22.97 + // NetSendString(1 << myplr, "A duplicate item has been detected. Unable to drop."); + ShowDupString("A duplicate item has been detected. Destroying duplicate..."); + SyncGetItem(x,y,plr[pnum].HoldItem.IDidx,plr[pnum].HoldItem._iCreateInfo,plr[pnum].HoldItem._iSeed); + // END.JMM.PATCH1.2.22.97 + } + // drb.patch1.end.02/18/97 + + VerifyItemActiveList(); + + // if square is too far away, then drop on adjacent square + int d = GetDirection(plr[pnum]._px, plr[pnum]._py, x, y); + int dx = x - plr[pnum]._px; + int dy = y - plr[pnum]._py; + if (abs(dx) > 1 || abs(dy) > 1) { + x = plr[pnum]._px + offset_x[d]; + y = plr[pnum]._py + offset_y[d]; + } + + if (!CanPut(x,y)) { + d = (d - 1) & 0x7; + x = plr[pnum]._px + offset_x[d]; + y = plr[pnum]._py + offset_y[d]; + if (!CanPut(x,y)) { + d = (d + 2) & 0x7; + x = plr[pnum]._px + offset_x[d]; + y = plr[pnum]._py + offset_y[d]; + if (!CanPut(x,y)) { + // radial search outward until a space is found + BOOL done = FALSE; + for (int l = 1; (l < 50) && !done; l++) { + for (int j = -l; (j <= l) && !done; j++) { + int yy = plr[pnum]._py + j; + for (int i = -l; (i <= l) && !done; i++) { + int xx = plr[pnum]._px + i; + if (!CanPut(xx,yy)) continue; + done = TRUE; + x = xx; + y = yy; + } + } + } + if (! done) return -1; + } + } + } +// JKEQUESTS Dropping stuff + if (currlevel == 0) + { + if (plr[pnum].HoldItem._iCurs == ITEM_RUNEBOMB) + { + if(((cursmx >= 79) && (cursmx <= 82)) && ((cursmy >= 61) && (cursmy <= 64))) + { + NetSendCmdLocParam2(FALSE, + CMD_OPEN_NEST, + plr[pnum]._px, + plr[pnum]._py, + dx, + dy ); + quests[Q_FARMER]._qactive = QUEST_DONE; + if (gbMaxPlayers != 1) + NetSendCmdQuest(TRUE, Q_FARMER); + return -1; + } + } + if (plr[pnum].HoldItem.IDidx == IDI_MAPOFDOOM) + { + if(((cursmx >= 35) && (cursmx <= 38)) && ((cursmy >= 20) && (cursmy <= 24))) + { + NetSendCmd(FALSE, CMD_OPEN_CRYPT); + quests[Q_CRYPTMAP]._qactive = QUEST_DONE; + if (gbMaxPlayers != 1) + NetSendCmdQuest(TRUE, Q_CRYPTMAP); + return -1; + } + } + } + + + app_assert(CanPut(x,y)); + ii = itemavail[0]; + dItem[x][y] = ii+1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + item[ii] = plr[pnum].HoldItem; + item[ii]._ix = x; + item[ii]._iy = y; + + + DROPLOG(" InvPutItem\n"); + RespawnItem(ii, TRUE); + numitems++; + + if (currlevel == CRYPTSTART) + { + if (x == CornerStone.x && y == CornerStone.y) + { +// memcpy(&(CornerStone.item), &(item[ii]), SAVE_ITEM_SIZE); + CornerStone.item = item[ii]; + + // Jims stuff + InitQTextMsg(TXT_CORNERSTONE1); + + quests[Q_CORNERSTONE]._qlog = FALSE; + quests[Q_CORNERSTONE]._qactive = QUEST_DONE; + + + } + } + + NewCursor(GLOVE_CURS); + return ii; +} + + +/*-----------------------------------------------------------------------* +** Processes CMD_PUTITEM player command from another person +**-----------------------------------------------------------------------*/ +#if CHEATS +BOOL syncdebug = FALSE; +#endif + + +int SyncPutItem( + int pnum, + int x, + int y, + int idx, + WORD icreateinfo, + int iseed, + BOOL Id, + int dur, + int mdur, + int ch, + int mch, + int ivalue, + DWORD ibuff, + int PLToHit, + int MaxDam, + int MinStr, + int MinMag, + int MinDex, + int AC) { + + #if CHEATS + if (syncdebug) { + sprintf(tempstr, "Player %i dropping item.", pnum); + NetSendString((1 << myplr), tempstr); + } + #endif + + // can't drop if too many items on floor already + if (numitems >= MAXITEMS) { + DROPLOG("numitems >= MAXITEMS\n"); + return -1; + } + + // drb.patch1.start.02/18/97 + // already in list? + int ii = FindGetItem(idx, icreateinfo, iseed); + if (ii != -1) { + DROPLOG(" Duplicate item detected!\n"); + // JMM.PATCH1.2.22.97 + //NetSendString(1 << myplr, "A duplicate item has been detected from another player."); + ShowDupString("A duplicate item has been detected from another player."); + SyncGetItem(x,y,idx,icreateinfo,iseed); + // END.JMM.PATCH1.2.22.97 + // return(-1); + } + // drb.patch1.end.02/18/97 + + // if square is too far away, then drop on adjacent square + int d = GetDirection(plr[pnum]._px, plr[pnum]._py, x, y); + int dx = x - plr[pnum]._px; + int dy = y - plr[pnum]._py; + if (abs(dx) > 1 || abs(dy) > 1) { + x = plr[pnum]._px + offset_x[d]; + y = plr[pnum]._py + offset_y[d]; + } + + if (!CanPut(x,y)) { + d = (d - 1) & 0x7; + x = plr[pnum]._px + offset_x[d]; + y = plr[pnum]._py + offset_y[d]; + if (!CanPut(x,y)) { + d = (d + 2) & 0x7; + x = plr[pnum]._px + offset_x[d]; + y = plr[pnum]._py + offset_y[d]; + if (!CanPut(x,y)) { + BOOL done = FALSE; + // radial search outward until a space is found + for (int l = 1; (l < 50) && !done; l++) { + for (int j = -l; (j <= l) && !done; j++) { + int yy = plr[pnum]._py + j; + for (int i = -l; (i <= l) && !done; i++) { + int xx = plr[pnum]._px + i; + if (!CanPut(xx,yy)) continue; + done = TRUE; + x = xx; + y = yy; + } + } + } + if (! done) { + DROPLOG("Failed to find a good square to drop in!\n"); + return -1; + } + } + } + } + + + app_assert(CanPut(x,y)); + ii = itemavail[0]; + dItem[x][y] = ii+1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + app_assert(ii >= 0); + + if (idx == IDI_EAR) { + RecreateEar(ii, icreateinfo, iseed, Id, dur, mdur, ch, mch, ivalue, ibuff); + } else { + RecreateItem(ii, idx, icreateinfo, iseed, ivalue); + if (Id) item[ii]._iIdentified = TRUE; + item[ii]._iDurability = dur; + item[ii]._iMaxDur = mdur; + item[ii]._iCharges = ch; + item[ii]._iMaxCharges = mch; + item[ii]._iPLToHit = PLToHit; + item[ii]._iMaxDam = MaxDam; + item[ii]._iMinStr = MinStr; + item[ii]._iMinMag = MinMag; + item[ii]._iMinDex = MinDex; + item[ii]._iAC = AC; + } + item[ii]._ix = x; + item[ii]._iy = y; + + DROPLOG("SyncPutItem: respawning object %d!\n",ii); + RespawnItem(ii, TRUE); + numitems++; + + if (currlevel == CRYPTSTART) + { + if (x == CornerStone.x && y == CornerStone.y) + { +// memcpy(&(CornerStone.item), &(item[ii]), SAVE_ITEM_SIZE); + CornerStone.item = item[ii]; + + // Jims stuff + InitQTextMsg(TXT_CORNERSTONE1); + + quests[Q_CORNERSTONE]._qlog = FALSE; + quests[Q_CORNERSTONE]._qactive = QUEST_DONE; + + } + } + + return(ii); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +char CheckInvHLight() { + + // find box + for (int r = 0; r < INVRECTS; r++) { + if ((MouseX >= InvRect[r].x) && + (MouseX < InvRect[r].x + 29) && + (MouseY >= InvRect[r].y - 29) && + (MouseY < InvRect[r].y)) + break; + } + if (r >= INVRECTS) return -1; + + char rv = -1; + infoclr = ICOLOR_WHITE; + ItemStruct * pi = NULL; + PlayerStruct * p = &plr[myplr]; + ClearPanel(); + + if (r >= 0 && r <= 3) { + rv = INVLOC_HEAD; + pi = &p->HeadItem; + } + else if (r == 4) { + rv = INVLOC_RING1; + pi = &p->Ring1Item; + } + else if (r == 5) { + rv = INVLOC_RING2; + pi = &p->Ring2Item; + } + else if (r == 6) { + rv = INVLOC_NECK; + pi = &p->NeckItem; + } + else if (r >= 7 && r <= 12) { + rv = INVLOC_HAND1; + pi = &p->Hand1Item; + } + else if (r >= 13 && r <= 18) { + // check for two handed item + pi = &p->Hand1Item; + if (pi->_itype != -1 && pi->_iLoc == IL_2HAND + && !(p->_pClass == CLASS_BARBARIAN + && ( p->Hand1Item._itype == IT_SWORD || + p->Hand1Item._itype == IT_MACE ) + ) + ) { + rv = INVLOC_HAND1; + } + else { + rv = INVLOC_HAND2; + pi = &p->Hand2Item; + } + } + else if (r >= 19 && r <= 24) { + rv = INVLOC_BODY; + pi = &p->BodyItem; + } + else if (r >= 25 && r <= 64) { + // is there an inventory item in this slot? + if (0 == (r = abs(p->InvGrid[r - 25]))) return -1; + + // make zero based + r--; + + // convert to global inventory slot number + rv = r + NUM_INVLOC; + + // get item + pi = &p->InvList[r]; + } + else if (r >= 65) { + drawsbarflag = TRUE; + r -= 65; + pi = &p->SpdList[r]; + if (pi->_itype == -1) return -1; + + // convert to global inventory slot number + rv = r + MAXINV + NUM_INVLOC; + } + + // Do I have an item (I should) + app_assert(pi); + + // Is it still there? + if (pi->_itype == -1) return -1; + + if (pi->_itype == IT_GOLD) { + int nGold = pi->_ivalue; + const char * get_pieces_str(int nGold); + sprintf(infostr,"%i gold %s",nGold,get_pieces_str(nGold)); + } + else { + if (pi->_iMagical == IMAGIC_MAGIC) infoclr = ICOLOR_BLUE; + else if (pi->_iMagical == IMAGIC_UNIQUE) infoclr = ICOLOR_GOLD; + strcpy(infostr, pi->_iName); + if (pi->_iIdentified) { + strcpy(infostr, pi->_iIName); + PrintItemDetails(pi); + } else { + PrintItemDur(pi); + } + } + + return rv; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RemoveScroll(int pnum) +{ + int i; + + for (i = 0; i < plr[pnum]._pNumInv; i++) { + if ((plr[pnum].InvList[i]._itype != -1) && + ((plr[pnum].InvList[i]._iMiscId == IMID_SCROLL) || + (plr[pnum].InvList[i]._iMiscId == IMID_TSCROLL)) && + (plr[pnum].InvList[i]._iSpell == plr[pnum]._pSpell)) { + RemoveInvItem(pnum, i); + CalcPlrScrolls(pnum); + return; + } + } + for (i = 0; i < MAXSPD; i++) { + if ((plr[pnum].SpdList[i]._itype != -1) && + ((plr[pnum].SpdList[i]._iMiscId == IMID_SCROLL) || + (plr[pnum].SpdList[i]._iMiscId == IMID_TSCROLL)) && + (plr[pnum].SpdList[i]._iSpell == plr[pnum]._pSpell)) { + RemoveSpdBarItem(pnum, i); + CalcPlrScrolls(pnum); + return; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL UseScroll() +{ + int i; + + if (curs != GLOVE_CURS) return(FALSE); + // rjs if (leveltype == 0) return(FALSE); + if (leveltype == 0 && spelldata[plr[myplr]._pRSpell].sTownSpell == FALSE) return(FALSE); + for (i = 0; i < plr[myplr]._pNumInv; i++) { + if ((plr[myplr].InvList[i]._itype != -1) && + ((plr[myplr].InvList[i]._iMiscId == IMID_SCROLL) || + (plr[myplr].InvList[i]._iMiscId == IMID_TSCROLL)) && + (plr[myplr].InvList[i]._iSpell == plr[myplr]._pRSpell)) { + return(TRUE); + } + } + for (i = 0; i < MAXSPD; i++) { + if ((plr[myplr].SpdList[i]._itype != -1) && + ((plr[myplr].SpdList[i]._iMiscId == IMID_SCROLL) || + (plr[myplr].SpdList[i]._iMiscId == IMID_TSCROLL)) && + (plr[myplr].SpdList[i]._iSpell == plr[myplr]._pRSpell)) { + return(TRUE); + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void UseStaffCharge(int pnum) +{ + if ((plr[pnum].Hand1Item._itype != -1) && + (plr[pnum].Hand1Item._iMiscId == IMID_STAFF || + plr[myplr].Hand1Item._iMiscId == IMID_UNIQUE) && + (plr[pnum].Hand1Item._iSpell == plr[pnum]._pRSpell) && + (plr[pnum].Hand1Item._iCharges > 0)) { + plr[pnum].Hand1Item._iCharges--; + CalcPlrStaff(pnum); + return; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL UseStaff() +{ + if (curs != GLOVE_CURS) return(FALSE); + if ((plr[myplr].Hand1Item._itype != -1) && + (plr[myplr].Hand1Item._iMiscId == IMID_STAFF || + plr[myplr].Hand1Item._iMiscId == IMID_UNIQUE) && + (plr[myplr].Hand1Item._iSpell == plr[myplr]._pRSpell) && + (plr[myplr].Hand1Item._iCharges > 0)) { + return(TRUE); + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL UseStaffSBook(int spl) +{ + if (curs != GLOVE_CURS) return(FALSE); + if ((plr[myplr].Hand1Item._itype != -1) && + (plr[myplr].Hand1Item._iMiscId == IMID_STAFF || + plr[myplr].Hand1Item._iMiscId == IMID_UNIQUE) && + (plr[myplr].Hand1Item._iSpell == spl) && + (plr[myplr].Hand1Item._iCharges > 0)) { + return(TRUE); + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CheckUsable(int pnum, int cii) +{ + int c, idata; + BOOL rv; + + // Can't use items on my body, just in my inv + rv = FALSE; + if (cii <= 5) return(rv); + if (cii <= 46) { + c = cii - 7; + idata = plr[pnum].InvList[c].IDidx; + if (AllItemsList[idata].iUsable) rv = TRUE; + } else { + c = cii - 47; + idata = plr[pnum].SpdList[c].IDidx; + if (AllItemsList[idata].iUsable) rv = TRUE; + } + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +extern int dropGoldValue; + +void StartGoldDrop() +{ + // Save the index of the gold pile + initialDropGoldIndex = cursinvitem; + + if (cursinvitem <= 46) // Gold item is in InvList + // Save the value of the gold pile + initialDropGoldValue = plr[myplr].InvList[cursinvitem-7]._ivalue; + else // Gold item is in SpdList + // Save the value of the gold pile + initialDropGoldValue = plr[myplr].SpdList[cursinvitem-47]._ivalue; + + // Set flag so drop gold functionality is enabled + dropGoldFlag = TRUE; + // Initialize the drop gold value when right click gold pile + dropGoldValue = 0; + + if (talkflag) TalkEnd(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL UseInvItem(int pnum, int cii) +{ + int c, idata, it; + ItemStruct *Item; + BOOL speedlist; + + // Don't use while dead + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) return TRUE; + // Don't use unless glove curs + if (curs != GLOVE_CURS) return TRUE; + // Don't use during stores + if (stextflag != STORE_NONE) return TRUE; + + // Can't use items on my body, just in my inv + if (cii <= 5) return FALSE; + if (cii <= 46) { + c = cii - 7; + Item = &plr[pnum].InvList[c]; + speedlist = FALSE; + } else { + if (talkflag) return TRUE; + c = cii - 47; + Item = &plr[pnum].SpdList[c]; + speedlist = TRUE; + } + + idata = Item->IDidx; + switch (idata) + { + case IDI_MUSHROOM: + sfxdelay = 10; + #if !IS_VERSION(SHAREWARE) + if (plr[pnum]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR95; + else if (plr[pnum]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE95; + else if (plr[pnum]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE95; + else if (plr[pnum]._pClass == CLASS_MONK) sfxdnum = PS_MONK95; + else if (plr[pnum]._pClass == CLASS_BARD) sfxdnum = PS_BARD95; + else if (plr[pnum]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN95; + #endif + return TRUE; + case IDI_FUNGALTM: + PlaySFX(IS_IBOOK); + sfxdelay = 10; + if (plr[pnum]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR29; + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE29; + else if (plr[pnum]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE29; + else if (plr[pnum]._pClass == CLASS_MONK) sfxdnum = PS_MONK29; + else if (plr[pnum]._pClass == CLASS_BARD) sfxdnum = PS_BARD29; + else if (plr[pnum]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN29; + #endif + return TRUE; + } + if (!AllItemsList[idata].iUsable) + return FALSE; + if (!Item->_iStatFlag) { + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR13); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE13); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE13); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySFX(PS_MONK13); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySFX(PS_BARD13); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN13); + #endif + return TRUE; + } else { + // Was the item chosen a pile of gold + if ((Item->_iMiscId == IMID_NONE) && (Item->_itype == IT_GOLD)) + { + StartGoldDrop(); + return TRUE;; + } + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + + if ((Item->_iMiscId == IMID_SCROLL) && (currlevel == 0) && + (spelldata[Item->_iSpell].sTownSpell == FALSE)) return TRUE; + if ((Item->_iMiscId == IMID_TSCROLL) && (currlevel == 0) && + (spelldata[Item->_iSpell].sTownSpell == FALSE)) return TRUE; + if ((Item->_iMiscId > IMID_FIRSTRUNE) && + (Item->_iMiscId < IMID_LASTRUNE) && + (currlevel == 0)) return TRUE; + it = ItemCAnimTbl[Item->_iCurs]; + if (Item->_iMiscId == IMID_BOOK) PlaySFX(IS_RBOOK); + else if (pnum == myplr) PlaySFX(ItemInvSnds[it]); + UseItem(pnum, Item->_iMiscId, Item->_iSpell); + + if (speedlist) + { + if (plr[pnum].SpdList[c]._iMiscId == IMID_FULLNOTE) + { + InitQTextMsg(TXT_SKULLJRNL7); + invflag = FALSE; +// PlaySFX(HSFX_SKULLJRNL7); + return TRUE; + } + RemoveSpdBarItem(pnum, c); + } + else + { + // Don't delete map of doom when used + if (plr[pnum].InvList[c]._iMiscId == IMID_MAPOFDOOM) return TRUE; + if (plr[pnum].InvList[c]._iMiscId == IMID_FULLNOTE) + { + InitQTextMsg(TXT_SKULLJRNL7); + invflag = FALSE; +// PlaySFX(HSFX_SKULLJRNL7); + return TRUE; + } + RemoveInvItem(pnum, c); + } + } + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoTelekinesis() +{ + if (cursobj != -1) { + NetSendCmdParam1(TRUE, CMD_OPOBJT, cursobj); + } + if (cursitem != -1) { + NetSendCmdGItem(TRUE, CMD_REQUESTAGITEM, myplr, myplr, cursitem); + } + BOOL M_Talker (int); + if ((cursmonst != -1) && (!M_Talker(cursmonst)) && (monster[cursmonst].mtalkmsg == 0)) { + NetSendCmdParam1(TRUE, CMD_KNOCKBACK, cursmonst); + } + + NewCursor(GLOVE_CURS); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +long CalculateGold(int pnum) +{ + int i; + long gold; + + // Initialize gold + gold = 0; + // Find the gold in the speedbar list + for (i = 0; i < MAXSPD; i++) { + if (plr[pnum].SpdList[i]._itype == IT_GOLD) { + gold += plr[pnum].SpdList[i]._ivalue; + force_redraw = FULLDRAW; + } + } + // Find the gold in the inventory list + for (i = 0; i < plr[pnum]._pNumInv; i++) { + if (plr[pnum].InvList[i]._itype == IT_GOLD) + gold += plr[pnum].InvList[i]._ivalue; + } + + return(gold); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL DropItemBeforeTrig() +/*-----------------------------------------------------------------------** +** DESCRIPTION: Drops the item the player has in hand before talking to a +** towner or entering a level. +** INPUT: None +** RETURN: TRUE = The item was dropped successfully +** FALSE = The item could not be dropped. +/*-----------------------------------------------------------------------*/ +{ + if (TryInvPut()) { + NetSendCmdPItem(TRUE,CMD_PUTITEM,cursmx,cursmy); + NewCursor(GLOVE_CURS); + return TRUE; + } + return FALSE; +} + +int GetHighRingValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_RING + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_RING + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + +int GetHighBowValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_BOW + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_BOW + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + +int GetHighStaffValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_STAFF + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_STAFF + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + +int GetHighSwordValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_SWORD + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_SWORD + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + +int GetHighHelmValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_HELM + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_HELM + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + +int GetHighShieldValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_SHIELD + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_SHIELD + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + +int GetHighArmorValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && (plr[myPlr].InvBody[i]._itype == IT_ARMOR + || plr[myPlr].InvBody[i]._itype == IT_MARMOR + || plr[myPlr].InvBody[i]._itype == IT_HARMOR ) + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && (plr[myPlr].InvList[i]._itype == IT_ARMOR + || plr[myPlr].InvList[i]._itype == IT_MARMOR + || plr[myPlr].InvList[i]._itype == IT_HARMOR) + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + +int GetHighMaceValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_MACE + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_MACE + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + return itemValue; +} + +int GetHighAmuletValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_AMULET + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_AMULET + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + return itemValue; +} + +int GetHighAxeValue(int myPlr) +{ + int itemValue = 0; + int i; + + for (i =0; i < NUM_INVLOC; ++i) + { + if (plr[myPlr].InvBody[i]._iClass != -1 + && plr[myPlr].InvBody[i]._itype == IT_AXE + && itemValue < plr[myPlr].InvBody[i]._iIvalue) + { + itemValue = plr[myPlr].InvBody[i]._iIvalue; + } + } + for (i =0; i < MAXINV; ++i) + { + if (plr[myPlr].InvList[i]._iClass != -1 + && plr[myPlr].InvList[i]._itype == IT_AXE + && itemValue < plr[myPlr].InvList[i]._iIvalue) + { + itemValue = plr[myPlr].InvList[i]._iIvalue; + } + } + + return itemValue; +} + diff --git a/INV.H b/INV.H new file mode 100644 index 0000000..11f2d9a --- /dev/null +++ b/INV.H @@ -0,0 +1,96 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/INV.H 3 2/14/97 11:23a Dbrevik $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern BOOL invflag; +extern BOOL drawsbarflag; + + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void InitInv(); + +void DrawInv(); +void DrawSpdBar(); + +void FreeInvGFX(); + +void CheckInvScrn(); +void CheckSpdBar(); + +void InvGetItem(int, int); +void AutoGetItem(int, int); +int FindGetItem(int, WORD, int); +void SyncGetItem(int, int, int, WORD, int); + +int InvPutItem(int, int, int); +int SyncPutItem(int, + int, + int, + int, + WORD, + int, + BOOL, + int, + int, + int, + int, + int, + DWORD, + int, + int, + int, + int, + int, + int); +BOOL TryInvPut(); + +char CheckInvHLight(); +void RemoveInvItem(int, int); + +void CheckInvPaste(int, int, int); +// drb.patch1.start.02/10/97 +//void SyncInvPaste(int pnum, BYTE bLoc, int idx, WORD icreateinfo, int iseed); +void SyncInvPaste(int pnum, BYTE bLoc, int idx, WORD icreateinfo, int iseed, BOOL Id); +// drb.patch1.end.02/10/97 +void CheckInvCut(int, int, int); +void SyncInvCut(int pnum, BYTE bLoc); + +BOOL CheckUsable(int, int); +BOOL UseInvItem(int, int); + +void RemoveScroll(int); +BOOL UseScroll(); + +void UseStaffCharge(int); +BOOL UseStaff(); +BOOL UseStaffSBook(int); + +BOOL AutoPlace(int, int, int, int, BOOL); +BOOL SpecialAutoPlace(int, int, int, int, BOOL); +void DoTelekinesis(); + +long CalculateGold(int pnum); +void RemoveSpdBarItem(int pnum, int iv); + +BOOL DropItemBeforeTrig(); +int GetHighRingValue(int /* myPlr */); +int GetHighBowValue(int /* myPlr */); +int GetHighStaffValue(int /* myPlr */); +int GetHighSwordValue(int /* myPlr */); +int GetHighHelmValue(int /* myPlr */); +int GetHighArmorValue(int /* myPlr */); +int GetHighMaceValue(int /* myPlr */); +int GetHighAmuletValue(int /* myPlr */); +int GetHighAxeValue(int /* myPlr */); +int GetHighShieldValue(int /* myPlr */); diff --git a/ITEMDAT.CPP b/ITEMDAT.CPP new file mode 100644 index 0000000..1106ecf --- /dev/null +++ b/ITEMDAT.CPP @@ -0,0 +1,2255 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Items file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/ITEMDAT.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "items.h" +#include "itemdat.h" +#include "spells.h" + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +// There is an enumeration which should match the order of the items in +// this list in items.h + +ItemDataStruct AllItemsList[] = { + // These first few must remain in this order + // Must be first + { IRND_NORMAL, IC_GOLD, IL_INV, ITEM_GOLD, IT_GOLD, ITEMID_NONE, "Gold", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, TRUE, 0, 0 }, + // Initial items + // Warrior init weapon + { IRND_NO, IC_WEAP, IL_HAND, ITEM_SHORTSRD, IT_SWORD, ITEMID_NONE, "Short Sword", NULL, + 2, 20, // Min level, durability + 2, 6, 0, 0, // Min damage, max damage, min ac, max ac + 18, 0, 0, // Min Str, Min Mag, Min Dex + 0, IMID_NONE, 0, FALSE, 50, 50 }, // Attr Flags, Misc Id, Spell, usable item, item value + // Warrior init shield + { IRND_NO, IC_ARMOR, IL_HAND, ITEM_BUCKLER, IT_SHIELD, ITEMID_NONE, "Buckler", NULL, + 2, 10, // Min level, durability + 0, 0, 3, 3, // Min damage, max damage, min ac, max ac + 0, 0, 0, // Min Str, Min Mag, Min Dex + 0, IMID_NONE, 0, FALSE, 50, 50 }, // Attr Flags, Misc Id, Spell, usable item, item value + // Warrior init club + { IRND_NO, IC_WEAP, IL_HAND, ITEM_CLUB, IT_MACE, ITEMID_CLUB, "Club", NULL, + 1, 20, + 1, 6, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 20, 20 }, + // Rogue init weapon + { IRND_NO, IC_WEAP, IL_2HAND, ITEM_SHORTBOW, IT_BOW, ITEMID_NONE, "Short Bow", NULL, + 1, 30, // Min level, durability + 1, 4, 0, 0, // Min damage, max damage, min ac, max ac + 0, 0, 0, // Min Str, Min Mag, Min Dex + 0, IMID_NONE, 0, FALSE, 100, 100 }, // Attr Flags, Misc Id, Spell, usable item, item value + // Sorceror init weapon + { IRND_NO, IC_WEAP, IL_2HAND, ITEM_SHRTSTAFF, IT_STAFF, ITEMID_NONE, "Short Staff of Mana", NULL, + 1, 25, // Min level, durability + 2, 4, 0, 0, // Min damage, max damage, min ac, max ac + 0, 20, 0, // Min Str, Min Mag, Min Dex + 0, IMID_STAFF, SPL_MANA, FALSE, 520, 520 }, // Attr Flags, Misc Id, Spell, usable item, item value + + // Start of Quest items + // The Butcher's Cleaver of DEATH! + { IRND_NO, IC_WEAP, IL_2HAND, ITEM_CLEAVER, IT_AXE, ITEMID_CLEAVER, "Cleaver", NULL, + 10, 10, + 4, 24, 0, 0, + 0, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 2000, 2000 }, + // Helm of life stealing from The Skeleton King + { IRND_NO, IC_ARMOR, IL_HEAD, ITEM_SKCROWN, IT_HELM, ITEMID_SKCROWN, "The Undead Crown", NULL, + 0, 50, + 0, 0, 15, 15, + 0, 0, 0, + IAF_SKING, IMID_UNIQUE, 0, FALSE, 10000, 10000 }, + // Empyrean band from meteor (infravision ring) + { IRND_NO, IC_ITEM, IL_RING, ITEM_EMPYBAND, IT_RING, ITEMID_IRING, "Empyrean Band", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 8000, 8000 }, + // Rock from rock quest + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_ROCK, IT_MISC, ITEMID_NONE, "Magic Rock", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + // Optic Amulet from the Halls of the Blind quest + { IRND_NO, IC_ITEM, IL_NECK, ITEM_AMULET, IT_AMULET, ITEMID_OPTAMULET, "Optic Amulet", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 5000, 5000 }, + // Ring of Truth for Poison Water Quest + { IRND_NO, IC_ITEM, IL_RING, ITEM_BLUERING, IT_RING, ITEMID_TRING, "Ring of Truth", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 1000, 1000 }, + // Banner from banner quest + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_INNSIGN, IT_MISC, ITEMID_NONE, "Tavern Sign", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + // Harlequin Crest from banner quest + { IRND_NO, IC_ARMOR, IL_HEAD, ITEM_SKLCAP2, IT_HELM, ITEMID_HALCREST, "Harlequin Crest", NULL, + 0, 15, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 15, 20 }, + // Veil of Steel for the Veil of Steel quest + { IRND_NO, IC_ARMOR, IL_HEAD, ITEM_GRTHELM, IT_HELM, ITEMID_STEELVEIL, "Veil of Steel", NULL, + 0, 60, + 0, 0, 18, 18, + 0, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 0, 0 }, + // Golden Elixor for the Veil of Steel quest + { IRND_NO, IC_ITEM, IL_INV, ITEM_GOLDENELIX, IT_MISC, ITEMID_ELIXIR, "Golden Elixir", NULL, + 15, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + // Anvil for anvil of fury quest + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_ANVIL, IT_MISC, ITEMID_NONE, "Anvil of Fury", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + // Black Mushroom for the quest by the same the name + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_MUSHROOM, IT_MISC, ITEMID_NONE, "Black Mushroom", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + // The brain for the Black Mushroom quest + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_BRAIN, IT_MISC, ITEMID_NONE, "Brain", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + // Fungal Tome + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_BOOK4, IT_MISC, ITEMID_NONE, "Fungal Tome", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + // Elixir for the Black Mushroom quest + { IRND_NO, IC_ITEM, IL_INV, ITEM_SPECTRAL, IT_MISC, ITEMID_ELIXIR, "Spectral Elixir", NULL, + 15, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SPECTRAL, 0, FALSE, 0, 0 }, + // Stones for the Stones of Blood quest + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_BLOODGEM, IT_MISC, ITEMID_NONE, "Blood Stone", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + + // Map for Demon Crypt quest (was Map of Doom quest) + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_MAP, IT_MISC, ITEMID_MAP, "Cathedral Map", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_MAPOFDOOM, 0, TRUE, 0, 0 }, + + // The infamous ear + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_EAR1, IT_MISC, ITEMID_NONE, "Heart", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_EAR, 0, FALSE, 0, 0 }, + + // end of quest items + + // Initial/Useful level items + { IRND_NO, IC_ITEM, IL_INV, ITEM_REDBTL, IT_MISC, ITEMID_NONE, "Potion of Healing", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PLHEAL, 0, TRUE, 50, 50 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_BLUEBTL2, IT_MISC, ITEMID_NONE, "Potion of Mana", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PMANA, 0, TRUE, 50, 50 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Identify", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SCROLL, SPL_IDENTIFY, TRUE, 200, 200 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Town Portal", NULL, + 4, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SCROLL, SPL_TOWN, TRUE, 200, 200 }, + +/*-----------------------------------------------------------------------*/ + + // The next few entries are for expansion + { IRND_NO, IC_ARMOR, IL_BODY, ITEM_ARKARMOR, IT_MARMOR, ITEMID_ARMOFVAL, "Arkaine's Valor", NULL, + 0, 40, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 0, 0 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_BREDBTL, IT_MISC, ITEMID_NONE, "Potion of Full Healing", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PHEAL, 0, TRUE, 150, 150 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_BLUEBTL, IT_MISC, ITEMID_NONE, "Potion of Full Mana", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PFMANA, 0, TRUE, 150, 150 }, + { IRND_NO, IC_WEAP, IL_HAND, ITEM_BROADSRD, IT_SWORD, ITEMID_GRISWOLD, "Griswold's Edge", NULL, + 8, 50, + 4, 12, 0, 0, + 40, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 750, 750 }, + { IRND_NO, IC_ARMOR, IL_BODY, ITEM_ARMRCOW, IT_HARMOR, ITEMID_ARMRCOW, "Bovine Plate", NULL, + 0, 40, + 0, 0, 0, 0, + 50, 0, 0, + 0, IMID_UNIQUE, 0, FALSE, 0, 0 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_BISHOPSTF, IT_MISC, ITEMID_LAZSTAFF, "Staff of Lazarus", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Resurrect", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_TSCROLL, SPL_RESURRECT, TRUE, 250, 250 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_BLKBTL, IT_MISC, ITEMID_NONE, "Blacksmith Oil", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_OILBLKSM, 0, TRUE, 100, 100 }, + { IRND_NO, IC_WEAP, IL_2HAND, ITEM_SHRTSTAFF, IT_STAFF, ITEMID_NONE, "Short Staff", NULL, // Monk inital staff + 1, 25, // Min level, durablity + 2, 4, 0, 0, // Min damage, max damage, min ac, max ac + 0, 0, 0, // Min Str, Min Mag, Min Dex + 0, IMID_NONE, 0, FALSE, 20, 20 }, // Attr Flags, Misc Id, Spell, usable item, item value + { IRND_NO, IC_WEAP, IL_HAND, ITEM_SHORTSRD, IT_SWORD, ITEMID_NONE, "Sword", NULL, // Bard sword + 2, 8, // Min level, durability + 1, 5, 0, 0, // Min damage, max damage, min ac, max ac + 15, 0, 20, // Min Str, Min Mag, Min Dex + 0, IMID_NONE, 0, FALSE, 20, 20 }, // Attr Flags, Misc Id, Spell, usable item, item value + { IRND_NO, IC_WEAP, IL_HAND, ITEM_DAGGER2, IT_SWORD, ITEMID_NONE, "Dagger", NULL, // Bard Dagger + 1, 16, // Min level, durability + 1, 4, 0, 0, // Min damage, max damage, min ac, max ac + 0, 0, 0, // Min Str, Min Mag, Min Dex + 0, IMID_NONE, 0, FALSE, 20, 20 }, // Attr Flags, Misc Id, Spell, usable item, item value + + // Bomb to open up Festering Nest + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_RUNEBOMB, IT_MISC, ITEMID_NONE, "Rune Bomb", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_THEODORE, IT_MISC, ITEMID_NONE, "Theodore", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + + // the Auric Amulet + { IRND_NO, IC_ITEM, IL_NECK, ITEM_AMULGOLD, IT_MISC, ITEMID_NONE, "Auric Amulet", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_AURIC, 0, FALSE, 100, 100 }, + + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_TORNPAPER1, IT_MISC, ITEMID_NONE, "Torn Note 1", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_TORNPAPER2, IT_MISC, ITEMID_NONE, "Torn Note 2", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_TORNPAPER3, IT_MISC, ITEMID_NONE, "Torn Note 3", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_WHOLEPAPER, IT_MISC, ITEMID_NONE, "Reconstructed Note", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_FULLNOTE, 0, TRUE, 0, 0 }, + + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_SUITBRWN, IT_MISC, ITEMID_NONE, "Brown Suit", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + + { IRND_NO, IC_SPECIAL, IL_INV, ITEM_SUITGREY, IT_MISC, ITEMID_NONE, "Grey Suit", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, + +/*-----------------------------------------------------------------------*/ + + // From here down just list of avail items + // Helmets and caps + { IRND_NORMAL, IC_ARMOR, IL_HEAD, ITEM_LCAP, IT_HELM, ITEMID_NONE, "Cap", "Cap", + 1, 15, + 0, 0, 1, 3, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 15, 20 }, + { IRND_NORMAL, IC_ARMOR, IL_HEAD, ITEM_SKLCAP, IT_HELM, ITEMID_SKULLCAP, "Skull Cap", "Cap", + 4, 20, + 0, 0, 2, 4, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 25, 30 }, + { IRND_NORMAL, IC_ARMOR, IL_HEAD, ITEM_FHELM, IT_HELM, ITEMID_HELM, "Helm", "Helm", + 8, 30, + 0, 0, 4, 6, + 25, 0, 0, + 0, IMID_NONE, 0, FALSE, 40, 70 }, + { IRND_NORMAL, IC_ARMOR, IL_HEAD, ITEM_HELM, IT_HELM, ITEMID_NONE, "Full Helm", "Helm", + 12, 35, + 0, 0, 6, 8, + 35, 0, 0, + 0, IMID_NONE, 0, FALSE, 90, 130 }, + { IRND_NORMAL, IC_ARMOR, IL_HEAD, ITEM_CROWN2, IT_HELM, ITEMID_CROWN, "Crown", "Crown", + 16, 40, + 0, 0, 8, 12, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 200, 300 }, + { IRND_NORMAL, IC_ARMOR, IL_HEAD, ITEM_FHELM3, IT_HELM, ITEMID_GREATHELM, "Great Helm", "Helm", + 20, 60, + 0, 0, 10, 15, + 50, 0, 0, + 0, IMID_NONE, 0, FALSE, 400, 500 }, + + // Body armor + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_CAPE, IT_ARMOR, ITEMID_CAPE, "Cape", "Cape", + 1, 12, + 0, 0, 1, 5, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 10, 50 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_RAGS, IT_ARMOR, ITEMID_RAGS, "Rags", "Rags", + 1, 6, + 0, 0, 2, 6, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 5, 25 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_CLOAK, IT_ARMOR, ITEMID_CLOAK, "Cloak", "Cloak", + 2, 18, + 0, 0, 3, 7, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 40, 70 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_ROBE, IT_ARMOR, ITEMID_ROBE, "Robe", "Robe", + 3, 24, + 0, 0, 4, 7, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 75, 125 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_QARMOR, IT_ARMOR, ITEMID_NONE, "Quilted Armor", "Armor", + 4, 30, + 0, 0, 7, 10, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 200, 300 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_LARMOR, IT_ARMOR, ITEMID_LEATHER, "Leather Armor", "Armor", + 6, 35, + 0, 0, 10, 13, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 300, 400 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_HLARMOR, IT_ARMOR, ITEMID_NONE, "Hard Leather Armor", "Armor", + 7, 40, + 0, 0, 11, 14, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 450, 550 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_STDARMOR, IT_ARMOR, ITEMID_STDLEATHER, "Studded Leather Armor", "Armor", + 9, 45, + 0, 0, 15, 17, + 20, 0, 0, + 0, IMID_NONE, 0, FALSE, 700, 800 }, + +#if !IS_VERSION(SHAREWARE) +// shareware version doesn't support medium and heavy armor classes + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_RINGMAIL, IT_MARMOR, ITEMID_NONE, "Ring Mail", "Mail", + 11, 50, + 0, 0, 17, 20, + 25, 0, 0, + 0, IMID_NONE, 0, FALSE, 900, 1100 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_CHARMOR, IT_MARMOR, ITEMID_CHAINMAIL, "Chain Mail", "Mail", + 13, 55, + 0, 0, 18, 22, + 30, 0, 0, + 0, IMID_NONE, 0, FALSE, 1250, 1750 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_SCLARMOR, IT_MARMOR, ITEMID_NONE, "Scale Mail", "Mail", + 15, 60, + 0, 0, 23, 28, + 35, 0, 0, + 0, IMID_NONE, 0, FALSE, 2300, 2800 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_BPLATE, IT_HARMOR, ITEMID_BREASTPLATE, "Breast Plate", "Plate", + 16, 80, + 0, 0, 20, 24, + 40, 0, 0, + 0, IMID_NONE, 0, FALSE, 2800, 3200 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_SPLTARMOR, IT_MARMOR, ITEMID_NONE, "Splint Mail", "Mail", + 17, 65, + 0, 0, 30, 35, + 40, 0, 0, + 0, IMID_NONE, 0, FALSE, 3250, 3750 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_PARMOR, IT_HARMOR, ITEMID_PLATEMAIL, "Plate Mail", "Plate", + 19, 75, + 0, 0, 42, 50, + 60, 0, 0, + 0, IMID_NONE, 0, FALSE, 4600, 5400 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_PARMOR, IT_HARMOR, ITEMID_NONE, "Field Plate", "Plate", + 21, 80, + 0, 0, 40, 45, + 65, 0, 0, + 0, IMID_NONE, 0, FALSE, 5800, 6200 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_PARMOR3, IT_HARMOR, ITEMID_NONE, "Gothic Plate", "Plate", + 23, 100, + 0, 0, 50, 60, + 80, 0, 0, + 0, IMID_NONE, 0, FALSE, 8000, 10000 }, + { IRND_NORMAL, IC_ARMOR, IL_BODY, ITEM_PARMOR2, IT_HARMOR, ITEMID_FULLPLATE, "Full Plate Mail", "Plate", + 25, 90, + 0, 0, 60, 75, + 90, 0, 0, + 0, IMID_NONE, 0, FALSE, 6500, 8000 }, +#endif + + // Shields + { IRND_NORMAL, IC_ARMOR, IL_HAND, ITEM_BUCKLER, IT_SHIELD, ITEMID_BUCKLER, "Buckler", "Shield", + 1, 16, + 0, 0, 1, 5, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 30, 70 }, + { IRND_NORMAL, IC_ARMOR, IL_HAND, ITEM_WSHIELD, IT_SHIELD, ITEMID_SMALLSHLD, "Small Shield", "Shield", + 5, 24, + 0, 0, 3, 8, + 25, 0, 0, + 0, IMID_NONE, 0, FALSE, 90, 130 }, + { IRND_NORMAL, IC_ARMOR, IL_HAND, ITEM_KITESHLD, IT_SHIELD, ITEMID_LARGESHLD, "Large Shield", "Shield", + 9, 32, + 0, 0, 5, 10, + 40, 0, 0, + 0, IMID_NONE, 0, FALSE, 200, 300 }, + { IRND_NORMAL, IC_ARMOR, IL_HAND, ITEM_HVYSHIELD, IT_SHIELD, ITEMID_KITESHLD, "Kite Shield", "Shield", + 14, 40, + 0, 0, 8, 15, + 50, 0, 0, + 0, IMID_NONE, 0, FALSE, 400, 700 }, + { IRND_NORMAL, IC_ARMOR, IL_HAND, ITEM_TSHIELD, IT_SHIELD, ITEMID_TOWERSHLD, "Tower Shield", "Shield", + 20, 50, + 0, 0, 12, 20, + 60, 0, 0, + 0, IMID_NONE, 0, FALSE, 850, 1200 }, + { IRND_NORMAL, IC_ARMOR, IL_HAND, ITEM_LRGSHLD, IT_SHIELD, ITEMID_TOWERSHLD, "Gothic Shield", "Shield", + 23, 60, + 0, 0, 14, 18, + 80, 0, 0, + 0, IMID_NONE, 0, FALSE, 2300, 2700 }, + + // Potions + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_REDBTL, IT_MISC, ITEMID_NONE, "Potion of Healing", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PLHEAL, 0, TRUE, 50, 50 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BREDBTL, IT_MISC, ITEMID_NONE, "Potion of Full Healing", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PHEAL, 0, TRUE, 150, 150 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLUEBTL2, IT_MISC, ITEMID_NONE, "Potion of Mana", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PMANA, 0, TRUE, 50, 50 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLUEBTL, IT_MISC, ITEMID_NONE, "Potion of Full Mana", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PFMANA, 0, TRUE, 150, 150 }, +/* removed 11/23 by dave + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLKBTL, IT_MISC, ITEMID_NONE, "Potion of Experience", NULL, + 20, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_PEXP, 0, TRUE, 0, 0 }, +*/ + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_GOLDBTL, IT_MISC, ITEMID_NONE, "Potion of Rejuvenation", NULL, + 3, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_REJUV, 0, TRUE, 120, 120 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_YELBTL, IT_MISC, ITEMID_NONE, "Potion of Full Rejuvenation", NULL, + 7, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_FREJUV, 0, TRUE, 600, 600 }, + + // Oils removed 11/21 by dave + // Oils back in for hellfire 7/30 by donald + + // Oils + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLKBTL, IT_MISC, ITEMID_NONE, "Blacksmith Oil", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_OILBLKSM, 0, TRUE, 100, 100 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLKBTL, IT_MISC, ITEMID_NONE, "Oil of Accuracy", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_OILACC, 0, TRUE, 500, 500 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLKBTL, IT_MISC, ITEMID_NONE, "Oil of Sharpness", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_OILSHRP, 0, TRUE, 500, 500 }, + + // a random oil + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLKBTL, IT_MISC, ITEMID_NONE, "Oil", NULL, + 10, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_OIL, 0, TRUE, 0, 0 }, + + // Elixirs + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_LTBLUEBTL, IT_MISC, ITEMID_NONE, "Elixir of Strength", NULL, + 15, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_ESTR, 0, TRUE, 5000, 5000 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_ORGBTL, IT_MISC, ITEMID_NONE, "Elixir of Magic", NULL, + 15, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_EMAG, 0, TRUE, 5000, 5000 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BLKBTL2, IT_MISC, ITEMID_NONE, "Elixir of Dexterity", NULL, + 15, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_EDEX, 0, TRUE, 5000, 5000 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_WHTEBTL, IT_MISC, ITEMID_NONE, "Elixir of Vitality", NULL, + 20, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_EVIT, 0, TRUE, 5000, 5000 }, + + // Scrolls +/* { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Firebolt", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_TSCROLL, SPL_FIREBOLT, TRUE, 50, 50 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Charged Bolt", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_TSCROLL, SPL_CBOLT, TRUE, 50, 50 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Holy Bolt", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_TSCROLL, SPL_HBOLT, TRUE, 50, 50 }, +*/ + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Healing", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SCROLL, SPL_HEAL, TRUE, 50, 50 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Search", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SCROLL, SPL_SHOWMAGITEMS, TRUE, 50, 50 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Lightning", NULL, + 4, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_TSCROLL, SPL_LIGHTNING, TRUE, 150, 150 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Identify", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SCROLL, SPL_IDENTIFY, TRUE, 100, 100 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Resurrect", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_TSCROLL, SPL_RESURRECT, TRUE, 250, 250 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Fire Wall", NULL, + 4, 0, + 0, 0, 0, 0, + 0, 17, 0, + 0, IMID_TSCROLL, SPL_WALL, TRUE, 400, 400 }, +/* { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Telekinesis", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 21, 0, + 0, IMID_TSCROLL, SPL_TELEKINESIS, TRUE, 50, 50 }, +*/ + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Inferno", NULL, + 1, 0, + 0, 0, 0, 0, + 0, 19, 0, + 0, IMID_TSCROLL, SPL_FLAME, TRUE, 100, 100 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Town Portal", NULL, + 4, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SCROLL, SPL_TOWN, TRUE, 200, 200 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Flash", NULL, + 6, 0, + 0, 0, 0, 0, + 0, 21, 0, + 0, IMID_TSCROLL, SPL_FLASH, TRUE, 500, 500 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Infravision", NULL, + 8, 0, + 0, 0, 0, 0, + 0, 23, 0, + 0, IMID_SCROLL, SPL_INFRA, TRUE, 600, 600 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Phasing", NULL, + 6, 0, + 0, 0, 0, 0, + 0, 25, 0, + 0, IMID_SCROLL, SPL_PHASE, TRUE, 200, 200 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Mana Shield", NULL, + 8, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_SCROLL, SPL_MANASHLD, TRUE, 1200, 1200 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Flame Wave", NULL, + 10, 0, + 0, 0, 0, 0, + 0, 29, 0, + 0, IMID_TSCROLL, SPL_WAVE, TRUE, 650, 650 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Fireball", NULL, + 8, 0, + 0, 0, 0, 0, + 0, 31, 0, + 0, IMID_TSCROLL, SPL_FIREBALL, TRUE, 300, 300 }, +#if IS_VERSION(RETAIL) + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Stone Curse", NULL, + 6, 0, + 0, 0, 0, 0, + 0, 33, 0, + 0, IMID_TSCROLL, SPL_STONE, TRUE, 800, 800 }, +#endif + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Chain Lightning", NULL, + 10, 0, + 0, 0, 0, 0, + 0, 35, 0, + 0, IMID_TSCROLL, SPL_CHAIN, TRUE, 750, 750 }, +#if IS_VERSION(RETAIL) + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Guardian", NULL, + 12, 0, + 0, 0, 0, 0, + 0, 47, 0, + 0, IMID_TSCROLL, SPL_GUARDIAN, TRUE, 950, 950 }, + { IRND_NO, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Non Item", NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 }, +#endif + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Nova", NULL, + 14, 0, + 0, 0, 0, 0, + 0, 57, 0, + 0, IMID_SCROLL, SPL_NOVA, TRUE, 1300, 1300 }, +#if IS_VERSION(RETAIL) + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Golem", NULL, + 10, 0, + 0, 0, 0, 0, + 0, 51, 0, + 0, IMID_TSCROLL, SPL_GOLEM, TRUE, 1100, 1100 }, + +// used to be scroll of blood boil - no longer in game - rjs + { IRND_NO, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of None", NULL, + 99, 0, + 0, 0, 0, 0, + 0, 61, 0, + 0, IMID_TSCROLL, SPL_NONE, TRUE, 1000, 1000 }, + +#endif + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Teleport", NULL, + 14, 0, + 0, 0, 0, 0, + 0, 81, 0, + 0, IMID_SCROLL, SPL_TELE, TRUE, 3000, 3000 }, +#if IS_VERSION(RETAIL) + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Apocalypse", NULL, + 22, 0, + 0, 0, 0, 0, + 0, 117, 0, + 0, IMID_SCROLL, SPL_APOCA, TRUE, 2000, 2000 }, +#endif +/* { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Bone Spirit", NULL, + 14, 0, + 0, 0, 0, 0, + 0, 35, 0, + 0, IMID_TSCROLL, SPL_, TRUE, 2000, 2000 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_SCROLL, IT_MISC, ITEMID_NONE, "Scroll of Blood Star", NULL, + 20, 0, + 0, 0, 0, 0, + 0, 35, 0, + 0, IMID_TSCROLL, SPL_, TRUE, 2000, 2000 }, +*/ + + // Books + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BOOK, IT_MISC, ITEMID_NONE, "Book of ", NULL, + 2, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_BOOK, 0, TRUE, 0, 0 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BOOK, IT_MISC, ITEMID_NONE, "Book of ", NULL, + 8, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_BOOK, 0, TRUE, 0, 0 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BOOK, IT_MISC, ITEMID_NONE, "Book of ", NULL, + 14, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_BOOK, 0, TRUE, 0, 0 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_BOOK, IT_MISC, ITEMID_NONE, "Book of ", NULL, + 20, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_BOOK, 0, TRUE, 0, 0 }, + // Bladed weapons + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_DAGGER2, IT_SWORD, ITEMID_DAGGER, "Dagger", "Dagger", + 1, 16, + 1, 4, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 60, 60 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_SHORTSRD, IT_SWORD, ITEMID_NONE, "Short Sword", "Sword", + 1, 24, + 2, 6, 0, 0, + 18, 0, 0, + 0, IMID_NONE, 0, FALSE, 120, 120 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_SCIMITAR, IT_SWORD, ITEMID_FALCHION, "Falchion", "Sword", + 2, 20, + 4, 8, 0, 0, + 30, 0, 0, + 0, IMID_NONE, 0, FALSE, 250, 250 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_SCIMITAR2, IT_SWORD, ITEMID_SCIMITAR, "Scimitar", "Sword", + 4, 28, + 3, 7, 0, 0, + 23, 0, 23, + 0, IMID_NONE, 0, FALSE, 200, 200 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_CLAYMORE, IT_SWORD, ITEMID_CLAYMORE, "Claymore", "Sword", + 5, 36, + 1, 12, 0, 0, + 35, 0, 0, + 0, IMID_NONE, 0, FALSE, 450, 450 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_BLADE, IT_SWORD, ITEMID_NONE, "Blade", "Blade", + 4, 30, + 3, 8, 0, 0, + 25, 0, 30, + 0, IMID_NONE, 0, FALSE, 280, 280 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_SABRE, IT_SWORD, ITEMID_SABRE, "Sabre", "Sabre", + 1, 45, + 1, 8, 0, 0, + 17, 0, 0, + 0, IMID_NONE, 0, FALSE, 170, 170 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_LONGSRD, IT_SWORD, ITEMID_LONGSWORD, "Long Sword", "Sword", + 6, 40, + 2, 10, 0, 0, + 30, 0, 30, + 0, IMID_NONE, 0, FALSE, 350, 350 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_BROADSRD, IT_SWORD, ITEMID_BROADSWORD, "Broad Sword", "Sword", + 8, 50, + 4, 12, 0, 0, + 40, 0, 0, + 0, IMID_NONE, 0, FALSE, 750, 750 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_BASTSRD, IT_SWORD, ITEMID_BASTSWORD, "Bastard Sword", "Sword", + 10, 60, + 6, 15, 0, 0, + 50, 0, 0, + 0, IMID_NONE, 0, FALSE, 1000, 1000 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_2HSWORD, IT_SWORD, ITEMID_2HANDSWORD, "Two-Handed Sword", "Sword", + 14, 75, + 8, 16, 0, 0, + 65, 0, 0, + 0, IMID_NONE, 0, FALSE, 1800, 1800 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_GRTSWORD, IT_SWORD, ITEMID_GREATSWORD, "Great Sword", "Sword", + 17, 100, + 10, 20, 0, 0, + 75, 0, 0, + 0, IMID_NONE, 0, FALSE, 3000, 3000 }, + + // Axes + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_SMALLAXE, IT_AXE, ITEMID_SMALLAXE, "Small Axe", "Axe", + 2, 24, + 2, 10, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 150, 150 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_HANDAXE, IT_AXE, ITEMID_NONE, "Axe", "Axe", + 4, 32, + 4, 12, 0, 0, + 22, 0, 0, + 0, IMID_NONE, 0, FALSE, 450, 450 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_LRGAXE, IT_AXE, ITEMID_LARGEAXE, "Large Axe", "Axe", + 6, 40, + 6, 16, 0, 0, + 30, 0, 0, + 0, IMID_NONE, 0, FALSE, 750, 750 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_BROADAXE, IT_AXE, ITEMID_BROADAXE, "Broad Axe", "Axe", + 8, 50, + 8, 20, 0, 0, + 50, 0, 0, + 0, IMID_NONE, 0, FALSE, 1000, 1000 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_BTLAXE, IT_AXE, ITEMID_BATTLEAXE, "Battle Axe", "Axe", + 10, 60, + 10, 25, 0, 0, + 65, 0, 0, + 0, IMID_NONE, 0, FALSE, 1500, 1500 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_WICKAXE, IT_AXE, ITEMID_GREATAXE, "Great Axe", "Axe", + 12, 75, + 12, 30, 0, 0, + 80, 0, 0, + 0, IMID_NONE, 0, FALSE, 2500, 2500 }, + + // Blunt weapons + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_MACE, IT_MACE, ITEMID_MACE, "Mace", "Mace", + 2, 32, + 1, 8, 0, 0, + 16, 0, 0, + 0, IMID_NONE, 0, FALSE, 200, 200 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_MORNSTAR, IT_MACE, ITEMID_MORNSTAR, "Morning Star", "Mace", + 3, 40, + 1, 10, 0, 0, + 26, 0, 0, + 0, IMID_NONE, 0, FALSE, 300, 300 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_SMLWARHAM, IT_MACE, ITEMID_WARHAMMER, "War Hammer", "Hammer", + 5, 50, + 5, 9, 0, 0, + 40, 0, 0, + 0, IMID_NONE, 0, FALSE, 600, 600 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_CLUB2, IT_MACE, ITEMID_CLUB, "Spiked Club", "Club", + 4, 20, + 3, 6, 0, 0, + 18, 0, 0, + 0, IMID_NONE, 0, FALSE, 225, 225 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_CLUB, IT_MACE, ITEMID_CLUB, "Club", "Club", + 1, 20, + 1, 6, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 20, 20 }, + { IRND_NORMAL, IC_WEAP, IL_HAND, ITEM_FLAIL, IT_MACE, ITEMID_FLAIL, "Flail", "Flail", + 7, 36, + 2, 12, 0, 0, + 30, 0, 0, + 0, IMID_NONE, 0, FALSE, 500, 500 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_MAUL, IT_MACE, ITEMID_MAUL, "Maul", "Maul", + 10, 50, + 6, 20, 0, 0, + 55, 0, 0, + 0, IMID_NONE, 0, FALSE, 900, 900 }, + + // Bows + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_SHORTBOW, IT_BOW, ITEMID_SHORTBOW, "Short Bow", "Bow", + 1, 30, + 1, 4, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 100, 100 }, + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_LONGBOW, IT_BOW, ITEMID_BOW, "Hunter's Bow", "Bow", + 3, 40, + 2, 5, 0, 0, + 20, 0, 35, + 0, IMID_NONE, 0, FALSE, 350, 350 }, + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_LONGBOW, IT_BOW, ITEMID_LONGBOW, "Long Bow", "Bow", + 5, 35, + 1, 6, 0, 0, + 25, 0, 30, + 0, IMID_NONE, 0, FALSE, 250, 250 }, + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_HNTRBOW, IT_BOW, ITEMID_COMPBOW, "Composite Bow", "Bow", + 7, 45, + 3, 6, 0, 0, + 25, 0, 40, + 0, IMID_NONE, 0, FALSE, 600, 600 }, + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_SBATLBOW, IT_BOW, ITEMID_NONE, "Short Battle Bow", "Bow", + 9, 45, + 3, 7, 0, 0, + 30, 0, 50, + 0, IMID_NONE, 0, FALSE, 750, 750 }, + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_STLLONGBOW, IT_BOW, ITEMID_LBATTLEBOW, "Long Battle Bow", "Bow", + 11, 50, + 1, 10, 0, 0, + 30, 0, 60, + 0, IMID_NONE, 0, FALSE, 1000, 1000 }, + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_SWARBOW, IT_BOW, ITEMID_NONE, "Short War Bow", "Bow", + 15, 55, + 4, 8, 0, 0, + 35, 0, 70, + 0, IMID_NONE, 0, FALSE, 1500, 1500 }, + { IRND_DOUBLE, IC_WEAP, IL_2HAND, ITEM_STLLONGBOW, IT_BOW, ITEMID_LWARBOW, "Long War Bow", "Bow", + 19, 60, + 1, 14, 0, 0, + 45, 0, 80, + 0, IMID_NONE, 0, FALSE, 2000, 2000 }, + // Staffs + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_SHRTSTAFF, IT_STAFF, ITEMID_SHORTSTAFF, "Short Staff", "Staff", + 1, 25, + 2, 4, 0, 0, + 0, 0, 0, + 0, IMID_STAFF, 0, FALSE, 30, 30 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_IRONSTAFF, IT_STAFF, ITEMID_LONGSTAFF, "Long Staff", "Staff", + 4, 35, + 4, 8, 0, 0, + 0, 0, 0, + 0, IMID_STAFF, 0, FALSE, 100, 100 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_COMPSTF, IT_STAFF, ITEMID_COMPSTAFF, "Composite Staff", "Staff", + 6, 45, + 5, 10, 0, 0, + 0, 0, 0, + 0, IMID_STAFF, 0, FALSE, 500, 500 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_SHRTSTAFF, IT_STAFF, ITEMID_QTRSTAFF, "Quarter Staff", "Staff", + 9, 55, + 6, 12, 0, 0, + 20, 0, 0, + 0, IMID_STAFF, 0, FALSE, 1000, 1000 }, + { IRND_NORMAL, IC_WEAP, IL_2HAND, ITEM_STLSTAFF, IT_STAFF, ITEMID_WARSTAFF, "War Staff", "Staff", + 12, 75, + 8, 16, 0, 0, + 30, 0, 0, + 0, IMID_STAFF, 0, FALSE, 1500, 1500 }, + + // Rings + { IRND_NORMAL, IC_ITEM, IL_RING, ITEM_SLVRRING, IT_RING, ITEMID_RING, "Ring", "Ring", + 5, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_RING, 0, FALSE, 1000, 1000 }, + { IRND_NORMAL, IC_ITEM, IL_RING, ITEM_SLVRRING, IT_RING, ITEMID_RING, "Ring", "Ring", + 10, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_RING, 0, FALSE, 1000, 1000 }, + { IRND_NORMAL, IC_ITEM, IL_RING, ITEM_SLVRRING, IT_RING, ITEMID_RING, "Ring", "Ring", + 15, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_RING, 0, FALSE, 1000, 1000 }, + + // Amulet + { IRND_NORMAL, IC_ITEM, IL_NECK, ITEM_AMULET1, IT_AMULET, ITEMID_AMULET, "Amulet", "Amulet", + 8, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_AMULET, 0, FALSE, 1200, 1200 }, + { IRND_NORMAL, IC_ITEM, IL_NECK, ITEM_AMULET1, IT_AMULET, ITEMID_AMULET, "Amulet", "Amulet", + 16, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_AMULET, 0, FALSE, 1200, 1200 }, + + + // Runes + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_FIRERUNE1, IT_MISC, ITEMID_NONE, "Rune of Fire", "Rune", + 1, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_RUNEFIRE, 0, TRUE, 100, 100 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_LIGHTRUNE1, IT_MISC, ITEMID_NONE, "Rune of Lightning", "Rune", + 3, 0, + 0, 0, 0, 0, + 0, 13, 0, + 0, IMID_RUNELIGHT, 0, TRUE, 200, 200 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_FIRERUNE2, IT_MISC, ITEMID_NONE, "Greater Rune of Fire", "Rune", + 7, 0, + 0, 0, 0, 0, + 0, 42, 0, + 0, IMID_RUNEIMMOLATE, 0, TRUE, 400, 400 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_LIGHTRUNE2, IT_MISC, ITEMID_NONE, "Greater Rune of Lightning", "Rune", + 7, 0, + 0, 0, 0, 0, + 0, 42, 0, + 0, IMID_RUNENOVA, 0, TRUE, 500, 500 }, + { IRND_NORMAL, IC_ITEM, IL_INV, ITEM_STONERUNE, IT_MISC, ITEMID_NONE, "Rune of Stone", "Rune", + 7, 0, + 0, 0, 0, 0, + 0, 25, 0, + 0, IMID_RUNESTONE, 0, TRUE, 300, 300 }, + + + // Min level, durablity + // Min damage, max damage, min ac, max ac + // Min Str, Min Mag, Min Dex + // Attr Flags, Misc Id, Spell, usable item, item value + + // Data stopper + { IRND_NO, 0, -1, 0, 0, ITEMID_NONE, NULL, NULL, + 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, IMID_NONE, 0, FALSE, 0, 0 } +}; + +/*-----------------------------------------------------------------------* +** Item Power lists +**-----------------------------------------------------------------------*/ + +// Prefix, Power, min, max, level, armor/shield/weapon/staff/bow/ring, good(10)/evil(01)/either(00), Double, item good (TRUE), min val, max val +const PLStruct PL_Prefix[] = { + { "Tin", PL_NTOHIT, 6, 10, 3, 0x001011, 0x00, TRUE, FALSE, 0, 0, -3 }, + { "Brass", PL_NTOHIT, 1, 5, 1, 0x001011, 0x00, TRUE, FALSE, 0, 0, -2 }, + { "Bronze", PL_TOHIT, 1, 5, 1, 0x001011, 0x00, TRUE, TRUE, 100, 500, 2 }, + { "Iron", PL_TOHIT, 6, 10, 4, 0x001011, 0x00, TRUE, TRUE, 600, 1000, 3 }, + { "Steel", PL_TOHIT, 11, 15, 6, 0x001011, 0x00, TRUE, TRUE, 1100, 1500, 5 }, + { "Silver", PL_TOHIT, 16, 20, 9, 0x001011, 0x10, TRUE, TRUE, 1600, 2000, 7 }, + { "Gold", PL_TOHIT, 21, 30, 12, 0x001011, 0x10, TRUE, TRUE, 2100, 3000, 9 }, + { "Platinum", PL_TOHIT, 31, 40, 16, 0x001010, 0x10, TRUE, TRUE, 3100, 4000, 11 }, + { "Mithril", PL_TOHIT, 41, 60, 20, 0x001010, 0x10, TRUE, TRUE, 4100, 6000, 13 }, + { "Meteoric", PL_TOHIT, 61, 80, 23, 0x001010, 0x00, TRUE, TRUE, 6100, 10000, 15 }, + { "Weird", PL_TOHIT, 81, 100, 35, 0x001010, 0x00, TRUE, TRUE, 10100, 14000, 17 }, + { "Strange", PL_TOHIT, 101, 150, 60, 0x001010, 0x00, TRUE, TRUE, 14100, 20000, 20 }, + + { "Useless", PL_NTODAM, 100, 100, 5, 0x001110, 0x00, TRUE, FALSE, 0, 0, -8 }, + { "Bent", PL_NTODAM, 50, 75, 3, 0x001110, 0x00, TRUE, FALSE, 0, 0, -4 }, + { "Weak", PL_NTODAM, 25, 45, 1, 0x001110, 0x00, TRUE, FALSE, 0, 0, -3 }, + { "Jagged", PL_TODAM, 20, 35, 4, 0x001110, 0x00, TRUE, TRUE, 250, 450, 3 }, + { "Deadly", PL_TODAM, 36, 50, 6, 0x001110, 0x00, TRUE, TRUE, 500, 700, 4 }, + { "Heavy", PL_TODAM, 51, 65, 9, 0x001110, 0x00, TRUE, TRUE, 750, 950, 5 }, + { "Vicious", PL_TODAM, 66, 80, 12, 0x001110, 0x01, TRUE, TRUE, 1000, 1450, 8 }, + { "Brutal", PL_TODAM, 81, 95, 16, 0x001110, 0x00, TRUE, TRUE, 1500, 1950, 10 }, + { "Massive", PL_TODAM, 96, 110, 20, 0x001110, 0x00, TRUE, TRUE, 2000, 2450, 13 }, + { "Savage", PL_TODAM, 111, 125, 23, 0x001010, 0x00, TRUE, TRUE, 2500, 3000, 15 }, + { "Ruthless", PL_TODAM, 126, 150, 35, 0x001010, 0x00, TRUE, TRUE, 10100, 15000, 17 }, + { "Merciless", PL_TODAM, 151, 175, 60, 0x001010, 0x00, TRUE, TRUE, 15000, 20000, 20 }, + + { "Clumsy", PL_NDAHT, 50, 75, 5, 0x001110, 0x00, TRUE, FALSE, 0, 0, -7 }, + { "Dull", PL_NDAHT, 25, 45, 1, 0x001110, 0x00, TRUE, FALSE, 0, 0, -5 }, + { "Sharp", PL_DAHT, 20, 35, 1, 0x001110, 0x00, TRUE, FALSE, 350, 950, 5 }, + { "Fine", PL_DAHT, 36, 50, 6, 0x001110, 0x00, TRUE, TRUE, 1100, 1700, 7 }, + { "Warrior's", PL_DAHT, 51, 65, 10, 0x001110, 0x00, TRUE, TRUE, 1850, 2450, 13 }, + { "Soldier's", PL_DAHT, 66, 80, 15, 0x001100, 0x00, TRUE, TRUE, 2600, 3950, 17 }, + { "Lord's", PL_DAHT, 81, 95, 19, 0x001100, 0x00, TRUE, TRUE, 4100, 5950, 21 }, + { "Knight's", PL_DAHT, 96, 110, 23, 0x001100, 0x00, TRUE, TRUE, 6100, 8450, 26 }, + { "Master's", PL_DAHT, 111, 125, 28, 0x001100, 0x00, TRUE, TRUE, 8600, 13000, 30 }, + { "Champion's", PL_DAHT, 126, 150, 40, 0x001100, 0x00, TRUE, TRUE, 15200, 24000, 33 }, + { "King's", PL_DAHT, 151, 175, 28, 0x001100, 0x00, TRUE, TRUE, 24100, 35000, 38 }, + + { "Vulnerable", PL_NAC, 51, 100, 3, 0x110000, 0x00, TRUE, FALSE, 0, 0, -3 }, + { "Rusted", PL_NAC, 25, 50, 1, 0x110000, 0x00, TRUE, FALSE, 0, 0, -2 }, + { "Fine", PL_AC, 20, 30, 1, 0x110000, 0x00, TRUE, TRUE, 20, 100, 2 }, + { "Strong", PL_AC, 31, 40, 3, 0x110000, 0x00, TRUE, TRUE, 120, 200, 3 }, + { "Grand", PL_AC, 41, 55, 6, 0x110000, 0x00, TRUE, TRUE, 220, 300, 5 }, + { "Valiant", PL_AC, 56, 70, 10, 0x110000, 0x00, TRUE, TRUE, 320, 400, 7 }, + { "Glorious", PL_AC, 71, 90, 14, 0x110000, 0x10, TRUE, TRUE, 420, 600, 9 }, + { "Blessed", PL_AC, 91, 110, 19, 0x110000, 0x10, TRUE, TRUE, 620, 800, 11 }, + { "Saintly", PL_AC, 111, 130, 24, 0x110000, 0x10, TRUE, TRUE, 820, 1200, 13 }, + { "Awesome", PL_AC, 131, 150, 28, 0x110000, 0x10, TRUE, TRUE, 1220, 2000, 15 }, + { "Holy", PL_AC, 151, 170, 35, 0x110000, 0x10, TRUE, TRUE, 5200, 6000, 17 }, + { "Godly", PL_AC, 171, 200, 60, 0x110000, 0x10, TRUE, TRUE, 6200, 7000, 20 }, + + { "Red", PL_RFIRE, 10, 20, 4, 0x111111, 0x00, FALSE, TRUE, 500, 1500, 2 }, + { "Crimson", PL_RFIRE, 21, 30, 10, 0x111111, 0x00, FALSE, TRUE, 2100, 3000, 2 }, + { "Crimson", PL_RFIRE, 31, 40, 16, 0x111111, 0x00, FALSE, TRUE, 3100, 4000, 2 }, + { "Garnet", PL_RFIRE, 41, 50, 20, 0x111111, 0x00, FALSE, TRUE, 8200, 12000, 3 }, + { "Ruby", PL_RFIRE, 51, 60, 26, 0x111111, 0x00, FALSE, TRUE, 17100, 20000, 5 }, + { "Blue", PL_RLGHT, 10, 20, 4, 0x111111, 0x00, FALSE, TRUE, 500, 1500, 2 }, + { "Azure", PL_RLGHT, 21, 30, 10, 0x111111, 0x00, FALSE, TRUE, 2100, 3000, 2 }, + { "Lapis", PL_RLGHT, 31, 40, 16, 0x111111, 0x00, FALSE, TRUE, 3100, 4000, 2 }, + { "Cobalt", PL_RLGHT, 41, 50, 20, 0x111111, 0x00, FALSE, TRUE, 8200, 12000, 3 }, + { "Sapphire", PL_RLGHT, 51, 60, 26, 0x111111, 0x00, FALSE, TRUE, 17100, 20000, 5 }, + { "White", PL_RMAG, 10, 20, 4, 0x111111, 0x00, FALSE, TRUE, 500, 1500, 2 }, + { "Pearl", PL_RMAG, 21, 30, 10, 0x111111, 0x00, FALSE, TRUE, 2100, 3000, 2 }, + { "Ivory", PL_RMAG, 31, 40, 16, 0x111111, 0x00, FALSE, TRUE, 3100, 4000, 2 }, + { "Crystal", PL_RMAG, 41, 50, 20, 0x111111, 0x00, FALSE, TRUE, 8200, 12000, 3 }, + { "Diamond", PL_RMAG, 51, 60, 26, 0x111111, 0x00, FALSE, TRUE, 17100, 20000, 5 }, + { "Topaz", PL_RALL, 10, 15, 8, 0x111111, 0x00, FALSE, TRUE, 2000, 5000, 3 }, + { "Amber", PL_RALL, 16, 20, 12, 0x111111, 0x00, FALSE, TRUE, 7400, 10000, 3 }, + { "Jade", PL_RALL, 21, 30, 18, 0x111111, 0x00, FALSE, TRUE, 11000, 15000, 3 }, + { "Obsidian", PL_RALL, 31, 40, 24, 0x111111, 0x00, FALSE, TRUE, 24000, 40000, 4 }, + { "Emerald", PL_RALL, 41, 50, 31, 0x011110, 0x00, FALSE, TRUE, 61000, 75000, 7 }, + + { "Hyena's", PL_NMANA, 11, 25, 4, 0x000101, 0x00, FALSE, FALSE, 100, 1000, -2 }, + { "Frog's", PL_NMANA, 1, 10, 1, 0x000101, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "Spider's", PL_MANA, 10, 15, 1, 0x000101, 0x01, FALSE, TRUE, 500, 1000, 2 }, + { "Raven's", PL_MANA, 15, 20, 5, 0x000101, 0x00, FALSE, TRUE, 1100, 2000, 3 }, + { "Snake's", PL_MANA, 21, 30, 9, 0x000101, 0x00, FALSE, TRUE, 2100, 4000, 5 }, + { "Serpent's", PL_MANA, 30, 40, 15, 0x000101, 0x00, FALSE, TRUE, 4100, 6000, 7 }, + { "Drake's", PL_MANA, 41, 50, 21, 0x000101, 0x00, FALSE, TRUE, 6100, 10000, 9 }, + { "Dragon's", PL_MANA, 51, 60, 27, 0x000101, 0x00, FALSE, TRUE, 10100, 15000, 11 }, + { "Wyrm's", PL_MANA, 61, 80, 35, 0x000100, 0x00, FALSE, TRUE, 15100, 19000, 12 }, + { "Hydra's", PL_MANA, 81, 100, 60, 0x000100, 0x00, FALSE, TRUE, 19100, 30000, 13 }, + + { "Angel's", PL_SLVL, 1, 1, 15, 0x000100, 0x10, FALSE, TRUE, 25000, 25000, 2 }, + { "Arch-Angel's", PL_SLVL, 2, 2, 25, 0x000100, 0x10, FALSE, TRUE, 50000, 50000, 3 }, + { "Plentiful", PL_CHRG, 2, 2, 4, 0x000100, 0x00, FALSE, TRUE, 2000, 2000, 2 }, + { "Bountiful", PL_CHRG, 3, 3, 9, 0x000100, 0x00, FALSE, TRUE, 3000, 3000, 3 }, + +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) + { "Flaming", PL_FHIT, 1, 10, 7, 0x001100, 0x00, FALSE, TRUE, 5000, 5000, 2 }, + { "Lightning", PL_LHIT, 2, 20, 18, 0x001100, 0x00, FALSE, TRUE, 10000, 10000, 2 }, +#endif + + { "Jester's", PL_RNDDAM, 1, 1, 7, 0x001000, 0x00, FALSE, TRUE, 1200, 1200, 3 }, + { "Crystalline", PL_FRAGILE, 30, 70, 5, 0x001000, 0x00, FALSE, TRUE, 1000, 3000, 3 }, + { "Doppelganger's", PL_DOPPEL, 81, 95, 11, 0x001100, 0x00, FALSE, TRUE, 2000, 2400, 10}, + + + { "", -1, 0, 0, 0, 0, 0, FALSE, 0, 0 } // Stopper +}; + +// Suffix, Power, min, max, level, armor/shield/weapon/staff/bow/ring, good(10)/evil(01)/either(00), Double +const PLStruct PL_Suffix[] = { + { "quality", PL_DAMADD, 1, 2, 2, 0x001110, 0x00, FALSE, TRUE, 100, 200, 2 }, + { "maiming", PL_DAMADD, 3, 5, 7, 0x001110, 0x00, FALSE, TRUE, 1300, 1500, 3 }, + { "slaying", PL_DAMADD, 6, 8, 15, 0x001000, 0x00, FALSE, TRUE, 2600, 3000, 5 }, + { "gore", PL_DAMADD, 9, 12, 25, 0x001000, 0x00, FALSE, TRUE, 4100, 5000, 8 }, + { "carnage", PL_DAMADD, 13, 16, 35, 0x001000, 0x00, FALSE, TRUE, 5100, 10000, 10 }, + { "slaughter", PL_DAMADD, 17, 20, 60, 0x001000, 0x00, FALSE, TRUE, 10100, 15000, 13 }, + + { "pain", PL_GETHIT, 2, 4, 4, 0x110001, 0x01, FALSE, FALSE, 0, 0, -4 }, + { "tears", PL_GETHIT, 1, 1, 2, 0x110001, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "health", PL_NGETHIT, 1, 1, 2, 0x110001, 0x10, FALSE, TRUE, 200, 200, 2 }, + { "protection", PL_NGETHIT, 2, 2, 6, 0x110000, 0x10, FALSE, TRUE, 400, 800, 4 }, + { "absorption", PL_NGETHIT, 3, 3, 12, 0x110000, 0x10, FALSE, TRUE, 1001, 2500, 10 }, + { "deflection", PL_NGETHIT, 4, 4, 20, 0x100000, 0x10, FALSE, TRUE, 2500, 6500, 15 }, + { "osmosis", PL_NGETHIT, 5, 6, 50, 0x100000, 0x10, FALSE, TRUE, 7500, 10000, 20 }, + + { "frailty", PL_NSTR, 6, 10, 3, 0x111011, 0x01, FALSE, FALSE, 0, 0, -3 }, + { "weakness", PL_NSTR, 1, 5, 1, 0x111111, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "strength", PL_STR, 1, 5, 1, 0x111111, 0x00, FALSE, TRUE, 200, 1000, 2 }, + { "might", PL_STR, 6, 10, 5, 0x111011, 0x00, FALSE, TRUE, 1200, 2000, 3 }, + { "power", PL_STR, 11, 15, 11, 0x111011, 0x00, FALSE, TRUE, 2200, 3000, 4 }, + { "giants", PL_STR, 16, 20, 17, 0x101011, 0x00, FALSE, TRUE, 3200, 5000, 7 }, + { "titans", PL_STR, 21, 30, 23, 0x001001, 0x00, FALSE, TRUE, 5200, 10000, 10 }, + + { "paralysis", PL_NDEX, 6, 10, 3, 0x111011, 0x01, FALSE, FALSE, 0,0, -3 }, + { "atrophy", PL_NDEX, 1, 5, 1, 0x111111, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "dexterity", PL_DEX, 1, 5, 1, 0x111111, 0x00, FALSE, TRUE, 200, 1000, 2 }, + { "skill", PL_DEX, 6, 10, 5, 0x111011, 0x00, FALSE, TRUE, 1200, 2000, 3 }, + { "accuracy", PL_DEX, 11, 15, 11, 0x111011, 0x00, FALSE, TRUE, 2200, 3000, 4 }, + { "precision", PL_DEX, 16, 20, 17, 0x101011, 0x00, FALSE, TRUE, 3200, 5000, 7 }, + { "perfection", PL_DEX, 21, 30, 23, 0x000011, 0x00, FALSE, TRUE, 5200, 10000, 10 }, + + { "the fool", PL_NMAG, 6, 10, 3, 0x111111, 0x01, FALSE, FALSE, 0, 0, -3 }, + { "dyslexia", PL_NMAG, 1, 5, 1, 0x111111, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "magic", PL_MAG, 1, 5, 1, 0x111111, 0x00, FALSE, TRUE, 200, 1000, 2 }, + { "the mind", PL_MAG, 6, 10, 5, 0x111111, 0x00, FALSE, TRUE, 1200, 2000, 3 }, + { "brilliance", PL_MAG, 11, 15, 11, 0x111111, 0x00, FALSE, TRUE, 2200, 3000, 4 }, + { "sorcery", PL_MAG, 16, 20, 17, 0x101111, 0x00, FALSE, TRUE, 3200, 5000, 7 }, + { "wizardry", PL_MAG, 21, 30, 23, 0x000101, 0x00, FALSE, TRUE, 5200, 10000, 10 }, + + { "illness", PL_NVIT, 6, 10, 3, 0x111111, 0x01, FALSE, FALSE, 0, 0, -3 }, + { "disease", PL_NVIT, 1, 5, 1, 0x111111, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "vitality", PL_VIT, 1, 5, 1, 0x111111, 0x10, FALSE, TRUE, 200, 1000, 2 }, + { "zest", PL_VIT, 6, 10, 5, 0x111011, 0x10, FALSE, TRUE, 1200, 2000, 3 }, + { "vim", PL_VIT, 11, 15, 11, 0x111011, 0x10, FALSE, TRUE, 2200, 3000, 4 }, + { "vigor", PL_VIT, 16, 20, 17, 0x101011, 0x10, FALSE, TRUE, 3200, 5000, 7 }, + { "life", PL_VIT, 21, 30, 23, 0x000001, 0x10, FALSE, TRUE, 5200, 10000, 10 }, + + { "trouble", PL_NSTATS, 6, 10, 12, 0x111111, 0x01, FALSE, FALSE, 0, 0, -10 }, + { "the pit", PL_NSTATS, 1, 5, 5, 0x111111, 0x01, FALSE, FALSE, 0, 0, -5 }, + { "the sky", PL_STATS, 1, 3, 5, 0x111111, 0x00, FALSE, TRUE, 800, 4000, 5 }, + { "the moon", PL_STATS, 4, 7, 11, 0x111111, 0x00, FALSE, TRUE, 4800, 8000, 10 }, + { "the stars", PL_STATS, 8, 11, 17, 0x101011, 0x00, FALSE, TRUE, 8800, 12000, 15 }, + { "the heavens", PL_STATS, 12, 15, 25, 0x001011, 0x00, FALSE, TRUE, 12800, 20000, 20 }, + { "the zodiac", PL_STATS, 16, 20, 30, 0x000001, 0x00, FALSE, TRUE, 20800, 40000, 30 }, + + { "the vulture", PL_NHP, 11, 25, 4, 0x110001, 0x01, FALSE, FALSE, 0, 0, -4 }, + { "the jackal", PL_NHP, 1, 10, 1, 0x110001, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "the fox", PL_HP, 10, 15, 1, 0x110001, 0x00, FALSE, TRUE, 100, 1000, 2 }, + { "the jaguar", PL_HP, 16, 20, 5, 0x110001, 0x00, FALSE, TRUE, 1100, 2000, 3 }, + { "the eagle", PL_HP, 21, 30, 9, 0x110001, 0x00, FALSE, TRUE, 2100, 4000, 5 }, + { "the wolf", PL_HP, 30, 40, 15, 0x110001, 0x00, FALSE, TRUE, 4100, 6000, 7 }, + { "the tiger", PL_HP, 41, 50, 21, 0x110001, 0x00, FALSE, TRUE, 6100, 10000, 9 }, + { "the lion", PL_HP, 51, 60, 27, 0x100001, 0x00, FALSE, TRUE, 10100, 15000, 11 }, + { "the mammoth", PL_HP, 61, 80, 35, 0x100000, 0x00, FALSE, TRUE, 15100, 19000, 12 }, + { "the whale", PL_HP, 81, 100, 60, 0x100000, 0x00, FALSE, TRUE, 19100, 30000, 13 }, + + { "fragility", PL_NDUR, 100, 100, 3, 0x111000, 0x01, FALSE, FALSE, 0, 0, -4 }, + { "brittleness", PL_NDUR, 26, 75, 1, 0x111000, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "sturdiness", PL_DUR, 26, 75, 1, 0x111100, 0x00, FALSE, TRUE, 100, 100, 2 }, + { "craftsmanship", PL_DUR, 51, 100, 6, 0x111100, 0x00, FALSE, TRUE, 200, 200, 2 }, + { "structure", PL_DUR, 101, 200, 12, 0x111100, 0x00, FALSE, TRUE, 300, 300, 2 }, + { "the ages", PL_IND, 0, 0, 25, 0x111100, 0x00, FALSE, TRUE, 600, 600, 5 }, + + { "the dark", PL_NLIGHT, 4, 4, 6, 0x101001, 0x01, FALSE, FALSE, 0, 0, -3 }, + { "the night", PL_NLIGHT, 2, 2, 3, 0x101001, 0x01, FALSE, FALSE, 0, 0, -2 }, + { "light", PL_LIGHT, 2, 2, 4, 0x101001, 0x10, FALSE, TRUE, 750, 750, 2 }, + { "radiance", PL_LIGHT, 4, 4, 8, 0x101001, 0x10, FALSE, TRUE, 1500, 1500, 3 }, + + { "flame", PL_FARROW, 1, 3, 1, 0x000010, 0x00, FALSE, TRUE, 2000, 2000, 2 }, + { "fire", PL_FARROW, 1, 6, 11, 0x000010, 0x00, FALSE, TRUE, 4000, 4000, 4 }, + { "burning", PL_FARROW, 1, 16, 35, 0x000010, 0x00, FALSE, TRUE, 6000, 6000, 6 }, +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) + { "shock", PL_LARROW, 1, 6, 13, 0x000010, 0x00, FALSE, TRUE, 6000, 6000, 2 }, + { "lightning", PL_LARROW, 1, 10, 21, 0x000010, 0x00, FALSE, TRUE, 8000, 8000, 4 }, + { "thunder", PL_LARROW, 1, 20, 60, 0x000010, 0x00, FALSE, TRUE, 12000, 12000, 6 }, +#endif + { "many", PL_DUR, 100, 100, 3, 0x000010, 0x00, FALSE, TRUE, 750, 750, 2 }, + { "plenty", PL_DUR, 200, 200, 7, 0x000010, 0x00, FALSE, TRUE, 1500, 1500, 3 }, + +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) + { "thorns", PL_THORN, 1, 3, 1, 0x110000, 0x00, FALSE, TRUE, 500, 500, 2 }, + { "corruption", PL_LMANA, 0, 0, 5, 0x111000, 0x01, FALSE, FALSE, -1000, -1000, 2 }, + + { "thieves", PL_TRAPDAM, 0, 0, 11, 0x110001, 0x00, FALSE, TRUE, 1500, 1500, 2 }, + { "the bear", PL_BEAR, 0, 0, 5, 0x001110, 0x01, FALSE, TRUE, 750, 750, 2 }, + + { "the bat", PL_BAT, 3, 3, 8, 0x001000, 0x00, FALSE, TRUE, 7500, 7500, 3 }, + { "vampires", PL_BAT, 5, 5, 19, 0x001000, 0x00, FALSE, TRUE, 15000, 15000, 3 }, + { "the leech", PL_LEECH, 3, 3, 8, 0x001000, 0x00, FALSE, TRUE, 7500, 7500, 3 }, + { "blood", PL_LEECH, 5, 5, 19, 0x001000, 0x00, FALSE, TRUE, 15000, 15000, 3 }, + + { "piercing", PL_ENAC, 1, 1, 1, 0x001010, 0x00, FALSE, TRUE, 1000, 1000, 3 }, + { "puncturing", PL_ENAC, 2, 2, 9, 0x001010, 0x00, FALSE, TRUE, 2000, 2000, 6 }, + { "bashing", PL_ENAC, 3, 3, 17, 0x001000, 0x00, FALSE, TRUE, 4000, 4000, 12 }, + + { "readiness", PL_ATANIM, 1, 1, 1, 0x001110, 0x00, FALSE, TRUE, 2000, 2000, 2 }, + { "swiftness", PL_ATANIM, 2, 2, 10, 0x001110, 0x00, FALSE, TRUE, 4000, 4000, 4 }, + { "speed", PL_ATANIM, 3, 3, 19, 0x001100, 0x00, FALSE, TRUE, 8000, 8000, 8 }, + { "haste", PL_ATANIM, 4, 4, 27, 0x001100, 0x00, FALSE, TRUE, 16000, 16000, 16 }, + { "balance", PL_HTANIM, 1, 1, 1, 0x100001, 0x00, FALSE, TRUE, 2000, 2000, 2 }, + { "stability", PL_HTANIM, 2, 2, 10, 0x100001, 0x00, FALSE, TRUE, 4000, 4000, 4 }, + { "harmony", PL_HTANIM, 3, 3, 20, 0x100001, 0x00, FALSE, TRUE, 8000, 8000, 8 }, + + { "blocking", PL_BLANIM, 1, 1, 5, 0x010000, 0x00, FALSE, TRUE, 4000, 4000, 4 }, + + { "devastation", PL_DEVAST, 1, 1, 1, 0x001110, 0x00, FALSE, TRUE, 1200, 1200, 3 }, + { "decay", PL_DECAY, 150, 250, 1, 0x001110, 0x00, FALSE, TRUE, 200, 200, 2 }, + { "peril", PL_PERIL, 1, 1, 5, 0x001110, 0x00, FALSE, TRUE, 500, 500, 1 }, + +#endif + + { "", -1, 0, 0, 0, 0, 0, FALSE, FALSE, 0, 0 } // Stopper +}; + +/*-----------------------------------------------------------------------* +** Unique items list +**-----------------------------------------------------------------------*/ + +// Item name, item id, level, number of Powers, value, avail for shareware +// Power, param1, param2 +const UItemStruct UniqueItemList[] = { + + // This must go at the beginning of the list because so the butcher can give it out + { "The Butcher's Cleaver", ITEMID_CLEAVER, 1, 3, 3650, + PL_STR, 10, 10, + PL_DAMAGE, 4, 24, + PL_DURNUM, 10, 10, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "The Undead Crown", ITEMID_SKCROWN, 1, 3, 16650, + PL_SKING, 0, 0, + PL_ACTUALAC, 8, 8, + PL_GFX, ITEM_CROWN, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Empyrean Band", ITEMID_IRING, 1, 4, 8000, + PL_STATS, 2, 2, + PL_LIGHT, 2, 2, + PL_HTANIM, 1, 1, + PL_TRAPDAM, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Optic Amulet", ITEMID_OPTAMULET, 1, 5, 9750, + PL_LIGHT, 2, 2, + PL_RLGHT, 20, 20, + PL_NGETHIT, 1, 1, + PL_MAG, 5, 5, + PL_GFX, ITEM_AMULET, 0, + 0, 0, 0 + }, + + { "Ring of Truth", ITEMID_TRING, 1, 4, 9100, + PL_HP, 10, 10, + PL_NGETHIT, 1, 1, + PL_RALL, 10, 10, + PL_GFX, ITEM_BLUERING, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Harlequin Crest", ITEMID_HALCREST, 1, 6, 4000, + PL_NACTULAC, 3, 3, + PL_NGETHIT, 1, 1, + PL_STATS, 2, 2, + PL_HP, 7, 7, + PL_MANA, 7, 7, + PL_GFX, ITEM_HARLEQ, 0, + }, + { "Veil of Steel", ITEMID_STEELVEIL, 1, 6, 63800, + PL_RALL, 50, 50, + PL_NLIGHT, 2, 2, + PL_AC, 60, 60, + PL_NMANA, 30, 30, + PL_STR, 15, 15, + PL_VIT, 15, 15 + }, + { "Arkaine's Valor", ITEMID_ARMOFVAL, 1, 4, 42000, + PL_ACTUALAC, 25, 25, + PL_VIT, 10, 10, + PL_NGETHIT, 3, 3, + PL_HTANIM, 3, 3, + 0, 0, 0, + 0, 0, 0 + }, + { "Griswold's Edge", ITEMID_GRISWOLD, 1, 6, 42000, + PL_FHIT, 1, 10, + PL_TOHIT, 25, 25, + PL_ATANIM, 2, 2, + PL_BEAR, 0, 0, + PL_MANA, 20, 20, + PL_NHP, 20, 20 + }, + { "Bovine Plate", ITEMID_ARMRCOW, 1, 6, 400, + PL_ACTUALAC, 150, 150, + PL_IND, 0, 0, + PL_LIGHT, 5, 5, + PL_RALL, 30, 30, + PL_NMANA, 50, 50, + PL_SLVL, -2, -2, + }, +#if 0 + { "Lightforge", ITEMID_MACE, 1, 6, 26675, + PL_LIGHT, 4, 4, + PL_TODAM, 150, 150, + PL_TOHIT, 25, 25, + PL_FHIT, 10, 20, + PL_IND, 0, 0, + PL_STATS, 8, 8 + }, +#endif + /* + { "Azurewrath", ITEMID_BASTSWORD, 1, 5, 66500, + PL_DAMDEMON, 200, 200, + PL_TOHIT, 40, 40, + PL_LHIT, 10, 20, + PL_STR, 15, 15, + PL_RMAG, 100, 100, + 0, 0, 0 + }, + { "Blackest Blade", ITEMID_SCIMITAR, 1, 5, 23667, + PL_MANA, 50, 50, + PL_RALL, 25, 25, + PL_TOHIT, 20, 20, + PL_TODAM, 100, 100, + PL_CONST, 0, 0, + 0, 0, 0 + }, + { "Codex of Enlightenment", ITEMID_BOOK, 1, 4, 5000, + PL_X, 0, 0, + PL_X, 0, 0, + PL_X, 0, 0, + PL_GFX, ITEM_BOOK3, 0, + 0, 0, 0, + 0, 0, 0 + }, +*/ + // From here down are random unique items + // Bow + { "The Rift Bow", ITEMID_SHORTBOW, 1, 3, 1800, + PL_RNDARW, 0, 0, + PL_DAMADD, 2, 2, + PL_NDEX, 3, 3, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "The Needler", ITEMID_SHORTBOW, 2, 4, 8900, + PL_TOHIT, 50, 50, + PL_DAMAGE, 1, 3, + PL_ATANIM, 2, 2, + PL_GFX, ITEM_CROSBOW, 0, + 0, 0, 0, + 0, 0, 0 + }, + +#if IS_VERSION(RETAIL) || IS_VERSION(BETA) + { "The Celestial Bow", ITEMID_LONGBOW, 2, 4, 1200, + PL_NSTRREQ, 0, 0, + PL_DAMADD, 2, 2, + PL_ACTUALAC, 5, 5, + PL_GFX, ITEM_HNTRBOW, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Deadly Hunter", ITEMID_COMPBOW, 3, 4, 8750, + PL_DAMDEMON, 10, 10, + PL_TOHIT, 20, 20, + PL_NMAG, 5, 5, + PL_GFX, ITEM_COMPBOW, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Bow of the Dead", ITEMID_COMPBOW, 5, 6, 2500, + PL_TOHIT, 10, 10, + PL_DEX, 4, 4, + PL_NVIT, 3, 3, + PL_NLIGHT, 2, 2, + PL_DURNUM, 30, 30, + PL_GFX, ITEM_COMPBOW, 0 + }, +#endif + + { "The Blackoak Bow", ITEMID_LONGBOW, 5, 4, 2500, + PL_DEX, 10, 10, + PL_NVIT, 10, 10, + PL_TODAM, 50, 50, + PL_NLIGHT, 1, 1, + 0, 0, 0, + 0, 0, 0 + }, + +#if IS_VERSION(RETAIL) + { "Flamedart", ITEMID_BOW, 10, 4, 14250, + PL_FARROW, 0, 0, + PL_FHIT, 1, 6, + PL_TOHIT, 20, 20, + PL_RFIRE, 40, 40, + 0, 0, 0, + 0, 0, 0 + }, + { "Fleshstinger", ITEMID_LONGBOW, 13, 4, 16500, + PL_DEX, 15, 15, + PL_TOHIT, 40, 40, + PL_TODAM, 80, 80, + PL_DUR, 6, 6, + 0, 0, 0, + 0, 0, 0 + }, + { "Windforce", ITEMID_LWARBOW, 17, 4, 37750, + PL_STR, 5, 5, + PL_TODAM, 200, 200, + PL_BEAR, 0, 0, + PL_GFX, ITEM_WINDFOR, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Eaglehorn", ITEMID_LBATTLEBOW, 26, 5, 42500, + PL_DEX, 20, 20, + PL_TOHIT, 50, 50, + PL_TODAM, 100, 100, + PL_IND, 0, 0, + PL_GFX, ITEM_COMPBOW, 0, + 0, 0, 0 + }, + + // Sword + { "Gonnagal's Dirk", ITEMID_DAGGER, 1, 5, 7040, + PL_NDEX, 5, 5, + PL_DAMADD, 4, 4, + PL_ATANIM, 2, 2, + PL_RFIRE, 25, 25, + PL_GFX, ITEM_DAGGER4, 0, + 0, 0, 0 + }, + { "The Defender", ITEMID_SABRE, 1, 3, 2000, + PL_ACTUALAC, 5, 5, + PL_VIT, 5, 5, + PL_NTOHIT, 5, 5, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Gryphons Claw", ITEMID_FALCHION, 1, 4, 1000, + PL_TODAM, 100, 100, + PL_NMAG, 2, 2, + PL_NDEX, 5, 5, + PL_GFX, ITEM_KNTSWORD, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Black Razor", ITEMID_DAGGER, 1, 4, 2000, + PL_TODAM, 150, 150, + PL_VIT, 2, 2, + PL_DURNUM, 5, 5, + PL_GFX, ITEM_DAGGER3, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Gibbous Moon", ITEMID_BROADSWORD, 2, 4, 6660, + PL_STATS, 2, 2, + PL_TODAM, 25, 25, + PL_MANA, 15, 15, + PL_NLIGHT, 3, 3, + 0, 0, 0, + 0, 0, 0 + }, + { "Ice Shank", ITEMID_LONGSWORD, 3, 3, 5250, + PL_RFIRE, 40, 40, + PL_DURNUM, 15, 15, + PL_STR, 5, 10, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "The Executioner's Blade", ITEMID_FALCHION, 3, 5, 7080, + PL_TODAM, 150, 150, + PL_NHP, 10, 10, + PL_NLIGHT, 1, 1, + PL_DUR, 200, 200, + PL_GFX, ITEM_FALCHION, 0, + 0, 0, 0 + }, + { "The Bonesaw", ITEMID_CLAYMORE, 6, 6, 4400, + PL_DAMADD, 10, 10, + PL_STR, 10, 10, + PL_NMAG, 5, 5, + PL_NDEX, 5, 5, + PL_HP, 10, 10, + PL_NMANA, 10, 10 + }, + { "Shadowhawk", ITEMID_BROADSWORD, 8, 4, 13750, + PL_NLIGHT, 2, 2, + PL_LEECH, 5, 5, + PL_TOHIT, 15, 15, + PL_RALL, 5, 5, + 0, 0, 0, + 0, 0, 0 + }, + { "Wizardspike", ITEMID_DAGGER, 11, 5, 12920, + PL_MAG, 15, 15, + PL_MANA, 35, 35, + PL_TOHIT, 25, 25, + PL_RALL, 15, 15, + PL_GFX, ITEM_DAGGER1, 0, + 0, 0, 0 + }, + { "Lightsabre", ITEMID_SABRE, 13, 4, 19150, + PL_LIGHT, 2, 2, + PL_LHIT, 1, 10, + PL_TOHIT, 20, 20, + PL_RLGHT, 50, 50, + 0, 0, 0, + 0, 0, 0 + }, + { "The Falcon's Talon", ITEMID_SCIMITAR, 15, 5, 7867, + PL_ATANIM, 4, 4, + PL_TOHIT, 20, 20, + PL_NTODAM, 33, 33, + PL_DEX, 10, 10, + PL_GFX, ITEM_KNTSWORD, 0, + 0, 0, 0 + }, + { "Inferno", ITEMID_LONGSWORD, 17, 4, 34600, + PL_FHIT, 2, 12, + PL_LIGHT, 3, 3, + PL_MANA, 20, 20, + PL_RFIRE, 80, 80, + 0, 0, 0, + 0, 0, 0 + }, + { "Doombringer", ITEMID_BASTSWORD, 19, 5, 18250, + PL_TOHIT, 25, 25, + PL_TODAM, 250, 250, + PL_NSTATS, 5, 5, + PL_NHP, 25, 25, + PL_NLIGHT, 2, 2, + 0, 0, 0 + }, + { "The Grizzly", ITEMID_2HANDSWORD, 23, 6, 50000, + PL_STR, 20, 20, + PL_NVIT, 5, 5, + PL_TODAM, 200, 200, + PL_BEAR, 0, 0, + PL_DUR, 100, 100, + PL_GFX, ITEM_GRIZZLY, 0 + }, + { "The Grandfather", ITEMID_GREATSWORD, 27, 6, 119800, + PL_ONEHAND, 0, 0, + PL_STATS, 5, 5, + PL_TOHIT, 20, 20, + PL_TODAM, 70, 70, + PL_HP, 20, 20, + PL_GFX, ITEM_GRANDPA, 0 + }, + // Axe + { "The Mangler", ITEMID_LARGEAXE, 2, 5, 2850, + PL_TODAM, 200, 200, + PL_NDEX, 5, 5, + PL_NMAG, 5, 5, + PL_NMANA, 10, 10, + PL_GFX, ITEM_HANDAXE, 0, + 0, 0, 0 + }, + { "Sharp Beak", ITEMID_LARGEAXE, 2, 4, 2850, + PL_HP, 20, 20, + PL_NMAG, 10, 10, + PL_NMANA, 10, 10, + PL_GFX, ITEM_WICKAXE, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "BloodSlayer", ITEMID_BROADAXE, 3, 5, 2500, + PL_TODAM, 100, 100, + PL_DAMDEMON, 50, 50, + PL_NSTATS, 5, 5, + PL_SLVL, -1, -1, + PL_GFX, ITEM_HANDAXE, 0, + 0, 0, 0 + }, + { "The Celestial Axe", ITEMID_BATTLEAXE, 4, 4, 14100, + PL_NSTRREQ, 0, 0, + PL_TOHIT, 15, 15, + PL_HP, 15, 15, + PL_NSTR, 15, 15, + 0, 0, 0, + 0, 0, 0 + }, + { "Wicked Axe", ITEMID_LARGEAXE, 5, 6, 31150, + PL_TOHIT, 30, 30, + PL_DEX, 10, 10, + PL_NVIT, 10, 10, + PL_NGETHIT, 1, 6, + PL_IND, 0, 0, + PL_GFX, ITEM_WICKAXE, 0, + }, + { "Stonecleaver", ITEMID_BROADAXE, 7, 5, 23900, + PL_HP, 30, 30, + PL_TOHIT, 20, 20, + PL_TODAM, 50, 50, + PL_RLGHT, 40, 40, + PL_GFX, ITEM_AXE, 0, + 0, 0, 0 + }, + { "Aguinara's Hatchet", ITEMID_SMALLAXE, 12, 3, 24800, + PL_SLVL, 1, 1, + PL_MAG, 10, 10, + PL_RMAG, 80, 80, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Hellslayer", ITEMID_BATTLEAXE, 15, 5, 26200, + PL_STR, 8, 8, + PL_VIT, 8, 8, + PL_TODAM, 100, 100, + PL_HP, 25, 25, + PL_NMANA, 25, 25, + 0, 0, 0 + }, + { "Messerschmidt's Reaver", ITEMID_GREATAXE, 25, 6, 58000, + PL_TODAM, 200, 200, + PL_DAMADD, 15, 15, + PL_STATS, 5, 5, + PL_NHP, 50, 50, + PL_FHIT, 2, 12, + PL_GFX, ITEM_REAVER, 0 + }, + // Mace + + { "Crackrust", ITEMID_MACE, 1, 5, 11375, + PL_STATS, 2, 2, + PL_IND, 0, 0, + PL_RALL, 15, 15, + PL_TODAM, 50, 50, + PL_SLVL, -1, -1, + 0, 0, 0 + }, + { "Hammer of Jholm", ITEMID_MAUL, 1, 4, 8700, + PL_TODAM, 4, 10, + PL_IND, 0, 0, + PL_STR, 3, 3, + PL_TOHIT, 15, 15, + 0, 0, 0, + 0, 0, 0 + }, + { "Civerb's Cudgel", ITEMID_MACE, 1, 3, 2000, + PL_DAMDEMON, 35, 35, + PL_NDEX, 5, 5, + PL_NMAG, 2, 2, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "The Celestial Star", ITEMID_FLAIL, 2, 5, 7810, + PL_NSTRREQ, 0, 0, + PL_LIGHT, 2, 2, + PL_DAMADD, 10, 10, + PL_NACTULAC, 8, 8, + PL_GFX, ITEM_FLAIL, 0, + 0, 0, 0 + }, + { "Baranar's Star", ITEMID_MORNSTAR, 5, 6, 6850, + PL_TOHIT, 12, 12, + PL_TODAM, 80, 80, + PL_ATANIM, 1, 1, + PL_VIT, 4, 4, + PL_NDEX, 4, 4, + PL_DURNUM, 60, 60 + }, + { "Gnarled Root", ITEMID_CLUB, 9, 6, 9820, + PL_TOHIT, 20, 20, + PL_TODAM, 300, 300, + PL_DEX, 10, 10, + PL_MAG, 5, 5, + PL_RALL, 10, 10, + PL_NACTULAC, 10, 10 + }, + { "The Cranium Basher", ITEMID_MAUL, 12, 6, 36500, + PL_DAMADD, 20, 20, + PL_STR, 15, 15, + PL_IND, 0, 0, + PL_NMANA, 150, 150, + PL_RALL, 5, 5, + PL_GFX, ITEM_MAUL, 0 + }, + { "Schaefer's Hammer", ITEMID_WARHAMMER, 16, 6, 56125, + PL_NTODAM, 100, 100, + PL_LHIT, 1, 50, + PL_HP, 50, 50, + PL_TOHIT, 30, 30, + PL_RLGHT, 80, 80, + PL_LIGHT, 1, 1 + }, + { "Dreamflange", ITEMID_MACE, 26, 5, 26450, + PL_MAG, 30, 30, + PL_MANA, 50, 50, + PL_RMAG, 50, 50, + PL_LIGHT, 2, 2, + PL_SLVL, 1, 1, + 0, 0, 0 + }, + // Staff + { "Staff of Shadows", ITEMID_LONGSTAFF, 2, 5, 1250, + PL_NMAG, 10, 10, + PL_TOHIT, 10, 10, + PL_TODAM, 60, 60, + PL_NLIGHT, 2, 2, + PL_ATANIM, 1, 1, + 0, 0, 0 + }, + { "Immolator", ITEMID_LONGSTAFF, 4, 4, 3900, + PL_RFIRE, 20, 20, + PL_FHIT, 4, 4, + PL_MANA, 10, 10, + PL_NVIT, 5, 5, + 0, 0, 0, + 0, 0, 0 + }, + { "Storm Spire", ITEMID_WARSTAFF, 8, 4, 22500, + PL_RLGHT, 50, 50, + PL_LHIT, 2, 8, + PL_STR, 10, 10, + PL_NMAG, 10, 10, + 0, 0, 0, + 0, 0, 0 + }, + { "Gleamsong", ITEMID_SHORTSTAFF, 8, 4, 6520, + PL_MANA, 25, 25, + PL_NSTR, 3, 3, + PL_NVIT, 3, 3, + PL_SPELL, SPL_PHASE, 76, + 0, 0, 0, + 0, 0, 0 + }, + { "Thundercall", ITEMID_COMPSTAFF, 14, 5, 22250, + PL_TOHIT, 35, 35, + PL_LHIT, 1, 10, + PL_SPELL, SPL_LIGHTNING, 76, + PL_RLGHT, 30, 30, + PL_LIGHT, 2, 2, + 0, 0, 0 + }, + { "The Protector", ITEMID_SHORTSTAFF, 16, 6, 17240, + PL_VIT, 5, 5, + PL_NGETHIT, 5, 5, + PL_ACTUALAC, 40, 40, + PL_SPELL, SPL_HEAL, 86, + PL_THORN, 1, 3, + PL_GFX, ITEM_PROTECT, 0 + }, + { "Naj's Puzzler", ITEMID_LONGSTAFF, 18, 5, 34000, + PL_MAG, 20, 20, + PL_DEX, 10, 10, + PL_RALL, 20, 20, + PL_SPELL, SPL_TELE, 57, + PL_NHP, 25, 25, + 0, 0, 0 + }, + { "Mindcry", ITEMID_QTRSTAFF, 20, 4, 41500, + PL_MAG, 15, 15, + PL_SPELL, SPL_GUARDIAN, 69, + PL_RALL, 15, 15, + PL_SLVL, 1, 1, + 0, 0, 0, + 0, 0, 0 + }, + { "Rod of Onan", ITEMID_WARSTAFF, 22, 3, 44167, + PL_SPELL, SPL_GOLEM, 50, + PL_TODAM, 100, 100, + PL_STATS, 5, 5, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + + // Cap / Helmet + { "Helm of Sprits", ITEMID_HELM, 1, 2, 7525, + PL_LEECH, 5, 5, + PL_GFX, ITEM_CROWN, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Thinking Cap", ITEMID_SKULLCAP, 6, 5, 2020, + PL_MANA, 30, 30, + PL_SLVL, 2, 2, + PL_RALL, 20, 20, + PL_DURNUM, 1, 1, + PL_GFX, ITEM_SKLCAP2, 0, + 0, 0, 0 + }, + { "OverLord's Helm", ITEMID_HELM, 7, 6, 12500, + PL_STR, 20, 20, + PL_DEX, 15, 15, + PL_VIT, 5, 5, + PL_NMAG, 20, 20, + PL_DURNUM, 15, 15, + PL_GFX, ITEM_SAMHELM, 0 + }, + { "Fool's Crest", ITEMID_HELM, 12, 5, 10150, + PL_NSTATS, 4, 4, + PL_HP, 100, 100, + PL_GETHIT, 1, 6, + PL_THORN, 1, 3, + PL_GFX, ITEM_JESTER, 0, + 0, 0, 0 + }, + { "Gotterdamerung", ITEMID_GREATHELM, 21, 6, 54900, + PL_STATS, 20, 20, + PL_ACTUALAC, 60, 60, + PL_NGETHIT, 4, 4, + PL_ZERORES, 0, 0, + PL_NLIGHT, 4, 4, + PL_GFX, ITEM_GRTHELM, 0 + }, + { "Royal Circlet", ITEMID_CROWN, 27, 5, 24875, + PL_STATS, 10, 10, + PL_MANA, 40, 40, + PL_ACTUALAC, 40, 40, + PL_LIGHT, 1, 1, + PL_GFX, ITEM_MCROWN, 0, + 0, 0, 0 + }, + + // Armor + { "Torn Flesh of Souls", ITEMID_RAGS, 2, 5, 4825, + PL_ACTUALAC, 8, 8, + PL_VIT, 10, 10, + PL_NGETHIT, 1, 1, + PL_IND, 0, 0, + PL_GFX, ITEM_FLESH, 0, + 0, 0, 0 + }, + { "The Gladiator's Bane", ITEMID_STDLEATHER, 6, 4, 3450, + PL_ACTUALAC, 25, 25, + PL_NGETHIT, 2, 2, + PL_DUR, 200, 200, + PL_NSTATS, 3, 3, + 0, 0, 0, + 0, 0, 0 + }, + { "The Rainbow Cloak", ITEMID_CLOAK, 2, 6, 4900, + PL_ACTUALAC, 10, 10, + PL_STATS, 1, 1, + PL_RALL, 10, 10, + PL_HP, 5, 5, + PL_DUR, 50, 50, + PL_GFX, ITEM_HVYROBE, 0 + }, + { "Leather of Aut", ITEMID_LEATHER, 4, 5, 10550, + PL_ACTUALAC, 15, 15, + PL_STR, 5, 5, + PL_NMAG, 5, 5, + PL_DEX, 5, 5, + PL_IND, 0, 0, + 0, 0, 0 + }, + { "Wisdom's Wrap", ITEMID_ROBE, 5, 6, 6200, + PL_MAG, 5, 5, + PL_MANA, 10, 10, + PL_RLGHT, 25, 25, + PL_ACTUALAC, 15, 15, + PL_NGETHIT, 1, 1, + PL_GFX, ITEM_HVYROBE, 0 + }, + { "Sparking Mail", ITEMID_CHAINMAIL, 9, 2, 15750, + PL_ACTUALAC, 30, 30, + PL_LHIT, 1, 10, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Scavenger Carapace", ITEMID_BREASTPLATE, 13, 4, 14000, + PL_NGETHIT, 15, 15, + PL_NACTULAC, 30, 30, + PL_DEX, 5, 5, + PL_RLGHT, 40, 40, + 0, 0, 0, + 0, 0, 0 + }, + { "Nightscape", ITEMID_CAPE, 16, 6, 11600, + PL_HTANIM, 2, 2, + PL_NLIGHT, 4, 4, + PL_ACTUALAC, 15, 15, + PL_DEX, 3, 3, + PL_RALL, 20, 20, + PL_GFX, ITEM_HVYROBE, 0, + }, + { "Naj's Light Plate", ITEMID_PLATEMAIL, 19, 6, 78700, + PL_NSTRREQ, 0, 0, + PL_MAG, 5, 5, + PL_MANA, 20, 20, + PL_RALL, 20, 20, + PL_SLVL, 1, 1, + PL_GFX, ITEM_NAJARMOR, 0 + }, + { "Demonspike Coat", ITEMID_FULLPLATE, 25, 5, 251175, + PL_ACTUALAC, 100, 100, + PL_NGETHIT, 6, 6, + PL_STR, 10, 10, + PL_IND, 0, 0, + PL_RFIRE, 50, 50, + 0, 0, 0 + }, + // Shield + { "The Deflector", ITEMID_BUCKLER, 1, 5, 1500, + PL_ACTUALAC, 7, 7, + PL_RALL, 10, 10, + PL_NTODAM, 20, 20, + PL_NTOHIT, 5, 5, + PL_GFX, ITEM_BUCKLER, 0, + 0, 0, 0 + }, + { "Split Skull Shield", ITEMID_BUCKLER, 1, 6, 2025, + PL_ACTUALAC, 10, 10, + PL_HP, 10, 10, + PL_STR, 2, 2, + PL_NLIGHT, 1, 1, + PL_DURNUM, 15, 15, + PL_GFX, ITEM_SKULLSHLD, 0 + }, + { "Dragon's Breach", ITEMID_KITESHLD, 2, 6, 19200, + PL_RFIRE, 25, 25, + PL_STR, 5, 5, + PL_ACTUALAC, 20, 20, + PL_NMAG, 5, 5, + PL_IND, 0, 0, + PL_GFX, ITEM_WOLFSHLD, 0 + }, + { "Blackoak Shield", ITEMID_SMALLSHLD, 4, 6, 5725, + PL_DEX, 10, 10, + PL_NVIT, 10, 10, + PL_ACTUALAC, 18, 18, + PL_NLIGHT, 1, 1, + PL_DUR, 150, 150, + PL_GFX, ITEM_IRONSHLD, 0 + }, + { "Holy Defender", ITEMID_LARGESHLD, 10, 6, 13800, + PL_ACTUALAC, 15, 15, + PL_NGETHIT, 2, 2, + PL_RFIRE, 20, 20, + PL_DUR, 200, 200, + PL_BLANIM, 1, 1, + PL_GFX, ITEM_IRONSHLD, 0 + }, + { "Stormshield", ITEMID_TOWERSHLD, 24, 6, 49000, + PL_ACTUALAC, 40, 40, + PL_GETHIT, 4, 4, + PL_STR, 10, 10, + PL_IND, 0, 0, + PL_BLANIM, 1, 1, + PL_GFX, ITEM_LRGSHLD, 0 + }, + + // Ring + { "Bramble", ITEMID_RING, 1, 4, 1000, + PL_NSTATS, 2, 2, + PL_DAMADD, 3, 3, + PL_MANA, 10, 10, + PL_GFX, ITEM_WOODRING, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Ring of Regha", ITEMID_RING, 1, 6, 4175, + PL_MAG, 10, 10, + PL_RMAG, 10, 10, + PL_LIGHT, 1, 1, + PL_NSTR, 3, 3, + PL_NDEX, 3, 3, + PL_GFX, ITEM_3JRING, 0, + }, + { "The Bleeder", ITEMID_RING, 2, 4, 8500, + PL_RMAG, 20, 20, + PL_MANA, 30, 30, + PL_NHP, 10, 10, + PL_GFX, ITEM_1JRING, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Constricting Ring", ITEMID_RING, 5, 3, 62000, + PL_RALL, 75, 75, + PL_CONST, 0, 0, + PL_GFX, ITEM_BRNRING, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Ring of Engagement", ITEMID_RING, 11, 5, 12476, + PL_NGETHIT, 1, 2, + PL_THORN, 1, 3, + PL_ACTUALAC, 5, 5, + PL_ENAC, 4, 12, + PL_GFX, ITEM_MJRING, 0, + 0, 0, 0 + }, + // added 7/30/97 by donald + { "Giant's Knuckle", ITEMID_RING, 8, 3, 8000, + PL_STR, 60, 60, + PL_NDEX, 30, 30, + PL_GFX, ITEM_RINGGIANTS, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Mercurial Ring", ITEMID_RING, 8, 3, 8000, + PL_DEX, 60, 60, + PL_NSTR, 30, 30, + PL_GFX, ITEM_MERCRING, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Xorine's Ring", ITEMID_RING, 8, 3, 8000, + PL_MAG, 60, 60, + PL_NSTR, 30, 30, + PL_GFX, ITEM_MERLINRING, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Karik's Ring", ITEMID_RING, 8, 3, 8000, + PL_VIT, 60, 60, + PL_NMAG, 30, 30, + PL_GFX, ITEM_KARIKSRING, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + + { "Ring of Magma", ITEMID_RING, 8, 4, 8000, + PL_RFIRE, 60, 60, + PL_NRLGHT, 30, 30, + PL_NRMAG, 30, 30, + PL_GFX, ITEM_RINGMAGMA, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Ring of the Mystics", ITEMID_RING, 8, 4, 8000, + PL_RMAG, 60, 60, + PL_NRFIRE, 30, 30, + PL_NRLGHT, 30, 30, + PL_GFX, ITEM_RINGMYSTIC, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Ring of Thunder", ITEMID_RING, 8, 4, 8000, + PL_RLGHT, 60, 60, + PL_NRFIRE, 30, 30, + PL_NRMAG, 30, 30, + PL_GFX, ITEM_RINGTHUND, 0, + 0, 0, 0, + 0, 0, 0 + }, + + { "Amulet of Warding", ITEMID_AMULET, 12, 3, 30000, + PL_RALL, 40, 40, + PL_NHP, 100, 100, + PL_GFX, ITEM_AMULWARD, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Gnat Sting", ITEMID_BOW, 15, 5, 30000, + PL_NUMARWS, 3, 3, + PL_DAMAGE, 1, 2, + PL_ATANIM, 1, 1, + PL_IND, 0, 0, + PL_GFX, ITEM_BOWSPEED, 0, + 0, 0, 0 + }, + { "Flambeau", ITEMID_COMPBOW, 11, 4, 30000, + PL_HITADD, 15, 20, + PL_DAMAGE, 0, 0, + PL_IND, 0, 0, + PL_GFX, ITEM_BOWVULCAN, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Armor of Gloom", ITEMID_FULLPLATE, 25, 5, 200000, + PL_NSTRREQ, 0, 0, + PL_ACTUALAC, 225, 225, + PL_ZERORES, 0, 0, + PL_NLIGHT, 2, 2, + PL_GFX, ITEM_ARMRDARK, 0, + 0, 0, 0 + }, + + { "Blitzen", ITEMID_COMPBOW, 13, 4, 30000, + PL_HARQUN, 10, 15, + PL_DAMAGE, 0, 0, + PL_IND, 0, 0, + PL_GFX, ITEM_BOWDECAY, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Thunderclap", ITEMID_WARHAMMER, 13, 6, 30000, + PL_HARQUN2, 3, 6, + PL_STR, 20, 20, + PL_RLGHT, 30, 30, + PL_LIGHT, 2, 2, + PL_IND, 0, 0, + PL_GFX, ITEM_HAMRTHUND, 0 + }, + { "Shirotachi", ITEMID_GREATSWORD, 21, 4, 36000, + PL_ONEHAND, 0, 0, + PL_ATANIM, 4, 4, + PL_ENAC, 2, 2, + PL_LHIT, 6, 6, + 0, 0, 0, + 0, 0, 0 + }, + { "Eater of Souls", ITEMID_2HANDSWORD, 23, 6, 42000, + PL_IND, 0, 0, + PL_HP, 50, 50, + PL_LEECH, 5, 5, + PL_BAT, 5, 5, + PL_CONST, 0, 0, + PL_GFX, ITEM_SWORDEDGE, 0 + }, + { "Diamondedge", ITEMID_LONGSWORD, 17, 6, 42000, + PL_DURNUM, 10, 10, + PL_TOHIT, 50, 50, + PL_TODAM, 100, 100, + PL_RLGHT, 50, 50, + PL_ACTUALAC, 10, 10, + PL_GFX, ITEM_SWRDCRYSTL, 0 + }, + { "Bone Chain Armor", ITEMID_CHAINMAIL, 13, 3, 36000, + PL_ACTUALAC, 40, 40, + PL_UNDEADAC, 0, 0, + PL_GFX, ITEM_ARMRBONECH, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Demon Plate Armor", ITEMID_FULLPLATE, 25, 3, 80000, + PL_ACTUALAC, 80, 80, + PL_DEMONAC, 0, 0, + PL_GFX, ITEM_ARMRDMNPLT, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Acolyte's Amulet", ITEMID_AMULET, 10, 2, 10000, + PL_ACOLYTE, 50, 50, + PL_GFX, ITEM_AMULACOLYT, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Gladiator's Ring", ITEMID_RING, 10, 2, 10000, + PL_GLADIATR, 40, 40, + PL_GFX, ITEM_RINGGLADTR, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, + + // Book +/* { "Zhar the Mad's Memoirs", ITEMID_NONE, 6, 4, 4000, + PL_NMANA, 10, 10, + PL_NMAG, 10, 10, + PL_SLVL, 1, 1, + PL_GFX, ITEM_BOOK1, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "T'farc Evol's Tomb", ITEMID_NONE, 8, 4, 5000, + PL_MAG, 15, 15, + PL_NMANA, 25, 25, + PL_SLVL, 1, 1, + PL_GFX, ITEM_BOOK2, 0, + 0, 0, 0, + 0, 0, 0 + }, + // Amulet + { "Yulm's Mystic Amulet", ITEMID_AMULET, 1, 4, 1200, + PL_MAG, 10, 10, + PL_RALL, 10, 10, + PL_NSTATS, 5, 5, + PL_GFX, ITEM_AMULET2, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Torka's Amulet of Power", ITEMID_AMULET, 2, 4, 19700, + PL_SLVL, 1, 1, + PL_MAG, 5, 5, + PL_LEECH, 5, 5, + PL_GFX, ITEM_AMULET2, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Amulet of the Dead", ITEMID_AMULET, 12, 4, 5000, + PL_NMANA, 20, 20, + PL_X, 0, 0,//(NW) + PL_X, 0, 0,//(NW) + PL_GFX, ITEM_AMULET4, 0, + 0, 0, 0, + 0, 0, 0 + }, + { "Scarab Amulet", ITEMID_AMULET, 18, 3, 5000, + PL_STATS, 5, 5, + PL_X, 0, 0,//(NW) + PL_GFX, ITEM_AMULET3, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, +*/ +#endif + + { "", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Stopper +}; + diff --git a/ITEMDAT.H b/ITEMDAT.H new file mode 100644 index 0000000..d4f50c8 --- /dev/null +++ b/ITEMDAT.H @@ -0,0 +1,301 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/ITEMDAT.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Powers List +**-----------------------------------------------------------------------*/ + +#define PL_TOHIT 0 // To hit +#define PL_NTOHIT 1 // Negative to hit +#define PL_TODAM 2 // Damage amount % +#define PL_NTODAM 3 // Negative damage amount % +#define PL_DAHT 4 // Damage and to hit % +#define PL_NDAHT 5 // Negative damage and to hit % +#define PL_AC 6 // Armor Class % increase +#define PL_NAC 7 // Negative % Armor Class + +#define PL_RFIRE 8 // Resistance to fire % +#define PL_RLGHT 9 // Resistance to lightning % +#define PL_RMAG 10 // Resistance to misc magic % +#define PL_RALL 11 // Resistance to all + +//#define PL_SCOST 12 // Spell cost (-) (removed by drb for multiplayer pickup flag) +//#define PL_SDUR 13 // Spell duration (removed by drb for unique crash) +#define PL_SLVL 14 // Spell levels + +#define PL_CHRG 15 // Staff charges + +#define PL_FHIT 16 // Fire hit +#define PL_LHIT 17 // Lightning hit +#define PL_CHAOS 18 //not in game + +#define PL_STR 19 // Strength attribute +#define PL_NSTR 20 // Negative strength attribute +#define PL_MAG 21 // Magic attribute +#define PL_NMAG 22 // Negative magic attribute +#define PL_DEX 23 // Dexterity attribute +#define PL_NDEX 24 // Negative dexterity attribute +#define PL_VIT 25 // Vitality attribute +#define PL_NVIT 26 // Negative vitality attribute +#define PL_STATS 27 // All attributes +#define PL_NSTATS 28 // Negative all attributes + +#define PL_GETHIT 29 // Add to every get hit +#define PL_NGETHIT 30 // Subtract from every get hit + +#define PL_HP 31 // Hit points attribute +#define PL_NHP 32 // Negative hit points attribute +#define PL_MANA 33 // Mana attribute +#define PL_NMANA 34 // Negative mana attribute + +#define PL_DUR 35 // Add to item's durability % +#define PL_NDUR 36 // Subtract from item's durability % +#define PL_IND 37 // Infinite durability + +#define PL_LIGHT 38 // Add to player's light source +#define PL_NLIGHT 39 // Subtract from player's light source + +#define PL_INVIS 40 //not in game Player invisible from radius + +#define PL_NUMARWS 41 // Shoots multiple arrows +#define PL_FARROW 42 // Fire arrows +#define PL_LARROW 43 // Lightning arrows + +#define PL_GFX 44 // Change to unique graphic + +#define PL_THORN 45 // When item deals damage user gets damaged too +#define PL_LMANA 46 // Player looses all mana/ can't regen +#define PL_NOHEAL 47 // User can't heal +#define PL_FEAR 48 // When monster is struck, runs in fear (50%-ML) +#define PL_RABID 49 //not in game +#define PL_HITADD 50 // Half damage is added to player's hp +#define PL_SEEINVIS 51 //not in game See invisible +#define PL_TRAPDAM 52 // Half trap damage +#define PL_BEAR 53 // Knock monster back a square (if poss) +#define PL_MNOHEAL 54 // Monster no longer heals +#define PL_BAT 55 // Damage done adds to mana +#define PL_LEECH 56 // Damage dones adds to life +#define PL_ENAC 57 // Reduces the enemies ac by this +#define PL_ATANIM 58 // Attack anim quicker +#define PL_HTANIM 59 // Hit anim quicker +#define PL_BLANIM 60 // Block anim quicker + +#define PL_DAMADD 61 // Damage Hit point modifier + +// From here down, from uniques + +#define PL_RNDARW 62 // Random arrow speeds +#define PL_DAMAGE 63 // Changes weapon damage to (param1-param2) +#define PL_DURNUM 64 // Durability set to param1 +#define PL_NSTRREQ 65 // No minimum strength requirement +#define PL_SPELL 66 // Add charges to your staff +#define PL_FALCON 67 // Skips frames 1-3 of swing anim +#define PL_ONEHAND 68 // Change item to one handed +#define PL_DAMDEMON 69 // damage vs. demon only +#define PL_ZERORES 70 // All resistance equal to zero +#define PL_HYPER 71 // Hyperspace spell (param1 charges) +#define PL_CONST 72 // Constricting +#define PL_SKING 73 // Skeleton king power (life stealing) +#define PL_INFRA 74 // Infravision +#define PL_ACTUALAC 75 // Actual Armor Class +#define PL_HARQUN 76 // +(Armor Class)HP +#define PL_HARQUN2 77 // +(Mana/10)armor +#define PL_HARQUN3 78 // +(30-charlevel) resist fire +#define PL_NACTULAC 79 // Negative actual armor class +#define PL_NRFIRE 80 // Resistance to fire % (negative) +#define PL_NRLGHT 81 // Resistance to lightning % (negative) +#define PL_NRMAG 82 // Resistance to misc magic % (negative) +#define PL_NRALL 83 // Resistance to all % (negative) +#define PL_DEVAST 84 +#define PL_DECAY 85 +#define PL_PERIL 86 +#define PL_RNDDAM 87 +#define PL_FRAGILE 88 +#define PL_DOPPEL 89 +#define PL_DEMONAC 90 +#define PL_UNDEADAC 91 +#define PL_ACOLYTE 92 +#define PL_GLADIATR 93 +#define PL_X 94 // Unknown???? TEMP-------- + +/*-----------------------------------------------------------------------** +** Power List Bit flags +**-----------------------------------------------------------------------*/ + +#define PLF_ARMOR 0x100000 +#define PLF_SHIELD 0x010000 +#define PLF_WEAPON 0x001000 +#define PLF_STAFF 0x000100 +#define PLF_BOW 0x000010 +#define PLF_RING 0x000001 + +/*-----------------------------------------------------------------------** +** Item Misc Id +**-----------------------------------------------------------------------*/ + +#define IMID_NONE 0 // No misc ability +#define IMID_FIRSTPOT 1 +#define IMID_PHEAL 2 // Potion of full heal +#define IMID_PLHEAL 3 // Potion of Light heal +#define IMID_PSHEAL 4 // Potion of Serious heal +#define IMID_PDHEAL 5 // Potion of Deadly heal +#define IMID_PMANA 6 // Potion of Mana +#define IMID_PFMANA 7 // Potion of Full mana +#define IMID_PEXP 8 // Potion of Experience +#define IMID_PNEXP 9 // Potion of Negative Experience +#define IMID_ESTR 10 // Elixir of Strength +#define IMID_EMAG 11 // Elixir of Magic +#define IMID_EDEX 12 // Elixir of Dexterity +#define IMID_EVIT 13 // Elixir of Vitality +#define IMID_ENSTR 14 // Elixir of Negative Strength +#define IMID_ENMAG 15 // Elixir of Negative Magic +#define IMID_ENDEX 16 // Elixir of Negative Dexerity +#define IMID_ENVIT 17 // Elixir of Negative Vitaltiy +#define IMID_REJUV 18 +#define IMID_FREJUV 19 +#define IMID_LASTPOT 20 + +#define IMID_SCROLL 21 // Scroll of spell +#define IMID_TSCROLL 22 // Scroll of targeted spell +#define IMID_STAFF 23 // Item with a spell + +#define IMID_BOOK 24 // Book of spell +#define IMID_RING 25 +#define IMID_AMULET 26 + +#define IMID_UNIQUE 27 // Unique item so no magic / magic already built in + +#define IMID_MEAT 28 // Slab of meat + +#define IMID_FIRSTOIL 29 +#define IMID_OIL 30 +#define IMID_OILACC 31 +#define IMID_OILMAST 32 +#define IMID_OILSHRP 33 +#define IMID_OILDEATH 34 +#define IMID_OILSKILL 35 +#define IMID_OILBLKSM 36 +#define IMID_OILFORT 37 +#define IMID_OILPERM 38 +#define IMID_OILHARD 39 +#define IMID_OILIMPER 40 +#define IMID_LASTOIL 41 + +#define IMID_MAPOFDOOM 42 // The end quest map of doom item + +#define IMID_EAR 43 +#define IMID_SPECTRAL 44 + +#define IMID_BOMB 45 + +#define IMID_FIRSTRUNE 46 +#define IMID_RUNEFIRE 47 +#define IMID_RUNELIGHT 48 +#define IMID_RUNENOVA 49 +#define IMID_RUNEIMMOLATE 50 +#define IMID_RUNESTONE 51 +#define IMID_LASTRUNE 52 + +#define IMID_AURIC 53 + +#define IMID_FULLNOTE 54 + +/*-----------------------------------------------------------------------** +** Item Id's +**-----------------------------------------------------------------------*/ + +#define ITEMID_NONE 0 + +#define ITEMID_SHORTBOW 1 +#define ITEMID_LONGBOW 2 +#define ITEMID_BOW 3 +#define ITEMID_COMPBOW 4 +#define ITEMID_LWARBOW 5 +#define ITEMID_LBATTLEBOW 6 + +#define ITEMID_DAGGER 7 +#define ITEMID_FALCHION 8 +#define ITEMID_CLAYMORE 9 +#define ITEMID_BROADSWORD 10 +#define ITEMID_SABRE 11 +#define ITEMID_SCIMITAR 12 +#define ITEMID_LONGSWORD 13 +#define ITEMID_BASTSWORD 14 +#define ITEMID_2HANDSWORD 15 +#define ITEMID_GREATSWORD 16 + +#define ITEMID_CLEAVER 17 +#define ITEMID_LARGEAXE 18 +#define ITEMID_BROADAXE 19 +#define ITEMID_SMALLAXE 20 +#define ITEMID_BATTLEAXE 21 +#define ITEMID_GREATAXE 22 + +#define ITEMID_MACE 23 +#define ITEMID_MORNSTAR 24 +#define ITEMID_CLUB 25 +#define ITEMID_MAUL 26 +#define ITEMID_WARHAMMER 27 +#define ITEMID_FLAIL 28 + +#define ITEMID_LONGSTAFF 29 +#define ITEMID_SHORTSTAFF 30 +#define ITEMID_COMPSTAFF 31 +#define ITEMID_QTRSTAFF 32 +#define ITEMID_WARSTAFF 33 + +#define ITEMID_SKULLCAP 34 +#define ITEMID_HELM 35 +#define ITEMID_GREATHELM 36 +#define ITEMID_CROWN 37 + +#define ITEMID_RAGS 39 +#define ITEMID_STDLEATHER 40 +#define ITEMID_CLOAK 41 +#define ITEMID_ROBE 42 +#define ITEMID_CHAINMAIL 43 +#define ITEMID_LEATHER 44 +#define ITEMID_BREASTPLATE 45 +#define ITEMID_CAPE 46 +#define ITEMID_PLATEMAIL 47 +#define ITEMID_FULLPLATE 48 + +#define ITEMID_BUCKLER 49 +#define ITEMID_SMALLSHLD 50 +#define ITEMID_LARGESHLD 51 +#define ITEMID_KITESHLD 52 +#define ITEMID_TOWERSHLD 53 + +#define ITEMID_RING 54 +#define ITEMID_BOOK 55 +#define ITEMID_AMULET 56 + +#define ITEMID_SKCROWN 57 +#define ITEMID_IRING 58 +#define ITEMID_OPTAMULET 59 +#define ITEMID_TRING 60 +#define ITEMID_HALCREST 61 +#define ITEMID_MAP 62 +#define ITEMID_ELIXIR 63 +#define ITEMID_ARMOFVAL 64 +#define ITEMID_STEELVEIL 65 +#define ITEMID_GRISWOLD 66 +#define ITEMID_LGTFORGE 67 +#define ITEMID_LAZSTAFF 68 +#define ITEMID_ARMRCOW 69// dude! + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern ItemDataStruct AllItemsList[]; +extern const PLStruct PL_Prefix[]; +extern const PLStruct PL_Suffix[]; +extern const UItemStruct UniqueItemList[]; diff --git a/ITEMS.BAK b/ITEMS.BAK new file mode 100644 index 0000000..cf01bea --- /dev/null +++ b/ITEMS.BAK @@ -0,0 +1,5532 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Items file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/ITEMS.CPP 4 2/06/97 6:08p Jessmac $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "objects.h" +#include "items.h" +#include "itemdat.h" +#include "engine.h" +#include "gendung.h" +#include "player.h" +#include "control.h" +#include "monster.h" +#include "spells.h" +#include "quests.h" +#include "cursor.h" +#include "effects.h" +#include "lighting.h" +#include "stores.h" +#include "spelldat.h" +#include "scrollrt.h" +#include "inv.h" +#include "msg.h" +#include "multi.h" +#include "monstdat.h" +#include "doom.h" +#include "missiles.h" +#include "minitext.h" +#include "storm.h" +#include "DRLG_l1.h" +#include "packplr.h" + + +void RecreateTownItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue); +void SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval); +void GetItemPower(int i, int minlvl, int maxlvl, long flgs, BOOL onlygood); +void GetItemAttrs(int i, int idata, int lvl); +void SetupItem(int); +void RecalcStoreStats(); +void SpawnMap(); +void DeleteItem(int ii, int i); + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ +CornerStoneType CornerStone; +extern char gszProgKey[]; + +int GOLD_VMAX = 5000; +ItemStruct item[MAXITEMS+1]; +long numitems = 0; + +int itemactive[MAXITEMS]; +int itemavail[MAXITEMS]; +int tem; + +//PATCH1.JMM +ItemGetRecordStruct itemgets[MAXITEMS]; +int gnNumGetRecords = 0; +//ENDPATCH1.JMM + + + +BOOL UniqueItemFlag[MAXUITEMS]; +BOOL uitemflag; +ItemStruct curruitem; +#if CHEATS +extern BOOL itemcheat; + +BOOL davecheat = FALSE; +#endif + +BOOL itemhold[3][3]; + + +#define MAXOIL 10 + +int OilLvlTbl[MAXOIL]= { 1, 10, 1, 10, 4, 1, 5, 17, 1, 10 }; +int OilValue[MAXOIL] = { 500, 2500, 500, 2500, 1500, 100, 2500, 15000, 500, 2500 }; +int OilIdVal[MAXOIL] = { + IMID_OILACC, + IMID_OILMAST, + IMID_OILSHRP, + IMID_OILDEATH, + IMID_OILSKILL, + IMID_OILBLKSM, + IMID_OILFORT, + IMID_OILPERM, + IMID_OILHARD, + IMID_OILIMPER +}; +char OilStr[MAXOIL][25] = { + "Oil of Accuracy", + "Oil of Mastery", + "Oil of Sharpness", + "Oil of Death", + "Oil of Skill", + "Blacksmith Oil", + "Oil of Fortitude", + "Oil of Permanence", + "Oil of Hardening", + "Oil of Imperviousness" +}; + +BYTE ItemCAnimTbl[] = { + // 1x1 + 20, // ITEM_BLUEBTL + 16, // ITEM_SCROLL + 16, // ITEM_SCROLL2 + 16, // ITEM_SCROLL3 + 4, // ITEM_1GOLD + 4, // ITEM_3GOLD + 4, // ITEM_5GOLD + 12, // ITEM_GOLDRING + 12, // ITEM_1JRING + 12, // ITEM_WOODRING + 12, // ITEM_BLUERING + 12, // ITEM_3JRING + 12, // ITEM_SLVRRING + 12, // ITEM_MJRING + 12, // ITEM_BRNRING + 21, // ITEM_SPECTRAL + 21, // ITEM_3COLORPOT + 25, // ITEM_GOLDENELIX + 12, // ITEM_EMPYBAND + 28, // ITEM_EAR1 + 28, // ITEM_EAR2 + 28, // ITEM_EAR3 + 38, // ITEM_SPHERE + 38, // ITEM_CUBE + 38, // ITEM_PYRIMID + 32, // ITEM_BLOODGEM + 38, // ITEM_JSPHERE + 38, // ITEM_JCUBE + 38, // ITEM_JPYRIMID + 24, // ITEM_VILE + 24, // ITEM_BLKBTL + 26, // ITEM_WHTEBTL + 2, // ITEM_REDBTL + 25, // ITEM_YELBTL + 22, // ITEM_ORGBTL + 23, // ITEM_BREDBTL + 24, // ITEM_BLKBTL2 + 25, // ITEM_GOLDBTL + 27, // ITEM_LTBLUEBTL + 27, // ITEM_BLUEBTL2 + 29, // ITEM_BRAIN + 0, // ITEM_CLAW + 0, // ITEM_FANG + 0, // ITEM_BREAD + 12, // ITEM_AMULET + 12, // ITEM_AMULET1 + 12, // ITEM_AMULET2 + 12, // ITEM_AMULET3 + 12, // ITEM_AMULET4 + 0, // ITEM_POUCH1 + //35, // ITEM_DOHICKY + //39, // ITEM_THEODORE + //36, // ITEM_PAPER1 + //36, // ITEM_PAPER2 + //36, // ITEM_PAPER3 + //37, // ITEM_PAPER4 + // 1x2 + 8, // ITEM_DAGGER1 + 8, // ITEM_DAGGER2 + 0, // ITEM_BIGBOTTLE + 8, // ITEM_DAGGER3 + 8, // ITEM_DAGGER4 + 8, // ITEM_DAGGER5 + // 1x3 + 8, // ITEM_BLADE + 8, // ITEM_BASTSRD + 8, // ITEM_FALCHION + 6, // ITEM_MACE + 8, // ITEM_LONGSRD + 8, // ITEM_BROADSRD + 8, // ITEM_SCIMITAR + 6, // ITEM_MORNSTAR + 8, // ITEM_SHORTSRD + 8, // ITEM_CLAYMORE + 6, // ITEM_CLUB + 8, // ITEM_SABRE + 8, // ITEM_KNTSWORD + 6, // ITEM_CLUB1 + 6, // ITEM_CLUB2 + 6, // ITEM_CLUB3 + 8, // ITEM_SCIMITAR2 + 8, // ITEM_MAGSWORD + 8, // ITEM_SKULSWORD + // 2x2 + 5, // ITEM_HELM + 9, // ITEM_ROCK + 13, // ITEM_SKCROWN + 13, // ITEM_CROWN + 13, // ITEM_MCROWN + 5, // ITEM_JESTER + 5, // ITEM_HARLEQ + 5, // ITEM_FHELM + 15, // ITEM_BUCKLER + 5, // ITEM_FHELM2 + 5, // ITEM_GRTHELM + 18, // ITEM_BOOK1 + 18, // ITEM_BOOK2 + 18, // ITEM_BOOK3 + 30, // ITEM_MUSHROOM + 5, // ITEM_SKLCAP + 5, // ITEM_LCAP + 14, // ITEM_FLESH + 5, // ITEM_SKLCAP2 + 14, // ITEM_CLOTHES + 13, // ITEM_CROWN2 + 16, // ITEM_MAP + 18, // ITEM_BOOK4 + 5, // ITEM_FHELM3 + 5, // ITEM_SAMHELM + // 2x3 + 7, // ITEM_LRGSHIELD + 1, // ITEM_BTLAXE + 3, // ITEM_LONGBOW + 17, // ITEM_PARMOR + 1, // ITEM_AXE + 15, // ITEM_WSHIELD + 10, // ITEM_CLEAVER + 14, // ITEM_STDARMOR + 3, // ITEM_COMPBOW + 11, // ITEM_SHRTSTAFF + 8, // ITEM_2HSWORD + 0, // ITEM_CHARMOR + 1, // ITEM_SMALLAXE + 7, // ITEM_HVYSHIELD + 0, // ITEM_SCLARMOR + 7, // ITEM_SMLSHIELD + 15, // ITEM_SKULLSHLD + 7, // ITEM_WOLFSHLD + 3, // ITEM_SHORTBOW + 3, // ITEM_STLLONGBOW + 3, // ITEM_STLSHRTBOW + 6, // ITEM_SMLWARHAM + 6, // ITEM_MAUL + 11, // ITEM_IRONSTAFF + 11, // ITEM_STLSTAFF + 11, // ITEM_LONGSTAFF + 31, // ITEM_INNSIGN + 14, // ITEM_HLARMOR + 14, // ITEM_RAGS + 14, // ITEM_QARMOR + 6, // ITEM_BALLNCHN + 6, // ITEM_FLAIL + 7, // ITEM_TSHIELD + 3, // ITEM_HNTRBOW + 8, // ITEM_GRTSWORD + 14, // ITEM_LARMOR + 0, // ITEM_SPLTARMOR + 14, // ITEM_ROBE + 14, // ITEM_HVYROBE + 0, // ITEM_RINGARMOR + 33, // ITEM_ANVIL + 1, // ITEM_BROADAXE + 1, // ITEM_LRGAXE + 1, // ITEM_WICKAXE + 1, // ITEM_HANDAXE + 1, // ITEM_GREATAXE + 7, // ITEM_IRONSHLD + 7, // ITEM_KITESHLD + 7, // ITEM_LRGSHLD + 14, // ITEM_CLOAK + 14, // ITEM_CAPE + 17, // ITEM_PARMOR2 + 17, // ITEM_PARMOR3 + 17, // ITEM_BPLATE + 0, // ITEM_RINGMAIL + 34, // ITEM_BISHOPSTF + 1, // ITEM_GEMGRTAXE + 0, // ITEM_ARKARMOR + 3, // ITEM_CROSBOW + 17, // ITEM_NAJARMOR + 8, // ITEM_GRIZZLY + 8, // ITEM_GRANDPA + 6, // ITEM_PROTECT + 1, // ITEM_REAVER + 3, // ITEM_WINDFOR + 3, // ITEM_SWARBOW + 11, // ITEM_COMPSTF + 3, // ITEM_SBATLBOW +// Misc +// 4, // ITEM_GOLD + +// new 1x1 + 12, // ITEM_MERLINRING + 12, // ITEM_MANARING + 12, // ITEM_AMULWARD + 12, // ITEM_NECMAGIC + 12, // ITEM_NECHEALTH + 12, // ITEM_KARIKSRING + 12, // ITEM_RINGGROUND + 12, // ITEM_AMULPROT + 12, // ITEM_MERCRING + 12, // ITEM_RINGTHUND + 12, // ITEM_NECTRUTH + 12, // ITEM_RINGGIANTS + 12, // ITEM_AMULGOLD + 12, // ITEM_RINGMYSTIC + 12, // ITEM_RINGCOPPER + 12, // ITEM_AMULACOLYT + 12, // ITEM_RINGMAGMA + 12, // ITEM_NECPURIFY + 12, // ITEM_RINGGLADTR + 35, // ITEM_RUNEBOMB +// new 1x3 + 8, // ITEM_SWORDEDGE + 8, // ITEM_SWORDGLAM + 8, // ITEM_SWORDSERR +// new 2x3 + 17, // ITEM_ARMRDARK + 0, // ITEM_ARMRBONECH + 6, // ITEM_HAMRTHUND + 8, // ITEM_SWRDCRYSTL + 11, // ITEM_STAFJESTER + 11, // ITEM_STAFMANA + 3, // ITEM_BOWVULCAN + 3, // ITEM_BOWSPEED + 1, // ITEM_AXEANCIENT + 6, // ITEM_CLUBCARNAG + 6, // ITEM_MACEDARK + 6, // ITEM_CLUBDECAY + 1, // ITEM_AXEDECAY + 8, // ITEM_SWRDDECAY + 6, // ITEM_MACEDECAY + 11, // ITEM_STAFDECAY + 3, // ITEM_BOWDECAY + 6, // ITEM_CLUBOUCH + 8, // ITEM_SWRDDEVAST + 1, // ITEM_AXEDEVAST + 6, // ITEM_MORNDEVAST + 6 // ITEM_MACEDEVAST + + }; + + +char *ItemFiles[] = { + "Armor2", // 0 + "Axe", // 1 + "FBttle", // 2 + "Bow", // 3 + "GoldFlip", // 4 + "Helmut", // 5 + "Mace", // 6 + "Shield", // 7 + "SwrdFlip", // 8 + "Rock", // 9 + "Cleaver", // 10 + "Staff", // 11 + "Ring", // 12 + "CrownF", // 13 + "LArmor", // 14 + "WShield", // 15 + "Scroll", // 16 + "FPlateAr", // 17 + "FBook", // 18 + "Food", // 19 + "FBttleBB", // 20 + "FBttleDY", // 21 + "FBttleOR", // 22 + "FBttleBR", // 23 + "FBttleBL", // 24 + "FBttleBY", // 25 + "FBttleWH", // 26 + "FBttleDB", // 27 + "FEar", // 28 + "FBrain", // 29 + "FMush", // 30 + "Innsign", // 31 + "Bldstn", // 32 + "Fanvil", // 33 + "FLazStaf", // 34 + "bombs1", // 35 + "halfps1", // 36 + "wholeps1", // 37 + "runes1", // 38 + "teddys1" // 39 +}; +#define ITEMFTYPES (sizeof(ItemFiles)/sizeof(char *)) + +BYTE *itemanims[ITEMFTYPES]; + +byte ItemAnimLs[ITEMFTYPES] = { + 15, // Armor2 + 13, // Axe + 16, // FBttle + 13, // Bow + 10, // GoldFlip + 13, // Helmut + 13, // Mace + 13, // Shield + 13, // SwrdFlip + 10, // Rock + 13, // Cleaver + 13, // Staff + 13, // Ring + 13, // Crown + 13, // LArmor + 13, // WShield + 13, // Scroll + 13, // FPlateAr + 13, // FBook + 1, // Food + 16, // FBttleBB + 16, // FBttleDY + 16, // FBttleOR + 16, // FBttleBR + 16, // FBttleBL + 16, // FBttleBY + 16, // FBttleWH + 16, // FBttleDB + 13, // FEar + 12, // FBrain + 12, // FMush + 13, // Innsign + 13, // Bldstn + 13, // Fanvil + 8, // FLazStaf + 10, // nest bomb + 13, // half paper + 13, // whole paper + 10, // runes + 12 // teddy bear +}; + +int ItemAnimSnds[ITEMFTYPES] = { + IS_FHARM, // Armor2 + IS_FAXE, // Axe + IS_FPOT, // FBttle + IS_FBOW, // Bow + IS_GOLD, // GoldFlip + IS_FCAP, // Helmet + IS_FSWOR, // Mace + IS_FSHLD, // Shield + IS_FSWOR, // SwrdFlip + IS_FROCK, // Rock + IS_FAXE, // Cleaver + IS_FSTAF, // Staff + IS_FRING, // Ring + IS_FCAP, // Crown + IS_FLARM, // LArmor + IS_FSHLD, // WShield + IS_FSCRL, // Scroll + IS_FHARM, // FPlateAr + IS_FBOOK, // FBook + IS_FLARM, // Food + IS_FPOT, // FBttleBB + IS_FPOT, // FBttleDY + IS_FPOT, // FBttleOR + IS_FPOT, // FBttleBR + IS_FPOT, // FBttleBL + IS_FPOT, // FBttleBY + IS_FPOT, // FBttleWH + IS_FPOT, // FBttleDB + IS_FBODY, // FEar + IS_FBODY, // FBrain + IS_FMUSH, // FMush + IS_ISIGN, // Innsign + IS_FBLST, // Bldstn + IS_FANVL, // Fanvil + IS_FSTAF, // FLazStaf + IS_FROCK, // Bomb + IS_FSCRL, // Half Paper + IS_FSCRL, // Whole Paper + IS_FROCK, // Rune + IS_FMUSH, // Theo +}; + +int ItemInvSnds[ITEMFTYPES] = { + IS_IHARM, // Armor2 + IS_IAXE, // Axe + IS_IPOT, // FBttle + IS_IBOW, // Bow + IS_GOLD, // GoldFlip + IS_ICAP, // Helmet + IS_ISWORD, // Mace + IS_ISHIEL, // Shield + IS_ISWORD, // SwrdFlip + IS_IROCK, // Rock + IS_IAXE, // Cleaver + IS_ISTAF, // Staff + IS_IRING, // Ring + IS_ICAP, // Crown + IS_ILARM, // LArmor + IS_ISHIEL, // WShield + IS_ISCROL, // Scroll + IS_IHARM, // FPlateAr + IS_IBOOK, // FBook + IS_IHARM, // Food + IS_IPOT, // FBttleBB + IS_IPOT, // FBttleDY + IS_IPOT, // FBttleOR + IS_IPOT, // FBttleBR + IS_IPOT, // FBttleBL + IS_IPOT, // FBttleBY + IS_IPOT, // FBttleWH + IS_IPOT, // FBttleDB + IS_IBODY, // FEar + IS_IBODY, // FBrain + IS_IMUSH, // FMush + IS_ISIGN, // Innsign + IS_IBLST, // Bldstn + IS_IANVL, // Fanvil + IS_ISTAF, // FLazStaf + IS_IROCK, // Bomb + IS_ISCROL, // Half Paper + IS_ISCROL, // Whole Paper + IS_IROCK, // Rune + IS_IMUSH // Theo +}; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitItemGFX() { + for (int i = 0; i < ITEMFTYPES; i++) { + char filestr[64]; + sprintf(filestr, "Items\\%s.CEL", ItemFiles[i]); + app_assert(! itemanims[i]); + itemanims[i] = LoadFileInMemSig(filestr,NULL,'IGFX'); + } + + ZeroMemory(UniqueItemFlag,sizeof(UniqueItemFlag)); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL ItemPlace(int xp, int yp) { + if (dMonster[xp][yp] != 0) return FALSE; + if (dPlayer[xp][yp] != 0) return FALSE; + if (dItem[xp][yp] != 0) return FALSE; + if (dObject[xp][yp] != 0) return FALSE; + if (dFlags[xp][yp] & BFLAG_SETPC) return FALSE; + if (nSolidTable[dPiece[xp][yp]]) return FALSE; + return TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void AddInitItems() { + int j = random(11, 3) + 3; + for (int i = 0; i < j; i++) { + int ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + int xx = random(12, DMAXX - DIRTEDGE) + (DIRTEDGED2); + int yy = random(12, DMAXY - DIRTEDGE) + (DIRTEDGED2); + while (! ItemPlace(xx, yy)) { + xx = random(12, DMAXX - DIRTEDGE) + (DIRTEDGED2); + yy = random(12, DMAXY - DIRTEDGE) + (DIRTEDGED2); + } + + item[ii]._ix = xx; + item[ii]._iy = yy; + dItem[xx][yy] = ii + 1; + item[ii]._iSeed = GetRndSeed(); + SetRndSeed(item[ii]._iSeed); + if (random(12, 2)) GetItemAttrs(ii, IDI_HEAL, currlevel); + else GetItemAttrs(ii, IDI_MANA, currlevel); + item[ii]._iCreateInfo = currlevel + ICI_PREGEN; + SetupItem(ii); + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iAnimFlag = FALSE; + item[ii]._iSelFlag = ISEL_FLR; + DeltaAddItem(ii); + numitems++; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitItems() { + int i; + + DROPLOG("Initing items...\n"); + // Setup a gold item + GetItemAttrs(0, 0, 1); + golditem = item[0]; + golditem._iStatFlag = TRUE; + + numitems = 0; + for (i = 0; i < MAXITEMS; i++) { + item[i]._itype = 0; + item[i]._ix = 0; + item[i]._iy = 0; + item[i]._iAnimFlag = FALSE; + item[i]._iSelFlag = ISEL_NONE; + item[i]._iIdentified = FALSE; + item[i]._iPostDraw = FALSE; + } + + for (i = 0; i < MAXITEMS; i++) { + itemavail[i] = i; + itemactive[i] = 0; + } + + if (!setlevel) { + + int rs = GetRndSeed(); + + if (QuestStatus(Q_ROCK)) { + SpawnRock(); + } + if (QuestStatus(Q_ANVIL)) { + SpawnQuestItem(IDI_ANVIL, (setpc_x << 1) + 11 + DIRTEDGED2, (setpc_y << 1) + 11 + DIRTEDGED2, FALSE, ISEL_FLR); + } + if (currlevel > 0 && currlevel < 16) + AddInitItems(); + } + + uitemflag = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CalcPlrItemVals(int p, BOOL Loadgfx) +{ + int mind, maxd, tac, g, d, i, mi; + int bdam, btohit, bac; + int sadd, madd, dadd, vadd; + int fr, lr, mr; + int dmod, ghit, lrad; + int ihp, imana; + int spllvladd; + int enac; + int fmin, fmax, lmin, lmax; + long iflgs, iflgs2; + __int64 spl, t; + + app_assert((DWORD) p < MAX_PLRS); + + mind = 0; + maxd = 0; + tac = 0; + bdam = 0; + btohit = 0; + bac = 0; + iflgs = 0; + iflgs2 = 0; + sadd = 0; + madd = 0; + dadd = 0; + vadd = 0; + spl = 0; + fr = 0; + lr = 0; + mr = 0; + dmod = 0; + ghit = 0; + lrad = PLRLRAD; + ihp = 0; + imana = 0; + spllvladd = 0; + enac = 0; + fmin = 0; + fmax = 0; + lmin = 0; + lmax = 0; + for (i = 0; i < 7; i++) { + const ItemStruct * itm = &plr[p].InvBody[i]; + if (itm->_itype == -1) continue; + if (! itm->_iStatFlag) continue; + + mind += itm->_iMinDam; + maxd += itm->_iMaxDam; + tac += itm->_iAC; + + t = 1; + if (itm->_iSpell != 0) + spl |= t << (itm->_iSpell - 1); + + // don't give benefit of unidentified magic items + if (itm->_iMagical != IMAGIC_NONE && ! itm->_iIdentified) + continue; + + bdam += itm->_iPLDam; + btohit += itm->_iPLToHit; + + if (itm->_iPLAC) { + int tmpac = (itm->_iAC * itm->_iPLAC) / 100; + if (tmpac == 0) tmpac = 1; + bac += tmpac; + } + + iflgs |= itm->_iFlags; + iflgs2 |= itm->_iFlags2; + sadd += itm->_iPLStr; + madd += itm->_iPLMag; + dadd += itm->_iPLDex; + vadd += itm->_iPLVit; + fr += itm->_iPLFR; + lr += itm->_iPLLR; + mr += itm->_iPLMR; + dmod += itm->_iPLDamMod; + ghit += itm->_iPLGetHit; + lrad += itm->_iPLLight; + ihp += itm->_iPLHP; + imana += itm->_iPLMana; + spllvladd += itm->_iSplLvlAdd; + enac += itm->_iPLEnAc; + fmin += itm->_iFMinDam; + fmax += itm->_iFMaxDam; + lmin += itm->_iLMinDam; + lmax += itm->_iLMaxDam; + } + + // If I have no weapons, then make it min of 1-1, if shield only, 1-3 + if (mind == 0 && maxd == 0) { + mind = 1; + maxd = 1; + if ((plr[p].Hand1Item._itype == IT_SHIELD) && (plr[p].Hand1Item._iStatFlag)) + maxd = 3; + if ((plr[p].Hand2Item._itype == IT_SHIELD) && (plr[p].Hand2Item._iStatFlag)) + maxd = 3; + + // monks have fists of fury. + if (plr[p]._pClass == CLASS_MONK) + { + mind = max(mind,plr[p]._pLevel >> 1); + maxd = max(maxd,plr[p]._pLevel); + } + } + + plr[p]._pIMinDam = mind; + plr[p]._pIMaxDam = maxd; + plr[p]._pIAC = tac; + plr[p]._pIBonusDam = bdam; + plr[p]._pIBonusToHit = btohit; + plr[p]._pIBonusAC = bac; + plr[p]._pIFlags = iflgs; + plr[p]._pIFlags2 = iflgs2; + plr[p]._pIBonusDamMod = dmod; + plr[p]._pIGetHit = ghit; + if (lrad < 2) lrad = 2; + if (lrad > 15) lrad = 15; + if ((plr[p]._pLightRad != lrad ) && (p == myplr)) { + ChangeLightRadius(plr[p]._plid, lrad); + if (lrad < 10) ChangeVisionRadius(plr[p]._pvid, 10); + else ChangeVisionRadius(plr[p]._pvid, lrad); + plr[p]._pLightRad = lrad; + } + + plr[p]._pStrength = plr[p]._pBaseStr + sadd; + if (plr[myplr]._pStrength <= 0) plr[myplr]._pStrength = 0; + plr[p]._pMagic = plr[p]._pBaseMag + madd; + if (plr[myplr]._pMagic <= 0) plr[myplr]._pMagic = 0; + plr[p]._pDexterity = plr[p]._pBaseDex + dadd; + if (plr[myplr]._pDexterity <= 0) plr[myplr]._pDexterity = 0; + plr[p]._pVitality = plr[p]._pBaseVit + vadd; + if (plr[myplr]._pVitality <= 0) plr[myplr]._pVitality = 0; + + if (plr[p]._pClass == CLASS_ROGUE) + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 200; + else if (plr[p]._pClass == CLASS_MONK) + { + if (plr[p].Hand1Item._itype == IT_STAFF || // bonus for staff + plr[p].Hand2Item._itype == IT_STAFF || + (plr[p].Hand1Item._itype == -1 && // bonus for no weapons. + plr[p].Hand2Item._itype == -1) + ) + { + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 150; + } + else + { + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 300; + } + } + else if (plr[p]._pClass == CLASS_BARD) + { + // GWPif ((plr[p].Hand1Item._itype == IT_SWORD // bonus for single handed swords + // GWP && plr[p].Hand1Item._iLoc != IL_2HAND) + // GWP ||( plr[p].Hand2Item._itype == IT_SWORD + // GWP && plr[p].Hand2Item._iLoc != IL_2HAND) + // GWP ) + if (plr[p].Hand1Item._itype == IT_SWORD // bonus for using a sword. + || plr[p].Hand2Item._itype == IT_SWORD) + { + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 200; + } + else if (plr[p].Hand1Item._itype == IT_BOW + || plr[p].Hand2Item._itype == IT_BOW) + { + // Better than a monk or warrior with a bow but not as good as a rogue. + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 250; + } + else + { + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; + } + } + else + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; + + plr[p]._pISpells = spl; + if ((plr[p]._pRSplType == SPT_ITEM) /*|| plr[p]._pRSplType == SPT_SCROLL)*/ + && ((plr[p]._pISpells & (((__int64)1) << (plr[p]._pRSpell-1))) == 0)) { + plr[p]._pRSpell = -1; + plr[p]._pRSplType = SPT_NONE; + force_redraw = FULLDRAW; + } + plr[p]._pISplLvlAdd = spllvladd; + + plr[p]._pIEnAc = enac; + + if (iflgs & IAF_ZERORES) { + mr = 0; + fr = 0; + lr = 0; + } + if (mr > RESIST_MAX) mr = RESIST_MAX; + plr[p]._pMagResist = mr; + if (fr > RESIST_MAX) fr = RESIST_MAX; + plr[p]._pFireResist = fr; + if (lr > RESIST_MAX) lr = RESIST_MAX; + plr[p]._pLghtResist = lr; + + if (plr[p]._pClass == CLASS_WARRIOR) vadd = vadd << 1; + if (plr[p]._pClass == CLASS_ROGUE || + plr[p]._pClass == CLASS_MONK || + plr[p]._pClass == CLASS_BARD ) vadd += (vadd >> 1); + ihp += (vadd << HP_SHIFT); + if (plr[p]._pClass == CLASS_SORCEROR) madd = madd << 1; + if (plr[p]._pClass == CLASS_ROGUE || + plr[p]._pClass == CLASS_MONK || + plr[p]._pClass == CLASS_BARD ) madd += (madd >> 1); + imana += (madd << MANA_SHIFT); + + plr[p]._pHitPoints = plr[p]._pHPBase + ihp; + plr[p]._pMaxHP = plr[p]._pMaxHPBase + ihp; + if ((p == myplr) && (plr[p]._pHitPoints >> HP_SHIFT) <= 0) + SetPlayerHitPoints(p, 0); + + plr[p]._pMana = plr[p]._pManaBase + imana; + plr[p]._pMaxMana = plr[p]._pMaxManaBase + imana; + + plr[p]._pIFMinDam = fmin; + plr[p]._pIFMaxDam = fmax; + plr[p]._pILMinDam = lmin; + plr[p]._pILMaxDam = lmax; + + + if (iflgs & IAF_INFRAVISION) plr[p]._pInfraFlag = TRUE; + else plr[p]._pInfraFlag = FALSE; + + plr[p]._pBlockFlag = FALSE; + if (plr[p]._pClass == CLASS_MONK) + { + if ((plr[p].Hand1Item._itype == IT_STAFF) && + (plr[p].Hand1Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + + if ((plr[p].Hand2Item._itype == IT_STAFF) && + (plr[p].Hand2Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + + if ((plr[p].Hand1Item._iClass == IC_WEAP) && + (plr[p].Hand1Item._iLoc != IL_2HAND) && + (plr[p].Hand2Item._itype == -1)) + { + plr[p]._pBlockFlag = TRUE; + } + + if ((plr[p].Hand2Item._iClass == IC_WEAP) && + (plr[p].Hand2Item._iLoc != IL_2HAND) && + (plr[p].Hand1Item._itype == -1)) + { + plr[p]._pBlockFlag = TRUE; + } + } +#if defined (HELLFIRE2) + else if (plr[p]._pClass == CLASS_BARD) + { + if ((plr[p].Hand1Item._itype == IT_SWORD) && + (plr[p].Hand1Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + + if ((plr[p].Hand2Item._itype == IT_SWORD) && + (plr[p].Hand2Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + } +#endif + + plr[p]._pwtype = WEAP_H2H; + // Determine which graphics to use + g = PGFX_NGUY; + if ((plr[p].Hand1Item._itype != -1) && + (plr[p].Hand1Item._iClass == IC_WEAP) && + (plr[p].Hand1Item._iStatFlag)) g = plr[p].Hand1Item._itype; + if ((plr[p].Hand2Item._itype != -1) && + (plr[p].Hand2Item._iClass == IC_WEAP) && + (plr[p].Hand2Item._iStatFlag)) g = plr[p].Hand2Item._itype; + switch (g) { + case IT_SWORD: + g = PGFX_XGUY; + break; + case IT_MACE: + g = PGFX_ZGUY; + break; + case IT_BOW: + plr[p]._pwtype = WEAP_RANGE; + g = PGFX_BGUY; + break; + case IT_AXE: + g = PGFX_FGUY; + break; + case IT_STAFF: + g = PGFX_TGUY; + break; + } + if ((plr[p].Hand1Item._itype == IT_SHIELD) && (plr[p].Hand1Item._iStatFlag)) { + plr[p]._pBlockFlag = TRUE; + g++; + } + if ((plr[p].Hand2Item._itype == IT_SHIELD) && (plr[p].Hand2Item._iStatFlag)) { + plr[p]._pBlockFlag = TRUE; + g++; + } + + #if IS_VERSION(RETAIL) || IS_VERSION(BETA) + if ((plr[p].BodyItem._itype == IT_MARMOR) && (plr[p].BodyItem._iStatFlag)) + { + if (plr[p]._pClass == CLASS_MONK) + { + plr[p]._pIAC += plr[p]._pLevel >> 1; // Monks get 1/2 level bonus while wearing light armor. + } + g += 16; + } + else if ((plr[p].BodyItem._itype == IT_HARMOR) && (plr[p].BodyItem._iStatFlag)) + { + g += 32; + } + else + { + if (plr[p]._pClass == CLASS_MONK) + { + plr[p]._pIAC += plr[p]._pLevel << 1; // Monks get 2x level bonus for no armor. + } + } + #endif + + if ((plr[p]._pgfxnum != g) && (Loadgfx)) { + plr[p]._pgfxnum = g; + plr[p]._pGFXLoad = 0; // Clear all graphics loaded flag + LoadPlrGFX(p, PGL_STAND); + SetPlrAnims(p); + d = plr[p]._pdir; + + app_assert(plr[p]._pNAnim[d]); + plr[p]._pAnimData = plr[p]._pNAnim[d]; + plr[p]._pAnimLen = plr[p]._pNFrames; + plr[p]._pAnimFrame = 1; + plr[p]._pAnimCnt = 0; + plr[p]._pAnimDelay = 3; + plr[p]._pAnimWidth = plr[p]._pNWidth; + plr[p]._pAnimWidth2 = (plr[p]._pNWidth - 64) >> 1; + } + else { + plr[p]._pgfxnum = g; + } + + for (i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if (missile[mi]._mitype == MIT_MANASHIELD && missile[mi]._misource == p) { + missile[mi]._miVar1 = plr[p]._pHitPoints; + missile[mi]._miVar2 = plr[p]._pHPBase; + } + } + + if (plr[p].NeckItem._itype != -1 && plr[p].NeckItem.IDidx == IDI_AURIC) + { + GOLD_VMAX = 10000; + } + else + { + int old_vmax = GOLD_VMAX; + + GOLD_VMAX = 5000; + + if (old_vmax != GOLD_VMAX) + StripTopGold(p); + } + + drawmanaflag = TRUE; + drawhpflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrScrolls(int p) { + int i; + __int64 t; + + plr[p]._pScrlSpells = 0; + for (i = 0; i < plr[p]._pNumInv; i++) { + if (plr[p].InvList[i]._itype != -1) { + if (((plr[p].InvList[i]._iMiscId == IMID_SCROLL) || + (plr[p].InvList[i]._iMiscId == IMID_TSCROLL)) && + (plr[p].InvList[i]._iStatFlag)) { + t = 1; + plr[p]._pScrlSpells |= (t << plr[p].InvList[i]._iSpell-1); + } + } + } + for (i = 0; i < MAXSPD; i++) { + if (plr[p].SpdList[i]._itype != -1) { + if (((plr[p].SpdList[i]._iMiscId == IMID_SCROLL) || + (plr[p].SpdList[i]._iMiscId == IMID_TSCROLL)) && + (plr[p].SpdList[i]._iStatFlag)) { + t = 1; + plr[p]._pScrlSpells |= (t << plr[p].SpdList[i]._iSpell-1); + } + } + } + + if ((plr[p]._pRSplType == SPT_SCROLL) + && ((plr[p]._pScrlSpells & (1 << (plr[p]._pRSpell-1))) == 0)) { + plr[p]._pRSpell = -1; + plr[p]._pRSplType = SPT_NONE; + force_redraw = FULLDRAW; + } + +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrStaff(int p) { + plr[p]._pISpells = 0; + if (plr[p].Hand1Item._itype == -1) return; + if (!plr[p].Hand1Item._iStatFlag) return; + if (plr[p].Hand1Item._iCharges > 0) { + __int64 t = 1; + plr[p]._pISpells |= t << (plr[p].Hand1Item._iSpell - 1); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcSelfItems(int pnum) { + int i; + ItemStruct * pi; + PlayerStruct * p = &plr[pnum]; + BOOL sf, changeflag; + int sa = 0; + int ma = 0; + int da = 0; + + // assume everything works, and calc potential + to str, mag, dex + pi = &p->InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) { + if (pi->_itype == -1) continue; + pi->_iStatFlag = TRUE; + if (!pi->_iIdentified) continue; + sa += pi->_iPLStr; + ma += pi->_iPLMag; + da += pi->_iPLDex; + } + + do { + changeflag = FALSE; + pi = &p->InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) { + if (pi->_itype == -1) continue; + if (!pi->_iStatFlag) continue; + sf = TRUE; + if ((p->_pBaseStr + sa) < pi->_iMinStr) sf = FALSE; + if ((p->_pBaseMag + ma) < pi->_iMinMag) sf = FALSE; + if ((p->_pBaseDex + da) < pi->_iMinDex) sf = FALSE; + if (!sf) { + changeflag = TRUE; + pi->_iStatFlag = FALSE; + if (pi->_iIdentified) { + sa -= pi->_iPLStr; + ma -= pi->_iPLMag; + da -= pi->_iPLDex; + } + } + } + } while (changeflag); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static BOOL ItemMinStats(const PlayerStruct * p,const ItemStruct * x) { + if (p->_pMagic < (byte)x->_iMinMag) return FALSE; + if (p->_pStrength < x->_iMinStr) return FALSE; + if (p->_pDexterity < x->_iMinDex) return FALSE; + return TRUE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrItemMin(int pnum) { + int i; + ItemStruct * pi; + PlayerStruct * p = &plr[pnum]; + + // handle inventory + pi = &p->InvList[0]; + for (i = p->_pNumInv; i--; pi++) + pi->_iStatFlag = ItemMinStats(p,pi); + + // handle speedbar + pi = &p->SpdList[0]; + for (i = MAXSPD; i--; pi++) { + if (pi->_itype == -1) continue; + pi->_iStatFlag = ItemMinStats(p,pi); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrBookVals(int p) +{ + int i, slvl; + + void WitchBookLevel(int); + if (currlevel == 0) { + for (i = 1; witchitem[i]._itype != -1; i++) + WitchBookLevel(i); + } + + for (i = 0; i < plr[p]._pNumInv; i++) { + if ((plr[p].InvList[i]._itype == IT_MISC) && (plr[p].InvList[i]._iMiscId == IMID_BOOK)) { + plr[p].InvList[i]._iMinMag = spelldata[plr[p].InvList[i]._iSpell].sMinInt; + slvl = plr[p]._pSplLvl[plr[p].InvList[i]._iSpell]; + while (slvl != 0) { + plr[p].InvList[i]._iMinMag += ((plr[p].InvList[i]._iMinMag * 20) / 100); + slvl--; + if ((plr[p].InvList[i]._iMinMag + ((plr[p].InvList[i]._iMinMag * 20) / 100)) > 255) { + plr[p].InvList[i]._iMinMag = 255; + slvl = 0; + } + } + plr[p].InvList[i]._iStatFlag = ItemMinStats(&plr[p], &plr[p].InvList[i]); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrInv(int p, BOOL Loadgfx) { + CalcPlrItemMin(p); + CalcSelfItems(p); + CalcPlrItemVals(p, Loadgfx); + CalcPlrItemMin(p); + if (p == myplr) { + CalcPlrBookVals(p); + CalcPlrScrolls(p); + CalcPlrStaff(p); + } + if ((p == myplr) && (currlevel == 0)) RecalcStoreStats(); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlrHandItem(ItemStruct *h, int idata) { + const ItemDataStruct * pAllItem = &AllItemsList[idata]; + + ZeroMemory(h,sizeof(ItemStruct)); + h->_itype = pAllItem->itype; + h->_iCurs = pAllItem->iCurs; + strcpy(h->_iName, pAllItem->iName); + strcpy(h->_iIName, pAllItem->iName); + h->_iLoc = pAllItem->iLoc; + h->_iClass = pAllItem->iClass; + h->_iMinDam = pAllItem->iMinDam; + h->_iMaxDam = pAllItem->iMaxDam; + h->_iAC = pAllItem->iMinAC; + h->_iMiscId = pAllItem->iMiscId; + h->_iSpell = pAllItem->iSpell; + if (pAllItem->iMiscId == IMID_STAFF) h->_iCharges = 18; // was 40 + h->_iMaxCharges = h->_iCharges; + h->_iDurability = pAllItem->iDurability; + h->_iMaxDur = pAllItem->iDurability; + h->_iMinStr = pAllItem->iMinStr; + h->_iMinMag = pAllItem->iMinMag; + h->_iMinDex = pAllItem->iMinDex; + h->_ivalue = pAllItem->iValue; + h->_iIvalue = pAllItem->iValue; + h->_iPrePower = -1; + h->_iSufPower = -1; + h->IDidx = idata; + h->_iMagical = IMAGIC_NONE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetPlrHandSeed(ItemStruct *h) +{ + h->_iSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetGoldSeed(int pnum, ItemStruct *h) +{ + int i, ii, s; + BOOL doneflag; + + do { + doneflag = TRUE; + s = GetRndSeed(); + for (i = 0; i < numitems; i++) { + ii = itemactive[i]; + if (item[ii]._iSeed == s) doneflag = FALSE; + } + if (pnum == myplr) { + for (i = 0; i < plr[pnum]._pNumInv; i++) + if (plr[pnum].InvList[i]._iSeed == s) doneflag = FALSE; + } + } while (!doneflag); + h->_iSeed = s; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlrHandSeed(ItemStruct *h, int iseed) +{ + h->_iSeed = iseed; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlrHandGoldCurs(ItemStruct *h) +{ + if (h->_ivalue >= GOLD_VT2) { + h->_iCurs = ITEM_5GOLD; + } else { + if (h->_ivalue <= GOLD_VT1) h->_iCurs = ITEM_1GOLD; + else h->_iCurs = ITEM_3GOLD; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CreatePlrItems(int p) { + int i; + ItemStruct * pi; + + // zero out carried items + pi = &plr[p].InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) + pi->_itype = -1; + + // zero inventory + ZeroMemory(plr[p].InvGrid,sizeof(plr[p].InvGrid)); + pi = &plr[p].InvList[0]; + for (i = MAXINV; i--; pi++) + pi->_itype = -1; + plr[p]._pNumInv = 0; + + // zero speedbar + pi = &plr[p].SpdList[0]; + for (i = MAXSPD; i--; pi++) + pi->_itype = -1; + + switch (plr[p]._pClass) { + case CLASS_WARRIOR : + // Sword in left + SetPlrHandItem(&plr[p].Hand1Item, IDI_WARRIOR); + GetPlrHandSeed(&plr[p].Hand1Item); + + // Shield in right + SetPlrHandItem(&plr[p].Hand2Item, IDI_WARRSHLD); + GetPlrHandSeed(&plr[p].Hand2Item); + +#if CHEATS + if (!davecheat) { + SetPlrHandItem(&plr[p].HoldItem, IDI_WARRCLUB); + GetPlrHandSeed(&plr[p].HoldItem); + AutoPlace(p, 0, 1, 3, TRUE); + } +#else + // Club in inv + SetPlrHandItem(&plr[p].HoldItem, IDI_WARRCLUB); + GetPlrHandSeed(&plr[p].HoldItem); + AutoPlace(p, 0, 1, 3, TRUE); +#endif + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + break; + + case CLASS_ROGUE : + #if !IS_VERSION(SHAREWARE) + // Bow in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_ROGUE); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + case CLASS_SORCEROR : + #if !IS_VERSION(SHAREWARE) + // Staff in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_SORCEROR); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); // was mana + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); // was mana + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + case CLASS_MONK : + #if !IS_VERSION(SHAREWARE) + // Bow in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_MONK); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + case CLASS_BARD : + #if !IS_VERSION(SHAREWARE) + // Bow in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_BARD); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].Hand2Item, IDI_BARDDAGGER); + GetPlrHandSeed(&plr[p].Hand2Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + } + + SetPlrHandItem(&plr[p].HoldItem, IDI_GOLD); + GetPlrHandSeed(&plr[p].HoldItem); +#if CHEATS + if (!davecheat) { + // 100 Gold + plr[p].HoldItem._ivalue = 100; + plr[p].HoldItem._iCurs = ITEM_1GOLD; + plr[p]._pGold = plr[p].HoldItem._ivalue; + i = plr[p]._pNumInv; + plr[p].InvList[i] = plr[p].HoldItem; + plr[p]._pNumInv++; + plr[p].InvGrid[30] = plr[p]._pNumInv; + } + else { + // 200000 Gold + plr[p].HoldItem._ivalue = 5000; + plr[p].HoldItem._iCurs = ITEM_5GOLD; + plr[p]._pGold = 200000; + for (int j = 0; j < 40; j++) { + GetGoldSeed(p, &plr[p].HoldItem); + i = plr[p]._pNumInv; + plr[p].InvList[i] = plr[p].HoldItem; + plr[p]._pNumInv++; + plr[p].InvGrid[j] = plr[p]._pNumInv; + } + } +#else + // 100 Gold + plr[p].HoldItem._ivalue = 100; + plr[p].HoldItem._iCurs = ITEM_1GOLD; + plr[p]._pGold = plr[p].HoldItem._ivalue; + i = plr[p]._pNumInv; + plr[p].InvList[i] = plr[p].HoldItem; + plr[p]._pNumInv++; + plr[p].InvGrid[30] = plr[p]._pNumInv; +#endif + + CalcPlrItemVals(p,FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL ItemSpaceOk(int i, int j) +{ + int pn, oi; + + if ((i < 0) || (i >= DMAXX) || (j < 0) || (j >= DMAXY)) return(FALSE); + if (dMonster[i][j] != 0) return(FALSE); + if (dPlayer[i][j] != 0) return(FALSE); + if (dItem[i][j] != 0) return(FALSE); + if (dObject[i][j] != 0) { + if (dObject[i][j] > 0) oi = dObject[i][j]-1; + else oi = -(dObject[i][j]+1); + if (object[oi]._oSolidFlag) return(FALSE); + } + if (dObject[i+1][j+1] > 0) { + oi = dObject[i+1][j+1]-1; + if (object[oi]._oSelFlag != OSEL_NONE) return(FALSE); + } + if (dObject[i+1][j+1] < 0) { + oi = -(dObject[i+1][j+1]+1); + if (object[oi]._oSelFlag != OSEL_NONE) return(FALSE); + } + if ((dObject[i+1][j] > 0) && (dObject[i][j+1] > 0)) { + oi = dObject[i+1][j]-1; + if (object[oi]._oSelFlag != OSEL_NONE) { + oi = dObject[i][j+1]-1; + if (object[oi]._oSelFlag != OSEL_NONE) return(FALSE); + } + } + pn = dPiece[i][j]; + if (nSolidTable[pn]) return(FALSE); + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +void DaveISpaceOk(int inum) +{ + int i,j; + + for (j = 0; j < MAXDUNY; j++) { + for (i = 0; i < MAXDUNX; i++) { + if (dItem[i][j] == inum+1) + app_fatal("Item in map already"); + } + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL GetItemSpace(int x, int y, char inum) +{ + int i,j,xx,yy,rs; + BOOL savail; + + // Try surrounding squares + yy = 0; + for (j = (y-1); j <= (y+1); j++) { + xx = 0; + for (i = (x-1); i <= (x+1); i++) { + itemhold[xx][yy] = ItemSpaceOk(i,j); + xx++; + } + yy++; + } + + savail = FALSE; + for (yy = 0; yy < 3; yy++) { + for (xx = 0; xx < 3; xx++) { + if (itemhold[xx][yy]) savail = TRUE; + } + } + + // Must go here so same number of rnd calls on multiplayer machines + rs = random(13, 15) + 1; + + // No fit, no good + if (!savail) return(FALSE); + + // Place item + xx = 0; + yy = 0; + while (rs > 0) { + if (itemhold[xx][yy]) rs--; + if (rs > 0) { + xx++; + if (xx == 3) { + xx = 0; + yy++; + if (yy == 3) yy = 0; + } + } + } + xx = xx + x - 1; + yy = yy + y - 1; + item[inum]._ix = xx; + item[inum]._iy = yy; + //DaveISpaceOk(inum); + dItem[xx][yy] = inum + 1; + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetSuperItemSpace(int x, int y, char inum) +{ + // try normal method first + if (GetItemSpace(x, y, inum)) return; + + int xx, yy; + + // radial search outward until a space is found + for (int l = 2; l < 50; l++) { + for (int j = -l; j <= l; j++) { + yy = y + j; + for (int i = -l; i <= l; i++) { + xx = x + i; + if (! ItemSpaceOk(xx,yy)) continue; + + // drop it + item[inum]._ix = xx; + item[inum]._iy = yy; + //DaveISpaceOk(inum); + dItem[xx][yy] = inum + 1; + return; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetSuperItemLoc(int x, int y, int &xx, int &yy) +{ + // radial search outward until a space is found + for (int l = 1; l < 50; l++) { + for (int j = -l; j <= l; j++) { + yy = y + j; + for (int i = -l; i <= l; i++) { + xx = x + i; + if (ItemSpaceOk(xx,yy)) // found it + return; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CalcItemValue(int i) +{ + int v = item[i]._iVMult1 + item[i]._iVMult2; + if (v > 0) v = item[i]._ivalue * v; + if (v < 0) v = item[i]._ivalue / v; + v += item[i]._iVAdd1 + item[i]._iVAdd2; + if (v <= 0) v = 1; + item[i]._iIvalue = v; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetBookSpell(int i, int lvl) +{ + + if (lvl == 0) lvl = 1; + int rv = random(14, SPL_LAST) + 1; + + #if IS_VERSION(SHAREWARE) + if (lvl > 5) lvl = 5; + #endif + + int bs = SPL_FIREBOLT; + int s = SPL_FIREBOLT; + while (rv > 0) { + if ((spelldata[s].sBookLvl != -1) && (lvl >= spelldata[s].sBookLvl)) { + rv--; + bs = s; + } + + s++; + if ((gbMaxPlayers == 1) && (s == SPL_RESURRECT)) s++; + if ((gbMaxPlayers == 1) && (s == SPL_HEALOTHER)) s++; + if (s == SPL_LAST) s = SPL_FIREBOLT; + } + strcat(item[i]._iName, spelldata[bs].sNameText); + strcat(item[i]._iIName, spelldata[bs].sNameText); + item[i]._iSpell = bs; + item[i]._iMinMag = spelldata[bs].sMinInt; + item[i]._ivalue += spelldata[bs].sBookCost; + item[i]._iIvalue += spelldata[bs].sBookCost; + if (spelldata[bs].sType == ST_FIRE) item[i]._iCurs = ITEM_BOOK3; + if (spelldata[bs].sType == ST_LIGHT) item[i]._iCurs = ITEM_BOOK; + if (spelldata[bs].sType == ST_MISC) item[i]._iCurs = ITEM_BOOK2; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetStaffPower(int i, int lvl, int bs, BOOL onlygood) +{ + int pre; + int l[256], nl; + int j, aii; + int preidx; + char istr[128]; + BOOL addok; + + // Prefix only (for a staff w/ spell) + pre = random(15, 10); + + preidx = -1; + +#if CHEATS + if ((pre == 0) || (cheatflag) || (onlygood)) { +#else + if ((pre == 0) || (onlygood)) { +#endif + nl = 0; + for (j = 0; PL_Prefix[j].PLPower != -1; j++) { + if (((PL_Prefix[j].PLIType & PLF_STAFF) != 0) && (PL_Prefix[j].PLMinLvl <= lvl)) { + addok = TRUE; + if ((onlygood) && (!PL_Prefix[j].PLOk)) addok = FALSE; + + if (addok) { + l[nl] = j; + nl++; + if (PL_Prefix[j].PLDouble) { + l[nl] = j; + nl++; + } + } + } + } + if (nl != 0) { + preidx = l[random(16, nl)]; + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = IMAGIC_MAGIC; + SaveItemPower(i, PL_Prefix[preidx].PLPower, PL_Prefix[preidx].PLParam1, PL_Prefix[preidx].PLParam2, PL_Prefix[preidx].PLMinVal, PL_Prefix[preidx].PLMaxVal, PL_Prefix[preidx].PLMultVal); + item[i]._iPrePower = PL_Prefix[preidx].PLPower; + } + } + if (!InfoFit(item[i]._iIName)) { + aii = item[i].IDidx; + strcpy(item[i]._iIName, AllItemsList[aii].iSName); + if (preidx != -1) { + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + } + sprintf(istr, "%s of %s", item[i]._iIName, spelldata[bs].sNameText); + strcpy(item[i]._iIName, istr); + if (!item[i]._iMagical) strcpy(item[i]._iName, item[i]._iIName); + } + CalcItemValue(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetStaffSpell(int i, int lvl, BOOL onlygood) +{ + int rv, s, bs, l; + char tstr[64]; + int maxc, minc; + + if (random(17, 4) == 0) GetItemPower(i, lvl >> 1, lvl, PLF_STAFF, onlygood); + else { + l = lvl >> 1; + if (l == 0) l = 1; + rv = random(18, SPL_LAST) + 1; + + #if IS_VERSION(SHAREWARE) + if (lvl > 10) lvl = 10; + #endif + + s = SPL_FIREBOLT; + while (rv > 0) { + if ((spelldata[s].sStaffLvl != -1) && (l >= spelldata[s].sStaffLvl)) { + rv--; + bs = s; + } + s++; + if ((gbMaxPlayers == 1) && (s == SPL_RESURRECT)) s++; + if ((gbMaxPlayers == 1) && (s == SPL_HEALOTHER)) s++; + if (s == SPL_LAST) s = SPL_FIREBOLT; + } + sprintf(tstr, "%s of %s", item[i]._iName, spelldata[bs].sNameText); + //Check to see if string will fit + if (!InfoFit(tstr)) { + sprintf(tstr, "Staff of %s", spelldata[bs].sNameText); + } + strcpy(item[i]._iName, tstr); + strcpy(item[i]._iIName, tstr); + item[i]._iSpell = bs; + minc = spelldata[bs].sStaffMin; + maxc = spelldata[bs].sStaffMax; + item[i]._iCharges = random(19, maxc-minc+1) + minc; + item[i]._iMaxCharges = item[i]._iCharges; + item[i]._iMinMag = spelldata[bs].sMinInt; + int v = (spelldata[bs].sStaffCost * item[i]._iCharges) / 5; + item[i]._ivalue += v; + item[i]._iIvalue += v; + GetStaffPower(i, lvl, bs, onlygood); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetOilType(int i, int lvl) +{ + int n, ro, roi, j; + char OilIndexList[30]; + + if (gbMaxPlayers == 1) { + if (lvl == 0) lvl = 1; + n = 0; + for (j=0; j < MAXOIL; j++) { + if (OilLvlTbl[j] <= lvl) { + OilIndexList[n] = j; + n++; + } + } + ro = random(165, n); + roi = OilIndexList[ro]; + } else { + ro = random(165, 2); + if (ro == 0) roi = 5; + else roi = 6; + } + + strcpy(item[i]._iName, OilStr[roi]); + strcpy(item[i]._iIName, OilStr[roi]); + item[i]._iMiscId = OilIdVal[roi]; + item[i]._ivalue = OilValue[roi]; + item[i]._iIvalue = OilValue[roi]; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemAttrs(int i, int idata, int lvl) +{ + int rndv; + + item[i]._itype = AllItemsList[idata].itype; + item[i]._iCurs = AllItemsList[idata].iCurs; + strcpy(item[i]._iName, AllItemsList[idata].iName); + strcpy(item[i]._iIName, AllItemsList[idata].iName); + item[i]._iLoc = AllItemsList[idata].iLoc; + item[i]._iClass = AllItemsList[idata].iClass; + item[i]._iMinDam = AllItemsList[idata].iMinDam; + item[i]._iMaxDam = AllItemsList[idata].iMaxDam; + item[i]._iAC = random(20, AllItemsList[idata].iMaxAC - AllItemsList[idata].iMinAC + 1) + AllItemsList[idata].iMinAC; + item[i]._iFlags = AllItemsList[idata].iFlags; + item[i]._iFlags2 = 0; + item[i]._iMiscId = AllItemsList[idata].iMiscId; + item[i]._iSpell = AllItemsList[idata].iSpell; + item[i]._iMagical = IMAGIC_NONE; + + item[i]._ivalue = AllItemsList[idata].iValue; + item[i]._iIvalue = AllItemsList[idata].iValue; + + item[i]._iVAdd1 = 0; + item[i]._iVMult1 = 0; + item[i]._iVAdd2 = 0; + item[i]._iVMult2 = 0; + + item[i]._iPLDam = 0; + item[i]._iPLToHit = 0; + item[i]._iPLAC = 0; + + item[i]._iPLStr = 0; + item[i]._iPLMag = 0; + item[i]._iPLDex = 0; + item[i]._iPLVit = 0; + + item[i]._iCharges = 0; + item[i]._iMaxCharges = 0; + + item[i]._iDurability = AllItemsList[idata].iDurability; + item[i]._iMaxDur = AllItemsList[idata].iDurability; + item[i]._iMinStr = AllItemsList[idata].iMinStr; + item[i]._iMinMag = AllItemsList[idata].iMinMag; + item[i]._iMinDex = AllItemsList[idata].iMinDex; + + item[i]._iPLFR = 0; + item[i]._iPLLR = 0; + item[i]._iPLMR = 0; + + item[i].IDidx = idata; + + item[i]._iPLDamMod = 0; + item[i]._iPLGetHit = 0; + item[i]._iPLLight = 0; + + item[i]._iSplLvlAdd = 0; + + item[i]._iRequest = FALSE; + + item[i]._iFMinDam = 0; + item[i]._iFMaxDam = 0; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + + item[i]._iPLEnAc = 0; + + item[i]._iPLMana = 0; + item[i]._iPLHP = 0; + + item[i]._iPrePower = -1; + item[i]._iSufPower = -1; + item[i]._iFlags = 0; + item[i]._iFlags2 = 0; + + if (item[i]._iMiscId == IMID_BOOK) GetBookSpell(i, lvl); + + if (item[i]._iMiscId == IMID_OIL) GetOilType(i, lvl); + + if (item[i]._itype == IT_GOLD) { + if (gnDifficulty == D_NORMAL) + rndv = (currlevel * 5) + random(21, currlevel * 10); + if (gnDifficulty == D_NIGHTMARE) + rndv = ((currlevel + 16) * 5) + random(21, (currlevel + 16) * 10); + if (gnDifficulty == D_HELL) + rndv = ((currlevel + 32) * 5) + random(21, (currlevel + 32) * 10); + if (leveltype == 4) rndv += (rndv >> 3); + if (rndv > 5000) rndv = 5000; + item[i]._ivalue = rndv; + if (rndv >= GOLD_VT2) { + item[i]._iCurs = ITEM_5GOLD; + } else { + if (rndv <= GOLD_VT1) item[i]._iCurs = ITEM_1GOLD; + else item[i]._iCurs = ITEM_3GOLD; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndPL(int param1, int param2) +{ + return(random(22, param2 - param1 + 1) + param1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PLVal(int pv, int p1, int p2, int minv, int maxv) +{ + if (p1 == p2) return(minv); + if (minv == maxv) return(minv); + return((((((pv - p1) * 100) / (p2 - p1)) * (maxv - minv)) / 100) + minv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval) +{ + int r, r2; + + r = RndPL(param1, param2); + switch (power) { + case PL_TOHIT: + item[i]._iPLToHit += r; + break; + case PL_NTOHIT: + item[i]._iPLToHit -= r; + break; + case PL_TODAM: + item[i]._iPLDam += r; + break; + case PL_NTODAM: + item[i]._iPLDam -= r; + break; + case PL_DOPPEL: + item[i]._iFlags2 |= IAF2_CLONE; + // fall through + case PL_DAHT: + r = RndPL(param1, param2); + item[i]._iPLDam += r; + if (param1 == 20) r2 = RndPL(1, 5); + if (param1 == 36) r2 = RndPL(6, 10); + if (param1 == 51) r2 = RndPL(11, 15); + if (param1 == 66) r2 = RndPL(16, 20); + if (param1 == 81) r2 = RndPL(21, 30); + if (param1 == 96) r2 = RndPL(31, 40); + if (param1 == 111) r2 = RndPL(41, 50); + if (param1 == 126) r2 = RndPL(51, 75); + if (param1 == 151) r2 = RndPL(76, 100); + item[i]._iPLToHit += r2; + break; + + case PL_NDAHT: + item[i]._iPLDam -= r; + if (param1 == 25) r2 = RndPL(1, 5); + if (param1 == 50) r2 = RndPL(6, 10); + item[i]._iPLToHit -= r2; + break; + case PL_AC: + item[i]._iPLAC += r; + break; + case PL_NAC: + item[i]._iPLAC -= r; + break; + case PL_ACTUALAC: + item[i]._iAC = r; + break; + case PL_NACTULAC: + item[i]._iAC -= r; + break; + case PL_RFIRE: + item[i]._iPLFR += r; + break; + case PL_RLGHT: + item[i]._iPLLR += r; + break; + case PL_RMAG: + item[i]._iPLMR += r; + break; + case PL_RALL: + item[i]._iPLFR += r; + item[i]._iPLLR += r; + item[i]._iPLMR += r; + if (item[i]._iPLFR < 0) item[i]._iPLFR = 0; + if (item[i]._iPLLR < 0) item[i]._iPLLR = 0; + if (item[i]._iPLMR < 0) item[i]._iPLMR = 0; + break; + case PL_SLVL: + item[i]._iSplLvlAdd = r; + break; + case PL_CHRG : + item[i]._iCharges = item[i]._iCharges * param1; + item[i]._iMaxCharges = item[i]._iCharges; + break; + case PL_SPELL : + item[i]._iSpell = param1; + item[i]._iCharges = param2; + item[i]._iMaxCharges = param2; + break; + case PL_FHIT: + item[i]._iFlags |= IAF_FIREHIT; + item[i]._iFlags &= ~IAF_LIGHTHIT; + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + break; + case PL_LHIT: + item[i]._iFlags |= IAF_LIGHTHIT; + item[i]._iFlags &= ~IAF_FIREHIT; + item[i]._iLMinDam = param1; + item[i]._iLMaxDam = param2; + item[i]._iFMinDam = 0; + item[i]._iFMaxDam = 0; + break; + case PL_STR: + item[i]._iPLStr += r; + break; + case PL_NSTR: + item[i]._iPLStr -= r; + break; + case PL_MAG: + item[i]._iPLMag += r; + break; + case PL_NMAG: + item[i]._iPLMag -= r; + break; + case PL_DEX: + item[i]._iPLDex += r; + break; + case PL_NDEX: + item[i]._iPLDex -= r; + break; + case PL_VIT: + item[i]._iPLVit += r; + break; + case PL_NVIT: + item[i]._iPLVit -= r; + break; + case PL_STATS: + item[i]._iPLStr += r; + item[i]._iPLMag += r; + item[i]._iPLDex += r; + item[i]._iPLVit += r; + break; + case PL_NSTATS: + item[i]._iPLStr -= r; + item[i]._iPLMag -= r; + item[i]._iPLDex -= r; + item[i]._iPLVit -= r; + break; + case PL_GETHIT: + item[i]._iPLGetHit += r; + break; + case PL_NGETHIT: + item[i]._iPLGetHit -= r; + break; + case PL_HP: + item[i]._iPLHP += (r << HP_SHIFT); + break; + case PL_NHP: + item[i]._iPLHP -= (r << HP_SHIFT); + break; + case PL_MANA: + item[i]._iPLMana += (r << MANA_SHIFT); + drawmanaflag = TRUE; + break; + case PL_NMANA: + item[i]._iPLMana -= (r << MANA_SHIFT); + drawmanaflag = TRUE; + break; + case PL_DUR: + r2 = (item[i]._iMaxDur * r) / 100; + item[i]._iMaxDur += r2; + item[i]._iDurability += r2; + break; + case PL_FRAGILE: + item[i]._iPLDam += 140 + r * 2; + // fall through + case PL_NDUR: + r2 = (item[i]._iMaxDur * r) / 100; + item[i]._iMaxDur -= r2; + if (item[i]._iMaxDur < 1) item[i]._iMaxDur = 1; + item[i]._iDurability = item[i]._iMaxDur; + break; + case PL_IND: + item[i]._iDurability = INFINITE_DUR; + item[i]._iMaxDur = INFINITE_DUR; + break; + case PL_LIGHT: + item[i]._iPLLight += param1; + break; + case PL_NLIGHT: + item[i]._iPLLight -= param1; + break; + case PL_NUMARWS: + item[i]._iFlags |= IAF_RABID; // unused -> multimissile --donald + break; + case PL_FARROW: + item[i]._iFlags |= IAF_FIREARROW; + item[i]._iFlags &= ~IAF_LARROW; + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + break; + case PL_LARROW: + item[i]._iFlags |= IAF_LARROW; + item[i]._iFlags &= ~IAF_FIREARROW; + item[i]._iLMinDam = param1; + item[i]._iLMaxDam = param2; + item[i]._iFMinDam = 0; + item[i]._iFMaxDam = 0; + break; + case PL_HITADD: // usurped for fireball arrows... + item[i]._iFlags |= (IAF_LARROW | IAF_FIREARROW); + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + break; + case PL_THORN: + item[i]._iFlags |= IAF_THORN; + break; + case PL_LMANA: + item[i]._iFlags |= IAF_LMANA; + drawmanaflag = TRUE; + break; + case PL_NOHEAL: + item[i]._iFlags |= IAF_NOHEAL; + break; + case PL_TRAPDAM: + item[i]._iFlags |= IAF_TRAPDAM; + break; + case PL_BEAR: + item[i]._iFlags |= IAF_KNOCKBACK; + break; + case PL_DAMDEMON: + item[i]._iFlags |= IAF_DAMDEMON; + break; + case PL_ZERORES: + item[i]._iFlags |= IAF_ZERORES; + break; + case PL_MNOHEAL: + item[i]._iFlags |= IAF_MNOHEAL; + break; + case PL_BAT: + if (param1 == 3) item[i]._iFlags |= IAF_BAT10; + if (param1 == 5) item[i]._iFlags |= IAF_BAT20; + drawmanaflag = TRUE; + break; + case PL_LEECH: + if (param1 == 3) item[i]._iFlags |= IAF_LEECH10; + if (param1 == 5) item[i]._iFlags |= IAF_LEECH20; + drawhpflag = TRUE; + break; + case PL_ENAC: + item[i]._iPLEnAc = param1; + break; + case PL_ATANIM: + if (param1 == 1) item[i]._iFlags |= IAF_ATANIM1; + if (param1 == 2) item[i]._iFlags |= IAF_ATANIM2; + if (param1 == 3) item[i]._iFlags |= IAF_ATANIM3; + if (param1 == 4) item[i]._iFlags |= IAF_ATANIM4; + break; + case PL_HTANIM: + if (param1 == 1) item[i]._iFlags |= IAF_HTANIM1; + if (param1 == 2) item[i]._iFlags |= IAF_HTANIM2; + if (param1 == 3) item[i]._iFlags |= IAF_HTANIM3; + break; + case PL_BLANIM: + item[i]._iFlags |= IAF_BLANIM; + break; + case PL_DAMADD: + item[i]._iPLDamMod += r; + break; + case PL_RNDARW: + item[i]._iFlags |= IAF_RNDARROW; + break; + case PL_DAMAGE: + item[i]._iMinDam = param1; + item[i]._iMaxDam = param2; + break; + case PL_DURNUM: + item[i]._iDurability = param1; + item[i]._iMaxDur = param1; + break; + case PL_FALCON: + item[i]._iFlags |= IAF_ATANIM3; + break; + case PL_ONEHAND: + item[i]._iLoc = IL_HAND; + break; + case PL_CONST: + item[i]._iFlags |= IAF_CONSTRICT; + break; + case PL_SKING: + item[i]._iFlags |= IAF_SKING; + break; + case PL_INFRA: + item[i]._iFlags |= IAF_INFRAVISION; + break; + case PL_NSTRREQ: + item[i]._iMinStr = 0; + break; + case PL_GFX: + item[i]._iCurs = param1; + break; + case PL_HARQUN: // usurped for lightning arrows + item[i]._iFlags |= (IAF_LARROW | IAF_FIREARROW); + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 1; + item[i]._iLMaxDam = 0; +#if 0 + //rjs item[i]._iPLHP = (byte)plr[myplr]._pArmorClass + plr[myplr]._pIBonusAC + plr[myplr]._pIAC; + item[i]._iPLHP = plr[myplr]._pIBonusAC + plr[myplr]._pIAC; + item[i]._iPLHP += (plr[myplr]._pDexterity / 5); + item[i]._iPLHP = item[i]._iPLHP << HP_SHIFT; +#endif + break; + case PL_HARQUN2: + item[i]._iFlags |= (IAF_LIGHTHIT | IAF_FIREHIT); + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 2; + item[i]._iLMaxDam = 0; +// item[i]._iAC += ((plr[myplr]._pMaxManaBase >> MANA_SHIFT) / 10); + break; + case PL_HARQUN3: + item[i]._iPLFR = 30 - plr[myplr]._pLevel; + if (item[i]._iPLFR < 0) item[i]._iPLFR = 0; + break; + case PL_NRFIRE: + item[i]._iPLFR -= r; + break; + case PL_NRLGHT: + item[i]._iPLLR -= r; + break; + case PL_NRMAG: + item[i]._iPLMR -= r; + break; + case PL_NRALL: + item[i]._iPLFR -= r; + item[i]._iPLLR -= r; + item[i]._iPLMR -= r; + break; + case PL_DEVAST: + item[i]._iFlags2 |= IAF2_DEVASTATION; + break; + case PL_DECAY: + item[i]._iFlags2 |= IAF2_DECAY; + item[i]._iPLDam += r; + break; + case PL_PERIL: + item[i]._iFlags2 |= IAF2_PERIL; + break; + case PL_RNDDAM: + item[i]._iFlags2 |= IAF2_JESTER; + break; + + case PL_DEMONAC: + item[i]._iFlags2 |= IAF2_DEMONAC; + break; + case PL_UNDEADAC: + item[i]._iFlags2 |= IAF2_UNDEADAC; + break; + + case PL_ACOLYTE: + r2 = ((plr[myplr]._pMaxManaBase >> MANA_SHIFT) * 50 / 100); + item[i]._iPLMana -= (r2 << MANA_SHIFT); + item[i]._iPLHP += (r2 << HP_SHIFT); + break; + case PL_GLADIATR: + r2 = ((plr[myplr]._pMaxHPBase >> HP_SHIFT) * 40 / 100); + item[i]._iPLHP -= (r2 << HP_SHIFT); + item[i]._iPLMana += (r2 << MANA_SHIFT); + break; + } + if ((item[i]._iVAdd1 == 0) && (item[i]._iVMult1 == 0)) { + item[i]._iVAdd1 = PLVal(r, param1, param2, minval, maxval); + item[i]._iVMult1 = multval; + } else { + item[i]._iVAdd2 = PLVal(r, param1, param2, minval, maxval); + item[i]._iVMult2 = multval; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemPower(int i, int minlvl, int maxlvl, long flgs, BOOL onlygood) +{ + int pre, post; + int l[256], nl; + int j, aii; + int preidx, sufidx; + char istr[128]; + byte goe; + + pre = random(23, 4); // Pre modifier (20%) + post = random(23, 3); // Post modifirer (66%) + // if no pre modifier, make sure post modifier + if ((pre != 0) && (post == 0)) { + if (random(23, 2)) post = 1; + else pre = 0; + } + + preidx = -1; + sufidx = -1; + goe = 0; + + // if not any only good item, then 67% chance of good, 33% chance of anything + if ((!onlygood) && (random(0, 3))) onlygood = TRUE; + + if (pre == 0) { + nl = 0; + for (j = 0; PL_Prefix[j].PLPower != -1; j++) { + if (((PL_Prefix[j].PLIType & flgs) != 0) && + (PL_Prefix[j].PLMinLvl >= minlvl) && + (PL_Prefix[j].PLMinLvl <= maxlvl) + ) { + if (onlygood && !PL_Prefix[j].PLOk) continue; + if ((flgs == PLF_STAFF) && (PL_Prefix[j].PLPower == PL_CHRG)) continue; + + l[nl] = j; + nl++; + if (PL_Prefix[j].PLDouble) { + l[nl] = j; + nl++; + } + } + } + if (nl != 0) { + preidx = l[random(23, nl)]; + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = IMAGIC_MAGIC; + SaveItemPower(i, PL_Prefix[preidx].PLPower, PL_Prefix[preidx].PLParam1, PL_Prefix[preidx].PLParam2, PL_Prefix[preidx].PLMinVal, PL_Prefix[preidx].PLMaxVal, PL_Prefix[preidx].PLMultVal); + item[i]._iPrePower = PL_Prefix[preidx].PLPower; + goe = PL_Prefix[preidx].PLGOE; + } + } + if (post != 0) { + nl = 0; + for (j = 0; PL_Suffix[j].PLPower != -1; j++) { + if (((PL_Suffix[j].PLIType & flgs) != 0) && + (PL_Suffix[j].PLMinLvl >= minlvl) && + (PL_Suffix[j].PLMinLvl <= maxlvl) && + ((goe | PL_Suffix[j].PLGOE) != 0x11) + ) { + if (onlygood && !PL_Suffix[j].PLOk) continue; + + l[nl] = j; + nl++; + } + } + if (nl != 0) { + sufidx = l[random(23, nl)]; + sprintf(istr, "%s of %s", item[i]._iIName, PL_Suffix[sufidx].PLName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = IMAGIC_MAGIC; + SaveItemPower(i, PL_Suffix[sufidx].PLPower, PL_Suffix[sufidx].PLParam1, PL_Suffix[sufidx].PLParam2, PL_Suffix[sufidx].PLMinVal, PL_Suffix[sufidx].PLMaxVal, PL_Suffix[sufidx].PLMultVal); + item[i]._iSufPower = PL_Suffix[sufidx].PLPower; + } + } + if (!InfoFit(item[i]._iIName)) { + aii = item[i].IDidx; + strcpy(item[i]._iIName, AllItemsList[aii].iSName); + if (preidx != -1) { + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + } + if (sufidx != -1) { + sprintf(istr, "%s of %s", item[i]._iIName, PL_Suffix[sufidx].PLName); + strcpy(item[i]._iIName, istr); + } + } + if ((preidx != -1) || (sufidx != -1)) CalcItemValue(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemBonus(int i, int idata, int minlvl, int maxlvl, BOOL onlygood) +{ + if (item[i]._iClass == IC_GOLD) return; + if (minlvl > 25) minlvl = 25; + + switch(item[i]._itype) { + case IT_SWORD : + case IT_AXE: + case IT_MACE: + GetItemPower(i, minlvl, maxlvl, PLF_WEAPON, onlygood); + break; + case IT_BOW: + GetItemPower(i, minlvl, maxlvl, PLF_BOW, onlygood); + break; + case IT_SHIELD: + GetItemPower(i, minlvl, maxlvl, PLF_SHIELD, onlygood); + break; + case IT_ARMOR: + case IT_HELM: + case IT_MARMOR: + case IT_HARMOR: + GetItemPower(i, minlvl, maxlvl, PLF_ARMOR, onlygood); + break; + case IT_STAFF: + GetStaffSpell(i, maxlvl, onlygood); + break; + case IT_RING: + case IT_AMULET: + GetItemPower(i, minlvl, maxlvl, PLF_RING, onlygood); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetupItem(int i) +{ + int it; + + DROPLOG("SetupItem: setting up object %d!\n",i); + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimData = itemanims[it]; + item[i]._iAnimLen = ItemAnimLs[it]; + item[i]._iAnimWidth = 96; + item[i]._iAnimWidth2 = 16; + item[i]._iIdentified = FALSE; + item[i]._iPostDraw = FALSE; + if (plr[myplr].pLvlLoad == LVLCHANGE_OFF) { + item[i]._iAnimFrame = 1; + item[i]._iAnimFlag = TRUE; + item[i]._iSelFlag = ISEL_NONE; + } else { + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = FALSE; + item[i]._iSelFlag = ISEL_FLR; + } +} + +/*-----------------------------------------------------------------------* +** Choose an item type from a monster +**-----------------------------------------------------------------------*/ + +int RndItem(int m) +{ + int r; + int ril[512]; // Max 512 items + int ri, i; + + // Unique item? + if (monster[m].MData->mTreasure & T_U) + return(-((monster[m].MData->mTreasure & T_MASK) + 1)); + + if (monster[m].MData->mTreasure & T_NONE) return(0); + +#if CHEATS + if (davedebug) r = 100; + else r = random(24, 100); + if (!cheatflag && (r > 40)) return(0); + if (!cheatflag && (random(24, 100) > 25)) return(IDI_GOLD+1); +#else + r = random(24, 100); + if (r > 40) return(0); + // Gold 75% of the time + if (random(24, 100) > 25) return(IDI_GOLD+1); +#endif + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + if ((AllItemsList[i].iRnd == IRND_DOUBLE) && + (monster[m].mLevel >= AllItemsList[i].iMinMLvl)) ril[ri++] = i; + if (AllItemsList[i].iRnd && + (monster[m].mLevel >= AllItemsList[i].iMinMLvl)) ril[ri++] = i; + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) ri--; + if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) ri--; + } + r = random(24, ri); + return(ril[r]+1); +} + +/*-----------------------------------------------------------------------* +** Choose an item type for a good or unique item +**-----------------------------------------------------------------------*/ + +int RndUItem(int m) +{ + int ril[512]; // Max 512 items + int ri, i; + BOOL okflag; + + // Unique item? + if (m != -1) { + if ((monster[m].MData->mTreasure & T_U) && (gbMaxPlayers == 1)) + return(-((monster[m].MData->mTreasure & T_MASK) + 1)); + } + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + okflag = TRUE; + if (!AllItemsList[i].iRnd) okflag = FALSE; + if (m != -1) { + if (monster[m].mLevel < AllItemsList[i].iMinMLvl) okflag = FALSE; + } else { + if ((currlevel << 1) < AllItemsList[i].iMinMLvl) okflag = FALSE; + } + if (AllItemsList[i].itype == IT_MISC) okflag = FALSE; + if (AllItemsList[i].itype == IT_GOLD) okflag = FALSE; + if (AllItemsList[i].itype == IT_FOOD) okflag = FALSE; + if (AllItemsList[i].iMiscId == IMID_BOOK) okflag = TRUE; + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) okflag = FALSE; + if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) okflag = FALSE; + if (okflag) ril[ri++] = i; + } + return(ril[random(25, ri)]); +} + +/*-----------------------------------------------------------------------* +** Choose any type of item +**-----------------------------------------------------------------------*/ + +int RndAllItems() +{ + int r; + int ril[512]; // Max 512 items + int ri, i; + +#if CHEATS + if (!cheatflag && !itemcheat && (random(26, 100) > 25)) return(IDI_GOLD); +#else + // Gold 75% of the time + if (random(26, 100) > 25) return(IDI_GOLD); +#endif + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && ((currlevel << 1) >= AllItemsList[i].iMinMLvl)) ril[ri++] = i; + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) ri--; + if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) ri--; + } + r = random(26, ri); + return(ril[r]); +} + +/*-----------------------------------------------------------------------* +** Choose an item of a specific type +**-----------------------------------------------------------------------*/ + +int RndTypeItems(int itype, int imid, int level) +{ + int ril[512]; // Max 512 items + int ri, i; + BOOL okflag; + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + okflag = TRUE; + if (!AllItemsList[i].iRnd) okflag = FALSE; + if ((level << 1) < AllItemsList[i].iMinMLvl) okflag = FALSE; + if (AllItemsList[i].itype != itype) okflag = FALSE; + if ((imid != -1) && (AllItemsList[i].iMiscId != imid)) okflag = FALSE; + if (okflag && ri < 512) + ril[ri++] = i; + } + return(ril[random(27, ri)]); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int CheckUnique(int i, int lvl, int uper, BOOL recreate) +{ + int j, idata; + BYTE uok[MAXUITEMS]; + int numu, u; + +#if CHEATS + if (!davedebug || !cheatflag) { + if (random(28, 100) > uper) return(-1); + } +#else + if (random(28, 100) > uper) return(-1); +#endif + + numu = 0; + ZeroMemory(uok,sizeof(uok)); + for (j = 0; UniqueItemList[j].UIItemId != -1; j++) { + idata = item[i].IDidx; + if (UniqueItemList[j].UIItemId != AllItemsList[idata].iItemId) continue; + if (lvl < UniqueItemList[j].UIMinLvl) continue; + if (!recreate && UniqueItemFlag[j] && (gbMaxPlayers == 1)) continue; + uok[j] = TRUE; + numu++; + } + + if (numu == 0) return(-1); + u = random(29, 10); + j = 0; + while (numu > 0) { + if (uok[j]) numu--; + if (numu > 0) { + j++; + if (j == MAXUITEMS) j = 0; + } + } + return(j); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetUniqueItem(int i, int uid) +{ + // Generated + UniqueItemFlag[uid] = TRUE; + // Save abilities + SaveItemPower(i, UniqueItemList[uid].UIPower1, UniqueItemList[uid].UIParam1, UniqueItemList[uid].UIParam2, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 1) + SaveItemPower(i, UniqueItemList[uid].UIPower2, UniqueItemList[uid].UIParam3, UniqueItemList[uid].UIParam4, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 2) + SaveItemPower(i, UniqueItemList[uid].UIPower3, UniqueItemList[uid].UIParam5, UniqueItemList[uid].UIParam6, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 3) + SaveItemPower(i, UniqueItemList[uid].UIPower4, UniqueItemList[uid].UIParam7, UniqueItemList[uid].UIParam8, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 4) + SaveItemPower(i, UniqueItemList[uid].UIPower5, UniqueItemList[uid].UIParam9, UniqueItemList[uid].UIParam10, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 5) + SaveItemPower(i, UniqueItemList[uid].UIPower6, UniqueItemList[uid].UIParam11, UniqueItemList[uid].UIParam12, 0, 0, 1); + // Save name + strcpy(item[i]._iIName, UniqueItemList[uid].UIName); + item[i]._iIvalue = UniqueItemList[uid].UIValue; + if (item[i]._iMiscId == IMID_UNIQUE) item[i]._iSeed = uid; // Save index into UniqueItemList + item[i]._iUid = uid; // Save index into Unique Item List + item[i]._iMagical = IMAGIC_UNIQUE; + item[i]._iCreateInfo |= ICI_UNIQUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnUnique(int uid, int x, int y) +{ + int ii, itype; + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + itype = 0; + while (AllItemsList[itype].iItemId != UniqueItemList[uid].UIItemId) itype++; + GetItemAttrs(ii, itype, currlevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + numitems++; + } +} + + +/*-----------------------------------------------------------------------* +** Items in dungeon have lower durs +**-----------------------------------------------------------------------*/ + +void ItemRndDur(int ii) +{ + if (item[ii]._iDurability == 0) return; + if (item[ii]._iDurability == INFINITE_DUR) return; + item[ii]._iDurability = random(0, item[ii]._iMaxDur >> 1) + (item[ii]._iMaxDur >> 2) + 1; +} + +/*-----------------------------------------------------------------------* +** Setup an item and determine magics +**-----------------------------------------------------------------------*/ + +void SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, BOOL onlygood, BOOL recreate, BOOL pregen) +{ + int iblvl, uid; + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + GetItemAttrs(ii, idx, lvl >> 1); + item[ii]._iCreateInfo = lvl; + if (pregen) item[ii]._iCreateInfo |= ICI_PREGEN; + if (onlygood) item[ii]._iCreateInfo |= ICI_ONLYGOOD; + if (uper == 15) item[ii]._iCreateInfo |= ICI_UPER15; + else if (uper == 1) item[ii]._iCreateInfo |= ICI_UPER1; + if (item[ii]._iMiscId != IMID_UNIQUE) { + iblvl = -1; + if (random(32, 100) <= 10) iblvl = lvl; + else if (random(33, 100) <= lvl) iblvl = lvl; + // Force rings, amulets, and staffs to be magical + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_STAFF)) iblvl = lvl; + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_RING)) iblvl = lvl; + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_AMULET)) iblvl = lvl; + if (onlygood) iblvl = lvl; +#if CHEATS + if (cheatflag) iblvl = lvl; +#endif + if (uper == 15) iblvl = lvl + 4; + if (iblvl != -1) { + uid = CheckUnique(ii, iblvl, uper, recreate); + if (uid == -1) + GetItemBonus(ii, idx, iblvl >> 1, iblvl, onlygood); + else { + GetUniqueItem(ii, uid); + item[ii]._iCreateInfo |= ICI_UNIQUE; + } + } + if (item[ii]._iMagical != IMAGIC_UNIQUE) ItemRndDur(ii); + } else { + // if it is something they wield, then get the attributes + if (item[ii]._iLoc != IL_INV) GetUniqueItem(ii, iseed); + } + SetupItem(ii); +} + +/*-----------------------------------------------------------------------* +** Create any item from a monster (or unqiue if monster gives one up) +**-----------------------------------------------------------------------*/ + +void SpawnItem(int m, int x, int y, BOOL sendmsg) +{ + int ii, idx; + BOOL onlygood; + + if ((monster[m]._uniqtype != 0) || + ((monster[m].MData->mTreasure & T_U) && (gbMaxPlayers != 1))) { + // If unique, make sure we get something good + idx = RndUItem(m); + if (idx < 0) { + SpawnUnique(-(idx+1), x, y); + return; + } + onlygood = TRUE; + } else { + // special code to pop out brain for Mushroom Quest + if (quests[Q_BKMUSHRM]._qactive == QUEST_NOTDONE + && quests[Q_BKMUSHRM]._qvar1 == QS_MUSHGIVEN) { + idx = IDI_BRAIN; + quests[Q_BKMUSHRM]._qvar1 = QS_BRAINSPAWNED; + } + else + { + idx = RndItem(m); + if (idx == 0) return; + if (idx > 0) { + idx--; + onlygood = FALSE; + } else { + SpawnUnique(-(idx+1), x, y); + return; + } + } + } + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + if (monster[m]._uniqtype != 0) SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 15, onlygood, FALSE, FALSE); +#if CHEATS + else if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 15, TRUE, FALSE, FALSE); +#endif + else SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 1, onlygood, FALSE, FALSE); + + numitems++; + if (sendmsg) NetSendCmdDItem(FALSE, ii); + } +} + + +/*-----------------------------------------------------------------------* +** Only used for quest (single player) +**-----------------------------------------------------------------------*/ + +void CreateItem(int uid, int x, int y) +{ + int ii, idx; + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + idx = 0; + while (AllItemsList[idx].iItemId != UniqueItemList[uid].UIItemId) idx++; + GetItemAttrs(ii, idx, currlevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + item[ii]._iMagical = IMAGIC_UNIQUE; + numitems++; + } +} + + +/*-----------------------------------------------------------------------* +** Create any item from an object, etc (chest, barrel, sarc) +**-----------------------------------------------------------------------*/ + +void CreateRndItem(int x, int y, BOOL onlygood, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + + if (onlygood) idx = RndUItem(-1); + else idx = RndAllItems(); + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, onlygood, FALSE, delta); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetupAllUseful(int ii, int iseed, int lvl) +{ + int idx; + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + +#if 0 + if (random(34, 2)) idx = IDI_HEAL; + else idx = IDI_MANA; + + // added 7/30/97 by donald + if (!random(34, 8)) idx = IDI_OILACC; + + if ((lvl > 1) && (random(34, 3) == 0)) idx = IDI_PORTAL; +#else + // why call random() so many times? + + switch(random(34,7)) + { + case 0: idx = IDI_PORTAL; if (lvl > 1) break; // else fallthrough + case 1: + case 2: idx = IDI_HEAL; break; + case 3: idx = IDI_PORTAL; if (lvl > 1) break; // else fallthrough + case 4: + case 5: idx = IDI_MANA; break; + default:idx = IDI_OILACC; break; + } +#endif + + GetItemAttrs(ii, idx, lvl); + item[ii]._iCreateInfo = ICI_USEFUL + lvl; + SetupItem(ii); +} + +/*-----------------------------------------------------------------------* +** Rnd item, but only health, mana, or id +**-----------------------------------------------------------------------*/ + +void CreateRndUseful(int pnum, int x, int y, BOOL sendmsg) +{ + int ii; + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + SetupAllUseful(ii, GetRndSeed(), currlevel); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +** Create any item of a specific type +**-----------------------------------------------------------------------*/ + +void CreateTypeItem(int x, int y, BOOL onlygood, int itype, int imisc, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + + if (itype != IT_GOLD) idx = RndTypeItems(itype, imisc, currlevel); + else idx = 0; + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, onlygood, FALSE, delta); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +** Recreate any item with the proper info +**-----------------------------------------------------------------------*/ + +void RecreateItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue) +{ + int uper; + BOOL onlygood, uavail, pregen; + + // PATCH1.JMM + #if 0 + int i, nIndex; + for(i = 0; i < numitems; i++) { + nIndex = itemactive[i]; + + if(((item[nIndex]._iSeed == iseed) && (item[nIndex]._iCreateInfo == icreateinfo) && (item[nIndex].IDidx == idx))) + DROPLOG(" Creating dupped item: idx->%8.8x seed->%8.8x ci->%8.8x\n",idx,iseed,icreateinfo); + + app_assert(!((item[nIndex]._iSeed == iseed) && (item[nIndex]._iCreateInfo == icreateinfo) && (item[nIndex].IDidx == idx))); + } + #endif + // ENDPATCH1.JMM + + + // Gold + if (idx == IDI_GOLD) { + SetPlrHandItem(&item[ii], idx); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = icreateinfo; + item[ii]._ivalue = ivalue; + if (item[ii]._ivalue >= GOLD_VT2) { + item[ii]._iCurs = ITEM_5GOLD; + } else { + if (ivalue <= GOLD_VT1) item[ii]._iCurs = ITEM_1GOLD; + else item[ii]._iCurs = ITEM_3GOLD; + } + } else { + // One the the players initial items? + if (icreateinfo == 0) { + SetPlrHandItem(&item[ii], idx); + SetPlrHandSeed(&item[ii], iseed); + } else { + // From town? + if (icreateinfo & ICI_TOWNMASK) RecreateTownItem(ii, idx, icreateinfo, iseed, ivalue); + else { + // From dungeon + if ((icreateinfo & ICI_USEFUL) == ICI_USEFUL) { + SetupAllUseful(ii, iseed, icreateinfo & ICI_LVLMASK); + } else { + uper = 0; + onlygood = FALSE; + uavail = FALSE; + pregen = FALSE; + if (icreateinfo & ICI_UPER1) uper = 1; + if (icreateinfo & ICI_UPER15) uper = 15; + if (icreateinfo & ICI_ONLYGOOD) onlygood = TRUE; + if (icreateinfo & ICI_UNIQUE) uavail = TRUE; + if (icreateinfo & ICI_PREGEN) pregen = TRUE; + SetupAllItems(ii, idx, iseed, icreateinfo & ICI_LVLMASK, uper, onlygood, uavail, pregen); + } + } + } + } +} + +/*-----------------------------------------------------------------------* +** Recreate any ear with the proper info +**-----------------------------------------------------------------------*/ + +void RecreateEar(int ii, WORD ic, int iseed, BOOL Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff) +{ + SetPlrHandItem(&item[ii], IDI_EAR); + tempstr[0] = (ic >> 8) & 0x7f; + tempstr[1] = ic & 0x7f; + tempstr[2] = (iseed >> 24) & 0x7f; + tempstr[3] = (iseed >> 16) & 0x7f; + tempstr[4] = (iseed >> 8) & 0x7f; + tempstr[5] = iseed & 0x7f; + tempstr[6] = Id & 0x7f; + tempstr[7] = dur & 0x7f; + tempstr[8] = mdur & 0x7f; + tempstr[9] = ch & 0x7f; + tempstr[10] = mch & 0x7f; + tempstr[11] = (ivalue >> 8) & 0x7f; + tempstr[12] = (ibuff >> 24) & 0x7f; + tempstr[13] = (ibuff >> 16) & 0x7f; + tempstr[14] = (ibuff >> 8) & 0x7f; + tempstr[15] = ibuff & 0x7f; + tempstr[16] = 0; + sprintf(item[ii]._iName, "Ear of %s", tempstr); + item[ii]._iCurs = ((ivalue >> 6) & 0x3) + ITEM_EAR1; + item[ii]._ivalue = ivalue & 0x3f; + item[ii]._iCreateInfo = ic; + item[ii]._iSeed = iseed; +} + + +const char * sgszCornerstone = "SItem"; + +void CornerstoneSave() +{ + if (!CornerStone.Initted) + return; + + PkItemStruct pki; + + if (CornerStone.item.IDidx >= 0) + { + PackItem(&pki, &(CornerStone.item)); + SRegSaveData(gszProgKey,sgszCornerstone,0, &pki, sizeof(PkItemStruct)); + } + else + { + SRegSaveData(gszProgKey,sgszCornerstone, 0, "", 1); + } +} + +void CornerstoneRestore(int x, int y) +{ + // read the info out of the options file + PkItemStruct pki; + + if (x == 0 || y == 0) + return; + + CornerStone.item.IDidx = 0; + CornerStone.Initted = TRUE; + + DWORD bytesread = 0; + if (! SRegLoadData(gszProgKey,sgszCornerstone, 0, &pki, sizeof(PkItemStruct), &bytesread) || + bytesread != sizeof(PkItemStruct)) + { + if (dItem[x][y] != 0) + { + // clear the square + int ii = dItem[x][y] - 1; + for (int i = 0; i < numitems; ++i) + if (itemactive[i] == ii) + { + DeleteItem(ii, i); + break; + } + dItem[x][y] = 0; + } + return; + } + + // create a new item slot + int ii = itemavail[0]; + dItem[x][y] = ii+1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + UnPackItem(&pki, &item[ii]); + item[ii]._ix = x; + item[ii]._iy = y; + + DROPLOG("CornerstoneRestore: respawning object %d!\n",ii); + RespawnItem(ii, FALSE); + CornerStone.item = item[ii]; + + numitems++; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnQuestItem(int itemid, int x,int y, int randarea, int selflag) +{ + int i,j; + BOOL failed; + + if (randarea) { + int tries = 0; + do { + if (++tries > 1000 && randarea > 1) + --randarea; + x = random(0, DMAXX); + y = random(0, DMAXY); + failed = FALSE; + for (i = 0; i < randarea && !failed; i++) + for (j = 0; j < randarea && !failed; j++) + failed = !ItemSpaceOk(x + i, y + j); + } while (failed); + } + + if (numitems < MAXITEMS) { + i = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = i; + item[i]._ix = x; + item[i]._iy = y; + dItem[x][y] = i + 1; + GetItemAttrs(i, itemid, currlevel); + SetupItem(i); + item[i]._iPostDraw = TRUE; + if (selflag != ISEL_NONE) { + // selflag indicates creation of post-flippy item + item[i]._iSelFlag = selflag; + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = FALSE; + } + + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SpawnRock() +{ + int i, ii, ostand; + int xx,yy; + BOOL done = FALSE; + + for (i = 0; i < numobjects && !done; i++) { + ostand = objectactive[i]; + done = (object[ostand]._otype == 23); // OBJ_STAND + + + } + if(done) + { + ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + xx = item[ii]._ix = object[ostand]._ox; + yy = item[ii]._iy = object[ostand]._oy; + dItem[xx][yy] = ii + 1; + GetItemAttrs(ii, IDI_ROCK, currlevel); + SetupItem(ii); + item[ii]._iSelFlag = ISEL_TOP; + item[ii]._iPostDraw = TRUE; + item[ii]._iAnimFrame = 11; + + numitems++; + } +} + +void SpawnSomething(int what, int xx, int yy) +{ + int ii = itemavail[0]; + + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + item[ii]._ix = xx; + item[ii]._iy = yy; + dItem[xx][yy] = ii + 1; + GetItemAttrs(ii, what, currlevel); + SetupItem(ii); + item[ii]._iSelFlag = ISEL_TOP; + item[ii]._iPostDraw = TRUE; + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iIdentified = TRUE; + + numitems++; +} + +void SpawnMap(int xx, int yy) +{ + SpawnSomething(IDI_MAPOFDOOM, xx, yy); +} + +void SpawnBomb(int xx, int yy) +{ + SpawnSomething(IDI_RUNEBOMB, xx, yy); +} + +void SpawnBear(int xx, int yy) +{ + SpawnSomething(IDI_THEODORE, xx, yy); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RespawnItem(int i, BOOL FlipFlag) +{ + int it; + + DROPLOG(" RespawnItem: Respawning item %d!\n",i); + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimData = itemanims[it]; + item[i]._iAnimLen = ItemAnimLs[it]; + item[i]._iAnimWidth = 96; + item[i]._iAnimWidth2 = 16; + item[i]._iPostDraw = FALSE; + item[i]._iRequest = FALSE; + if (FlipFlag) { + item[i]._iAnimFrame = 1; + item[i]._iAnimFlag = TRUE; + item[i]._iSelFlag = ISEL_NONE; + } else { + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = FALSE; + item[i]._iSelFlag = ISEL_FLR; + } + if (item[i]._iCurs == ITEM_ROCK) { + item[i]._iSelFlag = ISEL_FLR; + PlaySfxLoc(ItemAnimSnds[it], item[i]._ix, item[i]._iy); + } + if (item[i]._iCurs == ITEM_INNSIGN) item[i]._iSelFlag = ISEL_FLR; + if (item[i]._iCurs == ITEM_ANVIL) item[i]._iSelFlag = ISEL_FLR; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DeleteItem(int ii, int i) +{ + itemavail[MAXITEMS - numitems] = ii; + numitems--; + if ((numitems > 0) && (i != numitems)) { + itemactive[i] = itemactive[numitems]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int idoppely = DIRTEDGED2; + +void ItemDoppel() +{ + int idoppelx; + ItemStruct *i; + + if (gbMaxPlayers == 1) return; + + for (idoppelx = DIRTEDGED2; idoppelx < (DIRTEDGED2+80); idoppelx++) { + if (dItem[idoppelx][idoppely]) { + i = &item[dItem[idoppelx][idoppely] - 1]; + if ((i->_ix != idoppelx) || (i->_iy != idoppely)) + dItem[idoppelx][idoppely] = 0; + } + } + idoppely++; + if (idoppely == DIRTEDGED2+80) idoppely = DIRTEDGED2; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ProcessItems() +{ + int i, ii, it; + + VerifyItemActiveList(); + + for (i = 0; i < numitems; i++) { + ii = itemactive[i]; + + // Animate Spell GFX + if (item[ii]._iAnimFlag) { + item[ii]._iAnimFrame++; + if (item[ii]._iCurs == ITEM_ROCK) { + if ((item[ii]._iSelFlag == ISEL_FLR) && (item[ii]._iAnimFrame == 11)) + item[ii]._iAnimFrame = 1; + if ((item[ii]._iSelFlag == ISEL_TOP) && (item[ii]._iAnimFrame == 21)) + item[ii]._iAnimFrame = 11; + } else { + if (item[ii]._iAnimFrame == (item[ii]._iAnimLen >> 1)) { + it = ItemCAnimTbl[item[ii]._iCurs]; + PlaySfxLoc(ItemAnimSnds[it], item[ii]._ix, item[ii]._iy); + } + if (item[ii]._iAnimFrame >= item[ii]._iAnimLen) { + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iAnimFlag = FALSE; + item[ii]._iSelFlag = ISEL_FLR; + } + } + } + } + + ItemDoppel(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void FreeItemGFX() +{ + for (int i = 0; i < ITEMFTYPES; i++) + DiabloFreePtr(itemanims[i]); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncItemAnim(int ii) +{ + int a; + + a = ItemCAnimTbl[item[ii]._iCurs]; + item[ii]._iAnimData = itemanims[a]; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemStr(int i) { + + switch (item[i]._itype) { + case IT_GOLD: { + int nGold = item[i]._ivalue; + const char * get_pieces_str(int nGold); + sprintf(infostr,"%i gold %s",nGold,get_pieces_str(nGold)); + } + break; + + default : + int s = item[i]._itype; + if (item[i]._iIdentified) strcpy(infostr, item[i]._iIName); + else strcpy(infostr, item[i]._iName); + if (item[i]._iMagical == IMAGIC_MAGIC) infoclr = ICOLOR_BLUE; + if (item[i]._iMagical == IMAGIC_UNIQUE) infoclr = ICOLOR_GOLD; + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckIdentify(int pnum, int cii) { + ItemStruct * pi; + if (cii < NUM_INVLOC) + pi = &plr[pnum].InvBody[cii]; + else + pi = &plr[pnum].InvList[cii - NUM_INVLOC]; + pi->_iIdentified = TRUE; + CalcPlrInv(pnum,TRUE); + + if (pnum == myplr) + NewCursor(GLOVE_CURS); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void RepairItem(ItemStruct *i, int lvl) { + int d, rep; + + if (i->_iDurability == i->_iMaxDur) return; + // If item already has zero durability, wipe it out + if (i->_iMaxDur <= 0) { + i->_itype = -1; + return; + } + rep = 0; + do { + rep += random(37, lvl) + lvl; + d = i->_iMaxDur / (9 + lvl); + if (d < 1) d = 1; + i->_iMaxDur -= d; + // If I have no max durability, break + if (i->_iMaxDur == 0) { + i->_itype = -1; + return; + } + } while ((i->_iDurability + rep) < i->_iMaxDur); + i->_iDurability += rep; + if (i->_iDurability > i->_iMaxDur) + i->_iDurability = i->_iMaxDur; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoRepair(int pnum, int cii) { + PlayerStruct * p = &plr[pnum]; + PlaySfxLoc(IS_REPAIR, p->_px, p->_py); + + ItemStruct * pi; + if (cii < NUM_INVLOC) + pi = &p->InvBody[cii]; + else + pi = &p->InvList[cii - NUM_INVLOC]; + RepairItem(pi,p->_pLevel); + CalcPlrInv(pnum,TRUE); + + if (pnum == myplr) + NewCursor(GLOVE_CURS); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void RechargeItem(ItemStruct *i, int r) { + if (i->_iCharges == i->_iMaxCharges) return; + + do { + i->_iMaxCharges--; + if (i->_iMaxCharges == 0) { + //i->_itype = -1; + return; + } + i->_iCharges += r; + } while (i->_iCharges < i->_iMaxCharges); + + if (i->_iCharges > i->_iMaxCharges) i->_iCharges = i->_iMaxCharges; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoRecharge(int pnum, int cii) { + PlayerStruct * p = &plr[pnum]; + + ItemStruct * pi; + if (cii < NUM_INVLOC) pi = &p->InvBody[cii]; + else pi = &p->InvList[cii - NUM_INVLOC]; +// rmw.patch1.start.1/14/97 +// if (pi->_itype == IT_STAFF) { + if ((pi->_itype == IT_STAFF) && (pi->_iSpell != SPL_NONE)) { +// rmw.patch1.end.1/14/97 + int sp = pi->_iSpell; + int r = spelldata[sp].sBookLvl; + r = random(38, p->_pLevel / r) + 1; + + RechargeItem(pi, r); + CalcPlrInv(pnum, TRUE); + } + + if (pnum == myplr) NewCursor(GLOVE_CURS); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static BOOL OilItem(ItemStruct * i,const PlayerStruct * p) { + int v; + + if (i->_iClass == IC_ITEM) return(FALSE); + if (i->_iClass == IC_GOLD) return(FALSE); + if (i->_iClass == IC_SPECIAL) return(FALSE); + switch(p->_pOilType) { + case IMID_OILACC : + case IMID_OILMAST : + case IMID_OILSHRP : + if (i->_iClass == IC_ARMOR) return(FALSE); + break; + case IMID_OILDEATH : + if (i->_iClass == IC_ARMOR) return(FALSE); + if (i->_itype == IT_BOW) return(FALSE); + break; + case IMID_OILHARD : + case IMID_OILIMPER : + if (i->_iClass == IC_WEAP) return(FALSE); + break; + } + + switch(p->_pOilType) { + case IMID_OILACC : + if (i->_iPLToHit >= 50) break; + i->_iPLToHit += random(68, 2) + 1; + break; + case IMID_OILMAST : + if (i->_iPLToHit >= 100) break; + i->_iPLToHit += random(68, 3) + 3; + break; + case IMID_OILSHRP : + if (i->_iMaxDam - i->_iMinDam >= 30) break; + i->_iMaxDam += 1; + break; + case IMID_OILDEATH : + if (i->_iMaxDam - i->_iMinDam >= 30) break; + i->_iMinDam += 1; + i->_iMaxDam += 2; + break; + case IMID_OILSKILL : + v = random(68, 6) + 5; + + if (i->_iMinStr > v) { + i->_iMinStr -= v; + } + else { + i->_iMinStr = 0; + } + + if (i->_iMinMag > v) { + i->_iMinMag -= v; + } + else { + i->_iMinMag = 0; + } + + if (i->_iMinDex > v) { + i->_iMinDex -= v; + } + else { + i->_iMinDex = 0; + } + break; + case IMID_OILBLKSM : + if (i->_iMaxDur == INFINITE_DUR) break; +// i->_iDurability = (i->_iDurability + (random(68, 5) + 2)); +// i->_iMaxDur = (i->_iMaxDur + (random(68, 9) + 7)); + if (i->_iDurability < i->_iMaxDur) + { + // fix by 20% + int tmp = i->_iDurability + ((i->_iMaxDur + 4) / 5); + if (tmp > i->_iMaxDur) + tmp = i->_iMaxDur; + i->_iDurability = tmp; + } + else + { + if (i->_iMaxDur >= 100) break; + i->_iMaxDur += 1; + i->_iDurability = i->_iMaxDur; + } + break; + case IMID_OILFORT : + if (i->_iMaxDur == INFINITE_DUR) break; + if (i->_iMaxDur >= 200) break; + v = random(68, 41) + 10; + i->_iMaxDur += v; + i->_iDurability += v; + break; + case IMID_OILPERM : + i->_iDurability = INFINITE_DUR; + i->_iMaxDur = INFINITE_DUR; + break; + case IMID_OILHARD : + if (i->_iAC >= 60) break; + i->_iAC += random(68, 2) + 1; + break; + case IMID_OILIMPER : + if (i->_iAC >= 120) break; + i->_iAC += random(68, 3) + 3; + break; + } + + return(TRUE); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoOil(int pnum, int cii) { + ItemStruct * pi; + PlayerStruct * p = &plr[pnum]; + if (cii < NUM_INVLOC) switch (cii) { + case INVLOC_HEAD: + case INVLOC_HAND1: + case INVLOC_HAND2: + case INVLOC_BODY: + pi = &p->InvBody[cii]; + break; + + default: + return; + } + else { + pi = &p->InvList[cii - NUM_INVLOC]; + } + + if (OilItem(pi,p)) { + CalcPlrInv(pnum,TRUE); + if (pnum == myplr) NewCursor(GLOVE_CURS); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintItemOil(char IDidx) +{ + switch(IDidx) { + case IMID_OILACC : + strcpy(tempstr, "increases a weapon's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "chance to hit"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILMAST : + strcpy(tempstr, "greatly increases a"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "weapon's chance to hit"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILSHRP : + strcpy(tempstr, "increases a weapon's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "damage potential"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILDEATH : + strcpy(tempstr, "greatly increases a weapon's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "damage potential - not bows"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILSKILL : + strcpy(tempstr, "reduces attributes needed"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "to use armor or weapons"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILBLKSM : + strcpy(tempstr, "restores 20% of an"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "item's durability"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILFORT : + strcpy(tempstr, "increases an item's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "current and max durability"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILPERM : + strcpy(tempstr, "makes an item indestructible"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILHARD : + strcpy(tempstr, "increases the armor class"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "of armor and shields"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILIMPER : + strcpy(tempstr, "greatly increases the armor"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "class of armor and shields"); + AddPanelString(tempstr, TEXT_CENTER); + break; +// potions + case IMID_PHEAL : + strcpy(tempstr, "fully recover life"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PLHEAL : + strcpy(tempstr, "recover partial life"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PSHEAL : + strcpy(tempstr, "recover life"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PDHEAL : + strcpy(tempstr, "deadly heal"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PMANA : + strcpy(tempstr, "recover mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PFMANA : + strcpy(tempstr, "fully recover mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ESTR : + strcpy(tempstr, "increase strength"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_EMAG : + strcpy(tempstr, "increase magic"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_EDEX : + strcpy(tempstr, "increase dexterity"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_EVIT : + strcpy(tempstr, "increase vitality"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENSTR : + strcpy(tempstr, "decrease strength"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENMAG : + strcpy(tempstr, "decrease strength"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENDEX : + strcpy(tempstr, "decrease dexterity"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENVIT : + strcpy(tempstr, "decrease vitality"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_REJUV : + strcpy(tempstr, "recover life and mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_FREJUV : + strcpy(tempstr, "fully recover life and mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_RUNEFIRE: + case IMID_RUNEIMMOLATE: + strcpy(tempstr, "sets fire trap"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_RUNELIGHT: + case IMID_RUNENOVA: + strcpy(tempstr, "sets lightning trap"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_RUNESTONE: + strcpy(tempstr, "sets petrification trap"); + AddPanelString(tempstr, TEXT_CENTER); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrintItemPower(char plidx,const ItemStruct * x) { + int v; + + switch(plidx) { + case PL_TOHIT: + case PL_NTOHIT: + sprintf(tempstr, "chance to hit : %+i%%", x->_iPLToHit); + break; + case PL_TODAM: + case PL_NTODAM: + sprintf(tempstr, "%+i%% damage", x->_iPLDam); + break; + case PL_DAHT: + case PL_NDAHT: + sprintf(tempstr, "to hit: %+i%%, %+i%% damage", x->_iPLToHit, x->_iPLDam); + break; + case PL_AC: + case PL_NAC: + sprintf(tempstr, "%+i%% armor", x->_iPLAC); + break; + case PL_ACTUALAC: + sprintf(tempstr, "armor class: %i", x->_iAC); + break; + case PL_NACTULAC: + sprintf(tempstr, "armor class: %i", x->_iAC); + break; + case PL_RFIRE: + case PL_NRFIRE: + if (x->_iPLFR < 75) + sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR); + else + sprintf(tempstr, "Resist Fire : 75%% MAX"); + break; + case PL_RLGHT: + case PL_NRLGHT: + if (x->_iPLLR < 75) + sprintf(tempstr, "Resist Lightning : %+i%%", x->_iPLLR); + else + sprintf(tempstr, "Resist Lightning : 75%% MAX"); + break; + case PL_RMAG: + case PL_NRMAG: + if (x->_iPLMR < 75) + sprintf(tempstr, "Resist Magic : %+i%%", x->_iPLMR); + else + sprintf(tempstr, "Resist Magic : 75%% MAX"); + break; + case PL_RALL: + case PL_NRALL: + if (x->_iPLFR < 75) sprintf(tempstr, "Resist All : %+i%%", x->_iPLFR); + if (x->_iPLFR >= 75) sprintf(tempstr, "Resist All : 75%% MAX"); + break; + case PL_SLVL: + if (x->_iSplLvlAdd == 1 ) strcpy(tempstr, "spells are increased 1 level"); + if (x->_iSplLvlAdd == 2 ) strcpy(tempstr, "spells are increased 2 levels"); + if (x->_iSplLvlAdd < 1 ) strcpy(tempstr, "spells are decreased 1 level"); + break; + case PL_CHRG: + strcpy(tempstr, "Extra charges"); + break; + case PL_SPELL: + sprintf(tempstr, "%i %s charges", x->_iMaxCharges, spelldata[x->_iSpell].sNameText); + break; + case PL_FHIT: + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "Fire hit damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "Fire hit damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case PL_LHIT: + if (x->_iLMinDam == x->_iLMaxDam) + sprintf(tempstr, "Lightning hit damage: %i", x->_iLMinDam); + else + sprintf(tempstr, "Lightning hit damage: %i-%i", x->_iLMinDam, x->_iLMaxDam); + break; + case PL_STR: + case PL_NSTR: + sprintf(tempstr, "%+i to strength", x->_iPLStr); + break; + case PL_MAG: + case PL_NMAG: + sprintf(tempstr, "%+i to magic", x->_iPLMag); + break; + case PL_DEX: + case PL_NDEX: + sprintf(tempstr, "%+i to dexterity", x->_iPLDex); + break; + case PL_VIT: + case PL_NVIT: + sprintf(tempstr, "%+i to vitality", x->_iPLVit); + break; + case PL_STATS: + case PL_NSTATS: + sprintf(tempstr, "%+i to all attributes", x->_iPLStr); + break; + case PL_GETHIT: + case PL_NGETHIT: + sprintf(tempstr, "%+i damage from enemies", x->_iPLGetHit); + break; + case PL_HP: + case PL_NHP: + sprintf(tempstr, "Hit Points : %+i", (x->_iPLHP >> HP_SHIFT)); + break; + case PL_MANA: + case PL_NMANA: + sprintf(tempstr, "Mana : %+i", (x->_iPLMana >> MANA_SHIFT)); + break; + case PL_DUR: + strcpy(tempstr, "high durability"); + break; + case PL_NDUR: + strcpy(tempstr, "decreased durability"); + break; + case PL_IND: + strcpy(tempstr, "indestructible"); + break; + case PL_LIGHT: + v = x->_iPLLight * 10; + sprintf(tempstr, "+%i%% light radius", v); + break; + case PL_NLIGHT: + v = -x->_iPLLight * 10; + sprintf(tempstr, "-%i%% light radius", v); + break; + case PL_NUMARWS: + sprintf(tempstr, "multiple arrows per shot"); + break; + case PL_FARROW: + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "fire arrows damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "fire arrows damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case PL_LARROW: + if (x->_iLMinDam == x->_iLMaxDam) + sprintf(tempstr, "lightning arrows damage %i", x->_iLMinDam); + else + sprintf(tempstr, "lightning arrows damage %i-%i", x->_iLMinDam, x->_iLMaxDam); + break; + case PL_HITADD: // usurped for fireball arrows... + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "fireball damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "fireball damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case PL_THORN: + strcpy(tempstr, "attacker takes 1-3 damage"); + break; + case PL_LMANA: + strcpy(tempstr, "user loses all mana"); + break; + case PL_NOHEAL: + strcpy(tempstr, "you can't heal"); + break; + case PL_TRAPDAM: + strcpy(tempstr, "absorbs half of trap damage"); + break; + case PL_BEAR: + strcpy(tempstr, "knocks target back"); + break; + case PL_DAMDEMON: + strcpy(tempstr, "+200% damage vs. demons"); + break; + case PL_ZERORES: + strcpy(tempstr, "All Resistance equals 0"); + break; + case PL_MNOHEAL: + strcpy(tempstr, "hit monster doesn't heal"); + break; + case PL_BAT: + if (x->_iFlags & IAF_BAT10) strcpy(tempstr, "hit steals 3% mana"); + if (x->_iFlags & IAF_BAT20) strcpy(tempstr, "hit steals 5% mana"); + break; + case PL_LEECH: + if (x->_iFlags & IAF_LEECH10) strcpy(tempstr, "hit steals 3% life"); + if (x->_iFlags & IAF_LEECH20) strcpy(tempstr, "hit steals 5% life"); + break; + case PL_ENAC: + strcpy(tempstr, "penetrates target's armor"); + break; + case PL_ATANIM: + if (x->_iFlags & IAF_ATANIM1) strcpy(tempstr, "quick attack"); + if (x->_iFlags & IAF_ATANIM2) strcpy(tempstr, "fast attack"); + if (x->_iFlags & IAF_ATANIM3) strcpy(tempstr, "faster attack"); + if (x->_iFlags & IAF_ATANIM4) strcpy(tempstr, "fastest attack"); + break; + case PL_HTANIM: + if (x->_iFlags & IAF_HTANIM1) strcpy(tempstr, "fast hit recovery"); + if (x->_iFlags & IAF_HTANIM2) strcpy(tempstr, "faster hit recovery"); + if (x->_iFlags & IAF_HTANIM3) strcpy(tempstr, "fastest hit recovery"); + break; + case PL_BLANIM: + strcpy(tempstr, "fast block"); + break; + case PL_DAMADD: + sprintf(tempstr, "adds %i points to damage", x->_iPLDamMod); + break; + case PL_RNDARW: + strcpy(tempstr, "fires random speed arrows"); + break; + case PL_DAMAGE: + sprintf(tempstr, "unusual item damage"); + break; + case PL_DURNUM: + strcpy(tempstr, "altered durability"); + break; + case PL_FALCON: + strcpy(tempstr, "Faster attack swing"); + // not used + break; + case PL_ONEHAND: + strcpy(tempstr, "one handed sword"); + break; + case PL_CONST: + strcpy(tempstr, "constantly lose hit points"); + break; + case PL_SKING: + strcpy(tempstr, "life stealing"); + break; + case PL_NSTRREQ: + strcpy(tempstr, "no strength requirement"); + break; + case PL_INFRA: + strcpy(tempstr, "see with infravision"); + break; + case PL_GFX: + strcpy(tempstr, " "); + break; + case PL_HARQUN: + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "lightning damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "lightning damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); +// strcpy(tempstr, "Armor class added to life"); + break; + case PL_HARQUN2: + strcpy(tempstr, "charged bolts on hits"); +// strcpy(tempstr, "10% of mana added to armor"); + break; + case PL_HARQUN3: + if (x->_iPLFR <= 0) sprintf(tempstr, " "); + else if (x->_iPLFR >= 1) sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR); + break; + case PL_DEVAST: + strcpy(tempstr, "occasional triple damage"); + break; + case PL_DECAY: + sprintf(tempstr, "decaying %+i%% damage", x->_iPLDam); + break; + case PL_PERIL: + strcpy(tempstr, "2x dmg to monst, 1x to you"); + break; + case PL_RNDDAM: + strcpy(tempstr, "Random 0 - 500% damage"); + break; + case PL_FRAGILE: + sprintf(tempstr, "low dur, %+i%% damage", x->_iPLDam); + break; + case PL_DOPPEL: + sprintf(tempstr, "to hit: %+i%%, %+i%% damage", x->_iPLToHit, x->_iPLDam); + break; + case PL_DEMONAC: + sprintf(tempstr, "extra AC vs demons"); + break; + case PL_UNDEADAC: + sprintf(tempstr, "extra AC vs undead"); + break; + case PL_ACOLYTE: + sprintf(tempstr, "50%% Mana moved to Health"); + break; + case PL_GLADIATR: + sprintf(tempstr, "40%% Health moved to Mana"); + break; + + default: + strcpy(tempstr, "Another ability (NW)"); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawUBack() +{ + DrawCel(88, 487, pSTextBoxCels, 1, 271); + app_assert(gpBuffer); + + __asm { + mov edi,dword ptr [gpBuffer] + add edi,371803 + + xor eax,eax + mov edx,148 +_YLp: mov ecx,132 +_XLp1: stosb + inc edi + loop _XLp1 + stosb + sub edi,1033 + mov ecx,132 +_XLp2: inc edi + stosb + loop _XLp2 + sub edi,1032 + dec edx + jnz _YLp + mov ecx,132 +_XLp3: stosb + inc edi + loop _XLp3 + stosb + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PrintUString(int x, int y, BOOL cjustflag, char str[], char col) +{ + long boffset; + int sl,i,w,tw,yy; + + yy = SStringY[y]; + boffset = nBuffWTbl[yy + 204] + x + 96; + sl = strlen(str); + w = 0; + if (cjustflag) { + tw = 0; + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + tw += fontkern[c]+1; + } + if (tw < 257) w = (257 - tw) >> 1; + boffset += w; + } + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + w += fontkern[c]+1; + if ((c != 0) && (w <= 257)) DrawPanelFont(boffset, c, col); + boffset += fontkern[c]+1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawULine(int y) +{ + long doffset; + + app_assert(gpBuffer); + doffset = nBuffWTbl[SStringY[y] + 198] + 90; + __asm { + mov esi,dword ptr [gpBuffer] + mov edi,esi + add esi,142170 + add edi,dword ptr [doffset] + + mov ebx,502 + + mov edx,3 +_YLp: mov ecx,66 + rep movsd + movsw + add esi,ebx + add edi,ebx + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawUniqueInfo() +{ + int u,y; + + if (chrflag || questlog) return; + u = curruitem._iUid; + DrawUBack(); + PrintUString(0, 2, TRUE, UniqueItemList[u].UIName, ICOLOR_GOLD); + DrawULine(5); + PrintItemPower(UniqueItemList[u].UIPower1, &curruitem); + y = (6 - UniqueItemList[u].UINumPL) + 8; + PrintUString(0, y, TRUE, tempstr, ICOLOR_WHITE); + if (UniqueItemList[u].UINumPL > 1) { + PrintItemPower(UniqueItemList[u].UIPower2, &curruitem); + PrintUString(0, y+2, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 2) { + PrintItemPower(UniqueItemList[u].UIPower3, &curruitem); + PrintUString(0, y+4, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 3) { + PrintItemPower(UniqueItemList[u].UIPower4, &curruitem); + PrintUString(0, y+6, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 4) { + PrintItemPower(UniqueItemList[u].UIPower5, &curruitem); + PrintUString(0, y+8, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 5) { + PrintItemPower(UniqueItemList[u].UIPower6, &curruitem); + PrintUString(0, y+10, TRUE, tempstr, ICOLOR_WHITE); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintItemMisc(const ItemStruct * x) +{ + if (x->_iMiscId == IMID_SCROLL) { + strcpy(tempstr, "Right-click to read"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_TSCROLL) { + strcpy(tempstr, "Right-click to read, then"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "left-click to target"); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId >= IMID_FIRSTPOT) && (x->_iMiscId <= IMID_LASTPOT)) { + PrintItemOil(x->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId > IMID_FIRSTOIL) && (x->_iMiscId < IMID_LASTOIL)) { + PrintItemOil(x->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId > IMID_FIRSTRUNE) && (x->_iMiscId < IMID_LASTRUNE)) { + PrintItemOil(x->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_BOOK) { + strcpy(tempstr, "Right click to read"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_MAPOFDOOM) { + strcpy(tempstr, "Right click to view"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_EAR) { + sprintf(tempstr, "Level : %i", x->_ivalue); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_AURIC) { + strcpy(tempstr, "Doubles gold capacity"); + AddPanelString(tempstr, TEXT_CENTER); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrintItemDetails(const ItemStruct * x) +{ + if (x->_iClass == IC_WEAP) { + if (x->_iMinDam == x->_iMaxDam) + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i Indestructible", x->_iMinDam); + else + sprintf(tempstr, "damage: %i Dur: %i/%i", x->_iMinDam, x->_iDurability, x->_iMaxDur); + } + else + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + else + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iClass == IC_ARMOR) { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "armor: %i Indestructible", x->_iAC); + else + sprintf(tempstr, "armor: %i Dur: %i/%i", x->_iAC, x->_iDurability, x->_iMaxDur); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId == IMID_STAFF) && (x->_iMaxCharges != 0)) { + if (x->_iMinDam == x->_iMaxDam) + sprintf(tempstr, "dam: %i Dur: %i/%i", x->_iMinDam, x->_iDurability, x->_iMaxDur); + else + sprintf(tempstr, "dam: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iPrePower != -1) { + PrintItemPower(x->_iPrePower, x); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iSufPower != -1) { + PrintItemPower(x->_iSufPower, x); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMagical == IMAGIC_UNIQUE) { + AddPanelString("unique item", TEXT_CENTER); + uitemflag = TRUE; + curruitem = *x; + } + PrintItemMisc(x); + if ((x->_iMinStr + x->_iMinMag + x->_iMinDex) != 0) { + strcpy(tempstr, "Required:"); + if (x->_iMinStr != 0) sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + if (x->_iMinMag != 0) sprintf(tempstr, "%s %i Mag", tempstr, (byte) x->_iMinMag); + if (x->_iMinDex != 0) sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + AddPanelString(tempstr, TEXT_CENTER); + } + pinfoflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrintItemDur(const ItemStruct * x) +{ + if (x->_iClass == IC_WEAP) { + if (x->_iMinDam == x->_iMaxDam) + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i Indestructible", x->_iMinDam); + else + sprintf(tempstr, "damage: %i Dur: %i/%i", x->_iMinDam, x->_iDurability, x->_iMaxDur); + } + else + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + else + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, TEXT_CENTER); + if ((x->_iMiscId == IMID_STAFF) && (x->_iMaxCharges != 0)) { + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMagical) { + AddPanelString("Not Identified", TEXT_CENTER); + } + } + if (x->_iClass == IC_ARMOR) { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "armor: %i Indestructible", x->_iAC); + else + sprintf(tempstr, "armor: %i Dur: %i/%i", x->_iAC, x->_iDurability, x->_iMaxDur); + AddPanelString(tempstr, TEXT_CENTER); + if (x->_iMagical) { + AddPanelString("Not Identified", TEXT_CENTER); + } + if ((x->_iMiscId == IMID_STAFF) && (x->_iMaxCharges != 0)) { + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, TEXT_CENTER); + } + } + if ((x->_itype == IT_RING) || (x->_itype == IT_AMULET)) { + AddPanelString("Not Identified", TEXT_CENTER); + } + PrintItemMisc(x); + if ((x->_iMinStr + x->_iMinMag + x->_iMinDex) != 0) { + strcpy(tempstr, "Required:"); + if (x->_iMinStr != 0) sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + if (x->_iMinMag != 0) sprintf(tempstr, "%s %i Mag", tempstr, (byte) x->_iMinMag); + if (x->_iMinDex != 0) sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + AddPanelString(tempstr, TEXT_CENTER); + } + pinfoflag = TRUE; +} + +/*-------------------------------------------------------------------------* +**-------------------------------------------------------------------------*/ + +void UseItem(int p, int Mid, int spl) +{ + long l; + __int64 t; + + switch(Mid) { + case IMID_MEAT : + case IMID_PLHEAL : + l = plr[p]._pMaxHP >> (HP_SHIFT + 2); + l = ((random(39, l) + (l >> 1)) << HP_SHIFT); + if (plr[p]._pClass == CLASS_WARRIOR) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE) l += (l >> 1); + plr[p]._pHitPoints += l; + if (plr[p]._pHitPoints > plr[p]._pMaxHP) plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase += l; + if (plr[p]._pHPBase > plr[p]._pMaxHPBase) plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + break; + case IMID_PHEAL : + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + break; + case IMID_PMANA : + l = plr[p]._pMaxMana >> (MANA_SHIFT + 2); + l = ((random(40, l) + (l >> 1)) << MANA_SHIFT); + if (plr[p]._pClass == CLASS_SORCEROR) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE) l += (l >> 1); + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana += l; + if (plr[p]._pMana > plr[p]._pMaxMana) plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase += l; + if (plr[p]._pManaBase > plr[p]._pMaxManaBase) plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_PFMANA : + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_ESTR : + ModifyPlrStr(p, 1); + break; + case IMID_EMAG : + ModifyPlrMag(p, 1); + + // also give full mana potion effect + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + + break; + case IMID_EDEX : + ModifyPlrDex(p, 1); + break; + case IMID_EVIT : + ModifyPlrVit(p, 1); + + // heal the player, too + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + + break; + case IMID_BOOK : + t = 1; + plr[p]._pMemSpells |= (t << spl-1); + if (plr[p]._pSplLvl[spl] < SPELLCAP) plr[p]._pSplLvl[spl]++; + plr[p]._pMana += spelldata[spl].sManaCost << MANA_SHIFT; + if (plr[p]._pMana > plr[p]._pMaxMana) plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase += spelldata[spl].sManaCost << MANA_SHIFT; + if (plr[p]._pManaBase > plr[p]._pMaxManaBase) plr[p]._pManaBase = plr[p]._pMaxManaBase; + if (p == myplr) CalcPlrBookVals(p); + drawmanaflag = TRUE; + break; + case IMID_REJUV : + l = plr[p]._pMaxHP >> (HP_SHIFT + 2); + l = ((random(39, l) + (l >> 1)) << HP_SHIFT); + if (plr[p]._pClass == CLASS_WARRIOR) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE) l += (l >> 1); + plr[p]._pHitPoints += l; + if (plr[p]._pHitPoints > plr[p]._pMaxHP) plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase += l; + if (plr[p]._pHPBase > plr[p]._pMaxHPBase) plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + l = plr[p]._pMaxMana >> (MANA_SHIFT + 2); + l = ((random(40, l) + (l >> 1)) << MANA_SHIFT); + if (plr[p]._pClass == CLASS_SORCEROR) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE) l += (l >> 1); + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana += l; + if (plr[p]._pMana > plr[p]._pMaxMana) plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase += l; + if (plr[p]._pManaBase > plr[p]._pMaxManaBase) plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_FREJUV : + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_OILACC : + case IMID_OILMAST : + case IMID_OILSHRP : + case IMID_OILDEATH : + case IMID_OILSKILL : + case IMID_OILBLKSM : + case IMID_OILFORT : + case IMID_OILPERM : + case IMID_OILHARD : + case IMID_OILIMPER : + plr[p]._pOilType = Mid; + if (p == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(OIL_CURS); + } + break; + case IMID_SCROLL: + if (spelldata[spl].sTargeted) { + plr[p]._pTSpell = spl; + //plr[p]._pTSplType = SPT_SCROLL; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + } else { + ClrPlrPath(p); + plr[p]._pSpell = spl; + //plr[p]._pSplType = SPT_SCROLL; + plr[p]._pSplType = SPT_NONE; + plr[p]._pSplFrom = SPL_FROMSB; + plr[p].destAction = PCMD_SPELL; + plr[p].destParam1 = cursmx; + plr[p].destParam2 = cursmy; + } + break; + case IMID_TSCROLL: + if (spelldata[spl].sTargeted) { + plr[p]._pTSpell = spl; + //plr[p]._pTSplType = SPT_SCROLL; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + } else { + ClrPlrPath(p); + plr[p]._pSpell = spl; + //plr[p]._pSplType = SPT_SCROLL; + plr[p]._pSplType = SPT_NONE; + plr[p]._pSplFrom = SPL_FROMSB; + plr[p].destAction = PCMD_SPELL; + plr[p].destParam1 = cursmx; + plr[p].destParam2 = cursmy; + } + break; + case IMID_MAPOFDOOM: + InitMapOfDoomView(); + break; + case IMID_SPECTRAL: + ModifyPlrStr(p, 3); + ModifyPlrMag(p, 3); + ModifyPlrDex(p, 3); + ModifyPlrVit(p, 3); + break; + case IMID_RUNEFIRE: + plr[p]._pTSpell = SPL_RUNEOFFIRE; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNELIGHT: + plr[p]._pTSpell = SPL_RUNEOFLIGHT; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNEIMMOLATE: + plr[p]._pTSpell = SPL_RUNEOFIMMOLATION; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNENOVA: + plr[p]._pTSpell = SPL_RUNEOFNOVA; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNESTONE: + plr[p]._pTSpell = SPL_RUNEOFSTONE; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#define MAX_STORE_VAL 140000 +#define MAX_WIRT_VAL 90000 // Wirts stuff is 150% of normal + +BOOL StoreStatOk(ItemStruct *h) +{ + BOOL sf = TRUE; + if (plr[myplr]._pStrength < h->_iMinStr) sf = FALSE; + else if (plr[myplr]._pMagic < (byte)h->_iMinMag) sf = FALSE; + else if (plr[myplr]._pDexterity < h->_iMinDex) sf = FALSE; + return(sf); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL SmithItemOk(int i) +{ + BOOL rv; + + rv = TRUE; + // Selling oil is too powerful for the money received. +// if (AllItemsList[i].iMiscId > IMID_FIRSTOIL && +// AllItemsList[i].iMiscId < IMID_LASTOIL) rv = TRUE; +// else + if (AllItemsList[i].itype == IT_MISC) rv = FALSE; + + if (AllItemsList[i].itype == IT_GOLD) rv = FALSE; + if (AllItemsList[i].itype == IT_FOOD) rv = FALSE; + if (AllItemsList[i].itype == IT_STAFF) rv = FALSE; + if (AllItemsList[i].itype == IT_RING) rv = FALSE; + if (AllItemsList[i].itype == IT_AMULET) rv = FALSE; + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndSmithItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && SmithItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl)) { + ril[ri++] = i; + if (AllItemsList[i].iRnd == IRND_DOUBLE) ril[ri++] = i; + } + } + return(ril[random(50, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void BubbleSwapItem(ItemStruct * a, ItemStruct * b) +{ + ItemStruct h; + + h = *a; + *a = *b; + *b = h; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SortSmith() +{ + int j, k; + BOOL sorted; + + for (k = 0; smithitem[k+1]._itype != -1; k++); + sorted = FALSE; + while ((k > 0) && (!sorted)) { + sorted = TRUE; + for (j = 0; j < k; j++) { + if (smithitem[j].IDidx > smithitem[j+1].IDidx) { + BubbleSwapItem(&smithitem[j], &smithitem[j+1]); + sorted = FALSE; + } + } + k--; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnSmith(int lvl) +{ + int itype; + int i,nsi; + ItemStruct const holditem = item[0]; + + nsi = random(50, 10) + 10; + for (i = 0; i < nsi; i++) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndSmithItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + } while (item[0]._iIvalue > MAX_STORE_VAL); + smithitem[i] = item[0]; + smithitem[i]._iCreateInfo = lvl | ICI_SMITH; + smithitem[i]._iIdentified = TRUE; + smithitem[i]._iStatFlag = StoreStatOk(&smithitem[i]); + } + for (i = nsi; i < MAXSMITHITEMS; i++) smithitem[i]._itype = -1; + SortSmith(); + item[0] = holditem; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PremiumItemOk(int i) +{ + BOOL rv; + + rv = TRUE; + if (AllItemsList[i].itype == IT_MISC) rv = FALSE; + else if (AllItemsList[i].itype == IT_GOLD) rv = FALSE; + else if (AllItemsList[i].itype == IT_FOOD) rv = FALSE; + else if (AllItemsList[i].itype == IT_STAFF) rv = FALSE; + if (gbMaxPlayers != 1) { + if (AllItemsList[i].iMiscId == IMID_OIL) rv = FALSE; + else if (AllItemsList[i].itype == IT_RING) rv = FALSE; + else if (AllItemsList[i].itype == IT_AMULET) rv = FALSE; + } + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndPremiumItem(int minlvl, int maxlvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && PremiumItemOk(i) && + (AllItemsList[i].iMinMLvl >= minlvl) && + (AllItemsList[i].iMinMLvl <= maxlvl)) { + ril[ri++] = i; + } + } + return(ril[random(50, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnOnePremium(int i, int plvl, int myplr) +{ + int itype; + ItemStruct const holditem = item[0]; + int const maxval = MAX_STORE_VAL; + int ivalue; + int iCount = 0; + int maxPlrStr = GetMaxStr(plr[myplr]._pClass); + int maxPlrDex = GetMaxDex(plr[myplr]._pClass); + int maxPlrMag = GetMaxMag(plr[myplr]._pClass); + + // Test in case of bonus + if (maxPlrStr < plr[myplr]._pStrength) + { + maxPlrStr = plr[myplr]._pStrength; + } + maxPlrStr = (int)(maxPlrStr * 1.2); + + if (maxPlrDex < plr[myplr]._pDexterity) + { + maxPlrDex = plr[myplr]._pDexterity; + } + maxPlrDex = (int)(maxPlrDex * 1.2); + + if (maxPlrMag < plr[myplr]._pMagic) + { + maxPlrMag = plr[myplr]._pMagic; + } + maxPlrMag = (int)(maxPlrMag * 1.2); + + +#if CHEATS + if ((plvl > 30) || (davecheat)) plvl = 30; +#else + if (plvl > 30) plvl = 30; +#endif + if (plvl < 1) plvl = 1; + + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndPremiumItem(plvl>>2, plvl) - 1; + GetItemAttrs(0, itype, plvl); + GetItemBonus(0, itype, plvl>>1, plvl, TRUE); + + ivalue = 0; + + switch (item[0]._itype) + { + case IT_ARMOR: + case IT_MARMOR: + case IT_HARMOR: + ivalue = GetHighArmorValue(myplr); + break; + case IT_AXE: + ivalue = GetHighAxeValue(myplr); + break; + case IT_BOW: + ivalue = GetHighBowValue(myplr); + break; + case IT_MACE: + ivalue = GetHighMaceValue(myplr); + break; + case IT_SWORD: + ivalue = GetHighSwordValue(myplr); + break; + case IT_HELM: + ivalue = GetHighHelmValue(myplr); + break; + case IT_STAFF: + ivalue = GetHighStaffValue(myplr); + break; + case IT_RING: + ivalue = GetHighRingValue(myplr); + break; + case IT_AMULET: + ivalue = GetHighAmuletValue(myplr); + break; + } + ivalue = (int)(0.8 * ivalue); + + ++iCount; + + // GWP Make sure we can actually use it. + } while ((item[0]._iIvalue > maxval + || item[0]._iMinStr > maxPlrStr + || item[0]._iMinMag > maxPlrMag + || item[0]._iMinDex > maxPlrDex + || item[0]._iIvalue < ivalue) // already have better. + && iCount < 150 // prevent infinite loops. + ); + + premiumitem[i] = item[0]; + premiumitem[i]._iCreateInfo = plvl | ICI_PREMIUM; + premiumitem[i]._iIdentified = TRUE; + premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + item[0] = holditem; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int premiumlvladd[MAXPREMIUM] = { -1, -1, 0, 0, 0, 0, 1, 1, 2, 3 }; + +void SpawnPremium(int myplr) +{ + int lvl = plr[myplr]._pLevel; + int i; + + // Empty slots? + if (numpremium < MAXPREMIUM) { + for (i = 0; i < MAXPREMIUM; ++i) { + if (premiumitem[i]._itype == -1) + SpawnOnePremium(i, premiumlevel + premiumlvladd[i], myplr); + } + numpremium = MAXPREMIUM; + } + // New items? + while (premiumlevel < lvl) { + premiumlevel++; + premiumitem[0] = premiumitem[2]; + premiumitem[1] = premiumitem[3]; + premiumitem[2] = premiumitem[4]; + premiumitem[3] = premiumitem[5]; + premiumitem[4] = premiumitem[6]; + premiumitem[5] = premiumitem[7]; + premiumitem[6] = premiumitem[8]; + SpawnOnePremium(7, premiumlevel + premiumlvladd[6], myplr); + premiumitem[8] = premiumitem[9]; + SpawnOnePremium(9, premiumlevel + premiumlvladd[7], myplr); + } + +#if 10 != MAXPREMIUM +#error "Fix code for new MAXPREMIUM" +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL WitchItemOk(int i) +{ + BOOL rv; + + rv = FALSE; + if (AllItemsList[i].itype == IT_MISC) rv = TRUE; + if (AllItemsList[i].itype == IT_STAFF) rv = TRUE; + // Will already have the next one + if (AllItemsList[i].iMiscId == IMID_PMANA) rv = FALSE; + if (AllItemsList[i].iMiscId == IMID_PFMANA) rv = FALSE; + if (AllItemsList[i].iSpell == SPL_TOWN) rv = FALSE; + // no healing + if (AllItemsList[i].iMiscId == IMID_PHEAL) rv = FALSE; + if (AllItemsList[i].iMiscId == IMID_PLHEAL) rv = FALSE; + // no oils + if (AllItemsList[i].iMiscId > IMID_FIRSTOIL && + AllItemsList[i].iMiscId < IMID_LASTOIL) + rv = FALSE; + // None of these in single player + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) rv = FALSE; + if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) rv = FALSE; + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndWitchItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && WitchItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl)) ril[ri++] = i; + } + return(ril[random(51, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SortWitch() +{ + int j, k; + BOOL sorted; + + for (k = 3; witchitem[k+1]._itype != -1; k++); + sorted = FALSE; + while ((k > 3) && (!sorted)) { + sorted = TRUE; + for (j = 3; j < k; j++) { + if (witchitem[j].IDidx > witchitem[j+1].IDidx) { + BubbleSwapItem(&witchitem[j], &witchitem[j+1]); + sorted = FALSE; + } + } + k--; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void WitchBookLevel(int ii) +{ + if (witchitem[ii]._iMiscId != IMID_BOOK) return; + witchitem[ii]._iMinMag = spelldata[witchitem[ii]._iSpell].sMinInt; + int slvl = plr[myplr]._pSplLvl[witchitem[ii]._iSpell]; + while (slvl != 0) { + witchitem[ii]._iMinMag += ((witchitem[ii]._iMinMag * 20) / 100); + slvl--; + if ((witchitem[ii]._iMinMag + ((witchitem[ii]._iMinMag * 20) / 100)) > 255) { + witchitem[ii]._iMinMag = 255; + slvl = 0; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnWitch(int lvl) +{ + int itype, iblvl; + int i,nsi; + + // Will always have mana (endless supply) + GetItemAttrs(0, IDI_MANA, 1); + witchitem[0] = item[0]; + witchitem[0]._iCreateInfo = lvl; + witchitem[0]._iStatFlag = TRUE; + GetItemAttrs(0, IDI_FULLMANA, 1); + witchitem[1] = item[0]; + witchitem[1]._iCreateInfo = lvl; + witchitem[1]._iStatFlag = TRUE; + GetItemAttrs(0, IDI_PORTAL, 1); + witchitem[2] = item[0]; + witchitem[2]._iCreateInfo = lvl; + witchitem[2]._iStatFlag = TRUE; + + nsi = random(51, 8) + 10; + for (i = 3; i < nsi; i++) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndWitchItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + iblvl = -1; + if (random(51, 100) <= 5) iblvl = lvl << 1; + // Force staffs to be magical + if ((iblvl == -1) && (item[0]._iMiscId == IMID_STAFF)) iblvl = lvl << 1; +#if CHEATS + if (cheatflag) iblvl = lvl << 1; +#endif + if (iblvl != -1) GetItemBonus(0, itype, iblvl >> 1, iblvl, TRUE); + } while (item[0]._iIvalue > MAX_STORE_VAL); + witchitem[i] = item[0]; + witchitem[i]._iCreateInfo = lvl | ICI_WITCH; + witchitem[i]._iIdentified = TRUE; + WitchBookLevel(i); + witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + //WitchBookLevel(i); + } + for (i = nsi; i < MAXWITCHITEMS; i++) witchitem[i]._itype = -1; + SortWitch(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndBoyItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && PremiumItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl)) ril[ri++] = i; + } + return(ril[random(49, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnBoy(int lvl) +{ + int itype; + + if ((boylevel < (lvl >> 1)) || (boyitem._itype == -1)) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndBoyItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + // Always magical + GetItemBonus(0, itype, lvl, lvl << 1, TRUE); + } while (item[0]._iIvalue > MAX_WIRT_VAL); + boyitem = item[0]; + boyitem._iCreateInfo = lvl | ICI_BOY; + boyitem._iIdentified = TRUE; + boyitem._iStatFlag = StoreStatOk(&boyitem); + boylevel = lvl >> 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL HealerItemOk(int i) +{ + BOOL rv; + + rv = FALSE; + if (AllItemsList[i].itype != IT_MISC) return(FALSE); + // Heal scrolls + if ((AllItemsList[i].iMiscId == IMID_SCROLL) && (AllItemsList[i].iSpell == SPL_HEAL)) rv = TRUE; + // Will always have Resurrect scrolls (multiplayer only) + if ((AllItemsList[i].iMiscId == IMID_TSCROLL) && (AllItemsList[i].iSpell == SPL_RESURRECT) && (gbMaxPlayers != 1)) rv = FALSE; + // Heal Other scroll (multiplayer only) + if ((AllItemsList[i].iMiscId == IMID_TSCROLL) && (AllItemsList[i].iSpell == SPL_HEALOTHER) && (gbMaxPlayers != 1)) rv = TRUE; + // Elixirs + if (gbMaxPlayers == 1) { + if (AllItemsList[i].iMiscId == IMID_ESTR + && plr[myplr]._pBaseStr < MaxStats[plr[myplr]._pClass][0]) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_EMAG + && plr[myplr]._pBaseMag < MaxStats[plr[myplr]._pClass][1]) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_EDEX + && plr[myplr]._pBaseDex < MaxStats[plr[myplr]._pClass][2]) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_EVIT + && plr[myplr]._pBaseVit < MaxStats[plr[myplr]._pClass][3]) rv = TRUE; + } + // Potions + if (AllItemsList[i].iMiscId == IMID_PHEAL) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_REJUV) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_FREJUV) rv = TRUE; + // Will always have these + else if (AllItemsList[i].iMiscId == IMID_PLHEAL) rv = FALSE; + else if (AllItemsList[i].iMiscId == IMID_PHEAL) rv = FALSE; + // No mana + else if (AllItemsList[i].iMiscId == IMID_PMANA) rv = FALSE; + else if (AllItemsList[i].iMiscId == IMID_PFMANA) rv = FALSE; + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndHealerItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && HealerItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl)) ril[ri++] = i; + } + return(ril[random(50, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SortHealer() +{ + int j, k; + BOOL sorted; + + for (k = 2; healitem[k+1]._itype != -1; k++); + sorted = FALSE; + while ((k > 2) && (!sorted)) { + sorted = TRUE; + for (j = 2; j < k; j++) { + if (healitem[j].IDidx > healitem[j+1].IDidx) { + BubbleSwapItem(&healitem[j], &healitem[j+1]); + sorted = FALSE; + } + } + k--; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnHealer(int lvl) +{ + int itype; + int i,nsi,srnd; + + // Will always have healing (endless supply) + GetItemAttrs(0, IDI_HEAL, 1); + healitem[0] = item[0]; + healitem[0]._iCreateInfo = lvl; + healitem[0]._iStatFlag = TRUE; + GetItemAttrs(0, IDI_FULLHEAL, 1); + healitem[1] = item[0]; + healitem[1]._iCreateInfo = lvl; + healitem[1]._iStatFlag = TRUE; + if (gbMaxPlayers != 1) { + GetItemAttrs(0, IDI_RESURRECT, 1); + healitem[2] = item[0]; + healitem[2]._iCreateInfo = lvl; + healitem[2]._iStatFlag = TRUE; + srnd = 3; + } else srnd = 2; + + nsi = random(50, 8) + 10; + for (i = srnd; i < nsi; i++) { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndHealerItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + healitem[i] = item[0]; + healitem[i]._iCreateInfo = lvl | ICI_HEALER; + healitem[i]._iIdentified = TRUE; + healitem[i]._iStatFlag = StoreStatOk(&healitem[i]); + } + for (i = nsi; i < MAXHEALITEMS; i++) healitem[i]._itype = -1; + SortHealer(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnStoreGold() +{ + // Setup a gold item to place in inv if they sell + GetItemAttrs(0, 0, 1); + golditem = item[0]; + golditem._iStatFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateSmithItem(int ii, int idx, int lvl, int iseed) +{ + SetRndSeed(iseed); + int itype = RndSmithItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_SMITH; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreatePremiumItem(int ii, int idx, int plvl, int iseed) +{ + SetRndSeed(iseed); + int itype = RndPremiumItem(plvl>>2, plvl) - 1; + GetItemAttrs(ii, itype, plvl); + GetItemBonus(ii, itype, plvl>>1, plvl, TRUE); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = plvl | ICI_PREMIUM; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateBoyItem(int ii, int idx, int lvl, int iseed) +{ + SetRndSeed(iseed); + int itype = RndBoyItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + // Always magical + GetItemBonus(ii, itype, lvl, lvl << 1, TRUE); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_BOY; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateWitchItem(int ii, int idx, int lvl, int iseed) +{ + if ((idx == IDI_MANA) || (idx == IDI_FULLMANA) || (idx == IDI_PORTAL)) { + GetItemAttrs(ii, idx, lvl); + } else { + SetRndSeed(iseed); + int itype = RndWitchItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + int iblvl = -1; + if (random(51, 100) <= 5) iblvl = lvl << 1; + // Force staffs to be magical + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_STAFF)) iblvl = lvl << 1; +#if CHEATS + if (cheatflag) iblvl = lvl << 1; +#endif + if (iblvl != -1) GetItemBonus(ii, itype, iblvl >> 1, iblvl, TRUE); + } + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_WITCH; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateHealerItem(int ii, int idx, int lvl, int iseed) +{ + if ((idx == IDI_HEAL) || (idx == IDI_FULLHEAL) || (idx == IDI_RESURRECT)) { + GetItemAttrs(ii, idx, lvl); + } else { + SetRndSeed(iseed); + int itype = RndHealerItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + } + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_HEALER; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +** Recreate any item with the proper info +**-----------------------------------------------------------------------*/ + +void RecreateTownItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue) +{ + if (icreateinfo & ICI_SMITH) RecreateSmithItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_PREMIUM) RecreatePremiumItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_BOY) RecreateBoyItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_WITCH) RecreateWitchItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_HEALER) RecreateHealerItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DaveGold() +{ + int i,j; + + for (j = 0; j < MAXINV; j++) { + if (plr[myplr].InvGrid[j] == 0) { + i = plr[myplr]._pNumInv; + SetPlrHandItem(&plr[myplr].InvList[i], IDI_GOLD); + GetGoldSeed(myplr, &plr[myplr].InvList[i]); + plr[myplr].InvList[i]._ivalue = 5000; + plr[myplr].InvList[i]._iCurs = ITEM_5GOLD; + plr[myplr].InvList[i]._iStatFlag = TRUE; + plr[myplr]._pGold += 5000; + plr[myplr]._pNumInv++; + plr[myplr].InvGrid[j] = plr[myplr]._pNumInv; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DaveNewPremium() +{ + numpremium = 0; + for (int i = 0; i < MAXPREMIUM; i++) premiumitem[i]._itype = -1; + SpawnPremium(30); + for (i = 0; i < MAXWITCHITEMS; i++) witchitem[i]._itype = -1; + SpawnWitch(30); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DaveCleanUp() +{ + int i,j; + + for (j = 0; j < MAXINV; j++) { + if (plr[myplr].InvGrid[j] > 0) { + i = plr[myplr].InvGrid[j]-1; + if (plr[myplr].InvList[i]._itype == IT_GOLD) RemoveInvItem(myplr, i); + } + } + for (j = 0; j < MAXSPD; j++) { + if (plr[myplr].SpdList[j]._itype == IT_GOLD) plr[myplr].SpdList[j]._itype = -1; + } + plr[myplr]._pGold = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DaveSpells() +{ + for (int i = SPL_FIREBOLT; i < SPL_LAST; i++) { + if (spelldata[i].sBookLvl != -1) { + __int64 t = 1; + plr[myplr]._pMemSpells |= (t << (i-1)); + plr[myplr]._pSplLvl[i] = 10; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DaveSetSpell(int spl, int lvl) +{ + __int64 t = 1; + plr[myplr]._pMemSpells |= (t << (spl-1)); + plr[myplr]._pSplLvl[spl] = lvl; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DaveSpells2() +{ + DaveSetSpell(SPL_FIREBOLT, 8); + DaveSetSpell(SPL_CBOLT, 11); + DaveSetSpell(SPL_HBOLT, 10); + DaveSetSpell(SPL_HEAL, 7); + DaveSetSpell(SPL_HEALOTHER, 5); + DaveSetSpell(SPL_LIGHTNING, 9); + DaveSetSpell(SPL_WALL, 5); + DaveSetSpell(SPL_TELEKINESIS, 3); + DaveSetSpell(SPL_TOWN, 3); + DaveSetSpell(SPL_FLASH, 3); + DaveSetSpell(SPL_PHASE, 2); + DaveSetSpell(SPL_MANASHLD, 2); + DaveSetSpell(SPL_WAVE, 4); + DaveSetSpell(SPL_FIREBALL, 3); + DaveSetSpell(SPL_STONE, 1); + DaveSetSpell(SPL_CHAIN, 1); + DaveSetSpell(SPL_GUARDIAN, 4); + DaveSetSpell(SPL_ELEMENT, 3); + DaveSetSpell(SPL_NOVA, 1); + DaveSetSpell(SPL_GOLEM, 2); + DaveSetSpell(SPL_BSTAR, 1); + DaveSetSpell(SPL_BONESPIRIT, 1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RecalcStoreStats() +{ + int i; + + for (i = 0; i < MAXSMITHITEMS; i++) + if (smithitem[i]._itype != -1) smithitem[i]._iStatFlag = StoreStatOk(&smithitem[i]); + for (i = 0; i < MAXPREMIUM; i++) + if (premiumitem[i]._itype != -1) premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + for (i = 0; i < MAXWITCHITEMS; i++) + if (witchitem[i]._itype != -1) witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + for (i = 0; i < MAXHEALITEMS; i++) + if (healitem[i]._itype != -1) healitem[i]._iStatFlag = StoreStatOk(&healitem[i]); + boyitem._iStatFlag = StoreStatOk(&boyitem); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int ItemNoFlippy() +/*-----------------------------------------------------------------------** +** DESCRIPTION: Makes it so a newly created item will not have a flippy. +** INPUT: None +** RETURN: r = The item number if needed. +/*-----------------------------------------------------------------------*/ +{ + int r; + + r = itemactive[numitems-1]; + item[r]._iAnimFrame = item[r]._iAnimLen; + item[r]._iAnimFlag = FALSE; + item[r]._iSelFlag = ISEL_FLR; + + return r; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if CHEATS +void DaveQuestText() +{ + if (!tstQMsgIndexFlag) { + tstQMsgFlag = TRUE; + InitQTextMsg(tstQMsgIndex); + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateSpellBook(int x, int y, int ispell, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done = FALSE; + + int bookminlevel = spelldata[ispell].sBookLvl + 1; + + if (bookminlevel < 1) // unavailable + return; + + idx = RndTypeItems(IT_MISC, IMID_BOOK, currlevel); + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the book requested + do { + SetupAllItems(ii, idx, GetRndSeed(), /* currlevel */ bookminlevel << 1, 1, TRUE, FALSE, delta); + if ((item[ii]._iMiscId == IMID_BOOK) && + (item[ii]._iSpell == ispell)) { + done = TRUE; + } + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateMagicArmor(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done = FALSE; + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the armor requested + idx = RndTypeItems(imisc, IMID_NONE, currlevel); + do { +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, TRUE, FALSE, delta); + if (item[ii]._iCurs == icurs) { + done = TRUE; + } else idx = RndTypeItems(imisc, IMID_NONE, currlevel); + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateAmulet(int x, int y, int level, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + bool done = false; + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the amulet requested + idx = RndTypeItems(IT_AMULET, IMID_AMULET, level); + do { +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), level << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), level << 1, 1, TRUE, FALSE, delta); + if (item[ii]._iCurs == ITEM_AMULET1) { + done = true; + } else idx = RndTypeItems(IT_AMULET, IMID_AMULET, level); + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateMagicWeapon(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done = FALSE; + int const imid = (imisc == IT_STAFF) ? IMID_STAFF : IMID_NONE; + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the weapon requested + idx = RndTypeItems(imisc, imid, currlevel); + do { +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), currlevel << 1, 1, TRUE, FALSE, delta); + if (item[ii]._iCurs == icurs) { + done = TRUE; + } else idx = RndTypeItems(imisc, imid, currlevel); + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + + +// PATCH1.JMM +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DeleteGetRecord( int nIndex ) { + app_assert(nIndex < gnNumGetRecords); + app_assert(gnNumGetRecords > 0); + + gnNumGetRecords--; + + if(gnNumGetRecords == 0) + return; + + itemgets[nIndex].nIndex = itemgets[gnNumGetRecords].nIndex; + itemgets[nIndex].nSeed = itemgets[gnNumGetRecords].nSeed; + itemgets[nIndex].wCI = itemgets[gnNumGetRecords].wCI; + itemgets[nIndex].dwTimestamp = itemgets[gnNumGetRecords].dwTimestamp; +} + + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define RESEND_TIME 6000 // number of milliseconds to keep a getrecord around + +BOOL CheckGetRecord( int nSeed, WORD wCI, int nIndex ) { + DWORD dwCurr = GetTickCount(); + int i; + + for(i = 0; i < gnNumGetRecords; i++) { + if( (dwCurr - itemgets[i].dwTimestamp) > RESEND_TIME ) { + DeleteGetRecord( i ); + i--; + continue; + } + + if( (nSeed == itemgets[i].nSeed) && (wCI == itemgets[i].wCI) && (nIndex == itemgets[i].nIndex) ) + return FALSE; + + } + + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddGetRecord( int nSeed, WORD wCI, int nIndex ) { + DWORD dwCurr = GetTickCount(); + + if(gnNumGetRecords == MAXITEMS) + return; + + itemgets[gnNumGetRecords].dwTimestamp = dwCurr; + itemgets[gnNumGetRecords].nSeed = nSeed; + itemgets[gnNumGetRecords].wCI = wCI; + itemgets[gnNumGetRecords].nIndex = nIndex; + + gnNumGetRecords++; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RemoveGetRecord( int nSeed, WORD wCI, int nIndex ) { + DWORD dwCurr = GetTickCount(); + int i; + + for(i = 0; i < gnNumGetRecords; i++) { + if( (dwCurr - itemgets[i].dwTimestamp) > RESEND_TIME ) { + DeleteGetRecord( i ); + i--; + continue; + } + + if( (nSeed == itemgets[i].nSeed) && (wCI == itemgets[i].wCI) && (nIndex == itemgets[i].nIndex) ) { + DeleteGetRecord( i ); + return; + } + + } + +} + + +//ENDPATCH1.JMM diff --git a/ITEMS.CPP b/ITEMS.CPP new file mode 100644 index 0000000..60de545 --- /dev/null +++ b/ITEMS.CPP @@ -0,0 +1,5992 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Items file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/ITEMS.CPP 4 2/06/97 6:08p Jessmac $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "objects.h" +#include "items.h" +#include "itemdat.h" +#include "engine.h" +#include "gendung.h" +#include "player.h" +#include "control.h" +#include "monster.h" +#include "spells.h" +#include "quests.h" +#include "cursor.h" +#include "effects.h" +#include "lighting.h" +#include "stores.h" +#include "spelldat.h" +#include "scrollrt.h" +#include "inv.h" +#include "msg.h" +#include "multi.h" +#include "monstdat.h" +#include "doom.h" +#include "missiles.h" +#include "minitext.h" +#include "storm/h/storm.h" +#include "DRLG_l1.h" +#include "packplr.h" +#include "textdat.h" + + +void RecreateTownItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue); +void SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval); +void GetItemPower(int i, int minlvl, int maxlvl, long flgs, BOOL onlygood); +void GetItemAttrs(int i, int idata, int lvl); +void SetupItem(int); +void RecalcStoreStats(); +void SpawnMap(); +void DeleteItem(int ii, int i); + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ +CornerStoneType CornerStone; +extern char gszProgKey[]; + +int GOLD_VMAX = 5000; +const int GOLD_DOUBLE_VMAX = 2 * GOLD_VMAX; +ItemStruct item[MAXITEMS+1]; +long numitems = 0; + +int itemactive[MAXITEMS]; +int itemavail[MAXITEMS]; +int tem; + +//PATCH1.JMM +ItemGetRecordStruct itemgets[MAXITEMS]; +int gnNumGetRecords = 0; +//ENDPATCH1.JMM + + + +BOOL UniqueItemFlag[MAXUITEMS]; +BOOL uitemflag; +ItemStruct curruitem; +#if CHEATS +extern BOOL itemcheat; + +BOOL davecheat = FALSE; +#endif + +BOOL itemhold[3][3]; + + +#define MAXOIL 10 + +int OilLvlTbl[MAXOIL]= { 1, 10, 1, 10, 4, 1, 5, 17, 1, 10 }; +int OilValue[MAXOIL] = { 500, 2500, 500, 2500, 1500, 100, 2500, 15000, 500, 2500 }; +int OilIdVal[MAXOIL] = { + IMID_OILACC, + IMID_OILMAST, + IMID_OILSHRP, + IMID_OILDEATH, + IMID_OILSKILL, + IMID_OILBLKSM, + IMID_OILFORT, + IMID_OILPERM, + IMID_OILHARD, + IMID_OILIMPER +}; +char OilStr[MAXOIL][25] = { + "Oil of Accuracy", + "Oil of Mastery", + "Oil of Sharpness", + "Oil of Death", + "Oil of Skill", + "Blacksmith Oil", + "Oil of Fortitude", + "Oil of Permanence", + "Oil of Hardening", + "Oil of Imperviousness" +}; + +BYTE ItemCAnimTbl[ITEM_LAST_ID] = { + // 1x1 + 20, // ITEM_BLUEBTL + 16, // ITEM_SCROLL + 16, // ITEM_SCROLL2 + 16, // ITEM_SCROLL3 + 4, // ITEM_1GOLD + 4, // ITEM_3GOLD + 4, // ITEM_5GOLD + 12, // ITEM_GOLDRING + 12, // ITEM_1JRING + 12, // ITEM_WOODRING + 12, // ITEM_BLUERING + 12, // ITEM_3JRING + 12, // ITEM_SLVRRING + 12, // ITEM_MJRING + 12, // ITEM_BRNRING + 21, // ITEM_SPECTRAL + 21, // ITEM_3COLORPOT + 25, // ITEM_GOLDENELIX + 12, // ITEM_EMPYBAND + 28, // ITEM_EAR1 + 28, // ITEM_EAR2 + 28, // ITEM_EAR3 + 38, // ITEM_SPHERE + 38, // ITEM_CUBE + 38, // ITEM_PYRIMID + 32, // ITEM_BLOODGEM + 38, // ITEM_JSPHERE + 38, // ITEM_JCUBE + 38, // ITEM_JPYRIMID + 24, // ITEM_VILE + 24, // ITEM_BLKBTL + 26, // ITEM_WHTEBTL + 2, // ITEM_REDBTL + 25, // ITEM_YELBTL + 22, // ITEM_ORGBTL + 23, // ITEM_BREDBTL + 24, // ITEM_BLKBTL2 + 25, // ITEM_GOLDBTL + 27, // ITEM_LTBLUEBTL + 27, // ITEM_BLUEBTL2 + 29, // ITEM_BRAIN + 0, // ITEM_CLAW + 0, // ITEM_FANG + 0, // ITEM_BREAD + 12, // ITEM_AMULET + 12, // ITEM_AMULET1 + 12, // ITEM_AMULET2 + 12, // ITEM_AMULET3 + 12, // ITEM_AMULET4 + 0, // ITEM_POUCH1 + // 1x2 + 8, // ITEM_DAGGER1 + 8, // ITEM_DAGGER2 + 0, // ITEM_BIGBOTTLE + 8, // ITEM_DAGGER3 + 8, // ITEM_DAGGER4 + 8, // ITEM_DAGGER5 + // 1x3 + 8, // ITEM_BLADE + 8, // ITEM_BASTSRD + 8, // ITEM_FALCHION + 6, // ITEM_MACE + 8, // ITEM_LONGSRD + 8, // ITEM_BROADSRD + 8, // ITEM_SCIMITAR + 6, // ITEM_MORNSTAR + 8, // ITEM_SHORTSRD + 8, // ITEM_CLAYMORE + 6, // ITEM_CLUB + 8, // ITEM_SABRE + 8, // ITEM_KNTSWORD + 6, // ITEM_CLUB1 + 6, // ITEM_CLUB2 + 6, // ITEM_CLUB3 + 8, // ITEM_SCIMITAR2 + 8, // ITEM_MAGSWORD + 8, // ITEM_SKULSWORD + // 2x2 + 5, // ITEM_HELM + 9, // ITEM_ROCK + 13, // ITEM_SKCROWN + 13, // ITEM_CROWN + 13, // ITEM_MCROWN + 5, // ITEM_JESTER + 5, // ITEM_HARLEQ + 5, // ITEM_FHELM + 15, // ITEM_BUCKLER + 5, // ITEM_FHELM2 + 5, // ITEM_GRTHELM + 18, // ITEM_BOOK1 + 18, // ITEM_BOOK2 + 18, // ITEM_BOOK3 + 30, // ITEM_MUSHROOM + 5, // ITEM_SKLCAP + 5, // ITEM_LCAP + 14, // ITEM_FLESH + 5, // ITEM_SKLCAP2 + 14, // ITEM_CLOTHES + 13, // ITEM_CROWN2 + 16, // ITEM_MAP + 18, // ITEM_BOOK4 + 5, // ITEM_FHELM3 + 5, // ITEM_SAMHELM + // 2x3 + 7, // ITEM_LRGSHIELD + 1, // ITEM_BTLAXE + 3, // ITEM_LONGBOW + 17, // ITEM_PARMOR + 1, // ITEM_AXE + 15, // ITEM_WSHIELD + 10, // ITEM_CLEAVER + 14, // ITEM_STDARMOR + 3, // ITEM_COMPBOW + 11, // ITEM_SHRTSTAFF + 8, // ITEM_2HSWORD + 0, // ITEM_CHARMOR + 1, // ITEM_SMALLAXE + 7, // ITEM_HVYSHIELD + 0, // ITEM_SCLARMOR + 7, // ITEM_SMLSHIELD + 15, // ITEM_SKULLSHLD + 7, // ITEM_WOLFSHLD + 3, // ITEM_SHORTBOW + 3, // ITEM_STLLONGBOW + 3, // ITEM_STLSHRTBOW + 6, // ITEM_SMLWARHAM + 6, // ITEM_MAUL + 11, // ITEM_IRONSTAFF + 11, // ITEM_STLSTAFF + 11, // ITEM_LONGSTAFF + 31, // ITEM_INNSIGN + 14, // ITEM_HLARMOR + 14, // ITEM_RAGS + 14, // ITEM_QARMOR + 6, // ITEM_BALLNCHN + 6, // ITEM_FLAIL + 7, // ITEM_TSHIELD + 3, // ITEM_HNTRBOW + 8, // ITEM_GRTSWORD + 14, // ITEM_LARMOR + 0, // ITEM_SPLTARMOR + 14, // ITEM_ROBE + 14, // ITEM_HVYROBE + 0, // ITEM_RINGARMOR + 33, // ITEM_ANVIL + 1, // ITEM_BROADAXE + 1, // ITEM_LRGAXE + 1, // ITEM_WICKAXE + 1, // ITEM_HANDAXE + 1, // ITEM_GREATAXE + 7, // ITEM_IRONSHLD + 7, // ITEM_KITESHLD + 7, // ITEM_LRGSHLD + 14, // ITEM_CLOAK + 14, // ITEM_CAPE + 17, // ITEM_PARMOR2 + 17, // ITEM_PARMOR3 + 17, // ITEM_BPLATE + 0, // ITEM_RINGMAIL + 34, // ITEM_BISHOPSTF + 1, // ITEM_GEMGRTAXE + 0, // ITEM_ARKARMOR + 3, // ITEM_CROSBOW + 17, // ITEM_NAJARMOR + 8, // ITEM_GRIZZLY + 8, // ITEM_GRANDPA + 6, // ITEM_PROTECT + 1, // ITEM_REAVER + 3, // ITEM_WINDFOR + 3, // ITEM_SWARBOW + 11, // ITEM_COMPSTF + 3, // ITEM_SBATLBOW +// Misc +// 4, // ITEM_GOLD + +// new 1x1 + 12, // ITEM_MERLINRING + 12, // ITEM_MANARING + 12, // ITEM_AMULWARD + 12, // ITEM_NECMAGIC + 12, // ITEM_NECHEALTH + 12, // ITEM_KARIKSRING + 12, // ITEM_RINGGROUND + 12, // ITEM_AMULPROT + 12, // ITEM_MERCRING + 12, // ITEM_RINGTHUND + 12, // ITEM_NECTRUTH + 12, // ITEM_RINGGIANTS + 12, // ITEM_AMULGOLD + 12, // ITEM_RINGMYSTIC + 12, // ITEM_RINGCOPPER + 12, // ITEM_AMULACOLYT + 12, // ITEM_RINGMAGMA + 12, // ITEM_NECPURIFY + 12, // ITEM_RINGGLADTR + 35, // ITEM_RUNEBOMB + 39, // ITEM_THEODORE + 36, // ITEM_TORNPAPER1 + 36, // ITEM_TORNPAPER2 + 36, // ITEM_TORNPAPER3 + 37, // ITEM_WHOLEPAPER + 38, // ITEM_FIRERUNE1 + 38, // ITEM_FIRERUNE2 + 38, // ITEM_LIGHTRUNE1 + 38, // ITEM_LIGHTRUNE2 + 38, // ITEM_STONERUNE +// new 2x2 + 41, + 42, +// new 1x3 + 8, // ITEM_SWORDEDGE + 8, // ITEM_SWORDGLAM + 8, // ITEM_SWORDSERR +// new 2x3 + 17, // ITEM_ARMRDARK + 0, // ITEM_ARMRBONECH + 6, // ITEM_HAMRTHUND + 8, // ITEM_SWRDCRYSTL + 11, // ITEM_STAFJESTER + 11, // ITEM_STAFMANA + 3, // ITEM_BOWVULCAN + 3, // ITEM_BOWSPEED + 1, // ITEM_AXEANCIENT + 6, // ITEM_CLUBCARNAG + 6, // ITEM_MACEDARK + 6, // ITEM_CLUBDECAY + 1, // ITEM_AXEDECAY + 8, // ITEM_SWRDDECAY + 6, // ITEM_MACEDECAY + 11, // ITEM_STAFDECAY + 3, // ITEM_BOWDECAY + 6, // ITEM_CLUBOUCH + 8, // ITEM_SWRDDEVAST + 1, // ITEM_AXEDEVAST + 6, // ITEM_MORNDEVAST + 6, // ITEM_MACEDEVAST + 17, // ITEM_ARMRDMNPLT + 40, + }; + + +char *ItemFiles[] = { + "Armor2", // 0 + "Axe", // 1 + "FBttle", // 2 + "Bow", // 3 + "GoldFlip", // 4 + "Helmut", // 5 + "Mace", // 6 + "Shield", // 7 + "SwrdFlip", // 8 + "Rock", // 9 + "Cleaver", // 10 + "Staff", // 11 + "Ring", // 12 + "CrownF", // 13 + "LArmor", // 14 + "WShield", // 15 + "Scroll", // 16 + "FPlateAr", // 17 + "FBook", // 18 + "Food", // 19 + "FBttleBB", // 20 + "FBttleDY", // 21 + "FBttleOR", // 22 + "FBttleBR", // 23 + "FBttleBL", // 24 + "FBttleBY", // 25 + "FBttleWH", // 26 + "FBttleDB", // 27 + "FEar", // 28 + "FBrain", // 29 + "FMush", // 30 + "Innsign", // 31 + "Bldstn", // 32 + "Fanvil", // 33 + "FLazStaf", // 34 + "bombs1", // 35 + "halfps1", // 36 + "wholeps1", // 37 + "runes1", // 38 + "teddys1", // 39 + "cows1", // 40 + "donkys1", // 41 + "mooses1", // 42 +}; +#define ITEMFTYPES (sizeof(ItemFiles)/sizeof(char *)) + +BYTE *itemanims[ITEMFTYPES]; + +byte ItemAnimLs[ITEMFTYPES] = { + 15, // Armor2 + 13, // Axe + 16, // FBttle + 13, // Bow + 10, // GoldFlip + 13, // Helmut + 13, // Mace + 13, // Shield + 13, // SwrdFlip + 10, // Rock + 13, // Cleaver + 13, // Staff + 13, // Ring + 13, // Crown + 13, // LArmor + 13, // WShield + 13, // Scroll + 13, // FPlateAr + 13, // FBook + 1, // Food + 16, // FBttleBB + 16, // FBttleDY + 16, // FBttleOR + 16, // FBttleBR + 16, // FBttleBL + 16, // FBttleBY + 16, // FBttleWH + 16, // FBttleDB + 13, // FEar + 12, // FBrain + 12, // FMush + 13, // Innsign + 13, // Bldstn + 13, // Fanvil + 8, // FLazStaf + 10, // nest bomb + 16, // half paper + 16, // whole paper + 10, // runes + 10, // teddy bear + 15, + 15, + 15, +}; + +int ItemAnimSnds[ITEMFTYPES] = { + IS_FHARM, // Armor2 + IS_FAXE, // Axe + IS_FPOT, // FBttle + IS_FBOW, // Bow + IS_GOLD, // GoldFlip + IS_FCAP, // Helmet + IS_FSWOR, // Mace + IS_FSHLD, // Shield + IS_FSWOR, // SwrdFlip + IS_FROCK, // Rock + IS_FAXE, // Cleaver + IS_FSTAF, // Staff + IS_FRING, // Ring + IS_FCAP, // Crown + IS_FLARM, // LArmor + IS_FSHLD, // WShield + IS_FSCRL, // Scroll + IS_FHARM, // FPlateAr + IS_FBOOK, // FBook + IS_FLARM, // Food + IS_FPOT, // FBttleBB + IS_FPOT, // FBttleDY + IS_FPOT, // FBttleOR + IS_FPOT, // FBttleBR + IS_FPOT, // FBttleBL + IS_FPOT, // FBttleBY + IS_FPOT, // FBttleWH + IS_FPOT, // FBttleDB + IS_FBODY, // FEar + IS_FBODY, // FBrain + IS_FMUSH, // FMush + IS_ISIGN, // Innsign + IS_FBLST, // Bldstn + IS_FANVL, // Fanvil + IS_FSTAF, // FLazStaf + IS_FROCK, // Bomb + IS_FSCRL, // Half Paper + IS_FSCRL, // Whole Paper + IS_FROCK, // Rune + IS_FMUSH, // Theo + IS_FHARM, // Cow Armor + IS_FLARM, // + IS_FLARM, // +}; + +int ItemInvSnds[ITEMFTYPES] = { + IS_IHARM, // Armor2 + IS_IAXE, // Axe + IS_IPOT, // FBttle + IS_IBOW, // Bow + IS_GOLD, // GoldFlip + IS_ICAP, // Helmet + IS_ISWORD, // Mace + IS_ISHIEL, // Shield + IS_ISWORD, // SwrdFlip + IS_IROCK, // Rock + IS_IAXE, // Cleaver + IS_ISTAF, // Staff + IS_IRING, // Ring + IS_ICAP, // Crown + IS_ILARM, // LArmor + IS_ISHIEL, // WShield + IS_ISCROL, // Scroll + IS_IHARM, // FPlateAr + IS_IBOOK, // FBook + IS_IHARM, // Food + IS_IPOT, // FBttleBB + IS_IPOT, // FBttleDY + IS_IPOT, // FBttleOR + IS_IPOT, // FBttleBR + IS_IPOT, // FBttleBL + IS_IPOT, // FBttleBY + IS_IPOT, // FBttleWH + IS_IPOT, // FBttleDB + IS_IBODY, // FEar + IS_IBODY, // FBrain + IS_IMUSH, // FMush + IS_ISIGN, // Innsign + IS_IBLST, // Bldstn + IS_IANVL, // Fanvil + IS_ISTAF, // FLazStaf + IS_IROCK, // Bomb + IS_ISCROL, // Half Paper + IS_ISCROL, // Whole Paper + IS_IROCK, // Rune + IS_IMUSH, // Theo + IS_IHARM, // Cow Armor + IS_ILARM, // + IS_ILARM, // +}; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int GetEffLevel() +{ + int efflevel = currlevel; + if (currlevel >= HIVESTART && currlevel <= HIVEEND) + efflevel = currlevel - HIVESTART + 9; + if (currlevel >= CRYPTSTART && currlevel <= CRYPTEND) + efflevel = currlevel - CRYPTSTART + 14; + + return efflevel; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitItemGFX() { + for (int i = 0; i < ITEMFTYPES; i++) { + char filestr[64]; + sprintf(filestr, "Items\\%s.CEL", ItemFiles[i]); + app_assert(! itemanims[i]); + itemanims[i] = LoadFileInMemSig(filestr,NULL,'IGFX'); + } + + ZeroMemory(UniqueItemFlag,sizeof(UniqueItemFlag)); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL ItemPlace(int xp, int yp) { + if (dMonster[xp][yp] != 0) return FALSE; + if (dPlayer[xp][yp] != 0) return FALSE; + if (dItem[xp][yp] != 0) return FALSE; + if (dObject[xp][yp] != 0) return FALSE; + if (dFlags[xp][yp] & BFLAG_SETPC) return FALSE; + if (nSolidTable[dPiece[xp][yp]]) return FALSE; + return TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void AddInitItems() { + + int efflevel = GetEffLevel(); + int j = random(11, 3) + 3; + for (int i = 0; i < j; i++) { + int ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + int xx = random(12, DMAXX - DIRTEDGE) + (DIRTEDGED2); + int yy = random(12, DMAXY - DIRTEDGE) + (DIRTEDGED2); + while (! ItemPlace(xx, yy)) { + xx = random(12, DMAXX - DIRTEDGE) + (DIRTEDGED2); + yy = random(12, DMAXY - DIRTEDGE) + (DIRTEDGED2); + } + + item[ii]._ix = xx; + item[ii]._iy = yy; + dItem[xx][yy] = ii + 1; + item[ii]._iSeed = GetRndSeed(); + SetRndSeed(item[ii]._iSeed); + if (random(12, 2)) GetItemAttrs(ii, IDI_HEAL, efflevel); + else GetItemAttrs(ii, IDI_MANA, efflevel); + item[ii]._iCreateInfo = efflevel + ICI_PREGEN; + SetupItem(ii); + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iAnimFlag = FALSE; + item[ii]._iSelFlag = ISEL_FLR; + DeltaAddItem(ii); + numitems++; + } +} + +static void AddNote() +{ + int xx, yy; + + do + { + xx = random(12, DMAXX - DIRTEDGE) + (DIRTEDGED2); + yy = random(12, DMAXY - DIRTEDGE) + (DIRTEDGED2); + } while (! ItemPlace(xx, yy)); + + int idi; + switch(currlevel) + { + case CRYPTSTART+2: + idi = IDI_NOTE3; + break; + case CRYPTSTART+1: + idi = IDI_NOTE2; + break; + default: + idi = IDI_NOTE1; + break; + } + SpawnQuestItem(idi, xx, yy, FALSE, ISEL_FLR); + +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitItems() { + int i; + + DROPLOG("Initing items...\n"); + // Setup a gold item + GetItemAttrs(0, 0, 1); + golditem = item[0]; + golditem._iStatFlag = TRUE; + + numitems = 0; + for (i = 0; i < MAXITEMS; i++) { + item[i]._itype = 0; + item[i]._ix = 0; + item[i]._iy = 0; + item[i]._iAnimFlag = FALSE; + item[i]._iSelFlag = ISEL_NONE; + item[i]._iIdentified = FALSE; + item[i]._iPostDraw = FALSE; + } + + for (i = 0; i < MAXITEMS; i++) { + itemavail[i] = i; + itemactive[i] = 0; + } + + if (!setlevel) { + + int rs = GetRndSeed(); + + if (QuestStatus(Q_ROCK)) { + SpawnRock(); + } + if (QuestStatus(Q_ANVIL)) { + SpawnQuestItem(IDI_ANVIL, (setpc_x << 1) + 11 + DIRTEDGED2, (setpc_y << 1) + 11 + DIRTEDGED2, FALSE, ISEL_FLR); + } + if (gbCowsuit) + if (currlevel == HIVEEND) + SpawnQuestItem(IDI_SUITBRWN, 25, 25, 3, ISEL_FLR); + if (gbCowsuit) + if (currlevel == HIVESTART+2) + SpawnQuestItem(IDI_SUITGREY, 25, 25, 3, ISEL_FLR); + + if (currlevel > 0 && currlevel < 16) + AddInitItems(); + if (currlevel >= CRYPTSTART && currlevel <= CRYPTSTART+2) + AddNote(); + } + + uitemflag = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CalcPlrItemVals(int p, BOOL Loadgfx) +{ + int mind, maxd, tac, g, d, i, mi; + int bdam, btohit, bac; + int sadd, madd, dadd, vadd; + int fr, lr, mr; + int dmod, ghit, lrad; + int ihp, imana; + int spllvladd; + int enac; + int fmin, fmax, lmin, lmax; + long iflgs, iflgs2; + __int64 spl, t; + + app_assert((DWORD) p < MAX_PLRS); + + mind = 0; + maxd = 0; + tac = 0; + bdam = 0; + btohit = 0; + bac = 0; + iflgs = 0; + iflgs2 = 0; + sadd = 0; + madd = 0; + dadd = 0; + vadd = 0; + spl = 0; + fr = 0; + lr = 0; + mr = 0; + dmod = 0; + ghit = 0; + lrad = PLRLRAD; + ihp = 0; + imana = 0; + spllvladd = 0; + enac = 0; + fmin = 0; + fmax = 0; + lmin = 0; + lmax = 0; + for (i = 0; i < 7; i++) { + const ItemStruct * itm = &plr[p].InvBody[i]; + if (itm->_itype == -1) continue; + if (! itm->_iStatFlag) continue; + + mind += itm->_iMinDam; + maxd += itm->_iMaxDam; + tac += itm->_iAC; + + t = 1; + if (itm->_iSpell != 0) + spl |= t << (itm->_iSpell - 1); + + // don't give benefit of unidentified magic items + if (itm->_iMagical != IMAGIC_NONE && ! itm->_iIdentified) + continue; + + bdam += itm->_iPLDam; + btohit += itm->_iPLToHit; + + if (itm->_iPLAC) { + int tmpac = (itm->_iAC * itm->_iPLAC) / 100; + if (tmpac == 0) tmpac = 1; + bac += tmpac; + } + + iflgs |= itm->_iFlags; + iflgs2 |= itm->_iFlags2; + sadd += itm->_iPLStr; + madd += itm->_iPLMag; + dadd += itm->_iPLDex; + vadd += itm->_iPLVit; + fr += itm->_iPLFR; + lr += itm->_iPLLR; + mr += itm->_iPLMR; + dmod += itm->_iPLDamMod; + ghit += itm->_iPLGetHit; + lrad += itm->_iPLLight; + ihp += itm->_iPLHP; + imana += itm->_iPLMana; + spllvladd += itm->_iSplLvlAdd; + enac += itm->_iPLEnAc; + fmin += itm->_iFMinDam; + fmax += itm->_iFMaxDam; + lmin += itm->_iLMinDam; + lmax += itm->_iLMaxDam; + } + + // If I have no weapons, then make it min of 1-1, if shield only, 1-3 + if (mind == 0 && maxd == 0) { + mind = 1; + maxd = 1; + if ((plr[p].Hand1Item._itype == IT_SHIELD) && (plr[p].Hand1Item._iStatFlag)) + maxd = 3; + if ((plr[p].Hand2Item._itype == IT_SHIELD) && (plr[p].Hand2Item._iStatFlag)) + maxd = 3; + + // monks have fists of fury. + if (plr[p]._pClass == CLASS_MONK) + { + mind = max(mind,plr[p]._pLevel >> 1); + maxd = max(maxd,plr[p]._pLevel); + } + } + + if ((plr[p]._pSpellFlags & SF_RAGE) == SF_RAGE) { + sadd += 2 * plr[p]._pLevel; + dadd += plr[p]._pLevel + (plr[p]._pLevel/2); + vadd += 2 * plr[p]._pLevel; + } + + if ((plr[p]._pSpellFlags & SF_LETHERGY) == SF_LETHERGY) { + sadd -= 2 * plr[p]._pLevel; + dadd -= plr[p]._pLevel + (plr[p]._pLevel/2); + vadd -= 2 * plr[p]._pLevel; + } + + plr[p]._pIMinDam = mind; + plr[p]._pIMaxDam = maxd; + plr[p]._pIAC = tac; + plr[p]._pIBonusDam = bdam; + plr[p]._pIBonusToHit = btohit; + plr[p]._pIBonusAC = bac; + plr[p]._pIFlags = iflgs; + plr[p]._pIFlags2 = iflgs2; + plr[p]._pIBonusDamMod = dmod; + plr[p]._pIGetHit = ghit; + if (lrad < 2) lrad = 2; + if (lrad > 15) lrad = 15; + if ((plr[p]._pLightRad != lrad ) && (p == myplr)) { + ChangeLightRadius(plr[p]._plid, lrad); + if (lrad < 10) ChangeVisionRadius(plr[p]._pvid, 10); + else ChangeVisionRadius(plr[p]._pvid, lrad); + plr[p]._pLightRad = lrad; + } + + plr[p]._pStrength = plr[p]._pBaseStr + sadd; + if (plr[myplr]._pStrength <= 0) plr[myplr]._pStrength = 0; + plr[p]._pMagic = plr[p]._pBaseMag + madd; + if (plr[myplr]._pMagic <= 0) plr[myplr]._pMagic = 0; + plr[p]._pDexterity = plr[p]._pBaseDex + dadd; + if (plr[myplr]._pDexterity <= 0) plr[myplr]._pDexterity = 0; + plr[p]._pVitality = plr[p]._pBaseVit + vadd; + if (plr[myplr]._pVitality <= 0) plr[myplr]._pVitality = 0; + + if (plr[p]._pClass == CLASS_ROGUE) + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 200; + else if (plr[p]._pClass == CLASS_MONK) + { + if (plr[p].Hand1Item._itype == IT_STAFF || // bonus for staff + plr[p].Hand2Item._itype == IT_STAFF || + (plr[p].Hand1Item._itype == -1 && // bonus for no weapons. + plr[p].Hand2Item._itype == -1) + ) + { + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 150; + } + else + { + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 300; + } + } + else if (plr[p]._pClass == CLASS_BARD) + { + if (plr[p].Hand1Item._itype == IT_SWORD // bonus for using a sword. + || plr[p].Hand2Item._itype == IT_SWORD) + { + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 150; + } + else if (plr[p].Hand1Item._itype == IT_BOW + || plr[p].Hand2Item._itype == IT_BOW) + { + // Better than a monk or warrior with a bow but not as good as a rogue. + plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 250; + } + else + { + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; + } + } + else if (plr[p]._pClass == CLASS_BARBARIAN) + { + if (plr[p].Hand1Item._itype == IT_AXE + || plr[p].Hand2Item._itype == IT_AXE) + { + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 75; + } + else if (plr[p].Hand1Item._itype == IT_MACE + || plr[p].Hand2Item._itype == IT_MACE) + { + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 75; + } + else if (plr[p].Hand1Item._itype == IT_BOW + || plr[p].Hand2Item._itype == IT_BOW) + { + // As bad as it gets + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 300; + } + else + { + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; + } + + if (plr[p].Hand1Item._itype == IT_SHIELD || plr[p].Hand2Item._itype == IT_SHIELD) + { + // remove 1/2 the AC for the shield. + if (plr[p].Hand1Item._itype == IT_SHIELD) + { + plr[p]._pIAC -= plr[p].Hand1Item._iAC / 2; + } + else if (plr[p].Hand2Item._itype == IT_SHIELD) + { + plr[p]._pIAC -= plr[p].Hand2Item._iAC / 2; + } + } + else + { + // Bonus for not using a shield. + if ( !(plr[p].Hand1Item._itype == IT_STAFF || plr[p].Hand2Item._itype == IT_STAFF || + plr[p].Hand1Item._itype == IT_BOW || plr[p].Hand2Item._itype == IT_BOW) + ) + { + plr[p]._pDamageMod += (plr[p]._pVitality * plr[p]._pLevel) / 100; + } + } + // Barbarians have a natural armor (Thick skin) + plr[p]._pIAC += plr[p]._pLevel/4; + } + else + plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; + + plr[p]._pISpells = spl; + if ((plr[p]._pRSplType == SPT_ITEM) /*|| plr[p]._pRSplType == SPT_SCROLL)*/ + && ((plr[p]._pISpells & (((__int64)1) << (plr[p]._pRSpell-1))) == 0)) { + plr[p]._pRSpell = -1; + plr[p]._pRSplType = SPT_NONE; + force_redraw = FULLDRAW; + } + plr[p]._pISplLvlAdd = spllvladd; + + plr[p]._pIEnAc = enac; + + if (plr[p]._pClass == CLASS_BARBARIAN) // Barbarians have a natural bonus. + { + mr += plr[p]._pLevel; + fr += plr[p]._pLevel; + lr += plr[p]._pLevel; + } + + if ((plr[p]._pSpellFlags & SF_LETHERGY) == SF_LETHERGY) // Lethergy causes a loss of strength + { + mr -= plr[p]._pLevel; + fr -= plr[p]._pLevel; + lr -= plr[p]._pLevel; + } + + if (iflgs & IAF_ZERORES) { + mr = 0; + fr = 0; + lr = 0; + } + + if (mr > RESIST_MAX) mr = RESIST_MAX; + else if (mr < 0) mr = 0; + plr[p]._pMagResist = mr; + + if (fr > RESIST_MAX) fr = RESIST_MAX; + else if (fr < 0) fr = 0; + plr[p]._pFireResist = fr; + + if (lr > RESIST_MAX) lr = RESIST_MAX; + else if (lr < 0) lr = 0; + plr[p]._pLghtResist = lr; + + if (plr[p]._pClass == CLASS_WARRIOR) + { + vadd = vadd << 1; + } + else if (plr[p]._pClass == CLASS_BARBARIAN) + { + vadd *= 2; + vadd += (vadd >> 2); + } + else if (plr[p]._pClass == CLASS_ROGUE || + plr[p]._pClass == CLASS_MONK || + plr[p]._pClass == CLASS_BARD ) + { + vadd += (vadd >> 1); + } + ihp += (vadd << HP_SHIFT); + if (plr[p]._pClass == CLASS_SORCEROR) + madd = madd << 1; // 2 * madd + if (plr[p]._pClass == CLASS_ROGUE || + plr[p]._pClass == CLASS_MONK ) + madd += (madd >> 1); // 1.5 * madd + else if ( plr[p]._pClass == CLASS_BARD ) + madd += (madd >> 1) + (madd >> 2); // 1.75 * madd + + imana += (madd << MANA_SHIFT); + + plr[p]._pHitPoints = plr[p]._pHPBase + ihp; + plr[p]._pMaxHP = plr[p]._pMaxHPBase + ihp; + + if (plr[p]._pHitPoints > plr[p]._pMaxHP) + plr[p]._pHitPoints = plr[p]._pMaxHP; + + if ((p == myplr) && (plr[p]._pHitPoints >> HP_SHIFT) <= 0) + SetPlayerHitPoints(p, 0); + + plr[p]._pMana = plr[p]._pManaBase + imana; + plr[p]._pMaxMana = plr[p]._pMaxManaBase + imana; + + if (plr[p]._pMana > plr[p]._pMaxMana) + plr[p]._pMana = plr[p]._pMaxMana; + + plr[p]._pIFMinDam = fmin; + plr[p]._pIFMaxDam = fmax; + plr[p]._pILMinDam = lmin; + plr[p]._pILMaxDam = lmax; + + + if (iflgs & IAF_INFRAVISION) plr[p]._pInfraFlag = TRUE; + else plr[p]._pInfraFlag = FALSE; + + plr[p]._pBlockFlag = FALSE; + if (plr[p]._pClass == CLASS_MONK) + { + if ((plr[p].Hand1Item._itype == IT_STAFF) && + (plr[p].Hand1Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + + if ((plr[p].Hand2Item._itype == IT_STAFF) && + (plr[p].Hand2Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + + if ((plr[p].Hand1Item._itype == -1) && + (plr[p].Hand2Item._itype == -1)) + { + plr[p]._pBlockFlag = TRUE; + } + + if ((plr[p].Hand1Item._iClass == IC_WEAP) && + (plr[p].Hand1Item._iLoc != IL_2HAND) && + (plr[p].Hand2Item._itype == -1)) + { + plr[p]._pBlockFlag = TRUE; + } + + if ((plr[p].Hand2Item._iClass == IC_WEAP) && + (plr[p].Hand2Item._iLoc != IL_2HAND) && + (plr[p].Hand1Item._itype == -1)) + { + plr[p]._pBlockFlag = TRUE; + } + } +#if 0 + // No Block art + else if (plr[p]._pClass == CLASS_BARD) + { + if ((plr[p].Hand1Item._itype == IT_SWORD) && + (plr[p].Hand1Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + + if ((plr[p].Hand2Item._itype == IT_SWORD) && + (plr[p].Hand2Item._iStatFlag)) + { + plr[p]._pBlockFlag = TRUE; + plr[p]._pIFlags |= IAF_BLANIM; + } + } +#endif + + plr[p]._pwtype = WEAP_H2H; + // Determine which graphics to use + g = PGFX_NGUY; + if ((plr[p].Hand1Item._itype != -1) && + (plr[p].Hand1Item._iClass == IC_WEAP) && + (plr[p].Hand1Item._iStatFlag)) g = plr[p].Hand1Item._itype; + if ((plr[p].Hand2Item._itype != -1) && + (plr[p].Hand2Item._iClass == IC_WEAP) && + (plr[p].Hand2Item._iStatFlag)) g = plr[p].Hand2Item._itype; + switch (g) { + case IT_SWORD: + g = PGFX_XGUY; + break; + case IT_MACE: + g = PGFX_ZGUY; + break; + case IT_BOW: + plr[p]._pwtype = WEAP_RANGE; + g = PGFX_BGUY; + break; + case IT_AXE: + g = PGFX_FGUY; + break; + case IT_STAFF: + g = PGFX_TGUY; + break; + } + if ((plr[p].Hand1Item._itype == IT_SHIELD) && (plr[p].Hand1Item._iStatFlag)) { + plr[p]._pBlockFlag = TRUE; + g++; + } + if ((plr[p].Hand2Item._itype == IT_SHIELD) && (plr[p].Hand2Item._iStatFlag)) { + plr[p]._pBlockFlag = TRUE; + g++; + } + + #if IS_VERSION(RETAIL) || IS_VERSION(BETA) + if ((plr[p].BodyItem._itype == IT_HARMOR) && (plr[p].BodyItem._iStatFlag)) + { + if ((plr[p]._pClass == CLASS_MONK) && + (plr[p].BodyItem._iMagical == IMAGIC_UNIQUE)) + plr[p]._pIAC += plr[p]._pLevel >> 1; // Monks get 1/2 level bonus while wearing medium armor. + g += 32; + } + else if ((plr[p].BodyItem._itype == IT_MARMOR) && (plr[p].BodyItem._iStatFlag)) + { + if (plr[p]._pClass == CLASS_MONK) + { + if (plr[p].BodyItem._iMagical == IMAGIC_UNIQUE) + plr[p]._pIAC += plr[p]._pLevel << 1; // Monks get 2x level bonus while wearing light armor. + else + plr[p]._pIAC += plr[p]._pLevel >> 1; // Monks get 1/2 level bonus while wearing medium armor. + } + g += 16; + } + else + { + if (plr[p]._pClass == CLASS_MONK) + { + plr[p]._pIAC += plr[p]._pLevel << 1; // Monks get 2x level bonus for light/no armor. + } + } + #endif + + if ((plr[p]._pgfxnum != g) && (Loadgfx)) { + plr[p]._pgfxnum = g; + plr[p]._pGFXLoad = 0; // Clear all graphics loaded flag + LoadPlrGFX(p, PGL_STAND); + SetPlrAnims(p); + d = plr[p]._pdir; + + app_assert(plr[p]._pNAnim[d]); + plr[p]._pAnimData = plr[p]._pNAnim[d]; + plr[p]._pAnimLen = plr[p]._pNFrames; + plr[p]._pAnimFrame = 1; + plr[p]._pAnimCnt = 0; + plr[p]._pAnimDelay = 3; + plr[p]._pAnimWidth = plr[p]._pNWidth; + plr[p]._pAnimWidth2 = (plr[p]._pNWidth - 64) >> 1; + } + else { + plr[p]._pgfxnum = g; + } + + for (i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if (missile[mi]._mitype == MIT_MANASHIELD && missile[mi]._misource == p) { + missile[mi]._miVar1 = plr[p]._pHitPoints; + missile[mi]._miVar2 = plr[p]._pHPBase; + break; + } + } + + if (plr[p].NeckItem._itype != -1 && plr[p].NeckItem.IDidx == IDI_AURIC) + { + GOLD_VMAX = GOLD_DOUBLE_VMAX; + } + else + { + int const old_vmax = GOLD_VMAX; + + GOLD_VMAX = GOLD_DOUBLE_VMAX/2; + + if (old_vmax != GOLD_VMAX) + StripTopGold(p); + } + + drawmanaflag = TRUE; + drawhpflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrScrolls(int p) { + int i; + __int64 t; + + plr[p]._pScrlSpells = 0; + for (i = 0; i < plr[p]._pNumInv; i++) { + if (plr[p].InvList[i]._itype != -1) { + if (((plr[p].InvList[i]._iMiscId == IMID_SCROLL) || + (plr[p].InvList[i]._iMiscId == IMID_TSCROLL)) && + (plr[p].InvList[i]._iStatFlag)) { + t = 1; + plr[p]._pScrlSpells |= (t << plr[p].InvList[i]._iSpell-1); + } + } + } + for (i = 0; i < MAXSPD; i++) { + if (plr[p].SpdList[i]._itype != -1) { + if (((plr[p].SpdList[i]._iMiscId == IMID_SCROLL) || + (plr[p].SpdList[i]._iMiscId == IMID_TSCROLL)) && + (plr[p].SpdList[i]._iStatFlag)) { + t = 1; + plr[p]._pScrlSpells |= (t << plr[p].SpdList[i]._iSpell-1); + } + } + } + + if ((plr[p]._pRSplType == SPT_SCROLL) + && ((plr[p]._pScrlSpells & (1 << (plr[p]._pRSpell-1))) == 0)) { + plr[p]._pRSpell = -1; + plr[p]._pRSplType = SPT_NONE; + force_redraw = FULLDRAW; + } + +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrStaff(int p) { + plr[p]._pISpells = 0; + if (plr[p].Hand1Item._itype == -1) return; + if (!plr[p].Hand1Item._iStatFlag) return; + if (plr[p].Hand1Item._iCharges > 0) { + __int64 t = 1; + plr[p]._pISpells |= t << (plr[p].Hand1Item._iSpell - 1); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcSelfItems(int pnum) { + int i; + ItemStruct * pi; + PlayerStruct * p = &plr[pnum]; + BOOL sf, changeflag; + int sa = 0; + int ma = 0; + int da = 0; + + // assume everything works, and calc potential + to str, mag, dex + pi = &p->InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) { + if (pi->_itype == -1) continue; + pi->_iStatFlag = TRUE; + if (!pi->_iIdentified) continue; + sa += pi->_iPLStr; + ma += pi->_iPLMag; + da += pi->_iPLDex; + } + + do { + changeflag = FALSE; + pi = &p->InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) { + if (pi->_itype == -1) continue; + if (!pi->_iStatFlag) continue; + sf = TRUE; + if ((p->_pBaseStr + sa) < pi->_iMinStr) sf = FALSE; + if ((p->_pBaseMag + ma) < pi->_iMinMag) sf = FALSE; + if ((p->_pBaseDex + da) < pi->_iMinDex) sf = FALSE; + if (!sf) { + changeflag = TRUE; + pi->_iStatFlag = FALSE; + if (pi->_iIdentified) { + sa -= pi->_iPLStr; + ma -= pi->_iPLMag; + da -= pi->_iPLDex; + } + } + } + } while (changeflag); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static BOOL ItemMinStats(const PlayerStruct * p,const ItemStruct * x) { + if (p->_pMagic < (byte)x->_iMinMag) return FALSE; + if (p->_pStrength < x->_iMinStr) return FALSE; + if (p->_pDexterity < x->_iMinDex) return FALSE; + return TRUE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrItemMin(int pnum) { + int i; + ItemStruct * pi; + PlayerStruct * p = &plr[pnum]; + + // handle inventory + pi = &p->InvList[0]; + for (i = p->_pNumInv; i--; pi++) + pi->_iStatFlag = ItemMinStats(p,pi); + + // handle speedbar + pi = &p->SpdList[0]; + for (i = MAXSPD; i--; pi++) { + if (pi->_itype == -1) continue; + pi->_iStatFlag = ItemMinStats(p,pi); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrBookVals(int p) +{ + int i, slvl; + + void WitchBookLevel(int); + if (currlevel == 0) { + for (i = 1; witchitem[i]._itype != -1; i++) + WitchBookLevel(i); + } + + for (i = 0; i < plr[p]._pNumInv; i++) { + if ((plr[p].InvList[i]._itype == IT_MISC) && (plr[p].InvList[i]._iMiscId == IMID_BOOK)) { + plr[p].InvList[i]._iMinMag = spelldata[plr[p].InvList[i]._iSpell].sMinInt; + slvl = plr[p]._pSplLvl[plr[p].InvList[i]._iSpell]; + while (slvl != 0) { + plr[p].InvList[i]._iMinMag += ((plr[p].InvList[i]._iMinMag * 20) / 100); + slvl--; + if ((plr[p].InvList[i]._iMinMag + ((plr[p].InvList[i]._iMinMag * 20) / 100)) > 255) { + plr[p].InvList[i]._iMinMag = 255; + slvl = 0; + } + } + plr[p].InvList[i]._iStatFlag = ItemMinStats(&plr[p], &plr[p].InvList[i]); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CalcPlrInv(int p, BOOL Loadgfx) { + CalcPlrItemMin(p); + CalcSelfItems(p); + CalcPlrItemVals(p, Loadgfx); + CalcPlrItemMin(p); + if (p == myplr) { + CalcPlrBookVals(p); + CalcPlrScrolls(p); + CalcPlrStaff(p); + } + if ((p == myplr) && (currlevel == 0)) RecalcStoreStats(); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlrHandItem(ItemStruct *h, int idata) { + const ItemDataStruct * pAllItem = &AllItemsList[idata]; + + ZeroMemory(h,sizeof(ItemStruct)); + h->_itype = pAllItem->itype; + h->_iCurs = pAllItem->iCurs; + strcpy(h->_iName, pAllItem->iName); + strcpy(h->_iIName, pAllItem->iName); + h->_iLoc = pAllItem->iLoc; + h->_iClass = pAllItem->iClass; + h->_iMinDam = pAllItem->iMinDam; + h->_iMaxDam = pAllItem->iMaxDam; + h->_iAC = pAllItem->iMinAC; + h->_iMiscId = pAllItem->iMiscId; + h->_iSpell = pAllItem->iSpell; + if (pAllItem->iMiscId == IMID_STAFF) h->_iCharges = 18; // was 40 + h->_iMaxCharges = h->_iCharges; + h->_iDurability = pAllItem->iDurability; + h->_iMaxDur = pAllItem->iDurability; + h->_iMinStr = pAllItem->iMinStr; + h->_iMinMag = pAllItem->iMinMag; + h->_iMinDex = pAllItem->iMinDex; + h->_ivalue = pAllItem->iValue; + h->_iIvalue = pAllItem->iValue; + h->_iPrePower = -1; + h->_iSufPower = -1; + h->IDidx = idata; + h->_iMagical = IMAGIC_NONE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetPlrHandSeed(ItemStruct *h) +{ + h->_iSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetGoldSeed(int pnum, ItemStruct *h) +{ + int i, ii, s; + BOOL doneflag; + + do { + doneflag = TRUE; + s = GetRndSeed(); + for (i = 0; i < numitems; i++) { + ii = itemactive[i]; + if (item[ii]._iSeed == s) doneflag = FALSE; + } + if (pnum == myplr) { + for (i = 0; i < plr[pnum]._pNumInv; i++) + if (plr[pnum].InvList[i]._iSeed == s) doneflag = FALSE; + } + } while (!doneflag); + h->_iSeed = s; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlrHandSeed(ItemStruct *h, int iseed) +{ + h->_iSeed = iseed; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlrHandGoldCurs(ItemStruct *h) +{ + if (h->_ivalue >= GOLD_VT2) { + h->_iCurs = ITEM_5GOLD; + } else { + if (h->_ivalue <= GOLD_VT1) h->_iCurs = ITEM_1GOLD; + else h->_iCurs = ITEM_3GOLD; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CreatePlrItems(int p) { + int i; + ItemStruct * pi; + + // zero out carried items + pi = &plr[p].InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) + pi->_itype = -1; + + // zero inventory + ZeroMemory(plr[p].InvGrid,sizeof(plr[p].InvGrid)); + pi = &plr[p].InvList[0]; + for (i = MAXINV; i--; pi++) + pi->_itype = -1; + plr[p]._pNumInv = 0; + + // zero speedbar + pi = &plr[p].SpdList[0]; + for (i = MAXSPD; i--; pi++) + pi->_itype = -1; + + switch (plr[p]._pClass) { + case CLASS_WARRIOR : + // Sword in left + SetPlrHandItem(&plr[p].Hand1Item, IDI_WARRIOR); + GetPlrHandSeed(&plr[p].Hand1Item); + + // Shield in right + SetPlrHandItem(&plr[p].Hand2Item, IDI_WARRSHLD); + GetPlrHandSeed(&plr[p].Hand2Item); + +#if CHEATS + if (!davecheat) { + SetPlrHandItem(&plr[p].HoldItem, IDI_WARRCLUB); + GetPlrHandSeed(&plr[p].HoldItem); + AutoPlace(p, 0, 1, 3, TRUE); + } +#else + // Club in inv + SetPlrHandItem(&plr[p].HoldItem, IDI_WARRCLUB); + GetPlrHandSeed(&plr[p].HoldItem); + AutoPlace(p, 0, 1, 3, TRUE); +#endif + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + break; + + case CLASS_ROGUE : + #if !IS_VERSION(SHAREWARE) + // Bow in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_ROGUE); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + case CLASS_SORCEROR : + #if !IS_VERSION(SHAREWARE) + // Staff in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_SORCEROR); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); // was mana + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); // was mana + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + case CLASS_MONK : + #if !IS_VERSION(SHAREWARE) + // Bow in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_MONK); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + case CLASS_BARD : + #if !IS_VERSION(SHAREWARE) + // Bow in both hands + SetPlrHandItem(&plr[p].Hand1Item, IDI_BARD); + GetPlrHandSeed(&plr[p].Hand1Item); + SetPlrHandItem(&plr[p].Hand2Item, IDI_BARDDAGGER); + GetPlrHandSeed(&plr[p].Hand2Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + case CLASS_BARBARIAN : + #if !IS_VERSION(SHAREWARE) + // Club in left + SetPlrHandItem(&plr[p].Hand1Item, IDI_BARBARIAN); + GetPlrHandSeed(&plr[p].Hand1Item); + + // Shield in right + SetPlrHandItem(&plr[p].Hand2Item, IDI_BARSHLD); + GetPlrHandSeed(&plr[p].Hand2Item); + SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[0]); + SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL); + GetPlrHandSeed(&plr[p].SpdList[1]); + #endif + break; + + } + + SetPlrHandItem(&plr[p].HoldItem, IDI_GOLD); + GetPlrHandSeed(&plr[p].HoldItem); +#if CHEATS + if (!davecheat) { + // 100 Gold + plr[p].HoldItem._ivalue = 100; + plr[p].HoldItem._iCurs = ITEM_1GOLD; + plr[p]._pGold = plr[p].HoldItem._ivalue; + i = plr[p]._pNumInv; + plr[p].InvList[i] = plr[p].HoldItem; + plr[p]._pNumInv++; + plr[p].InvGrid[30] = plr[p]._pNumInv; + } + else { + // 200000 Gold + plr[p].HoldItem._ivalue = 5000; + plr[p].HoldItem._iCurs = ITEM_5GOLD; + plr[p]._pGold = 200000; + for (int j = 0; j < 40; j++) { + GetGoldSeed(p, &plr[p].HoldItem); + i = plr[p]._pNumInv; + plr[p].InvList[i] = plr[p].HoldItem; + plr[p]._pNumInv++; + plr[p].InvGrid[j] = plr[p]._pNumInv; + } + } +#else + // 100 Gold + plr[p].HoldItem._ivalue = 100; + plr[p].HoldItem._iCurs = ITEM_1GOLD; + plr[p]._pGold = plr[p].HoldItem._ivalue; + i = plr[p]._pNumInv; + plr[p].InvList[i] = plr[p].HoldItem; + plr[p]._pNumInv++; + plr[p].InvGrid[30] = plr[p]._pNumInv; +#endif + + CalcPlrItemVals(p,FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL ItemSpaceOk(int i, int j) +{ + int pn, oi; + + if ((i < 0) || (i >= DMAXX) || (j < 0) || (j >= DMAXY)) return(FALSE); + if (dMonster[i][j] != 0) return(FALSE); + if (dPlayer[i][j] != 0) return(FALSE); + if (dItem[i][j] != 0) return(FALSE); + if (dObject[i][j] != 0) { + if (dObject[i][j] > 0) oi = dObject[i][j]-1; + else oi = -(dObject[i][j]+1); + if (object[oi]._oSolidFlag) return(FALSE); + } + if (dObject[i+1][j+1] > 0) { + oi = dObject[i+1][j+1]-1; + if (object[oi]._oSelFlag != OSEL_NONE) return(FALSE); + } + if (dObject[i+1][j+1] < 0) { + oi = -(dObject[i+1][j+1]+1); + if (object[oi]._oSelFlag != OSEL_NONE) return(FALSE); + } + if ((dObject[i+1][j] > 0) && (dObject[i][j+1] > 0)) { + oi = dObject[i+1][j]-1; + if (object[oi]._oSelFlag != OSEL_NONE) { + oi = dObject[i][j+1]-1; + if (object[oi]._oSelFlag != OSEL_NONE) return(FALSE); + } + } + pn = dPiece[i][j]; + if (nSolidTable[pn]) return(FALSE); + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +#if CHEATS +void DaveISpaceOk(int inum) +{ + int i,j; + + for (j = 0; j < MAXDUNY; j++) { + for (i = 0; i < MAXDUNX; i++) { + if (dItem[i][j] == inum+1) + app_fatal("Item in map already"); + } + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL GetItemSpace(int x, int y, char inum) +{ + int i,j,xx,yy,rs; + BOOL savail; + + // Try surrounding squares + yy = 0; + for (j = (y-1); j <= (y+1); j++) { + xx = 0; + for (i = (x-1); i <= (x+1); i++) { + itemhold[xx][yy] = ItemSpaceOk(i,j); + xx++; + } + yy++; + } + + savail = FALSE; + for (yy = 0; yy < 3; yy++) { + for (xx = 0; xx < 3; xx++) { + if (itemhold[xx][yy]) savail = TRUE; + } + } + + // Must go here so same number of rnd calls on multiplayer machines + rs = random(13, 15) + 1; + + // No fit, no good + if (!savail) return(FALSE); + + // Place item + xx = 0; + yy = 0; + while (rs > 0) { + if (itemhold[xx][yy]) rs--; + if (rs > 0) { + xx++; + if (xx == 3) { + xx = 0; + yy++; + if (yy == 3) yy = 0; + } + } + } + xx = xx + x - 1; + yy = yy + y - 1; + item[inum]._ix = xx; + item[inum]._iy = yy; + //DaveISpaceOk(inum); + dItem[xx][yy] = inum + 1; + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetSuperItemSpace(int x, int y, char inum) +{ + // try normal method first + if (GetItemSpace(x, y, inum)) return; + + int xx, yy; + + // radial search outward until a space is found + for (int l = 2; l < 50; l++) { + for (int j = -l; j <= l; j++) { + yy = y + j; + for (int i = -l; i <= l; i++) { + xx = x + i; + if (! ItemSpaceOk(xx,yy)) continue; + + // drop it + item[inum]._ix = xx; + item[inum]._iy = yy; + //DaveISpaceOk(inum); + dItem[xx][yy] = inum + 1; + return; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetSuperItemLoc(int x, int y, int &xx, int &yy) +{ + // radial search outward until a space is found + for (int l = 1; l < 50; l++) { + for (int j = -l; j <= l; j++) { + yy = y + j; + for (int i = -l; i <= l; i++) { + xx = x + i; + if (ItemSpaceOk(xx,yy)) // found it + return; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CalcItemValue(int i) +{ + int v = item[i]._iVMult1 + item[i]._iVMult2; + if (v > 0) v = item[i]._ivalue * v; + if (v < 0) v = item[i]._ivalue / v; + v += item[i]._iVAdd1 + item[i]._iVAdd2; + if (v <= 0) v = 1; + item[i]._iIvalue = v; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetBookSpell(int i, int lvl) +{ + + if (lvl == 0) lvl = 1; + int rv = random(14, SPL_LAST) + 1; + + #if IS_VERSION(SHAREWARE) + if (lvl > 5) lvl = 5; + #endif + + int bs = SPL_FIREBOLT; + int s = SPL_FIREBOLT; + while (rv > 0) { + if ((spelldata[s].sBookLvl != -1) && (lvl >= spelldata[s].sBookLvl)) { + rv--; + bs = s; + } + + s++; + if ((gbMaxPlayers == 1) && (s == SPL_RESURRECT)) s++; + if ((gbMaxPlayers == 1) && (s == SPL_HEALOTHER)) s++; + if (s == SPL_LAST) s = SPL_FIREBOLT; + } + strcat(item[i]._iName, spelldata[bs].sNameText); + strcat(item[i]._iIName, spelldata[bs].sNameText); + item[i]._iSpell = bs; + item[i]._iMinMag = spelldata[bs].sMinInt; + item[i]._ivalue += spelldata[bs].sBookCost; + item[i]._iIvalue += spelldata[bs].sBookCost; + if (spelldata[bs].sType == ST_FIRE) item[i]._iCurs = ITEM_BOOK3; + else if (spelldata[bs].sType == ST_LIGHT) item[i]._iCurs = ITEM_BOOK; + else if (spelldata[bs].sType == ST_MISC) item[i]._iCurs = ITEM_BOOK2; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetStaffPower(int i, int lvl, int bs, BOOL onlygood) +{ + int pre; + int l[256], nl; + int j, aii; + int preidx; + char istr[128]; + BOOL addok; + + // Prefix only (for a staff w/ spell) + pre = random(15, 10); + + preidx = -1; + +#if CHEATS + if ((pre == 0) || (cheatflag) || (onlygood)) { +#else + if ((pre == 0) || (onlygood)) { +#endif + nl = 0; + for (j = 0; PL_Prefix[j].PLPower != -1; j++) { + if (((PL_Prefix[j].PLIType & PLF_STAFF) != 0) && (PL_Prefix[j].PLMinLvl <= lvl)) { + addok = TRUE; + if ((onlygood) && (!PL_Prefix[j].PLOk)) addok = FALSE; + + if (addok) { + l[nl] = j; + nl++; + if (PL_Prefix[j].PLDouble) { + l[nl] = j; + nl++; + } + } + } + } + if (nl != 0) { + preidx = l[random(16, nl)]; + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = IMAGIC_MAGIC; + SaveItemPower(i, PL_Prefix[preidx].PLPower, PL_Prefix[preidx].PLParam1, PL_Prefix[preidx].PLParam2, PL_Prefix[preidx].PLMinVal, PL_Prefix[preidx].PLMaxVal, PL_Prefix[preidx].PLMultVal); + item[i]._iPrePower = PL_Prefix[preidx].PLPower; + } + } + if (!InfoFit(item[i]._iIName)) { + aii = item[i].IDidx; + strcpy(item[i]._iIName, AllItemsList[aii].iSName); + if (preidx != -1) { + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + } + sprintf(istr, "%s of %s", item[i]._iIName, spelldata[bs].sNameText); + strcpy(item[i]._iIName, istr); + if (!item[i]._iMagical) strcpy(item[i]._iName, item[i]._iIName); + } + CalcItemValue(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetStaffSpell(int i, int lvl, BOOL onlygood) +{ + int rv, s, bs, l; + char tstr[64]; + int maxc, minc; + + //if (random(17, 4) == 0) GetItemPower(i, lvl >> 1, lvl, PLF_STAFF, onlygood); + //else +//{ + l = lvl >> 1; + if (l == 0) l = 1; + rv = random(18, SPL_LAST) + 1; + + #if IS_VERSION(SHAREWARE) + if (lvl > 10) lvl = 10; + #endif + + s = SPL_FIREBOLT; + while (rv > 0) { + if ((spelldata[s].sStaffLvl != -1) && (l >= spelldata[s].sStaffLvl)) { + rv--; + bs = s; + } + s++; + if ((gbMaxPlayers == 1) && (s == SPL_RESURRECT)) s++; + if ((gbMaxPlayers == 1) && (s == SPL_HEALOTHER)) s++; + if (s == SPL_LAST) s = SPL_FIREBOLT; + } + sprintf(tstr, "%s of %s", item[i]._iName, spelldata[bs].sNameText); + //Check to see if string will fit + if (!InfoFit(tstr)) { + sprintf(tstr, "Staff of %s", spelldata[bs].sNameText); + } + strcpy(item[i]._iName, tstr); + strcpy(item[i]._iIName, tstr); + item[i]._iSpell = bs; + minc = spelldata[bs].sStaffMin; + maxc = spelldata[bs].sStaffMax; + item[i]._iCharges = random(19, maxc-minc+1) + minc; + item[i]._iMaxCharges = item[i]._iCharges; + item[i]._iMinMag = spelldata[bs].sMinInt; + int v = (spelldata[bs].sStaffCost * item[i]._iCharges) / 5; + item[i]._ivalue += v; + item[i]._iIvalue += v; + GetStaffPower(i, lvl, bs, onlygood); +//} +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetOilType(int i, int lvl) +{ + int n, ro, roi, j; + char OilIndexList[30]; + + if (gbMaxPlayers == 1) { + if (lvl == 0) lvl = 1; + n = 0; + for (j=0; j < MAXOIL; j++) { + if (OilLvlTbl[j] <= lvl) { + OilIndexList[n] = j; + n++; + } + } + ro = random(165, n); + roi = OilIndexList[ro]; + } else { + ro = random(165, 2); + if (ro == 0) roi = 5; + else roi = 6; + } + + strcpy(item[i]._iName, OilStr[roi]); + strcpy(item[i]._iIName, OilStr[roi]); + item[i]._iMiscId = OilIdVal[roi]; + item[i]._ivalue = OilValue[roi]; + item[i]._iIvalue = OilValue[roi]; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemAttrs(int i, int idata, int lvl) +{ + int rndv; + + item[i]._itype = AllItemsList[idata].itype; + item[i]._iCurs = AllItemsList[idata].iCurs; + strcpy(item[i]._iName, AllItemsList[idata].iName); + strcpy(item[i]._iIName, AllItemsList[idata].iName); + item[i]._iLoc = AllItemsList[idata].iLoc; + item[i]._iClass = AllItemsList[idata].iClass; + item[i]._iMinDam = AllItemsList[idata].iMinDam; + item[i]._iMaxDam = AllItemsList[idata].iMaxDam; + item[i]._iAC = random(20, AllItemsList[idata].iMaxAC - AllItemsList[idata].iMinAC + 1) + AllItemsList[idata].iMinAC; + item[i]._iFlags = AllItemsList[idata].iFlags; + item[i]._iFlags2 = 0; + item[i]._iMiscId = AllItemsList[idata].iMiscId; + item[i]._iSpell = AllItemsList[idata].iSpell; + item[i]._iMagical = IMAGIC_NONE; + + item[i]._ivalue = AllItemsList[idata].iValue; + item[i]._iIvalue = AllItemsList[idata].iValue; + + item[i]._iVAdd1 = 0; + item[i]._iVMult1 = 0; + item[i]._iVAdd2 = 0; + item[i]._iVMult2 = 0; + + item[i]._iPLDam = 0; + item[i]._iPLToHit = 0; + item[i]._iPLAC = 0; + + item[i]._iPLStr = 0; + item[i]._iPLMag = 0; + item[i]._iPLDex = 0; + item[i]._iPLVit = 0; + + item[i]._iCharges = 0; + item[i]._iMaxCharges = 0; + + item[i]._iDurability = AllItemsList[idata].iDurability; + item[i]._iMaxDur = AllItemsList[idata].iDurability; + item[i]._iMinStr = AllItemsList[idata].iMinStr; + item[i]._iMinMag = AllItemsList[idata].iMinMag; + item[i]._iMinDex = AllItemsList[idata].iMinDex; + + item[i]._iPLFR = 0; + item[i]._iPLLR = 0; + item[i]._iPLMR = 0; + + item[i].IDidx = idata; + + item[i]._iPLDamMod = 0; + item[i]._iPLGetHit = 0; + item[i]._iPLLight = 0; + + item[i]._iSplLvlAdd = 0; + + item[i]._iRequest = FALSE; + + item[i]._iFMinDam = 0; + item[i]._iFMaxDam = 0; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + + item[i]._iPLEnAc = 0; + + item[i]._iPLMana = 0; + item[i]._iPLHP = 0; + + item[i]._iPrePower = -1; + item[i]._iSufPower = -1; + item[i]._iFlags = 0; + item[i]._iFlags2 = 0; + + if (item[i]._iMiscId == IMID_BOOK) GetBookSpell(i, lvl); + + if (item[i]._iMiscId == IMID_OIL) GetOilType(i, lvl); + + int efflevel = GetEffLevel(); + + if (item[i]._itype == IT_GOLD) { + if (gnDifficulty == D_NORMAL) + rndv = (efflevel * 5) + random(21, efflevel * 10); + else if (gnDifficulty == D_NIGHTMARE) + rndv = ((efflevel + 16) * 5) + random(21, (efflevel + 16) * 10); + else if (gnDifficulty == D_HELL) + rndv = ((efflevel + 32) * 5) + random(21, (efflevel + 32) * 10); + + if (leveltype == 4) rndv += (rndv >> 3); + if (rndv > 5000) rndv = 5000; + item[i]._ivalue = rndv; + if (rndv >= GOLD_VT2) { + item[i]._iCurs = ITEM_5GOLD; + } else { + if (rndv <= GOLD_VT1) item[i]._iCurs = ITEM_1GOLD; + else item[i]._iCurs = ITEM_3GOLD; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndPL(int param1, int param2) +{ + return(random(22, param2 - param1 + 1) + param1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PLVal(int pv, int p1, int p2, int minv, int maxv) +{ + if (p1 == p2) return(minv); + if (minv == maxv) return(minv); + return((((((pv - p1) * 100) / (p2 - p1)) * (maxv - minv)) / 100) + minv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval) +{ + int r, r2; + + r = RndPL(param1, param2); + switch (power) { + case PL_TOHIT: + item[i]._iPLToHit += r; + break; + case PL_NTOHIT: + item[i]._iPLToHit -= r; + break; + case PL_TODAM: + item[i]._iPLDam += r; + break; + case PL_NTODAM: + item[i]._iPLDam -= r; + break; + case PL_DOPPEL: + item[i]._iFlags2 |= IAF2_CLONE; + // fall through + case PL_DAHT: + r = RndPL(param1, param2); + item[i]._iPLDam += r; + if (param1 == 20) r2 = RndPL(1, 5); + if (param1 == 36) r2 = RndPL(6, 10); + if (param1 == 51) r2 = RndPL(11, 15); + if (param1 == 66) r2 = RndPL(16, 20); + if (param1 == 81) r2 = RndPL(21, 30); + if (param1 == 96) r2 = RndPL(31, 40); + if (param1 == 111) r2 = RndPL(41, 50); + if (param1 == 126) r2 = RndPL(51, 75); + if (param1 == 151) r2 = RndPL(76, 100); + item[i]._iPLToHit += r2; + break; + + case PL_NDAHT: + item[i]._iPLDam -= r; + if (param1 == 25) r2 = RndPL(1, 5); + if (param1 == 50) r2 = RndPL(6, 10); + item[i]._iPLToHit -= r2; + break; + case PL_AC: + item[i]._iPLAC += r; + break; + case PL_NAC: + item[i]._iPLAC -= r; + break; + case PL_ACTUALAC: + item[i]._iAC = r; + break; + case PL_NACTULAC: + item[i]._iAC -= r; + break; + case PL_RFIRE: + item[i]._iPLFR += r; + break; + case PL_RLGHT: + item[i]._iPLLR += r; + break; + case PL_RMAG: + item[i]._iPLMR += r; + break; + case PL_RALL: + item[i]._iPLFR += r; + item[i]._iPLLR += r; + item[i]._iPLMR += r; + if (item[i]._iPLFR < 0) item[i]._iPLFR = 0; + if (item[i]._iPLLR < 0) item[i]._iPLLR = 0; + if (item[i]._iPLMR < 0) item[i]._iPLMR = 0; + break; + case PL_SLVL: + item[i]._iSplLvlAdd = r; + break; + case PL_CHRG : + item[i]._iCharges = item[i]._iCharges * param1; + item[i]._iMaxCharges = item[i]._iCharges; + break; + case PL_SPELL : + item[i]._iSpell = param1; + item[i]._iCharges = param2; + item[i]._iMaxCharges = param2; + break; + case PL_FHIT: + item[i]._iFlags |= IAF_FIREHIT; + item[i]._iFlags &= ~IAF_LIGHTHIT; + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + break; + case PL_LHIT: + item[i]._iFlags |= IAF_LIGHTHIT; + item[i]._iFlags &= ~IAF_FIREHIT; + item[i]._iLMinDam = param1; + item[i]._iLMaxDam = param2; + item[i]._iFMinDam = 0; + item[i]._iFMaxDam = 0; + break; + case PL_STR: + item[i]._iPLStr += r; + break; + case PL_NSTR: + item[i]._iPLStr -= r; + break; + case PL_MAG: + item[i]._iPLMag += r; + break; + case PL_NMAG: + item[i]._iPLMag -= r; + break; + case PL_DEX: + item[i]._iPLDex += r; + break; + case PL_NDEX: + item[i]._iPLDex -= r; + break; + case PL_VIT: + item[i]._iPLVit += r; + break; + case PL_NVIT: + item[i]._iPLVit -= r; + break; + case PL_STATS: + item[i]._iPLStr += r; + item[i]._iPLMag += r; + item[i]._iPLDex += r; + item[i]._iPLVit += r; + break; + case PL_NSTATS: + item[i]._iPLStr -= r; + item[i]._iPLMag -= r; + item[i]._iPLDex -= r; + item[i]._iPLVit -= r; + break; + case PL_GETHIT: + item[i]._iPLGetHit += r; + break; + case PL_NGETHIT: + item[i]._iPLGetHit -= r; + break; + case PL_HP: + item[i]._iPLHP += (r << HP_SHIFT); + break; + case PL_NHP: + item[i]._iPLHP -= (r << HP_SHIFT); + break; + case PL_MANA: + item[i]._iPLMana += (r << MANA_SHIFT); + drawmanaflag = TRUE; + break; + case PL_NMANA: + item[i]._iPLMana -= (r << MANA_SHIFT); + drawmanaflag = TRUE; + break; + case PL_DUR: + r2 = (item[i]._iMaxDur * r) / 100; + item[i]._iMaxDur += r2; + item[i]._iDurability += r2; + break; + case PL_FRAGILE: + item[i]._iPLDam += 140 + r * 2; + // fall through + case PL_NDUR: + r2 = (item[i]._iMaxDur * r) / 100; + item[i]._iMaxDur -= r2; + if (item[i]._iMaxDur < 1) item[i]._iMaxDur = 1; + item[i]._iDurability = item[i]._iMaxDur; + break; + case PL_IND: + item[i]._iDurability = INFINITE_DUR; + item[i]._iMaxDur = INFINITE_DUR; + break; + case PL_LIGHT: + item[i]._iPLLight += param1; + break; + case PL_NLIGHT: + item[i]._iPLLight -= param1; + break; + case PL_NUMARWS: + item[i]._iFlags |= IAF_RABID; // unused -> multimissile --donald + break; + case PL_FARROW: + item[i]._iFlags |= IAF_FIREARROW; + item[i]._iFlags &= ~IAF_LARROW; + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + break; + case PL_LARROW: + item[i]._iFlags |= IAF_LARROW; + item[i]._iFlags &= ~IAF_FIREARROW; + item[i]._iLMinDam = param1; + item[i]._iLMaxDam = param2; + item[i]._iFMinDam = 0; + item[i]._iFMaxDam = 0; + break; + case PL_HITADD: // usurped for fireball arrows... + item[i]._iFlags |= (IAF_LARROW | IAF_FIREARROW); + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 0; + item[i]._iLMaxDam = 0; + break; + case PL_THORN: + item[i]._iFlags |= IAF_THORN; + break; + case PL_LMANA: + item[i]._iFlags |= IAF_LMANA; + drawmanaflag = TRUE; + break; + case PL_NOHEAL: + item[i]._iFlags |= IAF_NOHEAL; + break; + case PL_TRAPDAM: + item[i]._iFlags |= IAF_TRAPDAM; + break; + case PL_BEAR: + item[i]._iFlags |= IAF_KNOCKBACK; + break; + case PL_DAMDEMON: + item[i]._iFlags |= IAF_DAMDEMON; + break; + case PL_ZERORES: + item[i]._iFlags |= IAF_ZERORES; + break; + case PL_MNOHEAL: + item[i]._iFlags |= IAF_MNOHEAL; + break; + case PL_BAT: + if (param1 == 3) item[i]._iFlags |= IAF_BAT10; + if (param1 == 5) item[i]._iFlags |= IAF_BAT20; + drawmanaflag = TRUE; + break; + case PL_LEECH: + if (param1 == 3) item[i]._iFlags |= IAF_LEECH10; + if (param1 == 5) item[i]._iFlags |= IAF_LEECH20; + drawhpflag = TRUE; + break; + case PL_ENAC: + item[i]._iPLEnAc = param1; + break; + case PL_ATANIM: + if (param1 == 1) item[i]._iFlags |= IAF_ATANIM1; + if (param1 == 2) item[i]._iFlags |= IAF_ATANIM2; + if (param1 == 3) item[i]._iFlags |= IAF_ATANIM3; + if (param1 == 4) item[i]._iFlags |= IAF_ATANIM4; + break; + case PL_HTANIM: + if (param1 == 1) item[i]._iFlags |= IAF_HTANIM1; + if (param1 == 2) item[i]._iFlags |= IAF_HTANIM2; + if (param1 == 3) item[i]._iFlags |= IAF_HTANIM3; + break; + case PL_BLANIM: + item[i]._iFlags |= IAF_BLANIM; + break; + case PL_DAMADD: + item[i]._iPLDamMod += r; + break; + case PL_RNDARW: + item[i]._iFlags |= IAF_RNDARROW; + break; + case PL_DAMAGE: + item[i]._iMinDam = param1; + item[i]._iMaxDam = param2; + break; + case PL_DURNUM: + item[i]._iDurability = param1; + item[i]._iMaxDur = param1; + break; + case PL_FALCON: + item[i]._iFlags |= IAF_ATANIM3; + break; + case PL_ONEHAND: + item[i]._iLoc = IL_HAND; + break; + case PL_CONST: + item[i]._iFlags |= IAF_CONSTRICT; + break; + case PL_SKING: + item[i]._iFlags |= IAF_SKING; + break; + case PL_INFRA: + item[i]._iFlags |= IAF_INFRAVISION; + break; + case PL_NSTRREQ: + item[i]._iMinStr = 0; + break; + case PL_GFX: + item[i]._iCurs = param1; + break; + case PL_HARQUN: // usurped for lightning arrows + item[i]._iFlags |= (IAF_LARROW | IAF_FIREARROW); + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 1; + item[i]._iLMaxDam = 0; +#if 0 + //rjs item[i]._iPLHP = (byte)plr[myplr]._pArmorClass + plr[myplr]._pIBonusAC + plr[myplr]._pIAC; + item[i]._iPLHP = plr[myplr]._pIBonusAC + plr[myplr]._pIAC; + item[i]._iPLHP += (plr[myplr]._pDexterity / 5); + item[i]._iPLHP = item[i]._iPLHP << HP_SHIFT; +#endif + break; + case PL_HARQUN2: + item[i]._iFlags |= (IAF_LIGHTHIT | IAF_FIREHIT); + item[i]._iFMinDam = param1; + item[i]._iFMaxDam = param2; + item[i]._iLMinDam = 2; + item[i]._iLMaxDam = 0; +// item[i]._iAC += ((plr[myplr]._pMaxManaBase >> MANA_SHIFT) / 10); + break; + case PL_HARQUN3: + item[i]._iPLFR = 30 - plr[myplr]._pLevel; + if (item[i]._iPLFR < 0) item[i]._iPLFR = 0; + break; + case PL_NRFIRE: + item[i]._iPLFR -= r; + break; + case PL_NRLGHT: + item[i]._iPLLR -= r; + break; + case PL_NRMAG: + item[i]._iPLMR -= r; + break; + case PL_NRALL: + item[i]._iPLFR -= r; + item[i]._iPLLR -= r; + item[i]._iPLMR -= r; + break; + case PL_DEVAST: + item[i]._iFlags2 |= IAF2_DEVASTATION; + break; + case PL_DECAY: + item[i]._iFlags2 |= IAF2_DECAY; + item[i]._iPLDam += r; + break; + case PL_PERIL: + item[i]._iFlags2 |= IAF2_PERIL; + break; + case PL_RNDDAM: + item[i]._iFlags2 |= IAF2_JESTER; + break; + + case PL_DEMONAC: + item[i]._iFlags2 |= IAF2_DEMONAC; + break; + case PL_UNDEADAC: + item[i]._iFlags2 |= IAF2_UNDEADAC; + break; + + case PL_ACOLYTE: + r2 = ((plr[myplr]._pMaxManaBase >> MANA_SHIFT) * 50 / 100); + item[i]._iPLMana -= (r2 << MANA_SHIFT); + item[i]._iPLHP += (r2 << HP_SHIFT); + break; + case PL_GLADIATR: + r2 = ((plr[myplr]._pMaxHPBase >> HP_SHIFT) * 40 / 100); + item[i]._iPLHP -= (r2 << HP_SHIFT); + item[i]._iPLMana += (r2 << MANA_SHIFT); + break; + } + if ((item[i]._iVAdd1 == 0) && (item[i]._iVMult1 == 0)) { + item[i]._iVAdd1 = PLVal(r, param1, param2, minval, maxval); + item[i]._iVMult1 = multval; + } else { + item[i]._iVAdd2 = PLVal(r, param1, param2, minval, maxval); + item[i]._iVMult2 = multval; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemPower(int i, int minlvl, int maxlvl, long flgs, BOOL onlygood) +{ + int pre, post; + int l[256], nl; + int j, aii; + int preidx, sufidx; + char istr[128]; + byte goe; + + pre = random(23, 4); // Pre modifier (20%) + post = random(23, 3); // Post modifirer (66%) + // if no pre modifier, make sure post modifier + if ((pre != 0) && (post == 0)) { + if (random(23, 2)) post = 1; + else pre = 0; + } + + preidx = -1; + sufidx = -1; + goe = 0; + + // if not any only good item, then 67% chance of good, 33% chance of anything + if ((!onlygood) && (random(0, 3))) onlygood = TRUE; + + if (pre == 0) { + nl = 0; + for (j = 0; PL_Prefix[j].PLPower != -1; j++) { + if (((PL_Prefix[j].PLIType & flgs) != 0) && + (PL_Prefix[j].PLMinLvl >= minlvl) && + (PL_Prefix[j].PLMinLvl <= maxlvl) + ) { + if (onlygood && !PL_Prefix[j].PLOk) continue; + if ((flgs == PLF_STAFF) && (PL_Prefix[j].PLPower == PL_CHRG)) continue; + + l[nl] = j; + nl++; + if (PL_Prefix[j].PLDouble) { + l[nl] = j; + nl++; + } + } + } + if (nl != 0) { + preidx = l[random(23, nl)]; + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = IMAGIC_MAGIC; + SaveItemPower(i, PL_Prefix[preidx].PLPower, PL_Prefix[preidx].PLParam1, PL_Prefix[preidx].PLParam2, PL_Prefix[preidx].PLMinVal, PL_Prefix[preidx].PLMaxVal, PL_Prefix[preidx].PLMultVal); + item[i]._iPrePower = PL_Prefix[preidx].PLPower; + goe = PL_Prefix[preidx].PLGOE; + } + } + if (post != 0) { + nl = 0; + for (j = 0; PL_Suffix[j].PLPower != -1; j++) { + if (((PL_Suffix[j].PLIType & flgs) != 0) && + (PL_Suffix[j].PLMinLvl >= minlvl) && + (PL_Suffix[j].PLMinLvl <= maxlvl) && + ((goe | PL_Suffix[j].PLGOE) != 0x11) + ) { + if (onlygood && !PL_Suffix[j].PLOk) continue; + + l[nl] = j; + nl++; + } + } + if (nl != 0) { + sufidx = l[random(23, nl)]; + sprintf(istr, "%s of %s", item[i]._iIName, PL_Suffix[sufidx].PLName); + strcpy(item[i]._iIName, istr); + item[i]._iMagical = IMAGIC_MAGIC; + SaveItemPower(i, PL_Suffix[sufidx].PLPower, PL_Suffix[sufidx].PLParam1, PL_Suffix[sufidx].PLParam2, PL_Suffix[sufidx].PLMinVal, PL_Suffix[sufidx].PLMaxVal, PL_Suffix[sufidx].PLMultVal); + item[i]._iSufPower = PL_Suffix[sufidx].PLPower; + } + } + if (!InfoFit(item[i]._iIName)) { + aii = item[i].IDidx; + if (AllItemsList[aii].iSName) + strcpy(item[i]._iIName, AllItemsList[aii].iSName); + else + item[i]._iName[0] = 0; + + if (preidx != -1) { + sprintf(istr, "%s %s", PL_Prefix[preidx].PLName, item[i]._iIName); + strcpy(item[i]._iIName, istr); + } + if (sufidx != -1) { + sprintf(istr, "%s of %s", item[i]._iIName, PL_Suffix[sufidx].PLName); + strcpy(item[i]._iIName, istr); + } + } + if ((preidx != -1) || (sufidx != -1)) CalcItemValue(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemBonus(int i, int idata, int minlvl, int maxlvl, BOOL onlygood, bool SpellsOk) +{ + if (item[i]._iClass == IC_GOLD) return; + if (minlvl > 25) minlvl = 25; + + switch(item[i]._itype) { + case IT_SWORD : + case IT_AXE: + case IT_MACE: + GetItemPower(i, minlvl, maxlvl, PLF_WEAPON, onlygood); + break; + case IT_BOW: + GetItemPower(i, minlvl, maxlvl, PLF_BOW, onlygood); + break; + case IT_SHIELD: + GetItemPower(i, minlvl, maxlvl, PLF_SHIELD, onlygood); + break; + case IT_ARMOR: + case IT_HELM: + case IT_MARMOR: + case IT_HARMOR: + GetItemPower(i, minlvl, maxlvl, PLF_ARMOR, onlygood); + break; + case IT_STAFF: + if (SpellsOk) + GetStaffSpell(i, maxlvl, onlygood); + else + GetItemPower(i, minlvl, maxlvl, PLF_STAFF, onlygood); + break; + case IT_RING: + case IT_AMULET: + GetItemPower(i, minlvl, maxlvl, PLF_RING, onlygood); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetupItem(int i) +{ + int it; + + DROPLOG("SetupItem: setting up object %d!\n",i); + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimData = itemanims[it]; + item[i]._iAnimLen = ItemAnimLs[it]; + item[i]._iAnimWidth = 96; + item[i]._iAnimWidth2 = 16; + item[i]._iIdentified = FALSE; + item[i]._iPostDraw = FALSE; + if (plr[myplr].pLvlLoad == LVLCHANGE_OFF) { + item[i]._iAnimFrame = 1; + item[i]._iAnimFlag = TRUE; + item[i]._iSelFlag = ISEL_NONE; + } else { + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = FALSE; + item[i]._iSelFlag = ISEL_FLR; + } +} + +/*-----------------------------------------------------------------------* +** Choose an item type from a monster +**-----------------------------------------------------------------------*/ + +int RndItem(int m) +{ + int r; + int ril[512]; // Max 512 items + int ri, i; + + // Unique item? + if (monster[m].MData->mTreasure & T_U) + return(-((monster[m].MData->mTreasure & T_MASK) + 1)); + + if (monster[m].MData->mTreasure & T_NONE) return(0); + +#if CHEATS + if (davedebug) r = 100; + else r = random(24, 100); + if (!cheatflag && (r > 40)) return(0); + if (!cheatflag && (random(24, 100) > 25)) return(IDI_GOLD+1); +#else + r = random(24, 100); + if (r > 40) return(0); + // Gold 75% of the time + if (random(24, 100) > 25) return(IDI_GOLD+1); +#endif + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + if ((AllItemsList[i].iRnd == IRND_DOUBLE) && + (monster[m].mLevel >= AllItemsList[i].iMinMLvl) + && ri < 512) ril[ri++] = i; + if (AllItemsList[i].iRnd && + (monster[m].mLevel >= AllItemsList[i].iMinMLvl) + && ri < 512) ril[ri++] = i; + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) ri--; + if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) ri--; + } + r = random(24, ri); + return(ril[r]+1); +} + +/*-----------------------------------------------------------------------* +** Choose an item type for a good or unique item +**-----------------------------------------------------------------------*/ + +int RndUItem(int m) +{ + int ril[512]; // Max 512 items + int ri, i; + BOOL okflag; + + // Unique item? + if (m != -1) { + if ((monster[m].MData->mTreasure & T_U) && (gbMaxPlayers == 1)) + return(-((monster[m].MData->mTreasure & T_MASK) + 1)); + } + int efflevel = GetEffLevel(); + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + okflag = TRUE; + if (!AllItemsList[i].iRnd) okflag = FALSE; + if (m != -1) { + if (monster[m].mLevel < AllItemsList[i].iMinMLvl) okflag = FALSE; + } else { + if ((efflevel << 1) < AllItemsList[i].iMinMLvl) okflag = FALSE; + } + if (AllItemsList[i].itype == IT_MISC) okflag = FALSE; + if (AllItemsList[i].itype == IT_GOLD) okflag = FALSE; + if (AllItemsList[i].itype == IT_FOOD) okflag = FALSE; + if (AllItemsList[i].iMiscId == IMID_BOOK) okflag = TRUE; + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) okflag = FALSE; + if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) okflag = FALSE; + if (okflag && ri < 512) ril[ri++] = i; + } + return(ril[random(25, ri)]); +} + +/*-----------------------------------------------------------------------* +** Choose any type of item +**-----------------------------------------------------------------------*/ + +int RndAllItems() +{ + int r; + int ril[512]; // Max 512 items + int ri, i; + +#if CHEATS + if (!cheatflag && !itemcheat && (random(26, 100) > 25)) return(IDI_GOLD); +#else + // Gold 75% of the time + if (random(26, 100) > 25) return(IDI_GOLD); +#endif + int efflevel = GetEffLevel(); + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && ((efflevel << 1) >= AllItemsList[i].iMinMLvl) + && ri < 512) ril[ri++] = i; + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) ri--; + if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) ri--; + } + r = random(26, ri); + return(ril[r]); +} + +/*-----------------------------------------------------------------------* +** Choose an item of a specific type +**-----------------------------------------------------------------------*/ + +int RndTypeItems(int itype, int imid, int level) +{ + int ril[512]; // Max 512 items + int ri, i; + BOOL okflag; + + ri = 0; + for (i = 0; AllItemsList[i].iLoc != -1; i++) { + okflag = TRUE; + if (!AllItemsList[i].iRnd) okflag = FALSE; + if ((level << 1) < AllItemsList[i].iMinMLvl) okflag = FALSE; + if (AllItemsList[i].itype != itype) okflag = FALSE; + if ((imid != -1) && (AllItemsList[i].iMiscId != imid)) okflag = FALSE; + if (okflag && ri < 512) + ril[ri++] = i; + } + return(ril[random(27, ri)]); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int CheckUnique(int i, int lvl, int uper, BOOL recreate) +{ + int j, idata; + BYTE uok[MAXUITEMS]; + int numu, u; + +#if CHEATS + if (!davedebug || !cheatflag) { + if (random(28, 100) > uper) return(-1); + } +#else + if (random(28, 100) > uper) return(-1); +#endif + + numu = 0; + ZeroMemory(uok,sizeof(uok)); + for (j = 0; UniqueItemList[j].UIItemId != -1; j++) { + idata = item[i].IDidx; + if (UniqueItemList[j].UIItemId != AllItemsList[idata].iItemId) continue; + if (lvl < UniqueItemList[j].UIMinLvl) continue; + if (!recreate && UniqueItemFlag[j] && (gbMaxPlayers == 1)) continue; + uok[j] = TRUE; + numu++; + } + + if (numu == 0) return(-1); + u = random(29, 10); + j = 0; + while (numu > 0) { + if (uok[j]) numu--; + if (numu > 0) { + j++; + if (j == MAXUITEMS) j = 0; + } + } + return(j); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetUniqueItem(int i, int uid) +{ + // Generated + UniqueItemFlag[uid] = TRUE; + // Save abilities + SaveItemPower(i, UniqueItemList[uid].UIPower1, UniqueItemList[uid].UIParam1, UniqueItemList[uid].UIParam2, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 1) + SaveItemPower(i, UniqueItemList[uid].UIPower2, UniqueItemList[uid].UIParam3, UniqueItemList[uid].UIParam4, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 2) + SaveItemPower(i, UniqueItemList[uid].UIPower3, UniqueItemList[uid].UIParam5, UniqueItemList[uid].UIParam6, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 3) + SaveItemPower(i, UniqueItemList[uid].UIPower4, UniqueItemList[uid].UIParam7, UniqueItemList[uid].UIParam8, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 4) + SaveItemPower(i, UniqueItemList[uid].UIPower5, UniqueItemList[uid].UIParam9, UniqueItemList[uid].UIParam10, 0, 0, 1); + if (UniqueItemList[uid].UINumPL > 5) + SaveItemPower(i, UniqueItemList[uid].UIPower6, UniqueItemList[uid].UIParam11, UniqueItemList[uid].UIParam12, 0, 0, 1); + // Save name + strcpy(item[i]._iIName, UniqueItemList[uid].UIName); + item[i]._iIvalue = UniqueItemList[uid].UIValue; + if (item[i]._iMiscId == IMID_UNIQUE) item[i]._iSeed = uid; // Save index into UniqueItemList + item[i]._iUid = uid; // Save index into Unique Item List + item[i]._iMagical = IMAGIC_UNIQUE; + item[i]._iCreateInfo |= ICI_UNIQUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnUnique(int uid, int x, int y) +{ + int ii, itype; + + int efflevel = GetEffLevel(); + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + itype = 0; + while (AllItemsList[itype].iItemId != UniqueItemList[uid].UIItemId) itype++; + GetItemAttrs(ii, itype, efflevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + numitems++; + } +} + + +/*-----------------------------------------------------------------------* +** Items in dungeon have lower durs +**-----------------------------------------------------------------------*/ + +void ItemRndDur(int ii) +{ + if (item[ii]._iDurability == 0) return; + if (item[ii]._iDurability == INFINITE_DUR) return; + item[ii]._iDurability = random(0, item[ii]._iMaxDur >> 1) + (item[ii]._iMaxDur >> 2) + 1; +} + +/*-----------------------------------------------------------------------* +** Setup an item and determine magics +**-----------------------------------------------------------------------*/ + +void SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, BOOL onlygood, BOOL recreate, BOOL pregen) +{ + int iblvl, uid; + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + GetItemAttrs(ii, idx, lvl >> 1); + item[ii]._iCreateInfo = lvl; + if (pregen) item[ii]._iCreateInfo |= ICI_PREGEN; + if (onlygood) item[ii]._iCreateInfo |= ICI_ONLYGOOD; + if (uper == 15) item[ii]._iCreateInfo |= ICI_UPER15; + else if (uper == 1) item[ii]._iCreateInfo |= ICI_UPER1; + if (item[ii]._iMiscId != IMID_UNIQUE) { + iblvl = -1; + if (random(32, 100) <= 10) iblvl = lvl; + else if (random(33, 100) <= lvl) iblvl = lvl; + // Force rings, amulets, and staffs to be magical + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_STAFF)) iblvl = lvl; + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_RING)) iblvl = lvl; + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_AMULET)) iblvl = lvl; + if (onlygood) iblvl = lvl; +#if CHEATS + if (cheatflag) iblvl = lvl; +#endif + if (uper == 15) iblvl = lvl + 4; + if (iblvl != -1) { + uid = CheckUnique(ii, iblvl, uper, recreate); + if (uid == -1) + GetItemBonus(ii, idx, iblvl >> 1, iblvl, onlygood, true); + else { + GetUniqueItem(ii, uid); + item[ii]._iCreateInfo |= ICI_UNIQUE; + } + } + if (item[ii]._iMagical != IMAGIC_UNIQUE) ItemRndDur(ii); + } else { + // if it is something they wield, then get the attributes + if (item[ii]._iLoc != IL_INV) GetUniqueItem(ii, iseed); + } + SetupItem(ii); +} + +/*-----------------------------------------------------------------------* +** Create any item from a monster (or unqiue if monster gives one up) +**-----------------------------------------------------------------------*/ + +void SpawnItem(int m, int x, int y, BOOL sendmsg) +{ + int ii, idx; + BOOL onlygood; + + if ((monster[m]._uniqtype != 0) || + ((monster[m].MData->mTreasure & T_U) && (gbMaxPlayers != 1))) { + // If unique, make sure we get something good + idx = RndUItem(m); + if (idx < 0) { + SpawnUnique(-(idx+1), x, y); + return; + } + onlygood = TRUE; + } else { + // special code to pop out brain for Mushroom Quest + if (quests[Q_BKMUSHRM]._qactive == QUEST_NOTDONE + && quests[Q_BKMUSHRM]._qvar1 == QS_MUSHGIVEN) { + idx = IDI_BRAIN; + quests[Q_BKMUSHRM]._qvar1 = QS_BRAINSPAWNED; + } + else + { + idx = RndItem(m); + if (idx == 0) return; + if (idx > 0) { + idx--; + onlygood = FALSE; + } else { + SpawnUnique(-(idx+1), x, y); + return; + } + } + } + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + if (monster[m]._uniqtype != 0) SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 15, onlygood, FALSE, FALSE); +#if CHEATS + else if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 15, TRUE, FALSE, FALSE); +#endif + else SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 1, onlygood, FALSE, FALSE); + + numitems++; + if (sendmsg) NetSendCmdDItem(FALSE, ii); + } +} + + +/*-----------------------------------------------------------------------* +** Only used for quest (single player) +**-----------------------------------------------------------------------*/ + +void CreateItem(int uid, int x, int y) +{ + int ii, idx; + + int efflevel = GetEffLevel(); + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + idx = 0; + while (AllItemsList[idx].iItemId != UniqueItemList[uid].UIItemId) idx++; + GetItemAttrs(ii, idx, efflevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + item[ii]._iMagical = IMAGIC_UNIQUE; + numitems++; + } +} + + +/*-----------------------------------------------------------------------* +** Create any item from an object, etc (chest, barrel, sarc) +**-----------------------------------------------------------------------*/ + +void CreateRndItem(int x, int y, BOOL onlygood, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + + int efflevel = GetEffLevel(); + + if (onlygood) idx = RndUItem(-1); + else idx = RndAllItems(); + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 1, onlygood, FALSE, delta); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetupAllUseful(int ii, int iseed, int lvl) +{ + int idx; + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + +#if 0 + if (random(34, 2)) idx = IDI_HEAL; + else idx = IDI_MANA; + + // added 7/30/97 by donald + if (!random(34, 8)) idx = IDI_OILACC; + + if ((lvl > 1) && (random(34, 3) == 0)) idx = IDI_PORTAL; +#else + // why call random() so many times? + + switch(random(34,7)) + { + case 0: idx = IDI_PORTAL; if (lvl > 1) break; // else fallthrough + case 1: + case 2: idx = IDI_HEAL; break; + case 3: idx = IDI_PORTAL; if (lvl > 1) break; // else fallthrough + case 4: + case 5: idx = IDI_MANA; break; + default:idx = IDI_OILACC; break; + } +#endif + + GetItemAttrs(ii, idx, lvl); + item[ii]._iCreateInfo = ICI_USEFUL + lvl; + SetupItem(ii); +} + +/*-----------------------------------------------------------------------* +** Rnd item, but only health, mana, or id +**-----------------------------------------------------------------------*/ + +void CreateRndUseful(int pnum, int x, int y, BOOL sendmsg) +{ + int ii; + + int efflevel = GetEffLevel(); + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + SetupAllUseful(ii, GetRndSeed(), efflevel); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +** Create any item of a specific type +**-----------------------------------------------------------------------*/ + +void CreateTypeItem(int x, int y, BOOL onlygood, int itype, int imisc, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + + int efflevel = GetEffLevel(); + + if (itype != IT_GOLD) idx = RndTypeItems(itype, imisc, efflevel); + else idx = 0; + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 1, onlygood, FALSE, delta); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +** Recreate any item with the proper info +**-----------------------------------------------------------------------*/ + +void RecreateItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue) +{ + int uper; + BOOL onlygood, uavail, pregen; + + // PATCH1.JMM + #if 0 + int i, nIndex; + for(i = 0; i < numitems; i++) { + nIndex = itemactive[i]; + + if(((item[nIndex]._iSeed == iseed) && (item[nIndex]._iCreateInfo == icreateinfo) && (item[nIndex].IDidx == idx))) + DROPLOG(" Creating dupped item: idx->%8.8x seed->%8.8x ci->%8.8x\n",idx,iseed,icreateinfo); + + app_assert(!((item[nIndex]._iSeed == iseed) && (item[nIndex]._iCreateInfo == icreateinfo) && (item[nIndex].IDidx == idx))); + } + #endif + // ENDPATCH1.JMM + + + // Gold + if (idx == IDI_GOLD) { + SetPlrHandItem(&item[ii], idx); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = icreateinfo; + item[ii]._ivalue = ivalue; + if (item[ii]._ivalue >= GOLD_VT2) { + item[ii]._iCurs = ITEM_5GOLD; + } else { + if (ivalue <= GOLD_VT1) item[ii]._iCurs = ITEM_1GOLD; + else item[ii]._iCurs = ITEM_3GOLD; + } + } else { + // One the the players initial items? + if (icreateinfo == 0) { + SetPlrHandItem(&item[ii], idx); + SetPlrHandSeed(&item[ii], iseed); + } else { + // From town? + if (icreateinfo & ICI_TOWNMASK) RecreateTownItem(ii, idx, icreateinfo, iseed, ivalue); + else { + // From dungeon + if ((icreateinfo & ICI_USEFUL) == ICI_USEFUL) { + SetupAllUseful(ii, iseed, icreateinfo & ICI_LVLMASK); + } else { + uper = 0; + onlygood = FALSE; + uavail = FALSE; + pregen = FALSE; + if (icreateinfo & ICI_UPER1) uper = 1; + if (icreateinfo & ICI_UPER15) uper = 15; + if (icreateinfo & ICI_ONLYGOOD) onlygood = TRUE; + if (icreateinfo & ICI_UNIQUE) uavail = TRUE; + if (icreateinfo & ICI_PREGEN) pregen = TRUE; + SetupAllItems(ii, idx, iseed, icreateinfo & ICI_LVLMASK, uper, onlygood, uavail, pregen); + } + } + } + } +} + +/*-----------------------------------------------------------------------* +** Recreate any ear with the proper info +**-----------------------------------------------------------------------*/ + +void RecreateEar(int ii, WORD ic, int iseed, BOOL Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff) +{ + SetPlrHandItem(&item[ii], IDI_EAR); + tempstr[0] = (ic >> 8) & 0x7f; + tempstr[1] = ic & 0x7f; + tempstr[2] = (iseed >> 24) & 0x7f; + tempstr[3] = (iseed >> 16) & 0x7f; + tempstr[4] = (iseed >> 8) & 0x7f; + tempstr[5] = iseed & 0x7f; + tempstr[6] = Id & 0x7f; + tempstr[7] = dur & 0x7f; + tempstr[8] = mdur & 0x7f; + tempstr[9] = ch & 0x7f; + tempstr[10] = mch & 0x7f; + tempstr[11] = (ivalue >> 8) & 0x7f; + tempstr[12] = (ibuff >> 24) & 0x7f; + tempstr[13] = (ibuff >> 16) & 0x7f; + tempstr[14] = (ibuff >> 8) & 0x7f; + tempstr[15] = ibuff & 0x7f; + tempstr[16] = 0; + sprintf(item[ii]._iName, "Ear of %s", tempstr); + item[ii]._iCurs = ((ivalue >> 6) & 0x3) + ITEM_EAR1; + item[ii]._ivalue = ivalue & 0x3f; + item[ii]._iCreateInfo = ic; + item[ii]._iSeed = iseed; +} + + +const char * sgszCornerstone = "SItem"; + +void CornerstoneSave() +{ + if (!CornerStone.Initted) + return; + + PkItemStruct pki; + + if (CornerStone.item.IDidx >= 0) + { + PackItem(&pki, &(CornerStone.item)); + SRegSaveData(gszProgKey,sgszCornerstone,0, &pki, sizeof(PkItemStruct)); + } + else + { + SRegSaveData(gszProgKey,sgszCornerstone, 0, "", 1); + } +} + +void CornerstoneRestore(int x, int y) +{ + if (CornerStone.Initted) + return; + + // read the info out of the options file + PkItemStruct pki; + + if (x == 0 || y == 0) + return; + + CornerStone.item.IDidx = 0; + CornerStone.Initted = TRUE; + + if (dItem[x][y] != 0) + { + // clear the square + int ii = dItem[x][y] - 1; + for (int i = 0; i < numitems; ++i) + if (itemactive[i] == ii) + { + DeleteItem(ii, i); + break; + } + dItem[x][y] = 0; + } + + DWORD bytesread = 0; + if (! SRegLoadData(gszProgKey,sgszCornerstone, 0, &pki, sizeof(PkItemStruct), &bytesread)) + return; + + if (bytesread != sizeof(PkItemStruct)) + return; + + // create a new item slot + int ii = itemavail[0]; + dItem[x][y] = ii+1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + UnPackItem(&pki, &item[ii]); + item[ii]._ix = x; + item[ii]._iy = y; + + DROPLOG("CornerstoneRestore: respawning object %d!\n",ii); + RespawnItem(ii, FALSE); + CornerStone.item = item[ii]; + + numitems++; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnQuestItem(int itemid, int x,int y, int randarea, int selflag) +{ + int i,j; + BOOL failed; + + int efflevel = GetEffLevel(); + + if (randarea) { + int tries = 0; + do { + if (++tries > 1000 && randarea > 1) + --randarea; + x = random(0, DMAXX); + y = random(0, DMAXY); + failed = FALSE; + for (i = 0; i < randarea && !failed; i++) + for (j = 0; j < randarea && !failed; j++) + failed = !ItemSpaceOk(x + i, y + j); + } while (failed); + } + + if (numitems < MAXITEMS) { + i = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = i; + item[i]._ix = x; + item[i]._iy = y; + dItem[x][y] = i + 1; + GetItemAttrs(i, itemid, efflevel); + SetupItem(i); + item[i]._iPostDraw = TRUE; + if (selflag != ISEL_NONE) { + // selflag indicates creation of post-flippy item + item[i]._iSelFlag = selflag; + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = FALSE; + } + + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SpawnRock() +{ + int i, ii, ostand; + int xx,yy; + BOOL done = FALSE; + + for (i = 0; i < numobjects && !done; i++) { + ostand = objectactive[i]; + done = (object[ostand]._otype == 23); // OBJ_STAND + } + + int efflevel = GetEffLevel(); + + if(done) + { + ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + xx = item[ii]._ix = object[ostand]._ox; + yy = item[ii]._iy = object[ostand]._oy; + dItem[xx][yy] = ii + 1; + GetItemAttrs(ii, IDI_ROCK, efflevel); + SetupItem(ii); + item[ii]._iSelFlag = ISEL_TOP; + item[ii]._iPostDraw = TRUE; + item[ii]._iAnimFrame = 11; + + numitems++; + } +} + +void SpawnSomething(int what, int xx, int yy) +{ + int ii = itemavail[0]; + + int efflevel = GetEffLevel(); + + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + item[ii]._ix = xx; + item[ii]._iy = yy; + dItem[xx][yy] = ii + 1; + GetItemAttrs(ii, what, efflevel); + SetupItem(ii); + item[ii]._iSelFlag = ISEL_TOP; + item[ii]._iPostDraw = TRUE; + item[ii]._iAnimFrame = 1; // item[ii]._iAnimLen; + item[ii]._iAnimFlag = TRUE; + item[ii]._iIdentified = TRUE; + + numitems++; +} + +void SpawnMap(int xx, int yy) +{ + SpawnSomething(IDI_MAPOFDOOM, xx, yy); +} + +void SpawnBomb(int xx, int yy) +{ + SpawnSomething(IDI_RUNEBOMB, xx, yy); +} + +void SpawnBear(int xx, int yy) +{ + SpawnSomething(IDI_THEODORE, xx, yy); +} + +void SpawnCowArmor(int xx, int yy) +{ + CreateItem(UID_ARMRCOW, xx, yy); +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RespawnItem(int i, BOOL FlipFlag) +{ + int it; + + DROPLOG(" RespawnItem: Respawning item %d!\n",i); + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimData = itemanims[it]; + item[i]._iAnimLen = ItemAnimLs[it]; + item[i]._iAnimWidth = 96; + item[i]._iAnimWidth2 = 16; + item[i]._iPostDraw = FALSE; + item[i]._iRequest = FALSE; + if (FlipFlag) { + item[i]._iAnimFrame = 1; + item[i]._iAnimFlag = TRUE; + item[i]._iSelFlag = ISEL_NONE; + } else { + item[i]._iAnimFrame = item[i]._iAnimLen; + item[i]._iAnimFlag = FALSE; + item[i]._iSelFlag = ISEL_FLR; + } + if (item[i]._iCurs == ITEM_ROCK) { + item[i]._iSelFlag = ISEL_FLR; + PlaySfxLoc(ItemAnimSnds[it], item[i]._ix, item[i]._iy); + } + if (item[i]._iCurs == ITEM_INNSIGN) item[i]._iSelFlag = ISEL_FLR; + if (item[i]._iCurs == ITEM_ANVIL) item[i]._iSelFlag = ISEL_FLR; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DeleteItem(int ii, int i) +{ + itemavail[MAXITEMS - numitems] = ii; + numitems--; + if ((numitems > 0) && (i != numitems)) { + itemactive[i] = itemactive[numitems]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int idoppely = DIRTEDGED2; + +void ItemDoppel() +{ + int idoppelx; + ItemStruct *i; + + if (gbMaxPlayers == 1) return; + + for (idoppelx = DIRTEDGED2; idoppelx < (DIRTEDGED2+80); idoppelx++) { + if (dItem[idoppelx][idoppely]) { + i = &item[dItem[idoppelx][idoppely] - 1]; + if ((i->_ix != idoppelx) || (i->_iy != idoppely)) + dItem[idoppelx][idoppely] = 0; + } + } + idoppely++; + if (idoppely == DIRTEDGED2+80) idoppely = DIRTEDGED2; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ProcessItems() +{ + int i, ii, it; + + VerifyItemActiveList(); + + for (i = 0; i < numitems; i++) { + ii = itemactive[i]; + + // Animate Spell GFX + if (item[ii]._iAnimFlag) { + item[ii]._iAnimFrame++; + if (item[ii]._iCurs == ITEM_ROCK) { + if ((item[ii]._iSelFlag == ISEL_FLR) && (item[ii]._iAnimFrame == 11)) + item[ii]._iAnimFrame = 1; + if ((item[ii]._iSelFlag == ISEL_TOP) && (item[ii]._iAnimFrame == 21)) + item[ii]._iAnimFrame = 11; + } else { + if (item[ii]._iAnimFrame == (item[ii]._iAnimLen >> 1)) { + it = ItemCAnimTbl[item[ii]._iCurs]; + PlaySfxLoc(ItemAnimSnds[it], item[ii]._ix, item[ii]._iy); + } + if (item[ii]._iAnimFrame >= item[ii]._iAnimLen) { + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iAnimFlag = FALSE; + item[ii]._iSelFlag = ISEL_FLR; + } + } + } + } + + ItemDoppel(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void FreeItemGFX() +{ + for (int i = 0; i < ITEMFTYPES; i++) + DiabloFreePtr(itemanims[i]); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncItemAnim(int ii) +{ + int a; + + a = ItemCAnimTbl[item[ii]._iCurs]; + item[ii]._iAnimData = itemanims[a]; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetItemStr(int i) { + + switch (item[i]._itype) { + case IT_GOLD: { + int nGold = item[i]._ivalue; + const char * get_pieces_str(int nGold); + sprintf(infostr,"%i gold %s",nGold,get_pieces_str(nGold)); + } + break; + + default : + int s = item[i]._itype; + if (item[i]._iIdentified) strcpy(infostr, item[i]._iIName); + else strcpy(infostr, item[i]._iName); + if (item[i]._iMagical == IMAGIC_MAGIC) infoclr = ICOLOR_BLUE; + if (item[i]._iMagical == IMAGIC_UNIQUE) infoclr = ICOLOR_GOLD; + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckIdentify(int pnum, int cii) { + ItemStruct * pi; + if (cii < NUM_INVLOC) + pi = &plr[pnum].InvBody[cii]; + else + pi = &plr[pnum].InvList[cii - NUM_INVLOC]; + pi->_iIdentified = TRUE; + CalcPlrInv(pnum,TRUE); + + if (pnum == myplr) + NewCursor(GLOVE_CURS); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void RepairItem(ItemStruct *i, int lvl) { + int d, rep; + + if (i->_iDurability == i->_iMaxDur) return; + // If item already has zero durability, wipe it out + if (i->_iMaxDur <= 0) { + i->_itype = -1; + return; + } + rep = 0; + do { + rep += random(37, lvl) + lvl; + d = i->_iMaxDur / (9 + lvl); + if (d < 1) d = 1; + i->_iMaxDur -= d; + // If I have no max durability, break + if (i->_iMaxDur == 0) { + i->_itype = -1; + return; + } + } while ((i->_iDurability + rep) < i->_iMaxDur); + i->_iDurability += rep; + if (i->_iDurability > i->_iMaxDur) + i->_iDurability = i->_iMaxDur; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoRepair(int pnum, int cii) { + PlayerStruct * p = &plr[pnum]; + PlaySfxLoc(IS_REPAIR, p->_px, p->_py); + + ItemStruct * pi; + if (cii < NUM_INVLOC) + pi = &p->InvBody[cii]; + else + pi = &p->InvList[cii - NUM_INVLOC]; + RepairItem(pi,p->_pLevel); + CalcPlrInv(pnum,TRUE); + + if (pnum == myplr) + NewCursor(GLOVE_CURS); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void RechargeItem(ItemStruct *i, int r) { + if (i->_iCharges == i->_iMaxCharges) return; + + do { + i->_iMaxCharges--; + if (i->_iMaxCharges == 0) { + //i->_itype = -1; + return; + } + i->_iCharges += r; + } while (i->_iCharges < i->_iMaxCharges); + + if (i->_iCharges > i->_iMaxCharges) i->_iCharges = i->_iMaxCharges; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoRecharge(int pnum, int cii) { + PlayerStruct * p = &plr[pnum]; + + ItemStruct * pi; + if (cii < NUM_INVLOC) pi = &p->InvBody[cii]; + else pi = &p->InvList[cii - NUM_INVLOC]; +// rmw.patch1.start.1/14/97 +// if (pi->_itype == IT_STAFF) { + if ((pi->_itype == IT_STAFF) && (pi->_iSpell != SPL_NONE)) { +// rmw.patch1.end.1/14/97 + int sp = pi->_iSpell; + int r = spelldata[sp].sBookLvl; + r = random(38, p->_pLevel / r) + 1; + + RechargeItem(pi, r); + CalcPlrInv(pnum, TRUE); + } + + if (pnum == myplr) NewCursor(GLOVE_CURS); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static BOOL OilItem(ItemStruct * i,const PlayerStruct * p) { + int v; + + if (i->_iClass == IC_ITEM) return(FALSE); + if (i->_iClass == IC_GOLD) return(FALSE); + if (i->_iClass == IC_SPECIAL) return(FALSE); + switch(p->_pOilType) { + case IMID_OILACC : + case IMID_OILMAST : + case IMID_OILSHRP : + if (i->_iClass == IC_ARMOR) return(FALSE); + break; + case IMID_OILDEATH : + if (i->_iClass == IC_ARMOR) return(FALSE); + if (i->_itype == IT_BOW) return(FALSE); + break; + case IMID_OILHARD : + case IMID_OILIMPER : + if (i->_iClass == IC_WEAP) return(FALSE); + break; + } + + switch(p->_pOilType) { + case IMID_OILACC : + if (i->_iPLToHit >= 50) break; + i->_iPLToHit += random(68, 2) + 1; + break; + case IMID_OILMAST : + if (i->_iPLToHit >= 100) break; + i->_iPLToHit += random(68, 3) + 3; + break; + case IMID_OILSHRP : + if (i->_iMaxDam - i->_iMinDam >= 30) break; + i->_iMaxDam += 1; + break; + case IMID_OILDEATH : + if (i->_iMaxDam - i->_iMinDam >= 30) break; + i->_iMinDam += 1; + i->_iMaxDam += 2; + break; + case IMID_OILSKILL : + v = random(68, 6) + 5; + + if (i->_iMinStr > v) { + i->_iMinStr -= v; + } + else { + i->_iMinStr = 0; + } + + if (i->_iMinMag > v) { + i->_iMinMag -= v; + } + else { + i->_iMinMag = 0; + } + + if (i->_iMinDex > v) { + i->_iMinDex -= v; + } + else { + i->_iMinDex = 0; + } + break; + case IMID_OILBLKSM : + if (i->_iMaxDur == INFINITE_DUR) break; +// i->_iDurability = (i->_iDurability + (random(68, 5) + 2)); +// i->_iMaxDur = (i->_iMaxDur + (random(68, 9) + 7)); + if (i->_iDurability < i->_iMaxDur) + { + // fix by 20% + int tmp = i->_iDurability + ((i->_iMaxDur + 4) / 5); + if (tmp > i->_iMaxDur) + tmp = i->_iMaxDur; + i->_iDurability = tmp; + } + else + { + if (i->_iMaxDur >= 100) break; + i->_iMaxDur += 1; + i->_iDurability = i->_iMaxDur; + } + break; + case IMID_OILFORT : + if (i->_iMaxDur == INFINITE_DUR) break; + if (i->_iMaxDur >= 200) break; + v = random(68, 41) + 10; + i->_iMaxDur += v; + i->_iDurability += v; + break; + case IMID_OILPERM : + i->_iDurability = INFINITE_DUR; + i->_iMaxDur = INFINITE_DUR; + break; + case IMID_OILHARD : + if (i->_iAC >= 60) break; + i->_iAC += random(68, 2) + 1; + break; + case IMID_OILIMPER : + if (i->_iAC >= 120) break; + i->_iAC += random(68, 3) + 3; + break; + } + + return(TRUE); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoOil(int pnum, int cii) { + ItemStruct * pi; + PlayerStruct * p = &plr[pnum]; + if (cii < NUM_INVLOC) switch (cii) { + case INVLOC_HEAD: + case INVLOC_HAND1: + case INVLOC_HAND2: + case INVLOC_BODY: + pi = &p->InvBody[cii]; + break; + + default: + return; + } + else { + pi = &p->InvList[cii - NUM_INVLOC]; + } + + if (OilItem(pi,p)) { + CalcPlrInv(pnum,TRUE); + if (pnum == myplr) NewCursor(GLOVE_CURS); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintItemOil(char IDidx) +{ + switch(IDidx) { + case IMID_OILACC : + strcpy(tempstr, "increases a weapon's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "chance to hit"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILMAST : + strcpy(tempstr, "greatly increases a"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "weapon's chance to hit"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILSHRP : + strcpy(tempstr, "increases a weapon's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "damage potential"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILDEATH : + strcpy(tempstr, "greatly increases a weapon's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "damage potential - not bows"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILSKILL : + strcpy(tempstr, "reduces attributes needed"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "to use armor or weapons"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILBLKSM : + strcpy(tempstr, "restores 20% of an"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "item's durability"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILFORT : + strcpy(tempstr, "increases an item's"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "current and max durability"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILPERM : + strcpy(tempstr, "makes an item indestructible"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILHARD : + strcpy(tempstr, "increases the armor class"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "of armor and shields"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_OILIMPER : + strcpy(tempstr, "greatly increases the armor"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "class of armor and shields"); + AddPanelString(tempstr, TEXT_CENTER); + break; +// potions + case IMID_PHEAL : + strcpy(tempstr, "fully recover life"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PLHEAL : + strcpy(tempstr, "recover partial life"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PSHEAL : + strcpy(tempstr, "recover life"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PDHEAL : + strcpy(tempstr, "deadly heal"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PMANA : + strcpy(tempstr, "recover mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_PFMANA : + strcpy(tempstr, "fully recover mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ESTR : + strcpy(tempstr, "increase strength"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_EMAG : + strcpy(tempstr, "increase magic"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_EDEX : + strcpy(tempstr, "increase dexterity"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_EVIT : + strcpy(tempstr, "increase vitality"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENSTR : + strcpy(tempstr, "decrease strength"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENMAG : + strcpy(tempstr, "decrease strength"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENDEX : + strcpy(tempstr, "decrease dexterity"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_ENVIT : + strcpy(tempstr, "decrease vitality"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_REJUV : + strcpy(tempstr, "recover life and mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_FREJUV : + strcpy(tempstr, "fully recover life and mana"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_RUNEFIRE: + case IMID_RUNEIMMOLATE: + strcpy(tempstr, "sets fire trap"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_RUNELIGHT: + case IMID_RUNENOVA: + strcpy(tempstr, "sets lightning trap"); + AddPanelString(tempstr, TEXT_CENTER); + break; + case IMID_RUNESTONE: + strcpy(tempstr, "sets petrification trap"); + AddPanelString(tempstr, TEXT_CENTER); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrintItemPower(char plidx,const ItemStruct * x) { + int v; + + switch(plidx) { + case PL_TOHIT: + case PL_NTOHIT: + sprintf(tempstr, "chance to hit : %+i%%", x->_iPLToHit); + break; + case PL_TODAM: + case PL_NTODAM: + sprintf(tempstr, "%+i%% damage", x->_iPLDam); + break; + case PL_DAHT: + case PL_NDAHT: + sprintf(tempstr, "to hit: %+i%%, %+i%% damage", x->_iPLToHit, x->_iPLDam); + break; + case PL_AC: + case PL_NAC: + sprintf(tempstr, "%+i%% armor", x->_iPLAC); + break; + case PL_ACTUALAC: + sprintf(tempstr, "armor class: %i", x->_iAC); + break; + case PL_NACTULAC: + sprintf(tempstr, "armor class: %i", x->_iAC); + break; + case PL_RFIRE: + case PL_NRFIRE: + if (x->_iPLFR < 75) + sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR); + else + sprintf(tempstr, "Resist Fire : 75%% MAX"); + break; + case PL_RLGHT: + case PL_NRLGHT: + if (x->_iPLLR < 75) + sprintf(tempstr, "Resist Lightning : %+i%%", x->_iPLLR); + else + sprintf(tempstr, "Resist Lightning : 75%% MAX"); + break; + case PL_RMAG: + case PL_NRMAG: + if (x->_iPLMR < 75) + sprintf(tempstr, "Resist Magic : %+i%%", x->_iPLMR); + else + sprintf(tempstr, "Resist Magic : 75%% MAX"); + break; + case PL_RALL: + case PL_NRALL: + if (x->_iPLFR < 75) sprintf(tempstr, "Resist All : %+i%%", x->_iPLFR); + if (x->_iPLFR >= 75) sprintf(tempstr, "Resist All : 75%% MAX"); + break; + case PL_SLVL: +#if 0 + if (x->_iSplLvlAdd == 1 ) strcpy(tempstr, "spells are increased 1 level"); + if (x->_iSplLvlAdd == 2 ) strcpy(tempstr, "spells are increased 2 levels"); + if (x->_iSplLvlAdd < 1 ) strcpy(tempstr, "spells are decreased 1 level"); +#endif + if (x->_iSplLvlAdd == 1) strcpy(tempstr, "spells are increased 1 level"); + else if (x->_iSplLvlAdd > 1 ) sprintf(tempstr, "spells are increased %i levels", x->_iSplLvlAdd); + else if (x->_iSplLvlAdd == -1) strcpy(tempstr, "spells are decreased 1 level"); + else if (x->_iSplLvlAdd < -1 ) sprintf(tempstr, "spells are decreased %i levels", x->_iSplLvlAdd); + else if (x->_iSplLvlAdd == 0 ) strcpy(tempstr, "spell levels unchanged (?)"); + break; + case PL_CHRG: + strcpy(tempstr, "Extra charges"); + break; + case PL_SPELL: + sprintf(tempstr, "%i %s charges", x->_iMaxCharges, spelldata[x->_iSpell].sNameText); + break; + case PL_FHIT: + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "Fire hit damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "Fire hit damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case PL_LHIT: + if (x->_iLMinDam == x->_iLMaxDam) + sprintf(tempstr, "Lightning hit damage: %i", x->_iLMinDam); + else + sprintf(tempstr, "Lightning hit damage: %i-%i", x->_iLMinDam, x->_iLMaxDam); + break; + case PL_STR: + case PL_NSTR: + sprintf(tempstr, "%+i to strength", x->_iPLStr); + break; + case PL_MAG: + case PL_NMAG: + sprintf(tempstr, "%+i to magic", x->_iPLMag); + break; + case PL_DEX: + case PL_NDEX: + sprintf(tempstr, "%+i to dexterity", x->_iPLDex); + break; + case PL_VIT: + case PL_NVIT: + sprintf(tempstr, "%+i to vitality", x->_iPLVit); + break; + case PL_STATS: + case PL_NSTATS: + sprintf(tempstr, "%+i to all attributes", x->_iPLStr); + break; + case PL_GETHIT: + case PL_NGETHIT: + sprintf(tempstr, "%+i damage from enemies", x->_iPLGetHit); + break; + case PL_HP: + case PL_NHP: + sprintf(tempstr, "Hit Points : %+i", (x->_iPLHP >> HP_SHIFT)); + break; + case PL_MANA: + case PL_NMANA: + sprintf(tempstr, "Mana : %+i", (x->_iPLMana >> MANA_SHIFT)); + break; + case PL_DUR: + strcpy(tempstr, "high durability"); + break; + case PL_NDUR: + strcpy(tempstr, "decreased durability"); + break; + case PL_IND: + strcpy(tempstr, "indestructible"); + break; + case PL_LIGHT: + v = x->_iPLLight * 10; + sprintf(tempstr, "+%i%% light radius", v); + break; + case PL_NLIGHT: + v = -x->_iPLLight * 10; + sprintf(tempstr, "-%i%% light radius", v); + break; + case PL_NUMARWS: + sprintf(tempstr, "multiple arrows per shot"); + break; + case PL_FARROW: + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "fire arrows damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "fire arrows damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case PL_LARROW: + if (x->_iLMinDam == x->_iLMaxDam) + sprintf(tempstr, "lightning arrows damage %i", x->_iLMinDam); + else + sprintf(tempstr, "lightning arrows damage %i-%i", x->_iLMinDam, x->_iLMaxDam); + break; + case PL_HITADD: // usurped for fireball arrows... + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "fireball damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "fireball damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); + break; + case PL_THORN: + strcpy(tempstr, "attacker takes 1-3 damage"); + break; + case PL_LMANA: + strcpy(tempstr, "user loses all mana"); + break; + case PL_NOHEAL: + strcpy(tempstr, "you can't heal"); + break; + case PL_TRAPDAM: + strcpy(tempstr, "absorbs half of trap damage"); + break; + case PL_BEAR: + strcpy(tempstr, "knocks target back"); + break; + case PL_DAMDEMON: + strcpy(tempstr, "+200% damage vs. demons"); + break; + case PL_ZERORES: + strcpy(tempstr, "All Resistance equals 0"); + break; + case PL_MNOHEAL: + strcpy(tempstr, "hit monster doesn't heal"); + break; + case PL_BAT: + if (x->_iFlags & IAF_BAT10) strcpy(tempstr, "hit steals 3% mana"); + if (x->_iFlags & IAF_BAT20) strcpy(tempstr, "hit steals 5% mana"); + break; + case PL_LEECH: + if (x->_iFlags & IAF_LEECH10) strcpy(tempstr, "hit steals 3% life"); + if (x->_iFlags & IAF_LEECH20) strcpy(tempstr, "hit steals 5% life"); + break; + case PL_ENAC: + strcpy(tempstr, "penetrates target's armor"); + break; + case PL_ATANIM: + if (x->_iFlags & IAF_ATANIM1) strcpy(tempstr, "quick attack"); + if (x->_iFlags & IAF_ATANIM2) strcpy(tempstr, "fast attack"); + if (x->_iFlags & IAF_ATANIM3) strcpy(tempstr, "faster attack"); + if (x->_iFlags & IAF_ATANIM4) strcpy(tempstr, "fastest attack"); + break; + case PL_HTANIM: + if (x->_iFlags & IAF_HTANIM1) strcpy(tempstr, "fast hit recovery"); + if (x->_iFlags & IAF_HTANIM2) strcpy(tempstr, "faster hit recovery"); + if (x->_iFlags & IAF_HTANIM3) strcpy(tempstr, "fastest hit recovery"); + break; + case PL_BLANIM: + strcpy(tempstr, "fast block"); + break; + case PL_DAMADD: + sprintf(tempstr, "adds %i points to damage", x->_iPLDamMod); + break; + case PL_RNDARW: + strcpy(tempstr, "fires random speed arrows"); + break; + case PL_DAMAGE: + sprintf(tempstr, "unusual item damage"); + break; + case PL_DURNUM: + strcpy(tempstr, "altered durability"); + break; + case PL_FALCON: + strcpy(tempstr, "Faster attack swing"); + // not used + break; + case PL_ONEHAND: + strcpy(tempstr, "one handed sword"); + break; + case PL_CONST: + strcpy(tempstr, "constantly lose hit points"); + break; + case PL_SKING: + strcpy(tempstr, "life stealing"); + break; + case PL_NSTRREQ: + strcpy(tempstr, "no strength requirement"); + break; + case PL_INFRA: + strcpy(tempstr, "see with infravision"); + break; + case PL_GFX: + strcpy(tempstr, " "); + break; + case PL_HARQUN: + if (x->_iFMinDam == x->_iFMaxDam) + sprintf(tempstr, "lightning damage: %i", x->_iFMinDam); + else + sprintf(tempstr, "lightning damage: %i-%i", x->_iFMinDam, x->_iFMaxDam); +// strcpy(tempstr, "Armor class added to life"); + break; + case PL_HARQUN2: + strcpy(tempstr, "charged bolts on hits"); +// strcpy(tempstr, "10% of mana added to armor"); + break; + case PL_HARQUN3: + if (x->_iPLFR <= 0) sprintf(tempstr, " "); + else if (x->_iPLFR >= 1) sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR); + break; + case PL_DEVAST: + strcpy(tempstr, "occasional triple damage"); + break; + case PL_DECAY: + sprintf(tempstr, "decaying %+i%% damage", x->_iPLDam); + break; + case PL_PERIL: + strcpy(tempstr, "2x dmg to monst, 1x to you"); + break; + case PL_RNDDAM: + strcpy(tempstr, "Random 0 - 500% damage"); + break; + case PL_FRAGILE: + sprintf(tempstr, "low dur, %+i%% damage", x->_iPLDam); + break; + case PL_DOPPEL: + sprintf(tempstr, "to hit: %+i%%, %+i%% damage", x->_iPLToHit, x->_iPLDam); + break; + case PL_DEMONAC: + sprintf(tempstr, "extra AC vs demons"); + break; + case PL_UNDEADAC: + sprintf(tempstr, "extra AC vs undead"); + break; + case PL_ACOLYTE: + sprintf(tempstr, "50%% Mana moved to Health"); + break; + case PL_GLADIATR: + sprintf(tempstr, "40%% Health moved to Mana"); + break; + + default: + strcpy(tempstr, "Another ability (NW)"); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawUBack() +{ + DrawCel(88, 487, pSTextBoxCels, 1, 271); + app_assert(gpBuffer); + + __asm { + mov edi,dword ptr [gpBuffer] + add edi,371803 + + xor eax,eax + mov edx,148 +_YLp: mov ecx,132 +_XLp1: stosb + inc edi + loop _XLp1 + stosb + sub edi,1033 + mov ecx,132 +_XLp2: inc edi + stosb + loop _XLp2 + sub edi,1032 + dec edx + jnz _YLp + mov ecx,132 +_XLp3: stosb + inc edi + loop _XLp3 + stosb + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PrintUString(int x, int y, BOOL cjustflag, char str[], char col) +{ + long boffset; + int sl,i,w,tw,yy; + + yy = SStringY[y]; + boffset = nBuffWTbl[yy + 204] + x + 96; + sl = strlen(str); + w = 0; + if (cjustflag) { + tw = 0; + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + tw += fontkern[c]+1; + } + if (tw < 257) w = (257 - tw) >> 1; + boffset += w; + } + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + w += fontkern[c]+1; + if ((c != 0) && (w <= 257)) DrawPanelFont(boffset, c, col); + boffset += fontkern[c]+1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawULine(int y) +{ + long doffset; + + app_assert(gpBuffer); + doffset = nBuffWTbl[SStringY[y] + 198] + 90; + __asm { + mov esi,dword ptr [gpBuffer] + mov edi,esi + add esi,142170 + add edi,dword ptr [doffset] + + mov ebx,502 + + mov edx,3 +_YLp: mov ecx,66 + rep movsd + movsw + add esi,ebx + add edi,ebx + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawUniqueInfo() +{ + int u,y; + + if (chrflag || questlog) return; + u = curruitem._iUid; + DrawUBack(); + PrintUString(0, 2, TRUE, UniqueItemList[u].UIName, ICOLOR_GOLD); + DrawULine(5); + PrintItemPower(UniqueItemList[u].UIPower1, &curruitem); + y = (6 - UniqueItemList[u].UINumPL) + 8; + PrintUString(0, y, TRUE, tempstr, ICOLOR_WHITE); + if (UniqueItemList[u].UINumPL > 1) { + PrintItemPower(UniqueItemList[u].UIPower2, &curruitem); + PrintUString(0, y+2, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 2) { + PrintItemPower(UniqueItemList[u].UIPower3, &curruitem); + PrintUString(0, y+4, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 3) { + PrintItemPower(UniqueItemList[u].UIPower4, &curruitem); + PrintUString(0, y+6, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 4) { + PrintItemPower(UniqueItemList[u].UIPower5, &curruitem); + PrintUString(0, y+8, TRUE, tempstr, ICOLOR_WHITE); + } + if (UniqueItemList[u].UINumPL > 5) { + PrintItemPower(UniqueItemList[u].UIPower6, &curruitem); + PrintUString(0, y+10, TRUE, tempstr, ICOLOR_WHITE); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintItemMisc(const ItemStruct * x) +{ + if (x->_iMiscId == IMID_SCROLL) { + strcpy(tempstr, "Right-click to read"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_TSCROLL) { + strcpy(tempstr, "Right-click to read, then"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "left-click to target"); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId >= IMID_FIRSTPOT) && (x->_iMiscId <= IMID_LASTPOT)) { + PrintItemOil(x->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId > IMID_FIRSTOIL) && (x->_iMiscId < IMID_LASTOIL)) { + PrintItemOil(x->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId > IMID_FIRSTRUNE) && (x->_iMiscId < IMID_LASTRUNE)) { + PrintItemOil(x->_iMiscId); + strcpy(tempstr, "Right click to use"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_BOOK) { + strcpy(tempstr, "Right click to read"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_FULLNOTE) + { + strcpy(tempstr, "Right click to read"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_MAPOFDOOM) { + strcpy(tempstr, "Right click to view"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_EAR) { + sprintf(tempstr, "Level : %i", x->_ivalue); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMiscId == IMID_AURIC) { + strcpy(tempstr, "Doubles gold capacity"); + AddPanelString(tempstr, TEXT_CENTER); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrintItemDetails(const ItemStruct * x) +{ + if (x->_iClass == IC_WEAP) { + if (x->_iMinDam == x->_iMaxDam) + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i Indestructible", x->_iMinDam); + else + sprintf(tempstr, "damage: %i Dur: %i/%i", x->_iMinDam, x->_iDurability, x->_iMaxDur); + } + else + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + else + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iClass == IC_ARMOR) { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "armor: %i Indestructible", x->_iAC); + else + sprintf(tempstr, "armor: %i Dur: %i/%i", x->_iAC, x->_iDurability, x->_iMaxDur); + AddPanelString(tempstr, TEXT_CENTER); + } + if ((x->_iMiscId == IMID_STAFF) && (x->_iMaxCharges != 0)) { + if (x->_iMinDam == x->_iMaxDam) + sprintf(tempstr, "dam: %i Dur: %i/%i", x->_iMinDam, x->_iDurability, x->_iMaxDur); + else + sprintf(tempstr, "dam: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iPrePower != -1) { + PrintItemPower(x->_iPrePower, x); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iSufPower != -1) { + PrintItemPower(x->_iSufPower, x); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMagical == IMAGIC_UNIQUE) { + AddPanelString("unique item", TEXT_CENTER); + uitemflag = TRUE; + curruitem = *x; + } + PrintItemMisc(x); + if ((x->_iMinStr + x->_iMinMag + x->_iMinDex) != 0) { + strcpy(tempstr, "Required:"); + if (x->_iMinStr != 0) sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + if (x->_iMinMag != 0) sprintf(tempstr, "%s %i Mag", tempstr, (byte) x->_iMinMag); + if (x->_iMinDex != 0) sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + AddPanelString(tempstr, TEXT_CENTER); + } + pinfoflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrintItemDur(const ItemStruct * x) +{ + if (x->_iClass == IC_WEAP) { + if (x->_iMinDam == x->_iMaxDam) + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i Indestructible", x->_iMinDam); + else + sprintf(tempstr, "damage: %i Dur: %i/%i", x->_iMinDam, x->_iDurability, x->_iMaxDur); + } + else + { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "damage: %i-%i Indestructible", x->_iMinDam, x->_iMaxDam); + else + sprintf(tempstr, "damage: %i-%i Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur); + } + AddPanelString(tempstr, TEXT_CENTER); + if ((x->_iMiscId == IMID_STAFF) && (x->_iMaxCharges != 0)) { + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, TEXT_CENTER); + } + if (x->_iMagical) { + AddPanelString("Not Identified", TEXT_CENTER); + } + } + if (x->_iClass == IC_ARMOR) { + if (x->_iMaxDur == INFINITE_DUR) + sprintf(tempstr, "armor: %i Indestructible", x->_iAC); + else + sprintf(tempstr, "armor: %i Dur: %i/%i", x->_iAC, x->_iDurability, x->_iMaxDur); + AddPanelString(tempstr, TEXT_CENTER); + if (x->_iMagical) { + AddPanelString("Not Identified", TEXT_CENTER); + } + if ((x->_iMiscId == IMID_STAFF) && (x->_iMaxCharges != 0)) { + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + AddPanelString(tempstr, TEXT_CENTER); + } + } + if ((x->_itype == IT_RING) || (x->_itype == IT_AMULET)) { + AddPanelString("Not Identified", TEXT_CENTER); + } + PrintItemMisc(x); + if ((x->_iMinStr + x->_iMinMag + x->_iMinDex) != 0) { + strcpy(tempstr, "Required:"); + if (x->_iMinStr != 0) sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + if (x->_iMinMag != 0) sprintf(tempstr, "%s %i Mag", tempstr, (byte) x->_iMinMag); + if (x->_iMinDex != 0) sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + AddPanelString(tempstr, TEXT_CENTER); + } + pinfoflag = TRUE; +} + +/*-------------------------------------------------------------------------* +**-------------------------------------------------------------------------*/ + +void UseItem(int p, int Mid, int spl) +{ + long l; + __int64 t; + + switch(Mid) { + case IMID_MEAT : + case IMID_PLHEAL : + l = plr[p]._pMaxHP >> (HP_SHIFT + 2); + l = ((random(39, l) + (l >> 1)) << HP_SHIFT); + if (plr[p]._pClass == CLASS_WARRIOR + || plr[p]._pClass == CLASS_BARBARIAN) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE || + plr[p]._pClass == CLASS_MONK || + plr[p]._pClass == CLASS_BARD) l += (l >> 1); + plr[p]._pHitPoints += l; + if (plr[p]._pHitPoints > plr[p]._pMaxHP) plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase += l; + if (plr[p]._pHPBase > plr[p]._pMaxHPBase) plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + break; + case IMID_PHEAL : + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + break; + case IMID_PMANA : + l = plr[p]._pMaxMana >> (MANA_SHIFT + 2); + l = ((random(40, l) + (l >> 1)) << MANA_SHIFT); + if (plr[p]._pClass == CLASS_SORCEROR) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE || + plr[p]._pClass == CLASS_MONK || + plr[p]._pClass == CLASS_BARD) l += (l >> 1); + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana += l; + if (plr[p]._pMana > plr[p]._pMaxMana) plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase += l; + if (plr[p]._pManaBase > plr[p]._pMaxManaBase) plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_PFMANA : + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_ESTR : + ModifyPlrStr(p, 1); + break; + case IMID_EMAG : + ModifyPlrMag(p, 1); + + // also give full mana potion effect + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + + break; + case IMID_EDEX : + ModifyPlrDex(p, 1); + break; + case IMID_EVIT : + ModifyPlrVit(p, 1); + + // heal the player, too + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + + break; + case IMID_BOOK : + t = 1; + plr[p]._pMemSpells |= (t << spl-1); + if (plr[p]._pSplLvl[spl] < SPELLCAP) plr[p]._pSplLvl[spl]++; + plr[p]._pMana += spelldata[spl].sManaCost << MANA_SHIFT; + if (plr[p]._pMana > plr[p]._pMaxMana) plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase += spelldata[spl].sManaCost << MANA_SHIFT; + if (plr[p]._pManaBase > plr[p]._pMaxManaBase) plr[p]._pManaBase = plr[p]._pMaxManaBase; + if (p == myplr) CalcPlrBookVals(p); + drawmanaflag = TRUE; + break; + case IMID_REJUV : + l = plr[p]._pMaxHP >> (HP_SHIFT + 2); + l = ((random(39, l) + (l >> 1)) << HP_SHIFT); + if (plr[p]._pClass == CLASS_WARRIOR + || plr[p]._pClass == CLASS_BARBARIAN) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE) l += (l >> 1); + plr[p]._pHitPoints += l; + if (plr[p]._pHitPoints > plr[p]._pMaxHP) plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase += l; + if (plr[p]._pHPBase > plr[p]._pMaxHPBase) plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + l = plr[p]._pMaxMana >> (MANA_SHIFT + 2); + l = ((random(40, l) + (l >> 1)) << MANA_SHIFT); + if (plr[p]._pClass == CLASS_SORCEROR) l = l << 1; + if (plr[p]._pClass == CLASS_ROGUE) l += (l >> 1); + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana += l; + if (plr[p]._pMana > plr[p]._pMaxMana) plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase += l; + if (plr[p]._pManaBase > plr[p]._pMaxManaBase) plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_FREJUV : + plr[p]._pHitPoints = plr[p]._pMaxHP; + plr[p]._pHPBase = plr[p]._pMaxHPBase; + drawhpflag = TRUE; + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pMana = plr[p]._pMaxMana; + plr[p]._pManaBase = plr[p]._pMaxManaBase; + drawmanaflag = TRUE; + } + break; + case IMID_OILACC : + case IMID_OILMAST : + case IMID_OILSHRP : + case IMID_OILDEATH : + case IMID_OILSKILL : + case IMID_OILBLKSM : + case IMID_OILFORT : + case IMID_OILPERM : + case IMID_OILHARD : + case IMID_OILIMPER : + plr[p]._pOilType = Mid; + if (p == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(OIL_CURS); + } + break; + case IMID_SCROLL: + if (spelldata[spl].sTargeted) { + plr[p]._pTSpell = spl; + //plr[p]._pTSplType = SPT_SCROLL; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + } else { + ClrPlrPath(p); + plr[p]._pSpell = spl; + //plr[p]._pSplType = SPT_SCROLL; + plr[p]._pSplType = SPT_NONE; + plr[p]._pSplFrom = SPL_FROMSB; + plr[p].destAction = PCMD_SPELL; + plr[p].destParam1 = cursmx; + plr[p].destParam2 = cursmy; + } + break; + case IMID_TSCROLL: + if (spelldata[spl].sTargeted) { + plr[p]._pTSpell = spl; + //plr[p]._pTSplType = SPT_SCROLL; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + } else { + ClrPlrPath(p); + plr[p]._pSpell = spl; + //plr[p]._pSplType = SPT_SCROLL; + plr[p]._pSplType = SPT_NONE; + plr[p]._pSplFrom = SPL_FROMSB; + plr[p].destAction = PCMD_SPELL; + plr[p].destParam1 = cursmx; + plr[p].destParam2 = cursmy; + } + break; + case IMID_MAPOFDOOM: + InitMapOfDoomView(); + break; + case IMID_SPECTRAL: + ModifyPlrStr(p, 3); + ModifyPlrMag(p, 3); + ModifyPlrDex(p, 3); + ModifyPlrVit(p, 3); + break; + case IMID_RUNEFIRE: + plr[p]._pTSpell = SPL_RUNEOFFIRE; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNELIGHT: + plr[p]._pTSpell = SPL_RUNEOFLIGHT; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNEIMMOLATE: + plr[p]._pTSpell = SPL_RUNEOFIMMOLATION; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNENOVA: + plr[p]._pTSpell = SPL_RUNEOFNOVA; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_RUNESTONE: + plr[p]._pTSpell = SPL_RUNEOFSTONE; + plr[p]._pTSplType = SPT_NONE; + if (p == myplr) { + NewCursor(TARGET_CURS); + } + break; + case IMID_FULLNOTE: +// InitQTextMsg(TXT_SKULLJRNL7); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#define MAX_STORE_VAL 200000 +#define MAX_WIRT_VAL 200000 // Wirts stuff is 75% of normal + +BOOL StoreStatOk(ItemStruct *h) +{ + BOOL sf = TRUE; + if (plr[myplr]._pStrength < h->_iMinStr) sf = FALSE; + else if (plr[myplr]._pMagic < (byte)h->_iMinMag) sf = FALSE; + else if (plr[myplr]._pDexterity < h->_iMinDex) sf = FALSE; + return(sf); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL SmithItemOk(int i) +{ + BOOL rv; + + rv = TRUE; + // Selling oil is too powerful for the money received. +// if (AllItemsList[i].iMiscId > IMID_FIRSTOIL && +// AllItemsList[i].iMiscId < IMID_LASTOIL) rv = TRUE; +// else + if (AllItemsList[i].itype == IT_MISC) rv = FALSE; + + if (AllItemsList[i].itype == IT_GOLD) rv = FALSE; + if (AllItemsList[i].itype == IT_FOOD) rv = FALSE; + if (AllItemsList[i].itype == IT_STAFF + && AllItemsList[i].iSpell != 0) rv = FALSE; + if (AllItemsList[i].itype == IT_RING) rv = FALSE; + if (AllItemsList[i].itype == IT_AMULET) rv = FALSE; + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndSmithItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && SmithItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl) + && ri < 512) { + ril[ri++] = i; + if (AllItemsList[i].iRnd == IRND_DOUBLE + && ri < 512) ril[ri++] = i; + } + } + return(ril[random(50, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void BubbleSwapItem(ItemStruct * a, ItemStruct * b) +{ + ItemStruct h; + + h = *a; + *a = *b; + *b = h; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SortSmith() +{ + int j, k; + BOOL sorted; + + for (k = 0; smithitem[k+1]._itype != -1; k++); + sorted = FALSE; + while ((k > 0) && (!sorted)) { + sorted = TRUE; + for (j = 0; j < k; j++) { + if (smithitem[j].IDidx > smithitem[j+1].IDidx) { + BubbleSwapItem(&smithitem[j], &smithitem[j+1]); + sorted = FALSE; + } + } + k--; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnSmith(int lvl) +{ + int itype; + int i,nsi; + ItemStruct const holditem = item[0]; + + nsi = random(50, (MAXSMITHITEMS - 10)) + 10; + for (i = 0; i < nsi; i++) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndSmithItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + } while (item[0]._iIvalue > MAX_STORE_VAL); + smithitem[i] = item[0]; + smithitem[i]._iCreateInfo = lvl | ICI_SMITH; + smithitem[i]._iIdentified = TRUE; + smithitem[i]._iStatFlag = StoreStatOk(&smithitem[i]); + } + for (i = nsi; i < MAXSMITHITEMS; i++) smithitem[i]._itype = -1; + SortSmith(); + item[0] = holditem; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PremiumItemOk(int i) +{ + BOOL rv; + + rv = TRUE; + if (AllItemsList[i].itype == IT_MISC) rv = FALSE; + else if (AllItemsList[i].itype == IT_GOLD) rv = FALSE; + else if (AllItemsList[i].itype == IT_FOOD) rv = FALSE; + if (gbMaxPlayers != 1) { + if (AllItemsList[i].iMiscId == IMID_OIL) rv = FALSE; + else if (AllItemsList[i].itype == IT_RING) rv = FALSE; + else if (AllItemsList[i].itype == IT_AMULET) rv = FALSE; + } + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndPremiumItem(int minlvl, int maxlvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && PremiumItemOk(i) && + (AllItemsList[i].iMinMLvl >= minlvl) && + (AllItemsList[i].iMinMLvl <= maxlvl) && + ri < 512) { + ril[ri++] = i; + } + } + return(ril[random(50, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SpawnOnePremium(int i, int plvl, int myplr, bool noSpells) +{ + int itype; + ItemStruct const holditem = item[0]; + int const maxval = MAX_STORE_VAL; + int ivalue; + int iCount = 0; + int maxPlrStr = GetMaxStr(plr[myplr]._pClass); + int maxPlrDex = GetMaxDex(plr[myplr]._pClass); + int maxPlrMag = GetMaxMag(plr[myplr]._pClass); + + // Test in case of bonus + if (maxPlrStr < plr[myplr]._pStrength) + { + maxPlrStr = plr[myplr]._pStrength; + } + maxPlrStr = (int)(maxPlrStr * 1.2); + + if (maxPlrDex < plr[myplr]._pDexterity) + { + maxPlrDex = plr[myplr]._pDexterity; + } + maxPlrDex = (int)(maxPlrDex * 1.2); + + if (maxPlrMag < plr[myplr]._pMagic) + { + maxPlrMag = plr[myplr]._pMagic; + } + maxPlrMag = (int)(maxPlrMag * 1.2); + + +#if CHEATS + if ((plvl > 30) || (davecheat)) plvl = 30; +#else + if (plvl > 30) plvl = 30; +#endif + if (plvl < 1) plvl = 1; + + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndPremiumItem(plvl>>2, plvl) - 1; + GetItemAttrs(0, itype, plvl); + GetItemBonus(0, itype, plvl>>1, plvl, TRUE, noSpells); + + ivalue = 0; + + switch (item[0]._itype) + { + case IT_ARMOR: + case IT_MARMOR: + case IT_HARMOR: + ivalue = GetHighArmorValue(myplr); + break; + case IT_SHIELD: + ivalue = GetHighShieldValue(myplr); + break; + case IT_AXE: + ivalue = GetHighAxeValue(myplr); + break; + case IT_BOW: + ivalue = GetHighBowValue(myplr); + break; + case IT_MACE: + ivalue = GetHighMaceValue(myplr); + break; + case IT_SWORD: + ivalue = GetHighSwordValue(myplr); + break; + case IT_HELM: + ivalue = GetHighHelmValue(myplr); + break; + case IT_STAFF: + ivalue = GetHighStaffValue(myplr); + break; + case IT_RING: + ivalue = GetHighRingValue(myplr); + break; + case IT_AMULET: + ivalue = GetHighAmuletValue(myplr); + break; + } + ivalue = (int)(0.8 * ivalue); + + ++iCount; + + // GWP Make sure we can actually use it. + } while ((item[0]._iIvalue > maxval + || item[0]._iMinStr > maxPlrStr + || item[0]._iMinMag > maxPlrMag + || item[0]._iMinDex > maxPlrDex + || item[0]._iIvalue < ivalue) // already have better. + && iCount < 150 // prevent infinite loops. + ); + + premiumitem[i] = item[0]; + premiumitem[i]._iCreateInfo = plvl | ICI_PREMIUM; + premiumitem[i]._iIdentified = TRUE; + premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + item[0] = holditem; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int premiumlvladd[MAXPREMIUM] = { -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3 }; + +void SpawnPremium(int myplr) +{ + int lvl = plr[myplr]._pLevel; + int i; + + // Empty slots? + if (numpremium < MAXPREMIUM) { + for (i = 0; i < MAXPREMIUM; ++i) { + if (premiumitem[i]._itype == -1) + SpawnOnePremium(i, premiumlevel + premiumlvladd[i], myplr, false); + } + numpremium = MAXPREMIUM; + } + // New items? + while (premiumlevel < lvl) { + premiumlevel++; + premiumitem[0] = premiumitem[3]; + premiumitem[1] = premiumitem[4]; + premiumitem[2] = premiumitem[5]; + premiumitem[3] = premiumitem[6]; + premiumitem[4] = premiumitem[7]; + premiumitem[5] = premiumitem[8]; + premiumitem[6] = premiumitem[9]; + premiumitem[7] = premiumitem[10]; + premiumitem[8] = premiumitem[11]; + premiumitem[9] = premiumitem[12]; + SpawnOnePremium(10, premiumlevel + premiumlvladd[10], myplr, false); + premiumitem[11] = premiumitem[13]; + SpawnOnePremium(12, premiumlevel + premiumlvladd[12], myplr, false); + premiumitem[13] = premiumitem[14]; + SpawnOnePremium(14, premiumlevel + premiumlvladd[14], myplr, false); + } + +#if 15 != MAXPREMIUM +#error "Fix code for new MAXPREMIUM" +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL WitchItemOk(int i) +{ + BOOL rv; + + rv = FALSE; + if (AllItemsList[i].itype == IT_MISC) rv = TRUE; + else if (AllItemsList[i].itype == IT_STAFF) rv = TRUE; + + // Will already have the next one + if (AllItemsList[i].iMiscId == IMID_PMANA) rv = FALSE; + else if (AllItemsList[i].iMiscId == IMID_PFMANA) rv = FALSE; + + if (AllItemsList[i].iSpell == SPL_TOWN) rv = FALSE; + // no healing + if (AllItemsList[i].iMiscId == IMID_PHEAL) rv = FALSE; + else if (AllItemsList[i].iMiscId == IMID_PLHEAL) rv = FALSE; + + // no oils + if (AllItemsList[i].iMiscId > IMID_FIRSTOIL && + AllItemsList[i].iMiscId < IMID_LASTOIL) + rv = FALSE; + // None of these in single player + if (AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1) rv = FALSE; + else if (AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1) rv = FALSE; + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndWitchItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; ++i) { + if (AllItemsList[i].iRnd && WitchItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl) && + ri < 512) + { + ril[ri++] = i; + } + } + return(ril[random(51, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SortWitch() +{ + int j, k; + BOOL sorted; + + for (k = 3; witchitem[k+1]._itype != -1; k++); + sorted = FALSE; + while ((k > 3) && (!sorted)) { + sorted = TRUE; + for (j = 3; j < k; j++) { + if (witchitem[j].IDidx > witchitem[j+1].IDidx) { + BubbleSwapItem(&witchitem[j], &witchitem[j+1]); + sorted = FALSE; + } + } + k--; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void WitchBookLevel(int ii) +{ + if (witchitem[ii]._iMiscId != IMID_BOOK) + return; + + witchitem[ii]._iMinMag = spelldata[witchitem[ii]._iSpell].sMinInt; + int slvl = plr[myplr]._pSplLvl[witchitem[ii]._iSpell]; + + while (slvl != 0) { + witchitem[ii]._iMinMag += ((witchitem[ii]._iMinMag * 20) / 100); + slvl--; + if ((witchitem[ii]._iMinMag + ((witchitem[ii]._iMinMag * 20) / 100)) > 255) { + witchitem[ii]._iMinMag = 255; + slvl = 0; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnWitch(int lvl) +{ + int itype, iblvl; + int i; + int start = 3; + + int const nsi = random(51, (MAXWITCHITEMS - 10)) + 10; + int const max_number_of_books = random(3, 1 + (IDI_LAST_BOOK - IDI_FIRST_BOOK)); + int number_of_books; + + // Will always have mana (endless supply) + GetItemAttrs(0, IDI_MANA, 1); + witchitem[0] = item[0]; + witchitem[0]._iCreateInfo = lvl; + witchitem[0]._iStatFlag = TRUE; + GetItemAttrs(0, IDI_FULLMANA, 1); + witchitem[1] = item[0]; + witchitem[1]._iCreateInfo = lvl; + witchitem[1]._iStatFlag = TRUE; + GetItemAttrs(0, IDI_PORTAL, 1); + witchitem[2] = item[0]; + witchitem[2]._iCreateInfo = lvl; + witchitem[2]._iStatFlag = TRUE; + for (i = IDI_FIRST_BOOK, number_of_books = 0; + i <= IDI_LAST_BOOK + && number_of_books < max_number_of_books; + ++i) + { + + if ( WitchItemOk(i) + && lvl >= AllItemsList[i].iMinMLvl + ) + { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + volatile int dummy = random(0, 1); // to sync with below + + GetItemAttrs(0, i, lvl); + witchitem[start] = item[0]; + witchitem[start]._iCreateInfo = lvl | ICI_WITCH; + witchitem[start]._iIdentified = TRUE; + WitchBookLevel(start); + witchitem[start]._iStatFlag = StoreStatOk(&witchitem[start]); + ++start; + ++number_of_books; + } + } + + for (i = start; i < nsi; ++i) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndWitchItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + iblvl = -1; + if (random(51, 100) <= 5) iblvl = lvl << 1; + // Force staffs to be magical + if ((iblvl == -1) && (item[0]._iMiscId == IMID_STAFF)) iblvl = lvl << 1; +#if CHEATS + if (cheatflag) iblvl = lvl << 1; +#endif + if (iblvl != -1) GetItemBonus(0, itype, iblvl >> 1, iblvl, TRUE, true); + } while (item[0]._iIvalue > MAX_STORE_VAL); + witchitem[i] = item[0]; + witchitem[i]._iCreateInfo = lvl | ICI_WITCH; + witchitem[i]._iIdentified = TRUE; + WitchBookLevel(i); + witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + //WitchBookLevel(i); + } + for (i = nsi; i < MAXWITCHITEMS; i++) witchitem[i]._itype = -1; + SortWitch(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndBoyItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; ++i) { + if (AllItemsList[i].iRnd && PremiumItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl) && + ri < 512) ril[ri++] = i; + } + return(ril[random(49, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnBoy(int lvl) +{ + int itype; + int ivalue; + int iCount = 0; + int maxPlrStr = GetMaxStr(plr[myplr]._pClass); + int maxPlrDex = GetMaxDex(plr[myplr]._pClass); + int maxPlrMag = GetMaxMag(plr[myplr]._pClass); + int const PlayerClass = plr[myplr]._pClass; + + // Test in case of bonus + if (maxPlrStr < plr[myplr]._pStrength) + { + maxPlrStr = plr[myplr]._pStrength; + } + maxPlrStr = (int)(maxPlrStr * 1.2); + + if (maxPlrDex < plr[myplr]._pDexterity) + { + maxPlrDex = plr[myplr]._pDexterity; + } + maxPlrDex = (int)(maxPlrDex * 1.2); + + if (maxPlrMag < plr[myplr]._pMagic) + { + maxPlrMag = plr[myplr]._pMagic; + } + maxPlrMag = (int)(maxPlrMag * 1.2); + + + + if ((boylevel < (lvl >> 1)) || (boyitem._itype == -1)) { + do { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndBoyItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + // Always magical + GetItemBonus(0, itype, lvl, lvl << 1, TRUE, true); + ivalue = 0; + + int const itemType = item[0]._itype; + + switch (itemType) + { + case IT_ARMOR: + case IT_MARMOR: + case IT_HARMOR: + ivalue = GetHighArmorValue(myplr); + break; + case IT_SHIELD: + ivalue = GetHighShieldValue(myplr); + break; + case IT_AXE: + ivalue = GetHighAxeValue(myplr); + break; + case IT_BOW: + ivalue = GetHighBowValue(myplr); + break; + case IT_MACE: + ivalue = GetHighMaceValue(myplr); + break; + case IT_SWORD: + ivalue = GetHighSwordValue(myplr); + break; + case IT_HELM: + ivalue = GetHighHelmValue(myplr); + break; + case IT_STAFF: + ivalue = GetHighStaffValue(myplr); + break; + case IT_RING: + ivalue = GetHighRingValue(myplr); + break; + case IT_AMULET: + ivalue = GetHighAmuletValue(myplr); + break; + } + ivalue = (int)(0.8 * ivalue); + + ++iCount; + + if (iCount < 200) // prevent infinite loops. + { + switch (PlayerClass) + { + case CLASS_WARRIOR: + if (itemType == IT_BOW + || itemType == IT_STAFF) + ivalue = INT_MAX; + break; + case CLASS_ROGUE: + if (itemType == IT_SWORD + || itemType == IT_STAFF + || itemType == IT_AXE + || itemType == IT_MACE + || itemType == IT_SHIELD) + ivalue = INT_MAX; + break; + case CLASS_SORCEROR: + if (itemType == IT_STAFF + || itemType == IT_AXE + || itemType == IT_BOW + || itemType == IT_MACE) + ivalue = INT_MAX; + break; + case CLASS_MONK: + if (itemType == IT_BOW + || itemType == IT_MARMOR + || itemType == IT_SHIELD + || itemType == IT_MACE) + ivalue = INT_MAX; + break; + case CLASS_BARD: + if (itemType == IT_AXE + || itemType == IT_MACE + || itemType == IT_STAFF) + ivalue = INT_MAX; + break; + case CLASS_BARBARIAN: + if (itemType == IT_BOW + || itemType == IT_STAFF) + ivalue = INT_MAX; + break; + } + } + + + } while ((item[0]._iIvalue > MAX_WIRT_VAL + || item[0]._iMinStr > maxPlrStr + || item[0]._iMinMag > maxPlrMag + || item[0]._iMinDex > maxPlrDex + || item[0]._iIvalue < ivalue) // already have better. + && iCount < 250 // prevent infinite loops. + ); + boyitem = item[0]; + boyitem._iCreateInfo = lvl | ICI_BOY; + boyitem._iIdentified = TRUE; + boyitem._iStatFlag = StoreStatOk(&boyitem); + boylevel = lvl >> 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL HealerItemOk(int i) +{ + BOOL rv; + + rv = FALSE; + if (AllItemsList[i].itype != IT_MISC) return(FALSE); + // Heal scrolls + if ((AllItemsList[i].iMiscId == IMID_SCROLL) && (AllItemsList[i].iSpell == SPL_HEAL)) rv = TRUE; + // Will always have Resurrect scrolls (multiplayer only) + if ((AllItemsList[i].iMiscId == IMID_TSCROLL) && (AllItemsList[i].iSpell == SPL_RESURRECT) && (gbMaxPlayers != 1)) rv = FALSE; + // Heal Other scroll (multiplayer only) + if ((AllItemsList[i].iMiscId == IMID_TSCROLL) && (AllItemsList[i].iSpell == SPL_HEALOTHER) && (gbMaxPlayers != 1)) rv = TRUE; + // Elixirs + if (gbMaxPlayers == 1) { + if (AllItemsList[i].iMiscId == IMID_ESTR + && plr[myplr]._pBaseStr < MaxStats[plr[myplr]._pClass][0]) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_EMAG + && plr[myplr]._pBaseMag < MaxStats[plr[myplr]._pClass][1]) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_EDEX + && plr[myplr]._pBaseDex < MaxStats[plr[myplr]._pClass][2]) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_EVIT + && plr[myplr]._pBaseVit < MaxStats[plr[myplr]._pClass][3]) rv = TRUE; + } + // Potions + if (AllItemsList[i].iMiscId == IMID_PHEAL) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_REJUV) rv = TRUE; + else if (AllItemsList[i].iMiscId == IMID_FREJUV) rv = TRUE; + // Will always have these + else if (AllItemsList[i].iMiscId == IMID_PLHEAL) rv = FALSE; + else if (AllItemsList[i].iMiscId == IMID_PHEAL) rv = FALSE; + // No mana + else if (AllItemsList[i].iMiscId == IMID_PMANA) rv = FALSE; + else if (AllItemsList[i].iMiscId == IMID_PFMANA) rv = FALSE; + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int RndHealerItem(int lvl) +{ + int ril[512]; // Max 512 items + int ri, i; + + ri = 0; + for (i = 1; AllItemsList[i].iLoc != -1; i++) { + if (AllItemsList[i].iRnd && HealerItemOk(i) && + (lvl >= AllItemsList[i].iMinMLvl) && + ri < 512) ril[ri++] = i; + } + return(ril[random(50, ri)]+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SortHealer() +{ + int j, k; + BOOL sorted; + + for (k = 2; healitem[k+1]._itype != -1; k++); + sorted = FALSE; + while ((k > 2) && (!sorted)) { + sorted = TRUE; + for (j = 2; j < k; j++) { + if (healitem[j].IDidx > healitem[j+1].IDidx) { + BubbleSwapItem(&healitem[j], &healitem[j+1]); + sorted = FALSE; + } + } + k--; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnHealer(int lvl) +{ + int itype; + int i,nsi,srnd; + + // Will always have healing (endless supply) + GetItemAttrs(0, IDI_HEAL, 1); + healitem[0] = item[0]; + healitem[0]._iCreateInfo = lvl; + healitem[0]._iStatFlag = TRUE; + GetItemAttrs(0, IDI_FULLHEAL, 1); + healitem[1] = item[0]; + healitem[1]._iCreateInfo = lvl; + healitem[1]._iStatFlag = TRUE; + if (gbMaxPlayers != 1) { + GetItemAttrs(0, IDI_RESURRECT, 1); + healitem[2] = item[0]; + healitem[2]._iCreateInfo = lvl; + healitem[2]._iStatFlag = TRUE; + srnd = 3; + } else srnd = 2; + + nsi = random(50, (MAXHEALITEMS - 10)) + 10; + for (i = srnd; i < nsi; i++) { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndHealerItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + healitem[i] = item[0]; + healitem[i]._iCreateInfo = lvl | ICI_HEALER; + healitem[i]._iIdentified = TRUE; + healitem[i]._iStatFlag = StoreStatOk(&healitem[i]); + } + for (i = nsi; i < MAXHEALITEMS; i++) healitem[i]._itype = -1; + SortHealer(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnStoreGold() +{ + // Setup a gold item to place in inv if they sell + GetItemAttrs(0, 0, 1); + golditem = item[0]; + golditem._iStatFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateSmithItem(int ii, int idx, int lvl, int iseed) +{ + SetRndSeed(iseed); + int itype = RndSmithItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_SMITH; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreatePremiumItem(int ii, int idx, int plvl, int iseed) +{ + SetRndSeed(iseed); + int itype = RndPremiumItem(plvl>>2, plvl) - 1; + GetItemAttrs(ii, itype, plvl); + GetItemBonus(ii, itype, plvl>>1, plvl, TRUE, false); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = plvl | ICI_PREMIUM; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateBoyItem(int ii, int idx, int lvl, int iseed) +{ + SetRndSeed(iseed); + int itype = RndBoyItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + // Always magical + GetItemBonus(ii, itype, lvl, lvl << 1, TRUE, true); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_BOY; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateWitchItem(int ii, int idx, int lvl, int iseed) +{ + if ((idx == IDI_MANA) + || (idx == IDI_FULLMANA) + || (idx == IDI_PORTAL)) + { + GetItemAttrs(ii, idx, lvl); + } else if( idx >= IDI_FIRST_BOOK && idx <= IDI_LAST_BOOK) { + SetRndSeed(iseed); + volatile int dummy = random(0, 1); // to sync with below + GetItemAttrs(ii, idx, lvl); + } else { + SetRndSeed(iseed); + int itype = RndWitchItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + int iblvl = -1; + if (random(51, 100) <= 5) iblvl = lvl << 1; + // Force staffs to be magical + if ((iblvl == -1) && (item[ii]._iMiscId == IMID_STAFF)) iblvl = lvl << 1; +#if CHEATS + if (cheatflag) iblvl = lvl << 1; +#endif + if (iblvl != -1) GetItemBonus(ii, itype, iblvl >> 1, iblvl, TRUE, true); + } + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_WITCH; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RecreateHealerItem(int ii, int idx, int lvl, int iseed) +{ + if ((idx == IDI_HEAL) || (idx == IDI_FULLHEAL) || (idx == IDI_RESURRECT)) { + GetItemAttrs(ii, idx, lvl); + } else { + SetRndSeed(iseed); + int itype = RndHealerItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + } + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = lvl | ICI_HEALER; + item[ii]._iIdentified = TRUE; +} + +/*-----------------------------------------------------------------------* +** Recreate any item with the proper info +**-----------------------------------------------------------------------*/ + +void RecreateTownItem(int ii, int idx, WORD icreateinfo, int iseed, int ivalue) +{ + if (icreateinfo & ICI_SMITH) RecreateSmithItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_PREMIUM) RecreatePremiumItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_BOY) RecreateBoyItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_WITCH) RecreateWitchItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); + else if (icreateinfo & ICI_HEALER) RecreateHealerItem(ii, idx, icreateinfo & ICI_LVLMASK, iseed); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#if CHEATS +void DaveGold() +{ + int i,j; + + for (j = 0; j < MAXINV; j++) { + if (plr[myplr].InvGrid[j] == 0) { + i = plr[myplr]._pNumInv; + SetPlrHandItem(&plr[myplr].InvList[i], IDI_GOLD); + GetGoldSeed(myplr, &plr[myplr].InvList[i]); + plr[myplr].InvList[i]._ivalue = 5000; + plr[myplr].InvList[i]._iCurs = ITEM_5GOLD; + plr[myplr].InvList[i]._iStatFlag = TRUE; + plr[myplr]._pGold += 5000; + plr[myplr]._pNumInv++; + plr[myplr].InvGrid[j] = plr[myplr]._pNumInv; + } + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#if CHEATS +void DaveNewPremium() +{ + numpremium = 0; + for (int i = 0; i < MAXPREMIUM; i++) premiumitem[i]._itype = -1; + SpawnPremium(30); + for (i = 0; i < MAXWITCHITEMS; i++) witchitem[i]._itype = -1; + SpawnWitch(30); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#if CHEATS +void DaveCleanUp() +{ + int i,j; + + for (j = 0; j < MAXINV; j++) { + if (plr[myplr].InvGrid[j] > 0) { + i = plr[myplr].InvGrid[j]-1; + if (plr[myplr].InvList[i]._itype == IT_GOLD) RemoveInvItem(myplr, i); + } + } + for (j = 0; j < MAXSPD; j++) { + if (plr[myplr].SpdList[j]._itype == IT_GOLD) plr[myplr].SpdList[j]._itype = -1; + } + plr[myplr]._pGold = 0; +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#if CHEATS +void DaveSpells() +{ + for (int i = SPL_FIREBOLT; i < SPL_LAST; i++) { + if (spelldata[i].sBookLvl != -1) { + __int64 t = 1; + plr[myplr]._pMemSpells |= (t << (i-1)); + plr[myplr]._pSplLvl[i] = 10; + } + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#if CHEATS +void DaveSetSpell(int spl, int lvl) +{ + __int64 t = 1; + plr[myplr]._pMemSpells |= (t << (spl-1)); + plr[myplr]._pSplLvl[spl] = lvl; +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#if CHEATS +void DaveSpells2() +{ + DaveSetSpell(SPL_FIREBOLT, 8); + DaveSetSpell(SPL_CBOLT, 11); + DaveSetSpell(SPL_HBOLT, 10); + DaveSetSpell(SPL_HEAL, 7); + DaveSetSpell(SPL_HEALOTHER, 5); + DaveSetSpell(SPL_LIGHTNING, 9); + DaveSetSpell(SPL_WALL, 5); + DaveSetSpell(SPL_TELEKINESIS, 3); + DaveSetSpell(SPL_TOWN, 3); + DaveSetSpell(SPL_FLASH, 3); + DaveSetSpell(SPL_PHASE, 2); + DaveSetSpell(SPL_MANASHLD, 2); + DaveSetSpell(SPL_WAVE, 4); + DaveSetSpell(SPL_FIREBALL, 3); + DaveSetSpell(SPL_STONE, 1); + DaveSetSpell(SPL_CHAIN, 1); + DaveSetSpell(SPL_GUARDIAN, 4); + DaveSetSpell(SPL_ELEMENT, 3); + DaveSetSpell(SPL_NOVA, 1); + DaveSetSpell(SPL_GOLEM, 2); + DaveSetSpell(SPL_BSTAR, 1); + DaveSetSpell(SPL_BONESPIRIT, 1); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RecalcStoreStats() +{ + int i; + + for (i = 0; i < MAXSMITHITEMS; i++) + if (smithitem[i]._itype != -1) smithitem[i]._iStatFlag = StoreStatOk(&smithitem[i]); + for (i = 0; i < MAXPREMIUM; i++) + if (premiumitem[i]._itype != -1) premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + for (i = 0; i < MAXWITCHITEMS; i++) + if (witchitem[i]._itype != -1) witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + for (i = 0; i < MAXHEALITEMS; i++) + if (healitem[i]._itype != -1) healitem[i]._iStatFlag = StoreStatOk(&healitem[i]); + boyitem._iStatFlag = StoreStatOk(&boyitem); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int ItemNoFlippy() +/*-----------------------------------------------------------------------** +** DESCRIPTION: Makes it so a newly created item will not have a flippy. +** INPUT: None +** RETURN: r = The item number if needed. +/*-----------------------------------------------------------------------*/ +{ + int r; + + r = itemactive[numitems-1]; + item[r]._iAnimFrame = item[r]._iAnimLen; + item[r]._iAnimFlag = FALSE; + item[r]._iSelFlag = ISEL_FLR; + + return r; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if CHEATS +void DaveQuestText() +{ + if (!tstQMsgIndexFlag) { + tstQMsgFlag = TRUE; + InitQTextMsg(tstQMsgIndex); + } +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateSpellBook(int x, int y, int ispell, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done = FALSE; + + int bookminlevel = spelldata[ispell].sBookLvl + 1; + + if (bookminlevel < 1) // unavailable + return; + + idx = RndTypeItems(IT_MISC, IMID_BOOK, bookminlevel); + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the book requested + do { + SetupAllItems(ii, idx, GetRndSeed(), /* currlevel */ bookminlevel << 1, 1, TRUE, FALSE, delta); + if ((item[ii]._iMiscId == IMID_BOOK) && + (item[ii]._iSpell == ispell)) { + done = TRUE; + } + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateMagicArmor(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done = FALSE; + + int efflevel = GetEffLevel(); + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the armor requested + idx = RndTypeItems(imisc, IMID_NONE, efflevel); + do { +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 1, TRUE, FALSE, delta); + if (item[ii]._iCurs == icurs) { + done = TRUE; + } else idx = RndTypeItems(imisc, IMID_NONE, efflevel); + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateAmulet(int x, int y, int level, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + bool done = false; + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the amulet requested + idx = RndTypeItems(IT_AMULET, IMID_AMULET, level); + do { +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), level << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), level << 1, 1, TRUE, FALSE, delta); + if (item[ii]._iCurs == ITEM_AMULET1) { + done = true; + } else idx = RndTypeItems(IT_AMULET, IMID_AMULET, level); + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CreateMagicWeapon(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta) +{ + int ii, idx; + BOOL done = FALSE; + int const imid = (imisc == IT_STAFF) ? IMID_STAFF : IMID_NONE; + + int efflevel = GetEffLevel(); + + if (numitems < MAXITEMS) { + ii = itemavail[0]; + GetSuperItemSpace(x,y,ii); + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + //Loop until we get the weapon requested + idx = RndTypeItems(imisc, imid, efflevel); + do { +#if CHEATS + if (itemcheat) + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 15, TRUE, FALSE, delta); + else +#endif + SetupAllItems(ii, idx, GetRndSeed(), efflevel << 1, 1, TRUE, FALSE, delta); + if (item[ii]._iCurs == icurs) { + done = TRUE; + } else idx = RndTypeItems(imisc, imid, efflevel); + } while (!done); + if (sendmsg) NetSendCmdDItem(FALSE, ii); + if (delta) DeltaAddItem(ii); + numitems++; + } +} + + +// PATCH1.JMM +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void DeleteGetRecord( int nIndex ) { + app_assert(nIndex < gnNumGetRecords); + app_assert(gnNumGetRecords > 0); + + gnNumGetRecords--; + + if(gnNumGetRecords == 0) + return; + + itemgets[nIndex].nIndex = itemgets[gnNumGetRecords].nIndex; + itemgets[nIndex].nSeed = itemgets[gnNumGetRecords].nSeed; + itemgets[nIndex].wCI = itemgets[gnNumGetRecords].wCI; + itemgets[nIndex].dwTimestamp = itemgets[gnNumGetRecords].dwTimestamp; +} + + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define RESEND_TIME 6000 // number of milliseconds to keep a getrecord around + +BOOL CheckGetRecord( int nSeed, WORD wCI, int nIndex ) { + DWORD dwCurr = GetTickCount(); + int i; + + for(i = 0; i < gnNumGetRecords; i++) { + if( (dwCurr - itemgets[i].dwTimestamp) > RESEND_TIME ) { + DeleteGetRecord( i ); + i--; + continue; + } + + if( (nSeed == itemgets[i].nSeed) && (wCI == itemgets[i].wCI) && (nIndex == itemgets[i].nIndex) ) + return FALSE; + + } + + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddGetRecord( int nSeed, WORD wCI, int nIndex ) { + DWORD dwCurr = GetTickCount(); + + if(gnNumGetRecords == MAXITEMS) + return; + + itemgets[gnNumGetRecords].dwTimestamp = dwCurr; + itemgets[gnNumGetRecords].nSeed = nSeed; + itemgets[gnNumGetRecords].wCI = wCI; + itemgets[gnNumGetRecords].nIndex = nIndex; + + gnNumGetRecords++; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RemoveGetRecord( int nSeed, WORD wCI, int nIndex ) { + DWORD dwCurr = GetTickCount(); + int i; + + for(i = 0; i < gnNumGetRecords; i++) { + if( (dwCurr - itemgets[i].dwTimestamp) > RESEND_TIME ) { + DeleteGetRecord( i ); + i--; + continue; + } + + if( (nSeed == itemgets[i].nSeed) && (wCI == itemgets[i].wCI) && (nIndex == itemgets[i].nIndex) ) { + DeleteGetRecord( i ); + return; + } + + } + +} + + +//ENDPATCH1.JMM diff --git a/ITEMS.H b/ITEMS.H new file mode 100644 index 0000000..80826ee --- /dev/null +++ b/ITEMS.H @@ -0,0 +1,905 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/ITEMS.H 3 2/06/97 6:08p Jessmac $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXITEMS 127 + +#define MAXUITEMS 128 // Max number of uniques + +#define TEMPAVAIL 127 + +#define ITEM_RND -1 + +#define INFINITE_DUR 255 + +#define GOLD_VT1 1000 // Gold gfx transition from 1 to several +#define GOLD_VT2 2500 // Gold gfx transition from several to many +//#define GOLD_VMAX 5000 // Max gold in an inv slot +extern int GOLD_VMAX; +extern const int GOLD_DOUBLE_VMAX; + +// Used for cursors +// 1x1 +typedef enum { + ITEM_BLUEBTL = 0, + ITEM_SCROLL , // 1 + ITEM_SCROLL2 , // 2 + ITEM_SCROLL3 , // 3 + ITEM_1GOLD , // 4 + ITEM_3GOLD , // 5 + ITEM_5GOLD , // 6 + ITEM_GOLDRING , // 7 + ITEM_1JRING , // 8 + ITEM_WOODRING , // 9 + ITEM_BLUERING , // 10 + ITEM_3JRING , // 11 + ITEM_SLVRRING , // 12 + ITEM_MJRING , // 13 + ITEM_BRNRING , // 14 + ITEM_SPECTRAL , // 15 + ITEM_3COLORPOT , // 16 + ITEM_GOLDENELIX , // 17 + ITEM_EMPYBAND , // 18 + ITEM_EAR1 , // 19 + ITEM_EAR2 , // 20 + ITEM_EAR3 , // 21 + ITEM_SPHERE , // 22 + ITEM_CUBE , // 23 + ITEM_PYRIMID , // 24 + ITEM_BLOODGEM , // 25 + ITEM_JSPHERE , // 26 + ITEM_JCUBE , // 27 + ITEM_JPYRIMID , // 28 + ITEM_VILE , // 29 + ITEM_BLKBTL , // 30 + ITEM_WHTEBTL , // 31 + ITEM_REDBTL , // 32 + ITEM_YELBTL , // 33 + ITEM_ORGBTL , // 34 + ITEM_BREDBTL , // 35 + ITEM_BLKBTL2 , // 36 + ITEM_GOLDBTL , // 37 + ITEM_LTBLUEBTL , // 38 + ITEM_BLUEBTL2 , // 39 + ITEM_BRAIN , // 40 + ITEM_CLAW , // 41 + ITEM_FANG , // 42 + ITEM_BREAD , // 43 + ITEM_AMULET , // 44 + ITEM_AMULET1 , // 45 + ITEM_AMULET2 , // 46 + ITEM_AMULET3 , // 47 + ITEM_AMULET4 , // 48 + ITEM_POUCH1 , // 49 +// 1x2 + ITEM_DAGGER1 , // 50 + ITEM_DAGGER2 , // 51 + ITEM_BIGBOTTLE , // 52 + ITEM_DAGGER3 , // 53 + ITEM_DAGGER4 , // 54 + ITEM_DAGGER5 , // 55 +// 1x3 + ITEM_BLADE , // 56 + ITEM_BASTSRD , // 57 + ITEM_FALCHION , // 58 + ITEM_MACE , // 59 + ITEM_LONGSRD , // 60 + ITEM_BROADSRD , // 61 + ITEM_SCIMITAR , // 62 + ITEM_MORNSTAR , // 63 + ITEM_SHORTSRD , // 64 + ITEM_CLAYMORE , // 65 + ITEM_CLUB , // 66 + ITEM_SABRE , // 67 + ITEM_KNTSWORD , // 68 + ITEM_CLUB1 , // 69 + ITEM_CLUB2 , // 70 + ITEM_CLUB3 , // 71 + ITEM_SCIMITAR2 , // 72 + ITEM_MAGSWORD , // 73 + ITEM_SKULSWORD , // 74 +// 2x2 + ITEM_HELM , // 75 + ITEM_ROCK , // 76 + ITEM_CROWN , // 77 + ITEM_SKCROWN , // 78 + ITEM_MCROWN , // 79 + ITEM_JESTER , // 80 + ITEM_HARLEQ , // 81 + ITEM_FHELM , // 82 + ITEM_BUCKLER , // 83 + ITEM_FHELM2 , // 84 + ITEM_GRTHELM , // 85 + ITEM_BOOK2 , // 86 + ITEM_BOOK3 , // 87 + ITEM_BOOK , // 88 + ITEM_MUSHROOM , // 89 + ITEM_SKLCAP , // 90 + ITEM_LCAP , // 91 + ITEM_FLESH , // 92 + ITEM_SKLCAP2 , // 93 + ITEM_CLOTHES , // 94 + ITEM_CROWN2 , // 95 + ITEM_MAP , // 96 + ITEM_BOOK4 , // 97 + ITEM_FHELM3 , // 98 + ITEM_SAMHELM , // 99 +///#define ITEM_MUSHROOM 100 +// 2x3 + ITEM_COMPSHLD , // 100 + ITEM_BTLAXE , // 101 + ITEM_LONGBOW , // 102 + ITEM_PARMOR , // 103 + ITEM_AXE , // 104 + ITEM_WSHIELD , // 105 + ITEM_CLEAVER , // 106 + ITEM_STDARMOR , // 107 + ITEM_COMPBOW , // 108 + ITEM_SHRTSTAFF , // 109 + ITEM_2HSWORD , // 110 + ITEM_CHARMOR , // 111 + ITEM_SMALLAXE , // 112 + ITEM_HVYSHIELD , // 113 + ITEM_SCLARMOR , // 114 + ITEM_SMLSHLD , // 115 + ITEM_SKULLSHLD , // 116 + ITEM_WOLFSHLD , // 117 + ITEM_SHORTBOW , // 118 + ITEM_STLLONGBOW , // 119 + ITEM_STLSHRTBOW , // 120 + ITEM_SMLWARHAM , // 121 + ITEM_MAUL , // 122 + ITEM_IRONSTAFF , // 123 + ITEM_STLSTAFF , // 124 + ITEM_LONGSTAFF , // 125 + ITEM_INNSIGN , // 126 + ITEM_HLARMOR , // 127 + ITEM_RAGS , // 128 + ITEM_QARMOR , // 129 + ITEM_BALLNCHN , // 130 + ITEM_FLAIL , // 131 + ITEM_TSHIELD , // 132 + ITEM_HNTRBOW , // 133 + ITEM_GRTSWORD , // 134 + ITEM_LARMOR , // 135 + ITEM_SPLTARMOR , // 136 + ITEM_ROBE , // 137 + ITEM_HVYROBE , // 138 + ITEM_RINGARMOR , // 139 + ITEM_ANVIL , // 140 //#define ITEM_OBOLISK 140 + ITEM_BROADAXE , // 141 + ITEM_LRGAXE , // 142 + ITEM_WICKAXE , // 143 + ITEM_HANDAXE , // 144 + ITEM_GREATAXE , // 145 + ITEM_IRONSHLD , // 146 + ITEM_KITESHLD , // 147 + ITEM_LRGSHLD , // 148 + ITEM_CLOAK , // 149 + ITEM_CAPE , // 150 + ITEM_PARMOR2 , // 151 + ITEM_PARMOR3 , // 152 + ITEM_BPLATE , // 153 + ITEM_RINGMAIL , // 154 + ITEM_BISHOPSTF , // 155 + ITEM_GEMGRTAXE , // 156 + ITEM_ARKARMOR , // 157 + + ITEM_CROSBOW , // 158 + ITEM_NAJARMOR , // 159 + ITEM_GRIZZLY , // 160 + ITEM_GRANDPA , // 161 + ITEM_PROTECT , // 162 + ITEM_REAVER , // 163 + ITEM_WINDFOR , // 164 + ITEM_SWARBOW , // 165 + ITEM_COMPSTF , // 166 + ITEM_SBATLBOW , // 167 + + ITEM_GOLD , // 168 + +// New 1x1 + ITEM_MERLINRING = 168, // 168 // intentional duplicate to gold. + ITEM_MANARING , // 169 + ITEM_AMULWARD , // 170 + ITEM_NECMAGIC , // 171 + ITEM_NECHEALTH , // 172 + ITEM_KARIKSRING , // 173 + ITEM_RINGGROUND , // 174 + ITEM_AMULPROT , // 175 + ITEM_MERCRING , // 176 + ITEM_RINGTHUND , // 177 + ITEM_NECTRUTH , // 178 + ITEM_RINGGIANTS , // 179 + ITEM_AMULGOLD , // 180 + ITEM_RINGMYSTIC , // 181 + ITEM_RINGCOPPER , // 182 + ITEM_AMULACOLYT , // 183 + ITEM_RINGMAGMA , // 184 + ITEM_NECPURIFY , // 185 + ITEM_RINGGLADTR , // 186 + ITEM_RUNEBOMB , // 187 + ITEM_THEODORE , + ITEM_TORNPAPER1 , + ITEM_TORNPAPER2 , + ITEM_TORNPAPER3 , + ITEM_WHOLEPAPER , + ITEM_FIRERUNE1 , + ITEM_FIRERUNE2 , + ITEM_LIGHTRUNE1 , + ITEM_LIGHTRUNE2 , + ITEM_STONERUNE , + +// new 2x2 + ITEM_SUITGREY, + ITEM_SUITBRWN, + +// new 1x3 + ITEM_SWORDEDGE , // 188 + ITEM_SWORDGLAM , // 189 + ITEM_SWORDSERR , // 190 + +// new 2x3 + ITEM_ARMRDARK , // 191 + ITEM_ARMRBONECH , // 192 + ITEM_HAMRTHUND , // 193 + ITEM_SWRDCRYSTL , // 194 + ITEM_STAFJESTER , // 195 + ITEM_STAFMANA , // 196 + ITEM_BOWVULCAN , // 197 + ITEM_BOWSPEED , // 198 + ITEM_AXEANCIENT , // 199 + ITEM_CLUBCARNAG , // 200 + ITEM_MACEDARK , // 201 + ITEM_CLUBDECAY , // 202 + ITEM_AXEDECAY , // 203 + ITEM_SWRDDECAY , // 204 + ITEM_MACEDECAY , // 205 + ITEM_STAFDECAY , // 206 + ITEM_BOWDECAY , // 207 + ITEM_CLUBOUCH , // 208 + ITEM_SWRDDEVAST , // 209 + ITEM_AXEDEVAST , // 210 + ITEM_MORNDEVAST , // 211 + ITEM_MACEDEVAST, // 212 + ITEM_ARMRDMNPLT, + ITEM_ARMRCOW, + + ITEM_LAST_ID +} ITEM_IDS; + + +// Split later + +// Used for plr gfx +#define IT_MISC 0 +#define IT_SWORD 1 +#define IT_AXE 2 +#define IT_BOW 3 +#define IT_MACE 4 +#define IT_SHIELD 5 +#define IT_ARMOR 6 +#define IT_HELM 7 +#define IT_MARMOR 8 +#define IT_HARMOR 9 +#define IT_STAFF 10 +#define IT_GOLD 11 +#define IT_RING 12 +#define IT_AMULET 13 +#define IT_FOOD 14 + +// Used for inv location +#define IL_HAND 1 +#define IL_2HAND 2 +#define IL_BODY 3 +#define IL_HEAD 4 +#define IL_RING 5 +#define IL_NECK 6 +#define IL_INV 7 +#define IL_SPD 8 + +// Item classification for treasure types +#define IC_WEAP 1 +#define IC_ARMOR 2 +#define IC_ITEM 3 +#define IC_GOLD 4 +#define IC_SPECIAL 5 + +// Set item indexes for first non-random items +enum _item_indexes { + IDI_GOLD=0, // Item Data Table indexes +// Init items + IDI_WARRIOR, + IDI_WARRSHLD, + IDI_WARRCLUB, + IDI_ROGUE, + IDI_SORCEROR, +// Quest items + IDI_FIRSTQUEST, + IDI_CLEAVER=IDI_FIRSTQUEST, + IDI_SKCROWN, // Same as cleaver + IDI_INFRARING, // Same as cleaver + IDI_ROCK, + IDI_OPTAMULET, + IDI_TRING, // Same as cleaver + IDI_BANNER, + IDI_HARCREST, // Same as cleaver + IDI_STEELVEIL, // Same as cleaver + IDI_GLDNELIX, // Golden Elixor + IDI_ANVIL, // Anvil of Dawn + IDI_MUSHROOM, // Black Mushroom + IDI_BRAIN, // Brain + IDI_FUNGALTM, // Fungal Tome + IDI_SPECELIX, // Spectral Elixir + IDI_BLDSTONE, // Blood Stones + IDI_MAPOFDOOM, + IDI_LASTQUEST=IDI_MAPOFDOOM, +// Ears + IDI_EAR, +// Useful item + IDI_HEAL, + IDI_MANA, + IDI_IDENTIFY, + IDI_PORTAL, +// New items + IDI_ARMOFVAL, // Same as cleaver + IDI_FULLHEAL, + IDI_FULLMANA, + IDI_GRISWOLD, + IDI_ARMRCOW, + IDI_LAZSTAFF, + IDI_RESURRECT, + IDI_OILACC, + IDI_MONK, + IDI_BARD, + IDI_BARDDAGGER, + IDI_RUNEBOMB, + IDI_THEODORE, + IDI_AURIC, + IDI_NOTE1, + IDI_NOTE2, + IDI_NOTE3, + IDI_FULLNOTE, + IDI_SUITBRWN, + IDI_SUITGREY, + // Items for randomizing. + // Helmets and caps + IDI_CAP, + IDI_SKULLCAP, + IDI_HELM, + IDI_FULLHELM, + IDI_CROWN, + IDI_GREATHEALM, + // Body Armor + IDI_CAPE, + IDI_RAGS, + IDI_CLOAK, + IDI_ROBE, + IDI_QUILTED_ARMOR, + IDI_LEATHER_ARMOR, + IDI_HARD_LEATHER_ARMOR, + IDI_STUDDED_LEATHER_ARMOR, + IDI_RING_MAIL, + IDI_CHAIN_MAIL, + IDI_SCALE_MAIL, + IDI_BREAST_PLATE, + IDI_SPLINT_MAIL, + IDI_PLATE_MAIL, + IDI_FIELD_PLATE, + IDI_GOTHIC_PLATE, + IDI_FULL_PLATE_MAIL, + IDI_BUCKLER, + IDI_SMALL_SHIELD, + IDI_LARGE_SHIELD, + IDI_KITE_SHIELD, + IDI_TOWER_SHIELD, + IDI_GOTHIC_SHIELD, + IDI_POTION_OF_HEALING, + IDI_POTION_OF_FULL_HEALING, + IDI_POTION_OF_MANA, + IDI_POTION_OF_FULL_MANA, + // unused IDI_POTION_OF_EXPERIENCE, + IDI_POTION_OF_REJUVENATION, + IDI_POTION_OF_FULL_REJUVENATION, + IDI_BLACKSMITH_OIL, + IDI_OIL_OF_ACCURACY, + IDI_OIL_OF_SHARPNESS, + IDI_OIL, // random attributes. + IDI_ELIXIR_OF_STRENGTH, + IDI_ELIXIR_OF_MAGIC, + IDI_ELIXIR_OF_DEXTERITY, + IDI_ELIXIR_OF_VITALITY, + // unused IDI_SCROLL_OF_FIREBOLT, + // unused IDI_SCROLL_OF_CHARGED_BOLT, + // unused IDI_SCROLL_OF_HOLY_BOLT, + IDI_SCROLL_OF_HEALING, + IDI_SCROLL_OF_SEARCH, + IDI_SCROLL_OF_LIGHTNING, + IDI_SCROLL_OF_IDENTIFY, + IDI_SCROLL_OF_RESURRECT, + IDI_SCROLL_OF_FIREWALL, + // unused IDI_SCROLL_OF_TELEKINESIS, + IDI_SCROLL_OF_INFERNO, + IDI_SCROLL_OF_TOWN_PORTAL, + IDI_SCROLL_OF_FLASH, + IDI_SCROLL_OF_INFRAVISION, + IDI_SCROLL_OF_PHASING, + IDI_SCROLL_OF_MANA_SHIELD, + IDI_SCROLL_OF_FLAMEWAVE, + IDI_SCROLL_OF_FIREBALL, + IDI_SCROLL_OF_STONECURSE, + IDI_SCROLL_OF_CHAIN_LIGHTNING, + IDI_SCROLL_OF_GUARDIAN, + IDI_UNUSED_SCROLL, + IDI_SCROLL_OF_NOVA, + IDI_SCROLL_OF_GOLEM, + IDI_SCROLL_OF_BLOODBOIL, // unused + IDI_SCROLL_OF_TELEPORT, + IDI_SCROLL_OF_APOCALYPSE, + // unused IDI_SCROLL_OF_BONESPIRIT, + // unused IDI_SCROLL_OF_BLOODSTAR, + IDI_FIRST_BOOK, + IDI_SECOND_BOOK, + IDI_THIRD_BOOK, + IDI_LAST_BOOK, + IDI_DAGGER, + IDI_SHORT_SWORD, + IDI_FALCHION, + IDI_SCIMITAR, + IDI_CLAYMORE, + IDI_BLADE, + IDI_SABRE, + IDI_LONG_SWORD, + IDI_BROAD_SWORD, + IDI_BASTARD_SWORD, + IDI_TWO_HANDED_SWORD, + IDI_GREAT_SWORD, + IDI_SMALL_AXE, + IDI_AXE, + IDI_LARGE_AXE, + IDI_BROAD_AXE, + IDI_BATTLE_AXE, + IDI_GREAT_AXE, + IDI_MACE, + IDI_MORNINGSTAR, + IDI_WAR_HAMMER, + IDI_SPIKED_CLUB, + IDI_CLUB, + IDI_FLAIL, + IDI_MAUL, + IDI_SHORT_BOW, + IDI_HUNTERS_BOW, + IDI_LONG_BOW, + IDI_COMPOSITE_BOW, + IDI_SHORT_WAR_BOW, + IDI_LONG_WAR_BOW, + IDI_SHORT_STAFF, + IDI_LONG_STAFF, + IDI_COMPOSITE_STAFF, + IDI_QUARTER_STAFF, + IDI_WAR_STAFF, + IDI_FIRST_RING, + IDI_SECOND_RING, + IDI_LAST_RING, + IDI_FIRST_AMULET, + IDI_LAST_AMULET, + IDI_RUNE_OF_FIRE, + IDI_RUNE_OF_LIGHTNING, + IDI_GREATER_RUNE_OF_FIRE, + IDI_GREATER_RUNE_OF_LIGHTNING, + IDI_RUNE_OF_STONE, + + // Insert any new items above this line. + IDI_LAST_RANDOM_ITEM + +}; + +#define IDI_BARBARIAN IDI_SPIKED_CLUB +#define IDI_BARSHLD IDI_WARRSHLD + +#define IAF_INFRAVISION 0x00000001 +#define IAF_SKING 0x00000002 +#define IAF_RNDARROW 0x00000004 +#define IAF_FIREARROW 0x00000008 +#define IAF_FIREHIT 0x00000010 +#define IAF_LIGHTHIT 0x00000020 +#define IAF_CONSTRICT 0x00000040 +#define IAF_NOMANA 0x00000080 +#define IAF_NOHEAL 0x00000100 +#define IAF_RABID 0x00000200 // not in game +#define IAF_HALFTRAP 0x00000400 // not in game -called TRAPDAM +#define IAF_KNOCKBACK 0x00000800 +#define IAF_MNOHEAL 0x00001000 +#define IAF_BAT10 0x00002000 +#define IAF_BAT20 0x00004000 +#define IAF_ALLBAT (IAF_BAT10 | IAF_BAT20) +#define IAF_LEECH10 0x00008000 +#define IAF_LEECH20 0x00010000 +#define IAF_ALLLEECH (IAF_LEECH10 | IAF_LEECH20) +#define IAF_ATANIM1 0x00020000 +#define IAF_ATANIM2 0x00040000 +#define IAF_ATANIM3 0x00080000 +#define IAF_ATANIM4 0x00100000 +#define IAF_ALLATANIM (IAF_ATANIM1 | IAF_ATANIM2 | IAF_ATANIM3 | IAF_ATANIM4 ) +#define IAF_HTANIM1 0x00200000 +#define IAF_HTANIM2 0x00400000 +#define IAF_HTANIM3 0x00800000 +#define IAF_ALLHTANIM (IAF_HTANIM1 | IAF_HTANIM2 | IAF_HTANIM3) +#define IAF_BLANIM 0x01000000 +#define IAF_LARROW 0x02000000 +#define IAF_THORN 0x04000000 +#define IAF_LMANA 0x08000000 +#define IAF_TRAPDAM 0x10000000 +#define IAF_OMEHAND 0x20000000 +#define IAF_DAMDEMON 0x40000000 +#define IAF_ZERORES 0x80000000 + +#define IAF2_DEVASTATION 0x00000001 +#define IAF2_DECAY 0x00000002 +#define IAF2_PERIL 0x00000004 +#define IAF2_JESTER 0x00000008 +#define IAF2_CLONE 0x00000010 +#define IAF2_DEMONAC 0x00000020 +#define IAF2_UNDEADAC 0x00000040 + +#define ISEL_NONE 0 // Items start out unselectable +#define ISEL_FLR 1 // Most items +#define ISEL_TOP 2 // Items on objects usually +#define ISEL_ALL 3 // Large (2 square) items + +#define IMAGIC_NONE 0 +#define IMAGIC_MAGIC 1 +#define IMAGIC_UNIQUE 2 + +// Item re-creation information +// Creation bits are as follows: +// bit# desc +// 1-6 Level +// 7 Item Goodonly (T/F) +// 8,9 Unique percentage (0 = 0%, 1 = 15%, 2 = 1%) +// 8&9 Useful item only +// 10 Unique item +// 11 Spawned by Blacksmith +// 12 Spawned by Blacksmith premium +// 13 Spawned by Pegboy +// 14 Spawned by Witch +// 15 Spawned by Healer +#define ICI_USEFUL 0x0180 +#define ICI_UPER1 0x0100 +#define ICI_UPER15 0x0080 +#define ICI_ONLYGOOD 0x0040 +#define ICI_UNIQUE 0x0200 +#define ICI_SMITH 0x0400 +#define ICI_PREMIUM 0x0800 +#define ICI_BOY 0x1000 +#define ICI_WITCH 0x2000 +#define ICI_HEALER 0x4000 +#define ICI_PREGEN 0x8000 + +#define ICI_LVLMASK 0x003f +#define ICI_TOWNMASK 0x7c00 +#define ICI_PREGENMASK 0x7fff + +// Unique item index list +#define UID_CLEAVER 0 // Butcher's cleaver +#define UID_SKCROWN 1 // Skeleton King's crown +#define UID_INFRARING 2 // Infravision ring +#define UID_OPTAMULET 3 // Optic Amulet +#define UID_TRING 4 // Ring of truth +#define UID_HARCREST 5 // Harlequin Crest +#define UID_STEELVEIL 6 // Veil of Steel +#define UID_ARMOFVAL 7 // Armor of Valor +#define UID_GRISWOLD 8 // Griswold's Edge +#define UID_ARMRCOW 9 // Cow Armor +#define UID_LGTFORGE 9 + +// item no random spawn, normal random spawn, or double chance random spawn +#define IRND_NO 0 +#define IRND_NORMAL 1 +#define IRND_DOUBLE 2 + +#define RESIST_MAX 75 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + + +typedef struct { + char *PLName; // Name of power + int PLPower; // Power type + int PLParam1; // Misc param 1 + int PLParam2; // Misc param 2 + char PLMinLvl; // Min dungeon level of power appearing + long PLIType; // Item type (armor/shield/weapon/staff/bow/ring) + byte PLGOE; // Good/Evil/Either + BOOL PLDouble; // Double chance of spawning (more common magic) + BOOL PLOk; // Item good or bad + int PLMinVal; // Item min value modifier + int PLMaxVal; // Item max value modifier + int PLMultVal; // Item value multiplier +} PLStruct; + +typedef struct { + char *UIName; // Unique item name + char UIItemId; // Item id for base stats + char UIMinLvl; // Min level can be found at + char UINumPL; // Number of power list items + int UIValue; // Items value + char UIPower1; // Power 1 and 2 params + int UIParam1; + int UIParam2; + char UIPower2; // Power 2 and 2 params + int UIParam3; + int UIParam4; + char UIPower3; // Power 3 and 2 params + int UIParam5; + int UIParam6; + char UIPower4; // Power 4 and 2 params + int UIParam7; + int UIParam8; + char UIPower5; // Power 5 and 2 params + int UIParam9; + int UIParam10; + char UIPower6; // Power 6 and 2 params + int UIParam11; + int UIParam12; +} UItemStruct; + +typedef struct { + BOOL iRnd; // Random item or special + char iClass; // Item classification + char iLoc; // Item Body Location + int iCurs; // Item cursor gfx + char itype; // Item type + char iItemId; // Item id# + char *iName; // name + char *iSName; // short name + char iMinMLvl; // Min monster level to drop it + int iDurability; // Durability of the item + int iMinDam; // Min damage + int iMaxDam; // Max damage + int iMinAC; // Min Armor Class + int iMaxAC; // Max Armor Class + char iMinStr; // Min Strength stat to use item + char iMinMag; // Min Magic stat to use item + char iMinDex; // Min Dexterity stat to use item + long iFlags; // Item ability flags + int iMiscId; // Misc item uses id + long iSpell; // item spell + BOOL iUsable; // Usable item? + int iValue; // item min value + int iMaxValue; // item max value +} ItemDataStruct; + +// PATCH1.JMM +typedef struct { + int nSeed; + WORD wCI; + int nIndex; + DWORD dwTimestamp; +} ItemGetRecordStruct; +// ENDPATCH1.JMM + +typedef struct { + int _iSeed; // item seed to generate itself + WORD _iCreateInfo; // item re-creation info + int _itype; // item type + int _ix; // item map x + int _iy; // item map y + BOOL _iAnimFlag; // Does this item animate? + BYTE *_iAnimData; // Data pointer to anim tables + int _iAnimLen; // number of anim frames + int _iAnimFrame; // current anim frame + long _iAnimWidth; // Width of anim + long _iAnimWidth2; // (Width - 64) >> 1 of anim +// PATCH1.JMM + // FLAG IS NO LONGER USED + //BOOL _iDelFlag; // Delete this item + BOOL _iInvalid; +// ENDPATCH1.JMM + + char _iSelFlag; // Select top, floor, or all + BOOL _iPostDraw; // Draw after objects or before? + + BOOL _iIdentified; // Has item been identified? + char _iMagical; // (No/Reg/Unique) Does the item have magical attributes? + char _iName[64]; // item name + char _iIName[64]; // identified name + char _iLoc; // item body location + char _iClass; // item classification + int _iCurs; // item cursor type + int _ivalue; // item value + int _iIvalue; // item identified value + int _iMinDam; // item min damage + int _iMaxDam; // item max damage + int _iAC; // item armor class + long _iFlags; // item ability flags + int _iMiscId; // Misc item uses id + int _iSpell; // item spell + + int _iCharges; // random number of charges + int _iMaxCharges; // Max Charges of a staff + + int _iDurability; // How much strength until it breaks + int _iMaxDur; // Max Durability + + int _iPLDam; // Power List damage multiplier + int _iPLToHit; // Power List to hit increase + int _iPLAC; // Power List AC increase + int _iPLStr; // Power List Strength increase + int _iPLMag; // Power List Magic increase + int _iPLDex; // Power List Dexterity increase + int _iPLVit; // Power List Vitality increase + int _iPLFR; // Power List Fire resistance + int _iPLLR; // Power List Lightning resistance + int _iPLMR; // Power List Misc Magic resistance + long _iPLMana; // Power List Mana + long _iPLHP; // Power List Hit Points + int _iPLDamMod; // Power List damage modifier (num, not %) + int _iPLGetHit; // Power List Get hit modifier (+/-) + int _iPLLight; // Power List light radius + char _iSplLvlAdd; // What to add to each spell level + + char _iRequest; // If item has be requested to be picked up (drb 12/9) + int _iUid; // If unique item, index into unique table (drb 12/8) + + int _iFMinDam; // Fire hit min damage + int _iFMaxDam; // Fire hit max damage + int _iLMinDam; // Lightning hit min damage + int _iLMaxDam; // Lightning hit max damage + + int _iPLEnAc; // Enemy armor class reduced by this amount + + char _iPrePower; // Power List index for prefix + char _iSufPower; // Power List index for suffix + + int _iVAdd1; // value add #1 + int _iVMult1; // value multiplier #1 + int _iVAdd2; // value add #2 + int _iVMult2; // value multiplier #2 + + char _iMinStr; // Min Strength stat to use item + byte _iMinMag; // Min Magic stat to use item + char _iMinDex; // Min Dexterity stat to use item + BOOL _iStatFlag; // Draw with red filter or not + int IDidx; // AllItemsData index + char _oldlight; // Old prelight val + long _iFlags2; // item ability flags +} ItemStruct; + +#define SAVE_ITEM_SIZE sizeof(ItemStruct) + + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern ItemStruct item[MAXITEMS+1]; +extern long numitems; + +extern int itemactive[MAXITEMS]; +extern int itemavail[MAXITEMS]; + +// PATCH1.JMM +extern ItemGetRecordStruct itemgets[MAXITEMS]; +extern int gnNumGetRecords; +// ENDPATCH1.JMM + +extern BOOL UniqueItemFlag[MAXUITEMS]; +extern BOOL uitemflag; + +extern int ItemInvSnds[]; +extern BYTE ItemCAnimTbl[]; +#if CHEATS +extern BOOL davecheat; +extern int tstQMsgSpd; +extern int tstQMsgIndex; +extern BOOL tstQMsgFlag; +extern BOOL tstQMsgIndexFlag; +#endif + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitItems(); +void ProcessItems(); +void InitItemGFX(); +void FreeItemGFX(); +void DaveGold(); +void DaveNewPremium(); +void DaveCleanUp(); +void DaveSpells(); +void DaveSpells2(); +void DaveQuestText(); + +BOOL ItemSpaceOk(int, int); + +void SpawnItem(int, int, int, BOOL); // Called by monsters +void SpawnUnique(int, int, int); // Called by monsters +void RespawnItem(int ii, BOOL FlipFlag); // Called by plr placing object back + +void CreateItem(int, int, int); // Spawn a specific item at x, y +void CreateRndItem(int, int, BOOL, BOOL, BOOL); // Spawn any item around x,y (item level >= (currlevel*2)) +void CreateRndUseful(int, int, int, BOOL); // Spawn either health, mana, or identify +void CreateTypeItem(int, int, BOOL, int, int, BOOL, BOOL); // Spawn a specific type of item +void CreateSpellBook(int x, int y, int ispell, BOOL sendmsg, BOOL delta); //Spawn a specific spell book +void CreateMagicArmor(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta); //Spawn specific magical armor +void CreateAmulet(int x, int y, int level, BOOL sendmsg, BOOL delta); //Spawn an amulet +void CreateMagicWeapon(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta); //Spawn specific magical weapon + +void RecreateItem(int, int, WORD, int, int); +void RecreateEar(int, WORD, int, BOOL, int, int, int, int, int, int); + +void SyncItemAnim(int); + +void GetItemStr(int); + +void CalcPlrItemVals(int,BOOL); +void CalcPlrScrolls(int); +void CalcPlrStaff(int); +void CalcPlrItemMin(int); +void CalcPlrInv(int,BOOL); + +void CreatePlrItems(int); + +void SpawnRock(); + +void CheckIdentify(int, int); +void DoRepair(int, int); +void DoRecharge(int, int); +void DoOil(int, int); + +void PrintItemPower(char,const ItemStruct * x); +void PrintItemDetails(const ItemStruct * x); +void PrintItemDur(const ItemStruct * x); + +void UseItem(int, int, int); + +void SpawnSmith(int); +void SpawnPremium(int); +void SpawnWitch(int); +void SpawnBoy(int); +void SpawnHealer(int); +void SpawnStoreGold(); +void SpawnQuestItem(int itemid, int x,int y, int randarea, int selflag); + +void DrawUniqueInfo(); + +void GetItemAttrs(int i, int idata, int lvl); + +int ItemNoFlippy(); +void GetSuperItemLoc(int x, int y, int &xx, int &yy); + +// PATCH1.JMM +BOOL CheckGetRecord( int nSeed, WORD wCI, int nIndex ); +void AddGetRecord( int nSeed, WORD wCI, int nIndex ); +void RemoveGetRecord( int nSeed, WORD wCI, int nIndex ); +// ENDPATCH1.JMM + +void SetPlrHandItem(ItemStruct *h, int idata); +void GetPlrHandSeed(ItemStruct *h); + +typedef struct { + int x; + int y; + BOOL Initted; + ItemStruct item; +} CornerStoneType; + +extern CornerStoneType CornerStone; + +extern void CornerstoneRestore(int x, int y); +extern void CornerstoneSave(); diff --git a/ITEMS.HSV b/ITEMS.HSV new file mode 100644 index 0000000..7f039cf --- /dev/null +++ b/ITEMS.HSV @@ -0,0 +1,752 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/ITEMS.H 3 2/06/97 6:08p Jessmac $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXITEMS 127 + +#define MAXUITEMS 128 // Max number of uniques + +#define TEMPAVAIL 127 + +#define ITEM_RND -1 + +#define INFINITE_DUR 255 + +#define GOLD_VT1 1000 // Gold gfx transition from 1 to several +#define GOLD_VT2 2500 // Gold gfx transition from several to many +//#define GOLD_VMAX 5000 // Max gold in an inv slot +extern int GOLD_VMAX; + +// Used for cursors +// 1x1 +enum { + ITEM_BLUEBTL = 0, + ITEM_SCROLL , // 1 + ITEM_SCROLL2 , // 2 + ITEM_SCROLL3 , // 3 + ITEM_1GOLD , // 4 + ITEM_3GOLD , // 5 + ITEM_5GOLD , // 6 + ITEM_GOLDRING , // 7 + ITEM_1JRING , // 8 + ITEM_WOODRING , // 9 + ITEM_BLUERING , // 10 + ITEM_3JRING , // 11 + ITEM_SLVRRING , // 12 + ITEM_MJRING , // 13 + ITEM_BRNRING , // 14 + ITEM_SPECTRAL , // 15 + ITEM_3COLORPOT , // 16 + ITEM_GOLDENELIX , // 17 + ITEM_EMPYBAND , // 18 + ITEM_EAR1 , // 19 + ITEM_EAR2 , // 20 + ITEM_EAR3 , // 21 + ITEM_SPHERE , // 22 + ITEM_CUBE , // 23 + ITEM_PYRIMID , // 24 + ITEM_BLOODGEM , // 25 + ITEM_JSPHERE , // 26 + ITEM_JCUBE , // 27 + ITEM_JPYRIMID , // 28 + ITEM_VILE , // 29 + ITEM_BLKBTL , // 30 + ITEM_WHTEBTL , // 31 + ITEM_REDBTL , // 32 + ITEM_YELBTL , // 33 + ITEM_ORGBTL , // 34 + ITEM_BREDBTL , // 35 + ITEM_BLKBTL2 , // 36 + ITEM_GOLDBTL , // 37 + ITEM_LTBLUEBTL , // 38 + ITEM_BLUEBTL2 , // 39 + ITEM_BRAIN , // 40 + ITEM_CLAW , // 41 + ITEM_FANG , // 42 + ITEM_BREAD , // 43 + ITEM_AMULET , // 44 + ITEM_AMULET1 , // 45 + ITEM_AMULET2 , // 46 + ITEM_AMULET3 , // 47 + ITEM_AMULET4 , // 48 + ITEM_POUCH1 , // 49 + // Add these back in when you can read them from the .cel file. + //ITEM_DOHICKY , + //ITEM_THEODORE , + //ITEM_PAPER1 , + //ITEM_PAPER2 , + //ITEM_PAPER3 , + //ITEM_PAPER4 , +// 1x2 + ITEM_DAGGER1 , // 50 + ITEM_DAGGER2 , // 51 + ITEM_BIGBOTTLE , // 52 + ITEM_DAGGER3 , // 53 + ITEM_DAGGER4 , // 54 + ITEM_DAGGER5 , // 55 +// 1x3 + ITEM_BLADE , // 56 + ITEM_BASTSRD , // 57 + ITEM_FALCHION , // 58 + ITEM_MACE , // 59 + ITEM_LONGSRD , // 60 + ITEM_BROADSRD , // 61 + ITEM_SCIMITAR , // 62 + ITEM_MORNSTAR , // 63 + ITEM_SHORTSRD , // 64 + ITEM_CLAYMORE , // 65 + ITEM_CLUB , // 66 + ITEM_SABRE , // 67 + ITEM_KNTSWORD , // 68 + ITEM_CLUB1 , // 69 + ITEM_CLUB2 , // 70 + ITEM_CLUB3 , // 71 + ITEM_SCIMITAR2 , // 72 + ITEM_MAGSWORD , // 73 + ITEM_SKULSWORD , // 74 +// 2x2 + ITEM_HELM , // 75 + ITEM_ROCK , // 76 + ITEM_CROWN , // 77 + ITEM_SKCROWN , // 78 + ITEM_MCROWN , // 79 + ITEM_JESTER , // 80 + ITEM_HARLEQ , // 81 + ITEM_FHELM , // 82 + ITEM_BUCKLER , // 83 + ITEM_FHELM2 , // 84 + ITEM_GRTHELM , // 85 + ITEM_BOOK2 , // 86 + ITEM_BOOK3 , // 87 + ITEM_BOOK , // 88 + ITEM_MUSHROOM , // 89 + ITEM_SKLCAP , // 90 + ITEM_LCAP , // 91 + ITEM_FLESH , // 92 + ITEM_SKLCAP2 , // 93 + ITEM_CLOTHES , // 94 + ITEM_CROWN2 , // 95 + ITEM_MAP , // 96 + ITEM_BOOK4 , // 97 + ITEM_FHELM3 , // 98 + ITEM_SAMHELM , // 99 +///#define ITEM_MUSHROOM, // 100 +// 2x3 + ITEM_COMPSHLD , // 100 + ITEM_BTLAXE , // 101 + ITEM_LONGBOW , // 102 + ITEM_PARMOR , // 103 + ITEM_AXE , // 104 + ITEM_WSHIELD , // 105 + ITEM_CLEAVER , // 106 + ITEM_STDARMOR , // 107 + ITEM_COMPBOW , // 108 + ITEM_SHRTSTAFF , // 109 + ITEM_2HSWORD , // 110 + ITEM_CHARMOR , // 111 + ITEM_SMALLAXE , // 112 + ITEM_HVYSHIELD , // 113 + ITEM_SCLARMOR , // 114 + ITEM_SMLSHLD , // 115 + ITEM_SKULLSHLD , // 116 + ITEM_WOLFSHLD , // 117 + ITEM_SHORTBOW , // 118 + ITEM_STLLONGBOW , // 119 + ITEM_STLSHRTBOW , // 120 + ITEM_SMLWARHAM , // 121 + ITEM_MAUL , // 122 + ITEM_IRONSTAFF , // 123 + ITEM_STLSTAFF , // 124 + ITEM_LONGSTAFF , // 125 + ITEM_INNSIGN , // 126 + ITEM_HLARMOR , // 127 + ITEM_RAGS , // 128 + ITEM_QARMOR , // 129 + ITEM_BALLNCHN , // 130 + ITEM_FLAIL , // 131 + ITEM_TSHIELD , // 132 + ITEM_HNTRBOW , // 133 + ITEM_GRTSWORD , // 134 + ITEM_LARMOR , // 135 + ITEM_SPLTARMOR , // 136 + ITEM_ROBE , // 137 + ITEM_HVYROBE , // 138 + ITEM_RINGARMOR , // 139 + ITEM_ANVIL , // 140 //#define ITEM_OBOLISK 140 + ITEM_BROADAXE , // 141 + ITEM_LRGAXE , // 142 + ITEM_WICKAXE , // 143 + ITEM_HANDAXE , // 144 + ITEM_GREATAXE , // 145 + ITEM_IRONSHLD , // 146 + ITEM_KITESHLD , // 147 + ITEM_LRGSHLD , // 148 + ITEM_CLOAK , // 149 + ITEM_CAPE , // 150 + ITEM_PARMOR2 , // 151 + ITEM_PARMOR3 , // 152 + ITEM_BPLATE , // 153 + ITEM_RINGMAIL , // 154 + ITEM_BISHOPSTF , // 155 + ITEM_GEMGRTAXE , // 156 + ITEM_ARKARMOR , // 157 + + ITEM_CROSBOW , // 158 + ITEM_NAJARMOR , // 159 + ITEM_GRIZZLY , // 160 + ITEM_GRANDPA , // 161 + ITEM_PROTECT , // 162 + ITEM_REAVER , // 163 + ITEM_WINDFOR , // 164 + ITEM_SWARBOW , // 165 + ITEM_COMPSTF , // 166 + ITEM_SBATLBOW , // 167 + + ITEM_GOLD , // 168 + +// New 1x1 + ITEM_MERLINRING , // 168 + ITEM_MANARING , // 169 + ITEM_AMULWARD , // 170 + ITEM_NECMAGIC , // 171 + ITEM_NECHEALTH , // 172 + ITEM_KARIKSRING , // 173 + ITEM_RINGGROUND , // 174 + ITEM_AMULPROT , // 175 + ITEM_MERCRING , // 176 + ITEM_RINGTHUND , // 177 + ITEM_NECTRUTH , // 178 + ITEM_RINGGIANTS , // 179 + ITEM_AMULGOLD , // 180 + ITEM_RINGMYSTIC , // 181 + ITEM_RINGCOPPER , // 182 + ITEM_AMULACOLYT , // 183 + ITEM_RINGMAGMA , // 184 + ITEM_NECPURIFY , // 185 + ITEM_RINGGLADTR , // 186 + ITEM_RUNEBOMB , // 187 + +// new 1x3 + ITEM_SWORDEDGE , // 188 + ITEM_SWORDGLAM , // 189 + ITEM_SWORDSERR , // 190 + +// new 2x3 + ITEM_ARMRDARK , // 191 + ITEM_ARMRBONECH , // 192 + ITEM_HAMRTHUND , // 193 + ITEM_SWRDCRYSTL , // 194 + ITEM_STAFJESTER , // 195 + ITEM_STAFMANA , // 196 + ITEM_BOWVULCAN , // 197 + ITEM_BOWSPEED , // 198 + ITEM_AXEANCIENT , // 199 + ITEM_CLUBCARNAG , // 200 + ITEM_MACEDARK , // 201 + ITEM_CLUBDECAY , // 202 + ITEM_AXEDECAY , // 203 + ITEM_SWRDDECAY , // 204 + ITEM_MACEDECAY , // 205 + ITEM_STAFDECAY , // 206 + ITEM_BOWDECAY , // 207 + ITEM_CLUBOUCH , // 208 + ITEM_SWRDDEVAST , // 209 + ITEM_AXEDEVAST , // 210 + ITEM_MORNDEVAST , // 211 + ITEM_MACEDEVAST , // 212 +}; + +// Split later + +// Used for plr gfx +#define IT_MISC 0 +#define IT_SWORD 1 +#define IT_AXE 2 +#define IT_BOW 3 +#define IT_MACE 4 +#define IT_SHIELD 5 +#define IT_ARMOR 6 +#define IT_HELM 7 +#define IT_MARMOR 8 +#define IT_HARMOR 9 +#define IT_STAFF 10 +#define IT_GOLD 11 +#define IT_RING 12 +#define IT_AMULET 13 +#define IT_FOOD 14 + +// Used for inv location +#define IL_HAND 1 +#define IL_2HAND 2 +#define IL_BODY 3 +#define IL_HEAD 4 +#define IL_RING 5 +#define IL_NECK 6 +#define IL_INV 7 +#define IL_SPD 8 + +// Item classification for treasure types +#define IC_WEAP 1 +#define IC_ARMOR 2 +#define IC_ITEM 3 +#define IC_GOLD 4 +#define IC_SPECIAL 5 + +// Set item indexes for first non-random items +enum _item_indexes { + IDI_GOLD=0, // Item Data Table indexes +// Init items + IDI_WARRIOR, + IDI_WARRSHLD, + IDI_WARRCLUB, + IDI_ROGUE, + IDI_SORCEROR, +// Quest items + IDI_FIRSTQUEST, + IDI_CLEAVER=IDI_FIRSTQUEST, + IDI_SKCROWN, // Same as cleaver + IDI_INFRARING, // Same as cleaver + IDI_ROCK, + IDI_OPTAMULET, + IDI_TRING, // Same as cleaver + IDI_BANNER, + IDI_HARCREST, // Same as cleaver + IDI_STEELVEIL, // Same as cleaver + IDI_GLDNELIX, // Golden Elixor + IDI_ANVIL, // Anvil of Dawn + IDI_MUSHROOM, // Black Mushroom + IDI_BRAIN, // Brain + IDI_FUNGALTM, // Fungal Tome + IDI_SPECELIX, // Spectral Elixir + IDI_BLDSTONE, // Blood Stones + IDI_MAPOFDOOM, + IDI_LASTQUEST=IDI_MAPOFDOOM, +// Ears + IDI_EAR, +// Useful item + IDI_HEAL, + IDI_MANA, + IDI_IDENTIFY, + IDI_PORTAL, +// New items + IDI_ARMOFVAL, // Same as cleaver + IDI_FULLHEAL, + IDI_FULLMANA, + IDI_GRISWOLD, + IDI_LGTFORGE, + IDI_LAZSTAFF, + IDI_RESURRECT, + IDI_OILACC, + IDI_MONK, + IDI_BARD, + IDI_BARDDAGGER, + IDI_RUNEBOMB, + IDI_THEODORE, + IDI_AURIC +}; + +#define IAF_INFRAVISION 0x00000001 +#define IAF_SKING 0x00000002 +#define IAF_RNDARROW 0x00000004 +#define IAF_FIREARROW 0x00000008 +#define IAF_FIREHIT 0x00000010 +#define IAF_LIGHTHIT 0x00000020 +#define IAF_CONSTRICT 0x00000040 +#define IAF_NOMANA 0x00000080 +#define IAF_NOHEAL 0x00000100 +#define IAF_RABID 0x00000200 // not in game +#define IAF_HALFTRAP 0x00000400 // not in game -called TRAPDAM +#define IAF_KNOCKBACK 0x00000800 +#define IAF_MNOHEAL 0x00001000 +#define IAF_BAT10 0x00002000 +#define IAF_BAT20 0x00004000 +#define IAF_ALLBAT (IAF_BAT10 | IAF_BAT20) +#define IAF_LEECH10 0x00008000 +#define IAF_LEECH20 0x00010000 +#define IAF_ALLLEECH (IAF_LEECH10 | IAF_LEECH20) +#define IAF_ATANIM1 0x00020000 +#define IAF_ATANIM2 0x00040000 +#define IAF_ATANIM3 0x00080000 +#define IAF_ATANIM4 0x00100000 +#define IAF_ALLATANIM (IAF_ATANIM1 | IAF_ATANIM2 | IAF_ATANIM3 | IAF_ATANIM4 ) +#define IAF_HTANIM1 0x00200000 +#define IAF_HTANIM2 0x00400000 +#define IAF_HTANIM3 0x00800000 +#define IAF_ALLHTANIM (IAF_HTANIM1 | IAF_HTANIM2 | IAF_HTANIM3) +#define IAF_BLANIM 0x01000000 +#define IAF_LARROW 0x02000000 +#define IAF_THORN 0x04000000 +#define IAF_LMANA 0x08000000 +#define IAF_TRAPDAM 0x10000000 +#define IAF_OMEHAND 0x20000000 +#define IAF_DAMDEMON 0x40000000 +#define IAF_ZERORES 0x80000000 + +#define IAF2_DEVASTATION 0x00000001 +#define IAF2_DECAY 0x00000002 +#define IAF2_PERIL 0x00000004 +#define IAF2_JESTER 0x00000008 +#define IAF2_CLONE 0x00000010 +#define IAF2_DEMONAC 0x00000020 +#define IAF2_UNDEADAC 0x00000040 + +#define ISEL_NONE 0 // Items start out unselectable +#define ISEL_FLR 1 // Most items +#define ISEL_TOP 2 // Items on objects usually +#define ISEL_ALL 3 // Large (2 square) items + +#define IMAGIC_NONE 0 +#define IMAGIC_MAGIC 1 +#define IMAGIC_UNIQUE 2 + +// Item re-creation information +// Creation bits are as follows: +// bit# desc +// 1-6 Level +// 7 Item Goodonly (T/F) +// 8,9 Unique percentage (0 = 0%, 1 = 15%, 2 = 1%) +// 8&9 Useful item only +// 10 Unique item +// 11 Spawned by Blacksmith +// 12 Spawned by Blacksmith premium +// 13 Spawned by Pegboy +// 14 Spawned by Witch +// 15 Spawned by Healer +#define ICI_USEFUL 0x0180 +#define ICI_UPER1 0x0100 +#define ICI_UPER15 0x0080 +#define ICI_ONLYGOOD 0x0040 +#define ICI_UNIQUE 0x0200 +#define ICI_SMITH 0x0400 +#define ICI_PREMIUM 0x0800 +#define ICI_BOY 0x1000 +#define ICI_WITCH 0x2000 +#define ICI_HEALER 0x4000 +#define ICI_PREGEN 0x8000 + +#define ICI_LVLMASK 0x003f +#define ICI_TOWNMASK 0x7c00 +#define ICI_PREGENMASK 0x7fff + +// Unique item index list +#define UID_CLEAVER 0 // Butcher's cleaver +#define UID_SKCROWN 1 // Skeleton King's crown +#define UID_INFRARING 2 // Infravision ring +#define UID_OPTAMULET 3 // Optic Amulet +#define UID_TRING 4 // Ring of truth +#define UID_HARCREST 5 // Harlequin Crest +#define UID_STEELVEIL 6 // Veil of Steel +#define UID_ARMOFVAL 7 // Armor of Valor +#define UID_GRISWOLD 8 // Griswold's Edge +#define UID_LGTFORGE 9 // LightForge + +// item no random spawn, normal random spawn, or double chance random spawn +#define IRND_NO 0 +#define IRND_NORMAL 1 +#define IRND_DOUBLE 2 + +#define RESIST_MAX 75 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + + +typedef struct { + char *PLName; // Name of power + int PLPower; // Power type + int PLParam1; // Misc param 1 + int PLParam2; // Misc param 2 + char PLMinLvl; // Min dungeon level of power appearing + long PLIType; // Item type (armor/shield/weapon/staff/bow/ring) + byte PLGOE; // Good/Evil/Either + BOOL PLDouble; // Double chance of spawning (more common magic) + BOOL PLOk; // Item good or bad + int PLMinVal; // Item min value modifier + int PLMaxVal; // Item max value modifier + int PLMultVal; // Item value multiplier +} PLStruct; + +typedef struct { + char *UIName; // Unique item name + char UIItemId; // Item id for base stats + char UIMinLvl; // Min level can be found at + char UINumPL; // Number of power list items + int UIValue; // Items value + char UIPower1; // Power 1 and 2 params + int UIParam1; + int UIParam2; + char UIPower2; // Power 2 and 2 params + int UIParam3; + int UIParam4; + char UIPower3; // Power 3 and 2 params + int UIParam5; + int UIParam6; + char UIPower4; // Power 4 and 2 params + int UIParam7; + int UIParam8; + char UIPower5; // Power 5 and 2 params + int UIParam9; + int UIParam10; + char UIPower6; // Power 6 and 2 params + int UIParam11; + int UIParam12; +} UItemStruct; + +typedef struct { + BOOL iRnd; // Random item or special + char iClass; // Item classification + char iLoc; // Item Body Location + int iCurs; // Item cursor gfx + char itype; // Item type + char iItemId; // Item id# + char *iName; // name + char *iSName; // short name + char iMinMLvl; // Min monster level to drop it + int iDurability; // Durability of the item + int iMinDam; // Min damage + int iMaxDam; // Max damage + int iMinAC; // Min Armor Class + int iMaxAC; // Max Armor Class + char iMinStr; // Min Strength stat to use item + char iMinMag; // Min Magic stat to use item + char iMinDex; // Min Dexterity stat to use item + long iFlags; // Item ability flags + int iMiscId; // Misc item uses id + long iSpell; // item spell + BOOL iUsable; // Usable item? + int iValue; // item min value + int iMaxValue; // item max value +} ItemDataStruct; + +// PATCH1.JMM +typedef struct { + int nSeed; + WORD wCI; + int nIndex; + DWORD dwTimestamp; +} ItemGetRecordStruct; +// ENDPATCH1.JMM + +typedef struct { + int _iSeed; // item seed to generate itself + WORD _iCreateInfo; // item re-creation info + int _itype; // item type + int _ix; // item map x + int _iy; // item map y + BOOL _iAnimFlag; // Does this item animate? + BYTE *_iAnimData; // Data pointer to anim tables + int _iAnimLen; // number of anim frames + int _iAnimFrame; // current anim frame + long _iAnimWidth; // Width of anim + long _iAnimWidth2; // (Width - 64) >> 1 of anim +// PATCH1.JMM + // FLAG IS NO LONGER USED + //BOOL _iDelFlag; // Delete this item + BOOL _iInvalid; +// ENDPATCH1.JMM + + char _iSelFlag; // Select top, floor, or all + BOOL _iPostDraw; // Draw after objects or before? + + BOOL _iIdentified; // Has item been identified? + char _iMagical; // (No/Reg/Unique) Does the item have magical attributes? + char _iName[64]; // item name + char _iIName[64]; // identified name + char _iLoc; // item body location + char _iClass; // item classification + int _iCurs; // item cursor type + int _ivalue; // item value + int _iIvalue; // item identified value + int _iMinDam; // item min damage + int _iMaxDam; // item max damage + int _iAC; // item armor class + long _iFlags; // item ability flags + int _iMiscId; // Misc item uses id + int _iSpell; // item spell + + int _iCharges; // random number of charges + int _iMaxCharges; // Max Charges of a staff + + int _iDurability; // How much strength until it breaks + int _iMaxDur; // Max Durability + + int _iPLDam; // Power List damage multiplier + int _iPLToHit; // Power List to hit increase + int _iPLAC; // Power List AC increase + int _iPLStr; // Power List Strength increase + int _iPLMag; // Power List Magic increase + int _iPLDex; // Power List Dexterity increase + int _iPLVit; // Power List Vitality increase + int _iPLFR; // Power List Fire resistance + int _iPLLR; // Power List Lightning resistance + int _iPLMR; // Power List Misc Magic resistance + long _iPLMana; // Power List Mana + long _iPLHP; // Power List Hit Points + int _iPLDamMod; // Power List damage modifier (num, not %) + int _iPLGetHit; // Power List Get hit modifier (+/-) + int _iPLLight; // Power List light radius + char _iSplLvlAdd; // What to add to each spell level + + char _iRequest; // If item has be requested to be picked up (drb 12/9) + int _iUid; // If unique item, index into unique table (drb 12/8) + + int _iFMinDam; // Fire hit min damage + int _iFMaxDam; // Fire hit max damage + int _iLMinDam; // Lightning hit min damage + int _iLMaxDam; // Lightning hit max damage + + int _iPLEnAc; // Enemy armor class reduced by this amount + + char _iPrePower; // Power List index for prefix + char _iSufPower; // Power List index for suffix + + int _iVAdd1; // value add #1 + int _iVMult1; // value multiplier #1 + int _iVAdd2; // value add #2 + int _iVMult2; // value multiplier #2 + + char _iMinStr; // Min Strength stat to use item + byte _iMinMag; // Min Magic stat to use item + char _iMinDex; // Min Dexterity stat to use item + BOOL _iStatFlag; // Draw with red filter or not + int IDidx; // AllItemsData index + char _oldlight; // Old prelight val + long _iFlags2; // item ability flags +} ItemStruct; + +#define SAVE_ITEM_SIZE sizeof(ItemStruct) + + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern ItemStruct item[MAXITEMS+1]; +extern long numitems; + +extern int itemactive[MAXITEMS]; +extern int itemavail[MAXITEMS]; + +// PATCH1.JMM +extern ItemGetRecordStruct itemgets[MAXITEMS]; +extern int gnNumGetRecords; +// ENDPATCH1.JMM + +extern BOOL UniqueItemFlag[MAXUITEMS]; +extern BOOL uitemflag; + +extern int ItemInvSnds[]; +extern BYTE ItemCAnimTbl[]; +#if CHEATS +extern BOOL davecheat; +extern int tstQMsgSpd; +extern int tstQMsgIndex; +extern BOOL tstQMsgFlag; +extern BOOL tstQMsgIndexFlag; +#endif + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitItems(); +void ProcessItems(); +void InitItemGFX(); +void FreeItemGFX(); +void DaveGold(); +void DaveNewPremium(); +void DaveCleanUp(); +void DaveSpells(); +void DaveSpells2(); +void DaveQuestText(); + +BOOL ItemSpaceOk(int, int); + +void SpawnItem(int, int, int, BOOL); // Called by monsters +void SpawnUnique(int, int, int); // Called by monsters +void RespawnItem(int ii, BOOL FlipFlag); // Called by plr placing object back + +void CreateItem(int, int, int); // Spawn a specific item at x, y +void CreateRndItem(int, int, BOOL, BOOL, BOOL); // Spawn any item around x,y (item level >= (currlevel*2)) +void CreateRndUseful(int, int, int, BOOL); // Spawn either health, mana, or identify +void CreateTypeItem(int, int, BOOL, int, int, BOOL, BOOL); // Spawn a specific type of item +void CreateSpellBook(int x, int y, int ispell, BOOL sendmsg, BOOL delta); //Spawn a specific spell book +void CreateMagicArmor(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta); //Spawn specific magical armor +void CreateAmulet(int x, int y, int level, BOOL sendmsg, BOOL delta); //Spawn an amulet +void CreateMagicWeapon(int x, int y, int imisc, int icurs, BOOL sendmsg, BOOL delta); //Spawn specific magical weapon + +void RecreateItem(int, int, WORD, int, int); +void RecreateEar(int, WORD, int, BOOL, int, int, int, int, int, int); + +void SyncItemAnim(int); + +void GetItemStr(int); + +void CalcPlrItemVals(int,BOOL); +void CalcPlrScrolls(int); +void CalcPlrStaff(int); +void CalcPlrItemMin(int); +void CalcPlrInv(int,BOOL); + +void CreatePlrItems(int); + +void SpawnRock(); + +void CheckIdentify(int, int); +void DoRepair(int, int); +void DoRecharge(int, int); +void DoOil(int, int); + +void PrintItemPower(char,const ItemStruct * x); +void PrintItemDetails(const ItemStruct * x); +void PrintItemDur(const ItemStruct * x); + +void UseItem(int, int, int); + +void SpawnSmith(int); +void SpawnPremium(int); +void SpawnWitch(int); +void SpawnBoy(int); +void SpawnHealer(int); +void SpawnStoreGold(); +void SpawnQuestItem(int itemid, int x,int y, int randarea, int selflag); + +void DrawUniqueInfo(); + +void GetItemAttrs(int i, int idata, int lvl); + +int ItemNoFlippy(); +void GetSuperItemLoc(int x, int y, int &xx, int &yy); + +// PATCH1.JMM +BOOL CheckGetRecord( int nSeed, WORD wCI, int nIndex ); +void AddGetRecord( int nSeed, WORD wCI, int nIndex ); +void RemoveGetRecord( int nSeed, WORD wCI, int nIndex ); +// ENDPATCH1.JMM + +void SetPlrHandItem(ItemStruct *h, int idata); +void GetPlrHandSeed(ItemStruct *h); + +typedef struct { + int x; + int y; + BOOL Initted; + ItemStruct item; +} CornerStoneType; + +extern CornerStoneType CornerStone; + +extern void CornerstoneRestore(int x, int y); +extern void CornerstoneSave(); diff --git a/LIGHTING.CPP b/LIGHTING.CPP new file mode 100644 index 0000000..09711ca --- /dev/null +++ b/LIGHTING.CPP @@ -0,0 +1,1178 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Radial lighting ONLY +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/LIGHTING.CPP 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "lighting.h" +#include "gendung.h" +#include "engine.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "math.h" +#include "automap.h" + +/*-----------------------------------------------------------------------*/ + +#define PAUSEBANDS 224 // Pause band starting color +#define PAUSEBANDE PAUSEBANDS+15 // Pause band ending color + +/*-----------------------------------------------------------------------*/ + +// light test +int lnum = 0; + +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ + +extern "C" { + BYTE *pLightTbl; + char lightmax; +} + +int lightflag = 0; + +LightListStruct LightList[MAXLIGHTS]; +BYTE lightactive[MAXLIGHTS]; +int numlights; +BOOL dolighting; + +LightListStruct VisionList[MAXVISION]; +int numvision; +BOOL dovision; +int visionid; + +/*-----------------------------------------------------------------------** +** File variables +**-----------------------------------------------------------------------*/ + +// table of inc/dec for crawling the lighting radius (clockwise starting with N) +char CrawlTable[2749] = { + 1, 0, 0, + 4, 0, 1, 0, -1, -1, 0, 1, 0, + 16, 0, 2, 0, -2, -1, 2, 1, 2, -1, -2, 1, -2, -1, 1, 1, 1, -1, -1, 1, -1, -2, 1, 2, 1, -2, -1, 2, -1, + -2, 0, 2, 0, + 24, 0, 3, 0, -3, -1, 3, 1, 3, -1, -3, 1, -3, -2, 3, 2, 3, -2, -3, 2, -3, -2, 2, 2, 2, -2, -2, 2, -2, + -3, 2, 3, 2, -3, -2, 3, -2, -3, 1, 3, 1, -3, -1, 3, -1, -3, 0, 3, 0, + 32, 0, 4, 0, -4, -1, 4, 1, 4, -1, -4, 1, -4, -2, 4, 2, 4, -2, -4, 2, -4, -3, 4, 3, 4, -3, -4, 3, -4, + -3, 3, 3, 3, -3, -3, 3, -3, -4, 3, 4, 3, -4, -3, 4, -3, -4, 2, 4, 2, -4, -2, 4, -2, + -4, 1, 4, 1, -4, -1, 4, -1, -4, 0, 4, 0, + 40, 0, 5, 0, -5, -1, 5, 1, 5, -1, -5, 1, -5, -2, 5, 2, 5, -2, -5, 2, -5, -3, 5, 3, 5, -3, -5, 3, -5, + -4, 5, 4, 5, -4, -5, 4, -5, -4, 4, 4, 4, -4, -4, 4, -4, -5, 4, 5, 4, -5, -4, 5, -4, + -5, 3, 5, 3, -5, -3, 5, -3, -5, 2, 5, 2, -5, -2, 5, -2, -5, 1, 5, 1, -5, -1, 5, -1, + -5, 0, 5, 0, + 48, 0, 6, 0, -6, -1, 6, 1, 6, -1, -6, 1, -6, -2, 6, 2, 6, -2, -6, 2, -6, -3, 6, 3, 6, -3, -6, 3, -6, + -4, 6, 4, 6, -4, -6, 4, -6, -5, 6, 5, 6, -5, -6, 5, -6, -5, 5, 5, 5, -5, -5, 5, -5, + -6, 5, 6, 5, -6, -5, 6, -5, -6, 4, 6, 4, -6, -4, 6, -4, -6, 3, 6, 3, -6, -3, 6, -3, + -6, 2, 6, 2, -6, -2, 6, -2, -6, 1, 6, 1, -6, -1, 6, -1, -6, 0, 6, 0, + 56, 0, 7, 0, -7, -1, 7, 1, 7, -1, -7, 1, -7, -2, 7, 2, 7, -2, -7, 2, -7, -3, 7, 3, 7, -3, -7, 3, -7, + -4, 7, 4, 7, -4, -7, 4, -7, -5, 7, 5, 7, -5, -7, 5, -7, -6, 7, 6, 7, -6, -7, 6, -7, + -6, 6, 6, 6, -6, -6, 6, -6, -7, 6, 7, 6, -7, -6, 7, -6, -7, 5, 7, 5, -7, -5, 7, -5, + -7, 4, 7, 4, -7, -4, 7, -4, -7, 3, 7, 3, -7, -3, 7, -3, -7, 2, 7, 2, -7, -2, 7, -2, + -7, 1, 7, 1, -7, -1, 7, -1, -7, 0, 7, 0, + 64, 0, 8, 0, -8, -1, 8, 1, 8, -1, -8, 1, -8, -2, 8, 2, 8, -2, -8, 2, -8, -3, 8, 3, 8, -3, -8, 3, -8, + -4, 8, 4, 8, -4, -8, 4, -8, -5, 8, 5, 8, -5, -8, 5, -8, -6, 8, 6, 8, -6, -8, 6, -8, + -7, 8, 7, 8, -7, -8, 7, -8, -7, 7, 7, 7, -7, -7, 7, -7, -8, 7, 8, 7, -8, -7, 8, -7, + -8, 6, 8, 6, -8, -6, 8, -6, -8, 5, 8, 5, -8, -5, 8, -5, -8, 4, 8, 4, -8, -4, 8, -4, + -8, 3, 8, 3, -8, -3, 8, -3, -8, 2, 8, 2, -8, -2, 8, -2, -8, 1, 8, 1, -8, -1, 8, -1, + -8, 0, 8, 0, + 72, 0, 9, 0, -9, -1, 9, 1, 9, -1, -9, 1, -9, -2, 9, 2, 9, -2, -9, 2, -9, -3, 9, 3, 9, -3, -9, 3, -9, + -4, 9, 4, 9, -4, -9, 4, -9, -5, 9, 5, 9, -5, -9, 5, -9, -6, 9, 6, 9, -6, -9, 6, -9, + -7, 9, 7, 9, -7, -9, 7, -9, -8, 9, 8, 9, -8, -9, 8, -9, -8, 8, 8, 8, -8, -8, 8, -8, + -9, 8, 9, 8, -9, -8, 9, -8, -9, 7, 9, 7, -9, -7, 9, -7, -9, 6, 9, 6, -9, -6, 9, -6, + -9, 5, 9, 5, -9, -5, 9, -5, -9, 4, 9, 4, -9, -4, 9, -4, -9, 3, 9, 3, -9, -3, 9, -3, + -9, 2, 9, 2, -9, -2, 9, -2, -9, 1, 9, 1, -9, -1, 9, -1, -9, 0, 9, 0, + 80, 0, 10, 0,-10, -1, 10, 1, 10, -1,-10, 1,-10, -2, 10, 2, 10, -2,-10, 2,-10, -3, 10, 3, 10, -3,-10, 3,-10, + -4, 10, 4, 10, -4,-10, 4,-10, -5, 10, 5, 10, -5,-10, 5,-10, -6, 10, 6, 10, -6,-10, 6,-10, + -7, 10, 7, 10, -7,-10, 7,-10, -8, 10, 8, 10, -8,-10, 8,-10, -9, 10, 9, 10, -9,-10, 9,-10, + -9, 9, 9, 9, -9, -9, 9, -9,-10, 9, 10, 9,-10, -9, 10, -9,-10, 8, 10, 8,-10, -8, 10, -8, + -10, 7, 10, 7,-10, -7, 10, -7,-10, 6, 10, 6,-10, -6, 10, -6,-10, 5, 10, 5,-10, -5, 10, -5, + -10, 4, 10, 4,-10, -4, 10, -4,-10, 3, 10, 3,-10, -3, 10, -3,-10, 2, 10, 2,-10, -2, 10, -2, + -10, 1, 10, 1,-10, -1, 10, -1,-10, 0, 10, 0, + 88, 0, 11, 0,-11, -1, 11, 1, 11, -1,-11, 1,-11, -2, 11, 2, 11, -2,-11, 2,-11, -3, 11, 3, 11, -3,-11, 3,-11, + -4, 11, 4, 11, -4,-11, 4,-11, -5, 11, 5, 11, -5,-11, 5,-11, -6, 11, 6, 11, -6,-11, 6,-11, + -7, 11, 7, 11, -7,-11, 7,-11, -8, 11, 8, 11, -8,-11, 8,-11, -9, 11, 9, 11, -9,-11, 9,-11, + -10, 11, 10, 11,-10,-11, 10,-11,-10, 10, 10, 10,-10,-10, 10,-10,-11, 10, 11, 10,-11,-10, 11,-10, + -11, 9, 11, 9,-11, -9, 11, -9,-11, 8, 11, 8,-11, -8, 11, -8,-11, 7, 11, 7,-11, -7, 11, -7, + -11, 6, 11, 6,-11, -6, 11, -6,-11, 5, 11, 5,-11, -5, 11, -5,-11, 4, 11, 4,-11, -4, 11, -4, + -11, 3, 11, 3,-11, -3, 11, -3,-11, 2, 11, 2,-11, -2, 11, -2,-11, 1, 11, 1,-11, -1, 11, -1, + -11, 0, 11, 0, + 96, 0, 12, 0,-12, -1, 12, 1, 12, -1,-12, 1,-12, -2, 12, 2, 12, -2,-12, 2,-12, -3, 12, 3, 12, -3,-12, 3,-12, + -4, 12, 4, 12, -4,-12, 4,-12, -5, 12, 5, 12, -5,-12, 5,-12, -6, 12, 6, 12, -6,-12, 6,-12, + -7, 12, 7, 12, -7,-12, 7,-12, -8, 12, 8, 12, -8,-12, 8,-12, -9, 12, 9, 12, -9,-12, 9,-12, + -10, 12, 10, 12,-10,-12, 10,-12,-11, 12, 11, 12,-11,-12, 11,-12,-11, 11, 11, 11,-11,-11, 11,-11, + -12, 11, 12, 11,-12,-11, 12,-11,-12, 10, 12, 10,-12,-10, 12,-10,-12, 9, 12, 9,-12, -9, 12, -9, + -12, 8, 12, 8,-12, -8, 12, -8,-12, 7, 12, 7,-12, -7, 12, -7,-12, 6, 12, 6,-12, -6, 12, -6, + -12, 5, 12, 5,-12, -5, 12, -5,-12, 4, 12, 4,-12, -4, 12, -4,-12, 3, 12, 3,-12, -3, 12, -3, + -12, 2, 12, 2,-12, -2, 12, -2,-12, 1, 12, 1,-12, -1, 12, -1,-12, 0, 12, 0, +104, 0, 13, 0,-13, -1, 13, 1, 13, -1,-13, 1,-13, -2, 13, 2, 13, -2,-13, 2,-13, -3, 13, 3, 13, -3,-13, 3,-13, + -4, 13, 4, 13, -4,-13, 4,-13, -5, 13, 5, 13, -5,-13, 5,-13, -6, 13, 6, 13, -6,-13, 6,-13, + -7, 13, 7, 13, -7,-13, 7,-13, -8, 13, 8, 13, -8,-13, 8,-13, -9, 13, 9, 13, -9,-13, 9,-13, + -10, 13, 10, 13,-10,-13, 10,-13,-11, 13, 11, 13,-11,-13, 11,-13,-12, 13, 12, 13,-12,-13, 12,-13, + -12, 12, 12, 12,-12,-12, 12,-12,-13, 12, 13, 12,-13,-12, 13,-12,-13, 11, 13, 11,-13,-11, 13,-11, + -13, 10, 13, 10,-13,-10, 13,-10,-13, 9, 13, 9,-13, -9, 13, -9,-13, 8, 13, 8,-13, -8, 13, -8, + -13, 7, 13, 7,-13, -7, 13, -7,-13, 6, 13, 6,-13, -6, 13, -6,-13, 5, 13, 5,-13, -5, 13, -5, + -13, 4, 13, 4,-13, -4, 13, -4,-13, 3, 13, 3,-13, -3, 13, -3,-13, 2, 13, 2,-13, -2, 13, -2, + -13, 1, 13, 1,-13, -1, 13, -1,-13, 0, 13, 0, +112, 0, 14, 0,-14, -1, 14, 1, 14, -1,-14, 1,-14, -2, 14, 2, 14, -2,-14, 2,-14, -3, 14, 3, 14, -3,-14, 3,-14, + -4, 14, 4, 14, -4,-14, 4,-14, -5, 14, 5, 14, -5,-14, 5,-14, -6, 14, 6, 14, -6,-14, 6,-14, + -7, 14, 7, 14, -7,-14, 7,-14, -8, 14, 8, 14, -8,-14, 8,-14, -9, 14, 9, 14, -9,-14, 9,-14, + -10, 14, 10, 14,-10,-14, 10,-14,-11, 14, 11, 14,-11,-14, 11,-14,-12, 14, 12, 14,-12,-14, 12,-14, + -13, 14, 13, 14,-13,-14, 13,-14,-13, 13, 13, 13,-13,-13, 13,-13,-14, 13, 14, 13,-14,-13, 14,-13, + -14, 12, 14, 12,-14,-12, 14,-12,-14, 11, 14, 11,-14,-11, 14,-11,-14, 10, 14, 10,-14,-10, 14,-10, + -14, 9, 14, 9,-14, -9, 14, -9,-14, 8, 14, 8,-14, -8, 14, -8,-14, 7, 14, 7,-14, -7, 14, -7, + -14, 6, 14, 6,-14, -6, 14, -6,-14, 5, 14, 5,-14, -5, 14, -5,-14, 4, 14, 4,-14, -4, 14, -4, + -14, 3, 14, 3,-14, -3, 14, -3,-14, 2, 14, 2,-14, -2, 14, -2,-14, 1, 14, 1,-14, -1, 14, -1, + -14, 0, 14, 0, +120, 0, 15, 0,-15, -1, 15, 1, 15, -1,-15, 1,-15, -2, 15, 2, 15, -2,-15, 2,-15, -3, 15, 3, 15, -3,-15, 3,-15, + -4, 15, 4, 15, -4,-15, 4,-15, -5, 15, 5, 15, -5,-15, 5,-15, -6, 15, 6, 15, -6,-15, 6,-15, + -7, 15, 7, 15, -7,-15, 7,-15, -8, 15, 8, 15, -8,-15, 8,-15, -9, 15, 9, 15, -9,-15, 9,-15, + -10, 15, 10, 15,-10,-15, 10,-15,-11, 15, 11, 15,-11,-15, 11,-15,-12, 15, 12, 15,-12,-15, 12,-15, + -13, 15, 13, 15,-13,-15, 13,-15,-14, 15, 14, 15,-14,-15, 14,-15,-14, 14, 14, 14,-14,-14, 14,-14, + -15, 14, 15, 14,-15,-14, 15,-14,-15, 13, 15, 13,-15,-13, 15,-13,-15, 12, 15, 12,-15,-12, 15,-12, + -15, 11, 15, 11,-15,-11, 15,-11,-15, 10, 15, 10,-15,-10, 15,-10,-15, 9, 15, 9,-15, -9, 15, -9, + -15, 8, 15, 8,-15, -8, 15, -8,-15, 7, 15, 7,-15, -7, 15, -7,-15, 6, 15, 6,-15, -6, 15, -6, + -15, 5, 15, 5,-15, -5, 15, -5,-15, 4, 15, 4,-15, -4, 15, -4,-15, 3, 15, 3,-15, -3, 15, -3, + -15, 2, 15, 2,-15, -2, 15, -2,-15, 1, 15, 1,-15, -1, 15, -1,-15, 0, 15, 0, +(char)128, 0, 16, 0,-16, -1, 16, 1, 16, -1,-16, 1,-16, -2, 16, 2, 16, -2,-16, 2,-16, -3, 16, 3, 16, -3,-16, 3,-16, + -4, 16, 4, 16, -4,-16, 4,-16, -5, 16, 5, 16, -5,-16, 5,-16, -6, 16, 6, 16, -6,-16, 6,-16, + -7, 16, 7, 16, -7,-16, 7,-16, -8, 16, 8, 16, -8,-16, 8,-16, -9, 16, 9, 16, -9,-16, 9,-16, + -10, 16, 10, 16,-10,-16, 10,-16,-11, 16, 11, 16,-11,-16, 11,-16,-12, 16, 12, 16,-12,-16, 12,-16, + -13, 16, 13, 16,-13,-16, 13,-16,-14, 16, 14, 16,-14,-16, 14,-16,-15, 16, 15, 16,-15,-16, 15,-16, + -15, 15, 15, 15,-15,-15, 15,-15,-16, 15, 16, 15,-16,-15, 16,-15,-16, 14, 16, 14,-16,-14, 16,-14, + -16, 13, 16, 13,-16,-13, 16,-13,-16, 12, 16, 12,-16,-12, 16,-12,-16, 11, 16, 11,-16,-11, 16,-11, + -16, 10, 16, 10,-16,-10, 16,-10,-16, 9, 16, 9,-16, -9, 16, -9,-16, 8, 16, 8,-16, -8, 16, -8, + -16, 7, 16, 7,-16, -7, 16, -7,-16, 6, 16, 6,-16, -6, 16, -6,-16, 5, 16, 5,-16, -5, 16, -5, + -16, 4, 16, 4,-16, -4, 16, -4,-16, 3, 16, 3,-16, -3, 16, -3,-16, 2, 16, 2,-16, -2, 16, -2, + -16, 1, 16, 1,-16, -1, 16, -1,-16, 0, 16, 0, +(char)136, 0, 17, 0,-17, -1, 17, 1, 17, -1,-17, 1,-17, -2, 17, 2, 17, -2,-17, 2,-17, -3, 17, 3, 17, -3,-17, 3,-17, + -4, 17, 4, 17, -4,-17, 4,-17, -5, 17, 5, 17, -5,-17, 5,-17, -6, 17, 6, 17, -6,-17, 6,-17, + -7, 17, 7, 17, -7,-17, 7,-17, -8, 17, 8, 17, -8,-17, 8,-17, -9, 17, 9, 17, -9,-17, 9,-17, + -10, 17, 10, 17,-10,-17, 10,-17,-11, 17, 11, 17,-11,-17, 11,-17,-12, 17, 12, 17,-12,-17, 12,-17, + -13, 17, 13, 17,-13,-17, 13,-17,-14, 17, 14, 17,-14,-17, 14,-17,-15, 17, 15, 17,-15,-17, 15,-17, + -16, 17, 16, 17,-16,-17, 16,-17,-16, 16, 16, 16,-16,-16, 16,-16,-17, 16, 17, 16,-17,-16, 17,-16, + -17, 15, 17, 15,-17,-15, 17,-15,-17, 14, 17, 14,-17,-14, 17,-14,-17, 13, 17, 13,-17,-13, 17,-13, + -17, 12, 17, 12,-17,-12, 17,-12,-17, 11, 17, 11,-17,-11, 17,-11,-17, 10, 17, 10,-17,-10, 17,-10, + -17, 9, 17, 9,-17, -9, 17, -9,-17, 8, 17, 8,-17, -8, 17, -8,-17, 7, 17, 7,-17, -7, 17, -7, + -17, 6, 17, 6,-17, -6, 17, -6,-17, 5, 17, 5,-17, -5, 17, -5,-17, 4, 17, 4,-17, -4, 17, -4, + -17, 3, 17, 3,-17, -3, 17, -3,-17, 2, 17, 2,-17, -2, 17, -2,-17, 1, 17, 1,-17, -1, 17, -1, + -17, 0, 17, 0, +(char)144, 0, 18, 0,-18, -1, 18, 1, 18, -1,-18, 1,-18, -2, 18, 2, 18, -2,-18, 2,-18, -3, 18, 3, 18, -3,-18, 3,-18, + -4, 18, 4, 18, -4,-18, 4,-18, -5, 18, 5, 18, -5,-18, 5,-18, -6, 18, 6, 18, -6,-18, 6,-18, + -7, 18, 7, 18, -7,-18, 7,-18, -8, 18, 8, 18, -8,-18, 8,-18, -9, 18, 9, 18, -9,-18, 9,-18, + -10, 18, 10, 18,-10,-18, 10,-18,-11, 18, 11, 18,-11,-18, 11,-18,-12, 18, 12, 18,-12,-18, 12,-18, + -13, 18, 13, 18,-13,-18, 13,-18,-14, 18, 14, 18,-14,-18, 14,-18,-15, 18, 15, 18,-15,-18, 15,-18, + -16, 18, 16, 18,-16,-18, 16,-18,-17, 18, 17, 18,-17,-18, 17,-18,-17, 17, 17, 17,-17,-17, 17,-17, + -18, 17, 18, 17,-18,-17, 18,-17,-18, 16, 18, 16,-18,-16, 18,-16,-18, 15, 18, 15,-18,-15, 18,-15, + -18, 14, 18, 14,-18,-14, 18,-14,-18, 13, 18, 13,-18,-13, 18,-13,-18, 12, 18, 12,-18,-12, 18,-12, + -18, 11, 18, 11,-18,-11, 18,-11,-18, 10, 18, 10,-18,-10, 18,-10,-18, 9, 18, 9,-18, -9, 18, -9, + -18, 8, 18, 8,-18, -8, 18, -8,-18, 7, 18, 7,-18, -7, 18, -7,-18, 6, 18, 6,-18, -6, 18, -6, + -18, 5, 18, 5,-18, -5, 18, -5,-18, 4, 18, 4,-18, -4, 18, -4,-18, 3, 18, 3,-18, -3, 18, -3, + -18, 2, 18, 2,-18, -2, 18, -2,-18, 1, 18, 1,-18, -1, 18, -1,-18, 0, 18, 0 +}; + +// points to corresponding radius in above table +char * pCrawlEntry[19] = { + &(CrawlTable[0]), // 0 + &(CrawlTable[3]), // 1 + &(CrawlTable[12]), // 2 + &(CrawlTable[45]), // 3 + &(CrawlTable[94]), // 4 + &(CrawlTable[159]), // 5 + &(CrawlTable[240]), // 6 + &(CrawlTable[337]), // 7 + &(CrawlTable[450]), // 8 + &(CrawlTable[579]), // 9 + &(CrawlTable[724]), // 10 + &(CrawlTable[885]), // 11 + &(CrawlTable[1062]), // 12 + &(CrawlTable[1255]), // 13 + &(CrawlTable[1464]), // 14 + &(CrawlTable[1689]), // 15 + &(CrawlTable[1930]), // 16 + &(CrawlTable[2187]), // 17 + &(CrawlTable[2460]) // 18 +}; + +BYTE vCrawlTable[23][30] = { + {1,0, 2,0, 3,0, 4,0, 5,0, 6,0, 7,0, 8,0, 9,0, 10,0, 11,0, 12,0, 13,0, 14,0, 15,0}, // 0 + {1,0, 2,0, 3,0, 4,0, 5,0, 6,0, 7,0, 8,1, 9,1, 10,1, 11,1, 12,1, 13,1, 14,1, 15,1}, // 1 + {1,0, 2,0, 3,0, 4,1, 5,1, 6,1, 7,1, 8,1, 9,1, 10,1, 11,1, 12,2, 13,2, 14,2, 15,2}, // 2 + {1,0, 2,0, 3,1, 4,1, 5,1, 6,1, 7,1, 8,2, 9,2, 10,2, 11,2, 12,2, 13,3, 14,3, 15,3}, // 3 + {1,0, 2,1, 3,1, 4,1, 5,1, 6,2, 7,2, 8,2, 9,3, 10,3, 11,3, 12,3, 13,4, 14,4, 0,0}, // 4 + {1,0, 2,1, 3,1, 4,1, 5,2, 6,2, 7,3, 8,3, 9,3, 10,4, 11,4, 12,4, 13,5, 14,5, 0,0}, // 5 + {1,0, 2,1, 3,1, 4,2, 5,2, 6,3, 7,3, 8,3, 9,4, 10,4, 11,5, 12,5, 13,6, 14,6, 0,0}, // 6 + {1,1, 2,1, 3,2, 4,2, 5,3, 6,3, 7,4, 8,4, 9,5, 10,5, 11,6, 12,6, 13,7, 0,0, 0,0}, // 7 + {1,1, 2,1, 3,2, 4,2, 5,3, 6,4, 7,4, 8,5, 9,6, 10,6, 11,7, 12,7, 12,8, 13,8, 0,0}, // 8 + {1,1, 2,2, 3,2, 4,3, 5,4, 6,5, 7,5, 8,6, 9,7, 10,7, 10,8, 11,8, 12,9, 0,0, 0,0}, // 9 + {1,1, 2,2, 3,3, 4,4, 5,5, 6,5, 7,6, 8,7, 9,8, 10,9, 11,9, 11,10, 0,0, 0,0, 0,0}, // 10 + {1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7, 8,8, 9,9, 10,10, 11,11, 0,0, 0,0, 0,0, 0,0}, // 11 + {1,1, 2,2, 3,3, 4,4, 5,5, 5,6, 6,7, 7,8, 8,9, 9,10, 9,11, 10,11, 0,0, 0,0, 0,0}, // 12 + {1,1, 2,2, 2,3, 3,4, 4,5, 5,6, 5,7, 6,8, 7,9, 7,10, 8,10, 8,11, 9,12, 0,0, 0,0}, // 13 + {1,1, 1,2, 2,3, 2,4, 3,5, 4,6, 4,7, 5,8, 6,9, 6,10, 7,11, 7,12, 8,12, 8,13, 0,0}, // 14 + {1,1, 1,2, 2,3, 2,4, 3,5, 3,6, 4,7, 4,8, 5,9, 5,10, 6,11, 6,12, 7,13, 0,0, 0,0}, // 15 + {0,1, 1,2, 1,3, 2,4, 2,5, 3,6, 3,7, 3,8, 4,9, 4,10, 5,11, 5,12, 6,13, 6,14, 0,0}, // 16 + {0,1, 1,2, 1,3, 1,4, 2,5, 2,6, 3,7, 3,8, 3,9, 4,10, 4,11, 4,12, 5,13, 5,14, 0,0}, // 17 + {0,1, 1,2, 1,3, 1,4, 1,5, 2,6, 2,7, 2,8, 3,9, 3,10, 3,11, 3,12, 4,13, 4,14, 0,0}, // 18 + {0,1, 0,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,8, 2,9, 2,10, 2,11, 2,12, 3,13, 3,14, 3,15}, // 19 + {0,1, 0,2, 0,3, 1,4, 1,5, 1,6, 1,7, 1,8, 1,9, 1,10, 1,11, 2,12, 2,13, 2,14, 2,15}, // 20 + {0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,8, 1,9, 1,10, 1,11, 1,12, 1,13, 1,14, 1,15}, // 21 + {0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 0,8, 0,9, 0,10, 0,11, 0,12, 0,13, 0,14, 0,15} // 22 +}; + +BYTE LightLvls[16][128]; + + +BYTE LightLvls4[18][18] = { + { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 1 + { 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 2 + { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 3 + { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 4 + { 0, 0, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 1 + { 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 6 + { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 7 + { 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 8 + { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}, // 9 + { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3}, // 2 + { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3}, // 11 + { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, // 12 + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3}, // 13 + { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3}, // 14 + { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3}, // 3 + { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3}, // 16 + { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3}, // 17 + { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2} // 18 +}; + +BYTE Dist[64][256]; + +BYTE RadiusAdj[23] = {0,0,0,0,1,1,1,2,2,2,3,4,3,2,2,2,1,1,1,0,0,0,0}; + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RotateOffset(int &x, int &y, int &rx, int &ry, int &ox, int &oy, int &ax, int &ay) +{ + int tmp; + + ax = 0; + ay = 0; + + // rotate rx,ry by 90 deg. clockwise + tmp = rx; + rx = 7-ry; + ry = tmp; + + // rotate origin by 90 deg. clockwise + tmp = ox; + ox = 7-oy; + oy = tmp; + + // set x,y to rx,ry shifted relative to origin + x = rx - ox; + y = ry - oy; + + // bring them back into 0..7 range + if(x < 0) + { + x += 8; + ax = 1; + } + if(y < 0) + { + y += 8; + ay = 1; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoLighting (int nXPos, int nYPos, int nRadius, int Lnum) +{ + int LightVal; + int nCrawlX, nCrawlY; + int i, j; + int dist; + int xoff=0,yoff=0; // offset into tile, where tile is broken + // into 8x8 grid for increased distance resolution. + int rxoff, ryoff; // rotated offsets + int orgx=0, orgy=0; + int addx=0, addy=0; + int dtab; + int maxleft,maxright,maxup,maxdown; // clipping vars: offsets from nXPos,nYpos; absolute vals + + if(Lnum >= 0) + { + xoff = LightList[Lnum]._xoff; + yoff = LightList[Lnum]._yoff; + + if(xoff < 0) + { + xoff += 8; + nXPos--; + } + if(yoff < 0) + { + yoff += 8; + nYPos--; + } + } + rxoff = xoff; + ryoff = yoff; + + if((nXPos - 15) < 0) + maxleft = nXPos + 1; + else + maxleft = 15; + if((nXPos + 15) > MAXDUNX) + maxright = MAXDUNX - nXPos; + else + maxright = 15; + if((nYPos - 15) < 0) + maxup = nYPos + 1; + else + maxup = 15; + if((nYPos + 15) > MAXDUNY) + maxdown = MAXDUNY - nYPos; + else + maxdown = 15; + + if (currlevel < HIVESTART) + dLight[nXPos][nYPos] = 0; + else + if(dLight[nXPos][nYPos] > LightLvls[nRadius][0]) + dLight[nXPos][nYPos] = LightLvls[nRadius][0]; + + + // Quadrant 1 + // |x + // --- + // | + dtab = xoff + 8*yoff; + + for (j = 0; j < maxup; j++) + { + for (i = 1; i < maxright; i++) + { + dist = Dist[dtab][i+j*16]; + if(dist < 128) + { + nCrawlX = nXPos + i; + nCrawlY = nYPos + j; + LightVal = LightLvls[nRadius][dist]; + if(LightVal < dLight[nCrawlX][nCrawlY]) + dLight[nCrawlX][nCrawlY] = LightVal; + } + } + } + + // Quadrant 2 + // | + // --- + // |x + + RotateOffset(xoff,yoff, rxoff,ryoff, orgx,orgy, addx,addy); + dtab = xoff + 8*yoff; + for (j = 0; j < maxdown; j++) + { + for (i = 1; i < maxright; i++) + { + dist = Dist[dtab][(i+addx)+(j+addy)*16]; + if(dist < 128) + { + nCrawlX = nXPos + j; + nCrawlY = nYPos - i; + LightVal = LightLvls[nRadius][dist]; + if(LightVal < dLight[nCrawlX][nCrawlY]) + dLight[nCrawlX][nCrawlY] = LightVal; + } + } + } + + // Quadrant 3 + // | + // --- + // x| + RotateOffset(xoff,yoff, rxoff,ryoff, orgx,orgy, addx,addy); + dtab = xoff + 8*yoff; + for (j = 0; j < maxdown; j++) + { + for (i = 1; i < maxleft; i++) + { + dist = Dist[dtab][(i+addx)+(j+addy)*16]; + if(dist < 128) + { + nCrawlX = nXPos - i; + nCrawlY = nYPos - j; + LightVal = LightLvls[nRadius][dist]; + if(LightVal < dLight[nCrawlX][nCrawlY]) + dLight[nCrawlX][nCrawlY] = LightVal; + } + } + } + + // Quadrant 4 + // x| + // --- + // | + RotateOffset(xoff,yoff, rxoff,ryoff, orgx,orgy, addx,addy); + dtab = xoff + 8*yoff; + for (j = 0; j < maxup; j++) + { + for (i = 1; i < maxleft; i++) + { + dist = Dist[dtab][(i+addx)+(j+addy)*16]; + if(dist < 128) + { + nCrawlX = nXPos - j; + nCrawlY = nYPos + i; + LightVal = LightLvls[nRadius][dist]; + if(LightVal < dLight[nCrawlX][nCrawlY]) + dLight[nCrawlX][nCrawlY] = LightVal; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoUnLight (int nXPos, int nYPos, int nRadius) +{ + int i, j; + int x1,y1,x2,y2; + + nRadius++; + y1 = nYPos - nRadius; + y2 = nYPos + nRadius; + x1 = nXPos - nRadius; + x2 = nXPos + nRadius; + if (y1 < 0) y1 = 0; + if (y2 > DMAXY) y2 = DMAXY; + if (x1 < 0) x1 = 0; + if (x2 > DMAXX) x2 = DMAXX; + for (j = y1; j < y2; j++) { + for (i = x1; i < x2; i++) dLight[i][j] = dSaveLight[i][j]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoUnVision (int nXPos, int nYPos, int nRadius) +{ + int i, j; + int x1,y1,x2,y2; + + nRadius++; + y1 = nYPos - nRadius; + y2 = nYPos + nRadius; + x1 = nXPos - nRadius; + x2 = nXPos + nRadius; + if (y1 < 0) y1 = 0; + if (y2 > DMAXY) y2 = DMAXY; + if (x1 < 0) x1 = 0; + if (x2 > DMAXX) x2 = DMAXX; + for (i = x1; i < x2; i++) { + for (j = y1; j < y2; j++) dFlags[i][j] &= ~(BFLAG_VISIBLE | BFLAG_MONSTACTIVE); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoVision (int nXPos, int nYPos, int nRadius, BOOL doautomap, BOOL visible) +{ + int nCrawlX, nCrawlY, nLineLen; + int nBlockerFlag; + int i, j, k, v; + int x1adj, x2adj, y1adj, y2adj; + + // handle origin separately. Why? I don't know. + if (nXPos >= 0 && nXPos <= DMAXX && nYPos >= 0 && nYPos <= DMAXY) { + if (doautomap) { + if (dFlags[nXPos][nYPos] >= 0) SetAutomapView(nXPos, nXPos); + dFlags[nXPos][nYPos] |= BFLAG_AUTOMAP; + } + if (visible) + dFlags[nXPos][nYPos] |= BFLAG_VISIBLE; + dFlags[nXPos][nYPos] |= BFLAG_MONSTACTIVE; + } + + for (k = 0; k < 4; k ++) { + for (j = 0; j < 23; j ++) { + + nBlockerFlag = 0; + nLineLen = (nRadius - RadiusAdj[j]) << 1; + + for (i = 0; i < nLineLen && !nBlockerFlag; i += 2) { + x1adj = 0; + x2adj = 0; + y1adj = 0; + y2adj = 0; + + switch (k) { + case 0: + nCrawlX = nXPos + vCrawlTable[j][i]; + nCrawlY = nYPos + vCrawlTable[j][i + 1]; + if (vCrawlTable[j][i] > 0 && vCrawlTable[j][i+1] > 0) { + x1adj = -1; + y2adj = -1; + } + break; + case 1: + nCrawlX = nXPos - vCrawlTable[j][i]; + nCrawlY = nYPos - vCrawlTable[j][i + 1]; + if ((vCrawlTable[j][i] > 0) && (vCrawlTable[j][i+1] > 0)) { + y1adj = 1; + x2adj = 1; + } + break; + case 2: + nCrawlX = nXPos + vCrawlTable[j][i]; + nCrawlY = nYPos - vCrawlTable[j][i + 1]; + if (vCrawlTable[j][i] > 0 && vCrawlTable[j][i+1] > 0) { + x1adj = -1; + y2adj = 1; + } + break; + case 3: + nCrawlX = nXPos - vCrawlTable[j][i]; + nCrawlY = nYPos + vCrawlTable[j][i + 1]; + if (vCrawlTable[j][i] > 0 && vCrawlTable[j][i+1] > 0) { + y1adj = -1; + x2adj = 1; + } + break; + } + + if (nCrawlX >= 0 && nCrawlX <= DMAXX && nCrawlY >= 0 && nCrawlY <= DMAXY) { + + nBlockerFlag = nBlockTable[dPiece[nCrawlX][nCrawlY]]; + + if (!nBlockTable[dPiece[nCrawlX + x1adj][nCrawlY + y1adj]] + || !nBlockTable[dPiece[nCrawlX + x2adj][nCrawlY + y2adj]]) { + if (doautomap) { + if (dFlags[nCrawlX][nCrawlY] >= 0) SetAutomapView(nCrawlX, nCrawlY); + dFlags[nCrawlX][nCrawlY] |= BFLAG_AUTOMAP; + } + if (visible) + dFlags[nCrawlX][nCrawlY] |= BFLAG_VISIBLE; + + dFlags[nCrawlX][nCrawlY] |= BFLAG_MONSTACTIVE; + if (!nBlockerFlag) { + v = dTransVal[nCrawlX][nCrawlY]; + if (v != 0) TransList[v] = TRUE; + } + } + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FreeLightTable() { + DiabloFreePtr(pLightTbl); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitLightTable() +{ + // Palettes for 16 light values + app_assert(! pLightTbl); + pLightTbl = DiabloAllocPtrSig(LIGHTSIZE,'LGTt'); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void MakeLightTable() +{ + int i,j,k,idx,tlen; + BYTE ev,sv; + BYTE *InfraTemp; + BYTE *itp, *pLT; + int x,y; + int rad; + int d; + int a,b; + double ftmp, radiusmod; + + // Palettes for 16 light values + pLT = pLightTbl; + + idx = 0; + if (light4flag) tlen = 3; + else tlen = 15; + for (i = 0; i < tlen; i++) { + *pLT++ = 0; + for (j = 0; j < 8; j++) { + sv = idx + (j * 16); + ev = 15 + (j * 16); + for (k = 0; k < 16; k++) { + if ((k != 0) || (j != 0)) *pLT++ = sv; + if (sv < ev) sv++; + else sv = ev = 0; + } + } + for (j = 16; j < 20; j++) { + sv = (idx >> 1) + (j * 8); + ev = 7 + (j * 8); + for (k = 0; k < 8; k++) { + *pLT++ = sv; + if (sv < ev) sv++; + else sv = ev = 0; + } + } + for (j = 10; j < 16; j++) { + sv = idx + (j * 16); + ev = 15 + (j * 16); + for (k = 0; k < 16; k++) { + *pLT++ = sv; + if (sv < ev) sv++; + else sv = ev = 0; + if (sv == 255) sv = ev = 0; + } + } + if (light4flag) idx += 5; + else idx++; + } + for (j = 0; j < 256; j++) + *pLT++ = 0; + + + // Init fading for blood + if (leveltype == 4) { + byte bloodfadehold[16]; + pLT = pLightTbl; + for (i = 0; i < tlen; i++) { + int d = tlen - i; + int a = tlen / d; + int r = tlen % d; + int tr = d; + int ta = 0; + sv = 1; + bloodfadehold[0] = 0; + for (k = 1; k < 16; k++) { + bloodfadehold[k] = sv; + tr += r; + if ((tr > d) && (k < 15)) { + k++; + tr -= d; + bloodfadehold[k] = sv; + } + ta++; + if (ta == a) { + sv++; + ta = 0; + } + } + *pLT++ = 0; + for (k = 1; k < 16; k++) *pLT++ = bloodfadehold[k]; + for (k = 15; k > 0; k--) *pLT++ = bloodfadehold[k]; + *pLT = 1; + pLT += 225; + } + *pLT++ = 0; + for (j = 1; j < 32; j++) *pLT++ = 1; + pLT += 224; + } + if (currlevel >= HIVESTART) { + pLT = pLightTbl; + for (i = 0; i < tlen; i++) + { + *pLT++ = 0; +// for (j = 1; j < 9; j++) // 16 is the number of rotated colors. JKE + for (j = 1; j < 16; j++) + *pLT++ = j; +// pLT += 247; + pLT += 240; + } + *pLT++ = 0; + for (j = 1; j < 16; j++) *pLT++ = 1; + pLT += 240; + + } + + // Load infra vision table + InfraTemp = LoadFileInMemSig("PlrGFX\\Infra.TRN",NULL,'LGTt'); + itp = InfraTemp; + for (j = 0; j < 256; j++) *pLT++ = *itp++; + DiabloFreePtr(InfraTemp); + + // Load stone curse table + InfraTemp = LoadFileInMemSig("PlrGFX\\Stone.TRN",NULL,'LGTt'); + itp = InfraTemp; + for (j = 0; j < 256; j++) *pLT++ = *itp++; + DiabloFreePtr(InfraTemp); + + // Create pause table + for (j = 0; j < 8; j++) { + for (sv = PAUSEBANDS+2; sv < PAUSEBANDE; sv++) { + if ((j == 0) && (sv == PAUSEBANDS+2)) *pLT++ = 0; + else *pLT++ = sv; + } + *pLT++ = 0; + *pLT++ = 0; + *pLT++ = 0; + } + for (j = 0; j < 4; j++) { + sv = PAUSEBANDS; + for (i = PAUSEBANDS; i < PAUSEBANDE; i+=2) { + *pLT++ = sv; + sv += 2; + } + } + for (j = 0; j < 6; j++) { + for (sv = PAUSEBANDS; sv < PAUSEBANDE; sv++) *pLT++ = sv; + *pLT++ = 0; + } + + // Doron's new smooth light tables + for(rad = 0; rad < 16; rad++) + { + for(i = 0; i < 128; i++) + { + if(i > 8*(rad+1)) + LightLvls[rad][i] = 15; + else + { + ftmp = (double)15*i/((double)8*(rad+1)); + // round + LightLvls[rad][i] = (BYTE)(ftmp + 0.5); + } + } + } +// if (currlevel >= HIVESTART && currlevel < CRYPTSTART) + if (currlevel >= HIVESTART) + { + for(rad = 0; rad < 16; rad++) // avoid divide by zero + { + radiusmod = (sqrt((double)(16 - rad)))/128.0; + radiusmod *= radiusmod; + for(i = 0; i < 128; i++) + { + LightLvls[15-rad][i] = 15 - (BYTE)(radiusmod * (double)((128 - i) * (128 - i))); + if (LightLvls[15-rad][i] > 15) + LightLvls[15-rad][i] = 0; + LightLvls[15-rad][i] = LightLvls[15-rad][i] - (BYTE)((15-rad)/2); + if (LightLvls[15-rad][i] > 15) + LightLvls[15-rad][i] = 0; + } + } + } + // Distance Table + for(j = 0; j < 8; j++) + { + for(i = 0; i < 8; i++) + { + d = i + j*8; + for(y = 0; y < 16; y++) + { + for(x = 0; x < 16; x++) + { + a = (x<<3)-i; + b = (y<<3)-j; + ftmp = (BYTE)sqrt((double)(a*a + b*b)); + // round + ftmp += (ftmp < 0) ? -0.5:0.5; + + Dist[d][x+16*y] = (BYTE)ftmp; + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ResetLight () +{ + if (lightflag == 0) { + FillMemory(dLight,sizeof(dLight),lightmax); + for (int i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (currlevel != plr[i].plrlevel) continue; + DoLighting(plr[i]._px, plr[i]._py, plr[i]._pLightRad, -1); + } + } + else { + ZeroMemory(dLight,sizeof(dLight)); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ToggleLight () +{ + lightflag ^= 1; + if (lightflag == 0) { + CopyMemory(dLight,dSaveLight,sizeof(dLight)); + for (int i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (currlevel != plr[i].plrlevel) continue; + DoLighting(plr[i]._px, plr[i]._py, plr[i]._pLightRad, -1); + } + } + else { + ZeroMemory(dLight,sizeof(dLight)); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitLightMax() +{ + if (light4flag) lightmax = 3; + else lightmax = 15; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitLighting() +{ + int i; + + numlights = 0; + dolighting = FALSE; + lightflag = 0; + for(i = 0; i < MAXLIGHTS; i++) + lightactive[i] = i; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int AddLight(int x, int y, int r) +{ + int lid; + + if (lightflag != 0) return(-1); + lid = -1; + if (numlights < MAXLIGHTS) { + lid = lightactive[numlights++]; + LightList[lid]._lx = x; + LightList[lid]._ly = y; + LightList[lid]._lradius = r; + LightList[lid]._xoff = 0; + LightList[lid]._yoff = 0; + LightList[lid]._ldel = FALSE; + LightList[lid]._lunflag = FALSE; + dolighting = TRUE; + } + return(lid); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddUnLight(int i) +{ + if (lightflag != 0) return; + if (i == -1) return; + + LightList[i]._ldel = TRUE; + dolighting = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ChangeLightRadius(int i, int r) +{ + if (lightflag != 0) return; + if (i == -1) return; + + LightList[i]._lunflag = TRUE; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lradius = r; + dolighting = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ChangeLightXY(int i, int x, int y) +{ + if (lightflag != 0) return; + if (i == -1) return; + + LightList[i]._lunflag = TRUE; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lx = x; + LightList[i]._ly = y; + dolighting = TRUE; +} + +/*-----------------------------------------------------------------------* + * + * ChangeLightOff + * + * For increased lighting effect, we specify a position (-8..8,-8..8) + * within each dungeon grid coordinate. This is _xoff and _yoff. +**-----------------------------------------------------------------------*/ +void ChangeLightOff(int i, int x, int y) +{ + if (lightflag != 0) return; + if (i == -1) return; + + LightList[i]._lunflag = TRUE; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._xoff = x; + LightList[i]._yoff = y; + dolighting = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ChangeLight(int i, int x, int y, int r) +{ + if (lightflag != 0) return; + if (i == -1) return; + + LightList[i]._lunflag = TRUE; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lx = x; + LightList[i]._ly = y; + LightList[i]._lradius = r; + dolighting = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ProcessLightList() +{ + int i,j; + BYTE temp; + + if (lightflag != 0) return; + if (dolighting) { + for (j = 0; j < numlights; j++) { + i = lightactive[j]; + if (LightList[i]._ldel) DoUnLight(LightList[i]._lx, LightList[i]._ly, LightList[i]._lradius); + if (LightList[i]._lunflag) { + DoUnLight(LightList[i]._lunx, LightList[i]._luny, LightList[i]._lunr); + LightList[i]._lunflag = FALSE; + } + } + for (j = 0; j < numlights; j++) { + i = lightactive[j]; + if (!LightList[i]._ldel) + { + DoLighting(LightList[i]._lx, LightList[i]._ly, LightList[i]._lradius, i); + } + } + for (j = 0; j < numlights; ) { + i = lightactive[j]; + if (LightList[i]._ldel) { + temp = lightactive[--numlights]; + lightactive[numlights] = lightactive[j]; + lightactive[j] = temp; + } + else + j++; + } + } + dolighting = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SavePreLighting() +{ + CopyMemory(dSaveLight,dLight,sizeof(dSaveLight)); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitVision() +{ + int i; + + numvision = 0; + dovision = FALSE; + visionid = 1; + + for (i = 0; i < TransVal; i++) TransList[i] = FALSE; + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int AddVision(int x, int y, int r, BOOL mine) +{ + int vid; + + //if (lightflag != 0) return(-1); + if (numvision < MAXVISION) { + VisionList[numvision]._lx = x; + VisionList[numvision]._ly = y; + VisionList[numvision]._lradius = r; + vid = visionid++; + VisionList[numvision]._lid = vid; + VisionList[numvision]._ldel = FALSE; + VisionList[numvision]._lunflag = FALSE; + VisionList[numvision]._lflags = mine ? LFLAG_MINE : 0; + numvision++; + dovision = TRUE; + } + return(vid); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddUnVision(int id) +{ + int i; + + //if (lightflag != 0) return; + for (i = 0; i < numvision; i++) { + if (VisionList[i]._lid == id) { + VisionList[i]._ldel = TRUE; + dovision = TRUE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ChangeVisionRadius(int id, int r) +{ + int i; + + //if (lightflag != 0) return; + for (i = 0; i < numvision; i++) { + if (VisionList[i]._lid == id) { + VisionList[i]._lunflag = TRUE; + VisionList[i]._lunx = VisionList[i]._lx; + VisionList[i]._luny = VisionList[i]._ly; + VisionList[i]._lunr = VisionList[i]._lradius; + VisionList[i]._lradius = r; + dovision = TRUE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ChangeVisionXY(int id, int x, int y) +{ + int i; + + //if (lightflag != 0) return; + for (i = 0; i < numvision; i++) { + if (VisionList[i]._lid == id) { + VisionList[i]._lunflag = TRUE; + VisionList[i]._lunx = VisionList[i]._lx; + VisionList[i]._luny = VisionList[i]._ly; + VisionList[i]._lunr = VisionList[i]._lradius; + VisionList[i]._lx = x; + VisionList[i]._ly = y; + dovision = TRUE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ChangeVision(int id, int x, int y, int r) +{ + int i; + + //if (lightflag != 0) return; + for (i = 0; i < numvision; i++) { + if (VisionList[i]._lid == id) { + VisionList[i]._lunflag = TRUE; + VisionList[i]._lunx = VisionList[i]._lx; + VisionList[i]._luny = VisionList[i]._ly; + VisionList[i]._lunr = VisionList[i]._lradius; + VisionList[i]._lx = x; + VisionList[i]._ly = y; + VisionList[i]._lradius = r; + dovision = TRUE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ProcessVisionList() +{ + int i; + BOOL delflag; + + //if (lightflag != 0) return; + if (dovision) { + for (i = 0; i < numvision; i++) { + if (VisionList[i]._ldel) DoUnVision(VisionList[i]._lx, VisionList[i]._ly, VisionList[i]._lradius); + if (VisionList[i]._lunflag) { + DoUnVision(VisionList[i]._lunx, VisionList[i]._luny, VisionList[i]._lunr); + VisionList[i]._lunflag = FALSE; + } + } + for (i = 0; i < TransVal; i++) TransList[i] = FALSE; + for (i = 0; i < numvision; i++) + if (!VisionList[i]._ldel) + DoVision(VisionList[i]._lx, VisionList[i]._ly, VisionList[i]._lradius, + VisionList[i]._lflags & LFLAG_MINE, VisionList[i]._lflags & LFLAG_MINE); + do { + delflag = FALSE; + for (i = 0; i < numvision; i++) { + if (VisionList[i]._ldel) { + numvision--; + if ((numvision > 0) && (i != numvision)) VisionList[i] = VisionList[numvision]; + delflag = TRUE; + } + } + } while (delflag); + } + dovision = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void BloodCycle() +{ + int i,k,tlen; + BYTE h; + BYTE *pLT; + + // Cycle the blood + pLT = pLightTbl; + if (light4flag) tlen = 4; + else tlen = 16; + if (leveltype == 4) { + pLT = pLightTbl; + for (i = 0; i < tlen; i++) { + pLT++; + h = *pLT; + for (k = 0; k < 30; k++) { + *pLT = *(pLT+1); + *pLT++; + } + *pLT = h; + pLT += 225; + } + } +} diff --git a/LIGHTING.H b/LIGHTING.H new file mode 100644 index 0000000..a017b1b --- /dev/null +++ b/LIGHTING.H @@ -0,0 +1,132 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/LIGHTING.H 1 1/22/97 2:06p Dgartner $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define LIGHTSIZE 27*256 + +#define MAXLIGHTS 32 +#define MAXVISION 32 +#define MAXTRANS 32 + +#define PLRLRAD 10 // Player light radius +#define PLRVRAD 10 // Player vision radius + +#define HALF_T 1 +#define HALF_B 2 +#define HALF_R 3 +#define HALF_L 4 +#define QTR_UR 5 +#define QTR_LR 6 +#define QTR_UL 7 +#define QTR_LL 8 +#define VERT_T 9 +#define VERT_B 10 +#define VERT_LINE 11 +#define HORT_L 12 +#define HORT_R 13 +#define HORT_LINE 14 +#define SELF 15 +#define WHOLE 16 +#define NEG_WHOLE 17 + +#define LIGHT_NORM 0 // Normal lighting +#define LIGHT_INFRA 1 // Infravision +#define LIGHT_STONE 2 // Stone curse +#define LIGHT_GREY 3 // Pause & death +#define LIGHT_U 4 // Unique monster transform 3-11 + +#define LFLAG_MINE 1 // whether or not my player is the source + // (used in ProcessVision) + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + int _lx; + int _ly; + int _lradius; + int _lid; + BOOL _ldel; + BOOL _lunflag; + BOOL _lneg; + int _lunx; + int _luny; + int _lunr; + int _xoff; + int _yoff; + BOOL _lflags; +} LightListStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern int lightflag; +extern BYTE vCrawlTable[23][30]; +extern BYTE RadiusAdj[23]; +//extern int CrawlTable[2061]; +extern char CrawlTable[2749]; +extern char * pCrawlEntry[19]; + +extern LightListStruct LightList[MAXLIGHTS]; +extern BYTE lightactive[MAXLIGHTS]; +extern int numlights; +extern BOOL dolighting; +extern "C" { + extern char lightmax; + extern BYTE *pLightTbl; +} +extern LightListStruct VisionList[MAXVISION]; +extern int numvision; +extern BOOL dovision; +extern int visionid; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void DoLighting (int, int, int, int); +void DoUnLight (int, int, int); + +void InitLighting(); +void InitLightMax(); +int AddLight(int, int, int); +void AddUnLight(int); +void ChangeLightRadius(int, int); +void ChangeLightXY(int, int, int); +void ChangeLight(int, int, int, int); +void ChangeLightOff(int id, int x, int y); +void ProcessLightList(); + +void SavePreLighting(); + +void DoVision (int, int, int, BOOL, BOOL); +void DoUnVision (int, int, int); + +void InitVision(); +int AddVision(int, int, int, BOOL); +void AddUnVision(int); +void ChangeVisionRadius(int, int); +void ChangeVisionXY(int, int, int); +void ChangeVision(int, int, int, int); +void ProcessVisionList(); + +void ResetLight(); +void ToggleLight(); + +void InitLightTable(); +void MakeLightTable(); +void FreeLightTable(); + +void BloodCycle(); diff --git a/LOADSAVE.CPP b/LOADSAVE.CPP new file mode 100644 index 0000000..eefb76f --- /dev/null +++ b/LOADSAVE.CPP @@ -0,0 +1,768 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Game Menu file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/LOADSAVE.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include +#include "sound.h" +#include "engine.h" +#include "gendung.h" +#include "palette.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "dead.h" +#include "objects.h" +#include "spells.h" +#include "missiles.h" +#include "quests.h" +#include "trigs.h" +#include "lighting.h" +#include "control.h" +#include "inv.h" +#include "interfac.h" +#include "town.h" +#include "stores.h" +#include "cursor.h" +#include "automap.h" +#include "multi.h" +#include "doom.h" +#include "portal.h" + +/*-----------------------------------------------------------------------* +** extern +**-----------------------------------------------------------------------*/ +DWORD CalcEncodeDstBytes(DWORD dwSrcBytes); +void CreateSaveLevelName(char szName[MAX_PATH]); +void CreateLoadLevelName(char szName[MAX_PATH]); +void CreateSaveGameName(char szName[MAX_PATH]); +void WriteSaveFile(const char * pszName,BYTE * pbData,DWORD dwLen,DWORD dwEncodeLen); +BYTE * ReadSaveFile(const char * pszName,DWORD * pdwLen); +void SyncPlrAnim(int); +void DestroyTempSaves(); +void MoveTempSavesToPermanent(); +void RedoPlayerVision(); + + +/*-----------------------------------------------------------------------* +** private +**-----------------------------------------------------------------------*/ +// Save only these bits in the dFlags +#define BFLAG_SAVEMASK (BFLAG_AUTOMAP | BFLAG_VISIBLE | BFLAG_PLRLR | BFLAG_MONSTLR | BFLAG_SETPC) + +// save file buffer size +#define FILEBUFF 362147 + +// pointer into save file buffer +static BYTE *tbuff; + +#define SHAREWARE_ID 'SHAR' +#define BETA_ID 'BETA' +#define RETAIL_ID 'RETL' +#define HELLFIRE_ID 'HELF' + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static char BLoad() { + return *tbuff++; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int ILoad() { + int rv; + // drb old because we used to think ints were 16 bit +/* if ((*tbuff & 0x80) != 0) rv = -1 & 0xffff0000; + else rv = 0; + rv |= *tbuff++ << 8; + rv |= *tbuff++;*/ + rv = *tbuff++ << 24; + rv |= *tbuff++ << 16; + rv |= *tbuff++ << 8; + rv |= *tbuff++; + return(rv); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static long LLoad() { + long rv; + + rv = *tbuff++ << 24; + rv |= *tbuff++ << 16; + rv |= *tbuff++ << 8; + rv |= *tbuff++; + return(rv); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL OLoad() { + if (*tbuff++ == 1) return(TRUE); + else return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadPlr(int i) { + memcpy(&plr[i], tbuff, SAVE_PLAYER_SIZE); + tbuff += SAVE_PLAYER_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadMonst(int i) { + memcpy(&monster[i], tbuff, SAVE_MONSTER_SIZE); + tbuff += SAVE_MONSTER_SIZE; + SyncMonsterAnim(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadMissile(int i) { + memcpy(&missile[i], tbuff, SAVE_MISSILE_SIZE); + tbuff += SAVE_MISSILE_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadSpell(int i) { + tbuff += 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadObject(int i) { + memcpy(&object[i], tbuff, SAVE_OBJECT_SIZE); + tbuff += SAVE_OBJECT_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadItem(int i) { + memcpy(&item[i], tbuff, SAVE_ITEM_SIZE); + tbuff += SAVE_ITEM_SIZE; + SyncItemAnim(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadPremium(int i) { + memcpy(&premiumitem[i], tbuff, SAVE_ITEM_SIZE); + tbuff += SAVE_ITEM_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadQuest(int i) { + memcpy(&quests[i], tbuff, SAVE_QUEST_SIZE); + tbuff += SAVE_QUEST_SIZE; + + // where to go back to + ReturnLvlX = ILoad(); + ReturnLvlY = ILoad(); + ReturnLvl = ILoad(); + ReturnLvlT = ILoad(); + + // Map of doom + doomtime = ILoad(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadLight(int i) { + memcpy(&LightList[i], tbuff, sizeof(LightListStruct)); + tbuff += sizeof(LightListStruct); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadVision(int i) { + memcpy(&VisionList[i], tbuff, sizeof(LightListStruct)); + tbuff += sizeof(LightListStruct); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void LoadPortal(int i) { + memcpy(&portal[i], tbuff, sizeof(PortalStruct)); + tbuff += sizeof(PortalStruct); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GM_LoadGame(BOOL firstflag) { +#if !IS_VERSION(BETA) + int i,j; + int hvx, hvy; + int hnummonsters, hnumitems, hnummissiles, hnumobjects; + + app_assert(gbMaxPlayers == 1); + FreeGameMem(); + + // since we are loading an existing game, any temporary + // save files which were created can be removed + DestroyTempSaves(); + + DWORD dwLen; + char szName[MAX_PATH]; + CreateSaveGameName(szName); + BYTE *LoadBuff = ReadSaveFile(szName,&dwLen); + tbuff = LoadBuff; + + DWORD dwVersion = LLoad(); + #if IS_VERSION(SHAREWARE) + if (dwVersion != SHAREWARE_ID) app_fatal("Invalid save file"); + #elif IS_VERSION(BETA) + if (dwVersion != BETA_ID) app_fatal("Invalid save file"); + #elif IS_VERSION(RETAIL) + //if (dwVersion != RETAIL_ID) app_fatal("Invalid save file"); + if (dwVersion != HELLFIRE_ID) app_fatal("Invalid save file"); + #else + #error No version defined + #endif + + setlevel = OLoad(); + setlvlnum = ILoad(); + currlevel = ILoad(); + leveltype = ILoad(); + hvx = ILoad(); + hvy = ILoad(); + invflag = OLoad(); + chrflag = OLoad(); + hnummonsters = ILoad(); + hnumitems = ILoad(); + hnummissiles = ILoad(); + hnumobjects = ILoad(); + + for (i = 0; i < NUMLEVELS; i++) { + glSeedTbl[i] = LLoad(); + gnLevelTypeTbl[i] = ILoad(); + } + + // Load player info + LoadPlr(myplr); + gnDifficulty = plr[myplr]._gnDifficulty; + if (gnDifficulty < D_NORMAL || gnDifficulty > D_HELL) + gnDifficulty = D_NORMAL; + + // Load quest info + for (i = 0; i < MAXQUESTS; i++) LoadQuest(i); + + // Load town portal info + for (i = 0; i < MAXPORTAL; i++) LoadPortal(i); + + LoadGameLevel(firstflag, LVL_NODIR); + + SyncInitPlr(myplr); + SyncPlrAnim(myplr); + + ViewX = hvx; + ViewY = hvy; + nummonsters = hnummonsters; + numitems = hnumitems; + nummissiles = hnummissiles; + numobjects = hnumobjects; + + for (i = 0; i < MONSTERTYPES; i++) monstkills[i] = LLoad(); + + if (leveltype != 0) { + // Load monster block + for (i = 0; i < MAXMONSTERS; i++) monstactive[i] = ILoad(); + for (i = 0; i < nummonsters; i++) LoadMonst(monstactive[i]); + // Load missile block + for (i = 0; i < MAXMISSILES; i++) missileactive[i] = BLoad(); + for (i = 0; i < MAXMISSILES; i++) missileavail[i] = BLoad(); + for (i = 0; i < nummissiles; i++) LoadMissile(missileactive[i]); + // Load object block + for (i = 0; i < MAXOBJECTS; i++) objectactive[i] = BLoad(); + for (i = 0; i < MAXOBJECTS; i++) objectavail[i] = BLoad(); + for (i = 0; i < numobjects; i++) LoadObject(objectactive[i]); + for (i = 0; i < numobjects; i++) SyncObjectAnim(objectactive[i]); + // Load light and vision + numlights = ILoad(); + for (i = 0; i < MAXLIGHTS; i++) lightactive[i] = BLoad(); + for (i = 0; i < numlights; i++) LoadLight(lightactive[i]); + visionid = ILoad(); + numvision = ILoad(); + for (i = 0; i < numvision; i++) LoadVision(i); + } + // Load item block + for (i = 0; i < MAXITEMS; i++) itemactive[i] = BLoad(); + for (i = 0; i < MAXITEMS; i++) itemavail[i] = BLoad(); + for (i = 0; i < numitems; i++) LoadItem(itemactive[i]); + for (i = 0; i < MAXUITEMS; i++) UniqueItemFlag[i] = OLoad(); + + // Load map info + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dLight[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dFlags[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dPlayer[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dItem[i][j] = BLoad(); + + if (leveltype != 0) { + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dMonster[i][j] = ILoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dDead[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dObject[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dLight[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dSaveLight[i][j] = BLoad(); + for (j = 0; j < AUTOMAPY; j++) + for (i = 0; i < AUTOMAPX; i++) automapview[i][j] = OLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dMissile[i][j] = BLoad(); + } + + numpremium = ILoad(); + premiumlevel = ILoad(); + for (i = 0; i < MAXPREMIUM; i++) LoadPremium(i); + + automapflag = OLoad(); + automapscale = ILoad(); + + DiabloFreePtr(LoadBuff); + + // Misc sync routines + SyncAutomap(); + ResyncQuests(); + if (leveltype) + ProcessLightList(); + RedoPlayerVision(); + ProcessVisionList(); + SyncMissAnim(); + + ResetPal(); + SetCursor(GLOVE_CURS); + gbProcessPlayers = TRUE; +#endif +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void BSave(char v) { + *tbuff++ = v; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void ISave(int v) { + // Changed because we used to thing ints were 16 bit, but they are 32 +/* *tbuff++ = (char) (v >> 8); + *tbuff++ = (char) v;*/ + *tbuff++ = (char) (v >> 24); + *tbuff++ = (char) (v >> 16); + *tbuff++ = (char) (v >> 8); + *tbuff++ = (char) (v >> 0); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void LSave(long v) { + *tbuff++ = (char) (v >> 24); + *tbuff++ = (char) (v >> 16); + *tbuff++ = (char) (v >> 8); + *tbuff++ = (char) (v >> 0); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void OSave(BOOL v) { + if (v) *tbuff++ = 1; + else *tbuff++ = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SavePlr(int i) { + memcpy(tbuff, &plr[i], SAVE_PLAYER_SIZE); + tbuff += SAVE_PLAYER_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveMonst(int i) { + memcpy(tbuff, &monster[i], SAVE_MONSTER_SIZE); + tbuff += SAVE_MONSTER_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveMissile(int i) { + memcpy(tbuff, &missile[i], SAVE_MISSILE_SIZE); + tbuff += SAVE_MISSILE_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveSpell(int i) { + tbuff += 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveObject(int i) { + memcpy(tbuff, &object[i], SAVE_OBJECT_SIZE); + tbuff += SAVE_OBJECT_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveItem(int i) { + memcpy(tbuff, &item[i], SAVE_ITEM_SIZE); + tbuff += SAVE_ITEM_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SavePremium(int i) { + memcpy(tbuff, &premiumitem[i], SAVE_ITEM_SIZE); + tbuff += SAVE_ITEM_SIZE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveQuest(int i) { + memcpy(tbuff, &quests[i], SAVE_QUEST_SIZE); + tbuff += SAVE_QUEST_SIZE; + ISave(ReturnLvlX); + ISave(ReturnLvlY); + ISave(ReturnLvl); + ISave(ReturnLvlT); + ISave(doomtime); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveLight(int i) { + memcpy(tbuff, &LightList[i], sizeof(LightListStruct)); + tbuff += sizeof(LightListStruct); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SaveVision(int i) { + memcpy(tbuff, &VisionList[i], sizeof(LightListStruct)); + tbuff += sizeof(LightListStruct); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void SavePortal(int i) { + memcpy(tbuff, &portal[i], sizeof(PortalStruct)); + tbuff += sizeof(PortalStruct); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GM_SaveGame() { +#if !IS_VERSION(BETA) + BYTE *SaveBuff; + int i,j; + + // allocate a ptr large enough for save file + encode data + app_assert(gbMaxPlayers == 1); + SaveBuff = DiabloAllocPtrSig(CalcEncodeDstBytes(FILEBUFF),'SAVt'); + tbuff = SaveBuff; + + #if IS_VERSION(SHAREWARE) + LSave(SHAREWARE_ID); + #elif IS_VERSION(BETA) + LSave(BETA_ID); + #elif IS_VERSION(RETAIL) + //LSave(RETAIL_ID); + LSave(HELLFIRE_ID); + #else + #error No version defined + #endif + + OSave(setlevel); + ISave(setlvlnum); + ISave(currlevel); + ISave(leveltype); + ISave(ViewX); + ISave(ViewY); + OSave(invflag); + OSave(chrflag); + ISave(nummonsters); + ISave(numitems); + ISave(nummissiles); + ISave(numobjects); + + for (i = 0; i < NUMLEVELS; i++) { + LSave(glSeedTbl[i]); + ISave(gnLevelTypeTbl[i]); + } + + // Save player info + plr[myplr]._gnDifficulty = gnDifficulty; + SavePlr(myplr); + + // Save quest info + for (i = 0; i < MAXQUESTS; i++) SaveQuest(i); + + // Save town portal info + for (i = 0; i < MAXPORTAL; i++) SavePortal(i); + + for (i = 0; i < MONSTERTYPES; i++) LSave(monstkills[i]); + + if (leveltype != 0) { + // Save monster block + for (i = 0; i < MAXMONSTERS; i++) ISave(monstactive[i]); + for (i = 0; i < nummonsters; i++) SaveMonst(monstactive[i]); + // Save missile block + for (i = 0; i < MAXMISSILES; i++) BSave(missileactive[i]); + for (i = 0; i < MAXMISSILES; i++) BSave(missileavail[i]); + for (i = 0; i < nummissiles; i++) SaveMissile(missileactive[i]); + // Save object block + for (i = 0; i < MAXOBJECTS; i++) BSave(objectactive[i]); + for (i = 0; i < MAXOBJECTS; i++) BSave(objectavail[i]); + for (i = 0; i < numobjects; i++) SaveObject(objectactive[i]); + // Save light and vision + ISave(numlights); + for (i = 0; i < MAXLIGHTS; i++) BSave(lightactive[i]); + for (i = 0; i < numlights; i++) SaveLight(lightactive[i]); + ISave(visionid); + ISave(numvision); + for (i = 0; i < numvision; i++) SaveVision(i); + } + // Save item block + for (i = 0; i < MAXITEMS; i++) BSave(itemactive[i]); + for (i = 0; i < MAXITEMS; i++) BSave(itemavail[i]); + for (i = 0; i < numitems; i++) SaveItem(itemactive[i]); + for (i = 0; i < MAXUITEMS; i++) OSave(UniqueItemFlag[i]); + + // Save map info + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dLight[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dFlags[i][j] & BFLAG_SAVEMASK); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dPlayer[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dItem[i][j]); + + if (leveltype != 0) { + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) ISave(dMonster[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dDead[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dObject[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dLight[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dSaveLight[i][j]); + for (j = 0; j < AUTOMAPY; j++) + for (i = 0; i < AUTOMAPX; i++) OSave(automapview[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dMissile[i][j]); + } + ISave(numpremium); + ISave(premiumlevel); + for (i = 0; i < MAXPREMIUM; i++) SavePremium(i); + + OSave(automapflag); + ISave(automapscale); + + char szName[MAX_PATH]; + CreateSaveGameName(szName); + + // when we allocated SaveBuff, we made sure to include enough + // bytes for the encryption information + WriteSaveFile( + szName, + SaveBuff, + tbuff - SaveBuff, + CalcEncodeDstBytes(tbuff - SaveBuff) + ); + + DiabloFreePtr(SaveBuff); + gbValidSaveFile = TRUE; + + // take all the temporary save files which have accumulated + // during the course of gameplay and make them part of the + // permanent save game + MoveTempSavesToPermanent(); + + void UpdatePlayerFile(); + UpdatePlayerFile(); +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SaveLevel() +{ +#if !IS_VERSION(BETA) + BYTE *SaveBuff; + int i,j; + + // make sure this code doesn't get called in multiplayer + // or everyone will have different results... + app_assert(gbMaxPlayers == 1); + if (currlevel == 0) glSeedTbl[0] = GetRndSeed(); + + // allocate a ptr large enough for save file + encode data + SaveBuff = DiabloAllocPtrSig(CalcEncodeDstBytes(FILEBUFF),'SAVt'); + tbuff = SaveBuff; + + // Moved here to sync dead unique monsters drb 12/15 + if (leveltype != 0) { + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dDead[i][j]); + } + + ISave(nummonsters); + ISave(numitems); + ISave(numobjects); + + if (leveltype != 0) { + // Save monster block + for (i = 0; i < MAXMONSTERS; i++) ISave(monstactive[i]); + for (i = 0; i < nummonsters; i++) SaveMonst(monstactive[i]); + // Save object block + for (i = 0; i < MAXOBJECTS; i++) BSave(objectactive[i]); + for (i = 0; i < MAXOBJECTS; i++) BSave(objectavail[i]); + for (i = 0; i < numobjects; i++) SaveObject(objectactive[i]); + } + // Save item block + for (i = 0; i < MAXITEMS; i++) BSave(itemactive[i]); + for (i = 0; i < MAXITEMS; i++) BSave(itemavail[i]); + for (i = 0; i < numitems; i++) SaveItem(itemactive[i]); + + // Save map info + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) + BSave(dFlags[i][j] & BFLAG_SAVEMASK); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dItem[i][j]); + + if (leveltype != 0) { + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) ISave(dMonster[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dObject[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dLight[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dSaveLight[i][j]); + for (j = 0; j < AUTOMAPY; j++) + for (i = 0; i < AUTOMAPX; i++) OSave(automapview[i][j]); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) BSave(dMissile[i][j]); + } + + app_assert(FILEBUFF >= tbuff - SaveBuff); + char szName[MAX_PATH]; + CreateSaveLevelName(szName); + + // when we allocated SaveBuff, we made sure to include enough + // bytes for the encryption information + WriteSaveFile( + szName, + SaveBuff, + tbuff - SaveBuff, + CalcEncodeDstBytes(tbuff - SaveBuff) + ); + + DiabloFreePtr(SaveBuff); + if (!setlevel) plr[myplr]._pLvlVisited[currlevel] = TRUE; + else plr[myplr]._pSLvlVisited[setlvlnum] = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void LoadLevel() { +#if !IS_VERSION(BETA) + int i,j; + + DWORD LoadSize; + char szName[MAX_PATH]; + CreateLoadLevelName(szName); + BYTE * LoadBuff = ReadSaveFile(szName,&LoadSize); + tbuff = LoadBuff; + + if (leveltype != 0) { + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dDead[i][j] = BLoad(); + SyncUniqDead(); + } + + nummonsters = ILoad(); + numitems = ILoad(); + numobjects = ILoad(); + + if (leveltype != 0) { + // Load monster block + for (i = 0; i < MAXMONSTERS; i++) monstactive[i] = ILoad(); + for (i = 0; i < nummonsters; i++) LoadMonst(monstactive[i]); + // Load object block + for (i = 0; i < MAXOBJECTS; i++) objectactive[i] = BLoad(); + for (i = 0; i < MAXOBJECTS; i++) objectavail[i] = BLoad(); + for (i = 0; i < numobjects; i++) LoadObject(objectactive[i]); + for (i = 0; i < numobjects; i++) SyncObjectAnim(objectactive[i]); + } + // Load item block + for (i = 0; i < MAXITEMS; i++) itemactive[i] = BLoad(); + for (i = 0; i < MAXITEMS; i++) itemavail[i] = BLoad(); + for (i = 0; i < numitems; i++) LoadItem(itemactive[i]); + + // Load map info + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dFlags[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dItem[i][j] = BLoad(); + + if (leveltype != 0) { + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dMonster[i][j] = ILoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dObject[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dLight[i][j] = BLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dSaveLight[i][j] = BLoad(); + for (j = 0; j < AUTOMAPY; j++) + for (i = 0; i < AUTOMAPX; i++) automapview[i][j] = OLoad(); + for (j = 0; j < MAXDUNY; j++) + for (i = 0; i < MAXDUNX; i++) dMissile[i][j] = 0; + } + + // Misc sync routines + SyncAutomap(); + ResyncQuests(); + SyncPortals(); + + // player lighting needs to be reset because players enter level at different + // location than where they leave + dolighting = TRUE; + for (i = 0; i < MAX_PLRS; i++) { + if (plr[i].plractive && currlevel == plr[i].plrlevel) + LightList[plr[i]._plid]._lunflag = TRUE; + } + + DiabloFreePtr(LoadBuff); +#endif +} diff --git a/MAINMENU.CPP b/MAINMENU.CPP new file mode 100644 index 0000000..c5fd04d --- /dev/null +++ b/MAINMENU.CPP @@ -0,0 +1,203 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Main Menu +** +** (C)1996 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MAINMENU.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "diabloui.h" +#include "items.h" +#include "gendung.h" +#include "player.h" +#include "multi.h" +#include "sound.h" + + +/*-----------------------------------------------------------------------** +// externs +**-----------------------------------------------------------------------*/ +extern char gszPrintVersion[]; +void CALLBACK menusnd_play(LPBYTE lpWave); +BOOL CALLBACK UiEnumHeroes(ENUMHEROPROC enumproc); +BOOL CALLBACK UiCreateHero(TPUIHEROINFO heroinfo); +BOOL CALLBACK UiDeleteHero(TPUIHEROINFO heroinfo); +BOOL CALLBACK UiGetDefaultCharStats(int heroclass, TPUIDEFSTATS defaultstats); +void CALLBACK menusnd_play(LPCSTR pszFile); +void play_movie(const char * pszMovie,BOOL bAllowCancel); +BOOL StartGame(BOOL bNewGame,BOOL bSinglePlayer); +extern DWORD gbWalkOn; +extern const char *sgszWalkId; +extern char gszProgKey[]; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define PIXELS_PER_SEC 16 + +char gszHero[MAX_NAME_LEN]; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void menu_music() { + static int snMusic = MUSIC_INTRO; + music_start(snMusic); + +#if !IS_VERSION(SHAREWARE) + // look for a music track which is not the town, cause it's + // too wimpy for initial theme music, and is not l1, cause the + // players will hear waaaay too much of l1 music + do { + snMusic++; // next track + if (snMusic == NUM_MUSIC) snMusic = 0; // handle wrap + } while (snMusic == MUSIC_TOWN || snMusic == MUSIC_L1); +#endif +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL do_menu(DWORD selection) { + if (selection == SELHERO_PREVIOUS) + return TRUE; + + music_stop(); + + BOOL bResult = StartGame( + selection != SELHERO_CONTINUE, // new game ? + selection != SELHERO_CONNECT // single player game ? + ); + + if (bResult) menu_music(); + return bResult; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL DoSinglePlayer() { + while (1) { + gbMaxPlayers = 1; + DWORD selection = 0; + + if (!SRegLoadValue( gszProgKey,sgszWalkId,0,&gbWalkOn)) + { + gbWalkOn = TRUE; + } + + if (! UiSelHeroSingDialog( + UiEnumHeroes, + UiCreateHero, + UiDeleteHero, + UiGetDefaultCharStats, + &selection, + gszHero, + &gnDifficulty, + gbAllowBard, + gbAllowBarbarian + )) app_fatal(TEXT("Unable to display SelHeroSing")); + + if (selection == SELHERO_PREVIOUS) + return TRUE; + if (! do_menu(selection)) + return FALSE; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL DoMultiPlayer() { + while (1) { + gbMaxPlayers = MAX_PLRS; + DWORD selection = 0; + gbWalkOn = FALSE; + if (! UiSelHeroMultDialog( + UiEnumHeroes, + UiCreateHero, + UiDeleteHero, + UiGetDefaultCharStats, + &selection, + gszHero, + gbAllowBard, + gbAllowBarbarian + )) app_fatal(TEXT("Can't load multiplayer dialog")); + + if (selection == SELHERO_PREVIOUS) + return TRUE; + if (! do_menu(selection)) + return FALSE; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static void play_intro() { + music_stop(); + play_movie("gendata\\Hellfire.smk",TRUE); + menu_music(); +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DiabloMenu() { + menu_music(); + + BOOL bDone = FALSE; + while (! bDone) { + DWORD selection = 0; + if (! UiMainMenuDialog(gszPrintVersion, + &selection, + gbAllowMultiPlayer, + menusnd_play)) + app_fatal(TEXT("Unable to display mainmenu")); + + switch (selection) { + case MAINMENU_SINGLE_PLAYER: + #if IS_VERSION(BETA) + app_warning("Not available in beta version"); + #else + if (! DoSinglePlayer()) bDone = TRUE; + #endif + break; + + case MAINMENU_MULTIPLAYER: + if (! DoMultiPlayer()) bDone = TRUE; + break; + + case MAINMENU_ATTRACT_MODE: + // it crashes after 20 minutes, so stop doing this. + + break; + case MAINMENU_REPLAY_INTRO: + if (! bActive) break; + #if !IS_VERSION(SHAREWARE) + play_intro(); + #endif + break; + + case MAINMENU_SHOW_CREDITS: + UiCreditsDialog(PIXELS_PER_SEC); + break; + + case MAINMENU_SUPPORT: + UiSupportDialog(PIXELS_PER_SEC); + break; + + case MAINMENU_EXIT_DIABLO: + bDone = TRUE; + break; + } + } + + music_stop(); +} diff --git a/MAINMENU.H b/MAINMENU.H new file mode 100644 index 0000000..4fe0ea3 --- /dev/null +++ b/MAINMENU.H @@ -0,0 +1,19 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1996 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/MAINMENU.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void DiabloMenu(); diff --git a/MINITEXT.CPP b/MINITEXT.CPP new file mode 100644 index 0000000..d8cc054 --- /dev/null +++ b/MINITEXT.CPP @@ -0,0 +1,287 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Miniquest Text file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "minitext.h" +#include "textdat.h" +#include "engine.h" +#include "scrollrt.h" +#include "quests.h" +#include "effects.h" +#include "items.h" +#include "gendung.h" + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define KERNSPACE 2 + +static const BYTE qfonttrans[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 37, 49, 38, 0, 39, 40, 47, 42, 43, 41, 45, 52, 44, 53, 55, // 32-47 + 36, 27, 28, 29, 30, 31, 32, 33, 34, 35, 51, 50, 48, 46, 49, 54, // 48-63 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 64-79 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 0, 43, 0, 0, // 80-95 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 96-111 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 48, 0, 49, 0, 0 }; // 112-127 + +/*char qfontkern[56] = { 8, // Space/Invalid + 24, 16, 19, 20, 15, 15, 19, 18, 8, 8, 18, 14, 24, 20, 23, 15, // a-p + 24, 20, 16, 21, 24, 25, 32, 24, 25, 18, // q-z + 8, 16, 17, 17, 16, 16, 17, 16, 16, 24, // 1-0 + 8, 15, 26, 23, 13, 9, 8, 10, 13, 12, 8, 15, 15, 8, 8, 8, 8, 16, 17 }; // misc */ + +static const BYTE qfontkern[56] = { 5, // Space/Invalid + 15, 10, 13, 14, 10, 9, 13, 11, 5, 5, 11, 10, 16, 13, 16, 10, // a-p + 15, 12, 10, 14, 17, 17, 22, 17, 16, 11, // q-z + 5, 11, 11, 11, 10, 11, 11, 11, 11, 15, // 1-0 + 5, 10, 18, 15, 8, 6, 6, 7, 10, 9, 6, 10, 10, 5, 5, 5, 5, 11, 12 }; // misc + +BYTE qtextflag; +static BYTE *pMedTextCels; +static BYTE *pTextBoxCels; +static const char *qtextptr; +static int qtexty; +int qtextSpd; +static int qtextDelay; +static DWORD sgLastScroll; + +//Quest text scrolling rate 1 = slowest, 5 = normal, 9 = fastest +int qtextDelaySpd[10] = { 2, 4, 6, 8, 0, -1, -2, -3, -4 }; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#define MQTEXTX1 112 +#define MQTEXTY1 241 +#define MQTEXTW 543 +#define MQTEXTY2 469 +#define MQTEXTNL 38 + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeQuestText() { + DiabloFreePtr(pMedTextCels); + DiabloFreePtr(pTextBoxCels); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitQuestText() { + app_assert(! pMedTextCels); + pMedTextCels = LoadFileInMemSig("Data\\MedTextS.CEL",NULL,'MINI'); + pTextBoxCels = LoadFileInMemSig("Data\\TextBox.CEL",NULL,'MINI'); + qtextflag = FALSE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitQTextMsg(int m) { + app_assert((DWORD) m < gdwAllTextEntries); + if (alltext[m].scrlltxt) + { + questlog = FALSE; + qtextflag = TRUE; + qtextptr = alltext[m].txtstr; + qtexty = MQTEXTY2 + 31; + qtextSpd = qtextDelaySpd[alltext[m].txtspd-1]; + qtextDelay = qtextSpd; + sgLastScroll = GetTickCount(); + #if CHEATS + if ((currlevel == 0) && (davecheat)) { + qtextSpd = qtextDelaySpd[tstQMsgSpd-1]; + qtextDelay = qtextSpd; + } + #endif + } + PlaySFX(alltext[m].sfxnr); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DrawQTextBack() +{ + DrawCel(88, 487, pTextBoxCels, 1, 591); + app_assert(gpBuffer); + __asm { + mov edi,dword ptr [gpBuffer] + add edi,371803 + + xor eax,eax + mov edx,148 +_YLp: mov ecx,292 +_XLp1: stosb + inc edi + loop _XLp1 + stosb + sub edi,1353 + mov ecx,292 +_XLp2: inc edi + stosb + loop _XLp2 + sub edi,1352 + dec edx + jnz _YLp + mov ecx,292 +_XLp3: stosb + inc edi + loop _XLp3 + stosb + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawQTextCel (long xp, long yp, BYTE *pCelBuff, long nCel) +{ + BYTE *pTo, *pY1, *pY2; + long RLELen; + + app_assert(gpBuffer); + pTo = gpBuffer + nBuffWTbl[yp] + xp; + pY1 = gpBuffer + nBuffWTbl[MQTEXTY1-32]; + pY2 = gpBuffer + nBuffWTbl[MQTEXTY2]; + __asm { + mov ebx,dword ptr [pCelBuff] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + + mov esi,dword ptr [pCelBuff] + add esi,dword ptr [ebx] + + mov edi,dword ptr [pTo] // Dest + + mov ebx,dword ptr [RLELen] + add ebx,esi + +_T1Lp1: mov edx,22 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [pY1] + jb _T1C + cmp edi,dword ptr [pY2] + ja _T1C + mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd + jmp _T1x +_T1C: add esi,eax + add edi,eax +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,790 + cmp ebx,esi + jnz _T1Lp1 + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawQText() +{ + const char *p, *pt, *pnl; + char tempstr[128]; + int tx, ty; + int l, i; + BOOL doneflag; + + DrawQTextBack(); + + p = qtextptr; + pnl = NULL; + tx = MQTEXTX1; + ty = qtexty; + + doneflag = FALSE; + while (!doneflag) { + l = 0; + pt = p; + for (i = 0; (*pt != '\n') && (*pt != '|') && (l < MQTEXTW); i++) { + BYTE c = char2print(*pt++); + if (c != 0) { + tempstr[i] = c; + c = qfonttrans[c]; + l += qfontkern[c] + KERNSPACE; + } else i--; + } + tempstr[i] = 0; + if (*pt == '|') { + tempstr[i] = 0; + doneflag = TRUE; + } else if (*pt == '\n') { + pt++; + } else while ((tempstr[i] != ' ') && (i > 0)) { + tempstr[i] = 0; + i--; + } + for (i = 0; tempstr[i] != 0; i++) { + BYTE c = char2print(tempstr[i]); + c = qfonttrans[c]; + // while (*p == 0) p++; <<< this look awfully dangerous -- pat + p++; + if (*p == '\n') p++; + if (c != 0) DrawQTextCel(tx, ty, pMedTextCels, c); + tx += qfontkern[c] + KERNSPACE; + } + if (pnl == NULL) pnl = p; + tx = MQTEXTX1; + ty += MQTEXTNL; + if (ty > (MQTEXTY2+32)) doneflag = TRUE; + } + + //Delay for text scrolling + DWORD currTime = GetTickCount(); + do { + if (qtextSpd <= 0) { //Go faster + qtexty--; + qtexty += qtextSpd; + } else { //Go slower + qtextDelay--; + if (qtextDelay != 0) qtexty--; + } + if (qtextDelay == 0) qtextDelay = qtextSpd; + + if (qtexty <= (MQTEXTY1-32)) { + qtexty += MQTEXTNL; + qtextptr = pnl; + if (*qtextptr == '|') qtextflag = FALSE; // done? + break; + } + sgLastScroll += 1000/GAME_FRAMES_PER_SECOND; + } while (currTime-sgLastScroll < 0x7FFFFFFF); +} + diff --git a/MINITEXT.H b/MINITEXT.H new file mode 100644 index 0000000..732e993 --- /dev/null +++ b/MINITEXT.H @@ -0,0 +1,43 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/MINITEXT.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + char *txtstr; // String to be called + BOOL scrlltxt; // will text scroll ? + BOOL txtspd; // text speed + int sfxnr; // Sound effect to be called +} TextDataStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern BYTE qtextflag; +extern int qtextSpd; +extern int qtextDelaySpd[10]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void InitQuestText(); +void DrawQText(); +void FreeQuestText(); + +void InitQTextMsg(int); + +void DrawQTextBack(); + diff --git a/MISDAT.CPP b/MISDAT.CPP new file mode 100644 index 0000000..b8be083 --- /dev/null +++ b/MISDAT.CPP @@ -0,0 +1,1886 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Missiles data file +** +** (C)1996 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MISDAT.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "effects.h" +#include "missiles.h" +#include "misdat.h" + +void AddLArrow(int, int, int, int, int, int, char, int, int); +void AddArrow(int, int, int, int, int, int, char, int, int); +void AddRndTeleport(int, int, int, int, int, int, char, int, int); +void AddFirebolt(int, int, int, int, int, int, char, int, int); +void AddMagmaball(int, int, int, int, int, int, char, int, int); +void AddTeleport(int, int, int, int, int, int, char, int, int); +void AddLightball(int, int, int, int, int, int, char, int, int); +void AddLightwall(int, int, int, int, int, int, char, int, int); +void AddFirewall(int, int, int, int, int, int, char, int, int); +void AddFireball(int, int, int, int, int, int, char, int, int); +void AddLightctrl(int, int, int, int, int, int, char, int, int); +void AddLightning(int, int, int, int, int, int, char, int, int); +void AddMisexp(int, int, int, int, int, int, char, int, int); +void AddTown(int, int, int, int, int, int, char, int, int); +void AddFlash(int, int, int, int, int, int, char, int, int); +void AddFlash2(int, int, int, int, int, int, char, int, int); +void AddManashield(int, int, int, int, int, int, char, int, int); +void AddFiremove(int, int, int, int, int, int, char, int, int); +void AddGuardian(int, int, int, int, int, int, char, int, int); +void AddChain(int, int, int, int, int, int, char, int, int); +//void AddChainball(int, int, int, int, int, int, char, int, int); +void AddBlood(int, int, int, int, int, int, char, int, int); +void AddRage(int, int, int, int, int, int, char, int, int); +void AddBone(int, int, int, int, int, int, char, int, int); +void AddMetal(int, int, int, int, int, int, char, int, int); +void AddRhino(int, int, int, int, int, int, char, int, int); +void AddFireman(int, int, int, int, int, int, char, int, int); +void AddFlare(int, int, int, int, int, int, char, int, int); +//void AddDoom(int, int, int, int, int, int, char, int, int); +void AddFireonly(int, int, int, int, int, int, char, int, int); +void AddStone(int, int, int, int, int, int, char, int, int); +void AddBloodR(int, int, int, int, int, int, char, int, int); +void AddSpurt(int, int, int, int, int, int, char, int, int); +void AddBoom(int, int, int, int, int, int, char, int, int); +void AddHeal(int, int, int, int, int, int, char, int, int); +void AddMana(int, int, int, int, int, int, char, int, int); +void AddFMana(int, int, int, int, int, int, char, int, int); +void AddHealOther(int, int, int, int, int, int, char, int, int); +void AddIdentify(int, int, int, int, int, int, char, int, int); +void AddFirewallC(int, int, int, int, int, int, char, int, int); +void AddInfra(int, int, int, int, int, int, char, int, int); +void AddWave(int, int, int, int, int, int, char, int, int); +void AddNova(int, int, int, int, int, int, char, int, int); +void AddBoil(int, int, int, int, int, int, char, int, int); +void AddRepair(int, int, int, int, int, int, char, int, int); +void AddRecharge(int, int, int, int, int, int, char, int, int); +void AddDisarm(int, int, int, int, int, int, char, int, int); +void AddApoca(int, int, int, int, int, int, char, int, int); +void AddFlame(int, int, int, int, int, int, char, int, int); +void AddFlamec(int, int, int, int, int, int, char, int, int); +void AddKrull(int, int, int, int, int, int, char, int, int); +void AddCbolt(int, int, int, int, int, int, char, int, int); +void AddHbolt(int, int, int, int, int, int, char, int, int); +void AddResurrect(int, int, int, int, int, int, char, int, int); +void AddResurrectBeam(int, int, int, int, int, int, char, int, int); +void AddTelekinesis(int, int, int, int, int, int, char, int, int); +void AddAcid(int, int, int, int, int, int, char, int, int); +void AddAcidpud(int, int, int, int, int, int, char, int, int); +void AddGolem(int, int, int, int, int, int, char, int, int); +void AddElement(int, int, int, int, int, int, char, int, int); +void AddEther(int, int, int, int, int, int, char, int, int); +void AddBoneSpirit(int, int, int, int, int, int, char, int, int); +void AddWeapexp(int, int, int, int, int, int, char, int, int); +void AddRportal(int, int, int, int, int, int, char, int, int); +void AddDiabApoca(int, int, int, int, int, int, char, int, int); +void AddSpecialArrow(int, int, int, int, int, int, char, int, int); +void AddFBArrow(int, int, int, int, int, int, char, int, int); +void AddLTArrow(int, int, int, int, int, int, char, int, int); +void AddCBArrow(int, int, int, int, int, int, char, int, int); +void AddHBArrow(int, int, int, int, int, int, char, int, int); +void AddTeleStairs(int, int, int, int, int, int, char, int, int); +void AddReflect(int, int, int, int, int, int, char, int, int); +void AddBerserk(int, int, int, int, int, int, char, int, int); +void AddFlameBox(int, int, int, int, int, int, char, int, int); +void AddDisEnchant(int, int, int, int, int, int, char, int, int); +void AddManaRemove(int, int, int, int, int, int, char, int, int); +void AddShowMagicItems(int, int, int, int, int, int, char, int, int); +void AddAura(int, int, int, int, int, int, char, int, int); +void AddAura2(int, int, int, int, int, int, char, int, int); +void AddSpiralFireBall(int, int, int, int, int, int, char, int, int); +void AddRuneOfFire(int, int, int, int, int, int, char, int, int); +void AddRuneOfLight(int, int, int, int, int, int, char, int, int); +void AddRuneOfNova(int, int, int, int, int, int, char, int, int); +void AddRuneOfImmolation(int, int, int, int, int, int, char, int, int); +void AddRuneOfStone(int, int, int, int, int, int, char, int, int); +void AddBigExplosion(int, int, int, int, int, int, char, int, int); +void AddHorkSpawn(int, int, int, int, int, int, char, int, int); +void AddRandom(int, int, int, int, int, int, char, int, int); +void AddReallyBigExp(int, int, int, int, int, int, char, int, int); + +void MI_Dummy(int); +void MI_Manashield(int); +void MI_SetManashield(int); +void MI_LArrow(int); +void MI_Arrow(int); +void MI_Firebolt(int); +void MI_Lightball(int); +void MI_Lightwall(int); +void MI_Firewall(int); +void MI_Fireball(int); +void MI_Lightctrl(int); +void MI_Lightning(int); +void MI_Misexp(int); +void MI_Town(int); +void MI_Flash(int); +void MI_Flash2(int); +void MI_Manashield(int); +void MI_Firemove(int); +void MI_Guardian(int); +void MI_Chain(int); +//void MI_Chainball(int); +void MI_Blood(int); +void MI_Rage(int); +void MI_Rhino(int); +void MI_Fireman(int); +void MI_Misexp(int); +void MI_Teleport(int); +//void MI_Doom(int); +void MI_Stone(int); +void MI_Boom(int); +void MI_FirewallC(int); +void MI_LightwallC(int); +void MI_Infra(int); +void MI_Apoca(int); +void MI_Wave(int); +void MI_Nova(int); +void MI_FireNova(int); +void MI_Boil(int); +void MI_Flame(int); +void MI_Flamec(int); +void MI_Krull(int); +void MI_Cbolt(int); +void MI_Hbolt(int); +void MI_Acid(int); +void MI_Acidsplat(int); +void MI_Acidpud(int); +void MI_Ether(int); +void MI_Element(int); +void MI_ResurrectBeam(int); +void MI_Weapexp(int); +void MI_Rportal(int); +void MI_Golem(int); +void MI_Bonespirit(int); +void MI_SpecialArrow(int); +void MI_LTArrow(int); +void MI_FlameBox(int); +void MI_LightBox(int); +void MI_ShowMagicItems(int); +void MI_Aura(int); +void MI_Aura2(int); +void MI_SpiralFireBall(int); +void MI_Rune(int); +void MI_BigExplosion(int); +void MI_HorkSpawn(int); +void MI_Reflect(int); + + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +MissileData missiledata[NUMBER_OF_MISSILE_TYPES] = +{ + { MIT_ARROW, // #defines name of missile for ease of use + AddArrow, // procedure for creating one of these missiles + MI_Arrow, // procedure to run each frame + TRUE, // draw missile flag + MIS_WEAP, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_ARROW, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FIREBOLT, // #defines name of missile for ease of use + AddFirebolt, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIREBOLT, // file# of missile gfx table + LS_FBOLT1, // missile launch sound + LS_FIRIMP2 }, // missile impact sound + + { MIT_GUARDIAN, // #defines name of missile for ease of use + AddGuardian, // procedure for creating one of these missiles + MI_Guardian, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_GUARDIAN, // file# of missile gfx table + LS_GUARD, // missile launch sound + LS_GUARDLAN }, // missile impact sound + + { MIT_PHASE, // #defines name of missile for ease of use + AddRndTeleport, // procedure for creating one of these missiles + MI_Teleport, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_TELEPORT, // missile launch sound + -1 }, // missile impact sound + + { MIT_LIGHTBALL, // #defines name of missile for ease of use + AddLightball, // procedure for creating one of these missiles + MI_Lightball, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FIREWALL, // #defines name of missile for ease of use + AddFirewall, // procedure for creating one of these missiles + MI_Firewall, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIRE, // file# of missile gfx table + LS_WALLLOOP, // missile launch sound + LS_FIRIMP2 }, // missile impact sound + + { MIT_FIREBALL, // #defines name of missile for ease of use + AddFireball, // procedure for creating one of these missiles + MI_Fireball, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIREBOLT, // file# of missile gfx table + LS_FBOLT1, // missile launch sound + LS_FIRIMP2 }, // missile impact sound + + { MIT_LIGHTCTRL, // #defines name of missile for ease of use + AddLightctrl, // procedure for creating one of these missiles + MI_Lightctrl, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_LIGHTNING, // #defines name of missile for ease of use + AddLightning, // procedure for creating one of these missiles + MI_Lightning, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + LS_LNING1, // missile launch sound + LS_ELECIMP1 }, // missile impact sound + + { MIT_MISEXP, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Misexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_EXP1, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_TOWN, // #defines name of missile for ease of use + AddTown, // procedure for creating one of these missiles + MI_Town, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_TOWN, // file# of missile gfx table + LS_SENTINEL, // missile launch sound + LS_ELEMENTL }, // missile impact sound + + { MIT_FLASH, // #defines name of missile for ease of use + AddFlash, // procedure for creating one of these missiles + MI_Flash, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_FLASH1, // file# of missile gfx table + LS_NOVA, // missile launch sound + LS_ELECIMP1 }, // missile impact sound + + { MIT_FLASH2, // #defines name of missile for ease of use + AddFlash2, // procedure for creating one of these missiles + MI_Flash2, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_FLASH2, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_MANASHIELD, // #defines name of missile for ease of use + AddManashield, // procedure for creating one of these missiles + MI_SetManashield, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_MANASHLD, // file# of missile gfx table + LS_MSHIELD, // missile launch sound + -1 }, // missile impact sound + + { MIT_FIREMOVE, // #defines name of missile for ease of use + AddFiremove, // procedure for creating one of these missiles + MI_Firemove, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIRE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_CHAIN, // #defines name of missile for ease of use + AddChain, // procedure for creating one of these missiles + MI_Chain, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + LS_LNING1, // missile launch sound + LS_ELECIMP1 }, // missile impact sound + + { MIT_CHAINBALL, // #defines name of missile for ease of use + NULL, // procedure for creating one of these missiles + NULL, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_BLOOD, // #defines name of missile for ease of use + AddBlood, // procedure for creating one of these missiles + MI_Blood, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_BLOOD, // file# of missile gfx table + LS_BLODSTAR, // missile launch sound + LS_BLSIMPT }, // missile impact sound + + { MIT_BONE, // #defines name of missile for ease of use + AddBone, // procedure for creating one of these missiles + MI_Blood, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_BONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_METAL, // #defines name of missile for ease of use + AddMetal, // procedure for creating one of these missiles + MI_Blood, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_METAL, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RHINO, // #defines name of missile for ease of use + AddRhino, // procedure for creating one of these missiles + MI_Rhino, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_MAGMABALL, // #defines name of missile for ease of use + AddMagmaball, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_MAGBALL, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_THINLIGHTCTRL, // #defines name of missile for ease of use + AddLightctrl, // procedure for creating one of these missiles + MI_Lightctrl, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_THINLIGHT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_THINLIGHT, // #defines name of missile for ease of use + AddLightning, // procedure for creating one of these missiles + MI_Lightning, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_THINLIGHT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FLARE, // #defines name of missile for ease of use + AddFlare, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_FLARE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FLAREXP, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Misexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_FLAREXP, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_TELE, // #defines name of missile for ease of use + AddTeleport, // procedure for creating one of these missiles + MI_Teleport, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_ELEMENTL, // missile launch sound + -1 }, // missile impact sound + + { MIT_FARROW, // #defines name of missile for ease of use + AddLArrow, // procedure for creating one of these missiles + MI_LArrow, // procedure to run each frame + TRUE, // draw missile flag + MIS_WEAP, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FARROW, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_DOOM, // #defines name of missile for ease of use + NULL, // procedure for creating one of these missiles + NULL, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_DOOM, // file# of missile gfx table + LS_DSERP, // missile launch sound + -1 }, // missile impact sound + + { MIT_FIREONLY, // #defines name of missile for ease of use + AddFireonly, // procedure for creating one of these missiles + MI_Firewall, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIRE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_STONE, // #defines name of missile for ease of use + AddStone, // procedure for creating one of these missiles + MI_Stone, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_SCURIMP, // missile launch sound + -1 }, // missile impact sound + + { MIT_BLOODR, // #defines name of missile for ease of use + AddBloodR, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_INVIS, // #defines name of missile for ease of use + NULL, // procedure for creating one of these missiles + NULL, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_INVISIBL, // missile launch sound + -1 }, // missile impact sound + + { MIT_GOLEM, // #defines name of missile for ease of use + AddGolem, // procedure for creating one of these missiles + MI_Golem, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_GOLUM, // missile launch sound + -1 }, // missile impact sound + + { MIT_ETHER, // #defines name of missile for ease of use + AddEther, // procedure for creating one of these missiles + MI_Ether, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_ETHER, // file# of missile gfx table + LS_ETHEREAL, // missile launch sound + -1 }, // missile impact sound + + { MIT_SPURT, // #defines name of missile for ease of use + AddSpurt, // procedure for creating one of these missiles + MI_Blood, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_SPURT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_BOOM, // #defines name of missile for ease of use + AddBoom, // procedure for creating one of these missiles + MI_Boom, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_BOOM, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_HEAL, // #defines name of missile for ease of use + AddHeal, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FIREWALLC, // #defines name of missile for ease of use + AddFirewallC, // procedure for creating one of these missiles + MI_FirewallC, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIRE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_INFRA, // #defines name of missile for ease of use + AddInfra, // procedure for creating one of these missiles + MI_Infra, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_INFRAVIS, // missile launch sound + -1 }, // missile impact sound + + { MIT_IDENTIFY, // #defines name of missile for ease of use + AddIdentify, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_WAVE, // #defines name of missile for ease of use + AddWave, // procedure for creating one of these missiles + MI_Wave, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIRE, // file# of missile gfx table + LS_FLAMWAVE, // missile launch sound + -1 }, // missile impact sound + + { MIT_NOVA, // #defines name of missile for ease of use + AddNova, // procedure for creating one of these missiles + MI_Nova, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + LS_NOVA, // missile launch sound + -1 }, // missile impact sound + +#if 0 + { MIT_BLDBOIL, // #defines name of missile for ease of use + AddBoil, // procedure for creating one of these missiles + MI_Boil, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + LS_BLODBOIL }, // missile impact sound +#else + { MIT_RAGE, // #defines name of missile for ease of use + AddRage, // procedure for creating one of these missiles + MI_Rage, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound +#endif + + { MIT_APOCA, // #defines name of missile for ease of use + AddApoca, // procedure for creating one of these missiles + MI_Apoca, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_BOOM, // file# of missile gfx table + LS_APOC, // missile launch sound + -1 }, // missile impact sound + + { MIT_REPAIR, // #defines name of missile for ease of use + AddRepair, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RECHARGE, // #defines name of missile for ease of use + AddRecharge, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_DISARM, // #defines name of missile for ease of use + AddDisarm, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_TRAPDIS, // missile launch sound + -1 }, // missile impact sound + + { MIT_FLAME, // #defines name of missile for ease of use + AddFlame, // procedure for creating one of these missiles + MI_Flame, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FLAMES, // file# of missile gfx table + //MF_LIGHTNING, // file# of missile gfx table + LS_SPOUTSTR, // missile launch sound + -1 }, // missile impact sound + + { MIT_FLAMEC, // #defines name of missile for ease of use + AddFlamec, // procedure for creating one of these missiles + MI_Flamec, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FIREMAN, // #defines name of missile for ease of use + AddFireman, // procedure for creating one of these missiles + MI_Fireman, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_KRULL, // #defines name of missile for ease of use + AddKrull, // procedure for creating one of these missiles + MI_Krull, // procedure to run each frame + TRUE, // draw missile flag + MIS_WEAP, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_KRULL, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_CBOLT, // #defines name of missile for ease of use + AddCbolt, // procedure for creating one of these missiles + MI_Cbolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_CBOLT, // file# of missile gfx table + LS_CBOLT, // missile launch sound + -1 }, // missile impact sound + + { MIT_HBOLT, // #defines name of missile for ease of use + AddHbolt, // procedure for creating one of these missiles + MI_Hbolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_HBOLT, // file# of missile gfx table + LS_HOLYBOLT, // missile launch sound + LS_ELECIMP1 }, // missile impact sound + + { MIT_RESURRECT, // #defines name of missile for ease of use + AddResurrect, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + LS_RESUR }, // missile impact sound + + { MIT_TELEKINESIS, // #defines name of missile for ease of use + AddTelekinesis, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_ETHEREAL, // missile launch sound + -1 }, // missile impact sound + + { MIT_LARROW, // #defines name of missile for ease of use + AddLArrow, // procedure for creating one of these missiles + MI_LArrow, // procedure to run each frame + TRUE, // draw missile flag + MIS_WEAP, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LARROW, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_ACID, // #defines name of missile for ease of use + AddAcid, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_ACID, // missile resistance type (fire, light, misc, none) + MF_ACID, // file# of missile gfx table + LS_ACID, // missile launch sound + -1 }, // missile impact sound + + { MIT_ACIDSPLAT, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Acidsplat, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_ACID, // missile resistance type (fire, light, misc, none) + MF_ACIDSPLAT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_ACIDPUD, // #defines name of missile for ease of use + AddAcidpud, // procedure for creating one of these missiles + MI_Acidpud, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_ACID, // missile resistance type (fire, light, misc, none) + MF_ACIDPUD, // file# of missile gfx table + LS_PUDDLE, // missile launch sound + -1 }, // missile impact sound + + { MIT_HEALOTHER, // #defines name of missile for ease of use + AddHealOther, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_ELEMENT, // #defines name of missile for ease of use + AddElement, // procedure for creating one of these missiles + MI_Element, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIRERUN, // file# of missile gfx table + LS_ELEMENTL, // missile launch sound + -1 }, // missile impact sound + + { MIT_RESURRECTBEAM, // #defines name of missile for ease of use + AddResurrectBeam, // procedure for creating one of these missiles + MI_ResurrectBeam, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_RESURRECT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_BONESPIRIT, // #defines name of missile for ease of use + AddBoneSpirit, // procedure for creating one of these missiles + MI_Bonespirit, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_BONESPIRIT, // file# of missile gfx table + LS_BONESP, // missile launch sound + LS_BSIMPCT }, // missile impact sound + + { MIT_WEAPEXP, // #defines name of missile for ease of use + AddWeapexp, // procedure for creating one of these missiles + MI_Weapexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RPORTAL, // #defines name of missile for ease of use + AddRportal, // procedure for creating one of these missiles + MI_Rportal, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_RPORTAL, // file# of missile gfx table + LS_SENTINEL, // missile launch sound + LS_ELEMENTL }, // missile impact sound + + { MIT_FIREPLAR, // #defines name of missile for ease of use + AddBoom, // procedure for creating one of these missiles + MI_Boom, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_FIREPLAR, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_DIABAPOCA, // #defines name of missile for ease of use + AddDiabApoca, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_MANA, // #defines name of missile for ease of use + AddMana, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FMANA, // #defines name of missile for ease of use + AddFMana, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_LIGHTWALL, // #defines name of missile for ease of use + AddLightwall, // procedure for creating one of these missiles + MI_Lightwall, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + LS_LMAG, // missile launch sound + LS_ELECIMP1 }, // missile impact sound + + { MIT_LIGHTWALLC, // #defines name of missile for ease of use + AddFirewallC, // procedure for creating one of these missiles + MI_LightwallC, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_IMMOLATION, // #defines name of missile for ease of use + AddNova, // procedure for creating one of these missiles + MI_FireNova, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIREBOLT, // file# of missile gfx table + LS_FBOLT1, // missile launch sound + LS_FIRIMP2 }, // missile impact sound + + { MIT_SPECARROW, // #defines name of missile for ease of use + AddSpecialArrow, // procedure for creating one of these missiles + MI_SpecialArrow, // procedure to run each frame + TRUE, // draw missile flag + MIS_WEAP, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_ARROW, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FBARROW, // #defines name of missile for ease of use + AddFBArrow, // procedure for creating one of these missiles + MI_Fireball, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIREBOLT, // file# of missile gfx table + PS_FB_BFIRE, // missile launch sound + LS_FIRIMP2 }, // missile impact sound + + { MIT_LTARROW, // #defines name of missile for ease of use + AddLTArrow, // procedure for creating one of these missiles + MI_LTArrow, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + PS_FB_BFIRE, // missile launch sound + -1 }, // missile impact sound + + { MIT_CBARROW, // #defines name of missile for ease of use + AddCBArrow, // procedure for creating one of these missiles + MI_Cbolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_CBOLT, // file# of missile gfx table + LS_CBOLT, // missile launch sound + -1 }, // missile impact sound + + { MIT_HBARROW, // #defines name of missile for ease of use + AddHBArrow, // procedure for creating one of these missiles + MI_Hbolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_HBOLT, // file# of missile gfx table + LS_HOLYBOLT, // missile launch sound + LS_ELECIMP1 }, // missile impact sound + + { MIT_TELESTAIRS, // #defines name of missile for ease of use + AddTeleStairs, // procedure for creating one of these missiles + MI_Teleport, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + LS_ETHEREAL, // missile launch sound + -1 }, // missile impact sound + + { MIT_REFLECT, // #defines name of missile for ease of use + AddReflect, // procedure for creating one of these missiles + MI_Reflect, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_REFLECTSHLD, // file# of missile gfx table + LS_MSHIELD, // missile launch sound + -1 }, // missile impact sound + + { MIT_BERSERK, // #defines name of missile for ease of use + AddBerserk, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_FLAMEBOX, // #defines name of missile for ease of use + AddFlameBox, // procedure for creating one of these missiles + MI_FlameBox, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIRE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_DISENCHANT, // #defines name of missile for ease of use + AddDisEnchant, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_MANAREMOVE, // #defines name of missile for ease of use + AddManaRemove, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + IS_CAST7, // missile launch sound + -1 }, // missile impact sound + + { MIT_LIGHTBOX, // #defines name of missile for ease of use + AddFlameBox, // procedure for creating one of these missiles + MI_LightBox, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_LGHT, // missile resistance type (fire, light, misc, none) + MF_LIGHTNING, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_SHOWMAGITEMS, // #defines name of missile for ease of use + AddShowMagicItems, // procedure for creating one of these missiles + MI_ShowMagicItems, // procedure to run each frame + FALSE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_AURA, // #defines name of missile for ease of use + AddAura, // procedure for creating one of these missiles + MI_Aura, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_FLASH1, // file# of missile gfx table + -1, // missile launch sound + LS_ELECIMP1 }, // missile impact sound + + { MIT_AURA2, // #defines name of missile for ease of use + AddAura2, // procedure for creating one of these missiles + MI_Aura2, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_FLASH2, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_SPIRALFIREBALL, // #defines name of missile for ease of use + AddSpiralFireBall, // procedure for creating one of these missiles + MI_SpiralFireBall, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_FIREBOLT, // file# of missile gfx table + LS_FBOLT1, // missile launch sound + LS_FIRIMP2 }, // missile impact sound + + { MIT_RUNEOFFIRE, // #defines name of missile for ease of use + AddRuneOfFire, // procedure for creating one of these missiles + MI_Rune, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_RUNEHOTSPOT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RUNEOFLIGHT, // #defines name of missile for ease of use + AddRuneOfLight, // procedure for creating one of these missiles + MI_Rune, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_RUNEHOTSPOT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RUNEOFNOVA, // #defines name of missile for ease of use + AddRuneOfNova, // procedure for creating one of these missiles + MI_Rune, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_RUNEHOTSPOT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RUNEOFIMMOLATION, // #defines name of missile for ease of use + AddRuneOfImmolation, // procedure for creating one of these missiles + MI_Rune, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_RUNEHOTSPOT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RUNEOFSTONE, // #defines name of missile for ease of use + AddRuneOfStone, // procedure for creating one of these missiles + MI_Rune, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_RUNEHOTSPOT, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_BIGEXPLOSION, // #defines name of missile for ease of use + AddBigExplosion, // procedure for creating one of these missiles + MI_BigExplosion, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_FIRE, // missile resistance type (fire, light, misc, none) + MF_BIGEXP, // file# of missile gfx table + LS_BIGEXP, // missile launch sound + LS_BIGEXP }, // missile impact sound + + { MIT_HORKSPAWN, // #defines name of missile for ease of use + AddHorkSpawn, // procedure for creating one of these missiles + MI_HorkSpawn, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_HORKSPAWN, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_RANDOM, // #defines name of missile for ease of use + AddRandom, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_OPENNEST, // #defines name of missile for ease of use + AddReallyBigExp, // procedure for creating one of these missiles + MI_Dummy, // procedure to run each frame + FALSE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_NONE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_ORANGEFLARE, // #defines name of missile for ease of use + AddFlare, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_ORANGEFLARE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_BLUEFLARE, // #defines name of missile for ease of use + AddFlare, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_BLUE2FLARE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_REDFLARE, // #defines name of missile for ease of use + AddFlare, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_REDFLARE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_YELLOWFLARE, // #defines name of missile for ease of use + AddFlare, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_YELLOWFLARE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_BLUE2FLARE, // #defines name of missile for ease of use + AddFlare, // procedure for creating one of these missiles + MI_Firebolt, // procedure to run each frame + TRUE, // draw missile flag + MIS_SPL, // missile type (weapon, spell, none) + MIMT_MISC, // missile resistance type (fire, light, misc, none) + MF_BLUE2FLARE, // file# of missile gfx table + -1, // missile launch sound + -1 }, // missile impact sound + + { MIT_YELLOWEXPLOSION, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Misexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_YELLOWEXPLOSION, // file# of missile gfx table + LS_FIRIMP2, // missile launch sound + -1 }, // missile impact sound + + { MIT_REDEXPLOSION, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Misexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_REDEXPLOSION, // file# of missile gfx table + LS_FIRIMP2, // missile launch sound + -1 }, // missile impact sound + + { MIT_BLUEEXPLOSION, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Misexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_BLUEEXPLOSION, // file# of missile gfx table + LS_FIRIMP2, // missile launch sound + -1 }, // missile impact sound + + { MIT_BLUE2EXPLOSION, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Misexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_BLUE2EXPLOSION, // file# of missile gfx table + LS_FIRIMP2, // missile launch sound + -1 }, // missile impact sound + + { MIT_ORANGEEXPLOSION, // #defines name of missile for ease of use + AddMisexp, // procedure for creating one of these missiles + MI_Misexp, // procedure to run each frame + TRUE, // draw missile flag + MIS_NONE, // missile type (weapon, spell, none) + MIMT_NONE, // missile resistance type (fire, light, misc, none) + MF_ORANGEEXPLOSION, // file# of missile gfx table + LS_FIRIMP2, // missile launch sound + -1 }, // missile impact sound + +}; + + +MisFileData misfiledata[] = +{ + { MF_ARROW, // #defines name of missile file for ease of use + 1, // amount of files + "Arrows", // path for cels + MFF_STATIC, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FIREBOLT, // #defines name of missile file for ease of use + 16, // amount of files + "Fireba", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } }, // anim width2 + + { MF_GUARDIAN, // #defines name of missile file for ease of use + 3, // amount of files + "Guard", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15, 14, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_LIGHTNING, // #defines name of missile file for ease of use + 1, // amount of files + "Lghning", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FIRE, // #defines name of missile file for ease of use + 2, // amount of files + "Firewal", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 13, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_EXP1, // #defines name of missile file for ease of use + 1, // amount of files + "MagBlos", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_TOWN, // #defines name of missile file for ease of use + 2, // amount of files + "Portal", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FLASH1, // #defines name of missile file for ease of use + 1, // amount of files + "Bluexfr", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FLASH2, // #defines name of missile file for ease of use + 1, // amount of files + "Bluexbk", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_MANASHLD, // #defines name of missile file for ease of use + 1, // amount of files + "Manashld", // path for cels + MFF_STATIC, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BLOOD, // #defines name of missile file for ease of use + 4, // amount of files + "Blood", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BONE, // #defines name of missile file for ease of use + 3, // amount of files + "Bone", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_METAL, // #defines name of missile file for ease of use + 3, // amount of files + "Metlhit", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FARROW, // #defines name of missile file for ease of use + 16, // amount of files + "Farrow", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } }, // anim width2 + + { MF_DOOM, // #defines name of missile file for ease of use + 9, // amount of files + "Doom", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_GOLEM, // #defines name of missile file for ease of use + 1, // amount of files + " ", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_SPURT, // #defines name of missile file for ease of use + 2, // amount of files + "Blodbur", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BOOM, // #defines name of missile file for ease of use + 1, // amount of files + "Newexp", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_STONE, // #defines name of missile file for ease of use + 1, // amount of files + "Shatter1", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BIGEXP, // #defines name of missile file for ease of use + 1, // amount of files + "Bigexp", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FLAMES, // #defines name of missile file for ease of use + 1, // amount of files + "Inferno", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_THINLIGHT, // #defines name of missile file for ease of use + 1, // amount of files + "Thinlght", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FLARE, // #defines name of missile file for ease of use + 1, // amount of files + "Flare", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FLAREXP, // #defines name of missile file for ease of use + 1, // amount of files + "Flareexp", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_MAGBALL, // #defines name of missile file for ease of use + 8, // amount of files + "Magball", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_KRULL, // #defines name of missile file for ease of use + 1, // amount of files + "Krull", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + + { MF_CBOLT, // #defines name of missile file for ease of use + 1, // amount of files + "Miniltng", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_HBOLT, // #defines name of missile file for ease of use + 16, // amount of files + "Holy", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } }, // anim width2 + + { MF_HEXPL, // #defines name of missile file for ease of use + 1, // amount of files + "Holyexpl", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_LARROW, // #defines name of missile file for ease of use + 16, // amount of files + "Larrow", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } }, // anim width2 + + { MF_FAEXP, // #defines name of missile file for ease of use + 1, // amount of files + "Firarwex", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_ACID, // #defines name of missile file for ease of use + 16, // amount of files + "Acidbf", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } }, // anim width2 + + { MF_ACIDSPLAT, // #defines name of missile file for ease of use + 1, // amount of files + "Acidspla", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_ACIDPUD, // #defines name of missile file for ease of use + 2, // amount of files + "Acidpud" , // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 9, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96,96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_ETHER, // #defines name of missile file for ease of use + 1, // amount of files + "Ethrshld", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FIRERUN, // #defines name of missile file for ease of use + 8, // amount of files + "Firerun", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 12, 12, 12, 12, 12, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_RESURRECT, // #defines name of missile file for ease of use + 1, // amount of files + "Ressur1", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BONESPIRIT, // #defines name of missile file for ease of use + 9, // amount of files + "Sklball", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 16, 16, 16, 16, 16, 16, 16, 8, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_RPORTAL, // #defines name of missile file for ease of use + 2, // amount of files + "Rportal", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_FIREPLAR, // #defines name of missile file for ease of use + 1, // amount of files + "Fireplar", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 160,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BFLARE, // #defines name of missile file for ease of use + 1, // amount of files + "Scubmisb", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BFLAREXP, // #defines name of missile file for ease of use + 1, // amount of files + "Scbsexpb", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_CFLARE, // #defines name of missile file for ease of use + 1, // amount of files + "Scubmisc", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_CFLAREXP, // #defines name of missile file for ease of use + 1, // amount of files + "Scbsexpc", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_DFLARE, // #defines name of missile file for ease of use + 1, // amount of files + "Scubmisd", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_DFLAREXP, // #defines name of missile file for ease of use + 1, // amount of files + "Scbsexpd", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_HORKSPAWN, // #defines name of missile file for ease of use + 8, // amount of files + "spawns", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96,96,96,96,96,96,96,96, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 16,16,16,16,16,16,16,16, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_REFLECTSHLD, // #defines name of missile file for ease of use + 1, // amount of files + "reflect", // path for cels + MFF_STATIC, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + {160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + {160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_ORANGEFLARE, // #defines name of missile file for ease of use + 16, // amount of files + "ms_ora", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 }, // number of anim frames + { 96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96 }, // anim width + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 } }, // anim width2 + + { MF_BLUEFLARE, // #defines name of missile file for ease of use + 16, // amount of files + "ms_bla", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 }, // number of anim frames + { 96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96 }, // anim width + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 } }, // anim width2 + + { MF_REDFLARE, // #defines name of missile file for ease of use + 16, // amount of files + "ms_reb", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 }, // number of anim frames + { 96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96 }, // anim width + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 } }, // anim width2 + + { MF_YELLOWFLARE, // #defines name of missile file for ease of use + 16, // amount of files + "ms_yeb", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 }, // number of anim frames + { 96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96 }, // anim width + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 } }, // anim width2 + + { MF_RUNEHOTSPOT, // #defines name of missile file for ease of use + 1, // amount of files + "rglows1", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_YELLOWEXPLOSION, // #defines name of missile file for ease of use + 1, // amount of files + "ex_yel2", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BLUEEXPLOSION, // #defines name of missile file for ease of use + 1, // amount of files + "ex_blu2", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_REDEXPLOSION, // #defines name of missile file for ease of use + 1, // amount of files + "ex_red3", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BLUE2FLARE, // #defines name of missile file for ease of use + 16, // amount of files + "ms_blb", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 }, // number of anim frames + { 96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96 }, // anim width + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 } }, // anim width2 + + { MF_ORANGEEXPLOSION, // #defines name of missile file for ease of use + 1, // amount of files + "ex_ora1", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + + { MF_BLUE2EXPLOSION, // #defines name of missile file for ease of use + 1, // amount of files + "ex_blu3", // path for cels + MFF_MONSTONLY, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // anim width2 + +// END OF LIST INDICATOR + { MF_NONE, // #defines name of missile file for ease of use + 0, // amount of files + "", // path for cels + NULL, // flags, e.g., MFF_MONSTONLY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // data pointers to anim tables + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim delay amount + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // number of anim frames + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // anim width + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } // anim width2 +}; + diff --git a/MISDAT.H b/MISDAT.H new file mode 100644 index 0000000..3eba664 --- /dev/null +++ b/MISDAT.H @@ -0,0 +1,135 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1996 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MISDAT.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ +typedef void (*MIADDPRC)(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam); +typedef void (*MIPROC)(int i); + +#define MIS_WEAP 0 +#define MIS_SPL 1 +#define MIS_NONE 2 + +// Missile Magic Type +#define MIMT_NONE 0 +#define MIMT_FIRE 1 +#define MIMT_LGHT 2 +#define MIMT_MISC 3 +#define MIMT_ACID 4 + +// Missile File Flags +#define MFF_MONSTONLY 1 // Only loaded for particular monsters +#define MFF_STATIC 2 // Do not animate -- one frame per direction +#define MFF_MULTI 4 // All directions of anim are in one file + +#define MF_NONE 255 +#define MF_STARTLOAD 0 +#define MF_ARROW 0 +#define MF_FIREBOLT 1 +#define MF_GUARDIAN 2 +#define MF_LIGHTNING 3 +#define MF_FIRE 4 +#define MF_EXP1 5 +#define MF_TOWN 6 +#define MF_FLASH1 7 +#define MF_FLASH2 8 +#define MF_MANASHLD 9 +#define MF_BLOOD 10 +#define MF_BONE 11 +#define MF_METAL 12 +#define MF_FARROW 13 +#define MF_DOOM 14 +#define MF_GOLEM 15 +#define MF_SPURT 16 +#define MF_BOOM 17 +#define MF_STONE 18 +#define MF_BIGEXP 19 +#define MF_FLAMES 20 +#define MF_THINLIGHT 21 +#define MF_FLARE 22 +#define MF_FLAREXP 23 +#define MF_MAGBALL 24 +#define MF_KRULL 25 +#define MF_CBOLT 26 +#define MF_HBOLT 27 +#define MF_HEXPL 28 +#define MF_LARROW 29 +#define MF_FAEXP 30 +#define MF_ACID 31 +#define MF_ACIDSPLAT 32 +#define MF_ACIDPUD 33 +#define MF_ETHER 34 +#define MF_FIRERUN 35 +#define MF_RESURRECT 36 +#define MF_BONESPIRIT 37 +#define MF_RPORTAL 38 +#define MF_FIREPLAR 39 +#define MF_BFLARE 40 +#define MF_BFLAREXP 41 +#define MF_CFLARE 42 +#define MF_CFLAREXP 43 +#define MF_DFLARE 44 +#define MF_DFLAREXP 45 +#define MF_HORKSPAWN 46 +#define MF_REFLECTSHLD 47 +#define MF_ORANGEFLARE 48 +#define MF_BLUEFLARE 49 +#define MF_REDFLARE 50 +#define MF_YELLOWFLARE 51 +#define MF_RUNEHOTSPOT 52 +#define MF_YELLOWEXPLOSION 53 +#define MF_BLUEEXPLOSION 54 +#define MF_REDEXPLOSION 55 +#define MF_BLUE2FLARE 56 +#define MF_ORANGEEXPLOSION 57 +#define MF_BLUE2EXPLOSION 58 + + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ +typedef struct { + BYTE mName; // #defines name of missile for ease of use + MIADDPRC mAddProc; // procedure for creating one of these missiles + MIPROC mProc; // procedure to run each frame + BOOL mDraw; // missile draw or not flag + BYTE mType; // missile type (weapon, spell, none) + BYTE mResist; // missile resistance type (fire, light, misc, none) + BYTE mFileNum; // file# of missile gfx table + int mlSFX; // missile launch sound + int miSFX; // missile impact sound +} MissileData; + +typedef struct { + BYTE mAnimName; // #defines name of missile file for ease of use + BYTE mAnimFAmt; // amount of files + char *mAnimPath; // path for cels + BOOL mFlags; // e.g. MFF_MONSTOLY + BYTE *mAnimData[16]; // data pointer to anim tables + BYTE mAnimDelay[16]; // anim delay amount + BYTE mAnimLen[16]; // number of anim frames + long mAnimWidth[16]; // anim width + long mAnimWidth2[16]; // anim width2 +} MisFileData; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern MissileData missiledata[]; +extern MisFileData misfiledata[]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ diff --git a/MISSILES.CPP b/MISSILES.CPP new file mode 100644 index 0000000..2e6915c --- /dev/null +++ b/MISSILES.CPP @@ -0,0 +1,7451 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Missiles file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MISSILES.CPP 3 2/25/97 2:27p Jmcreynolds $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include +#include +#include "sound.h" +#include "missiles.h" +#include "misdat.h" +#include "engine.h" +#include "gendung.h" +#include "lighting.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "monstdat.h" +#include "monstint.h" +#include "control.h" +#include "objects.h" +#include "objdat.h" +#include "spells.h" +#include "cursor.h" +#include "dead.h" +#include "effects.h" +#include "palette.h" +#include "inv.h" +#include "msg.h" +#include "quests.h" +#include "itemdat.h" +#include "multi.h" +#include "trigs.h" +#include "scrollrt.h" + +#define MONOPRINT 1 + +/*-----------------------------------------------------------------------* +** Constants +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +#define CEL_EXT ".CL2" +#else +#define CEL_EXT ".CEL" +#endif + + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +MissileStruct missile[MAXMISSILES]; +int nummissiles; + +static int missilevars[MAXMISSILES][3]; //0 missile num; 1 var1; 2 var2 +static int nummissilevars; + +int missileactive[MAXMISSILES]; +int missileavail[MAXMISSILES]; + +int XDirAdd[8] = { 1, 0, -1, -1, -1, 0, 1, 1 }; +int YDirAdd[8] = { 1, 1, 1, 0, -1, -1, -1, 0 }; + +// Indexes into the CrawlTable. +static int const CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, + 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 }; + +BOOL ManashieldFlag; +BOOL MissilePreFlag; + +typedef BOOL (*CHECKFUNC)(int x, int y); + +static void GetMissilePos(int i); +void SetMissDir(int mi, int dir); + +/*-----------------------------------------------------------------------** +**----------------------- General use routines --------------------------** +**-----------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetDamageAmt(int i, int * mind, int * maxd) +{ + int k, sl; + + app_assert(myplr < MAX_PLRS && myplr >= 0); + app_assert(i < 64 && i >= 0); + sl = plr[myplr]._pSplLvl[i] + plr[myplr]._pISplLvlAdd; + + switch (i) { + case SPL_FIREBOLT: + *mind = 1 + (plr[myplr]._pMagic >> 3) + sl; + *maxd = 10 + (plr[myplr]._pMagic >> 3) + sl; + break; + case SPL_HEAL: + *mind = 1 + plr[myplr]._pLevel + sl; + if (plr[myplr]._pClass == CLASS_WARRIOR + || plr[myplr]._pClass == CLASS_MONK + || plr[myplr]._pClass == CLASS_BARBARIAN) *mind = *mind << 1; + else if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD) *mind += (*mind >> 1); + *maxd = 10; + for (k = 0; k < plr[myplr]._pLevel; ++k) *maxd += 4; + for (k = 0; k < sl; ++k) *maxd += 6; + if (plr[myplr]._pClass == CLASS_WARRIOR + || plr[myplr]._pClass == CLASS_MONK + || plr[myplr]._pClass == CLASS_BARBARIAN) *maxd = *maxd << 1; + else if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD) *maxd += (*maxd >> 1); + *mind = -1; + *maxd = -1; + break; + case SPL_LIGHTNING: + case SPL_RUNEOFLIGHT: + *mind = 2; + *maxd = plr[myplr]._pLevel + 2; + break; + case SPL_FLASH: + *mind = plr[myplr]._pLevel; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *mind += *mind >> 1; + *maxd = *mind << 1; // this is not actual(below is) - its a kludge to make it seem acurate text wise + /**maxd = 0; + for (k = 0; k <= plr[myplr]._pLevel; ++k) *maxd += 20; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + *maxd += *maxd >> 1;*/ + break; + case SPL_IDENTIFY: + case SPL_TOWN: + case SPL_STONE: + case SPL_RUNEOFSTONE: + case SPL_INFRA: + case SPL_PHASE: + case SPL_MANASHLD: + case SPL_DOOM: + case SPL_BLOODR: + case SPL_INVIS: + //case SPL_BLOODB: + case SPL_RAGE: + case SPL_TELE: + case SPL_ETHER: + case SPL_REPAIR: + case SPL_RECHARGE: + case SPL_DISARM: + case SPL_RESURRECT: + case SPL_TELEKINESIS: + case SPL_BONESPIRIT: + case SPL_TELESTAIRS: + case SPL_REFLECT: + case SPL_BERSERK: + case SPL_SHOWMAGITEMS: + *mind = -1; + *maxd = -1; + break; + case SPL_WALL: + case SPL_LTWALL: + case SPL_RINGOFFIRE: + *mind = ((2 + plr[myplr]._pLevel) << 2) >> 1; + *maxd = ((20 + plr[myplr]._pLevel) << 2) >> 1; + break; + case SPL_FIREBALL: + case SPL_RUNEOFFIRE: + *mind = (2 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *maxd = (20 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + break; + case SPL_GUARDIAN: + *mind = 1 + (plr[myplr]._pLevel >> 1); + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *maxd = 10 + (plr[myplr]._pLevel >> 1); + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + break; + case SPL_CHAIN: + // this is not actual - its a kludge to make it seem acurate text wise + *mind = 2 << 1; + *maxd = (plr[myplr]._pLevel + 2) << 1; + break; + case SPL_WAVE: + // this is not actual - its a kludge to make it seem acurate text wise + *mind = ((1 + plr[myplr]._pLevel) << 2) + ((1 + plr[myplr]._pLevel) << 1); + *maxd = ((10 + plr[myplr]._pLevel) << 2) + ((10 + plr[myplr]._pLevel) << 1); + break; + case SPL_NOVA: + case SPL_IMMOLATION: + case SPL_RUNEOFIMMOLATION: + case SPL_RUNEOFNOVA: + // this is not actual - its a kludge to make it seem acurate text wise + *mind = (5 + plr[myplr]._pLevel) >> 1; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *mind = (*mind << 2) + *mind; + *maxd = (30 + plr[myplr]._pLevel) >> 1; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + *maxd = (*maxd << 2) + *maxd; + break; + case SPL_FLAME: + *mind = 2; + *mind += *mind >> 1; + *maxd = (plr[myplr]._pLevel + 4); + *maxd += *maxd >> 1; + break; + case SPL_GOLEM: + *mind = 11; + *maxd = 17; + break; + case SPL_APOCA: + *mind = 0; + for (k = 0; k < plr[myplr]._pLevel; ++k) *mind += 1; + *maxd = 0; + for (k = 0; k < plr[myplr]._pLevel; ++k) *maxd += 6; + break; + case SPL_ELEMENT: + *mind = (2 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *maxd = (20 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + break; + case SPL_CBOLT: + *mind = 1; + *maxd = 1 + (plr[myplr]._pMagic >> 2); + break; + case SPL_HBOLT: + *mind = 9 + plr[myplr]._pLevel; + *maxd = 18 + plr[myplr]._pLevel; + break; + case SPL_HEALOTHER: + *mind = 1 + plr[myplr]._pLevel + sl; + if (plr[myplr]._pClass == CLASS_WARRIOR + || plr[myplr]._pClass == CLASS_MONK + || plr[myplr]._pClass == CLASS_BARBARIAN) *mind = *mind << 1; + if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD ) *mind += (*mind >> 1); + *maxd = 10; + for (k = 0; k < plr[myplr]._pLevel; ++k) *maxd += 4; + for (k = 0; k < sl; ++k) *maxd += 6; + if (plr[myplr]._pClass == CLASS_WARRIOR + || plr[myplr]._pClass == CLASS_MONK + || plr[myplr]._pClass == CLASS_BARBARIAN) *maxd = *maxd << 1; + if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD ) *maxd += (*maxd >> 1); + *mind = -1; + *maxd = -1; + break; + case SPL_BSTAR: + *mind = ((plr[myplr]._pMagic>>1)-(plr[myplr]._pMagic>>3)) + (sl << 1) + sl; + *maxd = *mind; + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int CheckBlock(int fx, int fy, int tx, int ty) +{ + int pn, dir, coll; + + coll = 0; + + while ((fx != tx) || (fy != ty)) { + dir = GetDirection(fx, fy, tx, ty); + fx += XDirAdd[dir]; + fy += YDirAdd[dir]; + app_assert(fx < MAXDUNX && fx >= 0); + app_assert(fy < MAXDUNY && fy >= 0); + pn = dPiece[fx][fy]; + app_assert(pn <= MAXTILES && pn >= 0); + if (nSolidTable[pn]) coll = 1; + } + + return coll; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int FindClosest(int sx, int sy, int rad) +{ + int cr, cidx, cent, cne, mid, tx, ty; + + if (rad > 19) rad = 19; + + for (cr = 1; cr < rad; ++cr) { + cidx = CrawlNum[cr]; + cent = cidx + 1; + for (cne = CrawlTable[cidx]; cne > 0; --cne) { + tx = sx + CrawlTable[cent]; + ty = sy + CrawlTable[(cent + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + mid = dMonster[tx][ty]; + if ((mid > 0) && (CheckBlock(sx, sy, tx, ty) == 0)) + return (mid - 1); + } + cent += 2; + } + } + + return (-1); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static bool SetMissileLocation(int i, int *sx, int *sy, int rad) +{ + bool success = false; + + if (rad > 19) rad = 19; + + for (int cr = 0; cr < rad && !success; ++cr) { + int const cidx = CrawlNum[cr]; + int cent = cidx + 1; + for (int cne = CrawlTable[cidx]; cne > 0; --cne, cent += 2) { + int const tx = *sx + CrawlTable[cent]; + int const ty = *sy + CrawlTable[(cent + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int const pn = dPiece[tx][ty]; + if (!nSolidTable[pn] + && dObject[tx][ty] == 0 + && dMissile[tx][ty] == 0) { + missile[i]._mix = tx; + missile[i]._miy = ty; + *sx = tx; + *sy = ty; + success = true; + break; + } + } + } + } + + return (success); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int GetSpellLevel(int id, int sn) +{ + int rv; + + app_assert(id < MAX_PLRS && id >= 0); + app_assert(sn < 64 && sn >= 0); + if (id == myplr) + rv = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd; + else + rv = 1; + if (rv < 0 ) rv = 0; + return (rv); +} + +#if 0 // UNUSED +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RndBlood(int x, int y, int type, int dam, int hp) +{ + int pct, str; + + app_assert(hp != 0); + str = 0; + pct = (dam * 100) / hp; + if (pct > 65) str = 1; + if (pct > 80) str = 2; + if (pct > 90) str = 3; + str = 1; + + //AddMissile(x, y, str, 0, 0, type, 0, myplr, 0); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static int GetDirection8(int x1, int y1, int x2, int y2) +{ + BYTE const Dirs[16][16] = { + { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0 + { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1 + { 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2 + { 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, // 3 + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // 4 + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, // 5 + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 6 + { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 7 + { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 8 + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 9 + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 10 + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 11 + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 12 + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 13 + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 14 + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }};// 15 + + BYTE const lrtoul[3] = { 3, 4, 5 }; + BYTE const urtoll[3] = { 3, 2, 1 }; + BYTE const lltour[3] = { 7, 6, 5 }; + BYTE const ultolr[3] = { 7, 0, 1 }; + + int mx, my, md; + + mx = abs(x2 - x1); + if (mx > 15) mx = 15; + my = abs(y2 - y1); + if (my > 15) my = 15; + md = Dirs[my][mx]; + + if (x1 > x2) { + if (y1 > y2) md = lrtoul[md]; + else md = urtoll[md]; + } else { + if (y1 > y2) md = lltour[md]; + else md = ultolr[md]; + } + + return (md); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static int GetDirection16(int x1, int y1, int x2, int y2) +{ + const BYTE Dirs[16][16] = { + { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0 + { 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1 + { 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2 + { 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // 3 + { 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 4 + { 4, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 5 + { 4, 4, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 }, // 6 + { 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 }, // 7 + { 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }, // 8 + { 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1 }, // 9 + { 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1 }, // 10 + { 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1 }, // 11 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }, // 12 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }, // 13 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2 }, // 14 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2 }};// 15 + + BYTE const lrtoul[5] = { 6, 7, 8, 9, 10 }; + BYTE const urtoll[5] = { 6, 5, 4, 3, 2 }; + BYTE const lltour[5] = { 14, 13, 12, 11, 10 }; + BYTE const ultolr[5] = { 14, 15, 0, 1, 2 }; + + + int mx = abs(x2 - x1); + if (mx > 15) mx = 15; + + int my = abs(y2 - y1); + if (my > 15) my = 15; + + int md = Dirs[my][mx]; + + if (x1 > x2) { + if (y1 > y2) md = lrtoul[md]; + else md = urtoll[md]; + } else { + if (y1 > y2) md = lltour[md]; + else md = ultolr[md]; + } + + return (md); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DeleteMissile(int mi, int i) +{ + app_assert(nummissiles <= MAXMISSILES); + missileavail[MAXMISSILES - nummissiles] = mi; + --nummissiles; + + if ((nummissiles > 0) && (i != nummissiles)) { + app_assert(i < MAXMISSILES); + missileactive[i] = missileactive[nummissiles]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void GetMissileVel(int i, int sx, int sy, int dx, int dy, int v) +{ + app_assert(i < MAXMISSILES && i >= 0); + + double const dxp = (((dx - sx) << 5) - ((dy - sy) << 5)) << 16; + double const dyp = (((dx - sx) << 5) + ((dy - sy) << 5)) << 16; + double const dr = sqrt((dxp * dxp) + (dyp * dyp)); + + missile[i]._mixvel = static_cast(((v << 16) * dxp) / dr); + missile[i]._miyvel = static_cast(((v << 15) * dyp) / dr); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void PutMissile(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + int const mx = missile[i]._mix; + int const my = missile[i]._miy; + + if (mx <= 0 || my <= 0 || mx >= DMAXX || my >= DMAXY) + missile[i]._miDelFlag = TRUE; + + if (!missile[i]._miDelFlag) { + dFlags[mx][my] |= BFLAG_MISSILE; + if (dMissile[mx][my] == 0) dMissile[mx][my] = static_cast(i + 1); + else dMissile[mx][my] = -1; + if (missile[i]._miPreFlag) MissilePreFlag = TRUE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static BYTE GetDirNum(int mi) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + return (misfiledata[(missile[mi]._miAnimType)].mAnimFAmt >= 8) ? missile[mi]._mimfnum : 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void GetMissilePos(int i) +{ + long mx, my; + long dx, dy; + long lx, ly; // lighting offsets + + app_assert(i < MAXMISSILES && i >= 0); + mx = missile[i]._mitxoff >> 16; + my = missile[i]._mityoff >> 16; + dx = (mx + (my << 1)); + dy = ((my << 1) - mx); + + if (dx < 0) { + lx = -((-dx) >> 3); + dx = -((-dx) >> 6); + } else { + lx = dx >> 3; + dx = dx >> 6; + } + + if (dy < 0) { + ly = -((-dy) >> 3); + dy = -((-dy) >> 6); + } else { + ly = dy >> 3; + dy = dy >> 6; + } + + missile[i]._mix = dx + missile[i]._misx; + missile[i]._miy = dy + missile[i]._misy; + missile[i]._mixoff = mx - ((dx - dy) << 5); + missile[i]._miyoff = my - ((dx + dy) << 4); + ChangeLightOff(missile[i]._mlid, lx - (dx << 3), ly - (dy << 3)); +} + +/*-----------------------------------------------------------------------* + * MoveMissilePos + * + * Adjusts missile's drawing location to prevent overlapping tiles + * Written specifically for monster missiles (e.g., Rhino), which are large. +**-----------------------------------------------------------------------*/ + +static void MoveMissilePos(int i) +{ + int dx,dy; + int mx,my; + + app_assert(i < MAXMISSILES && i >= 0); + switch (missile[i]._mimfnum) { + case 0 : // Down + dx = 1; + dy = 1; + break; + case 1 : // Down Left + dx = 1; + dy = 1; + break; + case 2 : // Left + dx = 0; + dy = 1; + break; + case 3 : // Up Left + dx = 0; + dy = 0; + break; + case 4 : // Up + dx = 0; + dy = 0; + break; + case 5 : // Up Right + dx = 0; + dy = 0; + break; + case 6 : // Right + dx = 1; + dy = 0; + break; + case 7 : // Down Right + dx = 1; + dy = 1; + break; + } + + mx = missile[i]._mix + dx; + my = missile[i]._miy + dy; + + // note -- _misource is the monster which became this missile + if (PosOkMonst(missile[i]._misource,mx,my)) { + missile[i]._mix += dx; + missile[i]._miy += dy; + missile[i]._mixoff -= ((dx - dy) << 5); + missile[i]._miyoff -= ((dx + dy) << 4); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, byte shift) +{ + int hit, hper; + long dam; + int mor; // monster's resist type + int mir; + BOOL resist = FALSE; + BOOL ret; + + app_assert(m < MAXMONSTERS && m >= 0); + if (monster[m].mtalkmsg != 0) return FALSE; + + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) return FALSE; + + app_assert(monster[m].MType != NULL); + if(monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MG_RUN_AWAY) + return FALSE; + + if (monster[m]._mmode == MM_MISSILE) return(FALSE); + + mir = missiledata[t].mResist; + mor = monster[m].mMagicRes; + if( (mor & M_IM && mir == MIMT_MISC) + || (mor & M_IF && mir == MIMT_FIRE) + || (mor & M_IL && mir == MIMT_LGHT)) + return FALSE; + + if( (mor & M_RM && mir == MIMT_MISC) + || (mor & M_RF && mir == MIMT_FIRE) + || (mor & M_RL && mir == MIMT_LGHT)) + resist = TRUE; + + hit = random(68, 100); + hper = 90 - monster[m].mArmorClass - dist; + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (CheckMonsterHit(m, ret)) + return(ret); +#if CHEATS + else if((hit < hper) || simplecheat || cheatflag || (monster[m]._mmode == MM_STONE)) { +#else + else if((hit < hper) || (monster[m]._mmode == MM_STONE)) { +#endif + dam = random(68, maxdam - mindam + 1) + mindam; + if (shift == 0) dam = dam << HP_SHIFT; + if (resist) + monster[m]._mhitpoints -= dam >> 2; + else + monster[m]._mhitpoints -= dam; + +#if CHEATS + if (simplecheat || cheatflag) monster[m]._mhitpoints = 0; +#endif + // rjs - x2 dam if stone - if (monster[m]._mmode == MM_STONE) monster[m]._mhitpoints -= dam; + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) { + if (monster[m]._mmode == MM_STONE) { + M_StartKill(m, -1); + monster[m]._mmode = MM_STONE; + } else M_StartKill(m, -1); + } + else if(resist) + { + PlayEffect(m, MS_GOTHIT); + } + else + { + if (monster[m]._mmode == MM_STONE) { + if (m > 3) M_StartHit(m, -1, dam); // dont let golems get hit + monster[m]._mmode = MM_STONE; + } else { + if (m > 3) M_StartHit(m, -1, dam); // dont let golems get hit + } + } + return(TRUE); + } else return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, byte shift) +{ + int hit, hper; + long dam; + int mor; // monster's resist type + int mir; // missile resistance category + BOOL resist = FALSE; + BOOL ret; + + app_assert(m < MAXMONSTERS && m >= 0); + if (monster[m].mtalkmsg != 0) return(FALSE); + + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) return(FALSE); + + app_assert(monster[m].MData != NULL); + if ((t == MIT_HBOLT) && + (monster[m].MType->mtype != MT_DIABLO) && + (monster[m].MData->mMonstClass != MC_UNDEAD)) return(FALSE); + + app_assert(monster[m].MType != NULL); + if(monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MG_RUN_AWAY) + return FALSE; + + if (monster[m]._mmode == MM_MISSILE) return(FALSE); + + mir = missiledata[t].mResist; + mor = monster[m].mMagicRes; + if( (mor & M_IM && mir == MIMT_MISC) + || (mor & M_IF && mir == MIMT_FIRE) + || (mor & M_IL && mir == MIMT_LGHT) + || (mor & M_IA && mir == MIMT_ACID)) + return FALSE; + + if( (mor & M_RM && mir == MIMT_MISC) + || (mor & M_RF && mir == MIMT_FIRE) + || (mor & M_RL && mir == MIMT_LGHT)) + resist = TRUE; + + if (t == MIT_HBOLT) + { + if ((monster[m].MType->mtype == MT_DIABLO) || + (monster[m].MType->mtype == MT_BONED2)) + resist = TRUE; + } + + hit = random(69, 100); + if (pnum != -1) { + if (missiledata[t].mType == MIS_WEAP) { + hper = BASE_TO_HIT + plr[pnum]._pLevel - monster[m].mArmorClass - plr[pnum]._pIEnAc; + hper += plr[pnum]._pDexterity + plr[pnum]._pIBonusToHit; + hper -= (dist * dist) >> 1; + if (plr[pnum]._pClass == CLASS_ROGUE) hper += 20; + if (plr[pnum]._pClass == CLASS_WARRIOR + || plr[pnum]._pClass == CLASS_BARD) hper += 10; + } else { + hper = BASE_TO_HIT + plr[pnum]._pMagic - (monster[m].mLevel << 1) - dist; + if (plr[pnum]._pClass == CLASS_SORCEROR) hper += 20; + else if (plr[pnum]._pClass == CLASS_BARD) hper += 10; + } + } + else { + hper = random(71,75) - (monster[m].mLevel * 2); + } + + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (monster[m]._mmode == MM_STONE) hit = 0; + if (CheckMonsterHit(m, ret)) + return(ret); +#if CHEATS + else if((hit < hper) || cheatflag || simplecheat) { +#else + else if (hit < hper) { +#endif + if (t == MIT_BONESPIRIT) + dam = (monster[m]._mhitpoints / 3) >> HP_SHIFT; + else + dam = random(70, maxdam - mindam + 1) + mindam; + if (missiledata[t].mType == MIS_WEAP) { + dam += (dam * plr[pnum]._pIBonusDam) / 100; + dam += plr[pnum]._pIBonusDamMod; + if (plr[pnum]._pClass == CLASS_ROGUE) dam += plr[pnum]._pDamageMod; + else dam += (plr[pnum]._pDamageMod >> 1); + } + if (shift == 0) dam = dam << HP_SHIFT; + if (resist) dam = dam >> 2; + if (pnum == myplr) monster[m]._mhitpoints -= dam; + + if (plr[pnum]._pIFlags & IAF_MNOHEAL) monster[m]._mFlags |= MFLAG_NOHEAL; +#if CHEATS + //if (pnum == myplr && cheatflag) monster[m]._mhitpoints = 0; +#endif + //rjs - x2 stone dam - if (pnum == myplr && monster[m]._mmode == MM_STONE) monster[m]._mhitpoints -= dam; + + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) { + if (monster[m]._mmode == MM_STONE) { + M_StartKill(m, pnum); + monster[m]._mmode = MM_STONE; + } else M_StartKill(m, pnum); + //(old) AddPlrExperience(pnum, monster[m].mLevel, monster[m].mExp); + //(new, but moved) AddPlrMonstExper(monster[m].mLevel, monster[m].mExp, monster[m].mWhoHit); + } + else if(resist) + { + PlayEffect(m, MS_GOTHIT); + } + else + { + if (monster[m]._mmode == MM_STONE) { + if (m > 3) M_StartHit(m, pnum, dam); + monster[m]._mmode = MM_STONE; + } else { + if ((missiledata[t].mType == MIS_WEAP) && (plr[pnum]._pIFlags & IAF_KNOCKBACK)) M_GetKnockback(m); + if (m > 3) M_StartHit(m, pnum, dam); + } + } + // wake up monster if it's inactive + if(!monster[m]._msquelch) + { + monster[m]._msquelch = 255; + monster[m]._lastx = plr[pnum]._px; + monster[m]._lasty = plr[pnum]._py; + } + return(TRUE); + } else return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, byte shift, BOOL earflag, bool *wasBlocked) +{ + int hit, hper, tac; + long dam; + int blk, blkper, blkdir; + int resper = 0; + + *wasBlocked = false; + app_assert(pnum < MAX_PLRS && pnum >= 0); + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) return(FALSE); + if (plr[pnum]._pInvincible) return(FALSE); + if (((plr[pnum]._pSpellFlags & SF_ETHER) != 0) && (missiledata[mtype].mType == MIS_WEAP)) return(FALSE); + + hit = random(72, 100); +#if CHEATS + if (simplecheat || cheatflag) hit = 1000; +#endif + if (missiledata[mtype].mType == MIS_WEAP) { + // rjs tac = (byte)plr[pnum]._pArmorClass + plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + tac += (plr[pnum]._pDexterity / 5); + if (m != -1) hper = 30 + monster[m].mHit - tac + ((monster[m].mLevel - plr[pnum]._pLevel) << 1) - (dist << 1); + else hper = 100 - (tac >> 1) - (dist << 1); + } else { + if (m != -1) hper = 40 + (monster[m].mLevel << 1) - (plr[pnum]._pLevel << 1) - (dist << 1); + else hper = 40; + } + if (hper < 10) hper = 10; + if ((currlevel == 14) && (hper < 20)) hper = 20; + if ((currlevel == 15) && (hper < 25)) hper = 25; + if ((currlevel == 16) && (hper < 30)) hper = 30; + if (((plr[pnum]._pmode == PM_STAND) || (plr[pnum]._pmode == PM_ATTACK)) && (plr[pnum]._pBlockFlag)) blk = random(73, 100); + else blk = 100; + if (shift == 1) blk = 100; // can't block continous damage spells + if (mtype == MIT_ACIDPUD) blk = 100; // can't block acid puddles (drb) + if (m != -1) blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[m].mLevel - plr[pnum]._pLevel) << 1); + else blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity; + if (blkper < 0) blkper = 0; + if (blkper > 100) blkper = 100; + switch(missiledata[mtype].mResist) { + case MIMT_FIRE: + resper = plr[pnum]._pFireResist; + break; + case MIMT_LGHT: + resper = plr[pnum]._pLghtResist; + break; + case MIMT_MISC: + case MIMT_ACID: + resper = plr[pnum]._pMagResist; + break; + default: + resper = 0; + break; + } + if (hit < hper) { + // Hit, so calc damage + if (mtype == MIT_BONESPIRIT) { + dam = plr[pnum]._pHitPoints / 3; + } else { + if (shift == 0) { + dam = (maxd - mind + 1) << HP_SHIFT; + dam = random(75, dam) + (mind << HP_SHIFT); + if (plr[pnum]._pIFlags & IAF_TRAPDAM) dam = dam >> 1; + dam += (plr[pnum]._pIGetHit << HP_SHIFT); + if (dam < (1 << HP_SHIFT)) dam = (1 << HP_SHIFT); + } else { + dam = maxd - mind + 1; + dam = random(75, dam) + mind; + if (plr[pnum]._pIFlags & IAF_TRAPDAM) dam = dam >> 1; + dam += plr[pnum]._pIGetHit; + if (dam < (1 << HP_SHIFT)) dam = (1 << HP_SHIFT); + } + } + + // Did I block? + if (blk < blkper) { + if (m != -1) blkdir = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[m]._mx, monster[m]._my); + else blkdir = plr[pnum]._pdir; + *wasBlocked = true; + StartPlrBlock(pnum, blkdir); + return(TRUE); + } + // Did I resist? + if (resper > 0) { + dam -= (dam * resper) / 100; + if (pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - plr[pnum]._pHitPoints = 0; + StartPlrKill(pnum, earflag); + } + else { + // No get hit + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySfxLoc(PS_MAGE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySfxLoc(PS_MONK69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySfxLoc(PS_BARD69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySfxLoc(PS_BARBARIAN69, plr[pnum]._px, plr[pnum]._py); + #endif + + //PlaySfxLoc(PS_LGHIT, plr[pnum]._px, plr[pnum]._py); + drawhpflag = TRUE; + } + return(TRUE); + } else { + if (pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - plr[pnum]._pHitPoints = 0; + StartPlrKill(pnum, earflag); + } else StartPlrHit(pnum, dam, FALSE); + return(TRUE); + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, byte shift, bool *wasBlocked) +{ + int hit, hper, tac; + long dam; + int blk, blkper, blkdir; + int resper; + + // pnum is missiles source + // p is missiles dest + + app_assert(p < MAX_PLRS && p >= 0); + *wasBlocked = false; + if (plr[p]._pInvincible) return(FALSE); + if (mtype == MIT_HBOLT) return(FALSE); + if (((plr[p]._pSpellFlags & SF_ETHER) != 0) && (missiledata[mtype].mType == MIS_WEAP)) return(FALSE); + + switch(missiledata[mtype].mResist) { + case MIMT_FIRE: + resper = plr[p]._pFireResist; + break; + case MIMT_LGHT: + resper = plr[p]._pLghtResist; + break; + case MIMT_MISC: + case MIMT_ACID: + resper = plr[p]._pMagResist; + break; + default: + resper = 0; + break; + } + hit = random(69, 100); + if (missiledata[mtype].mType == MIS_WEAP) { + //rjs tac = (byte)plr[p]._pArmorClass + plr[p]._pIAC + plr[p]._pIBonusAC; + tac = plr[p]._pIAC + plr[p]._pIBonusAC; + tac += (plr[p]._pDexterity / 5); + hper = BASE_TO_HIT + plr[pnum]._pLevel - tac; + hper += plr[pnum]._pDexterity + plr[pnum]._pIBonusToHit; + hper -= (dist * dist) >> 1; + if (plr[pnum]._pClass == CLASS_ROGUE) hper += 20; + if (plr[pnum]._pClass == CLASS_WARRIOR + || plr[pnum]._pClass == CLASS_BARD) hper += 10; + } else { + hper = BASE_TO_HIT + plr[pnum]._pMagic - (plr[p]._pLevel << 1) - dist; + if (plr[pnum]._pClass == CLASS_SORCEROR ) hper += 20; + else if (plr[pnum]._pClass == CLASS_BARD) hper += 10; + } + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (hit < hper) { + // Hit, calc blk % + if (((plr[p]._pmode == PM_STAND) || (plr[p]._pmode == PM_ATTACK)) && (plr[p]._pBlockFlag)) blk = random(73, 100); + else blk = 100; + if (shift == 1) blk = 100; // can't block continous damage spells + blkper = plr[p]._pBaseToBlk + plr[p]._pDexterity - ((plr[pnum]._pLevel - plr[p]._pLevel) << 1); + if (blkper < 0) blkper = 0; + if (blkper > 100) blkper = 100; + // Hit, so calc damage + if (mtype == MIT_BONESPIRIT) { + dam = plr[p]._pHitPoints / 3; + } else { + dam = random(70, maxdam - mindam + 1) + mindam; + if (missiledata[mtype].mType == MIS_WEAP) { + dam += (dam * plr[pnum]._pIBonusDam) / 100; + dam += plr[pnum]._pIBonusDamMod + plr[pnum]._pDamageMod; + } + if (shift == 0) dam = dam << HP_SHIFT; + } + // NEW! Take 1/2 damage from plr spells (drb 11/23) + if (missiledata[mtype].mType != MIS_WEAP) dam = dam >> 1; + // Did I resist? + if (resper > 0) { + dam -= (dam * resper) / 100; + // No get hit + if (pnum == myplr) NetSendCmdDamage(TRUE, p, dam); + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySfxLoc(PS_MAGE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySfxLoc(PS_MONK69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySfxLoc(PS_BARD69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySfxLoc(PS_BARBARIAN69, plr[pnum]._px, plr[pnum]._py); + #endif + + //PlaySfxLoc(PS_LGHIT, plr[p]._px, plr[p]._py); + return(TRUE); + } else { + // Did I block? + if (blk < blkper) { + blkdir = GetDirection(plr[p]._px, plr[p]._py, plr[pnum]._px, plr[pnum]._py); + StartPlrBlock(p, blkdir); + *wasBlocked = true; + return(TRUE); + } else { + if (pnum == myplr) NetSendCmdDamage(TRUE, p, dam); + StartPlrHit(p, dam, FALSE); + return(TRUE); + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void CheckMissileCol(int i, int mindam, int maxdam, byte shift, int mx, int my, byte nodel) +{ + int pn,oi; + BOOL earflag; + bool wasBlocked; + + if (!(i < MAXMISSILES && i >= 0)) return; + if (!(mx < MAXDUNX && mx >= 0)) return; + if (!(my < MAXDUNY && my >= 0)) return; + + if (missile[i]._micaster == MI_ENEMYBOTH || missile[i]._misource == -1){ + // Traps and fire and lightning walls. + if (dMonster[mx][my] > 0) { + if (missile[i]._micaster == MI_ENEMYBOTH) { + if (MonsterMHit(missile[i]._misource, dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } else { + if (MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + } + if (dPlayer[mx][my] > 0) { + if (missile[i]._miAnimType == MF_FIRE + || missile[i]._miAnimType == MF_LIGHTNING) earflag = TRUE; + else earflag = FALSE; + if (PlayerMHit(dPlayer[mx][my] - 1, -1, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, earflag, &wasBlocked)) { + if (wasBlocked) + { + int newdir = missile[i]._mimfnum + (random(10, 2) ? 1 : -1); + int numdirsAvail = misfiledata[missile[i]._miAnimType].mAnimFAmt; + if (newdir < 0) + newdir = numdirsAvail - 1; + else if (newdir > numdirsAvail) + newdir = 0; + + SetMissDir(i, newdir); // Changes the animation, but the missile keeps going. + } + else + { + if (nodel == 0) missile[i]._mirange = 0; + } + missile[i]._miHitFlag = TRUE; + } + } + } else { + if (missile[i]._micaster == MI_ENEMYMONST) { + if (dMonster[mx][my] > 0) { + if (MonsterMHit(missile[i]._misource, dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } else { + if ((dMonster[mx][my] < 0) && (monster[-(dMonster[mx][my] + 1)]._mmode == MM_STONE)) { + if (MonsterMHit(missile[i]._misource, -(dMonster[mx][my] + 1), mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + } + if ((dPlayer[mx][my] > 0) && ((dPlayer[mx][my]-1) != missile[i]._misource)) { + if (Plr2PlrMHit(missile[i]._misource, dPlayer[mx][my]-1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift, &wasBlocked)) { + if (wasBlocked) + { + int newdir = missile[i]._mimfnum + (random(10, 2) ? 1 : -1); + int numdirsAvail = misfiledata[missile[i]._miAnimType].mAnimFAmt; + if (newdir < 0) + newdir = numdirsAvail - 1; + else if (newdir > numdirsAvail) + newdir = 0; + + SetMissDir(i, newdir); // Changes the animation, but the missile keeps going. + } + else + { + if (nodel == 0) missile[i]._mirange = 0; + } + missile[i]._miHitFlag = TRUE; + } + } + } else { + if (((monster[missile[i]._misource]._mFlags & MFLAG_MID) != 0) && ((dMonster[mx][my] > 0) && (monster[(dMonster[mx][my] - 1)]._mFlags & MFLAG_MKILLER) != 0)) { + if (MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + if (dPlayer[mx][my] > 0) { + if (PlayerMHit(dPlayer[mx][my] - 1, missile[i]._misource, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, FALSE, &wasBlocked)) { + if (wasBlocked) + { + int newdir = missile[i]._mimfnum + (random(10, 2) ? 1 : -1); + int numdirsAvail = misfiledata[missile[i]._miAnimType].mAnimFAmt; + if (newdir < 0) + newdir = numdirsAvail - 1; + else if (newdir > numdirsAvail) + newdir = 0; + + SetMissDir(i, newdir); // Changes the animation, but the missile keeps going. + } + else + { + if (nodel == 0) missile[i]._mirange = 0; + } + missile[i]._miHitFlag = TRUE; + } + } + } + } + + if (dObject[mx][my] != 0) { + if (dObject[mx][my] > 0) oi = dObject[mx][my] - 1; + else oi = -(dObject[mx][my] + 1); + if (!object[oi]._oMissFlag) { + if (object[oi]._oBreak == OBJ_BREAKABLE) BreakObject(-1, oi); + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = FALSE; + } + } + + pn = dPiece[mx][my]; + app_assert(pn <= MAXTILES && pn >= 0); + if (nMissileTable[pn]) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = FALSE; + } + + if ((missile[i]._mirange == 0) && (missiledata[missile[i]._mitype].miSFX != -1)) { + PlaySfxLoc(missiledata[missile[i]._mitype].miSFX, missile[i]._mix, missile[i]._miy); + } +} + +static void SetMissAnim(int mi, int animtype) +{ + int dir; + + app_assert(mi < MAXMISSILES && mi >= 0); + dir = missile[mi]._mimfnum; + missile[mi]._miAnimType = animtype; + + missile[mi]._miAnimFlags = misfiledata[animtype].mFlags; + missile[mi]._miAnimData = misfiledata[animtype].mAnimData[dir]; + missile[mi]._miAnimDelay = misfiledata[animtype].mAnimDelay[dir]; + missile[mi]._miAnimLen = misfiledata[animtype].mAnimLen[dir]; + missile[mi]._miAnimWidth = misfiledata[animtype].mAnimWidth[dir]; + missile[mi]._miAnimWidth2 = misfiledata[animtype].mAnimWidth2[dir]; + missile[mi]._miAnimCnt = 0; + missile[mi]._miAnimFrame = 1; +} + + +void SetMissDir(int mi, int dir) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mimfnum = dir; + SetMissAnim(mi, missile[mi]._miAnimType); +} + +/*-----------------------------------------------------------------------** +**---------------------- Initialization Routines ------------------------** +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +void ILoadMissileGFX(BYTE mf) { + int i; + char strbuff[256]; + BYTE *p; + MisFileData * pMisDat; + + pMisDat = &misfiledata[mf]; + if (pMisDat->mFlags & MFF_MULTI) { + // All directions are packed into one file + sprintf(strbuff,"Missiles\\%s" CEL_EXT, pMisDat->mAnimPath); + p = LoadFileInMemSig(strbuff,NULL,'MISS'); + for (i = 0; i < pMisDat->mAnimFAmt; ++i) + pMisDat->mAnimData[i] = p + (reinterpret_cast(p))[i]; + } + else if (pMisDat->mAnimFAmt == 1) { + sprintf(strbuff,"Missiles\\%s" CEL_EXT, pMisDat->mAnimPath); + if(! pMisDat->mAnimData[0]) + pMisDat->mAnimData[0] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } + else { + for (i = 0; i < pMisDat->mAnimFAmt; ++i) { + sprintf(strbuff, "Missiles\\%s%i" CEL_EXT, pMisDat->mAnimPath, i + 1); + if(! pMisDat->mAnimData[i]) + pMisDat->mAnimData[i] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +void ILoadMissileGFX(BYTE mf) { + int i; + char strbuff[256]; + BYTE *p; + + if (misfiledata[mf].mFlags & MFF_MULTI) { + // All directions are packed into one file + sprintf(strbuff,"Missiles\\%s.CEL", misfiledata[mf].mAnimPath); + p = LoadFileInMemSig(strbuff,NULL,'MISS'); + for (i = 0; i < misfiledata[mf].mAnimFAmt; ++i) { + misfiledata[mf].mAnimData[i] = p + *reintrepret_cast(p + (i<<2)); + } + } + else if (misfiledata[mf].mAnimFAmt == 1) { + sprintf(strbuff,"Missiles\\%s.CEL", misfiledata[mf].mAnimPath); + if(! misfiledata[mf].mAnimData[0]) + misfiledata[mf].mAnimData[0] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } else { + for (i = 0; i < misfiledata[mf].mAnimFAmt; ++i) { + sprintf(strbuff, "Missiles\\%s%i.CEL", misfiledata[mf].mAnimPath, i + 1); + if(! misfiledata[mf].mAnimData[i]) + misfiledata[mf].mAnimData[i] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitMissileGFX() +{ + int i; + + for (i = 0; misfiledata[i].mAnimFAmt; ++i) { + if (!(misfiledata[i].mFlags & MFF_MONSTONLY)) { + ILoadMissileGFX(i); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void FreeMissileFile(int i) +{ + int j; + void * y; + + if (misfiledata[i].mFlags & MFF_MULTI) + { + if(misfiledata[i].mAnimData[0]) + { + y = static_cast (misfiledata[i].mAnimData[0] - (misfiledata[i].mAnimFAmt << 2)); + DiabloFreePtr(y); + misfiledata[i].mAnimData[0] = NULL; + } + } + else + { + for (j = 0; j < misfiledata[i].mAnimFAmt; ++j) + if(misfiledata[i].mAnimData[j]) + { + DiabloFreePtr(misfiledata[i].mAnimData[j]); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeMissileGFX() +{ + int i; + + for (i = 0; misfiledata[i].mAnimFAmt; ++i) { + if (!(misfiledata[i].mFlags & MFF_MONSTONLY)) { + FreeMissileFile(i); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void IFreeMissileGFX() +{ + int i; + + for (i = 0; misfiledata[i].mAnimFAmt; ++i) + if(misfiledata[i].mFlags & MFF_MONSTONLY) + FreeMissileFile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitMissiles() +{ + int i, j, mx; + + // Delete any active infravision/ etheralize + HighLightAllItems = false; + plr[myplr]._pSpellFlags &= ~SF_ETHER; + if (plr[myplr]._pInfraFlag == TRUE) { + app_assert(nummissiles <= MAXMISSILES); + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + app_assert(mx < MAXMISSILES && mx >= 0); + if ((missile[mx]._mitype == MIT_INFRA) && (missile[mx]._misource == myplr)) + CalcPlrItemVals(missile[mx]._misource,TRUE); + } + } + + if (((plr[myplr]._pSpellFlags & SF_RAGE) == SF_RAGE) + || ((plr[myplr]._pSpellFlags & SF_LETHERGY) == SF_LETHERGY)) + { + plr[myplr]._pSpellFlags &= ~SF_RAGE; + plr[myplr]._pSpellFlags &= ~SF_LETHERGY; + app_assert(nummissiles <= MAXMISSILES); + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + app_assert(mx < MAXMISSILES && mx >= 0); + if ((missile[mx]._mitype == MIT_RAGE) && (missile[mx]._misource == myplr)) + { + int const diffHpts = plr[myplr]._pMaxHP - plr[myplr]._pHitPoints; + CalcPlrItemVals(myplr,TRUE); + plr[myplr]._pHitPoints -= missile[mx]._miVar2 + diffHpts; + if (plr[myplr]._pHitPoints < (1 << HP_SHIFT)) { + // Don't quite die. + plr[myplr]._pHitPoints = 1 << HP_SHIFT; + } + } + } + } + + nummissiles = 0; + for (i = 0; i < MAXMISSILES; ++i) { + missileavail[i] = i; + missileactive[i] = 0; + } + + nummissilevars = 0; + for (i = 0; i < MAXMISSILES; ++i) { + missilevars[i][0] = -1; + missilevars[i][1] = 0; + missilevars[i][2] = 0; + } + + for (j = 0; j < DMAXY; ++j) { + for (i = 0; i < DMAXX; ++i) { + dFlags[i][j] = dFlags[i][j] & ~BFLAG_MISSILE; + } + } + + // Zero out all the reflect spells. + //for (j = 0; j < gbMaxPlayers; ++j) { + // plr[j]._pReflectCount = 0; + //} + plr[myplr]._pReflectCount = 0; +} + +/*-----------------------------------------------------------------------** +**------------------ Missile Initialization Routines --------------------** +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddReallyBigExp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + AddMissile (80, 62, 80, 62, midir, MIT_BIGEXPLOSION, mienemy, id, dam, 0); + AddMissile (80, 63, 80, 62, midir, MIT_BIGEXPLOSION, mienemy, id, dam, 0); + AddMissile (81, 62, 80, 62, midir, MIT_BIGEXPLOSION, mienemy, id, dam, 0); + AddMissile (81, 63, 80, 62, midir, MIT_BIGEXPLOSION, mienemy, id, dam, 0); + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfFire(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (LineClear(sx, sy, dx, dy)) + { + if (id >= 0) { + UseMana(id, SPL_RUNEOFFIRE); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_BIGEXPLOSION; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + } + else missile[mi]._miDelFlag = TRUE; + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfLight(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (LineClear(sx, sy, dx, dy)) + { + if (id >= 0) { + UseMana(id, SPL_RUNEOFLIGHT); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_LIGHTBALL; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + } + else missile[mi]._miDelFlag = TRUE; + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (LineClear(sx, sy, dx, dy)) + { + if (id >= 0) { + UseMana(id, SPL_RUNEOFNOVA); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_NOVA; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + } + else missile[mi]._miDelFlag = TRUE; + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfImmolation(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (LineClear(sx, sy, dx, dy)) + { + if (id >= 0) { + UseMana(id, SPL_RUNEOFIMMOLATION); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_IMMOLATION; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + + } + else missile[mi]._miDelFlag = TRUE; + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (LineClear(sx, sy, dx, dy)) + { + if (id >= 0) { + UseMana(id, SPL_RUNEOFSTONE); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_STONE; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + } + else missile[mi]._miDelFlag = TRUE; + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddReflect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + if (plr[id]._pReflectCount < 0) + plr[id]._pReflectCount = 0; + + plr[id]._pReflectCount += ((missile[mi]._mispllvl) ? missile[mi]._mispllvl : 2 ) * plr[id]._pLevel; + UseMana(id, SPL_REFLECT); + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = FALSE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBerserk(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._misource = id; + + // search in a 5 radius around tile clicked for monster + for (int k = 0; k < 6; ++k) { + int const l = CrawlNum[k]; + int j = l + 1; + for (int i = CrawlTable[l]; i > 0; --i, j += 2) { + int const tx = dx + CrawlTable[j]; + int const ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int mid = dMonster[tx][ty]; + if (mid > 0) --mid; + else mid = -(mid + 1); + + if ((mid > 3) + && (monster[mid]._uniqtype == 0) + && (monster[mid]._mAi != AI_DIABLO) + && (monster[mid]._mmode != MM_FADEIN) + && (monster[mid]._mmode != MM_FADEOUT) + //&& (monster[mid]._mmode != MM_DEATH) + && ((monster[mid].mMagicRes & M_IM) == 0) + && (((monster[mid].mMagicRes & M_RM) == 0) || + (((monster[mid].mMagicRes & M_RM) == M_RM) && 0 == random(99, 2))) + && (monster[mid]._mmode != MM_MISSILE)) { + i = -99; + k = 6; + int const SpellLevel = GetSpellLevel(id, SPL_BERSERK); + monster[mid]._mFlags |= MFLAG_BERSERK | MFLAG_MKILLER; + monster[mid].mMinDamage = static_cast(SpellLevel + monster[mid].mMinDamage * (1.0 + (0.01 * (random(145,10) + 20)))); + monster[mid].mMaxDamage = static_cast(SpellLevel + monster[mid].mMaxDamage * (1.0 + (0.01 * (random(145,10) + 20)))); + monster[mid].mMinDamage2 = static_cast(SpellLevel + monster[mid].mMinDamage2 * (1.0 + (0.01 * (random(145,10) + 20)))); + monster[mid].mMaxDamage2 = static_cast(SpellLevel + monster[mid].mMaxDamage2 * (1.0 + (0.01 * (random(145,10) + 20)))); + + monster[mid].mlid = AddLight(monster[mid]._mx, monster[mid]._my, + ((currlevel >= HIVESTART && currlevel <= HIVEEND) ? 9 : 3)); + + UseMana(id, SPL_BERSERK); + break; + } + } + } + } + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddHorkSpawn(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + + GetMissileVel(mi, sx, sy, dx, dy, 8); + missile[mi]._mirange = 9; + missile[mi]._miVar1 = midir; + PutMissile(mi); +} + +void AddRandom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + + // Let the random spell do the call, otherwise staff's use up 2 charges. + // if (id >= 0) { + // UseMana(id, SPL_RANDOM); + // } + int mitype = MIT_FIREBOLT; + int const r = random(255, 10); + switch(r) + { + case 0: // fall through + case 1: mitype = MIT_FIREBOLT; break; + case 2: mitype = MIT_FIREBALL; break; + case 3: mitype = MIT_FIREWALLC; break; + case 4: mitype = MIT_GUARDIAN; break; + case 5: mitype = MIT_CHAIN; break; + case 6: mitype = MIT_TOWN; UseMana(id, SPL_TOWN); break; + case 7: mitype = MIT_TELE; break; + case 8: mitype = MIT_APOCA; break; + case 9: mitype = MIT_STONE; break; + default: break; + } + AddMissile (sx, sy, dx, dy, midir, mitype, + missile[mi]._micaster, missile[mi]._misource, + 0, missile[mi]._mispllvl); + + missile[mi]._miDelFlag = TRUE; + missile[mi]._mirange = 0; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddDisEnchant(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._misource = id; + + // search in a 3 radius around chest trap for players. + for (int k = 0; k < 3; ++k) { + int const l = CrawlNum[k]; + int j = l + 1; + for (int i = CrawlTable[l]; i > 0; --i, j += 2) { + int const tx = sx + CrawlTable[j]; + int const ty = sy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int pid = dPlayer[tx][ty]; + + if (pid == 0) + continue; + + if (pid > 0) --pid; + else pid = -(pid + 1); + + + int newidata; + BOOL everplayed = FALSE; + + // Belt items only. + for (int splIndex = 0; splIndex < MAXSPD; ++splIndex) + { + newidata = -1; + + if (plr[pid].SpdList[splIndex]._itype == IT_MISC) + { + int what; + int const killed = random(205, 2); + if (!killed) + continue; + + switch(plr[pid].SpdList[splIndex]._iMiscId) { + case IMID_PLHEAL: + case IMID_PMANA: + RemoveSpdBarItem(pid, splIndex); + continue; + + case IMID_REJUV: + what = random(205, 2); + switch(what) + { + case 0: + newidata = ItemMiscIdIdx(IMID_PLHEAL); + break; + default: + newidata = ItemMiscIdIdx(IMID_PMANA); + break; + } + + case IMID_PHEAL: + newidata = ItemMiscIdIdx(IMID_PLHEAL); + break; + case IMID_PFMANA: + newidata = ItemMiscIdIdx(IMID_PMANA); + break; + case IMID_FREJUV: + what = random(205, 3); + switch(what) + { + case 0: + newidata = ItemMiscIdIdx(IMID_PFMANA); + break; + case 1: + newidata = ItemMiscIdIdx(IMID_PHEAL); + break; + default: + newidata = ItemMiscIdIdx(IMID_REJUV); + break; + } + break; + + default: + continue; + } + } + if (newidata != -1) { + SetPlrHandItem(&plr[pid].HoldItem, newidata); + GetPlrHandSeed(&plr[pid].HoldItem); + plr[pid].HoldItem._iStatFlag = TRUE; + plr[pid].SpdList[splIndex] = plr[pid].HoldItem; + } + if (!everplayed) + { + PlaySfxLoc(IS_URN, tx, ty); + everplayed = TRUE; + } + } + force_redraw = FULLDRAW; + } + } + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddManaRemove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._misource = id; + + // search in a 3 radius around chest trap for players. + for (int k = 0; k < 3; ++k) { + int const l = CrawlNum[k]; + int j = l + 1; + for (int i = CrawlTable[l]; i > 0; --i, j += 2) { + int const tx = sx + CrawlTable[j]; + int const ty = sy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int pid = dPlayer[tx][ty]; + + if (pid == 0) + continue; + + if (pid > 0) --pid; + else pid = -(pid + 1); + + plr[pid]._pMana = 0; + plr[pid]._pManaBase = plr[pid]._pMana - (plr[pid]._pMaxMana - plr[pid]._pMaxManaBase); + CalcPlrInv(pid, FALSE); + drawmanaflag = TRUE; + PlaySfxLoc(TSFX_COW7, tx, ty); + } + } + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES && mi >= 0); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + if (mienemy == MI_ENEMYMONST) { + int av=32; + if (plr[id]._pClass == CLASS_ROGUE) av += plr[id]._pLevel>>2; + else if (plr[id]._pClass == CLASS_WARRIOR + || plr[id]._pClass == CLASS_BARD) av += plr[id]._pLevel>>3; + if (plr[id]._pIFlags & IAF_ATANIM1) av += 1; + if (plr[id]._pIFlags & IAF_ATANIM2) av += 2; + if (plr[id]._pIFlags & IAF_ATANIM3) av += 4; + if (plr[id]._pIFlags & IAF_ATANIM4) av += 8; + + GetMissileVel(mi,sx,sy,dx,dy,av); + } else GetMissileVel(mi,sx,sy,dx,dy,32); + + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 5); + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int av; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + if (mienemy == MI_ENEMYMONST) { + av = 32; + if (plr[id]._pIFlags & IAF_RNDARROW) av = random(64, 32) + 16; // rnd arrow speed + if (plr[id]._pClass == CLASS_ROGUE) av += (plr[id]._pLevel-1) >> 2; // rouge level speed increase + else if (plr[id]._pClass == CLASS_WARRIOR + || plr[id]._pClass == CLASS_BARD) av += (plr[id]._pLevel-1) >> 3; // warrior level speed increase + + if (plr[id]._pIFlags & IAF_ATANIM1) av += 1; + if (plr[id]._pIFlags & IAF_ATANIM2) av += 2; + if (plr[id]._pIFlags & IAF_ATANIM3) av += 4; + if (plr[id]._pIFlags & IAF_ATANIM4) av += 8; + + GetMissileVel(mi,sx,sy,dx,dy,av); + } else GetMissileVel(mi,sx,sy,dx,dy,32); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miAnimFrame = GetDirection16(sx,sy,dx,dy) + 1; + + missile[mi]._mirange = 256; + + //PutMissile(mi); +} + +void AddSpecialArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int extraspeed = 0; + +// if ((sx == dx) && (sy == dy)) { +// dx += XDirAdd[midir]; +// dy += YDirAdd[midir]; +// } + + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) + { + if (plr[id]._pClass == CLASS_ROGUE) + extraspeed = (plr[id]._pLevel-1) >> 2; // rogue level speed increase + else if (plr[id]._pClass == CLASS_WARRIOR + || plr[id]._pClass == CLASS_BARD) + extraspeed = (plr[id]._pLevel-1) >> 3; // warrior level speed increase + + if (plr[id]._pIFlags & IAF_ATANIM1) extraspeed += 1; + if (plr[id]._pIFlags & IAF_ATANIM2) extraspeed += 2; + if (plr[id]._pIFlags & IAF_ATANIM3) extraspeed += 4; + if (plr[id]._pIFlags & IAF_ATANIM4) extraspeed += 8; + } + + missile[mi]._mirange = 1; + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._miVar3 = extraspeed; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetVileMissPos(int mi, int dx, int dy) +{ + int xx, yy; + app_assert(mi < MAXMISSILES && mi >= 0); + for (int l = 1; l < 50; ++l) { + for (int j = -l; j <= l; ++j) { + yy = dy + j; + for (int i = -l; i <= l; ++i) { + xx = dx + i; + if (PosOkPlayer(myplr,xx,yy)) { + missile[mi]._mix = xx; + missile[mi]._miy = yy; + return; + } + } + } + } + // There is just no way it will ever reach here + missile[mi]._mix = dx; + missile[mi]._miy = dy; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define DIST(x,y,d) (abs(x) < d && abs(y) < d) + +// Flag for fireman missile +#define MIF_DIDHIT 1 + +#define MINAWAY 3 +#define MAXAWAY 6 + +void AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_PHASE) || !PRE_BETA + int pn, r1, r2; + + int nTries = 0; + do { + // don't get stuck in an infinite loop... + if (++nTries > 500) { + r1 = 0; + r2 = 0; + break; + } + + r1 = random(58, MAXAWAY - MINAWAY) + MINAWAY + 1; + r2 = random(58, MAXAWAY - MINAWAY) + MINAWAY + 1; + if (random(58, 2) == 1) r1 = -r1; + if (random(58, 2) == 1) r2 = -r2; + + r1 = sx + r1; + r2 = sy + r2; + + if (r1 > MAXDUNX + || r1 < 0 + || r2 > MAXDUNY + || r2 < 0) + continue; + + pn = dPiece[r1][r2]; + } while (nSolidTable[pn] != 0 + || dObject[r1][r2] != 0 + || dMonster[r1][r2] != 0); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = 2; + missile[mi]._miVar1 = 0; + +// special code for Vile Betrayer quest + if ((setlevel) && (setlvlnum == 5)) { + int oi = dObject[dx][dy]-1; + if ((object[oi]._otype == OBJ_MCIRCLE1) || (object[oi]._otype == OBJ_MCIRCLE2)) { + missile[mi]._mix = dx; + missile[mi]._miy = dy; + if (!PosOkPlayer(myplr, dx, dy)) GetVileMissPos(mi, dx, dy); + } + } + else { + missile[mi]._mix = r1; + missile[mi]._miy = r2; + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_PHASE); + } + +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +#undef max +void AddTeleStairs(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int minDist = std::numeric_limits::is_specialized && std::numeric_limits::is_bounded + ? std::numeric_limits::max() : 99999; + if (id >= 0) { + sx = plr[id]._px; + sy = plr[id]._py; + } + + int rx = sx; + int ry = sy; + + for (int i = 0;i < numtrigs && i < MAXTRIGGERS; ++i) { + if (trigs[i]._tmsg == WM_DIABTWARPUP + || trigs[i]._tmsg == WM_DIABPREVLVL + || trigs[i]._tmsg == WM_DIABNEXTLVL + || trigs[i]._tmsg == WM_DIABRTNLVL) { + + int triggerx; + int triggery; + + if ((leveltype == 1 || leveltype == 2) + && (trigs[i]._tmsg == WM_DIABNEXTLVL + || trigs[i]._tmsg == WM_DIABPREVLVL + || trigs[i]._tmsg == WM_DIABRTNLVL) ){ + triggerx = trigs[i]._tx; + triggery = trigs[i]._ty + 1; + } + else { + triggerx = trigs[i]._tx + 1; + triggery = trigs[i]._ty; + } + + int xdiff = sx - triggerx; + xdiff *= xdiff; + int ydiff = sy - triggery; + ydiff *= ydiff; + int const NewDist = xdiff + ydiff; + + if (NewDist < minDist) + { + minDist = NewDist; + rx = triggerx; + ry = triggery; + } + + } + } + + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = 2; + missile[mi]._miVar1 = 0; + missile[mi]._mix = rx; + missile[mi]._miy = ry; + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_TELESTAIRS); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBOLT) || !PRE_BETA + int sp, i, mx; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + + app_assert(mi < MAXMISSILES && mi >= 0); + if (micaster == MI_ENEMYMONST) + { + app_assert(nummissiles <= MAXMISSILES); + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + app_assert(mx < MAXMISSILES && mx >= 0); + if ((missile[mx]._mitype == MIT_GUARDIAN) && + (missile[mx]._misource == id) && (missile[mx]._miVar3 == mi)) { + break; + } + } + if (i == nummissiles) UseMana(id, SPL_FIREBOLT); + + if (id != -1) { + sp = 16 + (missile[mi]._mispllvl << 1); + if (sp >= 63) sp = 63; + } else sp = 16; + } + else + sp = 26; + + GetMissileVel(mi,sx,sy,dx,dy,sp); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES && mi >= 0); + // Graphics don't line up, so we have to move them... + missile[mi]._mitxoff += 3*missile[mi]._mixvel; + missile[mi]._mityoff += 3*missile[mi]._miyvel; + + GetMissilePos(mi); + + if ((missile[mi]._mixvel >> 16) == 0 + && (missile[mi]._miyvel >> 16) == 0) + { + missile[mi]._mirange = 1; + } + else + { + missile[mi]._mirange = 256; + } + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddKrull(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; +// missile[mi]._mlid = AddLight(sx, sy, 8); + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_TELE) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty; + + app_assert(dx < MAXDUNX && dx >= 0); + app_assert(dy < MAXDUNY && dy >= 0); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty] | dPlayer[tx][ty]) == 0) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + k = 6; + break; + } + } + j += 2; + } + } + + if (missile[mi]._miDelFlag == FALSE) { + UseMana(id, SPL_TELE); + missile[mi]._mirange = 2; + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = dam; + + missile[mi]._miAnimFrame = random(63, 8) + 1; + + missile[mi]._mirange = 255; + + if (id < 0) { + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + } else { + missile[mi]._miVar1 = plr[id]._px; + missile[mi]._miVar2 = plr[id]._py; + } + + //PutMissile(mi); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLightwall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = dam; + + missile[mi]._miAnimFrame = random(63, 8) + 1; + + missile[mi]._mirange = 255 + (255 * missile[mi]._mispllvl); + + if (id < 0) { + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + } else { + missile[mi]._miVar1 = plr[id]._px; + missile[mi]._miVar2 = plr[id]._py; + } + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = (random(53, 10) + random(53, 10) + 2 + (id > 0) ? plr[id]._pLevel : currlevel) << 4; + missile[mi]._midam = missile[mi]._midam >> 1; + + GetMissileVel(mi,sx,sy,dx,dy,16); + + missile[mi]._mirange = 10 * (missile[mi]._mispllvl + 1); + + if (mienemy != MI_ENEMYMONST || id < 0) // trap or somesuch + { + missile[mi]._mirange = missile[mi]._mirange + currlevel; + } + else + { + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + } + missile[mi]._mirange = missile[mi]._mirange << 4; + + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) + { + missile[mi]._midam = (random(60, 10) + random(60, 10) + 2 + plr[id]._pLevel) << 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + + i = 16 + (missile[mi]._mispllvl << 1); + if (i > 50) i = 50; + + UseMana(id, SPL_FIREBALL); + } + else + { + i = 16; + } + + GetMissileVel(mi,sx,sy,dx,dy,i); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = sx; + missile[mi]._miVar5 = sy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBigExplosion(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST || mienemy == MI_ENEMYBOTH) + { + missile[mi]._midam = (random(60, 10) + random(60, 10) + 2 + plr[id]._pLevel) << 1; + for (int i = missile[mi]._mispllvl; i > 0; --i) + { + missile[mi]._midam += (missile[mi]._midam >> 3); + } + + dam = missile[mi]._midam; + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix-1, missile[mi]._miy-1, 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix , missile[mi]._miy-1, 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix+1, missile[mi]._miy-1, 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix-1, missile[mi]._miy , 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix , missile[mi]._miy , 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix+1, missile[mi]._miy , 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix-1, missile[mi]._miy+1, 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix , missile[mi]._miy+1, 1); + CheckMissileCol(mi, dam, dam, 0, missile[mi]._mix+1, missile[mi]._miy+1, 1); + } + + missile[mi]._mlid = AddLight(sx, sy, 8); + SetMissDir(mi, 0); + missile[mi]._miDelFlag = FALSE; + + missile[mi]._mirange = missile[mi]._miAnimLen - 1; + + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddSpiralFireBall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) + { + missile[mi]._midam = (random(60, 10) + random(60, 10) + 2 + plr[id]._pLevel) << 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + + i = 16 + (missile[mi]._mispllvl << 1); + if (i > 50) i = 50; + + UseMana(id, SPL_FIREBALL); + } + else + { + i = 16; + } + + GetMissileVel(mi,sx,sy,dx,dy,i); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = sx; + missile[mi]._miVar5 = sy; + missile[mi]._miVar6 = 2; + missile[mi]._miVar7 = 2; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddFBArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) + { + i = 16 + missile[mi]._mispllvl; + if (i > 50) i = 50; + +// UseMana(id, SPL_FIREBALL); + } + else + { + i = 16; + } + + GetMissileVel(mi,sx,sy,dx,dy,i); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = sx; + missile[mi]._miVar5 = sy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (dam == 0 && mienemy == MI_ENEMYMONST) UseMana(id, SPL_LIGHTNING); // if not 0 - probably is chain lightning + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + + GetMissileVel(mi,sx,sy,dx,dy,32); + + missile[mi]._miAnimFrame = random(52, 8) + 1; + + missile[mi]._mirange = 256; +} + +void AddLTArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi,sx,sy,dx,dy,32); + missile[mi]._miAnimFrame = random(52, 8) + 1; + + missile[mi]._mirange = 255; + + if (id < 0) { + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + } else { + missile[mi]._miVar1 = plr[id]._px; + missile[mi]._miVar2 = plr[id]._py; + } + + missile[mi]._midam <<= HP_SHIFT; + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + // Note: midir is used to pass in the missile # of the root of the lightning chain. + // A negative midir means that this is not part of a chain. + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._misx = dx; + missile[mi]._misy = dy; + + if(midir >= 0) + { + missile[mi]._mixoff = missile[midir]._mixoff; + missile[mi]._miyoff = missile[midir]._miyoff; + missile[mi]._mitxoff = missile[midir]._mitxoff; + missile[mi]._mityoff = missile[midir]._mityoff; + } + + missile[mi]._miAnimFrame = random(52, 8) + 1; + + if (midir >= 0 && mienemy != MI_ENEMYPLR && id != -1) { + missile[mi]._mirange = 6 + (missile[mi]._mispllvl >> 1); + } else { + if (midir >= 0 && id != -1) { + missile[mi]._mirange = 10; + } else missile[mi]._mirange = 8; + } + + missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 4); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + + if (mienemy != MI_ENEMYMONST && id > 0) { + app_assert(id < MAXMONSTERS); + app_assert(monster[id].MType != NULL); + switch (monster[id].MType->mtype) + { + case MT_SUCCUBUS: + SetMissAnim(mi,MF_FLAREXP); + break; + case MT_SNOWWICH: + SetMissAnim(mi,MF_BFLAREXP); + break; + case MT_HLSPWN: + SetMissAnim(mi,MF_DFLAREXP); + break; + case MT_SOLBRNR: + SetMissAnim(mi,MF_CFLAREXP); + break; + } + } + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mix = missile[dx]._mix; + missile[mi]._miy = missile[dx]._miy; + missile[mi]._misx = missile[dx]._misx; + missile[mi]._misy = missile[dx]._misy; + missile[mi]._mixoff = missile[dx]._mixoff; + missile[mi]._miyoff = missile[dx]._miyoff; + missile[mi]._mitxoff = missile[dx]._mitxoff; + missile[mi]._mityoff = missile[dx]._mityoff; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + + missile[mi]._mirange = missile[mi]._miAnimLen; + missile[mi]._miVar1 = 0; + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = dx; + + missile[mi]._mimfnum = 0; + if (dx == 1) SetMissAnim(mi, MF_EXP1); + else SetMissAnim(mi, MF_CBOLT); + missile[mi]._mirange = missile[mi]._miAnimLen - 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL CheckIfTrig(int x, int y) +{ + int i; + + app_assert(numtrigs <= MAXTRIGGERS); + for (i = 0; i < numtrigs; ++i) + if (((x == trigs[i]._tx) && (y == trigs[i]._ty)) || + ((abs(trigs[i]._tx-x) < 2) && (abs(trigs[i]._ty-y) < 2))) return(TRUE); + + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddTown(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_TOWN) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty, mx; + + app_assert(mi < MAXMISSILES && mi >= 0); + if (currlevel != 0) { + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + app_assert(pn <= MAXTILES && pn >= 0); + if (((nSolidTable[pn] | dObject[tx][ty] | nMissileTable[pn] | + dPlayer[tx][ty] | dMissile[tx][ty]) == 0) && + (!CheckIfTrig(tx, ty))) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + k = 6; + break; + } + } + j += 2; + } + } + } else { + tx = dx; + ty = dy; + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + } + + missile[mi]._mirange = 100; + missile[mi]._miVar1 = missile[mi]._mirange - (missile[mi]._miAnimLen); + missile[mi]._miVar2 = 0; + + // Move current portal? + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if ((missile[mx]._mitype == MIT_TOWN) && + (mx != mi) && + (missile[mx]._misource == id)) { + missile[mx]._mirange = 0; + } + } + + PutMissile(mi); + + if (id == myplr && missile[mi]._miDelFlag == FALSE && currlevel != 0) { + if (!setlevel) NetSendCmdLocParam3(TRUE, CMD_ACTIVATEPORTAL, tx, ty, currlevel, leveltype, FALSE); + else NetSendCmdLocParam3(TRUE, CMD_ACTIVATEPORTAL, tx, ty, setlvlnum, leveltype, TRUE); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) { + if (id != -1) { + missile[mi]._midam = 0; + for (i = 0; i <= plr[id]._pLevel; ++i) missile[mi]._midam += random(55, 20) + 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + missile[mi]._midam += missile[mi]._midam >> 1; + UseMana(id, SPL_FLASH); + } else { + missile[mi]._midam = (currlevel >> 1); + } + } + else + missile[mi]._midam = monster[id].mLevel << 1; + + missile[mi]._mirange = 19; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAura(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + +#if defined(HELLFIRE2) + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) { + if (id != -1) { + missile[mi]._midam = 0; + missile[mi]._mirange = 245 + (10 * missile[mi]._mispllvl) + (2 * (id > 0) ? plr[id]._pLevel : 1); + plr[id]._pBaseToBlk += 50; + UseMana(id, SPL_AURA); + } + } +#endif + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAura2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) { + if (id != -1) { + missile[mi]._midam = 0; + missile[mi]._mirange = 245 + (10 * missile[mi]._mispllvl) + (2 * (id > 0) ? plr[id]._pLevel : 1); + } + } + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES && mi >= 0); + if (mienemy == MI_ENEMYMONST) + { + if (id != -1) { + missile[mi]._midam = 0; + for (i = 0; i <= plr[id]._pLevel; ++i) missile[mi]._midam += random(56, 2) + 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + missile[mi]._midam += missile[mi]._midam >> 1; + } else { + missile[mi]._midam = (currlevel >> 1); + } + } + + missile[mi]._miPreFlag = TRUE; + + missile[mi]._mirange = 19; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_MANASHLD) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = ((plr[id]._pLevel << 4) << 1) + (plr[id]._pLevel << 4); + + missile[mi]._miVar1 = plr[id]._pHitPoints; + missile[mi]._miVar2 = plr[id]._pHPBase; + + missile[mi]._miVar8 = KILL_UNKNOWN; // killed by unknown source (inited) + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_MANASHLD); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = random(59, 10) + 1 + plr[id]._pLevel; + + GetMissileVel(mi,sx,sy,dx,dy,16); + + missile[mi]._mirange = 255; + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + + ++missile[mi]._mix; + ++missile[mi]._miy; + missile[mi]._miyoff-=32; +//PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_GUARDIAN) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = random(62, 10) + 1 + (plr[id]._pLevel >> 1); + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + app_assert(tx < MAXDUNX && tx >= 0); + app_assert(ty < MAXDUNY && ty >= 0); + pn = dPiece[tx][ty]; + app_assert(pn <= MAXTILES); + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + //if ((dFlags[tx][ty] & BFLAG_VISIBLE) && + if ((LineClear(sx, sy, tx, ty)) && + ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty] | nMissileTable[pn] | dMissile[tx][ty]) == 0)) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + UseMana(id, SPL_GUARDIAN); + k = 6; + break; + } + } + j += 2; + } + } + + if (missile[mi]._miDelFlag == TRUE) return; + missile[mi]._misource = id; + missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 1); + + missile[mi]._mirange = (plr[id]._pLevel >> 1) + missile[mi]._mispllvl; + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + if (missile[mi]._mirange > 30) missile[mi]._mirange = 30; + missile[mi]._mirange = missile[mi]._mirange << 4; + if (missile[mi]._mirange < 30) missile[mi]._mirange = 30; + + missile[mi]._miVar1 = missile[mi]._mirange - (missile[mi]._miAnimLen); + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 1; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddChain(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_CHAIN) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + + missile[mi]._mirange = 1; + UseMana(id, SPL_CHAIN); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddChainOLD(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, k, j, mx; + + if (dam == 0) { + k = 0; + j = -1; + for (i = 0; i < nummissilevars; ++i) { + mx = missilevars[i][0]; + if (mx >= 0 && missile[mx]._mitype == MIT_CHAIN && missile[mx]._miVar8 > k) k = missile[mx]._miVar8; + if (mx < 0) j = i; + } + ++k; + missile[mi]._miVar8 = k; + if (j == -1) { + ++nummissilevars; + j = nummissilevars; + } + missilevars[j][0] = mi; + missilevars[j][1] = MIT_CHAIN; + missilevars[j][2] = 0; + } else { + for (i = 0; i < nummissilevars; ++i) { + mx = missilevars[i][0]; + if (mx >= 0 && missile[mx]._mitype == MIT_CHAIN && missile[mx]._miVar8 == dam) missilevars[i][2]++; + } + } + + k = 0; + missile[mi]._midam = 0; + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if (missile[mx]._mitype == MIT_CHAIN && missile[mx]._midam > k) k = missile[mx]._midam; + if (missile[mx]._mitype == MIT_CHAINBALL && missile[mx]._miVar1 > k) k = missile[mx]._miVar1; + } + ++k; + missile[mi]._midam = k; + + missile[mi]._mirange = 12 + GetSpellLevel(id, SPL_LIGHTNING); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._miVar5 = dx; + missile[mi]._miVar6 = dy; + missile[mi]._miVar7 = 0; + + UseMana(id, SPL_CHAIN); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddChainballOLD(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, mx; + + missile[mi]._miVar1 = dam; + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if ((missile[mx]._mitype == MIT_CHAIN) && (missile[mx]._miVar2 == 1) && (missile[mx]._midam == dam)) { + missile[mi]._miVar2 = missile[mx]._miVar2; + missile[mi]._miVar3 = missile[mx]._miVar3; + missile[mi]._miVar4 = missile[mx]._miVar4; + } + if ((missile[mx]._mitype == MIT_CHAIN) && (missile[mx]._midam == dam)) + missile[mi]._miVar8 = missile[mx]._miVar8; + } + + if (dMonster[sx][sy] != 0) { + missile[mi]._miVar5 = sx; + missile[mi]._miVar6 = sy; + } else { + missile[mi]._miVar5 = 0; + missile[mi]._miVar6 = 0; + } + + missile[mi]._midam = (random(61, plr[id]._pLevel) + random(61, 6) + 4) << HP_SHIFT; + + GetMissileVel(mi, sx, sy, dx, dy, 16); + + missile[mi]._mirange = ((plr[id]._pLevel << 4) << 1) + (GetSpellLevel(id, SPL_CHAIN) << 4); + + PutMissile(mi); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBlood(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + SetMissDir(mi, str); + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = 0; + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = 250; + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBone(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + if (str > 3) str = 2; + SetMissDir(mi, str); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = 0; + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = 250; + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMetal(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + if (str > 3) str = 2; + SetMissDir(mi, str); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = 0; + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = (missile[mi]._miAnimLen); + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + AnimStruct *anim; + + app_assert(id < MAXMONSTERS && id >= 0); + app_assert(monster[id].MType != NULL); + if (EquivMonst(monster[id].MType->mtype, MT_HORNED)) + anim = &monster[id].MType->Anims[MA_SPECIAL]; + else if (EquivMonst(monster[id].MType->mtype, MT_NSNAKE)) + anim = &monster[id].MType->Anims[MA_ATTACK]; + else + anim = &monster[id].MType->Anims[MA_WALK]; + + GetMissileVel(mi,sx,sy,dx,dy,18); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mimfnum = midir; + missile[mi]._miAnimFlags = NULL; + missile[mi]._miAnimData = anim->Cels[midir]; + missile[mi]._miAnimDelay = anim->Rate; + missile[mi]._miAnimLen = anim->Frames; + missile[mi]._miAnimWidth = monster[id].MType->mAnimWidth; + missile[mi]._miAnimWidth2 = monster[id].MType->mAnimWidth2; + missile[mi]._miAnimAdd = 1; + if (EquivMonst(monster[id].MType->mtype, MT_NSNAKE)) + missile[mi]._miAnimFrame = 7; + + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + + missile[mi]._miLightFlag = TRUE; + if(monster[id]._uniqtype) { + missile[mi]._miUniqTrans = monster[id]._uniqtrans+1; + missile[mi]._mlid = monster[id].mlid; + } + + missile[mi]._mirange = 256; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFireman(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + AnimStruct *anim; + + app_assert(id < MAXMONSTERS && id >= 0); + app_assert(monster[id].MType != NULL); + anim = &monster[id].MType->Anims[MA_WALK]; + + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mimfnum = midir; + missile[mi]._miAnimFlags = NULL; + missile[mi]._miAnimData = anim->Cels[midir]; + missile[mi]._miAnimDelay = anim->Rate; + missile[mi]._miAnimLen = anim->Frames; + missile[mi]._miAnimWidth = monster[id].MType->mAnimWidth; + missile[mi]._miAnimWidth2 = monster[id].MType->mAnimWidth2; + missile[mi]._miAnimAdd = 1; + + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + + missile[mi]._miLightFlag = TRUE; + if(monster[id]._uniqtype) + missile[mi]._miUniqTrans = monster[id]._uniqtrans+1; + + dMonster[monster[id]._mx][monster[id]._my] = 0; + + missile[mi]._mirange = 256; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int d; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + if (mienemy == MI_ENEMYMONST) { + UseMana(id, SPL_BSTAR); + d = 5; + //for (k = missile[mi]._mispllvl; k > 0; --k) d -= 1; + //if (d <= 0) d = 1; +#if CHEATS + if (simplecheat || cheatflag) d = 0; +#endif + + plr[id]._pHitPoints -= (d << HP_SHIFT); + plr[id]._pHPBase -= (d << HP_SHIFT); + drawhpflag = TRUE; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + } else { + if (id > 0) { + if (monster[id].MType->mtype == MT_SUCCUBUS) SetMissAnim(mi,MF_FLARE); + if (monster[id].MType->mtype == MT_SNOWWICH) SetMissAnim(mi,MF_BFLARE); + if (monster[id].MType->mtype == MT_HLSPWN) SetMissAnim(mi,MF_DFLARE); + if (monster[id].MType->mtype == MT_SOLBRNR) SetMissAnim(mi,MF_CFLARE); + } + } + + if (misfiledata[missile[mi]._miAnimType].mAnimFAmt == 16) { + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + } + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + app_assert(mi < MAXMISSILES && mi >= 0); + if ((missile[mi]._mixvel >> 16) == 0 + && (missile[mi]._miyvel >> 16) == 0) + { + missile[mi]._mirange = 1; + } + else + { + missile[mi]._mirange = 15 + 5*(monster[id]._mint+1); + } + missile[mi]._mlid = -1; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddDoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, j, k, l; + int mid; + + // search in a 5 radius around tile clicked for monster + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + mid = dMonster[(dx + CrawlTable[j])][(dy + CrawlTable[(j + 1)])]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + if ((monster[mid]._mhitpoints >> HP_SHIFT) > 0) { + missile[mi]._miVar1 = dx + CrawlTable[j]; + missile[mi]._miVar2 = dy + CrawlTable[j + 1]; + missile[mi]._miVar3 = mid; + i = -99; + k = 6; + break; + } + } + j += 2; + } + } + + // if no monsters found in search + if (i != -99) { + missile[mi]._miDelFlag = TRUE; + return; + } + + GetMissileVel(mi, sx, sy, missile[mi]._miVar1, missile[mi]._miVar2, 16); + SetMissDir(mi, GetDirection(sx, sy, missile[mi]._miVar1, missile[mi]._miVar2)); + + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._misource = id; + missile[mi]._midam = 26; + + missile[mi]._mirange = ((plr[id]._pLevel << 4) >> 2) + (plr[id]._pLevel << 4) ; + for (i = GetSpellLevel(id, SPL_DOOM); i > 0; --i) missile[mi]._mirange += ((missile[mi]._mirange << 4) >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + UseMana(id, SPL_DOOM); + PutMissile(mi); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFireonly(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = dam; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + + missile[mi]._mirange = 50; + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int monst; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + + missile[mi]._mixoff = 0; + missile[mi]._miyoff = 0; +/* + missile[mi]._misx = missile[dx]._misx; + missile[mi]._misy = missile[dx]._misy; + missile[mi]._mixoff = missile[dx]._mixoff; + missile[mi]._miyoff = missile[dx]._miyoff; + missile[mi]._mitxoff = missile[dx]._mitxoff; + missile[mi]._mityoff = missile[dx]._mityoff; +*/ + + missile[mi]._miLightFlag = TRUE; + +// MoveMissilePos(mi); + + monst = missile[mi]._misource; + missile[mi]._mirange = random(50,15) + 40*(monster[monst]._mint + 1); + + missile[mi]._miPreFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_STONE) || !PRE_BETA + int i, j, k, l, tx, ty; + int mid; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._misource = id; + + // search in a 5 radius around tile clicked for monster + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + mid = dMonster[tx][ty]; + if (mid > 0) --mid; + else mid = -(mid + 1); + if ((mid > 3) + && (monster[mid]._mAi != AI_DIABLO) + && (monster[mid].MType->mtype != MT_NKR) + && (monster[mid]._mmode != MM_FADEIN) + && (monster[mid]._mmode != MM_FADEOUT) + //&& (monster[mid]._mmode != MM_DEATH) + && (monster[mid]._mmode != MM_MISSILE)) { + i = -99; + k = 6; + missile[mi]._miVar1 = monster[mid]._mmode; + missile[mi]._miVar2 = mid; + monster[mid]._mmode = MM_STONE; + break; + } + } + j += 2; + } + } + + // if no monsters found in search + if (i != -99) { + missile[mi]._miDelFlag = TRUE; + return; + } + + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = missile[mi]._mix; + missile[mi]._misy = missile[mi]._miy; + + missile[mi]._mirange = 6 + missile[mi]._mispllvl; + //if (missile[mi]._mirange == 0) missile[mi]._mirange = 1; + //for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._mirange += (missile[mi]._mirange >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + if (missile[mi]._mirange > 15) missile[mi]._mirange = 15; + missile[mi]._mirange = missile[mi]._mirange << 4; + UseMana(id, SPL_STONE); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddInvis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + missile[mi]._mirange = plr[id]._pLevel << 4; + for (i = GetSpellLevel(id, SPL_INVIS); i > 0; --i) missile[mi]._mirange += ((missile[mi]._mirange << 4) >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + UseMana(id, SPL_INVIS); + missile[mi]._miDelFlag = TRUE; +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_GOLEM) || !PRE_BETA + int i, mx; + //int tx, ty, k, j, l; + + app_assert(mi < MAXMISSILES && mi >= 0); + + missile[mi]._miDelFlag = FALSE; + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if ((missile[mx]._mitype == MIT_GOLEM) && (mx != mi) && + (missile[mx]._misource == id)) { + missile[mi]._miDelFlag = TRUE; + return; + } + } + + /*for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if ((LineClear(sx, sy, tx, ty)) && + ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty]) == 0)) {*/ + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + if ((monster[id]._mx != 1 || monster[id]._my != 0) && (id == myplr)) M_StartKill(id, id); + //missile[mi]._miDelFlag = FALSE; + UseMana(id, SPL_GOLEM); + /*k = 6; + break; + } + } + j += 2; + } + }*/ +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddEther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_ETHER) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = (plr[id]._pLevel << 4) >> 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._mirange += (missile[mi]._mirange >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + missile[mi]._miVar1 = plr[id]._pHitPoints; + missile[mi]._miVar2 = plr[id]._pHPBase; + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_ETHER); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBloodR(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_BLOODR) || !PRE_BETA + int manaval; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + return; // spell deleted - left code here just in case + + if (!(plr[id]._pIFlags & IAF_LMANA)) { + plr[id]._pHitPoints -= (10 << HP_SHIFT); + plr[id]._pHPBase -= (10 << HP_SHIFT); + + manaval = ((missile[mi]._mispllvl + 8) << MANA_SHIFT); + plr[id]._pMana += manaval; + plr[id]._pManaBase += manaval; + + if (plr[id]._pMana > plr[id]._pMaxMana) plr[id]._pMana = plr[id]._pMaxMana; + if (plr[id]._pManaBase > plr[id]._pMaxManaBase) plr[id]._pManaBase = plr[id]._pMaxManaBase; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + } + + UseMana(id, SPL_BLOODR); + drawhpflag = TRUE; + missile[mi]._miDelFlag = TRUE; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddSpurt(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = dam; + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._misource = id; + + if (dam == 1) + SetMissDir(mi, 0); + else + SetMissDir(mi, 1); + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = missile[mi]._miAnimLen; + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mix = dx; + missile[mi]._miy = dy; + missile[mi]._misx = dx; + missile[mi]._misy = dy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._midam = dam; + + missile[mi]._mirange = missile[mi]._miAnimLen; + missile[mi]._miVar1 = 0; + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEAL) || !PRE_BETA + int i; + long l; + + l = (random(57, 10) + 1) << HP_SHIFT; + for (i = 0; i < plr[id]._pLevel; ++i) l += ((random(57, 4) + 1) << HP_SHIFT); + app_assert(mi < MAXMISSILES && mi >= 0); + for (i = 0; i < missile[mi]._mispllvl; ++i) l += ((random(57, 6) + 1) << HP_SHIFT); + if (plr[id]._pClass == CLASS_WARRIOR + || plr[id]._pClass == CLASS_BARBARIAN + || plr[id]._pClass == CLASS_MONK) l = l << 1; + if (plr[id]._pClass == CLASS_ROGUE + || plr[id]._pClass == CLASS_BARD) l += (l >> 1); + plr[id]._pHitPoints += l; + if (plr[id]._pHitPoints > plr[id]._pMaxHP) plr[id]._pHitPoints = plr[id]._pMaxHP; + plr[id]._pHPBase += l; + if (plr[id]._pHPBase > plr[id]._pMaxHPBase) plr[id]._pHPBase = plr[id]._pMaxHPBase; + + UseMana(id, SPL_HEAL); + drawhpflag = TRUE; + + missile[mi]._miDelFlag = TRUE; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMana(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEAL) || !PRE_BETA + int i; + long l; + + l = (random(57, 10) + 1) << MANA_SHIFT; + for (i = 0; i < plr[id]._pLevel; ++i) l += ((random(57, 4) + 1) << MANA_SHIFT); + app_assert(mi < MAXMISSILES && mi >= 0); + for (i = 0; i < missile[mi]._mispllvl; ++i) l += ((random(57, 6) + 1) << MANA_SHIFT); + if (plr[id]._pClass == CLASS_SORCEROR) l = l << 1; + if (plr[id]._pClass == CLASS_ROGUE + || plr[id]._pClass == CLASS_BARD) l += (l >> 1); + + plr[id]._pMana += l; + if (plr[id]._pMana > plr[id]._pMaxMana) plr[id]._pMana = plr[id]._pMaxMana; + plr[id]._pManaBase += l; + if (plr[id]._pManaBase > plr[id]._pMaxManaBase) plr[id]._pManaBase = plr[id]._pMaxManaBase; + + UseMana(id, SPL_MANA); + drawmanaflag = TRUE; + + missile[mi]._miDelFlag = TRUE; + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddFMana(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEAL) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + plr[id]._pMana = plr[id]._pMaxMana; + plr[id]._pManaBase = plr[id]._pMaxManaBase; + UseMana(id, SPL_FMANA); + drawmanaflag = TRUE; +#endif + missile[mi]._miDelFlag = TRUE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEALOTHER) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_HEALOTHER); + if (id == myplr) { + NewCursor(HEALOTHER_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddElement(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_ELEMENT) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + //missile[mi]._midam = 0; + //for (i = 0; i < plr[id]._pLevel; ++i) missile[mi]._midam += random(67, 6) + 1; + //for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = (random(60, 10) + random(60, 10) + 2 + plr[id]._pLevel) << 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + missile[mi]._midam = missile[mi]._midam >> 1; + + GetMissileVel(mi, sx, sy, dx, dy, 16); + SetMissDir(mi, GetDirection8(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + UseMana(id, SPL_ELEMENT); + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_IDENTIFY) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_IDENTIFY); + if (id == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(IDENTIFY_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + //if ((dFlags[tx][ty] & BFLAG_VISIBLE) && ((sx != tx) || (sy != ty)) && + if ((LineClear(sx, sy, tx, ty)) && ((sx != tx) || (sy != ty)) && + ((nSolidTable[pn] | dObject[tx][ty]) == 0)) { + missile[mi]._miVar1 = tx; + missile[mi]._miVar2 = ty; + missile[mi]._miVar5 = tx; + missile[mi]._miVar6 = ty; + missile[mi]._miDelFlag = FALSE; + k = 6; + break; + } + } + j += 2; + } + } + + if (missile[mi]._miDelFlag == TRUE) return; + + missile[mi]._miVar7 = 0; + missile[mi]._miVar8 = 0; + + //midir = GetDirection(sx, sy, tx, ty); + missile[mi]._miVar3 = (midir - 2) & 0x0007; + missile[mi]._miVar4 = (midir + 2) & 0x0007; + + missile[mi]._mirange = 7; + UseMana(id, SPL_WALL); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlameBox(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + + if (mienemy == MI_ENEMYMONST){ + UseMana(id, SPL_RINGOFFIRE); + } + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miDelFlag = FALSE; + + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._miVar5 = 0; + missile[mi]._miVar6 = 0; + missile[mi]._miVar7 = 0; + missile[mi]._miVar8 = 0; + + missile[mi]._mirange = 7; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddShowMagicItems(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = FALSE; + + missile[mi]._miVar1 = id; + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._miVar5 = 0; + missile[mi]._miVar6 = 0; + missile[mi]._miVar7 = 0; + missile[mi]._miVar8 = 0; + + HighLightAllItems = true; + missile[mi]._mirange = 245 + (10 * missile[mi]._mispllvl) + (2 * (id > 0) ? plr[id]._pLevel : 1); + if (mienemy == MI_ENEMYMONST){ + UseMana(id, SPL_SHOWMAGITEMS); + } + + for(int i = 0; i < nummissiles; ++i) { + int const miActive = missileactive[i]; + if (miActive != mi) { + MissileStruct * const pMiss = &missile[miActive]; + + if (pMiss->_miVar1 == id + && pMiss->_mitype == MIT_SHOWMAGITEMS) { + + // to prevent ridiculous overflow. + if (pMiss->_mirange < (INT_MAX - missile[mi]._mirange)) { + pMiss->_mirange += missile[mi]._mirange; + } + missile[mi]._miDelFlag = TRUE; + break; + } + } + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_INFRA) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mirange = 99 << 4; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._mirange += (missile[mi]._mirange >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_INFRA); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddWave(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WAVE) || !PRE_BETA + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._mirange = 1; + missile[mi]._miAnimFrame = 4; + UseMana(id, SPL_WAVE); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_NOVA) || !PRE_BETA + int k; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + if (id != -1) { + missile[mi]._midam = random(66, 6) + random(66, 6) + random(66, 6) + random(66, 6) + random(66, 6); + missile[mi]._midam += 5 + plr[id]._pLevel; + missile[mi]._midam = missile[mi]._midam >> 1; + for (k = missile[mi]._mispllvl; k > 0; --k) missile[mi]._midam += (missile[mi]._midam >> 3); + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_NOVA); + } else { + missile[mi]._midam = random(66, 3) + random(66, 3) + random(66, 3); + missile[mi]._midam += (currlevel >> 1); + } + missile[mi]._mirange = 1; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBoil(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + // not in game + missile[mi]._miDelFlag = TRUE; + return; +/* +#if (PRE_BETA && PRE_BLOODB) || !PRE_BETA + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._mirange = 1; +#else + missile[mi]._miDelFlag = TRUE; +#endif*/ +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRage(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id != -1) { + if ((0 == (SF_RAGE & plr[id]._pSpellFlags)) // Only one rage at a time. + && (0 == (SF_LETHERGY & plr[id]._pSpellFlags)) // Can't rage while lethargic either. + && plr[id]._pHitPoints > (plr[id]._pLevel << HP_SHIFT)) { // And not too weak. + const int Sounds[NUM_CLASSES] = { PS_WARR70, + PS_ROGUE70, + PS_MAGE70, + PS_MAGE70, // monk + PS_BARD70, + PS_BARBARIAN70 }; + UseMana(id, SPL_RAGE); + missile[mi]._miVar1 = id; + int const hps = (plr[id]._pLevel * 6) << HP_SHIFT; + plr[id]._pSpellFlags |= SF_RAGE; + missile[mi]._miVar2 = hps; + missile[mi]._mirange = 245 + (10 * missile[mi]._mispllvl) + (2 * (id > 0) ? plr[id]._pLevel : 1); + CalcPlrItemVals(id, TRUE); + force_redraw = FULLDRAW; + PlaySfxLoc(Sounds[plr[id]._pClass], plr[id]._px, plr[id]._py); + } + else { + // Too weak to become enraged. + missile[mi]._miDelFlag = TRUE; + } + } + else { + missile[mi]._miDelFlag = TRUE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_REPAIR) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_REPAIR); + if (id == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(REPAIR_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_RECHARGE) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_RECHARGE); + if (id == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(RECHARGE_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_DISARM) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_DISARM); + if (id == myplr) { + NewCursor(DISARM_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_APOCA) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miVar1 = 8; + missile[mi]._miVar2 = sy - missile[mi]._miVar1; + missile[mi]._miVar3 = sy + missile[mi]._miVar1; + missile[mi]._miVar4 = sx - missile[mi]._miVar1; + missile[mi]._miVar5 = sx + missile[mi]._miVar1; + missile[mi]._miVar6 = missile[mi]._miVar4; + + if (missile[mi]._miVar2 <= 0) missile[mi]._miVar2 = 1; + if (missile[mi]._miVar3 >= MAXDUNY) missile[mi]._miVar3 = MAXDUNY - 1; + if (missile[mi]._miVar4 <= 0) missile[mi]._miVar4 = 1; + if (missile[mi]._miVar5 >= MAXDUNX) missile[mi]._miVar5 = MAXDUNX - 1; + + for (i = 0; i < plr[id]._pLevel; ++i) missile[mi]._midam += random(67, 6) + 1; + + missile[mi]._mirange = 255; + missile[mi]._miDelFlag = FALSE; + UseMana(id, SPL_APOCA); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int seqno) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + // seqno: the number of flame chunk for this spell instance + int i; + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miVar2 = 0; + //for (i = 0; i < 2 - seqno; ++i) { + for (i = seqno; i > 0; --i) { + missile[mi]._miVar2 += 5; + } + + missile[mi]._misx = dx; + missile[mi]._misy = dy; + + missile[mi]._mixoff = missile[midir]._mixoff; + missile[mi]._miyoff = missile[midir]._miyoff; + missile[mi]._mitxoff = missile[midir]._mitxoff; + missile[mi]._mityoff = missile[midir]._mityoff; + missile[mi]._mirange = 20 + missile[mi]._miVar2; + missile[mi]._mlid = AddLight(sx, sy, 1); + + if (mienemy == MI_ENEMYMONST) { + missile[mi]._midam = (random(79, plr[id]._pLevel) + random(79, 2) + 2) << 3; + missile[mi]._midam += missile[mi]._midam >> 1; + //missile[mi]._midam = plr[id]._pLevel << 2; + //for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + //missile[mi]._midam = missile[mi]._midam << 1 + missile[mi]._midam; + } else { + missile[mi]._midam = random(77, monster[id].mMaxDamage - monster[id].mMinDamage + 1) + monster[id].mMinDamage; + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + //int k; + //int tsx, tsy; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi, sx, sy, dx, dy, 32); + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_FLAME); + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._mirange = 256; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_CBOLT) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + if (micaster == MI_ENEMYMONST) + { + if (id == myplr) { + missile[mi]._mirnd = random(63, 15) + 1; + // INSERT send seed code + } else { + // INSERT get seed from network message for syncing + // used as a number idx not a seed so no SetRndSeed necessary + missile[mi]._mirnd = random(63, 15) + 1; + } + missile[mi]._midam = random(68, plr[id]._pMagic >> 2) + 1; + //for (i = missile[mi]._mispllvl; i > 0; --i) ++missile[mi]._midam; + } + else + { + missile[mi]._mirnd = random(63, 15) + 1; + missile[mi]._midam = 15; + } + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + missile[mi]._miAnimFrame = random(63, 8) + 1; + missile[mi]._mlid = AddLight(sx, sy, 5); + GetMissileVel(mi, sx, sy, dx, dy, 8); + + missile[mi]._miVar1 = 5; + missile[mi]._miVar2 = midir; + missile[mi]._miVar3 = 0; + + missile[mi]._mirange = 256; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddCBArrow(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_CBOLT) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + if (micaster == MI_ENEMYMONST) + { + if (id == myplr) { + missile[mi]._mirnd = random(63, 15) + 1; + // INSERT send seed code + } else { + // INSERT get seed from network message for syncing + // used as a number idx not a seed so no SetRndSeed necessary + missile[mi]._mirnd = random(63, 15) + 1; + } + } + else + { + missile[mi]._mirnd = random(63, 15) + 1; + missile[mi]._midam = 15; + } + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + missile[mi]._miAnimFrame = random(63, 8) + 1; + missile[mi]._mlid = AddLight(sx, sy, 5); + GetMissileVel(mi, sx, sy, dx, dy, 8); + + missile[mi]._miVar1 = 5; + missile[mi]._miVar2 = midir; + missile[mi]._miVar3 = 0; + + missile[mi]._mirange = 256; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_HBOLT) || !PRE_BETA + int sp; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES && mi >= 0); + if (id != -1) { + sp = 16 + (missile[mi]._mispllvl << 1); + if (sp >= 63) sp = 63; + } else sp = 16; + + GetMissileVel(mi, sx, sy, dx, dy, sp); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + missile[mi]._midam = random(69, 10) + 9 + plr[id]._pLevel; + + UseMana(id, SPL_HBOLT); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddHBArrow(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_HBOLT) || !PRE_BETA + int sp; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES && mi >= 0); + if (id != -1) { + sp = 16 + (missile[mi]._mispllvl << 1); + if (sp >= 63) sp = 63; + } else sp = 16; + + GetMissileVel(mi, sx, sy, dx, dy, sp); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_RESURRECT) || !PRE_BETA + UseMana(id, SPL_RESURRECT); + if (id == myplr) { + NewCursor(RESURRECT_CURS); + } +#endif + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_RESURRECT) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mix = dx; + missile[mi]._miy = dy; + missile[mi]._misx = missile[mi]._mix; + missile[mi]._misy = missile[mi]._miy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._mirange = misfiledata[MF_RESURRECT].mAnimLen[0]; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_TELEKINESIS) || !PRE_BETA + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_TELEKINESIS); + if (id == myplr) { + NewCursor(TELE_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int d, mid, mx, my; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi, sx, sy, dx, dy, 16); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + if (mienemy == MI_ENEMYMONST) { + UseMana(id, SPL_BONESPIRIT); + d = 6; + +#if CHEATS + if (simplecheat || cheatflag) d = 0; +#endif + + plr[id]._pHitPoints -= (d << HP_SHIFT); + plr[id]._pHPBase -= (d << HP_SHIFT); + drawhpflag = TRUE; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + + if (dPlayer[dx][dy] != 0) { + missile[mi]._miVar6 = 1; + if (dPlayer[dx][dy] > 0) mid = dPlayer[dx][dy] - 1; + else mid = -(dPlayer[dx][dy] + 1); + mx = plr[mid]._px; + my = plr[mid]._py; + } else { + missile[mi]._miVar6 = 0; + if (dMonster[dx][dy] <= 0) mid = FindClosest(sx, sy, 19); + else mid = dMonster[dx][dy] - 1; + mx = monster[mid]._mx; + my = monster[mid]._my; + } + + if (mid > 0) { + missile[mi]._miVar3 = mid; + GetMissileVel(mi, sx, sy, mx, my, 16); + SetMissDir(mi, GetDirection8(sx, sy, mx, my)); + } + } + + PutMissile(mi); +} + +*/ +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_BONESPIRIT) || !PRE_BETA + int d; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._midam = 0; + + GetMissileVel(mi, sx, sy, dx, dy, 16); + SetMissDir(mi, GetDirection8(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + if (mienemy == MI_ENEMYMONST) { + UseMana(id, SPL_BONESPIRIT); + d = 6; +#if CHEATS + if (simplecheat || cheatflag) d = 0; +#endif + plr[id]._pHitPoints -= (d << HP_SHIFT); + plr[id]._pHPBase -= (d << HP_SHIFT); + drawhpflag = TRUE; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + + missile[mi]._mirange = 100; + missile[mi]._miVar1 = missile[mi]._mirange - (missile[mi]._miAnimLen); + missile[mi]._miVar2 = 0; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + BOOL LineClear(int x1, int y1, int x2, int y2); + int pnum; + + for (pnum = 0; pnum < gbMaxPlayers; ++pnum) + { + if (plr[pnum].plractive + && LineClear(sx,sy,plr[pnum]._pfutx, plr[pnum]._pfuty)) + AddMissile(0, 0, plr[pnum]._pfutx, plr[pnum]._pfuty, 0, MIT_FIREPLAR, mienemy, id, dam, 0); + } + app_assert(mi < MAXMISSILES && mi >= 0); + missile[mi]._miDelFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int AddMissile(int sx, int sy, int v1, int v2, int midir, int mitype, char micaster, int id, int v3, int spllvl) +{ + // v1 and v2 are usually dx and dy (this can be different per missile) + // v3 is usually damage amount + + // check if exceeded number of missiles + if (nummissiles >= MAXMISSILES - 1) + return -1; + + // get next missile id that is available + int const mi = missileavail[0]; + missileavail[0] = missileavail[MAXMISSILES - nummissiles - 1]; + missileactive[nummissiles] = mi; + ++nummissiles; + + // Zero out the data first. + memset(&missile[mi], 0, sizeof(MissileStruct)); + + // do some standard missile setups + missile[mi]._mitype = mitype; + missile[mi]._micaster = micaster; + missile[mi]._misource = id; + missile[mi]._miAnimType = missiledata[mitype].mFileNum; + missile[mi]._miDrawFlag = missiledata[mitype].mDraw; + + missile[mi]._mispllvl = spllvl; + + missile[mi]._mimfnum = midir; + if (missile[mi]._miAnimType != MF_NONE + && misfiledata[(missile[mi]._miAnimType)].mAnimFAmt >= 8) + SetMissDir(mi, midir); + else + SetMissDir(mi, 0); + + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._mixoff = 0; + missile[mi]._miyoff = 0; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._mitxoff = 0; + missile[mi]._mityoff = 0; + + missile[mi]._miDelFlag = FALSE; + missile[mi]._miAnimAdd = 1; + + missile[mi]._miLightFlag = FALSE; + missile[mi]._miPreFlag = FALSE; + missile[mi]._miUniqTrans = FALSE; + missile[mi]._midam = v3; + missile[mi]._miHitFlag = FALSE; + missile[mi]._midist = 0; + missile[mi]._mlid = -1; + missile[mi]._mirnd = 0; + + if (missiledata[mitype].mlSFX != -1) + PlaySfxLoc(missiledata[mitype].mlSFX, missile[mi]._mix, missile[mi]._miy); + + missiledata[mitype].mAddProc(mi, sx, sy, v1, v2, midir, micaster, id, v3); + + return mi; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*int ChainBounceOLD (int i, int sx, int sy) +{ + int j, mi, mx, dir; + + if (dMonster[sx][sy] != 0) { + + if (dMonster[sx][sy] > 0) mi = dMonster[sx][sy] - 1; + else mi = -(dMonster[sx][sy] + 1); + + if ((monster[mi]._mhitpoints >> HP_SHIFT) > 0) { + for (j = 0; j < nummissilevars; ++j) { + mx = missilevars[j][0]; + if ((mx >= 0) && (missile[mx]._mitype == MIT_CHAIN) && (missile[mx]._miVar8 == missile[i]._miVar8) && + (missilevars[j][2] >= (plr[(missile[i]._misource)]._pLevel >> 1))) { + missilevars[j][0] = -1; + return 3; + } + } + dir = GetDirection(missile[i]._mix, missile[i]._miy, sx, sy); + AddMissile(missile[i]._mix, missile[i]._miy, sx, sy, dir, MIT_CHAIN, MI_ENEMYMONST, missile[i]._misource, missile[i]._miVar8); + return 1; + } + } + + return 0; +}*/ + +extern BOOL LineClear(int x1, int y1, int x2, int y2); +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int Sentfire(int i, int sx, int sy) +{ + int ex, dir; + + ex = 0; + app_assert(i < MAXMISSILES && i >= 0); + if (LineClear(missile[i]._mix, missile[i]._miy, sx, sy) + && (dMonster[sx][sy] > 0) + && ((monster[(dMonster[sx][sy] - 1)]._mhitpoints >> HP_SHIFT) > 0) + && ((dMonster[sx][sy]-1) > 3)) { + dir = GetDirection(missile[i]._mix, missile[i]._miy, sx, sy); + missile[i]._miVar3 = missileavail[0]; // get next mid + AddMissile(missile[i]._mix, missile[i]._miy, sx, sy, dir, MIT_FIREBOLT, MI_ENEMYMONST, missile[i]._misource, missile[i]._midam, GetSpellLevel(missile[i]._misource, SPL_FIREBOLT)); + ex = -1; + } + + if (ex == -1) { + SetMissDir(i, 2); + missile[i]._miVar2 = 3; + } + + return (ex); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Dummy(int i) +{} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_HorkSpawn(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + + + --missile[i]._mirange; + CheckMissileCol(i, 0, 0, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange <= 0) + { + missile[i]._miDelFlag = TRUE; + for (int k = 0; k<2; ++k) + { + int const l = CrawlNum[k]; + int j = l + 1; + for (int m = CrawlTable[l]; m > 0; --m, j += 2) { + int const tx = missile[i]._mix + CrawlTable[j]; + int const ty = missile[i]._miy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int const pn = dPiece[tx][ty]; + if(nSolidTable[pn] == 0 + && dMonster[tx][ty] == 0 + && dPlayer[tx][ty] == 0 + && dObject[tx][ty] == 0) { + m = -99; + k = 6; + int const hs = AddMonster(tx, ty, missile[i]._miVar1, 1, TRUE); + M_StartStand(hs, missile[i]._miVar1); + break; + } + } + } + } + } + else { + ++missile[i]._midist; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + } + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Rune(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + int const tx = missile[i]._mix; + int const ty = missile[i]._miy; + + int mid = dMonster[tx][ty]; + int pid = dPlayer[tx][ty]; + + if (mid || pid) + { + + int dir; + + if (mid != 0) + { + if (mid > 0) --mid; + else mid = -(mid + 1); + + dir = GetDirection(missile[i]._mix, missile[i]._miy, + monster[mid]._mx, monster[mid]._my); + } + else + { + if (pid > 0) --pid; + else pid = -(pid + 1); + + dir = GetDirection(missile[i]._mix, missile[i]._miy, + plr[pid]._px, plr[pid]._py); + } + + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + + AddMissile(tx, ty, tx, ty, dir, missile[i]._miVar1, MI_ENEMYBOTH, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + } + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Golem(int i) +{ +#if (PRE_BETA && PRE_GOLEM) || !PRE_BETA + int id, pn; + int j, k, l, m; + int tx, ty; + + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + + if (monster[id]._mx == 1 && monster[id]._my == 0) { + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (m = CrawlTable[l]; m > 0; --m) { + tx = missile[i]._miVar4 + CrawlTable[j]; + ty = missile[i]._miVar5 + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if ((LineClear(missile[i]._miVar1, missile[i]._miVar2, tx, ty)) && + ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty]) == 0)) { + k = 6; + SpawnGolum(id, tx, ty, i); + break; + } + } + j += 2; + } + } + } + missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_SetManashield(int i) +{ +#if (PRE_BETA && PRE_MANASHLD) || !PRE_BETA + ManashieldFlag = 1; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_LArrow(int i) +{ + int p, mind, maxd, rst; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + p = missile[i]._misource; + if (missile[i]._miAnimType != MF_CBOLT && missile[i]._miAnimType != MF_EXP1) { + ++missile[i]._midist; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + mind = plr[p]._pIMinDam; + maxd = plr[p]._pIMaxDam; + } else { + mind = monster[p].mMinDamage; + maxd = monster[p].mMaxDamage; + } + } else { + mind = currlevel + random(68, 10) + 1; + maxd = (currlevel * 2) + random(68, 10) + 1; + } + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) { + rst = missiledata[(missile[i]._mitype)].mResist; + missiledata[(missile[i]._mitype)].mResist = MIMT_NONE; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + missiledata[(missile[i]._mitype)].mResist = rst; + } + + if (missile[i]._mirange == 0) { + missile[i]._mimfnum = 0; + missile[i]._mitxoff -= missile[i]._mixvel; + missile[i]._mityoff -= missile[i]._miyvel; + GetMissilePos(i); + if (missile[i]._mitype == MIT_LARROW) { + SetMissAnim(i, MF_CBOLT); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } else { + SetMissAnim(i, MF_EXP1); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 5); + } + } + } else { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, 5 + missile[i]._miAnimFrame); + rst = missiledata[(missile[i]._mitype)].mResist; + // drb.patch1.start.02/25/97 + if (missile[i]._mitype == MIT_LARROW) { + if (p != -1) { + mind = plr[p]._pILMinDam; + maxd = plr[p]._pILMaxDam; + } else { + mind = currlevel + random(68, 10) + 1; + maxd = (currlevel * 2) + random(68, 10) + 1; + } + missiledata[MIT_LARROW].mResist = MIMT_LGHT; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 1); + } + if (missile[i]._mitype == MIT_FARROW) { + if (p != -1) { + mind = plr[p]._pIFMinDam; + maxd = plr[p]._pIFMaxDam; + } else { + mind = currlevel + random(68, 10) + 1; + maxd = (currlevel * 2) + random(68, 10) + 1; + } + missiledata[MIT_FARROW].mResist = MIMT_FIRE; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 1); + } + // endpatch1.2/25/97 + missiledata[(missile[i]._mitype)].mResist = rst; + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Arrow(int i) +{ + int p, mind, maxd; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + ++missile[i]._midist; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + p = missile[i]._misource; + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + mind = plr[p]._pIMinDam; + maxd = plr[p]._pIMaxDam; + } else { + mind = monster[p].mMinDamage; + maxd = monster[p].mMaxDamage; + } + } else { + mind = currlevel; + maxd = currlevel * 2; + } + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Firebolt(int i) +{ +#if (PRE_BETA && PRE_FIREBOLT) || !PRE_BETA + int omx, omy, d, p; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + + if (missile[i]._mitype == MIT_BONESPIRIT && missile[i]._mimfnum == 8) { + if (missile[i]._mirange == 0) { + if(missile[i]._mlid >= 0) AddUnLight(missile[i]._mlid); + missile[i]._miDelFlag = TRUE; + PlaySfxLoc(LS_BSIMPCT, missile[i]._mix, missile[i]._miy); + } + PutMissile(i); + return; + } + + omx = missile[i]._mitxoff; + omy = missile[i]._mityoff; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + p = missile[i]._misource; + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + switch(missile[i]._mitype) { + case MIT_FLARE: + d = ((plr[p]._pMagic>>1)-(plr[p]._pMagic>>3)) + (missile[i]._mispllvl << 1) + missile[i]._mispllvl; + break; + case MIT_FIREBOLT: + d = random(75, 10) + 1 + (plr[p]._pMagic >> 3) + missile[i]._mispllvl; + break; + case MIT_BONESPIRIT: + //d = (monster[missile[i]._miVar3]._mhitpoints >> HP_SHIFT) >> 1; + d = 0; + break; + } + } else d = (random(77, monster[p].mMaxDamage - monster[p].mMinDamage + 1) + monster[p].mMinDamage); + } else d = random(78, currlevel << 1) + currlevel; + + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, d, d, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + missile[i]._mitxoff = omx; + missile[i]._mityoff = omy; + GetMissilePos(i); + switch(missile[i]._mitype) { + case MIT_FLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_FLAREXP, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_FIREBOLT: + case MIT_MAGMABALL: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_MISEXP, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_YELLOWFLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_YELLOWEXPLOSION, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_REDFLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_REDEXPLOSION, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_BLUEFLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_BLUEEXPLOSION, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_BLUE2FLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_BLUE2EXPLOSION, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_ORANGEFLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_ORANGEEXPLOSION, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_ACID: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_ACIDSPLAT, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_BONESPIRIT: + SetMissDir(i, 8); + missile[i]._mirange = 7; + missile[i]._miDelFlag = FALSE; + PutMissile(i); + return; + } + if(missile[i]._mlid >= 0) AddUnLight(missile[i]._mlid); + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + if(missile[i]._mlid >= 0) ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Lightball(int i) +{ + int j, tx, ty, oi; + + app_assert(i < MAXMISSILES && i >= 0); + tx = missile[i]._miVar1; + ty = missile[i]._miVar2; + + --missile[i]._mirange; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + j = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + + // fix for shires and fireing nova - rjs + if (dObject[tx][ty] != 0 && tx == missile[i]._mix && ty == missile[i]._miy) { + if (dObject[tx][ty] > 0) oi = dObject[tx][ty] - 1; + else oi = -(dObject[tx][ty] + 1); + if (object[oi]._otype == OBJ_SHRINEL || object[oi]._otype == OBJ_SHRINER) missile[i]._mirange = j; + } + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Lightwall(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + + --missile[i]._mirange; + + int const j = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Krull(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Acidpud(int i) +{ + int range; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + +// GetMissilePos(i); + range = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + missile[i]._mirange = range; // CheckMissileCol clears range if there's a collision, + // but this missile sticks around even after a collision + +// MoveMissilePos(i); + + if (missile[i]._mirange == 0) + { + if(missile[i]._mimfnum) + missile[i]._miDelFlag = TRUE; + else + { + SetMissDir(i, 1); + missile[i]._mirange = missile[i]._miAnimLen; + } + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Firewall(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int ExpLight[14] = {2,3,4,5,5,6,7,8,9,10,11,12,12}; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + + if (missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + missile[i]._miAnimFrame = random(83, 11) + 1; + } + + if (missile[i]._mirange == missile[i]._miAnimLen - 1) { + SetMissDir(i, 0); + missile[i]._miAnimFrame = 13; + missile[i]._miAnimAdd = -1; + } + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + if ((missile[i]._mimfnum != 0) && (missile[i]._mirange != 0) && + (missile[i]._miAnimAdd != -1) && (missile[i]._miVar2 < 12)) { + + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Fireball(int i) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int dam, px, py, id, mx, my; + + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + dam = missile[i]._midam; + + //dam = missile[i]._mispllvl; // rjs test + //missiledata[(missile[i]._mitype)].mResist = MIMT_NONE; + + --missile[i]._mirange; + + if (missile[i]._micaster == MI_ENEMYMONST) { + px = plr[id]._px; + py = plr[id]._py; + } else { + px = monster[id]._mx; + py = monster[id]._my; + } + + if (missile[i]._miAnimType == MF_BIGEXP) { + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, dam, dam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + mx = missile[i]._mix; + my = missile[i]._miy; + + ChangeLight(missile[i]._mlid, mx, my, missile[i]._miAnimFrame); + + if (CheckBlock(px, py, mx , my ) == 0) CheckMissileCol(i, dam, dam, 0, mx, my, 1); + if (CheckBlock(px, py, mx , my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my + 1, 1); + if (CheckBlock(px, py, mx , my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my, 1); + if (CheckBlock(px, py, mx + 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my, 1); + if (CheckBlock(px, py, mx - 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my - 1, 1); + + //++missile[i]._mix; + //++missile[i]._miy; + //missile[i]._miyoff -= 32; + + if ((!TransList[dTransVal[mx][my]]) || + ((missile[i]._mixvel < 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff -= 32; + } + + if (((missile[i]._miyvel > 0) && + ((TransList[dTransVal[mx+1][my]] && nSolidTable[dPiece[mx+1][my]]) || + (TransList[dTransVal[mx-1][my]] && nSolidTable[dPiece[mx-1][my]])))) { + missile[i]._miyoff -= 32; + } + + if (((missile[i]._mixvel > 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + missile[i]._mixoff -= 32; + } + + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_BigExplosion(int i) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + + app_assert(i < MAXMISSILES && i >= 0); + + --missile[i]._mirange; + + if (missile[i]._mirange <= 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +#endif +} + + +/*-----------------------------------------------------------------------* + // Doesn't work yet. GWP +**-----------------------------------------------------------------------*/ +void MI_SpiralFireBall(int i) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int px, py, mx, my; + + app_assert(i < MAXMISSILES && i >= 0); + int const id = missile[i]._misource; + int const dam = missile[i]._midam; + + + int xcurve; + int ycurve; + + // Set the direction into a spiral. + if (missile[i]._miVar7 < 0) { + missile[i]._miVar6 *= 2; + missile[i]._miVar7 = missile[i]._miVar6; + + --missile[i]._mimfnum; + if (missile[i]._mimfnum < 0) + missile[i]._mimfnum = 7; + } + else --missile[i]._miVar7; + + switch (missile[i]._mimfnum) { + case 0: // Down + xcurve = missile[i]._mixvel; + ycurve = 0; + break; + case 1: // Down left + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + case 2: // Left + xcurve = 0; + ycurve = missile[i]._miyvel; + break; + case 3: // Up Left + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + case 4: // Up + xcurve = missile[i]._mixvel; + ycurve = 0; + break; + case 5: // Up right + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + case 6: // Right + xcurve = 0; + ycurve = missile[i]._miyvel; + break; + case 7: // Down Right + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + } + + + --missile[i]._mirange; + + if (missile[i]._micaster == MI_ENEMYMONST) { + px = plr[id]._px; + py = plr[id]._py; + } else { + px = monster[id]._mx; + py = monster[id]._my; + } + + if (missile[i]._miAnimType == MF_BIGEXP) { + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += xcurve; + missile[i]._mityoff += ycurve; + GetMissilePos(i); + + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, dam, dam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + mx = missile[i]._mix; + my = missile[i]._miy; + + ChangeLight(missile[i]._mlid, mx, my, missile[i]._miAnimFrame); + + if (CheckBlock(px, py, mx , my ) == 0) CheckMissileCol(i, dam, dam, 0, mx, my, 1); + if (CheckBlock(px, py, mx , my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my + 1, 1); + if (CheckBlock(px, py, mx , my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my, 1); + if (CheckBlock(px, py, mx + 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my, 1); + if (CheckBlock(px, py, mx - 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my - 1, 1); + + //++missile[i]._mix; + //++missile[i]._miy; + //missile[i]._miyoff -= 32; + + if ((!TransList[dTransVal[mx][my]]) || + ((missile[i]._mixvel < 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff -= 32; + } + + if (((missile[i]._miyvel > 0) && + ((TransList[dTransVal[mx+1][my]] && nSolidTable[dPiece[mx+1][my]]) || + (TransList[dTransVal[mx-1][my]] && nSolidTable[dPiece[mx-1][my]])))) { + missile[i]._miyoff -= 32; + } + + if (((missile[i]._mixvel > 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + missile[i]._mixoff -= 32; + } + + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + missile[i]._miDelFlag = TRUE; + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Lightctrl(int i) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + int pn, dam, p, mx, my; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + dam = 0; + + p = missile[i]._misource; + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + dam = random(79, plr[p]._pLevel) + random(79, 2) + 2; + dam = dam << HP_SHIFT; + } else { + dam = (random(80, monster[p].mMaxDamage - monster[p].mMinDamage + 1) + monster[p].mMinDamage) << 1; + } + } else { + dam = random(81, currlevel) + (currlevel << 1); + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + mx = missile[i]._mix; + my = missile[i]._miy; + + app_assert(mx < MAXDUNX && mx >= 0); + app_assert(my < MAXDUNY && my >= 0); + pn = dPiece[mx][my]; + app_assert(pn <= MAXTILES && pn >= 0); + if (missile[i]._misource == -1) { + if ((mx != missile[i]._misx) || (my != missile[i]._misy)) + if (nMissileTable[pn]) missile[i]._mirange = 0; + } else { + if (nMissileTable[pn]) missile[i]._mirange = 0; + } + + if ((!nMissileTable[pn]) && ((mx != missile[i]._miVar1) || (my != missile[i]._miVar2)) && + (mx > 0) && (my > 0) && (mx < DMAXX) && (my < DMAXY)) { + // Add LIGHTNING if the player or trap threw this, otherwise add THINLIGHT for thin demon + if (missile[i]._misource != -1) { + if (missile[i]._micaster == MI_ENEMYPLR && EquivMonst(monster[missile[i]._misource].MType->mtype, MT_STORM)) + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_THINLIGHT, missile[i]._micaster, missile[i]._misource, dam, missile[i]._mispllvl); + else + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, dam, missile[i]._mispllvl); + } else { + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, dam, missile[i]._mispllvl); + } + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + } + + if ((missile[i]._mirange == 0) || (mx <= 0) || (my <= 0) || (mx >= DMAXX) || (my > DMAXY)) + missile[i]._miDelFlag = TRUE; +#endif +} + +void MI_LTArrow(int i) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + int pn, mx, my; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + mx = missile[i]._mix; + my = missile[i]._miy; + + app_assert(mx < MAXDUNX && mx >= 0); + app_assert(my < MAXDUNY && my >= 0); + pn = dPiece[mx][my]; + app_assert(pn <= MAXTILES && pn >= 0); + if (missile[i]._misource == -1) { + if ((mx != missile[i]._misx) || (my != missile[i]._misy)) + if (nMissileTable[pn]) missile[i]._mirange = 0; + } else { + if (nMissileTable[pn]) missile[i]._mirange = 0; + } + + if ((!nMissileTable[pn]) && ((mx != missile[i]._miVar1) || (my != missile[i]._miVar2)) && + (mx > 0) && (my > 0) && (mx < DMAXX) && (my < DMAXY)) { + // Add LIGHTNING if the player or trap threw this, otherwise add THINLIGHT for thin demon + if (missile[i]._misource != -1) { + if (missile[i]._micaster == MI_ENEMYPLR && EquivMonst(monster[missile[i]._misource].MType->mtype, MT_STORM)) + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_THINLIGHT, missile[i]._micaster, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + else + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + } else { + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + } + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + } + + if ((missile[i]._mirange == 0) || (mx <= 0) || (my <= 0) || (mx >= DMAXX) || (my > DMAXY)) + missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Lightning(int i) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + int j; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + + j = missile[i]._mirange; + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Town(int i) +{ +#if (PRE_BETA && PRE_TOWN) || !PRE_BETA + int p; + + int ExpLight[17] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,15}; + + app_assert(i < MAXMISSILES && i >= 0); + if (missile[i]._mirange > 1) --missile[i]._mirange; + + if (missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + } + + if ((currlevel != 0) && (missile[i]._mimfnum != 1) && (missile[i]._mirange != 0)) { + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + + for (p = 0; p < MAX_PLRS; ++p) { + if (! plr[p].plractive) continue; + if (currlevel != plr[p].plrlevel) continue; + if (plr[p]._pLvlChanging) continue; + if (plr[p]._pmode != PM_STAND) continue; + if (plr[p]._px != missile[i]._mix) continue; + if (plr[p]._py != missile[i]._miy) continue; + + ClrPlrPath(p); + if (p == myplr) { + NetSendCmdParam1(TRUE,CMD_WARP,missile[i]._misource); + plr[p]._pmode = PM_NEWLVL; + } + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flash(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[missile[i]._misource]._pInvincible = TRUE; + --missile[i]._mirange; + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix-1, missile[i]._miy, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix+1, missile[i]._miy, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix-1, missile[i]._miy+1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy+1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix+1, missile[i]._miy+1, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pInvincible = FALSE; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Aura(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + int const id = missile[i]._misource; + + if ((missile[i]._micaster == MI_ENEMYMONST) && (id != -1)) { + missile[i]._mix = plr[id]._px; + missile[i]._miy = plr[id]._py; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + } + --missile[i]._mirange; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pBaseToBlk -= 50; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Aura2(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) { + missile[i]._mix = plr[missile[i]._misource]._pfutx; + missile[i]._miy = plr[missile[i]._misource]._pfuty; + } + --missile[i]._mirange; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flash2(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pInvincible = TRUE; + --missile[i]._mirange; + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix-1, missile[i]._miy-1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy-1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix+1, missile[i]._miy-1, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pInvincible = FALSE; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Reflect(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + int const id = missile[i]._misource; + + // Reset by GetMissilePos() + // missile[i]._mix = plr[id]._px; + // missile[i]._miy = plr[id]._py; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + + // These hard coded numbers are fudge factors to get the %$^& art to + // align up. + if (plr[id]._pmode == PM_WALK3) { + missile[i]._misx = plr[id]._pfutx + 2; + missile[i]._misy = plr[id]._pfuty + -1; + } else { + missile[i]._misx = plr[id]._px + 2; + missile[i]._misy = plr[id]._py + -1; + } + + GetMissilePos(i); + + if (plr[id]._pmode == PM_WALK3) { + if (plr[id]._pdir == DIR_L) ++missile[i]._mix; + else ++missile[i]._miy; + } + + if (id != myplr && + currlevel != plr[id].plrlevel) { + missile[i]._miDelFlag = TRUE; + } + + if (plr[id]._pReflectCount <= 0) + { + missile[i]._miDelFlag = TRUE; + NetSendCmd(TRUE, CMD_ENDREFLECT); + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Manashield(int i) +{ +#if (PRE_BETA && PRE_MANASHLD) || !PRE_BETA + int j, id; + long diff, pct; + + //--missile[i]._mirange; + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + + missile[i]._mix = plr[id]._px; + missile[i]._miy = plr[id]._py; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + + if (plr[id]._pmode == PM_WALK3) { + missile[i]._misx = plr[id]._pfutx; + missile[i]._misy = plr[id]._pfuty; + } else { + missile[i]._misx = plr[id]._px; + missile[i]._misy = plr[id]._py; + } + + GetMissilePos(i); + + if (plr[id]._pmode == PM_WALK3) { + if (plr[id]._pdir == DIR_L) ++missile[i]._mix; + else ++missile[i]._miy; + } + + if (id != myplr) { + if (currlevel != plr[id].plrlevel) missile[i]._miDelFlag = TRUE; + PutMissile(i); + return; + } + + if (plr[id]._pMana <= 0 || (!plr[id].plractive)) missile[i]._mirange = 0; + + if (plr[id]._pHitPoints < missile[i]._miVar1) { + diff = missile[i]._miVar1 - plr[id]._pHitPoints; + pct = 0; + for (j = 0; j < missile[i]._mispllvl && j < 7; ++j) pct += 3; + if (pct > 0) diff = diff - (diff / pct); + if (diff < 0) diff = 0; + drawmanaflag = TRUE; + drawhpflag = TRUE; + if (plr[id]._pMana >= diff) { + plr[id]._pHitPoints = missile[i]._miVar1; + plr[id]._pHPBase = missile[i]._miVar2; + plr[id]._pMana -= diff; + plr[id]._pManaBase -= diff; + } else { + plr[id]._pHitPoints -= (diff - plr[id]._pMana); + plr[id]._pHPBase -= (diff - plr[id]._pMana); + plr[id]._pMana = 0; + plr[id]._pManaBase = -(plr[id]._pMaxMana - plr[id]._pMaxManaBase); + missile[i]._mirange = 0; + missile[i]._miDelFlag = TRUE; + if (plr[id]._pHitPoints < 0) SetPlayerHitPoints(id, 0); + if (((plr[id]._pHitPoints >> HP_SHIFT) == 0) && (id == myplr)) + StartPlrKill(id, missile[i]._miVar8); + } + } + + missile[i]._miVar1 = plr[id]._pHitPoints; + missile[i]._miVar2 = plr[id]._pHPBase; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + NetSendCmd(TRUE, CMD_ENDSHIELD); + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Ether(int i) +{ +#if (PRE_BETA && PRE_ETHER) || !PRE_BETA + int id; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + id = missile[i]._misource; + + missile[i]._mix = plr[id]._px; + missile[i]._miy = plr[id]._py; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + + if (plr[id]._pmode == PM_WALK3) { + missile[i]._misx = plr[id]._pfutx; + missile[i]._misy = plr[id]._pfuty; + } else { + missile[i]._misx = plr[id]._px; + missile[i]._misy = plr[id]._py; + } + + GetMissilePos(i); + + if (plr[id]._pmode == PM_WALK3) { + if (plr[id]._pdir == DIR_L) ++missile[i]._mix; + else ++missile[i]._miy; + } + + plr[id]._pSpellFlags |= SF_ETHER; + + if (missile[i]._mirange == 0 || plr[id]._pHitPoints <= 0) { + missile[i]._miDelFlag = TRUE; + plr[id]._pSpellFlags &= ~SF_ETHER; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Firemove(int i) +{ + int j; + int ExpLight[14] = {2,3,4,5,5,6,7,8,9,10,11,12,12}; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mix; + --missile[i]._miy; + missile[i]._miyoff+=32; + + ++missile[i]._miVar1; + + if (missile[i]._miVar1 == missile[i]._miAnimLen) { + SetMissDir(i, 1); + missile[i]._miAnimFrame = random(82, 11) + 1; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + j = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + if ((missile[i]._mimfnum == 0) && (missile[i]._mirange != 0)) { + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + else if ((missile[i]._mix != missile[i]._miVar3) || (missile[i]._miy != missile[i]._miVar4)) { + missile[i]._miVar3 = missile[i]._mix; + missile[i]._miVar4 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar3, missile[i]._miVar4, 8); + } + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff-=32; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Guardian(int i) +{ +#if (PRE_BETA && PRE_GUARDIAN) || !PRE_BETA + int j, k, sx, sy, sx1, sy1, ex; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + if (missile[i]._miVar2 > 0) --missile[i]._miVar2; + + if ((missile[i]._mirange == missile[i]._miVar1) || ((missile[i]._mimfnum == 2) && + (missile[i]._miVar2 == 0))) { + SetMissDir(i, 1); + } + + if ((missile[i]._mirange % 16) == 0) { + ex = 0; + for (k = 0; (k < 23) && (ex != -1); ++k) { + for (j = 10; (j >= 0) && (ex != -1); j-=2) { + if (vCrawlTable[k][j] == 0 && vCrawlTable[k][j + 1] == 0) break; + if ((sx1 != vCrawlTable[k][j]) || (sy1 != vCrawlTable[k][j + 1])) { + sx = missile[i]._mix + vCrawlTable[k][j]; + sy = missile[i]._miy + vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx = missile[i]._mix - vCrawlTable[k][j]; + sy = missile[i]._miy - vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx = missile[i]._mix + vCrawlTable[k][j]; + sy = missile[i]._miy - vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx = missile[i]._mix - vCrawlTable[k][j]; + sy = missile[i]._miy + vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx1 = vCrawlTable[k][j]; + sy1 = vCrawlTable[k][j + 1]; + } + } + } + } + + if (missile[i]._mirange == 14) { + SetMissDir(i, 0); + missile[i]._miAnimFrame = 15; + missile[i]._miAnimAdd = -1; + } + + missile[i]._miVar3 += missile[i]._miAnimAdd; + if (missile[i]._miVar3 > 15) { + missile[i]._miVar3 = 15; + } else { + if (missile[i]._miVar3 > 0) + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar3); + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Chain(int i) +{ +#if (PRE_BETA && PRE_CHAIN) || !PRE_BETA + int sx, sy, id, dir; + int l, n, m, k, rad; + int tx, ty; + + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + sx = missile[i]._mix; + sy = missile[i]._miy; + + dir = GetDirection(sx, sy, missile[i]._miVar1, missile[i]._miVar2); + AddMissile(sx, sy, missile[i]._miVar1, missile[i]._miVar2, dir, MIT_LIGHTCTRL, MI_ENEMYMONST, id, 1, missile[i]._mispllvl); + + rad = 3 + missile[i]._mispllvl; + if (rad > 19) rad = 19; + for (m = 1; m < rad; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + tx = sx + CrawlTable[l]; + ty = sy + CrawlTable[(l + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + if ((dMonster[tx][ty]) > 0) { + dir = GetDirection(sx, sy, tx, ty); + AddMissile(sx, sy, tx, ty, dir, MIT_LIGHTCTRL, MI_ENEMYMONST, id, 1, missile[i]._mispllvl); + } + } + l += 2; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void MI_ChainOLD(int i) +{ + int dir; + + if ((missile[i]._mirange % 3) == 0) { + dir = GetDirection(missile[i]._mix, missile[i]._miy, missile[i]._miVar5, missile[i]._miVar6); + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._miVar5, missile[i]._miVar6, dir, MIT_CHAINBALL, MI_ENEMYMONST, missile[i]._misource, missile[i]._midam); + ++missile[i]._miVar7; + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void MI_ChainballOLD(int i) +{ + int mx, id; + int k, l, m, n, rad; + + --missile[i]._mirange; + id = missile[i]._misource; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + if ((missile[i]._miVar2 == 1) && (missile[i]._mix == missile[i]._miVar3) && (missile[i]._miy == missile[i]._miVar4)) { + missile[i]._miVar2 = 0; + missile[i]._mirange = 0; + + k = 0; + for (l = 0; l < nummissiles; ++l) { + mx = missileactive[l]; + if (missile[mx]._mitype == MIT_CHAINBALL && missile[i]._miVar1 == missile[mx]._miVar1) ++k; + if ((missile[mx]._mitype == MIT_CHAIN) && (missile[i]._miVar1 == missile[mx]._midam)) + k+=((4 + (GetSpellLevel(id, SPL_LIGHTNING) / 3)) - missile[mx]._miVar7); + } + + if (k == 1) { + rad = 6 + GetSpellLevel(id, SPL_CHAIN); + if (rad > 19) rad = 19; + for (m = 1; m < rad; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + if (ChainBounce (i, missile[i]._mix + CrawlTable[l], missile[i]._miy + CrawlTable[(l + 1)]) > 0) { + m = rad; + break; + } + l += 2; + } + } + } + } else { + if ((missile[i]._mix != missile[i]._miVar5) || (missile[i]._miy != missile[i]._miVar6)) + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._miHitFlag == TRUE && missile[i]._mirange == 0 && missile[i]._miVar2 == 0) { + for (l = 0; l < nummissiles; ++l) { + mx = missileactive[l]; + if ((missile[mx]._mitype == MIT_CHAIN && missile[i]._miVar1 == missile[mx]._midam) || + (missile[mx]._mitype == MIT_CHAINBALL && missile[i]._miVar1 == missile[mx]._miVar1)) { + missile[mx]._miVar2 = 1; // flag hit and cont until v3, v4 + missile[mx]._miVar3 = missile[i]._mix; // x of hit + missile[mx]._miVar4 = missile[i]._miy; // y of hit + } + } + } + } + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Blood(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + if (missile[i]._miAnimFrame == missile[i]._miAnimLen) { +// missile[i]._miAnimFrame = missile[i]._miAnimLen; + missile[i]._miPreFlag = TRUE; + } + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Weapexp(int i) +{ + int id, mind, maxd; + int ExpLight[10] = {9,10,11,12,11,10,8,6,4,2}; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + + id = missile[i]._misource; + if (missile[i]._miVar2 == 1) { + mind = plr[id]._pIFMinDam; + maxd = plr[id]._pIFMaxDam; + missiledata[missile[i]._mitype].mResist = MIMT_FIRE; + } else { + mind = plr[id]._pILMinDam; + maxd = plr[id]._pILMaxDam; + missiledata[missile[i]._mitype].mResist = MIMT_LGHT; + } + + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._miVar1 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } else { + if (missile[i]._mirange != 0) + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } + + ++missile[i]._miVar1; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + return; + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Misexp(int i) +{ + int ExpLight[15] = {9,10,11,12,11,10,8,6,4,2,1,0,0,0,0}; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + return; + } + + if (missile[i]._miVar1 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } else { + if (missile[i]._mirange != 0) + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } + + ++missile[i]._miVar1; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Acidsplat(int i) +{ + int monst; + int dam; + + app_assert(i < MAXMISSILES && i >= 0); + if (missile[i]._mirange == missile[i]._miAnimLen) { + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff-=32; + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + monst = missile[i]._misource; + dam = (monster[monst].MData->mLevel < 2) ? 1:2; + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_ACIDPUD, MI_ENEMYPLR, missile[i]._misource, dam, missile[i]._mispllvl); + return; + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Teleport(int i) +{ +#if (PRE_BETA && PRE_TELE) || !PRE_BETA + int id; + + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + + //sprintf(tempstr, "X: %i Y: %i FX: %i FY: %i", plr[myplr]._px, plr[myplr]._py, plr[myplr]._pfutx, plr[myplr]._pfuty); + //AddPanelString(tempstr, TEXT_LEFT); + + --missile[i]._mirange; + if (missile[i]._mirange <= 0) { + missile[i]._miDelFlag = TRUE; + return; + } + + dPlayer[(plr[id]._px)][(plr[id]._py)] = 0; + PlrClrTrans(plr[id]._px, plr[id]._py); + plr[id]._px = missile[i]._mix; + plr[id]._py = missile[i]._miy; + plr[id]._pfutx = plr[id]._px; + plr[id]._pfuty = plr[id]._py; + plr[id]._poldx = plr[id]._px; + plr[id]._poldy = plr[id]._py; + PlrDoTrans(plr[id]._px, plr[id]._py); + missile[i]._miVar1 = 1; + dPlayer[(plr[id]._px)][(plr[id]._py)] = 1 + (char)id; + + if (leveltype != 0) { + ChangeLightXY(plr[id]._plid, plr[id]._px, plr[id]._py); + ChangeVisionXY(plr[id]._pvid, plr[id]._px, plr[id]._py); + } + + if (id == myplr) { + ViewX = plr[id]._px - ScrollInfo._sdx; + ViewY = plr[id]._py - ScrollInfo._sdy; + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void MI_Doom(int i) +{ + int k, l, m, n; + int mid; + + --missile[i]._mirange; + + // check if monster moved + mid = dMonster[(missile[i]._miVar1)][(missile[i]._miVar2)]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + } + + // if he did search again + if (mid != missile[i]._miVar3) { + for (m = 0; m < 6; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + mid = dMonster[((missile[i]._miVar1) + CrawlTable[l])][((missile[i]._miVar2) + CrawlTable[(l + 1)])]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + if (mid == missile[i]._miVar3) { + missile[i]._miVar1 += CrawlTable[l]; + missile[i]._miVar2 += CrawlTable[l + 1]; + k = -99; + m = 6; + break; + } + } + l += 2; + } + } + + // if monster killed before doom kills it + if (k != -99) { + missile[i]._miDelFlag = TRUE; + PutMissile(i); + return; + } + + // get new velocity and directions + GetMissileVel(i, missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2, 16); + SetMissDir(i, GetDirection(missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2)); + } + + + // move missile + if (missile[i]._mimfnum != 9) { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + } + + // get mid for current missile pos - for checking if target monster killed + mid = dMonster[(missile[i]._mix)][(missile[i]._miy)]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + } + + // check for collision if not followed monster dont end missile + k = missile[i]._mirange; + if ((missile[i]._mix != plr[myplr]._px) || (missile[i]._miy != plr[myplr]._py)) CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + if ((missile[i]._mirange == 0) && (mid != missile[i]._miVar3) && (missile[i]._miHitFlag == TRUE)) missile[i]._mirange = k; + + // if target monster not dead halt missile in place + if ((missile[i]._mirange == 0) && (mid == missile[i]._miVar3)) { + missile[i]._mirange = k; + if ((monster[mid]._mhitpoints >> HP_SHIFT) > 0) { + if (missile[i]._mimfnum != 9) { + SetMissDir(i, 9); + } + } else { + // target is killed so re-search + for (m = 1; m < 6; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + mid = dMonster[((missile[i]._miVar1) + CrawlTable[l])][((missile[i]._miVar2) + CrawlTable[(l + 1)])]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + if ((monster[mid]._mhitpoints >> HP_SHIFT) > 0) { + missile[i]._miVar1 += CrawlTable[l]; + missile[i]._miVar2 += CrawlTable[l + 1]; + missile[i]._miVar3 = mid; + k = -99; + m = 6; + break; + } + } + l += 2; + } + } + + // get new velocity and directions + if (k == 0) missile[i]._mirange = 0; + else { + GetMissileVel(i, missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2, 16); + SetMissDir(i, GetDirection(missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2)); + } + } + } + + // delete or place missile + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Stone (int i) +{ +#if (PRE_BETA && PRE_STONE) || !PRE_BETA + int m; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + m = missile[i]._miVar2; + + if (monster[m]._mhitpoints == 0 && missile[i]._miAnimType != MF_STONE) { + SetMissAnim(i, MF_STONE); + missile[i]._mirange = 11; + } + + + if (monster[m]._mmode != MM_STONE) missile[i]._miDelFlag = TRUE; + + else { + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if (monster[m]._mhitpoints > 0) { +// app_assert(dMonster[monster[m]._mx][monster[m]._my] == m+1 +// || dMonster[monster[m]._mx][monster[m]._my] == -(m+1)); + monster[m]._mmode = missile[i]._miVar1; + } + else AddDead(monster[m]._mx, monster[m]._my, stonendx, monster[m]._mdir); + } + + if (missile[i]._miAnimType == MF_STONE) PutMissile(i); + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Boom(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + if (missile[i]._miVar1 == 0) CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 1); + if (missile[i]._miHitFlag == TRUE) missile[i]._miVar1 = 1; + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Rhino(int i) +{ + int mix,miy; + int mix2, miy2; + int omx, omy; + int monst; + BOOL placemiss = FALSE; + + app_assert(i < MAXMISSILES && i >= 0); + monst = missile[i]._misource; + + app_assert(monst < MAXMONSTERS && monst >= 0); + if (monster[monst]._mmode != MM_MISSILE) { // monster got blood-boiled or something + missile[i]._miDelFlag = TRUE; + return; + } + + GetMissilePos(i); + + omx = missile[i]._mix; + omy = missile[i]._miy; + + dMonster[omx][omy] = NULL; + + if (monster[monst]._mAi == AI_SNAKE) + { + // Snake should stop a few frames before it enters player's square + // So we run its animation a few frames ahead here and test below + // to see if the square is available + missile[i]._mitxoff += 2*missile[i]._mixvel; + missile[i]._mityoff += 2*missile[i]._miyvel; + + GetMissilePos(i); + + mix2 = missile[i]._mix; + miy2 = missile[i]._miy; + + missile[i]._mitxoff -= 1*missile[i]._mixvel; + missile[i]._mityoff -= 1*missile[i]._miyvel; + } + else + { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + } + + GetMissilePos(i); + + mix = missile[i]._mix; + miy = missile[i]._miy; + + + if (PosOkMonst(monst, mix, miy) + && (monster[monst]._mAi != AI_SNAKE || PosOkMonst(monst, mix2, miy2))) + { + dMonster[mix][miy] = -(monst + 1); + monster[monst]._mx = monster[monst]._moldx = monster[monst]._mfutx = mix; + monster[monst]._my = monster[monst]._moldy = monster[monst]._mfuty = miy; + + if(monster[monst]._uniqtype) + ChangeLightXY(missile[i]._mlid, mix, miy); + + MoveMissilePos(i); + PutMissile(i); + } + else + { + MissToMonst(i,omx,omy); + missile[i]._miDelFlag = TRUE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Fireman(int i) +{ + int mix,miy; + int omx, omy; + int id, m; + BOOL placemiss = FALSE; + int px,py, p; + + GetMissilePos(i); + + app_assert(i < MAXMISSILES && i >= 0); + omx = missile[i]._mix; + omy = missile[i]._miy; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + + m = missile[i]._misource; + mix = missile[i]._mix; + miy = missile[i]._miy; + + p = monster[m]._menemy; + if ((monster[m]._mFlags & MFLAG_MID) == 0) { + px = plr[p]._px; + py = plr[p]._py; + } else { + px = monster[p]._mx; + py = monster[p]._my; + } + + if((mix != omx || miy != omy) + && + ((missile[i]._miVar1 & MIF_DIDHIT + && !DIST(omx-px, omy-py, 4)) + || missile[i]._miVar2 > 1) + && PosOkMonst(missile[i]._misource, omx, omy) + ) + { + // return to monster domain + MissToMonst(i,omx, omy); + missile[i]._miDelFlag = TRUE; + } + + else + if ((monster[m]._mFlags & MFLAG_MID) == 0) id = dPlayer[mix][miy]; + else id = dMonster[mix][miy]; + if(!PosOkMissile(mix, miy) + || (id > 0 && !(missile[i]._miVar1 & MIF_DIDHIT))) + { + // bounce away + missile[i]._mixvel = -missile[i]._mixvel; + missile[i]._miyvel = -missile[i]._miyvel; + missile[i]._mimfnum = opposite[missile[i]._mimfnum]; + missile[i]._miAnimData = monster[m].MType->Anims[MA_WALK].Cels[missile[i]._mimfnum]; + + ++missile[i]._miVar2; + + if(id > 0) + { + missile[i]._miVar1 |= MIF_DIDHIT; + } + placemiss = TRUE; + } + else + placemiss = TRUE; + + if(placemiss) + { +// ChangeLightXY(monster[m].mlid, monster[m]._mx, monster[m]._my); + + MoveMissilePos(i); + PutMissile(i); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_FirewallC(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int tx, ty, pn, id; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + id = missile[i]._misource; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + else { + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar1 >= MAXDUNX || missile[i]._miVar2 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar1,missile[i]._miVar2); + pn = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + app_assert(pn <= MAXTILES && pn >= 0); + tx = missile[i]._miVar1 + XDirAdd[missile[i]._miVar3]; + ty = missile[i]._miVar2 + YDirAdd[missile[i]._miVar3]; + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar1, missile[i]._miVar2, missile[i]._miVar1, missile[i]._miVar2, plr[id]._pdir, MIT_FIREWALL, MI_ENEMYBOTH, id, 0, missile[i]._mispllvl); + missile[i]._miVar1 = tx; + missile[i]._miVar2 = ty; + } else missile[i]._miVar8 = 1; + + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar5 >= MAXDUNX || missile[i]._miVar6 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar5,missile[i]._miVar6); + pn = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + app_assert(pn <= MAXTILES && pn >= 0); + tx = missile[i]._miVar5 + XDirAdd[missile[i]._miVar4]; + ty = missile[i]._miVar6 + YDirAdd[missile[i]._miVar4]; + if (nMissileTable[pn] == 0 && missile[i]._miVar7 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar5, missile[i]._miVar6, missile[i]._miVar5, missile[i]._miVar6, plr[id]._pdir, MIT_FIREWALL, MI_ENEMYBOTH, id, 0, missile[i]._mispllvl); + missile[i]._miVar5 = tx; + missile[i]._miVar6 = ty; + } else missile[i]._miVar7 = 1; + } +#endif +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_FlameBox(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + missile[i]._miDelFlag = TRUE; + int const id = missile[i]._micaster; + int const l = CrawlNum[3]; + int j = l + 1; + int const dam = ((random(53, 10) + random(53, 10) + 2 + ((id > 0) ? plr[id]._pLevel : currlevel)) << 4) >> 1; + + for (int m = CrawlTable[l]; m > 0; --m, j+=2) { + int const tx = missile[i]._miVar1 + CrawlTable[j]; + int const ty = missile[i]._miVar2 + CrawlTable[j + 1]; + + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int const pn = dPiece[tx][ty]; + + if (!nSolidTable[pn] && dObject[tx][ty] == 0 + && LineClear(missile[i]._mix, missile[i]._miy, tx, ty) + ) + { + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(tx, ty, tx, ty, 0, MIT_FIREWALL, MI_ENEMYBOTH, id, dam, missile[i]._mispllvl); + } else missile[i]._miVar8 = 1; + + } + } + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_LightBox(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + missile[i]._miDelFlag = TRUE; + int const id = missile[i]._micaster; + int const l = CrawlNum[3]; + int j = l + 1; + int const dam = ((random(53, 10) + random(53, 10) + 2 + ((id > 0) ? plr[id]._pLevel : currlevel)) << 4) >> 1; + + for (int m = CrawlTable[l]; m > 0; --m, j+=2) { + int const tx = missile[i]._miVar1 + CrawlTable[j]; + int const ty = missile[i]._miVar2 + CrawlTable[j + 1]; + + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int const pn = dPiece[tx][ty]; + + if (!nSolidTable[pn] && dObject[tx][ty] == 0 + && LineClear(missile[i]._mix, missile[i]._miy, tx, ty) + ) + { + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(tx, ty, tx, ty, 0, MIT_LIGHTWALL, MI_ENEMYBOTH, id, dam, missile[i]._mispllvl); + } else missile[i]._miVar8 = 1; + + } + } + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_ShowMagicItems(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + + --missile[i]._mirange; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + int const id = missile[i]._miVar1; + PlaySfxLoc(IS_CAST7, plr[id]._px, plr[id]._py); + HighLightAllItems = false; + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_LightwallC(int i) +{ +// GWP 9/4/97 +// Copy of MI_FirewallC with switched to call the MIT_LIGHTWALL instead of MIT_FIREWALL +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int tx, ty, pn; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + + int const id = missile[i]._misource; + int const dam = (random(53, 10) + random(53, 10) + 2 + ((id > 0) ? plr[id]._pLevel : 0)) << 4; + + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + else { + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar1 >= MAXDUNX || missile[i]._miVar2 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar1,missile[i]._miVar2); + pn = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + app_assert(pn <= MAXTILES && pn >= 0); + tx = missile[i]._miVar1 + XDirAdd[missile[i]._miVar3]; + ty = missile[i]._miVar2 + YDirAdd[missile[i]._miVar3]; + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar1, missile[i]._miVar2, missile[i]._miVar1, missile[i]._miVar2, plr[id]._pdir, MIT_LIGHTWALL, MI_ENEMYBOTH, id, dam, missile[i]._mispllvl); + missile[i]._miVar1 = tx; + missile[i]._miVar2 = ty; + } else missile[i]._miVar8 = 1; + + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar5 >= MAXDUNX || missile[i]._miVar6 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar5,missile[i]._miVar6); + pn = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + app_assert(pn <= MAXTILES && pn >= 0); + tx = missile[i]._miVar5 + XDirAdd[missile[i]._miVar4]; + ty = missile[i]._miVar6 + YDirAdd[missile[i]._miVar4]; + if (nMissileTable[pn] == 0 && missile[i]._miVar7 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar5, missile[i]._miVar6, missile[i]._miVar5, missile[i]._miVar6, plr[id]._pdir, MIT_LIGHTWALL, MI_ENEMYBOTH, id, dam, missile[i]._mispllvl); + missile[i]._miVar5 = tx; + missile[i]._miVar6 = ty; + } else missile[i]._miVar7 = 1; + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Infra(int i) +{ +#if (PRE_BETA && PRE_INFRA) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + plr[(missile[i]._misource)]._pInfraFlag = TRUE; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + CalcPlrItemVals(missile[i]._misource,TRUE); + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Apoca(int i) +{ +#if (PRE_BETA && PRE_APOCA) || !PRE_BETA + int j, k, id; + BOOL exit; + + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + + exit = FALSE; + for (j = missile[i]._miVar2; (j < missile[i]._miVar3) && (exit == FALSE); ++j) { + for (k = missile[i]._miVar4; (k < missile[i]._miVar5) && (exit == FALSE); ++k) { + if (dMonster[k][j] > 3 + && nSolidTable[(dPiece[k][j])] == 0 + && LineClear(missile[i]._mix, missile[i]._miy, k, j)) { + AddMissile(k, j, k, j, plr[id]._pdir, MIT_BOOM, MI_ENEMYMONST, id, missile[i]._midam, 0); + exit = TRUE; + } + } + if (exit == FALSE) missile[i]._miVar4 = missile[i]._miVar6; + } + + if (exit == TRUE) { + missile[i]._miVar2 = j - 1; + missile[i]._miVar4 = k; + } else missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Wave(int i) +{ +#if (PRE_BETA && PRE_WAVE) || !PRE_BETA + int dira, dirb, nxa, nya, nxb, nyb; + int pn, sd, j, f1, f2, id, sx, sy, dx, dy; + + f1 = 0; + f2 = 0; + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + + sd = GetDirection(sx, sy, dx, dy); + dira = (sd - 2) & 0x0007; + dirb = (sd + 2) & 0x0007; + nxa = sx + XDirAdd[sd]; + nya = sy + YDirAdd[sd]; + + //if (nxa >= MAXDUNX || nya >= MAXDUNY) + // app_fatal("Tried placing flamewave piece off edge of map at (%d,%d)",nxa,nya); + pn = dPiece[nxa][nya]; + app_assert(pn <= MAXTILES && pn >= 0); + if (nMissileTable[pn] == 0) { + AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIT_FIREMOVE, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + + nxa += XDirAdd[dira]; + nya += YDirAdd[dira]; + nxb = sx + XDirAdd[sd] + XDirAdd[dirb]; + nyb = sy + YDirAdd[sd] + YDirAdd[dirb]; + for (j = 0; j < (2 + (missile[i]._mispllvl>>1)); ++j) { + //if (nxa >= MAXDUNX || nya >= MAXDUNY) + // app_fatal("Tried placing flamewave piece off edge of map at (%d,%d)",nxa,nya); + pn = dPiece[nxa][nya]; + app_assert(pn <= MAXTILES && pn >= 0); + if (nMissileTable[pn] == 0 && f1 == 0 && nxa > 0 && nxa < MAXDUNX && nya > 0 && nya < MAXDUNY) { + AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIT_FIREMOVE, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + nxa += XDirAdd[dira]; + nya += YDirAdd[dira]; + } else f1 = 1; + + //if (nxb >= MAXDUNX || nyb >= MAXDUNY) + // app_fatal("Tried placing flamewave piece off edge of map at (%d,%d)",nxb,nyb); + pn = dPiece[nxb][nyb]; + app_assert(pn <= MAXTILES && pn >= 0); + if (nMissileTable[pn] == 0 && f2 == 0 && nxb > 0 && nxb < MAXDUNX && nyb > 0 && nyb < MAXDUNY) { + AddMissile(nxb, nyb, nxb + XDirAdd[sd], nyb + YDirAdd[sd], plr[id]._pdir, MIT_FIREMOVE, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + nxb += XDirAdd[dirb]; + nyb += YDirAdd[dirb]; + } else f2 = 1; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define RAD 6 + +void MI_Nova(int i) +{ +#if (PRE_BETA && PRE_NOVA) || !PRE_BETA + int k, id, sx, sy, dir, en; + int sx1, sy1, dam, dx, dy; + + sx1 = sy1 = 0; + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + dam = missile[i]._midam; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + if (id != -1) { + dir = plr[id]._pdir; + en = MI_ENEMYMONST; + } else { + dir = 0; + en = MI_ENEMYPLR; + } + + for (k = 0; k < 23; ++k) { + if ((sx1 != vCrawlTable[k][RAD]) || (sy1 != vCrawlTable[k][RAD + 1])) { + dx = sx + vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + dx = sx + vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + sx1 = vCrawlTable[k][RAD]; + sy1 = vCrawlTable[k][RAD + 1]; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MI_FireNova(int i) +{ +#if (PRE_BETA && PRE_NOVA) || !PRE_BETA + int k, id, sx, sy, dir, en; + int sx1, sy1, dam, dx, dy; + + sx1 = sy1 = 0; + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + dam = missile[i]._midam; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + if (id != -1) { + dir = plr[id]._pdir; + en = MI_ENEMYMONST; + } else { + dir = 0; + en = MI_ENEMYPLR; + } + + for (k = 0; k < 23; ++k) { + if ((sx1 != vCrawlTable[k][RAD]) || (sy1 != vCrawlTable[k][RAD + 1])) { + dx = sx + vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + dx = sx + vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + sx1 = vCrawlTable[k][RAD]; + sy1 = vCrawlTable[k][RAD + 1]; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +void MI_SpecialArrow(int i) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int id, sx, sy, dir, en; + int sx1, sy1, dam, dx, dy; + + sx1 = sy1 = 0; + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + dam = missile[i]._midam; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + int extraspeed = missile[i]._miVar3; + + int mitype = MIT_ARROW; + if (id != -1) { + dir = plr[id]._pdir; + en = MI_ENEMYMONST; + switch(plr[id]._pILMinDam) + { + case 0: mitype = MIT_FBARROW; break; + case 1: mitype = MIT_LTARROW; break; + case 2: mitype = MIT_CBARROW; break; + case 3: mitype = MIT_HBARROW; break; + default: break; + } + } else { + dir = 0; + en = MI_ENEMYPLR; + } + + AddMissile(sx, sy, dx, dy, dir, mitype, en, id, dam, extraspeed); + if (mitype == MIT_CBARROW) + { + AddMissile(sx, sy, dx, dy, dir, mitype, en, id, dam, extraspeed); + AddMissile(sx, sy, dx, dy, dir, mitype, en, id, dam, extraspeed); + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Boil(int i) +{ + app_assert(i < MAXMISSILES && i >= 0); + missile[i]._miDelFlag = TRUE; + return; + +/*#if (PRE_BETA && PRE_BLOODB) || !PRE_BETA + int j, mid, id, dx, dy, pct; + long dm; + + BOOL M_Talker (int); + + id = missile[i]._misource; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + mid = dMonster[dx][dy]; + + if (mid > 0) --mid; + else mid = -(mid + 1); + if (mid > 0) { + if ((M_Talker(mid) && monster[mid].mtalkmsg != 0) || ((plr[id]._pLevel - 6 + missile[i]._mispllvl) <= monster[mid].mLevel)) { + missile[i]._miDelFlag = TRUE; + return; + } + + if (monster[mid].mMagicRes & M_IM) return; + + dm = monster[mid]._mhitpoints; + monster[mid]._mhitpoints = 0; + M_StartKill(mid, id); + AddPlrExperience(id, monster[mid].mLevel, monster[mid].mExp); + dMonster[monster[mid]._mx][monster[mid]._my] = 0; + monster[mid]._mDelFlag = TRUE; + AddMissile(monster[mid]._mx, monster[mid]._my, monster[mid]._mx, monster[mid]._my, plr[id]._pdir, MIT_SPURT, MI_ENEMYMONST, id, (random(87, 2) + 1), 0); + AddDead(monster[mid]._mx, monster[mid]._my, spurtndx, monster[mid]._mdir); + + pct = 0; + for (j = 0; j < missile[i]._mispllvl && j < 5; ++j) pct += 10; + //dm = (monster[mid]._mmaxhp >> 1); + if (pct > 0) dm -= (dm / pct); + plr[id]._pHitPoints -= dm; + plr[id]._pHPBase -= dm; + + if (plr[id]._pHitPoints > plr[id]._pMaxHP) { + plr[id]._pHitPoints = plr[id]._pMaxHP; + plr[id]._pHPBase = plr[id]._pMaxHPBase; + } + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } else StartPlrHit(id, dm); + + PlaySfxLoc(LS_BLODBOIL, monster[mid]._mx, monster[mid]._my); + UseMana(id, SPL_BLOODB); + } + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif*/ +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Rage(int i) +{ +#if !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + + --missile[i]._mirange; + if (missile[i]._mirange == 0) { + int const pid = missile[i]._miVar1; + if ((plr[pid]._pSpellFlags & SF_RAGE) == SF_RAGE) { + int const Sounds[NUM_CLASSES] = { PS_WARR72, + PS_ROGUE72, + PS_MAGE72, + PS_MAGE72, // monk + PS_BARD72, + PS_BARBARIAN72 }; + plr[pid]._pSpellFlags &= ~SF_RAGE; + plr[pid]._pSpellFlags |= SF_LETHERGY; + missile[i]._mirange = 245 + (10 * missile[i]._mispllvl) + (2 * (pid > 0) ? plr[pid]._pLevel : 1); + int const diffHpts = plr[pid]._pMaxHP - plr[pid]._pHitPoints; + CalcPlrItemVals(pid, TRUE); + + plr[pid]._pHitPoints -= diffHpts; + if (plr[pid]._pHitPoints < (1 << HP_SHIFT)) { + // Don't quite die. + plr[pid]._pHitPoints = 1 << HP_SHIFT; + } + force_redraw = FULLDRAW; + PlaySfxLoc(Sounds[plr[pid]._pClass], plr[pid]._px, plr[pid]._py); + } + else { + int const Sounds[NUM_CLASSES] = { PS_WARR72, + PS_ROGUE72, + PS_MAGE72, + PS_MAGE72, // monk + PS_BARD72, + PS_BARBARIAN72 }; + missile[i]._miDelFlag = TRUE; + plr[pid]._pSpellFlags &= ~SF_LETHERGY; + int const diffHpts = plr[pid]._pMaxHP - plr[pid]._pHitPoints; + CalcPlrItemVals(pid, TRUE); + plr[pid]._pHitPoints -= missile[i]._miVar2 + diffHpts; + if (plr[pid]._pHitPoints < (1 << HP_SHIFT)) { + // Don't quite die. + plr[pid]._pHitPoints = 1 << HP_SHIFT; + } + force_redraw = FULLDRAW; + PlaySfxLoc(Sounds[plr[pid]._pClass], plr[pid]._px, plr[pid]._py); + } + } +#endif +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flame(int i) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + int k, id; + + app_assert(i < MAXMISSILES && i >= 0); + id = missile[i]._misource; + --missile[i]._mirange; + --missile[i]._miVar2; + + k = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + if ((missile[i]._mirange == 0) && (missile[i]._miHitFlag == TRUE)) missile[i]._mirange = k; + if (missile[i]._miVar2 == 0) missile[i]._miAnimFrame = 20; + if (missile[i]._miVar2 <= 0) { + k = missile[i]._miAnimFrame; + if (k > 11) k = 24 - k; + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, k); + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + if (missile[i]._miVar2 <= 0) PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flamec(int i) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + int id, pn; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + id = missile[i]._misource; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + app_assert(missile[i]._mix < MAXDUNX && missile[i]._mix >= 0); + app_assert(missile[i]._miy < MAXDUNY && missile[i]._miy >= 0); + pn = dPiece[missile[i]._mix][missile[i]._miy]; + app_assert(pn <= MAXTILES && pn >= 0); + if (nMissileTable[pn] == 0) + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_FLAME, missile[i]._micaster, id, missile[i]._miVar3, missile[i]._mispllvl); + else + missile[i]._mirange = 0; + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ++missile[i]._miVar3; + } + + if (missile[i]._mirange == 0 || missile[i]._miVar3 == 3) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Cbolt(int i) +{ +#if (PRE_BETA && PRE_CBOLT) || !PRE_BETA + int bpath[16] = { -1, 0, 1, -1, 0, 1, -1, -1, 0, 0, 1, 1, 0, 1, -1, 0 }; + int sx, sy, dx, dy, md; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + if (missile[i]._miAnimType != MF_LIGHTNING) { + if (missile[i]._miVar3 == 0) { + md = (missile[i]._miVar2 + bpath[missile[i]._mirnd]) & 0x07; + missile[i]._mirnd = (missile[i]._mirnd + 1) & 0x0f; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = sx + XDirAdd[md]; + dy = sy + YDirAdd[md]; + GetMissileVel(i, sx, sy, dx, dy, 8); + missile[i]._miVar3 = 16; + } else --missile[i]._miVar3; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) { + missile[i]._miVar1 = 8; + missile[i]._mimfnum = 0; + missile[i]._mixoff = 0; + missile[i]._miyoff = 0; + SetMissAnim(i, MF_LIGHTNING); + missile[i]._mirange = missile[i]._miAnimLen; + GetMissilePos(i); + } + + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar1); + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Hbolt(int i) +{ +#if (PRE_BETA && PRE_HBOLT) || !PRE_BETA + int dam; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + if (missile[i]._miAnimType != MF_HEXPL) { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + + dam = missile[i]._midam; + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, dam, dam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + missile[i]._mitxoff -= missile[i]._mixvel; + missile[i]._mityoff -= missile[i]._miyvel; + GetMissilePos(i); + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_HEXPL); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + } else { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, 7 + missile[i]._miAnimFrame); + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Element(int i) +{ +#if (PRE_BETA && PRE_ELEMENT) || !PRE_BETA + int j, mid, sd, dam; + int cx, cy, px, py, id; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + dam = missile[i]._midam; + id = missile[i]._misource; + + if (missile[i]._miAnimType == MF_BIGEXP) { + cx = missile[i]._mix; + cy = missile[i]._miy; + px = plr[id]._px; + py = plr[id]._py; + ChangeLight(missile[i]._mlid, cx, cy, missile[i]._miAnimFrame); + + if (CheckBlock(px, py, cx , cy ) == 0) CheckMissileCol(i, dam, dam, 1, cx, cy, 1); + if (CheckBlock(px, py, cx , cy + 1) == 0) CheckMissileCol(i, dam, dam, 1, cx, cy + 1, 1); + if (CheckBlock(px, py, cx , cy - 1) == 0) CheckMissileCol(i, dam, dam, 1, cx, cy - 1, 1); + if (CheckBlock(px, py, cx + 1, cy ) == 0) CheckMissileCol(i, dam, dam, 1, cx + 1, cy, 1); + if (CheckBlock(px, py, cx + 1, cy - 1) == 0) CheckMissileCol(i, dam, dam, 1, cx + 1, cy - 1, 1); + if (CheckBlock(px, py, cx + 1, cy + 1) == 0) CheckMissileCol(i, dam, dam, 1, cx + 1, cy + 1, 1); + if (CheckBlock(px, py, cx - 1, cy ) == 0) CheckMissileCol(i, dam, dam, 1, cx - 1, cy, 1); + if (CheckBlock(px, py, cx - 1, cy + 1) == 0) CheckMissileCol(i, dam, dam, 1, cx - 1, cy + 1, 1); + if (CheckBlock(px, py, cx - 1, cy - 1) == 0) CheckMissileCol(i, dam, dam, 1, cx - 1, cy - 1, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + cx = missile[i]._mix; + cy = missile[i]._miy; + + j = missile[i]._mirange; + CheckMissileCol(i, dam, dam, 0, cx, cy, 0); + + if (missile[i]._miVar3 == 0) { + //if (missile[i]._mirange == 0 && missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + //if ((missile[i]._mirange == 0) && (missile[i]._miHitFlag != TRUE)) missile[i]._miVar3 = 1; + if ((cx == missile[i]._miVar4) && (cy == missile[i]._miVar5)) missile[i]._miVar3 = 1; + } + + if (missile[i]._miVar3 == 1) { + missile[i]._miVar3 = 2; + missile[i]._mirange = 255; + mid = FindClosest(cx, cy, 19); + if (mid > 0) { + sd = GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my); + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); + } else { + sd = plr[id]._pdir; + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16); + } + } + + if ((cx != missile[i]._miVar1) || (cy != missile[i]._miVar2)) { + missile[i]._miVar1 = cx; + missile[i]._miVar2 = cy; + ChangeLight(missile[i]._mlid, cx, cy, 8); + } + + if (missile[i]._mirange == 0) { + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Bonespirit(int i) +{ +#if (PRE_BETA && PRE_BONESPIRIT) || !PRE_BETA + int j, mid, sd, dam; + int cx, cy, id; + + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + dam = missile[i]._midam; + id = missile[i]._misource; + + if (missile[i]._mimfnum == 8) { + cx = missile[i]._mix; + cy = missile[i]._miy; + //px = plr[id]._px; + //py = plr[id]._py; + ChangeLight(missile[i]._mlid, cx, cy, missile[i]._miAnimFrame); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + cx = missile[i]._mix; + cy = missile[i]._miy; + + j = missile[i]._mirange; + CheckMissileCol(i, dam, dam, 0, cx, cy, 0); + + if (missile[i]._miVar3 == 0) { + //if (missile[i]._mirange == 0 && missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + //if ((missile[i]._mirange == 0) && (missile[i]._miHitFlag != TRUE)) missile[i]._miVar3 = 1; + if ((cx == missile[i]._miVar4) && (cy == missile[i]._miVar5)) missile[i]._miVar3 = 1; + } + + if (missile[i]._miVar3 == 1) { + missile[i]._miVar3 = 2; + missile[i]._mirange = 255; + mid = FindClosest(cx, cy, 19); + if (mid > 0) { + missile[i]._midam = (monster[mid]._mhitpoints >> HP_SHIFT) >> 1; + sd = GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my); + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); + } else { + sd = plr[id]._pdir; + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16); + } + } + + if ((cx != missile[i]._miVar1) || (cy != missile[i]._miVar2)) { + missile[i]._miVar1 = cx; + missile[i]._miVar2 = cy; + ChangeLight(missile[i]._mlid, cx, cy, 8); + } + + if (missile[i]._mirange == 0) { + SetMissDir(i, 8); + missile[i]._mirange = 7; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_ResurrectBeam(int i) +{ +#if (PRE_BETA && PRE_RESURRECT) || !PRE_BETA + app_assert(i < MAXMISSILES && i >= 0); + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Rportal(int i) +{ + int ExpLight[17] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,15}; + + app_assert(i < MAXMISSILES && i >= 0); + if (missile[i]._mirange > 1) --missile[i]._mirange; + + if (missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + } + + if ((currlevel != 0) && (missile[i]._mimfnum != 1) && (missile[i]._mirange != 0)) { + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ProcessMissiles () +{ + int i, mi; + + + for (i = 0; i < nummissiles; ++i) { + mi = missileactive[i]; + dFlags[missile[mi]._mix][missile[mi]._miy] &= BFMASK_MISSILE; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; + // Preventative code to prevent going off into the hinderlands. + if (missile[mi]._mix < 0 || missile[mi]._mix >= (MAXDUNX - 1)|| + missile[mi]._miy < 0 || missile[mi]._miy >= (MAXDUNY - 1) ) + { + missile[mi]._miDelFlag = TRUE; + } + } + + i = 0; + while (i < nummissiles) { + mi = missileactive[i]; + if (missile[mi]._miDelFlag) { + DeleteMissile(mi, i); + i = 0; + } else ++i; + } + + MissilePreFlag = FALSE; + ManashieldFlag = 0; + for (i = 0; i < nummissiles; ++i) { + mi = missileactive[i]; + + missiledata[missile[mi]._mitype].mProc(mi); + + if(!(missile[mi]._miAnimFlags & MFF_STATIC)) + { + ++missile[mi]._miAnimCnt; + if (missile[mi]._miAnimCnt >= missile[mi]._miAnimDelay) { + missile[mi]._miAnimCnt = 0; + missile[mi]._miAnimFrame += missile[mi]._miAnimAdd; + if (missile[mi]._miAnimFrame > missile[mi]._miAnimLen) missile[mi]._miAnimFrame = 1; + if (missile[mi]._miAnimFrame < 1) missile[mi]._miAnimFrame = missile[mi]._miAnimLen; + } + } + } + + if (ManashieldFlag) { + for (i = 0; i < nummissiles; ++i) { + mi = missileactive[i]; + if (missile[mi]._mitype == MIT_MANASHIELD) MI_Manashield(mi); + } + } + + i = 0; + while (i < nummissiles) { + mi = missileactive[i]; + if (missile[mi]._miDelFlag == TRUE) { + DeleteMissile(mi, i); + i = 0; + } else ++i; + } +} + +void SyncMissAnim() +{ + int i,mi; + + for (i = 0; i < nummissiles; ++i) + { + app_assert(i < MAXMISSILES && i >= 0); + mi = missileactive[i]; + + app_assert(mi < MAXMISSILES && mi >= 0); + MissileStruct *Miss = &missile[mi]; + + Miss->_miAnimData = misfiledata[Miss->_miAnimType].mAnimData[Miss->_mimfnum]; + + if (Miss->_mitype == MIT_RHINO) + { + AnimStruct *anim; + + if (EquivMonst(monster[Miss->_misource].MType->mtype, MT_HORNED)) + anim = &monster[Miss->_misource].MType->Anims[MA_SPECIAL]; + else if (EquivMonst(monster[Miss->_misource].MType->mtype, MT_NSNAKE)) + anim = &monster[Miss->_misource].MType->Anims[MA_ATTACK]; + else + anim = &monster[Miss->_misource].MType->Anims[MA_WALK]; + + missile[mi]._miAnimData = anim->Cels[Miss->_mimfnum]; + } + // need similar section for Fireman + } +} + +/*-----------------------------------------------------------------------* +** Used when we need to "emergency" delete missiles +**-----------------------------------------------------------------------*/ +void ClearMissileSpot(int mi) +{ + app_assert(mi < MAXMISSILES && mi >= 0); + dFlags[missile[mi]._mix][missile[mi]._miy] &= BFMASK_MISSILE; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; +} diff --git a/MISSILES.H b/MISSILES.H new file mode 100644 index 0000000..866170f --- /dev/null +++ b/MISSILES.H @@ -0,0 +1,220 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/MISSILES.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXMISSILES 125 + +#define MIT_ARROW 0 +#define MIT_FIREBOLT 1 +#define MIT_GUARDIAN 2 +#define MIT_PHASE 3 +#define MIT_LIGHTBALL 4 +#define MIT_FIREWALL 5 +#define MIT_FIREBALL 6 +#define MIT_LIGHTCTRL 7 +#define MIT_LIGHTNING 8 +#define MIT_MISEXP 9 +#define MIT_TOWN 10 +#define MIT_FLASH 11 +#define MIT_FLASH2 12 +#define MIT_MANASHIELD 13 +#define MIT_FIREMOVE 14 +#define MIT_CHAIN 15 +#define MIT_CHAINBALL 16 +#define MIT_BLOOD 17 +#define MIT_BONE 18 +#define MIT_METAL 19 +#define MIT_RHINO 20 +#define MIT_MAGMABALL 21 +#define MIT_THINLIGHTCTRL 22 +#define MIT_THINLIGHT 23 +#define MIT_FLARE 24 +#define MIT_FLAREXP 25 +#define MIT_TELE 26 +#define MIT_FARROW 27 +#define MIT_DOOM 28 +#define MIT_FIREONLY 29 +#define MIT_STONE 30 +#define MIT_BLOODR 31 +#define MIT_INVIS 32 +#define MIT_GOLEM 33 +#define MIT_ETHER 34 +#define MIT_SPURT 35 +#define MIT_BOOM 36 +#define MIT_HEAL 37 +#define MIT_FIREWALLC 38 +#define MIT_INFRA 39 +#define MIT_IDENTIFY 40 +#define MIT_WAVE 41 +#define MIT_NOVA 42 +//#define MIT_BLDBOIL 43 +#define MIT_RAGE 43 +#define MIT_APOCA 44 +#define MIT_REPAIR 45 +#define MIT_RECHARGE 46 +#define MIT_DISARM 47 +#define MIT_FLAME 48 +#define MIT_FLAMEC 49 +#define MIT_FIREMAN 50 +#define MIT_KRULL 51 +#define MIT_CBOLT 52 +#define MIT_HBOLT 53 +#define MIT_RESURRECT 54 +#define MIT_TELEKINESIS 55 +#define MIT_LARROW 56 +#define MIT_ACID 57 +#define MIT_ACIDSPLAT 58 +#define MIT_ACIDPUD 59 +#define MIT_HEALOTHER 60 +#define MIT_ELEMENT 61 +#define MIT_RESURRECTBEAM 62 +#define MIT_BONESPIRIT 63 +#define MIT_WEAPEXP 64 +#define MIT_RPORTAL 65 +#define MIT_FIREPLAR 66 +#define MIT_DIABAPOCA 67 +#define MIT_MANA 68 +#define MIT_FMANA 69 +#define MIT_LIGHTWALL 70 +#define MIT_LIGHTWALLC 71 +#define MIT_IMMOLATION 72 +#define MIT_SPECARROW 73 +#define MIT_FBARROW 74 +#define MIT_LTARROW 75 +#define MIT_CBARROW 76 +#define MIT_HBARROW 77 +#define MIT_TELESTAIRS 78 +#define MIT_REFLECT 79 +#define MIT_BERSERK 80 +#define MIT_FLAMEBOX 81 +#define MIT_DISENCHANT 82 +#define MIT_MANAREMOVE 83 +#define MIT_LIGHTBOX 84 +#define MIT_SHOWMAGITEMS 85 +#define MIT_AURA 86 +#define MIT_AURA2 87 +#define MIT_SPIRALFIREBALL 88 +#define MIT_RUNEOFFIRE 89 +#define MIT_RUNEOFLIGHT 90 +#define MIT_RUNEOFNOVA 91 +#define MIT_RUNEOFIMMOLATION 92 +#define MIT_RUNEOFSTONE 93 +#define MIT_BIGEXPLOSION 94 +#define MIT_HORKSPAWN 95 +#define MIT_RANDOM 96 +#define MIT_OPENNEST 97 +#define MIT_ORANGEFLARE 98 +#define MIT_BLUEFLARE 99 +#define MIT_REDFLARE 100 +#define MIT_YELLOWFLARE 101 +#define MIT_BLUE2FLARE 102 +#define MIT_YELLOWEXPLOSION 103 +#define MIT_REDEXPLOSION 104 +#define MIT_BLUEEXPLOSION 105 +#define MIT_BLUE2EXPLOSION 106 +#define MIT_ORANGEEXPLOSION 107 + +#define NUMBER_OF_MISSILE_TYPES (1 + MIT_ORANGEEXPLOSION) + +#define MI_ENEMYMONST 0 +#define MI_ENEMYPLR 1 +#define MI_ENEMYBOTH 2 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + int _mitype; // missile type + int _mix; // missile map x + int _miy; // missile map y + long _mixoff; // offset x from left of map tile + long _miyoff; // offset y from bottom of map tile + long _mixvel; // current x rate + long _miyvel; // current y rate + int _misx; // missile map start x + int _misy; // missile map start y + long _mitxoff; // missile total offset from start x + long _mityoff; // missile total offset from start y + int _mimfnum; // current facing direction + int _mispllvl; // level of missile + BOOL _miDelFlag; // delete flag + BYTE _miAnimType; // data pointer to anim tables + BOOL _miAnimFlags; // various animation related flags + BYTE *_miAnimData; // Data pointer to anim tables + int _miAnimDelay; // anim delay amount + int _miAnimLen; // number of anim frames + long _miAnimWidth; // anim width + long _miAnimWidth2; // anim width2 + int _miAnimCnt; // current anim delay value + int _miAnimAdd; // anim number to add to next frame (-1 backwards) + int _miAnimFrame; // current anim frame + BOOL _miDrawFlag; // draw missile at all + BOOL _miLightFlag; // draw with light sourcing? + BOOL _miPreFlag; // draw missile behind plr,monsters,objects + BOOL _miUniqTrans; // draw missile with special palette translation + int _mirange; // max range of missile + int _misource; // which monster/plr shot me + int _micaster; // monst/plr/damages both. + int _midam; // missile damage + BOOL _miHitFlag; // did it hit a monster or plr? + int _midist; // how long have I been traveling + int _mlid; // light id + int _mirnd; // random seed + long _miVar1; // scratch var 1 + long _miVar2; // scratch var 2 + long _miVar3; // scratch var 3 + long _miVar4; // scratch var 4 + long _miVar5; // scratch var 5 + long _miVar6; // scratch var 6 + long _miVar7; // scratch var 7 + long _miVar8; // scratch var 8 +} MissileStruct; +#define SAVE_MISSILE_SIZE sizeof(MissileStruct) + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern int nummissiles; +extern int missileactive[MAXMISSILES]; +extern int missileavail[MAXMISSILES]; +extern BOOL MissilePreFlag; +extern MissileStruct missile[MAXMISSILES]; +extern int XDirAdd[8]; +extern int YDirAdd[8]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitMissileGFX(); +void FreeMissileGFX(); +void ILoadMissileGFX(BYTE); +void IFreeMissileGFX(); +void InitMissiles(); + +void ProcessMissiles(); +int AddMissile(int, int, int, int, int, int, char, int, int, int); + +//void RndBlood (int, int, int, int, int); + +BOOL MonsterTrapHit(int, int, int, int, int, byte); +BOOL PlayerMHit(int, int, int, int, int, int, byte, BOOL, bool *); +int GetSpellLevel(int, int); +void GetDamageAmt(int, int *, int *); + +void SyncMissAnim(); + +void ClearMissileSpot(int mi); diff --git a/MISSILES.SAV b/MISSILES.SAV new file mode 100644 index 0000000..159028c --- /dev/null +++ b/MISSILES.SAV @@ -0,0 +1,6889 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Missiles file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MISSILES.CPP 3 2/25/97 2:27p Jmcreynolds $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include +#include +#include "sound.h" +#include "missiles.h" +#include "misdat.h" +#include "engine.h" +#include "gendung.h" +#include "lighting.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "monstdat.h" +#include "monstint.h" +#include "control.h" +#include "objects.h" +#include "objdat.h" +#include "spells.h" +#include "cursor.h" +#include "dead.h" +#include "effects.h" +#include "palette.h" +#include "inv.h" +#include "msg.h" +#include "quests.h" +#include "itemdat.h" +#include "multi.h" +#include "trigs.h" +#include "scrollrt.h" + +/*-----------------------------------------------------------------------* +** Constants +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +#define CEL_EXT ".CL2" +#else +#define CEL_EXT ".CEL" +#endif + + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +MissileStruct missile[MAXMISSILES]; +int nummissiles; + +static int missilevars[MAXMISSILES][3]; //0 missile num; 1 var1; 2 var2 +static int nummissilevars; + +int missileactive[MAXMISSILES]; +int missileavail[MAXMISSILES]; + +int XDirAdd[8] = { 1, 0, -1, -1, -1, 0, 1, 1 }; +int YDirAdd[8] = { 1, 1, 1, 0, -1, -1, -1, 0 }; + +// Indexes into the CrawlTable. +static int const CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, + 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 }; + +BOOL ManashieldFlag; +BOOL MissilePreFlag; + +typedef BOOL (*CHECKFUNC)(int x, int y); + +static void GetMissilePos(int i); + +/*-----------------------------------------------------------------------** +**----------------------- General use routines --------------------------** +**-----------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetDamageAmt(int i, int * mind, int * maxd) +{ + int k, sl; + + app_assert(myplr < MAX_PLRS); + app_assert(i < 64); + sl = plr[myplr]._pSplLvl[i] + plr[myplr]._pISplLvlAdd; + + switch (i) { + case SPL_FIREBOLT: + *mind = 1 + (plr[myplr]._pMagic >> 3) + sl; + *maxd = 10 + (plr[myplr]._pMagic >> 3) + sl; + break; + case SPL_HEAL: + *mind = 1 + plr[myplr]._pLevel + sl; + if (plr[myplr]._pClass == CLASS_WARRIOR) *mind = *mind << 1; + else if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD) *mind += (*mind >> 1); + *maxd = 10; + for (k = 0; k < plr[myplr]._pLevel; ++k) *maxd += 4; + for (k = 0; k < sl; ++k) *maxd += 6; + if (plr[myplr]._pClass == CLASS_WARRIOR) *maxd = *maxd << 1; + else if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD) *maxd += (*maxd >> 1); + *mind = -1; + *maxd = -1; + break; + case SPL_LIGHTNING: + *mind = 2; + *maxd = plr[myplr]._pLevel + 2; + break; + case SPL_FLASH: + *mind = plr[myplr]._pLevel; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *mind += *mind >> 1; + *maxd = *mind << 1; // this is not actual(below is) - its a kludge to make it seem acurate text wise + /**maxd = 0; + for (k = 0; k <= plr[myplr]._pLevel; ++k) *maxd += 20; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + *maxd += *maxd >> 1;*/ + break; + case SPL_IDENTIFY: + case SPL_TOWN: + case SPL_STONE: + case SPL_INFRA: + case SPL_PHASE: + case SPL_MANASHLD: + case SPL_DOOM: + case SPL_BLOODR: + case SPL_INVIS: + case SPL_BLOODB: + case SPL_TELE: + case SPL_ETHER: + case SPL_REPAIR: + case SPL_RECHARGE: + case SPL_DISARM: + case SPL_RESURRECT: + case SPL_TELEKINESIS: + case SPL_BONESPIRIT: + *mind = -1; + *maxd = -1; + break; + case SPL_WALL: + *mind = ((2 + plr[myplr]._pLevel) << 2) >> 1; + *maxd = ((20 + plr[myplr]._pLevel) << 2) >> 1; + break; + case SPL_FIREBALL: + *mind = (2 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *maxd = (20 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + break; + case SPL_GUARDIAN: + *mind = 1 + (plr[myplr]._pLevel >> 1); + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *maxd = 10 + (plr[myplr]._pLevel >> 1); + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + break; + case SPL_CHAIN: + // this is not actual - its a kludge to make it seem acurate text wise + *mind = 2 << 1; + *maxd = (plr[myplr]._pLevel + 2) << 1; + break; + case SPL_WAVE: + // this is not actual - its a kludge to make it seem acurate text wise + *mind = ((1 + plr[myplr]._pLevel) << 2) + ((1 + plr[myplr]._pLevel) << 1); + *maxd = ((10 + plr[myplr]._pLevel) << 2) + ((10 + plr[myplr]._pLevel) << 1); + break; + case SPL_NOVA: + // this is not actual - its a kludge to make it seem acurate text wise + *mind = (5 + plr[myplr]._pLevel) >> 1; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *mind = (*mind << 2) + *mind; + *maxd = (30 + plr[myplr]._pLevel) >> 1; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + *maxd = (*maxd << 2) + *maxd; + break; + case SPL_FLAME: + *mind = 2; + *mind += *mind >> 1; + *maxd = (plr[myplr]._pLevel + 4); + *maxd += *maxd >> 1; + break; + case SPL_GOLEM: + *mind = 11; + *maxd = 17; + break; + case SPL_APOCA: + *mind = 0; + for (k = 0; k < plr[myplr]._pLevel; ++k) *mind += 1; + *maxd = 0; + for (k = 0; k < plr[myplr]._pLevel; ++k) *maxd += 6; + break; + case SPL_ELEMENT: + *mind = (2 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *mind += (*mind >> 3); + *maxd = (20 + plr[myplr]._pLevel) << 1; + for (k = sl; k > 0; --k) *maxd += (*maxd >> 3); + break; + case SPL_CBOLT: + *mind = 1; + *maxd = 1 + (plr[myplr]._pMagic >> 2); + break; + case SPL_HBOLT: + *mind = 9 + plr[myplr]._pLevel; + *maxd = 18 + plr[myplr]._pLevel; + break; + case SPL_HEALOTHER: + *mind = 1 + plr[myplr]._pLevel + sl; + if (plr[myplr]._pClass == CLASS_WARRIOR) *mind = *mind << 1; + if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD ) *mind += (*mind >> 1); + *maxd = 10; + for (k = 0; k < plr[myplr]._pLevel; ++k) *maxd += 4; + for (k = 0; k < sl; ++k) *maxd += 6; + if (plr[myplr]._pClass == CLASS_WARRIOR) *maxd = *maxd << 1; + if (plr[myplr]._pClass == CLASS_ROGUE || + plr[myplr]._pClass == CLASS_BARD ) *maxd += (*maxd >> 1); + *mind = -1; + *maxd = -1; + break; + case SPL_BSTAR: + *mind = ((plr[myplr]._pMagic>>1)-(plr[myplr]._pMagic>>3)) + (sl << 1) + sl; + *maxd = *mind; + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int CheckBlock(int fx, int fy, int tx, int ty) +{ + int pn, dir, coll; + + coll = 0; + + while ((fx != tx) || (fy != ty)) { + dir = GetDirection(fx, fy, tx, ty); + fx += XDirAdd[dir]; + fy += YDirAdd[dir]; + app_assert(fx < MAXDUNX); + app_assert(fy < MAXDUNY); + pn = dPiece[fx][fy]; + app_assert(pn <= MAXTILES); + if (nSolidTable[pn]) coll = 1; + } + + return coll; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int FindClosest(int sx, int sy, int rad) +{ + int cr, cidx, cent, cne, mid, tx, ty; + + if (rad > 19) rad = 19; + + for (cr = 1; cr < rad; ++cr) { + cidx = CrawlNum[cr]; + cent = cidx + 1; + for (cne = CrawlTable[cidx]; cne > 0; --cne) { + tx = sx + CrawlTable[cent]; + ty = sy + CrawlTable[(cent + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + mid = dMonster[tx][ty]; + if ((mid > 0) && (CheckBlock(sx, sy, tx, ty) == 0)) + return (mid - 1); + } + cent += 2; + } + } + + return (-1); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static bool SetMissileLocation(int i, int *sx, int *sy, int rad) +{ + bool success = false; + + if (rad > 19) rad = 19; + + for (int cr = 1; cr < rad && !success; ++cr) { + int const cidx = CrawlNum[cr]; + int cent = cidx + 1; + for (int cne = CrawlTable[cidx]; cne > 0; --cne, cent += 2) { + int const tx = *sx + CrawlTable[cent]; + int const ty = *sy + CrawlTable[(cent + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int const pn = dPiece[tx][ty]; + if (!nSolidTable[pn] && dObject[tx][ty] == 0) { + missile[i]._mix = tx; + missile[i]._miy = ty; + *sx = tx; + *sy = ty; + success = true; + break; + } + } + } + } + + return (success); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int GetSpellLevel(int id, int sn) +{ + int rv; + + app_assert(id < MAX_PLRS); + app_assert(sn < 64); + if (id == myplr) + rv = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd; + else + rv = 1; + if (rv < 0 ) rv = 0; + return (rv); +} + +#if 0 // UNUSED +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RndBlood(int x, int y, int type, int dam, int hp) +{ + int pct, str; + + app_assert(hp != 0); + str = 0; + pct = (dam * 100) / hp; + if (pct > 65) str = 1; + if (pct > 80) str = 2; + if (pct > 90) str = 3; + str = 1; + + //AddMissile(x, y, str, 0, 0, type, 0, myplr, 0); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static int GetDirection8(int x1, int y1, int x2, int y2) +{ + BYTE const Dirs[16][16] = { + { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0 + { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1 + { 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2 + { 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, // 3 + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // 4 + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, // 5 + { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 6 + { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 7 + { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 8 + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 9 + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 10 + { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 11 + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 12 + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 13 + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 14 + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }};// 15 + + BYTE const lrtoul[3] = { 3, 4, 5 }; + BYTE const urtoll[3] = { 3, 2, 1 }; + BYTE const lltour[3] = { 7, 6, 5 }; + BYTE const ultolr[3] = { 7, 0, 1 }; + + int mx, my, md; + + mx = abs(x2 - x1); + if (mx > 15) mx = 15; + my = abs(y2 - y1); + if (my > 15) my = 15; + md = Dirs[my][mx]; + + if (x1 > x2) { + if (y1 > y2) md = lrtoul[md]; + else md = urtoll[md]; + } else { + if (y1 > y2) md = lltour[md]; + else md = ultolr[md]; + } + + return (md); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static int GetDirection16(int x1, int y1, int x2, int y2) +{ + const BYTE Dirs[16][16] = { + { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0 + { 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1 + { 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2 + { 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // 3 + { 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 4 + { 4, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // 5 + { 4, 4, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 }, // 6 + { 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 }, // 7 + { 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }, // 8 + { 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1 }, // 9 + { 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1 }, // 10 + { 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1 }, // 11 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }, // 12 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }, // 13 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2 }, // 14 + { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2 }};// 15 + + const BYTE lrtoul[5] = { 6, 7, 8, 9, 10 }; + const BYTE urtoll[5] = { 6, 5, 4, 3, 2 }; + const BYTE lltour[5] = { 14, 13, 12, 11, 10 }; + const BYTE ultolr[5] = { 14, 15, 0, 1, 2 }; + + int mx, my, md; + + mx = abs(x2 - x1); + if (mx > 15) mx = 15; + my = abs(y2 - y1); + if (my > 15) my = 15; + md = Dirs[my][mx]; + + if (x1 > x2) { + if (y1 > y2) md = lrtoul[md]; + else md = urtoll[md]; + } else { + if (y1 > y2) md = lltour[md]; + else md = ultolr[md]; + } + + return (md); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DeleteMissile(int mi, int i) +{ + app_assert(nummissiles <= MAXMISSILES); + missileavail[MAXMISSILES - nummissiles] = mi; + --nummissiles; + + if ((nummissiles > 0) && (i != nummissiles)) { + app_assert(i < MAXMISSILES); + missileactive[i] = missileactive[nummissiles]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void GetMissileVel(int i, int sx, int sy, int dx, int dy, int v) +{ + double dxp, dyp, dr; + + dxp = (((dx - sx) << 5) - ((dy - sy) << 5)) << 16; + dyp = (((dx - sx) << 5) + ((dy - sy) << 5)) << 16; + dr = sqrt((dxp * dxp) + (dyp * dyp)); + app_assert(i < MAXMISSILES); + missile[i]._mixvel = static_cast(((v << 16) * dxp) / dr); + missile[i]._miyvel = static_cast(((v << 15) * dyp) / dr); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void PutMissile(int i) +{ + int mx, my; + + app_assert(i < MAXMISSILES); + mx = missile[i]._mix; + my = missile[i]._miy; + + if (mx <= 0 || my <= 0 || mx >= DMAXX || my >= DMAXY) + missile[i]._miDelFlag = TRUE; + + if (!missile[i]._miDelFlag) { + dFlags[mx][my] |= BFLAG_MISSILE; + if (dMissile[mx][my] == 0) dMissile[mx][my] = (char)i + 1; + else dMissile[mx][my] = -1; + if (missile[i]._miPreFlag) MissilePreFlag = TRUE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static BYTE GetDirNum(int mi) +{ + app_assert(mi < MAXMISSILES); + return (misfiledata[(missile[mi]._miAnimType)].mAnimFAmt >= 8) ? missile[mi]._mimfnum : 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void GetMissilePos(int i) +{ + long mx, my; + long dx, dy; + long lx, ly; // lighting offsets + + app_assert(i < MAXMISSILES); + mx = missile[i]._mitxoff >> 16; + my = missile[i]._mityoff >> 16; + dx = (mx + (my << 1)); + dy = ((my << 1) - mx); + + if (dx < 0) { + lx = -((-dx) >> 3); + dx = -((-dx) >> 6); + } else { + lx = dx >> 3; + dx = dx >> 6; + } + + if (dy < 0) { + ly = -((-dy) >> 3); + dy = -((-dy) >> 6); + } else { + ly = dy >> 3; + dy = dy >> 6; + } + + missile[i]._mix = dx + missile[i]._misx; + missile[i]._miy = dy + missile[i]._misy; + missile[i]._mixoff = mx - ((dx - dy) << 5); + missile[i]._miyoff = my - ((dx + dy) << 4); + ChangeLightOff(missile[i]._mlid, lx - (dx << 3), ly - (dy << 3)); +} + +/*-----------------------------------------------------------------------* + * MoveMissilePos + * + * Adjusts missile's drawing location to prevent overlapping tiles + * Written specifically for monster missiles (e.g., Rhino), which are large. +**-----------------------------------------------------------------------*/ + +static void MoveMissilePos(int i) +{ + int dx,dy; + int mx,my; + + app_assert(i < MAXMISSILES); + switch (missile[i]._mimfnum) { + case 0 : // Down + dx = 1; + dy = 1; + break; + case 1 : // Down Left + dx = 1; + dy = 1; + break; + case 2 : // Left + dx = 0; + dy = 1; + break; + case 3 : // Up Left + dx = 0; + dy = 0; + break; + case 4 : // Up + dx = 0; + dy = 0; + break; + case 5 : // Up Right + dx = 0; + dy = 0; + break; + case 6 : // Right + dx = 1; + dy = 0; + break; + case 7 : // Down Right + dx = 1; + dy = 1; + break; + } + + mx = missile[i]._mix + dx; + my = missile[i]._miy + dy; + + // note -- _misource is the monster which became this missile + if (PosOkMonst(missile[i]._misource,mx,my)) { + missile[i]._mix += dx; + missile[i]._miy += dy; + missile[i]._mixoff -= ((dx - dy) << 5); + missile[i]._miyoff -= ((dx + dy) << 4); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, byte shift) +{ + int hit, hper; + long dam; + int mor; // monster's resist type + int mir; + BOOL resist = FALSE; + BOOL ret; + + app_assert(m < MAXMONSTERS); + if (monster[m].mtalkmsg != 0) return FALSE; + + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) return FALSE; + + app_assert(monster[m].MType != NULL); + if(monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MG_RUN_AWAY) + return FALSE; + + if (monster[m]._mmode == MM_MISSILE) return(FALSE); + + mir = missiledata[t].mResist; + mor = monster[m].mMagicRes; + if( (mor & M_IM && mir == MIMT_MISC) + || (mor & M_IF && mir == MIMT_FIRE) + || (mor & M_IL && mir == MIMT_LGHT)) + return FALSE; + + if( (mor & M_RM && mir == MIMT_MISC) + || (mor & M_RF && mir == MIMT_FIRE) + || (mor & M_RL && mir == MIMT_LGHT)) + resist = TRUE; + + hit = random(68, 100); + hper = 90 - monster[m].mArmorClass - dist; + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (CheckMonsterHit(m, ret)) + return(ret); +#if CHEATS + else if((hit < hper) || simplecheat || cheatflag || (monster[m]._mmode == MM_STONE)) { +#else + else if((hit < hper) || (monster[m]._mmode == MM_STONE)) { +#endif + dam = random(68, maxdam - mindam + 1) + mindam; + if (shift == 0) dam = dam << HP_SHIFT; + if (resist) + monster[m]._mhitpoints -= dam >> 2; + else + monster[m]._mhitpoints -= dam; + +#if CHEATS + if (simplecheat || cheatflag) monster[m]._mhitpoints = 0; +#endif + // rjs - x2 dam if stone - if (monster[m]._mmode == MM_STONE) monster[m]._mhitpoints -= dam; + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) { + if (monster[m]._mmode == MM_STONE) { + M_StartKill(m, -1); + monster[m]._mmode = MM_STONE; + } else M_StartKill(m, -1); + } + else if(resist) + { + PlayEffect(m, MS_GOTHIT); + } + else + { + if (monster[m]._mmode == MM_STONE) { + if (m > 3) M_StartHit(m, -1, dam); // dont let golems get hit + monster[m]._mmode = MM_STONE; + } else { + if (m > 3) M_StartHit(m, -1, dam); // dont let golems get hit + } + } + return(TRUE); + } else return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, byte shift) +{ + int hit, hper; + long dam; + int mor; // monster's resist type + int mir; // missile resistance category + BOOL resist = FALSE; + BOOL ret; + + app_assert(m < MAXMONSTERS); + if (monster[m].mtalkmsg != 0) return(FALSE); + + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) return(FALSE); + + app_assert(monster[m].MData != NULL); + if ((t == MIT_HBOLT) && + (monster[m].MType->mtype != MT_DIABLO) && + (monster[m].MData->mMonstClass != MC_UNDEAD)) return(FALSE); + + app_assert(monster[m].MType != NULL); + if(monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MG_RUN_AWAY) + return FALSE; + + if (monster[m]._mmode == MM_MISSILE) return(FALSE); + + mir = missiledata[t].mResist; + mor = monster[m].mMagicRes; + if( (mor & M_IM && mir == MIMT_MISC) + || (mor & M_IF && mir == MIMT_FIRE) + || (mor & M_IL && mir == MIMT_LGHT) + || (mor & M_IA && mir == MIMT_ACID)) + return FALSE; + + if( (mor & M_RM && mir == MIMT_MISC) + || (mor & M_RF && mir == MIMT_FIRE) + || (mor & M_RL && mir == MIMT_LGHT)) + resist = TRUE; + + hit = random(69, 100); + if (missiledata[t].mType == MIS_WEAP) { + hper = BASE_TO_HIT + plr[pnum]._pLevel - monster[m].mArmorClass - plr[pnum]._pIEnAc; + hper += plr[pnum]._pDexterity + plr[pnum]._pIBonusToHit; + hper -= (dist * dist) >> 1; + if (plr[pnum]._pClass == CLASS_ROGUE) hper += 20; + if (plr[pnum]._pClass == CLASS_WARRIOR || + plr[pnum]._pClass == CLASS_BARD) hper += 10; + } else { + hper = BASE_TO_HIT + plr[pnum]._pMagic - (monster[m].mLevel << 1) - dist; + if (plr[pnum]._pClass == CLASS_SORCEROR) hper += 20; + else if (plr[pnum]._pClass == CLASS_BARD) hper += 10; + } + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (monster[m]._mmode == MM_STONE) hit = 0; + if (CheckMonsterHit(m, ret)) + return(ret); +#if CHEATS + else if((hit < hper) || cheatflag || simplecheat) { +#else + else if (hit < hper) { +#endif + if (t == MIT_BONESPIRIT) + dam = (monster[m]._mhitpoints / 3) >> HP_SHIFT; + else + dam = random(70, maxdam - mindam + 1) + mindam; + if (missiledata[t].mType == MIS_WEAP) { + dam += (dam * plr[pnum]._pIBonusDam) / 100; + dam += plr[pnum]._pIBonusDamMod; + if (plr[pnum]._pClass == CLASS_ROGUE) dam += plr[pnum]._pDamageMod; + else dam += (plr[pnum]._pDamageMod >> 1); + } + if (shift == 0) dam = dam << HP_SHIFT; + if (resist) dam = dam >> 2; + if (pnum == myplr) monster[m]._mhitpoints -= dam; + + if (plr[pnum]._pIFlags & IAF_MNOHEAL) monster[m]._mFlags |= MFLAG_NOHEAL; +#if CHEATS + //if (pnum == myplr && cheatflag) monster[m]._mhitpoints = 0; +#endif + //rjs - x2 stone dam - if (pnum == myplr && monster[m]._mmode == MM_STONE) monster[m]._mhitpoints -= dam; + + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) { + if (monster[m]._mmode == MM_STONE) { + M_StartKill(m, pnum); + monster[m]._mmode = MM_STONE; + } else M_StartKill(m, pnum); + //(old) AddPlrExperience(pnum, monster[m].mLevel, monster[m].mExp); + //(new, but moved) AddPlrMonstExper(monster[m].mLevel, monster[m].mExp, monster[m].mWhoHit); + } + else if(resist) + { + PlayEffect(m, MS_GOTHIT); + } + else + { + if (monster[m]._mmode == MM_STONE) { + if (m > 3) M_StartHit(m, pnum, dam); + monster[m]._mmode = MM_STONE; + } else { + if ((missiledata[t].mType == MIS_WEAP) && (plr[pnum]._pIFlags & IAF_KNOCKBACK)) M_GetKnockback(m); + if (m > 3) M_StartHit(m, pnum, dam); + } + } + // wake up monster if it's inactive + if(!monster[m]._msquelch) + { + monster[m]._msquelch = 255; + monster[m]._lastx = plr[pnum]._px; + monster[m]._lasty = plr[pnum]._py; + } + return(TRUE); + } else return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, byte shift, BOOL earflag) +{ + int hit, hper, tac; + long dam; + int blk, blkper, blkdir; + int resper = 0; + + app_assert(pnum < MAX_PLRS); + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) return(FALSE); + if (plr[pnum]._pInvincible) return(FALSE); + if (((plr[pnum]._pSpellFlags & SF_ETHER) != 0) && (missiledata[mtype].mType == MIS_WEAP)) return(FALSE); + + hit = random(72, 100); +#if CHEATS + if (simplecheat || cheatflag) hit = 1000; +#endif + if (missiledata[mtype].mType == MIS_WEAP) { + // rjs tac = (byte)plr[pnum]._pArmorClass + plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + tac += (plr[pnum]._pDexterity / 5); + if (m != -1) hper = 30 + monster[m].mHit - tac + ((monster[m].mLevel - plr[pnum]._pLevel) << 1) - (dist << 1); + else hper = 100 - (tac >> 1) - (dist << 1); + } else { + if (m != -1) hper = 40 + (monster[m].mLevel << 1) - (plr[pnum]._pLevel << 1) - (dist << 1); + else hper = 40; + } + if (hper < 10) hper = 10; + if ((currlevel == 14) && (hper < 20)) hper = 20; + if ((currlevel == 15) && (hper < 25)) hper = 25; + if ((currlevel == 16) && (hper < 30)) hper = 30; + if (((plr[pnum]._pmode == PM_STAND) || (plr[pnum]._pmode == PM_ATTACK)) && (plr[pnum]._pBlockFlag)) blk = random(73, 100); + else blk = 100; + if (shift == 1) blk = 100; // can't block continous damage spells + if (mtype == MIT_ACIDPUD) blk = 100; // can't block acid puddles (drb) + if (m != -1) blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[m].mLevel - plr[pnum]._pLevel) << 1); + else blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity; + if (blkper < 0) blkper = 0; + if (blkper > 100) blkper = 100; + switch(missiledata[mtype].mResist) { + case MIMT_FIRE: + resper = plr[pnum]._pFireResist; + break; + case MIMT_LGHT: + resper = plr[pnum]._pLghtResist; + break; + case MIMT_MISC: + case MIMT_ACID: + resper = plr[pnum]._pMagResist; + break; + default: + resper = 0; + break; + } + if (hit < hper) { + // Hit, so calc damage + if (mtype == MIT_BONESPIRIT) { + dam = plr[pnum]._pHitPoints / 3; + } else { + if (shift == 0) { + dam = (maxd - mind + 1) << HP_SHIFT; + dam = random(75, dam) + (mind << HP_SHIFT); + if (plr[pnum]._pIFlags & IAF_TRAPDAM) dam = dam >> 1; + dam += (plr[pnum]._pIGetHit << HP_SHIFT); + if (dam < (1 << HP_SHIFT)) dam = (1 << HP_SHIFT); + } else { + dam = maxd - mind + 1; + dam = random(75, dam) + mind; + if (plr[pnum]._pIFlags & IAF_TRAPDAM) dam = dam >> 1; + dam += plr[pnum]._pIGetHit; + if (dam < (1 << HP_SHIFT)) dam = (1 << HP_SHIFT); + } + } + + // Did I resist? + if (resper > 0) { + dam -= (dam * resper) / 100; + if (pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - plr[pnum]._pHitPoints = 0; + StartPlrKill(pnum, earflag); + } + else { + // No get hit + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySfxLoc(PS_MAGE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySfxLoc(PS_MONK69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySfxLoc(PS_BARD69, plr[pnum]._px, plr[pnum]._py); + #endif + + //PlaySfxLoc(PS_LGHIT, plr[pnum]._px, plr[pnum]._py); + drawhpflag = TRUE; + } + return(TRUE); + } else { + // Did I block? + if (blk < blkper) { + if (m != -1) blkdir = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[m]._mx, monster[m]._my); + else blkdir = plr[pnum]._pdir; + StartPlrBlock(pnum, blkdir); + return(TRUE); + } else { + if (pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - plr[pnum]._pHitPoints = 0; + StartPlrKill(pnum, earflag); + } else StartPlrHit(pnum, dam, FALSE); + return(TRUE); + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, byte shift) +{ + int hit, hper, tac; + long dam; + int blk, blkper, blkdir; + int resper; + + // pnum is missiles source + // p is missiles dest + + app_assert(p < MAX_PLRS); + if (plr[p]._pInvincible) return(FALSE); + if (mtype == MIT_HBOLT) return(FALSE); + if (((plr[p]._pSpellFlags & SF_ETHER) != 0) && (missiledata[mtype].mType == MIS_WEAP)) return(FALSE); + + switch(missiledata[mtype].mResist) { + case MIMT_FIRE: + resper = plr[p]._pFireResist; + break; + case MIMT_LGHT: + resper = plr[p]._pLghtResist; + break; + case MIMT_MISC: + case MIMT_ACID: + resper = plr[p]._pMagResist; + break; + default: + resper = 0; + break; + } + hit = random(69, 100); + if (missiledata[mtype].mType == MIS_WEAP) { + //rjs tac = (byte)plr[p]._pArmorClass + plr[p]._pIAC + plr[p]._pIBonusAC; + tac = plr[p]._pIAC + plr[p]._pIBonusAC; + tac += (plr[p]._pDexterity / 5); + hper = BASE_TO_HIT + plr[pnum]._pLevel - tac; + hper += plr[pnum]._pDexterity + plr[pnum]._pIBonusToHit; + hper -= (dist * dist) >> 1; + if (plr[pnum]._pClass == CLASS_ROGUE) hper += 20; + if (plr[pnum]._pClass == CLASS_WARRIOR) hper += 10; + } else { + hper = BASE_TO_HIT + plr[pnum]._pMagic - (plr[p]._pLevel << 1) - dist; + if (plr[pnum]._pClass == CLASS_SORCEROR) hper += 20; + } + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (hit < hper) { + // Hit, calc blk % + if (((plr[p]._pmode == PM_STAND) || (plr[p]._pmode == PM_ATTACK)) && (plr[p]._pBlockFlag)) blk = random(73, 100); + else blk = 100; + if (shift == 1) blk = 100; // can't block continous damage spells + blkper = plr[p]._pBaseToBlk + plr[p]._pDexterity - ((plr[pnum]._pLevel - plr[p]._pLevel) << 1); + if (blkper < 0) blkper = 0; + if (blkper > 100) blkper = 100; + // Hit, so calc damage + if (mtype == MIT_BONESPIRIT) { + dam = plr[p]._pHitPoints / 3; + } else { + dam = random(70, maxdam - mindam + 1) + mindam; + if (missiledata[mtype].mType == MIS_WEAP) { + dam += (dam * plr[pnum]._pIBonusDam) / 100; + dam += plr[pnum]._pIBonusDamMod + plr[pnum]._pDamageMod; + } + if (shift == 0) dam = dam << HP_SHIFT; + } + // NEW! Take 1/2 damage from plr spells (drb 11/23) + if (missiledata[mtype].mType != MIS_WEAP) dam = dam >> 1; + // Did I resist? + if (resper > 0) { + dam -= (dam * resper) / 100; + // No get hit + if (pnum == myplr) NetSendCmdDamage(TRUE, p, dam); + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySfxLoc(PS_MAGE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySfxLoc(PS_MONK69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySfxLoc(PS_BARD69, plr[pnum]._px, plr[pnum]._py); + #endif + + //PlaySfxLoc(PS_LGHIT, plr[p]._px, plr[p]._py); + return(TRUE); + } else { + // Did I block? + if (blk < blkper) { + blkdir = GetDirection(plr[p]._px, plr[p]._py, plr[pnum]._px, plr[pnum]._py); + StartPlrBlock(p, blkdir); + return(TRUE); + } else { + if (pnum == myplr) NetSendCmdDamage(TRUE, p, dam); + StartPlrHit(p, dam, FALSE); + return(TRUE); + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void CheckMissileCol(int i, int mindam, int maxdam, byte shift, int mx, int my, byte nodel) +{ + int pn,oi; + BOOL earflag; + + app_assert(i < MAXMISSILES); + app_assert(mx < MAXDUNX); + app_assert(my < MAXDUNY); + if ((missile[i]._miAnimType == MF_FIRE) + || (missile[i]._miAnimType == MF_LIGHTNING && missile[i]._mixvel == 0 && missile[i]._miyvel == 0) + || (missile[i]._misource == -1)) { + if (dMonster[mx][my] > 0) { + if (missile[i]._miAnimType == MF_FIRE + || missile[i]._miAnimType == MF_LIGHTNING) { + if (MonsterMHit(missile[i]._misource, dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } else { + if (MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + } + if (dPlayer[mx][my] > 0) { + if (missile[i]._miAnimType == MF_FIRE + || missile[i]._miAnimType == MF_LIGHTNING) earflag = TRUE; + else earflag = FALSE; + if (PlayerMHit(dPlayer[mx][my] - 1, -1, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, earflag)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + } else { + if (missile[i]._micaster == MI_ENEMYMONST) { + if (dMonster[mx][my] > 0) { + if (MonsterMHit(missile[i]._misource, dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } else { + if ((dMonster[mx][my] < 0) && (monster[-(dMonster[mx][my] + 1)]._mmode == MM_STONE)) { + if (MonsterMHit(missile[i]._misource, -(dMonster[mx][my] + 1), mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + } + if ((dPlayer[mx][my] > 0) && ((dPlayer[mx][my]-1) != missile[i]._misource)) { + if (Plr2PlrMHit(missile[i]._misource, dPlayer[mx][my]-1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + } else { + if (((monster[missile[i]._misource]._mFlags & MFLAG_MID) != 0) && ((dMonster[mx][my] > 0) && (monster[(dMonster[mx][my] - 1)]._mFlags & MFLAG_MKILLER) != 0)) { + if (MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + if (dPlayer[mx][my] > 0) { + if (PlayerMHit(dPlayer[mx][my] - 1, missile[i]._misource, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, FALSE)) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = TRUE; + } + } + } + } + + if (dObject[mx][my] != 0) { + if (dObject[mx][my] > 0) oi = dObject[mx][my] - 1; + else oi = -(dObject[mx][my] + 1); + if (!object[oi]._oMissFlag) { + if (object[oi]._oBreak == OBJ_BREAKABLE) BreakObject(-1, oi); + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = FALSE; + } + } + + pn = dPiece[mx][my]; + app_assert(pn <= MAXTILES); + if (nMissileTable[pn]) { + if (nodel == 0) missile[i]._mirange = 0; + missile[i]._miHitFlag = FALSE; + } + + if ((missile[i]._mirange == 0) && (missiledata[missile[i]._mitype].miSFX != -1)) { + PlaySfxLoc(missiledata[missile[i]._mitype].miSFX, missile[i]._mix, missile[i]._miy); + } +} + +static void SetMissAnim(int mi, int animtype) +{ + int dir; + + app_assert(mi < MAXMISSILES); + dir = missile[mi]._mimfnum; + missile[mi]._miAnimType = animtype; + + missile[mi]._miAnimFlags = misfiledata[animtype].mFlags; + missile[mi]._miAnimData = misfiledata[animtype].mAnimData[dir]; + missile[mi]._miAnimDelay = misfiledata[animtype].mAnimDelay[dir]; + missile[mi]._miAnimLen = misfiledata[animtype].mAnimLen[dir]; + missile[mi]._miAnimWidth = misfiledata[animtype].mAnimWidth[dir]; + missile[mi]._miAnimWidth2 = misfiledata[animtype].mAnimWidth2[dir]; + missile[mi]._miAnimCnt = 0; + missile[mi]._miAnimFrame = 1; +} + + +void SetMissDir(int mi, int dir) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._mimfnum = dir; + SetMissAnim(mi, missile[mi]._miAnimType); +} + +/*-----------------------------------------------------------------------** +**---------------------- Initialization Routines ------------------------** +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +void ILoadMissileGFX(BYTE mf) { + int i; + char strbuff[256]; + BYTE *p; + MisFileData * pMisDat; + + pMisDat = &misfiledata[mf]; + if (pMisDat->mFlags & MFF_MULTI) { + // All directions are packed into one file + sprintf(strbuff,"Missiles\\%s" CEL_EXT, pMisDat->mAnimPath); + p = LoadFileInMemSig(strbuff,NULL,'MISS'); + for (i = 0; i < pMisDat->mAnimFAmt; ++i) + pMisDat->mAnimData[i] = p + (reinterpret_cast(p))[i]; + } + else if (pMisDat->mAnimFAmt == 1) { + sprintf(strbuff,"Missiles\\%s" CEL_EXT, pMisDat->mAnimPath); + if(! pMisDat->mAnimData[0]) + pMisDat->mAnimData[0] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } + else { + for (i = 0; i < pMisDat->mAnimFAmt; ++i) { + sprintf(strbuff, "Missiles\\%s%i" CEL_EXT, pMisDat->mAnimPath, i + 1); + if(! pMisDat->mAnimData[i]) + pMisDat->mAnimData[i] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +void ILoadMissileGFX(BYTE mf) { + int i; + char strbuff[256]; + BYTE *p; + + if (misfiledata[mf].mFlags & MFF_MULTI) { + // All directions are packed into one file + sprintf(strbuff,"Missiles\\%s.CEL", misfiledata[mf].mAnimPath); + p = LoadFileInMemSig(strbuff,NULL,'MISS'); + for (i = 0; i < misfiledata[mf].mAnimFAmt; ++i) { + misfiledata[mf].mAnimData[i] = p + *static_cast(p + (i<<2)); + } + } + else if (misfiledata[mf].mAnimFAmt == 1) { + sprintf(strbuff,"Missiles\\%s.CEL", misfiledata[mf].mAnimPath); + if(! misfiledata[mf].mAnimData[0]) + misfiledata[mf].mAnimData[0] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } else { + for (i = 0; i < misfiledata[mf].mAnimFAmt; ++i) { + sprintf(strbuff, "Missiles\\%s%i.CEL", misfiledata[mf].mAnimPath, i + 1); + if(! misfiledata[mf].mAnimData[i]) + misfiledata[mf].mAnimData[i] = LoadFileInMemSig(strbuff,NULL,'MISS'); + } + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitMissileGFX() +{ + int i; + + for (i = 0; misfiledata[i].mAnimFAmt; ++i) { + if (!(misfiledata[i].mFlags & MFF_MONSTONLY)) { + ILoadMissileGFX(i); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void FreeMissileFile(int i) +{ + int j; + void * y; + + if (misfiledata[i].mFlags & MFF_MULTI) + { + if(misfiledata[i].mAnimData[0]) + { + y = static_cast (misfiledata[i].mAnimData[0] - (misfiledata[i].mAnimFAmt << 2)); + DiabloFreePtr(y); + misfiledata[i].mAnimData[0] = NULL; + } + } + else + { + for (j = 0; j < misfiledata[i].mAnimFAmt; ++j) + if(misfiledata[i].mAnimData[j]) + { + DiabloFreePtr(misfiledata[i].mAnimData[j]); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeMissileGFX() +{ + int i; + + for (i = 0; misfiledata[i].mAnimFAmt; ++i) { + if (!(misfiledata[i].mFlags & MFF_MONSTONLY)) { + FreeMissileFile(i); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void IFreeMissileGFX() +{ + int i; + + for (i = 0; misfiledata[i].mAnimFAmt; ++i) + if(misfiledata[i].mFlags & MFF_MONSTONLY) + FreeMissileFile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitMissiles() +{ + int i, j, mx; + + // Delete any active infravision/ etheralize + plr[myplr]._pSpellFlags &= ~SF_ETHER; + if (plr[myplr]._pInfraFlag == TRUE) { + app_assert(nummissiles <= MAXMISSILES); + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + app_assert(mx < MAXMISSILES); + if ((missile[mx]._mitype == MIT_INFRA) && (missile[mx]._misource == myplr)) + CalcPlrItemVals(missile[mx]._misource,TRUE); + } + } + + nummissiles = 0; + for (i = 0; i < MAXMISSILES; ++i) { + missileavail[i] = i; + missileactive[i] = 0; + } + + nummissilevars = 0; + for (i = 0; i < MAXMISSILES; ++i) { + missilevars[i][0] = -1; + missilevars[i][1] = 0; + missilevars[i][2] = 0; + } + + for (j = 0; j < DMAXY; ++j) { + for (i = 0; i < DMAXX; ++i) { + dFlags[i][j] = dFlags[i][j] & ~BFLAG_MISSILE; + } + } +} + +/*-----------------------------------------------------------------------** +**------------------ Missile Initialization Routines --------------------** +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfFire(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + UseMana(id, SPL_RUNEOFFIRE); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_MISEXP; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfLight(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + UseMana(id, SPL_RUNEOFLIGHT); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_LIGHTBALL; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + UseMana(id, SPL_RUNEOFNOVA); + } + if (SetMissileLocation(mi, &sx, &sy, 10)) { + missile[mi]._miVar1 = MIT_NOVA; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(sx, sy, 8); + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfImmolation(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + UseMana(id, SPL_RUNEOFIMMOLATION); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_IMMOLATION; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRuneOfStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + UseMana(id, SPL_RUNEOFSTONE); + } + if (SetMissileLocation(mi, &dx, &dy, 10)) { + missile[mi]._miVar1 = MIT_STONE; + missile[mi]._miDelFlag = FALSE; + missile[mi]._mlid = AddLight(dx, dy, 8); + } + else missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddReflect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + if (plr[id]._pReflectCount < 0) + plr[id]._pReflectCount = 0; + + plr[id]._pReflectCount += GetSpellLevel(id, SPL_REFLECT) * plr[id]._pLevel; + UseMana(id, SPL_REFLECT); + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBerserk(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (id >= 0) { + + app_assert(mi < MAXMISSILES); + missile[mi]._misource = id; + + // search in a 5 radius around tile clicked for monster + for (int k = 0; k < 6; ++k) { + int const l = CrawlNum[k]; + int j = l + 1; + for (int i = CrawlTable[l]; i > 0; --i, j += 2) { + int const tx = dx + CrawlTable[j]; + int const ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int mid = dMonster[tx][ty]; + if (mid > 0) --mid; + else mid = -(mid + 1); + + if ((mid > 3) + && (monster[mid]._uniqtype == 0) + && (monster[mid]._mAi != AI_DIABLO) + && (monster[mid]._mmode != MM_FADEIN) + && (monster[mid]._mmode != MM_FADEOUT) + //&& (monster[mid]._mmode != MM_DEATH) + && (monster[mid]._mmode != MM_MISSILE)) { + i = -99; + k = 6; + int const SpellLevel = GetSpellLevel(id, SPL_BERSERK); + monster[mid]._mFlags |= MFLAG_BERSERK | MFLAG_MKILLER; + monster[mid].mMinDamage = static_cast(SpellLevel + monster[mid].mMinDamage * (1.0 + (0.01 * (random(145,10) + 20)))); + monster[mid].mMaxDamage = static_cast(SpellLevel + monster[mid].mMaxDamage * (1.0 + (0.01 * (random(145,10) + 20)))); + monster[mid].mMinDamage2 = static_cast(SpellLevel + monster[mid].mMinDamage2 * (1.0 + (0.01 * (random(145,10) + 20)))); + monster[mid].mMaxDamage2 = static_cast(SpellLevel + monster[mid].mMaxDamage2 * (1.0 + (0.01 * (random(145,10) + 20)))); + UseMana(id, SPL_BERSERK); + break; + } + } + } + } + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddDisEnchant(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._misource = id; + + // search in a 3 radius around chest trap for players. + for (int k = 0; k < 3; ++k) { + int const l = CrawlNum[k]; + int j = l + 1; + for (int i = CrawlTable[l]; i > 0; --i, j += 2) { + int const tx = sx + CrawlTable[j]; + int const ty = sy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int pid = dPlayer[tx][ty]; + + if (pid == 0) + continue; + + if (pid > 0) --pid; + else pid = -(pid + 1); + + // Belt items only. + if (random(205, 2)) { + // distroy healing and mana potions && 1/2 rejuvination. + for (int splIndex = 0; splIndex < MAXSPD; ++splIndex) { + if (plr[pid].SpdList[splIndex]._itype == IT_MISC + && (plr[pid].SpdList[splIndex]._iMiscId == IMID_PLHEAL + || plr[pid].SpdList[splIndex]._iMiscId == IMID_PHEAL + || plr[pid].SpdList[splIndex]._iMiscId == IMID_PMANA + || plr[pid].SpdList[splIndex]._iMiscId == IMID_PFMANA + || plr[pid].SpdList[splIndex]._iMiscId == IMID_REJUV) + ) { + RemoveSpdBarItem(pid, splIndex); + } + else if (plr[pid].SpdList[splIndex]._iMiscId == IMID_FREJUV){ + int const idata = ItemMiscIdIdx(IMID_REJUV); + SetPlrHandItem(&plr[pid].HoldItem, idata); + GetPlrHandSeed(&plr[pid].HoldItem); + plr[pid].HoldItem._iStatFlag = TRUE; + plr[pid].SpdList[splIndex] = plr[pid].HoldItem; + } + } + } + else if (random(206, 2)) { + // downgrade full potions to partial + // Partical go away. + for (int splIndex = 0; splIndex < MAXSPD; ++splIndex) { + if (plr[pid].SpdList[splIndex]._itype == IT_MISC ) { + switch (plr[pid].SpdList[splIndex]._iMiscId) + { + case IMID_PHEAL: + { + int const idata = ItemMiscIdIdx(IMID_PLHEAL); + SetPlrHandItem(&plr[pid].HoldItem, idata); + GetPlrHandSeed(&plr[pid].HoldItem); + plr[pid].HoldItem._iStatFlag = TRUE; + plr[pid].SpdList[splIndex] = plr[pid].HoldItem; + } + break; + case IMID_PFMANA: + { + int const idata = ItemMiscIdIdx(IMID_PMANA); + SetPlrHandItem(&plr[pid].HoldItem, idata); + GetPlrHandSeed(&plr[pid].HoldItem); + plr[pid].HoldItem._iStatFlag = TRUE; + plr[pid].SpdList[splIndex] = plr[pid].HoldItem; + } + break; + case IMID_FREJUV: + { + int const idata = ItemMiscIdIdx(IMID_REJUV); + SetPlrHandItem(&plr[pid].HoldItem, idata); + GetPlrHandSeed(&plr[pid].HoldItem); + plr[pid].HoldItem._iStatFlag = TRUE; + plr[pid].SpdList[splIndex] = plr[pid].HoldItem; + } + break; + case IMID_PMANA: + case IMID_PLHEAL: + case IMID_REJUV: + RemoveSpdBarItem(pid, splIndex); + break; + } + force_redraw = FULLDRAW; + } + } + } + else if (random(207, 2)) { + // convert rejuventation to healing or mana. + for (int splIndex = 0; splIndex < MAXSPD; ++splIndex) { + if (plr[pid].SpdList[splIndex]._itype == IT_MISC ) { + if(plr[pid].SpdList[splIndex]._iMiscId == IMID_REJUV) { + int const idata = ItemMiscIdIdx(random(210,2) ? IMID_PLHEAL : IMID_PMANA); + SetPlrHandItem(&plr[pid].HoldItem, idata); + GetPlrHandSeed(&plr[pid].HoldItem); + plr[pid].HoldItem._iStatFlag = TRUE; + plr[pid].SpdList[splIndex] = plr[pid].HoldItem; + } + else if(plr[pid].SpdList[splIndex]._iMiscId == IMID_FREJUV) { + int const idata = ItemMiscIdIdx(random(211,2) ? IMID_PHEAL : IMID_PFMANA); + SetPlrHandItem(&plr[pid].HoldItem, idata); + GetPlrHandSeed(&plr[pid].HoldItem); + plr[pid].HoldItem._iStatFlag = TRUE; + plr[pid].SpdList[splIndex] = plr[pid].HoldItem; + } + force_redraw = FULLDRAW; + } + } + } + else if (random(208, 5)) { + // distroy scrolls and oils. + for (int splIndex = 0; splIndex < MAXSPD; ++splIndex) { + if ( (plr[pid].SpdList[splIndex]._iMiscId > IMID_FIRSTOIL + && plr[pid].SpdList[splIndex]._iMiscId < IMID_LASTOIL) + || plr[pid].SpdList[splIndex]._iMiscId == IMID_SCROLL + || plr[pid].SpdList[splIndex]._iMiscId == IMID_TSCROLL + ) { + RemoveSpdBarItem(pid, splIndex); + } + } + } + } + } + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddManaRemove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._misource = id; + + // search in a 3 radius around chest trap for players. + for (int k = 0; k < 3; ++k) { + int const l = CrawlNum[k]; + int j = l + 1; + for (int i = CrawlTable[l]; i > 0; --i, j += 2) { + int const tx = sx + CrawlTable[j]; + int const ty = sy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int pid = dPlayer[tx][ty]; + + if (pid == 0) + continue; + + if (pid > 0) --pid; + else pid = -(pid + 1); + + plr[pid]._pMana = 0; + plr[pid]._pManaBase = plr[pid]._pMana - (plr[pid]._pMaxMana - plr[pid]._pMaxManaBase); + CalcPlrInv(pid, FALSE); + drawmanaflag = TRUE; + } + } + } + missile[mi]._mirange = 0; + missile[mi]._miDelFlag = TRUE; + + app_assert(mi < MAXMISSILES); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + if (mienemy == MI_ENEMYMONST) { + if (plr[id]._pClass == CLASS_ROGUE) GetMissileVel(mi,sx,sy,dx,dy,31+(plr[id]._pLevel>>2)); + else if (plr[id]._pClass == CLASS_WARRIOR) GetMissileVel(mi,sx,sy,dx,dy,31+(plr[id]._pLevel>>3)); + else GetMissileVel(mi,sx,sy,dx,dy,32); + } else GetMissileVel(mi,sx,sy,dx,dy,32); + + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 5); + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int av; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + if (mienemy == MI_ENEMYMONST) { + av = 32; + if (plr[id]._pIFlags & IAF_RNDARROW) av = random(64, 32) + 16; // rnd arrow speed + if (plr[id]._pClass == CLASS_ROGUE) av += (plr[id]._pLevel-1) >> 2; // rouge level speed increase + if (plr[id]._pClass == CLASS_WARRIOR) av += (plr[id]._pLevel-1) >> 3; // warrior level speed increase + GetMissileVel(mi,sx,sy,dx,dy,av); + } else GetMissileVel(mi,sx,sy,dx,dy,32); + + app_assert(mi < MAXMISSILES); + missile[mi]._miAnimFrame = GetDirection16(sx,sy,dx,dy) + 1; + + missile[mi]._mirange = 256; + + //PutMissile(mi); +} + +void AddSpecialArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int extraspeed = 0; + +// if ((sx == dx) && (sy == dy)) { +// dx += XDirAdd[midir]; +// dy += YDirAdd[midir]; +// } + + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) + { + if (plr[id]._pClass == CLASS_ROGUE) + extraspeed = (plr[id]._pLevel-1) >> 2; // rogue level speed increase + else if (plr[id]._pClass == CLASS_WARRIOR) + extraspeed = (plr[id]._pLevel-1) >> 3; // warrior level speed increase + } + + missile[mi]._mirange = 1; + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._miVar3 = extraspeed; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void GetVileMissPos(int mi, int dx, int dy) +{ + int xx, yy; + app_assert(mi < MAXMISSILES); + for (int l = 1; l < 50; ++l) { + for (int j = -l; j <= l; ++j) { + yy = dy + j; + for (int i = -l; i <= l; ++i) { + xx = dx + i; + if (PosOkPlayer(myplr,xx,yy)) { + missile[mi]._mix = xx; + missile[mi]._miy = yy; + return; + } + } + } + } + // There is just no way it will ever reach here + missile[mi]._mix = dx; + missile[mi]._miy = dy; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define DIST(x,y,d) (abs(x) < d && abs(y) < d) + +// Flag for fireman missile +#define MIF_DIDHIT 1 + +#define MINAWAY 3 +#define MAXAWAY 6 + +void AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_PHASE) || !PRE_BETA + int pn, r1, r2; + + int nTries = 0; + do { + // don't get stuck in an infinite loop... + if (++nTries > 500) { + r1 = 0; + r2 = 0; + break; + } + + r1 = random(58, MAXAWAY - MINAWAY) + MINAWAY + 1; + r2 = random(58, MAXAWAY - MINAWAY) + MINAWAY + 1; + if (random(58, 2) == 1) r1 = -r1; + if (random(58, 2) == 1) r2 = -r2; + pn = dPiece[sx + r1][sy + r2]; + } while (nSolidTable[pn] != 0 || dObject[sx + r1][sy + r2] != 0 || dMonster[sx + r1][sy + r2] != 0); + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = 2; + missile[mi]._miVar1 = 0; + +// special code for Vile Betrayer quest + if ((setlevel) && (setlvlnum == 5)) { + int oi = dObject[dx][dy]-1; + if ((object[oi]._otype == OBJ_MCIRCLE1) || (object[oi]._otype == OBJ_MCIRCLE2)) { + missile[mi]._mix = dx; + missile[mi]._miy = dy; + if (!PosOkPlayer(myplr, dx, dy)) GetVileMissPos(mi, dx, dy); + } + } + else { + missile[mi]._mix = sx + r1; + missile[mi]._miy = sy + r2; + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_PHASE); + } + +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +#undef max +void AddTeleStairs(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int minDist = std::numeric_limits::is_specialized && std::numeric_limits::is_bounded + ? std::numeric_limits::max() : 99999; + if (id >= 0) { + sx = plr[id]._px; + sy = plr[id]._py; + } + + int rx = sx; + int ry = sy; + + for (int i = 0;i < numtrigs && i < MAXTRIGGERS; ++i) { + if (trigs[i]._tmsg == WM_DIABTWARPUP + || trigs[i]._tmsg == WM_DIABPREVLVL + || trigs[i]._tmsg == WM_DIABNEXTLVL + || trigs[i]._tmsg == WM_DIABRTNLVL) { + + int triggerx; + int triggery; + + if ((leveltype == 1 || leveltype == 2) + && (trigs[i]._tmsg == WM_DIABNEXTLVL + || trigs[i]._tmsg == WM_DIABPREVLVL + || trigs[i]._tmsg == WM_DIABRTNLVL) ){ + triggerx = trigs[i]._tx; + triggery = trigs[i]._ty + 1; + } + else { + triggerx = trigs[i]._tx + 1; + triggery = trigs[i]._ty; + } + + int xdiff = sx - triggerx; + xdiff *= xdiff; + int ydiff = sy - triggery; + ydiff *= ydiff; + int const NewDist = xdiff + ydiff; + + if (NewDist < minDist) + { + minDist = NewDist; + rx = triggerx; + ry = triggery; + } + + } + } + + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = 2; + missile[mi]._miVar1 = 0; + missile[mi]._mix = rx; + missile[mi]._miy = ry; + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_TELESTAIRS); + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBOLT) || !PRE_BETA + int sp, i, mx; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + + app_assert(mi < MAXMISSILES); + if (micaster == MI_ENEMYMONST) + { + app_assert(nummissiles <= MAXMISSILES); + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + app_assert(mx < MAXMISSILES); + if ((missile[mx]._mitype == MIT_GUARDIAN) && + (missile[mx]._misource == id) && (missile[mx]._miVar3 == mi)) { + break; + } + } + if (i == nummissiles) UseMana(id, SPL_FIREBOLT); + + if (id != -1) { + sp = 16 + (missile[mi]._mispllvl << 1); + if (sp >= 63) sp = 63; + } else sp = 16; + } + else + sp = 26; + + GetMissileVel(mi,sx,sy,dx,dy,sp); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES); + // Graphics don't line up, so we have to move them... + missile[mi]._mitxoff += 3*missile[mi]._mixvel; + missile[mi]._mityoff += 3*missile[mi]._miyvel; + + GetMissilePos(mi); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddKrull(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; +// missile[mi]._mlid = AddLight(sx, sy, 8); + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_TELE) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty; + + app_assert(dx < MAXDUNX); + app_assert(dy < MAXDUNY); + + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty] | dPlayer[tx][ty]) == 0) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + k = 6; + break; + } + } + j += 2; + } + } + + if (missile[mi]._miDelFlag == FALSE) { + UseMana(id, SPL_TELE); + missile[mi]._mirange = 2; + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + app_assert(mi < MAXMISSILES); + missile[mi]._midam = dam; + + missile[mi]._miAnimFrame = random(63, 8) + 1; + + missile[mi]._mirange = 255; + + if (id < 0) { + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + } else { + missile[mi]._miVar1 = plr[id]._px; + missile[mi]._miVar2 = plr[id]._py; + } + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES); + missile[mi]._midam = (random(53, 10) + random(53, 10) + 2 + (id > 0) ? plr[id]._pLevel : currlevel) << 4; + missile[mi]._midam = missile[mi]._midam >> 1; + + GetMissileVel(mi,sx,sy,dx,dy,16); + + missile[mi]._mirange = 10; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._mirange += 10; + + if (mienemy != MI_ENEMYMONST || id < 0) // trap or somesuch + { + missile[mi]._mirange = missile[mi]._mirange + currlevel; + } + else + { + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + } + missile[mi]._mirange = missile[mi]._mirange << 4; + + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) + { + missile[mi]._midam = (random(60, 10) + random(60, 10) + 2 + plr[id]._pLevel) << 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + + i = 16 + (missile[mi]._mispllvl << 1); + if (i > 50) i = 50; + + UseMana(id, SPL_FIREBALL); + } + else + { + i = 16; + } + + GetMissileVel(mi,sx,sy,dx,dy,i); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = sx; + missile[mi]._miVar5 = sy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddSpiralFireBall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) + { + missile[mi]._midam = (random(60, 10) + random(60, 10) + 2 + plr[id]._pLevel) << 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + + i = 16 + (missile[mi]._mispllvl << 1); + if (i > 50) i = 50; + + UseMana(id, SPL_FIREBALL); + } + else + { + i = 16; + } + + GetMissileVel(mi,sx,sy,dx,dy,i); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = sx; + missile[mi]._miVar5 = sy; + missile[mi]._miVar6 = 2; + missile[mi]._miVar7 = 2; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddFBArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) + { + i = 16 + missile[mi]._mispllvl; + if (i > 50) i = 50; + +// UseMana(id, SPL_FIREBALL); + } + else + { + i = 16; + } + + GetMissileVel(mi,sx,sy,dx,dy,i); + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = sx; + missile[mi]._miVar5 = sy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + if (dam == 0 && mienemy == MI_ENEMYMONST) UseMana(id, SPL_LIGHTNING); // if not 0 - probably is chain lightning + + app_assert(mi < MAXMISSILES); + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + + GetMissileVel(mi,sx,sy,dx,dy,32); + + missile[mi]._miAnimFrame = random(52, 8) + 1; + + missile[mi]._mirange = 256; +} + +void AddLTArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi,sx,sy,dx,dy,32); + missile[mi]._miAnimFrame = random(52, 8) + 1; + + missile[mi]._mirange = 255; + + if (id < 0) { + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + } else { + missile[mi]._miVar1 = plr[id]._px; + missile[mi]._miVar2 = plr[id]._py; + } + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + // Note: midir is used to pass in the missile # of the root of the lightning chain. + // A negative midir means that this is not part of a chain. + + app_assert(mi < MAXMISSILES); + missile[mi]._misx = dx; + missile[mi]._misy = dy; + + if(midir >= 0) + { + missile[mi]._mixoff = missile[midir]._mixoff; + missile[mi]._miyoff = missile[midir]._miyoff; + missile[mi]._mitxoff = missile[midir]._mitxoff; + missile[mi]._mityoff = missile[midir]._mityoff; + } + + missile[mi]._miAnimFrame = random(52, 8) + 1; + + if (midir >= 0 && mienemy != MI_ENEMYPLR && id != -1) { + missile[mi]._mirange = 6 + (missile[mi]._mispllvl >> 1); + } else { + if (midir >= 0 && id != -1) { + missile[mi]._mirange = 10; + } else missile[mi]._mirange = 8; + } + + missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 4); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + + if (mienemy != MI_ENEMYMONST && id > 0) { + app_assert(id < MAXMONSTERS); + app_assert(monster[id].MType != NULL); + switch (monster[id].MType->mtype) + { + case MT_SUCCUBUS: + SetMissAnim(mi,MF_FLAREXP); + break; + case MT_SNOWWICH: + SetMissAnim(mi,MF_BFLAREXP); + break; + case MT_HLSPWN: + SetMissAnim(mi,MF_DFLAREXP); + break; + case MT_SOLBRNR: + SetMissAnim(mi,MF_CFLAREXP); + break; + } + } + + app_assert(mi < MAXMISSILES); + missile[mi]._mix = missile[dx]._mix; + missile[mi]._miy = missile[dx]._miy; + missile[mi]._misx = missile[dx]._misx; + missile[mi]._misy = missile[dx]._misy; + missile[mi]._mixoff = missile[dx]._mixoff; + missile[mi]._miyoff = missile[dx]._miyoff; + missile[mi]._mitxoff = missile[dx]._mitxoff; + missile[mi]._mityoff = missile[dx]._mityoff; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + + missile[mi]._mirange = missile[mi]._miAnimLen; + missile[mi]._miVar1 = 0; + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = dx; + + missile[mi]._mimfnum = 0; + if (dx == 1) SetMissAnim(mi, MF_EXP1); + else SetMissAnim(mi, MF_CBOLT); + missile[mi]._mirange = missile[mi]._miAnimLen - 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL CheckIfTrig(int x, int y) +{ + int i; + + app_assert(numtrigs <= MAXTRIGGERS); + for (i = 0; i < numtrigs; ++i) + if (((x == trigs[i]._tx) && (y == trigs[i]._ty)) || + ((abs(trigs[i]._tx-x) < 2) && (abs(trigs[i]._ty-y) < 2))) return(TRUE); + + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddTown(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_TOWN) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty, mx; + + app_assert(mi < MAXMISSILES); + if (currlevel != 0) { + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + app_assert(pn <= MAXTILES); + if (((nSolidTable[pn] | dObject[tx][ty] | nMissileTable[pn] | + dPlayer[tx][ty] | dMissile[tx][ty]) == 0) && + (!CheckIfTrig(tx, ty))) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + k = 6; + break; + } + } + j += 2; + } + } + } else { + tx = dx; + ty = dy; + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + } + + missile[mi]._mirange = 100; + missile[mi]._miVar1 = missile[mi]._mirange - (missile[mi]._miAnimLen); + missile[mi]._miVar2 = 0; + + // Move current portal? + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if ((missile[mx]._mitype == MIT_TOWN) && + (mx != mi) && + (missile[mx]._misource == id)) { + missile[mx]._mirange = 0; + } + } + + PutMissile(mi); + + if (id == myplr && missile[mi]._miDelFlag == FALSE && currlevel != 0) { + if (!setlevel) NetSendCmdLocParam3(TRUE, CMD_ACTIVATEPORTAL, tx, ty, currlevel, leveltype, FALSE); + else NetSendCmdLocParam3(TRUE, CMD_ACTIVATEPORTAL, tx, ty, setlvlnum, leveltype, TRUE); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) { + if (id != -1) { + missile[mi]._midam = 0; + for (i = 0; i <= plr[id]._pLevel; ++i) missile[mi]._midam += random(55, 20) + 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + missile[mi]._midam += missile[mi]._midam >> 1; + UseMana(id, SPL_FLASH); + } else { + missile[mi]._midam = (currlevel >> 1); + } + } + else + missile[mi]._midam = monster[id].mLevel << 1; + + missile[mi]._mirange = 19; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAura(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + +#if defined(HELLFIRE2) + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) { + if (id != -1) { + missile[mi]._midam = 0; + missile[mi]._mirange = 245 + (10 * missile[mi]._mispllvl) + (2 * (id > 0) ? plr[id].plrlevel : 1); + plr[id]._pBaseToBlk += 50; + UseMana(id, SPL_AURA); + } + } +#endif + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAura2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) { + if (id != -1) { + missile[mi]._midam = 0; + missile[mi]._mirange = 245 + (10 * missile[mi]._mispllvl) + (2 * (id > 0) ? plr[id].plrlevel : 1); + } + } + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES); + if (mienemy == MI_ENEMYMONST) + { + if (id != -1) { + missile[mi]._midam = 0; + for (i = 0; i <= plr[id]._pLevel; ++i) missile[mi]._midam += random(56, 2) + 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + missile[mi]._midam += missile[mi]._midam >> 1; + } else { + missile[mi]._midam = (currlevel >> 1); + } + } + + missile[mi]._miPreFlag = TRUE; + + missile[mi]._mirange = 19; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_MANASHLD) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = ((plr[id]._pLevel << 4) << 1) + (plr[id]._pLevel << 4); + + missile[mi]._miVar1 = plr[id]._pHitPoints; + missile[mi]._miVar2 = plr[id]._pHPBase; + + missile[mi]._miVar8 = KILL_UNKNOWN; // killed by unknown source (inited) + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_MANASHLD); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._midam = random(59, 10) + 1 + plr[id]._pLevel; + + GetMissileVel(mi,sx,sy,dx,dy,16); + + missile[mi]._mirange = 255; + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + + ++missile[mi]._mix; + ++missile[mi]._miy; + missile[mi]._miyoff-=32; +//PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_GUARDIAN) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty; + + app_assert(mi < MAXMISSILES); + missile[mi]._midam = random(62, 10) + 1 + (plr[id]._pLevel >> 1); + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + app_assert(tx < MAXDUNX); + app_assert(ty < MAXDUNY); + pn = dPiece[tx][ty]; + app_assert(pn <= MAXTILES); + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + //if ((dFlags[tx][ty] & BFLAG_VISIBLE) && + if ((LineClear(sx, sy, tx, ty)) && + ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty] | nMissileTable[pn] | dMissile[tx][ty]) == 0)) { + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = tx; + missile[mi]._misy = ty; + missile[mi]._miDelFlag = FALSE; + UseMana(id, SPL_GUARDIAN); + k = 6; + break; + } + } + j += 2; + } + } + + if (missile[mi]._miDelFlag == TRUE) return; + missile[mi]._misource = id; + missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 1); + + missile[mi]._mirange = (plr[id]._pLevel >> 1) + missile[mi]._mispllvl; + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + if (missile[mi]._mirange > 30) missile[mi]._mirange = 30; + missile[mi]._mirange = missile[mi]._mirange << 4; + if (missile[mi]._mirange < 30) missile[mi]._mirange = 30; + + missile[mi]._miVar1 = missile[mi]._mirange - (missile[mi]._miAnimLen); + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 1; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddChain(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_CHAIN) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + + missile[mi]._mirange = 1; + UseMana(id, SPL_CHAIN); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddChainOLD(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, k, j, mx; + + if (dam == 0) { + k = 0; + j = -1; + for (i = 0; i < nummissilevars; ++i) { + mx = missilevars[i][0]; + if (mx >= 0 && missile[mx]._mitype == MIT_CHAIN && missile[mx]._miVar8 > k) k = missile[mx]._miVar8; + if (mx < 0) j = i; + } + ++k; + missile[mi]._miVar8 = k; + if (j == -1) { + ++nummissilevars; + j = nummissilevars; + } + missilevars[j][0] = mi; + missilevars[j][1] = MIT_CHAIN; + missilevars[j][2] = 0; + } else { + for (i = 0; i < nummissilevars; ++i) { + mx = missilevars[i][0]; + if (mx >= 0 && missile[mx]._mitype == MIT_CHAIN && missile[mx]._miVar8 == dam) missilevars[i][2]++; + } + } + + k = 0; + missile[mi]._midam = 0; + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if (missile[mx]._mitype == MIT_CHAIN && missile[mx]._midam > k) k = missile[mx]._midam; + if (missile[mx]._mitype == MIT_CHAINBALL && missile[mx]._miVar1 > k) k = missile[mx]._miVar1; + } + ++k; + missile[mi]._midam = k; + + missile[mi]._mirange = 12 + GetSpellLevel(id, SPL_LIGHTNING); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._miVar5 = dx; + missile[mi]._miVar6 = dy; + missile[mi]._miVar7 = 0; + + UseMana(id, SPL_CHAIN); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddChainballOLD(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, mx; + + missile[mi]._miVar1 = dam; + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if ((missile[mx]._mitype == MIT_CHAIN) && (missile[mx]._miVar2 == 1) && (missile[mx]._midam == dam)) { + missile[mi]._miVar2 = missile[mx]._miVar2; + missile[mi]._miVar3 = missile[mx]._miVar3; + missile[mi]._miVar4 = missile[mx]._miVar4; + } + if ((missile[mx]._mitype == MIT_CHAIN) && (missile[mx]._midam == dam)) + missile[mi]._miVar8 = missile[mx]._miVar8; + } + + if (dMonster[sx][sy] != 0) { + missile[mi]._miVar5 = sx; + missile[mi]._miVar6 = sy; + } else { + missile[mi]._miVar5 = 0; + missile[mi]._miVar6 = 0; + } + + missile[mi]._midam = (random(61, plr[id]._pLevel) + random(61, 6) + 4) << HP_SHIFT; + + GetMissileVel(mi, sx, sy, dx, dy, 16); + + missile[mi]._mirange = ((plr[id]._pLevel << 4) << 1) + (GetSpellLevel(id, SPL_CHAIN) << 4); + + PutMissile(mi); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBlood(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + SetMissDir(mi, str); + app_assert(mi < MAXMISSILES); + missile[mi]._midam = 0; + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = 250; + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBone(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + if (str > 3) str = 2; + SetMissDir(mi, str); + + app_assert(mi < MAXMISSILES); + missile[mi]._midam = 0; + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = 250; + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMetal(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + if (str > 3) str = 2; + SetMissDir(mi, str); + + app_assert(mi < MAXMISSILES); + missile[mi]._midam = 0; + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = (missile[mi]._miAnimLen); + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + AnimStruct *anim; + + app_assert(id < MAXMONSTERS); + app_assert(monster[id].MType != NULL); + if (EquivMonst(monster[id].MType->mtype, MT_HORNED)) + anim = &monster[id].MType->Anims[MA_SPECIAL]; + else if (EquivMonst(monster[id].MType->mtype, MT_NSNAKE)) + anim = &monster[id].MType->Anims[MA_ATTACK]; + else + anim = &monster[id].MType->Anims[MA_WALK]; + + GetMissileVel(mi,sx,sy,dx,dy,18); + + app_assert(mi < MAXMISSILES); + missile[mi]._mimfnum = midir; + missile[mi]._miAnimFlags = NULL; + missile[mi]._miAnimData = anim->Cels[midir]; + missile[mi]._miAnimDelay = anim->Rate; + missile[mi]._miAnimLen = anim->Frames; + missile[mi]._miAnimWidth = monster[id].MType->mAnimWidth; + missile[mi]._miAnimWidth2 = monster[id].MType->mAnimWidth2; + missile[mi]._miAnimAdd = 1; + if (EquivMonst(monster[id].MType->mtype, MT_NSNAKE)) + missile[mi]._miAnimFrame = 7; + + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + + missile[mi]._miLightFlag = TRUE; + if(monster[id]._uniqtype) { + missile[mi]._miUniqTrans = monster[id]._uniqtrans+1; + missile[mi]._mlid = monster[id].mlid; + } + + missile[mi]._mirange = 256; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFireman(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + AnimStruct *anim; + + app_assert(id < MAXMONSTERS); + app_assert(monster[id].MType != NULL); + anim = &monster[id].MType->Anims[MA_WALK]; + + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES); + missile[mi]._mimfnum = midir; + missile[mi]._miAnimFlags = NULL; + missile[mi]._miAnimData = anim->Cels[midir]; + missile[mi]._miAnimDelay = anim->Rate; + missile[mi]._miAnimLen = anim->Frames; + missile[mi]._miAnimWidth = monster[id].MType->mAnimWidth; + missile[mi]._miAnimWidth2 = monster[id].MType->mAnimWidth2; + missile[mi]._miAnimAdd = 1; + + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + + missile[mi]._miLightFlag = TRUE; + if(monster[id]._uniqtype) + missile[mi]._miUniqTrans = monster[id]._uniqtrans+1; + + dMonster[monster[id]._mx][monster[id]._my] = 0; + + missile[mi]._mirange = 256; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int d; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi,sx,sy,dx,dy,16); + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + if (mienemy == MI_ENEMYMONST) { + UseMana(id, SPL_BSTAR); + d = 5; + //for (k = missile[mi]._mispllvl; k > 0; --k) d -= 1; + //if (d <= 0) d = 1; +#if CHEATS + if (simplecheat || cheatflag) d = 0; +#endif + + plr[id]._pHitPoints -= (d << HP_SHIFT); + plr[id]._pHPBase -= (d << HP_SHIFT); + drawhpflag = TRUE; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + } else { + if (id > 0) { + if (monster[id].MType->mtype == MT_SUCCUBUS) SetMissAnim(mi,MF_FLARE); + if (monster[id].MType->mtype == MT_SNOWWICH) SetMissAnim(mi,MF_BFLARE); + if (monster[id].MType->mtype == MT_HLSPWN) SetMissAnim(mi,MF_DFLARE); + if (monster[id].MType->mtype == MT_SOLBRNR) SetMissAnim(mi,MF_CFLARE); + } + } + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + GetMissileVel(mi,sx,sy,dx,dy,16); + + SetMissDir(mi, GetDirection16(sx,sy,dx,dy)); + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = 15 + 5*(monster[id]._mint+1); + missile[mi]._mlid = -1; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddDoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i, j, k, l; + int mid; + + // search in a 5 radius around tile clicked for monster + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + mid = dMonster[(dx + CrawlTable[j])][(dy + CrawlTable[(j + 1)])]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + if ((monster[mid]._mhitpoints >> HP_SHIFT) > 0) { + missile[mi]._miVar1 = dx + CrawlTable[j]; + missile[mi]._miVar2 = dy + CrawlTable[j + 1]; + missile[mi]._miVar3 = mid; + i = -99; + k = 6; + break; + } + } + j += 2; + } + } + + // if no monsters found in search + if (i != -99) { + missile[mi]._miDelFlag = TRUE; + return; + } + + GetMissileVel(mi, sx, sy, missile[mi]._miVar1, missile[mi]._miVar2, 16); + SetMissDir(mi, GetDirection(sx, sy, missile[mi]._miVar1, missile[mi]._miVar2)); + + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._misource = id; + missile[mi]._midam = 26; + + missile[mi]._mirange = ((plr[id]._pLevel << 4) >> 2) + (plr[id]._pLevel << 4) ; + for (i = GetSpellLevel(id, SPL_DOOM); i > 0; --i) missile[mi]._mirange += ((missile[mi]._mirange << 4) >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + UseMana(id, SPL_DOOM); + PutMissile(mi); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFireonly(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._midam = dam; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + + missile[mi]._mirange = 50; + missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; + missile[mi]._miVar2 = 0; + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int monst; + + app_assert(mi < MAXMISSILES); + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + + missile[mi]._mixoff = 0; + missile[mi]._miyoff = 0; +/* + missile[mi]._misx = missile[dx]._misx; + missile[mi]._misy = missile[dx]._misy; + missile[mi]._mixoff = missile[dx]._mixoff; + missile[mi]._miyoff = missile[dx]._miyoff; + missile[mi]._mitxoff = missile[dx]._mitxoff; + missile[mi]._mityoff = missile[dx]._mityoff; +*/ + + missile[mi]._miLightFlag = TRUE; + +// MoveMissilePos(mi); + + monst = missile[mi]._misource; + missile[mi]._mirange = random(50,15) + 40*(monster[monst]._mint + 1); + + missile[mi]._miPreFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_STONE) || !PRE_BETA + int i, j, k, l, tx, ty; + int mid; + + app_assert(mi < MAXMISSILES); + missile[mi]._misource = id; + + // search in a 5 radius around tile clicked for monster + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + mid = dMonster[tx][ty]; + if (mid > 0) --mid; + else mid = -(mid + 1); + if ((mid > 3) + && (monster[mid]._mAi != AI_DIABLO) + && (monster[mid]._mmode != MM_FADEIN) + && (monster[mid]._mmode != MM_FADEOUT) + //&& (monster[mid]._mmode != MM_DEATH) + && (monster[mid]._mmode != MM_MISSILE)) { + i = -99; + k = 6; + missile[mi]._miVar1 = monster[mid]._mmode; + missile[mi]._miVar2 = mid; + monster[mid]._mmode = MM_STONE; + break; + } + } + j += 2; + } + } + + // if no monsters found in search + if (i != -99) { + missile[mi]._miDelFlag = TRUE; + return; + } + + missile[mi]._mix = tx; + missile[mi]._miy = ty; + missile[mi]._misx = missile[mi]._mix; + missile[mi]._misy = missile[mi]._miy; + + missile[mi]._mirange = 6 + missile[mi]._mispllvl; + //if (missile[mi]._mirange == 0) missile[mi]._mirange = 1; + //for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._mirange += (missile[mi]._mirange >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + if (missile[mi]._mirange > 15) missile[mi]._mirange = 15; + missile[mi]._mirange = missile[mi]._mirange << 4; + UseMana(id, SPL_STONE); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddInvis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int i; + + missile[mi]._mirange = plr[id]._pLevel << 4; + for (i = GetSpellLevel(id, SPL_INVIS); i > 0; --i) missile[mi]._mirange += ((missile[mi]._mirange << 4) >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + UseMana(id, SPL_INVIS); + missile[mi]._miDelFlag = TRUE; +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_GOLEM) || !PRE_BETA + int i, mx; + //int tx, ty, k, j, l; + + app_assert(mi < MAXMISSILES); + + missile[mi]._miDelFlag = FALSE; + for (i = 0; i < nummissiles; ++i) { + mx = missileactive[i]; + if ((missile[mx]._mitype == MIT_GOLEM) && (mx != mi) && + (missile[mx]._misource == id)) { + missile[mi]._miDelFlag = TRUE; + return; + } + } + + /*for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if ((LineClear(sx, sy, tx, ty)) && + ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty]) == 0)) {*/ + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + if ((monster[id]._mx != 1 || monster[id]._my != 0) && (id == myplr)) M_StartKill(id, id); + //missile[mi]._miDelFlag = FALSE; + UseMana(id, SPL_GOLEM); + /*k = 6; + break; + } + } + j += 2; + } + }*/ +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddEther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_ETHER) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = (plr[id]._pLevel << 4) >> 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._mirange += (missile[mi]._mirange >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + missile[mi]._miVar1 = plr[id]._pHitPoints; + missile[mi]._miVar2 = plr[id]._pHPBase; + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_ETHER); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBloodR(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_BLOODR) || !PRE_BETA + int manaval; + + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + return; // spell deleted - left code here just in case + + if (!(plr[id]._pIFlags & IAF_LMANA)) { + plr[id]._pHitPoints -= (10 << HP_SHIFT); + plr[id]._pHPBase -= (10 << HP_SHIFT); + + manaval = ((missile[mi]._mispllvl + 8) << MANA_SHIFT); + plr[id]._pMana += manaval; + plr[id]._pManaBase += manaval; + + if (plr[id]._pMana > plr[id]._pMaxMana) plr[id]._pMana = plr[id]._pMaxMana; + if (plr[id]._pManaBase > plr[id]._pMaxManaBase) plr[id]._pManaBase = plr[id]._pMaxManaBase; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + } + + UseMana(id, SPL_BLOODR); + drawhpflag = TRUE; + missile[mi]._miDelFlag = TRUE; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddSpurt(int mi, int sx, int sy, int str, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._midam = dam; + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._misource = id; + + if (dam == 1) + SetMissDir(mi, 0); + else + SetMissDir(mi, 1); + + missile[mi]._miLightFlag = TRUE; + + missile[mi]._mirange = missile[mi]._miAnimLen; + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._mix = dx; + missile[mi]._miy = dy; + missile[mi]._misx = dx; + missile[mi]._misy = dy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._midam = dam; + + missile[mi]._mirange = missile[mi]._miAnimLen; + missile[mi]._miVar1 = 0; + + //PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEAL) || !PRE_BETA + int i; + long l; + + l = (random(57, 10) + 1) << HP_SHIFT; + for (i = 0; i < plr[id]._pLevel; ++i) l += ((random(57, 4) + 1) << HP_SHIFT); + app_assert(mi < MAXMISSILES); + for (i = 0; i < missile[mi]._mispllvl; ++i) l += ((random(57, 6) + 1) << HP_SHIFT); + if (plr[id]._pClass == CLASS_WARRIOR) l = l << 1; + if (plr[id]._pClass == CLASS_ROGUE) l += (l >> 1); + plr[id]._pHitPoints += l; + if (plr[id]._pHitPoints > plr[id]._pMaxHP) plr[id]._pHitPoints = plr[id]._pMaxHP; + plr[id]._pHPBase += l; + if (plr[id]._pHPBase > plr[id]._pMaxHPBase) plr[id]._pHPBase = plr[id]._pMaxHPBase; + + UseMana(id, SPL_HEAL); + drawhpflag = TRUE; + + missile[mi]._miDelFlag = TRUE; + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddMana(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEAL) || !PRE_BETA + int i; + long l; + + l = (random(57, 10) + 1) << MANA_SHIFT; + for (i = 0; i < plr[id]._pLevel; ++i) l += ((random(57, 4) + 1) << MANA_SHIFT); + app_assert(mi < MAXMISSILES); + for (i = 0; i < missile[mi]._mispllvl; ++i) l += ((random(57, 6) + 1) << MANA_SHIFT); + if (plr[id]._pClass == CLASS_SORCEROR) l = l << 1; + if (plr[id]._pClass == CLASS_ROGUE) l += (l >> 1); + + plr[id]._pMana += l; + if (plr[id]._pMana > plr[id]._pMaxMana) plr[id]._pMana = plr[id]._pMaxMana; + plr[id]._pManaBase += l; + if (plr[id]._pManaBase > plr[id]._pMaxManaBase) plr[id]._pManaBase = plr[id]._pMaxManaBase; + + UseMana(id, SPL_MANA); + drawmanaflag = TRUE; + + missile[mi]._miDelFlag = TRUE; + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddFMana(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEAL) || !PRE_BETA + app_assert(mi < MAXMISSILES); + plr[id]._pMana = plr[id]._pMaxMana; + plr[id]._pManaBase = plr[id]._pMaxManaBase; + UseMana(id, SPL_FMANA); + drawmanaflag = TRUE; +#endif + missile[mi]._miDelFlag = TRUE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_HEALOTHER) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_HEALOTHER); + if (id == myplr) { + NewCursor(HEALOTHER_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddElement(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_ELEMENT) || !PRE_BETA + int i; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + //missile[mi]._midam = 0; + //for (i = 0; i < plr[id]._pLevel; ++i) missile[mi]._midam += random(67, 6) + 1; + //for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + app_assert(mi < MAXMISSILES); + missile[mi]._midam = (random(60, 10) + random(60, 10) + 2 + plr[id]._pLevel) << 1; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + missile[mi]._midam = missile[mi]._midam >> 1; + + GetMissileVel(mi, sx, sy, dx, dy, 16); + SetMissDir(mi, GetDirection8(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + UseMana(id, SPL_ELEMENT); + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_IDENTIFY) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_IDENTIFY); + if (id == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(IDENTIFY_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int i, pn; + int k, l, j; + int tx, ty; + + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (i = CrawlTable[l]; i > 0; --i) { + tx = dx + CrawlTable[j]; + ty = dy + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + //if ((dFlags[tx][ty] & BFLAG_VISIBLE) && ((sx != tx) || (sy != ty)) && + if ((LineClear(sx, sy, tx, ty)) && ((sx != tx) || (sy != ty)) && + ((nSolidTable[pn] | dObject[tx][ty]) == 0)) { + missile[mi]._miVar1 = tx; + missile[mi]._miVar2 = ty; + missile[mi]._miVar5 = tx; + missile[mi]._miVar6 = ty; + missile[mi]._miDelFlag = FALSE; + k = 6; + break; + } + } + j += 2; + } + } + + if (missile[mi]._miDelFlag == TRUE) return; + + missile[mi]._miVar7 = 0; + missile[mi]._miVar8 = 0; + + //midir = GetDirection(sx, sy, tx, ty); + missile[mi]._miVar3 = (midir - 2) & 0x0007; + missile[mi]._miVar4 = (midir + 2) & 0x0007; + + missile[mi]._mirange = 7; + UseMana(id, SPL_WALL); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlameBox(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + + if (mienemy == MI_ENEMYMONST){ + UseMana(id, SPL_RINGOFFIRE); + } + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miDelFlag = FALSE; + + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._miVar5 = 0; + missile[mi]._miVar6 = 0; + missile[mi]._miVar7 = 0; + missile[mi]._miVar8 = 0; + + missile[mi]._mirange = 7; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddShowMagicItems(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = FALSE; + + missile[mi]._miVar1 = 0; + missile[mi]._miVar2 = 0; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._miVar5 = 0; + missile[mi]._miVar6 = 0; + missile[mi]._miVar7 = 0; + missile[mi]._miVar8 = 0; + + HighLightAllItems = true; + missile[mi]._mirange = 245 + (10 * missile[mi]._mispllvl) + (2 * (id > 0) ? plr[id].plrlevel : 1); + if (mienemy == MI_ENEMYMONST){ + UseMana(id, SPL_SHOWMAGITEMS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_INFRA) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES); + missile[mi]._mirange = 99 << 4; + for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._mirange += (missile[mi]._mirange >> 3); + missile[mi]._mirange = missile[mi]._mirange + ((plr[id]._pISplDur * missile[mi]._mirange) >> 7); + + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_INFRA); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddWave(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_WAVE) || !PRE_BETA + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = 0; + missile[mi]._mirange = 1; + missile[mi]._miAnimFrame = 4; + UseMana(id, SPL_WAVE); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_NOVA) || !PRE_BETA + int k; + + app_assert(mi < MAXMISSILES); + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + if (id != -1) { + missile[mi]._midam = random(66, 6) + random(66, 6) + random(66, 6) + random(66, 6) + random(66, 6); + missile[mi]._midam += 5 + plr[id]._pLevel; + missile[mi]._midam = missile[mi]._midam >> 1; + for (k = missile[mi]._mispllvl; k > 0; --k) missile[mi]._midam += (missile[mi]._midam >> 3); + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_NOVA); + } else { + missile[mi]._midam = random(66, 3) + random(66, 3) + random(66, 3); + missile[mi]._midam += (currlevel >> 1); + } + missile[mi]._mirange = 1; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBoil(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + // not in game + missile[mi]._miDelFlag = TRUE; + return; +/* +#if (PRE_BETA && PRE_BLOODB) || !PRE_BETA + missile[mi]._miVar1 = dx; + missile[mi]._miVar2 = dy; + missile[mi]._mirange = 1; +#else + missile[mi]._miDelFlag = TRUE; +#endif*/ +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_REPAIR) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_REPAIR); + if (id == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(REPAIR_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_RECHARGE) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_RECHARGE); + if (id == myplr) { + if (sbookflag) sbookflag = FALSE; + if (!invflag) invflag = TRUE; + NewCursor(RECHARGE_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_DISARM) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_DISARM); + if (id == myplr) { + NewCursor(DISARM_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_APOCA) || !PRE_BETA + int i; + + app_assert(mi < MAXMISSILES); + missile[mi]._miVar1 = 8; + missile[mi]._miVar2 = sy - missile[mi]._miVar1; + missile[mi]._miVar3 = sy + missile[mi]._miVar1; + missile[mi]._miVar4 = sx - missile[mi]._miVar1; + missile[mi]._miVar5 = sx + missile[mi]._miVar1; + missile[mi]._miVar6 = missile[mi]._miVar4; + + if (missile[mi]._miVar2 <= 0) missile[mi]._miVar2 = 1; + if (missile[mi]._miVar3 >= MAXDUNY) missile[mi]._miVar3 = MAXDUNY - 1; + if (missile[mi]._miVar4 <= 0) missile[mi]._miVar4 = 1; + if (missile[mi]._miVar5 >= MAXDUNX) missile[mi]._miVar5 = MAXDUNX - 1; + + for (i = 0; i < plr[id]._pLevel; ++i) missile[mi]._midam += random(67, 6) + 1; + + missile[mi]._mirange = 255; + missile[mi]._miDelFlag = FALSE; + UseMana(id, SPL_APOCA); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int seqno) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + // seqno: the number of flame chunk for this spell instance + int i; + + app_assert(mi < MAXMISSILES); + missile[mi]._miVar2 = 0; + //for (i = 0; i < 2 - seqno; ++i) { + for (i = seqno; i > 0; --i) { + missile[mi]._miVar2 += 5; + } + + missile[mi]._misx = dx; + missile[mi]._misy = dy; + + missile[mi]._mixoff = missile[midir]._mixoff; + missile[mi]._miyoff = missile[midir]._miyoff; + missile[mi]._mitxoff = missile[midir]._mitxoff; + missile[mi]._mityoff = missile[midir]._mityoff; + missile[mi]._mirange = 20 + missile[mi]._miVar2; + missile[mi]._mlid = AddLight(sx, sy, 1); + + if (mienemy == MI_ENEMYMONST) { + missile[mi]._midam = (random(79, plr[id]._pLevel) + random(79, 2) + 2) << 3; + missile[mi]._midam += missile[mi]._midam >> 1; + //missile[mi]._midam = plr[id]._pLevel << 2; + //for (i = missile[mi]._mispllvl; i > 0; --i) missile[mi]._midam += (missile[mi]._midam >> 3); + //missile[mi]._midam = missile[mi]._midam << 1 + missile[mi]._midam; + } else { + missile[mi]._midam = random(77, monster[id].mMaxDamage - monster[id].mMinDamage + 1) + monster[id].mMinDamage; + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + //int k; + //int tsx, tsy; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi, sx, sy, dx, dy, 32); + if (mienemy == MI_ENEMYMONST) UseMana(id, SPL_FLAME); + + app_assert(mi < MAXMISSILES); + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._mirange = 256; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_CBOLT) || !PRE_BETA + app_assert(mi < MAXMISSILES); + if (micaster == MI_ENEMYMONST) + { + if (id == myplr) { + missile[mi]._mirnd = random(63, 15) + 1; + // INSERT send seed code + } else { + // INSERT get seed from network message for syncing + // used as a number idx not a seed so no SetRndSeed necessary + missile[mi]._mirnd = random(63, 15) + 1; + } + missile[mi]._midam = random(68, plr[id]._pMagic >> 2) + 1; + //for (i = missile[mi]._mispllvl; i > 0; --i) ++missile[mi]._midam; + } + else + { + missile[mi]._mirnd = random(63, 15) + 1; + missile[mi]._midam = 15; + } + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + missile[mi]._miAnimFrame = random(63, 8) + 1; + missile[mi]._mlid = AddLight(sx, sy, 5); + GetMissileVel(mi, sx, sy, dx, dy, 8); + + missile[mi]._miVar1 = 5; + missile[mi]._miVar2 = midir; + missile[mi]._miVar3 = 0; + + missile[mi]._mirange = 256; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddCBArrow(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_CBOLT) || !PRE_BETA + app_assert(mi < MAXMISSILES); + if (micaster == MI_ENEMYMONST) + { + if (id == myplr) { + missile[mi]._mirnd = random(63, 15) + 1; + // INSERT send seed code + } else { + // INSERT get seed from network message for syncing + // used as a number idx not a seed so no SetRndSeed necessary + missile[mi]._mirnd = random(63, 15) + 1; + } + } + else + { + missile[mi]._mirnd = random(63, 15) + 1; + missile[mi]._midam = 15; + } + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + missile[mi]._miAnimFrame = random(63, 8) + 1; + missile[mi]._mlid = AddLight(sx, sy, 5); + GetMissileVel(mi, sx, sy, dx, dy, 8); + + missile[mi]._miVar1 = 5; + missile[mi]._miVar2 = midir; + missile[mi]._miVar3 = 0; + + missile[mi]._mirange = 256; + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_HBOLT) || !PRE_BETA + int sp; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES); + if (id != -1) { + sp = 16 + (missile[mi]._mispllvl << 1); + if (sp >= 63) sp = 63; + } else sp = 16; + + GetMissileVel(mi, sx, sy, dx, dy, sp); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + missile[mi]._midam = random(69, 10) + 9 + plr[id]._pLevel; + + UseMana(id, SPL_HBOLT); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +void AddHBArrow(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam) +{ +#if (PRE_BETA && PRE_HBOLT) || !PRE_BETA + int sp; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES); + if (id != -1) { + sp = 16 + (missile[mi]._mispllvl << 1); + if (sp >= 63) sp = 63; + } else sp = 16; + + GetMissileVel(mi, sx, sy, dx, dy, sp); + SetMissDir(mi, GetDirection16(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + //PutMissile(mi); +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_RESURRECT) || !PRE_BETA + UseMana(id, SPL_RESURRECT); + if (id == myplr) { + NewCursor(RESURRECT_CURS); + } +#endif + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_RESURRECT) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._mix = dx; + missile[mi]._miy = dy; + missile[mi]._misx = missile[mi]._mix; + missile[mi]._misy = missile[mi]._miy; + missile[mi]._mixvel = 0; + missile[mi]._miyvel = 0; + missile[mi]._mirange = misfiledata[MF_RESURRECT].mAnimLen[0]; +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_TELEKINESIS) || !PRE_BETA + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; + UseMana(id, SPL_TELEKINESIS); + if (id == myplr) { + NewCursor(TELE_CURS); + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + int d, mid, mx, my; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + GetMissileVel(mi, sx, sy, dx, dy, 16); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._mlid = AddLight(sx, sy, 8); + + if (mienemy == MI_ENEMYMONST) { + UseMana(id, SPL_BONESPIRIT); + d = 6; + +#if CHEATS + if (simplecheat || cheatflag) d = 0; +#endif + + plr[id]._pHitPoints -= (d << HP_SHIFT); + plr[id]._pHPBase -= (d << HP_SHIFT); + drawhpflag = TRUE; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + + if (dPlayer[dx][dy] != 0) { + missile[mi]._miVar6 = 1; + if (dPlayer[dx][dy] > 0) mid = dPlayer[dx][dy] - 1; + else mid = -(dPlayer[dx][dy] + 1); + mx = plr[mid]._px; + my = plr[mid]._py; + } else { + missile[mi]._miVar6 = 0; + if (dMonster[dx][dy] <= 0) mid = FindClosest(sx, sy, 19); + else mid = dMonster[dx][dy] - 1; + mx = monster[mid]._mx; + my = monster[mid]._my; + } + + if (mid > 0) { + missile[mi]._miVar3 = mid; + GetMissileVel(mi, sx, sy, mx, my, 16); + SetMissDir(mi, GetDirection8(sx, sy, mx, my)); + } + } + + PutMissile(mi); +} + +*/ +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ +#if (PRE_BETA && PRE_BONESPIRIT) || !PRE_BETA + int d; + + if ((sx == dx) && (sy == dy)) { + dx += XDirAdd[midir]; + dy += YDirAdd[midir]; + } + + app_assert(mi < MAXMISSILES); + missile[mi]._midam = 0; + + GetMissileVel(mi, sx, sy, dx, dy, 16); + SetMissDir(mi, GetDirection8(sx, sy, dx, dy)); + + missile[mi]._mirange = 256; + + missile[mi]._miVar1 = sx; + missile[mi]._miVar2 = sy; + missile[mi]._miVar3 = 0; + missile[mi]._miVar4 = dx; + missile[mi]._miVar5 = dy; + + missile[mi]._mlid = AddLight(sx, sy, 8); + + if (mienemy == MI_ENEMYMONST) { + UseMana(id, SPL_BONESPIRIT); + d = 6; +#if CHEATS + if (simplecheat || cheatflag) d = 0; +#endif + plr[id]._pHitPoints -= (d << HP_SHIFT); + plr[id]._pHPBase -= (d << HP_SHIFT); + drawhpflag = TRUE; + + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } + + } +#else + missile[mi]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + app_assert(mi < MAXMISSILES); + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + + missile[mi]._mirange = 100; + missile[mi]._miVar1 = missile[mi]._mirange - (missile[mi]._miAnimLen); + missile[mi]._miVar2 = 0; + + PutMissile(mi); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam) +{ + BOOL LineClear(int x1, int y1, int x2, int y2); + int pnum; + + for (pnum = 0; pnum < gbMaxPlayers; ++pnum) + { + if (plr[pnum].plractive + && LineClear(sx,sy,plr[pnum]._pfutx, plr[pnum]._pfuty)) + AddMissile(0, 0, plr[pnum]._pfutx, plr[pnum]._pfuty, 0, MIT_FIREPLAR, mienemy, id, dam, 0); + } + app_assert(mi < MAXMISSILES); + missile[mi]._miDelFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int AddMissile(int sx, int sy, int v1, int v2, int midir, int mitype, char micaster, int id, int v3, int spllvl) +{ + // v1 and v2 are usually dx and dy (this can be different per missile) + // v3 is usually damage amount + + int mi; + + // check if exceeded number of missiles + if (nummissiles >= MAXMISSILES) + return -1; + + // get next missile id that is available + mi = missileavail[0]; + missileavail[0] = missileavail[MAXMISSILES - nummissiles - 1]; + missileactive[nummissiles] = mi; + ++nummissiles; + + // Zero out the data first. + memset(&missile[mi], 0, sizeof(MissileStruct)); + + // do some standard missile setups + missile[mi]._mitype = mitype; + missile[mi]._micaster = micaster; + missile[mi]._misource = id; + missile[mi]._miAnimType = missiledata[mitype].mFileNum; + missile[mi]._miDrawFlag = missiledata[mitype].mDraw; + + missile[mi]._mispllvl = spllvl; + + missile[mi]._mimfnum = midir; + if (missile[mi]._miAnimType != MF_NONE + && misfiledata[(missile[mi]._miAnimType)].mAnimFAmt >= 8) + SetMissDir(mi, midir); + else + SetMissDir(mi, 0); + + missile[mi]._mix = sx; + missile[mi]._miy = sy; + missile[mi]._mixoff = 0; + missile[mi]._miyoff = 0; + missile[mi]._misx = sx; + missile[mi]._misy = sy; + missile[mi]._mitxoff = 0; + missile[mi]._mityoff = 0; + + missile[mi]._miDelFlag = FALSE; + missile[mi]._miAnimAdd = 1; + + missile[mi]._miLightFlag = FALSE; + missile[mi]._miPreFlag = FALSE; + missile[mi]._miUniqTrans = FALSE; + missile[mi]._midam = v3; + missile[mi]._miHitFlag = FALSE; + missile[mi]._midist = 0; + missile[mi]._mlid = -1; + missile[mi]._mirnd = 0; + + if (missiledata[mitype].mlSFX != -1) + PlaySfxLoc(missiledata[mitype].mlSFX, missile[mi]._mix, missile[mi]._miy); + + missiledata[mitype].mAddProc(mi, sx, sy, v1, v2, midir, micaster, id, v3); + + return mi; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*int ChainBounceOLD (int i, int sx, int sy) +{ + int j, mi, mx, dir; + + if (dMonster[sx][sy] != 0) { + + if (dMonster[sx][sy] > 0) mi = dMonster[sx][sy] - 1; + else mi = -(dMonster[sx][sy] + 1); + + if ((monster[mi]._mhitpoints >> HP_SHIFT) > 0) { + for (j = 0; j < nummissilevars; ++j) { + mx = missilevars[j][0]; + if ((mx >= 0) && (missile[mx]._mitype == MIT_CHAIN) && (missile[mx]._miVar8 == missile[i]._miVar8) && + (missilevars[j][2] >= (plr[(missile[i]._misource)]._pLevel >> 1))) { + missilevars[j][0] = -1; + return 3; + } + } + dir = GetDirection(missile[i]._mix, missile[i]._miy, sx, sy); + AddMissile(missile[i]._mix, missile[i]._miy, sx, sy, dir, MIT_CHAIN, MI_ENEMYMONST, missile[i]._misource, missile[i]._miVar8); + return 1; + } + } + + return 0; +}*/ + +extern BOOL LineClear(int x1, int y1, int x2, int y2); +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int Sentfire(int i, int sx, int sy) +{ + int ex, dir; + + ex = 0; + app_assert(i < MAXMISSILES); + if (LineClear(missile[i]._mix, missile[i]._miy, sx, sy) + && (dMonster[sx][sy] > 0) + && ((monster[(dMonster[sx][sy] - 1)]._mhitpoints >> HP_SHIFT) > 0) + && ((dMonster[sx][sy]-1) > 3)) { + dir = GetDirection(missile[i]._mix, missile[i]._miy, sx, sy); + missile[i]._miVar3 = missileavail[0]; // get next mid + AddMissile(missile[i]._mix, missile[i]._miy, sx, sy, dir, MIT_FIREBOLT, MI_ENEMYMONST, missile[i]._misource, missile[i]._midam, GetSpellLevel(missile[i]._misource, SPL_FIREBOLT)); + ex = -1; + } + + if (ex == -1) { + SetMissDir(i, 2); + missile[i]._miVar2 = 3; + } + + return (ex); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Dummy(int i) +{} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Rune(int i) +{ + int const tx = missile[i]._mix; + int const ty = missile[i]._miy; + int mid = dMonster[tx][ty]; + int pid = dPlayer[tx][ty]; + + if (mid != 0 + || pid != 0) { + + int dir; + + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + + dir = GetDirection(missile[i]._mixoff, missile[i]._miyoff, + monster[mid]._mxoff, monster[mid]._myoff); + } + else { + if (pid > 0) --pid; + else pid = -(pid + 1); + + dir = GetDirection(missile[i]._mixoff, missile[i]._miyoff, + plr[pid]._pxoff, plr[pid]._pyoff); + } + if (missile[i]._miVar1 == MIT_MISEXP){ + AddMissile(tx, ty, i, 0, dir, missile[i]._miVar1, MI_ENEMYMONST, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + } + else { + AddMissile(tx, ty, tx, ty, dir, missile[i]._miVar1, MI_ENEMYMONST, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + } + missile[i]._miDelFlag = TRUE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Golem(int i) +{ +#if (PRE_BETA && PRE_GOLEM) || !PRE_BETA + int id, pn; + int j, k, l, m; + int tx, ty; + + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + + if (monster[id]._mx == 1 && monster[id]._my == 0) { + for (k = 0; k < 6; ++k) { + l = CrawlNum[k]; + j = l + 1; + for (m = CrawlTable[l]; m > 0; --m) { + tx = missile[i]._miVar4 + CrawlTable[j]; + ty = missile[i]._miVar5 + CrawlTable[(j + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + pn = dPiece[tx][ty]; + if ((LineClear(missile[i]._miVar1, missile[i]._miVar2, tx, ty)) && + ((nSolidTable[pn] | dMonster[tx][ty] | dObject[tx][ty]) == 0)) { + k = 6; + SpawnGolum(id, tx, ty, i); + break; + } + } + j += 2; + } + } + } + missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_SetManashield(int i) +{ +#if (PRE_BETA && PRE_MANASHLD) || !PRE_BETA + ManashieldFlag = 1; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_LArrow(int i) +{ + int p, mind, maxd, rst; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + p = missile[i]._misource; + if (missile[i]._miAnimType != MF_CBOLT && missile[i]._miAnimType != MF_EXP1) { + ++missile[i]._midist; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + mind = plr[p]._pIMinDam; + maxd = plr[p]._pIMaxDam; + } else { + mind = monster[p].mMinDamage; + maxd = monster[p].mMaxDamage; + } + } else { + mind = currlevel + random(68, 10) + 1; + maxd = (currlevel * 2) + random(68, 10) + 1; + } + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) { + rst = missiledata[(missile[i]._mitype)].mResist; + missiledata[(missile[i]._mitype)].mResist = MIMT_NONE; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + missiledata[(missile[i]._mitype)].mResist = rst; + } + + if (missile[i]._mirange == 0) { + missile[i]._mimfnum = 0; + missile[i]._mitxoff -= missile[i]._mixvel; + missile[i]._mityoff -= missile[i]._miyvel; + GetMissilePos(i); + if (missile[i]._mitype == MIT_LARROW) { + SetMissAnim(i, MF_CBOLT); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } else { + SetMissAnim(i, MF_EXP1); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 5); + } + } + } else { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, 5 + missile[i]._miAnimFrame); + rst = missiledata[(missile[i]._mitype)].mResist; + // drb.patch1.start.02/25/97 + if (missile[i]._mitype == MIT_LARROW) { + if (p != -1) { + mind = plr[p]._pILMinDam; + maxd = plr[p]._pILMaxDam; + } else { + mind = currlevel + random(68, 10) + 1; + maxd = (currlevel * 2) + random(68, 10) + 1; + } + missiledata[MIT_LARROW].mResist = MIMT_LGHT; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 1); + } + if (missile[i]._mitype == MIT_FARROW) { + if (p != -1) { + mind = plr[p]._pIFMinDam; + maxd = plr[p]._pIFMaxDam; + } else { + mind = currlevel + random(68, 10) + 1; + maxd = (currlevel * 2) + random(68, 10) + 1; + } + missiledata[MIT_FARROW].mResist = MIMT_FIRE; + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 1); + } + // endpatch1.2/25/97 + missiledata[(missile[i]._mitype)].mResist = rst; + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Arrow(int i) +{ + int p, mind, maxd; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + ++missile[i]._midist; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + p = missile[i]._misource; + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + mind = plr[p]._pIMinDam; + maxd = plr[p]._pIMaxDam; + } else { + mind = monster[p].mMinDamage; + maxd = monster[p].mMaxDamage; + } + } else { + mind = currlevel; + maxd = currlevel * 2; + } + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Firebolt(int i) +{ +#if (PRE_BETA && PRE_FIREBOLT) || !PRE_BETA + int omx, omy, d, p; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + + if (missile[i]._mitype == MIT_BONESPIRIT && missile[i]._mimfnum == 8) { + if (missile[i]._mirange == 0) { + if(missile[i]._mlid >= 0) AddUnLight(missile[i]._mlid); + missile[i]._miDelFlag = TRUE; + PlaySfxLoc(LS_BSIMPCT, missile[i]._mix, missile[i]._miy); + } + PutMissile(i); + return; + } + + omx = missile[i]._mitxoff; + omy = missile[i]._mityoff; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + p = missile[i]._misource; + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + switch(missile[i]._mitype) { + case MIT_FLARE: + d = ((plr[p]._pMagic>>1)-(plr[p]._pMagic>>3)) + (missile[i]._mispllvl << 1) + missile[i]._mispllvl; + break; + case MIT_FIREBOLT: + d = random(75, 10) + 1 + (plr[p]._pMagic >> 3) + missile[i]._mispllvl; + break; + case MIT_BONESPIRIT: + //d = (monster[missile[i]._miVar3]._mhitpoints >> HP_SHIFT) >> 1; + d = 0; + break; + } + } else d = (random(77, monster[p].mMaxDamage - monster[p].mMinDamage + 1) + monster[p].mMinDamage); + } else d = random(78, currlevel << 1) + currlevel; + + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, d, d, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + missile[i]._mitxoff = omx; + missile[i]._mityoff = omy; + GetMissilePos(i); + switch(missile[i]._mitype) { + case MIT_FLARE: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_FLAREXP, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_FIREBOLT: + case MIT_MAGMABALL: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_MISEXP, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_ACID: + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_ACIDSPLAT, missile[i]._micaster, missile[i]._misource, 0, 0); + break; + case MIT_BONESPIRIT: + SetMissDir(i, 8); + missile[i]._mirange = 7; + missile[i]._miDelFlag = FALSE; + PutMissile(i); + return; + } + if(missile[i]._mlid >= 0) AddUnLight(missile[i]._mlid); + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + if(missile[i]._mlid >= 0) ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Lightball(int i) +{ + int j, tx, ty, oi; + + app_assert(i < MAXMISSILES); + tx = missile[i]._miVar1; + ty = missile[i]._miVar2; + + --missile[i]._mirange; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + j = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + + // fix for shires and fireing nova - rjs + if (dObject[tx][ty] != 0 && tx == missile[i]._mix && ty == missile[i]._miy) { + if (dObject[tx][ty] > 0) oi = dObject[tx][ty] - 1; + else oi = -(dObject[tx][ty] + 1); + if (object[oi]._otype == OBJ_SHRINEL || object[oi]._otype == OBJ_SHRINER) missile[i]._mirange = j; + } + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Krull(int i) +{ + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Acidpud(int i) +{ + int range; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + +// GetMissilePos(i); + range = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + missile[i]._mirange = range; // CheckMissileCol clears range if there's a collision, + // but this missile sticks around even after a collision + +// MoveMissilePos(i); + + if (missile[i]._mirange == 0) + { + if(missile[i]._mimfnum) + missile[i]._miDelFlag = TRUE; + else + { + SetMissDir(i, 1); + missile[i]._mirange = missile[i]._miAnimLen; + } + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Firewall(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int ExpLight[14] = {2,3,4,5,5,6,7,8,9,10,11,12,12}; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + + if (missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + missile[i]._miAnimFrame = random(83, 11) + 1; + } + + if (missile[i]._mirange == missile[i]._miAnimLen - 1) { + SetMissDir(i, 0); + missile[i]._miAnimFrame = 13; + missile[i]._miAnimAdd = -1; + } + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + if ((missile[i]._mimfnum != 0) && (missile[i]._mirange != 0) && + (missile[i]._miAnimAdd != -1) && (missile[i]._miVar2 < 12)) { + + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Fireball(int i) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int dam, px, py, id, mx, my; + + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + dam = missile[i]._midam; + + //dam = missile[i]._mispllvl; // rjs test + //missiledata[(missile[i]._mitype)].mResist = MIMT_NONE; + + --missile[i]._mirange; + + if (missile[i]._micaster == MI_ENEMYMONST) { + px = plr[id]._px; + py = plr[id]._py; + } else { + px = monster[id]._mx; + py = monster[id]._my; + } + + if (missile[i]._miAnimType == MF_BIGEXP) { + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, dam, dam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + mx = missile[i]._mix; + my = missile[i]._miy; + + ChangeLight(missile[i]._mlid, mx, my, missile[i]._miAnimFrame); + + if (CheckBlock(px, py, mx , my ) == 0) CheckMissileCol(i, dam, dam, 0, mx, my, 1); + if (CheckBlock(px, py, mx , my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my + 1, 1); + if (CheckBlock(px, py, mx , my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my, 1); + if (CheckBlock(px, py, mx + 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my, 1); + if (CheckBlock(px, py, mx - 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my - 1, 1); + + //++missile[i]._mix; + //++missile[i]._miy; + //missile[i]._miyoff -= 32; + + if ((!TransList[dTransVal[mx][my]]) || + ((missile[i]._mixvel < 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff -= 32; + } + + if (((missile[i]._miyvel > 0) && + ((TransList[dTransVal[mx+1][my]] && nSolidTable[dPiece[mx+1][my]]) || + (TransList[dTransVal[mx-1][my]] && nSolidTable[dPiece[mx-1][my]])))) { + missile[i]._miyoff -= 32; + } + + if (((missile[i]._mixvel > 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + missile[i]._mixoff -= 32; + } + + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + PutMissile(i); +#endif +} + + +/*-----------------------------------------------------------------------* + // Doesn't work yet. GWP +**-----------------------------------------------------------------------*/ +void MI_SpiralFireBall(int i) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int px, py, mx, my; + + app_assert(i < MAXMISSILES); + int const id = missile[i]._misource; + int const dam = missile[i]._midam; + + + int xcurve; + int ycurve; + + // Set the direction into a spiral. + if (missile[i]._miVar7 < 0) { + missile[i]._miVar6 *= 2; + missile[i]._miVar7 = missile[i]._miVar6; + + --missile[i]._mimfnum; + if (missile[i]._mimfnum < 0) + missile[i]._mimfnum = 7; + } + else --missile[i]._miVar7; + + switch (missile[i]._mimfnum) { + case 0: // Down + xcurve = missile[i]._mixvel; + ycurve = 0; + break; + case 1: // Down left + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + case 2: // Left + xcurve = 0; + ycurve = missile[i]._miyvel; + break; + case 3: // Up Left + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + case 4: // Up + xcurve = missile[i]._mixvel; + ycurve = 0; + break; + case 5: // Up right + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + case 6: // Right + xcurve = 0; + ycurve = missile[i]._miyvel; + break; + case 7: // Down Right + xcurve = missile[i]._mixvel; + ycurve = missile[i]._miyvel; + break; + } + + + --missile[i]._mirange; + + if (missile[i]._micaster == MI_ENEMYMONST) { + px = plr[id]._px; + py = plr[id]._py; + } else { + px = monster[id]._mx; + py = monster[id]._my; + } + + if (missile[i]._miAnimType == MF_BIGEXP) { + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += xcurve; + missile[i]._mityoff += ycurve; + GetMissilePos(i); + + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, dam, dam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + mx = missile[i]._mix; + my = missile[i]._miy; + + ChangeLight(missile[i]._mlid, mx, my, missile[i]._miAnimFrame); + + if (CheckBlock(px, py, mx , my ) == 0) CheckMissileCol(i, dam, dam, 0, mx, my, 1); + if (CheckBlock(px, py, mx , my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my + 1, 1); + if (CheckBlock(px, py, mx , my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my, 1); + if (CheckBlock(px, py, mx + 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my - 1, 1); + if (CheckBlock(px, py, mx + 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx + 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my ) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my, 1); + if (CheckBlock(px, py, mx - 1, my + 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my + 1, 1); + if (CheckBlock(px, py, mx - 1, my - 1) == 0) CheckMissileCol(i, dam, dam, 0, mx - 1, my - 1, 1); + + //++missile[i]._mix; + //++missile[i]._miy; + //missile[i]._miyoff -= 32; + + if ((!TransList[dTransVal[mx][my]]) || + ((missile[i]._mixvel < 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff -= 32; + } + + if (((missile[i]._miyvel > 0) && + ((TransList[dTransVal[mx+1][my]] && nSolidTable[dPiece[mx+1][my]]) || + (TransList[dTransVal[mx-1][my]] && nSolidTable[dPiece[mx-1][my]])))) { + missile[i]._miyoff -= 32; + } + + if (((missile[i]._mixvel > 0) && + ((TransList[dTransVal[mx][my+1]] && nSolidTable[dPiece[mx][my+1]]) || + (TransList[dTransVal[mx][my-1]] && nSolidTable[dPiece[mx][my-1]])))) { + missile[i]._mixoff -= 32; + } + + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Lightctrl(int i) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + int pn, dam, p, mx, my; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + dam = 0; + + p = missile[i]._misource; + if (p != -1) { + if (missile[i]._micaster == MI_ENEMYMONST) { + dam = random(79, plr[p]._pLevel) + random(79, 2) + 2; + dam = dam << HP_SHIFT; + } else { + dam = (random(80, monster[p].mMaxDamage - monster[p].mMinDamage + 1) + monster[p].mMinDamage) << 1; + } + } else { + dam = random(81, currlevel) + (currlevel << 1); + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + mx = missile[i]._mix; + my = missile[i]._miy; + + app_assert(mx < MAXDUNX); + app_assert(my < MAXDUNY); + pn = dPiece[mx][my]; + app_assert(pn <= MAXTILES); + if (missile[i]._misource == -1) { + if ((mx != missile[i]._misx) || (my != missile[i]._misy)) + if (nMissileTable[pn]) missile[i]._mirange = 0; + } else { + if (nMissileTable[pn]) missile[i]._mirange = 0; + } + + if ((!nMissileTable[pn]) && ((mx != missile[i]._miVar1) || (my != missile[i]._miVar2)) && + (mx > 0) && (my > 0) && (mx < DMAXX) && (my < DMAXY)) { + // Add LIGHTNING if the player or trap threw this, otherwise add THINLIGHT for thin demon + if (missile[i]._misource != -1) { + if (missile[i]._micaster == MI_ENEMYPLR && EquivMonst(monster[missile[i]._misource].MType->mtype, MT_STORM)) + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_THINLIGHT, missile[i]._micaster, missile[i]._misource, dam, missile[i]._mispllvl); + else + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, dam, missile[i]._mispllvl); + } else { + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, dam, missile[i]._mispllvl); + } + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + } + + if ((missile[i]._mirange == 0) || (mx <= 0) || (my <= 0) || (mx >= DMAXX) || (my > DMAXY)) + missile[i]._miDelFlag = TRUE; +#endif +} + +void MI_LTArrow(int i) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + int pn, mx, my; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + mx = missile[i]._mix; + my = missile[i]._miy; + + app_assert(mx < MAXDUNX); + app_assert(my < MAXDUNY); + pn = dPiece[mx][my]; + app_assert(pn <= MAXTILES); + if (missile[i]._misource == -1) { + if ((mx != missile[i]._misx) || (my != missile[i]._misy)) + if (nMissileTable[pn]) missile[i]._mirange = 0; + } else { + if (nMissileTable[pn]) missile[i]._mirange = 0; + } + + if ((!nMissileTable[pn]) && ((mx != missile[i]._miVar1) || (my != missile[i]._miVar2)) && + (mx > 0) && (my > 0) && (mx < DMAXX) && (my < DMAXY)) { + // Add LIGHTNING if the player or trap threw this, otherwise add THINLIGHT for thin demon + if (missile[i]._misource != -1) { + if (missile[i]._micaster == MI_ENEMYPLR && EquivMonst(monster[missile[i]._misource].MType->mtype, MT_STORM)) + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_THINLIGHT, missile[i]._micaster, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + else + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + } else { + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_LIGHTNING, missile[i]._micaster, missile[i]._misource, missile[i]._midam, missile[i]._mispllvl); + } + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + } + + if ((missile[i]._mirange == 0) || (mx <= 0) || (my <= 0) || (mx >= DMAXX) || (my > DMAXY)) + missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Lightning(int i) +{ +#if (PRE_BETA && PRE_LIGHTNING) || !PRE_BETA + int j; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + + j = missile[i]._mirange; + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Town(int i) +{ +#if (PRE_BETA && PRE_TOWN) || !PRE_BETA + int p; + + int ExpLight[17] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,15}; + + app_assert(i < MAXMISSILES); + if (missile[i]._mirange > 1) --missile[i]._mirange; + + if (missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + } + + if ((currlevel != 0) && (missile[i]._mimfnum != 1) && (missile[i]._mirange != 0)) { + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + + for (p = 0; p < MAX_PLRS; ++p) { + if (! plr[p].plractive) continue; + if (currlevel != plr[p].plrlevel) continue; + if (plr[p]._pLvlChanging) continue; + if (plr[p]._pmode != PM_STAND) continue; + if (plr[p]._px != missile[i]._mix) continue; + if (plr[p]._py != missile[i]._miy) continue; + + ClrPlrPath(p); + if (p == myplr) { + NetSendCmdParam1(TRUE,CMD_WARP,missile[i]._misource); + plr[p]._pmode = PM_NEWLVL; + } + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flash(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES); + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[missile[i]._misource]._pInvincible = TRUE; + --missile[i]._mirange; + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix-1, missile[i]._miy, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix+1, missile[i]._miy, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix-1, missile[i]._miy+1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy+1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix+1, missile[i]._miy+1, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pInvincible = FALSE; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Aura(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES); + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) { + missile[i]._mix = plr[missile[i]._misource]._pfutx; + missile[i]._miy = plr[missile[i]._misource]._pfuty; + } + --missile[i]._mirange; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pBaseToBlk -= 50; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Aura2(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES); + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) { + missile[i]._mix = plr[missile[i]._misource]._pfutx; + missile[i]._miy = plr[missile[i]._misource]._pfuty; + } + --missile[i]._mirange; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flash2(int i) +{ +#if (PRE_BETA && PRE_FLASH) || !PRE_BETA + app_assert(i < MAXMISSILES); + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pInvincible = TRUE; + --missile[i]._mirange; + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix-1, missile[i]._miy-1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy-1, 1); + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix+1, missile[i]._miy-1, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if ((missile[i]._micaster == MI_ENEMYMONST) && (missile[i]._misource != -1)) + plr[(missile[i]._misource)]._pInvincible = FALSE; + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Manashield(int i) +{ +#if (PRE_BETA && PRE_MANASHLD) || !PRE_BETA + int j, id; + long diff, pct; + + //--missile[i]._mirange; + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + + missile[i]._mix = plr[id]._px; + missile[i]._miy = plr[id]._py; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + + if (plr[id]._pmode == PM_WALK3) { + missile[i]._misx = plr[id]._pfutx; + missile[i]._misy = plr[id]._pfuty; + } else { + missile[i]._misx = plr[id]._px; + missile[i]._misy = plr[id]._py; + } + + GetMissilePos(i); + + if (plr[id]._pmode == PM_WALK3) { + if (plr[id]._pdir == DIR_L) ++missile[i]._mix; + else ++missile[i]._miy; + } + + if (id != myplr) { + if (currlevel != plr[id].plrlevel) missile[i]._miDelFlag = TRUE; + PutMissile(i); + return; + } + + if (plr[id]._pMana <= 0 || (!plr[id].plractive)) missile[i]._mirange = 0; + + if (plr[id]._pHitPoints < missile[i]._miVar1) { + diff = missile[i]._miVar1 - plr[id]._pHitPoints; + pct = 0; + for (j = 0; j < missile[i]._mispllvl && j < 7; ++j) pct += 3; + if (pct > 0) diff = diff - (diff / pct); + if (diff < 0) diff = 0; + drawmanaflag = TRUE; + drawhpflag = TRUE; + if (plr[id]._pMana >= diff) { + plr[id]._pHitPoints = missile[i]._miVar1; + plr[id]._pHPBase = missile[i]._miVar2; + plr[id]._pMana -= diff; + plr[id]._pManaBase -= diff; + } else { + plr[id]._pHitPoints -= (diff - plr[id]._pMana); + plr[id]._pHPBase -= (diff - plr[id]._pMana); + plr[id]._pMana = 0; + plr[id]._pManaBase = -(plr[id]._pMaxMana - plr[id]._pMaxManaBase); + missile[i]._mirange = 0; + missile[i]._miDelFlag = TRUE; + if (plr[id]._pHitPoints < 0) SetPlayerHitPoints(id, 0); + if (((plr[id]._pHitPoints >> HP_SHIFT) == 0) && (id == myplr)) + StartPlrKill(id, missile[i]._miVar8); + } + } + + missile[i]._miVar1 = plr[id]._pHitPoints; + missile[i]._miVar2 = plr[id]._pHPBase; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + NetSendCmd(TRUE, CMD_ENDSHIELD); + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Ether(int i) +{ +#if (PRE_BETA && PRE_ETHER) || !PRE_BETA + int id; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + id = missile[i]._misource; + + missile[i]._mix = plr[id]._px; + missile[i]._miy = plr[id]._py; + missile[i]._mitxoff = plr[id]._pxoff << 16; + missile[i]._mityoff = plr[id]._pyoff << 16; + + if (plr[id]._pmode == PM_WALK3) { + missile[i]._misx = plr[id]._pfutx; + missile[i]._misy = plr[id]._pfuty; + } else { + missile[i]._misx = plr[id]._px; + missile[i]._misy = plr[id]._py; + } + + GetMissilePos(i); + + if (plr[id]._pmode == PM_WALK3) { + if (plr[id]._pdir == DIR_L) ++missile[i]._mix; + else ++missile[i]._miy; + } + + plr[id]._pSpellFlags |= SF_ETHER; + + if (missile[i]._mirange == 0 || plr[id]._pHitPoints <= 0) { + missile[i]._miDelFlag = TRUE; + plr[id]._pSpellFlags &= ~SF_ETHER; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Firemove(int i) +{ + int j; + int ExpLight[14] = {2,3,4,5,5,6,7,8,9,10,11,12,12}; + + app_assert(i < MAXMISSILES); + --missile[i]._mix; + --missile[i]._miy; + missile[i]._miyoff+=32; + + ++missile[i]._miVar1; + + if (missile[i]._miVar1 == missile[i]._miAnimLen) { + SetMissDir(i, 1); + missile[i]._miAnimFrame = random(82, 11) + 1; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + j = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + if ((missile[i]._mimfnum == 0) && (missile[i]._mirange != 0)) { + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + else if ((missile[i]._mix != missile[i]._miVar3) || (missile[i]._miy != missile[i]._miVar4)) { + missile[i]._miVar3 = missile[i]._mix; + missile[i]._miVar4 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar3, missile[i]._miVar4, 8); + } + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff-=32; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Guardian(int i) +{ +#if (PRE_BETA && PRE_GUARDIAN) || !PRE_BETA + int j, k, sx, sy, sx1, sy1, ex; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + if (missile[i]._miVar2 > 0) --missile[i]._miVar2; + + if ((missile[i]._mirange == missile[i]._miVar1) || ((missile[i]._mimfnum == 2) && + (missile[i]._miVar2 == 0))) { + SetMissDir(i, 1); + } + + if ((missile[i]._mirange % 16) == 0) { + ex = 0; + for (k = 0; (k < 23) && (ex != -1); ++k) { + for (j = 10; (j >= 0) && (ex != -1); j-=2) { + if (vCrawlTable[k][j] == 0 && vCrawlTable[k][j + 1] == 0) break; + if ((sx1 != vCrawlTable[k][j]) || (sy1 != vCrawlTable[k][j + 1])) { + sx = missile[i]._mix + vCrawlTable[k][j]; + sy = missile[i]._miy + vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx = missile[i]._mix - vCrawlTable[k][j]; + sy = missile[i]._miy - vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx = missile[i]._mix + vCrawlTable[k][j]; + sy = missile[i]._miy - vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx = missile[i]._mix - vCrawlTable[k][j]; + sy = missile[i]._miy + vCrawlTable[k][j+1]; + ex = Sentfire(i, sx, sy); + if (ex == -1) break; + + sx1 = vCrawlTable[k][j]; + sy1 = vCrawlTable[k][j + 1]; + } + } + } + } + + if (missile[i]._mirange == 14) { + SetMissDir(i, 0); + missile[i]._miAnimFrame = 15; + missile[i]._miAnimAdd = -1; + } + + missile[i]._miVar3 += missile[i]._miAnimAdd; + if (missile[i]._miVar3 > 15) { + missile[i]._miVar3 = 15; + } else { + if (missile[i]._miVar3 > 0) + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar3); + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Chain(int i) +{ +#if (PRE_BETA && PRE_CHAIN) || !PRE_BETA + int sx, sy, id, dir; + int l, n, m, k, rad; + int tx, ty; + + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + sx = missile[i]._mix; + sy = missile[i]._miy; + + dir = GetDirection(sx, sy, missile[i]._miVar1, missile[i]._miVar2); + AddMissile(sx, sy, missile[i]._miVar1, missile[i]._miVar2, dir, MIT_LIGHTCTRL, MI_ENEMYMONST, id, 1, missile[i]._mispllvl); + + rad = 3 + missile[i]._mispllvl; + if (rad > 19) rad = 19; + for (m = 1; m < rad; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + tx = sx + CrawlTable[l]; + ty = sy + CrawlTable[(l + 1)]; + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + if ((dMonster[tx][ty]) > 0) { + dir = GetDirection(sx, sy, tx, ty); + AddMissile(sx, sy, tx, ty, dir, MIT_LIGHTCTRL, MI_ENEMYMONST, id, 1, missile[i]._mispllvl); + } + } + l += 2; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void MI_ChainOLD(int i) +{ + int dir; + + if ((missile[i]._mirange % 3) == 0) { + dir = GetDirection(missile[i]._mix, missile[i]._miy, missile[i]._miVar5, missile[i]._miVar6); + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._miVar5, missile[i]._miVar6, dir, MIT_CHAINBALL, MI_ENEMYMONST, missile[i]._misource, missile[i]._midam); + ++missile[i]._miVar7; + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void MI_ChainballOLD(int i) +{ + int mx, id; + int k, l, m, n, rad; + + --missile[i]._mirange; + id = missile[i]._misource; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + if ((missile[i]._miVar2 == 1) && (missile[i]._mix == missile[i]._miVar3) && (missile[i]._miy == missile[i]._miVar4)) { + missile[i]._miVar2 = 0; + missile[i]._mirange = 0; + + k = 0; + for (l = 0; l < nummissiles; ++l) { + mx = missileactive[l]; + if (missile[mx]._mitype == MIT_CHAINBALL && missile[i]._miVar1 == missile[mx]._miVar1) ++k; + if ((missile[mx]._mitype == MIT_CHAIN) && (missile[i]._miVar1 == missile[mx]._midam)) + k+=((4 + (GetSpellLevel(id, SPL_LIGHTNING) / 3)) - missile[mx]._miVar7); + } + + if (k == 1) { + rad = 6 + GetSpellLevel(id, SPL_CHAIN); + if (rad > 19) rad = 19; + for (m = 1; m < rad; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + if (ChainBounce (i, missile[i]._mix + CrawlTable[l], missile[i]._miy + CrawlTable[(l + 1)]) > 0) { + m = rad; + break; + } + l += 2; + } + } + } + } else { + if ((missile[i]._mix != missile[i]._miVar5) || (missile[i]._miy != missile[i]._miVar6)) + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._miHitFlag == TRUE && missile[i]._mirange == 0 && missile[i]._miVar2 == 0) { + for (l = 0; l < nummissiles; ++l) { + mx = missileactive[l]; + if ((missile[mx]._mitype == MIT_CHAIN && missile[i]._miVar1 == missile[mx]._midam) || + (missile[mx]._mitype == MIT_CHAINBALL && missile[i]._miVar1 == missile[mx]._miVar1)) { + missile[mx]._miVar2 = 1; // flag hit and cont until v3, v4 + missile[mx]._miVar3 = missile[i]._mix; // x of hit + missile[mx]._miVar4 = missile[i]._miy; // y of hit + } + } + } + } + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Blood(int i) +{ + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + if (missile[i]._miAnimFrame == missile[i]._miAnimLen) { +// missile[i]._miAnimFrame = missile[i]._miAnimLen; + missile[i]._miPreFlag = TRUE; + } + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Weapexp(int i) +{ + int id, mind, maxd; + int ExpLight[10] = {9,10,11,12,11,10,8,6,4,2}; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + + id = missile[i]._misource; + if (missile[i]._miVar2 == 1) { + mind = plr[id]._pIFMinDam; + maxd = plr[id]._pIFMaxDam; + missiledata[missile[i]._mitype].mResist = MIMT_FIRE; + } else { + mind = plr[id]._pILMinDam; + maxd = plr[id]._pILMaxDam; + missiledata[missile[i]._mitype].mResist = MIMT_LGHT; + } + + CheckMissileCol(i, mind, maxd, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._miVar1 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } else { + if (missile[i]._mirange != 0) + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } + + ++missile[i]._miVar1; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + return; + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Misexp(int i) +{ + int ExpLight[10] = {9,10,11,12,11,10,8,6,4,2}; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + return; + } + + if (missile[i]._miVar1 == 0) { + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } else { + if (missile[i]._mirange != 0) + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar1)]); + } + + ++missile[i]._miVar1; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Acidsplat(int i) +{ + int monst; + int dam; + + app_assert(i < MAXMISSILES); + if (missile[i]._mirange == missile[i]._miAnimLen) { + ++missile[i]._mix; + ++missile[i]._miy; + missile[i]._miyoff-=32; + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + monst = missile[i]._misource; + dam = (monster[monst].MData->mLevel < 2) ? 1:2; + AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIT_ACIDPUD, MI_ENEMYPLR, missile[i]._misource, dam, missile[i]._mispllvl); + return; + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Teleport(int i) +{ +#if (PRE_BETA && PRE_TELE) || !PRE_BETA + int id; + + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + + //sprintf(tempstr, "X: %i Y: %i FX: %i FY: %i", plr[myplr]._px, plr[myplr]._py, plr[myplr]._pfutx, plr[myplr]._pfuty); + //AddPanelString(tempstr, TEXT_LEFT); + + --missile[i]._mirange; + if (missile[i]._mirange <= 0) { + missile[i]._miDelFlag = TRUE; + return; + } + + dPlayer[(plr[id]._px)][(plr[id]._py)] = 0; + PlrClrTrans(plr[id]._px, plr[id]._py); + plr[id]._px = missile[i]._mix; + plr[id]._py = missile[i]._miy; + plr[id]._pfutx = plr[id]._px; + plr[id]._pfuty = plr[id]._py; + plr[id]._poldx = plr[id]._px; + plr[id]._poldy = plr[id]._py; + PlrDoTrans(plr[id]._px, plr[id]._py); + missile[i]._miVar1 = 1; + dPlayer[(plr[id]._px)][(plr[id]._py)] = 1 + (char)id; + + if (leveltype != 0) { + ChangeLightXY(plr[id]._plid, plr[id]._px, plr[id]._py); + ChangeVisionXY(plr[id]._pvid, plr[id]._px, plr[id]._py); + } + + if (id == myplr) { + ViewX = plr[id]._px - ScrollInfo._sdx; + ViewY = plr[id]._py - ScrollInfo._sdy; + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +/*void MI_Doom(int i) +{ + int k, l, m, n; + int mid; + + --missile[i]._mirange; + + // check if monster moved + mid = dMonster[(missile[i]._miVar1)][(missile[i]._miVar2)]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + } + + // if he did search again + if (mid != missile[i]._miVar3) { + for (m = 0; m < 6; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + mid = dMonster[((missile[i]._miVar1) + CrawlTable[l])][((missile[i]._miVar2) + CrawlTable[(l + 1)])]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + if (mid == missile[i]._miVar3) { + missile[i]._miVar1 += CrawlTable[l]; + missile[i]._miVar2 += CrawlTable[l + 1]; + k = -99; + m = 6; + break; + } + } + l += 2; + } + } + + // if monster killed before doom kills it + if (k != -99) { + missile[i]._miDelFlag = TRUE; + PutMissile(i); + return; + } + + // get new velocity and directions + GetMissileVel(i, missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2, 16); + SetMissDir(i, GetDirection(missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2)); + } + + + // move missile + if (missile[i]._mimfnum != 9) { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + } + + // get mid for current missile pos - for checking if target monster killed + mid = dMonster[(missile[i]._mix)][(missile[i]._miy)]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + } + + // check for collision if not followed monster dont end missile + k = missile[i]._mirange; + if ((missile[i]._mix != plr[myplr]._px) || (missile[i]._miy != plr[myplr]._py)) CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + if ((missile[i]._mirange == 0) && (mid != missile[i]._miVar3) && (missile[i]._miHitFlag == TRUE)) missile[i]._mirange = k; + + // if target monster not dead halt missile in place + if ((missile[i]._mirange == 0) && (mid == missile[i]._miVar3)) { + missile[i]._mirange = k; + if ((monster[mid]._mhitpoints >> HP_SHIFT) > 0) { + if (missile[i]._mimfnum != 9) { + SetMissDir(i, 9); + } + } else { + // target is killed so re-search + for (m = 1; m < 6; ++m) { + n = CrawlNum[m]; + l = n + 1; + for (k = CrawlTable[n]; k > 0; --k) { + mid = dMonster[((missile[i]._miVar1) + CrawlTable[l])][((missile[i]._miVar2) + CrawlTable[(l + 1)])]; + if (mid != 0) { + if (mid > 0) --mid; + else mid = -(mid + 1); + if ((monster[mid]._mhitpoints >> HP_SHIFT) > 0) { + missile[i]._miVar1 += CrawlTable[l]; + missile[i]._miVar2 += CrawlTable[l + 1]; + missile[i]._miVar3 = mid; + k = -99; + m = 6; + break; + } + } + l += 2; + } + } + + // get new velocity and directions + if (k == 0) missile[i]._mirange = 0; + else { + GetMissileVel(i, missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2, 16); + SetMissDir(i, GetDirection(missile[i]._mix, missile[i]._miy, missile[i]._miVar1, missile[i]._miVar2)); + } + } + } + + // delete or place missile + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +}*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Stone (int i) +{ +#if (PRE_BETA && PRE_STONE) || !PRE_BETA + int m; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + m = missile[i]._miVar2; + + if (monster[m]._mhitpoints == 0 && missile[i]._miAnimType != MF_STONE) { + SetMissAnim(i, MF_STONE); + missile[i]._mirange = 11; + } + + + if (monster[m]._mmode != MM_STONE) missile[i]._miDelFlag = TRUE; + + else { + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + if (monster[m]._mhitpoints > 0) { +// app_assert(dMonster[monster[m]._mx][monster[m]._my] == m+1 +// || dMonster[monster[m]._mx][monster[m]._my] == -(m+1)); + monster[m]._mmode = missile[i]._miVar1; + } + else AddDead(monster[m]._mx, monster[m]._my, stonendx, monster[m]._mdir); + } + + if (missile[i]._miAnimType == MF_STONE) PutMissile(i); + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Boom(int i) +{ + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + if (missile[i]._miVar1 == 0) CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 1); + if (missile[i]._miHitFlag == TRUE) missile[i]._miVar1 = 1; + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Rhino(int i) +{ + int mix,miy; + int mix2, miy2; + int omx, omy; + int monst; + BOOL placemiss = FALSE; + + app_assert(i < MAXMISSILES); + monst = missile[i]._misource; + + app_assert(monst < MAXMONSTERS); + if (monster[monst]._mmode != MM_MISSILE) { // monster got blood-boiled or something + missile[i]._miDelFlag = TRUE; + return; + } + + GetMissilePos(i); + + omx = missile[i]._mix; + omy = missile[i]._miy; + + dMonster[omx][omy] = NULL; + + if (monster[monst]._mAi == AI_SNAKE) + { + // Snake should stop a few frames before it enters player's square + // So we run its animation a few frames ahead here and test below + // to see if the square is available + missile[i]._mitxoff += 2*missile[i]._mixvel; + missile[i]._mityoff += 2*missile[i]._miyvel; + + GetMissilePos(i); + + mix2 = missile[i]._mix; + miy2 = missile[i]._miy; + + missile[i]._mitxoff -= 1*missile[i]._mixvel; + missile[i]._mityoff -= 1*missile[i]._miyvel; + } + else + { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + } + + GetMissilePos(i); + + mix = missile[i]._mix; + miy = missile[i]._miy; + + + if (PosOkMonst(monst, mix, miy) + && (monster[monst]._mAi != AI_SNAKE || PosOkMonst(monst, mix2, miy2))) + { + dMonster[mix][miy] = -(monst + 1); + monster[monst]._mx = monster[monst]._moldx = monster[monst]._mfutx = mix; + monster[monst]._my = monster[monst]._moldy = monster[monst]._mfuty = miy; + + if(monster[monst]._uniqtype) + ChangeLightXY(missile[i]._mlid, mix, miy); + + MoveMissilePos(i); + PutMissile(i); + } + else + { + MissToMonst(i,omx,omy); + missile[i]._miDelFlag = TRUE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Fireman(int i) +{ + int mix,miy; + int omx, omy; + int id, m; + BOOL placemiss = FALSE; + int px,py, p; + + GetMissilePos(i); + + app_assert(i < MAXMISSILES); + omx = missile[i]._mix; + omy = missile[i]._miy; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + + m = missile[i]._misource; + mix = missile[i]._mix; + miy = missile[i]._miy; + + p = monster[m]._menemy; + if ((monster[m]._mFlags & MFLAG_MID) == 0) { + px = plr[p]._px; + py = plr[p]._py; + } else { + px = monster[p]._mx; + py = monster[p]._my; + } + + if((mix != omx || miy != omy) + && + ((missile[i]._miVar1 & MIF_DIDHIT + && !DIST(omx-px, omy-py, 4)) + || missile[i]._miVar2 > 1) + && PosOkMonst(missile[i]._misource, omx, omy) + ) + { + // return to monster domain + MissToMonst(i,omx, omy); + missile[i]._miDelFlag = TRUE; + } + + else + if ((monster[m]._mFlags & MFLAG_MID) == 0) id = dPlayer[mix][miy]; + else id = dMonster[mix][miy]; + if(!PosOkMissile(mix, miy) + || (id > 0 && !(missile[i]._miVar1 & MIF_DIDHIT))) + { + // bounce away + missile[i]._mixvel = -missile[i]._mixvel; + missile[i]._miyvel = -missile[i]._miyvel; + missile[i]._mimfnum = opposite[missile[i]._mimfnum]; + missile[i]._miAnimData = monster[m].MType->Anims[MA_WALK].Cels[missile[i]._mimfnum]; + + ++missile[i]._miVar2; + + if(id > 0) + { + missile[i]._miVar1 |= MIF_DIDHIT; + } + placemiss = TRUE; + } + else + placemiss = TRUE; + + if(placemiss) + { +// ChangeLightXY(monster[m].mlid, monster[m]._mx, monster[m]._my); + + MoveMissilePos(i); + PutMissile(i); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_FirewallC(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int tx, ty, pn, id; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + id = missile[i]._misource; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + else { + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar1 >= MAXDUNX || missile[i]._miVar2 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar1,missile[i]._miVar2); + pn = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + app_assert(pn <= MAXTILES); + tx = missile[i]._miVar1 + XDirAdd[missile[i]._miVar3]; + ty = missile[i]._miVar2 + YDirAdd[missile[i]._miVar3]; + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar1, missile[i]._miVar2, missile[i]._miVar1, missile[i]._miVar2, plr[id]._pdir, MIT_FIREWALL, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + missile[i]._miVar1 = tx; + missile[i]._miVar2 = ty; + } else missile[i]._miVar8 = 1; + + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar5 >= MAXDUNX || missile[i]._miVar6 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar5,missile[i]._miVar6); + pn = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + app_assert(pn <= MAXTILES); + tx = missile[i]._miVar5 + XDirAdd[missile[i]._miVar4]; + ty = missile[i]._miVar6 + YDirAdd[missile[i]._miVar4]; + if (nMissileTable[pn] == 0 && missile[i]._miVar7 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar5, missile[i]._miVar6, missile[i]._miVar5, missile[i]._miVar6, plr[id]._pdir, MIT_FIREWALL, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + missile[i]._miVar5 = tx; + missile[i]._miVar6 = ty; + } else missile[i]._miVar7 = 1; + } +#endif +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_FlameBox(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + app_assert(i < MAXMISSILES); + missile[i]._miDelFlag = TRUE; + int const id = missile[i]._micaster; + int const l = CrawlNum[3]; + int j = l + 1; + int const dam = ((random(53, 10) + random(53, 10) + 2 + ((id > 0) ? plr[id]._pLevel : currlevel)) << 4) >> 1; + + for (int m = CrawlTable[l]; m > 0; --m, j+=2) { + int const tx = missile[i]._miVar1 + CrawlTable[j]; + int const ty = missile[i]._miVar2 + CrawlTable[j + 1]; + + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int const pn = dPiece[tx][ty]; + + if (!nSolidTable[pn] && dObject[tx][ty] == 0) + { + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(tx, ty, tx, ty, 0, MIT_FIREWALL, MI_ENEMYMONST, id, dam, missile[i]._mispllvl); + } else missile[i]._miVar8 = 1; + + } + } + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_LightBox(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + app_assert(i < MAXMISSILES); + missile[i]._miDelFlag = TRUE; + int const id = missile[i]._micaster; + int const l = CrawlNum[3]; + int j = l + 1; + int const dam = ((random(53, 10) + random(53, 10) + 2 + ((id > 0) ? plr[id]._pLevel : currlevel)) << 4) >> 1; + + for (int m = CrawlTable[l]; m > 0; --m, j+=2) { + int const tx = missile[i]._miVar1 + CrawlTable[j]; + int const ty = missile[i]._miVar2 + CrawlTable[j + 1]; + + if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + int const pn = dPiece[tx][ty]; + + if (!nSolidTable[pn] && dObject[tx][ty] == 0) + { + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(tx, ty, tx, ty, 0, MIT_LIGHTWALL, MI_ENEMYMONST, id, dam, missile[i]._mispllvl); + } else missile[i]._miVar8 = 1; + + } + } + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_ShowMagicItems(int i) +{ +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + app_assert(i < MAXMISSILES); + + --missile[i]._mirange; + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + HighLightAllItems = false; + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_LightwallC(int i) +{ +// GWP 9/4/97 +// Copy of MI_FirewallC with switched to call the MIT_LIGHTWALL instead of MIT_FIREWALL +#if (PRE_BETA && PRE_WALL) || !PRE_BETA + int tx, ty, pn; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + + int const id = missile[i]._misource; + int const dam = ((random(53, 10) + random(53, 10) + 2 + ((id > 0) ? plr[id]._pLevel : 0)) << 4) >> 1; + + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + else { + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar1 >= MAXDUNX || missile[i]._miVar2 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar1,missile[i]._miVar2); + pn = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + app_assert(pn <= MAXTILES); + tx = missile[i]._miVar1 + XDirAdd[missile[i]._miVar3]; + ty = missile[i]._miVar2 + YDirAdd[missile[i]._miVar3]; + if (nMissileTable[pn] == 0 && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar1, missile[i]._miVar2, missile[i]._miVar1, missile[i]._miVar2, plr[id]._pdir, MIT_LIGHTWALL, MI_ENEMYMONST, id, dam, missile[i]._mispllvl); + missile[i]._miVar1 = tx; + missile[i]._miVar2 = ty; + } else missile[i]._miVar8 = 1; + + // if you take this out of here the wall will go though everything (hence using the nsolidtable) + //if (missile[i]._miVar5 >= MAXDUNX || missile[i]._miVar6 >= MAXDUNY) + // app_fatal("Tried placing firewall piece off edge of map at (%d,%d)",missile[i]._miVar5,missile[i]._miVar6); + pn = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + app_assert(pn <= MAXTILES); + tx = missile[i]._miVar5 + XDirAdd[missile[i]._miVar4]; + ty = missile[i]._miVar6 + YDirAdd[missile[i]._miVar4]; + if (nMissileTable[pn] == 0 && missile[i]._miVar7 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar5, missile[i]._miVar6, missile[i]._miVar5, missile[i]._miVar6, plr[id]._pdir, MIT_LIGHTWALL, MI_ENEMYMONST, id, dam, missile[i]._mispllvl); + missile[i]._miVar5 = tx; + missile[i]._miVar6 = ty; + } else missile[i]._miVar7 = 1; + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Infra(int i) +{ +#if (PRE_BETA && PRE_INFRA) || !PRE_BETA + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + plr[(missile[i]._misource)]._pInfraFlag = TRUE; + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + CalcPlrItemVals(missile[i]._misource,TRUE); + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Apoca(int i) +{ +#if (PRE_BETA && PRE_APOCA) || !PRE_BETA + int j, k, id; + BOOL exit; + + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + + exit = FALSE; + for (j = missile[i]._miVar2; (j < missile[i]._miVar3) && (exit == FALSE); ++j) { + for (k = missile[i]._miVar4; (k < missile[i]._miVar5) && (exit == FALSE); ++k) { + if (dMonster[k][j] > 3 && nSolidTable[(dPiece[k][j])] == 0) { + AddMissile(k, j, k, j, plr[id]._pdir, MIT_BOOM, MI_ENEMYMONST, id, missile[i]._midam, 0); + exit = TRUE; + } + } + if (exit == FALSE) missile[i]._miVar4 = missile[i]._miVar6; + } + + if (exit == TRUE) { + missile[i]._miVar2 = j - 1; + missile[i]._miVar4 = k; + } else missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Wave(int i) +{ +#if (PRE_BETA && PRE_WAVE) || !PRE_BETA + int dira, dirb, nxa, nya, nxb, nyb; + int pn, sd, j, f1, f2, id, sx, sy, dx, dy; + + f1 = 0; + f2 = 0; + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + + sd = GetDirection(sx, sy, dx, dy); + dira = (sd - 2) & 0x0007; + dirb = (sd + 2) & 0x0007; + nxa = sx + XDirAdd[sd]; + nya = sy + YDirAdd[sd]; + + //if (nxa >= MAXDUNX || nya >= MAXDUNY) + // app_fatal("Tried placing flamewave piece off edge of map at (%d,%d)",nxa,nya); + pn = dPiece[nxa][nya]; + app_assert(pn <= MAXTILES); + if (nMissileTable[pn] == 0) { + AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIT_FIREMOVE, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + + nxa += XDirAdd[dira]; + nya += YDirAdd[dira]; + nxb = sx + XDirAdd[sd] + XDirAdd[dirb]; + nyb = sy + YDirAdd[sd] + YDirAdd[dirb]; + for (j = 0; j < (2 + (missile[i]._mispllvl>>1)); ++j) { + //if (nxa >= MAXDUNX || nya >= MAXDUNY) + // app_fatal("Tried placing flamewave piece off edge of map at (%d,%d)",nxa,nya); + pn = dPiece[nxa][nya]; + app_assert(pn <= MAXTILES); + if (nMissileTable[pn] == 0 && f1 == 0 && nxa > 0 && nxa < MAXDUNX && nya > 0 && nya < MAXDUNY) { + AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIT_FIREMOVE, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + nxa += XDirAdd[dira]; + nya += YDirAdd[dira]; + } else f1 = 1; + + //if (nxb >= MAXDUNX || nyb >= MAXDUNY) + // app_fatal("Tried placing flamewave piece off edge of map at (%d,%d)",nxb,nyb); + pn = dPiece[nxb][nyb]; + app_assert(pn <= MAXTILES); + if (nMissileTable[pn] == 0 && f2 == 0 && nxb > 0 && nxb < MAXDUNX && nyb > 0 && nyb < MAXDUNY) { + AddMissile(nxb, nyb, nxb + XDirAdd[sd], nyb + YDirAdd[sd], plr[id]._pdir, MIT_FIREMOVE, MI_ENEMYMONST, id, 0, missile[i]._mispllvl); + nxb += XDirAdd[dirb]; + nyb += YDirAdd[dirb]; + } else f2 = 1; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define RAD 6 + +void MI_Nova(int i) +{ +#if (PRE_BETA && PRE_NOVA) || !PRE_BETA + int k, id, sx, sy, dir, en; + int sx1, sy1, dam, dx, dy; + + sx1 = sy1 = 0; + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + dam = missile[i]._midam; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + if (id != -1) { + dir = plr[id]._pdir; + en = MI_ENEMYMONST; + } else { + dir = 0; + en = MI_ENEMYPLR; + } + + for (k = 0; k < 23; ++k) { + if ((sx1 != vCrawlTable[k][RAD]) || (sy1 != vCrawlTable[k][RAD + 1])) { + dx = sx + vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + dx = sx + vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_LIGHTBALL, en, id, dam, missile[i]._mispllvl); + + sx1 = vCrawlTable[k][RAD]; + sy1 = vCrawlTable[k][RAD + 1]; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MI_FireNova(int i) +{ +#if (PRE_BETA && PRE_NOVA) || !PRE_BETA + int k, id, sx, sy, dir, en; + int sx1, sy1, dam, dx, dy; + + sx1 = sy1 = 0; + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + dam = missile[i]._midam; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + if (id != -1) { + dir = plr[id]._pdir; + en = MI_ENEMYMONST; + } else { + dir = 0; + en = MI_ENEMYPLR; + } + + for (k = 0; k < 23; ++k) { + if ((sx1 != vCrawlTable[k][RAD]) || (sy1 != vCrawlTable[k][RAD + 1])) { + dx = sx + vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + dx = sx - vCrawlTable[k][RAD]; + dy = sy + vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + dx = sx + vCrawlTable[k][RAD]; + dy = sy - vCrawlTable[k][RAD + 1]; + AddMissile(sx, sy, dx, dy, dir, MIT_FBARROW, en, id, dam, missile[i]._mispllvl); + + sx1 = vCrawlTable[k][RAD]; + sy1 = vCrawlTable[k][RAD + 1]; + } + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif +} + +void MI_SpecialArrow(int i) +{ +#if (PRE_BETA && PRE_FIREBALL) || !PRE_BETA + int id, sx, sy, dir, en; + int sx1, sy1, dam, dx, dy; + + sx1 = sy1 = 0; + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + dam = missile[i]._midam; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + int extraspeed = missile[i]._miVar3; + + int mitype = MIT_ARROW; + if (id != -1) { + dir = plr[id]._pdir; + en = MI_ENEMYMONST; + switch(plr[id]._pILMinDam) + { + case 0: mitype = MIT_FBARROW; break; + case 1: mitype = MIT_LTARROW; break; + case 2: mitype = MIT_CBARROW; break; + case 3: mitype = MIT_HBARROW; break; + default: break; + } + } else { + dir = 0; + en = MI_ENEMYPLR; + } + + AddMissile(sx, sy, dx, dy, dir, mitype, en, id, dam, extraspeed); + if (mitype == MIT_CBARROW) + { + AddMissile(sx, sy, dx, dy, dir, mitype, en, id, dam, extraspeed); + AddMissile(sx, sy, dx, dy, dir, mitype, en, id, dam, extraspeed); + } + + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Boil(int i) +{ + app_assert(i < MAXMISSILES); + missile[i]._miDelFlag = TRUE; + return; + +/*#if (PRE_BETA && PRE_BLOODB) || !PRE_BETA + int j, mid, id, dx, dy, pct; + long dm; + + BOOL M_Talker (int); + + id = missile[i]._misource; + dx = missile[i]._miVar1; + dy = missile[i]._miVar2; + mid = dMonster[dx][dy]; + + if (mid > 0) --mid; + else mid = -(mid + 1); + if (mid > 0) { + if ((M_Talker(mid) && monster[mid].mtalkmsg != 0) || ((plr[id]._pLevel - 6 + missile[i]._mispllvl) <= monster[mid].mLevel)) { + missile[i]._miDelFlag = TRUE; + return; + } + + if (monster[mid].mMagicRes & M_IM) return; + + dm = monster[mid]._mhitpoints; + monster[mid]._mhitpoints = 0; + M_StartKill(mid, id); + AddPlrExperience(id, monster[mid].mLevel, monster[mid].mExp); + dMonster[monster[mid]._mx][monster[mid]._my] = 0; + monster[mid]._mDelFlag = TRUE; + AddMissile(monster[mid]._mx, monster[mid]._my, monster[mid]._mx, monster[mid]._my, plr[id]._pdir, MIT_SPURT, MI_ENEMYMONST, id, (random(87, 2) + 1), 0); + AddDead(monster[mid]._mx, monster[mid]._my, spurtndx, monster[mid]._mdir); + + pct = 0; + for (j = 0; j < missile[i]._mispllvl && j < 5; ++j) pct += 10; + //dm = (monster[mid]._mmaxhp >> 1); + if (pct > 0) dm -= (dm / pct); + plr[id]._pHitPoints -= dm; + plr[id]._pHPBase -= dm; + + if (plr[id]._pHitPoints > plr[id]._pMaxHP) { + plr[id]._pHitPoints = plr[id]._pMaxHP; + plr[id]._pHPBase = plr[id]._pMaxHPBase; + } + if (plr[id]._pHitPoints <= 0) { + // rjs - manashld fix? - plr[id]._pHitPoints = 0; + StartPlrKill(id, FALSE); + } else StartPlrHit(id, dm); + + PlaySfxLoc(LS_BLODBOIL, monster[mid]._mx, monster[mid]._my); + UseMana(id, SPL_BLOODB); + } + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; +#endif*/ +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flame(int i) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + int k, id; + + app_assert(i < MAXMISSILES); + id = missile[i]._misource; + --missile[i]._mirange; + --missile[i]._miVar2; + + k = missile[i]._mirange; + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 1, missile[i]._mix, missile[i]._miy, 0); + if ((missile[i]._mirange == 0) && (missile[i]._miHitFlag == TRUE)) missile[i]._mirange = k; + if (missile[i]._miVar2 == 0) missile[i]._miAnimFrame = 20; + if (missile[i]._miVar2 <= 0) { + k = missile[i]._miAnimFrame; + if (k > 11) k = 24 - k; + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, k); + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + if (missile[i]._miVar2 <= 0) PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Flamec(int i) +{ +#if (PRE_BETA && PRE_FLAME) || !PRE_BETA + int id, pn; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + id = missile[i]._misource; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + app_assert(missile[i]._mix < MAXDUNX); + app_assert(missile[i]._miy < MAXDUNY); + pn = dPiece[missile[i]._mix][missile[i]._miy]; + app_assert(pn <= MAXTILES); + if (nMissileTable[pn] == 0) + AddMissile(missile[i]._mix, missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIT_FLAME, missile[i]._micaster, id, missile[i]._miVar3, missile[i]._mispllvl); + else + missile[i]._mirange = 0; + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ++missile[i]._miVar3; + } + + if (missile[i]._mirange == 0 || missile[i]._miVar3 == 3) missile[i]._miDelFlag = TRUE; +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Cbolt(int i) +{ +#if (PRE_BETA && PRE_CBOLT) || !PRE_BETA + int bpath[16] = { -1, 0, 1, -1, 0, 1, -1, -1, 0, 0, 1, 1, 0, 1, -1, 0 }; + int sx, sy, dx, dy, md; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + if (missile[i]._miAnimType != MF_LIGHTNING) { + if (missile[i]._miVar3 == 0) { + md = (missile[i]._miVar2 + bpath[missile[i]._mirnd]) & 0x07; + missile[i]._mirnd = (missile[i]._mirnd + 1) & 0x0f; + sx = missile[i]._mix; + sy = missile[i]._miy; + dx = sx + XDirAdd[md]; + dy = sy + YDirAdd[md]; + GetMissileVel(i, sx, sy, dx, dy, 8); + missile[i]._miVar3 = 16; + } else --missile[i]._miVar3; + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + + CheckMissileCol(i, missile[i]._midam, missile[i]._midam, 0, missile[i]._mix, missile[i]._miy, 0); + if (missile[i]._miHitFlag == TRUE) { + missile[i]._miVar1 = 8; + missile[i]._mimfnum = 0; + missile[i]._mixoff = 0; + missile[i]._miyoff = 0; + SetMissAnim(i, MF_LIGHTNING); + missile[i]._mirange = missile[i]._miAnimLen; + GetMissilePos(i); + } + + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar1); + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Hbolt(int i) +{ +#if (PRE_BETA && PRE_HBOLT) || !PRE_BETA + int dam; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + if (missile[i]._miAnimType != MF_HEXPL) { + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + + GetMissilePos(i); + + dam = missile[i]._midam; + if ((missile[i]._mix != missile[i]._misx) || (missile[i]._miy != missile[i]._misy)) + CheckMissileCol(i, dam, dam, 0, missile[i]._mix, missile[i]._miy, 0); + + if (missile[i]._mirange == 0) { + missile[i]._mitxoff -= missile[i]._mixvel; + missile[i]._mityoff -= missile[i]._miyvel; + GetMissilePos(i); + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_HEXPL); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } else { + if ((missile[i]._mix != missile[i]._miVar1) || (missile[i]._miy != missile[i]._miVar2)) { + missile[i]._miVar1 = missile[i]._mix; + missile[i]._miVar2 = missile[i]._miy; + ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8); + } + } + } else { + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, 7 + missile[i]._miAnimFrame); + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + } + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Element(int i) +{ +#if (PRE_BETA && PRE_ELEMENT) || !PRE_BETA + int j, mid, sd, dam; + int cx, cy, px, py, id; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + dam = missile[i]._midam; + id = missile[i]._misource; + + if (missile[i]._miAnimType == MF_BIGEXP) { + cx = missile[i]._mix; + cy = missile[i]._miy; + px = plr[id]._px; + py = plr[id]._py; + ChangeLight(missile[i]._mlid, cx, cy, missile[i]._miAnimFrame); + + if (CheckBlock(px, py, cx , cy ) == 0) CheckMissileCol(i, dam, dam, 1, cx, cy, 1); + if (CheckBlock(px, py, cx , cy + 1) == 0) CheckMissileCol(i, dam, dam, 1, cx, cy + 1, 1); + if (CheckBlock(px, py, cx , cy - 1) == 0) CheckMissileCol(i, dam, dam, 1, cx, cy - 1, 1); + if (CheckBlock(px, py, cx + 1, cy ) == 0) CheckMissileCol(i, dam, dam, 1, cx + 1, cy, 1); + if (CheckBlock(px, py, cx + 1, cy - 1) == 0) CheckMissileCol(i, dam, dam, 1, cx + 1, cy - 1, 1); + if (CheckBlock(px, py, cx + 1, cy + 1) == 0) CheckMissileCol(i, dam, dam, 1, cx + 1, cy + 1, 1); + if (CheckBlock(px, py, cx - 1, cy ) == 0) CheckMissileCol(i, dam, dam, 1, cx - 1, cy, 1); + if (CheckBlock(px, py, cx - 1, cy + 1) == 0) CheckMissileCol(i, dam, dam, 1, cx - 1, cy + 1, 1); + if (CheckBlock(px, py, cx - 1, cy - 1) == 0) CheckMissileCol(i, dam, dam, 1, cx - 1, cy - 1, 1); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + cx = missile[i]._mix; + cy = missile[i]._miy; + + j = missile[i]._mirange; + CheckMissileCol(i, dam, dam, 0, cx, cy, 0); + + if (missile[i]._miVar3 == 0) { + //if (missile[i]._mirange == 0 && missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + //if ((missile[i]._mirange == 0) && (missile[i]._miHitFlag != TRUE)) missile[i]._miVar3 = 1; + if ((cx == missile[i]._miVar4) && (cy == missile[i]._miVar5)) missile[i]._miVar3 = 1; + } + + if (missile[i]._miVar3 == 1) { + missile[i]._miVar3 = 2; + missile[i]._mirange = 255; + mid = FindClosest(cx, cy, 19); + if (mid > 0) { + sd = GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my); + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); + } else { + sd = plr[id]._pdir; + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16); + } + } + + if ((cx != missile[i]._miVar1) || (cy != missile[i]._miVar2)) { + missile[i]._miVar1 = cx; + missile[i]._miVar2 = cy; + ChangeLight(missile[i]._mlid, cx, cy, 8); + } + + if (missile[i]._mirange == 0) { + missile[i]._mimfnum = 0; + SetMissAnim(i, MF_BIGEXP); + missile[i]._mirange = missile[i]._miAnimLen - 1; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Bonespirit(int i) +{ +#if (PRE_BETA && PRE_BONESPIRIT) || !PRE_BETA + int j, mid, sd, dam; + int cx, cy, id; + + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + dam = missile[i]._midam; + id = missile[i]._misource; + + if (missile[i]._mimfnum == 8) { + cx = missile[i]._mix; + cy = missile[i]._miy; + //px = plr[id]._px; + //py = plr[id]._py; + ChangeLight(missile[i]._mlid, cx, cy, missile[i]._miAnimFrame); + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); + return; + } + + missile[i]._mitxoff += missile[i]._mixvel; + missile[i]._mityoff += missile[i]._miyvel; + GetMissilePos(i); + cx = missile[i]._mix; + cy = missile[i]._miy; + + j = missile[i]._mirange; + CheckMissileCol(i, dam, dam, 0, cx, cy, 0); + + if (missile[i]._miVar3 == 0) { + //if (missile[i]._mirange == 0 && missile[i]._miHitFlag == TRUE) missile[i]._mirange = j; + //if ((missile[i]._mirange == 0) && (missile[i]._miHitFlag != TRUE)) missile[i]._miVar3 = 1; + if ((cx == missile[i]._miVar4) && (cy == missile[i]._miVar5)) missile[i]._miVar3 = 1; + } + + if (missile[i]._miVar3 == 1) { + missile[i]._miVar3 = 2; + missile[i]._mirange = 255; + mid = FindClosest(cx, cy, 19); + if (mid > 0) { + missile[i]._midam = (monster[mid]._mhitpoints >> HP_SHIFT) >> 1; + sd = GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my); + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); + } else { + sd = plr[id]._pdir; + SetMissDir(i, sd); + GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16); + } + } + + if ((cx != missile[i]._miVar1) || (cy != missile[i]._miVar2)) { + missile[i]._miVar1 = cx; + missile[i]._miVar2 = cy; + ChangeLight(missile[i]._mlid, cx, cy, 8); + } + + if (missile[i]._mirange == 0) { + SetMissDir(i, 8); + missile[i]._mirange = 7; + } + + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_ResurrectBeam(int i) +{ +#if (PRE_BETA && PRE_RESURRECT) || !PRE_BETA + app_assert(i < MAXMISSILES); + --missile[i]._mirange; + if (missile[i]._mirange == 0) missile[i]._miDelFlag = TRUE; + PutMissile(i); +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MI_Rportal(int i) +{ + int ExpLight[17] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,15}; + + app_assert(i < MAXMISSILES); + if (missile[i]._mirange > 1) --missile[i]._mirange; + + if (missile[i]._mirange == missile[i]._miVar1) { + SetMissDir(i, 1); + } + + if ((currlevel != 0) && (missile[i]._mimfnum != 1) && (missile[i]._mirange != 0)) { + if (missile[i]._miVar2 == 0) + missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[(missile[i]._miVar2)]); + ++missile[i]._miVar2; + } + + if (missile[i]._mirange == 0) { + missile[i]._miDelFlag = TRUE; + AddUnLight(missile[i]._mlid); + } + + PutMissile(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ProcessMissiles () +{ + int i, mi; + + + for (i = 0; i < nummissiles; ++i) { + mi = missileactive[i]; + dFlags[missile[mi]._mix][missile[mi]._miy] &= BFMASK_MISSILE; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; + } + + i = 0; + while (i < nummissiles) { + mi = missileactive[i]; + if (missile[mi]._miDelFlag) { + DeleteMissile(mi, i); + i = 0; + } else ++i; + } + + MissilePreFlag = FALSE; + ManashieldFlag = 0; + for (i = 0; i < nummissiles; ++i) { + mi = missileactive[i]; + + missiledata[missile[mi]._mitype].mProc(mi); + + if(!(missile[mi]._miAnimFlags & MFF_STATIC)) + { + ++missile[mi]._miAnimCnt; + if (missile[mi]._miAnimCnt >= missile[mi]._miAnimDelay) { + missile[mi]._miAnimCnt = 0; + missile[mi]._miAnimFrame += missile[mi]._miAnimAdd; + if (missile[mi]._miAnimFrame > missile[mi]._miAnimLen) missile[mi]._miAnimFrame = 1; + if (missile[mi]._miAnimFrame < 1) missile[mi]._miAnimFrame = missile[mi]._miAnimLen; + } + } + } + + if (ManashieldFlag) { + for (i = 0; i < nummissiles; ++i) { + mi = missileactive[i]; + if (missile[mi]._mitype == MIT_MANASHIELD) MI_Manashield(mi); + } + } + + i = 0; + while (i < nummissiles) { + mi = missileactive[i]; + if (missile[mi]._miDelFlag) { + DeleteMissile(mi, i); + i = 0; + } else ++i; + } +} + +void SyncMissAnim() +{ + int i,mi; + + for (i = 0; i < nummissiles; ++i) + { + app_assert(i < MAXMISSILES); + mi = missileactive[i]; + + app_assert(mi < MAXMISSILES); + MissileStruct *Miss = &missile[mi]; + + Miss->_miAnimData = misfiledata[Miss->_miAnimType].mAnimData[Miss->_mimfnum]; + + if (Miss->_mitype == MIT_RHINO) + { + AnimStruct *anim; + + if (EquivMonst(monster[Miss->_misource].MType->mtype, MT_HORNED)) + anim = &monster[Miss->_misource].MType->Anims[MA_SPECIAL]; + else if (EquivMonst(monster[Miss->_misource].MType->mtype, MT_NSNAKE)) + anim = &monster[Miss->_misource].MType->Anims[MA_ATTACK]; + else + anim = &monster[Miss->_misource].MType->Anims[MA_WALK]; + + missile[mi]._miAnimData = anim->Cels[Miss->_mimfnum]; + } + // need similar section for Fireman + } +} + +/*-----------------------------------------------------------------------* +** Used when we need to "emergency" delete missiles +**-----------------------------------------------------------------------*/ +void ClearMissileSpot(int mi) +{ + app_assert(mi < MAXMISSILES); + dFlags[missile[mi]._mix][missile[mi]._miy] &= BFMASK_MISSILE; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; +} diff --git a/MONO.CPP b/MONO.CPP new file mode 100644 index 0000000..d3d19b4 --- /dev/null +++ b/MONO.CPP @@ -0,0 +1,93 @@ +#include "mono.h" + + +// Allocate space for the MonoDriver data. +// and Call the constructor for one MonoDevice data object. +MonoDevice::DeviceData MonoDevice::MDA; + +MonoDevice::DeviceData::DeviceData() : + fhDevice (CreateFile("\\\\.\\DARKMONO.VXD", 0, 0, NULL, NULL, + FILE_FLAG_DELETE_ON_CLOSE, NULL)), + fEnabled((fhDevice != INVALID_HANDLE_VALUE)), + fNextRow(0), + fNextCol(0) +{ + ClearScreen(); +} + +MonoDevice::DeviceData::~DeviceData() +{ + if( Status() ) + { + CloseHandle(fhDevice); + fEnabled = false; + fhDevice = INVALID_HANDLE_VALUE; + fNextRow = 0; + fNextCol = 0; + } +} + +int MonoDevice::PutString( int row, int col, char const * string ) +{ + int Result = 0; + if( Status() && row < HEIGHT && col < WIDTH) + { + short buff[3 + 41]; // allow WIDTH character string + int len = strlen( string ); + Result = len; + int bufferLen = 0; + + for (;len > 0; len -= WIDTH, ++row, col=0, string += bufferLen ) + { + bufferLen = ((len + col) > WIDTH)? WIDTH - (len + col) : len; + if (row >= HEIGHT) + row = 0; + buff[0] = static_cast(row); + buff[1] = static_cast(col); + buff[2] = static_cast(bufferLen); + if( buff[2] > (WIDTH - col) ) + { + buff[2] = (WIDTH - col); + strncpy( reinterpret_cast(buff + 3), string, buff[2] ); + } + else + strcpy( reinterpret_cast(buff + 3), string ); + + DeviceIoControl(MDA.fhDevice, PUT_STRING, + &(buff[0]), sizeof( buff ), NULL, 0, NULL, NULL); + } + + } + return Result; +} + +void __cdecl MonoDevice::Printf( int row, int col, char const * const format, ... ) +{ + if( Status() ) + { + char strbuf [ 256 ]; + va_list argptr; + + va_start(argptr,format); + vsprintf(strbuf,format,argptr); + va_end(argptr); + + PutString( row, col, strbuf ); + } +} + +void __cdecl MonoDevice::Printf( char const * const format, ... ) +{ + if( Status() ) + { + char strbuf [ 256 ]; + va_list argptr; + + va_start(argptr,format); + vsprintf(strbuf,format,argptr); + va_end(argptr); + + PutString( strbuf ); + } +} + diff --git a/MONO.H b/MONO.H new file mode 100644 index 0000000..1dbaa17 --- /dev/null +++ b/MONO.H @@ -0,0 +1,223 @@ + +/* ======================================================================== + Copyright (c) 1990,1997 Synergistic Software + All Rights Reserved + Author: + ======================================================================== */ + + +#ifndef _MONO_H_ +#define _MONO_H_ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +//#ifdef __BORLANDC__ +//#pragma option -a4 +//#endif +//#ifdef _MSC_VER +//#pragma pack(push,4) +//#endif + +// Define __cdecl for non Microsoft compilers. +#if (!defined(_MSC_VER) && !defined(__cdecl) ) +#define __cdecl +#endif + +// This class is to help put text strings out to a monochrome monitor under +// Windows95. +// It requires the DARKMONO.VXD driver to be installed to work. +// It does do line wrapping. +// There is no stored buffer of the text, so no scrolling. + +class MonoDevice +{ +private: + // Helper class to do auto initialization and to keep from opening the + // driver more than once. + class DeviceData { + private: + friend class MonoDevice; + explicit DeviceData(); + inline bool Status() const; + + + HANDLE fhDevice; + bool fEnabled; + int fNextRow; + int fNextCol; + + protected: + public: + ~DeviceData(); + }; + + enum MonoDimisions + { + WIDTH = 80, + HEIGHT = 24 + }; + + enum MonoFunctions + { + MONO_VERSION = 1, + CURSOR_ON = 2, + CURSOR_OFF = 3, + SET_ATTRIBUTE = 4, + CLEAR_SCREEN = 5, + PUT_CHAR = 6, + PUT_STRING = 7 + }; + + // Can't create or distroy one of these. + MonoDevice(); + ~MonoDevice(); + + // Can only have one Monochrome display. + static DeviceData MDA; +public: + typedef enum Attrib + { + ERASE =0x00,NORM =0x07, NORM_BLNK =0x87, + INVRS =0x70,UNDRLN =0x01, UNDRLN_BLNK =0x81, + INVRS_BLNK=0xF0,HI =0x0F, HI_BLNK =0x8F, + HI_UNDRLN=0x09, HI_UNDRLN_BLNK=0x89 + }; + + + static inline bool Status() { return MDA.Status(); } + static inline bool IsEnabled(); + static inline void Enable(); + static inline void Disable(); + static inline void SetAttribute( Attrib attribute ); + static inline void CursorOn(); + static inline void CursorOff(); + static inline void ClearScreen( char fill = ERASE); + static inline bool PutChar( int row, int col, char value ); + static inline bool PutChar( char value ); + static int PutString( int row, int col, char const * const string ); + static inline int PutString( char const * const string ); + static void __cdecl Printf( int row, int col, char const * const format, ... ); + static void __cdecl Printf(char const * const format, ... ); +}; + +inline bool MonoDevice::DeviceData::Status() const +{ + return fhDevice != INVALID_HANDLE_VALUE && fEnabled; +} + +inline bool MonoDevice::IsEnabled() +{ + return MDA.fEnabled; +} + +inline void MonoDevice::Enable() +{ + MDA.fEnabled = true; +} + +inline void MonoDevice::Disable() +{ + MDA.fEnabled = false; +} + +inline void MonoDevice::SetAttribute( Attrib attribute ) +{ + if( Status() ) + { + unsigned char attr = static_cast(attribute); + DeviceIoControl(MDA.fhDevice, SET_ATTRIBUTE, + &attr, sizeof( attr ), + NULL, 0, NULL, NULL); + } +} + +inline void MonoDevice::CursorOn() +{ + if( Status() ) + DeviceIoControl(MDA.fhDevice, CURSOR_ON, + NULL, 0, NULL, 0, NULL, NULL); +} + +inline void MonoDevice::CursorOff() +{ + if( Status() ) + DeviceIoControl(MDA.fhDevice, CURSOR_OFF, + NULL, 0, NULL, 0, NULL, NULL); +} + +inline void MonoDevice::ClearScreen( char fill ) +{ + if( Status() ) + { + DeviceIoControl(MDA.fhDevice, CLEAR_SCREEN, + &fill, sizeof( fill ), NULL, 0, NULL, NULL); + MDA.fNextRow = 0; + MDA.fNextCol = 0; + } +} + +inline bool MonoDevice::PutChar( int row, int col, char value ) +{ + bool Result = false; + + if( Status() && row < HEIGHT && col < WIDTH) + { + short buff[3]; + buff[0] = static_cast(row); + buff[1] = static_cast(col); + buff[2] = value; // high byte doesn't matter + DeviceIoControl(MDA.fhDevice, PUT_CHAR, + &(buff[0]), sizeof( buff ), NULL, 0, NULL, NULL); + Result = true; + } + return Result; +} + +inline bool MonoDevice::PutChar( char value ) +{ + bool const Result = PutChar (MDA.fNextCol, MDA.fNextRow, value); + if (Result) + { + ++MDA.fNextCol; + if (MDA.fNextCol > WIDTH) + { + MDA.fNextCol = 0; + ++MDA.fNextRow; + if (MDA.fNextRow > HEIGHT) + { + MDA.fNextRow = 0; + } + } + } + return Result; +} + +inline int MonoDevice::PutString( char const * const string ) +{ + int const Result = PutString(MDA.fNextRow, MDA.fNextCol, string); + MDA.fNextCol += Result % WIDTH; + if (MDA.fNextCol > WIDTH) + { + MDA.fNextCol %= WIDTH; + ++MDA.fNextRow; + } + MDA.fNextRow += Result / WIDTH; + if (MDA.fNextRow > HEIGHT) + { + MDA.fNextRow %= HEIGHT; + } + return Result; +} + + +//#ifdef __BORLANDC__ +//#pragma option -a. +//#endif +//#ifdef _MSC_VER +//#pragma pack(pop) +//#endif + +#endif diff --git a/MONO_C.CPP b/MONO_C.CPP new file mode 100644 index 0000000..9e4ecea --- /dev/null +++ b/MONO_C.CPP @@ -0,0 +1,148 @@ +#ifdef _DEBUG +#include +#include +#include +#include +#include +#include + +#include "mono_c.h" + + + +//--------------------------------------------------------------------------- + + +bool mono_getExist( void ) +{ + return MonoDevice::Status() ? true : false; // Returns TRUE, if device detected +} // else returns FALSE + +int mono_getEnable( void ) +{ + return MonoDevice::IsEnabled() ? true : false; // Returns ON, if device enabled +} // else returns OFF + +void mono_setEnable( int flag ) // flag = TRUE - use mono device +{ // flag = FALSE - don't use + if( flag == TRUE ) + MonoDevice::Enable(); + else + MonoDevice::Disable(); +} + + + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +void mono_cls(void) +{ + MonoDevice::ClearScreen( ' ' ); +} + + +//--------------------------------------------------------------------------- + +void mono_putc( short x, short y, char c) +{ + MDA.PutChar( y, x, c ); +} + + +//--------------------------------------------------------------------------- + +void mono_puts( short x, short y, char const * const str ) +{ + MDA.PutString( y, x, str ); +} + + +//--------------------------------------------------------------------------- + +void __cdecl mono_printf( short x, short y, char const * const format, ... ) +{ + char strbuf [ 256 ]; + va_list argptr; + va_start(argptr,format); + vsprintf(strbuf,format,argptr); + va_end(argptr); + MDA.PutString( y, x, strbuf ); +} + + +//--------------------------------------------------------------------------- + +void mono_dump ( short port ) +{ +/* + if( MDA.IsEnabled() && MDA.Status() ) + { + char linefeed[3] = "\r\n"; + int fp; + char lptPort[] = "LPTx"; + lptPort[3] = port + '0'; //set LPT port + + short *ptr = 0;//(short *)(_x386_zero_base_ptr + MONOBASE); + short i; + short ch; + short attribute; + short col = 0; + if ((fp = open(lptPort, O_WRONLY) ) >= 0) + { + // Output screen + for (i=0; i>8; + ch = (*ptr) & 0x00ff; + (*ptr) = 0x0fdb; //display a progress character + + if (attribute == MONO_NORM) + write(fp, "(s0B", 5); //Normal on + else + write(fp, "(s7B", 5); //BOLD on + + if (!ch) + ch = ' '; // char 0 is also a space on the mono + write(fp, &ch, 1); //write the character + + if (++col == MONOWIDTH) //Next line? + { + col = 0; + write(fp,&linefeed,2); + } + (*ptr) = (attribute<<8)+ch; //remove progress character + ptr++; + } + + close(fp); + } + } +*/ +} + + +//--------------------------------------------------------------------------- + +void mono_setAttrib( MonoAttrib attrib ) +{ + MDA.SetAttribute( attrib ); +} + +MonoAttrib mono_getAttrib() +{ + return MONO_NORM; +} + +//--------------------------------------------------------------------------- + +void mono_setHardwareCursor( int flag ) // flag = TRUE - use mono device +{ // flag = FALSE - don't use + if( flag ) + MDA.CursorOn(); + else + MDA.CursorOff(); +} + +#endif + \ No newline at end of file diff --git a/MONO_C.H b/MONO_C.H new file mode 100644 index 0000000..e5bd566 --- /dev/null +++ b/MONO_C.H @@ -0,0 +1,36 @@ +#ifdef _DEBUG +#ifndef _MONO_C_H_ +#define _MONO_C_H_ + +#include "mono.h" + +//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° +// +// Global Function Declarations +// +//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° + +void mono_setAttrib( MonoAttrib aVal ); +MonoAttrib mono_getAttrib( void ); + + + +int mono_getExist ( void ); +int mono_getEnable( void ); +void mono_setEnable( int flag ); + +void mono_cls ( void ); + +void mono_putc ( short x, short y, char c ); +void mono_puts ( short x, short y, char const * const str ); +void __cdecl mono_printf( short x, short y, char const * const format, ... ); + +void mono_dump ( short port = 1); + +void mono_setHardwareCursor( int flag ); + + + +#endif +#endif + \ No newline at end of file diff --git a/MONSTDAT.CPP b/MONSTDAT.CPP new file mode 100644 index 0000000..8c7c9d1 --- /dev/null +++ b/MONSTDAT.CPP @@ -0,0 +1,6268 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Monsters Data file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MONSTDAT.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "cursor.h" +#include "monster.h" +#include "monstdat.h" +#include "minitext.h" +#include "textdat.h" +#include "items.h" + + +#if RLE_DRAW +#define CEL_EXT ".CL2" +#else +#define CEL_EXT ".CEL" +#endif + + +/*-----------------------------------------------------------------------** +** Image width, Image size in K bytes +** Image files +** Special animation +** Sound files +** Special sound +** Trans file?, Transformation file name +** Neutral, Walk, Attack, Get Hit, Death, Special (# frames) +** Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) +** Name +** Min, Max dungeon level +** Monster level ranking (1 = easy, 30 = hardest) +** Min, Max hitpoints +** Intelligence (0 = easiest, 3 = hardest of type) +** Hit% #1 +** Hit check frame #1 +** Min, Max damage #1 +** Hit% #2 +** Hit check frame #2 +** Min, Max damage #2 +** Armor Class +** Magic resist +** Monster Class +** Selection Flags +** Experience points +**-----------------------------------------------------------------------*/ + +MonsterData monsterdata[] = +{ +// MT_NZOMBIE + { 128, 799, // Image width, Image size + "Monsters\\Zombie\\Zombie%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Zombie\\Zombie%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 11, 24, 12, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Zombie", // Name + 1, 3, // Min, Max dungeon level + 1, // Monster level ranking (1 = easy, 30 = hardest) + 4, 7, // Min, Max hitpoints + AI_ZOMBIE, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 10, // Hit% #1 + 8, // Hit check frame #1 + 2, 5, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 5, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 54}, // Experience points + +// MT_BZOMBIE + { 128, 799, // Image width, Image size + "Monsters\\Zombie\\Zombie%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Zombie\\Zombie%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Zombie\\Bluered.TRN", // Trans file?, Transformation file name + { 11, 24, 12, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Ghoul", // Name + 2, 4, // Min, Max dungeon level + 2, // Monster level ranking (1 = easy, 30 = hardest) + 7, 11, // Min, Max hitpoints + AI_ZOMBIE, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 10, // Hit% #1 + 8, // Hit check frame #1 + 3, 10, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 10, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 58 }, // Experience points + +// MT_GZOMBIE + { 128, 799, // Image width, Image size + "Monsters\\Zombie\\Zombie%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Zombie\\Zombie%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Zombie\\Grey.TRN", // Trans file?, Transformation file name + { 11, 24, 12, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Rotting Carcass", // Name + 2, 6, // Min, Max dungeon level + 4, // Monster level ranking (1 = easy, 30 = hardest) + 15, 25, // Min, Max hitpoints + AI_ZOMBIE, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 25, // Hit% #1 + 8, // Hit check frame #1 + 5, 15, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 15, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II+M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 136 }, // Experience points + +// MT_YZOMBIE + { 128, 799, // Image width, Image size + "Monsters\\Zombie\\Zombie%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Zombie\\Zombie%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Zombie\\Yellow.TRN", // Trans file?, Transformation file name + { 11, 24, 12, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Black Death", // Name + 4, 8, // Min, Max dungeon level + 6, // Monster level ranking (1 = easy, 30 = hardest) + 25, 40, // Min, Max hitpoints + AI_ZOMBIE, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 30, // Hit% #1 + 8, // Hit check frame #1 + 6, 22, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 20, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 240 }, // Experience points + +// MT_RFALLSP + { 128, 543, // Image width, Image size + "Monsters\\FalSpear\\Phall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSpear\\Phall%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\FalSpear\\FallenT.TRN", // Trans file?, Transformation file name + { 11, 11, 13, 11, 18, 13 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Fallen One", // Name + 1, 3, // Min, Max dungeon level + 1, // Monster level ranking (1 = easy, 30 = hardest) + 1, 4, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 15, // Hit% #1 + 7, // Hit check frame #1 + 1, 3, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 46 }, // Experience points + +// MT_DFALLSP + { 128, 543, // Image width, Image size + "Monsters\\FalSpear\\Phall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSpear\\Phall%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\FalSpear\\Dark.TRN", // Trans file?, Transformation file name + { 11, 11, 13, 11, 18, 13 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Carver", // Name + 2, 5, // Min, Max dungeon level + 3, // Monster level ranking (1 = easy, 30 = hardest) + 4, 8, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 20, // Hit% #1 + 7, // Hit check frame #1 + 2, 5, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 5, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 80 }, // Experience points + +// MT_YFALLSP + { 128, 543, // Image width, Image size + "Monsters\\FalSpear\\Phall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSpear\\Phall%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 11, 11, 13, 11, 18, 13 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Devil Kin", // Name + 3, 7, // Min, Max dungeon level + 5, // Monster level ranking (1 = easy, 30 = hardest) + 12, 24, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 25, // Hit% #1 + 7, // Hit check frame #1 + 3, 7, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 10, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 155 }, // Experience points + +// MT_BFALLSP + { 128, 543, // Image width, Image size + "Monsters\\FalSpear\\Phall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSpear\\Phall%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\FalSpear\\Blue.TRN", // Trans file?, Transformation file name + { 11, 11, 13, 11, 18, 13 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Dark One", // Name + 5, 9, // Min, Max dungeon level + 7, // Monster level ranking (1 = easy, 30 = hardest) + 20, 36, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 30, // Hit% #1 + 7, // Hit check frame #1 + 4, 8, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 15, // Armor Class + MC_ANIMAL, // Monster Class + M_II, // Magic resist + M_II+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 255 }, // Experience points + +// MT_WSKELAX + { 128, 553, // Image width, Image size + "Monsters\\SkelAxe\\SklAx%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelAxe\\SklAx%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelAxe\\White.TRN", // Trans file?, Transformation file name + { 12, 8, 13, 6, 17, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 5, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Skeleton", // Name + 1, 3, // Min, Max dungeon level + 1, // Monster level ranking (1 = easy, 30 = hardest) + 2, 4, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 0, // Intelligence + 20, // Hit% #1 + 8, // Hit check frame #1 + 1, 4, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 64 }, // Experience points + +// MT_TSKELAX + { 128, 553, // Image width, Image size + "Monsters\\SkelAxe\\SklAx%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelAxe\\SklAx%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelAxe\\Skelt.TRN", // Trans file?, Transformation file name + { 12, 8, 13, 6, 17, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Corpse Axe", // Name + 2, 5, // Min, Max dungeon level + 2, // Monster level ranking (1 = easy, 30 = hardest) + 4, 7, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 25, // Hit% #1 + 8, // Hit check frame #1 + 3, 5, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 68 }, // Experience points + +// MT_RSKELAX + { 128, 553, // Image width, Image size + "Monsters\\SkelAxe\\SklAx%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelAxe\\SklAx%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 8, 13, 6, 17, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Burning Dead", // Name + 2, 6, // Min, Max dungeon level + 4, // Monster level ranking (1 = easy, 30 = hardest) + 8, 12, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 30, // Hit% #1 + 8, // Hit check frame #1 + 3, 7, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 5, // Armor Class + MC_UNDEAD, // Monster Class + M_RF+M_IM+M_II, // Magic resist + M_IF+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 154 }, // Experience points + +// MT_XSKELAX + { 128, 553, // Image width, Image size + "Monsters\\SkelAxe\\SklAx%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelAxe\\SklAx%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelAxe\\Black.TRN", // Trans file?, Transformation file name + { 12, 8, 13, 6, 17, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Horror", // Name + 4, 8, // Min, Max dungeon level + 6, // Monster level ranking (1 = easy, 30 = hardest) + 12, 20, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 8, // Hit check frame #1 + 4, 9, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 15, // Armor Class + MC_UNDEAD, // Monster Class + M_RL+M_IM+M_II, // Magic resist + M_RL+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 264 }, // Experience points + +// MT_RFALLSD + { 128, 623, // Image width, Image size + "Monsters\\FalSword\\Fall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSword\\Fall%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\FalSword\\FallenT.TRN", // Trans file?, Transformation file name + { 12, 12, 13, 11, 14, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Fallen One", // Name + 1, 3, // Min, Max dungeon level + 1, // Monster level ranking (1 = easy, 30 = hardest) + 2, 5, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 15, // Hit% #1 + 8, // Hit check frame #1 + 1, 4, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 10, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 52 }, // Experience points + +// MT_DFALLSD + { 128, 623, // Image width, Image size + "Monsters\\FalSword\\Fall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSword\\Fall%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\FalSword\\Dark.TRN", // Trans file?, Transformation file name + { 12, 12, 13, 11, 14, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Carver", // Name + 2, 5, // Min, Max dungeon level + 3, // Monster level ranking (1 = easy, 30 = hardest) + 5, 9, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 20, // Hit% #1 + 8, // Hit check frame #1 + 2, 7, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 15, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 90 }, // Experience points + +// MT_YFALLSD + { 128, 623, // Image width, Image size + "Monsters\\FalSword\\Fall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSword\\Fall%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 12, 13, 11, 14, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Devil Kin", // Name + 3, 7, // Min, Max dungeon level + 5, // Monster level ranking (1 = easy, 30 = hardest) + 16, 24, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 25, // Hit% #1 + 8, // Hit check frame #1 + 4, 10, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 20, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 180 }, // Experience points + +// MT_BFALLSD + { 128, 623, // Image width, Image size + "Monsters\\FalSword\\Fall%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\FalSword\\Fall%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\FalSword\\Blue.TRN", // Trans file?, Transformation file name + { 12, 12, 13, 11, 14, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Dark One", // Name + 5, 9, // Min, Max dungeon level + 7, // Monster level ranking (1 = easy, 30 = hardest) + 24, 36, // Min, Max hitpoints + AI_FALLEN, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 30, // Hit% #1 + 8, // Hit check frame #1 + 4, 12, // Min, Max damage #1 + 0, // Hit% #2 + 5, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 25, // Armor Class + MC_ANIMAL, // Monster Class + M_II, // Magic resist + M_II+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 280 }, // Experience points + +// MT_NSCAV + { 128, 410, // Image width, Image size + "Monsters\\Scav\\Scav%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Scav\\Scav%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 11 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Scavenger", // Name + 1, 4, // Min, Max dungeon level + 2, // Monster level ranking (1 = easy, 30 = hardest) + 3, 6, // Min, Max hitpoints + AI_SCAV, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 20, // Hit% #1 + 7, // Hit check frame #1 + 1, 5, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 10, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 80 }, // Experience points + +// MT_BSCAV + { 128, 410, // Image width, Image size + "Monsters\\Scav\\Scav%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Scav\\Scav%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Scav\\ScavBr.TRN", // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 11 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Plague Eater", // Name + 3, 6, // Min, Max dungeon level + 4, // Monster level ranking (1 = easy, 30 = hardest) + 12, 24, // Min, Max hitpoints + AI_SCAV, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 30, // Hit% #1 + 7, // Hit check frame #1 + 1, 8, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 20, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 188 }, // Experience points + +// MT_WSCAV + { 128, 410, // Image width, Image size + "Monsters\\Scav\\Scav%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Scav\\Scav%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Scav\\ScavBe.TRN", // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 11 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Shadow Beast", // Name + 4, 8, // Min, Max dungeon level + 6, // Monster level ranking (1 = easy, 30 = hardest) + 24, 36, // Min, Max hitpoints + AI_SCAV, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 7, // Hit check frame #1 + 3, 12, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 25, // Armor Class + MC_ANIMAL, // Monster Class + M_II, // Magic resist + M_II+M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 375 }, // Experience points + +// MT_YSCAV + { 128, 410, // Image width, Image size + "Monsters\\Scav\\Scav%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Scav\\Scav%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Scav\\ScavW.TRN", // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 11 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Bone Gasher", // Name + 6, 10, // Min, Max dungeon level + 8, // Monster level ranking (1 = easy, 30 = hardest) + 28, 40, // Min, Max hitpoints + AI_SCAV, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 7, // Hit check frame #1 + 5, 15, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_ANIMAL, // Monster Class + M_RM+M_II, // Magic resist + M_II+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 552 }, // Experience points + +// MT_WSKELBW + { 128, 567, // Image width, Image size + "Monsters\\SkelBow\\SklBw%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelBow\\SklBw%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelBow\\White.TRN", // Trans file?, Transformation file name + { 9, 8, 16, 5, 16, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Skeleton", // Name + 2, 5, // Min, Max dungeon level + 3, // Monster level ranking (1 = easy, 30 = hardest) + 2, 4, // Min, Max hitpoints + AI_SKELBOW, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 15, // Hit% #1 + 12, // Hit check frame #1 + 1, 2, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 110 }, // Experience points + +// MT_TSKELBW + { 128, 567, // Image width, Image size + "Monsters\\SkelBow\\SklBw%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelBow\\SklBw%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelBow\\Skelt.TRN", // Trans file?, Transformation file name + { 9, 8, 16, 5, 16, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Corpse Bow", // Name + 3, 7, // Min, Max dungeon level + 5, // Monster level ranking (1 = easy, 30 = hardest) + 8, 16, // Min, Max hitpoints + AI_SKELBOW, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 25, // Hit% #1 + 12, // Hit check frame #1 + 1, 4, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 210 }, // Experience points + +// MT_RSKELBW + { 128, 567, // Image width, Image size + "Monsters\\SkelBow\\SklBw%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelBow\\SklBw%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 9, 8, 16, 5, 16, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Burning Dead", // Name + 5, 9, // Min, Max dungeon level + 7, // Monster level ranking (1 = easy, 30 = hardest) + 10, 24, // Min, Max hitpoints + AI_SKELBOW, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 30, // Hit% #1 + 12, // Hit check frame #1 + 1, 6, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 5, // Armor Class + MC_UNDEAD, // Monster Class + M_RF+M_IM+M_II, // Magic resist + M_IF+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 364 }, // Experience points + +// MT_XSKELBW + { 128, 567, // Image width, Image size + "Monsters\\SkelBow\\SklBw%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelBow\\SklBw%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelBow\\Black.TRN", // Trans file?, Transformation file name + { 9, 8, 16, 5, 16, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Horror", // Name + 7, 11, // Min, Max dungeon level + 9, // Monster level ranking (1 = easy, 30 = hardest) + 15, 45, // Min, Max hitpoints + AI_SKELBOW, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 12, // Hit check frame #1 + 2, 9, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 15, // Armor Class + MC_UNDEAD, // Monster Class + M_RL+M_IM+M_II, // Magic resist + M_RL+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 594 }, // Experience points + +// MT_WSKELSD + { 128, 575, // Image width, Image size + "Monsters\\SkelSd\\SklSr%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelSd\\SklSr%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\SkelSd\\White.TRN", // Trans file?, Transformation file name + { 13, 8, 12, 7, 15, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Skeleton Captain", // Name + 1, 4, // Min, Max dungeon level + 2, // Monster level ranking (1 = easy, 30 = hardest) + 3, 6, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 20, // Hit% #1 + 8, // Hit check frame #1 + 2, 7, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 10, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 90 }, // Experience points + +// MT_TSKELSD + { 128, 575, // Image width, Image size + "Monsters\\SkelSd\\SklSr%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelSd\\SklSr%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelSd\\Skelt.TRN", // Trans file?, Transformation file name + { 13, 8, 12, 7, 15, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Corpse Captain", // Name + 2, 6, // Min, Max dungeon level + 4, // Monster level ranking (1 = easy, 30 = hardest) + 12, 20, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 30, // Hit% #1 + 8, // Hit check frame #1 + 3, 9, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 5, // Armor Class + MC_UNDEAD, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 200 }, // Experience points + +// MT_RSKELSD + { 128, 575, // Image width, Image size + "Monsters\\SkelSd\\SklSr%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelSd\\SklSr%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 8, 12, 7, 15, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Burning Dead Captain", // Name + 4, 8, // Min, Max dungeon level + 6, // Monster level ranking (1 = easy, 30 = hardest) + 16, 30, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 8, // Hit check frame #1 + 4, 10, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 15, // Armor Class + MC_UNDEAD, // Monster Class + M_RF+M_IM+M_II, // Magic resist + M_IF+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 393 }, // Experience points + +// MT_XSKELSD + { 128, 575, // Image width, Image size + "Monsters\\SkelSd\\SklSr%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SkelSd\\SklSr%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\SkelSd\\Black.TRN", // Trans file?, Transformation file name + { 13, 8, 12, 7, 15, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Horror Captain", // Name + 6, 10, // Min, Max dungeon level + 8, // Monster level ranking (1 = easy, 30 = hardest) + 35, 50, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 40, // Hit% #1 + 8, // Hit check frame #1 + 5, 14, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_UNDEAD, // Monster Class + M_RL+M_IM+M_II, // Magic resist + M_RL+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 604 }, // Experience points + +// MT_INVILORD + { 128, 800/*2000*/, // Image width, Image size + "Monsters\\TSneak\\TSneak%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\TSneak\\Sneakl%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 13, 15, 11, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Invisible Lord", // Name + 36, 39, // Min, Max dungeon level + 14, // Monster level ranking (1 = easy, 30 = hardest) + 278, 278, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 65, // Hit% #1 + 8, // Hit check frame #1 + 16, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_RF+M_RL+M_II, // Magic resist + M_RM+M_RF+M_RL+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2000 }, // Experience points + +// MT_SNEAK + { 128, 992, // Image width, Image size + "Monsters\\Sneak\\Sneak%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Sneak\\Sneak%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 16, 8, 12, 8, 24, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hidden", // Name + 3, 8, // Min, Max dungeon level + 5, // Monster level ranking (1 = easy, 30 = hardest) + 8, 24, // Min, Max hitpoints + AI_SNEAK, + MFLAG_INVISIBLE, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 8, // Hit check frame #1 + 3, 6, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 25, // Armor Class + MC_DEMON, // Monster Class + M_NONE, // Magic resist + M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 278 }, // Experience points + +// MT_STALKER + { 128, 992, // Image width, Image size + "Monsters\\Sneak\\Sneak%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Sneak\\Sneak%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Sneak\\Sneakv2.TRN", // Trans file?, Transformation file name + { 16, 8, 12, 8, 24, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Stalker", // Name + 8, 12, // Min, Max dungeon level + 9, // Monster level ranking (1 = easy, 30 = hardest) + 30, 45, // Min, Max hitpoints + AI_SNEAK, + MFLAG_INVISIBLE|MFLAG_PATH, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 40, // Hit% #1 + 8, // Hit check frame #1 + 8, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_DEMON, // Monster Class + M_NONE, // Magic resist + M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 630 }, // Experience points + +// MT_UNSEEN + { 128, 992, // Image width, Image size + "Monsters\\Sneak\\Sneak%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Sneak\\Sneak%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Sneak\\Sneakv3.TRN", // Trans file?, Transformation file name + { 16, 8, 12, 8, 24, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Unseen", // Name + 10, 14, // Min, Max dungeon level + 11, // Monster level ranking (1 = easy, 30 = hardest) + 35, 50, // Min, Max hitpoints + AI_SNEAK, + MFLAG_INVISIBLE|MFLAG_PATH, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 45, // Hit% #1 + 8, // Hit check frame #1 + 12, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 935 }, // Experience points + +// MT_ILLWEAV + { 128, 992, // Image width, Image size + "Monsters\\Sneak\\Sneak%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Sneak\\Sneak%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Sneak\\Sneakv1.TRN", // Trans file?, Transformation file name + { 16, 8, 12, 8, 24, 15 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Illusion Weaver", // Name + 14, 18, // Min, Max dungeon level + 13, // Monster level ranking (1 = easy, 30 = hardest) + 40, 60, // Min, Max hitpoints + AI_SNEAK, + MFLAG_INVISIBLE|MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 16, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_RF, // Magic resist + M_IM+M_RF+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1500 }, // Experience points + +// MT_LRDSAYTR + { 160, 800 /*2000*/, // Image width, Image size + "Monsters\\GoatLord\\GoatL%c" CEL_EXT, // Image files + FALSE, // Special animation +// "Monsters\\GoatLord\\Goatl%c%i.WAV", // Sound files + "Monsters\\newsfx\\Satyr%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 13, 14, 9, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Satyr Lord", // Name + 40, 43, // Min, Max dungeon level + 28, // Monster level ranking (1 = easy, 30 = hardest) + 160, 200, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 90, // Hit% #1 + 8, // Hit check frame #1 + 20, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_ANIMAL, // Monster Class + M_RL+M_RF, // Magic resist + M_RM+M_IL+M_IF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2800 }, // Experience points + +// MT_NGOATMC + { 128, 1030, // Image width, Image size + "Monsters\\GoatMace\\Goat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\GoatMace\\Goat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Flesh Clan", // Name + 6, 10, // Min, Max dungeon level + 8, // Monster level ranking (1 = easy, 30 = hardest) + 30, 45, // Min, Max hitpoints + AI_GOATMC, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 8, // Hit check frame #1 + 4, 10, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 40, // Armor Class + MC_DEMON, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 460 }, // Experience points + +// MT_BGOATMC + { 128, 1030, // Image width, Image size + "Monsters\\GoatMace\\Goat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\GoatMace\\Goat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\GoatMace\\Beige.TRN", // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Stone Clan", // Name + 8, 12, // Min, Max dungeon level + 10, // Monster level ranking (1 = easy, 30 = hardest) + 40, 55, // Min, Max hitpoints + AI_GOATMC, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 6, 12, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 40, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 685 }, // Experience points + +// MT_RGOATMC + { 128, 1030, // Image width, Image size + "Monsters\\GoatMace\\Goat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\GoatMace\\Goat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\GoatMace\\Red.TRN", // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Fire Clan", // Name + 10, 14, // Min, Max dungeon level + 12, // Monster level ranking (1 = easy, 30 = hardest) + 50, 65, // Min, Max hitpoints + AI_GOATMC, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 70, // Hit% #1 + 8, // Hit check frame #1 + 8, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 45, // Armor Class + MC_DEMON, // Monster Class + M_RF, // Magic resist + M_IF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 906 }, // Experience points + +// MT_GGOATMC + { 128, 1030, // Image width, Image size + "Monsters\\GoatMace\\Goat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\GoatMace\\Goat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\GoatMace\\Gray.TRN", // Trans file?, Transformation file name + { 12, 8, 12, 6, 20, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Night Clan", // Name + 12, 16, // Min, Max dungeon level + 14, // Monster level ranking (1 = easy, 30 = hardest) + 55, 70, // Min, Max hitpoints + AI_GOATMC, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 8, // Hit check frame #1 + 10, 20, // Min, Max damage #1 + 15, // Hit% #2 + 0, // Hit check frame #2 + 30, 30, // Min, Max damage #2 + 50, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1190 }, // Experience points + +// MT_FIEND + { 96, 364, // Image width, Image size + "Monsters\\Bat\\Bat%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Bat\\Bat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Bat\\red.trn", // Trans file?, Transformation file name + { 9, 13, 10, 9, 13, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Fiend", // Name + 2, 5, // Min, Max dungeon level + 3, // Monster level ranking (1 = easy, 30 = hardest) + 3, 6, // Min, Max hitpoints + AI_BAT, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 5, // Hit check frame #1 + 1, 6, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + T_NONE, // Treasure + MSEL_FLY, // Selection Type + 102 }, // Experience points + +// MT_BLINK + { 96, 364, // Image width, Image size + "Monsters\\Bat\\Bat%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Bat\\Bat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 9, 13, 10, 9, 13, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Blink", // Name + 5, 9, // Min, Max dungeon level + 7, // Monster level ranking (1 = easy, 30 = hardest) + 12, 28, // Min, Max hitpoints + AI_BAT, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 45, // Hit% #1 + 5, // Hit check frame #1 + 1, 8, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 15, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + T_NONE, // Treasure + MSEL_FLY, // Selection Type + 340 }, // Experience points + +// MT_GLOOM + { 96, 364, // Image width, Image size + "Monsters\\Bat\\Bat%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Bat\\Bat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Bat\\grey.trn", // Trans file?, Transformation file name + { 9, 13, 10, 9, 13, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Gloom", // Name + 7, 11, // Min, Max dungeon level + 9, // Monster level ranking (1 = easy, 30 = hardest) + 28, 36, // Min, Max hitpoints + AI_BAT, + MFLAG_PATH, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 70, // Hit% #1 + 5, // Hit check frame #1 + 4, 12, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_ANIMAL, // Monster Class + M_RM, // Magic resist + M_RM+M_II, // Magic resist2 + T_NONE, // Treasure + MSEL_FLY, // Selection Type + 509 }, // Experience points + +// MT_FAMILIAR + { 96, 364, // Image width, Image size + "Monsters\\Bat\\Bat%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Bat\\Bat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Bat\\orange.trn", // Trans file?, Transformation file name + { 9, 13, 10, 9, 13, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Familiar", // Name + 11, 15, // Min, Max dungeon level + 13, // Monster level ranking (1 = easy, 30 = hardest) + 20, 35, // Min, Max hitpoints + AI_BAT, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 5, // Hit check frame #1 + 4, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IL, // Magic resist + M_RM+M_IL+M_II, // Magic resist2 + T_NONE, // Treasure + MSEL_FLY, // Selection Type + 448 }, // Experience points + +// MT_NGOATBW + { 128, 1040, // Image width, Image size + "Monsters\\GoatBow\\GoatB%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\GoatBow\\GoatB%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 8, 16, 6, 20, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Flesh Clan", // Name + 6, 10, // Min, Max dungeon level + 8, // Monster level ranking (1 = easy, 30 = hardest) + 20, 35, // Min, Max hitpoints + AI_GOATBOW, + MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 35, // Hit% #1 + 13, // Hit check frame #1 + 1, 7, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_DEMON, // Monster Class + M_NONE, // Magic resist + M_NONE, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 448 }, // Experience points + +// MT_BGOATBW + { 128, 1040, // Image width, Image size + "Monsters\\GoatBow\\GoatB%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\GoatBow\\GoatB%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\GoatBow\\Beige.TRN", // Trans file?, Transformation file name + { 12, 8, 16, 6, 20, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Stone Clan", // Name + 8, 12, // Min, Max dungeon level + 10, // Monster level ranking (1 = easy, 30 = hardest) + 30, 40, // Min, Max hitpoints + AI_GOATBOW, + MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 40, // Hit% #1 + 13, // Hit check frame #1 + 2, 9, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 645 }, // Experience points + +// MT_RGOATBW + { 128, 1040, // Image width, Image size + "Monsters\\GoatBow\\GoatB%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\GoatBow\\GoatB%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\GoatBow\\Red.TRN", // Trans file?, Transformation file name + { 12, 8, 16, 6, 20, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Fire Clan", // Name + 10, 14, // Min, Max dungeon level + 12, // Monster level ranking (1 = easy, 30 = hardest) + 40, 50, // Min, Max hitpoints + AI_GOATBOW, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 45, // Hit% #1 + 13, // Hit check frame #1 + 3, 11, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_DEMON, // Monster Class + M_RF, // Magic resist + M_IF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 822 }, // Experience points + +// MT_GGOATBW + { 128, 1040, // Image width, Image size + "Monsters\\GoatBow\\GoatB%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\GoatBow\\GoatB%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\GoatBow\\Gray.TRN", // Trans file?, Transformation file name + { 12, 8, 16, 6, 20, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Night Clan", // Name + 12, 16, // Min, Max dungeon level + 14, // Monster level ranking (1 = easy, 30 = hardest) + 50, 65, // Min, Max hitpoints + AI_GOATBOW, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 13, // Hit check frame #1 + 4, 13, // Min, Max damage #1 + 15, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 40, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1092 }, // Experience points + +// MT_NACID + { 128, 716, // Image width, Image size + "Monsters\\Acid\\Acid%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 8, 12, 8, 16, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Acid Beast", // Name + 10, 14, // Min, Max dungeon level + 11, // Monster level ranking (1 = easy, 30 = hardest) + 40, 66, // Min, Max hitpoints + AI_ACID, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 40, // Hit% #1 + 8, // Hit check frame #1 + 4, 12, // Min, Max damage #1 + 25, // Hit% #2 + 8, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_ANIMAL, // Monster Class + M_IA, // Magic resist + M_IA+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 846 }, // Experience points + +// MT_RACID + { 128, 716, // Image width, Image size + "Monsters\\Acid\\Acid%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Acid\\AcidBlk.TRN", // Trans file?, Transformation file name + { 13, 8, 12, 8, 16, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Poison Spitter", // Name + 14, 18, // Min, Max dungeon level + 15, // Monster level ranking (1 = easy, 30 = hardest) + 60, 85, // Min, Max hitpoints + AI_ACID, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 45, // Hit% #1 + 8, // Hit check frame #1 + 4, 16, // Min, Max damage #1 + 25, // Hit% #2 + 8, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_ANIMAL, // Monster Class + M_IA, // Magic resist + M_IA+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1248 }, // Experience points + +// MT_BACID + { 128, 716, // Image width, Image size + "Monsters\\Acid\\Acid%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Acid\\AcidB.TRN", // Trans file?, Transformation file name + { 13, 8, 12, 8, 16, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Pit Beast", // Name + 18, 22, // Min, Max dungeon level + 21, // Monster level ranking (1 = easy, 30 = hardest) + 80, 110, // Min, Max hitpoints + AI_ACID, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 55, // Hit% #1 + 8, // Hit check frame #1 + 8, 18, // Min, Max damage #1 + 35, // Hit% #2 + 8, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_ANIMAL, // Monster Class + M_IA|M_RM, // Magic resist + M_IA|M_IM|M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2060 }, // Experience points + +// MT_XACID + { 128, 716, // Image width, Image size + "Monsters\\Acid\\Acid%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Acid\\AcidR.TRN", // Trans file?, Transformation file name + { 13, 8, 12, 8, 16, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Lava Maw", // Name + 22, 27, // Min, Max dungeon level + 25, // Monster level ranking (1 = easy, 30 = hardest) + 100, 150, // Min, Max hitpoints + AI_ACID, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 65, // Hit% #1 + 8, // Hit check frame #1 + 10, 20, // Min, Max damage #1 + 40, // Hit% #2 + 8, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_ANIMAL, // Monster Class + M_IA|M_RM|M_IF, // Magic resist + M_IA|M_IM|M_IF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2940 }, // Experience points + +// MT_SKING + { 160, 1010, // Image width, Image size + "Monsters\\SKing\\SKing%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\SKing\\SKing%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\SkelAxe\\White.TRN", // Trans file?, Transformation file name + { 8, 6, 16, 6, 16, 6 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 2 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Skeleton King", // Name + 6, 6, // Min, Max dungeon level + 9, // Monster level ranking (1 = easy, 30 = hardest) + 140, 140, // Min, Max hitpoints + AI_SKELKING, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 6, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_UNDEAD, // Monster Class + M_RF+M_RL+M_IM+M_II, // Magic resist + M_IF+M_IL+M_IM+M_II, // Magic resist2 + T_U+UID_SKCROWN, // Treasure + MSEL_BIG, // Selection Type + 570 }, // Experience points + +// MT_CLEAVER + { 128, 980, // Image width, Image size + "Monsters\\FatC\\FatC%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\FatC\\FatC%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 8, 12, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 1, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "The Butcher", // Name + 0, 0, // Min, Max dungeon level + 1, // Monster level ranking (1 = easy, 30 = hardest) + 320, 320, // Min, Max hitpoints + AI_CLEAVER, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 8, // Hit check frame #1 + 6, 12, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_RL, // Magic resist + M_IF+M_IL+M_RM, // Magic resist2 + T_U+UID_CLEAVER, // Treasure + MSEL_REG, // Selection Type + 710 }, // Experience points + +// MT_FAT + { 128, 1130, // Image width, Image size + "Monsters\\Fat\\Fat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 8, 10, 15, 6, 16, 10 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Overlord", // Name + 8, 12, // Min, Max dungeon level + 10, // Monster level ranking (1 = easy, 30 = hardest) + 60, 80, // Min, Max hitpoints + AI_FAT, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 55, // Hit% #1 + 8, // Hit check frame #1 + 6, 12, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 55, // Armor Class + MC_DEMON, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 635 }, // Experience points + +// MT_MUDMAN + { 128, 1130, // Image width, Image size + "Monsters\\Fat\\Fat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Fat\\Blue.TRN", // Trans file?, Transformation file name + { 8, 10, 15, 6, 16, 10 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Mud Man", // Name + 13, 17, // Min, Max dungeon level + 14, // Monster level ranking (1 = easy, 30 = hardest) + 100, 125, // Min, Max hitpoints + AI_FAT, + MFLAG_PATH, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 8, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_NONE, // Magic resist + M_IL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1165 }, // Experience points + +// MT_TOAD + { 128, 1130, // Image width, Image size + "Monsters\\Fat\\Fat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Fat\\FatB.TRN", // Trans file?, Transformation file name + { 8, 10, 15, 6, 16, 10 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Toad Demon", // Name + 15, 19, // Min, Max dungeon level + 16, // Monster level ranking (1 = easy, 30 = hardest) + 135, 160, // Min, Max hitpoints + AI_FAT, + MFLAG_PATH, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 70, // Hit% #1 + 8, // Hit check frame #1 + 8, 16, // Min, Max damage #1 + 40, // Hit% #2 + 0, // Hit check frame #2 + 8, 20, // Min, Max damage #2 + 65, // Armor Class + MC_DEMON, // Monster Class + M_IM, // Magic resist + M_IM+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1380 }, // Experience points + +// MT_FLAYED + { 128, 1130, // Image width, Image size + "Monsters\\Fat\\Fat%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Fat\\FatF.TRN", // Trans file?, Transformation file name + { 8, 10, 15, 6, 16, 10 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 4, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Flayed One", // Name + 19, 23, // Min, Max dungeon level + 20, // Monster level ranking (1 = easy, 30 = hardest) + 160, 200, // Min, Max hitpoints + AI_FAT, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 85, // Hit% #1 + 8, // Hit check frame #1 + 10, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IF, // Magic resist + M_IM+M_IF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2058 }, // Experience points + +// MT_WYRM + { 160, 2420, // Image width, Image size + "Monsters\\Worm\\Worm%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 13, 13, 11, 19, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Wyrm", // Name + 9, 13, // Min, Max dungeon level + 11, // Monster level ranking (1 = easy, 30 = hardest) + 60, 90, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 40, // Hit% #1 + 8, // Hit check frame #1 + 4, 10, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 25, // Armor Class + MC_ANIMAL, // Monster Class + M_RM, // Magic resist + M_RM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 660 }, // Experience points + +// MT_CAVSLUG + { 160, 2420, // Image width, Image size + "Monsters\\Worm\\Worm%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 13, 13, 11, 19, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Cave Slug", // Name + 11, 15, // Min, Max dungeon level + 13, // Monster level ranking (1 = easy, 30 = hardest) + 75, 110, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 8, // Hit check frame #1 + 6, 13, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_ANIMAL, // Monster Class + M_RM, // Magic resist + M_RM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 994 }, // Experience points + +// MT_DVLWYRM + { 160, 2420, // Image width, Image size + "Monsters\\Worm\\Worm%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 13, 13, 11, 19, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Devil Wyrm", // Name + 13, 17, // Min, Max dungeon level + 15, // Monster level ranking (1 = easy, 30 = hardest) + 100, 140, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 55, // Hit% #1 + 8, // Hit check frame #1 + 8, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_ANIMAL, // Monster Class + M_RM+M_RF, // Magic resist + M_RM+M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1320 }, // Experience points + +// MT_DEVOUR + { 160, 2420, // Image width, Image size + "Monsters\\Worm\\Worm%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Fat\\Fat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 13, 13, 11, 19, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Devourer", // Name + 15, 19, // Min, Max dungeon level + 17, // Monster level ranking (1 = easy, 30 = hardest) + 125, 200, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 10, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 35, // Armor Class + MC_ANIMAL, // Monster Class + M_RM+M_RF+M_II, // Magic resist + M_RM+M_RF+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1827 }, // Experience points + +// MT_NMAGMA + { 128, 1680, // Image width, Image size + "Monsters\\Magma\\Magma%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Magma\\Magma%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 8, 10, 14, 7, 18, 18 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Magma Demon", // Name + 14, 17, // Min, Max dungeon level + 13, // Monster level ranking (1 = easy, 30 = hardest) + 50, 70, // Min, Max hitpoints + AI_MAGMA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 45, // Hit% #1 + 4, // Hit check frame #1 + 2, 10, // Min, Max damage #1 + 50, // Hit% #2 + 13, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 45, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_IM, // Magic resist + M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1076 }, // Experience points + +// MT_YMAGMA + { 128, 1680, // Image width, Image size + "Monsters\\Magma\\Magma%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Magma\\Magma%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Magma\\Yellow.TRN", // Trans file?, Transformation file name + { 8, 10, 14, 7, 18, 18 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Blood Stone", // Name + 15, 19, // Min, Max dungeon level + 14, // Monster level ranking (1 = easy, 30 = hardest) + 55, 75, // Min, Max hitpoints + AI_MAGMA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 4, // Hit check frame #1 + 2, 12, // Min, Max damage #1 + 50, // Hit% #2 + 14, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 45, // Armor Class + MC_DEMON, // Monster Class + M_IF+M_IM, // Magic resist + M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1309 }, // Experience points + +// MT_BMAGMA + { 128, 1680, // Image width, Image size + "Monsters\\Magma\\Magma%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Magma\\Magma%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Magma\\Blue.TRN", // Trans file?, Transformation file name + { 8, 10, 14, 7, 18, 18 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hell Stone", // Name + 16, 20, // Min, Max dungeon level + 16, // Monster level ranking (1 = easy, 30 = hardest) + 60, 80, // Min, Max hitpoints + AI_MAGMA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 4, // Hit check frame #1 + 2, 20, // Min, Max damage #1 + 60, // Hit% #2 + 14, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_DEMON, // Monster Class + M_IF+M_IM, // Magic resist + M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1680 }, // Experience points + +// MT_WMAGMA + { 128, 1680, // Image width, Image size + "Monsters\\Magma\\Magma%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Magma\\Magma%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Magma\\Wierd.TRN", // Trans file?, Transformation file name + { 8, 10, 14, 7, 18, 18 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Lava Lord", // Name + 17, 21, // Min, Max dungeon level + 18, // Monster level ranking (1 = easy, 30 = hardest) + 70, 85, // Min, Max hitpoints + AI_MAGMA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 4, // Hit check frame #1 + 4, 24, // Min, Max damage #1 + 60, // Hit% #2 + 14, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_IF+M_IM, // Magic resist + M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2124 }, // Experience points + +// MT_HORNED + { 160, 1630, // Image width, Image size + "Monsters\\Rhino\\Rhino%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Rhino\\Rhino%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 8, 8, 14, 6, 16, 6 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Horned Demon", // Name + 12, 16, // Min, Max dungeon level + 13, // Monster level ranking (1 = easy, 30 = hardest) + 40, 80, // Min, Max hitpoints + AI_RHINO, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 7, // Hit check frame #1 + 2, 16, // Min, Max damage #1 + 100, // Hit% #2 + 0, // Hit check frame #2 + 5, 32, // Min, Max damage #2 + 40, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1172 }, // Experience points + +// MT_MUDRUN + { 160, 1630, // Image width, Image size + "Monsters\\Rhino\\Rhino%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Rhino\\Rhino%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Rhino\\Orange.TRN", // Trans file?, Transformation file name + { 8, 8, 14, 6, 16, 6 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Mud Runner", // Name + 14, 18, // Min, Max dungeon level + 15, // Monster level ranking (1 = easy, 30 = hardest) + 50, 90, // Min, Max hitpoints + AI_RHINO, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 70, // Hit% #1 + 7, // Hit check frame #1 + 6, 18, // Min, Max damage #1 + 100, // Hit% #2 + 0, // Hit check frame #2 + 12,36, // Min, Max damage #2 + 45, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1404 }, // Experience points + +// MT_FROSTC + { 160, 1630, // Image width, Image size + "Monsters\\Rhino\\Rhino%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Rhino\\Rhino%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Rhino\\Blue.TRN", // Trans file?, Transformation file name + { 8, 8, 14, 6, 16, 6 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Frost Charger", // Name + 16, 20, // Min, Max dungeon level + 17, // Monster level ranking (1 = easy, 30 = hardest) + 60, 100, // Min, Max hitpoints + AI_RHINO, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 7, // Hit check frame #1 + 8, 20, // Min, Max damage #1 + 100, // Hit% #2 + 0, // Hit check frame #2 + 20, 40, // Min, Max damage #2 + 50, // Armor Class + MC_ANIMAL, // Monster Class + M_RL+M_IM, // Magic resist + M_RL+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1720 }, // Experience points + +// MT_OBLORD + { 160, 1630, // Image width, Image size + "Monsters\\Rhino\\Rhino%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Rhino\\Rhino%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Rhino\\RhinoB.TRN", // Trans file?, Transformation file name + { 8, 8, 14, 6, 16, 6 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Obsidian Lord", // Name + 18, 22, // Min, Max dungeon level + 19, // Monster level ranking (1 = easy, 30 = hardest) + 70, 110, // Min, Max hitpoints + AI_RHINO, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 90, // Hit% #1 + 7, // Hit check frame #1 + 10, 22, // Min, Max damage #1 + 100, // Hit% #2 + 0, // Hit check frame #2 + 20, 50, // Min, Max damage #2 + 55, // Armor Class + MC_ANIMAL, // Monster Class + M_RL+M_IM, // Magic resist + M_IL+M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1809 }, // Experience points + +// MT_BONEDMN + { 128, 1740, // Image width, Image size + "Monsters\\Demskel\\Demskl%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, "Monsters\\Thin\\Thinv3.TRN", // Trans file?, Transformation file name + { 10, 8, 20, 6, 24, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "oldboned", // Name + 46, 47, // Min, Max dungeon level + 12, // Monster level ranking (1 = easy, 30 = hardest) + 70, 70, // Min, Max hitpoints + AI_STORM, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 6, 14, // Min, Max damage #1 + 12, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_DEMON, // Monster Class + M_IM+M_II, // Magic resist + M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1344 }, // Experience points + +// MT_REDDTH + { 160, 1740, // Image width, Image size + "Monsters\\Thin\\Thin%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Thin\\Thinv3.TRN", // Trans file?, Transformation file name + { 8, 8, 18, 4, 17, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Red Death", // Name + 14, 18, // Min, Max dungeon level + 16, // Monster level ranking (1 = easy, 30 = hardest) + 96, 96, // Min, Max hitpoints + AI_STORM, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 5, // Hit check frame #1 + 10, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_IM+M_IF, // Magic resist + M_IM+M_IF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2168 }, // Experience points + +// MT_LTCHDMN + { 160, 1740, // Image width, Image size + "Monsters\\Thin\\Thin%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Thin\\Thinv3.TRN", // Trans file?, Transformation file name + { 8, 8, 18, 4, 17, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Litch Demon", // Name + 16, 20, // Min, Max dungeon level + 18, // Monster level ranking (1 = easy, 30 = hardest) + 110, 110, // Min, Max hitpoints + AI_STORM, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 5, // Hit check frame #1 + 10, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 45, // Armor Class + MC_DEMON, // Monster Class + M_IM+M_IL+M_II, // Magic resist + M_IM+M_IL+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2736 }, // Experience points + +// MT_UDEDBLRG + { 160, 1740, // Image width, Image size + "Monsters\\Thin\\Thin%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Thin\\Thinv3.TRN", // Trans file?, Transformation file name + { 8, 8, 18, 4, 17, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Undead Balrog", // Name + 20, 24, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 130, 130, // Min, Max hitpoints + AI_STORM, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 85, // Hit% #1 + 5, // Hit check frame #1 + 12, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 65, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_RL+M_IM+M_II, // Magic resist + M_RF+M_RL+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3575 }, // Experience points + +// MT_INCIN + { 128, 1460, // Image width, Image size + "Monsters\\Fireman\\FireM%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 14, 19, 20, 8, 14, 23 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Incinerator", // Name + 40, 43, // Min, Max dungeon level + 16, // Monster level ranking (1 = easy, 30 = hardest) + 30, 45, // Min, Max hitpoints + AI_FIREMAN, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 8, // Hit check frame #1 + 8, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 25, // Armor Class + MC_DEMON, // Monster Class + M_IF+M_IM, // Magic resist + M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1888 }, // Experience points + +// MT_FLAMLRD + { 128, 1460, // Image width, Image size + "Monsters\\Fireman\\FireM%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 14, 19, 20, 8, 14, 23 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Flame Lord", // Name + 42, 45, // Min, Max dungeon level + 18, // Monster level ranking (1 = easy, 30 = hardest) + 40, 55, // Min, Max hitpoints + AI_FIREMAN, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 8, // Hit check frame #1 + 10, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 25, // Armor Class + MC_DEMON, // Monster Class + M_IF+M_IM, // Magic resist + M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2250 }, // Experience points + +// MT_DOOMFIRE + { 128, 1460, // Image width, Image size + "Monsters\\Fireman\\FireM%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 14, 19, 20, 8, 14, 23 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Doom Fire", // Name + 44, 47, // Min, Max dungeon level + 20, // Monster level ranking (1 = easy, 30 = hardest) + 50, 65, // Min, Max hitpoints + AI_FIREMAN, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 8, // Hit check frame #1 + 12, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_IF+M_IM, // Magic resist + M_RL+M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2740 }, // Experience points + +// MT_HELLBURN + { 128, 1460, // Image width, Image size + "Monsters\\Fireman\\FireM%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 14, 19, 20, 8, 14, 23 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hell Burner", // Name + 46, 47, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 60, 80, // Min, Max hitpoints + AI_FIREMAN, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 85, // Hit% #1 + 8, // Hit check frame #1 + 15, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_IF+M_IM, // Magic resist + M_RL+M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 3355 }, // Experience points + +// MT_STORM + { 160, 1740, // Image width, Image size + "Monsters\\Thin\\Thin%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Thin\\Thinv3.TRN", // Trans file?, Transformation file name + { 8, 8, 18, 4, 17, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Red Storm", // Name + 17, 21, // Min, Max dungeon level + 18, // Monster level ranking (1 = easy, 30 = hardest) + 55, 110, // Min, Max hitpoints + AI_STORM, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 5, // Hit check frame #1 + 8, 18, // Min, Max damage #1 + 75, // Hit% #2 + 8, // Hit check frame #2 + 4, 16, // Min, Max damage #2 + 30, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_IM, // Magic resist + M_IM+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2160 }, // Experience points + +// MT_RSTORM + { 160, 1740, // Image width, Image size + "Monsters\\Thin\\Thin%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 8, 8, 18, 4, 17, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Storm Rider", // Name + 19, 23, // Min, Max dungeon level + 20, // Monster level ranking (1 = easy, 30 = hardest) + 60, 120, // Min, Max hitpoints + AI_STORM, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 5, // Hit check frame #1 + 8, 18, // Min, Max damage #1 + 80, // Hit% #2 + 8, // Hit check frame #2 + 4, 16, // Min, Max damage #2 + 30, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IL, // Magic resist + M_IM+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2391 }, // Experience points + +// MT_STORML + { 160, 1740, // Image width, Image size + "Monsters\\Thin\\Thin%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Thin\\Thinv2.TRN", // Trans file?, Transformation file name + { 8, 8, 18, 4, 17, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Storm Lord", // Name + 21, 25, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 75, 135, // Min, Max hitpoints + AI_STORM, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 85, // Hit% #1 + 5, // Hit check frame #1 + 12, 24, // Min, Max damage #1 + 75, // Hit% #2 + 8, // Hit check frame #2 + 4, 16, // Min, Max damage #2 + 35, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IL, // Magic resist + M_IM+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2775 }, // Experience points + +// MT_MAEL + { 160, 1740, // Image width, Image size + "Monsters\\Thin\\Thin%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Thin\\Thin%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Thin\\Thinv1.TRN", // Trans file?, Transformation file name + { 8, 8, 18, 4, 17, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Maelstorm", // Name + 23, 27, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 90, 150, // Min, Max hitpoints + AI_STORM, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 90, // Hit% #1 + 5, // Hit check frame #1 + 12, 28, // Min, Max damage #1 + 75, // Hit% #2 + 8, // Hit check frame #2 + 4, 16, // Min, Max damage #2 + 40, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_II+M_IL, // Magic resist + M_IM+M_II+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3177 }, // Experience points + + // MT_BIGFALL + { 128, 800 /*1650*/, // Image width, Image size + "Monsters\\BigFall\\Fallg%c" CEL_EXT, // Image files + TRUE, // Special animation +// "Monsters\\BigFall\\Bfal%c%i.WAV", // Sound files + "Monsters\\newsfx\\KBrute%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 8, 11, 8, 17, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 2, 2 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Devil Kin Brute", // Name + 40, 43, // Min, Max dungeon level + 27, // Monster level ranking (1 = easy, 30 = hardest) + 120, 160, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 6, // Hit check frame #1 + 18, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_ANIMAL, // Monster Class + M_RF+M_RL, // Magic resist + M_RF+M_RL+M_RM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2400 }, // Experience points + + // MT_WINGED + { 160, 1650, // Image width, Image size + "Monsters\\Gargoyle\\Gargo%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Gargoyle\\Gargo%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 14, 14, 14, 10, 18, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 2 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Winged-Demon", // Name + 8, 12, // Min, Max dungeon level + 9, // Monster level ranking (1 = easy, 30 = hardest) + 45, 60, // Min, Max hitpoints + AI_GARG, + MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 7, // Hit check frame #1 + 10, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 45, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_II+M_IM, // Magic resist + M_IF+M_II+M_IM, // Magic resist2 + 0, // Treasure + MSEL_FLY, // Selection Type + 662 }, // Experience points + +// MT_GARGOYLE + { 160, 1650, // Image width, Image size + "Monsters\\Gargoyle\\Gargo%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Gargoyle\\Gargo%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Gargoyle\\GarE.TRN", // Trans file?, Transformation file name + { 14, 14, 14, 10, 18, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 2 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Gargoyle", // Name + 12, 16, // Min, Max dungeon level + 13, // Monster level ranking (1 = easy, 30 = hardest) + 60, 90, // Min, Max hitpoints + AI_GARG, + MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 65, // Hit% #1 + 7, // Hit check frame #1 + 10, 16, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 45, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_II+M_IM, // Magic resist + M_IL+M_II+M_IM, // Magic resist2 + 0, // Treasure + MSEL_FLY, // Selection Type + 1205 }, // Experience points + +// MT_BLOODCLW + { 160, 1650, // Image width, Image size + "Monsters\\Gargoyle\\Gargo%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Gargoyle\\Gargo%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Gargoyle\\GargBr.TRN", // Trans file?, Transformation file name + { 14, 14, 14, 10, 18, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Blood Claw", // Name + 16, 20, // Min, Max dungeon level + 19, // Monster level ranking (1 = easy, 30 = hardest) + 75, 125, // Min, Max hitpoints + AI_GARG, + MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 7, // Hit check frame #1 + 14, 22, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_DEMON, // Monster Class + M_II+M_IM+M_IF, // Magic resist + M_IF+M_RL+M_II+M_IM, // Magic resist2 + 0, // Treasure + MSEL_FLY, // Selection Type + 1873 }, // Experience points + +// MT_DEATHW + { 160, 1650, // Image width, Image size + "Monsters\\Gargoyle\\Gargo%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Gargoyle\\Gargo%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Gargoyle\\GargB.TRN", // Trans file?, Transformation file name + { 14, 14, 14, 10, 18, 14 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Death Wing", // Name + 18, 22, // Min, Max dungeon level + 23, // Monster level ranking (1 = easy, 30 = hardest) + 90, 150, // Min, Max hitpoints + AI_GARG, + MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 95, // Hit% #1 + 7, // Hit check frame #1 + 16, 28, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_II+M_IM+M_IL, // Magic resist + M_RF+M_IL+M_II+M_IM, // Magic resist2 + 0, // Treasure + MSEL_FLY, // Selection Type + 2278 }, // Experience points + +// MT_MEGA + { 160, 2220, // Image width, Image size + "Monsters\\Mega\\Mega%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mega\\Mega%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 6, 7, 14, 1, 24, 5 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 2, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Slayer", // Name + 19, 23, // Min, Max dungeon level + 20, // Monster level ranking (1 = easy, 30 = hardest) + 120, 140, // Min, Max hitpoints + AI_MEGA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 8, // Hit check frame #1 + 12, 20, // Min, Max damage #1 + 0, // Hit% #2 + 3, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IF, // Magic resist + M_RM+M_IF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2300 }, // Experience points + +// MT_GUARD + { 160, 2220, // Image width, Image size + "Monsters\\Mega\\Mega%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mega\\Mega%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Mega\\Guard.TRN", // Trans file?, Transformation file name + { 6, 7, 14, 1, 24, 5 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 2, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Guardian", // Name + 21, 25, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 140, 160, // Min, Max hitpoints + AI_MEGA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 110, // Hit% #1 + 8, // Hit check frame #1 + 14, 22, // Min, Max damage #1 + 0, // Hit% #2 + 3, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 65, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IF, // Magic resist + M_RM+M_IF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2714 }, // Experience points + +// MT_VTEXLRD + { 160, 2220, // Image width, Image size + "Monsters\\Mega\\Mega%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mega\\Mega%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Mega\\Vtexl.TRN", // Trans file?, Transformation file name + { 6, 7, 14, 1, 24, 5 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 2, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Vortex Lord", // Name + 23, 26, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 160, 180, // Min, Max hitpoints + AI_MEGA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 18, 24, // Min, Max damage #1 + 0, // Hit% #2 + 3, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IF+M_II, // Magic resist + M_RM+M_RL+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3252 }, // Experience points + +// MT_BALROG + { 160, 2220, // Image width, Image size + "Monsters\\Mega\\Mega%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mega\\Mega%c%i.WAV", // Sound files + TRUE, // Special sound + TRUE, "Monsters\\Mega\\Balr.TRN", // Trans file?, Transformation file name + { 6, 7, 14, 1, 24, 5 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 2, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Balrog", // Name + 25, 29, // Min, Max dungeon level + 26, // Monster level ranking (1 = easy, 30 = hardest) + 180, 200, // Min, Max hitpoints + AI_MEGA, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 130, // Hit% #1 + 8, // Hit check frame #1 + 22, 30, // Min, Max damage #1 + 0, // Hit% #2 + 3, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 75, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_IF+M_II, // Magic resist + M_RM+M_RL+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3643 }, // Experience points + +// MT_NSNAKE + { 160, 1270, // Image width, Image size + "Monsters\\Snake\\Snake%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Snake\\Snake%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 11, 13, 5, 18, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Cave Viper", // Name + 20, 24, // Min, Max dungeon level + 21, // Monster level ranking (1 = easy, 30 = hardest) + 100, 150, // Min, Max hitpoints + AI_SNAKE, + MFLAG_PATH, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 90, // Hit% #1 + 8, // Hit check frame #1 + 8, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_IM, // Magic resist + M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2725 }, // Experience points + +// MT_RSNAKE + { 160, 1270, // Image width, Image size + "Monsters\\Snake\\Snake%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Snake\\Snake%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Snake\\SnakR.TRN", // Trans file?, Transformation file name + { 12, 11, 13, 5, 18, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Fire Drake", // Name + 22, 26, // Min, Max dungeon level + 23, // Monster level ranking (1 = easy, 30 = hardest) + 120, 170, // Min, Max hitpoints + AI_SNAKE, + MFLAG_PATH, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 105, // Hit% #1 + 8, // Hit check frame #1 + 12, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 65, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_IM, // Magic resist + M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3139 }, // Experience points + +// MT_BSNAKE + { 160, 1270, // Image width, Image size + "Monsters\\Snake\\Snake%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Snake\\Snake%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Snake\\Snakg.TRN", // Trans file?, Transformation file name + { 12, 11, 13, 5, 18, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Gold Viper", // Name + 24, 27, // Min, Max dungeon level + 25, // Monster level ranking (1 = easy, 30 = hardest) + 140, 180, // Min, Max hitpoints + AI_SNAKE, + MFLAG_PATH, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 15, 26, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_IM, // Magic resist + M_RL+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3540 }, // Experience points + +// MT_GSNAKE + { 160, 1270, // Image width, Image size + "Monsters\\Snake\\Snake%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Snake\\Snake%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Snake\\Snakb.TRN", // Trans file?, Transformation file name + { 12, 11, 13, 5, 18, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 1, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Azure Drake", // Name + 28, 30, // Min, Max dungeon level + 27, // Monster level ranking (1 = easy, 30 = hardest) + 160, 200, // Min, Max hitpoints + AI_SNAKE, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 130, // Hit% #1 + 8, // Hit check frame #1 + 18, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 75, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_RL, // Magic resist + M_IL+M_RF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3791 }, // Experience points + +// MT_NBLACK + { 160, 2120, // Image width, Image size + "Monsters\\Black\\Black%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Black\\Black%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 8, 8, 16, 4, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Black Knight", // Name + 23, 27, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 150, 150, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 110, // Hit% #1 + 8, // Hit check frame #1 + 15, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 75, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_RM+M_II, // Magic resist + M_RM+M_IL+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3360 }, // Experience points + +// MT_RTBLACK + { 160, 2120, // Image width, Image size + "Monsters\\Black\\Black%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Black\\Black%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Black\\BlkKntRT.TRN", // Trans file?, Transformation file name + { 8, 8, 16, 4, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Doom Guard", // Name + 25, 29, // Min, Max dungeon level + 26, // Monster level ranking (1 = easy, 30 = hardest) + 165, 165, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 130, // Hit% #1 + 8, // Hit check frame #1 + 18, 25, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 75, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_RM+M_II, // Magic resist + M_RM+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3650 }, // Experience points + +// MT_BTBLACK + { 160, 2120, // Image width, Image size + "Monsters\\Black\\Black%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Black\\Black%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Black\\BlkKntBT.TRN", // Trans file?, Transformation file name + { 8, 8, 16, 4, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Steel Lord", // Name + 27, 30, // Min, Max dungeon level + 28, // Monster level ranking (1 = easy, 30 = hardest) + 180, 180, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 20, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 80, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_RM+M_IF+M_II, // Magic resist + M_RL+M_IM+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 4252 }, // Experience points + +// MT_RBLACK + { 160, 2120, // Image width, Image size + "Monsters\\Black\\Black%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Black\\Black%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Black\\BlkKntBe.TRN", // Trans file?, Transformation file name + { 8, 8, 16, 4, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Blood Knight", // Name + 24, 26, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 200, 200, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 130, // Hit% #1 + 8, // Hit check frame #1 + 25, 35, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 85, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_IL+M_II+M_IM, // Magic resist + M_RF+M_IL+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 5130 }, // Experience points + +// MT_UNRAV + { 96, 484, // Image width, Image size + "Monsters\\Unrav\\Unrav%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Shred%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 10, 12, 5, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "The Shredded", // Name + 32, 35, // Min, Max dungeon level + 23, // Monster level ranking (1 = easy, 30 = hardest) + 70, 90, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 7, // Hit check frame #1 + 4, 12, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 65, // Armor Class + MC_UNDEAD, // Monster Class + M_RF+M_RL+M_II, // Magic resist + M_RF+M_RL+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 900 }, // Experience points + +// MT_HOLOWONE + { 96, 484, // Image width, Image size + "Monsters\\Unrav\\Unrav%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 10, 12, 5, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hollow One", // Name + 34, 37, // Min, Max dungeon level + 27, // Monster level ranking (1 = easy, 30 = hardest) + 135, 240, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 7, // Hit check frame #1 + 12, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 75, // Armor Class + MC_UNDEAD, // Monster Class + M_RL+M_IM+M_IF+M_II, // Magic resist + M_RL+M_IM+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 4374 }, // Experience points + +// MT_PAINMSTR + { 96, 484, // Image width, Image size + "Monsters\\Unrav\\Unrav%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 10, 12, 5, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Pain Master", // Name + 36, 39, // Min, Max dungeon level + 29, // Monster level ranking (1 = easy, 30 = hardest) + 110, 200, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 7, // Hit check frame #1 + 16, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 80, // Armor Class + MC_UNDEAD, // Monster Class + M_RL+M_IM+M_IF+M_II, // Magic resist + M_RL+M_IM+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 5147 }, // Experience points + +// MT_REALWEAV + { 96, 484, // Image width, Image size + "Monsters\\Unrav\\Unrav%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Acid\\Acid%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 10, 12, 5, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Reality Weaver", // Name + 38, 39, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 135, 240, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 85, // Hit% #1 + 7, // Hit check frame #1 + 20, 35, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 85, // Armor Class + MC_UNDEAD, // Monster Class + M_RM+M_IL+M_IF+M_II, // Magic resist + M_RM+M_IL+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 5925 }, // Experience points + +// MT_SUCCUBUS + { 128, 980, // Image width, Image size + "Monsters\\Succ\\Scbs%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Succ\\Scbs%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 14, 8, 16, 7, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Succubus", // Name + 22, 26, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 120, 150, // Min, Max hitpoints + AI_SUCC, + MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 10, // Hit check frame #1 + 1, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_RM, // Magic resist + M_IM+M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 3696 }, // Experience points + +// MT_SNOWWICH + { 128, 980, // Image width, Image size + "Monsters\\Succ\\Scbs%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Succ\\Scbs%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Succ\\Succb.TRN", // Trans file?, Transformation file name + { 14, 8, 16, 7, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Snow Witch", // Name + 25, 28, // Min, Max dungeon level + 26, // Monster level ranking (1 = easy, 30 = hardest) + 135, 175, // Min, Max hitpoints + AI_SUCC, + MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 110, // Hit% #1 + 10, // Hit check frame #1 + 1, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 65, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_II, // Magic resist + M_IM+M_II+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 4084 }, // Experience points + +// MT_HLSPWN + { 128, 980, // Image width, Image size + "Monsters\\Succ\\Scbs%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Succ\\Scbs%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Succ\\Succrw.TRN", // Trans file?, Transformation file name + { 14, 8, 16, 7, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hell Spawn", // Name + 27, 30, // Min, Max dungeon level + 28, // Monster level ranking (1 = easy, 30 = hardest) + 150, 200, // Min, Max hitpoints + AI_SUCC, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 115, // Hit% #1 + 10, // Hit check frame #1 + 1, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 75, // Armor Class + MC_ANIMAL, // Monster Class + M_RM+M_IL, // Magic resist + M_IM+M_IF+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 4480 }, // Experience points + +// MT_SOLBRNR + { 128, 980, // Image width, Image size + "Monsters\\Succ\\Scbs%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\Succ\\Scbs%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Succ\\Succbw.TRN", // Trans file?, Transformation file name + { 14, 8, 16, 7, 24, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Soul Burner", // Name + 28, 30, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 140, 225, // Min, Max hitpoints + AI_SUCC, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 10, // Hit check frame #1 + 1, 35, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 85, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_RL+M_IF, // Magic resist + M_IM+M_IL+M_IF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 4644 }, // Experience points + +// MT_COUNSLR + { 128, 2000, // Image width, Image size + "Monsters\\Mage\\Mage%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mage\\Mage%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 1, 20, 8, 28, 20 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Counselor", // Name + 24, 26, // Min, Max dungeon level + 25, // Monster level ranking (1 = easy, 30 = hardest) + 70, 70, // Min, Max hitpoints + AI_COUNSLR, + MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 90, // Hit% #1 + 8, // Hit check frame #1 + 8, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_RL+M_RF, // Magic resist + M_RM+M_RL+M_RF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 4070 }, // Experience points + +// MT_MAGISTR + { 128, 2000, // Image width, Image size + "Monsters\\Mage\\Mage%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mage\\Mage%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Mage\\Cnselg.TRN", // Trans file?, Transformation file name + { 12, 1, 20, 8, 28, 20 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Magistrate", // Name + 26, 28, // Min, Max dungeon level + 27, // Monster level ranking (1 = easy, 30 = hardest) + 85, 85, // Min, Max hitpoints + AI_COUNSLR, + MFLAG_CHECKDOORS, // ai related flags + 1, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 8, // Hit check frame #1 + 10, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_RL+M_II+M_IF,// Magic resist + M_IM+M_RL+M_II+M_IF,// Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 4478 }, // Experience points + +// MT_CABALIST + { 128, 2000, // Image width, Image size + "Monsters\\Mage\\Mage%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mage\\Mage%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Mage\\Cnselgd.TRN", // Trans file?, Transformation file name + { 12, 1, 20, 8, 28, 20 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Cabalist", // Name + 28, 30, // Min, Max dungeon level + 29, // Monster level ranking (1 = easy, 30 = hardest) + 120, 120, // Min, Max hitpoints + AI_COUNSLR, + MFLAG_CHECKDOORS, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 110, // Hit% #1 + 8, // Hit check frame #1 + 14, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_RF+M_II+M_IL, // Magic resist + M_IM+M_RF+M_II+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 4929 }, // Experience points + +// MT_ADVOCATE + { 128, 2000, // Image width, Image size + "Monsters\\Mage\\Mage%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Mage\\Mage%c%i.WAV", // Sound files + FALSE, // Special sound + TRUE, "Monsters\\Mage\\Cnselbk.TRN", // Trans file?, Transformation file name + { 12, 1, 20, 8, 28, 20 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Advocate", // Name + 30, 30, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 145, 145, // Min, Max hitpoints + AI_COUNSLR, + MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 15, 25, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 0, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_IL+M_II+M_IM, // Magic resist + M_IM+M_IL+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 4968 }, // Experience points + +// MT_GOLEM + { 96, 386, // Image width, Image size + "Monsters\\Golem\\Golem%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Golem\\Golm%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 0, 16, 12, 0, 12, 20 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Golem", // Name + 0, 0, // Min, Max dungeon level + 12, // Monster level ranking (1 = easy, 30 = hardest) + 1, 1, // Min, Max hitpoints (calc in SPAWNGOLUM) + AI_GOLUM, // AI type + MFLAG_CHECKDOORS, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 0, // Hit% #1 (calc in SPAWNGOLUM) + 7, // Hit check frame #1 + 1, 1, // Min, Max damage #1 (calc in SPAWNGOLUM) + //0, 0, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 1, // Armor Class (calc in SPAWNGOLUM) + MC_DEMON, // Monster Class + 0, // Magic resist + 0, // Magic resist2 + 0, // Treasure + MSEL_NONE, // Selection Type + 0 }, // Experience points + +// MT_DIABLO + { 160, 2000, // Image width, Image size + "Monsters\\Diablo\\Diablo%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\Diablo\\Diablo%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 16, 6, 16, 2, 16, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "The Dark Lord", // Name + 50, 50, // Min, Max dungeon level + 45, // Monster level ranking (1 = easy, 30 = hardest) + 3333, 3333, // Min, Max hitpoints + AI_DIABLO, + MFLAG_KNOCKBACK|MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 220, // Hit% #1 + 4, // Hit check frame #1 + 30, 60, // Min, Max damage #1 + 0, // Hit% #2 + 11, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 90, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_RL+M_IM+M_II, // Magic resist + M_RF+M_RL+M_IM+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 31666 }, // Experience points + +// MT_DARKMAGE + { 128, 1060, // Image width, Image size + "Monsters\\DarkMage\\Dmage%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\DarkMage\\Dmag%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 6, 1, 21, 6, 23, 18 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "The Arch-Litch Malignus", // Name + 40, 41 /*24, 24*/, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 160, 160, // Min, Max hitpoints + AI_COUNSLR, + MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 20, 40, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_DEMON, // Monster Class + M_RM+M_RL+M_RF+M_II, // Magic resist + M_IM+M_IL+M_IF+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 4968 }, // Experience points + +//---------------------// +// New Monsters // +//---------------------// + +// Festering Nest + + { 188, 800 /*1250*/, // Image width, Image size + "Monsters\\Fork\\Fork%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\HBoar%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 10, 15, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hellboar", // Name + 32, 35, // Min, Max dungeon level + 23, // Monster level ranking (1 = easy, 30 = hardest) + 80, 100, // Min, Max hitpoints + AI_SKELSD, // eventually AI_RHINO? + MFLAG_PATH|MFLAG_KNOCKBACK, // ai related flags + 2, // Intelligence (0 = easiest, 3 = hardest of type) + 70, // Hit% #1 + 7, // Hit check frame #1 + 16, 24, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_DEMON, // Monster Class + M_NONE, // Magic resist + M_RL+M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 750}, // Experience points + + { 64, 305, // Image width, Image size + "Monsters\\Scorp\\Scorp%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Stingr%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 10, 12, 6, 15, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Stinger", // Name + 32, 35, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 30, 40, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 85, // Hit% #1 + 8, // Hit check frame #1 + 1, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RL, // Magic resist2 + 0, // Treasure + MSEL_FLR, // Selection Type + 500}, // Experience points + + { 156, 800 /*1156*/, // Image width, Image size + "Monsters\\Eye\\Eye%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\psyco%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 13, 13, 7, 21, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Psychorb", // Name + 32, 35, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 20, 30, // Min, Max hitpoints + AI_PSYCHORB, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 8, // Hit check frame #1 + 10, 10, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 40, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_FLY, // Selection Type + 450}, // Experience points + + { 148, 800/*1000*/, // Image width, Image size + "Monsters\\Spider\\Spider%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\SLord%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 10, 15, 6, 20, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Arachnon", // Name + 32, 35, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 60, 80, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 50, // Hit% #1 + 8, // Hit check frame #1 + 5, 15, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 500}, // Experience points + + { 128, 800/*2000*/, // Image width, Image size + "Monsters\\TSneak\\TSneak%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\FTwin%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 13, 13, 15, 11, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Felltwin", // Name + 32, 35, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 50, 70, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 70, // Hit% #1 + 8, // Hit check frame #1 + 10, 18, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_DEMON, // Monster Class + M_II, // Magic resist + M_RF+M_RL+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 600}, // Experience points + + { 164, 520, // Image width, Image size + "Monsters\\Spawn\\Spawn%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\HSpawn%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 15, 12, 14, 11, 14, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hork Spawn", // Name + 34, 37, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 30, 30, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 10, 25, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 25, // Armor Class + MC_DEMON, // Monster Class + M_RM, // Magic resist + M_RM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 250}, // Experience points + + { 86, 305, // Image width, Image size + "Monsters\\WScorp\\WScorp%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Stingr%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 10, 12, 6, 15, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Venomtail", // Name + 36, 39, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 40, 50, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 85, // Hit% #1 + 8, // Hit check frame #1 + 1, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_ANIMAL, // Monster Class + M_RL, // Magic resist + M_IL, // Magic resist2 + 0, // Treasure + MSEL_FLR, // Selection Type + 1000}, // Experience points + + { 140, 800 /*1200*/, // Image width, Image size + "Monsters\\Eye2\\Eye2%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Psyco%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 13, 13, 7, 21, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Necromorb",// Name + 36, 39, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 30, 40, // Min, Max hitpoints + AI_NECROMORB, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 8, // Hit check frame #1 + 20, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_ANIMAL, // Monster Class + M_RF, // Magic resist + M_RL+M_IF, // Magic resist2 + 0, // Treasure + MSEL_FLY, // Selection Type + 1100}, // Experience points + + { 148, 800/*1100*/, // Image width, Image size + "Monsters\\bSpidr\\bSpidr%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\SLord%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 10, 15, 6, 20, 10 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Spider Lord", // Name + 36, 39, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 80, 100, // Min, Max hitpoints + AI_ACID, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 8, 20, // Min, Max damage #1 + 75, // Hit% #2 + 8, // Hit check frame #2 + 10, 10, // Min, Max damage #2 + 60, // Armor Class + MC_ANIMAL, // Monster Class + M_RL, // Magic resist + M_RF+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1250}, // Experience points + + { 176, 800 /* 1700 */, // Image width, Image size + "Monsters\\Clasp\\Clasp%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Lworm%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 12, 15, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Lashworm", // Name + 36, 39, // Min, Max dungeon level + 20, // Monster level ranking (1 = easy, 30 = hardest) + 30, 30, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 90, // Hit% #1 + 8, // Hit check frame #1 + 12, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 50, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 600}, // Experience points + + { 192, 800 /*1080*/, // Image width, Image size + "Monsters\\AntWorm\\Worm%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\TchAnt%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 14, 12, 12, 6, 20, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Torchant", // Name + 36, 39, // Min, Max dungeon level + 22, // Monster level ranking (1 = easy, 30 = hardest) + 60, 80, // Min, Max hitpoints + AI_HELLBAT, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 8, // Hit check frame #1 + 20, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_ANIMAL, // Monster Class + M_IF, // Magic resist + M_RL+M_RM+M_IF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 1250}, // Experience points + + { 138, 800/*2000*/, // Image width, Image size + "Monsters\\HorkD\\HorkD%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\HDemon%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 15, 8, 16, 6, 16, 9 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 2 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hork Demon", // Name + 36, 37, // Min, Max dungeon level + 27, // Monster level ranking (1 = easy, 30 = hardest) + 120, 160, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 60, // Hit% #1 + 8, // Hit check frame #1 + 20, 35, // Min, Max damage #1 + 80, // Hit% #2 + 8, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 80, // Armor Class + MC_DEMON, // Monster Class + M_RL, // Magic resist + M_RM+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2000}, // Experience points + + { 198, 800 /* 2000 */, // Image width, Image size + "Monsters\\Hellbug\\Hellbg%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\Defile%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 8, 8, 14, 6, 14, 12 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hell Bug", // Name + 38, 39, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 240, 240, // Min, Max hitpoints + AI_SKELSD, + MFLAG_PATH, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 110, // Hit% #1 + 8, // Hit check frame #1 + 20, 30, // Min, Max damage #1 + 90, // Hit% #2 + 8, // Hit check frame #2 + 50, 60, // Min, Max damage #2 + 80, // Armor Class + MC_DEMON, // Monster Class + M_RF+M_RM+M_IL, // Magic resist + M_RM+M_IF+M_IL, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 5000}, // Experience points + + +// Demon Crypt + + { 124, 800, // Image width, Image size + "Monsters\\Gravdg\\Gravdg%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\GDiggr%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 24, 24, 12, 6, 16, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Gravedigger", // Name + 40, 41, // Min, Max dungeon level + 26, // Monster level ranking (1 = easy, 30 = hardest) + 120, 240, // Min, Max hitpoints + AI_SCAV, + MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 80, // Hit% #1 + 6, // Hit check frame #1 + 2, 12, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 20, // Armor Class + MC_UNDEAD, // Monster Class + M_IL+M_II, // Magic resist + M_RF+M_RM+M_IL+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 2000}, // Experience points + + { 104, 550, // Image width, Image size + "Monsters\\Rat\\Rat%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\TmbRat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 11, 8, 12, 6, 20, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Tomb Rat", // Name + 40, 43, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 80, 120, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 12, 25, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 30, // Armor Class + MC_ANIMAL, // Monster Class + M_NONE, // Magic resist + M_RF+M_RL, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 1800}, // Experience points + + { 96, 550, // Image width, Image size + "Monsters\\Hellbat\\Helbat%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\HelBat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 18, 16, 14, 6, 18, 11}, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0}, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Firebat", // Name + 40, 43, // Min, Max dungeon level + 24, // Monster level ranking (1 = easy, 30 = hardest) + 60, 80, // Min, Max hitpoints + AI_FIREBAT, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 8, // Hit check frame #1 + 15, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_ANIMAL, // Monster Class + M_IF, // Magic resist + M_RL+M_RM+M_IF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 2400}, // Experience points + + { 128, 1740, // Image width, Image size + "Monsters\\Demskel\\Demskl%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\SWing%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, "Monsters\\Thin\\Thinv3.TRN", // Trans file?, Transformation file name + { 10, 8, 20, 6, 24, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Skullwing", // Name + 40, 43, // Min, Max dungeon level + 27, // Monster level ranking (1 = easy, 30 = hardest) + 70, 70, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 75, // Hit% #1 + 7, // Hit check frame #1 + 15, 20, // Min, Max damage #1 + 75, // Hit% #2 + 9, // Hit check frame #2 + 15, 20, // Min, Max damage #2 + 80, // Armor Class + MC_UNDEAD, // Monster Class + M_RF+M_RL+M_II, // Magic resist + M_RF+M_RL+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3000 }, // Experience points + + { 96, 800 /*1109*/, // Image width, Image size + "Monsters\\Lich\\Lich%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Lich%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 10, 10, 7, 21, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 2, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Lich", // Name + 40, 43, // Min, Max dungeon level + 25, // Monster level ranking (1 = easy, 30 = hardest) + 80, 100, // Min, Max hitpoints + AI_LICH, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 8, // Hit check frame #1 + 15, 20, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 60, // Armor Class + MC_UNDEAD, // Monster Class + M_RL+M_II, // Magic resist + M_RF+M_RM+M_IL+M_II, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 3000}, // Experience points + + { 154, 800 /* 1100 */, // Image width, Image size + "Monsters\\Bubba\\Bubba%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Crypt%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 8, 18, 12, 8, 21, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Crypt Demon", // Name + 42, 45, // Min, Max dungeon level + 28, // Monster level ranking (1 = easy, 30 = hardest) + 200, 240, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 8, // Hit check frame #1 + 20, 40, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 85, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_RF+M_IM, // Magic resist + M_RL+M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 3200}, // Experience points + + { 96, 550, // Image width, Image size + "Monsters\\Hellbat2\\bhelbt%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\HelBat%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 18, 16, 14, 6, 18, 11 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Hellbat", // Name + 44, 47, // Min, Max dungeon level + 29, // Monster level ranking (1 = easy, 30 = hardest) + 100, 140, // Min, Max hitpoints + AI_HELLBAT, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 110, // Hit% #1 + 8, // Hit check frame #1 + 30, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 80, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_RM+M_IF, // Magic resist + M_IL+M_RM+M_IF, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 3600}, // Experience points + + { 128, 1740, // Image width, Image size + "Monsters\\Demskel\\Demskl%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\SWing%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, "Monsters\\Thin\\Thinv3.TRN", // Trans file?, Transformation file name + { 10, 8, 20, 6, 24, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 3, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Bone Demon", // Name + 44, 47, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 240, 280, // Min, Max hitpoints + AI_BONED, + 0, // ai related flags + 0, // Intelligence (0 = easiest, 3 = hardest of type) + 100, // Hit% #1 + 8, // Hit check frame #1 + 40, 50, // Min, Max damage #1 + 160, // Hit% #2 + 12, // Hit check frame #2 + 50, 50, // Min, Max damage #2 + 50, // Armor Class + MC_UNDEAD, // Monster Class + M_IF+M_IL+M_II, // Magic resist + M_IF+M_IL+M_II, // Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 5000 }, // Experience points + + { 136, 800 /*1109*/, // Image width, Image size + "Monsters\\Lich2\\Lich2%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Lich%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 10, 10, 7, 21, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 2, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Arch Lich", // Name + 44, 47, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 180, 200, // Min, Max hitpoints + AI_ARCHLICH, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 30, 30, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 75, // Armor Class + MC_UNDEAD, // Monster Class + M_RF+M_RM+M_IL+M_II,// Magic resist + M_IF+M_IM+M_IL+M_II,// Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 4000}, // Experience points + + { 180, 800 /*1000*/, // Image width, Image size + "Monsters\\Byclps\\Byclps%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Biclop%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 10, 11, 16, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 2, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Biclops", // Name + 44, 47, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 200, 240, // Min, Max hitpoints + AI_SKELSD, + MFLAG_KNOCKBACK|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 90, // Hit% #1 + 8, // Hit check frame #1 + 40, 50, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 80, // Armor Class + MC_DEMON, // Monster Class + M_RL, // Magic resist + M_RL+M_RF, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 4000}, // Experience points + + { 164, 800 /* 1700 */, // Image width, Image size + "Monsters\\Flesh\\Flesh%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\FleshT%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 15, 24, 15, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Flesh Thing", // Name + 44, 47, // Min, Max dungeon level + 28, // Monster level ranking (1 = easy, 30 = hardest) + 300, 400, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 150, // Hit% #1 + 8, // Hit check frame #1 + 12, 18, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 70, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_RF+M_RM, // Magic resist + M_RL+M_RF+M_RM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 4000}, // Experience points + + { 180, 800 /* 1600 */, // Image width, Image size + "Monsters\\Reaper\\Reap%c" CEL_EXT, // Image files + FALSE, // Special animation + "Monsters\\newsfx\\Reaper%c%i.WAV", // Sound files + FALSE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 12, 10, 14, 6, 16, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 2, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Reaper", // Name + 44, 47, // Min, Max dungeon level + 30, // Monster level ranking (1 = easy, 30 = hardest) + 260, 300, // Min, Max hitpoints + AI_SKELSD, + 0, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 120, // Hit% #1 + 8, // Hit check frame #1 + 30, 35, // Min, Max damage #1 + 0, // Hit% #2 + 0, // Hit check frame #2 + 0, 0, // Min, Max damage #2 + 90, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_IF+M_IM, // Magic resist + M_IL+M_IF+M_IM, // Magic resist2 + 0, // Treasure + MSEL_REG, // Selection Type + 6000}, // Experience points + + { 226, 1200/* 2100 */, // Image width, Image size + "Monsters\\Nkr\\Nkr%c" CEL_EXT, // Image files + TRUE, // Special animation + "Monsters\\newsfx\\Nakrul%c%i.WAV", // Sound files + TRUE, // Special sound + FALSE, NULL, // Trans file?, Transformation file name + { 2, 6, 16, 3, 16, 16 }, // Neutral, Walk, Attack, Get Hit, Death, Special (# frames) + { 0, 0, 0, 0, 0, 0 }, // Neutral, Walk, Attack, Get Hit, Death, Special (anim delays) + "Na-Krul", // Name + 60, 60, // Min, Max dungeon level + 40, // Monster level ranking (1 = easy, 30 = hardest) + 1332, 1332, // Min, Max hitpoints + AI_SKELSD, + MFLAG_KNOCKBACK|MFLAG_PATH|MFLAG_CHECKDOORS, // ai related flags + 3, // Intelligence (0 = easiest, 3 = hardest of type) + 150, // Hit% #1 + 7, // Hit check frame #1 + 40, 50, // Min, Max damage #1 + 150, // Hit% #2 + 10, // Hit check frame #2 + 40, 50, // Min, Max damage #2 + 125, // Armor Class + MC_DEMON, // Monster Class + M_RL+M_IF+M_IM+M_II,// Magic resist + M_IL+M_IF+M_IM+M_II,// Magic resist2 + 0, // Treasure + MSEL_BIG, // Selection Type + 13333}, // Experience points + +}; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +int MonstConvTbl[] = { + + MT_NZOMBIE, + MT_BZOMBIE, + MT_GZOMBIE, + MT_YZOMBIE, + + MT_RFALLSP, + MT_DFALLSP, + MT_YFALLSP, + MT_BFALLSP, + + MT_WSKELAX, + MT_TSKELAX, + MT_RSKELAX, + MT_XSKELAX, + + MT_RFALLSD, + MT_DFALLSD, + MT_YFALLSD, + MT_BFALLSD, + + MT_NSCAV, + MT_BSCAV, + MT_WSCAV, + MT_YSCAV, + + MT_WSKELBW, + MT_TSKELBW, + MT_RSKELBW, + MT_XSKELBW, + + MT_WSKELSD, + MT_TSKELSD, + MT_RSKELSD, + MT_XSKELSD, + + //MT_INVILORD, + + MT_SNEAK, + MT_STALKER, + MT_UNSEEN, + MT_ILLWEAV, + + //MT_LRDSAYTR, + + MT_NGOATMC, + MT_BGOATMC, + MT_RGOATMC, + MT_GGOATMC, + + MT_FIEND, + MT_GLOOM, + MT_BLINK, + MT_FAMILIAR, + + MT_NGOATBW, + MT_BGOATBW, + MT_RGOATBW, + MT_GGOATBW, + + MT_NACID, + MT_RACID, + MT_BACID, + MT_XACID, + + MT_SKING, + MT_FAT, + MT_MUDMAN, + MT_TOAD, + MT_FLAYED, + + MT_WYRM, + MT_CAVSLUG, + MT_DEVOUR, + MT_DVLWYRM, + + MT_NMAGMA, + MT_YMAGMA, + MT_BMAGMA, + MT_WMAGMA, + MT_HORNED, + MT_MUDRUN, + MT_FROSTC, + MT_OBLORD, + MT_BONEDMN, + MT_REDDTH, + MT_LTCHDMN, + MT_UDEDBLRG, + + 0, + 0, + 0, + 0, + + MT_INCIN, + MT_FLAMLRD, + MT_DOOMFIRE, + MT_HELLBURN, + + 0, + 0, + 0, + 0, + + MT_RSTORM, + MT_STORM, + MT_STORML, + MT_MAEL, + + MT_WINGED, + MT_GARGOYLE, + MT_BLOODCLW, + MT_DEATHW, + MT_MEGA, + MT_GUARD, + MT_VTEXLRD, + MT_BALROG, + MT_NSNAKE, + MT_RSNAKE, + + MT_GSNAKE, + MT_BSNAKE, + + MT_NBLACK, + MT_RTBLACK, + MT_BTBLACK, + MT_RBLACK, + MT_UNRAV, + MT_HOLOWONE, + MT_PAINMSTR, + MT_REALWEAV, + MT_SUCCUBUS, + MT_SNOWWICH, + MT_HLSPWN, + MT_SOLBRNR, + MT_COUNSLR, + MT_MAGISTR, + MT_CABALIST, + MT_ADVOCATE, + + 0, + MT_DIABLO, + 0, + MT_GOLEM, + 0, //BlackWound + 0, //SinWar + 0, + 0, //Lazarus + 0, //Warlord + 0, //FleshDoom + 0, //Snotspil + 0, //Temptress + 0, //Lachdanan + MT_BIGFALL, + MT_DARKMAGE, + + + MT_FORK, + MT_SCORP, + MT_EYE, + MT_SPIDER, + MT_FELLTWIN, + MT_SPAWN, + MT_SCORP, + MT_EYE, + MT_SPIDER, + MT_LASH, + MT_ANT, + MT_HORKD, + MT_BUG, + + MT_GRAVDG, + MT_RAT, + MT_HELLBAT, + MT_BONED, + MT_LICH, + MT_BUBBA, + MT_HELLBAT, + MT_BONED, + MT_LICH, + MT_BYCLPS, + MT_FLESH, + MT_REAPER, + MT_NKR, +}; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +int MonstAvailTbl[] = { + MAT_SW, // MT_NZOMBIE + MAT_SW, // MT_BZOMBIE + MAT_SW, // MT_GZOMBIE + MAT_SW, // MT_YZOMBIE + + MAT_SW, // MT_RFALLSP + MAT_SW, // MT_DFALLSP + MAT_SW, // MT_YFALLSP + MAT_SW, // MT_BFALLSP + + MAT_SW, // MT_WSKELAX + MAT_SW, // MT_TSKELAX + MAT_SW, // MT_RSKELAX + MAT_SW, // MT_XSKELAX + + MAT_SW, // MT_RFALLSD + MAT_SW, // MT_DFALLSD + MAT_SW, // MT_YFALLSD + MAT_SW, // MT_BFALLSD + + MAT_SW, // MT_NSCAV + MAT_SW, // MT_BSCAV + MAT_SW, // MT_WSCAV + MAT_SW, // MT_YSCAV + + MAT_SW, // MT_WSKELBW + MAT_SW, // MT_TSKELBW + MAT_SW, // MT_RSKELBW + MAT_SW, // MT_XSKELBW + + MAT_SW, // MT_WSKELSD + MAT_SW, // MT_TSKELSD + MAT_SW, // MT_RSKELSD + MAT_SW, // MT_XSKELSD + + MAT_NO, // MT_INVILORD 8/15 + + MAT_YES, // MT_SNEAK + MAT_YES, // MT_STALKER + MAT_YES, // MT_UNSEEN + MAT_YES, // MT_ILLWEAV + + MAT_YES, // MT_LRDSAYTR 8/15 + + MAT_YES, // MT_NGOATMC + MAT_YES, // MT_BGOATMC + MAT_YES, // MT_RGOATMC + MAT_YES, // MT_GGOATMC + + MAT_SW, // MT_FIEND + MAT_SW, // MT_BLINK + MAT_SW, // MT_GLOOM + MAT_SW, // MT_FAMILIAR + + MAT_YES, // MT_NGOATBW + MAT_YES, // MT_BGOATBW + MAT_YES, // MT_RGOATBW + MAT_YES, // MT_GGOATBW + + MAT_YES, // MT_NACID + MAT_YES, // MT_RACID + MAT_YES, // MT_BACID + MAT_YES, // MT_XACID + + MAT_NO, // MT_SKING + + MAT_NO, // MT_CLEAVER + + MAT_YES, // MT_FAT + MAT_YES, // MT_MUDMAN + MAT_YES, // MT_TOAD + MAT_YES, // MT_FLAYED + + MAT_NO, // MT_WYRM + MAT_NO, // MT_CAVSLUG + MAT_NO, // MT_DVLWYRM + MAT_NO, // MT_DEVOUR + + MAT_YES, // MT_NMAGMA + MAT_YES, // MT_YMAGMA + MAT_YES, // MT_BMAGMA + MAT_YES, // MT_WMAGMA + + MAT_YES, // MT_HORNED + MAT_YES, // MT_MUDRUN + MAT_YES, // MT_FROSTC + MAT_YES, // MT_OBLORD + + MAT_NO, // MT_BONEDMN 8/15 + MAT_NO, // MT_REDDTH + MAT_NO, // MT_LTCHDMN + MAT_NO, // MT_UDEDBLRG + + MAT_NO, // MT_INCIN 8/15 + MAT_NO, // MT_FLAMLRD 8/15 + MAT_NO, // MT_DOOMFIRE 8/15 + MAT_NO, // MT_HELLBURN 8/15 + + MAT_YES, // MT_STORM + MAT_YES, // MT_RSTORM + MAT_YES, // MT_STORML + MAT_YES, // MT_MAEL + + MAT_YES, // MT_BIGFALL 8/15 + + MAT_YES, // MT_WINGED + MAT_YES, // MT_GARGOYLE + MAT_YES, // MT_BLOODCLW + MAT_YES, // MT_DEATHW + + MAT_YES, // MT_MEGA + MAT_YES, // MT_GUARD + MAT_YES, // MT_VTEXLRD + MAT_YES, // MT_BALROG + + MAT_YES, // MT_NSNAKE + MAT_YES, // MT_RSNAKE + MAT_YES, // MT_BSNAKE + MAT_YES, // MT_GSNAKE + + MAT_YES, // MT_NBLACK + MAT_YES, // MT_RTBLACK + MAT_YES, // MT_BTBLACK + MAT_YES, // MT_RBLACK + + MAT_YES, // MT_UNRAV + MAT_NO, // MT_HOLOWONE + MAT_NO, // MT_PAINMSTR + MAT_NO, // MT_REALWEAV + + MAT_YES, // MT_SUCCUBUS + MAT_YES, // MT_SNOWICH + MAT_YES, // MT_HLSPWN + MAT_YES, // MT_SOLBURNR + + MAT_YES, // MT_COUNSLR + MAT_YES, // MT_MAGISTR + MAT_YES, // MT_CABALIST + MAT_YES, // MT_ADVOCATE + + MAT_NO, // MT_GOLEM + + MAT_NO, // MT_DIABLO + + MAT_NO, // MT_DARKMAGE 8/15 + + MAT_YES, // MT_FORK + MAT_YES, // MT_SCORP + MAT_YES, // MT_EYE + MAT_YES, // MT_SPIDER + MAT_YES, // MT_INVILORD + MAT_YES, // MT_SPAWN + MAT_YES, // MT_SCORP2 + MAT_YES, // MT_EYE2 + MAT_YES, // MT_SPIDER2 + MAT_YES, // MT_LASH + MAT_YES, // MT_ANT + MAT_NO, // MT_HORKD + MAT_NO, // MT_BUG + + MAT_YES, // MT_GRAVDG + MAT_YES, // MT_RAT + MAT_YES, // MT_HELLBAT + MAT_YES, // MT_BONED + MAT_YES, // MT_LICH + MAT_YES, // MT_BUBBA + MAT_YES, // MT_HELLBAT2 + MAT_YES, // MT_BONED2 + MAT_YES, // MT_LICH2 + MAT_YES, // MT_BYCLPS + MAT_YES, // MT_FLESH + MAT_YES, // MT_REAPER + MAT_NO, // MT_NKR +}; + +UniqMonstStruct UniqMonst[] = +{ +#if IS_VERSION(RETAIL) + // The first few are quest monsters and must go in this order for indexing + { + MT_NGOATMC, // i.e. MT_SKELSD + "Gharbad the Weak", // Monster Name + "BSDB", // Translation filename + 4, // level on which it appears + 120, // Hit Points + AI_GARBUD, // AI type + 3, // AI level + 8, // min damage + 16, // max damage + M_IL+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_GARB1 // Talking monster message number + }, + + { + MT_SKING, // i.e. MT_SKELSD + "Skeleton King", // Monster Name + "GENRL", // Translation filename + 0, // level on which it appears + 240, // Hit Points + AI_SKELKING, // AI type + 3, // AI level + 6, // min damage + 16, // max damage + M_RF+M_RL+M_IM+M_II, // Magic resistance + UN_PACK, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_COUNSLR, // i.e. MT_SKELSD *** Has to be the first level 8 monster loaded *** + "Zhar the Mad", // Monster Name + "GENERAL", // Translation filename + 8, // level on which it appears + 360, // Hit Points + AI_ZHAR, // AI type + 3, // AI level + 16, // min damage + 40, // max damage + M_RF+M_RL+M_IM, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_ZHAR1 // Talking monster message number + }, + + { + MT_BFALLSP, // i.e. MT_SKELSD + "Snotspill", // Monster Name + "BNG", // Translation filename + 4, // level on which it appears + 220, // Hit Points + AI_SNOTSPIL, // AI type + 3, // AI level + 10, // min damage + 18, // max damage + M_RL, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_BOL1 // Talking monster message number + }, + + { + MT_ADVOCATE, // i.e. MT_SKELSD + "Arch-Bishop Lazarus", // Monster Name + "GENERAL", // Translation filename + 0, // level on which it appears + 600, // Hit Points + AI_LAZURUS, // AI type + 3, // AI level + 30, // min damage + 50, // max damage + M_RF+M_RL+M_IM+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_VB1 // Talking monster message number + }, + + { + MT_HLSPWN, // i.e. MT_SKELSD + "Red Vex", // Monster Name + "REDV", // Translation filename + 0, // level on which it appears + 400, // Hit Points + AI_LAZHELP, // AI type + 3, // AI level + 30, // min damage + 50, // max damage + M_RF+M_IM+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_VB1 // Talking monster message number + }, + + { + MT_HLSPWN, // i.e. MT_SKELSD + "BlackJade", // Monster Name + "BLKJD", // Translation filename + 0, // level on which it appears + 400, // Hit Points + AI_LAZHELP, // AI type + 3, // AI level + 30, // min damage + 50, // max damage + M_RL+M_IM+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_VB1 // Talking monster message number + }, + + { + MT_RBLACK, // i.e. MT_SKELSD + "Lachdanan", // Monster Name + "BHKA", // Translation filename + 14, // level on which it appears + 500, // Hit Points + AI_LACHDANAN, // AI type + 3, // AI level + 0, // min damage + 0, // max damage + 0, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_VEIL1 // Talking monster message number + }, + + { + MT_BTBLACK, // i.e. MT_SKELSD + "Warlord of Blood", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 850, // Hit Points + AI_WARLORD, // AI type + 3, // AI level + 35, // min damage + 50, // max damage + M_IF+M_IL+M_IM+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + TXT_WARLRD1 // Talking monster message number + }, + + { + MT_CLEAVER, // i.e. MT_SKELSD + "The Butcher", // Monster Name + "GENRL", // Translation filename + 0, // level on which it appears + 220, // Hit Points + AI_CLEAVER, // AI type + 3, // AI level + 6, // min damage + 12, // max damage + M_RF+M_RL+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_HORKD, // i.e. MT_SKELSD + "Hork Demon", // Monster Name + "GENRL", // Translation filename + 19, // level on which it appears + 300, // Hit Points + AI_HORKDEMON, // AI type + 3, // AI level + 20, // min damage + 35, // max damage + M_RL, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BUG, // i.e. MT_SKELSD + "The Defiler", // Monster Name + "GENRL", // Translation filename + 20, // level on which it appears + 480, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 30, // min damage + 40, // max damage + M_RF+M_RM+M_IL, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NKR, // i.e. MT_SKELSD + "Na-Krul", // Monster Name + "GENRL", // Translation filename + 0, // level on which it appears + 1332, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 40, // min damage + 50, // max damage + M_IL+M_IF+M_IM+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + // From here down are random unique monsters + { + MT_TSKELAX, // i.e. MT_SKELSD + "Bonehead Keenaxe", // Monster Name + "BHKA", // Translation filename + 2, // level on which it appears + 91, // Hit Points + AI_SKELSD, // AI type + 2, // AI level + 4, // min damage + 10, // max damage + M_II+M_IM, // Magic resistance + UN_L|UN_H, // Unique attributes, i.e., pack leader + 100, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RFALLSD, // i.e. MT_SKELSD + "Bladeskin the Slasher",// Monster Name + "BSTS", // Translation filename + 2, // level on which it appears + 51, // Hit Points + AI_FALLEN, // AI type + 0, // AI level + 6, // min damage + 18, // max damage + M_RF, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 45, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NZOMBIE, // i.e. MT_SKELSD + "Soulpus", // Monster Name + "GENERAL", // Translation filename + 2, // level on which it appears + 133, // Hit Points + AI_ZOMBIE, // AI type + 0, // AI level + 4, // min damage + 8, // max damage + M_RF+M_RL, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RFALLSP, // i.e. MT_SKELSD + "Pukerat the Unclean", // Monster Name + "PTU", // Translation filename + 2, // level on which it appears + 77, // Hit Points + AI_FALLEN, // AI type + 3, // AI level + 1, // min damage + 5, // max damage + M_RF, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_WSKELAX, // i.e. MT_SKELSD + "Boneripper", // Monster Name + "BR", // Translation filename + 2, // level on which it appears + 54, // Hit Points + AI_BAT, // AI type + 0, // AI level + 6, // min damage + 15, // max damage + M_IF+M_II+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NZOMBIE, // i.e. MT_SKELSD + "Rotfeast the Hungry", // Monster Name + "ETH", // Translation filename + 2, // level on which it appears + 85, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 4, // min damage + 12, // max damage + M_II+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_DFALLSD, // i.e. MT_SKELSD + "Gutshank the Quick", // Monster Name + "GTQ", // Translation filename + 3, // level on which it appears + 66, // Hit Points + AI_BAT, // AI type + 2, // AI level + 6, // min damage + 16, // max damage + M_RF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_TSKELSD, // i.e. MT_SKELSD + "Brokenhead Bangshield", // Monster Name + "BHBS", // Translation filename + 3, // level on which it appears + 108, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 12, // min damage + 20, // max damage + M_RL+M_II+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_YFALLSP, // i.e. MT_SKELSD + "Bongo", // Monster Name + "BNG", // Translation filename + 3, // level on which it appears + 178, // Hit Points + AI_FALLEN, // AI type + 3, // AI level + 9, // min damage + 21, // max damage + M_NONE, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BZOMBIE, // i.e. MT_SKELSD + "Rotcarnage", // Monster Name + "RCRN", // Translation filename + 3, // level on which it appears + 102, // Hit Points + AI_ZOMBIE, // AI type + 3, // AI level + 9, // min damage + 24, // max damage + M_RL+M_II+M_IM, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 45, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NSCAV, // i.e. MT_SKELSD + "Shadowbite", // Monster Name + "SHBT", // Translation filename + 2, // level on which it appears + 60, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 3, // min damage + 20, // max damage + M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_WSKELBW, // i.e. MT_SKELSD + "Deadeye", // Monster Name + "DE", // Translation filename + 2, // level on which it appears + 49, // Hit Points + AI_GOATBOW, // AI type + 0, // AI level + 6, // min damage + 9, // max damage + M_RF+M_II+M_IM, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RSKELAX, // i.e. MT_SKELSD + "Madeye the Dead", // Monster Name + "MTD", // Translation filename + 4, // level on which it appears + 75, // Hit Points + AI_BAT, // AI type + 0, // AI level + 9, // min damage + 21, // max damage + M_IF+M_IM, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 30, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BSCAV, // i.e. MT_SKELSD + "El Chupacabras", // Monster Name + "GENERAL", // Translation filename + 3, // level on which it appears + 120, // Hit Points + AI_GOATMC, // AI type + 0, // AI level + 10, // min damage + 18, // max damage + M_RF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 30, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_TSKELBW, // i.e. MT_SKELSD + "Skullfire", // Monster Name + "SKFR", // Translation filename + 3, // level on which it appears + 125, // Hit Points + AI_GOATBOW, // AI type + 1, // AI level + 6, // min damage + 10, // max damage + M_IF, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 100, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_SNEAK, // i.e. MT_SKELSD + "Warpskull", // Monster Name + "TSPO", // Translation filename + 3, // level on which it appears + 117, // Hit Points + AI_SNEAK, // AI type + 2, // AI level + 6, // min damage + 18, // max damage + M_RF+M_RL, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_GZOMBIE, // i.e. MT_SKELSD + "Goretongue", // Monster Name + "PMR", // Translation filename + 3, // level on which it appears + 156, // Hit Points + AI_SKELSD, // AI type + 1, // AI level + 15, // min damage + 30, // max damage + M_II+M_IM, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_WSCAV, // i.e. MT_SKELSD + "Pulsecrawler", // Monster Name + "BHKA", // Translation filename + 4, // level on which it appears + 150, // Hit Points + AI_SCAV, // AI type + 0, // AI level + 16, // min damage + 20, // max damage + M_RL+M_IF, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 45, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BLINK, // i.e. MT_SKELSD + "Moonbender", // Monster Name + "GENERAL", // Translation filename + 4, // level on which it appears + 135, // Hit Points + AI_BAT, // AI type + 0, // AI level + 9, // min damage + 27, // max damage + M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BLINK, // i.e. MT_SKELSD + "Wrathraven", // Monster Name + "GENERAL", // Translation filename + 5, // level on which it appears + 135, // Hit Points + AI_BAT, // AI type + 2, // AI level + 9, // min damage + 22, // max damage + M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_YSCAV, // i.e. MT_SKELSD + "Spineeater", // Monster Name + "GENERAL", // Translation filename + 4, // level on which it appears + 180, // Hit Points + AI_SCAV, // AI type + 1, // AI level + 18, // min damage + 25, // max damage + M_IL+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RSKELBW, // i.e. MT_SKELSD + "Blackash the Burning", // Monster Name + "BASHTB", // Translation filename + 4, // level on which it appears + 120, // Hit Points + AI_GOATBOW, // AI type + 0, // AI level + 6, // min damage + 16, // max damage + M_IF+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BFALLSD, // i.e. MT_SKELSD + "Shadowcrow", // Monster Name + "GENERAL", // Translation filename + 5, // level on which it appears + 270, // Hit Points + AI_SNEAK, // AI type + 2, // AI level + 12, // min damage + 25, // max damage + M_NONE, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_LRDSAYTR, // i.e. MT_SKELSD + "Blightstone the Weak", // Monster Name + "BHKA", // Translation filename + 4, // level on which it appears + 360, // Hit Points + AI_SKELSD, // AI type + 0, // AI level + 4, // min damage + 12, // max damage + M_RL+M_IM, // Magic resistance + UN_L|UN_H, // Unique attributes, i.e., pack leader + 70, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_FAT, // i.e. MT_SKELSD + "Bilefroth the Pit Master", // Monster Name + "BFTP", // Translation filename + 6, // level on which it appears + 210, // Hit Points + AI_BAT, // AI type + 1, // AI level + 16, // min damage + 23, // max damage + M_RL+M_IM+M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NGOATBW, // i.e. MT_SKELSD + "Bloodskin Darkbow", // Monster Name + "BSDB", // Translation filename + 5, // level on which it appears + 207, // Hit Points + AI_GOATBOW, // AI type + 0, // AI level + 3, // min damage + 16, // max damage + M_RF+M_RL, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 55, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_GLOOM, // i.e. MT_SKELSD + "Foulwing", // Monster Name + "DB", // Translation filename + 5, // level on which it appears + 246, // Hit Points + AI_RHINO, // AI type + 3, // AI level + 12, // min damage + 28, // max damage + M_RF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_XSKELSD, // i.e. MT_SKELSD + "Shadowdrinker", // Monster Name + "SHDR", // Translation filename + 5, // level on which it appears + 300, // Hit Points + AI_SNEAK, // AI type + 1, // AI level + 18, // min damage + 26, // max damage + M_RF+M_RL+M_II+M_IM, // Magic resistance + UN_A, // Unique attributes, i.e., pack leader + 45, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_UNSEEN, // i.e. MT_SKELSD + "Hazeshifter", // Monster Name + "BHKA", // Translation filename + 5, // level on which it appears + 285, // Hit Points + AI_SNEAK, // AI type + 3, // AI level + 18, // min damage + 30, // max damage + M_IL+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NACID, // i.e. MT_SKELSD + "Deathspit", // Monster Name + "BFDS", // Translation filename + 6, // level on which it appears + 303, // Hit Points + AI_ACIDUNIQ, // AI type + 0, // AI level + 12, // min damage + 32, // max damage + M_RL+M_RF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RGOATMC, // i.e. MT_SKELSD + "Bloodgutter", // Monster Name + "BGBL", // Translation filename + 6, // level on which it appears + 315, // Hit Points + AI_BAT, // AI type + 1, // AI level + 24, // min damage + 34, // max damage + M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BGOATMC, // i.e. MT_SKELSD + "Deathshade Fleshmaul", // Monster Name + "DSFM", // Translation filename + 6, // level on which it appears + 276, // Hit Points + AI_RHINO, // AI type + 0, // AI level + 12, // min damage + 24, // max damage + M_RF+M_IM, // Magic resistance + UN_A, // Unique attributes, i.e., pack leader + 65, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_WYRM, // i.e. MT_SKELSD + "Warmaggot the Mad", // Monster Name + "GENERAL", // Translation filename + 6, // level on which it appears + 246, // Hit Points + AI_BAT, // AI type + 3, // AI level + 15, // min damage + 30, // max damage + M_RL, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_STORM, // i.e. MT_SKELSD + "Glasskull the Jagged", // Monster Name + "BHKA", // Translation filename + 7, // level on which it appears + 354, // Hit Points + AI_STORM, // AI type + 0, // AI level + 18, // min damage + 30, // max damage + M_IM+M_II+M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RGOATBW, // i.e. MT_SKELSD + "Blightfire", // Monster Name + "BLF", // Translation filename + 7, // level on which it appears + 321, // Hit Points + AI_SUCC, // AI type + 2, // AI level + 13, // min damage + 21, // max damage + M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_GARGOYLE, // i.e. MT_SKELSD + "Nightwing the Cold", // Monster Name + "GENERAL", // Translation filename + 7, // level on which it appears + 342, // Hit Points + AI_BAT, // AI type + 1, // AI level + 18, // min damage + 26, // max damage + M_RL+M_IM+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_GGOATBW, // i.e. MT_SKELSD + "Gorestone", // Monster Name + "GENERAL", // Translation filename + 7, // level on which it appears + 303, // Hit Points + AI_GOATBOW, // AI type + 1, // AI level + 15, // min damage + 28, // max damage + M_RL+M_II, // Magic resistance + UN_L|UN_H, // Unique attributes, i.e., pack leader + 70, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BMAGMA, // i.e. MT_SKELSD + "Bronzefist Firestone", // Monster Name + "GENERAL", // Translation filename + 8, // level on which it appears + 360, // Hit Points + AI_MAGMA, // AI type + 0, // AI level + 30, // min damage + 36, // max damage + M_RF+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_INCIN, // i.e. MT_SKELSD + "Wrathfire the Doomed", // Monster Name + "WFTD", // Translation filename + 8, // level on which it appears + 270, // Hit Points + AI_SKELSD, // AI type + 2, // AI level + 20, // min damage + 30, // max damage + M_RF+M_RL+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NMAGMA, // i.e. MT_SKELSD + "Firewound the Grim", // Monster Name + "BHKA", // Translation filename + 8, // level on which it appears + 303, // Hit Points + AI_MAGMA, // AI type + 0, // AI level + 18, // min damage + 22, // max damage + M_RF+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_MUDMAN, // i.e. MT_SKELSD + "Baron Sludge", // Monster Name + "BSM", // Translation filename + 8, // level on which it appears + 315, // Hit Points + AI_SNEAK, // AI type + 3, // AI level + 25, // min damage + 34, // max damage + M_RF+M_RL+M_IM+M_II, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 75, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_GGOATMC, // i.e. MT_SKELSD + "Blighthorn Steelmace", // Monster Name + "BHSM", // Translation filename + 7, // level on which it appears + 250, // Hit Points + AI_RHINO, // AI type + 0, // AI level + 20, // min damage + 28, // max damage + M_RL, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 45, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RACID, // i.e. MT_SKELSD + "Chaoshowler", // Monster Name + "GENERAL", // Translation filename + 8, // level on which it appears + 240, // Hit Points + AI_ACIDUNIQ, // AI type + 0, // AI level + 12, // min damage + 20, // max damage + 0, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_REDDTH, // i.e. MT_SKELSD + "Doomgrin the Rotting", // Monster Name + "GENERAL", // Translation filename + 8, // level on which it appears + 405, // Hit Points + AI_STORM, // AI type + 3, // AI level + 25, // min damage + 50, // max damage + M_RL+M_RF+M_IM+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_FLAMLRD, // i.e. MT_SKELSD + "Madburner", // Monster Name + "GENERAL", // Translation filename + 9, // level on which it appears + 270, // Hit Points + AI_STORM, // AI type + 0, // AI level + 20, // min damage + 40, // max damage + M_IF+M_IL+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_LTCHDMN, // i.e. MT_SKELSD + "Bonesaw the Litch", // Monster Name + "GENERAL", // Translation filename + 9, // level on which it appears + 495, // Hit Points + AI_STORM, // AI type + 2, // AI level + 30, // min damage + 55, // max damage + M_RF+M_RL+M_II+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_MUDRUN, // i.e. MT_SKELSD + "Breakspine", // Monster Name + "GENERAL", // Translation filename + 9, // level on which it appears + 351, // Hit Points + AI_RHINO, // AI type + 0, // AI level + 25, // min damage + 34, // max damage + M_RF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_REDDTH, // i.e. MT_SKELSD + "Devilskull Sharpbone", // Monster Name + "GENERAL", // Translation filename + 9, // level on which it appears + 444, // Hit Points + AI_STORM, // AI type + 1, // AI level + 25, // min damage + 40, // max damage + M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_STORM, // i.e. MT_SKELSD + "Brokenstorm", // Monster Name + "GENERAL", // Translation filename + 9, // level on which it appears + 411, // Hit Points + AI_STORM, // AI type + 2, // AI level + 25, // min damage + 36, // max damage + M_IL, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RSTORM, // i.e. MT_SKELSD + "Stormbane", // Monster Name + "GENERAL", // Translation filename + 9, // level on which it appears + 555, // Hit Points + AI_STORM, // AI type + 3, // AI level + 30, // min damage + 30, // max damage + M_IL, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_TOAD, // i.e. MT_SKELSD + "Oozedrool", // Monster Name + "GENERAL", // Translation filename + 9, // level on which it appears + 483, // Hit Points + AI_FAT, // AI type + 3, // AI level + 25, // min damage + 30, // max damage + M_RL, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BLOODCLW, // i.e. MT_SKELSD + "Goldblight of the Flame", // Monster Name + "GENERAL", // Translation filename + 10, // level on which it appears + 405, // Hit Points + AI_GARG, // AI type + 0, // AI level + 15, // min damage + 35, // max damage + M_IF+M_IM, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 80, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_OBLORD, // i.e. MT_SKELSD + "Blackstorm", // Monster Name + "GENERAL", // Translation filename + 10, // level on which it appears + 525, // Hit Points + AI_RHINO, // AI type + 3, // AI level + 20, // min damage + 40, // max damage + M_IL+M_IM, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 90, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RACID, // i.e. MT_SKELSD + "Plaguewrath", // Monster Name + "GENERAL", // Translation filename + 10, // level on which it appears + 450, // Hit Points + AI_ACIDUNIQ, // AI type + 2, // AI level + 20, // min damage + 30, // max damage + M_RF+M_IM+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RSTORM, // i.e. MT_SKELSD + "The Flayer", // Monster Name + "GENERAL", // Translation filename + 10, // level on which it appears + 501, // Hit Points + AI_STORM, // AI type + 1, // AI level + 20, // min damage + 35, // max damage + M_RF+M_RM+M_IL+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_FROSTC, // i.e. MT_SKELSD + "Bluehorn", // Monster Name + "GENERAL", // Translation filename + 11, // level on which it appears + 477, // Hit Points + AI_RHINO, // AI type + 1, // AI level + 25, // min damage + 30, // max damage + M_RF+M_IM, // Magic resistance + UN_L|UN_A, // Unique attributes, i.e., pack leader + 90, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_HELLBURN, // i.e. MT_SKELSD + "Warpfire Hellspawn", // Monster Name + "GENERAL", // Translation filename + 11, // level on which it appears + 525, // Hit Points + AI_FIREMAN, // AI type + 3, // AI level + 10, // min damage + 40, // max damage + M_RM+M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NSNAKE, // i.e. MT_SKELSD + "Fangspeir", // Monster Name + "GENERAL", // Translation filename + 11, // level on which it appears + 444, // Hit Points + AI_SKELSD, // AI type + 1, // AI level + 15, // min damage + 32, // max damage + M_IF+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_UDEDBLRG, // i.e. MT_SKELSD + "Festerskull", // Monster Name + "GENERAL", // Translation filename + 11, // level on which it appears + 600, // Hit Points + AI_STORM, // AI type + 2, // AI level + 15, // min damage + 30, // max damage + M_IM+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_NBLACK, // i.e. MT_SKELSD + "Lionskull the Bent", // Monster Name + "GENERAL", // Translation filename + 12, // level on which it appears + 525, // Hit Points + AI_SKELSD, // AI type + 2, // AI level + 25, // min damage + 25, // max damage + M_IM+M_IF+M_IL+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_COUNSLR, // i.e. MT_SKELSD + "Blacktongue", // Monster Name + "GENERAL", // Translation filename + 12, // level on which it appears + 360, // Hit Points + AI_COUNSLR, // AI type + 3, // AI level + 15, // min damage + 30, // max damage + M_RF+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_DEATHW, // i.e. MT_SKELSD + "Viletouch", // Monster Name + "GENERAL", // Translation filename + 12, // level on which it appears + 525, // Hit Points + AI_GARG, // AI type + 3, // AI level + 20, // min damage + 40, // max damage + M_IL+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RSNAKE, // i.e. MT_SKELSD + "Viperflame", // Monster Name + "GENERAL", // Translation filename + 12, // level on which it appears + 570, // Hit Points + AI_SKELSD, // AI type + 1, // AI level + 25, // min damage + 35, // max damage + M_RL+M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BSNAKE, // i.e. MT_SKELSD + "Fangskin", // Monster Name + "BHKA", // Translation filename + 14, // level on which it appears + 681, // Hit Points + AI_SKELSD, // AI type + 2, // AI level + 15, // min damage + 50, // max damage + M_RL+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_SUCCUBUS, // i.e. MT_SKELSD + "Witchfire the Unholy", // Monster Name + "GENERAL", // Translation filename + 12, // level on which it appears + 444, // Hit Points + AI_SUCC, // AI type + 3, // AI level + 10, // min damage + 20, // max damage + M_RL+M_IF+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BALROG, // i.e. MT_SKELSD + "Blackskull", // Monster Name + "BHKA", // Translation filename + 13, // level on which it appears + 750, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 25, // min damage + 40, // max damage + M_RL+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_UNRAV, // i.e. MT_SKELSD + "Soulslash", // Monster Name + "GENERAL", // Translation filename + 12, // level on which it appears + 450, // Hit Points + AI_SKELSD, // AI type + 0, // AI level + 25, // min damage + 25, // max damage + M_IM+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_VTEXLRD, // i.e. MT_SKELSD + "Windspawn", // Monster Name + "GENERAL", // Translation filename + 12, // level on which it appears + 711, // Hit Points + AI_SKELSD, // AI type + 1, // AI level + 35, // min damage + 40, // max damage + M_IF+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_GSNAKE, // i.e. MT_SKELSD + "Lord of the Pit", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 762, // Hit Points + AI_SKELSD, // AI type + 2, // AI level + 25, // min damage + 42, // max damage + M_RF+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RTBLACK, // i.e. MT_SKELSD + "Rustweaver", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 400, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 1, // min damage + 60, // max damage + M_IF+M_IL+M_IM+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_HOLOWONE, // i.e. MT_SKELSD + "Howlingire the Shade", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 450, // Hit Points + AI_SKELSD, // AI type + 2, // AI level + 40, // min damage + 75, // max damage + M_RF+M_RL, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_MAEL, // i.e. MT_SKELSD + "Doomcloud", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 612, // Hit Points + AI_STORM, // AI type + 1, // AI level + 1, // min damage + 60, // max damage + M_RF+M_IL, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_PAINMSTR, // i.e. MT_SKELSD + "Bloodmoon Soulfire", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 684, // Hit Points + AI_SKELSD, // AI type + 1, // AI level + 15, // min damage + 40, // max damage + M_RF+M_RL+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_SNOWWICH, // i.e. MT_SKELSD + "Witchmoon", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 310, // Hit Points + AI_SUCC, // AI type + 3, // AI level + 30, // min damage + 40, // max damage + M_RL, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_VTEXLRD, // i.e. MT_SKELSD + "Gorefeast", // Monster Name + "GENERAL", // Translation filename + 13, // level on which it appears + 771, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 20, // min damage + 55, // max damage + M_RF+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RTBLACK, // i.e. MT_SKELSD + "Graywar the Slayer", // Monster Name + "GENERAL", // Translation filename + 14, // level on which it appears + 672, // Hit Points + AI_SKELSD, // AI type + 1, // AI level + 30, // min damage + 50, // max damage + M_RL+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_MAGISTR, // i.e. MT_SKELSD + "Dreadjudge", // Monster Name + "GENERAL", // Translation filename + 14, // level on which it appears + 540, // Hit Points + AI_COUNSLR, // AI type + 1, // AI level + 30, // min damage + 40, // max damage + M_RF+M_RL+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_HLSPWN, // i.e. MT_SKELSD + "Stareye the Witch", // Monster Name + "GENERAL", // Translation filename + 14, // level on which it appears + 726, // Hit Points + AI_SUCC, // AI type + 2, // AI level + 30, // min damage + 50, // max damage + M_IF, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_BTBLACK, // i.e. MT_SKELSD + "Steelskull the Hunter", // Monster Name + "GENERAL", // Translation filename + 14, // level on which it appears + 831, // Hit Points + AI_SKELSD, // AI type + 3, // AI level + 40, // min damage + 50, // max damage + M_RL+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_RBLACK, // i.e. MT_SKELSD + "Sir Gorash", // Monster Name + "GENERAL", // Translation filename + 16, // level on which it appears + 1050, // Hit Points + AI_SKELSD, // AI type + 1, // AI level + 20, // min damage + 60, // max damage + M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_CABALIST, // i.e. MT_SKELSD + "The Vizier", // Monster Name + "GENERAL", // Translation filename + 15, // level on which it appears + 850, // Hit Points + AI_COUNSLR, // AI type + 2, // AI level + 25, // min damage + 40, // max damage + M_IF, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_REALWEAV, // i.e. MT_SKELSD + "Zamphir", // Monster Name + "GENERAL", // Translation filename + 15, // level on which it appears + 891, // Hit Points + AI_SKELSD, // AI type + 2, // AI level + 30, // min damage + 50, // max damage + M_RF+M_RL+M_II+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_HLSPWN, // i.e. MT_SKELSD + "Bloodlust", // Monster Name + "GENERAL", // Translation filename + 15, // level on which it appears + 825, // Hit Points + AI_SUCC, // AI type + 1, // AI level + 20, // min damage + 55, // max damage + M_IL+M_IM+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_HLSPWN, // i.e. MT_SKELSD + "Webwidow", // Monster Name + "GENERAL", // Translation filename + 16, // level on which it appears + 774, // Hit Points + AI_SUCC, // AI type + 1, // AI level + 20, // min damage + 50, // max damage + M_IF+M_IM+M_II, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_SOLBRNR, // i.e. MT_SKELSD + "Fleshdancer", // Monster Name + "GENERAL", // Translation filename + 16, // level on which it appears + 999, // Hit Points + AI_SUCC, // AI type + 3, // AI level + 30, // min damage + 50, // max damage + M_RF+M_II+M_IM, // Magic resistance + 0, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_OBLORD, // i.e. MT_SKELSD + "Grimspike", // Monster Name + "GENERAL", // Translation filename + 19, // level on which it appears + 534, // Hit Points + AI_SNEAK, // AI type + 1, // AI level + 25, // min damage + 40, // max damage + M_RF+M_II+M_IM, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, + + { + MT_STORML, // i.e. MT_SKELSD + "Doomlock", // Monster Name + "GENERAL", // Translation filename + 28, // level on which it appears + 534, // Hit Points + AI_SNEAK, // AI type + 1, // AI level + 35, // min damage + 55, // max damage + M_RF+M_RL+M_IM+M_II, // Magic resistance + UN_L, // Unique attributes, i.e., pack leader + 0, // parameter to unique attribute + 0, // " + 0 // Talking monster message number + }, +#endif + + { -1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0 } // Stopper + +}; + diff --git a/MONSTDAT.H b/MONSTDAT.H new file mode 100644 index 0000000..3698dec --- /dev/null +++ b/MONSTDAT.H @@ -0,0 +1,301 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/MONSTDAT.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +// Monster Type +#define MT_NZOMBIE 0 +#define MT_BZOMBIE 1 +#define MT_GZOMBIE 2 +#define MT_YZOMBIE 3 + +#define MT_RFALLSP 4 +#define MT_DFALLSP 5 +#define MT_YFALLSP 6 +#define MT_BFALLSP 7 + +#define MT_WSKELAX 8 +#define MT_TSKELAX 9 +#define MT_RSKELAX 10 +#define MT_XSKELAX 11 + +#define MT_RFALLSD 12 +#define MT_DFALLSD 13 +#define MT_YFALLSD 14 +#define MT_BFALLSD 15 + +#define MT_NSCAV 16 +#define MT_BSCAV 17 +#define MT_WSCAV 18 +#define MT_YSCAV 19 + +#define MT_WSKELBW 20 +#define MT_TSKELBW 21 +#define MT_RSKELBW 22 +#define MT_XSKELBW 23 + +#define MT_WSKELSD 24 +#define MT_TSKELSD 25 +#define MT_RSKELSD 26 +#define MT_XSKELSD 27 + +#define MT_INVILORD 28 + +#define MT_SNEAK 29 +#define MT_STALKER 30 +#define MT_UNSEEN 31 +#define MT_ILLWEAV 32 + +#define MT_LRDSAYTR 33 + +#define MT_NGOATMC 34 +#define MT_BGOATMC 35 +#define MT_RGOATMC 36 +#define MT_GGOATMC 37 + +#define MT_FIEND 38 +#define MT_BLINK 39 +#define MT_GLOOM 40 +#define MT_FAMILIAR 41 + +#define MT_NGOATBW 42 +#define MT_BGOATBW 43 +#define MT_RGOATBW 44 +#define MT_GGOATBW 45 + +#define MT_NACID 46 +#define MT_RACID 47 +#define MT_BACID 48 +#define MT_XACID 49 + +#define MT_SKING 50 + +#define MT_CLEAVER 51 + +#define MT_FAT 52 +#define MT_MUDMAN 53 +#define MT_TOAD 54 +#define MT_FLAYED 55 + +#define MT_WYRM 56 +#define MT_CAVSLUG 57 +#define MT_DVLWYRM 58 +#define MT_DEVOUR 59 + +#define MT_NMAGMA 60 +#define MT_YMAGMA 61 +#define MT_BMAGMA 62 +#define MT_WMAGMA 63 + +#define MT_HORNED 64 +#define MT_MUDRUN 65 +#define MT_FROSTC 66 +#define MT_OBLORD 67 + +#define MT_BONEDMN 68 +#define MT_REDDTH 69 +#define MT_LTCHDMN 70 +#define MT_UDEDBLRG 71 + +#define MT_INCIN 72 +#define MT_FLAMLRD 73 +#define MT_DOOMFIRE 74 +#define MT_HELLBURN 75 + +#define MT_STORM 76 +#define MT_RSTORM 77 +#define MT_STORML 78 +#define MT_MAEL 79 + +#define MT_BIGFALL 80 + +#define MT_WINGED 81 +#define MT_GARGOYLE 82 +#define MT_BLOODCLW 83 +#define MT_DEATHW 84 + +#define MT_MEGA 85 +#define MT_GUARD 86 +#define MT_VTEXLRD 87 +#define MT_BALROG 88 + +#define MT_NSNAKE 89 +#define MT_RSNAKE 90 +#define MT_BSNAKE 91 +#define MT_GSNAKE 92 + +#define MT_NBLACK 93 +#define MT_RTBLACK 94 +#define MT_BTBLACK 95 +#define MT_RBLACK 96 + +#define MT_UNRAV 97 +#define MT_HOLOWONE 98 +#define MT_PAINMSTR 99 +#define MT_REALWEAV 100 + +#define MT_SUCCUBUS 101 +#define MT_SNOWWICH 102 +#define MT_HLSPWN 103 +#define MT_SOLBRNR 104 + +#define MT_COUNSLR 105 +#define MT_MAGISTR 106 +#define MT_CABALIST 107 +#define MT_ADVOCATE 108 + +#define MT_GOLEM 109 + +#define MT_DIABLO 110 +#define MT_DARKMAGE 111 + +#define MT_FORK 112 +#define MT_SCORP 113 +#define MT_EYE 114 +#define MT_SPIDER 115 +#define MT_FELLTWIN 116 +#define MT_SPAWN 117 +#define MT_SCORP2 118 +#define MT_EYE2 119 +#define MT_SPIDER2 120 +#define MT_LASH 121 +#define MT_ANT 122 +#define MT_HORKD 123 +#define MT_BUG 124 + +#define MT_GRAVDG 125 +#define MT_RAT 126 +#define MT_HELLBAT 127 +#define MT_BONED 128 +#define MT_LICH 129 +#define MT_BUBBA 130 +#define MT_HELLBAT2 131 +#define MT_BONED2 132 +#define MT_LICH2 133 +#define MT_BYCLPS 134 +#define MT_FLESH 135 +#define MT_REAPER 136 +#define MT_NKR 137 + +#define LASTMT 138 + +// Temp unique monster identification +#define MU_GARBUD 0 +#define MU_SKELKING 1 +#define MU_ZHAR 2 +#define MU_SNOTSPIL 3 +#define MU_LAZARUS 4 +#define MU_REDVEX 5 +#define MU_BLKJADE 6 +#define MU_LACHDA 7 +#define MU_WARLORD 8 +#define MU_CLEAVER 9 +#define MU_HORKDEMON 10 +#define MU_DEFILER 11 +#define MU_NAKRUL 12 + +// Image data sizes +#define IMG_MAX 4000 + +// Unique Monster Attributes +#define UN_PACK 0x0001 // monster has pack surrounding him +#define UN_STICK 0x0002 // monster pack sticks near leader -- must be used w/UN_PACK +#define UN_H 0x0004 // modified hit points +#define UN_A 0x0008 // modified armor +#define UN_L (UN_PACK|UN_STICK) + +// Monster Classes +#define MC_UNDEAD 0 +#define MC_DEMON 1 +#define MC_ANIMAL 2 + +// Monster resists +#define M_NONE 0x0000 // No resist +#define M_RM 0x0001 // resist magic +#define M_RF 0x0002 // resist fire +#define M_RL 0x0004 // resist lightning +#define M_IM 0x0008 // immune to magic +#define M_IF 0x0010 // immune to fire +#define M_IL 0x0020 // immune to lightning +#define M_II 0x0040 // immune to infravision +#define M_IA 0x0080 // immune to acid + +#define T_U 0x8000 // Unique +#define T_NONE 0x4000 +//#define Unused 0x2000 +//#define Unused 0x1000 +#define T_MASK 0x0fff + +// Monster availability +#define MAT_NO 0 // Not available +#define MAT_SW 1 // Shareware + Normal +#define MAT_YES 2 // Normal only + + +#define AI_ZOMBIE 0 +#define AI_FAT 1 +#define AI_SKELSD 2 +#define AI_SKELBOW 3 +#define AI_SCAV 4 +#define AI_RHINO 5 +#define AI_GOATMC 6 +#define AI_GOATBOW 7 +#define AI_FALLEN 8 +#define AI_MAGMA 9 +#define AI_SKELKING 10 +#define AI_BAT 11 +#define AI_GARG 12 +#define AI_CLEAVER 13 +#define AI_SUCC 14 +#define AI_SNEAK 15 +#define AI_STORM 16 +#define AI_FIREMAN 17 +#define AI_GARBUD 18 +#define AI_ACID 19 +#define AI_ACIDUNIQ 20 +#define AI_GOLUM 21 +#define AI_ZHAR 22 +#define AI_SNOTSPIL 23 +#define AI_SNAKE 24 +#define AI_COUNSLR 25 +#define AI_MEGA 26 +#define AI_DIABLO 27 +#define AI_LAZURUS 28 +#define AI_LAZHELP 29 +#define AI_LACHDANAN 30 +#define AI_WARLORD 31 +#define AI_FIREBAT 32 +#define AI_HELLBAT 33 +#define AI_HORKDEMON 34 +#define AI_LICH 35 +#define AI_ARCHLICH 36 +#define AI_PSYCHORB 37 +#define AI_NECROMORB 38 +#define AI_BONED 39 +#define NUM_AI (1 + AI_BONED) + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern MonsterData monsterdata[]; +extern int MonstConvTbl[]; +extern int MonstAvailTbl[]; +extern UniqMonstStruct UniqMonst[]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ diff --git a/MONSTER.CPP b/MONSTER.CPP new file mode 100644 index 0000000..b16c2e0 --- /dev/null +++ b/MONSTER.CPP @@ -0,0 +1,7722 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Monsters file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MONSTER.CPP 3 1/23/97 7:22p Rseis $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "sound.h" +#include "debug.h" +#include "monster.h" +#include "monstdat.h" +#include "engine.h" +#include "gendung.h" +#include "lighting.h" +#include "items.h" +#include "itemdat.h" +#include "player.h" +#include "effects.h" +#include "dead.h" +#include "missiles.h" +#include "misdat.h" +#include "control.h" +#include "objects.h" +#include "objdat.h" +#include "path.h" +#include "quests.h" +#include "minitext.h" +#include "textdat.h" +#include "monstint.h" +#include "msg.h" +#include "inv.h" +#include "multi.h" +#include "trigs.h" +#include "themes.h" +#include "drlg_l4.h" +#include "towners.h" +#include "setmaps.h" +#include "palette.h" +#include "scrollrt.h" +#include "cursor.h" +#include "drlg_l1.h" +#include "spells.h" + + +/*-----------------------------------------------------------------------* +** Function Prototypes +**-----------------------------------------------------------------------*/ +BOOL LineClear(int x1, int y1, int x2, int y2); +int M_GetDir(int i); + +typedef BOOL (*CHECKFUNC)(int x, int y); +typedef BOOL (*CHECKFUNC1)(int arg1, int x, int y); +BOOL LineClearF(CHECKFUNC Clear, int x1, int y1, int x2, int y2); +BOOL LineClearF1(CHECKFUNC1 Clear, int arg, int x1, int y1, int x2, int y2); +BOOL CheckNoSolid(int x, int y); +BOOL PosOkMissile(int x, int y); +int M_SpawnSkel(int x, int y, int dir); +void M_Teleport(int i); +void PlaceGroup(int, int, BOOL, int); +void ClrAllMonsters(); +BOOL PosOkMonst2(int i, int x, int y); +BOOL PosOkMonst3(int i, int x, int y); +BOOL effect_is_playing(int nSFX); + +void SpawnMap(int x, int y); +void SpawnBear(int x, int y); + +extern const TextDataStruct alltext[]; + +//void DaveMonstMap(BOOL initupdate, int pnum); + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +MonsterStruct monster[MAXMONSTERS]; +long nummonsters; +int totalmonsters; + +// monstactive -- indexes into monster[] +int monstactive[MAXMONSTERS]; // [0..nummonsters-1] -- active monsters + // [nummonsters..MAXMONSTERS-1] -- available monsters + +int nummtypes = 0; +long monstimgtot; +int gfxflags; +int uniquetrans; // index to next available unique monster palette translation + +int mleveltypes[NUMLEVELS][MAX_LVLMTYPES]; + +long monstkills[MONSTERTYPES]; + +static char sgszInvalidMonstName[] = "Invalid Monster"; + +/*-----------------------------------------------------------------------* +** Defines +**-----------------------------------------------------------------------*/ +#define PACK_MEMBER 1 +#define PACK_NOMEMBER 2 + +#define INITMONSTRAD 15 // Initial vision radius for no monsters + +/*-----------------------------------------------------------------------* +** Macros +**-----------------------------------------------------------------------*/ +#define InBounds(x,y) (0 <= (y) && (y) < MAXDUNY && 0 <= (x) && (x) < MAXDUNX) +#define WALKMODE(m) ((m) == MM_WALK || (m) == MM_WALK2 || (m) == MM_WALK3) +#define Sign(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0) +#define Mod(val, x) ((val) < 0 ? (val)+(x) : (val) >= (x) ? (val)-(x) : (val)) + +/*-----------------------------------------------------------------------* +** File Variables +**-----------------------------------------------------------------------*/ +// I had to add this variable, because _mVar2 seems like +// it must have been trashed, since sound never came on again -- pjw +static BYTE sgbSaveSoundOn; + + // 16 32 64 +int MWVel[24][3] = { {0x100,0x200,0x400}, // 1 frame + {0x80,0x100,0x200}, // 2 frame + {0x55,0xaa,0x155}, // 3 frame + {0x40,0x80,0x100}, // 4 frame + {0x33,0x66,0xcc}, // 5 frame + {0x2a,0x55,0xaa}, // 6 frame + {0x24,0x49,0x92}, // 7 frame + {0x20,0x40,0x80}, // 8 frame + {0x1c,0x38,0x71}, // 9 frame + {0x1a,0x33,0x66}, // 10 frame + {0x17,0x2e,0x5d}, // 11 frame + {0x15,0x2a,0x55}, // 12 frame + {0x13,0x27,0x4e}, // 13 frame + {0x12,0x24,0x49}, // 14 frame + {0x11,0x22,0x44}, // 15 frame + {0x10,0x20,0x40}, // 16 frame + {0x0f,0x1e,0x3c}, // 17 frame + {0x0e,0x1c,0x39}, // 18 frame + {0x0d,0x1a,0x36}, // 19 frame + {0x0c,0x19,0x33}, // 20 frame + {0x0c,0x18,0x30}, // 21 frame + {0x0b,0x17,0x2e}, // 22 frame + {0x0b,0x16,0x2c}, // 23 frame + {0x0a,0x15,0x2a} }; // 24 frame + +// Muli-player monster multiplier % +/*int MPMM[4] = { 100, // 1 player + 150, // 2 player + 175, // 3 player + 200 }; // 4 player*/ + +CMonster Monsters[MAX_LVLMTYPES]; + +char animletter[] = "nwahds"; +int left[] = {7,0,1,2,3,4,5,6}; +int right[] = {1,2,3,4,5,6,7,0}; +int opposite[] = {4,5,6,7,0,1,2,3}; +int offset_x[] = {1,0,-1,-1,-1,0,1,1}; +int offset_y[] = {1,1,1,0,-1,-1,-1,0}; +static const int infront_x[] = { 1, 0,-1, -1, -1, 0, 1, 1}; +static const int infront_y[] = { 1, 1, 1, 0, -1, -1, -1, 0}; +int rnd5[] = { 5, 10, 15, 20 }; +int rnd10[] = { 10, 15, 20, 30 }; +int rnd20[] = { 20, 30, 40, 50 }; +int rnd60[] = { 60, 70, 80, 90 }; + + +void MAI_Zombie(int); +void MAI_Fat(int); +void MAI_SkelSd(int); +void MAI_SkelBow(int); +void MAI_Scav(int); +void MAI_Rhino(int); +void MAI_GoatMc(int); +void MAI_GoatBow(int); +void MAI_Fallen(int); +void MAI_Magma(int); +void MAI_SkelKing(int); +void MAI_Bat(int); +void MAI_Garg(int); +void MAI_Cleaver(int); +void MAI_Succ(int); +void MAI_Lich(int); +void MAI_ArchLich(int); +void MAI_Psychorb(int); +void MAI_Necromorb(int); +void MAI_Sneak(int); +void MAI_Storm(int); +void MAI_Fireman(int i); +void MAI_Garbud(int); +void MAI_Acid(int); +void MAI_AcidUniq(int); +void MAI_Golum(int); +void MAI_Zhar(int); +void MAI_SnotSpil(int); +void MAI_Snake(int); +void MAI_Counselor(int); +void MAI_Mega(int); +void MAI_Diablo(int); +void MAI_Lazurus(int); +void MAI_Lazhelp(int); +void MAI_Lachdanan(int); +void MAI_Warlord(int); +void MAI_Firebat(int); +void MAI_Hellbat(int); +void MAI_HorkDemon(int); +void MAI_BoneDemon(int); + +void (*AiProc[NUM_AI])(int) = +{ + MAI_Zombie, + MAI_Fat, + MAI_SkelSd, + MAI_SkelBow, + MAI_Scav, + MAI_Rhino, + MAI_GoatMc, + MAI_GoatBow, + MAI_Fallen, + MAI_Magma, + MAI_SkelKing, + MAI_Bat, + MAI_Garg, + MAI_Cleaver, + MAI_Succ, + MAI_Sneak, + MAI_Storm, + MAI_Fireman, + MAI_Garbud, + MAI_Acid, + MAI_AcidUniq, + MAI_Golum, + MAI_Zhar, + MAI_SnotSpil, + MAI_Snake, + MAI_Counselor, + MAI_Mega, + MAI_Diablo, + MAI_Lazurus, + MAI_Lazhelp, + MAI_Lachdanan, + MAI_Warlord, + MAI_Firebat, + MAI_Hellbat, + MAI_HorkDemon, + MAI_Lich, + MAI_ArchLich, + MAI_Psychorb, + MAI_Necromorb, + MAI_BoneDemon, +}; + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void TranslateMonsterGFX(int monst, BOOL HasSpecial) +{ + app_assert((DWORD)monst < MAX_LVLMTYPES); + BYTE * pData = Monsters[monst].pTrans; + + for (int n = 256; n--; ++pData) { + if (*pData == 255) + *pData = 0; + } + int const nf = HasSpecial ? 6 : 5; + for (int j = 0; j < nf; ++j) { + if ((j == 1) && (Monsters[monst].mtype >= MT_COUNSLR) && (Monsters[monst].mtype <= MT_ADVOCATE)) continue; + for (int i = 0; i < 8; ++i) + TranslateCels(Monsters[monst].Anims[j].Cels[i], Monsters[monst].pTrans, Monsters[monst].Anims[j].Frames); + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +#if 0 // UNUSED +static BOOL MonstTaken(int i) +{ + int lev; + BOOL found = FALSE; + int m; + int templvl; // JKE + +// Temp hack for monsters JKE 7/30 + templvl = currlevel; +// if (templvl > 20) templvl -= 8; +// else if (templvl > 16) templvl -= 4; + +// for(lev = 0; lev <= currlevel && !found; ++lev) // JKE + for(lev = 0; lev <= templvl && !found; ++lev) + { + for(m = 0; m < MAX_LVLMTYPES && mleveltypes[m] && !found; ++m) + found = ((i < mleveltypes[lev][m]-1) + && + !strcmp(monsterdata[i].filename, monsterdata[mleveltypes[lev][m]-1].filename)); + } + return found; +} +#endif // UNUSED + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitLevelMonsters() +{ + int i; + + nummtypes = 0; + monstimgtot = 0; + gfxflags = 0; + + for (i = 0; i < MAX_LVLMTYPES; ++i) + Monsters[i].mPlaceFlags = 0; + + ClrAllMonsters(); + nummonsters = 0; + totalmonsters = MAXMONSTERS; // this value gets further restricted later on + + // active monsters list + for (i = 0; i < MAXMONSTERS; ++i) { + monstactive[i] = i; + } + uniquetrans = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int AddMonsterType(int type, int placeflag) +{ + int i; + BOOL done = FALSE; + + // check if this type is already being loaded + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes && !done; ++i) + done = Monsters[i].mtype == type; + --i; + + if (!done) + { + i = nummtypes++; + Monsters[i].mtype = type; + monstimgtot += monsterdata[type].mImgSize; + InitMonsterGFX(i); + InitMonsterSND(i); + } + + Monsters[i].mPlaceFlags |= placeflag; + + return i; +} + +/*-----------------------------------------------------------------------* + * GetLevelMTypes() + * + * Pick the monsters types to be placed in this level +**-----------------------------------------------------------------------*/ + +void GetLevelMTypes() +{ + int typelist[MONSTERTYPES]; + int nt, i; + int tidx, mt; + int minl,maxl; + char mamask; + int templvl; // temp hack JKE + + #if IS_VERSION(SHAREWARE) + mamask = MAT_SW; + #else + mamask = MAT_SW | MAT_YES; + #endif + + // Certain monsters are required for certain levels + + AddMonsterType(MT_GOLEM, MPFLAG_DONT); + + if (currlevel == 16) { + AddMonsterType(MT_ADVOCATE, MPFLAG_SCATTER); + AddMonsterType(MT_RBLACK, MPFLAG_SCATTER); + AddMonsterType(MT_DIABLO, MPFLAG_DONT); + return; + } + + if (currlevel == HIVESTART + 1) + { + AddMonsterType(MT_SPAWN, MPFLAG_SCATTER); + } + if (currlevel == HIVESTART + 2) + { + AddMonsterType(MT_SPAWN, MPFLAG_SCATTER); + AddMonsterType(MT_HORKD, MPFLAG_UNIQ); + } + if (currlevel == HIVEEND) + { + AddMonsterType(MT_BUG, MPFLAG_UNIQ); + } + if (currlevel == NA_KRUL_LEVEL /*CRYPTEND*/) + { + AddMonsterType(MT_LICH2, MPFLAG_SCATTER); + AddMonsterType(MT_NKR, MPFLAG_DONT); + } + + // Set levels load their own monster types + if (!setlevel) + { + if (QuestStatus(Q_BUTCHER)) { + AddMonsterType(MT_CLEAVER, MPFLAG_DONT); + } + + if (QuestStatus(Q_GARBUD)) { + AddMonsterType(UniqMonst[MU_GARBUD].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_ZHAR)) { + AddMonsterType(UniqMonst[MU_ZHAR].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_LTBANNER)) { + AddMonsterType(UniqMonst[MU_SNOTSPIL].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_VEIL)) { + AddMonsterType(UniqMonst[MU_LACHDA].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_WARLORD)) { + AddMonsterType(UniqMonst[MU_WARLORD].mtype, MPFLAG_UNIQ); + } + + if (gbMaxPlayers != 1 && currlevel == quests[Q_SKELKING]._qlevel) { + AddMonsterType(MT_SKING, MPFLAG_UNIQ); + + // Skelking requires skeleton minions + int skeltypes[LASTMT]; + int numskeltypes = 0; + + for (i = MT_WSKELAX; i <= MT_XSKELSD; ++i) + { + if (IsSkel(i)) + { + minl = ((monsterdata[i].mMinDLvl * 15) / 30) + 1; + maxl = ((monsterdata[i].mMaxDLvl * 15) / 30) + 1; + if ((currlevel >= minl) && (currlevel <= maxl) && (MonstAvailTbl[i] & mamask)) + skeltypes[numskeltypes++] = i; + } + } + AddMonsterType(skeltypes[random(88,numskeltypes)], MPFLAG_SCATTER); + } + + // Pick general monsters + + // Make list of available monster types for this level +// Temp hack monster JKE + templvl = currlevel; +// if (templvl > 20) templvl -=8; +// else if (templvl > 16) templvl -= 4; + + nt = 0; + for (i = 0; i < LASTMT; ++i) { + minl = ((monsterdata[i].mMinDLvl * 15) / 30) + 1; + maxl = ((monsterdata[i].mMaxDLvl * 15) / 30) + 1; +// if ((currlevel >= minl) && (currlevel <= maxl) && (MonstAvailTbl[i] & mamask)) { +// typelist[nt] = i; +// ++nt; +// } + // use templvl to patch over current level + if ((templvl >= minl) && (templvl <= maxl) && (MonstAvailTbl[i] & mamask)) { + typelist[nt] = i; + ++nt; + } + } + + if (monstdebug) + { + for(i = 0; i < debugmonsttypes; ++i) + AddMonsterType(DebugMonsters[i], MPFLAG_SCATTER); + } + else + { + while ((nt > 0) && (nummtypes < MAX_LVLMTYPES) && (monstimgtot < IMG_MAX)) { + // prune excessively large monsters + for (i = 0; i < nt; ) + { + if (monsterdata[typelist[i]].mImgSize > IMG_MAX - monstimgtot) + typelist[i] = typelist[--nt]; + else + ++i; + } + + if (nt) + { + tidx = random(88, nt); + mt = typelist[tidx]; + AddMonsterType(mt, MPFLAG_SCATTER); + typelist[tidx] = typelist[--nt]; + } + } + } + } + else if (setlvlnum == SL_SKELKING) { + AddMonsterType(MT_SKING, MPFLAG_UNIQ); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitMonsterGFX (int monst) +{ + int anim; + long i; + char strBuff[256]; + int mtype; + BYTE *p; + + app_assert((DWORD)monst < MAX_LVLMTYPES); + mtype = Monsters[monst].mtype; + for(anim = 0; anim < MAX_ANIMTYPE; ++anim) + { + if((!(animletter[anim] == 's' && !monsterdata[mtype].has_special)) && monsterdata[mtype].Frames[anim] > 0) + { + sprintf(strBuff, monsterdata[mtype].filename, animletter[anim]); + app_assert(! Monsters[monst].Anims[anim].CMem); + Monsters[monst].Anims[anim].CMem = LoadFileInMemSig(strBuff,NULL,'MONS'); + p = Monsters[monst].Anims[anim].CMem; + if (Monsters[monst].mtype == MT_GOLEM && (animletter[anim] == 's' || animletter[anim] == 'd')) { + for(i=0; i<8; ++i) Monsters[monst].Anims[anim].Cels[i] = p; + } else { + for(i=0; i<8; ++i) Monsters[monst].Anims[anim].Cels[i] = p + *(DWORD *)(p + (i<<2)); + } + } + Monsters[monst].Anims[anim].Frames = monsterdata[mtype].Frames[anim]; + Monsters[monst].Anims[anim].Rate = monsterdata[mtype].Rate[anim]; + } + Monsters[monst].mAnimWidth = monsterdata[mtype].mAnimWidth; + Monsters[monst].mAnimWidth2 = (monsterdata[mtype].mAnimWidth - 64) >> 1; + Monsters[monst].mMinHP = monsterdata[mtype].mMinHP; + Monsters[monst].mMaxHP = monsterdata[mtype].mMaxHP; + Monsters[monst].has_special = monsterdata[mtype].has_special; + Monsters[monst].mAFNum = monsterdata[mtype].mAFNum; + Monsters[monst].MData = &monsterdata[mtype]; + if (monsterdata[mtype].transflag) { + Monsters[monst].pTrans = LoadFileInMemSig(monsterdata[mtype].TransFile,NULL,'MONS'); + TranslateMonsterGFX(monst, monsterdata[mtype].has_special); + DiabloFreePtr(Monsters[monst].pTrans); + } + if (EquivMonst(mtype, MT_NMAGMA) && ((gfxflags & 0x0001) == 0)) { + gfxflags |= 0x0001; + ILoadMissileGFX(MF_MAGBALL); + } + + if (EquivMonst(mtype, MT_STORM) && ((gfxflags & 0x0002) == 0)) { + gfxflags |= 0x0002; + ILoadMissileGFX(MF_THINLIGHT); + } + + if ((mtype == MT_SUCCUBUS) && ((gfxflags & 0x0004) == 0)) { + gfxflags |= 0x0004; +// ILoadMissileGFX(MF_FLARE); already used for Blood Star +// ILoadMissileGFX(MF_FLAREXP); + } + + if (EquivMonst(mtype, MT_INCIN) && ((gfxflags & 0x0008) == 0)) { + gfxflags |= 0x0008; + ILoadMissileGFX(MF_KRULL); + } + + if ((EquivMonst(mtype, MT_NACID) || mtype == MT_SPIDER2) && + ((gfxflags & 0x0010) == 0)) { + gfxflags |= 0x0010; + ILoadMissileGFX(MF_ACID); + ILoadMissileGFX(MF_ACIDSPLAT); + ILoadMissileGFX(MF_ACIDPUD); + } + + if ((mtype == MT_SNOWWICH) && ((gfxflags & 0x0020) == 0)) { + gfxflags |= 0x0020; + ILoadMissileGFX(MF_BFLARE); + ILoadMissileGFX(MF_BFLAREXP); + } + if ((mtype == MT_HLSPWN) && ((gfxflags & 0x0040) == 0)) { + gfxflags |= 0x0040; + ILoadMissileGFX(MF_DFLARE); + ILoadMissileGFX(MF_DFLAREXP); + } + if ((mtype == MT_SOLBRNR) && ((gfxflags & 0x0080) == 0)) { + gfxflags |= 0x0080; + ILoadMissileGFX(MF_CFLARE); + ILoadMissileGFX(MF_CFLAREXP); + } + + if ((mtype == MT_LICH) && ((gfxflags & 0x0100) == 0)) + { + gfxflags |= 0x0100; + ILoadMissileGFX(MF_ORANGEFLARE); + ILoadMissileGFX(MF_ORANGEEXPLOSION); + } + + if ((mtype == MT_LICH2) && ((gfxflags & 0x0200) == 0)) + { + gfxflags |= 0x0200; + ILoadMissileGFX(MF_YELLOWFLARE); + ILoadMissileGFX(MF_YELLOWEXPLOSION); + } + + if ((mtype == MT_EYE || mtype == MT_BONED2) && ((gfxflags & 0x0400) == 0)) + { + gfxflags |= 0x0400; + ILoadMissileGFX(MF_BLUE2FLARE); + } + + if ((mtype == MT_EYE2) && ((gfxflags & 0x0800) == 0)) + { + gfxflags |= 0x0800; + ILoadMissileGFX(MF_REDFLARE); + ILoadMissileGFX(MF_REDEXPLOSION); + } + + + if ((mtype == MT_EYE) && ((gfxflags & 0x1000) == 0)) + { + gfxflags |= 0x1000; + ILoadMissileGFX(MF_BLUEEXPLOSION); + } + + if ((mtype == MT_BONED2) && ((gfxflags & 0x2000) == 0)) + { + gfxflags |= 0x2000; + ILoadMissileGFX(MF_BLUE2EXPLOSION); + } + + + if (mtype == MT_DIABLO) + ILoadMissileGFX(MF_FIREPLAR); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void ClearMVars(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + monster[i]._mVar1 = 0; + monster[i]._mVar2 = 0; + monster[i]._mVar3 = 0; + monster[i]._mVar4 = 0; + monster[i]._mVar5 = 0; + monster[i]._mVar6 = 0; + monster[i]._mVar7 = 0; + monster[i]._mVar8 = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + + +void InitMonster(int i, int rd, int mtype, int x, int y) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert((DWORD)mtype < MAX_LVLMTYPES); + CMonster *monst = &Monsters[mtype]; + app_assert(monst->MData != NULL); + + monster[i]._mdir = rd; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + + monster[i]._mMTidx = mtype; + monster[i]._mmode = MM_STAND; + monster[i].mName = monst->MData->mName; + monster[i].MType = monst; + monster[i].MData = monst->MData; + monster[i]._mAnimData = monst->Anims[MA_STAND].Cels[rd]; + monster[i]._mAnimDelay = monst->Anims[MA_STAND].Rate; + monster[i]._mAnimCnt = random(88, monster[i]._mAnimDelay - 1); + monster[i]._mAnimLen = monst->Anims[MA_STAND].Frames; + monster[i]._mAnimFrame = random(88, monster[i]._mAnimLen - 1) + 1; + if (monst->mtype == MT_DIABLO) { +// monster[i]._mmaxhp = (random(88, 1666 - 1666 + 1) + 1666) << HP_SHIFT; + monster[i]._mmaxhp = (random(88, 3333 - 3333 + 1) + 3333) << HP_SHIFT; + } else { + monster[i]._mmaxhp = (random(88, monst->mMaxHP - monst->mMinHP + 1) + monst->mMinHP) << HP_SHIFT; + } +/* if (gbMaxPlayers != 1) + monster[i]._mmaxhp = (monster[i]._mmaxhp * MPMM[gbActivePlayers-1]) / 100; + else + monster[i]._mmaxhp = monster[i]._mmaxhp >> 1; + if (monster[i]._mmaxhp < (1 << HP_SHIFT)) monster[i]._mmaxhp = 1 << HP_SHIFT;*/ + if (gbMaxPlayers == 1) { + monster[i]._mmaxhp = monster[i]._mmaxhp >> 1; + if (monster[i]._mmaxhp < (1 << HP_SHIFT)) monster[i]._mmaxhp = 1 << HP_SHIFT; + } + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i]._mAi = monst->MData->mAi; + monster[i]._mint = monst->MData->mInt; + monster[i]._mgoal = MG_ATTACK; + monster[i]._mgoalvar1 = 0; + monster[i]._mgoalvar2 = 0; + monster[i]._mgoalvar3 = 0; + monster[i]._mgoalvar4 = 0; + monster[i]._pathcount = 0; + monster[i]._mDelFlag = FALSE; + monster[i]._uniqtype = 0; + monster[i]._msquelch = 0; + + monster[i].mlid = 0; + + monster[i]._mRndSeed = GetRndSeed(); + monster[i]._mAISeed = GetRndSeed(); + + monster[i].mWhoHit = 0; + + monster[i].mLevel = monst->MData->mLevel; + monster[i].mExp = monst->MData->mExp; + monster[i].mHit = monst->MData->mHit; + monster[i].mMinDamage = monst->MData->mMinDamage; + monster[i].mMaxDamage = monst->MData->mMaxDamage; + monster[i].mHit2 = monst->MData->mHit2; + monster[i].mMinDamage2 = monst->MData->mMinDamage2; + monster[i].mMaxDamage2 = monst->MData->mMaxDamage2; + monster[i].mArmorClass = monst->MData->mArmorClass; + monster[i].mMagicRes = monst->MData->mMagicRes; + monster[i].leader = 0; + monster[i].leaderflag = 0; + monster[i]._mFlags = monst->MData->mFlags; + monster[i].mtalkmsg = 0; + + if (monster[i]._mAi == AI_GARG) + { + monster[i]._mAnimData = monst->Anims[MA_SPECIAL].Cels[rd]; + monster[i]._mAnimFrame = 1; + monster[i]._mFlags |= MFLAG_STILL; + monster[i]._mmode = MM_SATTACK; + } + + if (gnDifficulty == D_NIGHTMARE) { + monster[i]._mmaxhp = (monster[i]._mmaxhp * 3) + (((gbMaxPlayers == 1) ? 50 : 100) << HP_SHIFT); + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mLevel += 15; + monster[i].mExp = (monster[i].mExp << 1) + 2000; + monster[i].mHit += 85; + monster[i].mMinDamage = (monster[i].mMinDamage * 2) + 4; + monster[i].mMaxDamage = (monster[i].mMaxDamage * 2) + 4; + monster[i].mHit2 += 85; + monster[i].mMinDamage2 = (monster[i].mMinDamage2 * 2) + 4; + monster[i].mMaxDamage2 = (monster[i].mMaxDamage2 * 2) + 4; + monster[i].mArmorClass += 50; + } + else if (gnDifficulty == D_HELL) { + monster[i]._mmaxhp = (monster[i]._mmaxhp * 4) + (((gbMaxPlayers == 1) ? 100 : 200) << HP_SHIFT); + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mLevel += 30; + monster[i].mExp = (monster[i].mExp << 2) + 4000; + monster[i].mHit += 120; + monster[i].mMinDamage = (monster[i].mMinDamage * 4) + 6; + monster[i].mMaxDamage = (monster[i].mMaxDamage * 4) + 6; + monster[i].mHit2 += 120; + monster[i].mMinDamage2 = (monster[i].mMinDamage2 * 4) + 6; + monster[i].mMaxDamage2 = (monster[i].mMaxDamage2 * 4) + 6; + monster[i].mArmorClass += 80; + monster[i].mMagicRes = monst->MData->mMagicRes2; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ClrAllMonsters() +{ + int i; + MonsterStruct *Monst; + + for (i = 0; i < MAXMONSTERS; ++i) { + Monst = &monster[i]; + ClearMVars(i); + + //track down freeloaders from previous levels by making them obvious + Monst->mName = sgszInvalidMonstName; + + Monst->_mgoal = 0; + Monst->_mmode = MM_STAND; + Monst->_mVar1 = MM_STAND; + Monst->_mVar2 = 0; + Monst->_mx = 0; + Monst->_my = 0; + Monst->_mfutx = 0; + Monst->_mfuty = 0; + Monst->_moldx = 0; + Monst->_moldy = 0; + Monst->_mdir = random(89, 8); + Monst->_mxvel = 0; + Monst->_myvel = 0; + Monst->_mAnimData = NULL; + Monst->_mAnimDelay = 0; + Monst->_mAnimCnt = 0; + Monst->_mAnimLen = 0; + Monst->_mAnimFrame = 0; + Monst->_mFlags = 0; + Monst->_mDelFlag = FALSE; + Monst->_menemy = random(89, gbActivePlayers); + Monst->_menemyx = plr[Monst->_menemy]._pfutx; + Monst->_menemyy = plr[Monst->_menemy]._pfuty; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL MonstPlace(int xp, int yp) { + if (xp < 0 || xp >= DMAXX || yp < 0 || yp >= DMAXY) return FALSE; + if (dMonster[xp][yp] != 0) return FALSE; + if (dPlayer[xp][yp] != 0) return FALSE; + if (dFlags[xp][yp] & BFLAG_MONSTACTIVE) return FALSE; + if (dFlags[xp][yp] & BFLAG_SETPC) return FALSE; + if (SolidLoc(xp,yp)) return FALSE; + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void PlaceMonster(int i, int mtype, int x, int y) +{ + int rd; + + // stoopid hack to NEVER get duplicate Na-Kruls + if (Monsters[mtype].mtype == MT_NKR) + { + int monstindex; + for (monstindex = 0; monstindex < nummonsters; ++monstindex) + if (monster[monstindex]._mMTidx == mtype || + monster[monstindex].MType->mtype == MT_NKR) + return; + } + + dMonster[x][y] = i + 1; + rd = random(90, 8); + InitMonster(i, rd, mtype, x, y); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void LoadUniMonstTrans(int uid) +{ + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void PlaceUniqueMonst(int uniqindex, int miniontype, int packsize) +{ + app_assert((DWORD)nummonsters < MAXMONSTERS); + UniqMonstStruct *Uniq = &UniqMonst[uniqindex]; + MonsterStruct *Monst = &monster[nummonsters]; + + int xp,yp; + int x,y; + BOOL done; + int count, count2; + char filestr[64]; + done = FALSE; + count2 = 0; + int uniqtype; + + // Check if too many uniques. Limit is unique palette translation table size + if((uniquetrans << 8) + 4864 >= LIGHTSIZE) + return; + + // find the index of the monster graphics + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (uniqtype = 0; uniqtype < nummtypes; ++uniqtype) + if (Monsters[uniqtype].mtype == UniqMonst[uniqindex].mtype) break; + app_assert(uniqtype < nummtypes); + + do + { + xp = random(91, DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(91, DMAXY - DIRTEDGE) + (DIRTEDGED2); + count = 0; + for(x = xp-3; x < xp+3; ++x) + for(y = yp-3; y < yp+3; ++y) + if(InBounds(x,y) && MonstPlace(x,y)) + ++count; + } while((count < 9 // try finding a clear spot + && ++count2 < 1000) // avoid infinite loop + || !MonstPlace(xp,yp)); // make sure there's at least + // a spot for the leader + + if(uniqindex == MU_SNOTSPIL) { + xp = (setpc_x << 1) + DIRTEDGED2 + 8; + yp = (setpc_y << 1) + DIRTEDGED2 + 12; + } + if(uniqindex == MU_WARLORD) { + xp = (setpc_x << 1) + DIRTEDGED2 + 6; + yp = (setpc_y << 1) + DIRTEDGED2 + 7; + } + if(uniqindex == MU_ZHAR) { + int i; + BOOL zharflag = TRUE; + for (i = 0; i < themeCount; ++i) { + if ((i == zharlib) && (zharflag == TRUE)) { + zharflag = FALSE; + xp = ((themeLoc[i].x << 1) + DIRTEDGED2)+4; + yp = ((themeLoc[i].y << 1) + DIRTEDGED2)+4; + } + } + } + if (gbMaxPlayers == 1) { + if(uniqindex == MU_LAZARUS) { + xp = 32; + yp = 46; + } + if(uniqindex == MU_REDVEX) { + xp = 40; + yp = 45; + } + if(uniqindex == MU_BLKJADE) { + xp = 38; + yp = 49; + } + if(uniqindex == MU_SKELKING) { + xp = 35; + yp = 47; + } + } else { + if(uniqindex == MU_LAZARUS) { + xp = (setpc_x << 1) + DIRTEDGED2 + 3; + yp = (setpc_y << 1) + DIRTEDGED2 + 6; + } + if(uniqindex == MU_REDVEX) { + xp = (setpc_x << 1) + DIRTEDGED2 + 5; + yp = (setpc_y << 1) + DIRTEDGED2 + 3; + } + if(uniqindex == MU_BLKJADE) { + xp = (setpc_x << 1) + DIRTEDGED2 + 5; + yp = (setpc_y << 1) + DIRTEDGED2 + 9; + } + } + + if (uniqindex == MU_CLEAVER) { + done = FALSE; + // Find certain tile where Butcher goes + for (yp = 0; yp < DMAXY && !done; ++yp) + for (xp = 0; xp < DMAXX && !done; ++xp) + done = (dPiece[xp][yp] == 367); + // NOTE: xp and yp get incremented an extra time after done=TRUE, but + // coincidentally, that's where we want to place butcher + } + + if (uniqindex == MU_NAKRUL) + { + if (Na_Krul.x == 0 || Na_Krul.y == 0) + { + Na_Krul.MIndex = -1; + return; + } + + xp = Na_Krul.x - 2; + yp = Na_Krul.y; + Na_Krul.MIndex = nummonsters; + } + + PlaceMonster(nummonsters, uniqtype, xp, yp); + Monst->_uniqtype = uniqindex+1; + if (Uniq->mlevel != 0) Monst->mLevel = Uniq->mlevel*2; + else Monst->mLevel += 5; + Monst->mExp = (Monst->mExp*2); + Monst->mName = Uniq->mName; + Monst->_mmaxhp = Uniq->mmaxhp << HP_SHIFT; +/* if (gbMaxPlayers != 1) + Monst->_mmaxhp = (Monst->_mmaxhp * MPMM[gbActivePlayers-1]) / 100; + else + Monst->_mmaxhp = Monst->_mmaxhp >> 1; + if (Monst->_mmaxhp < (1 << HP_SHIFT)) Monst->_mmaxhp = 1 << HP_SHIFT;*/ + if (gbMaxPlayers == 1) { + Monst->_mmaxhp = Monst->_mmaxhp >> 1; + if (Monst->_mmaxhp < (1 << HP_SHIFT)) Monst->_mmaxhp = 1 << HP_SHIFT; + } + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->_mAi = Uniq->mAi; + Monst->_mint = Uniq->mint; + Monst->mMinDamage = Uniq->mMinDamage; + Monst->mMaxDamage = Uniq->mMaxDamage; + Monst->mMinDamage2 = Uniq->mMinDamage; + Monst->mMaxDamage2 = Uniq->mMaxDamage; + Monst->mMagicRes = Uniq->mMagicRes; + Monst->mtalkmsg = Uniq->mtalkmsg; + // Don't light up the hork demon, it washes him out. + if ( uniqindex == MU_HORKDEMON) { + Monst->mlid = 0; + } + else { + Monst->mlid = AddLight(Monst->_mx, Monst->_my, 3); + } + if ((gbMaxPlayers != 1) && (Monst->_mAi == AI_LAZHELP)) Monst->mtalkmsg = 0; + if (Monst->mtalkmsg != 0) Monst->_mgoal = MG_TALK; + if (gnDifficulty == D_NIGHTMARE) { + Monst->_mmaxhp = (Monst->_mmaxhp * 3) + (((gbMaxPlayers == 1) ? 50 : 100) << HP_SHIFT); + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->mLevel += 15; + Monst->mExp = (Monst->mExp << 1) + 2000; + Monst->mMinDamage = (Monst->mMinDamage * 2) + 4; + Monst->mMaxDamage = (Monst->mMaxDamage * 2) + 4; + Monst->mMinDamage2 = (Monst->mMinDamage2 * 2) + 4; + Monst->mMaxDamage2 = (Monst->mMaxDamage2 * 2) + 4; + } + else if (gnDifficulty == D_HELL) { + Monst->_mmaxhp = (Monst->_mmaxhp * 4) + (((gbMaxPlayers == 1) ? 100 : 200) << HP_SHIFT); + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->mLevel += 30; + Monst->mExp = (Monst->mExp << 2) + 4000; + Monst->mMinDamage = (Monst->mMinDamage * 4) + 6; + Monst->mMaxDamage = (Monst->mMaxDamage * 4) + 6; + Monst->mMinDamage2 = (Monst->mMinDamage2 * 4) + 6; + Monst->mMaxDamage2 = (Monst->mMaxDamage2 * 4) + 6; + } + + // Load unique monster translations + sprintf(filestr, "Monsters\\Monsters\\%s.TRN", Uniq->mTFile); + app_assert((uniquetrans << 8) + 4864 < LIGHTSIZE); + LoadFileWithMem(filestr, pLightTbl + (uniquetrans << 8) + 4864); + Monst->_uniqtrans = uniquetrans; + ++uniquetrans; + + if(Uniq->mUnqAttr & UN_H) + { + Monst->mHit = Uniq->mUnqVar1; + Monst->mHit2 = Uniq->mUnqVar1; + } + if(Uniq->mUnqAttr & UN_A) + { + Monst->mArmorClass = Uniq->mUnqVar1; + } + + ++nummonsters; + + if(Uniq->mUnqAttr & UN_PACK) + { + PlaceGroup(miniontype, packsize, Uniq->mUnqAttr, nummonsters-1); + } + // quick fix for monsters that were gargoyles before they became unique + if (Monst->_mAi != AI_GARG) + { + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + Monst->_mAnimFrame = random(88, Monst->_mAnimLen - 1) + 1; + Monst->_mFlags &= ~MFLAG_STILL; + Monst->_mmode = MM_STAND; + } +} + +void Hose_NaKrul() +{ + if (currlevel == NA_KRUL_LEVEL) + { + int mi = Na_Krul.MIndex; + if (mi < 0 || mi >= nummonsters) + return; + + MonsterStruct *Monst = &monster[mi]; + PlayEffect(mi, MS_DEATH); + quests[Q_NA_KRUL]._qlog = FALSE; + + Monst->_mmaxhp = Monst->_mmaxhp / 2; + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->mArmorClass -= 50; + Monst->mMagicRes = 0x0000; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static void PlaceUniques() +{ + int u; + int mt; + BOOL done; + + //uniquetrans = 0; + for(u = 0; UniqMonst[u].mtype != -1; ++u) + { +#if CHEATS + if ((UniqMonst[u].mlevel == currlevel) + || (UniqMonst[u].mlevel && davedebug)) { +#else + if (UniqMonst[u].mlevel == currlevel) { +#endif + done = FALSE; + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(mt = 0; mt < nummtypes && !done; ++mt) + done = Monsters[mt].mtype == UniqMonst[u].mtype; + --mt; + if ((u == MU_GARBUD) && (quests[Q_GARBUD]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_ZHAR) && (quests[Q_ZHAR]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_SNOTSPIL) && (quests[Q_LTBANNER]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_LACHDA) && (quests[Q_VEIL]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_WARLORD) && (quests[Q_WARLORD]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if(done) + { + PlaceUniqueMonst(u, mt, 8); + } + } + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static void PlaceQuestMonsters() +{ + int skeltype; + byte *setp; + + if (!setlevel) { + if (QuestStatus(Q_BUTCHER)) + PlaceUniqueMonst(MU_CLEAVER, 0, 0); + + if ((currlevel == quests[Q_SKELKING]._qlevel) && (gbMaxPlayers != 1)) + { + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (skeltype = 0; skeltype < nummtypes; ++skeltype) + if (IsSkel(Monsters[skeltype].mtype)) break; + app_assert(skeltype < nummtypes); + + PlaceUniqueMonst(MU_SKELKING, skeltype, 30); + } + + if (QuestStatus(Q_LTBANNER)) + { + setp = LoadFileInMemSig("Levels\\L1Data\\Banner1.DUN",NULL,'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_BLOOD)) + { + setp = LoadFileInMemSig("Levels\\L2Data\\Blood2.DUN", NULL, 'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_BLIND)) + { + setp = LoadFileInMemSig("Levels\\L2Data\\Blind2.DUN", NULL, 'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_ANVIL)) + { + setp = LoadFileInMemSig("Levels\\L3Data\\Anvil.DUN",NULL,'MONS'); + SetMapMonsters(setp, ((setpc_x+1) << 1), ((setpc_y+1) << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_WARLORD)) + { + setp = LoadFileInMemSig("Levels\\L4Data\\Warlord.DUN",NULL,'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + AddMonsterType(UniqMonst[MU_WARLORD].mtype, MPFLAG_SCATTER); // to allow scatterable monst of mtype + } + + if (QuestStatus(Q_VEIL)) + { + AddMonsterType(UniqMonst[MU_LACHDA].mtype, MPFLAG_SCATTER); // to allow scatterable monst of mtype + } + + if (QuestStatus(Q_ZHAR)) { + if (zharlib == -1) + quests[Q_ZHAR]._qactive = QUEST_NOTAVAIL; + } + + if ((currlevel == quests[Q_BETRAYER]._qlevel) && (gbMaxPlayers != 1)) { + AddMonsterType(UniqMonst[MU_LAZARUS].mtype, MPFLAG_UNIQ); + AddMonsterType(UniqMonst[MU_REDVEX].mtype, MPFLAG_UNIQ); + PlaceUniqueMonst(MU_LAZARUS, 0, 0); + PlaceUniqueMonst(MU_REDVEX, 0, 0); + PlaceUniqueMonst(MU_BLKJADE, 0, 0); + setp = LoadFileInMemSig("Levels\\L4Data\\Vile1.DUN",NULL,'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + if (currlevel == NA_KRUL_LEVEL) + { + //if ((quests[Q_NA_KRUL]._qactive != QUEST_NOTAVAIL) && + // (quests[Q_NA_KRUL]._qlog)) + { + + int numminions = 2; + if (gnDifficulty == D_NIGHTMARE) + numminions = 4; + else if (gnDifficulty == D_HELL) + numminions = 6; + + // see if we already have a Na-Krul + Na_Krul.MIndex = -1; + + int uniqtype; + for (uniqtype = 0; uniqtype < nummtypes; ++uniqtype) + if (Monsters[uniqtype].mtype == UniqMonst[MU_NAKRUL].mtype) break; + + if (uniqtype < nummtypes) + { + int monstindex; + for (monstindex = 0; monstindex < nummonsters; ++monstindex) + { + if (monster[monstindex]._uniqtype != 0 || + monster[monstindex]._mMTidx == uniqtype) + { + Na_Krul.MIndex = monstindex; + break; + } + } + } + if (Na_Krul.MIndex == -1) // didn't find + { + PlaceUniqueMonst(MU_NAKRUL, 0, 0); + } + } + } + } + else if (setlvlnum == SL_SKELKING) { + PlaceUniqueMonst(MU_SKELKING, 0, 0); + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void PlaceGroup(int mtype, int num, BOOL leaderf, int leader) +{ + int xp, yp; + int x1, y1; + int j; + int placed = 0; + int try1 = 0; + int try2; + int rd; + + app_assert((DWORD)leader < MAXMONSTERS); + do + { + // Clear out the subset placed last time through the loop + while(placed) + { + --nummonsters; + --placed; + app_assert((DWORD)nummonsters < MAXMONSTERS); + app_assert((DWORD)monster[nummonsters]._mx < MAXDUNX); + app_assert((DWORD)monster[nummonsters]._my < MAXDUNY); + dMonster[monster[nummonsters]._mx][monster[nummonsters]._my] = 0; + } + + if(leaderf & UN_PACK) + { + rd = random(92, 8); + x1 = xp = monster[leader]._mx + offset_x[rd]; + y1 = yp = monster[leader]._my + offset_y[rd]; + } + else + { + do + { + x1 = xp = random(93, DMAXX - DIRTEDGE) + (DIRTEDGED2); + y1 = yp = random(93, DMAXY - DIRTEDGE) + (DIRTEDGED2); + } while (!MonstPlace(xp, yp)); + } + + if ((nummonsters + num) > totalmonsters) num = totalmonsters - nummonsters; + j = 0; + try2 = 0; + while (j < num && try2 < 100) { + if (MonstPlace(xp, yp) && (dTransVal[xp][yp] == dTransVal[x1][y1]) + && !((leaderf & UN_STICK) && !DIST(xp-x1,yp-y1,4))) { + PlaceMonster(nummonsters, mtype, xp, yp); + if(leaderf & UN_PACK) + { + monster[nummonsters]._mmaxhp *= 2; + monster[nummonsters]._mhitpoints = monster[nummonsters]._mmaxhp; + monster[nummonsters]._mint = monster[leader]._mint; + if (leaderf & UN_STICK) + { + monster[nummonsters].leader = leader; + monster[nummonsters].leaderflag = PACK_MEMBER; + monster[nummonsters]._mAi = monster[leader]._mAi; + } + // quick fix for monsters that were gargoyles before they became unique + if (monster[nummonsters]._mAi != AI_GARG) + { + monster[nummonsters]._mAnimData = monster[nummonsters].MType->Anims[MA_STAND].Cels[monster[nummonsters]._mdir]; + monster[nummonsters]._mAnimFrame = random(88, monster[nummonsters]._mAnimLen - 1) + 1; + monster[nummonsters]._mFlags &= ~MFLAG_STILL; + monster[nummonsters]._mmode = MM_STAND; + } + } + + ++nummonsters; + ++placed; + ++j; + } + else + ++try2; + xp += offset_x[random(94, 8)]; + yp += offset_x[random(94, 8)]; + } + } while((placed < num) && (++try1 < 10)); + if(leaderf & UN_STICK) + monster[leader].packsize = placed; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +void LoadDiabMonsts() +{ + BYTE *pSetPiece; + int xx, yy; + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab1.DUN",NULL,'STPC'); + xx = (diabquad1x << 1); + yy = (diabquad1y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab2a.DUN",NULL,'STPC'); + xx = (diabquad2x << 1); + yy = (diabquad2y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab3a.DUN",NULL,'STPC'); + xx = (diabquad3x << 1); + yy = (diabquad3y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab4a.DUN",NULL,'STPC'); + xx = (diabquad4x << 1); + yy = (diabquad4y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitMonsters () +{ + int i, mtype; + int na, nt; + int scattertypes[LASTMT]; + int numscattypes = 0; + long fv,j; + int numplacemonsters; + int s,t; + +void DaveCheck2(); + if (gbMaxPlayers != 1) DaveCheck2(); + + // add 4 golem places first + // WARNING!! IF YOU CHANGE THIS YOU MUST TEST POSION WATER QUEST!!! + if (!setlevel) { + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + } + + // We will place the monsters seperately for 16 +#if !IS_VERSION(SHAREWARE) + if (!setlevel && currlevel == 16) { + LoadDiabMonsts(); + } +#endif + + // Monsters are not placed where bFlags[][] & BFLAG_MONSTACTIVE is set + // This prevents: 1) Monsters attacking players as they enter dungeon + // 2) Monsters setting off traps + + nt = numtrigs; + if (currlevel == 15) nt = 1; + for (i = 0; i < nt; ++i) + { + for (s = -2; s < 2; ++s) + for (t = -2; t < 2; ++t) + DoVision(trigs[i]._tx + s, trigs[i]._ty + t, INITMONSTRAD, FALSE, FALSE); + } + +#if !IS_VERSION(SHAREWARE) + PlaceQuestMonsters(); +#endif + + if (!setlevel) + { +#if !IS_VERSION(SHAREWARE) + PlaceUniques(); // Place uniques before any other monsters +#endif + // Calc a volume of monsters + fv = 0; + for (i = DIRTEDGED2; i < (DMAXY - (DIRTEDGED2)); ++i) { + for (j = DIRTEDGED2; j < (DMAXX - (DIRTEDGED2)); ++j) { + if (!SolidLoc(i,j)) ++fv; + } + } + numplacemonsters = fv / MONSTDENSITY; +#if 0 // Debugging = 1, normal = 0 + numplacemonsters = 1; +#else + if (gbMaxPlayers != 1) numplacemonsters += (numplacemonsters >> 1); +#endif + if (numplacemonsters + nummonsters > MAXMONSTERS - 10) + numplacemonsters = MAXMONSTERS - 10 - nummonsters; + + totalmonsters = nummonsters + numplacemonsters; + + +#ifndef PACKS_ONLY // switch for debugging pack AI + // Place scattered monsters + + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes; ++i) + { + if (Monsters[i].mPlaceFlags & MPFLAG_SCATTER) + scattertypes[numscattypes++] = i; + } + + while (nummonsters < totalmonsters) { + mtype = scattertypes[random(95, numscattypes)]; + + if (currlevel != 1 // no groups on level 1 + && random(95, 2)) + { + if (currlevel == 2 || // half-size groups on level 2 + (currlevel >= CRYPTSTART && currlevel <= CRYPTEND)) + na = random(95, 2) + 2; + else + na = random(95, 3) + 3; + } + else na = 1; + + PlaceGroup(mtype, na, FALSE, NULL); + } +#endif // PACKS_ONLY + } + + for (i = 0; i < nt; ++i) + { + for (s = -2; s < 2; ++s) + for (t = -2; t < 2; ++t) + DoUnVision(trigs[i]._tx + s, trigs[i]._ty + t, INITMONSTRAD); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetMapMonsters(BYTE *pMap, int startx, int starty) +{ + int i,j; + WORD rw,rh; + WORD *lm; + int mt,mx,my; + int mtype; + + // add 4 golem places first + // WARNING! IF YOU CHANGE THIS YOU MUST TEST THE POISON WATER QUEST!!!! + AddMonsterType(MT_GOLEM, MPFLAG_DONT); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + + if ((setlevel) && (setlvlnum == SL_VILEBETRAYER)) { + AddMonsterType(UniqMonst[MU_LAZARUS].mtype, MPFLAG_UNIQ); + AddMonsterType(UniqMonst[MU_REDVEX].mtype, MPFLAG_UNIQ); + AddMonsterType(UniqMonst[MU_BLKJADE].mtype, MPFLAG_UNIQ); + PlaceUniqueMonst(MU_LAZARUS, 0, 0); + PlaceUniqueMonst(MU_REDVEX, 0, 0); + PlaceUniqueMonst(MU_BLKJADE, 0, 0); + } + + + lm = (WORD *)pMap; + rw = *(lm++); + rh = *(lm++); + // Skip map + lm += rw * rh; + // Convert to index mini tile level instead of mega + rw = rw << 1; + rh = rh << 1; + // Skip treasure map + lm += rw * rh; + for (j = 0; j < rh; ++j) { + for (i = 0; i < rw; ++i) { + if (*lm != 0) { + mt = *lm; + mt = MonstConvTbl[mt-1]; + mtype = AddMonsterType(mt, MPFLAG_DONT); + mx = i + DIRTEDGED2 + startx; + my = j + DIRTEDGED2 + starty; + PlaceMonster(nummonsters++, mtype, mx, my); + } + ++lm; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DeleteMonster(int i) +{ + int temp; + + app_assert((DWORD)(nummonsters-1) < MAXMONSTERS); + app_assert((DWORD)i < MAXMONSTERS); + temp = monstactive[--nummonsters]; + monstactive[nummonsters] = monstactive[i]; + monstactive[i] = temp; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int AddMonster(int x, int y, int dir, int mtype, BOOL InMap) +{ + int i; + + if (nummonsters < MAXMONSTERS) { + i = monstactive[nummonsters++]; + if (InMap) dMonster[x][y] = i + 1; + InitMonster(i, dir, mtype, x, y); + return i; + } else return -1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CloneMonster(int m) +{ + if (monster[m].MType == NULL) + return; + int oldx = monster[m]._mx; + int oldy = monster[m]._my; + int dir = monster[m]._mdir; + + // try to find a place to put a new monster, next to old monster + int x, y, theta; + + for (theta = 0; theta < 8; ++theta) + { + x = oldx + offset_x[theta]; + y = oldy + offset_y[theta]; + + if (SolidLoc(x, y) || dPlayer[x][y] || dMonster[x][y]) + continue; + + if (!dObject[x][y]) + break; + + int oi = (dObject[x][y] > 0) ? (dObject[x][y] - 1) : -(dObject[x][y] + 1); + if (!object[oi]._oSolidFlag) + break; + } + if (theta >= 8) // no space + return; + + int mtype = monster[m].MType->mtype; + for (int i=0; i < MAX_LVLMTYPES; ++i) + { + if (Monsters[i].mtype == mtype) + break; + } + if (i < MAX_LVLMTYPES) + AddMonster(x, y, dir, i, TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void NewMonsterAnim(int i, AnimStruct &anim, int md) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert((DWORD)md < 8); + MonsterStruct *Monst = &monster[i]; + + Monst->_mAnimData = anim.Cels[md]; + Monst->_mAnimLen = anim.Frames; + Monst->_mAnimFrame = 1; + Monst->_mAnimCnt = 0; + Monst->_mAnimDelay = anim.Rate; + Monst->_mdir = md; + Monst->_mFlags &= ~(MFLAG_BACKWARDS|MFLAG_STILL); +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL M_Ranged (int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + if (monster[i]._mAi == AI_SKELBOW || + monster[i]._mAi == AI_GOATBOW || + monster[i]._mAi == AI_SUCC || + monster[i]._mAi == AI_LAZHELP) return TRUE; + + return FALSE; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL M_Talker (int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + if (monster[i]._mAi == AI_LAZURUS || + monster[i]._mAi == AI_WARLORD || + monster[i]._mAi == AI_GARBUD || + monster[i]._mAi == AI_ZHAR || + monster[i]._mAi == AI_SNOTSPIL || + monster[i]._mAi == AI_LACHDANAN || + monster[i]._mAi == AI_LAZHELP) return TRUE; + + return FALSE; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_Enemy (int i) +{ + int j; + int pnum, closest; + int bestdist; + bool bestsameroom; + + app_assert((DWORD)i < MAXMONSTERS); + MonsterStruct *Monst = &monster[i]; + BYTE enemyx,enemyy; + + closest = -1; + bestdist = -1; + bestsameroom = false; + + + if (Monst->_mFlags & MFLAG_BERSERK + || !(Monst->_mFlags & MFLAG_MKILLER) ) { + for(pnum = 0; pnum < MAX_PLRS; ++pnum) { + if (!plr[pnum].plractive + || currlevel != plr[pnum].plrlevel + || plr[pnum]._pLvlChanging + || ((plr[pnum]._pHitPoints >> HP_SHIFT) == 0) ) + continue; + + bool const sameroom = (dTransVal[Monst->_mx][Monst->_my] == dTransVal[plr[pnum]._px][plr[pnum]._py]); + int const dist = max(abs(Monst->_mx - plr[pnum]._px), abs(Monst->_my - plr[pnum]._py)); + + if ((sameroom && !bestsameroom) || ((sameroom || !bestsameroom) && dist < bestdist) || closest == -1) { + Monst->_mFlags &= ~MFLAG_MID; +// Monst->_mFlags &= ~MFLAG_MKILLER; + closest = pnum; + enemyx = plr[pnum]._pfutx; + enemyy = plr[pnum]._pfuty; + bestdist = dist; + bestsameroom = sameroom; + } + } + } + + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (j = 0; j < nummonsters; ++j) { + + int const mi = monstactive[j]; + + if ((mi != i) && + ((monster[mi]._mhitpoints >> HP_SHIFT) > 0) && + ((monster[mi]._mx != 1) || (monster[mi]._my != 0)) && // special confus-o-matic code for inactive golum + ((!M_Talker(mi)) || monster[mi].mtalkmsg == 0) && + /*(DIST((monster[mi]._mx - Monst->_mx),(monster[mi]._my - Monst->_my),2)) &&*/ + ((Monst->_mFlags & MFLAG_MKILLER) || (Monst->_mFlags & MFLAG_BERSERK) || + ((DIST((monster[mi]._mx - Monst->_mx),(monster[mi]._my - Monst->_my),2)) || (M_Ranged(i)))) && + (Monst->_mFlags & MFLAG_MKILLER || (Monst->_mFlags & MFLAG_BERSERK) + || monster[mi]._mFlags & MFLAG_MKILLER)) { + + bool const sameroom = (dTransVal[Monst->_mx][Monst->_my] == dTransVal[monster[mi]._mx][monster[mi]._my]); + int const dist = max(abs(Monst->_mx - monster[mi]._mx), abs(Monst->_my - monster[mi]._my)); + + if ((sameroom && !bestsameroom) || ((sameroom || !bestsameroom) && dist < bestdist) || closest == -1) { + Monst->_mFlags |= MFLAG_MID; + closest = mi; + enemyx = monster[mi]._mfutx; + enemyy = monster[mi]._mfuty; + bestdist = dist; + bestsameroom = sameroom; + } + } + } + + // everyone dead? + if (closest != -1) + { + Monst->_menemy = closest; + Monst->_menemyx = enemyx; + Monst->_menemyy = enemyy; + Monst->_mFlags &= ~MFLAG_NOENEMY; + } + else + Monst->_mFlags |= MFLAG_NOENEMY; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static int M_GetDir(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + return GetDirection(monster[i]._mx, monster[i]._my, monster[i]._menemyx, monster[i]._menemyy); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_CheckEFlag(int i) +{ + int tx,ty,tv; + int t; + WORD *mt; + + app_assert((DWORD)i < MAXMONSTERS); + tx = monster[i]._mx - 1; + ty = monster[i]._my + 1; + tv = 0; + mt = &(dMT[tx][ty].mt[0]); + for(t = 2; t < 10; ++t) + tv |= mt[t]; + tv |= dSpecial[tx][ty]; + if (tv != 0) monster[i]._meflag = 1; + else monster[i]._meflag = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartStand(int i, int md) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + ClearMVars(i); + if (monster[i].MType->mtype == MT_GOLEM) + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], md); + else + NewMonsterAnim(i, monster[i].MType->Anims[MA_STAND], md); + + monster[i]._mVar1 = monster[i]._mmode; + monster[i]._mVar2 = 0; // count how long he's been standing + monster[i]._mmode = MM_STAND; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); + + // Pick nearest enemy + M_Enemy(i); +} + +/*-----------------------------------------------------------------------* + * M_StartDelay + * + * Keeps monster in Stand animation for len frames + * Monster must be in Stand mode before entering Delay mode +**-----------------------------------------------------------------------*/ + +static void M_StartDelay(int i, int len) +{ + if(len > 0) + { + if (monster[i]._mAi == AI_LAZURUS) return; + app_assert((DWORD)i < MAXMONSTERS); + monster[i]._mVar2 = len; + monster[i]._mmode = MM_DELAY; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartSpStand(int i, int md) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_SPSTAND; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartWalk(int i, int xvel, int yvel, int xadd, int yadd, int EndDir) +{ + long fx,fy; + int pn; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + app_assert((DWORD)fx < MAXDUNX); + app_assert((DWORD)fy < MAXDUNY); + pn = dPiece[fx][fy] - 1; + dMonster[fx][fy] = -1 - i; + monster[i]._mmode = MM_WALK; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar1 = xadd; + monster[i]._mVar2 = yadd; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], EndDir); + monster[i]._mVar6 = 0; + monster[i]._mVar7 = 0; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartWalk2(int i, int xvel, int yvel, int xoff, int yoff, + int xadd, int yadd, int EndDir) +{ + long fx,fy; + int pn; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + app_assert((DWORD)fx < MAXDUNX); + app_assert((DWORD)fy < MAXDUNY); + pn = dPiece[fx][fy] - 1; + app_assert((DWORD)monster[i]._mx < MAXDUNX); + app_assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = -1 - i; + monster[i]._mVar1 = monster[i]._mx; + monster[i]._mVar2 = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mx = fx; + monster[i]._my = fy; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + dMonster[fx][fy] = i + 1; + if( !(monster[i]._mFlags & MFLAG_INVISIBLE) + && monster[i].mlid != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + monster[i]._mxoff = xoff; + monster[i]._myoff = yoff; + monster[i]._mmode = MM_WALK2; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], EndDir); + monster[i]._mVar6 = xoff << 4; + monster[i]._mVar7 = yoff << 4; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartWalk3(int i, int xvel, int yvel, int xoff, int yoff, + int xadd, int yadd, int txa, int tya, int EndDir) +{ + long fx,fy; + long tx,ty; + int pn, pn2; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + tx = monster[i]._mx + txa; // Temp location for drawing + ty = monster[i]._my + tya; + if( !(monster[i]._mFlags & MFLAG_INVISIBLE) + && monster[i].mlid != 0) { + ChangeLightXY(monster[i].mlid, tx, ty); + } + app_assert((DWORD)fx < MAXDUNX); + app_assert((DWORD)fy < MAXDUNY); + pn = dPiece[fx][fy] - 1; + pn2 = dPiece[tx][ty] - 1; + app_assert((DWORD)monster[i]._mx < MAXDUNX); + app_assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = -1 - i; + dMonster[fx][fy] = -1 - i; + monster[i]._mVar4 = tx; + monster[i]._mVar5 = ty; + dFlags[tx][ty] |= BFLAG_MONSTLR; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + monster[i]._mxoff = xoff; + monster[i]._myoff = yoff; + monster[i]._mmode = MM_WALK3; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar1 = fx; + monster[i]._mVar2 = fy; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], EndDir); + monster[i]._mVar6 = xoff << 4; + monster[i]._mVar7 = yoff << 4; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartAttack(int i) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_ATTACK], md); + + monster[i]._mmode = MM_ATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +** Ranged weapons +**-----------------------------------------------------------------------*/ + +static void M_StartRAttack(int i, int missile_type, int dam) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_ATTACK], md); + + monster[i]._mmode = MM_RATTACK; + monster[i]._mVar1 = missile_type; + monster[i]._mVar2 = dam; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +** Ranged Special weapons +**-----------------------------------------------------------------------*/ + +static void M_StartRSpAttack(int i, int missile_type, int dam) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_RSATTACK; + monster[i]._mVar1 = missile_type; + monster[i]._mVar2 = 0; + monster[i]._mVar3 = dam; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartSpAttack(int i) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_SATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* + * M_StartEat is the same as M_StartSpAttack except mdir isn't affected +**-----------------------------------------------------------------------*/ + +static void M_StartEat(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], monster[i]._mdir); + + monster[i]._mmode = MM_SATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_ClearSquares(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + int const mx = monster[i]._moldx; + int const my = monster[i]._moldy; + int const mt = -1 - i; + int const mt2 = i + 1; + app_assert((DWORD)(mx+1) < MAXDUNX); + app_assert((DWORD)(my+1) < MAXDUNY); + for (int y = my-1; y <= my+1; ++y) { + for (int x = mx-1; x <= mx+1; ++x) { + if (dMonster[x][y] == mt || dMonster[x][y] == mt2) { + dMonster[x][y] = 0; + } + } + } + + dFlags[mx+1][my+0] &= BFMASK_MONSTLR; + dFlags[mx+0][my+1] &= BFMASK_MONSTLR; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_GetKnockback(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + // knock back enemy if you can + int const d = (monster[i]._mdir + 4) & 0x7; + if (DirOK(i, d)) { + M_ClearSquares(i); + monster[i]._moldx += offset_x[d]; + monster[i]._moldy += offset_y[d]; + NewMonsterAnim(i, monster[i].MType->Anims[MA_GOTHIT], monster[i]._mdir); + monster[i]._mmode = MM_GOTHIT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mx = monster[i]._moldx; + monster[i]._my = monster[i]._moldy; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + M_ClearSquares(i); + app_assert((DWORD)monster[i]._mx < MAXDUNX); + app_assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_StartHit(int i, int pnum, int dam) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + if (pnum >= 0) monster[i].mWhoHit |= (1 << pnum); // Who damaged me + + if (pnum == myplr) { + extern void delta_monster_hp(int mi,long hp,BYTE bLevel); + delta_monster_hp(i,monster[i]._mhitpoints,currlevel); + NetSendCmdMonstDamage(FALSE,i,dam); + } + PlayEffect(i, MS_GOTHIT); + + // Sneaky demons always get hit + if (!EquivMonst(monster[i].MType->mtype, MT_SNEAK)) + // Other monsters only get hit if damage is severe + //if (((dam >> HP_SHIFT) < (monster[i].mLevel + 3)) && (!(plr[pnum]._pIFlags & IAF_KNOCKBACK))) + if ((dam >> HP_SHIFT) < (monster[i].mLevel + 3)) + return; + + // Set monster's enemy to be this player + if (pnum >= 0) { + monster[i]._menemy = pnum; + monster[i]._menemyx = plr[pnum]._pfutx; + monster[i]._menemyy = plr[pnum]._pfuty; + monster[i]._mFlags &= ~MFLAG_MID; + monster[i]._mdir = M_GetDir(i); + } + + // Check for special hits/teleports + if(monster[i].MType->mtype == MT_BLINK) { + M_Teleport(i); + } else { + if (EquivMonst(monster[i].MType->mtype, MT_NSCAV) || + monster[i].MType->mtype == MT_GRAVDG) { + // allow it to seek food again. + monster[i]._mgoal = MG_ATTACK; + monster[i]._mgoalvar1 = 0; + monster[i]._mgoalvar2 = 0; + } + } + if (monster[i]._mmode != MM_STONE) { + NewMonsterAnim(i, monster[i].MType->Anims[MA_GOTHIT], monster[i]._mdir); + monster[i]._mmode = MM_GOTHIT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mx = monster[i]._moldx; + monster[i]._my = monster[i]._moldy; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + M_ClearSquares(i); + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void M_DiabloDeath(int i, BOOL sendmsg) +{ + MonsterStruct *Monst = &monster[i]; + + // disable any other sounds from playing, for dramatic effect + #if !IS_VERSION(SHAREWARE) + PlaySFX(USFX_DIABLOD); + #endif + quests[Q_DIABLO]._qactive = QUEST_DONE; + if (sendmsg) NetSendCmdQuest(TRUE, Q_DIABLO); + sgbSaveSoundOn = gbSoundOn; + gbSoundOn = FALSE; + // disable player processing, so we can take over screen scrolling + gbProcessPlayers = FALSE; + // kill all other monsters on level + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (int j = 0; j < nummonsters; ++j) { + int const k = monstactive[j]; + if (k != i && monster[i]._msquelch) { + NewMonsterAnim(k, monster[k].MType->Anims[MA_DEATH], monster[k]._mdir); + monster[k]._mmode = MM_DEATH; + monster[k]._mxoff = 0; + monster[k]._myoff = 0; + monster[k]._mVar1 = 0; + monster[k]._mx = monster[k]._moldx; + monster[k]._my = monster[k]._moldy; + monster[k]._mfutx = monster[k]._mx; + monster[k]._mfuty = monster[k]._my; + monster[k]._moldx = monster[k]._mx; + monster[k]._moldy = monster[k]._my; + M_CheckEFlag(k); + M_ClearSquares(k); + dMonster[monster[k]._mx][monster[k]._my] = k + 1; + } + } + AddLight(Monst->_mx, Monst->_my, 8); + DoVision(Monst->_mx, Monst->_my, 8, FALSE, TRUE); + // set up scrolling vars + int steps = max(abs(ViewX-Monst->_mx),abs(ViewY-Monst->_my)); + steps = min(20, steps); + + Monst->_mVar3 = ViewX << 16; // convert to fixed-point + Monst->_mVar4 = ViewY << 16; + // calculate scroll offsets + Monst->_mVar5 = (int)((double)(Monst->_mVar3 - (Monst->_mx << 16))/(double)steps); + Monst->_mVar6 = (int)((double)(Monst->_mVar4 - (Monst->_my << 16))/(double)steps); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M2MStartHit(int mid, int i, int dam) +{ + if ((DWORD)mid >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("Invalid monster %d getting hit by monster",mid); +#else + return; +#endif + } + if (monster[mid].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("Monster %d \"%s\" getting hit by monster: MType NULL",mid,monster[mid].mName); +#else + return; +#endif + } + + if (i >= 0) monster[i].mWhoHit |= (1 << i); // Who damaged me + + extern void delta_monster_hp(int mi,long hp, BYTE bLevel); + delta_monster_hp(mid, monster[mid]._mhitpoints, currlevel); + NetSendCmdMonstDamage(FALSE, mid, dam); + + PlayEffect(mid, MS_GOTHIT); + + // Sneaky demons always get hit + if (!EquivMonst(monster[mid].MType->mtype, MT_SNEAK)) + // Other monsters only get hit if damage is severe + if ((dam >> HP_SHIFT) < (monster[mid].mLevel + 3)) return; + + // face plr who hit me + if (i >= 0) monster[mid]._mdir = (monster[i]._mdir + 4) &0x07; + + // Check for special hits/teleports + if(monster[mid].MType->mtype == MT_BLINK) { + M_Teleport(mid); + } else { + if (EquivMonst(monster[mid].MType->mtype, MT_NSCAV) || + monster[mid].MType->mtype == MT_GRAVDG) { + // allow it to seek food again. + monster[mid]._mgoal = MG_ATTACK; + monster[mid]._mgoalvar1 = 0; + monster[mid]._mgoalvar2 = 0; + } + } + + if (monster[mid]._mmode != MM_STONE) { + if (monster[mid].MType->mtype != MT_GOLEM) { + NewMonsterAnim(mid, monster[mid].MType->Anims[MA_GOTHIT], monster[mid]._mdir); + monster[mid]._mmode = MM_GOTHIT; + } + + monster[mid]._mxoff = 0; + monster[mid]._myoff = 0; + monster[mid]._mx = monster[mid]._moldx; + monster[mid]._my = monster[mid]._moldy; + monster[mid]._mfutx = monster[mid]._mx; + monster[mid]._mfuty = monster[mid]._my; + monster[mid]._moldx = monster[mid]._mx; + monster[mid]._moldy = monster[mid]._my; + M_CheckEFlag(mid); + M_ClearSquares(mid); + dMonster[monster[mid]._mx][monster[mid]._my] = mid + 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void MonstKillEffect(int i, BOOL sendmsg) +{ + MonsterStruct *Monst = &monster[i]; + + if (QuestStatus(Q_GARBUD) && (Monst->mName == UniqMonst[MU_GARBUD].mName)) + CreateTypeItem(Monst->_mx+1, Monst->_my+1, TRUE, IT_MACE, IMID_NONE, TRUE, FALSE); + else if (Monst->mName == UniqMonst[MU_DEFILER].mName) + { + if (effect_is_playing(HSFX_DEFILER5)) + stream_stop(); + + quests[Q_DEFILER]._qlog = FALSE; + SpawnMap(Monst->_mx, Monst->_my); + } + else if (Monst->mName == UniqMonst[MU_HORKDEMON].mName) + { + if (gbTheo) + SpawnBear(Monst->_mx, Monst->_my); + else + CreateAmulet(Monst->_mx, Monst->_my, 13, FALSE, TRUE); + } + else if (Monst->MType->mtype == MT_SPAWN) + { + // do nothing + } + else if (Monst->MType->mtype == MT_NKR) + { + int whichEffect = (Na_Krul.Books)?HSFX_NA_KRUL4:HSFX_NA_KRUL5; + if (gbCowsuit) // override -- funny + whichEffect = HSFX_NA_KRUL6; + + if (effect_is_playing(whichEffect)) + stream_stop(); + + quests[Q_NA_KRUL]._qlog = FALSE; + Na_Krul.MIndex = -2; + CreateMagicWeapon(Monst->_mx, Monst->_my, IT_SWORD, ITEM_GRTSWORD, FALSE, TRUE); + CreateMagicWeapon(Monst->_mx, Monst->_my, IT_STAFF, ITEM_STLSTAFF, FALSE, TRUE); + CreateMagicWeapon(Monst->_mx, Monst->_my, IT_BOW, ITEM_STLLONGBOW, FALSE, TRUE); + CreateSpellBook (Monst->_mx, Monst->_my, SPL_APOCA, FALSE, TRUE); + } + else if (i > 3) + { + SpawnItem(i, Monst->_mx, Monst->_my, sendmsg); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void MonstStartKill(int i, int pnum, BOOL sendmsg) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined (_DEBUG) + app_fatal("MonstStartKill: Invalid monster %d",i); +#else + return; +#endif + } + + if (monster[i].MType == NULL) + { + //app_fatal("MonstStartKill: Monster %d \"%s\" MType NULL",i,monster[i].mName); + return; + } + + int md; + MonsterStruct *Monst = &monster[i]; + + // killer gets credit too, and divvy up exper + if (pnum >= 0) Monst->mWhoHit |= (1 << pnum); // Who killed me + + // rjs.patch1.start.1/23/97 - fixes golem giving exp when killed + //old. if (pnum < MAX_PLRS) AddPlrMonstExper(Monst->mLevel, Monst->mExp, Monst->mWhoHit); + if ((pnum < MAX_PLRS) && (i > MAX_PLRS)) AddPlrMonstExper(Monst->mLevel, Monst->mExp, Monst->mWhoHit); + // rjs.patch1.end.1/23/97 + + // Kill the monster (for myplr or other plr) + ++monstkills[Monst->MType->mtype]; + Monst->_mhitpoints = 0; + SetRndSeed(Monst->_mRndSeed); + MonstKillEffect(i, sendmsg); + +#if 0 + if (QuestStatus(Q_GARBUD) && (Monst->mName == UniqMonst[MU_GARBUD].mName)) + CreateTypeItem(Monst->_mx+1, Monst->_my+1, TRUE, IT_MACE, IMID_NONE, TRUE, FALSE); + else if (Monst->mName == UniqMonst[MU_DEFILER].mName) + { + quests[Q_DEFILER]._qlog = FALSE; + SpawnMap(Monst->_mx, Monst->_my); + } + else if (Monst->mName == UniqMonst[MU_HORKDEMON].mName) + if (gbTheo) + SpawnBear(Monst->_mx, Monst->_my); + else if (Monst->MType->mtype == MT_SPAWN) + { + // do nothing + } + else if (Monst->MType->mtype == MT_NKR) + { + quests[Q_NA_KRUL]._qlog = FALSE; + } + else if (i > 3) SpawnItem(i, Monst->_mx, Monst->_my, sendmsg); +#endif + + if (Monst->MType->mtype == MT_DIABLO) { + M_DiabloDeath(i, TRUE); + } + else + PlayEffect(i, MS_DEATH); + + if (pnum >= 0) md = M_GetDir(i); + else md = Monst->_mdir; + Monst->_mdir = md; + NewMonsterAnim(i, Monst->MType->Anims[MA_DEATH], md); + Monst->_mmode = MM_DEATH; + Monst->_mgoal = 0; + Monst->_mxoff = 0; + Monst->_myoff = 0; + Monst->_mVar1 = 0; + Monst->_mx = Monst->_moldx; + Monst->_my = Monst->_moldy; + Monst->_mfutx = Monst->_mx; + Monst->_mfuty = Monst->_my; + Monst->_moldx = Monst->_mx; + Monst->_moldy = Monst->_my; + M_CheckEFlag(i); + M_ClearSquares(i); + dMonster[Monst->_mx][Monst->_my] = i + 1; + CheckQuestKill(i, sendmsg); + // Send Fallen Ones running in fear + M_FallenFear(Monst->_mx, Monst->_my); + // Acid demon emits acid pool + if ((EquivMonst(Monst->MType->mtype, MT_NACID)) || + (Monst->MType->mtype == MT_SPIDER2)) + AddMissile(Monst->_mx, Monst->_my, 0, 0, 0, MIT_ACIDPUD, MI_ENEMYPLR, i, Monst->_mint + 1, 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M2MStartKill(int i, int mid) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M2MStartKill: Invalid monster (attacker) %d",i); +#else + return; +#endif + } + if ((DWORD)mid >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M2MStartKill: Invalid monster (killed) %d",mid); +#else + return; +#endif + } + if (monster[i].MType == NULL) + { + //app_fatal("M2MStartKill: Monster %d \"%s\" MType NULL",mid,monster[mid].mName); + return; + } + + int md; + + void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel); + delta_kill_monster(mid, monster[mid]._mx, monster[mid]._my, currlevel); + NetSendCmdLocParam1(FALSE, CMD_MONSTDEATH, monster[mid]._mx, monster[mid]._my, mid); + + monster[mid].mWhoHit |= (1 << i); // Who killed me + if (i < MAX_PLRS) AddPlrMonstExper(monster[mid].mLevel, monster[mid].mExp, monster[mid].mWhoHit); + + ++monstkills[monster[mid].MType->mtype]; + monster[mid]._mhitpoints = 0; + SetRndSeed(monster[mid]._mRndSeed); + + MonstKillEffect(mid, TRUE); +#if 0 + // @@@ needs to be fixed for multiplayer (death not synced, etc) + if (mid >= MAX_PLRS) SpawnItem(mid, monster[mid]._mx, monster[mid]._my, TRUE); +#endif + + if (monster[mid].MType->mtype == MT_DIABLO) { + M_DiabloDeath(mid, TRUE); + } + else + PlayEffect(mid, MS_DEATH); + //PlayEffect(mid, MS_DEATH); + md = (monster[i]._mdir + 4) & 0x07; + if (monster[mid].MType->mtype == MT_GOLEM) md = 0; + monster[mid]._mdir = md; + NewMonsterAnim(mid, monster[mid].MType->Anims[MA_DEATH], md); + monster[mid]._mmode = MM_DEATH; + monster[mid]._mxoff = 0; + monster[mid]._myoff = 0; + monster[mid]._mx = monster[mid]._moldx; + monster[mid]._my = monster[mid]._moldy; + monster[mid]._mfutx = monster[mid]._mx; + monster[mid]._mfuty = monster[mid]._my; + monster[mid]._moldx = monster[mid]._mx; + monster[mid]._moldy = monster[mid]._my; + M_CheckEFlag(mid); + M_ClearSquares(mid); + dMonster[monster[mid]._mx][monster[mid]._my] = mid + 1; + CheckQuestKill(mid, TRUE); + + // Send Fallen Ones running in fear + M_FallenFear(monster[mid]._mx, monster[mid]._my); + // Acid demon emits acid pool + if(EquivMonst(monster[mid].MType->mtype, MT_NACID)) + AddMissile(monster[mid]._mx, monster[mid]._my, 0, 0, 0, MIT_ACIDPUD, MI_ENEMYPLR, mid, monster[mid]._mint + 1, 0); + + M_StartStand(i, monster[i]._mdir); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartKill(int i, int pnum) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined (_DEBUG) + app_fatal("M_StartKill: Invalid monster %d",i); +#else + return; +#endif + } + // Send a message to everyone saying I killed the monster + if (myplr == pnum) { + void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel); + delta_kill_monster(i,monster[i]._mx,monster[i]._my,currlevel); + if (i != pnum) + NetSendCmdLocParam1(FALSE,CMD_MONSTDEATH,monster[i]._mx,monster[i]._my,i); + else + NetSendCmdLocParam1(FALSE,CMD_KILLGOLEM,monster[i]._mx,monster[i]._my,currlevel); + } + + MonstStartKill(i, pnum, TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_SyncStartKill(int i, int x, int y, int pnum) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_SyncStartKill: Invalid monster %d",i); +#else + return; +#endif + } + // Already dead? + if (monster[i]._mhitpoints == 0) return; + if (monster[i]._mmode == MM_DEATH) return; + + app_assert(pnum != myplr); + + if (!dMonster[x][y]) { + M_ClearSquares(i); + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + } + MonstStartKill(i, pnum, FALSE); +// app_assert(dMonster[monster[i]._mx][monster[i]._my] == i+1 +// || dMonster[monster[i]._mx][monster[i]._my] == -(i+1)); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartFadein(int i, int md, BOOL backwards) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_StartFadein: Invalid monster %d",i); +#else + return; +#endif + } + + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_StartFadein: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return; +#endif + } + + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_FADEIN; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + monster[i]._mdir = md; + monster[i]._mFlags &= ~MFLAG_INVISIBLE; + if (backwards) + { + monster[i]._mFlags |= MFLAG_BACKWARDS; + monster[i]._mAnimFrame = monster[i]._mAnimLen; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartFadeout(int i, int md, BOOL backwards) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_StartFadeout: Invalid monster %d",i); +#else + return; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_StartFadeout: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return; +#endif + } + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + monster[i]._mmode = MM_FADEOUT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + monster[i]._mdir = md; + if (backwards) + { + monster[i]._mFlags |= MFLAG_BACKWARDS; + monster[i]._mAnimFrame = monster[i]._mAnimLen; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_StartHeal(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_StartHeal: Invalid monster %d",i); +#else + return; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_StartHeal: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + Monst->_mAnimData = Monst->MType->Anims[MA_SPECIAL].Cels[Monst->_mdir]; + Monst->_mAnimFrame = Monst->MType->Anims[MA_SPECIAL].Frames; + Monst->_mFlags |= MFLAG_BACKWARDS; + Monst->_mmode = MM_HEAL; + Monst->_mVar1 = Monst->_mmaxhp / (16*(random(97, 5)+4)); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_ChangeLightOffset(int monst) +{ + if ((DWORD)monst >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_ChangeLightOffset: Invalid monster %d",monst); +#else + return; +#endif + } + int lx,ly; + int sign; + + lx = (monster[monst]._mxoff + (monster[monst]._myoff << 1)); + ly = ((monster[monst]._myoff << 1) - monster[monst]._mxoff); + + // Divide these values by 8, because lighting offsets have + // 8 subdivisions per tile. + if (lx < 0) + { + sign = -1; + lx = -lx; + } + else + sign = 1; + lx = lx >> 3; + lx *= sign; + + if (ly < 0) + { + sign = -1; + ly = -ly; + } + else + sign = 1; + ly = ly >> 3; + ly *= sign; + + if (monster[monst].mlid != 0) { + ChangeLightOff(monster[monst].mlid, lx, ly); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoStand(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoStand: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoStand: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->MType->mtype == MT_GOLEM) + Monst->_mAnimData = Monst->MType->Anims[MA_WALK].Cels[Monst->_mdir]; + else + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + if (Monst->_mAnimFrame == Monst->_mAnimLen) { + M_Enemy(i); + } + + ++Monst->_mVar2; + return RUN_DONE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoWalk(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoWalk: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoWalk: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + int rv; + + if (monster[i]._mVar8 == monster[i].MType->Anims[MA_WALK].Frames) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mx += monster[i]._mVar1; + monster[i]._my += monster[i]._mVar2; + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + if( !(monster[i]._mFlags & MFLAG_INVISIBLE) + && monster[i].mlid != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + M_StartStand(i, monster[i]._mdir); + rv = RUN_AGAIN; +// DaveMonstMap(FALSE, 0); + } else { + if (monster[i]._mAnimCnt == 0) { + if (monster[i]._mVar8 == 0 && monster[i].MType->mtype == MT_FLESH) + { + PlayEffect(i, MS_SATTACK); + } + ++monster[i]._mVar8; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = RUN_DONE; + } + if( !(monster[i]._mFlags & MFLAG_INVISIBLE) + && monster[i].mlid != 0) + M_ChangeLightOffset(i); + + return (rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoWalk2(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoWalk2: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoWalk2: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + int rv; + + if (monster[i]._mVar8 == monster[i].MType->Anims[MA_WALK].Frames) { + dMonster[monster[i]._mVar1][monster[i]._mVar2] = 0; + if( !(monster[i]._mFlags & MFLAG_INVISIBLE) + && monster[i].mlid != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + M_StartStand(i, monster[i]._mdir); + rv = RUN_AGAIN; +// DaveMonstMap(FALSE, 0); + } else { + if (monster[i]._mAnimCnt == 0) { + if (monster[i]._mVar8 == 0 && monster[i].MType->mtype == MT_FLESH) + { + PlayEffect(i, MS_SATTACK); + } + ++monster[i]._mVar8; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = RUN_DONE; + } + if( !(monster[i]._mFlags & MFLAG_INVISIBLE) + && monster[i].mlid != 0) + M_ChangeLightOffset(i); + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoWalk3(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoWalk3: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoWalk3: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + int rv; + + if (monster[i]._mVar8 == monster[i].MType->Anims[MA_WALK].Frames) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mx = monster[i]._mVar1; + monster[i]._my = monster[i]._mVar2; + dFlags[monster[i]._mVar4][monster[i]._mVar5] &= BFMASK_MONSTLR; + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + if( !(monster[i]._mFlags & MFLAG_INVISIBLE) + && monster[i].mlid != 0) { + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + } + M_StartStand(i, monster[i]._mdir); + rv = RUN_AGAIN; +// DaveMonstMap(FALSE, 0); + } else { + if (monster[i]._mAnimCnt == 0) { + if (monster[i]._mVar8 == 0 && monster[i].MType->mtype == MT_FLESH) + { + PlayEffect(i, MS_SATTACK); + } + ++monster[i]._mVar8; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = RUN_DONE; + } + if(monster[i]._uniqtype && !(monster[i]._mFlags & MFLAG_INVISIBLE)) + M_ChangeLightOffset(i); + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_TryM2MHit(int i, int mid, int hper, int mind, int maxd) +{ + int hit, dam; + BOOL ret; + + if ((DWORD)mid >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_TryM2MHit: Invalid monster %d",mid); +#else + return; +#endif + } + if (monster[mid].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_TryM2MHit: Monster %d \"%s\" MType NULL",mid,monster[mid].mName); +#else + return; +#endif + } + + if ((monster[mid]._mhitpoints >> HP_SHIFT) <= 0) return; + if (monster[mid].MType->mtype == MT_ILLWEAV && monster[mid]._mgoal == MG_RUN_AWAY) return; + + hit = random(4, 100); + if (monster[mid]._mmode == MM_STONE) hit = 0; + + if (CheckMonsterHit(mid, ret)) { + return; + } else { + if (hit < hper) { + dam = random(5, maxd - mind + 1) + mind; + dam = dam << HP_SHIFT; + + monster[mid]._mhitpoints -= dam; + //rjs - x2 stone dam fix - if (monster[mid]._mmode == MM_STONE) monster[mid]._mhitpoints -= dam; + if ((monster[mid]._mhitpoints >> HP_SHIFT) <= 0) { + if (monster[mid]._mmode == MM_STONE) { + M2MStartKill(i, mid); + monster[mid]._mmode = MM_STONE; + } else M2MStartKill(i, mid); + } else { + if (monster[mid]._mmode == MM_STONE) { + M2MStartHit(mid, i, dam); + monster[mid]._mmode = MM_STONE; + } else M2MStartHit(mid, i, dam); + } + } + } + return; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_TryH2HHit: Invalid monster %d",i); +#else + return; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_TryH2HHit: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return; +#endif + } + + int hit, hper, tac; + long dam; + int dx, dy; + int blk, blkper, blkdir; + int mdam; + + if ((monster[i]._mFlags & MFLAG_MID) != 0) { + M_TryM2MHit(i, pnum, Hit, MinDam, MaxDam); + return; + } + + app_assert((DWORD)pnum < MAX_PLRS); + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) return; + if (plr[pnum]._pInvincible) return; + if ((plr[pnum]._pSpellFlags & SF_ETHER) != 0) return; + + dx = abs(monster[i]._mx - plr[pnum]._px); + dy = abs(monster[i]._my - plr[pnum]._py); + if ((dx < 2) && (dy < 2)) { + // Did I hit? + hit = random(98, 100); +#if CHEATS + if (simplecheat || cheatflag) hit = 1000; // TEMP! +#endif + //rjs tac = (byte)plr[pnum]._pArmorClass + plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + + if ((plr[pnum]._pIFlags2 & IAF2_DEMONAC) && + (monster[i].MData->mMonstClass == MC_DEMON)) + tac += 40; + if ((plr[pnum]._pIFlags2 & IAF2_UNDEADAC) && + (monster[i].MData->mMonstClass == MC_UNDEAD)) + tac += 20; + + tac += (plr[pnum]._pDexterity / 5); + hper = 30 + Hit - tac + ((monster[i].mLevel - plr[pnum]._pLevel) << 1); + if (hper < 15) hper = 15; + if ((currlevel == 14) && (hper < 20)) hper = 20; + if ((currlevel == 15) && (hper < 25)) hper = 25; + if ((currlevel == 16) && (hper < 30)) hper = 30; + if (((plr[pnum]._pmode == PM_STAND) || (plr[pnum]._pmode == PM_ATTACK)) && (plr[pnum]._pBlockFlag)) blk = random(98, 100); + else blk = 100; + blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[i].mLevel - plr[pnum]._pLevel) << 1); + if (blkper < 0) blkper = 0; + if (blkper > 100) blkper = 100; + if (hit < hper) { + if (blk < blkper) { + blkdir = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mx, monster[i]._my); + StartPlrBlock(pnum, blkdir); + if (pnum == myplr + && plr[pnum]._pReflectCount > 0) { + --plr[pnum]._pReflectCount; + // Reflect back with 20->30% of the damage. + dam = (MaxDam - MinDam + 1) << HP_SHIFT; + dam = random(99, dam) + (MinDam << HP_SHIFT); + dam += (plr[pnum]._pIGetHit << HP_SHIFT); + if (dam < (1 << HP_SHIFT)) dam = (1 << HP_SHIFT); + mdam = static_cast(dam * (0.01 * (random(100, 10) + 20))); + monster[i]._mhitpoints -= mdam; + dam -= mdam; + if (dam < 0) { + dam = 0; + } + if (monster[i]._mhitpoints >> HP_SHIFT <= 0) { + M_StartKill (i, pnum); + } else { + M_StartHit(i, pnum, mdam); + } + } + + + } else { + + + if (monster[i].MType->mtype == MT_YZOMBIE && pnum == myplr) + { + + // find manashield + int k; + int mi; + int msi = -1; + for (k = 0; k < nummissiles; ++k) { + mi = missileactive[k]; + if (missile[mi]._mitype == MIT_MANASHIELD && missile[mi]._misource == pnum) { + msi = mi; + } + } + + if(plr[pnum]._pMaxHP > 1 << HP_SHIFT ) + { + plr[pnum]._pMaxHP -= 1 << HP_SHIFT; + if(plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + if( msi >= 0 ) + missile[msi]._miVar1 = plr[pnum]._pHitPoints; + } + plr[pnum]._pMaxHPBase -= 1 << HP_SHIFT; + if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) { + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + if( msi >= 0 ) + missile[msi]._miVar2 = plr[pnum]._pHPBase; + } + } + + + } + + + + dam = (MaxDam - MinDam + 1) << HP_SHIFT; + dam = random(99, dam) + (MinDam << HP_SHIFT); + dam += (plr[pnum]._pIGetHit << HP_SHIFT); + if (dam < (1 << HP_SHIFT)) dam = (1 << HP_SHIFT); + if (pnum == myplr) { + if (plr[pnum]._pReflectCount > 0) + { + --plr[pnum]._pReflectCount; + // Reflect back with 20->30% of the damage. + mdam = static_cast(dam * (0.01 * (random(100, 10) + 20))); + monster[i]._mhitpoints -= mdam; + dam -= mdam; + if (dam < 0) { + dam = 0; + } + if (monster[i]._mhitpoints >> HP_SHIFT <= 0) { + M_StartKill (i, pnum); + } else { + M_StartHit(i, pnum, mdam); + } + } + + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + } + + + + + if (plr[pnum]._pIFlags & IAF_THORN) { + mdam = ((random (99, 3) + 1) << HP_SHIFT); + monster[i]._mhitpoints -= mdam; + if (monster[i]._mhitpoints >> HP_SHIFT <= 0) { + M_StartKill (i, pnum); + //(old) AddPlrExperience(pnum, monster[i].mLevel, monster[i].mExp); + //(new, but moved) AddPlrMonstExper(monster[i].mLevel, monster[i].mExp, monster[i].mWhoHit); + } else { + M_StartHit(i, pnum, mdam); + } + } + if (!(monster[i]._mFlags & IAF_MNOHEAL)) { + if (monster[i].MType->mtype == MT_SKING + && gbMaxPlayers != 1) + monster[i]._mhitpoints += dam; + } + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - plr[pnum]._pHitPoints = 0; + StartPlrKill(pnum, FALSE); + M_StartStand(i, monster[i]._mdir); + } else { + StartPlrHit(pnum, dam, FALSE); + + if (monster[i]._mFlags & MFLAG_KNOCKBACK) { + // make sure player is doing a hit animation + if (plr[pnum]._pmode != PM_GOTHIT) + StartPlrHit(pnum, 0, TRUE); + + // knock back enemy one square + int newx,newy,oldx,oldy; + + oldx = plr[pnum]._px; + oldy = plr[pnum]._py; + newx = oldx + offset_x[monster[i]._mdir]; + newy = oldy + offset_y[monster[i]._mdir]; + if(PosOkPlayer(pnum, newx, newy)) + { + plr[pnum]._px = newx; + plr[pnum]._py = newy; + FixPlayerLocation(pnum,plr[pnum]._pdir); + FixPlrWalkTags(pnum); + dPlayer[newx][newy] = pnum + 1; + SetPlayerOld(pnum); + } + } + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoAttack: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mAnimFrame == Monst->MData->mAFNum) { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit, Monst->mMinDamage, Monst->mMaxDamage); + if (Monst->_mAi != AI_SNAKE) + PlayEffect(i, MS_ATTACK); + } + // Special code for Magma -- second punch + if (EquivMonst(Monst->MType->mtype, MT_NMAGMA) + && Monst->_mAnimFrame == 9) + { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit+10, Monst->mMinDamage-2, Monst->mMaxDamage-2); + PlayEffect(i, MS_ATTACK); + } + // Special code for Storm -- second punch + if (EquivMonst(Monst->MType->mtype, MT_STORM) + && Monst->_mAnimFrame == 13) + { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit-20, Monst->mMinDamage+4, Monst->mMaxDamage+4); + PlayEffect(i, MS_ATTACK); + } + // Special code for Snake -- play sound before attack frame + if (Monst->_mAi == AI_SNAKE && Monst->_mAnimFrame == 1) + PlayEffect(i, MS_ATTACK); + + if (Monst->_mAnimFrame == Monst->_mAnimLen) { + M_StartStand(i, Monst->_mdir); + return(RUN_AGAIN); + } else return (RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoRAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoRAttack: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoRAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoRAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + int multimissiles; + int mi; + + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum) { + if (monster[i]._mVar1 != -1) + { + if (monster[i]._mVar1 == MIT_CBOLT) + multimissiles = 3; + else + multimissiles = 1; + for (mi = 0; mi < multimissiles; ++mi) // special loop code to handle CBOLT, which must be cast 3 times + AddMissile(monster[i]._mx + infront_x[monster[i]._mdir], + monster[i]._my + infront_y[monster[i]._mdir], + monster[i]._menemyx, monster[i]._menemyy, monster[i]._mdir, monster[i]._mVar1, MI_ENEMYPLR, i, monster[i]._mVar2, 0); + } + PlayEffect(i, MS_ATTACK); + } + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return (RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoRSpAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoRSpAttack: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoRSpAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoRSpAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum2 && !monster[i]._mAnimCnt) { + AddMissile(monster[i]._mx + infront_x[monster[i]._mdir], + monster[i]._my + infront_y[monster[i]._mdir], + monster[i]._menemyx, monster[i]._menemyy, monster[i]._mdir, monster[i]._mVar1, MI_ENEMYPLR, i, monster[i]._mVar3, 0); + if (Monsters[i].Snds[MS_SATTACK].effect[0] != 0){ + PlayEffect(i, MS_SATTACK); + } + } + + // special code for Mega demon -- hold attack animation frame + if (monster[i]._mAi == AI_MEGA && monster[i]._mAnimFrame == 3) + { + if (!monster[i]._mVar2++) + monster[i]._mFlags |= MFLAG_STILL; + else if (monster[i]._mVar2 == 15) + monster[i]._mFlags &= ~MFLAG_STILL; + } + + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return (RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoSAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoSAttack: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoSAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoSAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum2) + M_TryH2HHit(i, monster[i]._menemy, monster[i].mHit2, monster[i].mMinDamage2, monster[i].mMaxDamage2); + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoFadein(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoFadein: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if ((monster[i]._mFlags & MFLAG_BACKWARDS && monster[i]._mAnimFrame == 1) + || (!(monster[i]._mFlags & MFLAG_BACKWARDS) && monster[i]._mAnimFrame == monster[i]._mAnimLen)) + { + M_StartStand(i, monster[i]._mdir); + monster[i]._mFlags &= ~MFLAG_BACKWARDS; + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoFadeout(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoFadeout: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + int mtype; + if ((monster[i]._mFlags & MFLAG_BACKWARDS && monster[i]._mAnimFrame == 1) + || (!(monster[i]._mFlags & MFLAG_BACKWARDS) && monster[i]._mAnimFrame == monster[i]._mAnimLen)) + { + app_assert(monster[i].MType != NULL); + mtype = monster[i].MType->mtype; + if (EquivMonst(mtype, MT_INCIN)) + monster[i]._mFlags &= ~MFLAG_BACKWARDS; + else + { + monster[i]._mFlags &= ~MFLAG_BACKWARDS; + monster[i]._mFlags |= MFLAG_INVISIBLE; + } + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoHeal(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoHeal: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (monster[i]._mFlags & MFLAG_NOHEAL) return RUN_DONE; + // Gargoyle turning back to stone + if(Monst->_mAnimFrame == 1) + { + Monst->_mFlags &= ~MFLAG_BACKWARDS; + Monst->_mFlags |= MFLAG_STILL; + if(Monst->_mhitpoints + Monst->_mVar1 < Monst->_mmaxhp) + Monst->_mhitpoints += Monst->_mVar1; + else + { + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->_mFlags &= ~MFLAG_STILL; + Monst->_mmode = MM_SATTACK; + } + } + return RUN_DONE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +int M_DoTalk(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoTalk: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + MonsterStruct *Monst = &monster[i]; + + M_StartStand(i, monster[i]._mdir); + Monst->_mgoal=MG_WAITTOTALK; + if (effect_is_playing(alltext[monster[i].mtalkmsg].sfxnr)) return RUN_DONE; + InitQTextMsg(monster[i].mtalkmsg); + if (monster[i].mName == UniqMonst[MU_GARBUD].mName) { + if (monster[i].mtalkmsg == TXT_GARB1) + quests[Q_GARBUD]._qactive = QUEST_NOTDONE; + quests[Q_GARBUD]._qlog = TRUE; + if (monster[i].mtalkmsg == TXT_GARB2) { + if(!(monster[i]._mFlags & MFLAG_DROP)) { + SpawnItem(i, monster[i]._mx+1, monster[i]._my+1, TRUE); + monster[i]._mFlags |= MFLAG_DROP; + } + } + } + if (monster[i].mName == UniqMonst[MU_ZHAR].mName) { + if (monster[i].mtalkmsg == TXT_ZHAR1) { + if(!(monster[i]._mFlags & MFLAG_DROP)) { + quests[Q_ZHAR]._qactive = QUEST_NOTDONE; + quests[Q_ZHAR]._qlog = TRUE; + CreateTypeItem(monster[i]._mx+1, monster[i]._my+1, FALSE, IT_MISC, IMID_BOOK, TRUE, FALSE); + monster[i]._mFlags |= MFLAG_DROP; + } + } + } + if (monster[i].mName == UniqMonst[MU_SNOTSPIL].mName) { + if ((monster[i].mtalkmsg == TXT_BOL1) && (!(monster[i]._mFlags & MFLAG_DROP))) { + app_assert(setpc_x != 0); + ObjChangeMap(setpc_x, setpc_y, setpc_x+(setpc_w>>1)+2, setpc_y+(setpc_h>>1)-2); + int const tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, setpc_x+(setpc_w>>1)+4, setpc_y+(setpc_h>>1)); + TransVal = tren; + quests[Q_LTBANNER]._qvar1 = 2; + if (quests[Q_LTBANNER]._qactive == QUEST_NOTACTIVE) quests[Q_LTBANNER]._qactive = QUEST_NOTDONE; + monster[i]._mFlags |= MFLAG_DROP; + } + if (quests[Q_LTBANNER]._qvar1 < 2) { + sprintf(tempstr, "SS Talk = %i, Flags = %i", monster[i].mtalkmsg, monster[i]._mFlags); + app_fatal(tempstr); + } + } + if (monster[i].mName == UniqMonst[MU_LACHDA].mName) { + if (monster[i].mtalkmsg == TXT_VEIL1) { + quests[Q_VEIL]._qactive = QUEST_NOTDONE; + quests[Q_VEIL]._qlog = TRUE; + } + if ((monster[i].mtalkmsg == TXT_VEIL3) && (!(monster[i]._mFlags & MFLAG_DROP))) { + SpawnUnique(UID_STEELVEIL, monster[i]._mx+1, monster[i]._my+1); + monster[i]._mFlags |= MFLAG_DROP; + } + } + if (monster[i].mName == UniqMonst[MU_WARLORD].mName) { + app_assert(gbMaxPlayers == 1); + quests[Q_WARLORD]._qvar1 = 2; + } + if ((monster[i].mName == UniqMonst[MU_LAZARUS].mName) && (gbMaxPlayers != 1)) { + quests[Q_BETRAYER]._qvar1 = 6; + monster[i]._mgoal = MG_ATTACK; + monster[i]._msquelch = 255; + monster[i].mtalkmsg = 0; + } + return RUN_DONE; +} + +/*-----------------------------------------------------------------------* + * M_Teleport + * + * Teleports monster i to one of it's enemy's 8 adjacent squares. +**----------------------------------------------------------------------*/ + +void M_Teleport(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_Teleport: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + BOOL done = FALSE; + int mulx,muly; + int x,y; + int a,b; + int px,py; + + if (Monst->_mmode == MM_STONE) + return; + + px = Monst->_menemyx; + py = Monst->_menemyy; + + // randomize search direction + mulx = random(100,2)*2-1; + muly = random(100,2)*2-1; + for(a = -1; a <= 1 && !done; ++a) + for(b = -1; b < 1 && !done; ++b) + if(a || b) + { + x = px + a*mulx; + y = py + b*muly; + if(InBounds(x,y) + && x != Monst->_mx && y != Monst->_my) + if(PosOkMonst(i,x,y)) + done = TRUE; + } + if(done) + { + M_ClearSquares(i); + app_assert((DWORD)Monst->_mx < MAXDUNX); + app_assert((DWORD)Monst->_my < MAXDUNY); + dMonster[Monst->_mx][Monst->_my] = 0; + dMonster[x][y] = i+1; + // M_StartHit knocks monster back to oldx,oldy, so those are the members to set + Monst->_moldx = x; + Monst->_moldy = y; + Monst->_mdir = M_GetDir(i); + M_CheckEFlag(i); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoGotHit(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoGotHit: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoGotHit: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_UpdateLeader(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_UpdateLeader: Invalid monster %d",i); +#else + return; +#endif + } + int x,tmp; + + // check for pack leader + if(monster[i]._uniqtype && (UniqMonst[monster[i]._uniqtype-1].mUnqAttr & UN_STICK)) + // free the pack + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for(x = 0; x < nummonsters; ++x) + { + if(monster[tmp=monstactive[x]].leaderflag == PACK_MEMBER + && monster[tmp].leader == i) + { + monster[tmp].leaderflag = 0; + } + } + // check for pack member + if(monster[i].leaderflag == PACK_MEMBER) + --monster[monster[i].leader].packsize; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void play_movie(const char * pszMovie,BOOL bAllowCancel); +extern BOOL gbRunGame; +extern BOOL deathflag; +extern BYTE gbDoEnding; + +void DoEnding() { + // tell other players to view victory + if (gbMaxPlayers > 1) SNetLeaveGame(SNET_EXIT_PLAYERWON); + + //SetCursor(NO_CURSOR); + //FullBlit(TRUE); + //PaletteFadeOut(FADE_FAST); + music_stop(); + + // give SNet some more time to field messages + if (gbMaxPlayers > 1) Sleep(1000); + + #if !IS_VERSION(SHAREWARE) + LONG lMusicVol; + BOOL bMusicOn; + if (plr[myplr]._pClass == CLASS_WARRIOR + || plr[myplr]._pClass == CLASS_BARBARIAN) play_movie("gendata\\DiabVic2.smk",FALSE); + else if (plr[myplr]._pClass == CLASS_SORCEROR) play_movie("gendata\\DiabVic1.smk",FALSE); + else if (plr[myplr]._pClass == CLASS_MONK) play_movie("gendata\\DiabVic1.smk",FALSE); + else play_movie("gendata\\DiabVic3.smk",FALSE); + play_movie("gendata\\Diabend.smk",FALSE); + + // turn music to full volume + bMusicOn = gbMusicOn; + gbMusicOn = TRUE; + lMusicVol = music_volume(VOLUME_READ); + music_volume(VOLUME_MAX); + music_start(MUSIC_L2); + + extern BOOL gbLoopMovie; + gbLoopMovie = TRUE; + play_movie("gendata\\loopdend.smk",TRUE); + gbLoopMovie = FALSE; + #endif + + //ClrDraw(); + //FullBlit(FALSE); + //PaletteFadeOut(FADE_FAST); + + // restore music volume + #if !IS_VERSION(SHAREWARE) + music_stop(); + music_volume(lMusicVol); + gbMusicOn = bMusicOn; + #endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrepDoEnding() { + // enable sound again + gbSoundOn = sgbSaveSoundOn; + gbDoEnding = TRUE; + gbRunGame = FALSE; + deathflag = FALSE; + + app_assert((DWORD)myplr < MAX_PLRS); + plr[myplr].pDiabloKillLevel = max( + plr[myplr].pDiabloKillLevel, + (DWORD) gnDifficulty + 1 + ); + + for (int i = 0; i < MAX_PLRS; ++i) { + plr[i]._pmode = PM_QUIT; + plr[i]._pInvincible = TRUE; + if (gbMaxPlayers > 1) { + if ((plr[i]._pHitPoints >> HP_SHIFT) == 0) + plr[i]._pHitPoints = 1 << HP_SHIFT; + if ((plr[i]._pMana >> MANA_SHIFT) == 0) + plr[i]._pMana = 1 << MANA_SHIFT; + } + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int M_DoDeath(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoDeath: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoDeath: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + ++monster[i]._mVar1; + if (monster[i].MType->mtype == MT_DIABLO) { + ViewX += Sign(monster[i]._mx - ViewX); + ViewY += Sign(monster[i]._my - ViewY); + if (monster[i]._mVar1 == 140) { + PrepDoEnding(); + } + } else { + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + if (monster[i]._uniqtype == 0) + AddDead(monster[i]._mx, monster[i]._my, monster[i].MType->mdeadval, monster[i]._mdir); + else + AddDead(monster[i]._mx, monster[i]._my, monster[i]._udeadval, monster[i]._mdir); + app_assert(!(dFlags[monster[i]._mx+1][monster[i]._my] & BFLAG_MONSTLR) + && !(dFlags[monster[i]._mx][monster[i]._my+1] & BFLAG_MONSTLR)); + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mDelFlag = TRUE; + M_UpdateLeader(i); + } + } + return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoSpStand(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoSpStand: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoSpStand: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum2) { + PlayEffect(i, MS_SATTACK); + } + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +int M_DoDelay(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoDelay: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_DoDelay: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return RUN_DONE; +#endif + } + int md; + + md = M_GetDir(i); + monster[i]._mAnimData = monster[i].MType->Anims[MA_STAND].Cels[md]; + if (monster[i]._mAi == AI_LAZURUS) { + if ((monster[i]._mVar2 > 8) || (monster[i]._mVar2 < 0)) monster[i]._mVar2 = 8; + } + if(!monster[i]._mVar2--) + { + int tmp = monster[i]._mAnimFrame; + M_StartStand(i, monster[i]._mdir); // StartStand sets AnimFrame to 0 + monster[i]._mAnimFrame = tmp; // restore AnimFrame to avoid pop + // in case monster continues standing. + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoStone(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_DoStone: Invalid monster %d",i); +#else + return RUN_DONE; +#endif + } + if (monster[i]._mhitpoints == 0) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mDelFlag = TRUE; + } + return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_WalkDir(int i, int md) +{ + int mwi; + + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_WalkDir: Invalid monster %d",i); +#else + return; +#endif + } + mwi = monster[i].MType->Anims[MA_WALK].Frames - 1; + + switch (md) { + case M_DIRU : + M_StartWalk(i, 0, -MWVel[mwi][1], -1, -1, M_DIRU); + break; + case M_DIRUR : + M_StartWalk(i, MWVel[mwi][1], -MWVel[mwi][0], 0, -1, M_DIRUR); + break; + case M_DIRR : + M_StartWalk3(i, MWVel[mwi][2], 0, -32, -16, 1, -1, 1, 0, M_DIRR); + break; + case M_DIRDR : + M_StartWalk2(i, MWVel[mwi][1], MWVel[mwi][0], -32, -16, 1, 0, M_DIRDR); + break; + case M_DIRD : + M_StartWalk2(i, 0, MWVel[mwi][1], 0, -32, 1, 1, M_DIRD); + break; + case M_DIRDL : + M_StartWalk2(i, -MWVel[mwi][1], MWVel[mwi][0], 32, -16, 0, 1, M_DIRDL); + break; + case M_DIRL : + M_StartWalk3(i, -MWVel[mwi][2], 0, 32, -16, -1, 1, 0, 1, M_DIRL); + break; + case M_DIRUL : + M_StartWalk(i, -MWVel[mwi][1], -MWVel[mwi][0], -1 ,0, M_DIRUL); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GroupUnity(int i) +{ + int leader; + int tmp; + int m; + + // + // IMPLEMENT GROUP COHESION + // + + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("GroupUnity: Invalid monster %d",i); +#else + return; +#endif + } + if(monster[i].leaderflag) + { + leader = monster[i].leader; + + // test if there's a wall between monst and pack leader + tmp = LineClearF(CheckNoSolid, monster[i]._mx, monster[i]._my, + monster[leader]._mfutx, monster[leader]._mfuty); + if(!tmp && monster[i].leaderflag == PACK_MEMBER) + { + // have to leave pack + --monster[leader].packsize; + monster[i].leaderflag = PACK_NOMEMBER; + } + else if(tmp && monster[i].leaderflag == PACK_NOMEMBER + && DIST(monster[i]._mx - monster[leader]._mfutx, + monster[i]._my - monster[leader]._mfuty, 4)) + { + // rejoin pack + ++monster[leader].packsize; + monster[i].leaderflag = PACK_MEMBER; + } + } + + if(monster[i].leaderflag == PACK_MEMBER) + { + // make sure leader is active + if(monster[i]._msquelch > monster[leader]._msquelch) + { + monster[leader]._lastx = monster[i]._mx; + monster[leader]._lasty = monster[i]._my; + monster[leader]._msquelch = monster[i]._msquelch-1; + } + if (monster[leader]._mAi == AI_GARG && (monster[leader]._mFlags & MFLAG_STILL)) { + monster[leader]._mFlags &= ~MFLAG_STILL; + monster[leader]._mmode = MM_SATTACK; + } + } + else if(monster[i]._uniqtype && (UniqMonst[monster[i]._uniqtype-1].mUnqAttr & UN_STICK)) + { + // make sure all of pack is activated + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for(m = 0; m < nummonsters; ++m) + { + if(monster[tmp=monstactive[m]].leaderflag == PACK_MEMBER + && monster[tmp].leader == i) + { + if(monster[i]._msquelch > monster[tmp]._msquelch) + { + monster[tmp]._lastx = monster[i]._mx; + monster[tmp]._lasty = monster[i]._my; + monster[tmp]._msquelch = monster[i]._msquelch-1; + } + if (monster[tmp]._mAi == AI_GARG && (monster[tmp]._mFlags & MFLAG_STILL)) { + monster[tmp]._mFlags &= ~MFLAG_STILL; + monster[tmp]._mmode = MM_SATTACK; + } + } + } + } + // END OF GROUP COHESION +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_CallWalk(int i, int md) +{ + int mdtemp = md; + BOOL ok = FALSE; + ok = DirOK(i,md); + + if(random(101,2)) + ok = ok || DirOK(i, md = left[mdtemp]) || DirOK(i, md = right[mdtemp]); + else + ok = ok || DirOK(i, md = right[mdtemp]) || DirOK(i, md = left[mdtemp]); + + if(random(102,2)) + ok = ok || DirOK(i, md = right[right[mdtemp]]) || DirOK(i, md = left[left[mdtemp]]); + else + ok = ok || DirOK(i, md = left[left[mdtemp]]) || DirOK(i, md = right[right[mdtemp]]); + + if(ok) + M_WalkDir(i, md); + + return ok; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_PathWalk(int i) +{ + char path[MAXPATHLEN]; + static const char plr2monst[] = { 0, 5, 3, 7, 1, 4, 6, 0, 2 }; + + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_PathWalk: Invalid monster %d",i); +#else + return FALSE; +#endif + } + CHECKFUNC1 Check = (monster[i]._mFlags & MFLAG_CHECKDOORS) ? PosOkMonst3:PosOkMonst; + + int pathlen = FindPath(Check, i, monster[i]._mx, monster[i]._my, + monster[i]._menemyx, monster[i]._menemyy, + path); + if(pathlen) { + M_CallWalk(i, plr2monst[path[0]]); + return TRUE; + } + else + return FALSE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_CallWalk2(int i, int md) +{ + int mdtemp = md; + BOOL ok = FALSE; + ok = DirOK(i,md); + + if(random(101,2)) + ok = ok || DirOK(i, md = left[mdtemp]) || DirOK(i, md = right[mdtemp]); + else + ok = ok || DirOK(i, md = right[mdtemp]) || DirOK(i, md = left[mdtemp]); + + if(ok) + M_WalkDir(i, md); + + return ok; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_DumbWalk(int i, int md) +{ + BOOL ok; + + ok = DirOK(i,md); + + if(ok) + M_WalkDir(i, md); + return ok; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_RoundWalk(int i, int md, int &dir) +{ + int mdtemp; + BOOL ok = FALSE; + + if(dir) + md = left[left[md]]; + else + md = right[right[md]]; + mdtemp = md; + + ok = DirOK(i,md); + if(!ok) + { + // Note: The use of || below is a trick: the second condition is not evaluated + // (and therefore md is not re-set) if the first condition evaluates TRUE. + + if(dir) + ok = DirOK(i, md = right[mdtemp]) || DirOK(i, md = right[right[mdtemp]]); + else + ok = DirOK(i, md = left[mdtemp]) || DirOK(i, md = left[left[mdtemp]]); + } + + if(ok) + M_WalkDir(i,md); + else + { + // Note: The value of md here is set according to the second condition of the + // || operators above. Therefore, md is, by design, the direction towards + // the player. + dir = !dir; + ok = M_CallWalk(i,opposite[mdtemp]); + } + return ok; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_Face(int i) +{ + int md; + + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("M_Face: Invalid monster %d",i); +#else + return; +#endif + } + if (monster[i]._msquelch) { + md = M_GetDir(i); + monster[i]._mdir = md; + if (monster[i].MType == NULL) + { +#if defined(_DEBUG) + app_fatal("M_Face: Monster %d \"%s\" MType NULL",i,monster[i].mName); +#else + return; +#endif + } + monster[i]._mAnimData = monster[i].MType->Anims[MA_STAND].Cels[md]; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Zombie(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Zombie: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int mx, my, md, v; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx -= Monst->_menemyx; + my -= Monst->_menemyy; + md = Monst->_mdir; + v = random(103,100); + + // Try attack + if (DIST(mx,my,2)) { + if (v < (10 + 2*Monst->_mint)) M_StartAttack(i); + } else { + // Try walk + if (v < (10 + 2*Monst->_mint)) { + // Check on distance from player + if(DIST(mx,my,4+2*Monst->_mint)) { + md = M_GetDir(i); + M_CallWalk(i, md); + } else { + if(random(104,100) < (20 + 2*Monst->_mint)) md = random(104,8); + M_DumbWalk(i, md); + } + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SkelSd(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_SkelSd: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int mx, my, md; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + // Try attack + if (DIST(mx,my,2)) { + if (Monst->_mVar1 == MM_DELAY || random(105,100) < 20 + 2*Monst->_mint) + M_StartAttack(i); + else + M_StartDelay(i, random(105,10)+10 - 2*Monst->_mint); + } else { + // Try walk -- more likely to walk if already walking + if ((Monst->_mVar1 != MM_DELAY) && random(106,100) < 35 - 4*Monst->_mint) + M_StartDelay(i, random(106,10) + 15 - 2*Monst->_mint); + else + M_CallWalk(i, md); + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL MAI_Path(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Path: Invalid monster %d",i); +#else + return FALSE; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if ((Monst->MType->mtype != MT_GOLEM) // golum always ready to walk + && ((!Monst->_msquelch) + || (Monst->_mmode != MM_STAND) + || !(Monst->_mgoal == MG_ATTACK + || Monst->_mgoal == MG_WALK_AROUND1 + || Monst->_mgoal == MG_ATTACK2) + || (Monst->_mx == 1 && Monst->_my == 0))) // inactive golum + return FALSE; + if (!LineClearF1(PosOkMonst2, i,Monst->_mx,Monst->_my,Monst->_menemyx,Monst->_menemyy) + || (Monst->_pathcount >= 5 && Monst->_pathcount < 8)) + { + // Try Opening Door + if (Monst->_mFlags & MFLAG_CHECKDOORS) + MonstCheckDoors(i); + + if (++Monst->_pathcount >= 5) + { + if (M_PathWalk(i)) + return TRUE; + } + else // don't want to zero pathcount + return FALSE; + } + + if (Monst->MType->mtype != MT_GOLEM) Monst->_pathcount = 0; //path count for golum handled in ai + return FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Snake(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Snake: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int fx, fy, mx, my, md, pnum; + char pattern[] = { +1, +1, 0, -1, -1 , 0}; + int tmp; + + pnum = Monst->_menemy; + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + // Try attack + if (DIST(mx,my,2)) { + if (Monst->_mVar1 == MM_DELAY + || Monst->_mVar1 == MM_MISSILE + || random(105,100) < 20 + 1*Monst->_mint) + M_StartAttack(i); + else + M_StartDelay(i, random(105,10)+10 - 1*Monst->_mint); + } + else if (DIST(mx,my,3) + && LineClearF1(PosOkMonst, i,Monst->_mx,Monst->_my,fx,fy) + && Monst->_mVar1 != MM_MISSILE) + { + // Launch snake + if (AddMissile(Monst->_mx, Monst->_my, fx,fy, md, MIT_RHINO, pnum, i, 0, 0) != -1) { + PlayEffect(i, MS_ATTACK); + dMonster[Monst->_mx][Monst->_my] = -(i+1); + Monst->_mmode = MM_MISSILE; + } + } else { + // Try walk -- more likely to walk if already walking + if ((Monst->_mVar1 != MM_DELAY) && random(106,100) < 35 - 2*Monst->_mint) + M_StartDelay(i, random(106,10) + 15 - 1*Monst->_mint); + else + { + md = Mod(md + pattern[Monst->_mgoalvar1], 8); + if (++Monst->_mgoalvar1 > 5) + Monst->_mgoalvar1 = 0; + tmp = Mod(md - Monst->_mgoalvar2, 8); + if (tmp > 0) + { + if (tmp < 4) + Monst->_mgoalvar2 = Mod(Monst->_mgoalvar2 + 1, 8); + else if (tmp == 4) + Monst->_mgoalvar2 = md; + else + Monst->_mgoalvar2 = Mod(Monst->_mgoalvar2 - 1, 8); + } + app_assert(Monst->_mgoalvar2 >= 0 && Monst->_mgoalvar2 < 8); + if (!M_DumbWalk(i, Monst->_mgoalvar2)) + M_CallWalk2(i, Monst->_mdir); + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Bat(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Bat: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int mx, my, md, v, pnum; + int fx, fy; + + pnum = Monst->_menemy; + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + v = random(107,100); + if(Monst->_mgoal == MG_RUN_AWAY) + { + if(!Monst->_mgoalvar1) + { + M_CallWalk(i, opposite[md]); + ++Monst->_mgoalvar1; + } + else + { + if(random(108,2)) + M_CallWalk(i, left[md]); + else + M_CallWalk(i, right[md]); + Monst->_mgoal = MG_ATTACK; + } + } + else + { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + // Try attack + if ((Monst->MType->mtype == MT_GLOOM) + && (!DIST(mx,my,5) && v < 33 + 4*Monst->_mint) && + LineClearF1(PosOkMonst, i,Monst->_mx,Monst->_my,fx,fy)) + { + // Turn into missile + if (AddMissile(Monst->_mx, Monst->_my, fx, fy, md, MIT_RHINO, pnum, i, 0, 0) != -1) { + dMonster[Monst->_mx][Monst->_my] = -(i+1); + Monst->_mmode = MM_MISSILE; + } + } + else if (DIST(mx,my,2)) { + if (v < 8 + 4*Monst->_mint) + { + M_StartAttack(i); + + // After attacking, fly away + Monst->_mgoal = MG_RUN_AWAY; + Monst->_mgoalvar1 = 0; + + if(Monst->MType->mtype == MT_FAMILIAR) { + // Note: arg 5 is a signal to the lightning code. + // The code checks if this is != to arg 1, and if so, checks for + // collision. Normally, collision is only checked for when + // lightning moves, but in this case it won't move! + AddMissile(Monst->_menemyx, Monst->_menemyy, Monst->_menemyx+1, 0, -1, MIT_LIGHTNING, MI_ENEMYPLR, i, random(109,10)+1, 0); + } + } + } else { + // Try walk + if ((Monst->_mVar2 > 20 && v < (13 + Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (63 + Monst->_mint))) { + M_CallWalk(i, md); + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SkelBow(int i) +{ + int mx, my, md, fx, fy; + BOOL walking = FALSE; + int v; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_SkelBow: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = M_GetDir(i); + Monst->_mdir = md; + + // Try walk + v = random(110,100); + if (DIST(mx,my,4) + && + ((Monst->_mVar2 > 20 + && v < 13 + 2*Monst->_mint) + || (WALKMODE(Monst->_mVar1) + && Monst->_mVar2 == 0 + && v < 63 + 2*Monst->_mint))) + { + walking = M_DumbWalk(i, opposite[md]); + } + fx = Monst->_menemyx; + fy = Monst->_menemyy; + if (!walking && (random(110,100) < 3+2*Monst->_mint) && + LineClear(Monst->_mx,Monst->_my,fx, fy)) + { + // Try attack + M_StartRAttack(i,MIT_ARROW,4); + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Fat(int i) +{ + int mx, my, md, v; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Fat: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = M_GetDir(i); + Monst->_mdir = md; + v = random(111,100); + // Try attack + if (DIST(mx,my,2)) { + if (v < (15 + 4*Monst->_mint)) M_StartAttack(i); + else if (v < (20 + 4*Monst->_mint)) M_StartSpAttack(i); + } else { + // Try walk + if ((Monst->_mVar2 > 20 && v < (20 + 4*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (70 + 4*Monst->_mint))) { + M_CallWalk(i, md); + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Sneak(int i) +{ + int mx, my, md, v; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Sneak: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int dist; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + if (dLight[mx][my] != lightmax) { + + mx -= Monst->_menemyx; + my -= Monst->_menemyy; + md = M_GetDir(i); + + dist = 5 - Monst->_mint; + + // If gothit, run away + if(Monst->_mVar1 == MM_GOTHIT) + { + Monst->_mgoal = MG_RUN_AWAY; + Monst->_mgoalvar1 = 0; // count run_away moves + } + // if far away enough, stop running away + else if(!DIST(mx,my,dist+3) || Monst->_mgoalvar1 > 8) + { + Monst->_mgoal = MG_ATTACK; + Monst->_mgoalvar1 = 0; + } + + if(Monst->_mgoal == MG_RUN_AWAY && !(Monst->_mFlags & MFLAG_NOENEMY)) + { + // Use special "owner location", i.e. the location of the player + // according to the computer which owns the player + // This is an attempt to reduce the amount of monster warping due to + // diverging paths on different computers + if (Monst->_mFlags & MFLAG_MID) { + md = GetDirection(Monst->_mx, Monst->_my, + monster[Monst->_menemy]._mx, monster[Monst->_menemy]._my); + } + else { + md = GetDirection(Monst->_mx, Monst->_my, + plr[Monst->_menemy]._pownerx, plr[Monst->_menemy]._pownery); + } + md = opposite[md]; + if(Monst->MType->mtype == MT_UNSEEN) + { + if(random(112,2)) + md = left[md]; + else + md = right[md]; + } + } + + Monst->_mdir = md; + + v = random(112,100); + // become visible + if(DIST(mx,my,dist) && (Monst->_mFlags & MFLAG_INVISIBLE)) + M_StartFadein(i,md,FALSE); + // become invisible + else if(!DIST(mx,my,dist+1) && !(Monst->_mFlags & MFLAG_INVISIBLE)) + M_StartFadeout(i,md,TRUE); + // Try attack + else if ((Monst->_mgoal == MG_RUN_AWAY) + || + ( !DIST(mx,my,2) + && + ((Monst->_mVar2 > 20 && v < (14 + 4*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (64 + 4*Monst->_mint))))) { + // Try walk + ++Monst->_mgoalvar1; + M_CallWalk(i, md); + } + // face dir + if (Monst->_mmode == MM_STAND) + { + if (DIST(mx,my,2) && (v < (10 + 4*Monst->_mint))) { + M_StartAttack(i); + } + else + { + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Fireman(int i) +{ + int mx, my, md, v, pnum; + int fx, fy; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Fireman: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND && Monst->_msquelch) { + pnum = Monst->_menemy; + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = M_GetDir(i); + + if(Monst->_mgoal == MG_ATTACK) + { + if(LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Launch monster missile + if (AddMissile(Monst->_mx, Monst->_my, fx,fy, md, MIT_FIREMAN, pnum, i, 0, 0) != -1) { + Monst->_mmode = MM_MISSILE; + Monst->_mgoal = MG_ATTACK2; + Monst->_mgoalvar1 = 0; + } + } + } + else if(Monst->_mgoal == MG_ATTACK2) + { + if(Monst->_mgoalvar1 == 3) + { + Monst->_mgoal = MG_ATTACK; + M_StartFadeout(i,md,TRUE); + } + else if(LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Try attack + M_StartRAttack(i,MIT_KRULL,4); + ++Monst->_mgoalvar1; + } + else + { + M_StartDelay(i, random(112,10) + 5); + ++Monst->_mgoalvar1; + } + } + + else if(Monst->_mgoal == MG_RUN_AWAY) + { + M_StartFadein(i, md,FALSE); + Monst->_mgoal = MG_ATTACK2; + } + + Monst->_mdir = md; + + v = random(112,100); + + if(Monst->_mmode == MM_STAND) + { + if(DIST(mx,my,2) && Monst->_mgoal == MG_ATTACK) + { + M_TryH2HHit(i, monster[i]._menemy, monster[i].mHit, monster[i].mMinDamage, monster[i].mMaxDamage); + Monst->_mgoal = MG_RUN_AWAY; + if(!M_CallWalk(i, opposite[md])) + { + M_StartFadein(i, md,FALSE); + Monst->_mgoal = MG_ATTACK2; + } + } + else + { + if(!M_CallWalk(i, md)) + { + if(Monst->_mgoal == MG_ATTACK || Monst->_mgoal == MG_RUN_AWAY) + { + M_StartFadein(i, md, FALSE); + Monst->_mgoal = MG_ATTACK2; + } + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Fallen(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Fallen: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int x,y; + int xpos,ypos; + int m; + int rad; + int mx,my; + int aitype; + + if (Monst->_mgoal == MG_ATTACK2) + { + if(Monst->_mgoalvar1) + --Monst->_mgoalvar1; + else + Monst->_mgoal = MG_ATTACK; + } + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) + { + if (Monst->_mgoal == MG_RUN_AWAY && Monst->_mgoalvar1-- == 0) + { + Monst->_mgoal = MG_ATTACK; + M_StartStand(i, opposite[Monst->_mdir]); + } + if (Monst->_mAnimFrame == Monst->_mAnimLen) { + if (random(113,4) == 0) + { + // start 'dance' + if (!(monster[i]._mFlags & MFLAG_NOHEAL)) { + M_StartSpStand(i, Monst->_mdir); + if(Monst->_mmaxhp - (2*Monst->_mint+2) >= Monst->_mhitpoints) + Monst->_mhitpoints += 2*Monst->_mint+2; + else + Monst->_mhitpoints = Monst->_mmaxhp; + } + // set surrounding monsters into relentless attack + rad = 2*Monst->_mint+4; + for(y = -rad; y <= rad; ++y) + { + for(x = -rad; x <= rad; ++x) + { + xpos = Monst->_mx + x; + ypos = Monst->_my + y; + if(InBounds(x,y)) + { + m = dMonster[xpos][ypos]; + if(m > 0) + { + --m; + aitype = monster[m]._mAi; + if(aitype == AI_FALLEN) + { + monster[m]._mgoal = MG_ATTACK2; + // Set # frames for crazy attack mode + monster[m]._mgoalvar1 = (2*Monst->_mint+7)*15; + } + } + } + } + } + } + } + else if (Monst->_mgoal == MG_RUN_AWAY) + { + M_CallWalk(i,Monst->_mdir); + } + else if (Monst->_mgoal == MG_ATTACK2) + { + // attack relentlessly + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if(DIST(mx,my,2)) + M_StartAttack(i); + else + M_CallWalk(i, M_GetDir(i)); + } + else + MAI_SkelSd(i); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Cleaver(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Cleaver: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int mx, my, md; + + if (Monst->_mmode == MM_STAND && Monst->_msquelch) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + // If close, attack + if (DIST(mx,my,2)) { + M_StartAttack(i); + } else { + // Try walk + M_CallWalk(i, md); + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Round(int i, BOOL special) +{ + int mx, my, md, v; + int fx, fy, dist; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Round: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(114,100); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,4) && !random(115,4))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(116,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if( (Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) + { + Monst->_mgoal = MG_ATTACK; + } + else if(!M_RoundWalk(i,md,Monst->_mgoalvar2)) + M_StartDelay(i, random(125,10)+10); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (DIST(mx,my,2)) { + if (v < 23 + 2*Monst->_mint) + { + Monst->_mdir = md; + if(special && Monst->_mhitpoints < (Monst->_mmaxhp >> 1) && random(117,2)) + M_StartSpAttack(i); + else + M_StartAttack(i); + } + } + else if ((Monst->_mVar2 > 20 && v < (28 + 2*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (78 + 2*Monst->_mint))) { + M_CallWalk(i, md); + } + } + + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +void MAI_GoatMc(int i) +{ + MAI_Round(i, TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Ranged(int i, int missile_type, BOOL special) +{ + int fx, fy, mx, my, md; + BOOL walking = FALSE; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Ranged: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + if (Monst->_msquelch == 255 + || monster[i]._mFlags & MFLAG_MID) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = M_GetDir(i); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + Monst->_mdir = md; + + if (Monst->_mVar1 == MM_RATTACK) + { + // pause after each arrow + M_StartDelay(i, random(118,20)); + } + else if (DIST(mx,my,4) && random(119,100) < 70 + 10*Monst->_mint) + { + // retreat + walking = M_CallWalk(i, opposite[md]); + } + if (Monst->_mmode == MM_STAND) + { + if (LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Try attack + if(special) + M_StartRSpAttack(i,missile_type,4); + else + M_StartRAttack(i,missile_type,4); + } + else + // face dir + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } + } + else if(Monst->_msquelch // 0 < msquelch < 255 + && !(monster[i]._mFlags & MFLAG_MID)) // temp. golum fix + { + mx = Monst->_lastx; + my = Monst->_lasty; + md = GetDirection(Monst->_mx, Monst->_my, mx, my); + + M_CallWalk(i, md); + } + } +} + +void MAI_GoatBow(int i) +{ + MAI_Ranged(i,MIT_ARROW, FALSE); +} + +void MAI_Succ(int i) +{ + MAI_Ranged(i,MIT_FLARE, FALSE); +} + +void MAI_Lich(int i) +{ + MAI_Ranged(i,MIT_ORANGEFLARE, FALSE); +} + +void MAI_ArchLich(int i) +{ + MAI_Ranged(i,MIT_YELLOWFLARE, FALSE); +} + +void MAI_Psychorb(int i) +{ + MAI_Ranged(i,MIT_BLUEFLARE, FALSE); +} + +void MAI_Necromorb(int i) +{ + MAI_Ranged(i,MIT_REDFLARE, FALSE); +} + +void MAI_AcidUniq(int i) +{ + MAI_Ranged(i,MIT_ACID, TRUE); +} + +void MAI_Firebat(int i) +{ + MAI_Ranged(i,MIT_FIREBOLT, FALSE); +} + +void MAI_Hellbat(int i) +{ + MAI_Ranged(i,MIT_FIREBALL, FALSE); +} + +/*-----------------------------------------------------------------------* + * MAI_Scav + * + * MG_EAT is the scavenger's eat goal. + * _mgoalvar1 : =0 ==> no goal dest + * >0 ==> _mgoalvar1-1 is x coord of food + * _mgoalvar2 : _mgoalvar2-1 is y coord of food + * +**-----------------------------------------------------------------------*/ + +void MAI_Scav(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Scav: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int x,y; + BOOL done = FALSE; + + if (Monst->_mmode == MM_STAND) { + if(Monst->_mhitpoints < (Monst->_mmaxhp >> 1) && Monst->_mgoal != MG_EAT) + { + if(monster[i].leaderflag) + { + // leave pack permanently + --monster[monster[i].leader].packsize; + monster[i].leaderflag = 0; + } + Monst->_mgoal = MG_EAT; + Monst->_mgoalvar3 = 10; + } + + if (Monst->_mgoal == MG_EAT && Monst->_mgoalvar3) + { + --Monst->_mgoalvar3; + + // Are we on top of food? + if (dDead[Monst->_mx][Monst->_my]) + { + M_StartEat(i); + if (!(monster[i]._mFlags & MFLAG_NOHEAL)) { + int maxhp = (Monst->MType->mMaxHP << HP_SHIFT); + if (gbMaxPlayers == 1) + maxhp >>= 1; + + int healamt = maxhp >> 3; + Monst->_mhitpoints += healamt; + + // by eating, the monster can get to its species maximum + // in hit points... + if (Monst->_mhitpoints > maxhp) + Monst->_mhitpoints = maxhp; + if (Monst->_mmaxhp < Monst->_mhitpoints) + Monst->_mmaxhp = Monst->_mhitpoints; + + if (Monst->_mgoalvar3 <= 0 || // done eating + Monst->_mhitpoints == maxhp) + { + dDead[Monst->_mx][Monst->_my] = 0; // monster buried + } + } +// if ((Monst->_mhitpoints) >= (Monst->_mmaxhp >> 1) + (Monst->_mmaxhp >> 2)) + if ((Monst->_mhitpoints) == (Monst->_mmaxhp)) + { + Monst->_mgoal = MG_ATTACK; + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = 0; + } + } + else + { + if (!Monst->_mgoalvar1) + { + // Find food! + // Randomize search direction + if(random(120,2)) + { + for(y = -4; y <= 4 && !done; ++y) + for(x = -4; x <= 4 && !done; ++x) + if(InBounds(x,y)) + done = dDead[Monst->_mx + x][Monst->_my + y] + && LineClearF(CheckNoSolid, Monst->_mx,Monst->_my,Monst->_mx + x,Monst->_my + y); + --x; + --y; + } + else + { + for(y = 4; y >= -4 && !done; --y) + for(x = 4; x >= -4 && !done; --x) + if(InBounds(x,y)) + done = dDead[Monst->_mx + x][Monst->_my + y] + && LineClearF(CheckNoSolid,Monst->_mx,Monst->_my,Monst->_mx + x,Monst->_my + y); + ++x; + ++y; + } + if(done) + { + // Note: 1 is added to the following vars because + // 0 is reserved as a flag meaning undefined. + Monst->_mgoalvar1 = Monst->_mx + x +1; + Monst->_mgoalvar2 = Monst->_my + y +1; + } + } + if(Monst->_mgoalvar1) + { + x = Monst->_mgoalvar1 - 1; + y = Monst->_mgoalvar2 - 1; + Monst->_mdir = GetDirection(Monst->_mx, Monst->_my, x, y); + M_CallWalk(i, Monst->_mdir); + } + } + } + else +// if(Monst->_mmode == MM_STAND) + // none of the above cases applied, so resort to default behavior + MAI_SkelSd(i); + } +} + + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Garg(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Garg: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int mx, my; + int md; + + mx = Monst->_mx - Monst->_lastx; + my = Monst->_my - Monst->_lasty; + md = M_GetDir(i); + if(Monst->_msquelch && (Monst->_mFlags & MFLAG_STILL)) + { + M_Enemy(i); + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + + if(DIST(mx,my,Monst->_mint+2)) + Monst->_mFlags &= ~MFLAG_STILL; + } + else if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) + { + if(Monst->_mhitpoints < (Monst->_mmaxhp >> 1)) + { + // run away to get healed. + Monst->_mgoal = MG_RUN_AWAY; + } + if(Monst->_mgoal == MG_RUN_AWAY) + { + if(DIST(mx,my,Monst->_mint+2)) + { + if(!M_CallWalk(i,opposite[md])) + Monst->_mgoal = MG_ATTACK; + } + else + { + Monst->_mgoal = MG_ATTACK; + M_StartHeal(i); + + } + } + MAI_Round(i, FALSE); + } +} + + +/*-----------------------------------------------------------------------* + * MAI_RoundRanged + * + * Similar to MAI_Round, but does ranged attacks (throws lava) + * +**-----------------------------------------------------------------------*/ + +void MAI_RoundRanged(int i, int missile_type, BOOL checkdoors, int dam, BOOL lessmissiles) +{ + int fx, fy, mx, my, md, v, pnum; + int dist; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_RoundRanged: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + pnum = Monst->_menemy; + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(checkdoors && Monst->_msquelch < 255) + MonstCheckDoors(i); + + // Using random(10000) instead of random(100) for increased precision + // for small numbers, e.g. random(100) < (5 >> 1) + v = random(121,10000); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,3) && !random(122,4 << lessmissiles))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(123,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if(Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + { + Monst->_mgoal = MG_ATTACK; + } + else if(v < (500 + 500*Monst->_mint) >> lessmissiles + && + LineClear(Monst->_mx, Monst->_my, fx, fy)) + { + // Missile Attack + M_StartRSpAttack(i,missile_type,dam); + } + else + M_RoundWalk(i,md,Monst->_mgoalvar2); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (((!DIST(mx,my,3) && v < (1000 + 500*Monst->_mint) >> lessmissiles) + || + v < (500 + 500*Monst->_mint) >> lessmissiles) + && + LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Missile Attack + M_StartRSpAttack(i,missile_type,dam); + } + else if (DIST(mx,my,2)) + { + if (v < 6000 + 1000*Monst->_mint) + { + Monst->_mdir = md; + M_StartAttack(i); + } + } + else if (((v=random(124,100)) < (5000 + 1000*Monst->_mint)) + || + (WALKMODE(Monst->_mVar1) + && + Monst->_mVar2 == 0 && v < (8000 + 1000*Monst->_mint))) + { + M_CallWalk(i, md); + } + } + + // face dir + if (Monst->_mmode == MM_STAND) + M_StartDelay(i, random(125,10)+5); + } +} + +void MAI_Magma(int i) +{ + MAI_RoundRanged(i, MIT_MAGMABALL, TRUE,4, FALSE); +} + +void MAI_Storm(int i) +{ + MAI_RoundRanged(i, MIT_THINLIGHTCTRL, TRUE,4, FALSE); +} + +void MAI_BoneDemon(int i) +{ + MAI_RoundRanged(i, MIT_BLUE2FLARE, TRUE,4, FALSE); +} + +void MAI_Acid(int i) +{ + MAI_RoundRanged(i, MIT_ACID, FALSE,4, TRUE); +} + +void MAI_Diablo(int i) +{ + MAI_RoundRanged(i, MIT_DIABAPOCA, FALSE, 40, FALSE); +} + +void MAI_RR2(int i, int mistype, int dam) +{ + int fx, fy, mx, my, md, v, pnum; + int dist; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_RR2: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if (!DIST(mx, my, 5)) + MAI_SkelSd(i); + else if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + pnum = Monst->_menemy; + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(121,100); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || !DIST(mx,my,3)) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(123,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + Monst->_mgoalvar3 = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if(Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + { + Monst->_mgoal = MG_ATTACK; + } + else if (v < 80 + 5*Monst->_mint) + M_RoundWalk(i,md,Monst->_mgoalvar2); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (((!DIST(mx,my,3) && v < 10 + 5*Monst->_mint) + || + v < 5 + 5*Monst->_mint + || Monst->_mgoalvar3 == MG_WALK_AROUND1) + && + LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Missile Attack + M_StartRSpAttack(i,mistype,dam); + } + else if (DIST(mx,my,2)) + { + if (random(124,100) < 40 + 10*Monst->_mint) + { + Monst->_mdir = md; + if (random(124, 2)) + M_StartAttack(i); + else + // Missile Attack + M_StartRSpAttack(i,mistype,dam); + } + } + else if (((v=random(124,100)) < (50 + 10*Monst->_mint)) + || + (WALKMODE(Monst->_mVar1) + && + Monst->_mVar2 == 0 && v < (80 + 10*Monst->_mint))) + { + M_CallWalk(i, md); + } + Monst->_mgoalvar3 = MG_ATTACK; + } + + if (Monst->_mmode == MM_STAND) + M_StartDelay(i, random(125,10)+5); + } +} + +void MAI_Mega(int i) +{ + MAI_RR2(i, MIT_FLAMEC,0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MAI_Golum(int i) +{ + int ok, j, k, mid; + int mx, my, md; + BOOL have_enemy; + + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Golum: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mx == 1) && (Monst->_my == 0)) return; + + if (Monst->_mmode == MM_DEATH) return; + if (Monst->_mmode == MM_SPSTAND) return; + if (Monst->_mmode >= MM_WALK && Monst->_mmode <= MM_WALK3) return; + + if (!(monster[i]._mFlags & MFLAG_MID)) M_Enemy(i); + + have_enemy = !(Monst->_mFlags & MFLAG_NOENEMY); + + if (Monst->_mmode != MM_ATTACK) { + mx = Monst->_mx - monster[Monst->_menemy]._mfutx; + my = Monst->_my - monster[Monst->_menemy]._mfuty; + md = GetDirection(Monst->_mx, Monst->_my, monster[Monst->_menemy]._mx, monster[Monst->_menemy]._my); + Monst->_mdir = md; + + if (DIST(mx,my,2) && have_enemy) { + Monst->_menemyx = monster[Monst->_menemy]._mx; + Monst->_menemyy = monster[Monst->_menemy]._my; + if(!monster[Monst->_menemy]._msquelch) { + monster[Monst->_menemy]._msquelch = 255; + monster[Monst->_menemy]._lastx = Monst->_mx; + monster[Monst->_menemy]._lasty = Monst->_my; + for (j = 0; j < 5; ++j) { + for (k = 0; k < 5; ++k) { + mid = dMonster[monster[i]._mx - 2 + k][monster[i]._my - 2 + j]; + if (mid > 0) monster[mid]._msquelch = 255; + } + } + } + M_StartAttack(i); + } else { + if (!have_enemy || + !MAI_Path(i)) { + ++Monst->_pathcount; + if (Monst->_pathcount > 8) Monst->_pathcount = 5; + ok = M_CallWalk(i, plr[i]._pdir); + if (ok == FALSE) { + md = (md - 1) & 0x07; + for (j = 0; j < 8 && ok == FALSE; ++j) { + md = (md + 1) & 0x07; + ok = DirOK(i, md); + } + if (ok) + M_WalkDir(i, md); + } + } + } + } + +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SkelKing(int i) +{ + int fx, fy, mx, my, md, v; + int dist; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_SkelKing: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + int nx,ny; // location for new skel spawn + int skel; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(126,100); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,3) && !random(127,4))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(128,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if( (Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) + { + Monst->_mgoal = MG_ATTACK; + } + else if(!M_RoundWalk(i,md,Monst->_mgoalvar2)) + M_StartDelay(i, random(125,10)+10); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (gbMaxPlayers == 1 // no spawning in multi-player + && ((!DIST(mx,my,3) && v < 35 + 4*Monst->_mint) + || v < 6) + && + LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Spawn new Skeleton + nx = Monst->_mx + offset_x[md]; + ny = Monst->_my + offset_y[md]; + if (PosOkMonst(i,nx,ny) && nummonsters < MAXMONSTERS) + { +// skel = AddMonster(nx, ny, md, 1, TRUE); +// M_StartSpStand(skel, md); + skel = M_SpawnSkel(nx, ny, md); + M_StartSpStand(i, md); + } + } + else if (DIST(mx,my,2)) { + if (v < 20 + Monst->_mint) + { + Monst->_mdir = md; + M_StartAttack(i); + } + } + else if (((v=random(129,100)) < (25 + Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (75 + Monst->_mint))) { + M_CallWalk(i, md); + } + else + M_StartDelay(i, random(130,10)+10); + } + + // face dir + if (Monst->_mmode == MM_STAND) + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Rhino(int i) +{ + int fx, fy, mx, my, md, v; + int dist; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Rhino: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND && Monst->_msquelch) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(131,100); + if (DIST(mx,my,2)) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,5) && random(132,4))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(133,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if( (Monst->_mgoalvar1++ >= (dist << 1)) + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) + { + Monst->_mgoal = MG_ATTACK; + } + else if(!M_RoundWalk(i,md,Monst->_mgoalvar2)) + M_StartDelay(i, random(125,10)+10); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if ((!DIST(mx,my,5) && v < 43 + 2*Monst->_mint) && + LineClearF1(PosOkMonst, i,Monst->_mx,Monst->_my,fx,fy)) + { + // Launch rhino + if (AddMissile(Monst->_mx, Monst->_my, fx,fy, md, MIT_RHINO, Monst->_menemy, i, 0, 0) != -1) { + if (Monst->MData->snd_special) PlayEffect(i, MS_SATTACK); + dMonster[Monst->_mx][Monst->_my] = -(i+1); + Monst->_mmode = MM_MISSILE; + } + } + else if (DIST(mx,my,2)) { + if (v < 28 + 2*Monst->_mint) + { + Monst->_mdir = md; + M_StartAttack(i); + } + } + else if (((v=random(134,100)) < (33 + 2*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (83 + 2*Monst->_mint))) { + M_CallWalk(i, md); + } + else + M_StartDelay(i, random(135,10)+10); + } + + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + } +} + +void MAI_HorkDemon(int i) +{ + int v; + + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_HorkDemon: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND && Monst->_msquelch) { + int const fx = Monst->_menemyx; + int const fy = Monst->_menemyy; + int const mx = Monst->_mx - fx; + int const my = Monst->_my - fy; + int const md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(131,100); + if (DIST(mx,my,2)) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,5) && random(132,4))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(133,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + int const dist = max(abs(mx),abs(my)); + + if( (Monst->_mgoalvar1++ >= (dist << 1)) + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) + { + Monst->_mgoal = MG_ATTACK; + } + else if(!M_RoundWalk(i,md,Monst->_mgoalvar2)) + M_StartDelay(i, random(125,10)+10); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if ((!DIST(mx,my,3) && v < 43 + 2*Monst->_mint)) + { + // Launch Hork Spawn + int const Enemyd = Monst->_mdir; + int const nx = Monst->_mx + infront_x[Enemyd]; + int const ny = Monst->_my + infront_y[Enemyd]; + if (PosOkMonst(i,nx,ny) && nummonsters < MAXMONSTERS) { + M_StartRSpAttack(i, MIT_HORKSPAWN, 0); + } + } + else if (DIST(mx,my,2)) { + if (v < 28 + 2*Monst->_mint) + { + Monst->_mdir = md; + M_StartAttack(i); + } + } + else if (((v=random(134,100)) < (33 + 2*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (83 + 2*Monst->_mint))) { + M_CallWalk(i, md); + } + else + M_StartDelay(i, random(135,10)+10); + } + + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Counselor(int i) +{ + int fx, fy, mx, my, md, v; + int dist; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Counselor: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + static const BYTE counsmiss[] = { MIT_FIREBOLT, MIT_CBOLT, MIT_LIGHTCTRL, MIT_FIREBALL }; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(121,100); + if (Monst->_mgoal == MG_RUN_AWAY) + { + if (Monst->_mgoalvar1++ > 3) + { + Monst->_mgoal = MG_ATTACK; + M_StartFadein(i, md, TRUE); + } + else + M_CallWalk(i, opposite[md]); + } + else if(Monst->_mgoal == MG_WALK_AROUND1) + { + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + M_StartFadein(i, md, TRUE); + } + else if(Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + { + Monst->_mgoal = MG_ATTACK; + M_StartFadein(i, md, TRUE); + } + else + M_RoundWalk(i,md,Monst->_mgoalvar2); + } + else if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (DIST(mx,my,2)) + { + Monst->_mdir = md; + if (Monst->_mhitpoints < (Monst->_mmaxhp >> 1)) + { + // run away! + Monst->_mgoal = MG_RUN_AWAY; + Monst->_mgoalvar1 = 0; + M_StartFadeout(i, md, FALSE); + } + else if (Monst->_mVar1 == MM_DELAY || random(105,100) < 20 + 2*Monst->_mint) + { + M_StartRAttack(i,-1,0); + AddMissile(monster[i]._mx, monster[i]._my, 0, 0, monster[i]._mdir, MIT_FLASH, MI_ENEMYPLR, i, 4, 0); + AddMissile(monster[i]._mx, monster[i]._my, 0, 0, monster[i]._mdir, MIT_FLASH2, MI_ENEMYPLR, i, 4, 0); + } + else + M_StartDelay(i, random(105,10)+10 - 2*Monst->_mint); + } + else if (v < 50 + 5*Monst->_mint + && LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Missile Attack + M_StartRAttack(i, counsmiss[Monst->_mint], random(77, Monst->mMaxDamage - Monst->mMinDamage + 1) + Monst->mMinDamage); + } + else if (random(124, 100) < 30) + { + Monst->_mgoal = MG_WALK_AROUND1; + Monst->_mgoalvar1 = 0; + M_StartFadeout(i, md, FALSE); + } + else + M_StartDelay(i, random(105,10)+10 - 2*Monst->_mint); + } + + // face dir + if (Monst->_mmode == MM_STAND) + M_StartDelay(i, random(125,10)+5); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Garbud(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Garbud: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if ((Monst->mtalkmsg < TXT_GARB4) && (Monst->mtalkmsg > (TXT_GARB1-1)) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + ++Monst->mtalkmsg; + Monst->_mgoal = MG_TALK; + } + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_GARB4) && !(effect_is_playing(USFX_GARBUD4)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_WALK_AROUND1)) { + MAI_Round(i, TRUE); + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Zhar(int i) +{ + int mx, my, md, dist; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Zhar: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if ((Monst->mtalkmsg == TXT_ZHAR1) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + ++Monst->mtalkmsg; + Monst->_mgoal = MG_TALK; + } + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + dist = max(abs(mx), abs(my)); + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_ZHAR2) && !(effect_is_playing(USFX_ZHAR2)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_RUN_AWAY) || (Monst->_mgoal == MG_WALK_AROUND1)) { + MAI_Counselor(i); + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SnotSpil(int i) +{ + int mx, my, md, pnum; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_SnotSpil: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + pnum = Monst->_menemy; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if ((Monst->mtalkmsg == TXT_BOL1) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->mtalkmsg = TXT_BOL2; + Monst->_mgoal = MG_TALK; + } + if ((Monst->mtalkmsg == TXT_BOL2) && (quests[Q_LTBANNER]._qvar1 == 3)) { + Monst->mtalkmsg = 0; + Monst->_mgoal = MG_ATTACK; + } + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_BOL3) && !(effect_is_playing(USFX_SNOT3)) && (Monst->_mgoal == MG_WAITTOTALK)) { + int i = plr[pnum]._pvid; + ObjChangeMap(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1); + quests[Q_LTBANNER]._qvar1 = 3; + extern void RedoPlayerVision(); + RedoPlayerVision(); + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + if (quests[Q_LTBANNER]._qvar1 == 3) { + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_ATTACK2)) { + MAI_Fallen(i); + } + } + + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Lazurus(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Lazurus: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if (gbMaxPlayers == 1) { + if ((Monst->mtalkmsg == TXT_VB1) && (Monst->_mgoal == MG_TALK) + && (plr[myplr]._px == 35) && (plr[myplr]._py == 46)) { + PlayInGameMovie("gendata\\fprst3.smk"); + Monst->_mmode = MM_TALK; + quests[Q_BETRAYER]._qvar1 = 5; + } + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VB1) && !(effect_is_playing(USFX_LAZ1)) && (Monst->_mgoal == MG_WAITTOTALK)) { + ObjChangeMapResync(1, 18, 20, 24); + extern void RedoPlayerVision(); + RedoPlayerVision(); + quests[Q_BETRAYER]._qvar1 = 6; + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if (gbMaxPlayers != 1) { + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VB1) && (Monst->_mgoal == MG_TALK) && (quests[Q_BETRAYER]._qvar1 <= 3)) { + Monst->_mmode = MM_TALK; + } + #endif + } + + } + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_RUN_AWAY) || (Monst->_mgoal == MG_WALK_AROUND1)) { + MAI_Counselor(i); + } + monster[i]._mdir = md; + if ((Monst->_mmode == MM_STAND) || (Monst->_mmode == MM_TALK)) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Lazhelp(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Lazhelp: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if (gbMaxPlayers == 1) { + if (quests[Q_BETRAYER]._qvar1 <= 5) + Monst->_mgoal = MG_TALK; + else { + Monst->_mgoal = MG_ATTACK; + Monst->mtalkmsg = 0; + } + } else if (gbMaxPlayers != 1) { + Monst->_mgoal = MG_ATTACK; + } + } + if (Monst->_mgoal == MG_ATTACK) { + MAI_Succ(i); + } + monster[i]._mdir = md; + } if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Lachdanan(int i) +{ + int mx, my, md, pnum; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Lachdanan: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + pnum = Monst->_menemy; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VEIL1) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + ++Monst->mtalkmsg; + Monst->_mgoal = MG_TALK; + } + #endif + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VEIL3) && !(effect_is_playing(USFX_LACH3)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->mtalkmsg = 0; + quests[Q_VEIL]._qactive = QUEST_DONE; + M_StartKill(i, -1); + } + #endif + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Warlord(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MAI_Warlord: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if ((Monst->mtalkmsg == TXT_WARLRD1) && (Monst->_mgoal == MG_TALK)) { + Monst->_mmode = MM_TALK; + } + + #if !IS_VERSION(SHAREWARE) + BOOL effect_is_playing(int nSFX); + if ((Monst->mtalkmsg == TXT_WARLRD1) && !(effect_is_playing(USFX_WARLRD1)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if (Monst->_mgoal == MG_ATTACK) { + MAI_SkelSd(i); + } + monster[i]._mdir = md; + if ((Monst->_mmode == MM_STAND) || (Monst->_mmode == MM_TALK)) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DeleteMonsterList() +{ + int i, mi; + + // pseudo delete dead golems + for (i = 0; i < 4; ++i) { + if (monster[i]._mDelFlag) { + monster[i]._mx = 1; + monster[i]._my = 0; + monster[i]._mfutx = 0; + monster[i]._mfuty = 0; + monster[i]._moldx = 0; + monster[i]._moldy = 0; + monster[i]._mDelFlag = FALSE; + } + } + + i = 4; // this is to skip the golems + app_assert((DWORD)nummonsters <= MAXMONSTERS); + while (i < nummonsters) { + mi = monstactive[i]; + if (monster[mi]._mDelFlag) { + DeleteMonster(i); + i = 0; + } else ++i; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ProcessMonsters () +{ + int i, mi; + int raflag; + int mx, my; + MonsterStruct *Monst; + int oldmode; + + DeleteMonsterList(); + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (i = 0; i < nummonsters; ++i) { + mi = monstactive[i]; + Monst = &monster[mi]; + raflag = RUN_DONE; + + // Try and run same AI's as best as possible in multiplayer + if (gbMaxPlayers > 1) { + SetRndSeed(Monst->_mAISeed); + Monst->_mAISeed = GetRndSeed(); + } + + // Turn regen + if (!(monster[mi]._mFlags & MFLAG_NOHEAL)) { + if ((Monst->_mhitpoints < Monst->_mmaxhp) && ((Monst->_mhitpoints >> HP_SHIFT) > 0)) { + if (Monst->mLevel > 1) + Monst->_mhitpoints += Monst->mLevel >> 1; + else + Monst->_mhitpoints += Monst->mLevel; + } + } + // Check if just activating + mx = Monst->_mx; + my = Monst->_my; + if ((dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_msquelch == 0)) { + #if !IS_VERSION(SHAREWARE) + if (Monst->MType->mtype == MT_CLEAVER) { + //if (gbMaxPlayers == 1) PlayInGameMovie("gendata\\fbutch3.smk"); + PlaySFX(USFX_CLEAVER); + } + if (Monst->MType->mtype == MT_NKR) { + if (gbCowsuit) + PlaySFX(HSFX_NA_KRUL6); + else if (Na_Krul.Books) + PlaySFX(HSFX_NA_KRUL4); + else + PlaySFX(HSFX_NA_KRUL5); + } + if (Monst->MType->mtype == MT_BUG) { + //if (gbMaxPlayers == 1) PlayInGameMovie("gendata\\fbutch3.smk"); + PlaySFX(HSFX_DEFILER5); + } + #endif + M_Enemy(mi); + } + + // Check if monster's enemy + if (Monst->_mFlags & MFLAG_MID) { + if ((DWORD)Monst->_menemy >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("Illegal enemy monster %d for monster \"%s\"",Monst->_menemy,Monst->mName); +#else + return; +#endif + } + Monst->_menemyx = Monst->_lastx = monster[Monst->_menemy]._mfutx; + Monst->_menemyy = Monst->_lasty = monster[Monst->_menemy]._mfuty; + } else { + // Deal with keeping a monster active for a while after its visibility flag + // goes off + if ((DWORD)Monst->_menemy >= MAX_PLRS) + { +#if defined(_DEBUG) + app_fatal("Illegal enemy player %d for monster \"%s\"",Monst->_menemy,Monst->mName); +#else + return; +#endif + } + Monst->_menemyx = plr[Monst->_menemy]._pfutx; + Monst->_menemyy = plr[Monst->_menemy]._pfuty; + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + Monst->_msquelch = 255; + Monst->_lastx = plr[Monst->_menemy]._pfutx; + Monst->_lasty = plr[Monst->_menemy]._pfuty; + } else if(Monst->_msquelch && (Monst->_mAi != MT_DIABLO)) --Monst->_msquelch; + } + + do { + // Run Monster's AI + + // Try Path Mode + if (Monst->_mFlags & MFLAG_PATH) + { + if (!MAI_Path(mi)) + AiProc[Monst->_mAi](mi); + } + else + AiProc[Monst->_mAi](mi); + + // Run Monster Mode + switch (oldmode = Monst->_mmode) { + case MM_STAND : + raflag = M_DoStand(mi); + break; + case MM_WALK : + raflag = M_DoWalk(mi); + break; + case MM_WALK2 : + raflag = M_DoWalk2(mi); + break; + case MM_WALK3: + raflag = M_DoWalk3(mi); + break; + case MM_ATTACK: + raflag = M_DoAttack(mi); + break; + case MM_RATTACK: + raflag = M_DoRAttack(mi); + break; + case MM_GOTHIT: + raflag = M_DoGotHit(mi); + break; + case MM_DEATH: + raflag = M_DoDeath(mi); + break; + case MM_SATTACK: + raflag = M_DoSAttack(mi); + break; + case MM_FADEIN: + raflag = M_DoFadein(mi); + break; + case MM_FADEOUT: + raflag = M_DoFadeout(mi); + break; + case MM_SPSTAND: + raflag = M_DoSpStand(mi); + break; + case MM_RSATTACK: + raflag = M_DoRSpAttack(mi); + break; + case MM_DELAY: + raflag = M_DoDelay(mi); + break; + case MM_MISSILE: + raflag = RUN_DONE; + break; + case MM_STONE: + raflag = M_DoStone(mi); + break; + case MM_HEAL: + raflag = M_DoHeal(mi); + break; + case MM_TALK: + raflag = M_DoTalk(mi); + break; + } + +/* for (int mm = 0; mm < nummonsters; ++mm) { + int mmi = monstactive[mm]; + app_assert(monster[mmi]._mDelFlag + || monster[mmi]._mmode == MM_MISSILE + || !monster[mmi]._msquelch + || mmi < 4 + || dMonster[monster[mmi]._mx][monster[mmi]._my] == mmi+1 + || dMonster[monster[mmi]._mx][monster[mmi]._my] == -(mmi+1)); + }*/ + + if(raflag != RUN_DONE) + GroupUnity(mi); + +// if (Monst->_msquelch) DaveMonstMap(FALSE, 0); + + } while (raflag != RUN_DONE); + + // Animate Monster + if (Monst->_mmode != MM_STONE) { + ++Monst->_mAnimCnt; + if (!(Monst->_mFlags & MFLAG_STILL)) + { + if (Monst->_mAnimCnt >= Monst->_mAnimDelay) { + Monst->_mAnimCnt = 0; + if(Monst->_mFlags & MFLAG_BACKWARDS) + { + --Monst->_mAnimFrame; + if (!Monst->_mAnimFrame) Monst->_mAnimFrame = Monst->_mAnimLen; + } + else + { + ++Monst->_mAnimFrame; + if (Monst->_mAnimFrame > Monst->_mAnimLen) Monst->_mAnimFrame = 1; + } + } + } + } + } + DeleteMonsterList(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeMonsterGFX() +{ + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (int monst = 0; monst < nummtypes; ++monst) { + int mtype = Monsters[monst].mtype; + for (int anim = 0; anim < MAX_ANIMTYPE; ++anim) { + if(!(animletter[anim] == 's' && !monsterdata[mtype].has_special)) { + DiabloFreePtr(Monsters[monst].Anims[anim].CMem); + } + } + } + + IFreeMissileGFX(); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL DirOK(int i, int mdir) +{ + long fx, fy; + int tmp; + + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("DirOK: Invalid monster %d",i); +#else + return FALSE; +#endif + } + fx = monster[i]._mx + offset_x[mdir]; + fy = monster[i]._my + offset_y[mdir]; + if(! InBounds(fx,fy)) + return FALSE; + + if (! PosOkMonst(i, fx, fy)) + return FALSE; + + if (mdir == M_DIRR) { + if (SolidLoc(fx+0,fy+1)) return FALSE; + if (dFlags[fx+0][fy+1] & BFLAG_MONSTLR) return FALSE; + } + else if(mdir == M_DIRL) { + if (SolidLoc(fx+1,fy+0)) return FALSE; + if (dFlags[fx+1][fy+0] & BFLAG_MONSTLR) return FALSE; + } + else if (mdir == M_DIRU) { + if (SolidLoc(fx+1,fy+0)) return FALSE; + if (SolidLoc(fx+0,fy+1)) return FALSE; + } + else if (mdir == M_DIRD) { + if (SolidLoc(fx-1,fy+0)) return FALSE; + if (SolidLoc(fx+0,fy-1)) return FALSE; + } + + // check for group cohesion + if(monster[i].leaderflag == PACK_MEMBER) { + // make sure monster is close to leader + return DIST( + fx-monster[monster[i].leader]._mfutx, + fy-monster[monster[i].leader]._mfuty, + 4 + ); + } + + if (monster[i]._uniqtype && (UniqMonst[monster[i]._uniqtype-1].mUnqAttr & UN_STICK)) + { + int mcount = 0; + for (int x = fx - 3; x <= fx + 3; ++x) { + for (int y = fy - 3; y <= fy + 3; ++y) { + if (! InBounds(x,y)) continue; + + if((tmp = dMonster[x][y]) < 0) tmp = -tmp; + if (tmp != 0) --tmp; + app_assert(tmp >= 0); + + if (monster[tmp].leaderflag == PACK_MEMBER && + monster[tmp].leader == i && + monster[tmp]._mfutx == x && + monster[tmp]._mfuty == y) ++mcount; + } + } + + return (mcount == monster[i].packsize); + } + + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PosOkMissile(int x, int y) +{ + return !(nMissileTable[dPiece[x][y]] || (dFlags[x][y] & BFLAG_MONSTLR)); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CheckNoSolid(int x, int y) +{ + return !nSolidTable[dPiece[x][y]]; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +BOOL LineClearF(CHECKFUNC Clear, int x1, int y1, int x2, int y2) +{ + int md; + BOOL done = FALSE; + + do + { + md = GetDirection(x1,y1,x2,y2); + x1 += offset_x[md]; + y1 += offset_y[md]; + done = !(*Clear)(x1, y1); + } while(!done && !(x1==x2 && y1==y2)); + return (x1 == x2) && (y1 == y2); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL LineClearF(CHECKFUNC Clear, int x1, int y1, int x2, int y2) +{ + // Bresenham line algorithm + // See Foley/van Dam, "Computer Graphics: Principles and Practice" + + int dx,dy; + int d; // test variable + int dincH; // Horizontal increment for d + int dincD; // Diagonal increment for d + int xincD,yincD; // Diagonal increments for minor axis + int xorg, yorg; + BOOL done = FALSE; + int tmp; + + xorg = x1; + yorg = y1; + + dx = x2 - x1; + dy = y2 - y1; + if(abs(dx) > abs(dy)) + { + // X is the major axis + if(dx < 0) + { + // swap endpoints + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + + dx = -dx; + dy = -dy; + } + if(dy > 0) + { + // pos. slope + d = 2*dy - dx; + dincH = 2*dy; + dincD = 2*(dy - dx); + yincD = 1; + } + else + { + // neg. slope + d = 2*dy + dx; + dincH = 2*dy; + dincD = 2*(dy + dx); + yincD = -1; + } + +// done = (x1 != xorg || y1 != yorg) && !(*Clear)(x1, y1); + + while(!done && !(x1 == x2 && y1 == y2)) + { + if((d <= 0) ^ (yincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + y1 += yincD; + } + ++x1; + done = (x1 != xorg || y1 != yorg) && !(*Clear)(x1, y1); + } + } + else + { + // Y is the major axis + if(dy < 0) + { + // swap endpoints + tmp = y1; + y1 = y2; + y2 = tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + + dy = -dy; + dx = -dx; + } + if(dx > 0) + { + // pos. slope + d = 2*dx - dy; + dincH = 2*dx; + dincD = 2*(dx - dy); + xincD = 1; + } + else + { + // neg. slope + d = 2*dx + dy; + dincH = 2*dx; + dincD = 2*(dx + dy); + xincD = -1; + } + +// done = (y1 != yorg || x1 != xorg) && !(*Clear)(x1, y1); + + while(!done && !(y1 == y2 && x1 == x2)) + { + if((d <= 0) ^ (xincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + x1 += xincD; + } + ++y1; + done = (y1 != yorg || x1 != xorg) && !(*Clear)(x1, y1); + } + } + + return x1 == x2 && y1 == y2; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL LineClear(int x1, int y1, int x2, int y2) +{ + return LineClearF(PosOkMissile, x1, y1, x2, y2); +} + +/*-----------------------------------------------------------------------* + * LineClearF1 + * + * This is exactly the same routine as LineClearF, except its Check + * routine requires an extra argument +**-----------------------------------------------------------------------*/ + +BOOL LineClearF1(CHECKFUNC1 Clear, int monst, int x1, int y1, int x2, int y2) +{ + // Bresenham line algorithm + // See Foley/van Dam, "Computer Graphics: Principles and Practice" + + int dx,dy; + int d; // test variable + int dincH; // Horizontal increment for d + int dincD; // Diagonal increment for d + int xincD,yincD; // Diagonal increments for minor axis + int xorg, yorg; + BOOL done = FALSE; + int tmp; + + xorg = x1; + yorg = y1; + + dx = x2 - x1; + dy = y2 - y1; + if(abs(dx) > abs(dy)) + { + // X is the major axis + if(dx < 0) + { + // swap endpoints + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + + dx = -dx; + dy = -dy; + } + if(dy > 0) + { + // pos. slope + d = 2*dy - dx; + dincH = 2*dy; + dincD = 2*(dy - dx); + yincD = 1; + } + else + { + // neg. slope + d = 2*dy + dx; + dincH = 2*dy; + dincD = 2*(dy + dx); + yincD = -1; + } + + while(!done && !(x1 == x2 && y1 == y2)) + { + if((d <= 0) ^ (yincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + y1 += yincD; + } + ++x1; + done = (x1 != xorg || y1 != yorg) && !Clear(monst, x1, y1); + } + } + else + { + // Y is the major axis + if(dy < 0) + { + // swap endpoints + tmp = y1; + y1 = y2; + y2 = tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + + dy = -dy; + dx = -dx; + } + if(dx > 0) + { + // pos. slope + d = 2*dx - dy; + dincH = 2*dx; + dincD = 2*(dx - dy); + xincD = 1; + } + else + { + // neg. slope + d = 2*dx + dy; + dincH = 2*dx; + dincD = 2*(dx + dy); + xincD = -1; + } + + while(!done && !(y1 == y2 && x1 == x2)) + { + if((d <= 0) ^ (xincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + x1 += xincD; + } + ++y1; + done = (y1 != yorg || x1 != xorg) && !Clear(monst, x1, y1); + } + } + + return x1 == x2 && y1 == y2; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncMonsterAnim(int m) +{ + int dir; + + if ((DWORD)m >= MAXMONSTERS || m < 0) + { +#if defined(_DEBUG) + app_fatal("SyncMonsterAnim: Invalid monster %d",m); +#else + return; +#endif + } + + app_assert(monster[m]._mMTidx < MAX_LVLMTYPES + && monster[m]._mMTidx >= 0); + monster[m].MType = &Monsters[monster[m]._mMTidx]; + monster[m].MData = Monsters[monster[m]._mMTidx].MData; + if(monster[m]._uniqtype) + monster[m].mName = UniqMonst[monster[m]._uniqtype-1].mName; + else { + app_assert(monster[m].MData != 0); + monster[m].mName = monster[m].MData->mName; + } + + dir = monster[m]._mdir; + switch (monster[m]._mmode) { + case MM_STAND : + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + break; + case MM_WALK : + monster[m]._mAnimData = monster[m].MType->Anims[MA_WALK].Cels[dir]; + break; + case MM_WALK2 : + monster[m]._mAnimData = monster[m].MType->Anims[MA_WALK].Cels[dir]; + break; + case MM_WALK3: + monster[m]._mAnimData = monster[m].MType->Anims[MA_WALK].Cels[dir]; + break; + case MM_ATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_ATTACK].Cels[dir]; + break; + case MM_RATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_ATTACK].Cels[dir]; + break; + case MM_GOTHIT: + monster[m]._mAnimData = monster[m].MType->Anims[MA_GOTHIT].Cels[dir]; + break; + case MM_DEATH: + monster[m]._mAnimData = monster[m].MType->Anims[MA_DEATH].Cels[dir]; + break; + case MM_SATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_FADEIN: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_FADEOUT: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_SPSTAND: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_RSATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_DELAY: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + break; + case MM_HEAL: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_TALK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + break; + case MM_STONE: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[MA_STAND].Frames; + break; + case MM_MISSILE: + monster[m]._mAnimData = monster[m].MType->Anims[MA_ATTACK].Cels[dir]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[MA_ATTACK].Frames; + break; + default: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[MA_STAND].Frames; + break; + } +} + + +/*-----------------------------------------------------------------------* +* When monster gets killed, make the fallen run in fear +**-----------------------------------------------------------------------*/ +void M_FallenFear(int x, int y) +{ + int i, mi; + int rundist; + int aitype; + + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (i = 0; i < nummonsters; ++i) { + mi = monstactive[i]; + rundist = 0; + switch(monster[mi].MType->mtype) { + case MT_RFALLSD : + case MT_RFALLSP : + rundist = 7; + break; + case MT_DFALLSD : + case MT_DFALLSP : + rundist = 5; + break; + case MT_YFALLSD : + case MT_YFALLSP : + rundist = 3; + break; + case MT_BFALLSD : + case MT_BFALLSP : + rundist = 2; + break; + } + + aitype = monster[mi]._mAi; + if(aitype == AI_FALLEN) { + if (rundist + && DIST(x-monster[mi]._mx, y-monster[mi]._my, 5) + && ((monster[mi]._mhitpoints >> HP_SHIFT) > 0)) + { + monster[mi]._mgoal = MG_RUN_AWAY; + monster[mi]._mgoalvar1 = rundist; // run away for 'rundist' squares + // next direction will be away from monster that got hit + monster[mi]._mdir = GetDirection(x, y, monster[i]._mx, monster[i]._my); + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintMonstHistory(int mt) +{ + int res, minhp, maxhp; + + sprintf(tempstr, "Total kills : %i", monstkills[mt]); + AddPanelString(tempstr, TEXT_CENTER); + if (monstkills[mt] >= 30) { + minhp = monsterdata[mt].mMinHP; + maxhp = monsterdata[mt].mMaxHP; + if (gbMaxPlayers == 1) { + minhp = minhp >> 1; + maxhp = maxhp >> 1; + } + if (minhp < 1) minhp = 1; + if (maxhp < 1) maxhp = 1; + if (gnDifficulty == D_NIGHTMARE) { + minhp = (minhp * 3) + ((gbMaxPlayers == 1) ? 50 : 100); + maxhp = (maxhp * 3) + ((gbMaxPlayers == 1) ? 50 : 100); + } + else if (gnDifficulty == D_HELL) { + minhp = (minhp * 4) + ((gbMaxPlayers == 1) ? 100 : 200); + maxhp = (maxhp * 4) + ((gbMaxPlayers == 1) ? 100 : 200); + } + sprintf(tempstr, "Hit Points : %i-%i", minhp, maxhp); + AddPanelString(tempstr, TEXT_CENTER); + } + /*minhp = monster[cursmonst]._mhitpoints >> HP_SHIFT; + maxhp = monster[cursmonst]._mmaxhp >> HP_SHIFT; + sprintf(tempstr, "Hit Points : %i of %i", minhp, maxhp); + AddPanelString(tempstr, TEXT_CENTER);*/ + if (monstkills[mt] >= 15) { + if (gnDifficulty != D_HELL) + res = monsterdata[mt].mMagicRes; + else + res = monsterdata[mt].mMagicRes2; + res &= (M_RM|M_RF|M_RL|M_IM|M_IF|M_IL); + if (res == M_NONE) { + strcpy(tempstr, "No magic resistance"); + AddPanelString(tempstr, TEXT_CENTER); + } else { + if (res & (M_RM|M_RF|M_RL)) { + strcpy(tempstr, "Resists : "); + if (res & M_RM) strcat(tempstr, "Magic "); + if (res & M_RF) strcat(tempstr, "Fire "); + if (res & M_RL) strcat(tempstr, "Lightning "); + tempstr[strlen(tempstr)-1] = 0; + AddPanelString(tempstr, TEXT_CENTER); + } + if (res & (M_IM|M_IF|M_IL)) { + strcpy(tempstr, "Immune : "); + if (res & M_IM) strcat(tempstr, "Magic "); + if (res & M_IF) strcat(tempstr, "Fire "); + if (res & M_IL) strcat(tempstr, "Lightning "); + tempstr[strlen(tempstr)-1] = 0; + AddPanelString(tempstr, TEXT_CENTER); + } + } + } + pinfoflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintUniqueHistory() +{ + int res; + + /*int minhp = monster[cursmonst]._mhitpoints >> HP_SHIFT; + int maxhp = monster[cursmonst]._mmaxhp >> HP_SHIFT; + sprintf(tempstr, "Hit Points : %i of %i", minhp, maxhp); + AddPanelString(tempstr, TEXT_CENTER);*/ + res = monster[cursmonst].mMagicRes; + res &= (M_RM|M_RF|M_RL|M_IM|M_IF|M_IL); + if (res == M_NONE) { + strcpy(tempstr, "No resistances"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "No Immunities"); + AddPanelString(tempstr, TEXT_CENTER); + } else { + if (res & (M_RM|M_RF|M_RL)) + strcpy(tempstr, "Some Magic Resistances"); + else + strcpy(tempstr, "No resistances"); + AddPanelString(tempstr, TEXT_CENTER); + if (res & (M_IM|M_IF|M_IL)) + strcpy(tempstr, "Some Magic Immunities"); + else + strcpy(tempstr, "No Immunities"); + AddPanelString(tempstr, TEXT_CENTER); + } + pinfoflag = TRUE; +} + +/*-----------------------------------------------------------------------* + * MissToMonst + * + * Used when Rhino charges and collides into something. +**-----------------------------------------------------------------------*/ + +void MissToMonst(int i, int x, int y) +{ + int oldx,oldy; + int newx,newy; + if ((DWORD)i >= MAXMISSILES) + { +#if defined(_DEBUG) + app_fatal("MissToMonst: Invalid missile %d",i); +#else + return; +#endif + } + MissileStruct *Miss = &missile[i]; + int m = Miss->_misource; + if ((DWORD)m >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("MissToMonst: Invalid monster %d",m); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[m]; + int pnum; + + app_assert(Monst->_mmode == MM_MISSILE); + + oldx = Miss->_mix; + oldy = Miss->_miy; + + dMonster[x][y] = m+1; + + Monst->_mdir = Miss->_mimfnum; + Monst->_mx = x; + Monst->_my = y; + M_StartStand(m, Monst->_mdir); + + if(EquivMonst(Monst->MType->mtype, MT_INCIN)) + M_StartFadein(m, Monst->_mdir, FALSE); + else { + if ((Monst->_mFlags & MFLAG_MID) == 0) + M_StartHit(m,-1,0); + else + M2MStartHit(m,-1,0); + } + + if ((Monst->_mFlags & MFLAG_MID) == 0) { + pnum = dPlayer[oldx][oldy]-1; + if((dPlayer[oldx][oldy] > 0) + && (Monst->MType->mtype != MT_GLOOM) + && !EquivMonst(Monst->MType->mtype, MT_INCIN)) + { + M_TryH2HHit(m, dPlayer[oldx][oldy]-1, 500, Monst->mMinDamage2, Monst->mMaxDamage2); + + // make sure player didn't go change location during h2hhit + if (pnum == dPlayer[oldx][oldy]-1 + && !EquivMonst(Monst->MType->mtype, MT_NSNAKE)) + { + // make sure player is doing a hit animation + if (plr[pnum]._pmode != PM_GOTHIT && plr[pnum]._pmode != PM_DEATH) + StartPlrHit(pnum, 0, TRUE); + + // knock opponent back one square + newx = oldx + offset_x[Monst->_mdir]; + newy = oldy + offset_y[Monst->_mdir]; + if(PosOkPlayer(pnum, newx, newy)) + { + plr[pnum]._px = newx; + plr[pnum]._py = newy; + FixPlayerLocation(pnum,plr[pnum]._pdir); + FixPlrWalkTags(pnum); + dPlayer[newx][newy] = pnum + 1; + SetPlayerOld(pnum); + } + } + } + } else { + if((dMonster[oldx][oldy] > 0) + && (Monst->MType->mtype != MT_GLOOM) && !EquivMonst(Monst->MType->mtype, MT_INCIN)) + { + M_TryM2MHit(m, dMonster[oldx][oldy]-1, 500, Monst->mMinDamage2, Monst->mMaxDamage2); + if (!EquivMonst(Monst->MType->mtype, MT_NSNAKE)) + { + // knock opponent back one square + newx = oldx + offset_x[Monst->_mdir]; + newy = oldy + offset_y[Monst->_mdir]; + if(PosOkMonst(dMonster[oldx][oldy]-1, newx, newy)) + { + // This assumes that monster got hit (since we use a 500% hit above) + // so we don't have to clean up his area, and we assume pnum is positive + pnum = dMonster[newx][newy] = dMonster[oldx][oldy]; + dMonster[oldx][oldy] = 0; + --pnum; + monster[pnum]._mfutx = monster[pnum]._mx = newx; + monster[pnum]._mfuty = monster[pnum]._my = newy; + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static bool CheckForMissileWalls(int i, int x, int y) +{ + bool ret = true; + int mi = dMissile[x][y]; + + if(mi && i >= 0) + { + bool fire = false; + bool lightwall = false; + + if(mi > 0) { + if(missile[mi]._mitype == MIT_FIREWALL) + fire = true; + else if ( missile[mi]._mitype == MIT_LIGHTWALL) + lightwall = true; + } else { + for(mi = 0; mi < nummissiles; ++mi) { + int const mx = missileactive[mi]; + + if (missile[mx]._mix == x && + missile[mx]._miy == y) { + if(missile[mx]._mitype == MIT_FIREWALL) { + fire = true; + break; + } + if (missile[mx]._mitype == MIT_LIGHTWALL) { + lightwall = true; + break; + } + } + } + } + if ((fire && !(monster[i].mMagicRes & M_IF)) || (fire && (monster[i].MType->mtype == MT_DIABLO))) + ret = FALSE; + if ((lightwall && !(monster[i].mMagicRes & M_IL)) || (lightwall && (monster[i].MType->mtype == MT_DIABLO))) + ret = FALSE; + } + + return ret; +} +/*-----------------------------------------------------------------------* + * PosOkMonst + * + * Map position (x,y) is ok for placement of a monster. +**-----------------------------------------------------------------------*/ + +BOOL PosOkMonst(int i, int x, int y) +{ + BOOL ret = TRUE; + ret = !SolidLoc(x, y) && !dPlayer[x][y] && !dMonster[x][y]; + int oi = dObject[x][y]; + + if(ret && oi) + { + if (oi > 0) oi -= 1; + else oi = -(oi + 1); + + if (object[oi]._oSolidFlag) ret = FALSE; + } + + if(ret) + { + ret = CheckForMissileWalls(i, x, y); + } + + return ret; +} + +/*-----------------------------------------------------------------------* + * PosOkMonst2 + * + * Map position (x,y) is ok for placement of a monster. + * Same as PosOkMonst, except ignores other monsters and players +**-----------------------------------------------------------------------*/ + +BOOL PosOkMonst2(int i, int x, int y) +{ + BOOL ret = TRUE; + int oi = dObject[x][y]; + + ret = !SolidLoc(x, y); + + if(ret && oi) + { + if (oi > 0) oi -= 1; + else oi = -(oi + 1); + + if (object[oi]._oSolidFlag) ret = FALSE; + } + if(ret) + { + ret = CheckForMissileWalls(i, x, y); + } + + return ret; +} + +/*-----------------------------------------------------------------------* + * PosOkMonst + * + * Map position (x,y) is ok for placement of a monster. + * Same as PosOkMonst3, except ignores doors +**-----------------------------------------------------------------------*/ + +BOOL PosOkMonst3(int i, int x, int y) +{ + BOOL ret = TRUE; + bool isdoor = false; + int oi = dObject[x][y]; + + if(oi) + { + if (oi > 0) oi -= 1; + else oi = -(oi + 1); + + int const objtype = object[oi]._otype; + isdoor = (objtype == OBJ_L1DOORL + || objtype == OBJ_L1DOORR + || objtype == OBJ_L2DOORL + || objtype == OBJ_L2DOORR + || objtype == OBJ_L3DOORL + || objtype == OBJ_L3DOORR); + if (object[oi]._oSolidFlag && !isdoor) + ret = FALSE; + } + + if (ret) + ret = (!SolidLoc(x, y) || isdoor) && !dPlayer[x][y] && !dMonster[x][y]; + + if(ret) + { + ret = CheckForMissileWalls(i, x, y); + } + + return ret; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL IsSkel(int mt) +{ + return EquivMonst(mt, MT_WSKELAX) + || EquivMonst(mt, MT_WSKELBW) + || EquivMonst(mt, MT_WSKELSD); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL IsGoat(int mt) +{ + return EquivMonst(mt, MT_NGOATMC) + || EquivMonst(mt, MT_NGOATBW); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_SpawnSkel(int x, int y, int dir) +{ + int i,j; + int skeltypes = 0; + int skel; + + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes; ++i) + if (IsSkel(Monsters[i].mtype)) + ++skeltypes; + + if (skeltypes) + { + j = random(136,skeltypes); + skeltypes = 0; + for (i = 0; i < nummtypes && skeltypes <= j; ++i) + if(IsSkel(Monsters[i].mtype)) + ++skeltypes; + --i; + skel = AddMonster(x, y, dir, i, TRUE); + if (skel != -1) M_StartSpStand(skel, dir); + return skel; + } + else + return -1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ActivateSpawn(int i, int x, int y, int dir) +{ + dMonster[x][y] = i + 1; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + M_StartSpStand(i, dir); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL SpawnSkeleton(int ii, int x, int y) +{ + int monstok[3][3]; + int i,j,xx,yy,rs; + BOOL savail; + + if (ii == -1) return FALSE; + // Try location first + if (PosOkMonst(-1, x, y)) { + ActivateSpawn(ii, x, y, GetDirection(x, y, x, y)); + } else { + // Try surrounding squares + savail = FALSE; + yy = 0; + for (j = (y-1); j <= (y+1); ++j) { + xx = 0; + for (i = (x-1); i <= (x+1); ++i) { + monstok[xx][yy] = PosOkMonst(-1, i,j); + savail |= monstok[xx][yy]; + ++xx; + } + ++yy; + } + + // No fit, no good + if (!savail) return(FALSE); + + // Place skeleton + rs = random(137,15) + 1; + xx = 0; + yy = 0; + while (rs > 0) { + if (monstok[xx][yy]) --rs; + if (rs > 0) { + ++xx; + if (xx == 3) { + xx = 0; + ++yy; + if (yy == 3) yy = 0; + } + } + } + xx = xx + x - 1; + yy = yy + y - 1; + ActivateSpawn(ii, xx, yy, GetDirection(xx, yy, x, y)); + } + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PreSpawnSkeleton() +{ + int i,j; + int skeltypes = 0; + int skel; + + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes; ++i) + if (IsSkel(Monsters[i].mtype)) + ++skeltypes; + + if (skeltypes) + { + j = random(136,skeltypes); + skeltypes = 0; + for (i = 0; i < nummtypes && skeltypes <= j; ++i) + { + if(IsSkel(Monsters[i].mtype)) + ++skeltypes; + } + --i; + skel = AddMonster(0, 0, 0, i, FALSE); + if (skel != -1) M_StartStand(skel, 0); + return skel; + } + else + return -1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void TalktoMonster(int i) +{ + int pnum, itm; + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("TalktoMonster: Invalid monster %d",i); +#else + return; +#endif + } + MonsterStruct *Monst = &monster[i]; + pnum = Monst->_menemy; + + Monst->_mmode = MM_TALK; + + if ((Monst->_mAi != AI_SNOTSPIL) && (Monst->_mAi != AI_LACHDANAN)) + return; + + if (QuestStatus(Q_LTBANNER)) { + if ((quests[Q_LTBANNER]._qvar1 == 2) && (PlrHasItem(pnum, IDI_BANNER, itm))) { + RemoveInvItem(pnum, itm); + quests[Q_LTBANNER]._qactive = QUEST_DONE; + Monst->mtalkmsg = TXT_BOL3; + Monst->_mgoal = MG_TALK; + } + } + if (QuestStatus(Q_VEIL)) { + if ((Monst->mtalkmsg >= TXT_VEIL1) && (PlrHasItem(pnum, IDI_GLDNELIX, itm))) { + RemoveInvItem(pnum, itm); + Monst->mtalkmsg = TXT_VEIL3; + Monst->_mgoal = MG_TALK; + } + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnGolum(int i, int x, int y, int mi) +{ + if ((DWORD)i >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("SpawnGolum: Invalid monster %d",i); +#else + return; +#endif + } + dMonster[x][y] = i + 1; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + monster[i]._pathcount = 0; + + monster[i]._mmaxhp = ((plr[i]._pMaxMana/3)<<1) + (((missile[mi]._mispllvl << HP_SHIFT) << 3) + ((missile[mi]._mispllvl << HP_SHIFT) << 1)); + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mArmorClass = 25; + monster[i].mHit = 40 + (plr[i]._pLevel << 1) + ((missile[mi]._mispllvl << 2) + (missile[mi]._mispllvl)); + monster[i].mMinDamage = 8 + (missile[mi]._mispllvl << 1); + monster[i].mMaxDamage = 16 + (missile[mi]._mispllvl << 1); + + monster[i]._mFlags |= MFLAG_MKILLER; + M_StartSpStand(i, 0); + M_Enemy(i); + + void NetSendCmdGolem(BYTE, BYTE, BYTE, BYTE, long, BYTE); + if (i == myplr) + NetSendCmdGolem(monster[i]._mx, monster[i]._my, monster[i]._mdir, monster[i]._menemy, monster[i]._mhitpoints, currlevel); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CanTalkToMonst(int m) +{ + if ((DWORD)m >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("CanTalkToMonst: Invalid monster %d",m); +#else + return FALSE; +#endif + } + if (monster[m]._mgoal == MG_TALK) return(TRUE); + if (monster[m]._mgoal == MG_WAITTOTALK) return(TRUE); + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CheckMonsterHit(int m, BOOL &ret) +{ + if ((DWORD)m >= MAXMONSTERS) + { +#if defined(_DEBUG) + app_fatal("CheckMonsterHit: Invalid monster %d",m); +#else + return FALSE; +#endif + } + if (monster[m]._mAi == AI_GARG && (monster[m]._mFlags & MFLAG_STILL)) + { + monster[m]._mFlags &= ~MFLAG_STILL; + monster[m]._mmode = MM_SATTACK; + ret = TRUE; + return(TRUE); + } + else if(EquivMonst(monster[m].MType->mtype, MT_COUNSLR) + && (monster[m]._mgoal != MG_ATTACK)) + { + ret = FALSE; + return TRUE; + } + return FALSE; +} + +//****************************************************************** +//****************************************************************** +int encode_enemy(int m) +{ + if (monster[m]._mFlags & MFLAG_MID) + return monster[m]._menemy + MAX_PLRS; + else + // enemy is player, guaranteed < MAX_PLRS + return monster[m]._menemy; +} + +//****************************************************************** +//****************************************************************** +void decode_enemy(int m, int enemy) +{ + if (enemy < MAX_PLRS) { + monster[m]._mFlags &= ~MFLAG_MID; + monster[m]._menemy = enemy; + monster[m]._menemyx = plr[enemy]._pfutx; + monster[m]._menemyy = plr[enemy]._pfuty; + } + else { + monster[m]._mFlags |= MFLAG_MID; + enemy -= MAX_PLRS; + monster[m]._menemy = enemy; + monster[m]._menemyx = monster[enemy]._mfutx; + monster[m]._menemyy = monster[enemy]._mfuty; + } +} diff --git a/MONSTER.H b/MONSTER.H new file mode 100644 index 0000000..199996e --- /dev/null +++ b/MONSTER.H @@ -0,0 +1,304 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/MONSTER.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXMONSTERS 200 + +#define MONSTERTYPES 200 + +//#define MAX_LVLMTYPES 16 //JKE 7/29 +#define MAX_LVLMTYPES 24 // new crypt level + +#define MONSTDENSITY 30 + +#define MFLAG_INVISIBLE 0x00000001 +#define MFLAG_BACKWARDS 0x00000002 +#define MFLAG_STILL 0x00000004 // Used for Gargoyles while they are stone +#define MFLAG_NOHEAL 0x00000008 // Monster can no longer heal itself +#define MFLAG_MID 0x00000010 // _menemy element indexes monsters[] (default is plr[]) +#define MFLAG_MKILLER 0x00000020 // monster is an attacker monster +#define MFLAG_DROP 0x00000040 // drop an item at special time +#define MFLAG_KNOCKBACK 0x00000080 // knock back enemy one square +#define MFLAG_PATH 0x00000100 // use path algorithm to navigate around obstacles +#define MFLAG_CHECKDOORS 0x00000200 // this monster has door-opening abilities +#define MFLAG_NOENEMY 0x00000400 // monster has no enemy (because there are none left) +#define MFLAG_BERSERK 0x00000800 // monster attacks everything. + +// Monster Placement Flags +#define MPFLAG_SCATTER 1 // scatter these all over +#define MPFLAG_DONT 2 // don't place -- taken care of elsewhere +#define MPFLAG_UNIQ 4 // place once, as in a unique + +#define MAX_ANIMTYPE 6 + +#define M_ID 0 +#define P_ID 1 + +/*-----------------------------------------------------------------------* +** Macros +**-----------------------------------------------------------------------*/ + +#define DIST(x,y,d) (abs(x) < d && abs(y) < d) +#define EquivMonst(m,t) ((m) >= (t) && (m) <= (t)+3) + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +// AnimStruct +// One per animation, e.g. Fat demon walk +typedef struct { + BYTE *CMem; + BYTE *Cels[8]; + int Frames; + int Rate; +} AnimStruct; + +typedef struct { + TSnd * effect[2]; +} SndEffectStruct; + +typedef struct { + long mAnimWidth; // width of monster + long mImgSize; // Size of graphics for monster + char *filename; // pattern used to denote this monster in file names + BOOL has_special; // has a special animation + char *sndfile; // Name of the sound file + BOOL snd_special; // has a special snd + BOOL transflag; // Does this monster need gfx translation + char *TransFile; // Name of the gfx translation file + int Frames[MAX_ANIMTYPE]; + int Rate[MAX_ANIMTYPE]; + char *mName; // name + char mMinDLvl; // Min dungeon level + char mMaxDLvl; // Max dungeon level + char mLevel; // monster ranking + long mMinHP; // base hitpoints + long mMaxHP; // random hitpoints + BYTE mAi; // AI type + DWORD mFlags; // ai related flags + BYTE mInt; // Intelligence (0-3) + BYTE mHit; // hit% + BYTE mAFNum; // Which frame to check for attack on + BYTE mMinDamage; // min damage + BYTE mMaxDamage; // max damage + BYTE mHit2; // hit% + BYTE mAFNum2; // Which frame to check for attack on + BYTE mMinDamage2; // min damage + BYTE mMaxDamage2; // max damage + char mArmorClass; // Armor class + char mMonstClass; // Monster class + WORD mMagicRes; // Magic resistance + WORD mMagicRes2; // Magic resistance (for nightmare & hell modes) + WORD mTreasure; // Treasure + char mSelFlag; // Which type of selection + WORD mExp; // base experience +} MonsterData; + +// CMonster +// One per monster class, e.g. Fat demon +typedef struct { + int mtype; + BYTE mPlaceFlags; // monster placement flags + AnimStruct Anims[6]; + SndEffectStruct Snds[4]; + long mAnimWidth; // width of monster + long mAnimWidth2; // (width - 64) / 2 of monster for drawing + long mMinHP; // base hitpoints + long mMaxHP; // random hitpoints + BOOL has_special; // has a special animation + BYTE mAFNum; // Which frame to check for attack on + char mdeadval; // Which val to put in flags when dead + MonsterData *MData; + byte *pTrans; // Pointer to gfx translation table +} CMonster; + +// MonsterStruct +// One per monster in the dungeon, e.g., Joe the Fat demon +typedef struct { + int _mMTidx; // Type index into Monsters[] array (*** NOT MT_whatever ***) + int _mmode; // monsters current mode + BYTE _mgoal; // higher-level mode, i.e., run away! + int _mgoalvar1; // goal scratch 1 + int _mgoalvar2; // goal scratch 2 + int _mgoalvar3; // goal scratch 3 + int _mgoalvar4; // goal scratch 4 + BYTE _pathcount; // + int _mx; // monster map x + int _my; // monster map y + int _mfutx; // monster future map x + int _mfuty; // monster future map y + int _moldx; // monster starting walk map x + int _moldy; // monster starting walk map y + long _mxoff; // offset x from left of map tile + long _myoff; // offset y from bottom of map tile + long _mxvel; // current x rate + long _myvel; // current y rate + int _mdir; // current facing direction + int _menemy; // Which player is my enemy + BYTE _menemyx; // x location of enemy in dungeon + BYTE _menemyy; // y " + BYTE *_mAnimData; // Data pointer to anim tables + int _mAnimDelay; // anim delay amount + int _mAnimCnt; // current anim delay value + int _mAnimLen; // number of anim frames + int _mAnimFrame; // current anim frame + int _meflag; // draw extra tile to left for walk fix (flag) + BOOL _mDelFlag; // Delete/Kill monster + long _mVar1; // scratch var 1 + long _mVar2; // scratch var 2 + long _mVar3; // scratch var 3 + long _mVar4; // scratch var 4 + long _mVar5; // scratch var 5 + long _mVar6; // scratch var 6 + long _mVar7; // scratch var 7 + long _mVar8; // scratch var 8 + long _mmaxhp; // Fully healed monster hit points + long _mhitpoints; // Monster hit points + BYTE _mAi; // AI type + BYTE _mint; // Monster intelligence + DWORD _mFlags; + BYTE _msquelch; // keeps monster active for a while after it's not visible + int _mAFNum; // Which frame to check for attack on + int _lastx; // Coordinates where player was last seen + int _lasty; + + int _mRndSeed; // Random seed for item generation + int _mAISeed; // Random seed for AI (multiplayer only) + + BOOL _Wandering; // Is this a wandering monster + + BYTE _uniqtype; // Type of unique (0==None) + BYTE _uniqtrans; // Pal translation index + char _udeadval; // If unique, it's dead val + + char mWhoHit; // Which players have hit me so I can divvy up experience + + char mLevel; // monster ranking + WORD mExp; // base experience + BYTE mHit; // hit% + BYTE mMinDamage; // min damage + BYTE mMaxDamage; // max damage + BYTE mHit2; // hit% + BYTE mMinDamage2; // min damage + BYTE mMaxDamage2; // max damage + char mArmorClass; // Armor class + WORD mMagicRes; // Magic resistance + int mtalkmsg; // talking monster message number + + BYTE leader; // monster # of pack leader + BYTE leaderflag; + BYTE packsize; // # of monsters in pack + + BYTE mlid; // light id + + // Anything below this will not be saved or sent during a sync + #define SAVE_MONSTER_SIZE offsetof(MonsterStruct,mName) + char *mName; + CMonster *MType; + MonsterData *MData; +} MonsterStruct; + + +typedef struct { + int mtype; // i.e. MT_SKELSD + char * mName; + char * mTFile; // Translation filename + BYTE mlevel; // level on which it appears + WORD mmaxhp; + BYTE mAi; // AI type + BYTE mint; // AI level + BYTE mMinDamage; // min damage + BYTE mMaxDamage; // max damage + WORD mMagicRes; // Magic resistance + WORD mUnqAttr; // Unique attributes, i.e., pack leader + BYTE mUnqVar1; // parameter to unique attribute + BYTE mUnqVar2; // " + int mtalkmsg; // talking monster message number +} UniqMonstStruct; + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern MonsterStruct monster[MAXMONSTERS]; +extern long nummonsters; +extern int monstactive[MAXMONSTERS]; + +extern long monstkills[MONSTERTYPES]; + +extern int offset_x[]; +extern int offset_y[]; +extern int left[]; +extern int right[]; +extern int opposite[]; + +extern int nummtypes; +extern CMonster Monsters[MAX_LVLMTYPES]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitLevelMonsters(); +void GetLevelMTypes(); +void InitMonsterGFX(int monst); +void InitMonsterSND(int monst); +void FreeMonsterGFX(); +void InitMonsters(); +void TalktoMonster(int i); +void SetMapMonsters(BYTE *, int, int); + +void ProcessMonsters(); + +void M_StartStand(int i, int md); +void M_StartKill(int, int); +void M_SyncStartKill(int, int, int, int); +void M_StartHit(int, int, int); +void M_GetKnockback(int i); +void M_WalkDir(int i, int md); +void MAI_Golum(int i); + +BOOL DirOK(int i, int mdir); + +void SyncMonsterAnim(int); + +void PrintMonstHistory(int); + +void MissToMonst(int i, int x, int y); +BOOL PosOkMonst(int i, int x, int y); +BOOL PosOkMissile(int x, int y); + +BOOL IsSkel(int mt); +BOOL SpawnSkeleton(int i, int x, int y); +int PreSpawnSkeleton(); +void SpawnGolum(int, int, int, int); +void DeleteMonsterList(); +void MonstStartKill(int, int, BOOL); + +void PlaceQuestMonsters(); + +int AddMonster(int x, int y, int dir, int mtype, BOOL InMap); + +BOOL IsGoat(int mt); + +BOOL CanTalkToMonst(int m); + +BOOL CheckMonsterHit(int m, BOOL &ret); +BOOL LineClear(int, int, int, int); +int encode_enemy(int m); +void decode_enemy(int m, int enemy); + +void Hose_NaKrul(); +void CloneMonster(int m); diff --git a/MONSTER.SAV b/MONSTER.SAV new file mode 100644 index 0000000..953cdc6 --- /dev/null +++ b/MONSTER.SAV @@ -0,0 +1,6618 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Monsters file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MONSTER.CPP 3 1/23/97 7:22p Rseis $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm.h" +#include "sound.h" +#include "debug.h" +#include "monster.h" +#include "monstdat.h" +#include "engine.h" +#include "gendung.h" +#include "lighting.h" +#include "items.h" +#include "itemdat.h" +#include "player.h" +#include "effects.h" +#include "dead.h" +#include "missiles.h" +#include "misdat.h" +#include "control.h" +#include "objects.h" +#include "objdat.h" +#include "path.h" +#include "quests.h" +#include "minitext.h" +#include "textdat.h" +#include "monstint.h" +#include "msg.h" +#include "inv.h" +#include "multi.h" +#include "trigs.h" +#include "themes.h" +#include "drlg_l4.h" +#include "towners.h" +#include "setmaps.h" +#include "palette.h" +#include "scrollrt.h" +#include "cursor.h" + + +/*-----------------------------------------------------------------------* +** Function Prototypes +**-----------------------------------------------------------------------*/ +BOOL LineClear(int x1, int y1, int x2, int y2); +int M_GetDir(int i); + +typedef BOOL (*CHECKFUNC)(int x, int y); +typedef BOOL (*CHECKFUNC1)(int arg1, int x, int y); +BOOL LineClearF(CHECKFUNC Clear, int x1, int y1, int x2, int y2); +BOOL LineClearF1(CHECKFUNC1 Clear, int arg, int x1, int y1, int x2, int y2); +BOOL CheckNoSolid(int x, int y); +BOOL PosOkMissile(int x, int y); +int M_SpawnSkel(int x, int y, int dir); +void M_Teleport(int i); +void PlaceGroup(int, int, BOOL, int); +void ClrAllMonsters(); +BOOL PosOkMonst2(int i, int x, int y); +BOOL PosOkMonst3(int i, int x, int y); +BOOL effect_is_playing(int nSFX); + +extern const TextDataStruct alltext[]; + +//void DaveMonstMap(BOOL initupdate, int pnum); + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +MonsterStruct monster[MAXMONSTERS]; +long nummonsters; +int totalmonsters; + +// monstactive -- indexes into monster[] +int monstactive[MAXMONSTERS]; // [0..nummonsters-1] -- active monsters + // [nummonsters..MAXMONSTERS-1] -- available monsters + +int nummtypes = 0; +long monstimgtot; +int gfxflags; +int uniquetrans; // index to next available unique monster palette translation + +BYTE mleveltypes[NUMLEVELS][MAX_LVLMTYPES]; + +long monstkills[MONSTERTYPES]; + +static char sgszInvalidMonstName[] = "Invalid Monster"; + +/*-----------------------------------------------------------------------* +** Defines +**-----------------------------------------------------------------------*/ +#define PACK_MEMBER 1 +#define PACK_NOMEMBER 2 + +#define INITMONSTRAD 15 // Initial vision radius for no monsters + +/*-----------------------------------------------------------------------* +** Macros +**-----------------------------------------------------------------------*/ +#define InBounds(x,y) (0 <= (y) && (y) < MAXDUNY && 0 <= (x) && (x) < MAXDUNX) +#define WALKMODE(m) ((m) == MM_WALK || (m) == MM_WALK2 || (m) == MM_WALK3) +#define Sign(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0) +#define Mod(val, x) ((val) < 0 ? (val)+(x) : (val) >= (x) ? (val)-(x) : (val)) + +/*-----------------------------------------------------------------------* +** File Variables +**-----------------------------------------------------------------------*/ +// I had to add this variable, because _mVar2 seems like +// it must have been trashed, since sound never came on again -- pjw +static BYTE sgbSaveSoundOn; + + // 16 32 64 +int MWVel[24][3] = { {0x100,0x200,0x400}, // 1 frame + {0x80,0x100,0x200}, // 2 frame + {0x55,0xaa,0x155}, // 3 frame + {0x40,0x80,0x100}, // 4 frame + {0x33,0x66,0xcc}, // 5 frame + {0x2a,0x55,0xaa}, // 6 frame + {0x24,0x49,0x92}, // 7 frame + {0x20,0x40,0x80}, // 8 frame + {0x1c,0x38,0x71}, // 9 frame + {0x1a,0x33,0x66}, // 10 frame + {0x17,0x2e,0x5d}, // 11 frame + {0x15,0x2a,0x55}, // 12 frame + {0x13,0x27,0x4e}, // 13 frame + {0x12,0x24,0x49}, // 14 frame + {0x11,0x22,0x44}, // 15 frame + {0x10,0x20,0x40}, // 16 frame + {0x0f,0x1e,0x3c}, // 17 frame + {0x0e,0x1c,0x39}, // 18 frame + {0x0d,0x1a,0x36}, // 19 frame + {0x0c,0x19,0x33}, // 20 frame + {0x0c,0x18,0x30}, // 21 frame + {0x0b,0x17,0x2e}, // 22 frame + {0x0b,0x16,0x2c}, // 23 frame + {0x0a,0x15,0x2a} }; // 24 frame + +// Muli-player monster multiplier % +/*int MPMM[4] = { 100, // 1 player + 150, // 2 player + 175, // 3 player + 200 }; // 4 player*/ + +CMonster Monsters[MAX_LVLMTYPES]; + +char animletter[] = "nwahds"; +int left[] = {7,0,1,2,3,4,5,6}; +int right[] = {1,2,3,4,5,6,7,0}; +int opposite[] = {4,5,6,7,0,1,2,3}; +int offset_x[] = {1,0,-1,-1,-1,0,1,1}; +int offset_y[] = {1,1,1,0,-1,-1,-1,0}; +int rnd5[] = { 5, 10, 15, 20 }; +int rnd10[] = { 10, 15, 20, 30 }; +int rnd20[] = { 20, 30, 40, 50 }; +int rnd60[] = { 60, 70, 80, 90 }; + + +void MAI_Zombie(int); +void MAI_Fat(int); +void MAI_SkelSd(int); +void MAI_SkelBow(int); +void MAI_Scav(int); +void MAI_Rhino(int); +void MAI_GoatMc(int); +void MAI_GoatBow(int); +void MAI_Fallen(int); +void MAI_Magma(int); +void MAI_SkelKing(int); +void MAI_Bat(int); +void MAI_Garg(int); +void MAI_Cleaver(int); +void MAI_Succ(int); +void MAI_Sneak(int); +void MAI_Storm(int); +void MAI_Fireman(int i); +void MAI_Garbud(int); +void MAI_Acid(int); +void MAI_AcidUniq(int); +void MAI_Golum(int); +void MAI_Zhar(int); +void MAI_SnotSpil(int); +void MAI_Snake(int); +void MAI_Counselor(int); +void MAI_Mega(int); +void MAI_Diablo(int); +void MAI_Lazurus(int); +void MAI_Lazhelp(int); +void MAI_Lachdanan(int); +void MAI_Warlord(int); + +void (*AiProc[])(int) = +{ + MAI_Zombie, + MAI_Fat, + MAI_SkelSd, + MAI_SkelBow, + MAI_Scav, + MAI_Rhino, + MAI_GoatMc, + MAI_GoatBow, + MAI_Fallen, + MAI_Magma, + MAI_SkelKing, + MAI_Bat, + MAI_Garg, + MAI_Cleaver, + MAI_Succ, + MAI_Sneak, + MAI_Storm, + MAI_Fireman, + MAI_Garbud, + MAI_Acid, + MAI_AcidUniq, + MAI_Golum, + MAI_Zhar, + MAI_SnotSpil, + MAI_Snake, + MAI_Counselor, + MAI_Mega, + MAI_Diablo, + MAI_Lazurus, + MAI_Lazhelp, + MAI_Lachdanan, + MAI_Warlord, +}; + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void TranslateMonsterGFX(int monst, BOOL sp) +{ + app_assert((DWORD)monst < MAX_LVLMTYPES); + int i,j,nf; + BYTE * pData = Monsters[monst].pTrans; + + for (int n = 256; n--; pData++) { + if (*pData == 255) + *pData = 0; + } + nf = sp ? 6 : 5; + for (j = 0; j < nf; j++) { + if ((j == 1) && (Monsters[monst].mtype >= MT_COUNSLR) && (Monsters[monst].mtype <= MT_ADVOCATE)) continue; + for (i = 0; i < 8; i++) + TranslateCels(Monsters[monst].Anims[j].Cels[i], Monsters[monst].pTrans, Monsters[monst].Anims[j].Frames); + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL MonstTaken(int i) +{ + int lev; + BOOL found = FALSE; + int m; + int templvl; // JKE + +// Temp hack for monsters JKE 7/30 + templvl = currlevel; +// if (templvl > 20) templvl -= 8; +// else if (templvl > 16) templvl -= 4; + +// for(lev = 0; lev <= currlevel && !found; lev++) // JKE + for(lev = 0; lev <= templvl && !found; lev++) + { + for(m = 0; m < MAX_LVLMTYPES && mleveltypes[m] && !found; m++) + found = ((i < mleveltypes[lev][m]-1) + && + !strcmp(monsterdata[i].filename, monsterdata[mleveltypes[lev][m]-1].filename)); + } + return found; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitLevelMonsters() +{ + int i; + + nummtypes = 0; + monstimgtot = 0; + gfxflags = 0; + + for (i = 0; i < MAX_LVLMTYPES; i++) + Monsters[i].mPlaceFlags = 0; + + ClrAllMonsters(); + nummonsters = 0; + totalmonsters = MAXMONSTERS; // this value gets further restricted later on + + // active monsters list + for (i = 0; i < MAXMONSTERS; i++) { + monstactive[i] = i; + } + uniquetrans = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int AddMonsterType(int type, int placeflag) +{ + int i; + BOOL done = FALSE; + + // check if this type is already being loaded + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes && !done; i++) + done = Monsters[i].mtype == type; + i--; + + if (!done) + { + i = nummtypes++; + Monsters[i].mtype = type; + monstimgtot += monsterdata[type].mImgSize; + InitMonsterGFX(i); + InitMonsterSND(i); + } + + Monsters[i].mPlaceFlags |= placeflag; + + return i; +} + +/*-----------------------------------------------------------------------* + * GetLevelMTypes() + * + * Pick the monsters types to be placed in this level +**-----------------------------------------------------------------------*/ + +void GetLevelMTypes() +{ + int typelist[MONSTERTYPES]; + int nt, i; + int tidx, mt; + int minl,maxl; + char mamask; + int templvl; // temp hack JKE + + #if IS_VERSION(SHAREWARE) + mamask = MAT_SW; + #else + mamask = MAT_SW | MAT_YES; + #endif + + // Certain monsters are required for certain levels + + AddMonsterType(MT_GOLEM, MPFLAG_DONT); + + if (currlevel == 16) { + AddMonsterType(MT_ADVOCATE, MPFLAG_SCATTER); + AddMonsterType(MT_RBLACK, MPFLAG_SCATTER); + AddMonsterType(MT_DIABLO, MPFLAG_DONT); + return; + } + + // Set levels load their own monster types + if (!setlevel) + { + if (QuestStatus(Q_BUTCHER)) { + AddMonsterType(MT_CLEAVER, MPFLAG_DONT); + } + + if (QuestStatus(Q_GARBUD)) { + AddMonsterType(UniqMonst[MU_GARBUD].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_ZHAR)) { + AddMonsterType(UniqMonst[MU_ZHAR].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_LTBANNER)) { + AddMonsterType(UniqMonst[MU_SNOTSPIL].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_VEIL)) { + AddMonsterType(UniqMonst[MU_LACHDA].mtype, MPFLAG_UNIQ); + } + + if (QuestStatus(Q_WARLORD)) { + AddMonsterType(UniqMonst[MU_WARLORD].mtype, MPFLAG_UNIQ); + } + + if (gbMaxPlayers != 1 && currlevel == quests[Q_SKELKING]._qlevel) { + AddMonsterType(MT_SKING, MPFLAG_UNIQ); + + // Skelking requires skeleton minions + int skeltypes[LASTMT]; + int numskeltypes = 0; + + for (i = MT_WSKELAX; i <= MT_XSKELSD; i++) + { + if (IsSkel(i)) + { + minl = ((monsterdata[i].mMinDLvl * 15) / 30) + 1; + maxl = ((monsterdata[i].mMaxDLvl * 15) / 30) + 1; + if ((currlevel >= minl) && (currlevel <= maxl) && (MonstAvailTbl[i] & mamask)) + skeltypes[numskeltypes++] = i; + } + } + AddMonsterType(skeltypes[random(88,numskeltypes)], MPFLAG_SCATTER); + } + + // Pick general monsters + + // Make list of available monster types for this level +// Temp hack monster JKE + templvl = currlevel; +// if (templvl > 20) templvl -=8; +// else if (templvl > 16) templvl -= 4; + + nt = 0; + for (i = 0; i < LASTMT; i++) { + minl = ((monsterdata[i].mMinDLvl * 15) / 30) + 1; + maxl = ((monsterdata[i].mMaxDLvl * 15) / 30) + 1; +// if ((currlevel >= minl) && (currlevel <= maxl) && (MonstAvailTbl[i] & mamask)) { +// typelist[nt] = i; +// nt++; +// } + // use templvl to patch over current level + if ((templvl >= minl) && (templvl <= maxl) && (MonstAvailTbl[i] & mamask)) { + typelist[nt] = i; + nt++; + } + } + + if (monstdebug) + { + for(i = 0; i < debugmonsttypes; i++) + AddMonsterType(DebugMonsters[i], MPFLAG_SCATTER); + } + else + { + while ((nt > 0) && (nummtypes < MAX_LVLMTYPES) && (monstimgtot < IMG_MAX)) { + // prune excessively large monsters + for (i = 0; i < nt; ) + { + if (monsterdata[typelist[i]].mImgSize > IMG_MAX - monstimgtot) + typelist[i] = typelist[--nt]; + else + i++; + } + + if (nt) + { + tidx = random(88, nt); + mt = typelist[tidx]; + AddMonsterType(mt, MPFLAG_SCATTER); + typelist[tidx] = typelist[--nt]; + } + } + } + } + else if (setlvlnum == SL_SKELKING) { + AddMonsterType(MT_SKING, MPFLAG_UNIQ); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitMonsterGFX (int monst) +{ + int anim; + long i; + char strBuff[256]; + int mtype; + BYTE *p; + + app_assert((DWORD)monst < MAX_LVLMTYPES); + mtype = Monsters[monst].mtype; + for(anim = 0; anim < MAX_ANIMTYPE; anim++) + { + if((!(animletter[anim] == 's' && !monsterdata[mtype].has_special)) && monsterdata[mtype].Frames[anim] > 0) + { + sprintf(strBuff, monsterdata[mtype].filename, animletter[anim]); + app_assert(! Monsters[monst].Anims[anim].CMem); + Monsters[monst].Anims[anim].CMem = LoadFileInMemSig(strBuff,NULL,'MONS'); + p = Monsters[monst].Anims[anim].CMem; + if (Monsters[monst].mtype == MT_GOLEM && (animletter[anim] == 's' || animletter[anim] == 'd')) { + for(i=0; i<8; i++) Monsters[monst].Anims[anim].Cels[i] = p; + } else { + for(i=0; i<8; i++) Monsters[monst].Anims[anim].Cels[i] = p + *(DWORD *)(p + (i<<2)); + } + } + Monsters[monst].Anims[anim].Frames = monsterdata[mtype].Frames[anim]; + Monsters[monst].Anims[anim].Rate = monsterdata[mtype].Rate[anim]; + } + Monsters[monst].mAnimWidth = monsterdata[mtype].mAnimWidth; + Monsters[monst].mAnimWidth2 = (monsterdata[mtype].mAnimWidth - 64) >> 1; + Monsters[monst].mMinHP = monsterdata[mtype].mMinHP; + Monsters[monst].mMaxHP = monsterdata[mtype].mMaxHP; + Monsters[monst].has_special = monsterdata[mtype].has_special; + Monsters[monst].mAFNum = monsterdata[mtype].mAFNum; + Monsters[monst].MData = &monsterdata[mtype]; + if (monsterdata[mtype].transflag) { + Monsters[monst].pTrans = LoadFileInMemSig(monsterdata[mtype].TransFile,NULL,'MONS'); + TranslateMonsterGFX(monst, monsterdata[mtype].has_special); + DiabloFreePtr(Monsters[monst].pTrans); + } + if (EquivMonst(mtype, MT_NMAGMA) && ((gfxflags & 0x0001) == 0)) { + gfxflags |= 0x0001; + ILoadMissileGFX(MF_MAGBALL); + } + + if (EquivMonst(mtype, MT_STORM) && ((gfxflags & 0x0002) == 0)) { + gfxflags |= 0x0002; + ILoadMissileGFX(MF_THINLIGHT); + } + + if ((mtype == MT_SUCCUBUS) && ((gfxflags & 0x0004) == 0)) { + gfxflags |= 0x0004; + ILoadMissileGFX(MF_FLARE); + ILoadMissileGFX(MF_FLAREXP); + } + if ((mtype == MT_SNOWWICH) && ((gfxflags & 0x0020) == 0)) { + gfxflags |= 0x0020; + ILoadMissileGFX(MF_BFLARE); + ILoadMissileGFX(MF_BFLAREXP); + } + if ((mtype == MT_HLSPWN) && ((gfxflags & 0x0040) == 0)) { + gfxflags |= 0x0040; + ILoadMissileGFX(MF_DFLARE); + ILoadMissileGFX(MF_DFLAREXP); + } + if ((mtype == MT_SOLBRNR) && ((gfxflags & 0x0080) == 0)) { + gfxflags |= 0x0080; + ILoadMissileGFX(MF_CFLARE); + ILoadMissileGFX(MF_CFLAREXP); + } + + if (EquivMonst(mtype, MT_INCIN) && ((gfxflags & 0x0008) == 0)) { + gfxflags |= 0x0008; + ILoadMissileGFX(MF_KRULL); + } + + if (EquivMonst(mtype, MT_NACID) && ((gfxflags & 0x0010) == 0)) { + gfxflags |= 0x0010; + ILoadMissileGFX(MF_ACID); + ILoadMissileGFX(MF_ACIDSPLAT); + ILoadMissileGFX(MF_ACIDPUD); + } + + if (mtype == MT_DIABLO) + ILoadMissileGFX(MF_FIREPLAR); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ClearMVars(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + monster[i]._mVar1 = 0; + monster[i]._mVar2 = 0; + monster[i]._mVar3 = 0; + monster[i]._mVar4 = 0; + monster[i]._mVar5 = 0; + monster[i]._mVar6 = 0; + monster[i]._mVar7 = 0; + monster[i]._mVar8 = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + + +void InitMonster(int i, int rd, int mtype, int x, int y) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert((DWORD)mtype < MAX_LVLMTYPES); + CMonster *monst = &Monsters[mtype]; + app_assert(monst->MData != NULL); + + monster[i]._mdir = rd; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + + monster[i]._mMTidx = mtype; + monster[i]._mmode = MM_STAND; + monster[i].mName = monst->MData->mName; + monster[i].MType = monst; + monster[i].MData = monst->MData; + monster[i]._mAnimData = monst->Anims[MA_STAND].Cels[rd]; + monster[i]._mAnimDelay = monst->Anims[MA_STAND].Rate; + monster[i]._mAnimCnt = random(88, monster[i]._mAnimDelay - 1); + monster[i]._mAnimLen = monst->Anims[MA_STAND].Frames; + monster[i]._mAnimFrame = random(88, monster[i]._mAnimLen - 1) + 1; + if (monst->mtype == MT_DIABLO) { + monster[i]._mmaxhp = (random(88, 1666 - 1666 + 1) + 1666) << HP_SHIFT; + } else { + monster[i]._mmaxhp = (random(88, monst->mMaxHP - monst->mMinHP + 1) + monst->mMinHP) << HP_SHIFT; + } +/* if (gbMaxPlayers != 1) + monster[i]._mmaxhp = (monster[i]._mmaxhp * MPMM[gbActivePlayers-1]) / 100; + else + monster[i]._mmaxhp = monster[i]._mmaxhp >> 1; + if (monster[i]._mmaxhp < (1 << HP_SHIFT)) monster[i]._mmaxhp = 1 << HP_SHIFT;*/ + if (gbMaxPlayers == 1) { + monster[i]._mmaxhp = monster[i]._mmaxhp >> 1; + if (monster[i]._mmaxhp < (1 << HP_SHIFT)) monster[i]._mmaxhp = 1 << HP_SHIFT; + } + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i]._mAi = monst->MData->mAi; + monster[i]._mint = monst->MData->mInt; + monster[i]._mgoal = MG_ATTACK; + monster[i]._mgoalvar1 = 0; + monster[i]._mgoalvar2 = 0; + monster[i]._mgoalvar3 = 0; + monster[i]._mgoalvar4 = 0; + monster[i]._pathcount = 0; + monster[i]._mDelFlag = FALSE; + monster[i]._uniqtype = 0; + monster[i]._msquelch = 0; + + monster[i]._mRndSeed = GetRndSeed(); + monster[i]._mAISeed = GetRndSeed(); + + monster[i].mWhoHit = 0; + + monster[i].mLevel = monst->MData->mLevel; + monster[i].mExp = monst->MData->mExp; + monster[i].mHit = monst->MData->mHit; + monster[i].mMinDamage = monst->MData->mMinDamage; + monster[i].mMaxDamage = monst->MData->mMaxDamage; + monster[i].mHit2 = monst->MData->mHit2; + monster[i].mMinDamage2 = monst->MData->mMinDamage2; + monster[i].mMaxDamage2 = monst->MData->mMaxDamage2; + monster[i].mArmorClass = monst->MData->mArmorClass; + monster[i].mMagicRes = monst->MData->mMagicRes; + monster[i].leader = 0; + monster[i].leaderflag = 0; + monster[i]._mFlags = monst->MData->mFlags; + monster[i].mtalkmsg = 0; + + if (monster[i]._mAi == AI_GARG) + { + monster[i]._mAnimData = monst->Anims[MA_SPECIAL].Cels[rd]; + monster[i]._mAnimFrame = 1; + monster[i]._mFlags |= MFLAG_STILL; + monster[i]._mmode = MM_SATTACK; + } + + if (gnDifficulty == D_NIGHTMARE) { + monster[i]._mmaxhp = (monster[i]._mmaxhp * 3) + 100; + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mLevel += 15; + monster[i].mExp = (monster[i].mExp << 1) + 2000; + monster[i].mHit += 85; + monster[i].mMinDamage = (monster[i].mMinDamage * 2) + 4; + monster[i].mMaxDamage = (monster[i].mMaxDamage * 2) + 4; + monster[i].mHit2 += 85; + monster[i].mMinDamage2 = (monster[i].mMinDamage2 * 2) + 4; + monster[i].mMaxDamage2 = (monster[i].mMaxDamage2 * 2) + 4; + monster[i].mArmorClass += 50; + } + if (gnDifficulty == D_HELL) { + monster[i]._mmaxhp = (monster[i]._mmaxhp * 4) + 200; + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mLevel += 30; + monster[i].mExp = (monster[i].mExp << 2) + 4000; + monster[i].mHit += 120; + monster[i].mMinDamage = (monster[i].mMinDamage * 4) + 6; + monster[i].mMaxDamage = (monster[i].mMaxDamage * 4) + 6; + monster[i].mHit2 += 120; + monster[i].mMinDamage2 = (monster[i].mMinDamage2 * 4) + 6; + monster[i].mMaxDamage2 = (monster[i].mMaxDamage2 * 4) + 6; + monster[i].mArmorClass += 80; + monster[i].mMagicRes = monst->MData->mMagicRes2; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ClrAllMonsters() +{ + int i; + MonsterStruct *Monst; + + for (i = 0; i < MAXMONSTERS; i++) { + Monst = &monster[i]; + ClearMVars(i); + + //track down freeloaders from previous levels by making them obvious + Monst->mName = sgszInvalidMonstName; + + Monst->_mgoal = 0; + Monst->_mmode = MM_STAND; + Monst->_mVar1 = MM_STAND; + Monst->_mVar2 = 0; + Monst->_mx = 0; + Monst->_my = 0; + Monst->_mfutx = 0; + Monst->_mfuty = 0; + Monst->_moldx = 0; + Monst->_moldy = 0; + Monst->_mdir = random(89, 8); + Monst->_mxvel = 0; + Monst->_myvel = 0; + Monst->_mAnimData = NULL; + Monst->_mAnimDelay = 0; + Monst->_mAnimCnt = 0; + Monst->_mAnimLen = 0; + Monst->_mAnimFrame = 0; + Monst->_mFlags = 0; + Monst->_mDelFlag = FALSE; + Monst->_menemy = random(89, gbActivePlayers); + Monst->_menemyx = plr[Monst->_menemy]._pfutx; + Monst->_menemyy = plr[Monst->_menemy]._pfuty; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL MonstPlace(int xp, int yp) { + if (xp < 0 || xp >= DMAXX || yp < 0 || yp >= DMAXY) return FALSE; + if (dMonster[xp][yp] != 0) return FALSE; + if (dPlayer[xp][yp] != 0) return FALSE; + if (dFlags[xp][yp] & BFLAG_MONSTACTIVE) return FALSE; + if (dFlags[xp][yp] & BFLAG_SETPC) return FALSE; + if (SolidLoc(xp,yp)) return FALSE; + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PlaceMonster(int i, int mtype, int x, int y) +{ + int rd; + + dMonster[x][y] = i + 1; + rd = random(90, 8); + InitMonster(i, rd, mtype, x, y); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void LoadUniMonstTrans(int uid) +{ + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PlaceUniqueMonst(int uniqindex, int miniontype, int packsize) +{ + app_assert((DWORD)nummonsters < MAXMONSTERS); + UniqMonstStruct *Uniq = &UniqMonst[uniqindex]; + MonsterStruct *Monst = &monster[nummonsters]; + + int xp,yp; + int x,y; + BOOL done; + int count, count2; + char filestr[64]; + done = FALSE; + count2 = 0; + int uniqtype; + + // Check if too many uniques. Limit is unique palette translation table size + if((uniquetrans << 8) + 4864 >= LIGHTSIZE) + return; + + // find the index of the monster graphics + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (uniqtype = 0; uniqtype < nummtypes; uniqtype++) + if (Monsters[uniqtype].mtype == UniqMonst[uniqindex].mtype) break; + app_assert(uniqtype < nummtypes); + + do + { + xp = random(91, DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(91, DMAXY - DIRTEDGE) + (DIRTEDGED2); + count = 0; + for(x = xp-3; x < xp+3; x++) + for(y = yp-3; y < yp+3; y++) + if(InBounds(x,y) && MonstPlace(x,y)) + count++; + } while((count < 9 // try finding a clear spot + && ++count2 < 1000) // avoid infinite loop + || !MonstPlace(xp,yp)); // make sure there's at least + // a spot for the leader + + if(uniqindex == MU_SNOTSPIL) { + xp = (setpc_x << 1) + DIRTEDGED2 + 8; + yp = (setpc_y << 1) + DIRTEDGED2 + 12; + } + if(uniqindex == MU_WARLORD) { + xp = (setpc_x << 1) + DIRTEDGED2 + 6; + yp = (setpc_y << 1) + DIRTEDGED2 + 7; + } + if(uniqindex == MU_ZHAR) { + int i; + BOOL zharflag = TRUE; + for (i = 0; i < themeCount; i++) { + if ((i == zharlib) && (zharflag == TRUE)) { + zharflag = FALSE; + xp = ((themeLoc[i].x << 1) + DIRTEDGED2)+4; + yp = ((themeLoc[i].y << 1) + DIRTEDGED2)+4; + } + } + } + if (gbMaxPlayers == 1) { + if(uniqindex == MU_LAZARUS) { + xp = 32; + yp = 46; + } + if(uniqindex == MU_REDVEX) { + xp = 40; + yp = 45; + } + if(uniqindex == MU_BLKJADE) { + xp = 38; + yp = 49; + } + if(uniqindex == MU_SKELKING) { + xp = 35; + yp = 47; + } + } else { + if(uniqindex == MU_LAZARUS) { + xp = (setpc_x << 1) + DIRTEDGED2 + 3; + yp = (setpc_y << 1) + DIRTEDGED2 + 6; + } + if(uniqindex == MU_REDVEX) { + xp = (setpc_x << 1) + DIRTEDGED2 + 5; + yp = (setpc_y << 1) + DIRTEDGED2 + 3; + } + if(uniqindex == MU_BLKJADE) { + xp = (setpc_x << 1) + DIRTEDGED2 + 5; + yp = (setpc_y << 1) + DIRTEDGED2 + 9; + } + } + + if (uniqindex == MU_CLEAVER) { + done = FALSE; + // Find certain tile where Butcher goes + for (yp = 0; yp < DMAXY && !done; yp++) + for (xp = 0; xp < DMAXX && !done; xp++) + done = (dPiece[xp][yp] == 367); + // NOTE: xp and yp get incremented an extra time after done=TRUE, but + // coincidentally, that's where we want to place butcher + } + + PlaceMonster(nummonsters, uniqtype, xp, yp); + Monst->_uniqtype = uniqindex+1; + if (Uniq->mlevel != 0) Monst->mLevel = Uniq->mlevel*2; + else Monst->mLevel += 5; + Monst->mExp = (Monst->mExp*2); + Monst->mName = Uniq->mName; + Monst->_mmaxhp = Uniq->mmaxhp << HP_SHIFT; +/* if (gbMaxPlayers != 1) + Monst->_mmaxhp = (Monst->_mmaxhp * MPMM[gbActivePlayers-1]) / 100; + else + Monst->_mmaxhp = Monst->_mmaxhp >> 1; + if (Monst->_mmaxhp < (1 << HP_SHIFT)) Monst->_mmaxhp = 1 << HP_SHIFT;*/ + if (gbMaxPlayers == 1) { + Monst->_mmaxhp = Monst->_mmaxhp >> 1; + if (Monst->_mmaxhp < (1 << HP_SHIFT)) Monst->_mmaxhp = 1 << HP_SHIFT; + } + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->_mAi = Uniq->mAi; + Monst->_mint = Uniq->mint; + Monst->mMinDamage = Uniq->mMinDamage; + Monst->mMaxDamage = Uniq->mMaxDamage; + Monst->mMinDamage2 = Uniq->mMinDamage; + Monst->mMaxDamage2 = Uniq->mMaxDamage; + Monst->mMagicRes = Uniq->mMagicRes; + Monst->mtalkmsg = Uniq->mtalkmsg; + Monst->mlid = AddLight(Monst->_mx, Monst->_my, 3); + if ((gbMaxPlayers != 1) && (Monst->_mAi == AI_LAZHELP)) Monst->mtalkmsg = 0; + if (Monst->mtalkmsg != 0) Monst->_mgoal = MG_TALK; + if (gnDifficulty == D_NIGHTMARE) { + Monst->_mmaxhp = (Monst->_mmaxhp * 3) + 100; + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->mLevel += 15; + Monst->mExp = (Monst->mExp << 1) + 2000; + Monst->mMinDamage = (Monst->mMinDamage * 2) + 4; + Monst->mMaxDamage = (Monst->mMaxDamage * 2) + 4; + Monst->mMinDamage2 = (Monst->mMinDamage2 * 2) + 4; + Monst->mMaxDamage2 = (Monst->mMaxDamage2 * 2) + 4; + } + if (gnDifficulty == D_HELL) { + Monst->_mmaxhp = (Monst->_mmaxhp * 4) + 200; + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->mLevel += 30; + Monst->mExp = (Monst->mExp << 2) + 4000; + Monst->mMinDamage = (Monst->mMinDamage * 4) + 6; + Monst->mMaxDamage = (Monst->mMaxDamage * 4) + 6; + Monst->mMinDamage2 = (Monst->mMinDamage2 * 4) + 6; + Monst->mMaxDamage2 = (Monst->mMaxDamage2 * 4) + 6; + } + + // Load unique monster translations + sprintf(filestr, "Monsters\\Monsters\\%s.TRN", Uniq->mTFile); + app_assert((uniquetrans << 8) + 4864 < LIGHTSIZE); + LoadFileWithMem(filestr, pLightTbl + (uniquetrans << 8) + 4864); + Monst->_uniqtrans = uniquetrans; + uniquetrans++; + + if(Uniq->mUnqAttr & UN_H) + { + Monst->mHit = Uniq->mUnqVar1; + Monst->mHit2 = Uniq->mUnqVar1; + } + if(Uniq->mUnqAttr & UN_A) + { + Monst->mArmorClass = Uniq->mUnqVar1; + } + + nummonsters++; + + if(Uniq->mUnqAttr & UN_PACK) + { + PlaceGroup(miniontype, packsize, Uniq->mUnqAttr, nummonsters-1); + } + // quick fix for monsters that were gargoyles before they became unique + if (Monst->_mAi != AI_GARG) + { + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + Monst->_mAnimFrame = random(88, Monst->_mAnimLen - 1) + 1; + Monst->_mFlags &= ~MFLAG_STILL; + Monst->_mmode = MM_STAND; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static void PlaceUniques() +{ + int u; + int mt; + BOOL done; + + //uniquetrans = 0; + for(u = 0; UniqMonst[u].mtype != -1; u++) + { +#if CHEATS + if ((UniqMonst[u].mlevel == currlevel) + || (UniqMonst[u].mlevel && davedebug)) { +#else + if (UniqMonst[u].mlevel == currlevel) { +#endif + done = FALSE; + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for(mt = 0; mt < nummtypes && !done; mt++) + done = Monsters[mt].mtype == UniqMonst[u].mtype; + mt--; + if ((u == MU_GARBUD) && (quests[Q_GARBUD]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_ZHAR) && (quests[Q_ZHAR]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_SNOTSPIL) && (quests[Q_LTBANNER]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_LACHDA) && (quests[Q_VEIL]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if ((u == MU_WARLORD) && (quests[Q_WARLORD]._qactive == QUEST_NOTAVAIL)) + done = FALSE; + if(done) + { + PlaceUniqueMonst(u, mt, 8); + } + } + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +void PlaceQuestMonsters() +{ + int skeltype; + byte *setp; + + if (!setlevel) { + if (QuestStatus(Q_BUTCHER)) + PlaceUniqueMonst(MU_CLEAVER, 0, 0); + + if ((currlevel == quests[Q_SKELKING]._qlevel) && (gbMaxPlayers != 1)) + { + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (skeltype = 0; skeltype < nummtypes; skeltype++) + if (IsSkel(Monsters[skeltype].mtype)) break; + app_assert(skeltype < nummtypes); + + PlaceUniqueMonst(MU_SKELKING, skeltype, 30); + } + + if (QuestStatus(Q_LTBANNER)) + { + setp = LoadFileInMemSig("Levels\\L1Data\\Banner1.DUN",NULL,'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_BLOOD)) + { + setp = LoadFileInMemSig("Levels\\L2Data\\Blood2.DUN", NULL, 'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_BLIND)) + { + setp = LoadFileInMemSig("Levels\\L2Data\\Blind2.DUN", NULL, 'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_ANVIL)) + { + setp = LoadFileInMemSig("Levels\\L3Data\\Anvil.DUN",NULL,'MONS'); + SetMapMonsters(setp, ((setpc_x+1) << 1), ((setpc_y+1) << 1)); + DiabloFreePtr(setp); + } + + if (QuestStatus(Q_WARLORD)) + { + setp = LoadFileInMemSig("Levels\\L4Data\\Warlord.DUN",NULL,'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + AddMonsterType(UniqMonst[MU_WARLORD].mtype, MPFLAG_SCATTER); // to allow scatterable monst of mtype + } + + if (QuestStatus(Q_VEIL)) + { + AddMonsterType(UniqMonst[MU_LACHDA].mtype, MPFLAG_SCATTER); // to allow scatterable monst of mtype + } + + if (QuestStatus(Q_ZHAR)) { + if (zharlib == -1) + quests[Q_ZHAR]._qactive = QUEST_NOTAVAIL; + } + + if ((currlevel == quests[Q_BETRAYER]._qlevel) && (gbMaxPlayers != 1)) { + AddMonsterType(UniqMonst[MU_LAZARUS].mtype, MPFLAG_UNIQ); + AddMonsterType(UniqMonst[MU_REDVEX].mtype, MPFLAG_UNIQ); + PlaceUniqueMonst(MU_LAZARUS, 0, 0); + PlaceUniqueMonst(MU_REDVEX, 0, 0); + PlaceUniqueMonst(MU_BLKJADE, 0, 0); + setp = LoadFileInMemSig("Levels\\L4Data\\Vile1.DUN",NULL,'MONS'); + SetMapMonsters(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + + } + else if (setlvlnum == SL_SKELKING) { + PlaceUniqueMonst(MU_SKELKING, 0, 0); + } +} +#endif + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PlaceGroup(int mtype, int num, BOOL leaderf, int leader) +{ + int xp, yp; + int x1, y1; + int j; + int placed = 0; + int try1 = 0; + int try2; + int rd; + + app_assert((DWORD)leader < MAXMONSTERS); + do + { + // Clear out the subset placed last time through the loop + while(placed) + { + nummonsters--; + placed--; + app_assert((DWORD)nummonsters < MAXMONSTERS); + app_assert((DWORD)monster[nummonsters]._mx < MAXDUNX); + app_assert((DWORD)monster[nummonsters]._my < MAXDUNY); + dMonster[monster[nummonsters]._mx][monster[nummonsters]._my] = 0; + } + + if(leaderf & UN_PACK) + { + rd = random(92, 8); + x1 = xp = monster[leader]._mx + offset_x[rd]; + y1 = yp = monster[leader]._my + offset_y[rd]; + } + else + { + do + { + x1 = xp = random(93, DMAXX - DIRTEDGE) + (DIRTEDGED2); + y1 = yp = random(93, DMAXY - DIRTEDGE) + (DIRTEDGED2); + } while (!MonstPlace(xp, yp)); + } + + if ((nummonsters + num) > totalmonsters) num = totalmonsters - nummonsters; + j = 0; + try2 = 0; + while (j < num && try2 < 100) { + if (MonstPlace(xp, yp) && (dTransVal[xp][yp] == dTransVal[x1][y1]) + && !((leaderf & UN_STICK) && !DIST(xp-x1,yp-y1,4))) { + PlaceMonster(nummonsters, mtype, xp, yp); + if(leaderf & UN_PACK) + { + monster[nummonsters]._mmaxhp *= 2; + monster[nummonsters]._mhitpoints = monster[nummonsters]._mmaxhp; + monster[nummonsters]._mint = monster[leader]._mint; + if (leaderf & UN_STICK) + { + monster[nummonsters].leader = leader; + monster[nummonsters].leaderflag = PACK_MEMBER; + monster[nummonsters]._mAi = monster[leader]._mAi; + } + // quick fix for monsters that were gargoyles before they became unique + if (monster[nummonsters]._mAi != AI_GARG) + { + monster[nummonsters]._mAnimData = monster[nummonsters].MType->Anims[MA_STAND].Cels[monster[nummonsters]._mdir]; + monster[nummonsters]._mAnimFrame = random(88, monster[nummonsters]._mAnimLen - 1) + 1; + monster[nummonsters]._mFlags &= ~MFLAG_STILL; + monster[nummonsters]._mmode = MM_STAND; + } + } + + nummonsters++; + placed++; + j++; + } + else + try2++; + xp += offset_x[random(94, 8)]; + yp += offset_x[random(94, 8)]; + } + } while((placed < num) && (++try1 < 10)); + if(leaderf & UN_STICK) + monster[leader].packsize = placed; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +void LoadDiabMonsts() +{ + BYTE *pSetPiece; + int xx, yy; + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab1.DUN",NULL,'STPC'); + xx = (diabquad1x << 1); + yy = (diabquad1y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab2a.DUN",NULL,'STPC'); + xx = (diabquad2x << 1); + yy = (diabquad2y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab3a.DUN",NULL,'STPC'); + xx = (diabquad3x << 1); + yy = (diabquad3y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab4a.DUN",NULL,'STPC'); + xx = (diabquad4x << 1); + yy = (diabquad4y << 1); + SetMapMonsters(pSetPiece, xx, yy); + DiabloFreePtr(pSetPiece); +} +#endif + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitMonsters () +{ + int i, mtype; + int na, nt; + int scattertypes[LASTMT]; + int numscattypes = 0; + long fv,j; + int numplacemonsters; + int s,t; + +void DaveCheck2(); + if (gbMaxPlayers != 1) DaveCheck2(); + + // add 4 golem places first + // WARNING!! IF YOU CHANGE THIS YOU MUST TEST POSION WATER QUEST!!! + if (!setlevel) { + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + } + + // We will place the monsters seperately for 16 +#if !IS_VERSION(SHAREWARE) + if (!setlevel && currlevel == 16) { + LoadDiabMonsts(); + } +#endif + + // Monsters are not placed where bFlags[][] & BFLAG_MONSTACTIVE is set + // This prevents: 1) Monsters attacking players as they enter dungeon + // 2) Monsters setting off traps + + nt = numtrigs; + if (currlevel == 15) nt = 1; + for (i = 0; i < nt; i++) + { + for (s = -2; s < 2; s++) + for (t = -2; t < 2; t++) + DoVision(trigs[i]._tx + s, trigs[i]._ty + t, INITMONSTRAD, FALSE, FALSE); + } + +#if !IS_VERSION(SHAREWARE) + PlaceQuestMonsters(); +#endif + + if (!setlevel) + { +#if !IS_VERSION(SHAREWARE) + PlaceUniques(); // Place uniques before any other monsters +#endif + // Calc a volume of monsters + fv = 0; + for (i = DIRTEDGED2; i < (DMAXY - (DIRTEDGED2)); i++) { + for (j = DIRTEDGED2; j < (DMAXX - (DIRTEDGED2)); j++) { + if (!SolidLoc(i,j)) fv++; + } + } + numplacemonsters = fv / MONSTDENSITY; +#if 0 // Debugging = 1, normal = 0 + numplacemonsters = 1; +#else + if (gbMaxPlayers != 1) numplacemonsters += (numplacemonsters >> 1); +#endif + if (numplacemonsters + nummonsters > MAXMONSTERS - 10) + numplacemonsters = MAXMONSTERS - 10 - nummonsters; + + totalmonsters = nummonsters + numplacemonsters; + + +#ifndef PACKS_ONLY // switch for debugging pack AI + // Place scattered monsters + + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes; i++) + { + if (Monsters[i].mPlaceFlags & MPFLAG_SCATTER) + scattertypes[numscattypes++] = i; + } + + while (nummonsters < totalmonsters) { + mtype = scattertypes[random(95, numscattypes)]; + + if (currlevel != 1 // no groups on level 1 + && random(95, 2)) + { + if (currlevel == 2) // half-size groups on level 2 + na = random(95, 2) + 2; + else + na = random(95, 3) + 3; + } + else na = 1; + + PlaceGroup(mtype, na, FALSE, NULL); + } +#endif // PACKS_ONLY + } + + for (i = 0; i < nt; i++) + { + for (s = -2; s < 2; s++) + for (t = -2; t < 2; t++) + DoUnVision(trigs[i]._tx + s, trigs[i]._ty + t, INITMONSTRAD); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetMapMonsters(BYTE *pMap, int startx, int starty) +{ + int i,j; + WORD rw,rh; + WORD *lm; + int mt,mx,my; + int mtype; + + // add 4 golem places first + // WARNING! IF YOU CHANGE THIS YOU MUST TEST THE POISON WATER QUEST!!!! + AddMonsterType(MT_GOLEM, MPFLAG_DONT); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + AddMonster(1, 0, 0, 0, FALSE); + + if ((setlevel) && (setlvlnum == SL_VILEBETRAYER)) { + AddMonsterType(UniqMonst[MU_LAZARUS].mtype, MPFLAG_UNIQ); + AddMonsterType(UniqMonst[MU_REDVEX].mtype, MPFLAG_UNIQ); + AddMonsterType(UniqMonst[MU_BLKJADE].mtype, MPFLAG_UNIQ); + PlaceUniqueMonst(MU_LAZARUS, 0, 0); + PlaceUniqueMonst(MU_REDVEX, 0, 0); + PlaceUniqueMonst(MU_BLKJADE, 0, 0); + } + + + lm = (WORD *)pMap; + rw = *(lm++); + rh = *(lm++); + // Skip map + lm += rw * rh; + // Convert to index mini tile level instead of mega + rw = rw << 1; + rh = rh << 1; + // Skip treasure map + lm += rw * rh; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*lm != 0) { + mt = *lm; + mt = MonstConvTbl[mt-1]; + mtype = AddMonsterType(mt, MPFLAG_DONT); + mx = i + DIRTEDGED2 + startx; + my = j + DIRTEDGED2 + starty; + PlaceMonster(nummonsters++, mtype, mx, my); + } + lm++; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DeleteMonster(int i) +{ + int temp; + + app_assert((DWORD)(nummonsters-1) < MAXMONSTERS); + app_assert((DWORD)i < MAXMONSTERS); + temp = monstactive[--nummonsters]; + monstactive[nummonsters] = monstactive[i]; + monstactive[i] = temp; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int AddMonster(int x, int y, int dir, int mtype, BOOL InMap) +{ + int i; + + if (nummonsters < MAXMONSTERS) { + i = monstactive[nummonsters++]; + if (InMap) dMonster[x][y] = i + 1; + InitMonster(i, dir, mtype, x, y); + return i; + } else return -1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void NewMonsterAnim(int i, AnimStruct &anim, int md) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert((DWORD)md < 8); + MonsterStruct *Monst = &monster[i]; + + Monst->_mAnimData = anim.Cels[md]; + Monst->_mAnimLen = anim.Frames; + Monst->_mAnimFrame = 1; + Monst->_mAnimCnt = 0; + Monst->_mAnimDelay = anim.Rate; + Monst->_mdir = md; + Monst->_mFlags &= ~(MFLAG_BACKWARDS|MFLAG_STILL); +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL M_Ranged (int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + if (monster[i]._mAi == AI_SKELBOW || + monster[i]._mAi == AI_GOATBOW || + monster[i]._mAi == AI_SUCC || + monster[i]._mAi == AI_LAZHELP) return TRUE; + + return FALSE; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL M_Talker (int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + if (monster[i]._mAi == AI_LAZURUS || + monster[i]._mAi == AI_WARLORD || + monster[i]._mAi == AI_GARBUD || + monster[i]._mAi == AI_ZHAR || + monster[i]._mAi == AI_SNOTSPIL || + monster[i]._mAi == AI_LACHDANAN || + monster[i]._mAi == AI_LAZHELP) return TRUE; + + return FALSE; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_Enemy (int i) +{ + int j, mi; + int pnum, closest; + int dist, bestdist; + BOOL sameroom, bestsameroom; + + app_assert((DWORD)i < MAXMONSTERS); + MonsterStruct *Monst = &monster[i]; + BYTE enemyx,enemyy; + + closest = -1; + bestdist = -1; + bestsameroom = FALSE; + + if (!(Monst->_mFlags & MFLAG_MKILLER)) { + for(pnum = 0; pnum < MAX_PLRS; pnum++) { + if (!plr[pnum].plractive + || currlevel != plr[pnum].plrlevel + || plr[pnum]._pLvlChanging + || (plr[pnum]._pHitPoints == 0) && (gbMaxPlayers != 1)) + continue; + + sameroom = (dTransVal[Monst->_mx][Monst->_my] == dTransVal[plr[pnum]._px][plr[pnum]._py]); + dist = max(abs(Monst->_mx - plr[pnum]._px), abs(Monst->_my - plr[pnum]._py)); + + if ((sameroom && !bestsameroom) || ((sameroom || !bestsameroom) && dist < bestdist) || closest == -1) { + Monst->_mFlags &= ~MFLAG_MID; +// Monst->_mFlags &= ~MFLAG_MKILLER; + closest = pnum; + enemyx = plr[pnum]._pfutx; + enemyy = plr[pnum]._pfuty; + bestdist = dist; + bestsameroom = sameroom; + } + } + } + + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (j = 0; j < nummonsters; j++) { + mi = monstactive[j]; + if ((mi != i) && + ((monster[mi]._mx != 1) || (monster[mi]._my != 0)) && // special confus-o-matic code for inactive golum + ((!M_Talker(mi)) || monster[mi].mtalkmsg == 0) && + /*(DIST((monster[mi]._mx - Monst->_mx),(monster[mi]._my - Monst->_my),2)) &&*/ + ((Monst->_mFlags & MFLAG_MKILLER) || + ((DIST((monster[mi]._mx - Monst->_mx),(monster[mi]._my - Monst->_my),2)) || (M_Ranged(i)))) && + (Monst->_mFlags & MFLAG_MKILLER || monster[mi]._mFlags & MFLAG_MKILLER)) { + sameroom = (dTransVal[Monst->_mx][Monst->_my] == dTransVal[monster[mi]._mx][monster[mi]._my]); + dist = max(abs(Monst->_mx - monster[mi]._mx), abs(Monst->_my - monster[mi]._my)); + if ((sameroom && !bestsameroom) || ((sameroom || !bestsameroom) && dist < bestdist) || closest == -1) { + Monst->_mFlags |= MFLAG_MID; + closest = mi; + enemyx = monster[mi]._mfutx; + enemyy = monster[mi]._mfuty; + bestdist = dist; + bestsameroom = sameroom; + } + } + } + + // everyone dead? + if (closest != -1) + { + Monst->_menemy = closest; + Monst->_menemyx = enemyx; + Monst->_menemyy = enemyy; + Monst->_mFlags &= ~MFLAG_NOENEMY; + } + else + Monst->_mFlags |= MFLAG_NOENEMY; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int M_GetDir(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + return GetDirection(monster[i]._mx, monster[i]._my, monster[i]._menemyx, monster[i]._menemyy); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_CheckEFlag(int i) +{ + int tx,ty,tv; + int t; + WORD *mt; + + app_assert((DWORD)i < MAXMONSTERS); + tx = monster[i]._mx - 1; + ty = monster[i]._my + 1; + tv = 0; + mt = &(dMT[tx][ty].mt[0]); + for(t = 2; t < 10; t++) + tv |= mt[t]; + tv |= dSpecial[tx][ty]; + if (tv != 0) monster[i]._meflag = 1; + else monster[i]._meflag = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartStand(int i, int md) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + ClearMVars(i); + if (monster[i].MType->mtype == MT_GOLEM) + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], md); + else + NewMonsterAnim(i, monster[i].MType->Anims[MA_STAND], md); + + monster[i]._mVar1 = monster[i]._mmode; + monster[i]._mVar2 = 0; // count how long he's been standing + monster[i]._mmode = MM_STAND; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); + + // Pick nearest enemy + M_Enemy(i); +} + +/*-----------------------------------------------------------------------* + * M_StartDelay + * + * Keeps monster in Stand animation for len frames + * Monster must be in Stand mode before entering Delay mode +**-----------------------------------------------------------------------*/ + +void M_StartDelay(int i, int len) +{ + if(len > 0) + { + if (monster[i]._mAi == AI_LAZURUS) return; + app_assert((DWORD)i < MAXMONSTERS); + monster[i]._mVar2 = len; + monster[i]._mmode = MM_DELAY; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartSpStand(int i, int md) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_SPSTAND; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartWalk(int i, int xvel, int yvel, int xadd, int yadd, int EndDir) +{ + long fx,fy; + int pn; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + app_assert((DWORD)fx < MAXDUNX); + app_assert((DWORD)fy < MAXDUNY); + pn = dPiece[fx][fy] - 1; + dMonster[fx][fy] = -1 - i; + monster[i]._mmode = MM_WALK; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar1 = xadd; + monster[i]._mVar2 = yadd; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], EndDir); + monster[i]._mVar6 = 0; + monster[i]._mVar7 = 0; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartWalk2(int i, int xvel, int yvel, int xoff, int yoff, + int xadd, int yadd, int EndDir) +{ + long fx,fy; + int pn; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + app_assert((DWORD)fx < MAXDUNX); + app_assert((DWORD)fy < MAXDUNY); + pn = dPiece[fx][fy] - 1; + app_assert((DWORD)monster[i]._mx < MAXDUNX); + app_assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = -1 - i; + monster[i]._mVar1 = monster[i]._mx; + monster[i]._mVar2 = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mx = fx; + monster[i]._my = fy; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + dMonster[fx][fy] = i + 1; + if(monster[i]._uniqtype) + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + monster[i]._mxoff = xoff; + monster[i]._myoff = yoff; + monster[i]._mmode = MM_WALK2; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], EndDir); + monster[i]._mVar6 = xoff << 4; + monster[i]._mVar7 = yoff << 4; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartWalk3(int i, int xvel, int yvel, int xoff, int yoff, + int xadd, int yadd, int txa, int tya, int EndDir) +{ + long fx,fy; + long tx,ty; + int pn, pn2; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + fx = monster[i]._mx + xadd; + fy = monster[i]._my + yadd; + tx = monster[i]._mx + txa; // Temp location for drawing + ty = monster[i]._my + tya; + if(monster[i]._uniqtype) + ChangeLightXY(monster[i].mlid, tx, ty); + app_assert((DWORD)fx < MAXDUNX); + app_assert((DWORD)fy < MAXDUNY); + pn = dPiece[fx][fy] - 1; + pn2 = dPiece[tx][ty] - 1; + app_assert((DWORD)monster[i]._mx < MAXDUNX); + app_assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = -1 - i; + dMonster[fx][fy] = -1 - i; + monster[i]._mVar4 = tx; + monster[i]._mVar5 = ty; + dFlags[tx][ty] |= BFLAG_MONSTLR; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = fx; + monster[i]._mfuty = fy; + monster[i]._mxoff = xoff; + monster[i]._myoff = yoff; + monster[i]._mmode = MM_WALK3; + monster[i]._mxvel = xvel; + monster[i]._myvel = yvel; + monster[i]._mVar1 = fx; + monster[i]._mVar2 = fy; + monster[i]._mVar3 = EndDir; + monster[i]._mdir = EndDir; + NewMonsterAnim(i, monster[i].MType->Anims[MA_WALK], EndDir); + monster[i]._mVar6 = xoff << 4; + monster[i]._mVar7 = yoff << 4; + monster[i]._mVar8 = 0; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartAttack(int i) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_ATTACK], md); + + monster[i]._mmode = MM_ATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +** Ranged weapons +**-----------------------------------------------------------------------*/ + +void M_StartRAttack(int i, int missile_type, int dam) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_ATTACK], md); + + monster[i]._mmode = MM_RATTACK; + monster[i]._mVar1 = missile_type; + monster[i]._mVar2 = dam; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +** Ranged Special weapons +**-----------------------------------------------------------------------*/ + +void M_StartRSpAttack(int i, int missile_type, int dam) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_RSATTACK; + monster[i]._mVar1 = missile_type; + monster[i]._mVar2 = 0; + monster[i]._mVar3 = dam; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartSpAttack(int i) +{ + int md; + + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + md = M_GetDir(i); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_SATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mdir = md; + M_CheckEFlag(i); +} + +/*-----------------------------------------------------------------------* + * M_StartEat is the same as M_StartSpAttack except mdir isn't affected +**-----------------------------------------------------------------------*/ + +void M_StartEat(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], monster[i]._mdir); + + monster[i]._mmode = MM_SATTACK; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_ClearSquares(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + int mx = monster[i]._moldx; + int my = monster[i]._moldy; + int mt = -1 - i; + int mt2 = i + 1; + app_assert((DWORD)(mx+1) < MAXDUNX); + app_assert((DWORD)(my+1) < MAXDUNY); + for (int y = my-1; y <= my+1; y++) { + for (int x = mx-1; x <= mx+1; x++) { + if (dMonster[x][y] == mt || dMonster[x][y] == mt2) { + dMonster[x][y] = 0; + } + } + } + + dFlags[mx+1][my+0] &= BFMASK_MONSTLR; + dFlags[mx+0][my+1] &= BFMASK_MONSTLR; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_GetKnockback(int i) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + // knock back enemy if you can + int d = (monster[i]._mdir + 4) & 0x7; + if (DirOK(i, d)) { + M_ClearSquares(i); + monster[i]._moldx += offset_x[d]; + monster[i]._moldy += offset_y[d]; + NewMonsterAnim(i, monster[i].MType->Anims[MA_GOTHIT], monster[i]._mdir); + monster[i]._mmode = MM_GOTHIT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mx = monster[i]._moldx; + monster[i]._my = monster[i]._moldy; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + M_ClearSquares(i); + app_assert((DWORD)monster[i]._mx < MAXDUNX); + app_assert((DWORD)monster[i]._my < MAXDUNY); + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_StartHit(int i, int pnum, int dam) +{ + app_assert((DWORD)i < MAXMONSTERS); + app_assert(monster[i].MType != NULL); + if (pnum >= 0) monster[i].mWhoHit |= (1 << pnum); // Who damaged me + + if (pnum == myplr) { + extern void delta_monster_hp(int mi,long hp,BYTE bLevel); + delta_monster_hp(i,monster[i]._mhitpoints,currlevel); + NetSendCmdParam2(FALSE,CMD_MONSTDAMAGE,i,dam); + } + PlayEffect(i, MS_GOTHIT); + + // Sneaky demons always get hit + if (!EquivMonst(monster[i].MType->mtype, MT_SNEAK)) + // Other monsters only get hit if damage is severe + //if (((dam >> HP_SHIFT) < (monster[i].mLevel + 3)) && (!(plr[pnum]._pIFlags & IAF_KNOCKBACK))) + if ((dam >> HP_SHIFT) < (monster[i].mLevel + 3)) + return; + + // Set monster's enemy to be this player + if (pnum >= 0) { + monster[i]._menemy = pnum; + monster[i]._menemyx = plr[pnum]._pfutx; + monster[i]._menemyy = plr[pnum]._pfuty; + monster[i]._mFlags &= ~MFLAG_MID; + monster[i]._mdir = M_GetDir(i); + } + + // Check for special hits/teleports + if(monster[i].MType->mtype == MT_BLINK) { + M_Teleport(i); + } else { + if (EquivMonst(monster[i].MType->mtype, MT_NSCAV) || + monster[i].MType->mtype == MT_GRAVDG) { + // allow it to seek food again. + monster[i]._mgoal = MG_ATTACK; + monster[i]._mgoalvar1 = 0; + monster[i]._mgoalvar2 = 0; + } + } + if (monster[i]._mmode != MM_STONE) { + NewMonsterAnim(i, monster[i].MType->Anims[MA_GOTHIT], monster[i]._mdir); + monster[i]._mmode = MM_GOTHIT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mx = monster[i]._moldx; + monster[i]._my = monster[i]._moldy; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + M_ClearSquares(i); + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void M_DiabloDeath(int i, BOOL sendmsg) +{ + MonsterStruct *Monst = &monster[i]; + + // disable any other sounds from playing, for dramatic effect + #if !IS_VERSION(SHAREWARE) + PlaySFX(USFX_DIABLOD); + #endif + quests[Q_DIABLO]._qactive = QUEST_DONE; + if (sendmsg) NetSendCmdQuest(TRUE, Q_DIABLO); + sgbSaveSoundOn = gbSoundOn; + gbSoundOn = FALSE; + // disable player processing, so we can take over screen scrolling + gbProcessPlayers = FALSE; + // kill all other monsters on level + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (int j = 0; j < nummonsters; j++) { + int k = monstactive[j]; + if (k != i && monster[i]._msquelch) { + NewMonsterAnim(k, monster[k].MType->Anims[MA_DEATH], monster[k]._mdir); + monster[k]._mmode = MM_DEATH; + monster[k]._mxoff = 0; + monster[k]._myoff = 0; + monster[k]._mVar1 = 0; + monster[k]._mx = monster[k]._moldx; + monster[k]._my = monster[k]._moldy; + monster[k]._mfutx = monster[k]._mx; + monster[k]._mfuty = monster[k]._my; + monster[k]._moldx = monster[k]._mx; + monster[k]._moldy = monster[k]._my; + M_CheckEFlag(k); + M_ClearSquares(k); + dMonster[monster[k]._mx][monster[k]._my] = k + 1; + } + } + AddLight(Monst->_mx, Monst->_my, 8); + DoVision(Monst->_mx, Monst->_my, 8, FALSE, TRUE); + // set up scrolling vars + int steps = max(abs(ViewX-Monst->_mx),abs(ViewY-Monst->_my)); + steps = min(20, steps); + + Monst->_mVar3 = ViewX << 16; // convert to fixed-point + Monst->_mVar4 = ViewY << 16; + // calculate scroll offsets + Monst->_mVar5 = (int)((double)(Monst->_mVar3 - (Monst->_mx << 16))/(double)steps); + Monst->_mVar6 = (int)((double)(Monst->_mVar4 - (Monst->_my << 16))/(double)steps); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M2MStartHit(int mid, int i, int dam) +{ + if ((DWORD)mid >= MAXMONSTERS) + app_fatal("Invalid monster %d getting hit by monster",mid); + if (monster[mid].MType == NULL) + app_fatal("Monster %d \"%s\" getting hit by monster: MType NULL",mid,monster[mid].mName); + + if (i >= 0) monster[i].mWhoHit |= (1 << i); // Who damaged me + + extern void delta_monster_hp(int mi,long hp, BYTE bLevel); + delta_monster_hp(mid, monster[mid]._mhitpoints, currlevel); + NetSendCmdParam2(FALSE, CMD_MONSTDAMAGE, mid, dam); + + PlayEffect(mid, MS_GOTHIT); + + // Sneaky demons always get hit + if (!EquivMonst(monster[mid].MType->mtype, MT_SNEAK)) + // Other monsters only get hit if damage is severe + if ((dam >> HP_SHIFT) < (monster[mid].mLevel + 3)) return; + + // face plr who hit me + if (i >= 0) monster[mid]._mdir = (monster[i]._mdir + 4) &0x07; + + // Check for special hits/teleports + if(monster[mid].MType->mtype == MT_BLINK) { + M_Teleport(mid); + } else { + if (EquivMonst(monster[mid].MType->mtype, MT_NSCAV) || + monster[mid].MType->mtype == MT_GRAVDG) { + // allow it to seek food again. + monster[mid]._mgoal = MG_ATTACK; + monster[mid]._mgoalvar1 = 0; + monster[mid]._mgoalvar2 = 0; + } + } + + if (monster[mid]._mmode != MM_STONE) { + if (monster[mid].MType->mtype != MT_GOLEM) { + NewMonsterAnim(mid, monster[mid].MType->Anims[MA_GOTHIT], monster[mid]._mdir); + monster[mid]._mmode = MM_GOTHIT; + } + + monster[mid]._mxoff = 0; + monster[mid]._myoff = 0; + monster[mid]._mx = monster[mid]._moldx; + monster[mid]._my = monster[mid]._moldy; + monster[mid]._mfutx = monster[mid]._mx; + monster[mid]._mfuty = monster[mid]._my; + monster[mid]._moldx = monster[mid]._mx; + monster[mid]._moldy = monster[mid]._my; + M_CheckEFlag(mid); + M_ClearSquares(mid); + dMonster[monster[mid]._mx][monster[mid]._my] = mid + 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MonstStartKill(int i, int pnum, BOOL sendmsg) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MonstStartKill: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("MonstStartKill: Monster %d \"%s\" MType NULL",i,monster[i].mName); + int md; + MonsterStruct *Monst = &monster[i]; + + // killer gets credit too, and divvy up exper + if (pnum >= 0) Monst->mWhoHit |= (1 << pnum); // Who killed me + + // rjs.patch1.start.1/23/97 - fixes golem giving exp when killed + //old. if (pnum < MAX_PLRS) AddPlrMonstExper(Monst->mLevel, Monst->mExp, Monst->mWhoHit); + if ((pnum < MAX_PLRS) && (i > MAX_PLRS)) AddPlrMonstExper(Monst->mLevel, Monst->mExp, Monst->mWhoHit); + // rjs.patch1.end.1/23/97 + + // Kill the monster (for myplr or other plr) + monstkills[Monst->MType->mtype]++; + Monst->_mhitpoints = 0; + SetRndSeed(Monst->_mRndSeed); + if (QuestStatus(Q_GARBUD) && (Monst->mName == UniqMonst[MU_GARBUD].mName)) + CreateTypeItem(Monst->_mx+1, Monst->_my+1, TRUE, IT_MACE, IMID_NONE, TRUE, FALSE); + else if (i > 3) SpawnItem(i, Monst->_mx, Monst->_my, sendmsg); + + if (Monst->MType->mtype == MT_DIABLO) { + M_DiabloDeath(i, TRUE); + } + else + PlayEffect(i, MS_DEATH); + + if (pnum >= 0) md = M_GetDir(i); + else md = Monst->_mdir; + Monst->_mdir = md; + NewMonsterAnim(i, Monst->MType->Anims[MA_DEATH], md); + Monst->_mmode = MM_DEATH; + Monst->_mxoff = 0; + Monst->_myoff = 0; + Monst->_mVar1 = 0; + Monst->_mx = Monst->_moldx; + Monst->_my = Monst->_moldy; + Monst->_mfutx = Monst->_mx; + Monst->_mfuty = Monst->_my; + Monst->_moldx = Monst->_mx; + Monst->_moldy = Monst->_my; + M_CheckEFlag(i); + M_ClearSquares(i); + dMonster[Monst->_mx][Monst->_my] = i + 1; + CheckQuestKill(i, sendmsg); + // Send Fallen Ones running in fear + M_FallenFear(Monst->_mx, Monst->_my); + // Acid demon emits acid pool + if(EquivMonst(Monst->MType->mtype, MT_NACID)) + AddMissile(Monst->_mx, Monst->_my, 0, 0, 0, MIT_ACIDPUD, MI_ENEMYPLR, i, Monst->_mint + 1, 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M2MStartKill(int i, int mid) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M2MStartKill: Invalid monster (attacker) %d",i); + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M2MStartKill: Invalid monster (killed) %d",mid); + if (monster[i].MType == NULL) + app_fatal("M2MStartKill: Monster %d \"%s\" MType NULL",mid,monster[mid].mName); + int md; + + void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel); + delta_kill_monster(mid, monster[mid]._mx, monster[mid]._my, currlevel); + NetSendCmdLocParam1(FALSE, CMD_MONSTDEATH, monster[mid]._mx, monster[mid]._my, mid); + + monster[mid].mWhoHit |= (1 << i); // Who killed me + if (i < MAX_PLRS) AddPlrMonstExper(monster[mid].mLevel, monster[mid].mExp, monster[mid].mWhoHit); + monstkills[monster[mid].MType->mtype]++; + monster[mid]._mhitpoints = 0; + SetRndSeed(monster[mid]._mRndSeed); + // @@@ needs to be fixed for multiplayer (death not synced, etc) + if (mid >= MAX_PLRS) SpawnItem(mid, monster[mid]._mx, monster[mid]._my, TRUE); + if (monster[mid].MType->mtype == MT_DIABLO) { + M_DiabloDeath(mid, TRUE); + } + else + PlayEffect(i, MS_DEATH); + PlayEffect(mid, MS_DEATH); + md = (monster[i]._mdir + 4) & 0x07; + if (monster[mid].MType->mtype == MT_GOLEM) md = 0; + monster[mid]._mdir = md; + NewMonsterAnim(mid, monster[mid].MType->Anims[MA_DEATH], md); + monster[mid]._mmode = MM_DEATH; + monster[mid]._mxoff = 0; + monster[mid]._myoff = 0; + monster[mid]._mx = monster[mid]._moldx; + monster[mid]._my = monster[mid]._moldy; + monster[mid]._mfutx = monster[mid]._mx; + monster[mid]._mfuty = monster[mid]._my; + monster[mid]._moldx = monster[mid]._mx; + monster[mid]._moldy = monster[mid]._my; + M_CheckEFlag(mid); + M_ClearSquares(mid); + dMonster[monster[mid]._mx][monster[mid]._my] = mid + 1; + CheckQuestKill(mid, TRUE); + + // Send Fallen Ones running in fear + M_FallenFear(monster[mid]._mx, monster[mid]._my); + // Acid demon emits acid pool + if(EquivMonst(monster[mid].MType->mtype, MT_NACID)) + AddMissile(monster[mid]._mx, monster[mid]._my, 0, 0, 0, MIT_ACIDPUD, MI_ENEMYPLR, mid, monster[mid]._mint + 1, 0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartKill(int i, int pnum) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_StartKill: Invalid monster %d",i); + // Send a message to everyone saying I killed the monster + if (myplr == pnum) { + void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel); + delta_kill_monster(i,monster[i]._mx,monster[i]._my,currlevel); + if (i != pnum) + NetSendCmdLocParam1(FALSE,CMD_MONSTDEATH,monster[i]._mx,monster[i]._my,i); + else + NetSendCmdLocParam1(FALSE,CMD_KILLGOLEM,monster[i]._mx,monster[i]._my,currlevel); + } + + MonstStartKill(i, pnum, TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_SyncStartKill(int i, int x, int y, int pnum) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_SyncStartKill: Invalid monster %d",i); + // Already dead? + if (monster[i]._mhitpoints == 0) return; + if (monster[i]._mmode == MM_DEATH) return; + + app_assert(pnum != myplr); + + if (!dMonster[x][y]) { + M_ClearSquares(i); + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + } + MonstStartKill(i, pnum, FALSE); +// app_assert(dMonster[monster[i]._mx][monster[i]._my] == i+1 +// || dMonster[monster[i]._mx][monster[i]._my] == -(i+1)); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartFadein(int i, int md, BOOL backwards) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_StartFadein: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_StartFadein: Monster %d \"%s\" MType NULL",i,monster[i].mName); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + + monster[i]._mmode = MM_FADEIN; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + monster[i]._mdir = md; + monster[i]._mFlags &= ~MFLAG_INVISIBLE; + if (backwards) + { + monster[i]._mFlags |= MFLAG_BACKWARDS; + monster[i]._mAnimFrame = monster[i]._mAnimLen; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartFadeout(int i, int md, BOOL backwards) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_StartFadeout: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_StartFadeout: Monster %d \"%s\" MType NULL",i,monster[i].mName); + NewMonsterAnim(i, monster[i].MType->Anims[MA_SPECIAL], md); + monster[i]._mmode = MM_FADEOUT; + monster[i]._mxoff = 0; + monster[i]._myoff = 0; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + M_CheckEFlag(i); + monster[i]._mdir = md; + if (backwards) + { + monster[i]._mFlags |= MFLAG_BACKWARDS; + monster[i]._mAnimFrame = monster[i]._mAnimLen; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_StartHeal(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_StartHeal: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_StartHeal: Monster %d \"%s\" MType NULL",i,monster[i].mName); + MonsterStruct *Monst = &monster[i]; + + Monst->_mAnimData = Monst->MType->Anims[MA_SPECIAL].Cels[Monst->_mdir]; + Monst->_mAnimFrame = Monst->MType->Anims[MA_SPECIAL].Frames; + Monst->_mFlags |= MFLAG_BACKWARDS; + Monst->_mmode = MM_HEAL; + Monst->_mVar1 = Monst->_mmaxhp / (16*(random(97, 5)+4)); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_ChangeLightOffset(int monst) +{ + if ((DWORD)monst >= MAXMONSTERS) + app_fatal("M_ChangeLightOffset: Invalid monster %d",monst); + int lx,ly; + int sign; + + lx = (monster[monst]._mxoff + (monster[monst]._myoff << 1)); + ly = ((monster[monst]._myoff << 1) - monster[monst]._mxoff); + + // Divide these values by 8, because lighting offsets have + // 8 subdivisions per tile. + if (lx < 0) + { + sign = -1; + lx = -lx; + } + else + sign = 1; + lx = lx >> 3; + lx *= sign; + + if (ly < 0) + { + sign = -1; + ly = -ly; + } + else + sign = 1; + ly = ly >> 3; + ly *= sign; + + ChangeLightOff(monster[monst].mlid, lx, ly); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoStand(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoStand: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoStand: Monster %d \"%s\" MType NULL",i,monster[i].mName); + MonsterStruct *Monst = &monster[i]; + + if (Monst->MType->mtype == MT_GOLEM) + Monst->_mAnimData = Monst->MType->Anims[MA_WALK].Cels[Monst->_mdir]; + else + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + if (Monst->_mAnimFrame == Monst->_mAnimLen) { + M_Enemy(i); + } + + Monst->_mVar2++; + return RUN_DONE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoWalk(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoWalk: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoWalk: Monster %d \"%s\" MType NULL",i,monster[i].mName); + int rv; + + if (monster[i]._mVar8 == monster[i].MType->Anims[MA_WALK].Frames) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mx += monster[i]._mVar1; + monster[i]._my += monster[i]._mVar2; + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + if(monster[i]._uniqtype) + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + M_StartStand(i, monster[i]._mdir); + rv = RUN_AGAIN; +// DaveMonstMap(FALSE, 0); + } else { + if (monster[i]._mAnimCnt == 0) { + monster[i]._mVar8++; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = RUN_DONE; + } + if(monster[i]._uniqtype) + M_ChangeLightOffset(i); + + return (rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoWalk2(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoWalk2: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoWalk2: Monster %d \"%s\" MType NULL",i,monster[i].mName); + int rv; + + if (monster[i]._mVar8 == monster[i].MType->Anims[MA_WALK].Frames) { + dMonster[monster[i]._mVar1][monster[i]._mVar2] = 0; + if(monster[i]._uniqtype) + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + M_StartStand(i, monster[i]._mdir); + rv = RUN_AGAIN; +// DaveMonstMap(FALSE, 0); + } else { + if (monster[i]._mAnimCnt == 0) { + monster[i]._mVar8++; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = RUN_DONE; + } + if(monster[i]._uniqtype) + M_ChangeLightOffset(i); + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoWalk3(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoWalk3: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoWalk3: Monster %d \"%s\" MType NULL",i,monster[i].mName); + int rv; + + if (monster[i]._mVar8 == monster[i].MType->Anims[MA_WALK].Frames) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mx = monster[i]._mVar1; + monster[i]._my = monster[i]._mVar2; + dFlags[monster[i]._mVar4][monster[i]._mVar5] &= BFMASK_MONSTLR; + dMonster[monster[i]._mx][monster[i]._my] = i + 1; + if(monster[i]._uniqtype) + ChangeLightXY(monster[i].mlid, monster[i]._mx, monster[i]._my); + M_StartStand(i, monster[i]._mdir); + rv = RUN_AGAIN; +// DaveMonstMap(FALSE, 0); + } else { + if (monster[i]._mAnimCnt == 0) { + monster[i]._mVar8++; + monster[i]._mVar6 += monster[i]._mxvel; + monster[i]._mVar7 += monster[i]._myvel; + monster[i]._mxoff = monster[i]._mVar6 >> 4; + monster[i]._myoff = monster[i]._mVar7 >> 4; + } + rv = RUN_DONE; + } + if(monster[i]._uniqtype) + M_ChangeLightOffset(i); + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_TryM2MHit(int i, int mid, int hper, int mind, int maxd) +{ + int hit, dam; + BOOL ret; + + if ((DWORD)mid >= MAXMONSTERS) + app_fatal("M_TryM2MHit: Invalid monster %d",mid); + if (monster[mid].MType == NULL) + app_fatal("M_TryM2MHit: Monster %d \"%s\" MType NULL",mid,monster[mid].mName); + + if ((monster[mid]._mhitpoints >> HP_SHIFT) <= 0) return; + if (monster[mid].MType->mtype == MT_ILLWEAV && monster[mid]._mgoal == MG_RUN_AWAY) return; + + hit = random(4, 100); + if (monster[mid]._mmode == MM_STONE) hit = 0; + + if (CheckMonsterHit(mid, ret)) { + return; + } else { + if (hit < hper) { + dam = random(5, maxd - mind + 1) + mind; + dam = dam << HP_SHIFT; + + monster[mid]._mhitpoints -= dam; + //rjs - x2 stone dam fix - if (monster[mid]._mmode == MM_STONE) monster[mid]._mhitpoints -= dam; + if ((monster[mid]._mhitpoints >> HP_SHIFT) <= 0) { + if (monster[mid]._mmode == MM_STONE) { + M2MStartKill(i, mid); + monster[mid]._mmode = MM_STONE; + } else M2MStartKill(i, mid); + } else { + if (monster[mid]._mmode == MM_STONE) { + M2MStartHit(mid, i, dam); + monster[mid]._mmode = MM_STONE; + } else M2MStartHit(mid, i, dam); + } + } + } + return; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_TryH2HHit: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_TryH2HHit: Monster %d \"%s\" MType NULL",i,monster[i].mName); + + int hit, hper, tac; + long dam; + int dx, dy; + int blk, blkper, blkdir; + int mdam; + + if ((monster[i]._mFlags & MFLAG_MID) != 0) { + M_TryM2MHit(i, pnum, Hit, MinDam, MaxDam); + return; + } + + app_assert((DWORD)pnum < MAX_PLRS); + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) return; + if (plr[pnum]._pInvincible) return; + if ((plr[pnum]._pSpellFlags & SF_ETHER) != 0) return; + + dx = abs(monster[i]._mx - plr[pnum]._px); + dy = abs(monster[i]._my - plr[pnum]._py); + if ((dx < 2) && (dy < 2)) { + // Did I hit? + hit = random(98, 100); +#if CHEATS + if (simplecheat || cheatflag) hit = 1000; // TEMP! +#endif + //rjs tac = (byte)plr[pnum]._pArmorClass + plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC; + tac += (plr[pnum]._pDexterity / 5); + hper = 30 + Hit - tac + ((monster[i].mLevel - plr[pnum]._pLevel) << 1); + if (hper < 15) hper = 15; + if ((currlevel == 14) && (hper < 20)) hper = 20; + if ((currlevel == 15) && (hper < 25)) hper = 25; + if ((currlevel == 16) && (hper < 30)) hper = 30; + if (((plr[pnum]._pmode == PM_STAND) || (plr[pnum]._pmode == PM_ATTACK)) && (plr[pnum]._pBlockFlag)) blk = random(98, 100); + else blk = 100; + blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[i].mLevel - plr[pnum]._pLevel) << 1); + if (blkper < 0) blkper = 0; + if (blkper > 100) blkper = 100; + if (hit < hper) { + if (blk < blkper) { + blkdir = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mx, monster[i]._my); + StartPlrBlock(pnum, blkdir); + } else { + + + if (monster[i].MType->mtype == MT_YZOMBIE && pnum == myplr) + { + + // find manashield + int k; + int mi; + int msi = -1; + for (k = 0; k < nummissiles; k++) { + mi = missileactive[k]; + if (missile[mi]._mitype == MIT_MANASHIELD && missile[mi]._misource == pnum) { + msi = mi; + } + } + + if(plr[pnum]._pMaxHP > 1 << HP_SHIFT ) + { + plr[pnum]._pMaxHP -= 1 << HP_SHIFT; + if(plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + if( msi >= 0 ) + missile[msi]._miVar1 = plr[pnum]._pHitPoints; + } + plr[pnum]._pMaxHPBase -= 1 << HP_SHIFT; + if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) { + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + if( msi >= 0 ) + missile[msi]._miVar2 = plr[pnum]._pHPBase; + } + } + + + } + + + + dam = (MaxDam - MinDam + 1) << HP_SHIFT; + dam = random(99, dam) + (MinDam << HP_SHIFT); + dam += (plr[pnum]._pIGetHit << HP_SHIFT); + if (dam < (1 << HP_SHIFT)) dam = (1 << HP_SHIFT); + if (pnum == myplr) { + plr[pnum]._pHitPoints -= dam; + plr[pnum]._pHPBase -= dam; + + if (plr[pnum]._pReflectCount > 0) + { + --plr[pnum]._pReflectCount; + // Reflect back with 20->30% of the damage. + mdam = static_cast(dam * (0.01 * (random(100, 10) + 20))); + monster[i]._mhitpoints -= mdam; + if (monster[i]._mhitpoints >> HP_SHIFT <= 0) { + M_StartKill (i, pnum); + } else { + M_StartHit(i, pnum, mdam); + } + } + } + + + + if (plr[pnum]._pIFlags & IAF_THORN) { + mdam = ((random (99, 3) + 1) << HP_SHIFT); + monster[i]._mhitpoints -= mdam; + if (monster[i]._mhitpoints >> HP_SHIFT <= 0) { + M_StartKill (i, pnum); + //(old) AddPlrExperience(pnum, monster[i].mLevel, monster[i].mExp); + //(new, but moved) AddPlrMonstExper(monster[i].mLevel, monster[i].mExp, monster[i].mWhoHit); + } else { + M_StartHit(i, pnum, mdam); + } + } + if (!(monster[i]._mFlags & IAF_MNOHEAL)) { + if (monster[i].MType->mtype == MT_SKING + && gbMaxPlayers != 1) + monster[i]._mhitpoints += dam; + } + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - plr[pnum]._pHitPoints = 0; + StartPlrKill(pnum, FALSE); + } else { + StartPlrHit(pnum, dam, FALSE); + + if (monster[i]._mFlags & MFLAG_KNOCKBACK) { + // make sure player is doing a hit animation + if (plr[pnum]._pmode != PM_GOTHIT) + StartPlrHit(pnum, 0, TRUE); + + // knock back enemy one square + int newx,newy,oldx,oldy; + + oldx = plr[pnum]._px; + oldy = plr[pnum]._py; + newx = oldx + offset_x[monster[i]._mdir]; + newy = oldy + offset_y[monster[i]._mdir]; + if(PosOkPlayer(pnum, newx, newy)) + { + plr[pnum]._px = newx; + plr[pnum]._py = newy; + FixPlayerLocation(pnum,plr[pnum]._pdir); + FixPlrWalkTags(pnum); + dPlayer[newx][newy] = pnum + 1; + SetPlayerOld(pnum); + } + } + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoAttack: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); + if (monster[i].MType == NULL) + app_fatal("M_DoAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mAnimFrame == Monst->MData->mAFNum) { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit, Monst->mMinDamage, Monst->mMaxDamage); + if (Monst->_mAi != AI_SNAKE) + PlayEffect(i, MS_ATTACK); + } + // Special code for Magma -- second punch + if (EquivMonst(Monst->MType->mtype, MT_NMAGMA) + && Monst->_mAnimFrame == 9) + { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit+10, Monst->mMinDamage-2, Monst->mMaxDamage-2); + PlayEffect(i, MS_ATTACK); + } + // Special code for Storm -- second punch + if (EquivMonst(Monst->MType->mtype, MT_STORM) + && Monst->_mAnimFrame == 13) + { + M_TryH2HHit(i, Monst->_menemy, Monst->mHit-20, Monst->mMinDamage+4, Monst->mMaxDamage+4); + PlayEffect(i, MS_ATTACK); + } + // Special code for Snake -- play sound before attack frame + if (Monst->_mAi == AI_SNAKE && Monst->_mAnimFrame == 1) + PlayEffect(i, MS_ATTACK); + + if (Monst->_mAnimFrame == Monst->_mAnimLen) { + M_StartStand(i, Monst->_mdir); + return(RUN_AGAIN); + } else return (RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoRAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoRAttack: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoRAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); + if (monster[i].MType == NULL) + app_fatal("M_DoRAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); + int multimissiles; + int mi; + + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum) { + if (monster[i]._mVar1 != -1) + { + if (monster[i]._mVar1 == MIT_CBOLT) + multimissiles = 3; + else + multimissiles = 1; + for (mi = 0; mi < multimissiles; mi++) // special loop code to handle CBOLT, which must be cast 3 times + AddMissile(monster[i]._mx, monster[i]._my, monster[i]._menemyx, monster[i]._menemyy, monster[i]._mdir, monster[i]._mVar1, MI_ENEMYPLR, i, monster[i]._mVar2, 0); + } + PlayEffect(i, MS_ATTACK); + } + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return (RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoRSpAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoRSpAttack: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoRSpAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); + if (monster[i].MType == NULL) + app_fatal("M_DoRSpAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum2 && !monster[i]._mAnimCnt) { + AddMissile(monster[i]._mx, monster[i]._my, monster[i]._menemyx, monster[i]._menemyy, monster[i]._mdir, monster[i]._mVar1, MI_ENEMYPLR, i, monster[i]._mVar3, 0); + PlayEffect(i, MS_SATTACK); + } + + // special code for Mega demon -- hold attack animation frame + if (monster[i]._mAi == AI_MEGA && monster[i]._mAnimFrame == 3) + { + if (!monster[i]._mVar2++) + monster[i]._mFlags |= MFLAG_STILL; + else if (monster[i]._mVar2 == 15) + monster[i]._mFlags &= ~MFLAG_STILL; + } + + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return (RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoSAttack(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoSAttack: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoSAttack: Monster %d \"%s\" MType NULL",i,monster[i].mName); + if (monster[i].MType == NULL) + app_fatal("M_DoSAttack: Monster %d \"%s\" MData NULL",i,monster[i].mName); + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum2) + M_TryH2HHit(i, monster[i]._menemy, monster[i].mHit2, monster[i].mMinDamage2, monster[i].mMaxDamage2); + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoFadein(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoFadein: Invalid monster %d",i); + if ((monster[i]._mFlags & MFLAG_BACKWARDS && monster[i]._mAnimFrame == 1) + || (!(monster[i]._mFlags & MFLAG_BACKWARDS) && monster[i]._mAnimFrame == monster[i]._mAnimLen)) + { + M_StartStand(i, monster[i]._mdir); + monster[i]._mFlags &= ~MFLAG_BACKWARDS; + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoFadeout(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoFadeout: Invalid monster %d",i); + int mtype; + if ((monster[i]._mFlags & MFLAG_BACKWARDS && monster[i]._mAnimFrame == 1) + || (!(monster[i]._mFlags & MFLAG_BACKWARDS) && monster[i]._mAnimFrame == monster[i]._mAnimLen)) + { + app_assert(monster[i].MType != NULL); + mtype = monster[i].MType->mtype; + if (EquivMonst(mtype, MT_INCIN)) + monster[i]._mFlags &= ~MFLAG_BACKWARDS; + else + { + monster[i]._mFlags &= ~MFLAG_BACKWARDS; + monster[i]._mFlags |= MFLAG_INVISIBLE; + } + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoHeal(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoHeal: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (monster[i]._mFlags & MFLAG_NOHEAL) return RUN_DONE; + // Gargoyle turning back to stone + if(Monst->_mAnimFrame == 1) + { + Monst->_mFlags &= ~MFLAG_BACKWARDS; + Monst->_mFlags |= MFLAG_STILL; + if(Monst->_mhitpoints + Monst->_mVar1 < Monst->_mmaxhp) + Monst->_mhitpoints += Monst->_mVar1; + else + { + Monst->_mhitpoints = Monst->_mmaxhp; + Monst->_mFlags &= ~MFLAG_STILL; + Monst->_mmode = MM_SATTACK; + } + } + return RUN_DONE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +int M_DoTalk(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoTalk: Invalid monster %d",i); + int tren; + MonsterStruct *Monst = &monster[i]; + + M_StartStand(i, monster[i]._mdir); + Monst->_mgoal=MG_WAITTOTALK; + if (effect_is_playing(alltext[monster[i].mtalkmsg].sfxnr)) return RUN_DONE; + InitQTextMsg(monster[i].mtalkmsg); + if (monster[i].mName == UniqMonst[MU_GARBUD].mName) { + if (monster[i].mtalkmsg == TXT_GARB1) + quests[Q_GARBUD]._qactive = QUEST_NOTDONE; + quests[Q_GARBUD]._qlog = TRUE; + if (monster[i].mtalkmsg == TXT_GARB2) { + if(!(monster[i]._mFlags & MFLAG_DROP)) { + SpawnItem(i, monster[i]._mx+1, monster[i]._my+1, TRUE); + monster[i]._mFlags |= MFLAG_DROP; + } + } + } + if (monster[i].mName == UniqMonst[MU_ZHAR].mName) { + if (monster[i].mtalkmsg == TXT_ZHAR1) { + if(!(monster[i]._mFlags & MFLAG_DROP)) { + quests[Q_ZHAR]._qactive = QUEST_NOTDONE; + quests[Q_ZHAR]._qlog = TRUE; + CreateTypeItem(monster[i]._mx+1, monster[i]._my+1, FALSE, IT_MISC, IMID_BOOK, TRUE, FALSE); + monster[i]._mFlags |= MFLAG_DROP; + } + } + } + if (monster[i].mName == UniqMonst[MU_SNOTSPIL].mName) { + if ((monster[i].mtalkmsg == TXT_BOL1) && (!(monster[i]._mFlags & MFLAG_DROP))) { + app_assert(setpc_x != 0); + ObjChangeMap(setpc_x, setpc_y, setpc_x+(setpc_w>>1)+2, setpc_y+(setpc_h>>1)-2); + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, setpc_x+(setpc_w>>1)+4, setpc_y+(setpc_h>>1)); + TransVal = tren; + quests[Q_LTBANNER]._qvar1 = 2; + if (quests[Q_LTBANNER]._qactive == QUEST_NOTACTIVE) quests[Q_LTBANNER]._qactive = QUEST_NOTDONE; + monster[i]._mFlags |= MFLAG_DROP; + } + if (quests[Q_LTBANNER]._qvar1 < 2) { + sprintf(tempstr, "SS Talk = %i, Flags = %i", monster[i].mtalkmsg, monster[i]._mFlags); + app_fatal(tempstr); + } + } + if (monster[i].mName == UniqMonst[MU_LACHDA].mName) { + if (monster[i].mtalkmsg == TXT_VEIL1) { + quests[Q_VEIL]._qactive = QUEST_NOTDONE; + quests[Q_VEIL]._qlog = TRUE; + } + if ((monster[i].mtalkmsg == TXT_VEIL3) && (!(monster[i]._mFlags & MFLAG_DROP))) { + SpawnUnique(UID_STEELVEIL, monster[i]._mx+1, monster[i]._my+1); + monster[i]._mFlags |= MFLAG_DROP; + } + } + if (monster[i].mName == UniqMonst[MU_WARLORD].mName) { + app_assert(gbMaxPlayers == 1); + quests[Q_WARLORD]._qvar1 = 2; + } + if ((monster[i].mName == UniqMonst[MU_LAZARUS].mName) && (gbMaxPlayers != 1)) { + quests[Q_BETRAYER]._qvar1 = 6; + monster[i]._mgoal = MG_ATTACK; + monster[i]._msquelch = 255; + monster[i].mtalkmsg = 0; + } + return RUN_DONE; +} + +/*-----------------------------------------------------------------------* + * M_Teleport + * + * Teleports monster i to one of it's enemy's 8 adjacent squares. +**----------------------------------------------------------------------*/ + +void M_Teleport(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_Teleport: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + BOOL done = FALSE; + int mulx,muly; + int x,y; + int a,b; + int px,py; + + if (Monst->_mmode == MM_STONE) + return; + + px = Monst->_menemyx; + py = Monst->_menemyy; + + // randomize search direction + mulx = random(100,2)*2-1; + muly = random(100,2)*2-1; + for(a = -1; a <= 1 && !done; a++) + for(b = -1; b < 1 && !done; b++) + if(a || b) + { + x = px + a*mulx; + y = py + b*muly; + if(InBounds(x,y) + && x != Monst->_mx && y != Monst->_my) + if(PosOkMonst(i,x,y)) + done = TRUE; + } + if(done) + { + M_ClearSquares(i); + app_assert((DWORD)Monst->_mx < MAXDUNX); + app_assert((DWORD)Monst->_my < MAXDUNY); + dMonster[Monst->_mx][Monst->_my] = 0; + dMonster[x][y] = i+1; + // M_StartHit knocks monster back to oldx,oldy, so those are the members to set + Monst->_moldx = x; + Monst->_moldy = y; + Monst->_mdir = M_GetDir(i); + M_CheckEFlag(i); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoGotHit(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoGotHit: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoGotHit: Monster %d \"%s\" MType NULL",i,monster[i].mName); + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_UpdateLeader(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_UpdateLeader: Invalid monster %d",i); + int x,tmp; + + // check for pack leader + if(monster[i]._uniqtype && (UniqMonst[monster[i]._uniqtype-1].mUnqAttr & UN_STICK)) + // free the pack + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for(x = 0; x < nummonsters; x++) + { + if(monster[tmp=monstactive[x]].leaderflag == PACK_MEMBER + && monster[tmp].leader == i) + { + monster[tmp].leaderflag = 0; + } + } + // check for pack member + if(monster[i].leaderflag == PACK_MEMBER) + monster[monster[i].leader].packsize--; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void play_movie(const char * pszMovie,BOOL bAllowCancel); +extern BOOL gbRunGame; +extern BOOL deathflag; +extern BYTE gbDoEnding; + +void DoEnding() { + // tell other players to view victory + if (gbMaxPlayers > 1) SNetLeaveGame(SNET_EXIT_PLAYERWON); + + //SetCursor(NO_CURSOR); + //FullBlit(TRUE); + //PaletteFadeOut(FADE_FAST); + music_stop(); + + // give SNet some more time to field messages + if (gbMaxPlayers > 1) Sleep(1000); + + #if !IS_VERSION(SHAREWARE) + LONG lMusicVol; + BOOL bMusicOn; + if (plr[myplr]._pClass == CLASS_WARRIOR) play_movie("gendata\\DiabVic2.smk",FALSE); + else if (plr[myplr]._pClass == CLASS_SORCEROR) play_movie("gendata\\DiabVic1.smk",FALSE); + else play_movie("gendata\\DiabVic3.smk",FALSE); + play_movie("gendata\\Diabend.smk",FALSE); + + // turn music to full volume + bMusicOn = gbMusicOn; + gbMusicOn = TRUE; + lMusicVol = music_volume(VOLUME_READ); + music_volume(VOLUME_MAX); + music_start(MUSIC_L2); + + extern BOOL gbLoopMovie; + gbLoopMovie = TRUE; + play_movie("gendata\\loopdend.smk",TRUE); + gbLoopMovie = FALSE; + #endif + + //ClrDraw(); + //FullBlit(FALSE); + //PaletteFadeOut(FADE_FAST); + + // restore music volume + #if !IS_VERSION(SHAREWARE) + music_stop(); + music_volume(lMusicVol); + gbMusicOn = bMusicOn; + #endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PrepDoEnding() { + // enable sound again + gbSoundOn = sgbSaveSoundOn; + gbDoEnding = TRUE; + gbRunGame = FALSE; + deathflag = FALSE; + + app_assert((DWORD)myplr < MAX_PLRS); + plr[myplr].pDiabloKillLevel = max( + plr[myplr].pDiabloKillLevel, + (DWORD) gnDifficulty + 1 + ); + + for (int i = 0; i < MAX_PLRS; i++) { + plr[i]._pmode = PM_QUIT; + plr[i]._pInvincible = TRUE; + if (gbMaxPlayers > 1) { + if ((plr[i]._pHitPoints >> HP_SHIFT) == 0) + plr[i]._pHitPoints = 1 << HP_SHIFT; + if ((plr[i]._pMana >> MANA_SHIFT) == 0) + plr[i]._pMana = 1 << MANA_SHIFT; + } + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int M_DoDeath(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoDeath: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoDeath: Monster %d \"%s\" MType NULL",i,monster[i].mName); + monster[i]._mVar1++; + if (monster[i].MType->mtype == MT_DIABLO) { + ViewX += Sign(monster[i]._mx - ViewX); + ViewY += Sign(monster[i]._my - ViewY); + if (monster[i]._mVar1 == 140) { + PrepDoEnding(); + } + } else { + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + if (monster[i]._uniqtype == 0) + AddDead(monster[i]._mx, monster[i]._my, monster[i].MType->mdeadval, monster[i]._mdir); + else + AddDead(monster[i]._mx, monster[i]._my, monster[i]._udeadval, monster[i]._mdir); + app_assert(!(dFlags[monster[i]._mx+1][monster[i]._my] & BFLAG_MONSTLR) + && !(dFlags[monster[i]._mx][monster[i]._my+1] & BFLAG_MONSTLR)); + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mDelFlag = TRUE; + M_UpdateLeader(i); + } + } + return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoSpStand(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoSpStand: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoSpStand: Monster %d \"%s\" MType NULL",i,monster[i].mName); + if (monster[i]._mAnimFrame == monster[i].MData->mAFNum2) { + PlayEffect(i, MS_SATTACK); + } + if (monster[i]._mAnimFrame == monster[i]._mAnimLen) { + M_StartStand(i, monster[i]._mdir); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +int M_DoDelay(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoDelay: Invalid monster %d",i); + if (monster[i].MType == NULL) + app_fatal("M_DoDelay: Monster %d \"%s\" MType NULL",i,monster[i].mName); + int md; + + md = M_GetDir(i); + monster[i]._mAnimData = monster[i].MType->Anims[MA_STAND].Cels[md]; + if (monster[i]._mAi == AI_LAZURUS) { + if ((monster[i]._mVar2 > 8) || (monster[i]._mVar2 < 0)) monster[i]._mVar2 = 8; + } + if(!monster[i]._mVar2--) + { + int tmp = monster[i]._mAnimFrame; + M_StartStand(i, monster[i]._mdir); // StartStand sets AnimFrame to 0 + monster[i]._mAnimFrame = tmp; // restore AnimFrame to avoid pop + // in case monster continues standing. + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_DoStone(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_DoStone: Invalid monster %d",i); + if (monster[i]._mhitpoints == 0) { + dMonster[monster[i]._mx][monster[i]._my] = 0; + monster[i]._mDelFlag = TRUE; + } + return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_WalkDir(int i, int md) +{ + int mwi; + + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_WalkDir: Invalid monster %d",i); + mwi = monster[i].MType->Anims[MA_WALK].Frames - 1; + + switch (md) { + case M_DIRU : + M_StartWalk(i, 0, -MWVel[mwi][1], -1, -1, M_DIRU); + break; + case M_DIRUR : + M_StartWalk(i, MWVel[mwi][1], -MWVel[mwi][0], 0, -1, M_DIRUR); + break; + case M_DIRR : + M_StartWalk3(i, MWVel[mwi][2], 0, -32, -16, 1, -1, 1, 0, M_DIRR); + break; + case M_DIRDR : + M_StartWalk2(i, MWVel[mwi][1], MWVel[mwi][0], -32, -16, 1, 0, M_DIRDR); + break; + case M_DIRD : + M_StartWalk2(i, 0, MWVel[mwi][1], 0, -32, 1, 1, M_DIRD); + break; + case M_DIRDL : + M_StartWalk2(i, -MWVel[mwi][1], MWVel[mwi][0], 32, -16, 0, 1, M_DIRDL); + break; + case M_DIRL : + M_StartWalk3(i, -MWVel[mwi][2], 0, 32, -16, -1, 1, 0, 1, M_DIRL); + break; + case M_DIRUL : + M_StartWalk(i, -MWVel[mwi][1], -MWVel[mwi][0], -1 ,0, M_DIRUL); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GroupUnity(int i) +{ + int leader; + int tmp; + int m; + + // + // IMPLEMENT GROUP COHESION + // + + if ((DWORD)i >= MAXMONSTERS) + app_fatal("GroupUnity: Invalid monster %d",i); + if(monster[i].leaderflag) + { + leader = monster[i].leader; + + // test if there's a wall between monst and pack leader + tmp = LineClearF(CheckNoSolid, monster[i]._mx, monster[i]._my, + monster[leader]._mfutx, monster[leader]._mfuty); + if(!tmp && monster[i].leaderflag == PACK_MEMBER) + { + // have to leave pack + monster[leader].packsize--; + monster[i].leaderflag = PACK_NOMEMBER; + } + else if(tmp && monster[i].leaderflag == PACK_NOMEMBER + && DIST(monster[i]._mx - monster[leader]._mfutx, + monster[i]._my - monster[leader]._mfuty, 4)) + { + // rejoin pack + monster[leader].packsize++; + monster[i].leaderflag = PACK_MEMBER; + } + } + + if(monster[i].leaderflag == PACK_MEMBER) + { + // make sure leader is active + if(monster[i]._msquelch > monster[leader]._msquelch) + { + monster[leader]._lastx = monster[i]._mx; + monster[leader]._lasty = monster[i]._my; + monster[leader]._msquelch = monster[i]._msquelch-1; + } + if (monster[leader]._mAi == AI_GARG && (monster[leader]._mFlags & MFLAG_STILL)) { + monster[leader]._mFlags &= ~MFLAG_STILL; + monster[leader]._mmode = MM_SATTACK; + } + } + else if(monster[i]._uniqtype && (UniqMonst[monster[i]._uniqtype-1].mUnqAttr & UN_STICK)) + { + // make sure all of pack is activated + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for(m = 0; m < nummonsters; m++) + { + if(monster[tmp=monstactive[m]].leaderflag == PACK_MEMBER + && monster[tmp].leader == i) + { + if(monster[i]._msquelch > monster[tmp]._msquelch) + { + monster[tmp]._lastx = monster[i]._mx; + monster[tmp]._lasty = monster[i]._my; + monster[tmp]._msquelch = monster[i]._msquelch-1; + } + if (monster[tmp]._mAi == AI_GARG && (monster[tmp]._mFlags & MFLAG_STILL)) { + monster[tmp]._mFlags &= ~MFLAG_STILL; + monster[tmp]._mmode = MM_SATTACK; + } + } + } + } + // END OF GROUP COHESION +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_CallWalk(int i, int md) +{ + int mdtemp = md; + BOOL ok = FALSE; + ok = DirOK(i,md); + + if(random(101,2)) + ok = ok || DirOK(i, md = left[mdtemp]) || DirOK(i, md = right[mdtemp]); + else + ok = ok || DirOK(i, md = right[mdtemp]) || DirOK(i, md = left[mdtemp]); + + if(random(102,2)) + ok = ok || DirOK(i, md = right[right[mdtemp]]) || DirOK(i, md = left[left[mdtemp]]); + else + ok = ok || DirOK(i, md = left[left[mdtemp]]) || DirOK(i, md = right[right[mdtemp]]); + + if(ok) + M_WalkDir(i, md); + + return ok; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_PathWalk(int i) +{ + char path[MAXPATHLEN]; + static const char plr2monst[] = { 0, 5, 3, 7, 1, 4, 6, 0, 2 }; + + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_PathWalk: Invalid monster %d",i); + CHECKFUNC1 Check = (monster[i]._mFlags & MFLAG_CHECKDOORS) ? PosOkMonst3:PosOkMonst; + + int pathlen = FindPath(Check, i, monster[i]._mx, monster[i]._my, + monster[i]._menemyx, monster[i]._menemyy, + path); + if(pathlen) { + M_CallWalk(i, plr2monst[path[0]]); + return TRUE; + } + else + return FALSE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_CallWalk2(int i, int md) +{ + int mdtemp = md; + BOOL ok = FALSE; + ok = DirOK(i,md); + + if(random(101,2)) + ok = ok || DirOK(i, md = left[mdtemp]) || DirOK(i, md = right[mdtemp]); + else + ok = ok || DirOK(i, md = right[mdtemp]) || DirOK(i, md = left[mdtemp]); + + if(ok) + M_WalkDir(i, md); + + return ok; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_DumbWalk(int i, int md) +{ + BOOL ok; + + ok = DirOK(i,md); + + if(ok) + M_WalkDir(i, md); + return ok; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL M_RoundWalk(int i, int md, int &dir) +{ + int mdtemp; + BOOL ok = FALSE; + + if(dir) + md = left[left[md]]; + else + md = right[right[md]]; + mdtemp = md; + + ok = DirOK(i,md); + if(!ok) + { + // Note: The use of || below is a trick: the second condition is not evaluated + // (and therefore md is not re-set) if the first condition evaluates TRUE. + + if(dir) + ok = DirOK(i, md = right[mdtemp]) || DirOK(i, md = right[right[mdtemp]]); + else + ok = DirOK(i, md = left[mdtemp]) || DirOK(i, md = left[left[mdtemp]]); + } + + if(ok) + M_WalkDir(i,md); + else + { + // Note: The value of md here is set according to the second condition of the + // || operators above. Therefore, md is, by design, the direction towards + // the player. + dir = !dir; + ok = M_CallWalk(i,opposite[mdtemp]); + } + return ok; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void M_Face(int i) +{ + int md; + + if ((DWORD)i >= MAXMONSTERS) + app_fatal("M_Face: Invalid monster %d",i); + if (monster[i]._msquelch) { + md = M_GetDir(i); + monster[i]._mdir = md; + if (monster[i].MType == NULL) + app_fatal("M_Face: Monster %d \"%s\" MType NULL",i,monster[i].mName); + monster[i]._mAnimData = monster[i].MType->Anims[MA_STAND].Cels[md]; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Zombie(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Zombie: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int mx, my, md, v; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx -= Monst->_menemyx; + my -= Monst->_menemyy; + md = Monst->_mdir; + v = random(103,100); + + // Try attack + if (DIST(mx,my,2)) { + if (v < (10 + 2*Monst->_mint)) M_StartAttack(i); + } else { + // Try walk + if (v < (10 + 2*Monst->_mint)) { + // Check on distance from player + if(DIST(mx,my,4+2*Monst->_mint)) { + md = M_GetDir(i); + M_CallWalk(i, md); + } else { + if(random(104,100) < (20 + 2*Monst->_mint)) md = random(104,8); + M_DumbWalk(i, md); + } + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SkelSd(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_SkelSd: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int mx, my, md; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + // Try attack + if (DIST(mx,my,2)) { + if (Monst->_mVar1 == MM_DELAY || random(105,100) < 20 + 2*Monst->_mint) + M_StartAttack(i); + else + M_StartDelay(i, random(105,10)+10 - 2*Monst->_mint); + } else { + // Try walk -- more likely to walk if already walking + if ((Monst->_mVar1 != MM_DELAY) && random(106,100) < 35 - 4*Monst->_mint) + M_StartDelay(i, random(106,10) + 15 - 2*Monst->_mint); + else + M_CallWalk(i, md); + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL MAI_Path(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Path: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if ((Monst->MType->mtype != MT_GOLEM) // golum always ready to walk + && ((!Monst->_msquelch) + || (Monst->_mmode != MM_STAND) + || !(Monst->_mgoal == MG_ATTACK + || Monst->_mgoal == MG_WALK_AROUND1 + || Monst->_mgoal == MG_ATTACK2) + || (Monst->_mx == 1 && Monst->_my == 0))) // inactive golum + return FALSE; + if (!LineClearF1(PosOkMonst2, i,Monst->_mx,Monst->_my,Monst->_menemyx,Monst->_menemyy) + || (Monst->_pathcount >= 5 && Monst->_pathcount < 8)) + { + // Try Opening Door + if (Monst->_mFlags & MFLAG_CHECKDOORS) + MonstCheckDoors(i); + + if (++Monst->_pathcount >= 5) + { + if (M_PathWalk(i)) + return TRUE; + } + else // don't want to zero pathcount + return FALSE; + } + + if (Monst->MType->mtype != MT_GOLEM) Monst->_pathcount = 0; //path count for golum handled in ai + return FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Snake(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Snake: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int fx, fy, mx, my, md, pnum; + char pattern[] = { +1, +1, 0, -1, -1 , 0}; + int tmp; + + pnum = Monst->_menemy; + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + // Try attack + if (DIST(mx,my,2)) { + if (Monst->_mVar1 == MM_DELAY + || Monst->_mVar1 == MM_MISSILE + || random(105,100) < 20 + 1*Monst->_mint) + M_StartAttack(i); + else + M_StartDelay(i, random(105,10)+10 - 1*Monst->_mint); + } + else if (DIST(mx,my,3) + && LineClearF1(PosOkMonst, i,Monst->_mx,Monst->_my,fx,fy) + && Monst->_mVar1 != MM_MISSILE) + { + // Launch snake + if (AddMissile(Monst->_mx, Monst->_my, fx,fy, md, MIT_RHINO, pnum, i, 0, 0) != -1) { + PlayEffect(i, MS_ATTACK); + dMonster[Monst->_mx][Monst->_my] = -(i+1); + Monst->_mmode = MM_MISSILE; + } + } else { + // Try walk -- more likely to walk if already walking + if ((Monst->_mVar1 != MM_DELAY) && random(106,100) < 35 - 2*Monst->_mint) + M_StartDelay(i, random(106,10) + 15 - 1*Monst->_mint); + else + { + md = Mod(md + pattern[Monst->_mgoalvar1], 8); + if (++Monst->_mgoalvar1 > 5) + Monst->_mgoalvar1 = 0; + tmp = Mod(md - Monst->_mgoalvar2, 8); + if (tmp > 0) + { + if (tmp < 4) + Monst->_mgoalvar2 = Mod(Monst->_mgoalvar2 + 1, 8); + else if (tmp == 4) + Monst->_mgoalvar2 = md; + else + Monst->_mgoalvar2 = Mod(Monst->_mgoalvar2 - 1, 8); + } + app_assert(Monst->_mgoalvar2 >= 0 && Monst->_mgoalvar2 < 8); + if (!M_DumbWalk(i, Monst->_mgoalvar2)) + M_CallWalk2(i, Monst->_mdir); + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Bat(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Bat: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int mx, my, md, v, pnum; + int fx, fy; + + pnum = Monst->_menemy; + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + v = random(107,100); + if(Monst->_mgoal == MG_RUN_AWAY) + { + if(!Monst->_mgoalvar1) + { + M_CallWalk(i, opposite[md]); + Monst->_mgoalvar1++; + } + else + { + if(random(108,2)) + M_CallWalk(i, left[md]); + else + M_CallWalk(i, right[md]); + Monst->_mgoal = MG_ATTACK; + } + } + else + { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + // Try attack + if ((Monst->MType->mtype == MT_GLOOM) + && (!DIST(mx,my,5) && v < 33 + 4*Monst->_mint) && + LineClearF1(PosOkMonst, i,Monst->_mx,Monst->_my,fx,fy)) + { + // Turn into missile + if (AddMissile(Monst->_mx, Monst->_my, fx, fy, md, MIT_RHINO, pnum, i, 0, 0) != -1) { + dMonster[Monst->_mx][Monst->_my] = -(i+1); + Monst->_mmode = MM_MISSILE; + } + } + else if (DIST(mx,my,2)) { + if (v < 8 + 4*Monst->_mint) + { + M_StartAttack(i); + + // After attacking, fly away + Monst->_mgoal = MG_RUN_AWAY; + Monst->_mgoalvar1 = 0; + + if(Monst->MType->mtype == MT_FAMILIAR) { + // Note: arg 5 is a signal to the lightning code. + // The code checks if this is != to arg 1, and if so, checks for + // collision. Normally, collision is only checked for when + // lightning moves, but in this case it won't move! + AddMissile(Monst->_menemyx, Monst->_menemyy, Monst->_menemyx+1, 0, -1, MIT_LIGHTNING, MI_ENEMYPLR, i, random(109,10)+1, 0); + } + } + } else { + // Try walk + if ((Monst->_mVar2 > 20 && v < (13 + Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (63 + Monst->_mint))) { + M_CallWalk(i, md); + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SkelBow(int i) +{ + int mx, my, md, fx, fy; + BOOL walking = FALSE; + int v; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_SkelBow: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = M_GetDir(i); + Monst->_mdir = md; + + // Try walk + v = random(110,100); + if (DIST(mx,my,4) + && + ((Monst->_mVar2 > 20 + && v < 13 + 2*Monst->_mint) + || (WALKMODE(Monst->_mVar1) + && Monst->_mVar2 == 0 + && v < 63 + 2*Monst->_mint))) + { + walking = M_DumbWalk(i, opposite[md]); + } + fx = Monst->_menemyx; + fy = Monst->_menemyy; + if (!walking && (random(110,100) < 3+2*Monst->_mint) && + LineClear(Monst->_mx,Monst->_my,fx, fy)) + { + // Try attack + M_StartRAttack(i,MIT_ARROW,4); + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Fat(int i) +{ + int mx, my, md, v; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Fat: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = M_GetDir(i); + Monst->_mdir = md; + v = random(111,100); + // Try attack + if (DIST(mx,my,2)) { + if (v < (15 + 4*Monst->_mint)) M_StartAttack(i); + else if (v < (20 + 4*Monst->_mint)) M_StartSpAttack(i); + } else { + // Try walk + if ((Monst->_mVar2 > 20 && v < (20 + 4*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (70 + 4*Monst->_mint))) { + M_CallWalk(i, md); + } + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Sneak(int i) +{ + int mx, my, md, v; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Sneak: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int dist; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + if (dLight[mx][my] != lightmax) { + + mx -= Monst->_menemyx; + my -= Monst->_menemyy; + md = M_GetDir(i); + + dist = 5 - Monst->_mint; + + // If gothit, run away + if(Monst->_mVar1 == MM_GOTHIT) + { + Monst->_mgoal = MG_RUN_AWAY; + Monst->_mgoalvar1 = 0; // count run_away moves + } + // if far away enough, stop running away + else if(!DIST(mx,my,dist+3) || Monst->_mgoalvar1 > 8) + { + Monst->_mgoal = MG_ATTACK; + Monst->_mgoalvar1 = 0; + } + + if(Monst->_mgoal == MG_RUN_AWAY) + { + // Use special "owner location", i.e. the location of the player + // according to the computer which owns the player + // This is an attempt to reduce the amount of monster warping due to + // diverging paths on different computers + if (Monst->_mFlags & MFLAG_MID) + md = GetDirection(Monst->_mx, Monst->_my, + plr[Monst->_menemy]._pownerx, plr[Monst->_menemy]._pownery); + md = opposite[md]; + if(Monst->MType->mtype == MT_UNSEEN) + { + if(random(112,2)) + md = left[md]; + else + md = right[md]; + } + } + + Monst->_mdir = md; + + v = random(112,100); + // become visible + if(DIST(mx,my,dist) && (Monst->_mFlags & MFLAG_INVISIBLE)) + M_StartFadein(i,md,FALSE); + // become invisible + else if(!DIST(mx,my,dist+1) && !(Monst->_mFlags & MFLAG_INVISIBLE)) + M_StartFadeout(i,md,TRUE); + // Try attack + else if ((Monst->_mgoal == MG_RUN_AWAY) + || + ( !DIST(mx,my,2) + && + ((Monst->_mVar2 > 20 && v < (14 + 4*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (64 + 4*Monst->_mint))))) { + // Try walk + Monst->_mgoalvar1++; + M_CallWalk(i, md); + } + // face dir + if (Monst->_mmode == MM_STAND) + { + if (DIST(mx,my,2) && (v < (10 + 4*Monst->_mint))) { + M_StartAttack(i); + } + else + { + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Fireman(int i) +{ + int mx, my, md, v, pnum; + int fx, fy; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Fireman: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND && Monst->_msquelch) { + pnum = Monst->_menemy; + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = M_GetDir(i); + + if(Monst->_mgoal == MG_ATTACK) + { + if(LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Launch monster missile + if (AddMissile(Monst->_mx, Monst->_my, fx,fy, md, MIT_FIREMAN, pnum, i, 0, 0) != -1) { + Monst->_mmode = MM_MISSILE; + Monst->_mgoal = MG_ATTACK2; + Monst->_mgoalvar1 = 0; + } + } + } + else if(Monst->_mgoal == MG_ATTACK2) + { + if(Monst->_mgoalvar1 == 3) + { + Monst->_mgoal = MG_ATTACK; + M_StartFadeout(i,md,TRUE); + } + else if(LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Try attack + M_StartRAttack(i,MIT_KRULL,4); + Monst->_mgoalvar1++; + } + else + { + M_StartDelay(i, random(112,10) + 5); + Monst->_mgoalvar1++; + } + } + + else if(Monst->_mgoal == MG_RUN_AWAY) + { + M_StartFadein(i, md,FALSE); + Monst->_mgoal = MG_ATTACK2; + } + + Monst->_mdir = md; + + v = random(112,100); + + if(Monst->_mmode == MM_STAND) + { + if(DIST(mx,my,2) && Monst->_mgoal == MG_ATTACK) + { + M_TryH2HHit(i, monster[i]._menemy, monster[i].mHit, monster[i].mMinDamage, monster[i].mMaxDamage); + Monst->_mgoal = MG_RUN_AWAY; + if(!M_CallWalk(i, opposite[md])) + { + M_StartFadein(i, md,FALSE); + Monst->_mgoal = MG_ATTACK2; + } + } + else + { + if(!M_CallWalk(i, md)) + { + if(Monst->_mgoal == MG_ATTACK || Monst->_mgoal == MG_RUN_AWAY) + { + M_StartFadein(i, md, FALSE); + Monst->_mgoal = MG_ATTACK2; + } + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Fallen(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Fallen: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int x,y; + int xpos,ypos; + int m; + int rad; + int mx,my; + int aitype; + + if (Monst->_mgoal == MG_ATTACK2) + { + if(Monst->_mgoalvar1) + Monst->_mgoalvar1--; + else + Monst->_mgoal = MG_ATTACK; + } + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) + { + if (Monst->_mgoal == MG_RUN_AWAY && Monst->_mgoalvar1-- == 0) + { + Monst->_mgoal = MG_ATTACK; + M_StartStand(i, opposite[Monst->_mdir]); + } + if (Monst->_mAnimFrame == Monst->_mAnimLen) { + if (random(113,4) == 0) + { + // start 'dance' + if (!(monster[i]._mFlags & MFLAG_NOHEAL)) { + M_StartSpStand(i, Monst->_mdir); + if(Monst->_mmaxhp - (2*Monst->_mint+2) >= Monst->_mhitpoints) + Monst->_mhitpoints += 2*Monst->_mint+2; + else + Monst->_mhitpoints = Monst->_mmaxhp; + } + // set surrounding monsters into relentless attack + rad = 2*Monst->_mint+4; + for(y = -rad; y <= rad; y++) + { + for(x = -rad; x <= rad; x++) + { + xpos = Monst->_mx + x; + ypos = Monst->_my + y; + if(InBounds(x,y)) + { + m = dMonster[xpos][ypos]; + if(m > 0) + { + m--; + aitype = monster[m]._mAi; + if(aitype == AI_FALLEN) + { + monster[m]._mgoal = MG_ATTACK2; + // Set # frames for crazy attack mode + monster[m]._mgoalvar1 = (2*Monst->_mint+7)*15; + } + } + } + } + } + } + } + else if (Monst->_mgoal == MG_RUN_AWAY) + { + M_CallWalk(i,Monst->_mdir); + } + else if (Monst->_mgoal == MG_ATTACK2) + { + // attack relentlessly + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if(DIST(mx,my,2)) + M_StartAttack(i); + else + M_CallWalk(i, M_GetDir(i)); + } + else + MAI_SkelSd(i); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Cleaver(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Cleaver: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int mx, my, md; + + if (Monst->_mmode == MM_STAND && Monst->_msquelch) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + Monst->_mdir = md; + // If close, attack + if (DIST(mx,my,2)) { + M_StartAttack(i); + } else { + // Try walk + M_CallWalk(i, md); + } + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Round(int i, BOOL special) +{ + int mx, my, md, v; + int fx, fy, dist; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Round: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(114,100); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,4) && !random(115,4))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(116,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if( (Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) + { + Monst->_mgoal = MG_ATTACK; + } + else if(!M_RoundWalk(i,md,Monst->_mgoalvar2)) + M_StartDelay(i, random(125,10)+10); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (DIST(mx,my,2)) { + if (v < 23 + 2*Monst->_mint) + { + Monst->_mdir = md; + if(special && Monst->_mhitpoints < (Monst->_mmaxhp >> 1) && random(117,2)) + M_StartSpAttack(i); + else + M_StartAttack(i); + } + } + else if ((Monst->_mVar2 > 20 && v < (28 + 2*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (78 + 2*Monst->_mint))) { + M_CallWalk(i, md); + } + } + + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +void MAI_GoatMc(int i) +{ + MAI_Round(i, TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Ranged(int i, int missile_type, BOOL special) +{ + int fx, fy, mx, my, md; + BOOL walking = FALSE; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Ranged: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + if (Monst->_msquelch == 255 + || monster[i]._mFlags & MFLAG_MID) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = M_GetDir(i); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + Monst->_mdir = md; + + if (Monst->_mVar1 == MM_RATTACK) + { + // pause after each arrow + M_StartDelay(i, random(118,20)); + } + else if (DIST(mx,my,4) && random(119,100) < 70 + 10*Monst->_mint) + { + // retreat + walking = M_CallWalk(i, opposite[md]); + } + if (Monst->_mmode == MM_STAND) + { + if (LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Try attack + if(special) + M_StartRSpAttack(i,missile_type,4); + else + M_StartRAttack(i,missile_type,4); + } + else + // face dir + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } + } + else if(Monst->_msquelch // 0 < msquelch < 255 + && !(monster[i]._mFlags & MFLAG_MID)) // temp. golum fix + { + mx = Monst->_lastx; + my = Monst->_lasty; + md = GetDirection(Monst->_mx, Monst->_my, mx, my); + + M_CallWalk(i, md); + } + } +} + +void MAI_GoatBow(int i) +{ + MAI_Ranged(i,MIT_ARROW, FALSE); +} + +void MAI_Succ(int i) +{ + MAI_Ranged(i,MIT_FLARE, FALSE); +} + +void MAI_AcidUniq(int i) +{ + MAI_Ranged(i,MIT_ACID, TRUE); +} + +/*-----------------------------------------------------------------------* + * MAI_Scav + * + * MG_EAT is the scavenger's eat goal. + * _mgoalvar1 : =0 ==> no goal dest + * >0 ==> _mgoalvar1-1 is x coord of food + * _mgoalvar2 : _mgoalvar2-1 is y coord of food + * +**-----------------------------------------------------------------------*/ + +void MAI_Scav(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Scav: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int x,y; + BOOL done = FALSE; + + if (Monst->_mmode == MM_STAND) { + if(Monst->_mhitpoints < (Monst->_mmaxhp >> 1) && Monst->_mgoal != MG_EAT) + { + if(monster[i].leaderflag) + { + // leave pack permanently + monster[monster[i].leader].packsize--; + monster[i].leaderflag = 0; + } + Monst->_mgoal = MG_EAT; + Monst->_mgoalvar3 = 10; + } + + if (Monst->_mgoal == MG_EAT && Monst->_mgoalvar3) + { + Monst->_mgoalvar3--; + + // Are we on top of food? + if (dDead[Monst->_mx][Monst->_my]) + { + M_StartEat(i); + if (!(monster[i]._mFlags & MFLAG_NOHEAL)) { + int maxhp = (Monst->MType->mMaxHP << HP_SHIFT); + if (gbMaxPlayers == 1) + maxhp >>= 1; + + int healamt = maxhp >> 3; + + sprintf(infostr, "Eating, hp = %d, amt = %d, max = %d", + Monst->_mhitpoints >> HP_SHIFT, + healamt >> HP_SHIFT, + maxhp >> HP_SHIFT); + ClearPanel(); + AddPanelString(infostr, TEXT_CENTER); + + Monst->_mhitpoints += healamt; + + // by eating, the monster can get to its species maximum + // in hit points... + if (Monst->_mhitpoints > maxhp) + Monst->_mhitpoints = maxhp; + if (Monst->_mmaxhp < Monst->_mhitpoints) + Monst->_mmaxhp = Monst->_mhitpoints; + + if (Monst->_mgoalvar3 <= 0 || // done eating + Monst->_mhitpoints == maxhp) + { + dDead[Monst->_mx][Monst->_my] = 0; // monster buried + } + } +// if ((Monst->_mhitpoints) >= (Monst->_mmaxhp >> 1) + (Monst->_mmaxhp >> 2)) + if ((Monst->_mhitpoints) == (Monst->_mmaxhp)) + { + Monst->_mgoal = MG_ATTACK; + Monst->_mgoalvar1 = 0; + Monst->_mgoalvar2 = 0; + } + } + else + { + if (!Monst->_mgoalvar1) + { + // Find food! + // Randomize search direction + if(random(120,2)) + { + for(y = -4; y <= 4 && !done; y++) + for(x = -4; x <= 4 && !done; x++) + if(InBounds(x,y)) + done = dDead[Monst->_mx + x][Monst->_my + y] + && LineClearF(CheckNoSolid, Monst->_mx,Monst->_my,Monst->_mx + x,Monst->_my + y); + x--; + y--; + } + else + { + for(y = 4; y >= -4 && !done; y--) + for(x = 4; x >= -4 && !done; x--) + if(InBounds(x,y)) + done = dDead[Monst->_mx + x][Monst->_my + y] + && LineClearF(CheckNoSolid,Monst->_mx,Monst->_my,Monst->_mx + x,Monst->_my + y); + x++; + y++; + } + if(done) + { + // Note: 1 is added to the following vars because + // 0 is reserved as a flag meaning undefined. + Monst->_mgoalvar1 = Monst->_mx + x +1; + Monst->_mgoalvar2 = Monst->_my + y +1; + } + } + if(Monst->_mgoalvar1) + { + x = Monst->_mgoalvar1 - 1; + y = Monst->_mgoalvar2 - 1; + Monst->_mdir = GetDirection(Monst->_mx, Monst->_my, x, y); + M_CallWalk(i, Monst->_mdir); + } + } + } + else +// if(Monst->_mmode == MM_STAND) + // none of the above cases applied, so resort to default behavior + MAI_SkelSd(i); + } +} + + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Garg(int i) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Garg: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int mx, my; + int md; + + mx = Monst->_mx - Monst->_lastx; + my = Monst->_my - Monst->_lasty; + md = M_GetDir(i); + if(Monst->_msquelch && (Monst->_mFlags & MFLAG_STILL)) + { + M_Enemy(i); + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + + if(DIST(mx,my,Monst->_mint+2)) + Monst->_mFlags &= ~MFLAG_STILL; + } + else if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) + { + if(Monst->_mhitpoints < (Monst->_mmaxhp >> 1)) + { + // run away to get healed. + Monst->_mgoal = MG_RUN_AWAY; + } + if(Monst->_mgoal == MG_RUN_AWAY) + { + if(DIST(mx,my,Monst->_mint+2)) + { + if(!M_CallWalk(i,opposite[md])) + Monst->_mgoal = MG_ATTACK; + } + else + { + Monst->_mgoal = MG_ATTACK; + M_StartHeal(i); + + } + } + MAI_Round(i, FALSE); + } +} + + +/*-----------------------------------------------------------------------* + * MAI_RoundRanged + * + * Similar to MAI_Round, but does ranged attacks (throws lava) + * +**-----------------------------------------------------------------------*/ + +void MAI_RoundRanged(int i, int missile_type, BOOL checkdoors, int dam, BOOL lessmissiles) +{ + int fx, fy, mx, my, md, v, pnum; + int dist; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_RoundRanged: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + pnum = Monst->_menemy; + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(checkdoors && Monst->_msquelch < 255) + MonstCheckDoors(i); + + // Using random(10000) instead of random(100) for increased precision + // for small numbers, e.g. random(100) < (5 >> 1) + v = random(121,10000); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,3) && !random(122,4 << lessmissiles))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(123,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if(Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + { + Monst->_mgoal = MG_ATTACK; + } + else if(v < (500 + 500*Monst->_mint) >> lessmissiles + && + LineClear(Monst->_mx, Monst->_my, fx, fy)) + { + // Missile Attack + M_StartRSpAttack(i,missile_type,dam); + } + else + M_RoundWalk(i,md,Monst->_mgoalvar2); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (((!DIST(mx,my,3) && v < (1000 + 500*Monst->_mint) >> lessmissiles) + || + v < (500 + 500*Monst->_mint) >> lessmissiles) + && + LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Missile Attack + M_StartRSpAttack(i,missile_type,dam); + } + else if (DIST(mx,my,2)) + { + if (v < 6000 + 1000*Monst->_mint) + { + Monst->_mdir = md; + M_StartAttack(i); + } + } + else if (((v=random(124,100)) < (5000 + 1000*Monst->_mint)) + || + (WALKMODE(Monst->_mVar1) + && + Monst->_mVar2 == 0 && v < (8000 + 1000*Monst->_mint))) + { + M_CallWalk(i, md); + } + } + + // face dir + if (Monst->_mmode == MM_STAND) + M_StartDelay(i, random(125,10)+5); + } +} + +void MAI_Magma(int i) +{ + MAI_RoundRanged(i, MIT_MAGMABALL, TRUE,4, FALSE); +} + +void MAI_Storm(int i) +{ + MAI_RoundRanged(i, MIT_THINLIGHTCTRL, TRUE,4, FALSE); +} + +void MAI_Acid(int i) +{ + MAI_RoundRanged(i, MIT_ACID, FALSE,4, TRUE); +} + + +void MAI_Diablo(int i) +{ + MAI_RoundRanged(i, MIT_DIABAPOCA, FALSE, 40, FALSE); +} + +void MAI_RR2(int i, int mistype, int dam) +{ + int fx, fy, mx, my, md, v, pnum; + int dist; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_RR2: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if (!DIST(mx, my, 5)) + MAI_SkelSd(i); + else if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + pnum = Monst->_menemy; + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(121,100); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || !DIST(mx,my,3)) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(123,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + Monst->_mgoalvar3 = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if(Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + { + Monst->_mgoal = MG_ATTACK; + } + else if (v < 80 + 5*Monst->_mint) + M_RoundWalk(i,md,Monst->_mgoalvar2); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (((!DIST(mx,my,3) && v < 10 + 5*Monst->_mint) + || + v < 5 + 5*Monst->_mint + || Monst->_mgoalvar3 == MG_WALK_AROUND1) + && + LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Missile Attack + M_StartRSpAttack(i,mistype,dam); + } + else if (DIST(mx,my,2)) + { + if (random(124,100) < 40 + 10*Monst->_mint) + { + Monst->_mdir = md; + if (random(124, 2)) + M_StartAttack(i); + else + // Missile Attack + M_StartRSpAttack(i,mistype,dam); + } + } + else if (((v=random(124,100)) < (50 + 10*Monst->_mint)) + || + (WALKMODE(Monst->_mVar1) + && + Monst->_mVar2 == 0 && v < (80 + 10*Monst->_mint))) + { + M_CallWalk(i, md); + } + Monst->_mgoalvar3 = MG_ATTACK; + } + + if (Monst->_mmode == MM_STAND) + M_StartDelay(i, random(125,10)+5); + } +} + +void MAI_Mega(int i) +{ + MAI_RR2(i, MIT_FLAMEC,0); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MAI_Golum(int i) +{ + int ok, j, k, mid; + int mx, my, md; + BOOL have_enemy; + + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Golum: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if ((Monst->_mx == 1) && (Monst->_my == 0)) return; + + if (Monst->_mmode == MM_DEATH) return; + if (Monst->_mmode == MM_SPSTAND) return; + if (Monst->_mmode >= MM_WALK && Monst->_mmode <= MM_WALK3) return; + + if (!(monster[i]._mFlags & MFLAG_MID)) M_Enemy(i); + + have_enemy = !(Monst->_mFlags & MFLAG_NOENEMY); + + if (Monst->_mmode != MM_ATTACK) { + mx = Monst->_mx - monster[Monst->_menemy]._mfutx; + my = Monst->_my - monster[Monst->_menemy]._mfuty; + md = GetDirection(Monst->_mx, Monst->_my, monster[Monst->_menemy]._mx, monster[Monst->_menemy]._my); + Monst->_mdir = md; + + if (DIST(mx,my,2) && have_enemy) { + Monst->_menemyx = monster[Monst->_menemy]._mx; + Monst->_menemyy = monster[Monst->_menemy]._my; + if(!monster[Monst->_menemy]._msquelch) { + monster[Monst->_menemy]._msquelch = 255; + monster[Monst->_menemy]._lastx = Monst->_mx; + monster[Monst->_menemy]._lasty = Monst->_my; + for (j = 0; j < 5; j++) { + for (k = 0; k < 5; k++) { + mid = dMonster[monster[i]._mx - 2 + k][monster[i]._my - 2 + j]; + if (mid > 0) monster[mid]._msquelch = 255; + } + } + } + M_StartAttack(i); + } else { + if (!have_enemy || + !MAI_Path(i)) { + Monst->_pathcount++; + if (Monst->_pathcount > 8) Monst->_pathcount = 5; + ok = M_CallWalk(i, plr[i]._pdir); + if (ok == FALSE) { + md = (md - 1) & 0x07; + for (j = 0; j < 8 && ok == FALSE; j++) { + md = (md + 1) & 0x07; + ok = DirOK(i, md); + } + if (ok) + M_WalkDir(i, md); + } + } + } + } + +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SkelKing(int i) +{ + int fx, fy, mx, my, md, v; + int dist; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_SkelKing: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + int nx,ny; // location for new skel spawn + int skel; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(126,100); + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,3) && !random(127,4))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(128,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if( (Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) + { + Monst->_mgoal = MG_ATTACK; + } + else if(!M_RoundWalk(i,md,Monst->_mgoalvar2)) + M_StartDelay(i, random(125,10)+10); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (gbMaxPlayers == 1 // no spawning in multi-player + && ((!DIST(mx,my,3) && v < 35 + 4*Monst->_mint) + || v < 6) + && + LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Spawn new Skeleton + nx = Monst->_mx + offset_x[md]; + ny = Monst->_my + offset_y[md]; + if (PosOkMonst(i,nx,ny) && nummonsters < MAXMONSTERS) + { +// skel = AddMonster(nx, ny, md, 1, TRUE); +// M_StartSpStand(skel, md); + skel = M_SpawnSkel(nx, ny, md); + M_StartSpStand(i, md); + } + } + else if (DIST(mx,my,2)) { + if (v < 20 + Monst->_mint) + { + Monst->_mdir = md; + M_StartAttack(i); + } + } + else if (((v=random(129,100)) < (25 + Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (75 + Monst->_mint))) { + M_CallWalk(i, md); + } + else + M_StartDelay(i, random(130,10)+10); + } + + // face dir + if (Monst->_mmode == MM_STAND) + Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Rhino(int i) +{ + int fx, fy, mx, my, md, v; + int dist; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Rhino: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND && Monst->_msquelch) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(131,100); + if (DIST(mx,my,2)) { + Monst->_mgoal = MG_ATTACK; + } + else if(Monst->_mgoal == MG_WALK_AROUND1 + || (!DIST(mx,my,5) && random(132,4))) + { + if(Monst->_mgoal != MG_WALK_AROUND1) + { + Monst->_mgoalvar1 = 0; // reset counter + // Pick direction to walk around player + Monst->_mgoalvar2 = random(133,2); + } + + // MODE CHANGE: Walk Around player + + Monst->_mgoal = MG_WALK_AROUND1; + + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if( (Monst->_mgoalvar1++ >= (dist << 1)) + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) + { + Monst->_mgoal = MG_ATTACK; + } + else if(!M_RoundWalk(i,md,Monst->_mgoalvar2)) + M_StartDelay(i, random(125,10)+10); + } + if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if ((!DIST(mx,my,5) && v < 43 + 2*Monst->_mint) && + LineClearF1(PosOkMonst, i,Monst->_mx,Monst->_my,fx,fy)) + { + // Launch rhino + if (AddMissile(Monst->_mx, Monst->_my, fx,fy, md, MIT_RHINO, Monst->_menemy, i, 0, 0) != -1) { + if (Monst->MData->snd_special) PlayEffect(i, MS_SATTACK); + dMonster[Monst->_mx][Monst->_my] = -(i+1); + Monst->_mmode = MM_MISSILE; + } + } + else if (DIST(mx,my,2)) { + if (v < 28 + 2*Monst->_mint) + { + Monst->_mdir = md; + M_StartAttack(i); + } + } + else if (((v=random(134,100)) < (33 + 2*Monst->_mint)) || + (WALKMODE(Monst->_mVar1) && + Monst->_mVar2 == 0 && v < (83 + 2*Monst->_mint))) { + M_CallWalk(i, md); + } + else + M_StartDelay(i, random(135,10)+10); + } + + // face dir + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[Monst->_mdir]; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Counselor(int i) +{ + int fx, fy, mx, my, md, v; + int dist; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Counselor: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + static const BYTE counsmiss[] = { MIT_FIREBOLT, MIT_CBOLT, MIT_LIGHTCTRL, MIT_FIREBALL }; + + if ((Monst->_mmode == MM_STAND) && (Monst->_msquelch)) { + fx = Monst->_menemyx; + fy = Monst->_menemyy; + mx = Monst->_mx - fx; + my = Monst->_my - fy; + md = GetDirection(Monst->_mx, Monst->_my, Monst->_lastx, Monst->_lasty); + + if(Monst->_msquelch < 255) + MonstCheckDoors(i); + + v = random(121,100); + if (Monst->_mgoal == MG_RUN_AWAY) + { + if (Monst->_mgoalvar1++ > 3) + { + Monst->_mgoal = MG_ATTACK; + M_StartFadein(i, md, TRUE); + } + else + M_CallWalk(i, opposite[md]); + } + else if(Monst->_mgoal == MG_WALK_AROUND1) + { + // Calculate distance to player + dist = max(abs(mx),abs(my)); + + if (DIST(mx,my,2) + || Monst->_msquelch != 255 + || dTransVal[Monst->_mx][Monst->_my] + != dTransVal[fx][fy]) { + Monst->_mgoal = MG_ATTACK; + M_StartFadein(i, md, TRUE); + } + else if(Monst->_mgoalvar1++ >= (dist << 1) + && DirOK(i,md)) + { + Monst->_mgoal = MG_ATTACK; + M_StartFadein(i, md, TRUE); + } + else + M_RoundWalk(i,md,Monst->_mgoalvar2); + } + else if(Monst->_mgoal == MG_ATTACK) + { + // Try attack + if (DIST(mx,my,2)) + { + Monst->_mdir = md; + if (Monst->_mhitpoints < (Monst->_mmaxhp >> 1)) + { + // run away! + Monst->_mgoal = MG_RUN_AWAY; + Monst->_mgoalvar1 = 0; + M_StartFadeout(i, md, FALSE); + } + else if (Monst->_mVar1 == MM_DELAY || random(105,100) < 20 + 2*Monst->_mint) + { + M_StartRAttack(i,-1,0); + AddMissile(monster[i]._mx, monster[i]._my, 0, 0, monster[i]._mdir, MIT_FLASH, MI_ENEMYPLR, i, 4, 0); + AddMissile(monster[i]._mx, monster[i]._my, 0, 0, monster[i]._mdir, MIT_FLASH2, MI_ENEMYPLR, i, 4, 0); + } + else + M_StartDelay(i, random(105,10)+10 - 2*Monst->_mint); + } + else if (v < 50 + 5*Monst->_mint + && LineClear(Monst->_mx,Monst->_my,fx,fy)) + { + // Missile Attack + M_StartRAttack(i, counsmiss[Monst->_mint], random(77, Monst->mMaxDamage - Monst->mMinDamage + 1) + Monst->mMinDamage); + } + else if (random(124, 100) < 30) + { + Monst->_mgoal = MG_WALK_AROUND1; + Monst->_mgoalvar1 = 0; + M_StartFadeout(i, md, FALSE); + } + else + M_StartDelay(i, random(105,10)+10 - 2*Monst->_mint); + } + + // face dir + if (Monst->_mmode == MM_STAND) + M_StartDelay(i, random(125,10)+5); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Garbud(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Garbud: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if ((Monst->mtalkmsg < TXT_GARB4) && (Monst->mtalkmsg > (TXT_GARB1-1)) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->mtalkmsg++; + Monst->_mgoal = MG_TALK; + } + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_GARB4) && !(effect_is_playing(USFX_GARBUD4)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_WALK_AROUND1)) { + MAI_Round(i, TRUE); + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Zhar(int i) +{ + int mx, my, md, dist; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Zhar: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if ((Monst->mtalkmsg == TXT_ZHAR1) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->mtalkmsg++; + Monst->_mgoal = MG_TALK; + } + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + dist = max(abs(mx), abs(my)); + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_ZHAR2) && !(effect_is_playing(USFX_ZHAR2)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_RUN_AWAY) || (Monst->_mgoal == MG_WALK_AROUND1)) { + MAI_Counselor(i); + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_SnotSpil(int i) +{ + int mx, my, md, pnum; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_SnotSpil: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + pnum = Monst->_menemy; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if ((Monst->mtalkmsg == TXT_BOL1) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->mtalkmsg = TXT_BOL2; + Monst->_mgoal = MG_TALK; + } + if ((Monst->mtalkmsg == TXT_BOL2) && (quests[Q_LTBANNER]._qvar1 == 3)) { + Monst->mtalkmsg = 0; + Monst->_mgoal = MG_ATTACK; + } + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_BOL3) && !(effect_is_playing(USFX_SNOT3)) && (Monst->_mgoal == MG_WAITTOTALK)) { + int i = plr[pnum]._pvid; + ObjChangeMap(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1); + quests[Q_LTBANNER]._qvar1 = 3; + extern void RedoPlayerVision(); + RedoPlayerVision(); + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + if (quests[Q_LTBANNER]._qvar1 == 3) { + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_ATTACK2)) { + MAI_Fallen(i); + } + } + + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Lazurus(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Lazurus: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if (gbMaxPlayers == 1) { + if ((Monst->mtalkmsg == TXT_VB1) && (Monst->_mgoal == MG_TALK) + && (plr[myplr]._px == 35) && (plr[myplr]._py == 46)) { + PlayInGameMovie("gendata\\fprst3.smk"); + Monst->_mmode = MM_TALK; + quests[Q_BETRAYER]._qvar1 = 5; + } + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VB1) && !(effect_is_playing(USFX_LAZ1)) && (Monst->_mgoal == MG_WAITTOTALK)) { + ObjChangeMapResync(1, 18, 20, 24); + extern void RedoPlayerVision(); + RedoPlayerVision(); + quests[Q_BETRAYER]._qvar1 = 6; + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if (gbMaxPlayers != 1) { + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VB1) && (Monst->_mgoal == MG_TALK) && (quests[Q_BETRAYER]._qvar1 <= 3)) { + Monst->_mmode = MM_TALK; + } + #endif + } + + } + if ((Monst->_mgoal == MG_ATTACK) || (Monst->_mgoal == MG_RUN_AWAY) || (Monst->_mgoal == MG_WALK_AROUND1)) { + MAI_Counselor(i); + } + monster[i]._mdir = md; + if ((Monst->_mmode == MM_STAND) || (Monst->_mmode == MM_TALK)) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Lazhelp(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Lazhelp: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if (gbMaxPlayers == 1) { + if (quests[Q_BETRAYER]._qvar1 <= 5) + Monst->_mgoal = MG_TALK; + else { + Monst->_mgoal = MG_ATTACK; + Monst->mtalkmsg = 0; + } + } else if (gbMaxPlayers != 1) { + Monst->_mgoal = MG_ATTACK; + } + } + if (Monst->_mgoal == MG_ATTACK) { + MAI_Succ(i); + } + monster[i]._mdir = md; + } if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Lachdanan(int i) +{ + int mx, my, md, pnum; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Lachdanan: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + pnum = Monst->_menemy; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VEIL1) && !(dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->mtalkmsg++; + Monst->_mgoal = MG_TALK; + } + #endif + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + #if !IS_VERSION(SHAREWARE) + if ((Monst->mtalkmsg == TXT_VEIL3) && !(effect_is_playing(USFX_LACH3)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->mtalkmsg = 0; + quests[Q_VEIL]._qactive = QUEST_DONE; + M_StartKill(i, -1); + } + #endif + } + monster[i]._mdir = md; + if (Monst->_mmode == MM_STAND) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MAI_Warlord(int i) +{ + int mx, my, md; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("MAI_Warlord: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + + if (Monst->_mmode == MM_STAND) { + mx = Monst->_mx; + my = Monst->_my; + md = M_GetDir(i); + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + mx = Monst->_mx - Monst->_menemyx; + my = Monst->_my - Monst->_menemyy; + if ((Monst->mtalkmsg == TXT_WARLRD1) && (Monst->_mgoal == MG_TALK)) { + Monst->_mmode = MM_TALK; + } + + #if !IS_VERSION(SHAREWARE) + BOOL effect_is_playing(int nSFX); + if ((Monst->mtalkmsg == TXT_WARLRD1) && !(effect_is_playing(USFX_WARLRD1)) && (Monst->_mgoal == MG_WAITTOTALK)) { + Monst->_mgoal = MG_ATTACK; + Monst->_msquelch = 255; + Monst->mtalkmsg = 0; + } + #endif + } + if (Monst->_mgoal == MG_ATTACK) { + MAI_SkelSd(i); + } + monster[i]._mdir = md; + if ((Monst->_mmode == MM_STAND) || (Monst->_mmode == MM_TALK)) Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Cels[md]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DeleteMonsterList() +{ + int i, mi; + + // pseudo delete dead golems + for (i = 0; i < 4; i++) { + if (monster[i]._mDelFlag) { + monster[i]._mx = 1; + monster[i]._my = 0; + monster[i]._mfutx = 0; + monster[i]._mfuty = 0; + monster[i]._moldx = 0; + monster[i]._moldy = 0; + monster[i]._mDelFlag = FALSE; + } + } + + i = 4; // this is to skip the golems + app_assert((DWORD)nummonsters <= MAXMONSTERS); + while (i < nummonsters) { + mi = monstactive[i]; + if (monster[mi]._mDelFlag) { + DeleteMonster(i); + i = 0; + } else i++; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ProcessMonsters () +{ + int i, mi; + int raflag; + int mx, my; + MonsterStruct *Monst; + int oldmode; + + DeleteMonsterList(); + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + Monst = &monster[mi]; + raflag = RUN_DONE; + + // Try and run same AI's as best as possible in multiplayer + if (gbMaxPlayers > 1) { + SetRndSeed(Monst->_mAISeed); + Monst->_mAISeed = GetRndSeed(); + } + + // Turn regen + if (!(monster[mi]._mFlags & MFLAG_NOHEAL)) { + if ((Monst->_mhitpoints < Monst->_mmaxhp) && ((Monst->_mhitpoints >> HP_SHIFT) > 0)) { + if (Monst->mLevel > 1) + Monst->_mhitpoints += Monst->mLevel >> 1; + else + Monst->_mhitpoints += Monst->mLevel; + } + } + // Check if just activating + mx = Monst->_mx; + my = Monst->_my; + if ((dFlags[mx][my] & BFLAG_MONSTACTIVE) && (Monst->_msquelch == 0)) { + #if !IS_VERSION(SHAREWARE) + if (Monst->MType->mtype == MT_CLEAVER) { + //if (gbMaxPlayers == 1) PlayInGameMovie("gendata\\fbutch3.smk"); + PlaySFX(USFX_CLEAVER); + } + #endif + } + + // Check if monster's enemy + if (Monst->_mFlags & MFLAG_MID) { + if ((DWORD)Monst->_menemy >= MAXMONSTERS) + app_fatal("Illegal enemy monster %d for monster \"%s\"",Monst->_menemy,Monst->mName); + Monst->_menemyx = Monst->_lastx = monster[Monst->_menemy]._mfutx; + Monst->_menemyy = Monst->_lasty = monster[Monst->_menemy]._mfuty; + } else { + // Deal with keeping a monster active for a while after its visibility flag + // goes off + if ((DWORD)Monst->_menemy >= MAX_PLRS) + app_fatal("Illegal enemy player %d for monster \"%s\"",Monst->_menemy,Monst->mName); + Monst->_menemyx = plr[Monst->_menemy]._pfutx; + Monst->_menemyy = plr[Monst->_menemy]._pfuty; + if (dFlags[mx][my] & BFLAG_MONSTACTIVE) { + Monst->_msquelch = 255; + Monst->_lastx = plr[Monst->_menemy]._pfutx; + Monst->_lasty = plr[Monst->_menemy]._pfuty; + } else if(Monst->_msquelch && (Monst->_mAi != MT_DIABLO)) Monst->_msquelch--; + } + + do { + // Run Monster's AI + + // Try Path Mode + if (Monst->_mFlags & MFLAG_PATH) + { + if (!MAI_Path(mi)) + AiProc[Monst->_mAi](mi); + } + else + AiProc[Monst->_mAi](mi); + + // Run Monster Mode + switch (oldmode = Monst->_mmode) { + case MM_STAND : + raflag = M_DoStand(mi); + break; + case MM_WALK : + raflag = M_DoWalk(mi); + break; + case MM_WALK2 : + raflag = M_DoWalk2(mi); + break; + case MM_WALK3: + raflag = M_DoWalk3(mi); + break; + case MM_ATTACK: + raflag = M_DoAttack(mi); + break; + case MM_RATTACK: + raflag = M_DoRAttack(mi); + break; + case MM_GOTHIT: + raflag = M_DoGotHit(mi); + break; + case MM_DEATH: + raflag = M_DoDeath(mi); + break; + case MM_SATTACK: + raflag = M_DoSAttack(mi); + break; + case MM_FADEIN: + raflag = M_DoFadein(mi); + break; + case MM_FADEOUT: + raflag = M_DoFadeout(mi); + break; + case MM_SPSTAND: + raflag = M_DoSpStand(mi); + break; + case MM_RSATTACK: + raflag = M_DoRSpAttack(mi); + break; + case MM_DELAY: + raflag = M_DoDelay(mi); + break; + case MM_MISSILE: + raflag = RUN_DONE; + break; + case MM_STONE: + raflag = M_DoStone(mi); + break; + case MM_HEAL: + raflag = M_DoHeal(mi); + break; + case MM_TALK: + raflag = M_DoTalk(mi); + break; + } + +/* for (int mm = 0; mm < nummonsters; mm++) { + int mmi = monstactive[mm]; + app_assert(monster[mmi]._mDelFlag + || monster[mmi]._mmode == MM_MISSILE + || !monster[mmi]._msquelch + || mmi < 4 + || dMonster[monster[mmi]._mx][monster[mmi]._my] == mmi+1 + || dMonster[monster[mmi]._mx][monster[mmi]._my] == -(mmi+1)); + }*/ + + if(raflag != RUN_DONE) + GroupUnity(mi); + +// if (Monst->_msquelch) DaveMonstMap(FALSE, 0); + + } while (raflag != RUN_DONE); + + // Animate Monster + if (Monst->_mmode != MM_STONE) { + Monst->_mAnimCnt++; + if (!(Monst->_mFlags & MFLAG_STILL)) + { + if (Monst->_mAnimCnt >= Monst->_mAnimDelay) { + Monst->_mAnimCnt = 0; + if(Monst->_mFlags & MFLAG_BACKWARDS) + { + Monst->_mAnimFrame--; + if (!Monst->_mAnimFrame) Monst->_mAnimFrame = Monst->_mAnimLen; + } + else + { + Monst->_mAnimFrame++; + if (Monst->_mAnimFrame > Monst->_mAnimLen) Monst->_mAnimFrame = 1; + } + } + } + } + } + DeleteMonsterList(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeMonsterGFX() +{ + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (int monst = 0; monst < nummtypes; monst++) { + int mtype = Monsters[monst].mtype; + for (int anim = 0; anim < MAX_ANIMTYPE; anim++) { + if(!(animletter[anim] == 's' && !monsterdata[mtype].has_special)) { + DiabloFreePtr(Monsters[monst].Anims[anim].CMem); + } + } + } + + IFreeMissileGFX(); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL DirOK(int i, int mdir) +{ + long fx, fy; + int tmp; + + if ((DWORD)i >= MAXMONSTERS) + app_fatal("DirOK: Invalid monster %d",i); + fx = monster[i]._mx + offset_x[mdir]; + fy = monster[i]._my + offset_y[mdir]; + if(! InBounds(fx,fy)) + return FALSE; + + if (! PosOkMonst(i, fx, fy)) + return FALSE; + + if (mdir == M_DIRR) { + if (SolidLoc(fx+0,fy+1)) return FALSE; + if (dFlags[fx+0][fy+1] & BFLAG_MONSTLR) return FALSE; + } + else if(mdir == M_DIRL) { + if (SolidLoc(fx+1,fy+0)) return FALSE; + if (dFlags[fx+1][fy+0] & BFLAG_MONSTLR) return FALSE; + } + else if (mdir == M_DIRU) { + if (SolidLoc(fx+1,fy+0)) return FALSE; + if (SolidLoc(fx+0,fy+1)) return FALSE; + } + else if (mdir == M_DIRD) { + if (SolidLoc(fx-1,fy+0)) return FALSE; + if (SolidLoc(fx+0,fy-1)) return FALSE; + } + + // check for group cohesion + if(monster[i].leaderflag == PACK_MEMBER) { + // make sure monster is close to leader + return DIST( + fx-monster[monster[i].leader]._mfutx, + fy-monster[monster[i].leader]._mfuty, + 4 + ); + } + + if (monster[i]._uniqtype && (UniqMonst[monster[i]._uniqtype-1].mUnqAttr & UN_STICK)) + { + int mcount = 0; + for (int x = fx - 3; x <= fx + 3; x++) { + for (int y = fy - 3; y <= fy + 3; y++) { + if (! InBounds(x,y)) continue; + + if((tmp = dMonster[x][y]) < 0) tmp = -tmp; + if (tmp != 0) tmp--; + app_assert(tmp >= 0); + + if (monster[tmp].leaderflag == PACK_MEMBER && + monster[tmp].leader == i && + monster[tmp]._mfutx == x && + monster[tmp]._mfuty == y) mcount++; + } + } + + return (mcount == monster[i].packsize); + } + + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PosOkMissile(int x, int y) +{ + return !(nMissileTable[dPiece[x][y]] || (dFlags[x][y] & BFLAG_MONSTLR)); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CheckNoSolid(int x, int y) +{ + return !nSolidTable[dPiece[x][y]]; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +BOOL LineClearF(CHECKFUNC Clear, int x1, int y1, int x2, int y2) +{ + int md; + BOOL done = FALSE; + + do + { + md = GetDirection(x1,y1,x2,y2); + x1 += offset_x[md]; + y1 += offset_y[md]; + done = !(*Clear)(x1, y1); + } while(!done && !(x1==x2 && y1==y2)); + return (x1 == x2) && (y1 == y2); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL LineClearF(CHECKFUNC Clear, int x1, int y1, int x2, int y2) +{ + // Bresenham line algorithm + // See Foley/van Dam, "Computer Graphics: Principles and Practice" + + int dx,dy; + int d; // test variable + int dincH; // Horizontal increment for d + int dincD; // Diagonal increment for d + int xincD,yincD; // Diagonal increments for minor axis + int xorg, yorg; + BOOL done = FALSE; + int tmp; + + xorg = x1; + yorg = y1; + + dx = x2 - x1; + dy = y2 - y1; + if(abs(dx) > abs(dy)) + { + // X is the major axis + if(dx < 0) + { + // swap endpoints + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + + dx = -dx; + dy = -dy; + } + if(dy > 0) + { + // pos. slope + d = 2*dy - dx; + dincH = 2*dy; + dincD = 2*(dy - dx); + yincD = 1; + } + else + { + // neg. slope + d = 2*dy + dx; + dincH = 2*dy; + dincD = 2*(dy + dx); + yincD = -1; + } + +// done = (x1 != xorg || y1 != yorg) && !(*Clear)(x1, y1); + + while(!done && !(x1 == x2 && y1 == y2)) + { + if((d <= 0) ^ (yincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + y1 += yincD; + } + x1++; + done = (x1 != xorg || y1 != yorg) && !(*Clear)(x1, y1); + } + } + else + { + // Y is the major axis + if(dy < 0) + { + // swap endpoints + tmp = y1; + y1 = y2; + y2 = tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + + dy = -dy; + dx = -dx; + } + if(dx > 0) + { + // pos. slope + d = 2*dx - dy; + dincH = 2*dx; + dincD = 2*(dx - dy); + xincD = 1; + } + else + { + // neg. slope + d = 2*dx + dy; + dincH = 2*dx; + dincD = 2*(dx + dy); + xincD = -1; + } + +// done = (y1 != yorg || x1 != xorg) && !(*Clear)(x1, y1); + + while(!done && !(y1 == y2 && x1 == x2)) + { + if((d <= 0) ^ (xincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + x1 += xincD; + } + y1++; + done = (y1 != yorg || x1 != xorg) && !(*Clear)(x1, y1); + } + } + + return x1 == x2 && y1 == y2; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL LineClear(int x1, int y1, int x2, int y2) +{ + return LineClearF(PosOkMissile, x1, y1, x2, y2); +} + +/*-----------------------------------------------------------------------* + * LineClearF1 + * + * This is exactly the same routine as LineClearF, except its Check + * routine requires an extra argument +**-----------------------------------------------------------------------*/ + +BOOL LineClearF1(CHECKFUNC1 Clear, int monst, int x1, int y1, int x2, int y2) +{ + // Bresenham line algorithm + // See Foley/van Dam, "Computer Graphics: Principles and Practice" + + int dx,dy; + int d; // test variable + int dincH; // Horizontal increment for d + int dincD; // Diagonal increment for d + int xincD,yincD; // Diagonal increments for minor axis + int xorg, yorg; + BOOL done = FALSE; + int tmp; + + xorg = x1; + yorg = y1; + + dx = x2 - x1; + dy = y2 - y1; + if(abs(dx) > abs(dy)) + { + // X is the major axis + if(dx < 0) + { + // swap endpoints + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + + dx = -dx; + dy = -dy; + } + if(dy > 0) + { + // pos. slope + d = 2*dy - dx; + dincH = 2*dy; + dincD = 2*(dy - dx); + yincD = 1; + } + else + { + // neg. slope + d = 2*dy + dx; + dincH = 2*dy; + dincD = 2*(dy + dx); + yincD = -1; + } + + while(!done && !(x1 == x2 && y1 == y2)) + { + if((d <= 0) ^ (yincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + y1 += yincD; + } + x1++; + done = (x1 != xorg || y1 != yorg) && !Clear(monst, x1, y1); + } + } + else + { + // Y is the major axis + if(dy < 0) + { + // swap endpoints + tmp = y1; + y1 = y2; + y2 = tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + + dy = -dy; + dx = -dx; + } + if(dx > 0) + { + // pos. slope + d = 2*dx - dy; + dincH = 2*dx; + dincD = 2*(dx - dy); + xincD = 1; + } + else + { + // neg. slope + d = 2*dx + dy; + dincH = 2*dx; + dincD = 2*(dx + dy); + xincD = -1; + } + + while(!done && !(y1 == y2 && x1 == x2)) + { + if((d <= 0) ^ (xincD < 0)) + { + d += dincH; + } + else + { + d += dincD; + x1 += xincD; + } + y1++; + done = (y1 != yorg || x1 != xorg) && !Clear(monst, x1, y1); + } + } + + return x1 == x2 && y1 == y2; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncMonsterAnim(int m) +{ + int dir; + + if ((DWORD)m >= MAXMONSTERS) + app_fatal("SyncMonsterAnim: Invalid monster %d",m); + app_assert((DWORD)monster[m]._mMTidx < MAX_LVLMTYPES); + monster[m].MType = &Monsters[monster[m]._mMTidx]; + monster[m].MData = Monsters[monster[m]._mMTidx].MData; + if(monster[m]._uniqtype) + monster[m].mName = UniqMonst[monster[m]._uniqtype-1].mName; + else + monster[m].mName = monster[m].MData->mName; + + dir = monster[m]._mdir; + switch (monster[m]._mmode) { + case MM_STAND : + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + break; + case MM_WALK : + monster[m]._mAnimData = monster[m].MType->Anims[MA_WALK].Cels[dir]; + break; + case MM_WALK2 : + monster[m]._mAnimData = monster[m].MType->Anims[MA_WALK].Cels[dir]; + break; + case MM_WALK3: + monster[m]._mAnimData = monster[m].MType->Anims[MA_WALK].Cels[dir]; + break; + case MM_ATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_ATTACK].Cels[dir]; + break; + case MM_RATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_ATTACK].Cels[dir]; + break; + case MM_GOTHIT: + monster[m]._mAnimData = monster[m].MType->Anims[MA_GOTHIT].Cels[dir]; + break; + case MM_DEATH: + monster[m]._mAnimData = monster[m].MType->Anims[MA_DEATH].Cels[dir]; + break; + case MM_SATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_FADEIN: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_FADEOUT: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_SPSTAND: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_RSATTACK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_DELAY: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + break; + case MM_HEAL: + monster[m]._mAnimData = monster[m].MType->Anims[MA_SPECIAL].Cels[dir]; + break; + case MM_TALK: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + break; + case MM_STONE: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[MA_STAND].Frames; + break; + case MM_MISSILE: + monster[m]._mAnimData = monster[m].MType->Anims[MA_ATTACK].Cels[dir]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[MA_ATTACK].Frames; + break; + default: + monster[m]._mAnimData = monster[m].MType->Anims[MA_STAND].Cels[dir]; + monster[m]._mAnimFrame = 1; + monster[m]._mAnimLen = monster[m].MType->Anims[MA_STAND].Frames; + break; + } +} + + +/*-----------------------------------------------------------------------* +* When monster gets killed, make the fallen run in fear +**-----------------------------------------------------------------------*/ +void M_FallenFear(int x, int y) +{ + int i, mi; + int rundist; + int aitype; + + app_assert((DWORD)nummonsters <= MAXMONSTERS); + for (i = 0; i < nummonsters; i++) { + mi = monstactive[i]; + rundist = 0; + switch(monster[mi].MType->mtype) { + case MT_RFALLSD : + case MT_RFALLSP : + rundist = 7; + break; + case MT_DFALLSD : + case MT_DFALLSP : + rundist = 5; + break; + case MT_YFALLSD : + case MT_YFALLSP : + rundist = 3; + break; + case MT_BFALLSD : + case MT_BFALLSP : + rundist = 2; + break; + } + + aitype = monster[mi]._mAi; + if(aitype == AI_FALLEN) { + if (rundist + && DIST(x-monster[mi]._mx, y-monster[mi]._my, 5) + && ((monster[mi]._mhitpoints >> HP_SHIFT) > 0)) + { + monster[mi]._mgoal = MG_RUN_AWAY; + monster[mi]._mgoalvar1 = rundist; // run away for 'rundist' squares + // next direction will be away from monster that got hit + monster[mi]._mdir = GetDirection(x, y, monster[i]._mx, monster[i]._my); + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintMonstHistory(int mt) +{ + int res, minhp, maxhp; + + sprintf(tempstr, "Total kills : %i", monstkills[mt]); + AddPanelString(tempstr, TEXT_CENTER); + if (monstkills[mt] >= 30) { + minhp = monsterdata[mt].mMinHP; + maxhp = monsterdata[mt].mMaxHP; + if (gbMaxPlayers == 1) { + minhp = minhp >> 1; + maxhp = maxhp >> 1; + } + if (minhp < 1) minhp = 1; + if (maxhp < 1) maxhp = 1; + if (gnDifficulty == D_NIGHTMARE) { + minhp = (minhp * 3) + 100; + maxhp = (maxhp * 3) + 100; + } + if (gnDifficulty == D_HELL) { + minhp = (minhp * 4) + 200; + maxhp = (maxhp * 4) + 200; + } + sprintf(tempstr, "Hit Points : %i-%i", minhp, maxhp); + AddPanelString(tempstr, TEXT_CENTER); + } + /*minhp = monster[cursmonst]._mhitpoints >> HP_SHIFT; + maxhp = monster[cursmonst]._mmaxhp >> HP_SHIFT; + sprintf(tempstr, "Hit Points : %i of %i", minhp, maxhp); + AddPanelString(tempstr, TEXT_CENTER);*/ + if (monstkills[mt] >= 15) { + if (gnDifficulty != D_HELL) + res = monsterdata[mt].mMagicRes; + else + res = monsterdata[mt].mMagicRes2; + res &= (M_RM|M_RF|M_RL|M_IM|M_IF|M_IL); + if (res == M_NONE) { + strcpy(tempstr, "No magic resistance"); + AddPanelString(tempstr, TEXT_CENTER); + } else { + if (res & (M_RM|M_RF|M_RL)) { + strcpy(tempstr, "Resists : "); + if (res & M_RM) strcat(tempstr, "Magic "); + if (res & M_RF) strcat(tempstr, "Fire "); + if (res & M_RL) strcat(tempstr, "Lightning "); + tempstr[strlen(tempstr)-1] = 0; + AddPanelString(tempstr, TEXT_CENTER); + } + if (res & (M_IM|M_IF|M_IL)) { + strcpy(tempstr, "Immune : "); + if (res & M_IM) strcat(tempstr, "Magic "); + if (res & M_IF) strcat(tempstr, "Fire "); + if (res & M_IL) strcat(tempstr, "Lightning "); + tempstr[strlen(tempstr)-1] = 0; + AddPanelString(tempstr, TEXT_CENTER); + } + } + } + pinfoflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PrintUniqueHistory() +{ + int res; + + /*int minhp = monster[cursmonst]._mhitpoints >> HP_SHIFT; + int maxhp = monster[cursmonst]._mmaxhp >> HP_SHIFT; + sprintf(tempstr, "Hit Points : %i of %i", minhp, maxhp); + AddPanelString(tempstr, TEXT_CENTER);*/ + res = monster[cursmonst].mMagicRes; + res &= (M_RM|M_RF|M_RL|M_IM|M_IF|M_IL); + if (res == M_NONE) { + strcpy(tempstr, "No resistances"); + AddPanelString(tempstr, TEXT_CENTER); + strcpy(tempstr, "No Immunities"); + AddPanelString(tempstr, TEXT_CENTER); + } else { + if (res & (M_RM|M_RF|M_RL)) + strcpy(tempstr, "Some Magic Resistances"); + else + strcpy(tempstr, "No resistances"); + AddPanelString(tempstr, TEXT_CENTER); + if (res & (M_IM|M_IF|M_IL)) + strcpy(tempstr, "Some Magic Immunities"); + else + strcpy(tempstr, "No Immunities"); + AddPanelString(tempstr, TEXT_CENTER); + } + pinfoflag = TRUE; +} + +/*-----------------------------------------------------------------------* + * MissToMonst + * + * Used when Rhino charges and collides into something. +**-----------------------------------------------------------------------*/ + +void MissToMonst(int i, int x, int y) +{ + int oldx,oldy; + int newx,newy; + if ((DWORD)i >= MAXMISSILES) + app_fatal("MissToMonst: Invalid missile %d",i); + MissileStruct *Miss = &missile[i]; + int m = Miss->_misource; + if ((DWORD)m >= MAXMONSTERS) + app_fatal("MissToMonst: Invalid monster %d",m); + MonsterStruct *Monst = &monster[m]; + int pnum; + + app_assert(Monst->_mmode == MM_MISSILE); + + oldx = Miss->_mix; + oldy = Miss->_miy; + + dMonster[x][y] = m+1; + + Monst->_mdir = Miss->_mimfnum; + Monst->_mx = x; + Monst->_my = y; + M_StartStand(m, Monst->_mdir); + + if(EquivMonst(Monst->MType->mtype, MT_INCIN)) + M_StartFadein(m, Monst->_mdir, FALSE); + else { + if ((Monst->_mFlags & MFLAG_MID) == 0) + M_StartHit(m,-1,0); + else + M2MStartHit(m,-1,0); + } + + if ((Monst->_mFlags & MFLAG_MID) == 0) { + pnum = dPlayer[oldx][oldy]-1; + if((dPlayer[oldx][oldy] > 0) + && (Monst->MType->mtype != MT_GLOOM) + && !EquivMonst(Monst->MType->mtype, MT_INCIN)) + { + M_TryH2HHit(m, dPlayer[oldx][oldy]-1, 500, Monst->mMinDamage2, Monst->mMaxDamage2); + + // make sure player didn't go change location during h2hhit + if (pnum == dPlayer[oldx][oldy]-1 + && !EquivMonst(Monst->MType->mtype, MT_NSNAKE)) + { + // make sure player is doing a hit animation + if (plr[pnum]._pmode != PM_GOTHIT && plr[pnum]._pmode != PM_DEATH) + StartPlrHit(pnum, 0, TRUE); + + // knock opponent back one square + newx = oldx + offset_x[Monst->_mdir]; + newy = oldy + offset_y[Monst->_mdir]; + if(PosOkPlayer(pnum, newx, newy)) + { + plr[pnum]._px = newx; + plr[pnum]._py = newy; + FixPlayerLocation(pnum,plr[pnum]._pdir); + FixPlrWalkTags(pnum); + dPlayer[newx][newy] = pnum + 1; + SetPlayerOld(pnum); + } + } + } + } else { + if((dMonster[oldx][oldy] > 0) + && (Monst->MType->mtype != MT_GLOOM) && !EquivMonst(Monst->MType->mtype, MT_INCIN)) + { + M_TryM2MHit(m, dMonster[oldx][oldy]-1, 500, Monst->mMinDamage2, Monst->mMaxDamage2); + if (!EquivMonst(Monst->MType->mtype, MT_NSNAKE)) + { + // knock opponent back one square + newx = oldx + offset_x[Monst->_mdir]; + newy = oldy + offset_y[Monst->_mdir]; + if(PosOkMonst(dMonster[oldx][oldy]-1, newx, newy)) + { + // This assumes that monster got hit (since we use a 500% hit above) + // so we don't have to clean up his area, and we assume pnum is positive + pnum = dMonster[newx][newy] = dMonster[oldx][oldy]; + dMonster[oldx][oldy] = 0; + pnum--; + monster[pnum]._mfutx = monster[pnum]._mx = newx; + monster[pnum]._mfuty = monster[pnum]._my = newy; + } + } + } + } +} + +/*-----------------------------------------------------------------------* + * PosOkMonst + * + * Map position (x,y) is ok for placement of a monster. +**-----------------------------------------------------------------------*/ + +BOOL PosOkMonst(int i, int x, int y) +{ + BOOL ret = TRUE; + int oi; + int mi; + BOOL fire = FALSE; + + ret = !SolidLoc(x, y) && !dPlayer[x][y] && !dMonster[x][y]; + + if(ret && dObject[x][y]) + { + if (dObject[x][y] > 0) oi = dObject[x][y] - 1; + else oi = -(dObject[x][y] + 1); + if (object[oi]._oSolidFlag) ret = FALSE; + } + if(ret && dMissile[x][y] && i >= 0) + { + if((mi = dMissile[x][y]) > 0) + if(missile[mi]._mitype == MIT_FIREWALL) + fire = TRUE; + else + { + for(mi = 0; mi < nummissiles; mi++) + if(missile[missileactive[mi]]._mitype == MIT_FIREWALL) + fire = TRUE; + } + if ((fire && !(monster[i].mMagicRes & M_IF)) || (fire && (monster[i].MType->mtype == MT_DIABLO))) + ret = FALSE; + } + + return ret; +} + +/*-----------------------------------------------------------------------* + * PosOkMonst2 + * + * Map position (x,y) is ok for placement of a monster. + * Same as PosOkMonst, except ignores other monsters and players +**-----------------------------------------------------------------------*/ + +BOOL PosOkMonst2(int i, int x, int y) +{ + BOOL ret = TRUE; + int oi; + int mi; + BOOL fire = FALSE; + + ret = !SolidLoc(x, y); + + if(ret && dObject[x][y]) + { + if (dObject[x][y] > 0) oi = dObject[x][y] - 1; + else oi = -(dObject[x][y] + 1); + if (object[oi]._oSolidFlag) ret = FALSE; + } + if(ret && dMissile[x][y] && i >= 0) + { + if((mi = dMissile[x][y]) > 0) + if(missile[mi]._mitype == MIT_FIREWALL) + fire = TRUE; + else + { + for(mi = 0; mi < nummissiles; mi++) + if(missile[missileactive[mi]]._mitype == MIT_FIREWALL) + fire = TRUE; + } + if ((fire && !(monster[i].mMagicRes & M_IF)) || (fire && (monster[i].MType->mtype == MT_DIABLO))) + ret = FALSE; + } + + return ret; +} + +/*-----------------------------------------------------------------------* + * PosOkMonst + * + * Map position (x,y) is ok for placement of a monster. + * Same as PosOkMonst3, except ignores doors +**-----------------------------------------------------------------------*/ + +BOOL PosOkMonst3(int i, int x, int y) +{ + BOOL ret = TRUE; + int oi, objtype; + int mi; + BOOL fire = FALSE; + BOOL isdoor = FALSE; + + if(dObject[x][y]) + { + if (dObject[x][y] > 0) oi = dObject[x][y] - 1; + else oi = -(dObject[x][y] + 1); + objtype = object[oi]._otype; + isdoor = (objtype == OBJ_L1DOORL + || objtype == OBJ_L1DOORR + || objtype == OBJ_L2DOORL + || objtype == OBJ_L2DOORR + || objtype == OBJ_L3DOORL + || objtype == OBJ_L3DOORR); + if (object[oi]._oSolidFlag && !isdoor) + ret = FALSE; + } + + if (ret) + ret = (!SolidLoc(x, y) || isdoor) && !dPlayer[x][y] && !dMonster[x][y]; + + if(ret && dMissile[x][y] && i >= 0) + { + if((mi = dMissile[x][y]) > 0) + if(missile[mi]._mitype == MIT_FIREWALL) + fire = TRUE; + else + { + for(mi = 0; mi < nummissiles; mi++) + if(missile[missileactive[mi]]._mitype == MIT_FIREWALL) + fire = TRUE; + } + if ((fire && !(monster[i].mMagicRes & M_IF)) || (fire && (monster[i].MType->mtype == MT_DIABLO))) + ret = FALSE; + } + + return ret; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL IsSkel(int mt) +{ + return EquivMonst(mt, MT_WSKELAX) + || EquivMonst(mt, MT_WSKELBW) + || EquivMonst(mt, MT_WSKELSD); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL IsGoat(int mt) +{ + return EquivMonst(mt, MT_NGOATMC) + || EquivMonst(mt, MT_NGOATBW); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int M_SpawnSkel(int x, int y, int dir) +{ + int i,j; + int skeltypes = 0; + int skel; + + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes; i++) + if (IsSkel(Monsters[i].mtype)) + skeltypes++; + + if (skeltypes) + { + j = random(136,skeltypes); + skeltypes = 0; + for (i = 0; i < nummtypes && skeltypes <= j; i++) + if(IsSkel(Monsters[i].mtype)) + skeltypes++; + i--; + skel = AddMonster(x, y, dir, i, TRUE); + if (skel != -1) M_StartSpStand(skel, dir); + return skel; + } + else + return -1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ActivateSpawn(int i, int x, int y, int dir) +{ + dMonster[x][y] = i + 1; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + M_StartSpStand(i, dir); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL SpawnSkeleton(int ii, int x, int y) +{ + int monstok[3][3]; + int i,j,xx,yy,rs; + BOOL savail; + + if (ii == -1) return FALSE; + // Try location first + if (PosOkMonst(-1, x, y)) { + ActivateSpawn(ii, x, y, GetDirection(x, y, x, y)); + } else { + // Try surrounding squares + savail = FALSE; + yy = 0; + for (j = (y-1); j <= (y+1); j++) { + xx = 0; + for (i = (x-1); i <= (x+1); i++) { + monstok[xx][yy] = PosOkMonst(-1, i,j); + savail |= monstok[xx][yy]; + xx++; + } + yy++; + } + + // No fit, no good + if (!savail) return(FALSE); + + // Place skeleton + rs = random(137,15) + 1; + xx = 0; + yy = 0; + while (rs > 0) { + if (monstok[xx][yy]) rs--; + if (rs > 0) { + xx++; + if (xx == 3) { + xx = 0; + yy++; + if (yy == 3) yy = 0; + } + } + } + xx = xx + x - 1; + yy = yy + y - 1; + ActivateSpawn(ii, xx, yy, GetDirection(xx, yy, x, y)); + } + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PreSpawnSkeleton() +{ + int i,j; + int skeltypes = 0; + int skel; + + app_assert((DWORD)nummtypes <= MAX_LVLMTYPES); + for (i = 0; i < nummtypes; i++) + if (IsSkel(Monsters[i].mtype)) + skeltypes++; + + if (skeltypes) + { + j = random(136,skeltypes); + skeltypes = 0; + for (i = 0; i < nummtypes && skeltypes <= j; i++) + { + if(IsSkel(Monsters[i].mtype)) + skeltypes++; + } + i--; + skel = AddMonster(0, 0, 0, i, FALSE); + if (skel != -1) M_StartStand(skel, 0); + return skel; + } + else + return -1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void TalktoMonster(int i) +{ + int pnum, itm; + if ((DWORD)i >= MAXMONSTERS) + app_fatal("TalktoMonster: Invalid monster %d",i); + MonsterStruct *Monst = &monster[i]; + pnum = Monst->_menemy; + + Monst->_mmode = MM_TALK; + + if ((Monst->_mAi != AI_SNOTSPIL) && (Monst->_mAi != AI_LACHDANAN)) + return; + + if (QuestStatus(Q_LTBANNER)) { + if ((quests[Q_LTBANNER]._qvar1 == 2) && (PlrHasItem(pnum, IDI_BANNER, itm))) { + RemoveInvItem(pnum, itm); + quests[Q_LTBANNER]._qactive = QUEST_DONE; + Monst->mtalkmsg = TXT_BOL3; + Monst->_mgoal = MG_TALK; + } + } + if (QuestStatus(Q_VEIL)) { + if ((Monst->mtalkmsg >= TXT_VEIL1) && (PlrHasItem(pnum, IDI_GLDNELIX, itm))) { + RemoveInvItem(pnum, itm); + Monst->mtalkmsg = TXT_VEIL3; + Monst->_mgoal = MG_TALK; + } + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SpawnGolum(int i, int x, int y, int mi) +{ + if ((DWORD)i >= MAXMONSTERS) + app_fatal("SpawnGolum: Invalid monster %d",i); + dMonster[x][y] = i + 1; + monster[i]._mx = x; + monster[i]._my = y; + monster[i]._mfutx = x; + monster[i]._mfuty = y; + monster[i]._moldx = x; + monster[i]._moldy = y; + monster[i]._pathcount = 0; + + monster[i]._mmaxhp = ((plr[i]._pMaxMana/3)<<1) + (((missile[mi]._mispllvl << HP_SHIFT) << 3) + ((missile[mi]._mispllvl << HP_SHIFT) << 1)); + monster[i]._mhitpoints = monster[i]._mmaxhp; + monster[i].mArmorClass = 25; + monster[i].mHit = 40 + (plr[i]._pLevel << 1) + ((missile[mi]._mispllvl << 2) + (missile[mi]._mispllvl)); + monster[i].mMinDamage = 8 + (missile[mi]._mispllvl << 1); + monster[i].mMaxDamage = 16 + (missile[mi]._mispllvl << 1); + + monster[i]._mFlags |= MFLAG_MKILLER; + M_StartSpStand(i, 0); + M_Enemy(i); + + void NetSendCmdGolem(BYTE, BYTE, BYTE, BYTE, long, BYTE); + if (i == myplr) + NetSendCmdGolem(monster[i]._mx, monster[i]._my, monster[i]._mdir, monster[i]._menemy, monster[i]._mhitpoints, currlevel); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CanTalkToMonst(int m) +{ + if ((DWORD)m >= MAXMONSTERS) + app_fatal("CanTalkToMonst: Invalid monster %d",m); + if (monster[m]._mgoal == MG_TALK) return(TRUE); + if (monster[m]._mgoal == MG_WAITTOTALK) return(TRUE); + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CheckMonsterHit(int m, BOOL &ret) +{ + if ((DWORD)m >= MAXMONSTERS) + app_fatal("CheckMonsterHit: Invalid monster %d",m); + if (monster[m]._mAi == AI_GARG && (monster[m]._mFlags & MFLAG_STILL)) + { + monster[m]._mFlags &= ~MFLAG_STILL; + monster[m]._mmode = MM_SATTACK; + ret = TRUE; + return(TRUE); + } + else if(EquivMonst(monster[m].MType->mtype, MT_COUNSLR) + && (monster[m]._mgoal != MG_ATTACK)) + { + ret = FALSE; + return TRUE; + } + return FALSE; +} + +//****************************************************************** +//****************************************************************** +int encode_enemy(int m) +{ + if (monster[m]._mFlags & MFLAG_MID) + return monster[m]._menemy + MAX_PLRS; + else + // enemy is player, guaranteed < MAX_PLRS + return monster[m]._menemy; +} + +//****************************************************************** +//****************************************************************** +void decode_enemy(int m, int enemy) +{ + if (enemy < MAX_PLRS) { + monster[m]._mFlags &= ~MFLAG_MID; + monster[m]._menemy = enemy; + monster[m]._menemyx = plr[enemy]._pfutx; + monster[m]._menemyy = plr[enemy]._pfuty; + } + else { + monster[m]._mFlags |= MFLAG_MID; + enemy -= MAX_PLRS; + monster[m]._menemy = enemy; + monster[m]._menemyx = monster[enemy]._mfutx; + monster[m]._menemyy = monster[enemy]._mfuty; + } +} diff --git a/MONSTINT.H b/MONSTINT.H new file mode 100644 index 0000000..054d674 --- /dev/null +++ b/MONSTINT.H @@ -0,0 +1,71 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Monstint.h +** +** Definitions internal to Monster modules +** See Monster.h for definitions necessary outside monster modules +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/MONSTINT.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +// Monster Modes +#define MM_STAND 0 +#define MM_WALK 1 +#define MM_WALK2 2 +#define MM_WALK3 3 +#define MM_ATTACK 4 +#define MM_GOTHIT 5 +#define MM_DEATH 6 +#define MM_SATTACK 7 // Special Attack +#define MM_FADEIN 8 +#define MM_FADEOUT 9 +#define MM_RATTACK 10 // Ranged weapon attack +#define MM_SPSTAND 11 // Special Neutral +#define MM_RSATTACK 12 // Ranged Special attack +#define MM_DELAY 13 // Stand for a while +#define MM_MISSILE 14 // Do nothing while monster is a missile +#define MM_STONE 15 // Monster is Stone Cursed +#define MM_HEAL 16 // Gargoyle still while healing +#define MM_TALK 17 // Monster is in talk mode + +// Monster Goals +#define MG_ATTACK 1 +#define MG_RUN_AWAY 2 +#define MG_EAT 3 +#define MG_WALK_AROUND1 4 +#define MG_ATTACK2 5 +#define MG_TALK 6 +#define MG_WAITTOTALK 7 + +// Monster Anims +#define MA_STAND 0 +#define MA_WALK 1 +#define MA_ATTACK 2 +#define MA_GOTHIT 3 +#define MA_DEATH 4 +#define MA_SPECIAL 5 + +// Monster Direction +#define M_DIRU 4 +#define M_DIRUR 5 +#define M_DIRR 6 +#define M_DIRDR 7 +#define M_DIRD 0 +#define M_DIRDL 1 + +#define M_DIRL 2 +#define M_DIRUL 3 + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void M_FallenFear(int x, int y); +BOOL SolidLoc(int x, int y); diff --git a/MOVIE.CPP b/MOVIE.CPP new file mode 100644 index 0000000..7e89290 --- /dev/null +++ b/MOVIE.CPP @@ -0,0 +1,114 @@ +//****************************************************************** +// movie.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "palette.h" +#include "engine.h" +#include "scrollrt.h" +#include "gendung.h" +#include "sound.h" + + +//****************************************************************** +// externs +//****************************************************************** +void CALLBACK menusnd_play(LPCSTR pszName); +WNDPROC my_SetWindowProc(WNDPROC wndProc); +void BlackPalette(); +void music_pause(BOOL bPause); +void stream_stop(); + + +//****************************************************************** +// private +//****************************************************************** +static BYTE sgbPlayMovie; + + +//****************************************************************** +//****************************************************************** +static LRESULT CALLBACK MovieWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { + switch (uMsg) { + case WM_SYSCOMMAND: + if (wParam == SC_CLOSE) { + sgbPlayMovie = FALSE; + return 0; + } + break; + + case WM_KEYDOWN: + sgbPlayMovie = FALSE; + break; + + case WM_CHAR: + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + sgbPlayMovie = FALSE; + break; + } + + return DiabloDefProc(hWnd,uMsg,wParam,lParam); +} + + +//****************************************************************** +//****************************************************************** +BOOL gbLoopMovie = FALSE; +void play_movie(const char * pszMovie,BOOL bAllowCancel) { + app_assert(pszMovie); + + // if we are not the frontmost window then don't play the movie + if (! bActive) return; + + app_assert(ghMainWnd); + WNDPROC saveProc = my_SetWindowProc(MovieWndProc); + InvalidateRect(ghMainWnd,NULL,0); + UpdateWindow(ghMainWnd); + + sgbPlayMovie = TRUE; + + // stop music and streaming SFX from playing so they + // don't interfere with the CD bandwidth during movie + music_pause(TRUE); + stream_stop(); + + // play "silence" because according to RAD software, it + // prevents a popping noise upon movie startup + menusnd_play("Sfx\\Misc\\blank.wav"); + HSVIDEO hVid; + SVidPlayBegin( + pszMovie, + NULL, + NULL, + NULL, + 0, + gbLoopMovie ? (SVID_AUTOCUTSCENE|SVID_FLAG_LOOP)&~SVID_FLAG_CLEARSCREEN : SVID_AUTOCUTSCENE, + &hVid + ); + + while (hVid && bActive) { + if (bAllowCancel && !sgbPlayMovie) break; + + MSG msg; + while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { + if (msg.message == WM_QUIT) continue; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (!SVidPlayContinue()) + break; + } + + if (hVid) SVidPlayEnd(hVid); + + // restore window procedure + saveProc = my_SetWindowProc(saveProc); + app_assert(saveProc == MovieWndProc); + + music_pause(FALSE); +} diff --git a/MPQAPI.CPP b/MPQAPI.CPP new file mode 100644 index 0000000..f1dc043 --- /dev/null +++ b/MPQAPI.CPP @@ -0,0 +1,1006 @@ +//****************************************************************** +// MPQapi.cpp +// File pack API +// By Michael O'Brien (6/1/96) && Patrick Wyatt (6/24/96) +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "engine.h" +#include "mpqapi.h" + + +//****************************************************************** +// debugging +//****************************************************************** +#define DUMP_BLOCK 0 // 0 in final +#ifdef NDEBUG +#undef DUMP_BLOCK +#define DUMP_BLOCK 0 +#endif + + +//****************************************************************** +// extern +//****************************************************************** +extern BYTE gbMaxPlayers; + + +//****************************************************************** +// public +//****************************************************************** +char gszProgKey[] = "Hellfire"; + + +//****************************************************************** +// private +//****************************************************************** +#define MPQ_HIDE_ATTR (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) + +static HANDLE sghArchive = INVALID_HANDLE_VALUE; +static BOOL sgbChanged; + +// extra header -- non-standard .MPQ stuff +#define FILE_EXHDR_SIZE 72 +#define FILE_EXHDR_OFFSET sizeof(FILEHEADER) + +// block table +#define BLOCK_ENTRIES 2048 +#define BLOCK_TBL_SIZE (BLOCK_ENTRIES * sizeof(BLOCKENTRY)) +#define BLOCK_TBL_OFFSET (FILE_EXHDR_OFFSET + FILE_EXHDR_SIZE) +static BLOCKENTRYPTR sgpBlockTbl; + +// hash table +#define HASH_ENTRIES 2048 // must be pow2 +#define HASH_TBL_SIZE (HASH_ENTRIES * sizeof(HASHENTRY)) +#define HASH_TBL_OFFSET (BLOCK_TBL_OFFSET + BLOCK_TBL_SIZE) +static HASHENTRYPTR sgpHashTbl; + +// offset past last file where next added file will start +#define FIRST_FILE_START (HASH_TBL_OFFSET + HASH_TBL_SIZE) +static DWORD sgdwNextFileStart; + +// minimum space we will allow as standalone "free" block in file +#define MIN_FREE_SIZE 1024 + +static BYTE sgbSaveCreationKey = FALSE; + +#if IS_VERSION(SHAREWARE) +static char sgszArchiveKey[] = "Audio Playback "; +#else +static char sgszArchiveKey[] = "Video Player "; +#endif + + +#define CREATION_TIME 0 +#define LASTWRITE_TIME 1 +#define NUM_TIMES 2 + +typedef struct EXFILEHEADER { + BYTE bData[FILE_EXHDR_SIZE]; +} EXFILEHEADER; + +typedef struct FULLHEADER { + FILEHEADER hdr; + EXFILEHEADER exhdr; +} FULLHEADER; + + +//****************************************************************** +// imported functions +//****************************************************************** +void InitializeHashSource(); +void Decrypt(LPDWORD data, DWORD bytes, DWORD key); +void Encrypt(LPDWORD data, DWORD bytes, DWORD key); +DWORD Hash(const char *filename, int hashtype); +DWORD Compress(LPBYTE data, DWORD bytes); + + +//****************************************************************** +//****************************************************************** +static void xor_timestamp(FILETIME * pTime) { + DWORD dwKey = 0xf0761ab; + LPBYTE lpStamp = (LPBYTE) pTime; + DWORD dwBytes = sizeof(FILETIME); + while (dwBytes--) { + *lpStamp++ ^= (BYTE) dwKey; + dwKey = _rotl(dwKey,1); + } +} + + +//****************************************************************** +//****************************************************************** +static BOOL reg_get_stamps(FILETIME * pft,DWORD dwSize) { + ZeroMemory(pft,dwSize); + DWORD dwBytes; + if (! SRegLoadData(gszProgKey,sgszArchiveKey,0,pft,dwSize,&dwBytes)) + return FALSE; + if (dwBytes != dwSize) + return FALSE; + + while (dwSize >= sizeof FILETIME) { + xor_timestamp(pft++); + dwSize -= sizeof FILETIME; + } + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static void reg_set_stamps(FILETIME * pft,DWORD dwSize) { + // only update registry stamps for multiplayer mode + app_assert(gbMaxPlayers != 1); + + FILETIME * pft2 = pft; + for (DWORD d = dwSize; d >= sizeof FILETIME; d -= sizeof FILETIME) + xor_timestamp(pft2++); + +// pjw.patch1.start +// SRegSaveData(gszProgKey,sgszArchiveKey,SREG_FLAG_FLUSHTODISK,pft,dwSize); + SRegSaveData(gszProgKey,sgszArchiveKey,0,pft,dwSize); +// pjw.patch1.end +} + + +//****************************************************************** +//****************************************************************** +/* pjw.patch1.start +static int stamp_compare(FILETIME * pf1,FILETIME * pf2) { + return ! memcmp(pf1,pf2,sizeof FILETIME); +} +pjw.patch1.end */ + + +//****************************************************************** +//****************************************************************** +BOOL MPQSetAttributes(const char * pszArchive,BOOL bHide) { + app_assert(pszArchive); + + // get the attributes for the file + DWORD dwAttr; + if (0xffffffff == (dwAttr = GetFileAttributes(pszArchive))) { + if (ERROR_FILE_NOT_FOUND == GetLastError()) + return TRUE; + return FALSE; + } + + DWORD dwWantAttr = bHide ? MPQ_HIDE_ATTR : 0; + if (dwAttr == dwWantAttr) return TRUE; + return SetFileAttributes(pszArchive,dwWantAttr); +} + + +//****************************************************************** +//****************************************************************** +BOOL MPQCompareTimeStamps(const char * pszArchive,DWORD dwChar) { +/* pjw.patch1.start + app_assert(pszArchive); + app_assert(dwChar < MAX_CHARACTERS); + + // get archive timestamps from registry + FILETIME ft[MAX_CHARACTERS][NUM_TIMES]; + if (! reg_get_stamps(&ft[0][0],sizeof ft)) return FALSE; + + // get archive file timestamps + WIN32_FIND_DATA finddata; + HANDLE findhandle = FindFirstFile(pszArchive,&finddata); + if (findhandle == INVALID_HANDLE_VALUE) return FALSE; + FindClose(findhandle); + + return + stamp_compare(&finddata.ftCreationTime,&ft[dwChar][CREATION_TIME]) + && + stamp_compare(&finddata.ftLastWriteTime,&ft[dwChar][LASTWRITE_TIME]); +pjw.patch1.end */ + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +void MPQMungeStamps(DWORD dwChar) { +/* pjw.patch1.start + // only update registry stamps for multiplayer mode + if (gbMaxPlayers == 1) return; + app_assert(dwChar < MAX_CHARACTERS); + + FILETIME ft[MAX_CHARACTERS][NUM_TIMES]; + reg_get_stamps(&ft[0][0],sizeof ft); + ft[dwChar][0].dwHighDateTime = 0x78341348; + reg_set_stamps(&ft[0][0],sizeof ft); +pjw.patch1.end */ +} + + +//****************************************************************** +//****************************************************************** +static void MPQUpdateLastWriteTimeStamp(const char * pszArchive,DWORD dwChar) { + // only update registry stamps for multiplayer mode + if (gbMaxPlayers == 1) return; + + app_assert(pszArchive); + app_assert(dwChar < MAX_CHARACTERS); + + // get archive timestamps from registry + FILETIME ft[MAX_CHARACTERS][NUM_TIMES]; + reg_get_stamps(&ft[0][0],sizeof ft); + + // get archive file timestamps + WIN32_FIND_DATA finddata; + HANDLE findhandle = FindFirstFile(pszArchive,&finddata); + if (findhandle == INVALID_HANDLE_VALUE) return; + FindClose(findhandle); + + // update timestamp + ft[dwChar][LASTWRITE_TIME] = finddata.ftLastWriteTime; + + // save back to registry + reg_set_stamps(&ft[0][0],sizeof ft); +} + + +//****************************************************************** +//****************************************************************** +void MPQUpdateCreationTimeStamp(const char * pszArchive,DWORD dwChar) { + // only update registry stamps for multiplayer mode + if (gbMaxPlayers == 1) return; + app_assert(pszArchive); + app_assert(dwChar < MAX_CHARACTERS); + + // get archive timestamps from registry + FILETIME ft[MAX_CHARACTERS][NUM_TIMES]; + reg_get_stamps(&ft[0][0],sizeof ft); + + // get archive file timestamps + WIN32_FIND_DATA finddata; + HANDLE findhandle = FindFirstFile(pszArchive,&finddata); + if (findhandle == INVALID_HANDLE_VALUE) return; + FindClose(findhandle); + + // update timestamp + ft[dwChar][CREATION_TIME] = finddata.ftCreationTime; + + reg_set_stamps(&ft[0][0],sizeof ft); +} + + +//****************************************************************** +//****************************************************************** +#if DUMP_BLOCK +static const char * fflags_2_str(DWORD dwFlags) { + if (dwFlags & MPQ_ADD_COMPRESSED) { + if (dwFlags & MPQ_ADD_ENCRYPTED) + return "ENCRYPT+COMPRESS"; + return "COMPRESS"; + } + + if (dwFlags & MPQ_ADD_ENCRYPTED) + return "ENCRYPT"; + return "NONE"; +} +#endif + + +//****************************************************************** +//****************************************************************** +#if DUMP_BLOCK +static void dump_blocktbl(void) { + + FILE * f = fopen("c:\\block.txt","wb"); + if (! f) return; + + fprintf(f," start + size = end\r\n"); + DWORD dwPosition = FIRST_FILE_START; + while (dwPosition != sgdwNextFileStart) { + BLOCKENTRY * pBlk = sgpBlockTbl; + for (DWORD i = BLOCK_ENTRIES; i--; pBlk++) { + if (pBlk->offset != dwPosition) continue; + fprintf(f,"%8d + %8d = %8d %s\r\n", + pBlk->offset, + pBlk->sizealloc, + pBlk->offset + pBlk->sizealloc, + fflags_2_str(pBlk->flags) + ); + dwPosition = pBlk->offset + pBlk->sizealloc; + break; + } + if (i == -1) { + fclose(f); + void myDebugBreak(); + myDebugBreak(); + app_fatal("Bad block table"); + } + } + + fprintf(f,"next file start: %d\r\n",sgdwNextFileStart); + fclose(f); +} +#endif + + +//****************************************************************** +//****************************************************************** +static BLOCKENTRY * get_free_block(DWORD * pdwBlockIndex) { + BLOCKENTRY * pBlk = sgpBlockTbl; + for (DWORD i = 0; i < BLOCK_ENTRIES; i++, pBlk++) { + if (pBlk->offset) continue; + if (pBlk->sizealloc) continue; + if (pBlk->flags) continue; + if (pBlk->sizefile) continue; + if (pdwBlockIndex) *pdwBlockIndex = i; + return pBlk; + } + + app_fatal("Out of free block entries"); + return NULL; +} + + +//****************************************************************** +//****************************************************************** +static void add_free_block(DWORD dwOffset,DWORD dwSize) { + // see if we can merge this block with an existing free block + BLOCKENTRY * pBlk = sgpBlockTbl; + for (DWORD i = BLOCK_ENTRIES; i--; pBlk++) { + // is this block unused? + if (pBlk->offset == 0) continue; + if (pBlk->flags != 0) continue; + if (pBlk->sizefile != 0) continue; + + if (pBlk->offset + pBlk->sizealloc == dwOffset) { + dwOffset = pBlk->offset; + dwSize += pBlk->sizealloc; + } + else if (dwOffset + dwSize == pBlk->offset) { + dwSize += pBlk->sizealloc; + } + else { + continue; + } + + // try adding the new larger block. + // NOTE: in the worst case, we free a block which is between + // two free blocks, which causes only one deep recursion + ZeroMemory(pBlk,sizeof(*pBlk)); + add_free_block(dwOffset,dwSize); + return; + } + + if (dwOffset + dwSize > sgdwNextFileStart) + app_fatal("MPQ free list error"); + + // is this block at the end of the file? + if (dwOffset + dwSize == sgdwNextFileStart) { + sgdwNextFileStart = dwOffset; + return; + } + + // create a new block entry + pBlk = get_free_block(NULL); + pBlk->offset = dwOffset; + pBlk->sizealloc = dwSize; + pBlk->sizefile = 0; + pBlk->flags = 0; +} + + +//****************************************************************** +//****************************************************************** +static DWORD get_free_space(DWORD dwSize,DWORD * pdwSizeAlloc) { + DWORD dwOffset; + + // see if there is a space large enough in an existing block + BLOCKENTRY * pBlk = sgpBlockTbl; + for (DWORD i = BLOCK_ENTRIES; i--; pBlk++) { + // is this block unused? + if (pBlk->offset == 0) continue; + if (pBlk->flags != 0) continue; + if (pBlk->sizefile != 0) continue; + if (pBlk->sizealloc < dwSize) continue; + + // use a portion of this block + dwOffset = pBlk->offset; + *pdwSizeAlloc = dwSize; + + // fixup this block + pBlk->offset += dwSize; + pBlk->sizealloc -= dwSize; + + // did we use the entire block? + if (! pBlk->sizealloc) ZeroMemory(pBlk,sizeof(BLOCKENTRY)); + + return dwOffset; + } + + // use free space at end of .MPQ file + *pdwSizeAlloc = dwSize; + dwOffset = sgdwNextFileStart; + sgdwNextFileStart += dwSize; + return dwOffset; +} + + +//****************************************************************** +//****************************************************************** +static DWORD SearchHashEntry( + DWORD hashindex, + DWORD hashcheck0, + DWORD hashcheck1, + LCID lcid +) { + DWORD dwCount = HASH_ENTRIES; + for ( + DWORD entry = hashindex & (HASH_ENTRIES - 1); + (sgpHashTbl+entry)->block != HASH_BLOCK_UNUSED; + entry = (entry + 1) & (HASH_ENTRIES - 1) + ) { + if (! dwCount--) break; + + if ((sgpHashTbl+entry)->hashcheck[0] != hashcheck0) + continue; + if ((sgpHashTbl+entry)->hashcheck[1] != hashcheck1) + continue; + if ((sgpHashTbl+entry)->lcid != lcid) + continue; + if ((sgpHashTbl+entry)->block == HASH_BLOCK_FREED) + continue; + + return entry; + } + + return HASH_ENTRY_UNUSED; +} + + +//****************************************************************** +//****************************************************************** +static BOOL WriteFileHeader() { + FULLHEADER fhdr; + + // initialize header + ZeroMemory(&fhdr,sizeof(fhdr)); + + // fill in .mpq header + fhdr.hdr.signature = SIGNATURE; + fhdr.hdr.headersize = sizeof(FILEHEADER); + fhdr.hdr.filesize = GetFileSize(sghArchive,NULL); + fhdr.hdr.version = VERSION; + fhdr.hdr.sectorsizeid = SECTORSIZEID; + fhdr.hdr.hashoffset = HASH_TBL_OFFSET; + fhdr.hdr.blockoffset = BLOCK_TBL_OFFSET; + fhdr.hdr.hashcount = HASH_ENTRIES; + fhdr.hdr.blockcount = BLOCK_ENTRIES; + + DWORD dwTemp; + if (0xffffffff == SetFilePointer(sghArchive,0,NULL,FILE_BEGIN)) + return FALSE; + if (! WriteFile(sghArchive,&fhdr.hdr,sizeof(fhdr),&dwTemp,NULL)) + return FALSE; + return sizeof(fhdr) == dwTemp; +} + + +//****************************************************************** +//****************************************************************** +static BOOL WriteBlockTable() { + #if DUMP_BLOCK + dump_blocktbl(); + #endif + + if (0xffffffff == SetFilePointer(sghArchive,BLOCK_TBL_OFFSET,NULL,FILE_BEGIN)) + return FALSE; + + DWORD dwTemp; + Encrypt((LPDWORD) sgpBlockTbl,BLOCK_TBL_SIZE,Hash("(block table)",HASH_ENCRYPTKEY)); + BOOL bResult = WriteFile(sghArchive,sgpBlockTbl,BLOCK_TBL_SIZE,&dwTemp,NULL); + Decrypt((LPDWORD) sgpBlockTbl,BLOCK_TBL_SIZE,Hash("(block table)",HASH_ENCRYPTKEY)); + + return bResult && BLOCK_TBL_SIZE == dwTemp; +} + + +//****************************************************************** +//****************************************************************** +static BOOL WriteHashTable() { + if (0xffffffff == SetFilePointer(sghArchive,HASH_TBL_OFFSET,NULL,FILE_BEGIN)) + return FALSE; + + DWORD dwTemp; + Encrypt((LPDWORD) sgpHashTbl,HASH_TBL_SIZE,Hash("(hash table)",HASH_ENCRYPTKEY)); + BOOL bResult = WriteFile(sghArchive,sgpHashTbl,HASH_TBL_SIZE,&dwTemp,NULL); + Decrypt((LPDWORD) sgpHashTbl,HASH_TBL_SIZE,Hash("(hash table)",HASH_ENCRYPTKEY)); + + return bResult && HASH_TBL_SIZE == dwTemp; +} + + +//****************************************************************** +//****************************************************************** +static BOOL SetEOF() { + if (0xffffffff == SetFilePointer(sghArchive,sgdwNextFileStart,NULL,FILE_BEGIN)) + return FALSE; + return SetEndOfFile(sghArchive); +} + + +//****************************************************************** +//****************************************************************** +static BOOL read_mpq_file_hdr(FULLHEADER * pHdr,DWORD * pdwNextFileStart) { + BOOL bError; + DWORD dwBytes; + app_assert(pHdr); + app_assert(pdwNextFileStart); + + // read file hdr + DWORD dwFileSize = GetFileSize(sghArchive,NULL); + *pdwNextFileStart = dwFileSize; + if (dwFileSize == 0xffffffff) + bError = TRUE; + else if (sizeof(*pHdr) > dwFileSize) + bError = TRUE; + else if (! ReadFile(sghArchive,pHdr,sizeof(*pHdr),&dwBytes,NULL)) + bError = TRUE; + else if (sizeof(*pHdr) != dwBytes) + bError = TRUE; + else if (pHdr->hdr.signature != SIGNATURE) + bError = TRUE; + else if (pHdr->hdr.headersize != sizeof(FILEHEADER)) + bError = TRUE; + else if (pHdr->hdr.version > VERSION) + bError = TRUE; + else if (pHdr->hdr.sectorsizeid != SECTORSIZEID) + bError = TRUE; + else if (pHdr->hdr.filesize != dwFileSize) + bError = TRUE; + else if (pHdr->hdr.hashoffset != HASH_TBL_OFFSET) + bError = TRUE; + else if (pHdr->hdr.blockoffset != BLOCK_TBL_OFFSET) + bError = TRUE; + else if (pHdr->hdr.hashcount != HASH_ENTRIES) + bError = TRUE; + else if (pHdr->hdr.blockcount != BLOCK_ENTRIES) + bError = TRUE; + else // NO ERROR (finally) + bError = FALSE; + + if (bError) { + // kill off any existing file hdr information + if (0xffffffff == SetFilePointer(sghArchive,0,NULL,FILE_BEGIN)) + return FALSE; + if (! SetEndOfFile(sghArchive)) + return FALSE; + + // initialize file header + ZeroMemory(pHdr,sizeof(*pHdr)); + + // fill in .mpq header + pHdr->hdr.signature = SIGNATURE; + pHdr->hdr.headersize = sizeof(FILEHEADER); + pHdr->hdr.sectorsizeid = SECTORSIZEID; + pHdr->hdr.version = VERSION; + + // set location of start of next file + *pdwNextFileStart = FIRST_FILE_START; + + // modified the file + sgbChanged = TRUE; + sgbSaveCreationKey = TRUE; + } + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static DWORD SearchHashName(const char * pszName) { + return SearchHashEntry( + Hash(pszName,HASH_INDEX), + Hash(pszName,HASH_CHECK0), + Hash(pszName,HASH_CHECK1), + MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT) + ); +} + + +//****************************************************************** +//****************************************************************** +static void mpq_delete_file(const char * pszName) { + DWORD dwEntry = SearchHashName(pszName); + if (dwEntry == HASH_ENTRY_UNUSED) + return; + + HASHENTRY * pHash = sgpHashTbl + dwEntry; + BLOCKENTRY * pBlk = sgpBlockTbl + pHash->block; + + // we can't set the hash block to HASH_BLOCK_UNUSED, because + // we use closed hashing. Another file may have hashed + // to the same spot, and so was added to the hash table + // after this hash entry. Therefore, just mark the hash + // entry as freed, but not unused + pHash->block = HASH_BLOCK_FREED; + + // free the block entry and give back the memory + DWORD dwOffset = pBlk->offset; + DWORD dwSize = pBlk->sizealloc; + ZeroMemory(pBlk,sizeof(*pBlk)); + add_free_block(dwOffset,dwSize); + + // modified the file + sgbChanged = TRUE; +} + + +//****************************************************************** +//****************************************************************** +void MPQDeleteFile(const char * pszName) { + app_assert(sghArchive != INVALID_HANDLE_VALUE); + app_assert(pszName); + + // if the specified file is not part of the archive, + // then consider the delete operation successful + mpq_delete_file(pszName); +} + + +//****************************************************************** +//****************************************************************** +void MPQDeleteFiles(TGetNameFcn fnGetName) { + app_assert(sghArchive != INVALID_HANDLE_VALUE); + app_assert(fnGetName); + + DWORD dwIndex = 0; + char szName[MAX_PATH]; + while (fnGetName(dwIndex++,szName)) + mpq_delete_file(szName); +} + + +//****************************************************************** +//****************************************************************** +static BLOCKENTRY * InsertIntoHash(const char * pszName,BLOCKENTRY * pBlk,DWORD dwBlock) { + DWORD hashindex = Hash(pszName,HASH_INDEX); + DWORD hashcheck0 = Hash(pszName,HASH_CHECK0); + DWORD hashcheck1 = Hash(pszName,HASH_CHECK1); + + if (HASH_ENTRY_UNUSED != SearchHashEntry( + hashindex, + hashcheck0, + hashcheck1, + MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT))) + app_fatal("Hash collision between \"%s\" and existing file\n",pszName); + + // find free slot in hash table + long lCount = HASH_ENTRIES; + DWORD entry = hashindex & (HASH_ENTRIES - 1); + while (lCount--) { + if ((sgpHashTbl+entry)->block == HASH_BLOCK_UNUSED) break; + if ((sgpHashTbl+entry)->block == HASH_BLOCK_FREED) break; + entry = (entry + 1) & (HASH_ENTRIES - 1); + } + if (lCount < 0) app_fatal("Out of hash space"); + + if (! pBlk) pBlk = get_free_block(&dwBlock); + (sgpHashTbl+entry)->hashcheck[0] = hashcheck0; + (sgpHashTbl+entry)->hashcheck[1] = hashcheck1; + (sgpHashTbl+entry)->lcid = MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT); + (sgpHashTbl+entry)->block = dwBlock; + return pBlk; +} + + +//****************************************************************** +//****************************************************************** +static BOOL WriteFileData( + const char * pszName, + const BYTE * pbData, + DWORD dwLen, + BLOCKENTRY * pBlk +) { + // DETERMINE THE FILE NAME PORTION OF THE PATH NAME + const char * pszTemp; + while (NULL != (pszTemp = strchr(pszName,':'))) + pszName = pszTemp + 1; + while (NULL != (pszTemp = strchr(pszName,'\\'))) + pszName = pszTemp + 1; + + // CREATE AN ENCRYPTION KEY BASED ON THE FILE NAME + DWORD key = Hash(pszName,HASH_ENCRYPTKEY); + DWORD sectors = (dwLen + SECTORSIZE - 1) / SECTORSIZE; + DWORD sectoroffsetsize = (sectors + 1) * sizeof(DWORD); + + // find free space for file + DWORD dwSizeAllocGuess = dwLen + sectoroffsetsize; + pBlk->offset = get_free_space(dwSizeAllocGuess,&pBlk->sizealloc); + pBlk->sizefile = dwLen; + pBlk->flags = MPQ_ADD_COMPRESSED | MPQ_ADD_ALLOCATED; + if (0xffffffff == SetFilePointer(sghArchive,pBlk->offset,NULL,FILE_BEGIN)) + return FALSE; + + DWORD sector = 0; + DWORD destsize = 0; + static BYTE buffer[SECTORSIZE]; + LPDWORD sectoroffsettable = NULL; + while (dwLen) { + for (int loop = 0; loop < SECTORSIZE; ++loop) + buffer[loop] += 0xAA; + + // PERFORM COMPRESSION + DWORD bytes = min(dwLen,SECTORSIZE); + CopyMemory(buffer,pbData,bytes); + pbData += bytes; + bytes = Compress(buffer,bytes); + + // LEAVE SPACE FOR THE SECTOR OFFSET TABLE. + if (! sector) { + sectoroffsetsize = (sectors+1)*sizeof(DWORD); + sectoroffsettable = (LPDWORD) DiabloAllocPtrSig(sectoroffsetsize,'MPQt'); + ZeroMemory(sectoroffsettable,sectoroffsetsize); + if (! WriteFile(sghArchive,sectoroffsettable,sectoroffsetsize,§oroffsetsize,NULL)) + goto error; + destsize += sectoroffsetsize; + } + + // SAVE THE SECTOR OFFSET + app_assert(sectoroffsettable); + *(sectoroffsettable+sector) = destsize; + + // PERFORM ENCRYPTION -- not encrypted for save files + // Encrypt((LPDWORD)buffer,bytes & 0xFFFFFFFC,key+sector); + + // WRITE THE SECTOR + if (! WriteFile(sghArchive,buffer,bytes,&bytes,NULL)) + goto error; + + ++sector; + if (dwLen > SECTORSIZE) + dwLen -= SECTORSIZE; + else + dwLen = 0; + destsize += bytes; + } + + app_assert(sectoroffsettable); + *(sectoroffsettable+sector) = destsize; + // bug in mopaq 1.91 -- fixed in 1.92 + // sector table is not supposed to be encrypted for unencrypted files + // Encrypt(sectoroffsettable,sectoroffsetsize,key+0xFFFFFFFF); + if (0xffffffff == SetFilePointer(sghArchive,-(LONG)destsize,NULL,FILE_CURRENT)) + goto error; + if (! WriteFile(sghArchive,sectoroffsettable,sectoroffsetsize,§oroffsetsize,NULL)) + goto error; + if (0xffffffff == SetFilePointer(sghArchive,destsize-sectoroffsetsize,NULL,FILE_CURRENT)) + goto error; + DiabloFreePtr(sectoroffsettable); + + // make sure the file fit into the hole we provided + app_assert(destsize <= pBlk->sizealloc); + + // give back any extra space we might have allocated + if (destsize < pBlk->sizealloc) { + DWORD dwLeftover = pBlk->sizealloc - destsize; + if (dwLeftover >= MIN_FREE_SIZE) { + pBlk->sizealloc = destsize; + add_free_block(pBlk->offset + destsize, dwLeftover); + } + } + + return TRUE; +error: + if (sectoroffsettable) DiabloFreePtr(sectoroffsettable); + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +BOOL MPQAddFile(const char * pszName,const BYTE * pbData,DWORD dwLen) { + app_assert(sghArchive != INVALID_HANDLE_VALUE); + app_assert(pszName); + app_assert(pbData); + app_assert(dwLen); + + // think positive + BOOL bResult = TRUE; + sgbChanged = TRUE; + + // delete any existing file with the same name + mpq_delete_file(pszName); + + // insert the new file data + BLOCKENTRY * pBlk = InsertIntoHash(pszName,NULL,0); + if (! WriteFileData(pszName,pbData,dwLen,pBlk)) { + mpq_delete_file(pszName); + return FALSE; + } + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +void MPQRenameFile(const char * pszOld,const char * pszNew) { + app_assert(sghArchive != INVALID_HANDLE_VALUE); + app_assert(pszOld); + app_assert(pszNew); + DWORD dwEntry = SearchHashName(pszOld); + if (dwEntry == HASH_ENTRY_UNUSED) + return; + + HASHENTRY * pHash = sgpHashTbl + dwEntry; + BLOCKENTRY * pBlk = sgpBlockTbl + pHash->block; + DWORD dwBlock = pHash->block; + + // we can't set the hash block to HASH_BLOCK_UNUSED, because + // we use closed hashing. Another file may have hashed + // to the same spot, and so was added to the hash table + // after this hash entry. Therefore, just mark the hash + // entry as freed, but not unused + pHash->block = HASH_BLOCK_FREED; + + // create a new hash entry which references the existing block + InsertIntoHash(pszNew,pBlk,dwBlock); + + // modified the file + sgbChanged = TRUE; +} + + +//****************************************************************** +//****************************************************************** +BOOL MPQFileExists(const char * pszName) { + app_assert(sghArchive != INVALID_HANDLE_VALUE); + app_assert(pszName); + return SearchHashName(pszName) != HASH_ENTRY_UNUSED; +} + + +//****************************************************************** +//****************************************************************** +static void CloseArchive(const char * pszArchive,BOOL bFree,DWORD dwChar) { + + if (bFree) { + DiabloFreePtr(sgpBlockTbl); + DiabloFreePtr(sgpHashTbl); + } + + if (sghArchive != INVALID_HANDLE_VALUE) { + CloseHandle(sghArchive); + sghArchive = INVALID_HANDLE_VALUE; + } + + if (sgbChanged) { + // since we wrote the file, update the last write timestamp + sgbChanged = FALSE; + MPQUpdateLastWriteTimeStamp(pszArchive,dwChar); + } + + if (sgbSaveCreationKey) { + // update the file creation timestamp if the archive was just created + sgbSaveCreationKey = FALSE; + MPQUpdateCreationTimeStamp(pszArchive,dwChar); + } +} + + +//****************************************************************** +//****************************************************************** +BOOL MPQOpenArchive(const char * pszArchive,BOOL bHide,DWORD dwChar) { + DWORD dwTemp; + app_assert(pszArchive); + app_assert(sghArchive == INVALID_HANDLE_VALUE); + InitializeHashSource(); + + if (! MPQSetAttributes(pszArchive,bHide)) + return FALSE; + + DWORD dwFlags = gbMaxPlayers > 1 ? FILE_FLAG_WRITE_THROUGH : 0; + + sgbSaveCreationKey = FALSE; + sghArchive = CreateFile( + pszArchive, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + dwFlags, + NULL + ); + + if (sghArchive == INVALID_HANDLE_VALUE) { + DWORD dwAttr = bHide ? MPQ_HIDE_ATTR : 0; + if (INVALID_HANDLE_VALUE == (sghArchive = CreateFile( + pszArchive, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + dwAttr | dwFlags, + NULL + ))) return FALSE; + sgbSaveCreationKey = TRUE; + sgbChanged = TRUE; + } + + // if the file is still loaded in memory, skip reading file + if (sgpBlockTbl && sgpHashTbl) + return TRUE; + + FULLHEADER fhdr; + ZeroMemory(&fhdr,sizeof(fhdr)); + if (! read_mpq_file_hdr(&fhdr,&sgdwNextFileStart)) + goto error; + + // allocate enough memory for all the blocks we might need + app_assert(! sgpBlockTbl); + sgpBlockTbl = (BLOCKENTRYPTR) DiabloAllocPtrSig(BLOCK_TBL_SIZE,'MPQt'); + ZeroMemory(sgpBlockTbl,BLOCK_TBL_SIZE); + + // read in block table + if (fhdr.hdr.blockcount) { + app_assert(fhdr.hdr.blockcount == BLOCK_ENTRIES); + app_assert(fhdr.hdr.blockoffset == BLOCK_TBL_OFFSET); + if (0xffffffff == SetFilePointer(sghArchive,BLOCK_TBL_OFFSET,NULL,FILE_BEGIN)) + goto error; + if (! ReadFile(sghArchive,sgpBlockTbl,BLOCK_TBL_SIZE,&dwTemp,NULL)) + goto error; + app_assert(BLOCK_TBL_SIZE == dwTemp); + Decrypt( + (LPDWORD) sgpBlockTbl, + BLOCK_TBL_SIZE, + Hash("(block table)", + HASH_ENCRYPTKEY) + ); + } + + // allocate enough memory for hash table + app_assert(! sgpHashTbl); + sgpHashTbl = (HASHENTRYPTR) DiabloAllocPtrSig(HASH_TBL_SIZE,'MPQt'); + FillMemory(sgpHashTbl,HASH_TBL_SIZE,0xff); + + // read in hash table + if (fhdr.hdr.hashcount) { + app_assert(fhdr.hdr.hashcount == HASH_ENTRIES); + app_assert(fhdr.hdr.hashoffset == HASH_TBL_OFFSET); + if (0xffffffff == SetFilePointer(sghArchive,HASH_TBL_OFFSET,NULL,FILE_BEGIN)) + goto error; + if (! ReadFile(sghArchive,sgpHashTbl,HASH_TBL_SIZE,&dwTemp,NULL)) + goto error; + app_assert(HASH_TBL_SIZE == dwTemp); + Decrypt( + (LPDWORD) sgpHashTbl, + HASH_TBL_SIZE, + Hash("(hash table)", + HASH_ENCRYPTKEY) + ); + } + + return TRUE; + +error: + CloseArchive(pszArchive,TRUE,dwChar); + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +BOOL MPQCloseArchive(const char * pszArchive,BOOL bFree,DWORD dwChar) { + // write archive data only if the file open & changed + BOOL bResult; + if (sghArchive == INVALID_HANDLE_VALUE) bResult = TRUE; + else if (! sgbChanged) bResult = TRUE; + else if (! SetEOF()) bResult = FALSE; + else if (! WriteFileHeader()) bResult = FALSE; + else if (! WriteBlockTable()) bResult = FALSE; + else if (! WriteHashTable()) bResult = FALSE; + else bResult = TRUE; + + CloseArchive(pszArchive,bFree,dwChar); + return bResult; +} diff --git a/MPQAPI.H b/MPQAPI.H new file mode 100644 index 0000000..4ad09c9 --- /dev/null +++ b/MPQAPI.H @@ -0,0 +1,85 @@ +//****************************************************************** +// MPQapi.H +// File pack API +// By Michael O'Brien (6/1/96) && Patrick Wyatt (6/24/96) && Dan Liebgold (9/26/96) +//****************************************************************** + + +#ifndef _MPQAPI +#define _MPQAPI + + +// diablo specific +#define MAX_CHARACTERS 10 // saved on disk + + +//****************************************************************** +// constants +//****************************************************************** + #define MPQ_ADD_COMPRESSED 0x00000100 + #define MPQ_ADD_ENCRYPTED 0x00010000 + #define MPQ_ADD_ALLOCATED 0x80000000 + + #define HASH_INDEX 0 + #define HASH_CHECK0 1 + #define HASH_CHECK1 2 + #define HASH_ENCRYPTKEY 3 + #define HASH_ENCRYPTDATA 4 + #define HASH_ENTRY_UNUSED 0xFFFFFFFF + + // possible values for HASHENTRY.block + #define HASH_BLOCK_FREED 0xFFFFFFFE + #define HASH_BLOCK_UNUSED 0xFFFFFFFF + + #define SIGNATURE 0x1A51504D + #define SIGNATURELENGTH 72 + #define VERSION 0 + #define SECTORSIZEID 3 + #define SECTORSIZE (512 << SECTORSIZEID) + + +//****************************************************************** +// structures used in output file +//****************************************************************** + typedef struct _FILEHEADER { + DWORD signature; + DWORD headersize; + DWORD filesize; + WORD version; + WORD sectorsizeid; + DWORD hashoffset; + DWORD blockoffset; + DWORD hashcount; + DWORD blockcount; + } FILEHEADER, *FILEHEADERPTR; + + typedef struct _HASHENTRY { + DWORD hashcheck[2]; + LCID lcid; + DWORD block; + } HASHENTRY, *HASHENTRYPTR; + + typedef struct _BLOCKENTRY { + DWORD offset; + DWORD sizealloc; + DWORD sizefile; + DWORD flags; + } BLOCKENTRY, *BLOCKENTRYPTR; + + + BOOL MPQOpenArchive(const char * pszArchive,BOOL bHide,DWORD dwChar); + BOOL MPQCloseArchive(const char * pszArchive,BOOL bFree,DWORD dwChar); + + typedef BOOL (CALLBACK * TGetNameFcn)(DWORD dwIndex,char szPath[MAX_PATH]); + void MPQDeleteFiles(TGetNameFcn fnGetName); + void MPQDeleteFile(const char * pszName); + BOOL MPQAddFile(const char * pszName,const BYTE * pbData,DWORD dwLen); + void MPQRenameFile(const char * pszOld,const char * pszNew); + BOOL MPQFileExists(const char * pszName); + + BOOL MPQCompareTimeStamps(const char * pszArchive,DWORD dwChar); + void MPQUpdateCreationTimeStamp(const char * pszArchive,DWORD dwChar); + void MPQMungeStamps(DWORD dwChar); + + +#endif diff --git a/MSG.CPP b/MSG.CPP new file mode 100644 index 0000000..48ab911 --- /dev/null +++ b/MSG.CPP @@ -0,0 +1,4246 @@ +//****************************************************************** +// msg.cpp +//****************************************************************** + +/* dig.patch1.start.1/30/97 + Replaced all occurrences of "DObject" with "DObjectStr" + Replaced all occurrences of "DMonster" with "DMonsterStr" + This was done because of a debugger bug. The debugger was + not able to distinguish between the global variable dObject + and the structure name DObject. + The change should have no effect on the executable. + dig.patch1.end.1/30/97 +*/ + +/* PATCH1.JMM + Added extensive logging to the msg handlers. All droplogs do not + compile in non-_DEBUG compiles. +*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "msg.h" +#include "multi.h" +#include "engine.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "monstdat.h" +#include "inv.h" +#include "lighting.h" +#include "objects.h" +#include "objdat.h" +#include "spells.h" +#include "spelldat.h" +#include "control.h" +#include "dead.h" +#include "storm/h/storm.h" +#include "diabloui.h" +#include "cursor.h" +#include "automap.h" +#include "portal.h" +#include "quests.h" +#include "missiles.h" +#include "drlg_l1.h" +#include "trigs.h" +#include "effects.h" + +/*-----------------------------------------------------------------------** +** extern +**-----------------------------------------------------------------------*/ +DWORD Compress(LPBYTE data, DWORD bytes); +void Expand(LPBYTE data, DWORD bytes, DWORD dwMaxBytes); +void M_ClearSquares(int nMonster); +void Obj_Trap(int i); +void StartStand(int pnum, int dir); +void SyncPlrAnim(int p); +void SyncInitPlr(int pnum); +void SendLocalPlayerInfo(int pnum,BYTE bCmd); +void recv_plrinfo(int pnum,const TCmdPlrInfoHdr * p,BOOL bAck); +void dthread_SendPlayerInfoChunk(int pnum,BYTE bCmd,const BYTE * pbSrc,DWORD dwLen); +void plrmsg_add(int pnum,const char * pszStr); +void M_UpdateLeader(int i); +void gamemenu_off(); +void DeleteItem(int ii, int i); +void SyncPortal(int i, BOOL open, int x, int y, int level, int ltype); +void __cdecl sysmsg_add(const char * pszFmt,...); +void NextPlrLevel(int pnum); +void nthread_set_delta_request(); +void NewPlrAnim(int pnum, BYTE *pAnim, int numFrames, int Delay, long width); +void AddWarpMissile(int i, int x, int y); + +// JMM.PATCH1.2.22.97 +void sysmsg_add_string(const char * pszMsg); +// END.JMM.PATCH1.2.22.97 + +void OpenNaKrul(); +void OpenNest(); +void OpenCrypt(); + +/*-----------------------------------------------------------------------** +** public +**-----------------------------------------------------------------------*/ +BOOL deltaload = FALSE; +BYTE gbBufferMsgs = BUFFER_OFF; + + +/*-----------------------------------------------------------------------** +** private +**-----------------------------------------------------------------------*/ +#pragma pack(push,1) + +typedef struct TCmdLoc { + BYTE bCmd; + BYTE x; + BYTE y; +} TCmdLoc; + +typedef struct TCmdLocParam1 { + BYTE bCmd; + BYTE x; + BYTE y; + WORD wParam1; +} TCmdLocParam1; + +typedef struct TCmdLocParam2 { + BYTE bCmd; + BYTE x; + BYTE y; + WORD wParam1; + WORD wParam2; +} TCmdLocParam2; + +typedef struct TCmdLocParam3 { + BYTE bCmd; + BYTE x; + BYTE y; + WORD wParam1; + WORD wParam2; + WORD wParam3; +} TCmdLocParam3; + +typedef struct TCmdParam1 { + BYTE bCmd; + WORD wParam1; +} TCmdParam1; + +typedef struct TCmdParam2 { + BYTE bCmd; + WORD wParam1; + WORD wParam2; +} TCmdParam2; + +typedef struct TCmdParam3 { + BYTE bCmd; + WORD wParam1; + WORD wParam2; + WORD wParam3; +} TCmdParam3; + +typedef struct TCmdString { + BYTE bCmd; + char str[MAX_SEND_STR_LEN]; +} TCmdString; + +typedef struct TCmdGolem { + BYTE bCmd; + BYTE _mx; + BYTE _my; + BYTE _mdir; + BYTE _menemy; + long _mhitpoints; + BYTE _currlevel; +} TCmdGolem; + +typedef struct TCmdQuest { + BYTE bCmd; + BYTE q; + BYTE qstate; + BYTE qlog; + BYTE qvar1; +} TCmdQuest; + +typedef struct TCmdGItem { + BYTE bCmd; + BYTE bMaster; + BYTE bPnum; + BYTE bCursitem; + // drb.patch1.start.2/05/97 + BYTE bLevel; + // drb.patch1.end.2/05/97 + BYTE x; + BYTE y; + WORD wIndx; + WORD wCI; + DWORD dwSeed; + BYTE bId; + BYTE bDur; + BYTE bMDur; + BYTE bCh; + BYTE bMCh; + WORD wValue; + DWORD dwBuff; + DWORD dwTime; + WORD wPLToHit; + WORD wMaxDam; + BYTE bMinStr; + BYTE bMinMag; + BYTE bMinDex; + BYTE bAC; +} TCmdGItem; + +typedef struct TCmdPItem { + BYTE bCmd; + BYTE x; + BYTE y; + WORD wIndx; + WORD wCI; + DWORD dwSeed; + BYTE bId; + BYTE bDur; + BYTE bMDur; + BYTE bCh; + BYTE bMCh; + WORD wValue; + DWORD dwBuff; + WORD wPLToHit; + WORD wMaxDam; + BYTE bMinStr; + BYTE bMinMag; + BYTE bMinDex; + BYTE bAC; +} TCmdPItem; +typedef struct TCmdChItem { + BYTE bCmd; + BYTE bLoc; + WORD wIndx; + WORD wCI; + DWORD dwSeed; + // drb.patch1.start.02/10/97 + BYTE bId; + // drb.patch1.end.02/10/97 +} TCmdChItem; + +typedef struct TCmdDelItem { + BYTE bCmd; + BYTE bLoc; +} TCmdDelItem; + + +typedef struct TCmdDamage{ + BYTE bCmd; + BYTE bPlr; + DWORD dwDam; +} TCmdDamage; + +typedef struct TCmdMonstDamage{ + BYTE bCmd; + WORD wMonst; + DWORD dwDam; +} TCmdMonstDamage; + +typedef struct TFakeCmdPlr { + BYTE bCmd; + BYTE bPlr; +} TFakeCmdPlr; + +typedef struct TFakeDropPlr { + BYTE bCmd; + BYTE bPlr; + DWORD dwReason; +} TFakeDropPlr; +// stuff that is on every level + +typedef struct DMonsterStr { + BYTE _mx; + BYTE _my; + BYTE _mdir; + BYTE _menemy; + BYTE _msquelch; + long _mhitpoints; +} DMonsterStr; + +typedef struct DObjectStr { + BYTE bCmd; +} DObjectStr; + +typedef struct DLevel { + TCmdPItem item[MAXITEMS]; + DObjectStr object[MAXOBJECTS]; + DMonsterStr monster[MAXMONSTERS]; +} DLevel; + +typedef struct LocalLevel { + BYTE automapsv[AUTOMAPX][AUTOMAPY]; +} LocalLevel; + +// stuff which is dungeon global +typedef struct DPortal { + BYTE x; + BYTE y; + BYTE level; + BYTE ltype; + BYTE setlvl; +} DPortal; +typedef struct MultiQuests { + BYTE qstate; + BYTE qlog; + BYTE qvar1; +} MultiQuests; +typedef struct DJunk { + DPortal portal[MAXPORTAL]; + MultiQuests quests[MAXMULTIQUESTS + 1]; +} DJunk; + +#pragma pack(pop) + +#define INIT_VAL 0xff +static DJunk sgJunk; +static DLevel sgLevels[NUMLEVELS]; // sent to other players +static LocalLevel sgLocals[NUMLEVELS]; // not sent + +// number of chunks of info we must receive to get all delta info +// 16 levels + 1 town level = NUMLEVELS +// + 1 global "junk" chunk +// + 1 terminator +// + 1 startup +// + 1 "99%" complete +#define DELTA_CHUNKS (NUMLEVELS+1+1+1+1) + +// allocate extra space to account for flag byte +#define SEND_LEVEL_SIZE (max(sizeof(DLevel),sizeof(DJunk)) + 1) + +// buffer to receive level information +static BYTE sgbRecvLevel[SEND_LEVEL_SIZE]; +static BYTE sgbRecvCmd; +static DWORD sgdwRecvOffset; +static BYTE sgbDeltaChunks; +static BYTE sgbDeltaChanged; +static DWORD sgdwOwnerWait; + + +// item flags which go into sgLevel[].item[].bCmd + // item generated on floor of dungeon -- presently on floor + #define ITEM_GEN_FLOOR 0 + + // item generated on floor of dungeon -- presently not on floor + #define ITEM_GEN_TAKEN 1 + + // item was dropped -- presently on floor + #define ITEM_DROP_FLOOR 2 + + // we don't have to keep track of items which were not originally + // part of the dungeon and were dropped and then picked up + + // item slot not in use + #define ITEM_FREE INIT_VAL + + +//****************************************************************** +//****************************************************************** +// time to keep resending messages if they don't make sense yet +#define RESEND_TIME 5000 // milliseconds + + +//****************************************************************** +// delta buffering +//****************************************************************** +#pragma pack(push,1) + +// this structure contains a whole bunch of link packets +typedef struct TMegaPkt { + struct TMegaPkt * pNext; + DWORD dwSpaceLeft; + BYTE data[32000]; +} TMegaPkt; + +#pragma pack(pop) + +static TMegaPkt * sgpMegaPkt; +static TMegaPkt * sgpCurrPkt; +static int sgnCurrMegaPlayer; + +// PATCH1.JMM +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +DWORD dwRecCount = 0; + +#if _DEBUG +void __cdecl DROPLOG(const char * pszFmt,...) { + extern BOOL gbDumpDropLog; + if (! gbDumpDropLog) return; + static FILE * f = NULL; + if (! f) f = fopen("c:\\droplog.txt","wb"); + if (! f) return; + + va_list args; + va_start(args,pszFmt); + fprintf(f,"(%8.8x,%2.2d):",dwRecCount,numitems); + vfprintf(f,pszFmt,args); + fflush(f); + va_end(args); +} +#else +#define DROPLOG // +#endif +// ENDPATCH1.JMM + + + +//****************************************************************** +//****************************************************************** +static void mega_add_pkt() { + sgpCurrPkt = (TMegaPkt *) DiabloAllocPtrSig(sizeof(TMegaPkt),'MEGA'); + sgpCurrPkt->pNext = NULL; + sgpCurrPkt->dwSpaceLeft = sizeof(sgpCurrPkt->data); + + TMegaPkt ** ppCurr = &sgpMegaPkt; + while (*ppCurr) ppCurr = &(*ppCurr)->pNext; + *ppCurr = sgpCurrPkt; +} + + +//****************************************************************** +//****************************************************************** +static void mega_free_pkts() { + while (sgpMegaPkt) { + sgpCurrPkt = sgpMegaPkt->pNext; + DiabloFreePtr(sgpMegaPkt); + sgpMegaPkt = sgpCurrPkt; + } + + // NOTE: both sgpMegaPkt & sgpCurrPkt are NULL +} + + +//****************************************************************** +//****************************************************************** +static void mega_run_pkts() { + int nPlayer = -1; + for (TMegaPkt * pMega = sgpMegaPkt; pMega; pMega = pMega->pNext) { + const BYTE * pbData = pMega->data; + DWORD dwBytes = sizeof(pMega->data); + while (dwBytes != pMega->dwSpaceLeft) { + if (*pbData == FAKE_CMD_SETID) { + const TFakeCmdPlr * p = (const TFakeCmdPlr *) pbData; + pbData += sizeof(TFakeCmdPlr); + dwBytes -= sizeof(TFakeCmdPlr); + nPlayer = p->bPlr; + } + else if (*pbData == FAKE_CMD_DROPID) { + const TFakeDropPlr * p = (const TFakeDropPlr *) pbData; + pbData += sizeof(TFakeDropPlr); + dwBytes -= sizeof(TFakeDropPlr); + void unbuffer_remove_player(int pnum,DWORD dwReason); + unbuffer_remove_player(p->bPlr,p->dwReason); + } + else { + app_assert((DWORD) nPlayer < MAX_PLRS); + const TCmd * p = (const TCmd *) pbData; + DWORD dwTemp = ParseCmd(nPlayer,p); + pbData += dwTemp; + dwBytes -= dwTemp; + } + } + } +} + + +//****************************************************************** +//****************************************************************** +static void mega_add_data(int pnum,const void * pMsg,DWORD dwLen) { + app_assert((DWORD) pnum < MAX_PLRS); + app_assert(pMsg); + app_assert(dwLen <= gdwLargestMsgSize); + + if (pnum != sgnCurrMegaPlayer) { + // add a command to set the current player + TFakeCmdPlr cmd; + sgnCurrMegaPlayer = pnum; + cmd.bCmd = FAKE_CMD_SETID; + cmd.bPlr = (BYTE) pnum; + mega_add_data(pnum,&cmd,sizeof(cmd)); + } + + // if there isn't enough space in the current megapkt, add another + app_assert(sgpCurrPkt); + if (sgpCurrPkt->dwSpaceLeft < dwLen) + mega_add_pkt(); + app_assert(sgpCurrPkt->dwSpaceLeft >= dwLen); + + // add data to megapacket + CopyMemory( + sgpCurrPkt->data + sizeof(sgpCurrPkt->data) - sgpCurrPkt->dwSpaceLeft, + pMsg, + dwLen + ); + sgpCurrPkt->dwSpaceLeft -= dwLen; +} + + +//****************************************************************** +//****************************************************************** +void buffer_drop_player(int pnum,DWORD dwReason) { + TFakeDropPlr cmd; + cmd.bCmd = FAKE_CMD_DROPID; + cmd.bPlr = (BYTE) pnum; + cmd.dwReason = dwReason; + mega_add_data(pnum,&cmd,sizeof(cmd)); +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start +static int CALLBACK delta_progress() { + if (sgbDeltaChunks == 0) { + // wait until we receive master player's future + // turn before we process our first turn. This is + // designed so that we don't start several turns ahead + // of the master player and stay there forever. We are + // waiting for turn X from all players. We wait for + // turn (X+gdwTurnsInTransit) from the master player, which + // means that the master player processed turn X and has + // sent turns X+1 and X+2. When we process turn X, we will be + // synced with the master player less the one-way packet + // latency from the master player. + DWORD dwTurns; + nthread_fill_sync_queue(0,0); + if (! SNetGetOwnerTurnsWaiting(&dwTurns)) { + if (GetLastError() == SNET_ERROR_NOT_IN_GAME) + return 100; + } + + // wait a maximum of 2 seconds before we give + // up syncing and just try for whatever we can get + // if a turn got dropped by the owner, it is possible + // we could wait forever for the owner, while he waits + // forever for us to resend the dropped turn. + if (GetTickCount() - sgdwOwnerWait <= 2000) { + if (dwTurns < gdwTurnsInTransit) + return 0; + } + + sgbDeltaChunks++; + } + + // handle asynchronous messages + NetReceivePackets(); + + // handle synchronous messages + BOOL bSendAsync; + nthread_fill_sync_queue(0,0); + // pjw.patch2.start -- if we call nthread_msg_check() without + // protection against "overcalling" then the gameclock will get + // continually reset and other systems will drop into timeout mode + // nthread_msg_check(&bSendAsync); + if (nthread_run_gameloop(FALSE)) nthread_msg_check(&bSendAsync); + // pjw.patch2.end + + // if the game was destroyed, return "100% complete" to exit dialog + if (gbGameDestroyed) return 100; + + // if the person sending us delta info dropped out, + // then we need to re-request the delta information + if (gbDeltaSender >= MAX_PLRS) { + sgbRecvCmd = CMD_DLEVEL_END; + sgbDeltaChunks = 0; + gbDeltaSender = (BYTE) myplr; + nthread_set_delta_request(); + } + + // make bar "full" + if (sgbDeltaChunks == DELTA_CHUNKS - 1) { + sgbDeltaChunks++; + return 99; + } + + // return completion status + return (sgbDeltaChunks * 100) / DELTA_CHUNKS; +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +BOOL wait_delta_info() { + app_assert(ghMainWnd); + app_assert(! sgpMegaPkt); + app_assert(! sgpCurrPkt); + mega_add_pkt(); + + sgbRecvCmd = CMD_DLEVEL_END; + sgbDeltaChunks = 0; + gbBufferMsgs = BUFFER_ON; + sgnCurrMegaPlayer = -1; + sgdwOwnerWait = GetTickCount(); + + BOOL bResult = UiProgressDialog( + ghMainWnd, + "Waiting for game data...", + TRUE, // allow abort + delta_progress, + GAME_FRAMES_PER_SECOND // calls per second + ); + + // done buffering messages, but don't go into BUFFER_PROCESS + // mode until we've successfully loaded the level + gbBufferMsgs = BUFFER_OFF; + + if (! bResult) { + // no message -- user canceled + mega_free_pkts(); + return FALSE; + } + else if (gbGameDestroyed) { + app_warning("The game ended"); + mega_free_pkts(); + return FALSE; + } + else if (sgbDeltaChunks != DELTA_CHUNKS) { + app_warning("Unable to get level data"); + mega_free_pkts(); + return FALSE; + } + + // leave the delta information around + // until the game level has been loaded + // and then run all the accumulated packets + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +void run_delta_info() { + if (gbMaxPlayers == 1) return; + + app_assert(currlevel == 0); + app_assert(plr[myplr].plrlevel == 0); + + gbBufferMsgs = BUFFER_PROCESS; + mega_run_pkts(); + gbBufferMsgs = BUFFER_OFF; + + mega_free_pkts(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BYTE * dbuild_items(BYTE * pbData,const TCmdPItem * pItem) { + for (int i = 0; i < MAXITEMS; i++,pItem++) { + if (pItem->bCmd == INIT_VAL) { + *pbData++ = INIT_VAL; + } + else { + //CopyMemory(pbData,pItem,sizeof(TCmdPItem)); + *(reinterpret_cast(pbData)) = *pItem; + pbData += sizeof(TCmdPItem); + } + } + + return pbData; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static const BYTE * dparse_items(const BYTE * pbData,TCmdPItem * pItem) { + for (int i = 0; i < MAXITEMS; i++,pItem++) { + if (*pbData == INIT_VAL) { + FillMemory(pItem,sizeof(TCmdPItem),INIT_VAL); + pbData++; + } + else { + //CopyMemory(pItem,pbData,sizeof(TCmdPItem)); + *pItem = *(reinterpret_cast(pbData)); + pbData += sizeof(TCmdPItem); + } + } + + return pbData; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BYTE * dbuild_objects(BYTE * pbData,const DObjectStr * pObj) { + // the object structure is only one byte, so just + // rely upon data compression to make it smaller + CopyMemory(pbData,pObj,MAXOBJECTS * sizeof(DObjectStr)); + return pbData + MAXOBJECTS * sizeof(DObjectStr); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static const BYTE * dparse_objects(const BYTE * pbData,DObjectStr * pObj) { + // the object structure is only one byte, so just + // rely upon data compression to make it smaller + CopyMemory(pObj,pbData,MAXOBJECTS * sizeof(DObjectStr)); + return pbData + MAXOBJECTS * sizeof(DObjectStr); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BYTE * dbuild_monsters(BYTE * pbData,const DMonsterStr * pM) { + for (int m = 0; m < MAXMONSTERS; m++,pM++) { + if (pM->_mx == INIT_VAL) { + *pbData++ = INIT_VAL; + } + else { + //CopyMemory(pbData,pM,sizeof(DMonsterStr)); + *(reinterpret_cast(pbData)) = *pM; + pbData += sizeof(DMonsterStr); + } + } + + return pbData; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static const BYTE * dparse_monsters(const BYTE * pbData,DMonsterStr * pM) { + for (int m = 0; m < MAXMONSTERS; m++,pM++) { + if (*pbData == INIT_VAL) { + FillMemory(pM,sizeof(DMonsterStr),INIT_VAL); + pbData++; + } + else { + //CopyMemory(pM,pbData,sizeof(DMonsterStr)); + *pM = *(reinterpret_cast (pbData)); + pbData += sizeof(DMonsterStr); + } + } + + return pbData; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +extern QuestData questlist[]; + +static BYTE * dbuild_junk(BYTE * pbData) { + for (int i = 0; i < MAXPORTAL; i++) { + if (sgJunk.portal[i].x == INIT_VAL) { + *pbData++ = INIT_VAL; + } + else { + //CopyMemory(pbData,&sgJunk.portal[i],sizeof(DPortal)); + *(reinterpret_cast(pbData)) = sgJunk.portal[i]; + pbData += sizeof(DPortal); + } + } + i = 0; + for (int q = 0; q < MAXQUESTS; q++) { + if (questlist[q]._qflags & QFLAG_MULTI) { + sgJunk.quests[i].qlog = quests[q]._qlog; + sgJunk.quests[i].qstate = quests[q]._qactive; + sgJunk.quests[i].qvar1 = quests[q]._qvar1; + //CopyMemory(pbData,&sgJunk.quests[i],sizeof(MultiQuests)); + *(reinterpret_cast(pbData)) = sgJunk.quests[i]; + pbData += sizeof(MultiQuests); + i++; + } + } + + return pbData; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void dparse_junk(const BYTE * pbData) { + int i; + for (i = 0; i < MAXPORTAL; i++) { + if (*pbData == INIT_VAL) { + FillMemory(&sgJunk.portal[i],sizeof(DPortal),INIT_VAL); + pbData++; + SyncPortal(i, FALSE, 0, 0, 0, 0); + } + else { + //CopyMemory(&sgJunk.portal[i],pbData,sizeof(DPortal)); + sgJunk.portal[i] = *(reinterpret_cast(pbData)); + pbData += sizeof(DPortal); + SyncPortal(i, TRUE, sgJunk.portal[i].x, sgJunk.portal[i].y, sgJunk.portal[i].level, sgJunk.portal[i].ltype); + } + } + i = 0; + for (int q = 0; q < MAXQUESTS; q++) { + if (questlist[q]._qflags & QFLAG_MULTI) { + //CopyMemory(&sgJunk.quests[i],pbData,sizeof(MultiQuests)); + sgJunk.quests[i] = *(reinterpret_cast(pbData)); + pbData += sizeof(MultiQuests); + quests[q]._qlog = sgJunk.quests[i].qlog; + quests[q]._qactive = sgJunk.quests[i].qstate; + quests[q]._qvar1 = sgJunk.quests[i].qvar1; + i++; + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD compress_chunk(BYTE * pbStart,BYTE * pbEnd) { + // calculate length excluding leading byte + DWORD dwLen = pbEnd - pbStart - 1; + + // compress data excluding leading byte + DWORD dwBytes = Compress(pbStart + 1,dwLen); + + // set compress flag ==> TRUE = compressed + *pbStart = (dwLen != dwBytes); + + // add one extra byte for compress flag + return dwBytes + 1; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DeltaSendAllLevels(int pnum) { + // send all delta information to player pnum + if (sgbDeltaChanged) { + BYTE * pbData; + DWORD dwBytes; + BYTE * pbBase = (BYTE *) DiabloAllocPtrSig(SEND_LEVEL_SIZE,'DLTt'); + for (int bLevel = 0; bLevel < NUMLEVELS; bLevel++) { + // save 1 byte for compress/uncompress flag + pbData = pbBase + 1; + + // build level data + pbData = dbuild_items(pbData,&sgLevels[bLevel].item[0]); + pbData = dbuild_objects(pbData,&sgLevels[bLevel].object[0]); + pbData = dbuild_monsters(pbData,&sgLevels[bLevel].monster[0]); + dwBytes = compress_chunk(pbBase,pbData); + dthread_SendPlayerInfoChunk(pnum,CMD_DLEVEL_0 + bLevel,pbBase,dwBytes); + } + + // send junk chunk -- save one byte for compress/uncompress flag + pbData = dbuild_junk(pbBase + 1); + dwBytes = compress_chunk(pbBase,pbData); + dthread_SendPlayerInfoChunk(pnum,CMD_DLEVEL_JUNK,pbBase,dwBytes); + DiabloFreePtr(pbBase); + } + + // send 1 byte terminator chunk + BYTE c = 0; // mark as "uncompressed" + dthread_SendPlayerInfoChunk(pnum,CMD_DLEVEL_END,&c,1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void dparse_chunk(BYTE bMsg,DWORD dwLen) { + // first byte is a flag which indicates whether the data is compressed + if (sgbRecvLevel[0]) Expand(&sgbRecvLevel[1],dwLen,sizeof(sgbRecvLevel) - 1); + const BYTE * pbData = &sgbRecvLevel[1]; + + if (bMsg == CMD_DLEVEL_JUNK) { + dparse_junk(pbData); + } + else if (bMsg >= CMD_DLEVEL_0 && bMsg <= CMD_DLEVEL_24) { + BYTE bLevel = bMsg - CMD_DLEVEL_0; + pbData = dparse_items(pbData,&sgLevels[bLevel].item[0]); + pbData = dparse_objects(pbData,&sgLevels[bLevel].object[0]); + pbData = dparse_monsters(pbData,&sgLevels[bLevel].monster[0]); + } + else { + app_fatal("msg:1"); + } + + sgbDeltaChanged = TRUE; + sgbDeltaChunks++; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD dreceive_chunk(int pnum,const TCmdPlrInfoHdr * p) { + + if (gbDeltaSender != pnum) { + // we are unexpectedly receiving delta info from somebody + // if they aren't sending us the starting information, ignore it + // otherwise, make them the new delta source + if (p->bCmd == CMD_DLEVEL_END) { + // we're getting an end chunk without any intervening delta + // which means there is no delta information + } + else if (p->bCmd != CMD_DLEVEL_0 || p->wOffset != 0) { + return p->wBytes + sizeof(TCmdPlrInfoHdr); + } + gbDeltaSender = (BYTE) pnum; + sgbRecvCmd = CMD_DLEVEL_END; + } + + if (sgbRecvCmd == CMD_DLEVEL_END) { + if (p->bCmd == CMD_DLEVEL_END) { + // we received the end command immediately, which + // means there was no level delta info + sgbDeltaChunks = DELTA_CHUNKS - 1; // set 99% done + return p->wBytes + sizeof(TCmdPlrInfoHdr); + } + + if (p->bCmd != CMD_DLEVEL_0 || p->wOffset != 0) { + // someone is in the middle of sending us info + // but we don't have the beginning + // just ignore the message + return p->wBytes + sizeof(TCmdPlrInfoHdr); + } + + // we just started receiving new data from the player + sgdwRecvOffset = 0; + sgbRecvCmd = p->bCmd; + } + else if (sgbRecvCmd != p->bCmd) { + // since we are receiving a new delta chunk, + // we must have finished receiving the last delta chunk. + // process last chunk before handling next chunk. + // ???dparse_chunk(sgbRecvCmd,sgdwRecvOffset + p->wBytes); + dparse_chunk(sgbRecvCmd,sgdwRecvOffset); + + // what's the new command? + if (p->bCmd == CMD_DLEVEL_END) { + // set 99% done flag + sgbDeltaChunks = DELTA_CHUNKS - 1; + sgbRecvCmd = CMD_DLEVEL_END; + return p->wBytes + sizeof(TCmdPlrInfoHdr); + } + + sgdwRecvOffset = 0; + sgbRecvCmd = p->bCmd; + } + + app_assert(p->wOffset == sgdwRecvOffset); + CopyMemory( &sgbRecvLevel[p->wOffset], + ((BYTE *)p) + sizeof(TCmdPlrInfoHdr), + p->wBytes + ); + + sgdwRecvOffset += p->wBytes; + return p->wBytes + sizeof(TCmdPlrInfoHdr); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void delta_init() { + sgbDeltaChanged = FALSE; + FillMemory(&sgJunk,sizeof sgJunk,INIT_VAL); + FillMemory(&sgLevels[0],sizeof sgLevels,INIT_VAL); + ZeroMemory(sgLocals,sizeof sgLocals); + deltaload = FALSE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel) { + if (gbMaxPlayers == 1) return; + app_assert((DWORD)mi < MAXMONSTERS); + app_assert(x < DMAXX); + app_assert(y < DMAXY); + app_assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = TRUE; + DMonsterStr * p = &sgLevels[bLevel].monster[mi]; + p->_mx = x; + p->_my = y; + p->_mdir = monster[mi]._mdir; + p->_mhitpoints = 0; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void delta_monster_hp(int mi,long hp,BYTE bLevel) { + if (gbMaxPlayers == 1) return; + app_assert((DWORD)mi < MAXMONSTERS); + app_assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = TRUE; + DMonsterStr * p = &sgLevels[bLevel].monster[mi]; + if (p->_mhitpoints > hp) p->_mhitpoints = hp; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void delta_sync_monster(const TSyncMonster * pSync,BYTE bLevel) { + if (gbMaxPlayers == 1) return; + app_assert(pSync != NULL); + app_assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = TRUE; + DMonsterStr * pD = &sgLevels[bLevel].monster[pSync->_mndx]; + + // is this monster already dead? + if (! pD->_mhitpoints) return; + + pD->_mx = pSync->_mx; + pD->_my = pSync->_my; + pD->_msquelch = 255; + + //app_assert((DWORD) pSync->_menemy < MAX_PLRS); @@@ Taken out becasue monster enemy could be a monster + pD->_menemy = pSync->_menemy; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void delta_sync_golem(const TCmdGolem * pG, int pnum, BYTE bLevel) { + if (gbMaxPlayers == 1) return; + + app_assert(bLevel < NUMLEVELS); + app_assert(bLevel != 0); + + sgbDeltaChanged = TRUE; + DMonsterStr * pD = &sgLevels[bLevel].monster[pnum]; + + pD->_mx = pG->_mx; + pD->_my = pG->_my; + pD->_msquelch = 255; + pD->_menemy = pG->_menemy; + pD->_mdir = pG->_mdir; + pD->_mhitpoints = pG->_mhitpoints; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void delta_leave_sync(BYTE bLevel) { + if (gbMaxPlayers == 1) return; + + // recycle town store seeds + if (currlevel == 0) glSeedTbl[0] = GetRndSeed(); + if (currlevel <= 0) return; + app_assert(bLevel < NUMLEVELS); + + for (int i = 0; i < nummonsters; i++) { + int ii = monstactive[i]; + if (monster[ii]._mhitpoints == 0) continue; + + sgbDeltaChanged = TRUE; + DMonsterStr * pD = &sgLevels[bLevel].monster[ii]; + pD->_mx = monster[ii]._mx; + pD->_my = monster[ii]._my; + pD->_mdir = monster[ii]._mdir; + pD->_menemy = encode_enemy(ii); + //app_assert((DWORD) pD->_menemy < MAX_PLRS); + pD->_mhitpoints = monster[ii]._mhitpoints; + pD->_msquelch = monster[ii]._msquelch; + } + + // copy automap + app_assert(sizeof(sgLocals[bLevel].automapsv) == sizeof(automapview)); + CopyMemory( + &sgLocals[bLevel].automapsv[0][0], + &automapview[0][0], + sizeof(sgLocals[bLevel].automapsv) + ); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void delta_sync_object(int oi,BYTE bCmd,BYTE bLevel) { + if (gbMaxPlayers == 1) return; + app_assert((DWORD)oi < MAXOBJECTS); + app_assert(bLevel < NUMLEVELS); + + sgbDeltaChanged = TRUE; + DObjectStr * p = &sgLevels[bLevel].object[oi]; + p->bCmd = bCmd; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL delta_get_item(const TCmdGItem * pI, BYTE bLevel) { + if (gbMaxPlayers == 1) return(TRUE); + app_assert(pI != NULL); + app_assert(bLevel < NUMLEVELS); + + TCmdPItem * pD = &sgLevels[bLevel].item[0]; + for (int i = 0; i < MAXITEMS; i++,pD++) { + + // find item + if (pD->bCmd == ITEM_FREE) continue; + if (pD->wIndx != pI->wIndx) continue; + if (pD->wCI != pI->wCI) continue; + if (pD->dwSeed != pI->dwSeed) continue; + + if (pD->bCmd == ITEM_GEN_TAKEN) { + // PATCH1.JMM + DROPLOG(" delta_get_item: item already picked up?!\n"); + // ENDPATCH1.JMM + // someone else already picked it up?! + return(TRUE); + } + else if (pD->bCmd == ITEM_GEN_FLOOR) { + // pick item up from floor, but keep track + // of the fact that it is a generated item + // PATCH1.JMM + DROPLOG(" delta_get_item: native item picked up from floor\n"); + // ENDPATCH1.JMM + + sgbDeltaChanged = TRUE; + pD->bCmd = ITEM_GEN_TAKEN; + return(TRUE); + } + else if (pD->bCmd == ITEM_DROP_FLOOR) { + // since the item was dropped on the floor but + // not part of the generated dungeon, as soon + // as it is picked up we can forget about it + // PATCH1.JMM + DROPLOG(" delta_get_item: foreign item picked up from floor\n"); + // ENDPATCH1.JMM + + sgbDeltaChanged = TRUE; + pD->bCmd = ITEM_FREE; + return(TRUE); + } + else { + app_fatal("delta:1"); + } + break; + } + + + // PATCH1.JMM + DROPLOG(" delta_get_item: item not found\n"); + // ENDPATCH1.JMM + // If we are trying to remove an item from the delta list and it is not a dungeon + // pregenerated item, then forget it. Chances are that it was a message sent and + // buffered before the level delta was passed to us. So the level delta has the + // change in it already and we are processing the buffered message which is just + // duplicating what is already there. + // The above is true, or it could be we are processing the pickup before the drop + // so, we will be resending this message to ourselves + if (!(pI->wCI & ICI_PREGEN)) + return(FALSE); + + //app_assert(bLevel > 0); + // If not found, then an item generated by a level that I have not been to yet + pD = &sgLevels[bLevel].item[0]; + for (i = 0; i < MAXITEMS; i++,pD++) { + + // Free slot? + if (pD->bCmd != ITEM_FREE) continue; + + // put the item into the delta table + // PATCH1.JMM + DROPLOG(" delta_get_item: added item to delta tbl"); + // ENDPATCH1.JMM + + sgbDeltaChanged = TRUE; + pD->bCmd = ITEM_GEN_TAKEN; + pD->x = pI->x; + pD->y = pI->y; + pD->wIndx = pI->wIndx; + pD->wCI = pI->wCI; + pD->dwSeed = pI->dwSeed; + pD->bId = pI->bId; + pD->bDur = pI->bDur; + pD->bMDur = pI->bMDur; + pD->bCh = pI->bCh; + pD->bMCh = pI->bMCh; + pD->wValue = pI->wValue; + pD->dwBuff = pI->dwBuff; + pD->wPLToHit = pI->wPLToHit; + pD->wMaxDam = pI->wMaxDam; + pD->bMinStr = pI->bMinStr; + pD->bMinMag = pI->bMinMag; + pD->bMinDex = pI->bMinDex; + pD->bAC = pI->bAC; + return(TRUE); + } + // PATCH1.JMM + DROPLOG(" delta_get_item: could not add item to delta tbl"); + // ENDPATCH1.JMM + return(TRUE); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void delta_put_item(const TCmdPItem * pI, int x, int y, BYTE bLevel) { + if (gbMaxPlayers == 1) return; + app_assert(pI != NULL); + app_assert(x < DMAXX); + app_assert(y < DMAXY); + app_assert(bLevel < NUMLEVELS); + + // see if the item was already part of the generated dungeon + TCmdPItem * pD = &sgLevels[bLevel].item[0]; + for (int i = 0; i < MAXITEMS; i++,pD++) { + if (pD->bCmd == ITEM_GEN_TAKEN) continue; + if (pD->bCmd == ITEM_FREE) continue; + if (pD->wIndx != pI->wIndx) continue; + if (pD->wCI != pI->wCI) continue; + if (pD->dwSeed != pI->dwSeed) continue; + + // Already placed? + if (pD->bCmd == ITEM_DROP_FLOOR) { + return; + } + + app_fatal("Trying to drop a floor item?"); + } + + // find a location to drop this item + pD = &sgLevels[bLevel].item[0]; + for (i = 0; i < MAXITEMS; i++,pD++) { + if (pD->bCmd != ITEM_FREE) continue; + + // put the item back onto the floor at its + // new location and with its new state + + sgbDeltaChanged = TRUE; + //CopyMemory(pD,pI,sizeof(TCmdPItem)); + *pD = *pI; // struct copy. + pD->bCmd = ITEM_DROP_FLOOR; + pD->x = x; + pD->y = y; + return; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL delta_portal_inited(int i) +{ + app_assert((DWORD)i < MAXPORTAL); + if (sgJunk.portal[i].x == INIT_VAL) return(TRUE); + else return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL delta_quest_inited(int i) +{ + app_assert((DWORD)i <= MAXMULTIQUESTS); + if (sgJunk.quests[i].qstate == INIT_VAL) return(FALSE); + else return(TRUE); +} + +/*-----------------------------------------------------------------------** +** Called when level creating +**-----------------------------------------------------------------------*/ +void DeltaAddItem(int ii) { + if (gbMaxPlayers == 1) return; + app_assert((DWORD)ii < MAXITEMS); + + // Already in delta? + TCmdPItem * pD = &sgLevels[currlevel].item[0]; + for (int i = 0; i < MAXITEMS; i++,pD++) { + if (pD->bCmd == ITEM_FREE) continue; + if (pD->wIndx != item[ii].IDidx) continue; + if (pD->wCI != item[ii]._iCreateInfo) continue; + if (pD->dwSeed != (DWORD)item[ii]._iSeed) continue; + + // taken? + if (pD->bCmd == ITEM_GEN_TAKEN) return; + // 2nd time down? + if (pD->bCmd == ITEM_GEN_FLOOR) return; + } + + + // find a location to drop this item + pD = &sgLevels[currlevel].item[0]; + for (i = 0; i < MAXITEMS; i++,pD++) { + if (pD->bCmd != ITEM_FREE) continue; + + // put the item back onto the floor at its + // new location and with its new state + + sgbDeltaChanged = TRUE; + pD->bCmd = ITEM_GEN_FLOOR; + pD->x = item[ii]._ix; + pD->y = item[ii]._iy; + pD->wIndx = item[ii].IDidx; + pD->wCI = item[ii]._iCreateInfo; + pD->dwSeed = item[ii]._iSeed; + pD->bId = item[ii]._iIdentified; + pD->bDur = item[ii]._iDurability; + pD->bMDur = item[ii]._iMaxDur; + pD->bCh = item[ii]._iCharges; + pD->bMCh = item[ii]._iMaxCharges; + pD->wValue = item[ii]._ivalue; + pD->wPLToHit = item[ii]._iPLToHit; + pD->wMaxDam = item[ii]._iMaxDam; + pD->bMinStr = item[ii]._iMinStr; + pD->bMinMag = item[ii]._iMinMag; + pD->bMinDex = item[ii]._iMinDex; + pD->bAC = item[ii]._iAC; + return; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DeltaSaveLevel() { + if (gbMaxPlayers == 1) return; + + // throw away everyone else's graphics, they + // are probably out of date anyway + for (int i = 0; i < MAX_PLRS; i++) + if (i != myplr) plr[i]._pGFXLoad = 0; + + app_assert((DWORD) currlevel < NUMLEVELS); + plr[myplr]._pLvlVisited[currlevel] = TRUE; + delta_leave_sync(currlevel); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +// PATCH1.JMM +BOOL CanPut(int i, int j); +// ENDPATCH1.JMM + + +void DeltaLoadLevel() { + if (gbMaxPlayers == 1) return; + + int i, ii; + + deltaload = TRUE; + + // don't do the monster stuff for level 0, that is the town! + if (currlevel != 0) { + for (i = 0; i < nummonsters; i++) { + if (sgLevels[currlevel].monster[i]._mx == INIT_VAL) continue; + M_ClearSquares(i); + monster[i]._mx = sgLevels[currlevel].monster[i]._mx; + monster[i]._my = sgLevels[currlevel].monster[i]._my; + monster[i]._moldx = monster[i]._mx; + monster[i]._moldy = monster[i]._my; + monster[i]._mfutx = monster[i]._mx; + monster[i]._mfuty = monster[i]._my; + if (sgLevels[currlevel].monster[i]._mhitpoints != -1) + monster[i]._mhitpoints = sgLevels[currlevel].monster[i]._mhitpoints; + // Is monster dead? + if (sgLevels[currlevel].monster[i]._mhitpoints == 0) { + monster[i]._moldx = sgLevels[currlevel].monster[i]._mx; + monster[i]._moldy = sgLevels[currlevel].monster[i]._my; + M_ClearSquares(i); + if (monster[i]._mAi != AI_DIABLO) { // Diablo has no death frame + if (monster[i]._uniqtype == 0) { + app_assert(monster[i].MType != NULL); + AddDead(monster[i]._mx, monster[i]._my, monster[i].MType->mdeadval, monster[i]._mdir); + } else { + AddDead(monster[i]._mx, monster[i]._my, monster[i]._udeadval, monster[i]._mdir); + } + } + monster[i]._mDelFlag = TRUE; + M_UpdateLeader(i); + } else { + int enemy = sgLevels[currlevel].monster[i]._menemy; + //app_assert((DWORD) enemy < MAX_PLRS); + decode_enemy(i, enemy); + if (((monster[i]._mx != 0) && (monster[i]._mx != 1)) || (monster[i]._my != 0)) dMonster[monster[i]._mx][monster[i]._my] = i + 1; + if (i < 4) { + MAI_Golum(i); + monster[i]._mFlags |= MFLAG_MID; + monster[i]._mFlags |= MFLAG_MKILLER; + } else M_StartStand(i, monster[i]._mdir); + monster[i]._msquelch = sgLevels[currlevel].monster[i]._msquelch; + } + } + + // copy automap + app_assert(sizeof(sgLocals[currlevel].automapsv) == sizeof(automapview)); + CopyMemory( + &automapview[0][0], + &sgLocals[currlevel].automapsv[0][0], + sizeof(automapview) + ); + } + + for (i = 0; i < MAXITEMS; i++) { + if (sgLevels[currlevel].item[i].bCmd == ITEM_FREE) continue; + if (sgLevels[currlevel].item[i].bCmd == ITEM_GEN_TAKEN) { + ii = FindGetItem(sgLevels[currlevel].item[i].wIndx, + sgLevels[currlevel].item[i].wCI, + sgLevels[currlevel].item[i].dwSeed); + if (ii != -1) { + if (dItem[item[ii]._ix][item[ii]._iy] == (ii+1)) dItem[item[ii]._ix][item[ii]._iy] = 0; + DeleteItem(ii, i); + } + } + if (sgLevels[currlevel].item[i].bCmd == ITEM_DROP_FLOOR) { + ii = itemavail[0]; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + if (sgLevels[currlevel].item[i].wIndx == IDI_EAR) { + RecreateEar(ii, + sgLevels[currlevel].item[i].wCI, + sgLevels[currlevel].item[i].dwSeed, + sgLevels[currlevel].item[i].bId, + sgLevels[currlevel].item[i].bDur, + sgLevels[currlevel].item[i].bMDur, + sgLevels[currlevel].item[i].bCh, + sgLevels[currlevel].item[i].bMCh, + sgLevels[currlevel].item[i].wValue, + sgLevels[currlevel].item[i].dwBuff); + } else { + RecreateItem(ii, + sgLevels[currlevel].item[i].wIndx, + sgLevels[currlevel].item[i].wCI, + sgLevels[currlevel].item[i].dwSeed, + sgLevels[currlevel].item[i].wValue); + if (sgLevels[currlevel].item[i].bId) item[ii]._iIdentified = TRUE; + item[ii]._iDurability = sgLevels[currlevel].item[i].bDur; + item[ii]._iMaxDur = sgLevels[currlevel].item[i].bMDur; + item[ii]._iCharges = sgLevels[currlevel].item[i].bCh; + item[ii]._iMaxCharges = sgLevels[currlevel].item[i].bMCh; + item[ii]._iPLToHit = sgLevels[currlevel].item[i].wPLToHit; + item[ii]._iMaxDam = sgLevels[currlevel].item[i].wMaxDam; + item[ii]._iMinStr = sgLevels[currlevel].item[i].bMinStr; + item[ii]._iMinMag = sgLevels[currlevel].item[i].bMinMag; + item[ii]._iMinDex = sgLevels[currlevel].item[i].bMinDex; + item[ii]._iAC = sgLevels[currlevel].item[i].bAC; + } + + int ox = sgLevels[currlevel].item[i].x; + int oy = sgLevels[currlevel].item[i].y; + + // PATCH1.JMM + if (!CanPut(ox,oy)) { + BOOL done = FALSE; + // radial search outward until a space is found + for (int l = 1; (l < 50) && !done; l++) { + for (int j = -l; (j <= l) && !done; j++) { + int yy = oy + j; + for (int i = -l; (i <= l) && !done; i++) { + int xx = ox + i; + if (!CanPut(xx,yy)) continue; + done = TRUE; + DROPLOG(" DeltaLoadLevel: moving object from (x,y)->(%2.2x,%2.2x) to (x,y)->(%2.2x,%2.2x)!\n",ox,oy,xx,yy); + ox = xx; + oy = yy; + } + } + } + + app_assert(done); + } + // ENDPATCH1.JMM + + + item[ii]._ix = ox; + item[ii]._iy = oy; + dItem[item[ii]._ix][item[ii]._iy] = ii+1; + // PATCH1.JMM + DROPLOG(" DeltaLoadLevel: respawning %d (%4.4x,%4.4x,%8.8x) @ (x,y)->(%2.2x,%2.2x)\n",ii,item[ii]._itype,item[ii]._iCreateInfo,item[ii]._iSeed,item[ii]._ix,item[ii]._iy); + // ENDPATCH1.JMM + RespawnItem(ii, FALSE); + numitems++; + } + } + + if (currlevel != 0) { + for (i = 0; i < MAXOBJECTS; i++) { + switch (sgLevels[currlevel].object[i].bCmd) { + case INIT_VAL: + // no object + break; + + case CMD_OPENDOOR: + case CMD_CLOSEDOOR: + case CMD_OPERATEOBJ: + case CMD_PLROPOBJ: + SyncOpObject(-1, sgLevels[currlevel].object[i].bCmd, i); + break; + + case CMD_BREAKOBJ: + SyncBreakObj(-1, i); + break; + } + } + for (i = 0; i < numobjects; i++) { + ii = objectactive[i]; + if ((object[ii]._otype == OBJ_TRAPL) || (object[ii]._otype == OBJ_TRAPR)) Obj_Trap(ii); + } + } + + deltaload = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmd(BOOL bHiPri,BYTE bCmd) { + TCmd cmd; + cmd.bCmd = bCmd; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdGolem(BYTE mx, BYTE my, BYTE dir, BYTE menemy, long hp, BYTE cl) { + app_assert(mx < DMAXX); + app_assert(my < DMAXY); + + TCmdGolem cmd; + + cmd.bCmd = CMD_AWAKEGOLEM; + cmd._mx = mx; + cmd._my = my; + cmd._mdir = dir; + cmd._menemy = menemy; + cmd._mhitpoints = hp; + cmd._currlevel = cl; + + NetSendLoPri((BYTE *) &cmd, sizeof(cmd)); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdLoc(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y) { + app_assert(x < DMAXX); + app_assert(y < DMAXY); + TCmdLoc cmd; + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdLocParam1(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1) { + app_assert(x < DMAXX); + app_assert(y < DMAXY); + TCmdLocParam1 cmd; + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdLocParam2(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1,WORD wParam2) { + app_assert(x < DMAXX); + app_assert(y < DMAXY); + TCmdLocParam2 cmd; + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdLocParam3(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1,WORD wParam2,WORD wParam3) { + app_assert(x < DMAXX); + app_assert(y < DMAXY); + TCmdLocParam3 cmd; + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + cmd.wParam3 = wParam3; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdParam1(BOOL bHiPri,BYTE bCmd,WORD wParam1) { + TCmdParam1 cmd; + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdParam2(BOOL bHiPri,BYTE bCmd,WORD wParam1,WORD wParam2) { + TCmdParam2 cmd; + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdParam3(BOOL bHiPri,BYTE bCmd,WORD wParam1,WORD wParam2, WORD wParam3) { + TCmdParam3 cmd; + cmd.bCmd = bCmd; + cmd.wParam1 = wParam1; + cmd.wParam2 = wParam2; + cmd.wParam3 = wParam3; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdQuest(BOOL bHiPri,BYTE q) { + TCmdQuest cmd; + cmd.bCmd = CMD_SYNCQUEST; + cmd.q = q; + cmd.qstate = quests[q]._qactive; + cmd.qlog = quests[q]._qlog; + cmd.qvar1 = quests[q]._qvar1; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdGItem(BOOL bHiPri,BYTE bCmd,BYTE mast,BYTE pnum,BYTE ii) { + app_assert(ii < MAXITEMS); + app_assert(pnum < MAX_PLRS); + + TCmdGItem cmd; + cmd.bCmd = bCmd; + cmd.bPnum = pnum; + cmd.bMaster = mast; + cmd.dwTime = 0; + cmd.bLevel = currlevel; + cmd.bCursitem = ii; + cmd.x = item[ii]._ix; + cmd.y = item[ii]._iy; + cmd.wIndx = item[ii].IDidx; + if (item[ii].IDidx == IDI_EAR) { + cmd.wCI = (item[ii]._iName[7] << 8) | item[ii]._iName[8]; + cmd.dwSeed = (item[ii]._iName[9] << 24) | + (item[ii]._iName[10] << 16) | + (item[ii]._iName[11] << 8) | + item[ii]._iName[12]; + cmd.bId = item[ii]._iName[13]; + cmd.bDur = item[ii]._iName[14]; + cmd.bMDur = item[ii]._iName[15]; + cmd.bCh = item[ii]._iName[16]; + cmd.bMCh = item[ii]._iName[17]; + cmd.wValue = (item[ii]._iName[18] << 8) | ((item[ii]._iCurs - ITEM_EAR1) << 6) | item[ii]._ivalue; + cmd.dwBuff = (item[ii]._iName[19] << 24) | + (item[ii]._iName[20] << 16) | + (item[ii]._iName[21] << 8) | + item[ii]._iName[22]; + } else { + cmd.wCI = item[ii]._iCreateInfo; + cmd.dwSeed = item[ii]._iSeed; + cmd.bId = item[ii]._iIdentified; + cmd.bDur = item[ii]._iDurability; + cmd.bMDur = item[ii]._iMaxDur; + cmd.bCh = item[ii]._iCharges; + cmd.bMCh = item[ii]._iMaxCharges; + cmd.wValue = item[ii]._ivalue; + cmd.wPLToHit = item[ii]._iPLToHit; + cmd.wMaxDam = item[ii]._iMaxDam; + cmd.bMinStr = item[ii]._iMinStr; + cmd.bMinMag = item[ii]._iMinMag; + cmd.bMinDex = item[ii]._iMinDex; + cmd.bAC = item[ii]._iAC; + } + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void NetSendCmdGItem2(BOOL usonly,BYTE bCmd,BYTE mast,BYTE pnum,const TCmdGItem * p) { + app_assert(pnum < MAX_PLRS); + app_assert(p != NULL); + + TCmdGItem cmd; + //CopyMemory(&cmd,p,sizeof(TCmdGItem)); + cmd = *p; // struct copy. + cmd.bCmd = bCmd; + cmd.bPnum = pnum; + cmd.bMaster = mast; + + // Should I init the timer? + if (!usonly) { + cmd.dwTime = 0; + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + } + else { + // Have I been sending this back to myself for more than 5 seconds? + DWORD dwCurr = GetTickCount(); + if (cmd.dwTime == 0) + cmd.dwTime = dwCurr; + else if ((long) (dwCurr - cmd.dwTime) > RESEND_TIME) + return; + NetSendMyselfPri((BYTE *) &cmd,sizeof(cmd)); + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL NetSendCmdReq2(BYTE bCmd,BYTE mast,BYTE pnum,const TCmdGItem * p) { + app_assert(pnum < MAX_PLRS); + app_assert(p != NULL); + + TCmdGItem cmd; + //CopyMemory(&cmd,p,sizeof(TCmdGItem)); + cmd = *p; // struct copy. + cmd.bCmd = bCmd; + cmd.bPnum = pnum; + cmd.bMaster = mast; + + // Have I been sending this back to myself for more than 5 seconds? + DWORD dwCurr = GetTickCount(); + if (cmd.dwTime == 0) // Timer inited in original send + cmd.dwTime = dwCurr; + else if ((long) (dwCurr - cmd.dwTime) > RESEND_TIME) + return(FALSE); + NetSendMyselfPri((BYTE *) &cmd,sizeof(cmd)); + return(TRUE); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdExtra(const TCmdGItem * p) +{ + app_assert(p != NULL); + + TCmdGItem cmd; + //CopyMemory(&cmd,p,sizeof(TCmdGItem)); + cmd = *p; // struct copy + cmd.bCmd = CMD_ITEMEXTRA; + cmd.dwTime = 0; + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdPItem(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y) { + app_assert(x < DMAXX); + app_assert(y < DMAXY); + + TCmdPItem cmd; + cmd.bCmd = bCmd; + cmd.x = x; + cmd.y = y; + cmd.wIndx = plr[myplr].HoldItem.IDidx; + if (plr[myplr].HoldItem.IDidx == IDI_EAR) { + cmd.wCI = (plr[myplr].HoldItem._iName[7] << 8) | plr[myplr].HoldItem._iName[8]; + cmd.dwSeed = (plr[myplr].HoldItem._iName[9] << 24) | + (plr[myplr].HoldItem._iName[10] << 16) | + (plr[myplr].HoldItem._iName[11] << 8) | + plr[myplr].HoldItem._iName[12]; + cmd.bId = plr[myplr].HoldItem._iName[13]; + cmd.bDur = plr[myplr].HoldItem._iName[14]; + cmd.bMDur = plr[myplr].HoldItem._iName[15]; + cmd.bCh = plr[myplr].HoldItem._iName[16]; + cmd.bMCh = plr[myplr].HoldItem._iName[17]; + cmd.wValue = (plr[myplr].HoldItem._iName[18] << 8) | + ((plr[myplr].HoldItem._iCurs - ITEM_EAR1) << 6) | + plr[myplr].HoldItem._ivalue; + cmd.dwBuff = (plr[myplr].HoldItem._iName[19] << 24) | + (plr[myplr].HoldItem._iName[20] << 16) | + (plr[myplr].HoldItem._iName[21] << 8) | + plr[myplr].HoldItem._iName[22]; + } else { + cmd.wCI = plr[myplr].HoldItem._iCreateInfo; + cmd.dwSeed = plr[myplr].HoldItem._iSeed; + cmd.bId = plr[myplr].HoldItem._iIdentified; + cmd.bDur = plr[myplr].HoldItem._iDurability; + cmd.bMDur = plr[myplr].HoldItem._iMaxDur; + cmd.bCh = plr[myplr].HoldItem._iCharges; + cmd.bMCh = plr[myplr].HoldItem._iMaxCharges; + cmd.wValue = plr[myplr].HoldItem._ivalue; + cmd.wPLToHit = plr[myplr].HoldItem._iPLToHit; + cmd.wMaxDam = plr[myplr].HoldItem._iMaxDam; + cmd.bMinStr = plr[myplr].HoldItem._iMinStr; + cmd.bMinMag = plr[myplr].HoldItem._iMinMag; + cmd.bMinDex = plr[myplr].HoldItem._iMinDex; + cmd.bAC = plr[myplr].HoldItem._iAC; + } + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdChItem(BOOL bHiPri,BYTE bLoc) { + TCmdChItem cmd; + cmd.bCmd = CMD_CHANGEPLRITEMS; + cmd.bLoc = bLoc; + cmd.wIndx = plr[myplr].HoldItem.IDidx; + cmd.wCI = plr[myplr].HoldItem._iCreateInfo; + cmd.dwSeed = plr[myplr].HoldItem._iSeed; + // drb.patch1.start.02/10/97 + cmd.bId = plr[myplr].HoldItem._iIdentified; + // drb.patch1.end.02/10/97 + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdDelItem(BOOL bHiPri,BYTE bLoc) { + TCmdDelItem cmd; + cmd.bCmd = CMD_DELPLRITEMS; + cmd.bLoc = bLoc; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdDItem(BOOL bHiPri,int ii) { + app_assert((DWORD)ii < MAXITEMS); + + TCmdPItem cmd; + cmd.bCmd = CMD_DROPITEM; + cmd.x = item[ii]._ix; + cmd.y = item[ii]._iy; + cmd.wIndx = item[ii].IDidx; + if (item[ii].IDidx == IDI_EAR) { + cmd.wCI = (item[ii]._iName[7] << 8) | item[ii]._iName[8]; + cmd.dwSeed = (item[ii]._iName[9] << 24) | + (item[ii]._iName[10] << 16) | + (item[ii]._iName[11] << 8) | + item[ii]._iName[12]; + cmd.bId = item[ii]._iName[13]; + cmd.bDur = item[ii]._iName[14]; + cmd.bMDur = item[ii]._iName[15]; + cmd.bCh = item[ii]._iName[16]; + cmd.bMCh = item[ii]._iName[17]; + cmd.wValue = (item[ii]._iName[18] << 8) | + ((item[ii]._iCurs - ITEM_EAR1) << 6) | + item[ii]._ivalue; + cmd.dwBuff = (item[ii]._iName[19] << 24) | + (item[ii]._iName[20] << 16) | + (item[ii]._iName[21] << 8) | + item[ii]._iName[22]; + } else { + cmd.wCI = item[ii]._iCreateInfo; + cmd.dwSeed = item[ii]._iSeed; + cmd.bId = item[ii]._iIdentified; + cmd.bDur = item[ii]._iDurability; + cmd.bMDur = item[ii]._iMaxDur; + cmd.bCh = item[ii]._iCharges; + cmd.bMCh = item[ii]._iMaxCharges; + cmd.wValue = item[ii]._ivalue; + cmd.wPLToHit = item[ii]._iPLToHit; + cmd.wMaxDam = item[ii]._iMaxDam; + cmd.bMinStr = item[ii]._iMinStr; + cmd.bMinMag = item[ii]._iMinMag; + cmd.bMinDex = item[ii]._iMinDex; + cmd.bAC = item[ii]._iAC; + } + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static BOOL i_own_level(int nReqLevel) { + // the lowest numbered player on a level is + // responsible for arbitrating disputes. + for (int i = 0; i < MAX_PLRS; i++) { + if (! plr[i].plractive) continue; + if (plr[i]._pLvlChanging) continue; + if (plr[i].plrlevel != nReqLevel) continue; + if (i == myplr && gbBufferMsgs != BUFFER_OFF) continue; + break; + } + + return i == myplr; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdDamage(BOOL bHiPri,BYTE bPlr,DWORD dwDam) { + app_assert(bPlr < MAX_PLRS); + + TCmdDamage cmd; + cmd.bCmd = CMD_PLRDAMAGE; + cmd.bPlr = bPlr; + cmd.dwDam = dwDam; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendCmdMonstDamage(BOOL bHiPri,WORD wMonst,DWORD dwDam) { + app_assert(wMonst < MAXMONSTERS); + + TCmdMonstDamage cmd; + cmd.bCmd = CMD_MONSTDAMAGE; + cmd.wMonst = wMonst; + cmd.dwDam = dwDam; + + if (bHiPri) + NetSendHiPri((BYTE *) &cmd,sizeof(cmd)); + else + NetSendLoPri((BYTE *) &cmd,sizeof(cmd)); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void NetSendString(DWORD dwSendMask,const char * pszStr) { + app_assert(pszStr); + + TCmdString cmd; + DWORD dwStrLen = strlen(pszStr); + app_assert(dwStrLen < sizeof(cmd.str)); + + cmd.bCmd = CMD_STRING; + strcpy(cmd.str,pszStr); + NetSendMask( + dwSendMask, + (BYTE *) &cmd, + (BYTE) (sizeof(cmd) - sizeof(cmd.str) + dwStrLen + 1) + ); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD cmd_string(int pnum,const TCmdString * p) { + app_assert((DWORD)pnum < MAX_PLRS); + app_assert(p != NULL); + + DWORD dwStrLen = strlen(p->str); + + // don't display messages while buffering or processing + if (gbBufferMsgs == BUFFER_OFF) + plrmsg_add(pnum,p->str); + + return sizeof(*p) - sizeof(p->str) + dwStrLen + 1; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void delta_open_portal( + int pnum, + BYTE x, + BYTE y, + BYTE bLevel, + BYTE bLType, + BYTE bSetLvl +) { + app_assert((DWORD)pnum < MAX_PLRS); + app_assert(x < DMAXX); + app_assert(y < DMAXY); + app_assert(bLevel < NUMLEVELS); + + sgJunk.portal[pnum].x = x; + sgJunk.portal[pnum].y = y; + sgJunk.portal[pnum].level = bLevel; + sgJunk.portal[pnum].ltype = bLType; + sgJunk.portal[pnum].setlvl = bSetLvl; + sgbDeltaChanged = TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void delta_close_portal(int pnum) { + app_assert((DWORD)pnum < MAX_PLRS); + FillMemory(&sgJunk.portal[pnum],sizeof(sgJunk.portal[pnum]),INIT_VAL); + sgbDeltaChanged = TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void check_update_plr(int pnum) { + if (gbMaxPlayers == 1) return; + + app_assert((DWORD)pnum < MAX_PLRS); + if (pnum != myplr) return; + + void TimedUpdatePlayerFile(BOOL bForce); + TimedUpdatePlayerFile(TRUE); +} + +// PATCH2.JMM.3/5/97 +#define MAX_ADDSTAT 256 +#define MAX_LEVEL 51 +#define MAX_STAT 750 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define CHEATER_DISP_INTERVAL 5 +static DWORD sgdwLastCheaterTime = 0; + +static void __cdecl IdentifyCheater( LPCSTR szFormat, ... ) { + DWORD dwCurrTime; + char szOut[256]; + + dwCurrTime = GetTickCount( ); + + if((dwCurrTime - sgdwLastCheaterTime) < (CHEATER_DISP_INTERVAL*1000)) + return; + + sgdwLastCheaterTime = dwCurrTime; + + va_list args; + va_start(args,szFormat); + vsprintf(szOut,szFormat,args); + va_end(args); + + sysmsg_add_string( szOut ); + +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SYNCDATA( const TCmd* pCmd, int pnum ) { + // sync_update handles gbBufferMsgs + + DROPLOG( "CMD_SYNCDATA(%d)\n", pnum ); + return sync_update( pnum, (CONST BYTE *) pCmd ); +} + + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_WALKXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLoc * p = (const TCmdLoc *) pCmd; + + DROPLOG("CMD_WALKXY(%d):(%d,%d)\n",pnum,p->x,p->y); + + ClrPlrPath(pnum); + MakePlrPath(pnum, p->x, p->y, TRUE); + plr[pnum].destAction = PCMD_NOTHING; + } + return sizeof(TCmdLoc); +} + + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ADDSTR( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_ADDSTR(%d)\n",pnum); + + // PATCH2.JMM.3/5/97 + if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) { + return sizeof(TCmdParam1); + } + // ENDPATCH2.JMM.3/5/97 + + ModifyPlrStr(pnum, p->wParam1); + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ADDMAG( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_ADDMAG(%d)\n",pnum); + + // PATCH2.JMM.3/5/97 + if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) { + return sizeof(TCmdParam1); + } + // ENDPATCH2.JMM.3/5/97 + + ModifyPlrMag(pnum, p->wParam1); + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ADDDEX( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_ADDDEX(%d)\n",pnum); + + // PATCH2.JMM.3/5/97 + if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) { + return sizeof(TCmdParam1); + } + // ENDPATCH2.JMM.3/5/97 + + ModifyPlrDex(pnum, p->wParam1); + } + + return sizeof(TCmdParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ADDVIT( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_ADDVIT(%d)\n",pnum); + + // PATCH2.JMM.3/5/97 + if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) { + return sizeof(TCmdParam1); + } + // ENDPATCH2.JMM.3/5/97 + + ModifyPlrVit(pnum, p->wParam1); + } + + return sizeof(TCmdParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SBSPELL( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_SBSPELL(%d)\n",pnum); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam1; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdParam1); + } + // ENDPATCH2.JMM.3/5/97 + + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pSBkSplType; + plr[pnum]._pSplFrom = SPL_FROMBK; + plr[pnum].destAction = PCMD_SPELL; + } + return sizeof(TCmdParam1); +} + + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_GOTOGETITEM( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + + DROPLOG("CMD_GOTOGETITEM(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = PCMD_REQGETITEM; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdLocParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_REQUESTGITEM( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else { + const TCmdGItem * p = (const TCmdGItem *) pCmd; + + DROPLOG("CMD_REQUESTGETITEM(%d,%8.8x): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->dwTime,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + + if (i_own_level(plr[pnum].plrlevel)) { + app_assert(currlevel == plr[myplr].plrlevel); + + // make sure we don't start resending an item we just picked up. + if( !CheckGetRecord( p->dwSeed, p->wCI, p->wIndx ) ) + return sizeof(TCmdGItem); + + int ii = FindGetItem(p->wIndx, p->wCI, p->dwSeed); + if (ii != -1) { + DROPLOG(" Item found. FindGetItem returned %d and iDelFlag is FALSE.\n",ii); + NetSendCmdGItem2(FALSE, CMD_GETITEM, myplr, p->bPnum, p); + + if (p->bPnum != myplr) { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + } + else { + InvGetItem(myplr, ii); + } + + AddGetRecord( p->dwSeed, p->wCI, p->wIndx ); + } + else { + if (ii == -1) { + DROPLOG(" Item not found. Resending.\n"); + if (! NetSendCmdReq2(CMD_REQUESTGITEM, myplr, p->bPnum, p)) { + DROPLOG(" Resend expired. Extra Item.\n"); + NetSendCmdExtra(p); + } + } + } + } + } + + return sizeof(TCmdGItem); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_GETITEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdGItem)); + } + else { + const TCmdGItem * p = (const TCmdGItem *) pCmd; + + DROPLOG("CMD_GETITEM(%d,%8.8x,%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->dwTime,p->bPnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + DROPLOG(" Data: bCmd = %2.2x\n", p->bCmd); + DROPLOG(" Data: bMaster = %2.2x\n",p->bMaster); + DROPLOG(" Data: bPnum = %2.2x\n",p->bPnum); + DROPLOG(" Data: bCursitem = %2.2x\n",p->bCursitem); + DROPLOG(" Data: bLevel = %2.2x\n",p->bLevel); + DROPLOG(" Data: x = %2.2x\n",p->x); + DROPLOG(" Data: y = %2.2x\n",p->y); + DROPLOG(" Data: wIndx = %4.4x\n",p->wIndx); + DROPLOG(" Data: wCI = %4.4x\n",p->wCI); + DROPLOG(" Data: dwSeed = %8.8x\n",p->dwSeed); + DROPLOG(" Data: bID = %2.2x\n",p->bId); + DROPLOG(" Data: bDur = %2.2x\n",p->bDur); + DROPLOG(" Data: bMDur = %2.2x\n",p->bMDur); + DROPLOG(" Data: bCh = %2.2x\n",p->bCh); + DROPLOG(" Data: bMCh = %2.2x\n",p->bMCh); + DROPLOG(" Data: wValue = %4.4x\n",p->wValue); + DROPLOG(" Data: dwBuff = %8.8x\n",p->dwBuff); + DROPLOG(" Data: dwTime = %8.8x\n",p->dwTime); + + int nIndex = FindGetItem( p->wIndx, p->wCI, p->dwSeed ); + + // Check if in the delta table + DROPLOG(" Looking in delta tbl[%d]\n",p->bLevel); + + //if (delta_get_item(p, plr[pnum].plrlevel) && (nIndex != -1)) { + if (delta_get_item(p, p->bLevel)) { + // Found in delta + DROPLOG(" Found in delta tbl.\n"); + + //if (currlevel == plr[pnum].plrlevel) { + if ((currlevel == p->bLevel) || (p->bPnum == myplr)) { + if (p->bMaster == myplr) { + // item has already been picked up + DROPLOG(" Item already picked up.\n"); + } + else if (p->bPnum == myplr) { + if (currlevel != p->bLevel) { + int hitem = SyncPutItem(myplr, + plr[myplr]._px, + plr[myplr]._py, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff, + p->wPLToHit, + p->wMaxDam, + p->bMinStr, + p->bMinMag, + p->bMinDex, + p->bAC ); + if (hitem != -1) InvGetItem(myplr, hitem); + } else + InvGetItem(myplr, nIndex); + DROPLOG(" Local player got item.\n"); + } + else { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + DROPLOG(" Remote player (%d) got item.\n",p->bPnum); + } + } + } + else { + // Not found, so let's send it to ourselves again + DROPLOG(" Not found in delta tbl. Resending...\n"); + NetSendCmdGItem2(TRUE, CMD_GETITEM, p->bMaster, p->bPnum, p); + } + } + + return sizeof(TCmdGItem); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_GOTOAGETITEM( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + DROPLOG("CMD_GOTOAUTOGETITEM(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = PCMD_REQAGETITEM; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdLocParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_REQUESTAGITEM( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else { + const TCmdGItem * p = (const TCmdGItem *) pCmd; + DROPLOG("CMD_REQUESTAUTOGETITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + if (i_own_level(plr[pnum].plrlevel)) { + app_assert(currlevel == plr[myplr].plrlevel); + + // make sure we don't start resending an item we just picked up. + if( !CheckGetRecord( p->dwSeed, p->wCI, p->wIndx ) ) + return sizeof(TCmdGItem); + + int ii = FindGetItem(p->wIndx, p->wCI, p->dwSeed); + if (ii != -1) { + NetSendCmdGItem2(FALSE, CMD_AGETITEM, myplr, p->bPnum, p); + DROPLOG(" Item found.\n"); + if (p->bPnum != myplr) SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + else AutoGetItem(myplr, p->bCursitem); + // PATCH1.JMM + AddGetRecord( p->dwSeed, p->wCI, p->wIndx ); + // ENDPATCH1.JMM + } else { + if (ii == -1) { + DROPLOG(" Item not found. Resending.\n"); + if (! NetSendCmdReq2(CMD_REQUESTAGITEM, myplr, p->bPnum, p)) { + DROPLOG(" Resend expired. Extra Item.\n"); + NetSendCmdExtra(p); + } + } + } + } + } + return sizeof(TCmdGItem); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_AGETITEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdGItem)); + } + else { + const TCmdGItem * p = (const TCmdGItem *) pCmd; + + // PATCH1.JMM + DROPLOG("CMD_AUTOGETITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + DROPLOG(" Data: bCmd = %2.2x\n", p->bCmd); + DROPLOG(" Data: bMaster = %2.2x\n",p->bMaster); + DROPLOG(" Data: bPnum = %2.2x\n",p->bPnum); + DROPLOG(" Data: bCursitem = %2.2x\n",p->bCursitem); + DROPLOG(" Data: bLevel = %2.2x\n",p->bLevel); + DROPLOG(" Data: x = %2.2x\n",p->x); + DROPLOG(" Data: y = %2.2x\n",p->y); + DROPLOG(" Data: wIndx = %4.4x\n",p->wIndx); + DROPLOG(" Data: wCI = %4.4x\n",p->wCI); + DROPLOG(" Data: dwSeed = %8.8x\n",p->dwSeed); + DROPLOG(" Data: bID = %2.2x\n",p->bId); + DROPLOG(" Data: bDur = %2.2x\n",p->bDur); + DROPLOG(" Data: bMDur = %2.2x\n",p->bMDur); + DROPLOG(" Data: bCh = %2.2x\n",p->bCh); + DROPLOG(" Data: bMCh = %2.2x\n",p->bMCh); + DROPLOG(" Data: wValue = %4.4x\n",p->wValue); + DROPLOG(" Data: dwBuff = %8.8x\n",p->dwBuff); + DROPLOG(" Data: dwTime = %8.8x\n",p->dwTime); + + int nIndex = FindGetItem( p->wIndx, p->wCI, p->dwSeed ); + // ENDPATCH1.JMM + + // Check if in the delta table + // drb.patch1.start.2/05/97 + //if (delta_get_item(p, plr[pnum].plrlevel)) { + DROPLOG(" Looking in delta tbl[%d]\n",p->bLevel); + if (delta_get_item(p, p->bLevel)) { + // drb.patch1.end.2/05/97 + // Found in delta + DROPLOG(" Found in delta tbl.\n"); + // PATCH1.JMM + //if (currlevel == plr[pnum].plrlevel) { + if ((currlevel == p->bLevel) || (p->bPnum == myplr)) { + // ENDPATCH1.JMM + if (p->bMaster == myplr) { + // item already picked up + DROPLOG(" Item already picked up.\n"); + } + else if (p->bPnum == myplr) { + // drb.patch1.start.02/14/97 + // This is the biggest kludge I have ever written. + // I am so ashamed, but it will work + if (currlevel != p->bLevel) { + int hitem = SyncPutItem(myplr, + plr[myplr]._px, + plr[myplr]._py, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff, + p->wPLToHit, + p->wMaxDam, + p->bMinStr, + p->bMinMag, + p->bMinDex, + p->bAC ); + if (hitem != -1) AutoGetItem(myplr, hitem); + } else + AutoGetItem(myplr, p->bCursitem); + // drb.patch1.end.02.14/97 + DROPLOG(" Local player got item.\n"); + } + else { + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + DROPLOG(" Remote player (%d) got item.\n",p->bPnum); + } + } + } + else { + // Not found, so let's send it to ourselves again + NetSendCmdGItem2(TRUE, CMD_AGETITEM, p->bMaster, p->bPnum, p); + DROPLOG(" Not found in delta tbl. Resending...\n"); + } + } + + return sizeof(TCmdGItem); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ITEMEXTRA( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdGItem)); + } + else { + const TCmdGItem * p = (const TCmdGItem *) pCmd; + + DROPLOG("CMD_ITEMEXTRA(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + // Check if in the delta table + // drb.patch1.start.2/05/97 + //delta_get_item(p, plr[p->bPnum].plrlevel); + DROPLOG(" Looking in delta tbl[%d]\n",p->bLevel); + delta_get_item(p, p->bLevel); + if (currlevel == plr[pnum].plrlevel) { + //if (currlevel == p->bLevel) { + // drb.patch1.end.2/05/97 + SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed); + } + } + + return sizeof(TCmdGItem); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_PUTITEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdPItem)); + } + else { + const TCmdPItem * p = (const TCmdPItem *) pCmd; + + DROPLOG("CMD_PUTITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + + if (currlevel == plr[pnum].plrlevel) { + DROPLOG(" Item on my level.\n"); + int ii; + if (pnum == myplr) { + ii = InvPutItem(pnum, p->x, p->y); + } + else { + ii = SyncPutItem(pnum, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff, + p->wPLToHit, + p->wMaxDam, + p->bMinStr, + p->bMinMag, + p->bMinDex, + p->bAC ); + } + + if (ii != -1) { + DROPLOG(" Put successful. Putting item into delta...\n"); + + RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx ); + + DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel); + delta_put_item(p,item[ii]._ix,item[ii]._iy,plr[pnum].plrlevel); + check_update_plr(pnum); + } + else { + DROPLOG(" Put unsuccessful.\n"); + } + + return sizeof(TCmdPItem); + } + + RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx ); + + DROPLOG(" Item not on my level. Adding to delta...\n"); + DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel); + delta_put_item(p, p->x, p->y, plr[pnum].plrlevel); + check_update_plr(pnum); + } + return sizeof(TCmdPItem); +} + + + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SYNCPUTITEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdPItem)); + } + else { + const TCmdPItem * p = (const TCmdPItem *) pCmd; + + DROPLOG("CMD_SYNCPUTITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + + if (currlevel == plr[pnum].plrlevel) { + DROPLOG(" Item on my level.\n"); + int ii = SyncPutItem(pnum, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff, + p->wPLToHit, + p->wMaxDam, + p->bMinStr, + p->bMinMag, + p->bMinDex, + p->bAC ); + if (ii != -1) { + RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx ); + + DROPLOG(" Put successful. Putting item into delta...\n"); + delta_put_item(p,item[ii]._ix,item[ii]._iy,plr[pnum].plrlevel); + DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel); + check_update_plr(pnum); + } + else { + DROPLOG(" Put unsuccessful.\n"); + } + + return sizeof(TCmdPItem); + } + + RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx ); + + DROPLOG(" Item not on my level. Adding to delta...\n"); + delta_put_item(p, p->x, p->y, plr[pnum].plrlevel); + DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel); + check_update_plr(pnum); + } + + return sizeof(TCmdPItem); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_RESPAWNITEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdPItem)); + } + else { + const TCmdPItem * p = (const TCmdPItem *) pCmd; + + DROPLOG("CMD_RESPAWNITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y); + + if ((currlevel == plr[pnum].plrlevel) && (pnum != myplr)) { + DROPLOG(" SyncPutting into level.\n"); + int ii = SyncPutItem(pnum, + p->x, + p->y, + p->wIndx, + p->wCI, + p->dwSeed, + p->bId, + p->bDur, + p->bMDur, + p->bCh, + p->bMCh, + p->wValue, + p->dwBuff, + p->wPLToHit, + p->wMaxDam, + p->bMinStr, + p->bMinMag, + p->bMinDex, + p->bAC ); + } + + RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx ); + + DROPLOG(" Adding to delta...\n"); + delta_put_item(p, p->x, p->y, plr[pnum].plrlevel); + DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel); + } + + return sizeof(TCmdPItem); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ATTACKXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLoc * p = (const TCmdLoc *) pCmd; + + DROPLOG("CMD_ATTACKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = PCMD_ATTACK; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + } + + return sizeof(TCmdLoc); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SATTACKXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLoc * p = (const TCmdLoc *) pCmd; + + DROPLOG("CMD_SATTACKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_ATTACK; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + } + + return sizeof(TCmdLoc); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_RATTACKXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLoc * p = (const TCmdLoc *) pCmd; + + DROPLOG("CMD_RATTACKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_RATTACK; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + } + + return sizeof(TCmdLoc); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SPELLXYD( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam3 * p = (const TCmdLocParam3 *) pCmd; + + DROPLOG("CMD_SPELLXYD(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam1; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdLocParam3); + } + // ENDPATCH2.JMM.3/5/97 + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_SPELLXYD; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + plr[pnum].destParam3 = p->wParam2; + plr[pnum].destParam4 = p->wParam3; + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = SPL_FROMR; + } + + return sizeof(TCmdLocParam3); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SPELLXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam2 * p = (const TCmdLocParam2 *) pCmd; + + DROPLOG("CMD_SPELLXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam1; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdLocParam2); + } + // ENDPATCH2.JMM.3/5/97 + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_SPELL; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + plr[pnum].destParam3 = p->wParam2; + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = SPL_FROMR; + } + return sizeof(TCmdLocParam2); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_TSPELLXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam2 * p = (const TCmdLocParam2 *) pCmd; + + DROPLOG("CMD_TSPELLXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam1; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdLocParam2); + } + // ENDPATCH2.JMM.3/5/97 + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_SPELL; + plr[pnum].destParam1 = p->x; + plr[pnum].destParam2 = p->y; + plr[pnum].destParam3 = p->wParam2; + plr[pnum]._pSpell = p->wParam1; + plr[pnum]._pSplType = plr[pnum]._pTSplType; + plr[pnum]._pSplFrom = SPL_FROMT; + } + + return sizeof(TCmdLocParam2); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_OPOBJXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + + DROPLOG("CMD_OPOBJXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + if (!object[p->wParam1]._oSolidFlag && !object[p->wParam1]._oDoorFlag) + MakePlrPath(pnum, p->x, p->y, TRUE); + else + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = PCMD_OPOBJ; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdLocParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_DISARMXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + DROPLOG("CMD_DISARMXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + if (!object[p->wParam1]._oSolidFlag && !object[p->wParam1]._oDoorFlag) + MakePlrPath(pnum, p->x, p->y, TRUE); + else + MakePlrPath(pnum, p->x, p->y, FALSE); + + plr[pnum].destAction = PCMD_DISARM; + plr[pnum].destParam1 = p->wParam1; + } + return sizeof(TCmdLocParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_OPOBJT( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_OPOBJT(%d)\n",pnum); + + plr[pnum].destAction = PCMD_TELEK; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ATTACKID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_ATTACKID(%d): id->%d\n",pnum,p->wParam1); + + int dx = abs(plr[pnum]._px - monster[p->wParam1]._mfutx); + int dy = abs(plr[pnum]._py - monster[p->wParam1]._mfuty); + if ((dx > 1) || (dy > 1)) + MakePlrPath(pnum, monster[p->wParam1]._mfutx, monster[p->wParam1]._mfuty, FALSE); + plr[pnum].destAction = PCMD_ATTACKID; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ATTACKPID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_ATTACKPID(%d): id->%d\n",pnum,p->wParam1); + + MakePlrPath(pnum, plr[p->wParam1]._pfutx, plr[p->wParam1]._pfuty, FALSE); + plr[pnum].destAction = PCMD_ATTACKPID; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_RATTACKID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_RATTACKID(%d): id->%d\n",pnum,p->wParam1); + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_RATTACKID; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_RATTACKPID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_RATTACKPID(%d): id->%d\n",pnum,p->wParam1); + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_RATTACKPID; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SPELLID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam3 * p = (const TCmdParam3 *) pCmd; + + DROPLOG("CMD_SPELLID(%d): id->%d\n",pnum,p->wParam1); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam2; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdParam3); + } + // ENDPATCH2.JMM.3/5/97 + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_SPELLID; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = SPL_FROMR; + } + + return sizeof(TCmdParam3); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SPELLPID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam3 * p = (const TCmdParam3 *) pCmd; + + DROPLOG("CMD_SPELLPID(%d): id->%d\n",pnum,p->wParam1); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam2; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdParam3); + } + // ENDPATCH2.JMM.3/5/97 + + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_SPELLPID; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + plr[pnum]._pSplFrom = SPL_FROMR; + } + + return sizeof(TCmdParam3); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_TSPELLID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam3 * p = (const TCmdParam3 *) pCmd; + + DROPLOG("CMD_TSPELLID(%d): id->%d\n",pnum,p->wParam1); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam2; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdParam3); + } + // ENDPATCH2.JMM.3/5/97 + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_SPELLID; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pTSplType; + plr[pnum]._pSplFrom = SPL_FROMT; + } + + return sizeof(TCmdParam3); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_TSPELLPID( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam3 * p = (const TCmdParam3 *) pCmd; + + DROPLOG("CMD_TSPELLPID(%d): id->%d\n",pnum,p->wParam1); + + // PATCH2.JMM.3/5/97 + UINT nSplType = p->wParam2; + + if(currlevel == 0 && !spelldata[nSplType].sTownSpell) { + IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName); + return sizeof(TCmdParam3); + } + // ENDPATCH2.JMM.3/5/97 + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_SPELLPID; + plr[pnum].destParam1 = p->wParam1; + plr[pnum].destParam2 = p->wParam3; + plr[pnum]._pSpell = p->wParam2; + plr[pnum]._pSplType = plr[pnum]._pTSplType; + plr[pnum]._pSplFrom = SPL_FROMT; + } + + return sizeof(TCmdParam3); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_KNOCKBACK( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_KNOCKBACK(%d): id->%d\n",pnum,p->wParam1); + + if (currlevel == plr[pnum].plrlevel) { + M_GetKnockback(p->wParam1); + M_StartHit(p->wParam1, pnum, 0); + } + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_RESURRECT( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_RESURRECT(%d): id->%d\n",pnum,p->wParam1); + + DoResurrect(pnum, p->wParam1); + + // update character file to prevent cheating + check_update_plr(pnum); + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_HEALOTHER( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_HEALOTHER(%d): id->%d\n",pnum,p->wParam1); + + DoHealOther(pnum, p->wParam1); + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_TALKXY( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else if (currlevel == plr[pnum].plrlevel) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + + DROPLOG("CMD_TALKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + MakePlrPath(pnum, p->x, p->y, FALSE); + plr[pnum].destAction = PCMD_TALK; + plr[pnum].destParam1 = p->wParam1; + } + + return sizeof(TCmdLocParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_NEWLVL( const TCmd* pCmd, int pnum ) { + + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam2)); + } + else if (pnum != myplr) { + const TCmdParam2 * p = (const TCmdParam2 *) pCmd; + + DROPLOG("CMD_NEWLVL(%d)\n",pnum); + + StartNewLvl(pnum,p->wParam1,p->wParam2); + } + + return sizeof(TCmdParam2); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_WARP( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + + DROPLOG("CMD_WARP(%d)\n",pnum); + + StartWarpLvl(pnum, p->wParam1); + + // drb.patch1.start.02/15/97 + if ((pnum == myplr) && (curs >= ICSTART)) { + item[TEMPAVAIL] = plr[myplr].HoldItem; + AutoGetItem(myplr, TEMPAVAIL); + } + // drb.patch1.end.02/15/97 + + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_MONSTDEATH( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdLocParam1)); + } + else if (pnum != myplr) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + DROPLOG("CMD_MONSTDEATH(%d): id->%d xy->(%d,%d)\n",pnum,p->wParam1,p->x,p->y); + if (currlevel == plr[pnum].plrlevel) + M_SyncStartKill(p->wParam1, p->x, p->y, pnum); + delta_kill_monster(p->wParam1, p->x, p->y,plr[pnum].plrlevel); + } + + return sizeof(TCmdLocParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_KILLGOLEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdLocParam1)); + } + else if (pnum != myplr) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + DROPLOG("CMD_KILLGOLEM(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + if (currlevel == p->wParam1) + M_SyncStartKill(pnum, p->x, p->y, pnum); + delta_kill_monster(pnum, p->x, p->y, plr[pnum].plrlevel); + } + + return sizeof(TCmdLocParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_AWAKEGOLEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) + mega_add_data(pnum, pCmd, sizeof(TCmdGolem)); + else { + DROPLOG("CMD_AWAKENGOLEM(%d)\n",pnum); + if (currlevel != plr[pnum].plrlevel) + delta_sync_golem((const TCmdGolem *) pCmd, pnum, ((const TCmdGolem *) pCmd)->_currlevel); + else { + if (pnum != myplr) { + BOOL addok = TRUE; + for (int i = 0; i < nummissiles; i++) { + int mi = missileactive[i]; + if ((missile[mi]._mitype == MIT_GOLEM) && (missile[mi]._misource == pnum)) addok = FALSE; + } + const TCmdGolem * pG = (const TCmdGolem *) pCmd; + if (addok) AddMissile(plr[pnum]._px, plr[pnum]._py, pG->_mx, pG->_my, pG->_mdir, MIT_GOLEM, MI_ENEMYMONST, pnum, 0, 1); + } + } + } + + return sizeof(TCmdGolem); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_MONSTDAMAGE( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam2)); + } + else if (pnum != myplr) { + const TCmdMonstDamage * p = (const TCmdMonstDamage *) pCmd; + + DROPLOG("CMD_MONSTDAMAGE(%d): id->%d\n",pnum,p->wMonst); + + if (currlevel == plr[pnum].plrlevel) { + monster[p->wMonst].mWhoHit |= (1 << pnum); + if (monster[p->wMonst]._mhitpoints >= 0) { + monster[p->wMonst]._mhitpoints -= p->dwDam; + // take damage but don't kill him + if ((monster[p->wMonst]._mhitpoints >> HP_SHIFT) < 1) + monster[p->wMonst]._mhitpoints = 1 << HP_SHIFT; + delta_monster_hp(p->wMonst,monster[p->wMonst]._mhitpoints,plr[pnum].plrlevel); + } + } + else { + // @@@@ Dave -- need some way to calculate new monster hp + // since we don't have its info handy + } + } + + return sizeof(TCmdMonstDamage); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_PLRDEAD( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else if (pnum != myplr) { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_PLAYERDEAD(%d): id->%d\n",pnum,p->wParam1); + SyncPlrKill(pnum, p->wParam1); + } + else { + DROPLOG("CMD_PLAYERDEAD(I'm dead!!!)\n",pnum); + check_update_plr(pnum); + } + + return sizeof(TCmdParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_PLRDAMAGE( const TCmd* pCmd, int pnum ) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + const TCmdDamage * p = (const TCmdDamage *) pCmd; + DROPLOG("CMD_PLAYERDAMAGE(%d)\n",pnum); + + if (p->bPlr != myplr) { + // ignore message + } + // JMM.PATCH1 + else if (currlevel == 0) { + // illegal message! + } + // JMM.ENDPATCH1 + else if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered, because + // the player isn't active yet, so he + // can't be taking any damage + } + // PATCH2.JMM.3/5/97 + else if (currlevel != plr[pnum].plrlevel) { + // illegal message! (player must be on same level) + } + else if ( p->dwDam > (3000<%d\n",currlevel); + // If I am already dead, don't kill me again. + if ((plr[myplr]._pHitPoints >> HP_SHIFT) > 0) { + // not dead yet + drawhpflag = TRUE; + plr[myplr]._pHitPoints -= p->dwDam; + plr[myplr]._pHPBase -= p->dwDam; + if (plr[myplr]._pHitPoints > plr[myplr]._pMaxHP) { + plr[myplr]._pHitPoints = plr[myplr]._pMaxHP; + plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase; + } + if ((plr[myplr]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - plr[myplr]._pHitPoints = 0; + StartPlrKill(myplr, TRUE); + } + } + } + + return sizeof(TCmdDamage); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_OPENDOOR( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_OPENDOOR(%d): id->%d\n",pnum,p->wParam1); + if (currlevel == plr[pnum].plrlevel) + SyncOpObject(pnum, CMD_OPENDOOR, p->wParam1); + delta_sync_object(p->wParam1,CMD_OPENDOOR,plr[pnum].plrlevel); + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**----------------------------------------------------------------------*/ +static DWORD On_CLOSEDOOR( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_CLOSEDOOR(%d): id->%d\n",pnum,p->wParam1); + if (currlevel == plr[pnum].plrlevel) + SyncOpObject(pnum, CMD_CLOSEDOOR, p->wParam1); + delta_sync_object(p->wParam1,CMD_CLOSEDOOR,plr[pnum].plrlevel); + } + + return sizeof(TCmdParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_OPERATEOBJ( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_OPERATEOBJ(%d): id->%d\n",pnum,p->wParam1); + if (currlevel == plr[pnum].plrlevel) + SyncOpObject(pnum, CMD_OPERATEOBJ, p->wParam1); + delta_sync_object(p->wParam1,CMD_OPERATEOBJ,plr[pnum].plrlevel); + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_PLROPOBJ( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam2)); + } + else { + const TCmdParam2 * p = (const TCmdParam2 *) pCmd; + DROPLOG("CMD_PLAYEROPOBJ(%d): plrid->%d objid->%d\n",pnum,p->wParam1,p->wParam2); + if (currlevel == plr[pnum].plrlevel) + SyncOpObject(p->wParam1, CMD_PLROPOBJ, p->wParam2); + delta_sync_object(p->wParam2,CMD_PLROPOBJ,plr[pnum].plrlevel); + } + + return sizeof(TCmdParam2); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_BREAKOBJ( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam2)); + } + else { + const TCmdParam2 * p = (const TCmdParam2 *) pCmd; + DROPLOG("CMD_BREAKOBJ(%d): id1->%d id2->%d\n",pnum,p->wParam1,p->wParam2); + if (currlevel == plr[pnum].plrlevel) + SyncBreakObj(p->wParam1, p->wParam2); + delta_sync_object(p->wParam2,CMD_BREAKOBJ,plr[pnum].plrlevel); + } + + return sizeof(TCmdParam2); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_CHANGEPLRITEMS( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdChItem)); + } + else { + const TCmdChItem * p = (const TCmdChItem *) pCmd; + DROPLOG("CMD_CHANGEPLAYERITEMS(%d): index->%8.8x ci->%8.8x seed->%8.8x\n",pnum,p->wIndx, p->wCI, p->dwSeed); + // drb.patch1.start.02/10/97 + // if (pnum != myplr) SyncInvPaste(pnum, p->bLoc, p->wIndx, p->wCI, p->dwSeed); + if (pnum != myplr) SyncInvPaste(pnum, p->bLoc, p->wIndx, p->wCI, p->dwSeed, p->bId); + // drb.patch1.end.02/10/97 + } + + return sizeof(TCmdChItem); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_DELPLRITEMS( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdDelItem)); + } + else { + const TCmdDelItem * p = (const TCmdDelItem *) pCmd; + DROPLOG("CMD_DELPLAYERITEMS(%d): loc->%d\n",pnum, p->bLoc); + if (pnum != myplr) SyncInvCut(pnum, p->bLoc); + } + + return sizeof(TCmdDelItem); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_PLRLEVEL( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_PLAYERLEVEL(%d)\n",pnum); + + if ((p->wParam1 <= MAX_LEVEL) && pnum != myplr) + plr[pnum]._pLevel = (char) p->wParam1; + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_DROPITEM( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdPItem)); + } + else { + // item dropped by a dead monster/chest/etc. + // doesn't have to do anything to level data + // only to delta info + const TCmdPItem * p = (const TCmdPItem *) pCmd; + DROPLOG("CMD_DROPITEM(%d): index->%8.8x ci->%8.8x seed->%8.8x xy->(%d,%d)\n",pnum,p->wIndx, p->wCI, p->dwSeed, p->x, p->y); + delta_put_item(p,p->x,p->y,plr[pnum].plrlevel); + } + + return sizeof(TCmdPItem); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SEND_PLRINFO( const TCmd* pCmd, int pnum ) { + const TCmdPlrInfoHdr * p = (const TCmdPlrInfoHdr *) pCmd; + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,p,p->wBytes + sizeof(TCmdPlrInfoHdr)); + } + else { + DROPLOG("CMD_ACK\\SENDPLRINFO(%d)\n",pnum); + recv_plrinfo(pnum,p,p->bCmd == CMD_ACK_PLRINFO); + } + + return p->wBytes + sizeof(TCmdPlrInfoHdr); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ACK_PLRINFO( const TCmd* pCmd, int pnum ) { + return On_SEND_PLRINFO( pCmd, pnum ); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_PLAYER_JOINLEVEL( const TCmd* pCmd, int pnum ) { + + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdLocParam1)); + } + else { + app_assert((DWORD)pnum < MAX_PLRS); + DROPLOG("CMD_PLAYERJOINLEVEL(%d)\n",pnum); + + plr[pnum]._pLvlChanging = FALSE; + + // joining game? + if (! plr[pnum]._pName[0]) { + // we are probably unbuffering messages, + // and we received this message before we + // received the message that tells us who + // this player is. Just ignore this message. + // Eventually we will get a PLRINFO message + // which will activate this player + #if TRACEOUT + TraceOut("(%d) received %d joinlevel before plrdata",myplr,pnum); + #endif + } + else if (! plr[pnum].plractive) { + plr[pnum].plractive = 1; + gbActivePlayers++; + sysmsg_add("Player '%s' (level %d) just joined the game",plr[pnum]._pName,plr[pnum]._pLevel); + #if TRACEOUT + TraceOut("(%d) activating %d on joinlevel",myplr,pnum); + #endif + } + + // activate player on this level + if (plr[pnum].plractive && myplr != pnum) { + const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd; + plr[pnum]._px = p->x; + plr[pnum]._py = p->y; + plr[pnum].plrlevel = p->wParam1; + plr[pnum]._pGFXLoad = 0; + if (currlevel == plr[pnum].plrlevel) { + LoadPlrGFX(pnum,PGL_STAND); + SyncInitPlr(pnum); + if ((plr[pnum]._pHitPoints >> HP_SHIFT) > 0) { + StartStand(pnum,0); + } else { + plr[pnum]._pgfxnum = PGFX_NGUY; + LoadPlrGFX(pnum, PGL_DEAD); + plr[pnum]._pmode = PM_DEATH; + NewPlrAnim(pnum, plr[pnum]._pDAnim[DIR_D], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth); + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1; + plr[pnum]._pVar8 = plr[pnum]._pAnimLen << 1; + dFlags[plr[pnum]._px][plr[pnum]._py] |= BFLAG_DEADPLR; + } + plr[pnum]._pvid = AddVision(plr[pnum]._px, plr[pnum]._py, + plr[pnum]._pLightRad, pnum==myplr); + plr[pnum]._plid = -1; + } + } + } + return sizeof(TCmdLocParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ACTIVATEPORTAL( const TCmd* pCmd, int pnum ) { + + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdLocParam3)); + } + else { + const TCmdLocParam3 * p = (const TCmdLocParam3 *) pCmd; + + DROPLOG("CMD_ACTIVATEPORTAL(%d): xy->(%d,%d)\n",pnum,p->x,p->y); + + ActivatePortal(pnum, p->x, p->y, p->wParam1, p->wParam2, p->wParam3); + if (pnum != myplr) { + if (currlevel == 0) { + AddInTownPortal(pnum); + } else { + if (currlevel == plr[pnum].plrlevel) { + // If on same level make sure portal appears + int i,mi; + BOOL addok = TRUE; + for (i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if ((missile[mi]._mitype == MIT_TOWN) && (missile[mi]._misource == pnum)) addok = FALSE; + } + if (addok) AddWarpMissile(pnum, p->x, p->y); + } else { + // Remove portal if it was on my level before + RemovePortalMissile(pnum); + } + } + } + delta_open_portal(pnum,p->x,p->y,(BYTE) p->wParam1,(BYTE) p->wParam2, (BYTE) p->wParam3); + } + + return sizeof(TCmdLocParam3); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_DEACTIVATEPORTAL( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmd)); + } + else { + DROPLOG("CMD_DEACTIVEPORTAL(%d)\n",pnum); + if (PortalOnLevel(pnum)) RemovePortalMissile(pnum); + DeactivatePortal(pnum); + delta_close_portal(pnum); + } + + return sizeof(TCmd); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_RETOWN( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmd)); + } + else { + DROPLOG("CMD_RETOWN(%d)\n",pnum); + if (pnum == myplr) { + deathflag = FALSE; + gamemenu_off(); + } + RestartTownLvl(pnum); + } + + return sizeof(TCmd); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SETSTR( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_SETSTR(%d)\n",pnum); + + if( p->wParam1 > MAX_STAT ) + return sizeof( TCmdParam1 ); + + if (pnum != myplr) { + SetPlrStr(pnum, p->wParam1); + } + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SETDEX( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_SETDEX(%d)\n",pnum); + + if( p->wParam1 > MAX_STAT ) + return sizeof( TCmdParam1 ); + + if (pnum != myplr) { + SetPlrDex(pnum, p->wParam1); + } + } + + return sizeof(TCmdParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SETMAG( const TCmd* pCmd, int pnum ) { + + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_SETMAG(%d)\n",pnum); + + if( p->wParam1 > MAX_STAT ) + return sizeof( TCmdParam1 ); + + + if (pnum != myplr) { + SetPlrMag(pnum, p->wParam1); + } + } + + return sizeof(TCmdParam1); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SETVIT( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdParam1)); + } + else { + const TCmdParam1 * p = (const TCmdParam1 *) pCmd; + DROPLOG("CMD_SETVIT(%d)\n",pnum); + + if( p->wParam1 > MAX_STAT ) + return sizeof( TCmdParam1 ); + + + if (pnum != myplr) { + SetPlrVit(pnum, p->wParam1); + } + } + + return sizeof(TCmdParam1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_STRING( const TCmd* pCmd, int pnum ) { + + DROPLOG("CMD_STRING(%d)\n",pnum); + // cmd_string handles gbBufferMsgs + return cmd_string(pnum,(const TCmdString *) pCmd); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_SYNCQUEST( const TCmd* pCmd, int pnum ) { + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmdQuest)); + } + else { + DROPLOG("CMD_SYNCQUEST(%d)\n",pnum); + if (pnum != myplr) { + const TCmdQuest * p = (const TCmdQuest *) pCmd; + SetMultiQuest(p->q, p->qstate, p->qlog, p->qvar1); + } + + sgbDeltaChanged = TRUE; + } + + return sizeof(TCmdQuest); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ENDSHIELD( const TCmd* pCmd, int pnum ) { + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else { + DROPLOG("CMD_ENDSHIELD(%d)\n",pnum); + if ((pnum != myplr) && (currlevel == plr[pnum].plrlevel)) { + void DeleteMissile(int, int); + for (int i = 0; i < nummissiles; i++) { + int mi = missileactive[i]; + if ((missile[mi]._mitype == MIT_MANASHIELD) && (missile[mi]._misource == pnum)) { + ClearMissileSpot(mi); + DeleteMissile(mi, i); + } + } + + } + } + + return sizeof(TCmd); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_ENDREFLECT( const TCmd* pCmd, int pnum ) { + + if (gbBufferMsgs == BUFFER_ON) { + // doesn't need to be buffered + } + else { + DROPLOG("CMD_ENDREFLECT(%d)\n",pnum); + if ((pnum != myplr) && (currlevel == plr[pnum].plrlevel)) { + void DeleteMissile(int, int); + for (int i = 0; i < nummissiles; i++) { + int mi = missileactive[i]; + if ((missile[mi]._mitype == MIT_REFLECT) && (missile[mi]._misource == pnum)) { + ClearMissileSpot(mi); + DeleteMissile(mi, i); + } + } + + } + } + + return sizeof(TCmd); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_CHEAT_EXPERIENCE( const TCmd* pCmd, int pnum ) { + +#if _DEBUG + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmd)); + } + else { + DROPLOG("CMD_CHEATEXPERIENCE(%d)\n",pnum); + if (plr[pnum]._pLevel < 50) { + plr[pnum]._pExperience = plr[pnum]._pNextExper; + NextPlrLevel(pnum); + } + } +#endif + + return sizeof(TCmd); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_CHEAT_SPELL_LEVEL( const TCmd* pCmd, int pnum ) { + +#if _DEBUG + if (gbBufferMsgs == BUFFER_ON) { + mega_add_data(pnum,pCmd,sizeof(TCmd)); + } + else { + DROPLOG("CMD_CHEATSPELLLEVEL(%d)\n",pnum); + plr[pnum]._pSplLvl[plr[pnum]._pRSpell]++; + } +#endif + + return sizeof(TCmd); +} +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_OPEN_NAKRUL(const TCmd* pCmd, int pnum) +{ + if (gbBufferMsgs == BUFFER_ON) + { + // doesn't need to be buffered + } + else + { + DROPLOG("CMD_OPEN_NAKRUL(%d)\n",pnum); + + OpenNaKrul(); + Na_Krul.Books = TRUE; + quests[Q_NA_KRUL]._qactive = QUEST_DONE; + Hose_NaKrul(); + + } + return sizeof(TCmd); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_OPEN_NEST(const TCmd * pCmd, int pnum) +{ + if (gbBufferMsgs == BUFFER_ON) + { + // doesn't need to be buffered + } + else + { + DROPLOG("CMD_OPEN_NEST(%d)\n",pnum); + const TCmdLocParam2 * p = (const TCmdLocParam2 *) pCmd; + + AddMissile (p->x, p->y, p->wParam1, p->wParam2, 0, MIT_OPENNEST, MI_PLR, pnum, 0, 0); + OpenNest(); + } + return sizeof(TCmdLocParam2); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_OPEN_CRYPT(const TCmd* pCmd, int pnum) +{ + if (gbBufferMsgs == BUFFER_ON) + { + // doesn't need to be buffered + } + else + { + DROPLOG("CMD_OPEN_CRYPT(%d)\n",pnum); + + OpenCrypt(); + InitTownTriggers(); + if (currlevel == TLVL_START) // In town + PlaySFX(IS_SARC); + + } + return sizeof(TCmd); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static DWORD On_DEBUG( const TCmd* pCmd, int pnum ) { + return sizeof(TCmd); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// PATCH3.JMM +extern WORD sgwPackPlrOffsetTbl[MAX_PLRS]; +// ENDPATCH3.JMM +#define HANDLE_CMD( c ) case CMD_##c : return On_##c( pCmd, pnum ) +DWORD ParseCmd(int pnum,const TCmd * pCmd) { + app_assert((DWORD)pnum < MAX_PLRS); + app_assert(pCmd != NULL); + + static BYTE sbLastCmd; + sbLastCmd = pCmd->bCmd; + + // patch3.jmm + if( sgwPackPlrOffsetTbl[pnum] && + sbLastCmd != CMD_ACK_PLRINFO && + sbLastCmd != CMD_SEND_PLRINFO ) + return 0; + // endpatch3.jmm + + switch(pCmd->bCmd) { + HANDLE_CMD( SYNCDATA ); + HANDLE_CMD( WALKXY ); + HANDLE_CMD( ADDSTR ); + HANDLE_CMD( ADDDEX ); + HANDLE_CMD( ADDMAG ); + HANDLE_CMD( ADDVIT ); + HANDLE_CMD( SBSPELL ); + HANDLE_CMD( GOTOGETITEM ); + HANDLE_CMD( REQUESTGITEM ); + HANDLE_CMD( GETITEM ); + HANDLE_CMD( GOTOAGETITEM ); + HANDLE_CMD( REQUESTAGITEM ); + HANDLE_CMD( AGETITEM ); + HANDLE_CMD( ITEMEXTRA ); + HANDLE_CMD( PUTITEM ); + HANDLE_CMD( SYNCPUTITEM ); + HANDLE_CMD( RESPAWNITEM ); + HANDLE_CMD( ATTACKXY ); + HANDLE_CMD( SATTACKXY ); + HANDLE_CMD( RATTACKXY ); + HANDLE_CMD( SPELLXYD ); + HANDLE_CMD( SPELLXY ); + HANDLE_CMD( TSPELLXY ); + HANDLE_CMD( OPOBJXY ); + HANDLE_CMD( DISARMXY ); + HANDLE_CMD( OPOBJT ); + HANDLE_CMD( ATTACKID ); + HANDLE_CMD( ATTACKPID ); + HANDLE_CMD( RATTACKID ); + HANDLE_CMD( RATTACKPID ); + HANDLE_CMD( SPELLID ); + HANDLE_CMD( SPELLPID ); + HANDLE_CMD( TSPELLID ); + HANDLE_CMD( TSPELLPID ); + HANDLE_CMD( KNOCKBACK ); + HANDLE_CMD( RESURRECT ); + HANDLE_CMD( HEALOTHER ); + HANDLE_CMD( TALKXY ); + HANDLE_CMD( DEBUG ); + HANDLE_CMD( NEWLVL ); + HANDLE_CMD( WARP ); + HANDLE_CMD( MONSTDEATH ); + HANDLE_CMD( KILLGOLEM ); + HANDLE_CMD( AWAKEGOLEM ); + HANDLE_CMD( MONSTDAMAGE ); + HANDLE_CMD( PLRDEAD ); + HANDLE_CMD( PLRDAMAGE ); + HANDLE_CMD( OPENDOOR ); + HANDLE_CMD( CLOSEDOOR ); + HANDLE_CMD( OPERATEOBJ ); + HANDLE_CMD( PLROPOBJ ); + HANDLE_CMD( BREAKOBJ ); + HANDLE_CMD( CHANGEPLRITEMS ); + HANDLE_CMD( DELPLRITEMS ); + HANDLE_CMD( PLRLEVEL ); + HANDLE_CMD( DROPITEM ); + HANDLE_CMD( ACK_PLRINFO ); + HANDLE_CMD( SEND_PLRINFO ); + HANDLE_CMD( PLAYER_JOINLEVEL ); + HANDLE_CMD( ACTIVATEPORTAL ); + HANDLE_CMD( DEACTIVATEPORTAL ); + HANDLE_CMD( RETOWN ); + HANDLE_CMD( SETSTR ); + HANDLE_CMD( SETMAG ); + HANDLE_CMD( SETDEX ); + HANDLE_CMD( SETVIT ); + HANDLE_CMD( STRING ); + HANDLE_CMD( SYNCQUEST ); + HANDLE_CMD( ENDSHIELD ); + HANDLE_CMD( CHEAT_EXPERIENCE ); + HANDLE_CMD( CHEAT_SPELL_LEVEL ); + HANDLE_CMD( ENDREFLECT ); + HANDLE_CMD( OPEN_NAKRUL ); + HANDLE_CMD( OPEN_NEST ); + HANDLE_CMD( OPEN_CRYPT ); + + default: + // dreceive_level handles gbBufferMsgs + if (pCmd->bCmd >= CMD_DLEVEL_0 && pCmd->bCmd <= CMD_DLEVEL_END) + return dreceive_chunk(pnum,(const TCmdPlrInfoHdr *) pCmd); +// PATCH3.JMM +// app_fatal("Unknown PCMD %d (last cmd %d)\n",pCmd->bCmd,sbLastCmd); + SNetDropPlayer( pnum, SNET_EXIT_NOTRESPONDING ); + return 0; // 0 is error condition: ditch rest of packet +// ENDPATCH3.JMM + } + + + // NO final return statement -- each case + // should have its own return statement +} +// ENDPATCH2.JMM.3/5/97 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* +int GetLDeltaItem(int itm) +{ + TCmdPItem * pD = &sgLevels[currlevel].item[0]; + for (int i = 0; i < MAXITEMS; i++,pD++) { + // find item + if (pD->bCmd == ITEM_FREE) continue; + if (pD->wIndx != item[itm].IDidx) continue; + if (pD->wCI != item[itm]._iCreateInfo) continue; + if (pD->dwSeed != (DWORD)item[itm]._iSeed) continue; + return(i); + } + return(-1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +old old old +void test_delta() { + static DLevel lvl[NUMLEVELS]; + + // randomize the level delta data + sgbDeltaChanged = TRUE; + srand(time(NULL)); + WORD * p = (WORD *) &sgLevels[0]; + for (int i = sizeof(sgLevels)/2; i--; ) + *p++ = rand(); + + // save level data for later comparison + CopyMemory(&lvl[0],&sgLevels[0],sizeof lvl); + + // send level delta info to myself + DeltaSendAllLevels(myplr); + + // reinit level delta info + ZeroMemory(&sgLevels[0],sizeof sgLevels); + + // get level delta packets + NetReceivePackets(); + + // make sure everything comps ok + for (i = 0; i < NUMLEVELS; i++) { + for (int j = 0; j < MAXITEMS; j++) { + if (sgLevels[i].item[j].bCmd == INIT_VAL) { + if (lvl[i].item[j].bCmd != INIT_VAL) + DebugBreak(); + } + else if (memcmp(&sgLevels[i].item[j],&lvl[i].item[j],sizeof(TCmdPItem))) { + DebugBreak(); + } + } + for (j = 0; j < MAXOBJECTS; j++) { + if (memcmp(&sgLevels[i].object[j],&lvl[i].object[j],sizeof(DObjectStr))) + DebugBreak(); + } + for (j = 0; j < MAXMONSTERS; j++) { + if (sgLevels[i].monster[j]._mx == INIT_VAL) { + if (lvl[i].monster[j]._mx != INIT_VAL) + DebugBreak(); + } + else if (memcmp(&sgLevels[i].monster[j],&lvl[i].monster[j],sizeof(DMonsterStr))) { + DebugBreak(); + } + } + } + + // reinit delta info + delta_init(); +} +*/ diff --git a/MSG.H b/MSG.H new file mode 100644 index 0000000..1ceb8fc --- /dev/null +++ b/MSG.H @@ -0,0 +1,260 @@ +//****************************************************************** +// msg.h +//****************************************************************** + +enum { + CMD_STAND = 0, + CMD_WALKXY, + CMD_ACK_PLRINFO, + CMD_ADDSTR, + CMD_ADDMAG, + CMD_ADDDEX, + CMD_ADDVIT, + CMD_SBSPELL, + CMD_GETITEM, + CMD_AGETITEM, + CMD_PUTITEM, + CMD_RESPAWNITEM, + CMD_ATTACKXY, + CMD_RATTACKXY, + CMD_SPELLXY, + CMD_TSPELLXY, + CMD_OPOBJXY, + CMD_DISARMXY, + CMD_ATTACKID, + CMD_ATTACKPID, + CMD_RATTACKID, + CMD_RATTACKPID, + CMD_SPELLID, + CMD_SPELLPID, + CMD_TSPELLID, + CMD_TSPELLPID, + CMD_RESURRECT, + CMD_OPOBJT, + CMD_KNOCKBACK, + CMD_TALKXY, + CMD_NEWLVL, + CMD_WARP, + CMD_CHEAT_EXPERIENCE, + CMD_CHEAT_SPELL_LEVEL, + CMD_DEBUG, + CMD_SYNCDATA, + CMD_MONSTDEATH, + CMD_MONSTDAMAGE, + CMD_PLRDEAD, + CMD_REQUESTGITEM, + CMD_REQUESTAGITEM, + CMD_GOTOGETITEM, + CMD_GOTOAGETITEM, + CMD_OPENDOOR, + CMD_CLOSEDOOR, + CMD_OPERATEOBJ, + CMD_PLROPOBJ, + CMD_BREAKOBJ, + CMD_CHANGEPLRITEMS, + CMD_DELPLRITEMS, + CMD_PLRDAMAGE, + CMD_PLRLEVEL, + CMD_DROPITEM, + CMD_PLAYER_JOINLEVEL, + CMD_SEND_PLRINFO, + CMD_SATTACKXY, + CMD_ACTIVATEPORTAL, + CMD_DEACTIVATEPORTAL, + CMD_DLEVEL_0, + CMD_DLEVEL_1, + CMD_DLEVEL_2, + CMD_DLEVEL_3, + CMD_DLEVEL_4, + CMD_DLEVEL_5, + CMD_DLEVEL_6, + CMD_DLEVEL_7, + CMD_DLEVEL_8, + CMD_DLEVEL_9, + CMD_DLEVEL_10, + CMD_DLEVEL_11, + CMD_DLEVEL_12, + CMD_DLEVEL_13, + CMD_DLEVEL_14, + CMD_DLEVEL_15, + CMD_DLEVEL_16, + CMD_DLEVEL_17, + CMD_DLEVEL_18, + CMD_DLEVEL_19, + CMD_DLEVEL_20, + CMD_DLEVEL_21, + CMD_DLEVEL_22, + CMD_DLEVEL_23, + CMD_DLEVEL_24, + CMD_DLEVEL_JUNK, + CMD_DLEVEL_END, + CMD_HEALOTHER, + CMD_STRING, + CMD_SETSTR, + CMD_SETMAG, + CMD_SETDEX, + CMD_SETVIT, + CMD_RETOWN, + CMD_SPELLXYD, + CMD_ITEMEXTRA, + CMD_SYNCPUTITEM, + CMD_KILLGOLEM, + CMD_SYNCQUEST, + CMD_ENDSHIELD, + CMD_AWAKEGOLEM, + CMD_ENDREFLECT, + CMD_OPEN_NAKRUL, + CMD_OPEN_NEST, + CMD_OPEN_CRYPT, + + // thse are commands which are never sent + FAKE_CMD_SETID, + FAKE_CMD_DROPID, + NUM_CMDS +}; + + +//****************************************************************** +// net commands +//****************************************************************** +#pragma pack(push,1) +typedef struct TCmd { + BYTE bCmd; +} TCmd; +void NetSendCmd(BOOL bHiPri,BYTE bCmd); + +void NetSendCmdLoc(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y); +void NetSendCmdLocParam1(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1); +void NetSendCmdLocParam2(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1,WORD wParam2); +void NetSendCmdLocParam3(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1,WORD wParam2,WORD wParam3); + +void NetSendCmdParam1(BOOL bHiPri,BYTE bCmd,WORD wParam1); +void NetSendCmdParam2(BOOL bHiPri,BYTE bCmd,WORD wParam1,WORD wParam2); +void NetSendCmdParam3(BOOL bHiPri,BYTE bCmd,WORD wParam1,WORD wParam2, WORD wParam3 ); + +void NetSendCmdQuest(BOOL bHiPri,BYTE q); + +void NetSendCmdGItem(BOOL bHiPri,BYTE bCmd,BYTE mast,BYTE pnum,BYTE bCursitem); +void NetSendCmdPItem(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y); +void NetSendCmdDItem(BOOL bHiPri,int ii); +void NetSendCmdChItem(BOOL bHiPri,BYTE bLoc); +void NetSendCmdDelItem(BOOL bHiPri,BYTE bLoc); + +void NetSendCmdDamage(BOOL bHiPri,BYTE bPlr,DWORD dwDam); +void NetSendCmdMonstDamage(BOOL bHiPri,WORD bMonst,DWORD dwDam); + +typedef struct TCmdPlrInfoHdr { + BYTE bCmd; + WORD wOffset; + WORD wBytes; +} TCmdPlrInfoHdr; + +// better not be bigger than this, the net will choke +#define MAX_SEND_STR_LEN 80 +#define SEND_ALL_MASK 0xffffffff +void NetSendString(DWORD dwSendMask,const char * pszStr); + + +#pragma pack(pop) + + +//****************************************************************** +// net syncing +//****************************************************************** +#pragma pack(push,1) +typedef struct TSyncHeader { + BYTE bCmd; + BYTE bLevel; + WORD wLen; + BYTE bObjId; + BYTE bObjCmd; + BYTE bItemI; + BYTE bItemX; + BYTE bItemY; + WORD wItemIndx; + WORD wItemCI; + int dwItemSeed; + BYTE bItemId; + BYTE bItemDur; + BYTE bItemMDur; + BYTE bItemCh; + BYTE bItemMCh; + WORD wItemVal; + DWORD dwItemBuff; + BYTE bPInvLoc; + WORD wPInvIndx; + WORD wPInvCI; + int dwPInvSeed; + // drb.patch1.start.02/10/97 + BYTE bPInvId; + // drb.patch1.end.02/10/97 + WORD wPLToHit; + WORD wMaxDam; + BYTE bMinStr; + BYTE bMinMag; + BYTE bMinDex; + BYTE bAC; +} TSyncHeader; + +typedef struct TSyncMonster { + BYTE _mndx; + BYTE _mx; + BYTE _my; + BYTE _menemy; + BYTE _mdelta; +} TSyncMonster; +#pragma pack(pop) + + +//****************************************************************** +// msg sizes +//****************************************************************** +#define MIN_MSG_SIZE 128 +#define MAX_MSG_SIZE 512 +extern DWORD gdwNormalMsgSize; // MIN_MSG_SIZE..MAX_MSG_SIZE +extern DWORD gdwLargestMsgSize; // MIN_MSG_SIZE..MAX_MSG_SIZE + + +//****************************************************************** +// net packets (which hold net commands inside them) +//****************************************************************** +#pragma pack(push,1) +typedef struct TPktHdr { + BYTE px; + BYTE py; + BYTE targx; + BYTE targy; + DWORD php; + DWORD pmhp; + BYTE bstr; + BYTE bmag; + BYTE bdex; + WORD wCheck; // @@ debug -- delete this + WORD wLen; // @@ debug -- delete this +} TPktHdr; +typedef struct TPkt { + TPktHdr hdr; + BYTE body[MAX_MSG_SIZE - sizeof TPktHdr]; +} TPkt; +#pragma pack(pop) + + +//****************************************************************** +//****************************************************************** +extern BOOL deltaload; +void DeltaSaveLevel(); +void DeltaLoadLevel(); +void DeltaSendAllLevels(int pnum); +DWORD ParseCmd(int pnum, const TCmd * pCmd); +void DeltaAddItem(int ii); + +// PATCH1.JMM +#if _DEBUG +void __cdecl DROPLOG(const char * pszFmt,...); +void VerifyItemActiveList( void ); +#else +#define VerifyItemActiveList( ) +#define DROPLOG // +#endif +// ENDPATCH1 + diff --git a/MSSCCPRJ.SCC b/MSSCCPRJ.SCC new file mode 100644 index 0000000..e8c4a0b --- /dev/null +++ b/MSSCCPRJ.SCC @@ -0,0 +1,4 @@ +SCC = This is a Source Code Control file + +[Diablo.mak] +SCC_Project_Name = "$/MainSrc", BAAAAAAA diff --git a/MULTI.CPP b/MULTI.CPP new file mode 100644 index 0000000..4a5cecc --- /dev/null +++ b/MULTI.CPP @@ -0,0 +1,1452 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Multi file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/MULTI.CPP 9 4/01/97 5:09p Pwyatt $ +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "storm/h/storm.h" +#include "msg.h" +#include "multi.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "spells.h" +#include "packplr.h" +#include "engine.h" +#include "diabloui.h" +#include "portal.h" + + +//****************************************************************** +// extern +//****************************************************************** +extern char gszHero[]; +extern BOOL gbRunGame; +extern char gszVersionNumber[]; +extern SNETVERSIONDATA gVersion; +extern int gnDifficulty; + + +void tmsg_init(); +void tmsg_free(); +void dthread_init(); +void dthread_free(); +void delta_init(); +void dthread_remove_player(int pnum); +void SetupLocalPlayer(); +void FixPlrWalkTags(int pnum); +void StartStand(int,int); +BOOL wait_delta_info(); +void plrmsg_init(); +void __cdecl sysmsg_add(const char * pszFmt,...); +void sysmsg_add_string(const char * pszMsg); +void game_2_ui_player(const PlayerStruct * p,TPUIHEROINFO heroinfo,BOOL bHasSaveFile); +void nthread_check_snet_error(const char * pszFcn); +DWORD tmsg_get(BYTE * pbMsg,DWORD dwMaxLen); +void tmsg_add(const BYTE * pbMsg,BYTE bLen); +void delta_close_portal(int pnum); +void NewPlrAnim(int pnum, BYTE *pAnim, int numFrames, int Delay, long width); + + +//****************************************************************** +// public +//****************************************************************** +BYTE gbMaxPlayers; +BYTE gbActivePlayers; +BYTE gbGameDestroyed; +BYTE gbSelectProvider; +BYTE gbDeltaSender; +BYTE gbSomebodyWonGameKludge; + +char gszGameName[128]; +char gszGamePass[128]; + + +//****************************************************************** +// private -- packets +//****************************************************************** +// network initialized +static BOOL sgbNetInited = FALSE; + +// did we send an async message in this messaging cycle? +static BOOL sgbSentThisCycle; + +// number of sync messages/game loops -- will be synchronized +// across all systems as new players asychronously join the game +static DWORD sgdwSyncMsgs; +static DWORD sgdwGameLoops; + +// buffers for player information which +// is too big to fit into one packet +// PATCH3.JMM +WORD sgwPackPlrOffsetTbl[MAX_PLRS]; +// ENDPATCH3.JMM +static PkPlayerStruct sgPackPlr[MAX_PLRS]; + +static BYTE sgbPlayerLeftGameTbl[MAX_PLRS]; +static DWORD sgdwPlayerLeftReasonTbl[MAX_PLRS]; +static BYTE sgbSendDeltaTbl[MAX_PLRS]; +static TGAMEDATA sgGameInitInfo; + +// pjw.patch2.start +static BYTE sgbGameJoiner[MAX_PLRS]; +// pjw.patch2.end + +static BYTE sgbTimeout; +static long sglTimeoutStart; + +// time to hang out in timeout state before dropping nonresponsive players +#define DROP_NOTRESPONDING_DELAY (10*1000) // milliseconds + +// time to hang out in timeout state if we're not the master +#define LEAVE_GAME_DELAY (20*1000) // milliseconds + + +//****************************************************************** +// private -- internal buffering +//****************************************************************** +#define MAX_BUF_DATA 4096 +typedef struct TBuffer { + DWORD dwNextWriteOffset; + BYTE bData[MAX_BUF_DATA]; +} TBuffer; +static TBuffer sgLoPriBuf; +static TBuffer sgHiPriBuf; + + +//****************************************************************** +//****************************************************************** +#if TRACEOUT +static DWORD sgdwTraceStartTime; +void __cdecl TraceOut(const char * pszFmt, ...) { + static FILE * f = NULL; + if (! f) f = fopen("c:\\dumphist.txt","wb"); + if (! f) return; + + va_list args; + va_start(args,pszFmt); + DWORD dwCurrTime = GetTickCount() - sgdwTraceStartTime; + fprintf(f,"%4u.%02u ",dwCurrTime / 1000, (dwCurrTime % 1000) / 10); + vfprintf(f,pszFmt,args); + fprintf( + f,"\r\n %x%c %x%c %x%c %x%c\r\n", + gdwMsgStatTbl[0] >> 16,plr[0].plractive ? 'A' : ' ', + gdwMsgStatTbl[1] >> 16,plr[1].plractive ? 'A' : ' ', + gdwMsgStatTbl[2] >> 16,plr[2].plractive ? 'A' : ' ', + gdwMsgStatTbl[3] >> 16,plr[3].plractive ? 'A' : ' ' + ); + va_end(args); + fflush(f); +} +#endif + + +//****************************************************************** +//****************************************************************** +static void buffer_init(TBuffer * pBuf) { + pBuf->dwNextWriteOffset = 0; + pBuf->bData[0] = 0; +} + + +//****************************************************************** +//****************************************************************** +static BOOL buffer_empty(TBuffer * pBuf) { + return pBuf->dwNextWriteOffset == 0; +} + + +//****************************************************************** +//****************************************************************** +static void buffer_add(TBuffer * pBuf,const BYTE * pbMsg,BYTE bLen) { + // is there enough space in the buffer for length byte + data + // plus one more byte for terminating NULL? + if (pBuf->dwNextWriteOffset + bLen + 2 > MAX_BUF_DATA) { + #ifndef NDEBUG + app_fatal("msg buffer failure"); + #endif + return; + } + + // get ptr to curr location, and setup next location + BYTE * pbData = &pBuf->bData[pBuf->dwNextWriteOffset]; + pBuf->dwNextWriteOffset += bLen + 1; + + // write length, data, terminating NULL + *pbData++ = bLen; + CopyMemory(pbData,pbMsg,bLen); + pbData += bLen; + *pbData = 0; +} + + +//****************************************************************** +//****************************************************************** +static BYTE * buffer_get(TBuffer * pBuf,BYTE * pbMsg,DWORD * pdwMaxLen) { + + // is there any data in the buffer? + if (! pBuf->dwNextWriteOffset) + return pbMsg; + + BYTE * pbData = pBuf->bData; + while (1) { + // is there enough space to copy the data from the buffer + BYTE bLen = *pbData; + if (! bLen) break; + if (bLen > *pdwMaxLen) break; + + // skip over the length byte, and copy the data + CopyMemory(pbMsg,++pbData,bLen); + pbData += bLen; + pbMsg += bLen; + *pdwMaxLen -= bLen; + } + + // fixup buffer + MoveMemory( + pBuf->bData, // start of buffer + pbData, // curr position in buffer + pBuf->dwNextWriteOffset - (pbData - pBuf->bData) + 1 + ); + + // fixup buffer write offset + pBuf->dwNextWriteOffset -= (pbData - pBuf->bData); + + return pbMsg; +} + + +//****************************************************************** +//****************************************************************** +static void build_pkt_hdr(TPkt * pkt) { + app_assert(pkt); + pkt->hdr.wCheck = 0x6970; + pkt->hdr.px = plr[myplr]._px; + pkt->hdr.py = plr[myplr]._py; + pkt->hdr.targx = plr[myplr]._ptargx; + pkt->hdr.targy = plr[myplr]._ptargy; + pkt->hdr.php = plr[myplr]._pHitPoints; + pkt->hdr.pmhp = plr[myplr]._pMaxHP; + pkt->hdr.bstr = plr[myplr]._pBaseStr; + pkt->hdr.bmag = plr[myplr]._pBaseMag; + pkt->hdr.bdex = plr[myplr]._pBaseDex; +} + + +//****************************************************************** +//****************************************************************** +void NetSendMyselfPri(const BYTE * pbMsg,BYTE bLen) { + app_assert(sgbNetInited); + if (! pbMsg) return; + if (! bLen) return; + app_assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + tmsg_add(pbMsg,bLen); +} + + +//****************************************************************** +//****************************************************************** +static void NetSendLocal(const BYTE * pbMsg,BYTE bLen) { + app_assert(sgbNetInited); + app_assert(pbMsg); + app_assert(bLen); + app_assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + + // build message + TPkt pkt; + build_pkt_hdr(&pkt); + pkt.hdr.wLen = sizeof(pkt.hdr) + bLen; + CopyMemory(pkt.body,pbMsg,bLen); + + // send it + TRACE_FCN("SNetSendMessage0"); + if (! SNetSendMessage(myplr,&pkt,pkt.hdr.wLen)) + nthread_check_snet_error("SNetSendMessage0"); + TRACE_FCN(NULL); + + #ifndef NDEBUG + extern DWORD gdwAsyncSendTbl[MAX_PLRS]; + gdwAsyncSendTbl[myplr]++; + #endif +} + + +//****************************************************************** +//****************************************************************** +void NetSendLoPri(const BYTE * pbMsg,BYTE bLen) { + app_assert(sgbNetInited); + if (! pbMsg) return; + if (! bLen) return; + app_assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + + // message not sent out of deference to higher priority + // commands which might come later in this message cycle + buffer_add(&sgLoPriBuf,pbMsg,bLen); + NetSendLocal(pbMsg,bLen); +} + + +//****************************************************************** +//****************************************************************** +void NetSendHiPri(const BYTE * pbMsg,BYTE bLen) { + app_assert(sgbNetInited); + if (pbMsg && bLen) { + app_assert(bLen <= gdwNormalMsgSize - sizeof(TPktHdr)); + buffer_add(&sgHiPriBuf,pbMsg,bLen); + NetSendLocal(pbMsg,bLen); + } + + // if we have already sent a message this cycle, then + // we cannot send another until the next cycle. + if (sgbSentThisCycle) + return; + sgbSentThisCycle = TRUE; + + app_assert((DWORD) myplr < MAX_PLRS); + + // setup packet header + TPkt pkt; + build_pkt_hdr(&pkt); + + // fill in packet body + BYTE * pbBody = pkt.body; + DWORD dwBytesLeft = gdwNormalMsgSize - sizeof(pkt.hdr); + pbBody = buffer_get(&sgHiPriBuf,pbBody,&dwBytesLeft); + pbBody = buffer_get(&sgLoPriBuf,pbBody,&dwBytesLeft); + dwBytesLeft = sync_get(pbBody,dwBytesLeft); + DWORD dwSendBytes = gdwNormalMsgSize - dwBytesLeft; + pkt.hdr.wLen = (WORD) dwSendBytes; + + // send it + TRACE_FCN("SNetSendMessage"); + if (! SNetSendMessage(SNET_BROADCASTNONLOCALPLAYERID,&pkt,dwSendBytes)) + nthread_check_snet_error("SNetSendMessage"); + TRACE_FCN(NULL); + + #ifndef NDEBUG + extern DWORD gdwAsyncSendTbl[MAX_PLRS]; + if (myplr != 0) gdwAsyncSendTbl[0]++; + if (myplr != 1) gdwAsyncSendTbl[1]++; + if (myplr != 2) gdwAsyncSendTbl[2]++; + if (myplr != 3) gdwAsyncSendTbl[3]++; + #endif +} + + +//****************************************************************** +//****************************************************************** +void NetSendMask(DWORD dwSendMask,const BYTE * pbMsg,BYTE bLen) { + app_assert(sgbNetInited); + app_assert(pbMsg); + app_assert(bLen); + + // setup packet header + TPkt pkt; + build_pkt_hdr(&pkt); + + // fill in packet body + DWORD dwSendBytes = sizeof(pkt.hdr) + bLen; + app_assert(dwSendBytes < gdwNormalMsgSize); + pkt.hdr.wLen = (WORD) dwSendBytes; + CopyMemory(pkt.body,pbMsg,bLen); + + // send to each player listed in send mask + DWORD dwMaskFlag = 0x1; + for (DWORD dwID = 0; dwID < MAX_PLRS; dwID++,dwMaskFlag <<= 1) { + if (! (dwMaskFlag & dwSendMask)) continue; + + TRACE_FCN("SNetSendMessage"); + BOOL bSent = SNetSendMessage(dwID,&pkt,dwSendBytes); + TRACE_FCN(NULL); + if (bSent) { + #ifndef NDEBUG + extern DWORD gdwAsyncSendTbl[MAX_PLRS]; + gdwAsyncSendTbl[dwID]++; + #endif + continue; + } + + // we don't keep track of players, so we may have sent a + // message to somebody who isn't there anymore. + if (GetLastError() == SNET_ERROR_INVALID_PLAYER) continue; + + nthread_check_snet_error("SNetSendMessage"); + break; + } +} + + +//****************************************************************** +//****************************************************************** +static void NetResync() { + // resync all monster seeds based on current value of game loops + sgdwGameLoops++; + + // reinitialize monster AI seed so that + // all systems can try to resynchronize + DWORD dwSeed = _rotr(sgdwGameLoops,8); + for (int i = 0; i < MAXMONSTERS; i++) + monster[i]._mAISeed = i + dwSeed; + + +#if 0 + if (! lpDDSPrimary) return; + if (sgdwGameLoops % 10) return; + + #define ACCUM_ENTRIES 4 + static DWORD sgdwTime[ACCUM_ENTRIES]; + static DWORD sgdwCount[ACCUM_ENTRIES]; + + MoveMemory(&sgdwTime[0],&sgdwTime[1],sizeof(DWORD) * (ACCUM_ENTRIES-1)); + MoveMemory(&sgdwCount[0],&sgdwCount[1],sizeof(DWORD) * (ACCUM_ENTRIES-1)); + sgdwTime[ACCUM_ENTRIES - 1] = GetTickCount(); + sgdwCount[ACCUM_ENTRIES - 1] = sgdwGameLoops; + + DWORD dwRate = sgdwTime[ACCUM_ENTRIES - 1] - sgdwTime[0]; + if (! dwRate) return; + dwRate = (sgdwCount[ACCUM_ENTRIES - 1] - sgdwCount[0]) * 1000 / dwRate; + + HDC hDC; + char szRate[16]; + sprintf(szRate,"%d",dwRate); + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr != DD_OK) return; + SetTextColor(hDC,0x00ff0000); + TextOut(hDC,0,420,szRate,strlen(szRate)); + lpDDSPrimary->ReleaseDC(hDC); +#endif +} + + +//****************************************************************** +//****************************************************************** +static void check_DeltaSendAllLevels(int nReceiver) { + // the lowest numbered active player is + // responsible for sending the level delta + // information to the new player + for (int nSender = 0; nSender < MAX_PLRS; nSender++) { + // inactive non-player cannot send info + // pjw.patch2.start + if (! (gdwMsgStatTbl[nSender] & SNET_PSF_ACTIVE)) continue; + // pjw.patch2.end + + // player requesting info cannot send info + if (nSender == nReceiver) continue; + + // we found a player who is responsible + break; + } + + if (myplr == nSender) + sgbSendDeltaTbl[nReceiver] = TRUE; + else if (myplr == nReceiver) + gbDeltaSender = (BYTE) nSender; +} + + +//****************************************************************** +//****************************************************************** +static void check_sync(int pnum,DWORD dwSyncMsgs) { + if (dwSyncMsgs & TURN_REQUEST_DELTA_FLAG) { + // player has just joined and needs delta information + check_DeltaSendAllLevels(pnum); + } + + // remove flag bits + dwSyncMsgs &= TURN_COUNTER_MASK; + + // if the other player has sent more sync msgs than we have, + // then recompute the number of game loops which have occurred + // using his msg count to keep both systems synchronized + if (sgdwSyncMsgs < dwSyncMsgs + gdwTurnsInTransit) { + if (dwSyncMsgs >= TURN_COUNTER_MASK) + dwSyncMsgs &= TURN_COUNTER_RESET_MASK; + sgdwSyncMsgs = dwSyncMsgs + gdwTurnsInTransit; + dwSyncMsgs *= ASYNC_CYCLES_PER_SYNC; + dwSyncMsgs *= gbGameLoopsPerPacket; + sgdwGameLoops = dwSyncMsgs; + } +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start +void process_turn() { + for (int i = 0; i < MAX_PLRS; i++) { + if (gdwMsgStatTbl[i] & SNET_PSF_TURNAVAILABLE) { + // make sure we got a valid message + app_assert(glpMsgTbl[i]); + + // odds are we will eventually get a bad packet + if (gdwMsgLenTbl[i] != sizeof(DWORD)) continue; + + // process turn + check_sync(i,*(DWORD *)glpMsgTbl[i]); + } + } +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +static void remove_active_player(int i,BOOL bMsg) { + if (! plr[i].plractive) return; + + #if TRACEOUT + TraceOut("(%d) player %d --> inactive",myplr,i); + #endif + + // remove player from map + void RemovePlrFromMap(int pnum); + RemovePlrFromMap(i); + RemovePortalMissile(i); + DeactivatePortal(i); + delta_close_portal(i); + void RemovePlrMissiles(int pnum); + RemovePlrMissiles(i); + + if (bMsg) { + const char * pszMsg_s = "Player '%s' just left the game"; + switch (sgdwPlayerLeftReasonTbl[i]) { + case SNET_EXIT_NOTRESPONDING: + pszMsg_s = "Player '%s' dropped due to timeout"; + break; + case SNET_EXIT_PLAYERWON: + pszMsg_s = "Player '%s' killed Diablo and left the game!"; + gbSomebodyWonGameKludge = TRUE; + break; + } + sysmsg_add(pszMsg_s,plr[i]._pName); + } + + plr[i].plractive = 0; + plr[i]._pName[0] = 0; + gbActivePlayers--; +} + + +//****************************************************************** +//****************************************************************** +static void update_players() { + for (int i = 0; i < MAX_PLRS; i++) { + // did the player leave the game + if (! sgbPlayerLeftGameTbl[i]) continue; + + if (gbBufferMsgs == BUFFER_ON) { + #if TRACEOUT + TraceOut("(%d) buffering -- player %d left game due to 0x%x",myplr,i,sgdwPlayerLeftReasonTbl[i]); + #endif + void buffer_drop_player(int pnum,DWORD dwReason); + buffer_drop_player(i,sgdwPlayerLeftReasonTbl[i]); + } + else { + #if TRACEOUT + TraceOut("(%d) player %d left game due to 0x%x",myplr,i,sgdwPlayerLeftReasonTbl[i]); + #endif + remove_active_player(i,TRUE); + } + + sgbPlayerLeftGameTbl[i] = FALSE; + sgdwPlayerLeftReasonTbl[i] = 0; + } +} + + +//****************************************************************** +//****************************************************************** +void unbuffer_remove_player(int pnum,DWORD dwReason) { + sgbPlayerLeftGameTbl[pnum] = TRUE; + sgdwPlayerLeftReasonTbl[pnum] = dwReason; + update_players(); +} + + +//****************************************************************** +//****************************************************************** +void NetStartTimeout() { + sgbTimeout = TRUE; + sglTimeoutStart = (long) GetTickCount(); +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start +static void drop_players() { + // kill other players + for (int i = 0; i < MAX_PLRS; i++) { + if (gdwMsgStatTbl[i] & SNET_PSF_RESPONDING) continue; + if (! (gdwMsgStatTbl[i] & SNET_PSF_ACTIVE)) continue; + + #if TRACEOUT + TraceOut("(%d) dropping player %d state 0x%x",myplr,i,gdwMsgStatTbl[i]); + #endif + + // snet drop player will perform a callback to + // our event function to indicate that the player "left" + TRACE_FCN("SNetDropPlayer"); + SNetDropPlayer(i,SNET_EXIT_NOTRESPONDING); + TRACE_FCN(NULL); + } +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start +static void drop_inactive_players() { + // if we're not in a timeout state, don't drop players + if (! sgbTimeout) return; + + // debug mode + #if CHEATS + extern BOOL gbNoDropInactive; + if (gbNoDropInactive) return; + #endif + + // check delay since timeout started + long lCurrTime = (long) GetTickCount(); + lCurrTime -= sglTimeoutStart; + + // if we've been hanging out forever, just exit game + if (lCurrTime > LEAVE_GAME_DELAY) { + gbRunGame = FALSE; + return; + } + + // time to kill other players? + if (lCurrTime < DROP_NOTRESPONDING_DELAY) return; + +// if there are only two players in the game, then the high +// player bails out, and the low player keeps playing. If there +// are three or more players in the game, then the group that has +// the most players keeps playing and the other player(s) bail. + int nLowestActive = -1; + int nLowestPlayer = -1; + BYTE bGroupPlayers = 0; + BYTE bNonGroupPlayers = 0; + for (int i = 0; i < MAX_PLRS; i++) { + if (! (gdwMsgStatTbl[i] & SNET_PSF_ACTIVE)) continue; + + if (nLowestPlayer == -1) nLowestPlayer = i; + + // get player state + if (gdwMsgStatTbl[i] & SNET_PSF_RESPONDING) { + // one more player in our group + bGroupPlayers++; + if (nLowestActive == -1) nLowestActive = i; + } + else { + // one more player not in our group + bNonGroupPlayers++; + } + } + app_assert(bGroupPlayers); + app_assert(nLowestActive != -1); + app_assert(nLowestPlayer != -1); + + + #if 0 + TraceOut( + "(%d) grp:%d ngrp:%d lowp:%d lowa:%d", + myplr, + bGroupPlayers, + bNonGroupPlayers, + nLowestPlayer, + nLowestActive + ); + #endif + + if (bGroupPlayers < bNonGroupPlayers) { + // we're not part of the big group, give up + gbGameDestroyed = TRUE; + } + else if (bGroupPlayers == bNonGroupPlayers) { + if (nLowestPlayer != nLowestActive) + gbGameDestroyed = TRUE; + else if (nLowestActive == myplr) + drop_players(); + } + else if (nLowestActive == myplr) { + drop_players(); + } +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +BOOL NetEndSendCycle() { + app_assert(sgbNetInited); + + if (gbGameDestroyed) { + gbRunGame = FALSE; + return FALSE; + } + + // send delta information to other players + for (int i = 0; i < MAX_PLRS; i++) { + // are we supposed to send somebody delta information? + if (! sgbSendDeltaTbl[i]) continue; + sgbSendDeltaTbl[i] = FALSE; + DeltaSendAllLevels(i); + } + + // fill up the outgoing message queue + // send the number of sync messages we think have been + // sent to other players (and increment by 1 each msg) + BOOL bSendAsync; + sgdwSyncMsgs = nthread_fill_sync_queue(sgdwSyncMsgs,1); + if (! nthread_msg_check(&bSendAsync)) { + drop_inactive_players(); + return FALSE; + } + + // we got some data -- reset timeout mode + sgbTimeout = FALSE; + + if (! bSendAsync) { + // it's not time to send an async message yet + } + else if (! sgbSentThisCycle) { + // we haven't sent any async messages this cycle so + // send a blank message and reset for next cycle + NetSendHiPri(NULL,0); + sgbSentThisCycle = FALSE; + } + else { + // we already sent an async message this cycle + // if there is any high priority stuff + // still in the queue, send the next cycle's + // message immediately + sgbSentThisCycle = FALSE; + if (! buffer_empty(&sgHiPriBuf)) + NetSendHiPri(NULL,0); + } + + // update the monster random number seeds + NetResync(); + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static void process_msg_body(DWORD dwID,const BYTE * pbCmd,DWORD dwBytes) { + while (dwBytes) { + DWORD dwCmdLen = ParseCmd(dwID,(const TCmd *) pbCmd); + // patch3.jmm + // zero is an error condition: + // skip the rest of the packet + if( dwCmdLen == 0 ) { + return; + } + // endpatch3.jmm + + pbCmd += dwCmdLen; + dwBytes -= dwCmdLen; + } +} + + +//****************************************************************** +//****************************************************************** +static void handle_local_msgs() { + DWORD dwLen; + BYTE msg[MAX_MSG_SIZE]; + while (0 != (dwLen = tmsg_get(msg,sizeof(msg)))) + process_msg_body(myplr,msg,dwLen); +} + + +//****************************************************************** +//****************************************************************** +// patch1.jmm +extern DWORD dwRecCount; +// endpatch1.jmm + +void NetReceivePackets() { + DWORD dwID; + LPVOID lpMsg; + DWORD dwMsgSize; + + // make sure all players are dropped ASAP + update_players(); + handle_local_msgs(); + + app_assert(sgbNetInited); + TRACE_FCN("SNetReceiveMessage"); + while (SNetReceiveMessage(&dwID,&lpMsg,&dwMsgSize)) { + TRACE_FCN(NULL); + + // patch1.jmm + dwRecCount++; + // endpatch1.jmm + + // do not dispatch any messages until + // we've dropped players who left the game + update_players(); + + // odds are we will eventually get a bad packet so ignore bad ones + const TPkt * pkt = (const TPkt *) lpMsg; + if (dwMsgSize < sizeof(TPktHdr)) continue; + if (dwID >= MAX_PLRS) continue; + if (pkt->hdr.wCheck != 0x6970) continue; + if (pkt->hdr.wLen != dwMsgSize) continue; + + plr[dwID]._pownerx = pkt->hdr.px; + plr[dwID]._pownery = pkt->hdr.py; + + #ifndef NDEBUG + extern DWORD gdwAsyncRecvTbl[MAX_PLRS]; + gdwAsyncRecvTbl[dwID]++; + #endif + + // the header contains the last known location of the + // player at the time the message was sent. Try to get + // the player to walk to his correct location. Any other + // commands in the message will be executed later and so + // can overwrite the results of this MakePlrPath. + if (dwID != (DWORD) myplr) { + app_assert(gbBufferMsgs != BUFFER_PROCESS); + plr[dwID]._pHitPoints = pkt->hdr.php; + plr[dwID]._pMaxHP = pkt->hdr.pmhp; + plr[dwID]._pBaseStr = pkt->hdr.bstr; + plr[dwID]._pBaseMag = pkt->hdr.bmag; + plr[dwID]._pBaseDex = pkt->hdr.bdex; + if (gbBufferMsgs == BUFFER_ON) { + // do nothing + } + else if (! plr[dwID].plractive) { + // do nothing + } + else if (plr[dwID]._pHitPoints == 0) { + // do nothing + } + else if ((currlevel == plr[dwID].plrlevel) && (!plr[dwID]._pLvlChanging)) { + int dx = abs(plr[dwID]._px - pkt->hdr.px); + int dy = abs(plr[dwID]._py - pkt->hdr.py); + // Is player in "ok delta" dist of where he should be? + if (((dx > 3) || (dy > 3)) && (!dPlayer[pkt->hdr.px][pkt->hdr.py])) { + // Warp player to location + FixPlrWalkTags(dwID); + plr[dwID]._poldx = plr[dwID]._px; + plr[dwID]._poldy = plr[dwID]._py; + FixPlrWalkTags(dwID); + plr[dwID]._px = pkt->hdr.px; + plr[dwID]._py = pkt->hdr.py; + plr[dwID]._pfutx = pkt->hdr.px; + plr[dwID]._pfuty = pkt->hdr.py; + dPlayer[plr[dwID]._px][plr[dwID]._py] = 1 + (char)dwID; + } + dx = abs(plr[dwID]._pfutx - plr[dwID]._px); + dy = abs(plr[dwID]._pfuty - plr[dwID]._py); + if ((dx > 1) || (dy > 1)) { + plr[dwID]._pfutx = plr[dwID]._px; + plr[dwID]._pfuty = plr[dwID]._py; + } + MakePlrPath(dwID, pkt->hdr.targx, pkt->hdr.targy, TRUE); + // do not override destAction + } + else { + plr[dwID]._px = pkt->hdr.px; + plr[dwID]._py = pkt->hdr.py; + plr[dwID]._pfutx = pkt->hdr.px; + plr[dwID]._pfuty = pkt->hdr.py; + plr[dwID]._ptargx = pkt->hdr.targx; + plr[dwID]._ptargy = pkt->hdr.targy; + // do not override destAction + } + } + process_msg_body(dwID,pkt->body,dwMsgSize - sizeof(TPktHdr)); + } + TRACE_FCN(NULL); + +// if (GetLastError() != SNET_ERROR_NO_MESSAGES_WAITING) +// nthread_check_snet_error("SNetReceiveMsg"); +} + + +//****************************************************************** +// NOTE: this routine is called from multiple threads +// don't do anything that would be thread unsafe +//****************************************************************** +void SendPlayerInfoChunk(int pnum,BYTE bCmd,const BYTE * pbSrc,DWORD dwLen) { + app_assert(pnum != myplr); + + // write info piece by piece + app_assert(pbSrc); + app_assert(dwLen <= 0x0ffff); + DWORD dwOffset = 0; + while (dwLen) { + // setup packet header + TPkt pkt; + pkt.hdr.wCheck = 0x6970; + pkt.hdr.px = 0; + pkt.hdr.py = 0; + pkt.hdr.targx = 0; + pkt.hdr.targy = 0; + pkt.hdr.php = 0; + pkt.hdr.pmhp = 0; + pkt.hdr.bstr = 0; + pkt.hdr.bmag = 0; + pkt.hdr.bdex = 0; + + // setup cmd header + TCmdPlrInfoHdr * p = (TCmdPlrInfoHdr *) &pkt.body[0]; + p->bCmd = bCmd; + p->wOffset = (WORD) dwOffset; + + // calculate how much data we can send + DWORD dwBody = gdwLargestMsgSize - sizeof(pkt.hdr) - sizeof(TCmdPlrInfoHdr); + dwBody = min(dwLen,dwBody); + app_assert(dwBody <= 0x0ffff); + p->wBytes = (WORD) dwBody; + + // copy cmd data + CopyMemory(&pkt.body[sizeof TCmdPlrInfoHdr],pbSrc,p->wBytes); + + // send message to target + DWORD dwSendBytes = sizeof(pkt.hdr); + dwSendBytes += sizeof(TCmdPlrInfoHdr); + dwSendBytes += p->wBytes; + pkt.hdr.wLen = (WORD) dwSendBytes; + + TRACE_FCN("SnetSendMessage"); + if (! SNetSendMessage(pnum,&pkt,dwSendBytes)) { + TRACE_FCN(NULL); + nthread_check_snet_error("SNetSendMessage2"); + break; + } + TRACE_FCN(NULL); + + #ifndef NDEBUG + extern DWORD gdwAsyncSendTbl[MAX_PLRS]; + if ((DWORD) pnum < MAX_PLRS) { + gdwAsyncSendTbl[pnum]++; + } + else { + if (myplr != 0) gdwAsyncSendTbl[0]++; + if (myplr != 1) gdwAsyncSendTbl[1]++; + if (myplr != 2) gdwAsyncSendTbl[2]++; + if (myplr != 3) gdwAsyncSendTbl[3]++; + } + #endif + + + // next data section + pbSrc += p->wBytes; + dwLen -= p->wBytes; + dwOffset += p->wBytes; + } +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start -- for patch, changed SendPlayerInfoChunk to +// dthread_SendPlayerInfoChunk to more closely attempt to match the +// available bandwidth. A player with a slow modem joining +// a game with 3 players would have to broadcast ~3k of playerdata, +// clogging the modem and preventing turns from getting out. +void dthread_SendPlayerInfoChunk(int pnum,BYTE bCmd,const BYTE * pbSrc,DWORD dwLen); +static void SendLocalPlayerInfo(int pnum,BYTE bCmd) { + // get local player information and send it to the specified net addr + PkPlayerStruct pack; + PackPlayer(&pack,myplr); + dthread_SendPlayerInfoChunk(pnum,bCmd,(const BYTE *) &pack,sizeof(pack)); +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +static int InitLevelType(int l) { + if (l == 0) return(0); + if ((l >= 1) && (l <= 4)) return(1); + if ((l >= 5) && (l <= 8)) return(2); + if ((l >= 9) && (l <= 12)) return(3); + //return(4); JKE 7/29 + if ((l >=13) && (l <= 16)) return(4); // Original level types JKE + if ((l >= CRYPTSTART) && (l <= CRYPTEND)) return(1); // change this to crypt type later JKE 7/29 + if ((l >= HIVESTART) && (l <= HIVEEND)) return(3); // use this for hives JKE + return(1); +} + + +//****************************************************************** +//****************************************************************** +static void SetupLocalCoords() { + // set the current level to start at the town + if (! leveldebug || gbMaxPlayers > 1) { + currlevel = 0; + leveltype = 0; + setlevel = FALSE; + } + + // put character near house on town level + int x = STARTX; + int y = STARTY; + + #if CHEATS + if (cheatflag || davedebug) { + //x = 25; // Near church + //y = 31; + x = 49; // Near maus + y = 23; + } + #endif + + // adjust character position for character number + // so everyone doesn't start on the same location + extern int plrxoff[9]; + extern int plryoff[9]; + x += plrxoff[myplr]; + y += plryoff[myplr]; + + plr[myplr]._px = x; + plr[myplr]._py = y; + plr[myplr]._pfutx = x; + plr[myplr]._pfuty = y; + plr[myplr]._ptargx = x; + plr[myplr]._ptargy = y; + plr[myplr].plrlevel = currlevel; + plr[myplr]._pLvlChanging = TRUE; + plr[myplr].pLvlLoad = 0; + plr[myplr]._pmode = PM_NEWLVL; + plr[myplr].destAction = PCMD_NOTHING; +} + + +//****************************************************************** +//****************************************************************** +static BOOL handle_upgrade(BOOL * pfExitProgram) { + DWORD dwStatus; + SNetPerformUpgrade(&dwStatus); + switch (dwStatus) { + case SNET_UPGRADE_FAILED: + app_warning("Network upgrade failed"); + break; + + case SNET_UPGRADE_NOT_NEEDED: + // continue game + return TRUE; + + case SNET_UPGRADE_SUCCEEDED: + // continue game + return TRUE; + + case SNET_UPGRADING_TERMINATE: + *pfExitProgram = TRUE; + break; + } + + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +static void CALLBACK net_callback(SNETEVENTPTR pEvt) { + DWORD dwReason; + TGAMEDATA * pGameData; + +// NOTE: this function must be thread-safe since +// it can be called from either the main thread, or during +// the progress screen, called from nthread_*() + switch (pEvt->eventid) { + case SNET_EVENT_INITDATA: + app_assert(pEvt->data); + app_assert(pEvt->databytes >= sizeof(DWORD)); + pGameData = (TGAMEDATA *) pEvt->data; + sgGameInitInfo.dwSeed = pGameData->dwSeed; + sgGameInitInfo.bDiff = pGameData->bDiff; + + // if we get a callback containing init data + // then we cannot be the one who started the game + // pjw.patch2.start + sgbGameJoiner[pEvt->playerid] = TRUE; + //pjw.patch2.end + break; + + case SNET_EVENT_PLAYERLEAVE: + app_assert(pEvt->playerid >= 0 && pEvt->playerid < MAX_PLRS); + sgbPlayerLeftGameTbl[pEvt->playerid] = TRUE; + sgbGameJoiner[pEvt->playerid] = FALSE; + dwReason = 0; + if (pEvt->data && pEvt->databytes >= sizeof(DWORD)) + dwReason = * (DWORD *) pEvt->data; + sgdwPlayerLeftReasonTbl[pEvt->playerid] = dwReason; + + if (dwReason == SNET_EXIT_PLAYERWON) + gbSomebodyWonGameKludge = TRUE; + + // protected by critical section -- OK + sgbSendDeltaTbl[pEvt->playerid] = 0; + dthread_remove_player(pEvt->playerid); + + // was this the guy who was supposed to send us delta info? + if (gbDeltaSender == pEvt->playerid) + gbDeltaSender = MAX_PLRS; + + #if TRACEOUT + TraceOut("(%d) callback: player %d left game due to 0x%x",myplr,pEvt->playerid,dwReason); + #endif + break; + + case SNET_EVENT_SERVERMESSAGE: + app_assert(pEvt->data); + sysmsg_add_string((const char *) pEvt->data); + break; + } +} + + +//****************************************************************** +//****************************************************************** +static void RegisterEventHandler(BOOL bRegister) { + static const DWORD sdwEventTbl[] = { + SNET_EVENT_PLAYERLEAVE, + SNET_EVENT_INITDATA, + SNET_EVENT_SERVERMESSAGE, + }; + + BOOL (__stdcall * fnReg)(DWORD,SNETEVENTPROC) = + bRegister ? SNetRegisterEventHandler : SNetUnregisterEventHandler; + + for (int i = 0; i < sizeof(sdwEventTbl) / sizeof(sdwEventTbl[0]); i++) { + if (! fnReg(sdwEventTbl[i],net_callback) && bRegister) + app_fatal("SNetRegisterEventHandler:\n%s",strGetLastError()); + } +} + + +//****************************************************************** +//****************************************************************** +void NetClose() { + if (sgbNetInited) { + sgbNetInited = FALSE; + nthread_free(); + dthread_free(); + tmsg_free(); + RegisterEventHandler(FALSE); + TRACE_FCN("SNetLeaveGame"); + SNetLeaveGame(SNET_EXIT_AUTO_SHUTDOWN); + TRACE_FCN(NULL); + + #if TRACEOUT + TraceOut("(%d) NetClose",myplr); + #endif + + // give storm enough time to send leave pkt + if (gbMaxPlayers > 1) Sleep(2000); + } +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch2.start +BOOL NetInit(BOOL bSinglePlayer,BOOL * pfExitProgram) { +top_of_routine: + + app_assert(pfExitProgram); + *pfExitProgram = FALSE; + + // get player description + char szPlayerDescript[UI_DESC_MAXLENGTH]; + ZeroMemory(szPlayerDescript,sizeof szPlayerDescript); + if (! bSinglePlayer) { + TUIHEROINFO heroinfo; + myplr = 0; + SetupLocalPlayer(); + game_2_ui_player(&plr[0],&heroinfo,gbValidSaveFile); + if (! UiCreatePlayerDescription(&heroinfo,PROGRAMID,szPlayerDescript)) + return FALSE; + } + + // initialize random seed for game + SetRndSeed(0); + sgGameInitInfo.dwSeed = (DWORD) time(NULL); + sgGameInitInfo.bDiff = (BYTE) gnDifficulty; + + // BUILD A PROGRAM DATA RECORD + SNETPROGRAMDATA progdata; + ZeroMemory(&progdata,sizeof(progdata)); + progdata.size = sizeof(progdata); + #if IS_VERSION(RETAIL) + //progdata.programname = TEXT("Diablo Retail"); + progdata.programname = TEXT("Hellfire Retail"); + #elif IS_VERSION(BETA) + progdata.programname = TEXT("Diablo"); + #elif IS_VERSION(SHAREWARE) + progdata.programname = TEXT("Diablo Shareware"); + #else + #error VERSION NOT DEFINED + #endif + progdata.programdescription = gszVersionNumber; + progdata.programid = PROGRAMID; + progdata.versionid = VERSIONID; + progdata.maxplayers = MAX_PLRS; + progdata.initdata = &sgGameInitInfo.dwSeed; + progdata.initdatabytes = sizeof(sgGameInitInfo); + progdata.optcategorybits = 0x0f; + + // BUILD A PLAYER DATA RECORD + SNETPLAYERDATA plrdata; + ZeroMemory(&plrdata,sizeof(plrdata)); + plrdata.size = sizeof(plrdata); + plrdata.playername = gszHero; + plrdata.playerdescription = szPlayerDescript; + + // BUILD AN INTERFACE DATA RECORD + SNETUIDATA uidata; + ZeroMemory(&uidata,sizeof(SNETUIDATA)); + uidata.size = sizeof(SNETUIDATA); + uidata.parentwindow = SDrawGetFrameWindow(); + uidata.artcallback = UiArtCallback; + uidata.createcallback = UiCreateGameCallback; + uidata.drawdesccallback = UiDrawDescCallback; + uidata.messageboxcallback = UiMessageBoxCallback; + uidata.soundcallback = UiSoundCallback; + uidata.authcallback = UiAuthCallback; + uidata.getdatacallback = UiGetDataCallback; + uidata.categorycallback = UiCategoryCallback; + + // pjw.patch2.start + ZeroMemory(sgbGameJoiner,sizeof(sgbGameJoiner)); + // pjw.patch2.end + gbGameDestroyed = FALSE; + ZeroMemory(sgbPlayerLeftGameTbl,sizeof(sgbPlayerLeftGameTbl)); + ZeroMemory(sgdwPlayerLeftReasonTbl,sizeof(sgdwPlayerLeftReasonTbl)); + ZeroMemory(sgbSendDeltaTbl,sizeof(sgbSendDeltaTbl)); + // pjw.patch1.start + ZeroMemory(plr,sizeof(PlayerStruct) * MAX_PLRS); + // pjw.patch1.end + ZeroMemory(sgwPackPlrOffsetTbl,sizeof(sgwPackPlrOffsetTbl)); + SNetSetBasePlayer(0); + + if (bSinglePlayer) { + if (! SNetInitializeProvider(NULL,&progdata,&plrdata,&uidata,&gVersion)) + app_fatal("SNetInitializeProvider:\n%s",strGetLastError()); + + DWORD dwID = 0; + if (! SNetCreateGame ( + "local", // gamename + "local", // password + "local", // gamedescription + 0, // game category bits + &sgGameInitInfo, // initdata + sizeof(sgGameInitInfo), // initdatabytes + 1, // maxplayers + "local", // playername + "local", // playerdescription + &dwID // playerid + )) app_fatal("SNetCreateGame1:\n%s",strGetLastError()); + app_assert(dwID == 0); + myplr = 0; + gbMaxPlayers = 1; + } + else { + + if (gbSelectProvider) { + BOOL bTryAgain = TRUE; + while (1) { + DWORD dwProviderID; + if (UiSelectProvider(NULL,&progdata,&plrdata,&uidata,&gVersion,&dwProviderID)) + break; + if (! bTryAgain) + return FALSE; + if (GetLastError() != SNET_ERROR_REQUIRES_UPGRADE) + return FALSE; + if (! handle_upgrade(pfExitProgram)) + return FALSE; + bTryAgain = FALSE; + } + } + + RegisterEventHandler(TRUE); + + DWORD dwID; + if (! UiSelectGame(SNET_SF_ALLOWCREATE,&progdata,&plrdata,&uidata,&gVersion,&dwID)) { + app_assert(! *pfExitProgram); + return FALSE; + } + // this happened once, so handle it... + if (dwID >= MAX_PLRS) return FALSE; + + myplr = dwID; + gbMaxPlayers = MAX_PLRS; + } + + #if TRACEOUT + sgdwTraceStartTime = GetTickCount(); + TraceOut("(%d) new game started",myplr); + #endif + + // do various network initializations + sgbNetInited = TRUE; + sgbTimeout = FALSE; + delta_init(); + plrmsg_init(); + buffer_init(&sgHiPriBuf); + buffer_init(&sgLoPriBuf); + sgbSentThisCycle = FALSE; + sync_init(); + // pjw.patch2.start + nthread_init(sgbGameJoiner[myplr]); + // pjw.patch2.end + dthread_init(); + tmsg_init(); + sgdwGameLoops = 0; + sgdwSyncMsgs = 0; + gbDeltaSender = (BYTE) myplr; + gbSomebodyWonGameKludge = FALSE; + + // request everyone's player info + SetupLocalPlayer(); + +// pjw.patch2.start -- added this code so that the first thing +// out of the modem is the turn, not tons of playerdata. If we send +// only playerdata, the modem queue gets filled up, and we don't respond +// fast enough to other players - sometimes causing a timeout + nthread_fill_sync_queue(0,0); +// pjw.patch2.end + + // broadcast our player info to everyone + SetupLocalCoords(); + SendLocalPlayerInfo(SNET_BROADCASTNONLOCALPLAYERID,CMD_SEND_PLRINFO); + + // i'm always active on my system + plr[myplr].plractive = 1; + gbActivePlayers = 1; + + // if we started the game, then we can proceed immediately. + // if we joined the game, we must wait until we receive + // all the level delta information before proceeding + // pjw.patch2.start + if (sgbGameJoiner[myplr] && !wait_delta_info()) { + NetClose(); + gbSelectProvider = FALSE; + goto top_of_routine; // sorry :( + } + // pjw.patch2.end + + // initialize map random number seeds + gnDifficulty = sgGameInitInfo.bDiff; + SetRndSeed(sgGameInitInfo.dwSeed); + for (int i = 0; i < NUMLEVELS; i++) { + glSeedTbl[i] = GetRndSeed(); + gnLevelTypeTbl[i] = InitLevelType(i); + } + + DWORD dwTemp; + if (! SNetGetGameInfo(SNET_INFO_GAMENAME,gszGameName,SNET_MAXNAMELENGTH,&dwTemp)) + nthread_check_snet_error("SNetGetGameInfo1"); + if (! SNetGetGameInfo(SNET_INFO_GAMEPASSWORD,gszGamePass,SNET_MAXNAMELENGTH,&dwTemp)) + nthread_check_snet_error("SNetGetGameInfo2"); + + return TRUE; +} +// pjw.patch2.end + + +//****************************************************************** +//****************************************************************** +void recv_plrinfo(int pnum,const TCmdPlrInfoHdr * p,BOOL bAck) { + // local player is always properly set up + // and doesn't need to be unpacked + if (myplr == pnum) + return; + + app_assert((DWORD)pnum < MAX_PLRS); + + // check for out of order packet + if (sgwPackPlrOffsetTbl[pnum] != p->wOffset) { + sgwPackPlrOffsetTbl[pnum] = 0; + if (p->wOffset != 0) return; + } + + // if this packet came to us unrequested + // and we haven't responded before, + // respond by sending back our plrinfo + if (! bAck && ! sgwPackPlrOffsetTbl[pnum]) + SendLocalPlayerInfo(pnum,CMD_ACK_PLRINFO); + + // copy the message information into a global structure + // until we have received the entire packed player + CopyMemory( + ((BYTE *)&sgPackPlr[pnum]) + p->wOffset, + ((BYTE *)p) + sizeof(TCmdPlrInfoHdr), + p->wBytes + ); + sgwPackPlrOffsetTbl[pnum] += p->wBytes; + + // did we get the entire pack structure yet? + if (sgwPackPlrOffsetTbl[pnum] != sizeof(PkPlayerStruct)) + return; + sgwPackPlrOffsetTbl[pnum] = 0; + + remove_active_player(pnum,FALSE); + plr[pnum]._pGFXLoad = 0; + UnPackPlayer(&sgPackPlr[pnum],pnum, TRUE); + + // if this packet was an acknowledgement to our request + // for character information, then this character must + // already be in the game, so activate him + // Otherwise, this packet was being broadcast by a newbie + // joining the game. Wait until he sends a joinlevel command + // before activating his character + if (bAck) { + plr[pnum].plractive = 1; + gbActivePlayers++; + + // pjw.patch2.start + sysmsg_add( + sgbGameJoiner[pnum] ? + "Player '%s' (level %d) just joined the game" : + "Player '%s' (level %d) is already in the game", + plr[pnum]._pName,plr[pnum]._pLevel + ); + // pjw.patch2.end + + LoadPlrGFX(pnum,PGL_STAND); + SyncInitPlr(pnum); + if (plr[pnum].plrlevel == currlevel) { + if ((plr[pnum]._pHitPoints >> HP_SHIFT) > 0) { + StartStand(pnum,0); + } else { + plr[pnum]._pgfxnum = PGFX_NGUY; + LoadPlrGFX(pnum, PGL_DEAD); + plr[pnum]._pmode = PM_DEATH; + NewPlrAnim(pnum, plr[pnum]._pDAnim[DIR_D], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth); + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1; + plr[pnum]._pVar8 = plr[pnum]._pAnimLen << 1; + dFlags[plr[pnum]._px][plr[pnum]._py] |= BFLAG_DEADPLR; + } + } + + #if TRACEOUT + TraceOut("(%d) making %d active -- recv_plrinfo",myplr,pnum); + #endif + } + else { + #if TRACEOUT + TraceOut("(%d) received all %d plrinfo",myplr,pnum); + #endif + } +} diff --git a/MULTI.H b/MULTI.H new file mode 100644 index 0000000..2126851 --- /dev/null +++ b/MULTI.H @@ -0,0 +1,88 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/MULTI.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + + +//****************************************************************** +// constants +//****************************************************************** +// for every X async messages, we send X/8 sync messages +#define ASYNC_CYCLES_PER_SYNC 4 + +// Near house +#define STARTX 75 +#define STARTY 68 + +#define TURN_REQUEST_DELTA_FLAG 0x80000000 +#define TURN_COUNTER_MASK 0x7fffffff +#define TURN_COUNTER_RESET_MASK 0x0000ffff + + +//****************************************************************** +// variables +//****************************************************************** +extern BYTE gbMaxPlayers; +extern BYTE gbActivePlayers; +extern BYTE gbDropInactive; +extern BYTE gbGameDestroyed; +extern BYTE gbGameLoopsPerPacket; +extern DWORD gdwTurnsInTransit; +extern BYTE gbDeltaSender; +extern char gszGameName[128]; +extern char gszGamePass[128]; + + +enum { + // msg buffering off when program running in normal game mode + BUFFER_OFF = 0, + + // msg buffering on when program waiting for level delta info, + // because program cannot handle any other messages besides deltas + BUFFER_ON, + + // processing msgs which were stored in the message buffer + BUFFER_PROCESS +}; +extern BYTE gbBufferMsgs; + + +// results from receiving the last synchronous turn +extern DWORD gdwMsgLenTbl[MAX_PLRS]; +extern LPVOID glpMsgTbl[MAX_PLRS]; +extern DWORD gdwMsgStatTbl[MAX_PLRS]; + + +//****************************************************************** +// functions +//****************************************************************** +// multi.cpp +BOOL NetInit(BOOL bSinglePlayer,BOOL * pfExitProgram); +void NetClose(); +void NetReceivePackets(); +BOOL NetEndSendCycle(); +void NetDropInactive(); +void process_turn(); + +void NetSendLoPri(const BYTE * pbMsg,BYTE bLen); +void NetSendHiPri(const BYTE * pbMsg,BYTE bLen); +void NetSendMyselfPri(const BYTE * pbMsg,BYTE bLen); +void NetSendMask(DWORD dwSendMask,const BYTE * pbMsg,BYTE bLen); + +// sync.cpp +void sync_init(); +DWORD sync_get(BYTE * pbBuf,DWORD dwMaxLen); +DWORD sync_update(int pnum,const BYTE * pbBuf); + +// nthread.cpp +void nthread_init(BOOL bRequestDelta); +void nthread_free(); +BOOL nthread_run_gameloop(BOOL bReloop); +void nthread_perform_keepalive(BOOL bStart); +DWORD nthread_fill_sync_queue(DWORD dwCounter,DWORD dwIncrement); +BOOL nthread_msg_check(BOOL * pfSendAsync); diff --git a/NTHREAD.CPP b/NTHREAD.CPP new file mode 100644 index 0000000..465b438 --- /dev/null +++ b/NTHREAD.CPP @@ -0,0 +1,705 @@ +//****************************************************************** +// nthread.cpp +// contains network code which runs in either main thread +// or auxiliary "progress" thread +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include +#include "storm/h/storm.h" +#include "msg.h" +#include "multi.h" +#include "gendung.h" +#include "sound.h" +#include "items.h" +#include "player.h" + + +//****************************************************************** +// debugging +//****************************************************************** +#define PRINT_STATUS 1 // 0 in final +#define STATUS_LASTERR 0 // 0 in final +#define DUMP_STATUS 0 // 0 in final + +#ifdef NDEBUG +#undef PRINT_STATUS +#undef STATUS_LASTERR +#undef DUMP_STATUS +#define PRINT_STATUS 0 +#define STATUS_LASTERR 0 +#define DUMP_STATUS 0 +#endif + + +//****************************************************************** +// public +//****************************************************************** +BYTE gbGameLoopsPerPacket; +DWORD gdwTurnsInTransit; +DWORD gdwNormalMsgSize; // MIN_MSG_SIZE..MAX_MSG_SIZE +DWORD gdwLargestMsgSize; // MIN_MSG_SIZE..MAX_MSG_SIZE +DWORD gdwDeltaBytesSec; + + +// results from receiving the last synchronous turn +DWORD gdwMsgLenTbl[MAX_PLRS]; +DWORD gdwMsgStatTbl[MAX_PLRS]; +LPVOID glpMsgTbl[MAX_PLRS]; + +#ifndef NDEBUG +DWORD gdwAsyncRecvTbl[MAX_PLRS]; +DWORD gdwAsyncSendTbl[MAX_PLRS]; +#endif + + +//****************************************************************** +// private -- packets +//****************************************************************** +static DWORD sgdwRequestDeltaFlag; + +static BYTE sgbRunThread; +static BYTE sgbThreadIsRunning; +static CCritSect sgCrit; +static HANDLE sghThread = INVALID_HANDLE_VALUE; +static unsigned sgThreadID; + +// are we waiting for a packet? +static BYTE sgbGotPacketOK; + +// countdown timer to the next time we need to send an +// async packet and value to initialize countdown timer +static BYTE sgbPacketCountdown; + +// countdown timer for synchronous message +static BYTE sgbSyncCountdown; + +// timer which marches forward to match the real time clock +// used to determine when to run game loops +static long sglGameClock = 0; + +// if game clock and the real clock differ by more than CATCH_UP_DELTA +// then reset the game clock to be equal to the real clock. This ensures +// that the game will attempt to maintain a normal frame rate, but if it +// falls too far outside normal bounds, it will not struggle indefinitely. +#define CATCH_UP_DELTA 500 // milliseconds + + +#if PRINT_STATUS +static BYTE sgbPrintStatus; +static DWORD sgdwPrintTime; +#if STATUS_LASTERR +static DWORD sgdwPrintTbl[MAX_PLRS]; +#endif +#endif + +#if DUMP_STATUS +static BYTE sgbDumpStatus; +static BYTE sgbDumpStatusOK; +static BYTE sbDumpInit = TRUE; +#endif + +#if ALLOW_TRACE_FCN +static BYTE sgbTraceFcn; +static const char * sgpszLastTrace; +#endif + + +//****************************************************************** +//****************************************************************** +#if ALLOW_TRACE_FCN +void trace_fcn(const char * pszFcn) { + // don't write stuff if we're not the active application + if (! bActive) return; + if (! sgbTraceFcn) return; + if (! lpDDSPrimary) return; + if (sgpszLastTrace == pszFcn) return; + sgpszLastTrace = pszFcn; + + // ooh -- how cheesy... + if (! pszFcn) pszFcn = " "; + + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr != DD_OK) return; + TextOut(hDC,5,370,pszFcn,strlen(pszFcn)); + lpDDSPrimary->ReleaseDC(hDC); +} +#endif + + +//****************************************************************** +//****************************************************************** +void nthread_check_snet_error(const char * pszFcn) { + app_assert(pszFcn); + DWORD dwErr = GetLastError(); + // we don't keep track of players, so we may have sent a + // message to somebody who isn't there anymore. + if (dwErr == SNET_ERROR_INVALID_PLAYER) + NULL; + else if (dwErr == SNET_ERROR_GAME_TERMINATED) + gbGameDestroyed = TRUE; + else if (dwErr == SNET_ERROR_NOT_IN_GAME) + gbGameDestroyed = TRUE; + else + app_fatal("%s:\n%s",pszFcn,strGetLastError()); +} + + +//****************************************************************** +//****************************************************************** +#ifdef _DEBUG +BOOL is_pat_debug_cmd(WPARAM wKey) { + // only a debug key if the control key is down + if (! (GetKeyState(VK_CONTROL) & 0x8000)) + return FALSE; + + switch (wKey) { + + case 0x03: // ctrl - break; + // debugger + if (!fullscreen) { + void myDebugBreak(); + myDebugBreak(); + force_redraw = FULLDRAW; + } + break; + + case 0x13: // ctrl - S + // stall the network by sleeping + Sleep(50); + break; + + #if PRINT_STATUS && STATUS_LASTERR + case 0x12: // ctrl - R + ZeroMemory(sgdwPrintTbl,sizeof(sgdwPrintTbl)); + break; + #endif + + #if PRINT_STATUS + case 0x10: // ctrl - P + // toggle print status + sgbPrintStatus = !sgbPrintStatus; + sgdwPrintTime = GetTickCount(); + break; + #endif + + #if DUMP_STATUS + case 0x4: // ctrl - D + sgbDumpStatus = !sgbDumpStatus; + sgbDumpStatusOK = TRUE; + sbDumpInit = TRUE; + + #if PRINT_STATUS + sgbPrintStatus = sgbDumpStatus; + #endif + break; + #endif + + #if ALLOW_TRACE_FCN + case 0xa: // ctrl - J + sgbTraceFcn = !sgbTraceFcn; + sgpszLastTrace = NULL; + break; + #endif + + default: + return FALSE; + } + + return TRUE; +} +#endif + + +//****************************************************************** +//****************************************************************** +DWORD nthread_fill_sync_queue(DWORD dwCounter,DWORD dwIncrement) { + // MAKE SURE THERE ARE ALWAYS SEVERAL SYNC TURNS IN TRANSIT + DWORD turns; + + TRACE_FCN("SNetGetTurnsInTransit"); + if (! SNetGetTurnsInTransit(&turns)) { + TRACE_FCN(NULL); + nthread_check_snet_error("SNetGetTurnsInTransit"); + return 0; + } + TRACE_FCN(NULL); + + app_assert(gdwTurnsInTransit); + while (turns++ < gdwTurnsInTransit) { + + // counter = low 31 bits + // hi bit = request delta flag or zero + // reset flag after first use + DWORD dwTemp = dwCounter & TURN_COUNTER_MASK; + dwTemp |= sgdwRequestDeltaFlag; + sgdwRequestDeltaFlag = 0; + + // send turn + TRACE_FCN("SNetSendTurn"); + if (! SNetSendTurn(&dwTemp,sizeof dwTemp)) { + TRACE_FCN(NULL); + nthread_check_snet_error("SNetSendTurn"); + return 0; + } + TRACE_FCN(NULL); + + // increment counter and reset wraparound + dwCounter += dwIncrement; + if (dwCounter >= TURN_COUNTER_MASK) + dwCounter &= TURN_COUNTER_RESET_MASK; + } + + return dwCounter; +} + + +//****************************************************************** +//****************************************************************** +#if DUMP_STATUS +void __cdecl dump_string(const char * pszFmt,...) { + app_assert(pszFmt); + + // open dumpfile + FILE * f = fopen("c:\\netdump.txt",sbDumpInit ? "wb" : "ab"); + if (! f) return; + sbDumpInit = FALSE; + + va_list args; + va_start(args,pszFmt); + vfprintf(f,pszFmt,args); + va_end(args); + + fclose(f); +} +#endif + + +//****************************************************************** +//****************************************************************** +#if DUMP_STATUS +static void DumpStatus() { + // don't write stuff if we're not the active application + if (! bActive) return; + + for (int i = 0; i < MAX_PLRS; i++) { + if (! (gdwMsgStatTbl[i] & SNET_PSF_RESPONDING)) + break; + } + + if (i >= MAX_PLRS) { + if (sgbDumpStatusOK) return; + sgbDumpStatusOK = TRUE; + } + else { + sgbDumpStatusOK = FALSE; + } + + // create status string + char szBuf[64]; + char * pszBuf = szBuf; + for (i = 0; i < MAX_PLRS; i++) { + if (i == myplr) *pszBuf++ = '>'; + *pszBuf++ = (char) (gdwMsgStatTbl[i] >> 16) + '0'; + if (plr[i].plractive) *pszBuf++ = '*'; + *pszBuf++ = ' '; + } + pszBuf--; + *pszBuf++ = '\r'; + *pszBuf++ = '\n'; + *pszBuf = 0; + dump_string(szBuf); +} +#endif + + +//****************************************************************** +//****************************************************************** +#if PRINT_STATUS +static void print_status() { + + // don't write stuff if we're not the active application + if (! bActive) return; + + // create status string + char szBuf[128]; + char * pszBuf = szBuf; + for (int i = 0; i < MAX_PLRS; i++) { + *pszBuf++ = (i == myplr) ? '<' : ' '; + #if STATUS_LASTERR + *pszBuf++ = (char) (sgdwPrintTbl[i] >> 16) + '0'; + #else + *pszBuf++ = (char) (gdwMsgStatTbl[i] >> 16) + '0'; + #endif + *pszBuf++ = plr[i].plractive ? 'A' : 'I'; + *pszBuf++ = (i == myplr) ? '>' : ' '; + } + *pszBuf++ = ' '; + *pszBuf = 0; + + if (! lpDDSPrimary) return; + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr != DD_OK) return; + COLORREF oldTextColor = SetTextColor(hDC,RGB(0xff,0xff,0)); + COLORREF oldBkColor = SetBkColor(hDC,RGB(0,0,0)); + int oldBkMode = SetBkMode(hDC,OPAQUE); + TextOut(hDC,5,385,szBuf,strlen(szBuf)); + + #ifndef NDEBUG + sprintf(szBuf,"%02x %02x %02x %02x", + gdwAsyncRecvTbl[0] & 0xff, + gdwAsyncRecvTbl[1] & 0xff, + gdwAsyncRecvTbl[2] & 0xff, + gdwAsyncRecvTbl[3] & 0xff + ); + TextOut(hDC,5,400,szBuf,strlen(szBuf)); + sprintf(szBuf,"%02x %02x %02x %02x", + gdwAsyncSendTbl[0] & 0xff, + gdwAsyncSendTbl[1] & 0xff, + gdwAsyncSendTbl[2] & 0xff, + gdwAsyncSendTbl[3] & 0xff + ); + TextOut(hDC,5,415,szBuf,strlen(szBuf)); + #endif + + static DWORD foo = 0; + sprintf(szBuf,"%d",foo++); + TextOut(hDC,5,430,szBuf,strlen(szBuf)); +/* + DWORD dwCurrTime = GetTickCount(); + if (dwCurrTime - sgdwPrintTime >= 1000) { + sgdwPrintTime = dwCurrTime; + + DWORD dwTurn,dwBytes; + SNetGetPerformanceData(SNET_PERFID_TURN,&dwTurn,NULL,NULL,NULL,NULL); + sprintf(szBuf,"turn: 0x%08x ",dwTurn); + TextOut(hDC,5,400,szBuf,strlen(szBuf)); + + static DWORD sgdwLastBytes; + SNetGetPerformanceData(SNET_PERFID_BYTESSENTONWIRE,&dwBytes,NULL,NULL,NULL,NULL); + sprintf(szBuf,"bytes: %8d ",dwBytes - sgdwLastBytes); + sgdwLastBytes = dwBytes; + TextOut(hDC,5,415,szBuf,strlen(szBuf)); + + DWORD dwUser,dwTotal; + static DWORD sdwLastUser; + static DWORD sdwLastTotal; + SNetGetPerformanceData(SNET_PERFID_USERBYTESSENT,&dwUser,NULL,NULL,NULL,NULL); + SNetGetPerformanceData(SNET_PERFID_TOTALBYTESSENT,&dwTotal,NULL,NULL,NULL,NULL); + dwBytes = dwTotal - sdwLastTotal; + if (! dwBytes) dwBytes = 1; + dwBytes = ((dwUser - sdwLastUser) * 100) / dwBytes; + sdwLastUser = dwUser; + sdwLastTotal = dwTotal; + sprintf(szBuf,"user: %3d%% ",dwBytes); + TextOut(hDC,5,430,szBuf,strlen(szBuf)); + } +*/ + + SetTextColor(hDC,oldTextColor); + SetBkColor(hDC,oldBkColor); + SetBkMode(hDC,oldBkMode); + lpDDSPrimary->ReleaseDC(hDC); +} +#endif + + +//****************************************************************** +//****************************************************************** +BOOL nthread_msg_check(BOOL * pfSendAsync) { + app_assert(pfSendAsync); + *pfSendAsync = FALSE; + + #if PRINT_STATUS + if (sgbPrintStatus) print_status(); + #endif + + // count down until time to send async packet + app_assert(sgbPacketCountdown); + if (--sgbPacketCountdown) { + // advance the game clock to the next + // time we will need to run a game loop + sglGameClock += 1000 / GAME_FRAMES_PER_SECOND; + return TRUE; + } + + // reset async countdown timer + sgbPacketCountdown = gbGameLoopsPerPacket; + + // is it time to receive sync message? + app_assert(sgbSyncCountdown); + if (! --sgbSyncCountdown) { + TRACE_FCN("SNetReceiveTurns"); + if (! SNetReceiveTurns(0,MAX_PLRS,glpMsgTbl,gdwMsgLenTbl,gdwMsgStatTbl)) { + TRACE_FCN(NULL); + DWORD dwErr = GetLastError(); + if (dwErr != SNET_ERROR_NO_MESSAGES_WAITING) + nthread_check_snet_error("SNetReceiveTurns"); + + // we didn't successfully receive a turn, so go run some + // user stuff, and come back here to try again next time + sgbPacketCountdown = sgbSyncCountdown = 1; + + #if PRINT_STATUS && STATUS_LASTERR + // copy results of last bad status info to private table + CopyMemory(sgdwPrintTbl,gdwMsgStatTbl,sizeof(sgdwPrintTbl)); + #endif + + #if DUMP_STATUS + DumpStatus(); + #endif + + sgbGotPacketOK = 0; + return FALSE; + } + else if (! sgbGotPacketOK) { + TRACE_FCN(NULL); + // we were waiting for the packet. Since + // there should be a bunch of messages in the + // queue, we should never have to wait. + sgbGotPacketOK = 1; + sglGameClock = GetTickCount(); + + #if DUMP_STATUS + DumpStatus(); + #endif + } + else { + TRACE_FCN(NULL); + } + + // reset sync countdown timer + sgbSyncCountdown = ASYNC_CYCLES_PER_SYNC; + + // process synchronous turn + process_turn(); + } + + // it's time to send an async message + *pfSendAsync = TRUE; + + // advance the game clock to the next + // time we will need to run a game loop + sglGameClock += 1000 / GAME_FRAMES_PER_SECOND; + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static unsigned __stdcall net_thread_proc(void *) { + long lDelta; + + while (sgbRunThread) { + sgCrit.Enter(); + + // if nthread_free() was called, it may have released the + // critical section so that this thread could run. However, + // we're just supposed to get out of here... + if (! sgbRunThread) { + sgCrit.Leave(); + return 0; + } + + // fill queue with minimum number of synchronous + // messages before we attempt to read any + BOOL bSendAsync; + nthread_fill_sync_queue(0,0); + if (nthread_msg_check(&bSendAsync)) { + // sleep until it is approximately time + // to send the next synchronous turn + lDelta = sglGameClock - (long) GetTickCount(); + } + else { + // we are waiting for a message from one of the other players + // since it is not here yet, sleep for a longish while so + // that we don't do any busy waiting + lDelta = 1000 / GAME_FRAMES_PER_SECOND; + } + sgCrit.Leave(); + if (lDelta > 0) Sleep(lDelta); + + // pjw.patch2.start + #if CHEATS + static DWORD sdwSkips = 0; + sdwSkips++; + if (lpDDSPrimary) + { + HDC hDC; + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr == DD_OK) { + char szBuf[16]; + wsprintf(szBuf,"n:%u",sdwSkips); + TextOut(hDC,5,440,szBuf,strlen(szBuf)); + lpDDSPrimary->ReleaseDC(hDC); + } + } + #endif + // pjw.patch2.end + } + + return 0; +} + + +//****************************************************************** +//****************************************************************** +void nthread_set_delta_request() { + sgdwRequestDeltaFlag = TURN_REQUEST_DELTA_FLAG; +} + + +//****************************************************************** +//****************************************************************** +void nthread_init(BOOL bRequestDelta) { + // start game clock and countdown timers + sglGameClock = GetTickCount(); + sgbPacketCountdown = 1; + sgbSyncCountdown = 1; + sgbGotPacketOK = 1; + if (bRequestDelta) nthread_set_delta_request(); + else sgdwRequestDeltaFlag = 0; + + // calculate the number of packets we should send + // per game loop based on the provider latency + SNETCAPS caps; + caps.size = sizeof caps; + if (! SNetGetProviderCaps(&caps)) + app_fatal("SNetGetProviderCaps:\n%s",strGetLastError()); + + // find out how many messages we should put into the queue + if (caps.defaultturnsintransit) + gdwTurnsInTransit = caps.defaultturnsintransit; + else + gdwTurnsInTransit = 1; + + // calculate the number of game loops to run per packet + // based on the speed of the network connection + if (caps.defaultturnssec > GAME_FRAMES_PER_SECOND || ! caps.defaultturnssec) + gbGameLoopsPerPacket = 1; + else + gbGameLoopsPerPacket = (BYTE) (GAME_FRAMES_PER_SECOND / caps.defaultturnssec); + + // size of largest packet which can be sent over network + gdwLargestMsgSize = min(caps.maxmessagesize,MAX_MSG_SIZE); + app_assert(gdwLargestMsgSize >= MIN_MSG_SIZE); + + // calculate how big our messages can be based on the available + // bandwidth and the number of messages we'll be sending per turn + // (bytes/sec) * (frames/pkt) / (frames/sec) = (bytes/pkt) + gdwNormalMsgSize = caps.bytessec * gbGameLoopsPerPacket / GAME_FRAMES_PER_SECOND; + + // use 1/4 of the channel for sending delta info to other players + gdwDeltaBytesSec = caps.bytessec * 1 / 4; + + // use 3/4 of channel for player messages + gdwNormalMsgSize *= 3; + gdwNormalMsgSize /= 4; + + // Divide by the number of players since we have to send a msg to each + // NOTE: we could subtract out the local player, since we send no + // info over the wire to local system, but leave this entry in + // to allow for "overhead" + app_assert(caps.maxplayers); + if (caps.maxplayers > MAX_PLRS) caps.maxplayers = MAX_PLRS; + gdwNormalMsgSize /= caps.maxplayers; + + // if our packet is too small, send fewer messages per turn + while (gdwNormalMsgSize < MIN_MSG_SIZE) { + gdwNormalMsgSize *= 2; + gbGameLoopsPerPacket *= 2; + } + + // bounds check maximum value + if (gdwNormalMsgSize > gdwLargestMsgSize) + gdwNormalMsgSize = gdwLargestMsgSize; + + // create synchronization object for thread + if (gbMaxPlayers > 1) { + sgbThreadIsRunning = FALSE; + sgCrit.Enter(); + + // create loader thread + sgbRunThread = TRUE; + app_assert(sghThread == INVALID_HANDLE_VALUE); + sghThread = (HANDLE) _beginthreadex( + NULL, // no security info + 0, // stack size + net_thread_proc, // start address + NULL, // argument list + 0, // initial state + &sgThreadID // sgThreadID + ); + if (sghThread == INVALID_HANDLE_VALUE) + app_fatal(TEXT("nthread2:\n%s"),strGetLastError()); + + // make sure this thread runs at higher priority than + // SFile, and at the same priority as SNet + SetThreadPriority(sghThread,THREAD_PRIORITY_HIGHEST); + } +} + + +//****************************************************************** +//****************************************************************** +void nthread_free() { + // kill off the thread + sgbRunThread = FALSE; + + // set parameters to invalid values + gdwTurnsInTransit = 0; + gdwNormalMsgSize = 0; + gdwLargestMsgSize = 0; + + // wait until it finishes + if (sghThread != INVALID_HANDLE_VALUE) { + if (sgThreadID != GetCurrentThreadId()) { + if (! sgbThreadIsRunning) sgCrit.Leave(); + if (WAIT_FAILED == WaitForSingleObject(sghThread,INFINITE)) + app_fatal(TEXT("nthread3:\n(%s)"),strGetLastError()); + CloseHandle(sghThread); + sghThread = INVALID_HANDLE_VALUE; + } + } +} + + +//****************************************************************** +//****************************************************************** +void nthread_perform_keepalive(BOOL bStart) { + if (sghThread == INVALID_HANDLE_VALUE) + return; + app_assert(sgbThreadIsRunning != bStart); + + if (bStart) { + // allow thread to run + sgCrit.Leave(); + } + else { + // prevent thread from running + sgCrit.Enter(); + } + + sgbThreadIsRunning = bStart; +} + + +//****************************************************************** +//****************************************************************** +BOOL nthread_run_gameloop(BOOL bReloop) { + long lRealClock = (long) GetTickCount(); + long lDelta = lRealClock - sglGameClock; + + // if it has been too long since we last ran a game loop, + // then pretend we have caught up and are running normally + if (gbMaxPlayers == 1 && lDelta > CATCH_UP_DELTA) { + sglGameClock = lRealClock; + lDelta = 0; + } + + return (lDelta >= 0); +} diff --git a/Newstm/STORM.H b/Newstm/STORM.H new file mode 100644 index 0000000..42aa011 --- /dev/null +++ b/Newstm/STORM.H @@ -0,0 +1,3332 @@ +#ifndef _STORM_H_ +#define _STORM_H_ + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +//#########################################################################// +//#########################################################################// +// // +// // +// STANDARD PROGRAMMING INTERFACE // +// // +// // +//#########################################################################// +//#########################################################################// + + +#define DECLARE_STRICT_HANDLE(name) typedef struct name##__ { int unused; } *name +#define DECLARE_DERIVED_HANDLE(name,base) typedef struct name##__ : public base##__ { int unused; } *name + + +/**************************************************************************** +* +* Error codes +* (Error text is defined in Stormerr.mc) +* +***/ + +#define STORMFAC 0x510 +#define STORMERROR(code) (0x80000000 | (STORMFAC << 16) | ((code) & 0xFFFF)) + +#define STORM_ERROR_ASSERTION STORMERROR(0) +#define STORM_ERROR_BAD_ARGUMENT STORMERROR(101) +#define STORM_ERROR_GAME_ALREADY_STARTED STORMERROR(102) +#define STORM_ERROR_GAME_FULL STORMERROR(103) +#define STORM_ERROR_GAME_NOT_FOUND STORMERROR(104) +#define STORM_ERROR_GAME_TERMINATED STORMERROR(105) +#define STORM_ERROR_INVALID_PLAYER STORMERROR(106) +#define STORM_ERROR_NO_MESSAGES_WAITING STORMERROR(107) +#define STORM_ERROR_NOT_ARCHIVE STORMERROR(108) +#define STORM_ERROR_NOT_ENOUGH_ARGUMENTS STORMERROR(109) +#define STORM_ERROR_NOT_IMPLEMENTED STORMERROR(110) +#define STORM_ERROR_NOT_IN_ARCHIVE STORMERROR(111) +#define STORM_ERROR_NOT_IN_GAME STORMERROR(112) +#define STORM_ERROR_NOT_INITIALIZED STORMERROR(113) +#define STORM_ERROR_NOT_PLAYING STORMERROR(114) +#define STORM_ERROR_NOT_REGISTERED STORMERROR(115) +#define STORM_ERROR_REQUIRES_CODEC STORMERROR(116) +#define STORM_ERROR_REQUIRES_DDRAW STORMERROR(117) +#define STORM_ERROR_REQUIRES_DSOUND STORMERROR(118) +#define STORM_ERROR_REQUIRES_UPGRADE STORMERROR(119) +#define STORM_ERROR_STILL_ACTIVE STORMERROR(120) +#define STORM_ERROR_VERSION_MISMATCH STORMERROR(121) +#define STORM_ERROR_MEMORY_ALREADY_FREED STORMERROR(122) +#define STORM_ERROR_MEMORY_CORRUPT STORMERROR(123) +#define STORM_ERROR_MEMORY_INVALID_BLOCK STORMERROR(124) +#define STORM_ERROR_MEMORY_MANAGER_INACTIVE STORMERROR(125) +#define STORM_ERROR_MEMORY_NEVER_RELEASED STORMERROR(126) +#define STORM_ERROR_HANDLE_NEVER_RELEASED STORMERROR(127) +#define STORM_ERROR_ACCESS_OUT_OF_BOUNDS STORMERROR(128) +#define STORM_ERROR_MEMORY_NULL_POINTER STORMERROR(129) + + +/**************************************************************************** +* +* BitBlt functions +* +***/ + +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SBltDestroy (); +#endif +extern "C" BOOL APIENTRY SBltGetSCode (DWORD rop3, + LPSTR buffer, + DWORD buffersize, + BOOL optimize = 1); +extern "C" BOOL APIENTRY SBltROP3 (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + DWORD pattern, + DWORD rop3); +extern "C" BOOL APIENTRY SBltROP3Clipped (LPBYTE dest, + LPRECT destrect, + LPSIZE destsize, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + LPSIZE sourcesize, + int sourcepitch, + DWORD pattern, + DWORD rop3); +extern "C" BOOL APIENTRY SBltROP3Tiled (LPBYTE dest, + LPRECT destrect, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + int sourcepitch, + int sourceoffsetx, + int sourceoffsety, + DWORD pattern, + DWORD rop3); + + +/**************************************************************************** +* +* Bitmap functions +* +***/ + +#define SBMP_IMAGETYPE_AUTO 0 +#define SBMP_IMAGETYPE_BMP 1 +#define SBMP_IMAGETYPE_PCX 2 + +typedef LPVOID (APIENTRY *SBMPALLOCPROC)(DWORD); + +extern "C" BOOL APIENTRY SBmpAllocLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE *returnedbuffer, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL, + int requestedbitdepth = 0, + SBMPALLOCPROC allocproc = NULL); +extern "C" BOOL APIENTRY SBmpDecodeImage (DWORD imagetype, + LPBYTE imagedata, + DWORD imagebytes, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SBmpLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SBmpSaveImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + int width, + int height, + int bitdepth); + + +/**************************************************************************** +* +* Command line parsing functions +* +***/ + +#define SCMD_ARG_FLAGGED (0 << 24) +#define SCMD_ARG_OPTIONAL (1 << 24) +#define SCMD_ARG_REQUIRED (2 << 24) +#define SCMD_ARG_MASK (SCMD_ARG_FLAGGED | SCMD_ARG_OPTIONAL | SCMD_ARG_REQUIRED) + +#define SCMD_BOOL_SET 0 +#define SCMD_BOOL_CLEAR 1 +#define SCMD_BOOL_MASK (SCMD_BOOL_CLEAR | SCMD_BOOL_SET) + +#define SCMD_CASESENSITIVE (0x01 << 8) + +#define SCMD_NUM_UNSIGNED 0 +#define SCMD_NUM_SIGNED 1 +#define SCMD_NUM_MASK (SCMD_NUM_UNSIGNED | SCMD_NUM_SIGNED) + +#define SCMD_TYPE_BOOL (0 << 16) +#define SCMD_TYPE_NUMERIC (1 << 16) +#define SCMD_TYPE_STRING (2 << 16) +#define SCMD_TYPE_MASK (SCMD_TYPE_BOOL | SCMD_TYPE_NUMERIC | SCMD_TYPE_STRING) + +#define SCMD_ERROR_BAD_ARGUMENT STORM_ERROR_BAD_ARGUMENT +#define SCMD_ERROR_NOT_ENOUGH_ARGUMENTS STORM_ERROR_NOT_ENOUGH_ARGUMENTS +#define SCMD_ERROR_OPEN_FAILED ERROR_OPEN_FAILED + +typedef struct _CMDERROR { + DWORD errorcode; + LPCTSTR itemstr; + LPCTSTR errorstr; +} CMDERROR, *CMDERRORPTR; + +typedef struct _CMDPARAMS { + DWORD flags; + DWORD id; + LPCTSTR name; + LPVOID variable; + DWORD setvalue; + DWORD setmask; + union { + BOOL boolvalue; + LONG signedvalue; + DWORD unsignedvalue; + LPCTSTR stringvalue; + }; +} CMDPARAMS, *CMDPARAMSPTR; + +typedef BOOL (CALLBACK *SCMDCALLBACK)(CMDPARAMSPTR,LPCTSTR); +typedef void (CALLBACK *SCMDERRORCALLBACK)(CMDERRORPTR); +typedef BOOL (CALLBACK *SCMDEXTRACALLBACK)(LPCTSTR); + +typedef struct _ARGLIST { + DWORD flags; + DWORD id; + LPCTSTR name; + SCMDCALLBACK callback; +} ARGLIST, *ARGLISTPTR; + +extern "C" BOOL APIENTRY SCmdCheckId (DWORD id); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SCmdDestroy (); +#endif +extern "C" BOOL APIENTRY SCmdGetBool (DWORD id); +extern "C" DWORD APIENTRY SCmdGetNum (DWORD id); +extern "C" BOOL APIENTRY SCmdGetString (DWORD id, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SCmdProcess (LPCTSTR cmdline, + BOOL skipprogname, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback); +extern "C" BOOL APIENTRY SCmdRegisterArgList (const ARGLIST *listptr, + DWORD numargs); +extern "C" BOOL APIENTRY SCmdRegisterArgument (DWORD flags, + DWORD id, + LPCTSTR name, + LPVOID variableptr = NULL, + DWORD variablebytes = 0, + DWORD setvalue = TRUE, + DWORD setmask = 0xFFFFFFFF, + SCMDCALLBACK callback = NULL); + +#define SCmdProcessCommandLine(ext,err) SCmdProcess(GetCommandLine(),TRUE,(ext),(err)) + +#define ARGBOOL(flags,name,var,callback) SCmdRegisterArgument(SCMD_TYPE_BOOL | (flags),0xFFFFFFFF,name,var,sizeof(var),TRUE,0xFFFFFFFF,callback) +#define ARGFLAG(flags,name,var,valuecallback) SCmdRegisterArgument(SCMD_TYPE_BOOL | (flags),0xFFFFFFFF,name,var,sizeof(var),value,value,callback) +#define ARGNUMBER(flags,name,var,callback) SCmdRegisterArgument(SCMD_TYPE_NUMERIC | (flags),0xFFFFFFFF,name,var,sizeof(var),0,0,callback) +#define ARGSTRING(flags,name,buffer,chars,callback) SCmdRegisterArgument(SCMD_TYPE_STRING | (flags),0xFFFFFFFF,name,buffer,(chars),0,0,callback) + + +/**************************************************************************** +* +* S-Code functions +* +***/ + +#define SCODE_CF_AUTOALIGNDWORD 0x00040000 +#define SCODE_CF_USESALTADJUSTS 0x04000000 + +DECLARE_STRICT_HANDLE(HSCODESTREAM); + +typedef struct _SCODEEXECUTEDATA { + DWORD size; + DWORD flags; + int xiterations; + int yiterations; + int adjustdest; + int adjustsource; + LPVOID dest; + LPVOID source; + LPVOID table; + DWORD a; + DWORD b; + DWORD c; + int adjustdestalt; + int adjustsourcealt; + DWORD reserved[2]; +} SCODEEXECUTEDATA, *SCODEEXECUTEDATAPTR; + +extern "C" BOOL APIENTRY SCodeCompile (LPCSTR prologstring, + LPCSTR loopstring, + LPCSTR *firsterror, + DWORD maxiterations, + DWORD flags, + HSCODESTREAM *handle); +extern "C" BOOL APIENTRY SCodeDelete (HSCODESTREAM handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SCodeDestroy (); +#endif +extern "C" BOOL APIENTRY SCodeExecute (HSCODESTREAM handle, + SCODEEXECUTEDATAPTR executedata); +extern "C" BOOL APIENTRY SCodeGetJumpTable (HSCODESTREAM handle, + LPBYTE **jumptableptr, + LPDWORD *prologpatchlocation, + LPDWORD *looppatchlocation, + LPDWORD *epilogpatchlocation); +extern "C" BOOL APIENTRY SCodeGetPseudocode (LPCSTR scodestring, + LPSTR buffer, + DWORD buffersize); + + +/**************************************************************************** +* +* Compression functions +* +***/ + +#define SCOMP_HINT_NONE 0 +#define SCOMP_HINT_BINARY 1 +#define SCOMP_HINT_TEXT 2 +#define SCOMP_HINT_EXECUTABLE 3 +#define SCOMP_HINT_ADPCM4 4 +#define SCOMP_HINT_ADPCM6 5 +#define SCOMP_HINTS 6 + +#define SCOMP_OPT_DEFAULT 0 +#define SCOMP_OPT_COMPRESSION 1 +#define SCOMP_OPT_SPEED 2 +#define SCOMP_OPT_QUALITY 3 + +#define SCOMP_TYPE_HUFFMAN 0x01 +#define SCOMP_TYPE_PKWARE 0x08 +#define SCOMP_TYPE_LOSSY_ADPCM_MONO 0x10 +#define SCOMP_TYPE_LOSSY_ADPCM_STEREO 0x20 + +extern "C" BOOL APIENTRY SCompCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD compressiontypes, + DWORD hint, + DWORD optimization); +extern "C" BOOL APIENTRY SCompDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize); + + +/**************************************************************************** +* +* Dialog box functions +* +***/ + +#define SDLG_ADJUST_NONE 0 +#define SDLG_ADJUST_VERTICAL 1 +#define SDLG_ADJUST_CONTROLPOS 2 + +#define SDLG_DBF_TILE 0x00000001 +#define SDLG_DBF_VCENTER 0x00000002 + +#define SDLG_STYLE_ANY 0xFFFFFFFF +#define SDLG_STYLE_ANYPUSHBUTTON 0x00010001 + +#define SDLG_USAGE_BACKGROUND 0x00000001 +#define SDLG_USAGE_NORMAL_UNFOCUSED 0x00000010 +#define SDLG_USAGE_NORMAL_FOCUSED 0x00000020 +#define SDLG_USAGE_NORMAL (SDLG_USAGE_NORMAL_UNFOCUSED | SDLG_USAGE_NORMAL_FOCUSED) +#define SDLG_USAGE_SELECTED_UNFOCUSED 0x00000040 +#define SDLG_USAGE_SELECTED_FOCUSED 0x00000080 +#define SDLG_USAGE_SELECTED (SDLG_USAGE_SELECTED_UNFOCUSED | SDLG_USAGE_SELECTED_FOCUSED) +#define SDLG_USAGE_NORMAL_GRAYED 0x00000100 +#define SDLG_USAGE_SELECTED_GRAYED 0x00000400 +#define SDLG_USAGE_GRAYED (SDLG_USAGE_NORMAL_GRAYED | SDLG_USAGE_SELECTED_GRAYED) +#define SDLG_USAGE_CURSORMASK 0x00001000 +#define SDLG_USAGE_CURSORIMAGE 0x00002000 + +extern "C" HDC APIENTRY SDlgBeginPaint (HWND window, LPPAINTSTRUCT ps); +extern "C" BOOL APIENTRY SDlgBltToWindowE (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey = 0xFFFFFFFF, + DWORD pattern = 0, + DWORD rop3 = SRCCOPY); +extern "C" BOOL APIENTRY SDlgBltToWindowI (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey = 0xFFFFFFFF, + DWORD pattern = 0, + DWORD rop3 = SRCCOPY); +extern "C" BOOL APIENTRY SDlgCheckTimers (); +extern "C" HWND APIENTRY SDlgCreateDialogIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" HWND APIENTRY SDlgCreateDialogParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" BOOL APIENTRY SDlgDefDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SDlgDestroy (); +#endif +extern "C" int APIENTRY SDlgDialogBoxIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" int APIENTRY SDlgDialogBoxParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" BOOL APIENTRY SDlgDrawBitmap (HWND window, + DWORD usage, + HRGN region, + int offsetx = 0, + int offsety = 0, + LPRECT boundingoffset = NULL, + DWORD flags = 0); +extern "C" BOOL APIENTRY SDlgEndDialog (HWND window, + int result); +extern "C" BOOL APIENTRY SDlgEndPaint (HWND window, LPPAINTSTRUCT ps); +extern "C" BOOL APIENTRY SDlgKillTimer (HWND window, + UINT event); +extern "C" BOOL APIENTRY SDlgSetBaseFont (int pointsize, + int weight, + DWORD flags, + DWORD family, + LPCTSTR face); +extern "C" BOOL APIENTRY SDlgSetBitmapE (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetBitmapI (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetControlBitmaps (HWND parentwindow, + LPINT controllist, + LPDWORD usagelist, + LPBYTE bitmapbits, + LPSIZE bitmapsize, + DWORD adjusttype, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetCursor (HWND window, + HCURSOR cursor, + DWORD id, + HCURSOR *oldcursor); +extern "C" BOOL APIENTRY SDlgSetSystemCursor (LPBYTE maskbitmap, + LPBYTE imagebitmap, + LPSIZE size, + DWORD id = 32512); +extern "C" BOOL APIENTRY SDlgSetTimer (HWND window, + UINT event, + UINT elapse, + TIMERPROC timerfunc); +extern "C" BOOL APIENTRY SDlgUpdateCursor (); + +#define SDlgCreateDialog(ins,tpl,wnd,prc) SDlgCreateDialogParam(ins,tpl,wnd,prc,0) +#define SDlgCreateDialogIndirect(ins,tpl,wnd,prc) SDlgCreateDialogIndirectParam(ins,tpl,wnd,prc,0) +#define SDlgDialogBox(ins,tpl,wnd,prc) SDlgDialogBoxParam(ins,tpl,wnd,prc,0) +#define SDlgDialogBoxIndirect(ins,tpl,wnd,prc) SDlgDialogBoxIndirectParam(ins,tpl,wnd,prc,0) + +#ifdef SDLG_USE_INCLUSIVE_RECTS +#define SDlgBltToWindow SDlgBltToWindowI +#define SDlgSetBitmap SDlgSetBitmapI +#else +#define SDlgBltToWindow SDlgBltToWindowE +#define SDlgSetBitmap SDlgSetBitmapE +#endif + +/**************************************************************************** +* +* DirectDraw functions +* +***/ + +#define SDRAW_SERVICE_BASIC 1 +#define SDRAW_SERVICE_PAGEFLIP 2 +#define SDRAW_SERVICE_DOUBLEBUFFER 3 +#define SDRAW_SERVICE_MAX 3 + +#define SDRAW_SURFACE_FRONT 0 +#define SDRAW_SURFACE_BACK 1 +#define SDRAW_SURFACE_SYSTEM 2 +#define SDRAW_SURFACE_TEMPORARY 3 + +#ifndef MAC +extern "C" BOOL APIENTRY SDrawAutoInitialize (HINSTANCE instance, + LPCTSTR classname, + LPCTSTR title, + WNDPROC wndproc = NULL, + int servicelevel = SDRAW_SERVICE_BASIC, + int width = 640, + int height = 480, + int bitdepth = 8); +extern "C" BOOL APIENTRY SDrawCaptureScreen (LPCTSTR filename = NULL); +#endif +extern "C" BOOL APIENTRY SDrawClearSurface (int surfacenumber); +extern "C" BOOL APIENTRY SDrawDestroy (); +extern "C" BOOL APIENTRY SDrawFlipPage (); +extern "C" HWND APIENTRY SDrawGetFrameWindow (HWND *window = NULL); +#ifdef __DDRAW_INCLUDED__ +extern "C" BOOL APIENTRY SDrawGetObjects (LPDIRECTDRAW *directdraw, + LPDIRECTDRAWSURFACE *frontbuffer, + LPDIRECTDRAWSURFACE *backbuffer, + LPDIRECTDRAWSURFACE *systembuffer, + LPDIRECTDRAWSURFACE *temporarybuffer, + LPDIRECTDRAWPALETTE *palette, + HPALETTE *gdipalette); +#endif +extern "C" BOOL APIENTRY SDrawGetScreenSize (int *width, + int *height, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SDrawGetServiceLevel (int *servicelevel = NULL); +extern "C" BOOL APIENTRY SDrawLockSurface (int surfacenumber, + LPCRECT rect, + LPBYTE *ptr, + int *pitch = NULL, + DWORD flags = 0); +#ifdef __DDRAW_INCLUDED__ +extern "C" BOOL APIENTRY SDrawManualInitialize (HWND framewindow, + LPDIRECTDRAW directdraw, + LPDIRECTDRAWSURFACE frontbuffer, + LPDIRECTDRAWSURFACE backbuffer, + LPDIRECTDRAWSURFACE systembuffer, + LPDIRECTDRAWSURFACE temporarybuffer, + LPDIRECTDRAWPALETTE palette, + HPALETTE gdipalette); +#endif +extern "C" int APIENTRY SDrawMessageBox (LPCTSTR text, + LPCTSTR title, + UINT flags); +extern "C" BOOL APIENTRY SDrawPostClose (); +extern "C" BOOL APIENTRY SDrawRealizePalette (); +#ifndef MAC +extern "C" BOOL APIENTRY SDrawSelectGdiSurface (BOOL select, BOOL copy); +#endif +extern "C" BOOL APIENTRY SDrawUnlockSurface (int surfacenumber, + LPBYTE ptr, + DWORD numrects = 0, + LPCRECT rectarray = NULL); +extern "C" BOOL APIENTRY SDrawUpdatePalette (DWORD firstentry, + DWORD numentries, + LPPALETTEENTRY entries, + BOOL reservedentries = FALSE); +extern "C" BOOL APIENTRY SDrawUpdateScreen (LPCRECT rect); +#ifdef MAC +extern "C" BOOL APIENTRY SDrawVidDriverInitialize (HWND framewindow, + int servicelevel); +#endif + + +/**************************************************************************** +* +* Error handling functions +* +***/ + +#define SERR_LINECODE_FUNCTION -1 +#define SERR_LINECODE_OBJECT -2 +#define SERR_LINECODE_HANDLE -3 +#define SERR_LINECODE_FILE -4 + +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SErrDestroy (); +#endif +extern "C" BOOL APIENTRY SErrDisplayError (DWORD errorcode, + LPCTSTR filename, + int linenumber, + LPCTSTR description, + BOOL recoverable, + UINT exitcode = 1); +extern "C" BOOL APIENTRY SErrGetErrorStr (DWORD errorcode, + LPTSTR buffer, + DWORD bufferchars); +#define GetLastError SErrGetLastError +extern "C" DWORD APIENTRY SErrGetLastError (); +extern "C" BOOL APIENTRY SErrRegisterMessageSource (WORD facility, + HMODULE module, + LPVOID reserved = NULL); +extern "C" void APIENTRY SErrReportResourceLeak (LPCTSTR handlename); +extern "C" void APIENTRY SErrSetLastError (DWORD errorcode); +extern "C" void APIENTRY SErrSuppressErrors (BOOL suppress); + +#define SErrGetLastErrorStr(buf,len) SErrGetErrorStr(SErrGetLastError(),buf,len) +#define FATALRESULT(str) SErrDisplayError(SErrGetLastError(),str,SERR_LINECODE_FUNCTION,NULL,FALSE) +#define REPORTRESOURCELEAK(handle) SErrReportResourceLeak(#handle) + +#ifdef _DEBUG +#define ASSERT(a) if (!(a)) \ + SErrDisplayError(STORM_ERROR_ASSERTION, \ + __FILE__, \ + __LINE__, \ + #a, \ + FALSE) +#define VALIDATEBEGIN do { +#define VALIDATE(a) ASSERT(a) +#define VALIDATEANDBLANK(a) do { \ + ASSERT(a); \ + *(a) = 0; \ + } while (0) +#define VALIDATEEND } while (0) +#define VALIDATEENDVOID } while (0) +#else +#define ASSERT(a) +#define VALIDATEBEGIN do { \ + int intrn_valresult = -1 +#define VALIDATE(a) intrn_valresult &= (a) ? -1 : 0 +#define VALIDATEANDBLANK(a) if (a) \ + *a = 0; \ + else \ + intrn_valresult = 0 +#define VALIDATEEND if (!intrn_valresult) { \ + SErrSetLastError( \ + ERROR_INVALID_PARAMETER); \ + return 0; \ + } \ + } while (0) +#define VALIDATEENDVOID if (!intrn_valresult) { \ + SErrSetLastError( \ + ERROR_INVALID_PARAMETER); \ + return; \ + } \ + } while (0) +#endif + + +/**************************************************************************** +* +* Event dispatching functions +* +***/ + +typedef void (CALLBACK *SEVTHANDLER)(LPVOID); + +extern "C" BOOL APIENTRY SEvtBreakHandlerChain (LPVOID data); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SEvtDestroy (); +#endif +extern "C" BOOL APIENTRY SEvtDispatch (DWORD type, + DWORD subtype, + DWORD id, + LPVOID data); +extern "C" BOOL APIENTRY SEvtPopState (DWORD type, + DWORD subtype); +extern "C" BOOL APIENTRY SEvtPushState (DWORD type, + DWORD subtype); +extern "C" BOOL APIENTRY SEvtRegisterHandler (DWORD type, + DWORD subtype, + DWORD id, + DWORD flags, + SEVTHANDLER handler); +extern "C" BOOL APIENTRY SEvtUnregisterHandler (DWORD type, + DWORD subtype, + DWORD id, + SEVTHANDLER handler); +extern "C" BOOL APIENTRY SEvtUnregisterType (DWORD type, + DWORD subtype); + + +/**************************************************************************** +* +* File I/O functions +* +***/ + +#define SFILE_AUTH_UNABLETOAUTHENTICATE 0 +#define SFILE_AUTH_NOSIGNATURE 1 +#define SFILE_AUTH_BADSIGNATURE 2 +#define SFILE_AUTH_UNKNOWNSIGNATURE 3 +#define SFILE_AUTH_FIRSTAUTHENTIC 5 +#define SFILE_AUTH_AUTHENTICBLIZZARD 5 + +#define SFILE_DDA_LOOP 0x00040000 + +#define SFILE_ERROR_BAD_FORMAT ERROR_BAD_FORMAT +#define SFILE_ERROR_BAD_PATHNAME ERROR_BAD_PATHNAME +#define SFILE_ERROR_CALL_NOT_IMPLEMENTED ERROR_CALL_NOT_IMPLEMENTED +#define SFILE_ERROR_FILE_INVALID ERROR_FILE_INVALID +#define SFILE_ERROR_FILE_NOT_FOUND ERROR_FILE_NOT_FOUND +#define SFILE_ERROR_HANDLE_EOF ERROR_HANDLE_EOF +#define SFILE_ERROR_INVALID_DATA ERROR_INVALID_DATA +#define SFILE_ERROR_INVALID_DRIVE ERROR_INVALID_DRIVE +#define SFILE_ERROR_INVALID_HANDLE ERROR_INVALID_HANDLE +#define SFILE_ERROR_INVALID_PARAMETER ERROR_INVALID_PARAMETER +#define SFILE_ERROR_NOT_ARCHIVE STORM_ERROR_NOT_ARCHIVE +#define SFILE_ERROR_NOT_AUTHENTICATED ERROR_NOT_AUTHENTICATED +#define SFILE_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY +#define SFILE_ERROR_NOT_IN_ARCHIVE STORM_ERROR_NOT_IN_ARCHIVE +#define SFILE_ERROR_NOT_INITIALIZED STORM_ERROR_NOT_INITIALIZED +#define SFILE_ERROR_NOT_PLAYING STORM_ERROR_NOT_PLAYING + +#define SFILE_ERRORMODE_RETURNCODE 0 +#define SFILE_ERRORMODE_CUSTOM 1 +#define SFILE_ERRORMODE_FATAL 2 + +#define SFILE_FIND_FILES 0x00000001 +#define SFILE_FIND_DIRECTORIES 0x00000002 + +DECLARE_STRICT_HANDLE(HSARCHIVE); +DECLARE_STRICT_HANDLE(HSFILE); + +typedef BOOL (CALLBACK *SFILEERRORPROC)(LPCTSTR,DWORD); + +extern "C" BOOL APIENTRY SFileAuthenticateArchive (HSARCHIVE archive, + DWORD *extendedresult); +extern "C" BOOL APIENTRY SFileCloseArchive (HSARCHIVE handle); +extern "C" BOOL APIENTRY SFileCloseFile (HSFILE handle); +extern "C" BOOL APIENTRY SFileDdaBegin (HSFILE handle, + DWORD buffersize, + DWORD flags); +extern "C" BOOL APIENTRY SFileDdaBeginEx (HSFILE handle, + DWORD buffersize, + DWORD flags, + DWORD offset, + LONG volume, + LONG pan, + LPVOID reserved); +extern "C" BOOL APIENTRY SFileDdaDestroy (); +extern "C" BOOL APIENTRY SFileDdaEnd (HSFILE handle); +extern "C" BOOL APIENTRY SFileDdaGetPos (HSFILE handle, + DWORD *position, + DWORD *maxposition); +extern "C" BOOL APIENTRY SFileDdaGetVolume (HSFILE handle, + LONG *volume, + LONG *pan); +#ifdef __DSOUND_INCLUDED__ +extern "C" BOOL APIENTRY SFileDdaInitialize (LPDIRECTSOUND directsound); +#endif +extern "C" BOOL APIENTRY SFileDdaSetVolume (HSFILE handle, + LONG volume, + LONG pan); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SFileDestroy (); +#endif +extern "C" BOOL APIENTRY SFileEnableDirectAccess (BOOL enable); +extern "C" BOOL APIENTRY SFileGetArchiveInfo (HSARCHIVE archive, + int *priority, + BOOL *cdrom); +extern "C" BOOL APIENTRY SFileGetArchiveName (HSARCHIVE archive, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SFileGetBasePath (LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SFileGetFileArchive (HSFILE file, + HSARCHIVE *archive); +extern "C" BOOL APIENTRY SFileGetFileName (HSFILE file, + LPTSTR buffer, + DWORD bufferchars); +extern "C" DWORD APIENTRY SFileGetFileSize (HSFILE handle, + LPDWORD filesizehigh = NULL); +extern "C" BOOL APIENTRY SFileOpenArchive (LPCTSTR archivename, + int priority, + BOOL cdonly, + HSARCHIVE *handle); +extern "C" BOOL APIENTRY SFileOpenFile (LPCTSTR filename, + HSFILE *handle); +extern "C" BOOL APIENTRY SFileOpenFileEx (HSARCHIVE archivehandle, + LPCTSTR filename, + DWORD flags, + HSFILE *handle); +extern "C" BOOL APIENTRY SFileReadFile (HSFILE handle, + LPVOID buffer, + DWORD bytestoread, + LPDWORD bytesread = NULL, + LPOVERLAPPED overlapped = NULL); +extern "C" BOOL APIENTRY SFileSetBasePath (LPCTSTR path); +extern "C" DWORD APIENTRY SFileSetFilePointer (HSFILE handle, + LONG distancetomove, + PLONG distancetomovehigh, + DWORD movemethod); +extern "C" BOOL APIENTRY SFileSetIoErrorMode (DWORD errormode, + SFILEERRORPROC errorproc = NULL); +extern "C" BOOL APIENTRY SFileSetLocale (LCID lcid); + + +/**************************************************************************** +* +* GDI functions +* +***/ + +#define ETO_TEXT_TRANSPARENT 0 +#define ETO_TEXT_COLOR 1 +#define ETO_TEXT_BLACK 2 +#define ETO_TEXT_WHITE 3 +#define ETO_BKG_TRANSPARENT 0 +#define ETO_BKG_COLOR 1 +#define ETO_BKG_BLACK 2 +#define ETO_BKG_WHITE 3 + +DECLARE_STRICT_HANDLE(HSGDIOBJ); +DECLARE_DERIVED_HANDLE(HSGDIFONT,HSGDIOBJ); + +extern "C" BOOL APIENTRY SGdiBitBlt (LPBYTE videobuffer, + int destx, + int desty, + LPBYTE sourcedata, + LPRECT sourcerect, + int sourcecx, + int sourcecy, + COLORREF color = 0, + DWORD rop = SRCCOPY); +extern "C" BOOL APIENTRY SGdiCreateFont (LPBYTE bits, + int width, + int height, + int bitdepth, + int filecharwidth, + int filecharheight, + LPSIZE charsizetable, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiDeleteObject (HSGDIOBJ handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SGdiDestroy (); +#endif +extern "C" BOOL APIENTRY SGdiExtTextOut (LPBYTE videobuffer, + int x, + int y, + LPRECT rect, + COLORREF color, + int textcoloruse, + int bkgcoloruse, + LPCTSTR string, + int chars = -1); +extern "C" BOOL APIENTRY SGdiGetTextExtent (LPCTSTR string, + int chars, + LPSIZE size); +extern "C" BOOL APIENTRY SGdiImportFont (HFONT windowsfont, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiLoadFont (LPCTSTR filename, + int filecharwidth, + int filecharheight, + int basecharwidth, + LPSIZE charsizetable, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiRectangle (LPBYTE videobuffer, + int left, + int top, + int right, + int bottom, + COLORREF color); +extern "C" BOOL APIENTRY SGdiSelectObject (HSGDIOBJ handle); +extern "C" BOOL APIENTRY SGdiSetPitch (int pitch); +extern "C" BOOL APIENTRY SGdiSetTargetDimensions (int width, + int height, + int bitdepth, + int pitch); +extern "C" BOOL APIENTRY SGdiTextOut (LPBYTE videobuffer, + int x, + int y, + COLORREF color, + LPCTSTR string, + int chars = -1); + + +/**************************************************************************** +* +* Logging functions +* +***/ + +DECLARE_STRICT_HANDLE(HSLOG); + +extern "C" void APIENTRY SLogClose (HSLOG log); +extern "C" BOOL APIENTRY SLogCreate (LPCTSTR filename, + DWORD flags, + HSLOG *log); +#ifdef STORMSTATIC +extern "C" void APIENTRY SLogDestroy (); +#endif +extern "C" void APIENTRY SLogDump (HSLOG log, + LPCVOID data, + DWORD bytes); +extern "C" void APIENTRY SLogFlush (HSLOG log); +extern "C" void APIENTRY SLogFlushAll (); +#ifdef STORMSTATIC +extern "C" void APIENTRY SLogInitialize (); +#endif +extern "C" void __cdecl SLogPend (HSLOG log, + LPCTSTR format, + ...); +extern "C" void __cdecl SLogWrite (HSLOG log, + LPCTSTR format, + ...); + + +/**************************************************************************** +* +* Memory allocation functions +* +***/ + +#define SMEM_FLAG_ZEROMEMORY 0x00000008 +#define SMEM_FLAG_PRESERVEONDESTROY 0x08000000 + +DECLARE_STRICT_HANDLE(HSHEAP); + +typedef struct _SMEMBLOCKDETAILS { + DWORD size; + LPVOID ptr; + BOOL allocated; + BOOL valid; + DWORD bytes; + DWORD overhead; +} SMEMBLOCKDETAILS, *LPSMEMBLOCKDETAILS; + +typedef struct _SMEMHEAPDETAILS { + DWORD size; + HSHEAP handle; + char filename[MAX_PATH]; + int linenumber; + DWORD regions; + DWORD committedbytes; + DWORD reservedbytes; + DWORD maximumsize; + DWORD allocatedblocks; +} SMEMHEAPDETAILS, *LPSMEMHEAPDETAILS; + +extern "C" LPVOID APIENTRY SMemAlloc (DWORD bytes, + LPCSTR filename = NULL, + int linenumber = 0, + DWORD flags = 0); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SMemDestroy (); +#endif +extern "C" BOOL APIENTRY SMemFindNextBlock (HSHEAP heap, + LPVOID prevblock, + LPVOID *nextblock, + LPSMEMBLOCKDETAILS details); +extern "C" BOOL APIENTRY SMemFindNextHeap (HSHEAP prevheap, + HSHEAP *nextheap, + LPSMEMHEAPDETAILS details); +extern "C" BOOL APIENTRY SMemFree (LPVOID ptr, + LPCSTR filename = NULL, + int linenumber = 0, + DWORD flags = 0); +extern "C" HSHEAP APIENTRY SMemGetHeapByCaller (LPCSTR filename, + int linenumber); +extern "C" HSHEAP APIENTRY SMemGetHeapByPtr (LPVOID ptr); +extern "C" LPVOID APIENTRY SMemHeapAlloc (HSHEAP handle, + DWORD flags, + DWORD bytes); +extern "C" HSHEAP APIENTRY SMemHeapCreate (DWORD options, + DWORD initialsize, + DWORD maximumsize); +extern "C" BOOL APIENTRY SMemHeapDestroy (HSHEAP handle); +extern "C" BOOL APIENTRY SMemHeapFree (HSHEAP handle, + DWORD flags, + LPVOID ptr); +#ifdef STORMSTATIC +extern "C" void APIENTRY SMemInitialize (); +#endif + +inline void __cdecl operator delete (void *ptr) { + if (ptr) + SMemFree(ptr,__FILE__,__LINE__,0); +} + +inline void * __cdecl operator new (size_t bytes) { + return SMemAlloc(bytes,__FILE__,__LINE__,0); +} + +#ifndef __ICL +#ifndef __MWERKS__ +inline void __cdecl operator delete[] (void *ptr) { + if (ptr) + SMemFree(ptr,__FILE__,__LINE__,0); +} + +inline void * __cdecl operator new[] (size_t bytes) { + return SMemAlloc(bytes,__FILE__,__LINE__,0); +} +#endif +#endif + +#ifndef __PLACEMENT_NEW_INLINE +#define __PLACEMENT_NEW_INLINE +inline void * __cdecl operator new (size_t, void *ptr) { + return (ptr); +} + +inline void * __cdecl operator new[] (size_t, void *ptr) { + return (ptr); +} +#endif + +#define ALLOC(bytes) SMemAlloc(bytes,__FILE__,__LINE__,0) +#define ALLOCZERO(bytes) SMemAlloc(bytes,__FILE__,__LINE__,SMEM_FLAG_ZEROMEMORY) +#define DEL(ptr) delete(ptr) +#define DELIFUSED(ptr) delete(ptr) +#define FREE(ptr) SMemFree(ptr,__FILE__,__LINE__,0) +#define FREEIFUSED(ptr) do if (ptr) SMemFree(ptr,__FILE__,__LINE__,0); while (0) +#define NEW(struct) (new(SMemAlloc(sizeof(struct),__FILE__,__LINE__,0)) struct) +#define NEWZERO(struct) (new(SMemAlloc(sizeof(struct),__FILE__,__LINE__,SMEM_FLAG_ZEROMEMORY)) struct) + + +/**************************************************************************** +* +* Message functions +* +***/ + +typedef struct _PARAMS { + HWND window; + UINT message; + WPARAM wparam; + LPARAM lparam; + UINT notifycode; + LPVOID extra; + BOOL useresult; + LRESULT result; +} PARAMS, *PARAMSPTR, *LPPARAMS; + +typedef BOOL (CALLBACK *SMSGIDLEPROC)(DWORD); +typedef void (CALLBACK *SMSGHANDLER)(LPPARAMS); + +extern "C" BOOL APIENTRY SMsgBreakHandlerChain (LPPARAMS params); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SMsgDestroy (); +#endif +extern "C" BOOL APIENTRY SMsgDispatchMessage (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam, + BOOL *useresult, + LRESULT *result); +extern "C" BOOL APIENTRY SMsgDoMessageLoop (SMSGIDLEPROC idleproc = NULL, + BOOL cleanuponquit = TRUE); +extern "C" BOOL APIENTRY SMsgPopRegisterState (HWND window); +extern "C" BOOL APIENTRY SMsgPushRegisterState (HWND window); +extern "C" BOOL APIENTRY SMsgRegisterCommand (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterMessage (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterCommand (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterMessage (HWND window, + UINT id, + SMSGHANDLER handler); + + +/**************************************************************************** +* +* Networking functions +* +***/ + +#define SNET_ART_BACKGROUND 0 +#define SNET_ART_BUTTONTEXTURE 1 +#define SNET_ART_JOINBACKGROUND 2 +#define SNET_ART_HELPBACKGROUND 3 +#define SNET_ART_POPUPBACKGROUND 4 +#define SNET_ART_BUTTON_XSML 5 +#define SNET_ART_BUTTON_SML 6 +#define SNET_ART_BUTTON_MED 7 +#define SNET_ART_BUTTON_LRG 8 +#define SNET_ART_APP_LOGO_SML 9 +#define SNET_ART_PROGRESS_BACKGROUND 10 +#define SNET_ART_PROGRESS_FILLER 11 +#define SNET_ART_POPUPBACKGROUND_SML 12 +#define SNET_ART_SCROLLBARARROWS 13 +#define SNET_ART_SCROLLTHUMB 14 +#define SNET_ART_SCROLLBAR 15 +#define SNET_ART_COMBOLEFT 16 +#define SNET_ART_COMBOMIDDLE 17 +#define SNET_ART_COMBORIGHT 18 + +#define SNET_AUTHTYPE_CHANNEL 1 +#define SNET_AUTHTYPE_GAME 2 + +#define SNET_BROADCASTNONLOCALPLAYERID 0xFFFFFFFE +#define SNET_BROADCASTPLAYERID 0xFFFFFFFF +#define SNET_INVALIDPLAYERID 0xFFFFFFFF + +#define SNET_CAPS_PAGELOCKEDBUFFERS 0x00000001 +#define SNET_CAPS_BASICINTERFACE 0x00000002 +#define SNET_CAPS_DEBUGONLY 0x10000000 +#define SNET_CAPS_RETAILONLY 0x20000000 + +#define SNET_CF_ALLOWPRIVATEGAMES 0x00000001 + +#define SNET_DATA_SYSCOLORS 1 +#define SNET_DATA_CURSORLINK 2 +#define SNET_DATA_CURSORARROW 3 +#define SNET_DATA_CURSORIBEAM 4 + +#define SNET_DDF_INCLUDENAME 0x00000001 +#define SNET_DDF_MULTILINE 0x00000002 + +#define SNET_DDPF_BLIZZARD 0x00000001 +#define SNET_DDPF_MODERATOR 0x00000002 +#define SNET_DDPF_SPEAKER 0x00000004 +#define SNET_DDPF_SYSOP 0x00000008 +#define SNET_DDPF_SQUELCHED 0x00000020 + +#define SNET_DRAWTYPE_GAME 1 +#define SNET_DRAWTYPE_PLAYER 2 + +#define SNET_ERROR_ALREADY_EXISTS ERROR_ALREADY_EXISTS +#define SNET_ERROR_BAD_PROVIDER ERROR_BAD_PROVIDER +#define SNET_ERROR_CANCELLED ERROR_CANCELLED +#define SNET_ERROR_INVALID_PARAMETER ERROR_INVALID_PARAMETER +#define SNET_ERROR_INVALID_PLAYER STORM_ERROR_INVALID_PLAYER +#define SNET_ERROR_GAME_ALREADY_STARTED STORM_ERROR_GAME_ALREADY_STARTED +#define SNET_ERROR_GAME_FULL STORM_ERROR_GAME_FULL +#define SNET_ERROR_GAME_NOT_FOUND STORM_ERROR_GAME_NOT_FOUND +#define SNET_ERROR_GAME_TERMINATED STORM_ERROR_GAME_TERMINATED +#define SNET_ERROR_HOST_UNREACHABLE ERROR_HOST_UNREACHABLE +#define SNET_ERROR_MAX_THRDS_REACHED ERROR_MAX_THRDS_REACHED +#define SNET_ERROR_NETWORK_BUSY ERROR_NETWORK_BUSY +#define SNET_ERROR_NO_MESSAGES_WAITING STORM_ERROR_NO_MESSAGES_WAITING +#define SNET_ERROR_NO_NETWORK ERROR_NO_NETWORK +#define SNET_ERROR_NOT_CONNECTED ERROR_NOT_CONNECTED +#define SNET_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY +#define SNET_ERROR_NOT_IMPLEMENTED STORM_ERROR_NOT_IMPLEMENTED +#define SNET_ERROR_NOT_IN_GAME STORM_ERROR_NOT_IN_GAME +#define SNET_ERROR_NOT_OWNER ERROR_NOT_OWNER +#define SNET_ERROR_NOT_REGISTERED STORM_ERROR_NOT_REGISTERED +#define SNET_ERROR_REQUIRES_UPGRADE STORM_ERROR_REQUIRES_UPGRADE +#define SNET_ERROR_STILL_ACTIVE STORM_ERROR_STILL_ACTIVE +#define SNET_ERROR_TOO_MANY_NAMES ERROR_TOO_MANY_NAMES +#define SNET_ERROR_VERSION_MISMATCH STORM_ERROR_VERSION_MISMATCH + +#define SNET_EVENT_INITDATA 1 +#define SNET_EVENT_PLAYERJOIN 2 +#define SNET_EVENT_PLAYERLEAVE 3 +#define SNET_EVENT_SERVERMESSAGE 4 + +#define SNET_EXIT_AUTO_JOINING 0x00000001 +#define SNET_EXIT_AUTO_NEWGAME 0x00000002 +#define SNET_EXIT_AUTO_SHUTDOWN 0x00000003 +#define SNET_EXIT_PLAYERQUIT 0x40000001 +#define SNET_EXIT_PLAYERKILLED 0x40000002 +#define SNET_EXIT_PLAYERWON 0x40000004 +#define SNET_EXIT_GAMEOVER 0x40000005 +#define SNET_EXIT_NOTRESPONDING 0x40000006 + +#define SNET_GM_PRIVATE 0x00000001 +#define SNET_GM_FULL 0x00000002 +#define SNET_GM_ADVERTISED 0x00000004 +#define SNET_GM_UNJOINABLE 0x00000008 +#define SNET_GM_UNLISTEDMASK (SNET_GM_PRIVATE | SNET_GM_FULL | SNET_GM_UNJOINABLE) + +#define SNET_INFO_GAMENAME 1 +#define SNET_INFO_GAMEPASSWORD 2 +#define SNET_INFO_GAMEDESCRIPTION 3 +#define SNET_INFO_GAMEMODE 4 +#define SNET_INFO_INITDATA 5 +#define SNET_INFO_MAXPLAYERS 6 + +#define SNET_LMT_EXPECTED 1 +#define SNET_LMT_CURRENT 2 +#define SNET_LMT_PEAK 4 + +#define SNET_PERFID_TURN 1 +#define SNET_PERFID_TURNSSENT 4 +#define SNET_PERFID_TURNSRECV 5 +#define SNET_PERFID_MSGSENT 6 +#define SNET_PERFID_MSGRECV 7 +#define SNET_PERFID_USERBYTESSENT 8 +#define SNET_PERFID_USERBYTESRECV 9 +#define SNET_PERFID_TOTALBYTESSENT 10 +#define SNET_PERFID_TOTALBYTESRECV 11 +#define SNET_PERFID_PKTSENTONWIRE 12 +#define SNET_PERFID_PKTRECVONWIRE 13 +#define SNET_PERFID_BYTESSENTONWIRE 14 +#define SNET_PERFID_BYTESRECVONWIRE 15 +#define SNET_PERFIDNUM 16 + +#define SNET_PERFTYPE_COUNTER 0x10410400 +#define SNET_PERFTYPE_RAWCOUNT 0x00010000 + +#define SNET_PSF_ACTIVE 0x00010000 +#define SNET_PSF_TURNAVAILABLE 0x00020000 +#define SNET_PSF_RESPONDING 0x00040000 + +#define SNET_SF_ALLOWCREATE 0x00000001 + +#define SNET_SND_CHANGEFOCUS 0 +#define SNET_SND_SELECTITEM 1 + +#define SNET_UPGRADE_FAILED -1 +#define SNET_UPGRADE_NOT_NEEDED 0 +#define SNET_UPGRADE_SUCCEEDED 1 +#define SNET_UPGRADING_TERMINATE 2 + +#define SNET_MAXNAMELENGTH 128 +#define SNET_MAXDESCLENGTH 128 + +typedef struct _SNETCAPS { + DWORD size; + DWORD flags; + DWORD maxmessagesize; + DWORD maxqueuesize; + DWORD maxplayers; + DWORD bytessec; + DWORD latencyms; + DWORD defaultturnssec; + DWORD defaultturnsintransit; +} SNETCAPS, *SNETCAPSPTR; + +typedef struct _SNETCREATEDATA { + DWORD size; + DWORD providerid; + DWORD maxplayers; + DWORD createflags; +} SNETCREATEDATA, *SNETCREATEDATAPTR; + +typedef struct _SNET_DATA_SYSCOLORTABLE { + DWORD syscolor; + COLORREF rgb; +} SNET_DATA_SYSCOLORTABLE, *SNET_DATA_SYSCOLORTABLEPTR; + +typedef struct _SNETEVENT { + DWORD eventid; + DWORD playerid; + LPVOID data; + DWORD databytes; +} SNETEVENT, *SNETEVENTPTR; + +typedef struct _SNETGAME { + DWORD size; + DWORD id; + LPCSTR gamename; + LPCSTR gamedescription; + DWORD categorybits; + DWORD numplayers; + DWORD maxplayers; +} SNETGAME, *SNETGAMEPTR; + +struct _SNETPROGRAMDATA; +struct _SNETPLAYERDATA; +struct _SNETUIDATA; +struct _SNETVERSIONDATA; + +typedef BOOL (CALLBACK *SNETABORTPROC )(); +typedef void (CALLBACK *SNETADDCATEGORYPROC )(LPCSTR,DWORD,DWORD); +typedef void (CALLBACK *SNETCATEGORYLISTPROC )(_SNETPLAYERDATA *,SNETADDCATEGORYPROC); +typedef BOOL (CALLBACK *SNETCATEGORYPROC )(BOOL,_SNETPROGRAMDATA *,_SNETPLAYERDATA *,_SNETUIDATA *,_SNETVERSIONDATA *,DWORD *,DWORD *); +typedef BOOL (CALLBACK *SNETCHECKAUTHPROC )(DWORD,LPCSTR,LPCSTR,DWORD,LPCSTR,LPSTR,DWORD); +typedef BOOL (CALLBACK *SNETCREATEPROC )(SNETCREATEDATAPTR,_SNETPROGRAMDATA *,_SNETPLAYERDATA *,_SNETUIDATA *,_SNETVERSIONDATA *,DWORD *); +typedef BOOL (CALLBACK *SNETDRAWDESCPROC )(DWORD,DWORD,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,LPDRAWITEMSTRUCT); +typedef BOOL (CALLBACK *SNETENUMDEVICESPROC )(DWORD,LPCSTR,LPCSTR); +typedef BOOL (CALLBACK *SNETENUMGAMESEXPROC )(SNETGAMEPTR); +typedef BOOL (CALLBACK *SNETENUMGAMESPROC )(DWORD,LPCSTR,LPCSTR); +typedef BOOL (CALLBACK *SNETENUMPROVIDERSPROC)(DWORD,LPCSTR,LPCSTR,SNETCAPSPTR); +typedef void (CALLBACK *SNETEVENTPROC )(SNETEVENTPTR); +typedef BOOL (CALLBACK *SNETGETARTPROC )(DWORD,DWORD,LPPALETTEENTRY,LPBYTE,DWORD,int *,int *,int *); +typedef BOOL (CALLBACK *SNETGETDATAPROC )(DWORD,DWORD,LPVOID,DWORD,DWORD *); +typedef int (CALLBACK *SNETMESSAGEBOXPROC )(HWND,LPCSTR,LPCSTR,UINT); +typedef BOOL (CALLBACK *SNETPLAYSOUNDPROC )(DWORD,DWORD,DWORD); +typedef BOOL (CALLBACK *SNETSELECTEDPROC )(DWORD,SNETCAPSPTR,_SNETUIDATA *,_SNETVERSIONDATA *); +typedef BOOL (CALLBACK *SNETSTATUSPROC )(LPCSTR,DWORD,DWORD,DWORD,SNETABORTPROC); +typedef BOOL (CALLBACK *SNETPROFILEPROC )(); // tbd -- include callback to save info +typedef BOOL (CALLBACK *SNETNEWACCOUNTPROC )(); // tbd -- include callback to try to create + +typedef struct _SNETPLAYERDATA { + DWORD size; + LPCSTR playername; + LPCSTR playerdescription; + // new for 1.05: + LPCSTR displayedfields; +} SNETPLAYERDATA, *SNETPLAYERDATAPTR; + +typedef struct _SNETPROGRAMDATA { + DWORD size; + LPCSTR programname; + LPCSTR programdescription; + DWORD programid; + DWORD versionid; + DWORD reserved1; + DWORD maxplayers; + LPVOID initdata; + DWORD initdatabytes; + LPVOID reserved2; + DWORD optcategorybits; +} SNETPROGRAMDATA, *SNETPROGRAMDATAPTR; + +typedef struct _SNETUIDATA { + DWORD size; + DWORD uiflags; + HWND parentwindow; + SNETGETARTPROC artcallback; + SNETCHECKAUTHPROC authcallback; + SNETCREATEPROC createcallback; + SNETDRAWDESCPROC drawdesccallback; + SNETSELECTEDPROC selectedcallback; + SNETMESSAGEBOXPROC messageboxcallback; + SNETPLAYSOUNDPROC soundcallback; + SNETSTATUSPROC statuscallback; + SNETGETDATAPROC getdatacallback; + SNETCATEGORYPROC categorycallback; + // new for 1.05: + SNETCATEGORYLISTPROC categorylistcallback; + SNETNEWACCOUNTPROC newaccountcallback; + SNETPROFILEPROC profilecallback; +} SNETUIDATA, *SNETUIDATAPTR; + +typedef struct _SNETVERSIONDATA { + DWORD size; + LPCSTR versionstring; + LPCSTR executablefile; + LPCSTR originalarchivefile; + LPCSTR patcharchivefile; +} SNETVERSIONDATA, *SNETVERSIONDATAPTR; + +extern "C" BOOL APIENTRY SNetCreateGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamecategorybits, + LPVOID initdata, + DWORD initdatabytes, + DWORD maxplayers, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetDestroy (); +extern "C" BOOL APIENTRY SNetDropPlayer (DWORD playerid, DWORD exitcode); +extern "C" BOOL APIENTRY SNetEnumDevices (SNETENUMDEVICESPROC callback); +extern "C" BOOL APIENTRY SNetEnumGames (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESPROC callback, + DWORD *hintnextcall); +extern "C" BOOL APIENTRY SNetEnumGamesEx (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESEXPROC callback, + DWORD *hintnextcall); +extern "C" BOOL APIENTRY SNetEnumProviders (SNETCAPSPTR mincaps, + SNETENUMPROVIDERSPROC callback); +extern "C" BOOL APIENTRY SNetGetGameInfo (DWORD index, + LPVOID buffer, + DWORD buffersize, + DWORD *byteswritten); +extern "C" BOOL APIENTRY SNetGetNetworkLatency (DWORD measurementtype, + DWORD *result); +extern "C" BOOL APIENTRY SNetGetNumPlayers (DWORD *firstplayerid, + DWORD *lastplayerid, + DWORD *activeplayers); +extern "C" BOOL APIENTRY SNetGetOwnerId (DWORD *playerid); +extern "C" BOOL APIENTRY SNetGetOwnerTurnsWaiting (DWORD *turns); +extern "C" BOOL APIENTRY SNetGetPerformanceData (DWORD counterid, + DWORD *countervalue, + DWORD *countertype, + LONG *counterscale, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq); +extern "C" BOOL APIENTRY SNetGetPlayerCaps (DWORD playerid, + SNETCAPSPTR caps); +extern "C" BOOL APIENTRY SNetGetPlayerName (DWORD playerid, + LPSTR buffer, + DWORD buffersize); +extern "C" BOOL APIENTRY SNetGetProviderCaps (SNETCAPSPTR caps); +extern "C" BOOL APIENTRY SNetGetTurnsInTransit (DWORD *turns); +extern "C" BOOL APIENTRY SNetInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +extern "C" BOOL APIENTRY SNetInitializeProvider (DWORD providerid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +extern "C" BOOL APIENTRY SNetJoinGame (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetLeaveGame (DWORD exitcode); +extern "C" BOOL APIENTRY SNetPerformUpgrade (DWORD *upgradestatus); +extern "C" BOOL APIENTRY SNetReceiveMessage (DWORD *senderplayerid, + LPVOID *data, + DWORD *databytes); +extern "C" BOOL APIENTRY SNetReceiveTurns (DWORD firstplayerid, + DWORD arraysize, + LPVOID *arraydata, + LPDWORD arraydatabytes, + LPDWORD arrayplayerstatus); +extern "C" BOOL APIENTRY SNetRegisterEventHandler (DWORD eventid, + SNETEVENTPROC callback); +extern "C" BOOL APIENTRY SNetResetLatencyMeasurements (); +extern "C" BOOL APIENTRY SNetSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetSelectProvider (SNETCAPSPTR mincaps, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *providerid); +extern "C" BOOL APIENTRY SNetSendMessage (DWORD targetplayerid, + LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SNetSendServerChatCommand (LPCSTR command); +extern "C" BOOL APIENTRY SNetSendTurn (LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SNetSetBasePlayer (DWORD playerid); +extern "C" BOOL APIENTRY SNetSetGameMode (DWORD modeflags); +extern "C" BOOL APIENTRY SNetUnregisterEventHandler (DWORD eventid, + SNETEVENTPROC callback); + + +/**************************************************************************** +* +* Networking service provider interface +* +***/ + +#define SNETSPI_MAXCLIENTDATA 256 +#define SNETSPI_MAXSTRINGLENGTH 128 + +typedef struct _SNETADDR { + BYTE address[16]; +} SNETADDR, *SNETADDRPTR; + +typedef struct _SNETSPI_DEVICELIST { + DWORD deviceid; + SNETCAPS devicecaps; + char devicename[SNETSPI_MAXSTRINGLENGTH]; + char devicedescription[SNETSPI_MAXSTRINGLENGTH]; + DWORD reserved; + _SNETSPI_DEVICELIST *next; +} SNETSPI_DEVICELIST, *SNETSPI_DEVICELISTPTR; + +typedef struct _SNETSPI_GAMELIST { + DWORD gameid; + DWORD gamemode; + DWORD creationtime; + SNETADDR owner; + DWORD ownerlatency; + DWORD ownerlasttime; + DWORD gamecategorybits; + char gamename[SNETSPI_MAXSTRINGLENGTH]; + char gamedescription[SNETSPI_MAXSTRINGLENGTH]; + _SNETSPI_GAMELIST *next; + // new for 1.05: + LPVOID clientdata; + DWORD clientdatabytes; +} SNETSPI_GAMELIST, *SNETSPI_GAMELISTPTR; + +typedef struct _SNETSPI { + DWORD size; + BOOL (CALLBACK *CompareNetAddresses)(SNETADDRPTR,SNETADDRPTR,DWORD *); + BOOL (CALLBACK *Destroy)(); + BOOL (CALLBACK *Free)(SNETADDRPTR,LPVOID,DWORD); + BOOL (CALLBACK *FreeExternalMessage)(LPCSTR,LPCSTR,LPCSTR); + BOOL (CALLBACK *GetGameInfo)(DWORD,LPCSTR,LPCSTR,SNETSPI_GAMELIST *); + BOOL (CALLBACK *GetPerformanceData)(DWORD,DWORD *,LARGE_INTEGER *,LARGE_INTEGER *); + BOOL (CALLBACK *Initialize)(SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR,HANDLE); + BOOL (CALLBACK *InitializeDevice)(DWORD,SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR); + BOOL (CALLBACK *LockDeviceList)(SNETSPI_DEVICELISTPTR *); + BOOL (CALLBACK *LockGameList)(DWORD,DWORD,SNETSPI_GAMELISTPTR *); + +/* note: this is the way that the Receive call should look... + + BOOL (CALLBACK *Receive)(SNETADDRPTR *,LPVOID *,DWORD *); + + below is the receive call with two parameters switched around + to make it incompatible with older .snp's during the beta... */ + + BOOL (CALLBACK *Receive)(LPVOID *,DWORD *,SNETADDRPTR *); + + BOOL (CALLBACK *ReceiveExternalMessage)(LPCSTR *,LPCSTR *,LPCSTR *); + BOOL (CALLBACK *SelectGame)(DWORD,SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR,DWORD *); + BOOL (CALLBACK *Send)(DWORD,SNETADDRPTR *,LPVOID,DWORD); + BOOL (CALLBACK *SendExternalMessage)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR); + BOOL (CALLBACK *StartAdvertisingGame)(LPCSTR,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCVOID,DWORD); + BOOL (CALLBACK *StopAdvertisingGame)(); + BOOL (CALLBACK *UnlockDeviceList)(SNETSPI_DEVICELISTPTR); + BOOL (CALLBACK *UnlockGameList)(SNETSPI_GAMELISTPTR,DWORD *); + // new for 1.05: + BOOL (CALLBACK *GetLocalPlayerName)(LPSTR,DWORD,LPSTR,DWORD); +} SNETSPI, *SNETSPIPTR; + +typedef BOOL (APIENTRY *SNETSPIBIND )(DWORD,SNETSPIPTR *); +typedef BOOL (APIENTRY *SNETSPIQUERY)(DWORD,DWORD *,LPCSTR *,LPCSTR *,SNETCAPSPTR *); + + +/**************************************************************************** +* +* Registry functions +* +***/ + +#define SREG_FLAG_USERSPECIFIC 0x00000001 +#define SREG_FLAG_BATTLENET 0x00000002 +#define SREG_FLAG_FLUSHTODISK 0x00000008 +#define SREG_FLAG_MULTISZ 0x00000080 + +extern "C" BOOL APIENTRY SRegGetBaseKey (DWORD flags, + LPSTR buffer, + DWORD buffersize); +extern "C" BOOL APIENTRY SRegLoadData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID buffer, + DWORD buffersize, + DWORD *bytesread); +extern "C" BOOL APIENTRY SRegLoadString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SRegLoadValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD *value); +extern "C" BOOL APIENTRY SRegSaveData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SRegSaveString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPCTSTR string); +extern "C" BOOL APIENTRY SRegSaveValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD value); + + +/**************************************************************************** +* +* Region manager functions +* +***/ + +#define SRGN_AND RGN_AND +#define SRGN_COPY RGN_COPY +#define SRGN_DIFF RGN_DIFF +#define SRGN_OR RGN_OR +#define SRGN_XOR RGN_XOR +#define SRGN_PARAMONLY 6 +#define SRGN_MIN 1 +#define SRGN_MAX 6 + +DECLARE_STRICT_HANDLE(HSRGN); + +extern "C" void APIENTRY SRgnClear (HSRGN handle); +extern "C" void APIENTRY SRgnCombineRect (HSRGN handle, + LPCRECT rect, + LPVOID param, + int combinemode); +extern "C" void APIENTRY SRgnCreate (HSRGN *handle, + DWORD reserved = 0); +extern "C" void APIENTRY SRgnDelete (HSRGN handle); +#ifdef STORMSTATIC +extern "C" void APIENTRY SRgnDestroy (); +#endif +extern "C" void APIENTRY SRgnDuplicate (HSRGN orighandle, + HSRGN *handle, + DWORD reserved = 0); +extern "C" void APIENTRY SRgnGetBoundingRect (HSRGN handle, + LPRECT rect); +extern "C" void APIENTRY SRgnGetRectParams (HSRGN handle, + LPCRECT rect, + DWORD *numparams, + LPVOID *buffer); +extern "C" void APIENTRY SRgnGetRects (HSRGN handle, + DWORD *numrects, + LPRECT buffer); + +#define SRgnAddParam(handle,rect,param) SRgnCombineRect(handle,rect,param,SRGN_PARAMONLY); +#define SRgnAddRect(handle,rect,param) SRgnCombineRect(handle,rect,param,SRGN_OR) + + +/**************************************************************************** +* +* Run-time library functions +* +***/ + +#define ONCE ONCEEXPAND(__FILE__##__##__LINE__##__once) +#define ONCEEXPAND(a) BOOL a = TRUE; a; a = FALSE + +#define TRY goto trylabel; trylabel: +#define LEAVE goto finallylabel +#define FINALLY goto finallylabel; finallylabel: + + +/**************************************************************************** +* +* String functions +* +***/ + +#define SSTR_HASH_CASESENSITIVE 0x00000001 + +#define SSTR_UNBOUNDED 0x7FFFFFFF + +extern "C" LPTSTR APIENTRY SStrChr (LPCTSTR string, + char ch, + BOOL reverse = FALSE); +extern "C" DWORD APIENTRY SStrCopy (LPTSTR dest, + LPCTSTR source, + DWORD destsize = SSTR_UNBOUNDED); +extern "C" DWORD APIENTRY SStrHash (LPCTSTR string, + DWORD flags = 0, + DWORD seed = 0); +extern "C" DWORD APIENTRY SStrLen (LPCTSTR string); +extern "C" void APIENTRY SStrPack (LPTSTR dest, + LPCTSTR source, + DWORD destsize = SSTR_UNBOUNDED); +extern "C" void APIENTRY SStrTokenize (LPCTSTR *string, + LPTSTR buffer, + DWORD bufferchars, + LPCTSTR whitespace, + BOOL *quoted = NULL); + + +/**************************************************************************** +* +* Transparency functions +* +***/ + +#define STRANS_CF_INTERSECT 0x00000001 +#define STRANS_CF_INVERTSECOND 0x00000002 +#define STRANS_CF_SUBTRACT (STRANS_CF_INTERSECT | STRANS_CF_INVERTSECOND) + +DECLARE_STRICT_HANDLE(HSTRANS); +typedef HSTRANS HTRANS; + +extern "C" BOOL APIENTRY STransBlt (LPBYTE dest, + int destx, + int desty, + int destpitch, + HSTRANS transparency); +extern "C" BOOL APIENTRY STransBltUsingMask (LPBYTE dest, + LPBYTE source, + int destpitch, + int sourcepitch, + HSTRANS mask); +extern "C" BOOL APIENTRY STransCombineMasks (HSTRANS basemask, + HSTRANS secondmask, + int offsetx, + int offsety, + DWORD flags, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateMaskE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateMaskI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransDelete (HSTRANS handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY STransDestroy (); +#endif +extern "C" BOOL APIENTRY STransDuplicate (HSTRANS source, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransIntersectDirtyArray (HSTRANS sourcemask, + LPBYTE dirtyarray, + BYTE dirtyarraymask, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransInvertMask (HSTRANS sourcemask, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransIsPixelInMask (HSTRANS mask, + int offsetx, + int offsety); +extern "C" BOOL APIENTRY STransLoadE (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransLoadI (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransSetDirtyArrayInfo (int screencx, + int screency, + int cellcx, + int cellcy); +extern "C" BOOL APIENTRY STransUpdateDirtyArray (LPBYTE dirtyarray, + BYTE dirtyvalue, + int destx, + int desty, + HSTRANS transparency, + BOOL tracecontour); + +#ifdef STRANS_USE_INCLUSIVE_RECTS +#define STransCreate STransCreateI +#define STransCreateMask STransCreateMaskI +#define STransLoad STransLoadI +#else +#define STransCreate STransCreateE +#define STransCreateMask STransCreateMaskE +#define STransLoad STransLoadE +#endif + + +/**************************************************************************** +* +* Video functions +* +***/ + +#define SVID_FLAG_DOUBLESCANS 0x00000001 +#define SVID_FLAG_INTERPOLATE 0x00000002 +#define SVID_FLAG_INTERLACE 0x00000004 +#define SVID_FLAG_AUTOQUALITY 0x00000008 +#define SVID_FLAG_1XSIZE 0x00000100 +#define SVID_FLAG_2XSIZE 0x00000200 +#define SVID_FLAG_AUTOSIZE 0x00000800 +#define SVID_FLAG_FILEHANDLE 0x00010000 +#define SVID_FLAG_PRELOAD 0x00020000 +#define SVID_FLAG_LOOP 0x00040000 +#define SVID_FLAG_FULLSCREEN 0x00080000 +#define SVID_FLAG_USECURRENTPALETTE 0x00100000 +#define SVID_FLAG_CLEARSCREEN 0x00200000 +#define SVID_FLAG_NOSKIP 0x00400000 +#define SVID_FLAG_NEEDPAN 0x02000000 +#define SVID_FLAG_NEEDVOLUME 0x04000000 +#define SVID_FLAG_TOSCREEN 0x10000000 +#define SVID_FLAG_TOBUFFER 0x20000000 + +#define SVID_CUTSCENE (SVID_FLAG_TOSCREEN | SVID_FLAG_FULLSCREEN | SVID_FLAG_CLEARSCREEN | SVID_FLAG_2XSIZE) +#define SVID_AUTOCUTSCENE (SVID_FLAG_TOSCREEN | SVID_FLAG_FULLSCREEN | SVID_FLAG_CLEARSCREEN | SVID_FLAG_AUTOSIZE | SVID_FLAG_AUTOQUALITY) + +#define SVID_QUALITY_LOW_SKIPSCANS SVID_FLAG_2XSIZE +#define SVID_QUALITY_LOW (SVID_FLAG_2XSIZE | SVID_FLAG_DOUBLESCANS) +#define SVID_QUALITY_HIGH_SKIPSCANS (SVID_FLAG_2XSIZE | SVID_FLAG_INTERPOLATE) +#define SVID_QUALITY_HIGH (SVID_FLAG_2XSIZE | SVID_FLAG_INTERPOLATE | SVID_FLAG_DOUBLESCANS) + +DECLARE_STRICT_HANDLE(HSVIDEO); + +typedef struct _SVIDPALETTEUSE { + DWORD size; + DWORD firstentry; + DWORD numentries; +} SVIDPALETTEUSE, *SVIDPALETTEUSEPTR; + +extern "C" BOOL APIENTRY SVidDestroy (); +extern "C" BOOL APIENTRY SVidGetPerformanceData (HSVIDEO video, + BOOL averageframems, + DWORD *framems, + BOOL averagepalettems, + DWORD *palettems); +extern "C" BOOL APIENTRY SVidGetSize (HSVIDEO video, + int *width, + int *height, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SVidInitialize (LPVOID directsound); +extern "C" BOOL APIENTRY SVidPlayBegin (LPCTSTR filename, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle); +extern "C" BOOL APIENTRY SVidPlayBeginFromMemory (LPVOID sourceptr, + DWORD sourcebytes, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle); +extern "C" BOOL APIENTRY SVidPlayContinue (); +extern "C" BOOL APIENTRY SVidPlayContinueSingle (HSVIDEO video, + BOOL forceupdate, + BOOL *updated); +extern "C" BOOL APIENTRY SVidPlayEnd (HSVIDEO video); +extern "C" BOOL APIENTRY SVidSetVolume (HSVIDEO video, + LONG volume, + LONG pan, + DWORD track = 0); + + +/**************************************************************************** +* +* Storm global functions +* +***/ + +extern "C" BOOL APIENTRY StormDestroy (); + +#ifdef MAC +extern "C" void StormStartup(); +extern "C" void StormShutdown(); +#endif + + +//#########################################################################// +//#########################################################################// +// // +// // +// CLASS-BASED PROGRAMMING INTERFACE // +// (under construction) // +// // +// // +//#########################################################################// +//#########################################################################// + + +/**************************************************************************** +* +* CSLog +* +***/ + +class CSLog { + + private: + HSLOG m_handle; + + public: + + //======================================================================= + CSLog (LPCTSTR filename) { + SLogCreate(filename,0,&m_handle); + } + + //======================================================================= + CSLog (LPCTSTR keyname, + LPCTSTR valuename) { + char filename[MAX_PATH] = ""; + SRegLoadString(keyname,valuename,0,filename,MAX_PATH); +#ifdef _DEBUG + SRegSaveString(keyname,valuename,0,filename); +#endif + if (filename[0]) + SLogCreate(filename,0,&m_handle); + } + + //======================================================================= + ~CSLog () { + SLogClose(m_handle); + } + + //======================================================================= + void Dump (LPCVOID data, + DWORD bytes) { + SLogDump(m_handle, + data, + bytes); + } + + //======================================================================= + void Flush () { + SLogFlush(m_handle); + } + + //======================================================================= + HSLOG GetHandle () { + return m_handle; + } + + //======================================================================= + void Pend (LPCSTR string) { + SLogPend(m_handle, + string); + } + + //======================================================================= + void Write (LPCSTR string) { + SLogWrite(m_handle, + string); + } + +}; + + +/**************************************************************************** +* +* CSRgn +* +***/ + +class CSRgn { + + private: + HSRGN m_handle; + + //======================================================================= + void CopyConstructor (const CSRgn & source) { + SRgnDuplicate(source.m_handle, + &m_handle); + } + + public: + + //======================================================================= + CSRgn () { + SRgnCreate(&m_handle); + } + + //======================================================================= + CSRgn (const CSRgn & source) { + CopyConstructor(source); + } + + //======================================================================= + ~CSRgn () { + SRgnDelete(m_handle); + } + + //======================================================================= + CSRgn & operator= (const CSRgn &source) { + if (this != &source) { + this->~CSRgn(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + void AddParam (LPCRECT rect, + LPVOID param) { + SRgnAddParam(m_handle, + rect, + param); + } + + //======================================================================= + void AddRect (LPCRECT rect, + LPVOID param) { + SRgnAddRect(m_handle, + rect, + param); + } + + //======================================================================= + void Clear () { + SRgnClear(m_handle); + } + + //======================================================================= + void CombineRect (LPCRECT rect, + LPVOID param, + int combinemode) { + SRgnCombineRect(m_handle, + rect, + param, + combinemode); + } + + //======================================================================= + void GetBoundingRect (LPRECT rect) { + SRgnGetBoundingRect(m_handle, + rect); + } + + //======================================================================= + void GetRects (DWORD *numrects, + LPRECT buffer) { + SRgnGetRects(m_handle, + numrects, + buffer); + } + + //======================================================================= + void GetRectParams (LPCRECT rect, + DWORD *numparams, + LPVOID *buffer) { + SRgnGetRectParams(m_handle, + rect, + numparams, + buffer); + } + +}; + + +//#########################################################################// +//#########################################################################// +// // +// // +// UTILITY CLASSES AND TEMPLATES // +// // +// // +//#########################################################################// +//#########################################################################// + + +/**************************************************************************** +* +* CCritSect -- Critical section class +* +* Methods: +* +* void Enter () +* void Leave () +* +***/ + +class CCritSect { + private: + CRITICAL_SECTION m_critsect; + public: + CCritSect () { InitializeCriticalSection(&m_critsect); } + ~CCritSect () { DeleteCriticalSection(&m_critsect); } + void Enter () { EnterCriticalSection(&m_critsect); } + void Enter (BOOL) { EnterCriticalSection(&m_critsect); } + void Leave () { LeaveCriticalSection(&m_critsect); } + void Leave (BOOL) { LeaveCriticalSection(&m_critsect); } +}; + + +/**************************************************************************** +* +* CLock -- Reader/writer lock class +* +* Methods: +* +* void Enter (BOOL forwriting) +* void Leave (BOOL fromwriting) +* +***/ + +class CLock { + + private: + + HANDLE m_mutexevent; + HANDLE m_readerevent; + LONG m_readercount; + + public: + + //======================================================================= + CLock () { + m_mutexevent = CreateEvent(NULL,FALSE,TRUE,NULL); + m_readerevent = CreateEvent(NULL,TRUE,FALSE,NULL); + m_readercount = -1; + } + + //======================================================================= + ~CLock () { + CloseHandle(m_readerevent); + CloseHandle(m_mutexevent); + } + + //======================================================================= + void Enter (BOOL forwriting) { + if (forwriting) + WaitForSingleObject(m_mutexevent,INFINITE); + else if (!InterlockedIncrement(&m_readercount)) { + WaitForSingleObject(m_mutexevent,INFINITE); + SetEvent(m_readerevent); + } + else + WaitForSingleObject(m_readerevent,INFINITE); + } + + //======================================================================= + void Leave (BOOL fromwriting) { + if (fromwriting) + SetEvent(m_mutexevent); + else if (InterlockedDecrement(&m_readercount) < 0) { + ResetEvent(m_readerevent); + SetEvent(m_mutexevent); + } + } + +}; + + +/**************************************************************************** +* +* CNullSync -- Null synchronization class +* +* (used for templates that take a synchronization class as a parameter) +* +***/ + +class CNullSync { + public: + void Enter (BOOL) { } + void Leave (BOOL) { } +}; + + +/**************************************************************************** +* +* type_info +* +* (used by templates to obtain the name of an object) +* +***/ + +#ifdef _MSC_VER + #ifdef _INC_TYPEINFO + #define INTERNALRAWNAME raw_name + #else + #define INTERNALRAWNAME internal_raw_name + class type_info { + public: + virtual ~type_info (); + const char * internal_raw_name () const { return _m_d_name; }; + private: + void *_m_data; + char _m_d_name[1]; + type_info (const type_info& rhs); + type_info& operator= (const type_info& rhs); + }; + #endif +#else + #if defined(MAC) && !defined(__typeinfo__) + #include + #endif + #define INTERNALRAWNAME name +#endif + + +/**************************************************************************** +* +* ARRAY -- Dynamically allocated array template +* +* Types: +* +* ARRAY(structname) -- dynamically sized array of struct +* +* Pointers to types: +* +* ARRAYPTR(structname) +* +* Array methods: +* +* void AddDiscontiguousElements (DWORD count, +* int stride, +* const *newelements); +* void AddElement (const *newelement); +* void AddElements (DWORD count, +* const *newelements); +* DWORD NumElements (); +* * NewElement (); +* * Ptr (); +* void ReserveSpace (DWORD count); +* void SetNumElements (DWORD totalcount); +* +***/ + +template +class TSArray { + + private: + DWORD m_allocchunksize; + T *m_data; + DWORD m_elements; + DWORD m_elementsalloc; + + //======================================================================= + BOOL CheckSpace (DWORD count) { + return (m_elements+count <= m_elementsalloc); + } + + //======================================================================= + void Constructor () { + m_allocchunksize = max(16,256/sizeof(T)); + m_data = NULL; + m_elements = 0; + m_elementsalloc = 0; + } + + //======================================================================= + void CopyConstructor (const TSArray & source) { + Constructor(); + m_allocchunksize = source.m_allocchunksize; + ReserveSpace(source.m_elementsalloc); + AddElements(source.m_elements, + source.m_data); + } + + public: + + //======================================================================= + TSArray () { + Constructor(); + } + + //======================================================================= + TSArray (const TSArray & source) { + CopyConstructor(source); + } + + //======================================================================= + ~TSArray () { + if (m_data) { + while (m_elements) { + --m_elements; + m_data[m_elements].~T(); + } + SMemFree(m_data,__FILE__,__LINE__,0); + m_data = NULL; + } + } + + //======================================================================= + TSArray & operator= (const TSArray &source) { + if (this != &source) { + this->~TSArray(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + T & operator[] (DWORD num) { + if (num >= m_elements) + SErrDisplayError(STORM_ERROR_ACCESS_OUT_OF_BOUNDS, + typeid(T).INTERNALRAWNAME(), + SERR_LINECODE_OBJECT, + NULL, + TRUE); + return m_data[num]; + } + + //======================================================================= + void AddDiscontiguousElements (DWORD count, + int stride, + const T *newelements) { + if (!CheckSpace(count)) + ReserveSpace(count); + if (stride == sizeof(T)) + AddElements(count,newelements); + else + for (DWORD loop = 0; loop < count; ++loop) { + new(m_data+m_elements++) T(*newelements); + newelements = (const T *)((LPBYTE)newelements+stride); + } + } + + //======================================================================= + void AddElement (const T *newelement) { + if (!CheckSpace(1)) + ReserveSpace(1); + new(m_data+m_elements++) T(*newelement); + } + + //======================================================================= + void AddElements (DWORD count, + const T *newelements) { + if (!CheckSpace(count)) + ReserveSpace(count); + for (DWORD loop = 0; loop < count; ++loop) + new(m_data+m_elements++) T(newelements[loop]); + } + + //======================================================================= + DWORD NumElements () { + return m_elements; + } + + //======================================================================= + T * NewElement () { + if (!CheckSpace(1)) + ReserveSpace(1); + return new(m_data+m_elements++) T; + } + + //======================================================================= + T * Ptr () { + if (!m_data) + ReserveSpace(1); + return m_data; + } + + //======================================================================= + void ReserveSpace (DWORD count) { + if (CheckSpace(count)) + return; + + // DETERMINE THE NUMBER OF NEW ELEMENTS TO ALLOCATE + DWORD newelements = m_elements+count; + DWORD partialchunk = newelements & (m_allocchunksize-1); + if (partialchunk) + newelements += m_allocchunksize-partialchunk; + + // ALLOCATE THE NEW ARRAY AND COPY DATA FROM THE OLD ARRAY + T *newdata = (T *)ALLOC(newelements*sizeof(T)); + if (m_data) { + for (DWORD loop = 0; loop < m_elements; ++loop) + new(newdata+loop) T(m_data[loop]); + FREE(m_data); + } + m_data = newdata; + m_elementsalloc = newelements; + + } + + //======================================================================= + void SetNumElements (DWORD totalcount) { + if (totalcount > m_elements) { + ReserveSpace(totalcount-m_elements); + for (DWORD loop = m_elements; loop < totalcount; ++loop) + new(m_data+loop) T; + } + else if (totalcount < m_elements) { + for (DWORD loop = totalcount; loop < m_elements; ++loop) + m_data[loop].~T(); + } + m_elements = totalcount; + } + +}; + +#define ARRAY(structname) TSArray< structname > +#define ARRAYDECL(structname,varname) TSArray< structname > varname +#define ARRAYPTR(structname) TSArray< structname > * + + +/**************************************************************************** +* +* NODE/LIST -- Linked list template +* +* Types: +* +* LINKEX(structname) -- explicit link field +* LIST(structname) -- linked list of implicitly linked nodes +* LISTEX(structname,linkname) -- linked list of explicitly linked nodes +* LISTEXDYN(structname) -- linked list of explicitly linked nodes, +* where the link field to be used by +* this list is not known at compile time +* NODEDECL(structname) -- implicitly linked node +* NODEDECLEX(structname) -- explicitly linked node (must contain one +* or more LINKEX fields) +* +* Pointers to types: +* +* LISTPTR(structname) +* LISTPTREX(structname) +* +* Link methods: +* +* * Next (); +* * Prev (); +* void Unlink (); +* +* Explicitly linked node methods: +* +* None. Use link methods for the link you want to manipulate. +* +* Implicitly linked node methods: +* +* * Next (); +* * Prev (); +* void Unlink (); +* +* List methods: +* +* void Clear (); +* * DeleteNode ( *ptr); +* * Head () const; +* BOOL IsEmpty () const; +* void LinkNode ( *ptr, +* DWORD linktype = LIST_TAIL, +* *existingptr = NULL); +* * NewNode (DWORD location = LIST_TAIL, +* DWORD extrabytes = 0, +* DWORD flags = 0); +* * Next (const *ptr) const; +* * Prev (const *ptr) const; +* * Tail () const; +* void UnlinkAll (); +* void UnlinkNode ( *ptr); +* +* Constants for use with LinkNode() and NewNode(): +* +* LIST_UNLINKED +* LIST_LINK_AFTER +* LIST_LINK_BEFORE +* LIST_HEAD +* LIST_TAIL +* +* Macros: +* +* LISTEXSETLINK(structname,listname,linkname) +* ITERATELIST(structname,listname,ptrname) +* ITERATELISTPTR(structname,listname,ptrname) +* ITERATEPARTIALLIST(structname,listname,start,ptrname) +* ITERATEPARTIALLISTPTR(structname,listname,start,ptrname) +* ITERATELISTREVERSE(structname,listname,ptrname) +* ITERATELISTREVERSEPTR(structname,listname,ptrname) +* ITERATEPARTIALLISTREVERSE(structname,listname,start,ptrname) +* ITERATEPARTIALLISTREVERSEPTR(structname,listname,start,ptrname) +* ITERATE_DELETE +* ITERATE_DELETEANDBREAK +* +***/ + +#define LIST_UNLINKED 0 +#define LIST_LINK_AFTER 1 +#define LIST_LINK_BEFORE 2 +#define LIST_HEAD LIST_LINK_AFTER +#define LIST_TAIL LIST_LINK_BEFORE + +template +class TSList; + +template +class TSLink { + friend class TSList; + friend class TSList; + + private: + TSLink *m_prevlink; + T *m_next; + + //======================================================================= + void Constructor () { + m_prevlink = NULL; + m_next = NULL; + } + + //======================================================================= + void CopyConstructor (const TSLink &) { + Constructor(); + } + + //======================================================================= + TSLink *NextLink () const { + + // IF THE NEXT NODE IS A TERMINATOR, ITS LINK POINTER IS THE SAME AS + // ITS NODE POINTER. + if ((int)m_next < 0) + return (TSLink *)~(DWORD)m_next; + + // OTHERWISE, COMPUTE THE LINK ADDRESS BY USING THE OFFSET OF THIS + // NODE'S LINK AND POINTER ADDRESSES. (THIS NODE MUST NOT BE A + // TERMINATOR.) + else { + DWORD linkoffset = (DWORD)this-(DWORD)(m_prevlink->m_next); + return (TSLink *)(linkoffset+(DWORD)m_next); + } + + } + + protected: + + //======================================================================= + T *NextThroughTerminator () const { + return ((int)m_next > 0) ? m_next : (T *)~(DWORD)m_next; + } + + public: + + //======================================================================= + TSLink () { + Constructor(); + } + + //======================================================================= + TSLink (const TSLink & source) { + CopyConstructor(source); + } + + //======================================================================= + ~TSLink () { + Unlink(); + } + + //======================================================================= + TSLink & operator= (const TSLink &) { + // LEAVE THE DESTINATION NODE LINKED INTO ITS CURRENT LIST + return *this; + } + + //======================================================================= + T * Next () const { + return ((int)m_next > 0) ? m_next : NULL; + } + + //======================================================================= + T * Prev () const { + return m_prevlink->m_prevlink->Next(); + } + + //======================================================================= + void Unlink () { + if (!m_prevlink) + return; + NextLink()->m_prevlink = m_prevlink; + m_prevlink->m_next = m_next; + m_prevlink = NULL; + m_next = NULL; + } + +}; + +template +class TSBaseNode { + public: + + //======================================================================= + inline void * __cdecl operator new (size_t bytes, + size_t extra, + DWORD flags) { + void *ptr = SMemAlloc(bytes+extra, + typeid(T).INTERNALRAWNAME(), + SERR_LINECODE_OBJECT, + flags | SMEM_FLAG_ZEROMEMORY); + return ptr; + } + +}; + +template +class TSExplicitNode : public TSBaseNode { + friend class TSList; + + private: + + //======================================================================= + TSLink *Link (BOOL explicitlink, int linkoffset) const { + ASSERT(explicitlink); + explicitlink; + return (TSLink *)((LPBYTE)this+linkoffset); + } + +}; + +template +class TSLinkedNode : public TSBaseNode { + friend class TSList; + + private: + TSLink m_link; + + //======================================================================= + TSLink *Link (BOOL explicitlink, int linkoffset) const { + if (explicitlink) + return (TSLink *)((LPBYTE)this+linkoffset); + else + return (TSLink *)&m_link; + } + + public: + + //======================================================================= + ~TSLinkedNode () { + Unlink(); + } + + //======================================================================= + T * Next () const { + return m_link.Next(); + } + + //======================================================================= + T * Prev () const { + return m_link.Prev(); + } + + //======================================================================= + void Unlink () { + m_link.Unlink(); + } + +}; + +template +class TSList { + + private: + int m_linkoffset; + TSLink m_terminator; + + //======================================================================= + void Constructor () { + m_linkoffset = 0; + InitializeTerminator(); + } + + //======================================================================= + void CopyConstructor (const TSList & source) { + m_linkoffset = source.m_linkoffset; + InitializeTerminator(); + } + + //======================================================================= + void InitializeTerminator () { + m_terminator.m_prevlink = &m_terminator; + m_terminator.m_next = (T *)~(DWORD)&m_terminator; + } + + //======================================================================= + TSLink *Link (const T *ptr) const { + // THIS FUNCTION CALLS THE LINK METHOD IN EITHER THE NODE OR THE LINK + // TO WHICH THIS LIST REFERS. IF THIS FUNCTION WON'T COMPILE, IT'S + // BECAUSE A NODE WITH EXPLICIT LINKS WAS DEFINED WITH NODEDECL() + // INSTEAD OF NODEDECLEX(). + return ptr->Link(explicitlink,m_linkoffset); + } + + protected: + + //======================================================================= + void SetLinkOffset (int linkoffset) { + m_linkoffset = linkoffset; + InitializeTerminator(); + } + + public: + + //======================================================================= + TSList () { + Constructor(); + }; + + //======================================================================= + TSList (const TSList &source) { + CopyConstructor(source); + }; + + //======================================================================= + TSList (int linkoffset) { + m_linkoffset = linkoffset; + InitializeTerminator(); + }; + + //======================================================================= + ~TSList () { + UnlinkAll(); + } + + //======================================================================= + TSList & operator= (const TSList &source) { + if (this != &source) { + this->~TSList(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + void ChangeLinkOffset (int linkoffset) { + UnlinkAll(); + SetLinkOffset(linkoffset); + } + + //======================================================================= + void Clear () { + T *curr; + while ((curr = Head()) != NULL) + delete curr; + } + + //======================================================================= + T * DeleteNode (T *ptr) { + T *nextptr = Next(ptr); + delete ptr; + return nextptr; + } + + //======================================================================= + T * Head () const { + return m_terminator.Next(); + } + + //======================================================================= + BOOL IsEmpty () const { + return !m_terminator.Next(); + } + + //======================================================================= + T * Iterate_RawNext (const T *ptr) const { + return Link(ptr)->m_next; + } + + //======================================================================= + void LinkNode (T *ptr, + DWORD linktype = LIST_TAIL, + T *existingptr = NULL) { + TSLink *link = Link(ptr); + + // IF THIS NODE IS ALREADY LINKED INTO THE LIST, UNLINK IT + if (link->m_prevlink) + link->Unlink(); + + // FIND THE NODE THAT WE WILL LINK BEFORE OR AFTER. USE THE + // TERMINATOR NODE IF WE'RE LINKING ONTO THE HEAD OR TAIL. + TSLink *existinglink; + if (existingptr) + existinglink = Link(existingptr); + else + existinglink = &m_terminator; + + // LINK THIS NODE INTO THE LIST + switch (linktype) { + + case LIST_LINK_AFTER: + { + link->m_prevlink = existinglink; + link->m_next = existinglink->m_next; + Link(existinglink->NextThroughTerminator())->m_prevlink = link; + existinglink->m_next = ptr; + } + break; + + case LIST_LINK_BEFORE: + { + TSLink *prevlink = existinglink->m_prevlink; + link->m_prevlink = prevlink; + link->m_next = prevlink->m_next; + prevlink->m_next = ptr; + existinglink->m_prevlink = link; + } + break; + + } + } + + //======================================================================= + T * NewNode (DWORD location = LIST_TAIL, + DWORD extrabytes = 0, + DWORD flags = 0) { + T *ptr = new(extrabytes,flags) T; + if (location != LIST_UNLINKED) + LinkNode(ptr,location); + return ptr; + } + + //======================================================================= + T * Next (const T *ptr) const { + return Link(ptr)->Next(); + } + + //======================================================================= + T * Prev (const T *ptr) const { + return Link(ptr)->Prev(); + } + + //======================================================================= + T * Tail () const { + return m_terminator.Prev(); + } + + //======================================================================= + void UnlinkAll () { + T *curr; + while ((curr = Head()) != NULL) + UnlinkNode(curr); + } + + //======================================================================= + void UnlinkNode (T *ptr) { + Link(ptr)->Unlink(); + } + +}; + +template +class TSExplicitList : public TSList { + public: + + //======================================================================= + TSExplicitList () { + SetLinkOffset(linkoffset); + } + +}; + + +#define LINKEX(structname) TSLink< structname > +#define LINKDECLEX(structname,varname) TSLink< structname > varname +#define LIST(structname) TSList< structname ,FALSE> +#define LISTDECL(structname,varname) TSList< structname ,FALSE> varname +#define LISTPTR(structname) TSList< structname ,FALSE> * +#define LISTPTREX(structname) TSList< structname ,TRUE> * +#define NODEDECL(structname) typedef struct structname : public TSLinkedNode< structname > +#define NODEDECLEX(structname) typedef struct structname : public TSExplicitNode< structname > + +#define LISTEX(structname,linkname) \ + TSExplicitList< structname ,(int)&(((structname *)0)->linkname)> + +#define LISTEXDYN(structname) \ + TSExplicitList< structname ,(int)0xDDDDDDDD> + +#define LISTEXSETLINK(structname,listname,linkname) \ + listname.ChangeLinkOffset((int)&(((structname *)0)->linkname)); + +#define LISTDECLEX(structname,linkname,varname) \ + TSExplicitList< structname ,(int)&(((structname *)0)->linkname)> varname + +#define ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,op) \ + for (structname *ptrname = start, \ + *iterate_delete = NULL; \ + (int)ptrname > 0; \ + iterate_delete \ + ? (ptrname = (listname)##op##DeleteNode(ptrname), \ + ptrname = ((int)iterate_delete > 0) ? ptrname : NULL, \ + iterate_delete = NULL, \ + ptrname) \ + : ptrname = (listname)##op##Iterate_RawNext(ptrname)) + +#define ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,op) \ + for (structname *ptrname = start, \ + *iterate_delete = NULL, \ + *iterate_delete_temp = NULL; \ + ptrname; \ + iterate_delete \ + ? (iterate_delete_temp = ((int)iterate_delete > 0) \ + ? (listname)##op##Prev(ptrname) \ + : NULL, \ + (listname)##op##DeleteNode(ptrname), \ + iterate_delete = NULL, \ + ptrname = iterate_delete_temp) \ + : ptrname = (listname)##op##Prev(ptrname)) + +#define ITERATELIST(structname,listname,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,(listname).Head(),ptrname,.) + +#define ITERATELISTPTR(structname,listname,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,(listname)->Head(),ptrname,->) + +#define ITERATEPARTIALLIST(structname,listname,start,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,.) + +#define ITERATEPARTIALLISTPTR(structname,listname,start,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,->) + +#define ITERATELISTREVERSE(structname,listname,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,(listname).Tail(),ptrname,.) + +#define ITERATELISTREVERSEPTR(structname,listname,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,(listname)->Tail(),ptrname,->) + +#define ITERATEPARTIALLISTREVERSE(structname,listname,start,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,.) + +#define ITERATEPARTIALLISTREVERSEPTR(structname,listname,start,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,->) + +#define ITERATE_DELETE \ + { \ + ++iterate_delete; \ + continue; \ + } + +#define ITERATE_DELETEANDBREAK \ + { \ + --iterate_delete; \ + continue; \ + } + + +/**************************************************************************** +* +* EXPORTOBJECT/EXPORTTABLE -- Export manager template +* +* Types: +* +* DECLARE_STRICT_HANDLE(handle) -- handle to object +* DECLARE_STRICT_HANDLE(lockedhandle) -- handle to locked object +* EXPORTOBJECTDECL(structname) -- object to be exported +* EXPORTTABLE(structname,handlename,lockedhandlename,synctype) +* EXPORTTABLEREUSE(structname,handlename,lockedhandlename,synctype) +* +* Export table methods: +* +* void Delete ( handle); +* void DeleteUnlock ( *ptr, +* lockedhandle); +* void Destroy (); +* * Lock ( handle, +* *lockedhandle, +* BOOL forwriting = FALSE); +* void New ( *handle); +* * NewLock ( *handle, +* *lockedhandle); +* void Unlock ( lockedhandle); +* +* Synchronization types for use with EXPORTTABLE(): +* +* SYNC_NONE -- use no synchronization +* SYNC_READWRITE -- use a reader/writer lock +* SYNC_ALWAYS -- use a critical section +* +***/ + +template +class TSExportTableBase { + + protected: + + //======================================================================= + T * BaseFindByHandle (LISTPTREX(T) list, unsigned handle) { + ITERATELISTPTR(T,list,curr) + if (curr->m_handle == handle) + return curr; + return NULL; + } + + //======================================================================= + T * BaseFindByHandleEx (LISTPTREX(T) list, unsigned handle, unsigned *count) { + *count = 0; + ITERATELISTPTR(T,list,curr) + if (curr->m_handle == handle) + return curr; + else + ++*count; + return NULL; + } + + //======================================================================= + unsigned BaseGetHandle (const T *ptr) { + return ptr->m_handle; + } + + //======================================================================= + int BaseGetLinkOffset () { + return (int)&(((T *)0)->m_linktoslot); + } + + //======================================================================= + void BaseSetHandle (T *ptr, unsigned handle) { + ptr->m_handle = handle; + } + +}; + +template +class TSExportTable : public TSExportTableBase { + + private: + ARRAY(LISTEXDYN(T)) m_listarray; + LISTEXDYN(T) m_reuselist; + H m_sequence; + unsigned m_slotmask; + SYNC m_sync; + + //======================================================================= + unsigned ComputeSlot (H handle) { + return (unsigned)handle & m_slotmask; + } + + //======================================================================= + H GenerateUniqueHandle () { + unsigned count; + for (;;) { + m_sequence = (H)((unsigned)m_sequence+1); + if (!BaseFindByHandleEx(&m_listarray[ComputeSlot(m_sequence)], + (unsigned)m_sequence, + &count)) + break; + } + if (count >= 4) + GrowListArray(); + return m_sequence; + } + + //======================================================================= + void GrowListArray () { +return; // note: out for testing + if (m_slotmask >= 1023) + return; + + // DETERMINE THE NEW ARRAY SIZE + unsigned oldarraysize = m_slotmask+1; + unsigned newarraysize = oldarraysize*2; + + // GROW THE ARRAY + { + m_listarray.SetNumElements(newarraysize); + int linkoffset = BaseGetLinkOffset(); + for (unsigned slot = oldarraysize; slot < newarraysize; ++slot) + m_listarray[slot].ChangeLinkOffset(linkoffset); + } + + // MOVE ALL RECORDS FROM THE OLD LISTS TO THE NEW LISTS + m_slotmask = newarraysize-1; + { + for (unsigned slot = 0; slot < oldarraysize; ++slot) { + T *currptr = m_listarray[slot].Head(); + while (currptr) { + T *nextptr = m_listarray[slot].Next(currptr); + unsigned newslot = ComputeSlot((H)BaseGetHandle(currptr)); + if (newslot != slot) { + m_listarray[slot].UnlinkNode(currptr); + m_listarray[newslot].LinkNode(currptr); + } + currptr = nextptr; + } + } + } + + } + + //======================================================================= + BOOL IsForWriting (LH lockedhandle) { + return (lockedhandle == (LH)1); + } + + //======================================================================= + void SyncEnterLock (LH *lockedhandle, BOOL forwriting) { + m_sync.Enter(forwriting); + *lockedhandle = (LH)(forwriting ? 1 : -1); + } + + //======================================================================= + void SyncLeaveLock (LH lockedhandle) { + if (lockedhandle) + m_sync.Leave(IsForWriting(lockedhandle)); + } + + public: + + //======================================================================= + TSExportTable () { + m_sequence = (H)0; + m_slotmask = 3; + m_listarray.SetNumElements(m_slotmask+1); + int linkoffset = BaseGetLinkOffset(); + for (unsigned slot = 0; slot <= m_slotmask; ++slot) + m_listarray[slot].ChangeLinkOffset(linkoffset); + m_reuselist.ChangeLinkOffset(linkoffset); + } + + //======================================================================= + ~TSExportTable () { + Destroy(); + } + + //======================================================================= + void Delete (H handle) { + LH lockedhandle; + T *ptr = Lock(handle,&lockedhandle,TRUE); + DeleteUnlock(ptr,lockedhandle); + } + + //======================================================================= + void DeleteUnlock (T *ptr, + LH lockedhandle) { + if (ptr) + if (REUSE) + m_reuselist.LinkNode(ptr); + else + delete ptr; + Unlock(lockedhandle); + } + + //======================================================================= + void Destroy () { + LH lockedhandle; + SyncEnterLock(&lockedhandle,TRUE); + for (unsigned slot = 0; slot <= m_slotmask; ++slot) { + T *curr; + while ((curr = m_listarray[slot].Head()) != NULL) { + delete curr; + SErrReportResourceLeak(typeid(H).INTERNALRAWNAME()); + } + } + m_reuselist.Clear(); + SyncLeaveLock(lockedhandle); + } + + //======================================================================= + T * Lock (H handle, + LH *lockedhandle, + BOOL forwriting = FALSE) { + SyncEnterLock(lockedhandle,forwriting); + T *result = BaseFindByHandle(&m_listarray[ComputeSlot(handle)], + (unsigned)handle); + if (!result) { + SyncLeaveLock(*lockedhandle); + *lockedhandle = (LH)0; + } + return result; + } + + //======================================================================= + void New (H *handle) { + LH lockedhandle; + NewLock(handle,&lockedhandle); + Unlock(lockedhandle); + } + + //======================================================================= + T * NewLock (H *handle, LH *lockedhandle) { + SyncEnterLock(lockedhandle,TRUE); + H newhandle = GenerateUniqueHandle(); + T *ptr = NULL; + if (REUSE) { + ptr = m_reuselist.Head(); + if (ptr) + m_listarray[ComputeSlot(newhandle)].LinkNode(ptr); + } + if (!ptr) + ptr = m_listarray[ComputeSlot(newhandle)].NewNode(); + BaseSetHandle(ptr,(unsigned)newhandle); + *handle = newhandle; + return ptr; + } + + //======================================================================= + void Unlock (LH lockedhandle) { + SyncLeaveLock(lockedhandle); + } + +}; + +template +class TSExportObject : public TSExplicitNode { + friend class TSExportTableBase; + + private: + unsigned m_handle; + LINKEX(T) m_linktoslot; + + public: + + //======================================================================= + TSExportObject () { + } + + //======================================================================= + TSExportObject (const TSExportObject &source) { + } + + //======================================================================= + TSExportObject & operator= (const TSExportObject &source) { + // COPY THE OBJECT DATA, BUT DON'T OVERWRITE THE DESTINATION OBJECT'S + // HANDLE OR LINK + return *this; + } + +}; + +#define SYNC_NONE CNullSync +#define SYNC_READWRITE CLock +#define SYNC_ALWAYS CCritSect + +#define EXPORTOBJECTDECL(structname) \ + typedef struct structname : public TSExportObject< structname > + +#define EXPORTTABLE(structname,handlename,lockedhandlename,synctype) \ + TSExportTable + +#define EXPORTTABLEREUSE(structname,handlename,lockedhandlename,synctype) \ + TSExportTable + + +/**************************************************************************** +* +* SWAP -- Swap template +* +* Macros: +* +* SWAP(a,b) +* +***/ + +//=========================================================================== +template +void inline TSSwap (T &a, T &b) { + T temp = a; + a = b; + b = temp; +} +#define SWAP(a,b) TSSwap(a,b) + + +/**************************************************************************** +* +* Old TList Template -- Obsolete!! +* +***/ + +//=========================================================================== +template +BOOL inline TListAdd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return FALSE; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber,0); + if (!newptr) + return FALSE; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = *head; + *head = newptr; + return TRUE; +} +#define LISTADD(a,b) TListAdd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddEnd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return FALSE; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber,0); + if (!newptr) + return FALSE; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = NULL; + + T **next = head; + while (*next) + next = &(*next)->next; + *next = newptr; + + return TRUE; +} +#define LISTADDEND(a,b) TListAddEnd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddPtr (T **head, T *ptr) { + if (!(head && ptr)) + return FALSE; + + ptr->next = *head; + *head = ptr; + return TRUE; +} +#define LISTADDPTR(a,b) TListAddPtr(a,b) + +//=========================================================================== +template +BOOL inline TListAddPtrEnd (T **head, T *ptr) { + if (!(head && ptr)) + return FALSE; + + ptr->next = NULL; + T **next = head; + while (*next) + next = &(*next)->next; + *next = ptr; + + return TRUE; +} +#define LISTADDPTREND(a,b) TListAddPtrEnd(a,b) + +//=========================================================================== +template +BOOL inline TListClear (T **head, LPCSTR filename = NULL, int linenumber = 0) { + if (!head) + return FALSE; + + while (*head) { + T *next = (*head)->next; + SMemFree(*head,filename,linenumber,0); + *head = next; + } + return TRUE; +} +#define LISTCLEAR(a) TListClear(a,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFree (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return FALSE; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + SMemFree(ptr,filename,linenumber,0); + return (*next != NULL); +} +#define LISTFREE(a,b) TListFree(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFreePtr (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return FALSE; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + return (*next != NULL); +} +#define LISTFREEPTR(a,b) TListFreePtr(a,b,(LPCSTR)__FILE__,__LINE__) + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import off +#endif + +#endif // ifndef _STORM_H_ diff --git a/OBJDAT.CPP b/OBJDAT.CPP new file mode 100644 index 0000000..937f11d --- /dev/null +++ b/OBJDAT.CPP @@ -0,0 +1,624 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Objects file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/OBJDAT.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "objects.h" +#include "objdat.h" +#include "quests.h" + +/*-----------------------------------------------------------------------*/ + +int ObjTypeConv[] = { + 0, + OBJ_LEVER, + OBJ_CRUX1, + OBJ_CRUX2, + OBJ_CRUX3, + OBJ_ANGEL, + OBJ_BANNERL, + OBJ_BANNERM, + OBJ_BANNERR, + OBJ_BLADEL, + OBJ_BLADER, + OBJ_BLOCK, + OBJ_BOOK1L, + OBJ_BOOK1R, + OBJ_BOOK2L, + OBJ_BOOK2R, + OBJ_BCROSS, + OBJ_CANBRA, + OBJ_CANDLE1, + OBJ_CANDLE2, + OBJ_CANDLEO, + OBJ_CAULDRON, + OBJ_CHAINEL, + OBJ_CHAINER, + OBJ_CHAING1L, + OBJ_CHAING1R, + OBJ_CHAING2L, + OBJ_CHAING2R, + OBJ_CHAINLL, + OBJ_CHAINLR, + OBJ_FLAMEHOLE, + OBJ_FTNROUND, + OBJ_FTNL, + OBJ_FTNR, + OBJ_GATEL, + OBJ_GATER, + OBJ_MCIRCLE1, + OBJ_MCIRCLE2, + OBJ_SKFIRE, + OBJ_SKPILE, + OBJ_SKSTICK1, + OBJ_SKSTICK2, + OBJ_SKSTICK3, + OBJ_SKSTICK4, + OBJ_SKSTICK5, + OBJ_SPKTRAP, + OBJ_STEAMTRAP, + OBJ_SWITCHML, + OBJ_SWITCHMR, + OBJ_SWITCHRL, + OBJ_SWITCHRR, + OBJ_SWITCHSKL, + OBJ_SWITCHSKR, + OBJ_TRAPL, + OBJ_TRAPR, + OBJ_TORTURE1, + OBJ_TORTURE2, + OBJ_TORTURE3, + OBJ_TORTURE4, + OBJ_TORTURE5, + OBJ_WATERJUG, + OBJ_TORTURE6R, + OBJ_NUDEW1L, + OBJ_NUDEW1R, + OBJ_NUDEW2L, + OBJ_NUDEW2R, + OBJ_NUDEW8, + OBJ_NUDEMAN1L, + OBJ_NUDEMAN1R, + OBJ_NUDEMAN3, + OBJ_TNUDEM1, + OBJ_TNUDEM2, + OBJ_TNUDEM3, + OBJ_TNUDEM4, + OBJ_TNUDEW1, + OBJ_TNUDEW2, + OBJ_TNUDEW3, + OBJ_CHEST1, + OBJ_CHEST1, + OBJ_CHEST1, + OBJ_CHEST2, + OBJ_CHEST2, + OBJ_CHEST2, + OBJ_CHEST3, + OBJ_CHEST3, + OBJ_CHEST3, + OBJ_DEADSKL, + OBJ_INVPLATE, + OBJ_WOODPLATE, + OBJ_MTLPLATE, + OBJ_STNPLATE, + OBJ_PEDISTAL, + OBJ_ANVIL, + OBJ_FORGE, + OBJ_BIGROCK, + OBJ_ROCK1, + OBJ_ROCK2, + OBJ_ROCK3, + OBJ_ROCK4, + OBJ_STALAG1, + OBJ_STALAG2, + OBJ_STALAG3, + OBJ_STALAG4, + OBJ_STALAG5, + OBJ_ALTGIRL, + OBJ_ALTBOY, + OBJ_TORCH, + OBJ_VILEPORT, + OBJ_WARARMOR, + OBJ_WARWEAP, + OBJ_TORCHR2, + OBJ_TORCHL2, + OBJ_MUSHPATCH, +}; + +/*-----------------------------------------------------------------------*/ + +// Random object, file list index, min level, max level, leveltype, theme number, quest number +// Animates, Anim Delay or Frame, Anim Length, Anim Width, Solid, Missile, Draw with Light, Breakable, Selectable, Trapable +ObjDataStruct AllObjects[] = { + { OBJMUST, 0, 1, 4, 1, -1, -1, // OBJ_L1LIGHT + TRUE, 1, 26, 64, TRUE, TRUE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 1, 1, 4, 1, -1, -1, // OBJ_L1DOORL + FALSE, 1, 0, 64, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJMUST, 1, 1, 4, 1, -1, -1, // OBJ_L1DOORR + FALSE, 2, 0, 64, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJTHEME, 7, 0, 0, 0, 3, -1, // OBJ_SKFIRE + TRUE, 2, 11, 96, TRUE, TRUE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 2, 1, 4, 1, -1, -1, // OBJ_LEVER + FALSE, 1, 1, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJMUST, 3, 1, 16, 0, -1, -1, // OBJ_CHEST1 + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJMUST, 4, 1, 16, 0, -1, -1, // OBJ_CHEST2 + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJMUST, 16, 1, 16, 0, -1, -1, // OBJ_CHEST3 + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJNO, 0, 0, 0, 0, -1, -1, // OBJ_CANDLE1 + FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJTHEME, 18, 0, 0, 0, 1, -1, // OBJ_CANDLE2 + TRUE, 2, 4, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 0, 0, 0, 0, -1, -1, // OBJ_CANDLEO + FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJTHEME, 5, 0, 0, 0, 3, -1, // OBJ_BANNERL + FALSE, 2, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJTHEME, 5, 0, 0, 0, 3, -1, // OBJ_BANNERM + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJTHEME, 5, 0, 0, 0, 3, -1, // OBJ_BANNERR + FALSE, 3, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 6, 1, 4, 0, -1, -1, // OBJ_SKPILE + FALSE, 0, 1, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 0, 0, 0, 0, -1, -1, // OBJ_SKSTICK1 + FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 0, 0, 0, 0, -1, -1, // OBJ_SKSTICK2 + FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 0, 0, 0, 0, -1, -1, // OBJ_SKSTICK3 + FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 0, 0, 0, 0, -1, -1, // OBJ_SKSTICK4 + FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 0, 0, 0, 0, -1, -1, // OBJ_SKSTICK5 + FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 9, 0, 0, 0, -1, -1, // OBJ_CRUX1 + FALSE, 1, 15, 96, TRUE, FALSE, TRUE, OBJ_BREAKABLE, OSEL_ALL, FALSE }, + + { OBJNO, 10, 0, 0, 0, -1, -1, // OBJ_CRUX2 + FALSE, 1, 15, 96, TRUE, FALSE, TRUE, OBJ_BREAKABLE, OSEL_ALL, FALSE }, + + { OBJNO, 11, 0, 0, 0, -1, -1, // OBJ_CRUX3 + FALSE, 1, 15, 96, TRUE, FALSE, TRUE, OBJ_BREAKABLE, OSEL_ALL, FALSE }, + + { OBJMUST, 14, 5, 5, 0, -1, -1, // OBJ_STAND + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 15, 0, 0, 0, -1, -1, // OBJ_ANGEL + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 13, 0, 0, 0, -1, -1, // OBJ_BOOK2L + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJNO, 17, 0, 0, 0, -1, -1, // OBJ_BCROSS + TRUE, 0, 10, 160, TRUE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 19, 0, 0, 0, -1, -1, // OBJ_NUDEW2R + TRUE, 3, 6, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 20, 16, 16, 0, -1, -1, // OBJ_SWITCHSKL + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJMUST, 21, 13, 16, 0, -1, Q_BUTCHER, // OBJ_TNUDEM1 + FALSE, 1, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 21, 13, 16, 0, 6, Q_BUTCHER, // OBJ_TNUDEM2 + FALSE, 2, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 21, 13, 16, 0, 6, Q_BUTCHER, // OBJ_TNUDEM3 + FALSE, 3, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 21, 13, 16, 0, 6, Q_BUTCHER, // OBJ_TNUDEM4 + FALSE, 4, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 22, 13, 16, 0, 6, Q_BUTCHER, // OBJ_TNUDEW1 + FALSE, 1, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 22, 13, 16, 0, 6, Q_BUTCHER, // OBJ_TNUDEW2 + FALSE, 2, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 22, 13, 16, 0, 6, Q_BUTCHER, // OBJ_TNUDEW3 + FALSE, 3, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 23, 13, 16, 0, -1, Q_BUTCHER, // OBJ_TORTURE1 + FALSE, 1, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 23, 13, 16, 0, -1, Q_BUTCHER, // OBJ_TORTURE2 + FALSE, 2, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 23, 13, 16, 0, -1, Q_BUTCHER, // OBJ_TORTURE3 + FALSE, 3, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 23, 13, 16, 0, -1, Q_BUTCHER, // OBJ_TORTURE4 + FALSE, 4, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 23, 13, 16, 0, -1, Q_BUTCHER, // OBJ_TORTURE5 + FALSE, 5, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 13, 6, 6, 0, -1, -1, // OBJ_BOOK2R + FALSE, 4, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 24, 5, 8, 2, -1, -1, // OBJ_L2DOORL + FALSE, 1, 0, 64, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJMUST, 24, 5, 8, 2, -1, -1, // OBJ_L2DOORR + FALSE, 2, 0, 64, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJMUST, 25, 5, 8, 2, -1, -1, // OBJ_TORCHL + TRUE, 1, 9, 96, FALSE, TRUE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 26, 5, 8, 2, -1, -1, // OBJ_TORCHR + TRUE, 1, 9, 96, FALSE, TRUE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 33, 5, 8, 2, -1, -1, // OBJ_TORCHL2 + TRUE, 1, 9, 96, FALSE, TRUE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 32, 5, 8, 2, -1, -1, // OBJ_TORCHR2 + TRUE, 1, 9, 96, FALSE, TRUE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 27, 1, 4, 1, -1, -1, // OBJ_SARC + FALSE, 1, 5, 128, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJNO, 28, 1, 4, 1, -1, -1, // OBJ_FLAMEHOLE + FALSE, 1, 20, 96, FALSE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 2, 1, 4, 1, -1, -1, // OBJ_FLAMELVR + FALSE, 1, 2, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJNO, 31, 1, 4, 1, -1, -1, // OBJ_WATER + TRUE, 1, 10, 64, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 12, 3, 4, 1, -1, -1, // OBJ_BOOKLVR + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 30, 1, 16, 0, -1, -1, // OBJ_TRAPL + FALSE, 1, 0, 64, FALSE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 30, 1, 16, 0, -1, -1, // OBJ_TRAPR + FALSE, 2, 0, 64, FALSE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 34, 0, 0, 0, -1, -1, // OBJ_BOOKSHELF + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 36, 0, 0, 0, -1, -1, // OBJ_WEAPRACK + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 37, 1, 16, 0, -1, -1, // OBJ_BARREL + FALSE, 1, 9, 96, TRUE, TRUE, TRUE, OBJ_BREAKABLE, OSEL_ALL, FALSE }, + + { OBJMUST, 38, 1, 16, 0, -1, -1, // OBJ_BARRELEX + FALSE, 1, 10, 96, TRUE, TRUE, TRUE, OBJ_BREAKABLE, OSEL_ALL, FALSE }, + + { OBJTHEME, 39, 0, 0, 0, 1, -1, // OBJ_SHRINEL + FALSE, 1, 11, 128, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 40, 0, 0, 0, 1, -1, // OBJ_SHRINER + FALSE, 1, 11, 128, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 13, 0, 0, 0, 3, -1, // OBJ_SKELBOOK + FALSE, 4, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 34, 0, 0, 0, 5, -1, // OBJ_BOOKCASEL + FALSE, 3, 0, 96, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 34, 0, 0, 0, 5, -1, // OBJ_BOOKCASER + FALSE, 4, 0, 96, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 13, 0, 0, 0, 5, -1, // OBJ_BOOKSTAND + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 18, 0, 0, 0, 5, -1, // OBJ_BOOKCANDLE + TRUE, 2, 4, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJTHEME, 41, 0, 0, 0, 7, -1, // OBJ_BLOODFTN + TRUE, 2, 10, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 42, 13, 16, 0, 8, -1, // OBJ_DECAP + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, FALSE }, + + { OBJMUST, 3, 1, 16, 0, -1, -1, // OBJ_TCHEST1 + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJMUST, 4, 1, 16, 0, -1, -1, // OBJ_TCHEST2 + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJMUST, 16, 1, 16, 0, -1, -1, // OBJ_TCHEST3 + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + + { OBJMUST, 12, 7, 7, 2, -1, Q_BLIND, // OBJ_BLINDBOOK + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 12, 5, 5, 2, -1, Q_BLOOD, // OBJ_BLOODBOOK + FALSE, 4, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 43, 5, 5, 2, -1, Q_BLOOD, // OBJ_PEDISTAL + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 44, 9, 12, 3, -1, -1, // OBJ_L3DOORL + FALSE, 1, 0, 64, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJMUST, 44, 9, 12, 3, -1, -1, // OBJ_L3DOORR + FALSE, 2, 0, 64, FALSE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJTHEME, 45, 0, 0, 0, 9, -1, // OBJ_PURIFYINGFTN + TRUE, 2, 10, 128, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 46, 0, 0, 0, 10, -1, // OBJ_ARMORSTAND + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 46, 0, 0, 0, 10, -1, // OBJ_ARMORSTANDN + FALSE, 2, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJTHEME, 47, 0, 0, 0, 11, -1, // OBJ_GOATSHRINE + TRUE, 2, 10, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 48, 13, 16, 0, -1, -1, // OBJ_CAULDRON + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 49, 0, 0, 0, 13, -1, // OBJ_MURKYFTN + TRUE, 2, 10, 128, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJTHEME, 50, 0, 0, 0, 14, -1, // OBJ_TEARFTN + TRUE, 2, 4, 128, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 51, 0, 0, 1, -1, Q_BETRAYER, // OBJ_ALTBOY + FALSE, 1, 0, 128, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 52, 0, 0, 1, -1, Q_BETRAYER, // OBJ_MCIRCLE1 + FALSE, 1, 0, 96, FALSE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 52, 0, 0, 1, -1, Q_BETRAYER, // OBJ_MCIRCLE2 + FALSE, 1, 0, 96, FALSE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 53, 1, 24, 0, -1, -1, // OBJ_STORYBOOK + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, // change 24 back to 12 JKE + + { OBJMUST, 18, 2, 12, 0, -1, 15, // OBJ_STORYCANDLE + TRUE, 2, 4, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJMUST, 12, 13, 13, 4, -1, Q_WARLORD, // OBJ_STEELTOME + FALSE, 4, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 46, 13, 13, 0, -1, Q_WARLORD, // OBJ_WARARMOR + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJNO, 36, 13, 13, 0, -1, Q_WARLORD, // OBJ_WARWEAP + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJNO, 17, 0, 0, 0, 15, -1, // OBJ_TBCROSS + TRUE, 0, 10, 160, TRUE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 36, 0, 0, 0, 16, -1, // OBJ_WEAPONRACK + FALSE, 1, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJNO, 36, 0, 0, 0, 16, -1, // OBJ_WEAPONRACKN + FALSE, 2, 0, 96, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_NONE, FALSE }, + + { OBJNO, 54, 0, 0, 0, -1, 1, // OBJ_MUSHPATCH + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_ALL, TRUE }, + + { OBJNO, 55, 0, 0, 0, -1, 15, // OBJ_LAZSTAND + FALSE, 1, 0, 128, TRUE, FALSE, TRUE, OBJ_NOBREAK, OSEL_ALL, FALSE }, + + { OBJMUST, 42, 9, 9, 3, -1, -1, // OBJ_SLAINHERO + FALSE, 2, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, FALSE }, + + { OBJNO, 16, 0, 0, 0, -1, -1, // OBJ_SIGNCHEST + FALSE, 1, 0, 96, TRUE, TRUE, TRUE, OBJ_NOBREAK, OSEL_FLR, TRUE }, + +// Random object, file list index, min level, max level, leveltype, theme number, quest number +// Animates, Anim Delay or Frame, Anim Length, Anim Width, Solid, Missile, Draw with Light, Breakable, Selectable, Trapable + + // Stopper + { -1, 0, 0, 0, -1, -1, -1, FALSE, 0, 0, 0, FALSE, FALSE, FALSE, OBJ_NOBREAK, OSEL_NONE, FALSE } +}; + +/*-----------------------------------------------------------------------*/ + +char *ObjMasterFList[] = { + "L1Braz", // 0 + "L1Doors", // 1 + "Lever", // 2 + "Chest1", // 3 + "Chest2", // 4 + "Banner", // 5 + "SkulPile", // 6 + "SkulFire", // 7 + "SkulStik", // 8 + "CruxSk1", // 9 + "CruxSk2", // 10 + "CruxSk3", // 11 + "Book1", // 12 + "Book2", // 13 + "Rockstan", // 14 + "Angel", // 15 + "Chest3", // 16 + "Burncros", // 17 + "Candle2", // 18 + "Nude2", // 19 + "Switch4", // 20 + "TNudeM", // 21 + "TNudeW", // 22 + "TSoul", // 23 + "L2Doors", // 24 + "WTorch4", // 25 + "WTorch3", // 26 + "Sarc", // 27 + "Flame1", // 28 + "Prsrplt1", // 29 + "Traphole", // 30 + "MiniWatr", // 31 + "WTorch2", // 32 + "WTorch1", // 33 + "BCase", // 34 + "BShelf", // 35 + "WeapStnd", // 36 + "Barrel", // 37 + "Barrelex", // 38 + "LShrineG", // 39 + "RShrineG", // 40 + "Bloodfnt", // 41 + "Decap", // 42 + "Pedistl", // 43 + "L3Doors", // 44 + "PFountn", // 45 + "Armstand", // 46 + "Goatshrn", // 47 + "Cauldren", // 48 + "MFountn", // 49 + "TFountn", // 50 + "Altboy", // 51 + "Mcirl", // 52 + "Bkslbrnt", // 53 + "Mushptch", // 54 + "LzStand", // 55 +}; + +char *CObjMasterFList[] = { + "L1Braz", // 0 + "L5Door", // 1 + "L5Lever", // 2 + "Chest1", // 3 + "Chest2", // 4 + "Banner", // 5 + "SkulPile", // 6 + "SkulFire", // 7 + "SkulStik", // 8 + "CruxSk1", // 9 + "CruxSk2", // 10 + "CruxSk3", // 11 + "Book1", // 12 + "Book2", // 13 + "Rockstan", // 14 + "Angel", // 15 + "Chest3", // 16 + "Burncros", // 17 + "L5Light", // 18 + "Nude2", // 19 + "Switch4", // 20 + "TNudeM", // 21 + "TNudeW", // 22 + "TSoul", // 23 + "L2Doors", // 24 + "WTorch4", // 25 + "WTorch3", // 26 + "L5Sarco", // 27 + "Flame1", // 28 + "Prsrplt1", // 29 + "Traphole", // 30 + "MiniWatr", // 31 + "WTorch2", // 32 + "WTorch1", // 33 + "BCase", // 34 + "BShelf", // 35 + "WeapStnd", // 36 + "Urn", // 37 + "Urnexpld", // 38 + "LShrineG", // 39 + "RShrineG", // 40 + "Bloodfnt", // 41 + "Decap", // 42 + "Pedistl", // 43 + "L3Doors", // 44 + "PFountn", // 45 + "Armstand", // 46 + "Goatshrn", // 47 + "Cauldren", // 48 + "MFountn", // 49 + "TFountn", // 50 + "Altboy", // 51 + "Mcirl", // 52 + "L5Books", // 53 + "Mushptch", // 54 + "LzStand", // 55 +}; + +char *HObjMasterFList[] = { + "L1Braz", // 0 + "L1Doors", // 1 + "Lever", // 2 + "Chest1", // 3 + "Chest2", // 4 + "Banner", // 5 + "SkulPile", // 6 + "SkulFire", // 7 + "SkulStik", // 8 + "CruxSk1", // 9 + "CruxSk2", // 10 + "CruxSk3", // 11 + "Book1", // 12 + "Book2", // 13 + "Rockstan", // 14 + "Angel", // 15 + "Chest3", // 16 + "Burncros", // 17 + "Candle2", // 18 + "Nude2", // 19 + "Switch4", // 20 + "TNudeM", // 21 + "TNudeW", // 22 + "TSoul", // 23 + "L2Doors", // 24 + "WTorch4", // 25 + "WTorch3", // 26 + "Sarc", // 27 + "Flame1", // 28 + "Prsrplt1", // 29 + "Traphole", // 30 + "MiniWatr", // 31 + "WTorch2", // 32 + "WTorch1", // 33 + "BCase", // 34 + "BShelf", // 35 + "WeapStnd", // 36 + "L6Pod1", // 37 + "L6Pod2", // 38 + "LShrineG", // 39 + "RShrineG", // 40 + "Bloodfnt", // 41 + "Decap", // 42 + "Pedistl", // 43 + "L3Doors", // 44 + "PFountn", // 45 + "Armstand", // 46 + "Goatshrn", // 47 + "Cauldren", // 48 + "MFountn", // 49 + "TFountn", // 50 + "Altboy", // 51 + "Mcirl", // 52 + "Bkslbrnt", // 53 + "Mushptch", // 54 + "LzStand", // 55 +}; + + diff --git a/OBJDAT.H b/OBJDAT.H new file mode 100644 index 0000000..ead2ebb --- /dev/null +++ b/OBJDAT.H @@ -0,0 +1,183 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/OBJDAT.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXOBJFILES 56 + +#define OBJ_L1LIGHT 0 +#define OBJ_L1DOORL 1 +#define OBJ_L1DOORR 2 +#define OBJ_SKFIRE 3 +#define OBJ_LEVER 4 +#define OBJ_CHEST1 5 +#define OBJ_CHEST2 6 +#define OBJ_CHEST3 7 +#define OBJ_CANDLE1 8 +#define OBJ_CANDLE2 9 +#define OBJ_CANDLEO 10 +#define OBJ_BANNERL 11 +#define OBJ_BANNERM 12 +#define OBJ_BANNERR 13 +#define OBJ_SKPILE 14 +#define OBJ_SKSTICK1 15 +#define OBJ_SKSTICK2 16 +#define OBJ_SKSTICK3 17 +#define OBJ_SKSTICK4 18 +#define OBJ_SKSTICK5 19 +#define OBJ_CRUX1 20 +#define OBJ_CRUX2 21 +#define OBJ_CRUX3 22 +#define OBJ_STAND 23 +#define OBJ_ANGEL 24 +#define OBJ_BOOK2L 25 +#define OBJ_BCROSS 26 +#define OBJ_NUDEW2R 27 +#define OBJ_SWITCHSKL 28 +#define OBJ_TNUDEM1 29 +#define OBJ_TNUDEM2 30 +#define OBJ_TNUDEM3 31 +#define OBJ_TNUDEM4 32 +#define OBJ_TNUDEW1 33 +#define OBJ_TNUDEW2 34 +#define OBJ_TNUDEW3 35 +#define OBJ_TORTURE1 36 +#define OBJ_TORTURE2 37 +#define OBJ_TORTURE3 38 +#define OBJ_TORTURE4 39 +#define OBJ_TORTURE5 40 +#define OBJ_BOOK2R 41 +#define OBJ_L2DOORL 42 +#define OBJ_L2DOORR 43 +#define OBJ_TORCHL 44 +#define OBJ_TORCHR 45 +#define OBJ_TORCHL2 46 +#define OBJ_TORCHR2 47 +#define OBJ_SARC 48 +#define OBJ_FLAMEHOLE 49 +#define OBJ_FLAMELVR 50 +#define OBJ_WATER 51 +#define OBJ_BOOKLVR 52 +#define OBJ_TRAPL 53 +#define OBJ_TRAPR 54 +#define OBJ_BOOKSHELF 55 +#define OBJ_WEAPRACK 56 +#define OBJ_BARREL 57 +#define OBJ_BARRELEX 58 +#define OBJ_SHRINEL 59 +#define OBJ_SHRINER 60 +#define OBJ_SKELBOOK 61 +#define OBJ_BOOKCASEL 62 +#define OBJ_BOOKCASER 63 +#define OBJ_BOOKSTAND 64 +#define OBJ_BOOKCANDLE 65 +#define OBJ_BLOODFTN 66 +#define OBJ_DECAP 67 +#define OBJ_TCHEST1 68 +#define OBJ_TCHEST2 69 +#define OBJ_TCHEST3 70 +#define OBJ_BLINDBOOK 71 +#define OBJ_BLOODBOOK 72 +#define OBJ_PEDISTAL 73 +#define OBJ_L3DOORL 74 +#define OBJ_L3DOORR 75 +#define OBJ_PURIFYINGFTN 76 +#define OBJ_ARMORSTAND 77 +#define OBJ_ARMORSTANDN 78 +#define OBJ_GOATSHRINE 79 +#define OBJ_CAULDRON 80 +#define OBJ_MURKYFTN 81 +#define OBJ_TEARFTN 82 +#define OBJ_ALTBOY 83 +#define OBJ_MCIRCLE1 84 +#define OBJ_MCIRCLE2 85 +#define OBJ_STORYBOOK 86 +#define OBJ_STORYCANDLE 87 +#define OBJ_STEELTOME 88 +#define OBJ_WARARMOR 89 +#define OBJ_WARWEAP 90 +#define OBJ_TBCROSS 91 +#define OBJ_WEAPONRACK 92 +#define OBJ_WEAPONRACKN 93 +#define OBJ_MUSHPATCH 94 +#define OBJ_LAZSTAND 95 +#define OBJ_SLAINHERO 96 +#define OBJ_SIGNCHEST 97 + +// These are not used yet, so their numbers are not relevent +#define OBJ_BLADEL 0 +#define OBJ_BLADER 0 +#define OBJ_BLOCK 0 +#define OBJ_BOOK1L 0 +#define OBJ_BOOK1R 0 +#define OBJ_CANBRA 0 +#define OBJ_CHAINEL 0 +#define OBJ_CHAINER 0 +#define OBJ_CHAING1L 0 +#define OBJ_CHAING1R 0 +#define OBJ_CHAING2L 0 +#define OBJ_CHAING2R 0 +#define OBJ_CHAINLL 0 +#define OBJ_CHAINLR 0 +#define OBJ_FTNROUND 0 +#define OBJ_FTNL 0 +#define OBJ_FTNR 0 +#define OBJ_GATEL 0 +#define OBJ_GATER 0 +#define OBJ_SPKTRAP 0 +#define OBJ_STEAMTRAP 0 +#define OBJ_SWITCHML 0 +#define OBJ_SWITCHMR 0 +#define OBJ_SWITCHRL 0 +#define OBJ_SWITCHRR 0 +#define OBJ_SWITCHSKR 0 +#define OBJ_WATERJUG 0 +#define OBJ_TORTURE6R 0 +#define OBJ_NUDEW1L 0 +#define OBJ_NUDEW1R 0 +#define OBJ_NUDEW2L 0 +#define OBJ_NUDEW8 0 +#define OBJ_NUDEMAN1L 0 +#define OBJ_NUDEMAN1R 0 +#define OBJ_NUDEMAN3 0 +#define OBJ_VAPOR 0 +#define OBJ_DEADSKL 0 +#define OBJ_INVPLATE 0 +#define OBJ_WOODPLATE 0 +#define OBJ_MTLPLATE 0 +#define OBJ_STNPLATE 0 +#define OBJ_ANVIL 0 +#define OBJ_FORGE 0 +#define OBJ_BIGROCK 0 +#define OBJ_ROCK1 0 +#define OBJ_ROCK2 0 +#define OBJ_ROCK3 0 +#define OBJ_ROCK4 0 +#define OBJ_STALAG1 0 +#define OBJ_STALAG2 0 +#define OBJ_STALAG3 0 +#define OBJ_STALAG4 0 +#define OBJ_STALAG5 0 +#define OBJ_ALTGIRL 0 +#define OBJ_TORCH 0 +#define OBJ_VILEPORT 0 + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern int ObjTypeConv[]; +extern ObjDataStruct AllObjects[]; +extern ObjDataStruct QuestObjects[]; +extern char *ObjMasterFList[]; +extern char *HObjMasterFList[]; +extern char *CObjMasterFList[]; diff --git a/OBJECTS.CPP b/OBJECTS.CPP new file mode 100644 index 0000000..b11fc8e --- /dev/null +++ b/OBJECTS.CPP @@ -0,0 +1,5865 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Objects file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/OBJECTS.CPP 5 2/12/97 10:51a Dbrevik2 $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ +#include + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "objects.h" +#include "objdat.h" +#include "engine.h" +#include "gendung.h" +#include "lighting.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "monstint.h" +#include "control.h" +#include "cursor.h" +#include "spells.h" +#include "minitext.h" +#include "textdat.h" +#include "quests.h" +#include "drlg_l1.h" +#include "missiles.h" +#include "misdat.h" +#include "effects.h" +#include "themes.h" +#include "itemdat.h" +#include "stores.h" +#include "monstdat.h" +#include "error.h" +#include "msg.h" +#include "multi.h" +#include "automap.h" +#include "drlg_l4.h" +#include "towners.h" +#include "inv.h" +#include "setmaps.h" + +/*-----------------------------------------------------------------------* +** Externs +**-----------------------------------------------------------------------*/ +int ObjIndex(int x, int y); +static bool OperateFountains(int, int); + +/*-----------------------------------------------------------------------* +** Local Defines +**-----------------------------------------------------------------------*/ + +//#define NO_L5_DOORS // JKE just until I get doors. + +#define DOOR_CLOSED 0 +#define DOOR_OPEN 1 +#define DOOR_BLOCKED 2 + +#define TRAP_NODIR 0 +#define TRAP_HORIZ 1 +#define TRAP_VERT 2 + +#define TOTAL_FOUNTAINS 4 + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +ObjectStruct object[MAXOBJECTS]; +long numobjects; + +static char ObjFileList[MAXLVLOBJS]; +static int numobjfiles = 0; +static BYTE *pObjCels[MAXLVLOBJS]; + +int objectactive[MAXOBJECTS]; +int objectavail[MAXOBJECTS]; + +static int trapid; +static int trapdir; + +static int leverid; + +BOOL InitObjFlag; //True while initing, false otherwise + +static int const bxadd[] = { -1, 0, 1, -1, 1, -1, 0, 1 }; +static int const byadd[] = { -1, -1, -1, 0, 0, 1, 1, 1 }; + +int SpellProgress; + +#if CHEATS +extern BOOL itemcheat; +extern BOOL uniqcheat; +#endif + +/*-----------------------------------------------------------------------* +** Function Prototypes +**-----------------------------------------------------------------------*/ +void AddMushPatch(); +void AddSlainHero(); +void AddSkulkenObject(int, int, int, int); +static void AddNa_Krul_Stuff(); +void OpenNaKrul(); +static void AddNaKrulLeverObj(); +static bool HCheckSpell(int); + +/*-----------------------------------------------------------------------*/ +// Shrine Data + + +// Shrine names +static char const * const shrinestrs[] = { + "Mysterious", // 0 + "Hidden", // 1 + "Gloomy", // 2 + "Weird", // 3 + "Magical", // 4 + "Stone", // 5 + "Religious", // 6 + "Enchanted", // 7 + "Thaumaturgic", // 8 + "Fascinating", // 9 + "Cryptic", // 10 + "Magical", // 11 + "Eldritch", // 12 + "Eerie", // 13 + "Divine", // 14 + "Holy", // 15 + "Sacred", // 16 + "Spiritual", // 17 + "Spooky", // 18 + "Abandoned", // 19 + "Creepy", // 20 + "Quiet", // 21 + "Secluded", // 22 + "Ornate", // 23 + "Glimmering", // 24 + "Tainted", // 25 + "Oily", // 26 + "Glowing", // 27 + "Mendicant's", // 28 + "Sparkling", // 29 + "Town", // 30 + "Shimmering", // 31 + "Solar", // 33 + "Murphy's", // 34 +}; +#define NUMSHRINETYPES (sizeof(shrinestrs)/sizeof(char *)) + +// Shrine min level it can appear +static char const shrineminlvl[NUMSHRINETYPES] = { + 1, // 0 Mysterious + 1, // 1 Hidden + 1, // 2 Gloomy + 1, // 3 Weird + 1, // 4 Magical + 1, // 5 Stone + 1, // 6 Religious + 1, // 7 Enchanted + 1, // 8 Thaumaturgic + 1, // 9 Fascinating + 1, // 10 Cryptic + 1, // 11 Supernatural + 1, // 12 Eldritch + 1, // 13 Eerie + 1, // 14 Divine + 1, // 15 Holy + 1, // 16 Sacred + 1, // 17 Spiritual + 1, // 18 Spooky + 1, // 19 Abandoned + 1, // 20 Creepy + 1, // 21 Quiet + 1, // 22 Secluded + 1, // 23 Ornate + 1, // 24 Glimmering + 1, // 25 Tainted + 1, // 26 Oily + 1, // 27 Glowing + 1, // 28 Mendicants + 1, // 29 Edisons + 1, // 30 Town + 1, // 31 Energy + 1, // 32 Solar + 1, // 33 Murphy's +}; + +// Shrine max level it can appear +static char const shrinemaxlvl[NUMSHRINETYPES] = { + MAX_LEVELS, // 0 Mysterious + MAX_LEVELS, // 1 Hidden + MAX_LEVELS, // 2 Gloomy + MAX_LEVELS, // 3 Weird + MAX_LEVELS, // 4 Magical + MAX_LEVELS, // 5 Stone + MAX_LEVELS, // 6 Religious + 8, // 7 Enchanted + MAX_LEVELS, // 8 Thaumaturgic + MAX_LEVELS, // 9 Fascinating + MAX_LEVELS, // 10 Cryptic + MAX_LEVELS, // 11 Supernatural + MAX_LEVELS, // 12 Eldritch + MAX_LEVELS, // 13 Eerie + MAX_LEVELS, // 14 Divine + MAX_LEVELS, // 15 Holy + MAX_LEVELS, // 16 Sacred + MAX_LEVELS, // 17 Spiritual + MAX_LEVELS, // 18 Spooky + MAX_LEVELS, // 19 Abandoned + MAX_LEVELS, // 20 Creepy + MAX_LEVELS, // 21 Quiet + MAX_LEVELS, // 22 Secluded + MAX_LEVELS, // 23 Ornate + MAX_LEVELS, // 24 Glimmering + MAX_LEVELS, // 25 Tainted + MAX_LEVELS, // 26 Oily + MAX_LEVELS, // 27 Glowing + MAX_LEVELS, // 28 Mendicants + MAX_LEVELS, // 29 Edisons + MAX_LEVELS, // 30 Town + MAX_LEVELS, // 31 Energy + MAX_LEVELS, // 32 Solar + MAX_LEVELS, // 33 Murphy's +}; + +#define SHRINE_ALL 0 +#define SHRINE_SINGLE 1 +#define SHRINE_MULTI 2 + +// Shrine available for either, single, or multiplayer? +static char const shrineavail[NUMSHRINETYPES] = { + SHRINE_ALL, // 0 Mysterious + SHRINE_ALL, // 1 Hidden + SHRINE_SINGLE, // 2 Gloomy + SHRINE_SINGLE, // 3 Weird + SHRINE_ALL, // 4 Magical + SHRINE_ALL, // 5 Stone + SHRINE_ALL, // 6 Religious + SHRINE_ALL, // 7 Enchanted + SHRINE_SINGLE, // 8 Thaumaturgic + SHRINE_ALL, // 9 Fascinating + SHRINE_ALL, // 10 Cryptic + SHRINE_ALL, // 11 Supernatural + SHRINE_ALL, // 12 Eldritch + SHRINE_ALL, // 13 Eerie + SHRINE_ALL, // 14 Divine + SHRINE_ALL, // 15 Holy + SHRINE_ALL, // 16 Sacred + SHRINE_ALL, // 17 Spiritual + SHRINE_MULTI, // 18 Spooky + SHRINE_ALL, // 19 Abandoned + SHRINE_ALL, // 20 Creepy + SHRINE_ALL, // 21 Quiet + SHRINE_ALL, // 22 Secluded + SHRINE_ALL, // 23 Ornate + SHRINE_ALL, // 24 Glimmering + SHRINE_MULTI, // 25 Tainted + SHRINE_ALL, // 26 Oily + SHRINE_ALL, // 27 Glowing + SHRINE_ALL, // 28 Mendicants + SHRINE_ALL, // 29 Edisons + SHRINE_ALL, // 30 Town + SHRINE_ALL, // 31 Energy + SHRINE_SINGLE, // 32 Solar + SHRINE_ALL, // 33 Murphy's +}; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static char const * const StoryBookName[] = { +// The Librium of the Horadrim (White Books) + + "The Great Conflict", + "The Wages of Sin are War", + "The Tale of the Horadrim", + +// Grimoire of the Burning Hells (Red Books) + + "The Dark Exile", + "The Sin War", + "The Binding of the Three", + +// The Journals of Lazarus the Betrayer (Normal Book Color) + + "The Realms Beyond", + "Tale of the Three", + "The Black King", + +// The Journals of Skulken the Necromancer JKE + + "Journal: The Ensorcellment", + "Journal: The Meeting", + "Journal: The Tirade", + "Journal: His Power Grows", + "Journal: NA-KRUL", + "Journal: The End", + + "A Spellbook" +}; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitObjectGFX() { + BYTE fileload[MAXOBJFILES]; + int i,j,t; + int templevel; //JKE + + ZeroMemory(fileload,sizeof(fileload)); + +// temp hack to get object art to appear. JKE + templevel = currlevel; + if ((currlevel >= CRYPTSTART) && (currlevel <= CRYPTEND)) + templevel = templevel - CRYPTSTART + 1; // replace templevel with currlevel when done. + else if ((currlevel >= HIVESTART) && (currlevel <= HIVEEND)) + templevel = templevel - HIVESTART + 9; + + for (i = 0; AllObjects[i].oload != -1; ++i) { + if ((AllObjects[i].oload == OBJMUST) + && (templevel >= AllObjects[i].ominlvl) + && (templevel <= AllObjects[i].omaxlvl)) + fileload[AllObjects[i].ofindex] = TRUE; + + if (AllObjects[i].otheme != -1) { + for (t = 0; t < numthemes; ++t) { + if (theme[t].ttype == AllObjects[i].otheme) + fileload[AllObjects[i].ofindex] = TRUE; + } + } + + if (AllObjects[i].oquest != -1) { + j = AllObjects[i].oquest; + if (QuestStatus(j)) + fileload[AllObjects[i].ofindex] = TRUE; + } + } + + app_assert(numobjfiles == 0); + for (i = 0; i < MAXOBJFILES; ++i) { + if (fileload[i]) { + char filestr[32]; + ObjFileList[numobjfiles] = i; + sprintf(filestr, "Objects\\%s.CEL", ObjMasterFList[i]); + if ((currlevel >= HIVESTART) && (currlevel < CRYPTSTART)) //JKE OBJECTS + sprintf(filestr, "Objects\\%s.CEL", HObjMasterFList[i]); + else if (currlevel >= CRYPTSTART) + sprintf(filestr, "Objects\\%s.CEL", CObjMasterFList[i]); + + app_assert(! pObjCels[numobjfiles]); + pObjCels[numobjfiles] = LoadFileInMemSig(filestr,NULL,'OGFX'); + ++numobjfiles; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeObjectGFX() { + for (int i = 0; i < numobjfiles; ++i) { + DiabloFreePtr(pObjCels[i]); + } + numobjfiles = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static bool RndLocOk(int xp, int yp) { + if (dMonster[xp][yp] != 0) return FALSE; + if (dPlayer[xp][yp] != 0) return FALSE; + if (dObject[xp][yp] != 0) return FALSE; + if (dFlags[xp][yp] & BFLAG_SETPC) return FALSE; + if (nSolidTable[dPiece[xp][yp]]) return FALSE; + if (leveltype == 1) { + if ((dPiece[xp][yp] > 126) && (dPiece[xp][yp] < 144)) + return false; + } + + return true; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static bool TrapLocOk(int xp, int yp) { + if (dFlags[xp][yp] & BFLAG_SETPC) return false; + if (nSolidTable[dPiece[xp][yp]]) return false; + return true; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static bool RoomLocOk(int xp, int yp) { + if (dPlayer[xp][yp] != 0) return false; + if (dObject[xp][yp] != 0) return false; + if (dFlags[xp][yp] & BFLAG_SETPC) return false; + if (nSolidTable[dPiece[xp][yp]]) return false; + return true; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitRndLocObj(int min, int max, int objtype) { + int xp, yp; + + int numobjs = random(139,max - min) + min; + for (int i = 0; i < numobjs; ++i) { + while (1) { + xp = random(139,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(139,DMAXY - DIRTEDGE) + (DIRTEDGED2); + if (! RndLocOk(xp-1, yp-1)) continue; + if (! RndLocOk(xp+0, yp-1)) continue; + if (! RndLocOk(xp+1, yp-1)) continue; + if (! RndLocOk(xp-1, yp+0)) continue; + if (! RndLocOk(xp+0, yp+0)) continue; + if (! RndLocOk(xp+1, yp+0)) continue; + if (! RndLocOk(xp-1, yp+1)) continue; + if (! RndLocOk(xp+0, yp+1)) continue; + if (! RndLocOk(xp+1, yp+1)) continue; + break; + } + AddObject(objtype, xp, yp); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void InitRndLocBigObj(int min, int max, int objtype) { + int xp, yp; + int numobjs = random(140,max - min) + min; + for (int i = 0; i < numobjs; ++i) { + while (1) { + xp = random(140,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(140,DMAXY - DIRTEDGE) + (DIRTEDGED2); + if (! RndLocOk(xp-1, yp-2)) continue; + if (! RndLocOk(xp+0, yp-2)) continue; + if (! RndLocOk(xp+1, yp-2)) continue; + if (! RndLocOk(xp-1, yp-1)) continue; + if (! RndLocOk(xp+0, yp-1)) continue; + if (! RndLocOk(xp+1, yp-1)) continue; + if (! RndLocOk(xp-1, yp+0)) continue; + if (! RndLocOk(xp+0, yp+0)) continue; + if (! RndLocOk(xp+1, yp+0)) continue; + if (! RndLocOk(xp-1, yp+1)) continue; + if (! RndLocOk(xp+0, yp+1)) continue; + if (! RndLocOk(xp+1, yp+1)) continue; + break; + } + + AddObject(objtype, xp, yp); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void InitRndLocObj5x5(int min, int max, int objtype) { + int xp, yp, xx, yy, cnt; + bool done; + + int numobjs = random(139,max - min) + min; + for (int i = 0; i < numobjs; ++i) { + cnt = 0; + done = false; + while (! done) { + done = true; + xp = random(139,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(139,DMAXY - DIRTEDGE) + (DIRTEDGED2); + for (yy = -2; yy <= 2; ++yy) { + for (xx = -2; xx <= 2; ++xx) if (! RndLocOk(xp+xx,yp+yy)) done = FALSE; + } + if (!done) { + ++cnt; + if (cnt > 20000) return; + } + } + AddObject(objtype, xp, yp); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void ClrAllObjects () +{ + int i; + + #if 0 + for (i = 0; i < MAXOBJECTS; ++i) { + object[i]._ox = 0; + object[i]._oy = 0; + object[i]._oAnimData = NULL; + object[i]._oAnimDelay = 0; + object[i]._oAnimCnt = 0; + object[i]._oAnimLen = 0; + object[i]._oAnimFrame = 0; + object[i]._oDelFlag = FALSE; + object[i]._oVar1 = 0; + object[i]._oVar2 = 0; + object[i]._oVar3 = 0; + object[i]._oVar4 = 0; + } + #else + memset(object, 0, sizeof(object)); + #endif + + numobjects = 0; + + for (i = 0; i < MAXOBJECTS; ++i) { + objectavail[i] = i; + //objectactive[i] = 0; + } + memset(objectactive, 0, sizeof(objectactive)); + trapid = 1; + trapdir = TRAP_NODIR; + leverid = 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddTortures() +{ + int yp, xp; + + for (yp = 0; yp < DMAXY; ++yp) { + for (xp = 0; xp < DMAXX; ++xp) { + if (dPiece[xp][yp] == 367) { + AddObject(OBJ_TORTURE1, xp, yp+1); + AddObject(OBJ_TORTURE3, xp+2, yp-1); + AddObject(OBJ_TORTURE2, xp, yp+3); + AddObject(OBJ_TORTURE4, xp+4, yp-1); + AddObject(OBJ_TORTURE5, xp, yp+5); + AddObject(OBJ_TNUDEM1, xp+1, yp+3); + AddObject(OBJ_TNUDEM2, xp+4, yp+5); + AddObject(OBJ_TNUDEM3, xp+2, yp); + AddObject(OBJ_TNUDEM4, xp+3, yp+2); + AddObject(OBJ_TNUDEW1, xp+2, yp+4); + AddObject(OBJ_TNUDEW2, xp+2, yp+1); + AddObject(OBJ_TNUDEW3, xp+4, yp+2); + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddCandles() +{ + int const xp = quests[Q_PWATER]._qtx; + int const yp = quests[Q_PWATER]._qty; + + AddObject(OBJ_STORYCANDLE, xp-2, yp+1); + AddObject(OBJ_STORYCANDLE, xp+3, yp+1); + AddObject(OBJ_STORYCANDLE, xp-1, yp+2); + AddObject(OBJ_STORYCANDLE, xp+2, yp+2); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddTrapLine(int min, int max, int tobjtype, int lobjtype) +{ + int i, j, xp, yp, numobjs; + int sx, sy, xa, ya, t; + int lx1, ly1, lx2, ly2; + bool found; + + numobjs = random(0,max - min) + min; + for (i = 0; i < numobjs; ++i) { + found = false; + while (!found) { + found = true; + xp = random(0,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(0,DMAXY - DIRTEDGE) + (DIRTEDGED2); + if (random(0,2)) { + while (TrapLocOk(xp, yp-1)) --yp; // Go to bottom + sx = xp; + sy = yp; + xa = 0; + ya = 1; + t = 0; + while (TrapLocOk(xp, yp+1) && found) { + found = found && RndLocOk(xp-3, yp); + found = found && RndLocOk(xp-2, yp); + found = found && RndLocOk(xp-1, yp); + found = found && RndLocOk(xp, yp); + found = found && RndLocOk(xp+1, yp); + found = found && RndLocOk(xp+2, yp); + found = found && RndLocOk(xp+3, yp); + ++yp; + ++t; + } + lx1 = xp-2; + ly1 = random(0,t-1) + sy + 1; + lx2 = xp+2; + ly2 = random(0,t-1) + sy + 1; + trapdir = TRAP_VERT; + } else { + while (TrapLocOk(xp-1, yp)) --xp; // Go to left + sx = xp; + sy = yp; + xa = 1; + ya = 0; + t = 0; + while (TrapLocOk(xp+1, yp) && found) { + found = found && RndLocOk(xp, yp-3); + found = found && RndLocOk(xp, yp-2); + found = found && RndLocOk(xp, yp-1); + found = found && RndLocOk(xp, yp); + found = found && RndLocOk(xp, yp+1); + found = found && RndLocOk(xp, yp+2); + found = found && RndLocOk(xp, yp+3); + ++xp; + ++t; + } + lx1 = random(0,t-1) + sx + 1; + ly1 = yp-2; + lx2 = random(0,t-1) + sx + 1; + ly2 = yp+2; + trapdir = TRAP_HORIZ; + } + if ((t < 5) || (t > 12)) found = FALSE; + } + + // Place trap + xp = sx; + yp = sy; + for (j = 0; j <= t; ++j) { + AddObject(tobjtype, xp, yp); + xp += xa; + yp += ya; + } + + // Place levers + AddObject(lobjtype, lx1, ly1); + AddObject(lobjtype, lx2, ly2); + + ++trapid; // Next trap + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddLeverObj(int lx1, int ly1, int lx2, int ly2, int x1, int y1, int x2, int y2) +{ + int xp, yp; + while (1) { + xp = random(141,lx2 - lx1 + 1) + lx1; + yp = random(141,ly2 - ly1 + 1) + ly1; + if (! RndLocOk(xp-1, yp-1)) continue; + if (! RndLocOk(xp+0, yp-1)) continue; + if (! RndLocOk(xp+1, yp-1)) continue; + if (! RndLocOk(xp-1, yp+0)) continue; + if (! RndLocOk(xp+0, yp+0)) continue; + if (! RndLocOk(xp+1, yp+0)) continue; + if (! RndLocOk(xp-1, yp+1)) continue; + if (! RndLocOk(xp+0, yp+1)) continue; + if (! RndLocOk(xp+1, yp+1)) continue; + break; + } + + AddObject(OBJ_LEVER, xp, yp); + int i = dObject[xp][yp] - 1; + SetObjMapRange(i, x1, y1, x2, y2, leverid); + ++leverid; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddBookLever(int lx1, int ly1, int lx2, int ly2, int x1, int y1, int x2, int y2, int msg) +{ +/* int xp, yp; + while (1) { + xp = random(142,lx2 - lx1 + 1) + lx1; + yp = random(142,ly2 - ly1 + 1) + ly1; + if (! RndLocOk(xp-1, yp-1)) continue; + if (! RndLocOk(xp+0, yp-1)) continue; + if (! RndLocOk(xp+1, yp-1)) continue; + if (! RndLocOk(xp-1, yp+0)) continue; + if (! RndLocOk(xp+0, yp+0)) continue; + if (! RndLocOk(xp+1, yp+0)) continue; + if (! RndLocOk(xp-1, yp+1)) continue; + if (! RndLocOk(xp+0, yp+1)) continue; + if (! RndLocOk(xp+1, yp+1)) continue; + break; + } +*/ + int xp, yp, xx, yy, cnt; + bool done; + + cnt = 0; + done = false; + while (! done) { + done = true; + xp = random(139,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(139,DMAXY - DIRTEDGE) + (DIRTEDGED2); + for (yy = -2; yy <= 2; ++yy) { + for (xx = -2; xx <= 2; ++xx) if (! RndLocOk(xp+xx,yp+yy)) done = FALSE; + } + if (!done) { + ++cnt; + if (cnt > 20000) return; + } + } + if (QuestStatus(Q_BLIND)) AddObject(OBJ_BLINDBOOK, xp, yp); + if (QuestStatus(Q_WARLORD)) AddObject(OBJ_STEELTOME, xp, yp); + if (QuestStatus(Q_BLOOD)) { + xp = (setpc_x << 1) + DIRTEDGED2 + 9; + yp = (setpc_y << 1) + DIRTEDGED2 + 24; + AddObject(OBJ_BLOODBOOK, xp, yp); + } + app_assert((DWORD)xp < MAXDUNX); + app_assert((DWORD)yp < MAXDUNY); + int i = dObject[xp][yp] - 1; + app_assert((DWORD)i < MAXOBJECTS); + SetObjMapRange(i, x1, y1, x2, y2, leverid); + SetBookMsg(i, msg); + ++leverid; + object[i]._oVar6 = object[i]._oAnimFrame + 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void InitRndBarrels() +{ + int xp, yp, o, rv, c, t; + + int numobjs = random(143,5) + 3; + for (int i = 0; i < numobjs; ++i) { + while (1) { + xp = random(143,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(143,DMAXY - DIRTEDGE) + (DIRTEDGED2); + if (! RndLocOk(xp, yp)) continue; + break; + } + + // Add normal or exploding barrel + if (random(143,4)) o = OBJ_BARREL; + else o = OBJ_BARRELEX; + AddObject(o, xp, yp); + c = 1; + + bool found = true; + while ((random(143,c >> 1) == 0) && (found)) { + t = 0; + found = false; + while ((!found) && (t < 3)) { + rv = random(143,8); + xp += bxadd[rv]; + yp += byadd[rv]; + found = RndLocOk(xp, yp); + ++t; + } + if (found) { + if (random(143,5)) o = OBJ_BARREL; + else o = OBJ_BARRELEX; + AddObject(o, xp, yp); + ++c; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddL1Objs(int x1, int y1, int x2, int y2) +{ + int i,j,pn; + + for (j = y1; j < y2; ++j) { + for (i = x1; i < x2; ++i) { + // Add Light + pn = dPiece[i][j]; + if (pn == 270) AddObject(OBJ_L1LIGHT, i, j); + if ((pn == 44) || (pn == 51) || (pn == 214)) + AddObject(OBJ_L1DOORL, i, j); + if ((pn == 46) || (pn == 56)) AddObject(OBJ_L1DOORR, i, j); + } + } +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddL5Objs(int x1, int y1, int x2, int y2) +{ + int i,j,pn; + + for (j = y1; j < y2; ++j) { + for (i = x1; i < x2; ++i) { + // Add Light + pn = dPiece[i][j]; +// if (pn == 270) AddObject(OBJ_L1LIGHT, i, j); + if (pn == 77) + AddObject(OBJ_L1DOORL, i, j); + if (pn == 80) + AddObject(OBJ_L1DOORR, i, j); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddL2Objs(int x1, int y1, int x2, int y2) +{ + int i,j,pn; + + for (j = y1; j < y2; ++j) { + for (i = x1; i < x2; ++i) { + // Add Doors + pn = dPiece[i][j]; + if (pn == 13 || pn == 541) AddObject(OBJ_L2DOORL, i, j); + if (pn == 17 || pn == 542) AddObject(OBJ_L2DOORR, i, j); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddL3Objs(int x1, int y1, int x2, int y2) +{ + int i,j,pn; + + for (j = y1; j < y2; ++j) { + for (i = x1; i < x2; ++i) { + // Add Doors + pn = dPiece[i][j]; + if (pn == 531) AddObject(OBJ_L3DOORL, i, j); + if (pn == 534) AddObject(OBJ_L3DOORR, i, j); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static bool TorchLocOK(int xp, int yp) +{ + if (dFlags[xp][yp] & BFLAG_SETPC) return false; + return true; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddL2Torches() +{ + int i,j,pn; + + for (j = 0; j < DMAXY; ++j) { + for (i = 0; i < DMAXX; ++i) { + // Add Torches + if(TorchLocOK(i,j)) { + pn = dPiece[i][j]; + if ((pn == 1) && (random(145,3) == 0)) AddObject(OBJ_TORCHL2, i, j); + if ((pn == 5) && (random(145,3) == 0)) AddObject(OBJ_TORCHR2, i, j); + if ((pn == 37) && (random(145,10) == 0) && (dObject[i-1][j] == 0)) AddObject(OBJ_TORCHL, i-1, j); + if ((pn == 41) && (random(145,10) == 0) && (dObject[i][j-1] == 0)) AddObject(OBJ_TORCHR, i, j-1); + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static bool WallTrapLocOk(int xp, int yp) +{ + if (dFlags[xp][yp] & BFLAG_SETPC) return false; + if (!nTrapTable[dPiece[xp][yp]]) return false; + return true; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddObjTraps() +{ + int i,j; + int x,y; + int rndv; + char oi, oi2; + + if (currlevel == 1) rndv = 10; + if (currlevel >= 2) rndv = 15; + if (currlevel >= 5) rndv = 20; + if (currlevel >= 7) rndv = 25; + for (j = 0; j < DMAXY; ++j) { + for (i = 0; i < DMAXX; ++i) { + if ((dObject[i][j] > 0) && (random(144,100) < rndv)) { + oi = dObject[i][j] - 1; + if (AllObjects[object[oi]._otype].oTrapFlag) { + x = i; + y = j; + if (random(144,2) == 0) { + --x; + while (!nSolidTable[dPiece[x][y]]) --x; + if (WallTrapLocOk(x, y) && ((i - x) > 1)) { + AddObject(OBJ_TRAPL, x, y); + oi2 = dObject[x][y] - 1; + object[oi2]._oVar1 = i; + object[oi2]._oVar2 = j; + object[oi]._oTrapFlag = TRUE; + } + } else { + --y; + while (!nSolidTable[dPiece[x][y]]) --y; + if (WallTrapLocOk(x, y) && ((j - y) > 1)) { + AddObject(OBJ_TRAPR, x, y); + oi2 = dObject[x][y] - 1; + object[oi2]._oVar1 = i; + object[oi2]._oVar2 = j; + object[oi]._oTrapFlag = TRUE; + } + } + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddChestTraps() +{ + int i,j; + char oi; + + for (j = 0; j < DMAXY; ++j) { + for (i = 0; i < DMAXX; ++i) { + if (dObject[i][j] > 0) { + oi = dObject[i][j] - 1; + if ((object[oi]._otype >= OBJ_CHEST1) && + (object[oi]._otype <= OBJ_CHEST3) && + (!object[oi]._oTrapFlag) && + (random(0, 100) < 10)) { + object[oi]._otype = (object[oi]._otype - OBJ_CHEST1) + OBJ_TCHEST1; + object[oi]._oTrapFlag = TRUE; + if (leveltype == 2) object[oi]._oVar4 = random(0, 2); // Type of trap +#if defined(HELLFIRE2) + else object[oi]._oVar4 = random(0, 7); +#else + else object[oi]._oVar4 = random(0, 6); +#endif + } + } + } + } +} + +/*-----------------------------------------------------------------------* +** Used by diablo level only!!!!! +**-----------------------------------------------------------------------*/ + +static void LoadMapObjects(BYTE *pMap, int startx, int starty, int x1, int y1, int w, int h, int leveridx) +{ + int i,j,rw,rh; + int ox,oy; + BYTE *lm; + long mapoff; + int ot, oi; + + InitObjFlag = TRUE; + + lm = pMap; + rw = *lm; + lm += 2; + rh = *lm; + // Skip map + height word + mapoff = ((rw * rh) << 1) + 2; + // Convert to index mini tile level instead of mega + rw = rw << 1; + rh = rh << 1; + // Skip treasure and monster map + mapoff += ((rw * rh) << 2); + lm += mapoff; + + for (j = 0; j < rh; ++j) { + for (i = 0; i < rw; ++i) { + if (*lm != 0) { + ot = *lm; + ox = i + DIRTEDGED2 + startx; + oy = j + DIRTEDGED2 + starty; + AddObject(ObjTypeConv[ot], ox, oy); + oi = ObjIndex(ox, oy); + SetObjMapRange(oi, x1, y1, x1+w, y1+h, leveridx); + } + lm+=2; + } + } + + InitObjFlag = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void LoadMapObjs(BYTE *pMap, int startx, int starty) +{ + int i,j,rw,rh; + int ox,oy; + BYTE *lm; + long mapoff; + int ot; + + InitObjFlag = TRUE; + + lm = pMap; + rw = *lm; + lm += 2; + rh = *lm; + // Skip map + height word + mapoff = ((rw * rh) << 1) + 2; + // Convert to index mini tile level instead of mega + rw = rw << 1; + rh = rh << 1; + // Skip treasure and monster map + mapoff += ((rw * rh) << 2); + lm += mapoff; + + for (j = 0; j < rh; ++j) { + for (i = 0; i < rw; ++i) { + if (*lm != 0) { + ot = *lm; + ox = i + DIRTEDGED2 + startx; + oy = j + DIRTEDGED2 + starty; + AddObject(ObjTypeConv[ot], ox, oy); + } + lm+=2; + } + } + + InitObjFlag = FALSE; +} + +/*-----------------------------------------------------------------------* +** Levers for diablo level +**-----------------------------------------------------------------------*/ + +static void AddDiabObjs() +{ + BYTE *pSetPiece; + int xx, yy; + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab1.DUN",NULL,'STPC'); + xx = (diabquad1x << 1); + yy = (diabquad1y << 1); + LoadMapObjects(pSetPiece, xx, yy, diabquad2x, diabquad2y, 11, 12, 1); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab2a.DUN",NULL,'STPC'); + xx = (diabquad2x << 1); + yy = (diabquad2y << 1); + LoadMapObjects(pSetPiece, xx, yy, diabquad3x, diabquad3y, 11, 11, 2); + DiabloFreePtr(pSetPiece); + + pSetPiece = LoadFileInMemSig("Levels\\L4Data\\diab3a.DUN",NULL,'STPC'); + xx = (diabquad3x << 1); + yy = (diabquad3y << 1); + LoadMapObjects(pSetPiece, xx, yy, diabquad4x, diabquad4y, 9, 9, 3); + DiabloFreePtr(pSetPiece); +} + +static void AddSkulkenBooks(int number) // Journal entry books JKE +{ + int xp,yp,xx,yy,cnt; + bool done; + + cnt = 0; + done = false; + while (! done) { + done = true; + xp = random(139,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(139,DMAXY - DIRTEDGE) + (DIRTEDGED2); + for (yy = -2; yy <= 2; ++yy) { + for (xx = -3; xx <= 3; ++xx) if (! RndLocOk(xp+xx,yp+yy)) done = FALSE; + } + if (!done) { + ++cnt; + if (cnt > 20000) return; + } + } + AddSkulkenObject(OBJ_STORYBOOK, number, xp, yp); + +// AddObject(OBJ_STORYBOOK, xp, yp); + + AddObject(OBJ_STORYCANDLE, xp-2, yp+1); + AddObject(OBJ_STORYCANDLE, xp-2, yp); + AddObject(OBJ_STORYCANDLE, xp-1, yp-1); + AddObject(OBJ_STORYCANDLE, xp+1, yp-1); + AddObject(OBJ_STORYCANDLE, xp+2, yp); + AddObject(OBJ_STORYCANDLE, xp+2, yp+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddStoryBooks() +{ + int xp,yp,xx,yy,cnt; + bool done; + + cnt = 0; + done = false; + while (! done) { + done = true; + xp = random(139,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(139,DMAXY - DIRTEDGE) + (DIRTEDGED2); + for (yy = -2; yy <= 2; ++yy) { + for (xx = -3; xx <= 3; ++xx) if (! RndLocOk(xp+xx,yp+yy)) done = FALSE; + } + if (!done) { + ++cnt; + if (cnt > 20000) return; + } + } + AddObject(OBJ_STORYBOOK, xp, yp); + AddObject(OBJ_STORYCANDLE, xp-2, yp+1); + AddObject(OBJ_STORYCANDLE, xp-2, yp); + AddObject(OBJ_STORYCANDLE, xp-1, yp-1); + AddObject(OBJ_STORYCANDLE, xp+1, yp-1); + AddObject(OBJ_STORYCANDLE, xp+2, yp); + AddObject(OBJ_STORYCANDLE, xp+2, yp+1); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddHookedBodies(int freq) +{ + int i, j, ii, jj; + + //Add tortured bodies on hooks + for (j = 0; j < MDMAXY; ++j) { + for (i = 0; i < MDMAXX; ++i) { + if ((dungeon[i][j] == 1 || dungeon[i][j] == 2) && + ((!random(0, freq)) && (SkipThemeRoom(i, j)))) { + ii = (i << 1) + DIRTEDGED2; + jj = (j << 1) + DIRTEDGED2; + if ((dungeon[i][j] == 1) && (dungeon[i+1][j] == 6)) { + switch(random(0, 3)) { + case 0: + AddObject(OBJ_TORTURE1, ii+1, jj); + break; + case 1: + AddObject(OBJ_TORTURE2, ii+1, jj); + break; + case 2: + AddObject(OBJ_TORTURE5, ii+1, jj); + break; + } + } else if ((dungeon[i][j] == 2) && (dungeon[i][j+1] == 6)) { + switch(random(0, 2)) { + case 0: + AddObject(OBJ_TORTURE3, ii, jj); + break; + case 1: + AddObject(OBJ_TORTURE4, ii, jj); + break; + } + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void AddL4Goodies() +{ + AddHookedBodies(6); + InitRndLocObj(2, 6, OBJ_TNUDEM1); + InitRndLocObj(2, 6, OBJ_TNUDEM2); + InitRndLocObj(2, 6, OBJ_TNUDEM3); + InitRndLocObj(2, 6, OBJ_TNUDEM4); + InitRndLocObj(2, 6, OBJ_TNUDEW1); + InitRndLocObj(2, 6, OBJ_TNUDEW2); + InitRndLocObj(2, 6, OBJ_TNUDEW3); + InitRndLocObj(2, 6, OBJ_DECAP); + InitRndLocObj(1, 3, OBJ_CAULDRON); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void AddLazStand() +{ + int xp,yp,xx,yy,cnt; + bool done = false; + + cnt = 0; + while (! done) { + done = true; + xp = random(139,DMAXX - DIRTEDGE) + (DIRTEDGED2); + yp = random(139,DMAXY - DIRTEDGE) + (DIRTEDGED2); + for (yy = -3; yy <= 3; ++yy) { + for (xx = -2; xx <= 3; ++xx) if (! RndLocOk(xp+xx,yp+yy)) done = FALSE; + } + if (!done) { + ++cnt; + if (cnt > 10000) { + // If can't find big area put it anywhere + InitRndLocObj(1, 1, OBJ_LAZSTAND); + return; + } + } + } + AddObject(OBJ_LAZSTAND, xp, yp); + AddObject(OBJ_TNUDEM2, xp+0, yp+2); + AddObject(OBJ_STORYCANDLE, xp+1, yp+2); + AddObject(OBJ_TNUDEM3, xp+2, yp+2); + AddObject(OBJ_TNUDEW1, xp+0, yp-2); + AddObject(OBJ_STORYCANDLE, xp+1, yp-2); + AddObject(OBJ_TNUDEW2, xp+2, yp-2); + AddObject(OBJ_STORYCANDLE, xp-1, yp-1); + AddObject(OBJ_TNUDEW3, xp-1, yp+0); + AddObject(OBJ_STORYCANDLE, xp-1, yp+1); +} + +/*-----------------------------------------------------------------------* +** Does not get called for setlevels so no worries +**-----------------------------------------------------------------------*/ + +void InitObjects () +{ + int textdef; + byte *setp; + + ClrAllObjects(); + SpellProgress = 0; + + // No objects on DIABLO_LEVEL. Inited seperatly + if (currlevel == DIABLO_LEVEL) { + AddDiabObjs(); + return; + } + + InitObjFlag = TRUE; + + int rs = GetRndSeed(); + + if (currlevel == SLAIN_HERO_LEVEL && gbMaxPlayers == 1) { + AddSlainHero(); + } + + if (currlevel == quests[Q_BKMUSHRM]._qlevel + && quests[Q_BKMUSHRM]._qactive == QUEST_NOTACTIVE) { + AddMushPatch(); + } + + if (currlevel == STORY_BOOK1_LEVEL) AddStoryBooks(); + else if (currlevel == STORY_BOOK2_LEVEL) AddStoryBooks(); + else if (currlevel == STORY_BOOK3_LEVEL) AddStoryBooks(); + + if (currlevel == SKULKEN_BOOK1_LEVEL) + { +// AddSkulkenBooks(0); + AddSkulkenBooks(1); + +// AddStoryBooks(); +// AddStoryBooks(); + } + else if (currlevel == SKULKEN_BOOK2_LEVEL) + { + AddSkulkenBooks(2); + AddSkulkenBooks(3); + } + else if (currlevel == SKULKEN_BOOK3_LEVEL) + { + AddSkulkenBooks(4); + AddSkulkenBooks(5); + } + + if (currlevel == NA_KRUL_LEVEL) + { + AddNa_Krul_Stuff(); + + } + + if (leveltype == 1) { + if (QuestStatus(Q_BUTCHER)) AddTortures(); + if (QuestStatus(Q_PWATER)) AddCandles(); + if (QuestStatus(Q_LTBANNER)) AddObject(OBJ_SIGNCHEST,(setpc_x << 1) + DIRTEDGED2 + 10, (setpc_y << 1) + DIRTEDGED2 + 3); + + InitRndLocBigObj(10, 15, OBJ_SARC); + if (currlevel < CRYPTSTART) + AddL1Objs(0, 0, DMAXX, DMAXY); + else + AddL5Objs(0,0,DMAXX,DMAXY); + InitRndBarrels(); + } + if (leveltype == 2) { + if (QuestStatus(Q_ROCK)) + InitRndLocObj5x5(1, 1, OBJ_STAND); // Rock stand + if (QuestStatus(Q_SCHAMB)) + InitRndLocObj5x5(1, 1, OBJ_BOOK2R); // SCamb book + + AddL2Objs(0, 0, DMAXX, DMAXY); + AddL2Torches(); + if (QuestStatus(Q_BLIND)) { + if (plr[myplr]._pClass == CLASS_WARRIOR) textdef = TXT_WARBLIND; + else if (plr[myplr]._pClass == CLASS_ROGUE) textdef = TXT_ROGBLIND; + else if (plr[myplr]._pClass == CLASS_SORCEROR) textdef = TXT_SORBLIND; + else if (plr[myplr]._pClass == CLASS_MONK) textdef = TXT_MNKBLIND; + else if (plr[myplr]._pClass == CLASS_BARD) textdef = TXT_BRDBLIND; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) textdef = TXT_BARBLIND; + quests[Q_BLIND]._qmsg = textdef; + AddBookLever(0, 0, DMAXX, DMAXY, setpc_x, setpc_y, setpc_x+setpc_w+1, setpc_y+setpc_h+1, textdef); + setp = LoadFileInMemSig("Levels\\L2Data\\Blind2.DUN",NULL,'STPC'); + LoadMapObjs(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + if (QuestStatus(Q_BLOOD)) { + if (plr[myplr]._pClass == CLASS_WARRIOR) textdef = TXT_WARBLOOD; + else if (plr[myplr]._pClass == CLASS_ROGUE) textdef = TXT_ROGBLOOD; + else if (plr[myplr]._pClass == CLASS_SORCEROR) textdef = TXT_SORBLOOD; + else if (plr[myplr]._pClass == CLASS_MONK) textdef = TXT_MNKBLOOD; + else if (plr[myplr]._pClass == CLASS_BARD) textdef = TXT_BRDBLOOD; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) textdef = TXT_BARBLOOD; + quests[Q_BLOOD]._qmsg = textdef; + AddBookLever(0, 0, DMAXX, DMAXY, setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7, textdef); + AddObject(OBJ_PEDISTAL, (setpc_x << 1) + DIRTEDGED2 + 9, (setpc_y << 1) +DIRTEDGED2 + 16); + } + InitRndBarrels(); + } + + if (leveltype == 3) { + AddL3Objs(0, 0, DMAXX, DMAXY); + InitRndBarrels(); + } + + if (leveltype == 4) { + if (QuestStatus(Q_WARLORD)) { + if (plr[myplr]._pClass == CLASS_WARRIOR) textdef = TXT_WARLORD; + else if (plr[myplr]._pClass == CLASS_ROGUE) textdef = TXT_ROGLORD; + else if (plr[myplr]._pClass == CLASS_SORCEROR) textdef = TXT_SORLORD; + else if (plr[myplr]._pClass == CLASS_MONK) textdef = TXT_MNKLORD; + else if (plr[myplr]._pClass == CLASS_BARD) textdef = TXT_BRDLORD; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) textdef = TXT_BARLORD; + quests[Q_WARLORD]._qmsg = textdef; + AddBookLever(0, 0, DMAXX, DMAXY, setpc_x, setpc_y, setpc_x+setpc_w, setpc_y+setpc_h, textdef); + setp = LoadFileInMemSig("Levels\\L4Data\\Warlord.DUN",NULL,'STPC'); + LoadMapObjs(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } + if (QuestStatus(Q_BETRAYER) && (gbMaxPlayers == 1)) { + AddLazStand(); + } + InitRndBarrels(); + AddL4Goodies(); + } + + InitRndLocObj(5, 10, OBJ_CHEST1); + InitRndLocObj(3, 6, OBJ_CHEST2); + InitRndLocObj(1, 5, OBJ_CHEST3); + if (leveltype != 4) AddObjTraps(); + if (leveltype > 1) AddChestTraps(); + + InitObjFlag = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetMapObjects(BYTE *pMap, int startx, int starty) +{ + int i,j,rw,rh; + int ox,oy; + BYTE *lm, *h; + long mapoff; + int ot; + bool fileload[MAXOBJFILES]; + char filestr[32]; + + ClrAllObjects(); + InitObjFlag = TRUE; + + for (i = 0; i < MAXOBJFILES; ++i) fileload[i] = FALSE; + + // Load all must obj gfx for leveltype + for (i = 0; AllObjects[i].oload != -1; ++i) { + if ((AllObjects[i].oload == OBJMUST) && (leveltype == AllObjects[i].olvltype)) + fileload[AllObjects[i].ofindex] = true; + } + + lm = pMap; + rw = *lm; + lm += 2; + rh = *lm; + // Skip map + height word + mapoff = ((rw * rh) << 1) + 2; + // Convert to index mini tile level instead of mega + rw = rw << 1; + rh = rh << 1; + // Skip treasure and monster map + mapoff += ((rw * rh) << 2); + lm += mapoff; + + h = lm; + for (j = 0; j < rh; ++j) { + for (i = 0; i < rw; ++i) { + if (*lm != 0) { + ot = *lm; + ot = ObjTypeConv[ot]; + fileload[AllObjects[ot].ofindex] = TRUE; + } + lm+=2; + } + } + + app_assert(numobjfiles == 0); + for (i = 0; i < MAXOBJFILES; ++i) { + if (fileload[i]) { + ObjFileList[numobjfiles] = i; + sprintf(filestr, "Objects\\%s.CEL", ObjMasterFList[i]); + app_assert(! pObjCels[numobjfiles]); + pObjCels[numobjfiles] = LoadFileInMemSig(filestr,NULL,'OGFX'); + ++numobjfiles; + } + } + + lm = h; + for (j = 0; j < rh; ++j) { + for (i = 0; i < rw; ++i) { + if (*lm != 0) { + ot = *lm; + ox = i + DIRTEDGED2 + startx; + oy = j + DIRTEDGED2 + starty; + AddObject(ObjTypeConv[ot], ox, oy); + } + lm+=2; + } + } + + InitObjFlag = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void DeleteObject(int oi, int i) +{ + int ox,oy; + + app_assert((DWORD)oi < MAXOBJECTS); + ox = object[oi]._ox; + oy = object[oi]._oy; + dObject[ox][oy] = 0; + + objectavail[MAXOBJECTS - numobjects] = oi; + --numobjects; + if ((numobjects > 0) && (i != numobjects)) { + objectactive[i] = objectactive[numobjects]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SetupObject(int i, int x, int y, int ot) +{ + int ai, j; + + app_assert((DWORD)i < MAXOBJECTS); + object[i]._otype = ot; + object[i]._ox = x; + object[i]._oy = y; + + ai = AllObjects[ot].ofindex; + for (j = 0; ObjFileList[j] != ai; ++j); + object[i]._oAnimData = pObjCels[j]; + + object[i]._oAnimFlag = AllObjects[ot].oAnimFlag; + if (object[i]._oAnimFlag) { + object[i]._oAnimDelay = AllObjects[ot].oAnimDelay; + object[i]._oAnimCnt = random(146,AllObjects[ot].oAnimDelay); + object[i]._oAnimLen = AllObjects[ot].oAnimLen; + object[i]._oAnimFrame = random(146,AllObjects[ot].oAnimLen-1) + 1; + } else { + object[i]._oAnimDelay = 1000; + object[i]._oAnimCnt = 0; + object[i]._oAnimLen = AllObjects[ot].oAnimLen; + object[i]._oAnimFrame = AllObjects[ot].oAnimDelay; + } + + object[i]._oAnimWidth = AllObjects[ot].oAnimWidth; + object[i]._oSolidFlag = AllObjects[ot].oSolidFlag; + object[i]._oMissFlag = AllObjects[ot].oMissFlag; + object[i]._oLight = AllObjects[ot].oLightFlag; + object[i]._oDelFlag = FALSE; + object[i]._oBreak = AllObjects[ot].oBreak; + object[i]._oSelFlag = AllObjects[ot].oSelFlag; + object[i]._oPreFlag = FALSE; + object[i]._oTrapFlag = FALSE; + object[i]._oDoorFlag = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = x1; + object[i]._oVar2 = y1; + object[i]._oVar3 = x2; + object[i]._oVar4 = y2; + object[i]._oVar8 = v; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SetBookMsg(int i, int msg) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oVar7 = msg; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddL1Door(int i, int x, int y, int ot) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oDoorFlag = TRUE; + if (ot == OBJ_L1DOORL) { + object[i]._oVar1 = dPiece[x][y]; + object[i]._oVar2 = dPiece[x][y-1]; + } else { + object[i]._oVar1 = dPiece[x][y]; + object[i]._oVar2 = dPiece[x-1][y]; + } + object[i]._oVar4 = DOOR_CLOSED; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddSCambBook(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); +// if (quests[Q_SCHAMB]._qactive != QUEST_NOTACTIVE) { +// object[i]._oSelFlag = OSEL_NONE; +// object[i]._oAnimFrame = 6; +// } + object[i]._oVar1 = setpc_x; + object[i]._oVar2 = setpc_y; + object[i]._oVar3 = setpc_x+setpc_w+1; + object[i]._oVar4 = setpc_y+setpc_h+1; + object[i]._oVar6 = object[i]._oAnimFrame + 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddChest(int i, int t) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (random(147,2) == 0) object[i]._oAnimFrame += 3; // Left or right + object[i]._oRndSeed = GetRndSeed(); + // Set # chest items. If a setlevel then so to max items. + switch(t) { + case OBJ_CHEST1: + case OBJ_TCHEST1: + if (setlevel) object[i]._oVar1 = 1; + else object[i]._oVar1 = random(147,2); + break; + case OBJ_CHEST2: + case OBJ_TCHEST2: + if (setlevel) object[i]._oVar1 = 2; + else object[i]._oVar1 = random(147,3); + break; + case OBJ_CHEST3: + case OBJ_TCHEST3: + if (setlevel) object[i]._oVar1 = 3; + else object[i]._oVar1 = random(147,4); + break; + } + object[i]._oVar2 = random(147,8); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddL2Door(int i, int x, int y, int ot) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oDoorFlag = TRUE; + if (ot == OBJ_L2DOORL) ObjSetMicro(x, y, 538); + else ObjSetMicro(x, y, 540); + object[i]._oVar4 = DOOR_CLOSED; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddL3Door(int i, int x, int y, int ot) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oDoorFlag = TRUE; + if (ot == OBJ_L3DOORL) ObjSetMicro(x, y, 531); + else ObjSetMicro(x, y, 534); + object[i]._oVar4 = DOOR_CLOSED; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddSarc(int i) +{ + int x,y; + + app_assert((DWORD)i < MAXOBJECTS); + x = object[i]._ox; + y = object[i]._oy - 1; + dObject[x][y] = -1 - (char)i; + object[i]._oVar1 = random(153,10); + object[i]._oRndSeed = GetRndSeed(); + if (object[i]._oVar1 >= 8) object[i]._oVar2 = PreSpawnSkeleton(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddFlameTrap(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = trapid; // Set trap id + object[i]._oVar2 = 0; // Trap active + object[i]._oVar3 = trapdir; // Horizontal, Vertical, or none + object[i]._oVar4 = 0; // Init to off +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddFlameLvr(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = trapid; // Set trap id + object[i]._oVar2 = OBJ_FLAMEHOLE; // Trap active +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddTrap(int i, int ot) +{ + int mt, tdiff; + + // Difficulty + tdiff = (currlevel / 3) + 1; +// Temp hack trap JKE 7/30 + if (currlevel > 16) tdiff = ((currlevel-4)/3) + 1; + if (currlevel > 20) tdiff = ((currlevel-8)/3) + 1; + + // Missile type + mt = random(148,tdiff); + app_assert((DWORD)i < MAXOBJECTS); + if (mt == 0) object[i]._oVar3 = MIT_ARROW; + if (mt == 1) object[i]._oVar3 = MIT_FIREBOLT; + if (mt == 2) object[i]._oVar3 = MIT_LIGHTCTRL; + object[i]._oVar4 = 0; // Trap active +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddObjLight(int i, int r) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (InitObjFlag) { + DoLighting(object[i]._ox, object[i]._oy, r, -1); + object[i]._oVar1 = -1; + } else object[i]._oVar1 = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddBarrel(int i, int ot) +{ + app_assert((DWORD)i < MAXOBJECTS); + //object[i]._oVar1 = random(149,5) + 5; // Barrel hit points + object[i]._oVar1 = 0; + object[i]._oRndSeed = GetRndSeed(); + object[i]._oVar2 = random(149,10); // What is inside + object[i]._oVar3 = random(149,3); // if item, useful or not + if (object[i]._oVar2 >= 8) + object[i]._oVar4 = PreSpawnSkeleton(); // Get monster index if one will pop out +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddShrine(int i) +{ + int st, j; + bool slist[NUMSHRINETYPES]; + + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oPreFlag = TRUE; + for (j = 0; j < NUMSHRINETYPES; ++j) { + if ((currlevel >= shrineminlvl[j]) && (currlevel <= shrinemaxlvl[j])) + slist[j] = true; + else + slist[j] = false; + if ((gbMaxPlayers != 1) && (shrineavail[j] == SHRINE_SINGLE)) slist[j] = false; + if ((gbMaxPlayers == 1) && (shrineavail[j] == SHRINE_MULTI)) slist[j] = false; + } + + // Choose shrine type + do { + st = random(150,NUMSHRINETYPES); + } while (!slist[st]); + + object[i]._oVar1 = st; + + if (random(150,2)) { + object[i]._oAnimFrame = 12; + object[i]._oAnimLen = 22; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddBookcase(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oPreFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddBookstand(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddBloodFtn(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddPurifyingFountain(int i) +{ + int x, y; + + app_assert((DWORD)i < MAXOBJECTS); + x = object[i]._ox; + y = object[i]._oy; + dObject[x][y-1] = -1 - (char)i; + dObject[x-1][y] = -1 - (char)i; + dObject[x-1][y-1] = -1 - (char)i; + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddArmorStand(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (!armorFlag) { + //A functional armor stand has already been placed + //Only place non-functional empty stands + object[i]._oAnimFlag = 2; + object[i]._oSelFlag = OSEL_NONE; + } + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddGoatShrine(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddCauldron(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddMurkyFountain(int i) +{ + int x, y; + + app_assert((DWORD)i < MAXOBJECTS); + x = object[i]._ox; + y = object[i]._oy; + dObject[x][y-1] = -1 - (char)i; + dObject[x-1][y] = -1 - (char)i; + dObject[x-1][y-1] = -1 - (char)i; + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddTearFountain(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddDecap(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oAnimFrame = random(151,8) + 1; + object[i]._oPreFlag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +const void AddVilebook(int i) +{ + if ((setlevel) && (setlvlnum == SL_VILEBETRAYER)) { + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oAnimFrame = 4; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +const void AddMagicCircle(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oPreFlag = TRUE; + object[i]._oVar6 = OBJNOWARP; + object[i]._oVar5 = OBJWARP1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +const void AddBrnCross(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +const void AddPedistal(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = setpc_x; + object[i]._oVar2 = setpc_y; + object[i]._oVar3 = setpc_x + setpc_w; + object[i]._oVar4 = setpc_y + setpc_h; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int const StoryText[3][3] = { + { TXT_BOOK11, TXT_BOOK12, TXT_BOOK13 }, + { TXT_BOOK21, TXT_BOOK22, TXT_BOOK23 }, + { TXT_BOOK31, TXT_BOOK32, TXT_BOOK33 } }; + +static void AddStoryBook(int i) +{ + // Use the last level seed to determine book types (which of 3) + SetRndSeed(glSeedTbl[16]); + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oVar1 = random(0, 3); + if (currlevel == STORY_BOOK1_LEVEL) object[i]._oVar2 = StoryText[object[i]._oVar1][0]; + else if (currlevel == STORY_BOOK2_LEVEL) object[i]._oVar2 = StoryText[object[i]._oVar1][1]; + else if (currlevel == STORY_BOOK3_LEVEL) object[i]._oVar2 = StoryText[object[i]._oVar1][2]; + object[i]._oVar3 = (object[i]._oVar1 * 3) + (currlevel >> 2) - 1; + + object[i]._oAnimFrame = 5 - (object[i]._oVar1 << 1); + object[i]._oVar4 = object[i]._oAnimFrame + 1; +} + +static void addskulkenbook (int i, int number) // number is the text to associate JKE +{ + app_assert((DWORD)i < MAXOBJECTS); + if (number > 5) + { + object[i]._oVar8 = number; + switch (object[i]._oVar8) + { + case 6: +// object[i]._oVar2 = TXT_SPELL1; + + if (plr[myplr]._pClass == CLASS_WARRIOR) object[i]._oVar2 = TXT_SPELL1; + else if (plr[myplr]._pClass == CLASS_ROGUE) object[i]._oVar2 = TXT_R_SPELL1; + else if (plr[myplr]._pClass == CLASS_SORCEROR) object[i]._oVar2 = TXT_S_SPELL1; + else if (plr[myplr]._pClass == CLASS_MONK) object[i]._oVar2 = TXT_M_SPELL1; + else if (plr[myplr]._pClass == CLASS_BARD) object[i]._oVar2 = TXT_B_SPELL1; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) object[i]._oVar2 = TXT_C_SPELL1; + break; + + case 7: +// object[i]._oVar2 = TXT_SPELL2; + + if (plr[myplr]._pClass == CLASS_WARRIOR) object[i]._oVar2 = TXT_SPELL2; + else if (plr[myplr]._pClass == CLASS_ROGUE) object[i]._oVar2 = TXT_R_SPELL2; + else if (plr[myplr]._pClass == CLASS_SORCEROR) object[i]._oVar2 = TXT_S_SPELL2; + else if (plr[myplr]._pClass == CLASS_MONK) object[i]._oVar2 = TXT_M_SPELL2; + else if (plr[myplr]._pClass == CLASS_BARD) object[i]._oVar2 = TXT_B_SPELL2; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) object[i]._oVar2 = TXT_C_SPELL2; + break; + + case 8: +// object[i]._oVar2 = TXT_SPELL3; + + if (plr[myplr]._pClass == CLASS_WARRIOR) object[i]._oVar2 = TXT_SPELL3; + else if (plr[myplr]._pClass == CLASS_ROGUE) object[i]._oVar2 = TXT_R_SPELL3; + else if (plr[myplr]._pClass == CLASS_SORCEROR) object[i]._oVar2 = TXT_S_SPELL3; + else if (plr[myplr]._pClass == CLASS_MONK) object[i]._oVar2 = TXT_M_SPELL3; + else if (plr[myplr]._pClass == CLASS_BARD) object[i]._oVar2 = TXT_B_SPELL3; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) object[i]._oVar2 = TXT_C_SPELL3; + break; + } + + object[i]._oVar1 = 1; + object[i]._oVar3 = 15; + + object[i]._oAnimFrame = 5 - ((object[i]._oVar1) << 1); + object[i]._oVar4 = object[i]._oAnimFrame + 1; + } + else + { + object[i]._oVar1 = 1; + object[i]._oVar2 = TXT_SKULLJRNL1 + number; + + object[i]._oVar3 = 9 + number; + + object[i]._oAnimFrame = 5 - (object[i]._oVar1 << 1); + object[i]._oVar4 = object[i]._oAnimFrame + 1; + object[i]._oVar8 = 0; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddWeaponRack(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (!weaponFlag) { + //A functional weapon rack has already been placed + //Only place non-functional empty racks + object[i]._oAnimFlag = 2; + object[i]._oSelFlag = OSEL_NONE; + } + object[i]._oRndSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddTorturedBody(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oRndSeed = GetRndSeed(); + object[i]._oAnimFrame = random(0, 4) + 1; + object[i]._oPreFlag = TRUE; +} + +/*-----------------------------------------------------------------------* + * GetRndObjLoc + * + * Gets a x by y empty location for object placement +**-----------------------------------------------------------------------*/ + +static void GetRndObjLoc(int randarea, int &xx, int &yy) +{ + int i,j; + bool failed; + + if (randarea) { + int tries = 0; + do { + if (++tries > 1000 && randarea > 1) + --randarea; + xx = random(0, DMAXX); + yy = random(0, DMAXY); + failed = false; + for (i = 0; i < randarea && !failed; ++i) + for (j = 0; j < randarea && !failed; ++j) + failed = !RndLocOk(xx + i, yy + j); + } while (failed); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddMushPatch() +{ + int x,y; + if (numobjects < MAXOBJECTS) { + int i = objectavail[0]; + + GetRndObjLoc(5, x, y); + dObject[x+1][y+1] = -1 - (char)i; + dObject[x+2][y+1] = -1 - (char)i; + dObject[x+1][y+2] = -1 - (char)i; + AddObject(OBJ_MUSHPATCH, x+2, y+2); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void AddSlainHero() +{ + int x, y; + + GetRndObjLoc(5, x, y); + AddObject(OBJ_SLAINHERO, x+2, y+2); +} + + +void AddSkulkenObject(int ot, int number, int ox, int oy) +{ + int oi; // Standard setup JKE + + if (numobjects < MAXOBJECTS) { + oi = objectavail[0]; + objectavail[0] = objectavail[MAXOBJECTS - numobjects - 1]; + objectactive[numobjects] = oi; + dObject[ox][oy] = (char)oi + 1; + // Standard init + SetupObject(oi, ox, oy, ot); + + addskulkenbook(oi, number); + + app_assert((DWORD)oi < MAXOBJECTS); + object[oi]._oAnimWidth2 = (object[oi]._oAnimWidth - 64) >> 1; + ++numobjects; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddObject(int ot, int ox, int oy) +{ + int oi; + + if (numobjects < MAXOBJECTS) { + oi = objectavail[0]; + objectavail[0] = objectavail[MAXOBJECTS - numobjects - 1]; + objectactive[numobjects] = oi; + dObject[ox][oy] = (char)oi + 1; + // Standard init + SetupObject(oi, ox, oy, ot); + // Bonus inits + switch (ot) { + case OBJ_L1LIGHT : + //AddObjLight(oi, 10); + AddObjLight(oi, 5); + break; + case OBJ_CANDLE1 : + case OBJ_CANDLE2 : + case OBJ_SKFIRE : + case OBJ_BOOKCANDLE: + AddObjLight(oi, 5); + break; + case OBJ_STORYCANDLE: + AddObjLight(oi, 3); + break; + case OBJ_TORCHL: + case OBJ_TORCHR: + case OBJ_TORCHL2: + case OBJ_TORCHR2: + AddObjLight(oi, 8); + break; + case OBJ_L1DOORL : + case OBJ_L1DOORR : + AddL1Door(oi, ox, oy, ot); + break; + case OBJ_L2DOORL : + case OBJ_L2DOORR : + AddL2Door(oi, ox, oy, ot); + break; + case OBJ_L3DOORL : + case OBJ_L3DOORR : + AddL3Door(oi, ox, oy, ot); + break; + case OBJ_BOOK2R: + AddSCambBook(oi); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + AddChest(oi, ot); + break; + case OBJ_SARC: + AddSarc(oi); + break; + case OBJ_FLAMEHOLE: + AddFlameTrap(oi); + break; + case OBJ_FLAMELVR: + AddFlameLvr(oi); + break; + case OBJ_WATER: + app_assert((DWORD)oi < MAXOBJECTS); + object[oi]._oAnimFrame = 1; + break; + case OBJ_TRAPL: + case OBJ_TRAPR: + AddTrap(oi, ot); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + AddBarrel(oi, ot); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + AddShrine(oi); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + AddBookcase(oi); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + AddBookstand(oi); + break; + case OBJ_BLOODFTN: + AddBloodFtn(oi); + break; + case OBJ_DECAP: + AddDecap(oi); + break; + case OBJ_PURIFYINGFTN: + AddPurifyingFountain(oi); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + AddArmorStand(oi); + break; + case OBJ_GOATSHRINE: + AddGoatShrine(oi); + break; + case OBJ_CAULDRON: + AddCauldron(oi); + break; + case OBJ_MURKYFTN: + AddMurkyFountain(oi); + break; + case OBJ_TEARFTN: + AddTearFountain(oi); + break; + case OBJ_BOOK2L: + AddVilebook(oi); + break; + case OBJ_MCIRCLE1: + case OBJ_MCIRCLE2: + AddMagicCircle(oi); + break; + case OBJ_STORYBOOK: + AddStoryBook(oi); + break; + case OBJ_TBCROSS: + case OBJ_BCROSS: + AddBrnCross(oi); + AddObjLight(oi, 5); + break; + case OBJ_PEDISTAL: + AddPedistal(oi); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + AddWeaponRack(oi); + break; + case OBJ_TNUDEM2: + AddTorturedBody(oi); + break; + } + app_assert((DWORD)oi < MAXOBJECTS); + object[oi]._oAnimWidth2 = (object[oi]._oAnimWidth - 64) >> 1; + ++numobjects; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Obj_Light(int i, int lr) +{ + int ox, oy; + int dx, dy, p, tr; + bool turnon = false; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar1 == -1) return; + + ox = object[i]._ox; + oy = object[i]._oy; + tr = lr + PLRLRAD; + if (lightflag == 0) { + for (p = 0; (p < MAX_PLRS) && (!turnon); ++p) { + if (!plr[p].plractive) continue; + if (currlevel != plr[p].plrlevel) continue; + dx = abs(plr[p]._px - ox); + dy = abs(plr[p]._py - oy); + if ((dx < tr) && (dy < tr)) turnon = true; + } + } + if (turnon) { + if (object[i]._oVar1 == 0) object[i]._olid = AddLight (ox, oy, lr); + object[i]._oVar1 = 1; + } else { + if (object[i]._oVar1 == 1) AddUnLight(object[i]._olid); + object[i]._oVar1 = 0; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Obj_Circle(int i) +{ + int px, py, ox, oy; + int v1, v2, v3; + + app_assert((DWORD)i < MAXOBJECTS); + ox = object[i]._ox; + oy = object[i]._oy; + px = plr[myplr]._px; + py = plr[myplr]._py; + if ((px == ox) && (py == oy)) { + if (object[i]._otype == OBJ_MCIRCLE1) object[i]._oAnimFrame = 2; + if (object[i]._otype == OBJ_MCIRCLE2) object[i]._oAnimFrame = 4; + if ((ox == 45) && (oy == 47)) object[i]._oVar6 = OBJWARP2; + else if ((ox == 26) && (oy == 46)) object[i]._oVar6 = OBJWARP1; + else object[i]._oVar6 = OBJNOWARP; + if ((ox == 35) && (oy == 36) && object[i]._oVar5 == OBJWARP3) { + object[i]._oVar6 = OBJDONEWARP; + v1 = 35; + v2 = 46; + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + if (quests[Q_BETRAYER]._qactive == QUEST_NOTDONE) + quests[Q_BETRAYER]._qvar1 = 4; + v3 = dPiece[v1][v2]; + //Cast phase + AddMissile(plr[myplr]._px, plr[myplr]._py, v1, v2, plr[myplr]._pdir, MIT_PHASE, MI_ENEMYMONST, myplr, 0, 0); + void TrackInit(BOOL bMouseDown); + TrackInit(FALSE); +// drb.patch1.start.1/24/97 +// static BYTE sgbMouseDown; + extern BYTE sgbMouseDown; +// drb.patch1.end.1/24/97 + sgbMouseDown = FALSE; + ReleaseCapture(); + ClrPlrPath(myplr); + void StartStand(int, int); + StartStand(myplr, 0); + } + } + else { + if (object[i]._otype == OBJ_MCIRCLE1) object[i]._oAnimFrame = 1; + if (object[i]._otype == OBJ_MCIRCLE2) object[i]._oAnimFrame = 3; + object[i]._oVar6 = OBJNOWARP; + } +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Obj_StopAnim(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oAnimFrame == object[i]._oAnimLen) { + object[i]._oAnimCnt = 0; + object[i]._oAnimDelay = 1000; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Obj_Door(int i) +{ + int dx, dy; + bool dok; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar4 == DOOR_CLOSED) { + object[i]._oSelFlag = OSEL_ALL; + object[i]._oMissFlag = FALSE; + } else { + dx = object[i]._ox; + dy = object[i]._oy; + dok = (dMonster[dx][dy] == 0); + dok = dok && (dItem[dx][dy] == 0); + dok = dok && (dDead[dx][dy] == 0); + dok = dok && (dPlayer[dx][dy] == 0); + object[i]._oSelFlag = OSEL_TOP; + if (dok) object[i]._oVar4 = DOOR_OPEN; + else object[i]._oVar4 = DOOR_BLOCKED; + object[i]._oMissFlag = TRUE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Obj_Sarc(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oAnimFrame == object[i]._oAnimLen) object[i]._oAnimFlag = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ActivateTrapLine(int ttype, int tid) +{ + int i, oi; + + for (i = 0; i < numobjects; ++i) { + oi = objectactive[i]; + if ((object[oi]._otype == ttype) && (object[oi]._oVar1 == tid)) { + object[oi]._oVar4 = 1; + object[oi]._oAnimFlag = TRUE; + object[oi]._oAnimDelay = 1; + object[oi]._olid = AddLight (object[oi]._ox, object[oi]._oy, 1); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Obj_FlameTrap(int i) +{ + int xp,yp; + int j; + + // Is trap active? + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar2 != 0) { + // Not active, try dying down + if (object[i]._oVar4 != 0) { + --object[i]._oAnimFrame; + if (object[i]._oAnimFrame == 1) { + object[i]._oVar4 = 0; + AddUnLight(object[i]._olid); + } else { + if (object[i]._oAnimFrame <= 4) ChangeLightRadius(object[i]._olid, object[i]._oAnimFrame); + } + } + } else { + // Active so continue + // Not on? + if (object[i]._oVar4 == 0) { + if (object[i]._oVar3 == TRAP_VERT) { + xp = object[i]._ox-2; + yp = object[i]._oy; + for (j = 0; j < 5; ++j) { + if ((dPlayer[xp][yp] != 0) || (dMonster[xp][yp] != 0)) + object[i]._oVar4 = 1; + ++xp; + } + } else { + xp = object[i]._ox; + yp = object[i]._oy-2; + for (j = 0; j < 5; ++j) { + if ((dPlayer[xp][yp] != 0) || (dMonster[xp][yp] != 0)) + object[i]._oVar4 = 1; + ++yp; + } + } + if (object[i]._oVar4 != 0) ActivateTrapLine(object[i]._otype, object[i]._oVar1); + } else { + if (object[i]._oAnimFrame == object[i]._oAnimLen) object[i]._oAnimFrame = 11; + if (object[i]._oAnimFrame <= 5) ChangeLightRadius(object[i]._olid, object[i]._oAnimFrame); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Obj_Trap(int i) +{ + int oti; + bool otrig = false; + int sx, sy, dx, dy; + int x, y; + int ax, ay; + int mdir; + + // Triggered? + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar4 == 0) { + oti = dObject[object[i]._oVar1][object[i]._oVar2] - 1; + switch (object[oti]._otype) { + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_SWITCHSKL: + case OBJ_LEVER : + case OBJ_SARC: + if (object[oti]._oSelFlag == OSEL_NONE) otrig = true; + break; + case OBJ_L1DOORL : + case OBJ_L1DOORR : + case OBJ_L2DOORL : + case OBJ_L2DOORR : + case OBJ_L3DOORL : + case OBJ_L3DOORR : + if (object[oti]._oVar4 != DOOR_CLOSED) otrig = true; + break; + } + if (otrig) { + object[i]._oVar4 = 1; + sx = object[i]._ox; + sy = object[i]._oy; + dx = object[oti]._ox; + dy = object[oti]._oy; + ax = dx; + ay = dy; + for (y = ay-1; y <= ay+1; ++y) { + for (x = ax-1; x <= ax+1; ++x) { + if (dPlayer[x][y] != 0) { + dx = x; + dy = y; + } + } + } + if (!deltaload) { + mdir = GetDirection(sx, sy, dx, dy); + AddMissile(sx, sy, dx, dy, mdir, object[i]._oVar3, MI_ENEMYPLR, -1, 0, 0); + PlaySfxLoc(IS_TRAP, object[oti]._ox, object[oti]._oy); + } + object[oti]._oTrapFlag = FALSE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void Obj_BCrossDamage(int i) +{ + int resist; + int damage[4] = { 6, 8, 10, 12 }; + + if (plr[myplr]._pmode != PM_DEATH) { + //Check for fire resistance. If resistance, adjust damage accordingly. + resist = plr[myplr]._pFireResist; + if (resist > 0) damage[leveltype-1] -= (damage[leveltype-1] * resist) / 100; + //Is the player in the fire? + app_assert((DWORD)i < MAXOBJECTS); + if ((plr[myplr]._px == object[i]._ox) && (plr[myplr]._py == object[i]._oy-1)) { + //Subtract damage + plr[myplr]._pHitPoints -= damage[leveltype-1]; + plr[myplr]._pHPBase -= damage[leveltype-1]; + //Check if player is dead + if ((plr[myplr]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - SetPlayerHitPoints(myplr, 0); + StartPlrKill(myplr, FALSE); + } else { + //Play pain sfx + if (plr[myplr]._pClass == CLASS_WARRIOR) PlaySfxLoc(PS_WARR68, plr[myplr]._px, plr[myplr]._py); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlaySfxLoc(PS_ROGUE68, plr[myplr]._px, plr[myplr]._py); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlaySfxLoc(PS_MAGE68, plr[myplr]._px, plr[myplr]._py); + else if (plr[myplr]._pClass == CLASS_MONK) PlaySfxLoc(PS_MONK68, plr[myplr]._px, plr[myplr]._py); + else if (plr[myplr]._pClass == CLASS_BARD) PlaySfxLoc(PS_BARD68, plr[myplr]._px, plr[myplr]._py); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlaySfxLoc(PS_BARBARIAN68, plr[myplr]._px, plr[myplr]._py); + #endif + } + drawhpflag = TRUE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ProcessObjects () +{ + int i, oi; + + for (i = 0; i < numobjects; ++i) { + oi = objectactive[i]; + app_assert((DWORD)oi < MAXOBJECTS); + switch (object[oi]._otype) { + case OBJ_L1LIGHT : + Obj_Light(oi, 10); + break; + case OBJ_CANDLE2 : + case OBJ_SKFIRE : + case OBJ_BOOKCANDLE: + Obj_Light(oi, 5); + break; + case OBJ_STORYCANDLE: + Obj_Light(oi, 3); + break; + case OBJ_CRUX1 : + case OBJ_CRUX2 : + case OBJ_CRUX3 : + case OBJ_BARREL: + case OBJ_BARRELEX: + case OBJ_SHRINEL: + case OBJ_SHRINER: + Obj_StopAnim(oi); + break; + case OBJ_L1DOORL : + case OBJ_L1DOORR : + case OBJ_L2DOORL : + case OBJ_L2DOORR : + case OBJ_L3DOORL : + case OBJ_L3DOORR : + Obj_Door(oi); + break; + case OBJ_TORCHL: + case OBJ_TORCHR: + case OBJ_TORCHL2: + case OBJ_TORCHR2: + Obj_Light(oi, 8); + break; + case OBJ_SARC: + Obj_Sarc(oi); + break; + case OBJ_FLAMEHOLE: + Obj_FlameTrap(oi); + break; + case OBJ_TRAPL: + case OBJ_TRAPR: + Obj_Trap(oi); + break; + case OBJ_MCIRCLE1: + case OBJ_MCIRCLE2: + Obj_Circle(oi); + break; + case OBJ_TBCROSS: + case OBJ_BCROSS: + Obj_Light(oi, 10); + Obj_BCrossDamage(oi); + break; + } + + // Animate Objects + if (object[oi]._oAnimFlag) { + ++object[oi]._oAnimCnt; + if (object[oi]._oAnimCnt >= object[oi]._oAnimDelay) { + object[oi]._oAnimCnt = 0; + ++object[oi]._oAnimFrame; + if (object[oi]._oAnimFrame > object[oi]._oAnimLen) object[oi]._oAnimFrame = 1; + } + } + } + i = 0; + while (i < numobjects) { + oi = objectactive[i]; + if (object[oi]._oDelFlag) { + DeleteObject(oi, i); + i = 0; + } else ++i; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ObjSetMicro(int dx, int dy, int pn) +{ + WORD *mtsource; + int t; + WORD *mt; + + dPiece[dx][dy] = pn; + --pn; + mt = &(dMT2[CalcRot(dx,dy)].mt[0]); + if (leveltype != 4) { + mtsource = (WORD *)(pMiniTiles + 20*pn); + for(t = 0; t < 10; ++t) + // MiniTiles array uses opposite y direction + // hence wierd index on next line + mt[t] = mtsource[8-(t&0xe)+(t&1)]; + } else { + mtsource = (WORD *)(pMiniTiles + 32*pn); + for(t = 0; t < 16; ++t) + // MiniTiles array uses opposite y direction + // hence wierd index on next line + mt[t] = mtsource[14-(t&0xe)+(t&1)]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void ObjSetMicro12(int dx, int dy) +{ + long mt1,mt2; + int pn; + + pn = dPiece[dx][dy] - 1; + __asm { + mov esi,dword ptr [pMiniTiles] + xor eax,eax + mov ax,word ptr [pn] + mov ebx,20 + mul ebx + add esi,eax + add esi,16 + xor eax,eax + lodsw + mov word ptr [mt1],ax + lodsw + mov word ptr [mt2],ax + } + dMT2[CalcRot(dx,dy)].mt[0] = mt1 & 0xffff; + dMT2[CalcRot(dx,dy)].mt[1] = mt2 & 0xffff; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void ObjSetMini(int x, int y, int v) +{ + long v1,v2,v3,v4; + int xx, yy; + + __asm { + mov esi,dword ptr [pMegaTiles] + xor eax,eax + mov ax,word ptr [v]; + dec eax + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + } + xx = (x << 1) + DIRTEDGED2; + yy = (y << 1) + DIRTEDGED2; + ObjSetMicro(xx, yy, v1); + ObjSetMicro(xx+1, yy, v2); + ObjSetMicro(xx, yy+1, v3); + ObjSetMicro(xx+1, yy+1, v4); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void ObjL1Special(int x1, int y1, int x2, int y2) +{ + int i,j; + + for (j = y1; j <= y2; ++j) { + for (i = x1; i <= x2; ++i) { + dSpecial[i][j] = 0; + // Place tops of arches + if (dPiece[i][j] == 12) dSpecial[i][j] = 1; + if (dPiece[i][j] == 11) dSpecial[i][j] = 2; + if (dPiece[i][j] == 71) dSpecial[i][j] = 1; + if (dPiece[i][j] == 259) dSpecial[i][j] = 5; + if (dPiece[i][j] == 249) dSpecial[i][j] = 2; + if (dPiece[i][j] == 325) dSpecial[i][j] = 2; + if (dPiece[i][j] == 321) dSpecial[i][j] = 1; + if (dPiece[i][j] == 255) dSpecial[i][j] = 4; + if (dPiece[i][j] == 211) dSpecial[i][j] = 1; + if (dPiece[i][j] == 344) dSpecial[i][j] = 2; + if (dPiece[i][j] == 341) dSpecial[i][j] = 1; + if (dPiece[i][j] == 331) dSpecial[i][j] = 2; + if (dPiece[i][j] == 418) dSpecial[i][j] = 1; + if (dPiece[i][j] == 421) dSpecial[i][j] = 2; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void ObjL2Special(int x1, int y1, int x2, int y2) +{ + int i,j; + + for (j = y1; j <= y2; ++j) { + for (i = x1; i <= x2; ++i) { + dSpecial[i][j] = 0; + if (dPiece[i][j] == 541) dSpecial[i][j] = 5; + if (dPiece[i][j] == 178) dSpecial[i][j] = 5; + if (dPiece[i][j] == 551) dSpecial[i][j] = 5; + if (dPiece[i][j] == 542) dSpecial[i][j] = 6; + if (dPiece[i][j] == 553) dSpecial[i][j] = 6; + if (dPiece[i][j] == 13) dSpecial[i][j] = 5; + if (dPiece[i][j] == 17) dSpecial[i][j] = 6; + } + } + + for (j = y1; j <= y2; ++j) { + for (i = x1; i <= x2; ++i) { + if (dPiece[i][j] == 132) { + dSpecial[i][j+1] = 2; + dSpecial[i][j+2] = 1; + } + if ((dPiece[i][j] == 135) || (dPiece[i][j] == 139)) { + dSpecial[i+1][j] = 3; + dSpecial[i+2][j] = 4; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void DoorSet(int oi, int dx, int dy) +{ + int pn; + + app_assert((DWORD)oi < MAXOBJECTS); + pn = dPiece[dx][dy]; + if (currlevel < HIVESTART) + { + if (pn == 43) ObjSetMicro(dx,dy,392); + if (pn == 45) ObjSetMicro(dx,dy,394); + if ((pn == 50) && (object[oi]._otype == OBJ_L1DOORL)) ObjSetMicro(dx,dy,411); + if ((pn == 50) && (object[oi]._otype == OBJ_L1DOORR)) ObjSetMicro(dx,dy,412); + if (pn == 54) ObjSetMicro(dx,dy,397); + if (pn == 55) ObjSetMicro(dx,dy,398); + if (pn == 61) ObjSetMicro(dx,dy,399); + if (pn == 67) ObjSetMicro(dx,dy,400); + if (pn == 68) ObjSetMicro(dx,dy,401); + if (pn == 69) ObjSetMicro(dx,dy,403); + if (pn == 70) ObjSetMicro(dx,dy,404); + if (pn == 72) ObjSetMicro(dx,dy,406); + if (pn == 212) ObjSetMicro(dx,dy,407); // Blood + if (pn == 354) ObjSetMicro(dx,dy,409); // Plain L + if (pn == 355) ObjSetMicro(dx,dy,410); // Plain R + if (pn == 411) ObjSetMicro(dx,dy,396); // Double open + if (pn == 412) ObjSetMicro(dx,dy,396); // Double open + } + else + { + + if (pn == 75) ObjSetMicro(dx,dy,204); + if (pn == 79) ObjSetMicro(dx,dy,208); + if ((pn == 86) && (object[oi]._otype == OBJ_L1DOORL)) ObjSetMicro(dx,dy,232); + if ((pn == 86) && (object[oi]._otype == OBJ_L1DOORR)) ObjSetMicro(dx,dy,234); + if (pn == 91) ObjSetMicro(dx,dy,215); + if (pn == 93) ObjSetMicro(dx,dy,218); + if (pn == 99) ObjSetMicro(dx,dy,220); + if (pn == 111) ObjSetMicro(dx,dy,222); + if (pn == 113) ObjSetMicro(dx,dy,224); + if (pn == 115) ObjSetMicro(dx,dy,226); + if (pn == 117) ObjSetMicro(dx,dy,228); + if (pn == 119) ObjSetMicro(dx,dy,230); + if (pn == 232) ObjSetMicro(dx,dy,212); // Double open + if (pn == 234) ObjSetMicro(dx,dy,212); // Double open + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void RedoPlayerVision() +{ + int p; + + for (p = 0; p < MAX_PLRS; ++p) { + if (! plr[p].plractive) continue; + if (currlevel != plr[p].plrlevel) continue; + ChangeVisionXY(plr[p]._pvid, plr[p]._px, plr[p]._py); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateL1RDoor(int pnum, int oi, bool sendflag) +{ + int dx, dy; + bool dok; + + app_assert((DWORD)oi < MAXOBJECTS); + if (object[oi]._oVar4 == DOOR_BLOCKED) { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + return; + } + dx = object[oi]._ox; + dy = object[oi]._oy; + if (object[oi]._oVar4 == DOOR_CLOSED) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_OPENDOOR,oi); + if (currlevel < CRYPTSTART) + { + if (!deltaload) PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + else + { + if (!deltaload) PlaySfxLoc(CR_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + if (currlevel < CRYPTSTART) + ObjSetMicro(dx,dy,395); + else + ObjSetMicro(dx,dy,209); + if (currlevel < HIVESTART) + dSpecial[dx][dy] = 8; + else + dSpecial[dx][dy] = 2; + ObjSetMicro12(dx,dy-1); + --dx; + object[oi]._oAnimFrame += 2; +#ifdef NO_L5_DOORS + if (currlevel > HIVESTART) + object[oi]._oAnimFrame = -1; +#endif + + object[oi]._oPreFlag = TRUE; + DoorSet(oi, dx, dy); + object[oi]._oVar4 = DOOR_OPEN; + object[oi]._oSelFlag = OSEL_TOP; + RedoPlayerVision(); + } else { + if (currlevel < CRYPTSTART) + { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + else + { + if (!deltaload) PlaySfxLoc(CR_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = (dMonster[dx][dy] == 0); + dok = dok && (dItem[dx][dy] == 0); + dok = dok && (dDead[dx][dy] == 0); + if (dok) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_CLOSEDOOR,oi); + object[oi]._oVar4 = DOOR_CLOSED; + object[oi]._oSelFlag = OSEL_ALL; + ObjSetMicro(dx,dy,object[oi]._oVar1); + if (currlevel < HIVESTART) + { + if (object[oi]._oVar2 != 50) ObjSetMicro(dx-1,dy,object[oi]._oVar2); + else { + // Double door + if (dPiece[dx-1][dy] == 396) ObjSetMicro(dx-1,dy,411); + else ObjSetMicro(dx-1,dy,object[oi]._oVar2); + } + } + else + { + if (object[oi]._oVar2 != 86) ObjSetMicro(dx-1,dy,object[oi]._oVar2); + else { + // Double door + if (dPiece[dx-1][dy] == 210) ObjSetMicro(dx-1,dy,232); + else ObjSetMicro(dx-1,dy,object[oi]._oVar2); + } + } + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = FALSE; + RedoPlayerVision(); + } else object[oi]._oVar4 = DOOR_BLOCKED; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateL1LDoor(int pnum, int oi, bool sendflag) +{ + int dx, dy; + bool dok; + + app_assert((DWORD)oi < MAXOBJECTS); + if (object[oi]._oVar4 == DOOR_BLOCKED) { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + return; + } + dx = object[oi]._ox; + dy = object[oi]._oy; + if (object[oi]._oVar4 == DOOR_CLOSED) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_OPENDOOR,oi); + if (currlevel < CRYPTSTART) + { + if (!deltaload) PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + else + { + if (!deltaload) PlaySfxLoc(CR_DOOROPEN, object[oi]._ox, object[oi]._oy); + } + if (currlevel < CRYPTSTART) + { + if (object[oi]._oVar1 == 214) + ObjSetMicro(dx,dy,408); //Blood + else + ObjSetMicro(dx,dy,393); + } + else + ObjSetMicro(dx,dy,206); + if (currlevel < HIVESTART) + dSpecial[dx][dy] = 7; + else + dSpecial[dx][dy] = 1; + ObjSetMicro12(dx-1,dy); + --dy; + object[oi]._oAnimFrame += 2; +#ifdef NO_L5_DOORS + if (currlevel > HIVESTART) + object[oi]._oAnimFrame = -1; +#endif + object[oi]._oPreFlag = TRUE; + DoorSet(oi, dx, dy); + object[oi]._oVar4 = DOOR_OPEN; + object[oi]._oSelFlag = OSEL_TOP; + RedoPlayerVision(); + } else { + if (currlevel < CRYPTSTART) + { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + else + { + if (!deltaload) PlaySfxLoc(CR_DOORCLOS, object[oi]._ox, object[oi]._oy); + } + dok = (dMonster[dx][dy] == 0); + dok = dok && (dItem[dx][dy] == 0); + dok = dok && (dDead[dx][dy] == 0); + if (dok) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_CLOSEDOOR,oi); + object[oi]._oVar4 = DOOR_CLOSED; + object[oi]._oSelFlag = OSEL_ALL; + ObjSetMicro(dx,dy,object[oi]._oVar1); + if (currlevel < HIVESTART) + { + if (object[oi]._oVar2 != 50) ObjSetMicro(dx,dy-1,object[oi]._oVar2); + else { + // Double door + if (dPiece[dx][dy-1] == 396) ObjSetMicro(dx,dy-1,412); + else ObjSetMicro(dx,dy-1,object[oi]._oVar2); + } + } + else + { + if (object[oi]._oVar2 != 86) ObjSetMicro(dx,dy-1,object[oi]._oVar2); + else { + // Double door + if (dPiece[dx][dy-1] == 210) ObjSetMicro(dx,dy-1,234); + else ObjSetMicro(dx,dy-1,object[oi]._oVar2); + } + } + + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = FALSE; + RedoPlayerVision(); + } else object[oi]._oVar4 = DOOR_BLOCKED; + } +} + +/*-----------------------------------------------------------------------*/ +// this is the stupidest fix I've ever seen an' I did it! JKE +/*-----------------------------------------------------------------------*/ +void OpenCloseAllDoors() +{ + int i; + BOOL odeltaload = deltaload; + + deltaload = TRUE; + for (i = 0; i < MAXOBJECTS; ++i) + { + if (object[i]._otype == OBJ_L1DOORL) + { + OperateL1LDoor(myplr, i, FALSE); + OperateL1LDoor(myplr, i, FALSE); + } + else + if (object[i]._otype == OBJ_L1DOORR) + { + OperateL1RDoor(myplr, i, FALSE); + OperateL1RDoor(myplr, i, FALSE); + } + } + deltaload = odeltaload; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateL2RDoor(int pnum, int oi, bool sendflag) +{ + int dx, dy; + bool dok; + + app_assert((DWORD)oi < MAXOBJECTS); + if (object[oi]._oVar4 == DOOR_BLOCKED) { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + return; + } + dx = object[oi]._ox; + dy = object[oi]._oy; + if (object[oi]._oVar4 == DOOR_CLOSED) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_OPENDOOR,oi); + if (!deltaload) PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + ObjSetMicro(dx,dy,17); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = TRUE; + object[oi]._oVar4 = DOOR_OPEN; + object[oi]._oSelFlag = OSEL_TOP; + RedoPlayerVision(); + } else { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + dok = (dMonster[dx][dy] == 0); + dok = dok && (dItem[dx][dy] == 0); + dok = dok && (dDead[dx][dy] == 0); + if (dok) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_CLOSEDOOR,oi); + object[oi]._oVar4 = DOOR_CLOSED; + object[oi]._oSelFlag = OSEL_ALL; + ObjSetMicro(dx,dy,540); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = FALSE; + RedoPlayerVision(); + } else object[oi]._oVar4 = DOOR_BLOCKED; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +const void OperateL2LDoor(int pnum, int oi, BOOL sendflag) +{ + int dx, dy; + bool dok; + + app_assert((DWORD)oi < MAXOBJECTS); + if (object[oi]._oVar4 == DOOR_BLOCKED) { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + return; + } + dx = object[oi]._ox; + dy = object[oi]._oy; + if (object[oi]._oVar4 == DOOR_CLOSED) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_OPENDOOR,oi); + if (!deltaload) PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + ObjSetMicro(dx,dy,13); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = TRUE; + object[oi]._oVar4 = DOOR_OPEN; + object[oi]._oSelFlag = OSEL_TOP; + RedoPlayerVision(); + } else { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + dok = (dMonster[dx][dy] == 0); + dok = dok && (dItem[dx][dy] == 0); + dok = dok && (dDead[dx][dy] == 0); + if (dok) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_CLOSEDOOR,oi); + object[oi]._oVar4 = DOOR_CLOSED; + object[oi]._oSelFlag = OSEL_ALL; + ObjSetMicro(dx,dy,538); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = FALSE; + RedoPlayerVision(); + } else object[oi]._oVar4 = DOOR_BLOCKED; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateL3RDoor(int pnum, int oi, bool sendflag) +{ + int dx, dy; + bool dok; + + app_assert((DWORD)oi < MAXOBJECTS); + if (object[oi]._oVar4 == DOOR_BLOCKED) { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + return; + } + dx = object[oi]._ox; + dy = object[oi]._oy; + if (object[oi]._oVar4 == DOOR_CLOSED) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_OPENDOOR,oi); + if (!deltaload) PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + ObjSetMicro(dx,dy,541); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = TRUE; + object[oi]._oVar4 = DOOR_OPEN; + object[oi]._oSelFlag = OSEL_TOP; + RedoPlayerVision(); + } else { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + dok = (dMonster[dx][dy] == 0); + dok = dok && (dItem[dx][dy] == 0); + dok = dok && (dDead[dx][dy] == 0); + if (dok) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_CLOSEDOOR,oi); + object[oi]._oVar4 = DOOR_CLOSED; + object[oi]._oSelFlag = OSEL_ALL; + ObjSetMicro(dx,dy,534); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = FALSE; + RedoPlayerVision(); + } else object[oi]._oVar4 = DOOR_BLOCKED; + } +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void OperateL3LDoor(int pnum, int oi, bool sendflag) +{ + int dx, dy; + bool dok; + + app_assert((DWORD)oi < MAXOBJECTS); + if (object[oi]._oVar4 == DOOR_BLOCKED) { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + return; + } + dx = object[oi]._ox; + dy = object[oi]._oy; + if (object[oi]._oVar4 == DOOR_CLOSED) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_OPENDOOR,oi); + if (!deltaload) PlaySfxLoc(IS_DOOROPEN, object[oi]._ox, object[oi]._oy); + ObjSetMicro(dx,dy,538); + object[oi]._oAnimFrame += 2; + object[oi]._oPreFlag = TRUE; + object[oi]._oVar4 = DOOR_OPEN; + object[oi]._oSelFlag = OSEL_TOP; + RedoPlayerVision(); + } else { + if (!deltaload) PlaySfxLoc(IS_DOORCLOS, object[oi]._ox, object[oi]._oy); + dok = (dMonster[dx][dy] == 0); + dok = dok && (dItem[dx][dy] == 0); + dok = dok && (dDead[dx][dy] == 0); + if (dok) { + if ((pnum == myplr) && sendflag) NetSendCmdParam1(TRUE,CMD_CLOSEDOOR,oi); + object[oi]._oVar4 = DOOR_CLOSED; + object[oi]._oSelFlag = OSEL_ALL; + ObjSetMicro(dx,dy,531); + object[oi]._oAnimFrame -= 2; + object[oi]._oPreFlag = FALSE; + RedoPlayerVision(); + } else object[oi]._oVar4 = DOOR_BLOCKED; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void MonstCheckDoors(int m) +{ + int i, oi, dpx, dpy; + int mx, my; + + mx = monster[m]._mx; + my = monster[m]._my; + if (!(dObject[mx-1][my-1] + || dObject[mx][my-1] + || dObject[mx+1][my-1] + || dObject[mx-1][my] + || dObject[mx+1][my] + || dObject[mx-1][my+1] + || dObject[mx][my+1] + || dObject[mx+1][my+1])) + return; + for (i = 0; i < numobjects; ++i) { + oi = objectactive[i]; + app_assert((DWORD)oi < MAXOBJECTS); + if ((object[oi]._otype == OBJ_L1DOORL) || (object[oi]._otype == OBJ_L1DOORR)) { + if (object[oi]._oVar4 == DOOR_CLOSED) { + dpx = abs(object[oi]._ox - mx); + dpy = abs(object[oi]._oy - my); + if ((dpx == 1) && (dpy <= 1) && (object[oi]._otype == OBJ_L1DOORL)) OperateL1LDoor(myplr, oi, true); + if ((dpx <= 1) && (dpy == 1) && (object[oi]._otype == OBJ_L1DOORR)) OperateL1RDoor(myplr, oi, true); + } + } + if ((object[oi]._otype == OBJ_L2DOORL) || (object[oi]._otype == OBJ_L2DOORR)) { + if (object[oi]._oVar4 == DOOR_CLOSED) { + dpx = abs(object[oi]._ox - mx); + dpy = abs(object[oi]._oy - my); + if ((dpx == 1) && (dpy <= 1) && (object[oi]._otype == OBJ_L2DOORL)) OperateL2LDoor(myplr, oi, true); + if ((dpx <= 1) && (dpy == 1) && (object[oi]._otype == OBJ_L2DOORR)) OperateL2RDoor(myplr, oi, true); + } + } + if ((object[oi]._otype == OBJ_L3DOORL) || (object[oi]._otype == OBJ_L3DOORR)) { + if (object[oi]._oVar4 == DOOR_CLOSED) { + dpx = abs(object[oi]._ox - mx); + dpy = abs(object[oi]._oy - my); + + if ((dpx == 1) && (dpy <= 1) && (object[oi]._otype == OBJ_L3DOORR)) OperateL3RDoor(myplr, oi, true); + if ((dpx <= 1) && (dpy == 1) && (object[oi]._otype == OBJ_L3DOORL)) OperateL3LDoor(myplr, oi, true); + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ObjChangeMap(int x1, int y1, int x2, int y2) +{ + int i,j; + + for (j = y1; j <= y2; ++j) { + for (i = x1; i <= x2; ++i) { + ObjSetMini(i, j, pdungeon[i][j]); + dungeon[i][j] = pdungeon[i][j]; // For automap + } + } + if ((leveltype == 1)&&(currlevel < HIVESTART)) { // JKE + ObjL1Special((x1 << 1) + DIRTEDGED2, (y1 << 1) + DIRTEDGED2, (x2 << 1) + DIRTEDGED2 + 1, (y2 << 1) + DIRTEDGED2 + 1); + AddL1Objs((x1 << 1) + DIRTEDGED2, (y1 << 1) + DIRTEDGED2, (x2 << 1) + DIRTEDGED2 + 1, (y2 << 1) + DIRTEDGED2 + 1); + } + if (leveltype == 2) { + ObjL2Special((x1 << 1) + DIRTEDGED2, (y1 << 1) + DIRTEDGED2, (x2 << 1) + DIRTEDGED2 + 1, (y2 << 1) + DIRTEDGED2 + 1); + AddL2Objs((x1 << 1) + DIRTEDGED2, (y1 << 1) + DIRTEDGED2, (x2 << 1) + DIRTEDGED2 + 1, (y2 << 1) + DIRTEDGED2 + 1); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ObjChangeMapResync(int x1, int y1, int x2, int y2) +{ + int i,j; + + for (j = y1; j <= y2; ++j) { + for (i = x1; i <= x2; ++i) { + ObjSetMini(i, j, pdungeon[i][j]); + dungeon[i][j] = pdungeon[i][j]; // For automap + } + } + + if ((leveltype == 1)&&(currlevel < HIVESTART)) + ObjL1Special((x1 << 1) + DIRTEDGED2, (y1 << 1) + DIRTEDGED2, (x2 << 1) + DIRTEDGED2 + 1, (y2 << 1) + DIRTEDGED2 + 1); + + if (leveltype == 2) + ObjL2Special((x1 << 1) + DIRTEDGED2, (y1 << 1) + DIRTEDGED2, (x2 << 1) + DIRTEDGED2 + 1, (y2 << 1) + DIRTEDGED2 + 1); + +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateL1Door(int pnum, int i, bool sendflag) +{ + int dpx, dpy; + + app_assert((DWORD)i < MAXOBJECTS); + dpx = abs(object[i]._ox - plr[pnum]._px); + dpy = abs(object[i]._oy - plr[pnum]._py); + if ((dpx == 1) && (dpy <= 1) && (object[i]._otype == OBJ_L1DOORL)) OperateL1LDoor(pnum, i, sendflag); + if ((dpx <= 1) && (dpy == 1) && (object[i]._otype == OBJ_L1DOORR)) OperateL1RDoor(pnum, i, sendflag); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateLever(int pnum, int i) +{ + bool mapflag; + int j, oi, ot; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (!deltaload) PlaySfxLoc(IS_LEVER, object[i]._ox, object[i]._oy); + + // Toggle to on + object[i]._oSelFlag = OSEL_NONE; + ++object[i]._oAnimFrame; + + mapflag = true; + if (currlevel == DIABLO_LEVEL) { + for (j = 0; j < numobjects; ++j) { + oi = objectactive[j]; + ot = object[oi]._otype; + if (ot == OBJ_SWITCHSKL) { + if ((object[i]._oVar8 == object[oi]._oVar8) && (object[oi]._oSelFlag != OSEL_NONE)) + mapflag = FALSE; + } + } + } + if (currlevel == NA_KRUL_LEVEL) + { +// dPiece[Na_Krul.LeverX][Na_Krul.LeverY] = 316; + OpenNaKrul(); + Na_Krul.Lever_Thrown = TRUE; + mapflag = FALSE; + quests[Q_NA_KRUL]._qactive = QUEST_DONE; + } + if (mapflag) ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateBook(int pnum, int i) +{ + int v1, v2, v3; + int j, oi, ot, itm; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if ((setlevel) && (setlvlnum == SL_VILEBETRAYER)) { + bool found = false; + bool dowarp = false; + for (j = 0; j < numobjects; ++j) { + oi = objectactive[j]; + ot = object[oi]._otype; + if ((ot == OBJ_MCIRCLE2) && (object[oi]._oVar6 == OBJWARP1)) { + v1 = 27; + v2 = 29; +// rmw.patch1.start.1/23/97 +// object[oi]._oVar6 == OBJDONEWARP; + object[oi]._oVar6 = OBJDONEWARP; +// rmw.patch1.end.1/23/97 + dowarp = TRUE; + } + if ((ot == OBJ_MCIRCLE2) && (object[oi]._oVar6 == OBJWARP2)) { + v1 = 43; + v2 = 29; +// rmw.patch1.start.1/23/97 +// object[oi]._oVar6 == OBJDONEWARP; + object[oi]._oVar6 = OBJDONEWARP; +// rmw.patch1.end.1/23/97 + dowarp = TRUE; + } + if (dowarp) { + v3 = dPiece[v1][v2]; + ++object[dObject[35][36]-1]._oVar5; + AddMissile(plr[pnum]._px, plr[pnum]._py, v1, v2, plr[pnum]._pdir, MIT_PHASE, MI_ENEMYMONST, pnum, 0, 0); + found = TRUE; + dowarp = FALSE; + } + } + if (!found) return; + } + // Toggle open + object[i]._oSelFlag = OSEL_NONE; + ++object[i]._oAnimFrame; + if ((setlevel) && (setlvlnum == SL_BONECHAMB)) { + __int64 t = 1; + plr[myplr]._pMemSpells |= t << (SPL_GUARDIAN-1); + if (plr[pnum]._pSplLvl[SPL_GUARDIAN] < SPELLCAP) { + ++plr[myplr]._pSplLvl[SPL_GUARDIAN]; + } + quests[Q_SCHAMB]._qactive = QUEST_DONE; + if (!deltaload) PlaySfxLoc(IS_QUESTDN, object[i]._ox, object[i]._oy); + InitDiabloMsg(MSG_INBONE); + AddMissile(plr[myplr]._px, plr[myplr]._py, object[i]._ox - 2, object[i]._oy - 4, plr[myplr]._pdir, MIT_GUARDIAN, MI_ENEMYMONST, myplr, 0, 0); + } + if ((setlevel) && (setlvlnum == SL_VILEBETRAYER)) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + for (itm = 0; itm < numobjects; ++itm) SyncObjectAnim(objectactive[itm]); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateBookLever(int pnum, int i) +{ + int x,y, tren; + + app_assert(gbMaxPlayers == 1); + x = (setpc_x << 1) + DIRTEDGED2; + y = (setpc_y << 1) + DIRTEDGED2; + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (qtextflag) return; + // Check quests + if ((object[i]._otype == OBJ_BLINDBOOK) && (quests[Q_BLIND]._qvar1 == 0)) { + quests[Q_BLIND]._qactive = QUEST_NOTDONE; + quests[Q_BLIND]._qlog = TRUE; + quests[Q_BLIND]._qvar1 = 1; + } + if ((object[i]._otype == OBJ_BLOODBOOK) && (quests[Q_BLOOD]._qvar1 == 0)) { + quests[Q_BLOOD]._qactive = QUEST_NOTDONE; + quests[Q_BLOOD]._qlog = TRUE; + quests[Q_BLOOD]._qvar1 = 1; + SpawnQuestItem(IDI_BLDSTONE, (setpc_x << 1) + 3 + DIRTEDGED2, (setpc_y << 1) + 10 + DIRTEDGED2, FALSE, ISEL_FLR); + SpawnQuestItem(IDI_BLDSTONE, (setpc_x << 1) + 15 + DIRTEDGED2, (setpc_y << 1) + 10 + DIRTEDGED2, FALSE, ISEL_FLR); + SpawnQuestItem(IDI_BLDSTONE, (setpc_x << 1) + 9 + DIRTEDGED2, (setpc_y << 1) + 17 + DIRTEDGED2, FALSE, ISEL_FLR); + } + if ((object[i]._otype == OBJ_STEELTOME) && (quests[Q_WARLORD]._qvar1 == 0)) { + quests[Q_WARLORD]._qactive = QUEST_NOTDONE; + quests[Q_WARLORD]._qlog = TRUE; + quests[Q_WARLORD]._qvar1 = 1; + } + // Change map + if (object[i]._oAnimFrame != object[i]._oVar6) { + if (object[i]._otype != OBJ_BLOODBOOK) ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + if (object[i]._otype == OBJ_BLINDBOOK) { + CreateItem(UID_OPTAMULET, x+5, y+5); + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + TransVal = tren; + } + } + // Toggle open + // object[i]._oSelFlag = OSEL_NONE; + object[i]._oAnimFrame = object[i]._oVar6; + // Display msg + InitQTextMsg(object[i]._oVar7); + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateSChambBk(int pnum, int i) +{ + int textdef,j; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (qtextflag) return; + // object[i]._oSelFlag = OSEL_NONE; + // Change map + if (object[i]._oAnimFrame != object[i]._oVar6) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + for (j = 0; j < numobjects; ++j) SyncObjectAnim(objectactive[j]); + } + // Toggle open + object[i]._oAnimFrame = object[i]._oVar6; + if (quests[Q_SCHAMB]._qactive == QUEST_NOTACTIVE) { + quests[Q_SCHAMB]._qactive = QUEST_NOTDONE; + quests[Q_SCHAMB]._qlog = TRUE; + } + + if (plr[myplr]._pClass == CLASS_WARRIOR) textdef = TXT_WARBONE; + else if (plr[myplr]._pClass == CLASS_ROGUE) textdef = TXT_ROGBONE; + else if (plr[myplr]._pClass == CLASS_SORCEROR) textdef = TXT_SORBONE; + else if (plr[myplr]._pClass == CLASS_MONK) textdef = TXT_MNKBONE; + else if (plr[myplr]._pClass == CLASS_BARD) textdef = TXT_BRDBONE; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) textdef = TXT_BARBONE; + quests[Q_SCHAMB]._qmsg = textdef; + InitQTextMsg(textdef); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateChest(int pnum, int i, bool sendmsg) +{ + int j, mdir, mtype = MIT_ARROW; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (!deltaload) PlaySfxLoc(IS_CHEST, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + object[i]._oAnimFrame += 2; + if (deltaload) return; + SetRndSeed(object[i]._oRndSeed); + + if (setlevel) { //Create only good items for set levels + for (j = 0; j < object[i]._oVar1; ++j) { + CreateRndItem(object[i]._ox, object[i]._oy, TRUE, sendmsg, FALSE); + } + } else { + for (j = 0; j < object[i]._oVar1; ++j) { + if (object[i]._oVar2) CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + else CreateRndUseful(pnum, object[i]._ox, object[i]._oy, sendmsg); + } + } + + if ((object[i]._oTrapFlag) && + (object[i]._otype >= OBJ_TCHEST1) && + (object[i]._otype <= OBJ_TCHEST3)) { + mdir = GetDirection(object[i]._ox, object[i]._oy, plr[pnum]._px, plr[pnum]._py); + switch(object[i]._oVar4) { + case 0: + mtype = MIT_ARROW; + break; + case 1: + mtype = MIT_FARROW; + break; + case 2: + mtype = MIT_NOVA; + break; + case 3: + mtype = MIT_FLAMEBOX; +// SpawnSkeleton(object[i]._oVar2, object[i]._ox, object[i]._oy); + break; + case 4: + mtype = MIT_DISENCHANT; + break; + case 5: + mtype = MIT_MANAREMOVE; + break; +#if defined(HELLFIRE2) + // GWP Another good trap might be acid splatted all around. + case 6: + mtype = MIT_LIGHTBOX; +// SpawnSkeleton(object[i]._oVar2, object[i]._ox, object[i]._oy); + break; +#endif + default: + mtype = MIT_ARROW; + break; + } + AddMissile(object[i]._ox, object[i]._oy, plr[pnum]._px, plr[pnum]._py, mdir, mtype, MI_ENEMYPLR, -1, 0, 0); + object[i]._oTrapFlag = FALSE; + } + if (pnum == myplr) NetSendCmdParam2(FALSE,CMD_PLROPOBJ,pnum,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateMushPatch(int pnum, int i) +{ + int x, y; + + if (!(quests[Q_BKMUSHRM]._qactive == QUEST_NOTDONE + && (quests[Q_BKMUSHRM]._qvar1 >= QS_TOMEGIVEN))) // FUNGALTM was given to Witch + { + if (!deltaload && pnum == myplr) { + if (plr[myplr]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR13); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE13); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE13); + else if (plr[myplr]._pClass == CLASS_MONK) PlaySFX(PS_MONK13); + else if (plr[myplr]._pClass == CLASS_BARD) PlaySFX(PS_BARD13); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN13); + #endif + } + return; + } + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) + return; + if (!deltaload) PlaySfxLoc(IS_CHEST, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + object[i]._oAnimFrame += 1; + if (deltaload) return; + GetSuperItemLoc(object[i]._ox, object[i]._oy, x, y); + SpawnQuestItem(IDI_MUSHROOM, x,y,0, ISEL_NONE); + quests[Q_BKMUSHRM]._qvar1 = QS_MUSHSPAWNED; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateInnSignChest(int pnum, int i) +{ + int x, y; + + if (!(quests[Q_LTBANNER]._qvar1 == 2)) + { + if (!deltaload && pnum == myplr) { + if (plr[myplr]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR24); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE24); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE24); + else if (plr[myplr]._pClass == CLASS_MONK) PlaySFX(PS_MONK24); + else if (plr[myplr]._pClass == CLASS_BARD) PlaySFX(PS_BARD24); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN24); + #endif + } + return; + } + + if (object[i]._oSelFlag == OSEL_NONE) + return; + if (!deltaload) PlaySfxLoc(IS_CHEST, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + object[i]._oAnimFrame += 2; + if (deltaload) return; + GetSuperItemLoc(object[i]._ox, object[i]._oy, x, y); + SpawnQuestItem(IDI_BANNER, x,y,0, ISEL_NONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateSlainHero(int pnum, int i, bool sendmsg) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + object[i]._oSelFlag = OSEL_NONE; + if (deltaload) return; + + if (plr[pnum]._pClass == CLASS_WARRIOR) { + //Create magic breast plate + CreateMagicArmor(object[i]._ox, object[i]._oy, IT_HARMOR, ITEM_BPLATE, FALSE, TRUE); + #if !IS_VERSION(SHAREWARE) + PlaySfxLoc(PS_WARR9, plr[myplr]._px, plr[myplr]._py); + #endif + } else if (plr[pnum]._pClass == CLASS_ROGUE) { + //Create magic long battle bow + CreateMagicWeapon(object[i]._ox, object[i]._oy, IT_BOW, ITEM_STLLONGBOW, FALSE, TRUE); + #if !IS_VERSION(SHAREWARE) + PlaySfxLoc(PS_ROGUE9, plr[myplr]._px, plr[myplr]._py); + #endif + } else if (plr[pnum]._pClass == CLASS_SORCEROR) { + //Create book of lightning + CreateSpellBook(object[i]._ox, object[i]._oy, SPL_LIGHTNING, FALSE, TRUE); + #if !IS_VERSION(SHAREWARE) + PlaySfxLoc(PS_MAGE9, plr[myplr]._px, plr[myplr]._py); + #endif + } else if (plr[pnum]._pClass == CLASS_MONK) { + //Create magic staff + CreateMagicWeapon(object[i]._ox, object[i]._oy, IT_STAFF, ITEM_STLSTAFF, FALSE, TRUE); + #if !IS_VERSION(SHAREWARE) + PlaySfxLoc(PS_MONK9, plr[myplr]._px, plr[myplr]._py); + #endif + } else if (plr[pnum]._pClass == CLASS_BARD) { + //Create special sword. + CreateMagicWeapon(object[i]._ox, object[i]._oy, IT_SWORD, ITEM_BASTSRD, FALSE, TRUE); + #if !IS_VERSION(SHAREWARE) + PlaySfxLoc(PS_BARD9, plr[myplr]._px, plr[myplr]._py); + #endif + } else if (plr[pnum]._pClass == CLASS_BARBARIAN) { + //Create special sword. + CreateMagicWeapon(object[i]._ox, object[i]._oy, IT_AXE, ITEM_BTLAXE, FALSE, TRUE); + #if !IS_VERSION(SHAREWARE) + PlaySfxLoc(PS_BARBARIAN9, plr[myplr]._px, plr[myplr]._py); + #endif + } + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateTrapLvr(int i) +{ + int j, oi; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oAnimFrame == 1) { + // Toggle to on + ++object[i]._oAnimFrame; + for (j = 0; j < numobjects; ++j) { + oi = objectactive[j]; + if ((object[oi]._otype == object[i]._oVar2) && (object[oi]._oVar1 == object[i]._oVar1)) { + object[oi]._oVar2 = 1; + object[oi]._oAnimFlag = FALSE; + } + } + } else { + // Toggle to off + --object[i]._oAnimFrame; + for (j = 0; j < numobjects; ++j) { + oi = objectactive[j]; + if ((object[oi]._otype == object[i]._oVar2) && (object[oi]._oVar1 == object[i]._oVar1)) { + object[oi]._oVar2 = 0; + if (object[oi]._oVar4 != 0) object[oi]._oAnimFlag = TRUE; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateSarc(int pnum, int i, bool sendmsg) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (!deltaload) PlaySfxLoc(IS_SARC, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + if (deltaload) { + object[i]._oAnimFrame = object[i]._oAnimLen; + return; + } else { + object[i]._oAnimFlag = TRUE; + object[i]._oAnimDelay = 3; + } + SetRndSeed(object[i]._oRndSeed); + if (object[i]._oVar1 <= 2) CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + if (object[i]._oVar1 >= 8) SpawnSkeleton(object[i]._oVar2, object[i]._ox, object[i]._oy); + +#if CHEATS + if (itemcheat) + CreateMagicWeapon(object[i]._ox, object[i]._oy, IT_STAFF, ITEM_SHRTSTAFF, FALSE, TRUE); +#endif + + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateL2Door(int pnum, int i, bool sendflag) +{ + int dpx, dpy; + + app_assert((DWORD)i < MAXOBJECTS); + dpx = abs(object[i]._ox - plr[pnum]._px); + dpy = abs(object[i]._oy - plr[pnum]._py); + if ((dpx == 1) && (dpy <= 1) && (object[i]._otype == OBJ_L2DOORL)) OperateL2LDoor(pnum, i, sendflag); + if ((dpx <= 1) && (dpy == 1) && (object[i]._otype == OBJ_L2DOORR)) OperateL2RDoor(pnum, i, sendflag); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateL3Door(int pnum, int i, bool sendflag) +{ + int dpx, dpy; + + app_assert((DWORD)i < MAXOBJECTS); + dpx = abs(object[i]._ox - plr[pnum]._px); + dpy = abs(object[i]._oy - plr[pnum]._py); + if ((dpx == 1) && (dpy <= 1) && (object[i]._otype == OBJ_L3DOORR)) OperateL3RDoor(pnum, i, sendflag); + if ((dpx <= 1) && (dpy == 1) && (object[i]._otype == OBJ_L3DOORL)) OperateL3LDoor(pnum, i, sendflag); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperatePedistal(int pnum, int i) +{ + int jstn; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar6 != 3) { + if (PlrHasItem(pnum, IDI_BLDSTONE, jstn)) { + RemoveInvItem(pnum, jstn); + ++object[i]._oAnimFrame; + ++object[i]._oVar6; + } + if (object[i]._oVar6 == 1) { + if (!deltaload) PlaySfxLoc(LS_PUDDLE, object[i]._ox, object[i]._oy); + ObjChangeMap(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + } + if (object[i]._oVar6 == 2) { + if (!deltaload) PlaySfxLoc(LS_PUDDLE, object[i]._ox, object[i]._oy); + ObjChangeMap(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7); + } + if (object[i]._oVar6 == 3) { + if (!deltaload) PlaySfxLoc(LS_BLODSTAR, object[i]._ox, object[i]._oy); + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + byte *setp; + setp = LoadFileInMemSig("Levels\\L2Data\\Blood2.DUN", NULL, 'STPC'); + LoadMapObjs(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + CreateItem(UID_ARMOFVAL, (setpc_x << 1) + 9 + DIRTEDGED2, (setpc_y << 1) + 3 + DIRTEDGED2); + object[i]._oSelFlag = OSEL_NONE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void TryDisarm(int pnum, int i) +{ + int j, oi, oti; + int trapdisper; + bool checkflag; + + if (pnum == myplr) NewCursor(GLOVE_CURS); + + app_assert((DWORD)i < MAXOBJECTS); + if (!object[i]._oTrapFlag) return; + + trapdisper = (plr[pnum]._pDexterity << 1) - (currlevel * 5); + if (random(154,100) > trapdisper) return; + + for (j = 0; j < numobjects; ++j) { + oi = objectactive[j]; + checkflag = false; + if (object[oi]._otype == OBJ_TRAPL) checkflag = true; + if (object[oi]._otype == OBJ_TRAPR) checkflag = true; + if (checkflag) { + oti = dObject[object[oi]._oVar1][object[oi]._oVar2] - 1; + if (oti == i) { + object[oi]._oVar4 = 1; + object[i]._oTrapFlag = FALSE; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int ItemMiscIdIdx(int imiscid) +{ + int i = 0; + while ((AllItemsList[i].iRnd == IRND_NO) || (AllItemsList[i].iMiscId != imiscid)) ++i; + return(i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateShrine(int pnum, int i, int sType) +{ + int r, xx, yy, idata, sc; + int v1, v2, v3, v4; + __int64 lv, t; + bool done; + + //Fixes any gold cheats + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + SetRndSeed(object[i]._oRndSeed); + object[i]._oSelFlag = OSEL_NONE; + if (! deltaload) { + PlaySfxLoc(sType, object[i]._ox, object[i]._oy); + object[i]._oAnimFlag = TRUE; + object[i]._oAnimDelay = 1; + } else { + object[i]._oAnimFrame = object[i]._oAnimLen; + object[i]._oAnimFlag = FALSE; + } + switch (object[i]._oVar1) { + case 0 : // Mysterious + if (deltaload) return; + if (pnum != myplr) return; + //Subtract 1 from all attributes + ModifyPlrStr(pnum, -1); + ModifyPlrMag(pnum, -1); + ModifyPlrDex(pnum, -1); + ModifyPlrVit(pnum, -1); + //Add 6 to random attribute. We are actually adding 5 since we + //subtracted 1 above. + switch(random(0, 4)) { + case 0: + ModifyPlrStr(pnum, 6); + break; + case 1: + ModifyPlrMag(pnum, 6); + break; + case 2: + ModifyPlrDex(pnum, 6); + break; + case 3: + ModifyPlrVit(pnum, 6); + break; + } + CheckStats(pnum); + InitDiabloMsg(SHRINE_1); + break; + case 1 : // Hidden + v1 = 0; + if (deltaload) return; + if (pnum != myplr) return; + //Find out if player has any items equipped + for (r = 0; r < NUM_INVLOC; ++r) { + if (plr[pnum].InvBody[r]._itype != -1) ++v1; + } + //Add 10 to max and current durability of all equipped items. + if (v1 > 0) { + for (r = 0; r < NUM_INVLOC; ++r) { + if (plr[pnum].InvBody[r]._itype != -1) { + //Ignore any items which are indestructible. + if ((plr[pnum].InvBody[r]._iMaxDur != INFINITE_DUR) && + (plr[pnum].InvBody[r]._iMaxDur != 0)) { + plr[pnum].InvBody[r]._iDurability += 10; + plr[pnum].InvBody[r]._iMaxDur += 10; + if (plr[pnum].InvBody[r]._iDurability > plr[pnum].InvBody[r]._iMaxDur) + plr[pnum].InvBody[r]._iDurability = plr[pnum].InvBody[r]._iMaxDur; + } + } + } + done = false; + while (!done) { + + // JMM.PATCH3 + int numitems = 0; + for( r = 0; r < NUM_INVLOC; ++r ) { + if ( plr[pnum].InvBody[r]._itype != -1 ) + ++numitems; + } + if( !numitems ) { + done = true; + break; + } + // JMM.ENDPATCH3 + + r = random(0, NUM_INVLOC); + if (plr[pnum].InvBody[r]._itype != -1) { + //Ignore any items which are indestructible. + if ((plr[pnum].InvBody[r]._iMaxDur != INFINITE_DUR) && + (plr[pnum].InvBody[r]._iMaxDur != 0)) { + //Subtract 20 from random equipped item. We are actually + //subtracting 10 since we added 10 above. + plr[pnum].InvBody[r]._iDurability -= 20; + plr[pnum].InvBody[r]._iMaxDur -= 20; + if (plr[pnum].InvBody[r]._iDurability <= 0) plr[pnum].InvBody[r]._iDurability = 1; + if (plr[pnum].InvBody[r]._iMaxDur <= 0) plr[pnum].InvBody[r]._iMaxDur = 1; + done = true; + break; + } + } + } + } + InitDiabloMsg(SHRINE_2); + break; + case 2: // Gloomy (Single Player Only) + if (deltaload) return; + if (pnum == myplr) { + if (plr[pnum].HeadItem._itype != -1) plr[pnum].HeadItem._iAC += 2; + if (plr[pnum].BodyItem._itype != -1) plr[pnum].BodyItem._iAC += 2; + if (plr[pnum].Hand1Item._itype != -1) { + if (plr[pnum].Hand1Item._itype == IT_SHIELD) + plr[pnum].Hand1Item._iAC += 2; + else { + --plr[pnum].Hand1Item._iMaxDam; + if (plr[pnum].Hand1Item._iMaxDam < plr[pnum].Hand1Item._iMinDam) + plr[pnum].Hand1Item._iMaxDam = plr[pnum].Hand1Item._iMinDam; + } + } + if (plr[pnum].Hand2Item._itype != -1) { + if (plr[pnum].Hand2Item._itype == IT_SHIELD) + plr[pnum].Hand2Item._iAC += 2; + else { + --plr[pnum].Hand2Item._iMaxDam; + if (plr[pnum].Hand2Item._iMaxDam < plr[pnum].Hand2Item._iMinDam) + plr[pnum].Hand2Item._iMaxDam = plr[pnum].Hand2Item._iMinDam; + } + } + for (r = 0; r < plr[pnum]._pNumInv; ++r) { + switch(plr[pnum].InvList[r]._itype) { + case IT_SHIELD: + case IT_ARMOR: + case IT_MARMOR: + case IT_HARMOR: + case IT_HELM: + plr[pnum].InvList[r]._iAC += 2; + break; + case IT_SWORD: + case IT_AXE: + case IT_BOW: + case IT_MACE: + case IT_STAFF: + --plr[pnum].InvList[r]._iMaxDam; + if (plr[pnum].InvList[r]._iMaxDam < plr[pnum].InvList[r]._iMinDam) + plr[pnum].InvList[r]._iMaxDam = plr[pnum].InvList[r]._iMinDam; + break; + } + } + InitDiabloMsg(SHRINE_3); + } + break; + case 3: // Weird (Single Player Only) + if (deltaload) return; + if (pnum == myplr) { + if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._itype != IT_SHIELD)) + ++plr[pnum].Hand1Item._iMaxDam; + if ((plr[pnum].Hand2Item._itype != -1) && (plr[pnum].Hand2Item._itype != IT_SHIELD)) + ++plr[pnum].Hand2Item._iMaxDam; + for (r = 0; r < plr[pnum]._pNumInv; ++r) { + switch(plr[pnum].InvList[r]._itype) { + case IT_SWORD: + case IT_AXE: + case IT_BOW: + case IT_MACE: + case IT_STAFF: + ++plr[pnum].InvList[r]._iMaxDam; + break; + } + } + InitDiabloMsg(SHRINE_4); + } + break; + case 4: // Magical + case 11: // Supernatural + if (deltaload) return; + //Cast mana shield + AddMissile(plr[pnum]._px, plr[pnum]._py, plr[pnum]._px, plr[pnum]._py, + plr[pnum]._pdir, MIT_MANASHIELD, -1, pnum, 0, + (leveltype << 1)); + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_5); + break; + case 5: // Stone + if (deltaload) return; + if (pnum == myplr) { + for (r = 0; r < NUM_INVLOC; ++r) { + if (plr[pnum].InvBody[r]._itype == IT_STAFF) + plr[pnum].InvBody[r]._iCharges = plr[pnum].InvBody[r]._iMaxCharges; + } + for (r = 0; r < plr[pnum]._pNumInv; ++r) { + if (plr[pnum].InvList[r]._itype == IT_STAFF) + plr[pnum].InvList[r]._iCharges = plr[pnum].InvList[r]._iMaxCharges; + } + for (r = 0; r < MAXSPD; ++r) { + if (plr[pnum].SpdList[r]._itype == IT_STAFF) + plr[pnum].SpdList[r]._iCharges = plr[pnum].SpdList[r]._iMaxCharges; + } + InitDiabloMsg(SHRINE_6); + } + break; + case 6: // Religious + if (deltaload) return; + if (pnum == myplr) { + for (r = 0; r < NUM_INVLOC; ++r) { + plr[pnum].InvBody[r]._iDurability = plr[pnum].InvBody[r]._iMaxDur; + } + for (r = 0; r < plr[pnum]._pNumInv; ++r) { + plr[pnum].InvList[r]._iDurability = plr[pnum].InvList[r]._iMaxDur; + } + for (r = 0; r < MAXSPD; ++r) { + plr[pnum].SpdList[r]._iDurability = plr[pnum].SpdList[r]._iMaxDur; + } + InitDiabloMsg(SHRINE_7); + } + break; + case 7: // Enchanted (Levels 1-8 Only) + if (deltaload) return; + if (pnum != myplr) return; + //Get memorized spell count + sc = 0; + lv = 1; + for (r = 1; r <= MAXSPELLS; ++r) { + if (plr[pnum]._pMemSpells & lv) ++sc; + lv = lv << 1; + } + //Only add and subtract if player has more than 1 spell memorized + if (sc > 1) { + //Add one to all memorized spell levels + lv = 1; + for (r = 1; r <= MAXSPELLS; ++r) { + if (plr[pnum]._pMemSpells & lv) { + if (plr[pnum]._pSplLvl[r] < SPELLCAP) { + ++plr[pnum]._pSplLvl[r]; + v1 = r; + } + } + lv = lv << 1; + } + //Subtract 2 from random memorized spell. We are actually subtracting + //1 since we added 1 above. + done = false; + while (!done) { + lv = 1; + r = random(0, MAXSPELLS); + lv = lv << r; + if (plr[pnum]._pMemSpells & lv) { + if (plr[pnum]._pSplLvl[r+1] >= 2) plr[pnum]._pSplLvl[r+1] -= 2; + else plr[pnum]._pSplLvl[r+1] = 0; + done = true; + break; + } + } + } + InitDiabloMsg(SHRINE_8); + break; + case 8: // Thaumaturgic (Single Player Only) + //All chests regenerate + for (r = 0; r < numobjects; ++r) { + v1 = objectactive[r]; + app_assert((DWORD)v1 < MAXOBJECTS); + if (((object[v1]._otype == OBJ_CHEST1) || + (object[v1]._otype == OBJ_CHEST2) || + (object[v1]._otype == OBJ_CHEST3)) && + (object[v1]._oSelFlag == OSEL_NONE)) { + object[v1]._oRndSeed = GetRndSeed(); + object[v1]._oSelFlag = OSEL_FLR; + object[v1]._oAnimFrame -= 2; + } + } + if (deltaload) return; + if (pnum == myplr) InitDiabloMsg(SHRINE_9); + break; + case 9: // Fascinating + if (deltaload) return; + if (pnum != myplr) return; + //Give player fire bolt level +2 + t = 1; + plr[pnum]._pMemSpells |= t << (SPL_FIREBOLT-1); + if (plr[pnum]._pSplLvl[SPL_FIREBOLT] < SPELLCAP) ++plr[pnum]._pSplLvl[SPL_FIREBOLT] ; + if (plr[pnum]._pSplLvl[SPL_FIREBOLT] < SPELLCAP) ++plr[pnum]._pSplLvl[SPL_FIREBOLT] ; + //Subtract 1/10 of mana + v1 = plr[pnum]._pMaxManaBase / 10; + v2 = plr[pnum]._pMana - plr[pnum]._pManaBase; + v3 = plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase; + plr[pnum]._pManaBase -= v1; + plr[pnum]._pMana -= v1; + plr[pnum]._pMaxMana -= v1; + plr[pnum]._pMaxManaBase -= v1; + if ((plr[pnum]._pMana >> MANA_SHIFT) <= 0) { + plr[pnum]._pMana = v2; + plr[pnum]._pManaBase = 0; + } + if ((plr[pnum]._pMaxMana >> MANA_SHIFT) <= 0) { + plr[pnum]._pMaxMana = v3; + plr[pnum]._pMaxManaBase = 0; + } + InitDiabloMsg(SHRINE_10); + break; + case 10: // Cryptic + if (deltaload) return; + //Cast nova + AddMissile(plr[pnum]._px, plr[pnum]._py, plr[pnum]._px, plr[pnum]._py, + plr[pnum]._pdir, MIT_NOVA, -1, pnum, 0, (leveltype << 1)); + if (pnum != myplr) return; + //Give full mana + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + InitDiabloMsg(SHRINE_11); + break; + case 12: // Eldritch + if (deltaload) return; + if (pnum == myplr) { + //All health and mana potions become full rejuv. + for (r = 0; r < plr[pnum]._pNumInv; ++r) { + if (plr[pnum].InvList[r]._itype == IT_MISC) { + if ((plr[pnum].InvList[r]._iMiscId == IMID_PLHEAL) || + (plr[pnum].InvList[r]._iMiscId == IMID_PMANA)) { + idata = ItemMiscIdIdx(IMID_REJUV); + SetPlrHandItem(&plr[pnum].HoldItem, idata); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = TRUE; + plr[pnum].InvList[r] = plr[pnum].HoldItem; + } + if ((plr[pnum].InvList[r]._iMiscId == IMID_PHEAL) || + (plr[pnum].InvList[r]._iMiscId == IMID_PFMANA)) { + idata = ItemMiscIdIdx(IMID_FREJUV); + SetPlrHandItem(&plr[pnum].HoldItem, idata); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = TRUE; + plr[pnum].InvList[r] = plr[pnum].HoldItem; + } + } + } + for (r = 0; r < MAXSPD; ++r) { + if (plr[pnum].SpdList[r]._itype == IT_MISC) { + if ((plr[pnum].SpdList[r]._iMiscId == IMID_PLHEAL) || + (plr[pnum].SpdList[r]._iMiscId == IMID_PMANA)) { + idata = ItemMiscIdIdx(IMID_REJUV); + SetPlrHandItem(&plr[pnum].HoldItem, idata); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = TRUE; + plr[pnum].SpdList[r] = plr[pnum].HoldItem; + } + if ((plr[pnum].SpdList[r]._iMiscId == IMID_PHEAL) || + (plr[pnum].SpdList[r]._iMiscId == IMID_PFMANA)) { + idata = ItemMiscIdIdx(IMID_FREJUV); + SetPlrHandItem(&plr[pnum].HoldItem, idata); + GetPlrHandSeed(&plr[pnum].HoldItem); + plr[pnum].HoldItem._iStatFlag = TRUE; + plr[pnum].SpdList[r] = plr[pnum].HoldItem; + } + } + } + InitDiabloMsg(SHRINE_13); + } + break; + case 13: // Eerie + if (deltaload) return; + if (pnum != myplr) return; + //Add 2 to magic + ModifyPlrMag(pnum, 2); + CheckStats(pnum); + InitDiabloMsg(SHRINE_14); + break; + case 14: // Divine + if (deltaload) return; + if (pnum != myplr) return; + //Put this in because full rejuvs are only available from level 7 on. + if ((currlevel << 1) < 7) { + //Create 1 full heal and 1 full mana + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_MISC, IMID_PFMANA, FALSE, TRUE); + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_MISC, IMID_PHEAL, FALSE, TRUE); + } else { + //Create 2 full rejuv + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_MISC, IMID_FREJUV, FALSE, TRUE); + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_MISC, IMID_FREJUV, FALSE, TRUE); + } + //Give full mana and life + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + InitDiabloMsg(SHRINE_15); + break; + case 15: // Holy + if (deltaload) return; + v4 = 0; + do { + v1 = random(159,DMAXX); + v2 = random(159,DMAXY); + v3 = dPiece[v1][v2]; + ++v4; + if (v4 > (DMAXX*DMAXY)) break; + } while (nSolidTable[v3] != 0 || dObject[v1][v2] != 0 || dMonster[v1][v2] != 0); + //Cast phase + AddMissile(plr[pnum]._px, plr[pnum]._py, v1, v2, plr[pnum]._pdir, + MIT_PHASE, -1, pnum, 0, (leveltype << 1)); + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_16); + break; + case 16: // Sacred + if (deltaload) return; + if (pnum != myplr) return; + //Give player charged bolt level +2 + t = 1; + plr[pnum]._pMemSpells |= t << (SPL_CBOLT-1); + if (plr[pnum]._pSplLvl[SPL_CBOLT] < SPELLCAP) ++plr[pnum]._pSplLvl[SPL_CBOLT] ; + if (plr[pnum]._pSplLvl[SPL_CBOLT] < SPELLCAP) ++plr[pnum]._pSplLvl[SPL_CBOLT] ; + //Subtract 1/10 of mana + v1 = plr[pnum]._pMaxManaBase / 10; + v2 = plr[pnum]._pMana - plr[pnum]._pManaBase; + v3 = plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase; + plr[pnum]._pManaBase -= v1; + plr[pnum]._pMana -= v1; + plr[pnum]._pMaxMana -= v1; + plr[pnum]._pMaxManaBase -= v1; + if ((plr[pnum]._pMana >> MANA_SHIFT) <= 0) { + plr[pnum]._pMana = v2; + plr[pnum]._pManaBase = 0; + } + if ((plr[pnum]._pMaxMana >> MANA_SHIFT) <= 0) { + plr[pnum]._pMaxMana = v3; + plr[pnum]._pMaxManaBase = 0; + } + InitDiabloMsg(SHRINE_17); + break; + case 17: // Spiritual + if (deltaload) return; + if (pnum != myplr) return; + //Fill inventory with gold + for (r = 0; r < MAXINV; ++r) { + if (plr[pnum].InvGrid[r] == 0) { + v2 = (leveltype * 5) + random(160,leveltype * 10); + v1 = plr[pnum]._pNumInv; + plr[pnum].InvList[v1] = golditem; + plr[pnum].InvList[v1]._iSeed = GetRndSeed(); + ++plr[pnum]._pNumInv; + plr[pnum].InvGrid[r] = plr[pnum]._pNumInv; + plr[pnum].InvList[v1]._ivalue = v2; + plr[pnum]._pGold += v2; + SetGoldCurs(pnum, v1); + } + } + InitDiabloMsg(SHRINE_18); + break; + case 18: // Spooky (Multi Player Only) + if (deltaload) return; + if (pnum == myplr) InitDiabloMsg(SHRINE_19); + else { + //Full rejuv for other players + InitDiabloMsg(SHRINE_19B); + plr[myplr]._pHitPoints = plr[myplr]._pMaxHP; + plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase; + plr[myplr]._pMana = plr[myplr]._pMaxMana; + plr[myplr]._pManaBase = plr[myplr]._pMaxManaBase; + } + break; + case 19: // Abandoned + if (deltaload) return; + if (pnum != myplr) return; + //Add 2 to dexterity + ModifyPlrDex(pnum, 2); + CheckStats(pnum); + if (pnum == myplr) InitDiabloMsg(SHRINE_20); + break; + case 20: // Creepy + if (deltaload) return; + if (pnum != myplr) return; + //Add 2 to strength + ModifyPlrStr(pnum, 2); + CheckStats(pnum); + if (pnum == myplr) InitDiabloMsg(SHRINE_21); + break; + case 21: // Quiet + if (deltaload) return; + if (pnum != myplr) return; + //Add 2 to vitality + ModifyPlrVit(pnum, 2); + CheckStats(pnum); + if (pnum == myplr) InitDiabloMsg(SHRINE_22); + break; + case 22: // Secluded + if (deltaload) return; + if (pnum == myplr) { + //Complete automap for current level + for (yy = 0; yy < AUTOMAPY; ++yy) { + for (xx = 0; xx < AUTOMAPX; ++xx) automapview[xx][yy] = TRUE; + } + InitDiabloMsg(SHRINE_23); + } + break; + case 23: // Ornate + if (deltaload) return; + if (pnum != myplr) return; + //Give player holy bolt level +2 + t = 1; + plr[pnum]._pMemSpells |= t << (SPL_HBOLT-1); + if (plr[pnum]._pSplLvl[SPL_HBOLT] < SPELLCAP) ++plr[pnum]._pSplLvl[SPL_HBOLT] ; + if (plr[pnum]._pSplLvl[SPL_HBOLT] < SPELLCAP) ++plr[pnum]._pSplLvl[SPL_HBOLT] ; + //Subtract 1/10 of mana + v1 = plr[pnum]._pMaxManaBase / 10; + v2 = plr[pnum]._pMana - plr[pnum]._pManaBase; + v3 = plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase; + plr[pnum]._pManaBase -= v1; + plr[pnum]._pMana -= v1; + plr[pnum]._pMaxMana -= v1; + plr[pnum]._pMaxManaBase -= v1; + if ((plr[pnum]._pMana >> MANA_SHIFT) <= 0) { + plr[pnum]._pMana = v2; + plr[pnum]._pManaBase = 0; + } + if ((plr[pnum]._pMaxMana >> MANA_SHIFT) <= 0) { + plr[pnum]._pMaxMana = v3; + plr[pnum]._pMaxManaBase = 0; + } + InitDiabloMsg(SHRINE_24); + break; + case 24: // Glimmering + if (deltaload) return; + if (pnum != myplr) return; + //All items are identified + for (r = 0; r < NUM_INVLOC; ++r) { + if ((plr[pnum].InvBody[r]._iMagical != IMAGIC_NONE) && !plr[pnum].InvBody[r]._iIdentified) + plr[pnum].InvBody[r]._iIdentified = TRUE; + } + for (r = 0; r < plr[pnum]._pNumInv; ++r) { + if ((plr[pnum].InvList[r]._iMagical != IMAGIC_NONE) && !plr[pnum].InvList[r]._iIdentified) + plr[pnum].InvList[r]._iIdentified = TRUE; + } + for (r = 0; r < MAXSPD; ++r) { + if ((plr[pnum].SpdList[r]._iMagical != IMAGIC_NONE) && !plr[pnum].SpdList[r]._iIdentified) + plr[pnum].SpdList[r]._iIdentified = TRUE; + } + InitDiabloMsg(SHRINE_25); + break; + case 25: // Tainted (Multi Player Only) + if (deltaload) return; + if (pnum == myplr) InitDiabloMsg(SHRINE_26); + else { + //All other players get +1 to 3 random stats and -1 to other + InitDiabloMsg(SHRINE_26B); + r = random(155,4); + if (r == 0) v1 = 1; + else v1 = -1; + if (r == 1) v2 = 1; + else v2 = -1; + if (r == 2) v3 = 1; + else v3 = -1; + if (r == 3) v4 = 1; + else v4 = -1; + ModifyPlrStr(myplr, v1); + ModifyPlrMag(myplr, v2); + ModifyPlrDex(myplr, v3); + ModifyPlrVit(myplr, v4); + CheckStats(myplr); + } + break; + case 26: // Oily + // Increase good stats by 1. + if (deltaload) return; + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_27); + switch(plr[myplr]._pClass) + { + case CLASS_SORCEROR: + ModifyPlrMag(myplr,2); + break; + case CLASS_ROGUE: + ModifyPlrDex(myplr,2); + break; + case CLASS_WARRIOR: + ModifyPlrStr(myplr,2); + break; + case CLASS_BARBARIAN: + ModifyPlrVit(myplr,2); + break; + case CLASS_MONK: + ModifyPlrStr(myplr,1); + ModifyPlrDex(myplr,1); + break; + case CLASS_BARD: + ModifyPlrDex(myplr,1); + ModifyPlrMag(myplr,1); + break; + } + CheckStats(pnum); + AddMissile(object[i]._ox, object[i]._oy, plr[myplr]._px, plr[myplr]._py, plr[myplr]._pdir, MIT_FIREWALL, MI_ENEMYPLR, 0, 2 + (2 * currlevel), 0); + break; + case 27: // Glowing + { + if (deltaload) return; + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_28); + long CurrentExp = plr[myplr]._pExperience; + long ModMagic; + + if (CurrentExp > 5000) + { + ModMagic = 5; + CurrentExp = (long)(CurrentExp * 0.95); + } + else + { + ModMagic = CurrentExp/1000; + CurrentExp = 0; + + } + + ModifyPlrMag(myplr, ModMagic); + plr[myplr]._pExperience = CurrentExp; + CheckStats(pnum); + + } + break; + case 28: // Mendicant's + { + if (deltaload) return; + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_29); + long const HalfCurrentGold = plr[myplr]._pGold / 2; + + AddPlrExperience(myplr, plr[myplr]._pLevel, HalfCurrentGold); + TakePlrsMoney(HalfCurrentGold); // uses global var myplr. + CheckStats(pnum); + } + break; + case 29: // Sparkling + if (deltaload) return; + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_30); + AddPlrExperience(myplr, plr[myplr]._pLevel, 1000 * currlevel); + AddMissile(object[i]._ox, object[i]._oy, plr[myplr]._px, plr[myplr]._py, plr[myplr]._pdir, MIT_FLASH, MI_ENEMYPLR, 0, 2 + (3 * currlevel), 0); + CheckStats(pnum); + break; + case 30: // Town + if (deltaload) return; + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_31); + AddMissile(object[i]._ox, object[i]._oy, plr[myplr]._px, plr[myplr]._py, plr[myplr]._pdir, MIT_TOWN, MI_ENEMYPLR, 0, 0, 0); + break; + case 31: // Shimmering + if (deltaload) return; + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_32); + plr[pnum]._pMana = plr[pnum]._pMaxMana; // restore to full mana. + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + break; + case 32: // Solar + { + if (deltaload) return; + if (pnum != myplr) return; + time_t time_of_day = time(0); + struct tm * const tmbuf = localtime(&time_of_day); + + if (tmbuf->tm_hour > 20 || tmbuf->tm_hour < 4) + { + InitDiabloMsg(SHRINE_33D); + ModifyPlrVit(myplr, 2); + } + else if (tmbuf->tm_hour > 18) + { + InitDiabloMsg(SHRINE_33C); + ModifyPlrMag(myplr, 2); + } + else if (tmbuf->tm_hour > 12) + { + InitDiabloMsg(SHRINE_33B); + ModifyPlrStr(myplr, 2); + } + else if (tmbuf->tm_hour > 4) + { + InitDiabloMsg(SHRINE_33A); + ModifyPlrDex(myplr, 2); + } + + CheckStats(pnum); + } + break; + case 33: // Murphy's + { + if (deltaload) return; + if (pnum != myplr) return; + InitDiabloMsg(SHRINE_34); + long i; + long broken = 0; + + for (i = 0; i < 7; ++i) + { + ItemStruct * const itm = &plr[myplr].InvBody[i]; + + if (itm->_itype == -1) continue; + + if (random(0,3) == 0 + && itm->_iDurability != INFINITE_DUR + && itm->_iDurability != 0) // There are two values for infinite durablity !!! + { + // Randomly break something. + itm->_iDurability /= 2; + broken = 1; + break; + } + } + + if (!broken) + { + long const ThirdCurrentGold = plr[myplr]._pGold / 3; + TakePlrsMoney(ThirdCurrentGold); // uses global var myplr. + } + } + break; + } + CalcPlrInv(pnum, TRUE); + force_redraw = FULLDRAW; + if (pnum == myplr) NetSendCmdParam2(FALSE,CMD_PLROPOBJ,pnum,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateSkelBook(int pnum, int i, bool sendmsg) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (!deltaload) PlaySfxLoc(IS_ISCROL, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + object[i]._oAnimFrame += 2; + if (deltaload) return; + SetRndSeed(object[i]._oRndSeed); + if (random(161,5)) CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_MISC, IMID_SCROLL, sendmsg, FALSE); + else CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_MISC, IMID_BOOK, sendmsg, FALSE); + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateBookCase(int pnum, int i, bool sendmsg) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (!deltaload) PlaySfxLoc(IS_ISCROL, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + object[i]._oAnimFrame -= 2; + if (deltaload) return; + SetRndSeed(object[i]._oRndSeed); + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_MISC, IMID_BOOK, sendmsg, FALSE); + if (QuestStatus(Q_ZHAR)) { + if (monster[4].mName == UniqMonst[MU_ZHAR].mName) { + if ((monster[4]._msquelch == 255) && (monster[4]._mhitpoints != 0)) { + monster[4].mtalkmsg = TXT_ZHAR2; + M_StartStand(0, monster[4]._mdir); + monster[4]._mgoal = MG_ATTACK2; + monster[4]._mmode = MM_TALK; + } + } + } + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateDecap(int pnum, int i, bool sendmsg) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + object[i]._oSelFlag = OSEL_NONE; + if (deltaload) return; + SetRndSeed(object[i]._oRndSeed); + CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateArmorStand(int pnum, int i, bool sendmsg) +{ + int uniqueRnd; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + object[i]._oSelFlag = OSEL_NONE; + ++object[i]._oAnimFrame; + if (deltaload) return; + SetRndSeed(object[i]._oRndSeed); + + //Randomize uniqueness + uniqueRnd = random(0, 2); + //Create an appropriate armor for the current level + if (currlevel <= 5) { + //Create unique only IT_ARMOR + CreateTypeItem(object[i]._ox, object[i]._oy, TRUE, IT_ARMOR, IMID_NONE, sendmsg, FALSE); + } else if (currlevel >= 6 && currlevel <= 9) { + //Create random unique IT_MARMOR + CreateTypeItem(object[i]._ox, object[i]._oy, uniqueRnd, IT_MARMOR, IMID_NONE, sendmsg, FALSE); + } else if (currlevel >= 10 && currlevel <= 12) { + //Create non-unique IT_HARMOR + CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, IT_HARMOR, IMID_NONE, sendmsg, FALSE); + } else if (currlevel >= 13 && currlevel <= 16) { + //Create unique IT_HARMOR + CreateTypeItem(object[i]._ox, object[i]._oy, TRUE, IT_HARMOR, IMID_NONE, sendmsg, FALSE); + } else if (currlevel >= 17) { + //Use the uniques for now, but we will add our own specifics JKE 7/30 + CreateTypeItem(object[i]._ox, object[i]._oy, TRUE, IT_HARMOR, IMID_NONE, sendmsg, FALSE); + } + + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static int FindValidShrine(int i) +/*-----------------------------------------------------------------------* +** Description: Used by OperateGoatShrine and OperateCauldron to find a +** usable shrine function. +** Input: i = Object index +** Return: Shrine function index. +**-----------------------------------------------------------------------*/ +{ + int rv; + bool done = false; + + //Search until we find a valid shrine type. Ignore Thaumaturgic shrine + //because it could possibly screw up the animation. + do { + rv = random(0, NUMSHRINETYPES); + if ((currlevel >= shrineminlvl[rv]) && + (currlevel <= shrinemaxlvl[rv]) && + (rv != 8)) { + done = true; + } + if (done) { + if ((gbMaxPlayers != 1) && (shrineavail[rv] == SHRINE_SINGLE)) { + done = FALSE; + } else if ((gbMaxPlayers == 1) && (shrineavail[rv] == SHRINE_MULTI)) { + done = FALSE; + } else done = TRUE; //We found a shrine type we can use. + } + } while (!done); + + return rv; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateGoatShrine(int pnum, int i, int sType) +{ + app_assert((DWORD)i < MAXOBJECTS); + SetRndSeed(object[i]._oRndSeed); + object[i]._oVar1 = FindValidShrine(i); + OperateShrine(pnum, i, sType); + object[i]._oAnimDelay = 2; + force_redraw = FULLDRAW; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateCauldron(int pnum, int i, int sType) +{ + app_assert((DWORD)i < MAXOBJECTS); + SetRndSeed(object[i]._oRndSeed); + object[i]._oVar1 = FindValidShrine(i); + OperateShrine(pnum, i, sType); + object[i]._oAnimFrame = 3; + object[i]._oAnimFlag = FALSE; + force_redraw = FULLDRAW; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static bool OperateFountains(int pnum, int i) +{ + int ii; + bool rv = false; + + app_assert((DWORD)i < MAXOBJECTS); + SetRndSeed(object[i]._oRndSeed); + + switch(object[i]._otype) { + case OBJ_PURIFYINGFTN: + if (deltaload) return rv; + if (pnum != myplr) return rv; + if (plr[pnum]._pMana < plr[pnum]._pMaxMana) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + //Add 1 Mana point + plr[pnum]._pMana += (1 << MANA_SHIFT); + plr[pnum]._pManaBase += (1 << MANA_SHIFT); + if (plr[pnum]._pMana > plr[pnum]._pMaxMana) { + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + } + rv = true; + } else if (!deltaload) PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + break; + case OBJ_BLOODFTN: + if (deltaload) return rv; + if (pnum != myplr) return rv; + if (plr[pnum]._pHitPoints < plr[pnum]._pMaxHP) { + PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + //Add 1 HP point + plr[pnum]._pHitPoints += (1 << HP_SHIFT); + plr[pnum]._pHPBase += (1 << HP_SHIFT); + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) { + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + } + rv = true; + } else if (!deltaload) PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + break; + case OBJ_MURKYFTN: + if (object[i]._oSelFlag != OSEL_NONE) { + if (!deltaload) PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + if (deltaload) return rv; + //Casts infravision + AddMissile(plr[pnum]._px, plr[pnum]._py, plr[pnum]._px, plr[pnum]._py, + plr[pnum]._pdir, MIT_INFRA, -1, pnum, 0, + (leveltype << 1)); + rv = true; + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); + } + break; + case OBJ_TEARFTN: + if (object[i]._oSelFlag != OSEL_NONE) { + int rndVal; + int statVal = -1; + int saveRnd = -1; + int status = FALSE; + ii = 0; + if (!deltaload) PlaySfxLoc(LS_FOUNTAIN, object[i]._ox, object[i]._oy); + object[i]._oSelFlag = OSEL_NONE; + if (deltaload) return rv; + if (pnum != myplr) return rv; + //-1 to random stat, +1 to another + do { + if ((rndVal = random(0, 4)) != saveRnd) { + switch(rndVal) { + case 0: + ModifyPlrStr(pnum, statVal); + break; + case 1: + ModifyPlrMag(pnum, statVal); + break; + case 2: + ModifyPlrDex(pnum, statVal); + break; + case 3: + ModifyPlrVit(pnum, statVal); + break; + } + saveRnd = rndVal; + statVal = 1; + ++ii; + } + if (ii > 1) status = TRUE; + } while(!status); + CheckStats(pnum); + rv = true; + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); + } + break; + } + force_redraw = FULLDRAW; + return rv; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateWeaponRack(int pnum, int i, bool sendmsg) +{ + int weaponType, sfxType; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + SetRndSeed(object[i]._oRndSeed); + + //Choose random weapon/sfx type + switch((random(0, 4)+1)) { + case 1: + weaponType = IT_SWORD; + sfxType = IS_FSWOR; + break; + case 2: + weaponType = IT_AXE; + sfxType = IS_FAXE; + break; + case 3: + weaponType = IT_BOW; + sfxType = IS_FBOW; + break; + case 4: + weaponType = IT_MACE; + sfxType = IS_FAXE; + break; + } + + object[i]._oSelFlag = OSEL_NONE; + ++object[i]._oAnimFrame; + if (deltaload) return; + + //Create a random weapon. Create unique weapons from level 4 down. + if (leveltype > 1) CreateTypeItem(object[i]._ox, object[i]._oy, TRUE, weaponType, IMID_NONE, sendmsg, FALSE); + else CreateTypeItem(object[i]._ox, object[i]._oy, FALSE, weaponType, IMID_NONE, sendmsg, FALSE); + + if (pnum == myplr) NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateStoryBook(int pnum, int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (deltaload) return; + if (qtextflag) return; + if (pnum != myplr) return; + object[i]._oAnimFrame = object[i]._oVar4; + PlaySfxLoc(IS_ISCROL, object[i]._ox, object[i]._oy); + + if ((object[i]._oVar8 != 0) && (currlevel == NA_KRUL_LEVEL)) + { + if ((Na_Krul.Lever_Thrown != TRUE) && (quests[Q_NA_KRUL]._qactive != QUEST_DONE)) + if(HCheckSpell(object[i]._oVar8)) + { + NetSendCmd(FALSE,CMD_OPEN_NAKRUL); + return; + } + } + else if (currlevel >= CRYPTSTART) + { + quests[Q_NA_KRUL]._qactive = QUEST_NOTDONE; + quests[Q_NA_KRUL]._qlog = TRUE; + quests[Q_NA_KRUL]._qmsg = object[i]._oVar2; + } + + InitQTextMsg(object[i]._oVar2); + NetSendCmdParam1(FALSE,CMD_OPERATEOBJ,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void OperateLazStand(int pnum, int i) +{ + int x, y; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; + if (deltaload) return; + if (qtextflag) return; + if (pnum != myplr) return; + ++object[i]._oAnimFrame; + object[i]._oSelFlag = OSEL_NONE; + GetSuperItemLoc(object[i]._ox, object[i]._oy, x, y); + SpawnQuestItem(IDI_LAZSTAFF, x, y, 0, ISEL_NONE); + //quests[Q_BKMUSHRM]._qvar1 = QS_MUSHSPAWNED; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void OperateObject(int pnum, int i, BOOL TeleFlag) +{ + bool senditemmsg; + + if (pnum == myplr) senditemmsg = true; + else senditemmsg = false; + + app_assert((DWORD)i < MAXOBJECTS); + switch (object[i]._otype) { + case OBJ_L1DOORL : + case OBJ_L1DOORR : + if (TeleFlag) { + if (object[i]._otype == OBJ_L1DOORL) OperateL1LDoor(pnum, i, true); + if (object[i]._otype == OBJ_L1DOORR) OperateL1RDoor(pnum, i, true); + } else { + if (pnum == myplr) OperateL1Door(pnum, i, TRUE); + } + break; + case OBJ_L2DOORL : + case OBJ_L2DOORR : + if (TeleFlag) { + if (object[i]._otype == OBJ_L2DOORL) OperateL2LDoor(pnum, i, true); + if (object[i]._otype == OBJ_L2DOORR) OperateL2RDoor(pnum, i, true); + } else { + if (pnum == myplr) OperateL2Door(pnum, i, TRUE); + } + break; + case OBJ_L3DOORL : + case OBJ_L3DOORR : + if (TeleFlag) { + if (object[i]._otype == OBJ_L3DOORL) OperateL3LDoor(pnum, i, true); + if (object[i]._otype == OBJ_L3DOORR) OperateL3RDoor(pnum, i, true); + } else { + if (pnum == myplr) OperateL3Door(pnum, i, TRUE); + } + break; + case OBJ_SWITCHSKL: + case OBJ_LEVER : + OperateLever(pnum, i); + break; + case OBJ_BOOK2L: + OperateBook(pnum, i); + break; + case OBJ_BOOK2R: + OperateSChambBk(pnum, i); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + OperateChest(pnum, i, senditemmsg); + break; + case OBJ_SARC: + OperateSarc(pnum, i, senditemmsg); + break; + case OBJ_FLAMELVR: + OperateTrapLvr(i); + break; +// case OBJ_BOOKLVR: + case OBJ_BLINDBOOK: + case OBJ_BLOODBOOK: + case OBJ_STEELTOME: + OperateBookLever(pnum, i); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + OperateShrine(pnum, i, IS_MAGIC); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + OperateSkelBook(pnum, i, senditemmsg); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + OperateBookCase(pnum, i, senditemmsg); + break; + case OBJ_DECAP: + OperateDecap(pnum, i, senditemmsg); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + OperateArmorStand(pnum, i, senditemmsg); + break; + case OBJ_GOATSHRINE: + OperateGoatShrine(pnum, i, LS_GSHRINE); + break; + case OBJ_CAULDRON: + OperateCauldron(pnum, i, LS_CALDRON); + break; + case OBJ_MURKYFTN: + case OBJ_TEARFTN: + case OBJ_BLOODFTN: + case OBJ_PURIFYINGFTN: + OperateFountains(pnum, i); + break; + case OBJ_STORYBOOK: + OperateStoryBook(pnum, i); + break; + case OBJ_PEDISTAL: + OperatePedistal(pnum, i); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + OperateWeaponRack(pnum, i, senditemmsg); + break; + case OBJ_MUSHPATCH: + OperateMushPatch(pnum, i); + break; + case OBJ_LAZSTAND: + OperateLazStand(pnum, i); + break; + case OBJ_SLAINHERO: + OperateSlainHero(pnum, i, senditemmsg); + break; + case OBJ_SIGNCHEST: + OperateInnSignChest(pnum, i); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncOpL1Door(int pnum, int cmd, int i) +{ + if (pnum == myplr) return; + bool opok = false; + app_assert((DWORD)i < MAXOBJECTS); + if ((cmd == CMD_OPENDOOR) && (object[i]._oVar4 == DOOR_CLOSED)) opok = TRUE; + if ((cmd == CMD_CLOSEDOOR) && (object[i]._oVar4 == DOOR_OPEN)) opok = TRUE; + if (opok) { + if (object[i]._otype == OBJ_L1DOORL) OperateL1LDoor(-1, i, false); + if (object[i]._otype == OBJ_L1DOORR) OperateL1RDoor(-1, i, false); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncOpL2Door(int pnum, int cmd, int i) +{ + if (pnum == myplr) return; + bool opok = false; + app_assert((DWORD)i < MAXOBJECTS); + if ((cmd == CMD_OPENDOOR) && (object[i]._oVar4 == DOOR_CLOSED)) opok = true; + if ((cmd == CMD_CLOSEDOOR) && (object[i]._oVar4 == DOOR_OPEN)) opok = true; + if (opok) { + if (object[i]._otype == OBJ_L2DOORL) OperateL2LDoor(-1, i, false); + if (object[i]._otype == OBJ_L2DOORR) OperateL2RDoor(-1, i, false); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncOpL3Door(int pnum, int cmd, int i) +{ + if (pnum == myplr) return; + bool opok = false; + app_assert((DWORD)i < MAXOBJECTS); + if ((cmd == CMD_OPENDOOR) && (object[i]._oVar4 == DOOR_CLOSED)) opok = true; + if ((cmd == CMD_CLOSEDOOR) && (object[i]._oVar4 == DOOR_OPEN)) opok = true; + if (opok) { + if (object[i]._otype == OBJ_L3DOORL) OperateL3LDoor(-1, i, false); + if (object[i]._otype == OBJ_L3DOORR) OperateL3RDoor(-1, i, false); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncOpObject(int pnum, int cmd, int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + switch (object[i]._otype) { + case OBJ_L1DOORL : + case OBJ_L1DOORR : + SyncOpL1Door(pnum, cmd, i); + break; + case OBJ_L2DOORL : + case OBJ_L2DOORR : + SyncOpL2Door(pnum, cmd, i); + break; + case OBJ_L3DOORL : + case OBJ_L3DOORR : + SyncOpL3Door(pnum, cmd, i); + break; + case OBJ_SWITCHSKL: + case OBJ_LEVER : + OperateLever(pnum, i); + break; + case OBJ_CHEST1: + case OBJ_CHEST2: + case OBJ_CHEST3: + case OBJ_TCHEST1: + case OBJ_TCHEST2: + case OBJ_TCHEST3: + OperateChest(pnum, i, FALSE); + break; + case OBJ_SARC: + OperateSarc(pnum, i, FALSE); + break; +// case OBJ_BOOKLVR: + case OBJ_BLINDBOOK: + case OBJ_BLOODBOOK: + case OBJ_STEELTOME: + OperateBookLever(pnum, i); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + OperateShrine(pnum, i, IS_MAGIC); + break; + case OBJ_SKELBOOK: + case OBJ_BOOKSTAND: + OperateSkelBook(pnum, i, FALSE); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + OperateBookCase(pnum, i, FALSE); + break; + case OBJ_DECAP: + OperateDecap(pnum, i, FALSE); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + OperateArmorStand(pnum, i, FALSE); + break; + case OBJ_GOATSHRINE: + OperateGoatShrine(pnum, i, LS_GSHRINE); + break; + case OBJ_CAULDRON: + OperateCauldron(pnum, i, LS_CALDRON); + break; + case OBJ_MURKYFTN: + case OBJ_TEARFTN: + OperateFountains(pnum, i); + break; + case OBJ_STORYBOOK: + OperateStoryBook(pnum, i); + break; + case OBJ_PEDISTAL: + OperatePedistal(pnum, i); + break; + case OBJ_WARWEAP: + case OBJ_WEAPONRACK: + OperateWeaponRack(pnum, i, FALSE); + break; + case OBJ_MUSHPATCH: + OperateMushPatch(pnum, i); + break; + case OBJ_SLAINHERO: + OperateSlainHero(pnum, i, FALSE); + break; + case OBJ_SIGNCHEST: + OperateInnSignChest(pnum, i); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void BreakCrux(int i) +{ + int j, ot, oi; + bool mapflag; + + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oAnimFlag = TRUE; + object[i]._oAnimFrame = 1; + object[i]._oAnimDelay = 1; + object[i]._oSolidFlag = TRUE; + object[i]._oMissFlag = TRUE; + object[i]._oBreak = OBJ_BROKEN; + object[i]._oSelFlag = OSEL_NONE; + + mapflag = true; + for (j = 0; j < numobjects; ++j) { + oi = objectactive[j]; + ot = object[oi]._otype; + if ((ot == OBJ_CRUX1) || (ot == OBJ_CRUX2) || (ot == OBJ_CRUX3)) { + if (object[i]._oVar8 == object[oi]._oVar8) { + if (object[oi]._oBreak != OBJ_BROKEN) mapflag = false; + } + } + } + + if (mapflag) { + if (!deltaload) PlaySfxLoc(IS_LEVER, object[i]._ox, object[i]._oy); + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +// DKT971012: Gary has items.cpp checked out; this should go there + +void RndUnique(int x, int y, int level) +{ + int uil[MAXUITEMS]; + int i, numui = 0; + + for (i=UID_LGTFORGE+1; i < MAXUITEMS && UniqueItemList[i].UIItemId != -1; ++i) + { + if (level*2 >= UniqueItemList[i].UIMinLvl) + uil[numui++] = i; + } + + if (numui > 0) + { + int uitem = uil[random(0, numui)]; + SpawnUnique(uitem, x, y); + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void BreakBarrel(int pnum, int i, int dam, BOOL forcebreak, BOOL sendmsg) +{ + int x, y, oi; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) return; // already broken? + if (forcebreak) { + object[i]._oVar1 = 0; // force it to bust open + } else { + object[i]._oVar1 -= dam; // normal damage + // if someone else is breaking the object, and it wasn't a force break + // message, then it hasn't broken yet. + if ((pnum != myplr) && (object[i]._oVar1 <= 0)) object[i]._oVar1 = 1; + } + if (object[i]._oVar1 > 0) { + if (!deltaload) PlaySfxLoc(IS_IBOW, object[i]._ox, object[i]._oy); + return; + } + + object[i]._oVar1 = 0; // broken + object[i]._oAnimFlag = TRUE; + object[i]._oAnimFrame = 1; + object[i]._oAnimDelay = 1; + object[i]._oSolidFlag = FALSE; + object[i]._oMissFlag = TRUE; + object[i]._oBreak = OBJ_BROKEN; + object[i]._oSelFlag = OSEL_NONE; + object[i]._oPreFlag = TRUE; + if (deltaload) { + object[i]._oAnimFrame = object[i]._oAnimLen; + object[i]._oAnimCnt = 0; + object[i]._oAnimDelay = 1000; + return; + } + if (object[i]._otype == OBJ_BARRELEX) { + bool foo; + + if (currlevel >= CRYPTSTART && currlevel <= CRYPTEND) + PlaySfxLoc(IS_URNFIRE, object[i]._ox, object[i]._oy); + else if (currlevel >= HIVESTART && currlevel <= HIVEEND) + PlaySfxLoc(IS_PODFIRE, object[i]._ox, object[i]._oy); + else + PlaySfxLoc(IS_BARLFIRE, object[i]._ox, object[i]._oy); + for (y = object[i]._oy-1; y <= object[i]._oy+1; ++y) { + for (x = object[i]._ox-1; x <= object[i]._ox+1; ++x) { + if (dMonster[x][y] > 0) MonsterTrapHit(dMonster[x][y]-1, 1, 4, 0, MIMT_FIRE, 0); + if (dPlayer[x][y] > 0) PlayerMHit(dPlayer[x][y]-1, -1, 0, 8, 16, MIMT_FIRE, 0, FALSE, &foo); + if (dObject[x][y] > 0) { + oi = dObject[x][y] - 1; + if ((object[oi]._otype == OBJ_BARRELEX) && (object[oi]._oBreak != OBJ_BROKEN)) + BreakBarrel(pnum, oi, dam, TRUE, sendmsg); + } + } + } + } else { + if (currlevel >= CRYPTSTART && currlevel <= CRYPTEND) + PlaySfxLoc(IS_URN, object[i]._ox, object[i]._oy); + else if (currlevel >= HIVESTART && currlevel <= HIVEEND) + PlaySfxLoc(IS_POD, object[i]._ox, object[i]._oy); + else + PlaySfxLoc(IS_BARREL, object[i]._ox, object[i]._oy); + SetRndSeed(object[i]._oRndSeed); +#if CHEATS + if (uniqcheat) + RndUnique(object[i]._ox, object[i]._oy, currlevel); + else +#endif + if (object[i]._oVar2 <= 1) { + if (!object[i]._oVar3) CreateRndUseful(pnum, object[i]._ox, object[i]._oy, sendmsg); + else CreateRndItem(object[i]._ox, object[i]._oy, FALSE, sendmsg, FALSE); + } + if (object[i]._oVar2 >= 8) SpawnSkeleton(object[i]._oVar4, object[i]._ox, object[i]._oy); + } + + + if (pnum == myplr) NetSendCmdParam2(FALSE,CMD_BREAKOBJ,pnum,i); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void BreakObject(int pnum, int oi) +{ + int objdam, mind, maxd; + + if (pnum != -1) { + mind = plr[pnum]._pIMinDam; + maxd = plr[pnum]._pIMaxDam; + objdam = random(163,maxd - mind + 1) + mind; + objdam += (objdam * plr[pnum]._pIBonusDam) / 100; + objdam += plr[pnum]._pIBonusDamMod + plr[pnum]._pDamageMod; + } else objdam = 10; + + app_assert((DWORD)oi < MAXOBJECTS); + switch (object[oi]._otype) { + case OBJ_CRUX1 : + case OBJ_CRUX2 : + case OBJ_CRUX3 : + BreakCrux(oi); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + BreakBarrel(pnum, oi, objdam, FALSE, TRUE); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncBreakObj(int pnum, int oi) +{ + app_assert((DWORD)oi < MAXOBJECTS); + switch (object[oi]._otype) { + case OBJ_BARREL: + case OBJ_BARRELEX: + BreakBarrel(pnum, oi, 0, TRUE, FALSE); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncL1Doors(int i) +{ + int dx, dy; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar4 == DOOR_CLOSED) { + object[i]._oMissFlag = FALSE; + return; + } else object[i]._oMissFlag = TRUE; + dx = object[i]._ox; + dy = object[i]._oy; + object[i]._oSelFlag = OSEL_TOP; + if (currlevel < HIVESTART) + { + if (object[i]._otype == OBJ_L1DOORL) { + if (object[i]._oVar1 == 214) ObjSetMicro(dx,dy,408); //Blood + else ObjSetMicro(dx,dy,393); + dSpecial[dx][dy] = 7; + ObjSetMicro12(dx-1,dy); + --dy; + } else { + ObjSetMicro(dx,dy,395); + if (currlevel < HIVESTART) + dSpecial[dx][dy] = 8; + ObjSetMicro12(dx,dy-1); + --dx; + } + } + else + { + if (object[i]._otype == OBJ_L1DOORL) { + ObjSetMicro(dx,dy,206); + dSpecial[dx][dy] = 1; + ObjSetMicro12(dx-1,dy); + --dy; + } else { + ObjSetMicro(dx,dy,209); + dSpecial[dx][dy] = 2; + ObjSetMicro12(dx,dy-1); + --dx; + } + } + + DoorSet(i, dx, dy); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncCrux(int i) +{ + int j, ot, oi; + bool mapflag; + + mapflag = TRUE; + for (j = 0; j < numobjects; ++j) { + oi = objectactive[j]; + app_assert((DWORD)oi < MAXOBJECTS); + ot = object[oi]._otype; + if ((ot == OBJ_CRUX1) || (ot == OBJ_CRUX2) || (ot == OBJ_CRUX3)) { + if (object[i]._oVar8 == object[oi]._oVar8) { + if (object[oi]._oBreak != OBJ_BROKEN) mapflag = FALSE; + } + } + } + + if (mapflag) ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncLever(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oSelFlag == OSEL_NONE) { + ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncQSTLever(int i) +{ + int tren; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oAnimFrame == object[i]._oVar6) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + if (object[i]._otype == OBJ_BLINDBOOK) { + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + TransVal = tren; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncPedistal(int i) +{ + byte *setp; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar6 == 1) { + ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + } + if (object[i]._oVar6 == 2) { + ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7); + ObjChangeMapResync(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7); + } + if (object[i]._oVar6 == 3) { + ObjChangeMapResync(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); + setp = LoadFileInMemSig("Levels\\L2Data\\Blood2.DUN", NULL, 'STPC'); + LoadMapObjs(setp, (setpc_x << 1), (setpc_y << 1)); + DiabloFreePtr(setp); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncL2Doors(int i) +{ + int dx, dy; + + app_assert((DWORD)i < MAXOBJECTS); + if (object[i]._oVar4 == DOOR_CLOSED) object[i]._oMissFlag = FALSE; + else object[i]._oMissFlag = TRUE; + dx = object[i]._ox; + dy = object[i]._oy; + object[i]._oSelFlag = OSEL_TOP; + + //Fix doors upon returning to level or loading level + if ((object[i]._otype == OBJ_L2DOORL) && + (object[i]._oVar4 == DOOR_CLOSED)) { + ObjSetMicro(dx,dy,538); + } else if ((object[i]._otype == OBJ_L2DOORL) && + ((object[i]._oVar4 == DOOR_OPEN) || + (object[i]._oVar4 == DOOR_BLOCKED))) { + ObjSetMicro(dx,dy,13); + } else if ((object[i]._otype == OBJ_L2DOORR) && + (object[i]._oVar4 == DOOR_CLOSED)) { + ObjSetMicro(dx,dy,540); + } else if ((object[i]._otype == OBJ_L2DOORR) && + ((object[i]._oVar4 == DOOR_OPEN) || + (object[i]._oVar4 == DOOR_BLOCKED))) { + ObjSetMicro(dx,dy,17); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +static void SyncL3Doors(int i) +{ + int dx, dy; + + app_assert((DWORD)i < MAXOBJECTS); + object[i]._oMissFlag = TRUE; + dx = object[i]._ox; + dy = object[i]._oy; + object[i]._oSelFlag = OSEL_TOP; + + //Fix doors upon returning to level or loading level + if ((object[i]._otype == OBJ_L3DOORL) && + (object[i]._oVar4 == DOOR_CLOSED)) { + ObjSetMicro(dx,dy,531); + } else if ((object[i]._otype == OBJ_L3DOORL) && + ((object[i]._oVar4 == DOOR_OPEN) || + (object[i]._oVar4 == DOOR_BLOCKED))) { + ObjSetMicro(dx,dy,538); + } else if ((object[i]._otype == OBJ_L3DOORR) && + (object[i]._oVar4 == DOOR_CLOSED)) { + ObjSetMicro(dx,dy,534); + } else if ((object[i]._otype == OBJ_L3DOORR) && + ((object[i]._oVar4 == DOOR_OPEN) || + (object[i]._oVar4 == DOOR_BLOCKED))) { + ObjSetMicro(dx,dy,541); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncObjectAnim(int o) +{ + int ai, ot, j; + + app_assert((DWORD)o < MAXOBJECTS); + ot = object[o]._otype; + ai = AllObjects[ot].ofindex; + for (j = 0; ObjFileList[j] != ai; ++j); + object[o]._oAnimData = pObjCels[j]; + + switch (object[o]._otype) { + case OBJ_L1DOORL : + case OBJ_L1DOORR : + SyncL1Doors(o); + break; + case OBJ_L2DOORL : + case OBJ_L2DOORR : + SyncL2Doors(o); + break; + case OBJ_L3DOORL : + case OBJ_L3DOORR : + SyncL3Doors(o); + break; + case OBJ_CRUX1 : + case OBJ_CRUX2 : + case OBJ_CRUX3 : + SyncCrux(o); + break; + case OBJ_SWITCHSKL: + case OBJ_LEVER : + case OBJ_BOOK2L: + SyncLever(o); + break; + case OBJ_BLINDBOOK: + case OBJ_STEELTOME: + case OBJ_BOOK2R: + SyncQSTLever(o); + break; + case OBJ_PEDISTAL: + SyncPedistal(o); + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetObjectStr(int i) +{ + app_assert((DWORD)i < MAXOBJECTS); + switch (object[i]._otype) { + case OBJ_CRUX1 : + case OBJ_CRUX2 : + case OBJ_CRUX3 : + strcpy(infostr, "Crucified Skeleton"); + break; + case OBJ_LEVER : + case OBJ_FLAMELVR: + strcpy(infostr, "Lever"); + break; + case OBJ_L1DOORL : + case OBJ_L1DOORR : + case OBJ_L2DOORL : + case OBJ_L2DOORR : + case OBJ_L3DOORL : + case OBJ_L3DOORR : + if (object[i]._oVar4 == DOOR_OPEN) strcpy(infostr, "Open Door"); + if (object[i]._oVar4 == DOOR_CLOSED) strcpy(infostr, "Closed Door"); + if (object[i]._oVar4 == DOOR_BLOCKED) strcpy(infostr, "Blocked Door"); + break; + case OBJ_BOOK2L: + if (setlevel) { + if (setlvlnum == SL_BONECHAMB) + strcpy(infostr, "Ancient Tome"); + else if (setlvlnum == SL_VILEBETRAYER) + strcpy(infostr, "Book of Vileness"); + } + break; + case OBJ_SWITCHSKL: + strcpy(infostr, "Skull Lever"); + break; +// case OBJ_BOOKLVR: +// strcpy(infostr, "Tome"); +// break; + case OBJ_BOOK2R: + strcpy(infostr, "Mythical Book"); + break; + case OBJ_CHEST1: + case OBJ_TCHEST1: + strcpy(infostr, "Small Chest"); + break; + case OBJ_CHEST2: + case OBJ_TCHEST2: + strcpy(infostr, "Chest"); + break; + case OBJ_CHEST3: + case OBJ_TCHEST3: + case OBJ_SIGNCHEST: + strcpy(infostr, "Large Chest"); + break; + case OBJ_SARC: + strcpy(infostr, "Sarcophagus"); + break; + case OBJ_BOOKSHELF: + strcpy(infostr, "Bookshelf"); + break; + case OBJ_BOOKCASEL: + case OBJ_BOOKCASER: + strcpy(infostr, "Bookcase"); + break; + case OBJ_BARREL: + case OBJ_BARRELEX: + if (currlevel >= HIVESTART && currlevel <= HIVEEND) + strcpy(infostr, "Pod"); + else if (currlevel >= CRYPTSTART && currlevel <= CRYPTEND) + strcpy(infostr, "Urn"); + else + strcpy(infostr, "Barrel"); + break; + case OBJ_SHRINEL: + case OBJ_SHRINER: + sprintf(tempstr, "%s Shrine", shrinestrs[object[i]._oVar1]); + strcpy(infostr, tempstr); + break; + case OBJ_SKELBOOK: + strcpy(infostr, "Skeleton Tome"); + break; + case OBJ_BOOKSTAND: + strcpy(infostr, "Library Book"); + break; + case OBJ_BLOODFTN: + strcpy(infostr, "Blood Fountain"); + break; + case OBJ_DECAP: + strcpy(infostr, "Decapitated Body"); + break; + case OBJ_BLINDBOOK: + strcpy(infostr, "Book of the Blind"); + break; + case OBJ_STEELTOME: + strcpy(infostr, "Steel Tome"); + break; + case OBJ_BLOODBOOK: + strcpy(infostr, "Book of Blood"); + break; + case OBJ_PURIFYINGFTN: + strcpy(infostr, "Purifying Spring"); + break; + case OBJ_ARMORSTAND: + case OBJ_WARARMOR: + strcpy(infostr, "Armor"); + break; + case OBJ_WARWEAP: + strcpy(infostr, "Weapon Rack"); + break; + case OBJ_GOATSHRINE: + strcpy(infostr, "Goat Shrine"); + break; + case OBJ_CAULDRON: + strcpy(infostr, "Cauldron"); + break; + case OBJ_MURKYFTN: + strcpy(infostr, "Murky Pool"); + break; + case OBJ_TEARFTN: + strcpy(infostr, "Fountain of Tears"); + break; + case OBJ_PEDISTAL: + strcpy(infostr, "Pedestal of Blood"); + break; + case OBJ_STORYBOOK: + strcpy(infostr, StoryBookName[object[i]._oVar3]); + break; + case OBJ_WEAPONRACK: + strcpy(infostr, "Weapon Rack"); + break; + case OBJ_MUSHPATCH: + strcpy(infostr, "Mushroom Patch"); + break; + case OBJ_LAZSTAND: + strcpy(infostr, "Vile Stand"); + break; + case OBJ_SLAINHERO: + strcpy(infostr, "Slain Hero"); + break; + } + if ((plr[myplr]._pClass == CLASS_ROGUE) && (object[i]._oTrapFlag)) { + sprintf(tempstr, "Trapped %s", infostr); + strcpy(infostr, tempstr); + infoclr = ICOLOR_RED; + } +} + +static void SpellBook (int number, int locx, int locy) +{ + AddSkulkenObject(OBJ_STORYBOOK, number, locx, locy); + + +} + +static void AddNa_Krul_Stuff() +{ + int spell; + + AddNaKrulLeverObj(); + + spell = random(0, 6); + switch (spell) + { + case 0: + SpellBook(6, Na_Krul.x + 3, Na_Krul.y); + SpellBook(7, Na_Krul.x + 2, Na_Krul.y - 3); + SpellBook(8, Na_Krul.x + 2, Na_Krul.y + 2); + break; + case 1: + SpellBook(6, Na_Krul.x + 3, Na_Krul.y); + SpellBook(8, Na_Krul.x + 2, Na_Krul.y - 3); + SpellBook(7, Na_Krul.x + 2, Na_Krul.y + 2); + break; + case 2: + SpellBook(7, Na_Krul.x + 3, Na_Krul.y); + SpellBook(6, Na_Krul.x + 2, Na_Krul.y - 3); + SpellBook(8, Na_Krul.x + 2, Na_Krul.y + 2); + break; + case 3: + SpellBook(7, Na_Krul.x + 3, Na_Krul.y); + SpellBook(8, Na_Krul.x + 2, Na_Krul.y - 3); + SpellBook(6, Na_Krul.x + 2, Na_Krul.y + 2); + break; + case 4: + SpellBook(8, Na_Krul.x + 3, Na_Krul.y); + SpellBook(7, Na_Krul.x + 2, Na_Krul.y - 3); + SpellBook(6, Na_Krul.x + 2, Na_Krul.y + 2); + break; + case 5: + SpellBook(8, Na_Krul.x + 3, Na_Krul.y); + SpellBook(6, Na_Krul.x + 2, Na_Krul.y - 3); + SpellBook(7, Na_Krul.x + 2, Na_Krul.y + 2); + break; + } + + +} + +static bool HCheckSpell(int number) +{ + + switch (number) + { + case 6: + SpellProgress = 1; + break; + case 7: + if (SpellProgress == 1) + SpellProgress = 2; + else + SpellProgress = 0; + break; + case 8: + if (SpellProgress == 2) + { +// qtextflag = FALSE; +// stream_stop(); + return true; + } + else + SpellProgress = 0; + } + return false; +} + + +void OpenNaKrul() +{ + if (currlevel == NA_KRUL_LEVEL) + { + PlaySfxLoc(CR_DOOROPEN, Na_Krul.x, Na_Krul.y); + dPiece[Na_Krul.x][Na_Krul.y] = 298; + dPiece[Na_Krul.x][Na_Krul.y - 1] = 301; + dPiece[Na_Krul.x][Na_Krul.y - 2] = 300; + dPiece[Na_Krul.x][Na_Krul.y + 1] = 299; + + SetDungeonMicros(); + } +} + +void OpenNaKrul2() +{ + dPiece[Na_Krul.x][Na_Krul.y] = 298; + dPiece[Na_Krul.x][Na_Krul.y - 1] = 301; + dPiece[Na_Krul.x][Na_Krul.y - 2] = 300; + dPiece[Na_Krul.x][Na_Krul.y + 1] = 299; + + SetDungeonMicros(); +} + +static void AddNaKrulLeverObj() +{ + int xp, yp; + while (1) { + xp = random(141,80) + DIRTEDGED2; + yp = random(141,80) + DIRTEDGED2; + if (! RndLocOk(xp-1, yp-1)) continue; + if (! RndLocOk(xp+0, yp-1)) continue; + if (! RndLocOk(xp+1, yp-1)) continue; + if (! RndLocOk(xp-1, yp+0)) continue; + if (! RndLocOk(xp+0, yp+0)) continue; + if (! RndLocOk(xp+1, yp+0)) continue; + if (! RndLocOk(xp-1, yp+1)) continue; + if (! RndLocOk(xp+0, yp+1)) continue; + if (! RndLocOk(xp+1, yp+1)) continue; + break; + } + + // temp test + xp = Na_Krul.x + 3; + yp = Na_Krul.y - 1; + + Na_Krul.LeverX = xp; + Na_Krul.LeverY = yp; + AddObject(OBJ_LEVER, xp, yp); +} + diff --git a/OBJECTS.H b/OBJECTS.H new file mode 100644 index 0000000..55bd8cb --- /dev/null +++ b/OBJECTS.H @@ -0,0 +1,152 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/OBJECTS.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXOBJECTS 127 + +#define MAXLVLOBJS 40 + +#define OBJ_NOBREAK 0 +#define OBJ_BREAKABLE 1 +#define OBJ_BROKEN -1 + +#define OSEL_NONE 0 +#define OSEL_FLR 1 +#define OSEL_TOP 2 +#define OSEL_ALL 3 + +#define OBJRND 0 +#define OBJMUST 1 +#define OBJNO 2 +#define OBJTHEME 3 + +#define OBJNOWARP 0 +#define OBJWARP1 1 +#define OBJWARP2 2 +#define OBJWARP3 3 +#define OBJDONEWARP 4 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + char oload; // Loading a must, rnd, or can't + char ofindex; // Filename index + char ominlvl; // Min level for object + char omaxlvl; // Max level for object + char olvltype; // Level type for set levels + char otheme; // Theme type + char oquest; // Quest related? + BOOL oAnimFlag; // Animates? + int oAnimDelay; // Anim Delay + int oAnimLen; // if Animates then Length of animation, else initial frame + long oAnimWidth; // Width of cels + BOOL oSolidFlag; // Can I stand on square with object? + BOOL oMissFlag; // Can I shoot missiles through this object? + BOOL oLightFlag; // Draw with lighting? + char oBreak; // Breakable + char oSelFlag; // Selectable object? + BOOL oTrapFlag; // Object trapable? +} ObjDataStruct; + +typedef struct { + int _otype; // object type + int _ox; // object map x + int _oy; // object map y + BOOL _oLight; // Light source drawn? + BOOL _oAnimFlag; // Animate at all? + BYTE *_oAnimData; // Data pointer to anim tables + int _oAnimDelay; // anim delay amount + int _oAnimCnt; // current anim delay value + int _oAnimLen; // number of anim frames + int _oAnimFrame; // current anim frame + long _oAnimWidth; // width of object + long _oAnimWidth2; // (width - 64) / 2 of object for drawing + BOOL _oDelFlag; // Delete this object? + char _oBreak; // Breakable + BOOL _oSolidFlag; // Can I stand on square with object? + BOOL _oMissFlag; // Can I shoot missiles through this object? + char _oSelFlag; // Selectable object? + BOOL _oPreFlag; // Draw behind player? + BOOL _oTrapFlag; // Am I trapped? + BOOL _oDoorFlag; // Am I a door? + int _olid; // Light id + int _oRndSeed; // random seed + long _oVar1; // scratch var 1 + long _oVar2; // scratch var 2 + long _oVar3; // scratch var 3 + long _oVar4; // scratch var 4 + long _oVar5; // scratch var 5 + long _oVar6; // scratch var 6 + long _oVar7; // scratch var 7 + long _oVar8; // scratch var 8 +} ObjectStruct; + +#define SAVE_OBJECT_SIZE sizeof(ObjectStruct) + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +extern ObjectStruct object[MAXOBJECTS]; +extern long numobjects; +extern int objectactive[MAXOBJECTS]; +extern int objectavail[MAXOBJECTS]; +extern BOOL InitObjFlag; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitObjectGFX(); +void FreeObjectGFX(); +void InitObjects(); +void SetMapObjects(BYTE *, int, int); +void ProcessObjects(); +void AddObject(int, int, int); + +void SyncObjectAnim(int); + +void BreakObject(int, int); +void SyncBreakObj(int, int); + +void MonstCheckDoors(int); + +void OperateObject(int, int, BOOL); +void SyncOpObject(int, int, int); +void TryDisarm(int, int); + +void ClrAllObjects (); + +void GetObjectStr(int); + +void ObjSetMicro(int, int, int); +void ObjSetMini(int, int, int); + +void AddL1Objs(int, int, int, int); +void AddL2Objs(int, int, int, int); + +void ObjL1Special(int, int, int, int); +void ObjL2Special(int, int, int, int); + +void AddLeverObj(int, int, int, int, int, int, int, int); +void AddBookLever(int, int, int, int, int, int, int, int, int); + +void SetObjMapRange(int, int, int, int, int, int); +void SetBookMsg(int, int); +void ObjChangeMap(int, int ,int, int); +void ObjChangeMapResync(int, int ,int, int); + +int ItemMiscIdIdx(int /* imiscid */); + diff --git a/PACKPLR.CPP b/PACKPLR.CPP new file mode 100644 index 0000000..337ab04 --- /dev/null +++ b/PACKPLR.CPP @@ -0,0 +1,302 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/PACKPLR.CPP 3 2/13/97 5:00p Dbrevik2 $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "msg.h" +#include "multi.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "spells.h" +#include "packplr.h" +#include "stores.h" +#include "engine.h" + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define INVALID_ITEM 0xffff + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void PackItem(PkItemStruct *id, const ItemStruct *is) { + if (is->_itype == -1) { + id->idx = INVALID_ITEM; + } + else { + id->idx = is->IDidx; + if (is->IDidx == IDI_EAR) { + id->iCreateInfo = (is->_iName[7] << 8) | is->_iName[8]; + id->iSeed = (is->_iName[9] << 24) | + (is->_iName[10] << 16) | + (is->_iName[11] << 8) | + is->_iName[12]; + id->bId = is->_iName[13]; + id->bDur = is->_iName[14]; + id->bMDur = is->_iName[15]; + id->bCh = is->_iName[16]; + id->bMCh = is->_iName[17]; + id->wValue = (is->_iName[18] << 8) | ((is->_iCurs - ITEM_EAR1) << 6) | is->_ivalue; + id->dwBuff = (is->_iName[19] << 24) | + (is->_iName[20] << 16) | + (is->_iName[21] << 8) | + is->_iName[22]; + } else { + id->iSeed = is->_iSeed; + id->iCreateInfo = is->_iCreateInfo; + id->bId = is->_iIdentified + (is->_iMagical << 1); + id->bDur = is->_iDurability; + id->bMDur = is->_iMaxDur; + id->bCh = is->_iCharges; + id->bMCh = is->_iMaxCharges; + if (is->IDidx == IDI_GOLD) id->wValue = is->_ivalue; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void PackPlayer(PkPlayerStruct * pPack, int pnum) { + ZeroMemory(pPack,sizeof PkPlayerStruct); + + int i; + PkItemStruct * pki; + const ItemStruct * pi; + const PlayerStruct * pPlayer = &plr[pnum]; + + pPack->destAction = pPlayer->destAction; + pPack->destParam1 = pPlayer->destParam1; + pPack->destParam2 = pPlayer->destParam2; + pPack->plrlevel = pPlayer->plrlevel; + pPack->px = pPlayer->_px; + pPack->py = pPlayer->_py; + pPack->targx = pPlayer->_ptargx; + pPack->targy = pPlayer->_ptargy; + + strcpy(pPack->pName,pPlayer->_pName); + pPack->pClass = pPlayer->_pClass; + + pPack->pBaseStr = pPlayer->_pBaseStr; + pPack->pBaseMag = pPlayer->_pBaseMag; + pPack->pBaseDex = pPlayer->_pBaseDex; + pPack->pBaseVit = pPlayer->_pBaseVit; + pPack->pLevel = pPlayer->_pLevel; + pPack->pStatPts = pPlayer->_pStatPts; + + pPack->pExperience = pPlayer->_pExperience; + pPack->pGold = pPlayer->_pGold; + + pPack->pHPBase = pPlayer->_pHPBase; + pPack->pMaxHPBase = pPlayer->_pMaxHPBase; + pPack->pManaBase = pPlayer->_pManaBase; + pPack->pMaxManaBase = pPlayer->_pMaxManaBase; + + pPack->pMemSpells = pPlayer->_pMemSpells; + +// hack hack hack; will have to fix later --donald + for (i = 0; i <= SPL_BONESPIRIT; i++) + pPack->pSplLvl[i] = pPlayer->_pSplLvl[i]; + unsigned char *p = (unsigned char *) ((void *) &(pPack->wReserved3)); + for (i = SPL_MANA; i < SPL_RUNEOFFIRE; i++) + { + p[i - SPL_MANA] = pPlayer->_pSplLvl[i]; + } + + pki = &pPack->InvBody[0]; + pi = &pPlayer->InvBody[0]; + for (i = NUM_INVLOC; i--; pki++,pi++) + PackItem(pki,pi); + + pki = &pPack->InvList[0]; + pi = &pPlayer->InvList[0]; + for (i = MAXINV; i--; pki++,pi++) + PackItem(pki,pi); + for (i = 0; i < MAXINV; i++) + pPack->InvGrid[i] = pPlayer->InvGrid[i]; + pPack->_pNumInv = pPlayer->_pNumInv; + + pki = &pPack->SpdList[0]; + pi = &pPlayer->SpdList[0]; + for (i = MAXSPD; i--; pki++,pi++) + PackItem(pki,pi); + + pPack->_pReflectCount = pPlayer->_pReflectCount; + pPack->pDiabloKillLevel = pPlayer->pDiabloKillLevel; + pPack->_gnDifficulty = pPlayer->_gnDifficulty; + pPack->_pIFlags2 = pPlayer->_pIFlags2; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void UnPackItem(const PkItemStruct *is, ItemStruct *id) { + if (is->idx == INVALID_ITEM) { + id->_itype = -1; + } + else { + if (is->idx == IDI_EAR) { + RecreateEar(TEMPAVAIL, + is->iCreateInfo, + is->iSeed, + is->bId, + is->bDur, + is->bMDur, + is->bCh, + is->bMCh, + is->wValue, + is->dwBuff); + } else { + RecreateItem(TEMPAVAIL, is->idx, is->iCreateInfo, is->iSeed, is->wValue); + item[TEMPAVAIL]._iMagical = is->bId >> 1; + item[TEMPAVAIL]._iIdentified = is->bId & 1; + item[TEMPAVAIL]._iDurability = is->bDur; + item[TEMPAVAIL]._iMaxDur = is->bMDur; + item[TEMPAVAIL]._iCharges = is->bCh; + item[TEMPAVAIL]._iMaxCharges = is->bMCh; + } + *id = item[TEMPAVAIL]; + } +} + +// drb.patch1.start.2/13/97 +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void VerifyGoldSeeds(PlayerStruct * pPlayer) +{ + int i, j; + + for (i = 0; i < pPlayer->_pNumInv; i++) { + if (pPlayer->InvList[i].IDidx == IDI_GOLD) { + for (j = 0; j < pPlayer->_pNumInv; j++) { + if ((i != j) && (pPlayer->InvList[j].IDidx == IDI_GOLD) && + (pPlayer->InvList[i]._iSeed == pPlayer->InvList[j]._iSeed)) { + + pPlayer->InvList[i]._iSeed = GetRndSeed(); + j = -1; + } + } + } + } +} +// drb.patch1.end.2/13/97 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void UnPackPlayer(const PkPlayerStruct *pPack, int pnum, BOOL killok) { + ItemStruct * pi; + const PkItemStruct * pki; + PlayerStruct * pPlayer = &plr[pnum]; + + void PlrInitReserved(PlayerStruct * p); + PlrInitReserved(pPlayer); + + // position player + pPlayer->_px = pPack->px; + pPlayer->_py = pPack->py; + pPlayer->_pfutx = pPack->px; + pPlayer->_pfuty = pPack->py; + pPlayer->_ptargx = pPack->targx; + pPlayer->_ptargy = pPack->targy; + pPlayer->plrlevel = pPack->plrlevel; + + // reset command to NOTHING + ClrPlrPath(pnum); + pPlayer->destAction = PCMD_NOTHING; + + strcpy(pPlayer->_pName,pPack->pName); + pPlayer->_pClass = pPack->pClass; + + InitPlayer(pnum,TRUE); + + pPlayer->_pBaseStr = pPack->pBaseStr; + pPlayer->_pStrength = pPack->pBaseStr; + pPlayer->_pBaseMag = pPack->pBaseMag; + pPlayer->_pMagic = pPack->pBaseMag; + pPlayer->_pBaseDex = pPack->pBaseDex; + pPlayer->_pDexterity = pPack->pBaseDex; + pPlayer->_pBaseVit = pPack->pBaseVit; + pPlayer->_pVitality = pPack->pBaseVit; + pPlayer->_pLevel = pPack->pLevel; + pPlayer->_pStatPts = pPack->pStatPts; + + pPlayer->_pExperience = pPack->pExperience; + pPlayer->_pGold = pPack->pGold; + + pPlayer->_pMaxHPBase = pPack->pMaxHPBase; + pPlayer->_pHPBase = pPack->pHPBase; + if (!killok && ((pPlayer->_pHPBase >> HP_SHIFT) < 1)) pPlayer->_pHPBase = 1 << HP_SHIFT; + pPlayer->_pMaxManaBase = pPack->pMaxManaBase; + pPlayer->_pManaBase = pPack->pManaBase; + + pPlayer->_pMemSpells = pPack->pMemSpells; + +// hack hack hack -- donald + + for (int i = 0; i <= SPL_BONESPIRIT; i++) + pPlayer->_pSplLvl[i] = pPack->pSplLvl[i]; + + unsigned char *p = (unsigned char *) ((void *)&(pPack->wReserved3)); + for (i = SPL_MANA; i < SPL_RUNEOFFIRE; i++) + { + pPlayer->_pSplLvl[i] = p[i - SPL_MANA]; + } + +// end hack -- donald + + pki = &pPack->InvBody[0]; + pi = &pPlayer->InvBody[0]; + for (i = NUM_INVLOC; i--; pki++,pi++) + UnPackItem(pki,pi); + + pki = &pPack->InvList[0]; + pi = &pPlayer->InvList[0]; + for (i = MAXINV; i--; pki++,pi++) + UnPackItem(pki,pi); + for (i = 0; i < MAXINV; i++) + pPlayer->InvGrid[i] = pPack->InvGrid[i]; + pPlayer->_pNumInv = pPack->_pNumInv; + // drb.patch1.start.2/13/97 + VerifyGoldSeeds(pPlayer); + // drb.patch1.end.2/13/97 + + pki = &pPack->SpdList[0]; + pi = &pPlayer->SpdList[0]; + for (i = MAXSPD; i--; pki++,pi++) + UnPackItem(pki,pi); + + // this is a fix below for witch store items - rjs + if (pnum == myplr) + for (i = 0; i < MAXWITCHITEMS; i++) witchitem[i]._itype = -1; + + CalcPlrInv(pnum, FALSE); + + pPlayer->_pReflectCount = pPack->_pReflectCount; + pPlayer->pTownWarps = 0; + pPlayer->pDungMsgs = 0; + pPlayer->pHellfireMsgs = 0; + pPlayer->pLvlLoad = 0; + pPlayer->pDiabloKillLevel = pPack->pDiabloKillLevel; + pPlayer->_gnDifficulty = pPack->_gnDifficulty; + pPlayer->_pIFlags2 = pPack->_pIFlags2; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void PackClearCheater(PkPlayerStruct *pPack) { + pPack->pGold = 0; + FillMemory(pPack->InvBody,sizeof pPack->InvBody,0xff); + FillMemory(pPack->InvList,sizeof pPack->InvList,0xff); + FillMemory(pPack->InvGrid,sizeof pPack->InvGrid,0); + pPack->_pNumInv = 0; + FillMemory(pPack->SpdList,sizeof pPack->SpdList,0xff); +} diff --git a/PACKPLR.H b/PACKPLR.H new file mode 100644 index 0000000..2378b10 --- /dev/null +++ b/PACKPLR.H @@ -0,0 +1,109 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1996 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/PACKPLR.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Packed structures +**-----------------------------------------------------------------------*/ + +#pragma pack(push,1) +typedef struct { + int iSeed; + WORD iCreateInfo; + WORD idx; + BYTE bId; + BYTE bDur; + BYTE bMDur; + BYTE bCh; + BYTE bMCh; + WORD wValue; + DWORD dwBuff; +} PkItemStruct; + +typedef struct { + FILETIME archiveTime; + BYTE destAction; + BYTE destParam1; + BYTE destParam2; + BYTE plrlevel; + BYTE px; + BYTE py; + BYTE targx; + BYTE targy; + + // Player attributes + char pName[PLR_NAME_LEN]; + BYTE pClass; + + BYTE pBaseStr; + BYTE pBaseMag; + BYTE pBaseDex; + BYTE pBaseVit; + BYTE pLevel; + BYTE pStatPts; + + long pExperience; + long pGold; + + long pHPBase; + long pMaxHPBase; + long pManaBase; + long pMaxManaBase; + + // hack hack hack --donald + BYTE pSplLvl[SPL_BONESPIRIT+1]; + __int64 pMemSpells; + + PkItemStruct InvBody[NUM_INVLOC]; + PkItemStruct InvList[MAXINV]; + char InvGrid[MAXINV]; + BYTE _pNumInv; + PkItemStruct SpdList[MAXSPD]; + + // these fields are to be used if more variables need to be added + // to the player structure so that the size won't change... + BYTE bReserved1; + BYTE bReserved2; + BYTE bReserved3; + BYTE bReserved4; + BYTE bReserved5; + BYTE bReserved6; + BYTE bReserved7; + BYTE bReserved8; + + WORD _pReflectCount; + WORD wReserved2; + WORD wReserved3; // + WORD wReserved4; // + WORD wReserved5; // wReserved3-8 are used for spell slots... + WORD wReserved6; // + WORD wReserved7; // + WORD wReserved8; // + + DWORD pDiabloKillLevel; // player killed Diablo at what level + DWORD _gnDifficulty; + DWORD _pIFlags2; + DWORD dwReserved4; + DWORD dwReserved5; + DWORD dwReserved6; + DWORD dwReserved7; + DWORD dwReserved8; + +} PkPlayerStruct; +#pragma pack(pop) + + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void PackPlayer(PkPlayerStruct *p, int pnum); +void UnPackPlayer(const PkPlayerStruct *p, int pnum, BOOL killok); + +void PackItem(PkItemStruct *id, const ItemStruct *is); +void UnPackItem(const PkItemStruct *is, ItemStruct *id); diff --git a/PALETTE.CPP b/PALETTE.CPP new file mode 100644 index 0000000..b79f35d --- /dev/null +++ b/PALETTE.CPP @@ -0,0 +1,424 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Palette file +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/PALETTE.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "palette.h" +#include "engine.h" +#include +#include "resource.h" + + +/*-----------------------------------------------------------------------** +** extern +**-----------------------------------------------------------------------*/ +extern char gszProgKey[]; +void ErrorDlg(int nDlgId,DWORD dwErr,const char * pszFile,int nLine); + + +/*-----------------------------------------------------------------------** +** File Variables +**-----------------------------------------------------------------------*/ +static LONG sglGamma = lGAMMA_MAX; +static int sgnStaticColors2 = 0; +static PALETTEENTRY sgLoad[256]; // original loaded palette -- used as reference + // for gamma conversion +static PALETTEENTRY sgBase[256]; // palettized version of sgLoad +static PALETTEENTRY sgCurr[256]; // palette to be displayed -- includes rotations + +static const char sgszGamma[] = "Gamma Correction"; +static BYTE sgbFadedIn = TRUE; + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void SetPaletteEntries() { + if (! lpDDPal) return; + + int nStart; + int nColors; + if (! fullscreen) { + nStart = sgnStaticColors2; + nColors = 256 - sgnStaticColors2*2; + } + else { + nStart = 0; + nColors = 256; + } + +// HRESULT ddrval = lpDDPal->SetEntries(0,nStart,nColors,&sgCurr[nStart]); +// ddraw_assert(ddrval); + SDrawUpdatePalette(nStart,nColors,&sgCurr[nStart]); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void GammaPalette(PALETTEENTRY * pDst, const PALETTEENTRY * pSrc, int nNum) { + double gamma = sglGamma / 100.0; + for(int i = 0; i < nNum; i++,pDst++,pSrc++) { + pDst->peRed = (BYTE)(256.0*pow(((double)pSrc->peRed)/256.0, gamma)); + pDst->peGreen = (BYTE)(256.0*pow(((double)pSrc->peGreen)/256.0, gamma)); + pDst->peBlue = (BYTE)(256.0*pow(((double)pSrc->peBlue)/256.0, gamma)); + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void SavePaletteSettings() { + SRegSaveValue(gszProgKey,sgszGamma,0,sglGamma); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void GetPaletteSettings() { + DWORD dwTemp = (DWORD) sglGamma; + if (! SRegLoadValue(gszProgKey,sgszGamma,0,&dwTemp)) + dwTemp = lGAMMA_MAX; + + sglGamma = (LONG) dwTemp; + if (sglGamma < lGAMMA_MIN) + sglGamma = lGAMMA_MIN; + else if (sglGamma > lGAMMA_MAX) + sglGamma = lGAMMA_MAX; + sglGamma -= sglGamma % lGAMMA_STEP; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void FixWindowsPal() { + int i; + + // reserve all colors so no mapping occurs + for (i = 0; i < 256; i++) + sgCurr[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED; + + if (fullscreen) return; + + // get static color count + HDC hDC = GetDC(NULL); + sgnStaticColors2 = GetDeviceCaps(hDC, NUMRESERVED) / 2; + + // get the lower windows color set + GetSystemPaletteEntries(hDC, 0, sgnStaticColors2, &sgCurr[0]); + for (i = 0; i < sgnStaticColors2; i++) sgCurr[i].peFlags = 0; + + // get the upper windows color set + i = 256 - sgnStaticColors2; + GetSystemPaletteEntries(hDC, i, sgnStaticColors2, &sgCurr[i]); + for ( ; i < 256; i++) sgCurr[i].peFlags = 0; + + ReleaseDC(NULL, hDC); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void CreatePalette() { + GetPaletteSettings(); + CopyMemory(sgCurr,sgLoad,sizeof(sgCurr)); + FixWindowsPal(); + HRESULT ddrval = lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE,sgCurr,&lpDDPal,NULL); + if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_PAL_ERR,ddrval,__FILE__,__LINE__); + + ddrval = lpDDSPrimary->SetPalette(lpDDPal); + if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_PAL_ERR,ddrval,__FILE__,__LINE__); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LoadPalette(const char * pszFileName) { + struct RGB { + BYTE red; + BYTE green; + BYTE blue; + } pal[256]; + + HSFILE hFile; + app_assert(pszFileName); + patSFileOpenFile(pszFileName,&hFile); + patSFileReadFile(hFile,&pal[0],sizeof(pal)); + patSFileCloseFile(hFile); + + for (int i = 0; i < 256; i++) { + sgLoad[i].peRed = pal[i].red; + sgLoad[i].peGreen = pal[i].green; + sgLoad[i].peBlue = pal[i].blue; + sgLoad[i].peFlags = 0; + } +// GammaPalette(sgBase, sgLoad, 256); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LoadRndLvlPal(int l) { + + if (l == 0) { + LoadPalette("Levels\\TownData\\Town.pal"); + } + else { + char filestr[MAX_PATH]; + int palnum = random(0, 4) + 1; + sprintf(filestr, "Levels\\L%iData\\L%i_%i.PAL", l, l, palnum); + // JKE add our palettes here + if (l == 5) + sprintf(filestr, "NLevels\\L5Data\\L5Base.PAL"); + if (l == 6) + { + if (!gbOurNest) + ++palnum; + sprintf(filestr, "NLevels\\L%iData\\L%iBase%i.PAL", l, l, palnum); + } + LoadPalette(filestr); + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ResetPal() { + if (lpDDSPrimary && lpDDSPrimary->IsLost() == DDERR_SURFACELOST) + if (DD_OK != lpDDSPrimary->Restore()) return; + SDrawRealizePalette(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void GammaUp() { + if(sglGamma < lGAMMA_MAX) { + sglGamma += lGAMMA_STEP; + if (sglGamma > lGAMMA_MAX) + sglGamma = lGAMMA_MAX; + GammaPalette(sgCurr,sgBase,256); + SetPaletteEntries(); + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void GammaDown() { + if(sglGamma > lGAMMA_MIN) { + sglGamma -= lGAMMA_STEP; + if (sglGamma < lGAMMA_MIN) + sglGamma = lGAMMA_MIN; + GammaPalette(sgCurr,sgBase,256); + SetPaletteEntries(); + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +LONG GammaLevel(LONG lGamma) { + if (lGamma != lGAMMA_READ) { + // invert gamma hi/lo + sglGamma = lGAMMA_MAX - lGamma + lGAMMA_MIN; + GammaPalette(sgCurr,sgBase,256); + SetPaletteEntries(); + } + + // invert gamma hi/lo + return lGAMMA_MAX - sglGamma + lGAMMA_MIN; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void SetFadeLevel(int fadeval) { + if (! lpDD) return; + + for (int i = 0; i < 255; i++) { + DWORD pv; + pv = sgBase[i].peRed * fadeval; + sgCurr[i].peRed = (BYTE) (pv/256); + pv = sgBase[i].peGreen * fadeval; + sgCurr[i].peGreen = (BYTE) (pv/256); + pv = sgBase[i].peBlue * fadeval; + sgCurr[i].peBlue = (BYTE) (pv/256); + } + +// sgCurr[i].peRed = 0xff; +// sgCurr[i].peGreen = 0xff; +// sgCurr[i].peBlue = 0xff; + + Sleep(3); + lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,NULL); + SetPaletteEntries(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void BlackPalette() { + SetFadeLevel(0); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void PaletteFadeIn(int faderate) { + GammaPalette(sgBase,sgLoad,256); + for (int i = 0; i < 256; i += faderate) + SetFadeLevel(i); + SetFadeLevel(256); + + // un-gamma-fy base palette + CopyMemory(sgBase,sgLoad,sizeof(sgBase)); + sgbFadedIn = TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void PaletteFadeOut(int faderate) { + if (! sgbFadedIn) return; + for (int i = 256; i > 0; i -= faderate) + SetFadeLevel(i); + SetFadeLevel(0); + sgbFadedIn = FALSE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void LavaCycle() { + PALETTEENTRY temp = sgCurr[1]; + for (int i = 1; i < 31; i++) { + sgCurr[i].peRed = sgCurr[i + 1].peRed; + sgCurr[i].peGreen = sgCurr[i + 1].peGreen; + sgCurr[i].peBlue = sgCurr[i + 1].peBlue; + // don't copy flags + } + + sgCurr[i].peRed = temp.peRed; + sgCurr[i].peGreen = temp.peGreen; + sgCurr[i].peBlue = temp.peBlue; + // don't copy flags + + SetPaletteEntries(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// JKE new cycle to do twin effects +void TwinCycleCrypt() { + int i; + static int toggle = 0; + static int toggle2 = 0; + PALETTEENTRY temp; + + if (toggle2 > 1) + { + temp = sgCurr[15]; + for (i = 15; i > 1; --i) { + sgCurr[i].peRed = sgCurr[i - 1].peRed; + sgCurr[i].peGreen = sgCurr[i - 1].peGreen; + sgCurr[i].peBlue = sgCurr[i - 1].peBlue; + // don't copy flags + } + sgCurr[i].peRed = temp.peRed; + sgCurr[i].peGreen = temp.peGreen; + sgCurr[i].peBlue = temp.peBlue; + // don't copy flags + toggle2 = 0; + } + else + ++toggle2; + + if (toggle > 0) + { + temp = sgCurr[31]; + for (i = 31; i > 16; --i) + { + sgCurr[i].peRed = sgCurr[i - 1].peRed; + sgCurr[i].peGreen = sgCurr[i - 1].peGreen; + sgCurr[i].peBlue = sgCurr[i - 1].peBlue; + } + sgCurr[i].peRed = temp.peRed; + sgCurr[i].peGreen = temp.peGreen; + sgCurr[i].peBlue = temp.peBlue; + + SetPaletteEntries(); + ++toggle; + } + else + toggle = 1; +} +void TwinCycleNest() { + int i; + static int toggle = 0; + static int toggle2 = 0; + PALETTEENTRY temp; + if (toggle2 == 2) + { + temp = sgCurr[8]; + for (i = 8; i > 1; --i) { + sgCurr[i].peRed = sgCurr[i - 1].peRed; + sgCurr[i].peGreen = sgCurr[i - 1].peGreen; + sgCurr[i].peBlue = sgCurr[i - 1].peBlue; + // don't copy flags + } + + sgCurr[i].peRed = temp.peRed; + sgCurr[i].peGreen = temp.peGreen; + sgCurr[i].peBlue = temp.peBlue; + // don't copy flags + toggle2 = 0; + } + else + ++toggle2; + + if (toggle == 2) + { + temp = sgCurr[15]; + for (i = 15; i > 9; --i) + { + sgCurr[i].peRed = sgCurr[i - 1].peRed; + sgCurr[i].peGreen = sgCurr[i - 1].peGreen; + sgCurr[i].peBlue = sgCurr[i - 1].peBlue; + } + sgCurr[i].peRed = temp.peRed; + sgCurr[i].peGreen = temp.peGreen; + sgCurr[i].peBlue = temp.peBlue; + + SetPaletteEntries(); + toggle = 0; + } + else + ++toggle; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void UpdateLavaPalette() { + for (int i = 0; i < 32; i++) + sgBase[i] = sgLoad[i]; + GammaPalette(sgCurr,sgBase,32); + SetPaletteEntries(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void MeshLavaPalette(int fadeval) { + int i; + + for (i = 32 - fadeval; i >= 0; i--) + sgBase[i] = sgLoad[i]; + GammaPalette(sgCurr, sgBase, 32); + SetPaletteEntries(); +} diff --git a/PALETTE.H b/PALETTE.H new file mode 100644 index 0000000..ab64ddb --- /dev/null +++ b/PALETTE.H @@ -0,0 +1,46 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/PALETTE.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ +#define FADE_SLOW 8 +#define FADE_MED 16 +//#define FADE_FAST 32 +#define FADE_FAST 8 +#define FADE_VFAST 128 + + + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void CreatePalette(); +void LoadRndLvlPal(int); +void LoadPalette(const char * pszFileName); +void ResetPal(); +void SetPalette(); +void PaletteFadeIn(int faderate); +void PaletteFadeOut(int faderate); +void LavaCycle(); +void TwinCycleCrypt(); // JKE new cycle for dual effects +void TwinCycleNest(); // JKE new cycle for nest +void MeshLavaPalette(int fadeval); + + +#define lGAMMA_READ 0 +#define lGAMMA_MIN 30 +#define lGAMMA_MAX 100 +#define lGAMMA_STEP 5 +#define lGAMMA_TICKS (((lGAMMA_MAX - lGAMMA_MIN) / lGAMMA_STEP) + 1) +void GammaUp(); +void GammaDown(); +LONG GammaLevel(LONG lGamma); \ No newline at end of file diff --git a/PATCH.TXT b/PATCH.TXT new file mode 100644 index 0000000..afa168f --- /dev/null +++ b/PATCH.TXT @@ -0,0 +1,129 @@ +-------------------------------------------------------------------- +patch.txt +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +PATCH 1 -- 1/13/97 +-------------------------------------------------------------------- + + +diabloui.dll (connect.cpp) +-------------------------------------------------------------------- +corrects crash bug when attempting to join game created with an +invalid time (year < 1970 or year > 2036) + +checks for characters with (level==0) and treats that as an invalid +diablo character (no portrait, can't create or join) + +mike.rc +-------------------------------------------------------------------- +Added version information + + +storm.dll (snet.cpp) +-------------------------------------------------------------------- +send relative time instead of absolute time to players joining game +(helps correct diabloui crash bug) + + +standard.snp (ipx.cpp) +-------------------------------------------------------------------- +run-time dynamically link to wsock32.dll to prevent errors when +that file does not exist. + + +battle.snp (chatchnl.cpp) +-------------------------------------------------------------------- +fixed deallocated pointer error which caused player to get locked out +after creating a channel + +joingame.cpp +-------------------------------------------------------------------- +added more descriptive messages for can't join if game is full or +game owner is not responding. + +games shown in the list of public games will not disappear anymore. +The list will be refreshed only if the user closes and opens the join +game dialog. + +scrollrt.cpp +engine.cpp +-------------------------------------------------------------------- +corrects the NULL cell buffer errors and other data corruption in draw code +now uses "GRACEFUL_EXIT" to prevent fatal exits on error conditions + + +diablo.rc +-------------------------------------------------------------------- +version number changed +changed IDESCAPE to IDCANCEL for IDD_CDROM_ERR dialog +now matches code in appfat.cpp + + +init.cpp +-------------------------------------------------------------------- +version number changed + + +dx.cpp -- init_backbuf() +-------------------------------------------------------------------- +potential bug -- never actually seen +commented out ddraw_assert on failure to unlock video surface. +In NT it is possible to lose a video surface while it is locked. + + +dx.cpp:170 -- init_directx() fail on SetDisplayMode +-------------------------------------------------------------------- +reported bug -- occurs on some notebook systems +if direct draw doesn't support switching screen resolutions, try +switching color depth and keep same screen resolution + + +wave.cpp -- patSFileReadFile() +-------------------------------------------------------------------- +reported bug -- can't recover from read failure +if read failure occurs, restart read from beginning, +not from where read error occurred + + +wave.cpp/appfat.cpp -- InsertCDDlg() +-------------------------------------------------------------------- +reported bug -- both OK and Exit buttons did the same thing (oops) + + +sound.cpp -- snd_restore_snd() +-------------------------------------------------------------------- +potential bug -- never actually seen +if sound buffer cannot be locked, no error occurs, sound skipped + + +sound.cpp:384 -- snd_set_format() +-------------------------------------------------------------------- +reported bug -- sound cards don't support SetFormat() +commented out assertion + + +diablo.cpp -- CommandLine() +-------------------------------------------------------------------- +fixed silly problem with special direct draw command line options so +they can now appear anywhere on the command line instead of at the end + + +init.cpp -- MainWndProc() +-------------------------------------------------------------------- +correct palette problems when other applications realize their +palettes in the background. + + +pfile.cpp +-------------------------------------------------------------------- +removed "retribution" code which deletes player inventory when +cheating dectected. + + +mpqapi.cpp +-------------------------------------------------------------------- +removed time-stamp save code which appears to damage registry on +some systems. Code was related to "retribution" code diff --git a/PATH.CPP b/PATH.CPP new file mode 100644 index 0000000..da2e756 --- /dev/null +++ b/PATH.CPP @@ -0,0 +1,399 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Path file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/PATH.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** A* Path Search Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "path.h" + +PATHNODE PNodePool[MAXPNODES]; +PATHNODE *OPEN; +PATHNODE *CLOSED; + +int tempath[MAXPATHLEN]; + +PATHNODE pathnodes[MAXPNODES]; // node cache +int numpnodes; // index to next pathnode + +PATHNODE *Stack[MAXPNODES]; // stack of nodes to process +int numstack; // index to next stack item + +static char DirCmd[] = + { PCMD_WALKU, PCMD_WALKUR, PCMD_WALKR, PCMD_WALKUL, 0, + PCMD_WALKDR, PCMD_WALKL, PCMD_WALKDL, PCMD_WALKD + }; + +int PATHDIST(int x1, int y1, int x2, int y2); +PATHNODE *GetPathNode(); +PATHNODE *ReturnBestNode(void); +BOOL GenerateSuccessors(CHECKFUNC1 PosOk, int PosOkArg, PATHNODE *BestNode,int dx,int dy); +BOOL GenerateSucc(PATHNODE *BestNode,int x, int y, int dx, int dy); +PATHNODE *CheckOPEN(int x, int y); +PATHNODE *CheckCLOSED(int x, int y); +void Insert(PATHNODE *Successor); +void PropagateDown(PATHNODE *Old); + +void Push(PATHNODE *Node); +PATHNODE *Pop(void); + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int FindPath(CHECKFUNC1 PosOk, int PosOkArg, int sx,int sy,int dx,int dy, char path[]) +{ + PATHNODE *Node, *BestNode; + int i,len; + + numpnodes = 0; // clear node chache + OPEN=GetPathNode(); + CLOSED=GetPathNode(); + numstack = 0; // clear stack + + Node=GetPathNode(); + Node->g=0; + Node->h=PATHDIST(sx,sy,dx,dy); + Node->f=Node->g+Node->h; + Node->x=sx; + Node->y=sy; + + OPEN->NextNode=Node; /* make Open List point to first node */ + for (;;) + { + BestNode=(PATHNODE *)ReturnBestNode(); + if(!BestNode) + return 0; + + if (BestNode->x == dx && BestNode->y == dy) /* if we've found the end, break and finish */ + break; + if(!GenerateSuccessors(PosOk, PosOkArg, BestNode,dx,dy)) + return 0; + } + + // generate list of moves + Node = BestNode; + + len = 0; + + while(Node->Parent && len < MAXPATHLEN) + { + tempath[len++] = DirCmd[(Node->x - Node->Parent->x + 1) + (Node->y - Node->Parent->y + 1)*3]; + Node = Node->Parent; + } + if(len == MAXPATHLEN) + return 0; + + for(i = 0; i < len; i++) + path[i] = tempath[len - i - 1]; + + return i; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PATHDIST(int x1, int y1, int x2, int y2) +{ + int dx,dy; + int mind,maxd; + + dx = abs(x1-x2); + dy = abs(y1-y2); + mind = min(dx,dy); + maxd = max(dx,dy); + + // Assign dist of 3 for diagonal, 2 for straight + // Therefore, 3*(mind) + 2*(maxd-mind) + // = mind + 2*maxd + return mind + maxd<<1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int PathVal(PATHNODE *Node, int x, int y) +{ + if(Node->x == x || Node->y == y) + return 2; + return 3; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +PATHNODE *ReturnBestNode(void) +{ + PATHNODE *tmp; + + if (OPEN->NextNode == NULL) + { + return NULL; + } + +/* Pick Node with lowest f, in this case it's the first node in list + because we sort the OPEN list wrt lowest f. Call it BESTNODE. */ + + tmp=OPEN->NextNode; // point to first node on OPEN + OPEN->NextNode=tmp->NextNode; // Make OPEN point to nextnode or NULL. + +/* Next take BESTNODE (or temp in this case) and put it on CLOSED */ + + tmp->NextNode=CLOSED->NextNode; + CLOSED->NextNode=tmp; + + return(tmp); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PathDirOk(PATHNODE *Node, int x, int y) +{ + BOOL ok = TRUE; + + switch(DirCmd[(x - Node->x + 1) + (y - Node->y + 1)*3]) + { + case PCMD_WALKU: + ok = !(nSolidTable[dPiece[x][y+1]] || nSolidTable[dPiece[x+1][y]]); + break; + case PCMD_WALKR: + ok = !(nSolidTable[dPiece[x][y+1]] || nSolidTable[dPiece[x-1][y]]); + break; + case PCMD_WALKD: + ok = !(nSolidTable[dPiece[x][y-1]] || nSolidTable[dPiece[x-1][y]]); + break; + case PCMD_WALKL: + ok = !(nSolidTable[dPiece[x+1][y]] || nSolidTable[dPiece[x][y-1]]); + break; + } + + return ok; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL GenerateSuccessors(CHECKFUNC1 PosOk, int PosOkArg, PATHNODE *BestNode,int dx,int dy) +{ + int x,y; + int i; + BOOL posok; + static const char nextx[] = { -1, -1, 1, 1, -1, 0, 1, 0 }; + static const char nexty[] = { -1, 1, -1, 1, 0, -1, 0, 1 }; + + for(i = 0; i < 8; i++) + { + x = BestNode->x + nextx[i]; + y = BestNode->y + nexty[i]; + + posok = PosOk(PosOkArg, x, y); + if((posok && PathDirOk(BestNode, x, y)) + || (!posok && x==dx && y==dy)) // allow user to click on walls + if(!GenerateSucc(BestNode,x,y,dx,dy)) + return FALSE; + } + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL GenerateSucc(PATHNODE *BestNode,int x, int y, int dx, int dy) +{ + int g,c=0; + PATHNODE *Old,*Successor; + + g=BestNode->g+PathVal(BestNode,x,y); /* g(Successor)=g(BestNode)+cost of getting from BestNode to Successor */ + + if ((Old=CheckOPEN(x, y)) != NULL) /* if equal to NULL then not in OPEN list, else it returns the Node in Old */ + { + for(c=0;c<8;c++) + if(BestNode->Child[c] == NULL) /* Add Old to the list of BestNode's Children (or Successors). */ + break; + BestNode->Child[c]=Old; + + if (g < Old->g && PathDirOk(BestNode, x, y)) /* if our new g value is < Old's then reset Old's parent to point to BestNode */ + { + Old->Parent=BestNode; + Old->g=g; + Old->f=g+Old->h; + } + } + else if ((Old=CheckCLOSED(x, y)) != NULL) /* if equal to NULL then not in OPEN list, else it returns the Node in Old */ + { + for(c=0;c<8;c++) + if (BestNode->Child[c] == NULL) /* Add Old to the list of BestNode's Children (or Successors). */ + break; + BestNode->Child[c]=Old; + + if (g < Old->g && PathDirOk(BestNode, x, y)) /* if our new g value is < Old's then reset Old's parent to point to BestNode */ + { + Old->Parent=BestNode; + Old->g=g; + Old->f=g+Old->h; + PropagateDown(Old); /* Since we changed the g value of Old, we need + to propagate this new value downwards, i.e. + do a Depth-First traversal of the tree! */ + } + } + else + { + if(!(Successor=GetPathNode())) + return FALSE; + else + { + Successor->Parent=BestNode; + Successor->g=g; + Successor->h=PATHDIST(x,y,dx,dy); + Successor->f=g+Successor->h; + Successor->x=x; + Successor->y=y; + Insert(Successor); /* Insert Successor on OPEN list wrt f */ + for(c=0;c<8;c++) + if (BestNode->Child[c] == NULL) /* Add Successor to the list of BestNode's Children (or Successors). */ + break; + BestNode->Child[c]=Successor; + } + } + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +PATHNODE *CheckOPEN(int x, int y) +{ + PATHNODE *tmp; + + tmp=OPEN->NextNode; + while (tmp != NULL) + { + if (tmp->x == x && tmp->y == y) + return (tmp); + else + tmp=tmp->NextNode; + } + return (NULL); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +PATHNODE *CheckCLOSED(int x, int y) +{ + PATHNODE *tmp; + + tmp=CLOSED->NextNode; + + while (tmp != NULL) + { + if (tmp->x == x && tmp->y == y) + return (tmp); + else + tmp=tmp->NextNode; + } + return (NULL); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Insert(PATHNODE *Successor) +{ + PATHNODE *tmp1,*tmp2; + int f; + + if (OPEN->NextNode == NULL) + { + OPEN->NextNode=Successor; + return; + } + + /* insert into OPEN successor wrt f */ + + f=Successor->f; + tmp1=OPEN; + tmp2=OPEN->NextNode; + + while ((tmp2 != NULL) && (tmp2->f < f)) + { + tmp1=tmp2; + tmp2=tmp2->NextNode; + } + Successor->NextNode=tmp2; + tmp1->NextNode=Successor; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PropagateDown(PATHNODE *Old) +{ + int c; + PATHNODE *Child, *Father; + + Push(Old); + while (numstack) + { + Father=Pop(); + for(c=0;c<8;c++) + { + if ((Child=Father->Child[c])==NULL) /* we may stop the propagation 2 ways: either */ + break; + if (Father->g+PathVal(Father, Child->x, Child->y) < Child->g && PathDirOk(Father, Child->x, Child->y)) /* there are no children, or that the g value of */ + { /* the child is equal or better than the cost we're propagating */ + Child->Parent=Father; + Child->g=Father->g+PathVal(Father, Child->x, Child->y); + Child->f=Child->g+Child->h; + Push(Child); + } + } + } +} + +/**************************************************************************/ +/* STACK FUNCTIONS */ +/**************************************************************************/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void Push(PATHNODE *Node) +{ + Stack[numstack++] = Node; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +PATHNODE *Pop() +{ + return Stack[--numstack]; +} + +PATHNODE *GetPathNode() +{ + PATHNODE *Node; + + if(numpnodes == MAXPNODES) + return NULL; + else + { + Node = &pathnodes[numpnodes++]; + + memset((void *)Node, 0, sizeof(PATHNODE)); + return Node; + } +} diff --git a/PATH.H b/PATH.H new file mode 100644 index 0000000..89d4f01 --- /dev/null +++ b/PATH.H @@ -0,0 +1,36 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Path Header File +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/PATH.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXPNODES 300 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct tagPATHNODE{ + char f,h; + char g; + int x,y; + struct tagPATHNODE *Parent; + struct tagPATHNODE *Child[8]; /* a node may have upto 8+(NULL) children. */ + struct tagPATHNODE *NextNode; /* for filing purposes */ +} PATHNODE; + +/*-----------------------------------------------------------------------** +** Function Prototypes +**-----------------------------------------------------------------------*/ + +typedef BOOL (*CHECKFUNC1)(int arg1, int x, int y); + +int FindPath(CHECKFUNC1 PosOk, int PosOkArg, int sx,int sy,int dx,int dy, char path[]); diff --git a/PFILE.CPP b/PFILE.CPP new file mode 100644 index 0000000..14b3200 --- /dev/null +++ b/PFILE.CPP @@ -0,0 +1,931 @@ +//****************************************************************** +// $Header: /Diablo/PFILE.CPP 3 2/04/97 11:17a Pwyatt $ +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include +#include "storm/h/storm.h" +#include "diabloui.h" +#include "items.h" +#include "gendung.h" +#include "player.h" +#include "engine.h" +#include "multi.h" +#include "spells.h" +#include "packplr.h" +#include "gamemenu.h" +#include "mpqapi.h" + + +//****************************************************************** +// compiler constants +//****************************************************************** +// pjw.patch1.start -- remove retribution code +#define PREVENT_CHEATING 0 // 0 in final +#ifdef NDEBUG +#undef PREVENT_CHEATING +#define PREVENT_CHEATING 0 +#endif +// pjw.patch1.end + + +#define ENCRYPT_WITH_NAME 1 // 1 in final +#ifdef NDEBUG +#undef ENCRYPT_WITH_NAME +#define ENCRYPT_WITH_NAME 1 +#endif + +#if !ENCRYPT_WITH_NAME +#define ENCRYPTNAME "BROPER" // replace name to debug specific file +#endif + + +//****************************************************************** +// extern +//****************************************************************** +extern char gszHero[]; +extern char gszProgKey[]; +extern char gszArchiveKey[]; +extern int StrengthTbl[NUM_CLASSES]; +extern int MagicTbl[NUM_CLASSES]; +extern int DexterityTbl[NUM_CLASSES]; +extern int VitalityTbl[NUM_CLASSES]; + +DWORD CalcEncodeDstBytes(DWORD dwSrcBytes); +void EncodeFile(BYTE * pbSrcDst,DWORD dwSrcBytes,DWORD dwDstBytes,const char * pszPassword); +DWORD DecodeFile(BYTE * pbSrcDst,DWORD dwDstBytes,const char * pszPassword); +void PackClearCheater(PkPlayerStruct *pPack); +void DiskFreeErrorDlg(const char * pszDir); + + +//****************************************************************** +// public +//****************************************************************** +BOOL gbValidSaveFile = FALSE; +BOOL gbSaveFileExists = FALSE; + + +//****************************************************************** +// private +//****************************************************************** +// signature name for machines with no network name +#ifndef ENCRYPTNAME +#define ENCRYPTNAME "xrgyrkj1" +#endif + +#define ARCHIVE_PRIORITY 0x7000 + +static char sgszCharNames[MAX_CHARACTERS+1][PLR_NAME_LEN]; + +static const char sgszSaveGame[] = "game"; +static const char sgszSaveChar[] = "hero"; +static const char sgszPermSaveLevel_d[] = "perml%02d"; +static const char sgszPermSaveSLevel_d[] = "perms%02d"; +static const char sgszTempSaveLevel_d[] = "templ%02d"; +static const char sgszTempSaveSLevel_d[] = "temps%02d"; + +typedef enum { + ARCHIVE_DIABLO, + ARCHIVE_HELLFIRE + } ARCHIVE_TYPE; + + +//****************************************************************** +//****************************************************************** +static void check_disk_space_priv(char * pszDir) { + app_assert(pszDir); + + // remove any trailing path from the drive name + char * pszTemp = pszDir; + while (*pszTemp) { + if (*pszTemp++ != '\\') continue; + *pszTemp = 0; + break; + } + + DWORD dwSectorsPerCluster; + DWORD dwBytesPerSector; + DWORD dwNumberOfFreeClusters; + DWORD dwTotalNumberOfClusters; + BOOL bResult = GetDiskFreeSpace( + pszDir, + &dwSectorsPerCluster, + &dwBytesPerSector, + &dwNumberOfFreeClusters, + &dwTotalNumberOfClusters + ); + + if (bResult) { + __int64 i64BytesFree = dwNumberOfFreeClusters; + i64BytesFree *= dwSectorsPerCluster; + i64BytesFree *= dwBytesPerSector; + if (i64BytesFree < 10 * 1024 * 1024) bResult = FALSE; + } + + if (! bResult) DiskFreeErrorDlg(pszDir); +} + + +//****************************************************************** +//****************************************************************** +void check_disk_space() { + char szDir[MAX_PATH]; + + #if IS_VERSION(BETA) + if (! GetSystemDirectory(szDir,MAX_PATH)) goto error; + #else + if (! GetWindowsDirectory(szDir,MAX_PATH)) goto error; + #endif + check_disk_space_priv(szDir); + + if (! GetModuleFileName(ghInst,szDir,MAX_PATH)) goto error; + check_disk_space_priv(szDir); + + return; +error: + app_fatal("Unable to initialize save directory"); +} + + +//****************************************************************** +//****************************************************************** +static void archive_name(char * pszBuf,DWORD dwBufSize,DWORD dwChar, ARCHIVE_TYPE arType) { + app_assert(pszBuf); + app_assert(dwBufSize >= MAX_PATH); + const char * pszSaveFile_d; + UINT uiResult; + + if (gbMaxPlayers > 1) { + #if IS_VERSION(SHAREWARE) + pszSaveFile_d = "\\slinfo_%d.drv"; + #else + if (arType == ARCHIVE_DIABLO) + pszSaveFile_d = "\\dlinfo_%d.drv"; + else + pszSaveFile_d = "\\hrinfo_%d.drv"; + #endif + + uiResult = GetModuleFileName(ghInst, pszBuf, MAX_PATH); + char* pszExeName = strrchr(pszBuf, '\\'); + if (pszExeName) *pszExeName = 0; + } + else { + #if IS_VERSION(SHAREWARE) + pszSaveFile_d = "\\spawn_%d.sv"; + #else + if (arType == ARCHIVE_DIABLO) + pszSaveFile_d = "\\single_%d.sv"; + else + pszSaveFile_d = "\\single_%d.hsv"; + #endif + + uiResult = GetModuleFileName(ghInst,pszBuf,MAX_PATH); + char * pszExeName = strrchr(pszBuf,'\\'); + if (pszExeName) *pszExeName = 0; + } + + // make sure we were able to get the parent directory + if (! uiResult) app_fatal("Unable to get save directory"); + + char szTemp[MAX_PATH]; + sprintf(szTemp,pszSaveFile_d,dwChar); + strcat(pszBuf,szTemp); + _strlwr(pszBuf); +} + + +//****************************************************************** +//****************************************************************** +static DWORD name_2_file_index(const char * pszName) { + for (DWORD d = 0; d < MAX_CHARACTERS; d++) { + if (! _stricmp(sgszCharNames[d],pszName)) + break; + } + + return d; +} + + +//****************************************************************** +//****************************************************************** +static BOOL CALLBACK GetPlayerFileNames(DWORD dwIndex,char szPath[MAX_PATH]) { + const char * pszFmt; + + if (gbMaxPlayers > 1) { + if (dwIndex) return FALSE; + pszFmt = sgszSaveChar; + } + else if (dwIndex < NUMLEVELS) { + // level file + pszFmt = sgszPermSaveLevel_d; + } + else if (dwIndex < NUMLEVELS*2) { + // slevel file + dwIndex -= NUMLEVELS; + pszFmt = sgszPermSaveSLevel_d; + } + else if (dwIndex == NUMLEVELS*2) { + // game file + pszFmt = sgszSaveGame; + } + else if (dwIndex == NUMLEVELS*2+1) { + // character file + pszFmt = sgszSaveChar; + } + else { + return FALSE; + } + + sprintf(szPath,pszFmt,dwIndex); + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static BOOL LoadCharacter(HSARCHIVE hsArchive,PkPlayerStruct * pPack) { + app_assert(pPack); + + // open the character file + HSFILE hsFile; + if (! SFileOpenFileEx(hsArchive,sgszSaveChar,0,&hsFile)) + return FALSE; + + // setup everything in case of error + BYTE * pbFile = NULL; + BOOL bResult = FALSE; + + // get password + char computername[MAX_COMPUTERNAME_LENGTH+1] = ENCRYPTNAME; + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + #if ENCRYPT_WITH_NAME + if (gbMaxPlayers > 1) GetComputerName(computername,&size); + #endif + + // read character data + DWORD dwSize = SFileGetFileSize(hsFile,NULL); + if (! dwSize) goto error; + pbFile = DiabloAllocPtrSig(dwSize,'SAVt'); + DWORD dwBytes; + if (! SFileReadFile(hsFile,pbFile,dwSize,&dwBytes,NULL)) + goto error; + app_assert(dwBytes == dwSize); + + // decode file using password + dwBytes = DecodeFile(pbFile,dwSize,computername); + if (dwBytes != sizeof(*pPack)) goto error; + + // success! + CopyMemory(pPack,pbFile,sizeof(*pPack)); + bResult = TRUE; + +error: // CLEANUP + if (pbFile) DiabloFreePtr(pbFile); + SFileCloseFile(hsFile); + return bResult; +} + + +//****************************************************************** +//****************************************************************** +static void SaveCharacter(const PkPlayerStruct * pPack) { + // get password + char computername[MAX_COMPUTERNAME_LENGTH+1] = ENCRYPTNAME; + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + #if ENCRYPT_WITH_NAME + if (gbMaxPlayers > 1) GetComputerName(computername,&size); + #endif + + // encrypt character data + DWORD dwDstBytes = CalcEncodeDstBytes(sizeof(*pPack)); + BYTE * pbSrcDst = DiabloAllocPtrSig(dwDstBytes,'SAVt'); + CopyMemory(pbSrcDst,pPack,sizeof(*pPack)); + EncodeFile(pbSrcDst,sizeof(*pPack),dwDstBytes,computername); + + // add file to archive + MPQAddFile(sgszSaveChar,pbSrcDst,dwDstBytes); + + // cleanup + DiabloFreePtr(pbSrcDst); +} + + +//****************************************************************** +//****************************************************************** +#if PREVENT_CHEATING +static BOOL FixCheaters(BOOL * pbMsgBox,DWORD dwChar) { + app_assert(dwChar < MAX_CHARACTERS); + + // only perform cheat detection/correction for multiplayer chars + if (gbMaxPlayers == 1) return TRUE; + + // compare current state of archive time stamps to expected values + char szSaveArchive[MAX_PATH]; + archive_name(szSaveArchive,MAX_PATH,dwChar, ARCHIVE_HELLFIRE); + if (MPQCompareTimeStamps(szSaveArchive,dwChar)) + return TRUE; + + HSARCHIVE hsArchive = NULL; + if (! SFileOpenArchive(szSaveArchive,ARCHIVE_PRIORITY,0,&hsArchive)) + return TRUE; + + // load character + PkPlayerStruct pack; + if (! LoadCharacter(hsArchive,&pack)) + pack.pName[0] = 0; + else + PackClearCheater(&pack); + SFileCloseArchive(hsArchive); + hsArchive = NULL; + + // write all characters + if (pack.pName[0]) { + if (! MPQOpenArchive(szSaveArchive,TRUE,dwChar)) return FALSE; + SaveCharacter(&pack); + MPQCloseArchive(szSaveArchive,TRUE,dwChar); + MPQUpdateCreationTimeStamp(szSaveArchive,dwChar); + } + else { + BOOL MPQSetAttributes(const char * pszArchive,BOOL bHide); + MPQSetAttributes(szSaveArchive,FALSE); + DeleteFile(szSaveArchive); + } + + if (pbMsgBox && *pbMsgBox) { + *pbMsgBox = FALSE; + UiMessageBoxCallback( + ghMainWnd, + "A problem with your saved game file has been detected." + "The file has been fixed, but changes to it may have occurred.", + "Diablo", + MB_OK + ); + } + + return TRUE; +} +#endif + + +//****************************************************************** +//****************************************************************** +static BOOL open_archive_write(BOOL bMungeOnError,DWORD dwChar) { + // make sure nobody is screwing with our file + #if PREVENT_CHEATING + if (FixCheaters(NULL,dwChar)) + #endif + { + char szSaveArchive[MAX_PATH]; + archive_name(szSaveArchive,MAX_PATH,dwChar, ARCHIVE_HELLFIRE); + if (MPQOpenArchive(szSaveArchive,gbMaxPlayers > 1,dwChar)) + return TRUE; + } + + if (bMungeOnError && gbMaxPlayers > 1) + MPQMungeStamps(dwChar); + return FALSE; +} + + +//****************************************************************** +//****************************************************************** +static void close_archive_write(BOOL bFree,DWORD dwChar) { + char szSaveArchive[MAX_PATH]; + archive_name(szSaveArchive,MAX_PATH,dwChar, ARCHIVE_HELLFIRE); + MPQCloseArchive(szSaveArchive,bFree,dwChar); +} + + +//****************************************************************** +//****************************************************************** +static HSARCHIVE open_archive_read(BOOL * pbMsgBox,DWORD dwChar) { + // make sure nobody is screwing with our file + #if PREVENT_CHEATING + if (! FixCheaters(pbMsgBox,dwChar)) + return FALSE; + #endif + + // open the archive for reading + HSARCHIVE hsArchive; + char szSaveArchive[MAX_PATH]; + archive_name(szSaveArchive,MAX_PATH,dwChar, ARCHIVE_HELLFIRE); + if (! SFileOpenArchive(szSaveArchive,ARCHIVE_PRIORITY,0,&hsArchive)) + { + //archive_name(szSaveArchive,MAX_PATH,dwChar, ARCHIVE_DIABLO); + //if (! SFileOpenArchive(szSaveArchive,ARCHIVE_PRIORITY,0,&hsArchive)) + return NULL; + } + return hsArchive; +} + + +//****************************************************************** +//****************************************************************** +static void close_archive_read(HSARCHIVE hsArchive) { + app_assert(hsArchive); + SFileCloseArchive(hsArchive); +} + + +//****************************************************************** +//****************************************************************** +static BOOL check_valid_save(HSARCHIVE hsArchive,DWORD dwChar) { + app_assert(dwChar < MAX_CHARACTERS); + + BOOL Result = FALSE; + + gbSaveFileExists = FALSE; + + // only single player games can have save games + if (gbMaxPlayers != 1) + return Result; + + HSFILE hsFile; + if (! SFileOpenFileEx(hsArchive,sgszSaveGame,0,&hsFile)) + return Result; + + // allocate a buffer large enough for the file + DWORD dwLen = SFileGetFileSize(hsFile,NULL); + if (! dwLen) app_fatal("Invalid save file"); + BYTE * pbData = DiabloAllocPtrSig(dwLen + 8,'SAVt'); + + // decode overwrites the headers, so give it extra room + BYTE *pbHackData = 4 + pbData; + + DWORD dwBytes; + if (SFileReadFile(hsFile, pbHackData, dwLen, &dwBytes, NULL)) + { + if (dwBytes == dwLen) + { + char computername[MAX_COMPUTERNAME_LENGTH+1] = ENCRYPTNAME; + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + #if ENCRYPT_WITH_NAME + if (gbMaxPlayers > 1) GetComputerName(computername,&size); + #endif + + gbSaveFileExists = TRUE; + + dwLen = DecodeFile(pbHackData,dwLen,computername); + if (dwLen) + { + long id; + id = *pbHackData << 24; + pbHackData++; + id |= *pbHackData << 16; + pbHackData++; + id |= *pbHackData << 8; + pbHackData++; + id |= *pbHackData; + + // Test first 4 bytes for our header. + if ('HELF' == id) + { + Result = TRUE; + } + } + } + } + + if (pbData) DiabloFreePtr(pbData); + SFileCloseFile(hsFile); + return Result; +} + + +//****************************************************************** +//****************************************************************** +void UpdatePlayerFile() { + app_assert(myplr >= 0 && myplr < MAX_PLRS); + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + if (! open_archive_write(TRUE,dwChar)) return; + + // pack and save player + PkPlayerStruct pack; + PackPlayer(&pack,myplr); + SaveCharacter(&pack); + + // close archive -- in single player mode, release + // the file memory. In multiplayer mode, leave the + // file info in memory so we don't have to reload + close_archive_write(gbMaxPlayers == 1,dwChar); +} + + +//****************************************************************** +//****************************************************************** +void ReleasePlayerFile() { + // free any memory associated with player file + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + close_archive_write(TRUE,dwChar); +} + + +//****************************************************************** +//****************************************************************** +static char ui_2_game_class(int heroclass) { + if (heroclass == UI_WARRIOR) + return CLASS_WARRIOR; + if (heroclass == UI_ROGUE) + return CLASS_ROGUE; + if (heroclass == UI_MONK) + return CLASS_MONK; + if (heroclass == UI_BARD) + return CLASS_BARD; + if (heroclass == UI_BARBARIAN) + return CLASS_BARBARIAN; + return CLASS_SORCEROR; +} + + +//****************************************************************** +//****************************************************************** +static BYTE game_2_ui_class(const PlayerStruct * p) { + if (p->_pClass == CLASS_WARRIOR) + return UI_WARRIOR; + if (p->_pClass == CLASS_ROGUE) + return UI_ROGUE; + if (p->_pClass == CLASS_MONK) + return UI_MONK; + if (p->_pClass == CLASS_BARD) + return UI_BARD; + if (p->_pClass == CLASS_BARBARIAN) + return UI_BARBARIAN; + return UI_SORCERER; +} + + +//****************************************************************** +//****************************************************************** +void game_2_ui_player(const PlayerStruct * p,TPUIHEROINFO heroinfo,BOOL bHasSaveFile) { + ZeroMemory(heroinfo,sizeof(TUIHEROINFO)); + strncpy(heroinfo->name,p->_pName,MAX_NAME_LEN-1); + heroinfo->name[MAX_NAME_LEN-1] = 0; + heroinfo->level = p->_pLevel; + heroinfo->heroclass = game_2_ui_class(p); + heroinfo->strength = p->_pStrength; + heroinfo->magic = p->_pMagic; + heroinfo->dexterity = p->_pDexterity; + heroinfo->vitality = p->_pVitality; + heroinfo->gold = p->_pGold; + heroinfo->hassaved = bHasSaveFile; + heroinfo->herorank = (BYTE) p->pDiabloKillLevel; + heroinfo->spawned = IS_VERSION(SHAREWARE); +} + + +//****************************************************************** +//****************************************************************** +BOOL CALLBACK UiEnumHeroes(ENUMHEROPROC enumproc) { + // assume there is no archive + ZeroMemory(sgszCharNames,sizeof(sgszCharNames)); + + // get the character name field and save into global + BOOL bMsgBox = TRUE; + for (DWORD dwChar = 0; dwChar < MAX_CHARACTERS; dwChar++) { + HSARCHIVE hsArchive; + if (NULL == (hsArchive = open_archive_read(&bMsgBox,dwChar))) + continue; + + PkPlayerStruct pack; + TUIHEROINFO heroinfo; + BOOL bResult = LoadCharacter(hsArchive,&pack); + if (bResult) { + app_assert(sizeof sgszCharNames[dwChar] == sizeof pack.pName); + strcpy(sgszCharNames[dwChar],pack.pName); + UnPackPlayer(&pack,0,FALSE); + game_2_ui_player(&plr[0],&heroinfo,check_valid_save(hsArchive,dwChar)); + enumproc(&heroinfo); + } + + // close archive + close_archive_read(hsArchive); + } + + return 1; +} + + +//****************************************************************** +//****************************************************************** +BOOL CALLBACK UiGetDefaultCharStats(int heroclass, TPUIDEFSTATS defaultstats) { + int nClass = ui_2_game_class(heroclass); + defaultstats->strength = StrengthTbl[nClass]; + defaultstats->magic = MagicTbl[nClass]; + defaultstats->dexterity = DexterityTbl[nClass]; + defaultstats->vitality = VitalityTbl[nClass]; + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +BOOL CALLBACK UiCreateHero(TPUIHEROINFO heroinfo) { + app_assert(heroinfo->name[0]); + + // find out if this guy already exists + // or find a free hero slot + DWORD dwChar = name_2_file_index(heroinfo->name); + if (dwChar >= MAX_CHARACTERS) { + for (dwChar = 0; dwChar < MAX_CHARACTERS; dwChar++) + if (! sgszCharNames[dwChar][0]) + break; + } + if (dwChar >= MAX_CHARACTERS) + return FALSE; + + // open archive to save character + if (! open_archive_write(FALSE,dwChar)) return FALSE; + + // we are going to overwrite a save slot. If the player + // has done any hacking, there may be invalid save files + // from a previous player in the slot. Remove those files + MPQDeleteFiles(GetPlayerFileNames); + + // fix up the name table + strncpy(sgszCharNames[dwChar],heroinfo->name,PLR_NAME_LEN); + sgszCharNames[dwChar][PLR_NAME_LEN - 1] = 0; + + // create character in player slot 0 + // heroinfo->heroclass = UI_BARD; + CreatePlayer(0,ui_2_game_class(heroinfo->heroclass)); + strncpy(plr[0]._pName,heroinfo->name,PLR_NAME_LEN); + plr[0]._pName[PLR_NAME_LEN - 1] = 0; + + // pack character and save + PkPlayerStruct pack; + PackPlayer(&pack,0); + SaveCharacter(&pack); + + // convert character into something the UI can use + + game_2_ui_player(&plr[0],heroinfo,FALSE); + + close_archive_write(TRUE,dwChar); + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +BOOL CALLBACK UiDeleteHero(TPUIHEROINFO heroinfo) { + DWORD dwChar = name_2_file_index(heroinfo->name); + if (dwChar >= MAX_CHARACTERS) return TRUE; + + // delete character + sgszCharNames[dwChar][0] = 0; + + // delete archive + char szSaveArchive[MAX_PATH]; + archive_name(szSaveArchive,MAX_PATH,dwChar, ARCHIVE_HELLFIRE); + DeleteFile(szSaveArchive); + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +void SetupLocalPlayer() { + // load the player information we want into our player slot + app_assert(myplr >= 0 && myplr < MAX_PLRS); + DWORD dwChar = name_2_file_index(gszHero); + app_assert(dwChar != MAX_CHARACTERS); + + // open the main archive + HSARCHIVE hsArchive; + PkPlayerStruct pack; + if (NULL == (hsArchive = open_archive_read(NULL,dwChar))) + app_fatal("Unable to open archive"); + if (! LoadCharacter(hsArchive,&pack)) + app_fatal("Unable to load character"); + UnPackPlayer(&pack,myplr,FALSE); + gbValidSaveFile = check_valid_save(hsArchive,dwChar); + close_archive_read(hsArchive); +} + + +//****************************************************************** +//****************************************************************** +void CreateSaveLevelName(char szName[MAX_PATH]) { + // make sure the character is currently valid + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + app_assert(dwChar < MAX_CHARACTERS); + app_assert(gbMaxPlayers == 1); + + // saving a level always saves it as a "temporary" save file + if (setlevel) sprintf(szName,sgszTempSaveSLevel_d,setlvlnum); + else sprintf(szName,sgszTempSaveLevel_d,currlevel); +} + + +//****************************************************************** +//****************************************************************** +void CreateLoadLevelName(char szName[MAX_PATH]) { + // make sure the character is currently valid + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + app_assert(dwChar < MAX_CHARACTERS); + app_assert(gbMaxPlayers == 1); + + // try "temporary" save file name + CreateSaveLevelName(szName); + + if (! open_archive_write(FALSE,dwChar)) + app_fatal("Unable to read to save file archive"); + BOOL bResult = MPQFileExists(szName); + close_archive_write(TRUE,dwChar); + if (bResult) return; + + // create "permanent" save file name + if (setlevel) sprintf(szName,sgszPermSaveSLevel_d,setlvlnum); + else sprintf(szName,sgszPermSaveLevel_d,currlevel); +} + + +//****************************************************************** +//****************************************************************** +void CreateSaveGameName(char szName[MAX_PATH]) { + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + app_assert(dwChar < MAX_CHARACTERS); + app_assert(gbMaxPlayers == 1); + strcpy(szName,sgszSaveGame); +} + + +//****************************************************************** +//****************************************************************** +static BOOL CALLBACK GetPermSaveNames(DWORD dwIndex,char szPath[MAX_PATH]) { + const char * pszFmt; + + app_assert(gbMaxPlayers == 1); + if (dwIndex < NUMLEVELS) { + // level file + pszFmt = sgszPermSaveLevel_d; + } + else if (dwIndex < NUMLEVELS*2) { + // slevel file + dwIndex -= NUMLEVELS; + pszFmt = sgszPermSaveSLevel_d; + } + else { + return FALSE; + } + + sprintf(szPath,pszFmt,dwIndex); + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static BOOL CALLBACK GetTempSaveNames(DWORD dwIndex,char szPath[MAX_PATH]) { + const char * pszFmt; + + app_assert(gbMaxPlayers == 1); + if (dwIndex < NUMLEVELS) { + // level file + pszFmt = sgszTempSaveLevel_d; + } + else if (dwIndex < NUMLEVELS*2) { + // slevel file + dwIndex -= NUMLEVELS; + pszFmt = sgszTempSaveSLevel_d; + } + else { + return FALSE; + } + + sprintf(szPath,pszFmt,dwIndex); + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +void DestroyTempSaves() { + if (gbMaxPlayers > 1) return; + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + app_assert(dwChar < MAX_CHARACTERS); + if (! open_archive_write(FALSE,dwChar)) + app_fatal("Unable to write to save file archive"); + MPQDeleteFiles(GetTempSaveNames); + close_archive_write(TRUE,dwChar); +} + + +//****************************************************************** +//****************************************************************** +void MoveTempSavesToPermanent() { + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + app_assert(dwChar < MAX_CHARACTERS); + app_assert(gbMaxPlayers == 1); + + if (! open_archive_write(FALSE,dwChar)) + app_fatal("Unable to write to save file archive"); + + DWORD dwIndex = 0; + char szTemp[MAX_PATH]; + char szPerm[MAX_PATH]; + while (GetTempSaveNames(dwIndex,szTemp)) { + BOOL bResult = GetPermSaveNames(dwIndex,szPerm); + app_assert(bResult); + dwIndex++; + + // is there a temp file? + if (! MPQFileExists(szTemp)) continue; + + // delete permanent file so we can rename temp file + if (MPQFileExists(szPerm)) MPQDeleteFile(szPerm); + + MPQRenameFile(szTemp,szPerm); + } + app_assert(! GetPermSaveNames(dwIndex,szPerm)); + + close_archive_write(TRUE,dwChar); +} + + +//****************************************************************** +//****************************************************************** +void WriteSaveFile(const char * pszName,BYTE * pbData,DWORD dwLen,DWORD dwDstBytes) { + app_assert(pszName); + app_assert(pbData); + app_assert(dwLen); + app_assert(gbMaxPlayers == 1); + + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + app_assert(dwChar < MAX_CHARACTERS); + + // encode file + char computername[MAX_COMPUTERNAME_LENGTH+1] = ENCRYPTNAME; + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + #if ENCRYPT_WITH_NAME + if (gbMaxPlayers > 1) GetComputerName(computername,&size); + #endif + EncodeFile(pbData,dwLen,dwDstBytes,computername); + + if (! open_archive_write(FALSE,dwChar)) + app_fatal("Unable to write to save file archive"); + MPQAddFile(pszName,pbData,dwDstBytes); + close_archive_write(TRUE,dwChar); +} + + +//****************************************************************** +//****************************************************************** +BYTE * ReadSaveFile(const char * pszName,DWORD * pdwLen) { + app_assert(pszName); + app_assert(pdwLen); + app_assert(gbMaxPlayers == 1); + + DWORD dwChar = name_2_file_index(plr[myplr]._pName); + app_assert(dwChar < MAX_CHARACTERS); + + HSARCHIVE hsArchive; + if (NULL == (hsArchive = open_archive_read(NULL,dwChar))) + app_fatal("Unable to open save file archive"); + + HSFILE hsFile; + if (! SFileOpenFileEx(hsArchive,pszName,0,&hsFile)) + app_fatal("Unable to open save file"); + + // allocate a buffer large enough for the file + *pdwLen = SFileGetFileSize(hsFile,NULL); + if (! *pdwLen) app_fatal("Invalid save file"); + BYTE * pbData = DiabloAllocPtrSig(*pdwLen,'SAVt'); + + DWORD dwBytes; + if (! SFileReadFile(hsFile,pbData,*pdwLen,&dwBytes,NULL)) + app_fatal("Unable to read save file"); + app_assert(dwBytes == *pdwLen); + + SFileCloseFile(hsFile); + close_archive_read(hsArchive); + + char computername[MAX_COMPUTERNAME_LENGTH+1] = ENCRYPTNAME; + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + #if ENCRYPT_WITH_NAME + if (gbMaxPlayers > 1) GetComputerName(computername,&size); + #endif + *pdwLen = DecodeFile(pbData,*pdwLen,computername); + if (! *pdwLen) app_fatal("Invalid save file"); + + return pbData; +} + + +//****************************************************************** +//****************************************************************** +void TimedUpdatePlayerFile(BOOL bForce) { + #define SAVE_TICKS (60*1000) // 60 seconds + static long slSaveTime = 0; + if (gbMaxPlayers == 1) return; + + long lCurrTime = (long) GetTickCount(); + if (bForce || lCurrTime - slSaveTime > SAVE_TICKS) { + slSaveTime = lCurrTime; + UpdatePlayerFile(); + } +} diff --git a/PLAYER.CPP b/PLAYER.CPP new file mode 100644 index 0000000..5e0fd48 --- /dev/null +++ b/PLAYER.CPP @@ -0,0 +1,4759 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Player file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/PLAYER.CPP 11 10-03-97 13:40 Jmcreynolds $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "sound.h" +#include "msg.h" +#include "multi.h" +#include "debug.h" +#include "engine.h" +#include "gendung.h" +#include "palette.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "missiles.h" +#include "spells.h" +#include "inv.h" +#include "lighting.h" +#include "cursor.h" +#include "control.h" +#include "effects.h" +#include "objects.h" +#include "town.h" +#include "towners.h" +#include "monstint.h" +#include "monstdat.h" +#include "gamemenu.h" +#include "stores.h" +#include "spelldat.h" +#include "path.h" +#include "quests.h" +#include "minitext.h" +#include "textdat.h" +#include "portal.h" +#include "themes.h" +#include "objdat.h" + +void SetPlrHandItem(ItemStruct *h, int idata); +void GetPlrHandSeed(ItemStruct *h); +void GetGoldSeed(int pnum, ItemStruct *h); +void SetPrlHandSeed(ItemStruct *h, int iseed); +void FixPlrWalkTags(int pnum); +void RemovePlrFromMap(int pnum); +void SetPlrHandGoldCurs(ItemStruct *h); + +extern BOOL GoldAutoPlace(int pnum); +extern HSARCHIVE ghsHFBardArchive; +extern HSARCHIVE ghsHFBarbarianArchive; +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ +// pjw.patch1.start +// PlayerStruct plr[MAX_PLRS]; +PlayerStruct * plr = NULL; +// pjw.patch1.end +int myplr; +int deathdelay; +BOOL deathflag; + +/*-----------------------------------------------------------------------* +** File Variables +**-----------------------------------------------------------------------*/ +// Init View offsets +int plrxoff[9] = { 0, 2, 0, 2, 1, 0, 1, 2, 1 }; +int plryoff[9] = { 0, 2, 2, 0, 1, 1, 0, 1, 2 }; + +int plrxoff2[9] = { 0, 1, 0, 1, 2, 0, 1, 2, 2 }; +int plryoff2[9] = { 0, 0, 1, 1, 0, 2, 2, 1, 2 }; + + +/*-----------------------------------------------------------------------*/ +char PlrGFXAnimLens[NUM_CLASSES][11] = { + // Warrior + // AS, AT, AW, BL, DT, Magic, HT, ST, WL, AFrame, SFrame + { 10, 16, 8, 2, 20, 20, 6, 20, 8, 9, 14 }, + // Rogue + // AS, AT, AW, BL, DT, Magic, HT, ST, WL, AFrame, SFrame + { 8, 18, 8, 4, 20, 16, 7, 20, 8, 10, 12 }, + // Sorceror + // AS, AT, AW, BL, DT, Magic, HT, ST, WL, AFrame, SFrame + { 8, 16, 8, 6, 20, 12, 8, 20, 8, 12, 8 }, + // Monk + // AS, AT, AW, BL, DT, Magic, HT, ST, WL, AFrame, SFrame + { 8, 16, 8, 3, 20, 18, 6, 20, 8, 12, 13 }, +// Fix this when we get art. + // Bard + // AS, AT, AW, BL, DT, Magic, HT, ST, WL, AFrame, SFrame + { 8, 18, 8, 4, 20, 16, 7, 20, 8, 10, 12 }, + // Barbarian + // AS, AT, AW, BL, DT, Magic, HT, ST, WL, AFrame, SFrame + { 10, 16, 8, 2, 20, 20, 6, 20, 8, 9, 14 }, +}; + +/*-----------------------------------------------------------------------*/ + +// Different walk velocities for different classes +int PlrWalkTbl[NUM_CLASSES][3] = { + { 2048, 1024, 512 }, // Warrior (8 frames) + //{ 2730, 1365, 682 }, // Warrior (6 frames) + { 2048, 1024, 512 }, // Rogue (8 frames) + //{ 2340, 1170, 585 }, // Rogue (7 frames) + { 2048, 1024, 512 }, // Sorceror (8 frames) + { 2048, 1024, 512 }, // Monk (8 frames) + { 2048, 1024, 512 }, // Bard (8 frames) + { 2048, 1024, 512 } }; // Barbarian (8 frames) + +// Different walk lengths for different classes +//int PlrWalkLenTbl[3] = { 6, 7, 8 }; +int PlrWalkLenTbl[NUM_CLASSES] = { 8, 8, 8, 8, 8, 8 }; + +extern DWORD gbWalkOn; // double speed walk + +/*-----------------------------------------------------------------------*/ + +int StrengthTbl[NUM_CLASSES] = { 30, 20, 15, 25, 20, 40}; +int MagicTbl[NUM_CLASSES] = { 10, 15, 35, 15, 20, 0}; +int DexterityTbl[NUM_CLASSES] = { 20, 30, 15, 25, 25, 20}; +int VitalityTbl[NUM_CLASSES] = { 25, 20, 20, 20, 20, 25}; + +//int ToHitTbl[NUM_CLASSES] = { 50, 50, 50 }; +int ToBlkTbl[NUM_CLASSES] = { 30, 20, 10, 25, 25, 30}; + +char *ClassStrTbl[NUM_CLASSES] = { "Warrior", + "Rogue", + "Sorceror", + "Monk", + "Bard", + "Barbarian" }; + +/*-----------------------------------------------------------------------*/ + +int MaxStats[NUM_CLASSES][4] = { + // Str, Mag, Dex, Vit. + { 250, 50, 60, 100 }, // warrior + { 55, 70, 250, 80 }, // rogue + { 45, 250, 85, 80 }, // sorceror + { 150, 80, 150, 80 }, // monk + { 120, 120, 120, 100 }, // bard + { 255, 0, 55, 150 }, // barbarian + }; + +/*-----------------------------------------------------------------------*/ + +#define MAX_EXPLVLS 50 + +long ExpLvlsTbl[MAX_EXPLVLS+1] = { +/* 0, // 0 Changed 11/5 Dave + 1000, // 1 + 2400, // 2 + 4353, // 3 + 7070, // 4 + 10837, // 5 + 16044, // 6 + 23217, // 7 + 33065, // 8 + 46542, // 9 + 64925, // 10 + 89917, // 11 + 123782, // 12 + 169516, // 13*/ + + 0, // 0 + 2000, // 1 + 4620, // 2 + 8040, // 3 + 12489, // 4 + 18258, // 5 + 25712, // 6 + 35309, // 7 + 47622, // 8 + 63364, // 9 + 83419, // 10 + 108879, // 11 + 141086, // 12 + 181683, // 13 + 231075, // 14 + 313656, // 15 + 424067, // 16 + 571190, // 17 + 766569, // 18 + 1025154, // 19 + 1366227, // 10 + 1814568, // 21 + 2401895, // 22 + 3168651, // 23 + 4166200, // 24 + 5459523, // 25 + 7130496, // 26 + 9281874, // 27 + 12042092, // 28 + 15571031, // 29 + 20066900, // 30 + 25774405, // 31 + 32994399, // 32 + 42095202, // 33 + 53525811, // 34 + 67831218, // 35 + 85670061, // 36 + 107834823, // 37 + 135274799, // 38 + 169122009, // 39 + 210720231, // 40 + 261657253, // 41 + 323800420, // 42 + 399335440, // 43 + 490808349, // 44 + 601170414, // 45 + 733825617, // 46 + 892680222, // 47 + 1082908612, // 48 + 1310707109, // 49 + 1583495809 }; // 50 + + +/*-----------------------------------------------------------------------* +** player animation files +**-----------------------------------------------------------------------*/ +static const char plrgfxlmh[] = "LMH"; +static const char plrgfxweap[] = "NUSDBAMHT"; +static const char sgcCharClass[NUM_CLASSES] = { 'W', 'R', 'S', 'M', 'B', 'C' }; +static const char sgcAlterCharClass[NUM_CLASSES] = { 'W', 'R', 'S', 'M', 'R', 'W'}; +static const char * const sgpszCharDir[NUM_CLASSES] = { + "Warrior","Rogue","Sorceror","Monk","Bard","Barbarian" +}; +static const char * const sgpszAlterCharDir[NUM_CLASSES] = { + "Warrior","Rogue","Sorceror","Monk","Rogue","Warrior" +}; + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetAnimPtrs(BYTE *pData, BYTE *pAnim[]) { + for (int i = 0; i < 8; i++) + pAnim[i] = pData + ((DWORD*)pData)[i]; +} + + +/*-----------------------------------------------------------------------* +** loads player anims based on bit flags +**-----------------------------------------------------------------------*/ +void LoadPlrGFX(int pnum,DWORD dwLoad) { + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("LoadPlrGFX: illegal player %d",pnum); + // get a pointer to the player + PlayerStruct * pPlayer = &plr[pnum]; + + // calculate which player type, weapon and armor values to use + #if IS_VERSION(SHAREWARE) + app_assert(pPlayer->_pClass == CLASS_WARRIOR); + #else + app_assert((DWORD) pPlayer->_pClass <= NUM_CLASSES); + #endif + + char szPlrType[16]; + char const * pszPlrPath = ""; + if ((pPlayer->_pClass == CLASS_BARD && ghsHFBardArchive == NULL) + || (pPlayer->_pClass == CLASS_BARBARIAN && ghsHFBarbarianArchive == NULL)) + { + sprintf( + szPlrType, + "%c%c%c", + sgcAlterCharClass[pPlayer->_pClass], // player class + plrgfxlmh[pPlayer->_pgfxnum >> PGFX_CSHIFT], // armor class + plrgfxweap[pPlayer->_pgfxnum & PGFX_MASK] // weapon + ); + pszPlrPath = sgpszAlterCharDir[pPlayer->_pClass]; + } else { + sprintf( + szPlrType, + "%c%c%c", + sgcCharClass[pPlayer->_pClass], // player class + plrgfxlmh[pPlayer->_pgfxnum >> PGFX_CSHIFT], // armor class + plrgfxweap[pPlayer->_pgfxnum & PGFX_MASK] // weapon + ); + pszPlrPath = sgpszCharDir[pPlayer->_pClass]; + } + // get player directory + + // load file + BYTE * pData; + BYTE ** ppAnim; + const char * pszAnim; + for (DWORD dwBit = 1; dwBit <= PGL_ALL; dwBit <<= 1) { + // load this graphic set? + if (! (dwBit & dwLoad)) continue; + + switch (dwBit) { + + case PGL_STAND: + // load dungeon/town stand + pszAnim = leveltype ? "AS" : "ST"; + pData = pPlayer->_pNData; + ppAnim = pPlayer->_pNAnim; + break; + + case PGL_WALK: + // load dungeon/town walk + pszAnim = leveltype ? "AW" : "WL"; + pData = pPlayer->_pWData; + ppAnim = pPlayer->_pWAnim; + break; + + case PGL_DEAD: + // dead anim only valid for guy holding no weapons + if ((pPlayer->_pgfxnum & PGFX_MASK) != PGFX_NGUY) continue; + pszAnim = "DT"; + pData = pPlayer->_pDData; + ppAnim = pPlayer->_pDAnim; + break; + + case PGL_ATTACK: + if (! leveltype) continue; + pszAnim = "AT"; + pData = pPlayer->_pAData; + ppAnim = pPlayer->_pAAnim; + break; + + case PGL_HIT: + if (! leveltype) continue; + pszAnim = "HT"; + pData = pPlayer->_pHData; + ppAnim = pPlayer->_pHAnim; + break; + + case PGL_LMAG: + if (! leveltype) continue; + pszAnim = "LM"; + pData = pPlayer->_pLData; + ppAnim = pPlayer->_pLAnim; + break; + + case PGL_FMAG: + if (! leveltype) continue; + pszAnim = "FM"; + pData = pPlayer->_pFData; + ppAnim = pPlayer->_pFAnim; + break; + + case PGL_TMAG: + if (! leveltype) continue; + pszAnim = "QM"; + pData = pPlayer->_pTData; + ppAnim = pPlayer->_pTAnim; + break; + + case PGL_BLOCK: + if (! leveltype) continue; + if (! pPlayer->_pBlockFlag) continue; + pszAnim = "BL"; + pData = pPlayer->_pBData; + ppAnim = pPlayer->_pBAnim; + break; + + default: + app_fatal("PLR:2"); + break; + } + + char szBuf[256]; + sprintf( + szBuf, + #if RLE_DRAW + "PlrGFX\\%s\\%s\\%s%s.CL2", + #else + "PlrGFX\\%s\\%s\\%s%s.CEL", + #endif + pszPlrPath, + szPlrType, + szPlrType, + pszAnim + ); + + app_assert(pData); + LoadFileWithMem(szBuf,pData); + SetAnimPtrs(pData,ppAnim); + pPlayer->_pGFXLoad |= dwBit; + } +} + + +/*-----------------------------------------------------------------------* +** loads all player anims +**-----------------------------------------------------------------------*/ +void InitPlayerGFX(int pnum) { + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("InitPlayerGFX: illegal player %d",pnum); + if ((plr[pnum]._pHitPoints >> HP_SHIFT) == 0) { + plr[pnum]._pgfxnum = PGFX_NGUY; + LoadPlrGFX(pnum, PGL_DEAD); + } else { + LoadPlrGFX(pnum,PGL_ALL); + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static DWORD calc_plr_mem(const char * pszAnim) { + DWORD dwMax = 0; + + for (DWORD dwClass = 0; dwClass < NUM_CLASSES; dwClass++) { + #if IS_VERSION(SHAREWARE) + if (dwClass != CLASS_WARRIOR) continue; + #endif + + for (const char * pszArmor = plrgfxlmh; *pszArmor; pszArmor++) { + #if IS_VERSION(SHAREWARE) + if (pszArmor != plrgfxlmh) break; + #endif + + for (const char * pszWeap = plrgfxweap; *pszWeap; pszWeap++) { + char szPlrType[16]; + char szBuf[256]; + + if ((dwClass == CLASS_BARD && ghsHFBardArchive == NULL) + || (dwClass == CLASS_BARBARIAN && ghsHFBarbarianArchive == NULL)) + { + sprintf( szPlrType, "%c%c%c", + sgcAlterCharClass[dwClass], + *pszArmor, + *pszWeap ); + sprintf( szBuf, + #if RLE_DRAW + "PlrGFX\\%s\\%s\\%s%s.CL2", + #else + "PlrGFX\\%s\\%s\\%s%s.CEL", + #endif + sgpszAlterCharDir[dwClass], + szPlrType, + szPlrType, + pszAnim + ); //whew + } else { + sprintf( szPlrType, "%c%c%c", + sgcCharClass[dwClass], + *pszArmor, + *pszWeap ); + sprintf( szBuf, + #if RLE_DRAW + "PlrGFX\\%s\\%s\\%s%s.CL2", + #else + "PlrGFX\\%s\\%s\\%s%s.CEL", + #endif + sgpszCharDir[dwClass], + szPlrType, + szPlrType, + pszAnim + ); //whew + } + + HSFILE hsFile; + if (! patSFileOpenFile(szBuf,&hsFile,TRUE)) + continue; + + app_assert(hsFile); + DWORD dwSize = patSFileGetFileSize(hsFile); + patSFileCloseFile(hsFile); + dwMax = max(dwMax,dwSize); + } + } + } + + return dwMax; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +// remember to update these numbers if we ever add another set of +// player graphics + +void InitPlrGFXMem(int pnum) { + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("InitPlrGFXMem: illegal player %d",pnum); + app_assert(! plr[pnum]._pNData); + + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL ) + ? 0x35E28 : max(calc_plr_mem("AS"),calc_plr_mem("ST")); + plr[pnum]._pNData = DiabloAllocPtrSig(dwMem,'PGFN'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x16EB9 : max(calc_plr_mem("AW"),calc_plr_mem("WL")); + plr[pnum]._pWData = DiabloAllocPtrSig(dwMem,'PGFW'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x40047 : calc_plr_mem("AT"); + plr[pnum]._pAData = DiabloAllocPtrSig(dwMem,'PGFA'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x16484 : calc_plr_mem("HT"); + plr[pnum]._pHData = DiabloAllocPtrSig(dwMem,'PGFH'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x4AD88 : calc_plr_mem("LM"); + plr[pnum]._pLData = DiabloAllocPtrSig(dwMem,'PGFL'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x67AED : calc_plr_mem("FM"); + plr[pnum]._pFData = DiabloAllocPtrSig(dwMem,'PGFF'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x92F55 : calc_plr_mem("QM"); + plr[pnum]._pTData = DiabloAllocPtrSig(dwMem,'PGFT'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x3A8A6 : calc_plr_mem("DT"); + plr[pnum]._pDData = DiabloAllocPtrSig(dwMem,'PGFD'); + } + { + static DWORD dwMem = (ghsHFBardArchive == NULL && ghsHFBarbarianArchive == NULL) + ? 0x10FE3 : calc_plr_mem("BL"); + plr[pnum]._pBData = DiabloAllocPtrSig(dwMem,'PGFB'); + } + + // no gfx loaded + plr[pnum]._pGFXLoad = 0; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreePlayerGFX(int pnum) { + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("FreePlayerGFX: illegal player %d",pnum); + DiabloFreePtr(plr[pnum]._pNData); + DiabloFreePtr(plr[pnum]._pWData); + DiabloFreePtr(plr[pnum]._pAData); + DiabloFreePtr(plr[pnum]._pHData); + DiabloFreePtr(plr[pnum]._pLData); + DiabloFreePtr(plr[pnum]._pFData); + DiabloFreePtr(plr[pnum]._pTData); + DiabloFreePtr(plr[pnum]._pDData); + DiabloFreePtr(plr[pnum]._pBData); + plr[pnum]._pGFXLoad = 0; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void NewPlrAnim(int pnum, BYTE *pAnim, int numFrames, int Delay, long width) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("NewPlrAnim: illegal player %d",pnum); + plr[pnum]._pAnimData = pAnim; + plr[pnum]._pAnimLen = numFrames; + plr[pnum]._pAnimFrame = 1; + plr[pnum]._pAnimCnt = 0; + plr[pnum]._pAnimDelay = Delay; + plr[pnum]._pAnimWidth = width; + plr[pnum]._pAnimWidth2 = (width - 64) >> 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ClearPlrPVars(int pnum) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("ClearPlrPVars: illegal player %d",pnum); + plr[pnum]._pVar1 = 0; + plr[pnum]._pVar2 = 0; + plr[pnum]._pVar3 = 0; + plr[pnum]._pVar4 = 0; + plr[pnum]._pVar5 = 0; + plr[pnum]._pVar6 = 0; + plr[pnum]._pVar7 = 0; + plr[pnum]._pVar8 = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlrAnims(int pnum) +{ + int gn,pc; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("SetPlrAnims: illegal player %d",pnum); + plr[pnum]._pNWidth = 96; + plr[pnum]._pWWidth = 96; + plr[pnum]._pAWidth = 128; + plr[pnum]._pHWidth = 96; + plr[pnum]._pSWidth = 96; + plr[pnum]._pDWidth = 128; + plr[pnum]._pBWidth = 96; + + pc = plr[pnum]._pClass; + if (leveltype == 0) { + plr[pnum]._pNFrames = PlrGFXAnimLens[pc][7]; + plr[pnum]._pWFrames = PlrGFXAnimLens[pc][8]; + plr[pnum]._pDFrames = PlrGFXAnimLens[pc][4]; + plr[pnum]._pSFrames = PlrGFXAnimLens[pc][5]; + plr[pnum]._pSFNum = PlrGFXAnimLens[pc][10]; + } + else { + plr[pnum]._pNFrames = PlrGFXAnimLens[pc][0]; + plr[pnum]._pWFrames = PlrGFXAnimLens[pc][2]; + plr[pnum]._pAFrames = PlrGFXAnimLens[pc][1]; + plr[pnum]._pHFrames = PlrGFXAnimLens[pc][6]; + plr[pnum]._pSFrames = PlrGFXAnimLens[pc][5]; + plr[pnum]._pDFrames = PlrGFXAnimLens[pc][4]; + plr[pnum]._pBFrames = PlrGFXAnimLens[pc][3]; + plr[pnum]._pAFNum = PlrGFXAnimLens[pc][9]; + plr[pnum]._pSFNum = PlrGFXAnimLens[pc][10]; + } + + gn = plr[pnum]._pgfxnum & PGFX_MASK; + if (pc == CLASS_WARRIOR) { + if (gn == PGFX_BGUY) { // Bow + if (leveltype != 0) plr[pnum]._pNFrames = 8; + plr[pnum]._pAWidth = 96; + plr[pnum]._pAFNum = 11; + } + else if (gn == PGFX_FGUY) { // Axe + plr[pnum]._pAFrames = 20; + plr[pnum]._pAFNum = 10; + } + else if (gn == PGFX_TGUY) { // Staff + plr[pnum]._pAFrames = 16; + plr[pnum]._pAFNum = 11; + } + } +#if !IS_VERSION(SHAREWARE) + else if (pc == CLASS_ROGUE) { + if (gn == PGFX_FGUY) { // Axe + plr[pnum]._pAFrames = 22; + plr[pnum]._pAFNum = 13; + } + else if (gn == PGFX_BGUY) { // Bow + plr[pnum]._pAFrames = 12; + plr[pnum]._pAFNum = 7; + } + else if (gn == PGFX_TGUY) { // Staff + plr[pnum]._pAFrames = 16; + plr[pnum]._pAFNum = 11; + } + } + else if (pc == CLASS_SORCEROR) { + plr[pnum]._pSWidth = 128; + + if (gn == PGFX_NGUY) { // No weapon + plr[pnum]._pAFrames = 20; + } + else if (gn == PGFX_SGUY) { // Shield only + plr[pnum]._pAFNum = 9; + } + else if (gn == PGFX_BGUY) { // Bow + plr[pnum]._pAFrames = 20; + plr[pnum]._pAFNum = 16; + } + else if (gn == PGFX_FGUY) { // Axe + plr[pnum]._pAFrames = 24; + plr[pnum]._pAFNum = 16; + } + } + + else if (pc == CLASS_MONK) + { + plr[pnum]._pNWidth = 112; + plr[pnum]._pWWidth = 112; + plr[pnum]._pAWidth = 130; + plr[pnum]._pHWidth = 98; + plr[pnum]._pSWidth = 114; + plr[pnum]._pDWidth = 160; + plr[pnum]._pBWidth = 98; + + switch(gn) + { + case PGFX_NGUY: + case PGFX_SGUY: // may want to slow this down + plr[pnum]._pAFrames = 12; + plr[pnum]._pAFNum = 7; + break; + case PGFX_BGUY: + plr[pnum]._pAFrames = 20; + plr[pnum]._pAFNum = 14; + break; + case PGFX_FGUY: + plr[pnum]._pAFrames = 23; + plr[pnum]._pAFNum = 14; + break; + case PGFX_TGUY: + plr[pnum]._pAFrames = 13; + plr[pnum]._pAFNum = 8; + break; + default: + break; + } + } + + // + // + // Fix this when the art arrives. + // + // + else if (pc == CLASS_BARD) + { + if (gn == PGFX_FGUY) { // Axe + plr[pnum]._pAFrames = 22; + plr[pnum]._pAFNum = 13; + } + else if (gn == PGFX_BGUY) { // Bow + plr[pnum]._pAFrames = 12; + plr[pnum]._pAFNum = 11; + } + else if (gn == PGFX_TGUY) { // Staff + plr[pnum]._pAFrames = 16; + plr[pnum]._pAFNum = 11; + } + else if (gn == PGFX_GUY) { // Sword and shield + plr[pnum]._pAFNum = 10; + } + else if (gn == PGFX_XGUY) { // Sword + plr[pnum]._pAFNum = 10; + } + } + else if (pc == CLASS_BARBARIAN) + { + if (gn == PGFX_FGUY) { // Axe + plr[pnum]._pAFrames = 20; + plr[pnum]._pAFNum = 8; + } + else if (gn == PGFX_BGUY) { // Bow + if (leveltype != 0) plr[pnum]._pNFrames = 8; + plr[pnum]._pAWidth = 96; + plr[pnum]._pAFNum = 11; + } + else if (gn == PGFX_TGUY) { // Staff + plr[pnum]._pAFrames = 16; + plr[pnum]._pAFNum = 11; + } + else if (gn == PGFX_ZGUY) { // Mace + plr[pnum]._pAFNum = 8; + } + else if (gn == PGFX_CGUY) { // Mace with Shield + plr[pnum]._pAFNum = 8; + } + } +#endif +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void PlrInitReserved(PlayerStruct * p) { + app_assert(p != NULL); +// REMEMBER -- every time you remove a variable from this +// list to rename it, it MUST be initialized in CreatePlayer() +// or you will screw up the character with unitialized data!!!! +// ALSO -- you MUST initialize the variable in UnPackPlayer() +// in packplr.cpp!!! + p->bReserved5 = 0; + p->bReserved6 = 0; + p->bReserved7 = 0; + p->bReserved8 = 0; + + p->wReserved2 = 0; + p->wReserved3 = 0; + p->wReserved4 = 0; + p->wReserved5 = 0; + p->wReserved6 = 0; + p->wReserved7 = 0; + p->wReserved8 = 0; + + p->dwReserved4 = 0; + p->dwReserved5 = 0; + p->dwReserved6 = 0; + p->dwReserved7 = 0; + p->dwReserved8 = 0; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CreatePlayer(int pnum, char c) { + + // This isn't good C++ but it beats the lack of initialization currently done. + memset(&plr[pnum], 0, sizeof(PlayerStruct)); + PlrInitReserved(&plr[pnum]); + + int i; + char vc; + +// dig.patch1.start.2/4/97 + // time() returns -1 if clock is set far ahead, e.g., the year 2097. + // Many customers have broken clock, resulting in all games being the same. + +// SetRndSeed((int) time(NULL)); + SetRndSeed((int) GetTickCount()); +// dig.patch1.end.2/4/97 + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("CreatePlayer: illegal player %d",pnum); + plr[pnum]._pClass = c; + + vc = StrengthTbl[c]; + if (vc < 0) vc = 0; + plr[pnum]._pStrength = vc; + plr[pnum]._pBaseStr = vc; + vc = MagicTbl[c]; + if (vc < 0) vc = 0; + plr[pnum]._pMagic = vc; + plr[pnum]._pBaseMag = vc; + vc = DexterityTbl[c]; + if (vc < 0) vc = 0; + plr[pnum]._pDexterity = vc; + plr[pnum]._pBaseDex = vc; + vc = VitalityTbl[c]; + if (vc < 0) vc = 0; + plr[pnum]._pVitality = vc; + plr[pnum]._pBaseVit = vc; + + plr[pnum]._pStatPts = 0; + + plr[pnum].pTownWarps = 0; + plr[pnum].pDungMsgs = 0; + plr[pnum].pHellfireMsgs = 0; + plr[pnum].pLvlLoad = 0; + plr[pnum].pDiabloKillLevel = 0; + plr[pnum]._gnDifficulty = D_NORMAL; + + + if (plr[pnum]._pClass == CLASS_MONK) + plr[pnum]._pDamageMod = ((plr[pnum]._pStrength + plr[pnum]._pDexterity) * plr[pnum]._pLevel) / 150; + else if (plr[pnum]._pClass == CLASS_ROGUE || + plr[pnum]._pClass == CLASS_BARD) + plr[pnum]._pDamageMod = ((plr[pnum]._pStrength + plr[pnum]._pDexterity) * plr[pnum]._pLevel) / 200; + else // Warrior and Barbarian + plr[pnum]._pDamageMod = (plr[pnum]._pStrength * plr[pnum]._pLevel) / 100; + plr[pnum]._pBaseToBlk = ToBlkTbl[c]; + + plr[pnum]._pHitPoints = (plr[pnum]._pVitality + 10) << HP_SHIFT; + if (plr[pnum]._pClass == CLASS_WARRIOR + || plr[pnum]._pClass == CLASS_BARBARIAN ) plr[pnum]._pHitPoints = plr[pnum]._pHitPoints << 1; + else if (plr[pnum]._pClass == CLASS_ROGUE || + plr[pnum]._pClass == CLASS_MONK || + plr[pnum]._pClass == CLASS_BARD) plr[pnum]._pHitPoints += (plr[pnum]._pHitPoints >> 1); + plr[pnum]._pMaxHP = plr[pnum]._pHitPoints; + plr[pnum]._pHPBase = plr[pnum]._pHitPoints; + plr[pnum]._pMaxHPBase = plr[pnum]._pHitPoints; + + plr[pnum]._pMana = plr[pnum]._pMagic << MANA_SHIFT; + if (plr[pnum]._pClass == CLASS_SORCEROR) plr[pnum]._pMana = plr[pnum]._pMana << 1; // 2x + else if( plr[pnum]._pClass == CLASS_BARD) plr[pnum]._pMana += (plr[pnum]._pMana * 3)/4; // 1.75 + else if (plr[pnum]._pClass == CLASS_ROGUE || + plr[pnum]._pClass == CLASS_MONK ) plr[pnum]._pMana += (plr[pnum]._pMana >> 1); // 1.5x + plr[pnum]._pMaxMana = plr[pnum]._pMana; + plr[pnum]._pManaBase = plr[pnum]._pMana; + plr[pnum]._pMaxManaBase = plr[pnum]._pMana; + + plr[pnum]._pLevel = 1; + plr[pnum]._pMaxLvl = plr[pnum]._pLevel; + + plr[pnum]._pExperience = 0; + plr[pnum]._pMaxExp = plr[pnum]._pExperience; + plr[pnum]._pNextExper = ExpLvlsTbl[1]; + + plr[pnum]._pArmorClass = 0; + + if (plr[pnum]._pClass == CLASS_BARBARIAN) { + plr[pnum]._pMagResist = 1; + plr[pnum]._pFireResist = 1; + plr[pnum]._pLghtResist = 1; + } + else { + plr[pnum]._pMagResist = 0; + plr[pnum]._pFireResist = 0; + plr[pnum]._pLghtResist = 0; + } + + plr[pnum]._pLightRad = PLRLRAD; + + plr[pnum]._pInfraFlag = FALSE; + + if (c == CLASS_WARRIOR) plr[pnum]._pAblSpells = (_int64)(1) << (SPL_REPAIR-1); + #if !IS_VERSION(SHAREWARE) + else if (c == CLASS_ROGUE) plr[pnum]._pAblSpells = (_int64)(1) << (SPL_DISARM-1); + else if (c == CLASS_SORCEROR) plr[pnum]._pAblSpells = (_int64)(1) << (SPL_RECHARGE-1); + else if (c == CLASS_MONK) plr[pnum]._pAblSpells = (__int64)(1) << (SPL_SHOWMAGITEMS-1); + else if (c == CLASS_BARD) plr[pnum]._pAblSpells = (_int64)(1) << (SPL_IDENTIFY-1); + else if (c == CLASS_BARBARIAN) plr[pnum]._pAblSpells = (_int64)(1) << (SPL_RAGE-1); + #endif + + if (c == CLASS_SORCEROR) plr[pnum]._pMemSpells = (_int64)(1) << (SPL_FIREBOLT-1); + else plr[pnum]._pMemSpells = 0; + + for (i = 0; i < 64; i++) + plr[pnum]._pSplLvl[i] = 0; + plr[pnum]._pSpellFlags = 0; + if (plr[pnum]._pClass == CLASS_SORCEROR) + plr[pnum]._pSplLvl[SPL_FIREBOLT] = 2; + + for (i = 0; i < 3; i++) plr[pnum]._pSplHotKey[i] = -1; + + if (c == CLASS_WARRIOR) plr[pnum]._pgfxnum = PGFX_GUY; + #if !IS_VERSION(SHAREWARE) + else if (c == CLASS_ROGUE) plr[pnum]._pgfxnum = PGFX_BGUY; + else if (c == CLASS_SORCEROR) plr[pnum]._pgfxnum = PGFX_TGUY; + else if (c == CLASS_MONK) plr[pnum]._pgfxnum = PGFX_TGUY; + else if (c == CLASS_BARD) plr[pnum]._pgfxnum = PGFX_GUY; + else if (c == CLASS_BARBARIAN) plr[pnum]._pgfxnum = PGFX_GUY; + #endif + + for (i = 0; i < NUMLEVELS; i++) + plr[pnum]._pLvlVisited[i] = FALSE; + for (i = 0; i < NUMSLEVELS; i++) + plr[pnum]._pSLvlVisited[i] = FALSE; + + plr[pnum]._pLvlChanging = FALSE; + plr[pnum].pTownWarps = 0; + plr[pnum].pLvlLoad = 0; + plr[pnum]._pIFlags2 = 0; + + plr[pnum]._pReflectCount = 0; + + InitDungMsgs(pnum); + + CreatePlrItems(pnum); + + SetRndSeed(0); +} + +// drb.patch1.start.2/05/97 +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int CalcStatDiff(int pnum) +{ + int c = plr[pnum]._pClass; + int d = MaxStats[c][0] - plr[pnum]._pBaseStr; + d += MaxStats[c][1] - plr[pnum]._pBaseMag; + d += MaxStats[c][2] - plr[pnum]._pBaseDex; + d += MaxStats[c][3] - plr[pnum]._pBaseVit; + return(d); +} +// drb.patch1.end.2/05/97 + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void NextPlrLevel(int pnum) { + long l; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("NextPlrLevel: illegal player %d",pnum); + plr[pnum]._pLevel++; + plr[pnum]._pMaxLvl++; + CalcPlrInv(pnum,TRUE); // added by donald 8/26 + + // drb.patch1.start.2/05/97 + // plr[pnum]._pStatPts += 5; + if (CalcStatDiff(pnum) < 5) plr[pnum]._pStatPts = CalcStatDiff(pnum); + else plr[pnum]._pStatPts += 5; + // drb.patch1.end.2/05/97 + + plr[pnum]._pNextExper = ExpLvlsTbl[plr[pnum]._pLevel]; + + if (plr[pnum]._pClass == CLASS_SORCEROR) + { + l = 1 << HP_SHIFT; + } + else + { + l = 2 << HP_SHIFT; + } + + if (gbMaxPlayers == 1) l++; + plr[pnum]._pMaxHP += l; + plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pMaxHPBase += l; + plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + if (pnum == myplr) drawhpflag = TRUE; + + if (plr[pnum]._pClass == CLASS_WARRIOR) + { + l = 1 << MANA_SHIFT; + } + else if ( plr[pnum]._pClass == CLASS_BARBARIAN) + { + l = 0; + } + else + { + l = 2 << MANA_SHIFT; + } + if (gbMaxPlayers == 1) l++; + plr[pnum]._pMaxMana += l; + plr[pnum]._pMaxManaBase += l; + + if (!(plr[pnum]._pIFlags & IAF_LMANA )) { + plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + } + if (pnum == myplr + && plr[pnum]._pMana > 0) drawmanaflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddPlrExperience(int pnum, int lvl, long exp) +{ + if (pnum != myplr) return; + if ((DWORD)myplr >= MAX_PLRS) + app_fatal("AddPlrExperience: illegal player %d",myplr); + if (plr[myplr]._pHitPoints <= 0) return; + + double v = (1 + (((double)lvl - (double)plr[pnum]._pLevel) * 0.1)) * (double)exp; + long e = long(v); + if (e < 0) e = 0; + + // put limits on how fast you go up levels + if (gbMaxPlayers > 1) { + long lLevel = max(0,plr[pnum]._pLevel); + lLevel = min(lLevel,MAX_EXPLVLS); + long lMax = ExpLvlsTbl[lLevel] / 20; + e = min(e,lMax); + lMax = lLevel * 200; + e = min(e,lMax); + } + + // upgrade player + plr[pnum]._pExperience += e; + if ((DWORD) plr[pnum]._pExperience > 2000000000) + plr[pnum]._pExperience = 2000000000; + if (plr[pnum]._pExperience >= ExpLvlsTbl[MAX_EXPLVLS-1]) { + plr[pnum]._pLevel = MAX_EXPLVLS; + } + else { + for (int l = 0; plr[pnum]._pExperience >= ExpLvlsTbl[l]; l++); + if (l != plr[pnum]._pLevel) { + l -= plr[pnum]._pLevel; + for (int i = 0; i < l; i++) + NextPlrLevel(pnum); + } + NetSendCmdParam1(FALSE, CMD_PLRLEVEL, plr[myplr]._pLevel); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddPlrMonstExper(int lvl, long exp, char pmask) +{ + int totplrs = 0; + for (int i = 0; i < MAX_PLRS; i++) + if (pmask & (1 << i)) totplrs++; + + if (totplrs) { + long myexp = exp / totplrs; + if (pmask & (1 << myplr)) AddPlrExperience(myplr, lvl, myexp); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitPlayer(int pnum, BOOL FirstTime) +{ + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("InitPlayer: illegal player %d",pnum); + PlrInitReserved(&plr[pnum]); + + if (FirstTime) { + /*if (plr[pnum]._pClass == CLASS_WARRIOR) { + plr[pnum]._pRSpell = SPL_REPAIR; + plr[pnum]._pRSplType = SPT_ABILITY; + } + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) { + plr[pnum]._pRSpell = SPL_DISARM; + plr[pnum]._pRSplType = SPT_ABILITY; + } + else if (plr[pnum]._pClass == CLASS_SORCEROR) { + plr[pnum]._pRSpell = SPL_FIREBOLT; + plr[pnum]._pRSplType = SPT_MEMORIZED; + } + else if (plr[pnum]._pClass == CLASS_MONK) { + plr[pnum]._pRSpell = SPL_SHOWMAGITEMS; + plr[pnum]._pRSplType = SPT_ABILITY; + } + else if (plr[pnum]._pClass == CLASS_BARD) { + plr[pnum]._pRSpell = SPL_IDENTIFY; + plr[pnum]._pRSplType = SPT_ABILITY; + } + else if (plr[pnum]._pClass == CLASS_BARBARIAN) { + plr[pnum]._pRSpell = SPL_RAGE; + plr[pnum]._pRSplType = SPT_ABILITY; + } + #endif + */ + + plr[pnum]._pRSplType = SPT_NONE; + plr[pnum]._pRSpell = -1; + + plr[pnum]._pSBkSpell = -1; + plr[pnum]._pSpell = plr[pnum]._pRSpell; + plr[pnum]._pSplType = plr[pnum]._pRSplType; + + if ((plr[pnum]._pgfxnum & PGFX_MASK) == PGFX_BGUY) + plr[pnum]._pwtype = WEAP_RANGE; + else + plr[pnum]._pwtype = WEAP_H2H; + } + + if ((plr[pnum].plrlevel == currlevel) || (leveldebug)) { + SetPlrAnims(pnum); + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + plr[pnum]._pxvel = 0; + plr[pnum]._pyvel = 0; + ClearPlrPVars(pnum); + + if ((plr[pnum]._pHitPoints >> HP_SHIFT) > 0) { + plr[pnum]._pmode = PM_STAND; + NewPlrAnim(pnum, plr[pnum]._pNAnim[DIR_D], plr[pnum]._pNFrames, 3, plr[pnum]._pNWidth); + plr[pnum]._pAnimFrame = random(2, plr[pnum]._pNFrames - 1) + 1; + plr[pnum]._pAnimCnt = random(2, 3); + } else { + plr[pnum]._pmode = PM_DEATH; + NewPlrAnim(pnum, plr[pnum]._pDAnim[DIR_D], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth); + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1; + plr[pnum]._pVar8 = plr[pnum]._pAnimLen << 1; + } + + plr[pnum]._pdir = DIR_D; + plr[pnum]._peflag = 0; + + if (pnum == myplr) { + // put me in my optimal space + if ((!FirstTime) || (currlevel != 0)) { + plr[pnum]._px = ViewX; + plr[pnum]._py = ViewY; + } + plr[pnum]._ptargx = plr[pnum]._px; + plr[pnum]._ptargy = plr[pnum]._py; + } + else { + // Make other players target position where he is now + plr[pnum]._ptargx = plr[pnum]._px; + plr[pnum]._ptargy = plr[pnum]._py; + + // Find space for player + for (int i = 0; i < sizeof(plrxoff2)/sizeof(plrxoff2[0]) - 1; i++) { + if (PosOkPlayer( + pnum, + plr[pnum]._px + plrxoff2[i], + plr[pnum]._py + plryoff2[i] + )) break; + } + plr[pnum]._px += plrxoff2[i]; + plr[pnum]._py += plryoff2[i]; + } + + plr[pnum]._pfutx = plr[pnum]._px; + plr[pnum]._pfuty = plr[pnum]._py; + plr[pnum].walkpath[0] = PCMD_NOTHING; // No buffered walking etc + plr[pnum].destAction = PCMD_NOTHING; + + if (pnum == myplr) + plr[pnum]._plid = AddLight(plr[pnum]._px, plr[pnum]._py, plr[pnum]._pLightRad); + else + plr[pnum]._plid = -1; + plr[pnum]._pvid = AddVision(plr[pnum]._px, plr[pnum]._py, + plr[pnum]._pLightRad, pnum==myplr); + } + + if (plr[pnum]._pClass == CLASS_WARRIOR) + plr[pnum]._pAblSpells = (_int64)(1) << (SPL_REPAIR-1); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) + plr[pnum]._pAblSpells = (_int64)(1) << (SPL_DISARM-1); + else if (plr[pnum]._pClass == CLASS_SORCEROR) + plr[pnum]._pAblSpells = (_int64)(1) << (SPL_RECHARGE-1); + else if (plr[pnum]._pClass == CLASS_MONK) + plr[pnum]._pAblSpells = (__int64)(1) << (SPL_SHOWMAGITEMS-1); + else if (plr[pnum]._pClass == CLASS_BARD) + plr[pnum]._pAblSpells = (_int64)(1) << (SPL_IDENTIFY-1); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) + plr[pnum]._pAblSpells = (_int64)(1) << (SPL_RAGE-1); + #endif + +#if CHEATS + if (simplecheat && FirstTime) { + plr[pnum]._pMemSpells |= (_int64)(1) << SPL_TELE; + if (! plr[myplr]._pSplLvl[SPL_TELE]) + plr[myplr]._pSplLvl[SPL_TELE] = 1; + } + if (cheatflag && FirstTime) { + //splhold = plr[pnum]._pMemSpells; + plr[pnum]._pMemSpells = 0x0fffffffffffffff; + //plr[pnum]._pMemSpells = 0x0000000000000000 | (((__int64)1) << (SPL_NOVA-1)); + //plr[pnum]._pMemSpells = plr[pnum]._pMemSpells | (((__int64)1) << (SPL_TELE-1)); + } +#endif + + plr[pnum]._pNextExper = ExpLvlsTbl[plr[pnum]._pLevel]; + plr[pnum]._pInvincible = FALSE; + + if (pnum == myplr) { + deathdelay = 0; + deathflag = FALSE; + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = SCRL_NONE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitMultiView() +{ + if ((DWORD)myplr >= MAX_PLRS) + app_fatal("InitPlayer: illegal player %d",myplr); + ViewX = plr[myplr]._px; + ViewY = plr[myplr]._py; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckEFlag(int pnum, int flag2) +{ + int tx,ty,tv; + int t; + WORD *mt; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("InitPlayer: illegal player %d",pnum); + tx = plr[pnum]._px - 1; + ty = plr[pnum]._py + 1; + tv = 0; + mt = &dMT2[CalcRot(tx,ty)].mt[0]; + for(t = 2; t < 10; t++) + tv |= mt[t]; + tv |= dSpecial[tx][ty]; + tv |= nSolidTable[dPiece[tx][ty]]; + if (tv != 0) plr[pnum]._peflag = 1; + else plr[pnum]._peflag = 0; + + if ((flag2 == E_DOUBLE) && (plr[pnum]._peflag == 1)) { + tx = plr[pnum]._px; + ty = plr[pnum]._py + 2; + tv = 0; + mt = &dMT2[CalcRot(tx,ty)].mt[0]; + for(t = 2; t < 10; t++) + tv |= mt[t]; + tv |= dSpecial[tx][ty]; + if (tv == 0) { + tx = plr[pnum]._px - 2; + ty = plr[pnum]._py + 1; + tv = 0; + mt = &dMT2[CalcRot(tx,ty)].mt[0]; + for(t = 2; t < 10; t++) + tv |= mt[t]; + tv |= dSpecial[tx][ty]; + if (tv != 0) plr[pnum]._peflag = 2; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int PlrGetDir(int pnum, int i) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PlrGetDir: illegal player %d",pnum); + return GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mx, monster[i]._my); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PlrGetDirXY(int pnum, int xx, int yy) +{ + int d; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PlrGetDirXY: illegal player %d",pnum); + d = GetDirection(plr[pnum]._px, plr[pnum]._py, xx, yy); + if ((plr[pnum]._px == xx) && (plr[pnum]._py == yy)) d = plr[pnum]._pdir; + return (d); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL SolidLoc(int x, int y) { + return nSolidTable[dPiece[x][y]]; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL PlrDirOK(int i, int pdir) { + if ((DWORD)i >= MAX_PLRS) + app_fatal("PlrDirOK: illegal player %d",i); + long fx = plr[i]._px + offset_x[pdir]; + long fy = plr[i]._py + offset_y[pdir]; + if (fx < 0) return FALSE; // SKing fix Dave 4/3 + if (dPiece[fx][fy] == 0) return FALSE; + if (! PosOkPlayer(i, fx, fy)) return FALSE; + + BOOL ret = TRUE; + if(ret && pdir == DIR_R) ret = !SolidLoc(fx, fy+1) && !(dFlags[fx][fy+1] & BFLAG_PLRLR); + if(ret && pdir == DIR_L) ret = !SolidLoc(fx+1, fy) && !(dFlags[fx+1][fy] & BFLAG_PLRLR); +// if(ret && pdir == DIR_U) ret = !SolidLoc(fx+1, fy) && !SolidLoc(fx, fy+1); +// if(ret && pdir == DIR_D) ret = !SolidLoc(fx-1, fy) && !SolidLoc(fx, fy-1); + return ret; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PlrClrTrans(int x, int y) +{ + int i,j; + char v; + + for (j = y-1; j <= y+1; j++) { + for (i = x-1; i <= x+1; i++) { + v = dTransVal[i][j]; + TransList[v] = FALSE; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PlrDoTrans(int x, int y) +{ + int i,j; + char v; + + if ((leveltype == 1) || (leveltype == 2)) { + for (j = y-1; j <= y+1; j++) { + for (i = x-1; i <= x+1; i++) { + if (!nSolidTable[dPiece[i][j]]) { + v = dTransVal[i][j]; + if (v != 0) TransList[v] = TRUE; + } + } + } + } else TransList[1] = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPlayerOld(int pnum) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("SetPlayerOld: illegal player %d",pnum); + plr[pnum]._poldx = plr[pnum]._px; + plr[pnum]._poldy = plr[pnum]._py; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FixPlayerLocation(int pnum,int bDir) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("FixPlayerLocation: illegal player %d",pnum); + plr[pnum]._pfutx = plr[pnum]._px; + plr[pnum]._pfuty = plr[pnum]._py; + + plr[pnum]._ptargx = plr[pnum]._px; + plr[pnum]._ptargy = plr[pnum]._py; + + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + CheckEFlag(pnum, E_SINGLE); + plr[pnum]._pdir = bDir; + + if (pnum == myplr) { + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = SCRL_NONE; + ViewX = plr[pnum]._px; + ViewY = plr[pnum]._py; + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void StartStand(int pnum, int dir) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartStand: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + if ((plr[pnum]._pGFXLoad & PGL_STAND) == 0) LoadPlrGFX(pnum, PGL_STAND); + NewPlrAnim(pnum, plr[pnum]._pNAnim[dir], plr[pnum]._pNFrames, 3, plr[pnum]._pNWidth); + plr[pnum]._pmode = PM_STAND; + FixPlayerLocation(pnum,dir); + FixPlrWalkTags(pnum); + dPlayer[plr[pnum]._px][plr[pnum]._py] = 1 + (char)pnum; + SetPlayerOld(pnum); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void StartWalkStand(int pnum) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartWalkStand: illegal player %d",pnum); + plr[pnum]._pmode = PM_STAND; + plr[pnum]._pfutx = plr[pnum]._px; + plr[pnum]._pfuty = plr[pnum]._py; + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + CheckEFlag(pnum, E_SINGLE); + if (pnum == myplr) { + ScrollInfo._sxoff = 0; + ScrollInfo._syoff = 0; + ScrollInfo._sdir = SCRL_NONE; + ViewX = plr[pnum]._px; + ViewY = plr[pnum]._py; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PM_ChangeLightOff(int pnum) +{ + int lx,ly; + int signx,signy; + static BYTE fix[] = {0,0,3,3,3,6,6,6,8}; + int totx, toty; + int oldtotx, oldtoty; + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_ChangeLightOff: illegal player %d",pnum); + LightListStruct * light = &LightList[plr[pnum]._plid]; + + // Convert from screen pixel offsets to dungeon coordinates + // i.e., 45 degree rotation + lx = (plr[pnum]._pxoff + (plr[pnum]._pyoff << 1)); + ly = ((plr[pnum]._pyoff << 1) - plr[pnum]._pxoff); + + // Divide these values by 8, because lighting offsets have + // 8 subdivisions per tile. + if (lx < 0) + { + signx = -1; + lx = -lx; + } + else + signx = 1; + + if (ly < 0) + { + signy = -1; + ly = -ly; + } + else + signy = 1; + + lx = lx >> 3; + ly = ly >> 3; + + // Then, fix the offset, because + // the player lighting looks bad with full lighting resolution. +// lx = fix[lx]; +// ly = fix[ly]; + + lx *= signx; + ly *= signy; + + totx = (light->_lx << 3) + lx; + toty = (light->_ly << 3) + ly; + + oldtotx = (light->_lx << 3) + light->_xoff; + oldtoty = (light->_ly << 3) + light->_yoff; + + if(abs(totx-oldtotx) >= 3 || abs(toty-oldtoty) >= 3) + ChangeLightOff(plr[pnum]._plid, lx, ly); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PM_ChangeOffset(int pnum) +{ + long xo, yo; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_ChangeOffset: illegal player %d",pnum); + plr[pnum]._pVar8++; + + xo = plr[pnum]._pVar6 >> 8; + yo = plr[pnum]._pVar7 >> 8; +#if 0 + plr[pnum]._pVar6 += plr[pnum]._pxvel; + plr[pnum]._pVar7 += plr[pnum]._pyvel; +#endif + + plr[pnum]._pVar6 += plr[pnum]._pxvel; + plr[pnum]._pVar7 += plr[pnum]._pyvel; + + if (currlevel == 0 && gbWalkOn) // double-speed walk + { + plr[pnum]._pVar6 += plr[pnum]._pxvel; + plr[pnum]._pVar7 += plr[pnum]._pyvel; + } + + plr[pnum]._pxoff = plr[pnum]._pVar6 >> 8; + plr[pnum]._pyoff = plr[pnum]._pVar7 >> 8; + xo -= (plr[pnum]._pVar6 >> 8); + yo -= (plr[pnum]._pVar7 >> 8); + if ((pnum == myplr) && (ScrollInfo._sdir != SCRL_NONE)) { + ScrollInfo._sxoff += xo; + ScrollInfo._syoff += yo; + } + PM_ChangeLightOff(pnum); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int scrldir) +{ + long fx,fy; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartWalk: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + SetPlayerOld(pnum); + fx = plr[pnum]._px + xadd; + fy = plr[pnum]._py + yadd; + if (PlrDirOK(pnum, EndDir)) { + //PlrClrTrans(plr[pnum]._px, plr[pnum]._py); + //PlrDoTrans(fx, fy); + plr[pnum]._pfutx = fx; + plr[pnum]._pfuty = fy; + if (pnum == myplr) { + ScrollInfo._sdx = plr[pnum]._px - ViewX; + ScrollInfo._sdy = plr[pnum]._py - ViewY; + } + dPlayer[fx][fy] = -1 - (char)pnum; + plr[pnum]._pmode = PM_WALK; + plr[pnum]._pxvel = xvel; + plr[pnum]._pyvel = yvel; + plr[pnum]._pxoff = 0; + plr[pnum]._pyoff = 0; + plr[pnum]._pVar1 = xadd; + plr[pnum]._pVar2 = yadd; + plr[pnum]._pVar3 = EndDir; + if ((plr[pnum]._pGFXLoad & PGL_WALK) == 0) LoadPlrGFX(pnum, PGL_WALK); + NewPlrAnim(pnum, plr[pnum]._pWAnim[EndDir], plr[pnum]._pWFrames, 0, plr[pnum]._pWWidth); + plr[pnum]._pdir = EndDir; + plr[pnum]._pVar6 = 0; + plr[pnum]._pVar7 = 0; + plr[pnum]._pVar8 = 0; + CheckEFlag(pnum, E_SINGLE); + if (pnum == myplr) { + if (svgamode) { + if ((abs(ScrollInfo._sdx) < 3) && (abs(ScrollInfo._sdy) < 3)) ScrollInfo._sdir = scrldir; + else ScrollInfo._sdir = SCRL_NONE; + } else { + if ((abs(ScrollInfo._sdx) < 2) && (abs(ScrollInfo._sdy) < 2)) ScrollInfo._sdir = scrldir; + else ScrollInfo._sdir = SCRL_NONE; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, + int xadd, int yadd, int EndDir, int scrldir) +{ + long fx,fy; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartWalk2: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + SetPlayerOld(pnum); + fx = plr[pnum]._px + xadd; + fy = plr[pnum]._py + yadd; + if (PlrDirOK(pnum, EndDir)) { + //PlrClrTrans(plr[pnum]._px, plr[pnum]._py); + //PlrDoTrans(fx, fy); + plr[pnum]._pfutx = fx; + plr[pnum]._pfuty = fy; + if (pnum == myplr) { + ScrollInfo._sdx = plr[pnum]._px - ViewX; + ScrollInfo._sdy = plr[pnum]._py - ViewY; + } + dPlayer[plr[pnum]._px][plr[pnum]._py] = -1 - (char)pnum; + plr[pnum]._pVar1 = plr[pnum]._px; + plr[pnum]._pVar2 = plr[pnum]._py; + plr[pnum]._px = fx; + plr[pnum]._py = fy; + dPlayer[plr[pnum]._px][plr[pnum]._py] = 1 + (char)pnum; + plr[pnum]._pxoff = xoff; + plr[pnum]._pyoff = yoff; + ChangeLightXY(plr[pnum]._plid, plr[pnum]._px, plr[pnum]._py); + PM_ChangeLightOff(pnum); + plr[pnum]._pmode = PM_WALK2; + plr[pnum]._pxvel = xvel; + plr[pnum]._pyvel = yvel; + plr[pnum]._pVar6 = xoff << 8; + plr[pnum]._pVar7 = yoff << 8; + plr[pnum]._pVar3 = EndDir; + if ((plr[pnum]._pGFXLoad & PGL_WALK) == 0) LoadPlrGFX(pnum, PGL_WALK); + NewPlrAnim(pnum, plr[pnum]._pWAnim[EndDir], plr[pnum]._pWFrames, 0, plr[pnum]._pWWidth); + plr[pnum]._pdir = EndDir; + plr[pnum]._pVar8 = 0; + if (EndDir == DIR_DR) CheckEFlag(pnum, E_DOUBLE); + else CheckEFlag(pnum, E_SINGLE); + if (pnum == myplr) { + if (svgamode) { + if ((abs(ScrollInfo._sdx) < 3) && (abs(ScrollInfo._sdy) < 3)) ScrollInfo._sdir = scrldir; + else ScrollInfo._sdir = SCRL_NONE; + } else { + if ((abs(ScrollInfo._sdx) < 2) && (abs(ScrollInfo._sdy) < 2)) ScrollInfo._sdir = scrldir; + else ScrollInfo._sdir = SCRL_NONE; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, + int xadd, int yadd, int txa, int tya, int EndDir, int scrldir) +{ + long fx,fy; + long tx,ty; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartWalk3: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + SetPlayerOld(pnum); + fx = plr[pnum]._px + xadd; + fy = plr[pnum]._py + yadd; + tx = plr[pnum]._px + txa; // Temp location for drawing + ty = plr[pnum]._py + tya; + if (PlrDirOK(pnum, EndDir)) { + //PlrClrTrans(plr[pnum]._px, plr[pnum]._py); + //PlrDoTrans(fx, fy); + plr[pnum]._pfutx = fx; + plr[pnum]._pfuty = fy; + if (pnum == myplr) { + ScrollInfo._sdx = plr[pnum]._px - ViewX; + ScrollInfo._sdy = plr[pnum]._py - ViewY; + } + dPlayer[plr[pnum]._px][plr[pnum]._py] = -1 - (char)pnum; + dPlayer[fx][fy] = -1 - (char)pnum; + plr[pnum]._pVar4 = tx; + plr[pnum]._pVar5 = ty; + dFlags[tx][ty] |= BFLAG_PLRLR; + plr[pnum]._pxoff = xoff; + plr[pnum]._pyoff = yoff; + if(leveltype) + { + ChangeLightXY(plr[pnum]._plid, tx, ty); + PM_ChangeLightOff(pnum); + } + plr[pnum]._pmode = PM_WALK3; + plr[pnum]._pxvel = xvel; + plr[pnum]._pyvel = yvel; + plr[pnum]._pVar1 = fx; + plr[pnum]._pVar2 = fy; + plr[pnum]._pVar6 = xoff << 8; + plr[pnum]._pVar7 = yoff << 8; + plr[pnum]._pVar3 = EndDir; + if ((plr[pnum]._pGFXLoad & PGL_WALK) == 0) LoadPlrGFX(pnum, PGL_WALK); + NewPlrAnim(pnum, plr[pnum]._pWAnim[EndDir], plr[pnum]._pWFrames, 0, plr[pnum]._pWWidth); + plr[pnum]._pdir = EndDir; + plr[pnum]._pVar8 = 0; + CheckEFlag(pnum, E_SINGLE); + if (pnum == myplr) { + if (svgamode) { + if ((abs(ScrollInfo._sdx) < 3) && (abs(ScrollInfo._sdy) < 3)) ScrollInfo._sdir = scrldir; + else ScrollInfo._sdir = SCRL_NONE; + } else { + if ((abs(ScrollInfo._sdx) < 2) && (abs(ScrollInfo._sdy) < 2)) ScrollInfo._sdir = scrldir; + else ScrollInfo._sdir = SCRL_NONE; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartAttack(int pnum, int d) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartAttack: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + if ((plr[pnum]._pGFXLoad & PGL_ATTACK) == 0) LoadPlrGFX(pnum, PGL_ATTACK); + NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth); + + plr[pnum]._pmode = PM_ATTACK; + FixPlayerLocation(pnum,d); + SetPlayerOld(pnum); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartRangeAttack(int pnum, int d, int dx, int dy) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartRangeAttack: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + if ((plr[pnum]._pGFXLoad & PGL_ATTACK) == 0) LoadPlrGFX(pnum, PGL_ATTACK); + NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth); + + plr[pnum]._pmode = PM_RATTACK; + FixPlayerLocation(pnum,d); + SetPlayerOld(pnum); + plr[pnum]._pVar1 = dx; + plr[pnum]._pVar2 = dy; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartPlrBlock(int pnum, int dir) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartPlrBlock: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + PlaySfxLoc(IS_ISWORD, plr[pnum]._px, plr[pnum]._py); + + if ((plr[pnum]._pGFXLoad & PGL_BLOCK) == 0) LoadPlrGFX(pnum, PGL_BLOCK); + NewPlrAnim(pnum, plr[pnum]._pBAnim[dir], plr[pnum]._pBFrames, 2, plr[pnum]._pBWidth); + plr[pnum]._pmode = PM_BLOCK; + FixPlayerLocation(pnum,dir); + SetPlayerOld(pnum); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartSpell(int pnum, int d, int cx, int cy) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartSpell: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + if (leveltype != 0) { + switch (spelldata[plr[pnum]._pSpell].sType) { + case ST_FIRE : + if ((plr[pnum]._pGFXLoad & PGL_FMAG) == 0) LoadPlrGFX(pnum, PGL_FMAG); + NewPlrAnim(pnum, plr[pnum]._pFAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth); + break; + case ST_LIGHT : + if ((plr[pnum]._pGFXLoad & PGL_LMAG) == 0) LoadPlrGFX(pnum, PGL_LMAG); + NewPlrAnim(pnum, plr[pnum]._pLAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth); + break; + case ST_MISC : + if ((plr[pnum]._pGFXLoad & PGL_TMAG) == 0) LoadPlrGFX(pnum, PGL_TMAG); + NewPlrAnim(pnum, plr[pnum]._pTAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth); + break; + } + } + PlaySfxLoc(spelldata[plr[pnum]._pSpell].sSFX, plr[pnum]._px, plr[pnum]._py); + + plr[pnum]._pmode = PM_SPELL; + FixPlayerLocation(pnum,d); + SetPlayerOld(pnum); + + plr[pnum]._pVar1 = cx; + plr[pnum]._pVar2 = cy; + //if (((plr[pnum]._pSplFrom == SPL_FROMBK) || (plr[pnum]._pSplFrom == SPL_FROMR)) && (pnum == myplr)) + plr[pnum]._pVar4 = GetSpellLevel(pnum, plr[pnum]._pSpell); + //else + // plr[pnum]._pVar4 = 1; + plr[pnum]._pVar8 = 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FixPlrWalkTags(int pnum) { + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("FixPlrWalkTags: illegal player %d",pnum); + + int pp = pnum + 1; + int pn = -1 - pnum; + int px = plr[pnum]._poldx; + int py = plr[pnum]._poldy; + for (int y = py - 1; y <= py + 1; y++) { + for (int x = px - 1; x <= px + 1; x++) { + if (x < 0 || x >= DMAXX) continue; + if (y < 0 || y >= DMAXY) continue; + if (dPlayer[x][y] == pp || dPlayer[x][y] == pn) + dPlayer[x][y] = 0; + } + } + + if (px < 0 || px >= DMAXX-1) return; + if (py < 0 || py >= DMAXY-1) return; + dFlags[px+1][py+0] &= BFMASK_PLRLR; + dFlags[px+0][py+1] &= BFMASK_PLRLR; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RemovePlrFromMap(int pnum) +{ + int pp = pnum + 1; + int pn = -1 - pnum; + int x,y; + for (y = 1; y < DMAXY; y++) { + for (x = 1; x < DMAXX; x++) { + if (((dPlayer[x][y-1] == pn) || (dPlayer[x-1][y] == pn)) && (dFlags[x][y] & BFLAG_PLRLR)) + dFlags[x][y] &= BFMASK_PLRLR; + } + } + for (y = 0; y < DMAXY; y++) { + for (x = 0; x < DMAXX; x++) { + if (dPlayer[x][y] == pp || dPlayer[x][y] == pn) + dPlayer[x][y] = 0; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartPlrHit(int pnum, int dam, BOOL forcehit) +{ + int pd; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartPlrHit: illegal player %d",pnum); + if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) { + StartPlrKill(pnum, KILL_UNKNOWN); + return; + } + + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySfxLoc(PS_MAGE69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySfxLoc(PS_MONK69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySfxLoc(PS_BARD69, plr[pnum]._px, plr[pnum]._py); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySfxLoc(PS_BARBARIAN69, plr[pnum]._px, plr[pnum]._py); + #endif + //PlaySfxLoc(PS_LGHIT, plr[pnum]._px, plr[pnum]._py); + + // Update hit bar + drawhpflag = TRUE; + + if (plr[pnum]._pClass == CLASS_BARBARIAN) + { + if ((dam >> HP_SHIFT) < (plr[pnum]._pLevel + (plr[pnum]._pLevel/4)) + && !forcehit) + { + return; + } + } + else if ((dam >> HP_SHIFT) < plr[pnum]._pLevel + && !forcehit) + return; + + pd = plr[pnum]._pdir; + if ((plr[pnum]._pGFXLoad & PGL_HIT) == 0) LoadPlrGFX(pnum, PGL_HIT); + NewPlrAnim(pnum, plr[pnum]._pHAnim[pd], plr[pnum]._pHFrames, 0, plr[pnum]._pHWidth); + plr[pnum]._pmode = PM_GOTHIT; + FixPlayerLocation(pnum,pd); + plr[pnum]._pVar8 = 1; + FixPlrWalkTags(pnum); + dPlayer[plr[pnum]._px][plr[pnum]._py] = 1 + (char)pnum; + SetPlayerOld(pnum); +} +// JMM.PATCH1.2/24/97 +void ShowDupString( LPCSTR lpszMessage ); +// END.PATCH1 +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RespawnDeadItem(ItemStruct *itm, int x, int y) +{ + int ii; + + if (numitems < MAXITEMS) { + // JMM.PATCH1.2/24/97 + if(FindGetItem(itm->IDidx, itm->_iCreateInfo, itm->_iSeed) >= 0) { + DROPLOG(" Duplicate item detected!\n"); + // JMM.PATCH1.2.22.97 + // NetSendString(1 << myplr, "A duplicate item has been detected. Unable to drop."); + ShowDupString("A duplicate item has been detected. Destroying duplicate..."); + SyncGetItem(x,y,itm->IDidx,itm->_iCreateInfo,itm->_iSeed); + // END.JMM.PATCH1.2.22.97 + } + // ENDPATCH1.2/24/97 + + ii = itemavail[0]; + dItem[x][y] = ii+1; + itemavail[0] = itemavail[MAXITEMS - numitems - 1]; + itemactive[numitems] = ii; + + item[ii] = *itm; + item[ii]._ix = x; + item[ii]._iy = y; + + RespawnItem(ii, TRUE); + numitems++; + + itm->_itype = -1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void PlrDeadItem(int pnum, ItemStruct *itm, int xx, int yy) { + + // no item to drop? + if (itm->_itype == -1) return; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PlrDeadItem: illegal player %d",pnum); + + // try optimal position first + int x = plr[pnum]._px + xx; + int y = plr[pnum]._py + yy; + + if ((xx != 0) || (yy != 0)) { + // Start placing + if (ItemSpaceOk(x, y)) { + RespawnDeadItem(itm, x, y); + plr[pnum].HoldItem = *itm; + NetSendCmdPItem(FALSE,CMD_RESPAWNITEM,x,y); + return; + } + } + + for (int l = 1; l < 50; l++) { + for (int j = -l; j <= l; j++) { + y = plr[pnum]._py + j; + for (int i = -l; i <= l; i++) { + x = plr[pnum]._px + i; + if (! ItemSpaceOk(x,y)) continue; + + // drop it + RespawnDeadItem(itm, x, y); + plr[pnum].HoldItem = *itm; + NetSendCmdPItem(FALSE,CMD_RESPAWNITEM,x,y); + return; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartPlayerKill(int pnum, BOOL earflag) +{ + ItemStruct * pi; + PlayerStruct * p = &plr[pnum]; + ItemStruct ear; + int i; + + // already dead? + if ((plr[pnum]._pHitPoints <= 0) && (plr[pnum]._pmode == PM_DEATH)) return; + + // if it's me, let everyone know + if (myplr == pnum) NetSendCmdParam1(TRUE,CMD_PLRDEAD,earflag); + + // dead players don't lose body items on diablo level + BOOL diablolevel = (gbMaxPlayers > 1) && (plr[pnum].plrlevel == 16); + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartPlayerKill: illegal player %d",pnum); + + if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySfxLoc(PS_DEAD, p->_px, p->_py); + #if !IS_VERSION(SHAREWARE) + else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySfxLoc(PS_ROGUE71, p->_px, p->_py); + else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySfxLoc(PS_MAGE71, p->_px, p->_py); + else if (plr[pnum]._pClass == CLASS_MONK) PlaySfxLoc(PS_MONK71, p->_px, p->_py); + else if (plr[pnum]._pClass == CLASS_BARD) PlaySfxLoc(PS_BARD71, p->_px, p->_py); + else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySfxLoc(PS_BARBARIAN71, p->_px, p->_py); + #endif + + // Give the plr no items in hands gfx + if (p->_pgfxnum != PGFX_NGUY) { + p->_pgfxnum = PGFX_NGUY; + p->_pGFXLoad = 0; + SetPlrAnims(pnum); + } + + if ((p->_pGFXLoad & PGL_DEAD) == 0) LoadPlrGFX(pnum, PGL_DEAD); + NewPlrAnim(pnum, p->_pDAnim[p->_pdir], p->_pDFrames, 1, p->_pDWidth); + p->_pmode = PM_DEATH; + p->_pBlockFlag = FALSE; + p->_pInvincible = TRUE; + SetPlayerHitPoints(pnum, 0); + p->_pVar8 = 1; + if ((pnum != myplr) && (earflag == FALSE) && !diablolevel) { + pi = &p->InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) pi->_itype = -1; + CalcPlrInv(pnum, FALSE); + } + + if (plr[pnum].plrlevel != currlevel) return; + + // Clean up map and set up vars for death + FixPlayerLocation(pnum,p->_pdir); + RemovePlrFromMap(pnum); + dFlags[p->_px][p->_py] |= BFLAG_DEADPLR; + SetPlayerOld(pnum); + + // Bail out if this is not me + if (pnum != myplr) return; + + drawhpflag = TRUE; + deathdelay = 30; + + // Drop all item in hand + if (curs >= ICSTART) { + PlrDeadItem(pnum, &p->HoldItem, 0, 0); + NewCursor(GLOVE_CURS); + } + + if (diablolevel) + return; + + // Drop half of players gold + DropHalfPlayersGold(pnum); + + // Drop player ear if killed by player + if (earflag == KILL_UNKNOWN) return; + + if (earflag) { + SetPlrHandItem(&ear, IDI_EAR); + sprintf(ear._iName, "Ear of %s", plr[pnum]._pName); + if (plr[pnum]._pClass == CLASS_SORCEROR) ear._iCurs = ITEM_EAR1; + else if (plr[pnum]._pClass == CLASS_WARRIOR) ear._iCurs = ITEM_EAR2; + else if (plr[pnum]._pClass == CLASS_ROGUE) ear._iCurs = ITEM_EAR3; + // Fix this if necessary. + else if (plr[pnum]._pClass == CLASS_MONK) ear._iCurs = ITEM_EAR3; + else if (plr[pnum]._pClass == CLASS_BARD) ear._iCurs = ITEM_EAR3; + else if (plr[pnum]._pClass == CLASS_BARBARIAN) ear._iCurs = ITEM_EAR3; + + ear._iCreateInfo = (plr[pnum]._pName[0] << 8) | plr[pnum]._pName[1]; + ear._iSeed = (plr[pnum]._pName[2] << 24) | + (plr[pnum]._pName[3] << 16) | + (plr[pnum]._pName[4] << 8) | + plr[pnum]._pName[5]; + ear._ivalue = plr[pnum]._pLevel; + // my ear already on ground? + int ii = FindGetItem(IDI_EAR, ear._iCreateInfo, ear._iSeed); + if (ii == -1) PlrDeadItem(pnum, &ear, 0, 0); + } else { + // Drop body items if killed by monster + pi = &p->InvBody[0]; + for (i = NUM_INVLOC; i--; pi++) { + int pdd = (p->_pdir + i) & 0x07; + PlrDeadItem(pnum, pi, offset_x[pdd], offset_y[pdd]); + } + CalcPlrInv(pnum, FALSE); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DropHalfPlayersGold(int pnum) +{ + int i; + long hGold; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("DropHalfPlayersGold: illegal player %d",pnum); + + // Get half of players gold + hGold = plr[pnum]._pGold >> 1; + + // Remove gold from speed list first; if there is any + // Try non GOLD_VMAX first, then break into the GOLD_VMAX piles + for (i = 0; ((i < MAXSPD) && (hGold > 0)); i++) { + if ((plr[pnum].SpdList[i]._itype == IT_GOLD) && + (plr[pnum].SpdList[i]._ivalue != GOLD_VMAX)) { + if (hGold < plr[pnum].SpdList[i]._ivalue) { + // update gold items value + plr[pnum].SpdList[i]._ivalue -= hGold; + // update gold items cursor + SetSpdbarGoldCurs(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to hGold + plr[pnum].HoldItem._ivalue = hGold; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + // initialize so we can exit the loop + hGold = 0; + } else { + // decrement hGold by SpdList items value + hGold -= plr[pnum].SpdList[i]._ivalue; + // remove gold item from SpdList + RemoveSpdBarItem(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to SpdList items value + plr[pnum].HoldItem._ivalue = plr[pnum].SpdList[i]._ivalue; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + // restart looping + i = -1; + } + } + } + if (hGold > 0) { + // SpdList GOLD_VMAX piles + for (i = 0; ((i < MAXSPD) && (hGold > 0)); i++) { + if (plr[pnum].SpdList[i]._itype == IT_GOLD) { + if (hGold < plr[pnum].SpdList[i]._ivalue) { + // update gold items value + plr[pnum].SpdList[i]._ivalue -= hGold; + // update gold items cursor + SetSpdbarGoldCurs(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to hGold + plr[pnum].HoldItem._ivalue = hGold; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + // initialize so we can exit the loop + hGold = 0; + } else { + // decrement hGold by SpdList items value + hGold -= plr[pnum].SpdList[i]._ivalue; + // remove gold item from SpdList + RemoveSpdBarItem(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to SpdList items value + plr[pnum].HoldItem._ivalue = plr[pnum].SpdList[i]._ivalue; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + // restart looping + i = -1; + } + } + } + } + force_redraw = FULLDRAW; + + // Remove gold from inventory list if there was no gold in the speed list + // or all gold from the speed list was deplenished. + // Try non GOLD_VMAX first, then break into the GOLD_VMAX piles + if (hGold > 0) { + for (i = 0; ((i < plr[pnum]._pNumInv) && (hGold > 0)); i++) { + if ((plr[pnum].InvList[i]._itype == IT_GOLD) && + (plr[pnum].InvList[i]._ivalue != GOLD_VMAX)) { + if (hGold < plr[pnum].InvList[i]._ivalue) { + // update gold items value + plr[pnum].InvList[i]._ivalue -= hGold; + // update gold items cursor + SetGoldCurs(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to hGold + plr[pnum].HoldItem._ivalue = hGold; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + hGold = 0; + } else { + // decrement hGold by InvList items value + hGold -= plr[pnum].InvList[i]._ivalue; + // remove gold item from InvList + RemoveInvItem(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to InvList items value + plr[pnum].HoldItem._ivalue = plr[pnum].InvList[i]._ivalue; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + // restart looping + i = -1; + } + } + } + if (hGold > 0) { + // InvList GOLD_VMAX piles + for (i = 0; ((i < plr[pnum]._pNumInv) && (hGold > 0)); i++) { + if (plr[pnum].InvList[i]._itype == IT_GOLD) { + if (hGold < plr[pnum].InvList[i]._ivalue) { + // update gold items value + plr[pnum].InvList[i]._ivalue -= hGold; + // update gold items cursor + SetGoldCurs(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to hGold + plr[pnum].HoldItem._ivalue = hGold; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + hGold = 0; + } else { + // decrement hGold by InvList items value + hGold -= plr[pnum].InvList[i]._ivalue; + // remove gold item from InvList + RemoveInvItem(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to InvList items value + plr[pnum].HoldItem._ivalue = plr[pnum].InvList[i]._ivalue; + // drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + // restart looping + i = -1; + } + } + } + } + } + // update players gold to account for losing half + plr[pnum]._pGold = CalculateGold(pnum); +} + + +void StripTopGold(int pnum) +{ + int i; + long hGold; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StripTopGold: illegal player %d",pnum); + + ItemStruct tmpHold = plr[pnum].HoldItem; + + // Remove gold from inventory list if there was no gold in the speed list + // or all gold from the speed list was deplenished. + // Try non GOLD_VMAX first, then break into the GOLD_VMAX piles + for (i = 0; i < plr[pnum]._pNumInv; i++) + { + if ((plr[pnum].InvList[i]._itype == IT_GOLD) && + (plr[pnum].InvList[i]._ivalue > GOLD_VMAX)) + { + + // first, remove the gold from the slot + hGold = plr[pnum].InvList[i]._ivalue - GOLD_VMAX; + plr[pnum].InvList[i]._ivalue = GOLD_VMAX; + + // update gold items cursor + SetGoldCurs(pnum, i); + // initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + SetPlrHandGoldCurs(&plr[pnum].HoldItem); + // set hold items value equal to hGold + plr[pnum].HoldItem._ivalue = hGold; + + hGold = 0; + // if it'll fit elsewhere, continue + if (!GoldAutoPlace(pnum)) // else drop the hold item + PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0); + } + } + // update players gold + plr[pnum]._pGold = CalculateGold(pnum); + plr[pnum].HoldItem = tmpHold; +} +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartPlrKill(int pnum, BOOL earflag) +{ + int i, mx; + + // PATCH1.JMM + // no death on first level + if ((0 >= plr[pnum]._pHitPoints) && (0 == currlevel)) { + SetPlayerHitPoints(pnum,1<mdeadval, monster[myplr]._mdir); + dMonster[monster[myplr]._mx][monster[myplr]._my] = 0; + monster[myplr]._mDelFlag = TRUE; + DeleteMonsterList(); + } + + void DeleteMissile(int, int); + for (i = 0; i < nummissiles; i++) { + mx = missileactive[i]; + if ((missile[mx]._mitype == MIT_STONE) && (missile[mx]._misource == pnum)) + monster[(missile[mx]._miVar2)]._mmode = missile[mx]._miVar1; + if ((missile[mx]._mitype == MIT_MANASHIELD) && (missile[mx]._misource == pnum)) { + ClearMissileSpot(mx); + DeleteMissile(mx, i); + } + if ((missile[mx]._mitype == MIT_ETHER) && (missile[mx]._misource == pnum)) { + ClearMissileSpot(mx); + DeleteMissile(mx, i); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitLevelChange(int pnum) +{ + RemovePlrMissiles(pnum); + + if ((pnum == myplr) && (qtextflag)) { + qtextflag = FALSE; + stream_stop(); + } + // remove player from current level immediately + RemovePlrFromMap(pnum); + SetPlayerOld(pnum); + if (pnum == myplr) dPlayer[plr[myplr]._px][plr[myplr]._py] = 1 + myplr; + else plr[pnum]._pLvlVisited[plr[pnum].plrlevel] = TRUE; + + ClrPlrPath(pnum); + plr[pnum].destAction = PCMD_NOTHING; + plr[pnum]._pLvlChanging = TRUE; + if (pnum == myplr) plr[pnum].pLvlLoad = LVLCHANGE_TIME; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void StartNewLvl(int pnum, int fom, int lvl) +{ + InitLevelChange(pnum); + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("StartNewLvl: illegal player %d",pnum); + switch (fom) { + case WM_DIABNEXTLVL: + case WM_DIABPREVLVL: + case WM_DIABTOWNWARP: + //app_assert(plr[pnum].plrlevel != lvl); + plr[pnum].plrlevel = lvl; + break; + + case WM_DIABTWARPUP: + plr[myplr].pTownWarps |= 1 << (leveltype - 2); + plr[pnum].plrlevel = lvl; + break; + + case WM_DIABRETOWN: + // everything already set + break; + + case WM_DIABRTNLVL: + // can't do any validation on this + // one since it stuffs into global vars + app_assert(gbMaxPlayers == 1); + plr[pnum].plrlevel = lvl; + break; + + case WM_DIABSETLVL: + setlvlnum = lvl; + app_assert(gbMaxPlayers == 1); + break; + + default: + app_fatal("StartNewLvl"); + break; + } + + if (pnum == myplr) { + plr[pnum]._pmode = PM_NEWLVL; + plr[pnum]._pInvincible = TRUE; + PostMessage(ghMainWnd,fom,0,0); + if (gbMaxPlayers > 1) NetSendCmdParam2(TRUE,CMD_NEWLVL,fom,lvl); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void RestartTownLvl(int pnum) +{ + InitLevelChange(pnum); + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("RestartTownLvl: illegal player %d",pnum); + + //app_assert(plr[pnum].plrlevel != 0); + plr[pnum].plrlevel = 0; + + plr[pnum]._pInvincible = FALSE; + SetPlayerHitPoints(pnum, 1 << HP_SHIFT); + plr[pnum]._pMana = 0; + plr[pnum]._pManaBase = plr[pnum]._pMana - (plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase); + CalcPlrInv(pnum, FALSE); + + if (pnum == myplr) { + plr[pnum]._pmode = PM_NEWLVL; + plr[pnum]._pInvincible = TRUE; + PostMessage(ghMainWnd,WM_DIABRETOWN,0,0); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartWarpLvl(int pnum, int pidx) +{ + InitLevelChange(pnum); + + if (gbMaxPlayers != 1) { + if (plr[pnum].plrlevel != 0) plr[pnum].plrlevel = 0; + else plr[pnum].plrlevel = portal[pidx].level; + } + + if (pnum == myplr) { + SetCurrentPortal(pidx); + plr[pnum]._pmode = PM_NEWLVL; + plr[pnum]._pInvincible = TRUE; + PostMessage(ghMainWnd,WM_DIABWARPLVL,0,0); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoStand(int pnum) +{ + return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +********************************** TEMP ********************************* +**-----------------------------------------------------------------------* + +BOOL rfix1 = FALSE; +BOOL rfix2 = FALSE; + +void TempWalkFix(int pnum) +{ + if (currlevel == 0) return; + if ((plr[pnum]._pClass == CLASS_ROGUE) && (plr[pnum]._pAnimLen == 6)) { + if ((plr[pnum]._pAnimFrame == 2) && !rfix1) { + plr[pnum]._pAnimFrame = 1; + rfix1 = TRUE; + } else rfix1 = FALSE; + if ((plr[pnum]._pAnimFrame == 4) && !rfix2) { + plr[pnum]._pAnimFrame = 3; + rfix2 = TRUE; + } else rfix2 = FALSE; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoWalk(int pnum) +{ + int rv; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoWalk: illegal player %d",pnum); + +#if 0 + // changed _pAnimFrame == 2 to == 3 to prevent "extra" footstep == pat +// if ((plr[pnum]._pAnimFrame == 3) +// || (plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7) +// || (plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4)) +// PlaySfxLoc(PS_WALK1, plr[pnum]._px, plr[pnum]._py); + //TempWalkFix(pnum); +#endif + + if (currlevel == 0 && gbWalkOn) // double-speed walk in town + { + if (plr[pnum]._pAnimFrame%2 == 0) // should be even frames only + { + ++plr[pnum]._pAnimFrame; + ++plr[pnum]._pVar8; + } + if (plr[pnum]._pAnimFrame >= plr[pnum]._pWFrames) + plr[pnum]._pAnimFrame = 0; + } + + int l = 8; + + if (currlevel != 0) l = PlrWalkLenTbl[plr[pnum]._pClass]; + if (plr[pnum]._pVar8 >= l) { + dPlayer[plr[pnum]._px][plr[pnum]._py] = 0; + plr[pnum]._px += plr[pnum]._pVar1; + plr[pnum]._py += plr[pnum]._pVar2; + dPlayer[plr[pnum]._px][plr[pnum]._py] = 1 + (char)pnum; + if (leveltype != 0) { + ChangeLightXY(plr[pnum]._plid, plr[pnum]._px, plr[pnum]._py); + ChangeVisionXY(plr[pnum]._pvid, plr[pnum]._px, plr[pnum]._py); + } + if (pnum == myplr) { + if (ScrollInfo._sdir != SCRL_NONE) { + ViewX = plr[pnum]._px - ScrollInfo._sdx; + ViewY = plr[pnum]._py - ScrollInfo._sdy; + } + } + if (plr[pnum].walkpath[0] != PCMD_NOTHING) StartWalkStand(pnum); + else StartStand(pnum, plr[pnum]._pVar3); + ClearPlrPVars(pnum); + if (leveltype != 0) ChangeLightOff(plr[pnum]._plid, 0, 0); + rv = RUN_AGAIN; + } else { + PM_ChangeOffset(pnum); + rv = RUN_DONE; + } + + return (rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoWalk2(int pnum) +{ + int rv; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoWalk2: illegal player %d",pnum); + +#if 0 + // changed _pAnimFrame == 2 to == 3 to prevent "extra" footstep == pat + if ((plr[pnum]._pAnimFrame == 3) + || (plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7) + || (plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4)) + PlaySfxLoc(PS_WALK1, plr[pnum]._px, plr[pnum]._py); + //TempWalkFix(pnum); +#endif + if (currlevel == 0 && gbWalkOn) // double-speed walk in town + { + if (plr[pnum]._pAnimFrame%2 == 0) // should be even frames only + { + ++plr[pnum]._pAnimFrame; + ++plr[pnum]._pVar8; + } + if (plr[pnum]._pAnimFrame >= plr[pnum]._pWFrames) + plr[pnum]._pAnimFrame = 0; + } + + int l = 8; + + if (currlevel != 0) l = PlrWalkLenTbl[plr[pnum]._pClass]; + if (plr[pnum]._pVar8 >= l) { + dPlayer[plr[pnum]._pVar1][plr[pnum]._pVar2] = 0; + if (leveltype != 0) { + ChangeLightXY(plr[pnum]._plid, plr[pnum]._px, plr[pnum]._py); + ChangeVisionXY(plr[pnum]._pvid, plr[pnum]._px, plr[pnum]._py); + } + if (pnum == myplr) { + if (ScrollInfo._sdir != SCRL_NONE) { + ViewX = plr[pnum]._px - ScrollInfo._sdx; + ViewY = plr[pnum]._py - ScrollInfo._sdy; + } + } + if (plr[pnum].walkpath[0] != PCMD_NOTHING) StartWalkStand(pnum); + else StartStand(pnum, plr[pnum]._pVar3); + ClearPlrPVars(pnum); + if (leveltype != 0) ChangeLightOff(plr[pnum]._plid, 0, 0); + rv = RUN_AGAIN; + } else { + PM_ChangeOffset(pnum); + rv = RUN_DONE; + } + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoWalk3(int pnum) +{ + int rv; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoWalk3: illegal player %d",pnum); + +#if 0 + // changed _pAnimFrame == 2 to == 3 to prevent "extra" footstep == pat + if ((plr[pnum]._pAnimFrame == 3) + || (plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7) + || (plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4)) + PlaySfxLoc(PS_WALK1, plr[pnum]._px, plr[pnum]._py); + //TempWalkFix(pnum); +#endif + + if (currlevel == 0 && gbWalkOn) // double-speed walk in town + { + if (plr[pnum]._pAnimFrame%2 == 0) // should be even frames only + { + ++plr[pnum]._pAnimFrame; + ++plr[pnum]._pVar8; + } + if (plr[pnum]._pAnimFrame >= plr[pnum]._pWFrames) + plr[pnum]._pAnimFrame = 0; + } + + + int l = 8; + + if (currlevel != 0) l = PlrWalkLenTbl[plr[pnum]._pClass]; + if (plr[pnum]._pVar8 >= l) { + dPlayer[plr[pnum]._px][plr[pnum]._py] = 0; + dFlags[plr[pnum]._pVar4][plr[pnum]._pVar5] &= BFMASK_PLRLR; + plr[pnum]._px = plr[pnum]._pVar1; + plr[pnum]._py = plr[pnum]._pVar2; + dPlayer[plr[pnum]._px][plr[pnum]._py] = 1 + (char)pnum; + if (leveltype != 0) { + ChangeLightXY(plr[pnum]._plid, plr[pnum]._px, plr[pnum]._py); + ChangeVisionXY(plr[pnum]._pvid, plr[pnum]._px, plr[pnum]._py); + } + if (pnum == myplr) { + if (ScrollInfo._sdir != SCRL_NONE) { + ViewX = plr[pnum]._px - ScrollInfo._sdx; + ViewY = plr[pnum]._py - ScrollInfo._sdy; + } + } + if (plr[pnum].walkpath[0] != PCMD_NOTHING) StartWalkStand(pnum); + else StartStand(pnum, plr[pnum]._pVar3); + ClearPlrPVars(pnum); + if (leveltype != 0) ChangeLightOff(plr[pnum]._plid, 0, 0); + rv = RUN_AGAIN; + } else { + PM_ChangeOffset(pnum); + rv = RUN_DONE; + } + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL WeaponDur(int pnum, int durrnd) +{ + if (pnum != myplr) + return FALSE; + + if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iClass == IC_WEAP)) { + if (plr[pnum].Hand1Item._iFlags2 & IAF2_DECAY) { + plr[pnum].Hand1Item._iPLDam -= 5; + if (plr[pnum].Hand1Item._iPLDam <= -100) { + NetSendCmdDelItem(TRUE, INVLOC_HAND1); + plr[pnum].Hand1Item._itype = -1; + CalcPlrInv(pnum,TRUE); + return(TRUE); + } + CalcPlrInv(pnum,TRUE); + } + } + if ((plr[pnum].Hand2Item._itype != -1) && (plr[pnum].Hand2Item._iClass == IC_WEAP)) { + if (plr[pnum].Hand2Item._iFlags2 & IAF2_DECAY) { + plr[pnum].Hand2Item._iPLDam -= 5; + if (plr[pnum].Hand2Item._iPLDam <= -100) { + NetSendCmdDelItem(TRUE, INVLOC_HAND1); + plr[pnum].Hand2Item._itype = -1; + CalcPlrInv(pnum,TRUE); + return(TRUE); + } + CalcPlrInv(pnum,TRUE); + } + } + + // Item used, so change durability + if (random(3, durrnd)) + return FALSE; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("WeaponDur: illegal player %d",pnum); + + if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iClass == IC_WEAP)) { + if (plr[pnum].Hand1Item._iDurability == INFINITE_DUR) return(FALSE); + plr[pnum].Hand1Item._iDurability--; + if (plr[pnum].Hand1Item._iDurability <= 0) { + NetSendCmdDelItem(TRUE, INVLOC_HAND1); + plr[pnum].Hand1Item._itype = -1; + CalcPlrInv(pnum,TRUE); + return(TRUE); + } + } + if ((plr[pnum].Hand2Item._itype != -1) && (plr[pnum].Hand2Item._iClass == IC_WEAP)) { + if (plr[pnum].Hand2Item._iDurability == INFINITE_DUR) return(FALSE); + plr[pnum].Hand2Item._iDurability--; + if (plr[pnum].Hand2Item._iDurability == 0) { + NetSendCmdDelItem(TRUE, INVLOC_HAND2); + plr[pnum].Hand2Item._itype = -1; + CalcPlrInv(pnum,TRUE); + return(TRUE); + } + } + // Shield only guy + if ((plr[pnum].Hand1Item._itype == -1) && (plr[pnum].Hand2Item._itype == IT_SHIELD)) { + if (plr[pnum].Hand2Item._iDurability == INFINITE_DUR) return(FALSE); + plr[pnum].Hand2Item._iDurability--; + if (plr[pnum].Hand2Item._iDurability == 0) { + NetSendCmdDelItem(TRUE, INVLOC_HAND2); + plr[pnum].Hand2Item._itype = -1; + CalcPlrInv(pnum,TRUE); + return(TRUE); + } + } + if ((plr[pnum].Hand2Item._itype == -1) && (plr[pnum].Hand1Item._itype == IT_SHIELD)) { + if (plr[pnum].Hand1Item._iDurability == INFINITE_DUR) return(FALSE); + plr[pnum].Hand1Item._iDurability--; + if (plr[pnum].Hand1Item._iDurability == 0) { + NetSendCmdDelItem(TRUE, INVLOC_HAND1); + plr[pnum].Hand1Item._itype = -1; + CalcPlrInv(pnum,TRUE); + return(TRUE); + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PlrHitMonst(int pnum, int m) +{ + int hit, hper = 0, mind, maxd; + long dam, skdam; + int phanditype; + int tmac; + BOOL rv; + BOOL ret = FALSE; + BOOL quarterdamage = FALSE; + + if ((DWORD)m >= MAXMONSTERS) + app_fatal("PlrHitMonst: illegal monster %d",m); + + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) return(FALSE); + + if(monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MG_RUN_AWAY) + return FALSE; + + if (monster[m]._mmode == MM_MISSILE) return(FALSE); + + if (pnum < 0) + { + quarterdamage = TRUE; + pnum = -pnum; + if (plr[pnum]._pLevel > 20) + hper -= 30; + else + hper -= 2 * (35 - plr[pnum]._pLevel); + } + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PlrHitMonst: illegal player %d",pnum); + + rv = FALSE; + // Did I hit? + hit = random(4, 100); + if (monster[m]._mmode == MM_STONE) hit = 0; + tmac = monster[m].mArmorClass; + if (plr[pnum]._pIEnAc > 0) // like Damage Reduction in Hero --DKT + { + int i = plr[pnum]._pIEnAc - 1; + if (i > 0) + tmac >>= i; // halved (n-1) times + else + tmac -= tmac >> 2; // three quarters + + if (plr[pnum]._pClass == CLASS_BARBARIAN) + { + tmac -= (monster[m].mArmorClass)/8; // Barbarians have a slight advantage using these weapons. + } + + // limit it to a zero. + if (tmac < 0) + { + tmac = 0; + } + } + + // note: modified this to += so quarterdamage shots are at minus to hit + // by giving negative initial value to hper. + hper += BASE_TO_HIT + plr[pnum]._pLevel - tmac + (plr[pnum]._pDexterity >> 1); + if (plr[pnum]._pClass == CLASS_WARRIOR) + hper += 20; + hper += plr[pnum]._pIBonusToHit; + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (CheckMonsterHit(m, ret)) // ret passed by &reference!! + return(ret); +#if CHEATS + else if((hit < hper) || cheatflag || simplecheat) { +#else + else if (hit < hper) { +#endif + if ((plr[pnum]._pIFlags & IAF_FIREHIT && + plr[pnum]._pIFlags & IAF_LIGHTHIT)) + { + int dmg = plr[pnum]._pIFMinDam + random(3, (plr[pnum]._pIFMaxDam - plr[pnum]._pIFMinDam)); + AddMissile(plr[pnum]._px, plr[pnum]._py, plr[pnum]._pVar1, plr[pnum]._pVar2, plr[pnum]._pdir, MIT_SPECARROW, MI_ENEMYMONST, pnum, dmg, 0); + } + mind = plr[pnum]._pIMinDam; + maxd = plr[pnum]._pIMaxDam; + dam = random(5, maxd - mind + 1) + mind; + dam += (dam * plr[pnum]._pIBonusDam) / 100; + dam += plr[pnum]._pIBonusDamMod; + + int perildam = dam << HP_SHIFT; + + dam += plr[pnum]._pDamageMod; + if (plr[pnum]._pClass == CLASS_WARRIOR + || plr[pnum]._pClass == CLASS_BARBARIAN) { + //ddp = (plr[pnum]._pDexterity + plr[pnum]._pLevel) >> 3; + int ddp = plr[pnum]._pLevel; + int doubledam = random(6, 100); + if (doubledam < ddp) dam = dam << 1; + } + phanditype = -1; + if ((plr[pnum].Hand1Item._itype == IT_SWORD) || (plr[pnum].Hand2Item._itype == IT_SWORD)) phanditype = IT_SWORD; + if ((plr[pnum].Hand1Item._itype == IT_MACE) || (plr[pnum].Hand2Item._itype == IT_MACE)) phanditype = IT_MACE; + switch (monster[m].MData->mMonstClass) { + case MC_UNDEAD: + if (phanditype == IT_SWORD) dam -= (dam >> 1); + else if (phanditype == IT_MACE) dam += (dam >> 1); + break; + case MC_ANIMAL: + if (phanditype == IT_MACE) dam -= (dam >> 1); + else if (phanditype == IT_SWORD) dam += (dam >> 1); + break; + } + if ((plr[pnum]._pIFlags & IAF_DAMDEMON) && (monster[m].MData->mMonstClass == MC_DEMON)) dam += (dam << 1); + + if (plr[pnum]._pIFlags2 & IAF2_DEVASTATION) + { + int tdp = 5; + int tripledamage = random(6, 100); + if (tripledamage < tdp) dam += dam << 1; + } + + if (plr[pnum]._pIFlags2 & IAF2_CLONE) // doppelganger + { + if (monster[m].MType->mtype != MT_DIABLO) + { + if ((monster[m]._uniqtype == 0) && (random(6, 100) < 10)) + CloneMonster(m); + } + } + + dam = dam << HP_SHIFT; + + // after shift, to increase resolution + if (plr[pnum]._pIFlags2 & IAF2_JESTER) + { + int dammult = random(6, 201); + if (dammult >= 100) + dammult = 100 + (dammult-100) * 5; + dam = (dam * dammult) / 100; + } + + if (quarterdamage) + dam >>= 2; + + + // can only be damaged by me + if (pnum == myplr) { + if (plr[pnum]._pIFlags2 & IAF2_PERIL) + { + perildam += plr[pnum]._pIGetHit << HP_SHIFT; + if (perildam < 0) + { + // do nothing + } + else if (plr[pnum]._pHitPoints > perildam) + { + plr[pnum]._pHitPoints -= perildam; + plr[pnum]._pHPBase -= perildam; + } + else + { + plr[pnum]._pHPBase -= plr[pnum]._pHitPoints - (1 << HP_SHIFT); + plr[pnum]._pHitPoints = 1 << HP_SHIFT; + } + dam <<= 1; + } + monster[m]._mhitpoints -= dam; + } + if (plr[pnum]._pIFlags & IAF_SKING) { + skdam = random(7, dam >> 3); + plr[pnum]._pHitPoints += skdam; + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase += skdam; + if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + drawhpflag = TRUE; + } + if ((plr[pnum]._pIFlags & IAF_ALLBAT) && (!(plr[pnum]._pIFlags & IAF_LMANA))) { + if (plr[pnum]._pIFlags & IAF_BAT10) skdam = (dam * 3) / 100; + if (plr[pnum]._pIFlags & IAF_BAT20) skdam = (dam * 5) / 100; + plr[pnum]._pMana += skdam; + if (plr[pnum]._pMana > plr[pnum]._pMaxMana) plr[pnum]._pMana = plr[pnum]._pMaxMana; + plr[pnum]._pManaBase += skdam; + if (plr[pnum]._pManaBase > plr[pnum]._pMaxManaBase) plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase; + drawmanaflag = TRUE; + } + if (plr[pnum]._pIFlags & IAF_ALLLEECH) { + if (plr[pnum]._pIFlags & IAF_LEECH10) skdam = (dam * 3) / 100; + if (plr[pnum]._pIFlags & IAF_LEECH20) skdam = (dam * 5) / 100; + plr[pnum]._pHitPoints += skdam; + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase += skdam; + if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + drawhpflag = TRUE; + } + if (plr[pnum]._pIFlags & IAF_NOHEAL) monster[m]._mFlags |= MFLAG_NOHEAL; +#if CHEATS + if (simplecheat || cheatflag) monster[m]._mhitpoints = 0; +// if (cheatflag) monster[m]._mhitpoints = 1 << HP_SHIFT; +#endif + //rjs - was doing double dam if stone - if (pnum == myplr && monster[m]._mmode == MM_STONE) monster[m]._mhitpoints -= dam; + if ((monster[m]._mhitpoints >> HP_SHIFT) <= 0) { + if (monster[m]._mmode == MM_STONE) { + M_StartKill(m, pnum); + monster[m]._mmode = MM_STONE; + } else M_StartKill(m, pnum); + } else { + if (monster[m]._mmode == MM_STONE) { + M_StartHit(m, pnum, dam); + monster[m]._mmode = MM_STONE; + } else { + if (plr[pnum]._pIFlags & IAF_KNOCKBACK) M_GetKnockback(m); + M_StartHit(m, pnum, dam); + } + } + rv = TRUE; + } + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PlrHitPlr(int pnum, char p) +{ + int hit, hper, mind, maxd; + int doubledam, ddp; + long dam, skdam; + int tac; + int blk, blkper, blkdir; + BOOL rv; + + if ((DWORD)p >= MAX_PLRS) + app_fatal("PlrHitPlr: illegal target player %d",p); + + rv = FALSE; + if (plr[p]._pInvincible) return(rv); + if ((plr[p]._pSpellFlags & SF_ETHER) != 0) return(rv); + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PlrHitPlr: illegal attacking player %d",pnum); + + // Did I hit? + hit = random(4, 100); + //rjs tac = (byte) plr[p]._pArmorClass + plr[p]._pIAC + plr[p]._pIBonusAC; + tac = plr[p]._pIAC + plr[p]._pIBonusAC; + tac += (plr[p]._pDexterity / 5); + hper = BASE_TO_HIT + plr[pnum]._pLevel - tac + (plr[pnum]._pDexterity >> 1); + if (plr[pnum]._pClass == CLASS_WARRIOR) + hper += 20; + hper += plr[pnum]._pIBonusToHit; + if (hper < 5) hper = 5; + if (hper > 95) hper = 95; + if (((plr[p]._pmode == PM_STAND) || (plr[p]._pmode == PM_ATTACK)) && (plr[p]._pBlockFlag)) blk = random(5, 100); + else blk = 100; + blkper = plr[p]._pBaseToBlk + plr[p]._pDexterity - ((plr[pnum]._pLevel - plr[p]._pLevel) << 1); + if (blkper < 0) blkper = 0; + if (blkper > 100) blkper = 100; + if (hit < hper) { + if (blk < blkper) { + blkdir = GetDirection(plr[p]._px, plr[p]._py, plr[pnum]._px, plr[pnum]._py); + StartPlrBlock(p, blkdir); + } else { + mind = plr[pnum]._pIMinDam; + maxd = plr[pnum]._pIMaxDam; + dam = random(5, maxd - mind + 1) + mind; + dam += (dam * plr[pnum]._pIBonusDam) / 100; + dam += plr[pnum]._pIBonusDamMod + plr[pnum]._pDamageMod; + if (plr[pnum]._pClass == CLASS_WARRIOR + || plr[pnum]._pClass == CLASS_BARBARIAN) { + //ddp = (plr[pnum]._pDexterity + plr[pnum]._pLevel) >> 3; + ddp = plr[pnum]._pLevel; + doubledam = random(6, 100); + if (doubledam < ddp) dam = dam << 1; + } + dam = dam << HP_SHIFT; + if (plr[pnum]._pIFlags & IAF_SKING) { + skdam = random(7, dam >> 3); + plr[pnum]._pHitPoints += skdam; + if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) plr[pnum]._pHitPoints = plr[pnum]._pMaxHP; + plr[pnum]._pHPBase += skdam; + if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase; + drawhpflag = TRUE; + } + if (pnum == myplr) NetSendCmdDamage(TRUE, p, dam); + StartPlrHit(p, dam, FALSE); + } + rv = TRUE; + } + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PlrHitObj(int pnum, int mx, int my) +{ + int oi; + + if (dObject[mx][my] > 0) oi = dObject[mx][my] - 1; + else oi = -(dObject[mx][my] + 1); + if (object[oi]._oBreak == OBJ_BREAKABLE) { + BreakObject(pnum, oi); + return(TRUE); + } else return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoAttack(int pnum) +{ + int dx,dy,m; + char p; + BOOL didhit = FALSE; + int frame; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoAttack: illegal player %d",pnum); + + frame = plr[pnum]._pAnimFrame; + + if ((plr[pnum]._pIFlags & IAF_ATANIM1) && (frame == 1)) + plr[pnum]._pAnimFrame++; + + if ((plr[pnum]._pIFlags & IAF_ATANIM2) && (frame == 1 || frame == 3)) + plr[pnum]._pAnimFrame++; + + if ((plr[pnum]._pIFlags & IAF_ATANIM3) && (frame == 1 || frame == 3 || frame == 5)) + plr[pnum]._pAnimFrame++; + + if ((plr[pnum]._pIFlags & IAF_ATANIM4) && (frame == 1 || frame == 4)) + plr[pnum]._pAnimFrame += 2; + + if (plr[pnum]._pAnimFrame == (plr[pnum]._pAFNum-1)) + PlaySfxLoc(PS_SWING, plr[pnum]._px, plr[pnum]._py); + + if (plr[pnum]._pAnimFrame == plr[pnum]._pAFNum) { + dx = plr[pnum]._px + offset_x[plr[pnum]._pdir]; + dy = plr[pnum]._py + offset_y[plr[pnum]._pdir]; + + if (dMonster[dx][dy] != 0) { + if (dMonster[dx][dy] > 0) m = dMonster[dx][dy] - 1; + else m = -(dMonster[dx][dy] + 1); + if (CanTalkToMonst(m)) { + plr[pnum]._pVar1 = 0; + return(RUN_DONE); + } + } + + if ((plr[pnum]._pIFlags & IAF_FIREHIT && + plr[pnum]._pIFlags & IAF_LIGHTHIT)) + { + } + else if (plr[pnum]._pIFlags & IAF_FIREHIT) + AddMissile(dx, dy, 1, 0, 0, MIT_WEAPEXP, MI_ENEMYMONST, pnum, 0, 0); + else if (plr[pnum]._pIFlags & IAF_LIGHTHIT) + AddMissile(dx, dy, 2, 0, 0, MIT_WEAPEXP, MI_ENEMYMONST, pnum, 0, 0); + + if (dMonster[dx][dy] != 0) { + if (dMonster[dx][dy] > 0) + m = dMonster[dx][dy] - 1; + else + m = -(dMonster[dx][dy] + 1); + didhit = PlrHitMonst(pnum, m); + } else { + if ((dPlayer[dx][dy] != 0) && (!FriendlyMode)) { + if (dPlayer[dx][dy] > 0) p = dPlayer[dx][dy] - 1; + else p = -(dPlayer[dx][dy] + 1); + didhit = PlrHitPlr(pnum, p); + } else { + if (dObject[dx][dy] > 0) didhit = PlrHitObj(pnum,dx,dy); + } + } + + if ((plr[pnum]._pClass == CLASS_MONK && + (plr[pnum].Hand1Item._itype == IT_STAFF || + plr[pnum].Hand2Item._itype == IT_STAFF) + ) + || (plr[pnum]._pClass == CLASS_BARD && + (plr[pnum].Hand1Item._itype == IT_SWORD && + plr[pnum].Hand2Item._itype == IT_SWORD) + ) + // Axes, 2handed Maces or 2handed swords with no shield used. + || (plr[pnum]._pClass == CLASS_BARBARIAN && + (plr[pnum].Hand1Item._itype == IT_AXE || + plr[pnum].Hand2Item._itype == IT_AXE || + ((((plr[pnum].Hand1Item._itype == IT_MACE && plr[pnum].Hand1Item._iLoc == IL_2HAND) || + (plr[pnum].Hand2Item._itype == IT_MACE && plr[pnum].Hand2Item._iLoc == IL_2HAND) || + (plr[pnum].Hand1Item._itype == IT_SWORD && plr[pnum].Hand1Item._iLoc == IL_2HAND) || + (plr[pnum].Hand2Item._itype == IT_SWORD && plr[pnum].Hand2Item._iLoc == IL_2HAND) + ) + && !(plr[pnum].Hand1Item._itype == IT_SHIELD || plr[pnum].Hand2Item._itype == IT_SHIELD) + ) + ) + ) + ) + ) + { + // check right-hand opponent, then left + // note that we temporarily redeclare dx, dy, and m here + int dx = plr[pnum]._px + offset_x[(plr[pnum]._pdir+1)%8]; + int dy = plr[pnum]._py + offset_y[(plr[pnum]._pdir+1)%8]; + int m = ((dMonster[dx][dy] > 0) ? + dMonster[dx][dy] : -dMonster[dx][dy]) + - 1; + if (dMonster[dx][dy] != 0 && !CanTalkToMonst(m) && + monster[m]._moldx == dx && monster[m]._moldy == dy) + { + if (PlrHitMonst(-pnum, m)) + didhit = TRUE; + } + dx = plr[pnum]._px + offset_x[(plr[pnum]._pdir+7)%8]; + dy = plr[pnum]._py + offset_y[(plr[pnum]._pdir+7)%8]; + m = ((dMonster[dx][dy] > 0) ? + dMonster[dx][dy] : -dMonster[dx][dy]) + - 1; + if (dMonster[dx][dy] != 0 && !CanTalkToMonst(m) && + monster[m]._moldx == dx && monster[m]._moldy == dy) + { + if (PlrHitMonst(-pnum, m)) + didhit = TRUE; + } + } + if (didhit) { + if (WeaponDur(pnum, 30)) { // 1 in 30 dur hit if plr hit monst/obj + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return(RUN_AGAIN); + } + } + } + if (plr[pnum]._pAnimFrame == plr[pnum]._pAFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoRangeAttack(int pnum) +{ + int mistype; + int numshots = 0; + int shottype = 0; + int deltaX = 0, deltaY = 0; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoRangeAttack: illegal player %d",pnum); + + if (plr[pnum]._pAnimFrame == plr[pnum]._pAFNum) + numshots = 1; + + if ((plr[pnum]._pIFlags & IAF_RABID) && + (plr[pnum]._pAnimFrame == plr[pnum]._pAFNum + 2)) + { + numshots = 2; + shottype = 1; // framing shots + } + + for (int shotnum = 0; shotnum < numshots; shotnum++) + { + switch(shottype) + { + case 0: break; + case 1: + { + int fanoffset = (shotnum == 0) ? -1 : 1; + int xoffset = plr[pnum]._pVar1 - plr[pnum]._px; + int yoffset = plr[pnum]._pVar2 - plr[pnum]._py; + if (xoffset < 0) + deltaY = fanoffset; + if (xoffset > 0) + deltaY = -fanoffset; + if (yoffset < 0) + deltaX = -fanoffset; + if (yoffset > 0) + deltaX = fanoffset; + } + break; + default: + break; + } + + mistype = MIT_ARROW; + if (plr[pnum]._pIFlags & IAF_FIREARROW) mistype = MIT_FARROW; + if (plr[pnum]._pIFlags & IAF_LARROW) mistype = MIT_LARROW; + + // both flags means a special arrow, doing (firedamage) damage. + // a bit of a hack. --donald + if ((plr[pnum]._pIFlags & IAF_FIREARROW) && + (plr[pnum]._pIFlags & IAF_LARROW)) + { + int dmg = plr[pnum]._pIFMinDam + random(3, (plr[pnum]._pIFMaxDam - plr[pnum]._pIFMinDam)); + mistype = MIT_SPECARROW; + + AddMissile(plr[pnum]._px, plr[pnum]._py, plr[pnum]._pVar1 + deltaX, plr[pnum]._pVar2 + deltaY, plr[pnum]._pdir, mistype, MI_ENEMYMONST, pnum, dmg, 0); + } + else + { + AddMissile(plr[pnum]._px, plr[pnum]._py, plr[pnum]._pVar1 + deltaX, plr[pnum]._pVar2 + deltaY, plr[pnum]._pdir, mistype, MI_ENEMYMONST, pnum, 4, 0); + if (shotnum == 0) + { + if (shottype == 0) + PlaySfxLoc(PS_BFIRE, plr[pnum]._px, plr[pnum]._py); + else + PlaySfxLoc(PS_NEW_BFIRE, plr[pnum]._px, plr[pnum]._py); + } + } + + if (WeaponDur(pnum, 40)) { // 1 in 40 bow dur hit + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return(RUN_AGAIN); + } + } + if (plr[pnum]._pAnimFrame >= plr[pnum]._pAFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ShieldDur(int pnum) +{ + if (pnum != myplr) return; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("ShieldDur: illegal player %d",pnum); + + // Item used, so change durability + if (plr[pnum].Hand1Item._itype == IT_SHIELD) { + if (plr[pnum].Hand1Item._iDurability == INFINITE_DUR) return; + plr[pnum].Hand1Item._iDurability--; + if (plr[pnum].Hand1Item._iDurability == 0) { + NetSendCmdDelItem(TRUE, INVLOC_HAND1); + plr[pnum].Hand1Item._itype = -1; + CalcPlrInv(pnum,TRUE); + } + } + if (plr[pnum].Hand2Item._itype == IT_SHIELD) { + if (plr[pnum].Hand2Item._iDurability == INFINITE_DUR) return; + plr[pnum].Hand2Item._iDurability--; + if (plr[pnum].Hand2Item._iDurability == 0) { + NetSendCmdDelItem(TRUE, INVLOC_HAND2); + plr[pnum].Hand2Item._itype = -1; + CalcPlrInv(pnum,TRUE); + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoBlock(int pnum) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoBlock: illegal player %d",pnum); + + if ((plr[pnum]._pIFlags & IAF_BLANIM) && (plr[pnum]._pAnimFrame != 1)) { + plr[pnum]._pAnimFrame = plr[pnum]._pBFrames; + } + if (plr[pnum]._pAnimFrame >= plr[pnum]._pBFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + if (random(3,10) == 0) ShieldDur(pnum); + return(RUN_AGAIN); + } else return(RUN_DONE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoSpell(int pnum) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoSpell: illegal player %d",pnum); + + if (plr[pnum]._pVar8 == plr[pnum]._pSFNum) { + CastSpell(pnum, plr[pnum]._pSpell, plr[pnum]._px, plr[pnum]._py, plr[pnum]._pVar1, plr[pnum]._pVar2, MI_PLR, plr[pnum]._pVar4); + if (plr[pnum]._pSplFrom == SPL_FROMR) { + if (plr[pnum]._pRSplType == SPT_SCROLL) { + if ((plr[pnum]._pScrlSpells & (((__int64)1) << (plr[pnum]._pRSpell-1))) == 0) { + plr[pnum]._pRSpell = -1; + plr[pnum]._pRSplType = SPT_NONE; + force_redraw = FULLDRAW; + } + } + if (plr[pnum]._pRSplType == SPT_ITEM) { + if (((plr[pnum]._pISpells & (((__int64)1) << (plr[pnum]._pRSpell-1)))) == 0) { + plr[pnum]._pRSpell = -1; + plr[pnum]._pRSplType = SPT_NONE; + force_redraw = FULLDRAW; + } + } + } + } + plr[pnum]._pVar8++; + if (leveltype == 0) { + if (plr[pnum]._pVar8 > plr[pnum]._pSFrames) { + StartWalkStand(pnum); + ClearPlrPVars(pnum); + return(RUN_AGAIN); + } else return(RUN_DONE); + } else { + if (plr[pnum]._pAnimFrame == plr[pnum]._pSFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + return(RUN_AGAIN); + } else return(RUN_DONE); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void ArmorDur(int pnum) { + if (pnum != myplr) return; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("ArmorDur: illegal player %d",pnum); + + PlayerStruct * p = &plr[pnum]; + if (p->BodyItem._itype == -1 && p->HeadItem._itype == -1) return; + + // Head or body hit? + int a = random(8, 3); + if (p->BodyItem._itype != -1 && p->HeadItem._itype == -1) a = 1; + if (p->BodyItem._itype == -1 && p->HeadItem._itype != -1) a = 0; + + ItemStruct * pi = a ? &p->BodyItem : &p->HeadItem; + if (pi->_iDurability == INFINITE_DUR) return; + + // lose some durability + pi->_iDurability--; + if (pi->_iDurability == 0) { + if (a) NetSendCmdDelItem(TRUE, INVLOC_BODY); + else NetSendCmdDelItem(TRUE, INVLOC_HEAD); + pi->_itype = -1; + CalcPlrInv(pnum,TRUE); + } +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +int PM_DoGotHit(int pnum) +{ + int rv; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoGotHit: illegal player %d",pnum); + + if (plr[pnum]._pIFlags & IAF_ALLHTANIM) + { + int htanimframes = 3; + if (plr[pnum]._pIFlags & IAF_HTANIM2) + htanimframes = 4; + if (plr[pnum]._pIFlags & IAF_HTANIM3) + htanimframes = 5; + + if (plr[pnum]._pVar8 > 1 && plr[pnum]._pVar8 < htanimframes) + plr[pnum]._pVar8 = htanimframes; + + // make sure we didn't go too far + if (plr[pnum]._pVar8 > plr[pnum]._pHFrames) + plr[pnum]._pVar8 = plr[pnum]._pHFrames; + } + if (plr[pnum]._pVar8 == plr[pnum]._pHFrames) { + StartStand(pnum, plr[pnum]._pdir); + ClearPlrPVars(pnum); + if (random(3,4)) ArmorDur(pnum); + rv = RUN_AGAIN; + } else { + plr[pnum]._pVar8++; + rv = RUN_DONE; + } + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoDeath(int pnum) +{ + int rv; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("PM_DoDeath: illegal player %d",pnum); + + // Hold last frame + if (plr[pnum]._pVar8 >= (plr[pnum]._pDFrames << 1)) { + if ((deathdelay > 1) && (pnum == myplr)) { + deathdelay--; + if (deathdelay == 1) { + deathflag = TRUE; + if (gbMaxPlayers == 1) gamemenu_on(); + } + } + plr[pnum]._pAnimDelay = 10000; + plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen; + dFlags[plr[pnum]._px][plr[pnum]._py] |= BFLAG_DEADPLR; + } + if (plr[pnum]._pVar8 < 100) plr[pnum]._pVar8++; + rv = RUN_DONE; + + return(rv); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int PM_DoNewLvl(int pnum) +{ + return(RUN_DONE); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckNewPath(int pnum) +{ + int i, dx, dy, d, oi; + int v1,v2,v3; + + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("CheckNewPath: illegal player %d",pnum); + + if (plr[pnum].destAction == PCMD_ATTACKID) { + i = plr[pnum].destParam1; + MakePlrPath(pnum, monster[i]._mfutx, monster[i]._mfuty, FALSE); + } + if (plr[pnum].destAction == PCMD_ATTACKPID) { + i = plr[pnum].destParam1; + MakePlrPath(pnum, plr[i]._pfutx, plr[i]._pfuty, FALSE); + } + if (plr[pnum].walkpath[0] != PCMD_NOTHING) { + if (plr[pnum]._pmode == PM_STAND) { + // Special case for attack + if (pnum == myplr) { + if ((plr[pnum].destAction == PCMD_ATTACKID) || (plr[pnum].destAction == PCMD_ATTACKPID)) { + i = plr[pnum].destParam1; + if (plr[pnum].destAction == PCMD_ATTACKID) { + dx = abs(plr[pnum]._pfutx - monster[i]._mfutx); + dy = abs(plr[pnum]._pfuty - monster[i]._mfuty); + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, monster[i]._mfutx, monster[i]._mfuty); + } else { + dx = abs(plr[pnum]._pfutx - plr[i]._pfutx); + dy = abs(plr[pnum]._pfuty - plr[i]._pfuty); + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, plr[i]._pfutx, plr[i]._pfuty); + } + if ((dx < 2) && (dy < 2)) { + ClrPlrPath(pnum); + if ((monster[i].mtalkmsg !=0) && (monster[i].mtalkmsg != TXT_VB2)) TalktoMonster(i); + else StartAttack(pnum, d); + plr[pnum].destAction = PCMD_NOTHING; + } + } + } + if (currlevel != 0) { + v1 = PlrWalkTbl[plr[pnum]._pClass][0]; + v2 = PlrWalkTbl[plr[pnum]._pClass][1]; + v3 = PlrWalkTbl[plr[pnum]._pClass][2]; + } else { + v1 = 2048; + v2 = 1024; + v3 = 512; + } + switch(plr[pnum].walkpath[0]) { + case PCMD_WALKU : + StartWalk(pnum, 0, -v2, -1, -1, DIR_U, SCRL_U); + break; + case PCMD_WALKUR : + StartWalk(pnum, v2, -v3, 0, -1, DIR_UR, SCRL_UR); + break; + case PCMD_WALKR : + StartWalk3(pnum, v1, 0, -32, -16, 1, -1, 1, 0, DIR_R, SCRL_R); + break; + case PCMD_WALKDR : + StartWalk2(pnum, v2, v3, -32, -16, 1, 0, DIR_DR, SCRL_DR); + break; + case PCMD_WALKD : + StartWalk2(pnum, 0, v2, 0, -32, 1, 1, DIR_D, SCRL_D); + break; + case PCMD_WALKDL : + StartWalk2(pnum, -v2, v3, 32, -16, 0, 1, DIR_DL, SCRL_DL); + break; + case PCMD_WALKL : + StartWalk3(pnum, -v1, 0, 32, -16, -1, 1, 0, 1, DIR_L, SCRL_L); + break; + case PCMD_WALKUL : + StartWalk(pnum, -v2, -v3, -1 ,0, DIR_UL, SCRL_UL); + break; + } + for (i = 1; i < MAXPATHLEN; i++) plr[pnum].walkpath[i-1] = plr[pnum].walkpath[i]; + plr[pnum].walkpath[MAXPATHLEN-1] = PCMD_NOTHING; + // if walk fails then start standing + if (plr[pnum]._pmode == PM_STAND) { + StartStand(pnum, plr[pnum]._pdir); + plr[pnum].destAction = PCMD_NOTHING; + } + } + } else { + if (plr[pnum].destAction != PCMD_NOTHING) { + if (plr[pnum]._pmode == PM_STAND) { + switch (plr[pnum].destAction) { + case PCMD_ATTACK : + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[pnum].destParam1, plr[pnum].destParam2); + StartAttack(pnum, d); + break; + case PCMD_ATTACKID : + i = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - monster[i]._mfutx); + dy = abs(plr[pnum]._py - monster[i]._mfuty); + if ((dx <= 1) && (dy <= 1)) { + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, monster[i]._mfutx, monster[i]._mfuty); + if ((monster[i].mtalkmsg !=0) && (monster[i].mtalkmsg != TXT_VB2)) TalktoMonster(i); + else StartAttack(pnum, d); + } + break; + case PCMD_ATTACKPID: + i = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - plr[i]._pfutx); + dy = abs(plr[pnum]._py - plr[i]._pfuty); + if ((dx <= 1) && (dy <= 1)) { + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, plr[i]._pfutx, plr[i]._pfuty); + StartAttack(pnum, d); + } + break; + case PCMD_RATTACK: + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[pnum].destParam1, plr[pnum].destParam2); + StartRangeAttack(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2); + break; + case PCMD_RATTACKID: + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, monster[i]._mfutx, monster[i]._mfuty); + if ((monster[i].mtalkmsg !=0) && (monster[i].mtalkmsg != TXT_VB2)) TalktoMonster(i); + else StartRangeAttack(pnum, d, monster[i]._mfutx, monster[i]._mfuty); + break; + case PCMD_RATTACKPID: + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, plr[i]._pfutx, plr[i]._pfuty); + StartRangeAttack(pnum, d, plr[i]._pfutx, plr[i]._pfuty); + break; + case PCMD_SPELL: + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[pnum].destParam1, plr[pnum].destParam2); + StartSpell(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2); + plr[pnum]._pVar4 = plr[pnum].destParam3; + break; + case PCMD_SPELLXYD: + StartSpell(pnum, plr[pnum].destParam3, plr[pnum].destParam1, plr[pnum].destParam2); + plr[pnum]._pVar3 = plr[pnum].destParam3; + plr[pnum]._pVar4 = plr[pnum].destParam4; + break; + case PCMD_SPELLID: + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mfutx, monster[i]._mfuty); + StartSpell(pnum, d, monster[i]._mfutx, monster[i]._mfuty); + plr[pnum]._pVar4 = plr[pnum].destParam2; + break; + case PCMD_SPELLPID: + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[i]._pfutx, plr[i]._pfuty); + StartSpell(pnum, d, plr[i]._pfutx, plr[i]._pfuty); + plr[pnum]._pVar4 = plr[pnum].destParam2; + break; + case PCMD_OPOBJ: + oi = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - object[oi]._ox); + dy = abs(plr[pnum]._py - object[oi]._oy); + if ((dy > 1) && (dObject[object[oi]._ox][object[oi]._oy-1] == (-1 - oi))) + dy = abs(plr[pnum]._py - object[oi]._oy + 1); + + if ((dx <= 1) && (dy <= 1)) { + if (object[oi]._oBreak == OBJ_BREAKABLE) { + d = GetDirection(plr[pnum]._px, plr[pnum]._py, object[oi]._ox, object[oi]._oy); + StartAttack(pnum, d); + } else OperateObject(pnum, oi, FALSE); + } + break; + case PCMD_DISARM: + oi = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - object[oi]._ox); + dy = abs(plr[pnum]._py - object[oi]._oy); + if ((dy > 1) && (dObject[object[oi]._ox][object[oi]._oy-1] == (-1 - oi))) + dy = abs(plr[pnum]._py - object[oi]._oy + 1); + if ((dx <= 1) && (dy <= 1)) { + if (object[oi]._oBreak == OBJ_BREAKABLE) { + d = GetDirection(plr[pnum]._px, plr[pnum]._py, object[oi]._ox, object[oi]._oy); + StartAttack(pnum, d); + } else { + TryDisarm(pnum, oi); + OperateObject(pnum, oi, FALSE); + } + } + break; + case PCMD_TELEK: + oi = plr[pnum].destParam1; + if (object[oi]._oBreak != OBJ_BREAKABLE) OperateObject(pnum, oi, TRUE); + break; + case PCMD_REQGETITEM : + if (pnum == myplr) { + i = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - item[i]._ix); + dy = abs(plr[pnum]._py - item[i]._iy); + // PATCH1.JMM + //if ((dx <= 1) && (dy <= 1) && (curs == GLOVE_CURS) && (!item[i]._iRequest) && (!item[i]._iDelFlag)) { + if ((dx <= 1) && (dy <= 1) && (curs == GLOVE_CURS) && (!item[i]._iRequest)) { + // ENDPATCH1.JMM + NetSendCmdGItem(TRUE, CMD_REQUESTGITEM, myplr, myplr, i); + item[i]._iRequest = TRUE; + } + } + break; + case PCMD_REQAGETITEM : + if (pnum == myplr) { + i = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - item[i]._ix); + dy = abs(plr[pnum]._py - item[i]._iy); + if ((dx <= 1) && (dy <= 1) && (curs == GLOVE_CURS)) + NetSendCmdGItem(TRUE, CMD_REQUESTAGITEM, myplr, myplr, i); + } + break; + case PCMD_TALK: + if (pnum == myplr) TalkToTowner(pnum, plr[pnum].destParam1); + break; + } + FixPlayerLocation(pnum,plr[pnum]._pdir); + plr[pnum].destAction = PCMD_NOTHING; + } else { + if ((plr[pnum]._pmode == PM_ATTACK) && (plr[pnum]._pAnimFrame > plr[myplr]._pAFNum)) { + if (plr[pnum].destAction == PCMD_ATTACK) { + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, plr[pnum].destParam1, plr[pnum].destParam2); + StartAttack(pnum, d); + plr[pnum].destAction = PCMD_NOTHING; + } + else if (plr[pnum].destAction == PCMD_ATTACKID) { + i = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - monster[i]._mfutx); + dy = abs(plr[pnum]._py - monster[i]._mfuty); + if ((dx <= 1) && (dy <= 1)) { + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, monster[i]._mfutx, monster[i]._mfuty); + StartAttack(pnum, d); + } + plr[pnum].destAction = PCMD_NOTHING; + } + else if (plr[pnum].destAction == PCMD_ATTACKPID) { + i = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - plr[i]._pfutx); + dy = abs(plr[pnum]._py - plr[i]._pfuty); + if ((dx <= 1) && (dy <= 1)) { + d = GetDirection(plr[pnum]._pfutx, plr[pnum]._pfuty, plr[i]._pfutx, plr[i]._pfuty); + StartAttack(pnum, d); + } + plr[pnum].destAction = PCMD_NOTHING; + } + else if (plr[pnum].destAction == PCMD_OPOBJ) + { + oi = plr[pnum].destParam1; + dx = abs(plr[pnum]._px - object[oi]._ox); + dy = abs(plr[pnum]._py - object[oi]._oy); + if ((dy > 1) && (dObject[object[oi]._ox][object[oi]._oy-1] == (-1 - oi))) + dy = abs(plr[pnum]._py - object[oi]._oy + 1); + if ((dx <= 1) && (dy <= 1)) { + if (object[oi]._oBreak == OBJ_BREAKABLE) { + d = GetDirection(plr[pnum]._px, plr[pnum]._py, object[oi]._ox, object[oi]._oy); + StartAttack(pnum, d); + } else OperateObject(pnum, oi, FALSE); + } + } + } + if ((plr[pnum]._pmode == PM_RATTACK) && (plr[pnum]._pAnimFrame > plr[myplr]._pAFNum)) { + if (plr[pnum].destAction == PCMD_RATTACK) { + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[pnum].destParam1, plr[pnum].destParam2); + StartRangeAttack(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2); + plr[pnum].destAction = PCMD_NOTHING; + } + else if (plr[pnum].destAction == PCMD_RATTACKID) { + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mfutx, monster[i]._mfuty); + StartRangeAttack(pnum, d, monster[i]._mfutx, monster[i]._mfuty); + plr[pnum].destAction = PCMD_NOTHING; + } + else if (plr[pnum].destAction == PCMD_RATTACKPID) { + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[i]._pfutx, plr[i]._pfuty); + StartRangeAttack(pnum, d, plr[i]._pfutx, plr[i]._pfuty); + plr[pnum].destAction = PCMD_NOTHING; + } + } + if ((plr[pnum]._pmode == PM_SPELL) && (plr[pnum]._pAnimFrame > plr[pnum]._pSFNum)) { + if (plr[pnum].destAction == PCMD_SPELL) { + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[pnum].destParam1, plr[pnum].destParam2); + StartSpell(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2); + plr[pnum].destAction = PCMD_NOTHING; + } + else if (plr[pnum].destAction == PCMD_SPELLID) { + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mfutx, monster[i]._mfuty); + StartSpell(pnum, d, monster[i]._mfutx, monster[i]._mfuty); + plr[pnum].destAction = PCMD_NOTHING; + } + else if (plr[pnum].destAction == PCMD_SPELLPID) { + i = plr[pnum].destParam1; + d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[i]._pfutx, plr[i]._pfuty); + StartSpell(pnum, d, plr[i]._pfutx, plr[i]._pfuty); + plr[pnum].destAction = PCMD_NOTHING; + } + } + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PlrDeathModeOK(int p) +{ + if (p != myplr) return(TRUE); + if ((DWORD)p >= MAX_PLRS) + app_fatal("PlrDeathModeOK: illegal player %d",p); + if (plr[p]._pmode == PM_DEATH) return(TRUE); + if (plr[p]._pmode == PM_QUIT) return(TRUE); + if (plr[p]._pmode == PM_NEWLVL) return(TRUE); + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ValidatePlayer() +{ + int i, gt, pc; + //jam.patch1.start.1/23/97 + //__int64 msk; + __int64 msk = 0; + //jam.patch1.end.1/23/97 + __int64 b = 1; + + if ((DWORD)myplr >= MAX_PLRS) + app_fatal("ValidatePlayer: illegal player %d",myplr); + if (plr[myplr]._pLevel > 50) plr[myplr]._pLevel = 50; + if (plr[myplr]._pExperience > plr[myplr]._pNextExper) + plr[myplr]._pExperience = plr[myplr]._pNextExper; + gt = 0; + for (i = 0; i < plr[myplr]._pNumInv; i++) { + if (plr[myplr].InvList[i]._itype == IT_GOLD) { + if (plr[myplr].InvList[i]._ivalue > GOLD_DOUBLE_VMAX) plr[myplr].InvList[i]._ivalue = GOLD_DOUBLE_VMAX; + gt += plr[myplr].InvList[i]._ivalue; + } + } + if (gt != plr[myplr]._pGold) plr[myplr]._pGold = gt; + pc = plr[myplr]._pClass; + if (plr[myplr]._pBaseStr > MaxStats[pc][0]) plr[myplr]._pBaseStr = MaxStats[pc][0]; + if (plr[myplr]._pBaseMag > MaxStats[pc][1]) plr[myplr]._pBaseMag = MaxStats[pc][1]; + if (plr[myplr]._pBaseDex > MaxStats[pc][2]) plr[myplr]._pBaseDex = MaxStats[pc][2]; + if (plr[myplr]._pBaseVit > MaxStats[pc][3]) plr[myplr]._pBaseVit = MaxStats[pc][3]; + + for (i = SPL_FIREBOLT; i < SPL_LAST; i++) { + if (spelldata[i].sBookLvl != -1) { + msk |= (b << (i-1)); + if (plr[myplr]._pSplLvl[i] > SPELLCAP) plr[myplr]._pSplLvl[i] = SPELLCAP; + } + } + plr[myplr]._pMemSpells &= msk; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +int pdoppely = DIRTEDGED2; + +void PlayerDoppel() +{ + int pdoppelx, pidx; + PlayerStruct *p; + BOOL forceclear; + + if (gbMaxPlayers == 1) return; + + for (pdoppelx = DIRTEDGED2; pdoppelx < (DIRTEDGED2+80); pdoppelx++) { + if (dPlayer[pdoppelx][pdoppely]) { + if (dPlayer[pdoppelx][pdoppely] > 0) + pidx = dPlayer[pdoppelx][pdoppely] - 1; + else + pidx = -(dPlayer[pdoppelx][pdoppely] + 1); + p = &plr[pidx]; + forceclear = FALSE; + if (p->plrlevel != currlevel) forceclear = TRUE; + if (!p->plractive) forceclear = TRUE; + if (!forceclear) { + if ((p->_pmode >= PM_WALK) && (p->_pmode <= PM_WALK3)) continue; + if (p->_pmode >= PM_NEWLVL) continue; + if ((p->_px == pdoppelx) && (p->_py == pdoppely)) continue; + forceclear = TRUE; + } + if (forceclear) { + dFlags[pdoppelx+1][pdoppely+0] &= BFMASK_PLRLR; + dFlags[pdoppelx+0][pdoppely+1] &= BFMASK_PLRLR; + dPlayer[pdoppelx][pdoppely] = 0; + } + } + } + pdoppely++; + if (pdoppely == DIRTEDGED2+80) pdoppely = DIRTEDGED2; +} +// PATCH2.JMM.3/5/97 +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#define MAX_STAT 750 +#define MAX_HP (2000< MAX_STAT ) + plr[pnum]._pStrength = MAX_STAT; + + if ( plr[pnum]._pDexterity > MAX_STAT ) + plr[pnum]._pDexterity = MAX_STAT; + + if ( plr[pnum]._pMagic > MAX_STAT ) + plr[pnum]._pMagic = MAX_STAT; + + if ( plr[pnum]._pVitality > MAX_STAT ) + plr[pnum]._pVitality = MAX_STAT; + + if ( plr[pnum]._pHitPoints > MAX_HP ) + plr[pnum]._pHitPoints = MAX_HP; + + if ( plr[pnum]._pMana > MAX_MANA ) + plr[pnum]._pMana = MAX_MANA; + +} +// ENDPATCH2 + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ProcessPlayers() +{ + int raflag; // Run again flag + int pnum; + + if ((DWORD)myplr >= MAX_PLRS) + app_fatal("ProcessPlayers: illegal player %d",myplr); + + // TEMP! debugging + for (int i = 0; i < MAXINV; i++) { + if (plr[myplr].InvGrid[i] > 0) + app_assert(plr[myplr].InvGrid[i] <= plr[myplr]._pNumInv); + } + + if (plr[myplr].pLvlLoad > 0) plr[myplr].pLvlLoad--; + + if (sfxdelay > 0) { + sfxdelay--; + if (sfxdelay == 0) + { + switch (sfxdnum) + { + case HSFX_DEFILER1: + InitQTextMsg(TXT_DEFILER1); + break; + case HSFX_DEFILER2: + InitQTextMsg(TXT_DEFILER2); + break; + case HSFX_DEFILER3: + InitQTextMsg(TXT_DEFILER3); + break; + case HSFX_DEFILER4: + InitQTextMsg(TXT_DEFILER4); + break; + default: + PlaySFX(sfxdnum); + } + } + } + + ValidatePlayer(); + + for (pnum = 0; pnum < MAX_PLRS; pnum++) { + if (!plr[pnum].plractive) continue; + if (currlevel != plr[pnum].plrlevel) continue; + if ((pnum != myplr) && (plr[pnum]._pLvlChanging)) continue; + + // PATCH2.JMM.3/5/97 + CheckCheatStats( pnum ); + // PATCH2.JMM.3/5/97 + + + + + if ((!PlrDeathModeOK(pnum)) && ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0)) { + // rjs - manashld fix? - SetPlayerHitPoints(pnum, 0); + StartPlrKill(pnum, KILL_UNKNOWN); + } + + if (pnum == myplr) { + // Constricting item + if ((plr[pnum]._pIFlags & IAF_CONSTRICT) && (currlevel != 0)) { + plr[pnum]._pHitPoints -= 4; + plr[pnum]._pHPBase -= 4; + if ((plr[pnum]._pHitPoints >> HP_SHIFT) <= 0) { + // rjs - manashld fix? - SetPlayerHitPoints(pnum, 0); + StartPlrKill(pnum, FALSE); + } + drawhpflag = TRUE; + } + + // lose mana item + if (plr[pnum]._pIFlags & IAF_LMANA) { + if (plr[pnum]._pManaBase > 0 ) { + plr[pnum]._pManaBase -= plr[pnum]._pMana; + plr[pnum]._pMana = 0; + drawmanaflag = TRUE; + } + } + } + + raflag = RUN_DONE; + do { + // Run Player Mode + switch (plr[pnum]._pmode) { + case PM_STAND : + raflag = PM_DoStand(pnum); + break; + case PM_WALK : + raflag = PM_DoWalk(pnum); + break; + case PM_WALK2 : + raflag = PM_DoWalk2(pnum); + break; + case PM_WALK3: + raflag = PM_DoWalk3(pnum); + break; + case PM_ATTACK: + raflag = PM_DoAttack(pnum); + break; + case PM_RATTACK: + raflag = PM_DoRangeAttack(pnum); + break; + case PM_BLOCK : + raflag = PM_DoBlock(pnum); + break; + case PM_SPELL: + raflag = PM_DoSpell(pnum); + break; + case PM_GOTHIT: + raflag = PM_DoGotHit(pnum); + break; + case PM_DEATH: + raflag = PM_DoDeath(pnum); + break; + case PM_NEWLVL: + raflag = PM_DoNewLvl(pnum); + break; + } + + // Check for new command + CheckNewPath(pnum); + + } while (raflag != RUN_DONE); + + // Animate Player + plr[pnum]._pAnimCnt++; + if (plr[pnum]._pAnimCnt > plr[pnum]._pAnimDelay) { + plr[pnum]._pAnimCnt = 0; + plr[pnum]._pAnimFrame++; + if (plr[pnum]._pAnimFrame > plr[pnum]._pAnimLen) plr[pnum]._pAnimFrame = 1; + } + } + + //PlayerDoppel(); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void ClrPlrPath(int pnum) { + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("ClrPlrPath: illegal player %d",pnum); + FillMemory(plr[pnum].walkpath,MAXPATHLEN,PCMD_NOTHING); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL PosOkPlayer(int pnum, int px, int py) +{ + int mi, p, pn; + char bv; + + if (dPiece[px][py] == 0) return FALSE; + pn = dPiece[px][py]; + if (SolidLoc(px, py)) return FALSE; + if (dPlayer[px][py]) { + if (dPlayer[px][py] > 0) p = dPlayer[px][py] - 1; + else p = -(dPlayer[px][py] + 1); + if ((p != pnum) && (plr[p]._pHitPoints != 0)) return FALSE; + } + if (dMonster[px][py]) { + if (currlevel == 0) return FALSE; + if (dMonster[px][py] > 0) { + mi = dMonster[px][py] - 1; + if ((monster[mi]._mhitpoints >> HP_SHIFT) > 0) return FALSE; + } else return FALSE; + } + if (dObject[px][py]) { + if (dObject[px][py] > 0) bv = dObject[px][py] - 1; + else bv = -(dObject[px][py] + 1); + if (object[bv]._oSolidFlag) return FALSE; + } + return TRUE; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void MakePlrPath(int pnum, int xx, int yy, BOOL endspace) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("MakePlrPath: illegal player %d",pnum); + + // set target position + plr[pnum]._ptargx = xx; + plr[pnum]._ptargy = yy; + + if (plr[pnum]._pfutx == xx && plr[pnum]._pfuty == yy) + return; + + int pathlen = FindPath(PosOkPlayer, pnum, plr[pnum]._pfutx, plr[pnum]._pfuty, xx, yy, plr[pnum].walkpath); + if(pathlen) { + if (!endspace) { + pathlen--; + switch (plr[pnum].walkpath[pathlen]) { + case PCMD_WALKUR: + yy++; + break; + case PCMD_WALKUL: + xx++; + break; + case PCMD_WALKDR: + xx--; + break; + case PCMD_WALKDL: + yy--; + break; + case PCMD_WALKU: + xx++; + yy++; + break; + case PCMD_WALKR: + xx--; + yy++; + break; + case PCMD_WALKD: + xx--; + yy--; + break; + case PCMD_WALKL: + xx++; + yy--; + break; + } + plr[pnum]._ptargx = xx; + plr[pnum]._ptargy = yy; + } + plr[pnum].walkpath[pathlen] = PCMD_NOTHING; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckPlrSpell() +{ + int sd; + BOOL addflag = FALSE; + + if ((DWORD)myplr >= MAX_PLRS) + app_fatal("CheckPlrSpell: illegal player %d",myplr); + + int rspell = plr[myplr]._pRSpell; + + if (rspell == -1) { + if (plr[myplr]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR34); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE34); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE34); + else if (plr[myplr]._pClass == CLASS_MONK) PlaySFX(PS_MONK34); + else if (plr[myplr]._pClass == CLASS_BARD) PlaySFX(PS_BARD34); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN34); + #endif + return; + } + + //rjs if (leveltype == 0) return; + if (leveltype == 0 && spelldata[plr[myplr]._pRSpell].sTownSpell == FALSE) { + if (plr[myplr]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR27); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE27); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE27); + else if (plr[myplr]._pClass == CLASS_MONK) PlaySFX(PS_MONK27); + else if (plr[myplr]._pClass == CLASS_BARD) PlaySFX(PS_BARD27); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN27); + #endif + return; + } + if (curs != GLOVE_CURS) return; + + // Check if cursor is in play area, allowing certain spells to be executed anywhere + if (!(((MouseY < 352) + && !(chrflag && MouseX < 320) + && !(invflag && MouseX > 320)) || + ((MouseY < 352) && (rspell == SPL_HEAL + || rspell == SPL_IDENTIFY + || rspell == SPL_REPAIR + || rspell == SPL_INFRA + || rspell == SPL_RECHARGE)))) + return; + + switch (plr[myplr]._pRSplType) { + case SPT_ABILITY : + case SPT_MEMORIZED : + addflag = CheckSpell(myplr, plr[myplr]._pRSpell, plr[myplr]._pRSplType, FALSE); + break; + case SPT_SCROLL : + addflag = UseScroll(); + break; + case SPT_ITEM: + addflag = UseStaff(); + break; + } + if (addflag) { + if (plr[myplr]._pRSpell == SPL_WALL + || plr[myplr]._pRSpell == SPL_LTWALL) { + sd = GetDirection(plr[myplr]._px, plr[myplr]._py, cursmx, cursmy); + NetSendCmdLocParam3(TRUE, CMD_SPELLXYD, cursmx, cursmy, plr[myplr]._pRSpell, sd, GetSpellLevel(myplr, plr[myplr]._pRSpell)); + } else { + if (cursmonst != -1) NetSendCmdParam3(TRUE, CMD_SPELLID, cursmonst, plr[myplr]._pRSpell,GetSpellLevel(myplr, plr[myplr]._pRSpell)); + else { + if (cursplr != -1) NetSendCmdParam3(TRUE, CMD_SPELLPID, cursplr, plr[myplr]._pRSpell,GetSpellLevel(myplr, plr[myplr]._pRSpell)); + else NetSendCmdLocParam2(TRUE, CMD_SPELLXY, cursmx, cursmy, plr[myplr]._pRSpell,GetSpellLevel(myplr, plr[myplr]._pRSpell)); + } + } + } else { + if (plr[myplr]._pRSplType == SPT_MEMORIZED) { + if (plr[myplr]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR35); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE35); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE35); + else if (plr[myplr]._pClass == CLASS_MONK) PlaySFX(PS_MONK35); + else if (plr[myplr]._pClass == CLASS_BARD) PlaySFX(PS_BARD35); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN35); + #endif + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SyncPlrAnim(int p) +{ + int dir, s; + + if ((DWORD)p >= MAX_PLRS) + app_fatal("SyncPlrAnim: illegal player %d",p); + + dir = plr[p]._pdir; + switch (plr[p]._pmode) { + case PM_STAND : + plr[p]._pAnimData = plr[p]._pNAnim[dir]; + break; + case PM_WALK : + plr[p]._pAnimData = plr[p]._pWAnim[dir]; + break; + case PM_WALK2 : + plr[p]._pAnimData = plr[p]._pWAnim[dir]; + break; + case PM_WALK3: + plr[p]._pAnimData = plr[p]._pWAnim[dir]; + break; + case PM_ATTACK: + plr[p]._pAnimData = plr[p]._pAAnim[dir]; + break; + case PM_RATTACK: + plr[p]._pAnimData = plr[p]._pAAnim[dir]; + break; + case PM_BLOCK: + plr[p]._pAnimData = plr[p]._pBAnim[dir]; + break; + case PM_SPELL: + if (p == myplr) s = spelldata[plr[p]._pSpell].sType; + //jam.patch1.start.1/23/97 + //else s == ST_FIRE; + else s = ST_FIRE; + //jam.patch1.end.1/23/97 + if (s == ST_FIRE) plr[p]._pAnimData = plr[p]._pFAnim[dir]; + if (s == ST_LIGHT) plr[p]._pAnimData = plr[p]._pLAnim[dir]; + if (s == ST_MISC) plr[p]._pAnimData = plr[p]._pTAnim[dir]; + break; + case PM_GOTHIT: + plr[p]._pAnimData = plr[p]._pHAnim[dir]; + break; + case PM_DEATH: + plr[p]._pAnimData = plr[p]._pDAnim[dir]; + break; + case PM_NEWLVL: + case PM_QUIT: + plr[p]._pAnimData = plr[p]._pNAnim[dir]; + break; + default: + app_fatal("SyncPlrAnim"); + break; + } + + app_assert(plr[p]._pAnimData); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SyncInitPlrPos(int pnum) +{ + // Force the player's target position to be where he wants it to be + plr[pnum]._ptargx = plr[pnum]._px; + plr[pnum]._ptargy = plr[pnum]._py; + + // Don't find a space for single player + if (gbMaxPlayers == 1) return; + + // Find a place to put him in the map + if (plr[pnum].plrlevel == currlevel) { + for (int i = 0; i < sizeof(plrxoff2)/sizeof(plrxoff2[0]) - 1; i++) { + if (PosOkPlayer( + pnum, + plr[pnum]._px + plrxoff2[i], + plr[pnum]._py + plryoff2[i] + )) break; + } + + // stuff player into the map + plr[pnum]._px += plrxoff2[i]; + plr[pnum]._py += plryoff2[i]; + dPlayer[plr[pnum]._px][plr[pnum]._py] = pnum + 1; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SyncInitPlr(int pnum) { + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("SyncInitPlr: illegal player %d",pnum); + + SetPlrAnims(pnum); + SyncInitPlrPos(pnum); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CheckStats(int p) +/*-----------------------------------------------------------------------* +** Description: Checks to see if specified characters base stat value +** is greater than the max base stat, or less than 0. +** If characters base stat > max. stat, then set characters base +** stat = max. stat. If characters base stat < 0, then set +** characters base stat = 0. +** Input: p = plr[?] index +** s = stat to check +** Return: None +**-----------------------------------------------------------------------*/ +{ + int c, i; + + if ((DWORD)p >= MAX_PLRS) + app_fatal("CheckStats: illegal player %d",p); + + //Find character class + if (plr[p]._pClass == CLASS_WARRIOR) c = 0; + else if (plr[p]._pClass == CLASS_ROGUE) c = 1; + else if (plr[p]._pClass == CLASS_SORCEROR) c = 2; + else if (plr[p]._pClass == CLASS_MONK) c = 3; + else if (plr[p]._pClass == CLASS_BARD) c = 4; + else if (plr[p]._pClass == CLASS_BARBARIAN) c = 5; + //Check stats + for (i = 0; i < 4; i++) { + switch(i) { + case 0: + //Strength + if (plr[p]._pBaseStr > MaxStats[c][0]) plr[p]._pBaseStr = MaxStats[c][0]; + else if (plr[p]._pBaseStr < 0) plr[p]._pBaseStr = 0; + break; + case 1: + //Magic + if (plr[p]._pBaseMag > MaxStats[c][1]) plr[p]._pBaseMag = MaxStats[c][1]; + else if (plr[p]._pBaseMag < 0) plr[p]._pBaseMag = 0; + break; + case 2: + //Dexterity + if (plr[p]._pBaseDex > MaxStats[c][2]) plr[p]._pBaseDex = MaxStats[c][2]; + else if (plr[p]._pBaseDex < 0) plr[p]._pBaseDex = 0; + break; + case 3: + //Vitality + if (plr[p]._pBaseVit > MaxStats[c][3]) plr[p]._pBaseVit = MaxStats[c][3]; + else if (plr[p]._pBaseVit < 0) plr[p]._pBaseVit = 0; + break; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ModifyPlrStr(int p, int l) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("ModifyPlrStr: illegal player %d",p); + int ms = MaxStats[plr[p]._pClass][0]; + if ((plr[p]._pBaseStr + l) > ms) l = ms - plr[p]._pBaseStr; + plr[p]._pStrength += l; + plr[p]._pBaseStr += l; +// if (plr[p]._pClass == CLASS_ROGUE || +// plr[p]._pClass == CLASS_MONK || +// plr[p]._pClass == CLASS_BARD) +// plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 200; +// else +// plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; + CalcPlrInv(p,TRUE); + if (p == myplr) NetSendCmdParam1(FALSE, CMD_SETSTR, plr[p]._pBaseStr); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ModifyPlrMag(int p, int l) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("ModifyPlrMag: illegal player %d",p); + int ms = MaxStats[plr[p]._pClass][1]; + if ((plr[p]._pBaseMag + l) > ms) l = ms - plr[p]._pBaseMag; + plr[p]._pMagic += l; + plr[p]._pBaseMag += l; + l = l << MANA_SHIFT; + if (plr[p]._pClass == CLASS_SORCEROR) l = l << 1; // 2x + else if (plr[p]._pClass == CLASS_BARD) l += l >> 1; // 1.5x + plr[p]._pMaxManaBase += l; + plr[p]._pMaxMana += l; + + if (!(plr[p]._pIFlags & IAF_LMANA)) { + plr[p]._pManaBase += l; + plr[p]._pMana += l; + } + CalcPlrInv(p,TRUE); + if (p == myplr) NetSendCmdParam1(FALSE, CMD_SETMAG, plr[p]._pBaseMag); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ModifyPlrDex(int p, int l) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("ModifyPlrDex: illegal player %d",p); + int ms = MaxStats[plr[p]._pClass][2]; + if ((plr[p]._pBaseDex + l) > ms) l = ms - plr[p]._pBaseDex; + plr[p]._pDexterity += l; + plr[p]._pBaseDex += l; + CalcPlrInv(p,TRUE); +// if (plr[p]._pClass == CLASS_ROGUE || +// plr[p]._pClass == CLASS_MONK || +// plr[p]._pClass == CLASS_BARD) +// { +// plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 200; +// } + if (p == myplr) NetSendCmdParam1(FALSE, CMD_SETDEX, plr[p]._pBaseDex); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ModifyPlrVit(int p, int l) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("ModifyPlrVit: illegal player %d",p); + int ms = MaxStats[plr[p]._pClass][3]; + if ((plr[p]._pBaseVit + l) > ms) l = ms - plr[p]._pBaseVit; + plr[p]._pVitality += l; + plr[p]._pBaseVit += l; + l = l << HP_SHIFT; + if (plr[p]._pClass == CLASS_WARRIOR + || plr[p]._pClass == CLASS_BARBARIAN) l = l << 1; + plr[p]._pHPBase += l; + plr[p]._pMaxHPBase += l; + plr[p]._pHitPoints += l; + plr[p]._pMaxHP += l; + CalcPlrInv(p,TRUE); + if (p == myplr) NetSendCmdParam1(FALSE, CMD_SETVIT, plr[p]._pBaseVit); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetPlayerHitPoints(int pnum, int newhp) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("SetPlayerHitPoints: illegal player %d",pnum); + plr[pnum]._pHitPoints = newhp; + plr[pnum]._pHPBase = newhp - (plr[pnum]._pMaxHP - plr[pnum]._pMaxHPBase); + if (pnum == myplr) drawhpflag = TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetPlrStr(int p, int v) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("SetPlrStr: illegal player %d",p); + plr[p]._pBaseStr = v; + CalcPlrInv(p,TRUE); +/* this stuff is done in CalcPlrInv */ +// if (plr[p]._pClass == CLASS_ROGUE || +// plr[p]._pClass == CLASS_MONK || +// plr[p]._pClass == CLASS_BARD) +// { +// plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 200; +// } +// else +// plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetPlrMag(int p, int v) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("SetPlrMag: illegal player %d",p); + plr[p]._pBaseMag = v; + v = v << MANA_SHIFT; + if (plr[p]._pClass == CLASS_SORCEROR) v = v << 1; // 2x + else if (plr[p]._pClass == CLASS_BARD) v += v >> 1; // 1.5x + plr[p]._pMaxManaBase = v; + plr[p]._pMaxMana = v; + CalcPlrInv(p,TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetPlrDex(int p, int v) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("SetPlrDex: illegal player %d",p); + plr[p]._pBaseDex = v; + CalcPlrInv(p,TRUE); +/* this stuff is done in CalcPlrInv */ +// if (plr[p]._pClass == CLASS_ROGUE || +// plr[p]._pClass == CLASS_MONK || +// plr[p]._pClass == CLASS_BARD) +// { +// plr[p]._pDamageMod = ((plr[p]._pStrength + plr[p]._pDexterity) * plr[p]._pLevel) / 200; +// } +// else +// plr[p]._pDamageMod = (plr[p]._pStrength * plr[p]._pLevel) / 100; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetPlrVit(int p, int v) +{ + if ((DWORD)p >= MAX_PLRS) + app_fatal("SetPlrVit: illegal player %d",p); + plr[p]._pBaseVit = v; + v = v << HP_SHIFT; + if (plr[p]._pClass == CLASS_WARRIOR + || plr[p]._pClass == CLASS_BARBARIAN) v = v << 1; + plr[p]._pHPBase = v; + plr[p]._pMaxHPBase = v; + CalcPlrInv(p,TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitDungMsgs(int pnum) +{ + if ((DWORD)pnum >= MAX_PLRS) + app_fatal("InitDungMsgs: illegal player %d",pnum); + plr[pnum].pDungMsgs = 0; + plr[pnum].pHellfireMsgs = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void PlayDungMsgs() +{ + if ((DWORD)myplr >= MAX_PLRS) + app_fatal("PlayDungMsgs: illegal player %d",myplr); + if ((currlevel == 1) && (!plr[myplr]._pLvlVisited[1]) && (gbMaxPlayers == 1) && (!(plr[myplr].pDungMsgs & DUNGMSG_1))) { + // play "The sancity of this place" speech + sfxdelay = 40; + #if !IS_VERSION(SHAREWARE) + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR97; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE97; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE97; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK97; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD97; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN97; + #else + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR97; + #endif + plr[myplr].pDungMsgs |= DUNGMSG_1; + } + + else if ((currlevel == 5) && (!plr[myplr]._pLvlVisited[5]) && (gbMaxPlayers == 1) && (!(plr[myplr].pDungMsgs & DUNGMSG_2))) { + // play "smells of death" speech + sfxdelay = 40; + #if !IS_VERSION(SHAREWARE) + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR96B; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE96; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE96; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK96; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD96; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN96; + #else + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR96B; + #endif + plr[myplr].pDungMsgs |= DUNGMSG_2; + } + + else if ((currlevel == 9) && (!plr[myplr]._pLvlVisited[9]) && (gbMaxPlayers == 1) && (!(plr[myplr].pDungMsgs & DUNGMSG_3))) { + // play "It's hot down here" speech + sfxdelay = 40; + #if !IS_VERSION(SHAREWARE) + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR98; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE98; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE98; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK98; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD98; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN98; + #else + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR98; + #endif + plr[myplr].pDungMsgs |= DUNGMSG_3; + } + + else if ((currlevel == 13) && (!plr[myplr]._pLvlVisited[13]) && (gbMaxPlayers == 1) && (!(plr[myplr].pDungMsgs & DUNGMSG_4))) { + // play "I must be getting close" speech + sfxdelay = 40; + #if !IS_VERSION(SHAREWARE) + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR99; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE99; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE99; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK99; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD99; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN99; + #else + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR99; + #endif + plr[myplr].pDungMsgs |= DUNGMSG_4; + } + + else if ((currlevel == 16) && (!plr[myplr]._pLvlVisited[15]) && (gbMaxPlayers == 1) && (!(plr[myplr].pDungMsgs & DUNGMSG_5))) { + // play "Diablo's Wrath" + sfxdelay = 40; + #if !IS_VERSION(SHAREWARE) + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_DIABLVLINT; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_DIABLVLINT; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_DIABLVLINT; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_DIABLVLINT; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_DIABLVLINT; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_DIABLVLINT; + #endif + plr[myplr].pDungMsgs |= DUNGMSG_5; + } + else if ((currlevel == HIVESTART) && (!plr[myplr]._pLvlVisited[HIVESTART]) && (gbMaxPlayers == 1) && (!(plr[myplr].pHellfireMsgs & DUNGMSG_1))) + { + // play Defiler 1 JKE + sfxdelay = 10; + sfxdnum = HSFX_DEFILER1; + quests[Q_DEFILER]._qactive = QUEST_NOTDONE; + quests[Q_DEFILER]._qlog = TRUE; + quests[Q_DEFILER]._qmsg = TXT_DEFILER1; + plr[myplr].pHellfireMsgs |= DUNGMSG_1; + } +/* else if ((currlevel == (HIVESTART+1)) && (!plr[myplr]._pLvlVisited[(HIVESTART+1)]) && (gbMaxPlayers == 1) && (!(plr[myplr].pHellfireMsgs & DUNGMSG_2))) { + // play Defiler 2 JKE + sfxdelay = 10; + sfxdnum = HSFX_DEFILER2; + plr[myplr].pHellfireMsgs |= DUNGMSG_2; + } */ + else if ((currlevel == (HIVESTART+2)) && (!plr[myplr]._pLvlVisited[(HIVESTART+2)]) && (gbMaxPlayers == 1) && (!(plr[myplr].pHellfireMsgs & DUNGMSG_3))) { + // play Defiler 3 JKE + sfxdelay = 10; + sfxdnum = HSFX_DEFILER3; + plr[myplr].pHellfireMsgs |= DUNGMSG_3; + } +/* else if ((currlevel == (HIVESTART+3)) && (!plr[myplr]._pLvlVisited[(HIVESTART+3)]) && (gbMaxPlayers == 1) && (!(plr[myplr].pHellfireMsgs & DUNGMSG_4))) { + // play Defiler 4 JKE + sfxdelay = 10; + sfxdnum = HSFX_DEFILER4; + plr[myplr].pHellfireMsgs |= DUNGMSG_4; + } */ + else if ((currlevel == CRYPTSTART) && (!plr[myplr]._pLvlVisited[CRYPTSTART]) && (gbMaxPlayers == 1) && (!(plr[myplr].pDungMsgs & DUNGMSG_6))) { + // play "great power " JKE + sfxdelay = 30; + +// sfxdnum = HSFX_CORNERSTONE1; +/* quests[Q_CORNERSTONE]._qactive = QUEST_NOTDONE; + quests[Q_CORNERSTONE]._qlog = TRUE; + quests[Q_CORNERSTONE]._qmsg = TXT_CORNERSTONE1; + InitQTextMsg(TXT_CORNERSTONE1); */ + + #if !IS_VERSION(SHAREWARE) + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR92; + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE92; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE92; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK92; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD92; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN92; + #else + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR92; + #endif + + plr[myplr].pDungMsgs |= DUNGMSG_6; + } + + else sfxdelay = 0; +} + + +int GetMaxStr(int Plrclass) +{ + return MaxStats[Plrclass][0]; +} + +int GetMaxMag(int Plrclass) +{ + return MaxStats[Plrclass][1]; +} + +int GetMaxDex(int Plrclass) +{ + return MaxStats[Plrclass][2]; +} diff --git a/PLAYER.H b/PLAYER.H new file mode 100644 index 0000000..2e751da --- /dev/null +++ b/PLAYER.H @@ -0,0 +1,520 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/PLAYER.H 3 2/22/97 12:54p Pwyatt $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ +#define MAXPACKLEN 256 + +#define PM_STAND 0 +#define PM_WALK 1 +#define PM_WALK2 2 +#define PM_WALK3 3 +#define PM_ATTACK 4 +#define PM_RATTACK 5 +#define PM_BLOCK 6 +#define PM_GOTHIT 7 +#define PM_DEATH 8 +#define PM_SPELL 9 +#define PM_NEWLVL 10 +#define PM_QUIT 11 + +#define PCMD_NOTHING -1 +#define PCMD_STAND 0 +#define PCMD_WALKUR 1 +#define PCMD_WALKUL 2 +#define PCMD_WALKDR 3 +#define PCMD_WALKDL 4 +#define PCMD_WALKU 5 +#define PCMD_WALKR 6 +#define PCMD_WALKD 7 +#define PCMD_WALKL 8 +#define PCMD_ATTACK 9 +#define PCMD_RATTACK 10 +#define PCMD_BLOCK 11 +#define PCMD_SPELL 12 +#define PCMD_OPOBJ 13 +#define PCMD_DISARM 14 +#define PCMD_REQGETITEM 15 +#define PCMD_REQAGETITEM 16 +#define PCMD_TALK 17 +#define PCMD_TELEK 18 +// free space +#define PCMD_ATTACKID 20 +#define PCMD_ATTACKPID 21 +#define PCMD_RATTACKID 22 +#define PCMD_RATTACKPID 23 +#define PCMD_SPELLID 24 +#define PCMD_SPELLPID 25 +#define PCMD_SPELLXYD 26 + +#define DIR_U 4 +#define DIR_UR 5 +#define DIR_R 6 +#define DIR_DR 7 +#define DIR_D 0 +#define DIR_DL 1 +#define DIR_L 2 +#define DIR_UL 3 + +#define PGFX_MASK 0x0f +#define PGFX_CMASK 0xf0 +#define PGFX_CSHIFT 4 + +#define PGFX_NGUY 0 // Nothing in hands +#define PGFX_SGUY 1 // Shield only +#define PGFX_XGUY 2 // Sword only +#define PGFX_GUY 3 // Sword and shield +#define PGFX_BGUY 4 // Bow +#define PGFX_FGUY 5 // Axe +#define PGFX_ZGUY 6 // Mace +#define PGFX_CGUY 7 // Mace and shield +#define PGFX_TGUY 8 // Staff + +#define PGFX_NMGUY 16 // Same as above, medium armor = 0x10 + plain version +#define PGFX_SMGUY 17 +#define PGFX_XMGUY 18 +#define PGFX_MGUY 19 +#define PGFX_BMGUY 20 +#define PGFX_FMGUY 21 +#define PGFX_ZMGUY 22 +#define PGFX_CMGUY 23 +#define PGFX_TMGUY 24 + +#define PGFX_NHGUY 32 // Same as above, heavy armor = 0x20 + plain version +#define PGFX_SHGUY 33 +#define PGFX_XHGUY 34 +#define PGFX_HGUY 35 +#define PGFX_BHGUY 36 +#define PGFX_FHGUY 37 +#define PGFX_ZHGUY 38 +#define PGFX_CHGUY 39 +#define PGFX_THGUY 40 + +#define PGL_STAND 0x0001 // Player gfx load +#define PGL_WALK 0x0002 +#define PGL_ATTACK 0x0004 +#define PGL_HIT 0x0008 +#define PGL_LMAG 0x0010 +#define PGL_FMAG 0x0020 +#define PGL_TMAG 0x0040 +#define PGL_DEAD 0x0080 +#define PGL_BLOCK 0x0100 +#define PGL_ALL 0x017f + +#define E_SINGLE 0 +#define E_DOUBLE 1 + + +#define CLASS_WARRIOR 0 +#define CLASS_ROGUE 1 +#define CLASS_SORCEROR 2 +#define CLASS_MONK 3 +#define CLASS_BARD 4 +#define CLASS_BARBARIAN 5 + +#define NUM_CLASSES (1 + CLASS_BARBARIAN) + +#define HP_SHIFT 6 // number of fractional bits for hit points +#define MANA_SHIFT 6 // number of fractional bits for mana points + +#define WEAP_H2H 0 +#define WEAP_RANGE 1 + +#define MAXPATHLEN 25 + +#define MAXINV 40 // maximum inventory items per player +#define MAXSPD 8 // maximum invertory speed items per player + +#define SPL_FROMR 0 // Current spell from readied spell +#define SPL_FROMBK 1 // Current spell from spell book +#define SPL_FROMT 2 // Current spell from targeted spell +#define SPL_FROMSB 3 // Current spell from scroll in speed bar + +#define PLR_NAME_LEN 32 + +#define BASE_TO_HIT 50 + +#define SF_ETHER 0x01 // Etheralize spell on +#define SF_RAGE 0x02 // Rage spell on. +#define SF_LETHERGY 0x04 // Lethergy spell on. +#define SF_FLAG4 0x08 // +#define SF_FLAG5 0x10 // +#define SF_FLAG6 0x20 // +#define SF_FLAG7 0x40 // +#define SF_FLAG8 0x80 // + + +#define INVLOC_HEAD 0 +#define INVLOC_RING1 1 +#define INVLOC_RING2 2 +#define INVLOC_NECK 3 + +#define INVLOC_HAND1 4 +#define INVLOC_HAND2 5 +#define INVLOC_BODY 6 +#define NUM_INVLOC 7 + +#define DUNGMSG_1 0x01 +#define DUNGMSG_2 0x02 +#define DUNGMSG_3 0x04 +#define DUNGMSG_4 0x08 +#define DUNGMSG_5 0x10 +#define DUNGMSG_6 0x20 // JKE CRYPT +#define DUNGMSG_7 0x40 // JKE HIVE +#define DUNGMSG_8 0x80 // JKEQUEST HIVE2 + +#define STAT_STR 0 +#define STAT_MAG 1 +#define STAT_DEX 2 +#define STAT_VIT 3 + +#define LVLCHANGE_OFF 0 +#define LVLCHANGE_TIME 10 + +#define KILL_UNKNOWN -1 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ +typedef struct { + int _pmode; // players current mode + + char walkpath[MAXPATHLEN]; + BYTE plractive; + + int destAction; + int destParam1; + int destParam2; + int destParam3; + int destParam4; + int plrlevel; + + int _px; // plr map x + int _py; // plr map y + int _pfutx; // plr future map x + int _pfuty; // plr future map y + int _ptargx; // final target x + int _ptargy; // final target y + int _pownerx; // x coord from computer which owns this player + int _pownery; // x coord from computer which owns this player + int _poldx; // plr old x position + int _poldy; // plr old y position + + long _pxoff; // offset x from left of map tile + long _pyoff; // offset y from bottom of map tile + long _pxvel; // current x rate + long _pyvel; // current y rate + int _pdir; // current player direction + int _nextdir; // Next direction wanted + int _pgfxnum; // Graphic set player number + BYTE *_pAnimData; // Data pointer to anim tables + int _pAnimDelay; // anim delay amount + int _pAnimCnt; // current anim delay value + int _pAnimLen; // number of anim frames + int _pAnimFrame; // current anim frame + long _pAnimWidth; // current width of anim + long _pAnimWidth2; // (width - 64) / 2 + int _peflag; // draw extra tile to left for walk fix (flag) + + int _plid; // player light id + int _pvid; // player vision id + + int _pSpell; // Spell to cast (from book or readied) + char _pSplType; // Spell type of spell to cast + char _pSplFrom; // Spell from Readied, book, or speed bar + + int _pTSpell; // Targeted spell + char _pTSplType; // Targeted spell type + + int _pRSpell; // Readied spell + char _pRSplType; // Readied spell type (Memorized, ability, staff/item) + + int _pSBkSpell; // Current spell book spell + char _pSBkSplType; // Spell book spell type + + char _pSplLvl[64]; // Spell level corresponding to SplType bits + __int64 _pMemSpells; // Flags for which spell the char has from memorizing books + __int64 _pAblSpells; // Flags for which spell the char has class abilities + __int64 _pScrlSpells; // Flags for which spell the char has from scrolls + char _pSpellFlags; // Flags for spells, these can be used for anything, see defines above + + int _pSplHotKey[4]; // Spell hotkeys + char _pSplTHotKey[4]; // Spell type hotkeys + + int _pwtype; // Weapon type (ranged, h2h) + + BYTE _pBlockFlag; // Do I have a shield to block with? + BYTE _pInvincible; // Can I be hit? + char _pLightRad; // Player light radius + BYTE _pLvlChanging; // Am I in the process of changing levels? + + // Player attributes + char _pName[PLR_NAME_LEN]; + char _pClass; + + int _pStrength; + int _pBaseStr; + int _pMagic; + int _pBaseMag; + int _pDexterity; + int _pBaseDex; + int _pVitality; + int _pBaseVit; + + int _pStatPts; + + int _pDamageMod; // Damage modifier + int _pBaseToBlk; // Block % + + long _pHPBase; + long _pMaxHPBase; + long _pHitPoints; + long _pMaxHP; + int _pHPPer; + long _pManaBase; + long _pMaxManaBase; + long _pMana; + long _pMaxMana; + int _pManaPer; + + char _pLevel; + char _pMaxLvl; + long _pExperience; + long _pMaxExp; + long _pNextExper; + + char _pArmorClass; + + char _pMagResist; + char _pFireResist; + char _pLghtResist; + + long _pGold; + + BOOL _pInfraFlag; + + long _pVar1; // scratch var 1 + long _pVar2; // scratch var 2 + long _pVar3; // scratch var 3 + long _pVar4; // scratch var 4 + long _pVar5; // scratch var 5 + long _pVar6; // scratch var 6 + long _pVar7; // scratch var 7 + long _pVar8; // scratch var 8 + + BYTE _pLvlVisited[NUMLEVELS]; // Have I been on this level? + BYTE _pSLvlVisited[NUMLEVELS]; // Have I been on this set piece level? + + int _pGFXLoad; // Flag for which graphics are loaded + + BYTE *_pNAnim[8]; // Neutral anims + int _pNFrames; // Number of neutral frames + long _pNWidth; // Width of neutral frames + BYTE *_pWAnim[8]; // Walk anims + int _pWFrames; // Number of walk frames + long _pWWidth; // Width of walk frames + BYTE *_pAAnim[8]; // Attack anims + int _pAFrames; // Number of attack frames + long _pAWidth; // Width of attack frames + int _pAFNum; // Which frame to check for attack on + BYTE *_pLAnim[8]; // Lightning Spell anims + BYTE *_pFAnim[8]; // Fire Spell anims + BYTE *_pTAnim[8]; // Misc Spell anims + int _pSFrames; // Number of spell frames + long _pSWidth; // Width of spell frames + int _pSFNum; // Which frame to cast spell on + BYTE *_pHAnim[8]; // Got Hit anims + int _pHFrames; // Number of got hit frames + long _pHWidth; // Width of got hit frames + BYTE *_pDAnim[8]; // Death anims + int _pDFrames; // Number of death frames + long _pDWidth; // Width of death frames + BYTE *_pBAnim[8]; // Block anims + int _pBFrames; // Number of block frames + long _pBWidth; // Width of block frames + + ItemStruct InvBody[NUM_INVLOC]; + ItemStruct InvList[MAXINV]; + int _pNumInv; + char InvGrid[MAXINV]; + ItemStruct SpdList[MAXSPD]; + ItemStruct HoldItem; // Item in transit + + int _pIMinDam; // Min damage from all items + int _pIMaxDam; // Max damage from all items + int _pIAC; // AC bonus from all items + int _pIBonusDam; // Added to damage after calced (%) + int _pIBonusToHit; // Added to hit percent + int _pIBonusAC; // Added to AC + int _pIBonusDamMod; // Added to damage after calced (number) + __int64 _pISpells; // item activated spells + long _pIFlags; // tot item flags from all items + int _pIGetHit; // When I gen hit, added to or subtracted from damage + char _pISplLvlAdd; // What to add to each spell level + char _pISplCost; // % modifier to spell cost + int _pISplDur; // % modifier to spell duration + int _pIEnAc; + int _pIFMinDam; // Fire hit min damage + int _pIFMaxDam; // Fire hit min damage + int _pILMinDam; // Lightning hit min damage + int _pILMaxDam; // Lightning hit min damage + +/* BOOL _WarpActive; // If I am on the town level from a portal, this turns true. + int _WarpLevel; // Level Town portal was cast on + int _WarpLvlType; // Level type where warp occurred + BOOL _WarpSet; // Was it a set level? + int _WarpX; // Level X pos where warp occurred + int _WarpY; // Level Y pos where warp occurred */ + + int _pOilType; // Temp hold for oil creation + + + // these fields are to be used if more variables need to be added + // to the player structure so that the size won't change + BYTE pTownWarps; // Town warp flags for single player (drb 11/22) + BYTE pDungMsgs; // Dungeon phrases that the player says + BYTE pLvlLoad; + BYTE pHellfireMsgs; // Message slots for nest messages + BYTE bReserved5; + BYTE bReserved6; + BYTE bReserved7; + BYTE bReserved8; + + WORD _pReflectCount; // Number of reflected hits left. + WORD wReserved2; + WORD wReserved3; + WORD wReserved4; + WORD wReserved5; + WORD wReserved6; + WORD wReserved7; + WORD wReserved8; + + DWORD pDiabloKillLevel; // player killed Diablo at what level + DWORD _gnDifficulty; + DWORD _pIFlags2; + DWORD dwReserved4; + DWORD dwReserved5; + DWORD dwReserved6; + DWORD dwReserved7; + DWORD dwReserved8; + + // Anything below this will not be saved or sent during a sync + #define SAVE_PLAYER_SIZE offsetof(PlayerStruct,_pNData) + BYTE *_pNData; // Neutral anim memory + BYTE *_pWData; // Walk anim memory + BYTE *_pAData; // Attack anim memory + BYTE *_pLData; // Spell anim memory + BYTE *_pFData; // Spell anim memory + BYTE *_pTData; // Spell anim memory + BYTE *_pHData; // Got Hit anim memory + BYTE *_pDData; // Death anim memory + BYTE *_pBData; // Block anim memory +} PlayerStruct; + +// for compatiblity with existing code +#define HeadItem InvBody[INVLOC_HEAD] +#define BodyItem InvBody[INVLOC_BODY] +#define Ring1Item InvBody[INVLOC_RING1] +#define Ring2Item InvBody[INVLOC_RING2] +#define NeckItem InvBody[INVLOC_NECK] +#define Hand1Item InvBody[INVLOC_HAND1] +#define Hand2Item InvBody[INVLOC_HAND2] + + +extern DWORD glSeedTbl[NUMLEVELS]; +extern int gnLevelTypeTbl[NUMLEVELS]; +extern char *ClassStrTbl[NUM_CLASSES]; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +// pjw.patch1.start +// extern PlayerStruct plr[MAX_PLRS]; +extern PlayerStruct * plr; +// pjw.patch1.end + +extern int myplr; +extern int pholdx, pholdy; +extern int MaxStats[NUM_CLASSES][4]; + +extern int deathdelay; +extern BOOL deathflag; +extern BOOL gbValidSaveFile; +extern BOOL gbSaveFileExists; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitPlrGFXMem(int); +void LoadPlrGFX(int,DWORD); +void InitPlayerGFX(int); +void FreePlayerGFX(int); +void SetPlrAnims(int); + +void InitPlayer(int, BOOL); +void InitMultiView(); +void ProcessPlayers(); +int PlrGetDirXY(int, int, int); + +void StartSpell(int, int, int, int); +void StartPlrKill(int, BOOL); +void SyncPlrKill(int, BOOL); +void StartPlrHit(int, int, BOOL); +void StartPlrBlock(int, int); +void StartNewLvl(int, int, int); +void StartWarpLvl(int, int); +void RestartTownLvl(int); + +void CreatePlayer(int, char); + +void CreateMyPacket(); +void ProcessPackets(); + +void AddPlrExperience(int, int, long); +void AddPlrMonstExper(int, long, char); + +void SyncInitPlr(int); + +void ClrPlrPath(int); +BOOL PosOkPlayer(int, int, int); +void MakePlrPath(int, int, int, BOOL); +void CheckPlrSpell(); + +void PlrClrTrans(int, int); +void PlrDoTrans(int, int); + +void ModifyPlrStr(int, int); +void ModifyPlrMag(int, int); +void ModifyPlrDex(int, int); +void ModifyPlrVit(int, int); + +void SetPlayerHitPoints(int pnum, int newhp); +void SetPlrStr(int p, int v); +void SetPlrMag(int p, int v); +void SetPlrDex(int p, int v); +void SetPlrVit(int p, int v); + +void DropHalfPlayersGold(int pnum); +extern void StripTopGold(int pnum); + +void InitDungMsgs(int pnum); +void PlayDungMsgs(); + +void CheckStats(int p); + +void FixPlrWalkTags(int pnum); +void FixPlayerLocation(int pnum,int bDir); +void SetPlayerOld(int pnum); + +int GetMaxStr(int /* class */); +int GetMaxMag(int /* class */); +int GetMaxDex(int /* class */); diff --git a/PLRMSG.CPP b/PLRMSG.CPP new file mode 100644 index 0000000..eecbd76 --- /dev/null +++ b/PLRMSG.CPP @@ -0,0 +1,214 @@ +//****************************************************************** +// plrmsg.cpp +//****************************************************************** + +#include "diablo.h" +#pragma hdrstop +#include "msg.h" +#include "engine.h" +#include "scrollrt.h" +#include "control.h" +#include "inv.h" +#include "quests.h" +#include "gendung.h" +#include "items.h" +#include "player.h" + + +//****************************************************************** +// private +//****************************************************************** +typedef struct TMsg { + long lMsgTime; + BYTE bPlr; + // a little padding for "(level %d): " and stuff + char str[MAX_SEND_STR_LEN + PLR_NAME_LEN + 32]; +} TMsg; + + +#define MAX_MSGS 8 +#define MAX_MSGS_MASK (MAX_MSGS-1) +static TMsg sgMsgs[MAX_MSGS]; +static BYTE sgbNextMsg; + +#define MSG_TIME 10000 // milliseconds +#define MSG_XOFF 10 +#define MSG_YOFF 70 +#define MSG_YFONT 10 +#define MSG_YDELTA ((GAMEY - MSG_YOFF) / MAX_MSGS) +#define MAX_MSG_LINES 3 + + +//****************************************************************** +//****************************************************************** +void plrmsg_hold(BOOL bStart) { + static long slStartTime; + + // save starting time + if (bStart) { + slStartTime = - (long) GetTickCount(); + } + else { + // calculate hold interval + slStartTime += (long) GetTickCount(); + TMsg * pMsg = sgMsgs; + for (int i = MAX_MSGS; i--; pMsg++) + pMsg->lMsgTime += slStartTime; + } +} + + +//****************************************************************** +//****************************************************************** +void sysmsg_add_string(const char * pszMsg) { + app_assert(pszMsg); + TMsg * pMsg = &sgMsgs[sgbNextMsg++]; + sgbNextMsg &= MAX_MSGS_MASK; + + pMsg->bPlr = MAX_PLRS; + pMsg->lMsgTime = (long) GetTickCount(); + + strncpy(pMsg->str,pszMsg,sizeof(pMsg->str)); + pMsg->str[sizeof(pMsg->str) - 1] = 0; +} + + +//****************************************************************** +//****************************************************************** +void __cdecl sysmsg_add(const char * pszFmt,...) { + app_assert(pszFmt); + TMsg * pMsg = &sgMsgs[sgbNextMsg++]; + sgbNextMsg &= MAX_MSGS_MASK; + + pMsg->bPlr = MAX_PLRS; + pMsg->lMsgTime = (long) GetTickCount(); + + va_list args; + va_start(args,pszFmt); + vsprintf(pMsg->str,pszFmt,args); + va_end(args); + app_assert(strlen(pMsg->str) < sizeof(pMsg->str)); +} + + +//****************************************************************** +//****************************************************************** +void plrmsg_add(int pnum, const char * pszStr) { + app_assert((DWORD) pnum < MAX_PLRS); + app_assert(pszStr); + + TMsg * pMsg = &sgMsgs[sgbNextMsg++]; + sgbNextMsg &= MAX_MSGS_MASK; + + pMsg->bPlr = (BYTE) pnum; + pMsg->lMsgTime = (long) GetTickCount(); + + app_assert(strlen(plr[pnum]._pName) < PLR_NAME_LEN); + app_assert(strlen(pszStr) < MAX_SEND_STR_LEN); + sprintf(pMsg->str,"%s (lvl %d): %s",plr[pnum]._pName,plr[pnum]._pLevel,pszStr); +} + + +//****************************************************************** +//****************************************************************** +void plrmsg_update() { + +#if 0 + // debugging + static DWORD d = 0; + static long lTime = 0; + if ((long) GetTickCount() - lTime > 2000) { + plrmsg_add(myplr,strGetError(d++)); + lTime = (long) GetTickCount(); + } +#endif + + TMsg * pMsg = sgMsgs; + long lCurrTime = (long) GetTickCount(); + for (int i = MAX_MSGS; i--; pMsg++) { + if (lCurrTime - pMsg->lMsgTime > MSG_TIME) + pMsg->str[0] = 0; + } +} + + +//****************************************************************** +//****************************************************************** +void plrmsg_init() { + ZeroMemory(&sgMsgs[0],sizeof(sgMsgs)); + sgbNextMsg = 0; +} + + +//****************************************************************** +//****************************************************************** +static void draw_str(DWORD x,DWORD y,DWORD wdt,const char * pszStr,char cColor) { + + DWORD dwLines = 0; + while (*pszStr) { + // calc offset into draw buffer + DWORD dwOffset = nBuffWTbl[y] + x; + + // calculate maximum wrappable line + DWORD dwLineWdt = 0; + const char * pszLine = pszStr; + const char * pszEOL = pszStr; + while (1) { + if (! *pszLine) { + pszEOL = pszLine; + break; + } + BYTE c = char2print(*pszLine++); + c = fonttrans[c]; + dwLineWdt += fontkern[c] + 1; + if (! c) + pszEOL = pszLine; + else if (dwLineWdt >= wdt) + break; + } + + // draw line + while (pszStr < pszEOL) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + if (c) DrawPanelFont(dwOffset,c,cColor); + dwOffset += fontkern[c] + 1; + } + + // move down a line + y += MSG_YFONT; + + if (++dwLines == MAX_MSG_LINES) break; + } +} + + +//****************************************************************** +//****************************************************************** +void plrmsg_draw() { + static const char scColorTbl[MAX_PLRS + 1] = { + ICOLOR_WHITE, + ICOLOR_WHITE, + ICOLOR_WHITE, + ICOLOR_WHITE, + ICOLOR_GOLD + }; + + DWORD x = MSG_XOFF + (BUFFERX - TOTALX) /2 ; + DWORD y = MSG_YOFF + 160; + DWORD wdt = TOTALX - MSG_XOFF*2; + if (chrflag || questlog) { + if (invflag || sbookflag) return; + x += TOTALX / 2; + wdt -= TOTALX / 2; + } + else if (invflag || sbookflag) { + wdt -= TOTALX / 2; + } + + TMsg * pMsg = sgMsgs; + for (int i = MAX_MSGS; i--; pMsg++,y += MSG_YDELTA) { + if (! pMsg->str[0]) continue; + draw_str(x,y,wdt,pMsg->str,scColorTbl[pMsg->bPlr]); + } +} diff --git a/PORTAL.CPP b/PORTAL.CPP new file mode 100644 index 0000000..b3eb99c --- /dev/null +++ b/PORTAL.CPP @@ -0,0 +1,256 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Triggers file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "portal.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "misdat.h" +#include "missiles.h" +#include "effects.h" +#include "msg.h" +#include "lighting.h" + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +PortalStruct portal[MAXPORTAL]; + +int WarpDropX[MAXPORTAL] = { 57, 59, 61, 63 }; +int WarpDropY[MAXPORTAL] = { 40, 40, 40, 40 }; + +int portalindex; // current portal in use for myplr + +/*-----------------------------------------------------------------------** +** externs +**-----------------------------------------------------------------------*/ +void SetMissDir(int mi, int dir); +void DeleteMissile(int mi, int i); +BOOL delta_portal_inited(int i); + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitPortals() +{ + for (int i = 0; i < MAXPORTAL; i++) { + // Check to see if needs initing or parsed from level delta + if (delta_portal_inited(i)) + portal[i].open = FALSE; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SyncPortal(int i, BOOL open, int x, int y, int level, int ltype) +{ + app_assert((DWORD)i < MAXPORTAL); + portal[i].open = open; + portal[i].x = x; + portal[i].y = y; + portal[i].level = level; + portal[i].ltype = ltype; + portal[i].setlvl = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void AddWarpMissile(int i, int x, int y) +{ + // Don't play sound when loading level + missiledata[MIT_TOWN].mlSFX = -1; + + // Fix because portal cant be drawn on top of each other + dMissile[x][y] = 0; + + // Put in map and activate + int mi = AddMissile(0, 0, x, y, 0, MIT_TOWN, MI_ENEMYMONST, i, 0, 0); + + //check if AddMissile unsuccessful + if (mi == -1) + return; //too many missiles already, so quit + + // Force open + SetMissDir(mi, 1); + + // Give it a lightsource +//DL - 11/9/97 +// This is a serious bug. Under certain situations, missile[i] will be +// uninitialized, causing coordinate (0, 0) to be passed to AddLight(). +// When the light is processed later, and the radius is subtracted from +// the (0, 0) coordinate, the light table will be written to with negative +// indicies, causing an array underwrite. This was causing a crash on the +// Mac because it was overwriting the memory block header, trashing the +// application's heap. I don't know what is getting overwritten on the PC +// version. An example of when this will happen is if player 1 creates a +// new game, and player 2 joins it. Both players go to level 1. Player 2 +// casts town portal (with cheats on). On player 1's machine, +// AddWarpMissile( will be called with i = 1 (player 2's player index). +// Since there are no missles yet, AddMissile() will use missle index 0, so +// mi wil be 0. But since i is 1, AddLight() will be passed the coordinates +// of missle[1], which doesn't exist, so its coordinates are undefined. In +// this case, they are uninitialized, so they are zero. + +// if (currlevel != 0) missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, 15); + if (currlevel != 0) missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 15); + + // play sound while in dungeon + missiledata[MIT_TOWN].mlSFX = LS_SENTINEL; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SyncPortals() +{ + // Add the warp fields + for (int i = 0; i < MAXPORTAL; i++) { + if (portal[i].open) { + if (currlevel == 0) { + AddWarpMissile(i, WarpDropX[i], WarpDropY[i]); + } else { + if (! setlevel) { + if (portal[i].level == currlevel) AddWarpMissile(i, portal[i].x, portal[i].y); + } else { + if (portal[i].level == setlvlnum) AddWarpMissile(i, portal[i].x, portal[i].y); + } + } + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddInTownPortal(int i) +{ + AddWarpMissile(i, WarpDropX[i], WarpDropY[i]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ActivatePortal(int i, int x, int y, int lvl, int lvltype, BOOL sp) +{ + app_assert((DWORD)i < MAXPORTAL); + portal[i].open = TRUE; + if (lvl != 0) { + portal[i].x = x; + portal[i].y = y; + portal[i].level = lvl; + portal[i].ltype = lvltype; + portal[i].setlvl = sp; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DeactivatePortal(int i) +{ + app_assert((DWORD)i < MAXPORTAL); + portal[i].open = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL PortalOnLevel(int i) +{ + app_assert((DWORD)i < MAXPORTAL); + if (portal[i].level == currlevel) return(TRUE); + if (currlevel == 0) return(TRUE); + else return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void RemovePortalMissile(int id) +{ + int i, mi; + + // Remove current portal + for (i = 0; i < nummissiles; i++) { + mi = missileactive[i]; + if ((missile[mi]._mitype == MIT_TOWN) && (missile[mi]._misource == id)) { + dFlags[missile[mi]._mix][missile[mi]._miy] &= BFMASK_MISSILE; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; + if (portal[id].level != 0) AddUnLight(missile[mi]._mlid); + DeleteMissile(mi, i); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void SetCurrentPortal(int p) +{ + portalindex = p; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void GetPortalLevel() { + if (currlevel) { + setlevel = FALSE; + currlevel = 0; + plr[myplr].plrlevel = 0; + leveltype = 0; + return; + } + app_assert((DWORD)portalindex < MAXPORTAL); + if (portal[portalindex].setlvl) { + setlevel = TRUE; + setlvlnum = portal[portalindex].level; + currlevel = portal[portalindex].level; + plr[myplr].plrlevel = setlvlnum; + leveltype = portal[portalindex].ltype; + } + else { + setlevel = FALSE; + currlevel = portal[portalindex].level; + plr[myplr].plrlevel = currlevel; + leveltype = portal[portalindex].ltype; + } + if (portalindex == myplr) { + NetSendCmd(TRUE, CMD_DEACTIVATEPORTAL); + DeactivatePortal(portalindex); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void GetPortalLvlPos() +{ + app_assert((DWORD)portalindex < MAXPORTAL); + if (!currlevel) { + ViewX = WarpDropX[portalindex] + 1; + ViewY = WarpDropY[portalindex] + 1; + return; + } + ViewX = portal[portalindex].x; + ViewY = portal[portalindex].y; + if (portalindex != myplr) { + ViewX++; + ViewY++; + } +} + diff --git a/PORTAL.H b/PORTAL.H new file mode 100644 index 0000000..ad07b69 --- /dev/null +++ b/PORTAL.H @@ -0,0 +1,53 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXPORTAL 4 // Must be the same as MAX_PLRS! + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + BOOL open; + int x; + int y; + int level; + int ltype; + BOOL setlvl; +} PortalStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern PortalStruct portal[MAXPORTAL]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitPortals(); +void SyncPortals(); +void AddInTownPortal(int i); + +void ActivatePortal(int i, int x, int y, int lvl, int lvltype, BOOL sp); +void DeactivatePortal(int i); + +void SetCurrentPortal(int p); + +void GetPortalLvlPos(); +void GetPortalLevel(); + +BOOL PortalOnLevel(int i); +void RemovePortalMissile(int i); diff --git a/QUESTS.CPP b/QUESTS.CPP new file mode 100644 index 0000000..741c8e2 --- /dev/null +++ b/QUESTS.CPP @@ -0,0 +1,1115 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Quests file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/QUESTS.CPP 3 1/23/97 4:51p Vdwel $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "quests.h" +#include "gendung.h" +#include "engine.h" +#include "control.h" +#include "items.h" +#include "objects.h" +#include "objdat.h" +#include "player.h" +#include "monster.h" +#include "monstdat.h" +#include "drlg_l1.h" +#include "stores.h" +#include "scrollrt.h" +#include "minitext.h" +#include "textdat.h" +#include "effects.h" +#include "cursor.h" +#include "palette.h" +#include "msg.h" +#include "multi.h" +#include "doom.h" +#include "missiles.h" +#include "trigs.h" +#include "towners.h" +#include "setmaps.h" + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL delta_quest_inited(int i); + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +QuestStruct quests[MAXQUESTS]; + +int ReturnLvlX, ReturnLvlY, ReturnLvl, ReturnLvlT; +BOOL rporttest; +BOOL questlog; +int qspin, qline, numqlines, qtopline; +int qlist[MAXQUESTS]; // index list of displayed quests in questlog +int qfade; + + +BYTE *pQLogCel; + +#if CHEATS +int questcheat = -1; // TEMP!!!!!! drb +#endif + +/*-----------------------------------------------------------------------* +** private +**-----------------------------------------------------------------------*/ +// level, multi lvl, lvl type, id, % chance, setlevel #, multi flag, qmsg, string +QuestData questlist[] = { + // Contained + { 5, -1, 255, Q_ROCK, 100, 0, 0, TXT_INFRABS1, "The Magic Rock" }, // 0 + { 9, -1, 255, Q_BKMUSHRM, 100, 0, 0, TXT_BLKMW1, "Black Mushroom" }, // 1 + { 4, -1, 255, Q_GARBUD, 100, 0, 0, TXT_GARB1, "Gharbad The Weak" }, // 2 + { 8, -1, 255, Q_ZHAR, 100, 0, 0, TXT_ZHAR1, "Zhar the Mad" }, // 3 + { 14, -1, 255, Q_VEIL, 100, 0, 0, TXT_VEIL1, "Lachdanan" }, // 4 + { 15, -1, 255, Q_DIABLO, 100, 0, QFLAG_MULTI, TXT_VBST3, "Diablo" }, // 5 + // Internal Set Pieces + { 2, 2, 255, Q_BUTCHER, 100, 0, QFLAG_MULTI, TXT_BUTCH1, "The Butcher" }, // 6 + { 4, -1, 255, Q_LTBANNER, 100, 0, 0, TXT_BOLTO1, "Ogden's Sign" }, // 7 + { 7, -1, 255, Q_BLIND, 100, 0, 0, TXT_WARBLIND, "Halls of the Blind" }, // 8 + { 5, -1, 255, Q_BLOOD, 100, 0, 0, TXT_WARBLOOD, "Valor" }, // 9 + { 10, -1, 255, Q_ANVIL, 100, 0, 0, TXT_ANVILBS1, "Anvil of Fury" }, // 10 + { 13, -1, 255, Q_WARLORD, 100, 0, 0, TXT_WARLORD, "Warlord of Blood" }, // 11 + // External Levels Maps + { 3, 3, 1, Q_SKELKING, 100, 1, QFLAG_MULTI, TXT_KINGTO1, "The Curse of King Leoric"},// 12 + { 2, -1, 3, Q_PWATER, 100, 4, 0, TXT_PWH1, "Poisoned Water Supply" }, // 13 + { 6, -1, 2, Q_SCHAMB, 100, 2, 0, TXT_WARBONE, "The Chamber of Bone" }, // 14 + { 15, 15, 1, Q_BETRAYER, 100, 5, QFLAG_MULTI, TXT_VBST1, "Archbishop Lazarus" }, // 15 + // New quests for Hellfire JKEQUEST + { 17, 17, 255, Q_CRYPTMAP, 100, 0, QFLAG_MULTI, TXT_CRYPTMAP7, "Grave Matters" }, // 16 + { 9, 9, 255, Q_FARMER, 100, 0, QFLAG_MULTI, TXT_FARMER1, "Farmer's Orchard" }, // 17 + { 17, -1, 255, Q_THEO, 100, 0, 0, TXT_THEO2, "Little Girl" }, // 18 + { 19, -1, 255, Q_TRADER, 100, 0, 0, TXT_TRADER1, "Wandering Trader" }, // 19 + { 17, 17, 255, Q_DEFILER, 100, 0, QFLAG_MULTI, TXT_DEFILER1, "The Defiler" }, // 20 + { 21, 21, 255, Q_NA_KRUL, 100, 0, QFLAG_MULTI, TXT_NA_KRUL1, "Na-Krul" }, // 21 + { 21, -1, 255, Q_CORNERSTONE, 100, 0, 0, TXT_CORNERSTONE1, "Cornerstone of the World"}, // 22 + { 9, 9, 255, Q_COWSUIT, 100, 0, QFLAG_MULTI, TXT_COWSUIT4, "The Jersey's Jersey" } // 23 +}; +#define ALLQUESTS (sizeof(questlist) / sizeof(questlist[0])) + +#define QUEST_OFFSETS 7 +static char questxoff[QUEST_OFFSETS] = { 0, -1, 0, -1, -2, -1, -2 }; +static char questyoff[QUEST_OFFSETS] = { 0, 0, -1, -1, -1, -2, -2 }; + +char *questtrigstr[] = { + "King Leoric's Tomb", + "The Chamber of Bone", + "Maze", + "A Dark Passage", + "Unholy Altar" +}; + +// Single player quest lists +int QuestGroup1[3] = { Q_BUTCHER, Q_LTBANNER, Q_GARBUD }; // 2 of 3 +int QuestGroup2[3] = { Q_BLIND, Q_ROCK, Q_BLOOD }; // 2 of 3 +int QuestGroup3[3] = { Q_BKMUSHRM, Q_ZHAR, Q_ANVIL }; // 2 of 3 +int QuestGroup4[2] = { Q_VEIL, Q_WARLORD }; // 1 of 2 + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitQuests() { + int i, gri, deltaq; + + if (gbMaxPlayers == 1) { + for (i = 0; i < MAXQUESTS; i++) + quests[i]._qactive = QUEST_NOTAVAIL; + } else { + for (i = 0; i < MAXQUESTS; i++) { + if (!(questlist[i]._qflags & QFLAG_MULTI)) + quests[i]._qactive = QUEST_NOTAVAIL; + } + } + + questlog = FALSE; + qspin = 1; + qfade = 0; + deltaq = 0; + for (i = 0; i < ALLQUESTS; i++) { + if (gbMaxPlayers > 1 && !(questlist[i]._qflags & QFLAG_MULTI)) continue; + + quests[i]._qtype = questlist[i]._qdtype; + if (gbMaxPlayers > 1) { + quests[i]._qlevel = questlist[i]._qdmultlvl; + if (! delta_quest_inited(deltaq)) { + quests[i]._qactive = QUEST_NOTACTIVE; + quests[i]._qvar1 = 0; + quests[i]._qlog = FALSE; + } + deltaq++; + } else { + quests[i]._qactive = QUEST_NOTACTIVE; + quests[i]._qlevel = questlist[i]._qdlvl; + quests[i]._qvar1 = 0; + quests[i]._qlog = FALSE; + } + quests[i]._qslvl = questlist[i]._qslvl; + quests[i]._qtx = 0; + quests[i]._qty = 0; + quests[i]._qidx = i; + quests[i]._qlvltype = questlist[i]._qlvlt; + quests[i]._qvar2 = 0; + quests[i]._qmsg = questlist[i]._qdmsg; + } + + // Random select quests + if (gbMaxPlayers == 1) { + SetRndSeed(glSeedTbl[15]); + if (random(0, 2)) quests[Q_PWATER]._qactive = QUEST_NOTAVAIL; + else quests[Q_SKELKING]._qactive = QUEST_NOTAVAIL; + gri = QuestGroup1[random(0, 3)]; + quests[gri]._qactive = QUEST_NOTAVAIL; + gri = QuestGroup2[random(0, 3)]; + quests[gri]._qactive = QUEST_NOTAVAIL; + gri = QuestGroup3[random(0, 3)]; + quests[gri]._qactive = QUEST_NOTAVAIL; + gri = QuestGroup4[random(0, 2)]; + quests[gri]._qactive = QUEST_NOTAVAIL; + } + +#if CHEATS + // New 12/01 drb + if (questcheat != -1) + quests[questcheat]._qactive = QUEST_NOTDONE; ///test area +#endif + + #if IS_VERSION(SHAREWARE) + for (i = 0; i < ALLQUESTS; i++) { + quests[i]._qactive = QUEST_NOTAVAIL; + } + #endif + +// additional inits for the quests (not to be messed with) + if (quests[Q_SKELKING]._qactive == QUEST_NOTAVAIL) quests[Q_SKELKING]._qvar2 = 2; + if (quests[Q_ROCK]._qactive == QUEST_NOTAVAIL) quests[Q_ROCK]._qvar2 = 2; + quests[Q_LTBANNER]._qvar1 = 1; // so the door is open to snotspil for the lame gamers (LAME!!!) + if (gbMaxPlayers != 1) quests[Q_BETRAYER]._qvar1 = 2; // so that betrayer is on level 15 +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CheckQuests() +{ +// no quests in shareware version +#if !IS_VERSION(SHAREWARE) + int i; + int rportx, rporty; + + if ((QuestStatus(Q_BETRAYER)) && (gbMaxPlayers != 1) && (quests[Q_BETRAYER]._qvar1 == 2)) { + AddObject(OBJ_ALTBOY, (setpc_x << 1) + DIRTEDGED2 + 4, (setpc_y << 1) + DIRTEDGED2 + 6); + quests[Q_BETRAYER]._qvar1 = 3; + NetSendCmdQuest(TRUE, Q_BETRAYER); + } + // If multiplayer return + if (gbMaxPlayers != 1) return; + + if ((currlevel == quests[Q_BETRAYER]._qlevel) && (!(setlevel)) && (quests[Q_BETRAYER]._qvar1 >= 2) + && ((quests[Q_BETRAYER]._qactive == QUEST_NOTDONE) || (quests[Q_BETRAYER]._qactive == QUEST_DONE))) { + if ((quests[Q_BETRAYER]._qvar2 == QS_VBRPOFF) || (quests[Q_BETRAYER]._qvar2 == QS_VBRP2)) { + rportx = (quests[Q_BETRAYER]._qtx<<1)+DIRTEDGED2; + rporty = (quests[Q_BETRAYER]._qty<<1)+DIRTEDGED2; + quests[Q_BETRAYER]._qtx = rportx; + quests[Q_BETRAYER]._qty = rporty; + AddMissile(rportx, rporty, rportx, rporty, 0, MIT_RPORTAL, MI_ENEMYMONST, myplr, 0, 0); + quests[Q_BETRAYER]._qvar2 = QS_VBRP1; + if (quests[Q_BETRAYER]._qactive == QUEST_NOTDONE) + quests[Q_BETRAYER]._qvar1 = 3; + } + } + if ((quests[Q_BETRAYER]._qactive == QUEST_DONE) && (setlevel && (setlvlnum == SL_VILEBETRAYER)) + && (quests[Q_BETRAYER]._qvar2 == QS_VBRP4)) { + AddMissile(35, 32, 35, 32, 0, MIT_RPORTAL, MI_ENEMYMONST, myplr, 0, 0); + quests[Q_BETRAYER]._qvar2 = QS_VBRP3; + } + if (setlevel) { + if ((setlvlnum == quests[Q_PWATER]._qslvl) && (quests[Q_PWATER]._qactive != QUEST_NOTACTIVE) && (leveltype == quests[Q_PWATER]._qlvltype)) { + if (nummonsters == 4 && quests[Q_PWATER]._qactive != QUEST_DONE) { + quests[Q_PWATER]._qactive = QUEST_DONE; + PlaySfxLoc(IS_QUESTDN, plr[myplr]._px, plr[myplr]._py); + LoadPalette("Levels\\L3Data\\L3pwater.pal"); + qfade = 32; + } + } + + if (qfade > 0) { + MeshLavaPalette(qfade); + qfade--; + } + + return; + } + + // only check quests in stand mode + if (plr[myplr]._pmode != PM_STAND) + return; + + for (i = 0; i < MAXQUESTS; i++) { + if ((currlevel == quests[i]._qlevel) && (quests[i]._qslvl != 0) && (quests[i]._qactive != QUEST_NOTAVAIL)) { + if ((plr[myplr]._px == quests[i]._qtx) && (plr[myplr]._py == quests[i]._qty)) { + if (quests[i]._qlvltype != 255) setlvltype = quests[i]._qlvltype; + StartNewLvl(myplr,WM_DIABSETLVL,quests[i]._qslvl); + } + } + } +#endif +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL ForceQuests() { +// no quests in shareware version +#if !IS_VERSION(SHAREWARE) + // If multiplayer return + if (gbMaxPlayers != 1) return(FALSE); + + for (int i = 0; i < MAXQUESTS; i++) { + if (i == Q_BETRAYER) continue; + if (currlevel != quests[i]._qlevel) continue; +// if (quests[i]._qactive != QUEST_NOTDONE) continue; + if (quests[i]._qslvl == 0) continue; + + int ql = quests[quests[i]._qidx]._qslvl - 1; + int qx = quests[i]._qtx; + int qy = quests[i]._qty; + for (int j = 0; j < QUEST_OFFSETS; j++) { + if (qx + questxoff[j] != cursmx) continue; + if (qy + questyoff[j] != cursmy) continue; + + sprintf(infostr, "To %s", questtrigstr[ql]); + cursmx = qx; + cursmy = qy; + return TRUE; + } + } +#endif + + return FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +BOOL QuestStatus(int i) { + if (setlevel) return FALSE; + app_assert((DWORD)i < MAXQUESTS); + if (currlevel != quests[i]._qlevel) return FALSE; + if (quests[i]._qactive == QUEST_NOTAVAIL) return FALSE; + if ((gbMaxPlayers != 1) && !(questlist[i]._qflags & QFLAG_MULTI)) return FALSE; + return TRUE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void CheckQuestKill(int m, BOOL sendmsg) +{ +// no quests in shareware version +#if !IS_VERSION(SHAREWARE) + + app_assert((DWORD)m < MAXMONSTERS); + + if (monster[m].MType->mtype == MT_SKING) { + quests[Q_SKELKING]._qactive = QUEST_DONE; + sfxdelay = 30; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR82; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE82; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE82; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK82; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD82; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN82; + #endif + if (sendmsg) NetSendCmdQuest(TRUE, Q_SKELKING); + } + else if (monster[m].MType->mtype == MT_CLEAVER) { + quests[Q_BUTCHER]._qactive = QUEST_DONE; + sfxdelay = 30; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR80; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE80; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE80; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK80; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD80; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN80; + #endif + if (sendmsg) NetSendCmdQuest(TRUE, Q_BUTCHER); + } + else if (monster[m].mName == UniqMonst[MU_GARBUD].mName) { + quests[Q_GARBUD]._qactive = QUEST_DONE; + sfxdelay = 30; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR61; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE61; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE61; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK61; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD61; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN61; + #endif + } + else if (monster[m].mName == UniqMonst[MU_ZHAR].mName) { + quests[Q_ZHAR]._qactive = QUEST_DONE; + sfxdelay = 30; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR62; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE62; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE62; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK62; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD62; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN62; + #endif + } + else if ((monster[m].mName == UniqMonst[MU_LAZARUS].mName ) && (gbMaxPlayers != 1)) { + int i,j; + quests[Q_BETRAYER]._qactive = QUEST_DONE; + quests[Q_BETRAYER]._qvar1 = 7; + sfxdelay = 30; + quests[Q_DIABLO]._qactive = QUEST_NOTDONE; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 370) { + if (quests[Q_BETRAYER]._qactive == QUEST_DONE) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + } + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR83; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE83; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE83; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK83; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD83; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN83; + #endif + if (sendmsg) { + NetSendCmdQuest(TRUE, Q_BETRAYER); + NetSendCmdQuest(TRUE, Q_DIABLO); + } + } + else if ((monster[m].mName == UniqMonst[MU_LAZARUS].mName) && (gbMaxPlayers == 1)) { + quests[Q_BETRAYER]._qactive = QUEST_DONE; + sfxdelay = 30; + InitVPTriggers(); + quests[Q_BETRAYER]._qvar1 = 7; + quests[Q_BETRAYER]._qvar2 = QS_VBRP4; + quests[Q_DIABLO]._qactive = QUEST_NOTDONE; + AddMissile(35, 32, 35, 32, 0, MIT_RPORTAL, MI_ENEMYMONST, myplr, 0, 0); + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR83; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE83; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE83; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK83; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD83; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN83; + #endif + } + else if (monster[m].mName == UniqMonst[MU_WARLORD].mName) { + app_assert(gbMaxPlayers == 1); + quests[Q_WARLORD]._qactive = QUEST_DONE; + sfxdelay = 30; + if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR94; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE94; + else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE94; + else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK94; + else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD94; + else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN94; + #endif + } +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void SetPostDungeon() +{ + int i,j; + + for (j = 0; j < MDMAXY; j++) { + for (i = 0; i < MDMAXX; i++) pdungeon[i][j] = dungeon[i][j]; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawButcher() +{ + int x, y; + + x = (setpc_x << 1) + DIRTEDGED2; + y = (setpc_y << 1) + DIRTEDGED2; + DRLG_RectTrans(x+3, y+3, x+10, y+10); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawSkelKing(int q, int x, int y) +{ + app_assert((DWORD)q < MAXQUESTS); + quests[q]._qtx = DIRTEDGED2 + (x << 1) + 12; + quests[q]._qty = DIRTEDGED2 + (y << 1) + 7; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawWarLord(int x, int y) +{ + int rw,rh; + int i,j; + byte *sp, *setp; + + setp = LoadFileInMemSig("Levels\\L4Data\\Warlord2.DUN",NULL,'QSTt'); + sp = setp; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_w = rw; + setpc_h = rh; + setpc_x = x; + setpc_y = y; + + app_assert((DWORD)(rw + x - 1) < MDMAXX); + app_assert((DWORD)(rh + y - 1) < MDMAXY); + for (j = y; j < (rh + y); j++) { + for (i = x; i < (rw + x); i++) { + dungeon[i][j] = *sp ? *sp : 6; + sp+=2; + } + } + DiabloFreePtr(setp); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawSChamber(int q, int x, int y) +{ + int i, j, rw, rh, xx, yy; + byte *sp, *setp; + + setp = LoadFileInMemSig("Levels\\L2Data\\Bonestr1.DUN",NULL,'QSTt'); + sp = setp; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_w = rw; + setpc_h = rh; + setpc_x = x; + setpc_y = y; + + app_assert((DWORD)(rw + x - 1) < MDMAXX); + app_assert((DWORD)(rh + y - 1) < MDMAXY); + for (j = y; j < (rh + y); j++) { + for (i = x; i < (rw + x); i++) { + dungeon[i][j] = *sp ? *sp : 3; + sp+=2; + } + } + + xx = DIRTEDGED2 + (x << 1) + 6; + yy = DIRTEDGED2 + (y << 1) + 7; + app_assert((DWORD)q < MAXQUESTS); + quests[q]._qtx = xx; + quests[q]._qty = yy; + DiabloFreePtr(setp); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawLTBanner(int x, int y) +{ + int rw,rh; + int i,j; + byte *sp, *setp; + + setp = LoadFileInMemSig("Levels\\L1Data\\Banner1.DUN",NULL,'QSTt'); + sp = setp; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_w = rw; + setpc_h = rh; + setpc_x = x; + setpc_y = y; + + app_assert((DWORD)(x+rw-1) < MDMAXX); + app_assert((DWORD)(y+rh-1) < MDMAXY); + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp) pdungeon[x+i][y+j] = *sp; + sp+=2; + } + } + DiabloFreePtr(setp); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawBlind(int x, int y) +{ + int rw,rh; + int i,j; + byte *sp, *setp; + + setp = LoadFileInMemSig("Levels\\L2Data\\Blind1.DUN",NULL,'QSTt'); + sp = setp; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_x = x; + setpc_y = y; + setpc_w = rw; + setpc_h = rh; + + app_assert((DWORD)(x+rw-1) < MDMAXX); + app_assert((DWORD)(y+rh-1) < MDMAXY); + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp) pdungeon[x+i][y+j] = *sp; + sp+=2; + } + } + DiabloFreePtr(setp); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawBlood(int x, int y) +{ + int rw,rh; + int i,j; + byte *sp, *setp; + + setp = LoadFileInMemSig("Levels\\L2Data\\Blood2.DUN",NULL,'QSTt'); + sp = setp; + rw = *sp; + sp+=2; + rh = *sp; + sp+=2; + + setpc_x = x; + setpc_y = y; + setpc_w = rw; + setpc_h = rh; + + app_assert((DWORD)(rw + x - 1) < MDMAXX); + app_assert((DWORD)(rh + y - 1) < MDMAXY); + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + if (*sp) dungeon[x+i][y+j] = *sp; + //else dungeon[x+i][x+j] = 3; + sp+=2; + } + } + + DiabloFreePtr(setp); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DRLG_CheckQuests(int x, int y) +{ + int i; + + for (i = 0; i < MAXQUESTS; i++) { + if (!QuestStatus(i)) + continue; + switch (quests[i]._qtype) { + case Q_BUTCHER: + DrawButcher(); + break; + case Q_SKELKING : + DrawSkelKing(i, x, y); + break; + case Q_SCHAMB : + DrawSChamber(i, x, y); + break; + case Q_BLIND : + DrawBlind(x, y); + break; + case Q_BLOOD : + DrawBlood(x,y); + break; + case Q_LTBANNER : + DrawLTBanner(x, y); + break; + case Q_WARLORD: + DrawWarLord(x, y); + break; + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetReturnLvlPos() +{ + switch (setlvlnum) { + case SL_SKELKING: // SKing + ReturnLvlX = quests[Q_SKELKING]._qtx + 1; + ReturnLvlY = quests[Q_SKELKING]._qty; + ReturnLvl = quests[Q_SKELKING]._qlevel; + ReturnLvlT = 1; + break; + case SL_BONECHAMB: // Bone chamber + ReturnLvlX = quests[Q_SCHAMB]._qtx + 1; + ReturnLvlY = quests[Q_SCHAMB]._qty; + ReturnLvl = quests[Q_SCHAMB]._qlevel; + ReturnLvlT = 2; + break; + case SL_POISONWATER: // Poison Water + ReturnLvlX = quests[Q_PWATER]._qtx; + ReturnLvlY = quests[Q_PWATER]._qty + 1; + ReturnLvl = quests[Q_PWATER]._qlevel; + ReturnLvlT = 1; + break; + case SL_VILEBETRAYER: // Vile Betrayer + ReturnLvlX = quests[Q_BETRAYER]._qtx + 1; + ReturnLvlY = quests[Q_BETRAYER]._qty - 1; + ReturnLvl = quests[Q_BETRAYER]._qlevel; + ReturnLvlT = 4; + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void GetReturnLvlPos() +{ + if (quests[Q_BETRAYER]._qactive == QUEST_DONE) quests[Q_BETRAYER]._qvar2 = QS_VBRP2; + ViewX = ReturnLvlX; + ViewY = ReturnLvlY; + currlevel = ReturnLvl; + leveltype = ReturnLvlT; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ResyncMPQuests() +{ +// no quests in shareware version +#if !IS_VERSION(SHAREWARE) + if (quests[Q_SKELKING]._qactive == QUEST_NOTACTIVE) { + if ((currlevel >= (quests[Q_SKELKING]._qlevel - 1)) && (currlevel <= (quests[Q_SKELKING]._qlevel + 1))) { + quests[Q_SKELKING]._qactive = QUEST_NOTDONE; + NetSendCmdQuest(TRUE, Q_SKELKING); + } + } + if (quests[Q_BUTCHER]._qactive == QUEST_NOTACTIVE) { + if ((currlevel >= (quests[Q_BUTCHER]._qlevel - 1)) && (currlevel <= (quests[Q_BUTCHER]._qlevel + 1))) { + quests[Q_BUTCHER]._qactive = QUEST_NOTDONE; + NetSendCmdQuest(TRUE, Q_BUTCHER); + } + } + if (quests[Q_BETRAYER]._qactive == QUEST_NOTACTIVE) { + if (currlevel == (quests[Q_BETRAYER]._qlevel - 1)) { + quests[Q_BETRAYER]._qactive = QUEST_NOTDONE; + NetSendCmdQuest(TRUE, Q_BETRAYER); + } + } + if (QuestStatus(Q_BETRAYER)) + AddObject(OBJ_ALTBOY, (setpc_x << 1) + DIRTEDGED2 + 4, (setpc_y << 1) + DIRTEDGED2 + 6); + + // Add Multi player Hellfire quests here + if (quests[Q_CRYPTMAP]._qactive == QUEST_NOTACTIVE) + if (currlevel == (quests[Q_CRYPTMAP]._qlevel - 1)) { + quests[Q_CRYPTMAP]._qactive = QUEST_NOTDONE; + NetSendCmdQuest(TRUE, Q_CRYPTMAP); + } + + if (quests[Q_DEFILER]._qactive == QUEST_NOTACTIVE) + if (currlevel == (quests[Q_DEFILER]._qlevel - 1)) { + quests[Q_DEFILER]._qactive = QUEST_NOTDONE; + NetSendCmdQuest(TRUE, Q_DEFILER); + } + + if (quests[Q_NA_KRUL]._qactive == QUEST_NOTACTIVE) + if (currlevel == (quests[Q_NA_KRUL]._qlevel - 1)) { + quests[Q_NA_KRUL]._qactive = QUEST_NOTDONE; + NetSendCmdQuest(TRUE, Q_NA_KRUL); + } + + if (quests[Q_COWSUIT]._qactive == QUEST_NOTACTIVE) + if (currlevel == (quests[Q_COWSUIT]._qlevel - 1)) { + quests[Q_COWSUIT]._qactive = QUEST_NOTDONE; + NetSendCmdQuest(TRUE, Q_COWSUIT); + } + +#endif + +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void ResyncQuests() +{ +// no quests in shareware version +#if !IS_VERSION(SHAREWARE) + + int i, tren; + + // for Poison Water quest only - inits the poison/not poison water pal + if (setlevel) { + if ((setlvlnum == quests[Q_PWATER]._qslvl) && (quests[Q_PWATER]._qactive != QUEST_NOTACTIVE) && (leveltype == quests[Q_PWATER]._qlvltype)) { + if (quests[Q_PWATER]._qactive == QUEST_DONE) LoadPalette("Levels\\L3Data\\L3pwater.pal"); + else LoadPalette("Levels\\L3Data\\L3pfoul.pal"); + for (i = 0; i <= 32; i++) { + MeshLavaPalette(i); + } + } + } + + if (QuestStatus(Q_LTBANNER)) { + if (quests[Q_LTBANNER]._qvar1 == 1) { + ObjChangeMapResync(setpc_x + setpc_w - 2, setpc_y + setpc_h - 2, setpc_x + setpc_w+1, setpc_y + setpc_h+1); + } + if (quests[Q_LTBANNER]._qvar1 == 2) { + ObjChangeMapResync(setpc_x + setpc_w - 2, setpc_y + setpc_h - 2, setpc_x + setpc_w+1, setpc_y + setpc_h+1); + ObjChangeMapResync(setpc_x, setpc_y, setpc_x+(setpc_w>>1)+2, setpc_y+(setpc_h>>1)-2); + for (i = 0; i < numobjects; i++) SyncObjectAnim(objectactive[i]); + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, setpc_x+(setpc_w>>1)+4, setpc_y+(setpc_h>>1)); + TransVal = tren; + } + if (quests[Q_LTBANNER]._qvar1 == 3) { + ObjChangeMapResync(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1); + for (i = 0; i < numobjects; i++) SyncObjectAnim(objectactive[i]); + tren = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, setpc_x+(setpc_w>>1)+4, setpc_y+(setpc_h>>1)); + TransVal = tren; + } + } + + if (currlevel == quests[Q_BKMUSHRM]._qlevel) { + if (quests[Q_BKMUSHRM]._qactive == QUEST_NOTACTIVE + && quests[Q_BKMUSHRM]._qvar1 == QS_INIT) + { + SpawnQuestItem(IDI_FUNGALTM, 0,0,5, ISEL_FLR); + quests[Q_BKMUSHRM]._qvar1 = QS_TOMESPAWNED; + } + else if (quests[Q_BKMUSHRM]._qactive == QUEST_NOTDONE) + { + if (quests[Q_BKMUSHRM]._qvar1 >= QS_MUSHGIVEN) // Mushroom was given to Witch + { + Qtalklist[TWN_HEALER][Q_BKMUSHRM] = TXT_BLKMH1; + Qtalklist[TWN_WITCH][Q_BKMUSHRM] = -1; + } + else if (quests[Q_BKMUSHRM]._qvar1 >= QS_BRAINGIVEN) // Brain was given to Healer + { + Qtalklist[TWN_HEALER][Q_BKMUSHRM] = -1; + } + } + } + if (currlevel == (quests[Q_VEIL]._qlevel + 1)) { + if ((quests[Q_VEIL]._qactive == QUEST_NOTDONE) && (quests[Q_VEIL]._qvar1 == 0)) { + quests[Q_VEIL]._qvar1 = 1; + SpawnQuestItem(IDI_GLDNELIX, 0,0,5, ISEL_FLR); + } + } + + if (setlevel && (setlvlnum == SL_VILEBETRAYER)) { + if (quests[Q_BETRAYER]._qvar1 >= 4) + ObjChangeMapResync(1, 11, 20, 18); + if (quests[Q_BETRAYER]._qvar1 >= 6) + ObjChangeMapResync(1, 18, 20, 24); + if (quests[Q_BETRAYER]._qvar1 >= 7) + InitVPTriggers(); + for (i = 0; i < numobjects; i++) SyncObjectAnim(objectactive[i]); + } + +// rmw.patch1.start.1/23/97 +// if ((currlevel == quests[Q_BETRAYER]._qlevel) && (quests[Q_BETRAYER]._qvar2 == QS_VBRP1) + if ((currlevel == quests[Q_BETRAYER]._qlevel) && !setlevel + && ((quests[Q_BETRAYER]._qvar2 == QS_VBRP1) || (quests[Q_BETRAYER]._qvar2 >= QS_VBRP3)) +// rmw.patch1.end.1/23/97 + && ((quests[Q_BETRAYER]._qactive == QUEST_NOTDONE) || (quests[Q_BETRAYER]._qactive == QUEST_DONE))) { + quests[Q_BETRAYER]._qvar2 = QS_VBRP2; + } + +#endif +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +void DrawQLBack() +{ + DrawCel(408, 487, pSTextBoxCels, 1, 271); + + __asm { + mov edi,dword ptr [pBuffer] + add edi,372123 + + xor eax,eax + mov edx,148 +_YLp: mov ecx,132 +_XLp1: stosb + inc edi + loop _XLp1 + stosb + sub edi,1033 + mov ecx,132 +_XLp2: inc edi + stosb + loop _XLp2 + sub edi,1032 + dec edx + jnz _YLp + mov ecx,132 +_XLp3: stosb + inc edi + loop _XLp3 + stosb + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PrintQLString(int x, int y, BOOL cjustflag, char str[], char col) +{ + long boffset; + int sl,i,w,tw,xx,yy; + + yy = SStringY[y]; + boffset = nBuffWTbl[yy + 204] + x + 96; + sl = strlen(str); + w = 0; + if (cjustflag) { + tw = 0; + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + tw += fontkern[c]+1; + } + if (tw < 257) w = (257 - tw) >> 1; + boffset += w; + } + if (qline == y) { + if (cjustflag) xx = x + w + 76; + else xx = x + 76; + DrawCel(xx, yy + 205, pSTextSpinCels, qspin, 12); + } + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + w += fontkern[c]+1; + if ((c != 0) && (w <= 257)) DrawPanelFont(boffset, c, col); + boffset += fontkern[c]+1; + } + if (qline == y) { + if (cjustflag) xx = x + w + 100; + else xx = 340 - x; + DrawCel(xx, yy + 205, pSTextSpinCels, qspin, 12); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* + +void DrawQLLine(int y) +{ + long doffset; + + doffset = nBuffWTbl[SStringY[y] + 198] + 410; + __asm { + mov esi,dword ptr [pBuffer] + mov edi,esi + add esi,142170 + add edi,dword ptr [doffset] + + mov ebx,502 + + mov edx,3 +_YLp: mov ecx,66 + rep movsd + movsw + add esi,ebx + add edi,ebx + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawQuestLog() +{ + int i, l, q; + + //DrawQLBack(); + PrintQLString(0, 2, TRUE, "Quest Log", ICOLOR_GOLD); + //DrawQLLine(5); + + DrawCel(64, 511, pQLogCel, 1, 320); + + l = qtopline; + for (i = 0; i < numqlines; i++) { + q = qlist[i]; + PrintQLString(0, l , TRUE, questlist[q]._qlstr, ICOLOR_WHITE); + l+=2; + } + PrintQLString(0, 22, TRUE, "Close Quest Log", ICOLOR_WHITE); + qspin = (qspin & 0x7) + 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void StartQuestlog() +{ + int i; + + numqlines = 0; + for (i = 0; i < ALLQUESTS; i++) { + if ((quests[i]._qactive == QUEST_NOTDONE) && (quests[i]._qlog)) { + qlist[numqlines] = i; + numqlines++; + } + } + if (numqlines > 5) qtopline = 5 - (numqlines >> 1); + else qtopline = 8; + if (numqlines == 0) qline = 22; + else qline = qtopline; + questlog = TRUE; + qspin = 1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void QuestlogUp() +{ + if (numqlines != 0) { + if (qline == qtopline) qline = 22; + else { + if (qline == 22) qline = ((numqlines-1) << 1) + qtopline; + else qline -= 2; + } + PlaySFX(IS_TITLEMOV); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void QuestlogDown() +{ + if (numqlines != 0) { + if (qline == 22) qline = qtopline; + else { + if (qline == (((numqlines-1) << 1) + qtopline)) qline = 22; + else qline += 2; + } + PlaySFX(IS_TITLEMOV); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void QuestlogEnter() +{ + int q; + + PlaySFX(IS_TITLSLCT); + if ((numqlines != 0) && (qline != 22)) { + q = qlist[(qline - qtopline) >> 1]; + InitQTextMsg(quests[q]._qmsg); + } + questlog = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CheckQLogBtn() +{ + int i, ql; + + ql = (MouseY - 32) / 12; + if (numqlines != 0) { + for (i = 0; i < numqlines; i++) { + if (ql == ((i << 1) + qtopline)) { + qline = ql; + QuestlogEnter(); + } + } + } + if (ql == 22) { + qline = 22; + QuestlogEnter(); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void QuestlogESC() +{ + questlog = FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetMultiQuest(int q, int s, BOOL l, int v1) +{ +#if !IS_VERSION(SHAREWARE) + app_assert((DWORD)q < MAXQUESTS); + app_assert(quests[q]._qactive != QUEST_NOTAVAIL); + + // Don't change if already done + if (quests[q]._qactive == QUEST_DONE) + return; + + // always next state + if (s > quests[q]._qactive) + quests[q]._qactive = s; + + // never change from TRUE to FALSE + quests[q]._qlog |= l; + + // always next state + if (v1 > quests[q]._qvar1) + quests[q]._qvar1 = v1; +#endif +} diff --git a/QUESTS.H b/QUESTS.H new file mode 100644 index 0000000..0805aa6 --- /dev/null +++ b/QUESTS.H @@ -0,0 +1,155 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/QUESTS.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ +#ifndef MAXQUESTS // only one copy in existsence JKE + + + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXQUESTS 24 // JKEQUEST add to this when adding new quests +#define MAXMULTIQUESTS 9 + +#define Q_ROCK 0 +#define Q_BKMUSHRM 1 +#define Q_GARBUD 2 +#define Q_ZHAR 3 +#define Q_VEIL 4 +#define Q_DIABLO 5 +#define Q_BUTCHER 6 +#define Q_LTBANNER 7 +#define Q_BLIND 8 +#define Q_BLOOD 9 +#define Q_ANVIL 10 +#define Q_WARLORD 11 +#define Q_SKELKING 12 +#define Q_PWATER 13 +#define Q_SCHAMB 14 +#define Q_BETRAYER 15 +#define Q_CRYPTMAP 16 // JKEQUEST +#define Q_FARMER 17 +#define Q_THEO 18 +#define Q_TRADER 19 +#define Q_DEFILER 20 +#define Q_NA_KRUL 21 +#define Q_CORNERSTONE 22 +#define Q_COWSUIT 23 + +#define QUEST_NOTAVAIL 0 +#define QUEST_NOTACTIVE 1 +#define QUEST_NOTDONE 2 +#define QUEST_DONE 3 +#define QUEST_TOOWEAK1 4 +#define QUEST_TOOWEAK2 5 +#define QUEST_TOOWEAK3 6 +#define QUEST_PASS1 7 +#define QUEST_PASS2 8 +#define QUEST_PASS3 9 +#define QUEST_REALLYDONE 10 + + +#define QFLAG_MULTI 1 + +// Vile Betrayer Red Portal +#define QS_VBRPOFF 0 // Red Portal not init +#define QS_VBRP1 1 // Red Portal lvl 15 on +#define QS_VBRP2 2 // Red Portal lvl 15 off +#define QS_VBRP3 3 // Red Portal set lvl on +#define QS_VBRP4 4 // Red Portal set lvl off + +// Mushroom Quest states +enum { + QS_INIT=0, + QS_TOMESPAWNED, + QS_TOMEGIVEN, + QS_MUSHSPAWNED, + QS_MUSHPICKED, + QS_MUSHGIVEN, + QS_BRAINSPAWNED, + QS_BRAINGIVEN, // == elixir spawned +}; + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + byte _qlevel; // Which level the quest will appear on + byte _qtype; // Which quest it is + byte _qactive; // Not avail, not active, not completed, done flag + byte _qlvltype; // Quest level type (255 is current) + int _qtx; // X trigger to level + int _qty; // Y trigger to level + byte _qslvl; // Which set level is it? + byte _qidx; // quest data index + int _qmsg; // current quest msg + BYTE _qvar1; // quest-dependent state variable + BYTE _qvar2; + BOOL _qlog; // display in quest log +} QuestStruct; +#define SAVE_QUEST_SIZE sizeof(QuestStruct) + +typedef struct { + byte _qdlvl; // level the quest will appear on + char _qdmultlvl; // Which level the quest will appear on in multiplayer + byte _qlvlt; // Level gfx type + byte _qdtype; // Which quest it is + byte _qdrnd; // Random percent of quest appearing + byte _qslvl; // Set level number + BOOL _qflags; // Quest flags + int _qdmsg; // initial quest message + char *_qlstr; // String description for log +} QuestData; + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern QuestStruct quests[MAXQUESTS]; + +extern BOOL questlog; + +extern BYTE *pQLogCel; + +extern int ReturnLvlX, ReturnLvlY, ReturnLvl, ReturnLvlT; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitQuests(); +void DRLG_CheckQuests(int, int); +void CheckQuests(); +void CheckQuestKill(int, BOOL); + +void SetReturnLvlPos(); +void GetReturnLvlPos(); + +void ResyncQuests(); +void ResyncMPQuests(); + +void DrawQuestLog(); + +void StartQuestlog(); +void QuestlogUp(); +void QuestlogDown(); +void QuestlogEnter(); +void QuestlogESC(); +void CheckQLogBtn(); + +BOOL ForceQuests(); +BOOL QuestStatus(int); + +void SetMultiQuest(int, int, BOOL, int); + + +#endif \ No newline at end of file diff --git a/REGCONST.H b/REGCONST.H new file mode 100644 index 0000000..da5a4fc --- /dev/null +++ b/REGCONST.H @@ -0,0 +1,20 @@ +//************************************** +// regconst.h +// written 9.17.94 +// written by Patrick Wyatt +//************************************** + + +//************************************** +// registration blocks +//************************************** + // length of registration block embedded in program + #define REG_LEN 128 + + // length of table of registration blocks embedded in program + #define TBL_LEN 128 + + // offset to registration block + typedef ULONG REG_OFF; + #define MAX_REGS 10 + diff --git a/RESOURCE.H b/RESOURCE.H new file mode 100644 index 0000000..07a8001 --- /dev/null +++ b/RESOURCE.H @@ -0,0 +1,28 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Diablo.rc +// +#define IDI_ICON1 101 +#define IDD_DDRAW_ERR 104 +#define IDD_MEM_ERR 105 +#define IDD_FILE_ERR 106 +#define IDD_DDRAW_DLL_ERR 107 +#define IDD_DSOUND_DLL_ERR 108 +#define IDD_CHIP_ERR 109 +#define IDD_DISKFREE_ERR 110 +#define IDI_ICON2 110 +#define IDD_DDRAW_PAL_ERR 111 +#define IDD_CDROM_ERR 112 +#define IDC_ERROR_TAG 1000 +#define IDESCAPE 1001 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 112 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/SCLASS.H b/SCLASS.H new file mode 100644 index 0000000..0e1c039 --- /dev/null +++ b/SCLASS.H @@ -0,0 +1,158 @@ +#ifndef _STORM_SCLASS_H_ +#define _STORM_SCLASS_H_ + +extern "C++" { + +/**************************************************************************** +* +* CCRITSECT -- Critical section class +* +***/ + +class CCritSect { + private: + CRITICAL_SECTION m_critsect; + public: + CCritSect () { InitializeCriticalSection(&m_critsect); } + ~CCritSect () { DeleteCriticalSection(&m_critsect); } + void inline Enter () { EnterCriticalSection(&m_critsect); } + void inline Leave () { LeaveCriticalSection(&m_critsect); } +}; + +/**************************************************************************** +* +* CLOCK -- Lock class +* +***/ + +class CLock { + private: + SSYNCLOCK m_lock; + public: + CLock () { SSyncInitializeLock(&m_lock); } + ~CLock () { SSyncDeleteLock(&m_lock); } + void inline Enter (BOOL forwriting) { SSyncEnterLock(&m_lock,forwriting); } + void inline Leave (BOOL fromwriting) { SSyncLeaveLock(&m_lock,fromwriting); } +}; + +/**************************************************************************** +* +* TLIST -- Linked list function templates +* +***/ + +//=========================================================================== +template +BOOL inline TListAdd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return 0; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber); + if (!newptr) + return 0; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = *head; + *head = newptr; + return 1; +} +#define LISTADD(a,b) TListAdd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddEnd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return 0; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber); + if (!newptr) + return 0; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = NULL; + + T **next = head; + while (*next) + next = &(*next)->next; + *next = newptr; + + return 1; +} +#define LISTADDEND(a,b) TListAddEnd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddPtr (T **head, T *ptr) { + if (!(head && ptr)) + return 0; + + ptr->next = *head; + *head = ptr; + return 1; +} +#define LISTADDPTR(a,b) TListAddPtr(a,b) + +//=========================================================================== +template +BOOL inline TListAddPtrEnd (T **head, T *ptr) { + if (!(head && ptr)) + return 0; + + ptr->next = NULL; + T **next = head; + while (*next) + next = &(*next)->next; + *next = ptr; + + return 1; +} +#define LISTADDPTREND(a,b) TListAddPtrEnd(a,b) + +//=========================================================================== +template +BOOL inline TListClear (T **head, LPCSTR filename = NULL, int linenumber = 0) { + if (!head) + return 0; + + while (*head) { + T *next = (*head)->next; + SMemFree(*head,filename,linenumber); + *head = next; + } + return 1; +} +#define LISTCLEAR(a) TListClear(a,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFree (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return 0; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + SMemFree(ptr,filename,linenumber); + return (*next != NULL); +} +#define LISTFREE(a,b) TListFree(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFreePtr (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return 0; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + return (*next != NULL); +} +#define LISTFREEPTR(a,b) TListFreePtr(a,b,(LPCSTR)__FILE__,__LINE__) + +} // extern "C++" +#endif // ifndef _STORM_SCLASS_H_ diff --git a/SCRLASM.CPP b/SCRLASM.CPP new file mode 100644 index 0000000..08030b0 --- /dev/null +++ b/SCRLASM.CPP @@ -0,0 +1,6946 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Scrolling file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/SCRLASM.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +** CheckForScroll +** DrawAndBlit +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "scrlasm.h" +#include "gendung.h" +#include "lighting.h" + + //************************************************************************* + // Externs from scrollrt.cpp + //************************************************************************* + extern long nLVal; + extern DWORD gdwPNum; + extern long ClipY; + extern int gnPieceNum; + extern BOOL nTrans; + extern char gbPartialTrans; + extern char lightmax; + + + //************************************************************************* + // Private + //************************************************************************* + static long sgLineVal, cm; + static byte wt; + static long *t; + static long sgRightMask[32] = { + 0xeaaaaaaa, // 1110 1010 1010 1010 1010 1010 1010 1010 + 0xf5555555, // 1111 0101 0101 0101 0101 0101 0101 0101 + 0xfeaaaaaa, // 1111 1110 1010 1010 1010 1010 1010 1010 + 0xff555555, // 1111 1111 0101 0101 0101 0101 0101 0101 + 0xffeaaaaa, // 1111 1111 1110 1010 1010 1010 1010 1010 + 0xfff55555, // 1111 1111 1111 0101 0101 0101 0101 0101 + 0xfffeaaaa, // 1111 1111 1111 1110 1010 1010 1010 1010 + 0xffff5555, // 1111 1111 1111 1111 0101 0101 0101 0101 + 0xffffeaaa, // 1111 1111 1111 1111 1110 1010 1010 1010 + 0xfffff555, // 1111 1111 1111 1111 1111 0101 0101 0101 + 0xfffffeaa, // 1111 1111 1111 1111 1111 1110 1010 1010 + 0xffffff55, // 1111 1111 1111 1111 1111 1111 0101 0101 + 0xffffffea, // 1111 1111 1111 1111 1111 1111 1110 1010 + 0xfffffff5, // 1111 1111 1111 1111 1111 1111 1111 0101 + 0xfffffffe, // 1111 1111 1111 1111 1111 1111 1111 1110 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff }; // 1111 1111 1111 1111 1111 1111 1111 1111 + + static long sgLeftMask[32] = { + 0xaaaaaaab, // 1010 1010 1010 1010 1010 1010 1010 1011 + 0x5555555f, // 0101 0101 0101 0101 0101 0101 0101 1111 + 0xaaaaaabf, // 1010 1010 1010 1010 1010 1010 1011 1111 + 0x555555ff, // 0101 0101 0101 0101 0101 0101 1111 1111 + 0xaaaaabff, // 1010 1010 1010 1010 1010 1011 1111 1111 + 0x55555fff, // 0101 0101 0101 0101 0101 1111 1111 1111 + 0xaaaabfff, // 1010 1010 1010 1010 1011 1111 1111 1111 + 0x5555ffff, // 0101 0101 0101 0101 1111 1111 1111 1111 + 0xaaabffff, // 1010 1010 1010 1011 1111 1111 1111 1111 + 0x555fffff, // 0101 0101 0101 1111 1111 1111 1111 1111 + 0xaabfffff, // 1010 1010 1011 1111 1111 1111 1111 1111 + 0x55ffffff, // 0101 0101 1111 1111 1111 1111 1111 1111 + 0xabffffff, // 1010 1011 1111 1111 1111 1111 1111 1111 + 0x5fffffff, // 0101 1111 1111 1111 1111 1111 1111 1111 + 0xbfffffff, // 1011 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff, // 1111 1111 1111 1111 1111 1111 1111 1111 + 0xffffffff }; // 1111 1111 1111 1111 1111 1111 1111 1111 + + static long sgFullMask[32] = { + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555, // 0101 0101 0101 0101 0101 0101 0101 0101 + 0xaaaaaaaa, // 1010 1010 1010 1010 1010 1010 1010 1010 + 0x55555555 }; // 0101 0101 0101 0101 0101 0101 0101 0101 + + +/*-----------------------------------------------------------------------** +** Now with Y clipping (top clip) +**-----------------------------------------------------------------------*/ + +void TDecodeMicroTile (BYTE *pDecodeTo) +{ + t = µoffset[0][0]; + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,dword ptr [nLVal] + or al,al + jz _NoLt + cmp al,byte ptr [lightmax] + jz _Black + + mov eax,dword ptr [gdwPNum] + and eax,08000h + jnz _Speed + + mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov ebx,dword ptr [nLVal]; // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl]; + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh + jz _Type0 // Solid 32x32 block + cmp ax,1 + jz _Type1 // 32x32 block with '0' holes + cmp ax,2 + jz _Type2 // Left Triangle + cmp ax,3 + jz _Type3 // Right Triangle + cmp ax,4 + jz _Type4 // Left Triangle to wall + jmp _Type5 // Right Triangle to wall + +_Speed: mov esi,dword ptr [t] + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,4 + add eax,dword ptr [nLVal] + shl eax,2 + add esi,eax // Source + mov eax,dword ptr [esi] + mov esi,dword ptr [pSpeedCels] + add esi,eax + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh +_SCmp: cmp ax,8 + jz _Type8 // PreTrans Solid 32x32 block + cmp ax,9 + jz _Type9 // PreTrans 32x32 block with '0' holes + cmp ax,10 + jz _TypeA // PreTrans Left Triangle + cmp ax,11 + jz _TypeB // PreTrans Right Triangle + cmp ax,12 + jz _TypeC // PreTrans Left Triangle to wall + jmp _TypeD // PreTrans Right Triangle to wall + +_NoLt: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RNoLt + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RNoLt: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + add eax,8 + jmp _SCmp + +_Black: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RBlk + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RBlk: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + jz _TypeG // Black Trans Solid 32x32 block + cmp ax,1 + jz _TypeH // Black Trans 32x32 block with '0' holes + cmp ax,2 + jz _TypeI // Black Trans Left Triangle + cmp ax,3 + jz _TypeJ // Black Trans Right Triangle + cmp ax,4 + jz _TypeK // Black Trans Left Triangle to wall + jmp _TypeL // Black Trans Right Triangle to wall + +/*-----------------------------------------------------------------------*/ + +_Type0: mov edx,16 +_T0Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquad2 + pop edx + + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquad1 + pop edx + + sub edi,NBUFFW32 + dec edx + jnz _T0Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type1: mov eax,edi + and eax,1 + mov dword ptr [sgLineVal],eax + mov ecx,32 + +_T1Lp1: push ecx + mov edx,32 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + mov ecx,eax + mov eax,edi + and eax,1 + cmp eax,dword ptr [sgLineVal] + jnz _T1Od + + push edx + call xbyte1 + pop edx + jmp _T1x + +_T1Od: + push edx + call xbyte2 + pop edx + +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 + +_T1Nxt: pop ecx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + sub edi,NBUFFW32 + dec ecx + jnz _T1Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type2: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T2Lp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T2Od + + push edx + call xbyte1 + pop edx + jmp _T2x + +_T2Od: + push edx + call xbyte2 + pop edx + +_T2x: sub edi,NBUFFW32 + or edx,edx + jz _T2b + sub edx,2 + jmp _T2Lp1 + +_T2b: mov edx,2 +_T2Lp4: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T2Od2 + + push edx + call xbyte1 + pop edx + jmp _T2x2 + +_T2Od2: + push edx + call xbyte2 + pop edx + +_T2x2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _T2Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type3: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T3Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T3Od + + push edx + call xbyte1 + pop edx + jmp _T3x + +_T3Od: + push edx + call xbyte2 + pop edx + +_T3x: sub edi,NBUFFW32 + or edx,edx + jz _T3b + add edi,edx + sub edx,2 + jmp _T3Lp1 + +_T3b: mov edx,2 +_T3Lp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T3Od2 + + push edx + call xbyte1 + pop edx + jmp _T3x2 + +_T3Od2: + push edx + call xbyte2 + pop edx + +_T3x2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _T3Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type4: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T4Lp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T4Od + + push edx + call xbyte1 + pop edx + jmp _T4x + +_T4Od: + push edx + call xbyte2 + pop edx + +_T4x: sub edi,NBUFFW32 + or edx,edx + jz _T4b + sub edx,2 + jmp _T4Lp1 + +_T4b: mov edx,8 +_T4Lp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquad2 + pop edx + + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquad1 + pop edx + + sub edi,NBUFFW32 + dec edx + jnz _T4Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type5: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T5Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T5Od + + push edx + call xbyte1 + pop edx + jmp _T5x + +_T5Od: + push edx + call xbyte2 + pop edx + +_T5x: sub edi,NBUFFW32 + or edx,edx + jz _T5b + add edi,edx + sub edx,2 + jmp _T5Lp1 + +_T5b: mov edx,8 +_T5Lp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquad2 + pop edx + + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquad1 + pop edx + + sub edi,NBUFFW32 + dec edx + jnz _T5Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type8: mov edx,16 +_T8Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_T8Lp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _T8Lp2 + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_T8Lp3: lodsd + stosb + inc edi + ror eax,16 + stosb + inc edi + loop _T8Lp3 + sub edi,NBUFFW32 + dec edx + jnz _T8Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type9: mov eax,edi + and eax,1 + mov dword ptr [sgLineVal],eax + mov ecx,32 + +_T9Lp1: push ecx + mov edx,32 + +_T9Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T9J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + mov ecx,eax + mov eax,edi + and eax,1 + cmp eax,dword ptr [sgLineVal] + jnz _T9Od + shr ecx,1 + jnc _T9w + inc esi + inc edi + jecxz _T9x + jmp _T9w2 +_T9w: shr ecx,1 + jnc _T9Lp3 + inc esi + inc edi + movsb + jecxz _T9x +_T9Lp3: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _T9Lp3 + jmp _T9x + +_T9Od: shr ecx,1 + jnc _T9w2 + movsb + jecxz _T9x + jmp _T9w +_T9w2: shr ecx,1 + jnc _T9Lp4 + movsb + inc esi + inc edi + jecxz _T9x +_T9Lp4: lodsd + stosb + inc edi + ror eax,16 + stosb + inc edi + loop _T9Lp4 + +_T9x: or edx,edx + jz _T9Nxt + jmp _T9Lp2 + +_T9J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T9Lp2 + +_T9Nxt: pop ecx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + sub edi,NBUFFW32 + dec ecx + jnz _T9Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeA: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TALp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TAOd + shr ecx,2 + jnc _TALp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TAx +_TALp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TALp2 + jmp _TAx + +_TAOd: shr ecx,2 + jnc _TALp3 + lodsw + stosb + inc edi + jecxz _TAx +_TALp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TALp3 + +_TAx: sub edi,NBUFFW32 + or edx,edx + jz _TAb + sub edx,2 + jmp _TALp1 + +_TAb: mov edx,2 +_TALp4: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TAOd2 + shr ecx,2 + jnc _TALp5 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TAx2 +_TALp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TALp5 + jmp _TAx2 + +_TAOd2: shr ecx,2 + jnc _TALp6 + lodsw + stosb + inc edi + jecxz _TAx2 +_TALp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TALp6 + +_TAx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TALp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeB: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TBLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TBOd + shr ecx,2 + jnc _TBLp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TBx +_TBLp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TBLp2 + jmp _TBx + +_TBOd: shr ecx,2 + jnc _TBLp3 + lodsw + stosb + inc edi + jecxz _TBx +_TBLp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TBLp3 + +_TBx: sub edi,NBUFFW32 + or edx,edx + jz _TBb + add edi,edx + sub edx,2 + jmp _TBLp1 + +_TBb: mov edx,2 +_TBLp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TBOd2 + shr ecx,2 + jnc _TBLp5 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TBx2 +_TBLp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TBLp5 + jmp _TBx2 + +_TBOd2: shr ecx,2 + jnc _TBLp6 + lodsw + stosb + inc edi + jecxz _TBx2 +_TBLp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TBLp6 + +_TBx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TBLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeC: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TCLp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TCOd + shr ecx,2 + jnc _TCLp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TCx +_TCLp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TCLp2 + jmp _TCx + +_TCOd: shr ecx,2 + jnc _TCLp3 + lodsw + stosb + inc edi + jecxz _TCx +_TCLp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TCLp3 + +_TCx: sub edi,NBUFFW32 + or edx,edx + jz _TCb + sub edx,2 + jmp _TCLp1 + +_TCb: mov edx,8 +_TCLp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TCLp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TCLp5 + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TCLp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TCLp6 + sub edi,NBUFFW32 + dec edx + jnz _TCLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeD: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TDLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TDOd + shr ecx,2 + jnc _TDLp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TDx +_TDLp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TDLp2 + jmp _TDx + +_TDOd: shr ecx,2 + jnc _TDLp3 + lodsw + stosb + inc edi + jecxz _TDx +_TDLp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TDLp3 + +_TDx: sub edi,NBUFFW32 + or edx,edx + jz _TDb + add edi,edx + sub edx,2 + jmp _TDLp1 + +_TDb: mov edx,8 +_TDLp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TDLp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TDLp5 + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TDLp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TDLp6 + sub edi,NBUFFW32 + dec edx + jnz _TDLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeG: mov edx,16 + xor eax,eax +_TGLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TGLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TGLp2 + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TGLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TGLp3 + sub edi,NBUFFW32 + dec edx + jnz _TGLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeH: mov eax,edi + and eax,1 + mov dword ptr [sgLineVal],eax + mov ecx,32 + +_THLp1: push ecx + mov edx,32 + +_THLp2: xor eax,eax // Load control byte + lodsb + or al,al + js _THJ + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + mov ecx,eax + add esi,ecx + mov eax,edi + and eax,1 + cmp eax,dword ptr [sgLineVal] + jnz _THOd + xor eax,eax + shr ecx,1 + jnc _THw + inc edi + jecxz _THx + jmp _THw2 +_THw: shr ecx,1 + jnc _THLp3 + inc edi + stosb + jecxz _THx +_THLp3: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _THLp3 + jmp _THx + +_THOd: xor eax,eax + shr ecx,1 + jnc _THw2 + stosb + jecxz _THx + jmp _THw +_THw2: shr ecx,1 + jnc _THLp4 + stosb + inc edi + jecxz _THx +_THLp4: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _THLp4 + +_THx: or edx,edx + jz _THNxt + jmp _THLp2 + +_THJ: neg al // Do jump + add edi,eax + sub edx,eax + jnz _THLp2 + +_THNxt: pop ecx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + sub edi,NBUFFW32 + dec ecx + jnz _THLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeI: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TILp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TIOd + xor eax,eax + shr ecx,2 + jnc _TILp2 + inc edi + stosb + jecxz _TIx +_TILp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TILp2 + jmp _TIx + +_TIOd: xor eax,eax + shr ecx,2 + jnc _TILp3 + stosb + inc edi + jecxz _TIx +_TILp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TILp3 + +_TIx: sub edi,NBUFFW32 + or edx,edx + jz _TIb + sub edx,2 + jmp _TILp1 + +_TIb: mov edx,2 +_TILp4: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TIOd2 + xor eax,eax + shr ecx,2 + jnc _TILp5 + inc edi + stosb + jecxz _TIx2 +_TILp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TILp5 + jmp _TIx2 + +_TIOd2: xor eax,eax + shr ecx,2 + jnc _TILp6 + stosb + inc edi + jecxz _TIx2 +_TILp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TILp6 + +_TIx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TILp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeJ: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TJLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TJOd + xor eax,eax + shr ecx,2 + jnc _TJLp2 + inc edi + stosb + jecxz _TJx +_TJLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TJLp2 + jmp _TJx + +_TJOd: xor eax,eax + shr ecx,2 + jnc _TJLp3 + stosb + inc edi + jecxz _TJx +_TJLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TJLp3 + +_TJx: sub edi,NBUFFW32 + or edx,edx + jz _TJb + add edi,edx + sub edx,2 + jmp _TJLp1 + +_TJb: mov edx,2 +_TJLp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TJOd2 + xor eax,eax + shr ecx,2 + jnc _TJLp5 + inc edi + stosb + jecxz _TJx2 +_TJLp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TJLp5 + jmp _TJx2 + +_TJOd2: xor eax,eax + shr ecx,2 + jnc _TJLp6 + stosb + inc edi + jecxz _TJx2 +_TJLp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TJLp6 + +_TJx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TJLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeK: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TKLp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TKOd + xor eax,eax + shr ecx,2 + jnc _TKLp2 + inc edi + stosb + jecxz _TKx +_TKLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TKLp2 + jmp _TKx + +_TKOd: xor eax,eax + shr ecx,2 + jnc _TKLp3 + stosb + inc edi + jecxz _TKx +_TKLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TKLp3 + +_TKx: sub edi,NBUFFW32 + or edx,edx + jz _TKb + sub edx,2 + jmp _TKLp1 + +_TKb: mov edx,8 + xor eax,eax +_TKLp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TKLp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TKLp5 + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TKLp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TKLp6 + sub edi,NBUFFW32 + dec edx + jnz _TKLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeL: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TLLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TLOd + xor eax,eax + shr ecx,2 + jnc _TLLp2 + inc edi + stosb + jecxz _TLx +_TLLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TLLp2 + jmp _TLx + +_TLOd: xor eax,eax + shr ecx,2 + jnc _TLLp3 + stosb + inc edi + jecxz _TLx +_TLLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TLLp3 + +_TLx: sub edi,NBUFFW32 + or edx,edx + jz _TLb + add edi,edx + sub edx,2 + jmp _TLLp1 + +_TLb: mov edx,8 + xor eax,eax +_TLLp4: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TLLp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TLLp5 + sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 +_TLLp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TLLp6 + sub edi,NBUFFW32 + dec edx + jnz _TLLp4 + jmp _Done + +xbyte1: // blank first + + shr ecx,1 + jnc xword2 + inc esi + inc edi + +xword1: // xlat first + shr ecx,1 + jnc xquadt1 + mov dl,[esi] + mov dl,[ebx+edx] + add esi,2 + mov [edi],dl + add edi,2 + +xquadt1: + test cl,cl + jz xend + +xquad1: // xlat first +/* debug + shl ecx,2 + add esi,ecx + add edi,ecx + ret +*/ + + mov eax,[esi] + add esi,4 + mov dl,al + shr eax,16 + mov dl,[ebx+edx] + mov [edi],dl + mov dl,al + add edi,4 + mov dl,[ebx+edx] + dec ecx + mov [edi-2],dl + jnz xquad1 + + ret + + +xbyte2: // xlat first + + shr ecx,1 + jnc xword1 + mov dl,[esi] + mov dl,[ebx+edx] + inc esi + mov [edi],dl + inc edi + +xword2: // blank first + shr ecx,1 + jnc xquadt2 + mov dl,[esi+1] + mov dl,[ebx+edx] + add esi,2 + mov [edi+1],dl + add edi,2 + +xquadt2: + test cl,cl + jz xend + +xquad2: // blank first +/* debug + shl ecx,2 + add esi,ecx + add edi,ecx + ret +*/ + + + mov eax,[esi] + add esi,4 + mov dl,ah + shr eax,16 + mov dl,[ebx+edx] + mov [edi+1],dl + mov dl,ah + add edi,4 + mov dl,[ebx+edx] + dec ecx + mov [edi-1],dl + jnz xquad2 + +xend: + ret + +_PDone: pop eax +_Done: nop + + + } // end of asm block +} + +/*-----------------------------------------------------------------------** +** Now with Y clipping and Masking Transparency +**-----------------------------------------------------------------------*/ + +void TDecodeM12Tile (BYTE *pDecodeTo, long *mask) +{ + t = µoffset[0][0]; + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,dword ptr [nLVal] + or al,al + jz _NoLt + cmp al,byte ptr [lightmax] + jz _Black + + mov eax,dword ptr [gdwPNum] + and eax,08000h + jnz _Speed + + mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov ebx,dword ptr [nLVal]; // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl]; + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh + jz _Type0 // Solid 32x32 block + cmp ax,1 + jz _Type1 // 32x32 block with '0' holes + cmp ax,2 + jz _Type2 // Left Triangle + cmp ax,3 + jz _Type3 // Right Triangle + cmp ax,4 + jz _Type4 // Left Triangle to wall + jmp _Type5 // Right Triangle to wall + +_Speed: mov esi,dword ptr [t] + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,4 + add eax,dword ptr [nLVal] + shl eax,2 + add esi,eax // Source + mov eax,dword ptr [esi] + mov esi,dword ptr [pSpeedCels] + add esi,eax + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh +_SCmp: cmp ax,8 + jz _Type8 // PreTrans Solid 32x32 block + cmp ax,9 + jz _Type9 // PreTrans 32x32 block with '0' holes + cmp ax,10 + jz _TypeA // PreTrans Left Triangle + cmp ax,11 + jz _TypeB // PreTrans Right Triangle + cmp ax,12 + jz _TypeC // PreTrans Left Triangle to wall + jmp _TypeD // PreTrans Right Triangle to wall + +_NoLt: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RNoLt + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RNoLt: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + add eax,8 + jmp _SCmp + +_Black: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RBlk + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RBlk: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + jz _TypeG // Black Trans Solid 32x32 block + cmp ax,1 + jz _TypeH // Black Trans 32x32 block with '0' holes + cmp ax,2 + jz _TypeI // Black Trans Left Triangle + cmp ax,3 + jz _TypeJ // Black Trans Right Triangle + cmp ax,4 + jz _TypeK // Black Trans Left Triangle to wall + jmp _TypeL // Black Trans Right Triangle to wall + +/*-----------------------------------------------------------------------*/ + +_Type0: mov edx,32 +_T0Lp1: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T0Lp2: lodsb + shl edx,1 + jnc _T0S1 + xlatb + mov byte ptr [edi],al +_T0S1: inc edi + loop _T0Lp2 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T0Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type1: mov ecx,32 + +_T1Lp1: push ecx + mov eax,dword ptr [mask] + mov eax,dword ptr [eax] + mov dword ptr [cm],eax + + mov edx,32 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + mov ecx,eax + push edx + mov edx,dword ptr [cm] +_T1Lp3: lodsb + shl edx,1 + jnc _T1S1 + xlatb + mov byte ptr [edi],al +_T1S1: inc edi + loop _T1Lp3 + mov dword ptr [cm],edx + pop edx + or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + mov ecx,eax + and ecx,01fh + jz _T1S2 + push eax + mov eax,dword ptr [cm] + shl eax,cl + mov dword ptr [cm],eax + pop eax +_T1S2: sub edx,eax + jnz _T1Lp2 +_T1Nxt: pop ecx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec ecx + jnz _T1Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type2: mov edx,30 +_T2Lp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T2Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T2x +_T2Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T2Lp2 +_T2x: sub edi,NBUFFW32 + or edx,edx + jz _T2b + sub edx,2 + jmp _T2Lp1 + +_T2b: mov edx,2 +_T2Lp3: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T2Lp4 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T2x2 +_T2Lp4: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T2Lp4 +_T2x2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _T2Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type3: mov edx,30 +_T3Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T3Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T3x +_T3Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T3Lp2 +_T3x: sub edi,NBUFFW32 + or edx,edx + jz _T3b + add edi,edx + sub edx,2 + jmp _T3Lp1 + +_T3b: mov edx,2 +_T3Lp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T3Lp4 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T3x2 +_T3Lp4: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T3Lp4 +_T3x2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _T3Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type4: mov edx,30 +_T4Lp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T4Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T4x +_T4Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T4Lp2 +_T4x: sub edi,NBUFFW32 + or edx,edx + jz _T4b + sub edx,2 + jmp _T4Lp1 + +_T4b: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_T4Lp3: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T4Lp4: lodsb + shl edx,1 + jnc _T4S1 + xlatb + mov byte ptr [edi],al +_T4S1: inc edi + loop _T4Lp4 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T4Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type5: mov edx,30 +_T5Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T5Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T5x +_T5Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T5Lp2 +_T5x: sub edi,NBUFFW32 + or edx,edx + jz _T5b + add edi,edx + sub edx,2 + jmp _T5Lp1 + +_T5b: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_T5Lp3: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T5Lp4: lodsb + shl edx,1 + jnc _T5S1 + xlatb + mov byte ptr [edi],al +_T5S1: inc edi + loop _T5Lp4 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T5Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type8: mov edx,32 +_T8Lp1: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T8Lp2: lodsb + shl edx,1 + jnc _T8S1 + mov byte ptr [edi],al +_T8S1: inc edi + loop _T8Lp2 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T8Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type9: mov ecx,32 + +_T9Lp1: push ecx + mov eax,dword ptr [mask] + mov eax,dword ptr [eax] + mov dword ptr [cm],eax + + mov edx,32 + +_T9Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T9J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + push edx + mov edx,dword ptr [cm] + mov ecx,eax +_T9Lp3: lodsb + shl edx,1 + jnc _T9S1 + mov byte ptr [edi],al +_T9S1: inc edi + loop _T9Lp3 + mov dword ptr [cm],edx + pop edx + or edx,edx + jz _T9Nxt + jmp _T9Lp2 + +_T9J: neg al // Do jump + add edi,eax + mov ecx,eax + and ecx,01fh + jz _T9S2 + mov ebx,dword ptr [cm] + shl ebx,cl + mov dword ptr [cm],ebx +_T9S2: sub edx,eax + jnz _T9Lp2 +_T9Nxt: pop ecx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec ecx + jnz _T9Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeA: mov edx,30 +_TALp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp2 + movsw + jecxz _TAx +_TALp2: rep movsd +_TAx: sub edi,NBUFFW32 + or edx,edx + jz _TAb + sub edx,2 + jmp _TALp1 + +_TAb: mov edx,2 +_TALp3: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp4 + movsw + jecxz _TAx2 +_TALp4: rep movsd +_TAx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TALp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeB: mov edx,30 +_TBLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp2 + movsw + jecxz _TBx +_TBLp2: rep movsd +_TBx: sub edi,NBUFFW32 + or edx,edx + jz _TBb + add edi,edx + sub edx,2 + jmp _TBLp1 + +_TBb: mov edx,2 +_TBLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp4 + movsw + jecxz _TBx2 +_TBLp4: rep movsd +_TBx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TBLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeC: mov edx,30 +_TCLp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TCLp2 + movsw + jecxz _TCx +_TCLp2: rep movsd +_TCx: sub edi,NBUFFW32 + or edx,edx + jz _TCb + sub edx,2 + jmp _TCLp1 + +_TCb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TCLp3: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_TCLp4: lodsb + shl edx,1 + jnc _TCS1 + mov byte ptr [edi],al +_TCS1: inc edi + loop _TCLp4 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TCLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeD: mov edx,30 +_TDLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TDLp2 + movsw + jecxz _TDx +_TDLp2: rep movsd +_TDx: sub edi,NBUFFW32 + or edx,edx + jz _TDb + add edi,edx + sub edx,2 + jmp _TDLp1 + +_TDb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TDLp3: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_TDLp4: lodsb + shl edx,1 + jnc _TDS1 + mov byte ptr [edi],al +_TDS1: inc edi + loop _TDLp4 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TDLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeG: mov edx,32 +_TGLp1: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + xor eax,eax + mov ecx,32 +_TGLp2: shl edx,1 + jnc _TGS1 + mov byte ptr [edi],al +_TGS1: inc edi + loop _TGLp2 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TGLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeH: mov ecx,32 + +_THLp1: push ecx + mov eax,dword ptr [mask] + mov eax,dword ptr [eax] + mov dword ptr [cm],eax + + mov edx,32 + +_THLp2: xor eax,eax // Load control byte + lodsb + or al,al + js _THJ + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + push edx + mov edx,dword ptr [cm] + mov ecx,eax + add esi,ecx + xor eax,eax +_THLp3: shl edx,1 + jnc _THS1 + mov byte ptr [edi],al +_THS1: inc edi + loop _THLp3 + mov dword ptr [cm],edx + pop edx + or edx,edx + jz _THNxt + jmp _THLp2 + +_THJ: neg al // Do jump + add edi,eax + mov ecx,eax + and ecx,01fh + jz _THS2 + mov ebx,dword ptr [cm] + shl ebx,cl + mov dword ptr [cm],ebx +_THS2: sub edx,eax + jnz _THLp2 +_THNxt: pop ecx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec ecx + jnz _THLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeI: mov edx,30 + xor eax,eax +_TILp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TILp2 + stosw + jecxz _TIx +_TILp2: rep stosd +_TIx: sub edi,NBUFFW32 + or edx,edx + jz _TIb + sub edx,2 + jmp _TILp1 + +_TIb: mov edx,2 +_TILp3: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + + shr ecx,2 + jnc _TILp4 + stosw + jecxz _TIx2 +_TILp4: rep stosd +_TIx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TILp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeJ: mov edx,30 + xor eax,eax +_TJLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp2 + stosw + jecxz _TJx +_TJLp2: rep stosd +_TJx: sub edi,NBUFFW32 + or edx,edx + jz _TJb + add edi,edx + sub edx,2 + jmp _TJLp1 + +_TJb: mov edx,2 +_TJLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp4 + stosw + jecxz _TJx2 +_TJLp4: rep stosd +_TJx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TJLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeK: mov edx,30 + xor eax,eax +_TKLp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TKLp2 + stosw + jecxz _TKx +_TKLp2: rep stosd +_TKx: sub edi,NBUFFW32 + or edx,edx + jz _TKb + sub edx,2 + jmp _TKLp1 + +_TKb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TKLp3: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + xor eax,eax + mov ecx,32 +_TKLp4: shl edx,1 + jnc _TKS1 + mov byte ptr [edi],al +_TKS1: inc edi + loop _TKLp4 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TKLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeL: mov edx,30 + xor eax,eax +_TLLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TLLp2 + stosw + jecxz _TLx +_TLLp2: rep stosd +_TLx: sub edi,NBUFFW32 + or edx,edx + jz _TLb + add edi,edx + sub edx,2 + jmp _TLLp1 + +_TLb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TLLp3: cmp edi,dword ptr [ClipY] + jb _Done + push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + xor eax,eax + mov ecx,32 +_TLLp4: shl edx,1 + jnc _TLS1 + mov byte ptr [edi],al +_TLS1: inc edi + loop _TLLp4 + pop edx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TLLp3 + jmp _Done + +_PDone: pop eax +_Done: nop + + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Now with Y clipping (top clip) +**-----------------------------------------------------------------------*/ + +void DecodeMicroTile (BYTE *pDecodeTo) +{ + if (nTrans) { + if (gbPartialTrans == PART_TRANS_NONE) { + TDecodeMicroTile(pDecodeTo); + return; + } else { + if (gbPartialTrans == PART_TRANS_LEFT) { + wt = nWTypeTable[gnPieceNum]; + if ((wt == WTYPE_LEFT) || (wt == WTYPE_ULC)) { + TDecodeM12Tile(pDecodeTo, &sgLeftMask[31]); + return; + } + if (wt == WTYPE_LRC) { + TDecodeM12Tile(pDecodeTo, &sgRightMask[31]); + return; + } + } + if (gbPartialTrans == PART_TRANS_RIGHT) { + wt = nWTypeTable[gnPieceNum]; + if ((wt == WTYPE_RIGHT) || (wt == WTYPE_ULC)) { + TDecodeM12Tile(pDecodeTo, &sgRightMask[31]); + return; + } + if (wt == WTYPE_LRC) { + TDecodeM12Tile(pDecodeTo, &sgLeftMask[31]); + return; + } + } + } + } + t = µoffset[0][0]; + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,dword ptr [nLVal] + or al,al + jz _NoLt + cmp al,byte ptr [lightmax] + jz _Black + + mov eax,dword ptr [gdwPNum] + and eax,08000h + jnz _Speed + + mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov ebx,dword ptr [nLVal] // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl] + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh + jz _Type0 // Solid 32x32 block + cmp ax,1 + jz _Type1 // 32x32 block with '0' holes + cmp ax,2 + jz _Type2 // Left Triangle + cmp ax,3 + jz _Type3 // Right Triangle + cmp ax,4 + jz _Type4 // Left Triangle to wall + jmp _Type5 // Right Triangle to wall + +_Speed: mov esi,dword ptr [t] + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,4 + add eax,dword ptr [nLVal] + shl eax,2 + add esi,eax // Source + mov eax,dword ptr [esi] + mov esi,dword ptr [pSpeedCels] + add esi,eax + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh +_SCmp: cmp ax,8 + jz _Type8 // PreTrans Solid 32x32 block + cmp ax,9 + jz _Type9 // PreTrans 32x32 block with '0' holes + cmp ax,10 + jz _TypeA // PreTrans Left Triangle + cmp ax,11 + jz _TypeB // PreTrans Right Triangle + cmp ax,12 + jz _TypeC // PreTrans Left Triangle to wall + jmp _TypeD // PreTrans Right Triangle to wall + +_NoLt: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RNoLt + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RNoLt: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + add eax,8 + jmp _SCmp + +_Black: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RBlk + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RBlk: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + jz _TypeG // Black Trans Solid 32x32 block + cmp ax,1 + jz _TypeH // Black Trans 32x32 block with '0' holes + cmp ax,2 + jz _TypeI // Black Trans Left Triangle + cmp ax,3 + jz _TypeJ // Black Trans Right Triangle + cmp ax,4 + jz _TypeK // Black Trans Left Triangle to wall + jmp _TypeL // Black Trans Right Triangle to wall + +/*-----------------------------------------------------------------------*/ + +_Type0: mov edx,32 +_T0Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquads + pop edx + + sub edi,NBUFFW32 + dec edx + jnz _T0Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type1: mov ecx,32 + +_T1Lp1: push ecx + mov edx,32 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + mov ecx,eax + + push edx + call xbytes + pop edx + + or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: pop ecx + sub edi,NBUFFW32 + dec ecx + jnz _T1Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type2: mov edx,30 +_T2Lp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + + sub edi,NBUFFW32 + or edx,edx + jz _T2b + sub edx,2 + jmp _T2Lp1 + +_T2b: mov edx,2 +_T2Lp3: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + + sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _T2Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type3: mov edx,30 +_T3Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + + sub edi,NBUFFW32 + or edx,edx + jz _T3b + add edi,edx + sub edx,2 + jmp _T3Lp1 + +_T3b: mov edx,2 +_T3Lp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + + sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _T3Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type4: mov edx,30 +_T4Lp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + + sub edi,NBUFFW32 + or edx,edx + jz _T4b + sub edx,2 + jmp _T4Lp1 + +_T4b: mov edx,16 +_T4Lp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquads + pop edx + + sub edi,NBUFFW32 + dec edx + jnz _T4Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type5: mov edx,30 +_T5Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + + sub edi,NBUFFW32 + or edx,edx + jz _T5b + add edi,edx + sub edx,2 + jmp _T5Lp1 + +_T5b: mov edx,16 +_T5Lp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + + push edx + call xquads + pop edx + + sub edi,NBUFFW32 + dec edx + jnz _T5Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type8: mov edx,32 +_T8Lp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + rep movsd + sub edi,NBUFFW32 + dec edx + jnz _T8Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type9: mov ecx,32 + +_T9Lp1: push ecx + mov edx,32 + +_T9Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T9J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + mov ecx,eax + shr ecx,1 + jnc _T9w + movsb + jecxz _T9x +_T9w: shr ecx,1 + jnc _T9Lp3 + movsw + jecxz _T9x +_T9Lp3: rep movsd +_T9x: or edx,edx + jz _T9Nxt + jmp _T9Lp2 + +_T9J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T9Lp2 +_T9Nxt: pop ecx + sub edi,NBUFFW32 + loop _T9Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeA: mov edx,30 +_TALp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp2 + movsw + jecxz _TAx +_TALp2: rep movsd +_TAx: sub edi,NBUFFW32 + or edx,edx + jz _TAb + sub edx,2 + jmp _TALp1 + +_TAb: mov edx,2 +_TALp3: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp4 + movsw + jecxz _TAx2 +_TALp4: rep movsd +_TAx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TALp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeB: mov edx,30 +_TBLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp2 + movsw + jecxz _TBx +_TBLp2: rep movsd +_TBx: sub edi,NBUFFW32 + or edx,edx + jz _TBb + add edi,edx + sub edx,2 + jmp _TBLp1 + +_TBb: mov edx,2 +_TBLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp4 + movsw + jecxz _TBx2 +_TBLp4: rep movsd +_TBx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TBLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeC: mov edx,30 +_TCLp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TCLp2 + movsw + jecxz _TCx +_TCLp2: rep movsd +_TCx: sub edi,NBUFFW32 + or edx,edx + jz _TCb + sub edx,2 + jmp _TCLp1 + +_TCb: mov edx,16 +_TCLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + rep movsd + sub edi,NBUFFW32 + dec edx + jnz _TCLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeD: mov edx,30 +_TDLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TDLp2 + movsw + jecxz _TDx +_TDLp2: rep movsd +_TDx: sub edi,NBUFFW32 + or edx,edx + jz _TDb + add edi,edx + sub edx,2 + jmp _TDLp1 + +_TDb: mov edx,16 +_TDLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + rep movsd + sub edi,NBUFFW32 + dec edx + jnz _TDLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeG: mov edx,32 + xor eax,eax +_TGLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + rep stosd + sub edi,NBUFFW32 + dec edx + jnz _TGLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeH: mov ecx,32 + +_THLp1: push ecx + mov edx,32 + +_THLp2: xor eax,eax // Load control byte + lodsb + or al,al + js _THJ + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _PDone + mov ecx,eax + add esi,ecx + xor eax,eax + shr ecx,1 + jnc _THw + stosb + jecxz _THx +_THw: shr ecx,1 + jnc _THLp3 + stosw + jecxz _THx +_THLp3: rep stosd +_THx: or edx,edx + jz _THNxt + jmp _THLp2 + +_THJ: neg al // Do jump + add edi,eax + sub edx,eax + jnz _THLp2 +_THNxt: pop ecx + sub edi,NBUFFW32 + loop _THLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeI: mov edx,30 + xor eax,eax +_TILp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TILp2 + stosw + jecxz _TIx +_TILp2: rep stosd +_TIx: sub edi,NBUFFW32 + or edx,edx + jz _TIb + sub edx,2 + jmp _TILp1 + +_TIb: mov edx,2 +_TILp3: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TILp4 + stosw + jecxz _TIx2 +_TILp4: rep stosd +_TIx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TILp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeJ: mov edx,30 + xor eax,eax +_TJLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp2 + stosw + jecxz _TJx +_TJLp2: rep stosd +_TJx: sub edi,NBUFFW32 + or edx,edx + jz _TJb + add edi,edx + sub edx,2 + jmp _TJLp1 + +_TJb: mov edx,2 +_TJLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp4 + stosw + jecxz _TJx2 +_TJLp4: rep stosd +_TJx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TJLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeK: mov edx,30 + xor eax,eax +_TKLp1: cmp edi,dword ptr [ClipY] + jb _Done + add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TKLp2 + stosw + jecxz _TKx +_TKLp2: rep stosd +_TKx: sub edi,NBUFFW32 + or edx,edx + jz _TKb + sub edx,2 + jmp _TKLp1 + +_TKb: mov edx,16 +_TKLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + rep stosd + sub edi,NBUFFW32 + dec edx + jnz _TKLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeL: mov edx,30 + xor eax,eax +_TLLp1: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TLLp2 + stosw + jecxz _TLx +_TLLp2: rep stosd +_TLx: sub edi,NBUFFW32 + or edx,edx + jz _TLb + add edi,edx + sub edx,2 + jmp _TLLp1 + +_TLb: mov edx,16 +_TLLp3: cmp edi,dword ptr [ClipY] + jb _Done + mov ecx,8 + rep stosd + sub edi,NBUFFW32 + dec edx + jnz _TLLp3 + jmp _Done + +xbytes: + + shr cl,1 + jnc xwords + + mov dl, [esi] + mov dl, [ebx+edx] + mov [edi],dl + + add esi,1 + add edi,1 + +xwords: + shr cl,1 + jnc xquads + + mov dl, [esi] + mov ch, [ebx+edx] + + mov [edi],ch + mov dl, [esi+1] + + mov ch, [ebx+edx] + mov [edi+1],ch + + add esi,2 + add edi,2 + +xquads: + test cl,cl + jz xend + +xnext: + mov eax, [esi] + add esi,4 + + mov dl,al + mov ch,[ebx+edx] + + mov dl,ah + ror eax,16 + mov [edi],ch + + mov ch,[ebx+edx] + + mov dl,al + mov [edi+1],ch + + mov ch,[ebx+edx] + + mov dl,ah + mov [edi+2],ch + + mov ch,[ebx+edx] + mov [edi+3],ch + + add edi,4 + + dec cl + jnz xnext + +xend: + ret + +_PDone: pop eax +_Done: nop + + } // end of asm block +} + +/*-----------------------------------------------------------------------** +** Now with Y clipping +**-----------------------------------------------------------------------*/ + +void TCDecodeMicroTile (BYTE *pDecodeTo) +{ + t = µoffset[0][0]; + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,dword ptr [nLVal] + or al,al + jz _NoLt + cmp al,byte ptr [lightmax] + jz _Black + + mov eax,dword ptr [gdwPNum] + and eax,08000h + jnz _Speed + + mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov ebx,dword ptr [nLVal]; // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl]; + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh + jz _Type0 // Solid 32x32 block + cmp ax,1 + jz _Type1 // 32x32 block with '0' holes + cmp ax,2 + jz _Type2 // Left Triangle + cmp ax,3 + jz _Type3 // Right Triangle + cmp ax,4 + jz _Type4 // Left Triangle to wall + jmp _Type5 // Right Triangle to wall + +_Speed: mov esi,dword ptr [t] + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,4 + add eax,dword ptr [nLVal] + shl eax,2 + add esi,eax // Source + mov eax,dword ptr [esi] + mov esi,dword ptr [pSpeedCels] + add esi,eax + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh +_SCmp: cmp ax,8 + jz _Type8 // PreTrans Solid 32x32 block + cmp ax,9 + jz _Type9 // PreTrans 32x32 block with '0' holes + cmp ax,10 + jz _TypeA // PreTrans Left Triangle + cmp ax,11 + jz _TypeB // PreTrans Right Triangle + cmp ax,12 + jz _TypeC // PreTrans Left Triangle to wall + jmp _TypeD // PreTrans Right Triangle to wall + +_NoLt: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RNoLt + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RNoLt: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + add eax,8 + jmp _SCmp + +_Black: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RBlk + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RBlk: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + jz _TypeG // Black Trans Solid 32x32 block + cmp ax,1 + jz _TypeH // Black Trans 32x32 block with '0' holes + cmp ax,2 + jz _TypeI // Black Trans Left Triangle + cmp ax,3 + jz _TypeJ // Black Trans Right Triangle + cmp ax,4 + jz _TypeK // Black Trans Left Triangle to wall + jmp _TypeL // Black Trans Right Triangle to wall + +/*-----------------------------------------------------------------------*/ + +_Type0: mov edx,16 +_T0Lp1: cmp edi,dword ptr [ClipY] + jb _T0C1 + add esi,32 + add edi,32 + jmp _T0C2 +_T0C1: mov ecx,8 + + push edx + call xquad2 + pop edx + +_T0C2: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _T0C3 + add esi,32 + add edi,32 + jmp _T0C4 +_T0C3: mov ecx,8 + + push edx + call xquad1 + pop edx + +_T0C4: sub edi,NBUFFW32 + dec edx + jnz _T0Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type1: mov eax,edi + and eax,1 + mov dword ptr [sgLineVal],eax + mov ecx,32 + +_T1Lp1: push ecx + mov edx,32 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: mov ecx,eax + mov eax,edi + and eax,1 + cmp eax,dword ptr [sgLineVal] + jnz _T1Od + + push edx + call xbyte1 + pop edx + jmp _T1x + +_T1Od: + push edx + call xbyte2 + pop edx + +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: pop ecx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + sub edi,NBUFFW32 + dec ecx + jnz _T1Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type2: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T2Lp1: cmp edi,dword ptr [ClipY] + jb _T2C1 + add esi,32 + sub esi,edx + add edi,32 + jmp _T2x +_T2C1: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T2Od + + push edx + call xbyte1 + pop edx + jmp _T2x + +_T2Od: + push edx + call xbyte2 + pop edx + +_T2x: sub edi,NBUFFW32 + or edx,edx + jz _T2b + sub edx,2 + jmp _T2Lp1 + +_T2b: mov edx,2 +_T2Lp4: cmp edi,dword ptr [ClipY] + jb _T2C2 + add esi,32 + sub esi,edx + add edi,32 + jmp _T2x2 +_T2C2: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T2Od2 + + push edx + call xbyte1 + pop edx + jmp _T2x2 + +_T2Od2: + push edx + call xbyte2 + pop edx + +_T2x2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _T2Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type3: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T3Lp1: cmp edi,dword ptr [ClipY] + jb _T3C1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T3x +_T3C1: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T3Od + + push edx + call xbyte1 + pop edx + jmp _T3x + +_T3Od: + push edx + call xbyte2 + pop edx + +_T3x: sub edi,NBUFFW32 + or edx,edx + jz _T3b + add edi,edx + sub edx,2 + jmp _T3Lp1 + +_T3b: mov edx,2 +_T3Lp4: cmp edi,dword ptr [ClipY] + jb _T3C2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T3x2 +_T3C2: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T3Od2 + + push edx + call xbyte1 + pop edx + jmp _T3x2 + +_T3Od2: + push edx + call xbyte2 + pop edx + +_T3x2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _T3Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type4: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T4Lp1: cmp edi,dword ptr [ClipY] + jb _T4C1 + add esi,32 + sub esi,edx + add edi,32 + jmp _T4x +_T4C1: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T4Od + + push edx + call xbyte1 + pop edx + jmp _T4x + +_T4Od: + push edx + call xbyte2 + pop edx + +_T4x: sub edi,NBUFFW32 + or edx,edx + jz _T4b + sub edx,2 + jmp _T4Lp1 + +_T4b: mov edx,8 +_T4Lp4: cmp edi,dword ptr [ClipY] + jb _T4C2 + add esi,32 + add edi,32 + jmp _T4C3 +_T4C2: mov ecx,8 + + push edx + call xquad2 + pop edx + +_T4C3: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _T4C4 + add esi,32 + add edi,32 + jmp _T4C5 +_T4C4: mov ecx,8 + + push edx + call xquad1 + pop edx + +_T4C5: sub edi,NBUFFW32 + dec edx + jnz _T4Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type5: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_T5Lp1: cmp edi,dword ptr [ClipY] + jb _T5C1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T5x +_T5C1: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _T5Od + + push edx + call xbyte1 + pop edx + jmp _T5x + +_T5Od: + push edx + call xbyte2 + pop edx + +_T5x: sub edi,NBUFFW32 + or edx,edx + jz _T5b + add edi,edx + sub edx,2 + jmp _T5Lp1 + +_T5b: mov edx,8 +_T5Lp4: cmp edi,dword ptr [ClipY] + jb _T5C2 + add esi,32 + add edi,32 + jmp _T5C3 +_T5C2: mov ecx,8 + + push edx + call xquad2 + pop edx + +_T5C3: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _T5C4 + add esi,32 + add edi,32 + jmp _T5C5 +_T5C4: mov ecx,8 + + push edx + call xquad1 + pop edx + +_T5C5: sub edi,NBUFFW32 + dec edx + jnz _T5Lp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type8: mov edx,16 +_T8Lp1: cmp edi,dword ptr [ClipY] + jb _T8C1 + add esi,32 + add edi,32 + jmp _T8C2 +_T8C1: mov ecx,8 +_T8Lp2: lodsd + inc edi + ror eax,8 + stosb + inc edi + ror eax,16 + stosb + loop _T8Lp2 +_T8C2: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _T8C3 + add esi,32 + add edi,32 + jmp _T8C4 +_T8C3: mov ecx,8 +_T8Lp3: lodsd + stosb + inc edi + ror eax,16 + stosb + inc edi + loop _T8Lp3 +_T8C4: sub edi,NBUFFW32 + dec edx + jnz _T8Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type9: mov eax,edi + and eax,1 + mov dword ptr [sgLineVal],eax + mov ecx,32 + +_T9Lp1: push ecx + mov edx,32 + +_T9Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T9J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _T9C1 + add esi,eax + add edi,eax + jmp _T9x +_T9C1: mov ecx,eax + mov eax,edi + and eax,1 + cmp eax,dword ptr [sgLineVal] + jnz _T9Od + shr ecx,1 + jnc _T9w + inc esi + inc edi + jecxz _T9x + jmp _T9w2 +_T9w: shr ecx,1 + jnc _T9Lp3 + inc esi + inc edi + movsb + jecxz _T9x +_T9Lp3: lodsd + inc edi + ror eax,8 + stosb + inc edi + ror eax,16 + stosb + loop _T9Lp3 + jmp _T9x + +_T9Od: shr ecx,1 + jnc _T9w2 + movsb + jecxz _T9x + jmp _T9w +_T9w2: shr ecx,1 + jnc _T9Lp4 + movsb + inc esi + inc edi + jecxz _T9x +_T9Lp4: lodsd + stosb + inc edi + ror eax,16 + stosb + inc edi + loop _T9Lp4 + +_T9x: or edx,edx + jz _T9Nxt + jmp _T9Lp2 + +_T9J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T9Lp2 +_T9Nxt: pop ecx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + sub edi,NBUFFW32 + dec ecx + jnz _T9Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeA: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TALp1: cmp edi,dword ptr [ClipY] + jb _TAC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TAx +_TAC1: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TAOd + shr ecx,2 + jnc _TALp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TAx +_TALp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TALp2 + jmp _TAx + +_TAOd: shr ecx,2 + jnc _TALp3 + lodsw + stosb + inc edi + jecxz _TAx +_TALp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TALp3 + +_TAx: sub edi,NBUFFW32 + or edx,edx + jz _TAb + sub edx,2 + jmp _TALp1 + +_TAb: mov edx,2 +_TALp4: cmp edi,dword ptr [ClipY] + jb _TAC2 + add esi,32 + sub esi,edx + add edi,32 + jmp _TAx2 +_TAC2: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TAOd2 + shr ecx,2 + jnc _TALp5 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TAx2 +_TALp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TALp5 + jmp _TAx2 + +_TAOd2: shr ecx,2 + jnc _TALp6 + lodsw + stosb + inc edi + jecxz _TAx2 +_TALp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TALp6 + +_TAx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TALp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeB: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TBLp1: cmp edi,dword ptr [ClipY] + jb _TBC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TBx +_TBC1: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TBOd + shr ecx,2 + jnc _TBLp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TBx +_TBLp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TBLp2 + jmp _TBx + +_TBOd: shr ecx,2 + jnc _TBLp3 + lodsw + stosb + inc edi + jecxz _TBx +_TBLp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TBLp3 + +_TBx: sub edi,NBUFFW32 + or edx,edx + jz _TBb + add edi,edx + sub edx,2 + jmp _TBLp1 + +_TBb: mov edx,2 +_TBLp4: cmp edi,dword ptr [ClipY] + jb _TBC2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TBx2 +_TBC2: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TBOd2 + shr ecx,2 + jnc _TBLp5 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TBx2 +_TBLp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TBLp5 + jmp _TBx2 + +_TBOd2: shr ecx,2 + jnc _TBLp6 + lodsw + stosb + inc edi + jecxz _TBx2 +_TBLp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TBLp6 + +_TBx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TBLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeC: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TCLp1: cmp edi,dword ptr [ClipY] + jb _TCC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TCx +_TCC1: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TCOd + shr ecx,2 + jnc _TCLp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TCx +_TCLp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TCLp2 + jmp _TCx + +_TCOd: shr ecx,2 + jnc _TCLp3 + lodsw + stosb + inc edi + jecxz _TCx +_TCLp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TCLp3 + +_TCx: sub edi,NBUFFW32 + or edx,edx + jz _TCb + sub edx,2 + jmp _TCLp1 + +_TCb: mov edx,8 +_TCLp4: cmp edi,dword ptr [ClipY] + jb _TCC2 + add esi,32 + add edi,32 + jmp _TCC3 +_TCC2: mov ecx,8 +_TCLp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TCLp5 +_TCC3: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _TCC4 + add esi,32 + add edi,32 + jmp _TCC5 +_TCC4: mov ecx,8 +_TCLp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TCLp6 +_TCC5: sub edi,NBUFFW32 + dec edx + jnz _TCLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeD: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TDLp1: cmp edi,dword ptr [ClipY] + jb _TDC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TDx +_TDC1: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TDOd + shr ecx,2 + jnc _TDLp2 + lodsw + inc edi + ror eax,8 + stosb + jecxz _TDx +_TDLp2: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TDLp2 + jmp _TDx + +_TDOd: shr ecx,2 + jnc _TDLp3 + lodsw + stosb + inc edi + jecxz _TDx +_TDLp3: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TDLp3 + +_TDx: sub edi,NBUFFW32 + or edx,edx + jz _TDb + add edi,edx + sub edx,2 + jmp _TDLp1 + +_TDb: mov edx,8 +_TDLp4: cmp edi,dword ptr [ClipY] + jb _TDC2 + add esi,32 + add edi,32 + jmp _TDC3 +_TDC2: mov ecx,8 +_TDLp5: lodsd + inc edi + ror eax,8 + stosb + ror eax,16 + inc edi + stosb + loop _TDLp5 +_TDC3: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _TDC4 + add esi,32 + add edi,32 + jmp _TDC5 +_TDC4: mov ecx,8 +_TDLp6: lodsd + stosb + ror eax,16 + inc edi + stosb + inc edi + loop _TDLp6 +_TDC5: sub edi,NBUFFW32 + dec edx + jnz _TDLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeG: mov edx,16 + xor eax,eax +_TGLp1: cmp edi,dword ptr [ClipY] + jb _TGC1 + add esi,32 + add edi,32 + jmp _TGC2 +_TGC1: mov ecx,8 +_TGLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TGLp2 +_TGC2: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _TGC3 + add esi,32 + add edi,32 + jmp _TGC4 +_TGC3: mov ecx,8 +_TGLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TGLp3 +_TGC4: sub edi,NBUFFW32 + dec edx + jnz _TGLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeH: mov eax,edi + and eax,1 + mov dword ptr [sgLineVal],eax + mov ecx,32 + +_THLp1: push ecx + mov edx,32 + +_THLp2: xor eax,eax // Load control byte + lodsb + or al,al + js _THJ + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _THC1 + add esi,eax + add edi,eax + jmp _THx +_THC1: mov ecx,eax + add esi,ecx + mov eax,edi + and eax,1 + cmp eax,dword ptr [sgLineVal] + jnz _THOd + xor eax,eax + shr ecx,1 + jnc _THw + inc edi + jecxz _THx + jmp _THw2 +_THw: shr ecx,1 + jnc _THLp3 + inc edi + stosb + jecxz _THx +_THLp3: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _THLp3 + jmp _THx + +_THOd: xor eax,eax + shr ecx,1 + jnc _THw2 + stosb + jecxz _THx + jmp _THw +_THw2: shr ecx,1 + jnc _THLp4 + stosb + inc edi + jecxz _THx +_THLp4: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _THLp4 + +_THx: or edx,edx + jz _THNxt + jmp _THLp2 + +_THJ: neg al // Do jump + add edi,eax + sub edx,eax + jnz _THLp2 +_THNxt: pop ecx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + sub edi,NBUFFW32 + dec ecx + jnz _THLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeI: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TILp1: cmp edi,dword ptr [ClipY] + jb _TIC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TIx +_TIC1: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TIOd + xor eax,eax + shr ecx,2 + jnc _TILp2 + inc edi + stosb + jecxz _TIx +_TILp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TILp2 + jmp _TIx + +_TIOd: xor eax,eax + shr ecx,2 + jnc _TILp3 + stosb + inc edi + jecxz _TIx +_TILp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TILp3 + +_TIx: sub edi,NBUFFW32 + or edx,edx + jz _TIb + sub edx,2 + jmp _TILp1 + +_TIb: mov edx,2 +_TILp4: cmp edi,dword ptr [ClipY] + jb _TIC2 + add esi,32 + sub esi,edx + add edi,32 + jmp _TIx2 +_TIC2: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TIOd2 + xor eax,eax + shr ecx,2 + jnc _TILp5 + inc edi + stosb + jecxz _TIx2 +_TILp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TILp5 + jmp _TIx2 + +_TIOd2: xor eax,eax + shr ecx,2 + jnc _TILp6 + stosb + inc edi + jecxz _TIx2 +_TILp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TILp6 + +_TIx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TILp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeJ: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TJLp1: cmp edi,dword ptr [ClipY] + jb _TJC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TJx +_TJC1: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TJOd + xor eax,eax + shr ecx,2 + jnc _TJLp2 + inc edi + stosb + jecxz _TJx +_TJLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TJLp2 + jmp _TJx + +_TJOd: xor eax,eax + shr ecx,2 + jnc _TJLp3 + stosb + inc edi + jecxz _TJx +_TJLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TJLp3 + +_TJx: sub edi,NBUFFW32 + or edx,edx + jz _TJb + add edi,edx + sub edx,2 + jmp _TJLp1 + +_TJb: mov edx,2 +_TJLp4: cmp edi,dword ptr [ClipY] + jb _TJC2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TJx2 +_TJC2: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TJOd2 + xor eax,eax + shr ecx,2 + jnc _TJLp5 + inc edi + stosb + jecxz _TJx2 +_TJLp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TJLp5 + jmp _TJx2 + +_TJOd2: xor eax,eax + shr ecx,2 + jnc _TJLp6 + stosb + inc edi + jecxz _TJx2 +_TJLp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TJLp6 + +_TJx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TJLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeK: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TKLp1: cmp edi,dword ptr [ClipY] + jb _TKC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TKx +_TKC1: add edi,edx + mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TKOd + xor eax,eax + shr ecx,2 + jnc _TKLp2 + inc edi + stosb + jecxz _TKx +_TKLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TKLp2 + jmp _TKx + +_TKOd: xor eax,eax + shr ecx,2 + jnc _TKLp3 + stosb + inc edi + jecxz _TKx +_TKLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TKLp3 + +_TKx: sub edi,NBUFFW32 + or edx,edx + jz _TKb + sub edx,2 + jmp _TKLp1 + +_TKb: mov edx,8 +_TKLp4: cmp edi,dword ptr [ClipY] + jb _TKC2 + add esi,32 + add edi,32 + jmp _TKC3 +_TKC2: mov ecx,8 + xor eax,eax +_TKLp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TKLp5 +_TKC3: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _TKC4 + add esi,32 + add edi,32 + jmp _TKC5 +_TKC4: mov ecx,8 + xor eax,eax +_TKLp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TKLp6 +_TKC5: sub edi,NBUFFW32 + dec edx + jnz _TKLp4 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeL: xor eax,eax + mov dword ptr [sgLineVal],eax + mov edx,30 +_TLLp1: cmp edi,dword ptr [ClipY] + jb _TLC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TLx +_TLC1: mov ecx,32 + sub ecx,edx + mov eax,dword ptr [sgLineVal] + inc eax + and eax,1 + mov dword ptr [sgLineVal],eax + jz _TLOd + xor eax,eax + shr ecx,2 + jnc _TLLp2 + inc edi + stosb + jecxz _TLx +_TLLp2: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TLLp2 + jmp _TLx + +_TLOd: xor eax,eax + shr ecx,2 + jnc _TLLp3 + stosb + inc edi + jecxz _TLx +_TLLp3: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TLLp3 + +_TLx: sub edi,NBUFFW32 + or edx,edx + jz _TLb + add edi,edx + sub edx,2 + jmp _TLLp1 + +_TLb: mov edx,8 +_TLLp4: cmp edi,dword ptr [ClipY] + jb _TLC2 + add esi,32 + add edi,32 + jmp _TLC3 +_TLC2: mov ecx,8 + xor eax,eax +_TLLp5: mov byte ptr [edi+1],al + mov byte ptr [edi+3],al + add edi,4 + loop _TLLp5 +_TLC3: sub edi,NBUFFW32 + + cmp edi,dword ptr [ClipY] + jb _TLC4 + add esi,32 + add edi,32 + jmp _TLC5 +_TLC4: mov ecx,8 + xor eax,eax +_TLLp6: mov byte ptr [edi],al + mov byte ptr [edi+2],al + add edi,4 + loop _TLLp6 +_TLC5: sub edi,NBUFFW32 + dec edx + jnz _TLLp4 + jmp _Done + +xbyte1: // blank first + + shr ecx,1 + jnc xword2 + inc esi + inc edi + +xword1: // xlat first + shr ecx,1 + jnc xquadt1 + mov dl,[esi] + mov dl,[ebx+edx] + add esi,2 + mov [edi],dl + add edi,2 + +xquadt1: + test cl,cl + jz xend + +xquad1: // xlat first +/* debug + shl ecx,2 + add esi,ecx + add edi,ecx + ret +*/ + + mov eax,[esi] + add esi,4 + mov dl,al + shr eax,16 + mov dl,[ebx+edx] + mov [edi],dl + mov dl,al + add edi,4 + mov dl,[ebx+edx] + dec ecx + mov [edi-2],dl + jnz xquad1 + + ret + + +xbyte2: // xlat first + + shr ecx,1 + jnc xword1 + mov dl,[esi] + mov dl,[ebx+edx] + inc esi + mov [edi],dl + inc edi + +xword2: // blank first + shr ecx,1 + jnc xquadt2 + mov dl,[esi+1] + mov dl,[ebx+edx] + add esi,2 + mov [edi+1],dl + add edi,2 + +xquadt2: + test cl,cl + jz xend + +xquad2: // blank first +/* debug + shl ecx,2 + add esi,ecx + add edi,ecx + ret +*/ + + + mov eax,[esi] + add esi,4 + mov dl,ah + shr eax,16 + mov dl,[ebx+edx] + mov [edi+1],dl + mov dl,ah + add edi,4 + mov dl,[ebx+edx] + dec ecx + mov [edi-1],dl + jnz xquad2 + +xend: + ret + +_Done: nop + + } // end of asm block +} + +/*-----------------------------------------------------------------------** +** Now with Y clipping and Masking Transparency +**-----------------------------------------------------------------------*/ + +void TCDecodeM12Tile (BYTE *pDecodeTo, long *mask) +{ + t = µoffset[0][0]; + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,dword ptr [nLVal] + or al,al + jz _NoLt + cmp al,byte ptr [lightmax] + jz _Black + + mov eax,dword ptr [gdwPNum] + and eax,08000h + jnz _Speed + + mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov ebx,dword ptr [nLVal]; // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl]; + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh + jz _Type0 // Solid 32x32 block + cmp ax,1 + jz _Type1 // 32x32 block with '0' holes + cmp ax,2 + jz _Type2 // Left Triangle + cmp ax,3 + jz _Type3 // Right Triangle + cmp ax,4 + jz _Type4 // Left Triangle to wall + jmp _Type5 // Right Triangle to wall + +_Speed: mov esi,dword ptr [t] + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,4 + add eax,dword ptr [nLVal] + shl eax,2 + add esi,eax // Source + mov eax,dword ptr [esi] + mov esi,dword ptr [pSpeedCels] + add esi,eax + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh +_SCmp: cmp ax,8 + jz _Type8 // PreTrans Solid 32x32 block + cmp ax,9 + jz _Type9 // PreTrans 32x32 block with '0' holes + cmp ax,10 + jz _TypeA // PreTrans Left Triangle + cmp ax,11 + jz _TypeB // PreTrans Right Triangle + cmp ax,12 + jz _TypeC // PreTrans Left Triangle to wall + jmp _TypeD // PreTrans Right Triangle to wall + +_NoLt: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RNoLt + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RNoLt: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + add eax,8 + jmp _SCmp + +_Black: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RBlk + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RBlk: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + jz _TypeG // Black Trans Solid 32x32 block + cmp ax,1 + jz _TypeH // Black Trans 32x32 block with '0' holes + cmp ax,2 + jz _TypeI // Black Trans Left Triangle + cmp ax,3 + jz _TypeJ // Black Trans Right Triangle + cmp ax,4 + jz _TypeK // Black Trans Left Triangle to wall + jmp _TypeL // Black Trans Right Triangle to wall + +/*-----------------------------------------------------------------------*/ + +_Type0: mov edx,32 +_T0Lp1: cmp edi,dword ptr [ClipY] + jb _T0C1 + add esi,32 + add edi,32 + jmp _T0C2 +_T0C1: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T0Lp2: lodsb + shl edx,1 + jnc _T0S1 + xlatb + mov byte ptr [edi],al +_T0S1: inc edi + loop _T0Lp2 + pop edx +_T0C2: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T0Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type1: mov ecx,32 + +_T1Lp1: push ecx + mov eax,dword ptr [mask] + mov eax,dword ptr [eax] + mov dword ptr [cm],eax + + mov edx,32 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: mov ecx,eax + push edx + mov edx,dword ptr [cm] +_T1Lp3: lodsb + shl edx,1 + jnc _T1S1 + xlatb + mov byte ptr [edi],al +_T1S1: inc edi + loop _T1Lp3 + mov dword ptr [cm],edx + pop edx +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + mov ecx,eax + and ecx,01fh + jz _T1S2 + push eax + mov eax,dword ptr [cm] + shl eax,cl + mov dword ptr [cm],eax + pop eax +_T1S2: sub edx,eax + jnz _T1Lp2 +_T1Nxt: pop ecx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec ecx + jnz _T1Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type2: mov edx,30 +_T2Lp1: cmp edi,dword ptr [ClipY] + jb _T2C1 + add esi,32 + sub esi,edx + add edi,32 + jmp _T2x +_T2C1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T2Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T2x +_T2Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T2Lp2 +_T2x: sub edi,NBUFFW32 + or edx,edx + jz _T2b + sub edx,2 + jmp _T2Lp1 + +_T2b: mov edx,2 +_T2Lp3: cmp edi,dword ptr [ClipY] + jb _T2C2 + add esi,32 + sub esi,edx + add edi,32 + jmp _T2x2 +_T2C2: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T2Lp4 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T2x2 +_T2Lp4: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T2Lp4 +_T2x2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _T2Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type3: mov edx,30 +_T3Lp1: cmp edi,dword ptr [ClipY] + jb _T3C1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T3x +_T3C1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T3Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T3x +_T3Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T3Lp2 +_T3x: sub edi,NBUFFW32 + or edx,edx + jz _T3b + add edi,edx + sub edx,2 + jmp _T3Lp1 + +_T3b: mov edx,2 +_T3Lp3: cmp edi,dword ptr [ClipY] + jb _T3C2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T3x2 +_T3C2: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T3Lp4 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T3x2 +_T3Lp4: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T3Lp4 +_T3x2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _T3Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type4: mov edx,30 +_T4Lp1: cmp edi,dword ptr [ClipY] + jb _T4C1 + add esi,32 + sub esi,edx + add edi,32 + jmp _T4x +_T4C1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T4Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T4x +_T4Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T4Lp2 +_T4x: sub edi,NBUFFW32 + or edx,edx + jz _T4b + sub edx,2 + jmp _T4Lp1 + +_T4b: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_T4Lp3: cmp edi,dword ptr [ClipY] + jb _T4C2 + add esi,32 + add edi,32 + jmp _T4C3 +_T4C2: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T4Lp4: lodsb + shl edx,1 + jnc _T4S1 + xlatb + mov byte ptr [edi],al +_T4S1: inc edi + loop _T4Lp4 + pop edx +_T4C3: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T4Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type5: mov edx,30 +_T5Lp1: cmp edi,dword ptr [ClipY] + jb _T5C1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T5x +_T5C1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _T5Lp2 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T5x +_T5Lp2: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T5Lp2 +_T5x: sub edi,NBUFFW32 + or edx,edx + jz _T5b + add edi,edx + sub edx,2 + jmp _T5Lp1 + +_T5b: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_T5Lp3: cmp edi,dword ptr [ClipY] + jb _T5C2 + add esi,32 + add edi,32 + jmp _T5C3 +_T5C2: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T5Lp4: lodsb + shl edx,1 + jnc _T5S1 + xlatb + mov byte ptr [edi],al +_T5S1: inc edi + loop _T5Lp4 + pop edx +_T5C3: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T5Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type8: mov edx,32 +_T8Lp1: cmp edi,dword ptr [ClipY] + jb _T8C1 + add esi,32 + add edi,32 + jmp _T8C2 +_T8C1: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_T8Lp2: lodsb + shl edx,1 + jnc _T8S1 + mov byte ptr [edi],al +_T8S1: inc edi + loop _T8Lp2 + pop edx +_T8C2: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _T8Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type9: mov ecx,32 + +_T9Lp1: push ecx + mov eax,dword ptr [mask] + mov eax,dword ptr [eax] + mov dword ptr [cm],eax + + mov edx,32 + +_T9Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T9J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _T9C1 + add esi,eax + add edi,eax + jmp _T9x +_T9C1: mov ecx,eax + push edx + mov edx,dword ptr [cm] +_T9Lp3: lodsb + shl edx,1 + jnc _T9S1 + mov byte ptr [edi],al +_T9S1: inc edi + loop _T9Lp3 + mov dword ptr [cm],edx + pop edx +_T9x: or edx,edx + jz _T9Nxt + jmp _T9Lp2 + +_T9J: neg al // Do jump + add edi,eax + mov ecx,eax + and ecx,01fh + jz _T9S2 + mov ebx,dword ptr [cm] + shl ebx,cl + mov dword ptr [cm],ebx +_T9S2: sub edx,eax + jnz _T9Lp2 +_T9Nxt: pop ecx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec ecx + jnz _T9Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeA: mov edx,30 +_TALp1: cmp edi,dword ptr [ClipY] + jb _TAC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TAx +_TAC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp2 + movsw + jecxz _TAx +_TALp2: rep movsd +_TAx: sub edi,NBUFFW32 + or edx,edx + jz _TAb + sub edx,2 + jmp _TALp1 + +_TAb: mov edx,2 +_TALp3: cmp edi,dword ptr [ClipY] + jb _TAC2 + add esi,32 + sub esi,edx + add edi,32 + jmp _TAx2 +_TAC2: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp4 + movsw + jecxz _TAx2 +_TALp4: rep movsd +_TAx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TALp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeB: mov edx,30 +_TBLp1: cmp edi,dword ptr [ClipY] + jb _TBC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TBx +_TBC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp2 + movsw + jecxz _TBx +_TBLp2: rep movsd +_TBx: sub edi,NBUFFW32 + or edx,edx + jz _TBb + add edi,edx + sub edx,2 + jmp _TBLp1 + +_TBb: mov edx,2 +_TBLp3: cmp edi,dword ptr [ClipY] + jb _TBC2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TBx2 +_TBC2: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp4 + movsw + jecxz _TBx2 +_TBLp4: rep movsd +_TBx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TBLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeC: mov edx,30 +_TCLp1: cmp edi,dword ptr [ClipY] + jb _TCC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TCx +_TCC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TCLp2 + movsw + jecxz _TCx +_TCLp2: rep movsd +_TCx: sub edi,NBUFFW32 + or edx,edx + jz _TCb + sub edx,2 + jmp _TCLp1 + +_TCb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TCLp3: cmp edi,dword ptr [ClipY] + jb _TCC2 + add esi,32 + add edi,32 + jmp _TCC3 +_TCC2: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_TCLp4: lodsb + shl edx,1 + jnc _TCS1 + mov byte ptr [edi],al +_TCS1: inc edi + loop _TCLp4 + pop edx +_TCC3: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TCLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeD: mov edx,30 +_TDLp1: cmp edi,dword ptr [ClipY] + jb _TDC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TDx +_TDC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TDLp2 + movsw + jecxz _TDx +_TDLp2: rep movsd +_TDx: sub edi,NBUFFW32 + or edx,edx + jz _TDb + add edi,edx + sub edx,2 + jmp _TDLp1 + +_TDb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TDLp3: cmp edi,dword ptr [ClipY] + jb _TDC2 + add esi,32 + add edi,32 + jmp _TDC3 +_TDC2: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + mov ecx,32 +_TDLp4: lodsb + shl edx,1 + jnc _TDS1 + mov byte ptr [edi],al +_TDS1: inc edi + loop _TDLp4 + pop edx +_TDC3: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TDLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeG: mov edx,32 +_TGLp1: cmp edi,dword ptr [ClipY] + jb _TGC1 + add esi,32 + add edi,32 + jmp _TGC2 +_TGC1: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + xor eax,eax + mov ecx,32 +_TGLp2: shl edx,1 + jnc _TGS1 + mov byte ptr [edi],al +_TGS1: inc edi + loop _TGLp2 + pop edx +_TGC2: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TGLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeH: mov ecx,32 + +_THLp1: push ecx + mov eax,dword ptr [mask] + mov eax,dword ptr [eax] + mov dword ptr [cm],eax + + mov edx,32 + +_THLp2: xor eax,eax // Load control byte + lodsb + or al,al + js _THJ + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _THC1 + add esi,eax + add edi,eax + jmp _THx +_THC1: mov ecx,eax + add esi,ecx + push edx + mov edx,dword ptr [cm] + xor eax,eax +_THLp3: shl edx,1 + jnc _THS1 + mov byte ptr [edi],al +_THS1: inc edi + loop _THLp3 + mov dword ptr [cm],edx + pop edx +_THx: or edx,edx + jz _THNxt + jmp _THLp2 + +_THJ: neg al // Do jump + add edi,eax + mov ecx,eax + and ecx,01fh + jz _THS2 + mov ebx,dword ptr [cm] + shl ebx,cl + mov dword ptr [cm],ebx +_THS2: sub edx,eax + jnz _THLp2 +_THNxt: pop ecx + sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec ecx + jnz _THLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeI: mov edx,30 + xor eax,eax +_TILp1: cmp edi,dword ptr [ClipY] + jb _TIC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TIx +_TIC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TILp2 + stosw + jecxz _TIx +_TILp2: rep stosd +_TIx: sub edi,NBUFFW32 + or edx,edx + jz _TIb + sub edx,2 + jmp _TILp1 + +_TIb: mov edx,2 +_TILp3: cmp edi,dword ptr [ClipY] + jb _TIC2 + add esi,32 + sub esi,edx + add edi,32 + jmp _TIx2 +_TIC2: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TILp4 + stosw + jecxz _TIx2 +_TILp4: rep stosd +_TIx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TILp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeJ: mov edx,30 + xor eax,eax +_TJLp1: cmp edi,dword ptr [ClipY] + jb _TJC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TJx +_TJC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp2 + stosw + jecxz _TJx +_TJLp2: rep stosd +_TJx: sub edi,NBUFFW32 + or edx,edx + jz _TJb + add edi,edx + sub edx,2 + jmp _TJLp1 + +_TJb: mov edx,2 +_TJLp3: cmp edi,dword ptr [ClipY] + jb _TJC2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TJx2 +_TJC2: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp4 + stosw + jecxz _TJx2 +_TJLp4: rep stosd +_TJx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TJLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeK: mov edx,30 + xor eax,eax +_TKLp1: cmp edi,dword ptr [ClipY] + jb _TKC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TKx +_TKC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TKLp2 + stosw + jecxz _TKx +_TKLp2: rep stosd +_TKx: sub edi,NBUFFW32 + or edx,edx + jz _TKb + sub edx,2 + jmp _TKLp1 + +_TKb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TKLp3: cmp edi,dword ptr [ClipY] + jb _TKC2 + add esi,32 + add edi,32 + jmp _TKC3 +_TKC2: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + xor eax,eax + mov ecx,32 +_TKLp4: shl edx,1 + jnc _TKS1 + mov byte ptr [edi],al +_TKS1: inc edi + loop _TKLp4 + pop edx +_TKC3: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TKLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeL: mov edx,30 + xor eax,eax +_TLLp1: cmp edi,dword ptr [ClipY] + jb _TLC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TLx +_TLC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TLLp2 + stosw + jecxz _TLx +_TLLp2: rep stosd +_TLx: sub edi,NBUFFW32 + or edx,edx + jz _TLb + add edi,edx + sub edx,2 + jmp _TLLp1 + +_TLb: mov eax,dword ptr [mask] + sub eax,64 + mov dword ptr [mask],eax + mov edx,16 +_TLLp3: cmp edi,dword ptr [ClipY] + jb _TLC2 + add esi,32 + add edi,32 + jmp _TLC3 +_TLC2: push edx + mov eax,dword ptr [mask] + mov edx,dword ptr [eax] + xor eax,eax + mov ecx,32 +_TLLp4: shl edx,1 + jnc _TLS1 + mov byte ptr [edi],al +_TLS1: inc edi + loop _TLLp4 + pop edx +_TLC3: sub edi,NBUFFW32 + mov eax,dword ptr [mask] + sub eax,4 + mov dword ptr [mask],eax + dec edx + jnz _TLLp3 + +_Done: nop + + } // end of asm block +} + + +/*-----------------------------------------------------------------------** +** Now with Y clipping +**-----------------------------------------------------------------------*/ + +void CDecodeMicroTile (BYTE *pDecodeTo) +{ + if (nTrans) { + switch (gbPartialTrans) { + case PART_TRANS_NONE: + TCDecodeMicroTile(pDecodeTo); + return; + case PART_TRANS_LEFT: + wt = nWTypeTable[gnPieceNum]; + if ((wt == WTYPE_LEFT) || (wt == WTYPE_ULC)) { + TCDecodeM12Tile(pDecodeTo, &sgLeftMask[31]); + return; + } + if (wt == WTYPE_LRC) { + TCDecodeM12Tile(pDecodeTo, &sgRightMask[31]); + return; + } + break; + case PART_TRANS_RIGHT: + wt = nWTypeTable[gnPieceNum]; + if ((wt == WTYPE_RIGHT) || (wt == WTYPE_ULC)) { + TCDecodeM12Tile(pDecodeTo, &sgRightMask[31]); + return; + } + if (wt == WTYPE_LRC) { + TCDecodeM12Tile(pDecodeTo, &sgLeftMask[31]); + return; + } + } + } + t = µoffset[0][0]; + __asm { + + mov edi,dword ptr [pDecodeTo] // Dest + + mov eax,dword ptr [nLVal] + or al,al + jz _NoLt + cmp al,byte ptr [lightmax] + jz _Black + + mov eax,dword ptr [gdwPNum] + and eax,08000h + jnz _Speed + + mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov ebx,dword ptr [nLVal]; // Light conversion table + shl ebx,8 + add ebx,dword ptr [pLightTbl]; + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh + jz _Type0 // Solid 32x32 block + cmp ax,1 + jz _Type1 // 32x32 block with '0' holes + cmp ax,2 + jz _Type2 // Left Triangle + cmp ax,3 + jz _Type3 // Right Triangle + cmp ax,4 + jz _Type4 // Left Triangle to wall + jmp _Type5 // Right Triangle to wall + +_Speed: mov esi,dword ptr [t] + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,4 + add eax,dword ptr [nLVal] + shl eax,2 + add esi,eax // Source + mov eax,dword ptr [esi] + mov esi,dword ptr [pSpeedCels] + add esi,eax + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,0fh +_SCmp: cmp ax,8 + jz _Type8 // PreTrans Solid 32x32 block + cmp ax,9 + jz _Type9 // PreTrans 32x32 block with '0' holes + cmp ax,10 + jz _TypeA // PreTrans Left Triangle + cmp ax,11 + jz _TypeB // PreTrans Right Triangle + cmp ax,12 + jz _TypeC // PreTrans Left Triangle to wall + jmp _TypeD // PreTrans Right Triangle to wall + +_NoLt: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RNoLt + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RNoLt: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + add eax,8 + jmp _SCmp + +_Black: mov eax,dword ptr [gdwPNum] + and eax,08000h + jz _RBlk + + mov esi,dword ptr [t] // Get old micro tile number + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,6 + add esi,eax + mov eax,dword ptr [gdwPNum] + and eax,0f000h + add eax,dword ptr [esi] + mov dword ptr [gdwPNum],eax + +_RBlk: mov ebx,dword ptr [pDungeonCels] + mov esi,ebx + mov eax,dword ptr [gdwPNum] + and eax,00fffh + shl eax,2 + add ebx,eax + add esi,dword ptr [ebx] // Source + + mov eax,dword ptr [gdwPNum] // Determine draw type + mov al,ah + shr eax,4 + and eax,07h + jz _TypeG // Black Trans Solid 32x32 block + cmp ax,1 + jz _TypeH // Black Trans 32x32 block with '0' holes + cmp ax,2 + jz _TypeI // Black Trans Left Triangle + cmp ax,3 + jz _TypeJ // Black Trans Right Triangle + cmp ax,4 + jz _TypeK // Black Trans Left Triangle to wall + jmp _TypeL // Black Trans Right Triangle to wall + +/*-----------------------------------------------------------------------*/ + +_Type0: mov edx,32 + push ebp +_T0Lp1: + push edx + cmp edi,dword ptr [ClipY] + jb _T0C1 + add esi,32 + add edi,32 + jmp _T0C2 +_T0C1: + xor edx,edx + mov ebp,8 +_T0Lp2: + mov eax,[esi] + add esi,4 + ror eax,16 + mov dl,al + mov cl,[ebx+edx] + mov dl,ah + mov ch,[ebx+edx] + ror eax,16 + shl ecx,16 + mov dl,al + mov cl,[ebx+edx] + mov dl,ah + mov ch,[ebx+edx] + mov [edi],ecx + add edi,4 + + dec ebp + jnz _T0Lp2 +_T0C2: + sub edi,NBUFFW32 + pop edx + dec edx + jnz _T0Lp1 + pop ebp + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type1: push ebp + mov ecx,32 +_T1Lp1: push ecx + mov ebp,32 +_T1Lp2: + xor eax,eax // Load control byte + mov al,[esi] + inc esi + + or al,al + jns _T1NoSkip + neg al + add edi,eax + sub ebp,eax + jmp _T1continue +_T1NoSkip: + sub ebp,eax + cmp edi,dword ptr [ClipY] + jb _T1NotCliped + add esi,eax + add edi,eax + jmp _T1continue +_T1NotCliped: + mov ecx,eax + call xbytes +_T1continue: + or ebp,ebp + jnz _T1Lp2 + + pop ecx + sub edi,NBUFFW32 + dec ecx + jnz _T1Lp1 + pop ebp + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type2: + push ebp + mov ebp,30 +_T2Lp1: + cmp edi,dword ptr [ClipY] + jb _T2NotClipped + add esi,32 + add edi,32 + sub esi,ebp + jmp _T2continue +_T2NotClipped: + add edi,ebp + mov ecx,32 + sub ecx,ebp + call xbytes +_T2continue: + sub edi,NBUFFW32 + sub ebp,2 + jge _T2Lp1 + + + mov ebp,2 +_T2Lp2: + cmp edi,dword ptr [ClipY] + jb _T2NotClipped2 + add esi,32 + add edi,32 + sub esi,ebp + jmp _T2continue2 +_T2NotClipped2: + add edi,ebp + mov ecx,32 + sub ecx,ebp + call xbytes +_T2continue2: + add ebp,2 + sub edi,NBUFFW32 + cmp ebp,32 + jnz _T2Lp2 + + pop ebp + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type3: mov edx,30 +_T3Lp1: cmp edi,dword ptr [ClipY] + jb _T3C1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T3x +_T3C1: mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + +_T3x: sub edi,NBUFFW32 + or edx,edx + jz _T3b + add edi,edx + sub edx,2 + jmp _T3Lp1 + +_T3b: mov edx,2 +_T3Lp3: cmp edi,dword ptr [ClipY] + jb _T3C2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T3x2 +_T3C2: mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + +_T3x2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _T3Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type4: mov edx,30 +_T4Lp1: cmp edi,dword ptr [ClipY] + jb _T4C1 + add esi,32 + sub esi,edx + add edi,32 + jmp _T4x +_T4C1: add edi,edx + mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + +_T4x: sub edi,NBUFFW32 + or edx,edx + jz _T4b + sub edx,2 + jmp _T4Lp1 + +_T4b: mov edx,16 +_T4Lp3: cmp edi,dword ptr [ClipY] + jb _T4C2 + add esi,32 + add edi,32 + jmp _T4C3 +_T4C2: mov ecx,8 + + push edx + call xquads + pop edx + +_T4C3: sub edi,NBUFFW32 + dec edx + jnz _T4Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type5: mov edx,30 +_T5Lp1: cmp edi,dword ptr [ClipY] + jb _T5C1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _T5x +_T5C1: mov ecx,32 + sub ecx,edx + + push edx + call xbytes + pop edx + +_T5x: sub edi,NBUFFW32 + or edx,edx + jz _T5b + add edi,edx + sub edx,2 + jmp _T5Lp1 + +_T5b: mov edx,16 +_T5Lp3: cmp edi,dword ptr [ClipY] + jb _T5C2 + add esi,32 + add edi,32 + jmp _T5C3 +_T5C2: mov ecx,8 + + push edx + call xquads + pop edx + +_T5C3: sub edi,NBUFFW32 + dec edx + jnz _T5Lp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type8: mov edx,32 +_T8Lp1: cmp edi,dword ptr [ClipY] + jb _T8C1 + add esi,32 + add edi,32 + jmp _T8C2 +_T8C1: mov ecx,8 + rep movsd +_T8C2: sub edi,NBUFFW32 + dec edx + jnz _T8Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_Type9: mov ecx,32 + +_T9Lp1: push ecx + mov edx,32 + +_T9Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T9J + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _T9C1 + add esi,eax + add edi,eax + jmp _T9x +_T9C1: mov ecx,eax + shr ecx,1 + jnc _T9w + movsb + jecxz _T9x +_T9w: shr ecx,1 + jnc _T9Lp3 + movsw + jecxz _T9x +_T9Lp3: rep movsd +_T9x: or edx,edx + jz _T9Nxt + jmp _T9Lp2 + +_T9J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T9Lp2 +_T9Nxt: pop ecx + sub edi,NBUFFW32 + loop _T9Lp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeA: mov edx,30 +_TALp1: cmp edi,dword ptr [ClipY] + jb _TAC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TAx +_TAC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp2 + movsw + jecxz _TAx +_TALp2: rep movsd +_TAx: sub edi,NBUFFW32 + or edx,edx + jz _TAb + sub edx,2 + jmp _TALp1 + +_TAb: mov edx,2 +_TALp3: cmp edi,dword ptr [ClipY] + jb _TAC2 + add esi,32 + sub esi,edx + add edi,32 + jmp _TAx2 +_TAC2: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TALp4 + movsw + jecxz _TAx2 +_TALp4: rep movsd +_TAx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TALp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeB: mov edx,30 +_TBLp1: cmp edi,dword ptr [ClipY] + jb _TBC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TBx +_TBC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp2 + movsw + jecxz _TBx +_TBLp2: rep movsd +_TBx: sub edi,NBUFFW32 + or edx,edx + jz _TBb + add edi,edx + sub edx,2 + jmp _TBLp1 + +_TBb: mov edx,2 +_TBLp3: cmp edi,dword ptr [ClipY] + jb _TBC2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TBx2 +_TBC2: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TBLp4 + movsw + jecxz _TBx2 +_TBLp4: rep movsd +_TBx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TBLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeC: mov edx,30 +_TCLp1: cmp edi,dword ptr [ClipY] + jb _TCC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TCx +_TCC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TCLp2 + movsw + jecxz _TCx +_TCLp2: rep movsd +_TCx: sub edi,NBUFFW32 + or edx,edx + jz _TCb + sub edx,2 + jmp _TCLp1 + +_TCb: mov edx,16 +_TCLp3: cmp edi,dword ptr [ClipY] + jb _TCC2 + add esi,32 + add edi,32 + jmp _TCC3 +_TCC2: mov ecx,8 + rep movsd +_TCC3: sub edi,NBUFFW32 + dec edx + jnz _TCLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeD: mov edx,30 +_TDLp1: cmp edi,dword ptr [ClipY] + jb _TDC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TDx +_TDC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TDLp2 + movsw + jecxz _TDx +_TDLp2: rep movsd +_TDx: sub edi,NBUFFW32 + or edx,edx + jz _TDb + add edi,edx + sub edx,2 + jmp _TDLp1 + +_TDb: mov edx,16 +_TDLp3: cmp edi,dword ptr [ClipY] + jb _TDC2 + add esi,32 + add edi,32 + jmp _TDC3 +_TDC2: mov ecx,8 + rep movsd +_TDC3: sub edi,NBUFFW32 + dec edx + jnz _TDLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeG: mov edx,32 + xor eax,eax +_TGLp1: cmp edi,dword ptr [ClipY] + jb _TGC1 + add esi,32 + add edi,32 + jmp _TGC2 +_TGC1: mov ecx,8 + rep stosd +_TGC2: sub edi,NBUFFW32 + dec edx + jnz _TGLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeH: mov ecx,32 + +_THLp1: push ecx + mov edx,32 + +_THLp2: xor eax,eax // Load control byte + lodsb + or al,al + js _THJ + + sub edx,eax + cmp edi,dword ptr [ClipY] + jb _THC1 + add esi,eax + add edi,eax + jmp _THx +_THC1: mov ecx,eax + add esi,ecx + xor eax,eax + shr ecx,1 + jnc _THw + stosb + jecxz _THx +_THw: shr ecx,1 + jnc _THLp3 + stosw + jecxz _THx +_THLp3: rep stosd +_THx: or edx,edx + jz _THNxt + jmp _THLp2 + +_THJ: neg al // Do jump + add edi,eax + sub edx,eax + jnz _THLp2 +_THNxt: pop ecx + sub edi,NBUFFW32 + loop _THLp1 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeI: mov edx,30 + xor eax,eax +_TILp1: cmp edi,dword ptr [ClipY] + jb _TIC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TIx +_TIC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TILp2 + stosw + jecxz _TIx +_TILp2: rep stosd +_TIx: sub edi,NBUFFW32 + or edx,edx + jz _TIb + sub edx,2 + jmp _TILp1 + +_TIb: mov edx,2 +_TILp3: cmp edi,dword ptr [ClipY] + jb _TIC2 + add esi,32 + sub esi,edx + add edi,32 + jmp _TIx2 +_TIC2: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TILp4 + stosw + jecxz _TIx2 +_TILp4: rep stosd +_TIx2: sub edi,NBUFFW32 + add edx,2 + cmp edx,32 + jnz _TILp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeJ: mov edx,30 + xor eax,eax +_TJLp1: cmp edi,dword ptr [ClipY] + jb _TJC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TJx +_TJC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp2 + stosw + jecxz _TJx +_TJLp2: rep stosd +_TJx: sub edi,NBUFFW32 + or edx,edx + jz _TJb + add edi,edx + sub edx,2 + jmp _TJLp1 + +_TJb: mov edx,2 +_TJLp3: cmp edi,dword ptr [ClipY] + jb _TJC2 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TJx2 +_TJC2: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TJLp4 + stosw + jecxz _TJx2 +_TJLp4: rep stosd +_TJx2: sub edi,NBUFFW32 + add edi,edx + add edx,2 + cmp edx,32 + jnz _TJLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeK: mov edx,30 + xor eax,eax +_TKLp1: cmp edi,dword ptr [ClipY] + jb _TKC1 + add esi,32 + sub esi,edx + add edi,32 + jmp _TKx +_TKC1: add edi,edx + mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TKLp2 + stosw + jecxz _TKx +_TKLp2: rep stosd +_TKx: sub edi,NBUFFW32 + or edx,edx + jz _TKb + sub edx,2 + jmp _TKLp1 + +_TKb: mov edx,16 +_TKLp3: cmp edi,dword ptr [ClipY] + jb _TKC2 + add esi,32 + add edi,32 + jmp _TKC3 +_TKC2: mov ecx,8 + rep stosd +_TKC3: sub edi,NBUFFW32 + dec edx + jnz _TKLp3 + jmp _Done + +/*-----------------------------------------------------------------------*/ + +_TypeL: mov edx,30 + xor eax,eax +_TLLp1: cmp edi,dword ptr [ClipY] + jb _TLC1 + add esi,32 + sub esi,edx + add edi,32 + sub edi,edx + jmp _TLx +_TLC1: mov ecx,32 + sub ecx,edx + shr ecx,2 + jnc _TLLp2 + stosw + jecxz _TLx +_TLLp2: rep stosd +_TLx: sub edi,NBUFFW32 + or edx,edx + jz _TLb + add edi,edx + sub edx,2 + jmp _TLLp1 + +_TLb: mov edx,16 +_TLLp3: cmp edi,dword ptr [ClipY] + jb _TLC2 + add esi,32 + add edi,32 + jmp _TLC3 +_TLC2: mov ecx,8 + rep stosd +_TLC3: sub edi,NBUFFW32 + dec edx + jnz _TLLp3 + + jmp _Done + +xbytes: + + shr cl,1 + jnc xwords + + mov dl, [esi] + mov dl, [ebx+edx] + mov [edi],dl + + add esi,1 + add edi,1 + +xwords: + shr cl,1 + jnc xquads + + mov dl, [esi] + mov ch, [ebx+edx] + + mov [edi],ch + mov dl, [esi+1] + + mov ch, [ebx+edx] + mov [edi+1],ch + + add esi,2 + add edi,2 + +xquads: + test cl,cl + jz xend + +xnext: + mov eax, [esi] + add esi,4 + + mov dl,al + mov ch,[ebx+edx] + + mov dl,ah + ror eax,16 + mov [edi],ch + + mov ch,[ebx+edx] + + mov dl,al + mov [edi+1],ch + + mov ch,[ebx+edx] + + mov dl,ah + mov [edi+2],ch + + mov ch,[ebx+edx] + mov [edi+3],ch + + add edi,4 + + dec cl + jnz xnext + +xend: + ret + +_Done: + + } // end of asm block +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawBlankMini(BYTE *pDecodeTo) +{ + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov edx,30 + mov ebx,1 + xor eax,eax + //mov eax,092929292h // yellow +_BLp1: add edi,edx + mov ecx,ebx + rep stosd + add edi,edx + sub edi,NBUFFW64 + or edx,edx + jz _Bb + sub edx,2 + inc ebx + jmp _BLp1 + +_Bb: mov edx,2 + mov ebx,15 +_BLp2: add edi,edx + mov ecx,ebx + rep stosd + add edi,edx + sub edi,NBUFFW64 + dec ebx + add edx,2 + cmp edx,32 + jnz _BLp2 + } +} + diff --git a/SCRLASM.H b/SCRLASM.H new file mode 100644 index 0000000..5796107 --- /dev/null +++ b/SCRLASM.H @@ -0,0 +1,38 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/SCRLASM.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +//************************************************************************* +// Flags for partial transparency (bottoms of trans walls, etc.) +//************************************************************************* +enum { + PART_TRANS_NONE, + PART_TRANS_LEFT, + PART_TRANS_RIGHT, +}; + + + +#define NBUFFW32 800 +#define NBUFFW64 832 + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +extern "C" void _fastcall DrawMTileClipTop(BYTE *pDecodeTo); +extern "C" void _fastcall DrawMTileClipBottom(BYTE *pDecodeTo); diff --git a/SCROLLRT.CPP b/SCROLLRT.CPP new file mode 100644 index 0000000..4faad47 --- /dev/null +++ b/SCROLLRT.CPP @@ -0,0 +1,3819 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Scrolling file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/SCROLLRT.CPP 3 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +** CheckForScroll +** DrawAndBlit +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "sound.h" +#include "engine.h" +#include "scrollrt.h" +#include "scrlasm.h" +#include "gendung.h" +#include "debug.h" +#include "inv.h" +#include "multi.h" +#include "lighting.h" +#include "control.h" +#include "gamemenu.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "monstint.h" +#include "dead.h" +#include "objects.h" +#include "missiles.h" +#include "misdat.h" +#include "spells.h" +#include "cursor.h" +#include "quests.h" +#include "town.h" +#include "minitext.h" +#include "automap.h" +#include "help.h" +#include "error.h" +#include "doom.h" + + +/*-----------------------------------------------------------------------** +** debugging +**-----------------------------------------------------------------------*/ +#define LOCK_WAIT 1 // 1 in final +#define LOCK_SLEEP 1 // 1 in final +#define MAX_FRAMES 50 // arbitrary limit to check for bogus numbers of frames +const char sgszUnknownAction[] = "unknown action"; +#define GRACEFUL_EXIT // this needs to be undefined later to get assert turned back on. JKE + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszRegSig6[REG_LEN] = "REGISTRATION_BLOCK"; + + +/*-----------------------------------------------------------------------** +** Function stubs +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +void DrawUnit(long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend); +void DrawUnitOutline(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend); +void DrawInfraUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff); +void DrawLitUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend); + +void DrawUnitClipped(long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend); +void DrawUnitOutlineClipped(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend); +void DrawInfraUnitClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff); +void DrawLitUnitClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend); +#endif + +void DrawHTLXsub (BYTE *pTo, int sx, int sy, int xp, int yp, BOOL chflag); +void DrawHTLXsub2 (BYTE *pTo, int sx, int sy, int sv, int sv2, int xp, int yp, BOOL chflag); +void DrawHTLXsub3 (BYTE *pTo, int sx, int sy, int ev, int ev2, int xp, int yp, BOOL chflag); +void plrmsg_draw(); + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#define MOUTC 233 +#define IOUTC 181 //130 +#define OOUTC 194 //148 +#define POUTC 165 + +extern "C" { + BOOL nTrans; + long nLVal; + int gnPieceNum; + char gbPartialTrans; + DWORD gdwPNum; + long glClipY; +} +int gnMI; +long nBuffWTbl[1024]; + + +// frame counter +#ifndef NDEBUG +static DWORD sgnLastFrame; +static BYTE sgfFrameCounterEnabled = FALSE; +#endif + +bool HighLightAllItems = false; + +//****************************************************************** +// savecrsr variables +//****************************************************************** +static BYTE sgSaveBack[8*1024]; +static DWORD sgdwCursX,sgdwCursY,sgdwCursWdt,sgdwCursHgt; +static DWORD sgdwOldX,sgdwOldY,sgdwOldWdt,sgdwOldHgt; + + +//****************************************************************** +//****************************************************************** +void savecrsr_reset() { + // inhibit cursor redraw + sgdwCursWdt = 0; + sgdwOldWdt = 0; +} + + +//****************************************************************** +//****************************************************************** +static void savecrsr_hide() { + if (! sgdwCursWdt) return; + + // copy from save cursor buffer to draw buffer + app_assert(gpBuffer); + BYTE * pbDst = gpBuffer + (sgdwCursY + 160) * 768 + sgdwCursX + 64; + const BYTE * pbSrc = sgSaveBack; + for (DWORD hgt = sgdwCursHgt; hgt--; ) { + memcpy(pbDst,pbSrc,sgdwCursWdt); + pbSrc += sgdwCursWdt; + pbDst += 768; + } + + sgdwOldX = sgdwCursX; + sgdwOldY = sgdwCursY; + sgdwOldWdt = sgdwCursWdt; + sgdwOldHgt = sgdwCursHgt; + sgdwCursWdt = 0; +} + + +//****************************************************************** +//****************************************************************** +static void savecrsr_show() { + // make sure cursor was already erased before + app_assert(! sgdwCursWdt); + + if (curs <= 0) return; + if (! cursW || ! cursH) return; + + // add one pixel in each direction for outline drawn around cursor + int cursX = MouseX - 1; + if (cursX < 0) cursX = 0; + else if (cursX > 639) return; + int cursY = MouseY - 1; + if (cursY < 0) cursY = 0; + else if (cursY > 479) return; + + // calculate area behind cursor -- X/WDT rounded to DWORD boundary/size + sgdwCursX = cursX; // get X1 coord + sgdwCursWdt = cursX + cursW + 2 - 1; // get X2 coord + if (sgdwCursWdt > 639) sgdwCursWdt = 639; // clip X + sgdwCursX &= ~3; // X1 % 4 == 0 + sgdwCursWdt |= 3; // X2 % 4 == 3 + sgdwCursWdt += 1 - sgdwCursX; // WDT = X2 - X1 + 1 + + sgdwCursY = cursY; // get X1 coord + sgdwCursHgt = cursY + cursH + 2 - 1; // get X2 coord + if (sgdwCursHgt > 479) sgdwCursHgt = 479; // clip Y + sgdwCursHgt += 1 - sgdwCursY; // HGT = Y2 - Y1 + 1 + app_assert(sgdwCursWdt * sgdwCursHgt < sizeof sgSaveBack); + + // copy from draw buffer to save cursor buffer + app_assert(gpBuffer); + const BYTE * pbSrc = gpBuffer + (sgdwCursY + 160) * 768 + sgdwCursX + 64; + BYTE * pbDst = sgSaveBack; + for (DWORD hgt = sgdwCursHgt; hgt--; ) { + memcpy(pbDst,pbSrc,sgdwCursWdt); + pbDst += sgdwCursWdt; + pbSrc += 768; + } + + // remove one pixel in each direction for outline drawn around cursor + cursX += 1; + cursY += 1; + glClipY = (long) gpBuffer + nBuffWTbl[640] - (cursW + 2); + if (curs >= ICSTART) { + int oc = 197; + if (plr[myplr].HoldItem._iMagical) oc = 181; + if (!plr[myplr].HoldItem._iStatFlag) oc = 229; + if (curs <= ICLAST) + { + COutlineSlabCel(oc, cursX+64, cursY+160+cursH-1, pCursCels, curs, cursW, 0, 8); + if (oc != 229) CDrawSlabCel(cursX+64, cursY+160+cursH-1, pCursCels, curs, cursW, 0, 8); + else CDrawSlabCelI(cursX+64, cursY+160+cursH-1, pCursCels, curs, cursW, 0, 8, LIGHT_INFRA); + } + else + { + COutlineSlabCel(oc, cursX+64, cursY+160+cursH-1, pCursCels2, curs - ICLAST, cursW, 0, 8); + if (oc != 229) CDrawSlabCel(cursX+64, cursY+160+cursH-1, pCursCels2, curs - ICLAST, cursW, 0, 8); + else CDrawSlabCelI(cursX+64, cursY+160+cursH-1, pCursCels2, curs - ICLAST, cursW, 0, 8, LIGHT_INFRA); + } + } + else { + CDrawSlabCel(cursX+64, cursY+160+cursH-1, pCursCels, curs, cursW, 0, 8); + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +void DrawMissile(int sx, int sy, int xp, int yp, int ds, int de, BOOL pre) +{ + int i, gnMI, mx, my; + + if (dMissile[sx][sy] != -1) { + gnMI = dMissile[sx][sy] - 1; + if(missile[gnMI]._miPreFlag == pre) { + mx = missile[gnMI]._mixoff + xp - missile[gnMI]._miAnimWidth2; + my = missile[gnMI]._miyoff + yp; + if (missile[gnMI]._miUniqTrans) { + DrawSlabCelI(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de, LIGHT_U + missile[gnMI]._miUniqTrans - 1); + } + else { + if (missile[gnMI]._miLightFlag) { + DrawSlabCelL(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + } + else { + app_assert(missile[gnMI]._miAnimData); + DrawSlabCel(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + } + } + } + } else { + for (i = 0; i < nummissiles; ++i) { + gnMI = missileactive[i]; + if ((missile[gnMI]._mix == sx) && (missile[gnMI]._miy == sy) + && (missile[gnMI]._miPreFlag == pre) && (missile[gnMI]._miDrawFlag == TRUE)) + { + mx = missile[gnMI]._mixoff + xp - missile[gnMI]._miAnimWidth2; + my = missile[gnMI]._miyoff + yp; + if (missile[gnMI]._miUniqTrans) { + DrawSlabCelI(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de, LIGHT_U + missile[gnMI]._miUniqTrans - 1); + } + else { + if (missile[gnMI]._miLightFlag) { + DrawSlabCelL(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + } + else { + app_assert(missile[gnMI]._miAnimData); + DrawSlabCel(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + } + } + } + } + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +void CDrawMissile(int sx, int sy, int xp, int yp, int ds, int de, BOOL pre) +{ + int i, gnMI, mx, my; + + if (dMissile[sx][sy] != -1) { + gnMI = dMissile[sx][sy] - 1; + if (missile[gnMI]._miPreFlag == pre) { + mx = missile[gnMI]._mixoff + xp - missile[gnMI]._miAnimWidth2; + my = missile[gnMI]._miyoff + yp; + if (missile[gnMI]._miUniqTrans) + CDrawSlabCelI(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de, LIGHT_U + missile[gnMI]._miUniqTrans - 1); + else { + if (missile[gnMI]._miLightFlag) CDrawSlabCelL(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + else CDrawSlabCel(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + } + } + } else { + for (i = 0; i < nummissiles; ++i) { + gnMI = missileactive[i]; + if ((missile[gnMI]._mix == sx) && (missile[gnMI]._miy == sy) + && (missile[gnMI]._miPreFlag == pre) && (missile[gnMI]._miDrawFlag == TRUE)) + { + mx = missile[gnMI]._mixoff + xp - missile[gnMI]._miAnimWidth2; + my = missile[gnMI]._miyoff + yp; + if (missile[gnMI]._miUniqTrans) + CDrawSlabCelI(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de, LIGHT_U + missile[gnMI]._miUniqTrans - 1); + else { + if (missile[gnMI]._miLightFlag) CDrawSlabCelL(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + else CDrawSlabCel(mx, my, missile[gnMI]._miAnimData, missile[gnMI]._miAnimFrame, missile[gnMI]._miAnimWidth, ds, de); + } + } + } + } +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +void DrawMissile(int sx, int sy, int xp, int yp, int ds, int de, BOOL pre) +{ + int i, mx, my; + MissileStruct * pMiss; + + if (dMissile[sx][sy] == -1) { + for (i = 0; i < nummissiles; ++i) { + app_assert(missileactive[i] < MAXMISSILES && missileactive[i] >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (missileactive[i] >= MAXMISSILES || missileactive[i] < 0 ) + return; + #endif + // jcm.patch1.end.1/14/97 + pMiss = &missile[missileactive[i]]; + if ((pMiss->_mix != sx) || (pMiss->_miy != sy) || (pMiss->_miPreFlag != pre) || !pMiss->_miDrawFlag) + continue; + if (pMiss->_miAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Missile type %d: NULL Cel Buffer",pMiss->_mitype); + #endif + // jcm.patch1.end.1/14/97 + if (pMiss->_miAnimFrame < 1 || *(DWORD*)pMiss->_miAnimData > MAX_FRAMES || + pMiss->_miAnimFrame > *(long*)pMiss->_miAnimData) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Missile: frame %d of %d, missile type==%d", + pMiss->_miAnimFrame, + *(long*)pMiss->_miAnimData, + pMiss->_mitype + ); + #endif + // jcm.patch1.end.1/14/97 + } + mx = pMiss->_mixoff + xp - pMiss->_miAnimWidth2; + my = pMiss->_miyoff + yp; + if (pMiss->_miUniqTrans) { + DrawInfraUnit( + mx, my, + pMiss->_miAnimData, + pMiss->_miAnimFrame, + pMiss->_miAnimWidth, + ds, de, + LIGHT_U + pMiss->_miUniqTrans - 1 + ); + } else if (pMiss->_miLightFlag) { + DrawLitUnit(mx, my, pMiss->_miAnimData, pMiss->_miAnimFrame, pMiss->_miAnimWidth, ds, de); + } else { + DrawUnit(mx, my, pMiss->_miAnimData, pMiss->_miAnimFrame, pMiss->_miAnimWidth, ds, de); + } + } + return; + } + pMiss = &missile[dMissile[sx][sy] - 1]; + if (pMiss->_miPreFlag != pre) + return; + if (pMiss->_miAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Missile 2 type %d: NULL Cel Buffer",pMiss->_mitype); + #endif + // jcm.patch1.end.1/14/97 + if (pMiss->_miAnimFrame < 1 || *(DWORD*)pMiss->_miAnimData > MAX_FRAMES + || pMiss->_miAnimFrame > *(long*)pMiss->_miAnimData) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Missile 2: frame %d of %d, missile type==%d", + pMiss->_miAnimFrame, + *(long*)pMiss->_miAnimData, + pMiss->_mitype + ); + #endif + // jcm.patch1.end.1/14/97 + } + mx = pMiss->_mixoff + xp - pMiss->_miAnimWidth2; + my = pMiss->_miyoff + yp; + if (pMiss->_miUniqTrans) { + DrawInfraUnit( + mx, my, + pMiss->_miAnimData, + pMiss->_miAnimFrame, + pMiss->_miAnimWidth, + ds, de, + LIGHT_U + pMiss->_miUniqTrans - 1 + ); + } else if (pMiss->_miLightFlag) { + DrawLitUnit(mx, my, pMiss->_miAnimData, pMiss->_miAnimFrame, pMiss->_miAnimWidth, ds, de); + } else { + DrawUnit(mx, my, pMiss->_miAnimData, pMiss->_miAnimFrame, pMiss->_miAnimWidth, ds, de); + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +void CDrawMissile(int sx, int sy, int xp, int yp, int ds, int de, BOOL pre) +{ + int i, mx, my; + MissileStruct * pMiss; + + if (dMissile[sx][sy] == -1) { + for (i = 0; i < nummissiles; ++i) { + app_assert(missileactive[i] < MAXMISSILES && missileactive[i] >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (missileactive[i] >= MAXMISSILES || missileactive[i] < 0) + return; + #endif + // jcm.patch1.end.1/14/97 + pMiss = &missile[missileactive[i]]; + if ((pMiss->_mix != sx) || (pMiss->_miy != sy) || (pMiss->_miPreFlag != pre) || !pMiss->_miDrawFlag) + continue; + if (pMiss->_miAnimData == NULL) + // jcm.patch1.start.1/14/97 + //#ifdef GRACEFUL_EXIT + return; + //#else + //app_fatal("Draw Missile type %d Clipped: NULL Cel Buffer",pMiss->_mitype); + //#endif + // jcm.patch1.end.1/14/97 + if (pMiss->_miAnimFrame < 1 || *reinterpret_cast(pMiss->_miAnimData) > MAX_FRAMES + || pMiss->_miAnimFrame > *reinterpret_cast(pMiss->_miAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Clipped Missile: frame %d of %d, missile type==%d", + pMiss->_miAnimFrame, + *reinterpret_cast(pMiss->_miAnimData), + pMiss->_mitype + ); + #endif + // jcm.patch1.end.1/14/97 + } + mx = pMiss->_mixoff + xp - pMiss->_miAnimWidth2; + my = pMiss->_miyoff + yp; + if (pMiss->_miUniqTrans) { + DrawInfraUnitClipped( + mx, my, + pMiss->_miAnimData, + pMiss->_miAnimFrame, + pMiss->_miAnimWidth, + ds, de, + LIGHT_U + pMiss->_miUniqTrans - 1 + ); + } else if (pMiss->_miLightFlag) { + DrawLitUnitClipped(mx,my,pMiss->_miAnimData,pMiss->_miAnimFrame,pMiss->_miAnimWidth,ds,de); + } else { + DrawUnitClipped(mx,my,pMiss->_miAnimData,pMiss->_miAnimFrame,pMiss->_miAnimWidth,ds,de); + } + } + return; + } + pMiss = &missile[dMissile[sx][sy] - 1]; + if (pMiss->_miPreFlag != pre) + return; + if (pMiss->_miAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Missile 2 type %d Clipped: NULL Cel Buffer",pMiss->_mitype); + #endif + // jcm.patch1.end.1/14/97 + if (pMiss->_miAnimFrame < 1 || *(DWORD*)pMiss->_miAnimData > MAX_FRAMES + || pMiss->_miAnimFrame > *(long*)pMiss->_miAnimData) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Clipped Missile 2: frame %d of %d, missile type==%d", + pMiss->_miAnimFrame, + *reinterpret_cast(pMiss->_miAnimData), + pMiss->_mitype + ); + #endif + // jcm.patch1.end.1/14/97 + } + mx = pMiss->_mixoff + xp - pMiss->_miAnimWidth2; + my = pMiss->_miyoff + yp; + if (pMiss->_miUniqTrans) { + DrawInfraUnitClipped( + mx, my, + pMiss->_miAnimData, + pMiss->_miAnimFrame, + pMiss->_miAnimWidth, + ds, de, + LIGHT_U + pMiss->_miUniqTrans - 1 + ); + } else if (pMiss->_miLightFlag) { + DrawLitUnitClipped(mx,my,pMiss->_miAnimData,pMiss->_miAnimFrame,pMiss->_miAnimWidth,ds,de); + } else { + DrawUnitClipped(mx,my,pMiss->_miAnimData,pMiss->_miAnimFrame,pMiss->_miAnimWidth,ds,de); + } +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +static void DrawMSlabCelL (int sx, int sy, int xp, int yp, int gnMI, int ostart, int oend) +{ + char dinfra; + + if (!(dFlags[sx][sy] & BFLAG_VISIBLE)) + DrawSlabCelI(xp, yp, monster[gnMI]._mAnimData, monster[gnMI]._mAnimFrame, monster[gnMI].MType->mAnimWidth, ostart, oend, LIGHT_INFRA); + else { + dinfra = LIGHT_NORM; + if (monster[gnMI]._uniqtype != 0) dinfra = LIGHT_U + monster[gnMI]._uniqtrans; + if (monster[gnMI]._mmode == MM_STONE) dinfra = LIGHT_STONE; + if ((plr[myplr]._pInfraFlag) && (nLVal > 8)) dinfra = LIGHT_INFRA; + if (dinfra != LIGHT_NORM) + DrawSlabCelI(xp, yp, monster[gnMI]._mAnimData, monster[gnMI]._mAnimFrame, monster[gnMI].MType->mAnimWidth, ostart, oend, dinfra); + else + DrawSlabCelL(xp, yp, monster[gnMI]._mAnimData, monster[gnMI]._mAnimFrame, monster[gnMI].MType->mAnimWidth, ostart, oend); + } +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +static void CDrawMSlabCelL (int sx, int sy, int xp, int yp, int gnMI, int ostart, int oend) +{ + char dinfra; + + if (!(dFlags[sx][sy] & BFLAG_VISIBLE)) + CDrawSlabCelI(xp, yp, monster[gnMI]._mAnimData, monster[gnMI]._mAnimFrame, monster[gnMI].MType->mAnimWidth, ostart, oend, LIGHT_INFRA); + else { + dinfra = LIGHT_NORM; + if (monster[gnMI]._uniqtype != 0) dinfra = LIGHT_U + monster[gnMI]._uniqtrans; + if (monster[gnMI]._mmode == MM_STONE) dinfra = LIGHT_STONE; + if ((plr[myplr]._pInfraFlag) && (nLVal > 8)) dinfra = LIGHT_INFRA; + if (dinfra != LIGHT_NORM) + CDrawSlabCelI(xp, yp, monster[gnMI]._mAnimData, monster[gnMI]._mAnimFrame, monster[gnMI].MType->mAnimWidth, ostart, oend, dinfra); + else + CDrawSlabCelL(xp, yp, monster[gnMI]._mAnimData, monster[gnMI]._mAnimFrame, monster[gnMI].MType->mAnimWidth, ostart, oend); + } +} +#endif + + +//*************************************************************************** +//*************************************************************************** + // These strings should match the MM_xxx constants defined in monstint.h + const char * sgszMonsterAction[] = { + "standing", + "walking (1)", + "walking (2)", + "walking (3)", + "attacking", + "getting hit", + "dying", + "attacking (special)", + "fading in", + "fading out", + "attacking (ranged)", + "standing (special)", + "attacking (special ranged)", + "delaying", + "charging", + "stoned", + "healing", + "talking" + }; +inline const char * MonsterActionString(DWORD dwAction) { + if (dwAction <= MM_TALK) + return sgszMonsterAction[dwAction]; + return sgszUnknownAction; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +static void DrawMSlabCelL (int sx, int sy, int xp, int yp, int gnMI, int ostart, int oend) +{ + if ((DWORD)gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Monster: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + if (monster[gnMI]._mAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Monster \"%s\": NULL Cel Buffer",monster[gnMI].mName); + #endif + // jcm.patch1.end.1/14/97 + if (monster[gnMI]._mAnimFrame < 1 || *reinterpret_cast(monster[gnMI]._mAnimData) > MAX_FRAMES + || monster[gnMI]._mAnimFrame > *reinterpret_cast(monster[gnMI]._mAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Monster \"%s\" %s: facing %d, frame %d of %d", + monster[gnMI].mName, + MonsterActionString(monster[gnMI]._mmode), + monster[gnMI]._mdir, + monster[gnMI]._mAnimFrame, + *reinterpret_cast(monster[gnMI]._mAnimData) + ); + #endif + // jcm.patch1.end.1/14/97 + } + if (!(dFlags[sx][sy] & BFLAG_VISIBLE)) { + DrawInfraUnit( + xp, yp, + monster[gnMI]._mAnimData, + monster[gnMI]._mAnimFrame, + monster[gnMI].MType->mAnimWidth, + ostart, + oend, + LIGHT_INFRA + ); + return; + } + char dinfra = LIGHT_NORM; + if (monster[gnMI]._uniqtype) + dinfra = LIGHT_U + monster[gnMI]._uniqtrans; + if (monster[gnMI]._mmode == MM_STONE) + dinfra = LIGHT_STONE; + if (plr[myplr]._pInfraFlag && (nLVal > 8)) + dinfra = LIGHT_INFRA; + if (dinfra != LIGHT_NORM) + DrawInfraUnit( + xp, yp, + monster[gnMI]._mAnimData, + monster[gnMI]._mAnimFrame, + monster[gnMI].MType->mAnimWidth, + ostart, + oend, + dinfra + ); + else + DrawLitUnit( + xp, yp, + monster[gnMI]._mAnimData, + monster[gnMI]._mAnimFrame, + monster[gnMI].MType->mAnimWidth, + ostart, + oend + ); +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +static void CDrawMSlabCelL (int sx, int sy, int xp, int yp, int gnMI, int ostart, int oend) +{ + if ((DWORD)gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Monster Clipped: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + if (monster[gnMI]._mAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Monster \"%s\" Clipped: NULL Cel Buffer",monster[gnMI].mName); + #endif + // jcm.patch1.end.1/14/97 + if (monster[gnMI]._mAnimFrame < 1 || *reinterpret_cast(monster[gnMI]._mAnimData) > MAX_FRAMES + || monster[gnMI]._mAnimFrame > *reinterpret_cast(monster[gnMI]._mAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Monster \"%s\" %s Clipped: facing %d, frame %d of %d", + monster[gnMI].mName, + MonsterActionString(monster[gnMI]._mmode), + monster[gnMI]._mdir, + monster[gnMI]._mAnimFrame, + *reinterpret_cast(monster[gnMI]._mAnimData) + ); + #endif + // jcm.patch1.end.1/14/97 + } + if (!(dFlags[sx][sy] & BFLAG_VISIBLE)) { + DrawInfraUnitClipped( + xp, yp, + monster[gnMI]._mAnimData, + monster[gnMI]._mAnimFrame, + monster[gnMI].MType->mAnimWidth, + ostart, + oend, + LIGHT_INFRA + ); + return; + } + char dinfra = LIGHT_NORM; + if (monster[gnMI]._uniqtype) + dinfra = LIGHT_U + monster[gnMI]._uniqtrans; + if (monster[gnMI]._mmode == MM_STONE) + dinfra = LIGHT_STONE; + if (plr[myplr]._pInfraFlag && (nLVal > 8)) + dinfra = LIGHT_INFRA; + if (dinfra != LIGHT_NORM) + DrawInfraUnitClipped( + xp, yp, + monster[gnMI]._mAnimData, + monster[gnMI]._mAnimFrame, + monster[gnMI].MType->mAnimWidth, + ostart, + oend, + dinfra + ); + else + DrawLitUnitClipped( + xp, yp, + monster[gnMI]._mAnimData, + monster[gnMI]._mAnimFrame, + monster[gnMI].MType->mAnimWidth, + ostart, + oend + ); +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +static void DrawPSlabCelL (int gnPlayer, int sx, int sy, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + if (dFlags[sx][sy] & BFLAG_VISIBLE || plr[myplr]._pInfraFlag) { + if (gnPlayer == cursplr) { + OutlineSlabCel( + POUTC, + xp, yp, + pCelBuff, nCel, nCelW, + ostart, oend + ); + } + + if (gnPlayer == myplr) { + app_assert(pCelBuff); + DrawSlabCel(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + } + else if (!(dFlags[sx][sy] & BFLAG_VISIBLE) + || plr[myplr]._pInfraFlag && (nLVal > 8)) { + DrawSlabCelI(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, LIGHT_INFRA); + } + else { + // Draw other players slightly brighter than monsters + int templval = nLVal; + if (nLVal >= 5) + nLVal -= 5; + else + nLVal = 0; + DrawSlabCelL(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + nLVal = templval; + } + } +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if !RLE_DRAW +static void CDrawPSlabCelL (int gnPlayer, int sx, int sy, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + if (dFlags[sx][sy] & BFLAG_VISIBLE || plr[myplr]._pInfraFlag + || (!setlevel && currlevel == 0)) { + if (gnPlayer == cursplr) + COutlineSlabCel( + POUTC, + xp, yp, + pCelBuff, nCel, nCelW, + ostart, oend + ); + if (gnPlayer == myplr) + CDrawSlabCel(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + else if (!(dFlags[sx][sy] & BFLAG_VISIBLE) + || plr[myplr]._pInfraFlag && (nLVal > 8)) + CDrawSlabCelI(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, LIGHT_INFRA); + else + { + // Draw other players slightly brighter than monsters + int templval = nLVal; + if (nLVal >= 5) + nLVal -= 5; + else + nLVal = 0; + CDrawSlabCelL(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + nLVal = templval; + } + } +} +#endif + + +//*************************************************************************** +//*************************************************************************** + // These strings should match the PM_xxx constants defined in player.h + const char * sgszPlayerAction[] = { + "standing", + "walking (1)", + "walking (2)", + "walking (3)", + "attacking (melee)", + "attacking (ranged)", + "blocking", + "getting hit", + "dying", + "casting a spell", + "changing levels", + "quitting" + }; +inline const char * PlayerActionString(DWORD dwAction) { + if (dwAction <= PM_QUIT) + return sgszPlayerAction[dwAction]; + return sgszUnknownAction; +} + + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +static void DrawPSlabCelL ( + int nPlayer, int sx, int sy, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + if (!(dFlags[sx][sy] & BFLAG_VISIBLE) && !plr[myplr]._pInfraFlag && (setlevel || currlevel)) + return; + if (pCelBuff == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Drawing player %d \"%s\": NULL Cel Buffer",nPlayer,plr[nPlayer]._pName); + #endif + // jcm.patch1.end.1/14/97 + if (nCel < 1 || *(DWORD*)pCelBuff > MAX_FRAMES || nCel > *reinterpret_cast(pCelBuff)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Drawing player %d \"%s\" %s: facing %d, frame %d of %d", + nPlayer, + plr[nPlayer]._pName, + PlayerActionString(plr[nPlayer]._pmode), + plr[nPlayer]._pdir, + nCel, + *reinterpret_cast(pCelBuff) + ); + #endif + // jcm.patch1.end.1/14/97 + } + if (nPlayer == cursplr) + DrawUnitOutline(POUTC,xp,yp,pCelBuff,nCel,nCelW,ostart,oend); + + if (nPlayer == myplr) { + DrawUnit(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + } + else if (!(dFlags[sx][sy] & BFLAG_VISIBLE) + || plr[myplr]._pInfraFlag && (nLVal > 8)) { + DrawInfraUnit(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, LIGHT_INFRA); + } + else { + // Draw other players slightly brighter than monsters + int templval = nLVal; + nLVal = (nLVal < 5) ? 0 : nLVal - 5; + DrawLitUnit(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + nLVal = templval; + } +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#if RLE_DRAW +static void CDrawPSlabCelL ( + int nPlayer, int sx, int sy, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend) +{ + if (!(dFlags[sx][sy] & BFLAG_VISIBLE) && !plr[myplr]._pInfraFlag) + return; + if (pCelBuff == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Drawing player %d \"%s\" clipped: NULL Cel Buffer",nPlayer,plr[nPlayer]._pName); + #endif + // jcm.patch1.end.1/14/97 + if (nCel < 1 || *(DWORD*)pCelBuff > MAX_FRAMES || nCel > *reinterpret_cast(pCelBuff)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Drawing player %d \"%s\" %s clipped: facing %d, frame %d of %d", + nPlayer, + plr[nPlayer]._pName, + PlayerActionString(plr[nPlayer]._pmode), + plr[nPlayer]._pdir, + nCel, + *reinterpret_cast(pCelBuff) + ); + #endif + // jcm.patch1.end.1/14/97 + } + if (nPlayer == cursplr) + DrawUnitOutlineClipped(POUTC,xp,yp,pCelBuff,nCel,nCelW,ostart,oend); + if (nPlayer == myplr) { + DrawUnitClipped(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + } else if (!(dFlags[sx][sy] & BFLAG_VISIBLE) + || plr[myplr]._pInfraFlag && (nLVal > 8)) { + DrawInfraUnitClipped(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, LIGHT_INFRA); + } else { + // Draw other players slightly brighter than monsters + int templval = nLVal; + nLVal = (nLVal < 5) ? 0 : nLVal - 5; + DrawLitUnitClipped(xp, yp, pCelBuff, nCel, nCelW, ostart, oend); + nLVal = templval; + } +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawDeadPlr(int sx, int sy, int xp, int yp, int ostart, int oend, BOOL clip) +{ + int pnum; + static void (*PlayerDraw)(int, int, int, long, long, BYTE *, long, long, long, long); + PlayerStruct * pPlayer; + + PlayerDraw = clip ? CDrawPSlabCelL : DrawPSlabCelL; + + dFlags[sx][sy] &= ~BFLAG_DEADPLR; + for (pnum = 0; pnum < MAX_PLRS; ++pnum) + { + pPlayer = &plr[pnum]; + if (!pPlayer->plractive || pPlayer->_pHitPoints || pPlayer->plrlevel != currlevel + || pPlayer->_px != sx || pPlayer->_py != sy) + continue; + if (pPlayer->_pAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Drawing dead player %d \"%s\": NULL Cel Buffer", pnum, pPlayer->_pName); + #endif + // jcm.patch1.end.1/14/97 + if (pPlayer->_pAnimFrame < 1 || *reinterpret_cast(pPlayer->_pAnimData) > MAX_FRAMES + || pPlayer->_pAnimFrame > *reinterpret_cast(pPlayer->_pAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Drawing dead player %d \"%s\": facing %d, frame %d of %d", + pnum, + pPlayer->_pName, + pPlayer->_pdir, + pPlayer->_pAnimFrame, + *reinterpret_cast(pPlayer->_pAnimData) + ); + #endif + // jcm.patch1.end.1/14/97 + } + dFlags[sx][sy] |= BFLAG_DEADPLR; + PlayerDraw(pnum, sx, sy, + pPlayer->_pxoff + xp - pPlayer->_pAnimWidth2, + pPlayer->_pyoff + yp, + pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth, + ostart, oend); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawObjCel(int sx, int sy, int xp, int yp, BOOL pre, int ostart, int oend) +{ + char bv; + int pxp, pyp; + int odx, ody; + + if (dObject[sx][sy] > 0) { + bv = dObject[sx][sy] - 1; + if (object[bv]._oPreFlag != pre) return; + pxp = xp - object[bv]._oAnimWidth2; + pyp = yp; + } else { + bv = -(dObject[sx][sy]+1); + if (object[bv]._oPreFlag != pre) return; + odx = (object[bv]._ox - sx); + ody = (object[bv]._oy - sy); + pxp = xp - object[bv]._oAnimWidth2 + (odx << 5) - (ody << 5); + pyp = yp + (odx << 4) + (ody << 4); + ostart = 0; + oend = 8; + } + app_assert(bv < MAXOBJECTS && bv >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bv >= MAXOBJECTS || bv < 0) + return; + #endif + // jcm.patch1.end.1/14/97 + if (object[bv]._oAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Object type %d: NULL Cel Buffer",object[bv]._otype); + #endif + // jcm.patch1.end.1/14/97 + if (object[bv]._oAnimFrame < 1 || *reinterpret_cast(object[bv]._oAnimData) > MAX_FRAMES + || object[bv]._oAnimFrame > *reinterpret_cast(object[bv]._oAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Object: frame %d of %d, object type==%d", + object[bv]._oAnimFrame, + *reinterpret_cast(object[bv]._oAnimData), + object[bv]._otype + ); + #endif + // jcm.patch1.end.1/14/97 + } + if (bv == cursobj) OutlineSlabCel(OOUTC, pxp, pyp, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, ostart, oend); + if (object[bv]._oLight) { + DrawSlabCelL(pxp, pyp, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, ostart, oend); + } + else { + app_assert(object[bv]._oAnimData); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (object[bv]._oAnimData == NULL) + return; + #endif + // jcm.patch1.end.1/14/97 + DrawSlabCel(pxp, pyp, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, ostart, oend); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void CDrawObjCel(int sx, int sy, int xp, int yp, BOOL pre, int ostart, int oend) +{ + char bv; + int pxp, pyp; + int odx, ody; + + if (dObject[sx][sy] > 0) { + bv = dObject[sx][sy] - 1; + if (object[bv]._oPreFlag != pre) return; + pxp = xp - object[bv]._oAnimWidth2; + pyp = yp; + } else { + bv = -(dObject[sx][sy]+1); + if (object[bv]._oPreFlag != pre) return; + odx = (object[bv]._ox - sx); + ody = (object[bv]._oy - sy); + pxp = xp - object[bv]._oAnimWidth2 + (odx << 5) - (ody << 5); + pyp = yp + (odx << 4) + (ody << 4); + ostart = 0; + oend = 8; + } + app_assert(bv < MAXOBJECTS && bv >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bv >= MAXOBJECTS) + return; + #endif + // jcm.patch1.end.1/14/97 + if (object[bv]._oAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal("Draw Object type %d Clipped: NULL Cel Buffer",object[bv]._otype); + #endif + // jcm.patch1.end.1/14/97 + if (object[bv]._oAnimFrame < 1 || *reinterpret_cast(object[bv]._oAnimData) > MAX_FRAMES + || object[bv]._oAnimFrame > *reinterpret_cast(object[bv]._oAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + return; + #else + app_fatal( + "Draw Clipped Object: frame %d of %d, object type==%d", + object[bv]._oAnimFrame, + *reinterpret_cast(object[bv]._oAnimData), + object[bv]._otype + ); + #endif + // jcm.patch1.end.1/14/97 + } + if (bv == cursobj) COutlineSlabCel(OOUTC, pxp, pyp, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, ostart, oend); + if (object[bv]._oLight) CDrawSlabCelL(pxp, pyp, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, ostart, oend); + else CDrawSlabCel(pxp, pyp, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth, ostart, oend); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawEFlag1(BYTE *pTo2, int sx, int sy, int xp, int yp) +{ + BYTE *pTo; + long oldnLVal; + BOOL oldnTrans; + int oldPieceNum; + WORD *mt; + + oldnLVal = nLVal; + oldnTrans = nTrans; + oldPieceNum = gnPieceNum; + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + gbPartialTrans = PART_TRANS_LEFT; + if (gdwPNum = mt[0]) + DrawMTileClipBottom (pTo2); + gbPartialTrans = PART_TRANS_RIGHT; + if (gdwPNum = mt[1]) + DrawMTileClipBottom (pTo2+32); + gbPartialTrans = PART_TRANS_NONE; + pTo = pTo2; + for(int t = 2; t < MicroTileLen; t += 2) + { + pTo -= NBUFFWSL5; + if (gdwPNum = mt[t]) + DrawMTileClipBottom (pTo); + if (gdwPNum = mt[t+1]) + DrawMTileClipBottom (pTo+32); + } + + DrawHTLXsub (pTo2, sx, sy, xp, yp, FALSE); + + nLVal = oldnLVal; + nTrans = oldnTrans; + gnPieceNum = oldPieceNum; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawHTLXsub (BYTE *pTo, int sx, int sy, int xp, int yp, BOOL chflag) +{ + char bFlags, bDead, bObject, bItem, bPlayer, bSpecial, bPlayerAbove, bTransVal; + int nMonster, nMonsterAbove; + int pxp,pyp; + + app_assert(sx < MAXDUNX); + app_assert(sy < MAXDUNY); + bFlags = dFlags[sx][sy]; + bDead = dDead[sx][sy]; + bObject = dObject[sx][sy]; + bItem = dItem[sx][sy]; + bPlayer = dPlayer[sx][sy]; + bSpecial = dSpecial[sx][sy]; + bTransVal = dTransVal[sx][sy]; + nMonster = dMonster[sx][sy]; + + app_assert((sy-1) < MAXDUNY); + bPlayerAbove = dPlayer[sx][sy-1]; + nMonsterAbove = dMonster[sx][sy-1]; + + if ((visiondebug) && (bFlags & BFLAG_VISIBLE)) + CDrawSlabCelP(pTo, pSquareCel, 1, 64, 0, 8); + if (MissilePreFlag && (bFlags & BFLAG_MISSILE)) + CDrawMissile(sx, sy, xp, yp, 0, 8, TRUE); + if (nLVal < lightmax) { + if (bDead) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + DeadStruct * pDeadGuy = &dead[(bDead & 0x1f) - 1]; + char dd = (bDead & 0xe0) >> 5; + pxp = xp - pDeadGuy->_deadWidth2; + app_assert(pDeadGuy->_deadData[dd] != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDeadGuy->_deadData[dd] == NULL) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pDeadGuy->_deadFrame < 1 || *reinterpret_cast(pDeadGuy->_deadData[dd]) > MAX_FRAMES + || pDeadGuy->_deadFrame > *reinterpret_cast(pDeadGuy->_deadData[dd])) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Clipped dead sub: frame %d of %d, deadnum==%d", + pDeadGuy->_deadFrame, + *reinterpret_cast(pDeadGuy->_deadData[dd]), + (bDead & 0x1f) - 1 + ); + #endif + // jcm.patch1.end.1/14/97 + } + #if RLE_DRAW + if (pDeadGuy->_deadtrans) + DrawInfraUnitClipped( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + 8, + pDeadGuy->_deadtrans + ); + else + DrawLitUnitClipped( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + 8 + ); + #else + if (pDeadGuy->_deadtrans) + CDrawSlabCelI( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + 8, + pDeadGuy->_deadtrans + ); + else + CDrawSlabCelL( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + 8 + ); + #endif + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bObject) + CDrawObjCel(sx, sy, xp, yp, TRUE, 0, 8); + } + if (bItem) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + ItemStruct * pItem = &item[bItem - 1]; + if (!pItem->_iPostDraw) { + app_assert(bItem <= MAXITEMS && bItem >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bItem > MAXITEMS || bItem < 0) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Item \"%s\" Clipped 1: NULL Cel Buffer",pItem->_iIName); + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimFrame < 1 || *reinterpret_cast(pItem->_iAnimData) > MAX_FRAMES + || pItem->_iAnimFrame > *reinterpret_cast(pItem->_iAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Draw Clipped \"%s\" Item: frame %d of %d, item type==%d", + pItem->_iIName, + pItem->_iAnimFrame, + *reinterpret_cast(pItem->_iAnimData), + pItem->_itype + ); + #endif + // jcm.patch1.end.1/14/97 + } + pxp = xp - pItem->_iAnimWidth2; + if ((bItem - 1) == cursitem + || HighLightAllItems == true) + COutlineSlabCel( + IOUTC, + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + 8 + ); + CDrawSlabCelL( + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + 8 + ); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_PLRLR) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + int nPlayer = -(bPlayerAbove + 1); + if ((DWORD)nPlayer >= MAX_PLRS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("draw player clipped: tried to draw illegal player %d",nPlayer); + #endif + // jcm.patch1.end.1/14/97 + PlayerStruct * pPlayer = &plr[nPlayer]; + pxp = pPlayer->_pxoff + xp - pPlayer->_pAnimWidth2; + pyp = pPlayer->_pyoff + yp; + CDrawPSlabCelL( + -(bPlayerAbove + 1), + sx, sy-1, + pxp, + pyp, + pPlayer->_pAnimData, + pPlayer->_pAnimFrame, + pPlayer->_pAnimWidth, + 0, + 8 + ); + if (chflag && pPlayer->_peflag) { + if (pPlayer->_peflag == 2) + DrawEFlag1(pTo-(NBUFFWSL4+96), sx-2, sy+1, xp-96, yp-16); + DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while(0); + #endif + // jcm.patch1.end.1/14/97 + } + if ((bFlags & BFLAG_MONSTLR) && ((bFlags & BFLAG_VISIBLE) || plr[myplr]._pInfraFlag) && (nMonsterAbove < 0)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + gnMI = -(nMonsterAbove + 1); + if ((DWORD)gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster Clipped: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + MonsterStruct * pMonster = &monster[gnMI]; + if (!(pMonster->_mFlags & MFLAG_INVISIBLE)) { + if (pMonster->MType == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster",pMonster->mName); + #endif + // jcm.patch1.end.1/14/97 + pxp = pMonster->_mxoff + xp - pMonster->MType->mAnimWidth2; + pyp = pMonster->_myoff + yp; + #if RLE_DRAW + if (gnMI == cursmonst) + DrawUnitOutlineClipped( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + 8 + ); + #else + if (gnMI == cursmonst) + COutlineSlabCel( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + 8 + ); + #endif + CDrawMSlabCelL(sx, sy, pxp, pyp, gnMI, 0, 8); + if (chflag && pMonster->_meflag) + DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_DEADPLR) + DrawDeadPlr(sx, sy, xp, yp, 0, 8, TRUE); + if (bPlayer > 0) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + int nPlayer = bPlayer - 1; + if ((DWORD)nPlayer >= MAX_PLRS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("draw player clipped: tried to draw illegal player %d",nPlayer); + #endif + // jcm.patch1.end.1/14/97 + PlayerStruct * pPlayer = &plr[nPlayer]; + pxp = pPlayer->_pxoff + xp - pPlayer->_pAnimWidth2; + pyp = pPlayer->_pyoff + yp; + CDrawPSlabCelL( + bPlayer - 1, + sx, sy, + pxp, + pyp, + pPlayer->_pAnimData, + pPlayer->_pAnimFrame, + pPlayer->_pAnimWidth, + 0, + 8 + ); + if (chflag && pPlayer->_peflag) { + if (pPlayer->_peflag == 2) + DrawEFlag1(pTo-(NBUFFWSL4+96), sx-2, sy+1, xp-96, yp-16); + DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if ((nMonster > 0) && ((bFlags & BFLAG_VISIBLE) || plr[myplr]._pInfraFlag)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + gnMI = nMonster - 1; + if ((DWORD)gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster Clipped: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + MonsterStruct * pMonster = &monster[gnMI]; + if (!(pMonster->_mFlags & MFLAG_INVISIBLE)) { + if (pMonster->MType == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster",pMonster->mName); + #endif + // jcm.patch1.end.1/14/97 + pxp = pMonster->_mxoff + xp - pMonster->MType->mAnimWidth2; + pyp = pMonster->_myoff + yp; + #if RLE_DRAW + if (gnMI == cursmonst) + DrawUnitOutlineClipped( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + 8 + ); + #else + if (gnMI == cursmonst) + COutlineSlabCel( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + 8 + ); + #endif + CDrawMSlabCelL(sx, sy, pxp, pyp, gnMI, 0, 8); + if (chflag && pMonster->_meflag) + DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_MISSILE) + CDrawMissile(sx, sy, xp, yp, 0, 8, FALSE); + if (bObject && (nLVal < lightmax)) + CDrawObjCel(sx, sy, xp, yp, FALSE, 0, 8); + if (bItem) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + ItemStruct * pItem = &item[bItem - 1]; + if (pItem->_iPostDraw) { + app_assert(bItem <= MAXITEMS && bItem >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bItem > MAXITEMS || bItem < 0) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Item \"%s\" Clipped 2: NULL Cel Buffer",pItem->_iIName); + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimFrame < 1 || *reinterpret_cast(pItem->_iAnimData) > MAX_FRAMES + || pItem->_iAnimFrame > *reinterpret_cast(pItem->_iAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Draw Clipped \"%s\" Item 2: frame %d of %d, item type==%d", + pItem->_iIName, + pItem->_iAnimFrame, + *reinterpret_cast(pItem->_iAnimData), + pItem->_itype + ); + #endif + // jcm.patch1.end.1/14/97 + } + pxp = xp - pItem->_iAnimWidth2; + if ((bItem - 1) == cursitem + || HighLightAllItems == true) + COutlineSlabCel( + IOUTC, + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + 8 + ); + CDrawSlabCelL( + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + 8 + ); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bSpecial) { + nTrans = TransList[bTransVal]; + TCDrawSlabCelPL(pTo, pSpecialCels, bSpecial, 64, 0, 8); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawHTileLineX (int sx, int sy, int xp, int yp, int nd, int halfflag) +{ + int i; + BYTE *pTo; + int t; + MICROS *pmt; + WORD *mt; + + app_assert(gpBuffer); + pmt = &dMT2[CalcRot(sx,sy)]; + if (halfflag) { + if (((unsigned)sy < DMAXY) && ((unsigned)sx < DMAXX)) { + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (gnPieceNum) { + pTo = gpBuffer + nBuffWTbl[yp] + xp + 32; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + + mt = &pmt->mt[0]; + + gbPartialTrans = PART_TRANS_RIGHT; + if (gdwPNum = mt[1]) + DrawMTileClipBottom (pTo); + gbPartialTrans = PART_TRANS_NONE; + + pTo -= NBUFFWSL5; + if (gdwPNum = mt[3]) + DrawMTileClipBottom (pTo); + + pTo -= NBUFFWSL5; + if (gdwPNum = mt[5]) + DrawMTileClipBottom (pTo); + + pTo -= NBUFFWSL5; + if (gdwPNum = mt[7]) + DrawMTileClipBottom (pTo); + + pTo -= NBUFFWSL5; + if (gdwPNum = mt[9]) + DrawMTileClipBottom (pTo); + + pTo -= NBUFFWSL5; + if ((gdwPNum = mt[11]) && (leveltype == 4)) + DrawMTileClipBottom (pTo); + + DrawHTLXsub (gpBuffer + nBuffWTbl[yp] + xp, sx, sy, xp, yp, FALSE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawBlankMTile(pTo); + } + } + ++sx; + --sy; + xp += 64; + ++pmt; + --nd; + } + + for (i = nd; i-- && sy >= 0 && sx < DMAXX; ++sx, --sy, xp += 64, ++pmt) { + if (sy >= DMAXY || sx < 0) + continue; + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (!gnPieceNum) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawBlankMTile(pTo); + continue; + } + pTo = gpBuffer + nBuffWTbl[yp] + xp; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + + mt = &pmt->mt[0]; + + gbPartialTrans = PART_TRANS_LEFT; + if (gdwPNum = mt[0]) DrawMTileClipBottom (pTo); + gbPartialTrans = PART_TRANS_RIGHT; + if (gdwPNum = mt[1]) DrawMTileClipBottom (pTo+32); + gbPartialTrans = PART_TRANS_NONE; + for(t = 2; t < MicroTileLen; t += 2) + { + pTo -= NBUFFWSL5; + if (gdwPNum = mt[t]) + DrawMTileClipBottom (pTo); + if (gdwPNum = mt[t+1]) + DrawMTileClipBottom (pTo+32); + } + + DrawHTLXsub (gpBuffer + nBuffWTbl[yp] + xp, sx, sy, xp, yp, TRUE); + } + + if (!halfflag || !((unsigned)sy < DMAXY && (unsigned)sx < DMAXX)) + return; + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (!gnPieceNum) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawBlankMTile(pTo); + return; + } + pTo = gpBuffer + nBuffWTbl[yp] + xp; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &pmt->mt[0]; + gbPartialTrans = PART_TRANS_LEFT; + if (gdwPNum = mt[0]) + DrawMTileClipBottom (pTo); + gbPartialTrans = PART_TRANS_NONE; + pTo -= NBUFFWSL5; + if (gdwPNum = mt[2]) + DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + if (gdwPNum = mt[4]) + DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + if (gdwPNum = mt[6]) + DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + if (gdwPNum = mt[8]) + DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + if ((gdwPNum = mt[10]) && (leveltype == 4)) + DrawMTileClipBottom (pTo); + DrawHTLXsub (gpBuffer + nBuffWTbl[yp] + xp, sx, sy, xp, yp, FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawEFlag2(BYTE *pTo2, int sx, int sy, int sv, int sv2, int xp, int yp) +{ + BYTE *pTo; + long oldnLVal; + BOOL oldnTrans; + int oldPieceNum; + WORD *mt; + + oldnLVal = nLVal; + oldnTrans = nTrans; + oldPieceNum = gnPieceNum; + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + pTo = pTo2 + (NBUFFWSL5 * sv); + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + switch (sv) { + case 0: + if (gdwPNum = mt[2]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[3]) DrawMTileClipBottom (pTo+32); + case 1: + pTo -= NBUFFWSL5; + if (gdwPNum = mt[4]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[5]) DrawMTileClipBottom (pTo+32); + case 2: + pTo -= NBUFFWSL5; + if (gdwPNum = mt[6]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[7]) DrawMTileClipBottom (pTo+32); + case 3: + pTo -= NBUFFWSL5; + if (gdwPNum = mt[8]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[9]) DrawMTileClipBottom (pTo+32); +// case 4: +// pTo -= NBUFFWSL5; +// if (leveltype == 4) { +// if (gdwPNum = mt[10]) DrawMTileClipBottom (pTo); +// if (gdwPNum = mt[11]) DrawMTileClipBottom (pTo+32); +// } + } + + if (sv2 < 8) + DrawHTLXsub2 (pTo2, sx, sy, sv, sv2, xp, yp, FALSE); + nLVal = oldnLVal; + nTrans = oldnTrans; + gnPieceNum = oldPieceNum; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawHTLXsub2 (BYTE *pTo, int sx, int sy, int sv, int sv2, int xp, int yp, BOOL chflag) +{ + char bFlags, bDead, bObject, bItem, bPlayer, bSpecial, bPlayerAbove, bTransVal; + int nMonster, nMonsterAbove; + int pxp,pyp; + + app_assert(sx < MAXDUNX); + app_assert(sy < MAXDUNY); + bFlags = dFlags[sx][sy]; + bDead = dDead[sx][sy]; + bObject = dObject[sx][sy]; + bItem = dItem[sx][sy]; + bPlayer = dPlayer[sx][sy]; + bSpecial = dSpecial[sx][sy]; + bTransVal = dTransVal[sx][sy]; + nMonster = dMonster[sx][sy]; + + app_assert((sy-1) < MAXDUNY); + bPlayerAbove = dPlayer[sx][sy-1]; + nMonsterAbove = dMonster[sx][sy-1]; + + if (visiondebug && (bFlags & BFLAG_VISIBLE)) + CDrawSlabCelP(pTo, pSquareCel, 1, 64, sv2, 8); + if (MissilePreFlag && (bFlags & BFLAG_MISSILE)) + CDrawMissile(sx, sy, xp, yp, sv2, 8, TRUE); + if (nLVal < lightmax) { + if (bDead) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + DeadStruct * pDeadGuy = &dead[(bDead & 0x1f) - 1]; + char dd = (bDead & 0xe0) >> 5; + pxp = xp - pDeadGuy->_deadWidth2; + app_assert(pDeadGuy->_deadData[dd] != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDeadGuy->_deadData[dd] == NULL) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pDeadGuy->_deadFrame < 1 || *reinterpret_cast(pDeadGuy->_deadData[dd]) > MAX_FRAMES + || pDeadGuy->_deadFrame > *reinterpret_cast(pDeadGuy->_deadData[dd])) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Clipped dead sub2: frame %d of %d, deadnum==%d", + pDeadGuy->_deadFrame, + *reinterpret_cast(pDeadGuy->_deadData[dd]), + (bDead & 0x1f) - 1 + ); + #endif + // jcm.patch1.end.1/14/97 + } + #if RLE_DRAW + if (pDeadGuy->_deadtrans) + DrawInfraUnitClipped( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + sv2, + 8, + pDeadGuy->_deadtrans + ); + else + DrawLitUnitClipped( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + sv2, + 8 + ); + #else + if (pDeadGuy->_deadtrans) + CDrawSlabCelI( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + sv2, + 8, + pDeadGuy->_deadtrans + ); + else + CDrawSlabCelL( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + sv2, + 8 + ); + #endif + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bObject) + CDrawObjCel(sx, sy, xp, yp, TRUE, sv2, 8); + } + if (bItem) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + ItemStruct * pItem = &item[bItem - 1]; + if (!pItem->_iPostDraw) { + app_assert(bItem <= MAXITEMS && bItem >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bItem > MAXITEMS || bItem < 0) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Item \"%s\" Clipped 3: NULL Cel Buffer",pItem->_iIName); + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimFrame < 1 || *reinterpret_cast(pItem->_iAnimData) > MAX_FRAMES + || pItem->_iAnimFrame > *reinterpret_cast(pItem->_iAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Draw Clipped \"%s\" Item 3: frame %d of %d, item type==%d", + pItem->_iIName, + pItem->_iAnimFrame, + *reinterpret_cast(pItem->_iAnimData), + pItem->_itype + ); + #endif + // jcm.patch1.end.1/14/97 + } + pxp = xp - pItem->_iAnimWidth2; + if ((bItem - 1) == cursitem + || HighLightAllItems == true) + COutlineSlabCel( + IOUTC, + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + sv2, + 8 + ); + CDrawSlabCelL( + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + sv2, + 8 + ); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_PLRLR) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + int nPlayer = -(bPlayerAbove + 1); + if (nPlayer >= MAX_PLRS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("draw player clipped: tried to draw illegal player %d",nPlayer); + #endif + // jcm.patch1.end.1/14/97 + PlayerStruct * pPlayer = &plr[nPlayer]; + pxp = pPlayer->_pxoff + xp - pPlayer->_pAnimWidth2; + pyp = pPlayer->_pyoff + yp; + CDrawPSlabCelL( + -(bPlayerAbove + 1), + sx, sy-1, + pxp, + pyp, + pPlayer->_pAnimData, + pPlayer->_pAnimFrame, + pPlayer->_pAnimWidth, + sv2, + 8 + ); + if (chflag && pPlayer->_peflag) { + if (pPlayer->_peflag == 2) + DrawEFlag2(pTo-(NBUFFWSL4+96), sx-2, sy+1, sv, sv2, xp-96, yp-16); + DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if ((bFlags & BFLAG_MONSTLR) && ((bFlags & BFLAG_VISIBLE) || (plr[myplr]._pInfraFlag)) && (nMonsterAbove < 0)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + gnMI = -(nMonsterAbove + 1); + if (gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster Clipped: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + MonsterStruct * pMonster = &monster[gnMI]; + if (!(pMonster->_mFlags & MFLAG_INVISIBLE)) { + if (pMonster->MType == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster",pMonster->mName); + #endif + // jcm.patch1.end.1/14/97 + pxp = pMonster->_mxoff + xp - pMonster->MType->mAnimWidth2; + pyp = pMonster->_myoff + yp; + #if RLE_DRAW + if (gnMI == cursmonst) + DrawUnitOutlineClipped( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + sv2, + 8 + ); + #else + if (gnMI == cursmonst) + COutlineSlabCel( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + sv2, + 8 + ); + #endif + CDrawMSlabCelL(sx, sy, pxp, pyp, gnMI, sv2, 8); + if (chflag && !pMonster->_meflag) + DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_DEADPLR) + DrawDeadPlr(sx, sy, xp, yp, sv2, 8, TRUE); + if (bPlayer > 0) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + int nPlayer = bPlayer - 1; + if ((DWORD)nPlayer >= MAX_PLRS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("draw player clipped: tried to draw illegal player %d",nPlayer); + #endif + // jcm.patch1.end.1/14/97 + PlayerStruct * pPlayer = &plr[nPlayer]; + pxp = pPlayer->_pxoff + xp - pPlayer->_pAnimWidth2; + pyp = pPlayer->_pyoff + yp; + CDrawPSlabCelL( + bPlayer - 1, + sx, sy, + pxp, + pyp, + pPlayer->_pAnimData, + pPlayer->_pAnimFrame, + pPlayer->_pAnimWidth, + sv2, + 8 + ); + if (chflag && pPlayer->_peflag) { + if (pPlayer->_peflag == 2) + DrawEFlag2(pTo-(NBUFFWSL4+96), sx-2, sy+1, sv, sv2, xp-96, yp-16); + DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if ((nMonster > 0) && ((bFlags & BFLAG_VISIBLE) || (plr[myplr]._pInfraFlag))) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + gnMI = nMonster - 1; + if ((DWORD)gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster Clipped: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + MonsterStruct * pMonster = &monster[gnMI]; + if (!(pMonster->_mFlags & MFLAG_INVISIBLE)) { + if (pMonster->MType == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster \"%s\" Clipped: uninitialized monster",pMonster->mName); + #endif + // jcm.patch1.end.1/14/97 + pxp = pMonster->_mxoff + xp - pMonster->MType->mAnimWidth2; + pyp = pMonster->_myoff + yp; + #if RLE_DRAW + if (gnMI == cursmonst) + DrawUnitOutlineClipped( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + sv2, + 8 + ); + #else + if (gnMI == cursmonst) + COutlineSlabCel( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + sv2, + 8 + ); + #endif + CDrawMSlabCelL(sx, sy, pxp, pyp, gnMI, sv2, 8); + if (chflag && !pMonster->_meflag) + DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_MISSILE) + CDrawMissile(sx, sy, xp, yp, sv2, 8, FALSE); + if (bObject && (nLVal < lightmax)) + CDrawObjCel(sx, sy, xp, yp, FALSE, sv2, 8); + if (bItem) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + ItemStruct * pItem = &item[bItem - 1]; + if (pItem->_iPostDraw) { + app_assert(bItem <= MAXITEMS && bItem >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bItem > MAXITEMS || bItem < 0) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Item \"%s\" Clipped 4: NULL Cel Buffer",pItem->_iIName); + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimFrame < 1 || *reinterpret_cast(pItem->_iAnimData) > MAX_FRAMES + || pItem->_iAnimFrame > *reinterpret_cast(pItem->_iAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Draw Clipped \"%s\" Item 4: frame %d of %d, item type==%d", + pItem->_iIName, + pItem->_iAnimFrame, + *reinterpret_cast(pItem->_iAnimData), + pItem->_itype + ); + #endif + // jcm.patch1.end.1/14/97 + } + pxp = xp - pItem->_iAnimWidth2; + if ((bItem - 1) == cursitem + || HighLightAllItems == true) + COutlineSlabCel( + IOUTC, + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + sv2, + 8 + ); + CDrawSlabCelL( + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + sv2, + 8 + ); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bSpecial) { + nTrans = TransList[bTransVal]; + TCDrawSlabCelPL(pTo, pSpecialCels, bSpecial, 64, sv2, 8); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawHTLX2 (int sx, int sy, int xp, int yp, int nd, int sv, int halfflag) +{ + int i; + BYTE *pTo; + int sv2; + int t; + MICROS *pmt; + WORD *mt; + + app_assert(gpBuffer); + pmt = &dMT2[CalcRot(sx,sy)]; + sv2 = (sv + 1) << 1; + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (gnPieceNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5 + 32; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &pmt->mt[0]; + + for(t = 0; t < ((MicroTileLen>>1)-1); ++t) + { + if ((sv <= t) && (gdwPNum = mt[2*t+3])) DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + } + if (sv2 < 8) { + pTo = gpBuffer + nBuffWTbl[yp] + xp - (NBUFFWSL4 * sv2); + DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, FALSE); + } + } + } + ++sx; + --sy; + xp += 64; + --nd; + ++pmt; + } + + for (i = nd; i-- && sx < DMAXX && sy >= 0; ++sx, --sy, xp += 64, ++pmt) { + if (sy >= DMAXY || sx < 0) + continue; + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (!gnPieceNum) + continue; + pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &pmt->mt[0]; + for(t = 0; t < ((MicroTileLen>>1)-1); ++t, pTo -= NBUFFWSL5) + { + if (sv > t) + continue; + if (gdwPNum = mt[2*t + 2]) + DrawMTileClipBottom (pTo); + if (gdwPNum = mt[2*t + 3]) + DrawMTileClipBottom (pTo+32); + } + + if (sv2 >= 8) + continue; + pTo = gpBuffer + nBuffWTbl[yp] + xp - (NBUFFWSL5 * (sv + 1)); + DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, TRUE); + } + + if (!halfflag || !(static_cast(sy) < DMAXY && static_cast(sx) < DMAXX)) + return; + + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + + if (!gnPieceNum) + return; + pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &pmt->mt[0]; + + for(t = 0; t < ((MicroTileLen>>1)-1); ++t) + { + if ((sv <= t) && (gdwPNum = mt[2*t+2])) DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + } + + if (sv2 < 8) { + pTo = gpBuffer + nBuffWTbl[yp] + xp - (NBUFFWSL4 * sv2); + DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, FALSE); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawEFlag3(BYTE *pTo2, int sx, int sy, int ev, int ev2, int xp, int yp) +{ + BYTE *pTo; + long oldnLVal; + BOOL oldnTrans; + int oldPieceNum; + int t; + WORD *mt; + + oldnLVal = nLVal; + oldnTrans = nTrans; + oldPieceNum = gnPieceNum; + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + pTo = pTo2; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + gbPartialTrans = PART_TRANS_LEFT; + if (gdwPNum = mt[0]) DrawMTileClipTop (pTo); + gbPartialTrans = PART_TRANS_RIGHT; + if (gdwPNum = mt[1]) DrawMTileClipTop (pTo+32); + gbPartialTrans = PART_TRANS_NONE; + for(t = 1; t < ((MicroTileLen>>1)-1); ++t) + { + pTo -= NBUFFWSL5; + if (ev >= t) { + if (gdwPNum = mt[2*t]) DrawMTileClipTop (pTo); + if (gdwPNum = mt[2*t+1]) DrawMTileClipTop (pTo+32); + } + } + + DrawHTLXsub3 (pTo2, sx, sy, ev, ev2, xp, yp, FALSE); + + nLVal = oldnLVal; + nTrans = oldnTrans; + gnPieceNum = oldPieceNum; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawHTLXsub3 (BYTE *pTo, int sx, int sy, int ev, int ev2, int xp, int yp, BOOL chflag) +{ + char bFlags, bDead, bObject, bItem, bPlayer, bSpecial, bPlayerAbove, bTransVal; + int nMonster, nMonsterAbove; + int pxp,pyp; + + app_assert(sx < MAXDUNX); + app_assert(sy < MAXDUNY); + bFlags = dFlags[sx][sy]; + bDead = dDead[sx][sy]; + bObject = dObject[sx][sy]; + bItem = dItem[sx][sy]; + bPlayer = dPlayer[sx][sy]; + bSpecial = dSpecial[sx][sy]; + bTransVal = dTransVal[sx][sy]; + nMonster = dMonster[sx][sy]; + + app_assert((sy-1) < MAXDUNY); + bPlayerAbove = dPlayer[sx][sy-1]; + nMonsterAbove = dMonster[sx][sy-1]; + + if (visiondebug && (bFlags & BFLAG_VISIBLE)) + DrawSlabCelP(pTo, pSquareCel, 1, 64, 0, ev2); + if (MissilePreFlag && (bFlags & BFLAG_MISSILE)) + DrawMissile(sx, sy, xp, yp, 0, ev2, TRUE); + if (nLVal < lightmax) { + if (bDead) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + DeadStruct * pDeadGuy = &dead[(bDead & 0x1f) - 1]; + char dd = (bDead & 0xe0) >> 5; + pxp = xp - pDeadGuy->_deadWidth2; + app_assert(pDeadGuy->_deadData[dd] != NULL); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (pDeadGuy->_deadData[dd] == NULL) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pDeadGuy->_deadFrame < 1 || *reinterpret_cast(pDeadGuy->_deadData[dd]) > MAX_FRAMES + || pDeadGuy->_deadFrame > *reinterpret_cast(pDeadGuy->_deadData[dd])) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Unclipped dead: frame %d of %d, deadnum==%d", + pDeadGuy->_deadFrame, + *reinterpret_cast(pDeadGuy->_deadData[dd]), + (bDead & 0x1f) - 1 + ); + #endif + // jcm.patch1.end.1/14/97 + } + #if RLE_DRAW + if (pDeadGuy->_deadtrans) + DrawInfraUnit( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + ev2,//diff + pDeadGuy->_deadtrans + ); + else + DrawLitUnit( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + ev2//diff + ); + #else + if (pDeadGuy->_deadtrans) + DrawSlabCelI( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + ev2,//diff + pDeadGuy->_deadtrans + ); + else + DrawSlabCelL( + pxp, + yp, + pDeadGuy->_deadData[dd], + pDeadGuy->_deadFrame, + pDeadGuy->_deadWidth, + 0, + ev2//diff + ); + #endif + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bObject) + DrawObjCel(sx, sy, xp, yp, TRUE, 0, ev2);//diff + } + if (bItem) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + ItemStruct * pItem = &item[bItem - 1]; + if (!pItem->_iPostDraw) { + app_assert(bItem <= MAXITEMS && bItem >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bItem > MAXITEMS || bItem < 0) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Item \"%s\" 1: NULL Cel Buffer",pItem->_iIName); + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimFrame < 1 || *reinterpret_cast(pItem->_iAnimData) > MAX_FRAMES + || pItem->_iAnimFrame > *reinterpret_cast(pItem->_iAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Draw \"%s\" Item 1: frame %d of %d, item type==%d", + pItem->_iIName, + pItem->_iAnimFrame, + *reinterpret_cast(pItem->_iAnimData), + pItem->_itype + ); + #endif + // jcm.patch1.end.1/14/97 + } + pxp = xp - pItem->_iAnimWidth2; + if ((bItem - 1) == cursitem + || HighLightAllItems == true) + OutlineSlabCel( + IOUTC, + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + ev2//diff + ); + DrawSlabCelL( + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + ev2//diff + ); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_PLRLR) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + int nPlayer = -(bPlayerAbove + 1); + if (nPlayer >= MAX_PLRS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("draw player: tried to draw illegal player %d",nPlayer); + #endif + // jcm.patch1.end.1/14/97 + PlayerStruct * pPlayer = &plr[nPlayer]; + pxp = pPlayer->_pxoff + xp - pPlayer->_pAnimWidth2; + pyp = pPlayer->_pyoff + yp; + DrawPSlabCelL( + -(bPlayerAbove + 1), + sx, sy-1, + pxp, + pyp, + pPlayer->_pAnimData, + pPlayer->_pAnimFrame, + pPlayer->_pAnimWidth, + 0, + ev2//diff + ); + if (chflag && pPlayer->_peflag) { + if (pPlayer->_peflag == 2) + DrawEFlag3(pTo-(NBUFFWSL4+96), sx-2, sy+1, ev, ev2, xp-96, yp-16); + DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if ((bFlags & BFLAG_MONSTLR) && ((bFlags & BFLAG_VISIBLE) || plr[myplr]._pInfraFlag) && (nMonsterAbove < 0)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + gnMI = -(nMonsterAbove + 1); + if (gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + MonsterStruct * pMonster = &monster[gnMI]; + if (!(pMonster->_mFlags & MFLAG_INVISIBLE)) { + if (pMonster->MType == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster \"%s\": uninitialized monster",pMonster->mName); + #endif + // jcm.patch1.end.1/14/97 + pxp = pMonster->_mxoff + xp - pMonster->MType->mAnimWidth2; + pyp = pMonster->_myoff + yp; + #if RLE_DRAW + if (gnMI == cursmonst) + DrawUnitOutline( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + ev2 + ); + #else + if (gnMI == cursmonst) + OutlineSlabCel( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + ev2 + ); + #endif + DrawMSlabCelL(sx, sy, pxp, pyp, gnMI, 0, ev2); + if (chflag && !pMonster->_meflag) + DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_DEADPLR) + DrawDeadPlr(sx, sy, xp, yp, 0, ev2, FALSE); + if (bPlayer > 0) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + int nPlayer = bPlayer - 1; + if (nPlayer >= MAX_PLRS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("draw player: tried to draw illegal player %d",nPlayer); + #endif + // jcm.patch1.end.1/14/97 + PlayerStruct * pPlayer = &plr[nPlayer]; + pxp = pPlayer->_pxoff + xp - pPlayer->_pAnimWidth2; + pyp = pPlayer->_pyoff + yp; + DrawPSlabCelL( + bPlayer - 1, + sx, sy, + pxp, + pyp, + pPlayer->_pAnimData, + pPlayer->_pAnimFrame, + pPlayer->_pAnimWidth, + 0, + ev2 + ); + if (chflag && pPlayer->_peflag) { + if (pPlayer->_peflag == 2) + DrawEFlag3(pTo-(NBUFFWSL4+96), sx-2, sy+1, ev, ev2, xp-96, yp-16); + DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if ((nMonster > 0) && ((bFlags & BFLAG_VISIBLE) || (plr[myplr]._pInfraFlag))) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + gnMI = nMonster - 1; + if ((DWORD)gnMI >= MAXMONSTERS) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster: tried to draw illegal monster %d",gnMI); + #endif + // jcm.patch1.end.1/14/97 + MonsterStruct * pMonster = &monster[gnMI]; + if (!(pMonster->_mFlags & MFLAG_INVISIBLE)) { + if (pMonster->MType == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Monster \"%s\": uninitialized monster",pMonster->mName); + #endif + // jcm.patch1.end.1/14/97 + pxp = pMonster->_mxoff + xp - pMonster->MType->mAnimWidth2; + pyp = pMonster->_myoff + yp; + #if RLE_DRAW + if (gnMI == cursmonst) + DrawUnitOutline( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + ev2 + ); + #else + if (gnMI == cursmonst) + OutlineSlabCel( + MOUTC, + pxp, + pyp, + pMonster->_mAnimData, + pMonster->_mAnimFrame, + pMonster->MType->mAnimWidth, + 0, + ev2 + ); + #endif + DrawMSlabCelL(sx, sy, pxp, pyp, gnMI, 0, ev2); + if (chflag && !pMonster->_meflag) + DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bFlags & BFLAG_MISSILE) + DrawMissile(sx, sy, xp, yp, 0, ev2, FALSE); + if (bObject && (nLVal < lightmax)) + DrawObjCel(sx, sy, xp, yp, FALSE, 0, ev2); + if (bItem) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + do { + #endif + // jcm.patch1.end.1/14/97 + ItemStruct * pItem = &item[bItem - 1]; + if (pItem->_iPostDraw) { + app_assert(bItem <= MAXITEMS && bItem >= 0); + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + if (bItem > MAXITEMS || bItem < 0) + break; + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimData == NULL) + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal("Draw Item \"%s\" 2: NULL Cel Buffer",pItem->_iIName); + #endif + // jcm.patch1.end.1/14/97 + if (pItem->_iAnimFrame < 1 || *reinterpret_cast(pItem->_iAnimData) > MAX_FRAMES + || pItem->_iAnimFrame > *reinterpret_cast(pItem->_iAnimData)) { + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + break; + #else + app_fatal( + "Draw \"%s\" Item 2: frame %d of %d, item type==%d", + pItem->_iIName, + pItem->_iAnimFrame, + *reinterpret_cast(pItem->_iAnimData), + pItem->_itype + ); + #endif + // jcm.patch1.end.1/14/97 + } + pxp = xp - pItem->_iAnimWidth2; + if ((bItem - 1) == cursitem + || HighLightAllItems == true) + OutlineSlabCel( + IOUTC, + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + ev2 + ); + DrawSlabCelL( + pxp, + yp, + pItem->_iAnimData, + pItem->_iAnimFrame, + pItem->_iAnimWidth, + 0, + ev2 + ); + } + // jcm.patch1.start.1/14/97 + #ifdef GRACEFUL_EXIT + } while (0); + #endif + // jcm.patch1.end.1/14/97 + } + if (bSpecial) { + nTrans = TransList[bTransVal]; + TDrawSlabCelPL(pTo, pSpecialCels, bSpecial, 64, 0, ev2); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void DrawHTLX3 (int sx, int sy, int xp, int yp, int nd, int ev, int halfflag) +{ + int i; + BYTE *pTo; + int ev2; + int t; + MICROS *pmt; + WORD *mt; + + app_assert(gpBuffer); + pmt = &dMT2[CalcRot(sx,sy)]; + ev2 = (ev + 1) << 1; + if (ev2 > 8) ev2 = 8; + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (gnPieceNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp + 32; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &pmt->mt[0]; + if ((ev >= 0) && (gdwPNum = mt[1])) { + gbPartialTrans = PART_TRANS_RIGHT; + DrawMTileClipTop (pTo); + gbPartialTrans = PART_TRANS_NONE; + } + pTo -= NBUFFWSL5; + if ((ev >= 1) && (gdwPNum = mt[3])) + DrawMTileClipTop (pTo); + pTo -= NBUFFWSL5; + if ((ev >= 2) && (gdwPNum = mt[5])) + DrawMTileClipTop (pTo); + pTo -= NBUFFWSL5; + if ((ev >= 3) && (gdwPNum = mt[7])) + DrawMTileClipTop (pTo); + //pTo -= NBUFFWSL5; + //if ((ev >= 4) && (gdwPNum = mt[9]) && (leveltype == 4)) DrawMTileClipTop (pTo); + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, FALSE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawBlankMTile(pTo); + } + } + ++sx; + --sy; + xp += 64; + --nd; + ++pmt; + } + + for (i = 0; i < nd; ++i) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (gnPieceNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &pmt->mt[0]; + + gbPartialTrans = PART_TRANS_LEFT; + if (gdwPNum = mt[0]) DrawMTileClipTop (pTo); + gbPartialTrans = PART_TRANS_RIGHT; + if (gdwPNum = mt[1]) DrawMTileClipTop (pTo+32); + gbPartialTrans = PART_TRANS_NONE; + for(t = 1; t < ((MicroTileLen>>1)-1); ++t) + { + pTo -= NBUFFWSL5; + if (ev >= t) { + if (gdwPNum = mt[2*t]) DrawMTileClipTop (pTo); + if (gdwPNum = mt[2*t+1]) DrawMTileClipTop (pTo+32); + } + } + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, TRUE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawBlankMTile(pTo); + } + } + ++sx; + --sy; + xp += 64; + ++pmt; + } + + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gnPieceNum = dPiece[sx][sy]; + nLVal = dLight[sx][sy]; + if (gnPieceNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + nTrans = TransList[dTransVal[sx][sy]] & nTransTable[gnPieceNum]; + mt = &pmt->mt[0]; + + gbPartialTrans = PART_TRANS_LEFT; + if ((ev >= 0) && (gdwPNum = mt[0])) DrawMTileClipTop (pTo); + gbPartialTrans = PART_TRANS_NONE; + pTo -= NBUFFWSL5; + if ((ev >= 1) && (gdwPNum = mt[2])) DrawMTileClipTop (pTo); + pTo -= NBUFFWSL5; + if ((ev >= 2) && (gdwPNum = mt[4])) DrawMTileClipTop (pTo); + pTo -= NBUFFWSL5; + if ((ev >= 3) && (gdwPNum = mt[6])) DrawMTileClipTop (pTo); + //pTo -= NBUFFWSL5; + //if ((ev >= 4) && (gdwPNum = mt[8]) && (leveltype == 4)) DrawMTileClipTop (pTo); + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, FALSE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + DrawBlankMTile(pTo); + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void SVGADrawView(int StartX, int StartY) +{ + int xpos, ypos; + int i; + int width,height; + + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + + xpos = 64 + ScrollInfo._sxoff; + ypos = 175 + ScrollInfo._syoff; + StartX -= 10; + StartY -= 1; + width = 10; + height = 8; + + if (chrflag || questlog) { + StartX += 2; + StartY -= 2; + xpos += 288; + width = 6; + } + if (invflag || sbookflag) { + StartX += 2; + StartY -= 2; + xpos -= 32; + width = 6; + } + + switch (ScrollInfo._sdir) { + case SCRL_UR : + ++width; + case SCRL_U : + ypos -= 32; + --StartX; + --StartY; + height; + break; + case SCRL_DR : + ++height; + case SCRL_R : + ++width; + break; + case SCRL_D : + ++height; + break; + case SCRL_DL : + ++height; + case SCRL_L : + xpos -= 64; + --StartX; + ++StartY; + ++width; + break; + case SCRL_UL : + xpos -= 64; + ypos -= 32; + StartX -= 2; + ++width; + ++height; + break; +// case SCRL_NONE : + } + + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[160]; + for (i = 0; i < 4; ++i) { + DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 0); + ++StartY; + xpos -= 32; + ypos += 16; + DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 1); + ++StartX; + xpos += 32; + ypos += 16; + } + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[512]; + for (i = 0; i < height; ++i) { + DrawHTileLineX(StartX, StartY, xpos, ypos, width, 0); + ++StartY; + xpos -= 32; + ypos += 16; + DrawHTileLineX(StartX, StartY, xpos, ypos, width, 1); + ++StartX; + xpos += 32; + ypos += 16; + } + gbPartialTrans = PART_TRANS_NONE; + for (i = 0; i < 4; ++i) { + DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 0); + ++StartY; + xpos -= 32; + ypos += 16; + DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 1); + ++StartX; + xpos += 32; + ypos += 16; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void VGADrawView (int StartX, int StartY) +{ + int xpos, ypos; + int i; + int width,height; + long csrc, cdest, cw; + + ViewDX = 384; + ViewDY = 192; + ViewBX = 6; + ViewBY = 6; + + xpos = 64 + ScrollInfo._sxoff; + ypos = 143 + ScrollInfo._syoff; + StartX -= 6; + StartY -= 1; + width = 6; + height = 3; + + switch (ScrollInfo._sdir) { + case SCRL_UR : + ++width; + case SCRL_U : + ypos -= 32; + --StartX; + --StartY; + ++height; + break; + case SCRL_DR : + ++height; + case SCRL_R : + ++width; + break; + case SCRL_D : + ++height; + break; + case SCRL_DL : + ++height; + case SCRL_L : + xpos -= 64; + --StartX; + ++StartY; + ++width; + break; + case SCRL_UL : + xpos -= 64; + ypos -= 32; + StartX -= 2; + ++width; + ++height; +// case SCRL_NONE : + } + + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[143]; + for (i = 0; i < 4; ++i) { + DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 0); + ++StartY; + xpos -= 32; + ypos += 16; + DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 1); + ++StartX; + xpos += 32; + ypos += 16; + } + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[320]; + for (i = 0; i < height; ++i) { + DrawHTileLineX(StartX, StartY, xpos, ypos, width, 0); + ++StartY; + xpos -= 32; + ypos += 16; + DrawHTileLineX(StartX, StartY, xpos, ypos, width, 1); + ++StartX; + xpos += 32; + ypos += 16; + } + gbPartialTrans = PART_TRANS_NONE; + for (i = 0; i < 4; ++i) { + DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 0); + ++StartY; + xpos -= 32; + ypos += 16; + DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 1); + ++StartX; + xpos += 32; + ypos += 16; + } + + if (chrflag || questlog) { + csrc = 245168; + cdest = 392064; + cw = 160; + } else { + if (invflag || sbookflag) { + csrc = 245168; + cdest = 391744; + cw = 160; + } else { + csrc = 245088; + cdest = 391744; + cw = 320; + } + } + // Double res copy + app_assert(gpBuffer); + __asm { + mov esi,[gpBuffer] + mov edx,[cdest] + mov edi,esi + mov ecx,[csrc] + add edi,edx + add esi,ecx + mov ebx,edi + add ebx,768 + + mov edx,176 +_YLp: + mov ecx,[cw] +_XLp: + mov al,[esi] + inc esi + mov ah,al + mov [edi],ax + mov [ebx],ax + add edi,2 + add ebx,2 + dec ecx + jnz _XLp + mov eax,768 + add eax,[cw] + sub esi,eax + add eax,eax + sub ebx,eax + sub edi,eax + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawView(int StartX, int StartY) +{ + app_assert(gpBuffer); +/* __asm { + mov edi,dword ptr [gpBuffer] + add edi,122944 + + mov edx,352 + mov eax,092929292h // yellow + //xor eax,eax // black +_YLp: mov ecx,160 + rep stosd + add edi,128 + dec edx + jnz _YLp + }*/ + + if (svgamode) SVGADrawView (StartX, StartY); + else VGADrawView (StartX, StartY); + if (automapflag) DrawAutomap(); + + if (invflag) DrawInv(); + else if (sbookflag) DrawSpellBook(); + + DrawDurIcon(); + + if (chrflag) DrawChr(); + else if (questlog) DrawQuestLog(); + else if ((plr[myplr]._pStatPts != 0) && (!spselflag)) DrawLevelUpIcon(); + + if (uitemflag) DrawUniqueInfo(); + if (qtextflag) DrawQText(); + if (spselflag) DrawSpellList(); + if (dropGoldFlag) DrawGoldBox(dropGoldValue); + if (helpflag) DrawHelp(); + if (msgflag) DrawDiabloMsg(); + if (deathflag) RedBack(); + else if (PauseMode) DrawPause(); + + plrmsg_draw(); + + gmenu_draw(); + + DrawMapOfDoom(); + + DrawInfoBox(); + DrawHealthTop(); + DrawManaTop(); + + /* TEMP! ONLY ENABLE FOR TESTING + if (automapflag) { + if (leveltype == 1) + DrawDungMiniMap(22); + if (leveltype == 2) + DrawDungMiniMap(12); + if (leveltype == 3) + DrawDungMiniMap(8); + if (leveltype == 4) + DrawDungMiniMap(30); + } + TEMP! ONLY ENABLE FOR TESTING */ +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ClrDraw() +{ + // Clear drawing area with solid color to detect transparency problems + lock_buf(3); + app_assert(gpBuffer); + __asm { + mov edi,dword ptr [gpBuffer] + add edi,122944 + + mov edx,480 + xor eax,eax // black +_YLp: mov ecx,160 + rep stosd + add edi,128 + dec edx + jnz _YLp + } + unlock_buf(3); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckForScroll () +{ + if (curs >= ICSTART) return; + + BOOL bScrollUpdate = FALSE; + if (MouseX < 20) { + if ((ViewY < (dmaxy - 1)) && (ViewX > dminx)) { + ++ViewY; + --ViewX; + bScrollUpdate = TRUE; + } else { + if (ViewY < (dmaxy - 1)) { + ++ViewY; + bScrollUpdate = TRUE; + } + if (ViewX > dminx) { + --ViewX; + bScrollUpdate = TRUE; + } + } + } + + if (MouseX > 620) { + if ((ViewX < (dmaxx - 1)) && (ViewY > dminy)) { + --ViewY; + ++ViewX; + bScrollUpdate = TRUE; + } else { + if (ViewX < (dmaxx - 1)) { + ++ViewX; + bScrollUpdate = TRUE; + } + if (ViewY > dminy) { + ViewY--; + bScrollUpdate = TRUE; + } + } + } + + if (MouseY < 20) { + if ((ViewY > dminy) && (ViewX > dminx)) { + --ViewX; + --ViewY; + bScrollUpdate = TRUE; + } else { + if (ViewY > dminy) { + --ViewY; + bScrollUpdate = TRUE; + } + if (ViewX > dminx) { + --ViewX; + bScrollUpdate = TRUE; + } + } + } + + if (MouseY > 460) { + if ((ViewY < (dmaxy - 1)) && (ViewX < (dmaxx - 1))) { + ++ViewX; + ++ViewY; + bScrollUpdate = TRUE; + } else { + if (ViewY < (dmaxy - 1)) { + ++ViewY; + bScrollUpdate = TRUE; + } + if (ViewX < (dmaxx - 1)) { + ++ViewX; + bScrollUpdate = TRUE; + } + } + } + + if (bScrollUpdate) + ScrollInfo._sdir = SCRL_NONE; +} + + +//******************************************************************* +//******************************************************************* +#ifndef NDEBUG +void toggle_frame_counter() { + sgfFrameCounterEnabled = !sgfFrameCounterEnabled; + sgnLastFrame = GetTickCount(); +} +#endif + + +//******************************************************************* +//******************************************************************* +#ifndef NDEBUG +static void draw_frame_rate() { + if (!sgfFrameCounterEnabled) + return; + // don't write stuff if we're not the active application + if (! bActive) + return; + + static int snFrameCount = 0; + static int nFrameRate = 0; + int nTimeSpent; + char szFrameRate[10]; + DWORD nThisFrame; + HDC hDC; + + ++snFrameCount; + nThisFrame = GetTickCount(); + //give a 1 second average frame rate + if (nThisFrame - sgnLastFrame >= 1000) { + nTimeSpent = nThisFrame - sgnLastFrame; + sgnLastFrame = nThisFrame; + nFrameRate = (snFrameCount*1000)/nTimeSpent; + snFrameCount = 0; + } + + if (nFrameRate > 99) nFrameRate = 99; + wsprintf(szFrameRate, "%2d", nFrameRate); + HRESULT ddr = lpDDSPrimary->GetDC(&hDC); + if (ddr != DD_OK) return; + TextOut(hDC,0,400,szFrameRate,strlen(szFrameRate)); + lpDDSPrimary->ReleaseDC(hDC); +} +#endif + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define BUFFER_STARTX 64 +#define BUFFER_STARTY 160 +static DDSURFACEDESC sgDDSD; +extern LPDIRECTDRAWSURFACE lpDDSBackBuf; +static void DDBlit(DWORD dwX,DWORD dwY,DWORD dwWdt,DWORD dwHgt) { + + app_assert(! (dwX & 3)); + app_assert(! (dwWdt & 3)); + + // if we have a back buffer, it is because we cannot lock the + // primary surface. Use BltFast to avoid locking problem + if (lpDDSBackBuf) { + HRESULT ddrval; + RECT r; + r.left = dwX + BUFFER_STARTX; + r.top = dwY + BUFFER_STARTY; + r.right = r.left + dwWdt - 1; + r.bottom = r.top + dwHgt - 1; + + // make sure nobody is holding a lock on back surface + // because we wouldn't be able to BltFast + app_assert(! gpBuffer); + + DWORD dwStartTime = GetTickCount(); + while (1) { + // perform draw + #if LOCK_WAIT + ddrval = lpDDSPrimary->BltFast(dwX,dwY,lpDDSBackBuf,&r,DDBLTFAST_WAIT); + #else + ddrval = lpDDSPrimary->BltFast(dwX,dwY,lpDDSBackBuf,&r,0); + #endif + if (ddrval == DD_OK) break; + + // fatal if we've waited a long time for surface + if (dwStartTime - GetTickCount() > 5*1000) break; + + #if LOCK_SLEEP + Sleep(LOCK_SLEEP); + #endif + + // hey, we just checked a second ago, and we still + // had our surface -- try to get it next time + if (ddrval == DDERR_SURFACELOST) return; + + // handle errors related to another thread locking surface + if (ddrval == DDERR_WASSTILLDRAWING) continue; + if (ddrval == DDERR_SURFACEBUSY) continue; + + // other errors -- fatal + break; + } + + if (ddrval == DDERR_SURFACELOST) return; + if (ddrval == DDERR_WASSTILLDRAWING) return; + if (ddrval == DDERR_SURFACEBUSY) return; + ddraw_assert(ddrval); + return; + } + + LONG lSrcOff = (dwY + BUFFER_STARTY) * BUFFERX + dwX + BUFFER_STARTX; + LONG lDstOff = dwY * sgDDSD.lPitch + dwX; + LONG lSrcMod = BUFFERX - dwWdt; + LONG lDstMod = sgDDSD.lPitch - dwWdt; + dwWdt >>= 2; + lock_buf(6); + app_assert(gpBuffer); + __asm { + mov esi, [gpBuffer] + mov edi, [sgDDSD.lpSurface] + add esi, [lSrcOff] + add edi, [lDstOff] + mov eax, [lSrcMod] + mov ebx, [lDstMod] + mov edx, [dwHgt] + lpdword: + mov ecx, [dwWdt] + rep movsd + add esi, eax + add edi, ebx + dec edx + jnz lpdword + } + unlock_buf(6); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void DirectDrawBlt( + long ysize, + BOOL tbox, + BOOL hp, + BOOL mana, + BOOL spdbar, + BOOL btns +) { + HRESULT ddrval; + + // don't redraw if we aren't the active application + if (! bActive) return; + + // don't redraw if we don't have a direct draw buffer + if (! lpDDSPrimary) return; + + // make sure primary surface is still in video memory + if (lpDDSPrimary->IsLost() == DDERR_SURFACELOST) { + ddrval = lpDDSPrimary->Restore(); + if (ddrval != DD_OK) return; + void ResetPal(); + ResetPal(); + + // force redraw of everything + ysize = TOTALY; + } + + // lock the surface if we have to manually blit + if (! lpDDSBackBuf) { + BOOL bReinit = TRUE; + DWORD dwStartTime = GetTickCount(); + while (1) { + // try to lock the surface + sgDDSD.dwSize = sizeof(sgDDSD); + #if LOCK_WAIT + ddrval = lpDDSPrimary->Lock(NULL,&sgDDSD,DDLOCK_WAIT | DDLOCK_WRITEONLY,NULL); + #else + ddrval = lpDDSPrimary->Lock(NULL,&sgDDSD,DDLOCK_WRITEONLY,NULL); + #endif + if (ddrval == DD_OK) break; + + // fatal if we've waited a long time for surface + if (dwStartTime - GetTickCount() > 5*1000) break; + + #if LOCK_SLEEP + Sleep(LOCK_SLEEP); + #endif + + // hey, we just checked a second ago, and we still + // had our surface -- try to get it next time + if (ddrval == DDERR_SURFACELOST) return; + + // handle errors related to another thread locking surface + if (ddrval == DDERR_WASSTILLDRAWING) continue; + if (ddrval == DDERR_SURFACEBUSY) continue; + + // this is to fix a bug when user switches to a different + // screen mode in another app. In windows NT, a DOS app + // switching to Mode 0x13 will cause a DDERR_GENERIC in + // this app when it is restored + if (bReinit && ddrval == DDERR_GENERIC) { + bReinit = FALSE; + void ddraw_reinit(); + ddraw_reinit(); + ysize = TOTALY; + dwStartTime = GetTickCount(); + continue; + } + + // other errors -- fatal + break; + } + + // handle errors related to another thread locking surface + if (ddrval == DDERR_SURFACELOST) return; + if (ddrval == DDERR_WASSTILLDRAWING) return; + if (ddrval == DDERR_SURFACEBUSY) return; + + ddraw_assert(ddrval); + } + + app_assert(ysize >= 0 && ysize <= 480); + + if (ysize > 0) { + // blit main game area + DDBlit(0,0,160*4,ysize); // X is divisible by 4 + } + + if (ysize < TOTALY) { + if (spdbar) { + // speed bar + // DDBlit(205,357,58*4,28); + DDBlit(204,357,58*4,28); // X is divisible by 4 + } + + if (tbox) { + // text box + // DDBlit(177,398,72*4,60); + DDBlit(176,398,72*4,60); // X is divisible by 4 + } + + if (mana) { + // mana bar + // DDBlit(461,352,22*4,72); + DDBlit(460,352,22*4,72); // X is divisible by 4 + + // spell icon + // DDBlit(565,416,14*4,56); + DDBlit(564,416,14*4,56); // X is divisible by 4 + } + + if (hp) { + // hitpoint bar + DDBlit(96,352,22*4,72); // X is divisible by 4 + } + + if (btns) { + // buttons on left side + // DDBlit(11,357,18*4,119); + DDBlit(8,357,18*4,119); // X is divisible by 4 + + // buttons on right side + // DDBlit(558,357,18*4,42); + DDBlit(556,357,18*4,48); // X is divisible by 4 + + if (gbMaxPlayers > 1) { + // "chat" button + // DDBlit(87,443,9*4,32); + DDBlit(84,443,9*4,32); // X is divisible by 4 + + // "friendly" button + // DDBlit(527,443,9*4,32); + DDBlit(524,443,9*4,32); // X is divisible by 4 + } + } + + if (sgdwOldWdt) { + DDBlit(sgdwOldX,sgdwOldY,sgdwOldWdt,sgdwOldHgt); + } + if (sgdwCursWdt) { + DDBlit(sgdwCursX,sgdwCursY,sgdwCursWdt,sgdwCursHgt); + } + + } + + if (! lpDDSBackBuf) { + // in NT, it is possible for us to lose the surface + // even when it is locked! + ddrval = lpDDSPrimary->Unlock(NULL); + if (ddrval != DDERR_SURFACELOST) + ddraw_assert(ddrval); + } + + #ifndef NDEBUG + draw_frame_rate(); + #endif +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FullBlit(BOOL bArrow) { + int y; + if (force_redraw == FULLDRAW) { + force_redraw = NODRAW; + y = TOTALY; + } + else { + y = 0; + } + + if (bArrow) { + lock_buf(0); + savecrsr_show(); + unlock_buf(0); + } + + DirectDrawBlt(y, FALSE, FALSE, FALSE, FALSE, FALSE); + + if (bArrow) { + lock_buf(0); + savecrsr_hide(); + unlock_buf(0); + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +extern BOOL gbRunGame; + +void DrawAndBlit(void) { + BOOL tBox; + BOOL ctrlPan; + long ysize; + + if (! gbRunGame) return; + + if (force_redraw == FULLDRAW) { + drawhpflag = TRUE; + drawmanaflag = TRUE; + drawbtnflag = TRUE; + drawsbarflag = TRUE; + tBox = FALSE; + ctrlPan = TRUE; + ysize = TOTALY; + } + else if (force_redraw == VIEWDRAW) { + tBox = TRUE; + ctrlPan = FALSE; + ysize = GAMEY; + } + else { + return; + } + force_redraw = NODRAW; + + lock_buf(0); + if (leveltype) DrawView(ViewX, ViewY); + else T_DrawView(ViewX, ViewY); + if (ctrlPan) DrawCtrlPan(); + if (drawhpflag) DrawHealthBar(); + if (drawmanaflag) DrawManaBar(); + if (drawbtnflag) DrawButtons(); + if (drawsbarflag) DrawSpdBar(); + if (talkflag) { + DrawTalkBox(); + ysize = TOTALY; + } + savecrsr_show(); + unlock_buf(0); + + DirectDrawBlt(ysize, tBox, drawhpflag, drawmanaflag, drawsbarflag, drawbtnflag); + + lock_buf(0); + savecrsr_hide(); + unlock_buf(0); + + drawhpflag = FALSE; + drawmanaflag = FALSE; + drawbtnflag = FALSE; + drawsbarflag = FALSE; +} diff --git a/SCROLLRT.H b/SCROLLRT.H new file mode 100644 index 0000000..d2af3bb --- /dev/null +++ b/SCROLLRT.H @@ -0,0 +1,45 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/SCROLLRT.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define NBUFFWSL4 12288 +#define NBUFFWSL5 24576 + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern "C" { + extern long nLVal; + extern DWORD gdwPNum; + extern BOOL nTrans; +} +extern long nBuffWTbl[1024]; +extern bool HighLightAllItems; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void DrawBlankMTile(BYTE *); + +void DrawAndBlit (void); + +void FullBlit(BOOL); +void ClrDraw(); + +void CheckForScroll(); + +void DrawMissile(int, int, int, int, int, int, BOOL); +void CDrawMissile(int, int, int, int, int, int, BOOL); +void DrawDeadPlr(int sx, int sy, int xp, int yp, int ostart, int oend, BOOL clip); diff --git a/SETMAPS.CPP b/SETMAPS.CPP new file mode 100644 index 0000000..9aa10d4 --- /dev/null +++ b/SETMAPS.CPP @@ -0,0 +1,255 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Set Maps file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/SETMAPS.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "setmaps.h" +#include "gendung.h" +#include "palette.h" +#include "engine.h" + +#include "objects.h" +#include "quests.h" + +#include "drlg_l1.h" +#include "drlg_l2.h" +#include "drlg_l3.h" +#include "drlg_l4.h" + +#include "trigs.h" + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +static byte SkelKingTrans1[] = { + 19, 47, 26, 55, + 26, 49, 30, 53 }; + //18, 49, 18, 49 }; + +static byte SkelKingTrans2[] = { + 33, 19, 47, 29, + 37, 29, 43, 39 }; + +static byte SkelKingTrans3[] = { + 27, 53, 35, 61, + 27, 35, 34, 42, + 45, 35, 53, 43, + 45, 53, 53, 61, + 31, 39, 49, 57 }; + +static byte SkelKingTrans4[] = { + 49, 45, 58, 51, + 57, 31, 62, 37, + 63, 31, 69, 40, + 59, 41, 73, 55, + 63, 55, 69, 65, + 73, 45, 78, 51, + 79, 43, 89, 53 }; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static byte SkelChamTrans1[] = { + 43, 19, 50, 26, + 51, 19, 59, 26, + 35, 27, 42, 34, + 43, 27, 49, 34, + 50, 27, 59, 34}; + +static byte SkelChamTrans2[] = { + 19, 31, 34, 47, + 34, 35, 42, 42}; + +static byte SkelChamTrans3[] = { + 43, 35, 50, 42, + 51, 35, 62, 42, + 63, 31, 66, 46, + 67, 31, 78, 34, + 67, 35, 78, 42, + 67, 43, 78, 46, + 35, 43, 42, 51, + 43, 43, 49, 51, + 50, 43, 59, 51}; + +char *SetLevelName[] = { + "", + "Skeleton King's Lair", + "Bone Chamber", + "Maze", + "Poisoned Water Supply", + "Archbishop Lazarus' Lair", +}; + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int ObjIndex(int x, int y) +{ + int i, oi; + + for (i = 0; i < numobjects; i++) { + oi = objectactive[i]; + if ((object[oi]._ox == x) && (object[oi]._oy == y)) + return(oi); + } + app_fatal("ObjIndex: Active object not found at (%d,%d)",x,y); + return -1; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddSKingObjs() +{ + // Levers + SetObjMapRange(ObjIndex(64,34), 20, 7, 23, 10, 1); + SetObjMapRange(ObjIndex(64,59), 20, 14, 21, 16, 2); + + // Crux + SetObjMapRange(ObjIndex(27,37), 8, 1, 15, 11, 3); + SetObjMapRange(ObjIndex(46,35), 8, 1, 15, 11, 3); + SetObjMapRange(ObjIndex(49,53), 8, 1, 15, 11, 3); + SetObjMapRange(ObjIndex(27,53), 8, 1, 15, 11, 3); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddSChamObjs() +{ + // Levers + SetObjMapRange(ObjIndex(37,30), 17, 0, 21, 5, 1); + SetObjMapRange(ObjIndex(37,46), 13, 0, 16, 5, 2); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void AddVileObjs() +{ + // Books + SetObjMapRange(ObjIndex(26,45), 1, 1, 9, 10, 1); + SetObjMapRange(ObjIndex(45,46), 11, 1, 20, 10, 2); + + //Magic Circles + SetObjMapRange(ObjIndex(35,36), 7, 11, 13, 18, 3); + } + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DRLG_SetMapTrans(char sFileName[]) +{ + int i,j,rw,rh; + byte *pLevelMap,*lm; + long mapoff; + + //*** This data file seems to be stored as word values, but + //*** it is being accessed and stored in dTransVal as bytes. + //*** Is this correct? If so, the data is double sized. -Collin + + // Load map + pLevelMap = LoadFileInMemSig(sFileName,NULL,'LMPt'); + lm = pLevelMap; + + rw = *lm; + lm += 2; + rh = *lm; + // Skip map + height word + mapoff = ((rw * rh) << 1) + 2; + // Convert to index mini tile level instead of mega + rw = rw << 1; + rh = rh << 1; + // Skip treasure, monster, trap maps + mapoff += (((rw * rh) << 1) * 3); + lm += mapoff; + for (j = 0; j < rh; j++) { + for (i = 0; i < rw; i++) { + dTransVal[i+DIRTEDGED2][j+DIRTEDGED2] = *lm; + lm += 2; + } + } + + // Free map + DiabloFreePtr(pLevelMap); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +void LoadSetMap() +{ + switch (setlvlnum) { + case SL_SKELKING: + if (quests[Q_SKELKING]._qactive == QUEST_NOTACTIVE) { + quests[Q_SKELKING]._qactive = QUEST_NOTDONE; + quests[Q_SKELKING]._qvar1 = 1; + } + LoadPreL1Dungeon("Levels\\L1Data\\SklKng1.DUN", 83, 45); + LoadL1Dungeon("Levels\\L1Data\\SklKng2.DUN", 83, 45); + LoadPalette ("Levels\\L1Data\\L1_2.pal"); + DRLG_AreaTrans(2, &SkelKingTrans1[0]); + DRLG_ListTrans(2, &SkelKingTrans2[0]); + DRLG_AreaTrans(5, &SkelKingTrans3[0]); + DRLG_ListTrans(7, &SkelKingTrans4[0]); + AddL1Objs(0, 0, DMAXX, DMAXY); + AddSKingObjs(); + InitSKingTriggers(); + break; + + case SL_BONECHAMB: + LoadPreL2Dungeon("Levels\\L2Data\\Bonecha2.DUN", 69, 39); + LoadL2Dungeon("Levels\\L2Data\\Bonecha1.DUN", 69, 39); + LoadPalette ("Levels\\L2Data\\L2_2.pal"); + DRLG_ListTrans(5, &SkelChamTrans1[0]); + DRLG_AreaTrans(2, &SkelChamTrans2[0]); + DRLG_ListTrans(9, &SkelChamTrans3[0]); + AddL2Objs(0, 0, DMAXX, DMAXY); + AddSChamObjs(); + InitSChambTriggers(); + break; + + case SL_MAZE: + LoadPreL1Dungeon("Levels\\L1Data\\Lv1MazeA.DUN", 20, 50); + LoadL1Dungeon("Levels\\L1Data\\Lv1MazeB.DUN", 20, 50); + LoadPalette ("Levels\\L1Data\\L1_5.pal"); + AddL1Objs(0, 0, DMAXX, DMAXY); + DRLG_SetMapTrans("Levels\\L1Data\\Lv1MazeA.DUN"); + break; + + case SL_POISONWATER: + if (quests[Q_PWATER]._qactive == QUEST_NOTACTIVE) + quests[Q_PWATER]._qactive = QUEST_NOTDONE; + LoadPreL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 19, 50); + LoadL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 20, 50); + LoadPalette ("Levels\\L3Data\\L3pfoul.pal"); + InitPWaterTriggers(); + break; + + case SL_VILEBETRAYER: + if (quests[Q_BETRAYER]._qactive == QUEST_DONE) + quests[Q_BETRAYER]._qvar2 = QS_VBRP4; + else if (quests[Q_BETRAYER]._qactive == QUEST_NOTDONE) + quests[Q_BETRAYER]._qvar2 = QS_VBRP3; + LoadPreL1Dungeon("Levels\\L1Data\\Vile1.DUN", 35, 36); + LoadL1Dungeon("Levels\\L1Data\\Vile2.DUN", 35, 36); + LoadPalette ("Levels\\L1Data\\L1_2.pal"); + AddL1Objs(0, 0, DMAXX, DMAXY); + AddVileObjs(); + DRLG_SetMapTrans("Levels\\L1Data\\Vile1.DUN"); + InitNoTriggers(); + break; + } +} +#endif diff --git a/SETMAPS.H b/SETMAPS.H new file mode 100644 index 0000000..00b6636 --- /dev/null +++ b/SETMAPS.H @@ -0,0 +1,35 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/SETMAPS.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ +enum _setlevels { + SL_SKELKING=1, + SL_BONECHAMB, + SL_MAZE, + SL_POISONWATER, + SL_VILEBETRAYER, +}; + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern char *SetLevelName[]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void LoadSetMap(); diff --git a/SHA.CPP b/SHA.CPP new file mode 100644 index 0000000..8516800 --- /dev/null +++ b/SHA.CPP @@ -0,0 +1,189 @@ +/**************************************************************************** +* +* SHA.CPP +* Secure Hash Algorithm +* +* Implementation copyright (C) 1995, Michael O'Brien. All rights reserved. +* +* key size - N/A +* input block size - 512 bits +* output block size - 160 bits +* +***/ + + +#include "diablo.h" +#pragma hdrstop + + +//****************************************************************** +//****************************************************************** +#define SHA_BLOCKSIZE 64 +#define SHA_DIGESTSIZE 20 + +#define F1(x,y,z) ((x & y) | (~x & z)) +#define F2(x,y,z) (x ^ y ^ z) +#define F3(x,y,z) ((x & y) | (x & z) | (y & z)) +#define F4(x,y,z) (x ^ y ^ z) + +#define K1 0x5A827999 +#define K2 0x6ED9EBA1 +#define K3 0x8f1BBCDC +#define K4 0xCA62C1D6 + +#define H0INIT 0x67452301 +#define H1INIT 0xEFCDAB89 +#define H2INIT 0x98BADCFE +#define H3INIT 0x10325476 +#define H4INIT 0xC3D2E1F0 + +#define S(n,x) ((x << n) | (x >> (32 - n))) + +#define EXPAND(c) w[c] = w[c-3] ^ w[c-8] ^ w[c-14] ^ w[c-16] + +#define SUBROUND1(num) temp = S(5,a) + F1(b,c,d) + e + w[num] + K1 +#define SUBROUND2(num) temp = S(5,a) + F2(b,c,d) + e + w[num] + K2 +#define SUBROUND3(num) temp = S(5,a) + F3(b,c,d) + e + w[num] + K3 +#define SUBROUND4(num) temp = S(5,a) + F4(b,c,d) + e + w[num] + K4 + +typedef struct _shainfo { + int digest[5]; + int countlo; + int counthi; + int data[16]; +} shainfo, *shainfoptr; + + +//****************************************************************** +//****************************************************************** +static void InitializeHash (shainfoptr infoptr) { + infoptr->digest[0] = H0INIT; + infoptr->digest[1] = H1INIT; + infoptr->digest[2] = H2INIT; + infoptr->digest[3] = H3INIT; + infoptr->digest[4] = H4INIT; + infoptr->countlo = 0; + infoptr->counthi = 0; +} + + +//****************************************************************** +//****************************************************************** +static void TransformHash (shainfoptr infoptr) { + int w[80]; + int loop; + for (loop = 0; loop < 16; loop++) + w[loop] = infoptr->data[loop]; + for (loop = 16; loop < 80; loop++) + EXPAND(loop); + + int a = infoptr->digest[0]; + int b = infoptr->digest[1]; + int c = infoptr->digest[2]; + int d = infoptr->digest[3]; + int e = infoptr->digest[4]; + + int temp; + for (loop = 0; loop < 20; loop++) { + SUBROUND1(loop); + e = d; + d = c; + c = S(30,b); + b = a; + a = temp; + } + for (loop = 20; loop < 40; loop++) { + SUBROUND2(loop); + e = d; + d = c; + c = S(30,b); + b = a; + a = temp; + } + for (loop = 40; loop < 60; loop++) { + SUBROUND3(loop); + e = d; + d = c; + c = S(30,b); + b = a; + a = temp; + } + for (loop = 60; loop < 80; loop++) { + SUBROUND4(loop); + e = d; + d = c; + c = S(30,b); + b = a; + a = temp; + } + + infoptr->digest[0] += a; + infoptr->digest[1] += b; + infoptr->digest[2] += c; + infoptr->digest[3] += d; + infoptr->digest[4] += e; + + for (loop = 0; loop < 80; loop++) + w[loop] = 0; + a = b = c = d = e = 0; +} + + +//****************************************************************** +//****************************************************************** +static void UpdateHash (shainfoptr infoptr, const BYTE *buffer, int bytes) { + if ((infoptr->countlo + (bytes << 3)) < infoptr->countlo) + infoptr->counthi++; + infoptr->countlo += bytes << 3; + infoptr->counthi += bytes >> 29; + + while (bytes >= SHA_BLOCKSIZE) { + CopyMemory(infoptr->data,buffer,SHA_BLOCKSIZE); + TransformHash(infoptr); + buffer += SHA_BLOCKSIZE; + bytes -= SHA_BLOCKSIZE; + } +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +static shainfo currinfo[3]; + + +//****************************************************************** +//****************************************************************** +void ShaDestroy () { + ZeroMemory(&currinfo,3*sizeof(shainfo)); +} + + +//****************************************************************** +//****************************************************************** +void ShaGetLastHash (int streamnum, void *outptr) { + if (outptr) { + DWORD *outptr32 = (DWORD *)outptr; + int loop = 0; + while (loop < 5) + *(outptr32++) = currinfo[streamnum].digest[loop++]; + } +} + + +//****************************************************************** +//****************************************************************** +void ShaHash (int streamnum, const void *inptr, void *outptr) { + UpdateHash(&currinfo[streamnum],(const BYTE *)inptr,SHA_BLOCKSIZE); + if (outptr) + ShaGetLastHash(streamnum,outptr); +} + + +//****************************************************************** +//****************************************************************** +void ShaInitialize (int streamnum) { + InitializeHash(&currinfo[streamnum]); +} diff --git a/SOUND.CPP b/SOUND.CPP new file mode 100644 index 0000000..207911e --- /dev/null +++ b/SOUND.CPP @@ -0,0 +1,559 @@ +//****************************************************************** +// sound.cpp +// created 10.18.96 +// written by Patrick Wyatt +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "sound.h" +#include "engine.h" +#include "resource.h" + + +//****************************************************************** +// debugging +//****************************************************************** +#define ALLOW_DUP_SOUNDS 1 // 1 in final + + +//****************************************************************** +// extern +//****************************************************************** +BOOL wave_read_header(HSFILE hsFile,WAVEFORMATEX * pwfx); +LPBYTE wave_load_file(HSFILE hsFile,WAVEFORMATEX * pwfx,CKINFO * pWaveInfo); +void wave_free_file(LPBYTE lpWave); +void ErrorDlg(int nDlgId,DWORD dwErr,const char * pszFile,int nLine); + + +//****************************************************************** +// public +//****************************************************************** +BYTE gbSndInited = FALSE; +BYTE gbMusicOn = TRUE; +BYTE gbSoundOn = TRUE; +BYTE gbDupSounds = TRUE; + + +//****************************************************************** +// private +//****************************************************************** +static LONG sglMusicVolume = VOLUME_MAX; +static LONG sglSoundVolume = VOLUME_MAX; +static int sgnMusicTrack = NUM_MUSIC; + +static HINSTANCE sghDSlib = NULL; +static LPDIRECTSOUND sglpDS; +static HSFILE sghMusic = NULL; +static const char * sgszMusicTracks[NUM_MUSIC] = { +#if IS_VERSION(SHAREWARE) + "Music\\sTowne.wav", + "Music\\sLvla.wav", + "Music\\sLvla.wav", + "Music\\sLvla.wav", + "Music\\sLvla.wav", + "Music\\sLvla.wav", + "Music\\sLvla.wav", + "Music\\sintro.wav", +#else + "Music\\DTowne.wav", + "Music\\DLvlA.wav", + "Music\\DLvlB.wav", + "Music\\DLvlC.wav", + "Music\\DLvlD.wav", + "Music\\DLvlE.wav", + "Music\\DLvlF.wav", + "Music\\Dintro.wav", +#endif +}; + +static const char sgszSoundVol[] = "Sound Volume"; +static const char sgszMusicVol[] = "Music Volume"; +extern char gszProgKey[]; + + +#if ALLOW_DUP_SOUNDS +#define MAX_DUP_DSB 8 +#define S1 0xf00ff00f +#define S2 0xe11ee11e +static int signpost1 = S1; +static LPDIRECTSOUNDBUFFER sgDupDSB[MAX_DUP_DSB]; +static int signpost2 = S2; +#endif + +// do not play the same sound effect more frequently than this value +#define MIN_REPLAY_THRESHOLD 80 // milliseconds + +//****************************************************************** +//****************************************************************** +void snd_update(BOOL bStopAll) { + +#if ALLOW_DUP_SOUNDS + for (DWORD d = 0; d < MAX_DUP_DSB; d++) { + if (! sgDupDSB[d]) continue; + if (! bStopAll) { + DWORD dwStatus; + HRESULT hr = sgDupDSB[d]->GetStatus(&dwStatus); + if (hr == DS_OK && dwStatus == DSBSTATUS_PLAYING) continue; + } + + sgDupDSB[d]->Stop(); + sgDupDSB[d]->Release(); + sgDupDSB[d] = NULL; + } +#endif +} + + +//****************************************************************** +//****************************************************************** +#if ALLOW_DUP_SOUNDS +static LPDIRECTSOUNDBUFFER snd_dup_snd(LPDIRECTSOUNDBUFFER pDSB) { + // did user disable duplicate sounds? + if (! gbDupSounds) return NULL; + + for (DWORD d = 0; d < MAX_DUP_DSB; d++) { + if (sgDupDSB[d]) continue; + if (DS_OK != sglpDS->DuplicateSoundBuffer(pDSB,&sgDupDSB[d])) + return NULL; + return sgDupDSB[d]; + } + + return NULL; +} +#endif + + +//****************************************************************** +//****************************************************************** +static void snd_get_volume(const char * pszKey,LONG * plVolume) { + DWORD dwTemp = (DWORD) *plVolume; + if (! SRegLoadValue(gszProgKey,pszKey,0,&dwTemp)) + dwTemp = VOLUME_MAX; + *plVolume = (LONG) dwTemp; + + if (*plVolume < VOLUME_MIN) + *plVolume = VOLUME_MIN; + else if (*plVolume > VOLUME_MAX) + *plVolume = VOLUME_MAX; + *plVolume -= *plVolume % VOLUME_STEP; +} + + +//****************************************************************** +//****************************************************************** +static void snd_set_volume(const char * pszKey,LONG lVolume) { + SRegSaveValue(gszProgKey,pszKey,0,lVolume); +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start.1/13/97 +static BOOL snd_restore_snd(TSnd * pSnd,LPDIRECTSOUNDBUFFER pDSB) { + app_assert(pSnd); + app_assert(pDSB); + + // restore sound memory + if (DS_OK != pDSB->Restore()) + return FALSE; + + // open file containing sound only if it isn't already open + HSFILE hsFile; + BOOL bResult = FALSE; + patSFileOpenFile(pSnd->pszName,&hsFile); + patSFileSetFilePointer(hsFile,pSnd->waveInfo.dwOffset,NULL,FILE_BEGIN); + + // lock sound buffer + BYTE * pbData; + BYTE * pbData2; + DWORD dwLen; + DWORD dwLen2; + HRESULT hr = pDSB->Lock(0,pSnd->waveInfo.dwSize,&pbData,&dwLen,&pbData2,&dwLen2,0); + // dsound_assert(hr); + if (DS_OK != hr) goto err; + + patSFileReadFile(hsFile,pbData,dwLen); + + // unlock sound buffer + hr = pDSB->Unlock(pbData,dwLen,pbData2,dwLen2); + // dsound_assert(hr); + if (DS_OK != hr) goto err; + + bResult = TRUE; +err: + patSFileCloseFile(hsFile); + return bResult; +} +// pjw.patch1.end.1/13/97 + + +//****************************************************************** +//****************************************************************** +void snd_stop_snd(TSnd * pSnd) { + if (! pSnd) return; + if (pSnd->pDSB == NULL) return; + pSnd->pDSB->Stop(); +} + + +//****************************************************************** +//****************************************************************** +BOOL snd_playing(TSnd * pSnd) { + if (! pSnd) return FALSE; + if (pSnd->pDSB == NULL) return FALSE; + + // get new status + DWORD dwStatus; + HRESULT hr = pSnd->pDSB->GetStatus(&dwStatus); + // pjw.patch1.start.1/13/97 + // dsound_assert(hr); + if (DS_OK != hr) return FALSE; + // pjw.patch1.end.1/13/97 + + // still playing? + return (dwStatus == DSBSTATUS_PLAYING); +} + + +//****************************************************************** +//****************************************************************** +void snd_play_snd(TSnd * pSnd,LONG lVolume,LONG lPan) { + HRESULT hr; + LPDIRECTSOUNDBUFFER pDSB; + + if (! pSnd) return; + if (! gbSoundOn) return; + if (NULL == (pDSB = pSnd->pDSB)) + return; + + // don't allow sounds to be replayed too frequently + DWORD dwCurrTime = GetTickCount(); + if (dwCurrTime - pSnd->dwLastPlayTime < MIN_REPLAY_THRESHOLD) { + dwCurrTime = GetTickCount(); + return; + } + + // if the sound is already playing, duplicate the sound + if (snd_playing(pSnd)) { + #if ALLOW_DUP_SOUNDS + if (NULL == (pDSB = snd_dup_snd(pSnd->pDSB))) return; + #else + return; + #endif + } + + // set parameters + lVolume += sglSoundVolume; + if (lVolume < VOLUME_MIN) lVolume = VOLUME_MIN; + else if (lVolume > VOLUME_MAX) lVolume = VOLUME_MAX; + + // pjw.patch1.start.1/13/97 + hr = pDSB->SetVolume(lVolume); + // dsound_assert(hr); + hr = pDSB->SetPan(lPan); + // dsound_assert(hr); + // pjw.patch1.end.1/13/97 + + if (DSERR_BUFFERLOST != (hr = pDSB->Play(0,0,0))) + dsound_assert(hr); + else if (snd_restore_snd(pSnd,pDSB)) + pDSB->Play(0,0,0); + + pSnd->dwLastPlayTime = dwCurrTime; +} + + +//****************************************************************** +//****************************************************************** +static void snd_alloc_buffer(TSnd * pSnd) { + app_assert(sglpDS); + + // set up the direct sound buffer. + DSBUFFERDESC dsbd; + ZeroMemory(&dsbd,sizeof(dsbd)); + dsbd.dwSize = sizeof(dsbd); + dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME; + dsbd.dwBufferBytes = pSnd->waveInfo.dwSize; + dsbd.lpwfxFormat = &pSnd->wfx; + HRESULT hr = sglpDS->CreateSoundBuffer(&dsbd,&pSnd->pDSB,NULL); + dsound_assert(hr); +} + + +//****************************************************************** +//****************************************************************** +TSnd * snd_load_snd(const char * pszName) { + if (! sglpDS) return NULL; + + // open file containing sound + HSFILE hsFile; + patSFileOpenFile(pszName,&hsFile); + + // initialize sound record + TSnd * pSnd = (TSnd *) DiabloAllocPtrSig(sizeof(TSnd),'SND '); + ZeroMemory(pSnd,sizeof(TSnd)); + pSnd->pszName = pszName; + pSnd->dwLastPlayTime = GetTickCount() - MIN_REPLAY_THRESHOLD - 1; + + // get the sound format + LPBYTE lpWave = wave_load_file(hsFile,&pSnd->wfx,&pSnd->waveInfo); + if (! lpWave) app_fatal("Invalid sound format on file %s",pSnd->pszName); + + // allocate a buffer based on sound format + snd_alloc_buffer(pSnd); + + // lock sound buffer + BYTE * pbData; + BYTE * pbData2; + DWORD dwLen; + DWORD dwLen2; + HRESULT hr = pSnd->pDSB->Lock(0,pSnd->waveInfo.dwSize,&pbData,&dwLen,&pbData2,&dwLen2,0); + dsound_assert(hr); + + // read sound data + CopyMemory(pbData,lpWave + pSnd->waveInfo.dwOffset,dwLen); + + // unlock sound buffer + hr = pSnd->pDSB->Unlock(pbData,dwLen,pbData2,dwLen2); + dsound_assert(hr); + + #if DEBUG_MEM + mem_use_sig('DSND',pSnd->waveInfo.dwSize); + #endif + + // cleanup + wave_free_file(lpWave); + patSFileCloseFile(hsFile); + + return pSnd; +} + + +//****************************************************************** +//****************************************************************** +void snd_free_snd(TSnd * pSnd) { + if (pSnd) { + if (pSnd->pDSB) { + pSnd->pDSB->Stop(); + pSnd->pDSB->Release(); + pSnd->pDSB = NULL; + } + + #if DEBUG_MEM + mem_unuse_sig('DSND',pSnd->waveInfo.dwSize); + #endif + + DiabloFreePtr(pSnd); + } +} + + +//****************************************************************** +//****************************************************************** +static void snd_set_format(HSFILE hsFile) { + HRESULT hr; + app_assert(sglpDS); + + // Set up the primary direct sound buffer -- only try to + // do this the first time we're called (when hsFile == NULL). + // Don't worry about releasing the primary sound buffer, it + // will be done by directsound on application exit. + static LPDIRECTSOUNDBUFFER slpDSPrimary = NULL; + if (hsFile == NULL) { + DSBUFFERDESC dsbd; + ZeroMemory(&dsbd,sizeof(dsbd)); + dsbd.dwSize = sizeof(dsbd); + dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; + hr = sglpDS->CreateSoundBuffer(&dsbd,&slpDSPrimary,NULL); + dsound_assert(hr); + } + if (! slpDSPrimary) return; + + // get sound card capabilities + DSCAPS caps; + caps.dwSize = sizeof(DSCAPS); + hr = sglpDS->GetCaps(&caps); + dsound_assert(hr); + + // setup new format for primary buffer + WAVEFORMATEX fmt; + if (! hsFile || !wave_read_header(hsFile,&fmt)) { + ZeroMemory(&fmt,sizeof(fmt)); + fmt.wFormatTag = WAVE_FORMAT_PCM; + fmt.nSamplesPerSec = 22050; // 22k + fmt.wBitsPerSample = 16; // 16 bit + fmt.nChannels = 2; // stereo + fmt.cbSize = 0; + } + + // force stereo + fmt.nChannels = 2; + + // calculate sound buffer parameters + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample/8; + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + hr = slpDSPrimary->SetFormat(&fmt); + +// pjw.patch1.start.1/13/97 + // since sound cards may not implement this feature, or may not + // support certain formats, just ignore error codes... + // if (hr != DS_OK && hr != DSERR_BADFORMAT && hr != DSERR_PRIOLEVELNEEDED) + // dsound_assert(hr); +// pjw.patch1.end.1/13/97 +} + + +//****************************************************************** +//****************************************************************** +static HRESULT InDirectSoundCreate( + GUID * lpGUID, + LPDIRECTSOUND * lplpDS, + IUnknown * pUnkOuter +) { + // load direct sound library + if (! sghDSlib) sghDSlib = LoadLibrary(TEXT("dsound.dll")); + if (! sghDSlib) ErrorDlg(IDD_DSOUND_DLL_ERR,GetLastError(),__FILE__,__LINE__); + + // bind to DirectSoundCreate + typedef HRESULT (WINAPI * DSCREATETYPE)(GUID *,LPDIRECTSOUND *,IUnknown *); + DSCREATETYPE dscreatefunc = (DSCREATETYPE) GetProcAddress(sghDSlib,TEXT("DirectSoundCreate")); + if (! dscreatefunc) ErrorDlg(IDD_DSOUND_DLL_ERR,GetLastError(),__FILE__,__LINE__); + + // call DirectDrawCreate + return dscreatefunc(lpGUID,lplpDS,pUnkOuter); +} + + +//****************************************************************** +//****************************************************************** +void snd_init(HWND hWnd) { + snd_get_volume(sgszSoundVol,&sglSoundVolume); + gbSoundOn = (sglSoundVolume > VOLUME_MIN); + snd_get_volume(sgszMusicVol,&sglMusicVolume); + gbMusicOn = (sglMusicVolume > VOLUME_MIN); + + app_assert(! sglpDS); + HRESULT hr = InDirectSoundCreate(NULL,&sglpDS,NULL); + if (hr != DS_OK) sglpDS = NULL; + + if (sglpDS && DS_OK == sglpDS->SetCooperativeLevel(hWnd,DSSCL_EXCLUSIVE)) + snd_set_format(NULL); + + BOOL bSuccess = SVidInitialize(sglpDS); + app_assert(! sglpDS || bSuccess); + + bSuccess = SFileDdaInitialize(sglpDS); + app_assert(! sglpDS || bSuccess); + + // tell the world we can do sound + gbSndInited = (sglpDS != NULL); +} + + +//****************************************************************** +//****************************************************************** +void snd_exit() { + snd_update(TRUE); + + // shut down storm stuff before we release directsound + SVidDestroy(); + SFileDdaDestroy(); + + if (sglpDS) { + sglpDS->Release(); + sglpDS = NULL; + } + +// cannot free library now, still may be in use +// by directX window procedure... +/* + if (sghDSlib) { + FreeLibrary(sghDSlib); + sghDSlib = NULL; + } +*/ + + // turn off sound + if (gbSndInited) { + gbSndInited = FALSE; + snd_set_volume(sgszSoundVol,sglSoundVolume); + snd_set_volume(sgszMusicVol,sglMusicVolume); + } +} + + +//****************************************************************** +//****************************************************************** +void music_stop() { + if (sghMusic) { + SFileDdaEnd(sghMusic); + SFileCloseFile(sghMusic); + sghMusic = NULL; + sgnMusicTrack = NUM_MUSIC; + } +} + + +//****************************************************************** +//****************************************************************** +void music_start(int nTrack) { + app_assert((DWORD) nTrack < NUM_MUSIC); + music_stop(); + + if (! sglpDS) return; + if (! gbMusicOn) return; + + #ifndef NDEBUG + SFileEnableDirectAccess(0); + #endif + BOOL bResult = SFileOpenFile(sgszMusicTracks[nTrack],&sghMusic); + #ifndef NDEBUG + SFileEnableDirectAccess(1); + #endif + snd_set_format(sghMusic); + if (! bResult) { + sghMusic = NULL; + return; + } + + SFileDdaBeginEx(sghMusic,DDA_BUF_SIZE,SFILE_DDA_LOOP,0,sglMusicVolume,0,0); + sgnMusicTrack = nTrack; +} + + +//****************************************************************** +//****************************************************************** +void music_pause(BOOL bPause) { + if (bPause) + music_stop(); + else if (sgnMusicTrack != NUM_MUSIC) + music_start(sgnMusicTrack); +} + + +//****************************************************************** +//****************************************************************** +LONG music_volume(LONG lVolume) { + if (lVolume == VOLUME_READ) return sglMusicVolume; + app_assert(lVolume >= VOLUME_MIN); + app_assert(lVolume <= VOLUME_MAX); + sglMusicVolume = lVolume; + + if (sghMusic) SFileDdaSetVolume(sghMusic,sglMusicVolume,0); + + return sglMusicVolume; +} + + +//****************************************************************** +//****************************************************************** +LONG sound_volume(LONG lVolume) { + if (lVolume == VOLUME_READ) return sglSoundVolume; + app_assert(lVolume >= VOLUME_MIN); + app_assert(lVolume <= VOLUME_MAX); + sglSoundVolume = lVolume; + return sglSoundVolume; +} diff --git a/SOUND.H b/SOUND.H new file mode 100644 index 0000000..befde2e --- /dev/null +++ b/SOUND.H @@ -0,0 +1,78 @@ +//****************************************************************** +// sound.h +// created 10.18.96 +// written by Patrick Wyatt +//****************************************************************** + + +#ifndef H_SND +#define H_SND + + +//****************************************************************** +// public structures +//****************************************************************** +#define DDA_BUF_SIZE 0x40000 + +typedef struct CKINFO { + DWORD dwSize; + DWORD dwOffset; +} CKINFO; + + +typedef struct TSnd { + WAVEFORMATEX wfx; + CKINFO waveInfo; + const char * pszName; + LPDIRECTSOUNDBUFFER pDSB; + DWORD dwLastPlayTime; +} TSnd; + + +//****************************************************************** +// public vars +//****************************************************************** +extern BYTE gbMusicOn; +extern BYTE gbSoundOn; +extern BYTE gbSndInited; + + +//****************************************************************** +// public functions +//****************************************************************** +void snd_init(HWND hWnd); +void snd_exit(void); + +TSnd * snd_load_snd(const char * pszName); +void snd_free_snd(TSnd * pSnd); +void snd_play_snd(TSnd * pSnd,LONG lVolume,LONG lPan); +void snd_stop_snd(TSnd * pSnd); +BOOL snd_playing(TSnd * pSnd); + + +enum { + MUSIC_TOWN, + MUSIC_L1, + MUSIC_L2, + MUSIC_L3, + MUSIC_L4, + MUSIC_L5, + MUSIC_L6, + MUSIC_INTRO, + NUM_MUSIC +}; +void music_start(int nTrack); +void music_stop(); + + +#define VOLUME_READ 1 +#define VOLUME_MIN -1600 +#define VOLUME_MAX 0 +#define VOLUME_STEP 100 +#define VOLUME_TICKS (((VOLUME_MAX - VOLUME_MIN) / VOLUME_STEP) + 1) +LONG music_volume(LONG lVolume); +LONG sound_volume(LONG lVolume); + + + +#endif diff --git a/SPELL.SAV b/SPELL.SAV new file mode 100644 index 0000000..744350f --- /dev/null +++ b/SPELL.SAV @@ -0,0 +1,2819 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Control panel file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/CONTROL.CPP 2 2/05/97 10:41a Dbrevik2 $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "engine.h" +#include "control.h" +#include "gendung.h" +#include "scrollrt.h" +#include "msg.h" + +#include "items.h" +#include "itemdat.h" +#include "player.h" +#include "monster.h" +#include "objects.h" +#include "cursor.h" +#include "spells.h" +#include "missiles.h" + +#include "town.h" +#include "towners.h" +#include "trigs.h" +#include "gamemenu.h" +#include "inv.h" +#include "minitext.h" +#include "lighting.h" +#include "stores.h" +#include "automap.h" +#include "quests.h" + +#include "multi.h" + +#include "error.h" +#include "spelldat.h" + +/*-----------------------------------------------------------------------** +** Registration info +**-----------------------------------------------------------------------*/ +#include "regconst.h" +char sgszRegSig5[REG_LEN] = "REGISTRATION_BLOCK"; + +/*-----------------------------------------------------------------------** +** Local defines +**-----------------------------------------------------------------------*/ + +#define MANABUFFSIZE 7744 // 88x88 +#define LIFEBUFFSIZE 7744 + +#define STRN_GOLD 0 +#define STRN_BLUE 1 +#define STRN_RED 2 +#define STRN_ORANGE 3 +#define STRN_GREY 4 + +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ + +BYTE *pBtmBuff; // Offscreen control panel buffer +BYTE *pStatusPanel; +BYTE *pPanelButtons; +BYTE *pPanelText; +BYTE *pManaBuff; +BYTE *pLifeBuff; +BYTE *pChrPanel; +BYTE *pChrButtons; +BYTE *pSpellCels; +BYTE *pGBoxBuff; + +char panelstr[4][64]; +int pstrjust[4]; +BOOL pinfoflag; +int pnumlines; + +char infostr[256]; +char infoclr; + +char tempstr[256]; + +int pentaspin; +int dropGoldValue; +int initialDropGoldValue; +int initialDropGoldIndex; + +const BYTE fonttrans[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 54, 44, 57, 58, 56, 55, 47, 40, 41, 59, 39, 50, 37, 51, 52, // 32-47 + 36, 27, 28, 29, 30, 31, 32, 33, 34, 35, 48, 49, 60, 38, 61, 53, // 48-63 + 62, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 64-79 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 63, 43, 64, 65, // 80-95 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 96-111 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 40, 66, 41, 67, 0 }; // 112-127 + +const BYTE fontkern[68] = { 8, // Space/Invalid + 10, 7, 9, 8, 7, 6, 8, 8, 3, 3, 8, 6, 11, 9, 10, 6, // a-p + 9, 9, 6, 9, 11, 10, 13, 10, 11, 7, // q-z + 5, 7, 7, 8, 7, 7, 7, 7, 7, 10, // 1-0 + 4, 5, 6, 3, 3, 4, 3, 6, 6, 3, 3, 3, 3, 3, 2, 7, 6, 3, 10, 10, 6, // misc + 6, 7, 4, 4, 9, 6, 6, 12, 3, 7 }; // misc + +static const long fontofs[5][5] = { + { 456433, 24576, 24576, 24576, 24756 }, + { 447217, 465649, 24576, 24576, 24576 }, + { 442609, 456433, 470257, 24576, 24576 }, + { 439537, 451057, 461809, 473329, 24576 }, + { 438001, 447217, 456433, 465649, 474097 } }; + +BOOL drawhpflag; +BOOL drawmanaflag; +BOOL chrflag; + +/*-----------------------------------------------------------------------*/ + +BOOL spselflag = FALSE; +int pSpell, pSplType; +byte SpellTrans[256]; +static char SpellITbl[MAXSPELLS] = { + 1, // Invalid + 1, // SPL_FIREBOLT + 2, // SPL_HEAL + 3, // SPL_LIGHTNING + 4, // SPL_FLASH + 5, // SPL_IDENTIFY + 6, // SPL_WALL + 7, // SPL_TOWN + 8, // SPL_STONE + 9, // SPL_INFRA + 28, // SPL_PHASE + 13, // SPL_MANASHLD + 12, // SPL_FIREBALL + 18, // SPL_GUARDIAN + 16, // SPL_CHAIN + 14, // SPL_WAVE + 18, // SPL_DOOM + 19, // SPL_BLOODR + 11, // SPL_NOVA + 20, // SPL_INVIS + 15, // SPL_FLAME + 21, // SPL_GOLEM + 23, // SPL_BLOODB + 24, // SPL_TELE + 25, // SPL_APOCA + 22, // SPL_ETHER + 26, // SPL_REPAIR + 29, // SPL_RECHARGE + 37, // SPL_DISARM + 38, // SPL_ELEMENT + 39, // SPL_CBOLT + 42, // SPL_HBOLT + 41, // SPL_RESURRECT + 40, // SPL_TELEKINESIS + 10, // SPL_HEALOTHER + 36, // SPL_BSTAR + 30, // SPL_BONESPIRT + 26, // SPL_MANA + 29, // SPL_FMANA + 37, // SPL_RANDOM + 6, // SPL_LTWALL + 11, // SPL_IMMOLATION + 28, // SPL_TELESTAIRS + 26, // SPL_REFLECT + 4, // SPL_BERSERK + 6, // SPL_RINGOFFIRE + 6, // SPL_RINGOFLIGHT + 5, // SPL_SHOWMAGITEMS + }; + +/*-----------------------------------------------------------------------*/ + +#define NUMPBTNS 8 +#define SINGLE_PBTNS 6 +#define MULTI_PBTNS NUMPBTNS + +#define PBTN_CHR 0 +#define PBTN_TPLR1 0 +#define PBTN_QUEST 1 +#define PBTN_AMAP 2 +#define PBTN_TPLR2 2 +#define PBTN_MENU 3 +#define PBTN_INV 4 +#define PBTN_TPLR3 4 +#define PBTN_SBOOK 5 +#define PBTN_TALK 6 +#define PBTN_ATTACK 7 + +// x1, y1, width, height, talk pushable +int PanBtnPos[NUMPBTNS][5] = { + { 9, 361, 71, 19, TRUE }, + { 9, 387, 71, 19, FALSE }, + { 9, 427, 71, 19, TRUE }, + { 9, 453, 71, 19, FALSE }, + { 560, 361, 71, 19, TRUE }, + { 560, 387, 71, 19, FALSE }, + { 87, 443, 33, 32, TRUE }, + { 527, 443, 33, 32, TRUE }, +}; + +char *PanBtnHotKey[NUMPBTNS] = { + "'c'", + "'q'", + "Tab", + "Esc", + "'i'", + "'b'", + "Enter", + NULL }; + +char *PanBtnStr[NUMPBTNS] = { + "Character Information", + "Quests log", + "Automap", + "Main Menu", + "Inventory", + "Spell book", + "Send Message", + "Player Attack" }; + +BOOL panbtn[NUMPBTNS]; +BOOL drawbtnflag, panbtndown; +BOOL panelflag; // panel info draw +int numpanbtns; + +BYTE *pDurIcons; + +BOOL drawdurflag; +BOOL dropGoldFlag; + +/*-----------------------------------------------------------------------*/ + +#define NUMCBTNS 4 + +#define CBTN_STR 0 +#define CBTN_MAG 1 +#define CBTN_DEX 2 +#define CBTN_VIT 3 + +// x1, y1, width, height +int ChrBtnPos[NUMCBTNS][4] = { + { 137, 138, 41, 22 }, + { 137, 166, 41, 22 }, + { 137, 195, 41, 22 }, + { 137, 223, 41, 22 } }; + +BOOL chrbtn[NUMCBTNS]; +BOOL chrbtndown; + +/*-----------------------------------------------------------------------*/ + +BOOL lvlbtndown; + +/*-----------------------------------------------------------------------*/ + +BYTE *pSpellBkCel; +BYTE *pSBkBtnCel; +BYTE *pSBkIconCels; + +int sbooktab; +BOOL sbookflag; + +// The first entry will be filled during init with the player types skill +int SpellPages[6][7] = { + { 0, SPL_FIREBOLT, SPL_CBOLT, SPL_HBOLT, SPL_HEAL, SPL_HEALOTHER, SPL_FLAME }, + { SPL_RESURRECT, SPL_WALL, SPL_TELEKINESIS, SPL_LIGHTNING, SPL_TOWN, SPL_FLASH, SPL_STONE }, + { SPL_PHASE, SPL_MANASHLD, SPL_ELEMENT, SPL_FIREBALL, SPL_WAVE, SPL_CHAIN, SPL_GUARDIAN}, + { SPL_NOVA, SPL_GOLEM, SPL_TELE, SPL_APOCA, SPL_BONESPIRIT, SPL_BSTAR, SPL_ETHER }, + { SPL_LTWALL, SPL_IMMOLATION, SPL_TELESTAIRS, SPL_REFLECT, SPL_BERSERK, SPL_RINGOFFIRE, SPL_SHOWMAGITEMS }, + { -1, -1, -1, -1, -1, -1, -1 } +}; + +/*-----------------------------------------------------------------------*/ +#define MAX_TALK_SAVES 8 // must be pow2 +BOOL talkflag; +static int tspin; +static long talkofs; +static char sgszTalkMsg[MAX_SEND_STR_LEN]; +static BYTE sgbTalkSavePos; +static BYTE sgbNextTalkSave; +static char sgszTalkSaveMsg[MAX_TALK_SAVES][MAX_SEND_STR_LEN]; +static BYTE sgbPlrTalkTbl[MAX_PLRS]; +static BYTE *pTalkPanel; +static BYTE *pMultiBtns; +static BYTE *pTalkBtns; +static BOOL talkbtndown[3]; + +void TalkStart(); +void TalkEnd(); +void PlrStringXY(int x1, int y, int x2,const char * pszStr,char col); + + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ +void SetPlrHandItem(ItemStruct *h, int idata); +void GetPlrHandSeed(ItemStruct *h); +void GetGoldSeed(int pnum, ItemStruct *h); +void SetSpellTrans(char); + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawSpellCel(long xp, long yp, BYTE *pCels, long nCel, long w) +{ + BYTE *pTo; + byte *ttbl; + long RLELen; + + ttbl = &SpellTrans[0]; + app_assert(gpBuffer); + pTo = gpBuffer + nBuffWTbl[yp] + xp; + __asm { + mov ebx,dword ptr [pCels] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + + mov esi,dword ptr [pCels] // Source + add esi,dword ptr [ebx] + + mov edi,dword ptr [pTo] // Dest + + mov eax,dword ptr [RLELen] + add eax,esi + mov dword ptr [RLELen],eax + + mov ebx,dword ptr [ttbl] + +_T1Lp1: mov edx,dword ptr [w] + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + mov ecx,eax + shr ecx,1 + jnc _T1w + lodsb + xlatb + stosb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + lodsw + xlatb + ror ax,8 + xlatb + ror ax,8 + stosw + jecxz _T1x +_T1Lp3: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop _T1Lp3 +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,768 + sub edi,dword ptr [w] + cmp esi,dword ptr [RLELen] + jnz _T1Lp1 + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetSpellTrans(char t) +{ + int i; + + if (t == STRN_GOLD) { + for (i = 0; i < 128; i++) SpellTrans[i] = i; + } + for (i = 128; i < 256; i++) SpellTrans[i] = i; + SpellTrans[255] = 0; + + switch (t) { + case STRN_BLUE : + SpellTrans[144] = 177; + SpellTrans[145] = 179; + SpellTrans[146] = 181; + for (i = 176; i < 192; i++) { + SpellTrans[i - 16] = i; // 160-175 + SpellTrans[i + 16] = i; // 192-207 + SpellTrans[i + 32] = i; // 208-223 + } + break; + case STRN_ORANGE : + SpellTrans[144] = 209; + SpellTrans[145] = 211; + SpellTrans[146] = 213; + for (i = 208; i < 224; i++) { + SpellTrans[i - 48] = i; // 160-175 + SpellTrans[i - 16] = i; // 192-207 + } + break; + case STRN_RED : + SpellTrans[144] = 161; + SpellTrans[145] = 163; + SpellTrans[146] = 165; + for (i = 160; i < 176; i++) { + SpellTrans[i + 32] = i; // 192-207 + SpellTrans[i + 48] = i; // 208-223 + } + break; + case STRN_GREY : + SpellTrans[144] = 241; + SpellTrans[145] = 243; + SpellTrans[146] = 245; + for (i = 240; i < 255; i++) { + SpellTrans[i - 80] = i; // 160-174 + SpellTrans[i - 48] = i; // 192-206 + SpellTrans[i - 32] = i; // 208-222 + } + SpellTrans[175] = 0; + SpellTrans[207] = 0; + SpellTrans[223] = 0; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawSpellIcon() { + char t, sn; + int sl; + + t = plr[myplr]._pRSplType; + sn = plr[myplr]._pRSpell; + sl = plr[myplr]._pSplLvl[sn] + plr[myplr]._pISplLvlAdd; + if ((t == SPT_MEMORIZED) && (sn != -1)) { + if (!CheckSpell(myplr, sn, t, TRUE)) t = STRN_GREY; + if (sl <= 0 ) t = STRN_GREY; + } + + if ((currlevel == 0) && (t != STRN_GREY) && (spelldata[sn].sTownSpell == FALSE)) t = STRN_GREY; + if (plr[myplr]._pRSpell < 0) t = STRN_GREY; + SetSpellTrans(t); + if (sn != -1) DrawSpellCel(629, 631, pSpellCels, SpellITbl[sn], 56); + else DrawSpellCel(629, 631, pSpellCels, 27, 56); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#define SPLICONSIZE 56 +#define SPLICONRIGHT 636 // (640 - (trunc(640 / 56) * 56)) / 2) + 640 + 64 - SPLICONSIZE +#define SPLICONLEFT 20 // SPLICONRIGHT - (trunc(640 / 56) * 56) - SPLICONSIZE + +void DrawSpellList() +{ + int mx,my,x,y,i,j,t; + __int64 mask,spl; + int s,c,hk; + int v, selbox; + + x = SPLICONRIGHT; + y = 495; + + pSpell = -1; + infostr[0] = 0; + ClearPanel(); + for (j = 0; j < 4; j++) { + switch(j) { + case 0: + SetSpellTrans(STRN_GOLD); + spl = plr[myplr]._pAblSpells; + selbox = 46; + break; + case 1: + spl = plr[myplr]._pMemSpells; + selbox = 47; + break; + case 2: + SetSpellTrans(STRN_RED); + spl = plr[myplr]._pScrlSpells; + selbox = 44; + break; + case 3: + SetSpellTrans(STRN_ORANGE); + spl = plr[myplr]._pISpells; + selbox = 45; + break; + } + mask = 1; + for (i = 1; i < SPL_LAST; i++) { + if ((spl & mask) != 0) { + if (j == 1) { + v = plr[myplr]._pSplLvl[i] + plr[myplr]._pISplLvlAdd; + if ( v < 0 ) v = 0; + if (v > 0) t = STRN_BLUE; + else t = STRN_GREY; + SetSpellTrans(t); + } + + if ((currlevel == 0) && (spelldata[i].sTownSpell == FALSE)) SetSpellTrans(STRN_GREY); + + DrawSpellCel(x, y, pSpellCels, SpellITbl[i], SPLICONSIZE); + mx = x - 64; + my = y - (160 + SPLICONSIZE); + if ((MouseX >= mx) && (MouseX < (mx+SPLICONSIZE)) && (MouseY >= my) && (MouseY < (my+SPLICONSIZE))) { + pSpell = i; + pSplType = j; + DrawSpellCel(x, y, pSpellCels, selbox, SPLICONSIZE); + switch (j) { + case 0: + sprintf(infostr, "%s Skill", spelldata[pSpell].sSkillText); + break; + case 1: + sprintf(infostr, "%s Spell", spelldata[pSpell].sNameText); + if (pSpell == SPL_HBOLT) { + sprintf(tempstr, "Damages undead only"); + AddPanelString(tempstr, TEXT_CENTER); + } + if (v == 0) sprintf(tempstr, "Spell Level 0 - Unusable"); + else sprintf(tempstr, "Spell Level %i", v); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 2: + sprintf(infostr, "Scroll of %s", spelldata[pSpell].sNameText); + c = 0; + for (s = 0; s < plr[myplr]._pNumInv; s++) { + if ((plr[myplr].InvList[s]._itype != -1) && + ((plr[myplr].InvList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].InvList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].InvList[s]._iSpell == pSpell) c++; + } + } + for (s = 0; s < MAXSPD; s++) { + if ((plr[myplr].SpdList[s]._itype != -1) && + ((plr[myplr].SpdList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].SpdList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].SpdList[s]._iSpell == pSpell) c++; + } + } + if (c == 1) strcpy(tempstr, "1 Scroll"); + else sprintf(tempstr, "%i Scrolls", c); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 3: + sprintf(infostr, "Staff of %s", spelldata[pSpell].sNameText); + if (plr[myplr].Hand1Item._iCharges == 1) strcpy(tempstr, "1 Charge"); + else sprintf(tempstr, "%i Charges", plr[myplr].Hand1Item._iCharges); + AddPanelString(tempstr, TEXT_CENTER); + break; + } + for (hk = 0; hk < 4; hk++) { + if ((plr[myplr]._pSplHotKey[hk] == pSpell) && (plr[myplr]._pSplTHotKey[hk] == pSplType)) { + DrawSpellCel(x, y, pSpellCels, 48+hk, SPLICONSIZE); + sprintf(tempstr, "Spell Hot Key #F%i", hk+5); + AddPanelString(tempstr, TEXT_CENTER); + } + } + } + x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } + mask = mask << 1; + } + if (spl && (x != SPLICONRIGHT)) x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void SetSpell() +{ + spselflag = FALSE; + if (pSpell != -1) { + ClearPanel(); + plr[myplr]._pRSpell = pSpell; + plr[myplr]._pRSplType = pSplType; + force_redraw = FULLDRAW; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetSpellHK(int hk) +{ + if (pSpell != -1) { + for (int i = 0; i < 4; i++) { + if ((plr[myplr]._pSplHotKey[i] == pSpell) && (plr[myplr]._pSplTHotKey[i] == pSplType)) + plr[myplr]._pSplHotKey[i] = -1; + } + plr[myplr]._pSplHotKey[hk] = pSpell; + plr[myplr]._pSplTHotKey[hk] = pSplType; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void GetSpellHK(int hk) +{ + __int64 spl; + + if (plr[myplr]._pSplHotKey[hk] == -1) return; + + switch(plr[myplr]._pSplTHotKey[hk]) { + case 0: + spl = plr[myplr]._pAblSpells; + break; + case 1: + spl = plr[myplr]._pMemSpells; + break; + case 2: + spl = plr[myplr]._pScrlSpells; + break; + case 3: + spl = plr[myplr]._pISpells; + break; + } + spl &= (((__int64)1) << (plr[myplr]._pSplHotKey[hk]-1)); + if (spl) { + plr[myplr]._pRSpell = plr[myplr]._pSplHotKey[hk]; + plr[myplr]._pRSplType = plr[myplr]._pSplTHotKey[hk]; + force_redraw = FULLDRAW; + } +} + +/*-----------------------------------------------------------------------** +** Draws a small font letter +**-----------------------------------------------------------------------*/ + +void DrawPanelFont (long poffset, long nCel, char clr) +{ + app_assert(gpBuffer); + __asm { + mov ebx,dword ptr [pPanelText] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + + mov edx,dword ptr [ebx+4] // Length + sub edx,dword ptr [ebx] + + mov esi,dword ptr [pPanelText] // Source + add esi,dword ptr [ebx] + + mov edi,dword ptr [gpBuffer] // Dest + add edi,dword ptr [poffset] + + mov ebx,edx + add ebx,esi + + xor edx,edx + mov dl,byte ptr [clr] + cmp edx,ICOLOR_WHITE + jz _T1Lp1 // Normal / White + cmp edx,ICOLOR_BLUE + jz _T2Lp1 // Blue + cmp edx,ICOLOR_RED + jz _T3Lp1 // Red + jmp _T4Lp1 // Gold + +/*- White ---------------------------------------------------------------*/ + +_T1Lp1: mov edx,13 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax // Draw + mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,781 + cmp ebx,esi + jnz _T1Lp1 + jmp _Done + +/*- Blue ----------------------------------------------------------------*/ + +_T2Lp1: mov edx,13 + +_T2Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T2J + + sub edx,eax // Draw + mov ecx,eax +_T2Lp3: lodsb + cmp al,253 + ja _T2F + cmp al,240 + jb _T2Sv + sub al,62 + jmp _T2Sv +_T2F: mov al,191 +_T2Sv: stosb + loop _T2Lp3 + or edx,edx + jz _T2Nxt + jmp _T2Lp2 + +_T2J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T2Lp2 +_T2Nxt: sub edi,781 + cmp ebx,esi + jnz _T2Lp1 + jmp _Done + +/*- Red -----------------------------------------------------------------*/ + +_T3Lp1: mov edx,13 + +_T3Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T3J + + sub edx,eax // Draw + mov ecx,eax +_T3Lp3: lodsb + cmp al,240 + jb _T3Sv + sub al,16 +_T3Sv: stosb + loop _T3Lp3 + or edx,edx + jz _T3Nxt + jmp _T3Lp2 + +_T3J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T3Lp2 +_T3Nxt: sub edi,781 + cmp ebx,esi + jnz _T3Lp1 + jmp _Done + +/*- Gold ----------------------------------------------------------------*/ + +_T4Lp1: mov edx,13 + +_T4Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T4J + + sub edx,eax // Draw + mov ecx,eax +_T4Lp3: lodsb + cmp al,240 + jb _T4Sv + cmp al,254 + jae _T4val + sub al,46 + jmp _T4Sv +_T4val: mov al,207 +_T4Sv: stosb + loop _T4Lp3 + or edx,edx + jz _T4Nxt + jmp _T4Lp2 + +_T4J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T4Lp2 +_T4Nxt: sub edi,781 + cmp ebx,esi + jnz _T4Lp1 + +/*-----------------------------------------------------------------------*/ + +_Done: + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddPanelString(const char * str, int just) +{ + strcpy(panelstr[pnumlines],str); + pstrjust[pnumlines] = just; + if (pnumlines < 4) pnumlines++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ClearPanel() +{ + pnumlines = 0; + pinfoflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CopyCtrlPan(int sx, int sy, int deltax, int deltay, int dx, int dy) +{ + long src, dest; + + app_assert(gpBuffer); + src = (sy * 640) + sx; + dest = (dy * 768) + dx; + __asm { + mov esi,dword ptr [pBtmBuff] + add esi,dword ptr [src] + mov edi,dword ptr [gpBuffer] + add edi,dword ptr [dest] + + xor ebx,ebx + mov bx,word ptr [deltax] + xor edx,edx + mov dx,word ptr [deltay] +_CLp: mov ecx,ebx + shr ecx,1 + jnc _Tw + movsb + jecxz _Tx +_Tw: shr ecx,1 + jnc _TLp + movsw + jecxz _Tx +_TLp: rep movsd +_Tx: add esi,640 + sub esi,ebx + add edi,768 + sub edi,ebx + dec edx + jnz _CLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitPanelStr() +{ + ClearPanel(); + //AddPanelString("Welcome to Diablo", TEXT_CENTER); // This was ok (pre Demo) now its not + //AddPanelString("Press F1 for help", TEXT_CENTER); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void BuffCopy(BYTE *pSrc, int y1, int y2, int dx, int dy) +{ + long srco, desto, deltay; + + app_assert(gpBuffer); + srco = y1 * 88; + desto = (dy * 768) + dx; + deltay = y2 - y1; + __asm { + mov esi,dword ptr [pSrc] + add esi,dword ptr [srco] + mov edi,dword ptr [gpBuffer] + add edi,dword ptr [desto] + + mov edx,dword ptr [deltay] +_YLp: mov ecx,22 + rep movsd + add edi,680 + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TransBuffCopy(BYTE *pSrc, long srcwidth, long srcoff, BYTE *pDest, long destoff, long dy) +{ + __asm { + mov esi,dword ptr [pSrc] + add esi,dword ptr [srcoff] + mov edi,dword ptr [pDest] + add edi,dword ptr [destoff] + + mov edx,dword ptr [dy] +_YLp: mov ecx,59 +_XLp: lodsb + or al,al + jz _Skip + mov byte ptr [edi],al +_Skip: inc edi + loop _XLp + add esi,dword ptr [srcwidth] + sub esi,59 + add edi,709 + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawHealthTop() +{ + double v; + int dv; + + if (plr[myplr]._pMaxHP <= 0) + v = 0.0; + else + v = ((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP) * 80; + dv = (int)v; + plr[myplr]._pHPPer = dv; + + + long dy; + + dy = 80 - plr[myplr]._pHPPer; + if (dy > 11) dy = 11; + dy += 2; + + app_assert(gpBuffer); + TransBuffCopy(pLifeBuff, 88, 277, gpBuffer, 383405, dy); + if (dy != 13) TransBuffCopy(pBtmBuff, 640, (dy * 640) + 2029, gpBuffer, (dy * 768) + 383405, 13 - dy); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawHealthBar() +{ + double v; + int dv; + + if (plr[myplr]._pMaxHP <= 0) + v = 0.0; + else + v = ((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP) * 80; + dv = (int)v; + plr[myplr]._pHPPer = dv; + + if (dv > 69) dv = 69; + if (dv != 69) BuffCopy(pLifeBuff, 16, 85-dv, 160, 512); + if (dv != 0) CopyCtrlPan(96, 85-dv, 88, dv, 160, 581-dv); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawManaTop() +{ + long dy; + + dy = 80 - plr[myplr]._pManaPer; + if (dy > 11) dy = 11; + dy += 2; + + app_assert(gpBuffer); + TransBuffCopy(pManaBuff, 88, 277, gpBuffer, 383771, dy); + if (dy != 13) TransBuffCopy(pBtmBuff, 640, (dy * 640) + 2395, gpBuffer, (dy * 768) + 383771, 13 - dy); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CalcInitBallPer() +{ + double v; + int dv; + long m,mm; + + mm = plr[myplr]._pMaxMana; + m = plr[myplr]._pMana; + if (mm < 0) mm = 0; + if (m < 0) m = 0; + if (mm == 0) dv = 0; + else { + v = ((double)m / (double)mm) * 80; + dv = (int)v; + } + plr[myplr]._pManaPer = dv; + v = ((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP) * 80; + dv = (int)v; + plr[myplr]._pHPPer = dv; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawManaBar() +{ + double v; + int dv; + long m,mm; + + mm = plr[myplr]._pMaxMana; + m = plr[myplr]._pMana; + if (mm < 0) mm = 0; + if (m < 0) m = 0; + if (mm == 0) dv = 0; + else { + v = ((double)m / (double)mm) * 80; + dv = (int)v; + } + plr[myplr]._pManaPer = dv; + + if (dv > 69) dv = 69; + if (dv != 69) BuffCopy(pManaBuff, 16, 85-dv, 528, 512); + if (dv != 0) CopyCtrlPan(464, 85-dv, 88, dv, 528, 581-dv); + + DrawSpellIcon(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitControlPan() +{ + int i; + + app_assert(! pBtmBuff); + if (gbMaxPlayers == 1) { + pBtmBuff = DiabloAllocPtrSig(BTMBUFFSIZE,'CTRL'); + ZeroMemory(pBtmBuff,BTMBUFFSIZE); + } else { + pBtmBuff = DiabloAllocPtrSig(BTMBUFFMULTISIZE,'CTRL'); + ZeroMemory(pBtmBuff,BTMBUFFMULTISIZE); + } + pManaBuff = DiabloAllocPtrSig(MANABUFFSIZE,'CTRL'); + ZeroMemory(pManaBuff,MANABUFFSIZE); + pLifeBuff = DiabloAllocPtrSig(LIFEBUFFSIZE,'CTRL'); + ZeroMemory(pLifeBuff,LIFEBUFFSIZE); + pPanelText = LoadFileInMemSig("CtrlPan\\SmalText.CEL",NULL,'CTRL'); + pChrPanel = LoadFileInMemSig("Data\\Char.CEL",NULL,'CTRL'); + pSpellCels = LoadFileInMemSig("CtrlPan\\SpelIcon.CEL",NULL,'CTRL'); + SetSpellTrans(STRN_GOLD); + + // Init Control panel offscreen buffer + pStatusPanel = LoadFileInMemSig("CtrlPan\\Panel8.CEL",NULL,'CTRL'); + DrawBuffCel(pBtmBuff, 0, 143, BTMBUFFX, pStatusPanel, 1, 640); + DiabloFreePtr (pStatusPanel); + pStatusPanel = LoadFileInMemSig("CtrlPan\\P8Bulbs.CEL",NULL,'CTRL'); + DrawBuffCel(pLifeBuff, 0, 87, 88, pStatusPanel, 1, 88); + DrawBuffCel(pManaBuff, 0, 87, 88, pStatusPanel, 2, 88); + DiabloFreePtr (pStatusPanel); + talkflag = FALSE; + if (gbMaxPlayers != 1) { + pTalkPanel = LoadFileInMemSig("CtrlPan\\TalkPanl.CEL",NULL,'CTRL'); + DrawBuffCel(pBtmBuff, 0, 287, BTMBUFFX, pTalkPanel, 1, 640); + DiabloFreePtr (pTalkPanel); + pMultiBtns = LoadFileInMemSig("CtrlPan\\P8But2.CEL",NULL,'CTRL'); + pTalkBtns = LoadFileInMemSig("CtrlPan\\TalkButt.CEL",NULL,'CTRL'); + talkofs = 0; + sgszTalkMsg[0] = 0; + for (i = 0; i < MAX_PLRS; i++) sgbPlrTalkTbl[i] = TRUE; + for (i = 0; i < 3; i++) talkbtndown[i] = FALSE; + } + panelflag = FALSE; + + lvlbtndown = FALSE; + + pPanelButtons = LoadFileInMemSig("CtrlPan\\Panel8bu.CEL",NULL,'CTRL'); + for (i = 0; i < NUMPBTNS; i++) panbtn[i] = FALSE; + panbtndown = FALSE; + if (gbMaxPlayers == 1) numpanbtns = SINGLE_PBTNS; + else numpanbtns = MULTI_PBTNS; + + pChrButtons = LoadFileInMemSig("Data\\CharBut.CEL",NULL,'CTRL'); + for (i = 0; i < NUMCBTNS; i++) chrbtn[i] = FALSE; + chrbtndown = FALSE; + + pDurIcons = LoadFileInMemSig("Items\\DurIcons.CEL",NULL,'CTRL'); + + strcpy(infostr,""); + InitPanelStr(); + drawhpflag = TRUE; + drawmanaflag = TRUE; + chrflag = FALSE; + spselflag = FALSE; + + pSpellBkCel = LoadFileInMemSig("Data\\SpellBk.CEL",NULL,'CTRL'); + pSBkBtnCel = LoadFileInMemSig("Data\\SpellBkB.CEL",NULL,'CTRL'); + pSBkIconCels = LoadFileInMemSig("Data\\SpellI2.CEL",NULL,'CTRL'); + sbooktab = 0; + sbookflag = FALSE; + if (plr[myplr]._pClass == CLASS_WARRIOR) SpellPages[0][0] = SPL_REPAIR; + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) SpellPages[0][0] = SPL_DISARM; + else if (plr[myplr]._pClass == CLASS_SORCEROR) SpellPages[0][0] = SPL_RECHARGE; + else if (plr[myplr]._pClass == CLASS_MONK) SpellPages[0][0] = SPL_HEALOTHER; + else if (plr[myplr]._pClass == CLASS_BARD) SpellPages[0][0] = SPL_IDENTIFY; + #endif + + pQLogCel = LoadFileInMemSig("Data\\Quest.CEL",NULL,'CTRL'); + + pGBoxBuff = LoadFileInMemSig("CtrlPan\\Golddrop.cel",NULL,'CTRL'); + // Initialize gold drop variables + dropGoldFlag = FALSE; + dropGoldValue = 0; + initialDropGoldValue = 0; + initialDropGoldIndex = 0; + pentaspin = 1; + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawCtrlPan() { + CopyCtrlPan(0, 16+talkofs, 640, 128, 64, 512); + DrawInfoBox(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawButtons() +{ + for (int i = 0; i < SINGLE_PBTNS; i++) { + if (!panbtn[i]) + CopyCtrlPan(PanBtnPos[i][0], PanBtnPos[i][1]-336, 71, 20, PanBtnPos[i][0] + 64, PanBtnPos[i][1] + 160); + else + DrawCel(PanBtnPos[i][0]+64, PanBtnPos[i][1]+178, pPanelButtons, i+1, 71); + } + + if (numpanbtns == MULTI_PBTNS) { + // Draw talk button + DrawCel(151, 634, pMultiBtns, 1+panbtn[PBTN_TALK], 33); + // Draw Friend or foe button + if (FriendlyMode) { + DrawCel(591, 634, pMultiBtns, 3+panbtn[PBTN_ATTACK], 33); + } else { + DrawCel(591, 634, pMultiBtns, 5+panbtn[PBTN_ATTACK], 33); + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetupSpellSel() +{ + int x,y,i,j; + __int64 mask,spl; + int cx, cy; + + spselflag = TRUE; + x = SPLICONRIGHT; + y = 495; + cx = x - (64 - (SPLICONSIZE >> 1)); + cy = y - (160 + (SPLICONSIZE >> 1)); + if (plr[myplr]._pRSpell != -1) { + for (j = 0; j < 4; j++) { + switch(j) { + case 0: + spl = plr[myplr]._pAblSpells; + break; + case 1: + spl = plr[myplr]._pMemSpells; + break; + case 2: + spl = plr[myplr]._pScrlSpells; + break; + case 3: + spl = plr[myplr]._pISpells; + break; + } + mask = 1; + for (i = 1; i < SPL_LAST; i++) { + if ((spl & mask) != 0) { + if ((i == plr[myplr]._pRSpell) && (j == plr[myplr]._pRSplType)) { + cx = x - (64 - (SPLICONSIZE >> 1)); + cy = y - (160 + (SPLICONSIZE >> 1)); + } + x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } + mask = mask << 1; + } + if (spl && (x != SPLICONRIGHT)) x -= SPLICONSIZE; + if (x == SPLICONLEFT) { + x = SPLICONRIGHT; + y -= SPLICONSIZE; + } + } + } + SetCursorPos(cx,cy); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckPanelBtns() +{ + for (int i = 0; i < numpanbtns; i++) { + int x2 = PanBtnPos[i][0] + PanBtnPos[i][2]; + int y2 = PanBtnPos[i][1] + PanBtnPos[i][3]; + if ((MouseX >= PanBtnPos[i][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[i][1]) && (MouseY <= y2)) { + panbtn[i] = TRUE; + drawbtnflag = TRUE; + panbtndown = TRUE; + } + } + + if (!spselflag) { + if (MouseX >= 565 && MouseX < 621 && MouseY >= 416 && MouseY < 472) { + SetupSpellSel(); + gamemenu_off(); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ActivatePanelBtn(int i) +{ + panbtn[i] = TRUE; + drawbtnflag = TRUE; + panbtndown = TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckDeadButtons() +{ + int x2, y2; + + x2 = PanBtnPos[PBTN_MENU][0] + PanBtnPos[PBTN_MENU][2]; + y2 = PanBtnPos[PBTN_MENU][1] + PanBtnPos[PBTN_MENU][3]; + if ((MouseX >= PanBtnPos[PBTN_MENU][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[PBTN_MENU][1]) && (MouseY <= y2)) + ActivatePanelBtn(PBTN_MENU); + x2 = PanBtnPos[PBTN_TALK][0] + PanBtnPos[PBTN_TALK][2]; + y2 = PanBtnPos[PBTN_TALK][1] + PanBtnPos[PBTN_TALK][3]; + if ((MouseX >= PanBtnPos[PBTN_TALK][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[PBTN_TALK][1]) && (MouseY <= y2)) + ActivatePanelBtn(PBTN_TALK); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DoAutoMap() { + // if we are multiplayer on the town level, DO NOT display + // the error message. Instead, the automap will show the + // game name and password + if (currlevel == 0 && gbMaxPlayers == 1) { + InitDiabloMsg(MSG_AMAPTWN); + return; + } + + // toggle automap + if (!automapflag) StartAutomap(); + else automapflag = FALSE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckPanelInfo() +{ + int i; + int x2, y2; + int pSpell, c, s; + int v; + + panelflag = FALSE; + ClearPanel(); + + for (i = 0; i < numpanbtns; i++) { + x2 = PanBtnPos[i][0] + PanBtnPos[i][2]; + y2 = PanBtnPos[i][1] + PanBtnPos[i][3]; + if ((MouseX >= PanBtnPos[i][0]) && (MouseX <= x2) && (MouseY >= PanBtnPos[i][1]) && (MouseY <= y2)) { + if (i != PBTN_ATTACK) + strcpy(infostr, PanBtnStr[i]); + else if (FriendlyMode) + strcpy(infostr, "Player friendly"); + else + strcpy(infostr, "Player attack"); + if (PanBtnHotKey[i] != NULL) { + sprintf(tempstr, "Hotkey : %s", PanBtnHotKey[i]); + AddPanelString(tempstr, TEXT_CENTER); + } + infoclr = ICOLOR_WHITE; + panelflag = TRUE; + pinfoflag = TRUE; + } + } + + if (!spselflag) { + if ((MouseX >= 565) && (MouseX < 621) && (MouseY >= 416) && (MouseY < 472)) { + strcpy(infostr, "Select current spell button"); + infoclr = ICOLOR_WHITE; + panelflag = TRUE; + pinfoflag = TRUE; + strcpy(tempstr, "Hotkey : 's'"); + AddPanelString(tempstr, TEXT_CENTER); + pSpell = plr[myplr]._pRSpell; + if (pSpell != -1) { + switch (plr[myplr]._pRSplType) { + case 0: + sprintf(tempstr, "%s Skill", spelldata[pSpell].sSkillText); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 1: + sprintf(tempstr, "%s Spell", spelldata[pSpell].sNameText); + AddPanelString(tempstr, TEXT_CENTER); + v = plr[myplr]._pSplLvl[pSpell]+plr[myplr]._pISplLvlAdd; + if ( v < 0 ) v = 0; + if (v == 0) sprintf(tempstr, "Spell Level 0 - Unusable"); + else sprintf(tempstr, "Spell Level %i", v); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 2: + sprintf(tempstr, "Scroll of %s", spelldata[pSpell].sNameText); + AddPanelString(tempstr, TEXT_CENTER); + c = 0; + for (s = 0; s < plr[myplr]._pNumInv; s++) { + if ((plr[myplr].InvList[s]._itype != -1) && + ((plr[myplr].InvList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].InvList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].InvList[s]._iSpell == pSpell) c++; + } + } + for (s = 0; s < MAXSPD; s++) { + if ((plr[myplr].SpdList[s]._itype != -1) && + ((plr[myplr].SpdList[s]._iMiscId == IMID_SCROLL) || + (plr[myplr].SpdList[s]._iMiscId == IMID_TSCROLL))) { + if (plr[myplr].SpdList[s]._iSpell == pSpell) c++; + } + } + if (c == 1) strcpy(tempstr, "1 Scroll"); + else sprintf(tempstr, "%i Scrolls", c); + AddPanelString(tempstr, TEXT_CENTER); + break; + case 3: + sprintf(tempstr, "Staff of %s", spelldata[pSpell].sNameText); + AddPanelString(tempstr, TEXT_CENTER); + if (plr[myplr].Hand1Item._iCharges == 1) strcpy(tempstr, "1 Charge"); + else sprintf(tempstr, "%i Charges", plr[myplr].Hand1Item._iCharges); + AddPanelString(tempstr, TEXT_CENTER); + break; + } + } + } + } + + if ((MouseX > 190) && (MouseX < 437) && (MouseY > 356) && (MouseY < 385)) + cursinvitem = CheckInvHLight(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ReleasePanelBtn() { + BYTE bMenuOff = TRUE; + + drawbtnflag = TRUE; + panbtndown = FALSE; + for (int i = 0; i < NUMPBTNS; i++) { + if (! panbtn[i]) continue; + panbtn[i] = FALSE; + + // was the mouseup in this button? + if (MouseX < PanBtnPos[i][0]) continue; + if (MouseX > PanBtnPos[i][0] + PanBtnPos[i][2]) continue; + if (MouseY < PanBtnPos[i][1]) continue; + if (MouseY > PanBtnPos[i][1] + PanBtnPos[i][3]) continue; + + switch(i) { + case PBTN_CHR : + questlog = FALSE; + chrflag = !chrflag; + break; + case PBTN_QUEST: + chrflag = FALSE; + if (!questlog) StartQuestlog(); + else questlog = FALSE; + break; + case PBTN_AMAP : + DoAutoMap(); + break; + case PBTN_MENU : + qtextflag = FALSE; + gamemenu_toggle(); + bMenuOff = FALSE; + break; + case PBTN_INV : + sbookflag = FALSE; + invflag = !invflag; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + break; + case PBTN_SBOOK : + invflag = FALSE; + if (dropGoldFlag) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + } + sbookflag = !sbookflag; + break; + case PBTN_TALK: + if (talkflag) TalkEnd(); + else TalkStart(); + break; + case PBTN_ATTACK: + FriendlyMode = !FriendlyMode; + break; + } + } + + if (bMenuOff) gamemenu_off(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FreeControlPan() +{ + DiabloFreePtr(pBtmBuff); + DiabloFreePtr(pManaBuff); + DiabloFreePtr(pLifeBuff); + DiabloFreePtr(pPanelText); + DiabloFreePtr(pChrPanel); + DiabloFreePtr(pSpellCels); + DiabloFreePtr(pPanelButtons); + DiabloFreePtr(pMultiBtns); + DiabloFreePtr(pTalkBtns); + DiabloFreePtr(pChrButtons); + DiabloFreePtr(pDurIcons); + DiabloFreePtr(pQLogCel); + DiabloFreePtr(pSpellBkCel); + DiabloFreePtr(pSBkBtnCel); + DiabloFreePtr(pSBkIconCels); + DiabloFreePtr(pGBoxBuff); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL InfoFit(const char * p) { + long tw = 0; + while (*p) { + BYTE c = char2print(*p++); + c = fonttrans[c]; + tw += fontkern[c]; + if (tw >= 125) return FALSE; + } + + return TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void CPrintString(int l,const char * pszStr, int just, int pnl) { + long boffset = fontofs[pnl][l]; + + int w = 0; + if (just == TEXT_CENTER) { + long tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + 2; + } + + if (tw < 288) w = (288 - tw) >> 1; + boffset += w; + } + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + 2; + if (c && (w < 288)) DrawPanelFont(boffset, c, infoclr); + boffset += fontkern[c] + 2; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PrintInfo() { + if (talkflag) return; + + int nOffset1 = 0; + int nOffset2 = 1; + if (infostr[0] != 0) { + CPrintString(0, infostr, TEXT_CENTER, pnumlines); + nOffset1 = 1; + nOffset2 = 0; + } + + for (int i = 0; i < pnumlines; i++) + CPrintString(i+nOffset1, panelstr[i], pstrjust[i], pnumlines-nOffset2); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawInfoBox() +{ + // Erase old box + CopyCtrlPan(177, 62, 288, 60, 241, 558); + + if ((!panelflag) && (!trigflag) && (cursinvitem == -1) && (!spselflag)) { + infostr[0] = 0; + infoclr = ICOLOR_WHITE; + ClearPanel(); + } + + if ((spselflag) || (trigflag)) { + infoclr = ICOLOR_WHITE; + } else { + if (curs >= ICSTART) { + if (plr[myplr].HoldItem._itype == IT_GOLD) { + int nGold = plr[myplr].HoldItem._ivalue; + const char * get_pieces_str(int nGold); + sprintf(infostr,"%i gold %s",nGold,get_pieces_str(nGold)); + } + else if (!plr[myplr].HoldItem._iStatFlag) { + ClearPanel(); + AddPanelString("Requirements not met", TEXT_CENTER); + pinfoflag = TRUE; + } + else { + if (plr[myplr].HoldItem._iIdentified) strcpy(infostr, plr[myplr].HoldItem._iIName); + else strcpy(infostr, plr[myplr].HoldItem._iName); + if (plr[myplr].HoldItem._iMagical == IMAGIC_MAGIC) infoclr = ICOLOR_BLUE; + if (plr[myplr].HoldItem._iMagical == IMAGIC_UNIQUE) infoclr = ICOLOR_GOLD; + } + } else { + // if cursinvitem != -1 then the string will already be in infostr + // if trigflag then the string will already be set as well + if (cursitem != -1) { + // @@@ drb debug +#if 0 + +int GetLDeltaItem(); + + ClearPanel(); + ItemStruct *pi = &item[cursitem]; + strcpy(infostr, pi->_iName); + sprintf(tempstr, "Delta # = %i", GetLDeltaItem()); + AddPanelString(tempstr, TEXT_CENTER); + //sprintf(tempstr, "seed = %i", pi->_iSeed); + //AddPanelString(tempstr, TEXT_CENTER); + // @@@ drb end debug +#else + GetItemStr(cursitem); +#endif + } + if (cursobj != -1) GetObjectStr(cursobj); + if (cursmonst != -1) { + if (leveltype != 0) { + infoclr = ICOLOR_WHITE; + strcpy(infostr, monster[cursmonst].mName); + ClearPanel(); + if (monster[cursmonst]._uniqtype != 0) { + infoclr = ICOLOR_GOLD; + void PrintUniqueHistory(); + PrintUniqueHistory(); + } else PrintMonstHistory(monster[cursmonst].MType->mtype); + } else strcpy(infostr, towner[cursmonst]._tName); + } + if (cursplr != -1) { + infoclr = ICOLOR_GOLD; + strcpy(infostr, plr[cursplr]._pName); + ClearPanel(); + sprintf(tempstr, "Level : %i", plr[cursplr]._pLevel); + AddPanelString(tempstr, TEXT_CENTER); + sprintf(tempstr, "Hit Points %i of %i", (plr[cursplr]._pHitPoints >> HP_SHIFT), (plr[cursplr]._pMaxHP >> HP_SHIFT)); + AddPanelString(tempstr, TEXT_CENTER); + } + } + } + //if ((pinfoflag) && (cursmonst == -1) && (cursinvitem == -1) && (curs < ICSTART)) ClearPanel(); + if ((infostr[0] != 0) || (pnumlines != 0)) PrintInfo(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PlrStringXY(int x1, int y, int x2,const char * pszStr,char col) { + long boffset = nBuffWTbl[y + 160] + x1 + 64; + int aw = x2 - x1 + 1; + int w = 0; + + // calculate string width + int tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + 1; + } + + if (tw < aw) w = (aw - tw) >> 1; + boffset += w; + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + 1; + if (c && w < aw) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + 1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PrintStringXY(int x, int y,const char * pszStr, char col) { + long boffset = nBuffWTbl[y + 160] + x + 64; + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + if (c) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + 1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PlrStringXY2(int x1, int y, int x2,const char * pszStr,char col,int a) { + long boffset = nBuffWTbl[y + 160] + x1 + 64; + int aw = x2 - x1 + 1; + int w = 0; + + // calculate string width + int tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + a; + } + + if (tw < aw) w = (aw - tw) >> 1; + boffset += w; + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + a; + if (c && w < aw) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + a; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawChr() +{ + char c; + char chrstr[64]; + int pc; + long mind, maxd; + int hper, ac; + + DrawCel(64, 511, pChrPanel, 1, 320); + + PlrStringXY(20, 32, 151, plr[myplr]._pName, ICOLOR_WHITE); + if (plr[myplr]._pClass == CLASS_WARRIOR) PlrStringXY(168, 32, 299, "Warrior", ICOLOR_WHITE); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlrStringXY(168, 32, 299, "Rogue", ICOLOR_WHITE); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlrStringXY(168, 32, 299, "Sorceror", ICOLOR_WHITE); + else if (plr[myplr]._pClass == CLASS_MONK) PlrStringXY(168, 32, 299, "Monk", ICOLOR_WHITE); + else if (plr[myplr]._pClass == CLASS_BARD) PlrStringXY(168, 32, 299, "Bard", ICOLOR_WHITE); + #endif + + sprintf(chrstr, "%i", plr[myplr]._pLevel); + PlrStringXY(66, 69, 109, chrstr, ICOLOR_WHITE); + + sprintf(chrstr, "%li", plr[myplr]._pExperience); + PlrStringXY(216, 69, 300, chrstr, ICOLOR_WHITE); + + if (plr[myplr]._pLevel == 50) { + strcpy(chrstr, "None"); + c = ICOLOR_GOLD; + } else { + sprintf(chrstr, "%li", plr[myplr]._pNextExper); + c = ICOLOR_WHITE; + } + PlrStringXY(216, 97, 300, chrstr, c); + + sprintf(chrstr, "%i", plr[myplr]._pGold); + PlrStringXY(216, 146, 300, chrstr, ICOLOR_WHITE); + + c = ICOLOR_WHITE; + if (plr[myplr]._pIBonusAC > 0) c = ICOLOR_BLUE; + if (plr[myplr]._pIBonusAC < 0) c = ICOLOR_RED; + // rjs ac = (byte)plr[myplr]._pArmorClass+plr[myplr]._pIAC+plr[myplr]._pIBonusAC; + ac = plr[myplr]._pIAC+plr[myplr]._pIBonusAC; + ac += (plr[myplr]._pDexterity / 5); + sprintf(chrstr, "%i", ac); + PlrStringXY(258, 183, 301, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pIBonusToHit > 0) c = ICOLOR_BLUE; + if (plr[myplr]._pIBonusToHit < 0) c = ICOLOR_RED; + hper = BASE_TO_HIT + (plr[myplr]._pDexterity >> 1) + plr[myplr]._pIBonusToHit; + sprintf(chrstr, "%i%%", hper); + PlrStringXY(258, 211, 301, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pIBonusDam > 0) c = ICOLOR_BLUE; + if (plr[myplr]._pIBonusDam < 0) c = ICOLOR_RED; + mind = plr[myplr]._pIMinDam; + mind += (mind * plr[myplr]._pIBonusDam) / 100; + mind += plr[myplr]._pIBonusDamMod; + if (plr[myplr].Hand1Item._itype == IT_BOW) { + if (plr[myplr]._pClass == CLASS_ROGUE) mind += plr[myplr]._pDamageMod; + else mind += (plr[myplr]._pDamageMod >> 1); + } else mind += plr[myplr]._pDamageMod; + maxd = plr[myplr]._pIMaxDam; + maxd += (maxd * plr[myplr]._pIBonusDam) / 100; + maxd += plr[myplr]._pIBonusDamMod; + if (plr[myplr].Hand1Item._itype == IT_BOW) { + if (plr[myplr]._pClass == CLASS_ROGUE) maxd += plr[myplr]._pDamageMod; + else maxd += (plr[myplr]._pDamageMod >> 1); + } else maxd += plr[myplr]._pDamageMod; + sprintf(chrstr, "%i-%i", mind, maxd); + if ((mind >= 100) || (maxd >= 100)) + PlrStringXY2(254, 239, 305, chrstr, c, -1); + else + PlrStringXY2(258, 239, 301, chrstr, c, 0); + + // Magic Resist + if (plr[myplr]._pMagResist == 0) c = ICOLOR_WHITE; + else c = ICOLOR_BLUE; + if (plr[myplr]._pMagResist < RESIST_MAX) sprintf(chrstr, "%i%%", plr[myplr]._pMagResist); + else { + c = ICOLOR_GOLD; + sprintf(chrstr, "MAX"); + } + PlrStringXY(257, 276, 300, chrstr, c); + + // Fire Resist + if (plr[myplr]._pFireResist == 0) c = ICOLOR_WHITE; + else c = ICOLOR_BLUE; + if (plr[myplr]._pFireResist < RESIST_MAX) sprintf(chrstr, "%i%%", plr[myplr]._pFireResist); + else { + c = ICOLOR_GOLD; + sprintf(chrstr, "MAX"); + } + PlrStringXY(257, 304, 300, chrstr, c); + + // Lightning Resist + if (plr[myplr]._pLghtResist == 0) c = ICOLOR_WHITE; + else c = ICOLOR_BLUE; + if (plr[myplr]._pLghtResist < RESIST_MAX) sprintf(chrstr, "%i%%", plr[myplr]._pLghtResist); + else { + c = ICOLOR_GOLD; + sprintf(chrstr, "MAX"); + } + PlrStringXY(257, 332, 300, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseStr); + if (MaxStats[plr[myplr]._pClass][0] == plr[myplr]._pBaseStr) c = ICOLOR_GOLD; + PlrStringXY( 95, 155, 126, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseMag); + if (MaxStats[plr[myplr]._pClass][1] == plr[myplr]._pBaseMag) c = ICOLOR_GOLD; + PlrStringXY( 95, 183, 126, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseDex); + if (MaxStats[plr[myplr]._pClass][2] == plr[myplr]._pBaseDex) c = ICOLOR_GOLD; + PlrStringXY( 95, 211, 126, chrstr, c); + + c = ICOLOR_WHITE; + sprintf(chrstr, "%i", plr[myplr]._pBaseVit); + if (MaxStats[plr[myplr]._pClass][3] == plr[myplr]._pBaseVit) c = ICOLOR_GOLD; + PlrStringXY( 95, 239, 126, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pStrength > plr[myplr]._pBaseStr) c = ICOLOR_BLUE; + if (plr[myplr]._pStrength < plr[myplr]._pBaseStr) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pStrength); + PlrStringXY(143, 155, 173, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pMagic > plr[myplr]._pBaseMag) c = ICOLOR_BLUE; + if (plr[myplr]._pMagic < plr[myplr]._pBaseMag) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pMagic); + PlrStringXY(143, 183, 173, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pDexterity > plr[myplr]._pBaseDex) c = ICOLOR_BLUE; + if (plr[myplr]._pDexterity < plr[myplr]._pBaseDex) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pDexterity); + PlrStringXY(143, 211, 173, chrstr, c); + + c = ICOLOR_WHITE; + if (plr[myplr]._pVitality > plr[myplr]._pBaseVit) c = ICOLOR_BLUE; + if (plr[myplr]._pVitality < plr[myplr]._pBaseVit) c = ICOLOR_RED; + sprintf(chrstr, "%i", plr[myplr]._pVitality); + PlrStringXY(143, 239, 173, chrstr, c); + + // drb.patch1.start.2/05/97 + if (plr[myplr]._pStatPts > 0) { + int CalcStatDiff(int); + if (CalcStatDiff(myplr) < plr[myplr]._pStatPts) plr[myplr]._pStatPts = CalcStatDiff(myplr); + } + // drb.patch1.end.2/05/97 + // Points to distibute + if (plr[myplr]._pStatPts > 0) { + sprintf(chrstr, "%i", plr[myplr]._pStatPts); + PlrStringXY(95, 266, 126, chrstr, ICOLOR_RED);// check x y + pc = plr[myplr]._pClass; + if (plr[myplr]._pBaseStr < MaxStats[pc][0]) DrawCel(201, 319, pChrButtons, 2+chrbtn[0], 41); + if (plr[myplr]._pBaseMag < MaxStats[pc][1]) DrawCel(201, 347, pChrButtons, 4+chrbtn[1], 41); + if (plr[myplr]._pBaseDex < MaxStats[pc][2]) DrawCel(201, 376, pChrButtons, 6+chrbtn[2], 41); + if (plr[myplr]._pBaseVit < MaxStats[pc][3]) DrawCel(201, 404, pChrButtons, 8+chrbtn[3], 41); + } + + if (plr[myplr]._pMaxHP > plr[myplr]._pMaxHPBase) c = ICOLOR_BLUE; + else c = ICOLOR_WHITE; + sprintf(chrstr, "%i", (plr[myplr]._pMaxHP >> HP_SHIFT)); + PlrStringXY( 95, 304, 126, chrstr, c); + if (plr[myplr]._pHitPoints != plr[myplr]._pMaxHP) c = ICOLOR_RED; + sprintf(chrstr, "%i", (plr[myplr]._pHitPoints >> HP_SHIFT)); + PlrStringXY(143, 304, 174, chrstr, c); + + if (plr[myplr]._pMaxMana > plr[myplr]._pMaxManaBase) c = ICOLOR_BLUE; + else c = ICOLOR_WHITE; + sprintf(chrstr, "%i", (plr[myplr]._pMaxMana >> MANA_SHIFT)); + PlrStringXY( 95, 332, 126, chrstr, c); + if (plr[myplr]._pMana != plr[myplr]._pMaxMana) c = ICOLOR_RED; + sprintf(chrstr, "%i", (plr[myplr]._pMana >> MANA_SHIFT)); + PlrStringXY(143, 332, 174, chrstr, c); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void CheckLvlBtn() { + if (lvlbtndown) return; + if ((MouseX >= 40) && (MouseX <= 81) && (MouseY >= 313) && (MouseY <= 335)) + lvlbtndown = TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ReleaseLvlBtn() { + if ((MouseX >= 40) && (MouseX <= 81) && (MouseY >= 313) && (MouseY <= 335)) + chrflag = TRUE; + lvlbtndown = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawLevelUpIcon() { + int c; + + if (stextflag != STORE_NONE) return; + if (lvlbtndown) c = 3; + else c = 2; + PlrStringXY(0, 303, 120, "Level Up", ICOLOR_WHITE); + DrawCel(104, 495, pChrButtons, c, 41); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void CheckChrBtns() { + if (chrbtndown) return; + if (! plr[myplr]._pStatPts) return; + + int pc = plr[myplr]._pClass; + for (int i = 0; i < NUMCBTNS; i++) { + switch(i) { + case 0: + if (plr[myplr]._pBaseStr >= MaxStats[pc][i]) + continue; + break; + + case 1: + if (plr[myplr]._pBaseMag >= MaxStats[pc][i]) + continue; + break; + + case 2: + if (plr[myplr]._pBaseDex >= MaxStats[pc][i]) + continue; + break; + + case 3: + if (plr[myplr]._pBaseVit >= MaxStats[pc][i]) + continue; + break; + + default: + continue; + } + + int x2 = ChrBtnPos[i][0] + ChrBtnPos[i][2]; + int y2 = ChrBtnPos[i][1] + ChrBtnPos[i][3]; + if ((MouseX >= ChrBtnPos[i][0]) && (MouseX <= x2) && (MouseY >= ChrBtnPos[i][1]) && (MouseY <= y2)) { + chrbtn[i] = TRUE; + chrbtndown = TRUE; + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void ReleaseChrBtn() { + chrbtndown = FALSE; + for (int i = 0; i < NUMCBTNS; i++) { + if (! chrbtn[i]) continue; + chrbtn[i] = FALSE; + + // was mouseup inside button? + if (MouseX < ChrBtnPos[i][0]) continue; + if (MouseX > ChrBtnPos[i][0] + ChrBtnPos[i][2]) continue; + if (MouseY < ChrBtnPos[i][1]) continue; + if (MouseY > ChrBtnPos[i][1] + ChrBtnPos[i][3]) continue; + + switch(i) { + case CBTN_STR : + NetSendCmdParam1(TRUE,CMD_ADDSTR,1); + plr[myplr]._pStatPts--; + break; + case CBTN_MAG : + NetSendCmdParam1(TRUE,CMD_ADDMAG,1); + plr[myplr]._pStatPts--; + break; + case CBTN_DEX : + NetSendCmdParam1(TRUE,CMD_ADDDEX,1); + plr[myplr]._pStatPts--; + break; + case CBTN_VIT : + NetSendCmdParam1(TRUE,CMD_ADDVIT,1); + plr[myplr]._pStatPts--; + break; + } + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static int DrawDurIcon4Item(const ItemStruct * pItem, int x, int c) { + + // don't need to draw icon if there is no item + if (pItem->_itype == -1) return x; + + // don't need to draw icon if durability is high + if (pItem->_iDurability > 5) return x; + + if (c == 0) { + if (pItem->_iClass == IC_WEAP) switch(pItem->_itype) { + case IT_SWORD: + c = 2; + break; + case IT_AXE: + c = 6; + break; + case IT_BOW: + c = 7; + break; + case IT_MACE: + c = 5; + break; + case IT_STAFF: + c = 8; + break; + } + else { + c = 1; + } + } + + // choose cel to draw based on durability + if (pItem->_iDurability > 2) c += 8; + + // draw it + DrawCel(x, 495, pDurIcons, c, 32); + + // adjust position for next durability icon + return x - 40; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawDurIcon() { + if ((chrflag || questlog) && (invflag || sbookflag)) return; + + int x = 656; + if (invflag || sbookflag) x -= 320; + const PlayerStruct * p = &plr[myplr]; + x = DrawDurIcon4Item(&p->InvBody[INVLOC_HEAD],x,4); + x = DrawDurIcon4Item(&p->InvBody[INVLOC_BODY],x,3); + x = DrawDurIcon4Item(&p->InvBody[INVLOC_HAND1],x,0); + x = DrawDurIcon4Item(&p->InvBody[INVLOC_HAND2],x,0); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void RedBack() { + long ltaboff; + + if (light4flag) ltaboff = 1536; + else ltaboff = 4608; + + app_assert(gpBuffer); + if (leveltype != 4) { + __asm { + mov edi,dword ptr [gpBuffer] + add edi,122944 + + mov ebx,dword ptr [pLightTbl] + add ebx,dword ptr [ltaboff] + + mov edx,352 +_YLp: mov ecx,640 +_XLp: mov al,byte ptr [edi] + xlatb + stosb + loop _XLp + add edi,128 + dec edx + jnz _YLp + } + } else { + __asm { + mov edi,dword ptr [gpBuffer] + add edi,122944 + + mov ebx,dword ptr [pLightTbl] + add ebx,dword ptr [ltaboff] + + mov edx,352 +_YLp2: mov ecx,640 +_XLp2: mov al,byte ptr [edi] + cmp al,32 + jb _Skip + xlatb +_Skip: stosb + loop _XLp2 + add edi,128 + dec edx + jnz _YLp2 + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void PrintSBookStr(int x, int y, BOOL cjustflag,const char * pszStr, char col) { + long boffset = nBuffWTbl[y] + x + 440; + int w = 0; + + if (cjustflag) { + int tw = 0; + const char * pszTemp = pszStr; + while (*pszTemp) { + BYTE c = char2print(*pszTemp++); + c = fonttrans[c]; + tw += fontkern[c] + 1; + } + + if (tw < 222) w = (222 - tw) >> 1; + boffset += w; + } + + while (*pszStr) { + BYTE c = char2print(*pszStr++); + c = fonttrans[c]; + w += fontkern[c] + 1; + if (c && w <= 222) DrawPanelFont(boffset, c, col); + boffset += fontkern[c] + 1; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +char GetSBookTrans(int ii, BOOL townok) { + char st, sl; + + st = STRN_BLUE; + if (plr[myplr]._pISpells & (((__int64)1) << (ii-1))) st = STRN_ORANGE; + if (plr[myplr]._pAblSpells & (1 << (ii-1))) st = STRN_GOLD; + if (st == STRN_BLUE) { + if (!CheckSpell(myplr, ii, SPT_MEMORIZED, TRUE)) st = STRN_GREY; + sl = plr[myplr]._pSplLvl[ii] + plr[myplr]._pISplLvlAdd; + if (sl <= 0 ) st = STRN_GREY; + } + if ((townok) && (currlevel == 0) && (st != STRN_GREY) && (spelldata[ii].sTownSpell == FALSE)) st = STRN_GREY; + return(st); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawSpellBook() +{ + int i, ii, x, y, mind, maxd; + __int64 tspls; + char st; + int v; + + // Drawbackground + DrawCel(384, 511, pSpellBkCel, 1, 320); + + // Draw tab + //x = (sbooktab * 51) + 391; + //DrawCel(x, 508, pSBkBtnCel, 1 + sbooktab, 51); + x = (sbooktab * 76) + 391; + DrawCel(x, 508, pSBkBtnCel, 1 + sbooktab, 76); + + // Draw Spell Icons + y = 215; + tspls = plr[myplr]._pISpells | plr[myplr]._pMemSpells | plr[myplr]._pAblSpells; + for (i = 1; i < 8; i++) { + ii = SpellPages[sbooktab][i-1]; + if (ii != -1) { + if (tspls & (((__int64) 1) << (ii-1))) { + st = GetSBookTrans(ii, TRUE); + SetSpellTrans(st); + DrawSpellCel(395, y, pSBkIconCels, SpellITbl[ii], 37); + if ((ii == plr[myplr]._pRSpell) && (st == plr[myplr]._pRSplType)) { + SetSpellTrans(STRN_GOLD); + DrawSpellCel(395, y, pSBkIconCels, 43, 37); + } + PrintSBookStr(10, y-23, FALSE, spelldata[ii].sNameText, ICOLOR_WHITE); + st = GetSBookTrans(ii, FALSE); + switch (st) { + case STRN_GOLD: + strcpy(tempstr, "Skill"); + break; + case STRN_ORANGE: + sprintf(tempstr, "Staff (%i charges)", plr[myplr].Hand1Item._iCharges); + break; + default: + v = GetManaAmount(myplr, ii) >> MANA_SHIFT; + GetDamageAmt(ii, &mind, &maxd); + if (mind != -1) sprintf(tempstr, "Mana: %i Dam: %i - %i", v, mind, maxd); + else sprintf(tempstr, "Mana: %i Dam: n/a", v); + if (ii == SPL_BONESPIRIT) sprintf(tempstr, "Mana: %i Dam: 1/3 tgt hp", v); + PrintSBookStr(10, y-1, FALSE, tempstr, ICOLOR_WHITE); + + v = plr[myplr]._pSplLvl[ii]+plr[myplr]._pISplLvlAdd; + if ( v < 0 ) v = 0; + if (v == 0) sprintf(tempstr, "Spell Level 0 - Unusable"); + else sprintf(tempstr, "Spell Level %i", v); + break; + } + PrintSBookStr(10, y-12, FALSE, tempstr, ICOLOR_WHITE); + } + } + y += 43; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckSBook() +{ + int spl; + __int64 tspls; + char st; + + // Check spell icon + if ((MouseX >= 331) && (MouseX < 368) && (MouseY >= 18) && (MouseY < 314)) { + spl = (MouseY - 18) / 43; + spl = SpellPages[sbooktab][spl]; + tspls = plr[myplr]._pISpells | plr[myplr]._pMemSpells | plr[myplr]._pAblSpells; + if (spl != -1) { + if (tspls & (((__int64)1) << (spl-1))) { + st = SPT_MEMORIZED; + if (plr[myplr]._pISpells & (((__int64)1) << (spl-1))) st = SPT_ITEM; + if (plr[myplr]._pAblSpells & (1 << (spl-1))) st = SPT_ABILITY; + + plr[myplr]._pRSpell = spl; + plr[myplr]._pRSplType = st; + force_redraw = FULLDRAW; + } + } + } + // Check spell tabs + if ((MouseX >= 327) && (MouseX < 633) && (MouseY >= 320) && (MouseY < 349)) { + sbooktab = (MouseX - 327) / 76; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------* + +BOOL CheckSBookCast() +{ + int spl; + __int64 tspls; + char st; + BOOL okflag; + + if (currlevel == 0) return(FALSE); + // Check spell icon + if ((MouseX >= 327) && (MouseX < 368) && (MouseY >= 29) && (MouseY < 346)) { + spl = (MouseY - 29) / 46; + spl = SpellPages[sbooktab][spl]; + tspls = plr[myplr]._pISpells | plr[myplr]._pMemSpells | plr[myplr]._pAblSpells; + if (spl != -1) { + if (tspls & (1 << (spl-1))) { + st = SPT_MEMORIZED; + if (plr[myplr]._pISpells & (((__int64)1) << (spl-1))) st = SPT_ITEM; + if (plr[myplr]._pAblSpells & (1 << (spl-1))) st = SPT_ABILITY; + okflag = FALSE; + switch (st) { + case SPT_ABILITY : + case SPT_MEMORIZED : + okflag = CheckSpell(myplr, spl, st, FALSE); + break; + case SPT_ITEM: + okflag = UseStaffSBook(spl); + break; + } + if (okflag) { + if (spelldata[spl].sTargeted) { + plr[myplr]._pTSpell = spl; + plr[myplr]._pTSplType = st; + NewCursor(TARGET_CURS); + } + else { + plr[myplr]._pSBkSpell = spl; + plr[myplr]._pSBkSplType = st; + NetSendCmdParam1(TRUE,CMD_SBSPELL,plr[myplr]._pSBkSpell); + } + return(TRUE); + } + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +const char * get_pieces_str(int nGold) { + if (nGold == 1) return "piece"; + return "pieces"; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void DrawGoldBox(int gold) +{ + int i; + long xOffset; + + // Initialize + xOffset = 0; + + // Draw the box + DrawCel(415, 338, pGBoxBuff, 1, 261); + // Output the strings + sprintf(tempstr, "You have %u gold",initialDropGoldValue); + PlrStringXY(366, 87, 600, tempstr, ICOLOR_GOLD); + sprintf(tempstr, "%s. How many do", get_pieces_str(initialDropGoldValue)); + PlrStringXY(366, 103, 600, tempstr, ICOLOR_GOLD); + PlrStringXY(366, 121, 600, "you want to remove?", ICOLOR_GOLD); + + if (gold > 0) { + sprintf(tempstr, "%u", gold); + PrintStringXY(388, 140, tempstr, ICOLOR_WHITE); + } + + // Get x offset for pentagram + if (gold > 0) { + for (i = 0; i < tempstr[i] != 0; i++) { + BYTE c = char2print(tempstr[i]); + c = fonttrans[c]; + xOffset += fontkern[c]+1; + } + xOffset += 452; + } else xOffset = 450; + + // Draw the pentagram + DrawCel(xOffset, 300, pSTextSpinCels, pentaspin, 12); + // Increment the pentagram spinner + pentaspin = (pentaspin & 0x7) + 1; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +// macro to convert char to int +#define ATON(c) (c - 0x30) +// keyboard constants +#define DG_CR 0x0d +#define DG_ESC 0x1b +#define DG_BACK 0x08 + +void DropGoldType(char c) //, int ivalue) +{ + char dGoldStr[6]; + + // Check if player is dead. This should prevent the multi player death frame + // gold cheat. + if ((plr[myplr]._pHitPoints >> HP_SHIFT) <= 0) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + return; + } + + // Clear the string + memset(dGoldStr, 0x00, sizeof(dGoldStr)); + // Convert number to string + _itoa(dropGoldValue, dGoldStr, 10); + + // Carriage Return was pressed so the player wants to drop some gold + if (c == DG_CR) { + if (dropGoldValue > 0) DropGold(myplr, initialDropGoldIndex); + dropGoldFlag = FALSE; + return; + } + // Escape was pressed so the player wants to quit w/out dropping gold + if (c == DG_ESC) { + dropGoldFlag = FALSE; + dropGoldValue = 0; + return; + } + // Backspace was pressed so clear the last char in the string + if (c == DG_BACK) { + dGoldStr[strlen(dGoldStr)-1] = NULL; + dropGoldValue = atoi(dGoldStr); + return; + } + // Check to see if the player typed a number and if so update the string + if ((ATON(c) >= 0) && (ATON(c) <= 9)) { + if ((dropGoldValue == 0) && (atoi(dGoldStr) > initialDropGoldValue)) + dGoldStr[0] = c; + else { + dGoldStr[strlen(dGoldStr)] = c; + if ((atoi(dGoldStr) > initialDropGoldValue) || (strlen(dGoldStr) > strlen(dGoldStr))) + return; + } + dropGoldValue = atoi(dGoldStr); + return; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DropGold(int pnum, int cii) +{ + int c; + + if (cii <= 46) { + // Item is in the InvList + c = cii - 7; + plr[pnum].InvList[c]._ivalue -= dropGoldValue; + // Modify item cursor in the InvList + if (plr[pnum].InvList[c]._ivalue > 0) SetGoldCurs(pnum, c); + else RemoveInvItem(pnum, c); + } else { + // Item is in the SpdList + c = cii - 47; + plr[pnum].SpdList[c]._ivalue -= dropGoldValue; + // Modify item cursor in the SpdList + if (plr[pnum].SpdList[c]._ivalue > 0) SetSpdbarGoldCurs(pnum, c); + else RemoveSpdBarItem(pnum, c); + } + + // Initialize hold item to gold type + SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD); + GetGoldSeed(pnum, &plr[pnum].HoldItem); + // Set hold item values + plr[pnum].HoldItem._ivalue = dropGoldValue; + plr[pnum].HoldItem._iStatFlag = TRUE; + // Set cursor arrow to gold + SetDropGoldCursor(pnum); + + // Recalculate players gold + plr[pnum]._pGold = CalculateGold(pnum); + + dropGoldValue = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetDropGoldCursor(int pnum) +{ + if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) + plr[pnum].HoldItem._iCurs = ITEM_5GOLD; + else { + if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) + plr[pnum].HoldItem._iCurs = ITEM_1GOLD; + else + plr[pnum].HoldItem._iCurs = ITEM_3GOLD; + } + + NewCursor(plr[pnum].HoldItem._iCurs + ICSTART); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +/* +void WhiteCtrlPan(int sx, int sy, int deltax, int deltay, int dx, int dy) +{ + long dest; + + dest = (dy * 768) + dx; + __asm { + mov edi,dword ptr [pBuffer] + add edi,dword ptr [dest] + + xor ebx,ebx + mov bx,word ptr [deltax] + xor edx,edx + mov dx,word ptr [deltay] + mov eax, 0ffffffffh +_CLp: mov ecx,ebx + shr ecx,1 + jnc _Tw + stosb + jecxz _Tx +_Tw: shr ecx,1 + jnc _TLp + stosw + jecxz _Tx +_TLp: rep stosd +_Tx: add edi,768 + sub edi,ebx + dec edx + jnz _CLp + } +} +*/ + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static char * print_talk_string( + char * pszStr, + int x, + int y, + long * plOffset, + int color +) { + // move to top left of talk box + x += 264; + //y += 546; + y += 534; + + int w = x; + *plOffset = nBuffWTbl[y] + x; + while (*pszStr) { + // can we fit the next character on this row? + BYTE c = char2print(*pszStr); + c = fonttrans[c]; + w += fontkern[c] + 1; + if (w > 250+264) return pszStr; + pszStr++; + + // draw char + if (c != 0) DrawPanelFont(*plOffset, c, color); + *plOffset += fontkern[c] + 1; + } + + return NULL; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define TALK_ROW_HGT 13 +void DrawTalkBox() { + + if (!talkflag) return; + app_assert(gpBuffer); + + // erase old box + CopyCtrlPan(175, 20+talkofs, 294, 5, 239, 516); + for (int i = 0; i < 10; i++) + CopyCtrlPan(175+(i>>1), 25+i+talkofs, 293-i, 1, 239+(i>>1), 521+i); + CopyCtrlPan(185, 35+talkofs, 274, 30, 249, 531); + CopyCtrlPan(180, 65+talkofs, 284, 5, 244, 561); + for (i = 0; i < 10; i++) + CopyCtrlPan(180, 70+i+talkofs, 284+i, 1, 244, 566+i); + CopyCtrlPan(170, 80+talkofs, 310, 55, 234, 576); + + // 200,373-450,456 (screen coords) + long lOffset; + char * pszStr = sgszTalkMsg; + for (int row = 0; row < 3; row++) { + pszStr = print_talk_string(pszStr,0,row * TALK_ROW_HGT,&lOffset,ICOLOR_WHITE); + if (! pszStr) break; + } + + // don't allow string to be too long + if (pszStr) *pszStr = 0; + + // draw spinnies on last row + DrawCelP(gpBuffer + lOffset, pSTextSpinCels, tspin, 12); + tspin = (tspin & 0x7) + 1; + + // draw player names + row = 0; + for (i = 0; i < MAX_PLRS; i++) { + if (i == myplr) continue; + + // are we "talking" to this player + int nColor, nCel; + if (sgbPlrTalkTbl[i]) { + nColor = ICOLOR_GOLD; + if (talkbtndown[row]) { + if (row == 0) nCel = 3; + else nCel = 4; + DrawCel(236, 596 + (row * 18), pTalkBtns, nCel, 61); + } + } else { + nColor = ICOLOR_RED; + if (row == 0) nCel = 1; + else nCel = 2; + if (talkbtndown[row]) nCel += 4; + DrawCel(236, 596 + (row * 18), pTalkBtns, nCel, 61); + } + + if (plr[i].plractive) + print_talk_string(plr[i]._pName,46,60 + (row * 18),&lOffset,nColor); + row++; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define TALK_NAME_TOP 421 +#define TALK_NAME_LEFT 172 +#define TALK_NAME_WDT 61 +#define TALK_NAME_HGT (18*(MAX_PLRS-1)) + +BOOL talk_click() { + if (! talkflag) return FALSE; + + if (MouseX < TALK_NAME_LEFT) return FALSE; + if (MouseY < TALK_NAME_TOP) return FALSE; + if (MouseX > TALK_NAME_LEFT + TALK_NAME_WDT) return FALSE; + if (MouseY > TALK_NAME_TOP + TALK_NAME_HGT) return FALSE; + + for (int i = 0; i < 3; i++) talkbtndown[i] = FALSE; + talkbtndown[(MouseY - TALK_NAME_TOP) / 18] = TRUE; + + return TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void talk_release() { + if (! talkflag) return; + + for (int i = 0; i < 3; i++) talkbtndown[i] = FALSE; + + if (MouseX < TALK_NAME_LEFT) return; + if (MouseY < TALK_NAME_TOP) return; + if (MouseX > TALK_NAME_LEFT + TALK_NAME_WDT) return; + if (MouseY > TALK_NAME_TOP + TALK_NAME_HGT) return; + + int pnum = (MouseY - TALK_NAME_TOP) / 18; + for (i = 0; (i < MAX_PLRS) && (pnum != -1); i++) + //if ((i != myplr) && plr[i].plractive) pnum--; + if (i != myplr) pnum--; + if (i <= MAX_PLRS) sgbPlrTalkTbl[i - 1] = !sgbPlrTalkTbl[i - 1]; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void TalkStart() { + if (gbMaxPlayers == 1) return; + talkflag = TRUE; + talkofs = 144; + sgszTalkMsg[0] = 0; + tspin = 1; + for (int i = 0; i < 3; i++) talkbtndown[i] = FALSE; + force_redraw = FULLDRAW; + + // reset history position + sgbTalkSavePos = sgbNextTalkSave; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void TalkEnd() { + talkflag = FALSE; + talkofs = 0; + force_redraw = FULLDRAW; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void TalkSendMsg() { + + if (sgszTalkMsg[0] != 0) { + // send message to all players who have flag set + DWORD sendmask = 0; + for (int i = 0; i < MAX_PLRS; i++) + if (sgbPlrTalkTbl[i]) sendmask |= 1 << i; + NetSendString(sendmask,sgszTalkMsg); + + // save msg in history buffer if it is unique + for (i = 0; i < MAX_TALK_SAVES; i++) { + if (! strcmp(sgszTalkSaveMsg[i],sgszTalkMsg)) + break; + } + if (i >= MAX_TALK_SAVES) { + // string is unique -- save in history buffer + strcpy(sgszTalkSaveMsg[sgbNextTalkSave],sgszTalkMsg); + sgbNextTalkSave++; + sgbNextTalkSave &= MAX_TALK_SAVES - 1; + } + else { + // string is not unique -- swap curr string with non-unique + BYTE bTemp = sgbNextTalkSave - 1; + bTemp &= MAX_TALK_SAVES - 1; + if (i != bTemp) { + strcpy(sgszTalkSaveMsg[i],sgszTalkSaveMsg[bTemp]); + strcpy(sgszTalkSaveMsg[bTemp],sgszTalkMsg); + } + } + + // reset history position + sgbTalkSavePos = sgbNextTalkSave; + + // reset talk string + sgszTalkMsg[0] = 0; + } + + TalkEnd(); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL Talk_wm_char(WPARAM wKey) { + if (gbMaxPlayers == 1) return FALSE; + if (! talkflag) return FALSE; + if (wKey < 32) return FALSE; + + int i = strlen(sgszTalkMsg); + if (i < (MAX_SEND_STR_LEN-2)) { + sgszTalkMsg[i] = (char) wKey; + sgszTalkMsg[i+1] = 0; + } + + return TRUE; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void talk_history(int nDelta) { + for (int i = 0; i < MAX_TALK_SAVES; i++) { + sgbTalkSavePos += nDelta; + sgbTalkSavePos &= MAX_TALK_SAVES - 1; + if (! sgszTalkSaveMsg[sgbTalkSavePos][0]) continue; + + // we found a string in the history + strcpy(sgszTalkMsg,sgszTalkSaveMsg[sgbTalkSavePos]); + break; + } +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL Talk_wm_keydown(WPARAM wKey) { + // only in multiplayer + if (gbMaxPlayers == 1) return FALSE; + if (! talkflag) return FALSE; + + if (wKey == VK_SPACE) { + // grab keystroke so + // program doesn't get it + } + else if (wKey == VK_ESCAPE) { + TalkEnd(); + } + else if (wKey == VK_RETURN) { + TalkSendMsg(); + } + else if (wKey == VK_BACK) { + int i = strlen(sgszTalkMsg); + if (i > 0) sgszTalkMsg[i-1] = 0; + } + else if (wKey == VK_DOWN) { + talk_history(+1); + } + else if (wKey == VK_UP) { + talk_history(-1); + } + else { + return FALSE; + } + + return TRUE; +} + + +//****************************************************************** +// conversion table -- converts funky ANSI/OEM chars to ASCII +// NOTE: only '\0' is allowed to translate to zero +// map all other characters into range 32..127 +//****************************************************************** +const BYTE gbFontTransTbl[256] = { + // control characters + 0, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 0x07 + 1, 1, 1, 1, 1, 1, 1, 1, // 0x08 - 0x0f + 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 0x17 + 1, 1, 1, 1, 1, 1, 1, 1, // 0x18 - 0x1f + + // punctuation/digits + ' ', '!', '"', '#', '$', '%', '&', '\'',// 0x20 - 0x27 + '(', ')', '*', '+', ',', '-', '.', '/', // 0x28 - 0x2f + '0', '1', '2', '3', '4', '5', '6', '7', // 0x30 - 0x37 + '8', '9', ':', ';', '<', '=', '>', '?', // 0x38 - 0x3f + + // uppercase + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', // 0x40 - 0x47 + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', // 0x48 - 0x4f + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', // 0x50 - 0x57 + 'X', 'Y', 'Z', '[', '\\',']', '^', '_', // 0x58 - 0x5f + + // lowercase + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', // 0x60 - 0x67 + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', // 0x68 - 0x6f + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', // 0x70 - 0x77 + 'x', 'y', 'z', '{', '|', '}', '~', 1, // 0x78 - 0x7f + + 'C', 'u', 'e', 'a', 'a', 'a', 'a', 'c', // 0x80 - 0x87 + 'e', 'e', 'e', 'i', 'i', 'i', 'A', 'A', // 0x88 - 0x8f + 'E', 'a', 'A', 'o', 'o', 'o', 'u', 'u', // 0x90 - 0x97 + 'y', 'O', 'U', 'c', 'L', 'Y', 'P', 'f', // 0x98 - 0x9f + + 'a', 'i', 'o', 'u', 'n', 'N', 'a', 'o', // 0xa0 - 0xa7 + '?', 1, 1, 1, 1, '!', '<', '>', // 0xa8 - 0xaf + 'o', '+', '2', '3', '\'','u', 'P', '.', // 0xb0 - 0xb7 + ',', '1', '0', '>', 1, 1, 1, '?', // 0xb8 - 0xbf + + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'C', // 0xc0 - 0xc7 + 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', // 0xc8 - 0xcf + 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'X', // 0xd0 - 0xd7 + '0', 'U', 'U', 'U', 'U', 'Y', 'b', 'B', // 0xd8 - 0xdf + + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', // 0xe0 - 0xe7 + 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', // 0xe8 - 0xef + 'o', 'n', 'o', 'o', 'o', 'o', 'o', '/', // 0xf0 - 0xf7 + '0', 'u', 'u', 'u', 'u', 'y', 'b', 'y', // 0xf8 - 0xff +}; diff --git a/SPELLDAT.CPP b/SPELLDAT.CPP new file mode 100644 index 0000000..12d982c --- /dev/null +++ b/SPELLDAT.CPP @@ -0,0 +1,1127 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Spells Data file +** +** (C)1996 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/SPELLDAT.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "effects.h" +#include "spelldat.h" +#include "spells.h" +#include "missiles.h" + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +SpellData spelldata[SPL_LAST] = +{ + { SPL_NONE, // #defines name of spell for ease of use + 0, // base cost in mana + NULL, // spell type (fire, light, misc) + NULL, // text name of spell + NULL, // text name of spell if it can be a skill + 0, // lvl book can be found + 0, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 0, // min intelligence to use + NULL, // sfx to use + { NULL, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + + { SPL_FIREBOLT, // #defines name of spell for ease of use + 6, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Firebolt", // text name of spell + "Firebolt", // text name of spell if it can be a skill + 1, // lvl book can be found + 1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 15, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_FIREBOLT, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 3, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 1000, // book cost + 50 }, // scroll cost + + { SPL_HEAL, // #defines name of spell for ease of use + 5, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Healing", // text name of spell + NULL, // text name of spell if it can be a skill + 1, // lvl book can be found + 1, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + 17, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_HEAL, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 1, // min mana for use + 20, // min number of staff charges + 40, // max number of staff charges + 1000, // book cost + 50 }, // scroll cost + + { SPL_LIGHTNING, // #defines name of spell for ease of use + 10, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Lightning", // text name of spell + NULL, // text name of spell if it can be a skill + 4, // lvl book can be found + 3, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 20, // min intelligence to use + IS_CAST4, // sfx to use + { MIT_LIGHTCTRL, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 6, // min mana for use + 20, // min number of staff charges + 60, // max number of staff charges + 3000, // book cost + 150 }, // scroll cost + + { SPL_FLASH, // #defines name of spell for ease of use + 30, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Flash", // text name of spell + NULL, // text name of spell if it can be a skill + 5, // lvl book can be found + 4, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 33, // min intelligence to use + IS_CAST4, // sfx to use + { MIT_FLASH, MIT_FLASH2, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 16, // min mana for use + 20, // min number of staff charges + 40, // max number of staff charges + 7500, // book cost + 500 }, // scroll cost + + { SPL_IDENTIFY, // #defines name of spell for ease of use + 13, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Identify", // text name of spell + "Identify", // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + 23, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_IDENTIFY, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 1, // min mana for use + 8, // min number of staff charges + 12, // max number of staff charges + 0, // book cost + 100 }, // scroll cost + + { SPL_WALL, // #defines name of spell for ease of use + 28, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Fire Wall", // text name of spell + NULL, // text name of spell if it can be a skill + 3, // lvl book can be found + 2, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 27, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_FIREWALLC, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 16, // min mana for use + 8, // min number of staff charges + 16, // max number of staff charges + 6000, // book cost + 400 }, // scroll cost + + { SPL_TOWN, // #defines name of spell for ease of use + 35, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Town Portal", // text name of spell + NULL, // text name of spell if it can be a skill + 3, // lvl book can be found + 3, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 20, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_TOWN, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 18, // min mana for use + 8, // min number of staff charges + 12, // max number of staff charges + 3000, // book cost + 200 }, // scroll cost + + { SPL_STONE, // #defines name of spell for ease of use + 60, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Stone Curse", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + 6, // lvl book can be found + 5, // lvl staff can be found +#else + -1,-1, +#endif + TRUE, // Targeted spell? + FALSE, // Avail in town? + 51, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_STONE, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 40, // min mana for use + 8, // min number of staff charges + 16, // max number of staff charges + 12000, // book cost + 800 }, // scroll cost + + { SPL_INFRA, // #defines name of spell for ease of use + 40, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Infravision", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 36, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_INFRA, NULL, NULL }, // missiles to launch per casting + 5, // mana adj per spell lvl + 20, // min mana for use + 0, // min number of staff charges + 0, // max number of staff charges + 0, // book cost + 600 }, // scroll cost + + { SPL_PHASE, // #defines name of spell for ease of use + 12, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Phasing", // text name of spell + NULL, // text name of spell if it can be a skill + 7, // lvl book can be found + 6, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 39, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_PHASE, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 4, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 3500, // book cost + 200 }, // scroll cost + + { SPL_MANASHLD, // #defines name of spell for ease of use + 33, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Mana Shield", // text name of spell + NULL, // text name of spell if it can be a skill + 6, // lvl book can be found + 5, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 25, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_MANASHIELD, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 33, // min mana for use + 4, // min number of staff charges + 10, // max number of staff charges + 16000, // book cost + 1200 }, // scroll cost + + { SPL_FIREBALL, // #defines name of spell for ease of use + 16, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Fireball", // text name of spell + NULL, // text name of spell if it can be a skill + 8, // lvl book can be found + 7, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 48, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_FIREBALL, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 10, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 8000, // book cost + 300 }, // scroll cost + + { SPL_GUARDIAN, // #defines name of spell for ease of use + 50, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Guardian", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + 9, // lvl book can be found + 8, // lvl staff can be found +#else + -1,-1, +#endif + TRUE, // Targeted spell? + FALSE, // Avail in town? + 61, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_GUARDIAN, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 30, // min mana for use + 16, // min number of staff charges + 32, // max number of staff charges + 14000, // book cost + 950 }, // scroll cost + + { SPL_CHAIN, // #defines name of spell for ease of use + 30, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Chain Lightning", // text name of spell + NULL, // text name of spell if it can be a skill + 8, // lvl book can be found + 7, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 54, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_CHAIN, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 18, // min mana for use + 20, // min number of staff charges + 60, // max number of staff charges + 11000, // book cost + 750 }, // scroll cost + + { SPL_WAVE, // #defines name of spell for ease of use + 35, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Flame Wave", // text name of spell + NULL, // text name of spell if it can be a skill + 9, // lvl book can be found + 8, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 54, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_WAVE, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 20, // min mana for use + 20, // min number of staff charges + 40, // max number of staff charges + 10000, // book cost + 650 }, // scroll cost + + { SPL_DOOM, // #defines name of spell for ease of use + 0, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Doom Serpents", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 0, // min intelligence to use + IS_CAST2, // sfx to use + { NULL, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + + { SPL_BLOODR, // #defines name of spell for ease of use + 0, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Blood Ritual", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 0, // min intelligence to use + IS_CAST2, // sfx to use + { NULL, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + + { SPL_NOVA, // #defines name of spell for ease of use + 60, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Nova", // text name of spell + NULL, // text name of spell if it can be a skill + 14, // lvl book can be found + 10, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 87, // min intelligence to use + IS_CAST4, // sfx to use + { MIT_NOVA, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 35, // min mana for use + 16, // min number of staff charges + 32, // max number of staff charges + 21000, // book cost + 1300 }, // scroll cost + + { SPL_INVIS, // #defines name of spell for ease of use + 0, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Invisibility", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 0, // min intelligence to use + IS_CAST2, // sfx to use + { NULL, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + + { SPL_FLAME, // #defines name of spell for ease of use + 11, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Inferno", // text name of spell + NULL, // text name of spell if it can be a skill + 3, // lvl book can be found + 2, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 20, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_FLAMEC, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 6, // min mana for use + 20, // min number of staff charges + 40, // max number of staff charges + 2000, // book cost + 100 }, // scroll cost + + { SPL_GOLEM, // #defines name of spell for ease of use + 100, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Golem", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + 11, // lvl book can be found + 9, // lvl staff can be found +#else + -1,-1, +#endif + FALSE, // Targeted spell? + FALSE, // Avail in town? + 81, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_GOLEM, NULL, NULL }, // missiles to launch per casting + 6, // mana adj per spell lvl + 60, // min mana for use + 16, // min number of staff charges + 32, // max number of staff charges + 18000, // book cost + 1100 }, // scroll cost + + #if 0 + { SPL_BLOODB, // #defines name of spell for ease of use + 0, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Blood Boil", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 0, // min intelligence to use + IS_CAST8, // sfx to use + { NULL, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 0, // min number of staff charges + 0, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + #else + { SPL_RAGE, // #defines name of spell for ease of use + 15, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Rage", // text name of spell + "Rage", // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 0, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RAGE, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 1, // min mana for use + 0, // min number of staff charges + 0, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + #endif + + { SPL_TELE, // #defines name of spell for ease of use + 35, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Teleport", // text name of spell + NULL, // text name of spell if it can be a skill + 14, // lvl book can be found + 12, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 105, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_TELE, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 15, // min mana for use + 16, // min number of staff charges + 32, // max number of staff charges + 20000, // book cost + 1250 }, // scroll cost + + { SPL_APOCA, // #defines name of spell for ease of use + 150, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Apocalypse", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + 19, // lvl book can be found + 15, // lvl staff can be found +#else + -1,-1, +#endif + FALSE, // Targeted spell? + FALSE, // Avail in town? + 149, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_APOCA, NULL, NULL }, // missiles to launch per casting + 6, // mana adj per spell lvl + 90, // min mana for use + 8, // min number of staff charges + 12, // max number of staff charges + 30000, // book cost + 2000 }, // scroll cost + + { SPL_ETHER, // #defines name of spell for ease of use + 100, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Etherealize", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + -1, // lvl book can be found + -1, // lvl staff can be found +#else + -1,-1, +#endif + FALSE, // Targeted spell? + FALSE, // Avail in town? + 93, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_ETHER, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 100, // min mana for use + 2, // min number of staff charges + 6, // max number of staff charges + 26000, // book cost + 1600 }, // scroll cost + + { SPL_REPAIR, // #defines name of spell for ease of use + 0, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Item Repair", // text name of spell + "Item Repair", // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + -1, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_REPAIR, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + + { SPL_RECHARGE, // #defines name of spell for ease of use + 0, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Staff Recharge", // text name of spell + "Staff Recharge", // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + -1, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_RECHARGE, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + + { SPL_DISARM, // #defines name of spell for ease of use + 0, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Trap Disarm", // text name of spell + "Trap Disarm", // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + -1, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_DISARM, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 0, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 0, // book cost + 0 }, // scroll cost + + { SPL_ELEMENT, // #defines name of spell for ease of use + 35, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Elemental", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + 8, // lvl book can be found + 6, // lvl staff can be found +#else + -1,-1, +#endif + FALSE, // Targeted spell? + FALSE, // Avail in town? + 68, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_ELEMENT, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 20, // min mana for use + 20, // min number of staff charges + 60, // max number of staff charges + 10500, // book cost + 700 }, // scroll cost + + { SPL_CBOLT, // #defines name of spell for ease of use + 6, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Charged Bolt", // text name of spell + NULL, // text name of spell if it can be a skill + 1, // lvl book can be found + 1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 25, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_CBOLT, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 6, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 1000, // book cost + 50 }, // scroll cost + + { SPL_HBOLT, // #defines name of spell for ease of use + 7, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Holy Bolt", // text name of spell + NULL, // text name of spell if it can be a skill + 1, // lvl book can be found + 1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 20, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_HBOLT, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 3, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 1000, // book cost + 50 }, // scroll cost + + { SPL_RESURRECT, // #defines name of spell for ease of use + 20, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Resurrect", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + 5, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + 30, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RESURRECT, NULL, NULL }, // missiles to launch per casting + 0, // mana adj per spell lvl + 20, // min mana for use + 4, // min number of staff charges + 10, // max number of staff charges + 4000, // book cost + 250 }, // scroll cost + + { SPL_TELEKINESIS, // #defines name of spell for ease of use + 15, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Telekinesis", // text name of spell + NULL, // text name of spell if it can be a skill + 2, // lvl book can be found + 2, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 33, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_TELEKINESIS, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 8, // min mana for use + 20, // min number of staff charges + 40, // max number of staff charges + 2500, // book cost + 200 }, // scroll cost + + { SPL_HEALOTHER, // #defines name of spell for ease of use + 5, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Heal Other", // text name of spell + NULL, // text name of spell if it can be a skill + 1, // lvl book can be found + 1, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + 17, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_HEALOTHER, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 1, // min mana for use + 20, // min number of staff charges + 40, // max number of staff charges + 1000, // book cost + 50 }, // scroll cost + + { SPL_BSTAR, // #defines name of spell for ease of use + 25, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Blood Star", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + 14, // lvl book can be found + 13, // lvl staff can be found +#else + -1,-1, +#endif + FALSE, // Targeted spell? + FALSE, // Avail in town? + 70, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_FLARE, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 14, // min mana for use + 20, // min number of staff charges + 60, // max number of staff charges + 27500, // book cost + 1800 }, // scroll cost + + { SPL_BONESPIRIT, // #defines name of spell for ease of use + 24, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Bone Spirit", // text name of spell + NULL, // text name of spell if it can be a skill +#if IS_VERSION(RETAIL) + 9, // lvl book can be found + 7, // lvl staff can be found +#else + -1,-1, +#endif + FALSE, // Targeted spell? + FALSE, // Avail in town? + 34, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_BONESPIRIT, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 12, // min mana for use + 20, // min number of staff charges + 60, // max number of staff charges + 11500, // book cost + 800 }, // scroll cost + + { SPL_MANA, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Mana", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + 5, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + 17, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_MANA, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 1, // min mana for use + 12, // min number of staff charges + 24, // max number of staff charges + 1000, // book cost + 50 }, // scroll cost + + { SPL_FMANA, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "the Magi", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + 20, // lvl staff can be found + FALSE, // Targeted spell? + TRUE, // Avail in town? + 45, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_FMANA, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 1, // min mana for use + 15, // min number of staff charges + 30, // max number of staff charges + 100000, // book cost + 200 }, // scroll cost + + { SPL_RANDOM, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "the Jester", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + 4, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 30, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RANDOM, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 1, // min mana for use + 15, // min number of staff charges + 30, // max number of staff charges + 100000, // book cost + 200 }, // scroll cost + + { SPL_LTWALL, // #defines name of spell for ease of use + 28, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Lightning Wall", // text name of spell + NULL, // text name of spell if it can be a skill + 3, // lvl book can be found + 2, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 27, // min intelligence to use + IS_CAST4, // sfx to use + { MIT_LIGHTWALLC, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 16, // min mana for use + 8, // min number of staff charges + 16, // max number of staff charges + 6000, // book cost + 400 }, // scroll cost + + { SPL_IMMOLATION, // #defines name of spell for ease of use + 60, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Immolation", // text name of spell + NULL, // text name of spell if it can be a skill + 14, // lvl book can be found + 10, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 87, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_IMMOLATION, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 35, // min mana for use + 16, // min number of staff charges + 32, // max number of staff charges + 21000, // book cost + 1300 }, // scroll cost + + { SPL_TELESTAIRS, // #defines name of spell for ease of use + 35, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Warp", // text name of spell + NULL, // text name of spell if it can be a skill + 3, // lvl book can be found + 3, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 25, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_TELESTAIRS, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 18, // min mana for use + 8, // min number of staff charges + 12, // max number of staff charges + 3000, // book cost + 200 }, // scroll cost + + { SPL_REFLECT, // #defines name of spell for ease of use + 35, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Reflect", // text name of spell + NULL, // text name of spell if it can be a skill + 3, // lvl book can be found + 3, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 25, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_REFLECT, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 15, // min mana for use + 8, // min number of staff charges + 12, // max number of staff charges + 3000, // book cost + 200 }, // scroll cost + + { SPL_BERSERK, // #defines name of spell for ease of use + 35, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Berserk", // text name of spell + NULL, // text name of spell if it can be a skill + 3, // lvl book can be found + 3, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 35, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_BERSERK, NULL, NULL }, // missiles to launch per casting + 3, // mana adj per spell lvl + 15, // min mana for use + 8, // min number of staff charges + 12, // max number of staff charges + 3000, // book cost + 200 }, // scroll cost + + { SPL_RINGOFFIRE, // #defines name of spell for ease of use + 28, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Ring of Fire", // text name of spell + NULL, // text name of spell if it can be a skill + 5, // lvl book can be found + 5, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 27, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_FLAMEBOX, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 16, // min mana for use + 8, // min number of staff charges + 16, // max number of staff charges + 6000, // book cost + 400 }, // scroll cost + + { SPL_SHOWMAGITEMS, // #defines name of spell for ease of use + 15, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Search", // text name of spell + "Search", // text name of spell if it can be a skill + 1, // lvl book can be found + 3, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 25, // min intelligence to use + IS_CAST6, // sfx to use + { MIT_SHOWMAGITEMS, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 1, // min mana for use + 8, // min number of staff charges + 12, // max number of staff charges + 3000, // book cost + 200 }, // scroll cost + + { SPL_RUNEOFFIRE, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Rune of Fire", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 48, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RUNEOFFIRE, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 10, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 8000, // book cost + 300 }, // scroll cost + + { SPL_RUNEOFLIGHT, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Rune of Light", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 48, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RUNEOFLIGHT, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 10, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 8000, // book cost + 300 }, // scroll cost + + { SPL_RUNEOFNOVA, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Rune of Nova", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 48, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RUNEOFNOVA, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 10, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 8000, // book cost + 300 }, // scroll cost + + { SPL_RUNEOFIMMOLATION, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Rune of Immolation", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 48, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RUNEOFIMMOLATION, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 10, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 8000, // book cost + 300 }, // scroll cost + + { SPL_RUNEOFSTONE, // #defines name of spell for ease of use + 255, // base cost in mana + ST_MISC, // spell type (fire, light, misc) + "Rune of Stone", // text name of spell + NULL, // text name of spell if it can be a skill + -1, // lvl book can be found + -1, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 48, // min intelligence to use + IS_CAST8, // sfx to use + { MIT_RUNEOFSTONE, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 10, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 8000, // book cost + 300 }, // scroll cost + +#if defined (HELLFIRE2) + { SPL_RINGOFLIGHT, // #defines name of spell for ease of use + 28, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Ring of Light", // text name of spell + NULL, // text name of spell if it can be a skill + 6, // lvl book can be found + 6, // lvl staff can be found + TRUE, // Targeted spell? + FALSE, // Avail in town? + 23, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_LIGHTBOX, NULL, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 16, // min mana for use + 8, // min number of staff charges + 16, // max number of staff charges + 6000, // book cost + 400 }, // scroll cost + + { SPL_AURA, // #defines name of spell for ease of use + 30, // base cost in mana + ST_LIGHT, // spell type (fire, light, misc) + "Aura", // text name of spell + NULL, // text name of spell if it can be a skill + 1, // lvl book can be found + 1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 33, // min intelligence to use + IS_CAST4, // sfx to use + { MIT_AURA, MIT_AURA2, NULL }, // missiles to launch per casting + 2, // mana adj per spell lvl + 16, // min mana for use + 20, // min number of staff charges + 40, // max number of staff charges + 7500, // book cost + 500 }, // scroll cost + + { SPL_SPIRALFIREBALL, // #defines name of spell for ease of use + 6, // base cost in mana + ST_FIRE, // spell type (fire, light, misc) + "Spiral Firebolt", // text name of spell + NULL, // text name of spell if it can be a skill + 1, // lvl book can be found + 1, // lvl staff can be found + FALSE, // Targeted spell? + FALSE, // Avail in town? + 15, // min intelligence to use + IS_CAST2, // sfx to use + { MIT_SPIRALFIREBALL, NULL, NULL }, // missiles to launch per casting + 1, // mana adj per spell lvl + 3, // min mana for use + 40, // min number of staff charges + 80, // max number of staff charges + 1000, // book cost + 50 }, // scroll cost +#endif // HELLFIRE2 +}; diff --git a/SPELLDAT.H b/SPELLDAT.H new file mode 100644 index 0000000..988b78d --- /dev/null +++ b/SPELLDAT.H @@ -0,0 +1,53 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/SPELLDAT.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define ST_FIRE 0 +#define ST_LIGHT 1 +#define ST_MISC 2 + +#define MA_MAX 255 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + BYTE sName; // #defines name of spell for ease of use + BYTE sManaCost; // base cost in mana + BYTE sType; // spell type (fire, light, misc) + char *sNameText; // text name of spell + char *sSkillText; // text name of spell if can be a skill + int sBookLvl; // lvl book can be found + int sStaffLvl; // lvl staff can be found + BOOL sTargeted; // Targeted spell? + BOOL sTownSpell; // Avail in town? + int sMinInt; // min intelligence to use + BYTE sSFX; // sfx to use + BYTE sMissiles[3]; // missiles to launch per casting + BYTE sManaAdj; // mana adj per spell lvl + BYTE sMinMana; // min mana for use + int sStaffMin; // min staff charges + int sStaffMax; // max staff charges + int sBookCost; // book cost + int sStaffCost; // staff cost +} SpellData; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern SpellData spelldata[]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ diff --git a/SPELLS.CPP b/SPELLS.CPP new file mode 100644 index 0000000..8bf608d --- /dev/null +++ b/SPELLS.CPP @@ -0,0 +1,255 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Spells file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/SPELLS.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "engine.h" +#include "sound.h" +#include "spells.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "monster.h" +#include "cursor.h" +#include "missiles.h" +#include "control.h" +#include "inv.h" +#include "spelldat.h" +#include "gamemenu.h" + +extern void StartStand(int, int); + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +int GetManaAmount(int id, int sn) +{ + int i; + int sl, ma, adj; + + // get total mana adjustments + adj = 0; + sl = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd - 1; + if (sl < 0 ) sl = 0; + for (i = sl; i > 0; i--) adj += spelldata[sn].sManaAdj; + + // special cases for adjustments + //if (sn == SPL_CBOLT) adj = -adj; + if (sn == SPL_FIREBOLT) adj = adj >> 1; + if (sn == SPL_RESURRECT && sl > 0) { + adj = 0; + for (i = sl; i > 0; i--) adj += spelldata[sn].sManaCost >> 3; + } + + // calc mana cost with adj + if (spelldata[sn].sManaCost == MA_MAX) + ma = (((BYTE)plr[id]._pMaxManaBase) - adj) << MANA_SHIFT; + else + ma = (spelldata[sn].sManaCost - adj) << MANA_SHIFT; + + // special cases for mana cost + if (sn == SPL_HEAL) ma = ((plr[id]._pLevel << 1) + spelldata[SPL_HEAL].sManaCost - adj) << MANA_SHIFT; + if (sn == SPL_HEALOTHER) ma = ((plr[id]._pLevel << 1) + spelldata[SPL_HEAL].sManaCost - adj) << MANA_SHIFT; + if (sn == SPL_RESURRECT) { + adj = 0; + for (i = sl; i > 0; i--) adj += spelldata[sn].sManaCost; + } + + // calc mana cost with class adj + if (plr[id]._pClass == CLASS_SORCEROR) + { + ma >>= 1; + } + else if (plr[id]._pClass == CLASS_ROGUE || + plr[id]._pClass == CLASS_MONK || + plr[id]._pClass == CLASS_BARD) + { + ma -= (ma >> 2); + } + + // total final mana amount + if (spelldata[sn].sMinMana > (ma >> MANA_SHIFT)) ma = spelldata[sn].sMinMana << MANA_SHIFT; + //if (ma <= 0) ma = 1 << MANA_SHIFT; + ma = (ma * (100 - plr[id]._pISplCost)) / 100; + + return(ma); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void UseMana(int id, int sn) +{ + int ma; + + if (id != myplr) return; + // calc mana amounts seperated by the way spell was cast + switch (plr[id]._pSplType) { + case SPT_ABILITY: + case SPT_NONE: + break; + + case SPT_SCROLL: + RemoveScroll(id); + break; + + case SPT_ITEM: + UseStaffCharge(id); + break; + + case SPT_MEMORIZED: +#if CHEATS + if (!cheatflag) { + ma = GetManaAmount(id, sn); + plr[id]._pMana -= ma; + plr[id]._pManaBase -= ma; + drawmanaflag = TRUE; + } +#else + ma = GetManaAmount(id, sn); + plr[id]._pMana -= ma; + plr[id]._pManaBase -= ma; + drawmanaflag = TRUE; +#endif + break; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL CheckSpell(int id, int sn, char st, BOOL manaonly) +{ + int ma; + + // various checks to see if a player can cast a spell (assumes they + // already have casting available by some means, staff, scroll, etc.) +#if CHEATS + if (cheatflag) return(TRUE); +#endif + if ((!manaonly) && (curs != GLOVE_CURS)) return(FALSE); + if (st == SPT_ABILITY) return(TRUE); + + if ((GetSpellLevel(id, sn)) <= 0) return(FALSE); + + ma = GetManaAmount(id, sn); + if (plr[id]._pMana < ma) return(FALSE); + + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void CastSpell(int id, int spl, int sx, int sy, int dx, int dy, int caster, int spllvl) +{ + int i; + int dir; + + switch (caster) { + case MI_PLR: + dir = plr[id]._pdir; + caster = MI_ENEMYMONST; // delete later + if (spl == SPL_WALL || spl == SPL_LTWALL) dir = plr[id]._pVar3; + break; + case MI_MONST: + dir = monster[id]._mdir; + break; + } + + for (i = 0; (spelldata[spl].sMissiles[i] != NULL) && (i < 3); i++) + AddMissile(sx, sy, dx, dy, dir, spelldata[spl].sMissiles[i], caster, id, 0, spllvl); + + if (spelldata[spl].sMissiles[0] == MIT_TOWN) UseMana(id, SPL_TOWN); + if (spelldata[spl].sMissiles[0] == MIT_CBOLT) { + UseMana(id, SPL_CBOLT); + for (i = (spllvl >> 1) + 3; i > 0; i--) + AddMissile(sx, sy, dx, dy, dir, MIT_CBOLT, caster, id, 0, spllvl); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoResurrect(int pnum, int rid) +{ + if ((char) rid != -1) + AddMissile(plr[rid]._px, plr[rid]._py, plr[rid]._px, plr[rid]._py, 0, MIT_RESURRECTBEAM, MI_PLR, pnum, 0, 0); + + if (pnum == myplr) { + NewCursor(GLOVE_CURS); + } + + if (((char) rid) != -1) { + // if I am casting on a live person bail out + if (plr[rid]._pHitPoints != 0) return; + if (rid == myplr) { + deathflag = FALSE; + gamemenu_off(); + drawhpflag = TRUE; + drawmanaflag = TRUE; + } + ClrPlrPath(rid); + plr[rid].destAction = PCMD_NOTHING; + plr[rid]._pInvincible = FALSE; + SetPlayerHitPoints(rid, 10 << HP_SHIFT); + plr[rid]._pHPBase = plr[rid]._pHitPoints - (plr[rid]._pMaxHP - plr[rid]._pMaxHPBase); + plr[rid]._pMana = 0; + plr[rid]._pManaBase = plr[rid]._pMana - (plr[rid]._pMaxMana - plr[rid]._pMaxManaBase); + CalcPlrInv(rid, TRUE); + if (plr[rid].plrlevel == currlevel) StartStand(rid, plr[rid]._pdir); + else plr[rid]._pmode = PM_STAND; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void DoHealOther(int pnum, int rid) +{ + int i; + long l; + + if (pnum == myplr) { + NewCursor(GLOVE_CURS); + } + + if (((char) rid) != -1) { + // if I am casting on a dead person bail out + if ((plr[rid]._pHitPoints >> HP_SHIFT) <= 0) return; + + l = (random(57, 10) + 1) << HP_SHIFT; + for (i = 0; i < plr[pnum]._pLevel; i++) l += ((random(57, 4) + 1) << HP_SHIFT); + for (i = 0; i < GetSpellLevel(pnum, SPL_HEALOTHER); i++) l += ((random(57, 6) + 1) << HP_SHIFT); + if (plr[pnum]._pClass == CLASS_WARRIOR + || plr[pnum]._pClass == CLASS_BARBARIAN) + { + l = l << 1; + } + else if (plr[pnum]._pClass == CLASS_ROGUE || + plr[pnum]._pClass == CLASS_BARD) + { + l += (l >> 1); + } + else if (plr[pnum]._pClass == CLASS_MONK) + { + l += (l << 1); + } + plr[rid]._pHitPoints += l; + if (plr[rid]._pHitPoints > plr[rid]._pMaxHP) plr[rid]._pHitPoints = plr[rid]._pMaxHP; + plr[rid]._pHPBase += l; + if (plr[rid]._pHPBase > plr[rid]._pMaxHPBase) plr[rid]._pHPBase = plr[rid]._pMaxHPBase; + drawhpflag = TRUE; + } +} diff --git a/SPELLS.H b/SPELLS.H new file mode 100644 index 0000000..1166882 --- /dev/null +++ b/SPELLS.H @@ -0,0 +1,149 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/SPELLS.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define PRE_BETA IS_VERSION(BETA) +#define PRE_NONE TRUE +#define PRE_FIREBOLT TRUE +#define PRE_HEAL TRUE +#define PRE_LIGHTNING TRUE +#define PRE_FLASH TRUE +#define PRE_IDENTIFY TRUE +#define PRE_WALL TRUE +#define PRE_TOWN TRUE +#define PRE_STONE TRUE +#define PRE_INFRA TRUE +#define PRE_PHASE TRUE +#define PRE_MANASHLD TRUE +#define PRE_FIREBALL TRUE +#define PRE_GUARDIAN FALSE +#define PRE_CHAIN TRUE +#define PRE_WAVE TRUE +#define PRE_DOOM FALSE +#define PRE_BLOODR FALSE +#define PRE_NOVA TRUE +#define PRE_INVIS FALSE +#define PRE_FLAME TRUE +#define PRE_GOLEM TRUE +#define PRE_BLOODB TRUE +#define PRE_TELE TRUE +#define PRE_APOCA FALSE +#define PRE_ETHER FALSE +#define PRE_REPAIR TRUE +#define PRE_RECHARGE TRUE +#define PRE_DISARM TRUE +#define PRE_ELEMENT TRUE +#define PRE_CBOLT TRUE +#define PRE_HBOLT TRUE +#define PRE_RESURRECT TRUE +#define PRE_TELEKINESIS TRUE +#define PRE_HEALOTHER TRUE +#define PRE_BSTAR FALSE +#define PRE_BONESPIRIT FALSE + +#define SPL_NONE 0 +#define SPL_FIREBOLT 1 +#define SPL_HEAL 2 +#define SPL_LIGHTNING 3 +#define SPL_FLASH 4 +#define SPL_IDENTIFY 5 +#define SPL_WALL 6 +#define SPL_TOWN 7 +#define SPL_STONE 8 +#define SPL_INFRA 9 +#define SPL_PHASE 10 +#define SPL_MANASHLD 11 +#define SPL_FIREBALL 12 +#define SPL_GUARDIAN 13 +#define SPL_CHAIN 14 +#define SPL_WAVE 15 +#define SPL_DOOM 16 +#define SPL_BLOODR 17 +#define SPL_NOVA 18 +#define SPL_INVIS 19 +#define SPL_FLAME 20 +#define SPL_GOLEM 21 +//#define SPL_BLOODB 22 +#define SPL_RAGE 22 +#define SPL_TELE 23 +#define SPL_APOCA 24 +#define SPL_ETHER 25 +#define SPL_REPAIR 26 +#define SPL_RECHARGE 27 +#define SPL_DISARM 28 +#define SPL_ELEMENT 29 +#define SPL_CBOLT 30 +#define SPL_HBOLT 31 +#define SPL_RESURRECT 32 +#define SPL_TELEKINESIS 33 +#define SPL_HEALOTHER 34 +#define SPL_BSTAR 35 +#define SPL_BONESPIRIT 36 + +// added 7/31 by donald +#define SPL_MANA 37 // staff versions of mana potions +#define SPL_FMANA 38 +#define SPL_RANDOM 39 +// Added 9/5/97 by Gary +#define SPL_LTWALL 40 +#define SPL_IMMOLATION 41 +#define SPL_TELESTAIRS 42 +#define SPL_REFLECT 43 +#define SPL_BERSERK 44 +#define SPL_RINGOFFIRE 45 +#define SPL_SHOWMAGITEMS 46 +#define SPL_RUNEOFFIRE 47 +#define SPL_RUNEOFLIGHT 48 +#define SPL_RUNEOFNOVA 49 +#define SPL_RUNEOFIMMOLATION 50 +#define SPL_RUNEOFSTONE 51 + + +#if defined(HELLFIRE2) +#define SPL_RINGOFLIGHT 46 +#define SPL_AURA 48 +#define SPL_SPIRALFIREBALL 49 +#endif // HELLFIRE2 + +#define SPL_LAST (SPL_RUNEOFSTONE + 1) + +#define MAXSPELLS SPL_LAST +#define SPELLCAP 15 + +#define SPT_ABILITY 0 +#define SPT_MEMORIZED 1 +#define SPT_SCROLL 2 +#define SPT_ITEM 3 +#define SPT_NONE 4 + +#define MI_PLR 0 +#define MI_MONST 1 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void CastSpell(int, int, int, int, int, int, int, int); +void DoResurrect(int, int); +void DoHealOther(int, int); +void UseMana(int, int); +int GetManaAmount(int, int); +BOOL CheckSpell(int, int, char, BOOL); diff --git a/STORES.CPP b/STORES.CPP new file mode 100644 index 0000000..be70fbf --- /dev/null +++ b/STORES.CPP @@ -0,0 +1,3035 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Control panel file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/STORES.CPP 6 3/19/97 11:19a Jmcreynolds $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "engine.h" +#include "control.h" +#include "scrollrt.h" +#include "gendung.h" +#include "items.h" +#include "itemdat.h" +#include "player.h" +#include "stores.h" +#include "minitext.h" +#include "cursor.h" +#include "inv.h" +#include "quests.h" +#include "effects.h" +#include "multi.h" +#include "towners.h" +#include "spelldat.h" +#include "textdat.h" +#include "spells.h" + +/*-----------------------------------------------------------------------** +** Local defines +**-----------------------------------------------------------------------*/ + +#define STEXT_SMALL 0 +#define STEXT_LARGE 1 + +#define MAXHOLDITEMS 48 + +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ + +BYTE *pSTextBoxCels; +BYTE *pSTextSpinCels; +BYTE *pSTextSlidCels; + +char stextflag, stextsize; +int stextspin, stextsel; +int stextlhold, stextshold, stextvhold; + +BOOL stextscrl; +int stextsval, stextsmax; +int stextup, stextdown; + +char stextscrlubtn, stextscrldbtn; + +int SStringY[24] = { + 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, + 156, 168, 180, 192, 204, 216, 228, 240, 252, 264, 276 }; + +STextStruct stext[NUMSTLINES]; + +ItemStruct smithitem[MAXSMITHITEMS]; + +ItemStruct premiumitem[MAXPREMIUM]; +int numpremium, premiumlevel; + +ItemStruct witchitem[MAXWITCHITEMS]; + +ItemStruct boyitem; +int boylevel; + +ItemStruct healitem[MAXHEALITEMS]; + +ItemStruct storehold[MAXHOLDITEMS]; +char storehidx[MAXHOLDITEMS]; + +ItemStruct golditem; + +int storenumh; + +int gossipstart, gossipend; + +/*-----------------------------------------------------------------------*/ + +char *talkname[] = { + "Griswold", + "Pepin", + "", + "Ogden", + "Cain", + "Farnham", + "Adria", + "Gillian", + "Wirt" +}; + +int talker; +extern QuestData questlist[]; + +/*-----------------------------------------------------------------------*/ + +void ClearSText(int, int); + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void InitStores() +{ + app_assert(! pSTextBoxCels); + pSTextBoxCels = LoadFileInMemSig("Data\\TextBox2.CEL",NULL,'STOR'); + pSTextSpinCels = LoadFileInMemSig("Data\\PentSpn2.CEL",NULL,'STOR'); + pSTextSlidCels = LoadFileInMemSig("Data\\TextSlid.CEL",NULL,'STOR'); + ClearSText(0, NUMSTLINES); + stextflag = STORE_NONE; + stextspin = 1; + stextsize = STEXT_SMALL; + stextscrl = FALSE; + numpremium = 0; + premiumlevel = 1; + for (int i = 0; i < MAXPREMIUM; i++) premiumitem[i]._itype = -1; + boyitem._itype = -1; + boylevel = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void SetupTownStores() +{ + int i, l; + + // PATCH2.JMM.3/10/97 + SetRndSeed( glSeedTbl[currlevel] * GetTickCount( ) ); + // ENDPATCh2.JMM.3/10/97 + + + // How deep have I gone? + if (gbMaxPlayers == 1) { + l = 0; + for (i = 0; i < NUMLEVELS; i++) + if (plr[myplr]._pLvlVisited[i]) l = i; + } else { + l = plr[myplr]._pLevel >> 1; + } + + // Make sure they carry relevant items all the time + l += 2; + if (l < 6) l = 6; + if (l > 16) l = 16; + + // Setup a gold item for transactions + SpawnStoreGold(); + // Setup blacksmith items + SpawnSmith(l); + // Setup witch items + SpawnWitch(l); + // Setup healer items + SpawnHealer(l); + + // Setup boy items can alter the random seed + SpawnBoy(plr[myplr]._pLevel); + // SpawnPremium can alter the random seed + SpawnPremium(myplr); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void FreeStoreMem() +{ + DiabloFreePtr(pSTextBoxCels); + DiabloFreePtr(pSTextSpinCels); + DiabloFreePtr(pSTextSlidCels); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +BOOL StoreQuestTalk(int t) +{ + int i; + for (i = 0; i < MAXQUESTS; i++) { + if ((quests[i]._qactive == QUEST_NOTDONE) && (Qtalklist[t][i] != -1)) return(TRUE); + } + return(FALSE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void DrawSTextBack() +{ + DrawCel(408, 487, pSTextBoxCels, 1, 271); + + app_assert(gpBuffer); + __asm { + mov edi,dword ptr [gpBuffer] + add edi,372123 + + xor eax,eax + mov edx,148 +_YLp: mov ecx,132 +_XLp1: stosb + inc edi + loop _XLp1 + stosb + sub edi,1033 + mov ecx,132 +_XLp2: inc edi + stosb + loop _XLp2 + sub edi,1032 + dec edx + jnz _YLp + mov ecx,132 +_XLp3: stosb + inc edi + loop _XLp3 + stosb + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PrintSString(int x, int y, BOOL cjustflag, char str[], char col, int val) +{ + long boffset; + int sl,i,w,tw,aw,xx,yy,xa; + char valstr[32]; + + yy = SStringY[y] + stext[y]._syoff; + if (stextsize == STEXT_SMALL) xa = 416; + else xa = 96; + boffset = nBuffWTbl[yy + 204] + x + xa; + sl = strlen(str); + if (stextsize == STEXT_SMALL) aw = 257; + else aw = 577; + w = 0; + if (cjustflag) { + tw = 0; + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + tw += fontkern[c]+1; + } + if (tw < aw) w = (aw - tw) >> 1; + boffset += w; + } + if (stextsel == y) { + if (cjustflag) xx = x + w + xa - 20; + else xx = x + xa - 20; + DrawCel(xx, yy + 205, pSTextSpinCels, stextspin, 12); + } + for (i = 0; i < sl; i++) { + BYTE c = char2print(str[i]); + c = fonttrans[c]; + w += fontkern[c]+1; + if ((c != 0) && (w <= aw)) DrawPanelFont(boffset, c, col); + boffset += fontkern[c]+1; + } + if ((!cjustflag) && (val >= 0)) { + sprintf(valstr, "%i", val); + boffset = nBuffWTbl[yy + 204] + 656 - x; + sl = strlen(valstr); + for (i = sl-1; i >= 0; i--) { + BYTE c = char2print(valstr[i]); + c = fonttrans[c]; + boffset -= fontkern[c]+1; + if (c != 0) DrawPanelFont(boffset, c, col); + } + } + if (stextsel == y) { + if (cjustflag) xx = x + w + xa + 4; + else xx = 660 - x; + DrawCel(xx, yy + 205, pSTextSpinCels, stextspin, 12); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawSLine(int y) +{ + long soffset, doffset; + long width, wadd; + int yy; + + yy = SStringY[y]; + if (stextsize == STEXT_LARGE) { + soffset = 142170; + doffset = nBuffWTbl[yy + 198] + 90; + width = 146; + wadd = 182; + } else { + soffset = 142490; + doffset = nBuffWTbl[yy + 198] + 410; + width = 66; + wadd = 502; + } + + app_assert(gpBuffer); + __asm { + mov esi,dword ptr [gpBuffer] + mov edi,esi + add esi,dword ptr [soffset] + add edi,dword ptr [doffset] + + mov ebx,dword ptr [wadd] + + mov edx,3 +_YLp: mov ecx,dword ptr [width] + rep movsd + movsw + add esi,ebx + add edi,ebx + dec edx + jnz _YLp + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawScrlBar(int y1, int y2) +{ + int i, yy1, yy2, v, s; + + yy1 = SStringY[y1] + 204; + yy2 = SStringY[y2] + 204; + if (stextscrlubtn != -1) DrawCel(665, yy1, pSTextSlidCels, 12, 12); + else DrawCel(665, yy1, pSTextSlidCels, 10, 12); + if (stextscrldbtn != -1) DrawCel(665, yy2, pSTextSlidCels, 11, 12); + else DrawCel(665, yy2, pSTextSlidCels, 9, 12); + for (i = (yy1+12); i < yy2; i+=12) DrawCel(665, i, pSTextSlidCels, 14, 12); + + if (stextsel != 22) s = stextsel; + else s = stextlhold; + if (storenumh > 1) { + v = ((s - stextup) >> 2) + stextsval; + v = v * 1000; + v = v / (storenumh-1); + v = v * (SStringY[y2]-SStringY[y1]-24); + v = v / 1000; + } else v = 0; + v += SStringY[y1+1] + 204; + DrawCel(665, v, pSTextSlidCels, 13, 12); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetupSTextWin() +{ + stextsize = STEXT_SMALL; + stextsel = -1; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetupSTextLWin() +{ + stextsize = STEXT_LARGE; + stextsel = -1; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ClearSText(int s, int e) +{ + int i; + + for (i = s; i < e; i++) { + stext[i]._sx = 0; + stext[i]._syoff = 0; + stext[i]._sstr[0] = 0; + stext[i]._sjust = FALSE; + stext[i]._sclr = ICOLOR_WHITE; + stext[i]._sline = FALSE; + stext[i]._ssel = FALSE; + stext[i]._sval = -1; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddSLine(int y) +{ + stext[y]._sx = 0; + stext[y]._syoff = 0; + stext[y]._sstr[0] = 0; + stext[y]._sline = TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddSTextVal(int y, int val) +{ + stext[y]._sval = val; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void OffsetSTextY(int y, int yo) +{ + stext[y]._syoff = yo; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddSText(int x, int y, BOOL j, char str[], char clr, BOOL sel) +{ + stext[y]._sx = x; + stext[y]._syoff = 0; + strcpy(stext[y]._sstr,str); + stext[y]._sjust = j; + stext[y]._sclr = clr; + stext[y]._sline = FALSE; + stext[y]._ssel = sel; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static void PrintStoreItem(const ItemStruct * x, int l, char iclr) +{ + char sstr[128]; + + sstr[0] = 0; + if (x->_iIdentified) { + if ((x->_iMagical != IMAGIC_UNIQUE) && (x->_iPrePower != -1)) { + PrintItemPower(x->_iPrePower, x); + strcat(sstr, tempstr); + } + if (x->_iSufPower != -1) { + PrintItemPower(x->_iSufPower, x); + if (sstr[0] != 0) strcat(sstr, ", "); + strcat(sstr, tempstr); + } + } + if ((x->_iMiscId == IMID_STAFF) && (x->_iMaxCharges != 0)) { + sprintf(tempstr, "Charges: %i/%i", x->_iCharges, x->_iMaxCharges); + if (sstr[0] != 0) strcat(sstr, ", "); + strcat(sstr, tempstr); + } + + if (sstr[0] != 0) { + AddSText(40, l, FALSE, sstr, iclr, FALSE); + l++; + } + + sstr[0] = 0; + if (x->_iClass == IC_WEAP) sprintf(sstr, "Damage: %i-%i ", x->_iMinDam, x->_iMaxDam); + if (x->_iClass == IC_ARMOR) sprintf(sstr, "Armor: %i ", x->_iAC); + + if ((x->_iMaxDur == INFINITE_DUR) || (x->_iMaxDur == 0)) strcat(sstr, "Indestructible, "); + else { + sprintf(tempstr, "Dur: %i/%i, ", x->_iDurability, x->_iMaxDur); + strcat(sstr, tempstr); + } + if (x->_itype == IT_MISC) sstr[0] = 0; + if ((x->_iMinStr + x->_iMinMag + x->_iMinDex) == 0) { + strcat(sstr, "No required attributes"); + } else { + strcpy(tempstr, "Required:"); + if (x->_iMinStr != 0) sprintf(tempstr, "%s %i Str", tempstr, x->_iMinStr); + if (x->_iMinMag != 0) sprintf(tempstr, "%s %i Mag", tempstr, (byte) x->_iMinMag); + if (x->_iMinDex != 0) sprintf(tempstr, "%s %i Dex", tempstr, x->_iMinDex); + strcat(sstr, tempstr); + } + AddSText(40, l++, FALSE, sstr, iclr, FALSE); + + if ((x->_iMagical == IMAGIC_UNIQUE) && (x->_iIdentified)) + AddSText(40, l++, FALSE, "Unique Item", iclr, FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +extern int AP2x2Tbl[10]; + +void StoreAutoPlace() +{ + int i, w, h, idx; + BOOL done; + + SetICursor(plr[myplr].HoldItem._iCurs + ICSTART); + // all items are either 1x1, 1x2, 1x3, 2x2, or 2x3 + // the inv is 10x4 + w = icursW28; + h = icursH28; + done = FALSE; + if ((w == 1) && (h == 1)) { + // Check to see if speed bar available first + idx = plr[myplr].HoldItem.IDidx; + if ((plr[myplr].HoldItem._iStatFlag) && (AllItemsList[idx].iUsable)) { + for (i = 0; (i < MAXSPD) && (!done); i++) { + if (plr[myplr].SpdList[i]._itype == -1) { + plr[myplr].SpdList[i] = plr[myplr].HoldItem; + done = TRUE; + } + } + } + // Start in lower left and continue trying right then up a line + for (i = 30; (i <= 39) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 20; (i <= 29) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 10; (i <= 19) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 0; (i <= 9) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + } + if ((w == 1) && (h == 2)) { + // Try 3rd row, 1st row, and then 2nd row + for (i = 29; (i >= 20) && (!done); i--) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 9; (i >= 0) && (!done); i--) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 19; (i >= 10) && (!done); i--) done = AutoPlace(myplr, i, w, h, TRUE); + } + if ((w == 1) && (h == 3)) { + // Try 1st row then 2nd row + for (i = 0; (i < 20) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + } + if ((w == 2) && (h == 2)) { + // Try 1st and 3rd row starting right and moving left + for (i = 0; (i < 10) && (!done); i++) done = AutoPlace(myplr, AP2x2Tbl[i], w, h, TRUE); + // Try 3rd row, 1st row, and then 2nd row + for (i = 21; (i < 29) && (!done); i+=2) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 1; (i < 9) && (!done); i+=2) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 10; (i < 19) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + } + if ((w == 2) && (h == 3)) { + // Try 1st row then 2nd row + for (i = 0; (i < 9) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + for (i = 10; (i < 19) && (!done); i++) done = AutoPlace(myplr, i, w, h, TRUE); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartSmith() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 1, TRUE, "Welcome to the", ICOLOR_GOLD, FALSE); + AddSText(0, 3, TRUE, "Blacksmith's shop", ICOLOR_GOLD, FALSE); + AddSText(0, 7, TRUE, "Would you like to:", ICOLOR_GOLD, FALSE); + AddSText(0, 10, TRUE, "Talk to Griswold", ICOLOR_BLUE, TRUE); + AddSText(0, 12, TRUE, "Buy basic items", ICOLOR_WHITE, TRUE); + AddSText(0, 14, TRUE, "Buy premium items", ICOLOR_WHITE, TRUE); + AddSText(0, 16, TRUE, "Sell items", ICOLOR_WHITE, TRUE); + AddSText(0, 18, TRUE, "Repair items", ICOLOR_WHITE, TRUE); + AddSText(0, 20, TRUE, "Leave the shop", ICOLOR_WHITE, TRUE); + AddSLine(5); + storenumh = 20; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_ScrollSBuy(int idx) +{ + int l, ls; + char iclr; + + ClearSText(5, 21); + stextup = 5; + for (l = 5; l < 20; l+=4) { + if (smithitem[idx]._itype != -1) { + ls = l; + iclr = ICOLOR_WHITE; + if (smithitem[idx]._iMagical) iclr = ICOLOR_BLUE; + if (!smithitem[idx]._iStatFlag) iclr = ICOLOR_RED; + if (smithitem[idx]._iMagical) AddSText(20, l, FALSE, smithitem[idx]._iIName, iclr, TRUE); + else AddSText(20, l, FALSE, smithitem[idx]._iName, iclr, TRUE); + AddSTextVal(l, smithitem[idx]._iIvalue); + PrintStoreItem(&smithitem[idx], l+1, iclr); + stextdown = ls; + idx++; + } + } + if ((!stext[stextsel]._ssel) && (stextsel != 22)) stextsel = stextdown; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartSBuy() +{ + int i; + + stextsize = STEXT_LARGE; + stextscrl = TRUE; + stextsval = 0; + sprintf(tempstr, "I have these items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSBuy(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, FALSE); + OffsetSTextY(22, 6); + + storenumh = 0; + for (i = 0; smithitem[i]._itype != -1; i++) storenumh++; + stextsmax = storenumh - 4; + if (stextsmax < 0) stextsmax = 0; + //if (storenumh == 0) StartStore(STORE_SMITH); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_ScrollSPBuy(int idx) +{ + int l, ls; + char iclr; + int boughtitems; + + ClearSText(5, 21); + stextup = 5; + // Premium items don't get deleted from the list, so idx is not an index + // into premium array, but rather to the nth available item. + boughtitems = idx; + idx = 0; + while (boughtitems) { + if (premiumitem[idx]._itype != -1) + boughtitems--; + idx++; + } + for (l = 5; ((l < 20) && (idx < MAXPREMIUM)); l+=4) { + if (premiumitem[idx]._itype != -1) { + ls = l; + iclr = ICOLOR_WHITE; + if (premiumitem[idx]._iMagical) iclr = ICOLOR_BLUE; + if (!premiumitem[idx]._iStatFlag) iclr = ICOLOR_RED; + AddSText(20, l, FALSE, premiumitem[idx]._iIName, iclr, TRUE); + AddSTextVal(l, premiumitem[idx]._iIvalue); + PrintStoreItem(&premiumitem[idx], l+1, iclr); + stextdown = ls; + } else if (idx < MAXPREMIUM) l-=4; + idx++; + } + if ((!stext[stextsel]._ssel) && (stextsel != 22)) stextsel = stextdown; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL S_StartSPBuy() +{ + int i; + + storenumh = 0; + for (i = 0; i < MAXPREMIUM; i++) if (premiumitem[i]._itype != -1) storenumh++; + if (storenumh == 0) { + StartStore(STORE_SMITH); + stextsel = 14; + return(FALSE); + } else { + stextsize = STEXT_LARGE; + stextscrl = TRUE; + stextsval = 0; + sprintf(tempstr, "I have these premium items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, FALSE); + OffsetSTextY(22, 6); + + stextsmax = storenumh - 4; + if (stextsmax < 0) stextsmax = 0; + + S_ScrollSPBuy(stextsval); + } + return(TRUE); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL SmithSellOk(int i) +{ + ItemStruct *pI; + + if (i >= 0) + pI = &plr[myplr].InvList[i]; + else + pI = &plr[myplr].SpdList[-(i+1)]; + + if (pI->_itype == -1) return FALSE; + + if (pI->_iMiscId > IMID_FIRSTOIL && + pI->_iMiscId < IMID_LASTOIL) + return TRUE; + + if (pI->_itype == IT_MISC) return FALSE; + if (pI->_itype == IT_GOLD) return FALSE; + if (pI->_itype == IT_FOOD) return FALSE; + if (pI->_itype == IT_STAFF && pI->_iSpell != SPL_NONE) return FALSE; + if (pI->_iClass == IC_SPECIAL) return FALSE; + if (pI->IDidx == IDI_LAZSTAFF) return FALSE; + +// if (plr[myplr].InvList[i]._iMagical && plr[myplr].InvList[i]._iIdentified) { +// if (plr[myplr].InvList[i]._iIvalue == 0) return FALSE; +// } + return TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_ScrollSSell(int idx) +{ + int l, ls, sidx, v; + char iclr; + + ClearSText(5, 21); + stextup = 5; + sidx = idx; + for (l = 5; l < 20 && idx < storenumh; l+=4) { + if (storehold[idx]._itype != -1) { + ls = l; + iclr = ICOLOR_WHITE; + if (storehold[idx]._iMagical) iclr = ICOLOR_BLUE; + if (!storehold[idx]._iStatFlag) iclr = ICOLOR_RED; + if (storehold[idx]._iMagical && storehold[idx]._iIdentified) { + AddSText(20, l, FALSE, storehold[idx]._iIName, iclr, TRUE); + v = storehold[idx]._iIvalue; + } else { + AddSText(20, l, FALSE, storehold[idx]._iName, iclr, TRUE); + v = storehold[idx]._ivalue; + } + AddSTextVal(l, v); + PrintStoreItem(&storehold[idx], l+1, iclr); + stextdown = ls; + } + idx++; + } + stextsmax = storenumh - 4; + if (stextsmax < 0) stextsmax = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartSSell() +{ + int i; + BOOL sellok; + + stextsize = STEXT_LARGE; + sellok = FALSE; + storenumh = 0; + for (i = 0; i < MAXHOLDITEMS; i++) storehold[i]._itype = -1; + for (i = 0; i < plr[myplr]._pNumInv && storenumh < MAXHOLDITEMS; i++) { + if (SmithSellOk(i)) { + sellok = TRUE; + storehold[storenumh] = plr[myplr].InvList[i]; + if (storehold[storenumh]._iMagical && storehold[storenumh]._iIdentified) + storehold[storenumh]._ivalue = storehold[storenumh]._iIvalue; + storehold[storenumh]._ivalue = storehold[storenumh]._ivalue >> 2; + if (!storehold[storenumh]._ivalue) + storehold[storenumh]._ivalue = 1; + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = i; + storenumh++; + } + } + for (i = 0; i < MAXSPD && storenumh < MAXHOLDITEMS; i++) { + if (SmithSellOk(-(i+1))) { + sellok = TRUE; + storehold[storenumh] = plr[myplr].SpdList[i]; + if (storehold[storenumh]._iMagical && storehold[storenumh]._iIdentified) + storehold[storenumh]._ivalue = storehold[storenumh]._iIvalue; + storehold[storenumh]._ivalue = storehold[storenumh]._ivalue >> 2; + if (!storehold[storenumh]._ivalue) + storehold[storenumh]._ivalue = 1; + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = -(i+1); + storenumh++; + } + } + + if (!sellok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing I want. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Which item is for sale? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL SmithRepairOk(int i) +{ + if (plr[myplr].InvList[i]._itype == -1) return FALSE; + if (plr[myplr].InvList[i]._itype == IT_MISC) return FALSE; + if (plr[myplr].InvList[i]._itype == IT_GOLD) return FALSE; + if (plr[myplr].InvList[i]._itype == IT_FOOD) return FALSE; + if (plr[myplr].InvList[i]._iDurability == plr[myplr].InvList[i]._iMaxDur) return FALSE; + return TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void AddStoreHoldRepair(ItemStruct * itm,int i) +{ + int v; + + app_assert(itm->_iMaxDur > 0); + + storehold[storenumh] = *itm; + itm = &storehold[storenumh]; + if (itm->_iMagical && itm->_iIdentified) + itm->_ivalue = (itm->_iIvalue * 30) / 100; + v = ((itm->_iMaxDur - itm->_iDurability) * 100) / itm->_iMaxDur; + v = (v * itm->_ivalue) / 100; + if (v == 0) { + if (itm->_iMagical && itm->_iIdentified) return; + else v = 1; + } + if (v > 1) v >>= 1; + itm->_ivalue = itm->_iIvalue = v; + storehidx[storenumh++] = i; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartSRepair() +{ + int i; + BOOL repairok; + + stextsize = STEXT_LARGE; + repairok = FALSE; + storenumh = 0; + for (i = 0; i < MAXHOLDITEMS; i++) storehold[i]._itype = -1; + if ((plr[myplr].HeadItem._itype != -1) && (plr[myplr].HeadItem._iDurability != plr[myplr].HeadItem._iMaxDur)) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].HeadItem, -1); + } + if ((plr[myplr].BodyItem._itype != -1) && (plr[myplr].BodyItem._iDurability != plr[myplr].BodyItem._iMaxDur)) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].BodyItem, -2); + } + if ((plr[myplr].Hand1Item._itype != -1) && (plr[myplr].Hand1Item._iDurability != plr[myplr].Hand1Item._iMaxDur)) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].Hand1Item, -3); + } + if ((plr[myplr].Hand2Item._itype != -1) && (plr[myplr].Hand2Item._iDurability != plr[myplr].Hand2Item._iMaxDur)) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].Hand2Item, -4); + } + for (i = 0; i < plr[myplr]._pNumInv && storenumh < MAXHOLDITEMS; i++) { + if (SmithRepairOk(i)) { + repairok = TRUE; + AddStoreHoldRepair(&plr[myplr].InvList[i], i); + } + } + if (!repairok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing to repair. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Repair which item? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartWitch() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 2, TRUE, "Witch's shack", ICOLOR_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", ICOLOR_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Adria", ICOLOR_BLUE, TRUE); + AddSText(0, 14, TRUE, "Buy items", ICOLOR_WHITE, TRUE); + AddSText(0, 16, TRUE, "Sell items", ICOLOR_WHITE, TRUE); + AddSText(0, 18, TRUE, "Recharge staves", ICOLOR_WHITE, TRUE); + AddSText(0, 20, TRUE, "Leave the shack", ICOLOR_WHITE, TRUE); + AddSLine(5); + storenumh = 20; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_ScrollWBuy(int idx) +{ + int l, ls, sidx; + char iclr; + + ClearSText(5, 21); + stextup = 5; + sidx = idx; + for (l = 5; l < 20; l+=4) { + if (witchitem[idx]._itype != -1) { + ls = l; + iclr = ICOLOR_WHITE; + if (witchitem[idx]._iMagical) iclr = ICOLOR_BLUE; + if (!witchitem[idx]._iStatFlag) iclr = ICOLOR_RED; + if (witchitem[idx]._iMagical) AddSText(20, l, FALSE, witchitem[idx]._iIName, iclr, TRUE); + else AddSText(20, l, FALSE, witchitem[idx]._iName, iclr, TRUE); + AddSTextVal(l, witchitem[idx]._iIvalue); + PrintStoreItem(&witchitem[idx], l+1, iclr); + stextdown = ls; + idx++; + } + } + if ((!stext[stextsel]._ssel) && (stextsel != 22)) stextsel = stextdown; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartWBuy() +{ + int i; + + stextsize = STEXT_LARGE; + stextscrl = TRUE; + stextsval = 0; + stextsmax = 20; + sprintf(tempstr, "I have these items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollWBuy(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, FALSE); + OffsetSTextY(22, 6); + + storenumh = 0; + for (i = 0; witchitem[i]._itype != -1; i++) storenumh++; + stextsmax = storenumh - 4; + if (stextsmax < 0) stextsmax = 0; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL WitchSellOk(int i) +{ + BOOL rv; + ItemStruct *pI; + + rv = FALSE; + if (i >= 0) + pI = &plr[myplr].InvList[i]; + else + pI = &plr[myplr].SpdList[-(i+1)]; + + if (pI->_itype == IT_MISC) rv = TRUE; + if ((pI->_iMiscId > IMID_FIRSTOIL) && (pI->_iMiscId < IMID_LASTOIL)) + rv = FALSE; + if (pI->_iClass == IC_SPECIAL) + rv = FALSE; + + if (pI->_itype == IT_STAFF && pI->_iSpell != SPL_NONE) rv = TRUE; +// if (pI->_iMagical && pI->_iIdentified) { +// if (pI->_iIvalue == 0) rv = FALSE; +// } + if (pI->IDidx >= IDI_FIRSTQUEST + && pI->IDidx <= IDI_LASTQUEST) + rv = FALSE; + if (pI->IDidx == IDI_LAZSTAFF) rv = FALSE; + return(rv); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartWSell() +{ + int i; + BOOL sellok; + + stextsize = STEXT_LARGE; + sellok = FALSE; + storenumh = 0; + for (i = 0; i < MAXHOLDITEMS; i++) storehold[i]._itype = -1; + for (i = 0; i < plr[myplr]._pNumInv && storenumh < MAXHOLDITEMS; i++) { + if (WitchSellOk(i)) { + sellok = TRUE; + storehold[storenumh] = plr[myplr].InvList[i]; + if (storehold[storenumh]._iMagical && storehold[storenumh]._iIdentified) + storehold[storenumh]._ivalue = storehold[storenumh]._iIvalue; + storehold[storenumh]._ivalue = storehold[storenumh]._ivalue >> 2; + if (!storehold[storenumh]._ivalue) + storehold[storenumh]._ivalue = 1; + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = i; + storenumh++; + } + } + for (i = 0; i < MAXSPD && storenumh < MAXHOLDITEMS; i++) { + if ((plr[myplr].SpdList[i]._itype != -1) && (WitchSellOk(-(i+1)))) { + sellok = TRUE; + storehold[storenumh] = plr[myplr].SpdList[i]; + if (storehold[storenumh]._iMagical && storehold[storenumh]._iIdentified) + storehold[storenumh]._ivalue = storehold[storenumh]._iIvalue; + storehold[storenumh]._ivalue = storehold[storenumh]._ivalue >> 2; + if (!storehold[storenumh]._ivalue) + storehold[storenumh]._ivalue = 1; + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = -(i+1); + storenumh++; + } + } + if (!sellok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing I want. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Which item is for sale? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL WitchRechargeOk(int i) +{ + BOOL rv; + + rv = FALSE; + if ((plr[myplr].InvList[i]._itype == IT_STAFF) && + (plr[myplr].InvList[i]._iCharges != plr[myplr].InvList[i]._iMaxCharges)) + { + rv = TRUE; + } + + // new: you can recharge unique items too. + if ((plr[myplr].InvList[i]._iMiscId == IMID_UNIQUE || + (plr[myplr].InvList[i]._iMiscId == IMID_STAFF)) && + (plr[myplr].InvList[i]._iCharges < plr[myplr].InvList[i]._iMaxCharges)) + { + rv = TRUE; + } + //***** + return(rv); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void AddStoreHoldRecharge(ItemStruct itm, int i) +{ + int v; + + storehold[storenumh] = itm; + storehold[storenumh]._ivalue += spelldata[itm._iSpell].sStaffCost; + v = ((storehold[storenumh]._iMaxCharges - storehold[storenumh]._iCharges) * 100) / storehold[storenumh]._iMaxCharges; + storehold[storenumh]._ivalue = ((v * storehold[storenumh]._ivalue) / 100) >> 1; + storehold[storenumh]._iIvalue = storehold[storenumh]._ivalue; + storehidx[storenumh] = i; + storenumh++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartWRecharge() +{ + int i; + BOOL rechargeok; + + stextsize = STEXT_LARGE; + rechargeok = FALSE; + storenumh = 0; + for (i = 0; i < MAXHOLDITEMS; i++) storehold[i]._itype = -1; + if (( (plr[myplr].Hand1Item._itype == IT_STAFF) + || (plr[myplr].Hand1Item._iMiscId == IMID_UNIQUE)) + && (plr[myplr].Hand1Item._iCharges != plr[myplr].Hand1Item._iMaxCharges)) + { + rechargeok = TRUE; + AddStoreHoldRecharge(plr[myplr].Hand1Item, -1); + } + for (i = 0; i < plr[myplr]._pNumInv && storenumh < MAXHOLDITEMS; i++) { + if (WitchRechargeOk(i)) { + rechargeok = TRUE; + AddStoreHoldRecharge(plr[myplr].InvList[i], i); + } + } + if (!rechargeok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing to recharge. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Recharge which item? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartNoMoney() +{ + StartStore(stextshold); + stextsize = STEXT_LARGE; + stextscrl = FALSE; + ClearSText(5, 23); + AddSText(0, 14, TRUE, "You do not have enough gold", ICOLOR_WHITE, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartNoRoom() +{ + StartStore(stextshold); + stextscrl = FALSE; + ClearSText(5, 23); + AddSText(0, 14, TRUE, "You do not have enough room in inventory", ICOLOR_WHITE, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartConfirm() +{ + char iclr; + BOOL idprint; + + StartStore(stextshold); + stextscrl = FALSE; + ClearSText(5, 23); + iclr = ICOLOR_WHITE; + if (plr[myplr].HoldItem._iMagical) iclr = ICOLOR_BLUE; + if (!plr[myplr].HoldItem._iStatFlag) iclr = ICOLOR_RED; + + if (plr[myplr].HoldItem._iMagical) idprint = TRUE; + else idprint = FALSE; + + if (stextshold == STORE_STORYID) idprint = FALSE; + + if ((plr[myplr].HoldItem._iMagical) && (!plr[myplr].HoldItem._iIdentified)) { + if (stextshold == STORE_SSELL) idprint = FALSE; + if (stextshold == STORE_WSELL) idprint = FALSE; + if (stextshold == STORE_SREPAIR) idprint = FALSE; + if (stextshold == STORE_WRECHARGE) idprint = FALSE; + } + + if (idprint) + AddSText(20, 8, FALSE, plr[myplr].HoldItem._iIName, iclr, FALSE); + else + AddSText(20, 8, FALSE, plr[myplr].HoldItem._iName, iclr, FALSE); + + AddSTextVal(8, plr[myplr].HoldItem._iIvalue); + PrintStoreItem(&plr[myplr].HoldItem, 9, iclr); + switch(stextshold) { + case STORE_SBUY: + case STORE_WBUY: + case STORE_HBUY: + case STORE_SPBUY: + strcpy(tempstr, "Are you sure you want to buy this item?"); + break; + case STORE_SSELL: + case STORE_WSELL: + strcpy(tempstr, "Are you sure you want to sell this item?"); + break; + case STORE_SREPAIR: + strcpy(tempstr, "Are you sure you want to repair this item?"); + break; + case STORE_WRECHARGE: + strcpy(tempstr, "Are you sure you want to recharge this item?"); + break; + case STORE_BBUY: + strcpy(tempstr, "Do we have a deal?"); + break; + case STORE_STORYID: + strcpy(tempstr, "Are you sure you want to identify this item?"); + break; + } + AddSText(0, 15, TRUE, tempstr, ICOLOR_WHITE, FALSE); + AddSText(0, 18, TRUE, "Yes", ICOLOR_WHITE, TRUE); + AddSText(0, 20, TRUE, "No", ICOLOR_WHITE, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartBoy() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 2, TRUE, "Wirt the Peg-legged boy", ICOLOR_GOLD, FALSE); + AddSLine(5); + if (boyitem._itype != -1) { + AddSText(0, 8, TRUE, "Talk to Wirt", ICOLOR_BLUE, TRUE); + AddSText(0, 12, TRUE, "I have something for sale,", ICOLOR_GOLD, FALSE); + AddSText(0, 14, TRUE, "but it will cost 50 gold", ICOLOR_GOLD, FALSE); + AddSText(0, 16, TRUE, "just to take a look. ", ICOLOR_GOLD, FALSE); + AddSText(0, 18, TRUE, "What have you got?", ICOLOR_WHITE, TRUE); + AddSText(0, 20, TRUE, "Say goodbye", ICOLOR_WHITE, TRUE); + } + else { + AddSText(0, 12, TRUE, "Talk to Wirt", ICOLOR_BLUE, TRUE); + AddSText(0, 18, TRUE, "Say goodbye", ICOLOR_WHITE, TRUE); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartBBoy() +{ + int iclr; + + stextsize = STEXT_LARGE; + stextscrl = FALSE; + sprintf(tempstr, "I have this item for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + iclr = ICOLOR_WHITE; + if (boyitem._iMagical) iclr = ICOLOR_BLUE; + if (!boyitem._iStatFlag) iclr = ICOLOR_RED; + if (boyitem._iMagical) AddSText(20, 10, FALSE, boyitem._iIName, iclr, TRUE); + else AddSText(20, 10, FALSE, boyitem._iName, iclr, TRUE); +// PATCH2.JMM + // No actual change--just note that the value of the item = 75% value + AddSTextVal(10, boyitem._iIvalue - (boyitem._iIvalue >> 2)); +// ENDPATCH2.JMM + PrintStoreItem(&boyitem, 11, iclr); + AddSText(0, 22, TRUE, "Leave", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartHealer() +{ + // heal automatically + if (plr[myplr]._pHitPoints != plr[myplr]._pMaxHP) PlaySFX(IS_CAST8); + plr[myplr]._pHitPoints = plr[myplr]._pMaxHP; + plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase; + drawhpflag = TRUE; + + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 1, TRUE, "Welcome to the", ICOLOR_GOLD, FALSE); + AddSText(0, 3, TRUE, "Healer's home", ICOLOR_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", ICOLOR_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Pepin", ICOLOR_BLUE, TRUE); +// AddSText(0, 14, TRUE, "Receive healing", ICOLOR_WHITE, TRUE); + AddSText(0, 14, TRUE, "Buy items", ICOLOR_WHITE, TRUE); + AddSText(0, 16, TRUE, "Leave Healer's home", ICOLOR_WHITE, TRUE); + AddSLine(5); + storenumh = 20; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_ScrollHBuy(int idx) +{ + int l, ls; + char iclr; + + ClearSText(5, 21); + stextup = 5; + for (l = 5; l < 20; l+=4) { + if (healitem[idx]._itype != -1) { + ls = l; + iclr = ICOLOR_WHITE; + if (!healitem[idx]._iStatFlag) iclr = ICOLOR_RED; + AddSText(20, l, FALSE, healitem[idx]._iName, iclr, TRUE); + AddSTextVal(l, healitem[idx]._iIvalue); + PrintStoreItem(&healitem[idx], l+1, iclr); + stextdown = ls; + idx++; + } + } + if ((!stext[stextsel]._ssel) && (stextsel != 22)) stextsel = stextdown; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartHBuy() +{ + int i; + + stextsize = STEXT_LARGE; + stextscrl = TRUE; + stextsval = 0; + sprintf(tempstr, "I have these items for sale : Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollHBuy(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, FALSE); + OffsetSTextY(22, 6); + + storenumh = 0; + for (i = 0; healitem[i]._itype != -1; i++) storenumh++; + stextsmax = storenumh - 4; + if (stextsmax < 0) stextsmax = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartStory() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 2, TRUE, "The Town Elder", ICOLOR_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", ICOLOR_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Cain", ICOLOR_BLUE, TRUE); + AddSText(0, 14, TRUE, "Identify an item", ICOLOR_WHITE, TRUE); + AddSText(0, 18, TRUE, "Say goodbye", ICOLOR_WHITE, TRUE); + AddSLine(5); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +BOOL IdItemOk(ItemStruct *i) +{ + if (i->_itype == -1) return(FALSE); + if (i->_iMagical == IMAGIC_NONE) return(FALSE); + if (i->_iIdentified) return(FALSE); + return(TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#define STOREIDCOST 100 + +void AddStoreHoldId(ItemStruct itm, int i) +{ + storehold[storenumh] = itm; + storehold[storenumh]._ivalue = STOREIDCOST; + storehold[storenumh]._iIvalue = STOREIDCOST; + storehidx[storenumh] = i; + storenumh++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartSIdentify() +{ + int i; + BOOL idok; + + stextsize = STEXT_LARGE; + idok = FALSE; + storenumh = 0; + for (i = 0; i < MAXHOLDITEMS; i++) storehold[i]._itype = -1; + if (IdItemOk(&plr[myplr].HeadItem)) { + idok = TRUE; + AddStoreHoldId(plr[myplr].HeadItem, -1); + } + if (IdItemOk(&plr[myplr].BodyItem)) { + idok = TRUE; + AddStoreHoldId(plr[myplr].BodyItem, -2); + } + if (IdItemOk(&plr[myplr].Hand1Item)) { + idok = TRUE; + AddStoreHoldId(plr[myplr].Hand1Item, -3); + } + if (IdItemOk(&plr[myplr].Hand2Item)) { + idok = TRUE; + AddStoreHoldId(plr[myplr].Hand2Item, -4); + } + if (IdItemOk(&plr[myplr].Ring1Item)) { + idok = TRUE; + AddStoreHoldId(plr[myplr].Ring1Item, -5); + } + if (IdItemOk(&plr[myplr].Ring2Item)) { + idok = TRUE; + AddStoreHoldId(plr[myplr].Ring2Item, -6); + } + if (IdItemOk(&plr[myplr].NeckItem)) { + idok = TRUE; + AddStoreHoldId(plr[myplr].NeckItem, -7); + } + for (i = 0; i < plr[myplr]._pNumInv && storenumh < MAXHOLDITEMS; i++) { + if (IdItemOk(&plr[myplr].InvList[i])) { + idok = TRUE; + AddStoreHoldId(plr[myplr].InvList[i], i); + } + } + if (!idok) { + stextscrl = FALSE; + sprintf(tempstr, "You have nothing to identify. Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } else { + stextscrl = TRUE; + stextsval = 0; + stextsmax = plr[myplr]._pNumInv; + sprintf(tempstr, "Identify which item? Your gold : %i", plr[myplr]._pGold); + AddSText(0, 1, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(3); + AddSLine(21); + S_ScrollSSell(stextsval); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); + OffsetSTextY(22, 6); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartIdShow() +{ + char iclr; + + StartStore(stextshold); + stextscrl = FALSE; + ClearSText(5, 23); + iclr = ICOLOR_WHITE; + if (plr[myplr].HoldItem._iMagical) iclr = ICOLOR_BLUE; + if (!plr[myplr].HoldItem._iStatFlag) iclr = ICOLOR_RED; + + AddSText(0, 7, TRUE, "This item is:", ICOLOR_WHITE, FALSE); + + AddSText(20, 11, FALSE, plr[myplr].HoldItem._iIName, iclr, FALSE); + PrintStoreItem(&plr[myplr].HoldItem, 12, iclr); + + AddSText(0, 18, TRUE, "Done", ICOLOR_WHITE, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#if !IS_VERSION(SHAREWARE) +void S_StartTalk() +{ + int i, tq, sn, la, gl; + + stextsize = STEXT_SMALL; + stextscrl = FALSE; + sprintf(tempstr, "Talk to %s", talkname[talker]); + AddSText(0, 2, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(5); + + tq = 0; + for (i = 0; i < MAXQUESTS; i++) { + if ((quests[i]._qactive == QUEST_NOTDONE) && (Qtalklist[talker][i] != -1) && quests[i]._qlog) tq++; + } + if (tq > 6) { + sn = 14 - (tq >> 1); + la = 1; + } else { + sn = 15 - tq; + la = 2; + } + gl = sn - 2; + for (i = 0; i < MAXQUESTS; i++) { + if ((quests[i]._qactive == QUEST_NOTDONE) && (Qtalklist[talker][i] != -1) && quests[i]._qlog) { + AddSText(0, sn, TRUE, questlist[i]._qlstr, ICOLOR_WHITE, TRUE); + sn += la; + } + } + + AddSText(0, gl, TRUE, "Gossip", ICOLOR_BLUE, TRUE); + + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); +} + +#else +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartShareTalk() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + sprintf(tempstr, "Talk to %s", talkname[talker]); + AddSText(0, 2, TRUE, tempstr, ICOLOR_GOLD, FALSE); + AddSLine(5); + + sprintf(tempstr, "Talking to %s", talkname[talker]); + AddSText(0, 10, TRUE, tempstr, ICOLOR_WHITE, FALSE); + AddSText(0, 12, TRUE, "is not available", ICOLOR_WHITE, FALSE); + AddSText(0, 14, TRUE, "in the shareware", ICOLOR_WHITE, FALSE); + AddSText(0, 16, TRUE, "version.", ICOLOR_WHITE, FALSE); + AddSText(0, 22, TRUE, "Back", ICOLOR_WHITE, TRUE); +} +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartTavern() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 1, TRUE, "Welcome to the", ICOLOR_GOLD, FALSE); + AddSText(0, 3, TRUE, "Rising Sun", ICOLOR_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", ICOLOR_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Ogden", ICOLOR_BLUE, TRUE); + AddSText(0, 18, TRUE, "Leave the tavern", ICOLOR_WHITE, TRUE); + AddSLine(5); + storenumh = 20; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartBarMaid() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 2, TRUE, "Gillian", ICOLOR_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", ICOLOR_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Gillian", ICOLOR_BLUE, TRUE); + AddSText(0, 18, TRUE, "Say goodbye", ICOLOR_WHITE, TRUE); + AddSLine(5); + storenumh = 20; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StartDrunk() +{ + stextsize = STEXT_SMALL; + stextscrl = FALSE; + AddSText(0, 2, TRUE, "Farnham the Drunk", ICOLOR_GOLD, FALSE); + AddSText(0, 9, TRUE, "Would you like to:", ICOLOR_GOLD, FALSE); + AddSText(0, 12, TRUE, "Talk to Farnham", ICOLOR_BLUE, TRUE); + AddSText(0, 18, TRUE, "Say Goodbye", ICOLOR_WHITE, TRUE); + AddSLine(5); + storenumh = 20; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void StartStore(char s) +{ + int i; + + sbookflag = FALSE; + invflag = FALSE; + chrflag = FALSE; + questlog = FALSE; + dropGoldFlag = FALSE; + ClearSText(0, NUMSTLINES); + ReleaseStoreBtn(); + switch(s) { + case STORE_SMITH: + S_StartSmith(); + break; + case STORE_SBUY: + if (storenumh > 0) S_StartSBuy(); + break; + case STORE_SSELL: + S_StartSSell(); + break; + case STORE_SREPAIR: + S_StartSRepair(); + break; + case STORE_WITCH: + S_StartWitch(); + break; + case STORE_WBUY: + if (storenumh > 0) S_StartWBuy(); + break; + case STORE_WSELL: + S_StartWSell(); + break; + case STORE_WRECHARGE: + S_StartWRecharge(); + break; + case STORE_NOMONEY: + S_StartNoMoney(); + break; + case STORE_NOROOM: + S_StartNoRoom(); + break; + case STORE_CONFIRM: + S_StartConfirm(); + break; + case STORE_BOY: + S_StartBoy(); + break; + case STORE_BBUY: + S_StartBBoy(); + break; + case STORE_HEALER: + S_StartHealer(); + break; + case STORE_STORYTLR: + S_StartStory(); + break; + case STORE_HBUY: + if (storenumh > 0) S_StartHBuy(); + break; + case STORE_STORYID: + S_StartSIdentify(); + break; + case STORE_SPBUY: + if (! S_StartSPBuy()) return; + break; + case STORE_TALK: + #if IS_VERSION(SHAREWARE) + S_StartShareTalk(); + #else + S_StartTalk(); + #endif + break; + case STORE_IDSHOW: + S_StartIdShow(); + break; + case STORE_TAVERN: + S_StartTavern(); + break; + case STORE_DRUNK: + S_StartDrunk(); + break; + case STORE_BARMAID: + S_StartBarMaid(); + break; + } + + for (i = 0; (i < NUMSTLINES) && (!stext[i]._ssel); i++) + NULL; + if (i == NUMSTLINES) stextsel = -1; + else stextsel = i; + stextflag = s; + if (s == STORE_SBUY && storenumh == 0) { + StartStore(STORE_SMITH); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void DrawSText() +{ + int i; + + // Draw background + if (stextsize == STEXT_SMALL) DrawSTextBack(); + else DrawQTextBack(); + + if (stextscrl) { + switch(stextflag) { + case STORE_SBUY: + S_ScrollSBuy(stextsval); + break; + case STORE_SPBUY: + S_ScrollSPBuy(stextsval); + break; + case STORE_SSELL: + case STORE_SREPAIR: + case STORE_WSELL: + case STORE_WRECHARGE: + case STORE_STORYID: + S_ScrollSSell(stextsval); + break; + case STORE_WBUY: + S_ScrollWBuy(stextsval); + break; + case STORE_HBUY: + S_ScrollHBuy(stextsval); + break; + } + } + + for (i = 0; i < NUMSTLINES; i++) { + if (stext[i]._sline) DrawSLine(i); + if (stext[i]._sstr[0] != 0) PrintSString(stext[i]._sx, i, stext[i]._sjust, stext[i]._sstr, stext[i]._sclr, stext[i]._sval); + } + + if (stextscrl) DrawScrlBar(4, 20); + + stextspin = (stextspin & 0x7) + 1; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void STextESC() +{ + if (qtextflag) { + qtextflag = FALSE; + if (leveltype == 0) stream_stop(); + return; + } + switch(stextflag) { + case STORE_SMITH: + case STORE_WITCH: + case STORE_BOY: + case STORE_BBUY: + case STORE_HEALER: + case STORE_STORYTLR: + case STORE_TAVERN: + case STORE_BARMAID: + case STORE_DRUNK: + stextflag = STORE_NONE; + break; + case STORE_TALK: + StartStore(stextshold); + stextsel = stextlhold; + break; + case STORE_SBUY: + StartStore(STORE_SMITH); + stextsel = 12; + break; + case STORE_SPBUY: + StartStore(STORE_SMITH); + stextsel = 14; + break; + case STORE_SSELL: + StartStore(STORE_SMITH); + stextsel = 16; + break; + case STORE_SREPAIR: + StartStore(STORE_SMITH); + stextsel = 18; + break; + case STORE_WBUY: + StartStore(STORE_WITCH); + stextsel = 14; + break; + case STORE_WSELL: + StartStore(STORE_WITCH); + stextsel = 16; + break; + case STORE_WRECHARGE: + StartStore(STORE_WITCH); + stextsel = 18; + break; + case STORE_HBUY: + StartStore(STORE_HEALER); + stextsel = 16; + break; + case STORE_STORYID: + StartStore(STORE_STORYTLR); + stextsel = 14; + break; + case STORE_IDSHOW: + StartStore(STORE_STORYID); + break; + case STORE_NOMONEY: + case STORE_NOROOM: + case STORE_CONFIRM: + StartStore(stextshold); + stextsel = stextlhold; + stextsval = stextvhold; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void STextUp() +{ + PlaySFX(IS_TITLEMOV); + if (stextsel != -1) { + if (stextscrl) { + if (stextsel == stextup) { + if (stextsval != 0) stextsval--; + } else { + stextsel--; + while (!stext[stextsel]._ssel) { + if (stextsel == 0) stextsel = NUMSTLINES-1; + else stextsel--; + } + } + } else { + if (stextsel == 0) stextsel = NUMSTLINES-1; + else stextsel--; + while (!stext[stextsel]._ssel) { + if (stextsel == 0) stextsel = NUMSTLINES-1; + else stextsel--; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void STextDown() +{ + PlaySFX(IS_TITLEMOV); + if (stextsel != -1) { + if (stextscrl) { + if (stextsel == stextdown) { + if (stextsval < stextsmax) stextsval++; + } else { + stextsel++; + while (!stext[stextsel]._ssel) { + if (stextsel == NUMSTLINES-1) stextsel = 0; + else stextsel++; + } + } + } else { + if (stextsel == NUMSTLINES-1) stextsel = 0; + else stextsel++; + while (!stext[stextsel]._ssel) { + if (stextsel == NUMSTLINES-1) stextsel = 0; + else stextsel++; + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void STextPgUp() +{ + PlaySFX(IS_TITLEMOV); + if ((stextsel != -1) && (stextscrl)) { + if (stextsel == stextup) { + if (stextsval != 0) stextsval-=4; + if (stextsval < 0) stextsval = 0; + } else { + stextsel = stextup; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void STextPgDown() +{ + PlaySFX(IS_TITLEMOV); + if ((stextsel != -1) && (stextscrl)) { + if (stextsel == stextdown) { + if (stextsval < stextsmax) stextsval+=4; + if (stextsval > stextsmax) stextsval = stextsmax; + } else { + stextsel = stextdown; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_SmithEnter() +{ + switch(stextsel) { + case 10: + talker = TWN_BLKSMITH; + stextshold = STORE_SMITH; + stextlhold = 10; + gossipstart = TXT_GRIS2; + gossipend = TXT_GRIS13; + StartStore(STORE_TALK); + break; + case 12: + StartStore(STORE_SBUY); + break; + case 14: + StartStore(STORE_SPBUY); + break; + case 16: + StartStore(STORE_SSELL); + break; + case 18: + StartStore(STORE_SREPAIR); + break; + case 20: + stextflag = STORE_NONE; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetGoldCurs(int pnum, int i) +{ + if (plr[pnum].InvList[i]._ivalue >= GOLD_VT2) { + plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; + } else { + if (plr[pnum].InvList[i]._ivalue <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; + else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SetSpdbarGoldCurs(int pnum, int i) +{ + if (plr[pnum].SpdList[i]._ivalue >= GOLD_VT2) { + plr[pnum].SpdList[i]._iCurs = ITEM_5GOLD; + } else { + if (plr[pnum].SpdList[i]._ivalue <= GOLD_VT1) plr[pnum].SpdList[i]._iCurs = ITEM_1GOLD; + else plr[pnum].SpdList[i]._iCurs = ITEM_3GOLD; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TakePlrsMoney(long cost) +{ + int i; + + // Take players money + plr[myplr]._pGold = CalculateGold(myplr) - cost; + + // Remove gold from speed list first; if there is any + // Try non GOLD_VMAX first, then break into the GOLD_VMAX piles + for (i = 0; ((i < MAXSPD) && (cost > 0)); i++) { + if ((plr[myplr].SpdList[i]._itype == IT_GOLD) && + (plr[myplr].SpdList[i]._ivalue != GOLD_VMAX)) { + if (cost < plr[myplr].SpdList[i]._ivalue) { + plr[myplr].SpdList[i]._ivalue -= cost; + SetSpdbarGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].SpdList[i]._ivalue; + RemoveSpdBarItem(myplr, i); + i = -1; // restart looping + } + } + } + if (cost > 0) { + // GOLD_VMAX piles + for (i = 0; ((i < MAXSPD) && (cost > 0)); i++) { + if (plr[myplr].SpdList[i]._itype == IT_GOLD) { + if (cost < plr[myplr].SpdList[i]._ivalue) { + plr[myplr].SpdList[i]._ivalue -= cost; + SetSpdbarGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].SpdList[i]._ivalue; + RemoveSpdBarItem(myplr, i); + i = -1; // restart looping + } + } + } + } + force_redraw = FULLDRAW; + + // Remove gold from inventory list if there was no gold in the speed list + // or all gold from the speed list was deplenished. + // Try non GOLD_VMAX first, then break into the GOLD_VMAX piles + if (cost > 0) { + for (i = 0; ((i < plr[myplr]._pNumInv) && (cost > 0)); i++) { + if ((plr[myplr].InvList[i]._itype == IT_GOLD) && + (plr[myplr].InvList[i]._ivalue != GOLD_VMAX)) { + if (cost < plr[myplr].InvList[i]._ivalue) { + plr[myplr].InvList[i]._ivalue -= cost; + SetGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].InvList[i]._ivalue; + RemoveInvItem(myplr, i); + i = -1; // restart looping + } + } + } + if (cost > 0) { + // GOLD_VMAX piles + for (i = 0; ((i < plr[myplr]._pNumInv) && (cost > 0)); i++) { + if (plr[myplr].InvList[i]._itype == IT_GOLD) { + if (cost < plr[myplr].InvList[i]._ivalue) { + plr[myplr].InvList[i]._ivalue -= cost; + SetGoldCurs(myplr, i); + cost = 0; + } else { + cost -= plr[myplr].InvList[i]._ivalue; + RemoveInvItem(myplr, i); + i = -1; // restart looping + } + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SmithBuyItem() +{ + int idx; + + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + // Put in players inv + if (!plr[myplr].HoldItem._iMagical) plr[myplr].HoldItem._iIdentified = FALSE; + StoreAutoPlace(); + + // Remove from smithitems + idx = ((stextlhold - stextup) >> 2) + stextvhold; + if (idx == MAXSMITHITEMS-1) smithitem[idx]._itype = -1; + else { + while (smithitem[idx+1]._itype != -1) { + smithitem[idx] = smithitem[idx+1]; + idx++; + } + smithitem[idx]._itype = -1; + } + + CalcPlrInv(myplr, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_SBuyEnter() +{ + int idx, i; + BOOL done; + + if (stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 12; + } else { + stextshold = STORE_SBUY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + if (plr[myplr]._pGold < smithitem[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = smithitem[idx]; + SetCursor(plr[myplr].HoldItem._iCurs + ICSTART); + done = FALSE; + for (i = 0; (i < MAXINV) && (!done); i++) done = AutoPlace(myplr, i, cursW/28, cursH/28, FALSE); + if (done) StartStore(STORE_CONFIRM); + else StartStore(STORE_NOROOM); + SetCursor(GLOVE_CURS); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SmithBuyPItem() +{ + int idx, i; + + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + // Put in players inv + if (!plr[myplr].HoldItem._iMagical) plr[myplr].HoldItem._iIdentified = FALSE; + StoreAutoPlace(); + + // Remove from premiumitems + int xx = ((stextlhold - stextup) >> 2) + stextvhold; + idx = 0; + for (i = 0; xx >= 0; i++) { + if (premiumitem[i]._itype != -1) { + xx--; + idx = i; + } + } + premiumitem[idx]._itype = -1; + numpremium--; + + // replenish premium list + SpawnPremium(myplr); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_SPBuyEnter() +{ + int idx, i; + BOOL done; + + if (stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 14; + } else { + stextshold = STORE_SPBUY; + stextlhold = stextsel; + stextvhold = stextsval; + int xx = ((stextsel - stextup) >> 2) + stextsval; + idx = 0; + for (i = 0; xx >= 0; i++) { + if (premiumitem[i]._itype != -1) { + xx--; + idx = i; + } + } + if (plr[myplr]._pGold < premiumitem[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = premiumitem[idx]; + SetCursor(plr[myplr].HoldItem._iCurs + ICSTART); + done = FALSE; + for (i = 0; (i < MAXINV) && (!done); i++) done = AutoPlace(myplr, i, cursW/28, cursH/28, FALSE); + if (done) StartStore(STORE_CONFIRM); + else StartStore(STORE_NOROOM); + SetCursor(GLOVE_CURS); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL StoreGoldFit(int idx) +{ + int sz, numsqrs, i; + long cost; + + // How many squares am I going to need? + cost = storehold[idx]._iIvalue; + numsqrs = cost / GOLD_VMAX; + if ((cost % GOLD_VMAX) != 0) numsqrs++; + SetCursor(storehold[idx]._iCurs + ICSTART); + sz = (cursW/28) * (cursH/28); + SetCursor(GLOVE_CURS); + if (sz >= numsqrs) return(TRUE); + for (i = 0; i < MAXINV; i++) { + if (plr[myplr].InvGrid[i] == 0) sz++; + } + for (i = 0; i < plr[myplr]._pNumInv; i++) { + if ((plr[myplr].InvList[i]._itype == IT_GOLD) && + (plr[myplr].InvList[i]._ivalue != GOLD_VMAX)) { + if ((cost + plr[myplr].InvList[i]._ivalue) <= GOLD_VMAX) cost = 0; + else cost -= (GOLD_VMAX - plr[myplr].InvList[i]._ivalue); + } + } + numsqrs = cost / GOLD_VMAX; + if ((cost % GOLD_VMAX) != 0) numsqrs++; + if (sz >= numsqrs) return(TRUE); + else return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PlaceStoreGold(long v) +{ + int i, ii, xx, yy; + BOOL done; + + done = FALSE; + for (ii = 0; (ii < MAXINV) && (!done); ii++) { + yy = (ii / 10) * 10; + xx = ii % 10; + if (plr[myplr].InvGrid[xx+yy] == 0) { + i = plr[myplr]._pNumInv; + // drb.patch1.start.02/13/97 + void GetGoldSeed(int pnum, ItemStruct *h); + GetGoldSeed(myplr, &golditem); + // drb.patch1.end.02/13/97 + plr[myplr].InvList[i] = golditem; + plr[myplr]._pNumInv++; + plr[myplr].InvGrid[xx+yy] = plr[myplr]._pNumInv; + plr[myplr].InvList[i]._ivalue = v; + SetGoldCurs(myplr, i); + done = TRUE; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void StoreSellItem() +{ + int idx, i; + long cost; + + // Remove item from inv + idx = ((stextlhold - stextup) >> 2) + stextvhold; + if (storehidx[idx] >= 0) RemoveInvItem(myplr, storehidx[idx]); + else RemoveSpdBarItem(myplr, -(storehidx[idx]+1)); + + // Get value + cost = storehold[idx]._iIvalue; + + // Remove from hold list + storenumh--; + if (idx != storenumh) { + while (idx < storenumh) { + storehold[idx] = storehold[idx+1]; + storehidx[idx] = storehidx[idx+1]; + idx++; + } + } + + // Add value to player + plr[myplr]._pGold += cost; + // Try placing with other gold first + for (i = 0; ((i < plr[myplr]._pNumInv) && (cost > 0)); i++) { + if ((plr[myplr].InvList[i]._itype == IT_GOLD) && + (plr[myplr].InvList[i]._ivalue != GOLD_VMAX)) { + if ((cost + plr[myplr].InvList[i]._ivalue) <= GOLD_VMAX) { + plr[myplr].InvList[i]._ivalue += cost; + SetGoldCurs(myplr, i); + cost = 0; + } else { + cost -= (GOLD_VMAX - plr[myplr].InvList[i]._ivalue); + plr[myplr].InvList[i]._ivalue = GOLD_VMAX; + SetGoldCurs(myplr, i); + } + } + } + // Place new gold slots + if (cost > 0) { + while (cost > GOLD_VMAX) { + PlaceStoreGold(GOLD_VMAX); + cost -= GOLD_VMAX; + } + PlaceStoreGold(cost); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_SSellEnter() +{ + int idx; + + if (stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 16; + } else { + stextshold = STORE_SSELL; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + plr[myplr].HoldItem = storehold[idx]; + if (StoreGoldFit(idx)) StartStore(STORE_CONFIRM); + else StartStore(STORE_NOROOM); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SmithRepairItem() +{ + int i, idx; + + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + idx = ((stextlhold - stextup) >> 2) + stextvhold; + storehold[idx]._iDurability = storehold[idx]._iMaxDur; + i = storehidx[idx]; + if (i < 0) { + if (i == -1) plr[myplr].HeadItem._iDurability = plr[myplr].HeadItem._iMaxDur; + if (i == -2) plr[myplr].BodyItem._iDurability = plr[myplr].BodyItem._iMaxDur; + if (i == -3) plr[myplr].Hand1Item._iDurability = plr[myplr].Hand1Item._iMaxDur; + if (i == -4) plr[myplr].Hand2Item._iDurability = plr[myplr].Hand2Item._iMaxDur; + } else plr[myplr].InvList[i]._iDurability = plr[myplr].InvList[i]._iMaxDur; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_SRepairEnter() +{ + int idx; + + if (stextsel == 22) { + StartStore(STORE_SMITH); + stextsel = 18; + } else { + stextshold = STORE_SREPAIR; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + plr[myplr].HoldItem = storehold[idx]; + if (plr[myplr]._pGold < storehold[idx]._iIvalue) StartStore(STORE_NOMONEY); + else StartStore(STORE_CONFIRM); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_WitchEnter() +{ + switch(stextsel) { + case 12: + talker = TWN_WITCH; + stextshold = STORE_WITCH; + stextlhold = 12; + gossipstart = TXT_ADRIA2; + gossipend = TXT_ADRIA13; + StartStore(STORE_TALK); + break; + case 14: + StartStore(STORE_WBUY); + break; + case 16: + StartStore(STORE_WSELL); + break; + case 18: + StartStore(STORE_WRECHARGE); + break; + case 20: + stextflag = STORE_NONE; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void WitchBuyItem() +{ + int idx; + + // Check if mana, full mana, portal, at top of list. These need new seeds + idx = ((stextlhold - stextup) >> 2) + stextvhold; + if (idx < 3) plr[myplr].HoldItem._iSeed = GetRndSeed(); + + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + // Put in players inv + StoreAutoPlace(); + + // Remove from witchitems + // If item index is mana, don't remove from her items list + if (idx < 3) { + CalcPlrInv(myplr, TRUE); + return; + } + if (idx == MAXWITCHITEMS-1) witchitem[idx]._itype = -1; + else { + while (witchitem[idx+1]._itype != -1) { + witchitem[idx] = witchitem[idx+1]; + idx++; + } + witchitem[idx]._itype = -1; + } + + CalcPlrInv(myplr, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_WBuyEnter() +{ + int idx, i; + BOOL done; + + if (stextsel == 22) { + StartStore(STORE_WITCH); + stextsel = 14; + } else { + stextshold = STORE_WBUY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + if (plr[myplr]._pGold < witchitem[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = witchitem[idx]; + SetCursor(plr[myplr].HoldItem._iCurs + ICSTART); + done = FALSE; + for (i = 0; (i < MAXINV) && (!done); i++) done = SpecialAutoPlace(myplr, i, cursW/28, cursH/28, FALSE); + if (done) StartStore(STORE_CONFIRM); + else StartStore(STORE_NOROOM); + SetCursor(GLOVE_CURS); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_WSellEnter() +{ + int idx; + + if (stextsel == 22) { + StartStore(STORE_WITCH); + stextsel = 16; + } else { + stextshold = STORE_WSELL; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + plr[myplr].HoldItem = storehold[idx]; + if (StoreGoldFit(idx)) StartStore(STORE_CONFIRM); + else StartStore(STORE_NOROOM); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void WitchRechargeItem() +{ + int i, idx; + + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + // Recharge staff + idx = ((stextlhold - stextup) >> 2) + stextvhold; + storehold[idx]._iCharges = storehold[idx]._iMaxCharges; + i = storehidx[idx]; + if (i < 0) plr[myplr].Hand1Item._iCharges = plr[myplr].Hand1Item._iMaxCharges; + else plr[myplr].InvList[i]._iCharges = plr[myplr].InvList[i]._iMaxCharges; + CalcPlrInv(myplr, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_WRechargeEnter() +{ + int idx; + + if (stextsel == 22) { + StartStore(STORE_WITCH); + stextsel = 18; + } else { + stextshold = STORE_WRECHARGE; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + plr[myplr].HoldItem = storehold[idx]; + if (plr[myplr]._pGold < storehold[idx]._iIvalue) StartStore(STORE_NOMONEY); + else StartStore(STORE_CONFIRM); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_BoyEnter() +{ + if ((boyitem._itype != -1) && (stextsel == 18)) { + if (plr[myplr]._pGold < 50) { + stextshold = STORE_BOY; + stextlhold = stextsel; + stextvhold = stextsval; + StartStore(STORE_NOMONEY); + } else { + TakePlrsMoney(50); + StartStore(STORE_BBUY); + } + } else { + if ( ((stextsel == 8) && (boyitem._itype != -1)) || ((stextsel == 12) && (boyitem._itype == -1)) ) { + talker = TWN_BOY; + stextshold = STORE_BOY; + stextlhold = stextsel; + gossipstart = TXT_WIRT2; + gossipend = TXT_WIRT12; + StartStore(STORE_TALK); + } else stextflag = STORE_NONE; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void BoyBuyItem() +{ + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + // Put in players inv + StoreAutoPlace(); + + // Remove from boyitem + boyitem._itype = -1; + stextshold = STORE_BOY; + + CalcPlrInv(myplr, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void HealerBuyItem() +{ + int idx; + + // Check if healing, full healing at top of list. These need new seeds + idx = ((stextlhold - stextup) >> 2) + stextvhold; + if (gbMaxPlayers == 1) { + if (idx < 2) plr[myplr].HoldItem._iSeed = GetRndSeed(); + } else { + if (idx < 3) plr[myplr].HoldItem._iSeed = GetRndSeed(); + } + + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + + // Put in players inv + if (!plr[myplr].HoldItem._iMagical) plr[myplr].HoldItem._iIdentified = FALSE; + StoreAutoPlace(); + + // Remove from healitems + // If item index is mana, don't remove from his items list + if (gbMaxPlayers == 1) { + if (idx < 2) return; + } else { + if (idx < 3) return; + } + idx = ((stextlhold - stextup) >> 2) + stextvhold; + if (idx == MAXHEALITEMS-1) healitem[idx]._itype = -1; + else { + while (healitem[idx+1]._itype != -1) { + healitem[idx] = healitem[idx+1]; + idx++; + } + healitem[idx]._itype = -1; + } + + CalcPlrInv(myplr, TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_BBuyEnter() +{ + int i; + BOOL done; + + if (stextsel == 10) { + stextshold = STORE_BBUY; + stextlhold = stextsel; + stextvhold = stextsval; + // PATCH2.JMM + //if (plr[myplr]._pGold < ( boyitem._iIvalue + ) StartStore(STORE_NOMONEY); + if (plr[myplr]._pGold < ( boyitem._iIvalue - (boyitem._iIvalue >> 2) ) ) StartStore(STORE_NOMONEY); + // ENDPATCH2.JMM + else { + plr[myplr].HoldItem = boyitem; + plr[myplr].HoldItem._iIvalue -= (plr[myplr].HoldItem._iIvalue >> 2); + SetCursor(plr[myplr].HoldItem._iCurs + ICSTART); + done = FALSE; + for (i = 0; (i < MAXINV) && (!done); i++) done = AutoPlace(myplr, i, cursW/28, cursH/28, FALSE); + if (done) StartStore(STORE_CONFIRM); + else StartStore(STORE_NOROOM); + SetCursor(GLOVE_CURS); + } + } else stextflag = STORE_NONE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void StoryIdItem() +{ + int i, idx; + + idx = ((stextlhold - stextup) >> 2) + stextvhold; + i = storehidx[idx]; + if (i < 0) { + if (i == -1) plr[myplr].HeadItem._iIdentified = TRUE; + if (i == -2) plr[myplr].BodyItem._iIdentified = TRUE; + if (i == -3) plr[myplr].Hand1Item._iIdentified = TRUE; + if (i == -4) plr[myplr].Hand2Item._iIdentified = TRUE; + if (i == -5) plr[myplr].Ring1Item._iIdentified = TRUE; + if (i == -6) plr[myplr].Ring2Item._iIdentified = TRUE; + if (i == -7) plr[myplr].NeckItem._iIdentified = TRUE; + } + else + plr[myplr].InvList[i]._iIdentified = TRUE; + + plr[myplr].HoldItem._iIdentified = TRUE; + + // Take players money + TakePlrsMoney(plr[myplr].HoldItem._iIvalue); + CalcPlrInv(myplr,TRUE); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_ConfirmEnter() +{ + if (stextsel == 18) { + switch(stextshold) { + case STORE_SBUY: + SmithBuyItem(); + break; + case STORE_SPBUY: + SmithBuyPItem(); + break; + case STORE_SSELL: + case STORE_WSELL: + StoreSellItem(); + break; + case STORE_SREPAIR: + SmithRepairItem(); + break; + case STORE_WBUY: + WitchBuyItem(); + break; + case STORE_WRECHARGE: + WitchRechargeItem(); + break; + case STORE_BBUY: + BoyBuyItem(); + break; + case STORE_HBUY: + HealerBuyItem(); + break; + case STORE_STORYID: + StoryIdItem(); + StartStore(STORE_IDSHOW); + return; + } + StartStore(stextshold); + } else { + StartStore(stextshold); + stextsel = stextlhold; + stextsval = stextvhold; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_HealerEnter() +{ + switch(stextsel) { + case 12: + talker = TWN_HEALER; + stextshold = STORE_HEALER; + stextlhold = 12; + gossipstart = TXT_PEPIN2; + gossipend = TXT_PEPIN11; + StartStore(STORE_TALK); + break; +// case 14: +// if (plr[myplr]._pHitPoints != plr[myplr]._pMaxHP) PlaySFX(IS_CAST8); +// plr[myplr]._pHitPoints = plr[myplr]._pMaxHP; +// plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase; +// drawhpflag = TRUE; +// break; + case 14: + StartStore(STORE_HBUY); + break; + case 16: + stextflag = STORE_NONE; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_HBuyEnter() +{ + int idx, i; + BOOL done; + + if (stextsel == 22) { + StartStore(STORE_HEALER); + stextsel = 16; + } else { + stextshold = STORE_HBUY; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + if (plr[myplr]._pGold < healitem[idx]._iIvalue) { + StartStore(STORE_NOMONEY); + } else { + plr[myplr].HoldItem = healitem[idx]; + SetCursor(plr[myplr].HoldItem._iCurs + ICSTART); + done = FALSE; + for (i = 0; (i < MAXINV) && (!done); i++) done = SpecialAutoPlace(myplr, i, cursW/28, cursH/28, FALSE); + if (done) StartStore(STORE_CONFIRM); + else StartStore(STORE_NOROOM); + SetCursor(GLOVE_CURS); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_StoryEnter() +{ + switch(stextsel) { + case 12: + talker = TWN_TELLER; + stextshold = STORE_STORYTLR; + stextlhold = 12; + gossipstart = TXT_STORY2; + gossipend = TXT_STORY11; + StartStore(STORE_TALK); + break; + case 14: + StartStore(STORE_STORYID); + break; + case 18: + stextflag = STORE_NONE; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_SIDEnter() +{ + int idx; + + if (stextsel == 22) { + StartStore(STORE_STORYTLR); + stextsel = 14; + } else { + stextshold = STORE_STORYID; + stextlhold = stextsel; + stextvhold = stextsval; + idx = ((stextsel - stextup) >> 2) + stextsval; + plr[myplr].HoldItem = storehold[idx]; + if (plr[myplr]._pGold < storehold[idx]._iIvalue) StartStore(STORE_NOMONEY); + else StartStore(STORE_CONFIRM); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_TalkEnter() +{ + int i, tq, sn, la; + + if (stextsel == 22) { + StartStore(stextshold); + stextsel = stextlhold; + } else { + tq = 0; + for (i = 0; i < MAXQUESTS; i++) { + if ((quests[i]._qactive == QUEST_NOTDONE) && (Qtalklist[talker][i] != -1) && quests[i]._qlog) tq++; + } + if (tq > 6) { + sn = 14 - (tq >> 1); + la = 1; + } else { + sn = 15 - tq; + la = 2; + } + if (stextsel == (sn - 2)) { + // Gossip + SetRndSeed(towner[talker]._tSeed); + int m = random(0, gossipend - gossipstart + 1) + gossipstart; + InitQTextMsg(m); + } else { + // Quest info + for (i = 0; i < MAXQUESTS; i++) { + if ((quests[i]._qactive == QUEST_NOTDONE) && (Qtalklist[talker][i] != -1) && quests[i]._qlog) { + if (sn == stextsel) InitQTextMsg(Qtalklist[talker][i]); + sn += la; + } + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_TavernEnter() +{ + switch(stextsel) { + case 12: + talker = TWN_BAROWNER; + stextshold = STORE_TAVERN; + stextlhold = 12; + gossipstart = TXT_OGDEN2; + gossipend = TXT_OGDEN10; + StartStore(STORE_TALK); + break; + case 18: + stextflag = STORE_NONE; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_BarmaidEnter() +{ + switch(stextsel) { + case 12: + talker = TWN_BARMAID; + stextshold = STORE_BARMAID; + stextlhold = 12; + gossipstart = TXT_GILIAN2; + gossipend = TXT_GILIAN10; + StartStore(STORE_TALK); + break; + case 18: + stextflag = STORE_NONE; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void S_DrunkEnter() +{ + switch(stextsel) { + case 12: + talker = TWN_DRUNK; + stextshold = STORE_DRUNK; + stextlhold = 12; + gossipstart = TXT_FARN2; + gossipend = TXT_FARN13; + StartStore(STORE_TALK); + break; + case 18: + stextflag = STORE_NONE; + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void STextEnter() +{ + if (qtextflag) { + qtextflag = FALSE; + if (leveltype == 0) stream_stop(); + return; + } + PlaySFX(IS_TITLSLCT); + switch(stextflag) { + case STORE_SMITH: + S_SmithEnter(); + break; + case STORE_SBUY: + S_SBuyEnter(); + break; + case STORE_SPBUY: + S_SPBuyEnter(); + break; + case STORE_SSELL: + S_SSellEnter(); + break; + case STORE_SREPAIR: + S_SRepairEnter(); + break; + case STORE_WITCH: + S_WitchEnter(); + break; + case STORE_WBUY: + S_WBuyEnter(); + break; + case STORE_WSELL: + S_WSellEnter(); + break; + case STORE_WRECHARGE: + S_WRechargeEnter(); + break; + case STORE_NOMONEY: + case STORE_NOROOM: + StartStore(stextshold); + stextsel = stextlhold; + stextsval = stextvhold; + break; + case STORE_CONFIRM: + S_ConfirmEnter(); + break; + case STORE_BOY: + S_BoyEnter(); + break; + case STORE_BBUY: + S_BBuyEnter(); + break; + case STORE_HEALER: + S_HealerEnter(); + break; + case STORE_STORYTLR: + S_StoryEnter(); + break; + case STORE_HBUY: + S_HBuyEnter(); + break; + case STORE_STORYID: + S_SIDEnter(); + break; + case STORE_TALK: + S_TalkEnter(); + break; + case STORE_IDSHOW: + StartStore(STORE_STORYID); + break; + case STORE_TAVERN: + S_TavernEnter(); + break; + case STORE_BARMAID: + S_BarmaidEnter(); + break; + case STORE_DRUNK: + S_DrunkEnter(); + break; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckStoreBtn() +{ + int y; + + if (qtextflag) { + qtextflag = FALSE; + if (leveltype == 0) stream_stop(); + return; + } + if (stextsel == -1) return; + if ((MouseY < 32) || (MouseY > 320)) return; + if (stextsize == STEXT_SMALL) { + if ((MouseX < 344) || (MouseX > 616)) return; + } else { + if ((MouseX < 24) || (MouseX > 616)) return; + } + y = (MouseY - 32) / 12; + if ((stextscrl) && (MouseX > 600)) { + if (y == 4) { + if (stextscrlubtn <= 0) { + STextUp(); + stextscrlubtn = 10; + } else stextscrlubtn--; + } + if (y == 20) { + if (stextscrldbtn <= 0) { + STextDown(); + stextscrldbtn = 10; + } else stextscrldbtn--; + } + } else { + if (y < 5) return; + if (y >= 23) y = 22; + if ((stextscrl) && (y < 21) && (!stext[y]._ssel)) { + if (stext[y-2]._ssel) y -= 2; + else if (stext[y-1]._ssel) y--; + } + if ((stext[y]._ssel) || (stextscrl && (y == 22))) { + stextsel = y; + STextEnter(); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void ReleaseStoreBtn() +{ + stextscrlubtn = -1; + stextscrldbtn = -1; +} + diff --git a/STORES.H b/STORES.H new file mode 100644 index 0000000..2dc1f50 --- /dev/null +++ b/STORES.H @@ -0,0 +1,115 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/STORES.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + + +#define MAXSMITHITEMS 25 +#define MAXWITCHITEMS 25 +#define MAXHEALITEMS 20 +#define MAXPREMIUM 15 + +#define NUMSTLINES ((MAXSMITHITEMS + 1) * 4) //24 + +#define STORE_NONE 0 +#define STORE_SMITH 1 +#define STORE_SBUY 2 +#define STORE_SSELL 3 +#define STORE_SREPAIR 4 +#define STORE_WITCH 5 +#define STORE_WBUY 6 +#define STORE_WSELL 7 +#define STORE_WRECHARGE 8 +#define STORE_NOMONEY 9 +#define STORE_NOROOM 10 +#define STORE_CONFIRM 11 +#define STORE_BOY 12 +#define STORE_BBUY 13 +#define STORE_HEALER 14 +#define STORE_STORYTLR 15 +#define STORE_HBUY 16 +#define STORE_STORYID 17 +#define STORE_SPBUY 18 +#define STORE_TALK 19 +#define STORE_IDSHOW 20 +#define STORE_TAVERN 21 +#define STORE_DRUNK 22 +#define STORE_BARMAID 23 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + int _sx; // X justify + int _syoff; // Y offset (usually 0) + char _sstr[128]; // string to print + BOOL _sjust; // Center, left, or right + char _sclr; // color + BOOL _sline; // just a line + BOOL _ssel; // selectable + //BOOL _shigh; // Highlighted + int _sval; // displayable value +} STextStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern BYTE *pSTextBoxCels; +extern BYTE *pSTextSpinCels; +extern BYTE *pSTextSlidCels; + +extern int SStringY[]; + +extern char stextflag; +extern ItemStruct smithitem[]; +extern ItemStruct premiumitem[]; +extern int numpremium, premiumlevel; +extern ItemStruct witchitem[]; +extern ItemStruct boyitem; +extern int boylevel; +extern ItemStruct golditem; +extern ItemStruct healitem[]; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitStores(); +void SetupTownStores(); +void FreeStoreMem(); + +void DrawSText(); +void STextESC(); +void STextUp(); +void STextDown(); +void STextPgUp(); +void STextPgDown(); +void STextEnter(); + +void StartStore(char); + +void DrawSTextBack(); +void PrintSString(int x, int y, BOOL cjustflag, char str[], char col, int val); +void DrawSLine(int y); + +void SetupSTextWin(); +void SetupSTextLWin(); + +void CheckStoreBtn(); +void ReleaseStoreBtn(); + +void TakePlrsMoney(long); +void SetGoldCurs(int, int); + +void SetSpdbarGoldCurs(int pnum, int i); diff --git a/STORM.DLL b/STORM.DLL new file mode 100644 index 0000000..c8295c3 Binary files /dev/null and b/STORM.DLL differ diff --git a/STORM.LIB b/STORM.LIB new file mode 100644 index 0000000..a2eefb2 Binary files /dev/null and b/STORM.LIB differ diff --git a/SYNC.CPP b/SYNC.CPP new file mode 100644 index 0000000..ad824f7 --- /dev/null +++ b/SYNC.CPP @@ -0,0 +1,470 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** sync.cpp +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/SYNC.CPP 3 2/10/97 6:23p Dbrevik2 $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "msg.h" +#include "multi.h" +#include "gendung.h" +#include "engine.h" +#include "items.h" +#include "player.h" +#include "error.h" +#include "debug.h" +#include "monster.h" +#include "monstint.h" +#include "inv.h" + +//****************************************************************** +// externs +//****************************************************************** +void M_ClearSquares(int nMonster); +void delta_sync_monster(const TSyncMonster * p,BYTE bLevel); + + +//****************************************************************** +// private +//****************************************************************** +static int sgnMonsters; +static WORD sgwDelta[MAXMONSTERS]; +static WORD sgwLRU[MAXMONSTERS]; +static int sgnLRUScan; + +#define LRU_NEVER 0xffff +#define LRU_REINIT 0xfffe +#define LRU_INIT 0xff + +static int sgnSyncItem = 0; +static int sgnSyncObj = 0; +static int sgnSyncPInv = 0; + +//****************************************************************** +//****************************************************************** +static void prep_monster_list(void) { + for (int i = 0; i < nummonsters; i++) { + int mi = monstactive[i]; + sgwDelta[mi] = abs(plr[myplr]._px - monster[mi]._mx) + + abs(plr[myplr]._py - monster[mi]._my); + + // make all the squelched monsters particularly unattractive + // make all the unsquelched monsters decrement their LRU + // counters so that they will get sent eventually + if (! monster[mi]._msquelch) + sgwDelta[mi] += 0x1000; + else if (sgwLRU[mi]) + sgwLRU[mi]--; + } +} + + +//****************************************************************** +//****************************************************************** +static void get_monster(TSyncMonster * p,int mi) { + // get the true monster number + // and save monster's parameters + p->_mndx = mi; + p->_mx = monster[mi]._mx; + p->_my = monster[mi]._my; + // encode player/monster enemy + p->_menemy = encode_enemy(mi); + p->_mdelta = sgwDelta[mi] > 0xff ? 0xff : sgwDelta[mi]; + // cant have this since menemy maybe a monster id + //app_assert((DWORD) p->_menemy < MAX_PLRS); + + // reset delta table so we don't find this monster again + sgwDelta[mi] = 0xffff; + + // reset LRU count so we don't resend this monster unnecessarily + sgwLRU[mi] = monster[mi]._msquelch ? LRU_REINIT : LRU_NEVER; +} + + +//****************************************************************** +//****************************************************************** +static BOOL get_best_monster(TSyncMonster * p) { + // search all the monsters for the one closest to the player + int nFound = -1; + DWORD dwMin = 0xffffffff; + for (int i = 0; i < nummonsters; i++) { + int mi = monstactive[i]; + + // is this monster close to the local player? + if (sgwDelta[mi] >= dwMin) continue; + + // is this a monster which has already been sent LRU? + if (sgwLRU[mi] >= LRU_REINIT) continue; + + // found better candidate + dwMin = sgwDelta[mi]; + nFound = mi; + } + if (nFound == -1) return FALSE; + get_monster(p,nFound); + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static BOOL get_lru_monster(TSyncMonster * p) { + // search all the monsters for the lowest LRU number + int nFound = -1; + DWORD dwMin = LRU_REINIT; + for (int i = 0; i < nummonsters; i++,sgnLRUScan++) { + if (sgnLRUScan >= nummonsters) sgnLRUScan = 0; + int mi = monstactive[sgnLRUScan]; + + // is this a monster which hasn't been sent in a while? + if (sgwLRU[mi] >= dwMin) continue; + + dwMin = sgwLRU[mi]; + nFound = mi; + } + if (nFound == -1) return FALSE; + get_monster(p,nFound); + return TRUE; +} + +//****************************************************************** +//****************************************************************** +static void FillHeaderSync(TSyncHeader * pHdr) +{ + // Fill one item + int ii; + if (numitems > 0) { + if (sgnSyncItem >= numitems) sgnSyncItem = 0; + ii = itemactive[sgnSyncItem++]; + pHdr->bItemI = ii; + pHdr->bItemX = item[ii]._ix; + pHdr->bItemY = item[ii]._iy; + pHdr->wItemIndx = item[ii].IDidx; + if (item[ii].IDidx == IDI_EAR) { + pHdr->wItemCI = (item[ii]._iName[7] << 8) | item[ii]._iName[8]; + pHdr->dwItemSeed = (item[ii]._iName[9] << 24) | + (item[ii]._iName[10] << 16) | + (item[ii]._iName[11] << 8) | + item[ii]._iName[12]; + pHdr->bItemId = item[ii]._iName[13]; + pHdr->bItemDur = item[ii]._iName[14]; + pHdr->bItemMDur = item[ii]._iName[15]; + pHdr->bItemCh = item[ii]._iName[16]; + pHdr->bItemMCh = item[ii]._iName[17]; + pHdr->wItemVal = (item[ii]._iName[18] << 8) | ((item[ii]._iCurs - ITEM_EAR1) << 6) | item[ii]._ivalue; + pHdr->dwItemBuff = (item[ii]._iName[19] << 24) | + (item[ii]._iName[20] << 16) | + (item[ii]._iName[21] << 8) | + item[ii]._iName[22]; + } else { + pHdr->wItemCI = item[ii]._iCreateInfo; + pHdr->dwItemSeed = item[ii]._iSeed; + pHdr->bItemId = item[ii]._iIdentified; + pHdr->bItemDur = item[ii]._iDurability; + pHdr->bItemMDur = item[ii]._iMaxDur; + pHdr->bItemCh = item[ii]._iCharges; + pHdr->bItemMCh = item[ii]._iMaxCharges; + if (item[ii].IDidx == IDI_GOLD) pHdr->wItemVal = item[ii]._ivalue; + } + } + else { + pHdr->bItemI = 0xff; + } + + // Fill with player inv info + app_assert((DWORD) sgnSyncPInv < NUM_INVLOC); + ItemStruct *itm = &plr[myplr].InvBody[sgnSyncPInv]; + if (itm->_itype != -1) { + pHdr->bPInvLoc = sgnSyncPInv; + pHdr->wPInvIndx = itm->IDidx; + pHdr->wPInvCI = itm->_iCreateInfo; + pHdr->dwPInvSeed = itm->_iSeed; + // drb.patch1.start.02/10/97 + pHdr->bPInvId = itm->_iIdentified; + // drb.patch1.end.02/10/97 + } + else { + pHdr->bPInvLoc = 0xff; + } + + // next item + sgnSyncPInv++; + if (sgnSyncPInv >= NUM_INVLOC) + sgnSyncPInv = 0; +} + + +//****************************************************************** +//****************************************************************** +DWORD sync_get(BYTE * pbBuf,DWORD dwMaxLen) { + // if there are no monsters to sync, exit + if (nummonsters < 1) return dwMaxLen; + + // is there enough space for at header + one monster sync + if (dwMaxLen < sizeof(TSyncMonster) + sizeof(TSyncHeader)) + return dwMaxLen; + + // setup header + TSyncHeader * pHdr = (TSyncHeader *) pbBuf; + pbBuf += sizeof(TSyncHeader); + dwMaxLen -= sizeof(TSyncHeader); + pHdr->bCmd = CMD_SYNCDATA; + pHdr->bLevel = currlevel; + pHdr->wLen = 0; + // Put one object, one item and one plr inv item into sync packets + FillHeaderSync(pHdr); + + // make sure we don't overrun header maximum length + app_assert(dwMaxLen <= 0xffff); + + prep_monster_list(); + for (int nMonsters = 0; nMonsters < nummonsters; nMonsters++) { + if (dwMaxLen < sizeof(TSyncMonster)) break; + + BOOL bGotOne = FALSE; + if (nMonsters < 2) bGotOne = get_lru_monster((TSyncMonster *) pbBuf); + if (! bGotOne) bGotOne = get_best_monster((TSyncMonster *) pbBuf); + if (! bGotOne) break; + + pbBuf += sizeof(TSyncMonster); + pHdr->wLen += sizeof(TSyncMonster); + dwMaxLen -= sizeof(TSyncMonster); + } + + // return bytes left in buffer + return dwMaxLen; +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------* + +byte monstupdate[MAXMONSTERS]; + +void DaveMonstMap(BOOL initupdate, int pnum) +{ + int i,j,m; + char tempstr[512], tempstr2[256]; + + if (initupdate) + for (i = 0; i < MAXMONSTERS; i++) monstupdate[i] = 0; + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dFlags[i][j] & BFLAG_MONSTLR) { + if (dMonster[i-1][j] != dMonster[i][j-1]) { + sprintf(tempstr, "Error in map @ %i,%i x-1,j = %i, x,j-1 = %i\n", i, j, dMonster[i-1][j], dMonster[i][j-1]); + if (dMonster[i-1][j] == 0) sprintf(tempstr2, "Null monster\n @ %i,%i", i-1, j); + else { + if (dMonster[i-1][j] > 0) m = dMonster[i-1][j] - 1; + else m = -(dMonster[i-1][j] + 1); + sprintf(tempstr2, "Monst %i xy = %i,%i oxy = %i,%i mode = %i Updated = %i\n", + m, monster[m]._mx, monster[m]._my, monster[m]._moldx, monster[m]._moldy, monster[m]._mmode, monstupdate[m]); + } + strcat(tempstr, tempstr2); + if (dMonster[i][j-1] == 0) sprintf(tempstr2, "Null monster @ %i,%i\n", i, j-1); + else { + if (dMonster[i][j-1] > 0) m = dMonster[i][j-1] - 1; + else m = -(dMonster[i][j-1] + 1); + sprintf(tempstr2, "Monst %i xy = %i,%i oxy = %i,%i mode = %i Updated = %i\n", + m, monster[m]._mx, monster[m]._my, monster[m]._moldx, monster[m]._moldy, monster[m]._mmode, monstupdate[m]); + } + strcat(tempstr, tempstr2); + sprintf(tempstr2, "Info from plr %i = %s", pnum, plr[pnum]._pName); + strcat(tempstr, tempstr2); + app_fatal(tempstr); + } + } + } + } +} +*/ +//****************************************************************** +//****************************************************************** +static void sync_monster(int pnum,const TSyncMonster * p) { + + // get monster index + int ndx = p->_mndx; + + // did I just kill this monster? + if (monster[ndx]._mhitpoints <= 0) return; + + // check for valid index + for (int i = 0; i < nummonsters && monstactive[i] != ndx; i++); + //app_assert(i < nummonsters); + + // calc distance I think he is from me + DWORD delta = + abs(plr[myplr]._px - monster[ndx]._mx) + + abs(plr[myplr]._py - monster[ndx]._my); + if (delta > 0xff) delta = 0xff; + + // if my delta is less than the other player's delta, use mine + if (delta < p->_mdelta) return; + // if the deltas are the same use the lowest player num + else if ((delta == p->_mdelta) && (pnum > myplr)) return; + + // if the monster is going to be there soon, don't do anything + if (monster[ndx]._mfutx == p->_mx && monster[ndx]._mfuty == p->_my) return; + + // Snake crash fix. Don't mess with missile monsters while they are warping + if (monster[ndx]._mmode == MM_MISSILE) return; + // Don't mess with stone cursed monsters + if (monster[ndx]._mmode == MM_STONE) return; + + // if the monster is far away, jump him into position + int mdx = abs(monster[ndx]._mx - p->_mx); + int mdy = abs(monster[ndx]._my - p->_my); + if (mdx > 2 || mdy > 2) { + if (! dMonster[p->_mx][p->_my]) { + // remove where monster is now + M_ClearSquares(ndx); + + // put him in new location + dMonster[p->_mx][p->_my] = ndx + 1; + monster[ndx]._mx = p->_mx; + monster[ndx]._my = p->_my; + decode_enemy(ndx, p->_menemy); + M_StartStand(ndx, GetDirection(p->_mx,p->_my, monster[ndx]._menemyx, monster[ndx]._menemyy)); + + // make sure he's awake + monster[ndx]._msquelch = 255; + } + } + else { + // if the monster is not already on the way to a nearby + // square, start him immediately on his way + if ((monster[ndx]._mmode < MM_WALK) || (monster[ndx]._mmode > MM_WALK3)) { + int md = GetDirection(monster[ndx]._mx, monster[ndx]._my, p->_mx, p->_my); + + if (DirOK(ndx, md)) { + // remove where monster is now + M_ClearSquares(ndx); + + // make monster walk into square where he should be + dMonster[monster[ndx]._mx][monster[ndx]._my] = ndx + 1; + M_WalkDir(ndx, md); + + // make sure he's awake + monster[ndx]._msquelch = 255; + } + } + } + + // sync enemy + // cant have this since menemy maybe a monster id + //app_assert((DWORD) p->_menemy < MAX_PLRS); + decode_enemy(ndx, p->_menemy); +} + + +//****************************************************************** +//****************************************************************** +static void UpdateHeaderSync(int pnum, const TSyncHeader * pHdr) +{ + // Fill one item + if (pHdr->bItemI != 0xff) { + int ii = pHdr->bItemI; + if ((pHdr->wItemIndx != item[ii].IDidx) || + (pHdr->wItemCI != item[ii]._iCreateInfo) || + (pHdr->dwItemSeed != item[ii]._iSeed)) { + ii = FindGetItem(pHdr->wItemIndx, pHdr->wItemCI, pHdr->dwItemSeed); + if (ii == -1) { + SyncPutItem(pnum, + pHdr->bItemX, + pHdr->bItemY, + pHdr->wItemIndx, + pHdr->wItemCI, + pHdr->dwItemSeed, + pHdr->bItemId, + pHdr->bItemDur, + pHdr->bItemMDur, + pHdr->bItemCh, + pHdr->bItemMCh, + pHdr->wItemVal, + pHdr->dwItemBuff, + pHdr->wPLToHit, + pHdr->wMaxDam, + pHdr->bMinStr, + pHdr->bMinMag, + pHdr->bMinDex, + pHdr->bAC + ); + } + } + } + // Fill with player inv info + if (pHdr->bPInvLoc != 0xff) { + ItemStruct *itm = &plr[myplr].InvBody[pHdr->bPInvLoc]; + if ((pHdr->wPInvIndx != itm->IDidx) || + (pHdr->wPInvCI != itm->_iCreateInfo) || + // drb.patch1.start.02/10/97 + // (pHdr->dwPInvSeed != itm->_iSeed)) { + (pHdr->dwPInvSeed != itm->_iSeed) || + (pHdr->bPInvId != itm->_iIdentified)) { + // SyncInvPaste(pnum, pHdr->bPInvLoc, pHdr->wPInvIndx, pHdr->wPInvCI, pHdr->dwPInvSeed,); + SyncInvPaste(pnum, pHdr->bPInvLoc, pHdr->wPInvIndx, pHdr->wPInvCI, pHdr->dwPInvSeed, pHdr->bPInvId); + // drb.patch1.end.02/10/97 + } + } +} + + +//****************************************************************** +//****************************************************************** +DWORD sync_update(int pnum,const BYTE * pbBuf) { + const TSyncHeader * pHdr = (const TSyncHeader *) pbBuf; + pbBuf += sizeof(TSyncHeader); + + // make sure we have a valid sync record + if (pHdr->bCmd != CMD_SYNCDATA) + app_fatal("bad sync command"); + + // don't resync while we're in buffer mode + app_assert(gbBufferMsgs != BUFFER_PROCESS); + if (gbBufferMsgs == BUFFER_ON) + return pHdr->wLen + sizeof(TSyncHeader); + + // we don't resync using our own information + if (pnum == myplr) return pHdr->wLen + sizeof(TSyncHeader); + + // Make sure we are in sync with others on the level + //if (currlevel == pHdr->bLevel) UpdateHeaderSync(pnum, pHdr); + + WORD wLen = pHdr->wLen; + while (wLen >= sizeof(TSyncMonster)) { + if (currlevel == pHdr->bLevel) + sync_monster(pnum,(const TSyncMonster *) pbBuf); + delta_sync_monster((const TSyncMonster *) pbBuf,pHdr->bLevel); + pbBuf += sizeof(TSyncMonster); + wLen -= sizeof(TSyncMonster); + } + + // make sure we used all the bytes + app_assert(wLen == 0); + + // return true number of bytes in our sync section + return pHdr->wLen + sizeof(TSyncHeader); +} + + +//****************************************************************** +//****************************************************************** +void sync_init() { + // don't let all the players start scanning in the same location. + // if each player is scanning from a different location, it is + // more likely that multiple monsters can be synced every turn + sgnLRUScan = myplr * 16; + FillMemory(sgwLRU,sizeof sgwLRU,LRU_INIT); +} diff --git a/SYSMON.EXE b/SYSMON.EXE new file mode 100644 index 0000000..d06854a Binary files /dev/null and b/SYSMON.EXE differ diff --git a/Scroll_asm.cpp b/Scroll_asm.cpp new file mode 100644 index 0000000..e6c107b --- /dev/null +++ b/Scroll_asm.cpp @@ -0,0 +1,840 @@ +// scroll_asm.cpp +// + +#include +#include +#include + +#ifndef SCROLL_FASTCALL +# if defined(_MSC_VER) +# define SCROLL_FASTCALL __fastcall +# elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(_M_IX86)) +# define SCROLL_FASTCALL __attribute__((fastcall)) +# else +# define SCROLL_FASTCALL +# endif +#endif + +#ifndef SCROLL_EXTERN_C +# if defined(__cplusplus) +# define SCROLL_EXTERN_C extern "C" +# else +# define SCROLL_EXTERN_C +# endif +#endif + + /* + * The original MASM module imported/exported C-linkage COFF symbols + * (_nLVal, _pDungeonCels, @DrawMTileClipTop@4, ...). Keep that linkage + * even if this .c file is accidentally compiled as C++. + */ +#ifndef SCROLL_PORT_EXTERN_C_GLOBALS +# define SCROLL_PORT_EXTERN_C_GLOBALS 1 +#endif + +#ifndef SCROLL_BYTE_DEFINED +typedef uint8_t BYTE; +#define SCROLL_BYTE_DEFINED 1 +#endif + +#ifndef SCROLL_DWORD_DEFINED +typedef uint32_t DWORD; +#define SCROLL_DWORD_DEFINED 1 +#endif + +#define WTYPE_NONE 0 +#define WTYPE_LEFT 1 +#define WTYPE_RIGHT 2 +#define WTYPE_ULC 3 +#define WTYPE_LRC 4 + +#define PART_TRANS_NONE 0 +#define PART_TRANS_LEFT 1 +#define PART_TRANS_RIGHT 2 + +#define NBUFFW32 800 +#define NBUFFW64 832 + +#ifndef SCROLL_UNUSED +# if defined(__GNUC__) || defined(__clang__) +# define SCROLL_UNUSED __attribute__((unused)) +# else +# define SCROLL_UNUSED +# endif +#endif + +/* + * Externals from the original engine modules. + * + * scroll.asm used these as C-linkage imports, so these declarations must also + * use C linkage when this file is compiled as C++. Otherwise MSVC emits + * unresolved symbols such as ?pSpeedCels@@3PAEA instead of the original + * _pSpeedCels import. + * + * Leave SCROLL_DEFINE_GLOBALS undefined for the normal Diablo build, where + * scrollrt.cpp, lighting.cpp, and gendung.cpp provide the storage. Define it + * in exactly one translation unit only for a standalone harness that does not + * link those modules. + */ +#if defined(__cplusplus) && SCROLL_PORT_EXTERN_C_GLOBALS +extern "C" { +#endif +#ifndef SCROLL_DEFINE_GLOBALS + extern int32_t nLVal; + extern BYTE* glClipY; + extern int32_t gnPieceNum; + extern int32_t nTrans; + extern DWORD gdwPNum; + extern BYTE gbPartialTrans; + + extern BYTE lightmax; + extern BYTE* pLightTbl; + + extern DWORD microoffset[]; + extern BYTE* pDungeonCels; + extern BYTE* pSpeedCels; + extern BYTE nWTypeTable[]; +#else + int32_t nLVal; + BYTE* glClipY; + int32_t gnPieceNum; + int32_t nTrans; + DWORD gdwPNum; + BYTE gbPartialTrans; + + BYTE lightmax; + BYTE* pLightTbl; + + DWORD microoffset[4096 * 16]; + BYTE* pDungeonCels; + BYTE* pSpeedCels; + BYTE nWTypeTable[4096]; +#endif +#if defined(__cplusplus) && SCROLL_PORT_EXTERN_C_GLOBALS +} +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + void SCROLL_FASTCALL DrawMTileClipTop(BYTE* pDecodeTo); + void SCROLL_FASTCALL DrawMTileClipBottom(BYTE* pDecodeTo); +#if defined(__cplusplus) +} +#endif + +/* Private data from scroll.asm. */ +static DWORD sgLineVal; +static DWORD sgCM; +static BYTE sgWT; +static DWORD* sgT; +static const DWORD* sgMask; +static DWORD sgTimeLow; +static DWORD sgTimeHigh; +static DWORD sgLoopTime; +static DWORD sgUnrollTime; + +static const DWORD sgRightMask[32] = { + 0xEAAAAAAAu, 0xF5555555u, 0xFEAAAAAAu, 0xFF555555u, + 0xFFEAAAAAu, 0xFFF55555u, 0xFFFEAAAAu, 0xFFFF5555u, + 0xFFFFEAAAu, 0xFFFFF555u, 0xFFFFFEAAu, 0xFFFFFF55u, + 0xFFFFFFEAu, 0xFFFFFFF5u, 0xFFFFFFFEu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, +}; + +static const DWORD sgLeftMask[32] = { + 0xAAAAAAABu, 0x5555555Fu, 0xAAAAAABFu, 0x555555FFu, + 0xAAAAABFFu, 0x55555FFFu, 0xAAAABFFFu, 0x5555FFFFu, + 0xAAABFFFFu, 0x555FFFFFu, 0xAABFFFFFu, 0x55FFFFFFu, + 0xABFFFFFFu, 0x5FFFFFFFu, 0xBFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, +}; + +static const DWORD sgFullMask[32] = { + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, + 0xAAAAAAAAu, 0x55555555u, 0xAAAAAAAAu, 0x55555555u, +}; + +static const DWORD sgDivBy3MulBy4[48] = { + 0, 0, 0, 4, 4, 4, 8, 8, 8,12,12,12,16,16,16, + 20,20,20,24,24,24,28,28,28,32,32,32,36,36,36, + 40,40,40,44,44,44,48,48,48,52,52,52,56,56,56, + 60,60,60 +}; + +static const DWORD TotalDataPerLineBottom[17] = { + 0, 4, 8, 16, 24, 36, 48, 64, 80, + 100,120,144,168,196,224,256,288 +}; + +static const DWORD TotalDataPerLineTop[17] = { + 0, 32, 60, 88,112,136,156,176,192, + 208,220,232,240,248,252,256,288 +}; + +static SCROLL_UNUSED uint16_t LoadLE16(const BYTE* p) +{ + return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] << 8)); +} + +static uint32_t LoadLE32(const BYTE* p) +{ + return (uint32_t)p[0] + | ((uint32_t)p[1] << 8) + | ((uint32_t)p[2] << 16) + | ((uint32_t)p[3] << 24); +} + +static SCROLL_UNUSED void StoreLE16(BYTE* p, uint16_t v) +{ + p[0] = (BYTE)(v & 0xFFu); + p[1] = (BYTE)((v >> 8) & 0xFFu); +} + +static void StoreLE32(BYTE* p, uint32_t v) +{ + p[0] = (BYTE)(v & 0xFFu); + p[1] = (BYTE)((v >> 8) & 0xFFu); + p[2] = (BYTE)((v >> 16) & 0xFFu); + p[3] = (BYTE)((v >> 24) & 0xFFu); +} + +static uintptr_t ClipAddr(void) +{ + return (uintptr_t)glClipY; +} + +static int PtrBelowClip(const BYTE* p) +{ + return (uintptr_t)p < ClipAddr(); +} + +static int BeginRowTop(BYTE* dst) +{ + return !PtrBelowClip(dst); +} + +static int BeginRowBottomDraw(BYTE* dst) +{ + return PtrBelowClip(dst); +} + +typedef enum PixelMode { + PIXELS_LIGHT, + PIXELS_PRETRANS, + PIXELS_BLACK +} PixelMode; + +typedef enum TransMode { + TRANS_OPAQUE, + TRANS_DITHER, + TRANS_HALF_MASK +} TransMode; + +typedef enum ClipMode { + CLIP_TOP_MODE, + CLIP_BOTTOM_MODE +} ClipMode; + +typedef enum PadMode { + PAD_NONE, + PAD_PRE, + PAD_POST +} PadMode; + +typedef struct RenderSetup { + const BYTE* src; + const BYTE* lightTbl; + PixelMode pixelMode; + int shape; +} RenderSetup; + +typedef struct RenderCtx { + const BYTE* src; + BYTE* dst; + const BYTE* lightTbl; + PixelMode pixelMode; + TransMode transMode; + ClipMode clipMode; + const DWORD* maskPtr; + DWORD maskWord; + int linePhase; +} RenderCtx; + +static const BYTE* GetDungeonCelSource(DWORD pnum) +{ + DWORD cel = pnum & 0x0FFFu; + DWORD offs = LoadLE32(pDungeonCels + cel * 4u); + return pDungeonCels + offs; +} + +static const BYTE* GetSpeedCelSource(DWORD pnum) +{ + DWORD cel = pnum & 0x0FFFu; + DWORD idx = (cel << 4) + (DWORD)nLVal; + return pSpeedCels + microoffset[idx]; +} + +static void ResolveSpeedCelToNormalPNum(void) +{ + DWORD pnum = gdwPNum; + DWORD cel = pnum & 0x0FFFu; + gdwPNum = (pnum & 0xF000u) + microoffset[cel << 4]; +} + +static int ShapeFromNormalType(DWORD type) +{ + return (type <= 4u) ? (int)type : 5; +} + +static int ShapeFromPretransType(DWORD type) +{ + switch (type) { + case 8: return 0; + case 9: return 1; + case 10: return 2; + case 11: return 3; + case 12: return 4; + default: return 5; + } +} + +static int ShapeFromBlackType(DWORD type) +{ + return (type <= 4u) ? (int)type : 5; +} + +static RenderSetup GetRenderSetup(void) +{ + RenderSetup setup; + DWORD pnum = gdwPNum; + BYTE lval = (BYTE)nLVal; + + setup.src = NULL; + setup.lightTbl = NULL; + setup.pixelMode = PIXELS_PRETRANS; + setup.shape = 0; + + sgT = microoffset; + + if (lval != 0) { + if (lval == lightmax) { + if ((pnum & 0x8000u) != 0) { + ResolveSpeedCelToNormalPNum(); + pnum = gdwPNum; + } + setup.src = GetDungeonCelSource(pnum); + setup.pixelMode = PIXELS_BLACK; + setup.shape = ShapeFromBlackType((pnum >> 12) & 0x07u); + return setup; + } + + if ((pnum & 0x8000u) != 0) { + setup.src = GetSpeedCelSource(pnum); + setup.pixelMode = PIXELS_PRETRANS; + setup.shape = ShapeFromPretransType((pnum >> 12) & 0x0Fu); + return setup; + } + + setup.src = GetDungeonCelSource(pnum); + setup.lightTbl = pLightTbl + ((DWORD)nLVal << 8); + setup.pixelMode = PIXELS_LIGHT; + setup.shape = ShapeFromNormalType((pnum >> 12) & 0x0Fu); + return setup; + } + + /* No light: resolve speed CELs back to the unlighted dungeon CEL. */ + if ((pnum & 0x8000u) != 0) { + ResolveSpeedCelToNormalPNum(); + pnum = gdwPNum; + } + setup.src = GetDungeonCelSource(pnum); + setup.pixelMode = PIXELS_PRETRANS; + setup.shape = ShapeFromPretransType(((pnum >> 12) & 0x07u) + 8u); + return setup; +} + +static int PixelSelected(const RenderCtx* ctx, int x) +{ + if (ctx->transMode == TRANS_DITHER) { + return ((x & 1) != ctx->linePhase); + } + if (ctx->transMode == TRANS_HALF_MASK) { + return (ctx->maskWord & (0x80000000u >> (unsigned)x)) != 0; + } + return 1; +} + +static void DrawSpan(RenderCtx* ctx, int count, int xStart, PadMode pad, int draw) +{ + int i; + const BYTE* src; + BYTE* dst; + + if (count <= 0) { + return; + } + + if (pad == PAD_PRE) { + ctx->src += (count & 2); + } + + src = ctx->src; + dst = ctx->dst; + + if (draw) { + for (i = 0; i < count; i++) { + if (PixelSelected(ctx, xStart + i)) { + switch (ctx->pixelMode) { + case PIXELS_LIGHT: + dst[i] = ctx->lightTbl[src[i]]; + break; + case PIXELS_PRETRANS: + dst[i] = src[i]; + break; + case PIXELS_BLACK: + dst[i] = 0; + break; + } + } + } + } + + ctx->src = src + count; + ctx->dst = dst + count; + + if (pad == PAD_POST) { + ctx->src += ((uintptr_t)ctx->src & 2u); + } +} + +static void FinishRow(RenderCtx* ctx) +{ + if (ctx->transMode == TRANS_DITHER) { + ctx->linePhase ^= 1; + } + else if (ctx->transMode == TRANS_HALF_MASK && ctx->maskPtr != NULL) { + ctx->maskPtr--; + } +} + +static int StartRow(RenderCtx* ctx, int* draw) +{ + if (ctx->clipMode == CLIP_TOP_MODE) { + if (!BeginRowTop(ctx->dst)) { + return 0; + } + *draw = 1; + } + else { + *draw = BeginRowBottomDraw(ctx->dst); + } + + if (ctx->transMode == TRANS_HALF_MASK && ctx->maskPtr != NULL) { + ctx->maskWord = *ctx->maskPtr; + } + else { + ctx->maskWord = 0xFFFFFFFFu; + } + return 1; +} + +static int DrawFullRow(RenderCtx* ctx) +{ + int draw; + if (!StartRow(ctx, &draw)) { + return 0; + } + DrawSpan(ctx, 32, 0, PAD_NONE, draw); + ctx->dst -= NBUFFW32; + FinishRow(ctx); + return 1; +} + +static int DrawLeftTriangleRow(RenderCtx* ctx, int leftSkip) +{ + int draw; + if (!StartRow(ctx, &draw)) { + return 0; + } + ctx->dst += leftSkip; + DrawSpan(ctx, 32 - leftSkip, leftSkip, PAD_PRE, draw); + ctx->dst -= NBUFFW32; + FinishRow(ctx); + return 1; +} + +static int DrawRightTriangleRow(RenderCtx* ctx, int rightSkip) +{ + int draw; + if (!StartRow(ctx, &draw)) { + return 0; + } + DrawSpan(ctx, 32 - rightSkip, 0, PAD_POST, draw); + ctx->dst -= NBUFFW32; + ctx->dst += rightSkip; + FinishRow(ctx); + return 1; +} + +static int DrawSolidRows(RenderCtx* ctx, int rows) +{ + int row; + for (row = 0; row < rows; row++) { + if (!DrawFullRow(ctx)) { + return 0; + } + } + return 1; +} + +static int DrawLeftBottomHalf(RenderCtx* ctx) +{ + int skip; + for (skip = 30; skip >= 0; skip -= 2) { + if (!DrawLeftTriangleRow(ctx, skip)) { + return 0; + } + } + return 1; +} + +static int DrawLeftTopHalf(RenderCtx* ctx) +{ + int skip; + for (skip = 2; skip != 32; skip += 2) { + if (!DrawLeftTriangleRow(ctx, skip)) { + return 0; + } + } + return 1; +} + +static int DrawRightBottomHalf(RenderCtx* ctx) +{ + int skip; + for (skip = 30; skip >= 0; skip -= 2) { + if (!DrawRightTriangleRow(ctx, skip)) { + return 0; + } + } + return 1; +} + +static int DrawRightTopHalf(RenderCtx* ctx) +{ + int skip; + for (skip = 2; skip != 32; skip += 2) { + if (!DrawRightTriangleRow(ctx, skip)) { + return 0; + } + } + return 1; +} + +static int DrawRleRows(RenderCtx* ctx) +{ + int row; + for (row = 0; row < 32; row++) { + int remaining = 32; + int x = 0; + + if (ctx->transMode == TRANS_HALF_MASK && ctx->maskPtr != NULL) { + ctx->maskWord = *ctx->maskPtr; + } + else { + ctx->maskWord = 0xFFFFFFFFu; + } + + while (remaining != 0) { + BYTE raw = *ctx->src++; + if ((raw & 0x80u) != 0) { + int jump = (int)((BYTE)(0u - raw)); + ctx->dst += jump; + x += jump; + remaining -= jump; + } + else { + int count = (int)raw; + int draw; + remaining -= count; + + if (ctx->clipMode == CLIP_TOP_MODE) { + if (!BeginRowTop(ctx->dst)) { + return 0; + } + draw = 1; + } + else { + draw = BeginRowBottomDraw(ctx->dst); + } + + DrawSpan(ctx, count, x, PAD_NONE, draw); + x += count; + } + } + + ctx->dst -= NBUFFW32; + FinishRow(ctx); + } + return 1; +} + +static void RenderShape(BYTE* dst, const RenderSetup* setup, TransMode transMode, ClipMode clipMode, const DWORD* maskStart) +{ + RenderCtx ctx; + ctx.src = setup->src; + ctx.dst = dst; + ctx.lightTbl = setup->lightTbl; + ctx.pixelMode = setup->pixelMode; + ctx.transMode = transMode; + ctx.clipMode = clipMode; + ctx.maskPtr = maskStart; + ctx.maskWord = 0xFFFFFFFFu; + ctx.linePhase = 0; + + switch (setup->shape) { + case 0: /* Solid 32x32 block. */ + (void)DrawSolidRows(&ctx, 32); + break; + + case 1: /* 32x32 block with transparent holes. */ + (void)DrawRleRows(&ctx); + break; + + case 2: /* Left triangle / diamond. */ + if (transMode == TRANS_HALF_MASK) { + ctx.transMode = TRANS_OPAQUE; + ctx.maskPtr = NULL; + } + if (!DrawLeftBottomHalf(&ctx)) { + break; + } + (void)DrawLeftTopHalf(&ctx); + break; + + case 3: /* Right triangle / diamond. */ + if (transMode == TRANS_HALF_MASK) { + ctx.transMode = TRANS_OPAQUE; + ctx.maskPtr = NULL; + } + if (!DrawRightBottomHalf(&ctx)) { + break; + } + (void)DrawRightTopHalf(&ctx); + break; + + case 4: /* Left triangle to wall. */ + if (transMode == TRANS_HALF_MASK) { + ctx.transMode = TRANS_OPAQUE; + ctx.maskPtr = NULL; + } + if (!DrawLeftBottomHalf(&ctx)) { + break; + } + if (transMode == TRANS_HALF_MASK) { + ctx.transMode = TRANS_HALF_MASK; + ctx.maskPtr = maskStart - 16; + } + else { + ctx.transMode = transMode; + } + (void)DrawSolidRows(&ctx, 16); + break; + + case 5: /* Right triangle to wall. */ + default: + if (transMode == TRANS_HALF_MASK) { + ctx.transMode = TRANS_OPAQUE; + ctx.maskPtr = NULL; + } + if (!DrawRightBottomHalf(&ctx)) { + break; + } + if (transMode == TRANS_HALF_MASK) { + ctx.transMode = TRANS_HALF_MASK; + ctx.maskPtr = maskStart - 16; + } + else { + ctx.transMode = transMode; + } + (void)DrawSolidRows(&ctx, 16); + break; + } +} + +static void DrawMTileDitherClipTop(BYTE* pDecodeTo) +{ + RenderSetup setup = GetRenderSetup(); + RenderShape(pDecodeTo, &setup, TRANS_DITHER, CLIP_TOP_MODE, NULL); +} + +static void DrawMTileHalfDitherClipTop(BYTE* pDecodeTo, const DWORD* mask) +{ + RenderSetup setup = GetRenderSetup(); + RenderShape(pDecodeTo, &setup, TRANS_HALF_MASK, CLIP_TOP_MODE, mask); +} + +static void DrawMTileDitherClipBottom(BYTE* pDecodeTo) +{ + RenderSetup setup = GetRenderSetup(); + RenderShape(pDecodeTo, &setup, TRANS_DITHER, CLIP_BOTTOM_MODE, NULL); +} + +static void DrawMTileHalfDitherClipBottom(BYTE* pDecodeTo, const DWORD* mask) +{ + RenderSetup setup = GetRenderSetup(); + RenderShape(pDecodeTo, &setup, TRANS_HALF_MASK, CLIP_BOTTOM_MODE, mask); +} + +static void DrawMTileNoTransClipTop(BYTE* pDecodeTo) +{ + RenderSetup setup = GetRenderSetup(); + RenderShape(pDecodeTo, &setup, TRANS_OPAQUE, CLIP_TOP_MODE, NULL); +} + +static void DrawMTileNoTransClipBottom(BYTE* pDecodeTo) +{ + RenderSetup setup = GetRenderSetup(); + RenderShape(pDecodeTo, &setup, TRANS_OPAQUE, CLIP_BOTTOM_MODE, NULL); +} + +SCROLL_EXTERN_C void SCROLL_FASTCALL DrawMTileClipTop(BYTE* pDecodeTo) +{ + BYTE partial; + BYTE wt; + + if (nTrans != 0) { + partial = gbPartialTrans; + if (partial == PART_TRANS_NONE) { + DrawMTileDitherClipTop(pDecodeTo); + return; + } + + if (partial == PART_TRANS_LEFT) { + wt = nWTypeTable[gnPieceNum]; + if (wt == WTYPE_LEFT || wt == WTYPE_ULC) { + DrawMTileHalfDitherClipTop(pDecodeTo, &sgLeftMask[31]); + return; + } + /* The original assembly jumps to the PART_TRANS_RIGHT test here; + * its following WTYPE_LRC check is unreachable, so it is preserved + * as unreachable behavior by falling through to no-trans rendering. + */ + } + + if (partial == PART_TRANS_RIGHT) { + wt = nWTypeTable[gnPieceNum]; + if (wt == WTYPE_RIGHT || wt == WTYPE_ULC) { + DrawMTileHalfDitherClipTop(pDecodeTo, &sgRightMask[31]); + return; + } + /* Same unreachable WTYPE_LRC path as in scroll.asm. */ + } + } + + DrawMTileNoTransClipTop(pDecodeTo); +} + +SCROLL_EXTERN_C void SCROLL_FASTCALL DrawMTileClipBottom(BYTE* pDecodeTo) +{ + BYTE partial; + BYTE wt; + + if (nTrans != 0) { + partial = gbPartialTrans; + if (partial == PART_TRANS_NONE) { + DrawMTileDitherClipBottom(pDecodeTo); + return; + } + + if (partial == PART_TRANS_LEFT) { + wt = nWTypeTable[gnPieceNum]; + if (wt == WTYPE_LEFT || wt == WTYPE_ULC) { + DrawMTileHalfDitherClipBottom(pDecodeTo, &sgLeftMask[31]); + return; + } + /* Preserve the assembly's unreachable WTYPE_LRC check. */ + } + + if (partial == PART_TRANS_RIGHT) { + wt = nWTypeTable[gnPieceNum]; + if (wt == WTYPE_RIGHT || wt == WTYPE_ULC) { + DrawMTileHalfDitherClipBottom(pDecodeTo, &sgRightMask[31]); + return; + } + /* Preserve the assembly's unreachable WTYPE_LRC check. */ + } + } + + DrawMTileNoTransClipBottom(pDecodeTo); +} + + void DrawBlankMTile(BYTE* pDecodeTo) +{ + BYTE* dst = pDecodeTo; + int edx = 30; + int ebx = 1; + uint32_t zero = 0; + + for (;;) { + int ecx; + dst += edx; + for (ecx = ebx; ecx != 0; ecx--) { + StoreLE32(dst, zero); + dst += 4; + } + dst += edx; + dst -= NBUFFW64; + if (edx == 0) { + break; + } + edx -= 2; + ebx++; + } + + edx = 2; + ebx = 15; + while (edx != 32) { + int ecx; + dst += edx; + for (ecx = ebx; ecx != 0; ecx--) { + StoreLE32(dst, zero); + dst += 4; + } + dst += edx; + dst -= NBUFFW64; + ebx--; + edx += 2; + } +} + +/* Keep private symbols referenced so aggressive compilers do not drop the + * data tables when this file is compiled into projects that inspect them while + * debugging or compare against the original assembly data segment. + */ +static SCROLL_UNUSED void ScrollPortKeepPrivateDataReferenced(void) +{ + volatile DWORD sink = 0; + sink ^= sgLineVal; + sink ^= sgCM; + sink ^= sgWT; + sink ^= (DWORD)(uintptr_t)sgT; + sink ^= (DWORD)(uintptr_t)sgMask; + sink ^= sgTimeLow ^ sgTimeHigh ^ sgLoopTime ^ sgUnrollTime; + sink ^= sgRightMask[0] ^ sgLeftMask[0] ^ sgFullMask[0]; + sink ^= sgDivBy3MulBy4[0] ^ TotalDataPerLineBottom[0] ^ TotalDataPerLineTop[0]; + (void)sink; +} diff --git a/Storm/ARCHIVE.BAT b/Storm/ARCHIVE.BAT new file mode 100644 index 0000000..a177e11 --- /dev/null +++ b/Storm/ARCHIVE.BAT @@ -0,0 +1,13 @@ +@echo off +if "%1"=="" goto usage +if "%2"=="" goto usage +goto start +:usage +echo Usage: ARCHIVE filename password +goto done +:start +cmd /c clean +pkzip32 -add -dir -max %1.zip * -excl=*.smk -excl=*.cod -excl=*.dsp -excl=*.dsw -excl=*.mak -excl=*.map +rename %1.zip %1.zip.enc +encrypt %1.zip.enc %2 +:done diff --git a/Storm/BIN/BATTLE.SNP b/Storm/BIN/BATTLE.SNP new file mode 100644 index 0000000..853dddf Binary files /dev/null and b/Storm/BIN/BATTLE.SNP differ diff --git a/Storm/BIN/BATTLED.SNP b/Storm/BIN/BATTLED.SNP new file mode 100644 index 0000000..55ea508 Binary files /dev/null and b/Storm/BIN/BATTLED.SNP differ diff --git a/Storm/BIN/SMACKW32.DLL b/Storm/BIN/SMACKW32.DLL new file mode 100644 index 0000000..02c7940 Binary files /dev/null and b/Storm/BIN/SMACKW32.DLL differ diff --git a/Storm/BIN/STANDARD.SNP b/Storm/BIN/STANDARD.SNP new file mode 100644 index 0000000..8e4dafb Binary files /dev/null and b/Storm/BIN/STANDARD.SNP differ diff --git a/Storm/BIN/STANDA~1.SNP b/Storm/BIN/STANDA~1.SNP new file mode 100644 index 0000000..5c685a9 Binary files /dev/null and b/Storm/BIN/STANDA~1.SNP differ diff --git a/Storm/BIN/STORM.DLL b/Storm/BIN/STORM.DLL new file mode 100644 index 0000000..c8295c3 Binary files /dev/null and b/Storm/BIN/STORM.DLL differ diff --git a/Storm/BIN/STORMD.DLL b/Storm/BIN/STORMD.DLL new file mode 100644 index 0000000..443ad7d Binary files /dev/null and b/Storm/BIN/STORMD.DLL differ diff --git a/Storm/CLEAN.BAT b/Storm/CLEAN.BAT new file mode 100644 index 0000000..eff2ed0 --- /dev/null +++ b/Storm/CLEAN.BAT @@ -0,0 +1,8 @@ +@echo off +if not exist bin\storm.dll goto done +locate /d bin\*.bak +locate /d help\*.fts +locate /d samples\*.aps *.bak *.ilk *.exp *.obj *.pch *.pdb *.res *.tmp a.* dump.* +locate /d source\*.aps *.bak *.ilk *.exp *.obj *.pch *.pdb *.res *.tmp a.* dump.* *.lib *.dll *.snp +if exist *.bak del *.bak +:done diff --git a/Storm/DOCS/C.BAT b/Storm/DOCS/C.BAT new file mode 100644 index 0000000..98f6497 --- /dev/null +++ b/Storm/DOCS/C.BAT @@ -0,0 +1,7 @@ +@echo off +if exist storm.hlp del storm.hlp +hc31 storm.hpj +if exist storm.ph del storm.ph +if exist *.bak del *.bak +if exist storm.hlp copy storm.hlp o:\help\storm.hlp /v +if exist storm.hlp start winhlp32 storm.hlp diff --git a/Storm/DOCS/CATEGO~1.RTF b/Storm/DOCS/CATEGO~1.RTF new file mode 100644 index 0000000..0ca6c98 --- /dev/null +++ b/Storm/DOCS/CATEGO~1.RTF @@ -0,0 +1,60 @@ +{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f16\froman\fcharset238\fprq2 Times New Roman CE;}{\f17\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f19\froman\fcharset161\fprq2 Times New Roman Greek;}{\f20\froman\fcharset162\fprq2 Times New Roman Tur;} +{\f21\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f28\fmodern\fcharset238\fprq1 Courier New CE;}{\f29\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f31\fmodern\fcharset161\fprq1 Courier New Greek;}{\f32\fmodern\fcharset162\fprq1 Courier New Tur;} +{\f33\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255; +\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\nowidctlpar\widctlpar\adjustright \fs20 \snext0 Normal;} +{\*\cs10 \additive Default Paragraph Font;}{\s15\nowidctlpar\widctlpar\adjustright \b\fs40 \sbasedon0 \snext16 API Title;}{\s16\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 API Description;}{\s17\nowidctlpar\widctlpar\adjustright \f2\fs22 +\sbasedon0 \snext17 API Function;}{\s18\nowidctlpar\widctlpar\adjustright \b \sbasedon0 \snext16 API Section;}{\s19\li720\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 API Parameter Description;}{\s20\nowidctlpar\widctlpar\adjustright \i +\sbasedon0 \snext19 API Parameter Name;}{\s21\nowidctlpar\widctlpar\adjustright \fs20 \sbasedon0 \snext21 footnote text;}{\*\cs22 \additive \super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien} +{\creatim\yr1997\mo3\dy21\hr17\min1}{\revtim\yr1997\mo3\dy21\hr18\min23}{\version5}{\edmins17}{\nofpages2}{\nofwords261}{\nofchars1490}{\*\company Blizzard Entertainment}{\nofcharsws0}{\vern71}} +\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind1\viewscale100 \fet0\sectd \linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3 +\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}} +{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain +\s15\keepn\nowidctlpar\widctlpar\adjustright \b\fs40 {\cs22\super ${\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super $}{ CategoryProc}}#{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super #}{ +CategoryProc}}K{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super K}{ CategoryProc}}}{ CategoryProc +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }{\b\i CategoryProc() is a placeholder for an application-defined function name.}{ +\par +\par This function is called by from SNetSelectGame() prior to enumerating games, and optionally in response to a user request, so that the application can prompt the user about which categories of games he would like to display. +\par +\par }\pard\plain \s17\nowidctlpar\widctlpar\adjustright \f2\fs22 {BOOL CALLBACK SelectCategoryProc ( +\par \tab BOOL\tab \tab \tab \tab userinitiated, +\par \tab SNETPROGRAMDATAPTR\tab programdata, +\par \tab SNETPLAYERDATAPTR\tab playerdata, +\par \tab SNETUIDATAPTR\tab \tab interfacedata, +\par \tab SNETVERSIONDATAPTR\tab versiondata, +\par \tab DWORD *\tab \tab \tab categorybits, +\par \tab DWORD *\tab \tab \tab categorymask +\par ); +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Parameters +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {userinitiated +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A boolean value spec +ifying why the callback function is being called. If this value is FALSE, the function is being called automatically prior to bringing up the list of games. If this value is TRUE, the function is being called in response to a user request. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {programdata +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A structure containing the program data that was passed to SNetSelectGame(). +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {playerdata +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A structure containing the player data that was passed to SNetSelectGame(). +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {interfacedata +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A structure containing the interface data that was passed to SNetSelectGame(), modified as necessary to ensure that the dialog that the create callback displays fits with the network provider +\rquote s interface. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {versiondata +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A structure containing the version data that was passed to SNetSelectGame(). +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {Categorybits +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A value returned by the callback function specifying which categories of games the user is interested in joining. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {categorymask +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A value returned by the callback function specifying which bits must match between the value of }{\i categorybits}{ and the game\rquote s category bits for a game to be enumerated. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Return Value +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par The application should return TRUE to cause game enumeration to begin, or FALSE to abort the call to SNetSelectGame(). +\par +\par }} \ No newline at end of file diff --git a/Storm/DOCS/CHECKA~1.RTF b/Storm/DOCS/CHECKA~1.RTF new file mode 100644 index 0000000..d68a1ed --- /dev/null +++ b/Storm/DOCS/CHECKA~1.RTF @@ -0,0 +1,62 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo11\dy28\hr2\min32}{\version3} +{\edmins34}{\nofpages2}{\nofwords249}{\nofchars1420}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} CheckAuthProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} CheckAuthProc}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} CheckAuthProc}} CheckAuthProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i CheckAuthProc() is a placeholder for an application-defined function name.} +\par +\par \pard \s16\widctlpar This function is called by the current network provider to determine whether the active user is authorized to join a game or chat channel. +\par \pard \s16\widctlpar +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK CheckAuthProc ( +\par \tab DWORD\tab \tab itemtype, +\par \tab LPCSTR\tab playername, +\par \tab LPCSTR\tab playerdescription, +\par \tab DWORD\tab \tab userflags, +\par \tab LPCSTR\tab itemdescription, +\par \tab LPSTR\tab \tab errorbuffer, +\par \tab DWORD\tab \tab errorsize +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 itemtype +\par \pard\plain \s19\li720\widctlpar \f4 An identifier which tells whether the name and description describe a game or a player. It can be one of the following values: +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx4140\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell \pard \s19\widctlpar\intbl {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4140\cellx7812 \pard\plain +\s19\widctlpar\intbl \f4 SNET_AUTHTYPE_GAME\cell \pard \s19\widctlpar\intbl Item is a game.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4140\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_AUTHTYPE_CHANNEL\cell +\pard \s19\widctlpar\intbl Item is a chat channel.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playername +\par \pard\plain \s19\li720\widctlpar \f4 The name of the player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerdescription +\par \pard\plain \s19\li720\widctlpar \f4 An application defined string containing information about the player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 userflags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags for the player. The following flags are currently defined: +\par \pard\plain \s16\widctlpar \f4 \tab +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNE +T_DDPF_BLIZZARD\cell Player is a Blizzard employee\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_DDPF_MODERATOR\cell Player is a channel moderator\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain +\s19\widctlpar\intbl \f4 SNET_DDPF_SPEAKER\cell Player is a speaker for a special event\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_DDPF_SYSOP\cell Player is a sysop of the selected gaming service\cell +\pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_DDPF_SQUELCHED\cell Player has been squelched by the local user\cell \pard\plain \widctlpar\intbl \f4\fs20 \row +\pard\plain \s16\widctlpar \f4 +\par +\par \pard\plain \s20\widctlpar \i\f4 itemdescription +\par \pard\plain \s19\li720\widctlpar \f4 If {\i itemtype} is SNET_AUTHTYPE_GAME, this field contains the game description. If {\i itemtype} is SNET_AUTHTYPE_CHANNEL, this field contains the channel name. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 errorbuffer +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a string buffer which the application fills in with an error message in the case that authorization is not granted. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 errorsize +\par \pard\plain \s19\li720\widctlpar \f4 The size, in characters, of the string buffer. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par \pard \s16\widctlpar This function should return TRUE if the user is authorized to join the game or channel, or FALSE if the function fails or the user is not authorized. +\par \pard \s16\widctlpar +\par } \ No newline at end of file diff --git a/Storm/DOCS/CREATE~1.RTF b/Storm/DOCS/CREATE~1.RTF new file mode 100644 index 0000000..8c58d6f --- /dev/null +++ b/Storm/DOCS/CREATE~1.RTF @@ -0,0 +1,52 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy21\hr17\min2}{\version4} +{\edmins8}{\nofpages2}{\nofwords261}{\nofchars1490}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} CreateProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} CreateProc}K{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super K} CreateProc}} CreateProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i CreateProc() is a placeholder for an application-defined function name.} +\par +\par This function is called by +from SNetSelectGame() if the user has decided to create a new game. The create callback is responsible for display a dialog to the user to request game information like the game name and difficulty, and then calling SNetCreateGame(). +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK CreateProc ( +\par \tab SNETCREATEDATAPTR\tab createdata, +\par \tab SNETPROGRAMDATAPTR\tab programdata, +\par \tab SNETPLAYERDATAPTR\tab playerdata, +\par \tab SNETUIDATAPTR\tab \tab interfacedata, +\par \tab SNETVERSIONDATAPTR\tab versiondata, +\par \tab DWORD\tab *\tab \tab \tab playerid +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 createdata +\par \pard\plain \s19\li720\widctlpar \f4 A structure provided by the service provider containing data that the application will need to create the game. When the data in this structure conflicts with the application\rquote +s own data, the application should use the data in the structure. For example, the maxplayers field may be set lower than the application\rquote s maximum number of players if the network provider does not support the application\rquote +s maximum number of players. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 programdata +\par \pard\plain \s19\li720\widctlpar \f4 A structure containing the program data that was passed to SNetSelectGame(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerdata +\par \pard\plain \s19\li720\widctlpar \f4 A structure containing the player data that was passed to SNetSelectGame(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 interfacedata +\par \pard\plain \s19\li720\widctlpar \f4 A structure containing the interface data that was passed to SNetSelectGame(), modified as necessary to ensure that the dialog that the create callback displays fits with the network provider\rquote s interface. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 versiondata +\par \pard\plain \s19\li720\widctlpar \f4 A structure containing the version data that was passed to SNetSelectGame(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerid +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a DWORD which the function should fill in with the player ID assigned in the call to SNetCreateGame(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par The application should return TRUE if it called SNetCreateGame() and the call was successful. It should return FALSE if the game was not created for any reason. +\par +\par } \ No newline at end of file diff --git a/Storm/DOCS/DRAWDE~1.RTF b/Storm/DOCS/DRAWDE~1.RTF new file mode 100644 index 0000000..834d73b --- /dev/null +++ b/Storm/DOCS/DRAWDE~1.RTF @@ -0,0 +1,69 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo11\dy22\min44}{\version2} +{\edmins1}{\nofpages2}{\nofwords310}{\nofchars1768}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} DrawDescProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} DrawDescProc}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} DrawDescProc}} DrawDescProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i DrawDescProc() is a placeholder for an application-defined function name.} +\par +\par This function is called by Storm or the current network provider when it needs to draw a game or player description. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK DrawDescProc ( +\par \tab DWORD\tab \tab \tab \tab providerid, +\par \tab DWORD\tab \tab \tab \tab itemtype, +\par \tab LPCSTR\tab \tab \tab itemname, +\par \tab LPCSTR\tab \tab \tab itemdescription, +\par \tab DWORD\tab \tab \tab \tab itemflags, +\par \tab DWORD\tab \tab \tab \tab itemcreationtime, +\par \tab DWORD\tab \tab \tab \tab drawflags, +\par \tab LPDRAWITEMSTRUCT\tab drawdata +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the network provider which is making the request. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 itemtype +\par \pard\plain \s19\li720\widctlpar \f4 An identifier which tells whether the name and description describe a game or a player. It can be one of the following values: +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_DRAWTYPE_GAME\cell Item is a game\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_DRAWTYPE_PLAYER\cell Item is a player\cell \pard\plain \widctlpar\intbl +\f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 itemname +\par \pard\plain \s19\li720\widctlpar \f4 The name of the game or player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 itemdescription +\par \pard\plain \s19\li720\widctlpar \f4 The description of the game or player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 itemflags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags for the game or player. The following flags are currently defined for players: +\par \pard\plain \s16\widctlpar \f4 \tab +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_DDPF_BLIZZARD\cell Player is a Blizzard employee\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_DDPF_MODERATOR\cell Player is a channel moderator\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain +\s19\widctlpar\intbl \f4 SNET_DDPF_SPEAKER\cell Player is a speaker for a special event\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_DDPF_SYSOP\cell Player is a sysop of the selected gaming service\cell +\pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_DDPF_SQUELCHED\cell Player has been squelched by the local user\cell \pard\plain \widctlpar\intbl \f4\fs20 \row +\pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 itemcreationtime +\par \pard\plain \s19\li720\widctlpar \f4 The creation time of the game, expressed as the number of seconds since midnight, January 1, 1970 UTC. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 drawflags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags defining how the item should be drawn. The following flags are defined: +\par +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard \s19\widctlpar\intbl {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_DDF_INCLUDENAME\cell The callback function should draw the game name as well as the description. If this flag is not specified then the game is already visible elsewhere on the screen, and only the description needs to be drawn.\cell \pard\plain +\widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_DDF_MULTILINE\cell The area for the description is large enough to include more than one line of text.\cell \pard\plain +\widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 drawdata +\par \pard\plain \s19\li720\widctlpar \f4 A structure containing information about the output device. This includes the device context, and the rectangle (in client coordinates) to which the application should bound its output. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function should return TRUE if the description was successfully drawn, or FALSE if an error occurred. +\par +\par } \ No newline at end of file diff --git a/Storm/DOCS/ENUMGA~1.RTF b/Storm/DOCS/ENUMGA~1.RTF new file mode 100644 index 0000000..bfd5149 --- /dev/null +++ b/Storm/DOCS/ENUMGA~1.RTF @@ -0,0 +1,36 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr15\min4}{\version2} +{\edmins3}{\nofpages1}{\nofwords82}{\nofchars472}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} EnumGamesProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} EnumGamesProc}} {\cs22\super K +{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} EnumGamesProc}} EnumGamesProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i EnumGamesProc() is a placeholder for an application-defined function name.} +\par +\par This function is called by SNetEnumGames() once for each active game that matches the program and version IDs of the application. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK EnumGamesProc ( +\par \tab DWORD\tab \tab gameid, +\par \tab LPCSTR\tab gamename, +\par \tab LPCSTR\tab gamedescription +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 gameid +\par \pard\plain \s19\li720\widctlpar \f4 Unique identifier of the game. Pass this value to SNetJoinGame(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 gamename +\par \pard\plain \s19\li720\widctlpar \f4 The name of the game. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 gamedescription +\par \pard\plain \s19\li720\widctlpar \f4 A description of the game. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function should return TRUE to continue enumeration, or FALSE to stop. +\par } \ No newline at end of file diff --git a/Storm/DOCS/ENUMPR~1.RTF b/Storm/DOCS/ENUMPR~1.RTF new file mode 100644 index 0000000..0d4ff29 --- /dev/null +++ b/Storm/DOCS/ENUMPR~1.RTF @@ -0,0 +1,40 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr15\min5}{\version3} +{\edmins1}{\nofpages1}{\nofwords105}{\nofchars602}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} EnumProvidersProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} EnumProvidersProc}K +{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} EnumProvidersProc}} EnumProvidersProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i EnumProvidersProc() is a placeholder for an application-defined function name.} +\par +\par This function is called by SNetEnumProviders() once for each network provider installed on the system. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK EnumProvidersProc ( +\par \tab DWORD\tab \tab \tab providerid, +\par \tab LPCSTR\tab \tab name, +\par \tab LPCSTR\tab \tab requirements, +\par \tab SNETCAPSPTR\tab caps +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The unique ID of the provider. Pass this value to SNetInitializeProvider(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 name +\par \pard\plain \s19\li720\widctlpar \f4 The name of the provider. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 requirements +\par \pard\plain \s19\li720\widctlpar \f4 A string describing the requirements for using this provider, such as \ldblquote two computers connected by a serial cable and null-modem.\rdblquote +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 caps +\par \pard\plain \s19\li720\widctlpar \f4 The capabilities of this provider. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function should return TRUE to continue enumeration, or FALSE to stop. +\par } \ No newline at end of file diff --git a/Storm/DOCS/EVENTP~1.RTF b/Storm/DOCS/EVENTP~1.RTF new file mode 100644 index 0000000..0720219 --- /dev/null +++ b/Storm/DOCS/EVENTP~1.RTF @@ -0,0 +1,28 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr15\min5}{\version2} +{\edmins0}{\nofpages1}{\nofwords77}{\nofchars439}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} EventProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} EventProc}K{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super K} EventProc}} EventProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i EventProc() is a placeholder for an application-defined function name.} +\par +\par This function is called to notify the application of a network event. Network events are queued up, and only delivered to the application when it calls SNetReceiveMessage() or SNetReceiveTurns(). +\par +\par \pard\plain \s17\widctlpar \f11\fs22 void CALLBACK EventProc ( +\par \tab SNETEVENTPTR event +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 eventdata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure describing the event, and containing the ID of the player who caused the event to be generated. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function does not return a value. +\par } \ No newline at end of file diff --git a/Storm/DOCS/GETART~1.RTF b/Storm/DOCS/GETART~1.RTF new file mode 100644 index 0000000..95481f8 --- /dev/null +++ b/Storm/DOCS/GETART~1.RTF @@ -0,0 +1,59 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr15\min5}{\version2} +{\edmins0}{\nofpages2}{\nofwords290}{\nofchars1656}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} GetArtProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} GetArtProc}K{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super K} GetArtProc}} GetArtProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i GetArtProc() is a placeholder for an application-defined function name.} +\par +\par This function is called by Storm or the current network provider to get artwork necessary for displaying a user interface screen. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK GetArtProc ( +\par \tab DWORD\tab \tab \tab providerid, +\par \tab DWORD\tab \tab \tab artid, +\par \tab LPPALETTEENTRY\tab palette, +\par \tab LPBYTE\tab \tab buffer, +\par \tab DWORD\tab \tab \tab buffersize, +\par \tab int\tab \tab \tab *width, +\par \tab int\tab \tab \tab *height, +\par \tab int\tab \tab \tab *bitdepth +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the network provider which is requesting the artwork, or zero if the artwork is being requested for a screen which is not provider specific. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 artid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the artwork being requested. The standard artwork IDs are shown below. Network providers can define their own IDs, above 0x80000000, for artwork that is specific to the provider. +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx4230\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4230\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_ART_BACKGROUND\cell The background bitmap for the dialog.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4230\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_ART_BUTTONTEXTURE\cell +The texture which is tiled over buttons in the dialog.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 palette +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to an array of palette entries, to be filled in by the function. This parameter can be NULL if the provider doesn\rquote t need to load a palette. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 buffer +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a buffer where the function should copy the bitmap data. This parameter can be NULL if the provider doesn\rquote t need the bitmap data, or if it is only querying the bitmap dimensions. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 buffersize +\par \pard\plain \s19\li720\widctlpar \f4 The size of the buffer pointed to by {\i buffer}. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 width +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a variable which the function should fill in with the width of the bitmap. This parameter can be NULL if the provider doesn\rquote t need the bitmap width. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 height +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a variable which the function should fill in with the height of the bitmap. This parameter can be NULL if the provider doesn\rquote t need the bitmap height. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 bitdepth +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a variable which the function should fill in with the number of bits per pixel in the bitmap. This parameter can be NULL if the provider doesn\rquote t need the bitmap pixel depth. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function should return TRUE if the picture was successfully loaded, or FALSE if an error occurred. +\par } \ No newline at end of file diff --git a/Storm/DOCS/GETDAT~1.RTF b/Storm/DOCS/GETDAT~1.RTF new file mode 100644 index 0000000..3600552 --- /dev/null +++ b/Storm/DOCS/GETDAT~1.RTF @@ -0,0 +1,44 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo11\dy22\hr18\min12}{\version3} +{\edmins6}{\nofpages1}{\nofwords172}{\nofchars981}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} GetDataProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} GetDataProc}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} GetDataProc}} GetDataProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i GetDataProc() is a placeholder for an application-defined function name.} +\par +\par This function can be called by a network provider to get data other than artwork from the current application. To get artwork, a network provider calls GetArtProc(). +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK GetDataProc ( +\par \tab DWORD\tab \tab \tab providerid, +\par \tab DWORD\tab \tab \tab dataid, +\par \tab LPVOID\tab \tab buffer, +\par \tab DWORD\tab \tab \tab buffersize, +\par \tab DWORD\tab \tab \tab *bytesused +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the network provider which is requesting the artwork. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 dataid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the data item being requested. There are no predefined IDs. Network providers can define their own IDs, above 0x80000000, for data that is specific to the provider. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 buffer +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a buffer where the function should copy the data. This parameter can be NULL if the provider is only querying the data size. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 buffersize +\par \pard\plain \s19\li720\widctlpar \f4 The size of the buffer pointed to by {\i buffer}. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 bytesused +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a variable which the function should fill in with the number of bytes written to the buffer. If the buffer is NULL, the function should fill in the total number of bytes in the data item. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function should return TRUE if the data ID is valid and can be provided, or FALSE otherwise. +\par } \ No newline at end of file diff --git a/Storm/DOCS/MESSAG~1.RTF b/Storm/DOCS/MESSAG~1.RTF new file mode 100644 index 0000000..5dd52d2 --- /dev/null +++ b/Storm/DOCS/MESSAG~1.RTF @@ -0,0 +1,59 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy21\hr11\min40}{\version5} +{\edmins11}{\nofpages2}{\nofwords255}{\nofchars1458}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} MessageBoxProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} MessageBoxProc}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} MessageBoxProc}} MessageBoxProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i MessageBoxProc() is a placeholder for an application-defined function name.} +\par +\par \pard \s16\widctlpar This function is called by Storm or the current network provider when it needs to display a message box. +\par \pard \s16\widctlpar +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK MessageBoxProc ( +\par \tab HWND\tab \tab parentwindow, +\par \tab LPCSTR\tab text, +\par \tab LPCSTR\tab caption, +\par \tab UINT\tab \tab type +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 parentwindow +\par \pard\plain \s19\li720\widctlpar \f4 A handle to the window that the message box should use as its parent. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 text +\par \pard\plain \s19\li720\widctlpar \f4 The text of the message. The procedure should dynamically scale the message box in order to fit the entire text. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 caption +\par \pard\plain \s19\li720\widctlpar \f4 The caption, which should be used as the title of the message box window. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 type +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags which indicate the type of the message box. The following constants are allowed: +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell \pard \s19\widctlpar\intbl {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain +\s19\widctlpar\intbl \f4 MB_OK\cell The message box contains one push button: OK. This is the default.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 MB_OKCANCEL\cell The message box contains tw +o push buttons: OK and Cancel.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 MB_RETRYCANCEL\cell The message box contains two push buttons: Retry and Cancel.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row +\pard\plain \s19\widctlpar\intbl \f4 MB_YESNO\cell The message box contains two push buttons: Yes and No.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 MB_YESNOCANCEL\cell +The message box contains three push buttons: Yes, No, and Cancel.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 MB_DEFBUTTON1\cell \pard \s19\widctlpar\intbl +The first button is the default button. This is the default.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 MB_DEFBUTTON2\cell The second button is the default button.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row +\trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 MB_DEFBUTTON3\cell \pard \s19\widctlpar\intbl The third button is the default button.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 + +\par \pard\plain \s20\widctlpar \i\f4 flags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags specifying how the sound should be played. Use the SND_* constants defined in Windows.h. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par \pard \s16\widctlpar The return value is FALSE if the procedure is not able to display the message box. +\par +\par Otherwise, the return value is one of the following item values returned by the dialog box: +\par +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 IDOK\cell The OK button was selected.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl +\f4 IDCANCEL\cell The Cancel button was selected.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 IDYES\cell The Yes button was selected.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain +\s19\widctlpar\intbl \f4 IDNO\cell The No button was selected.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 IDRETRY\cell \pard \s19\widctlpar\intbl +The Retry button was selected.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard \s16\widctlpar +\par } \ No newline at end of file diff --git a/Storm/DOCS/PLAYSO~1.RTF b/Storm/DOCS/PLAYSO~1.RTF new file mode 100644 index 0000000..10aa335 --- /dev/null +++ b/Storm/DOCS/PLAYSO~1.RTF @@ -0,0 +1,40 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy21\hr11\min30}{\version3} +{\edmins5}{\nofpages1}{\nofwords145}{\nofchars829}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} PlaySoundProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} PlaySoundProc}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} PlaySoundProc}} PlaySoundProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i PlaySoundProc() is a placeholder for an application-defined function name.} +\par +\par This function is called by Storm or the current network provider when it needs to play a sound effect. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK PlaySoundProc ( +\par \tab DWORD\tab \tab providerid, +\par \tab DWORD\tab \tab soundid, +\par \tab DWORD\tab \tab flags +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the network provider which is making the request. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 soundid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the requested sound effect. The standard IDs are shown below. Network providers can define their own IDs, above 0x80000000, for sound effects that are specific to the provider. +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_SND_CHANGEFOCUS\cell A sound to indicate that the user has changed to focus to a new menu or list-box item.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_SND_SELECTITEM\cell A sound to indicate that the user has selected the current item.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 flags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags specifying how the sound should be played. Use the SND_* constants defined in Windows.h. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function should return TRUE if the sound was successfully played, or FALSE if an error occurred. +\par +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETCAPS.RTF b/Storm/DOCS/SNETCAPS.RTF new file mode 100644 index 0000000..6539a3f --- /dev/null +++ b/Storm/DOCS/SNETCAPS.RTF @@ -0,0 +1,54 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo11\dy13\hr23\min45}{\version2} +{\edmins1}{\nofpages2}{\nofwords185}{\nofchars1060}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNETCAPS}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNETCAPS}K{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super K} SNETCAPS}} SNETCAPS +\par \pard\plain \s16\widctlpar \f4 +\par The SNETCAPS structure contains capabilities for a network provider or a player. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 typedef struct _SNETCAPS \{ +\par \tab DWORD\tab \tab size; +\par \tab DWORD\tab \tab flags; +\par \tab DWORD\tab \tab maxmessagesize; +\par \tab DWORD\tab \tab maxqueuesize; +\par \tab DWORD\tab \tab maxplayers; +\par \tab DWORD\tab \tab bytessec; +\par \tab DWORD\tab \tab latencyms; +\par \tab DWORD\tab \tab defaultturnssec; +\par \tab DWORD\tab \tab defaultturnsintransit; +\par \} SNETCAPS, *SNETCAPSPTR; +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Members +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 size +\par \pard\plain \s19\li720\widctlpar \f4 The size of the structure, in bytes. Must be filled in by the application. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 flags +\par \pard\plain \s19\li720\widctlpar \f4 Network capability flags. No flags are currently defined. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 maxmessagesize +\par \pard\plain \s19\li720\widctlpar \f4 The maximum size, in bytes, of a message or turn that can be sent using this network provider. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 maxqueuesize +\par \pard\plain \s19\li720\widctlpar \f4 The maximum size of the outgoing message queue. This field is only meaningful if the network provider makes use of Microsoft DirectPlay. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 maxplayers +\par \pard\plain \s19\li720\widctlpar \f4 The maximum number of players supported by this network provider. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 bytessec +\par \pard\plain \s19\li720\widctlpar \f4 The expected bandwidth of the communications medium, expressed in bytes per second. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 latencyms +\par \pard\plain \s19\li720\widctlpar \f4 The expected latency of the communications medium, expressed as the number of milliseconds for a round-trip transmission. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 defaultturnssec +\par \pard\plain \s19\li720\widctlpar \f4 The recommended number of turns per second for this network provider. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 defaultturnsintransit +\par \pard\plain \s19\li720\widctlpar \f4 The recommended number of turns that the application should maintain in transit when using this network provider. +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETCR~1.RTF b/Storm/DOCS/SNETCR~1.RTF new file mode 100644 index 0000000..e3e7bbe --- /dev/null +++ b/Storm/DOCS/SNETCR~1.RTF @@ -0,0 +1,37 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy21\hr16\min49}{\version2} +{\edmins0}{\nofpages1}{\nofwords126}{\nofchars719}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNETCREATEDATA}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNETCREATEDATA}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNETCREATEDATA}} SNETCREATEDATA +\par \pard\plain \s16\widctlpar \f4 +\par The SNETCREATEDATA structure is used in the create game callback function to communicate information about the current provider\rquote s abilities. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 typedef struct _SNETCREATEDATA \{ +\par \tab DWORD\tab \tab size; +\par \tab DWORD\tab \tab providerid; +\par \tab DWORD\tab \tab maxplayers; +\par \tab DWORD\tab \tab createflags; +\par \} SNETCREATEDATA, *SNETCREATEDATAPTR; +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Members +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 size +\par \pard\plain \s19\li720\widctlpar \f4 The size of the structure, in bytes. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the currently selected provider. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 maxplayers +\par \pard\plain \s19\li720\widctlpar \f4 The maximum number of players that can join the game. This value is the minimum of the maximum number of players the application supports and the maximum number of players the provider supports. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 createflags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags specifying what creation options are available. The following flags are defined: +\par +\par \trowd \trgaph108\trleft612 \cellx4680\cellx7812 \pard \s19\widctlpar\intbl {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4680\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_CF_ALLOWPRIVATEGAMES\cell The creation callback function should allow the user the opportunity to create a private game.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETCR~2.RTF b/Storm/DOCS/SNETCR~2.RTF new file mode 100644 index 0000000..0463103 --- /dev/null +++ b/Storm/DOCS/SNETCR~2.RTF @@ -0,0 +1,85 @@ +{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f16\froman\fcharset238\fprq2 Times New Roman CE;}{\f17\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f19\froman\fcharset161\fprq2 Times New Roman Greek;} +{\f20\froman\fcharset162\fprq2 Times New Roman Tur;}{\f21\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f28\fmodern\fcharset238\fprq1 Courier New CE;}{\f29\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f31\fmodern\fcharset161\fprq1 Courier New Greek;} +{\f32\fmodern\fcharset162\fprq1 Courier New Tur;}{\f33\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0; +\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{ +\nowidctlpar\widctlpar\adjustright \fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\nowidctlpar\widctlpar\adjustright \b\fs40 \sbasedon0 \snext16 API Title;}{\s16\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 +API Description;}{\s17\nowidctlpar\widctlpar\adjustright \f2\fs22 \sbasedon0 \snext17 API Function;}{\s18\nowidctlpar\widctlpar\adjustright \b \sbasedon0 \snext16 API Section;}{\s19\li720\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 +API Parameter Description;}{\s20\nowidctlpar\widctlpar\adjustright \i \sbasedon0 \snext19 API Parameter Name;}{\s21\nowidctlpar\widctlpar\adjustright \fs20 \sbasedon0 \snext21 footnote text;}{\*\cs22 \additive \super \sbasedon10 footnote reference;}} +{\*\listtable{\list\listtemplateid-1\listsimple{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'01*;}{\levelnumbers;}}{\listname ;}\listid-2}}{\*\listoverridetable{\listoverride\listid-2 +\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent360{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360 }}\ls1}}{\info{\title SNetCreateGame} +{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1997\mo3\dy21\hr16\min55}{\version3}{\edmins5}{\nofpages2}{\nofwords409}{\nofchars2332}{\*\company Blizzard Entertainment}{\nofcharsws0}{\vern71}} +\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind1\viewscale100 \fet0\sectd \linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3 +\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}} +{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain +\s15\keepn\nowidctlpar\widctlpar\adjustright \b\fs40 {\cs22\super ${\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super $}{ SNetCreateGame}}#{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super #}{ + SNetCreateGame}}K{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super K}{ SNetCreateGame}}}{ SNetCreateGame +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par Creates a new network game using the currently selected network provider, and adds the local player as the game master. The game master is always player number one. +\par +\par Rather than calling this function manually, an application will generally call SNetSelectGame() to present the user with a list of games and allow him to join a game or create a new one. +\par +\par }\pard\plain \s17\nowidctlpar\widctlpar\adjustright \f2\fs22 {BOOL SNetCreateGame ( +\par \tab LPCSTR\tab gamename, +\par \tab LPCSTR\tab gamepassword, +\par \tab LPCSTR\tab gamedescription, +\par \tab DWORD\tab \tab gamecategorybits, +\par \tab LPVOID\tab initdata, +\par \tab DWORD\tab \tab initdatabytes, +\par \tab DWORD\tab \tab maxplayers, +\par \tab LPCSTR\tab playername, +\par \tab LPCSTR\tab playerdescription, +\par \tab DWORD\tab \tab *playerid +\par ); +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Parameters +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {gamename +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The name of the game being created, as specified by the player. For example, \ldblquote Bob\rquote s Game\rdblquote . +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {gamepassword +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A password for the game. If the password is not blank, then the game + is considered private. It does not show up on lists of games, and players cannot join the game without knowing the password. Passwords are not case sensitive. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {gamedescription +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A description of the game. This can be generated by the program, and cont +ain information about the game options. On joining systems, the options strings may be simply displayed as text, or may be decoded by the game into a graphical or iconic representation of game options, such as whether fog of war is in effect. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {gamecategorybits +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A set of bits describing the categories to which this game belongs. Other systems can either enumerate all games, or enumerate only games which belong to certain categories. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {initdata +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A +pointer to application-specific initialization data. This data is sent to all joining players. The application receives it on the joining side through the SNET_EVENT_INITDATA callback, which it is guaranteed to get on its first call to SNetReceiveMessag +e() or SNetReceiveTurns() after joining. The maximum size of the initialization data is equal to the maximum message size for the current network provider. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {initdatabytes +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The number of bytes in the application-specific initialization data. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {maxplayers +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The +maximum number of players which will be allowed to join this game. This number must be less than or equal to the maximum number of players that was set during the call to SNetInitializeProvider(). +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {playername +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The name of the local player. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {playerdescription +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A description of the local player. This can be generated by the program, and contain information such as the player\rquote +s character class or level. On joining systems, it may be decoded into a graphical or iconic representation of the player. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {playerid +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The ID that is assigned to the player, if creating the game is successful. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Return Value +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \s16\fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {No network provider has been initialized + +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}No game name or description is specified +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}The maximum number of players is out of range +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}No player name or description is specified +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}No variable is given to receive the player ID +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}The system is out of memory +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}The network provider uses a server, and the server is unable to process the request +\par }\pard\plain \nowidctlpar\widctlpar\adjustright \fs20 { +\par }} diff --git a/Storm/DOCS/SNETDE~1.RTF b/Storm/DOCS/SNETDE~1.RTF new file mode 100644 index 0000000..ddd09ca --- /dev/null +++ b/Storm/DOCS/SNETDE~1.RTF @@ -0,0 +1,25 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\widctlpar \f4\fs20 \sbasedon0\snext19 footnote text;}{\*\cs20 \additive\super \sbasedon10 +footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min19}{\revtim\yr1996\mo10\dy3\hr15\min6}{\version2}{\edmins0}{\nofpages1}{\nofwords53}{\nofchars307}{\*\company Blizzard Entertainment}{\vern57431}} +\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}} +{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs20\super ${\footnote \pard\plain +\s19\widctlpar \f4\fs20 {\cs20\super $} SNetDestroy}#{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super #} SNetDestroy}K{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super K} SNetDestroy}} SNetDestroy +\par \pard\plain \s16\widctlpar \f4 +\par Closes all active games, uninitializes the network provider, and frees all memory used by this module. +\par +\par Normally, a program should call StormDestroy() once at the end of the program, rather than calling the individual destroy functions. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetDestroy (); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par None. +\par +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}This function returns TRUE for success or FALSE for failure. +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETEN~1.RTF b/Storm/DOCS/SNETEN~1.RTF new file mode 100644 index 0000000..94bba38 --- /dev/null +++ b/Storm/DOCS/SNETEN~1.RTF @@ -0,0 +1,60 @@ +{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f16\froman\fcharset238\fprq2 Times New Roman CE;}{\f17\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f19\froman\fcharset161\fprq2 Times New Roman Greek;} +{\f20\froman\fcharset162\fprq2 Times New Roman Tur;}{\f21\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f28\fmodern\fcharset238\fprq1 Courier New CE;}{\f29\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f31\fmodern\fcharset161\fprq1 Courier New Greek;} +{\f32\fmodern\fcharset162\fprq1 Courier New Tur;}{\f33\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0; +\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{ +\nowidctlpar\widctlpar\adjustright \fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\nowidctlpar\widctlpar\adjustright \b\fs40 \sbasedon0 \snext16 API Title;}{\s16\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 +API Description;}{\s17\nowidctlpar\widctlpar\adjustright \f2\fs22 \sbasedon0 \snext17 API Function;}{\s18\nowidctlpar\widctlpar\adjustright \b \sbasedon0 \snext16 API Section;}{\s19\li720\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 +API Parameter Description;}{\s20\nowidctlpar\widctlpar\adjustright \i \sbasedon0 \snext19 API Parameter Name;}{\s21\li720\nowidctlpar\widctlpar\adjustright \f2 \sbasedon19 \snext21 API Callback;}{\s22\nowidctlpar\widctlpar\adjustright \fs20 +\sbasedon0 \snext22 footnote text;}{\*\cs23 \additive \super \sbasedon10 footnote reference;}}{\*\listtable{\list\listtemplateid-1\listsimple{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'01*;}{\levelnumbers +;}}{\listname ;}\listid-2}}{\*\listoverridetable{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent360{\leveltext\'01\u-3913 ?;}{\levelnumbers;} +\f3\fbias0 \fi-360\li360 }}\ls1}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min19}{\revtim\yr1997\mo3\dy21\hr17}{\version3}{\edmins5}{\nofpages2}{\nofwords256}{\nofchars1462}{\*\company Blizzard Entertainment} +{\nofcharsws1795}{\vern71}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind1\viewscale100 \fet0\sectd \linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang +{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain +\s15\keepn\nowidctlpar\widctlpar\adjustright \b\fs40 {\cs23\super ${\footnote \pard\plain \s22\nowidctlpar\widctlpar\adjustright \fs20 {\cs23\super $}{ SNetEnumGames}}#{\footnote \pard\plain \s22\nowidctlpar\widctlpar\adjustright \fs20 {\cs23\super #}{ + SNetEnumGames}}K{\footnote \pard\plain \s22\nowidctlpar\widctlpar\adjustright \fs20 {\cs23\super K}{ SNetEnumGames}}}{ SNetEnumGames +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par Enumerates all games available on the current network provider which match the program and version IDs. The callback function you provide is called once for each matching game. +\par +\par Some network providers can take a significant amount of time to find all active games (for example, one second). Instead of blocking for this duration, the function returns only the games it current +ly knows about, and then gives you a hint about when you should call it back to receive a more complete list. +\par +\par Rather than calling this function manually, an application will generally call SNetSelectGame() to present the user with a list of games and allow him to join a game or create a new one. +\par +\par }\pard\plain \s17\nowidctlpar\widctlpar\adjustright \f2\fs22 {BOOL SNetEnumGames ( +\par \tab DWORD\tab \tab \tab \tab categorybits, +\par \tab DWORD\tab \tab \tab \tab categorymask, +\par \tab SNETENUMGAMESPROC\tab callback, +\par \tab DWORD\tab \tab \tab \tab *hintnextcall +\par ); +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Parameters +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {categorybits +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A set of bits that specify which categories of games the application is interested in enumerating. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {categorymask +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A mask specifying which categories must match in order for a game to be enumerated. The following logical statement shows how }{\i categorybits}{ and }{\i categorymask}{ are used to select games: + +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard \s16\li1440\nowidctlpar\widctlpar\adjustright {if (categorybits AND categorymask) +\par equals (gamecategorybits AND categorymask) +\par then enumerate game +\par }\pard \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {callback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The application\rquote s callback function. See EnumGamesProc() for a description. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {hintnextcall +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The time that the application should wait before calling this function again, in milliseconds. If this number is zero, there is no need to call the function again. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Return Value +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \s16\fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {No network provider has been initialized + +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}No callback function is provided +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}The system is out of memory +\par {\pntext\pard\plain\s16 \f3 \loch\af3\dbch\af0\hich\f3 \'b7\tab}The network provider is unable to retrieve a list of games +\par }\pard\plain \nowidctlpar\widctlpar\adjustright \fs20 { +\par }} \ No newline at end of file diff --git a/Storm/DOCS/SNETEN~2.RTF b/Storm/DOCS/SNETEN~2.RTF new file mode 100644 index 0000000..6bd2d7e --- /dev/null +++ b/Storm/DOCS/SNETEN~2.RTF @@ -0,0 +1,40 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\li720\widctlpar \f11 \sbasedon19\snext21 API Callback;}{\s22\widctlpar \f4\fs20 \sbasedon0\snext22 footnote text;}{\*\cs23 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien} +{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min19}{\revtim\yr1996\mo10\dy3\hr19\min16}{\version2}{\edmins1}{\nofpages1}{\nofwords178}{\nofchars1020}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade +\fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (} +{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs23\super ${\footnote \pard\plain \s22\widctlpar +\f4\fs20 {\cs23\super $} SNetEnumProviders}#{\footnote \pard\plain \s22\widctlpar \f4\fs20 {\cs23\super #} SNetEnumProviders}K{\footnote \pard\plain \s22\widctlpar \f4\fs20 {\cs23\super K} SNetEnumProviders}} SNetEnumProviders +\par \pard\plain \s16\widctlpar \f4 +\par Enumerates all network providers installed on the system. The callback function you provide is called once for each provider. If desired, you can specify a minimum set of capabilities, and only providers which meet or exceed those capabilities will be r +eturned. +\par +\par Rather than calling this function manually, an application will generally call SNetSelectProvider() to present the user with a list of network providers and allow him to select and initialize one. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetEnumProviders ( +\par \tab SNETCAPSPTR\tab \tab \tab mincaps, +\par \tab SNETENUMPROVIDERSPROC\tab \tab callback +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 mincaps +\par \pard\plain \s19\li720\widctlpar \f4 +A pointer to an SNETCAPS structure specifying the minimum capabilities required of network providers. The size field must be filled in which the size of the structure. Any other field can contain a number to specify a minimum capability, or zero to spec +ify that the field should be ignored. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s19\li720\widctlpar \f4 If the mincaps parameter is NULL, all network providers are enumerated. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 callback +\par \pard\plain \s19\li720\widctlpar \f4 The application\rquote s callback function. See EnumProvidersProc() for a description. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No callback function is provided +\par {\pntext\pard\plain\f1 \'b7\tab}The size field of the SNETCAPS structure is invalid +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETGE~1.RTF b/Storm/DOCS/SNETGE~1.RTF new file mode 100644 index 0000000..bfb23ef --- /dev/null +++ b/Storm/DOCS/SNETGE~1.RTF @@ -0,0 +1,40 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min20} +{\revtim\yr1996\mo11\dy13\hr23\min45}{\version2}{\edmins0}{\nofpages2}{\nofwords202}{\nofchars1152}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetGetNetworkLatency}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetGetNetworkLatency}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetGetNetworkLatency}} SNetGetNetworkLatency +\par \pard\plain \s16\widctlpar \f4 +\par Returns the expected or measured round-trip latency. This is twice the approximate time, in milliseconds, that a message sent from one computer will take to reach another computer. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetGetNetworkLatency ( +\par \tab DWORD\tab \tab measurementtype, +\par \tab DWORD\tab \tab *result +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 measurementtype +\par \pard\plain \s19\li720\widctlpar \f4 An identifier specifying the way in which the latency should be measured. +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx3492\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3492\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_LMT_EXPECTED\cell The expected latency for this network provider. This value is always the same for any given network provider.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_LMT_CURRENT\cell +The current latency of the game. This computer must currently be joined in a game. The latency returned is the highest latency between this computer and any of the other players.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd +\trgaph108\trleft612 \cellx3492\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_LMT_PEAK\cell The peak latency of the game. This computer must currently be joined in a game. The latency returned is the highest measured latency between this computer + and any of the other players since the beginning of the game, or since the last call to SNetResetLatencyMeasurements().\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\li720\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 result +\par \pard\plain \s19\li720\widctlpar \f4 The returned latency. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}The measurement type identifier is invalid +\par {\pntext\pard\plain\f1 \'b7\tab}The measurement type calls for a measured rather than expected latency, and no game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}No variable is provided to receive the result +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETGE~2.RTF b/Storm/DOCS/SNETGE~2.RTF new file mode 100644 index 0000000..3ca1c40 --- /dev/null +++ b/Storm/DOCS/SNETGE~2.RTF @@ -0,0 +1,37 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min20} +{\revtim\yr1996\mo10\dy3\hr15\min7}{\version2}{\edmins0}{\nofpages1}{\nofwords98}{\nofchars559}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetGetNumPlayers}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetGetNumPlayers}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetGetNumPlayers}} SNetGetNumPlayers +\par \pard\plain \s16\widctlpar \f4 +\par Returns the number of active players in the game, and the range of active player IDs. The range of IDs may be larger than the number of active players if players have dropped out of the game. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetGetNumPlayers ( +\par \tab DWORD\tab \tab *firstplayerid, +\par \tab DWORD\tab \tab *lastplayerid, +\par \tab DWORD\tab \tab *activeplayers +\par \}; +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 firstplayerid +\par \pard\plain \s19\li720\widctlpar \f4 The lowest numbered ID of any active player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 lastplayerid +\par \pard\plain \s19\li720\widctlpar \f4 The highest numbered ID of any active player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 activeplayers +\par \pard\plain \s19\li720\widctlpar \f4 The total number of active players. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETGE~3.RTF b/Storm/DOCS/SNETGE~3.RTF new file mode 100644 index 0000000..3e3236e --- /dev/null +++ b/Storm/DOCS/SNETGE~3.RTF @@ -0,0 +1,35 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min20} +{\revtim\yr1996\mo10\dy3\hr15\min7}{\version2}{\edmins0}{\nofpages1}{\nofwords103}{\nofchars588}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetGetPlayerCaps}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetGetPlayerCaps}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetGetPlayerCaps}} SNetGetPlayerCaps +\par \pard\plain \s16\widctlpar \f4 +\par Returns the capabilities of an individual player. You can use this function to get the latency between this machine and any other player in the game. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetGetPlayerCaps ( +\par \tab DWORD\tab \tab \tab playerid, +\par \tab SNETCAPSPTR\tab caps +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the player for which capabilities will be returned. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 caps +\par \pard\plain \s19\li720\widctlpar \f4 An SNETCAPS structure. You must fill in the size field before passing this structure to SNetGetPlayerCaps(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}No active player exists with the given ID +\par {\pntext\pard\plain\f1 \'b7\tab}The size field of the SNETCAPS structure is invalid +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETGE~4.RTF b/Storm/DOCS/SNETGE~4.RTF new file mode 100644 index 0000000..32bf088 --- /dev/null +++ b/Storm/DOCS/SNETGE~4.RTF @@ -0,0 +1,40 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min21} +{\revtim\yr1996\mo10\dy3\hr15\min7}{\version2}{\edmins0}{\nofpages1}{\nofwords87}{\nofchars500}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetGetPlayerName}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetGetPlayerName}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetGetPlayerName}} SNetGetPlayerName +\par \pard\plain \s16\widctlpar \f4 +\par Returns the name of any player in the game. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetGetPlayerName ( +\par \tab DWORD\tab \tab playerid, +\par \tab LPSTR\tab \tab buffer, +\par \tab DWORD\tab \tab buffersize +\par ); +\par +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the player whose name is being requested. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 buffer +\par \pard\plain \s19\li720\widctlpar \f4 A string buffer into which the name will be copied. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 buffersize +\par \pard\plain \s19\li720\widctlpar \f4 The size, in characters, of the buffer. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}No active player exists with the given ID +\par {\pntext\pard\plain\f1 \'b7\tab}No buffer is given +\par {\pntext\pard\plain\f1 \'b7\tab}The size of the buffer is zero +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETGE~5.RTF b/Storm/DOCS/SNETGE~5.RTF new file mode 100644 index 0000000..89a4b34 --- /dev/null +++ b/Storm/DOCS/SNETGE~5.RTF @@ -0,0 +1,29 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min20} +{\revtim\yr1996\mo10\dy3\hr19\min18}{\version2}{\edmins0}{\nofpages1}{\nofwords67}{\nofchars387}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetGetProviderCaps}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetGetProviderCaps}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetGetProviderCaps}} SNetGetProviderCaps +\par \pard\plain \s16\widctlpar \f4 +\par Returns the capabilities of the currently selected network provider. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetGetProviderCaps ( +\par \tab SNETCAPSPTR\tab caps +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 caps +\par \pard\plain \s19\li720\widctlpar \f4 An SNETCAPS structure. You must fill in the size field before passing this structure to SNetGetProviderCaps(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}The size field of the SNETCAPS structure is invalid +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETGE~6.RTF b/Storm/DOCS/SNETGE~6.RTF new file mode 100644 index 0000000..cb372a4 --- /dev/null +++ b/Storm/DOCS/SNETGE~6.RTF @@ -0,0 +1,45 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min21} +{\revtim\yr1996\mo10\dy3\hr15\min8}{\version2}{\edmins1}{\nofpages2}{\nofwords292}{\nofchars1667}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetGetTurnsInTransit}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetGetTurnsInTransit}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetGetTurnsInTransit}} SNetGetTurnsInTransit +\par \pard\plain \s16\widctlpar \f4 +\par Returns the number of turns which have been from this machine with SNetSendTurn() but not yet received with SNetReceiveTurns(). It is generally a good idea to keep two or more turns in transit (on the wire) so that other machines can process turns withou +t having to wait for them to be transmitted. +\par +\par For example, if a game runs at the rate of two turns per second, and for each turn it simply sends its turn and then waits for turns from all other players to arrive, then the game speed may be cut in half when running on a high-latency network such as th +e Internet. This is because at least a quarter of a second will be wasted for every turn waiting for turns to arrive from other players. +\par +\par However, if the game is modified so that it always sends out turns two in advance of what it is processing (sending tu +rn 3 and then processing all turns for turn 1, sending turn 4 and then processing all turns for turn 2, etc.) then the turns will have plenty of time for transmission, so no game delay will be required. +\par +\par The two primary ways to compensate for latency in a turn-based game are: +\par {\pntext\pard\plain 1. \tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlbody\pndec\pnb0\pni0\pnf4\pnfs24\pnstart1\pnindent360\pnhang{\pntxta . }}Decrease the number of turns processed per second, or +\par {\pntext\pard\plain 2. \tab}Increase the number of turns in transit. +\par \pard \s16\widctlpar +\par Since decreasing the number of turns processed per second compensates not only for latency problems but also bandwidth problems, +it is probably best to fix the number of turns in transit at two and then adjust the number of turns per second. You can get a recommendation for the number of turns per second from the network provider\rquote +s capabilities, returned during SNetEnumerateProviders(). +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetGetTurnsInTransit ( +\par \tab DWORD\tab \tab *turns +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 turns +\par \pard\plain \s19\li720\widctlpar \f4 The number of turns that have been sent from this computer with SNetSendTurn() but not yet received with SNetReceiveTurns(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}No variable is provided to receive the result +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETIN~1.RTF b/Storm/DOCS/SNETIN~1.RTF new file mode 100644 index 0000000..cb5a126 --- /dev/null +++ b/Storm/DOCS/SNETIN~1.RTF @@ -0,0 +1,60 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min21} +{\revtim\yr1996\mo10\dy3\hr19\min16}{\version2}{\edmins0}{\nofpages2}{\nofwords438}{\nofchars2502}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetInitializeProvider}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetInitializeProvider}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetInitializeProvider}} SNetInitializeProvider +\par \pard\plain \s16\widctlpar \f4 +\par Initializes the given network provider, which will provide support for all further SNet calls. +\par +\par Some providers can take a second or more to initialize, especially if initialization involves connecting to a server. +\par +\par Rather than calling this function manually, an application will generally call SNetSelectProvider() to present the user with a list of network providers and allow him to select and initialize one. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetInitializeProvider ( +\par \tab DWORD\tab \tab \tab \tab providerid, +\par \tab SNETPROGRAMDATAPTR\tab programdata, +\par \tab SNETPLAYERDATAPTR\tab playerdata, +\par \tab SNETUIDATAPTR\tab \tab interfacedata, +\par \tab SNETVERSIONDATAPTR\tab versiondata +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the provider to be initialized. This is obtained from a call to SNetEnumerateProviders(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s19\li720\widctlpar \f4 You can also specify zero to use the null provider. The null provider is used just l +ike any other provider, but it does not make use of any communications medium. It is provided so that single player games can use the same code as multi-player games. To create a single player game using the null provider, first initialize the provider, + then create a game using SNetCreateGame(), then send messages and turns using the SNet functions as normal. At the end of the game, call SNetLeaveGame(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 programdata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing information about the program, such as the program name, version, and number of players supported. This is a mandatory parameter. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerdata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing the name and description of the current player. The provider may use this information if it performs a matchmaking process. This is a mandatory parameter. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 interfacedata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing information about how the network provider should display user interface screens if necessary. Most network providers will fail if this information is not given. For example, +the modem provider cannot query the user for a phone number to dial without the ability to display user interface screens. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 versiondata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing information about the application which is necessary for automatic version control. Some network providers are capable of performing over-the-wire version updates. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}The program data is missing or invalid. +\par {\pntext\pard\plain\f1 \'b7\tab}The player data is missing or invalid. +\par {\pntext\pard\plain\f1 \'b7\tab}The interface data is missing or invalid, and the provider needs to display user interface in order to initialize itself. +\par {\pntext\pard\plain\f1 \'b7\tab}The system is out of memory or resources +\par {\pntext\pard\plain\f1 \'b7\tab}The network provider was unable to initialize itself. For example, the IPX provider may fail if IPX support is not available, and the Battle.net provider may fail if it cannot contact any Battle.net servers. +\par {\pntext\pard\plain\f1 \'b7\tab}The application needs to be upgraded before it can connect to the server. +\par \pard \s16\widctlpar +\par If this function fails, the application should call GetLastError() to determine the reason for failure. If GetLastError() returns SNET_ERROR_REQUIRES_UPGRADE, the application should call SNetPerformUpgrade(). +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETJO~1.RTF b/Storm/DOCS/SNETJO~1.RTF new file mode 100644 index 0000000..2e91d01 --- /dev/null +++ b/Storm/DOCS/SNETJO~1.RTF @@ -0,0 +1,56 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min21} +{\revtim\yr1996\mo10\dy3\hr19\min14}{\version2}{\edmins0}{\nofpages2}{\nofwords232}{\nofchars1328}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetJoinGame}#{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super #} SNetJoinGame}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetJoinGame}} SNetJoinGame +\par \pard\plain \s16\widctlpar \f4 +\par Joins an existing game. Rather than calling this function manually, an application will generally call SNetSelectGame() to present the user with a list of games and allow him to join a game or create a new one. +\par +\par To leave a game after joining, call SNetLeaveGame(). +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetJoinGame ( +\par \tab DWORD\tab \tab \tab gameid, +\par \tab LPCSTR\tab \tab gamename, +\par \tab LPCSTR\tab \tab gamepassword, +\par \tab LPCSTR\tab \tab playername, +\par \tab LPCSTR\tab \tab playerdescription, +\par \tab DWORD\tab \tab \tab *playerid +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 gameid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the game to be joined. You can discover IDs of active games using SNetEnumGames(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 gamename +\par \pard\plain \s19\li720\widctlpar \f4 The name of the game to be joined. By passing a name, you can join a game which was not enumerated, such as a private game. If {\i gameid} is not zero, this parameter is ignored. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 gamepassword +\par \pard\plain \s19\li720\widctlpar \f4 The password of the game to be joined. The function will fail if the password is incorrect. If the game to be joined is not password protected, simply pass a blank password. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playername +\par \pard\plain \s19\li720\widctlpar \f4 The name of the local player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerdescription +\par \pard\plain \s19\li720\widctlpar \f4 A description of the local player. This can be generated by the program, and contain information such as the player\rquote s character class or level. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID that is assigned to the player, if joining is successful. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No player name or description is specified +\par {\pntext\pard\plain\f1 \'b7\tab}No variable is provided to receive the player ID +\par {\pntext\pard\plain\f1 \'b7\tab}The game owner cannot be contacted (possibly due to a firewall) +\par {\pntext\pard\plain\f1 \'b7\tab}The game password is incorrect +\par {\pntext\pard\plain\f1 \'b7\tab}The game is full or is closed to new players +\par {\pntext\pard\plain\f1 \'b7\tab}The system is out of memory +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETLE~1.RTF b/Storm/DOCS/SNETLE~1.RTF new file mode 100644 index 0000000..f84c8e7 --- /dev/null +++ b/Storm/DOCS/SNETLE~1.RTF @@ -0,0 +1,24 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\widctlpar \f4\fs20 \sbasedon0\snext19 footnote text;}{\*\cs20 \additive\super \sbasedon10 +footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min22}{\revtim\yr1996\mo10\dy3\hr15\min8}{\version2}{\edmins0}{\nofpages1}{\nofwords61}{\nofchars348}{\*\company Blizzard Entertainment}{\vern57431}} +\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}} +{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs20\super ${\footnote \pard\plain +\s19\widctlpar \f4\fs20 {\cs20\super $} SNetLeaveGame}#{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super #} SNetLeaveGame}K{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super K} SNetLeaveGame}} SNetLeaveGame +\par \pard\plain \s16\widctlpar \f4 +\par Leaves the current game. If the local player created the game using SNetCreateGame(), and hasn\rquote t yet started the game, then leaving will destroy the game. Otherwise, the game will continue without the local player. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetLeaveGame(); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par None. +\par +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETPE~1.RTF b/Storm/DOCS/SNETPE~1.RTF new file mode 100644 index 0000000..408b84b --- /dev/null +++ b/Storm/DOCS/SNETPE~1.RTF @@ -0,0 +1,36 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien} +{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr19\min28}{\version2}{\edmins1}{\nofpages1}{\nofwords152}{\nofchars869}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd +\linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNet +PerformUpgrade}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetPerformUpgrade}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetPerformUpgrade}} SNetPerformUpgrade +\par \pard\plain \s16\widctlpar \f4 +\par Performs an automatic version update of the application. You should call this function is SNetSelectProvider() or SNetInitializeProvider() fails and GetLastError() returns SNET_ERROR_REQUIRES_UPGRADE. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetPerformUpgrade ( +\par \tab DWORD\tab \tab *upgradestatus +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 upgradestatus +\par \pard\plain \s19\li720\widctlpar \f4 Returns one of the following values, specifying whether the upgrade was successful: +\par +\par \trowd \trgaph108\trleft612 \cellx4500\cellx7812 \pard \s19\widctlpar\intbl {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4500\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_UPGRADE_FAILED\cell The upgrade failed or was canceled by the user.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_UPGRADE_NOT_NEEDED\cell No upgrade is needed.\cell \pard\plain \widctlpar\intbl \f4\fs20 +\row \pard\plain \s19\widctlpar\intbl \f4 SNET_UPGRADE_SUCCEEDED\cell The upgrade succeeded.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4500\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_UPGRADING_TERMINATE + +\par \pard\plain \s16\widctlpar\intbl \f4 \cell \pard\plain \s19\widctlpar\intbl \f4 The upgrade is currently in progress. The patch program needs the application to terminate so that it can modify the application\rquote +s EXE or DLL files. The patch program will restart the application after the upgrade is complete. \cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No variable was provided to receive the upgrade status +\par {\pntext\pard\plain\f1 \'b7\tab}The upgrade failed or was canceled by the user +\par {\pntext\pard\plain\f1 \'b7\tab}No upgrade was needed +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETPL~1.RTF b/Storm/DOCS/SNETPL~1.RTF new file mode 100644 index 0000000..4b350d6 --- /dev/null +++ b/Storm/DOCS/SNETPL~1.RTF @@ -0,0 +1,31 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr18\min2}{\version4} +{\edmins1}{\nofpages1}{\nofwords91}{\nofchars524}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNETPLAYERDATA}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNETPLAYERDATA}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNETPLAYERDATA}} SNETPLAYERDATA +\par \pard\plain \s16\widctlpar \f4 +\par The SNETPLAYERDATA function contains information about the local player. This information is required when initializing a provider, since the provider may provide a matchmaking service, and when creating or joining a game. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 typedef struct _SNETPLAYERDATA \{ +\par \tab DWORD\tab \tab size; +\par \tab DWORD\tab \tab playername; +\par \tab DWORD\tab \tab playerdescription; +\par \} SNETPLAYERDATA, *SNETPLAYERDATAPTR; +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Members +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 size +\par \pard\plain \s19\li720\widctlpar \f4 The size of the structure, in bytes. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playername +\par \pard\plain \s19\li720\widctlpar \f4 The name of the local player. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerdescription +\par \pard\plain \s19\li720\widctlpar \f4 A description of the local player. This can be generated by the program, and contain information such as the player\rquote s character class or level. +\par \pard\plain \s16\widctlpar \f4 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETPR~1.RTF b/Storm/DOCS/SNETPR~1.RTF new file mode 100644 index 0000000..0fb8ea8 --- /dev/null +++ b/Storm/DOCS/SNETPR~1.RTF @@ -0,0 +1,70 @@ +{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f16\froman\fcharset238\fprq2 Times New Roman CE;}{\f17\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f19\froman\fcharset161\fprq2 Times New Roman Greek;}{\f20\froman\fcharset162\fprq2 Times New Roman Tur;} +{\f21\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f28\fmodern\fcharset238\fprq1 Courier New CE;}{\f29\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f31\fmodern\fcharset161\fprq1 Courier New Greek;}{\f32\fmodern\fcharset162\fprq1 Courier New Tur;} +{\f33\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255; +\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\nowidctlpar\widctlpar\adjustright \fs20 \snext0 Normal;} +{\*\cs10 \additive Default Paragraph Font;}{\s15\nowidctlpar\widctlpar\adjustright \b\fs40 \sbasedon0 \snext16 API Title;}{\s16\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 API Description;}{\s17\nowidctlpar\widctlpar\adjustright \f2\fs22 +\sbasedon0 \snext17 API Function;}{\s18\nowidctlpar\widctlpar\adjustright \b \sbasedon0 \snext16 API Section;}{\s19\li720\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 API Parameter Description;}{\s20\nowidctlpar\widctlpar\adjustright \i +\sbasedon0 \snext19 API Parameter Name;}{\s21\nowidctlpar\widctlpar\adjustright \fs20 \sbasedon0 \snext21 footnote text;}{\*\cs22 \additive \super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien} +{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1997\mo3\dy21\hr17\min47}{\version3}{\edmins5}{\nofpages2}{\nofwords224}{\nofchars1280}{\*\company Blizzard Entertainment}{\nofcharsws0}{\vern71}} +\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind1\viewscale100 \fet0\sectd \linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3 +\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}} +{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain +\s15\keepn\nowidctlpar\widctlpar\adjustright \b\fs40 {\cs22\super ${\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super $}{ SNETPROGRAMDATA}}#{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super #}{ + SNETPROGRAMDATA}}K{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super K}{ SNETPROGRAMDATA}}}{ SNETPROGRAMDATA +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par The SNETPROGRAMDATA structure contains information about the application, such as the program name and version number. +\par +\par }\pard\plain \s17\nowidctlpar\widctlpar\adjustright \f2\fs22 {typedef struct _SNETPROGRAMDATA \{ +\par \tab DWORD\tab \tab size; +\par \tab LPCSTR\tab programname; +\par \tab LPCSTR\tab programdescription; +\par \tab DWORD\tab \tab programid; +\par \tab DWORD\tab \tab versionid; +\par \tab DWORD\tab \tab reserved1; +\par \tab DWORD\tab \tab maxplayers; +\par \tab LPVOID\tab initdata; +\par \tab DWORD\tab \tab initdatabytes; +\par \tab LPVOID\tab reserved2; +\par \tab DWORD\tab \tab optcategorybits; +\par \} SNETPROGRAMDATA, *SNETPROGRAMDATAPTR; +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Members +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {size +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The size of the structure, in bytes. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {programname +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The name of the program. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {programdescription +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The description of the progr +am. This usually includes a name and version number. It is displayed at the bottom of the standard connection screens. If this field is not provided, Storm will automatically generate it using the EXE file\rquote s product version information. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {programid +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A unique 32-bit identifier for the application. The use of this unique identifier allows multiple applications using Storm to create games on the same network without interfering with each other. + +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {versionid +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A unique 32-bit identifier for the network version of the application. This number should be incremented whenever a change in the application makes it incompatible with older versions. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {reserved1 +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {Reserved -- must be set to 0. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {maxplayers +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The maximum number of players per game supported by the application. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {initdata +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {Application-specific initialization data. This data is provided by the game creator, and is available to all joining computers through the SNET_EVENT_INITDATA callback. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {initdatabytes +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The size of the application-specific initialization data. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {reserved2 +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {Reserved \endash must be set to 0. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {optcategorybits +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {This value provides a hint to the network provider about which category bits will most often be used by users to narrow the list of joinable games. The network provider can us +e this hint to structure the way it stores its list of games. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }} \ No newline at end of file diff --git a/Storm/DOCS/SNETRE~1.RTF b/Storm/DOCS/SNETRE~1.RTF new file mode 100644 index 0000000..96d2750 --- /dev/null +++ b/Storm/DOCS/SNETRE~1.RTF @@ -0,0 +1,38 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min22} +{\revtim\yr1996\mo10\dy3\hr15\min9}{\version2}{\edmins0}{\nofpages1}{\nofwords112}{\nofchars640}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetReceiveMessage}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetReceiveMessage}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetReceiveMessage}} SNetReceiveMessage +\par \pard\plain \s16\widctlpar \f4 +\par This function receives the next unread message from any player. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetReceiveMessage ( +\par \tab DWORD\tab \tab *senderplayerid, +\par \tab LPVOID\tab *data, +\par \tab DWORD\tab \tab *databytes +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 senderplayerid +\par \pard\plain \s19\li720\widctlpar \f4 If a message is available, this parameter returns the ID of the player who sent the message. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 data +\par \pard\plain \s19\li720\widctlpar \f4 If a message is available, this parameter returns a pointer to the message data. The pointer remains valid until the next call to an SNet function or to StormDestroy(). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 databytes +\par \pard\plain \s19\li720\widctlpar \f4 If a message is available, this parameter returns the number of bytes in the message. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}No messages are available +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETRE~2.RTF b/Storm/DOCS/SNETRE~2.RTF new file mode 100644 index 0000000..23ed3d5 --- /dev/null +++ b/Storm/DOCS/SNETRE~2.RTF @@ -0,0 +1,54 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetReceiveTurns}{\author Mike O'Brien}{\operator Mike O'Brien} +{\creatim\yr1996\mo8\dy21\hr16\min22}{\revtim\yr1996\mo10\dy3\hr15\min9}{\version3}{\edmins0}{\nofpages2}{\nofwords269}{\nofchars1536}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd +\linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} + SNetReceiveTurns}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetReceiveTurns}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetReceiveTurns}} SNetReceiveTurns +\par \pard\plain \s16\widctlpar \f4 +\par This function receives the next set of turns from every active player, if all turns are available. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetReceiveTurns ( +\par \tab DWORD\tab \tab firstplayerid, +\par \tab DWORD\tab \tab arraysize, +\par \tab LPVOID\tab *arraydata, +\par \tab LPDWORD\tab arraydatabytes, +\par \tab LPDWORD\tab arrayplayerstatus +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 firstplayerid +\par \pard\plain \s19\li720\widctlpar \f4 The player ID of the first player for which a turn will be received. For example, if this parameter is one, then slot zero in the each array corresponds to player number one. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 arraysize +\par \pard\plain \s19\li720\widctlpar \f4 The number of slots in each array. This limits the number of players for which turns can be returned. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 arraydata +\par \pard\plain \s19\li720\widctlpar \f4 An array of pointers, which will be filled in with pointers to the message data for each player\rquote s turn. Each returned pointer will remain valid until the next call to an SNet function or to StormDestroy(). + +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 arraydatabytes +\par \pard\plain \s19\li720\widctlpar \f4 An array of DWORDs, which will be filled in with the size, in bytes, of the message data for each player\rquote s turn. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 arrayplayerstatus +\par \pard\plain \s19\li720\widctlpar \f4 An array of DWORDs, which will be filled in with the status of each player, whether or not the function successfully returns turns for each player. The following status codes can be returned: +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_PS_UNUSED\cell There is no active player in this slot.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_PS_READY\cell The next turn for this player has been received.\cell \pard\plain \widctlpar\intbl +\f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_PS_WAITING\cell The next turn for this player has not yet been received.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3960\cellx7812 \pard\plain +\s19\widctlpar\intbl \f4 SNET_PS_NOTRESPONDING\cell The next turn for this player has not been received, and attempts to contact the computer for a resend have been unsuccessful. The player may have lost his network connection.\cell \pard\plain +\widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}An array size of zero is specified +\par {\pntext\pard\plain\f1 \'b7\tab}An array was not provided +\par {\pntext\pard\plain\f1 \'b7\tab}This machine has not yet received the next turn from at least one player +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETRE~3.RTF b/Storm/DOCS/SNETRE~3.RTF new file mode 100644 index 0000000..118eec7 --- /dev/null +++ b/Storm/DOCS/SNETRE~3.RTF @@ -0,0 +1,42 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\li720\widctlpar \f11 \sbasedon19\snext21 API Callback;}{\s22\widctlpar \f4\fs20 \sbasedon0\snext22 footnote text;}{\*\cs23 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien} +{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min22}{\revtim\yr1996\mo10\dy11\hr14\min19}{\version2}{\edmins1}{\nofpages2}{\nofwords197}{\nofchars1126}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade +\fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (} +{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs23\super ${\footnote \pard\plain \s22\widctlpar +\f4\fs20 {\cs23\super $} SNetRegisterEventHandler}#{\footnote \pard\plain \s22\widctlpar \f4\fs20 {\cs23\super #} SNetRegisterEventHandler}K{\footnote \pard\plain \s22\widctlpar \f4\fs20 {\cs23\super K} SNetRegisterEventHandler}} SNetRegisterEventHandler + +\par \pard\plain \s16\widctlpar \f4 +\par Registers a callback function which will be called when the specified event occurs. Applications can use this functionality to receive notifications of players joining and leaving a game, among other things. +\par +\par Events can occur at any time, but Storm queues the events and only dispatches them to the appropriate event handler function during an application call to SNetReceiveMessage() or SNetReceiveTurns(). This protects the application from reentrancy issues. + +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetRegisterEventHandler ( +\par \tab DWORD\tab \tab \tab eventid, +\par \tab SNETEVENTPROC\tab callback +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 eventid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the event for which the callback function is being registered. The following events are defined: +\par \pard\plain \s16\widctlpar \f4 +\par \trowd \trgaph108\trleft612 \cellx4320\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4320\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_EVENT_INITDATA\cell Used to receive application-specific initialization data that the game creator specified in the call to SNetCreateGame().\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_EVENT_GAMEDESTROY +\cell The current game has been destroyed by the owner.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s19\widctlpar\intbl \f4 SNET_EVENT_GAMESTART\cell The current game has been started.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row +\pard\plain \s19\widctlpar\intbl \f4 SNET_EVENT_PLAYERJOIN\cell A player has joined the current game.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx4320\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 +SNET_EVENT_PLAYERLEAVE\cell A player has left the current game.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 callback +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to the callback function. See EventProc() for a description. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}An invalid event ID was specified +\par {\pntext\pard\plain\f1 \'b7\tab}No callback function was provided +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETRE~4.RTF b/Storm/DOCS/SNETRE~4.RTF new file mode 100644 index 0000000..af158ea --- /dev/null +++ b/Storm/DOCS/SNETRE~4.RTF @@ -0,0 +1,26 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\widctlpar \f4\fs20 \sbasedon0\snext19 footnote text;}{\*\cs20 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien} +{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min23}{\revtim\yr1996\mo10\dy3\hr15\min9}{\version2}{\edmins0}{\nofpages1}{\nofwords103}{\nofchars591}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0 +\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs20\super ${\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super $} + SNetResetLatencyMeasurements}#{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super #} SNetResetLatencyMeasurements}K{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super K} SNetResetLatencyMeasurements}} SNetResetLatencyMeasurements +\par \pard\plain \s16\widctlpar \f4 +\par This function has two effects. First, it clears the peak latency that has been measured since the beginning of the game, as returned by SNetGetNetworkLatency() with SNET_LMT_PEAK. Second, it causes all players in the game to be immediately polled for a +new current latency, as returned by SNetGetNetworkLatency() with SNET_LMT_CURRENT. +\par +\par It can be useful to call SNetResetLatencyMeasurements() after a player drops out of a game, especially if the game bases its speed or number of turns per second on the measured latency of the current players. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetResetLatencyMeasurements (); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par None. +\par +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETSE~1.RTF b/Storm/DOCS/SNETSE~1.RTF new file mode 100644 index 0000000..4a947a1 --- /dev/null +++ b/Storm/DOCS/SNETSE~1.RTF @@ -0,0 +1,59 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien} +{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr19\min9}{\version2}{\edmins1}{\nofpages2}{\nofwords317}{\nofchars1812}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd +\linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} + SNetSelectGame}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetSelectGame}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetSelectGame}} SNetSelectGame +\par \pard\plain \s16\widctlpar \f4 +\par Supplies user interface screens to allow the player to select from a list of games or create a new game, then creates or joins the game and returns the local user\rquote s game player ID. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetSelectGame ( +\par \tab DWORD\tab \tab \tab \tab flags, +\par \tab SNETPROGRAMDATAPTR\tab programdata, +\par \tab SNETPLAYERDATAPTR\tab playerdata, +\par \tab SNETUIDATAPTR\tab \tab interfacedata, +\par \tab SNETVERSIONDATAPTR\tab versiondata, +\par \tab DWORD\tab \tab \tab \tab *playerid +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 flags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags specifying which options should be provided to the user. The following flags are defined: +\par +\par \trowd \trgaph108\trleft612 \cellx3780\cellx7812 \pard \s19\widctlpar\intbl {\b Value}\cell {\b Meaning}\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \trowd \trgaph108\trleft612 \cellx3780\cellx7812 \pard\plain \s19\widctlpar\intbl \f4 SNET_ +SF_ALLOWCREATE\cell The user is allowed to create new games. If this flag is not specified, the user is only allowed to join existing games.\cell \pard\plain \widctlpar\intbl \f4\fs20 \row \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 programdata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing information about the program, such as the program name, version, and number of players supported. This is a mandatory parameter. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerdata +\par \pard\plain \s19\li720\widctlpar \f4 +A pointer to a structure containing the name and description of the current player. The provider may use this information if it performs a matchmaking process. The provider also uses this information when creating or joining a game. This is a mandatory + parameter. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 interfacedata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing i +nformation about how the network provider should display user interface screens if necessary. Most network providers will fail if this information is not given. For example, the modem provider cannot query the user for a phone number to dial without the + ability to display user interface screens. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 versiondata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing information about the application which is necessary for automatic version control. Some network providers are capable of performing over-the-wire version updates. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID that is assigned to the player, if the function successfully creates or joins a game. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized. +\par {\pntext\pard\plain\f1 \'b7\tab}The program data is missing or invalid. +\par {\pntext\pard\plain\f1 \'b7\tab}The player data is missing or invalid. +\par {\pntext\pard\plain\f1 \'b7\tab}The interface data is missing or invalid +\par {\pntext\pard\plain\f1 \'b7\tab}No variable is provided to receive the player ID. +\par {\pntext\pard\plain\f1 \'b7\tab}The user canceled the creation or joining process. +\par {\pntext\pard\plain\f1 \'b7\tab}The system is out of memory. +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETSE~2.RTF b/Storm/DOCS/SNETSE~2.RTF new file mode 100644 index 0000000..f6ac105 --- /dev/null +++ b/Storm/DOCS/SNETSE~2.RTF @@ -0,0 +1,52 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien} +{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr19\min8}{\version5}{\edmins12}{\nofpages2}{\nofwords310}{\nofchars1770}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd +\linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNet +SelectProvider}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetSelectProvider}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetSelectProvider}} SNetSelectProvider +\par \pard\plain \s16\widctlpar \f4 +\par \pard \s16\widctlpar Supplies user interface screens to allow the user to select a network provider, then initializes that provider. +\par \pard \s16\widctlpar +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetSelectGame ( +\par \pard \s17\widctlpar \tab SNETCAPSPTR\tab \tab mincaps, +\par \tab SNETPROGRAMDATAPTR\tab programdata, +\par \tab SNETPLAYERDATAPTR\tab playerdata, +\par \tab SNETUIDATAPTR\tab \tab interfacedata, +\par \tab SNETVERSIONDATAPTR\tab versiondata, +\par \tab DWORD\tab \tab \tab \tab *providerid +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 programdata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing information about the program, such as the program name, version, and number of players supported. This is a mandatory parameter. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 playerdata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing the name and description of the current player. The provider may use this information if it performs a matchmaking process. This is a mandatory parameter. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 interfacedata +\par \pard\plain \s19\li720\widctlpar \f4 +A pointer to a structure containing information about how the network provider should display user interface screens if necessary. Most network providers will fail if this information is not given. For example, the modem provider cannot query the user f +or a phone number to dial without the ability to display user interface screens. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 versiondata +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a structure containing information about the application which is necessary for automatic version control. Some network providers are capable of performing over-the-wire version updates. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 providerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the provider that was selected. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}The program data is missing or invalid. +\par {\pntext\pard\plain\f1 \'b7\tab}The player data is missing or invalid. +\par {\pntext\pard\plain\f1 \'b7\tab}The interface data is missing or invalid, and the provider needs to display interface during the initialization process. +\par {\pntext\pard\plain\f1 \'b7\tab}The network provider was unable to initialize itself. For example, the IPX provider may fail if IPX support is not available, and the Battle.net provider may fail if it cannot contact any Battle.net servers. +\par {\pntext\pard\plain\f1 \'b7\tab}The application needs to be upgraded before it can connect to the server. +\par \pard \s16\widctlpar +\par If this function fails, the application should call GetLastError() to determine the reason for failure. If GetLastError() returns SNET_ERROR_REQUIRES_UPGRADE, the application should call SNetPerformUpgrade(). +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETSE~3.RTF b/Storm/DOCS/SNETSE~3.RTF new file mode 100644 index 0000000..2683a82 --- /dev/null +++ b/Storm/DOCS/SNETSE~3.RTF @@ -0,0 +1,44 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min23} +{\revtim\yr1996\mo10\dy21\hr11\min47}{\version2}{\edmins0}{\nofpages1}{\nofwords169}{\nofchars964}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetSendMessage}#{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super #} SNetSendMessage}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetSendMessage}} SNetSendMessage +\par \pard\plain \s16\widctlpar \f4 +\par Sends a message to another player, or to all players. It must be received on the target computer using SNetReceiveMessage(). +\par +\par A message is different from a turn, in that messages can be sent between two individual players, and can be sent at any time, whereas turns are sent to all players at a specific interval. The choice of whether to use messages or turns depends on the netw +orking model of the game. Games can also mix and match, using messages for some purposes and turns for others. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetSendMessage ( +\par \tab DWORD\tab \tab targetplayerid, +\par \tab LPVOID\tab data, +\par \tab DWORD\tab \tab databytes +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 targetplayerid +\par \pard\plain \s19\li720\widctlpar \f4 The ID of the player to whom the message will be sent. Specify SNET_BROADCASTPLAYERID to broadcast the message to all players. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 data +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to the message data. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 databytes +\par \pard\plain \s19\li720\widctlpar \f4 The size of the message, in bytes. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}A player ID was given, and no active player exists with that ID +\par {\pntext\pard\plain\f1 \'b7\tab}No data pointer was provided +\par {\pntext\pard\plain\f1 \'b7\tab}The size of the message is zero +\par {\pntext\pard\plain\f1 \'b7\tab}The system is out of memory +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETSE~4.RTF b/Storm/DOCS/SNETSE~4.RTF new file mode 100644 index 0000000..cdce77e --- /dev/null +++ b/Storm/DOCS/SNETSE~4.RTF @@ -0,0 +1,41 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min23} +{\revtim\yr1996\mo10\dy3\hr15\min10}{\version2}{\edmins0}{\nofpages1}{\nofwords182}{\nofchars1042}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetSendTurn}#{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super #} SNetSendTurn}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetSendTurn}} SNetSendTurn +\par \pard\plain \s16\widctlpar \f4 +\par Sends out the next turn for this computer. The turn must be received on the local machine and all other machines in the game using SNetReceiveTurns(). +\par +\par Typically, a game will send a turn as soon as it is generated (for example, as soon a +s the user performs an action), and then receive turns at a specific rate, such as two turns per second. By sending turns as soon as they are generated, rather than sending only two turns per second, the game ensures that turns are given as much time as +possible to travel over the wire. However, it is also important for the game to ensure that it has always sent more turns than it has processed, to ensure that there are always turns on the wire. The game can accomplish this by checking the number of tu +rns in transit, using SNetGetTurnsInTransit(), before calling SNetReceiveTurns(). +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetSendTurn ( +\par \tab LPVOID\tab data, +\par \tab DWORD\tab \tab databytes +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 data +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to the turn data. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 databytes +\par \pard\plain \s19\li720\widctlpar \f4 The size of the turn data, in bytes. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}No data pointer was provided +\par {\pntext\pard\plain\f1 \'b7\tab}The size of the turn is zero +\par {\pntext\pard\plain\f1 \'b7\tab}The system is out of memory +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETST~1.RTF b/Storm/DOCS/SNETST~1.RTF new file mode 100644 index 0000000..2d24635 --- /dev/null +++ b/Storm/DOCS/SNETST~1.RTF @@ -0,0 +1,31 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\widctlpar \f4\fs20 \sbasedon0\snext19 footnote text;}{\*\cs20 \additive\super \sbasedon10 +footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min23}{\revtim\yr1996\mo10\dy3\hr15\min10}{\version2}{\edmins0}{\nofpages1}{\nofwords157}{\nofchars898}{\*\company Blizzard Entertainment}{\vern57431}} +\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}} +{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs20\super ${\footnote \pard\plain +\s19\widctlpar \f4\fs20 {\cs20\super $} SNetStartGame}#{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super #} SNetStartGame}K{\footnote \pard\plain \s19\widctlpar \f4\fs20 {\cs20\super K} SNetStartGame}} SNetStartGame +\par \pard\plain \s16\widctlpar \f4 +\par Starts the current game. Only the game master can call this function. Once the game has been started, no new players can join, and the game will continue even if the game master has left. +\par +\par The SNetStartGame() function was designed around games like Warcraft, where all players sit in a chat room while waiting for the game to join, and then start playing the game at th +e same time. It makes less sense in a game like Quake where players can drop in and out of the game at any time. For this reason, it will probably be removed and replaced with a more comprehensive API that allows individual control over such game attrib +utes as whether new players can join, whether the game shows up in lists of games, and whether the game master is necessary to maintain the game. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetStartGame (); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par None. +\par +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}No network provider has been initialized +\par {\pntext\pard\plain\f1 \'b7\tab}No game has been created or joined +\par {\pntext\pard\plain\f1 \'b7\tab}The local player is not the master player +\par {\pntext\pard\plain\f1 \'b7\tab}The game has already been started +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETUI~1.RTF b/Storm/DOCS/SNETUI~1.RTF new file mode 100644 index 0000000..077d7e1 --- /dev/null +++ b/Storm/DOCS/SNETUI~1.RTF @@ -0,0 +1,80 @@ +{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f16\froman\fcharset238\fprq2 Times New Roman CE;}{\f17\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f19\froman\fcharset161\fprq2 Times New Roman Greek;}{\f20\froman\fcharset162\fprq2 Times New Roman Tur;} +{\f21\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f28\fmodern\fcharset238\fprq1 Courier New CE;}{\f29\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f31\fmodern\fcharset161\fprq1 Courier New Greek;}{\f32\fmodern\fcharset162\fprq1 Courier New Tur;} +{\f33\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255; +\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\nowidctlpar\widctlpar\adjustright \fs20 \snext0 Normal;} +{\*\cs10 \additive Default Paragraph Font;}{\s15\nowidctlpar\widctlpar\adjustright \b\fs40 \sbasedon0 \snext16 API Title;}{\s16\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 API Description;}{\s17\nowidctlpar\widctlpar\adjustright \f2\fs22 +\sbasedon0 \snext17 API Function;}{\s18\nowidctlpar\widctlpar\adjustright \b \sbasedon0 \snext16 API Section;}{\s19\li720\nowidctlpar\widctlpar\adjustright \sbasedon0 \snext16 API Parameter Description;}{\s20\nowidctlpar\widctlpar\adjustright \i +\sbasedon0 \snext19 API Parameter Name;}{\s21\nowidctlpar\widctlpar\adjustright \fs20 \sbasedon0 \snext21 footnote text;}{\*\cs22 \additive \super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien} +{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1997\mo3\dy21\hr17\min50}{\version4}{\edmins2}{\nofpages2}{\nofwords369}{\nofchars2106}{\*\company Blizzard Entertainment}{\nofcharsws0}{\vern71}} +\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind1\viewscale100 \fet0\sectd \linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3 +\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}} +{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain +\s15\keepn\nowidctlpar\widctlpar\adjustright \b\fs40 {\cs22\super ${\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super $}{ SNETUIDATA}}#{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super #}{ + SNETUIDATA}}K{\footnote \pard\plain \s21\nowidctlpar\widctlpar\adjustright \fs20 {\cs22\super K}{ SNETUIDATA}}}{ SNETUIDATA +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par The SNETUIDATA structure contains information which Storm and the network providers use to display user interface on behalf of the application program. +\par +\par }\pard\plain \s17\nowidctlpar\widctlpar\adjustright \f2\fs22 {typedef struct _SNETUIDATA \{ +\par \tab DWORD\tab \tab \tab \tab size; +\par \tab DWORD\tab \tab \tab \tab uiflags; +\par \tab HWND\tab \tab \tab \tab parentwindow; +\par \tab SNETGETARTPROC\tab \tab artcallback; +\par \tab SNETCHECKAUTHPROC\tab authcallback; +\par \tab SNETCREATEPROC\tab \tab createcallback; +\par \tab SNETDRAWDESCPROC\tab drawdesccallback; +\par \tab SNETSELECTEDPROC\tab selectedcallback; +\par \tab SNETMESSAGEBOXPROC\tab messageboxcallback; +\par \tab SNETPLAYSOUNDPROC\tab soundcallback; +\par \tab SNETSTATUSPROC\tab \tab statuscallback; +\par \tab SNETGETDATAPROC\tab \tab getdatacallback; +\par \tab SNETCATEGORYPROC\tab \tab categorycallback; +\par \} SNETUIDATA, *SNETUIDATAPTR; +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s18\nowidctlpar\widctlpar\adjustright \b {Members +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {size +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The size of the structure, in bytes. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {uiflags +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A set of flags specifying the desired behavior of the network provider\rquote s user interface. No flags are currently defined. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {parentwindow +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {The window handle of the active window. If Storm or a network provider creates a dialog box, it will use this handle for the parent window. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {artcallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function which Storm or a network provider can call to obtain artwork for the dialog background or controls. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {authcallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function which the network provider calls to determine whether the local player has access to a chat room. This only applies to network providers which provide chat functionality. + +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {createcallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright { +A pointer to a function which the network provider calls when the user has decided to create a game. This function is responsible for asking the user for the game name and options, and then calling SNetCreateGame(). +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {drawdesccallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright { +A pointer to a function which the network provider calls if it needs to draw a game or player description. This allows the application to perform its own drawing. For example, it could convert a cryptic description str +ing which only the application understands, like \ldblquote FOG LOW BATTLE.PUD\rdblquote into a group of icons which would represent the game options in a way players could easily understand. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {selectedcallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function which Storm calls when the user selects a network provider. This provides the application a chance to review the network provider\rquote +s ID and capabilities, and either accept the selection or present the user with an error message and reject the selection. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {messageboxcallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function which Storm and the network provider can use to display message boxes. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {soundcallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function which Storm and the network provider can use to play sound effects. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {statuscallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function that the network provider can use to provide feedback on the status of a long operation. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {getdatacallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function that the network provider can use to request provider-specific data from the application. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }\pard\plain \s20\nowidctlpar\widctlpar\adjustright \i {categorycallback +\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\adjustright {A pointer to a function that the network provider can use to request information about which categories of games the user is interested in joining. +\par }\pard\plain \s16\nowidctlpar\widctlpar\adjustright { +\par }} \ No newline at end of file diff --git a/Storm/DOCS/SNETUN~1.RTF b/Storm/DOCS/SNETUN~1.RTF new file mode 100644 index 0000000..a9c3ccf --- /dev/null +++ b/Storm/DOCS/SNETUN~1.RTF @@ -0,0 +1,33 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f1\froman\fcharset2\fprq2 Symbol;}{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; +\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; +\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 +\sbasedon0\snext16 API Description;}{\s17\widctlpar \f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 +\sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 \sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min23} +{\revtim\yr1996\mo10\dy3\hr15\min10}{\version2}{\edmins0}{\nofpages1}{\nofwords77}{\nofchars443}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNetUnregisterEventHandler}#{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNetUnregisterEventHandler}K{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNetUnregisterEventHandler}} SNetUnregisterEventHandler +\par \pard\plain \s16\widctlpar \f4 +\par This removes a given function from the list of registered event handlers. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL SNetUnregisterEventHandler ( +\par \tab DWORD\tab \tab \tab eventid, +\par \tab SNETEVENTPROC\tab callback +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 eventid +\par \pard\plain \s19\li720\widctlpar \f4 The event ID for which the handler was registered. See SNetRegisterEventHandler() for a list of event IDs. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 callback +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to the event handler function. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par This function returns TRUE for success or FALSE for failure. The function can fail if: +\par {\pntext\pard\plain\f1 \'b7\tab}\pard \s16\fi-360\li360\widctlpar{\*\pn \pnlvlblt\pnf1\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}An invalid event ID was specified +\par {\pntext\pard\plain\f1 \'b7\tab}No callback function was provided +\par \pard\plain \widctlpar \f4\fs20 +\par } \ No newline at end of file diff --git a/Storm/DOCS/SNETVE~1.RTF b/Storm/DOCS/SNETVE~1.RTF new file mode 100644 index 0000000..6a2b923 --- /dev/null +++ b/Storm/DOCS/SNETVE~1.RTF @@ -0,0 +1,39 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo10\dy3\hr18\min29}{\version2} +{\edmins2}{\nofpages1}{\nofwords135}{\nofchars771}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} SNETVERSIONDATA}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} SNETVERSIONDATA}K{\footnote +\pard\plain \s21\widctlpar \f4\fs20 {\cs22\super K} SNETVERSIONDATA}} SNETVERSIONDATA +\par \pard\plain \s16\widctlpar \f4 +\par The SNETVERSIONDATA structure contains information that is needed to perform an over-the-wire program upgrade. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 typedef struct _SNETVERSIONDATA \{ +\par \tab DWORD\tab \tab size; +\par \tab LPCSTR\tab versionstring; +\par \tab LPCSTR\tab executablefile; +\par \tab LPCSTR\tab originalarchivefile; +\par \tab LCPSTR\tab patcharchivefile; +\par \} SNETVERSIONDATA, *SNETVERSIONDATAPTR; +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Members +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 size +\par \pard\plain \s19\li720\widctlpar \f4 The size of the structure, in bytes. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 versionstring +\par \pard\plain \s19\li720\widctlpar \f4 A human-readable string representing the product version. If this string is provided, it overrides the product version string in the executable file\rquote s version information resource. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 executablefile +\par \pard\plain \s19\li720\widctlpar \f4 The full path name of the program\rquote s executable file. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 originalarchivename +\par \pard\plain \s19\li720\widctlpar \f4 The full path name to the archive file which contains all of the program\rquote s data. This file will typically be located on CD. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 patcharchivefile +\par \pard\plain \s19\li720\widctlpar \f4 The full path name to the archive file which contains patched program data. This file must be located on the user\rquote s hard drive. +\par \pard\plain \s16\widctlpar \f4 +\par } \ No newline at end of file diff --git a/Storm/DOCS/STATUS~1.RTF b/Storm/DOCS/STATUS~1.RTF new file mode 100644 index 0000000..5b03c03 --- /dev/null +++ b/Storm/DOCS/STATUS~1.RTF @@ -0,0 +1,47 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18}{\revtim\yr1996\mo11\dy27\hr19\min45}{\version3} +{\edmins1}{\nofpages2}{\nofwords170}{\nofchars971}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 {\cs22\super ${\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super $} StatusProc}#{\footnote \pard\plain \s21\widctlpar \f4\fs20 {\cs22\super #} StatusProc}K{\footnote \pard\plain +\s21\widctlpar \f4\fs20 {\cs22\super K} StatusProc}} StatusProc +\par \pard\plain \s16\widctlpar \f4 +\par {\b\i StatusProc() is a placeholder for an application-defined function name.} +\par +\par This function is called by the network provider during a long operation to allow the program to provide visual feedback to the user. +\par +\par \pard\plain \s17\widctlpar \f11\fs22 BOOL CALLBACK StatusProc ( +\par \tab LPCSTR\tab \tab statustext, +\par \tab DWORD\tab \tab \tab workcompleted, +\par \tab DWORD\tab \tab \tab estimatedworkremaining, +\par \tab DWORD\tab \tab \tab flags, +\par \tab SNETABORTPROC\tab abortproc +\par ); +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Parameters +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 statustext +\par \pard\plain \s19\li720\widctlpar \f4 A human-readable description of the current status of the operation. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 workcompleted +\par \pard\plain \s19\li720\widctlpar \f4 A value representing the amount of work on this operation that the network provider has already completed. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 estimatedworkremaining +\par \pard\plain \s19\li720\widctlpar \f4 A value representing the network provider\rquote s best estimate for the amount of work remaining. If the application wants to display the progress as a percent, it can use the following equation: +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s19\fi720\li720\widctlpar \f4 percent = (completed*100)/(completed+remaining). +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 flags +\par \pard\plain \s19\li720\widctlpar \f4 A set of flags which specify the state of the service provider. There are no flags currently defined. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s20\widctlpar \i\f4 abortproc +\par \pard\plain \s19\li720\widctlpar \f4 A pointer to a function that the application can call to cancel the current operation. +\par \pard\plain \s16\widctlpar \f4 +\par \pard\plain \s18\widctlpar \b\f4 Return Value +\par \pard\plain \s16\widctlpar \f4 +\par If the application uses this information, it should return TRUE. Otherwise, it should return FALSE. +\par +\par } \ No newline at end of file diff --git a/Storm/DOCS/STORM.GID b/Storm/DOCS/STORM.GID new file mode 100644 index 0000000..5d647c2 Binary files /dev/null and b/Storm/DOCS/STORM.GID differ diff --git a/Storm/DOCS/STORM.HLP b/Storm/DOCS/STORM.HLP new file mode 100644 index 0000000..4905dcb Binary files /dev/null and b/Storm/DOCS/STORM.HLP differ diff --git a/Storm/DOCS/STORM.HPJ b/Storm/DOCS/STORM.HPJ new file mode 100644 index 0000000..32d5e65 --- /dev/null +++ b/Storm/DOCS/STORM.HPJ @@ -0,0 +1,49 @@ +[OPTIONS] +TITLE=Storm Reference +COMPRESS=on +WARNING=3 + +[FILES] +Title.rtf +SNetCreateGame.rtf +SNetDestroy.rtf +SNetEnumGames.rtf +SNetEnumProviders.rtf +SNetGetNetworkLatency.rtf +SNetGetNumPlayers.rtf +SNetGetPlayerCaps.rtf +SNetGetPlayerName.rtf +SNetGetProviderCaps.rtf +SNetGetTurnsInTransit.rtf +SNetInitializeProvider.rtf +SNetJoinGame.rtf +SNetLeaveGame.rtf +SNetPerformUpgrade.rtf +SNetReceiveMessage.rtf +SNetReceiveTurns.rtf +SNetRegisterEventHandler.rtf +SNetResetLatencyMeasurements.rtf +SNetSelectGame.rtf +SNetSelectProvider.rtf +SNetSendMessage.rtf +SNetSendTurn.rtf +SNetStartGame.rtf +SNetUnregisterEventHandler.rtf +CategoryProc.rtf +CheckAuthProc.rtf +CreateProc.rtf +DrawDescProc.rtf +EnumGamesProc.rtf +EnumProvidersProc.rtf +EventProc.rtf +GetArtProc.rtf +GetDataProc.rtf +MessageBoxProc.rtf +PlaySoundProc.rtf +StatusProc.rtf +SNETCAPS.rtf +SNETCREATEDATA.rtf +SNETPLAYERDATA.rtf +SNETPROGRAMDATA.rtf +SNETUIDATA.rtf +SNETVERSIONDATA.rtf diff --git a/Storm/DOCS/STORM.PH b/Storm/DOCS/STORM.PH new file mode 100644 index 0000000..7ad0786 --- /dev/null +++ b/Storm/DOCS/STORM.PH @@ -0,0 +1,652 @@ +*playerid +0x80000000, +32-bit +A description of the local player. This can be generated by the program, and contain information such as the player +A pointer to a structure containing information about how the network provider should display user interface screens if necessary. Most network providers will fail if this information is not given. For example, the modem provider cannot query the user +A pointer to a structure containing information about the application which is necessary for automatic version control. Some network providers are capable of performing over-the-wire version updates. +A pointer to a structure containing information about the program, such as the program name, version, and number of players supported. This is a mandatory parameter. +A set of flags specifying how the sound should be played. Use the SND_* constants defined in Windows.h. +A structure containing the interface data that was passed to SNetSelectGame(), modified as necessary to ensure that the dialog that the create callback displays fits with the network provider +A structure containing the player data that was passed to SNetSelectGame(). +A structure containing the program data that was passed to SNetSelectGame(). +A structure containing the version data that was passed to SNetSelectGame(). +A value returned by the callback function specifying which +An array +An identifier which tells whether the name and description describe a game or a player. It can be one of the following values: +An invalid event ID was specified +Any +Applications +BOOL SNetSelectGame ( +Battle.net +Blizzard +Cancel +Cancel. +CategoryProc +CheckAuthProc +Courier New; +CreateProc +DWORD +DWORD * +DWORDs, +DrawDescProc +EnumGamesProc +EnumProvidersProc +EventProc +FALSE +For +Functions +GetArtProc +GetDataProc +GetLastError() +IDs +IDs, +IDs. +If this function fails, the application should call GetLastError() to determine the reason for failure. If GetLastError() returns SNET_ERROR_REQUIRES_UPGRADE, the application should call SNetPerformUpgrade(). +LPCSTR +LPDWORD +LPVOID +Meaning +Members +MessageBoxProc +Most +New; +No active player exists with the given ID +No callback function is provided +No callback function was provided +No data pointer was provided +No game has been created or joined +No network provider has been initialized +No player name or description is specified +No variable is provided to receive the result +None. +Other +Otherwise, +Parameters +PlaySoundProc +Player has been squelched by the local user +Player is a Blizzard employee +Player is a channel moderator +Player is a speaker for a special event +Player is a sysop of the selected gaming service +Rather than calling this function manually, an application will generally call SNetSelectGame() to present the user with a list of games and allow him to join a game or create a new one. +Rather than calling this function manually, an application will generally call SNetSelectProvider() to present the user with a list of network providers and allow him to select and initialize one. +Return Value +SNETCAPS +SNETCAPSPTR +SNETCREATEDATA +SNETEVENTPROC +SNETPLAYERDATA +SNETPLAYERDATAPTR +SNETPROGRAMDATA +SNETPROGRAMDATAPTR +SNETUIDATA +SNETUIDATAPTR +SNETVERSIONDATA +SNETVERSIONDATAPTR +SNET_DDPF_BLIZZARD +SNET_DDPF_MODERATOR +SNET_DDPF_SPEAKER +SNET_DDPF_SQUELCHED +SNET_DDPF_SYSOP +SNET_ERROR_REQUIRES_UPGRADE, +SNET_EVENT_INITDATA +SNet +SNetCreateGame +SNetCreateGame() +SNetCreateGame(), +SNetCreateGame(). +SNetDestroy +SNetEnumGames +SNetEnumProviders +SNetEnumerateProviders(). +SNetGetNetworkLatency +SNetGetNetworkLatency() +SNetGetNumPlayers +SNetGetPlayerCaps +SNetGetPlayerName +SNetGetProviderCaps +SNetGetTurnsInTransit +SNetInitializeProvider +SNetInitializeProvider(). +SNetJoinGame +SNetLeaveGame +SNetLeaveGame(). +SNetPerformUpgrade +SNetPerformUpgrade(). +SNetReceiveMessage +SNetReceiveMessage() +SNetReceiveTurns +SNetReceiveTurns(). +SNetRegisterEventHandler +SNetResetLatencyMeasurements +SNetSelectGame +SNetSelectGame() +SNetSelectGame(), +SNetSelectGame(). +SNetSelectProvider +SNetSelectProvider() +SNetSendMessage +SNetSendTurn +SNetSendTurn() +SNetStartGame +SNetUnregisterEventHandler +Some +StatusProc +Storm +StormDestroy(). +Symbol; +TRUE +The ID of the network provider which is making the request. +The application +The application needs to be upgraded before it can connect to the server. +The name of the local player. +The network provider was unable to initialize itself. For example, the IPX provider may fail if IPX support is not available, and the Battle.net provider may fail if it cannot contact any Battle.net servers. +The player data is missing or invalid. +The program data is missing or invalid. +The size field of the SNETCAPS structure is invalid +The size of the buffer pointed to by +The size of the structure, in bytes. +The size of the turn +The system is out of memory +This function returns TRUE for success or FALSE for failure. The function can fail if: +This function should return TRUE to continue enumeration, or FALSE to stop. +Value +Windows.h. +ability +abortproc +about +above +active +after +all +allow +allowed +allows +already +also +always +amount +and +another +application +application-defined +application-specific +application. +archive +are +array +arrayplayerstatus +artwork +artwork, +assigned +authorized +automatic +automatically +available +available, +available. +background +bandwidth +been +before +beginning +being +below. +between +bitmap +bitmap. +bits +box +box. +buffer +buffer, +buffer. +buffersize +buffersize, +but +button +button. +buttons: +bytes +bytes, +bytes. +call +callback +callback, +called +calling +calls +can +canceled +cannot +capabilities +capabilities, +capable +caps +caption, +categories +category +categorybits +categorymask +categorymask) +channel +channel. +character +characters, +chat +class +communications +computer +computer. +computers +connect +constants +contact +contain +containing +contains +continue +control. +create +created +createdata +creates +creating +creation +current +currently +data +data, +data. +databytes +decided +decoded +default +default. +defaultturns +define +defined +defined. +defined: +describe +describing +description +description. +destroy +determine +dial +dialog +dialog. +display +displayed +displays +does +doesn +draw +drawdata +drawn. +during +each +effect. +effects. +either +employee +ensure +enumerate +enumerated. +enumeration, +error +especially +event +eventid +eventid, +events +example, +executable +existing +exists +expected +expressed +fail +failed +fails, +failure. +feedback +field +file +fill +filled +first +firstplayerid +flags +flags, +following +from +full +function +function. +game +game, +game. +gamedescription +gameid +gamename +gamename, +gamepassword +gamepassword, +games +games, +games. +gaming +generally +generated +get +given +given. +graphical +handle +handler +has +have +height +highest +him +hint +how +human-readable +iconic +identifier +if: +ignored. +includes +indicate +individual +information +initdata +initdatabytes +initialization +initialize +initialized +initialized. +installed +interested +interface +interface. +interfacedata +interfacedata, +into +invalid +invalid, +invalid. +item +item. +itemdescription +itemdescription, +itemtype +itemtype, +its +itself. +join +join, +joined +joined. +joining +joining. +latency +latency, +latency. +leaving +level. +like +list +local +located +machine +machines +maintain +makes +making +mandatory +manually, +master +match +matchmaking +maximum +maxplayers +maxplayers; +may +measured +measurement +medium, +memory +message +message. +messages +mincaps +mincaps, +minimum +missing +modem +moderator +modified +more +must +name +name, +name. +necessary +necessary. +need +needed +needs +network +new +next +not +null +number +number. +numbered +occurred. +once +one +one. +only +operation +operation. +options +options, +or a phone number to dial without the ability to display user interface screens. +order +out +over +over-the-wire +own +palette +parameter +parameter. +parentwindow +pass +passed +passing +password +password. +path +per +perform +performing +performs +phone +placeholder +played. +player +player, +player. +playerdata +playerdata, +playerdescription +playerdescription, +playerid +playerid, +playername +playername, +players +players. +pointed +pointer +pointers +present +private +probably +procedure +process +process. +processed +processing +product +program +program, +programdata +programdata, +provide +provided +provided, +provider +provider, +provider. +providerid +providerid, +providers +provides +push +query +querying +range +rather +reason +receive +received +received. +receives +recommended +registered. +represent +representing +request +request. +requested +requested. +requesting +required +requirements +response +responsible +result +return +returned +returned. +returns +round-trip +s character class or level. +s interface. +s maximum number of players +same +screens +screens. +second +second, +second. +select +selected +selected. +sending +sent +server +server. +servers. +service +set +should +simply +since +single +size +size, +size; +soon +sound +soundid +speaker +special +specific +specified +specify +specifying +squelched +standard +started +status +string +struct +structure +structure, +structure. +success +successful. +successfully +such +support +supported +supported. +supports +system +system. +systems, +take +than +that +the +their +then +there +this +through +time +time, +transit +turn +turns +two +type +unable +unique +updates. +upgrade +upgraded +use +used +user +user. +uses +using +valid +values: +variable +version +version, +versiondata +versiondata, +waiting +was +when +where +whether +which +will +window +window. +with +without +yet +you +zero diff --git a/Storm/DOCS/TITLE.BMP b/Storm/DOCS/TITLE.BMP new file mode 100644 index 0000000..638152a Binary files /dev/null and b/Storm/DOCS/TITLE.BMP differ diff --git a/Storm/DOCS/TITLE.RTF b/Storm/DOCS/TITLE.RTF new file mode 100644 index 0000000..044e363 --- /dev/null +++ b/Storm/DOCS/TITLE.RTF @@ -0,0 +1,62 @@ +{\rtf1\ansi \deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}{\f11\fmodern\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\stylesheet{\widctlpar \f4\fs20 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\widctlpar \b\f4\fs40 \sbasedon0\snext16 API Title;}{\s16\widctlpar \f4 \sbasedon0\snext16 API Description;}{\s17\widctlpar +\f11\fs22 \sbasedon0\snext17 API Function;}{\s18\widctlpar \b\f4 \sbasedon0\snext16 API Section;}{\s19\li720\widctlpar \f4 \sbasedon0\snext16 API Parameter Description;}{\s20\widctlpar \i\f4 \sbasedon0\snext19 API Parameter Name;}{\s21\widctlpar \f4\fs20 +\sbasedon0\snext21 footnote text;}{\*\cs22 \additive\super \sbasedon10 footnote reference;}{\s23\widctlpar\tqc\tx4320\tqr\tx8640 \f4\fs20 \sbasedon0\snext23 header;}{\s24\widctlpar\tqc\tx4320\tqr\tx8640 \f4\fs20 \sbasedon0\snext24 footer;}{\*\cs25 +\additive\uldb \sbasedon10 Link Text;}{\*\cs26 \additive\v \sbasedon10 Link Pointer;}{\*\cs27 \additive\sbasedon10 Default Font;}}{\info{\title SNetCreateGame}{\author Mike O'Brien}{\operator Mike O'Brien}{\creatim\yr1996\mo8\dy21\hr16\min18} +{\revtim\yr1996\mo11\dy28\hr2\min33}{\version2}{\edmins0}{\nofpages2}{\nofwords207}{\nofchars1184}{\*\company Blizzard Entertainment}{\vern57431}}\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade \fet0\sectd \linex0\endnhere {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\keepn\widctlpar \b\f4\fs40 Storm Reference +\par \pard\plain \s16\widctlpar \f4 +\par {\b SNet API Functions} +\par +\par {\cs25\uldb SNetCreateGame()}{\cs26\v SNetCreateGame}{\cs27 +\par }{\cs25\uldb SNetDestroy()}{\cs26\v SNetDestroy}{\cs27 +\par }{\cs25\uldb SNetEnumGames()}{\cs26\v SNetEnumGames}{\cs27 +\par }{\cs25\uldb SNetEnumProviders()}{\cs26\v SNetEnumProviders}{\cs27 +\par }{\cs25\uldb SNetGetNetworkLatency()}{\cs26\v SNetGetNetworkLatency}{\cs27 +\par }{\cs25\uldb SNetGetNumPlayers()}{\cs26\v SNetGetNumPlayers}{\cs27 +\par }{\cs25\uldb SNetGetPlayerCaps()}{\cs26\v SNetGetPlayerCaps}{\cs27 +\par }{\cs25\uldb SNetGetPlayerName()}{\cs26\v SNetGetPlayerName}{\cs27 +\par }{\cs25\uldb SNetGetProviderCaps()}{\cs26\v SNetGetProviderCaps}{\cs27 +\par }{\cs25\uldb SNetGetTurnsInTransit()}{\cs26\v SNetGetTurnsInTransit}{\cs27 +\par }{\cs25\uldb SNetInitializeProvider()}{\cs26\v SNetInitializeProvider}{\cs27 +\par }{\cs25\uldb SNetJoinGame()}{\cs26\v SNetJoinGame}{\cs27 +\par }{\cs25\uldb SNetLeaveGame()}{\cs26\v SNetLeaveGame}{\cs27 +\par }{\cs25\uldb SNetPerformUpgrade()}{\cs26\v SNetPerformUpgrade}{\cs27 +\par }{\cs25\uldb SNetReceiveMessage()}{\cs26\v SNetReceiveMessage}{\cs27 +\par }{\cs25\uldb SNetReceiveTurns()}{\cs26\v SNetReceiveTurns}{\cs27 +\par }{\cs25\uldb SNetRegisterEventHandler()}{\cs26\v SNetRegisterEventHandler}{\cs27 +\par }{\cs25\uldb SNetResetLatencyMeasurements()}{\cs26\v SNetResetLatencyMeasurements}{\cs27 +\par }{\cs25\uldb SNetSelectGame()}{\cs26\v SNetSelectGame}{\cs27 +\par }{\cs25\uldb SNetSelectProvider()}{\cs26\v SNetSelectProvider}{\cs27 +\par }{\cs25\uldb SNetSendMessage()}{\cs26\v SNetSendMessage}{\cs27 +\par }{\cs25\uldb SNetSendTurn()}{\cs26\v SNetSendTurn}{\cs27 +\par }{\cs25\uldb SNetStartGame()}{\cs26\v SNetStartGame}{\cs27 +\par }{\cs25\uldb SNetUnregisterEventHandler()}{\cs26\v SNetUnregisterEventHandler}{\cs27 +\par } +\par {\b Callback Functions} +\par +\par {\cs25\uldb CheckAuthProc()}{\cs26\v CheckAuthProc} +\par {\cs25\uldb CreateProc()}{\cs26\v CreateProc} +\par {\cs25\uldb DrawDescProc()}{\cs26\v DrawDescProc}{\cs27 +\par }{\cs25\uldb EnumGamesProc()}{\cs26\v EnumGamesProc}{\cs27 +\par }{\cs25\uldb EnumProvidersProc()}{\cs26\v EnumProvidersProc}{\cs27 +\par }{\cs25\uldb EventProc()}{\cs26\v EventProc}{\cs27 +\par }{\cs25\uldb GetArtProc()}{\cs26\v GetArtProc}{\cs27 +\par }{\cs25\uldb GetDataProc()}{\cs26\v GetDataProc}{\cs27 +\par }{\cs25\uldb MessageBoxProc()}{\cs26\v MessageBoxProc}{\cs27 +\par }{\cs25\uldb PlaySoundProc()}{\cs26\v PlaySoundProc}{\cs27 +\par }{\cs25\uldb StatusProc()}{\cs26\v StatusProc}{\cs27 +\par +\par }{\cs27\b Data Structures +\par +\par }{\cs25\uldb SNETCAPS}{\cs26\v SNETCAPS}{\cs27 +\par }{\cs25\uldb SNETCREATEDATA}{\cs26\v SNETCREATEDATA}{\cs27 +\par }{\cs25\uldb SNETPLAYERDATA}{\cs26\v SNETPLAYERDATA}{\cs27 +\par }{\cs25\uldb SNETPROGRAMDATA}{\cs26\v SNETPROGRAMDATA}{\cs27 +\par }{\cs25\uldb SNETUIDATA}{\cs26\v SNETUIDATA}{\cs27 +\par }{\cs25\uldb SNETVERSIONDATA}{\cs26\v SNETVERSIONDATA}{\cs27 +\par } +\par } \ No newline at end of file diff --git a/Storm/DOCS/~$ETCAPS.RTF b/Storm/DOCS/~$ETCAPS.RTF new file mode 100644 index 0000000..f244f5c Binary files /dev/null and b/Storm/DOCS/~$ETCAPS.RTF differ diff --git a/Storm/H/BNETART.H b/Storm/H/BNETART.H new file mode 100644 index 0000000..6025781 --- /dev/null +++ b/Storm/H/BNETART.H @@ -0,0 +1,30 @@ +/**************************************************************************** +* +* bnetart.h +* +* This file should be included by an application that wants to provide +* battle.net-specific artwork in its art callback. +* +***/ + +enum _BATTLENET_ART { + SNET_ART_BATTLE_BTNS = 0x80000000, + SNET_ART_BATTLE_CHAT_BKG, + SNET_ART_BATTLE_GREENLAG, + SNET_ART_BATTLE_YELLOWLAG, + SNET_ART_BATTLE_REDLAG, + SNET_ART_BATTLE_CONNECT_BKG, + SNET_ART_BATTLE_SELECT_CHNL_BKG, + SNET_ART_BATTLE_LOGIN_BKG, + + SNET_ART_BATTLE_BADCONNECTION, + SNET_ART_BATTLE_WELCOME_AD, + + SNET_ART_BATTLE_LRG_EDIT_POPUP_BKG, +}; + + +enum _BATTLENET_DATA { + SNET_DATA_BATTLE_LOGODELAY = 0x80000000, // (DWORD) delay between frames +}; + diff --git a/Storm/H/STORM.BAK b/Storm/H/STORM.BAK new file mode 100644 index 0000000..0c5aebf --- /dev/null +++ b/Storm/H/STORM.BAK @@ -0,0 +1,3330 @@ +#ifndef _STORM_H_ +#define _STORM_H_ + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +//#########################################################################// +//#########################################################################// +// // +// // +// STANDARD PROGRAMMING INTERFACE // +// // +// // +//#########################################################################// +//#########################################################################// + + +#define DECLARE_STRICT_HANDLE(name) typedef struct name##__ { int unused; } *name +#define DECLARE_DERIVED_HANDLE(name,base) typedef struct name##__ : public base##__ { int unused; } *name + + +/**************************************************************************** +* +* Error codes +* (Error text is defined in Stormerr.mc) +* +***/ + +#define STORMFAC 0x510 +#define STORMERROR(code) (0x80000000 | (STORMFAC << 16) | ((code) & 0xFFFF)) + +#define STORM_ERROR_ASSERTION STORMERROR(0) +#define STORM_ERROR_BAD_ARGUMENT STORMERROR(101) +#define STORM_ERROR_GAME_ALREADY_STARTED STORMERROR(102) +#define STORM_ERROR_GAME_FULL STORMERROR(103) +#define STORM_ERROR_GAME_NOT_FOUND STORMERROR(104) +#define STORM_ERROR_GAME_TERMINATED STORMERROR(105) +#define STORM_ERROR_INVALID_PLAYER STORMERROR(106) +#define STORM_ERROR_NO_MESSAGES_WAITING STORMERROR(107) +#define STORM_ERROR_NOT_ARCHIVE STORMERROR(108) +#define STORM_ERROR_NOT_ENOUGH_ARGUMENTS STORMERROR(109) +#define STORM_ERROR_NOT_IMPLEMENTED STORMERROR(110) +#define STORM_ERROR_NOT_IN_ARCHIVE STORMERROR(111) +#define STORM_ERROR_NOT_IN_GAME STORMERROR(112) +#define STORM_ERROR_NOT_INITIALIZED STORMERROR(113) +#define STORM_ERROR_NOT_PLAYING STORMERROR(114) +#define STORM_ERROR_NOT_REGISTERED STORMERROR(115) +#define STORM_ERROR_REQUIRES_CODEC STORMERROR(116) +#define STORM_ERROR_REQUIRES_DDRAW STORMERROR(117) +#define STORM_ERROR_REQUIRES_DSOUND STORMERROR(118) +#define STORM_ERROR_REQUIRES_UPGRADE STORMERROR(119) +#define STORM_ERROR_STILL_ACTIVE STORMERROR(120) +#define STORM_ERROR_VERSION_MISMATCH STORMERROR(121) +#define STORM_ERROR_MEMORY_ALREADY_FREED STORMERROR(122) +#define STORM_ERROR_MEMORY_CORRUPT STORMERROR(123) +#define STORM_ERROR_MEMORY_INVALID_BLOCK STORMERROR(124) +#define STORM_ERROR_MEMORY_MANAGER_INACTIVE STORMERROR(125) +#define STORM_ERROR_MEMORY_NEVER_RELEASED STORMERROR(126) +#define STORM_ERROR_HANDLE_NEVER_RELEASED STORMERROR(127) +#define STORM_ERROR_ACCESS_OUT_OF_BOUNDS STORMERROR(128) + + +/**************************************************************************** +* +* BitBlt functions +* +***/ + +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SBltDestroy (); +#endif +extern "C" BOOL APIENTRY SBltGetSCode (DWORD rop3, + LPSTR buffer, + DWORD buffersize, + BOOL optimize = 1); +extern "C" BOOL APIENTRY SBltROP3 (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + DWORD pattern, + DWORD rop3); +extern "C" BOOL APIENTRY SBltROP3Clipped (LPBYTE dest, + LPRECT destrect, + LPSIZE destsize, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + LPSIZE sourcesize, + int sourcepitch, + DWORD pattern, + DWORD rop3); +extern "C" BOOL APIENTRY SBltROP3Tiled (LPBYTE dest, + LPRECT destrect, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + int sourcepitch, + int sourceoffsetx, + int sourceoffsety, + DWORD pattern, + DWORD rop3); + + +/**************************************************************************** +* +* Bitmap functions +* +***/ + +#define SBMP_IMAGETYPE_AUTO 0 +#define SBMP_IMAGETYPE_BMP 1 +#define SBMP_IMAGETYPE_PCX 2 + +typedef LPVOID (APIENTRY *SBMPALLOCPROC)(DWORD); + +extern "C" BOOL APIENTRY SBmpAllocLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE *returnedbuffer, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL, + int requestedbitdepth = 0, + SBMPALLOCPROC allocproc = NULL); +extern "C" BOOL APIENTRY SBmpDecodeImage (DWORD imagetype, + LPBYTE imagedata, + DWORD imagebytes, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SBmpLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SBmpSaveImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + int width, + int height, + int bitdepth); + + +/**************************************************************************** +* +* Command line parsing functions +* +***/ + +#define SCMD_ARG_FLAGGED (0 << 24) +#define SCMD_ARG_OPTIONAL (1 << 24) +#define SCMD_ARG_REQUIRED (2 << 24) +#define SCMD_ARG_MASK (SCMD_ARG_FLAGGED | SCMD_ARG_OPTIONAL | SCMD_ARG_REQUIRED) + +#define SCMD_BOOL_SET 0 +#define SCMD_BOOL_CLEAR 1 +#define SCMD_BOOL_MASK (SCMD_BOOL_CLEAR | SCMD_BOOL_SET) + +#define SCMD_CASESENSITIVE (0x01 << 8) + +#define SCMD_NUM_UNSIGNED 0 +#define SCMD_NUM_SIGNED 1 +#define SCMD_NUM_MASK (SCMD_NUM_UNSIGNED | SCMD_NUM_SIGNED) + +#define SCMD_TYPE_BOOL (0 << 16) +#define SCMD_TYPE_NUMERIC (1 << 16) +#define SCMD_TYPE_STRING (2 << 16) +#define SCMD_TYPE_MASK (SCMD_TYPE_BOOL | SCMD_TYPE_NUMERIC | SCMD_TYPE_STRING) + +#define SCMD_ERROR_BAD_ARGUMENT STORM_ERROR_BAD_ARGUMENT +#define SCMD_ERROR_NOT_ENOUGH_ARGUMENTS STORM_ERROR_NOT_ENOUGH_ARGUMENTS +#define SCMD_ERROR_OPEN_FAILED ERROR_OPEN_FAILED + +typedef struct _CMDERROR { + DWORD errorcode; + LPCTSTR itemstr; + LPCTSTR errorstr; +} CMDERROR, *CMDERRORPTR; + +typedef struct _CMDPARAMS { + DWORD flags; + DWORD id; + LPCTSTR name; + LPVOID variable; + DWORD setvalue; + DWORD setmask; + union { + BOOL boolvalue; + LONG signedvalue; + DWORD unsignedvalue; + LPCTSTR stringvalue; + }; +} CMDPARAMS, *CMDPARAMSPTR; + +typedef BOOL (CALLBACK *SCMDCALLBACK)(CMDPARAMSPTR,LPCTSTR); +typedef void (CALLBACK *SCMDERRORCALLBACK)(CMDERRORPTR); +typedef BOOL (CALLBACK *SCMDEXTRACALLBACK)(LPCTSTR); + +typedef struct _ARGLIST { + DWORD flags; + DWORD id; + LPCTSTR name; + SCMDCALLBACK callback; +} ARGLIST, *ARGLISTPTR; + +extern "C" BOOL APIENTRY SCmdCheckId (DWORD id); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SCmdDestroy (); +#endif +extern "C" BOOL APIENTRY SCmdGetBool (DWORD id); +extern "C" DWORD APIENTRY SCmdGetNum (DWORD id); +extern "C" BOOL APIENTRY SCmdGetString (DWORD id, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SCmdProcess (LPCTSTR cmdline, + BOOL skipprogname, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback); +extern "C" BOOL APIENTRY SCmdRegisterArgList (const ARGLIST *listptr, + DWORD numargs); +extern "C" BOOL APIENTRY SCmdRegisterArgument (DWORD flags, + DWORD id, + LPCTSTR name, + LPVOID variableptr = NULL, + DWORD variablebytes = 0, + DWORD setvalue = TRUE, + DWORD setmask = 0xFFFFFFFF, + SCMDCALLBACK callback = NULL); + +#define SCmdProcessCommandLine(ext,err) SCmdProcess(GetCommandLine(),TRUE,(ext),(err)) + +#define ARGBOOL(flags,name,var,callback) SCmdRegisterArgument(SCMD_TYPE_BOOL | (flags),0xFFFFFFFF,name,var,sizeof(var),TRUE,0xFFFFFFFF,callback) +#define ARGFLAG(flags,name,var,valuecallback) SCmdRegisterArgument(SCMD_TYPE_BOOL | (flags),0xFFFFFFFF,name,var,sizeof(var),value,value,callback) +#define ARGNUMBER(flags,name,var,callback) SCmdRegisterArgument(SCMD_TYPE_NUMERIC | (flags),0xFFFFFFFF,name,var,sizeof(var),0,0,callback) +#define ARGSTRING(flags,name,buffer,chars,callback) SCmdRegisterArgument(SCMD_TYPE_STRING | (flags),0xFFFFFFFF,name,buffer,(chars),0,0,callback) + + +/**************************************************************************** +* +* S-Code functions +* +***/ + +#define SCODE_CF_AUTOALIGNDWORD 0x00040000 +#define SCODE_CF_USESALTADJUSTS 0x04000000 + +DECLARE_STRICT_HANDLE(HSCODESTREAM); + +typedef struct _SCODEEXECUTEDATA { + DWORD size; + DWORD flags; + int xiterations; + int yiterations; + int adjustdest; + int adjustsource; + LPVOID dest; + LPVOID source; + LPVOID table; + DWORD a; + DWORD b; + DWORD c; + int adjustdestalt; + int adjustsourcealt; + DWORD reserved[2]; +} SCODEEXECUTEDATA, *SCODEEXECUTEDATAPTR; + +extern "C" BOOL APIENTRY SCodeCompile (LPCSTR prologstring, + LPCSTR loopstring, + LPCSTR *firsterror, + DWORD maxiterations, + DWORD flags, + HSCODESTREAM *handle); +extern "C" BOOL APIENTRY SCodeDelete (HSCODESTREAM handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SCodeDestroy (); +#endif +extern "C" BOOL APIENTRY SCodeExecute (HSCODESTREAM handle, + SCODEEXECUTEDATAPTR executedata); +extern "C" BOOL APIENTRY SCodeGetJumpTable (HSCODESTREAM handle, + LPBYTE **jumptableptr, + LPDWORD *prologpatchlocation, + LPDWORD *looppatchlocation, + LPDWORD *epilogpatchlocation); +extern "C" BOOL APIENTRY SCodeGetPseudocode (LPCSTR scodestring, + LPSTR buffer, + DWORD buffersize); + + +/**************************************************************************** +* +* Compression functions +* +***/ + +#define SCOMP_HINT_NONE 0 +#define SCOMP_HINT_BINARY 1 +#define SCOMP_HINT_TEXT 2 +#define SCOMP_HINT_EXECUTABLE 3 +#define SCOMP_HINT_ADPCM4 4 +#define SCOMP_HINT_ADPCM6 5 +#define SCOMP_HINTS 6 + +#define SCOMP_OPT_DEFAULT 0 +#define SCOMP_OPT_COMPRESSION 1 +#define SCOMP_OPT_SPEED 2 +#define SCOMP_OPT_QUALITY 3 + +#define SCOMP_TYPE_HUFFMAN 0x01 +#define SCOMP_TYPE_PKWARE 0x08 +#define SCOMP_TYPE_LOSSY_ADPCM_MONO 0x10 +#define SCOMP_TYPE_LOSSY_ADPCM_STEREO 0x20 + +extern "C" BOOL APIENTRY SCompCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD compressiontypes, + DWORD hint, + DWORD optimization); +extern "C" BOOL APIENTRY SCompDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize); + + +/**************************************************************************** +* +* Dialog box functions +* +***/ + +#define SDLG_ADJUST_NONE 0 +#define SDLG_ADJUST_VERTICAL 1 +#define SDLG_ADJUST_CONTROLPOS 2 + +#define SDLG_DBF_TILE 0x00000001 +#define SDLG_DBF_VCENTER 0x00000002 + +#define SDLG_STYLE_ANY 0xFFFFFFFF +#define SDLG_STYLE_ANYPUSHBUTTON 0x00010001 + +#define SDLG_USAGE_BACKGROUND 0x00000001 +#define SDLG_USAGE_NORMAL_UNFOCUSED 0x00000010 +#define SDLG_USAGE_NORMAL_FOCUSED 0x00000020 +#define SDLG_USAGE_NORMAL (SDLG_USAGE_NORMAL_UNFOCUSED | SDLG_USAGE_NORMAL_FOCUSED) +#define SDLG_USAGE_SELECTED_UNFOCUSED 0x00000040 +#define SDLG_USAGE_SELECTED_FOCUSED 0x00000080 +#define SDLG_USAGE_SELECTED (SDLG_USAGE_SELECTED_UNFOCUSED | SDLG_USAGE_SELECTED_FOCUSED) +#define SDLG_USAGE_NORMAL_GRAYED 0x00000100 +#define SDLG_USAGE_SELECTED_GRAYED 0x00000400 +#define SDLG_USAGE_GRAYED (SDLG_USAGE_NORMAL_GRAYED | SDLG_USAGE_SELECTED_GRAYED) +#define SDLG_USAGE_CURSORMASK 0x00001000 +#define SDLG_USAGE_CURSORIMAGE 0x00002000 + +extern "C" HDC APIENTRY SDlgBeginPaint (HWND window, LPPAINTSTRUCT ps); +extern "C" BOOL APIENTRY SDlgBltToWindowE (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey = 0xFFFFFFFF, + DWORD pattern = 0, + DWORD rop3 = SRCCOPY); +extern "C" BOOL APIENTRY SDlgBltToWindowI (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey = 0xFFFFFFFF, + DWORD pattern = 0, + DWORD rop3 = SRCCOPY); +extern "C" BOOL APIENTRY SDlgCheckTimers (); +extern "C" HWND APIENTRY SDlgCreateDialogIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" HWND APIENTRY SDlgCreateDialogParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" BOOL APIENTRY SDlgDefDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SDlgDestroy (); +#endif +extern "C" int APIENTRY SDlgDialogBoxIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" int APIENTRY SDlgDialogBoxParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" BOOL APIENTRY SDlgDrawBitmap (HWND window, + DWORD usage, + HRGN region, + int offsetx = 0, + int offsety = 0, + LPRECT boundingoffset = NULL, + DWORD flags = 0); +extern "C" BOOL APIENTRY SDlgEndDialog (HWND window, + int result); +extern "C" BOOL APIENTRY SDlgEndPaint (HWND window, LPPAINTSTRUCT ps); +extern "C" BOOL APIENTRY SDlgKillTimer (HWND window, + UINT event); +extern "C" BOOL APIENTRY SDlgSetBaseFont (int pointsize, + int weight, + DWORD flags, + DWORD family, + LPCTSTR face); +extern "C" BOOL APIENTRY SDlgSetBitmapE (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetBitmapI (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetControlBitmaps (HWND parentwindow, + LPINT controllist, + LPDWORD usagelist, + LPBYTE bitmapbits, + LPSIZE bitmapsize, + DWORD adjusttype, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetCursor (HWND window, + HCURSOR cursor, + DWORD id, + HCURSOR *oldcursor); +extern "C" BOOL APIENTRY SDlgSetSystemCursor (LPBYTE maskbitmap, + LPBYTE imagebitmap, + LPSIZE size, + DWORD id = 32512); +extern "C" BOOL APIENTRY SDlgSetTimer (HWND window, + UINT event, + UINT elapse, + TIMERPROC timerfunc); +extern "C" BOOL APIENTRY SDlgUpdateCursor (); + +#define SDlgCreateDialog(ins,tpl,wnd,prc) SDlgCreateDialogParam(ins,tpl,wnd,prc,0) +#define SDlgCreateDialogIndirect(ins,tpl,wnd,prc) SDlgCreateDialogIndirectParam(ins,tpl,wnd,prc,0) +#define SDlgDialogBox(ins,tpl,wnd,prc) SDlgDialogBoxParam(ins,tpl,wnd,prc,0) +#define SDlgDialogBoxIndirect(ins,tpl,wnd,prc) SDlgDialogBoxIndirectParam(ins,tpl,wnd,prc,0) + +#ifdef SDLG_USE_INCLUSIVE_RECTS +#define SDlgBltToWindow SDlgBltToWindowI +#define SDlgSetBitmap SDlgSetBitmapI +#else +#define SDlgBltToWindow SDlgBltToWindowE +#define SDlgSetBitmap SDlgSetBitmapE +#endif + +/**************************************************************************** +* +* DirectDraw functions +* +***/ + +#define SDRAW_SERVICE_BASIC 1 +#define SDRAW_SERVICE_PAGEFLIP 2 +#define SDRAW_SERVICE_DOUBLEBUFFER 3 +#define SDRAW_SERVICE_MAX 3 + +#define SDRAW_SURFACE_FRONT 0 +#define SDRAW_SURFACE_BACK 1 +#define SDRAW_SURFACE_SYSTEM 2 +#define SDRAW_SURFACE_TEMPORARY 3 + +#ifndef MAC +extern "C" BOOL APIENTRY SDrawAutoInitialize (HINSTANCE instance, + LPCTSTR classname, + LPCTSTR title, + WNDPROC wndproc = NULL, + int servicelevel = SDRAW_SERVICE_BASIC, + int width = 640, + int height = 480, + int bitdepth = 8); +extern "C" BOOL APIENTRY SDrawCaptureScreen (LPCTSTR filename = NULL); +#endif +extern "C" BOOL APIENTRY SDrawClearSurface (int surfacenumber); +extern "C" BOOL APIENTRY SDrawDestroy (); +extern "C" BOOL APIENTRY SDrawFlipPage (); +extern "C" HWND APIENTRY SDrawGetFrameWindow (HWND *window = NULL); +#ifdef __DDRAW_INCLUDED__ +extern "C" BOOL APIENTRY SDrawGetObjects (LPDIRECTDRAW *directdraw, + LPDIRECTDRAWSURFACE *frontbuffer, + LPDIRECTDRAWSURFACE *backbuffer, + LPDIRECTDRAWSURFACE *systembuffer, + LPDIRECTDRAWSURFACE *temporarybuffer, + LPDIRECTDRAWPALETTE *palette, + HPALETTE *gdipalette); +#endif +extern "C" BOOL APIENTRY SDrawGetScreenSize (int *width, + int *height, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SDrawGetServiceLevel (int *servicelevel = NULL); +extern "C" BOOL APIENTRY SDrawLockSurface (int surfacenumber, + LPCRECT rect, + LPBYTE *ptr, + int *pitch = NULL, + DWORD flags = 0); +#ifdef __DDRAW_INCLUDED__ +extern "C" BOOL APIENTRY SDrawManualInitialize (HWND framewindow, + LPDIRECTDRAW directdraw, + LPDIRECTDRAWSURFACE frontbuffer, + LPDIRECTDRAWSURFACE backbuffer, + LPDIRECTDRAWSURFACE systembuffer, + LPDIRECTDRAWSURFACE temporarybuffer, + LPDIRECTDRAWPALETTE palette, + HPALETTE gdipalette); +#endif +extern "C" int APIENTRY SDrawMessageBox (LPCTSTR text, + LPCTSTR title, + UINT flags); +extern "C" BOOL APIENTRY SDrawPostClose (); +extern "C" BOOL APIENTRY SDrawRealizePalette (); +#ifndef MAC +extern "C" BOOL APIENTRY SDrawSelectGdiSurface (BOOL select, BOOL copy); +#endif +extern "C" BOOL APIENTRY SDrawUnlockSurface (int surfacenumber, + LPBYTE ptr, + DWORD numrects = 0, + LPCRECT rectarray = NULL); +extern "C" BOOL APIENTRY SDrawUpdatePalette (DWORD firstentry, + DWORD numentries, + LPPALETTEENTRY entries, + BOOL reservedentries = FALSE); +extern "C" BOOL APIENTRY SDrawUpdateScreen (LPCRECT rect); +#ifdef MAC +extern "C" BOOL APIENTRY SDrawVidDriverInitialize (HWND framewindow, + int servicelevel); +#endif + + +/**************************************************************************** +* +* Error handling functions +* +***/ + +#define SERR_LINECODE_FUNCTION -1 +#define SERR_LINECODE_OBJECT -2 +#define SERR_LINECODE_HANDLE -3 +#define SERR_LINECODE_FILE -4 + +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SErrDestroy (); +#endif +extern "C" BOOL APIENTRY SErrDisplayError (DWORD errorcode, + LPCTSTR filename, + int linenumber, + LPCTSTR description, + BOOL recoverable, + UINT exitcode = 1); +extern "C" BOOL APIENTRY SErrGetErrorStr (DWORD errorcode, + LPTSTR buffer, + DWORD bufferchars); +extern "C" DWORD APIENTRY SErrGetLastError (); +extern "C" BOOL APIENTRY SErrRegisterMessageSource (WORD facility, + HMODULE module, + LPVOID reserved = NULL); +extern "C" void APIENTRY SErrReportResourceLeak (LPCTSTR handlename); +extern "C" void APIENTRY SErrSetLastError (DWORD errorcode); +extern "C" void APIENTRY SErrSuppressErrors (BOOL suppress); + +#define SErrGetLastErrorStr(buf,len) SErrGetErrorStr(SErrGetLastError(),buf,len) +#define FATALRESULT(str) SErrDisplayError(SErrGetLastError(),str,SERR_LINECODE_FUNCTION,NULL,FALSE) +#define REPORTRESOURCELEAK(handle) SErrReportResourceLeak(#handle) + +#ifdef _DEBUG +#define ASSERT(a) if (!(a)) \ + SErrDisplayError(STORM_ERROR_ASSERTION, \ + __FILE__, \ + __LINE__, \ + #a, \ + FALSE) +#define VALIDATEBEGIN do { +#define VALIDATE(a) ASSERT(a) +#define VALIDATEANDBLANK(a) do { \ + ASSERT(a); \ + *(a) = 0; \ + } while (0) +#define VALIDATEEND } while (0) +#define VALIDATEENDVOID } while (0) +#else +#define ASSERT(a) +#define VALIDATEBEGIN do { \ + int intrn_valresult = -1 +#define VALIDATE(a) intrn_valresult &= (a) ? -1 : 0 +#define VALIDATEANDBLANK(a) if (a) \ + *a = 0; \ + else \ + intrn_valresult = 0 +#define VALIDATEEND if (!intrn_valresult) { \ + SErrSetLastError( \ + ERROR_INVALID_PARAMETER); \ + return 0; \ + } \ + } while (0) +#define VALIDATEENDVOID if (!intrn_valresult) { \ + SErrSetLastError( \ + ERROR_INVALID_PARAMETER); \ + return; \ + } \ + } while (0) +#endif + + +/**************************************************************************** +* +* Event dispatching functions +* +***/ + +typedef void (CALLBACK *SEVTHANDLER)(LPVOID); + +extern "C" BOOL APIENTRY SEvtBreakHandlerChain (LPVOID data); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SEvtDestroy (); +#endif +extern "C" BOOL APIENTRY SEvtDispatch (DWORD type, + DWORD subtype, + DWORD id, + LPVOID data); +extern "C" BOOL APIENTRY SEvtPopState (DWORD type, + DWORD subtype); +extern "C" BOOL APIENTRY SEvtPushState (DWORD type, + DWORD subtype); +extern "C" BOOL APIENTRY SEvtRegisterHandler (DWORD type, + DWORD subtype, + DWORD id, + DWORD flags, + SEVTHANDLER handler); +extern "C" BOOL APIENTRY SEvtUnregisterHandler (DWORD type, + DWORD subtype, + DWORD id, + SEVTHANDLER handler); +extern "C" BOOL APIENTRY SEvtUnregisterType (DWORD type, + DWORD subtype); + + +/**************************************************************************** +* +* File I/O functions +* +***/ + +#define SFILE_AUTH_UNABLETOAUTHENTICATE 0 +#define SFILE_AUTH_NOSIGNATURE 1 +#define SFILE_AUTH_BADSIGNATURE 2 +#define SFILE_AUTH_UNKNOWNSIGNATURE 3 +#define SFILE_AUTH_FIRSTAUTHENTIC 5 +#define SFILE_AUTH_AUTHENTICBLIZZARD 5 + +#define SFILE_DDA_LOOP 0x00040000 + +#define SFILE_ERROR_BAD_FORMAT ERROR_BAD_FORMAT +#define SFILE_ERROR_BAD_PATHNAME ERROR_BAD_PATHNAME +#define SFILE_ERROR_CALL_NOT_IMPLEMENTED ERROR_CALL_NOT_IMPLEMENTED +#define SFILE_ERROR_FILE_INVALID ERROR_FILE_INVALID +#define SFILE_ERROR_FILE_NOT_FOUND ERROR_FILE_NOT_FOUND +#define SFILE_ERROR_HANDLE_EOF ERROR_HANDLE_EOF +#define SFILE_ERROR_INVALID_DATA ERROR_INVALID_DATA +#define SFILE_ERROR_INVALID_DRIVE ERROR_INVALID_DRIVE +#define SFILE_ERROR_INVALID_HANDLE ERROR_INVALID_HANDLE +#define SFILE_ERROR_INVALID_PARAMETER ERROR_INVALID_PARAMETER +#define SFILE_ERROR_NOT_ARCHIVE STORM_ERROR_NOT_ARCHIVE +#define SFILE_ERROR_NOT_AUTHENTICATED ERROR_NOT_AUTHENTICATED +#define SFILE_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY +#define SFILE_ERROR_NOT_IN_ARCHIVE STORM_ERROR_NOT_IN_ARCHIVE +#define SFILE_ERROR_NOT_INITIALIZED STORM_ERROR_NOT_INITIALIZED +#define SFILE_ERROR_NOT_PLAYING STORM_ERROR_NOT_PLAYING + +#define SFILE_ERRORMODE_RETURNCODE 0 +#define SFILE_ERRORMODE_CUSTOM 1 +#define SFILE_ERRORMODE_FATAL 2 + +#define SFILE_FIND_FILES 0x00000001 +#define SFILE_FIND_DIRECTORIES 0x00000002 + +DECLARE_STRICT_HANDLE(HSARCHIVE); +DECLARE_STRICT_HANDLE(HSFILE); + +typedef BOOL (CALLBACK *SFILEERRORPROC)(LPCTSTR,DWORD); + +extern "C" BOOL APIENTRY SFileAuthenticateArchive (HSARCHIVE archive, + DWORD *extendedresult); +extern "C" BOOL APIENTRY SFileCloseArchive (HSARCHIVE handle); +extern "C" BOOL APIENTRY SFileCloseFile (HSFILE handle); +extern "C" BOOL APIENTRY SFileDdaBegin (HSFILE handle, + DWORD buffersize, + DWORD flags); +extern "C" BOOL APIENTRY SFileDdaBeginEx (HSFILE handle, + DWORD buffersize, + DWORD flags, + DWORD offset, + LONG volume, + LONG pan, + LPVOID reserved); +extern "C" BOOL APIENTRY SFileDdaDestroy (); +extern "C" BOOL APIENTRY SFileDdaEnd (HSFILE handle); +extern "C" BOOL APIENTRY SFileDdaGetPos (HSFILE handle, + DWORD *position, + DWORD *maxposition); +extern "C" BOOL APIENTRY SFileDdaGetVolume (HSFILE handle, + LONG *volume, + LONG *pan); +#ifdef __DSOUND_INCLUDED__ +extern "C" BOOL APIENTRY SFileDdaInitialize (LPDIRECTSOUND directsound); +#endif +extern "C" BOOL APIENTRY SFileDdaSetVolume (HSFILE handle, + LONG volume, + LONG pan); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SFileDestroy (); +#endif +extern "C" BOOL APIENTRY SFileEnableDirectAccess (BOOL enable); +extern "C" BOOL APIENTRY SFileGetArchiveInfo (HSARCHIVE archive, + int *priority, + BOOL *cdrom); +extern "C" BOOL APIENTRY SFileGetArchiveName (HSARCHIVE archive, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SFileGetBasePath (LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SFileGetFileArchive (HSFILE file, + HSARCHIVE *archive); +extern "C" BOOL APIENTRY SFileGetFileName (HSFILE file, + LPTSTR buffer, + DWORD bufferchars); +extern "C" DWORD APIENTRY SFileGetFileSize (HSFILE handle, + LPDWORD filesizehigh = NULL); +extern "C" BOOL APIENTRY SFileOpenArchive (LPCTSTR archivename, + int priority, + BOOL cdonly, + HSARCHIVE *handle); +extern "C" BOOL APIENTRY SFileOpenFile (LPCTSTR filename, + HSFILE *handle); +extern "C" BOOL APIENTRY SFileOpenFileEx (HSARCHIVE archivehandle, + LPCTSTR filename, + DWORD flags, + HSFILE *handle); +extern "C" BOOL APIENTRY SFileReadFile (HSFILE handle, + LPVOID buffer, + DWORD bytestoread, + LPDWORD bytesread = NULL, + LPOVERLAPPED overlapped = NULL); +extern "C" BOOL APIENTRY SFileSetBasePath (LPCTSTR path); +extern "C" DWORD APIENTRY SFileSetFilePointer (HSFILE handle, + LONG distancetomove, + PLONG distancetomovehigh, + DWORD movemethod); +extern "C" BOOL APIENTRY SFileSetIoErrorMode (DWORD errormode, + SFILEERRORPROC errorproc = NULL); +extern "C" BOOL APIENTRY SFileSetLocale (LCID lcid); + + +/**************************************************************************** +* +* GDI functions +* +***/ + +#define ETO_TEXT_TRANSPARENT 0 +#define ETO_TEXT_COLOR 1 +#define ETO_TEXT_BLACK 2 +#define ETO_TEXT_WHITE 3 +#define ETO_BKG_TRANSPARENT 0 +#define ETO_BKG_COLOR 1 +#define ETO_BKG_BLACK 2 +#define ETO_BKG_WHITE 3 + +DECLARE_STRICT_HANDLE(HSGDIOBJ); +DECLARE_DERIVED_HANDLE(HSGDIFONT,HSGDIOBJ); + +extern "C" BOOL APIENTRY SGdiBitBlt (LPBYTE videobuffer, + int destx, + int desty, + LPBYTE sourcedata, + LPRECT sourcerect, + int sourcecx, + int sourcecy, + COLORREF color = 0, + DWORD rop = SRCCOPY); +extern "C" BOOL APIENTRY SGdiCreateFont (LPBYTE bits, + int width, + int height, + int bitdepth, + int filecharwidth, + int filecharheight, + LPSIZE charsizetable, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiDeleteObject (HSGDIOBJ handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SGdiDestroy (); +#endif +extern "C" BOOL APIENTRY SGdiExtTextOut (LPBYTE videobuffer, + int x, + int y, + LPRECT rect, + COLORREF color, + int textcoloruse, + int bkgcoloruse, + LPCTSTR string, + int chars = -1); +extern "C" BOOL APIENTRY SGdiGetTextExtent (LPCTSTR string, + int chars, + LPSIZE size); +extern "C" BOOL APIENTRY SGdiImportFont (HFONT windowsfont, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiLoadFont (LPCTSTR filename, + int filecharwidth, + int filecharheight, + int basecharwidth, + LPSIZE charsizetable, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiRectangle (LPBYTE videobuffer, + int left, + int top, + int right, + int bottom, + COLORREF color); +extern "C" BOOL APIENTRY SGdiSelectObject (HSGDIOBJ handle); +extern "C" BOOL APIENTRY SGdiSetPitch (int pitch); +extern "C" BOOL APIENTRY SGdiSetTargetDimensions (int width, + int height, + int bitdepth, + int pitch); +extern "C" BOOL APIENTRY SGdiTextOut (LPBYTE videobuffer, + int x, + int y, + COLORREF color, + LPCTSTR string, + int chars = -1); + + +/**************************************************************************** +* +* Logging functions +* +***/ + +DECLARE_STRICT_HANDLE(HSLOG); + +extern "C" void APIENTRY SLogClose (HSLOG log); +extern "C" BOOL APIENTRY SLogCreate (LPCTSTR filename, + DWORD flags, + HSLOG *log); +#ifdef STORMSTATIC +extern "C" void APIENTRY SLogDestroy (); +#endif +extern "C" void APIENTRY SLogDump (HSLOG log, + LPCVOID data, + DWORD bytes); +extern "C" void APIENTRY SLogFlush (HSLOG log); +extern "C" void APIENTRY SLogFlushAll (); +#ifdef STORMSTATIC +extern "C" void APIENTRY SLogInitialize (); +#endif +extern "C" void __cdecl SLogPend (HSLOG log, + LPCTSTR format, + ...); +extern "C" void __cdecl SLogWrite (HSLOG log, + LPCTSTR format, + ...); + + +/**************************************************************************** +* +* Memory allocation functions +* +***/ + +#define SMEM_FLAG_ZEROMEMORY 0x00000008 +#define SMEM_FLAG_PRESERVEONDESTROY 0x08000000 + +DECLARE_STRICT_HANDLE(HSHEAP); + +typedef struct _SMEMBLOCKDETAILS { + DWORD size; + LPVOID ptr; + BOOL allocated; + BOOL valid; + DWORD bytes; + DWORD overhead; +} SMEMBLOCKDETAILS, *LPSMEMBLOCKDETAILS; + +typedef struct _SMEMHEAPDETAILS { + DWORD size; + HSHEAP handle; + char filename[MAX_PATH]; + int linenumber; + DWORD regions; + DWORD committedbytes; + DWORD reservedbytes; + DWORD maximumsize; + DWORD allocatedblocks; +} SMEMHEAPDETAILS, *LPSMEMHEAPDETAILS; + +extern "C" LPVOID APIENTRY SMemAlloc (DWORD bytes, + LPCSTR filename = NULL, + int linenumber = 0, + DWORD flags = 0); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SMemDestroy (); +#endif +extern "C" BOOL APIENTRY SMemFindNextBlock (HSHEAP heap, + LPVOID prevblock, + LPVOID *nextblock, + LPSMEMBLOCKDETAILS details); +extern "C" BOOL APIENTRY SMemFindNextHeap (HSHEAP prevheap, + HSHEAP *nextheap, + LPSMEMHEAPDETAILS details); +extern "C" BOOL APIENTRY SMemFree (LPVOID ptr, + LPCSTR filename = NULL, + int linenumber = 0, + DWORD flags = 0); +extern "C" HSHEAP APIENTRY SMemGetHeapByCaller (LPCSTR filename, + int linenumber); +extern "C" HSHEAP APIENTRY SMemGetHeapByPtr (LPVOID ptr); +extern "C" LPVOID APIENTRY SMemHeapAlloc (HSHEAP handle, + DWORD flags, + DWORD bytes); +extern "C" HSHEAP APIENTRY SMemHeapCreate (DWORD options, + DWORD initialsize, + DWORD maximumsize); +extern "C" BOOL APIENTRY SMemHeapDestroy (HSHEAP handle); +extern "C" BOOL APIENTRY SMemHeapFree (HSHEAP handle, + DWORD flags, + LPVOID ptr); +#ifdef STORMSTATIC +extern "C" void APIENTRY SMemInitialize (); +#endif + +inline void __cdecl operator delete (void *ptr) { + if (ptr) + SMemFree(ptr,__FILE__,__LINE__,0); +} + +inline void * __cdecl operator new (size_t bytes) { + return SMemAlloc(bytes,__FILE__,__LINE__,0); +} + +#ifndef __ICL +#ifndef __MWERKS__ +inline void __cdecl operator delete[] (void *ptr) { + if (ptr) + SMemFree(ptr,__FILE__,__LINE__,0); +} + +inline void * __cdecl operator new[] (size_t bytes) { + return SMemAlloc(bytes,__FILE__,__LINE__,0); +} +#endif +#endif + +#ifndef __PLACEMENT_NEW_INLINE +#define __PLACEMENT_NEW_INLINE +inline void * __cdecl operator new (size_t, void *ptr) { + return (ptr); +} + +inline void * __cdecl operator new[] (size_t, void *ptr) { + return (ptr); +} +#endif + +#define ALLOC(bytes) SMemAlloc(bytes,__FILE__,__LINE__,0) +#define ALLOCZERO(bytes) SMemAlloc(bytes,__FILE__,__LINE__,SMEM_FLAG_ZEROMEMORY) +#define DEL(ptr) delete(ptr) +#define DELIFUSED(ptr) delete(ptr) +#define FREE(ptr) SMemFree(ptr,__FILE__,__LINE__,0) +#define FREEIFUSED(ptr) do if (ptr) SMemFree(ptr,__FILE__,__LINE__,0); while (0) +#define NEW(struct) (new(SMemAlloc(sizeof(struct),__FILE__,__LINE__,0)) struct) +#define NEWZERO(struct) (new(SMemAlloc(sizeof(struct),__FILE__,__LINE__,SMEM_FLAG_ZEROMEMORY)) struct) + + +/**************************************************************************** +* +* Message functions +* +***/ + +typedef struct _PARAMS { + HWND window; + UINT message; + WPARAM wparam; + LPARAM lparam; + UINT notifycode; + LPVOID extra; + BOOL useresult; + LRESULT result; +} PARAMS, *PARAMSPTR, *LPPARAMS; + +typedef BOOL (CALLBACK *SMSGIDLEPROC)(DWORD); +typedef void (CALLBACK *SMSGHANDLER)(LPPARAMS); + +extern "C" BOOL APIENTRY SMsgBreakHandlerChain (LPPARAMS params); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SMsgDestroy (); +#endif +extern "C" BOOL APIENTRY SMsgDispatchMessage (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam, + BOOL *useresult, + LRESULT *result); +extern "C" BOOL APIENTRY SMsgDoMessageLoop (SMSGIDLEPROC idleproc = NULL, + BOOL cleanuponquit = TRUE); +extern "C" BOOL APIENTRY SMsgPopRegisterState (HWND window); +extern "C" BOOL APIENTRY SMsgPushRegisterState (HWND window); +extern "C" BOOL APIENTRY SMsgRegisterCommand (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterMessage (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterCommand (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterMessage (HWND window, + UINT id, + SMSGHANDLER handler); + + +/**************************************************************************** +* +* Networking functions +* +***/ + +#define SNET_ART_BACKGROUND 0 +#define SNET_ART_BUTTONTEXTURE 1 +#define SNET_ART_JOINBACKGROUND 2 +#define SNET_ART_HELPBACKGROUND 3 +#define SNET_ART_POPUPBACKGROUND 4 +#define SNET_ART_BUTTON_XSML 5 +#define SNET_ART_BUTTON_SML 6 +#define SNET_ART_BUTTON_MED 7 +#define SNET_ART_BUTTON_LRG 8 +#define SNET_ART_APP_LOGO_SML 9 +#define SNET_ART_PROGRESS_BACKGROUND 10 +#define SNET_ART_PROGRESS_FILLER 11 +#define SNET_ART_POPUPBACKGROUND_SML 12 +#define SNET_ART_SCROLLBARARROWS 13 +#define SNET_ART_SCROLLTHUMB 14 +#define SNET_ART_SCROLLBAR 15 +#define SNET_ART_COMBOLEFT 16 +#define SNET_ART_COMBOMIDDLE 17 +#define SNET_ART_COMBORIGHT 18 + +#define SNET_AUTHTYPE_CHANNEL 1 +#define SNET_AUTHTYPE_GAME 2 + +#define SNET_BROADCASTNONLOCALPLAYERID 0xFFFFFFFE +#define SNET_BROADCASTPLAYERID 0xFFFFFFFF +#define SNET_INVALIDPLAYERID 0xFFFFFFFF + +#define SNET_CAPS_PAGELOCKEDBUFFERS 0x00000001 +#define SNET_CAPS_BASICINTERFACE 0x00000002 +#define SNET_CAPS_DEBUGONLY 0x10000000 +#define SNET_CAPS_RETAILONLY 0x20000000 + +#define SNET_CF_ALLOWPRIVATEGAMES 0x00000001 + +#define SNET_DATA_SYSCOLORS 1 +#define SNET_DATA_CURSORLINK 2 +#define SNET_DATA_CURSORARROW 3 +#define SNET_DATA_CURSORIBEAM 4 + +#define SNET_DDF_INCLUDENAME 0x00000001 +#define SNET_DDF_MULTILINE 0x00000002 + +#define SNET_DDPF_BLIZZARD 0x00000001 +#define SNET_DDPF_MODERATOR 0x00000002 +#define SNET_DDPF_SPEAKER 0x00000004 +#define SNET_DDPF_SYSOP 0x00000008 +#define SNET_DDPF_SQUELCHED 0x00000020 + +#define SNET_DRAWTYPE_GAME 1 +#define SNET_DRAWTYPE_PLAYER 2 + +#define SNET_ERROR_ALREADY_EXISTS ERROR_ALREADY_EXISTS +#define SNET_ERROR_BAD_PROVIDER ERROR_BAD_PROVIDER +#define SNET_ERROR_CANCELLED ERROR_CANCELLED +#define SNET_ERROR_INVALID_PARAMETER ERROR_INVALID_PARAMETER +#define SNET_ERROR_INVALID_PLAYER STORM_ERROR_INVALID_PLAYER +#define SNET_ERROR_GAME_ALREADY_STARTED STORM_ERROR_GAME_ALREADY_STARTED +#define SNET_ERROR_GAME_FULL STORM_ERROR_GAME_FULL +#define SNET_ERROR_GAME_NOT_FOUND STORM_ERROR_GAME_NOT_FOUND +#define SNET_ERROR_GAME_TERMINATED STORM_ERROR_GAME_TERMINATED +#define SNET_ERROR_HOST_UNREACHABLE ERROR_HOST_UNREACHABLE +#define SNET_ERROR_MAX_THRDS_REACHED ERROR_MAX_THRDS_REACHED +#define SNET_ERROR_NETWORK_BUSY ERROR_NETWORK_BUSY +#define SNET_ERROR_NO_MESSAGES_WAITING STORM_ERROR_NO_MESSAGES_WAITING +#define SNET_ERROR_NO_NETWORK ERROR_NO_NETWORK +#define SNET_ERROR_NOT_CONNECTED ERROR_NOT_CONNECTED +#define SNET_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY +#define SNET_ERROR_NOT_IMPLEMENTED STORM_ERROR_NOT_IMPLEMENTED +#define SNET_ERROR_NOT_IN_GAME STORM_ERROR_NOT_IN_GAME +#define SNET_ERROR_NOT_OWNER ERROR_NOT_OWNER +#define SNET_ERROR_NOT_REGISTERED STORM_ERROR_NOT_REGISTERED +#define SNET_ERROR_REQUIRES_UPGRADE STORM_ERROR_REQUIRES_UPGRADE +#define SNET_ERROR_STILL_ACTIVE STORM_ERROR_STILL_ACTIVE +#define SNET_ERROR_TOO_MANY_NAMES ERROR_TOO_MANY_NAMES +#define SNET_ERROR_VERSION_MISMATCH STORM_ERROR_VERSION_MISMATCH + +#define SNET_EVENT_INITDATA 1 +#define SNET_EVENT_PLAYERJOIN 2 +#define SNET_EVENT_PLAYERLEAVE 3 +#define SNET_EVENT_SERVERMESSAGE 4 + +#define SNET_EXIT_AUTO_JOINING 0x00000001 +#define SNET_EXIT_AUTO_NEWGAME 0x00000002 +#define SNET_EXIT_AUTO_SHUTDOWN 0x00000003 +#define SNET_EXIT_PLAYERQUIT 0x40000001 +#define SNET_EXIT_PLAYERKILLED 0x40000002 +#define SNET_EXIT_PLAYERWON 0x40000004 +#define SNET_EXIT_GAMEOVER 0x40000005 +#define SNET_EXIT_NOTRESPONDING 0x40000006 + +#define SNET_GM_PRIVATE 0x00000001 +#define SNET_GM_FULL 0x00000002 +#define SNET_GM_ADVERTISED 0x00000004 +#define SNET_GM_UNJOINABLE 0x00000008 +#define SNET_GM_UNLISTEDMASK (SNET_GM_PRIVATE | SNET_GM_FULL | SNET_GM_UNJOINABLE) + +#define SNET_INFO_GAMENAME 1 +#define SNET_INFO_GAMEPASSWORD 2 +#define SNET_INFO_GAMEDESCRIPTION 3 +#define SNET_INFO_GAMEMODE 4 +#define SNET_INFO_INITDATA 5 +#define SNET_INFO_MAXPLAYERS 6 + +#define SNET_LMT_EXPECTED 1 +#define SNET_LMT_CURRENT 2 +#define SNET_LMT_PEAK 4 + +#define SNET_PERFID_TURN 1 +#define SNET_PERFID_TURNSSENT 4 +#define SNET_PERFID_TURNSRECV 5 +#define SNET_PERFID_MSGSENT 6 +#define SNET_PERFID_MSGRECV 7 +#define SNET_PERFID_USERBYTESSENT 8 +#define SNET_PERFID_USERBYTESRECV 9 +#define SNET_PERFID_TOTALBYTESSENT 10 +#define SNET_PERFID_TOTALBYTESRECV 11 +#define SNET_PERFID_PKTSENTONWIRE 12 +#define SNET_PERFID_PKTRECVONWIRE 13 +#define SNET_PERFID_BYTESSENTONWIRE 14 +#define SNET_PERFID_BYTESRECVONWIRE 15 +#define SNET_PERFIDNUM 16 + +#define SNET_PERFTYPE_COUNTER 0x10410400 +#define SNET_PERFTYPE_RAWCOUNT 0x00010000 + +#define SNET_PSF_ACTIVE 0x00010000 +#define SNET_PSF_TURNAVAILABLE 0x00020000 +#define SNET_PSF_RESPONDING 0x00040000 + +#define SNET_SF_ALLOWCREATE 0x00000001 + +#define SNET_SND_CHANGEFOCUS 0 +#define SNET_SND_SELECTITEM 1 + +#define SNET_UPGRADE_FAILED -1 +#define SNET_UPGRADE_NOT_NEEDED 0 +#define SNET_UPGRADE_SUCCEEDED 1 +#define SNET_UPGRADING_TERMINATE 2 + +#define SNET_MAXNAMELENGTH 128 +#define SNET_MAXDESCLENGTH 128 + +typedef struct _SNETCAPS { + DWORD size; + DWORD flags; + DWORD maxmessagesize; + DWORD maxqueuesize; + DWORD maxplayers; + DWORD bytessec; + DWORD latencyms; + DWORD defaultturnssec; + DWORD defaultturnsintransit; +} SNETCAPS, *SNETCAPSPTR; + +typedef struct _SNETCREATEDATA { + DWORD size; + DWORD providerid; + DWORD maxplayers; + DWORD createflags; +} SNETCREATEDATA, *SNETCREATEDATAPTR; + +typedef struct _SNET_DATA_SYSCOLORTABLE { + DWORD syscolor; + COLORREF rgb; +} SNET_DATA_SYSCOLORTABLE, *SNET_DATA_SYSCOLORTABLEPTR; + +typedef struct _SNETEVENT { + DWORD eventid; + DWORD playerid; + LPVOID data; + DWORD databytes; +} SNETEVENT, *SNETEVENTPTR; + +typedef struct _SNETGAME { + DWORD size; + DWORD id; + LPCSTR gamename; + LPCSTR gamedescription; + DWORD categorybits; + DWORD numplayers; + DWORD maxplayers; +} SNETGAME, *SNETGAMEPTR; + +struct _SNETPROGRAMDATA; +struct _SNETPLAYERDATA; +struct _SNETUIDATA; +struct _SNETVERSIONDATA; + +typedef BOOL (CALLBACK *SNETABORTPROC )(); +typedef void (CALLBACK *SNETADDCATEGORYPROC )(LPCSTR,DWORD,DWORD); +typedef void (CALLBACK *SNETCATEGORYLISTPROC )(_SNETPLAYERDATA *,SNETADDCATEGORYPROC); +typedef BOOL (CALLBACK *SNETCATEGORYPROC )(BOOL,_SNETPROGRAMDATA *,_SNETPLAYERDATA *,_SNETUIDATA *,_SNETVERSIONDATA *,DWORD *,DWORD *); +typedef BOOL (CALLBACK *SNETCHECKAUTHPROC )(DWORD,LPCSTR,LPCSTR,DWORD,LPCSTR,LPSTR,DWORD); +typedef BOOL (CALLBACK *SNETCREATEPROC )(SNETCREATEDATAPTR,_SNETPROGRAMDATA *,_SNETPLAYERDATA *,_SNETUIDATA *,_SNETVERSIONDATA *,DWORD *); +typedef BOOL (CALLBACK *SNETDRAWDESCPROC )(DWORD,DWORD,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,LPDRAWITEMSTRUCT); +typedef BOOL (CALLBACK *SNETENUMDEVICESPROC )(DWORD,LPCSTR,LPCSTR); +typedef BOOL (CALLBACK *SNETENUMGAMESEXPROC )(SNETGAMEPTR); +typedef BOOL (CALLBACK *SNETENUMGAMESPROC )(DWORD,LPCSTR,LPCSTR); +typedef BOOL (CALLBACK *SNETENUMPROVIDERSPROC)(DWORD,LPCSTR,LPCSTR,SNETCAPSPTR); +typedef void (CALLBACK *SNETEVENTPROC )(SNETEVENTPTR); +typedef BOOL (CALLBACK *SNETGETARTPROC )(DWORD,DWORD,LPPALETTEENTRY,LPBYTE,DWORD,int *,int *,int *); +typedef BOOL (CALLBACK *SNETGETDATAPROC )(DWORD,DWORD,LPVOID,DWORD,DWORD *); +typedef int (CALLBACK *SNETMESSAGEBOXPROC )(HWND,LPCSTR,LPCSTR,UINT); +typedef BOOL (CALLBACK *SNETPLAYSOUNDPROC )(DWORD,DWORD,DWORD); +typedef BOOL (CALLBACK *SNETSELECTEDPROC )(DWORD,SNETCAPSPTR,_SNETUIDATA *,_SNETVERSIONDATA *); +typedef BOOL (CALLBACK *SNETSTATUSPROC )(LPCSTR,DWORD,DWORD,DWORD,SNETABORTPROC); +typedef BOOL (CALLBACK *SNETPROFILEPROC )(); // tbd -- include callback to save info +typedef BOOL (CALLBACK *SNETNEWACCOUNTPROC )(); // tbd -- include callback to try to create + +typedef struct _SNETPLAYERDATA { + DWORD size; + LPCSTR playername; + LPCSTR playerdescription; + // new for 1.05: + LPCSTR displayedfields; +} SNETPLAYERDATA, *SNETPLAYERDATAPTR; + +typedef struct _SNETPROGRAMDATA { + DWORD size; + LPCSTR programname; + LPCSTR programdescription; + DWORD programid; + DWORD versionid; + DWORD reserved1; + DWORD maxplayers; + LPVOID initdata; + DWORD initdatabytes; + LPVOID reserved2; + DWORD optcategorybits; +} SNETPROGRAMDATA, *SNETPROGRAMDATAPTR; + +typedef struct _SNETUIDATA { + DWORD size; + DWORD uiflags; + HWND parentwindow; + SNETGETARTPROC artcallback; + SNETCHECKAUTHPROC authcallback; + SNETCREATEPROC createcallback; + SNETDRAWDESCPROC drawdesccallback; + SNETSELECTEDPROC selectedcallback; + SNETMESSAGEBOXPROC messageboxcallback; + SNETPLAYSOUNDPROC soundcallback; + SNETSTATUSPROC statuscallback; + SNETGETDATAPROC getdatacallback; + SNETCATEGORYPROC categorycallback; + // new for 1.05: + SNETCATEGORYLISTPROC categorylistcallback; + SNETNEWACCOUNTPROC newaccountcallback; + SNETPROFILEPROC profilecallback; +} SNETUIDATA, *SNETUIDATAPTR; + +typedef struct _SNETVERSIONDATA { + DWORD size; + LPCSTR versionstring; + LPCSTR executablefile; + LPCSTR originalarchivefile; + LPCSTR patcharchivefile; +} SNETVERSIONDATA, *SNETVERSIONDATAPTR; + +extern "C" BOOL APIENTRY SNetCreateGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamecategorybits, + LPVOID initdata, + DWORD initdatabytes, + DWORD maxplayers, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetDestroy (); +extern "C" BOOL APIENTRY SNetDropPlayer (DWORD playerid, DWORD exitcode); +extern "C" BOOL APIENTRY SNetEnumDevices (SNETENUMDEVICESPROC callback); +extern "C" BOOL APIENTRY SNetEnumGames (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESPROC callback, + DWORD *hintnextcall); +extern "C" BOOL APIENTRY SNetEnumGamesEx (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESEXPROC callback, + DWORD *hintnextcall); +extern "C" BOOL APIENTRY SNetEnumProviders (SNETCAPSPTR mincaps, + SNETENUMPROVIDERSPROC callback); +extern "C" BOOL APIENTRY SNetGetGameInfo (DWORD index, + LPVOID buffer, + DWORD buffersize, + DWORD *byteswritten); +extern "C" BOOL APIENTRY SNetGetNetworkLatency (DWORD measurementtype, + DWORD *result); +extern "C" BOOL APIENTRY SNetGetNumPlayers (DWORD *firstplayerid, + DWORD *lastplayerid, + DWORD *activeplayers); +extern "C" BOOL APIENTRY SNetGetOwnerId (DWORD *playerid); +extern "C" BOOL APIENTRY SNetGetOwnerTurnsWaiting (DWORD *turns); +extern "C" BOOL APIENTRY SNetGetPerformanceData (DWORD counterid, + DWORD *countervalue, + DWORD *countertype, + LONG *counterscale, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq); +extern "C" BOOL APIENTRY SNetGetPlayerCaps (DWORD playerid, + SNETCAPSPTR caps); +extern "C" BOOL APIENTRY SNetGetPlayerName (DWORD playerid, + LPSTR buffer, + DWORD buffersize); +extern "C" BOOL APIENTRY SNetGetProviderCaps (SNETCAPSPTR caps); +extern "C" BOOL APIENTRY SNetGetTurnsInTransit (DWORD *turns); +extern "C" BOOL APIENTRY SNetInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +extern "C" BOOL APIENTRY SNetInitializeProvider (DWORD providerid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +extern "C" BOOL APIENTRY SNetJoinGame (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetLeaveGame (DWORD exitcode); +extern "C" BOOL APIENTRY SNetPerformUpgrade (DWORD *upgradestatus); +extern "C" BOOL APIENTRY SNetReceiveMessage (DWORD *senderplayerid, + LPVOID *data, + DWORD *databytes); +extern "C" BOOL APIENTRY SNetReceiveTurns (DWORD firstplayerid, + DWORD arraysize, + LPVOID *arraydata, + LPDWORD arraydatabytes, + LPDWORD arrayplayerstatus); +extern "C" BOOL APIENTRY SNetRegisterEventHandler (DWORD eventid, + SNETEVENTPROC callback); +extern "C" BOOL APIENTRY SNetResetLatencyMeasurements (); +extern "C" BOOL APIENTRY SNetSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetSelectProvider (SNETCAPSPTR mincaps, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *providerid); +extern "C" BOOL APIENTRY SNetSendMessage (DWORD targetplayerid, + LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SNetSendServerChatCommand (LPCSTR command); +extern "C" BOOL APIENTRY SNetSendTurn (LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SNetSetBasePlayer (DWORD playerid); +extern "C" BOOL APIENTRY SNetSetGameMode (DWORD modeflags); +extern "C" BOOL APIENTRY SNetUnregisterEventHandler (DWORD eventid, + SNETEVENTPROC callback); + + +/**************************************************************************** +* +* Networking service provider interface +* +***/ + +#define SNETSPI_MAXCLIENTDATA 256 +#define SNETSPI_MAXSTRINGLENGTH 128 + +typedef struct _SNETADDR { + BYTE address[16]; +} SNETADDR, *SNETADDRPTR; + +typedef struct _SNETSPI_DEVICELIST { + DWORD deviceid; + SNETCAPS devicecaps; + char devicename[SNETSPI_MAXSTRINGLENGTH]; + char devicedescription[SNETSPI_MAXSTRINGLENGTH]; + DWORD reserved; + _SNETSPI_DEVICELIST *next; +} SNETSPI_DEVICELIST, *SNETSPI_DEVICELISTPTR; + +typedef struct _SNETSPI_GAMELIST { + DWORD gameid; + DWORD gamemode; + DWORD creationtime; + SNETADDR owner; + DWORD ownerlatency; + DWORD ownerlasttime; + DWORD gamecategorybits; + char gamename[SNETSPI_MAXSTRINGLENGTH]; + char gamedescription[SNETSPI_MAXSTRINGLENGTH]; + _SNETSPI_GAMELIST *next; + // new for 1.05: + LPVOID clientdata; + DWORD clientdatabytes; +} SNETSPI_GAMELIST, *SNETSPI_GAMELISTPTR; + +typedef struct _SNETSPI { + DWORD size; + BOOL (CALLBACK *CompareNetAddresses)(SNETADDRPTR,SNETADDRPTR,DWORD *); + BOOL (CALLBACK *Destroy)(); + BOOL (CALLBACK *Free)(SNETADDRPTR,LPVOID,DWORD); + BOOL (CALLBACK *FreeExternalMessage)(LPCSTR,LPCSTR,LPCSTR); + BOOL (CALLBACK *GetGameInfo)(DWORD,LPCSTR,LPCSTR,SNETSPI_GAMELIST *); + BOOL (CALLBACK *GetPerformanceData)(DWORD,DWORD *,LARGE_INTEGER *,LARGE_INTEGER *); + BOOL (CALLBACK *Initialize)(SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR,HANDLE); + BOOL (CALLBACK *InitializeDevice)(DWORD,SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR); + BOOL (CALLBACK *LockDeviceList)(SNETSPI_DEVICELISTPTR *); + BOOL (CALLBACK *LockGameList)(DWORD,DWORD,SNETSPI_GAMELISTPTR *); + +/* note: this is the way that the Receive call should look... + + BOOL (CALLBACK *Receive)(SNETADDRPTR *,LPVOID *,DWORD *); + + below is the receive call with two parameters switched around + to make it incompatible with older .snp's during the beta... */ + + BOOL (CALLBACK *Receive)(LPVOID *,DWORD *,SNETADDRPTR *); + + BOOL (CALLBACK *ReceiveExternalMessage)(LPCSTR *,LPCSTR *,LPCSTR *); + BOOL (CALLBACK *SelectGame)(DWORD,SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR,DWORD *); + BOOL (CALLBACK *Send)(DWORD,SNETADDRPTR *,LPVOID,DWORD); + BOOL (CALLBACK *SendExternalMessage)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR); + BOOL (CALLBACK *StartAdvertisingGame)(LPCSTR,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCVOID,DWORD); + BOOL (CALLBACK *StopAdvertisingGame)(); + BOOL (CALLBACK *UnlockDeviceList)(SNETSPI_DEVICELISTPTR); + BOOL (CALLBACK *UnlockGameList)(SNETSPI_GAMELISTPTR,DWORD *); + // new for 1.05: + BOOL (CALLBACK *GetLocalPlayerName)(LPSTR,DWORD,LPSTR,DWORD); +} SNETSPI, *SNETSPIPTR; + +typedef BOOL (APIENTRY *SNETSPIBIND )(DWORD,SNETSPIPTR *); +typedef BOOL (APIENTRY *SNETSPIQUERY)(DWORD,DWORD *,LPCSTR *,LPCSTR *,SNETCAPSPTR *); + + +/**************************************************************************** +* +* Registry functions +* +***/ + +#define SREG_FLAG_USERSPECIFIC 0x00000001 +#define SREG_FLAG_BATTLENET 0x00000002 +#define SREG_FLAG_FLUSHTODISK 0x00000008 +#define SREG_FLAG_MULTISZ 0x00000080 + +extern "C" BOOL APIENTRY SRegGetBaseKey (DWORD flags, + LPSTR buffer, + DWORD buffersize); +extern "C" BOOL APIENTRY SRegLoadData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID buffer, + DWORD buffersize, + DWORD *bytesread); +extern "C" BOOL APIENTRY SRegLoadString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SRegLoadValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD *value); +extern "C" BOOL APIENTRY SRegSaveData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SRegSaveString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPCTSTR string); +extern "C" BOOL APIENTRY SRegSaveValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD value); + + +/**************************************************************************** +* +* Region manager functions +* +***/ + +#define SRGN_AND RGN_AND +#define SRGN_COPY RGN_COPY +#define SRGN_DIFF RGN_DIFF +#define SRGN_OR RGN_OR +#define SRGN_XOR RGN_XOR +#define SRGN_PARAMONLY 6 +#define SRGN_MIN 1 +#define SRGN_MAX 6 + +DECLARE_STRICT_HANDLE(HSRGN); + +extern "C" void APIENTRY SRgnClear (HSRGN handle); +extern "C" void APIENTRY SRgnCombineRect (HSRGN handle, + LPCRECT rect, + LPVOID param, + int combinemode); +extern "C" void APIENTRY SRgnCreate (HSRGN *handle, + DWORD reserved = 0); +extern "C" void APIENTRY SRgnDelete (HSRGN handle); +#ifdef STORMSTATIC +extern "C" void APIENTRY SRgnDestroy (); +#endif +extern "C" void APIENTRY SRgnDuplicate (HSRGN orighandle, + HSRGN *handle, + DWORD reserved = 0); +extern "C" void APIENTRY SRgnGetBoundingRect (HSRGN handle, + LPRECT rect); +extern "C" void APIENTRY SRgnGetRectParams (HSRGN handle, + LPCRECT rect, + DWORD *numparams, + LPVOID *buffer); +extern "C" void APIENTRY SRgnGetRects (HSRGN handle, + DWORD *numrects, + LPRECT buffer); + +#define SRgnAddParam(handle,rect,param) SRgnCombineRect(handle,rect,param,SRGN_PARAMONLY); +#define SRgnAddRect(handle,rect,param) SRgnCombineRect(handle,rect,param,SRGN_OR) + + +/**************************************************************************** +* +* Run-time library functions +* +***/ + +#define ONCE ONCEEXPAND(__FILE__##__##__LINE__##__once) +#define ONCEEXPAND(a) BOOL a = TRUE; a; a = FALSE + +#define TRY goto trylabel; trylabel: +#define LEAVE goto finallylabel +#define FINALLY goto finallylabel; finallylabel: + + +/**************************************************************************** +* +* String functions +* +***/ + +#define SSTR_HASH_CASESENSITIVE 0x00000001 + +#define SSTR_UNBOUNDED 0x7FFFFFFF + +extern "C" LPTSTR APIENTRY SStrChr (LPCTSTR string, + char ch, + BOOL reverse = FALSE); +extern "C" DWORD APIENTRY SStrCopy (LPTSTR dest, + LPCTSTR source, + DWORD destsize = SSTR_UNBOUNDED); +extern "C" DWORD APIENTRY SStrHash (LPCTSTR string, + DWORD flags = 0, + DWORD seed = 0); +extern "C" DWORD APIENTRY SStrLen (LPCTSTR string); +extern "C" void APIENTRY SStrPack (LPTSTR dest, + LPCTSTR source, + DWORD destsize = SSTR_UNBOUNDED); +extern "C" void APIENTRY SStrTokenize (LPCTSTR *string, + LPTSTR buffer, + DWORD bufferchars, + LPCTSTR whitespace, + BOOL *quoted = NULL); + + +/**************************************************************************** +* +* Transparency functions +* +***/ + +#define STRANS_CF_INTERSECT 0x00000001 +#define STRANS_CF_INVERTSECOND 0x00000002 +#define STRANS_CF_SUBTRACT (STRANS_CF_INTERSECT | STRANS_CF_INVERTSECOND) + +DECLARE_STRICT_HANDLE(HSTRANS); +typedef HSTRANS HTRANS; + +extern "C" BOOL APIENTRY STransBlt (LPBYTE dest, + int destx, + int desty, + int destpitch, + HSTRANS transparency); +extern "C" BOOL APIENTRY STransBltUsingMask (LPBYTE dest, + LPBYTE source, + int destpitch, + int sourcepitch, + HSTRANS mask); +extern "C" BOOL APIENTRY STransCombineMasks (HSTRANS basemask, + HSTRANS secondmask, + int offsetx, + int offsety, + DWORD flags, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateMaskE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateMaskI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransDelete (HSTRANS handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY STransDestroy (); +#endif +extern "C" BOOL APIENTRY STransDuplicate (HSTRANS source, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransIntersectDirtyArray (HSTRANS sourcemask, + LPBYTE dirtyarray, + BYTE dirtyarraymask, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransInvertMask (HSTRANS sourcemask, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransIsPixelInMask (HSTRANS mask, + int offsetx, + int offsety); +extern "C" BOOL APIENTRY STransLoadE (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransLoadI (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransSetDirtyArrayInfo (int screencx, + int screency, + int cellcx, + int cellcy); +extern "C" BOOL APIENTRY STransUpdateDirtyArray (LPBYTE dirtyarray, + BYTE dirtyvalue, + int destx, + int desty, + HSTRANS transparency, + BOOL tracecontour); + +#ifdef STRANS_USE_INCLUSIVE_RECTS +#define STransCreate STransCreateI +#define STransCreateMask STransCreateMaskI +#define STransLoad STransLoadI +#else +#define STransCreate STransCreateE +#define STransCreateMask STransCreateMaskE +#define STransLoad STransLoadE +#endif + + +/**************************************************************************** +* +* Video functions +* +***/ + +#define SVID_FLAG_DOUBLESCANS 0x00000001 +#define SVID_FLAG_INTERPOLATE 0x00000002 +#define SVID_FLAG_INTERLACE 0x00000004 +#define SVID_FLAG_AUTOQUALITY 0x00000008 +#define SVID_FLAG_1XSIZE 0x00000100 +#define SVID_FLAG_2XSIZE 0x00000200 +#define SVID_FLAG_AUTOSIZE 0x00000800 +#define SVID_FLAG_FILEHANDLE 0x00010000 +#define SVID_FLAG_PRELOAD 0x00020000 +#define SVID_FLAG_LOOP 0x00040000 +#define SVID_FLAG_FULLSCREEN 0x00080000 +#define SVID_FLAG_USECURRENTPALETTE 0x00100000 +#define SVID_FLAG_CLEARSCREEN 0x00200000 +#define SVID_FLAG_NOSKIP 0x00400000 +#define SVID_FLAG_NEEDPAN 0x02000000 +#define SVID_FLAG_NEEDVOLUME 0x04000000 +#define SVID_FLAG_TOSCREEN 0x10000000 +#define SVID_FLAG_TOBUFFER 0x20000000 + +#define SVID_CUTSCENE (SVID_FLAG_TOSCREEN | SVID_FLAG_FULLSCREEN | SVID_FLAG_CLEARSCREEN | SVID_FLAG_2XSIZE) +#define SVID_AUTOCUTSCENE (SVID_FLAG_TOSCREEN | SVID_FLAG_FULLSCREEN | SVID_FLAG_CLEARSCREEN | SVID_FLAG_AUTOSIZE | SVID_FLAG_AUTOQUALITY) + +#define SVID_QUALITY_LOW_SKIPSCANS SVID_FLAG_2XSIZE +#define SVID_QUALITY_LOW (SVID_FLAG_2XSIZE | SVID_FLAG_DOUBLESCANS) +#define SVID_QUALITY_HIGH_SKIPSCANS (SVID_FLAG_2XSIZE | SVID_FLAG_INTERPOLATE) +#define SVID_QUALITY_HIGH (SVID_FLAG_2XSIZE | SVID_FLAG_INTERPOLATE | SVID_FLAG_DOUBLESCANS) + +DECLARE_STRICT_HANDLE(HSVIDEO); + +typedef struct _SVIDPALETTEUSE { + DWORD size; + DWORD firstentry; + DWORD numentries; +} SVIDPALETTEUSE, *SVIDPALETTEUSEPTR; + +extern "C" BOOL APIENTRY SVidDestroy (); +extern "C" BOOL APIENTRY SVidGetPerformanceData (HSVIDEO video, + BOOL averageframems, + DWORD *framems, + BOOL averagepalettems, + DWORD *palettems); +extern "C" BOOL APIENTRY SVidGetSize (HSVIDEO video, + int *width, + int *height, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SVidInitialize (LPVOID directsound); +extern "C" BOOL APIENTRY SVidPlayBegin (LPCTSTR filename, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle); +extern "C" BOOL APIENTRY SVidPlayBeginFromMemory (LPVOID sourceptr, + DWORD sourcebytes, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle); +extern "C" BOOL APIENTRY SVidPlayContinue (); +extern "C" BOOL APIENTRY SVidPlayContinueSingle (HSVIDEO video, + BOOL forceupdate, + BOOL *updated); +extern "C" BOOL APIENTRY SVidPlayEnd (HSVIDEO video); +extern "C" BOOL APIENTRY SVidSetVolume (HSVIDEO video, + LONG volume, + LONG pan, + DWORD track = 0); + + +/**************************************************************************** +* +* Storm global functions +* +***/ + +extern "C" BOOL APIENTRY StormDestroy (); + +#ifdef MAC +extern "C" void StormStartup(); +extern "C" void StormShutdown(); +#endif + + +//#########################################################################// +//#########################################################################// +// // +// // +// CLASS-BASED PROGRAMMING INTERFACE // +// (under construction) // +// // +// // +//#########################################################################// +//#########################################################################// + + +/**************************************************************************** +* +* CSLog +* +***/ + +class CSLog { + + private: + HSLOG m_handle; + + public: + + //======================================================================= + CSLog (LPCTSTR filename) { + SLogCreate(filename,0,&m_handle); + } + + //======================================================================= + CSLog (LPCTSTR keyname, + LPCTSTR valuename) { + char filename[MAX_PATH] = ""; + SRegLoadString(keyname,valuename,0,filename,MAX_PATH); +#ifdef _DEBUG + SRegSaveString(keyname,valuename,0,filename); +#endif + if (filename[0]) + SLogCreate(filename,0,&m_handle); + } + + //======================================================================= + ~CSLog () { + SLogClose(m_handle); + } + + //======================================================================= + void Dump (LPCVOID data, + DWORD bytes) { + SLogDump(m_handle, + data, + bytes); + } + + //======================================================================= + void Flush () { + SLogFlush(m_handle); + } + + //======================================================================= + HSLOG GetHandle () { + return m_handle; + } + + //======================================================================= + void Pend (LPCSTR string) { + SLogPend(m_handle, + string); + } + + //======================================================================= + void Write (LPCSTR string) { + SLogWrite(m_handle, + string); + } + +}; + + +/**************************************************************************** +* +* CSRgn +* +***/ + +class CSRgn { + + private: + HSRGN m_handle; + + //======================================================================= + void CopyConstructor (const CSRgn & source) { + SRgnDuplicate(source.m_handle, + &m_handle); + } + + public: + + //======================================================================= + CSRgn () { + SRgnCreate(&m_handle); + } + + //======================================================================= + CSRgn (const CSRgn & source) { + CopyConstructor(source); + } + + //======================================================================= + ~CSRgn () { + SRgnDelete(m_handle); + } + + //======================================================================= + CSRgn & operator= (const CSRgn &source) { + if (this != &source) { + this->~CSRgn(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + void AddParam (LPCRECT rect, + LPVOID param) { + SRgnAddParam(m_handle, + rect, + param); + } + + //======================================================================= + void AddRect (LPCRECT rect, + LPVOID param) { + SRgnAddRect(m_handle, + rect, + param); + } + + //======================================================================= + void Clear () { + SRgnClear(m_handle); + } + + //======================================================================= + void CombineRect (LPCRECT rect, + LPVOID param, + int combinemode) { + SRgnCombineRect(m_handle, + rect, + param, + combinemode); + } + + //======================================================================= + void GetBoundingRect (LPRECT rect) { + SRgnGetBoundingRect(m_handle, + rect); + } + + //======================================================================= + void GetRects (DWORD *numrects, + LPRECT buffer) { + SRgnGetRects(m_handle, + numrects, + buffer); + } + + //======================================================================= + void GetRectParams (LPCRECT rect, + DWORD *numparams, + LPVOID *buffer) { + SRgnGetRectParams(m_handle, + rect, + numparams, + buffer); + } + +}; + + +//#########################################################################// +//#########################################################################// +// // +// // +// UTILITY CLASSES AND TEMPLATES // +// // +// // +//#########################################################################// +//#########################################################################// + + +/**************************************************************************** +* +* CCritSect -- Critical section class +* +* Methods: +* +* void Enter () +* void Leave () +* +***/ + +class CCritSect { + private: + CRITICAL_SECTION m_critsect; + public: + CCritSect () { InitializeCriticalSection(&m_critsect); } + ~CCritSect () { DeleteCriticalSection(&m_critsect); } + void Enter () { EnterCriticalSection(&m_critsect); } + void Enter (BOOL) { EnterCriticalSection(&m_critsect); } + void Leave () { LeaveCriticalSection(&m_critsect); } + void Leave (BOOL) { LeaveCriticalSection(&m_critsect); } +}; + + +/**************************************************************************** +* +* CLock -- Reader/writer lock class +* +* Methods: +* +* void Enter (BOOL forwriting) +* void Leave (BOOL fromwriting) +* +***/ + +class CLock { + + private: + + HANDLE m_mutexevent; + HANDLE m_readerevent; + LONG m_readercount; + + public: + + //======================================================================= + CLock () { + m_mutexevent = CreateEvent(NULL,FALSE,TRUE,NULL); + m_readerevent = CreateEvent(NULL,TRUE,FALSE,NULL); + m_readercount = -1; + } + + //======================================================================= + ~CLock () { + CloseHandle(m_readerevent); + CloseHandle(m_mutexevent); + } + + //======================================================================= + void Enter (BOOL forwriting) { + if (forwriting) + WaitForSingleObject(m_mutexevent,INFINITE); + else if (!InterlockedIncrement(&m_readercount)) { + WaitForSingleObject(m_mutexevent,INFINITE); + SetEvent(m_readerevent); + } + else + WaitForSingleObject(m_readerevent,INFINITE); + } + + //======================================================================= + void Leave (BOOL fromwriting) { + if (fromwriting) + SetEvent(m_mutexevent); + else if (InterlockedDecrement(&m_readercount) < 0) { + ResetEvent(m_readerevent); + SetEvent(m_mutexevent); + } + } + +}; + + +/**************************************************************************** +* +* CNullSync -- Null synchronization class +* +* (used for templates that take a synchronization class as a parameter) +* +***/ + +class CNullSync { + public: + void Enter (BOOL) { } + void Leave (BOOL) { } +}; + + +/**************************************************************************** +* +* type_info +* +* (used by templates to obtain the name of an object) +* +***/ + +#ifdef _MSC_VER + #ifdef _INC_TYPEINFO + #define INTERNALRAWNAME raw_name + #else + #define INTERNALRAWNAME internal_raw_name + class type_info { + public: + virtual ~type_info (); + const char * internal_raw_name () const { return _m_d_name; }; + private: + void *_m_data; + char _m_d_name[1]; + type_info (const type_info& rhs); + type_info& operator= (const type_info& rhs); + }; + #endif +#else + #if defined(MAC) && !defined(__typeinfo__) + #include + #endif + #define INTERNALRAWNAME name +#endif + + +/**************************************************************************** +* +* ARRAY -- Dynamically allocated array template +* +* Types: +* +* ARRAY(structname) -- dynamically sized array of struct +* +* Pointers to types: +* +* ARRAYPTR(structname) +* +* Array methods: +* +* void AddDiscontiguousElements (DWORD count, +* int stride, +* const *newelements); +* void AddElement (const *newelement); +* void AddElements (DWORD count, +* const *newelements); +* DWORD NumElements (); +* * NewElement (); +* * Ptr (); +* void ReserveSpace (DWORD count); +* void SetNumElements (DWORD totalcount); +* +***/ + +template +class TSArray { + + private: + DWORD m_allocchunksize; + T *m_data; + DWORD m_elements; + DWORD m_elementsalloc; + + //======================================================================= + BOOL CheckSpace (DWORD count) { + return (m_elements+count <= m_elementsalloc); + } + + //======================================================================= + void Constructor () { + m_allocchunksize = max(16,256/sizeof(T)); + m_data = NULL; + m_elements = 0; + m_elementsalloc = 0; + } + + //======================================================================= + void CopyConstructor (const TSArray & source) { + Constructor(); + m_allocchunksize = source.m_allocchunksize; + ReserveSpace(source.m_elementsalloc); + AddElements(source.m_elements, + source.m_data); + } + + public: + + //======================================================================= + TSArray () { + Constructor(); + } + + //======================================================================= + TSArray (const TSArray & source) { + CopyConstructor(source); + } + + //======================================================================= + ~TSArray () { + if (m_data) { + while (m_elements) { + --m_elements; + m_data[m_elements].~T(); + } + SMemFree(m_data,__FILE__,__LINE__,0); + m_data = NULL; + } + } + + //======================================================================= + TSArray & operator= (const TSArray &source) { + if (this != &source) { + this->~TSArray(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + T & operator[] (DWORD num) { + if (num >= m_elements) + SErrDisplayError(STORM_ERROR_ACCESS_OUT_OF_BOUNDS, + typeid(T).INTERNALRAWNAME(), + SERR_LINECODE_OBJECT, + NULL, + TRUE); + return m_data[num]; + } + + //======================================================================= + void AddDiscontiguousElements (DWORD count, + int stride, + const T *newelements) { + if (!CheckSpace(count)) + ReserveSpace(count); + if (stride == sizeof(T)) + AddElements(count,newelements); + else + for (DWORD loop = 0; loop < count; ++loop) { + new(m_data+m_elements++) T(*newelements); + newelements = (const T *)((LPBYTE)newelements+stride); + } + } + + //======================================================================= + void AddElement (const T *newelement) { + if (!CheckSpace(1)) + ReserveSpace(1); + new(m_data+m_elements++) T(*newelement); + } + + //======================================================================= + void AddElements (DWORD count, + const T *newelements) { + if (!CheckSpace(count)) + ReserveSpace(count); + for (DWORD loop = 0; loop < count; ++loop) + new(m_data+m_elements++) T(newelements[loop]); + } + + //======================================================================= + DWORD NumElements () { + return m_elements; + } + + //======================================================================= + T * NewElement () { + if (!CheckSpace(1)) + ReserveSpace(1); + return new(m_data+m_elements++) T; + } + + //======================================================================= + T * Ptr () { + if (!m_data) + ReserveSpace(1); + return m_data; + } + + //======================================================================= + void ReserveSpace (DWORD count) { + if (CheckSpace(count)) + return; + + // DETERMINE THE NUMBER OF NEW ELEMENTS TO ALLOCATE + DWORD newelements = m_elements+count; + DWORD partialchunk = newelements & (m_allocchunksize-1); + if (partialchunk) + newelements += m_allocchunksize-partialchunk; + + // ALLOCATE THE NEW ARRAY AND COPY DATA FROM THE OLD ARRAY + T *newdata = (T *)ALLOC(newelements*sizeof(T)); + if (m_data) { + for (DWORD loop = 0; loop < m_elements; ++loop) + new(newdata+loop) T(m_data[loop]); + FREE(m_data); + } + m_data = newdata; + m_elementsalloc = newelements; + + } + + //======================================================================= + void SetNumElements (DWORD totalcount) { + if (totalcount > m_elements) { + ReserveSpace(totalcount-m_elements); + for (DWORD loop = m_elements; loop < totalcount; ++loop) + new(m_data+loop) T; + } + else if (totalcount < m_elements) { + for (DWORD loop = totalcount; loop < m_elements; ++loop) + m_data[loop].~T(); + } + m_elements = totalcount; + } + +}; + +#define ARRAY(structname) TSArray< structname > +#define ARRAYDECL(structname,varname) TSArray< structname > varname +#define ARRAYPTR(structname) TSArray< structname > * + + +/**************************************************************************** +* +* NODE/LIST -- Linked list template +* +* Types: +* +* LINKEX(structname) -- explicit link field +* LIST(structname) -- linked list of implicitly linked nodes +* LISTEX(structname,linkname) -- linked list of explicitly linked nodes +* LISTEXDYN(structname) -- linked list of explicitly linked nodes, +* where the link field to be used by +* this list is not known at compile time +* NODEDECL(structname) -- implicitly linked node +* NODEDECLEX(structname) -- explicitly linked node (must contain one +* or more LINKEX fields) +* +* Pointers to types: +* +* LISTPTR(structname) +* LISTPTREX(structname) +* +* Link methods: +* +* * Next (); +* * Prev (); +* void Unlink (); +* +* Explicitly linked node methods: +* +* None. Use link methods for the link you want to manipulate. +* +* Implicitly linked node methods: +* +* * Next (); +* * Prev (); +* void Unlink (); +* +* List methods: +* +* void Clear (); +* * DeleteNode ( *ptr); +* * Head () const; +* BOOL IsEmpty () const; +* void LinkNode ( *ptr, +* DWORD linktype = LIST_TAIL, +* *existingptr = NULL); +* * NewNode (DWORD location = LIST_TAIL, +* DWORD extrabytes = 0, +* DWORD flags = 0); +* * Next (const *ptr) const; +* * Prev (const *ptr) const; +* * Tail () const; +* void UnlinkAll (); +* void UnlinkNode ( *ptr); +* +* Constants for use with LinkNode() and NewNode(): +* +* LIST_UNLINKED +* LIST_LINK_AFTER +* LIST_LINK_BEFORE +* LIST_HEAD +* LIST_TAIL +* +* Macros: +* +* LISTEXSETLINK(structname,listname,linkname) +* ITERATELIST(structname,listname,ptrname) +* ITERATELISTPTR(structname,listname,ptrname) +* ITERATEPARTIALLIST(structname,listname,start,ptrname) +* ITERATEPARTIALLISTPTR(structname,listname,start,ptrname) +* ITERATELISTREVERSE(structname,listname,ptrname) +* ITERATELISTREVERSEPTR(structname,listname,ptrname) +* ITERATEPARTIALLISTREVERSE(structname,listname,start,ptrname) +* ITERATEPARTIALLISTREVERSEPTR(structname,listname,start,ptrname) +* ITERATE_DELETE +* ITERATE_DELETEANDBREAK +* +***/ + +#define LIST_UNLINKED 0 +#define LIST_LINK_AFTER 1 +#define LIST_LINK_BEFORE 2 +#define LIST_HEAD LIST_LINK_AFTER +#define LIST_TAIL LIST_LINK_BEFORE + +template +class TSList; + +template +class TSLink { + friend class TSList; + friend class TSList; + + private: + TSLink *m_prevlink; + T *m_next; + + //======================================================================= + void Constructor () { + m_prevlink = NULL; + m_next = NULL; + } + + //======================================================================= + void CopyConstructor (const TSLink &) { + Constructor(); + } + + //======================================================================= + TSLink *NextLink () const { + + // IF THE NEXT NODE IS A TERMINATOR, ITS LINK POINTER IS THE SAME AS + // ITS NODE POINTER. + if ((int)m_next < 0) + return (TSLink *)~(DWORD)m_next; + + // OTHERWISE, COMPUTE THE LINK ADDRESS BY USING THE OFFSET OF THIS + // NODE'S LINK AND POINTER ADDRESSES. (THIS NODE MUST NOT BE A + // TERMINATOR.) + else { + DWORD linkoffset = (DWORD)this-(DWORD)(m_prevlink->m_next); + return (TSLink *)(linkoffset+(DWORD)m_next); + } + + } + + protected: + + //======================================================================= + T *NextThroughTerminator () const { + return ((int)m_next > 0) ? m_next : (T *)~(DWORD)m_next; + } + + public: + + //======================================================================= + TSLink () { + Constructor(); + } + + //======================================================================= + TSLink (const TSLink & source) { + CopyConstructor(source); + } + + //======================================================================= + ~TSLink () { + Unlink(); + } + + //======================================================================= + TSLink & operator= (const TSLink &) { + // LEAVE THE DESTINATION NODE LINKED INTO ITS CURRENT LIST + return *this; + } + + //======================================================================= + T * Next () const { + return ((int)m_next > 0) ? m_next : NULL; + } + + //======================================================================= + T * Prev () const { + return m_prevlink->m_prevlink->Next(); + } + + //======================================================================= + void Unlink () { + if (!m_prevlink) + return; + NextLink()->m_prevlink = m_prevlink; + m_prevlink->m_next = m_next; + m_prevlink = NULL; + m_next = NULL; + } + +}; + +template +class TSBaseNode { + public: + + //======================================================================= + inline void * __cdecl operator new (size_t bytes, + size_t extra, + DWORD flags) { + void *ptr = SMemAlloc(bytes+extra, + typeid(T).INTERNALRAWNAME(), + SERR_LINECODE_OBJECT, + flags | SMEM_FLAG_ZEROMEMORY); + return ptr; + } + +}; + +template +class TSExplicitNode : public TSBaseNode { + friend class TSList; + + private: + + //======================================================================= + TSLink *Link (BOOL explicitlink, int linkoffset) const { + ASSERT(explicitlink); + explicitlink; + return (TSLink *)((LPBYTE)this+linkoffset); + } + +}; + +template +class TSLinkedNode : public TSBaseNode { + friend class TSList; + + private: + TSLink m_link; + + //======================================================================= + TSLink *Link (BOOL explicitlink, int linkoffset) const { + if (explicitlink) + return (TSLink *)((LPBYTE)this+linkoffset); + else + return (TSLink *)&m_link; + } + + public: + + //======================================================================= + ~TSLinkedNode () { + Unlink(); + } + + //======================================================================= + T * Next () const { + return m_link.Next(); + } + + //======================================================================= + T * Prev () const { + return m_link.Prev(); + } + + //======================================================================= + void Unlink () { + m_link.Unlink(); + } + +}; + +template +class TSList { + + private: + int m_linkoffset; + TSLink m_terminator; + + //======================================================================= + void Constructor () { + m_linkoffset = 0; + InitializeTerminator(); + } + + //======================================================================= + void CopyConstructor (const TSList & source) { + m_linkoffset = source.m_linkoffset; + InitializeTerminator(); + } + + //======================================================================= + void InitializeTerminator () { + m_terminator.m_prevlink = &m_terminator; + m_terminator.m_next = (T *)~(DWORD)&m_terminator; + } + + //======================================================================= + TSLink *Link (const T *ptr) const { + // THIS FUNCTION CALLS THE LINK METHOD IN EITHER THE NODE OR THE LINK + // TO WHICH THIS LIST REFERS. IF THIS FUNCTION WON'T COMPILE, IT'S + // BECAUSE A NODE WITH EXPLICIT LINKS WAS DEFINED WITH NODEDECL() + // INSTEAD OF NODEDECLEX(). + return ptr->Link(explicitlink,m_linkoffset); + } + + protected: + + //======================================================================= + void SetLinkOffset (int linkoffset) { + m_linkoffset = linkoffset; + InitializeTerminator(); + } + + public: + + //======================================================================= + TSList () { + Constructor(); + }; + + //======================================================================= + TSList (const TSList &source) { + CopyConstructor(source); + }; + + //======================================================================= + TSList (int linkoffset) { + m_linkoffset = linkoffset; + InitializeTerminator(); + }; + + //======================================================================= + ~TSList () { + UnlinkAll(); + } + + //======================================================================= + TSList & operator= (const TSList &source) { + if (this != &source) { + this->~TSList(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + void ChangeLinkOffset (int linkoffset) { + UnlinkAll(); + SetLinkOffset(linkoffset); + } + + //======================================================================= + void Clear () { + T *curr; + while ((curr = Head()) != NULL) + delete curr; + } + + //======================================================================= + T * DeleteNode (T *ptr) { + T *nextptr = Next(ptr); + delete ptr; + return nextptr; + } + + //======================================================================= + T * Head () const { + return m_terminator.Next(); + } + + //======================================================================= + BOOL IsEmpty () const { + return !m_terminator.Next(); + } + + //======================================================================= + T * Iterate_RawNext (const T *ptr) const { + return Link(ptr)->m_next; + } + + //======================================================================= + void LinkNode (T *ptr, + DWORD linktype = LIST_TAIL, + T *existingptr = NULL) { + TSLink *link = Link(ptr); + + // IF THIS NODE IS ALREADY LINKED INTO THE LIST, UNLINK IT + if (link->m_prevlink) + link->Unlink(); + + // FIND THE NODE THAT WE WILL LINK BEFORE OR AFTER. USE THE + // TERMINATOR NODE IF WE'RE LINKING ONTO THE HEAD OR TAIL. + TSLink *existinglink; + if (existingptr) + existinglink = Link(existingptr); + else + existinglink = &m_terminator; + + // LINK THIS NODE INTO THE LIST + switch (linktype) { + + case LIST_LINK_AFTER: + { + link->m_prevlink = existinglink; + link->m_next = existinglink->m_next; + Link(existinglink->NextThroughTerminator())->m_prevlink = link; + existinglink->m_next = ptr; + } + break; + + case LIST_LINK_BEFORE: + { + TSLink *prevlink = existinglink->m_prevlink; + link->m_prevlink = prevlink; + link->m_next = prevlink->m_next; + prevlink->m_next = ptr; + existinglink->m_prevlink = link; + } + break; + + } + } + + //======================================================================= + T * NewNode (DWORD location = LIST_TAIL, + DWORD extrabytes = 0, + DWORD flags = 0) { + T *ptr = new(extrabytes,flags) T; + if (location != LIST_UNLINKED) + LinkNode(ptr,location); + return ptr; + } + + //======================================================================= + T * Next (const T *ptr) const { + return Link(ptr)->Next(); + } + + //======================================================================= + T * Prev (const T *ptr) const { + return Link(ptr)->Prev(); + } + + //======================================================================= + T * Tail () const { + return m_terminator.Prev(); + } + + //======================================================================= + void UnlinkAll () { + T *curr; + while ((curr = Head()) != NULL) + UnlinkNode(curr); + } + + //======================================================================= + void UnlinkNode (T *ptr) { + Link(ptr)->Unlink(); + } + +}; + +template +class TSExplicitList : public TSList { + public: + + //======================================================================= + TSExplicitList () { + SetLinkOffset(linkoffset); + } + +}; + + +#define LINKEX(structname) TSLink< structname > +#define LINKDECLEX(structname,varname) TSLink< structname > varname +#define LIST(structname) TSList< structname ,FALSE> +#define LISTDECL(structname,varname) TSList< structname ,FALSE> varname +#define LISTPTR(structname) TSList< structname ,FALSE> * +#define LISTPTREX(structname) TSList< structname ,TRUE> * +#define NODEDECL(structname) typedef struct structname : public TSLinkedNode< structname > +#define NODEDECLEX(structname) typedef struct structname : public TSExplicitNode< structname > + +#define LISTEX(structname,linkname) \ + TSExplicitList< structname ,(int)&(((structname *)0)->linkname)> + +#define LISTEXDYN(structname) \ + TSExplicitList< structname ,(int)0xDDDDDDDD> + +#define LISTEXSETLINK(structname,listname,linkname) \ + listname.ChangeLinkOffset((int)&(((structname *)0)->linkname)); + +#define LISTDECLEX(structname,linkname,varname) \ + TSExplicitList< structname ,(int)&(((structname *)0)->linkname)> varname + +#define ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,op) \ + for (structname *ptrname = start, \ + *iterate_delete = NULL; \ + (int)ptrname > 0; \ + iterate_delete \ + ? (ptrname = (listname)##op##DeleteNode(ptrname), \ + ptrname = ((int)iterate_delete > 0) ? ptrname : NULL, \ + iterate_delete = NULL, \ + ptrname) \ + : ptrname = (listname)##op##Iterate_RawNext(ptrname)) + +#define ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,op) \ + for (structname *ptrname = start, \ + *iterate_delete = NULL, \ + *iterate_delete_temp = NULL; \ + ptrname; \ + iterate_delete \ + ? (iterate_delete_temp = ((int)iterate_delete > 0) \ + ? (listname)##op##Prev(ptrname) \ + : NULL, \ + (listname)##op##DeleteNode(ptrname), \ + iterate_delete = NULL, \ + ptrname = iterate_delete_temp) \ + : ptrname = (listname)##op##Prev(ptrname)) + +#define ITERATELIST(structname,listname,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,(listname).Head(),ptrname,.) + +#define ITERATELISTPTR(structname,listname,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,(listname)->Head(),ptrname,->) + +#define ITERATEPARTIALLIST(structname,listname,start,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,.) + +#define ITERATEPARTIALLISTPTR(structname,listname,start,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,->) + +#define ITERATELISTREVERSE(structname,listname,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,(listname).Tail(),ptrname,.) + +#define ITERATELISTREVERSEPTR(structname,listname,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,(listname)->Tail(),ptrname,->) + +#define ITERATEPARTIALLISTREVERSE(structname,listname,start,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,.) + +#define ITERATEPARTIALLISTREVERSEPTR(structname,listname,start,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,->) + +#define ITERATE_DELETE \ + { \ + ++iterate_delete; \ + continue; \ + } + +#define ITERATE_DELETEANDBREAK \ + { \ + --iterate_delete; \ + continue; \ + } + + +/**************************************************************************** +* +* EXPORTOBJECT/EXPORTTABLE -- Export manager template +* +* Types: +* +* DECLARE_STRICT_HANDLE(handle) -- handle to object +* DECLARE_STRICT_HANDLE(lockedhandle) -- handle to locked object +* EXPORTOBJECTDECL(structname) -- object to be exported +* EXPORTTABLE(structname,handlename,lockedhandlename,synctype) +* EXPORTTABLEREUSE(structname,handlename,lockedhandlename,synctype) +* +* Export table methods: +* +* void Delete ( handle); +* void DeleteUnlock ( *ptr, +* lockedhandle); +* void Destroy (); +* * Lock ( handle, +* *lockedhandle, +* BOOL forwriting = FALSE); +* void New ( *handle); +* * NewLock ( *handle, +* *lockedhandle); +* void Unlock ( lockedhandle); +* +* Synchronization types for use with EXPORTTABLE(): +* +* SYNC_NONE -- use no synchronization +* SYNC_READWRITE -- use a reader/writer lock +* SYNC_ALWAYS -- use a critical section +* +***/ + +template +class TSExportTableBase { + + protected: + + //======================================================================= + T * BaseFindByHandle (LISTPTREX(T) list, unsigned handle) { + ITERATELISTPTR(T,list,curr) + if (curr->m_handle == handle) + return curr; + return NULL; + } + + //======================================================================= + T * BaseFindByHandleEx (LISTPTREX(T) list, unsigned handle, unsigned *count) { + *count = 0; + ITERATELISTPTR(T,list,curr) + if (curr->m_handle == handle) + return curr; + else + ++*count; + return NULL; + } + + //======================================================================= + unsigned BaseGetHandle (const T *ptr) { + return ptr->m_handle; + } + + //======================================================================= + int BaseGetLinkOffset () { + return (int)&(((T *)0)->m_linktoslot); + } + + //======================================================================= + void BaseSetHandle (T *ptr, unsigned handle) { + ptr->m_handle = handle; + } + +}; + +template +class TSExportTable : public TSExportTableBase { + + private: + ARRAY(LISTEXDYN(T)) m_listarray; + LISTEXDYN(T) m_reuselist; + H m_sequence; + unsigned m_slotmask; + SYNC m_sync; + + //======================================================================= + unsigned ComputeSlot (H handle) { + return (unsigned)handle & m_slotmask; + } + + //======================================================================= + H GenerateUniqueHandle () { + unsigned count; + for (;;) { + m_sequence = (H)((unsigned)m_sequence+1); + if (!BaseFindByHandleEx(&m_listarray[ComputeSlot(m_sequence)], + (unsigned)m_sequence, + &count)) + break; + } + if (count >= 4) + GrowListArray(); + return m_sequence; + } + + //======================================================================= + void GrowListArray () { +return; // note: out for testing + if (m_slotmask >= 1023) + return; + + // DETERMINE THE NEW ARRAY SIZE + unsigned oldarraysize = m_slotmask+1; + unsigned newarraysize = oldarraysize*2; + + // GROW THE ARRAY + { + m_listarray.SetNumElements(newarraysize); + int linkoffset = BaseGetLinkOffset(); + for (unsigned slot = oldarraysize; slot < newarraysize; ++slot) + m_listarray[slot].ChangeLinkOffset(linkoffset); + } + + // MOVE ALL RECORDS FROM THE OLD LISTS TO THE NEW LISTS + m_slotmask = newarraysize-1; + { + for (unsigned slot = 0; slot < oldarraysize; ++slot) { + T *currptr = m_listarray[slot].Head(); + while (currptr) { + T *nextptr = m_listarray[slot].Next(currptr); + unsigned newslot = ComputeSlot((H)BaseGetHandle(currptr)); + if (newslot != slot) { + m_listarray[slot].UnlinkNode(currptr); + m_listarray[newslot].LinkNode(currptr); + } + currptr = nextptr; + } + } + } + + } + + //======================================================================= + BOOL IsForWriting (LH lockedhandle) { + return (lockedhandle == (LH)1); + } + + //======================================================================= + void SyncEnterLock (LH *lockedhandle, BOOL forwriting) { + m_sync.Enter(forwriting); + *lockedhandle = (LH)(forwriting ? 1 : -1); + } + + //======================================================================= + void SyncLeaveLock (LH lockedhandle) { + if (lockedhandle) + m_sync.Leave(IsForWriting(lockedhandle)); + } + + public: + + //======================================================================= + TSExportTable () { + m_sequence = (H)0; + m_slotmask = 3; + m_listarray.SetNumElements(m_slotmask+1); + int linkoffset = BaseGetLinkOffset(); + for (unsigned slot = 0; slot <= m_slotmask; ++slot) + m_listarray[slot].ChangeLinkOffset(linkoffset); + m_reuselist.ChangeLinkOffset(linkoffset); + } + + //======================================================================= + ~TSExportTable () { + Destroy(); + } + + //======================================================================= + void Delete (H handle) { + LH lockedhandle; + T *ptr = Lock(handle,&lockedhandle,TRUE); + DeleteUnlock(ptr,lockedhandle); + } + + //======================================================================= + void DeleteUnlock (T *ptr, + LH lockedhandle) { + if (ptr) + if (REUSE) + m_reuselist.LinkNode(ptr); + else + delete ptr; + Unlock(lockedhandle); + } + + //======================================================================= + void Destroy () { + LH lockedhandle; + SyncEnterLock(&lockedhandle,TRUE); + for (unsigned slot = 0; slot <= m_slotmask; ++slot) { + T *curr; + while ((curr = m_listarray[slot].Head()) != NULL) { + delete curr; + SErrReportResourceLeak(typeid(H).INTERNALRAWNAME()); + } + } + m_reuselist.Clear(); + SyncLeaveLock(lockedhandle); + } + + //======================================================================= + T * Lock (H handle, + LH *lockedhandle, + BOOL forwriting = FALSE) { + SyncEnterLock(lockedhandle,forwriting); + T *result = BaseFindByHandle(&m_listarray[ComputeSlot(handle)], + (unsigned)handle); + if (!result) { + SyncLeaveLock(*lockedhandle); + *lockedhandle = (LH)0; + } + return result; + } + + //======================================================================= + void New (H *handle) { + LH lockedhandle; + NewLock(handle,&lockedhandle); + Unlock(lockedhandle); + } + + //======================================================================= + T * NewLock (H *handle, LH *lockedhandle) { + SyncEnterLock(lockedhandle,TRUE); + H newhandle = GenerateUniqueHandle(); + T *ptr = NULL; + if (REUSE) { + ptr = m_reuselist.Head(); + if (ptr) + m_listarray[ComputeSlot(newhandle)].LinkNode(ptr); + } + if (!ptr) + ptr = m_listarray[ComputeSlot(newhandle)].NewNode(); + BaseSetHandle(ptr,(unsigned)newhandle); + *handle = newhandle; + return ptr; + } + + //======================================================================= + void Unlock (LH lockedhandle) { + SyncLeaveLock(lockedhandle); + } + +}; + +template +class TSExportObject : public TSExplicitNode { + friend class TSExportTableBase; + + private: + unsigned m_handle; + LINKEX(T) m_linktoslot; + + public: + + //======================================================================= + TSExportObject () { + } + + //======================================================================= + TSExportObject (const TSExportObject &source) { + } + + //======================================================================= + TSExportObject & operator= (const TSExportObject &source) { + // COPY THE OBJECT DATA, BUT DON'T OVERWRITE THE DESTINATION OBJECT'S + // HANDLE OR LINK + return *this; + } + +}; + +#define SYNC_NONE CNullSync +#define SYNC_READWRITE CLock +#define SYNC_ALWAYS CCritSect + +#define EXPORTOBJECTDECL(structname) \ + typedef struct structname : public TSExportObject< structname > + +#define EXPORTTABLE(structname,handlename,lockedhandlename,synctype) \ + TSExportTable + +#define EXPORTTABLEREUSE(structname,handlename,lockedhandlename,synctype) \ + TSExportTable + + +/**************************************************************************** +* +* SWAP -- Swap template +* +* Macros: +* +* SWAP(a,b) +* +***/ + +//=========================================================================== +template +void inline TSSwap (T &a, T &b) { + T temp = a; + a = b; + b = temp; +} +#define SWAP(a,b) TSSwap(a,b) + + +/**************************************************************************** +* +* Old TList Template -- Obsolete!! +* +***/ + +//=========================================================================== +template +BOOL inline TListAdd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return FALSE; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber,0); + if (!newptr) + return FALSE; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = *head; + *head = newptr; + return TRUE; +} +#define LISTADD(a,b) TListAdd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddEnd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return FALSE; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber,0); + if (!newptr) + return FALSE; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = NULL; + + T **next = head; + while (*next) + next = &(*next)->next; + *next = newptr; + + return TRUE; +} +#define LISTADDEND(a,b) TListAddEnd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddPtr (T **head, T *ptr) { + if (!(head && ptr)) + return FALSE; + + ptr->next = *head; + *head = ptr; + return TRUE; +} +#define LISTADDPTR(a,b) TListAddPtr(a,b) + +//=========================================================================== +template +BOOL inline TListAddPtrEnd (T **head, T *ptr) { + if (!(head && ptr)) + return FALSE; + + ptr->next = NULL; + T **next = head; + while (*next) + next = &(*next)->next; + *next = ptr; + + return TRUE; +} +#define LISTADDPTREND(a,b) TListAddPtrEnd(a,b) + +//=========================================================================== +template +BOOL inline TListClear (T **head, LPCSTR filename = NULL, int linenumber = 0) { + if (!head) + return FALSE; + + while (*head) { + T *next = (*head)->next; + SMemFree(*head,filename,linenumber,0); + *head = next; + } + return TRUE; +} +#define LISTCLEAR(a) TListClear(a,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFree (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return FALSE; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + SMemFree(ptr,filename,linenumber,0); + return (*next != NULL); +} +#define LISTFREE(a,b) TListFree(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFreePtr (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return FALSE; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + return (*next != NULL); +} +#define LISTFREEPTR(a,b) TListFreePtr(a,b,(LPCSTR)__FILE__,__LINE__) + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import off +#endif + +#endif // ifndef _STORM_H_ diff --git a/Storm/H/STORM.H b/Storm/H/STORM.H new file mode 100644 index 0000000..6cd505a --- /dev/null +++ b/Storm/H/STORM.H @@ -0,0 +1,3335 @@ +#ifndef _STORM_H_ +#define _STORM_H_ + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +#include + + +//#########################################################################// +//#########################################################################// +// // +// // +// STANDARD PROGRAMMING INTERFACE // +// // +// // +//#########################################################################// +//#########################################################################// + + +#define DECLARE_STRICT_HANDLE(name) typedef struct name##__ { int unused; } *name +#define DECLARE_DERIVED_HANDLE(name,base) typedef struct name##__ : public base##__ { int unused; } *name + + +/**************************************************************************** +* +* Error codes +* (Error text is defined in Stormerr.mc) +* +***/ + +#define STORMFAC 0x510 +#define STORMERROR(code) (0x80000000 | (STORMFAC << 16) | ((code) & 0xFFFF)) + +#define STORM_ERROR_ASSERTION STORMERROR(0) +#define STORM_ERROR_BAD_ARGUMENT STORMERROR(101) +#define STORM_ERROR_GAME_ALREADY_STARTED STORMERROR(102) +#define STORM_ERROR_GAME_FULL STORMERROR(103) +#define STORM_ERROR_GAME_NOT_FOUND STORMERROR(104) +#define STORM_ERROR_GAME_TERMINATED STORMERROR(105) +#define STORM_ERROR_INVALID_PLAYER STORMERROR(106) +#define STORM_ERROR_NO_MESSAGES_WAITING STORMERROR(107) +#define STORM_ERROR_NOT_ARCHIVE STORMERROR(108) +#define STORM_ERROR_NOT_ENOUGH_ARGUMENTS STORMERROR(109) +#define STORM_ERROR_NOT_IMPLEMENTED STORMERROR(110) +#define STORM_ERROR_NOT_IN_ARCHIVE STORMERROR(111) +#define STORM_ERROR_NOT_IN_GAME STORMERROR(112) +#define STORM_ERROR_NOT_INITIALIZED STORMERROR(113) +#define STORM_ERROR_NOT_PLAYING STORMERROR(114) +#define STORM_ERROR_NOT_REGISTERED STORMERROR(115) +#define STORM_ERROR_REQUIRES_CODEC STORMERROR(116) +#define STORM_ERROR_REQUIRES_DDRAW STORMERROR(117) +#define STORM_ERROR_REQUIRES_DSOUND STORMERROR(118) +#define STORM_ERROR_REQUIRES_UPGRADE STORMERROR(119) +#define STORM_ERROR_STILL_ACTIVE STORMERROR(120) +#define STORM_ERROR_VERSION_MISMATCH STORMERROR(121) +#define STORM_ERROR_MEMORY_ALREADY_FREED STORMERROR(122) +#define STORM_ERROR_MEMORY_CORRUPT STORMERROR(123) +#define STORM_ERROR_MEMORY_INVALID_BLOCK STORMERROR(124) +#define STORM_ERROR_MEMORY_MANAGER_INACTIVE STORMERROR(125) +#define STORM_ERROR_MEMORY_NEVER_RELEASED STORMERROR(126) +#define STORM_ERROR_HANDLE_NEVER_RELEASED STORMERROR(127) +#define STORM_ERROR_ACCESS_OUT_OF_BOUNDS STORMERROR(128) +#define STORM_ERROR_MEMORY_NULL_POINTER STORMERROR(129) + + +/**************************************************************************** +* +* BitBlt functions +* +***/ + +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SBltDestroy (); +#endif +extern "C" BOOL APIENTRY SBltGetSCode (DWORD rop3, + LPSTR buffer, + DWORD buffersize, + BOOL optimize = 1); +extern "C" BOOL APIENTRY SBltROP3 (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + DWORD pattern, + DWORD rop3); +extern "C" BOOL APIENTRY SBltROP3Clipped (LPBYTE dest, + LPRECT destrect, + LPSIZE destsize, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + LPSIZE sourcesize, + int sourcepitch, + DWORD pattern, + DWORD rop3); +extern "C" BOOL APIENTRY SBltROP3Tiled (LPBYTE dest, + LPRECT destrect, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + int sourcepitch, + int sourceoffsetx, + int sourceoffsety, + DWORD pattern, + DWORD rop3); + + +/**************************************************************************** +* +* Bitmap functions +* +***/ + +#define SBMP_IMAGETYPE_AUTO 0 +#define SBMP_IMAGETYPE_BMP 1 +#define SBMP_IMAGETYPE_PCX 2 + +typedef LPVOID (APIENTRY *SBMPALLOCPROC)(DWORD); + +extern "C" BOOL APIENTRY SBmpAllocLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE *returnedbuffer, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL, + int requestedbitdepth = 0, + SBMPALLOCPROC allocproc = NULL); +extern "C" BOOL APIENTRY SBmpDecodeImage (DWORD imagetype, + LPBYTE imagedata, + DWORD imagebytes, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SBmpLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width = NULL, + int *height = NULL, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SBmpSaveImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + int width, + int height, + int bitdepth); + + +/**************************************************************************** +* +* Command line parsing functions +* +***/ + +#define SCMD_ARG_FLAGGED (0 << 24) +#define SCMD_ARG_OPTIONAL (1 << 24) +#define SCMD_ARG_REQUIRED (2 << 24) +#define SCMD_ARG_MASK (SCMD_ARG_FLAGGED | SCMD_ARG_OPTIONAL | SCMD_ARG_REQUIRED) + +#define SCMD_BOOL_SET 0 +#define SCMD_BOOL_CLEAR 1 +#define SCMD_BOOL_MASK (SCMD_BOOL_CLEAR | SCMD_BOOL_SET) + +#define SCMD_CASESENSITIVE (0x01 << 8) + +#define SCMD_NUM_UNSIGNED 0 +#define SCMD_NUM_SIGNED 1 +#define SCMD_NUM_MASK (SCMD_NUM_UNSIGNED | SCMD_NUM_SIGNED) + +#define SCMD_TYPE_BOOL (0 << 16) +#define SCMD_TYPE_NUMERIC (1 << 16) +#define SCMD_TYPE_STRING (2 << 16) +#define SCMD_TYPE_MASK (SCMD_TYPE_BOOL | SCMD_TYPE_NUMERIC | SCMD_TYPE_STRING) + +#define SCMD_ERROR_BAD_ARGUMENT STORM_ERROR_BAD_ARGUMENT +#define SCMD_ERROR_NOT_ENOUGH_ARGUMENTS STORM_ERROR_NOT_ENOUGH_ARGUMENTS +#define SCMD_ERROR_OPEN_FAILED ERROR_OPEN_FAILED + +typedef struct _CMDERROR { + DWORD errorcode; + LPCTSTR itemstr; + LPCTSTR errorstr; +} CMDERROR, *CMDERRORPTR; + +typedef struct _CMDPARAMS { + DWORD flags; + DWORD id; + LPCTSTR name; + LPVOID variable; + DWORD setvalue; + DWORD setmask; + union { + BOOL boolvalue; + LONG signedvalue; + DWORD unsignedvalue; + LPCTSTR stringvalue; + }; +} CMDPARAMS, *CMDPARAMSPTR; + +typedef BOOL (CALLBACK *SCMDCALLBACK)(CMDPARAMSPTR,LPCTSTR); +typedef void (CALLBACK *SCMDERRORCALLBACK)(CMDERRORPTR); +typedef BOOL (CALLBACK *SCMDEXTRACALLBACK)(LPCTSTR); + +typedef struct _ARGLIST { + DWORD flags; + DWORD id; + LPCTSTR name; + SCMDCALLBACK callback; +} ARGLIST, *ARGLISTPTR; + +extern "C" BOOL APIENTRY SCmdCheckId (DWORD id); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SCmdDestroy (); +#endif +extern "C" BOOL APIENTRY SCmdGetBool (DWORD id); +extern "C" DWORD APIENTRY SCmdGetNum (DWORD id); +extern "C" BOOL APIENTRY SCmdGetString (DWORD id, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SCmdProcess (LPCTSTR cmdline, + BOOL skipprogname, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback); +extern "C" BOOL APIENTRY SCmdRegisterArgList (const ARGLIST *listptr, + DWORD numargs); +extern "C" BOOL APIENTRY SCmdRegisterArgument (DWORD flags, + DWORD id, + LPCTSTR name, + LPVOID variableptr = NULL, + DWORD variablebytes = 0, + DWORD setvalue = TRUE, + DWORD setmask = 0xFFFFFFFF, + SCMDCALLBACK callback = NULL); + +#define SCmdProcessCommandLine(ext,err) SCmdProcess(GetCommandLine(),TRUE,(ext),(err)) + +#define ARGBOOL(flags,name,var,callback) SCmdRegisterArgument(SCMD_TYPE_BOOL | (flags),0xFFFFFFFF,name,var,sizeof(var),TRUE,0xFFFFFFFF,callback) +#define ARGFLAG(flags,name,var,valuecallback) SCmdRegisterArgument(SCMD_TYPE_BOOL | (flags),0xFFFFFFFF,name,var,sizeof(var),value,value,callback) +#define ARGNUMBER(flags,name,var,callback) SCmdRegisterArgument(SCMD_TYPE_NUMERIC | (flags),0xFFFFFFFF,name,var,sizeof(var),0,0,callback) +#define ARGSTRING(flags,name,buffer,chars,callback) SCmdRegisterArgument(SCMD_TYPE_STRING | (flags),0xFFFFFFFF,name,buffer,(chars),0,0,callback) + + +/**************************************************************************** +* +* S-Code functions +* +***/ + +#define SCODE_CF_AUTOALIGNDWORD 0x00040000 +#define SCODE_CF_USESALTADJUSTS 0x04000000 + +DECLARE_STRICT_HANDLE(HSCODESTREAM); + +typedef struct _SCODEEXECUTEDATA { + DWORD size; + DWORD flags; + int xiterations; + int yiterations; + int adjustdest; + int adjustsource; + LPVOID dest; + LPVOID source; + LPVOID table; + DWORD a; + DWORD b; + DWORD c; + int adjustdestalt; + int adjustsourcealt; + DWORD reserved[2]; +} SCODEEXECUTEDATA, *SCODEEXECUTEDATAPTR; + +extern "C" BOOL APIENTRY SCodeCompile (LPCSTR prologstring, + LPCSTR loopstring, + LPCSTR *firsterror, + DWORD maxiterations, + DWORD flags, + HSCODESTREAM *handle); +extern "C" BOOL APIENTRY SCodeDelete (HSCODESTREAM handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SCodeDestroy (); +#endif +extern "C" BOOL APIENTRY SCodeExecute (HSCODESTREAM handle, + SCODEEXECUTEDATAPTR executedata); +extern "C" BOOL APIENTRY SCodeGetJumpTable (HSCODESTREAM handle, + LPBYTE **jumptableptr, + LPDWORD *prologpatchlocation, + LPDWORD *looppatchlocation, + LPDWORD *epilogpatchlocation); +extern "C" BOOL APIENTRY SCodeGetPseudocode (LPCSTR scodestring, + LPSTR buffer, + DWORD buffersize); + + +/**************************************************************************** +* +* Compression functions +* +***/ + +#define SCOMP_HINT_NONE 0 +#define SCOMP_HINT_BINARY 1 +#define SCOMP_HINT_TEXT 2 +#define SCOMP_HINT_EXECUTABLE 3 +#define SCOMP_HINT_ADPCM4 4 +#define SCOMP_HINT_ADPCM6 5 +#define SCOMP_HINTS 6 + +#define SCOMP_OPT_DEFAULT 0 +#define SCOMP_OPT_COMPRESSION 1 +#define SCOMP_OPT_SPEED 2 +#define SCOMP_OPT_QUALITY 3 + +#define SCOMP_TYPE_HUFFMAN 0x01 +#define SCOMP_TYPE_PKWARE 0x08 +#define SCOMP_TYPE_LOSSY_ADPCM_MONO 0x10 +#define SCOMP_TYPE_LOSSY_ADPCM_STEREO 0x20 + +extern "C" BOOL APIENTRY SCompCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD compressiontypes, + DWORD hint, + DWORD optimization); +extern "C" BOOL APIENTRY SCompDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize); + + +/**************************************************************************** +* +* Dialog box functions +* +***/ + +#define SDLG_ADJUST_NONE 0 +#define SDLG_ADJUST_VERTICAL 1 +#define SDLG_ADJUST_CONTROLPOS 2 + +#define SDLG_DBF_TILE 0x00000001 +#define SDLG_DBF_VCENTER 0x00000002 + +#define SDLG_STYLE_ANY 0xFFFFFFFF +#define SDLG_STYLE_ANYPUSHBUTTON 0x00010001 + +#define SDLG_USAGE_BACKGROUND 0x00000001 +#define SDLG_USAGE_NORMAL_UNFOCUSED 0x00000010 +#define SDLG_USAGE_NORMAL_FOCUSED 0x00000020 +#define SDLG_USAGE_NORMAL (SDLG_USAGE_NORMAL_UNFOCUSED | SDLG_USAGE_NORMAL_FOCUSED) +#define SDLG_USAGE_SELECTED_UNFOCUSED 0x00000040 +#define SDLG_USAGE_SELECTED_FOCUSED 0x00000080 +#define SDLG_USAGE_SELECTED (SDLG_USAGE_SELECTED_UNFOCUSED | SDLG_USAGE_SELECTED_FOCUSED) +#define SDLG_USAGE_NORMAL_GRAYED 0x00000100 +#define SDLG_USAGE_SELECTED_GRAYED 0x00000400 +#define SDLG_USAGE_GRAYED (SDLG_USAGE_NORMAL_GRAYED | SDLG_USAGE_SELECTED_GRAYED) +#define SDLG_USAGE_CURSORMASK 0x00001000 +#define SDLG_USAGE_CURSORIMAGE 0x00002000 + +extern "C" BOOL APIENTRY SDirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter); + +extern "C" HDC APIENTRY SDlgBeginPaint (HWND window, LPPAINTSTRUCT ps); +extern "C" BOOL APIENTRY SDlgBltToWindowE (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey = 0xFFFFFFFF, + DWORD pattern = 0, + DWORD rop3 = SRCCOPY); +extern "C" BOOL APIENTRY SDlgBltToWindowI (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey = 0xFFFFFFFF, + DWORD pattern = 0, + DWORD rop3 = SRCCOPY); +extern "C" BOOL APIENTRY SDlgCheckTimers (); +extern "C" HWND APIENTRY SDlgCreateDialogIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" HWND APIENTRY SDlgCreateDialogParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" BOOL APIENTRY SDlgDefDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SDlgDestroy (); +#endif +extern "C" int APIENTRY SDlgDialogBoxIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" int APIENTRY SDlgDialogBoxParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam); +extern "C" BOOL APIENTRY SDlgDrawBitmap (HWND window, + DWORD usage, + HRGN region, + int offsetx = 0, + int offsety = 0, + LPRECT boundingoffset = NULL, + DWORD flags = 0); +extern "C" BOOL APIENTRY SDlgEndDialog (HWND window, + int result); +extern "C" BOOL APIENTRY SDlgEndPaint (HWND window, LPPAINTSTRUCT ps); +extern "C" BOOL APIENTRY SDlgKillTimer (HWND window, + UINT event); +extern "C" BOOL APIENTRY SDlgSetBaseFont (int pointsize, + int weight, + DWORD flags, + DWORD family, + LPCTSTR face); +extern "C" BOOL APIENTRY SDlgSetBitmapE (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetBitmapI (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetControlBitmaps (HWND parentwindow, + LPINT controllist, + LPDWORD usagelist, + LPBYTE bitmapbits, + LPSIZE bitmapsize, + DWORD adjusttype, + COLORREF colorkey = 0xFFFFFFFF); +extern "C" BOOL APIENTRY SDlgSetCursor (HWND window, + HCURSOR cursor, + DWORD id, + HCURSOR *oldcursor); +extern "C" BOOL APIENTRY SDlgSetSystemCursor (LPBYTE maskbitmap, + LPBYTE imagebitmap, + LPSIZE size, + DWORD id = 32512); +extern "C" BOOL APIENTRY SDlgSetTimer (HWND window, + UINT event, + UINT elapse, + TIMERPROC timerfunc); +extern "C" BOOL APIENTRY SDlgUpdateCursor (); + +#define SDlgCreateDialog(ins,tpl,wnd,prc) SDlgCreateDialogParam(ins,tpl,wnd,prc,0) +#define SDlgCreateDialogIndirect(ins,tpl,wnd,prc) SDlgCreateDialogIndirectParam(ins,tpl,wnd,prc,0) +#define SDlgDialogBox(ins,tpl,wnd,prc) SDlgDialogBoxParam(ins,tpl,wnd,prc,0) +#define SDlgDialogBoxIndirect(ins,tpl,wnd,prc) SDlgDialogBoxIndirectParam(ins,tpl,wnd,prc,0) + +#ifdef SDLG_USE_INCLUSIVE_RECTS +#define SDlgBltToWindow SDlgBltToWindowI +#define SDlgSetBitmap SDlgSetBitmapI +#else +#define SDlgBltToWindow SDlgBltToWindowE +#define SDlgSetBitmap SDlgSetBitmapE +#endif + +/**************************************************************************** +* +* DirectDraw functions +* +***/ + +#define SDRAW_SERVICE_BASIC 1 +#define SDRAW_SERVICE_PAGEFLIP 2 +#define SDRAW_SERVICE_DOUBLEBUFFER 3 +#define SDRAW_SERVICE_MAX 3 + +#define SDRAW_SURFACE_FRONT 0 +#define SDRAW_SURFACE_BACK 1 +#define SDRAW_SURFACE_SYSTEM 2 +#define SDRAW_SURFACE_TEMPORARY 3 + +#ifndef MAC +extern "C" BOOL APIENTRY SDrawAutoInitialize (HINSTANCE instance, + LPCTSTR classname, + LPCTSTR title, + WNDPROC wndproc = NULL, + int servicelevel = SDRAW_SERVICE_BASIC, + int width = 640, + int height = 480, + int bitdepth = 8); +extern "C" BOOL APIENTRY SDrawCaptureScreen (LPCTSTR filename = NULL); +#endif +extern "C" BOOL APIENTRY SDrawClearSurface (int surfacenumber); +extern "C" BOOL APIENTRY SDrawDestroy (); +extern "C" BOOL APIENTRY SDrawFlipPage (); +extern "C" HWND APIENTRY SDrawGetFrameWindow (HWND *window = NULL); +#ifdef __DDRAW_INCLUDED__ +extern "C" BOOL APIENTRY SDrawGetObjects (LPDIRECTDRAW *directdraw, + LPDIRECTDRAWSURFACE *frontbuffer, + LPDIRECTDRAWSURFACE *backbuffer, + LPDIRECTDRAWSURFACE *systembuffer, + LPDIRECTDRAWSURFACE *temporarybuffer, + LPDIRECTDRAWPALETTE *palette, + HPALETTE *gdipalette); +#endif +extern "C" BOOL APIENTRY SDrawGetScreenSize (int *width, + int *height, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SDrawGetServiceLevel (int *servicelevel = NULL); +extern "C" BOOL APIENTRY SDrawLockSurface (int surfacenumber, + LPCRECT rect, + LPBYTE *ptr, + int *pitch = NULL, + DWORD flags = 0); +#ifdef __DDRAW_INCLUDED__ +extern "C" BOOL APIENTRY SDrawManualInitialize (HWND framewindow, + LPDIRECTDRAW directdraw, + LPDIRECTDRAWSURFACE frontbuffer, + LPDIRECTDRAWSURFACE backbuffer, + LPDIRECTDRAWSURFACE systembuffer, + LPDIRECTDRAWSURFACE temporarybuffer, + LPDIRECTDRAWPALETTE palette, + HPALETTE gdipalette); +#endif +extern "C" int APIENTRY SDrawMessageBox (LPCTSTR text, + LPCTSTR title, + UINT flags); +extern "C" BOOL APIENTRY SDrawPostClose (); +extern "C" BOOL APIENTRY SDrawRealizePalette (); +#ifndef MAC +extern "C" BOOL APIENTRY SDrawSelectGdiSurface (BOOL select, BOOL copy); +#endif +extern "C" BOOL APIENTRY SDrawUnlockSurface (int surfacenumber, + LPBYTE ptr, + DWORD numrects = 0, + LPCRECT rectarray = NULL); +extern "C" BOOL APIENTRY SDrawUpdatePalette (DWORD firstentry, + DWORD numentries, + LPPALETTEENTRY entries, + BOOL reservedentries = FALSE); +extern "C" BOOL APIENTRY SDrawUpdateScreen (LPCRECT rect); +#ifdef MAC +extern "C" BOOL APIENTRY SDrawVidDriverInitialize (HWND framewindow, + int servicelevel); +#endif + + +/**************************************************************************** +* +* Error handling functions +* +***/ + +#define SERR_LINECODE_FUNCTION -1 +#define SERR_LINECODE_OBJECT -2 +#define SERR_LINECODE_HANDLE -3 +#define SERR_LINECODE_FILE -4 + +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SErrDestroy (); +#endif +extern "C" BOOL APIENTRY SErrDisplayError (DWORD errorcode, + LPCTSTR filename, + int linenumber, + LPCTSTR description, + BOOL recoverable, + UINT exitcode = 1); +extern "C" BOOL APIENTRY SErrGetErrorStr (DWORD errorcode, + LPTSTR buffer, + DWORD bufferchars); +extern "C" DWORD APIENTRY SErrGetLastError (); +extern "C" BOOL APIENTRY SErrRegisterMessageSource (WORD facility, + HMODULE module, + LPVOID reserved = NULL); +extern "C" void APIENTRY SErrReportResourceLeak (LPCTSTR handlename); +extern "C" void APIENTRY SErrSetLastError (DWORD errorcode); +extern "C" void APIENTRY SErrSuppressErrors (BOOL suppress); + +#define SErrGetLastErrorStr(buf,len) SErrGetErrorStr(SErrGetLastError(),buf,len) +#define FATALRESULT(str) SErrDisplayError(SErrGetLastError(),str,SERR_LINECODE_FUNCTION,NULL,FALSE) +#define REPORTRESOURCELEAK(handle) SErrReportResourceLeak(#handle) + +#ifdef _DEBUG +#define ASSERT(a) if (!(a)) \ + SErrDisplayError(STORM_ERROR_ASSERTION, \ + __FILE__, \ + __LINE__, \ + #a, \ + FALSE) +#define VALIDATEBEGIN do { +#define VALIDATE(a) ASSERT(a) +#define VALIDATEANDBLANK(a) do { \ + ASSERT(a); \ + *(a) = 0; \ + } while (0) +#define VALIDATEEND } while (0) +#define VALIDATEENDVOID } while (0) +#else +#define ASSERT(a) +#define VALIDATEBEGIN do { \ + int intrn_valresult = -1 +#define VALIDATE(a) intrn_valresult &= (a) ? -1 : 0 +#define VALIDATEANDBLANK(a) if (a) \ + *a = 0; \ + else \ + intrn_valresult = 0 +#define VALIDATEEND if (!intrn_valresult) { \ + SErrSetLastError( \ + ERROR_INVALID_PARAMETER); \ + return 0; \ + } \ + } while (0) +#define VALIDATEENDVOID if (!intrn_valresult) { \ + SErrSetLastError( \ + ERROR_INVALID_PARAMETER); \ + return; \ + } \ + } while (0) +#endif + + +/**************************************************************************** +* +* Event dispatching functions +* +***/ + +typedef void (CALLBACK *SEVTHANDLER)(LPVOID); + +extern "C" BOOL APIENTRY SEvtBreakHandlerChain (LPVOID data); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SEvtDestroy (); +#endif +extern "C" BOOL APIENTRY SEvtDispatch (DWORD type, + DWORD subtype, + DWORD id, + LPVOID data); +extern "C" BOOL APIENTRY SEvtPopState (DWORD type, + DWORD subtype); +extern "C" BOOL APIENTRY SEvtPushState (DWORD type, + DWORD subtype); +extern "C" BOOL APIENTRY SEvtRegisterHandler (DWORD type, + DWORD subtype, + DWORD id, + DWORD flags, + SEVTHANDLER handler); +extern "C" BOOL APIENTRY SEvtUnregisterHandler (DWORD type, + DWORD subtype, + DWORD id, + SEVTHANDLER handler); +extern "C" BOOL APIENTRY SEvtUnregisterType (DWORD type, + DWORD subtype); + + +/**************************************************************************** +* +* File I/O functions +* +***/ + +#define SFILE_AUTH_UNABLETOAUTHENTICATE 0 +#define SFILE_AUTH_NOSIGNATURE 1 +#define SFILE_AUTH_BADSIGNATURE 2 +#define SFILE_AUTH_UNKNOWNSIGNATURE 3 +#define SFILE_AUTH_FIRSTAUTHENTIC 5 +#define SFILE_AUTH_AUTHENTICBLIZZARD 5 + +#define SFILE_DDA_LOOP 0x00040000 + +#define SFILE_ERROR_BAD_FORMAT ERROR_BAD_FORMAT +#define SFILE_ERROR_BAD_PATHNAME ERROR_BAD_PATHNAME +#define SFILE_ERROR_CALL_NOT_IMPLEMENTED ERROR_CALL_NOT_IMPLEMENTED +#define SFILE_ERROR_FILE_INVALID ERROR_FILE_INVALID +#define SFILE_ERROR_FILE_NOT_FOUND ERROR_FILE_NOT_FOUND +#define SFILE_ERROR_HANDLE_EOF ERROR_HANDLE_EOF +#define SFILE_ERROR_INVALID_DATA ERROR_INVALID_DATA +#define SFILE_ERROR_INVALID_DRIVE ERROR_INVALID_DRIVE +#define SFILE_ERROR_INVALID_HANDLE ERROR_INVALID_HANDLE +#define SFILE_ERROR_INVALID_PARAMETER ERROR_INVALID_PARAMETER +#define SFILE_ERROR_NOT_ARCHIVE STORM_ERROR_NOT_ARCHIVE +#define SFILE_ERROR_NOT_AUTHENTICATED ERROR_NOT_AUTHENTICATED +#define SFILE_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY +#define SFILE_ERROR_NOT_IN_ARCHIVE STORM_ERROR_NOT_IN_ARCHIVE +#define SFILE_ERROR_NOT_INITIALIZED STORM_ERROR_NOT_INITIALIZED +#define SFILE_ERROR_NOT_PLAYING STORM_ERROR_NOT_PLAYING + +#define SFILE_ERRORMODE_RETURNCODE 0 +#define SFILE_ERRORMODE_CUSTOM 1 +#define SFILE_ERRORMODE_FATAL 2 + +#define SFILE_FIND_FILES 0x00000001 +#define SFILE_FIND_DIRECTORIES 0x00000002 + +DECLARE_STRICT_HANDLE(HSARCHIVE); +DECLARE_STRICT_HANDLE(HSFILE); + +typedef BOOL (CALLBACK *SFILEERRORPROC)(LPCTSTR,DWORD); + +extern "C" BOOL APIENTRY SFileAuthenticateArchive (HSARCHIVE archive, + DWORD *extendedresult); +extern "C" BOOL APIENTRY SFileCloseArchive (HSARCHIVE handle); +extern "C" BOOL APIENTRY SFileCloseFile (HSFILE handle); +extern "C" BOOL APIENTRY SFileDdaBegin (HSFILE handle, + DWORD buffersize, + DWORD flags); +extern "C" BOOL APIENTRY SFileDdaBeginEx (HSFILE handle, + DWORD buffersize, + DWORD flags, + DWORD offset, + LONG volume, + LONG pan, + LPVOID reserved); +extern "C" BOOL APIENTRY SFileDdaDestroy (); +extern "C" BOOL APIENTRY SFileDdaEnd (HSFILE handle); +extern "C" BOOL APIENTRY SFileDdaGetPos (HSFILE handle, + DWORD *position, + DWORD *maxposition); +extern "C" BOOL APIENTRY SFileDdaGetVolume (HSFILE handle, + LONG *volume, + LONG *pan); +#ifdef __DSOUND_INCLUDED__ +extern "C" BOOL APIENTRY SFileDdaInitialize (LPDIRECTSOUND directsound); +#endif +extern "C" BOOL APIENTRY SFileDdaSetVolume (HSFILE handle, + LONG volume, + LONG pan); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SFileDestroy (); +#endif +extern "C" BOOL APIENTRY SFileEnableDirectAccess (BOOL enable); +extern "C" BOOL APIENTRY SFileGetArchiveInfo (HSARCHIVE archive, + int *priority, + BOOL *cdrom); +extern "C" BOOL APIENTRY SFileGetArchiveName (HSARCHIVE archive, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SFileGetBasePath (LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SFileGetFileArchive (HSFILE file, + HSARCHIVE *archive); +extern "C" BOOL APIENTRY SFileGetFileName (HSFILE file, + LPTSTR buffer, + DWORD bufferchars); +extern "C" DWORD APIENTRY SFileGetFileSize (HSFILE handle, + LPDWORD filesizehigh = NULL); +extern "C" BOOL APIENTRY SFileOpenArchive (LPCTSTR archivename, + int priority, + BOOL cdonly, + HSARCHIVE *handle); +extern "C" BOOL APIENTRY SFileOpenFile (LPCTSTR filename, + HSFILE *handle); +extern "C" BOOL APIENTRY SFileOpenFileEx (HSARCHIVE archivehandle, + LPCTSTR filename, + DWORD flags, + HSFILE *handle); +extern "C" BOOL APIENTRY SFileReadFile (HSFILE handle, + LPVOID buffer, + DWORD bytestoread, + LPDWORD bytesread = NULL, + LPOVERLAPPED overlapped = NULL); +extern "C" BOOL APIENTRY SFileSetBasePath (LPCTSTR path); +extern "C" DWORD APIENTRY SFileSetFilePointer (HSFILE handle, + LONG distancetomove, + PLONG distancetomovehigh, + DWORD movemethod); +extern "C" BOOL APIENTRY SFileSetIoErrorMode (DWORD errormode, + SFILEERRORPROC errorproc = NULL); +extern "C" BOOL APIENTRY SFileSetLocale (LCID lcid); + + +/**************************************************************************** +* +* GDI functions +* +***/ + +#define ETO_TEXT_TRANSPARENT 0 +#define ETO_TEXT_COLOR 1 +#define ETO_TEXT_BLACK 2 +#define ETO_TEXT_WHITE 3 +#define ETO_BKG_TRANSPARENT 0 +#define ETO_BKG_COLOR 1 +#define ETO_BKG_BLACK 2 +#define ETO_BKG_WHITE 3 + +DECLARE_STRICT_HANDLE(HSGDIOBJ); +DECLARE_DERIVED_HANDLE(HSGDIFONT,HSGDIOBJ); + +extern "C" BOOL APIENTRY SGdiBitBlt (LPBYTE videobuffer, + int destx, + int desty, + LPBYTE sourcedata, + LPRECT sourcerect, + int sourcecx, + int sourcecy, + COLORREF color = 0, + DWORD rop = SRCCOPY); +extern "C" BOOL APIENTRY SGdiCreateFont (LPBYTE bits, + int width, + int height, + int bitdepth, + int filecharwidth, + int filecharheight, + LPSIZE charsizetable, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiDeleteObject (HSGDIOBJ handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SGdiDestroy (); +#endif +extern "C" BOOL APIENTRY SGdiExtTextOut (LPBYTE videobuffer, + int x, + int y, + LPRECT rect, + COLORREF color, + int textcoloruse, + int bkgcoloruse, + LPCTSTR string, + int chars = -1); +extern "C" BOOL APIENTRY SGdiGetTextExtent (LPCTSTR string, + int chars, + LPSIZE size); +extern "C" BOOL APIENTRY SGdiImportFont (HFONT windowsfont, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiLoadFont (LPCTSTR filename, + int filecharwidth, + int filecharheight, + int basecharwidth, + LPSIZE charsizetable, + HSGDIFONT *handle); +extern "C" BOOL APIENTRY SGdiRectangle (LPBYTE videobuffer, + int left, + int top, + int right, + int bottom, + COLORREF color); +extern "C" BOOL APIENTRY SGdiSelectObject (HSGDIOBJ handle); +extern "C" BOOL APIENTRY SGdiSetPitch (int pitch); +extern "C" BOOL APIENTRY SGdiSetTargetDimensions (int width, + int height, + int bitdepth, + int pitch); +extern "C" BOOL APIENTRY SGdiTextOut (LPBYTE videobuffer, + int x, + int y, + COLORREF color, + LPCTSTR string, + int chars = -1); + + +/**************************************************************************** +* +* Logging functions +* +***/ + +DECLARE_STRICT_HANDLE(HSLOG); + +extern "C" void APIENTRY SLogClose (HSLOG log); +extern "C" BOOL APIENTRY SLogCreate (LPCTSTR filename, + DWORD flags, + HSLOG *log); +#ifdef STORMSTATIC +extern "C" void APIENTRY SLogDestroy (); +#endif +extern "C" void APIENTRY SLogDump (HSLOG log, + LPCVOID data, + DWORD bytes); +extern "C" void APIENTRY SLogFlush (HSLOG log); +extern "C" void APIENTRY SLogFlushAll (); +#ifdef STORMSTATIC +extern "C" void APIENTRY SLogInitialize (); +#endif +extern "C" void __cdecl SLogPend (HSLOG log, + LPCTSTR format, + ...); +extern "C" void __cdecl SLogWrite (HSLOG log, + LPCTSTR format, + ...); + + +/**************************************************************************** +* +* Memory allocation functions +* +***/ + +#define SMEM_FLAG_ZEROMEMORY 0x00000008 +#define SMEM_FLAG_PRESERVEONDESTROY 0x08000000 + +DECLARE_STRICT_HANDLE(HSHEAP); + +typedef struct _SMEMBLOCKDETAILS { + DWORD size; + LPVOID ptr; + BOOL allocated; + BOOL valid; + DWORD bytes; + DWORD overhead; +} SMEMBLOCKDETAILS, *LPSMEMBLOCKDETAILS; + +typedef struct _SMEMHEAPDETAILS { + DWORD size; + HSHEAP handle; + char filename[MAX_PATH]; + int linenumber; + DWORD regions; + DWORD committedbytes; + DWORD reservedbytes; + DWORD maximumsize; + DWORD allocatedblocks; +} SMEMHEAPDETAILS, *LPSMEMHEAPDETAILS; + +extern "C" LPVOID APIENTRY SMemAlloc (DWORD bytes, + LPCSTR filename = NULL, + int linenumber = 0, + DWORD flags = 0); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SMemDestroy (); +#endif +extern "C" BOOL APIENTRY SMemFindNextBlock (HSHEAP heap, + LPVOID prevblock, + LPVOID *nextblock, + LPSMEMBLOCKDETAILS details); +extern "C" BOOL APIENTRY SMemFindNextHeap (HSHEAP prevheap, + HSHEAP *nextheap, + LPSMEMHEAPDETAILS details); +extern "C" BOOL APIENTRY SMemFree (LPVOID ptr, + LPCSTR filename = NULL, + int linenumber = 0, + DWORD flags = 0); +extern "C" HSHEAP APIENTRY SMemGetHeapByCaller (LPCSTR filename, + int linenumber); +extern "C" HSHEAP APIENTRY SMemGetHeapByPtr (LPVOID ptr); +extern "C" LPVOID APIENTRY SMemHeapAlloc (HSHEAP handle, + DWORD flags, + DWORD bytes); +extern "C" HSHEAP APIENTRY SMemHeapCreate (DWORD options, + DWORD initialsize, + DWORD maximumsize); +extern "C" BOOL APIENTRY SMemHeapDestroy (HSHEAP handle); +extern "C" BOOL APIENTRY SMemHeapFree (HSHEAP handle, + DWORD flags, + LPVOID ptr); +#ifdef STORMSTATIC +extern "C" void APIENTRY SMemInitialize (); +#endif + +inline void __cdecl operator delete (void *ptr) { + if (ptr) + SMemFree(ptr,__FILE__,__LINE__,0); +} + +inline void * __cdecl operator new (size_t bytes) { + return SMemAlloc(bytes,__FILE__,__LINE__,0); +} + +#ifndef __ICL +#ifndef __MWERKS__ +inline void __cdecl operator delete[] (void *ptr) { + if (ptr) + SMemFree(ptr,__FILE__,__LINE__,0); +} + +inline void * __cdecl operator new[] (size_t bytes) { + return SMemAlloc(bytes,__FILE__,__LINE__,0); +} +#endif +#endif + +#ifndef __PLACEMENT_NEW_INLINE +#define __PLACEMENT_NEW_INLINE +inline void * __cdecl operator new (size_t, void *ptr) { + return (ptr); +} + +inline void * __cdecl operator new[] (size_t, void *ptr) { + return (ptr); +} +#endif + +#define ALLOC(bytes) SMemAlloc(bytes,__FILE__,__LINE__,0) +#define ALLOCZERO(bytes) SMemAlloc(bytes,__FILE__,__LINE__,SMEM_FLAG_ZEROMEMORY) +#define DEL(ptr) delete(ptr) +#define DELIFUSED(ptr) delete(ptr) +#define FREE(ptr) SMemFree(ptr,__FILE__,__LINE__,0) +#define FREEIFUSED(ptr) do if (ptr) SMemFree(ptr,__FILE__,__LINE__,0); while (0) +#define NEW(struct) (new(SMemAlloc(sizeof(struct),__FILE__,__LINE__,0)) struct) +#define NEWZERO(struct) (new(SMemAlloc(sizeof(struct),__FILE__,__LINE__,SMEM_FLAG_ZEROMEMORY)) struct) + + +/**************************************************************************** +* +* Message functions +* +***/ + +typedef struct _PARAMS { + HWND window; + UINT message; + WPARAM wparam; + LPARAM lparam; + UINT notifycode; + LPVOID extra; + BOOL useresult; + LRESULT result; +} PARAMS, *PARAMSPTR, *LPPARAMS; + +typedef BOOL (CALLBACK *SMSGIDLEPROC)(DWORD); +typedef void (CALLBACK *SMSGHANDLER)(LPPARAMS); + +extern "C" BOOL APIENTRY SMsgBreakHandlerChain (LPPARAMS params); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY SMsgDestroy (); +#endif +extern "C" BOOL APIENTRY SMsgDispatchMessage (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam, + BOOL *useresult, + LRESULT *result); +extern "C" BOOL APIENTRY SMsgDoMessageLoop (SMSGIDLEPROC idleproc = NULL, + BOOL cleanuponquit = TRUE); +extern "C" BOOL APIENTRY SMsgPopRegisterState (HWND window); +extern "C" BOOL APIENTRY SMsgPushRegisterState (HWND window); +extern "C" BOOL APIENTRY SMsgRegisterCommand (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgRegisterMessage (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterCommand (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler); +extern "C" BOOL APIENTRY SMsgUnregisterMessage (HWND window, + UINT id, + SMSGHANDLER handler); + + +/**************************************************************************** +* +* Networking functions +* +***/ + +#define SNET_ART_BACKGROUND 0 +#define SNET_ART_BUTTONTEXTURE 1 +#define SNET_ART_JOINBACKGROUND 2 +#define SNET_ART_HELPBACKGROUND 3 +#define SNET_ART_POPUPBACKGROUND 4 +#define SNET_ART_BUTTON_XSML 5 +#define SNET_ART_BUTTON_SML 6 +#define SNET_ART_BUTTON_MED 7 +#define SNET_ART_BUTTON_LRG 8 +#define SNET_ART_APP_LOGO_SML 9 +#define SNET_ART_PROGRESS_BACKGROUND 10 +#define SNET_ART_PROGRESS_FILLER 11 +#define SNET_ART_POPUPBACKGROUND_SML 12 +#define SNET_ART_SCROLLBARARROWS 13 +#define SNET_ART_SCROLLTHUMB 14 +#define SNET_ART_SCROLLBAR 15 +#define SNET_ART_COMBOLEFT 16 +#define SNET_ART_COMBOMIDDLE 17 +#define SNET_ART_COMBORIGHT 18 + +#define SNET_AUTHTYPE_CHANNEL 1 +#define SNET_AUTHTYPE_GAME 2 + +#define SNET_BROADCASTNONLOCALPLAYERID 0xFFFFFFFE +#define SNET_BROADCASTPLAYERID 0xFFFFFFFF +#define SNET_INVALIDPLAYERID 0xFFFFFFFF + +#define SNET_CAPS_PAGELOCKEDBUFFERS 0x00000001 +#define SNET_CAPS_BASICINTERFACE 0x00000002 +#define SNET_CAPS_DEBUGONLY 0x10000000 +#define SNET_CAPS_RETAILONLY 0x20000000 + +#define SNET_CF_ALLOWPRIVATEGAMES 0x00000001 + +#define SNET_DATA_SYSCOLORS 1 +#define SNET_DATA_CURSORLINK 2 +#define SNET_DATA_CURSORARROW 3 +#define SNET_DATA_CURSORIBEAM 4 + +#define SNET_DDF_INCLUDENAME 0x00000001 +#define SNET_DDF_MULTILINE 0x00000002 + +#define SNET_DDPF_BLIZZARD 0x00000001 +#define SNET_DDPF_MODERATOR 0x00000002 +#define SNET_DDPF_SPEAKER 0x00000004 +#define SNET_DDPF_SYSOP 0x00000008 +#define SNET_DDPF_SQUELCHED 0x00000020 + +#define SNET_DRAWTYPE_GAME 1 +#define SNET_DRAWTYPE_PLAYER 2 + +#define SNET_ERROR_ALREADY_EXISTS ERROR_ALREADY_EXISTS +#define SNET_ERROR_BAD_PROVIDER ERROR_BAD_PROVIDER +#define SNET_ERROR_CANCELLED ERROR_CANCELLED +#define SNET_ERROR_INVALID_PARAMETER ERROR_INVALID_PARAMETER +#define SNET_ERROR_INVALID_PLAYER STORM_ERROR_INVALID_PLAYER +#define SNET_ERROR_GAME_ALREADY_STARTED STORM_ERROR_GAME_ALREADY_STARTED +#define SNET_ERROR_GAME_FULL STORM_ERROR_GAME_FULL +#define SNET_ERROR_GAME_NOT_FOUND STORM_ERROR_GAME_NOT_FOUND +#define SNET_ERROR_GAME_TERMINATED STORM_ERROR_GAME_TERMINATED +#define SNET_ERROR_HOST_UNREACHABLE ERROR_HOST_UNREACHABLE +#define SNET_ERROR_MAX_THRDS_REACHED ERROR_MAX_THRDS_REACHED +#define SNET_ERROR_NETWORK_BUSY ERROR_NETWORK_BUSY +#define SNET_ERROR_NO_MESSAGES_WAITING STORM_ERROR_NO_MESSAGES_WAITING +#define SNET_ERROR_NO_NETWORK ERROR_NO_NETWORK +#define SNET_ERROR_NOT_CONNECTED ERROR_NOT_CONNECTED +#define SNET_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY +#define SNET_ERROR_NOT_IMPLEMENTED STORM_ERROR_NOT_IMPLEMENTED +#define SNET_ERROR_NOT_IN_GAME STORM_ERROR_NOT_IN_GAME +#define SNET_ERROR_NOT_OWNER ERROR_NOT_OWNER +#define SNET_ERROR_NOT_REGISTERED STORM_ERROR_NOT_REGISTERED +#define SNET_ERROR_REQUIRES_UPGRADE STORM_ERROR_REQUIRES_UPGRADE +#define SNET_ERROR_STILL_ACTIVE STORM_ERROR_STILL_ACTIVE +#define SNET_ERROR_TOO_MANY_NAMES ERROR_TOO_MANY_NAMES +#define SNET_ERROR_VERSION_MISMATCH STORM_ERROR_VERSION_MISMATCH + +#define SNET_EVENT_INITDATA 1 +#define SNET_EVENT_PLAYERJOIN 2 +#define SNET_EVENT_PLAYERLEAVE 3 +#define SNET_EVENT_SERVERMESSAGE 4 + +#define SNET_EXIT_AUTO_JOINING 0x00000001 +#define SNET_EXIT_AUTO_NEWGAME 0x00000002 +#define SNET_EXIT_AUTO_SHUTDOWN 0x00000003 +#define SNET_EXIT_PLAYERQUIT 0x40000001 +#define SNET_EXIT_PLAYERKILLED 0x40000002 +#define SNET_EXIT_PLAYERWON 0x40000004 +#define SNET_EXIT_GAMEOVER 0x40000005 +#define SNET_EXIT_NOTRESPONDING 0x40000006 + +#define SNET_GM_PRIVATE 0x00000001 +#define SNET_GM_FULL 0x00000002 +#define SNET_GM_ADVERTISED 0x00000004 +#define SNET_GM_UNJOINABLE 0x00000008 +#define SNET_GM_UNLISTEDMASK (SNET_GM_PRIVATE | SNET_GM_FULL | SNET_GM_UNJOINABLE) + +#define SNET_INFO_GAMENAME 1 +#define SNET_INFO_GAMEPASSWORD 2 +#define SNET_INFO_GAMEDESCRIPTION 3 +#define SNET_INFO_GAMEMODE 4 +#define SNET_INFO_INITDATA 5 +#define SNET_INFO_MAXPLAYERS 6 + +#define SNET_LMT_EXPECTED 1 +#define SNET_LMT_CURRENT 2 +#define SNET_LMT_PEAK 4 + +#define SNET_PERFID_TURN 1 +#define SNET_PERFID_TURNSSENT 4 +#define SNET_PERFID_TURNSRECV 5 +#define SNET_PERFID_MSGSENT 6 +#define SNET_PERFID_MSGRECV 7 +#define SNET_PERFID_USERBYTESSENT 8 +#define SNET_PERFID_USERBYTESRECV 9 +#define SNET_PERFID_TOTALBYTESSENT 10 +#define SNET_PERFID_TOTALBYTESRECV 11 +#define SNET_PERFID_PKTSENTONWIRE 12 +#define SNET_PERFID_PKTRECVONWIRE 13 +#define SNET_PERFID_BYTESSENTONWIRE 14 +#define SNET_PERFID_BYTESRECVONWIRE 15 +#define SNET_PERFIDNUM 16 + +#define SNET_PERFTYPE_COUNTER 0x10410400 +#define SNET_PERFTYPE_RAWCOUNT 0x00010000 + +#define SNET_PSF_ACTIVE 0x00010000 +#define SNET_PSF_TURNAVAILABLE 0x00020000 +#define SNET_PSF_RESPONDING 0x00040000 + +#define SNET_SF_ALLOWCREATE 0x00000001 + +#define SNET_SND_CHANGEFOCUS 0 +#define SNET_SND_SELECTITEM 1 + +#define SNET_UPGRADE_FAILED -1 +#define SNET_UPGRADE_NOT_NEEDED 0 +#define SNET_UPGRADE_SUCCEEDED 1 +#define SNET_UPGRADING_TERMINATE 2 + +#define SNET_MAXNAMELENGTH 128 +#define SNET_MAXDESCLENGTH 128 + +typedef struct _SNETCAPS { + DWORD size; + DWORD flags; + DWORD maxmessagesize; + DWORD maxqueuesize; + DWORD maxplayers; + DWORD bytessec; + DWORD latencyms; + DWORD defaultturnssec; + DWORD defaultturnsintransit; +} SNETCAPS, *SNETCAPSPTR; + +typedef struct _SNETCREATEDATA { + DWORD size; + DWORD providerid; + DWORD maxplayers; + DWORD createflags; +} SNETCREATEDATA, *SNETCREATEDATAPTR; + +typedef struct _SNET_DATA_SYSCOLORTABLE { + DWORD syscolor; + COLORREF rgb; +} SNET_DATA_SYSCOLORTABLE, *SNET_DATA_SYSCOLORTABLEPTR; + +typedef struct _SNETEVENT { + DWORD eventid; + DWORD playerid; + LPVOID data; + DWORD databytes; +} SNETEVENT, *SNETEVENTPTR; + +typedef struct _SNETGAME { + DWORD size; + DWORD id; + LPCSTR gamename; + LPCSTR gamedescription; + DWORD categorybits; + DWORD numplayers; + DWORD maxplayers; +} SNETGAME, *SNETGAMEPTR; + +struct _SNETPROGRAMDATA; +struct _SNETPLAYERDATA; +struct _SNETUIDATA; +struct _SNETVERSIONDATA; + +typedef BOOL (CALLBACK *SNETABORTPROC )(); +typedef void (CALLBACK *SNETADDCATEGORYPROC )(LPCSTR,DWORD,DWORD); +typedef void (CALLBACK *SNETCATEGORYLISTPROC )(_SNETPLAYERDATA *,SNETADDCATEGORYPROC); +typedef BOOL (CALLBACK *SNETCATEGORYPROC )(BOOL,_SNETPROGRAMDATA *,_SNETPLAYERDATA *,_SNETUIDATA *,_SNETVERSIONDATA *,DWORD *,DWORD *); +typedef BOOL (CALLBACK *SNETCHECKAUTHPROC )(DWORD,LPCSTR,LPCSTR,DWORD,LPCSTR,LPSTR,DWORD); +typedef BOOL (CALLBACK *SNETCREATEPROC )(SNETCREATEDATAPTR,_SNETPROGRAMDATA *,_SNETPLAYERDATA *,_SNETUIDATA *,_SNETVERSIONDATA *,DWORD *); +typedef BOOL (CALLBACK *SNETDRAWDESCPROC )(DWORD,DWORD,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,LPDRAWITEMSTRUCT); +typedef BOOL (CALLBACK *SNETENUMDEVICESPROC )(DWORD,LPCSTR,LPCSTR); +typedef BOOL (CALLBACK *SNETENUMGAMESEXPROC )(SNETGAMEPTR); +typedef BOOL (CALLBACK *SNETENUMGAMESPROC )(DWORD,LPCSTR,LPCSTR); +typedef BOOL (CALLBACK *SNETENUMPROVIDERSPROC)(DWORD,LPCSTR,LPCSTR,SNETCAPSPTR); +typedef void (CALLBACK *SNETEVENTPROC )(SNETEVENTPTR); +typedef BOOL (CALLBACK *SNETGETARTPROC )(DWORD,DWORD,LPPALETTEENTRY,LPBYTE,DWORD,int *,int *,int *); +typedef BOOL (CALLBACK *SNETGETDATAPROC )(DWORD,DWORD,LPVOID,DWORD,DWORD *); +typedef int (CALLBACK *SNETMESSAGEBOXPROC )(HWND,LPCSTR,LPCSTR,UINT); +typedef BOOL (CALLBACK *SNETPLAYSOUNDPROC )(DWORD,DWORD,DWORD); +typedef BOOL (CALLBACK *SNETSELECTEDPROC )(DWORD,SNETCAPSPTR,_SNETUIDATA *,_SNETVERSIONDATA *); +typedef BOOL (CALLBACK *SNETSTATUSPROC )(LPCSTR,DWORD,DWORD,DWORD,SNETABORTPROC); +typedef BOOL (CALLBACK *SNETPROFILEPROC )(); // tbd -- include callback to save info +typedef BOOL (CALLBACK *SNETNEWACCOUNTPROC )(); // tbd -- include callback to try to create + +typedef struct _SNETPLAYERDATA { + DWORD size; + LPCSTR playername; + LPCSTR playerdescription; + // new for 1.05: + LPCSTR displayedfields; +} SNETPLAYERDATA, *SNETPLAYERDATAPTR; + +typedef struct _SNETPROGRAMDATA { + DWORD size; + LPCSTR programname; + LPCSTR programdescription; + DWORD programid; + DWORD versionid; + DWORD reserved1; + DWORD maxplayers; + LPVOID initdata; + DWORD initdatabytes; + LPVOID reserved2; + DWORD optcategorybits; +} SNETPROGRAMDATA, *SNETPROGRAMDATAPTR; + +typedef struct _SNETUIDATA { + DWORD size; + DWORD uiflags; + HWND parentwindow; + SNETGETARTPROC artcallback; + SNETCHECKAUTHPROC authcallback; + SNETCREATEPROC createcallback; + SNETDRAWDESCPROC drawdesccallback; + SNETSELECTEDPROC selectedcallback; + SNETMESSAGEBOXPROC messageboxcallback; + SNETPLAYSOUNDPROC soundcallback; + SNETSTATUSPROC statuscallback; + SNETGETDATAPROC getdatacallback; + SNETCATEGORYPROC categorycallback; + // new for 1.05: + SNETCATEGORYLISTPROC categorylistcallback; + SNETNEWACCOUNTPROC newaccountcallback; + SNETPROFILEPROC profilecallback; +} SNETUIDATA, *SNETUIDATAPTR; + +typedef struct _SNETVERSIONDATA { + DWORD size; + LPCSTR versionstring; + LPCSTR executablefile; + LPCSTR originalarchivefile; + LPCSTR patcharchivefile; +} SNETVERSIONDATA, *SNETVERSIONDATAPTR; + +extern "C" BOOL APIENTRY SNetCreateGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamecategorybits, + LPVOID initdata, + DWORD initdatabytes, + DWORD maxplayers, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetDestroy (); +extern "C" BOOL APIENTRY SNetDropPlayer (DWORD playerid, DWORD exitcode); +extern "C" BOOL APIENTRY SNetEnumDevices (SNETENUMDEVICESPROC callback); +extern "C" BOOL APIENTRY SNetEnumGames (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESPROC callback, + DWORD *hintnextcall); +extern "C" BOOL APIENTRY SNetEnumGamesEx (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESEXPROC callback, + DWORD *hintnextcall); +extern "C" BOOL APIENTRY SNetEnumProviders (SNETCAPSPTR mincaps, + SNETENUMPROVIDERSPROC callback); +extern "C" BOOL APIENTRY SNetGetGameInfo (DWORD index, + LPVOID buffer, + DWORD buffersize, + DWORD *byteswritten); +extern "C" BOOL APIENTRY SNetGetNetworkLatency (DWORD measurementtype, + DWORD *result); +extern "C" BOOL APIENTRY SNetGetNumPlayers (DWORD *firstplayerid, + DWORD *lastplayerid, + DWORD *activeplayers); +extern "C" BOOL APIENTRY SNetGetOwnerId (DWORD *playerid); +extern "C" BOOL APIENTRY SNetGetOwnerTurnsWaiting (DWORD *turns); +extern "C" BOOL APIENTRY SNetGetPerformanceData (DWORD counterid, + DWORD *countervalue, + DWORD *countertype, + LONG *counterscale, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq); +extern "C" BOOL APIENTRY SNetGetPlayerCaps (DWORD playerid, + SNETCAPSPTR caps); +extern "C" BOOL APIENTRY SNetGetPlayerName (DWORD playerid, + LPSTR buffer, + DWORD buffersize); +extern "C" BOOL APIENTRY SNetGetProviderCaps (SNETCAPSPTR caps); +extern "C" BOOL APIENTRY SNetGetTurnsInTransit (DWORD *turns); +extern "C" BOOL APIENTRY SNetInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +extern "C" BOOL APIENTRY SNetInitializeProvider (DWORD providerid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +extern "C" BOOL APIENTRY SNetJoinGame (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetLeaveGame (DWORD exitcode); +extern "C" BOOL APIENTRY SNetPerformUpgrade (DWORD *upgradestatus); +extern "C" BOOL APIENTRY SNetReceiveMessage (DWORD *senderplayerid, + LPVOID *data, + DWORD *databytes); +extern "C" BOOL APIENTRY SNetReceiveTurns (DWORD firstplayerid, + DWORD arraysize, + LPVOID *arraydata, + LPDWORD arraydatabytes, + LPDWORD arrayplayerstatus); +extern "C" BOOL APIENTRY SNetRegisterEventHandler (DWORD eventid, + SNETEVENTPROC callback); +extern "C" BOOL APIENTRY SNetResetLatencyMeasurements (); +extern "C" BOOL APIENTRY SNetSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); +extern "C" BOOL APIENTRY SNetSelectProvider (SNETCAPSPTR mincaps, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *providerid); +extern "C" BOOL APIENTRY SNetSendMessage (DWORD targetplayerid, + LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SNetSendServerChatCommand (LPCSTR command); +extern "C" BOOL APIENTRY SNetSendTurn (LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SNetSetBasePlayer (DWORD playerid); +extern "C" BOOL APIENTRY SNetSetGameMode (DWORD modeflags); +extern "C" BOOL APIENTRY SNetUnregisterEventHandler (DWORD eventid, + SNETEVENTPROC callback); + + +/**************************************************************************** +* +* Networking service provider interface +* +***/ + +#define SNETSPI_MAXCLIENTDATA 256 +#define SNETSPI_MAXSTRINGLENGTH 128 + +typedef struct _SNETADDR { + BYTE address[16]; +} SNETADDR, *SNETADDRPTR; + +typedef struct _SNETSPI_DEVICELIST { + DWORD deviceid; + SNETCAPS devicecaps; + char devicename[SNETSPI_MAXSTRINGLENGTH]; + char devicedescription[SNETSPI_MAXSTRINGLENGTH]; + DWORD reserved; + _SNETSPI_DEVICELIST *next; +} SNETSPI_DEVICELIST, *SNETSPI_DEVICELISTPTR; + +typedef struct _SNETSPI_GAMELIST { + DWORD gameid; + DWORD gamemode; + DWORD creationtime; + SNETADDR owner; + DWORD ownerlatency; + DWORD ownerlasttime; + DWORD gamecategorybits; + char gamename[SNETSPI_MAXSTRINGLENGTH]; + char gamedescription[SNETSPI_MAXSTRINGLENGTH]; + _SNETSPI_GAMELIST *next; + // new for 1.05: + LPVOID clientdata; + DWORD clientdatabytes; +} SNETSPI_GAMELIST, *SNETSPI_GAMELISTPTR; + +typedef struct _SNETSPI { + DWORD size; + BOOL (CALLBACK *CompareNetAddresses)(SNETADDRPTR,SNETADDRPTR,DWORD *); + BOOL (CALLBACK *Destroy)(); + BOOL (CALLBACK *Free)(SNETADDRPTR,LPVOID,DWORD); + BOOL (CALLBACK *FreeExternalMessage)(LPCSTR,LPCSTR,LPCSTR); + BOOL (CALLBACK *GetGameInfo)(DWORD,LPCSTR,LPCSTR,SNETSPI_GAMELIST *); + BOOL (CALLBACK *GetPerformanceData)(DWORD,DWORD *,LARGE_INTEGER *,LARGE_INTEGER *); + BOOL (CALLBACK *Initialize)(SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR,HANDLE); + BOOL (CALLBACK *InitializeDevice)(DWORD,SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR); + BOOL (CALLBACK *LockDeviceList)(SNETSPI_DEVICELISTPTR *); + BOOL (CALLBACK *LockGameList)(DWORD,DWORD,SNETSPI_GAMELISTPTR *); + +/* note: this is the way that the Receive call should look... + + BOOL (CALLBACK *Receive)(SNETADDRPTR *,LPVOID *,DWORD *); + + below is the receive call with two parameters switched around + to make it incompatible with older .snp's during the beta... */ + + BOOL (CALLBACK *Receive)(LPVOID *,DWORD *,SNETADDRPTR *); + + BOOL (CALLBACK *ReceiveExternalMessage)(LPCSTR *,LPCSTR *,LPCSTR *); + BOOL (CALLBACK *SelectGame)(DWORD,SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR,DWORD *); + BOOL (CALLBACK *Send)(DWORD,SNETADDRPTR *,LPVOID,DWORD); + BOOL (CALLBACK *SendExternalMessage)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR); + BOOL (CALLBACK *StartAdvertisingGame)(LPCSTR,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCVOID,DWORD); + BOOL (CALLBACK *StopAdvertisingGame)(); + BOOL (CALLBACK *UnlockDeviceList)(SNETSPI_DEVICELISTPTR); + BOOL (CALLBACK *UnlockGameList)(SNETSPI_GAMELISTPTR,DWORD *); + // new for 1.05: + BOOL (CALLBACK *GetLocalPlayerName)(LPSTR,DWORD,LPSTR,DWORD); +} SNETSPI, *SNETSPIPTR; + +typedef BOOL (APIENTRY *SNETSPIBIND )(DWORD,SNETSPIPTR *); +typedef BOOL (APIENTRY *SNETSPIQUERY)(DWORD,DWORD *,LPCSTR *,LPCSTR *,SNETCAPSPTR *); + + +/**************************************************************************** +* +* Registry functions +* +***/ + +#define SREG_FLAG_USERSPECIFIC 0x00000001 +#define SREG_FLAG_BATTLENET 0x00000002 +#define SREG_FLAG_FLUSHTODISK 0x00000008 +#define SREG_FLAG_MULTISZ 0x00000080 + +extern "C" BOOL APIENTRY SRegGetBaseKey (DWORD flags, + LPSTR buffer, + DWORD buffersize); +extern "C" BOOL APIENTRY SRegLoadData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID buffer, + DWORD buffersize, + DWORD *bytesread); +extern "C" BOOL APIENTRY SRegLoadString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPTSTR buffer, + DWORD bufferchars); +extern "C" BOOL APIENTRY SRegLoadValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD *value); +extern "C" BOOL APIENTRY SRegSaveData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID data, + DWORD databytes); +extern "C" BOOL APIENTRY SRegSaveString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPCTSTR string); +extern "C" BOOL APIENTRY SRegSaveValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD value); + + +/**************************************************************************** +* +* Region manager functions +* +***/ + +#define SRGN_AND RGN_AND +#define SRGN_COPY RGN_COPY +#define SRGN_DIFF RGN_DIFF +#define SRGN_OR RGN_OR +#define SRGN_XOR RGN_XOR +#define SRGN_PARAMONLY 6 +#define SRGN_MIN 1 +#define SRGN_MAX 6 + +DECLARE_STRICT_HANDLE(HSRGN); + +extern "C" void APIENTRY SRgnClear (HSRGN handle); +extern "C" void APIENTRY SRgnCombineRect (HSRGN handle, + LPCRECT rect, + LPVOID param, + int combinemode); +extern "C" void APIENTRY SRgnCreate (HSRGN *handle, + DWORD reserved = 0); +extern "C" void APIENTRY SRgnDelete (HSRGN handle); +#ifdef STORMSTATIC +extern "C" void APIENTRY SRgnDestroy (); +#endif +extern "C" void APIENTRY SRgnDuplicate (HSRGN orighandle, + HSRGN *handle, + DWORD reserved = 0); +extern "C" void APIENTRY SRgnGetBoundingRect (HSRGN handle, + LPRECT rect); +extern "C" void APIENTRY SRgnGetRectParams (HSRGN handle, + LPCRECT rect, + DWORD *numparams, + LPVOID *buffer); +extern "C" void APIENTRY SRgnGetRects (HSRGN handle, + DWORD *numrects, + LPRECT buffer); + +#define SRgnAddParam(handle,rect,param) SRgnCombineRect(handle,rect,param,SRGN_PARAMONLY); +#define SRgnAddRect(handle,rect,param) SRgnCombineRect(handle,rect,param,SRGN_OR) + + +/**************************************************************************** +* +* Run-time library functions +* +***/ + +#define ONCE ONCEEXPAND(__FILE__##__##__LINE__##__once) +#define ONCEEXPAND(a) BOOL a = TRUE; a; a = FALSE + +#define TRY goto trylabel; trylabel: +#define LEAVE goto finallylabel +#define FINALLY goto finallylabel; finallylabel: + + +/**************************************************************************** +* +* String functions +* +***/ + +#define SSTR_HASH_CASESENSITIVE 0x00000001 + +#define SSTR_UNBOUNDED 0x7FFFFFFF + +extern "C" LPTSTR APIENTRY SStrChr (LPCTSTR string, + char ch, + BOOL reverse = FALSE); +extern "C" DWORD APIENTRY SStrCopy (LPTSTR dest, + LPCTSTR source, + DWORD destsize = SSTR_UNBOUNDED); +extern "C" DWORD APIENTRY SStrHash (LPCTSTR string, + DWORD flags = 0, + DWORD seed = 0); +extern "C" DWORD APIENTRY SStrLen (LPCTSTR string); +extern "C" void APIENTRY SStrPack (LPTSTR dest, + LPCTSTR source, + DWORD destsize = SSTR_UNBOUNDED); +extern "C" void APIENTRY SStrTokenize (LPCTSTR *string, + LPTSTR buffer, + DWORD bufferchars, + LPCTSTR whitespace, + BOOL *quoted = NULL); + + +/**************************************************************************** +* +* Transparency functions +* +***/ + +#define STRANS_CF_INTERSECT 0x00000001 +#define STRANS_CF_INVERTSECOND 0x00000002 +#define STRANS_CF_SUBTRACT (STRANS_CF_INTERSECT | STRANS_CF_INVERTSECOND) + +DECLARE_STRICT_HANDLE(HSTRANS); +typedef HSTRANS HTRANS; + +extern "C" BOOL APIENTRY STransBlt (LPBYTE dest, + int destx, + int desty, + int destpitch, + HSTRANS transparency); +extern "C" BOOL APIENTRY STransBltUsingMask (LPBYTE dest, + LPBYTE source, + int destpitch, + int sourcepitch, + HSTRANS mask); +extern "C" BOOL APIENTRY STransCombineMasks (HSTRANS basemask, + HSTRANS secondmask, + int offsetx, + int offsety, + DWORD flags, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateMaskE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransCreateMaskI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransDelete (HSTRANS handle); +#ifdef STORMSTATIC +extern "C" BOOL APIENTRY STransDestroy (); +#endif +extern "C" BOOL APIENTRY STransDuplicate (HSTRANS source, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransIntersectDirtyArray (HSTRANS sourcemask, + LPBYTE dirtyarray, + BYTE dirtyarraymask, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransInvertMask (HSTRANS sourcemask, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransIsPixelInMask (HSTRANS mask, + int offsetx, + int offsety); +extern "C" BOOL APIENTRY STransLoadE (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransLoadI (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle); +extern "C" BOOL APIENTRY STransSetDirtyArrayInfo (int screencx, + int screency, + int cellcx, + int cellcy); +extern "C" BOOL APIENTRY STransUpdateDirtyArray (LPBYTE dirtyarray, + BYTE dirtyvalue, + int destx, + int desty, + HSTRANS transparency, + BOOL tracecontour); + +#ifdef STRANS_USE_INCLUSIVE_RECTS +#define STransCreate STransCreateI +#define STransCreateMask STransCreateMaskI +#define STransLoad STransLoadI +#else +#define STransCreate STransCreateE +#define STransCreateMask STransCreateMaskE +#define STransLoad STransLoadE +#endif + + +/**************************************************************************** +* +* Video functions +* +***/ + +#define SVID_FLAG_DOUBLESCANS 0x00000001 +#define SVID_FLAG_INTERPOLATE 0x00000002 +#define SVID_FLAG_INTERLACE 0x00000004 +#define SVID_FLAG_AUTOQUALITY 0x00000008 +#define SVID_FLAG_1XSIZE 0x00000100 +#define SVID_FLAG_2XSIZE 0x00000200 +#define SVID_FLAG_AUTOSIZE 0x00000800 +#define SVID_FLAG_FILEHANDLE 0x00010000 +#define SVID_FLAG_PRELOAD 0x00020000 +#define SVID_FLAG_LOOP 0x00040000 +#define SVID_FLAG_FULLSCREEN 0x00080000 +#define SVID_FLAG_USECURRENTPALETTE 0x00100000 +#define SVID_FLAG_CLEARSCREEN 0x00200000 +#define SVID_FLAG_NOSKIP 0x00400000 +#define SVID_FLAG_NEEDPAN 0x02000000 +#define SVID_FLAG_NEEDVOLUME 0x04000000 +#define SVID_FLAG_TOSCREEN 0x10000000 +#define SVID_FLAG_TOBUFFER 0x20000000 + +#define SVID_CUTSCENE (SVID_FLAG_TOSCREEN | SVID_FLAG_FULLSCREEN | SVID_FLAG_CLEARSCREEN | SVID_FLAG_2XSIZE) +#define SVID_AUTOCUTSCENE (SVID_FLAG_TOSCREEN | SVID_FLAG_FULLSCREEN | SVID_FLAG_CLEARSCREEN | SVID_FLAG_AUTOSIZE | SVID_FLAG_AUTOQUALITY) + +#define SVID_QUALITY_LOW_SKIPSCANS SVID_FLAG_2XSIZE +#define SVID_QUALITY_LOW (SVID_FLAG_2XSIZE | SVID_FLAG_DOUBLESCANS) +#define SVID_QUALITY_HIGH_SKIPSCANS (SVID_FLAG_2XSIZE | SVID_FLAG_INTERPOLATE) +#define SVID_QUALITY_HIGH (SVID_FLAG_2XSIZE | SVID_FLAG_INTERPOLATE | SVID_FLAG_DOUBLESCANS) + +DECLARE_STRICT_HANDLE(HSVIDEO); + +typedef struct _SVIDPALETTEUSE { + DWORD size; + DWORD firstentry; + DWORD numentries; +} SVIDPALETTEUSE, *SVIDPALETTEUSEPTR; + +extern "C" BOOL APIENTRY SVidDestroy (); +extern "C" BOOL APIENTRY SVidGetPerformanceData (HSVIDEO video, + BOOL averageframems, + DWORD *framems, + BOOL averagepalettems, + DWORD *palettems); +extern "C" BOOL APIENTRY SVidGetSize (HSVIDEO video, + int *width, + int *height, + int *bitdepth = NULL); +extern "C" BOOL APIENTRY SVidInitialize (LPVOID directsound); +extern "C" BOOL APIENTRY SVidPlayBegin (LPCTSTR filename, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle); +extern "C" BOOL APIENTRY SVidPlayBeginFromMemory (LPVOID sourceptr, + DWORD sourcebytes, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle); +extern "C" BOOL APIENTRY SVidPlayContinue (); +extern "C" BOOL APIENTRY SVidPlayContinueSingle (HSVIDEO video, + BOOL forceupdate, + BOOL *updated); +extern "C" BOOL APIENTRY SVidPlayEnd (HSVIDEO video); +extern "C" BOOL APIENTRY SVidSetVolume (HSVIDEO video, + LONG volume, + LONG pan, + DWORD track = 0); + + +/**************************************************************************** +* +* Storm global functions +* +***/ + +extern "C" BOOL APIENTRY StormDestroy (); + +#ifdef MAC +extern "C" void StormStartup(); +extern "C" void StormShutdown(); +#endif + + +//#########################################################################// +//#########################################################################// +// // +// // +// CLASS-BASED PROGRAMMING INTERFACE // +// (under construction) // +// // +// // +//#########################################################################// +//#########################################################################// + + +/**************************************************************************** +* +* CSLog +* +***/ + +class CSLog { + + private: + HSLOG m_handle; + + public: + + //======================================================================= + CSLog (LPCTSTR filename) { + SLogCreate(filename,0,&m_handle); + } + + //======================================================================= + CSLog (LPCTSTR keyname, + LPCTSTR valuename) { + char filename[MAX_PATH] = ""; + SRegLoadString(keyname,valuename,0,filename,MAX_PATH); +#ifdef _DEBUG + SRegSaveString(keyname,valuename,0,filename); +#endif + if (filename[0]) + SLogCreate(filename,0,&m_handle); + } + + //======================================================================= + ~CSLog () { + SLogClose(m_handle); + } + + //======================================================================= + void Dump (LPCVOID data, + DWORD bytes) { + SLogDump(m_handle, + data, + bytes); + } + + //======================================================================= + void Flush () { + SLogFlush(m_handle); + } + + //======================================================================= + HSLOG GetHandle () { + return m_handle; + } + + //======================================================================= + void Pend (LPCSTR string) { + SLogPend(m_handle, + string); + } + + //======================================================================= + void Write (LPCSTR string) { + SLogWrite(m_handle, + string); + } + +}; + + +/**************************************************************************** +* +* CSRgn +* +***/ + +class CSRgn { + + private: + HSRGN m_handle; + + //======================================================================= + void CopyConstructor (const CSRgn & source) { + SRgnDuplicate(source.m_handle, + &m_handle); + } + + public: + + //======================================================================= + CSRgn () { + SRgnCreate(&m_handle); + } + + //======================================================================= + CSRgn (const CSRgn & source) { + CopyConstructor(source); + } + + //======================================================================= + ~CSRgn () { + SRgnDelete(m_handle); + } + + //======================================================================= + CSRgn & operator= (const CSRgn &source) { + if (this != &source) { + this->~CSRgn(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + void AddParam (LPCRECT rect, + LPVOID param) { + SRgnAddParam(m_handle, + rect, + param); + } + + //======================================================================= + void AddRect (LPCRECT rect, + LPVOID param) { + SRgnAddRect(m_handle, + rect, + param); + } + + //======================================================================= + void Clear () { + SRgnClear(m_handle); + } + + //======================================================================= + void CombineRect (LPCRECT rect, + LPVOID param, + int combinemode) { + SRgnCombineRect(m_handle, + rect, + param, + combinemode); + } + + //======================================================================= + void GetBoundingRect (LPRECT rect) { + SRgnGetBoundingRect(m_handle, + rect); + } + + //======================================================================= + void GetRects (DWORD *numrects, + LPRECT buffer) { + SRgnGetRects(m_handle, + numrects, + buffer); + } + + //======================================================================= + void GetRectParams (LPCRECT rect, + DWORD *numparams, + LPVOID *buffer) { + SRgnGetRectParams(m_handle, + rect, + numparams, + buffer); + } + +}; + + +//#########################################################################// +//#########################################################################// +// // +// // +// UTILITY CLASSES AND TEMPLATES // +// // +// // +//#########################################################################// +//#########################################################################// + + +/**************************************************************************** +* +* CCritSect -- Critical section class +* +* Methods: +* +* void Enter () +* void Leave () +* +***/ + +class CCritSect { + private: + CRITICAL_SECTION m_critsect; + public: + CCritSect () { InitializeCriticalSection(&m_critsect); } + ~CCritSect () { DeleteCriticalSection(&m_critsect); } + void Enter () { EnterCriticalSection(&m_critsect); } + void Enter (BOOL) { EnterCriticalSection(&m_critsect); } + void Leave () { LeaveCriticalSection(&m_critsect); } + void Leave (BOOL) { LeaveCriticalSection(&m_critsect); } +}; + + +/**************************************************************************** +* +* CLock -- Reader/writer lock class +* +* Methods: +* +* void Enter (BOOL forwriting) +* void Leave (BOOL fromwriting) +* +***/ + +class CLock { + + private: + + HANDLE m_mutexevent; + HANDLE m_readerevent; + LONG m_readercount; + + public: + + //======================================================================= + CLock () { + m_mutexevent = CreateEvent(NULL,FALSE,TRUE,NULL); + m_readerevent = CreateEvent(NULL,TRUE,FALSE,NULL); + m_readercount = -1; + } + + //======================================================================= + ~CLock () { + CloseHandle(m_readerevent); + CloseHandle(m_mutexevent); + } + + //======================================================================= + void Enter (BOOL forwriting) { + if (forwriting) + WaitForSingleObject(m_mutexevent,INFINITE); + else if (!InterlockedIncrement(&m_readercount)) { + WaitForSingleObject(m_mutexevent,INFINITE); + SetEvent(m_readerevent); + } + else + WaitForSingleObject(m_readerevent,INFINITE); + } + + //======================================================================= + void Leave (BOOL fromwriting) { + if (fromwriting) + SetEvent(m_mutexevent); + else if (InterlockedDecrement(&m_readercount) < 0) { + ResetEvent(m_readerevent); + SetEvent(m_mutexevent); + } + } + +}; + + +/**************************************************************************** +* +* CNullSync -- Null synchronization class +* +* (used for templates that take a synchronization class as a parameter) +* +***/ + +class CNullSync { + public: + void Enter (BOOL) { } + void Leave (BOOL) { } +}; + + +/**************************************************************************** +* +* type_info +* +* (used by templates to obtain the name of an object) +* +***/ + +#ifdef _MSC_VER + #ifdef _INC_TYPEINFO + #define INTERNALRAWNAME raw_name + #else + #define INTERNALRAWNAME internal_raw_name + class type_info { + public: + virtual ~type_info (); + const char * internal_raw_name () const { return _m_d_name; }; + private: + void *_m_data; + char _m_d_name[1]; + type_info (const type_info& rhs); + type_info& operator= (const type_info& rhs); + }; + #endif +#else + #if defined(MAC) && !defined(__typeinfo__) + #include + #endif + #define INTERNALRAWNAME name +#endif + + +/**************************************************************************** +* +* ARRAY -- Dynamically allocated array template +* +* Types: +* +* ARRAY(structname) -- dynamically sized array of struct +* +* Pointers to types: +* +* ARRAYPTR(structname) +* +* Array methods: +* +* void AddDiscontiguousElements (DWORD count, +* int stride, +* const *newelements); +* void AddElement (const *newelement); +* void AddElements (DWORD count, +* const *newelements); +* DWORD NumElements (); +* * NewElement (); +* * Ptr (); +* void ReserveSpace (DWORD count); +* void SetNumElements (DWORD totalcount); +* +***/ + +template +class TSArray { + + private: + DWORD m_allocchunksize; + T *m_data; + DWORD m_elements; + DWORD m_elementsalloc; + + //======================================================================= + BOOL CheckSpace (DWORD count) { + return (m_elements+count <= m_elementsalloc); + } + + //======================================================================= + void Constructor () { + m_allocchunksize = max(16,256/sizeof(T)); + m_data = NULL; + m_elements = 0; + m_elementsalloc = 0; + } + + //======================================================================= + void CopyConstructor (const TSArray & source) { + Constructor(); + m_allocchunksize = source.m_allocchunksize; + ReserveSpace(source.m_elementsalloc); + AddElements(source.m_elements, + source.m_data); + } + + public: + + //======================================================================= + TSArray () { + Constructor(); + } + + //======================================================================= + TSArray (const TSArray & source) { + CopyConstructor(source); + } + + //======================================================================= + ~TSArray () { + if (m_data) { + while (m_elements) { + --m_elements; + m_data[m_elements].~T(); + } + SMemFree(m_data,__FILE__,__LINE__,0); + m_data = NULL; + } + } + + //======================================================================= + TSArray & operator= (const TSArray &source) { + if (this != &source) { + this->~TSArray(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + T & operator[] (DWORD num) { + if (num >= m_elements) + SErrDisplayError(STORM_ERROR_ACCESS_OUT_OF_BOUNDS, + typeid(T).INTERNALRAWNAME(), + SERR_LINECODE_OBJECT, + NULL, + TRUE); + return m_data[num]; + } + + //======================================================================= + void AddDiscontiguousElements (DWORD count, + int stride, + const T *newelements) { + if (!CheckSpace(count)) + ReserveSpace(count); + if (stride == sizeof(T)) + AddElements(count,newelements); + else + for (DWORD loop = 0; loop < count; ++loop) { + new(m_data+m_elements++) T(*newelements); + newelements = (const T *)((LPBYTE)newelements+stride); + } + } + + //======================================================================= + void AddElement (const T *newelement) { + if (!CheckSpace(1)) + ReserveSpace(1); + new(m_data+m_elements++) T(*newelement); + } + + //======================================================================= + void AddElements (DWORD count, + const T *newelements) { + if (!CheckSpace(count)) + ReserveSpace(count); + for (DWORD loop = 0; loop < count; ++loop) + new(m_data+m_elements++) T(newelements[loop]); + } + + //======================================================================= + DWORD NumElements () { + return m_elements; + } + + //======================================================================= + T * NewElement () { + if (!CheckSpace(1)) + ReserveSpace(1); + return new(m_data+m_elements++) T; + } + + //======================================================================= + T * Ptr () { + if (!m_data) + ReserveSpace(1); + return m_data; + } + + //======================================================================= + void ReserveSpace (DWORD count) { + if (CheckSpace(count)) + return; + + // DETERMINE THE NUMBER OF NEW ELEMENTS TO ALLOCATE + DWORD newelements = m_elements+count; + DWORD partialchunk = newelements & (m_allocchunksize-1); + if (partialchunk) + newelements += m_allocchunksize-partialchunk; + + // ALLOCATE THE NEW ARRAY AND COPY DATA FROM THE OLD ARRAY + T *newdata = (T *)ALLOC(newelements*sizeof(T)); + if (m_data) { + for (DWORD loop = 0; loop < m_elements; ++loop) + new(newdata+loop) T(m_data[loop]); + FREE(m_data); + } + m_data = newdata; + m_elementsalloc = newelements; + + } + + //======================================================================= + void SetNumElements (DWORD totalcount) { + if (totalcount > m_elements) { + ReserveSpace(totalcount-m_elements); + for (DWORD loop = m_elements; loop < totalcount; ++loop) + new(m_data+loop) T; + } + else if (totalcount < m_elements) { + for (DWORD loop = totalcount; loop < m_elements; ++loop) + m_data[loop].~T(); + } + m_elements = totalcount; + } + +}; + +#define ARRAY(structname) TSArray< structname > +#define ARRAYDECL(structname,varname) TSArray< structname > varname +#define ARRAYPTR(structname) TSArray< structname > * + + +/**************************************************************************** +* +* NODE/LIST -- Linked list template +* +* Types: +* +* LINKEX(structname) -- explicit link field +* LIST(structname) -- linked list of implicitly linked nodes +* LISTEX(structname,linkname) -- linked list of explicitly linked nodes +* LISTEXDYN(structname) -- linked list of explicitly linked nodes, +* where the link field to be used by +* this list is not known at compile time +* NODEDECL(structname) -- implicitly linked node +* NODEDECLEX(structname) -- explicitly linked node (must contain one +* or more LINKEX fields) +* +* Pointers to types: +* +* LISTPTR(structname) +* LISTPTREX(structname) +* +* Link methods: +* +* * Next (); +* * Prev (); +* void Unlink (); +* +* Explicitly linked node methods: +* +* None. Use link methods for the link you want to manipulate. +* +* Implicitly linked node methods: +* +* * Next (); +* * Prev (); +* void Unlink (); +* +* List methods: +* +* void Clear (); +* * DeleteNode ( *ptr); +* * Head () const; +* BOOL IsEmpty () const; +* void LinkNode ( *ptr, +* DWORD linktype = LIST_TAIL, +* *existingptr = NULL); +* * NewNode (DWORD location = LIST_TAIL, +* DWORD extrabytes = 0, +* DWORD flags = 0); +* * Next (const *ptr) const; +* * Prev (const *ptr) const; +* * Tail () const; +* void UnlinkAll (); +* void UnlinkNode ( *ptr); +* +* Constants for use with LinkNode() and NewNode(): +* +* LIST_UNLINKED +* LIST_LINK_AFTER +* LIST_LINK_BEFORE +* LIST_HEAD +* LIST_TAIL +* +* Macros: +* +* LISTEXSETLINK(structname,listname,linkname) +* ITERATELIST(structname,listname,ptrname) +* ITERATELISTPTR(structname,listname,ptrname) +* ITERATEPARTIALLIST(structname,listname,start,ptrname) +* ITERATEPARTIALLISTPTR(structname,listname,start,ptrname) +* ITERATELISTREVERSE(structname,listname,ptrname) +* ITERATELISTREVERSEPTR(structname,listname,ptrname) +* ITERATEPARTIALLISTREVERSE(structname,listname,start,ptrname) +* ITERATEPARTIALLISTREVERSEPTR(structname,listname,start,ptrname) +* ITERATE_DELETE +* ITERATE_DELETEANDBREAK +* +***/ + +#define LIST_UNLINKED 0 +#define LIST_LINK_AFTER 1 +#define LIST_LINK_BEFORE 2 +#define LIST_HEAD LIST_LINK_AFTER +#define LIST_TAIL LIST_LINK_BEFORE + +template +class TSList; + +template +class TSLink { + friend class TSList; + friend class TSList; + + private: + TSLink *m_prevlink; + T *m_next; + + //======================================================================= + void Constructor () { + m_prevlink = NULL; + m_next = NULL; + } + + //======================================================================= + void CopyConstructor (const TSLink &) { + Constructor(); + } + + //======================================================================= + TSLink *NextLink () const { + + // IF THE NEXT NODE IS A TERMINATOR, ITS LINK POINTER IS THE SAME AS + // ITS NODE POINTER. + if ((int)m_next < 0) + return (TSLink *)~(DWORD)m_next; + + // OTHERWISE, COMPUTE THE LINK ADDRESS BY USING THE OFFSET OF THIS + // NODE'S LINK AND POINTER ADDRESSES. (THIS NODE MUST NOT BE A + // TERMINATOR.) + else { + DWORD linkoffset = (DWORD)this-(DWORD)(m_prevlink->m_next); + return (TSLink *)(linkoffset+(DWORD)m_next); + } + + } + + protected: + + //======================================================================= + T *NextThroughTerminator () const { + return ((int)m_next > 0) ? m_next : (T *)~(DWORD)m_next; + } + + public: + + //======================================================================= + TSLink () { + Constructor(); + } + + //======================================================================= + TSLink (const TSLink & source) { + CopyConstructor(source); + } + + //======================================================================= + ~TSLink () { + Unlink(); + } + + //======================================================================= + TSLink & operator= (const TSLink &) { + // LEAVE THE DESTINATION NODE LINKED INTO ITS CURRENT LIST + return *this; + } + + //======================================================================= + T * Next () const { + return ((int)m_next > 0) ? m_next : NULL; + } + + //======================================================================= + T * Prev () const { + return m_prevlink->m_prevlink->Next(); + } + + //======================================================================= + void Unlink () { + if (!m_prevlink) + return; + NextLink()->m_prevlink = m_prevlink; + m_prevlink->m_next = m_next; + m_prevlink = NULL; + m_next = NULL; + } + +}; + +template +class TSBaseNode { + public: + + //======================================================================= + inline void * __cdecl operator new (size_t bytes, + size_t extra, + DWORD flags) { + void *ptr = SMemAlloc(bytes+extra, + typeid(T).INTERNALRAWNAME(), + SERR_LINECODE_OBJECT, + flags | SMEM_FLAG_ZEROMEMORY); + return ptr; + } + +}; + +template +class TSExplicitNode : public TSBaseNode { + friend class TSList; + + private: + + //======================================================================= + TSLink *Link (BOOL explicitlink, int linkoffset) const { + ASSERT(explicitlink); + explicitlink; + return (TSLink *)((LPBYTE)this+linkoffset); + } + +}; + +template +class TSLinkedNode : public TSBaseNode { + friend class TSList; + + private: + TSLink m_link; + + //======================================================================= + TSLink *Link (BOOL explicitlink, int linkoffset) const { + if (explicitlink) + return (TSLink *)((LPBYTE)this+linkoffset); + else + return (TSLink *)&m_link; + } + + public: + + //======================================================================= + ~TSLinkedNode () { + Unlink(); + } + + //======================================================================= + T * Next () const { + return m_link.Next(); + } + + //======================================================================= + T * Prev () const { + return m_link.Prev(); + } + + //======================================================================= + void Unlink () { + m_link.Unlink(); + } + +}; + +template +class TSList { + + private: + int m_linkoffset; + TSLink m_terminator; + + //======================================================================= + void Constructor () { + m_linkoffset = 0; + InitializeTerminator(); + } + + //======================================================================= + void CopyConstructor (const TSList & source) { + m_linkoffset = source.m_linkoffset; + InitializeTerminator(); + } + + //======================================================================= + void InitializeTerminator () { + m_terminator.m_prevlink = &m_terminator; + m_terminator.m_next = (T *)~(DWORD)&m_terminator; + } + + //======================================================================= + TSLink *Link (const T *ptr) const { + // THIS FUNCTION CALLS THE LINK METHOD IN EITHER THE NODE OR THE LINK + // TO WHICH THIS LIST REFERS. IF THIS FUNCTION WON'T COMPILE, IT'S + // BECAUSE A NODE WITH EXPLICIT LINKS WAS DEFINED WITH NODEDECL() + // INSTEAD OF NODEDECLEX(). + return ptr->Link(explicitlink,m_linkoffset); + } + + protected: + + //======================================================================= + void SetLinkOffset (int linkoffset) { + m_linkoffset = linkoffset; + InitializeTerminator(); + } + + public: + + //======================================================================= + TSList () { + Constructor(); + }; + + //======================================================================= + TSList (const TSList &source) { + CopyConstructor(source); + }; + + //======================================================================= + TSList (int linkoffset) { + m_linkoffset = linkoffset; + InitializeTerminator(); + }; + + //======================================================================= + ~TSList () { + UnlinkAll(); + } + + //======================================================================= + TSList & operator= (const TSList &source) { + if (this != &source) { + this->~TSList(); + CopyConstructor(source); + } + return *this; + } + + //======================================================================= + void ChangeLinkOffset (int linkoffset) { + UnlinkAll(); + SetLinkOffset(linkoffset); + } + + //======================================================================= + void Clear () { + T *curr; + while ((curr = Head()) != NULL) + delete curr; + } + + //======================================================================= + T * DeleteNode (T *ptr) { + T *nextptr = Next(ptr); + delete ptr; + return nextptr; + } + + //======================================================================= + T * Head () const { + return m_terminator.Next(); + } + + //======================================================================= + BOOL IsEmpty () const { + return !m_terminator.Next(); + } + + //======================================================================= + T * Iterate_RawNext (const T *ptr) const { + return Link(ptr)->m_next; + } + + //======================================================================= + void LinkNode (T *ptr, + DWORD linktype = LIST_TAIL, + T *existingptr = NULL) { + TSLink *link = Link(ptr); + + // IF THIS NODE IS ALREADY LINKED INTO THE LIST, UNLINK IT + if (link->m_prevlink) + link->Unlink(); + + // FIND THE NODE THAT WE WILL LINK BEFORE OR AFTER. USE THE + // TERMINATOR NODE IF WE'RE LINKING ONTO THE HEAD OR TAIL. + TSLink *existinglink; + if (existingptr) + existinglink = Link(existingptr); + else + existinglink = &m_terminator; + + // LINK THIS NODE INTO THE LIST + switch (linktype) { + + case LIST_LINK_AFTER: + { + link->m_prevlink = existinglink; + link->m_next = existinglink->m_next; + Link(existinglink->NextThroughTerminator())->m_prevlink = link; + existinglink->m_next = ptr; + } + break; + + case LIST_LINK_BEFORE: + { + TSLink *prevlink = existinglink->m_prevlink; + link->m_prevlink = prevlink; + link->m_next = prevlink->m_next; + prevlink->m_next = ptr; + existinglink->m_prevlink = link; + } + break; + + } + } + + //======================================================================= + T * NewNode (DWORD location = LIST_TAIL, + DWORD extrabytes = 0, + DWORD flags = 0) { + T *ptr = new(extrabytes,flags) T; + if (location != LIST_UNLINKED) + LinkNode(ptr,location); + return ptr; + } + + //======================================================================= + T * Next (const T *ptr) const { + return Link(ptr)->Next(); + } + + //======================================================================= + T * Prev (const T *ptr) const { + return Link(ptr)->Prev(); + } + + //======================================================================= + T * Tail () const { + return m_terminator.Prev(); + } + + //======================================================================= + void UnlinkAll () { + T *curr; + while ((curr = Head()) != NULL) + UnlinkNode(curr); + } + + //======================================================================= + void UnlinkNode (T *ptr) { + Link(ptr)->Unlink(); + } + +}; + +template +class TSExplicitList : public TSList { + public: + + //======================================================================= + TSExplicitList () { + SetLinkOffset(linkoffset); + } + +}; + + +#define LINKEX(structname) TSLink< structname > +#define LINKDECLEX(structname,varname) TSLink< structname > varname +#define LIST(structname) TSList< structname ,FALSE> +#define LISTDECL(structname,varname) TSList< structname ,FALSE> varname +#define LISTPTR(structname) TSList< structname ,FALSE> * +#define LISTPTREX(structname) TSList< structname ,TRUE> * +#define NODEDECL(structname) typedef struct structname : public TSLinkedNode< structname > +#define NODEDECLEX(structname) typedef struct structname : public TSExplicitNode< structname > + +#define LISTEX(structname,linkname) \ + TSExplicitList< structname ,(int)&(((structname *)0)->linkname)> + +#define LISTEXDYN(structname) \ + TSExplicitList< structname ,(int)0xDDDDDDDD> + +#define LISTEXSETLINK(structname,listname,linkname) \ + listname.ChangeLinkOffset((int)&(((structname *)0)->linkname)); + +#define LISTDECLEX(structname,linkname,varname) \ + TSExplicitList< structname ,(int)&(((structname *)0)->linkname)> varname + +#define ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,op) \ + for (structname *ptrname = start, \ + *iterate_delete = NULL; \ + (int)ptrname > 0; \ + iterate_delete \ + ? (ptrname = (listname)##op##DeleteNode(ptrname), \ + ptrname = ((int)iterate_delete > 0) ? ptrname : NULL, \ + iterate_delete = NULL, \ + ptrname) \ + : ptrname = (listname)##op##Iterate_RawNext(ptrname)) + +#define ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,op) \ + for (structname *ptrname = start, \ + *iterate_delete = NULL, \ + *iterate_delete_temp = NULL; \ + ptrname; \ + iterate_delete \ + ? (iterate_delete_temp = ((int)iterate_delete > 0) \ + ? (listname)##op##Prev(ptrname) \ + : NULL, \ + (listname)##op##DeleteNode(ptrname), \ + iterate_delete = NULL, \ + ptrname = iterate_delete_temp) \ + : ptrname = (listname)##op##Prev(ptrname)) + +#define ITERATELIST(structname,listname,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,(listname).Head(),ptrname,.) + +#define ITERATELISTPTR(structname,listname,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,(listname)->Head(),ptrname,->) + +#define ITERATEPARTIALLIST(structname,listname,start,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,.) + +#define ITERATEPARTIALLISTPTR(structname,listname,start,ptrname) \ + ITERATEFORWARDTEMPLATE(structname,listname,start,ptrname,->) + +#define ITERATELISTREVERSE(structname,listname,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,(listname).Tail(),ptrname,.) + +#define ITERATELISTREVERSEPTR(structname,listname,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,(listname)->Tail(),ptrname,->) + +#define ITERATEPARTIALLISTREVERSE(structname,listname,start,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,.) + +#define ITERATEPARTIALLISTREVERSEPTR(structname,listname,start,ptrname) \ + ITERATEREVERSETEMPLATE(structname,listname,start,ptrname,->) + +#define ITERATE_DELETE \ + { \ + ++iterate_delete; \ + continue; \ + } + +#define ITERATE_DELETEANDBREAK \ + { \ + --iterate_delete; \ + continue; \ + } + + +/**************************************************************************** +* +* EXPORTOBJECT/EXPORTTABLE -- Export manager template +* +* Types: +* +* DECLARE_STRICT_HANDLE(handle) -- handle to object +* DECLARE_STRICT_HANDLE(lockedhandle) -- handle to locked object +* EXPORTOBJECTDECL(structname) -- object to be exported +* EXPORTTABLE(structname,handlename,lockedhandlename,synctype) +* EXPORTTABLEREUSE(structname,handlename,lockedhandlename,synctype) +* +* Export table methods: +* +* void Delete ( handle); +* void DeleteUnlock ( *ptr, +* lockedhandle); +* void Destroy (); +* * Lock ( handle, +* *lockedhandle, +* BOOL forwriting = FALSE); +* void New ( *handle); +* * NewLock ( *handle, +* *lockedhandle); +* void Unlock ( lockedhandle); +* +* Synchronization types for use with EXPORTTABLE(): +* +* SYNC_NONE -- use no synchronization +* SYNC_READWRITE -- use a reader/writer lock +* SYNC_ALWAYS -- use a critical section +* +***/ + +template +class TSExportTableBase { + + protected: + + //======================================================================= + T * BaseFindByHandle (LISTPTREX(T) list, unsigned handle) { + ITERATELISTPTR(T,list,curr) + if (curr->m_handle == handle) + return curr; + return NULL; + } + + //======================================================================= + T * BaseFindByHandleEx (LISTPTREX(T) list, unsigned handle, unsigned *count) { + *count = 0; + ITERATELISTPTR(T,list,curr) + if (curr->m_handle == handle) + return curr; + else + ++*count; + return NULL; + } + + //======================================================================= + unsigned BaseGetHandle (const T *ptr) { + return ptr->m_handle; + } + + //======================================================================= + int BaseGetLinkOffset () { + return (int)&(((T *)0)->m_linktoslot); + } + + //======================================================================= + void BaseSetHandle (T *ptr, unsigned handle) { + ptr->m_handle = handle; + } + +}; + +template +class TSExportTable : public TSExportTableBase { + + private: + ARRAY(LISTEXDYN(T)) m_listarray; + LISTEXDYN(T) m_reuselist; + H m_sequence; + unsigned m_slotmask; + SYNC m_sync; + + //======================================================================= + unsigned ComputeSlot (H handle) { + return (unsigned)handle & m_slotmask; + } + + //======================================================================= + H GenerateUniqueHandle () { + unsigned count; + for (;;) { + m_sequence = (H)((unsigned)m_sequence+1); + if (!BaseFindByHandleEx(&m_listarray[ComputeSlot(m_sequence)], + (unsigned)m_sequence, + &count)) + break; + } + if (count >= 4) + GrowListArray(); + return m_sequence; + } + + //======================================================================= + void GrowListArray () { +return; // note: out for testing + if (m_slotmask >= 1023) + return; + + // DETERMINE THE NEW ARRAY SIZE + unsigned oldarraysize = m_slotmask+1; + unsigned newarraysize = oldarraysize*2; + + // GROW THE ARRAY + { + m_listarray.SetNumElements(newarraysize); + int linkoffset = BaseGetLinkOffset(); + for (unsigned slot = oldarraysize; slot < newarraysize; ++slot) + m_listarray[slot].ChangeLinkOffset(linkoffset); + } + + // MOVE ALL RECORDS FROM THE OLD LISTS TO THE NEW LISTS + m_slotmask = newarraysize-1; + { + for (unsigned slot = 0; slot < oldarraysize; ++slot) { + T *currptr = m_listarray[slot].Head(); + while (currptr) { + T *nextptr = m_listarray[slot].Next(currptr); + unsigned newslot = ComputeSlot((H)BaseGetHandle(currptr)); + if (newslot != slot) { + m_listarray[slot].UnlinkNode(currptr); + m_listarray[newslot].LinkNode(currptr); + } + currptr = nextptr; + } + } + } + + } + + //======================================================================= + BOOL IsForWriting (LH lockedhandle) { + return (lockedhandle == (LH)1); + } + + //======================================================================= + void SyncEnterLock (LH *lockedhandle, BOOL forwriting) { + m_sync.Enter(forwriting); + *lockedhandle = (LH)(forwriting ? 1 : -1); + } + + //======================================================================= + void SyncLeaveLock (LH lockedhandle) { + if (lockedhandle) + m_sync.Leave(IsForWriting(lockedhandle)); + } + + public: + + //======================================================================= + TSExportTable () { + m_sequence = (H)0; + m_slotmask = 3; + m_listarray.SetNumElements(m_slotmask+1); + int linkoffset = BaseGetLinkOffset(); + for (unsigned slot = 0; slot <= m_slotmask; ++slot) + m_listarray[slot].ChangeLinkOffset(linkoffset); + m_reuselist.ChangeLinkOffset(linkoffset); + } + + //======================================================================= + ~TSExportTable () { + Destroy(); + } + + //======================================================================= + void Delete (H handle) { + LH lockedhandle; + T *ptr = Lock(handle,&lockedhandle,TRUE); + DeleteUnlock(ptr,lockedhandle); + } + + //======================================================================= + void DeleteUnlock (T *ptr, + LH lockedhandle) { + if (ptr) + if (REUSE) + m_reuselist.LinkNode(ptr); + else + delete ptr; + Unlock(lockedhandle); + } + + //======================================================================= + void Destroy () { + LH lockedhandle; + SyncEnterLock(&lockedhandle,TRUE); + for (unsigned slot = 0; slot <= m_slotmask; ++slot) { + T *curr; + while ((curr = m_listarray[slot].Head()) != NULL) { + delete curr; + SErrReportResourceLeak(typeid(H).INTERNALRAWNAME()); + } + } + m_reuselist.Clear(); + SyncLeaveLock(lockedhandle); + } + + //======================================================================= + T * Lock (H handle, + LH *lockedhandle, + BOOL forwriting = FALSE) { + SyncEnterLock(lockedhandle,forwriting); + T *result = BaseFindByHandle(&m_listarray[ComputeSlot(handle)], + (unsigned)handle); + if (!result) { + SyncLeaveLock(*lockedhandle); + *lockedhandle = (LH)0; + } + return result; + } + + //======================================================================= + void New (H *handle) { + LH lockedhandle; + NewLock(handle,&lockedhandle); + Unlock(lockedhandle); + } + + //======================================================================= + T * NewLock (H *handle, LH *lockedhandle) { + SyncEnterLock(lockedhandle,TRUE); + H newhandle = GenerateUniqueHandle(); + T *ptr = NULL; + if (REUSE) { + ptr = m_reuselist.Head(); + if (ptr) + m_listarray[ComputeSlot(newhandle)].LinkNode(ptr); + } + if (!ptr) + ptr = m_listarray[ComputeSlot(newhandle)].NewNode(); + BaseSetHandle(ptr,(unsigned)newhandle); + *handle = newhandle; + return ptr; + } + + //======================================================================= + void Unlock (LH lockedhandle) { + SyncLeaveLock(lockedhandle); + } + +}; + +template +class TSExportObject : public TSExplicitNode { + friend class TSExportTableBase; + + private: + unsigned m_handle; + LINKEX(T) m_linktoslot; + + public: + + //======================================================================= + TSExportObject () { + } + + //======================================================================= + TSExportObject (const TSExportObject &source) { + } + + //======================================================================= + TSExportObject & operator= (const TSExportObject &source) { + // COPY THE OBJECT DATA, BUT DON'T OVERWRITE THE DESTINATION OBJECT'S + // HANDLE OR LINK + return *this; + } + +}; + +#define SYNC_NONE CNullSync +#define SYNC_READWRITE CLock +#define SYNC_ALWAYS CCritSect + +#define EXPORTOBJECTDECL(structname) \ + typedef struct structname : public TSExportObject< structname > + +#define EXPORTTABLE(structname,handlename,lockedhandlename,synctype) \ + TSExportTable + +#define EXPORTTABLEREUSE(structname,handlename,lockedhandlename,synctype) \ + TSExportTable + + +/**************************************************************************** +* +* SWAP -- Swap template +* +* Macros: +* +* SWAP(a,b) +* +***/ + +//=========================================================================== +template +void inline TSSwap (T &a, T &b) { + T temp = a; + a = b; + b = temp; +} +#define SWAP(a,b) TSSwap(a,b) + + +/**************************************************************************** +* +* Old TList Template -- Obsolete!! +* +***/ + +//=========================================================================== +template +BOOL inline TListAdd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return FALSE; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber,0); + if (!newptr) + return FALSE; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = *head; + *head = newptr; + return TRUE; +} +#define LISTADD(a,b) TListAdd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddEnd (T **head, T *rec, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && rec)) + return FALSE; + + T *newptr = (T *)SMemAlloc(sizeof(T),filename,linenumber,0); + if (!newptr) + return FALSE; + CopyMemory(newptr,rec,sizeof(T)); + newptr->next = NULL; + + T **next = head; + while (*next) + next = &(*next)->next; + *next = newptr; + + return TRUE; +} +#define LISTADDEND(a,b) TListAddEnd(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListAddPtr (T **head, T *ptr) { + if (!(head && ptr)) + return FALSE; + + ptr->next = *head; + *head = ptr; + return TRUE; +} +#define LISTADDPTR(a,b) TListAddPtr(a,b) + +//=========================================================================== +template +BOOL inline TListAddPtrEnd (T **head, T *ptr) { + if (!(head && ptr)) + return FALSE; + + ptr->next = NULL; + T **next = head; + while (*next) + next = &(*next)->next; + *next = ptr; + + return TRUE; +} +#define LISTADDPTREND(a,b) TListAddPtrEnd(a,b) + +//=========================================================================== +template +BOOL inline TListClear (T **head, LPCSTR filename = NULL, int linenumber = 0) { + if (!head) + return FALSE; + + while (*head) { + T *next = (*head)->next; + SMemFree(*head,filename,linenumber,0); + *head = next; + } + return TRUE; +} +#define LISTCLEAR(a) TListClear(a,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFree (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return FALSE; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + SMemFree(ptr,filename,linenumber,0); + return (*next != NULL); +} +#define LISTFREE(a,b) TListFree(a,b,(LPCSTR)__FILE__,__LINE__) + +//=========================================================================== +template +BOOL inline TListFreePtr (T **head, T *ptr, LPCSTR filename = NULL, int linenumber = 0) { + if (!(head && ptr)) + return FALSE; + + T **next = head; + while (*next && (*next != ptr)) + next = &(*next)->next; + if (*next) + *next = (*next)->next; + + return (*next != NULL); +} +#define LISTFREEPTR(a,b) TListFreePtr(a,b,(LPCSTR)__FILE__,__LINE__) + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import off +#endif + +#endif // ifndef _STORM_H_ diff --git a/Storm/HELP/STORM.HLP b/Storm/HELP/STORM.HLP new file mode 100644 index 0000000..3a09005 Binary files /dev/null and b/Storm/HELP/STORM.HLP differ diff --git a/Storm/LIB/STORM.LIB b/Storm/LIB/STORM.LIB new file mode 100644 index 0000000..986e26a Binary files /dev/null and b/Storm/LIB/STORM.LIB differ diff --git a/Storm/LIB/STORMD.LIB b/Storm/LIB/STORMD.LIB new file mode 100644 index 0000000..649bed1 Binary files /dev/null and b/Storm/LIB/STORMD.LIB differ diff --git a/Storm/LIB/STORMST.LIB b/Storm/LIB/STORMST.LIB new file mode 100644 index 0000000..988a57d Binary files /dev/null and b/Storm/LIB/STORMST.LIB differ diff --git a/Storm/LIB/STORMST.RES b/Storm/LIB/STORMST.RES new file mode 100644 index 0000000..2433693 Binary files /dev/null and b/Storm/LIB/STORMST.RES differ diff --git a/Storm/PKWARE/BIN/IMPBORL.DLL b/Storm/PKWARE/BIN/IMPBORL.DLL new file mode 100644 index 0000000..badd2a1 Binary files /dev/null and b/Storm/PKWARE/BIN/IMPBORL.DLL differ diff --git a/Storm/PKWARE/BIN/IMPLODE.DLL b/Storm/PKWARE/BIN/IMPLODE.DLL new file mode 100644 index 0000000..3fd5aca Binary files /dev/null and b/Storm/PKWARE/BIN/IMPLODE.DLL differ diff --git a/Storm/PKWARE/EXAMPLES.TXT b/Storm/PKWARE/EXAMPLES.TXT new file mode 100644 index 0000000..18f8ad8 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES.TXT @@ -0,0 +1,142 @@ +******************************************************************* +*** Important information for use with the *** +*** PKWARE Data Compression Library (R) for Win32 *** +*** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** +*** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** +******************************************************************* + +* The examples provided show how the PKWARE Data Compression Library is + implemented. These examples show how to do "file-to-file" compression, + "memory-to-memory" compression, and disk spanning. We recommend that + you run the examples with a debugger, and set breakpoints in the I/O + callback functions. These functions handle the data I/O, and can be + modified to compress or extract data from any device, not just from a file. + + +* Visual C++ users + + * To build a Visual C++ project, load the Visual Workbench, and open + the .MAK file through the "Open" menu item under "Project." This + will automatically update the makefile to the path of where the + examples are installed. + + * To make a VC++ .MAK file, add all the files in the example directory + with the extensions: *.c*, *.rc, *.def, *.lib + +* Borland C++ 4.x users + + * Borland .IDE files are provided for each example on the distribution + disk. You must set your include and library directories by going into + the OPTIONS | PROJECT | DIRECTORIES window. + + * If you are making your own .IDE file, add all the files in the current + directory to the project with the extensions: *.c*, *.rc, *.def, *.lib. + + +* DLL examples + + If you will be using the DLL examples, make sure that IMPLODE.DLL and/or + IMPBORL.DLL is in your user path. + + +Directory Structure for the examples: + + ÀÄÄÄEXAMPLES + ÃÄÄÄCMDLINE + ³ ÃÄÄÄFIL2FIL + ³ ÃÄÄÄMEM2MEM + ³ ÀÄÄÄMULTFILE + ÃÄÄÄGUI + ³ ÃÄÄÄFIL2FIL + ³ ÀÄÄÄMEM2MEM + ÃÄÄÄMFC + ³ ÃÄÄÄFIL2FIL + ³ ³ ÀÄÄÄRES + ³ ÃÄÄÄMEM2MEM + ³ ³ ÀÄÄÄRES + ³ ÃÄÄÄMULTFILE + ³ ³ ÀÄÄÄRES + ³ ÀÄÄÄSPAN + ³ ÀÄÄÄRES + ÀÄÄÄOWL + ÃÄÄÄMEM2MEM + ÀÄÄÄSPAN + + +CMDLINE Examples +---------------- + +FIL2FIL => This example shows how to compress and uncompress from one + file to another. Requires the TEST.IN file in the executable + directory to run. + +MEM2MEM => This example shows how to compress and uncompress from one + memory buffer to another. TEST.IN must be less than 62K bytes. + +MULTFILE => This example shows how to compress multiple files into one file, + then uncompress the file. The multiple files must be specified + on the command line. + + +GUI Examples +------------ + +FIL2FIL => SDK Windows example. Requires the TEST.IN file in the executable + directory to run. + +MEM2MEM => SDK Windows example. Requires the TEST.IN file in the executable + directory to run. This example shows how to compress and + uncompress from one memory buffer to another. + + +MFC Examples +------------ + +FIL2FIL => Written using Visual C++ with MFC and the static link library. + Requires the TEST.IN file in the executable directory to run. + This example also contains debugging statements to help display + how the PKWARE Data Compression Library calls the read and write + routines repeatedly. + +MEM2MEM => This example shows how to compress and uncompress from one + memory buffer to another. Written using Visual C++ with MFC + (also uses MFC DLL). Prompts for file to load, which must be + less than 62K bytes. + +MULTFILE => This example shows how to compress multiple files into one file, + then uncompress the file. Written using Visual C++ with MFC + (also uses MFC DLL). + +SPAN => Written using Visual C++ with MFC (also uses MFC DLL). This + example uses MULTFILE as a base, but includes disk spanning. + All files are extracted to a temporary directory, C:\TEMP\. + To change the extract directory, modify the global variable + "UncompressDir" in MAINFRM.CPP. + + +OWL Examples +------------ + +MEM2MEM => This example shows how to compress and uncompress from one + memory buffer to another. Written using Borland C++ 4.5 with OWL. + Prompts for file to load, which must be less than 62K bytes. + + +SPAN => Written using Borland C++ 4.5 with OWL. This example compresses + multiple files and includes disk spanning. All files are + extracted to a temporary directory, C:\TEMP\. To change the + extract directory, modify the global variable "UncompressDir" + in SPANAPP.CPP. + + +Directions on Using MULTFILE and SPAN Programs: + + To compress multiple files: Select Compress Files from the File + menu, and use the Shift and Ctrl keys with the mouse to + highlight multiple files. Select OK after selecting the files. + Enter the path and name of file to compress the selected files + to. + + To uncompress a file: Select Uncompress Files from the File menu, + and enter or select the file to uncompress, then select the OK + button. The files will be uncompressed in the same directory. diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/BORLDLL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/BORLDLL.BAT new file mode 100644 index 0000000..6900790 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/BORLDLL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using Borland compiler and DLL +: + +bcc32 example.c ..\..\..\impborli.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/EXAMPLE.C b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/EXAMPLE.C new file mode 100644 index 0000000..589d5b4 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/EXAMPLE.C @@ -0,0 +1,132 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#include +#include + +#include "implode.h" + +/* Define a structure containing data to be passed to the callback + functions through the user defined parameter. +*/ + +struct PassedParam +{ + unsigned int CmpPhase; + FILE *InFile; + FILE *OutFile; + unsigned long CRC; +}; + +/*------------------------------------------------------------------- + Routine to supply data to the implode() or explode() routines. + When this routine returns 0 bytes read, the implode() or explode() + routines will terminate. Also calculate the CRC-32 on the original + uncompressed data during the implode() call. +*/ + +unsigned int ReadData(char *Buff, unsigned int *Size, void *Param) +{ + size_t Read; + struct PassedParam *Par = (struct PassedParam *)Param; + + Read = fread(Buff, 1, *Size, Par->InFile); + if (Par->CmpPhase) + Par->CRC = crc32(Buff, (unsigned int *)&Read, &Par->CRC); + + return (unsigned int)Read; +} + +/*------------------------------------------------------------------- + Routine to write compressed data output from implode() or + uncompressed data from explode(). Also calculate the CRC on + the uncompressed data during the explode() call. +*/ + +void WriteData(char *Buff, unsigned int *Size, void *Param) +{ + struct PassedParam *Par = (struct PassedParam *)Param; + + fwrite(Buff, 1, *Size, Par->OutFile); + if (!Par->CmpPhase) + Par->CRC = crc32(Buff, Size, &Par->CRC); +} + +int cdecl main(void) +{ + char *WorkBuff; /* buffer for compression tables */ + unsigned int Error; + unsigned int type; /* ASCII or Binary compression */ + unsigned int dsize; /* Dictionary Size. 1,2 or 4K */ + unsigned long OrgCRC; /* CRC of original input file */ + struct PassedParam Param; /* Parameters passed to callback functions */ + + /* Open the input file */ + Param.InFile = fopen("test.in","rb"); + if (Param.InFile == NULL) + { + puts("Unable to open input file"); + return 1; + } + + /* Create the output compressed file */ + Param.OutFile = fopen("test.cmp","wb"); + + /* Allocate memory for implode work buffer */ + WorkBuff = (char *)malloc(CMP_BUFFER_SIZE); + if (WorkBuff == NULL) + { + puts("Unable to allocate work buffer"); + return 1; + } + + /* Initialize CRC */ + Param.CmpPhase = 1; + Param.CRC = (unsigned long) -1; + + type = CMP_ASCII; /* Use ASCII compression */ + dsize = 4096; /* Use 4K dictionary */ + + puts("Calling Implode"); + implode(ReadData, WriteData, WorkBuff, &Param, &type, &dsize); + puts("Done Compressing"); + + OrgCRC = ~Param.CRC; + free(WorkBuff); + + fclose(Param.InFile); + fclose(Param.OutFile); + + /* Compression done, now try extracting the compressed file */ + + WorkBuff = (char *)malloc(EXP_BUFFER_SIZE); + if (WorkBuff == NULL) + { + puts("Unable to allocate work buffer"); + return 1; + } + + Param.InFile = fopen("test.cmp","rb"); /* Compressed file */ + Param.OutFile = fopen("test.ext","wb"); /* File to extract to */ + + /* Initialize CRC */ + Param.CmpPhase = 0; + Param.CRC = (unsigned long) -1; + + puts("Calling Explode"); + Error = explode(ReadData, WriteData, WorkBuff, &Param); + + Param.CRC = ~Param.CRC; + free(WorkBuff); + fclose(Param.InFile); + fclose(Param.OutFile); + + printf("Uncompression completed - Error %d\n", Error); + printf("Original CRC=%08lx Uncompressed CRC=%08lx\n",OrgCRC,Param.CRC); + + return 0; +} + diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/IMPLODE.H b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKE.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKE.BAT new file mode 100644 index 0000000..0eae9b5 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKE.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program +: + +cl example.c ..\..\..\implode.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKEBORL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKEBORL.BAT new file mode 100644 index 0000000..b47bbcc --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKEBORL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using Borland compiler +: + +bcc32 example.c ..\..\..\impborl.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKEDLL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKEDLL.BAT new file mode 100644 index 0000000..3810184 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/FIL2FIL/MAKEDLL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using DLL +: + +cl example.c ..\..\..\implodei.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/BORLDLL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/BORLDLL.BAT new file mode 100644 index 0000000..0fd6b68 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/BORLDLL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using Borland compiler and DLL +: + +bcc32 mem2mem.c ..\..\..\impborli.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/IMPLODE.H b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKE.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKE.BAT new file mode 100644 index 0000000..6f5fab1 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKE.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program +: + +cl mem2mem.c ..\..\..\implode.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKEBORL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKEBORL.BAT new file mode 100644 index 0000000..742ce25 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKEBORL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using Borland compiler +: + +bcc32 mem2mem.c ..\..\..\impborl.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKEDLL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKEDLL.BAT new file mode 100644 index 0000000..6eae367 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MAKEDLL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using DLL +: + +cl mem2mem.c ..\..\..\implodei.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MEM2MEM.C b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MEM2MEM.C new file mode 100644 index 0000000..6cceb3a --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MEM2MEM/MEM2MEM.C @@ -0,0 +1,286 @@ +/************************************************************************* + Example to interface the PKWARE Data Compression Library (R) + Copyright 1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off + Version 1.11 + + This example takes a file from the disk (file must be <= 62K), + compresses the file to memory, and then expands the compressed + data back into another memory buffer. This data is then written + to a file called test.ext, that can be compared to the original file. +*************************************************************************/ + +#include +#include +#include + +#include "implode.h" + +#define BUFFERSIZE ((long)(62 * 1024)) /* File size limit */ +#define FALSE 0 +#define TRUE (!FALSE) + +typedef struct PassedParam +{ + char *pSource; /* Pointer to source buffer */ + char *pDestination; /* Pointer to destination buffer */ + unsigned long SourceOffset; /* Offset into the source buffer */ + unsigned long DestinationOffset; /* Offset into the destination buffer */ + unsigned long CompressedSize; /* Need this for extracting! */ + unsigned long UnCompressedSize; /* Size of uncompressed data file */ + unsigned long BufferSize; + unsigned long Crc; /* Calculated CRC value */ + unsigned long OrigCrc; /* Original CRC value of data */ +} PARAM; + + +/* +** BufferSize defines the maximum size allowed for output of compressed +** data from implode(), or uncompressed data from explode(). Notice that +** if you are compressing files that compress to a size greater than +** BufferSize, an error message will result. You can modify the value of +** BufferSize if you need a bigger buffer. If you know your maximum file +** size, you can adjust BUFFERSIZE. This will allow for larger, or smaller +** maximum values of BufferSize. +*/ + +/* Routine to read uncompressed data. Used only by implode(). +** This routine reads the data that is to be compressed. +*/ + +unsigned int +ReadUnCompressed(char *buff, unsigned int *size, void *Param) +{ + PARAM *Ptr = (PARAM *) Param; + + if (Ptr->UnCompressedSize == 0L) + { + /* This will terminate the compression or extraction process */ + return(0); + } + + if (Ptr->UnCompressedSize < (unsigned long)*size) + { + *size = (unsigned int)Ptr->UnCompressedSize; + } + + memcpy(buff, Ptr->pSource + Ptr->SourceOffset, *size); + Ptr->SourceOffset += (unsigned long)*size; + Ptr->UnCompressedSize -= (unsigned long)*size; + Ptr->Crc = crc32(buff, size, &Ptr->Crc); + + return(*size); +} + +/* Routine to read compressed data. Used only by explode(). +** This routine reads the compressed data that is to be uncompressed. +*/ + +unsigned int +ReadCompressed(char *buff, unsigned int *size, void *Param) +{ + PARAM *Ptr = (PARAM *) Param; + + if (Ptr->CompressedSize == 0L) + { + /* This will terminate the compression or extraction process */ + return(0); + } + + if (Ptr->CompressedSize < (unsigned long)*size) + { + *size = (unsigned int)Ptr->CompressedSize; + } + + memcpy(buff, Ptr->pSource + Ptr->SourceOffset, *size); + Ptr->SourceOffset += (unsigned long)*size; + Ptr->CompressedSize -= (unsigned long)*size; + + return(*size); +} + +/* Routime to write compressed data. Used only by implode(). +** This routine writes the compressed data to a memory buffer. +*/ + +void +WriteCompressed(char *buff, unsigned int *size, void *Param) +{ + PARAM *Ptr = (PARAM *) Param; + + if (Ptr->CompressedSize + (unsigned long)*size > Ptr->BufferSize) + { + puts("Compressed data will overflow buffer. Increase size of buffer!"); + exit(1); + } + memcpy(Ptr->pDestination + Ptr->DestinationOffset, buff, *size); + Ptr->DestinationOffset += (unsigned long)*size; + Ptr->CompressedSize += (unsigned long)*size; +} + +/* Routine to write uncompressed data. Used only by explode(). +** This routine writes the uncompressed data to a memory buffer. +*/ + +void +WriteUnCompressed(char *buff, unsigned int *size, void *Param) +{ + PARAM *Ptr = (PARAM *) Param; + + if (Ptr->CompressedSize + (unsigned long)*size > Ptr->BufferSize) + { + puts("Compressed data will overflow buffer. Increase size of buffer!"); + exit(1); + } + memcpy(Ptr->pDestination + Ptr->DestinationOffset, buff, *size); + Ptr->DestinationOffset += (unsigned long)*size; + Ptr->UnCompressedSize += (unsigned long)*size; + Ptr->Crc = crc32(buff, size, &Ptr->Crc); +} + +void +main(int argc, char *argv[]) +{ + char *WorkBuff; /* Buffer for compression tables */ + char *InFileName; + char *temp; + unsigned int error; + unsigned int bytes_read; + unsigned int type; + unsigned int dsize; + unsigned int written; + PARAM Param; + FILE *InFile; + FILE *OutFile; + + /* Use the first command line argument as the name of the file + ** to read as the data source. If no filename is given, default + ** to use "test.in" + */ + if (argc > 1) + { + InFileName = argv[1]; + } + else + { + InFileName = "test.in"; + } + + /* Open the file so it's contents can be read into memory. */ + if ((InFile = fopen(InFileName, "rb")) == NULL) + { + puts("Unable to open input file."); + exit(1); + } + + /* Determine the size of the file, and rewind to beginning of file. */ + if (fseek(InFile, 0L, SEEK_END)) + { + puts("Unable to determine input file size."); + exit(1); + } + Param.UnCompressedSize = ftell(InFile); + fseek(InFile, 0L, SEEK_SET); + + if (Param.UnCompressedSize > BUFFERSIZE) + { + fclose(InFile); + printf("Cannot compress files larger than %d.\n",BUFFERSIZE); + exit(1); + } + Param.BufferSize = Param.UnCompressedSize; + Param.CompressedSize = 0L; + + /* Allocate memory buffers to hold the compressed and uncompressed + ** contents of the data file. + */ + Param.pSource = (char *)malloc(Param.BufferSize); + Param.pDestination = (char *)malloc(Param.BufferSize); + + /* We make the destination buffer the same size as the source buffer. + ** You should determine what compression ratios you achieve with your + ** specific data. You may only need a destination buffer about one half + ** the size of the source buffer (assuming 50% compression). + */ + + if (Param.pSource == NULL || Param.pDestination == NULL) + { + puts("Unable to allocate source & destination buffers."); + exit(1); + } + + /* Read the contents of the file into the uncompressed data buffer. */ + fread((void *)Param.pSource, 1, Param.UnCompressedSize, InFile); + fclose(InFile); + + /* Allocate the buffer used by implode() for compression tables. */ + WorkBuff = (char *)malloc(CMP_BUFFER_SIZE); + if (WorkBuff == NULL) + { + puts("Unable to allocate work buffer."); + return; + } + + puts("Calling Implode"); + type = CMP_ASCII; + dsize = 1024; + + Param.SourceOffset = 0L; + Param.DestinationOffset = 0L; + Param.Crc = (unsigned long) -1; + implode(ReadUnCompressed,WriteCompressed,WorkBuff,&Param,&type,&dsize); + Param.OrigCrc = ~Param.Crc; + free(WorkBuff); + + /* Since the imploding is done, the data in the compressed buffer + ** will be used as the source for the exploding process. + */ + temp = Param.pSource; + Param.pSource = Param.pDestination; + Param.pDestination = temp; + + /* Clear buffer containing original uncompressed data */ + memset(Param.pDestination, 0, Param.UnCompressedSize); + + /* Allocate the buffer used by explode() for compression tables. */ + WorkBuff = (char *)malloc(EXP_BUFFER_SIZE); + if (WorkBuff == NULL) + { + puts("Unable to allocate work buffer."); + return; + } + Param.SourceOffset = 0L; + Param.DestinationOffset = 0L; + Param.UnCompressedSize = 0L; + Param.Crc = (unsigned long) -1; + + /* Now try extracting the compressed file data */ + puts("Calling Explode"); + error = explode(ReadCompressed,WriteUnCompressed,WorkBuff,&Param); + Param.Crc = ~Param.Crc; + + if (error || (Param.Crc != Param.OrigCrc)) + { + puts("Error in compressed data!"); + } + printf("Original CRC=%lx Uncompressed CRC=%lx\n",Param.OrigCrc, Param.Crc); + + /* The uncompressed data is now in pDestination. Lets write this to a file + ** called test.ext. We can compare this buffer to the original input file. + */ + + if ((OutFile = fopen("test.ext", "wb+")) == NULL) + { + puts("Unable to open output file."); + } + else + { + fwrite((void *)Param.pDestination, 1, Param.UnCompressedSize, OutFile); + fclose(OutFile); + } + + /* Free buffers */ + free(WorkBuff); + free(Param.pSource); + free(Param.pDestination); +} diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/BORLDLL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/BORLDLL.BAT new file mode 100644 index 0000000..4df5376 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/BORLDLL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using Borland compiler and DLL +: + +bcc32 multfile.c ..\..\..\impborli.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/IMPLODE.H b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKE.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKE.BAT new file mode 100644 index 0000000..4db430f --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKE.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program +: + +cl multfile.c ..\..\..\implode.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKEBORL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKEBORL.BAT new file mode 100644 index 0000000..d04c870 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKEBORL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using Borland compiler +: + +bcc32 multfile.c ..\..\..\impborl.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKEDLL.BAT b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKEDLL.BAT new file mode 100644 index 0000000..9b433a5 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MAKEDLL.BAT @@ -0,0 +1,5 @@ +: +: Make file for example program using DLL +: + +cl multfile.c ..\..\..\implodei.lib diff --git a/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MULTFILE.C b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MULTFILE.C new file mode 100644 index 0000000..2bcabd4 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/CMDLINE/MULTFILE/MULTFILE.C @@ -0,0 +1,479 @@ +/************************************************************************* + Example to interface the PKWARE Data Compression Library (R) + Copyright 1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off + Version 1.11 + + This example compresses a set of one or more files into a single + output file. The set of files is taken from the command line. Each + file is compressed, and written to the output file. A record + holding information for each file is written to the output file along + with the compressed data. The name of the compressed output file + created by this program is PKWDCL.CMP. +**************************************************************************/ + +#include +#include +#include +#include + +#include "implode.h" + +#define BUFSIZE 2048 /* Work buffer */ +#define TEMPNAME "PKWDCL.TMP" /* Temporary file */ +#define COMPRESSED_FILE_NAME "PKWDCL.CMP" /* Name of compressed output file */ +#define FALSE 0 +#define TRUE (!FALSE) + + +/* +** Structure definitions +*/ + +typedef struct FileHeader +{ + char signature[4]; /* Signature in case of errors */ + char filename[13]; /* File name */ + unsigned long CompSize; /* Compressed size of file */ + unsigned long UnCompSize; /* Original size of file */ + unsigned long Crc; /* Crc value for file */ +} HEADER; +/* +** This structure will be written to the compressed output file and +** will record information for each input file that is compressed +** into the output file. +*/ + +typedef struct PassedParam +{ + FILE *InFile; /* Pointer to file for reading data */ + FILE *OutFile; /* Pointer to file for writing data */ + FILE *Destination; /* Pointer to compressed output file */ + int Imploding; /* Flag indicating compression or */ + /* uncompression is in progress. */ + unsigned long Crc; /* CRC value for current file. */ + unsigned long OrigCrc; /* Original CRC for a file */ + unsigned long CompressedFileSize; /* Size of compressed file */ + unsigned long UnCompressedFileSize;/* Original file size */ +} PARAM; +/* +** This structure is used to pass values shared between the main +** application and the callback functions called by implode() and +** explode(). +*/ + + +/* +** Function Prototypes +*/ +unsigned long FileSize(FILE *); +void ReadHeader(FILE *, HEADER *); +void SkipFile(FILE *, unsigned long); +void Expand(char *,int); +void CompressFile(char *, char *, PARAM *); +void AppendFile(FILE *,unsigned long); +void WriteHeader(char *, PARAM *); +void Compress(char *,int, char **); + + +/* The ReadBuff function is used by the implode() and explode() +** functions to read a stream of data that will be either +** compressed, or uncompressed. +*/ + +unsigned int +ReadBuff(char *buff, unsigned int *size, void *Param) +{ + PARAM *Ptr = (PARAM *) Param; + unsigned int Read = 0; + + /* This function may ask for up to 4K of data at a time. If your archive + ** file contains several compressed files, you may read too much. For + ** example, your first compressed file in the archive may be 100 bytes. + ** So you do not want to read more than 100 bytes or you'll be unable to + ** uncompress the second file, since you will not be located at the + ** beginning of the file any longer. We will use the variable + ** "CompressedFileSize" to check for this condition. + */ + + if (Ptr->Imploding == FALSE) + { + /* If we are exploding data, and the number of bytes left in the + ** compressed file is less than the number of bytes requested, then + ** set the number of bytes requested to the bytes remaining in the + ** compressed file. + */ + + /* Set size to bytes left */ + + if ((unsigned long)*size > Ptr->CompressedFileSize) + { + *size = (unsigned)Ptr->CompressedFileSize; + } + + /* Subtract the number of bytes read from the total size of the + ** compressed file. + */ + + Ptr->CompressedFileSize -= (unsigned long)*size; + } + + /* Read 'size' bytes from input source */ + Read = fread(buff, 1, *size, Ptr->InFile); + + if (Ptr->Imploding == FALSE) + { + /* Check the CRC value of data as it's uncompressed. */ + Ptr->Crc = crc32(buff, &Read, &Ptr->Crc); + } + + /* Return the number of bytes read from the input source */ + return(Read); +} + +/* The WriteBuff function is used by the implode() and explode() +** functions to write a stream of data that has been either +** compressed, or uncompressed. +*/ + +void +WriteBuff(char *buff, unsigned int *size, void *Param) +{ + /* If compressing data, add the number of bytes to 'CompressedFileSize'. + ** We need to keep track of the size of the compressed file. + */ + + PARAM *Ptr = (PARAM *) Param; + int Written; + + if (Ptr->Imploding) + { + Ptr->CompressedFileSize += (unsigned long)*size; + } + + /* Write the data to the file. If we are Imploding, this is compressed + ** data. Otherwise it is uncompressed data. + */ + + Written = fwrite((void *)buff, 1, *size, Ptr->OutFile); + if (Written != *size) + { + puts("Failed to write compressed data"); + } + if (Ptr->Imploding == TRUE) + { + /* Calculate the CRC value of data as it's compressed. */ + Ptr->Crc = crc32(buff, size, &Ptr->Crc); + } +} + +/* The ReadHeader function is used to read a HEADER data structure +** from the compressed output file. This HEADER record contains the +** information about the compressed file. +*/ +void +ReadHeader(FILE *pFile, HEADER *header) +{ + fread(header, 1, sizeof(HEADER), pFile); +} + +/* The SkipFile function is used to skip over a file that is in +** the compressed output file if that file is not to be uncompressed. +*/ +void +SkipFile(FILE *pFile, unsigned long Size) +{ + fseek(pFile, Size, SEEK_CUR); +} + +/* The FileSize function is used to determine the number of +** bytes in a file that is to be compressed. +*/ +unsigned long +FileSize(FILE *pFile) +{ + unsigned long Size; + + if (fseek(pFile, 0L, SEEK_END)) + { + puts("Unable to determine input file size."); + } + Size = ftell(pFile); + fseek(pFile, 0L, SEEK_SET); + + return(Size); +} + +/* The Expand function is used to uncompress the files that were +** written to the compressed output file. A prompt is displayed +** for each file allowing the user to skip the file if it is not +** to be uncompressed. +*/ +void +Expand(char *WorkBuff, int Files) +{ + HEADER header; + PARAM Param; + int error; + int i; + int FileCount; + char ch; + char s[80]; + + memset( &Param, 0, sizeof(Param) ); + + Param.InFile = fopen(COMPRESSED_FILE_NAME, "rb"); + if (Param.InFile == NULL) + { + printf("Unable to open compressed output file %s\n",COMPRESSED_FILE_NAME); + } + + for (FileCount = 1; FileCount < Files; FileCount++) + { + Param.CompressedFileSize = 0L; + ReadHeader(Param.InFile,&header); + + /* Display a message and ask if you wish to extract this file */ + sprintf(s,"Extract file %s ? File is %lu bytes. (Y/N)", + header.filename, header.UnCompSize); + puts(s); + + /* We need to remember how many bytes are in this compressed data + ** stream. We don't want to read too many bytes. + */ + Param.CompressedFileSize = header.CompSize; + Param.OrigCrc = header.Crc; + Param.Imploding = FALSE; + + do + { + ch = toupper(getchar()); + } + while(ch != 'Y' && ch != 'N'); + if (ch == 'Y') + { + /* If the file is to be uncompressed, create new, empty file + ** of the same name where the uncompressed contents of the + ** file will be written. + */ + Param.OutFile = fopen(header.filename, "wb+"); + if (Param.OutFile == NULL) + { + printf("Unable to open output data file %s\n",header.filename); + /* Skip past this file and go on to the next one. */ + SkipFile(Param.InFile,Param.CompressedFileSize); + } + else + { + /* Call explode to uncompress the file. */ + Param.Crc = (unsigned long) -1; + error = explode(ReadBuff,WriteBuff,WorkBuff,&Param); + Param.Crc = ~Param.Crc; + if (error || (Param.OrigCrc != Param.Crc)) + { + printf("Error in compressed file %s!\n",header.filename); + } + printf("Expanding file %s Original CRC = %lx Uncompressed CRC = %lx\n",header.filename,Param.OrigCrc,Param.Crc); + /* Close the file we just created */ + fclose(Param.OutFile); + } + } + else + { + /* Skip past this file and go on to the next one. */ + SkipFile(Param.InFile,Param.CompressedFileSize); + } + } + fclose(Param.InFile); +} + +/* The CompressFile function is used to compress a file into a +** temporary file. +*/ +void +CompressFile(char *file, char *WorkBuff, PARAM *Param) +{ + unsigned int type; /* Compression type */ + unsigned int dsize; /* Dictionary size */ + + /* Set the compression type to BINARY compression */ + type = CMP_BINARY; + + /* Set the compression dictionary size to 4K */ + dsize = 4096; + + /* Open the file to be compressed. */ + Param->InFile = fopen(file, "rb"); + if (Param->InFile == NULL) + { + puts("Unable to open input file"); + return; + } + + /* Open the temporary file where the compressed data will be written. */ + Param->OutFile = fopen(TEMPNAME, "wb+"); + if (Param->OutFile == NULL) + { + printf("Unable to open temporary output file %s\n",Param->OutFile); + } + else + { + Param->Crc = (unsigned long) -1; + Param->UnCompressedFileSize = FileSize(Param->InFile); + + /* Call implode() to compress the file. */ + implode(ReadBuff,WriteBuff,WorkBuff,Param,&type,&dsize); + printf("Compressing file %s", file); + printf(" File size = %ld bytes Compressed size = %ld bytes\n", + Param->UnCompressedFileSize,Param->CompressedFileSize); + + /* Close the temp file and the file being compressed */ + Param->OrigCrc = ~Param->Crc; + fclose(Param->InFile); + fclose(Param->OutFile); + } +} + +/* The AppendFile function is used to copy the compressed data from +** the temporary file to the compressed output file after the +** header record for the file has been written. +*/ + +void +AppendFile(FILE *pDest,unsigned long Size) +{ + char buf[BUFSIZE]; + unsigned long left; + unsigned int Read; + unsigned int written; + FILE *pFile; + + /* Keep track of the number of bytes that need to be appended */ + left = Size; + + /* Open the temporary file containing the compressed input file + ** data. The contents of this file are then written to the + ** final output file. + */ + if ((pFile = fopen(TEMPNAME, "rb")) != NULL) + { + do + { + Read = fread(buf, 1, BUFSIZE, pFile); + written = fwrite(buf, 1, Read, pDest); + left -= (unsigned long)written; + } + while (left && written); + fclose(pFile); + } + else + { + printf("Unable to open temporary file %s\n",TEMPNAME); + } +} + +/* The WriteHeader function is used to format and write the +** record header for each file compressed into the compressed +** output file. +*/ +void +WriteHeader(char *filename, PARAM *Param) +{ + HEADER header; + int Written; + + /* Save the filename and compressed file size in the structure */ + strcpy(header.filename, filename); + header.CompSize = Param->CompressedFileSize; + header.UnCompSize = Param->UnCompressedFileSize; + header.Crc = Param->OrigCrc; + + /* Save a signature, can be used to help rebuild a damaged file */ + header.signature[0] = 'D'; + header.signature[1] = 'H'; + header.signature[2] = 9; + header.signature[3] = 2; + + /* Write the data to the compressed archive file */ + Written = fwrite(&header, 1, sizeof(HEADER), Param->Destination); + if (Written != sizeof(HEADER)) + { + puts("Failed to write compressed file header record."); + } +} + +/* The Compress function is used to compress each file specified +** on the command line. +*/ +void +Compress(char *WorkBuff, int Files, char** FileList) +{ + PARAM Param; + int FileCount; + + memset( &Param, 0, sizeof(Param) ); + + /* Open the file that will be the final output file for all + ** of the compressed input files. + */ + Param.Destination = fopen(COMPRESSED_FILE_NAME, "wb+"); + if (Param.Destination == NULL) + { + printf("Unable to open compressed output file %s\n",COMPRESSED_FILE_NAME); + } + else + { + /* For each file specified on the command line, compress the file, + ** write a header record for the file, then write the compressed + ** file data to the output file. + */ + for (FileCount = 1; FileCount < Files; FileCount++) + { + Param.Imploding = TRUE; + Param.CompressedFileSize = 0L; + Param.OrigCrc = 0L; + CompressFile(FileList[FileCount], WorkBuff,&Param); + WriteHeader(FileList[FileCount], &Param); + AppendFile(Param.Destination,Param.CompressedFileSize); + } + + if( Param.InFile ) + fclose(Param.InFile); + fclose(Param.Destination); + unlink(TEMPNAME); + } +} + +/* The main function simply allocates a work buffer needed for +** calling the implode() and explode() functions, and then +** calls the functions will compress and uncompress the +** files specified on the commandline. +*/ +int +main(int argc, char *argv[]) +{ + char *WorkBuff; /* Buffer for compression tables */ + + if( argc < 2 ) + { + printf( "Usage: multfile filename(s)\n" ); + return 0; + } + + /* Allocate the memory needed for implode(). The explode() routine + ** will use this same buffer, although it can generally use a + ** smaller sized buffer. + */ + WorkBuff = (char *)malloc(CMP_BUFFER_SIZE); + + if (WorkBuff == NULL) + { + puts("Unable to allocate work buffer"); + return 1; + } + Compress(WorkBuff,argc,argv); /* Call Compress, pass the allocated memory */ + Expand(WorkBuff,argc); /* Call Expand, pass the allocated memory. */ + free(WorkBuff); /* Free the allocated memory */ + + return 0; +} diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/IMPLODE.H b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKE.BAT b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKE.BAT new file mode 100644 index 0000000..0d9465f --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKE.BAT @@ -0,0 +1 @@ +nmake makefile.msc diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEDLL.BAT b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEDLL.BAT new file mode 100644 index 0000000..543a8b9 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEDLL.BAT @@ -0,0 +1 @@ +nmake makefdll.msc diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEFDLL.MSC b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEFDLL.MSC new file mode 100644 index 0000000..2ea09e4 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEFDLL.MSC @@ -0,0 +1,18 @@ +ALL : WinDCL.exe + +WinDCL.res : WinDCL.rc resource.h + rc -r WinDCL.rc + +WinDCL.obj : WinDCL.c WinDCL.h + cl -c /D "_X86_" /D "WIN32" WinDCL.c + +# rc WinDCL.res + +LINK32_OBJS= \ + WINDCL.res \ + WINDCL.OBJ \ + +WinDcl.exe : WinDCL.res WinDCL.obj + link /SUBSYSTEM:windows /INCREMENTAL:no /MACHINE:I386 /OUT:"windcl.exe" \ + $(LINK32_OBJS) ..\..\..\IMPLODEI.LIB + diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEFILE.MSC b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEFILE.MSC new file mode 100644 index 0000000..08347b6 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/MAKEFILE.MSC @@ -0,0 +1,18 @@ +ALL : WinDCL.exe + +WinDCL.res : WinDCL.rc resource.h + rc -r WinDCL.rc + +WinDCL.obj : WinDCL.c WinDCL.h + cl -c /D "_X86_" /D "WIN32" WinDCL.c + +# rc WinDCL.res + +LINK32_OBJS= \ + WINDCL.res \ + WINDCL.OBJ \ + +WinDcl.exe : WinDCL.res WinDCL.obj + link /SUBSYSTEM:windows /INCREMENTAL:no /MACHINE:I386 /OUT:"windcl.exe" \ + $(LINK32_OBJS) ..\..\..\IMPLODE.LIB + diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/RESOURCE.H b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/RESOURCE.H new file mode 100644 index 0000000..fce9635 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/RESOURCE.H @@ -0,0 +1,2 @@ +#define IDM_TEST_DCL 1000 + diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WDCLDLL.IDE b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WDCLDLL.IDE new file mode 100644 index 0000000..dda887e Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WDCLDLL.IDE differ diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.C b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.C new file mode 100644 index 0000000..7d0a3f7 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.C @@ -0,0 +1,247 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#include + +#include +#include +#include + +#include "resource.h" +#include "WinDCL.h" +#include "implode.h" + +void TestDLL(void); + +#ifndef _MSC_VER + #pragma argsused +#endif + +int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) +{ + WNDCLASS wndclass; + MSG msg; + + // Get rid of any compiler warnings + lpszCmdLine = lpszCmdLine; + + hInst = hInstance; + + // Register the DCL Test window Class + if(!hPrevInstance) + { + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInst; + wndclass.hIcon = LoadIcon(hInst, "WinDCL"); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wndclass.lpszMenuName = "WinDCL"; + wndclass.lpszClassName = "WinDCL"; + + if (!RegisterClass(&wndclass)) + return FALSE; + } + + // create Main window + hWndMain = CreateWindow( + "WinDCL", + "DCL Example", // no title + WS_CAPTION | // Title and Min/Max + WS_SYSMENU | // Add system menu box + WS_MINIMIZEBOX | // Add minimize box + WS_MAXIMIZEBOX | // Add maximize box + WS_THICKFRAME | // thick sizeable frame + WS_CLIPCHILDREN | // don't draw in child windows areas + WS_VISIBLE | // window created visible + WS_OVERLAPPED, + CW_USEDEFAULT, 0, // Use default X, Y + CW_USEDEFAULT, 0, // Use default X, Y + NULL, // Parent window's handle + NULL, // Default to Class Menu + hInst, // Instance of window + NULL); // Create struct for WM_CREATE + + // Did the Create Work?? + if(hWndMain == NULL) + return 0; + + ShowWindow(hWndMain, nCmdShow); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return msg.wParam; +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_COMMAND: + if (wParam == IDM_TEST_DCL) + TestDLL(); + break; + case WM_CLOSE: + DestroyWindow(hWnd); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, Message, wParam, lParam); + } + return 0L; +} + +UINT ProcessInBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + LPIOFILEBLOCK lpFileIOBlock; + unsigned int iRead; + + lpFileIOBlock = (LPIOFILEBLOCK) pParam; + + iRead = fread(buffer, 1, *iSize, lpFileIOBlock->InFile ); + + if( iRead > 0 && lpFileIOBlock->bDoCRC == DO_CRC_INSTREAM ) + lpFileIOBlock->dwCRC = crc32(buffer, &iRead, &lpFileIOBlock->dwCRC); + + return iRead; +} + +void ProcessOutBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + LPIOFILEBLOCK lpFileIOBlock; + unsigned int iWrite; + + lpFileIOBlock = (LPIOFILEBLOCK) pParam; + + iWrite = fwrite( buffer, 1, *iSize, lpFileIOBlock->OutFile ); + + if( lpFileIOBlock->bDoCRC == DO_CRC_OUTSTREAM ) + lpFileIOBlock->dwCRC = crc32(buffer, &iWrite, &lpFileIOBlock->dwCRC); +} + +void TestDLL() +{ + int iStatus; + char szVerbose[128]; + IOFILEBLOCK FileIOBlock; + HGLOBAL hWorkBuff; + PCHAR pWorkBuff; + unsigned int type; /* ASCII or Binary compression */ + unsigned int dsize; /* Dictionary Size. 1,2 or 4K */ + + type = CMP_ASCII; /* Use ASCII compression */ + dsize = 4096; /* Use 4K dictionary */ + + // allocate the memory block for the scratch pad + if( (hWorkBuff = GlobalAlloc(GHND, CMP_BUFFER_SIZE)) == NULL ) + { + return; + } + + if ((pWorkBuff = (LPSTR) GlobalLock(hWorkBuff)) == NULL) + { + GlobalFree(hWorkBuff); + return; + } + + // setup structure used by ProcessReadBuffer() and ProcessWriteBuffer() + FileIOBlock.InFile = fopen( "Test.in", "rb" ); + FileIOBlock.OutFile = fopen( "Test.cmp", "wb" ); + FileIOBlock.bDoCRC = DO_CRC_INSTREAM; + FileIOBlock.dwCRC = ~((DWORD)0); // Pre-condition CRC + + if( (FileIOBlock.InFile != NULL) && (FileIOBlock.OutFile != NULL) ) + { + MessageBox(NULL, "Ready to implode", "Notice", MB_OK); + + iStatus = implode(ProcessInBuffer, + ProcessOutBuffer, + pWorkBuff, + &FileIOBlock, + &type, &dsize ); + + if( iStatus != 0 ) + { + wsprintf(szVerbose, "Implode Error: %d", iStatus ); + MessageBox(NULL, szVerbose, "Error", MB_OK); + } + else + { + // Post-condition CRC + if (FileIOBlock.bDoCRC == DO_CRC_INSTREAM) + { + FileIOBlock.dwCRC = ~FileIOBlock.dwCRC; + wsprintf(szVerbose, "CRC of input file: %lX", FileIOBlock.dwCRC); + MessageBox(NULL, szVerbose, "Notice", MB_OK); + } + } + + fclose(FileIOBlock.OutFile); + fclose(FileIOBlock.InFile); + + if( iStatus == 0 ) + { + // setup structure used by ProcessReadBuffer() and ProcessWriteBuffer() + FileIOBlock.InFile = fopen( "Test.cmp", "rb" ); + FileIOBlock.OutFile = fopen( "Test.ext", "wb" ); + FileIOBlock.bDoCRC = DO_CRC_OUTSTREAM; + FileIOBlock.dwCRC = ~((DWORD)0); // Pre-condition CRC + + MessageBox(NULL, "Ready to explode", "Notice", MB_OK); + iStatus = explode(ProcessInBuffer, + ProcessOutBuffer, + pWorkBuff, + &FileIOBlock ); + + if( iStatus != 0 ) + { + wsprintf(szVerbose, "Explode Error: %d", iStatus ); + MessageBox(NULL, szVerbose, "Error", MB_OK); + } + else + { + // Post-condition CRC + if (FileIOBlock.bDoCRC == DO_CRC_OUTSTREAM) + { + FileIOBlock.dwCRC = ~FileIOBlock.dwCRC; + wsprintf(szVerbose, "CRC of exploded file: %lX", FileIOBlock.dwCRC); + MessageBox(NULL, szVerbose, "Notice", MB_OK); + } + } + + fclose(FileIOBlock.OutFile); + fclose(FileIOBlock.InFile); + } + } + else + { + if( FileIOBlock.InFile != NULL ) + { + fclose( FileIOBlock.InFile ); + } + + if( FileIOBlock.OutFile != NULL ) + { + fclose( FileIOBlock.OutFile ); + } + + MessageBox(NULL, "The file TEST.IN must be in the current directory", "Error", MB_OK); + } + + GlobalUnlock(hWorkBuff); + GlobalFree(hWorkBuff); +} + diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.H b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.H new file mode 100644 index 0000000..7389311 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.H @@ -0,0 +1,26 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#define DO_CRC_INSTREAM 1 +#define DO_CRC_OUTSTREAM 2 + +#define WM_FAILEDVALIDATE (WM_USER + 1) + +typedef struct IOFILEBLOCK { + FILE *InFile; + FILE *OutFile; + BOOL bDoCRC; + DWORD dwCRC; +}IOFILEBLOCK, *LPIOFILEBLOCK; + +HWND hInst; +HWND hWndMain; + +LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); + diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.ICO b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.ICO new file mode 100644 index 0000000..aaffe20 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.IDE b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.IDE new file mode 100644 index 0000000..f836d70 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.IDE differ diff --git a/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.RC b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.RC new file mode 100644 index 0000000..4c07061 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/FIL2FIL/WINDCL.RC @@ -0,0 +1,9 @@ +#include "resource.h" + +WinDcl ICON "WinDcl.ico" + +WinDCL MENU + BEGIN + MENUITEM "&Test DCL", IDM_TEST_DCL + END + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/DCL.C b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/DCL.C new file mode 100644 index 0000000..5fb9eb0 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/DCL.C @@ -0,0 +1,497 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#include + +#include +#include +#include + +#include "implode.h" + +typedef enum +{ + COMPRESSING = 1, + UNCOMPRESSING +} FILEMODE; + +typedef struct +{ + PBYTE Buffer; // POINTER TO BUFFER + UINT CurPos; // CURRENT POSITION IN BUFFER + UINT BuffSize; // SIZE OF THE BUFFER +} BUFFER_BLOCK, *PBUFFER_BLOCK; + +// STRUCT TO PASS TO THE FILE IO FUNCTIONS +typedef struct +{ + BUFFER_BLOCK FileBuff; // FILE BUFFER + BUFFER_BLOCK cmpBuff; // COMPRESSION BUFFER + BUFFER_BLOCK uncmpBuff; // UNCOMPRESSION BUFFER + FILEMODE mode; + ULONG ulCrc; // CRC + UINT nCompressSize; + BOOL ErrorOccurred; // ERROR FLAG +} DATABLOCK, *PDATABLOCK; + +UINT DataType = CMP_ASCII; // GLOBAL FOR DATA TYPE FOR COMPRESSION +UINT DictSize = 4096; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +static int iLineCnt; // CURRENT LINE TO OUTPUT STRING + +/********************************************************************* + * + * Function: ReadBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * read requests. If compressing, then the data read is + * in uncompressed form. If compressing, then the data + * read is data that was previously compressed. This + * function is called until zero is returned. + * + * Parameters: buffer -> Address of buffer to read the data into + * iSize -> Number of bytes to read into buffer + * dwParam -> User-defined parameter, in this case a + * pointer to the DATABLOCK + * + * Returns: Number of bytes actually read, or zero on EOF + * + *********************************************************************/ +UINT ReadBuffer( PCHAR buffer, UINT *iSize, void *pParam ) +{ + PDATABLOCK pDataBlock; + PBUFFER_BLOCK pBufferBlock; + UINT iRead; + UINT Num2Read = *iSize; + + pDataBlock = (PDATABLOCK) pParam; + + // IF AN ERROR OCCURRED + if( pDataBlock->ErrorOccurred == TRUE ) + { + return 0; + } + + if( pDataBlock->mode == COMPRESSING ) + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE COMPRESSION BUFFER + pBufferBlock = &pDataBlock->FileBuff; + } + else + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE UNCOMPRESSION BUFFER + pBufferBlock = &pDataBlock->cmpBuff; + } + + if( pBufferBlock->CurPos < pBufferBlock->BuffSize ) + { + UINT BytesLeft = pBufferBlock->BuffSize - pBufferBlock->CurPos; + + // IF REQUESTING MORE BYTES THAN ARE LEFT + if( BytesLeft < Num2Read ) + { + // SET NUMBER OF BYTES TO COPY TO WHAT IS LEFT + Num2Read = BytesLeft; + } + + // COPY BYTES AND UPDATE COUNTER + memcpy( buffer, (pBufferBlock->Buffer + pBufferBlock->CurPos), Num2Read ); + pBufferBlock->CurPos += Num2Read; + + iRead = Num2Read; + } + else // ELSE - NOTHING LEFT IN BUFFER SO RETURN 0 + { + iRead = 0; + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if( pDataBlock->mode == COMPRESSING ) + { + pDataBlock->ulCrc = crc32( buffer, &iRead, &pDataBlock->ulCrc ); + } + + return iRead; +} + +/********************************************************************* + * + * Function: WriteBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * write requests. + * + * Parameters: buffer -> Address of buffer to write data from + * iSize -> Number of bytes to write + * dwParam -> User-defined parameter, in this case a + * pointer to the DATABLOCK + * + * Returns: Zero, the return value is not used by the Data + * Compression Library + * + *********************************************************************/ +void WriteBuffer( PCHAR buffer, UINT *iSize, void *pParam ) +{ + PDATABLOCK pDataBlock; + PBUFFER_BLOCK pBufferBlock; + UINT Num2Write; + + Num2Write = *iSize; + + pDataBlock = (PDATABLOCK) pParam; + + // IF AN ERROR OCCURRED + if( pDataBlock->ErrorOccurred == TRUE ) + { + return; + } + + if( pDataBlock->mode == COMPRESSING ) + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE COMPRESSION BUFFER + pBufferBlock = &pDataBlock->cmpBuff; + + // SINCE COMPRESSING, KEEP A TOTAL OF THE COMPRESSED FILE SIZE + pDataBlock->nCompressSize += Num2Write; + } + else + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE UNCOMPRESSION BUFFER + pBufferBlock = &pDataBlock->uncmpBuff; + } + + // IF NOT OUT OF BUFFER SPACE + if( pBufferBlock->CurPos < pBufferBlock->BuffSize ) + { + // IF WRITING MORE BYTES THAN ARE LEFT + if( (pBufferBlock->BuffSize - pBufferBlock->CurPos) < Num2Write ) + { + MessageBox( NULL, "Out of buffer space - #1", "Compression Error", MB_OK ); + pDataBlock->ErrorOccurred = TRUE; + return; + } + + // COPY BYTES AND UPDATE COUNTER + memcpy( (pBufferBlock->Buffer + pBufferBlock->CurPos), + buffer, Num2Write ); + pBufferBlock->CurPos += Num2Write; + } + else // ELSE - NOTHING LEFT IN BUFFER SO RETURN 0 + { + MessageBox( NULL, "Out of buffer space - #2", "Compression Error", MB_OK ); + pDataBlock->ErrorOccurred = TRUE; + return; + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if (pDataBlock->mode == UNCOMPRESSING ) + { + pDataBlock->ulCrc = crc32( buffer, &Num2Write, &pDataBlock->ulCrc ); + } + + return; +} + +/********************************************************************* + * + * Function: CompressMemToMem() + * + * Purpose: To compress a buffer to another buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pulCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * pnCompressedSize -> Number of bytes in the compressed + * buffer + * pFileBuffer -> Pointer to buffer to compress + * pCompressedBuffer -> Pointer to buffer to place + * compressed data + * BuffSize -> Size of the buffers (both are allocated + * for same number of bytes) + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressMemToMem( HWND hWnd, HDC hDC, ULONG *pulCrc, + UINT *pnCompressedSize, PBYTE pFileBuffer, + PBYTE pCompressedBuffer, UINT BuffSize ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + DATABLOCK DataBlock; + HGLOBAL hWorkBuff; + PCHAR pWorkBuff; + + // allocate the memory block for the scratch pad + if( (hWorkBuff = GlobalAlloc(GHND, CMP_BUFFER_SIZE)) == NULL ) + { + return 0; + } + + if ((pWorkBuff = (LPSTR) GlobalLock(hWorkBuff)) == NULL) + { + GlobalFree(hWorkBuff); + return 0; + } + + memset( &DataBlock, 0, sizeof(DataBlock) ); + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + DataBlock.mode = COMPRESSING; + DataBlock.ulCrc = ~((DWORD)0); // Pre-condition CRC + + // SETUP BUFFER BLOCK FOR FILE BUFFER + DataBlock.FileBuff.Buffer = pFileBuffer; + DataBlock.FileBuff.BuffSize = BuffSize; + + // SETUP BUFFER BLOCK FOR COMPRESSION BUFFER + DataBlock.cmpBuff.Buffer = pCompressedBuffer; + DataBlock.cmpBuff.BuffSize = BuffSize; + + wsprintf( szVerbose, "Compressing %u byte buffer to memory ", BuffSize ); + TextOut( hDC, 10, (iLineCnt++ * 20) + 5, szVerbose, strlen(szVerbose) ); + + // COMPRESS THE FILE + iStatus = implode( ReadBuffer, WriteBuffer, + pWorkBuff, &DataBlock, &DataType, &DictSize ); + + // IF THERE WAS AN ERROR COMPRESSING FILE + if( iStatus || DataBlock.ErrorOccurred ) + { + wsprintf( szVerbose, "Error occurred while imploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - COMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + DataBlock.ulCrc = ~DataBlock.ulCrc; + + // RETURN CRC + *pulCrc = DataBlock.ulCrc; + + // RETURN COMPRESSED BUFFER SIZE + *pnCompressedSize = DataBlock.nCompressSize; + + wsprintf( szVerbose, "Compressed file to memory -> CRC = %08lX ", + DataBlock.ulCrc ); + TextOut( hDC, 10, (iLineCnt++ * 20) + 5, szVerbose, strlen(szVerbose) ); + } + + GlobalUnlock(hWorkBuff); + GlobalFree(hWorkBuff); + + return rc; +} + + +/********************************************************************* + * + * Function: ExpandMemToMem() + * + * Purpose: To expand a compressed buffer to a buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pulCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file after uncompression + * pCompressedBuffer -> Pointer to buffer to place + * compressed data + * nCompressedSize -> Number of bytes in the compressed + * buffer + * pUncompressedBuffer -> Pointer to buffer to place + * uncompressed data + * BuffSize -> Size of the uncompressed buffer + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int ExpandMemToMem( HWND hWnd, HDC hDC, ULONG *pulCrc, + PBYTE pCompressedBuffer, UINT nCompressedSize, + PBYTE pUncompressedBuffer, UINT BuffSize ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + DATABLOCK DataBlock; + HGLOBAL hWorkBuff; + PCHAR pWorkBuff; + + // allocate the memory block for the scratch pad + if( (hWorkBuff = GlobalAlloc(GHND, CMP_BUFFER_SIZE)) == NULL ) + { + return 0; + } + + if ((pWorkBuff = (LPSTR) GlobalLock(hWorkBuff)) == NULL) + { + GlobalFree(hWorkBuff); + return 0; + } + + memset( &DataBlock, 0, sizeof(DataBlock) ); + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + DataBlock.mode = UNCOMPRESSING; + DataBlock.ulCrc = ~((DWORD)0); // Pre-condition CRC + + // SETUP BUFFER BLOCK FOR COMPRESSION BUFFER + DataBlock.cmpBuff.Buffer = pCompressedBuffer; + DataBlock.cmpBuff.BuffSize = nCompressedSize; + + // SETUP BUFFER BLOCK FOR UNCOMPRESSION BUFFER + DataBlock.uncmpBuff.Buffer = pUncompressedBuffer; + DataBlock.uncmpBuff.BuffSize = BuffSize; + + wsprintf( szVerbose, "Compressed buffer size = %u ", nCompressedSize ); + TextOut( hDC, 10, (iLineCnt++ * 20) + 5, szVerbose, strlen(szVerbose) ); + + TextOut( hDC, 10, (iLineCnt++ * 20) + 5, "Uncompressing buffer to memory ", 32 ); + + // UNCOMPRESS THE FILE + iStatus = explode( ReadBuffer, WriteBuffer, pWorkBuff, &DataBlock ); + + // IF THERE WAS AN ERROR UNCOMPRESSING FILE + if( iStatus || DataBlock.ErrorOccurred ) + { + wsprintf( szVerbose, "Error occurred while exploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - UNCOMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + DataBlock.ulCrc = ~DataBlock.ulCrc; + + // RETURN CRC + *pulCrc = DataBlock.ulCrc; + + wsprintf( szVerbose, "Uncompressed file to memory -> CRC = %08lX ", + DataBlock.ulCrc ); + TextOut( hDC, 10, (iLineCnt++ * 20) + 5, szVerbose, strlen(szVerbose) ); + } + + GlobalUnlock(hWorkBuff); + GlobalFree(hWorkBuff); + + return rc; +} + + +/********************************************************************* + * + * Function: MemToMemExample() + * + * Purpose: To load a file into memory. Then compress and uncompress + * the buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszFilename -> Name of file to load + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int MemToMemExample( HWND hWnd, HDC hDC, PCHAR pszFilename ) +{ + FILE *InFile; + int rc=1; // RETURN CODE + UINT BufferSize; + UINT cmpSize; + PBYTE pFileBuffer; // BUFFER FOR FILE DATA + PBYTE pCompressedBuffer; // BUFFER FOR THE COMPRESSED DATA + PBYTE pUncompressedBuffer; // BUFFER FOR THE UNCOMPRESSED DATA + DWORD cmpCrc; // CRC OF FILE BEFORE COMPRESSION + DWORD uncmpCrc; // CRC OF FILE AFTER UNCOMPRESSION + fpos_t FileSize; + + + iLineCnt = 0; + + // OPEN THE FILE + InFile = fopen( pszFilename, "rb" ); + if( InFile == NULL ) + { + MessageBox( hWnd, "Error opening file for compression", "Error", MB_OK ); + return 0; + } + + fseek( InFile, 0, SEEK_END ); + + // CHECK IF FILE IS TOO LARGE + if( fgetpos( InFile, &FileSize ) || FileSize > 64000U ) + { + MessageBox( hWnd, "File is too large to compress to memory", "Error", MB_OK ); + return 0; + } + + fseek( InFile, 0, SEEK_SET ); + + BufferSize = (UINT) FileSize; + + // ALLOCATE BUFFER MEMORY + pFileBuffer = (PBYTE) malloc(BufferSize); + pCompressedBuffer = (PBYTE) malloc(BufferSize); + pUncompressedBuffer = (PBYTE) malloc(BufferSize); + + // IF SUCCESSFULLY ALLOCATED MEMORY + if( (pFileBuffer != NULL) && + (pCompressedBuffer != NULL) && + (pUncompressedBuffer != NULL) ) + { + // READ FILE + fread( pFileBuffer, 1, BufferSize, InFile ); + + // IF COMPRESSED OK + if( CompressMemToMem( hWnd, hDC, &cmpCrc, &cmpSize, + pFileBuffer, pCompressedBuffer, BufferSize ) ) + { + // IF ERROR UNCOMPRESSING + if( !ExpandMemToMem( hWnd, hDC, &uncmpCrc, + pCompressedBuffer, cmpSize, + pUncompressedBuffer, BufferSize ) ) + { + MessageBox( hWnd, "Error uncompressing to memory", "Error", MB_OK ); + rc = 0; + } + } + else + { + MessageBox( hWnd, "Error compressing to memory", "Error", MB_OK ); + rc = 0; + } + } + + + if( pFileBuffer != NULL ) + { + free(pFileBuffer); + } + + if( pCompressedBuffer != NULL ) + { + free(pCompressedBuffer); + } + + if( pUncompressedBuffer != NULL ) + { + free(pUncompressedBuffer); + } + + return rc; +} + + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/DCL.H b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/DCL.H new file mode 100644 index 0000000..fa65195 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/DCL.H @@ -0,0 +1,2 @@ + +int MemToMemExample( HWND hWnd, CDC *pDC, LPSTR lpszFilename ); diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/IMPLODE.H b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKE.BAT b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKE.BAT new file mode 100644 index 0000000..0d9465f --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKE.BAT @@ -0,0 +1 @@ +nmake makefile.msc diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEDLL.BAT b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEDLL.BAT new file mode 100644 index 0000000..543a8b9 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEDLL.BAT @@ -0,0 +1 @@ +nmake makefdll.msc diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEFDLL.MSC b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEFDLL.MSC new file mode 100644 index 0000000..f5c876a --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEFDLL.MSC @@ -0,0 +1,22 @@ +ALL : WINDCL.EXE + +WINDCL.RES : WINDCL.RC RESOURCE.H + rc -r WinDCL.rc + +WINDCL.OBJ : WINDCL.C WINDCL.H + cl -c /D "_X86_" /D "WIN32" WinDCL.c + +DCL.OBJ : DCL.C DCL.H + cl -c /D "_X86_" /D "WIN32" DCL.C + +# rc WinDCL.res + +LINK32_OBJS= \ + WINDCL.res \ + WINDCL.OBJ \ + DCL.OBJ + +WINDCL.EXE : WINDCL.RES WINDCL.OBJ DCL.OBJ + link /SUBSYSTEM:windows /INCREMENTAL:no /MACHINE:I386 /OUT:"windcl.exe" \ + $(LINK32_OBJS) ..\..\..\IMPLODEI.LIB GDI32.LIB + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEFILE.MSC b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEFILE.MSC new file mode 100644 index 0000000..8ffa35e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/MAKEFILE.MSC @@ -0,0 +1,22 @@ +ALL : WINDCL.EXE + +WINDCL.RES : WINDCL.RC RESOURCE.H + rc -r WinDCL.rc + +WINDCL.OBJ : WINDCL.C WINDCL.H + cl -c /D "_X86_" /D "WIN32" WinDCL.c + +DCL.OBJ : DCL.C DCL.H + cl -c /D "_X86_" /D "WIN32" DCL.C + +# rc WinDCL.res + +LINK32_OBJS= \ + WINDCL.res \ + WINDCL.OBJ \ + DCL.OBJ + +WINDCL.EXE : WINDCL.RES WINDCL.OBJ DCL.OBJ + link /SUBSYSTEM:windows /INCREMENTAL:no /MACHINE:I386 /OUT:"windcl.exe" \ + $(LINK32_OBJS) ..\..\..\IMPLODE.LIB GDI32.LIB + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/RESOURCE.H b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/RESOURCE.H new file mode 100644 index 0000000..fce9635 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/RESOURCE.H @@ -0,0 +1,2 @@ +#define IDM_TEST_DCL 1000 + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WDCLDLL.IDE b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WDCLDLL.IDE new file mode 100644 index 0000000..bffbfb5 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WDCLDLL.IDE differ diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.C b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.C new file mode 100644 index 0000000..89bb97d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.C @@ -0,0 +1,114 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#include + +#include +#include +#include + +#include "resource.h" +#include "WinDCL.h" +#include "implode.h" + +void TestDLL(void); + +#ifndef _MSC_VER + #pragma argsused +#endif + +int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) +{ + WNDCLASS wndclass; + MSG msg; + + // Get rid of any compiler warnings + lpszCmdLine = lpszCmdLine; + + hInst = hInstance; + + // Register the DCL Test window Class + if(!hPrevInstance) + { + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInst; + wndclass.hIcon = LoadIcon(hInst, "WinDCL"); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wndclass.lpszMenuName = "WinDCL"; + wndclass.lpszClassName = "WinDCL"; + + if (!RegisterClass(&wndclass)) + return FALSE; + } + + // create Main window + hWndMain = CreateWindow( + "WinDCL", + "DCL Example", // no title + WS_CAPTION | // Title and Min/Max + WS_SYSMENU | // Add system menu box + WS_MINIMIZEBOX | // Add minimize box + WS_MAXIMIZEBOX | // Add maximize box + WS_THICKFRAME | // thick sizeable frame + WS_CLIPCHILDREN | // don't draw in child windows areas + WS_VISIBLE | // window created visible + WS_OVERLAPPED, + CW_USEDEFAULT, 0, // Use default X, Y + CW_USEDEFAULT, 0, // Use default X, Y + NULL, // Parent window's handle + NULL, // Default to Class Menu + hInst, // Instance of window + NULL); // Create struct for WM_CREATE + + // Did the Create Work?? + if(hWndMain == NULL) + return 0; + + ShowWindow(hWndMain, nCmdShow); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return msg.wParam; +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_COMMAND: + if (wParam == IDM_TEST_DCL) + { + HDC hDC; + + hDC = GetDC( hWnd ); + SetBkMode( hDC, TRANSPARENT ); + MemToMemExample( hWnd, hDC, "TEST.IN" ); + ReleaseDC( hWnd, hDC ); + } + break; + case WM_CLOSE: + DestroyWindow(hWnd); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, Message, wParam, lParam); + } + return 0L; +} + + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.H b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.H new file mode 100644 index 0000000..c29d9ec --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.H @@ -0,0 +1,15 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +HWND hInst; +HWND hWndMain; + +LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); +int MemToMemExample( HWND hWnd, HDC hDC, PCHAR pszFilename ); + diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.ICO b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.ICO new file mode 100644 index 0000000..aaffe20 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.IDE b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.IDE new file mode 100644 index 0000000..6b813f8 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.IDE differ diff --git a/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.RC b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.RC new file mode 100644 index 0000000..4c07061 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/GUI/MEM2MEM/WINDCL.RC @@ -0,0 +1,9 @@ +#include "resource.h" + +WinDcl ICON "WinDcl.ico" + +WinDCL MENU + BEGIN + MENUITEM "&Test DCL", IDM_TEST_DCL + END + diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/COMPDLG.CPP b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/COMPDLG.CPP new file mode 100644 index 0000000..d8e32b7 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/COMPDLG.CPP @@ -0,0 +1,424 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// compdlg.cpp : implementation file +// + + +#include "stdafx.h" +#include +#include "dcl.h" + +// Start, Added by PKWARE +#include "implode.h" +#include "PKstruct.h" +#include "compdlg.h" + +static char CancelCompression[] = "Cancel Compression"; + +#define DO_CRC_INSTREAM 1 +#define DO_CRC_OUTSTREAM 2 + +void ProcessOutBuffer(PCHAR buffer, UINT *iSize, void *Param); +UINT ProcessInBuffer(PCHAR buffer, UINT *iSize, void *pParam); + +void PKCompressFile(void); +// End, added by PKWARE + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CCompDlg dialog + + +CCompDlg::CCompDlg(CWnd* pParent /*=NULL*/) + : CDialog(CCompDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CCompDlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + +void CCompDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CCompDlg) + // NOTE: the ClassWizard will add DDX and DDV calls here + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CCompDlg, CDialog) + //{{AFX_MSG_MAP(CCompDlg) + ON_BN_CLICKED(IDC_BUTTON1, OnCompressButton) + ON_BN_CLICKED(IDC_BUTTON2, OnTestButton) + ON_BN_CLICKED(IDC_BUTTON3, OnClearButton) + ON_BN_CLICKED(IDC_BUTTON4, OnDebugButton) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CCompDlg message handlers +BOOL CCompDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // TODO: Add extra initialization here + SetDlgItemText(IDC_EDIT1, "TEST.IN"); + SetDlgItemText(IDC_EDIT9, "?"); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON2), FALSE); // Disable the Extract button + DebugMessages = FALSE; + return TRUE; // return TRUE unless you set the focus to a control +} + +// Function to add an item to the listbox. The listbox is then scrolled to display this item +void CCompDlg::PKLBMessage(char *message) +{ + SendDlgItemMessage(IDC_LIST1, LB_ADDSTRING, 0, (LONG)(PCHAR)(const char *)message); + int Items = (int)SendDlgItemMessage(IDC_LIST1, LB_GETCOUNT, 0,0); + SendDlgItemMessage(IDC_LIST1, LB_SETCURSEL, Items-1, 0); // Show this item +} + +void CCompDlg::OnCompressButton() +{ + // TODO: Add your control notification handler code here + ClearMessages(); // Clear listbox and filesizes + PKCompressFile(); // Start compression +} + +void CCompDlg::OnTestButton() +{ + // TODO: Add your control notification handler code here + SendDlgItemMessage(IDC_LIST1, LB_RESETCONTENT, 0, 0L); // Clear the listbox + PKLBMessage("Extracting file..."); + PKExtractFile(); // Start extraction +} + +void CCompDlg::OnClearButton() +{ + // TODO: Add your control notification handler code here + ClearMessages(); +} + +void CCompDlg::OnCancel() +{ + // TODO: Add extra cleanup here + CDialog::OnCancel(); +} + +// Function to calculate the percentage of compression without using floating point math +int GetPercent(unsigned long top, unsigned long bottom) +{ + int percent; + unsigned long bot; + + if (top == 0L) + return(0); + + bot = bottom ? bottom : 1L; + + if (top > 400000000L) // 400,000,000 + percent = (int)(top / (bot / 100L)); + else if (top > 40000000L) // 40,000,000 + percent = int((top * 10L) / (bot / 10L)); + else + percent = int((top * 100L) / bot); + + return(percent > 100 ? 100 : percent); +} + +void CCompDlg::ClearMessages() +{ + SendDlgItemMessage(IDC_LIST1, LB_RESETCONTENT, 0, 0L); // Clear the listbox + SetDlgItemText(IDC_EDIT2, (PCHAR)""); // Clear all the edit boxes + SetDlgItemText(IDC_EDIT3, (PCHAR)""); + SetDlgItemText(IDC_EDIT4, (PCHAR)""); + SetDlgItemText(IDC_EDIT5, (PCHAR)""); + SetDlgItemText(IDC_EDIT6, (PCHAR)""); + SetDlgItemText(IDC_EDIT7, (PCHAR)""); + SetDlgItemText(IDC_EDIT8, (PCHAR)""); +} + +// This function is called by the implode and explode functions. +UINT ProcessInBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + PIOFILEBLOCK pFileIOBlock; + unsigned int iRead; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + if (pFileIOBlock->PKAbortOperation) // Set this variable to abort compression or extraction + return 0; + + iRead = fread( buffer, 1, *iSize, pFileIOBlock->InFile ); // Read data from disk + + if (pFileIOBlock->DebugMessages) // Debugging messages on ? + { + char s[80]; + wsprintf(s, "Asked to read %u bytes, actually read %u bytes", *iSize, iRead); + SendDlgItemMessage(pFileIOBlock->hWindow, IDC_LIST1, LB_ADDSTRING, 0, (LONG)(PCHAR)(const char *)s); + int Items = (int)SendDlgItemMessage(pFileIOBlock->hWindow, IDC_LIST1, LB_GETCOUNT, 0, 0); + SendDlgItemMessage(pFileIOBlock->hWindow, IDC_LIST1, LB_SETCURSEL, Items-1, 0); + } + + if( iRead > 0 && pFileIOBlock->bDoCRC == DO_CRC_INSTREAM) + pFileIOBlock->dwCRC = crc32(buffer, &iRead, &pFileIOBlock->dwCRC); + + return iRead; +} + +// This function is called by the implode and explode functions. +void ProcessOutBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + PIOFILEBLOCK pFileIOBlock; + unsigned int iWrite; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + if (pFileIOBlock->PKAbortOperation) // Set this variable to abort compression or extraction + return; + + iWrite = fwrite( buffer, 1, *iSize, pFileIOBlock->OutFile ); // Write the data to disk + + if (pFileIOBlock->DebugMessages) // Debugging messages on ? + { + char s[80]; + wsprintf(s, "Asked to write %u bytes, actually wrote %u bytes", iSize, iWrite); + SendDlgItemMessage(pFileIOBlock->hWindow, IDC_LIST1, LB_ADDSTRING, 0, (LONG)(PCHAR)(const char *)s); + int Items = (int)SendDlgItemMessage(pFileIOBlock->hWindow, IDC_LIST1, LB_GETCOUNT, 0, 0); + SendDlgItemMessage(pFileIOBlock->hWindow, IDC_LIST1, LB_SETCURSEL, Items-1, 0); + } + + if( iWrite > 0 && pFileIOBlock->bDoCRC == DO_CRC_OUTSTREAM) + pFileIOBlock->dwCRC = crc32(buffer, &iWrite, &pFileIOBlock->dwCRC); + + return; +} + +void CCompDlg::PKCompressFile() +{ + int iStatus; + UINT CompType = CMP_ASCII, DictSize; + char szVerbose[128], FileName[80]; + fpos_t FileSize = 0, CompressedFileSize; + static char *Comp[] = { "Binary", "ASCII" }; + + FileIOBlock.hWindow = m_hWnd; // Used in the read and write routines + FileIOBlock.DebugMessages = DebugMessages; + FileIOBlock.PKAbortOperation = FALSE; + + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON1), FALSE); // Disable buttons + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON2), FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON3), FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON4), FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDCANCEL), FALSE); + + HANDLE hScratchPad; + PCHAR pScratchPad; + + // allocate the memory block for the scratch pad + if( (hScratchPad = GlobalAlloc(GHND, CMP_BUFFER_SIZE)) == NULL ) + { + return; + } + + if( (pScratchPad = (PCHAR) GlobalLock(hScratchPad)) == NULL ) + { + GlobalFree(hScratchPad); + return; + } + + int LoopCnt; + + for( LoopCnt=0, CompType = CMP_ASCII; LoopCnt < 2; LoopCnt++, CompType = CMP_BINARY ) + { + for (DictSize = 1024; DictSize <= 4096; DictSize *= 2) // Dictionary size + { + FileIOBlock.InFile = FileIOBlock.OutFile = NULL; // Initialize + + GetDlgItemText(IDC_EDIT1, FileName, 80); + FileIOBlock.InFile = fopen(FileName, "rb" ); // Open the source file + + if( FileIOBlock.InFile == NULL ) // Error opening file + { + char s[80]; + wsprintf(s, "Error opening file %s.", (PCHAR)FileName); + PKLBMessage(s); + break; + } + + if( FileSize == 0 ) + { + fseek(FileIOBlock.InFile, 0L, SEEK_END); // Get the filesize + fgetpos(FileIOBlock.InFile, &FileSize ); // Get the filesize + fseek(FileIOBlock.InFile, 0L, SEEK_SET); // Rewind the file + wsprintf(szVerbose, "%ld", (PCHAR)FileSize); // Uncompressed size + SetDlgItemText(IDC_EDIT9, szVerbose); + } + + FileIOBlock.OutFile = fopen( "Test.cmp", "wb" ); + FileIOBlock.bDoCRC = DO_CRC_INSTREAM; + FileIOBlock.dwCRC = ~((DWORD)0); // Pre-condition CRC + + if( (FileIOBlock.InFile != NULL) && (FileIOBlock.OutFile != NULL)) + { + iStatus = implode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, + &FileIOBlock, &CompType, &DictSize ); + + // Check the value of iStatus for errors + + // Post-condition CRC + if (FileIOBlock.bDoCRC == DO_CRC_INSTREAM) + { + CString CRCvalue; + FileIOBlock.dwCRC = ~FileIOBlock.dwCRC; + InputCRC = FileIOBlock.dwCRC; + wsprintf(szVerbose, "%lX", FileIOBlock.dwCRC); + SetDlgItemText(IDC_EDIT8, szVerbose); // Display CRC + } + + fgetpos(FileIOBlock.OutFile, &CompressedFileSize ); // Get the filesize + + fclose(FileIOBlock.OutFile); // Close the files + fclose(FileIOBlock.InFile); + + wsprintf(szVerbose, "%ld", CompressedFileSize); + + if (CompType == CMP_ASCII) + { + if (DictSize == 1024) + SetDlgItemText(IDC_EDIT2, szVerbose); + else if (DictSize == 2048) + SetDlgItemText(IDC_EDIT3, szVerbose); + else + SetDlgItemText(IDC_EDIT4, szVerbose); + } + else // Binary + { + if (DictSize == 1024) + SetDlgItemText(IDC_EDIT5, szVerbose); + else if (DictSize == 2048) + SetDlgItemText(IDC_EDIT6, szVerbose); + else + SetDlgItemText(IDC_EDIT7, szVerbose); + } + wsprintf(szVerbose, "Using %d dictionary, %s compression. File Compressed %d%%.", + DictSize, (PCHAR)Comp[CompType], 100 - GetPercent(CompressedFileSize, FileSize)); + PKLBMessage(szVerbose); + } + } + } + + GlobalUnlock(hScratchPad); + GlobalFree(hScratchPad); + + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON1), TRUE); // Reset the buttons + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON2), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON3), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON4), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDCANCEL), TRUE); +} + +void CCompDlg::PKExtractFile() +{ + int iStatus; + + FileIOBlock.hWindow = m_hWnd; // Used in the read and write routines + FileIOBlock.DebugMessages = DebugMessages; + FileIOBlock.PKAbortOperation = FALSE; + + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON1), FALSE); // Disable the buttons + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON2), FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON3), FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON4), FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDCANCEL), FALSE); + + HANDLE hScratchPad; + PCHAR pScratchPad; + + // allocate the memory block for the scratch pad + if( (hScratchPad = GlobalAlloc(GHND, EXP_BUFFER_SIZE)) == NULL ) + { + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON1), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON2), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON3), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON4), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDCANCEL), TRUE); + return; + } + + if( (pScratchPad = (PCHAR) GlobalLock(hScratchPad)) == NULL ) + { + GlobalFree(hScratchPad); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON1), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON2), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON3), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON4), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDCANCEL), TRUE); + return; + } + + FileIOBlock.InFile = FileIOBlock.OutFile = NULL; + + // setup structure used by ProcessReadBuffer() and ProcessWriteBuffer() + FileIOBlock.InFile = fopen( "Test.cmp", "rb" ); + + if( FileIOBlock.InFile == NULL ) + { + int Items = (int)SendDlgItemMessage(IDC_LIST1, LB_GETCOUNT, 0,0); + SendDlgItemMessage(IDC_LIST1, LB_INSERTSTRING, Items, (LONG)(PCHAR)(const char *)"The file TEST.CMP was not found, you must compress a file first."); + } + else + { + FileIOBlock.OutFile = fopen( "Test.ext", "wb" ); + FileIOBlock.bDoCRC = DO_CRC_OUTSTREAM; + FileIOBlock.dwCRC = ~((DWORD)0); // Pre-condition CRC + + iStatus = explode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, &FileIOBlock ); + + // Check the value of iStatus for errors + + // Post-condition CRC + if (FileIOBlock.bDoCRC == DO_CRC_OUTSTREAM) + { + FileIOBlock.dwCRC = ~FileIOBlock.dwCRC; + if (InputCRC != FileIOBlock.dwCRC) + PKLBMessage("File fails the CRC check!"); + else + PKLBMessage("File tests OK."); + } + + if( FileIOBlock.OutFile != NULL ) + fclose(FileIOBlock.OutFile); + if( FileIOBlock.InFile != NULL ) + fclose(FileIOBlock.InFile); + + PKLBMessage("Done extracting."); + } + + GlobalUnlock(hScratchPad); + GlobalFree(hScratchPad); + + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON1), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON2), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON3), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON4), TRUE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDCANCEL), TRUE); +} + +void CCompDlg::OnDebugButton() +{ + // TODO: Add your control notification handler code here + + DebugMessages = !DebugMessages; + ::SetWindowText(::GetDlgItem(m_hWnd, IDC_BUTTON4), DebugMessages ? (PCHAR)"Debug Messages = On" : (PCHAR)"Debug Messages = Off"); +} + diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/COMPDLG.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/COMPDLG.H new file mode 100644 index 0000000..f1d68a4 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/COMPDLG.H @@ -0,0 +1,50 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// compdlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CCompDlg dialog + +#include "pkstruct.h" + +class CCompDlg : public CDialog +{ +// Construction +public: + CCompDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CCompDlg) + enum { IDD = IDD_DIALOG1 }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + +// Implementation +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + // Generated message map functions + //{{AFX_MSG(CCompDlg) + afx_msg void OnCompressButton(); + afx_msg void OnTestButton(); + afx_msg void OnClearButton(); + virtual void OnCancel(); + virtual void PKCompressFile(); // Added by PKWARE + virtual void PKExtractFile(); // Added by PKWARE + virtual void ClearMessages(); // Added by PKWARE + virtual void PKLBMessage(char *); // Added by PKWARE + afx_msg void OnDebugButton(); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + BOOL DebugMessages; // Added by PKWARE + unsigned long InputCRC; // Added by PKWARE + IOFILEBLOCK FileIOBlock; // Added by PKWARE +}; diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.CPP b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.CPP new file mode 100644 index 0000000..fe22c9d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.CPP @@ -0,0 +1,137 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// dcl.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "dcl.h" + +#include "mainfrm.h" +#include "dcldoc.h" +#include "dclview.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDclApp + +BEGIN_MESSAGE_MAP(CDclApp, CWinApp) + //{{AFX_MSG_MAP(CDclApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDclApp construction + +CDclApp::CDclApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CDclApp object + +CDclApp NEAR theApp; + +///////////////////////////////////////////////////////////////////////////// +// CDclApp initialization + +BOOL CDclApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + SetDialogBkColor(); // Set dialog background color to gray + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CSingleDocTemplate* pDocTemplate; + pDocTemplate = new CSingleDocTemplate( + IDR_MAINFRAME, + RUNTIME_CLASS(CDclDoc), + RUNTIME_CLASS(CMainFrame), // main SDI frame window + RUNTIME_CLASS(CDclView)); + AddDocTemplate(pDocTemplate); + + // create a new (empty) document + OnFileNew(); + + if (m_lpCmdLine[0] != '\0') + { + // TODO: add command line processing here + } + + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + +// Implementation +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CDclApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CDclApp commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.H new file mode 100644 index 0000000..a475f44 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.H @@ -0,0 +1,42 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// dcl.h : main header file for the DCL application +// + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CDclApp: +// See dcl.cpp for the implementation of this class +// + +class CDclApp : public CWinApp +{ +public: + CDclApp(); + +// Overrides + virtual BOOL InitInstance(); + +// Implementation + + //{{AFX_MSG(CDclApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.MAK b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.MAK new file mode 100644 index 0000000..68ddab8 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.MAK @@ -0,0 +1,264 @@ +# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE No configuration specified. Defaulting to Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DCL.MAK" CFG="Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Win32 Debug" +MTL=MkTypLib.exe +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Win32 Release" + +# PROP BASE Use_MFC 1 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 1 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/DCL.exe $(OUTDIR)/DCL.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE CPP /nologo /MT /W3 /GX /YX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FR /c +# ADD CPP /nologo /MT /W3 /GX /YX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MT /W3 /GX /YX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_MBCS" /Fp$(OUTDIR)/"DCL.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DCL.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"DCL.bsc" + +$(OUTDIR)/DCL.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /MACHINE:IX86 +# ADD LINK32 oldnames.lib implode.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /MACHINE:IX86 +# SUBTRACT LINK32 /INCREMENTAL:yes +LINK32_FLAGS=oldnames.lib implode.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows\ + /INCREMENTAL:no /PDB:$(OUTDIR)/"DCL.pdb" /MACHINE:IX86 /OUT:$(OUTDIR)/"DCL.exe"\ + +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/DCL.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/DCL.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/DCLDOC.OBJ \ + $(INTDIR)/DCLVIEW.OBJ \ + $(INTDIR)/COMPDLG.OBJ + +$(OUTDIR)/DCL.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# PROP BASE Use_MFC 1 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 1 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/DCL.exe $(OUTDIR)/DCL.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE CPP /nologo /MT /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /c +# ADD CPP /nologo /MT /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MT /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /D "_MBCS" /Fp$(OUTDIR)/"DCL.pch" /Fo$(INTDIR)/ /Fd$(OUTDIR)/"DCL.pdb" /c +CPP_OBJS=.\WinDebug/ +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DCL.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"DCL.bsc" + +$(OUTDIR)/DCL.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /DEBUG /MACHINE:IX86 +# ADD LINK32 oldnames.lib implode.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /INCREMENTAL:no /DEBUG /MACHINE:IX86 +LINK32_FLAGS=oldnames.lib implode.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows\ + /INCREMENTAL:no /PDB:$(OUTDIR)/"DCL.pdb" /DEBUG /MACHINE:IX86\ + /OUT:$(OUTDIR)/"DCL.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/DCL.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/DCL.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/DCLDOC.OBJ \ + $(INTDIR)/DCLVIEW.OBJ \ + $(INTDIR)/COMPDLG.OBJ + +$(OUTDIR)/DCL.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Group "Source Files" + +################################################################################ +# Begin Source File + +SOURCE=.\DCL.RC +DEP_DCL_R=\ + .\RES\DCL.ICO\ + .\RES\TOOLBAR.BMP\ + .\RESOURCE.H\ + .\RES\DCL.RC2 + +$(INTDIR)/DCL.res : $(SOURCE) $(DEP_DCL_R) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\STDAFX.CPP +DEP_STDAF=\ + .\STDAFX.H + +$(INTDIR)/STDAFX.OBJ : $(SOURCE) $(DEP_STDAF) $(INTDIR) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DCL.CPP +DEP_DCL_C=\ + .\STDAFX.H\ + .\DCL.H\ + .\MAINFRM.H\ + .\DCLDOC.H\ + .\DCLVIEW.H\ + .\RESOURCE.H + +$(INTDIR)/DCL.OBJ : $(SOURCE) $(DEP_DCL_C) $(INTDIR) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MAINFRM.CPP +DEP_MAINF=\ + .\STDAFX.H\ + .\DCL.H\ + .\MAINFRM.H\ + .\RESOURCE.H + +$(INTDIR)/MAINFRM.OBJ : $(SOURCE) $(DEP_MAINF) $(INTDIR) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DCLDOC.CPP +DEP_DCLDO=\ + .\STDAFX.H\ + .\DCL.H\ + .\DCLDOC.H\ + .\RESOURCE.H + +$(INTDIR)/DCLDOC.OBJ : $(SOURCE) $(DEP_DCLDO) $(INTDIR) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DCLVIEW.CPP +DEP_DCLVI=\ + .\STDAFX.H\ + .\DCL.H\ + .\DCLDOC.H\ + .\DCLVIEW.H\ + .\COMPDLG.H\ + .\RESOURCE.H\ + .\PKSTRUCT.H + +$(INTDIR)/DCLVIEW.OBJ : $(SOURCE) $(DEP_DCLVI) $(INTDIR) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\COMPDLG.CPP +DEP_COMPD=\ + .\STDAFX.H\ + .\DCL.H\ + .\implode.h\ + .\PKSTRUCT.H\ + .\COMPDLG.H\ + .\RESOURCE.H + +$(INTDIR)/COMPDLG.OBJ : $(SOURCE) $(DEP_COMPD) $(INTDIR) + +# End Source File +# End Group +# End Project +################################################################################ diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.RC b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.RC new file mode 100644 index 0000000..92c04d4 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCL.RC @@ -0,0 +1,255 @@ +//Microsoft App Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#ifdef APSTUDIO_INVOKED +////////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""res\\dcl.rc2"" // non-App Studio edited resources\r\n" + "\r\n" + "#include ""afxres.rc"" \011// Standard components\r\n" + "\0" +END + +///////////////////////////////////////////////////////////////////////////////////// +#endif // APSTUDIO_INVOKED + + +////////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +IDR_MAINFRAME ICON DISCARDABLE "RES\\DCL.ICO" + +////////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINFRAME BITMAP MOVEABLE PURE "RES\\TOOLBAR.BMP" + +////////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU PRELOAD DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "Compress...", COMP_DIALOG + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "&Help" + BEGIN + MENUITEM "&About Dcl...", ID_APP_ABOUT + END +END + + +////////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE +BEGIN + "N", ID_FILE_NEW, VIRTKEY,CONTROL + "O", ID_FILE_OPEN, VIRTKEY,CONTROL + "S", ID_FILE_SAVE, VIRTKEY,CONTROL + "Z", ID_EDIT_UNDO, VIRTKEY,CONTROL + "X", ID_EDIT_CUT, VIRTKEY,CONTROL + "C", ID_EDIT_COPY, VIRTKEY,CONTROL + "V", ID_EDIT_PASTE, VIRTKEY,CONTROL + VK_BACK, ID_EDIT_UNDO, VIRTKEY,ALT + VK_DELETE, ID_EDIT_CUT, VIRTKEY,SHIFT + VK_INSERT, ID_EDIT_COPY, VIRTKEY,CONTROL + VK_INSERT, ID_EDIT_PASTE, VIRTKEY,SHIFT + VK_F6, ID_NEXT_PANE, VIRTKEY + VK_F6, ID_PREV_PANE, VIRTKEY,SHIFT +END + + +////////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 34, 22, 217, 55 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Dcl" +FONT 8, "MS Sans Serif" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20 + LTEXT "Dcl Application Version 1.0",IDC_STATIC,40,10,119,8 + LTEXT "Copyright \251 1994,1995",IDC_STATIC,40,25,119,8 + DEFPUSHBUTTON "OK",IDOK,176,6,32,14,WS_GROUP +END + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 248, 258 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "PKWARE Data Compression Library for Win32" +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON "Exit",IDCANCEL,153,237,87,13 + LISTBOX IDC_LIST1,2,121,238,67,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | + WS_TABSTOP + DEFPUSHBUTTON "Compress",IDC_BUTTON1,3,194,94,28 + PUSHBUTTON "Extract Compressed file",IDC_BUTTON2,3,226,94,28 + EDITTEXT IDC_EDIT1,7,16,115,12,ES_AUTOHSCROLL + LTEXT "ASCII",IDC_STATIC,52,42,20,10 + LTEXT "Binary",IDC_STATIC,99,42,20,10 + EDITTEXT IDC_EDIT2,52,55,42,13,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EDIT3,52,70,42,13,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EDIT4,52,85,42,13,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EDIT5,99,55,42,13,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EDIT6,99,70,42,13,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EDIT7,99,85,42,13,ES_AUTOHSCROLL | ES_READONLY + LTEXT "1K Dictionary",IDC_STATIC,5,58,44,9 + LTEXT "2K Dictionary",IDC_STATIC,5,73,43,9 + LTEXT "4K Dictionary",IDC_STATIC,5,87,43,9 + LTEXT "Messages",IDC_STATIC,2,108,58,9 + PUSHBUTTON "Clear Messages",IDC_BUTTON3,153,194,87,13 + LTEXT "CRC32",IDC_STATIC,150,43,30,10 + EDITTEXT IDC_EDIT8,150,55,45,13,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Input File",IDC_STATIC,7,4,59,9 + PUSHBUTTON "Debug Messages = Off",IDC_BUTTON4,153,210,87,13 + LTEXT "File Size",IDC_STATIC,150,4,30,8 + EDITTEXT IDC_EDIT9,150,16,45,12,ES_AUTOHSCROLL | ES_READONLY +END + + +////////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + IDR_MAINFRAME "Dcl Win32 Application\nDcl\nDcl Document\n\n\nDcl.Document\nDcl Document" +END + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + AFX_IDS_APP_TITLE "Dcl Win32 Application" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_INDICATOR_EXT "EXT" + ID_INDICATOR_CAPS "CAP" + ID_INDICATOR_NUM "NUM" + ID_INDICATOR_SCRL "SCRL" + ID_INDICATOR_OVR "OVR" + ID_INDICATOR_REC "REC" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_NEW "Create a new document" + ID_FILE_OPEN "Open an existing document" + ID_FILE_CLOSE "Close the active document" + ID_FILE_SAVE "Save the active document" + ID_FILE_SAVE_AS "Save the active document with a new name" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright" + ID_APP_EXIT "Quit the application; prompts to save documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_MRU_FILE1 "Open this document" + ID_FILE_MRU_FILE2 "Open this document" + ID_FILE_MRU_FILE3 "Open this document" + ID_FILE_MRU_FILE4 "Open this document" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane" + ID_PREV_PANE "Switch back to the previous window pane" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection" + ID_EDIT_CLEAR_ALL "Erase everything" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard" + ID_EDIT_FIND "Find the specified text" + ID_EDIT_PASTE "Insert Clipboard contents" + ID_EDIT_REPEAT "Repeat the last action" + ID_EDIT_REPLACE "Replace specific text with different text" + ID_EDIT_SELECT_ALL "Select the entire document" + ID_EDIT_UNDO "Undo the last action" + ID_EDIT_REDO "Redo the previously undone action" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_VIEW_TOOLBAR "Show or hide the toolbar" + ID_VIEW_STATUS_BAR "Show or hide the status bar" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + + +#ifndef APSTUDIO_INVOKED +//////////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "res\dcl.rc2" // non-App Studio edited resources + +#include "afxres.rc" // Standard components + +///////////////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLDOC.CPP b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLDOC.CPP new file mode 100644 index 0000000..18d1089 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLDOC.CPP @@ -0,0 +1,88 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// dcldoc.cpp : implementation of the CDclDoc class +// + +#include "stdafx.h" +#include "dcl.h" + +#include "dcldoc.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDclDoc + +IMPLEMENT_DYNCREATE(CDclDoc, CDocument) + +BEGIN_MESSAGE_MAP(CDclDoc, CDocument) + //{{AFX_MSG_MAP(CDclDoc) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDclDoc construction/destruction + +CDclDoc::CDclDoc() +{ + // TODO: add one-time construction code here +} + +CDclDoc::~CDclDoc() +{ +} + +BOOL CDclDoc::OnNewDocument() +{ + if (!CDocument::OnNewDocument()) + return FALSE; + + // TODO: add reinitialization code here + // (SDI documents will reuse this document) + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CDclDoc serialization + +void CDclDoc::Serialize(CArchive& ar) +{ + if (ar.IsStoring()) + { + // TODO: add storing code here + } + else + { + // TODO: add loading code here + } +} + +///////////////////////////////////////////////////////////////////////////// +// CDclDoc diagnostics + +#ifdef _DEBUG +void CDclDoc::AssertValid() const +{ + CDocument::AssertValid(); +} + +void CDclDoc::Dump(CDumpContext& dc) const +{ + CDocument::Dump(dc); +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CDclDoc commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLDOC.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLDOC.H new file mode 100644 index 0000000..e6df009 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLDOC.H @@ -0,0 +1,45 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// dcldoc.h : interface of the CDclDoc class +// +///////////////////////////////////////////////////////////////////////////// + +class CDclDoc : public CDocument +{ +protected: // create from serialization only + CDclDoc(); + DECLARE_DYNCREATE(CDclDoc) + +// Attributes +public: +// Operations +public: + +// Implementation +public: + virtual ~CDclDoc(); + virtual void Serialize(CArchive& ar); // overridden for document i/o +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + virtual BOOL OnNewDocument(); + +// Generated message map functions +protected: + //{{AFX_MSG(CDclDoc) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLVIEW.CPP b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLVIEW.CPP new file mode 100644 index 0000000..2181616 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLVIEW.CPP @@ -0,0 +1,87 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// dclview.cpp : implementation of the CDclView class +// + +#include "stdafx.h" +#include "dcl.h" + +#include "dcldoc.h" +#include "dclview.h" +#include "compdlg.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDclView + +IMPLEMENT_DYNCREATE(CDclView, CView) + +BEGIN_MESSAGE_MAP(CDclView, CView) + //{{AFX_MSG_MAP(CDclView) + ON_COMMAND(COMP_DIALOG, OnDialog) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDclView construction/destruction + +CDclView::CDclView() +{ + // TODO: add construction code here +} + +CDclView::~CDclView() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// CDclView drawing + +void CDclView::OnDraw(CDC* pDC) +{ + CDclDoc* pDoc = GetDocument(); + ASSERT_VALID(pDoc); + + // TODO: add draw code for native data here +} + +///////////////////////////////////////////////////////////////////////////// +// CDclView diagnostics + +#ifdef _DEBUG +void CDclView::AssertValid() const +{ + CView::AssertValid(); +} + +void CDclView::Dump(CDumpContext& dc) const +{ + CView::Dump(dc); +} + +CDclDoc* CDclView::GetDocument() // non-debug version is inline +{ + ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDclDoc))); + return (CDclDoc*)m_pDocument; +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CDclView message handlers + +void CDclView::OnDialog() +{ + // TODO: Add your command handler code here + CCompDlg dlg; + dlg.DoModal(); +} diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLVIEW.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLVIEW.H new file mode 100644 index 0000000..4e004b5 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/DCLVIEW.H @@ -0,0 +1,50 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// dclview.h : interface of the CDclView class +// +///////////////////////////////////////////////////////////////////////////// + +class CDclView : public CView +{ +protected: // create from serialization only + CDclView(); + DECLARE_DYNCREATE(CDclView) + +// Attributes +public: + CDclDoc* GetDocument(); + +// Operations +public: + +// Implementation +public: + virtual ~CDclView(); + virtual void OnDraw(CDC* pDC); // overridden to draw this view +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + +// Generated message map functions +protected: + //{{AFX_MSG(CDclView) + afx_msg void OnDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#ifndef _DEBUG // debug version in dclview.cpp +inline CDclDoc* CDclView::GetDocument() + { return (CDclDoc*)m_pDocument; } +#endif + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/IMPLODE.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/IMPLODE.LIB b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/IMPLODE.LIB new file mode 100644 index 0000000..4cc55e1 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/IMPLODE.LIB differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/MAINFRM.CPP b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/MAINFRM.CPP new file mode 100644 index 0000000..086a4ab --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/MAINFRM.CPP @@ -0,0 +1,114 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mainfrm.cpp : implementation of the CMainFrame class +// + +#include "stdafx.h" +#include "dcl.h" + +#include "mainfrm.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code ! + ON_WM_CREATE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// arrays of IDs used to initialize control bars + +// toolbar buttons - IDs are command buttons +static UINT BASED_CODE buttons[] = +{ + // same order as in the bitmap 'toolbar.bmp' + ID_FILE_NEW, + ID_FILE_OPEN, + ID_FILE_SAVE, + ID_SEPARATOR, + ID_EDIT_PASTE, + ID_SEPARATOR, + ID_FILE_PRINT, + ID_APP_ABOUT, +}; + +static UINT BASED_CODE indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + // TODO: add member initialization code here +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndToolBar.Create(this) || + !m_wndToolBar.LoadBitmap(IDR_MAINFRAME) || + !m_wndToolBar.SetButtons(buttons, + sizeof(buttons)/sizeof(UINT))) + { + TRACE("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE("Failed to create status bar\n"); + return -1; // fail to create + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/MAINFRM.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/MAINFRM.H new file mode 100644 index 0000000..1e000cc --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/MAINFRM.H @@ -0,0 +1,47 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mainfrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + CMainFrame(); + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + +// Operations +public: + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/PKSTRUCT.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/PKSTRUCT.H new file mode 100644 index 0000000..bfdee74 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/PKSTRUCT.H @@ -0,0 +1,24 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#ifndef __PKSTRUCT__ +#define __PKSTRUCT__ 1 + +typedef struct IOFILEBLOCK +{ + FILE *InFile; + FILE *OutFile; + BOOL bDoCRC; + DWORD dwCRC; + BOOL DebugMessages; + HWND hWindow; + BOOL PKAbortOperation; +} +*PIOFILEBLOCK; + +#endif diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/DCL.ICO b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/DCL.ICO new file mode 100644 index 0000000..b718392 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/DCL.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/DCL.RC2 b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/DCL.RC2 new file mode 100644 index 0000000..f138e1f --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/DCL.RC2 @@ -0,0 +1,52 @@ +// +// DCL.RC2 - resources App Studio does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by App Studio +#endif //APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// Version stamp for this .EXE + +#include "ver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG|VS_FF_PRIVATEBUILD|VS_FF_PRERELEASE +#else + FILEFLAGS 0 // final version +#endif + FILEOS VOS_DOS_WINDOWS16 + FILETYPE VFT_APP + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "DCL MFC Application\0" + VALUE "FileVersion", "1.0.001\0" + VALUE "InternalName", "DCL\0" + VALUE "LegalCopyright", "\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename","DCL.EXE\0" + VALUE "ProductName", "DCL\0" + VALUE "ProductVersion", "1.0.001\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + // English language (0x409) and the Windows ANSI codepage (1252) + END +END + +///////////////////////////////////////////////////////////////////////////// +// Add additional manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/TOOLBAR.BMP b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/TOOLBAR.BMP new file mode 100644 index 0000000..eaf5db2 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RES/TOOLBAR.BMP differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RESOURCE.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RESOURCE.H new file mode 100644 index 0000000..81a1161 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/RESOURCE.H @@ -0,0 +1,42 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +//{{NO_DEPENDENCIES}} +// App Studio generated include file. +// Used by DCL.RC +// +#define IDR_MAINFRAME 2 +#define IDD_ABOUTBOX 100 +#define IDD_DIALOG1 102 +#define IDC_LIST1 1000 +#define IDC_BUTTON1 1001 +#define IDC_BUTTON2 1002 +#define IDC_EDIT1 1003 +#define IDC_EDIT2 1004 +#define IDC_EDIT3 1005 +#define IDC_EDIT4 1006 +#define IDC_EDIT5 1007 +#define IDC_EDIT6 1008 +#define IDC_EDIT7 1009 +#define IDC_BUTTON3 1010 +#define IDC_EDIT8 1011 +#define IDC_BUTTON4 1012 +#define IDC_EDIT9 1013 +#define COMP_DIALOG 32771 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 32772 +#define _APS_NEXT_CONTROL_VALUE 1014 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/STDAFX.CPP b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/STDAFX.CPP new file mode 100644 index 0000000..07f7b46 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/STDAFX.CPP @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// stdafx.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/STDAFX.H b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/STDAFX.H new file mode 100644 index 0000000..6179a32 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/FIL2FIL/STDAFX.H @@ -0,0 +1,7 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#include // MFC core and standard components +#include // MFC extensions (including VB) diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/DCL.CPP b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/DCL.CPP new file mode 100644 index 0000000..52967dd --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/DCL.CPP @@ -0,0 +1,479 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +/* + * DCL.cpp - File to call various DCL DLL functions + */ + +#include "stdafx.h" + +#include +#include +#include + +#include "implode.h" + +typedef enum +{ + COMPRESSING = 1, + UNCOMPRESSING +} FILEMODE; + +typedef struct +{ + PBYTE Buffer; // POINTER TO BUFFER + UINT CurPos; // CURRENT POSITION IN BUFFER + UINT BuffSize; // SIZE OF THE BUFFER +} BUFFER_BLOCK, *PBUFFER_BLOCK; + +// STRUCT TO PASS TO THE FILE IO FUNCTIONS +typedef struct +{ + BUFFER_BLOCK FileBuff; // FILE BUFFER + BUFFER_BLOCK cmpBuff; // COMPRESSION BUFFER + BUFFER_BLOCK uncmpBuff; // UNCOMPRESSION BUFFER + FILEMODE mode; + DWORD dwCrc; // CRC + UINT nCompressSize; + BOOL ErrorOccurred; // ERROR FLAG +} DATABLOCK, *PDATABLOCK; + +UINT DataType = CMP_ASCII; // GLOBAL FOR DATA TYPE FOR COMPRESSION +UINT DictSize = 4096; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +static int iLineCnt; // CURRENT LINE TO OUTPUT STRING + +/********************************************************************* + * + * Function: ReadBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * read requests. If compressing, then the data read is + * in uncompressed form. If compressing, then the data + * read is data that was previously compressed. This + * function is called until zero is returned. + * + * Parameters: buffer -> Address of buffer to read the data into + * iSize -> Number of bytes to read into buffer + * dwParam -> User-defined parameter, in this case a + * pointer to the DATABLOCK + * + * Returns: Number of bytes actually read, or zero on EOF + * + *********************************************************************/ +UINT ReadBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + PDATABLOCK pDataBlock; + PBUFFER_BLOCK pBufferBlock; + UINT iRead; + + pDataBlock = (PDATABLOCK) pParam; + + // IF AN ERROR OCCURRED + if( pDataBlock->ErrorOccurred == TRUE ) + { + return 0; + } + + if( pDataBlock->mode == COMPRESSING ) + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE COMPRESSION BUFFER + pBufferBlock = &pDataBlock->FileBuff; + } + else + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE UNCOMPRESSION BUFFER + pBufferBlock = &pDataBlock->cmpBuff; + } + + if( pBufferBlock->CurPos < pBufferBlock->BuffSize ) + { + UINT BytesLeft = pBufferBlock->BuffSize - pBufferBlock->CurPos; + + // IF REQUESTING MORE BYTES THAN ARE LEFT + if( BytesLeft < *iSize ) + { + // SET NUMBER OF BYTES TO COPY TO WHAT IS LEFT + *iSize = BytesLeft; + } + + // COPY BYTES AND UPDATE COUNTER + memcpy( buffer, (pBufferBlock->Buffer + pBufferBlock->CurPos), *iSize ); + pBufferBlock->CurPos += *iSize; + + iRead = *iSize; + } + else // ELSE - NOTHING LEFT IN BUFFER SO RETURN 0 + { + iRead = 0; + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if( pDataBlock->mode == COMPRESSING ) + { + pDataBlock->dwCrc = crc32( buffer, &iRead, &pDataBlock->dwCrc ); + } + + return iRead; +} + +/********************************************************************* + * + * Function: WriteBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * write requests. + * + * Parameters: buffer -> Address of buffer to write data from + * iSize -> Number of bytes to write + * dwParam -> User-defined parameter, in this case a + * pointer to the DATABLOCK + * + * Returns: Zero, the return value is not used by the Data + * Compression Library + * + *********************************************************************/ +void WriteBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + PDATABLOCK pDataBlock; + PBUFFER_BLOCK pBufferBlock; + + pDataBlock = (PDATABLOCK) pParam; + + // IF AN ERROR OCCURRED + if( pDataBlock->ErrorOccurred == TRUE ) + { + return; + } + + if( pDataBlock->mode == COMPRESSING ) + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE COMPRESSION BUFFER + pBufferBlock = &pDataBlock->cmpBuff; + + // SINCE COMPRESSING, KEEP A TOTAL OF THE COMPRESSED FILE SIZE + pDataBlock->nCompressSize += *iSize; + } + else + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE UNCOMPRESSION BUFFER + pBufferBlock = &pDataBlock->uncmpBuff; + } + + // IF NOT OUT OF BUFFER SPACE + if( pBufferBlock->CurPos < pBufferBlock->BuffSize ) + { + // IF WRITING MORE BYTES THAN ARE LEFT + if( (pBufferBlock->BuffSize - pBufferBlock->CurPos) < *iSize ) + { + MessageBox( NULL, "Out of buffer space - #1", "Compression Error", MB_OK ); + pDataBlock->ErrorOccurred = TRUE; + return; + } + + // COPY BYTES AND UPDATE COUNTER + memcpy( (pBufferBlock->Buffer + pBufferBlock->CurPos), + buffer, *iSize ); + pBufferBlock->CurPos += *iSize; + } + else // ELSE - NOTHING LEFT IN BUFFER SO RETURN 0 + { + MessageBox( NULL, "Out of buffer space - #2", "Compression Error", MB_OK ); + pDataBlock->ErrorOccurred = TRUE; + return; + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if (pDataBlock->mode == UNCOMPRESSING ) + { + pDataBlock->dwCrc = crc32( buffer, iSize, &pDataBlock->dwCrc ); + } + + return; +} + +/********************************************************************* + * + * Function: CompressMemToMem() + * + * Purpose: To compress a buffer to another buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * pnCompressedSize -> Number of bytes in the compressed + * buffer + * pFileBuffer -> Pointer to buffer to compress + * pCompressedBuffer -> Pointer to buffer to place + * compressed data + * BuffSize -> Size of the buffers (both are allocated + * for same number of bytes) + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressMemToMem( HWND hWnd, CDC *pDC, DWORD *pdwCrc, + UINT *pnCompressedSize, PBYTE pFileBuffer, + PBYTE pCompressedBuffer, UINT BuffSize ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + DATABLOCK DataBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + memset( &DataBlock, 0, sizeof(DataBlock) ); + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + DataBlock.mode = COMPRESSING; + DataBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + // SETUP BUFFER BLOCK FOR FILE BUFFER + DataBlock.FileBuff.Buffer = pFileBuffer; + DataBlock.FileBuff.BuffSize = BuffSize; + + // SETUP BUFFER BLOCK FOR COMPRESSION BUFFER + DataBlock.cmpBuff.Buffer = pCompressedBuffer; + DataBlock.cmpBuff.BuffSize = BuffSize; + + wsprintf( szVerbose, "Compressing %u byte buffer to memory ", BuffSize ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + + // COMPRESS THE FILE + iStatus = implode( ReadBuffer, WriteBuffer, + pScratchPad, &DataBlock, &DataType, &DictSize ); + + // IF THERE WAS AN ERROR COMPRESSING FILE + if( iStatus || DataBlock.ErrorOccurred ) + { + // DISPLAY ERROR STRING IF ERROR OCCURRED IN IMPLODE + wsprintf( szVerbose, "Error occurred while imploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - COMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + DataBlock.dwCrc = ~DataBlock.dwCrc; + + // RETURN CRC + *pdwCrc = DataBlock.dwCrc; + + // RETURN COMPRESSED BUFFER SIZE + *pnCompressedSize = DataBlock.nCompressSize; + + wsprintf( szVerbose, "Compressed file to memory -> CRC = %08lX ", + DataBlock.dwCrc ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + } + + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: ExpandMemToMem() + * + * Purpose: To expand a compressed buffer to a buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file after uncompression + * pCompressedBuffer -> Pointer to buffer to place + * compressed data + * nCompressedSize -> Number of bytes in the compressed + * buffer + * pUncompressedBuffer -> Pointer to buffer to place + * uncompressed data + * BuffSize -> Size of the uncompressed buffer + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int ExpandMemToMem( HWND hWnd, CDC *pDC, DWORD *pdwCrc, + PBYTE pCompressedBuffer, UINT nCompressedSize, + PBYTE pUncompressedBuffer, UINT BuffSize ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + DATABLOCK DataBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + memset( &DataBlock, 0, sizeof(DataBlock) ); + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + DataBlock.mode = UNCOMPRESSING; + DataBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + // SETUP BUFFER BLOCK FOR COMPRESSION BUFFER + DataBlock.cmpBuff.Buffer = pCompressedBuffer; + DataBlock.cmpBuff.BuffSize = nCompressedSize; + + // SETUP BUFFER BLOCK FOR UNCOMPRESSION BUFFER + DataBlock.uncmpBuff.Buffer = pUncompressedBuffer; + DataBlock.uncmpBuff.BuffSize = BuffSize; + + wsprintf( szVerbose, "Compressed buffer size = %u ", nCompressedSize ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, "Uncompressing buffer to memory " ); + + // UNCOMPRESS THE FILE + iStatus = explode( ReadBuffer, WriteBuffer, pScratchPad, &DataBlock ); + + // IF THERE WAS AN ERROR UNCOMPRESSING FILE + if( iStatus || DataBlock.ErrorOccurred ) + { + wsprintf( szVerbose, "Error occurred while exploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - UNCOMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + DataBlock.dwCrc = ~DataBlock.dwCrc; + + // RETURN CRC + *pdwCrc = DataBlock.dwCrc; + + wsprintf( szVerbose, "Uncompressed file to memory -> CRC = %08lX ", + DataBlock.dwCrc ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + } + + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: MemToMemExample() + * + * Purpose: To load a file into memory. Then compress and uncompress + * the buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszFilename -> Name of file to load + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int MemToMemExample( HWND hWnd, CDC *pDC, PCHAR pszFilename ) +{ + ASSERT( hWnd ); + ASSERT_VALID( pDC ); + + CFile InFile; + int rc=1; // RETURN CODE + UINT BufferSize; + UINT cmpSize; + PBYTE pFileBuffer; // BUFFER FOR FILE DATA + PBYTE pCompressedBuffer; // BUFFER FOR THE COMPRESSED DATA + PBYTE pUncompressedBuffer; // BUFFER FOR THE UNCOMPRESSED DATA + DWORD cmpCrc; // CRC OF FILE BEFORE COMPRESSION + DWORD uncmpCrc; // CRC OF FILE AFTER UNCOMPRESSION + + + iLineCnt = 0; + + // OPEN THE FILE + if( !InFile.Open( pszFilename, + CFile::modeRead | CFile::shareExclusive | CFile::typeBinary ) ) + { + MessageBox( hWnd, "Error opening file for compression", "Error", MB_OK ); + return 0; + } + + // CHECK IF FILE IS TOO LARGE + if( InFile.GetLength() > 64000U ) + { + MessageBox( hWnd, "File is too large to compress to memory", "Error", MB_OK ); + return 0; + } + + BufferSize = (UINT) InFile.GetLength(); + + // ALLOCATE BUFFER MEMORY + pFileBuffer = (PBYTE) new char[BufferSize]; + pCompressedBuffer = (PBYTE) new char[BufferSize]; + pUncompressedBuffer = (PBYTE) new char[BufferSize]; + + // IF SUCCESSFULLY ALLOCATED MEMORY + if( (pFileBuffer != NULL) && + (pCompressedBuffer != NULL) && + (pUncompressedBuffer != NULL) ) + { + // READ FILE + InFile.Read( pFileBuffer, BufferSize ); + + // IF COMPRESSED OK + if( CompressMemToMem( hWnd, pDC, &cmpCrc, &cmpSize, + pFileBuffer, pCompressedBuffer, BufferSize ) ) + { + // IF ERROR UNCOMPRESSING + if( !ExpandMemToMem( hWnd, pDC, &uncmpCrc, + pCompressedBuffer, cmpSize, + pUncompressedBuffer, BufferSize ) ) + { + MessageBox( hWnd, "Error uncompressing to memory", "Error", MB_OK ); + rc = 0; + } + } + else + { + MessageBox( hWnd, "Error compressing to memory", "Error", MB_OK ); + rc = 0; + } + } + + + if( pFileBuffer != NULL ) + { + delete pFileBuffer; + } + + if( pCompressedBuffer != NULL ) + { + delete pCompressedBuffer; + } + + if( pUncompressedBuffer != NULL ) + { + delete pUncompressedBuffer; + } + + return rc; +} + + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/DCL.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/DCL.H new file mode 100644 index 0000000..c70ef42 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/DCL.H @@ -0,0 +1,10 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1994,1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +int MemToMemExample( HWND hWnd, CDC *pDC, PCHAR lpszFilename ); diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/IMPLODE.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/IMPLODEI.LIB b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/IMPLODEI.LIB new file mode 100644 index 0000000..ca0b4df Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/IMPLODEI.LIB differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MAINFRM.CPP b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MAINFRM.CPP new file mode 100644 index 0000000..47fb798 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MAINFRM.CPP @@ -0,0 +1,126 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mainfrm.cpp : implementation of the CMainFrame class +// + +#include "stdafx.h" +#include "mem2mem.h" + +#include "mainfrm.h" +#include "DCL.H" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_COMMAND(IDM_TEST, OnTest) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// arrays of IDs used to initialize control bars + +// toolbar buttons - IDs are command buttons +static UINT BASED_CODE buttons[] = +{ + // same order as in the bitmap 'toolbar.bmp' + ID_FILE_NEW, + ID_FILE_OPEN, + ID_FILE_SAVE, + ID_SEPARATOR, + ID_EDIT_CUT, + ID_EDIT_COPY, + ID_EDIT_PASTE, + ID_SEPARATOR, + ID_FILE_PRINT, + ID_APP_ABOUT, +}; + +static UINT BASED_CODE indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + // TODO: add member initialization code here +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE("Failed to create status bar\n"); + return -1; // fail to create + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnTest() +{ + CFileDialog FileDlg( TRUE, NULL, "*.*" ); + + if( FileDlg.DoModal() == IDOK ) + { + HWND hWnd; + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + CClientDC dc(this); + COLORREF bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + hWnd = CWnd::GetSafeHwnd(); + + MemToMemExample( hWnd, &dc, (LPSTR)(const char *)FileDlg.GetPathName() ); + } +} diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MAINFRM.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MAINFRM.H new file mode 100644 index 0000000..78e8804 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MAINFRM.H @@ -0,0 +1,46 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mainfrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + CMainFrame(); + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + +// Operations +public: + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnTest(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MDOC.CPP b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MDOC.CPP new file mode 100644 index 0000000..e2c5e90 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MDOC.CPP @@ -0,0 +1,88 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mem2mdoc.cpp : implementation of the CMem2memDoc class +// + +#include "stdafx.h" +#include "mem2mem.h" + +#include "mem2mdoc.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMem2memDoc + +IMPLEMENT_DYNCREATE(CMem2memDoc, CDocument) + +BEGIN_MESSAGE_MAP(CMem2memDoc, CDocument) + //{{AFX_MSG_MAP(CMem2memDoc) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMem2memDoc construction/destruction + +CMem2memDoc::CMem2memDoc() +{ + // TODO: add one-time construction code here +} + +CMem2memDoc::~CMem2memDoc() +{ +} + +BOOL CMem2memDoc::OnNewDocument() +{ + if (!CDocument::OnNewDocument()) + return FALSE; + + // TODO: add reinitialization code here + // (SDI documents will reuse this document) + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMem2memDoc serialization + +void CMem2memDoc::Serialize(CArchive& ar) +{ + if (ar.IsStoring()) + { + // TODO: add storing code here + } + else + { + // TODO: add loading code here + } +} + +///////////////////////////////////////////////////////////////////////////// +// CMem2memDoc diagnostics + +#ifdef _DEBUG +void CMem2memDoc::AssertValid() const +{ + CDocument::AssertValid(); +} + +void CMem2memDoc::Dump(CDumpContext& dc) const +{ + CDocument::Dump(dc); +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMem2memDoc commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MDOC.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MDOC.H new file mode 100644 index 0000000..13745b9 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MDOC.H @@ -0,0 +1,45 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mem2mdoc.h : interface of the CMem2memDoc class +// +///////////////////////////////////////////////////////////////////////////// + +class CMem2memDoc : public CDocument +{ +protected: // create from serialization only + CMem2memDoc(); + DECLARE_DYNCREATE(CMem2memDoc) + +// Attributes +public: +// Operations +public: + +// Implementation +public: + virtual ~CMem2memDoc(); + virtual void Serialize(CArchive& ar); // overridden for document i/o +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + virtual BOOL OnNewDocument(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMem2memDoc) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.CPP b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.CPP new file mode 100644 index 0000000..1c49951 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.CPP @@ -0,0 +1,137 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mem2mem.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "mem2mem.h" + +#include "mainfrm.h" +#include "mem2mdoc.h" +#include "mem2mvw.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMem2memApp + +BEGIN_MESSAGE_MAP(CMem2memApp, CWinApp) + //{{AFX_MSG_MAP(CMem2memApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMem2memApp construction + +CMem2memApp::CMem2memApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CMem2memApp object + +CMem2memApp NEAR theApp; + +///////////////////////////////////////////////////////////////////////////// +// CMem2memApp initialization + +BOOL CMem2memApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + SetDialogBkColor(); // Set dialog background color to gray + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CSingleDocTemplate* pDocTemplate; + pDocTemplate = new CSingleDocTemplate( + IDR_MAINFRAME, + RUNTIME_CLASS(CMem2memDoc), + RUNTIME_CLASS(CMainFrame), // main SDI frame window + RUNTIME_CLASS(CMem2memView)); + AddDocTemplate(pDocTemplate); + + // create a new (empty) document + OnFileNew(); + + if (m_lpCmdLine[0] != '\0') + { + // TODO: add command line processing here + } + + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + +// Implementation +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CMem2memApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CMem2memApp commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.H new file mode 100644 index 0000000..58899ff --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.H @@ -0,0 +1,42 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mem2mem.h : main header file for the MEM2MEM application +// + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CMem2memApp: +// See mem2mem.cpp for the implementation of this class +// + +class CMem2memApp : public CWinApp +{ +public: + CMem2memApp(); + +// Overrides + virtual BOOL InitInstance(); + +// Implementation + + //{{AFX_MSG(CMem2memApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.MAK b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.MAK new file mode 100644 index 0000000..8a78592 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.MAK @@ -0,0 +1,283 @@ +# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE No configuration specified. Defaulting to Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "MEM2MEM.MAK" CFG="Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Win32 Debug" +MTL=MkTypLib.exe +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Win32 Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/MEM2MEM.exe $(OUTDIR)/MEM2MEM.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE CPP /nologo /MD /W3 /GX /YX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"STDAFX.H" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MEM2MEM.pch" /Yu"STDAFX.H" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ +# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"MEM2MEM.res" /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"MEM2MEM.bsc" + +$(OUTDIR)/MEM2MEM.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib pkwdcl.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /MACHINE:IX86 +# ADD LINK32 oldnames.lib implodei.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /MACHINE:IX86 +# SUBTRACT LINK32 /INCREMENTAL:yes +LINK32_FLAGS=oldnames.lib implodei.lib /NOLOGO /STACK:0x10240\ + /SUBSYSTEM:windows /INCREMENTAL:no /PDB:$(OUTDIR)/"MEM2MEM.pdb" /MACHINE:IX86\ + /OUT:$(OUTDIR)/"MEM2MEM.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/MEM2MEM.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/MEM2MEM.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/MEM2MDOC.OBJ \ + $(INTDIR)/MEM2MVW.OBJ \ + $(INTDIR)/DCL.OBJ + +$(OUTDIR)/MEM2MEM.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/MEM2MEM.exe $(OUTDIR)/MEM2MEM.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE CPP /nologo /MD /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"STDAFX.H" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MEM2MEM.pch" /Yu"STDAFX.H" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"MEM2MEM.pdb" /c +CPP_OBJS=.\WinDebug/ +# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"MEM2MEM.res" /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"MEM2MEM.bsc" + +$(OUTDIR)/MEM2MEM.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib pkwdcl.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /DEBUG /MACHINE:IX86 +# ADD LINK32 oldnames.lib implodei.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /INCREMENTAL:no /DEBUG /MACHINE:IX86 +LINK32_FLAGS=oldnames.lib implodei.lib /NOLOGO /STACK:0x10240\ + /SUBSYSTEM:windows /INCREMENTAL:no /PDB:$(OUTDIR)/"MEM2MEM.pdb" /DEBUG\ + /MACHINE:IX86 /OUT:$(OUTDIR)/"MEM2MEM.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/MEM2MEM.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/MEM2MEM.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/MEM2MDOC.OBJ \ + $(INTDIR)/MEM2MVW.OBJ \ + $(INTDIR)/DCL.OBJ + +$(OUTDIR)/MEM2MEM.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Group "Source Files" + +################################################################################ +# Begin Source File + +SOURCE=.\MEM2MEM.RC +DEP_MEM2M=\ + .\RES\MEM2MEM.ICO\ + .\RES\TOOLBAR.BMP\ + .\RESOURCE.H\ + .\RES\MEM2MEM.RC2 + +$(INTDIR)/MEM2MEM.res : $(SOURCE) $(DEP_MEM2M) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\STDAFX.CPP +DEP_STDAF=\ + .\STDAFX.H + +!IF "$(CFG)" == "Win32 Release" + +# ADD BASE CPP /Yc"STDAFX.H" +# ADD CPP /Yc"STDAFX.H" + +$(INTDIR)/STDAFX.OBJ : $(SOURCE) $(DEP_STDAF) $(INTDIR) + $(CPP) /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MEM2MEM.pch" /Yc"STDAFX.H" /Fo$(INTDIR)/ /c\ + $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# ADD BASE CPP /Yc"STDAFX.H" +# ADD CPP /Yc"STDAFX.H" + +$(INTDIR)/STDAFX.OBJ : $(SOURCE) $(DEP_STDAF) $(INTDIR) + $(CPP) /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MEM2MEM.pch" /Yc"STDAFX.H" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"MEM2MEM.pdb" /c $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MEM2MEM.CPP +DEP_MEM2ME=\ + .\STDAFX.H\ + .\MEM2MEM.H\ + .\MAINFRM.H\ + .\MEM2MDOC.H\ + .\MEM2MVW.H\ + .\RESOURCE.H + +$(INTDIR)/MEM2MEM.OBJ : $(SOURCE) $(DEP_MEM2ME) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MAINFRM.CPP +DEP_MAINF=\ + .\STDAFX.H\ + .\MEM2MEM.H\ + .\MAINFRM.H\ + .\DCL.H\ + .\RESOURCE.H + +$(INTDIR)/MAINFRM.OBJ : $(SOURCE) $(DEP_MAINF) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MEM2MDOC.CPP +DEP_MEM2MD=\ + .\STDAFX.H\ + .\MEM2MEM.H\ + .\MEM2MDOC.H\ + .\RESOURCE.H + +$(INTDIR)/MEM2MDOC.OBJ : $(SOURCE) $(DEP_MEM2MD) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MEM2MVW.CPP +DEP_MEM2MV=\ + .\STDAFX.H\ + .\MEM2MEM.H\ + .\MEM2MDOC.H\ + .\MEM2MVW.H\ + .\RESOURCE.H + +$(INTDIR)/MEM2MVW.OBJ : $(SOURCE) $(DEP_MEM2MV) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DCL.CPP +DEP_DCL_C=\ + .\STDAFX.H\ + .\PKWDCL.H + +$(INTDIR)/DCL.OBJ : $(SOURCE) $(DEP_DCL_C) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +# End Group +# End Project +################################################################################ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.RC b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.RC new file mode 100644 index 0000000..d125235 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MEM.RC @@ -0,0 +1,209 @@ +//Microsoft App Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#ifdef APSTUDIO_INVOKED +////////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""res\\mem2mem.rc2"" // non-App Studio edited resources\r\n" + "\r\n" + "#include ""afxres.rc"" \011// Standard components\r\n" + "\0" +END + +///////////////////////////////////////////////////////////////////////////////////// +#endif // APSTUDIO_INVOKED + + +////////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +IDR_MAINFRAME ICON DISCARDABLE "RES\\MEM2MEM.ICO" + +////////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINFRAME BITMAP MOVEABLE PURE "RES\\TOOLBAR.BMP" + +////////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU PRELOAD DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Test", IDM_TEST + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "&View" + BEGIN + MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR + END + POPUP "&Help" + BEGIN + MENUITEM "&About Mem2mem...", ID_APP_ABOUT + END +END + + +////////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 34, 22, 217, 55 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Mem2mem" +FONT 8, "MS Sans Serif" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20 + LTEXT "Mem2mem Application Version 1.0",IDC_STATIC,40,10,119,8 + LTEXT "Copyright \251 1995",IDC_STATIC,40,25,119,8 + DEFPUSHBUTTON "OK",IDOK,176,6,32,14,WS_GROUP +END + + +////////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + IDR_MAINFRAME "Mem2mem Windows Application\n\nMem2me Document\n\n\nMem2me.Document\nMem2me Document" +END + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + AFX_IDS_APP_TITLE "Mem2mem Windows Application" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_INDICATOR_EXT "EXT" + ID_INDICATOR_CAPS "CAP" + ID_INDICATOR_NUM "NUM" + ID_INDICATOR_SCRL "SCRL" + ID_INDICATOR_OVR "OVR" + ID_INDICATOR_REC "REC" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_NEW "Create a new document" + ID_FILE_OPEN "Open an existing document" + ID_FILE_CLOSE "Close the active document" + ID_FILE_SAVE "Save the active document" + ID_FILE_SAVE_AS "Save the active document with a new name" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright" + ID_APP_EXIT "Quit the application; prompts to save documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_MRU_FILE1 "Open this document" + ID_FILE_MRU_FILE2 "Open this document" + ID_FILE_MRU_FILE3 "Open this document" + ID_FILE_MRU_FILE4 "Open this document" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane" + ID_PREV_PANE "Switch back to the previous window pane" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection" + ID_EDIT_CLEAR_ALL "Erase everything" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard" + ID_EDIT_FIND "Find the specified text" + ID_EDIT_PASTE "Insert Clipboard contents" + ID_EDIT_REPEAT "Repeat the last action" + ID_EDIT_REPLACE "Replace specific text with different text" + ID_EDIT_SELECT_ALL "Select the entire document" + ID_EDIT_UNDO "Undo the last action" + ID_EDIT_REDO "Redo the previously undone action" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_VIEW_TOOLBAR "Show or hide the toolbar" + ID_VIEW_STATUS_BAR "Show or hide the status bar" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDM_TEST "Test compression to and from memory" +END + + +#ifndef APSTUDIO_INVOKED +//////////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "res\mem2mem.rc2" // non-App Studio edited resources + +#include "afxres.rc" // Standard components + +///////////////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MVW.CPP b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MVW.CPP new file mode 100644 index 0000000..22cf6a1 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MVW.CPP @@ -0,0 +1,80 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mem2mvw.cpp : implementation of the CMem2memView class +// + +#include "stdafx.h" +#include "mem2mem.h" + +#include "mem2mdoc.h" +#include "mem2mvw.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMem2memView + +IMPLEMENT_DYNCREATE(CMem2memView, CView) + +BEGIN_MESSAGE_MAP(CMem2memView, CView) + //{{AFX_MSG_MAP(CMem2memView) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMem2memView construction/destruction + +CMem2memView::CMem2memView() +{ + // TODO: add construction code here +} + +CMem2memView::~CMem2memView() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// CMem2memView drawing + +void CMem2memView::OnDraw(CDC* pDC) +{ + CMem2memDoc* pDoc = GetDocument(); + ASSERT_VALID(pDoc); + + // TODO: add draw code for native data here +} + +///////////////////////////////////////////////////////////////////////////// +// CMem2memView diagnostics + +#ifdef _DEBUG +void CMem2memView::AssertValid() const +{ + CView::AssertValid(); +} + +void CMem2memView::Dump(CDumpContext& dc) const +{ + CView::Dump(dc); +} + +CMem2memDoc* CMem2memView::GetDocument() // non-debug version is inline +{ + ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMem2memDoc))); + return (CMem2memDoc*)m_pDocument; +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMem2memView message handlers diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MVW.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MVW.H new file mode 100644 index 0000000..402a082 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/MEM2MVW.H @@ -0,0 +1,51 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mem2mvw.h : interface of the CMem2memView class +// +///////////////////////////////////////////////////////////////////////////// + +class CMem2memView : public CView +{ +protected: // create from serialization only + CMem2memView(); + DECLARE_DYNCREATE(CMem2memView) + +// Attributes +public: + CMem2memDoc* GetDocument(); + +// Operations +public: + +// Implementation +public: + virtual ~CMem2memView(); + virtual void OnDraw(CDC* pDC); // overridden to draw this view +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + +// Generated message map functions +protected: + //{{AFX_MSG(CMem2memView) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#ifndef _DEBUG // debug version in mem2mvw.cpp +inline CMem2memDoc* CMem2memView::GetDocument() + { return (CMem2memDoc*)m_pDocument; } +#endif + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/MEM2MEM.ICO b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/MEM2MEM.ICO new file mode 100644 index 0000000..b718392 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/MEM2MEM.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/MEM2MEM.RC2 b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/MEM2MEM.RC2 new file mode 100644 index 0000000..a579bf3 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/MEM2MEM.RC2 @@ -0,0 +1,52 @@ +// +// MEM2MEM.RC2 - resources App Studio does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by App Studio +#endif //APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// Version stamp for this .EXE + +#include "ver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG|VS_FF_PRIVATEBUILD|VS_FF_PRERELEASE +#else + FILEFLAGS 0 // final version +#endif + FILEOS VOS_DOS_WINDOWS16 + FILETYPE VFT_APP + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "MEM2MEM MFC Application\0" + VALUE "FileVersion", "1.0.001\0" + VALUE "InternalName", "MEM2MEM\0" + VALUE "LegalCopyright", "\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename","MEM2MEM.EXE\0" + VALUE "ProductName", "MEM2MEM\0" + VALUE "ProductVersion", "1.0.001\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + // English language (0x409) and the Windows ANSI codepage (1252) + END +END + +///////////////////////////////////////////////////////////////////////////// +// Add additional manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/TOOLBAR.BMP b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/TOOLBAR.BMP new file mode 100644 index 0000000..49695e2 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RES/TOOLBAR.BMP differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RESOURCE.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RESOURCE.H new file mode 100644 index 0000000..45c5b88 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/RESOURCE.H @@ -0,0 +1,27 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +//{{NO_DEPENDENCIES}} +// App Studio generated include file. +// Used by MEM2MEM.RC +// +#define IDR_MAINFRAME 2 +#define IDD_ABOUTBOX 100 +#define IDM_TEST 32771 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 32772 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/STDAFX.CPP b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/STDAFX.CPP new file mode 100644 index 0000000..07f7b46 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/STDAFX.CPP @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// stdafx.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/STDAFX.H b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/STDAFX.H new file mode 100644 index 0000000..6179a32 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MEM2MEM/STDAFX.H @@ -0,0 +1,7 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#include // MFC core and standard components +#include // MFC extensions (including VB) diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/DCL.CPP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/DCL.CPP new file mode 100644 index 0000000..dc292aa --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/DCL.CPP @@ -0,0 +1,705 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +/* + * DCL.cpp - File to call various DCL DLL functions + */ + +#include "stdafx.h" + +#include +#include +#include + +#include "implode.h" + +#define TEMPFILENAME "~~~.$$$" // TEMPORARY FILENAME TO CREATE +#define APPENDBUFSIZE 32000 // SIZE OF BUFFER TO ALLOCATE FOR APPENDING + // A COMPRESSED FILE TO .MCF FILE + +typedef enum +{ + COMPRESSING = 1, + UNCOMPRESSING +} FILEMODE; + + +// STRUCT TO PASS TO THE FILE IO FUNCTIONS +typedef struct +{ + CFile *InFile; + CFile *OutFile; + CDC *pDC; + BYTE nPrevNdx; + BYTE nCnt; + DWORD dwCompressSize; + FILEMODE mode; + DWORD dwCrc; +}IOFILEBLOCK, *PIOFILEBLOCK; + +// FOUR LETTER IDENTIFIER TO IDENTIFY A FILE AS +// A .MCF (MULTIPLE COMPRESSED FILES) FILE +char MCF_FILEHEADER[] = { "MCFX" }; + +#pragma pack(2) + +// HEADER FOR EACH FILE COMPRESSED INTO THE .MCF FILE +typedef struct +{ + DWORD dwCompressSize; // SIZE OF FILE COMPRESSED + DWORD dwCrc; // THE CRC OF THE FILE BEFORE COMPRESSION + char filename[13]; // NAME OF THE FILE +}CMP_FILEHEADER, *PCMP_FILEHEADER; + +#pragma pack(8) + +/* + * FORMAT OF .MCF FILE: + * + * .MCF FILEHEADER => MCFX + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * AND SO ON + * + */ + +static char *pszActiveString[] = { "|", "/", "-", "\\" }; + +UINT DataType = CMP_ASCII; // GLOBAL FOR DATA TYPE FOR COMPRESSION +UINT DictSize = 4096; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + + +/********************************************************************* + * + * Function: ProcessMessages() + * + * Purpose: To allow Windows to process window messages which + * allows the user to multitask will compressing and + * uncompressing files. + * + * Returns: Nothing + * + *********************************************************************/ +void ProcessMessages(void) +{ + MSG msg; + + while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { + if (msg.message == WM_QUIT) + return; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +/********************************************************************* + * + * Function: ProcessInBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * read requests. If compressing, then the data read is + * in uncompressed form. If compressing, then the data + * read is data that was previously compressed. This + * function is called until zero is returned. + * + * Parameters: buffer -> Address of buffer to read the data into + * iSize -> Number of bytes to read into buffer + * dwParam -> User-defined parameter, in this case a + * pointer to the IOFILEBLOCK + * + * Returns: Number of bytes actually read, or zero on EOF + * + *********************************************************************/ +UINT ProcessInBuffer( PCHAR buffer, UINT *iSize, void *pParam) +{ + PIOFILEBLOCK pFileIOBlock; + UINT iRead; + UINT ndx; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + // DISPLAY ROTATING LINE + ndx = (pFileIOBlock->nCnt >> 4) & 3; + if( ndx != pFileIOBlock->nPrevNdx ) + { + pFileIOBlock->pDC->TextOut( 10,2, pszActiveString[ndx] ); + pFileIOBlock->nPrevNdx = ndx; + } + pFileIOBlock->nCnt++; + + // THIS FUNCTION MAY ASK FOR UP TO 4K OF DATA AT A TIME. IF YOUR + // ARCHIVE FILE CONTAINS SEVERAL COMPRESSED FILES, YOU MAY READ TOO + // MUCH. FOR EXAMPLE, YOUR FIRST COMPRESSED FILE IN THE ARCHIVE MAY + // BE 100 BYTES. SO YOU DO NOT WANT TO READ MORE THAN 100 BYTES OR + // YOU WILL BE UNABLE TO UNCOMPRESS THE SECOND FILE, SINCE YOU WILL + // NOT BE LOCATED AT THE BEGINNING OF THE FILE ANY LONGER. + // WE WILL USE THE VARIABLE "dwCompressSize" TO CHECK FOR THIS + // CONDITION. + if( pFileIOBlock->mode == UNCOMPRESSING ) + { + // IF DCL REQUESTED MORE BYTES THAN ARE LEFT IN COMPRESSED FILE, THEN + // SET THE NUMBER OF BYTES TO READ TO THE AMOUNT LEFT IN THE BUFFER + if( (DWORD) *iSize > pFileIOBlock->dwCompressSize ) + *iSize = (UINT) pFileIOBlock->dwCompressSize; + + pFileIOBlock->dwCompressSize -= (DWORD) *iSize; + } + + // READ BUFFER FROM DISK + iRead = (UINT)pFileIOBlock->InFile->Read( buffer, *iSize ); + + // IF COMPRESSING, THEN CALCULATE THE CRC + if( pFileIOBlock->mode == COMPRESSING ) + { + pFileIOBlock->dwCrc = crc32( buffer, &iRead, &pFileIOBlock->dwCrc ); + } + + // ENTER MESSAGE LOOP TO PROCESS BACKGROUND MESSAGES + // AND SIMULATE MULTITASKING + ProcessMessages(); + + return iRead; +} + +/********************************************************************* + * + * Function: ProcessOutBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * write requests. + * + * Parameters: buffer -> Address of buffer to write data from + * iSize -> Number of bytes to write + * dwParam -> User-defined parameter, in this case a + * pointer to the IOFILEBLOCK + * + * Returns: Zero, the return value is not used by the Data + * Compression Library + * + *********************************************************************/ +void ProcessOutBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + PIOFILEBLOCK pFileIOBlock; + UINT ndx; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + // DISPLAY ROTATING LINE PACIFIER + ndx = (pFileIOBlock->nCnt >> 4) & 3; + if( ndx != pFileIOBlock->nPrevNdx ) + { + pFileIOBlock->pDC->TextOut( 10,2, pszActiveString[ndx] ); + pFileIOBlock->nPrevNdx = ndx; + } + pFileIOBlock->nCnt++; + + // WRITE BUFFER TO DISK + pFileIOBlock->OutFile->Write(buffer, *iSize); + + // IF COMPRESSING, THEN KEEP A TOTAL OF THE COMPRESSED FILE SIZE + if (pFileIOBlock->mode == COMPRESSING ) + { + pFileIOBlock->dwCompressSize += (DWORD) *iSize; + } + else // ELSE UNCOMPRESSING, SO CALCULATE CRC ON THE UNCOMPRESSED DATA + { + pFileIOBlock->dwCrc = crc32(buffer, iSize, &pFileIOBlock->dwCrc); + } + + // ENTER MESSAGE LOOP TO PROCESS BACKGROUND MESSAGES + // AND SIMULATE MULTITASKING + ProcessMessages(); + + return; +} + +/********************************************************************* + * + * Function: CompressFile() + * + * Purpose: To compress file to a separate temporary file. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * pdwCompFileSize -> Pointer to DWORD buffer to return + * the size of the compressed file + * pszFileToCompress -> Name of file to compress + * OutputFile -> Name of file to write compressed data to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressFile( HWND hWnd, CDC *pDC, DWORD *pdwCrc, + DWORD *pdwCompFileSize, PCHAR pszFileToCompress, + PCHAR OutputFile ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + IOFILEBLOCK FileIOBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + // OPEN THE INPUT AND OUTPUT FILES + FileIOBlock.InFile = new CFile; + FileIOBlock.OutFile = new CFile; + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + FileIOBlock.mode = COMPRESSING; + FileIOBlock.dwCompressSize = 0; + FileIOBlock.pDC = pDC; + FileIOBlock.nCnt = 0; + FileIOBlock.nPrevNdx = 0; + FileIOBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + pDC->TextOut( 10,2, " " ); + + // OPEN THE FILES + if (FileIOBlock.InFile->Open( pszFileToCompress, CFile::modeRead | CFile::shareExclusive | CFile::typeBinary) && + FileIOBlock.OutFile->Open( OutputFile, CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary)) + { + wsprintf( szVerbose, "Compressing file: %s ", pszFileToCompress ); + pDC->TextOut( 10,40, szVerbose ); + + // ONLY COMPRESS IF FILE IS NOT A ZERO LENGTH FILE + if( FileIOBlock.InFile->GetLength() ) + { + // COMPRESS THE FILE + iStatus = implode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, + &FileIOBlock, &DataType, &DictSize ); + } + else + { + // SINCE THIS IS A ZERO LENGTH FILE, THERE IS NOTHING TO COMPRESS + // SET STATUS TO NO ERROR + iStatus = 0; + } + + // IF THERE WAS AN ERROR COMPRESSING FILE + if( iStatus ) + { + // DISPLAY ERROR STRING FROM DLL + wsprintf( szVerbose, "Error occurred while imploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - COMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + FileIOBlock.dwCrc = ~FileIOBlock.dwCrc; + + // RETURN CRC + *pdwCrc = FileIOBlock.dwCrc; + + // RETURN COMPRESSED FILE SIZE + *pdwCompFileSize = FileIOBlock.dwCompressSize; + } + + FileIOBlock.OutFile->Close(); + FileIOBlock.InFile->Close(); + } + else // ELSE - ERROR OPENING FILES + { + MessageBox( hWnd, "Error opening files for compression", "Error", MB_OK ); + rc = 0; + } + + // CLEAN-UP + delete FileIOBlock.InFile; + delete FileIOBlock.OutFile; + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: ExpandFile() + * + * Purpose: To uncompress file from a .MCF file. The .MCF file will + * have been read upto the compressed data stream. + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * dwCompFileSize -> Size of the compressed file + * pMcfFile -> Pointer to already opened .MCF file + * OutputFile -> Name of file to write uncompressed data to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int ExpandFile( HWND hWnd, CDC *pDC, DWORD *pdwCrc, + DWORD dwCompFileSize, CFile *pMcfFile, PCHAR OutputFile ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + IOFILEBLOCK FileIOBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + FileIOBlock.InFile = pMcfFile; + FileIOBlock.OutFile = new CFile; + + // SETUP STRUCTURE USED BY ProcessReadBuffer() and ProcessWriteBuffer() + FileIOBlock.mode = UNCOMPRESSING; + FileIOBlock.dwCompressSize = dwCompFileSize; + FileIOBlock.pDC = pDC; + FileIOBlock.nCnt = 0; + FileIOBlock.nPrevNdx = 0; + FileIOBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + pDC->TextOut( 10,2, " " ); + + if( FileIOBlock.OutFile->Open(OutputFile, CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary) ) + { + // ONLY UNCOMPRESS IF FILE IS NOT A ZERO LENGTH FILE + if( FileIOBlock.dwCompressSize ) + { + iStatus = explode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, &FileIOBlock ); + } + else + { + // SINCE THIS IS A ZERO LENGTH FILE, THERE IS NOTHING TO UNCOMPRESS + // SET STATUS TO NO ERROR + iStatus = 0; + } + + if( iStatus ) + { + wsprintf( szVerbose, "Error occurred while exploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else + { + FileIOBlock.dwCrc = ~FileIOBlock.dwCrc; + *pdwCrc = FileIOBlock.dwCrc; + + if( FileIOBlock.dwCompressSize != 0 ) + { + wsprintf( szVerbose, "Error uncompressing file: %s", OutputFile ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + } + + FileIOBlock.OutFile->Close(); + } + else + { + MessageBox( hWnd, "Error opening files for uncompression", "Error", MB_OK ); + rc = 0; + } + + delete FileIOBlock.OutFile; + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: AddFileToMcfFile() + * + * Purpose: To add a compressed file with header to a .MCF file. + * The file header is written followed by the compressed + * file data + * + * Parameters: pFileHeader -> File header for the compressed file + * pszInput -> Filename of the compressed file's data + * pszOutput -> Filename of .MCF file + * CompressedFileSize -> Size of the compressed file + * NewMcfFile -> Flag used to create a new .MCF file + * TRUE - A new .MCF file will be created + * FALSE - The .MCF file will appended to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int AddFileToMcfFile( PCMP_FILEHEADER pFileHeader, PCHAR pszInput, + PCHAR pszOutput, DWORD CompressedFileSize, + BOOL NewMcfFile ) +{ + PCHAR buf; + UINT read; + CFile InFile; + CFile OutFile; + + // ALLOCATE I/O BUFFER + if( (buf = new char[APPENDBUFSIZE]) == NULL ) + { + return 0; + } + + TRY + { + // OPEN THE FILES + InFile.Open( pszInput, CFile::modeRead | CFile::shareExclusive | CFile::typeBinary); + + // IF NEW FILE, THEN CREATE MULTIPLE COMPRESSED FILES FILE + if( NewMcfFile ) + { + // CREATE NEW .MCF FILE + OutFile.Open( pszOutput, CFile::modeCreate | CFile::modeWrite | CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary); + + // WRITE .MCF FILE HEADER + OutFile.Write( MCF_FILEHEADER, 4 ); + } + else + { + // OPEN OLD .MCF FILE + OutFile.Open( pszOutput, CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary); + + // GO TO END OF FILE + OutFile.SeekToEnd(); + } + + // WRITE THE COMPRESSED FILE'S FILEHEADER + OutFile.Write( pFileHeader, sizeof(CMP_FILEHEADER) ); + + do + { + // READ FROM COMPRESSED FILE + read = InFile.Read( buf, APPENDBUFSIZE ); + + // WRITE DATA TO .MCF FILE + OutFile.Write( buf, read ); + + // IF ERROR OCCURRED + if( CompressedFileSize < (DWORD) read ) + { + delete buf; + return 0; + } + + CompressedFileSize -= (DWORD) read; + } + while( CompressedFileSize > 0 ); + } + CATCH( CFileException, theException ) + { + // IF ERROR OCCURRED WHILE APPENDING FILE + if( theException->m_cause != CFileException::none ) + { + delete buf; + return 0; + } + } + END_CATCH + + delete buf; + + return 1; +} + +/********************************************************************* + * + * Function: CompressFileToMCF() + * + * Purpose: To compress a file then add it to a .MCF file + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszMcfFile -> Filename of .MCF file + * pszFileToCompress -> Filename of file with full path + * pszFilenameOnly -> Filename of file without any path + * This is the filename that is stored + * in the compressed file's file header + * NewMcfFile -> Flag used to create a new .MCF file + * TRUE - A new .MCF file will be created + * FALSE - The .MCF file will appended to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressFileToMCF( HWND hWnd, CDC *pDC, + PCHAR pszMcfFile, PCHAR pszFileToCompress, + PCHAR pszFilenameOnly, BOOL NewMcfFile ) +{ + ASSERT( hWnd ); + ASSERT_VALID( pDC ); + + CMP_FILEHEADER FileHeader; + + memset( &FileHeader, 0, sizeof(FileHeader) ); + + // ATTEMPT TO COMPRESS THE FILE + if( !CompressFile( hWnd, pDC, &FileHeader.dwCrc, + &FileHeader.dwCompressSize, pszFileToCompress, + TEMPFILENAME ) ) + { + remove( TEMPFILENAME ); + MessageBox( hWnd, "Compress File Failed", "Error", MB_OK ); + return 0; + } + + strcpy( FileHeader.filename, pszFilenameOnly ); + + if( !AddFileToMcfFile( &FileHeader, TEMPFILENAME, pszMcfFile, + FileHeader.dwCompressSize, NewMcfFile ) ) + { + remove( TEMPFILENAME ); + MessageBox( hWnd, "Compress File Failed", "Error", MB_OK ); + return 0; + } + + remove( TEMPFILENAME ); + + return 1; +} + +/********************************************************************* + * + * Function: UncompressFileToMCF() + * + * Purpose: To uncompress a .MCF file + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszMcfFilename -> Filename of .MCF file + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int UncompressMcfFile( HWND hWnd, CDC *pDC, PCHAR pszMcfFilename ) +{ + ASSERT( hWnd ); + ASSERT_VALID( pDC ); + + CMP_FILEHEADER FileHeader; + char szSaveDir[80]; + char McfFileheader[5]; + char szOutMsg[128]; + char szOutputFilename[100]; + UINT nNumFiles = 0; + PCHAR pszTemp; + DWORD dwCrc; // CRC OF FILE BEFORE COMPRESSION + UINT read; + CFile McfFile; + + // MAKE A COPY OF BUFFER SO THAT IT CAN BE MODIFIED + strcpy( szSaveDir, pszMcfFilename ); + + // SET BUFFER WITH NAME OF FILE WITHOUT A PATH OR EXTENSION + if( !(pszTemp = (PCHAR) strrchr( szSaveDir, '\\' )) ) + { + MessageBox( hWnd, "Error getting directory name", "Error", MB_OK ); + return 0; + } + + // POINT TO FIRST CHAR AFTER BACKSLASH + *(++pszTemp) = '\0'; + + TRY + { + // OPEN THE FILES + McfFile.Open( pszMcfFilename, CFile::modeRead | CFile::shareExclusive | CFile::typeBinary); + + memset( McfFileheader, 0, sizeof(McfFileheader) ); + + // MAKE SURE FILE IS A MULTIPLE COMPRESSED FILE + if( (McfFile.Read( McfFileheader, 4 ) != 4) || + (strcmp( McfFileheader, MCF_FILEHEADER ) != 0) ) + { + MessageBox( hWnd, "Invalid file format", "Error", MB_OK ); + return 0; + } + + do + { + // READ COMPRESSED FILE FILEHEADER + read = McfFile.Read( &FileHeader, sizeof(FileHeader) ); + + // IF SUCCESSFULLY READ COMPRESSED FILE FILEHEADER + if( read == sizeof(FileHeader) ) + { + // CREATE OUTPUT FILENAME + strcpy( szOutputFilename, szSaveDir ); + strcat( szOutputFilename, FileHeader.filename ); + + wsprintf( szOutMsg, "Uncompressing file: %s ", FileHeader.filename ); + pDC->TextOut( 10,60, szOutMsg ); + + // ATTEMPT TO EXPAND THE FILE + if( !ExpandFile( hWnd, pDC, &dwCrc, FileHeader.dwCompressSize, + &McfFile, szOutputFilename ) ) + { + wsprintf( szOutMsg, "Error Uncompressing file: %s", + szOutputFilename ); + MessageBox( hWnd, szOutMsg, "Error", MB_OK ); + return 0; + } + + // CHECK THE CRC OF THE FILE + if( dwCrc != FileHeader.dwCrc ) + { + wsprintf( szOutMsg, "There is an error in the CRC of %s", + szOutputFilename ); + MessageBox( hWnd, szOutMsg, "Error", MB_OK ); + } + + nNumFiles++; + } + } + while( read == sizeof(FileHeader) ); + + if( read != 0 ) + { + MessageBox( hWnd, "Invalid file format", "Error", MB_OK ); + return 0; + } + else + { + wsprintf( szOutMsg, "Uncompressed %u file(s)", nNumFiles ); + MessageBox( hWnd, szOutMsg, "MultFile", MB_OK ); + } + } + CATCH( CFileException, theException ) + { + if( theException->m_cause != CFileException::none ) + { + MessageBox( hWnd, "File Error", "Error", MB_OK ); + return 0; + } + } + END_CATCH + + return 1; +} + + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/DCL.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/DCL.H new file mode 100644 index 0000000..087d28b --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/DCL.H @@ -0,0 +1,13 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +int CompressFileToMCF( HWND hWnd, CDC *pDC, + LPSTR lpszMcfFile, LPSTR lpszFileToCompress, + LPSTR lpszFilenameOnly, BOOL NewMcfFile ); +int UncompressMcfFile( HWND hWnd, CDC *pDC, LPSTR lpszMcfFile ); diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/IMPLODE.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/IMPLODEI.LIB b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/IMPLODEI.LIB new file mode 100644 index 0000000..ca0b4df Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/IMPLODEI.LIB differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MAINFRM.CPP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MAINFRM.CPP new file mode 100644 index 0000000..547fe5d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MAINFRM.CPP @@ -0,0 +1,421 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +// mainfrm.cpp : implementation of the CMainFrame class +// + +#include "stdafx.h" +#include +#include "multfile.h" + +#include "mainfrm.h" +#include "dcl.h" +#include "multfdlg.h" +#include "implode.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +extern UINT DataType; // GLOBAL FOR DATA TYPE FOR COMPRESSION +extern UINT DictSize; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_QUERYENDSESSION() + ON_WM_CLOSE() + ON_COMMAND(IDM_COMPRESS_FILES, OnCompressFiles) + ON_COMMAND(IDM_UNCOMPRESS_FILES, OnUncompressFiles) + ON_UPDATE_COMMAND_UI(IDM_COMPRESS_FILES, OnUpdateCompressFiles) + ON_UPDATE_COMMAND_UI(IDM_UNCOMPRESS_FILES, OnUpdateUncompressFiles) + ON_COMMAND(IDM_CMP_ASCII, OnCmpAscii) + ON_COMMAND(IDM_CMP_BINARY, OnCmpBinary) + ON_COMMAND(IDM_DICT_SIZE_1024, OnDictSize1024) + ON_COMMAND(IDM_DICT_SIZE_2048, OnDictSize2048) + ON_COMMAND(IDM_DICT_SIZE_4096, OnDictSize4096) + ON_UPDATE_COMMAND_UI(IDM_CMP_ASCII, OnUpdateCmpAscii) + ON_UPDATE_COMMAND_UI(IDM_CMP_BINARY, OnUpdateCmpBinary) + ON_UPDATE_COMMAND_UI(IDM_DICT_SIZE_1024, OnUpdateDictSize1024) + ON_UPDATE_COMMAND_UI(IDM_DICT_SIZE_2048, OnUpdateDictSize2048) + ON_UPDATE_COMMAND_UI(IDM_DICT_SIZE_4096, OnUpdateDictSize4096) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// arrays of IDs used to initialize control bars + +// toolbar buttons - IDs are command buttons +static UINT BASED_CODE buttons[] = +{ + // same order as in the bitmap 'toolbar.bmp' + ID_FILE_NEW, + ID_FILE_OPEN, + ID_FILE_SAVE, + ID_SEPARATOR, + ID_EDIT_CUT, + ID_EDIT_COPY, + ID_EDIT_PASTE, + ID_SEPARATOR, + ID_FILE_PRINT, + ID_APP_ABOUT, +}; + +static UINT BASED_CODE indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + // TODO: add member initialization code here +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE("Failed to create status bar\n"); + return -1; // fail to create + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnCompressFiles() +{ + int rc; + HWND hWnd; + + // GET HANDLE TO WINDOW AND INSTANCE HANDLE + hWnd = CWnd::GetSafeHwnd(); + + // TURN OFF HELP MESSAGE SCREEN AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_OFF_HELP ); + + // CREATE FILE DIALOG THAT CAN USE CAN SELECT MULTIPLE FILES + CMultiSelFileDialog *FileDlg = new CMultiSelFileDialog( this ); + + // IF USER PRESSED OK BUTTON + if( (rc = FileDlg->DoModal()) == IDOK ) + { + // CREATE SAVE AS FILE DIALOG + CFileDialog SaveFileDlg( FALSE, "MCF", "*.MCF", + OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, + "Mult. Compressed Files (*.MCF) |*.MCF ||", this ); + + // GET FILENAME OF FILE TO PUT COMPRESSED FILES IN + if( (SaveFileDlg.DoModal()) == IDOK ) + { + BOOL GotFilenameOk, + bError = FALSE, + CreateMcfFile; + UINT nNumCmpFiles = 0; + char szFilename[13]; // BUFFER FOR FILENAME ONLY + char szFullPathname[128]; // BUFFER FOR FULL PATH FOR FILE + char szOutBuff[64]; // TEMP OUTPUT BUFFER + + // SET FLAG TO PREVENT EXITING IN THE MIDDLE OF THE COMPRESSION + ((CMultfileApp *) AfxGetApp())->OkToExit = FALSE; + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + CClientDC dc(this); + COLORREF bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + wsprintf( szOutBuff, "Compressing to: %s ", + (LPSTR) (const char *) SaveFileDlg.GetPathName() ); + dc.TextOut( 10,20, szOutBuff ); + + // SET CREATE .MCF FILE FLAG TO TRUE, SO THAT THE FIRST TIME + // CompressFileToMCF IS CALLED THE .MCF WILL BE CREATED INSTEAD + // OF APPENDED TO + CreateMcfFile = TRUE; + + // GET THE FIRST FILENAME IN THE LIST + GotFilenameOk = FileDlg->GetFirstFilename( szFullPathname, + sizeof(szFullPathname), + szFilename ); + // WHILE GOT A FILENAME FROM THE LIST + while( GotFilenameOk ) + { + // COMPRESS THE FILE AND ADD IT TO THE .MCF FILE + if( !CompressFileToMCF( hWnd, &dc, + (LPSTR) (const char *) SaveFileDlg.GetPathName(), + szFullPathname, szFilename, CreateMcfFile ) ) + { + // ERROR OCCURRED SO DELETE THE .MCF FILE + remove( (const char *) SaveFileDlg.GetPathName() ); + bError = TRUE; + break; + } + // INCREMENT TOTAL + nNumCmpFiles++; + + // RESET .MCF FILE FLAG SO THAT .MCF FILE WILL NOT BE CREATED + CreateMcfFile = FALSE; + + // GET THE FIRST FILENAME IN THE LIST + GotFilenameOk = FileDlg->GetNextFilename( szFullPathname, + sizeof(szFullPathname), + szFilename ); + } + + // IF THERE WAS NOT ERROR, THEN DISPLAY MESSAGE + if( !bError ) + { + wsprintf( szOutBuff, "Compressed %u file(s)", nNumCmpFiles ); + MessageBox( szOutBuff ); + } + + // DONE WITH COMPRESION SO ALLOW THE USER TO EXIT + ((CMultfileApp *) AfxGetApp())->OkToExit = TRUE; + } + } + + // CLEAN-UP + delete FileDlg; + + // TURN ON HELP MESSAGE AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_ON_HELP ); +} + +void CMainFrame::OnUncompressFiles() +{ + HWND hWnd; + + hWnd = CWnd::GetSafeHwnd(); + + // TURN OFF HELP MESSAGE AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_OFF_HELP ); + + // OPENFILENAME + CFileDialog OpenFileDlg( TRUE, "MCF", "*.MCF", + OFN_HIDEREADONLY | OFN_NOCHANGEDIR, + "Mult. Compressed Files (*.MCF) |*.MCF ||", this ); + + // GET FILENAME OF FILE TO PUT COMPRESSED FILES IN + if( (OpenFileDlg.DoModal()) == IDOK ) + { + char szOutBuff[64]; // TEMP OUTPUT BUFFER + + // SET FLAG TO PREVENT EXITING IN THE MIDDLE OF THE UNCOMPRESSION + ((CMultfileApp *) AfxGetApp())->OkToExit = FALSE; + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + CClientDC dc(this); + COLORREF bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + wsprintf( szOutBuff, "Uncompressing: %s ", + (LPSTR) (const char *) OpenFileDlg.GetPathName() ); + dc.TextOut( 10,20, szOutBuff ); + + // UNCOMPRESS THE FILE + UncompressMcfFile( hWnd, &dc, (LPSTR) (const char *) OpenFileDlg.GetPathName() ); + + // DONE WITH UNCOMPRESION SO ALLOW THE USER TO EXIT + ((CMultfileApp *) AfxGetApp())->OkToExit = TRUE; + } + + // TURN ON HELP MESSAGE AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_ON_HELP ); +} + +BOOL CMainFrame::OnQueryEndSession() +{ + if (!CFrameWnd::OnQueryEndSession()) + return FALSE; + + // RETURN FALSE IF CANNOT EXIT RIGHT NOW + if( !((CMultfileApp *) AfxGetApp())->OkToExit ) + return FALSE; + + return TRUE; +} + +void CMainFrame::OnClose() +{ + // RETURN IF CANNOT EXIT RIGHT NOW + if( !((CMultfileApp *) AfxGetApp())->OkToExit ) + return; + + CFrameWnd::OnClose(); +} + +void CMainFrame::OnUpdateCompressFiles(CCmdUI* pCmdUI) +{ + pCmdUI->Enable( ((CMultfileApp *) AfxGetApp())->OkToExit ); +} + +void CMainFrame::OnUpdateUncompressFiles(CCmdUI* pCmdUI) +{ + pCmdUI->Enable( ((CMultfileApp *) AfxGetApp())->OkToExit ); +} + + +void CMainFrame::OnCmpAscii() +{ + DataType = CMP_ASCII; +} + +void CMainFrame::OnCmpBinary() +{ + DataType = CMP_BINARY; +} + +void CMainFrame::OnDictSize1024() +{ + DictSize = 1024; +} + +void CMainFrame::OnDictSize2048() +{ + DictSize = 2048; +} + +void CMainFrame::OnDictSize4096() +{ + DictSize = 4096; +} + +void CMainFrame::OnUpdateCmpAscii(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CMultfileApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DataType == CMP_ASCII ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateCmpBinary(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CMultfileApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DataType == CMP_BINARY ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateDictSize1024(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CMultfileApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DictSize == 1024 ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateDictSize2048(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CMultfileApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DictSize == 2048 ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateDictSize4096(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CMultfileApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DictSize == 4096 ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MAINFRM.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MAINFRM.H new file mode 100644 index 0000000..297fb13 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MAINFRM.H @@ -0,0 +1,61 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mainfrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + CMainFrame(); + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + +// Operations +public: + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnCompressFiles(); + afx_msg void OnUncompressFiles(); + afx_msg BOOL OnQueryEndSession(); + afx_msg void OnClose(); + afx_msg void OnUpdateCompressFiles(CCmdUI* pCmdUI); + afx_msg void OnUpdateUncompressFiles(CCmdUI* pCmdUI); + afx_msg void OnCmpAscii(); + afx_msg void OnCmpBinary(); + afx_msg void OnDictSize1024(); + afx_msg void OnDictSize2048(); + afx_msg void OnDictSize4096(); + afx_msg void OnUpdateCmpAscii(CCmdUI* pCmdUI); + afx_msg void OnUpdateCmpBinary(CCmdUI* pCmdUI); + afx_msg void OnUpdateDictSize1024(CCmdUI* pCmdUI); + afx_msg void OnUpdateDictSize2048(CCmdUI* pCmdUI); + afx_msg void OnUpdateDictSize4096(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDLG.CPP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDLG.CPP new file mode 100644 index 0000000..aff5eb3 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDLG.CPP @@ -0,0 +1,158 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include "stdafx.h" +#include + +#include "multfdlg.h" + +#define FILELIST_BUFFSIZE 4096 // AMOUNT OF MEMORY TO ALLOCATE FOR FILE LIST + + +CMultiSelFileDialog::CMultiSelFileDialog( CWnd *pParentWnd ) + :CFileDialog( TRUE, NULL, "*.*", + OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR, + "All Files (*.*) |*.* ||", pParentWnd ) +{ + // ALLOCATE MEMORY FOR FILE LIST + pszFileList = (PCHAR) new char[FILELIST_BUFFSIZE]; + + // SET ALLOCATED BUFFER AS FILENAME BUFER IN OPENFILENAME STRUCT + // AND REPLACE IT IN THE OPENFILENAME STRUCT + pszOldPtr = m_ofn.lpstrFile; + m_ofn.lpstrFile = pszFileList; + m_ofn.nMaxFile = FILELIST_BUFFSIZE; + + // DO SOME INITIALIZATION + memset( pszFileList, 0, FILELIST_BUFFSIZE ); + strcpy( pszFileList, "*.*" ); + memset( szPath, 0, sizeof(szPath) ); + nPathLen = 0; + Done = TRUE; +} + + +CMultiSelFileDialog::~CMultiSelFileDialog() +{ + // REPLACE OLD POINTER AND FREE MEMORY + m_ofn.lpstrFile = pszOldPtr; + delete pszFileList; +} + + +BOOL CMultiSelFileDialog::GetFirstFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ) +{ + PCHAR pszToken; + + nPathLen = 0; + Done = FALSE; + + // GET THE FIRST TOKEN WHICH SHOULD BE THE PATH + if( strchr( pszFileList, ' ' ) == NULL ) + { + // COULD NOT FIND TOKEN SO MUST BE PATH AND FILENAME + + Done = TRUE; + + memset( szPath, 0, sizeof(szPath) ); + nPathLen = 0; + + // MAKE SURE THE FILENAME + PATH WILL FIT + if( strlen( pszFileList ) > nPathBuffSize ) + { + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // CREATE FILENAME ONLY + strcpy( pszFilenameBuff, GetFileName() ); + strcat( pszFilenameBuff, "." ); + strcat( pszFilenameBuff, GetFileExt() ); + + // COPY PATH AND FILENAME TO BUFFER + strcpy( pszFullPathBuff, pszFileList ); + + return TRUE; + } + + // GET THE FIRST TOKEN WHICH SHOULD BE THE PATH + if( (pszToken = strtok( pszFileList, " " )) == NULL ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + memset( szPath, 0, sizeof(szPath) ); + strcpy( szPath, pszToken ); + strcat( szPath, "\\" ); + + nPathLen = strlen( szPath ); + + return GetNextFilename( pszFullPathBuff, nPathBuffSize, pszFilenameBuff ); +} + + +// pszFilenameBuff MUST BE AT LEAST 13 BYTES +BOOL CMultiSelFileDialog::GetNextFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ) +{ + PCHAR pszToken; + + if( Done ) + { + return FALSE; + } + + // GET THE NEXT TOKEN WHICH SHOULD BE A FILENAME + if( (pszToken = strtok( NULL, " " )) == NULL ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // MAKE SURE THE FILENAME + PATH WILL FIT + if( (strlen( pszToken ) + nPathLen) > nPathBuffSize ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // COPY PATH AND FILENAME TO BUFFER + strcpy( pszFullPathBuff, szPath ); + strcat( pszFullPathBuff, pszToken ); + + PCHAR pszNameOnly = strrchr( pszFullPathBuff, '\\' ); + + if( (pszNameOnly == NULL) || (strlen(pszNameOnly) > 13) ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + strcpy( pszFilenameBuff, ++pszNameOnly ); + + return TRUE; +} + + + + + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDLG.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDLG.H new file mode 100644 index 0000000..d9729e3 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDLG.H @@ -0,0 +1,30 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include + +class CMultiSelFileDialog : public CFileDialog +{ + private: + PCHAR pszFileList; + PCHAR pszOldPtr; + int nPathLen; + char szPath[80]; + BOOL Done; + + public: + CMultiSelFileDialog( CWnd *pParentWnd ); + ~CMultiSelFileDialog(); + BOOL GetFirstFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ); + BOOL GetNextFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ); +}; diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDOC.CPP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDOC.CPP new file mode 100644 index 0000000..f4fdf2b --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDOC.CPP @@ -0,0 +1,89 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +// multfdoc.cpp : implementation of the CMultfileDoc class +// + +#include "stdafx.h" +#include "multfile.h" + +#include "multfdoc.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMultfileDoc + +IMPLEMENT_DYNCREATE(CMultfileDoc, CDocument) + +BEGIN_MESSAGE_MAP(CMultfileDoc, CDocument) + //{{AFX_MSG_MAP(CMultfileDoc) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMultfileDoc construction/destruction + +CMultfileDoc::CMultfileDoc() +{ + // TODO: add one-time construction code here +} + +CMultfileDoc::~CMultfileDoc() +{ +} + +BOOL CMultfileDoc::OnNewDocument() +{ + if (!CDocument::OnNewDocument()) + return FALSE; + + // TODO: add reinitialization code here + // (SDI documents will reuse this document) + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMultfileDoc serialization + +void CMultfileDoc::Serialize(CArchive& ar) +{ + if (ar.IsStoring()) + { + // TODO: add storing code here + } + else + { + // TODO: add loading code here + } +} + +///////////////////////////////////////////////////////////////////////////// +// CMultfileDoc diagnostics + +#ifdef _DEBUG +void CMultfileDoc::AssertValid() const +{ + CDocument::AssertValid(); +} + +void CMultfileDoc::Dump(CDumpContext& dc) const +{ + CDocument::Dump(dc); +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMultfileDoc commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDOC.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDOC.H new file mode 100644 index 0000000..9fabd25 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFDOC.H @@ -0,0 +1,46 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +// multfdoc.h : interface of the CMultfileDoc class +// +///////////////////////////////////////////////////////////////////////////// + +class CMultfileDoc : public CDocument +{ +protected: // create from serialization only + CMultfileDoc(); + DECLARE_DYNCREATE(CMultfileDoc) + +// Attributes +public: +// Operations +public: + +// Implementation +public: + virtual ~CMultfileDoc(); + virtual void Serialize(CArchive& ar); // overridden for document i/o +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + virtual BOOL OnNewDocument(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMultfileDoc) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.CPP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.CPP new file mode 100644 index 0000000..201a332 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.CPP @@ -0,0 +1,140 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +// multfile.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "multfile.h" + +#include "mainfrm.h" +#include "multfdoc.h" +#include "multfvw.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMultfileApp + +BEGIN_MESSAGE_MAP(CMultfileApp, CWinApp) + //{{AFX_MSG_MAP(CMultfileApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMultfileApp construction + +CMultfileApp::CMultfileApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CMultfileApp object + +CMultfileApp NEAR theApp; + +///////////////////////////////////////////////////////////////////////////// +// CMultfileApp initialization + +BOOL CMultfileApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + OkToExit = TRUE; + + SetDialogBkColor(); // Set dialog background color to gray + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CSingleDocTemplate* pDocTemplate; + pDocTemplate = new CSingleDocTemplate( + IDR_MAINFRAME, + RUNTIME_CLASS(CMultfileDoc), + RUNTIME_CLASS(CMainFrame), // main SDI frame window + RUNTIME_CLASS(CMultfileView)); + AddDocTemplate(pDocTemplate); + + // create a new (empty) document + OnFileNew(); + + if (m_lpCmdLine[0] != '\0') + { + // TODO: add command line processing here + } + + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + +// Implementation +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CMultfileApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CMultfileApp commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.H new file mode 100644 index 0000000..aaf884d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.H @@ -0,0 +1,49 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +// multfile.h : main header file for the MULTFILE application +// + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +#define WM_TURN_OFF_HELP WM_USER+1 +#define WM_TURN_ON_HELP WM_USER+2 + +///////////////////////////////////////////////////////////////////////////// +// CMultfileApp: +// See multfile.cpp for the implementation of this class +// + +class CMultfileApp : public CWinApp +{ +public: + CMultfileApp(); + + BOOL OkToExit; + + +// Overrides + virtual BOOL InitInstance(); + +// Implementation + + //{{AFX_MSG(CMultfileApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.MAK b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.MAK new file mode 100644 index 0000000..651b52d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.MAK @@ -0,0 +1,300 @@ +# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE No configuration specified. Defaulting to Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "MULTFILE.MAK" CFG="Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Win32 Debug" +MTL=MkTypLib.exe +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Win32 Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/MULTFILE.exe $(OUTDIR)/MULTFILE.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE CPP /nologo /MD /W3 /GX /YX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"STDAFX.H" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MULTFILE.pch" /Yu"STDAFX.H" /Fo$(INTDIR)/ /c\ + +CPP_OBJS=.\WinRel/ +# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"MULTFILE.res" /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"MULTFILE.bsc" + +$(OUTDIR)/MULTFILE.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib pkwdcl.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /MACHINE:IX86 +# ADD LINK32 oldnames.lib implodei.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /INCREMENTAL:yes /MACHINE:IX86 +LINK32_FLAGS=oldnames.lib implodei.lib /NOLOGO /STACK:0x10240\ + /SUBSYSTEM:windows /INCREMENTAL:yes /PDB:$(OUTDIR)/"MULTFILE.pdb" /MACHINE:IX86\ + /OUT:$(OUTDIR)/"MULTFILE.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/MULTFILE.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/MULTFILE.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/MULTFDOC.OBJ \ + $(INTDIR)/MULTFVW.OBJ \ + $(INTDIR)/DCL.OBJ \ + $(INTDIR)/MULTFDLG.OBJ + +$(OUTDIR)/MULTFILE.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/MULTFILE.exe $(OUTDIR)/MULTFILE.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE CPP /nologo /MD /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"STDAFX.H" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MULTFILE.pch" /Yu"STDAFX.H" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"MULTFILE.pdb" /c +CPP_OBJS=.\WinDebug/ +# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"MULTFILE.res" /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"MULTFILE.bsc" + +$(OUTDIR)/MULTFILE.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib pkwdcl.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /DEBUG /MACHINE:IX86 +# ADD LINK32 oldnames.lib implodei.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /DEBUG /MACHINE:IX86 +# SUBTRACT LINK32 /INCREMENTAL:no +LINK32_FLAGS=oldnames.lib implodei.lib /NOLOGO /STACK:0x10240\ + /SUBSYSTEM:windows /INCREMENTAL:yes /PDB:$(OUTDIR)/"MULTFILE.pdb" /DEBUG\ + /MACHINE:IX86 /OUT:$(OUTDIR)/"MULTFILE.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/MULTFILE.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/MULTFILE.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/MULTFDOC.OBJ \ + $(INTDIR)/MULTFVW.OBJ \ + $(INTDIR)/DCL.OBJ \ + $(INTDIR)/MULTFDLG.OBJ + +$(OUTDIR)/MULTFILE.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Group "Source Files" + +################################################################################ +# Begin Source File + +SOURCE=.\MULTFILE.RC +DEP_MULTF=\ + .\RES\MULTFILE.ICO\ + .\RES\TOOLBAR.BMP\ + .\resource.h\ + .\res\multfile.rc2 + +$(INTDIR)/MULTFILE.res : $(SOURCE) $(DEP_MULTF) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\STDAFX.CPP +DEP_STDAF=\ + .\stdafx.h + +!IF "$(CFG)" == "Win32 Release" + +# ADD BASE CPP /Yc"STDAFX.H" +# ADD CPP /Yc"STDAFX.H" + +$(INTDIR)/STDAFX.OBJ : $(SOURCE) $(DEP_STDAF) $(INTDIR) + $(CPP) /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MULTFILE.pch" /Yc"STDAFX.H" /Fo$(INTDIR)/ /c\ + $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# ADD BASE CPP /Yc"STDAFX.H" +# ADD CPP /Yc"STDAFX.H" + +$(INTDIR)/STDAFX.OBJ : $(SOURCE) $(DEP_STDAF) $(INTDIR) + $(CPP) /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"MULTFILE.pch" /Yc"STDAFX.H" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"MULTFILE.pdb" /c $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MULTFILE.CPP +DEP_MULTFI=\ + .\stdafx.h\ + .\multfile.h\ + .\mainfrm.h\ + .\multfdoc.h\ + .\multfvw.h\ + .\resource.h + +$(INTDIR)/MULTFILE.OBJ : $(SOURCE) $(DEP_MULTFI) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MAINFRM.CPP +DEP_MAINF=\ + .\stdafx.h\ + .\multfile.h\ + .\mainfrm.h\ + .\dcl.h\ + .\multfdlg.h\ + .\implode.h\ + .\resource.h + +$(INTDIR)/MAINFRM.OBJ : $(SOURCE) $(DEP_MAINF) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MULTFDOC.CPP +DEP_MULTFD=\ + .\stdafx.h\ + .\multfile.h\ + .\multfdoc.h\ + .\resource.h + +$(INTDIR)/MULTFDOC.OBJ : $(SOURCE) $(DEP_MULTFD) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MULTFVW.CPP +DEP_MULTFV=\ + .\stdafx.h\ + .\multfile.h\ + .\multfdoc.h\ + .\multfvw.h\ + .\resource.h + +$(INTDIR)/MULTFVW.OBJ : $(SOURCE) $(DEP_MULTFV) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DCL.CPP +DEP_DCL_C=\ + .\stdafx.h\ + .\implode.h + +$(INTDIR)/DCL.OBJ : $(SOURCE) $(DEP_DCL_C) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MULTFDLG.CPP +DEP_MULTFDL=\ + .\stdafx.h\ + .\multfdlg.h + +$(INTDIR)/MULTFDLG.OBJ : $(SOURCE) $(DEP_MULTFDL) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +# End Group +# End Project +################################################################################ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.RC b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.RC new file mode 100644 index 0000000..9d63d34 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFILE.RC @@ -0,0 +1,195 @@ +//Microsoft App Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#ifdef APSTUDIO_INVOKED +////////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""res\\multfile.rc2"" // non-App Studio edited resources\r\n" + "\r\n" + "#include ""afxres.rc"" \011// Standard components\r\n" + "\0" +END + +///////////////////////////////////////////////////////////////////////////////////// +#endif // APSTUDIO_INVOKED + + +////////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +IDR_MAINFRAME ICON DISCARDABLE "RES\\MULTFILE.ICO" + +////////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINFRAME BITMAP MOVEABLE PURE "RES\\TOOLBAR.BMP" + +////////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU PRELOAD DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Compress Files", IDM_COMPRESS_FILES + MENUITEM "&Uncompress Files", IDM_UNCOMPRESS_FILES + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "&Options" + BEGIN + MENUITEM "&ASCII", IDM_CMP_ASCII + MENUITEM "&Binary", IDM_CMP_BINARY + MENUITEM SEPARATOR + MENUITEM "&1024", IDM_DICT_SIZE_1024 + MENUITEM "&2048", IDM_DICT_SIZE_2048 + MENUITEM "&4096", IDM_DICT_SIZE_4096 + END + POPUP "&View" + BEGIN + MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR + END + POPUP "&Help" + BEGIN + MENUITEM "&About Multfile...", ID_APP_ABOUT + END +END + + +////////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 34, 22, 217, 55 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Multfile" +FONT 8, "MS Sans Serif" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20 + LTEXT "Multfile Application Version 1.0",IDC_STATIC,40,10,119, + 8 + LTEXT "Copyright \251 1995",IDC_STATIC,40,25,119,8 + DEFPUSHBUTTON "OK",IDOK,176,6,32,14,WS_GROUP +END + + +////////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + IDR_MAINFRAME "Multfile (DLL Version)\n\nMultfile Document\n\n\nMultfile.Document\nMultfile Document" +END + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + AFX_IDS_APP_TITLE "Multfile Windows Application" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_INDICATOR_EXT "EXT" + ID_INDICATOR_CAPS "CAP" + ID_INDICATOR_NUM "NUM" + ID_INDICATOR_SCRL "SCRL" + ID_INDICATOR_OVR "OVR" + ID_INDICATOR_REC "REC" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright" + ID_APP_EXIT "Quit the application; prompts to save documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane" + ID_PREV_PANE "Switch back to the previous window pane" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_VIEW_TOOLBAR "Show or hide the toolbar" + ID_VIEW_STATUS_BAR "Show or hide the status bar" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDM_CHOOSE_FILES "Select files to test Data Compression Library" + IDM_COMPRESS_FILES "Demo of compressing one or more files" + IDM_UNCOMPRESS_FILES "Demo of uncompressing a file created by 'Compress Files'" + IDM_CMP_BINARY "Set data type as binary" + IDM_CMP_ASCII "Set data type as text" + IDM_DICT_SIZE_1024 "Set dictionary size to 1024 bytes" + IDM_DICT_SIZE_2048 "Set dictionary size to 2048 bytes" + IDM_DICT_SIZE_4096 "Set dictionary size to 4096 bytes" +END + + +#ifndef APSTUDIO_INVOKED +//////////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "res\multfile.rc2" // non-App Studio edited resources + +#include "afxres.rc" // Standard components + +///////////////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFVW.CPP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFVW.CPP new file mode 100644 index 0000000..8f290ec --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFVW.CPP @@ -0,0 +1,121 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +// multfvw.cpp : implementation of the CMultfileView class +// + +#include "stdafx.h" +#include "multfile.h" + +#include "multfdoc.h" +#include "multfvw.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + + +char szHelpMsg[] = { + "To compress multiple files: Select Compress Files from the File " + "menu, and use the shift and control keys with the mouse to " + "highlight multiple files. Press Ok after selecting the files. " + "Enter the path and name of file to compress the selected files " + "to.\n\n" + "To uncompress a file: Select Uncompress Files from the File menu, " + "and enter or select the file to uncompress, then press the Ok " + "button. The files will be uncompressed in the same directory." }; + + +///////////////////////////////////////////////////////////////////////////// +// CMultfileView + +IMPLEMENT_DYNCREATE(CMultfileView, CView) + +BEGIN_MESSAGE_MAP(CMultfileView, CView) + //{{AFX_MSG_MAP(CMultfileView) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + ON_MESSAGE( WM_TURN_OFF_HELP, OnTurnOffHelp ) + ON_MESSAGE( WM_TURN_ON_HELP, OnTurnOnHelp ) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMultfileView construction/destruction + +CMultfileView::CMultfileView() +{ + bDisplayHelp = TRUE; +} + +CMultfileView::~CMultfileView() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// CMultfileView drawing + +void CMultfileView::OnDraw(CDC* pDC) +{ + CMultfileDoc* pDoc = GetDocument(); + ASSERT_VALID(pDoc); + + // TODO: add draw code for native data here + if( bDisplayHelp ) + { + RECT rect; + + pDC->SetBkMode( TRANSPARENT ); + GetClientRect( &rect ); + pDC->DrawText( szHelpMsg, -1, &rect, DT_LEFT | DT_WORDBREAK ); + } +} + +///////////////////////////////////////////////////////////////////////////// +// CMultfileView diagnostics + +#ifdef _DEBUG +void CMultfileView::AssertValid() const +{ + CView::AssertValid(); +} + +void CMultfileView::Dump(CDumpContext& dc) const +{ + CView::Dump(dc); +} + +CMultfileDoc* CMultfileView::GetDocument() // non-debug version is inline +{ + ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMultfileDoc))); + return (CMultfileDoc*)m_pDocument; +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMultfileView message handlers + +LRESULT CMultfileView::OnTurnOffHelp( WPARAM wParam, LPARAM lParam ) +{ + bDisplayHelp = FALSE; + InvalidateRect( NULL, TRUE ); + + return 0; +} + +LRESULT CMultfileView::OnTurnOnHelp( WPARAM wParam, LPARAM lParam ) +{ + bDisplayHelp = TRUE; + InvalidateRect( NULL, TRUE ); + + return 0; +} + + diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFVW.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFVW.H new file mode 100644 index 0000000..374c3b7 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/MULTFVW.H @@ -0,0 +1,57 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +// multfvw.h : interface of the CMultfileView class +// +///////////////////////////////////////////////////////////////////////////// + +class CMultfileView : public CView +{ +private: + BOOL bDisplayHelp; + +protected: // create from serialization only + CMultfileView(); + DECLARE_DYNCREATE(CMultfileView) + +// Attributes +public: + CMultfileDoc* GetDocument(); + +// Operations +public: + +// Implementation +public: + virtual ~CMultfileView(); + virtual void OnDraw(CDC* pDC); // overridden to draw this view + afx_msg LRESULT OnTurnOffHelp( WPARAM wParam, LPARAM lParam ); + afx_msg LRESULT OnTurnOnHelp( WPARAM wParam, LPARAM lParam ); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + +// Generated message map functions +protected: + //{{AFX_MSG(CMultfileView) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#ifndef _DEBUG // debug version in multfvw.cpp +inline CMultfileDoc* CMultfileView::GetDocument() + { return (CMultfileDoc*)m_pDocument; } +#endif + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/MULTFILE.ICO b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/MULTFILE.ICO new file mode 100644 index 0000000..b718392 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/MULTFILE.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/MULTFILE.RC2 b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/MULTFILE.RC2 new file mode 100644 index 0000000..169e748 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/MULTFILE.RC2 @@ -0,0 +1,52 @@ +// +// MULTFILE.RC2 - resources App Studio does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by App Studio +#endif //APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// Version stamp for this .EXE + +#include "ver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG|VS_FF_PRIVATEBUILD|VS_FF_PRERELEASE +#else + FILEFLAGS 0 // final version +#endif + FILEOS VOS_DOS_WINDOWS16 + FILETYPE VFT_APP + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "MULTFILE MFC Application\0" + VALUE "FileVersion", "1.0.001\0" + VALUE "InternalName", "MULTFILE\0" + VALUE "LegalCopyright", "\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename","MULTFILE.EXE\0" + VALUE "ProductName", "MULTFILE\0" + VALUE "ProductVersion", "1.0.001\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + // English language (0x409) and the Windows ANSI codepage (1252) + END +END + +///////////////////////////////////////////////////////////////////////////// +// Add additional manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/TOOLBAR.BMP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/TOOLBAR.BMP new file mode 100644 index 0000000..49695e2 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RES/TOOLBAR.BMP differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RESOURCE.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RESOURCE.H new file mode 100644 index 0000000..7ddf0f9 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/RESOURCE.H @@ -0,0 +1,34 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +//{{NO_DEPENDENCIES}} +// App Studio generated include file. +// Used by MULTFILE.RC +// +#define IDR_MAINFRAME 2 +#define IDD_ABOUTBOX 100 +#define IDM_CHOOSE_FILES 32771 +#define IDM_COMPRESS_FILES 32772 +#define IDM_UNCOMPRESS_FILES 32773 +#define IDM_CMP_BINARY 32774 +#define IDM_CMP_ASCII 32775 +#define IDM_DICT_SIZE_1024 32777 +#define IDM_DICT_SIZE_2048 32778 +#define IDM_DICT_SIZE_4096 32779 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 32780 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/STDAFX.CPP b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/STDAFX.CPP new file mode 100644 index 0000000..07f7b46 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/STDAFX.CPP @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// stdafx.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/STDAFX.H b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/STDAFX.H new file mode 100644 index 0000000..6179a32 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/MULTFILE/STDAFX.H @@ -0,0 +1,7 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#include // MFC core and standard components +#include // MFC extensions (including VB) diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/DCL.CPP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/DCL.CPP new file mode 100644 index 0000000..fff2f7f --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/DCL.CPP @@ -0,0 +1,889 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +/* + * DCL.cpp - File to call various DCL DLL functions + */ + +#include "stdafx.h" + +#include + +#include +#include +#include + +#include "implode.h" + +#define TEMPFILENAME "~~~.$$$" // TEMPORARY FILENAME TO CREATE +#define APPENDBUFSIZE 32000 // SIZE OF BUFFER TO ALLOCATE FOR APPENDING + // A COMPRESSED FILE TO .MCF FILE + +typedef enum +{ + COMPRESSING = 1, + UNCOMPRESSING +} FILEMODE; + + +// STRUCT TO PASS TO THE FILE IO FUNCTIONS +typedef struct +{ + CFile *InFile; + CFile *OutFile; + CDC *pDC; + BYTE nPrevNdx; + BYTE nCnt; + DWORD dwCompressSize; + FILEMODE mode; + DWORD dwCrc; +} IOFILEBLOCK, *PIOFILEBLOCK; + +// FOUR LETTER IDENTIFIER TO IDENTIFY A FILE AS +// A .MCF (MULTIPLE COMPRESSED FILES) FILE +char MCF_FILEHEADER[] = { "MCFX" }; + +#pragma pack(2) +// HEADER FOR EACH FILE COMPRESSED INTO THE .MCF FILE +typedef struct +{ + DWORD dwCompressSize; // SIZE OF FILE COMPRESSED + DWORD dwCrc; // THE CRC OF THE FILE BEFORE COMPRESSION + char filename[13]; // NAME OF THE FILE +}CMP_FILEHEADER, *PCMP_FILEHEADER; +#pragma pack(8) + +/* + * FORMAT OF .MCF FILE: + * + * .MCF FILEHEADER => MCFX + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * AND SO ON + * + */ + +static char *pszActiveString[] = { "|", "/", "-", "\\" }; + +UINT DataType = CMP_ASCII; // GLOBAL FOR DATA TYPE FOR COMPRESSION +UINT DictSize = 4096; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +static PCHAR pszFilename; // NAME OF THE .MCF FILE + +/********************************************************************* + * + * Function: ProcessMessages() + * + * Purpose: To allow Windows to process window messages which + * allows the user to multitask will compressing and + * uncompressing files. + * + * Returns: Nothing + * + *********************************************************************/ +void ProcessMessages(void) +{ + MSG msg; + + while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { + if (msg.message == WM_QUIT) + return; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + + +/********************************************************************* + * + * Function: ReadFromDisk() + * + * Purpose: To read data from disk, and prompt user for another + * disk when needed. This function makes a large assumption + * that if when reading a header zero bytes are read, then + * EOF has been reached. + * + * Parameters: Infile -> Pointer to already opened .MCF file + * pBuffer -> input buffer + * nSize -> number of bytes to read + * numread -> pointer to return actual number of bytes read + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred (A FileException is thrown) + * + *********************************************************************/ +int ReadFromDisk( CFile *InFile, PCHAR pBuffer, UINT nSize, UINT *numread, + BOOL ReadingHeader ) +{ + UINT bytesread; + + // READ DATA FROM DISK + *numread = bytesread = InFile->Read( pBuffer, nSize ); + + // IF READING A HEADER AND READ 0 BYTES, THEN ASSUME THIS IS THE END + if( bytesread == 0 && ReadingHeader ) + { + return 1; + } + + // IF COULD NOT READ ALL BYTES + if( bytesread < nSize ) + { + // CALCULATE NUMBER OF BYTES TO READ + nSize -= bytesread; + + // CLOSE THE FILE + InFile->Close(); + + // PROMPT USER FOR ANOTHER DISK + MessageBox( NULL, "Insert Next Disk", "Uncompress", MB_OK ); + + // OPEN .MCF FILE ON NEW DISK + if( !InFile->Open( pszFilename, + CFile::modeRead | CFile::shareExclusive | CFile::typeBinary ) ) + { + AfxThrowFileException( CFileException::fileNotFound ); + return 0; + } + + // READ DATA FROM DISK + bytesread = InFile->Read( (pBuffer + bytesread), nSize ); + + *numread += bytesread; + } + + return 1; +} + + +/********************************************************************* + * + * Function: ProcessInBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * read requests. If compressing, then the data read is + * in uncompressed form. If compressing, then the data + * read is data that was previously compressed. This + * function is called until zero is returned. + * + * Parameters: buffer -> Address of buffer to read the data into + * iSize -> Number of bytes to read into buffer + * dwParam -> User-defined parameter, in this case a + * pointer to the IOFILEBLOCK + * + * Returns: Number of bytes actually read, or zero on EOF + * + *********************************************************************/ +UINT ProcessInBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + PIOFILEBLOCK pFileIOBlock; + UINT iRead; + UINT ndx; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + // DISPLAY ROTATING LINE + ndx = (pFileIOBlock->nCnt >> 4) & 3; + if( ndx != pFileIOBlock->nPrevNdx ) + { + pFileIOBlock->pDC->TextOut( 10,2, pszActiveString[ndx] ); + pFileIOBlock->nPrevNdx = ndx; + } + pFileIOBlock->nCnt++; + + // THIS FUNCTION MAY ASK FOR UP TO 4K OF DATA AT A TIME. IF YOUR + // ARCHIVE FILE CONTAINS SEVERAL COMPRESSED FILES, YOU MAY READ TOO + // MUCH. FOR EXAMPLE, YOUR FIRST COMPRESSED FILE IN THE ARCHIVE MAY + // BE 100 BYTES. SO YOU DO NOT WANT TO READ MORE THAN 100 BYTES OR + // YOU WILL BE UNABLE TO UNCOMPRESS THE SECOND FILE, SINCE YOU WILL + // NOT BE LOCATED AT THE BEGINNING OF THE FILE ANY LONGER. + // WE WILL USE THE VARIABLE "dwCompressSize" TO CHECK FOR THIS + // CONDITION. + if( pFileIOBlock->mode == UNCOMPRESSING ) + { + // IF DCL REQUESTED MORE BYTES THAN ARE LEFT IN COMPRESSED FILE, THEN + // SET THE NUMBER OF BYTES TO READ TO THE AMOUNT LEFT IN THE BUFFER + if( (DWORD)*iSize > pFileIOBlock->dwCompressSize ) + *iSize = (UINT) pFileIOBlock->dwCompressSize; + + pFileIOBlock->dwCompressSize -= (DWORD) *iSize; + + // READ COMPRESSED FILE FILEHEADER + if( !ReadFromDisk( pFileIOBlock->InFile, buffer, *iSize, &iRead, FALSE ) ) + { + return 0; + } + } + else + { + // READ BUFFER FROM DISK + iRead = (UINT)pFileIOBlock->InFile->Read( buffer, *iSize ); + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if( pFileIOBlock->mode == COMPRESSING ) + { + pFileIOBlock->dwCrc = crc32( buffer, &iRead, &pFileIOBlock->dwCrc ); + } + + // ENTER MESSAGE LOOP TO PROCESS BACKGROUND MESSAGES + // AND SIMULATE MULTITASKING + ProcessMessages(); + + return iRead; +} + +/********************************************************************* + * + * Function: ProcessOutBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * write requests. + * + * Parameters: buffer -> Address of buffer to write data from + * iSize -> Number of bytes to write + * dwParam -> User-defined parameter, in this case a + * pointer to the IOFILEBLOCK + * + * Returns: Zero, the return value is not used by the Data + * Compression Library + * + *********************************************************************/ +void ProcessOutBuffer(PCHAR buffer, UINT *iSize, void *pParam) +{ + PIOFILEBLOCK pFileIOBlock; + UINT ndx; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + // DISPLAY ROTATING LINE PACIFIER + ndx = (pFileIOBlock->nCnt >> 4) & 3; + if( ndx != pFileIOBlock->nPrevNdx ) + { + pFileIOBlock->pDC->TextOut( 10,2, pszActiveString[ndx] ); + pFileIOBlock->nPrevNdx = ndx; + } + pFileIOBlock->nCnt++; + + // WRITE BUFFER TO DISK + pFileIOBlock->OutFile->Write(buffer, *iSize); + + // IF COMPRESSING, THEN KEEP A TOTAL OF THE COMPRESSED FILE SIZE + if (pFileIOBlock->mode == COMPRESSING ) + { + pFileIOBlock->dwCompressSize += (DWORD) *iSize; + } + else // ELSE UNCOMPRESSING, SO CALCULATE CRC ON THE UNCOMPRESSED DATA + { + pFileIOBlock->dwCrc = crc32(buffer, iSize, &pFileIOBlock->dwCrc); + } + + // ENTER MESSAGE LOOP TO PROCESS BACKGROUND MESSAGES + // AND SIMULATE MULTITASKING + ProcessMessages(); + + return; +} + +/********************************************************************* + * + * Function: CompressFile() + * + * Purpose: To compress file to a separate temporary file. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * pdwCompFileSize -> Pointer to DWORD buffer to return + * the size of the compressed file + * pszFileToCompress -> Name of file to compress + * OutputFile -> Name of file to write compressed data to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressFile( HWND hWnd, CDC *pDC, DWORD *pdwCrc, DWORD *pdwCompFileSize, + PCHAR pszFileToCompress, PCHAR OutputFile ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + IOFILEBLOCK FileIOBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + // OPEN THE INPUT AND OUTPUT FILES + FileIOBlock.InFile = new CFile; + FileIOBlock.OutFile = new CFile; + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + FileIOBlock.mode = COMPRESSING; + FileIOBlock.dwCompressSize = 0; + FileIOBlock.pDC = pDC; + FileIOBlock.nCnt = 0; + FileIOBlock.nPrevNdx = 0; + FileIOBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + pDC->TextOut( 10,2, " " ); + + // OPEN THE FILES + if (FileIOBlock.InFile->Open( pszFileToCompress, CFile::modeRead | CFile::shareExclusive | CFile::typeBinary) && + FileIOBlock.OutFile->Open( OutputFile, CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary)) + { + wsprintf( szVerbose, "Compressing file: %s ", pszFileToCompress ); + pDC->TextOut( 10,40, szVerbose ); + + // ONLY COMPRESS IF FILE IS NOT A ZERO LENGTH FILE + if( FileIOBlock.InFile->GetLength() ) + { + // COMPRESS THE FILE + iStatus = implode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, &FileIOBlock, + &DataType, &DictSize ); + } + else + { + // SINCE THIS IS A ZERO LENGTH FILE, THERE IS NOTHING TO COMPRESS + // SET STATUS TO NO ERROR + iStatus = 0; + } + + // IF THERE WAS AN ERROR COMPRESSING FILE + if( iStatus ) + { + // DISPLAY ERROR STRING FROM DLL + wsprintf( szVerbose, "Error occurred while imploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - COMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + FileIOBlock.dwCrc = ~FileIOBlock.dwCrc; + + // RETURN CRC + *pdwCrc = FileIOBlock.dwCrc; + + // RETURN COMPRESSED FILE SIZE + *pdwCompFileSize = FileIOBlock.dwCompressSize; + } + + FileIOBlock.OutFile->Close(); + FileIOBlock.InFile->Close(); + } + else // ELSE - ERROR OPENING FILES + { + MessageBox( hWnd, "Error opening files for compression", "Error", MB_OK ); + rc = 0; + } + + // CLEAN-UP + delete FileIOBlock.InFile; + delete FileIOBlock.OutFile; + + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: ExpandFile() + * + * Purpose: To uncompress file from a .MCF file. The .MCF file will + * have been read upto the compressed data stream. + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * dwCompFileSize -> Size of the compressed file + * pMcfFile -> Pointer to already opened .MCF file + * OutputFile -> Name of file to write uncompressed data to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int ExpandFile( HWND hWnd, CDC *pDC, DWORD *pdwCrc, DWORD dwCompFileSize, + CFile *pMcfFile, PCHAR OutputFile ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + IOFILEBLOCK FileIOBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + FileIOBlock.InFile = pMcfFile; + FileIOBlock.OutFile = new CFile; + + // SETUP STRUCTURE USED BY ProcessReadBuffer() and ProcessWriteBuffer() + FileIOBlock.mode = UNCOMPRESSING; + FileIOBlock.dwCompressSize = dwCompFileSize; + FileIOBlock.pDC = pDC; + FileIOBlock.nCnt = 0; + FileIOBlock.nPrevNdx = 0; + FileIOBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + pDC->TextOut( 10,2, " " ); + + if( FileIOBlock.OutFile->Open(OutputFile, CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary) ) + { + // ONLY UNCOMPRESS IF FILE IS NOT A ZERO LENGTH FILE + if( FileIOBlock.dwCompressSize ) + { + // UNCOMPRESS FILE + iStatus = explode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, &FileIOBlock ); + } + else + { + // SINCE THIS IS A ZERO LENGTH FILE, THERE IS NOTHING TO UNCOMPRESS + // SET STATUS TO NO ERROR + iStatus = 0; + } + + if( iStatus ) + { + wsprintf( szVerbose, "Error occurred while exploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else + { + FileIOBlock.dwCrc = ~FileIOBlock.dwCrc; + *pdwCrc = FileIOBlock.dwCrc; + + if( FileIOBlock.dwCompressSize != 0 ) + { + wsprintf( szVerbose, "Error uncompressing file: %s", OutputFile ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + } + + FileIOBlock.OutFile->Close(); + } + else + { + MessageBox( hWnd, "Error opening files for uncompression", "Error", MB_OK ); + rc = 0; + } + + delete FileIOBlock.OutFile; + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: AmountDriveSpaceFree() + * + * Purpose: To calculate the number of bytes free on drive + * + * Parameters: drivenum -> Drive to check (A=1, B=2, ...) + * pdwBytesFree -> DWORD to return number of bytes free + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int AmountDriveSpaceFree( UINT drivenum, DWORD *pdwBytesFree ) +{ + static char RootStr[] = { "?:\\" }; + DWORD SectorsPerCluster, + BytesPerSector, + FreeClusters, + Clusters; + + *RootStr = 'A' + drivenum - 1; + + if( GetDiskFreeSpace( RootStr, &SectorsPerCluster, &BytesPerSector, + &FreeClusters, &Clusters ) == FALSE ) + { + return 0; + } + + *pdwBytesFree = SectorsPerCluster * BytesPerSector * FreeClusters; + + return 1; +} + + +/********************************************************************* + * + * Function: WriteToDisk() + * + * Purpose: To write data to disk, and prompt user for another + * disk when full. + * + * Parameters: OutFile -> Pointer to already opened file + * pBuffer -> output buffer + * nSize -> number of bytes to write + * pdwBytesFree -> number of bytes left on disk + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred (A FileException is thrown) + * + *********************************************************************/ +int WriteToDisk( CFile *OutFile, PCHAR pBuffer, UINT nSize, DWORD *pdwBytesFree ) +{ + UINT drivenum; + + // IF THERE IS SPACE TO WRITE FILE + if( (ULONG)nSize <= (ULONG)*pdwBytesFree ) + { + OutFile->Write( pBuffer, nSize ); + *pdwBytesFree -= nSize; + } + else // ELSE - NOT ENOUGH SPACE TO WRITE FILE + { + // FILL UP REMAINING DISKSPACE IF ANY + if( *pdwBytesFree > 0 ) + { + OutFile->Write( pBuffer, (UINT) *pdwBytesFree ); + nSize -= (UINT) *pdwBytesFree; + OutFile->Close(); + } + + drivenum = *pszFilename - 'A' + 1; + + // IF ON A FIXED DRIVE, THEN GIVE DISKFULL ERROR + if( drivenum > 2 ) + { + AfxThrowFileException( CFileException::diskFull ); + return 0; + } + + UINT nBytesRead = (UINT) *pdwBytesFree; + + // PROMPT USER FOR ANOTHER DISK + MessageBox( NULL, "Insert Another Disk", "Compress", MB_OK ); + + // GET NUMBER OF BYTES FREE ON DISK + if( !AmountDriveSpaceFree( drivenum, pdwBytesFree ) ) + { + AfxThrowFileException( CFileException::diskFull ); + return 0; + } + + // CREATE NEW .MCF FILE + OutFile->Open( pszFilename, CFile::modeCreate | CFile::modeWrite | CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary ); + + // WRITE REMAINING BYTES + OutFile->Write( (pBuffer + nBytesRead), nSize ); + *pdwBytesFree -= nSize; + } + + return 1; +} + + +/********************************************************************* + * + * Function: AddFileToMcfFile() + * + * Purpose: To add a compressed file with header to a .MCF file. + * The file header is written followed by the compressed + * file data + * + * Parameters: pFileHeader -> File header for the compressed file + * pszInput -> Filename of the compressed file's data + * pszOutput -> Filename of .MCF file + * CompressedFileSize -> Size of the compressed file + * NewMcfFile -> Flag used to create a new .MCF file + * TRUE - A new .MCF file will be created + * FALSE - The .MCF file will appended to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int AddFileToMcfFile( PCMP_FILEHEADER pFileHeader, PCHAR pszInput, + DWORD CompressedFileSize, BOOL NewMcfFile ) +{ + PCHAR buf; + UINT read; + CFile InFile; + CFile OutFile; + UINT drivenum; + DWORD BytesFree; + + // ALLOCATE I/O BUFFER + if( (buf = new char[APPENDBUFSIZE]) == NULL ) + { + return 0; + } + + drivenum = *pszFilename - 'A' + 1; + + // GET NUMBER OF BYTES FREE ON DISK + if( !AmountDriveSpaceFree( drivenum, &BytesFree ) ) + { + delete buf; + return 0; + } + + TRY + { + // OPEN THE FILES + InFile.Open( pszInput, CFile::modeRead | CFile::shareExclusive | CFile::typeBinary); + + // IF NEW FILE, THEN CREATE MULTIPLE COMPRESSED FILES FILE + if( NewMcfFile ) + { + // CREATE NEW .MCF FILE + OutFile.Open( pszFilename, CFile::modeCreate | CFile::modeWrite | CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary); + + // WRITE .MCF FILE HEADER + WriteToDisk( &OutFile, MCF_FILEHEADER, 4, &BytesFree ); + } + else + { + // OPEN OLD .MCF FILE + OutFile.Open( pszFilename, CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary); + + // GO TO END OF FILE + OutFile.SeekToEnd(); + } + + // WRITE THE COMPRESSED FILE'S FILEHEADER + OutFile.Write( pFileHeader, sizeof(CMP_FILEHEADER) ); + + do + { + // READ FROM COMPRESSED FILE + read = InFile.Read( buf, APPENDBUFSIZE ); + + // WRITE DATA TO .MCF FILE + WriteToDisk( &OutFile, buf, read, &BytesFree ); + + // IF ERROR OCCURRED + if( CompressedFileSize < (DWORD) read ) + { + delete buf; + return 0; + } + + CompressedFileSize -= (DWORD) read; + } + while( CompressedFileSize > 0 ); + } + CATCH( CFileException, theException ) + { + // IF ERROR OCCURRED WHILE APPENDING FILE + if( theException->m_cause != CFileException::none ) + { + delete buf; + return 0; + } + } + END_CATCH + + delete buf; + + return 1; +} + +/********************************************************************* + * + * Function: CompressFileToMCF() + * + * Purpose: To compress a file then add it to a .MCF file + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszMcfFile -> Filename of .MCF file + * pszFileToCompress -> Filename of file with full path + * pszFilenameOnly -> Filename of file without any path + * This is the filename that is stored + * in the compressed file's file header + * NewMcfFile -> Flag used to create a new .MCF file + * TRUE - A new .MCF file will be created + * FALSE - The .MCF file will appended to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressFileToMCF( HWND hWnd, CDC *pDC, PCHAR pszMcfFile, PCHAR pszFileToCompress, + PCHAR pszFilenameOnly, BOOL NewMcfFile ) +{ + ASSERT( hWnd ); + ASSERT_VALID( pDC ); + + CMP_FILEHEADER FileHeader; + + pszFilename = pszMcfFile; + + memset( &FileHeader, 0, sizeof(FileHeader) ); + + // ATTEMPT TO COMPRESS THE FILE + if( !CompressFile( hWnd, pDC, &FileHeader.dwCrc, + &FileHeader.dwCompressSize, pszFileToCompress, + TEMPFILENAME ) ) + { + remove( TEMPFILENAME ); + MessageBox( hWnd, "Compress File Failed", "Error", MB_OK ); + return 0; + } + + strcpy( FileHeader.filename, pszFilenameOnly ); + + if( !AddFileToMcfFile( &FileHeader, TEMPFILENAME, FileHeader.dwCompressSize, NewMcfFile ) ) + { + remove( TEMPFILENAME ); + MessageBox( hWnd, "Compress File Failed", "Error", MB_OK ); + return 0; + } + + remove( TEMPFILENAME ); + + return 1; +} + +/********************************************************************* + * + * Function: UncompressFileToMCF() + * + * Purpose: To uncompress a .MCF file + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszMcfFilename -> Filename of .MCF file + * pszSaveDir -> Directory to save uncompressed files + * a backslash must be the last character + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int UncompressMcfFile( HWND hWnd, CDC *pDC, PCHAR pszMcfFilename, PCHAR pszSaveDir ) +{ + ASSERT( hWnd ); + ASSERT_VALID( pDC ); + + CMP_FILEHEADER FileHeader; + char McfFileheader[5]; + char szOutMsg[128]; + char szOutputFilename[100]; + UINT nNumFiles = 0; + DWORD dwCrc; // CRC OF FILE BEFORE COMPRESSION + UINT read; + CFile McfFile; + + pszFilename = pszMcfFilename; + + TRY + { + // OPEN THE FILES + McfFile.Open( pszFilename, CFile::modeRead | CFile::shareExclusive | CFile::typeBinary); + + memset( McfFileheader, 0, sizeof(McfFileheader) ); + + // MAKE SURE FILE IS A MULTIPLE COMPRESSED FILE + if( (!ReadFromDisk( &McfFile, McfFileheader, 4, &read, FALSE )) || + (read != 4) || + (strcmp( McfFileheader, MCF_FILEHEADER ) != 0) ) + { + MessageBox( hWnd, "Invalid file format", "Error", MB_OK ); + return 0; + } + + do + { + // READ COMPRESSED FILE FILEHEADER + if( !ReadFromDisk( &McfFile, (PCHAR)&FileHeader, sizeof(FileHeader), + &read, TRUE ) ) + { + MessageBox( hWnd, "Error Uncompressing file", "Error", MB_OK ); + return 0; + } + + // IF SUCCESSFULLY READ COMPRESSED FILE FILEHEADER + if( read == sizeof(FileHeader) ) + { + // CREATE OUTPUT FILENAME + strcpy( szOutputFilename, pszSaveDir ); + strcat( szOutputFilename, FileHeader.filename ); + + wsprintf( szOutMsg, "Uncompressing file: %s ", + FileHeader.filename ); + pDC->TextOut( 10,60, szOutMsg ); + + // ATTEMPT TO EXPAND THE FILE + if( !ExpandFile( hWnd, pDC, &dwCrc, + FileHeader.dwCompressSize, + &McfFile, szOutputFilename ) ) + { + wsprintf( szOutMsg, "Error Uncompressing file: %s", + szOutputFilename ); + MessageBox( hWnd, szOutMsg, "Error", MB_OK ); + return 0; + } + + // CHECK THE CRC OF THE FILE + if( dwCrc != FileHeader.dwCrc ) + { + wsprintf( szOutMsg, "There is an error in the CRC of %s", + szOutputFilename ); + MessageBox( hWnd, szOutMsg, "Error", MB_OK ); + } + + nNumFiles++; + } + } + while( read == sizeof(FileHeader) ); + + if( read != 0 ) + { + MessageBox( hWnd, "Invalid file format", "Error", MB_OK ); + return 0; + } + else + { + wsprintf( szOutMsg, "Uncompressed %u file(s)", nNumFiles ); + MessageBox( hWnd, szOutMsg, "Span", MB_OK ); + } + } + CATCH( CFileException, theException ) + { + if( theException->m_cause != CFileException::none ) + { + MessageBox( hWnd, "File Error", "Error", MB_OK ); + return 0; + } + } + END_CATCH + + return 1; +} + + diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/DCL.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/DCL.H new file mode 100644 index 0000000..9a0de62 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/DCL.H @@ -0,0 +1,13 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +int CompressFileToMCF( HWND hWnd, CDC *pDC, + LPSTR lpszMcfFile, LPSTR lpszFileToCompress, + LPSTR lpszFilenameOnly, BOOL NewMcfFile ); +int UncompressMcfFile( HWND hWnd, CDC *pDC, LPSTR lpszMcfFile, LPSTR lpszSaveDir ); diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/IMPLODE.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/IMPLODEI.LIB b/Storm/PKWARE/EXAMPLES/MFC/SPAN/IMPLODEI.LIB new file mode 100644 index 0000000..ca0b4df Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/SPAN/IMPLODEI.LIB differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/MAINFRM.CPP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MAINFRM.CPP new file mode 100644 index 0000000..7ba6b50 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MAINFRM.CPP @@ -0,0 +1,427 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mainfrm.cpp : implementation of the CMainFrame class +// + +#include "stdafx.h" +#include "span.h" + +#include "mainfrm.h" +#include "implode.h" +#include "dcl.h" +#include "multfdlg.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +extern UINT DataType; // GLOBAL FOR DATA TYPE FOR COMPRESSION +extern UINT DictSize; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +// THE UNCOMPRESS DIRECTORY MUST END WITH A BACKSLASH +char far *UncompressDir = "C:\\TEMP\\"; + + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_COMMAND(IDM_CMP_ASCII, OnCmpAscii) + ON_UPDATE_COMMAND_UI(IDM_CMP_ASCII, OnUpdateCmpAscii) + ON_COMMAND(IDM_CMP_BINARY, OnCmpBinary) + ON_UPDATE_COMMAND_UI(IDM_CMP_BINARY, OnUpdateCmpBinary) + ON_COMMAND(IDM_COMPRESS_FILES, OnCompressFiles) + ON_UPDATE_COMMAND_UI(IDM_COMPRESS_FILES, OnUpdateCompressFiles) + ON_COMMAND(IDM_DICT_SIZE_1024, OnDictSize1024) + ON_UPDATE_COMMAND_UI(IDM_DICT_SIZE_1024, OnUpdateDictSize1024) + ON_COMMAND(IDM_DICT_SIZE_2048, OnDictSize2048) + ON_UPDATE_COMMAND_UI(IDM_DICT_SIZE_2048, OnUpdateDictSize2048) + ON_COMMAND(IDM_DICT_SIZE_4096, OnDictSize4096) + ON_UPDATE_COMMAND_UI(IDM_DICT_SIZE_4096, OnUpdateDictSize4096) + ON_COMMAND(IDM_UNCOMPRESS_FILES, OnUncompressFiles) + ON_UPDATE_COMMAND_UI(IDM_UNCOMPRESS_FILES, OnUpdateUncompressFiles) + ON_WM_CLOSE() + ON_WM_QUERYENDSESSION() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// arrays of IDs used to initialize control bars + +// toolbar buttons - IDs are command buttons +static UINT BASED_CODE buttons[] = +{ + // same order as in the bitmap 'toolbar.bmp' + ID_FILE_NEW, + ID_FILE_OPEN, + ID_FILE_SAVE, + ID_SEPARATOR, + ID_EDIT_CUT, + ID_EDIT_COPY, + ID_EDIT_PASTE, + ID_SEPARATOR, + ID_FILE_PRINT, + ID_APP_ABOUT, +}; + +static UINT BASED_CODE indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + // TODO: add member initialization code here +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE("Failed to create status bar\n"); + return -1; // fail to create + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + + +void CMainFrame::OnCompressFiles() +{ + int rc; + HWND hWnd; + + // GET HANDLE TO WINDOW AND INSTANCE HANDLE + hWnd = CWnd::GetSafeHwnd(); + + // TURN OFF HELP MESSAGE SCREEN AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_OFF_HELP ); + + // CREATE FILE DIALOG THAT CAN USE CAN SELECT MULTIPLE FILES + CMultiSelFileDialog *FileDlg = new CMultiSelFileDialog( this ); + + // IF USER PRESSED OK BUTTON + if( (rc = FileDlg->DoModal()) == IDOK ) + { + // CREATE SAVE AS FILE DIALOG + CFileDialog SaveFileDlg( FALSE, "MCF", "*.MCF", + OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, + "Mult. Compressed Files (*.MCF) |*.MCF ||", this ); + + // GET FILENAME OF FILE TO PUT COMPRESSED FILES IN + if( (SaveFileDlg.DoModal()) == IDOK ) + { + BOOL GotFilenameOk, + bError = FALSE, + CreateMcfFile; + UINT nNumCmpFiles = 0; + char szFilename[13]; // BUFFER FOR FILENAME ONLY + char szFullPathname[128]; // BUFFER FOR FULL PATH FOR FILE + char szOutBuff[64]; // TEMP OUTPUT BUFFER + + // SET FLAG TO PREVENT EXITING IN THE MIDDLE OF THE COMPRESSION + ((CSpanApp *) AfxGetApp())->OkToExit = FALSE; + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + CClientDC dc(this); + COLORREF bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + wsprintf( szOutBuff, "Compressing to: %s ", + (LPSTR) (const char *) SaveFileDlg.GetPathName() ); + dc.TextOut( 10,20, szOutBuff ); + + // SET CREATE .MCF FILE FLAG TO TRUE, SO THAT THE FIRST TIME + // CompressFileToMCF IS CALLED THE .MCF WILL BE CREATED INSTEAD + // OF APPENDED TO + CreateMcfFile = TRUE; + + // GET THE FIRST FILENAME IN THE LIST + GotFilenameOk = FileDlg->GetFirstFilename( szFullPathname, + sizeof(szFullPathname), + szFilename ); + // WHILE GOT A FILENAME FROM THE LIST + while( GotFilenameOk ) + { + // COMPRESS THE FILE AND ADD IT TO THE .MCF FILE + if( !CompressFileToMCF( hWnd, &dc, + (LPSTR) (const char *) SaveFileDlg.GetPathName(), + szFullPathname, szFilename, CreateMcfFile ) ) + { + // ERROR OCCURRED SO DELETE THE .MCF FILE + remove( (const char *) SaveFileDlg.GetPathName() ); + bError = TRUE; + break; + } + // INCREMENT TOTAL + nNumCmpFiles++; + + // RESET .MCF FILE FLAG SO THAT .MCF FILE WILL NOT BE CREATED + CreateMcfFile = FALSE; + + // GET THE FIRST FILENAME IN THE LIST + GotFilenameOk = FileDlg->GetNextFilename( szFullPathname, + sizeof(szFullPathname), + szFilename ); + } + + // IF THERE WAS NOT ERROR, THEN DISPLAY MESSAGE + if( !bError ) + { + wsprintf( szOutBuff, "Compressed %u file(s)", nNumCmpFiles ); + MessageBox( szOutBuff ); + } + + // DONE WITH COMPRESION SO ALLOW THE USER TO EXIT + ((CSpanApp *) AfxGetApp())->OkToExit = TRUE; + } + } + + // CLEAN-UP + delete FileDlg; + + // TURN ON HELP MESSAGE AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_ON_HELP ); +} + +void CMainFrame::OnUncompressFiles() +{ + HWND hWnd; + + hWnd = CWnd::GetSafeHwnd(); + + // TURN OFF HELP MESSAGE AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_OFF_HELP ); + + // OPENFILENAME + CFileDialog OpenFileDlg( TRUE, "MCF", "*.MCF", + OFN_HIDEREADONLY | OFN_NOCHANGEDIR, + "Mult. Compressed Files (*.MCF) |*.MCF ||", this ); + + // GET FILENAME OF FILE TO PUT COMPRESSED FILES IN + if( (OpenFileDlg.DoModal()) == IDOK ) + { + char szOutBuff[64]; // TEMP OUTPUT BUFFER + + // SET FLAG TO PREVENT EXITING IN THE MIDDLE OF THE UNCOMPRESSION + ((CSpanApp *) AfxGetApp())->OkToExit = FALSE; + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + CClientDC dc(this); + COLORREF bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + wsprintf( szOutBuff, "Uncompressing: %s ", + (LPSTR) (const char *) OpenFileDlg.GetPathName() ); + dc.TextOut( 10,20, szOutBuff ); + + // UNCOMPRESS THE FILE + UncompressMcfFile( hWnd, &dc, + (LPSTR) (const char *) OpenFileDlg.GetPathName(), + UncompressDir ); + + // DONE WITH UNCOMPRESION SO ALLOW THE USER TO EXIT + ((CSpanApp *) AfxGetApp())->OkToExit = TRUE; + } + + // TURN ON HELP MESSAGE AND CLEAR SCREEN + SendMessageToDescendants( WM_TURN_ON_HELP ); +} + +BOOL CMainFrame::OnQueryEndSession() +{ + if (!CFrameWnd::OnQueryEndSession()) + return FALSE; + + // RETURN FALSE IF CANNOT EXIT RIGHT NOW + if( !((CSpanApp *) AfxGetApp())->OkToExit ) + return FALSE; + + return TRUE; +} + +void CMainFrame::OnClose() +{ + // RETURN IF CANNOT EXIT RIGHT NOW + if( !((CSpanApp *) AfxGetApp())->OkToExit ) + return; + + CFrameWnd::OnClose(); +} + +void CMainFrame::OnUpdateCompressFiles(CCmdUI* pCmdUI) +{ + pCmdUI->Enable( ((CSpanApp *) AfxGetApp())->OkToExit ); +} + +void CMainFrame::OnUpdateUncompressFiles(CCmdUI* pCmdUI) +{ + pCmdUI->Enable( ((CSpanApp *) AfxGetApp())->OkToExit ); +} + + +void CMainFrame::OnCmpAscii() +{ + DataType = CMP_ASCII; +} + +void CMainFrame::OnCmpBinary() +{ + DataType = CMP_BINARY; +} + +void CMainFrame::OnDictSize1024() +{ + DictSize = 1024; +} + +void CMainFrame::OnDictSize2048() +{ + DictSize = 2048; +} + +void CMainFrame::OnDictSize4096() +{ + DictSize = 4096; +} + +void CMainFrame::OnUpdateCmpAscii(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CSpanApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DataType == CMP_ASCII ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateCmpBinary(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CSpanApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DataType == CMP_BINARY ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateDictSize1024(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CSpanApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DictSize == 1024 ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateDictSize2048(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CSpanApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DictSize == 2048 ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + +void CMainFrame::OnUpdateDictSize4096(CCmdUI* pCmdUI) +{ + // IF PROGRAM IS COMPRESSING OR UNCOMPRESSING RIGHT NOW + if( !((CSpanApp *) AfxGetApp())->OkToExit ) + { + pCmdUI->Enable( FALSE ); + return; + } + + if( DictSize == 4096 ) + { + pCmdUI->SetCheck( 1 ); + } + else + { + pCmdUI->SetCheck( 0 ); + } +} + diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/MAINFRM.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MAINFRM.H new file mode 100644 index 0000000..da293e9 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MAINFRM.H @@ -0,0 +1,61 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// mainfrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + CMainFrame(); + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + +// Operations +public: + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnCmpAscii(); + afx_msg void OnUpdateCmpAscii(CCmdUI* pCmdUI); + afx_msg void OnCmpBinary(); + afx_msg void OnUpdateCmpBinary(CCmdUI* pCmdUI); + afx_msg void OnCompressFiles(); + afx_msg void OnUpdateCompressFiles(CCmdUI* pCmdUI); + afx_msg void OnDictSize1024(); + afx_msg void OnUpdateDictSize1024(CCmdUI* pCmdUI); + afx_msg void OnDictSize2048(); + afx_msg void OnUpdateDictSize2048(CCmdUI* pCmdUI); + afx_msg void OnDictSize4096(); + afx_msg void OnUpdateDictSize4096(CCmdUI* pCmdUI); + afx_msg void OnUncompressFiles(); + afx_msg void OnUpdateUncompressFiles(CCmdUI* pCmdUI); + afx_msg void OnClose(); + afx_msg BOOL OnQueryEndSession(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/MULTFDLG.CPP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MULTFDLG.CPP new file mode 100644 index 0000000..aff5eb3 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MULTFDLG.CPP @@ -0,0 +1,158 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include "stdafx.h" +#include + +#include "multfdlg.h" + +#define FILELIST_BUFFSIZE 4096 // AMOUNT OF MEMORY TO ALLOCATE FOR FILE LIST + + +CMultiSelFileDialog::CMultiSelFileDialog( CWnd *pParentWnd ) + :CFileDialog( TRUE, NULL, "*.*", + OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR, + "All Files (*.*) |*.* ||", pParentWnd ) +{ + // ALLOCATE MEMORY FOR FILE LIST + pszFileList = (PCHAR) new char[FILELIST_BUFFSIZE]; + + // SET ALLOCATED BUFFER AS FILENAME BUFER IN OPENFILENAME STRUCT + // AND REPLACE IT IN THE OPENFILENAME STRUCT + pszOldPtr = m_ofn.lpstrFile; + m_ofn.lpstrFile = pszFileList; + m_ofn.nMaxFile = FILELIST_BUFFSIZE; + + // DO SOME INITIALIZATION + memset( pszFileList, 0, FILELIST_BUFFSIZE ); + strcpy( pszFileList, "*.*" ); + memset( szPath, 0, sizeof(szPath) ); + nPathLen = 0; + Done = TRUE; +} + + +CMultiSelFileDialog::~CMultiSelFileDialog() +{ + // REPLACE OLD POINTER AND FREE MEMORY + m_ofn.lpstrFile = pszOldPtr; + delete pszFileList; +} + + +BOOL CMultiSelFileDialog::GetFirstFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ) +{ + PCHAR pszToken; + + nPathLen = 0; + Done = FALSE; + + // GET THE FIRST TOKEN WHICH SHOULD BE THE PATH + if( strchr( pszFileList, ' ' ) == NULL ) + { + // COULD NOT FIND TOKEN SO MUST BE PATH AND FILENAME + + Done = TRUE; + + memset( szPath, 0, sizeof(szPath) ); + nPathLen = 0; + + // MAKE SURE THE FILENAME + PATH WILL FIT + if( strlen( pszFileList ) > nPathBuffSize ) + { + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // CREATE FILENAME ONLY + strcpy( pszFilenameBuff, GetFileName() ); + strcat( pszFilenameBuff, "." ); + strcat( pszFilenameBuff, GetFileExt() ); + + // COPY PATH AND FILENAME TO BUFFER + strcpy( pszFullPathBuff, pszFileList ); + + return TRUE; + } + + // GET THE FIRST TOKEN WHICH SHOULD BE THE PATH + if( (pszToken = strtok( pszFileList, " " )) == NULL ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + memset( szPath, 0, sizeof(szPath) ); + strcpy( szPath, pszToken ); + strcat( szPath, "\\" ); + + nPathLen = strlen( szPath ); + + return GetNextFilename( pszFullPathBuff, nPathBuffSize, pszFilenameBuff ); +} + + +// pszFilenameBuff MUST BE AT LEAST 13 BYTES +BOOL CMultiSelFileDialog::GetNextFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ) +{ + PCHAR pszToken; + + if( Done ) + { + return FALSE; + } + + // GET THE NEXT TOKEN WHICH SHOULD BE A FILENAME + if( (pszToken = strtok( NULL, " " )) == NULL ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // MAKE SURE THE FILENAME + PATH WILL FIT + if( (strlen( pszToken ) + nPathLen) > nPathBuffSize ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // COPY PATH AND FILENAME TO BUFFER + strcpy( pszFullPathBuff, szPath ); + strcat( pszFullPathBuff, pszToken ); + + PCHAR pszNameOnly = strrchr( pszFullPathBuff, '\\' ); + + if( (pszNameOnly == NULL) || (strlen(pszNameOnly) > 13) ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + strcpy( pszFilenameBuff, ++pszNameOnly ); + + return TRUE; +} + + + + + diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/MULTFDLG.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MULTFDLG.H new file mode 100644 index 0000000..d9729e3 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/MULTFDLG.H @@ -0,0 +1,30 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include + +class CMultiSelFileDialog : public CFileDialog +{ + private: + PCHAR pszFileList; + PCHAR pszOldPtr; + int nPathLen; + char szPath[80]; + BOOL Done; + + public: + CMultiSelFileDialog( CWnd *pParentWnd ); + ~CMultiSelFileDialog(); + BOOL GetFirstFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ); + BOOL GetNextFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ); +}; diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/SPAN.ICO b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/SPAN.ICO new file mode 100644 index 0000000..b718392 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/SPAN.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/SPAN.RC2 b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/SPAN.RC2 new file mode 100644 index 0000000..1dd2e43 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/SPAN.RC2 @@ -0,0 +1,52 @@ +// +// SPAN.RC2 - resources App Studio does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by App Studio +#endif //APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// Version stamp for this .EXE + +#include "ver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG|VS_FF_PRIVATEBUILD|VS_FF_PRERELEASE +#else + FILEFLAGS 0 // final version +#endif + FILEOS VOS_DOS_WINDOWS16 + FILETYPE VFT_APP + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "SPAN MFC Application\0" + VALUE "FileVersion", "1.0.001\0" + VALUE "InternalName", "SPAN\0" + VALUE "LegalCopyright", "\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename","SPAN.EXE\0" + VALUE "ProductName", "SPAN\0" + VALUE "ProductVersion", "1.0.001\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + // English language (0x409) and the Windows ANSI codepage (1252) + END +END + +///////////////////////////////////////////////////////////////////////////// +// Add additional manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/TOOLBAR.BMP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/TOOLBAR.BMP new file mode 100644 index 0000000..49695e2 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RES/TOOLBAR.BMP differ diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/RESOURCE.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RESOURCE.H new file mode 100644 index 0000000..2438033 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/RESOURCE.H @@ -0,0 +1,33 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +//{{NO_DEPENDENCIES}} +// App Studio generated include file. +// Used by SPAN.RC +// +#define IDR_MAINFRAME 2 +#define IDD_ABOUTBOX 100 +#define IDM_COMPRESS_FILES 32772 +#define IDM_UNCOMPRESS_FILES 32773 +#define IDM_CMP_BINARY 32774 +#define IDM_CMP_ASCII 32775 +#define IDM_DICT_SIZE_1024 32777 +#define IDM_DICT_SIZE_2048 32778 +#define IDM_DICT_SIZE_4096 32779 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.CPP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.CPP new file mode 100644 index 0000000..bf25012 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.CPP @@ -0,0 +1,139 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// span.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "span.h" + +#include "mainfrm.h" +#include "spandoc.h" +#include "spanview.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSpanApp + +BEGIN_MESSAGE_MAP(CSpanApp, CWinApp) + //{{AFX_MSG_MAP(CSpanApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSpanApp construction + +CSpanApp::CSpanApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSpanApp object + +CSpanApp NEAR theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSpanApp initialization + +BOOL CSpanApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + OkToExit = TRUE; + + SetDialogBkColor(); // Set dialog background color to gray + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CSingleDocTemplate* pDocTemplate; + pDocTemplate = new CSingleDocTemplate( + IDR_MAINFRAME, + RUNTIME_CLASS(CSpanDoc), + RUNTIME_CLASS(CMainFrame), // main SDI frame window + RUNTIME_CLASS(CSpanView)); + AddDocTemplate(pDocTemplate); + + // create a new (empty) document + OnFileNew(); + + if (m_lpCmdLine[0] != '\0') + { + // TODO: add command line processing here + } + + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + +// Implementation +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSpanApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSpanApp commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.H new file mode 100644 index 0000000..e5335e5 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.H @@ -0,0 +1,47 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// span.h : main header file for the SPAN application +// + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +#define WM_TURN_OFF_HELP WM_USER+1 +#define WM_TURN_ON_HELP WM_USER+2 + +///////////////////////////////////////////////////////////////////////////// +// CSpanApp: +// See span.cpp for the implementation of this class +// + +class CSpanApp : public CWinApp +{ +public: + CSpanApp(); + + BOOL OkToExit; + +// Overrides + virtual BOOL InitInstance(); + +// Implementation + + //{{AFX_MSG(CSpanApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.MAK b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.MAK new file mode 100644 index 0000000..47220a5 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.MAK @@ -0,0 +1,297 @@ +# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE No configuration specified. Defaulting to Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SPAN.MAK" CFG="Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Win32 Debug" +MTL=MkTypLib.exe +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Win32 Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/SPAN.exe $(OUTDIR)/SPAN.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE CPP /nologo /MD /W3 /GX /YX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"STDAFX.H" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"SPAN.pch" /Yu"STDAFX.H" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ +# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"SPAN.res" /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"SPAN.bsc" + +$(OUTDIR)/SPAN.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib pkwdcl.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /MACHINE:IX86 +# ADD LINK32 oldnames.lib implodei.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /MACHINE:IX86 +# SUBTRACT LINK32 /INCREMENTAL:yes +LINK32_FLAGS=oldnames.lib implodei.lib /NOLOGO /STACK:0x10240\ + /SUBSYSTEM:windows /INCREMENTAL:no /PDB:$(OUTDIR)/"SPAN.pdb" /MACHINE:IX86\ + /OUT:$(OUTDIR)/"SPAN.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/SPAN.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/SPAN.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/SPANDOC.OBJ \ + $(INTDIR)/SPANVIEW.OBJ \ + $(INTDIR)/DCL.OBJ \ + $(INTDIR)/MULTFDLG.OBJ + +$(OUTDIR)/SPAN.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/SPAN.exe $(OUTDIR)/SPAN.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE CPP /nologo /MD /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"STDAFX.H" /c +# SUBTRACT CPP /Fr +CPP_PROJ=/nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"SPAN.pch" /Yu"STDAFX.H" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"SPAN.pdb" /c +CPP_OBJS=.\WinDebug/ +# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"SPAN.res" /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +BSC32_SBRS= \ + +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"SPAN.bsc" + +$(OUTDIR)/SPAN.bsc : $(OUTDIR) $(BSC32_SBRS) +LINK32=link.exe +# ADD BASE LINK32 oldnames.lib pkwdcl.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /DEBUG /MACHINE:IX86 +# ADD LINK32 oldnames.lib implodei.lib /NOLOGO /STACK:0x10240 /SUBSYSTEM:windows /INCREMENTAL:no /DEBUG /MACHINE:IX86 +LINK32_FLAGS=oldnames.lib implodei.lib /NOLOGO /STACK:0x10240\ + /SUBSYSTEM:windows /INCREMENTAL:no /PDB:$(OUTDIR)/"SPAN.pdb" /DEBUG\ + /MACHINE:IX86 /OUT:$(OUTDIR)/"SPAN.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/SPAN.res \ + $(INTDIR)/STDAFX.OBJ \ + $(INTDIR)/SPAN.OBJ \ + $(INTDIR)/MAINFRM.OBJ \ + $(INTDIR)/SPANDOC.OBJ \ + $(INTDIR)/SPANVIEW.OBJ \ + $(INTDIR)/DCL.OBJ \ + $(INTDIR)/MULTFDLG.OBJ + +$(OUTDIR)/SPAN.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Group "Source Files" + +################################################################################ +# Begin Source File + +SOURCE=.\SPAN.RC +DEP_SPAN_=\ + .\RES\SPAN.ICO\ + .\RES\TOOLBAR.BMP\ + .\resource.h\ + .\res\span.rc2 + +$(INTDIR)/SPAN.res : $(SOURCE) $(DEP_SPAN_) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\STDAFX.CPP +DEP_STDAF=\ + .\stdafx.h + +!IF "$(CFG)" == "Win32 Release" + +# ADD BASE CPP /Yc"STDAFX.H" +# ADD CPP /Yc"STDAFX.H" + +$(INTDIR)/STDAFX.OBJ : $(SOURCE) $(DEP_STDAF) $(INTDIR) + $(CPP) /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"SPAN.pch" /Yc"STDAFX.H" /Fo$(INTDIR)/ /c\ + $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# ADD BASE CPP /Yc"STDAFX.H" +# ADD CPP /Yc"STDAFX.H" + +$(INTDIR)/STDAFX.OBJ : $(SOURCE) $(DEP_STDAF) $(INTDIR) + $(CPP) /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D\ + "_AFXDLL" /D "_MBCS" /Fp$(OUTDIR)/"SPAN.pch" /Yc"STDAFX.H" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"SPAN.pdb" /c $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPAN.CPP +DEP_SPAN_C=\ + .\stdafx.h\ + .\span.h\ + .\mainfrm.h\ + .\spandoc.h\ + .\spanview.h\ + .\resource.h + +$(INTDIR)/SPAN.OBJ : $(SOURCE) $(DEP_SPAN_C) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MAINFRM.CPP +DEP_MAINF=\ + .\stdafx.h\ + .\span.h\ + .\mainfrm.h\ + .\implode.h\ + .\dcl.h\ + .\multfdlg.h\ + .\resource.h + +$(INTDIR)/MAINFRM.OBJ : $(SOURCE) $(DEP_MAINF) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPANDOC.CPP +DEP_SPAND=\ + .\stdafx.h\ + .\span.h\ + .\spandoc.h\ + .\resource.h + +$(INTDIR)/SPANDOC.OBJ : $(SOURCE) $(DEP_SPAND) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPANVIEW.CPP +DEP_SPANV=\ + .\stdafx.h\ + .\span.h\ + .\spandoc.h\ + .\spanview.h\ + .\resource.h + +$(INTDIR)/SPANVIEW.OBJ : $(SOURCE) $(DEP_SPANV) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DCL.CPP +DEP_DCL_C=\ + .\stdafx.h\ + .\implode.h + +$(INTDIR)/DCL.OBJ : $(SOURCE) $(DEP_DCL_C) $(INTDIR) $(INTDIR)/STDAFX.OBJ + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MULTFDLG.CPP +DEP_MULTF=\ + .\stdafx.h\ + .\multfdlg.h + +$(INTDIR)/MULTFDLG.OBJ : $(SOURCE) $(DEP_MULTF) $(INTDIR)\ + $(INTDIR)/STDAFX.OBJ + +# End Source File +# End Group +# End Project +################################################################################ diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.RC b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.RC new file mode 100644 index 0000000..15a7b64 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPAN.RC @@ -0,0 +1,214 @@ +//Microsoft App Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#ifdef APSTUDIO_INVOKED +////////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""res\\span.rc2"" // non-App Studio edited resources\r\n" + "\r\n" + "#include ""afxres.rc"" \011// Standard components\r\n" + "\0" +END + +///////////////////////////////////////////////////////////////////////////////////// +#endif // APSTUDIO_INVOKED + + +////////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +IDR_MAINFRAME ICON DISCARDABLE "RES\\SPAN.ICO" + +////////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINFRAME BITMAP MOVEABLE PURE "RES\\TOOLBAR.BMP" + +////////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU PRELOAD DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Compress Files", IDM_COMPRESS_FILES + MENUITEM "&Uncompress Files", IDM_UNCOMPRESS_FILES + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "&Options" + BEGIN + MENUITEM "&ASCII", IDM_CMP_ASCII + MENUITEM "&Binary", IDM_CMP_BINARY + MENUITEM SEPARATOR + MENUITEM "&1024", IDM_DICT_SIZE_1024 + MENUITEM "&2048", IDM_DICT_SIZE_2048 + MENUITEM "&4096", IDM_DICT_SIZE_4096 + END + POPUP "&View" + BEGIN + MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR + END + POPUP "&Help" + BEGIN + MENUITEM "&About Multfile...", ID_APP_ABOUT + END +END + + +////////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 34, 22, 217, 55 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Span" +FONT 8, "MS Sans Serif" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20 + LTEXT "Span Application Version 1.0",IDC_STATIC,40,10,119,8 + LTEXT "Copyright \251 1995",IDC_STATIC,40,25,119,8 + DEFPUSHBUTTON "OK",IDOK,176,6,32,14,WS_GROUP +END + + +////////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + IDR_MAINFRAME "Span Windows Application\n\nSpan Document\n\n\nSpan.Document\nSpan Document" +END + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + AFX_IDS_APP_TITLE "Span Windows Application" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_INDICATOR_EXT "EXT" + ID_INDICATOR_CAPS "CAP" + ID_INDICATOR_NUM "NUM" + ID_INDICATOR_SCRL "SCRL" + ID_INDICATOR_OVR "OVR" + ID_INDICATOR_REC "REC" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_NEW "Create a new document" + ID_FILE_OPEN "Open an existing document" + ID_FILE_CLOSE "Close the active document" + ID_FILE_SAVE "Save the active document" + ID_FILE_SAVE_AS "Save the active document with a new name" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright" + ID_APP_EXIT "Quit the application; prompts to save documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_MRU_FILE1 "Open this document" + ID_FILE_MRU_FILE2 "Open this document" + ID_FILE_MRU_FILE3 "Open this document" + ID_FILE_MRU_FILE4 "Open this document" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane" + ID_PREV_PANE "Switch back to the previous window pane" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection" + ID_EDIT_CLEAR_ALL "Erase everything" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard" + ID_EDIT_FIND "Find the specified text" + ID_EDIT_PASTE "Insert Clipboard contents" + ID_EDIT_REPEAT "Repeat the last action" + ID_EDIT_REPLACE "Replace specific text with different text" + ID_EDIT_SELECT_ALL "Select the entire document" + ID_EDIT_UNDO "Undo the last action" + ID_EDIT_REDO "Redo the previously undone action" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_VIEW_TOOLBAR "Show or hide the toolbar" + ID_VIEW_STATUS_BAR "Show or hide the status bar" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + + +#ifndef APSTUDIO_INVOKED +//////////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "res\span.rc2" // non-App Studio edited resources + +#include "afxres.rc" // Standard components + +///////////////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANDOC.CPP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANDOC.CPP new file mode 100644 index 0000000..e268f55 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANDOC.CPP @@ -0,0 +1,88 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// spandoc.cpp : implementation of the CSpanDoc class +// + +#include "stdafx.h" +#include "span.h" + +#include "spandoc.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSpanDoc + +IMPLEMENT_DYNCREATE(CSpanDoc, CDocument) + +BEGIN_MESSAGE_MAP(CSpanDoc, CDocument) + //{{AFX_MSG_MAP(CSpanDoc) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSpanDoc construction/destruction + +CSpanDoc::CSpanDoc() +{ + // TODO: add one-time construction code here +} + +CSpanDoc::~CSpanDoc() +{ +} + +BOOL CSpanDoc::OnNewDocument() +{ + if (!CDocument::OnNewDocument()) + return FALSE; + + // TODO: add reinitialization code here + // (SDI documents will reuse this document) + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CSpanDoc serialization + +void CSpanDoc::Serialize(CArchive& ar) +{ + if (ar.IsStoring()) + { + // TODO: add storing code here + } + else + { + // TODO: add loading code here + } +} + +///////////////////////////////////////////////////////////////////////////// +// CSpanDoc diagnostics + +#ifdef _DEBUG +void CSpanDoc::AssertValid() const +{ + CDocument::AssertValid(); +} + +void CSpanDoc::Dump(CDumpContext& dc) const +{ + CDocument::Dump(dc); +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CSpanDoc commands diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANDOC.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANDOC.H new file mode 100644 index 0000000..fe29226 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANDOC.H @@ -0,0 +1,45 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// spandoc.h : interface of the CSpanDoc class +// +///////////////////////////////////////////////////////////////////////////// + +class CSpanDoc : public CDocument +{ +protected: // create from serialization only + CSpanDoc(); + DECLARE_DYNCREATE(CSpanDoc) + +// Attributes +public: +// Operations +public: + +// Implementation +public: + virtual ~CSpanDoc(); + virtual void Serialize(CArchive& ar); // overridden for document i/o +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + virtual BOOL OnNewDocument(); + +// Generated message map functions +protected: + //{{AFX_MSG(CSpanDoc) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANVIEW.CPP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANVIEW.CPP new file mode 100644 index 0000000..c7fc730 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANVIEW.CPP @@ -0,0 +1,125 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// spanview.cpp : implementation of the CSpanView class +// + +#include "stdafx.h" +#include "span.h" + +#include "spandoc.h" +#include "spanview.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + + +char szHelpMsg[] = { + "To compress multiple files: Select Compress Files from the File " + "menu, and use the shift and control keys with the mouse to " + "highlight multiple files. Press Ok after selecting the files. " + "Enter the path and name of file to compress the selected files " + "to.\n\n" + "To uncompress a file: Select Uncompress Files from the File menu, " + "and enter or select the file to uncompress, then press the Ok " + "button. The files will be uncompressed to " }; + +extern char far *UncompressDir; + +///////////////////////////////////////////////////////////////////////////// +// CSpanView + +IMPLEMENT_DYNCREATE(CSpanView, CView) + +BEGIN_MESSAGE_MAP(CSpanView, CView) + //{{AFX_MSG_MAP(CSpanView) + ON_MESSAGE( WM_TURN_OFF_HELP, OnTurnOffHelp ) + ON_MESSAGE( WM_TURN_ON_HELP, OnTurnOnHelp ) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSpanView construction/destruction + +CSpanView::CSpanView() +{ + bDisplayHelp = TRUE; +} + +CSpanView::~CSpanView() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// CSpanView drawing + +void CSpanView::OnDraw(CDC* pDC) +{ + CSpanDoc* pDoc = GetDocument(); + ASSERT_VALID(pDoc); + + // TODO: add draw code for native data here + if( bDisplayHelp ) + { + RECT rect; + char *pszHelpString; + + pszHelpString = new char[1024]; + + strcpy( pszHelpString, szHelpMsg ); + strcat( pszHelpString, UncompressDir ); + + pDC->SetBkMode( TRANSPARENT ); + GetClientRect( &rect ); + pDC->DrawText( pszHelpString, -1, &rect, DT_LEFT | DT_WORDBREAK ); + } +} + +///////////////////////////////////////////////////////////////////////////// +// CSpanView diagnostics + +#ifdef _DEBUG +void CSpanView::AssertValid() const +{ + CView::AssertValid(); +} + +void CSpanView::Dump(CDumpContext& dc) const +{ + CView::Dump(dc); +} + +CSpanDoc* CSpanView::GetDocument() // non-debug version is inline +{ + ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSpanDoc))); + return (CSpanDoc*)m_pDocument; +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CSpanView message handlers + +LRESULT CSpanView::OnTurnOffHelp( WPARAM wParam, LPARAM lParam ) +{ + bDisplayHelp = FALSE; + InvalidateRect( NULL, TRUE ); + + return 0; +} + +LRESULT CSpanView::OnTurnOnHelp( WPARAM wParam, LPARAM lParam ) +{ + bDisplayHelp = TRUE; + InvalidateRect( NULL, TRUE ); + + return 0; +} + + diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANVIEW.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANVIEW.H new file mode 100644 index 0000000..8833a0e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/SPANVIEW.H @@ -0,0 +1,54 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +// spanview.h : interface of the CSpanView class +// +///////////////////////////////////////////////////////////////////////////// + +class CSpanView : public CView +{ +private: + BOOL bDisplayHelp; + +protected: // create from serialization only + CSpanView(); + DECLARE_DYNCREATE(CSpanView) + +// Attributes +public: + CSpanDoc* GetDocument(); + +// Operations +public: + +// Implementation +public: + virtual ~CSpanView(); + virtual void OnDraw(CDC* pDC); // overridden to draw this view + afx_msg LRESULT OnTurnOffHelp( WPARAM wParam, LPARAM lParam ); + afx_msg LRESULT OnTurnOnHelp( WPARAM wParam, LPARAM lParam ); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + +// Generated message map functions +protected: + //{{AFX_MSG(CSpanView) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#ifndef _DEBUG // debug version in spanview.cpp +inline CSpanDoc* CSpanView::GetDocument() + { return (CSpanDoc*)m_pDocument; } +#endif + +///////////////////////////////////////////////////////////////////////////// diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/STDAFX.CPP b/Storm/PKWARE/EXAMPLES/MFC/SPAN/STDAFX.CPP new file mode 100644 index 0000000..07f7b46 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/STDAFX.CPP @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// stdafx.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/Storm/PKWARE/EXAMPLES/MFC/SPAN/STDAFX.H b/Storm/PKWARE/EXAMPLES/MFC/SPAN/STDAFX.H new file mode 100644 index 0000000..6179a32 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/MFC/SPAN/STDAFX.H @@ -0,0 +1,7 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#include // MFC core and standard components +#include // MFC extensions (including VB) diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/APPLDOCV.ICO b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/APPLDOCV.ICO new file mode 100644 index 0000000..b4843af Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/APPLDOCV.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/DCL.CPP b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/DCL.CPP new file mode 100644 index 0000000..6b5f7c1 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/DCL.CPP @@ -0,0 +1,478 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +/* + * DCL.cpp - File to call various DCL DLL functions + */ + +#include +#include + +#include +#include +#include + +#include "implode.h" + +typedef enum +{ + COMPRESSING = 1, + UNCOMPRESSING +} FILEMODE; + +typedef struct +{ + PBYTE Buffer; // POINTER TO BUFFER + UINT CurPos; // CURRENT POSITION IN BUFFER + UINT BuffSize; // SIZE OF THE BUFFER +} BUFFER_BLOCK, *PBUFFER_BLOCK; + +// STRUCT TO PASS TO THE FILE IO FUNCTIONS +typedef struct +{ + BUFFER_BLOCK FileBuff; // FILE BUFFER + BUFFER_BLOCK cmpBuff; // COMPRESSION BUFFER + BUFFER_BLOCK uncmpBuff; // UNCOMPRESSION BUFFER + FILEMODE mode; + DWORD dwCrc; // CRC + UINT nCompressSize; + BOOL ErrorOccurred; // ERROR FLAG +} DATABLOCK, *PDATABLOCK; + +UINT DataType = CMP_ASCII; // GLOBAL FOR DATA TYPE FOR COMPRESSION +UINT DictSize = 4096; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +static int iLineCnt; // CURRENT LINE TO OUTPUT STRING + + +/********************************************************************* + * + * Function: ReadBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * read requests. If compressing, then the data read is + * in uncompressed form. If compressing, then the data + * read is data that was previously compressed. This + * function is called until zero is returned. + * + * Parameters: buffer -> Address of buffer to read the data into + * iSize -> Number of bytes to read into buffer + * dwParam -> User-defined parameter, in this case a + * pointer to the DATABLOCK + * + * Returns: Number of bytes actually read, or zero on EOF + * + *********************************************************************/ +UINT ReadBuffer( PCHAR buffer, UINT *iSize, void *pParam ) +{ + PDATABLOCK pDataBlock; + PBUFFER_BLOCK pBufferBlock; + UINT iRead; + + pDataBlock = (PDATABLOCK) pParam; + + // IF AN ERROR OCCURRED + if( pDataBlock->ErrorOccurred == TRUE ) + { + return 0; + } + + if( pDataBlock->mode == COMPRESSING ) + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE COMPRESSION BUFFER + pBufferBlock = &pDataBlock->FileBuff; + } + else + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE UNCOMPRESSION BUFFER + pBufferBlock = &pDataBlock->cmpBuff; + } + + if( pBufferBlock->CurPos < pBufferBlock->BuffSize ) + { + UINT BytesLeft = pBufferBlock->BuffSize - pBufferBlock->CurPos; + + // IF REQUESTING MORE BYTES THAN ARE LEFT + if( BytesLeft < *iSize ) + { + // SET NUMBER OF BYTES TO COPY TO WHAT IS LEFT + *iSize = BytesLeft; + } + + // COPY BYTES AND UPDATE COUNTER + memcpy( buffer, (pBufferBlock->Buffer + pBufferBlock->CurPos), *iSize ); + pBufferBlock->CurPos += *iSize; + + iRead = *iSize; + } + else // ELSE - NOTHING LEFT IN BUFFER SO RETURN 0 + { + iRead = 0; + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if( pDataBlock->mode == COMPRESSING ) + { + pDataBlock->dwCrc = crc32( buffer, &iRead, &pDataBlock->dwCrc ); + } + + return iRead; +} + +/********************************************************************* + * + * Function: WriteBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * write requests. + * + * Parameters: buffer -> Address of buffer to write data from + * iSize -> Number of bytes to write + * dwParam -> User-defined parameter, in this case a + * pointer to the DATABLOCK + * + * Returns: Zero, the return value is not used by the Data + * Compression Library + * + *********************************************************************/ +void WriteBuffer( PCHAR buffer, UINT *iSize, void *pParam ) +{ + PDATABLOCK pDataBlock; + PBUFFER_BLOCK pBufferBlock; + + pDataBlock = (PDATABLOCK) pParam; + + // IF AN ERROR OCCURRED + if( pDataBlock->ErrorOccurred == TRUE ) + { + return; + } + + if( pDataBlock->mode == COMPRESSING ) + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE COMPRESSION BUFFER + pBufferBlock = &pDataBlock->cmpBuff; + + // SINCE COMPRESSING, KEEP A TOTAL OF THE COMPRESSED FILE SIZE + pDataBlock->nCompressSize += *iSize; + } + else + { + // SINCE COMPRESSING THEN WANT TO WRITE DATA TO THE UNCOMPRESSION BUFFER + pBufferBlock = &pDataBlock->uncmpBuff; + } + + // IF NOT OUT OF BUFFER SPACE + if( pBufferBlock->CurPos < pBufferBlock->BuffSize ) + { + // IF WRITING MORE BYTES THAN ARE LEFT + if( (pBufferBlock->BuffSize - pBufferBlock->CurPos) < *iSize ) + { + MessageBox( NULL, "Out of buffer space - #1", "Compression Error", MB_OK ); + pDataBlock->ErrorOccurred = TRUE; + return; + } + + // COPY BYTES AND UPDATE COUNTER + memcpy( (pBufferBlock->Buffer + pBufferBlock->CurPos), + buffer, *iSize ); + pBufferBlock->CurPos += *iSize; + } + else // ELSE - NOTHING LEFT IN BUFFER SO RETURN 0 + { + MessageBox( NULL, "Out of buffer space - #2", "Compression Error", MB_OK ); + pDataBlock->ErrorOccurred = TRUE; + return; + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if (pDataBlock->mode == UNCOMPRESSING ) + { + pDataBlock->dwCrc = crc32( buffer, iSize, &pDataBlock->dwCrc ); + } + + return; +} + +/********************************************************************* + * + * Function: CompressMemToMem() + * + * Purpose: To compress a buffer to another buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * pnCompressedSize -> Number of bytes in the compressed + * buffer + * pFileBuffer -> Pointer to buffer to compress + * pCompressedBuffer -> Pointer to buffer to place + * compressed data + * BuffSize -> Size of the buffers (both are allocated + * for same number of bytes) + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressMemToMem( HWND hWnd, TDC *pDC, DWORD *pdwCrc, + UINT *pnCompressedSize, PBYTE pFileBuffer, + PBYTE pCompressedBuffer, UINT BuffSize ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + DATABLOCK DataBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + memset( &DataBlock, 0, sizeof(DataBlock) ); + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + DataBlock.mode = COMPRESSING; + DataBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + // SETUP BUFFER BLOCK FOR FILE BUFFER + DataBlock.FileBuff.Buffer = pFileBuffer; + DataBlock.FileBuff.BuffSize = BuffSize; + + // SETUP BUFFER BLOCK FOR COMPRESSION BUFFER + DataBlock.cmpBuff.Buffer = pCompressedBuffer; + DataBlock.cmpBuff.BuffSize = BuffSize; + + wsprintf( szVerbose, "Compressing %u byte buffer to memory ", BuffSize ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + + // COMPRESS THE FILE + iStatus = implode( ReadBuffer, WriteBuffer, pScratchPad, &DataBlock, + &DataType, &DictSize ); + + // IF THERE WAS AN ERROR COMPRESSING FILE + if( iStatus || DataBlock.ErrorOccurred ) + { + // DISPLAY ERROR STRING IF ERROR OCCURRED IN IMPLODE + wsprintf( szVerbose, "Error occurred while imploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - COMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + DataBlock.dwCrc = ~DataBlock.dwCrc; + + // RETURN CRC + *pdwCrc = DataBlock.dwCrc; + + // RETURN COMPRESSED BUFFER SIZE + *pnCompressedSize = DataBlock.nCompressSize; + + wsprintf( szVerbose, "Compressed file to memory -> CRC = %08lX ", + DataBlock.dwCrc ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + } + + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: ExpandMemToMem() + * + * Purpose: To expand a compressed buffer to a buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file after uncompression + * pCompressedBuffer -> Pointer to buffer to place + * compressed data + * nCompressedSize -> Number of bytes in the compressed + * buffer + * pUncompressedBuffer -> Pointer to buffer to place + * uncompressed data + * BuffSize -> Size of the uncompressed buffer + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int ExpandMemToMem( HWND hWnd, TDC *pDC, DWORD *pdwCrc, + PBYTE pCompressedBuffer, UINT nCompressedSize, + PBYTE pUncompressedBuffer, UINT BuffSize ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + DATABLOCK DataBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + memset( &DataBlock, 0, sizeof(DataBlock) ); + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + DataBlock.mode = UNCOMPRESSING; + DataBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + // SETUP BUFFER BLOCK FOR COMPRESSION BUFFER + DataBlock.cmpBuff.Buffer = pCompressedBuffer; + DataBlock.cmpBuff.BuffSize = nCompressedSize; + + // SETUP BUFFER BLOCK FOR UNCOMPRESSION BUFFER + DataBlock.uncmpBuff.Buffer = pUncompressedBuffer; + DataBlock.uncmpBuff.BuffSize = BuffSize; + + wsprintf( szVerbose, "Compressed buffer size = %u ", nCompressedSize ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, "Uncompressing buffer to memory " ); + + // UNCOMPRESS THE FILE + iStatus = explode( ReadBuffer, WriteBuffer, pScratchPad, &DataBlock ); + + // IF THERE WAS AN ERROR UNCOMPRESSING FILE + if( iStatus || DataBlock.ErrorOccurred ) + { + // DISPLAY ERROR STRING IF ERROR OCCURRED IN IMPLODE + wsprintf( szVerbose, "Error occurred while exploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else // ELSE - UNCOMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + DataBlock.dwCrc = ~DataBlock.dwCrc; + + // RETURN CRC + *pdwCrc = DataBlock.dwCrc; + + wsprintf( szVerbose, "Uncompressed file to memory -> CRC = %08lX ", + DataBlock.dwCrc ); + pDC->TextOut( 10, (iLineCnt++ * 20) + 5, szVerbose ); + } + + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: MemToMemExample() + * + * Purpose: To load a file into memory. Then compress and uncompress + * the buffer in memory. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszFilename -> Name of file to load + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int MemToMemExample( HWND hWnd, TDC *pDC, PCHAR pszFilename ) +{ + TFile InFile; + int rc=1; // RETURN CODE + UINT BufferSize; + UINT cmpSize; + PBYTE pFileBuffer; // BUFFER FOR FILE DATA + PBYTE pCompressedBuffer; // BUFFER FOR THE COMPRESSED DATA + PBYTE pUncompressedBuffer; // BUFFER FOR THE UNCOMPRESSED DATA + DWORD cmpCrc; // CRC OF FILE BEFORE COMPRESSION + DWORD uncmpCrc; // CRC OF FILE AFTER UNCOMPRESSION + + + iLineCnt = 0; + + // OPEN THE FILE + if( !InFile.Open( pszFilename, TFile::ReadOnly, TFile::PermRdWr ) ) + { + MessageBox( hWnd, "Error opening file for compression", "Error", MB_OK ); + return 0; + } + + // CHECK IF FILE IS TOO LARGE + if( InFile.Length() > 64000U ) + { + MessageBox( hWnd, "File is too large to compress to memory", "Error", MB_OK ); + return 0; + } + + BufferSize = (UINT) InFile.Length(); + + // ALLOCATE BUFFER MEMORY + pFileBuffer = (PBYTE) new char[BufferSize]; + pCompressedBuffer = (PBYTE) new char[BufferSize]; + pUncompressedBuffer = (PBYTE) new char[BufferSize]; + + // IF SUCCESSFULLY ALLOCATED MEMORY + if( (pFileBuffer != NULL) && + (pCompressedBuffer != NULL) && + (pUncompressedBuffer != NULL) ) + { + // READ FILE + InFile.Read( pFileBuffer, BufferSize ); + + // IF COMPRESSED OK + if( CompressMemToMem( hWnd, pDC, &cmpCrc, &cmpSize, + pFileBuffer, pCompressedBuffer, BufferSize ) ) + { + // IF ERROR UNCOMPRESSING + if( !ExpandMemToMem( hWnd, pDC, &uncmpCrc, + pCompressedBuffer, cmpSize, + pUncompressedBuffer, BufferSize ) ) + { + MessageBox( hWnd, "Error uncompressing to memory", "Error", MB_OK ); + rc = 0; + } + } + else + { + MessageBox( hWnd, "Error compressing to memory", "Error", MB_OK ); + rc = 0; + } + } + + + if( pFileBuffer != NULL ) + { + delete pFileBuffer; + } + + if( pCompressedBuffer != NULL ) + { + delete pCompressedBuffer; + } + + if( pUncompressedBuffer != NULL ) + { + delete pUncompressedBuffer; + } + + return rc; +} + + diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/DCL.H b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/DCL.H new file mode 100644 index 0000000..0ea3138 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/DCL.H @@ -0,0 +1,10 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +int MemToMemExample( HWND hWnd, TDC *pDC, LPSTR lpszFilename ); diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/IMPBORLI.LIB b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/IMPBORLI.LIB new file mode 100644 index 0000000..9ef7765 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/IMPBORLI.LIB differ diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/IMPLODE.H b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MEM2MEM.IDE b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MEM2MEM.IDE new file mode 100644 index 0000000..9b1898b Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MEM2MEM.IDE differ diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMABD.CPP b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMABD.CPP new file mode 100644 index 0000000..f24049e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMABD.CPP @@ -0,0 +1,157 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include +#pragma hdrstop + +#if !defined(__FLAT__) +#include +#endif + +#include "mm2mmapp.h" +#include "mm2mmabd.h" + + +ProjectRCVersion::ProjectRCVersion (TModule *module) +{ + char appFName[255]; + char subBlockName[255]; + DWORD fvHandle; + UINT vSize; + + FVData = 0; + + module->GetModuleFileName(appFName, sizeof(appFName)); + OemToAnsi(appFName, appFName); + DWORD dwSize = ::GetFileVersionInfoSize(appFName, &fvHandle); + if (dwSize) { + FVData = (void FAR *)new char[(UINT)dwSize]; + if (::GetFileVersionInfo(appFName, fvHandle, dwSize, FVData)) { + // Copy string to buffer so if the -dc compiler switch (Put constant strings in code segments) + // is on VerQueryValue will work under Win16. This works around a problem in Microsoft's ver.dll + // which writes to the string pointed to by subBlockName. + strcpy(subBlockName, "\\VarFileInfo\\Translation"); + if (!::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&TransBlock, &vSize)) { + delete FVData; + FVData = 0; + } else + // Swap the words so wsprintf will print the lang-charset in the correct format. + *(DWORD *)TransBlock = MAKELONG(HIWORD(*(DWORD *)TransBlock), LOWORD(*(DWORD *)TransBlock)); + } + } +} + + +ProjectRCVersion::~ProjectRCVersion () +{ + if (FVData) + delete FVData; +} + + +bool ProjectRCVersion::GetProductName (LPSTR &prodName) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"ProductName"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&prodName, &vSize) : false; +} + + +bool ProjectRCVersion::GetProductVersion (LPSTR &prodVersion) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"ProductVersion"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&prodVersion, &vSize) : false; +} + + +bool ProjectRCVersion::GetCopyright (LPSTR ©right) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"LegalCopyright"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)©right, &vSize) : false; +} + + +bool ProjectRCVersion::GetDebug (LPSTR &debug) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"SpecialBuild"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&debug, &vSize) : false; +} + + +//{{mem2memAboutDlg Implementation}} + + +////////////////////////////////////////////////////////// +// mem2memAboutDlg +// ========== +// Construction/Destruction handling. +mem2memAboutDlg::mem2memAboutDlg (TWindow *parent, TResId resId, TModule *module) + : TDialog(parent, resId, module) +{ + // INSERT>> Your constructor code here. +} + + +mem2memAboutDlg::~mem2memAboutDlg () +{ + Destroy(); + + // INSERT>> Your destructor code here. +} + + +void mem2memAboutDlg::SetupWindow () +{ + LPSTR prodName = 0, prodVersion = 0, copyright = 0, debug = 0; + + // Get the static text for the value based on VERSIONINFO. + TStatic *versionCtrl = new TStatic(this, IDC_VERSION, 255); + TStatic *copyrightCtrl = new TStatic(this, IDC_COPYRIGHT, 255); + TStatic *debugCtrl = new TStatic(this, IDC_DEBUG, 255); + + TDialog::SetupWindow(); + + // Process the VERSIONINFO. + ProjectRCVersion applVersion(GetModule()); + + // Get the product name and product version strings. + if (applVersion.GetProductName(prodName) && applVersion.GetProductVersion(prodVersion)) { + // IDC_VERSION is the product name and version number, the initial value of IDC_VERSION is + // the word Version (in whatever language) product name VERSION product version. + char buffer[255]; + char versionName[128]; + + buffer[0] = '\0'; + versionName[0] = '\0'; + + versionCtrl->GetText(versionName, sizeof(versionName)); + wsprintf(buffer, "%s %s %s", prodName, versionName, prodVersion); + + versionCtrl->SetText(buffer); + } + + //Get the legal copyright string. + if (applVersion.GetCopyright(copyright)) + copyrightCtrl->SetText(copyright); + + // Only get the SpecialBuild text if the VERSIONINFO resource is there. + if (applVersion.GetDebug(debug)) + debugCtrl->SetText(debug); +} diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMABD.H b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMABD.H new file mode 100644 index 0000000..1ea0c5e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMABD.H @@ -0,0 +1,53 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#if !defined(__mm2mmabd_h) // Sentry, use file only if it's not already included. +#define __mm2mmabd_h + +#include +#pragma hdrstop + +#include "mm2mmapp.rh" // Definition of all resources. + + +//{{TDialog = mem2memAboutDlg}} +class mem2memAboutDlg : public TDialog { +public: + mem2memAboutDlg (TWindow *parent, TResId resId = IDD_ABOUT, TModule *module = 0); + virtual ~mem2memAboutDlg (); + +//{{mem2memAboutDlgVIRTUAL_BEGIN}} +public: + void SetupWindow (); +//{{mem2memAboutDlgVIRTUAL_END}} +}; //{{mem2memAboutDlg}} + + +// Reading the VERSIONINFO resource. +class ProjectRCVersion { +public: + ProjectRCVersion (TModule *module); + virtual ~ProjectRCVersion (); + + bool GetProductName (LPSTR &prodName); + bool GetProductVersion (LPSTR &prodVersion); + bool GetCopyright (LPSTR ©right); + bool GetDebug (LPSTR &debug); + +protected: + LPBYTE TransBlock; + void FAR *FVData; + +private: + // Don't allow this object to be copied. + ProjectRCVersion (const ProjectRCVersion &); + ProjectRCVersion & operator =(const ProjectRCVersion &); +}; + + +#endif // __mm2mmabd_h sentry. diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.CPP b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.CPP new file mode 100644 index 0000000..6ba50c8 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.CPP @@ -0,0 +1,208 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include +#pragma hdrstop + +#include "mm2mmapp.h" +#include "mm2mmedv.h" // Definition of client class. +#include "mm2mmabd.h" // Definition of about dialog. +#include "dcl.h" + +//{{mem2memApp Implementation}} + + + +//{{DOC_VIEW}} +DEFINE_DOC_TEMPLATE_CLASS(TFileDocument, mem2memEditView, DocType1); +//{{DOC_VIEW_END}} + +//{{DOC_MANAGER}} +DocType1 __dvt1("All Files (*.*)", "*.*", 0, "TXT", dtAutoDelete | dtUpdateDir); +//{{DOC_MANAGER_END}} + + +// +// Build a response table for all messages/commands handled +// by the application. +// +DEFINE_RESPONSE_TABLE1(mem2memApp, TApplication) +//{{mem2memAppRSP_TBL_BEGIN}} + EV_OWLVIEW(dnCreate, EvNewView), + EV_OWLVIEW(dnClose, EvCloseView), + EV_COMMAND(CM_HELPABOUT, CmHelpAbout), +//{{mem2memAppRSP_TBL_END}} +END_RESPONSE_TABLE; + + +////////////////////////////////////////////////////////// +// mem2memApp +// ===== +// +mem2memApp::mem2memApp () : TApplication("mem2mem") +{ + SetDocManager(new TDocManager(dmSDI, this)); + + // INSERT>> Your constructor code here. +} + + +mem2memApp::~mem2memApp () +{ + // INSERT>> Your destructor code here. +} + + + + +////////////////////////////////////////////////////////// +// mem2memApp +// ===== +// Application intialization. +// +void mem2memApp::InitMainWindow () +{ + if (nCmdShow != SW_HIDE) + nCmdShow = (nCmdShow != SW_SHOWMINNOACTIVE) ? SW_SHOWNORMAL : nCmdShow; + + SDIDecFrame *frame = new SDIDecFrame(0, GetName(), 0, true, this); + + // + // Assign ICON w/ this application. + // + frame->SetIcon(this, IDI_SDIAPPLICATION); + + // + // Menu associated with window and accelerator table associated with table. + // + frame->AssignMenu(SDI_MENU); + + // + // Associate with the accelerator table. + // + frame->Attr.AccelTable = SDI_MENU; + + + TStatusBar *sb = new TStatusBar(frame, TGadget::Recessed, + TStatusBar::CapsLock | + TStatusBar::NumLock | + TStatusBar::ScrollLock | + TStatusBar::Overtype); + frame->Insert(*sb, TDecoratedFrame::Bottom); + + SetMainWindow(frame); + + frame->SetMenuDescr(TMenuDescr(SDI_MENU)); + +} + + +////////////////////////////////////////////////////////// +// mem2memApp +// ===== +// Response Table handlers: +// +void mem2memApp::EvNewView (TView& view) +{ + GetMainWindow()->SetClientWindow(view.GetWindow()); + if (!view.IsOK()) + GetMainWindow()->SetClientWindow(0); + else if (view.GetViewMenu()) + GetMainWindow()->MergeMenu(*view.GetViewMenu()); +} + + +void mem2memApp::EvCloseView (TView&) +{ + GetMainWindow()->SetClientWindow(0); + GetMainWindow()->SetCaption("mem2mem"); +} + + +// +// Build a response table for all messages/commands handled +// by the application. +// +DEFINE_RESPONSE_TABLE1(SDIDecFrame, TDecoratedFrame) +//{{SDIDecFrameRSP_TBL_BEGIN}} + EV_COMMAND(CM_TEST_DCL, OnTestDcl), + EV_COMMAND_ENABLE(CM_TEST_DCL, OnTestDclEnable), +//{{SDIDecFrameRSP_TBL_END}} +END_RESPONSE_TABLE; + + +//{{SDIDecFrame Implementation}} + + +SDIDecFrame::SDIDecFrame (TWindow *parent, const char far *title, TWindow *clientWnd, bool trackMenuSelection, TModule *module) + : TDecoratedFrame(parent, title, clientWnd, trackMenuSelection, module) +{ + // INSERT>> Your constructor code here. + +} + + +SDIDecFrame::~SDIDecFrame () +{ + // INSERT>> Your destructor code here. + +} + + +////////////////////////////////////////////////////////// +// mem2memApp +// =========== +// Menu Help About mem2mem.exe command +void mem2memApp::CmHelpAbout () +{ + // + // Show the modal dialog. + // + mem2memAboutDlg(GetMainWindow()).Execute(); +} + + +int OwlMain (int , char* []) +{ + try { + mem2memApp app; + return app.Run(); + } + catch (xmsg& x) { + ::MessageBox(0, x.why().c_str(), "Exception", MB_OK); + } + + return -1; +} + +void SDIDecFrame::OnTestDcl () +{ + TOpenSaveDialog::TData data( OFN_FILEMUSTEXIST|OFN_HIDEREADONLY| + OFN_PATHMUSTEXIST|OFN_NOCHANGEDIR, + "All Files (*.*)|*.*|", 0, "", "*" ); + + if( TFileOpenDialog( this, data ).Execute() == IDOK ) + { + TWindow *ClientWnd = GetClientWindow(); + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + TWindowDC dc( ClientWnd->HWindow ); + TColor bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + MemToMemExample( ClientWnd->HWindow, &dc, data.FileName ); + } +} + + +void SDIDecFrame::OnTestDclEnable (TCommandEnabler &tce) +{ + tce.Enable( TRUE ); +} + diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.DEF b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.DEF new file mode 100644 index 0000000..b60e724 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.DEF @@ -0,0 +1,8 @@ +NAME mem2mem + +DESCRIPTION 'mem2mem Application' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE +HEAPSIZE 4096 +STACKSIZE 8192 diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.H b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.H new file mode 100644 index 0000000..a6a2d39 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.H @@ -0,0 +1,60 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#if !defined(__mm2mmapp_h) // Sentry, use file only if it's not already included. +#define __mm2mmapp_h + +#include +#pragma hdrstop + + +#include "mm2mmapp.rh" // Definition of all resources. + + +// +// FrameWindow must be derived to override Paint for Preview and Print. +// +//{{TDecoratedFrame = SDIDecFrame}} +class SDIDecFrame : public TDecoratedFrame { +public: + SDIDecFrame (TWindow *parent, const char far *title, TWindow *clientWnd, bool trackMenuSelection = false, TModule *module = 0); + ~SDIDecFrame (); + +//{{SDIDecFrameRSP_TBL_BEGIN}} +protected: + void OnTestDcl (); + void OnTestDclEnable (TCommandEnabler &tce); +//{{SDIDecFrameRSP_TBL_END}} +DECLARE_RESPONSE_TABLE(SDIDecFrame); +}; //{{SDIDecFrame}} + + +//{{TApplication = mem2memApp}} +class mem2memApp : public TApplication { +private: + +public: + mem2memApp (); + virtual ~mem2memApp (); + +//{{mem2memAppVIRTUAL_BEGIN}} +public: + virtual void InitMainWindow (); +//{{mem2memAppVIRTUAL_END}} + +//{{mem2memAppRSP_TBL_BEGIN}} +protected: + void EvNewView (TView& view); + void EvCloseView (TView& view); + void CmHelpAbout (); +//{{mem2memAppRSP_TBL_END}} +DECLARE_RESPONSE_TABLE(mem2memApp); +}; //{{mem2memApp}} + + +#endif // __mm2mmapp_h sentry. diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.RC b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.RC new file mode 100644 index 0000000..21c54ba --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.RC @@ -0,0 +1,389 @@ +/* Project mem2mem + PKWARE, INC. + Copyright © 1995. All Rights Reserved. + + SUBSYSTEM: mem2mem.exe Application + FILE: mm2mmapp.rc + AUTHOR: + + + OVERVIEW + ======== + All resources defined here. +*/ + +#if !defined(WORKSHOP_INVOKED) +#include +#endif +#include "mm2mmapp.rh" + +SDI_MENU MENU +{ + POPUP "&File" + { + MENUITEM "&Test Dcl", CM_TEST_DCL + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", CM_EXIT + } + + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + POPUP "&Help" + { + MENUITEM "&About...", CM_HELPABOUT + } + +} + + +// Accelerator table for short-cut to menu commands. (include\owl\editfile.rc) +SDI_MENU ACCELERATORS +BEGIN + VK_DELETE, CM_EDITDELETE, VIRTKEY + VK_DELETE, CM_EDITCUT, VIRTKEY, SHIFT + VK_INSERT, CM_EDITCOPY, VIRTKEY, CONTROL + VK_INSERT, CM_EDITPASTE, VIRTKEY, SHIFT + VK_DELETE, CM_EDITCLEAR, VIRTKEY, CONTROL + VK_BACK, CM_EDITUNDO, VIRTKEY, ALT + VK_F3, CM_EDITFINDNEXT, VIRTKEY +END + + +// Menu merged in when TEditView is active, notice the extra MENUITEM SEPARATORs which are +// for menu negotation. These separators are used as group markers by OWL. +IDM_EDITVIEW MENU +{ + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR +} + + +// Menu merged in when TListView is active, notice the extra MENUITEM SEPARATORs which are +// for menu negotation. These separators are used as group markers by OWL. +IDM_LISTVIEW MENU +{ + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR +} + + +IDM_DOCMANAGERFILE MENU +{ + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", CM_EXIT +} + + +// +// Table of help hints displayed in the status bar. +// +STRINGTABLE +BEGIN + -1, "File/document operations" + CM_FILENEW, "Creates a new document" + CM_FILEOPEN, "Opens an existing document" + CM_VIEWCREATE, "Create a new view for this document" + CM_FILEREVERT, "Reverts changes to last document save" + CM_FILECLOSE, "Close this document" + CM_FILESAVE, "Saves this document" + CM_FILESAVEAS, "Saves this document with a new name" + CM_EXIT, "Quits mem2memApp and prompts to save the documents" + CM_EDITUNDO-1, "Edit operations" + CM_EDITUNDO, "Reverses the last operation" + CM_EDITCUT, "Cuts the selection and puts it on the Clipboard" + CM_EDITCOPY, "Copies the selection and puts it on the Clipboard" + CM_EDITPASTE, "Inserts the clipboard contents at the insertion point" + CM_EDITDELETE, "Deletes the selection" + CM_EDITCLEAR, "Clear the document" + CM_EDITADD, "Insert a new line" + CM_EDITEDIT, "Edit the current line" + CM_EDITFIND-1, "Search/replace operations" + CM_EDITFIND, "Finds the specified text" + CM_EDITREPLACE, "Finds the specified text and changes it" + CM_EDITFINDNEXT, "Finds the next match" + CM_HELPABOUT-1, "Access About" + CM_HELPABOUT, "About the mem2mem application" +END + + +// +// OWL string table +// + +// EditFile (include\owl\editfile.rc and include\owl\editsear.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_CANNOTFIND, "Cannot find ""%s""." + IDS_UNABLEREAD, "Unable to read file %s from disk." + IDS_UNABLEWRITE, "Unable to write file %s to disk." + IDS_FILECHANGED, "The text in the %s file has changed.\n\nDo you want to save the changes?" + IDS_FILEFILTER, "Text files (*.TXT)|*.TXT|AllFiles (*.*)|*.*|" +END + + +// ListView (include\owl\listview.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_LISTNUM, "Line number %d" +END + + +// Doc/View (include\owl\docview.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_DOCMANAGERFILE, "&File" + IDS_DOCLIST, "--Document Type--" + IDS_VIEWLIST, "--View Type--" + IDS_UNTITLED, "Document" + IDS_UNABLEOPEN, "Unable to open document." + IDS_UNABLECLOSE, "Unable to close document." + IDS_READERROR, "Document read error." + IDS_WRITEERROR, "Document write error." + IDS_DOCCHANGED, "The document has been changed.\n\nDo you want to save the changes?" + IDS_NOTCHANGED, "The document has not been changed." + IDS_NODOCMANAGER, "Document Manager not present." + IDS_NOMEMORYFORVIEW, "Insufficient memory for view." + IDS_DUPLICATEDOC, "Document already loaded." +END + + +// Exception string resources (include\owl\except.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_OWLEXCEPTION, "ObjectWindows Exception" + IDS_UNHANDLEDXMSG, "Unhandled Exception" + IDS_OKTORESUME, "OK to resume?" + IDS_UNKNOWNEXCEPTION, "Unknown exception" + + IDS_UNKNOWNERROR, "Unknown error" + IDS_NOAPP, "No application object" + IDS_OUTOFMEMORY, "Out of memory" + IDS_INVALIDMODULE, "Invalid module specified for window" + IDS_INVALIDMAINWINDOW, "Invalid MainWindow" + IDS_VBXLIBRARYFAIL, "VBX Library init failure" + + IDS_INVALIDWINDOW, "Invalid window %s" + IDS_INVALIDCHILDWINDOW, "Invalid child window %s" + IDS_INVALIDCLIENTWINDOW, "Invalid client window %s" + + IDS_CLASSREGISTERFAIL, "Class registration fail for window %s" + IDS_CHILDREGISTERFAIL, "Child class registration fail for window %s" + IDS_WINDOWCREATEFAIL, "Create fail for window %s" + IDS_WINDOWEXECUTEFAIL, "Execute fail for window %s" + IDS_CHILDCREATEFAIL, "Child create fail for window %s" + + IDS_MENUFAILURE, "Menu creation failure" + IDS_VALIDATORSYNTAX, "Validator syntax error" + IDS_PRINTERERROR, "Printer error" + + IDS_LAYOUTINCOMPLETE, "Incomplete layout constraints specified in window %s" + IDS_LAYOUTBADRELWIN, "Invalid relative window specified in layout constraint in window %s" + + IDS_GDIFAILURE, "GDI failure" + IDS_GDIALLOCFAIL, "GDI allocate failure" + IDS_GDICREATEFAIL, "GDI creation failure" + IDS_GDIRESLOADFAIL, "GDI resource load failure" + IDS_GDIFILEREADFAIL, "GDI file read failure" + IDS_GDIDELETEFAIL, "GDI object %X delete failure" + IDS_GDIDESTROYFAIL, "GDI object %X destroy failure" + IDS_INVALIDDIBHANDLE, "Invalid DIB handle %X" +END + + +// General Window's status bar messages. (include\owl\statusba.rc) +STRINGTABLE +BEGIN + IDS_MODES "EXT|CAPS|NUM|SCRL|OVR|REC" + IDS_MODESOFF " | | | | | " + SC_SIZE, "Changes the size of the window" + SC_MOVE, "Moves the window to another position" + SC_MINIMIZE, "Reduces the window to an icon" + SC_MAXIMIZE, "Enlarges the window to it maximum size" + SC_RESTORE, "Restores the window to its previous size" + SC_CLOSE, "Closes the window" + SC_TASKLIST, "Opens task list" + SC_NEXTWINDOW, "Switches to next window" +END + + +// Validator messages (include\owl\validate.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_VALPXPCONFORM "Input does not conform to picture:\n""%s""" + IDS_VALINVALIDCHAR "Invalid character in input" + IDS_VALNOTINRANGE "Value is not in the range %ld to %ld." + IDS_VALNOTINLIST "Input is not in valid-list" +END + + +// +// Misc application definitions +// + +// Application ICON +IDI_SDIAPPLICATION ICON "appldocv.ico" + + +// About box. +IDD_ABOUT DIALOG 12, 17, 204, 65 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About mem2mem" +FONT 8, "MS Sans Serif" +BEGIN + CTEXT "Version", IDC_VERSION, 2, 14, 200, 8, SS_NOPREFIX + CTEXT "Memory To Memory Compression", -1, 2, 4, 200, 8, SS_NOPREFIX + CTEXT "", IDC_COPYRIGHT, 2, 27, 200, 17, SS_NOPREFIX + RTEXT "", IDC_DEBUG, 136, 55, 66, 8, SS_NOPREFIX + ICON IDI_SDIAPPLICATION, -1, 2, 2, 34, 34 + DEFPUSHBUTTON "OK", IDOK, 82, 48, 40, 14 +END + + +// TInputDialog class dialog box. +IDD_INPUTDIALOG DIALOG 20, 24, 180, 64 +STYLE WS_POPUP | WS_CAPTION | DS_SETFONT +FONT 8, "Helv" +BEGIN + LTEXT "", ID_PROMPT, 10, 8, 160, 10, SS_NOPREFIX + CONTROL "", ID_INPUT, "EDIT", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL, 10, 20, 160, 12 + DEFPUSHBUTTON "&OK", IDOK, 47, 42, 40, 14 + PUSHBUTTON "&Cancel", IDCANCEL, 93, 42, 40, 14 +END + + +// Horizontal slider thumb bitmap for TSlider and VSlider (include\owl\slider.rc) +IDB_HSLIDERTHUMB BITMAP PRELOAD MOVEABLE DISCARDABLE +BEGIN + '42 4D 66 01 00 00 00 00 00 00 76 00 00 00 28 00' + '00 00 12 00 00 00 14 00 00 00 01 00 04 00 00 00' + '00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 10 00 00 00 00 00 00 00 00 00 C0 00 00 C0' + '00 00 00 C0 C0 00 C0 00 00 00 C0 00 C0 00 C0 C0' + '00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF' + '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' + '00 00 FF FF FF 00 BB BB 0B BB BB BB B0 BB BB 00' + '00 00 BB B0 80 BB BB BB 08 0B BB 00 00 00 BB 08' + 'F8 0B BB B0 87 70 BB 00 00 00 B0 8F F8 80 BB 08' + '77 77 0B 00 00 00 08 F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 88 00 88 77 77 70 00 00 00 0F F8' + '88 88 00 88 88 87 70 00 00 00 0F F7 77 88 00 88' + '77 77 70 00 00 00 0F F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 88 00 88 77 77 70 00 00 00 0F F8' + '88 88 00 88 88 87 70 00 00 00 0F F7 77 88 00 88' + '77 77 70 00 00 00 0F F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 88 00 88 77 77 70 00 00 00 0F F8' + '88 88 00 88 88 87 70 00 00 00 0F F7 77 88 00 88' + '77 77 70 00 00 00 0F F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 78 00 88 77 77 70 00 00 00 0F FF' + 'FF FF 00 88 88 88 80 00 00 00 B0 00 00 00 BB 00' + '00 00 0B 00 00 00' +END + + +// Vertical slider thumb bitmap for TSlider and HSlider (include\owl\slider.rc) +IDB_VSLIDERTHUMB BITMAP PRELOAD MOVEABLE DISCARDABLE +BEGIN + '42 4D 2A 01 00 00 00 00 00 00 76 00 00 00 28 00' + '00 00 28 00 00 00 09 00 00 00 01 00 04 00 00 00' + '00 00 B4 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 10 00 00 00 00 00 00 00 00 00 C0 00 00 C0' + '00 00 00 C0 C0 00 C0 00 00 00 C0 00 C0 00 C0 C0' + '00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF' + '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' + '00 00 FF FF FF 00 B0 00 00 00 00 00 00 00 00 0B' + 'B0 00 00 00 00 00 00 00 00 0B 0F 88 88 88 88 88' + '88 88 88 80 08 88 88 88 88 88 88 88 88 80 0F 77' + '77 77 77 77 77 77 77 80 08 77 77 77 77 77 77 77' + '77 80 0F 77 FF FF FF FF FF FF F7 80 08 77 FF FF' + 'FF FF FF FF F7 80 0F 70 00 00 00 00 00 00 77 80' + '08 70 00 00 00 00 00 00 77 80 0F 77 77 77 77 77' + '77 77 77 80 08 77 77 77 77 77 77 77 77 80 0F 77' + '77 77 77 77 77 77 77 80 08 77 77 77 77 77 77 77' + '77 80 0F FF FF FF FF FF FF FF FF F0 08 88 88 88' + '88 88 88 88 88 80 B0 00 00 00 00 00 00 00 00 0B' + 'B0 00 00 00 00 00 00 00 00 0B' +END + + +// Version info. +// +#if !defined(__DEBUG_) +// Non-Debug VERSIONINFO +1 VERSIONINFO LOADONCALL MOVEABLE +FILEVERSION 1, 0, 0, 0 +PRODUCTVERSION 1, 0, 0, 0 +FILEFLAGSMASK 0 +FILEFLAGS VS_FFI_FILEFLAGSMASK +FILEOS VOS__WINDOWS16 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + // Language type = U.S. English (0x0409) and Character Set = Windows, Multilingual(0x04e4) + BLOCK "040904E4" // Matches VarFileInfo Translation hex value. + BEGIN + VALUE "CompanyName", "PKWARE, INC.\000" + VALUE "FileDescription", "mem2mem for Windows\000" + VALUE "FileVersion", "1.0\000" + VALUE "InternalName", "mem2mem\000" + VALUE "LegalCopyright", "Copyright © 1995. All Rights Reserved.\000" + VALUE "LegalTrademarks", "Windows (TM) is a trademark of Microsoft Corporation\000" + VALUE "OriginalFilename", "mem2mem.EXE\000" + VALUE "ProductName", "mem2mem\000" + VALUE "ProductVersion", "1.0\000" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04e4 // U.S. English(0x0409) & Windows Multilingual(0x04e4) 1252 + END + +END +#else + +// Debug VERSIONINFO +1 VERSIONINFO LOADONCALL MOVEABLE +FILEVERSION 1, 0, 0, 0 +PRODUCTVERSION 1, 0, 0, 0 +FILEFLAGSMASK VS_FF_DEBUG | VS_FF_PRERELEASE | VS_FF_PATCHED | VS_FF_PRIVATEBUILD | VS_FF_SPECIALBUILD +FILEFLAGS VS_FFI_FILEFLAGSMASK +FILEOS VOS__WINDOWS16 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + // Language type = U.S. English (0x0409) and Character Set = Windows, Multilingual(0x04e4) + BLOCK "040904E4" // Matches VarFileInfo Translation hex value. + BEGIN + VALUE "CompanyName", "PKWARE, INC.\000" + VALUE "FileDescription", "mem2mem for Windows\000" + VALUE "FileVersion", "1.0\000" + VALUE "InternalName", "mem2mem\000" + VALUE "LegalCopyright", "Copyright © 1995. All Rights Reserved.\000" + VALUE "LegalTrademarks", "Windows (TM) is a trademark of Microsoft Corporation\000" + VALUE "OriginalFilename", "mem2mem.EXE\000" + VALUE "ProductName", "mem2mem\000" + VALUE "ProductVersion", "1.0\000" + VALUE "SpecialBuild", "Debug Version\000" + VALUE "PrivateBuild", "Built by \000" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04e4 // U.S. English(0x0409) & Windows Multilingual(0x04e4) 1252 + END + +END +#endif diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.RH b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.RH new file mode 100644 index 0000000..98fdb0d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMAPP.RH @@ -0,0 +1,198 @@ +//#if !defined(__mm2mmapp_rh) // Sentry use file only if it's not already included. +//#define __mm2mmapp_rh + +/* Project mem2mem + PKWARE, INC. + Copyright © 1995. All Rights Reserved. + + SUBSYSTEM: mem2mem.exe Application + FILE: mm2mmapp.h + AUTHOR: + + + OVERVIEW + ======== + Constant definitions for all resources defined in mm2mmapp.rc. +*/ + + +// +// IDHELP BorButton for BWCC dialogs. +// +#define IDHELP 998 // Id of help button + + +// +// Application specific definitions: +// +#define IDI_SDIAPPLICATION 1001 // Application icon + +#define SDI_MENU 100 // Menu resource ID and Accelerator IDs +#define CM_TEST_DCL 101 + +#define IDM_DOCMANAGERFILE 32401 // Menu for DocManager merging. +#define IDM_EDITVIEW 32581 // Menu for TEditView merging. +#define IDM_LISTVIEW 32582 // Menu for TListView merging. + +// +// CM_FILEnnnn commands (include\owl\editfile.rh except for CM_FILEPRINTPREVIEW) +// +#define CM_FILENEW 24331 // SDI New +#define CM_FILEOPEN 24332 // SDI Open +#define CM_FILECLOSE 24339 +#define CM_FILESAVE 24333 +#define CM_FILESAVEAS 24334 +#define CM_FILEREVERT 24335 +#define CM_VIEWCREATE 24341 + + +// +// Window commands (include\owl\window.rh) +// +#define CM_EXIT 24310 + + +// +// CM_EDITnnnn commands (include\owl\window.rh) +// +#define CM_EDITUNDO 24321 +#define CM_EDITCUT 24322 +#define CM_EDITCOPY 24323 +#define CM_EDITPASTE 24324 +#define CM_EDITDELETE 24325 +#define CM_EDITCLEAR 24326 +#define CM_EDITADD 24327 +#define CM_EDITEDIT 24328 + + +// +// Search menu commands (include\owl\editsear.rh) +// +#define CM_EDITFIND 24351 +#define CM_EDITREPLACE 24352 +#define CM_EDITFINDNEXT 24353 + + +// +// Help menu commands. +// +#define CM_HELPABOUT 2009 + + +// +// About Dialogs +// +#define IDD_ABOUT 22000 +#define IDC_VERSION 22001 +#define IDC_COPYRIGHT 22002 +#define IDC_DEBUG 22003 + + +// +// OWL defined strings +// + +// Statusbar +#define IDS_MODES 32530 +#define IDS_MODESOFF 32531 + + +// EditFile +#define IDS_UNABLEREAD 32551 +#define IDS_UNABLEWRITE 32552 +#define IDS_FILECHANGED 32553 +#define IDS_FILEFILTER 32554 + +// EditSearch +#define IDS_CANNOTFIND 32540 + + +// +// General & application exception messages (include\owl\except.rh) +// +#define IDS_UNKNOWNEXCEPTION 32767 +#define IDS_OWLEXCEPTION 32766 +#define IDS_OKTORESUME 32765 +#define IDS_UNHANDLEDXMSG 32764 +#define IDS_UNKNOWNERROR 32763 +#define IDS_NOAPP 32762 +#define IDS_OUTOFMEMORY 32761 +#define IDS_INVALIDMODULE 32760 +#define IDS_INVALIDMAINWINDOW 32759 +#define IDS_VBXLIBRARYFAIL 32758 + +// +// Owl 1 compatibility messages +// +#define IDS_INVALIDWINDOW 32756 +#define IDS_INVALIDCHILDWINDOW 32755 +#define IDS_INVALIDCLIENTWINDOW 32754 + +// +// TXWindow messages +// +#define IDS_CLASSREGISTERFAIL 32749 +#define IDS_CHILDREGISTERFAIL 32748 +#define IDS_WINDOWCREATEFAIL 32747 +#define IDS_WINDOWEXECUTEFAIL 32746 +#define IDS_CHILDCREATEFAIL 32745 + +#define IDS_MENUFAILURE 32744 +#define IDS_VALIDATORSYNTAX 32743 +#define IDS_PRINTERERROR 32742 + +#define IDS_LAYOUTINCOMPLETE 32741 +#define IDS_LAYOUTBADRELWIN 32740 + +// +// TXGdi messages +// +#define IDS_GDIFAILURE 32739 +#define IDS_GDIALLOCFAIL 32738 +#define IDS_GDICREATEFAIL 32737 +#define IDS_GDIRESLOADFAIL 32736 +#define IDS_GDIFILEREADFAIL 32735 +#define IDS_GDIDELETEFAIL 32734 +#define IDS_GDIDESTROYFAIL 32733 +#define IDS_INVALIDDIBHANDLE 32732 + + +// ListView (include\owl\listview.rh) +#define IDS_LISTNUM 32584 + + +// DocView (include\owl\docview.rh) +#define IDS_DOCMANAGERFILE 32500 +#define IDS_DOCLIST 32501 +#define IDS_VIEWLIST 32502 +#define IDS_UNTITLED 32503 +#define IDS_UNABLEOPEN 32504 +#define IDS_UNABLECLOSE 32505 +#define IDS_READERROR 32506 +#define IDS_WRITEERROR 32507 +#define IDS_DOCCHANGED 32508 +#define IDS_NOTCHANGED 32509 +#define IDS_NODOCMANAGER 32510 +#define IDS_NOMEMORYFORVIEW 32511 +#define IDS_DUPLICATEDOC 32512 + + +// TInputDialog DIALOG resource (include\owl\inputdia.rh) +#define IDD_INPUTDIALOG 32514 +#define ID_PROMPT 4091 +#define ID_INPUT 4090 + + +// TSlider bitmaps (horizontal and vertical) (include\owl\slider.rh) +#define IDB_HSLIDERTHUMB 32000 +#define IDB_VSLIDERTHUMB 32001 + + +// Validation messages (include\owl\validate.rh) +#define IDS_VALPXPCONFORM 32520 +#define IDS_VALINVALIDCHAR 32521 +#define IDS_VALNOTINRANGE 32522 +#define IDS_VALNOTINLIST 32523 + + +//#endif // __mm2mmapp_rh sentry. diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMEDV.CPP b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMEDV.CPP new file mode 100644 index 0000000..959b5b9 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMEDV.CPP @@ -0,0 +1,38 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include +#pragma hdrstop + +#include "mm2mmapp.h" +#include "mm2mmedv.h" + +#include + + +//{{mem2memEditView Implementation}} + + +////////////////////////////////////////////////////////// +// mem2memEditView +// ========== +// Construction/Destruction handling. +mem2memEditView::mem2memEditView (TDocument& doc, TWindow* parent) + : TEditView(doc, parent) +{ + // INSERT>> Your constructor code here. + +} + + +mem2memEditView::~mem2memEditView () +{ + // INSERT>> Your destructor code here. + +} diff --git a/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMEDV.H b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMEDV.H new file mode 100644 index 0000000..f734738 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/MEM2MEM/MM2MMEDV.H @@ -0,0 +1,27 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#if !defined(__mm2mmedv_h) // Sentry, use file only if it's not already included. +#define __mm2mmedv_h + +#include +#pragma hdrstop + + +#include "mm2mmapp.rh" // Definition of all resources. + + +//{{TEditView = mem2memEditView}} +class mem2memEditView : public TEditView { +public: + mem2memEditView (TDocument& doc, TWindow* parent = 0); + virtual ~mem2memEditView (); +}; //{{mem2memEditView}} + + +#endif // __mm2mmedv_h sentry. diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/APPLDOCV.ICO b/Storm/PKWARE/EXAMPLES/OWL/SPAN/APPLDOCV.ICO new file mode 100644 index 0000000..b4843af Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/OWL/SPAN/APPLDOCV.ICO differ diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/DCL.CPP b/Storm/PKWARE/EXAMPLES/OWL/SPAN/DCL.CPP new file mode 100644 index 0000000..bf26645 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/DCL.CPP @@ -0,0 +1,939 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +/* + * DCL.cpp - File to call various DCL DLL functions + */ + +#include +#include +#include "implode.h" + +#include +#include +#include +#include + +#define TEMPFILENAME "~~~.$$$" // TEMPORARY FILENAME TO CREATE +#define APPENDBUFSIZE 32000 // SIZE OF BUFFER TO ALLOCATE FOR APPENDING + // A COMPRESSED FILE TO .MCF FILE + +typedef enum +{ + COMPRESSING = 1, + UNCOMPRESSING +} FILEMODE; + +typedef enum +{ + NO_ERRORS = 0, + ERROR_OCCURRED +} ERRORFLAG; + + +// STRUCT TO PASS TO THE FILE IO FUNCTIONS +typedef struct +{ + TFile *InFile; + TFile *OutFile; + TDC *pDC; + UINT nPrevNdx; + UINT nCnt; + DWORD dwCompressSize; + FILEMODE mode; + ERRORFLAG ErrorOccurred; + DWORD dwCrc; +}IOFILEBLOCK, *PIOFILEBLOCK; + +// FOUR LETTER IDENTIFIER TO IDENTIFY A FILE AS +// A .MCF (MULTIPLE COMPRESSED FILES) FILE +char MCF_FILEHEADER[] = { "MCFX" }; + +#pragma pack(2) + +// HEADER FOR EACH FILE COMPRESSED INTO THE .MCF FILE +typedef struct +{ + DWORD dwCompressSize; // SIZE OF FILE COMPRESSED + DWORD dwCrc; // THE CRC OF THE FILE BEFORE COMPRESSION + char filename[13]; // NAME OF THE FILE +}CMP_FILEHEADER, *PCMP_FILEHEADER; + +#pragma pack(8) + +/* + * FORMAT OF .MCF FILE: + * + * .MCF FILEHEADER => MCFX + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * COMPRESSED FILE FILEHEADER => { CMP_FILEHEADER } + * FOLLOWED BY { ... COMPRESSED FILE DATA ... } + * AND SO ON + * + */ + +static char *pszActiveString[] = { "|", "/", "-", "\\" }; + +UINT DataType = CMP_ASCII; // GLOBAL FOR DATA TYPE FOR COMPRESSION +UINT DictSize = 4096; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +static PCHAR pszFilename; // NAME OF THE .MCF FILE + + +/********************************************************************* + * + * Function: ProcessMessages() + * + * Purpose: To allow Windows to process window messages which + * allows the user to multitask will compressing and + * uncompressing files. + * + * Returns: Nothing + * + *********************************************************************/ +void ProcessMessages(void) +{ + MSG msg; + + while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { + if (msg.message == WM_QUIT) + return; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + + +/********************************************************************* + * + * Function: ReadFromDisk() + * + * Purpose: To read data from disk, and prompt user for another + * disk when needed. This function makes a large assumption + * that if when reading a header zero bytes are read, then + * EOF has been reached. + * + * Parameters: Infile -> Pointer to already opened .MCF file + * pBuffer -> input buffer + * nSize -> number of bytes to read + * numread -> pointer to return actual number of bytes read + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred (A FileException is thrown) + * + *********************************************************************/ +int ReadFromDisk( TFile *InFile, PCHAR pBuffer, UINT nSize, UINT *numread, + BOOL ReadingHeader ) +{ + UINT bytesread; + + // READ DATA FROM DISK + *numread = bytesread = InFile->Read( pBuffer, nSize ); + + // IF READING A HEADER AND READ 0 BYTES, THEN ASSUME THIS IS THE END + if( bytesread == 0 && ReadingHeader ) + { + return 1; + } + + // IF COULD NOT READ ALL BYTES + if( bytesread < nSize ) + { + // CALCULATE NUMBER OF BYTES TO READ + nSize -= bytesread; + + // CLOSE THE FILE + InFile->Close(); + + // PROMPT USER FOR ANOTHER DISK + MessageBox( NULL, "Insert Next Disk", "Uncompress", MB_OK ); + + // OPEN .MCF FILE ON NEW DISK + if( !InFile->Open( pszFilename, + TFile::ReadOnly, TFile::PermRdWr ) ) + { + return 0; + } + + // READ DATA FROM DISK + bytesread = InFile->Read( (pBuffer + bytesread), nSize ); + + *numread += bytesread; + } + + return 1; +} + + +/********************************************************************* + * + * Function: ProcessInBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * read requests. If compressing, then the data read is + * in uncompressed form. If compressing, then the data + * read is data that was previously compressed. This + * function is called until zero is returned. + * + * Parameters: buffer -> Address of buffer to read the data into + * iSize -> Number of bytes to read into buffer + * dwParam -> User-defined parameter, in this case a + * pointer to the IOFILEBLOCK + * + * Returns: Number of bytes actually read, or zero on EOF + * + *********************************************************************/ +UINT ProcessInBuffer( PCHAR buffer, UINT *iSize, void *pParam ) +{ + PIOFILEBLOCK pFileIOBlock; + UINT iRead; + UINT ndx; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + if( pFileIOBlock->ErrorOccurred ) + { + return 0; + } + + // DISPLAY ROTATING LINE + ndx = (pFileIOBlock->nCnt >> 4) & 3; + if( ndx != pFileIOBlock->nPrevNdx ) + { + pFileIOBlock->pDC->TextOut( 10,2, pszActiveString[ndx] ); + pFileIOBlock->nPrevNdx = ndx; + } + pFileIOBlock->nCnt++; + + // THIS FUNCTION MAY ASK FOR UP TO 4K OF DATA AT A TIME. IF YOUR + // ARCHIVE FILE CONTAINS SEVERAL COMPRESSED FILES, YOU MAY READ TOO + // MUCH. FOR EXAMPLE, YOUR FIRST COMPRESSED FILE IN THE ARCHIVE MAY + // BE 100 BYTES. SO YOU DO NOT WANT TO READ MORE THAN 100 BYTES OR + // YOU WILL BE UNABLE TO UNCOMPRESS THE SECOND FILE, SINCE YOU WILL + // NOT BE LOCATED AT THE BEGINNING OF THE FILE ANY LONGER. + // WE WILL USE THE VARIABLE "dwCompressSize" TO CHECK FOR THIS + // CONDITION. + if( pFileIOBlock->mode == UNCOMPRESSING ) + { + // IF DCL REQUESTED MORE BYTES THAN ARE LEFT IN COMPRESSED FILE, THEN + // SET THE NUMBER OF BYTES TO READ TO THE AMOUNT LEFT IN THE BUFFER + if( (DWORD) *iSize > pFileIOBlock->dwCompressSize ) + *iSize = (UINT) pFileIOBlock->dwCompressSize; + + pFileIOBlock->dwCompressSize -= (DWORD) *iSize; + + // READ COMPRESSED FILE FILEHEADER + if( !ReadFromDisk( pFileIOBlock->InFile, buffer, *iSize, &iRead, FALSE ) ) + { + pFileIOBlock->ErrorOccurred = ERROR_OCCURRED; + return 0; + } + } + else + { + // READ BUFFER FROM DISK + iRead = (UINT)pFileIOBlock->InFile->Read( buffer, *iSize ); + } + + // IF COMPRESSING, THEN CALCULATE THE CRC + if( pFileIOBlock->mode == COMPRESSING ) + { + pFileIOBlock->dwCrc = crc32( buffer, &iRead, &pFileIOBlock->dwCrc ); + } + + // ENTER MESSAGE LOOP TO PROCESS BACKGROUND MESSAGES + // AND SIMULATE MULTITASKING + ProcessMessages(); + + return iRead; +} + +/********************************************************************* + * + * Function: ProcessOutBuffer() + * + * Purpose: To handle calls from the Data Compression Library for + * write requests. + * + * Parameters: buffer -> Address of buffer to write data from + * iSize -> Number of bytes to write + * dwParam -> User-defined parameter, in this case a + * pointer to the IOFILEBLOCK + * + * Returns: Zero, the return value is not used by the Data + * Compression Library + * + *********************************************************************/ +void ProcessOutBuffer( PCHAR buffer, UINT *iSize, void *pParam ) +{ + PIOFILEBLOCK pFileIOBlock; + UINT ndx; + + pFileIOBlock = (PIOFILEBLOCK) pParam; + + if( pFileIOBlock->ErrorOccurred ) + { + return; + } + + // DISPLAY ROTATING LINE PACIFIER + ndx = (pFileIOBlock->nCnt >> 4) & 3; + if( ndx != pFileIOBlock->nPrevNdx ) + { + pFileIOBlock->pDC->TextOut( 10,2, pszActiveString[ndx] ); + pFileIOBlock->nPrevNdx = ndx; + } + pFileIOBlock->nCnt++; + + // WRITE BUFFER TO DISK + if( pFileIOBlock->OutFile->Write(buffer, *iSize) != *iSize ) + { + pFileIOBlock->ErrorOccurred = ERROR_OCCURRED; + return; + } + + // IF COMPRESSING, THEN KEEP A TOTAL OF THE COMPRESSED FILE SIZE + if (pFileIOBlock->mode == COMPRESSING ) + { + pFileIOBlock->dwCompressSize += (DWORD) *iSize; + } + else // ELSE UNCOMPRESSING, SO CALCULATE CRC ON THE UNCOMPRESSED DATA + { + pFileIOBlock->dwCrc = crc32(buffer, iSize, &pFileIOBlock->dwCrc); + } + + // ENTER MESSAGE LOOP TO PROCESS BACKGROUND MESSAGES + // AND SIMULATE MULTITASKING + ProcessMessages(); + + return; +} + +/********************************************************************* + * + * Function: CompressFile() + * + * Purpose: To compress file to a separate temporary file. + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * pdwCompFileSize -> Pointer to DWORD buffer to return + * the size of the compressed file + * pszFileToCompress -> Name of file to compress + * OutputFile -> Name of file to write compressed data to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressFile( HWND hWnd, TDC *pDC, DWORD *pdwCrc, DWORD *pdwCompFileSize, + PCHAR pszFileToCompress, PCHAR OutputFile ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + IOFILEBLOCK FileIOBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + // OPEN THE INPUT AND OUTPUT FILES + FileIOBlock.InFile = new TFile; + FileIOBlock.OutFile = new TFile; + + // SETUP STRUCTURE USED BY ProcessReadBuffer() AND ProcessWriteBuffer() + FileIOBlock.mode = COMPRESSING; + FileIOBlock.dwCompressSize = 0; + FileIOBlock.pDC = pDC; + FileIOBlock.nCnt = 0; + FileIOBlock.nPrevNdx = 0; + FileIOBlock.ErrorOccurred = NO_ERRORS; + FileIOBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + pDC->TextOut( 10,2, " " ); + + // OPEN THE FILES + if (FileIOBlock.InFile->Open( pszFileToCompress, TFile::ReadOnly, TFile::PermRdWr ) && + FileIOBlock.OutFile->Open( OutputFile, TFile::Create | TFile::ReadWrite, TFile::PermRdWr )) + { + wsprintf( szVerbose, "Compressing file: %s ", pszFileToCompress ); + pDC->TextOut( 10,40, szVerbose ); + + // ONLY COMPRESS IF FILE IS NOT A ZERO LENGTH FILE + if( FileIOBlock.InFile->Length() ) + { + // COMPRESS THE FILE + iStatus = implode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, + &FileIOBlock, &DataType, &DictSize ); + } + else + { + // SINCE THIS IS A ZERO LENGTH FILE, THERE IS NOTHING TO COMPRESS + // SET STATUS TO NO ERROR + iStatus = 0; + } + + // IF THERE WAS AN ERROR COMPRESSING FILE + if( iStatus ) + { + // DISPLAY ERROR STRING FROM DLL + wsprintf( szVerbose, "Error occurred while imploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else if( FileIOBlock.ErrorOccurred ) + { + MessageBox( hWnd, "Error occurred during compression", "Error", MB_OK ); + rc = 0; + } + else // ELSE - COMPRESSION WAS SUCCESSFUL + { + // POST-CONDITION CRC + FileIOBlock.dwCrc = ~FileIOBlock.dwCrc; + + // RETURN CRC + *pdwCrc = FileIOBlock.dwCrc; + + // RETURN COMPRESSED FILE SIZE + *pdwCompFileSize = FileIOBlock.dwCompressSize; + } + } + else // ELSE - ERROR OPENING FILES + { + MessageBox( hWnd, "Error opening files for compression", "Error", MB_OK ); + rc = 0; + } + + // CLEAN-UP + FileIOBlock.OutFile->Close(); + FileIOBlock.InFile->Close(); + delete FileIOBlock.InFile; + delete FileIOBlock.OutFile; + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: ExpandFile() + * + * Purpose: To uncompress file from a .MCF file. The .MCF file will + * have been read upto the compressed data stream. + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pdwCrc -> Pointer to DWORD buffer to return the CRC + * of the compressed file before compression + * dwCompFileSize -> Size of the compressed file + * pMcfFile -> Pointer to already opened .MCF file + * OutputFile -> Name of file to write uncompressed data to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int ExpandFile( HWND hWnd, TDC *pDC, DWORD *pdwCrc, DWORD dwCompFileSize, + TFile *pMcfFile, PCHAR OutputFile ) +{ + int iStatus; + int rc = 1; + char szVerbose[128]; + IOFILEBLOCK FileIOBlock; + PCHAR pScratchPad; + + if( (pScratchPad = (PCHAR) new char[CMP_BUFFER_SIZE]) == NULL ) + { + return 0; + } + + FileIOBlock.InFile = pMcfFile; + FileIOBlock.OutFile = new TFile; + + // SETUP STRUCTURE USED BY ProcessReadBuffer() and ProcessWriteBuffer() + FileIOBlock.mode = UNCOMPRESSING; + FileIOBlock.dwCompressSize = dwCompFileSize; + FileIOBlock.pDC = pDC; + FileIOBlock.nCnt = 0; + FileIOBlock.nPrevNdx = 0; + FileIOBlock.ErrorOccurred = NO_ERRORS; + FileIOBlock.dwCrc = ~((DWORD)0); // Pre-condition CRC + + pDC->TextOut( 10,2, " " ); + + if( FileIOBlock.OutFile->Open(OutputFile, TFile::Create | TFile::ReadWrite, TFile::PermRdWr ) ) + { + // ONLY UNCOMPRESS IF FILE IS NOT A ZERO LENGTH FILE + if( FileIOBlock.dwCompressSize ) + { + // UNCOMPRESS FILE + iStatus = explode( ProcessInBuffer, ProcessOutBuffer, pScratchPad, &FileIOBlock ); + } + else + { + // SINCE THIS IS A ZERO LENGTH FILE, THERE IS NOTHING TO UNCOMPRESS + // SET STATUS TO NO ERROR + iStatus = 0; + } + + if( iStatus ) + { + wsprintf( szVerbose, "Error occurred while exploding - %d ", iStatus ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + else if( FileIOBlock.ErrorOccurred ) + { + MessageBox( hWnd, "Error occurred during uncompression", "Error", MB_OK ); + rc = 0; + } + else + { + FileIOBlock.dwCrc = ~FileIOBlock.dwCrc; + *pdwCrc = FileIOBlock.dwCrc; + + if( FileIOBlock.dwCompressSize != 0 ) + { + wsprintf( szVerbose, "Error uncompressing file: %s", OutputFile ); + MessageBox( hWnd, szVerbose, "Error", MB_OK ); + rc = 0; + } + } + } + else + { + MessageBox( hWnd, "Error opening files for uncompression", "Error", MB_OK ); + rc = 0; + } + + FileIOBlock.OutFile->Close(); + delete FileIOBlock.OutFile; + delete pScratchPad; + + return rc; +} + + +/********************************************************************* + * + * Function: AmountDriveSpaceFree() + * + * Purpose: To calculate the number of bytes free on drive + * + * Parameters: drivenum -> Drive to check (A=1, B=2, ...) + * pdwBytesFree -> DWORD to return number of bytes free + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int AmountDriveSpaceFree( UINT drivenum, DWORD *pdwBytesFree ) +{ + static char RootStr[] = { "?:\\" }; + DWORD SectorsPerCluster, + BytesPerSector, + FreeClusters, + Clusters; + + *RootStr = (char) ('A' + drivenum - 1); + + if( GetDiskFreeSpace( RootStr, &SectorsPerCluster, &BytesPerSector, + &FreeClusters, &Clusters ) == FALSE ) + { + return 0; + } + + *pdwBytesFree = SectorsPerCluster * BytesPerSector * FreeClusters; + + return 1; +} + + +/********************************************************************* + * + * Function: WriteToDisk() + * + * Purpose: To write data to disk, and prompt user for another + * disk when full. + * + * Parameters: OutFile -> Pointer to already opened file + * pBuffer -> output buffer + * nSize -> number of bytes to write + * pdwBytesFree -> number of bytes left on disk + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int WriteToDisk( TFile *OutFile, PCHAR pBuffer, UINT nSize, DWORD *pdwBytesFree ) +{ + UINT drivenum; + + // IF THERE IS SPACE TO WRITE FILE + if( (ULONG) nSize <= (ULONG) *pdwBytesFree ) + { + OutFile->Write( pBuffer, nSize ); + *pdwBytesFree -= nSize; + } + else // ELSE - NOT ENOUGH SPACE TO WRITE FILE + { + // FILL UP REMAINING DISKSPACE IF ANY + if( *pdwBytesFree > 0 ) + { + OutFile->Write( pBuffer, (UINT) *pdwBytesFree ); + nSize -= (UINT) *pdwBytesFree; + } + OutFile->Close(); + + drivenum = *pszFilename - 'A' + 1; + + // IF ON A FIXED DRIVE, THEN GIVE DISKFULL ERROR + if( drivenum > 2 ) + { + return 0; + } + + UINT nBytesRead = (UINT) *pdwBytesFree; + + // PROMPT USER FOR ANOTHER DISK + MessageBox( NULL, "Insert Another Disk", "Compress", MB_OK ); + + // GET NUMBER OF BYTES FREE ON DISK + if( !AmountDriveSpaceFree( drivenum, pdwBytesFree ) ) + { + return 0; + } + + // CREATE NEW .MCF FILE + if( !OutFile->Open( pszFilename, TFile::Create | TFile::ReadWrite, TFile::PermRdWr ) ) + { + return 0; + } + + // WRITE REMAINING BYTES + if( OutFile->Write( (pBuffer + nBytesRead), nSize ) != nSize ) + { + return 0; + } + *pdwBytesFree -= nSize; + } + + return 1; +} + + +/********************************************************************* + * + * Function: AddFileToMcfFile() + * + * Purpose: To add a compressed file with header to a .MCF file. + * The file header is written followed by the compressed + * file data + * + * Parameters: pFileHeader -> File header for the compressed file + * pszInput -> Filename of the compressed file's data + * pszOutput -> Filename of .MCF file + * CompressedFileSize -> Size of the compressed file + * NewMcfFile -> Flag used to create a new .MCF file + * TRUE - A new .MCF file will be created + * FALSE - The .MCF file will appended to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int AddFileToMcfFile( PCMP_FILEHEADER pFileHeader, PCHAR pszInput, + DWORD CompressedFileSize, BOOL NewMcfFile ) +{ + PCHAR buf; + UINT read; + TFile InFile; + TFile OutFile; + UINT drivenum; + DWORD BytesFree; + + // ALLOCATE I/O BUFFER + if( (buf = new char[APPENDBUFSIZE]) == NULL ) + { + return 0; + } + + drivenum = *pszFilename - 'A' + 1; + + // OPEN THE FILES + InFile.Open( pszInput, TFile::ReadOnly, TFile::PermRdWr ); + + // IF NEW FILE, THEN CREATE MULTIPLE COMPRESSED FILES FILE + if( NewMcfFile ) + { + // CREATE NEW .MCF FILE + if( !OutFile.Open( pszFilename, TFile::Create | TFile::ReadWrite, TFile::PermRdWr ) ) + { + InFile.Close(); + delete buf; + return 0; + } + + // GET NUMBER OF BYTES FREE ON DISK + if( !AmountDriveSpaceFree( drivenum, &BytesFree ) ) + { + delete buf; + return 0; + } + + // WRITE .MCF FILE HEADER + if( !WriteToDisk( &OutFile, MCF_FILEHEADER, 4, &BytesFree ) ) + { + OutFile.Close(); + InFile.Close(); + delete buf; + return 0; + } + } + else + { + // OPEN OLD .MCF FILE + if( !OutFile.Open( pszFilename, TFile::ReadWrite, TFile::PermRdWr ) ) + { + InFile.Close(); + delete buf; + return 0; + } + + // GET NUMBER OF BYTES FREE ON DISK + if( !AmountDriveSpaceFree( drivenum, &BytesFree ) ) + { + delete buf; + return 0; + } + + // GO TO END OF FILE + OutFile.SeekToEnd(); + } + + // WRITE THE COMPRESSED FILE'S FILEHEADER + if( !WriteToDisk( &OutFile, (PCHAR) pFileHeader, sizeof(CMP_FILEHEADER), + &BytesFree ) ) + { + OutFile.Close(); + InFile.Close(); + delete buf; + return 0; + } + + do + { + // READ FROM COMPRESSED FILE + read = InFile.Read( buf, APPENDBUFSIZE ); + + // WRITE DATA TO .MCF FILE + if( !WriteToDisk( &OutFile, buf, read, &BytesFree ) ) + { + OutFile.Close(); + InFile.Close(); + delete buf; + return 0; + } + + // IF ERROR OCCURRED + if( CompressedFileSize < (DWORD) read ) + { + OutFile.Close(); + InFile.Close(); + delete buf; + return 0; + } + + CompressedFileSize -= (DWORD) read; + } + while( CompressedFileSize > 0 ); + + OutFile.Close(); + InFile.Close(); + + delete buf; + + return 1; +} + +/********************************************************************* + * + * Function: CompressFileToMCF() + * + * Purpose: To compress a file then add it to a .MCF file + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszMcfFile -> Filename of .MCF file + * pszFileToCompress -> Filename of file with full path + * pszFilenameOnly -> Filename of file without any path + * This is the filename that is stored + * in the compressed file's file header + * NewMcfFile -> Flag used to create a new .MCF file + * TRUE - A new .MCF file will be created + * FALSE - The .MCF file will appended to + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int CompressFileToMCF( HWND hWnd, TDC *pDC, PCHAR pszMcfFile, PCHAR pszFileToCompress, + PCHAR pszFilenameOnly, BOOL NewMcfFile ) +{ + CMP_FILEHEADER FileHeader; + + pszFilename = pszMcfFile; + + memset( &FileHeader, 0, sizeof(FileHeader) ); + + // ATTEMPT TO COMPRESS THE FILE + if( !CompressFile( hWnd, pDC, &FileHeader.dwCrc, + &FileHeader.dwCompressSize, pszFileToCompress, + TEMPFILENAME ) ) + { + remove( TEMPFILENAME ); + MessageBox( hWnd, "Compress File Failed", "Error", MB_OK ); + return 0; + } + + _fstrcpy( FileHeader.filename, pszFilenameOnly ); + + if( !AddFileToMcfFile( &FileHeader, TEMPFILENAME, FileHeader.dwCompressSize, NewMcfFile ) ) + { + remove( TEMPFILENAME ); + MessageBox( hWnd, "Compress File Failed", "Error", MB_OK ); + return 0; + } + + remove( TEMPFILENAME ); + + return 1; +} + +/********************************************************************* + * + * Function: UncompressFileToMCF() + * + * Purpose: To uncompress a .MCF file + * + * + * Parameters: HWnd -> Handle to window + * pDC -> Pointer to a device context + * pszMcfFilename -> Filename of .MCF file + * pszSaveDir -> Directory to save uncompressed files + * a backslash must be the last character + * + * Returns: 1 -> Successful completion + * 0 -> Error occurred + * + *********************************************************************/ +int UncompressMcfFile( HWND hWnd, TDC *pDC, PCHAR pszMcfFilename, PCHAR pszSaveDir ) +{ + CMP_FILEHEADER FileHeader; + char McfFileheader[5]; + char szOutMsg[128]; + char szOutputFilename[100]; + UINT nNumFiles = 0; + DWORD dwCrc; // CRC OF FILE BEFORE COMPRESSION + UINT read; + TFile McfFile; + + pszFilename = pszMcfFilename; + + // OPEN THE FILES + McfFile.Open( pszFilename, TFile::ReadOnly, TFile::PermRdWr ); + + memset( McfFileheader, 0, sizeof(McfFileheader) ); + + // MAKE SURE FILE IS A MULTIPLE COMPRESSED FILE + if( (!ReadFromDisk( &McfFile, McfFileheader, 4, &read, FALSE )) || + (read != 4) || + (strcmp( McfFileheader, MCF_FILEHEADER ) != 0) ) + { + MessageBox( hWnd, "Invalid file format", "Error", MB_OK ); + return 0; + } + + do + { + // READ COMPRESSED FILE FILEHEADER + if( !ReadFromDisk( &McfFile, (PCHAR)&FileHeader, sizeof(FileHeader), + &read, TRUE ) ) + { + McfFile.Close(); + MessageBox( hWnd, "Error Uncompressing file", "Error", MB_OK ); + return 0; + } + + // IF SUCCESSFULLY READ COMPRESSED FILE FILEHEADER + if( read == sizeof(FileHeader) ) + { + // CREATE OUTPUT FILENAME + strcpy( szOutputFilename, pszSaveDir ); + strcat( szOutputFilename, FileHeader.filename ); + + wsprintf( szOutMsg, "Uncompressing file: %s ", + FileHeader.filename ); + pDC->TextOut( 10,60, szOutMsg ); + + // ATTEMPT TO EXPAND THE FILE + if( !ExpandFile( hWnd, pDC, &dwCrc, + FileHeader.dwCompressSize, + &McfFile, szOutputFilename ) ) + { + McfFile.Close(); + wsprintf( szOutMsg, "Error Uncompressing file: %s", + szOutputFilename ); + MessageBox( hWnd, szOutMsg, "Error", MB_OK ); + return 0; + } + + // CHECK THE CRC OF THE FILE + if( dwCrc != FileHeader.dwCrc ) + { + wsprintf( szOutMsg, "There is an error in the CRC of %s", + szOutputFilename ); + MessageBox( hWnd, szOutMsg, "Error", MB_OK ); + } + + nNumFiles++; + } + } + while( read == sizeof(FileHeader) ); + + McfFile.Close(); + + if( read != 0 ) + { + MessageBox( hWnd, "Invalid file format", "Error", MB_OK ); + return 0; + } + else + { + wsprintf( szOutMsg, "Uncompressed %u file(s)", nNumFiles ); + MessageBox( hWnd, szOutMsg, "Span", MB_OK ); + } + + return 1; +} + + diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/DCL.H b/Storm/PKWARE/EXAMPLES/OWL/SPAN/DCL.H new file mode 100644 index 0000000..a4bd419 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/DCL.H @@ -0,0 +1,13 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +int CompressFileToMCF( HWND hWnd, TDC *pDC, + LPSTR lpszMcfFile, LPSTR lpszFileToCompress, + LPSTR lpszFilenameOnly, BOOL NewMcfFile ); +int UncompressMcfFile( HWND hWnd, TDC *pDC, LPSTR lpszMcfFile, LPSTR lpszSaveDir ); diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/IMPBORLI.LIB b/Storm/PKWARE/EXAMPLES/OWL/SPAN/IMPBORLI.LIB new file mode 100644 index 0000000..9ef7765 Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/OWL/SPAN/IMPBORLI.LIB differ diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/IMPLODE.H b/Storm/PKWARE/EXAMPLES/OWL/SPAN/IMPLODE.H new file mode 100644 index 0000000..116934e --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/MULTFDLG.CPP b/Storm/PKWARE/EXAMPLES/OWL/SPAN/MULTFDLG.CPP new file mode 100644 index 0000000..e7e814d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/MULTFDLG.CPP @@ -0,0 +1,160 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include + +#include "multfdlg.h" + +#define FILELIST_BUFFSIZE 4096 // AMOUNT OF MEMORY TO ALLOCATE FOR FILE LIST + + +MultiSelFileDialog::MultiSelFileDialog( TWindow *pParentWnd, TData& data ) + :TFileOpenDialog( pParentWnd, data ) +{ + // ALLOCATE MEMORY FOR FILE LIST + pszFileList = (PCHAR) new char[FILELIST_BUFFSIZE]; + + // SET ALLOCATED BUFFER AS FILENAME BUFER IN OPENFILENAME STRUCT + // AND REPLACE IT IN THE OPENFILENAME STRUCT + pszOldPtr = ofn.lpstrFile; + ofn.lpstrFile = pszFileList; + ofn.nMaxFile = FILELIST_BUFFSIZE; + + // DO SOME INITIALIZATION + memset( pszFileList, 0, FILELIST_BUFFSIZE ); + strcpy( pszFileList, "*.*" ); + memset( szPath, 0, sizeof(szPath) ); + nPathLen = 0; + Done = TRUE; +} + + +MultiSelFileDialog::~MultiSelFileDialog() +{ + // REPLACE OLD POINTER AND FREE MEMORY + ofn.lpstrFile = pszOldPtr; + delete pszFileList; +} + + +BOOL MultiSelFileDialog::GetFirstFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ) +{ + PCHAR pszToken; + + nPathLen = 0; + Done = FALSE; + + // GET THE FIRST TOKEN WHICH SHOULD BE THE PATH + if( strchr( pszFileList, ' ' ) == NULL ) + { + // COULD NOT FIND TOKEN SO MUST BE PATH AND FILENAME + + Done = TRUE; + + memset( szPath, 0, sizeof(szPath) ); + nPathLen = 0; + + // MAKE SURE THE FILENAME + PATH WILL FIT + if( strlen( pszFileList ) > nPathBuffSize ) + { + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // COPY FILENAME ONLY + char *NameOnly = strrchr( pszFileList, '\\' ); + if( NameOnly == NULL || strlen( NameOnly ) > 13 ) + { + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + strcpy( pszFilenameBuff, ++NameOnly ); + + // COPY PATH AND FILENAME TO BUFFER + strcpy( pszFullPathBuff, pszFileList ); + + return TRUE; + } + + // GET THE FIRST TOKEN WHICH SHOULD BE THE PATH + if( (pszToken = strtok( pszFileList, " " )) == NULL ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + memset( szPath, 0, sizeof(szPath) ); + strcpy( szPath, pszToken ); + strcat( szPath, "\\" ); + + nPathLen = strlen( szPath ); + + return GetNextFilename( pszFullPathBuff, nPathBuffSize, pszFilenameBuff ); +} + + +// pszFilenameBuff MUST BE AT LEAST 13 BYTES +BOOL MultiSelFileDialog::GetNextFilename( PCHAR pszFullPathBuff, + UINT nPathBuffSize, + PCHAR pszFilenameBuff ) +{ + PCHAR pszToken; + + if( Done ) + { + return FALSE; + } + + // GET THE NEXT TOKEN WHICH SHOULD BE A FILENAME + if( (pszToken = strtok( NULL, " " )) == NULL ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // MAKE SURE THE FILENAME + PATH WILL FIT + if( (strlen( pszToken ) + nPathLen) > nPathBuffSize ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + // COPY PATH AND FILENAME TO BUFFER + strcpy( pszFullPathBuff, szPath ); + strcat( pszFullPathBuff, pszToken ); + + PCHAR pszNameOnly = strrchr( pszFullPathBuff, '\\' ); + + if( (pszNameOnly == NULL) || (strlen(pszNameOnly) > 13) ) + { + Done = TRUE; + *pszFullPathBuff = '\0'; + *pszFilenameBuff = '\0'; + return FALSE; + } + + strcpy( pszFilenameBuff, ++pszNameOnly ); + + return TRUE; +} + + + + + diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/MULTFDLG.H b/Storm/PKWARE/EXAMPLES/OWL/SPAN/MULTFDLG.H new file mode 100644 index 0000000..eed3ecc --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/MULTFDLG.H @@ -0,0 +1,30 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include + +class MultiSelFileDialog : public TFileOpenDialog +{ + private: + PCHAR pszFileList; + PCHAR pszOldPtr; + int nPathLen; + char szPath[80]; + BOOL Done; + + public: + MultiSelFileDialog( TWindow *pParentWnd, TData& data ); + ~MultiSelFileDialog(); + BOOL GetFirstFilename( PCHAR lpszFullPathBuff, + UINT nPathBuffSize, + PCHAR lpszFilenameBuff ); + BOOL GetNextFilename( PCHAR lpszFullPathBuff, + UINT nPathBuffSize, + PCHAR lpszFilenameBuff ); +}; diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPAN.IDE b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPAN.IDE new file mode 100644 index 0000000..ff384fa Binary files /dev/null and b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPAN.IDE differ diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.CPP b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.CPP new file mode 100644 index 0000000..73e7474 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.CPP @@ -0,0 +1,419 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include +#include +#pragma hdrstop + +#include "spanapp.h" +#include "spnedtvw.h" // Definition of client class. +#include "spnabtdl.h" // Definition of about dialog. +#include "multfdlg.h" +#include "dcl.h" +#include "implode.h" + +#include + +//{{spanApp Implementation}} + +//{{DOC_VIEW}} +DEFINE_DOC_TEMPLATE_CLASS(TFileDocument, spanEditView, DocType1); +//{{DOC_VIEW_END}} + +//{{DOC_MANAGER}} +DocType1 __dvt1("All Files (*.*)", "*.*", 0, "TXT", dtAutoDelete | dtUpdateDir); +//{{DOC_MANAGER_END}} + + +// +// Build a response table for all messages/commands handled +// by the application. +// +DEFINE_RESPONSE_TABLE1(spanApp, TApplication) +//{{spanAppRSP_TBL_BEGIN}} + EV_OWLVIEW(dnCreate, EvNewView), + EV_OWLVIEW(dnClose, EvCloseView), + EV_COMMAND(CM_HELPABOUT, CmHelpAbout), +//{{spanAppRSP_TBL_END}} +END_RESPONSE_TABLE; + + +extern UINT DataType; // GLOBAL FOR DATA TYPE FOR COMPRESSION +extern UINT DictSize; // GLOBAL FOR DICTIONARY SIZE FOR COMPRESSION + +// THE UNCOMPRESS DIRECTORY MUST END WITH A BACKSLASH +char far *UncompressDir = "C:\\TEMP\\"; + +// FLAG TO DETERMINE IF CURRENTLY COMPRESSING OR UNCOMPRESSING +static BOOL bActive = FALSE; + +////////////////////////////////////////////////////////// +// spanApp +// ===== +// +spanApp::spanApp () : TApplication("span") +{ + SetDocManager(new TDocManager(dmSDI, this)); + + // INSERT>> Your constructor code here. +} + + +spanApp::~spanApp () +{ + // INSERT>> Your destructor code here. +} + + + + +////////////////////////////////////////////////////////// +// spanApp +// ===== +// Application intialization. +// +void spanApp::InitMainWindow () +{ + if (nCmdShow != SW_HIDE) + nCmdShow = (nCmdShow != SW_SHOWMINNOACTIVE) ? SW_SHOWNORMAL : nCmdShow; + + SDIDecFrame *frame = new SDIDecFrame(0, GetName(), 0, true, this); + + // + // Assign ICON w/ this application. + // + frame->SetIcon(this, IDI_SDIAPPLICATION); + + // + // Menu associated with window and accelerator table associated with table. + // + frame->AssignMenu(SDI_MENU); + + // + // Associate with the accelerator table. + // + frame->Attr.AccelTable = SDI_MENU; + + + TStatusBar *sb = new TStatusBar(frame, TGadget::Recessed, + TStatusBar::CapsLock | + TStatusBar::NumLock | + TStatusBar::ScrollLock | + TStatusBar::Overtype); + frame->Insert(*sb, TDecoratedFrame::Bottom); + + SetMainWindow(frame); + + frame->SetMenuDescr(TMenuDescr(SDI_MENU)); + +} + + +////////////////////////////////////////////////////////// +// spanApp +// ===== +// Response Table handlers: +// +void spanApp::EvNewView (TView& view) +{ + GetMainWindow()->SetClientWindow(view.GetWindow()); + if (!view.IsOK()) + GetMainWindow()->SetClientWindow(0); + else if (view.GetViewMenu()) + GetMainWindow()->MergeMenu(*view.GetViewMenu()); +} + + +void spanApp::EvCloseView (TView&) +{ + GetMainWindow()->SetClientWindow(0); + GetMainWindow()->SetCaption("span"); +} + +// +// Build a response table for all messages/commands handled +// by the application. +// +DEFINE_RESPONSE_TABLE1(SDIDecFrame, TDecoratedFrame) +//{{SDIDecFrameRSP_TBL_BEGIN}} + EV_COMMAND(CM_COMPRESS_FILES, OnCompressFiles), + EV_COMMAND_ENABLE(CM_COMPRESS_FILES, OnCompressFilesEnable), + EV_COMMAND(CM_UNCOMPRESS_FILES, OnUncompressFiles), + EV_COMMAND_ENABLE(CM_UNCOMPRESS_FILES, OnUncompressFilesEnable), + EV_COMMAND(CM_COMP_TYPE_ASCII, OnCompTypeAscii), + EV_COMMAND_ENABLE(CM_COMP_TYPE_ASCII, OnCompTypeAsciiEnable), + EV_COMMAND(CM_COMP_TYPE_BINARY, OnCompTypeBinary), + EV_COMMAND_ENABLE(CM_COMP_TYPE_BINARY, OnCompTypeBinaryEnable), + EV_COMMAND(CM_DICT_SIZE_1024, OnDictSize1024), + EV_COMMAND_ENABLE(CM_DICT_SIZE_1024, OnDictSize1024Enable), + EV_COMMAND(CM_DICT_SIZE_2048, OnDictSize2048), + EV_COMMAND_ENABLE(CM_DICT_SIZE_2048, OnDictSize2048Enable), + EV_COMMAND(CM_DICT_SIZE_4096, OnDictSize4096), + EV_COMMAND_ENABLE(CM_DICT_SIZE_4096, OnDictSize4096Enable), +//{{SDIDecFrameRSP_TBL_END}} +END_RESPONSE_TABLE; + + +//{{SDIDecFrame Implementation}} + + +SDIDecFrame::SDIDecFrame (TWindow *parent, const char far *title, TWindow *clientWnd, bool trackMenuSelection, TModule *module) + : TDecoratedFrame(parent, title, clientWnd, trackMenuSelection, module) +{ +} + + +SDIDecFrame::~SDIDecFrame () +{ + // INSERT>> Your destructor code here. + +} + + +////////////////////////////////////////////////////////// +// spanApp +// =========== +// Menu Help About span.exe command +void spanApp::CmHelpAbout () +{ + // + // Show the modal dialog. + // + spanAboutDlg(GetMainWindow()).Execute(); +} + + +int OwlMain (int , char* []) +{ + try { + spanApp app; + return app.Run(); + } + catch (xmsg& x) { + ::MessageBox(0, x.why().c_str(), "Exception", MB_OK); + } + + return -1; +} + +void SDIDecFrame::OnCompressFiles () +{ + // TURN OFF HELP MESSAGE AND CLEAR SCREEN +// ChildBroadcastMessage( WM_TURN_OFF_HELP, 0, 0L ); + + TOpenSaveDialog::TData data( OFN_FILEMUSTEXIST|OFN_HIDEREADONLY| + OFN_PATHMUSTEXIST|OFN_NOCHANGEDIR|OFN_ALLOWMULTISELECT, + "All Files (*.*)|*.*||", 0, "", "*" ); + + MultiSelFileDialog FileDlg( this, data ); + + if( FileDlg.Execute() == IDOK ) + { + TOpenSaveDialog::TData SaveData( OFN_HIDEREADONLY|OFN_PATHMUSTEXIST| + OFN_NOCHANGEDIR|OFN_OVERWRITEPROMPT, + "Mult. Compressed Files (*.MCF)|*.MCF||", 0, "*.MCF", "MCF" ); + + if( TFileSaveDialog( this, SaveData ).Execute() == IDOK ) + { + BOOL GotFilenameOk, + bError = FALSE, + CreateMcfFile; + UINT nNumCmpFiles = 0; + char szFilename[13]; // BUFFER FOR FILENAME ONLY + char szFullPathname[128]; // BUFFER FOR FULL PATH FOR FILE + char szOutBuff[64]; // TEMP OUTPUT BUFFER + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + TWindow *ClientWnd = GetClientWindow(); + TWindowDC dc( ClientWnd->HWindow ); + TColor bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + // SET FLAG TO PREVENT EXITING IN THE MIDDLE OF THE COMPRESSION + bActive = TRUE; + + wsprintf( szOutBuff, "Compressing to: %s ", (LPSTR) + SaveData.FileName ); + dc.TextOut( 10,20, szOutBuff ); + + // SET CREATE .MCF FILE FLAG TO TRUE, SO THAT THE FIRST TIME + // CompressFileToMCF IS CALLED THE .MCF WILL BE CREATED INSTEAD + // OF APPENDED TO + CreateMcfFile = TRUE; + + // GET THE FIRST FILENAME IN THE LIST + GotFilenameOk = FileDlg.GetFirstFilename( szFullPathname, + sizeof(szFullPathname), + szFilename ); + // WHILE GOT A FILENAME FROM THE LIST + while( GotFilenameOk ) + { + // COMPRESS THE FILE AND ADD IT TO THE .MCF FILE + if( !CompressFileToMCF( ClientWnd->HWindow, &dc, + SaveData.FileName, szFullPathname, + szFilename, CreateMcfFile ) ) + { + // ERROR OCCURRED SO DELETE THE .MCF FILE + remove( SaveData.FileName ); + bError = TRUE; + break; + } + // INCREMENT TOTAL + nNumCmpFiles++; + + // RESET .MCF FILE FLAG SO THAT .MCF FILE WILL NOT BE CREATED + CreateMcfFile = FALSE; + + // GET THE FIRST FILENAME IN THE LIST + GotFilenameOk = FileDlg.GetNextFilename( szFullPathname, + sizeof(szFullPathname), + szFilename ); + } + + // IF THERE WAS NOT ERROR, THEN DISPLAY MESSAGE + if( !bError ) + { + wsprintf( szOutBuff, "Compressed %u file(s)", nNumCmpFiles ); + MessageBox( szOutBuff, "Span" ); + } + + // DONE WITH COMPRESION SO ALLOW THE USER TO EXIT + bActive = FALSE; + } + } + + // TURN OFF HELP MESSAGE AND CLEAR SCREEN +// ChildBroadcastMessage( WM_TURN_ON_HELP, 0, 0L ); +} + + +void SDIDecFrame::OnUncompressFiles () +{ + // TURN OFF HELP MESSAGE AND CLEAR SCREEN +// ChildBroadcastMessage( WM_TURN_OFF_HELP, 0, 0L ); + + TOpenSaveDialog::TData data( OFN_FILEMUSTEXIST|OFN_HIDEREADONLY| + OFN_PATHMUSTEXIST|OFN_NOCHANGEDIR, + "Mult. Compressed Files (*.MCF)|*.MCF||", 0, "*.MCF", "MCF" ); + + if( TFileOpenDialog( this, data ).Execute() == IDOK ) + { + char szOutBuff[64]; // TEMP OUTPUT BUFFER + + // SET FLAG TO PREVENT EXITING IN THE MIDDLE OF THE UNCOMPRESSION + bActive = TRUE; + + // GET DC AND SET THE TEXT BACKGROUND COLOR TO WINDOW BACKGROUND COLOR + TWindow *ClientWnd = GetClientWindow(); + TWindowDC dc( ClientWnd->HWindow ); + TColor bkGroundColor = dc.GetPixel( 0, 0 ); + dc.SetBkColor( bkGroundColor ); + + wsprintf( szOutBuff, "Uncompressing: %s ",(LPSTR) data.FileName ); + dc.TextOut( 10,20, szOutBuff ); + + // UNCOMPRESS THE FILE + UncompressMcfFile( ClientWnd->HWindow, &dc, data.FileName, UncompressDir ); + + // DONE WITH UNCOMPRESION SO ALLOW THE USER TO EXIT + bActive = FALSE; + } + + // TURN OFF HELP MESSAGE AND CLEAR SCREEN +// ChildBroadcastMessage( WM_TURN_ON_HELP, 0, 0L ); +} + + + +void SDIDecFrame::OnCompressFilesEnable (TCommandEnabler &tce) +{ + tce.Enable( TRUE && !bActive ); +} + + +void SDIDecFrame::OnUncompressFilesEnable (TCommandEnabler &tce) +{ + tce.Enable( TRUE && !bActive ); +} + + +void SDIDecFrame::OnCompTypeAscii () +{ + DataType = CMP_ASCII; +} + + +void SDIDecFrame::OnCompTypeAsciiEnable (TCommandEnabler &tce) +{ + tce.Enable( (DataType != CMP_ASCII) && !bActive ); +} + + +void SDIDecFrame::OnCompTypeBinary () +{ + DataType = CMP_BINARY; +} + + +void SDIDecFrame::OnCompTypeBinaryEnable (TCommandEnabler &tce) +{ + tce.Enable( (DataType != CMP_BINARY) && !bActive ); +} + + +void SDIDecFrame::OnDictSize1024 () +{ + DictSize = 1024; +} + + +void SDIDecFrame::OnDictSize1024Enable (TCommandEnabler &tce) +{ + tce.Enable( (DictSize != 1024) && !bActive ); +} + + +void SDIDecFrame::OnDictSize2048 () +{ + DictSize = 2048; +} + + +void SDIDecFrame::OnDictSize2048Enable (TCommandEnabler &tce) +{ + tce.Enable( (DictSize != 2048) && !bActive ); +} + + +void SDIDecFrame::OnDictSize4096 () +{ + DictSize = 4096; +} + + +void SDIDecFrame::OnDictSize4096Enable (TCommandEnabler &tce) +{ + tce.Enable( (DictSize != 4096) && !bActive ); +} + + +bool SDIDecFrame::CanClose () +{ + bool result; + + if( bActive ) + return FALSE; + + result = TDecoratedFrame::CanClose(); + + return result; +} + + + diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.DEF b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.DEF new file mode 100644 index 0000000..f06100c --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.DEF @@ -0,0 +1,8 @@ +NAME span + +DESCRIPTION 'span Application' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE +HEAPSIZE 4096 +STACKSIZE 8192 diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.H b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.H new file mode 100644 index 0000000..4eef75d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.H @@ -0,0 +1,81 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#if !defined(__spanapp_h) // Sentry, use file only if it's not already included. +#define __spanapp_h + +#include +#pragma hdrstop + + +#include "spanapp.rh" // Definition of all resources. + + +#define WM_TURN_OFF_HELP WM_USER+1 +#define WM_TURN_ON_HELP WM_USER+2 + + +// +// FrameWindow must be derived to override Paint for Preview and Print. +// +//{{TDecoratedFrame = SDIDecFrame}} +class SDIDecFrame : public TDecoratedFrame { +public: + SDIDecFrame (TWindow *parent, const char far *title, TWindow *clientWnd, bool trackMenuSelection = false, TModule *module = 0); + ~SDIDecFrame (); + +//{{SDIDecFrameVIRTUAL_BEGIN}} +public: + virtual bool CanClose (); +//{{SDIDecFrameVIRTUAL_END}} + +//{{SDIDecFrameRSP_TBL_BEGIN}} +protected: + void OnCompressFiles (); + void OnCompressFilesEnable (TCommandEnabler &tce); + void OnUncompressFiles (); + void OnUncompressFilesEnable (TCommandEnabler &tce); + void OnCompTypeAscii (); + void OnCompTypeAsciiEnable (TCommandEnabler &tce); + void OnCompTypeBinary (); + void OnCompTypeBinaryEnable (TCommandEnabler &tce); + void OnDictSize1024 (); + void OnDictSize1024Enable (TCommandEnabler &tce); + void OnDictSize2048 (); + void OnDictSize2048Enable (TCommandEnabler &tce); + void OnDictSize4096 (); + void OnDictSize4096Enable (TCommandEnabler &tce); +//{{SDIDecFrameRSP_TBL_END}} +DECLARE_RESPONSE_TABLE(SDIDecFrame); +}; //{{SDIDecFrame}} + + +//{{TApplication = spanApp}} +class spanApp : public TApplication { +private: + +public: + spanApp (); + virtual ~spanApp (); + +//{{spanAppVIRTUAL_BEGIN}} +public: + virtual void InitMainWindow (); +//{{spanAppVIRTUAL_END}} + +//{{spanAppRSP_TBL_BEGIN}} +protected: + void EvNewView (TView& view); + void EvCloseView (TView& view); + void CmHelpAbout (); +//{{spanAppRSP_TBL_END}} +DECLARE_RESPONSE_TABLE(spanApp); +}; //{{spanApp}} + + +#endif // __spanapp_h sentry. diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.RC b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.RC new file mode 100644 index 0000000..37ef28d --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.RC @@ -0,0 +1,399 @@ +/* Project span + PKWARE, INC. + Copyright © 1995. All Rights Reserved. + + SUBSYSTEM: span.exe Application + FILE: spanapp.rc + AUTHOR: + + + OVERVIEW + ======== + All resources defined here. +*/ + +#if !defined(WORKSHOP_INVOKED) +#include +#endif +#include "spanapp.rh" + +SDI_MENU MENU +{ + POPUP "&File" + { + MENUITEM "&Compress Files", CM_COMPRESS_FILES + MENUITEM "&Uncompress Files", CM_UNCOMPRESS_FILES + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", CM_EXIT + } + + POPUP "&Options" + { + MENUITEM "&1024", CM_DICT_SIZE_1024 + MENUITEM "&2048", CM_DICT_SIZE_2048 + MENUITEM "&4096", CM_DICT_SIZE_4096 + MENUITEM SEPARATOR + MENUITEM "&ASCII", CM_COMP_TYPE_ASCII + MENUITEM "&Binary", CM_COMP_TYPE_BINARY + } + + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + POPUP "&Help" + { + MENUITEM "&About...", CM_HELPABOUT + } + +} + + +// Accelerator table for short-cut to menu commands. (include\owl\editfile.rc) +SDI_MENU ACCELERATORS +BEGIN + VK_DELETE, CM_EDITDELETE, VIRTKEY + VK_DELETE, CM_EDITCUT, VIRTKEY, SHIFT + VK_INSERT, CM_EDITCOPY, VIRTKEY, CONTROL + VK_INSERT, CM_EDITPASTE, VIRTKEY, SHIFT + VK_DELETE, CM_EDITCLEAR, VIRTKEY, CONTROL + VK_BACK, CM_EDITUNDO, VIRTKEY, ALT + VK_F3, CM_EDITFINDNEXT, VIRTKEY +END + + +// Menu merged in when TEditView is active, notice the extra MENUITEM SEPARATORs which are +// for menu negotation. These separators are used as group markers by OWL. +IDM_EDITVIEW MENU +{ + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR +} + + +// Menu merged in when TListView is active, notice the extra MENUITEM SEPARATORs which are +// for menu negotation. These separators are used as group markers by OWL. +IDM_LISTVIEW MENU +{ + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM SEPARATOR +} + + +IDM_DOCMANAGERFILE MENU +{ + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", CM_EXIT +} + + +// +// Table of help hints displayed in the status bar. +// +STRINGTABLE +BEGIN + -1, "File/document operations" + CM_FILENEW, "Creates a new document" + CM_FILEOPEN, "Opens an existing document" + CM_VIEWCREATE, "Create a new view for this document" + CM_FILEREVERT, "Reverts changes to last document save" + CM_FILECLOSE, "Close this document" + CM_FILESAVE, "Saves this document" + CM_FILESAVEAS, "Saves this document with a new name" + CM_EXIT, "Quits spanApp and prompts to save the documents" + CM_EDITUNDO-1, "Edit operations" + CM_EDITUNDO, "Reverses the last operation" + CM_EDITCUT, "Cuts the selection and puts it on the Clipboard" + CM_EDITCOPY, "Copies the selection and puts it on the Clipboard" + CM_EDITPASTE, "Inserts the clipboard contents at the insertion point" + CM_EDITDELETE, "Deletes the selection" + CM_EDITCLEAR, "Clear the document" + CM_EDITADD, "Insert a new line" + CM_EDITEDIT, "Edit the current line" + CM_EDITFIND-1, "Search/replace operations" + CM_EDITFIND, "Finds the specified text" + CM_EDITREPLACE, "Finds the specified text and changes it" + CM_EDITFINDNEXT, "Finds the next match" + CM_HELPABOUT-1, "Access About" + CM_HELPABOUT, "About the span application" +END + + +// +// OWL string table +// + +// EditFile (include\owl\editfile.rc and include\owl\editsear.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_CANNOTFIND, "Cannot find ""%s""." + IDS_UNABLEREAD, "Unable to read file %s from disk." + IDS_UNABLEWRITE, "Unable to write file %s to disk." + IDS_FILECHANGED, "The text in the %s file has changed.\n\nDo you want to save the changes?" + IDS_FILEFILTER, "Text files (*.TXT)|*.TXT|AllFiles (*.*)|*.*|" +END + + +// ListView (include\owl\listview.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_LISTNUM, "Line number %d" +END + + +// Doc/View (include\owl\docview.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_DOCMANAGERFILE, "&File" + IDS_DOCLIST, "--Document Type--" + IDS_VIEWLIST, "--View Type--" + IDS_UNTITLED, "Document" + IDS_UNABLEOPEN, "Unable to open document." + IDS_UNABLECLOSE, "Unable to close document." + IDS_READERROR, "Document read error." + IDS_WRITEERROR, "Document write error." + IDS_DOCCHANGED, "The document has been changed.\n\nDo you want to save the changes?" + IDS_NOTCHANGED, "The document has not been changed." + IDS_NODOCMANAGER, "Document Manager not present." + IDS_NOMEMORYFORVIEW, "Insufficient memory for view." + IDS_DUPLICATEDOC, "Document already loaded." +END + + +// Exception string resources (include\owl\except.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_OWLEXCEPTION, "ObjectWindows Exception" + IDS_UNHANDLEDXMSG, "Unhandled Exception" + IDS_OKTORESUME, "OK to resume?" + IDS_UNKNOWNEXCEPTION, "Unknown exception" + + IDS_UNKNOWNERROR, "Unknown error" + IDS_NOAPP, "No application object" + IDS_OUTOFMEMORY, "Out of memory" + IDS_INVALIDMODULE, "Invalid module specified for window" + IDS_INVALIDMAINWINDOW, "Invalid MainWindow" + IDS_VBXLIBRARYFAIL, "VBX Library init failure" + + IDS_INVALIDWINDOW, "Invalid window %s" + IDS_INVALIDCHILDWINDOW, "Invalid child window %s" + IDS_INVALIDCLIENTWINDOW, "Invalid client window %s" + + IDS_CLASSREGISTERFAIL, "Class registration fail for window %s" + IDS_CHILDREGISTERFAIL, "Child class registration fail for window %s" + IDS_WINDOWCREATEFAIL, "Create fail for window %s" + IDS_WINDOWEXECUTEFAIL, "Execute fail for window %s" + IDS_CHILDCREATEFAIL, "Child create fail for window %s" + + IDS_MENUFAILURE, "Menu creation failure" + IDS_VALIDATORSYNTAX, "Validator syntax error" + IDS_PRINTERERROR, "Printer error" + + IDS_LAYOUTINCOMPLETE, "Incomplete layout constraints specified in window %s" + IDS_LAYOUTBADRELWIN, "Invalid relative window specified in layout constraint in window %s" + + IDS_GDIFAILURE, "GDI failure" + IDS_GDIALLOCFAIL, "GDI allocate failure" + IDS_GDICREATEFAIL, "GDI creation failure" + IDS_GDIRESLOADFAIL, "GDI resource load failure" + IDS_GDIFILEREADFAIL, "GDI file read failure" + IDS_GDIDELETEFAIL, "GDI object %X delete failure" + IDS_GDIDESTROYFAIL, "GDI object %X destroy failure" + IDS_INVALIDDIBHANDLE, "Invalid DIB handle %X" +END + + +// General Window's status bar messages. (include\owl\statusba.rc) +STRINGTABLE +BEGIN + IDS_MODES "EXT|CAPS|NUM|SCRL|OVR|REC" + IDS_MODESOFF " | | | | | " + SC_SIZE, "Changes the size of the window" + SC_MOVE, "Moves the window to another position" + SC_MINIMIZE, "Reduces the window to an icon" + SC_MAXIMIZE, "Enlarges the window to it maximum size" + SC_RESTORE, "Restores the window to its previous size" + SC_CLOSE, "Closes the window" + SC_TASKLIST, "Opens task list" + SC_NEXTWINDOW, "Switches to next window" +END + + +// Validator messages (include\owl\validate.rc) +STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE +BEGIN + IDS_VALPXPCONFORM "Input does not conform to picture:\n""%s""" + IDS_VALINVALIDCHAR "Invalid character in input" + IDS_VALNOTINRANGE "Value is not in the range %ld to %ld." + IDS_VALNOTINLIST "Input is not in valid-list" +END + + +// +// Misc application definitions +// + +// Application ICON +IDI_SDIAPPLICATION ICON "appldocv.ico" + + +// About box. +IDD_ABOUT DIALOG 12, 17, 204, 65 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About span" +FONT 8, "MS Sans Serif" +BEGIN + CTEXT "Version", IDC_VERSION, 2, 14, 200, 8, SS_NOPREFIX + CTEXT "Disk Spanning Example", -1, 2, 4, 200, 8, SS_NOPREFIX + CTEXT "", IDC_COPYRIGHT, 2, 27, 200, 17, SS_NOPREFIX + RTEXT "", IDC_DEBUG, 136, 55, 66, 8, SS_NOPREFIX + ICON IDI_SDIAPPLICATION, -1, 2, 2, 34, 34 + DEFPUSHBUTTON "OK", IDOK, 82, 48, 40, 14 +END + + +// TInputDialog class dialog box. +IDD_INPUTDIALOG DIALOG 20, 24, 180, 64 +STYLE WS_POPUP | WS_CAPTION | DS_SETFONT +FONT 8, "Helv" +BEGIN + LTEXT "", ID_PROMPT, 10, 8, 160, 10, SS_NOPREFIX + CONTROL "", ID_INPUT, "EDIT", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL, 10, 20, 160, 12 + DEFPUSHBUTTON "&OK", IDOK, 47, 42, 40, 14 + PUSHBUTTON "&Cancel", IDCANCEL, 93, 42, 40, 14 +END + + +// Horizontal slider thumb bitmap for TSlider and VSlider (include\owl\slider.rc) +IDB_HSLIDERTHUMB BITMAP PRELOAD MOVEABLE DISCARDABLE +BEGIN + '42 4D 66 01 00 00 00 00 00 00 76 00 00 00 28 00' + '00 00 12 00 00 00 14 00 00 00 01 00 04 00 00 00' + '00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 10 00 00 00 00 00 00 00 00 00 C0 00 00 C0' + '00 00 00 C0 C0 00 C0 00 00 00 C0 00 C0 00 C0 C0' + '00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF' + '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' + '00 00 FF FF FF 00 BB BB 0B BB BB BB B0 BB BB 00' + '00 00 BB B0 80 BB BB BB 08 0B BB 00 00 00 BB 08' + 'F8 0B BB B0 87 70 BB 00 00 00 B0 8F F8 80 BB 08' + '77 77 0B 00 00 00 08 F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 88 00 88 77 77 70 00 00 00 0F F8' + '88 88 00 88 88 87 70 00 00 00 0F F7 77 88 00 88' + '77 77 70 00 00 00 0F F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 88 00 88 77 77 70 00 00 00 0F F8' + '88 88 00 88 88 87 70 00 00 00 0F F7 77 88 00 88' + '77 77 70 00 00 00 0F F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 88 00 88 77 77 70 00 00 00 0F F8' + '88 88 00 88 88 87 70 00 00 00 0F F7 77 88 00 88' + '77 77 70 00 00 00 0F F8 88 88 00 88 88 87 70 00' + '00 00 0F F7 77 78 00 88 77 77 70 00 00 00 0F FF' + 'FF FF 00 88 88 88 80 00 00 00 B0 00 00 00 BB 00' + '00 00 0B 00 00 00' +END + + +// Vertical slider thumb bitmap for TSlider and HSlider (include\owl\slider.rc) +IDB_VSLIDERTHUMB BITMAP PRELOAD MOVEABLE DISCARDABLE +BEGIN + '42 4D 2A 01 00 00 00 00 00 00 76 00 00 00 28 00' + '00 00 28 00 00 00 09 00 00 00 01 00 04 00 00 00' + '00 00 B4 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 10 00 00 00 00 00 00 00 00 00 C0 00 00 C0' + '00 00 00 C0 C0 00 C0 00 00 00 C0 00 C0 00 C0 C0' + '00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF' + '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' + '00 00 FF FF FF 00 B0 00 00 00 00 00 00 00 00 0B' + 'B0 00 00 00 00 00 00 00 00 0B 0F 88 88 88 88 88' + '88 88 88 80 08 88 88 88 88 88 88 88 88 80 0F 77' + '77 77 77 77 77 77 77 80 08 77 77 77 77 77 77 77' + '77 80 0F 77 FF FF FF FF FF FF F7 80 08 77 FF FF' + 'FF FF FF FF F7 80 0F 70 00 00 00 00 00 00 77 80' + '08 70 00 00 00 00 00 00 77 80 0F 77 77 77 77 77' + '77 77 77 80 08 77 77 77 77 77 77 77 77 80 0F 77' + '77 77 77 77 77 77 77 80 08 77 77 77 77 77 77 77' + '77 80 0F FF FF FF FF FF FF FF FF F0 08 88 88 88' + '88 88 88 88 88 80 B0 00 00 00 00 00 00 00 00 0B' + 'B0 00 00 00 00 00 00 00 00 0B' +END + + +// Version info. +// +#if !defined(__DEBUG_) +// Non-Debug VERSIONINFO +1 VERSIONINFO LOADONCALL MOVEABLE +FILEVERSION 1, 0, 0, 0 +PRODUCTVERSION 1, 0, 0, 0 +FILEFLAGSMASK 0 +FILEFLAGS VS_FFI_FILEFLAGSMASK +FILEOS VOS__WINDOWS16 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + // Language type = U.S. English (0x0409) and Character Set = Windows, Multilingual(0x04e4) + BLOCK "040904E4" // Matches VarFileInfo Translation hex value. + BEGIN + VALUE "CompanyName", "PKWARE, INC.\000" + VALUE "FileDescription", "span for Windows\000" + VALUE "FileVersion", "1.0\000" + VALUE "InternalName", "span\000" + VALUE "LegalCopyright", "Copyright © 1995. All Rights Reserved.\000" + VALUE "LegalTrademarks", "Windows (TM) is a trademark of Microsoft Corporation\000" + VALUE "OriginalFilename", "span.EXE\000" + VALUE "ProductName", "span\000" + VALUE "ProductVersion", "1.0\000" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04e4 // U.S. English(0x0409) & Windows Multilingual(0x04e4) 1252 + END + +END +#else + +// Debug VERSIONINFO +1 VERSIONINFO LOADONCALL MOVEABLE +FILEVERSION 1, 0, 0, 0 +PRODUCTVERSION 1, 0, 0, 0 +FILEFLAGSMASK VS_FF_DEBUG | VS_FF_PRERELEASE | VS_FF_PATCHED | VS_FF_PRIVATEBUILD | VS_FF_SPECIALBUILD +FILEFLAGS VS_FFI_FILEFLAGSMASK +FILEOS VOS__WINDOWS16 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + // Language type = U.S. English (0x0409) and Character Set = Windows, Multilingual(0x04e4) + BLOCK "040904E4" // Matches VarFileInfo Translation hex value. + BEGIN + VALUE "CompanyName", "PKWARE, INC.\000" + VALUE "FileDescription", "span for Windows\000" + VALUE "FileVersion", "1.0\000" + VALUE "InternalName", "span\000" + VALUE "LegalCopyright", "Copyright © 1995. All Rights Reserved.\000" + VALUE "LegalTrademarks", "Windows (TM) is a trademark of Microsoft Corporation\000" + VALUE "OriginalFilename", "span.EXE\000" + VALUE "ProductName", "span\000" + VALUE "ProductVersion", "1.0\000" + VALUE "SpecialBuild", "Debug Version\000" + VALUE "PrivateBuild", "Built by \000" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04e4 // U.S. English(0x0409) & Windows Multilingual(0x04e4) 1252 + END + +END +#endif diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.RH b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.RH new file mode 100644 index 0000000..f59b650 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPANAPP.RH @@ -0,0 +1,204 @@ +//#if !defined(__spanapp_rh) // Sentry use file only if it's not already included. +//#define __spanapp_rh + +/* Project span + PKWARE, INC. + Copyright © 1995. All Rights Reserved. + + SUBSYSTEM: span.exe Application + FILE: spanapp.h + AUTHOR: + + + OVERVIEW + ======== + Constant definitions for all resources defined in spanapp.rc. +*/ + + +// +// IDHELP BorButton for BWCC dialogs. +// +#define IDHELP 998 // Id of help button + + +// +// Application specific definitions: +// +#define IDI_SDIAPPLICATION 1001 // Application icon + +#define SDI_MENU 100 // Menu resource ID and Accelerator IDs +#define CM_COMP_TYPE_BINARY 107 +#define CM_COMP_TYPE_ASCII 106 +#define CM_DICT_SIZE_4096 105 +#define CM_DICT_SIZE_2048 104 +#define CM_DICT_SIZE_1024 103 +#define CM_UNCOMPRESS_FILES 102 +#define CM_COMPRESS_FILES 101 + +#define IDM_DOCMANAGERFILE 32401 // Menu for DocManager merging. +#define IDM_EDITVIEW 32581 // Menu for TEditView merging. +#define IDM_LISTVIEW 32582 // Menu for TListView merging. + +// +// CM_FILEnnnn commands (include\owl\editfile.rh except for CM_FILEPRINTPREVIEW) +// +#define CM_FILENEW 24331 // SDI New +#define CM_FILEOPEN 24332 // SDI Open +#define CM_FILECLOSE 24339 +#define CM_FILESAVE 24333 +#define CM_FILESAVEAS 24334 +#define CM_FILEREVERT 24335 +#define CM_VIEWCREATE 24341 + + +// +// Window commands (include\owl\window.rh) +// +#define CM_EXIT 24310 + + +// +// CM_EDITnnnn commands (include\owl\window.rh) +// +#define CM_EDITUNDO 24321 +#define CM_EDITCUT 24322 +#define CM_EDITCOPY 24323 +#define CM_EDITPASTE 24324 +#define CM_EDITDELETE 24325 +#define CM_EDITCLEAR 24326 +#define CM_EDITADD 24327 +#define CM_EDITEDIT 24328 + + +// +// Search menu commands (include\owl\editsear.rh) +// +#define CM_EDITFIND 24351 +#define CM_EDITREPLACE 24352 +#define CM_EDITFINDNEXT 24353 + + +// +// Help menu commands. +// +#define CM_HELPABOUT 2009 + + +// +// About Dialogs +// +#define IDD_ABOUT 22000 +#define IDC_VERSION 22001 +#define IDC_COPYRIGHT 22002 +#define IDC_DEBUG 22003 + + +// +// OWL defined strings +// + +// Statusbar +#define IDS_MODES 32530 +#define IDS_MODESOFF 32531 + + +// EditFile +#define IDS_UNABLEREAD 32551 +#define IDS_UNABLEWRITE 32552 +#define IDS_FILECHANGED 32553 +#define IDS_FILEFILTER 32554 + +// EditSearch +#define IDS_CANNOTFIND 32540 + + +// +// General & application exception messages (include\owl\except.rh) +// +#define IDS_UNKNOWNEXCEPTION 32767 +#define IDS_OWLEXCEPTION 32766 +#define IDS_OKTORESUME 32765 +#define IDS_UNHANDLEDXMSG 32764 +#define IDS_UNKNOWNERROR 32763 +#define IDS_NOAPP 32762 +#define IDS_OUTOFMEMORY 32761 +#define IDS_INVALIDMODULE 32760 +#define IDS_INVALIDMAINWINDOW 32759 +#define IDS_VBXLIBRARYFAIL 32758 + +// +// Owl 1 compatibility messages +// +#define IDS_INVALIDWINDOW 32756 +#define IDS_INVALIDCHILDWINDOW 32755 +#define IDS_INVALIDCLIENTWINDOW 32754 + +// +// TXWindow messages +// +#define IDS_CLASSREGISTERFAIL 32749 +#define IDS_CHILDREGISTERFAIL 32748 +#define IDS_WINDOWCREATEFAIL 32747 +#define IDS_WINDOWEXECUTEFAIL 32746 +#define IDS_CHILDCREATEFAIL 32745 + +#define IDS_MENUFAILURE 32744 +#define IDS_VALIDATORSYNTAX 32743 +#define IDS_PRINTERERROR 32742 + +#define IDS_LAYOUTINCOMPLETE 32741 +#define IDS_LAYOUTBADRELWIN 32740 + +// +// TXGdi messages +// +#define IDS_GDIFAILURE 32739 +#define IDS_GDIALLOCFAIL 32738 +#define IDS_GDICREATEFAIL 32737 +#define IDS_GDIRESLOADFAIL 32736 +#define IDS_GDIFILEREADFAIL 32735 +#define IDS_GDIDELETEFAIL 32734 +#define IDS_GDIDESTROYFAIL 32733 +#define IDS_INVALIDDIBHANDLE 32732 + + +// ListView (include\owl\listview.rh) +#define IDS_LISTNUM 32584 + + +// DocView (include\owl\docview.rh) +#define IDS_DOCMANAGERFILE 32500 +#define IDS_DOCLIST 32501 +#define IDS_VIEWLIST 32502 +#define IDS_UNTITLED 32503 +#define IDS_UNABLEOPEN 32504 +#define IDS_UNABLECLOSE 32505 +#define IDS_READERROR 32506 +#define IDS_WRITEERROR 32507 +#define IDS_DOCCHANGED 32508 +#define IDS_NOTCHANGED 32509 +#define IDS_NODOCMANAGER 32510 +#define IDS_NOMEMORYFORVIEW 32511 +#define IDS_DUPLICATEDOC 32512 + + +// TInputDialog DIALOG resource (include\owl\inputdia.rh) +#define IDD_INPUTDIALOG 32514 +#define ID_PROMPT 4091 +#define ID_INPUT 4090 + + +// TSlider bitmaps (horizontal and vertical) (include\owl\slider.rh) +#define IDB_HSLIDERTHUMB 32000 +#define IDB_VSLIDERTHUMB 32001 + + +// Validation messages (include\owl\validate.rh) +#define IDS_VALPXPCONFORM 32520 +#define IDS_VALINVALIDCHAR 32521 +#define IDS_VALNOTINRANGE 32522 +#define IDS_VALNOTINLIST 32523 + + +//#endif // __spanapp_rh sentry. diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNABTDL.CPP b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNABTDL.CPP new file mode 100644 index 0000000..e2dfc02 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNABTDL.CPP @@ -0,0 +1,157 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include +#pragma hdrstop + +#if !defined(__FLAT__) +#include +#endif + +#include "spanapp.h" +#include "spnabtdl.h" + + +ProjectRCVersion::ProjectRCVersion (TModule *module) +{ + char appFName[255]; + char subBlockName[255]; + DWORD fvHandle; + UINT vSize; + + FVData = 0; + + module->GetModuleFileName(appFName, sizeof(appFName)); + OemToAnsi(appFName, appFName); + DWORD dwSize = ::GetFileVersionInfoSize(appFName, &fvHandle); + if (dwSize) { + FVData = (void FAR *)new char[(UINT)dwSize]; + if (::GetFileVersionInfo(appFName, fvHandle, dwSize, FVData)) { + // Copy string to buffer so if the -dc compiler switch (Put constant strings in code segments) + // is on VerQueryValue will work under Win16. This works around a problem in Microsoft's ver.dll + // which writes to the string pointed to by subBlockName. + strcpy(subBlockName, "\\VarFileInfo\\Translation"); + if (!::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&TransBlock, &vSize)) { + delete FVData; + FVData = 0; + } else + // Swap the words so wsprintf will print the lang-charset in the correct format. + *(DWORD *)TransBlock = MAKELONG(HIWORD(*(DWORD *)TransBlock), LOWORD(*(DWORD *)TransBlock)); + } + } +} + + +ProjectRCVersion::~ProjectRCVersion () +{ + if (FVData) + delete FVData; +} + + +bool ProjectRCVersion::GetProductName (LPSTR &prodName) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"ProductName"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&prodName, &vSize) : false; +} + + +bool ProjectRCVersion::GetProductVersion (LPSTR &prodVersion) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"ProductVersion"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&prodVersion, &vSize) : false; +} + + +bool ProjectRCVersion::GetCopyright (LPSTR ©right) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"LegalCopyright"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)©right, &vSize) : false; +} + + +bool ProjectRCVersion::GetDebug (LPSTR &debug) +{ + UINT vSize; + char subBlockName[255]; + + wsprintf(subBlockName, "\\StringFileInfo\\%08lx\\%s", *(DWORD *)TransBlock, (LPSTR)"SpecialBuild"); + return FVData ? ::VerQueryValue(FVData, subBlockName, (void FAR* FAR*)&debug, &vSize) : false; +} + + +//{{spanAboutDlg Implementation}} + + +////////////////////////////////////////////////////////// +// spanAboutDlg +// ========== +// Construction/Destruction handling. +spanAboutDlg::spanAboutDlg (TWindow *parent, TResId resId, TModule *module) + : TDialog(parent, resId, module) +{ + // INSERT>> Your constructor code here. +} + + +spanAboutDlg::~spanAboutDlg () +{ + Destroy(); + + // INSERT>> Your destructor code here. +} + + +void spanAboutDlg::SetupWindow () +{ + LPSTR prodName = 0, prodVersion = 0, copyright = 0, debug = 0; + + // Get the static text for the value based on VERSIONINFO. + TStatic *versionCtrl = new TStatic(this, IDC_VERSION, 255); + TStatic *copyrightCtrl = new TStatic(this, IDC_COPYRIGHT, 255); + TStatic *debugCtrl = new TStatic(this, IDC_DEBUG, 255); + + TDialog::SetupWindow(); + + // Process the VERSIONINFO. + ProjectRCVersion applVersion(GetModule()); + + // Get the product name and product version strings. + if (applVersion.GetProductName(prodName) && applVersion.GetProductVersion(prodVersion)) { + // IDC_VERSION is the product name and version number, the initial value of IDC_VERSION is + // the word Version (in whatever language) product name VERSION product version. + char buffer[255]; + char versionName[128]; + + buffer[0] = '\0'; + versionName[0] = '\0'; + + versionCtrl->GetText(versionName, sizeof(versionName)); + wsprintf(buffer, "%s %s %s", prodName, versionName, prodVersion); + + versionCtrl->SetText(buffer); + } + + //Get the legal copyright string. + if (applVersion.GetCopyright(copyright)) + copyrightCtrl->SetText(copyright); + + // Only get the SpecialBuild text if the VERSIONINFO resource is there. + if (applVersion.GetDebug(debug)) + debugCtrl->SetText(debug); +} diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNABTDL.H b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNABTDL.H new file mode 100644 index 0000000..f7ad9bb --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNABTDL.H @@ -0,0 +1,53 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#if !defined(__spnabtdl_h) // Sentry, use file only if it's not already included. +#define __spnabtdl_h + +#include +#pragma hdrstop + +#include "spanapp.rh" // Definition of all resources. + + +//{{TDialog = spanAboutDlg}} +class spanAboutDlg : public TDialog { +public: + spanAboutDlg (TWindow *parent, TResId resId = IDD_ABOUT, TModule *module = 0); + virtual ~spanAboutDlg (); + +//{{spanAboutDlgVIRTUAL_BEGIN}} +public: + void SetupWindow (); +//{{spanAboutDlgVIRTUAL_END}} +}; //{{spanAboutDlg}} + + +// Reading the VERSIONINFO resource. +class ProjectRCVersion { +public: + ProjectRCVersion (TModule *module); + virtual ~ProjectRCVersion (); + + bool GetProductName (LPSTR &prodName); + bool GetProductVersion (LPSTR &prodVersion); + bool GetCopyright (LPSTR ©right); + bool GetDebug (LPSTR &debug); + +protected: + LPBYTE TransBlock; + void FAR *FVData; + +private: + // Don't allow this object to be copied. + ProjectRCVersion (const ProjectRCVersion &); + ProjectRCVersion & operator =(const ProjectRCVersion &); +}; + + +#endif // __spnabtdl_h sentry. diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNEDTVW.CPP b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNEDTVW.CPP new file mode 100644 index 0000000..783d687 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNEDTVW.CPP @@ -0,0 +1,38 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ + +#include +#pragma hdrstop + +#include "spanapp.h" +#include "spnedtvw.h" + +#include + + +//{{spanEditView Implementation}} + + +////////////////////////////////////////////////////////// +// spanEditView +// ========== +// Construction/Destruction handling. +spanEditView::spanEditView (TDocument& doc, TWindow* parent) + : TEditView(doc, parent) +{ + // INSERT>> Your constructor code here. + +} + + +spanEditView::~spanEditView () +{ + // INSERT>> Your destructor code here. + +} diff --git a/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNEDTVW.H b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNEDTVW.H new file mode 100644 index 0000000..b983307 --- /dev/null +++ b/Storm/PKWARE/EXAMPLES/OWL/SPAN/SPNEDTVW.H @@ -0,0 +1,27 @@ +/* + ******************************************************************* + *** Important information for use with the *** + *** PKWARE Data Compression Library (R) for Win32 *** + *** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** + *** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** + ******************************************************************* + */ +#if !defined(__spnedtvw_h) // Sentry, use file only if it's not already included. +#define __spnedtvw_h + +#include +#pragma hdrstop + + +#include "spanapp.rh" // Definition of all resources. + + +//{{TEditView = spanEditView}} +class spanEditView : public TEditView { +public: + spanEditView (TDocument& doc, TWindow* parent = 0); + virtual ~spanEditView (); +}; //{{spanEditView}} + + +#endif // __spnedtvw_h sentry. diff --git a/Storm/PKWARE/H/IMPLODE.H b/Storm/PKWARE/H/IMPLODE.H new file mode 100644 index 0000000..c65ccc1 --- /dev/null +++ b/Storm/PKWARE/H/IMPLODE.H @@ -0,0 +1,44 @@ +/*************************************************************** + PKWARE Data Compression Library (R) for Win32 + Copyright 1991,1992,1994,1995 PKWARE Inc. All Rights Reserved. + PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. +***************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int __cdecl implode( + unsigned int (__cdecl *read_buf)(char *buf, unsigned int *size, void *param), + void (__cdecl *write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int __cdecl explode( + unsigned int (__cdecl *read_buf)(char *buf, unsigned int *size, void *param), + void (__cdecl *write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +unsigned long __cdecl crc32(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + + +#define CMP_BUFFER_SIZE 36312 +#define EXP_BUFFER_SIZE 12596 + +#define CMP_BINARY 0 +#define CMP_ASCII 1 + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + diff --git a/Storm/PKWARE/LIB/IMPBORL.LIB b/Storm/PKWARE/LIB/IMPBORL.LIB new file mode 100644 index 0000000..f0fc096 Binary files /dev/null and b/Storm/PKWARE/LIB/IMPBORL.LIB differ diff --git a/Storm/PKWARE/LIB/IMPBORLI.LIB b/Storm/PKWARE/LIB/IMPBORLI.LIB new file mode 100644 index 0000000..9ef7765 Binary files /dev/null and b/Storm/PKWARE/LIB/IMPBORLI.LIB differ diff --git a/Storm/PKWARE/LIB/IMPLODE.LIB b/Storm/PKWARE/LIB/IMPLODE.LIB new file mode 100644 index 0000000..4cc55e1 Binary files /dev/null and b/Storm/PKWARE/LIB/IMPLODE.LIB differ diff --git a/Storm/PKWARE/LIB/IMPLODEI.LIB b/Storm/PKWARE/LIB/IMPLODEI.LIB new file mode 100644 index 0000000..ca0b4df Binary files /dev/null and b/Storm/PKWARE/LIB/IMPLODEI.LIB differ diff --git a/Storm/PKWARE/README b/Storm/PKWARE/README new file mode 100644 index 0000000..024007d --- /dev/null +++ b/Storm/PKWARE/README @@ -0,0 +1,79 @@ +******************************************************************* +*** Important information for use with the *** +*** PKWARE Data Compression Library (R) for Win32 *** +*** Copyright 1995 by PKWARE Inc. All Rights Reserved. *** +*** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off. *** +******************************************************************* + +* Please read the following file before calling PKWARE for technical support! + +*************************************************************************** + + +* When installing the PKWARE Data Compression Library for Win32, you + should keep the directory structure of the floppy intact on your hard + disk. Use the supplied INSTALL.BAT file to install the files from the + floppy disk to your hard disk. To use the INSTALL.BAT program, type: + + [source:]install [source:] [destination:] + + where [source:] is the PKWARE distribution disk + and [destination:] is the target disk. + + The PKWARE Data Compression Library will be installed in a directory + called PKW32DCL on the destination drive. + + +* For more information on the examples, read the EXAMPLES.TXT file. + + + F I L E D E S C R I P T I O N S +-------------------------------------------------------------- + +implode.lib Static link library (includes all .OBJ files). + +implodei.lib Dynamic link import library for use with DLL files. + +impborl.lib Static link library for Borland C++ compiler (includes + all .OBJ files). + +impborli.lib Dynamic link import library for Borland C++ compiler, + for use with DLL files. + +implode.dll Dynamic link library of the PKWARE Data Compression Library. + +impborl.dll Dynamic link library created by Borland C++ compiler. + +crc32.obj Object module file for CRC-32 error checking routine. + +crcborl.obj Borland C++ Object module file for CRC-32 error checking + routine. + +crcfast.obj __fastcall calling convention object module file for CRC-32 + error checking routine. + +crcstd.obj __stdcall calling convention object module file for CRC-32 + error checking routine. + +explode.obj Object module file for explode routine. + +expborl.obj Borland C++ Object module file for explode routine. + +expfast.obj __fastcall calling convention object module file for explode + routine. + +expstd.obj __stdcall calling convention object module file for explode + routine. + +implode.obj Object module file for implode routine. + +impborl.obj Borland C++ Object module file for implode routine. + +impfast.obj __fastcall calling convention object module file for implode + routine. + +impstd.obj __stdcall calling convention object module file for implode + routine. + +implode.h A C/C++ header file for use with the PKWARE Data Compression + Library. diff --git a/Storm/SAMPLES/ANIM/ANIM1/ANIM1.CPP b/Storm/SAMPLES/ANIM/ANIM1/ANIM1.CPP new file mode 100644 index 0000000..a5a6990 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM1/ANIM1.CPP @@ -0,0 +1,241 @@ +/**************************************************************************** +* +* ANIM1.CPP +* +* This is the first of a series of programs that demonstrate progressively +* better ways to do animation. +* +* This first program just composites each frame to an offscreen buffer, +* then blits the offscreen buffer onto the screen. +* +***/ + +#include +#include +#include + +#define SPRITES 4 + +#define SIN(a) sintable[((a) & 255)] +#define COS(a) sintable[(((a)+64) & 255)] + +static LPBYTE backgroundbuffer = NULL; +static HSGDIFONT font = 0; +static LPBYTE offscreenbuffer = NULL; +static HSTRANS overlay = 0; +static int sintable[256]; +static HSTRANS sprite[SPRITES] = {0,0,0,0}; + +//=========================================================================== +static BOOL CreateBackgroundBuffer () { + backgroundbuffer = (LPBYTE)ALLOC(640*480); + if (!backgroundbuffer) + return 0; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\bkg.pcx",&pe[0],backgroundbuffer,640*480)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +static BOOL CreateOffscreenBuffer () { + offscreenbuffer = (LPBYTE)ALLOC(640*480); + if (!offscreenbuffer) + return 0; + CopyMemory(offscreenbuffer,backgroundbuffer,640*480); + return 1; +} + +//=========================================================================== +static void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +static void DisplayFramesPerSecond (LPBYTE buffer, int pitch) { + static DWORD frames = 0; + static DWORD lastfps = 0; + static DWORD lasttime = GetTickCount(); + + // UPDATE THE NUMBER OF FRAMES THIS SECOND + if (GetTickCount()-lasttime >= 1000) { + lastfps = frames; + frames = 0; + lasttime += 1000; + } + ++frames; + + // DISPLAY THE LAST NUMBER OF FRAMES PER SECOND + char outstr[16]; + wsprintf(outstr,"%3u FPS",lastfps); + RECT rect = {0,20,60,32}; + SGdiSetPitch(pitch); + SGdiExtTextOut(buffer, + 0, + 20, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + +} + +//=========================================================================== +static BOOL CALLBACK IdleProc (DWORD) { + + // INITIALIZE THE OFFSCREEN BUFFER USING THE BACKGROUND IMAGE + CopyMemory(offscreenbuffer,backgroundbuffer,640*480); + + // DRAW EACH SPRITE INTO THE OFFSCREEN BUFFER + { + static BYTE distance = 0; + static BYTE rotation = 0; + for (int loop = 0; loop < SPRITES; ++loop) { + int x = 170+(SIN(rotation+64*loop)*SIN(distance/2)/100); + int y = 165+(COS(rotation+64*loop)*SIN(distance/2)/100); + STransBlt(offscreenbuffer, + x, + y, + 640, + sprite[loop]); + } + ++distance; + rotation += 3; + } + + // DRAW THE STATUS BAR INTO THE OFFSCREEN BUFFER + STransBlt(offscreenbuffer, + 0, + 0, + 640, + overlay); + + // DRAW THE FRAMES PER SECOND COUNTER INTO THE OFFSCREEN BUFFER + DisplayFramesPerSecond(offscreenbuffer,640); + + // COPY THE OFFSCREEN BUFFER ONTO THE SCREEN + { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiBitBlt(videobuffer, + 0, + 0, + offscreenbuffer, + NULL, + 640, + 480); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + } + + return TRUE; +} + +//=========================================================================== +static BOOL LoadFont () { + { + HFONT winfont = CreateFont(-12,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +static BOOL LoadOverlay () { + LPBYTE temp = (LPBYTE)ALLOC(640*480); + if (!SBmpLoadImage("..\\demodata\\overlay.pcx",NULL,temp,640*480)) + return 0; + if (!STransCreate(temp,640,480,8,NULL,PALETTEINDEX(111),&overlay)) + return 0; + FREE(temp); + return 1; +} + +//=========================================================================== +static BOOL LoadSprites () { + LPBYTE temp = (LPBYTE)ALLOC(300*500); + if (!SBmpLoadImage("..\\demodata\\sprites.pcx",NULL,temp,300*500)) + return 0; + for (int loop = 0; loop < SPRITES; ++loop) { + RECT rect = {0,loop*125,299,loop*125+124}; + if (!STransCreate(temp,300,500,8,&rect,PALETTEINDEX(*temp),&sprite[loop])) + return 0; + } + FREE(temp); + return 1; +} + +//=========================================================================== +static void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbuffer); + FREE(offscreenbuffer); + SGdiDeleteObject(font); + STransDelete(overlay); + for (int loop = 0; loop < SPRITES; ++loop) + STransDelete(sprite[loop]); +} + +//=========================================================================== +static void CALLBACK OnPaint (LPPARAMS params) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SBltROP3(videobuffer, + offscreenbuffer, + 640, + 480, + videopitch, + 640, + 0, + SRCCOPY); + STransBlt(videobuffer, + 0, + 0, + videopitch, + overlay); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + ValidateRect(params->window,NULL); + params->useresult = TRUE; + params->result = 0; +} + +//=========================================================================== +static void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + TEXT("ANIM1"), + TEXT("Animation Example 1"))) + FATALRESULT("SDrawAutoInitialize()"); + if (!CreateBackgroundBuffer()) + FATALRESULT("CreateBackgroundBuffer()"); + if (!CreateOffscreenBuffer()) + FATALRESULT("CreateOffsreenBuffer()"); + if (!LoadFont()) + FATALRESULT("LoadFont()"); + if (!LoadOverlay()) + FATALRESULT("LoadOverlay()"); + if (!LoadSprites()) + FATALRESULT("LoadSprites()"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/ANIM/ANIM1/ANIM1.CS b/Storm/SAMPLES/ANIM/ANIM1/ANIM1.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM1/ANIM1.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/ANIM/ANIM1/ANIM1.EXE b/Storm/SAMPLES/ANIM/ANIM1/ANIM1.EXE new file mode 100644 index 0000000..a565b41 Binary files /dev/null and b/Storm/SAMPLES/ANIM/ANIM1/ANIM1.EXE differ diff --git a/Storm/SAMPLES/ANIM/ANIM2/ANIM2.CPP b/Storm/SAMPLES/ANIM/ANIM2/ANIM2.CPP new file mode 100644 index 0000000..435c245 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM2/ANIM2.CPP @@ -0,0 +1,234 @@ +/**************************************************************************** +* +* ANIM2.CPP +* +* This sample application demonstrates the use of overlays. +* +* Instead of drawing the entire screen every frame, this application draws +* only the portion which is not covered up by the status bar, since the +* status bar is known not to change. +* +***/ + +#include +#include +#include + +#define SPRITES 4 + +#define SIN(a) sintable[((a) & 255)] +#define COS(a) sintable[(((a)+64) & 255)] + +static LPBYTE backgroundbuffer = NULL; +static HSGDIFONT font = 0; +static LPBYTE offscreenbuffer = NULL; +static HSTRANS overlay = 0; +static HSTRANS updatemask = 0; +static int sintable[256]; +static HSTRANS sprite[SPRITES] = {0,0,0,0}; + +//=========================================================================== +static BOOL CreateBackgroundBuffer () { + backgroundbuffer = (LPBYTE)ALLOC(640*480); + if (!backgroundbuffer) + return 0; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\bkg.pcx",&pe[0],backgroundbuffer,640*480)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +static BOOL CreateOffscreenBuffer () { + offscreenbuffer = (LPBYTE)ALLOC(640*480); + if (!offscreenbuffer) + return 0; + CopyMemory(offscreenbuffer,backgroundbuffer,640*480); + return 1; +} + +//=========================================================================== +static void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +static void DisplayFramesPerSecond (LPBYTE buffer, int pitch) { + static DWORD frames = 0; + static DWORD lastfps = 0; + static DWORD lasttime = GetTickCount(); + + // UPDATE THE NUMBER OF FRAMES THIS SECOND + if (GetTickCount()-lasttime >= 1000) { + lastfps = frames; + frames = 0; + lasttime += 1000; + } + ++frames; + + // DISPLAY THE LAST NUMBER OF FRAMES PER SECOND + char outstr[16]; + wsprintf(outstr,"%3u FPS",lastfps); + RECT rect = {0,20,60,32}; + SGdiSetPitch(pitch); + SGdiExtTextOut(buffer, + 0, + 20, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + +} + +//=========================================================================== +static BOOL CALLBACK IdleProc (DWORD) { + + // INITIALIZE THE OFFSCREEN BUFFER USING THE BACKGROUND IMAGE + CopyMemory(offscreenbuffer,backgroundbuffer,640*480); + + // DRAW EACH SPRITE INTO THE OFFSCREEN BUFFER + { + static BYTE distance = 0; + static BYTE rotation = 0; + for (int loop = 0; loop < SPRITES; ++loop) { + int x = 170+(SIN(rotation+64*loop)*SIN(distance/2)/100); + int y = 165+(COS(rotation+64*loop)*SIN(distance/2)/100); + STransBlt(offscreenbuffer, + x, + y, + 640, + sprite[loop]); + } + ++distance; + rotation += 3; + } + + // DRAW THE FRAMES PER SECOND COUNTER INTO THE OFFSCREEN BUFFER + DisplayFramesPerSecond(offscreenbuffer,640); + + // DRAW THE OFFSCREEN BUFFER ONTO THE SCREEN, BLITTING AROUND THE + // STATUS BAR + { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + STransBltUsingMask(videobuffer, + offscreenbuffer, + videopitch, + 640, + updatemask); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + } + + return TRUE; +} + +//=========================================================================== +static BOOL LoadFont () { + { + HFONT winfont = CreateFont(-12,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +static BOOL LoadOverlay () { + LPBYTE temp = (LPBYTE)ALLOC(640*480); + if (!SBmpLoadImage("..\\demodata\\overlay.pcx",NULL,temp,640*480)) + return 0; + if (!STransCreate(temp,640,480,8,NULL,PALETTEINDEX(111),&overlay)) + return 0; + if (!STransInvertMask(overlay,&updatemask)) + return 0; + FREE(temp); + return 1; +} + +//=========================================================================== +static BOOL LoadSprites () { + LPBYTE temp = (LPBYTE)ALLOC(300*500); + if (!SBmpLoadImage("..\\demodata\\sprites.pcx",NULL,temp,300*500)) + return 0; + for (int loop = 0; loop < SPRITES; ++loop) { + RECT rect = {0,loop*125,299,loop*125+124}; + if (!STransCreate(temp,300,500,8,&rect,PALETTEINDEX(*temp),&sprite[loop])) + return 0; + } + FREE(temp); + return 1; +} + +//=========================================================================== +static void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbuffer); + FREE(offscreenbuffer); + SGdiDeleteObject(font); + STransDelete(overlay); + STransDelete(updatemask); + for (int loop = 0; loop < SPRITES; ++loop) + STransDelete(sprite[loop]); +} + +//=========================================================================== +static void CALLBACK OnPaint (LPPARAMS params) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + STransBltUsingMask(videobuffer, + offscreenbuffer, + videopitch, + 640, + updatemask); + STransBlt(videobuffer, + 0, + 0, + videopitch, + overlay); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + ValidateRect(params->window,NULL); + params->useresult = TRUE; + params->result = 0; +} + +//=========================================================================== +static void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + TEXT("ANIM3"), + TEXT("Animation Example 3"))) + FATALRESULT("SDrawAutoInitialize()"); + if (!CreateBackgroundBuffer()) + FATALRESULT("CreateBackgroundBuffer()"); + if (!CreateOffscreenBuffer()) + FATALRESULT("CreateOffsreenBuffer()"); + if (!LoadFont()) + FATALRESULT("LoadFont()"); + if (!LoadOverlay()) + FATALRESULT("LoadOverlay()"); + if (!LoadSprites()) + FATALRESULT("LoadSprites()"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/ANIM/ANIM2/ANIM2.CS b/Storm/SAMPLES/ANIM/ANIM2/ANIM2.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM2/ANIM2.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/ANIM/ANIM2/ANIM2.EXE b/Storm/SAMPLES/ANIM/ANIM2/ANIM2.EXE new file mode 100644 index 0000000..33d207b Binary files /dev/null and b/Storm/SAMPLES/ANIM/ANIM2/ANIM2.EXE differ diff --git a/Storm/SAMPLES/ANIM/ANIM3/ANIM3.CPP b/Storm/SAMPLES/ANIM/ANIM3/ANIM3.CPP new file mode 100644 index 0000000..d23aa45 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM3/ANIM3.CPP @@ -0,0 +1,251 @@ +/**************************************************************************** +* +* ANIM3.CPP +* +* This sample application improves on the performance of Anim2 by reducing +* the amount of time it has to spend repainting the offscreen buffer. +* Instead of erasing the entire offscreen buffer with the background every +* frame, it only erases those portions that were covered by a sprite last +* frame. +* +* A weakness of this sample application is that it doesn't test whether +* a portion of the offscreen buffer has already been erased before erasing +* it again. This means its performance will degrade substantially as more +* of the screen gets covered by sprites, potentially at some point becoming +* slower than Anim2. +* +***/ + +#include +#include +#include + +#define SPRITES 4 + +#define SIN(a) sintable[((a) & 255)] +#define COS(a) sintable[(((a)+64) & 255)] + +static LPBYTE backgroundbuffer = NULL; +static HSGDIFONT font = 0; +static LPBYTE offscreenbuffer = NULL; +static HSTRANS overlay = 0; +static HSTRANS updatemask = 0; +static int sintable[256]; +static HSTRANS sprite[SPRITES] = {0,0,0,0}; + +//=========================================================================== +static BOOL CreateBackgroundBuffer () { + backgroundbuffer = (LPBYTE)ALLOC(640*480); + if (!backgroundbuffer) + return 0; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\bkg.pcx",&pe[0],backgroundbuffer,640*480)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +static BOOL CreateOffscreenBuffer () { + offscreenbuffer = (LPBYTE)ALLOC(640*480); + if (!offscreenbuffer) + return 0; + CopyMemory(offscreenbuffer,backgroundbuffer,640*480); + return 1; +} + +//=========================================================================== +static void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +static void DisplayFramesPerSecond (LPBYTE buffer, int pitch) { + static DWORD frames = 0; + static DWORD lastfps = 0; + static DWORD lasttime = GetTickCount(); + + // UPDATE THE NUMBER OF FRAMES THIS SECOND + if (GetTickCount()-lasttime >= 1000) { + lastfps = frames; + frames = 0; + lasttime += 1000; + } + ++frames; + + // DISPLAY THE LAST NUMBER OF FRAMES PER SECOND + char outstr[16]; + wsprintf(outstr,"%3u FPS",lastfps); + RECT rect = {0,20,60,32}; + SGdiSetPitch(pitch); + SGdiExtTextOut(buffer, + 0, + 20, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + +} + +//=========================================================================== +static BOOL CALLBACK IdleProc (DWORD) { + static BYTE distance = 0; + static BYTE rotation = 0; + + // ERASE EACH SPRITE THAT WAS DRAWN LAST FRAME FROM THE OFFSCREEN BUFFER + // BY OVERWRITING IT WITH DATA FROM THE BACKGROUND + { + for (int loop = 0; loop < SPRITES; ++loop) { + int x = 170+(SIN(rotation+64*loop)*SIN(distance/2)/100); + int y = 165+(COS(rotation+64*loop)*SIN(distance/2)/100); + STransBltUsingMask(offscreenbuffer+y*640+x, + backgroundbuffer+y*640+x, + 640, + 640, + sprite[loop]); + } + } + + // DRAW EACH SPRITE IN ITS NEW POSITION INTO THE OFFSCREEN BUFFER + ++distance; + rotation += 3; + { + for (int loop = 0; loop < SPRITES; ++loop) { + int x = 170+(SIN(rotation+64*loop)*SIN(distance/2)/100); + int y = 165+(COS(rotation+64*loop)*SIN(distance/2)/100); + STransBlt(offscreenbuffer, + x, + y, + 640, + sprite[loop]); + } + } + + // DRAW THE FRAMES PER SECOND COUNTER INTO THE OFFSCREEN BUFFER + DisplayFramesPerSecond(offscreenbuffer,640); + + // DRAW THE OFFSCREEN BUFFER ONTO THE SCREEN, BLITTING AROUND THE + // STATUS BAR + { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + STransBltUsingMask(videobuffer, + offscreenbuffer, + videopitch, + 640, + updatemask); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + } + + return TRUE; +} + +//=========================================================================== +static BOOL LoadFont () { + { + HFONT winfont = CreateFont(-12,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +static BOOL LoadOverlay () { + LPBYTE temp = (LPBYTE)ALLOC(640*480); + if (!SBmpLoadImage("..\\demodata\\overlay.pcx",NULL,temp,640*480)) + return 0; + if (!STransCreate(temp,640,480,8,NULL,PALETTEINDEX(111),&overlay)) + return 0; + if (!STransInvertMask(overlay,&updatemask)) + return 0; + FREE(temp); + return 1; +} + +//=========================================================================== +static BOOL LoadSprites () { + LPBYTE temp = (LPBYTE)ALLOC(300*500); + if (!SBmpLoadImage("..\\demodata\\sprites.pcx",NULL,temp,300*500)) + return 0; + for (int loop = 0; loop < SPRITES; ++loop) { + RECT rect = {0,loop*125,299,loop*125+124}; + if (!STransCreate(temp,300,500,8,&rect,PALETTEINDEX(*temp),&sprite[loop])) + return 0; + } + FREE(temp); + return 1; +} + +//=========================================================================== +static void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbuffer); + FREE(offscreenbuffer); + SGdiDeleteObject(font); + STransDelete(overlay); + STransDelete(updatemask); + for (int loop = 0; loop < SPRITES; ++loop) + STransDelete(sprite[loop]); +} + +//=========================================================================== +static void CALLBACK OnPaint (LPPARAMS params) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + STransBltUsingMask(videobuffer, + offscreenbuffer, + videopitch, + 640, + updatemask); + STransBlt(videobuffer, + 0, + 0, + videopitch, + overlay); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + ValidateRect(params->window,NULL); + params->useresult = TRUE; + params->result = 0; +} + +//=========================================================================== +static void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + TEXT("ANIM3"), + TEXT("Animation Example 3"))) + FATALRESULT("SDrawAutoInitialize()"); + if (!CreateBackgroundBuffer()) + FATALRESULT("CreateBackgroundBuffer()"); + if (!CreateOffscreenBuffer()) + FATALRESULT("CreateOffsreenBuffer()"); + if (!LoadFont()) + FATALRESULT("LoadFont()"); + if (!LoadOverlay()) + FATALRESULT("LoadOverlay()"); + if (!LoadSprites()) + FATALRESULT("LoadSprites()"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/ANIM/ANIM3/ANIM3.CS b/Storm/SAMPLES/ANIM/ANIM3/ANIM3.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM3/ANIM3.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/ANIM/ANIM3/ANIM3.EXE b/Storm/SAMPLES/ANIM/ANIM3/ANIM3.EXE new file mode 100644 index 0000000..c3a2293 Binary files /dev/null and b/Storm/SAMPLES/ANIM/ANIM3/ANIM3.EXE differ diff --git a/Storm/SAMPLES/ANIM/ANIM4/ANIM4.CPP b/Storm/SAMPLES/ANIM/ANIM4/ANIM4.CPP new file mode 100644 index 0000000..6ff9220 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM4/ANIM4.CPP @@ -0,0 +1,293 @@ +/**************************************************************************** +* +* ANIM4.CPP +* +* This sample application introduces the use of dirty rectangles. +* +* The application keeps an array of dirty cells, each one representing a +* 16x16 pixel area of the screen. Each cell contains one bit telling +* whether the cell has been updated this frame, and another bit telling +* whether it was updated last frame. For each frame we need to blit to +* the screen cells that have either bit set, so that sprites will be erased +* from their old positions and drawn to their new positions. +* +* The screen drawing function starts by clearing the update bits in each +* cell. Next, it erases the sprites from their old positions on the +* offscreen buffer, using an erase mask which will be described later. +* Next, it draws the sprites to their new positions on the offscreen buffer, +* and marks each cell that's touched by a sprite as dirty. Finally, it +* creates an update mask which is the intersection of the screen mask +* (that portion of the screen which is not covered by the status bar) and +* the array of dirty cells. It uses this update mask to blit the offscreen +* buffer onto the screen. Then it saves the update mask to use as the +* erase mask for the next frame. +* +* In addition to the use of a dirty rectangle system, the fact that we have +* a screen update mask which we are able to use as an erase mask for the +* next frame substantially decreases the amount of time required to erase +* the offscreen buffer. There is never a case when a portion of the +* offscreen buffer is erased more than once, as in Anim3. Also, the +* application never wastes time erasing the portion of the offscreen buffer +* which is covered up by the status bar. +* +***/ + +#include +#include +#include + +#define SPRITES 4 + +#define SIN(a) sintable[((a) & 255)] +#define COS(a) sintable[(((a)+64) & 255)] + +static LPBYTE backgroundbuffer = NULL; +static HSTRANS baseupdatemask = 0; +static HSTRANS currupdatemask = 0; +static LPBYTE dirtycells = NULL; +static HSGDIFONT font = 0; +static LPBYTE offscreenbuffer = NULL; +static HSTRANS overlay = 0; +static int sintable[256]; +static HSTRANS sprite[SPRITES] = {0,0,0,0}; + +//=========================================================================== +static BOOL CreateBackgroundBuffer () { + backgroundbuffer = (LPBYTE)ALLOC(640*480); + if (!backgroundbuffer) + return 0; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\bkg.pcx",&pe[0],backgroundbuffer,640*480)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +static BOOL CreateDirtyCellArray () { + dirtycells = (LPBYTE)ALLOC(40*30); + if (!dirtycells) + return 0; + ZeroMemory(dirtycells,40*30); + STransSetDirtyArrayInfo(640,480,16,16); + return 1; +} + +//=========================================================================== +static BOOL CreateOffscreenBuffer () { + offscreenbuffer = (LPBYTE)ALLOC(640*480); + if (!offscreenbuffer) + return 0; + CopyMemory(offscreenbuffer,backgroundbuffer,640*480); + return 1; +} + +//=========================================================================== +static void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +static void DisplayFramesPerSecond (LPBYTE buffer, int pitch) { + static DWORD frames = 0; + static DWORD lastfps = 0; + static DWORD lasttime = GetTickCount(); + + // UPDATE THE NUMBER OF FRAMES THIS SECOND + if (GetTickCount()-lasttime >= 1000) { + lastfps = frames; + frames = 0; + lasttime += 1000; + } + ++frames; + + // DISPLAY THE LAST NUMBER OF FRAMES PER SECOND + char outstr[16]; + wsprintf(outstr,"%3u FPS",lastfps); + RECT rect = {0,20,60,32}; + SGdiSetPitch(pitch); + SGdiExtTextOut(buffer, + 0, + 20, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + +} + +//=========================================================================== +static BOOL CALLBACK IdleProc (DWORD) { + static BYTE dirtyvalue = 1; + + // [1] BLT THE BACKGROUND BUFFER OVER THE DIRTY PORTIONS OF THE OFFSCREEN + // BUFFER + STransBltUsingMask(offscreenbuffer,backgroundbuffer,640,640,currupdatemask); + + // [2] CLEAR THE ARRAY OF DIRTY CELLS + dirtyvalue = 3-dirtyvalue; + { + for (int loop = 0; loop < 40*30; ++loop) + *(dirtycells+loop) &= ~dirtyvalue; + } + + // [3] DRAW THE SPRITES ONTO THE OFFSCREEN BUFFER, UPDATING THE ARRAY OF + // DIRTY CELLS + { + static BYTE distance = 0; + static BYTE rotation = 0; + for (int loop = 0; loop < SPRITES; ++loop) { + int x = 170+(SIN(rotation+64*loop)*SIN(distance/2)/100); + int y = 165+(COS(rotation+64*loop)*SIN(distance/2)/100); + STransBlt(offscreenbuffer, + x, + y, + 640, + sprite[loop]); + STransUpdateDirtyArray(dirtycells, + dirtyvalue, + x, + y, + sprite[loop], + 0); + } + ++distance; + rotation += 3; + } + + // [4] DELETE THE OLD UPDATE MASK, AND CREATE A NEW ONE WHICH IS THE + // INTERSECTION OF THE ARRAY OF THE CURRENTLY DIRTY CELLS AND THE + // AREA NOT COVERED BY THE OVERLAY + STransDelete(currupdatemask); + STransIntersectDirtyArray(baseupdatemask,dirtycells,3,&currupdatemask); + + // [5] BLT THE OFFSCREEN BUFFER ONTO THE SCREEN USING THE NEW MASK + { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + STransBltUsingMask(videobuffer, + offscreenbuffer, + videopitch, + 640, + currupdatemask); + DisplayFramesPerSecond(videobuffer,videopitch); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + } + + return TRUE; +} + +//=========================================================================== +static BOOL LoadFont () { + { + HFONT winfont = CreateFont(-12,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +static BOOL LoadOverlay () { + LPBYTE temp = (LPBYTE)ALLOC(640*480); + if (!SBmpLoadImage("..\\demodata\\overlay.pcx",NULL,temp,640*480)) + return 0; + if (!STransCreate(temp,640,480,8,NULL,PALETTEINDEX(111),&overlay)) + return 0; + if (!STransInvertMask(overlay,&baseupdatemask)) + return 0; + if (!STransDuplicate(baseupdatemask,&currupdatemask)) + return 0; + FREE(temp); + return 1; +} + +//=========================================================================== +static BOOL LoadSprites () { + LPBYTE temp = (LPBYTE)ALLOC(300*500); + if (!SBmpLoadImage("..\\demodata\\sprites.pcx",NULL,temp,300*500)) + return 0; + for (int loop = 0; loop < SPRITES; ++loop) { + RECT rect = {0,loop*125,299,loop*125+124}; + if (!STransCreate(temp,300,500,8,&rect,PALETTEINDEX(*temp),&sprite[loop])) + return 0; + } + FREE(temp); + return 1; +} + +//=========================================================================== +static void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbuffer); + FREE(dirtycells); + FREE(offscreenbuffer); + SGdiDeleteObject(font); + STransDelete(overlay); + STransDelete(baseupdatemask); + STransDelete(currupdatemask); + for (int loop = 0; loop < SPRITES; ++loop) + STransDelete(sprite[loop]); +} + +//=========================================================================== +static void CALLBACK OnPaint (LPPARAMS params) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + STransBltUsingMask(videobuffer, + offscreenbuffer, + videopitch, + 640, + baseupdatemask); + STransBlt(videobuffer, + 0, + 0, + videopitch, + overlay); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + ValidateRect(params->window,NULL); + params->useresult = TRUE; + params->result = 0; +} + +//=========================================================================== +static void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + TEXT("ANIM4"), + TEXT("Animation Example 4"))) + FATALRESULT("SDrawAutoInitialize()"); + if (!CreateBackgroundBuffer()) + FATALRESULT("CreateBackgroundBuffer()"); + if (!CreateDirtyCellArray()) + FATALRESULT("CreateDirtyCellArray()"); + if (!CreateOffscreenBuffer()) + FATALRESULT("CreateOffsreenBuffer()"); + if (!LoadFont()) + FATALRESULT("LoadFont()"); + if (!LoadOverlay()) + FATALRESULT("LoadOverlay()"); + if (!LoadSprites()) + FATALRESULT("LoadSprites()"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/ANIM/ANIM4/ANIM4.CS b/Storm/SAMPLES/ANIM/ANIM4/ANIM4.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM4/ANIM4.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/ANIM/ANIM4/ANIM4.EXE b/Storm/SAMPLES/ANIM/ANIM4/ANIM4.EXE new file mode 100644 index 0000000..0f55989 Binary files /dev/null and b/Storm/SAMPLES/ANIM/ANIM4/ANIM4.EXE differ diff --git a/Storm/SAMPLES/ANIM/ANIM5/ANIM5.CPP b/Storm/SAMPLES/ANIM/ANIM5/ANIM5.CPP new file mode 100644 index 0000000..25b0df9 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM5/ANIM5.CPP @@ -0,0 +1,270 @@ +/**************************************************************************** +* +* ANIM5.CPP +* +* Under construction... +* +***/ + +#include "pch.h" +#pragma hdrstop + +#include // note: take this out!! + +//#define COMBINEDOVERLAY + +#define ANIMSPRITES 4 +#define SPRITE_FPS (ANIMSPRITES+0) +#define SPRITE_BKG (ANIMSPRITES+1) +#define SPRITE_OVL1 (ANIMSPRITES+2) +#ifdef COMBINEDOVERLAY +#define SPRITES (ANIMSPRITES+3) +#else +#define SPRITE_OVL2 (ANIMSPRITES+3) +#define SPRITES (ANIMSPRITES+4) +#endif + +#define FPSWIDTH 60 +#define FPSHEIGHT 16 + +#define TRANSCOLOR PALETTEINDEX(111) + +#define SIN(a) s_sintable[((a) & 255)] +#define COS(a) s_sintable[(((a)+64) & 255)] + +static HSGDIFONT s_font; +static HSIMAGE s_fpsimage; +static int s_sintable[256]; +static HSSPRITE s_sprite[SPRITES]; +static HSTARGET s_target; + +static void UpdateFramesPerSecond (); + +//=========================================================================== +static void CreateFont () { + HFONT winfont = CreateFont(-12,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + SGdiImportFont(winfont,&s_font); + DeleteObject(winfont); + SGdiSelectObject(s_font); +} + +//=========================================================================== +static BOOL CreatePalette () { + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\bkg.pcx",&pe[0],NULL,0)) + return FALSE; + SDrawUpdatePalette(0,256,&pe[0]); + return TRUE; +} + +//=========================================================================== +static void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + s_sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +static BOOL CreateSprites () { + DWORD loop; + HSIMAGE imagearray[SPRITES]; + + // LOAD THE ANIMATED SPRITE IMAGES + { + RECT rectarray[ANIMSPRITES]; + for (loop = 0; loop < ANIMSPRITES; ++loop) { + rectarray[loop].left = 0; + rectarray[loop].top = 125*loop; + rectarray[loop].right = 300; + rectarray[loop].bottom = 125*loop+125; + } + if (!S2dImageCreateFromFile("..\\demodata\\sprites.pcx", + TRANSCOLOR, + ANIMSPRITES, + rectarray, + imagearray)) + return FALSE; + } + + // CREATE THE FPS SPRITE IMAGE + S2dImageCreate(FPSWIDTH, + FPSHEIGHT, + 8, + TRANSCOLOR, + &imagearray[SPRITE_FPS]); + + // LOAD THE BACKGROUND SPRITE IMAGE + if (!S2dImageCreateFromFile("..\\demodata\\bkg.pcx", + TRANSCOLOR, + 1, + NULL, + &imagearray[SPRITE_BKG])) + return FALSE; + + // LOAD THE OVERLAY SPRITE IMAGES +#ifdef COMBINEDOVERLAY + if (!S2dImageCreateFromFile("..\\demodata\\overlay.pcx", + TRANSCOLOR, + 1, + NULL, + &imagearray[SPRITE_OVL1])) + return FALSE; +#else + { + RECT rectarray[2] = {{0,0,167,18},{0,295,640,480}}; + if (!S2dImageCreateFromFile("..\\demodata\\overlay.pcx", + TRANSCOLOR, + 2, + rectarray, + &imagearray[SPRITE_OVL1])) + return FALSE; + } +#endif + + // ATTACH THE IMAGES TO SPRITES, AND THEN CLOSE OR SAVE THE IMAGE HANDLES + for (loop = 0; loop < SPRITES; ++loop) { + S2dSpriteCreate(&s_sprite[loop]); + S2dSpriteSetImage(s_sprite[loop],imagearray[loop]); + if (loop == SPRITE_FPS) { + S2dSpriteSetPos(s_sprite[loop],0,20); + s_fpsimage = imagearray[loop]; + } + else { + S2dSpriteSetPos(s_sprite[loop],0,0); +#ifndef COMBINEDOVERLAY +if (loop == SPRITE_OVL2) S2dSpriteSetPos(s_sprite[loop],0,295); +#endif + S2dImageDelete(imagearray[loop]); + } + } + + // CREATE A TARGET, AND ATTACH THE SPRITES TO THE TARGET + S2dTargetCreate(&s_target); + for (loop = 0; loop < SPRITES; ++loop) + S2dSpriteSetTarget(s_sprite[loop], + s_target, + (loop >= SPRITE_OVL1) ? -1 : loop); + + return TRUE; +} + +//=========================================================================== +static BOOL CALLBACK IdleProc (DWORD) { + static BYTE rotation = 0; + static BYTE distance = 0; + ++distance; + rotation += 3; + for (DWORD loop = 0; loop < ANIMSPRITES; ++loop) + S2dSpriteSetPos(s_sprite[loop], + 170+(SIN(rotation+64*loop)*SIN(distance/2)/100), + 165+(COS(rotation+64*loop)*SIN(distance/2)/100)); + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { +//SGdiSetPitch(videopitch); +//SGdiRectangle(videobuffer,0,0,640,480,PALETTEINDEX(255)); + S2dTestDrawTarget(s_target,videobuffer,videopitch); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + UpdateFramesPerSecond(); +//return FALSE; + return TRUE; +} + +//=========================================================================== +static void CALLBACK OnClose (LPPARAMS) { + for (DWORD loop = 0; loop < SPRITES; ++loop) { + S2dSpriteDelete(s_sprite[loop]); + s_sprite[loop] = (HSSPRITE)0; + } + S2dImageDelete(s_fpsimage); + s_fpsimage = (HSIMAGE)0; + S2dTargetDelete(s_target); + s_target = (HSTARGET)0; + SGdiDeleteObject(s_font); + s_font = (HSGDIFONT)0; +} + +//=========================================================================== +static void CALLBACK OnPaint (LPPARAMS params) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + S2dTestDrawTarget(s_target,videobuffer,videopitch); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + ValidateRect(params->window,NULL); + params->useresult = TRUE; + params->result = 0; +} + +//=========================================================================== +static void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +static void UpdateFramesPerSecond () { + static DWORD frames = 0; + static DWORD starttime = GetTickCount(); + static DWORD lasttime = starttime; + + // INCREMENT THE NUMBER OF FRAMES + ++frames; + + // RETURN IF A SECOND HAS NOT YET ELAPSED + if (GetTickCount()-lasttime < 1000) + return; + lasttime += 1000; + + // DRAW THE AVERAGE NUMBER OF FRAMES PER SECOND + LPBYTE ptr; + if (S2dImageLockBuffer(s_fpsimage,FALSE,&ptr)) { + char outstr[16]; + wsprintf(outstr,"%3u FPS",frames/((lasttime-starttime)/1000)); + RECT rect = {0,0,FPSWIDTH,FPSHEIGHT}; + SGdiSetTargetDimensions(FPSWIDTH, + FPSHEIGHT, + 8, + FPSWIDTH); + SGdiExtTextOut(ptr, + 0, + 0, + &rect, + TRANSCOLOR, + ETO_TEXT_WHITE, + ETO_BKG_COLOR, + outstr); + S2dImageUnlockBuffer(s_fpsimage,ptr); + } + + // note: shouldn't be needed but it is for now... + S2dSpriteSetPos(s_sprite[SPRITE_FPS],0,20); + +static FILE *f = fopen("trace.txt","wt"); +fprintf(f,"%u\n",frames/((lasttime-starttime)/1000)); +fflush(f); + +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateFont(); + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + "ANIM5", + "Animation Example 5")) + FATALRESULT("SDrawAutoInitialize()"); + if (!CreatePalette()) + FATALRESULT("CreatePalette()"); + if (!CreateSprites()) + FATALRESULT("CreateSprites()"); + + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/ANIM/ANIM5/ANIM5.CS b/Storm/SAMPLES/ANIM/ANIM5/ANIM5.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM5/ANIM5.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/ANIM/ANIM5/ANIM5.EXE b/Storm/SAMPLES/ANIM/ANIM5/ANIM5.EXE new file mode 100644 index 0000000..74beca9 Binary files /dev/null and b/Storm/SAMPLES/ANIM/ANIM5/ANIM5.EXE differ diff --git a/Storm/SAMPLES/ANIM/ANIM5/FPS.TXT b/Storm/SAMPLES/ANIM/ANIM5/FPS.TXT new file mode 100644 index 0000000..da1cc45 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM5/FPS.TXT @@ -0,0 +1 @@ +276 - 283 diff --git a/Storm/SAMPLES/ANIM/ANIM5/PCH.H b/Storm/SAMPLES/ANIM/ANIM5/PCH.H new file mode 100644 index 0000000..8938a3f --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM5/PCH.H @@ -0,0 +1,6 @@ +#include +#include +#include +#include +#include "s2d.h" + diff --git a/Storm/SAMPLES/ANIM/ANIM5/S2D.CPP b/Storm/SAMPLES/ANIM/ANIM5/S2D.CPP new file mode 100644 index 0000000..b11371f --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM5/S2D.CPP @@ -0,0 +1,828 @@ +/**************************************************************************** +* +* S2D.CPP +* Storm 2d graphics engine +* +* By Michael O'Brien (8/8/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define MAXSPANLENGTH 0xFC + +#define SF_DISPLAYED 0x00000001 +#define SF_ERASEMARKER 0x00000002 + +DECLARE_STRICT_HANDLE(HLOCKEDIMAGE); +DECLARE_STRICT_HANDLE(HLOCKEDSPRITE); +DECLARE_STRICT_HANDLE(HLOCKEDTARGET); + +struct IMAGE; +struct SPRITE; +struct TARGET; + +static void SpriteRemoveImageReference (SPRITE *spriteptr); + +typedef BYTE SPAN; + +typedef struct _SPANPAIR { + SPAN copyspan; + SPAN skipspan; +} SPANPAIR, *SPANPAIRPTR; + +typedef struct _COMPOSITEDATA { + SPRITE *spriteptr; + BOOL stable; + BOOL erasing; + SPAN *spanptr; + int currspan; + LPBYTE dataptr; +} COMPOSITEDATA, *COMPOSITEDATAPTR; + +EXPORTOBJECTDECL(SPRITE) { + POINT pos; + RECT boundingrect; + DWORD flags; + int zorder; + IMAGE *image; + TARGET *target; + LINKEX(SPRITE) linkimage; + LINKEX(SPRITE) linkzlist; + + inline ~SPRITE () { + if (image) + SpriteRemoveImageReference(this); + } + +} *SPRITEPTR; + +typedef LISTEX(SPRITE,linkimage) SPRITEIMAGELIST; +typedef LISTEX(SPRITE,linkzlist) SPRITEZLIST; + +EXPORTOBJECTDECL(IMAGE) { + SIZE size; + RECT boundingrect; + BOOL transparent; + BYTE transidx; + BYTE reserved[3]; + LPBYTE imagedata; + DWORD refcount; + ARRAY(SPANPAIR) spandata; + ARRAY(DWORD) spanindex; + SPRITEIMAGELIST spritelist; + + inline ~IMAGE () { + FREEIFUSED(imagedata); + } + +} *IMAGEPTR; + +EXPORTOBJECTDECL(TARGET) { + ARRAY(COMPOSITEDATA) compositedata; + CSRgn dirtyrgn; + ARRAY(RECT) dirtyrects; + ARRAY(LPVOID) dirtyrectparams; +// SPRITEZLIST sparelist; + SPRITEZLIST spritezlist; +} *TARGETPTR; + +typedef EXPORTTABLE(IMAGE ,HSIMAGE ,HLOCKEDIMAGE ,SYNC_NONE) IMAGETABLE; +typedef EXPORTTABLE(SPRITE,HSSPRITE,HLOCKEDSPRITE,SYNC_NONE) SPRITETABLE; +typedef EXPORTTABLE(TARGET,HSTARGET,HLOCKEDTARGET,SYNC_NONE) TARGETTABLE; + +static CCritSect s_apicritsect; +static IMAGETABLE s_imagetable; +static SPRITETABLE s_spritetable; +static TARGETTABLE s_targettable; + +//=========================================================================== +static inline BOOL CheckForSupportedColorFormat (int bitdepth, + COLORREF colorkey) { + return ((bitdepth == 8) && + (colorkey & 0x01000000)); +} + +//=========================================================================== +static inline void ImageAddSpanPair (IMAGEPTR imageptr, + SPANPAIRPTR pair, + int nextx, + int y) { + + // ADD THIS SPAN PAIR TO THE ARRAY + imageptr->spandata.AddElement(pair); + + // IF THIS SPAN PAIR CONTAINS A COPY SPAN, COMPUTE THE STARTING AND + // ENDING X COORDINATES IN THE COPY SPAN, AND ADD THAT RANGE TO THE + // BOUNDING RECTANGLE + if (pair->copyspan) { + int x2 = nextx-pair->skipspan; + int x1 = x2-pair->copyspan; + imageptr->boundingrect.left = min(x1 ,imageptr->boundingrect.left); + imageptr->boundingrect.top = min(y ,imageptr->boundingrect.top); + imageptr->boundingrect.right = max(x2 ,imageptr->boundingrect.right); + imageptr->boundingrect.bottom = max(y+1,imageptr->boundingrect.bottom); + } + + // BLANK THE SPAN PAIR + pair->copyspan = pair->skipspan = 0; +} + +//=========================================================================== +static void ImageCreateSpanData (IMAGEPTR imageptr) { + + // RESET THE COMPUTED IMAGE DATA + imageptr->boundingrect.left = imageptr->size.cx; + imageptr->boundingrect.top = imageptr->size.cy; + imageptr->boundingrect.right = 0; + imageptr->boundingrect.bottom = 0; + imageptr->transparent = FALSE; + imageptr->spandata.SetNumElements(0); + imageptr->spandata.ReserveSpace(imageptr->size.cx*4); + imageptr->spanindex.SetNumElements(imageptr->size.cy); + + // BUILD THE SPAN ARRAY + LPBYTE currdata = imageptr->imagedata; + for (int y = 0; y < imageptr->size.cy; ++y) { + + // SAVE THE SPAN INDEX THE CORRESPONDS WITH THE BEGINNING OF THIS + // SCAN LINE + imageptr->spanindex[y] = imageptr->spandata.NumElements(); + + // INITIALIZE THE OUTPUT VARIABLES + SPANPAIR currpair = {0,0}; + SPAN *currspan = &currpair.copyspan; + + // IF THIS SCAN LINE HAS ZERO WIDTH, THEN JUST OUTPUT THE LINE TERMINATOR + if (imageptr->size.cx <= 0) { + ImageAddSpanPair(imageptr,&currpair,0,y); + continue; + } + + // OTHERWISE, BUILD AND OUTPUT SPANS + int x; + for (x = 0; x < imageptr->size.cx; ++x) { + if ((*(currdata++) != imageptr->transidx) != (currspan == &currpair.copyspan)) + if (currspan == &currpair.copyspan) { + imageptr->transparent = TRUE; + currspan = &currpair.skipspan; + } + else { + ImageAddSpanPair(imageptr,&currpair,x,y); + currspan = &currpair.copyspan; + } + if (*currspan == MAXSPANLENGTH) + ImageAddSpanPair(imageptr,&currpair,x,y); + ++*currspan; + } + ImageAddSpanPair(imageptr,&currpair,x,y); + + // OUTPUT THE LINE TERMINATOR + ImageAddSpanPair(imageptr,&currpair,x,y); + + } + +} + +//=========================================================================== +static void SpriteLinkToZList (TARGETPTR targetptr, + SPRITEPTR spriteptr) { + spriteptr->linkzlist.Unlink(); + SPRITEPTR before = NULL; + ITERATELIST(SPRITE,targetptr->spritezlist,curr) + if (curr->zorder > spriteptr->zorder) { + before = curr; + break; + } + targetptr->spritezlist.LinkNode(spriteptr,LIST_LINK_BEFORE,before); +} + +//=========================================================================== +static void SpriteRemoveImageReference (SPRITE *spriteptr) { + if (!--spriteptr->image->refcount) + delete spriteptr->image; + spriteptr->image = NULL; + spriteptr->linkimage.Unlink(); +} + +//=========================================================================== +static void TargetBuildDirtyRects (TARGETPTR targetptr) { + targetptr->dirtyrgn.Clear(); + ITERATELIST(SPRITE,targetptr->spritezlist,spriteptr) + if ((spriteptr->flags & SF_ERASEMARKER) || + !(spriteptr->flags & SF_DISPLAYED)) + targetptr->dirtyrgn.AddRect(&spriteptr->boundingrect,spriteptr); + else + targetptr->dirtyrgn.AddParam(&spriteptr->boundingrect,spriteptr); + DWORD numrects; + targetptr->dirtyrgn.GetRects(&numrects,NULL); + targetptr->dirtyrects.SetNumElements(numrects); + targetptr->dirtyrgn.GetRects(&numrects,targetptr->dirtyrects.Ptr()); +} + +//=========================================================================== +static void TargetCompositeRect (LPBYTE videoptr, + int pitch, + TARGETPTR targetptr, + LPCRECT rect, + DWORD sprites, + SPRITEPTR *spritearray) { + DWORD loop; + + // BUILD A LIST OF SPRITES TO COMPOSITE + targetptr->compositedata.SetNumElements(sprites); + COMPOSITEDATAPTR compositedata = targetptr->compositedata.Ptr(); + DWORD compositenum = 0; + { + BOOL erasing = FALSE; + DWORD lastdraw = UINT_MAX; + for (loop = 0; loop < sprites; ++loop) { + SPRITEPTR spriteptr = spritearray[loop]; + if (spriteptr->flags & SF_ERASEMARKER) + erasing = TRUE; + if (!(spriteptr->flags & SF_DISPLAYED)) + lastdraw = compositenum; + compositedata[compositenum].spriteptr = spriteptr; + compositedata[compositenum].stable + = ((spriteptr->flags & SF_DISPLAYED) != 0) + && !(spriteptr->flags & SF_ERASEMARKER); + compositedata[compositenum].erasing + = ((spriteptr->flags & SF_ERASEMARKER) != 0); + compositedata[compositenum].dataptr + = spriteptr->image->imagedata + +((rect->top-spriteptr->pos.y-1)*spriteptr->image->size.cx) + +(rect->left-spriteptr->pos.x) + +(rect->right-rect->left); + ++compositenum; + } + if (!erasing) + compositenum = lastdraw+1; + } + + LPBYTE destptr = videoptr+rect->top*pitch+rect->left; + for (int y = rect->top; y < rect->bottom; ++y) { + + // SETUP COMPOSITING INFO FOR THIS SCAN LINE FOR EACH SPRITE + for (loop = 0; loop < compositenum; ++loop) { + SPRITEPTR spriteptr = compositedata[loop].spriteptr; + compositedata[loop].dataptr += spriteptr->image->size.cx-(rect->right-rect->left); + if ((y >= spriteptr->boundingrect.top) && + (y < spriteptr->boundingrect.bottom)) { + compositedata[loop].spanptr = (SPAN *)(spriteptr->image->spandata.Ptr() + +spriteptr->image->spanindex[y-spriteptr->pos.y]); + compositedata[loop].currspan = spriteptr->pos.x-rect->left; + while (compositedata[loop].currspan <= 0) + if ((!((DWORD)compositedata[loop].spanptr & 1)) && + !*(LPWORD)compositedata[loop].spanptr) + compositedata[loop].currspan = INT_MAX; + else + compositedata[loop].currspan += *compositedata[loop].spanptr++; + } + else { + compositedata[loop].spanptr = NULL; + compositedata[loop].currspan = INT_MAX; + } + } + + int x = rect->left; + int xspan; + while ((xspan = rect->right-x) > 0) { + + BOOL belowerase = FALSE; + for (loop = 0; loop < compositenum; ++loop) { + xspan = min(xspan,compositedata[loop].currspan); + if ((DWORD)compositedata[loop].spanptr & 1) + if (compositedata[loop].erasing) + belowerase = TRUE; + else + break; + } + + if ((loop < compositenum) && + (belowerase || !compositedata[loop].stable)) { + LPBYTE sourceptr = compositedata[loop].dataptr; +#ifdef _X86_ + __asm { + + // SETUP REGISTERS + push esi + push edi + mov eax,[xspan] + xor ecx,ecx + mov esi,[sourceptr] + mov edi,[destptr] + + // PERFORM THE COPY + cmp al,3 + jbe ds_done4 + + // IF NECESSARY, MOVE A SINGLE BYTE TO WORD-ALIGN THE + // DESTINATION + test edi,1 + jz ds_aligned2 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec al + ds_aligned2: + + // IF NECESSARY, MOVE A SINGLE WORD TO DWORD-ALIGN THE + // DESTINATION + test edi,2 + jz ds_aligned4 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + sub al,2 + ds_aligned4: + + // MOVE AS MANY ALIGNED DWORDS AS POSSIBLE + // note: get rid of the rep movsd!! + mov ecx,eax + and ecx,0FCh + shr ecx,2 + rep movsd + ds_done4: + + // MOVE ONE MORE WORD IF NECESSARY + test al,2 + jz ds_done2 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + ds_done2: + + // MOVE ONE MORE BYTE IF NECESSARY + test al,1 + jz ds_done1 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + ds_done1: + + pop edi + pop esi + } +#else + CopyMemory(destptr, + sourceptr, + xspan); +#endif + } + + destptr += xspan; + x += xspan; + + for (loop = 0; loop < compositenum; ++loop) { + compositedata[loop].dataptr += xspan; + int advance = xspan; + while (advance >= compositedata[loop].currspan) { + advance -= compositedata[loop].currspan; + if ((!((DWORD)compositedata[loop].spanptr & 1)) && + !*(LPWORD)compositedata[loop].spanptr) + compositedata[loop].currspan = INT_MAX; + else + compositedata[loop].currspan = *compositedata[loop].spanptr++; + } + compositedata[loop].currspan -= advance; + } + + } + + destptr += pitch-(rect->right-rect->left); + } +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +void APIENTRY S2dImageCreate (int width, + int height, + int bitdepth, + COLORREF colorkey, + HSIMAGE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATEENDVOID; + + if (!CheckForSupportedColorFormat(bitdepth,colorkey)) + return; + + s_apicritsect.Enter(); + + // CREATE A NEW IMAGE RECORD + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.NewLock(handle,&lockedhandle); + imageptr->size.cx = width; + imageptr->size.cy = height; + imageptr->boundingrect.left = UINT_MAX; + imageptr->boundingrect.top = UINT_MAX; + imageptr->boundingrect.right = UINT_MAX; + imageptr->boundingrect.bottom = UINT_MAX; + imageptr->transidx = (BYTE)(colorkey & 0xFF); + imageptr->refcount = 1; + s_imagetable.Unlock(lockedhandle); + + s_apicritsect.Leave(); +} + +//=========================================================================== +BOOL APIENTRY S2dImageCreateFromFile (LPCTSTR filename, + COLORREF colorkey, + DWORD numimages, + LPCRECT rectarray, + HSIMAGE *handlearray) { + if (numimages && handlearray) + ZeroMemory(handlearray,numimages*sizeof(HSIMAGE)); + + VALIDATEBEGIN; + VALIDATE(filename && *filename); + VALIDATE(numimages); + VALIDATE(handlearray); + VALIDATEEND; + + s_apicritsect.Enter(); + HSFILE file = (HSFILE)0; + LPBYTE filebuffer = NULL; + BOOL result = FALSE; + TRY { + + // LOAD THE FILE FROM DISK + if (!SFileOpenFile(filename,&file)) + LEAVE; + DWORD filesize = SFileGetFileSize(file,NULL); + filebuffer = (LPBYTE)ALLOC(filesize); + if (!SFileReadFile(file,filebuffer,filesize)) + LEAVE; + + // DETERMINE THE SOURCE IMAGE DIMENSIONS + int width, height, bitdepth; + if (!SBmpDecodeImage(SBMP_IMAGETYPE_AUTO, + filebuffer, + filesize, + NULL, + NULL, + 0, + &width, + &height, + &bitdepth)) + LEAVE; + + // VERIFY THAT THE FILE IS IN A SUPPORTED COLOR FORMAT + if (!CheckForSupportedColorFormat(bitdepth,colorkey)) + LEAVE; + + // DECODE THE FILE INTO A TEMPORARY BUFFER + int bytedepth = bitdepth/8; + DWORD sourcebytes = width*height*(DWORD)bytedepth; + LPBYTE buffer = (LPBYTE)ALLOC(sourcebytes); + SBmpDecodeImage(SBMP_IMAGETYPE_AUTO, + filebuffer, + filesize, + NULL, + buffer, + sourcebytes); + + // PROCESS EACH IMAGE + for (DWORD loop = 0; + loop < numimages; + ++loop) { + + // DETERMINE THE IMAGE DIMENSIONS + int destwidth = width; + int destheight = height; + if (rectarray) { + destwidth = min(destwidth ,rectarray[loop].right+1-rectarray[loop].left); + destheight = min(destheight,rectarray[loop].bottom+1-rectarray[loop].top); + } + + // CREATE THE IMAGE + S2dImageCreate(destwidth, + destheight, + bitdepth, + colorkey, + &handlearray[loop]); + + // LOCK THE IMAGE BUFFER + LPBYTE ptr; + S2dImageLockBuffer(handlearray[loop],TRUE,&ptr); + + // BLT THE SOURCE RECTANGLE INTO THE IMAGE BUFFER + SIZE adjdestsize = {destwidth*bytedepth, + destheight}; + SIZE adjsourcesize = {width*bytedepth, + height}; + RECT adjsourcerect = {0, + 0, + adjsourcesize.cx, + adjsourcesize.cy}; + if (rectarray) { + adjsourcerect.left = rectarray[loop].left*bytedepth; + adjsourcerect.top = rectarray[loop].top; + adjsourcerect.right = rectarray[loop].right*bytedepth; + adjsourcerect.bottom = rectarray[loop].bottom; + } + SBltROP3Clipped(ptr, + NULL, + &adjdestsize, + adjdestsize.cx, + buffer, + &adjsourcerect, + &adjsourcesize, + adjsourcesize.cx, + 0, + SRCCOPY); + + // UNLOCK THE IMAGE BUFFER + S2dImageUnlockBuffer(handlearray[loop],ptr); + + } + + // FREE THE TEMPORARY BUFFER + FREE(buffer); + + result = TRUE; + } + FINALLY { + FREEIFUSED(filebuffer); + if (file) + SFileCloseFile(file); + } + s_apicritsect.Leave(); + return result; +} + +//=========================================================================== +void APIENTRY S2dImageDelete (HSIMAGE handle) { + s_apicritsect.Enter(); + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.Lock(handle,&lockedhandle); + if (!--imageptr->refcount) + s_imagetable.DeleteUnlock(imageptr,lockedhandle); + else + s_imagetable.Unlock(lockedhandle); + s_apicritsect.Leave(); +} + +//=========================================================================== +BOOL APIENTRY S2dImageLockBuffer (HSIMAGE handle, + BOOL blank, + LPBYTE *ptr) { + VALIDATEBEGIN; + VALIDATEANDBLANK(ptr); + VALIDATEEND; + + s_apicritsect.Enter(); + for (ONCE) { + + // FIND THE IMAGE RECORD + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.Lock(handle,&lockedhandle); + if (!imageptr) + break; + + // ALLOCATE A BUFFER IF NECESSARY + DWORD bytes = imageptr->size.cx*imageptr->size.cy; + if (!imageptr->imagedata) + imageptr->imagedata = (LPBYTE)ALLOC(bytes); + + // BLANK THE BUFFER IF REQUESTED + if (blank) + FillMemory(imageptr->imagedata,bytes,imageptr->transidx); + + // RETURN THE BUFFER + *ptr = imageptr->imagedata; + + s_imagetable.Unlock(lockedhandle); + } + s_apicritsect.Leave(); + return (*ptr != NULL); +} + +//=========================================================================== +void APIENTRY S2dImageUnlockBuffer (HSIMAGE handle, + LPBYTE ptr) { + s_apicritsect.Enter(); + for (ONCE) { + + // FIND THE IMAGE RECORD + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.Lock(handle,&lockedhandle); + if (!imageptr) + break; + + // PRODUCE THE SPAN DATA + ImageCreateSpanData(imageptr); + + s_imagetable.Unlock(lockedhandle); + } + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteCreate (HSSPRITE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + s_spritetable.New(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteDelete (HSSPRITE handle) { + s_apicritsect.Enter(); + s_spritetable.Delete(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteSetImage (HSSPRITE handle, + HSIMAGE imagehandle) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(imagehandle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + + // LOCK THE SPRITE AND IMAGE + HLOCKEDSPRITE lockedsprite; + HLOCKEDIMAGE lockedimage; + SPRITEPTR spriteptr = s_spritetable.Lock(handle,&lockedsprite); + IMAGEPTR imageptr = s_imagetable.Lock(imagehandle,&lockedimage); + if (spriteptr->image != imageptr) { + + // REMOVE THE REFERENCE TO THE SPRITE'S OLD IMAGE + if (spriteptr->image) + SpriteRemoveImageReference(spriteptr); + + // ASSOCIATE THE IMAGE WITH THE SPRITE + if (imageptr) { + ++imageptr->refcount; + spriteptr->image = imageptr; + imageptr->spritelist.LinkNode(spriteptr); + } + + } + + // UNLOCK THE SPRITE AND IMAGE + s_imagetable.Unlock(lockedimage); + s_spritetable.Unlock(lockedsprite); + + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteSetPos (HSSPRITE handle, + int x, + int y) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + for (ONCE) { + + // LOCK THE SPRITE + HLOCKEDSPRITE lockedhandle; + SPRITEPTR spriteptr = s_spritetable.Lock(handle,&lockedhandle); + if (!spriteptr) + break; + + // PLACE AN ERASE MARKER AT THE SPRITE'S OLD POSITION + if (spriteptr->flags & SF_DISPLAYED) { + SPRITEPTR newptr = spriteptr->target->spritezlist.NewNode(LIST_UNLINKED); + newptr->pos = spriteptr->pos; + newptr->boundingrect = spriteptr->boundingrect; + newptr->flags = SF_ERASEMARKER; + newptr->zorder = spriteptr->zorder; + newptr->target = spriteptr->target; + newptr->image = spriteptr->image; + ++spriteptr->image->refcount; + spriteptr->target->spritezlist.LinkNode(newptr,LIST_LINK_AFTER,spriteptr); + } + + // SET THE SPRITE'S POSITION AND BOUNDING RECTANGLE + spriteptr->pos.x = x; + spriteptr->pos.y = y; + spriteptr->boundingrect.left = x+spriteptr->image->boundingrect.left; + spriteptr->boundingrect.top = y+spriteptr->image->boundingrect.top; + spriteptr->boundingrect.right = x+spriteptr->image->boundingrect.right; + spriteptr->boundingrect.bottom = y+spriteptr->image->boundingrect.bottom; + spriteptr->flags &= ~SF_DISPLAYED; + + // UNLOCK THE SPRITE + s_spritetable.Unlock(lockedhandle); + + } + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteSetTarget (HSSPRITE handle, + HSTARGET targethandle, + int zorder) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(targethandle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + + // LOCK THE SPRITE AND TARGET + HLOCKEDSPRITE lockedsprite; + HLOCKEDTARGET lockedtarget; + SPRITEPTR spriteptr = s_spritetable.Lock(handle,&lockedsprite); + TARGETPTR targetptr = s_targettable.Lock(targethandle,&lockedtarget); + + // SET THE SPRITE'S Z ORDER AND LINK IT INTO THE TARGET'S Z LIST + spriteptr->zorder = zorder; + spriteptr->target = targetptr; + SpriteLinkToZList(targetptr,spriteptr); + + // UNLOCK THE SPRITE AND TARGET + s_targettable.Unlock(lockedtarget); + s_spritetable.Unlock(lockedsprite); + + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dTargetCreate (HSTARGET *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + s_targettable.New(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dTargetDelete (HSTARGET handle) { + s_apicritsect.Enter(); + s_targettable.Delete(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dTestDrawTarget (HSTARGET handle, + LPBYTE ptr, + int pitch) { + s_apicritsect.Enter(); + for (ONCE) { + + HLOCKEDTARGET lockedhandle; + TARGETPTR targetptr = s_targettable.Lock(handle,&lockedhandle); + if (!targetptr) + break; + + TargetBuildDirtyRects(targetptr); + for (DWORD rectindex = 0; + rectindex < targetptr->dirtyrects.NumElements(); + ++rectindex) { + DWORD totalparams; + targetptr->dirtyrgn.GetRectParams(&targetptr->dirtyrects[rectindex], + &totalparams, + NULL); + targetptr->dirtyrectparams.SetNumElements(totalparams); + targetptr->dirtyrgn.GetRectParams(&targetptr->dirtyrects[rectindex], + &totalparams, + targetptr->dirtyrectparams.Ptr()); +/* + SGdiRectangle(ptr, + targetptr->dirtyrects[rectindex].left, + targetptr->dirtyrects[rectindex].top, + targetptr->dirtyrects[rectindex].right, + targetptr->dirtyrects[rectindex].bottom, + PALETTEINDEX(111+totalparams)); +*/ + TargetCompositeRect(ptr, + pitch, + targetptr, + &targetptr->dirtyrects[rectindex], + totalparams, + (SPRITEPTR *)(targetptr->dirtyrectparams.Ptr())); + } + + ITERATELIST(SPRITE,targetptr->spritezlist,spriteptr) + if (spriteptr->flags & SF_ERASEMARKER) + ITERATE_DELETE + else + spriteptr->flags |= SF_DISPLAYED; + + s_targettable.Unlock(lockedhandle); + } + s_apicritsect.Leave(); +} diff --git a/Storm/SAMPLES/ANIM/ANIM5/S2D.H b/Storm/SAMPLES/ANIM/ANIM5/S2D.H new file mode 100644 index 0000000..ded5029 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM5/S2D.H @@ -0,0 +1,42 @@ +/**************************************************************************** +* +* 2D graphics engine functions +* +***/ + +DECLARE_STRICT_HANDLE(HSIMAGE); +DECLARE_STRICT_HANDLE(HSSPRITE); +DECLARE_STRICT_HANDLE(HSTARGET); + +void APIENTRY S2dImageCreate (int width, + int height, + int bitdepth, + COLORREF colorkey, + HSIMAGE *handle); +BOOL APIENTRY S2dImageCreateFromFile (LPCTSTR filename, + COLORREF colorkey, + DWORD numimages, + LPCRECT rectarray, + HSIMAGE *handlearray); +void APIENTRY S2dImageDelete (HSIMAGE handle); +BOOL APIENTRY S2dImageLockBuffer (HSIMAGE handle, + BOOL blank, + LPBYTE *ptr); +void APIENTRY S2dImageUnlockBuffer (HSIMAGE handle, + LPBYTE ptr); +void APIENTRY S2dSpriteCreate (HSSPRITE *handle); +void APIENTRY S2dSpriteDelete (HSSPRITE handle); +void APIENTRY S2dSpriteSetImage (HSSPRITE handle, + HSIMAGE imagehandle); +void APIENTRY S2dSpriteSetPos (HSSPRITE handle, + int x, + int y); +void APIENTRY S2dSpriteSetTarget (HSSPRITE handle, + HSTARGET targethandle, + int zorder); +void APIENTRY S2dTargetCreate (HSTARGET *handle); +void APIENTRY S2dTargetDelete (HSTARGET handle); + +void APIENTRY S2dTestDrawTarget (HSTARGET handle, + LPBYTE ptr, + int pitch); diff --git a/Storm/SAMPLES/ANIM/ANIM5/TRACE.TXT b/Storm/SAMPLES/ANIM/ANIM5/TRACE.TXT new file mode 100644 index 0000000..6eee0d1 --- /dev/null +++ b/Storm/SAMPLES/ANIM/ANIM5/TRACE.TXT @@ -0,0 +1,2 @@ +279 +275 diff --git a/Storm/SAMPLES/ANIM/DEMODATA/BKG.PCX b/Storm/SAMPLES/ANIM/DEMODATA/BKG.PCX new file mode 100644 index 0000000..d24cdf1 Binary files /dev/null and b/Storm/SAMPLES/ANIM/DEMODATA/BKG.PCX differ diff --git a/Storm/SAMPLES/ANIM/DEMODATA/FLAG.PCX b/Storm/SAMPLES/ANIM/DEMODATA/FLAG.PCX new file mode 100644 index 0000000..c83f1b4 Binary files /dev/null and b/Storm/SAMPLES/ANIM/DEMODATA/FLAG.PCX differ diff --git a/Storm/SAMPLES/ANIM/DEMODATA/OVERLAY.OLD b/Storm/SAMPLES/ANIM/DEMODATA/OVERLAY.OLD new file mode 100644 index 0000000..41818e2 Binary files /dev/null and b/Storm/SAMPLES/ANIM/DEMODATA/OVERLAY.OLD differ diff --git a/Storm/SAMPLES/ANIM/DEMODATA/OVERLAY.PCX b/Storm/SAMPLES/ANIM/DEMODATA/OVERLAY.PCX new file mode 100644 index 0000000..e9a3e67 Binary files /dev/null and b/Storm/SAMPLES/ANIM/DEMODATA/OVERLAY.PCX differ diff --git a/Storm/SAMPLES/ANIM/DEMODATA/SHIPS.PCX b/Storm/SAMPLES/ANIM/DEMODATA/SHIPS.PCX new file mode 100644 index 0000000..3fc7727 Binary files /dev/null and b/Storm/SAMPLES/ANIM/DEMODATA/SHIPS.PCX differ diff --git a/Storm/SAMPLES/ANIM/DEMODATA/SPRITES.PCX b/Storm/SAMPLES/ANIM/DEMODATA/SPRITES.PCX new file mode 100644 index 0000000..f9dc3e2 Binary files /dev/null and b/Storm/SAMPLES/ANIM/DEMODATA/SPRITES.PCX differ diff --git a/Storm/SAMPLES/ANIM/OLD/ANIM5.CPP b/Storm/SAMPLES/ANIM/OLD/ANIM5.CPP new file mode 100644 index 0000000..25b0df9 --- /dev/null +++ b/Storm/SAMPLES/ANIM/OLD/ANIM5.CPP @@ -0,0 +1,270 @@ +/**************************************************************************** +* +* ANIM5.CPP +* +* Under construction... +* +***/ + +#include "pch.h" +#pragma hdrstop + +#include // note: take this out!! + +//#define COMBINEDOVERLAY + +#define ANIMSPRITES 4 +#define SPRITE_FPS (ANIMSPRITES+0) +#define SPRITE_BKG (ANIMSPRITES+1) +#define SPRITE_OVL1 (ANIMSPRITES+2) +#ifdef COMBINEDOVERLAY +#define SPRITES (ANIMSPRITES+3) +#else +#define SPRITE_OVL2 (ANIMSPRITES+3) +#define SPRITES (ANIMSPRITES+4) +#endif + +#define FPSWIDTH 60 +#define FPSHEIGHT 16 + +#define TRANSCOLOR PALETTEINDEX(111) + +#define SIN(a) s_sintable[((a) & 255)] +#define COS(a) s_sintable[(((a)+64) & 255)] + +static HSGDIFONT s_font; +static HSIMAGE s_fpsimage; +static int s_sintable[256]; +static HSSPRITE s_sprite[SPRITES]; +static HSTARGET s_target; + +static void UpdateFramesPerSecond (); + +//=========================================================================== +static void CreateFont () { + HFONT winfont = CreateFont(-12,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + SGdiImportFont(winfont,&s_font); + DeleteObject(winfont); + SGdiSelectObject(s_font); +} + +//=========================================================================== +static BOOL CreatePalette () { + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\bkg.pcx",&pe[0],NULL,0)) + return FALSE; + SDrawUpdatePalette(0,256,&pe[0]); + return TRUE; +} + +//=========================================================================== +static void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + s_sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +static BOOL CreateSprites () { + DWORD loop; + HSIMAGE imagearray[SPRITES]; + + // LOAD THE ANIMATED SPRITE IMAGES + { + RECT rectarray[ANIMSPRITES]; + for (loop = 0; loop < ANIMSPRITES; ++loop) { + rectarray[loop].left = 0; + rectarray[loop].top = 125*loop; + rectarray[loop].right = 300; + rectarray[loop].bottom = 125*loop+125; + } + if (!S2dImageCreateFromFile("..\\demodata\\sprites.pcx", + TRANSCOLOR, + ANIMSPRITES, + rectarray, + imagearray)) + return FALSE; + } + + // CREATE THE FPS SPRITE IMAGE + S2dImageCreate(FPSWIDTH, + FPSHEIGHT, + 8, + TRANSCOLOR, + &imagearray[SPRITE_FPS]); + + // LOAD THE BACKGROUND SPRITE IMAGE + if (!S2dImageCreateFromFile("..\\demodata\\bkg.pcx", + TRANSCOLOR, + 1, + NULL, + &imagearray[SPRITE_BKG])) + return FALSE; + + // LOAD THE OVERLAY SPRITE IMAGES +#ifdef COMBINEDOVERLAY + if (!S2dImageCreateFromFile("..\\demodata\\overlay.pcx", + TRANSCOLOR, + 1, + NULL, + &imagearray[SPRITE_OVL1])) + return FALSE; +#else + { + RECT rectarray[2] = {{0,0,167,18},{0,295,640,480}}; + if (!S2dImageCreateFromFile("..\\demodata\\overlay.pcx", + TRANSCOLOR, + 2, + rectarray, + &imagearray[SPRITE_OVL1])) + return FALSE; + } +#endif + + // ATTACH THE IMAGES TO SPRITES, AND THEN CLOSE OR SAVE THE IMAGE HANDLES + for (loop = 0; loop < SPRITES; ++loop) { + S2dSpriteCreate(&s_sprite[loop]); + S2dSpriteSetImage(s_sprite[loop],imagearray[loop]); + if (loop == SPRITE_FPS) { + S2dSpriteSetPos(s_sprite[loop],0,20); + s_fpsimage = imagearray[loop]; + } + else { + S2dSpriteSetPos(s_sprite[loop],0,0); +#ifndef COMBINEDOVERLAY +if (loop == SPRITE_OVL2) S2dSpriteSetPos(s_sprite[loop],0,295); +#endif + S2dImageDelete(imagearray[loop]); + } + } + + // CREATE A TARGET, AND ATTACH THE SPRITES TO THE TARGET + S2dTargetCreate(&s_target); + for (loop = 0; loop < SPRITES; ++loop) + S2dSpriteSetTarget(s_sprite[loop], + s_target, + (loop >= SPRITE_OVL1) ? -1 : loop); + + return TRUE; +} + +//=========================================================================== +static BOOL CALLBACK IdleProc (DWORD) { + static BYTE rotation = 0; + static BYTE distance = 0; + ++distance; + rotation += 3; + for (DWORD loop = 0; loop < ANIMSPRITES; ++loop) + S2dSpriteSetPos(s_sprite[loop], + 170+(SIN(rotation+64*loop)*SIN(distance/2)/100), + 165+(COS(rotation+64*loop)*SIN(distance/2)/100)); + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { +//SGdiSetPitch(videopitch); +//SGdiRectangle(videobuffer,0,0,640,480,PALETTEINDEX(255)); + S2dTestDrawTarget(s_target,videobuffer,videopitch); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + UpdateFramesPerSecond(); +//return FALSE; + return TRUE; +} + +//=========================================================================== +static void CALLBACK OnClose (LPPARAMS) { + for (DWORD loop = 0; loop < SPRITES; ++loop) { + S2dSpriteDelete(s_sprite[loop]); + s_sprite[loop] = (HSSPRITE)0; + } + S2dImageDelete(s_fpsimage); + s_fpsimage = (HSIMAGE)0; + S2dTargetDelete(s_target); + s_target = (HSTARGET)0; + SGdiDeleteObject(s_font); + s_font = (HSGDIFONT)0; +} + +//=========================================================================== +static void CALLBACK OnPaint (LPPARAMS params) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + S2dTestDrawTarget(s_target,videobuffer,videopitch); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + ValidateRect(params->window,NULL); + params->useresult = TRUE; + params->result = 0; +} + +//=========================================================================== +static void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +static void UpdateFramesPerSecond () { + static DWORD frames = 0; + static DWORD starttime = GetTickCount(); + static DWORD lasttime = starttime; + + // INCREMENT THE NUMBER OF FRAMES + ++frames; + + // RETURN IF A SECOND HAS NOT YET ELAPSED + if (GetTickCount()-lasttime < 1000) + return; + lasttime += 1000; + + // DRAW THE AVERAGE NUMBER OF FRAMES PER SECOND + LPBYTE ptr; + if (S2dImageLockBuffer(s_fpsimage,FALSE,&ptr)) { + char outstr[16]; + wsprintf(outstr,"%3u FPS",frames/((lasttime-starttime)/1000)); + RECT rect = {0,0,FPSWIDTH,FPSHEIGHT}; + SGdiSetTargetDimensions(FPSWIDTH, + FPSHEIGHT, + 8, + FPSWIDTH); + SGdiExtTextOut(ptr, + 0, + 0, + &rect, + TRANSCOLOR, + ETO_TEXT_WHITE, + ETO_BKG_COLOR, + outstr); + S2dImageUnlockBuffer(s_fpsimage,ptr); + } + + // note: shouldn't be needed but it is for now... + S2dSpriteSetPos(s_sprite[SPRITE_FPS],0,20); + +static FILE *f = fopen("trace.txt","wt"); +fprintf(f,"%u\n",frames/((lasttime-starttime)/1000)); +fflush(f); + +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateFont(); + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + "ANIM5", + "Animation Example 5")) + FATALRESULT("SDrawAutoInitialize()"); + if (!CreatePalette()) + FATALRESULT("CreatePalette()"); + if (!CreateSprites()) + FATALRESULT("CreateSprites()"); + + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/ANIM/OLD/ANIM5.CS b/Storm/SAMPLES/ANIM/OLD/ANIM5.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/ANIM/OLD/ANIM5.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/ANIM/OLD/ANIM5.EXE b/Storm/SAMPLES/ANIM/OLD/ANIM5.EXE new file mode 100644 index 0000000..19ee8a1 Binary files /dev/null and b/Storm/SAMPLES/ANIM/OLD/ANIM5.EXE differ diff --git a/Storm/SAMPLES/ANIM/OLD/PCH.H b/Storm/SAMPLES/ANIM/OLD/PCH.H new file mode 100644 index 0000000..8938a3f --- /dev/null +++ b/Storm/SAMPLES/ANIM/OLD/PCH.H @@ -0,0 +1,6 @@ +#include +#include +#include +#include +#include "s2d.h" + diff --git a/Storm/SAMPLES/ANIM/OLD/S2D.CPP b/Storm/SAMPLES/ANIM/OLD/S2D.CPP new file mode 100644 index 0000000..c96322f --- /dev/null +++ b/Storm/SAMPLES/ANIM/OLD/S2D.CPP @@ -0,0 +1,815 @@ +/**************************************************************************** +* +* S2D.CPP +* Storm 2d graphics engine +* +* By Michael O'Brien (8/8/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define MAXSPANLENGTH 0xFC + +#define SF_DISPLAYED 0x00000001 +#define SF_ERASEMARKER 0x00000002 + +DECLARE_STRICT_HANDLE(HLOCKEDIMAGE); +DECLARE_STRICT_HANDLE(HLOCKEDSPRITE); +DECLARE_STRICT_HANDLE(HLOCKEDTARGET); + +struct IMAGE; +struct SPRITE; +struct TARGET; + +static void SpriteRemoveImageReference (SPRITE *spriteptr); + +typedef BYTE SPAN; + +typedef struct _SPANPAIR { + SPAN copyspan; + SPAN skipspan; +} SPANPAIR, *SPANPAIRPTR; + +typedef struct _COMPOSITEDATA { + SPRITE *spriteptr; + BOOL stable; + SPAN *spanptr; + int currspan; + LPBYTE dataptr; +} COMPOSITEDATA, *COMPOSITEDATAPTR; + +EXPORTOBJECTDECL(SPRITE) { + POINT pos; + RECT boundingrect; + DWORD flags; + int zorder; + IMAGE *image; + TARGET *target; + LINKEX(SPRITE) linkimage; + LINKEX(SPRITE) linkzlist; + + inline ~SPRITE () { + if (image) + SpriteRemoveImageReference(this); + } + +} *SPRITEPTR; + +typedef LISTEX(SPRITE,linkimage) SPRITEIMAGELIST; +typedef LISTEX(SPRITE,linkzlist) SPRITEZLIST; + +EXPORTOBJECTDECL(IMAGE) { + SIZE size; + RECT boundingrect; + BOOL transparent; + BYTE transidx; + BYTE reserved[3]; + LPBYTE imagedata; + DWORD refcount; + ARRAY(SPANPAIR) spandata; + ARRAY(DWORD) spanindex; + SPRITEIMAGELIST spritelist; + + inline ~IMAGE () { + FREEIFUSED(imagedata); + } + +} *IMAGEPTR; + +EXPORTOBJECTDECL(TARGET) { + ARRAY(COMPOSITEDATA) compositedata; + CSRgn dirtyrgn; + ARRAY(RECT) dirtyrects; + ARRAY(LPVOID) dirtyrectparams; +// SPRITEZLIST sparelist; + SPRITEZLIST spritezlist; +} *TARGETPTR; + +typedef EXPORTTABLE(IMAGE ,HSIMAGE ,HLOCKEDIMAGE ,SYNC_NONE) IMAGETABLE; +typedef EXPORTTABLE(SPRITE,HSSPRITE,HLOCKEDSPRITE,SYNC_NONE) SPRITETABLE; +typedef EXPORTTABLE(TARGET,HSTARGET,HLOCKEDTARGET,SYNC_NONE) TARGETTABLE; + +static CCritSect s_apicritsect; +static IMAGETABLE s_imagetable; +static SPRITETABLE s_spritetable; +static TARGETTABLE s_targettable; + +//=========================================================================== +static inline BOOL CheckForSupportedColorFormat (int bitdepth, + COLORREF colorkey) { + return ((bitdepth == 8) && + (colorkey & 0x01000000)); +} + +//=========================================================================== +static inline void ImageAddSpanPair (IMAGEPTR imageptr, + SPANPAIRPTR pair, + int nextx, + int y) { + + // ADD THIS SPAN PAIR TO THE ARRAY + imageptr->spandata.AddElement(pair); + + // IF THIS SPAN PAIR CONTAINS A COPY SPAN, COMPUTE THE STARTING AND + // ENDING X COORDINATES IN THE COPY SPAN, AND ADD THAT RANGE TO THE + // BOUNDING RECTANGLE + if (pair->copyspan) { + int x2 = nextx-pair->skipspan; + int x1 = x2-pair->copyspan; + imageptr->boundingrect.left = min(x1 ,imageptr->boundingrect.left); + imageptr->boundingrect.top = min(y ,imageptr->boundingrect.top); + imageptr->boundingrect.right = max(x2 ,imageptr->boundingrect.right); + imageptr->boundingrect.bottom = max(y+1,imageptr->boundingrect.bottom); + } + + // BLANK THE SPAN PAIR + pair->copyspan = pair->skipspan = 0; +} + +//=========================================================================== +static void ImageCreateSpanData (IMAGEPTR imageptr) { + + // RESET THE COMPUTED IMAGE DATA + imageptr->boundingrect.left = imageptr->size.cx; + imageptr->boundingrect.top = imageptr->size.cy; + imageptr->boundingrect.right = 0; + imageptr->boundingrect.bottom = 0; + imageptr->transparent = FALSE; + imageptr->spandata.SetNumElements(0); + imageptr->spandata.ReserveSpace(imageptr->size.cx*4); + imageptr->spanindex.SetNumElements(imageptr->size.cy); + + // BUILD THE SPAN ARRAY + LPBYTE currdata = imageptr->imagedata; + for (int y = 0; y < imageptr->size.cy; ++y) { + + // SAVE THE SPAN INDEX THE CORRESPONDS WITH THE BEGINNING OF THIS + // SCAN LINE + imageptr->spanindex[y] = imageptr->spandata.NumElements(); + + // INITIALIZE THE OUTPUT VARIABLES + SPANPAIR currpair = {0,0}; + SPAN *currspan = &currpair.copyspan; + + // IF THIS SCAN LINE HAS ZERO WIDTH, THEN JUST OUTPUT THE LINE TERMINATOR + if (imageptr->size.cx <= 0) { + ImageAddSpanPair(imageptr,&currpair,0,y); + continue; + } + + // OTHERWISE, BUILD AND OUTPUT SPANS + int x; + for (x = 0; x < imageptr->size.cx; ++x) { + if ((*(currdata++) != imageptr->transidx) != (currspan == &currpair.copyspan)) + if (currspan == &currpair.copyspan) { + imageptr->transparent = TRUE; + currspan = &currpair.skipspan; + } + else { + ImageAddSpanPair(imageptr,&currpair,x,y); + currspan = &currpair.copyspan; + } + if (*currspan == MAXSPANLENGTH) + ImageAddSpanPair(imageptr,&currpair,x,y); + ++*currspan; + } + ImageAddSpanPair(imageptr,&currpair,x,y); + + // OUTPUT THE LINE TERMINATOR + ImageAddSpanPair(imageptr,&currpair,x,y); + + } + +} + +//=========================================================================== +static void SpriteLinkToZList (TARGETPTR targetptr, + SPRITEPTR spriteptr) { + spriteptr->linkzlist.Unlink(); + SPRITEPTR before = NULL; + ITERATELIST(SPRITE,targetptr->spritezlist,curr) + if (curr->zorder > spriteptr->zorder) { + before = curr; + break; + } + targetptr->spritezlist.LinkNode(spriteptr,LIST_LINK_BEFORE,before); +} + +//=========================================================================== +static void SpriteRemoveImageReference (SPRITE *spriteptr) { + if (!--spriteptr->image->refcount) + delete spriteptr->image; + spriteptr->image = NULL; + spriteptr->linkimage.Unlink(); +} + +//=========================================================================== +static void TargetBuildDirtyRects (TARGETPTR targetptr) { + targetptr->dirtyrgn.Clear(); + ITERATELIST(SPRITE,targetptr->spritezlist,spriteptr) + if ((spriteptr->flags & SF_ERASEMARKER) || + !(spriteptr->flags & SF_DISPLAYED)) + targetptr->dirtyrgn.AddRect(&spriteptr->boundingrect,spriteptr); + else + targetptr->dirtyrgn.AddParam(&spriteptr->boundingrect,spriteptr); + DWORD numrects; + targetptr->dirtyrgn.GetRects(&numrects,NULL); + targetptr->dirtyrects.SetNumElements(numrects); + targetptr->dirtyrgn.GetRects(&numrects,targetptr->dirtyrects.Ptr()); +} + +//=========================================================================== +static void TargetCompositeRect (LPBYTE videoptr, + int pitch, + TARGETPTR targetptr, + LPCRECT rect, + DWORD sprites, + SPRITEPTR *spritearray) { + DWORD loop; + + // BUILD A LIST OF SPRITES TO COMPOSITE + targetptr->compositedata.SetNumElements(sprites); + COMPOSITEDATAPTR compositedata = targetptr->compositedata.Ptr(); + DWORD compositenum = 0; + { + BOOL aboveallchanges = TRUE; + BOOL erasing = FALSE; + DWORD lastdisplayed = UINT_MAX; + for (loop = 0; loop < sprites; ++loop) { + SPRITEPTR spriteptr = spritearray[loop]; + if (spriteptr->flags & SF_ERASEMARKER) { + aboveallchanges = FALSE; + erasing = TRUE; + } + else { + if (!(spriteptr->flags & SF_DISPLAYED)) { + aboveallchanges = FALSE; + lastdisplayed = compositenum; + } + compositedata[compositenum].spriteptr = spriteptr; + compositedata[compositenum].stable = aboveallchanges; + compositedata[compositenum].dataptr + = spriteptr->image->imagedata + +((rect->top-spriteptr->pos.y-1)*spriteptr->image->size.cx) + +(rect->left-spriteptr->pos.x) + +(rect->right-rect->left); + ++compositenum; + } + } + if (!erasing) + compositenum = lastdisplayed+1; + } + + LPBYTE destptr = videoptr+rect->top*pitch+rect->left; + for (int y = rect->top; y < rect->bottom; ++y) { + + // SETUP COMPOSITING INFO FOR THIS SCAN LINE FOR EACH SPRITE + for (loop = 0; loop < compositenum; ++loop) { + SPRITEPTR spriteptr = compositedata[loop].spriteptr; + compositedata[loop].dataptr += spriteptr->image->size.cx-(rect->right-rect->left); + if ((y >= spriteptr->boundingrect.top) && + (y < spriteptr->boundingrect.bottom)) { + compositedata[loop].spanptr = (SPAN *)(spriteptr->image->spandata.Ptr() + +spriteptr->image->spanindex[y-spriteptr->pos.y]); + compositedata[loop].currspan = spriteptr->pos.x-rect->left; + while (compositedata[loop].currspan <= 0) + if ((!((DWORD)compositedata[loop].spanptr & 1)) && + !*(LPWORD)compositedata[loop].spanptr) + compositedata[loop].currspan = INT_MAX; + else + compositedata[loop].currspan += *compositedata[loop].spanptr++; + } + else { + compositedata[loop].spanptr = NULL; + compositedata[loop].currspan = INT_MAX; + } + } + + int x = rect->left; + int xspan; + while ((xspan = rect->right-x) > 0) { + + for (loop = 0; loop < compositenum; ++loop) { + xspan = min(xspan,compositedata[loop].currspan); + if ((DWORD)compositedata[loop].spanptr & 1) + break; + } + + if ((loop < compositenum) && + !compositedata[loop].stable) { + LPBYTE sourceptr = compositedata[loop].dataptr; +#ifdef _X86_ + __asm { + + // SETUP REGISTERS + push esi + push edi + mov eax,[xspan] + xor ecx,ecx + mov esi,[sourceptr] + mov edi,[destptr] + + // PERFORM THE COPY + cmp al,3 + jbe ds_done4 + + // IF NECESSARY, MOVE A SINGLE BYTE TO WORD-ALIGN THE + // DESTINATION + test edi,1 + jz ds_aligned2 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec al + ds_aligned2: + + // IF NECESSARY, MOVE A SINGLE WORD TO DWORD-ALIGN THE + // DESTINATION + test edi,2 + jz ds_aligned4 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + sub al,2 + ds_aligned4: + + // MOVE AS MANY ALIGNED DWORDS AS POSSIBLE + mov ecx,eax + and ecx,0FCh + shr ecx,2 + rep movsd + ds_done4: + + // MOVE ONE MORE WORD IF NECESSARY + test al,2 + jz ds_done2 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + ds_done2: + + // MOVE ONE MORE BYTE IF NECESSARY + test al,1 + jz ds_done1 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + ds_done1: + + pop edi + pop esi + } +#else + CopyMemory(destptr, + sourceptr, + xspan); +#endif + } + + destptr += xspan; + x += xspan; + + for (loop = 0; loop < compositenum; ++loop) { + compositedata[loop].dataptr += xspan; + int advance = xspan; + while (advance >= compositedata[loop].currspan) { + advance -= compositedata[loop].currspan; + if ((!((DWORD)compositedata[loop].spanptr & 1)) && + !*(LPWORD)compositedata[loop].spanptr) + compositedata[loop].currspan = INT_MAX; + else + compositedata[loop].currspan = *compositedata[loop].spanptr++; + } + compositedata[loop].currspan -= advance; + } + + } + + destptr += pitch-(rect->right-rect->left); + } +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +void APIENTRY S2dImageCreate (int width, + int height, + int bitdepth, + COLORREF colorkey, + HSIMAGE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATEENDVOID; + + if (!CheckForSupportedColorFormat(bitdepth,colorkey)) + return; + + s_apicritsect.Enter(); + + // CREATE A NEW IMAGE RECORD + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.NewLock(handle,&lockedhandle); + imageptr->size.cx = width; + imageptr->size.cy = height; + imageptr->boundingrect.left = UINT_MAX; + imageptr->boundingrect.top = UINT_MAX; + imageptr->boundingrect.right = UINT_MAX; + imageptr->boundingrect.bottom = UINT_MAX; + imageptr->transidx = (BYTE)(colorkey & 0xFF); + imageptr->refcount = 1; + s_imagetable.Unlock(lockedhandle); + + s_apicritsect.Leave(); +} + +//=========================================================================== +BOOL APIENTRY S2dImageCreateFromFile (LPCTSTR filename, + COLORREF colorkey, + DWORD numimages, + LPCRECT rectarray, + HSIMAGE *handlearray) { + if (numimages && handlearray) + ZeroMemory(handlearray,numimages*sizeof(HSIMAGE)); + + VALIDATEBEGIN; + VALIDATE(filename && *filename); + VALIDATE(numimages); + VALIDATE(handlearray); + VALIDATEEND; + + s_apicritsect.Enter(); + HSFILE file = (HSFILE)0; + LPBYTE filebuffer = NULL; + BOOL result = FALSE; + TRY { + + // LOAD THE FILE FROM DISK + if (!SFileOpenFile(filename,&file)) + LEAVE; + DWORD filesize = SFileGetFileSize(file,NULL); + filebuffer = (LPBYTE)ALLOC(filesize); + if (!SFileReadFile(file,filebuffer,filesize)) + LEAVE; + + // DETERMINE THE SOURCE IMAGE DIMENSIONS + int width, height, bitdepth; + if (!SBmpDecodeImage(SBMP_IMAGETYPE_AUTO, + filebuffer, + filesize, + NULL, + NULL, + 0, + &width, + &height, + &bitdepth)) + LEAVE; + + // VERIFY THAT THE FILE IS IN A SUPPORTED COLOR FORMAT + if (!CheckForSupportedColorFormat(bitdepth,colorkey)) + LEAVE; + + // DECODE THE FILE INTO A TEMPORARY BUFFER + int bytedepth = bitdepth/8; + DWORD sourcebytes = width*height*(DWORD)bytedepth; + LPBYTE buffer = (LPBYTE)ALLOC(sourcebytes); + SBmpDecodeImage(SBMP_IMAGETYPE_AUTO, + filebuffer, + filesize, + NULL, + buffer, + sourcebytes); + + // PROCESS EACH IMAGE + for (DWORD loop = 0; + loop < numimages; + ++loop) { + + // DETERMINE THE IMAGE DIMENSIONS + int destwidth = width; + int destheight = height; + if (rectarray) { + destwidth = min(destwidth ,rectarray[loop].right+1-rectarray[loop].left); + destheight = min(destheight,rectarray[loop].bottom+1-rectarray[loop].top); + } + + // CREATE THE IMAGE + S2dImageCreate(destwidth, + destheight, + bitdepth, + colorkey, + &handlearray[loop]); + + // LOCK THE IMAGE BUFFER + LPBYTE ptr; + S2dImageLockBuffer(handlearray[loop],TRUE,&ptr); + + // BLT THE SOURCE RECTANGLE INTO THE IMAGE BUFFER + SIZE adjdestsize = {destwidth*bytedepth, + destheight}; + SIZE adjsourcesize = {width*bytedepth, + height}; + RECT adjsourcerect = {0, + 0, + adjsourcesize.cx, + adjsourcesize.cy}; + if (rectarray) { + adjsourcerect.left = rectarray[loop].left*bytedepth; + adjsourcerect.top = rectarray[loop].top; + adjsourcerect.right = rectarray[loop].right*bytedepth; + adjsourcerect.bottom = rectarray[loop].bottom; + } + SBltROP3Clipped(ptr, + NULL, + &adjdestsize, + adjdestsize.cx, + buffer, + &adjsourcerect, + &adjsourcesize, + adjsourcesize.cx, + 0, + SRCCOPY); + + // UNLOCK THE IMAGE BUFFER + S2dImageUnlockBuffer(handlearray[loop],ptr); + + } + + // FREE THE TEMPORARY BUFFER + FREE(buffer); + + result = TRUE; + } + FINALLY { + FREEIFUSED(filebuffer); + if (file) + SFileCloseFile(file); + } + s_apicritsect.Leave(); + return result; +} + +//=========================================================================== +void APIENTRY S2dImageDelete (HSIMAGE handle) { + s_apicritsect.Enter(); + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.Lock(handle,&lockedhandle); + if (!--imageptr->refcount) + s_imagetable.DeleteUnlock(imageptr,lockedhandle); + else + s_imagetable.Unlock(lockedhandle); + s_apicritsect.Leave(); +} + +//=========================================================================== +BOOL APIENTRY S2dImageLockBuffer (HSIMAGE handle, + BOOL blank, + LPBYTE *ptr) { + VALIDATEBEGIN; + VALIDATEANDBLANK(ptr); + VALIDATEEND; + + s_apicritsect.Enter(); + for (ONCE) { + + // FIND THE IMAGE RECORD + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.Lock(handle,&lockedhandle); + if (!imageptr) + break; + + // ALLOCATE A BUFFER IF NECESSARY + DWORD bytes = imageptr->size.cx*imageptr->size.cy; + if (!imageptr->imagedata) + imageptr->imagedata = (LPBYTE)ALLOC(bytes); + + // BLANK THE BUFFER IF REQUESTED + if (blank) + FillMemory(imageptr->imagedata,bytes,imageptr->transidx); + + // RETURN THE BUFFER + *ptr = imageptr->imagedata; + + s_imagetable.Unlock(lockedhandle); + } + s_apicritsect.Leave(); + return (*ptr != NULL); +} + +//=========================================================================== +void APIENTRY S2dImageUnlockBuffer (HSIMAGE handle, + LPBYTE ptr) { + s_apicritsect.Enter(); + for (ONCE) { + + // FIND THE IMAGE RECORD + HLOCKEDIMAGE lockedhandle; + IMAGEPTR imageptr = s_imagetable.Lock(handle,&lockedhandle); + if (!imageptr) + break; + + // PRODUCE THE SPAN DATA + ImageCreateSpanData(imageptr); + + s_imagetable.Unlock(lockedhandle); + } + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteCreate (HSSPRITE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + s_spritetable.New(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteDelete (HSSPRITE handle) { + s_apicritsect.Enter(); + s_spritetable.Delete(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteSetImage (HSSPRITE handle, + HSIMAGE imagehandle) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(imagehandle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + + // LOCK THE SPRITE AND IMAGE + HLOCKEDSPRITE lockedsprite; + HLOCKEDIMAGE lockedimage; + SPRITEPTR spriteptr = s_spritetable.Lock(handle,&lockedsprite); + IMAGEPTR imageptr = s_imagetable.Lock(imagehandle,&lockedimage); + if (spriteptr->image != imageptr) { + + // REMOVE THE REFERENCE TO THE SPRITE'S OLD IMAGE + if (spriteptr->image) + SpriteRemoveImageReference(spriteptr); + + // ASSOCIATE THE IMAGE WITH THE SPRITE + if (imageptr) { + ++imageptr->refcount; + spriteptr->image = imageptr; + imageptr->spritelist.LinkNode(spriteptr); + } + + } + + // UNLOCK THE SPRITE AND IMAGE + s_imagetable.Unlock(lockedimage); + s_spritetable.Unlock(lockedsprite); + + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteSetPos (HSSPRITE handle, + int x, + int y) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + for (ONCE) { + + // LOCK THE SPRITE + HLOCKEDSPRITE lockedhandle; + SPRITEPTR spriteptr = s_spritetable.Lock(handle,&lockedhandle); + if (!spriteptr) + break; + + // PLACE AN ERASE MARKER AT THE SPRITE'S OLD POSITION + if (spriteptr->flags & SF_DISPLAYED) { + SPRITEPTR newptr = spriteptr->target->spritezlist.NewNode(LIST_UNLINKED); + newptr->pos = spriteptr->pos; + newptr->boundingrect = spriteptr->boundingrect; + newptr->flags = SF_ERASEMARKER; + newptr->zorder = spriteptr->zorder; + newptr->target = spriteptr->target; + spriteptr->target->spritezlist.LinkNode(newptr,LIST_LINK_AFTER,spriteptr); + } + + // SET THE SPRITE'S POSITION AND BOUNDING RECTANGLE + spriteptr->pos.x = x; + spriteptr->pos.y = y; + spriteptr->boundingrect.left = x+spriteptr->image->boundingrect.left; + spriteptr->boundingrect.top = y+spriteptr->image->boundingrect.top; + spriteptr->boundingrect.right = x+spriteptr->image->boundingrect.right; + spriteptr->boundingrect.bottom = y+spriteptr->image->boundingrect.bottom; + spriteptr->flags &= ~SF_DISPLAYED; + + // UNLOCK THE SPRITE + s_spritetable.Unlock(lockedhandle); + + } + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dSpriteSetTarget (HSSPRITE handle, + HSTARGET targethandle, + int zorder) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(targethandle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + + // LOCK THE SPRITE AND TARGET + HLOCKEDSPRITE lockedsprite; + HLOCKEDTARGET lockedtarget; + SPRITEPTR spriteptr = s_spritetable.Lock(handle,&lockedsprite); + TARGETPTR targetptr = s_targettable.Lock(targethandle,&lockedtarget); + + // SET THE SPRITE'S Z ORDER AND LINK IT INTO THE TARGET'S Z LIST + spriteptr->zorder = zorder; + spriteptr->target = targetptr; + SpriteLinkToZList(targetptr,spriteptr); + + // UNLOCK THE SPRITE AND TARGET + s_targettable.Unlock(lockedtarget); + s_spritetable.Unlock(lockedsprite); + + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dTargetCreate (HSTARGET *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATEENDVOID; + + s_apicritsect.Enter(); + s_targettable.New(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dTargetDelete (HSTARGET handle) { + s_apicritsect.Enter(); + s_targettable.Delete(handle); + s_apicritsect.Leave(); +} + +//=========================================================================== +void APIENTRY S2dTestDrawTarget (HSTARGET handle, + LPBYTE ptr, + int pitch) { + s_apicritsect.Enter(); + for (ONCE) { + + HLOCKEDTARGET lockedhandle; + TARGETPTR targetptr = s_targettable.Lock(handle,&lockedhandle); + if (!targetptr) + break; + + TargetBuildDirtyRects(targetptr); + for (DWORD rectindex = 0; + rectindex < targetptr->dirtyrects.NumElements(); + ++rectindex) { + DWORD totalparams; + targetptr->dirtyrgn.GetRectParams(&targetptr->dirtyrects[rectindex], + &totalparams, + NULL); + targetptr->dirtyrectparams.SetNumElements(totalparams); + targetptr->dirtyrgn.GetRectParams(&targetptr->dirtyrects[rectindex], + &totalparams, + targetptr->dirtyrectparams.Ptr()); + TargetCompositeRect(ptr, + pitch, + targetptr, + &targetptr->dirtyrects[rectindex], + totalparams, + (SPRITEPTR *)(targetptr->dirtyrectparams.Ptr())); + } + + ITERATELIST(SPRITE,targetptr->spritezlist,spriteptr) + if (spriteptr->flags & SF_ERASEMARKER) + ITERATE_DELETE + else + spriteptr->flags |= SF_DISPLAYED; + + s_targettable.Unlock(lockedhandle); + } + s_apicritsect.Leave(); +} diff --git a/Storm/SAMPLES/ANIM/OLD/S2D.H b/Storm/SAMPLES/ANIM/OLD/S2D.H new file mode 100644 index 0000000..ded5029 --- /dev/null +++ b/Storm/SAMPLES/ANIM/OLD/S2D.H @@ -0,0 +1,42 @@ +/**************************************************************************** +* +* 2D graphics engine functions +* +***/ + +DECLARE_STRICT_HANDLE(HSIMAGE); +DECLARE_STRICT_HANDLE(HSSPRITE); +DECLARE_STRICT_HANDLE(HSTARGET); + +void APIENTRY S2dImageCreate (int width, + int height, + int bitdepth, + COLORREF colorkey, + HSIMAGE *handle); +BOOL APIENTRY S2dImageCreateFromFile (LPCTSTR filename, + COLORREF colorkey, + DWORD numimages, + LPCRECT rectarray, + HSIMAGE *handlearray); +void APIENTRY S2dImageDelete (HSIMAGE handle); +BOOL APIENTRY S2dImageLockBuffer (HSIMAGE handle, + BOOL blank, + LPBYTE *ptr); +void APIENTRY S2dImageUnlockBuffer (HSIMAGE handle, + LPBYTE ptr); +void APIENTRY S2dSpriteCreate (HSSPRITE *handle); +void APIENTRY S2dSpriteDelete (HSSPRITE handle); +void APIENTRY S2dSpriteSetImage (HSSPRITE handle, + HSIMAGE imagehandle); +void APIENTRY S2dSpriteSetPos (HSSPRITE handle, + int x, + int y); +void APIENTRY S2dSpriteSetTarget (HSSPRITE handle, + HSTARGET targethandle, + int zorder); +void APIENTRY S2dTargetCreate (HSTARGET *handle); +void APIENTRY S2dTargetDelete (HSTARGET handle); + +void APIENTRY S2dTestDrawTarget (HSTARGET handle, + LPBYTE ptr, + int pitch); diff --git a/Storm/SAMPLES/ANIM/OLD/TRACE.TXT b/Storm/SAMPLES/ANIM/OLD/TRACE.TXT new file mode 100644 index 0000000..37befe1 --- /dev/null +++ b/Storm/SAMPLES/ANIM/OLD/TRACE.TXT @@ -0,0 +1,6 @@ +3642 +3384 +3441 +3492 +3505 +3528 diff --git a/Storm/SAMPLES/BUILDALL.BAT b/Storm/SAMPLES/BUILDALL.BAT new file mode 100644 index 0000000..9536e14 --- /dev/null +++ b/Storm/SAMPLES/BUILDALL.BAT @@ -0,0 +1,2 @@ +@echo off +for /r %%a in (*.cs) do c /as %%a diff --git a/Storm/SAMPLES/SAMPLE.CS b/Storm/SAMPLES/SAMPLE.CS new file mode 100644 index 0000000..01ff78c --- /dev/null +++ b/Storm/SAMPLES/SAMPLE.CS @@ -0,0 +1,6 @@ +if not %project%==sample goto start +halt +:start +#include +#include +!if exist *.bak del *.bak diff --git a/Storm/SAMPLES/SBLT/BENCH/BENCH.CPP b/Storm/SAMPLES/SBLT/BENCH/BENCH.CPP new file mode 100644 index 0000000..2c11069 --- /dev/null +++ b/Storm/SAMPLES/SBLT/BENCH/BENCH.CPP @@ -0,0 +1,121 @@ +/**************************************************************************** +* +* BENCH.CPP +* +* Benchmarks Storm's bitblt performance. +* +***/ + +#include +#include + +#define ALIGNED + +LPBYTE bitmap = NULL; +HSGDIFONT font = (HSGDIFONT)0; +BOOL paused = 0; +DWORD iterations = 0; + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 640)-20; + int top = (rand() % 450)+12; +#ifdef ALIGNED + left = (left >> 2) << 2; +#endif + SGdiSetPitch(pitch); + SGdiBitBlt(videobuffer,left,top,bitmap,NULL,40,40); + ++iterations; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL LoadBitmap () { + PALETTEENTRY pe[256]; + if (!SBmpAllocLoadImage("blizlogo.pcx",&pe[0],&bitmap)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + KillTimer(params->window,1); + SGdiDeleteObject(font); + FREE(bitmap); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + char outstr[64]; + wsprintf(outstr,"%u bitblts per second",iterations); + RECT rect = {0,0,320,12}; + SGdiSetPitch(pitch); + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + iterations = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DDBENCH"), + TEXT("Benchmark"))) + return 1; + if (!LoadBitmap()) + return 1; + if (!LoadFont()) + return 1; + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SBLT/BENCH/BENCH.CS b/Storm/SAMPLES/SBLT/BENCH/BENCH.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SBLT/BENCH/BENCH.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SBLT/BENCH/BENCH.EXE b/Storm/SAMPLES/SBLT/BENCH/BENCH.EXE new file mode 100644 index 0000000..cfb0e3a Binary files /dev/null and b/Storm/SAMPLES/SBLT/BENCH/BENCH.EXE differ diff --git a/Storm/SAMPLES/SBLT/BENCH/BLIZLOGO.PCX b/Storm/SAMPLES/SBLT/BENCH/BLIZLOGO.PCX new file mode 100644 index 0000000..4dc0a66 Binary files /dev/null and b/Storm/SAMPLES/SBLT/BENCH/BLIZLOGO.PCX differ diff --git a/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.CPP b/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.CPP new file mode 100644 index 0000000..d7b8db4 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.CPP @@ -0,0 +1,225 @@ +/**************************************************************************** +* +* LIGHT1.CPP +* +* This series of examples performs lighting, using table lookup, while +* blting a 40x40 image. +* +* This first example does the bitblt in assembly language, using a simple +* implementation that loads the next byte, looks it up in the lighting +* table, then writes it. +* +***/ + +#include +#include + +BYTE lightingtable[16][256]; + +LPBYTE bitmapbits = NULL; +HSGDIFONT font = (HSGDIFONT)0; +BOOL paused = 0; +DWORD rectangles = 0; + +int inline square (int a) { return a*a; } + +//=========================================================================== +void BitBltLighting (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + int lightlevel) { + LPVOID table = lightingtable; + __asm { + + // SAVE IMPORTANT REGISTERS + push esi + push edi + push ebp + + // SETUP THE SOURCE AND DESTINATION + mov esi,source + mov edi,dest + + // COMPUTE THE AMOUNT WE WILL ADJUST THE SOURCE AND + // DESTINATION AFTER EACH LINE + mov ebx,sourcecx + mov edx,destcx + sub ebx,width + sub edx,width + + // SAVE THE LOOP COUNTERS + mov eax,width + mov cl,al + mov eax,height + mov ch,al + push ecx + + // SETUP A POINTER TO THE LIGHTING TABLE + mov eax,lightlevel + mov ebp,table + shl eax,8 + add ebp,eax + + // BLANK OUT EAX FOR USE AS A WORK REGISTER + xor eax,eax + + // PERFORM THE BITBLT + next: mov al,[esi] + inc esi + mov al,[ebp+eax] + mov [edi],al + inc edi + dec cl + jnz next + mov cl,[esp] + add esi,ebx + add edi,edx + dec ch + jnz next + + // RESTORE REGISTERS + pop ecx + pop ebp + pop edi + pop esi + + } +} + +//=========================================================================== +void CreateLightingTable (LPPALETTEENTRY pe) { + for (int lightlevel = 0; lightlevel < 16; ++lightlevel) + for (int index = 0; index < 256; ++index) { + int red = ((int)(pe+index)->peRed )*lightlevel/8; + int green = ((int)(pe+index)->peGreen)*lightlevel/8; + int blue = ((int)(pe+index)->peBlue )*lightlevel/8; + int minval = 0x7FFFFFFF; + int minindex = 0; + for (int testindex = 0; testindex < 256; ++testindex) { + int proximity = square(red-(int)(pe+testindex)->peRed) + +square(green-(int)(pe+testindex)->peGreen) + +square(blue-(int)(pe+testindex)->peBlue); + if (proximity < minval) { + minval = proximity; + minindex = testindex; + } + } + lightingtable[lightlevel][index] = minindex; + } +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + static BYTE lightlevel = 0; + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 600); + int top = (rand() % 428)+12; + BitBltLighting(videobuffer+top*pitch+left,bitmapbits,40,40,pitch,40,lightlevel & 0x0F); + ++lightlevel; + ++rectangles; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + FREE(bitmapbits); + bitmapbits = NULL; + KillTimer(params->window,1); + SGdiDeleteObject(font); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + char outstr[80]; + wsprintf(outstr,"%u bitblts per second using assembly (bytes)",rectangles); + RECT rect = {0,0,639,12}; + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + rectangles = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + + // INITIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("LIGHTING"), + TEXT("Lighting Test"))) + return 1; + + // LOAD THE TEST BITMAP AND SET THE PALETTE + { + bitmapbits = (LPBYTE)ALLOC(40*40); + if (!bitmapbits) + return 1; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage(TEXT("test.pcx"),&pe[0],bitmapbits,40*40)) + return 1; + if (!SDrawUpdatePalette(0,256,&pe[0])) + return 1; + CreateLightingTable(&pe[0]); + } + + // LOAD AND SELECT THE FONT + if (!LoadFont()) + return 1; + + // REGISTER MESSAGE HANDLERS AND SET THE TIMER + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + + // RUN THE MESSAGE LOOP + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.CS b/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.CS new file mode 100644 index 0000000..c42d6c0 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.CS @@ -0,0 +1 @@ +#include "..\..\sample.cs" diff --git a/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.EXE b/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.EXE new file mode 100644 index 0000000..8114bf7 Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT1/LIGHT1.EXE differ diff --git a/Storm/SAMPLES/SCODE/LIGHT1/TEST.PCX b/Storm/SAMPLES/SCODE/LIGHT1/TEST.PCX new file mode 100644 index 0000000..5421a7d Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT1/TEST.PCX differ diff --git a/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.CPP b/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.CPP new file mode 100644 index 0000000..b06c301 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.CPP @@ -0,0 +1,223 @@ +/**************************************************************************** +* +* LIGHT2.CPP +* +* This next example also uses an assembly language bitblt function, but this +* time it tries to read and write as many whole doublewords as possible. +* The inner loop of the function is taken from Diablo. +* +***/ + +#include +#include + +BYTE lightingtable[16][256]; + +LPBYTE bitmapbits = NULL; +HSGDIFONT font = (HSGDIFONT)0; +BOOL paused = 0; +DWORD rectangles = 0; + +int inline square (int a) { return a*a; } + +//=========================================================================== +void BitBltLighting (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + int lightlevel) { + LPVOID table = lightingtable; + DWORD destadjust = destcx-width; + DWORD sourceadjust = sourcecx-width; + __asm { + + // SAVE IMPORTANT REGISTERS + push esi + push edi + + // SETUP THE SOURCE AND DESTINATION + mov esi,source + mov edi,dest + + // SETUP REGISTERS + mov eax,lightlevel + mov ebx,table + shl eax,8 + add ebx,eax + mov edx,width + + // START THE NEXT LINE + startline: mov ecx,edx + and ecx,3 + jz startdword + + // USE BYTES FOR ODD PIXELS + nextbyte: lodsb + xlatb + stosb + loop nextbyte + + // USE DWORDS FOR THE REST + startdword: mov ecx,edx + shr ecx,2 + nextdword: lodsd + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + xlatb + ror eax,8 + stosd + loop nextdword + + // ADJUST FOR THE NEXT LINE + add esi,sourceadjust + add edi,destadjust + dec height + jnz startline + + // RESTORE REGISTERS + pop edi + pop esi + + } +} + +//=========================================================================== +void CreateLightingTable (LPPALETTEENTRY pe) { + for (int lightlevel = 0; lightlevel < 16; ++lightlevel) + for (int index = 0; index < 256; ++index) { + int red = ((int)(pe+index)->peRed )*lightlevel/8; + int green = ((int)(pe+index)->peGreen)*lightlevel/8; + int blue = ((int)(pe+index)->peBlue )*lightlevel/8; + int minval = 0x7FFFFFFF; + int minindex = 0; + for (int testindex = 0; testindex < 256; ++testindex) { + int proximity = square(red-(int)(pe+testindex)->peRed) + +square(green-(int)(pe+testindex)->peGreen) + +square(blue-(int)(pe+testindex)->peBlue); + if (proximity < minval) { + minval = proximity; + minindex = testindex; + } + } + lightingtable[lightlevel][index] = minindex; + } +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + static BYTE lightlevel = 0; + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 600); + int top = (rand() % 428)+12; + BitBltLighting(videobuffer+top*pitch+left,bitmapbits,40,40,pitch,40,lightlevel & 0x0F); + ++lightlevel; + ++rectangles; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + FREE(bitmapbits); + bitmapbits = NULL; + KillTimer(params->window,1); + SGdiDeleteObject(font); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + char outstr[80]; + wsprintf(outstr,"%u bitblts per second using assembly (dwords, complex instructions)",rectangles); + RECT rect = {0,0,639,12}; + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + rectangles = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + + // INITIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("LIGHTING"), + TEXT("Lighting Test"))) + return 1; + + // LOAD THE TEST BITMAP AND SET THE PALETTE + { + bitmapbits = (LPBYTE)ALLOC(40*40); + if (!bitmapbits) + return 1; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage(TEXT("test.pcx"),&pe[0],bitmapbits,40*40)) + return 1; + if (!SDrawUpdatePalette(0,256,&pe[0])) + return 1; + CreateLightingTable(&pe[0]); + } + + // LOAD AND SELECT THE FONT + if (!LoadFont()) + return 1; + + // REGISTER MESSAGE HANDLERS AND SET THE TIMER + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + + // RUN THE MESSAGE LOOP + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.CS b/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.CS new file mode 100644 index 0000000..c42d6c0 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.CS @@ -0,0 +1 @@ +#include "..\..\sample.cs" diff --git a/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.EXE b/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.EXE new file mode 100644 index 0000000..9d48dd8 Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT2/LIGHT2.EXE differ diff --git a/Storm/SAMPLES/SCODE/LIGHT2/TEST.PCX b/Storm/SAMPLES/SCODE/LIGHT2/TEST.PCX new file mode 100644 index 0000000..5421a7d Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT2/TEST.PCX differ diff --git a/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.CPP b/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.CPP new file mode 100644 index 0000000..caff784 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.CPP @@ -0,0 +1,233 @@ +/**************************************************************************** +* +* LIGHT3.CPP +* +* This next version also uses assembly language, and also does reads and +* writes whole doublewords at a time where possible. The difference is +* that the inner loop has been recoded to avoid the use of complex +* instructions, which execute slowly on modern Intel processors. +* +***/ + +#include +#include + +BYTE lightingtable[16][256]; + +LPBYTE bitmapbits = NULL; +HSGDIFONT font = (HSGDIFONT)0; +BOOL paused = 0; +DWORD rectangles = 0; + +int inline square (int a) { return a*a; } + +//=========================================================================== +void BitBltLighting (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + int lightlevel) { + LPBYTE table = ((LPBYTE)lightingtable)+(lightlevel << 8); + BYTE width8 = width & 0xFF; + DWORD destadjust = destcx-width; + DWORD sourceadjust = sourcecx-width; + __asm { + + // SAVE IMPORTANT REGISTERS + push esi + push edi + + // SETUP THE SOURCE AND DESTINATION + mov esi,source + mov edi,dest + + // SETUP REGISTERS + xor eax,eax + xor ebx,ebx + + // START THE NEXT LINE + startline: mov ch,width8 + mov cl,ch + push ebp + mov ebp,table + shr ch,2 + and cl,3 + jz nextdword + + // USE BYTES FOR ODD PIXELS + nextbyte: mov al,[esi] + inc esi + mov al,[ebp+eax] + mov [edi],al + inc edi + dec cl + jnz nextbyte + + // USE DWORDS FOR THE REST + nextdword: mov edx,[esi] + add esi,4 + mov al,dl + mov bl,dh + mov dl,[ebp+eax] + mov dh,[ebp+ebx] + ror edx,16 + mov al,dl + mov bl,dh + mov dl,[ebp+eax] + mov dh,[ebp+ebx] + ror edx,16 + mov [edi],edx + add edi,4 + dec ch + jnz nextdword + + // ADJUST FOR THE NEXT LINE + pop ebp + add esi,sourceadjust + add edi,destadjust + dec height + jnz startline + + // RESTORE REGISTERS + pop edi + pop esi + + } +} + +//=========================================================================== +void CreateLightingTable (LPPALETTEENTRY pe) { + for (int lightlevel = 0; lightlevel < 16; ++lightlevel) + for (int index = 0; index < 256; ++index) { + int red = ((int)(pe+index)->peRed )*lightlevel/8; + int green = ((int)(pe+index)->peGreen)*lightlevel/8; + int blue = ((int)(pe+index)->peBlue )*lightlevel/8; + int minval = 0x7FFFFFFF; + int minindex = 0; + for (int testindex = 0; testindex < 256; ++testindex) { + int proximity = square(red-(int)(pe+testindex)->peRed) + +square(green-(int)(pe+testindex)->peGreen) + +square(blue-(int)(pe+testindex)->peBlue); + if (proximity < minval) { + minval = proximity; + minindex = testindex; + } + } + lightingtable[lightlevel][index] = minindex; + } +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + static BYTE lightlevel = 0; + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 600); + int top = (rand() % 428)+12; + BitBltLighting(videobuffer+top*pitch+left,bitmapbits,40,40,pitch,40,lightlevel & 0x0F); + ++lightlevel; + ++rectangles; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + FREE(bitmapbits); + bitmapbits = NULL; + KillTimer(params->window,1); + SGdiDeleteObject(font); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + char outstr[80]; + wsprintf(outstr,"%u bitblts per second using assembly (dwords, simple instructions)",rectangles); + RECT rect = {0,0,639,12}; + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + rectangles = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + + // INITIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("LIGHTING"), + TEXT("Lighting Test"))) + return 1; + + // LOAD THE TEST BITMAP AND SET THE PALETTE + { + bitmapbits = (LPBYTE)ALLOC(40*40); + if (!bitmapbits) + return 1; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage(TEXT("test.pcx"),&pe[0],bitmapbits,40*40)) + return 1; + if (!SDrawUpdatePalette(0,256,&pe[0])) + return 1; + CreateLightingTable(&pe[0]); + } + + // LOAD AND SELECT THE FONT + if (!LoadFont()) + return 1; + + // REGISTER MESSAGE HANDLERS AND SET THE TIMER + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + + // RUN THE MESSAGE LOOP + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.CS b/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.CS new file mode 100644 index 0000000..c42d6c0 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.CS @@ -0,0 +1 @@ +#include "..\..\sample.cs" diff --git a/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.EXE b/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.EXE new file mode 100644 index 0000000..6a6131d Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT3/LIGHT3.EXE differ diff --git a/Storm/SAMPLES/SCODE/LIGHT3/TEST.PCX b/Storm/SAMPLES/SCODE/LIGHT3/TEST.PCX new file mode 100644 index 0000000..5421a7d Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT3/TEST.PCX differ diff --git a/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.CPP b/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.CPP new file mode 100644 index 0000000..248599c --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.CPP @@ -0,0 +1,240 @@ +/**************************************************************************** +* +* LIGHT4.CPP +* +* This version is similar to the previous one, except that it does aligned +* dword writes where possible. +* +***/ + +#include +#include + +BYTE lightingtable[16][256]; + +LPBYTE bitmapbits = NULL; +HSGDIFONT font = (HSGDIFONT)0; +BOOL paused = 0; +DWORD rectangles = 0; + +int inline square (int a) { return a*a; } + +//=========================================================================== +void BitBltLighting (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + int lightlevel) { + LPBYTE table = ((LPBYTE)lightingtable)+(lightlevel << 8); + DWORD destadjust = destcx-width; + DWORD sourceadjust = sourcecx-width; + __asm { + + // SAVE IMPORTANT REGISTERS + push esi + push edi + + // SETUP THE SOURCE AND DESTINATION + mov esi,source + mov edi,dest + + // SETUP REGISTERS + xor eax,eax + xor ebx,ebx + + // START THE NEXT LINE + startline: mov ecx,width + push ebp + mov ebp,table + + // USE BYTES FOR THE FIRST SET OF UNALIGNED PIXELS + nextbyte1: test edi,3 + jz nextdword + mov al,[esi] + inc esi + mov al,[ebp+eax] + dec ecx + mov [edi],al + inc edi + jmp nextbyte1 + + // USE DWORDS FOR THE MAIN BODY + nextdword: cmp ecx,4 + jb nextbyte2 + mov edx,[esi] + add esi,4 + mov al,dl + mov bl,dh + mov dl,[ebp+eax] + mov dh,[ebp+ebx] + ror edx,16 + mov al,dl + mov bl,dh + mov dl,[ebp+eax] + mov dh,[ebp+ebx] + ror edx,16 + sub ecx,4 + mov [edi],edx + add edi,4 + jmp nextdword + + // USE BYTES FOR THE SECOND SET OF UNALIGNED PIXELS + nextbyte2: dec ecx + js finish + mov al,[esi] + inc esi + mov al,[ebp+eax] + mov [edi],al + inc edi + jmp nextbyte2 + + // ADJUST FOR THE NEXT LINE + finish: pop ebp + add esi,sourceadjust + add edi,destadjust + dec height + jnz startline + + // RESTORE REGISTERS + pop edi + pop esi + + } +} + +//=========================================================================== +void CreateLightingTable (LPPALETTEENTRY pe) { + for (int lightlevel = 0; lightlevel < 16; ++lightlevel) + for (int index = 0; index < 256; ++index) { + int red = ((int)(pe+index)->peRed )*lightlevel/8; + int green = ((int)(pe+index)->peGreen)*lightlevel/8; + int blue = ((int)(pe+index)->peBlue )*lightlevel/8; + int minval = 0x7FFFFFFF; + int minindex = 0; + for (int testindex = 0; testindex < 256; ++testindex) { + int proximity = square(red-(int)(pe+testindex)->peRed) + +square(green-(int)(pe+testindex)->peGreen) + +square(blue-(int)(pe+testindex)->peBlue); + if (proximity < minval) { + minval = proximity; + minindex = testindex; + } + } + lightingtable[lightlevel][index] = minindex; + } +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + static BYTE lightlevel = 0; + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 600); + int top = (rand() % 428)+12; + BitBltLighting(videobuffer+top*pitch+left,bitmapbits,40,40,pitch,40,lightlevel & 0x0F); + ++lightlevel; + ++rectangles; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + FREE(bitmapbits); + bitmapbits = NULL; + KillTimer(params->window,1); + SGdiDeleteObject(font); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + char outstr[80]; + wsprintf(outstr,"%u bitblts per second using assembly (aligned dwords)",rectangles); + RECT rect = {0,0,639,12}; + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + rectangles = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + + // INITIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("LIGHTING"), + TEXT("Lighting Test"))) + return 1; + + // LOAD THE TEST BITMAP AND SET THE PALETTE + { + bitmapbits = (LPBYTE)ALLOC(40*40); + if (!bitmapbits) + return 1; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage(TEXT("test.pcx"),&pe[0],bitmapbits,40*40)) + return 1; + if (!SDrawUpdatePalette(0,256,&pe[0])) + return 1; + CreateLightingTable(&pe[0]); + } + + // LOAD AND SELECT THE FONT + if (!LoadFont()) + return 1; + + // REGISTER MESSAGE HANDLERS AND SET THE TIMER + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + + // RUN THE MESSAGE LOOP + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.CS b/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.CS new file mode 100644 index 0000000..c42d6c0 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.CS @@ -0,0 +1 @@ +#include "..\..\sample.cs" diff --git a/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.EXE b/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.EXE new file mode 100644 index 0000000..07f0754 Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT4/LIGHT4.EXE differ diff --git a/Storm/SAMPLES/SCODE/LIGHT4/TEST.PCX b/Storm/SAMPLES/SCODE/LIGHT4/TEST.PCX new file mode 100644 index 0000000..5421a7d Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT4/TEST.PCX differ diff --git a/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.CPP b/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.CPP new file mode 100644 index 0000000..33285dd --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.CPP @@ -0,0 +1,189 @@ +/**************************************************************************** +* +* LIGHT5.CPP +* +* This final version uses Storm's S-code compiler instead of assembly +* language to perform the blt. The advantages are: +* 1. Storm compiles S-code into fully unrolled machine language loops, +* which can process an entire scan line with no loop counter or +* conditional jumps. +* 2. Storm ensures that all dword operations are aligned on dword +* boundaries. +* 3. Since there is no loop counter, an additional general purpose register +* is available for the code to use. (In this particular case, there was +* no need of the extra register, but in many programs this would provide +* an additional speed boost.) +* 4. Using S-code instead of assembly language simplifies the program. +* (In this case, the number of lines of code involved with the lighting +* blt was reduced from 87 to 16.) +* 5. Using S-code instead of assembly language simplifies porting the +* program to other platforms. +* +***/ + +#include +#include + +BYTE lightingtable[16][256]; + +LPBYTE bitmapbits = NULL; +HSGDIFONT font = (HSGDIFONT)0; +BOOL paused = 0; +DWORD rectangles = 0; +HSCODESTREAM scodestream = (HSCODESTREAM)0; +SCODEEXECUTEDATA scodeexec; + +int inline square (int a) { return a*a; } + +//=========================================================================== +void CreateLightingTable (LPPALETTEENTRY pe) { + for (int lightlevel = 0; lightlevel < 16; ++lightlevel) + for (int index = 0; index < 256; ++index) { + int red = ((int)(pe+index)->peRed )*lightlevel/8; + int green = ((int)(pe+index)->peGreen)*lightlevel/8; + int blue = ((int)(pe+index)->peBlue )*lightlevel/8; + int minval = 0x7FFFFFFF; + int minindex = 0; + for (int testindex = 0; testindex < 256; ++testindex) { + int proximity = square(red-(int)(pe+testindex)->peRed) + +square(green-(int)(pe+testindex)->peGreen) + +square(blue-(int)(pe+testindex)->peBlue); + if (proximity < minval) { + minval = proximity; + minindex = testindex; + } + } + lightingtable[lightlevel][index] = minindex; + } +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + static BYTE lightlevel = 0; + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + scodeexec.adjustdest = pitch-40; + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 600); + int top = (rand() % 428)+12; + scodeexec.dest = videobuffer+top*pitch+left; + scodeexec.table = &lightingtable[lightlevel & 0x0F][0]; + SCodeExecute(scodestream,&scodeexec); + ++lightlevel; + ++rectangles; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + FREE(bitmapbits); + bitmapbits = NULL; + KillTimer(params->window,1); + SGdiDeleteObject(font); + SCodeDelete(scodestream); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + char outstr[80]; + wsprintf(outstr,"%u bitblts per second using S-code",rectangles); + RECT rect = {0,0,639,12}; + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + rectangles = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + + // INITIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("LIGHTING"), + TEXT("Lighting Test"))) + return 1; + + // LOAD THE TEST BITMAP AND SET THE PALETTE + { + bitmapbits = (LPBYTE)ALLOC(40*40); + if (!bitmapbits) + return 1; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage(TEXT("test.pcx"),&pe[0],bitmapbits,40*40)) + return 1; + if (!SDrawUpdatePalette(0,256,&pe[0])) + return 1; + CreateLightingTable(&pe[0]); + } + + // LOAD AND SELECT THE FONT + if (!LoadFont()) + return 1; + + // CREATE THE S-CODE STREAM AND EXECUTE DATA + if (!SCodeCompile(TEXT("1 B=S D=TB"), + TEXT("4 W=S A1=W1 B1=W2 W1=TA W2=TB A1=W3 B1=W4 W3=TA W4=TB D=W"), + NULL, + 64, + SCODE_CF_AUTOALIGNDWORD, + &scodestream)) + return 1; + ZeroMemory(&scodeexec,sizeof(SCODEEXECUTEDATA)); + scodeexec.size = sizeof(SCODEEXECUTEDATA); + scodeexec.xiterations = 40; + scodeexec.yiterations = 40; + scodeexec.source = bitmapbits; + + // REGISTER MESSAGE HANDLERS AND SET THE TIMER + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + + // RUN THE MESSAGE LOOP + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.CS b/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.EXE b/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.EXE new file mode 100644 index 0000000..58acedb Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT5/LIGHT5.EXE differ diff --git a/Storm/SAMPLES/SCODE/LIGHT5/TEST.PCX b/Storm/SAMPLES/SCODE/LIGHT5/TEST.PCX new file mode 100644 index 0000000..5421a7d Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIGHT5/TEST.PCX differ diff --git a/Storm/SAMPLES/SCODE/LIST/LIST.CPP b/Storm/SAMPLES/SCODE/LIST/LIST.CPP new file mode 100644 index 0000000..53ebfc1 --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIST/LIST.CPP @@ -0,0 +1,42 @@ +/**************************************************************************** +* +* LIST.CPP +* +* This simple command line program can be used to check an S-code string for +* errors, and to list pseudocode for the compiled string. +* +***/ + +#include +#include +#include + +int __cdecl main () { + + // GET THE S-CODE STRING + printf("Enter S-code string: "); + char scodestring[256]; + gets(scodestring); + printf("\n"); + + // DO A TEST COMPILE TO CHECK FOR ERRORS + { + HSCODESTREAM handle; + const char *firsterror = NULL; + if (SCodeCompile(NULL,scodestring,&firsterror,1,0,&handle)) + SCodeDelete(handle); + else if (firsterror) { + printf("%s\n%*s^\n",scodestring,firsterror-scodestring,""); + return 0; + } + } + + // COMPILE IT INTO PSEUDOCODE AND LIST THE PSEUDOCODE + { + char buffer[1024] = ""; + SCodeGetPseudocode(scodestring,buffer,1024); + printf("%s\n",buffer); + } + + return 0; +} diff --git a/Storm/SAMPLES/SCODE/LIST/LIST.CS b/Storm/SAMPLES/SCODE/LIST/LIST.CS new file mode 100644 index 0000000..c4f052a --- /dev/null +++ b/Storm/SAMPLES/SCODE/LIST/LIST.CS @@ -0,0 +1,2 @@ +#include "..\..\sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/SCODE/LIST/LIST.EXE b/Storm/SAMPLES/SCODE/LIST/LIST.EXE new file mode 100644 index 0000000..0c45127 Binary files /dev/null and b/Storm/SAMPLES/SCODE/LIST/LIST.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.CPP b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.CPP new file mode 100644 index 0000000..b28b1a0 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.CPP @@ -0,0 +1,72 @@ +/**************************************************************************** +* +* DLGEX1.CPP +* +* Creates a dialog box using the normal Windows dialog manager. +* +* The dialog looks functional enough, but there are some not-so-obvious +* problems using it in a DirectDraw game: +* +* 1. The dialog automatically adjusts itself to the display device's font +* size and pixels-per-inch ratio. This is a nice feature for normal +* Windows applications, but problematic for games that want their glue +* screens to always exactly fill the screen. +* +* 2. The dialog also displays itself using the system's currently selected +* color scheme and metrics. This, again, reduces the ability of the +* application to control exactly how its glue screens look. +* +* 3. It is difficult to customize the look of Windows dialog boxes. There +* is no support for background bitmaps or button textures. +* +* 4. Windows' dialog manager is not well integrated with DirectDraw. For +* example, if you alt+tab away from the application while the dialog is +* on the screen, you will never be able to switch back. +* +***/ + +#define STRICT +#include +#include +#include "resource.h" + +//=========================================================================== +BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_COMMAND: + switch (LOWORD(wparam)) { + + case IDOK: + EndDialog(window,1); + break; + + case IDCANCEL: + EndDialog(window,0); + break; + + } + break; + + case WM_INITDIALOG: + return 1; + + } + return 0; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DLGEX1"), + TEXT("Dialog Example 1"))) + return 1; + DialogBox(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + SDrawGetFrameWindow(), + DlgProc); + return 0; +} diff --git a/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.CS b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.EXE b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.EXE new file mode 100644 index 0000000..30dcb6f Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.RC b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.RC new file mode 100644 index 0000000..492c4b8 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX1/DLGEX1.RC @@ -0,0 +1,97 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SDLG/DLGEX1/RESOURCE.H b/Storm/SAMPLES/SDLG/DLGEX1/RESOURCE.H new file mode 100644 index 0000000..952cb72 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX1/RESOURCE.H @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dlgex1.rc +// +#define IDD_DIALOG1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.CPP b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.CPP new file mode 100644 index 0000000..dc1cafb --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.CPP @@ -0,0 +1,60 @@ +/**************************************************************************** +* +* DLGEX2.CPP +* +* This sample displays the same dialog as DLGEX1, but now using Storm's +* dialog manager instead of Windows'. +* +* No changes were required to the dialog resource. The only changes +* required in the program itself were changing Windows API calls to +* Storm equivalents (i.e. prepending everything with "SDlg") and making +* the dialog box procedure call SDlgDefDialogProc() instead of returning +* zero. +* +***/ + +#define STRICT +#include +#include +#include "resource.h" + +//=========================================================================== +BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_COMMAND: + switch (LOWORD(wparam)) { + + case IDOK: + SDlgEndDialog(window,1); + break; + + case IDCANCEL: + SDlgEndDialog(window,0); + break; + + } + break; + + case WM_INITDIALOG: + return 1; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DLGEX2"), + TEXT("Dialog Example 2"))) + return 1; + SDlgDialogBox(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + SDrawGetFrameWindow(), + DlgProc); + return 0; +} diff --git a/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.CS b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.EXE b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.EXE new file mode 100644 index 0000000..ca1edac Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.RC b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.RC new file mode 100644 index 0000000..492c4b8 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX2/DLGEX2.RC @@ -0,0 +1,97 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SDLG/DLGEX2/RESOURCE.H b/Storm/SAMPLES/SDLG/DLGEX2/RESOURCE.H new file mode 100644 index 0000000..19f6760 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX2/RESOURCE.H @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dlgex2.rc +// +#define IDD_DIALOG1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SDLG/DLGEX3/BKG1.PCX b/Storm/SAMPLES/SDLG/DLGEX3/BKG1.PCX new file mode 100644 index 0000000..539db54 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX3/BKG1.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.CPP b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.CPP new file mode 100644 index 0000000..8f1fb00 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.CPP @@ -0,0 +1,95 @@ +/**************************************************************************** +* +* DLGEX3.CPP +* +* Demonstrates the use of background bitmaps. +* +* This sample displays the same simple dialog box again. However, it +* has been modified to use a background bitmap. It loads the bitmap from +* disk during the WM_INITDIALOG message, and registers it with Storm's +* dialog manager. It frees the bitmap on WM_DESTROY. +* +***/ + +#define STRICT +#include +#include +#include "resource.h" + +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height); + +//=========================================================================== +BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + static LPBYTE backgroundbitmap = NULL; + switch (message) { + + case WM_COMMAND: + switch (LOWORD(wparam)) { + + case IDOK: + SDlgEndDialog(window,1); + break; + + case IDCANCEL: + SDlgEndDialog(window,0); + break; + + } + break; + + case WM_DESTROY: + if (backgroundbitmap) { + FREE(backgroundbitmap); + backgroundbitmap = NULL; + } + break; + + case WM_INITDIALOG: + { + int width, height; + backgroundbitmap = LoadBitmap(TEXT("bkg1.pcx"),&width,&height); + if (backgroundbitmap) + SDlgSetBitmap(window, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + } + return 1; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height) { + if (!SBmpLoadImage(filename,NULL,NULL,0,width,height)) + return NULL; + LPBYTE bitmapbits = (LPBYTE)ALLOC((*width)*(*height)); + if (!bitmapbits) + return NULL; + PALETTEENTRY pe[256]; + if (SBmpLoadImage(filename,&pe[0],bitmapbits,(*width)*(*height))) + SDrawUpdatePalette(10,236,&pe[10]); + return bitmapbits; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DLGEX3"), + TEXT("Dialog Example 3"))) + return 1; + SDlgDialogBox(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + SDrawGetFrameWindow(), + DlgProc); + return 0; +} diff --git a/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.CS b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.EXE b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.EXE new file mode 100644 index 0000000..13e73fa Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.RC b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.RC new file mode 100644 index 0000000..492c4b8 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX3/DLGEX3.RC @@ -0,0 +1,97 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SDLG/DLGEX3/RESOURCE.H b/Storm/SAMPLES/SDLG/DLGEX3/RESOURCE.H new file mode 100644 index 0000000..ce4d1a3 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX3/RESOURCE.H @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dlgex3.rc +// +#define IDD_DIALOG1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SDLG/DLGEX4/BKG1.PCX b/Storm/SAMPLES/SDLG/DLGEX4/BKG1.PCX new file mode 100644 index 0000000..539db54 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX4/BKG1.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX4/BKG2.PCX b/Storm/SAMPLES/SDLG/DLGEX4/BKG2.PCX new file mode 100644 index 0000000..37352b0 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX4/BKG2.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX4/BKG3.PCX b/Storm/SAMPLES/SDLG/DLGEX4/BKG3.PCX new file mode 100644 index 0000000..105d203 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX4/BKG3.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX4/BKG4.PCX b/Storm/SAMPLES/SDLG/DLGEX4/BKG4.PCX new file mode 100644 index 0000000..f69bfd2 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX4/BKG4.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.CPP b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.CPP new file mode 100644 index 0000000..38b1cd9 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.CPP @@ -0,0 +1,118 @@ +/**************************************************************************** +* +* DLGEX4.CPP +* +* Demonstrates multiple overlapping dialog boxes. +* +* The dialog box has been given a new button, named "Create...", which +* creates a child dialog. The dialogs all share a common dialog box +* procedure, but each has a different background bitmap. Since each dialog +* box must have a unique pointer to its bitmap data, the pointers are now +* kept as window properties rather than static variables. +* +***/ + +#define STRICT +#include +#include +#include "resource.h" + +HINSTANCE instance = (HINSTANCE)0; + +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height); + +//=========================================================================== +BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_COMMAND: + switch (LOWORD(wparam)) { + + case IDOK: + SDlgEndDialog(window,1); + break; + + case IDCANCEL: + SDlgEndDialog(window,0); + break; + + case IDC_BUTTON1: + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + window, + DlgProc, + (LPARAM)GetProp(window,TEXT("RecursionDepth"))+1); + break; + + } + break; + + case WM_DESTROY: + if (GetProp(window,TEXT("BackgroundBitmap"))) + FREE((LPVOID)GetProp(window,TEXT("BackgroundBitmap"))); + break; + + case WM_INITDIALOG: + + // SAVE THE RECURSION DEPTH + SetProp(window,TEXT("RecursionDepth"),(HANDLE)lparam); + + // POSITION THE DIALOG BOX ON THE SCREEN + SetWindowPos(window,NULL,lparam*22,lparam*22,0,0,SWP_NOSIZE | SWP_NOZORDER); + + // LOAD THE BACKGROUND BITMAP + { + TCHAR filename[16]; + wsprintf(filename,TEXT("bkg%u.pcx"),(lparam & 3)+1); + int width, height; + LPBYTE backgroundbitmap = LoadBitmap(filename,&width,&height); + if (backgroundbitmap) { + SetProp(window,TEXT("BackgroundBitmap"),(HANDLE)backgroundbitmap); + SDlgSetBitmap(window, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + } + } + + return 1; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height) { + if (!SBmpLoadImage(filename,NULL,NULL,0,width,height)) + return NULL; + LPBYTE bitmapbits = (LPBYTE)ALLOC((*width)*(*height)); + if (!bitmapbits) + return NULL; + PALETTEENTRY pe[256]; + if (SBmpLoadImage(filename,&pe[0],bitmapbits,(*width)*(*height))) + SDrawUpdatePalette(10,236,&pe[10]); + return bitmapbits; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR, int) { + instance = passinstance; + if (!SDrawAutoInitialize(instance, + TEXT("DLGEX4"), + TEXT("Dialog Example 4"))) + return 1; + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + SDrawGetFrameWindow(), + DlgProc, + 0); + return 0; +} diff --git a/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.CS b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.EXE b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.EXE new file mode 100644 index 0000000..0c81ac1 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.RC b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.RC new file mode 100644 index 0000000..b4aab45 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX4/DLGEX4.RC @@ -0,0 +1,98 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + PUSHBUTTON "&Create...",IDC_BUTTON1,129,41,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SDLG/DLGEX4/RESOURCE.H b/Storm/SAMPLES/SDLG/DLGEX4/RESOURCE.H new file mode 100644 index 0000000..7e6877b --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX4/RESOURCE.H @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dlgex4.RC +// +#define IDD_DIALOG1 101 +#define IDC_BUTTON1 1000 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SDLG/DLGEX5/BKG1.PCX b/Storm/SAMPLES/SDLG/DLGEX5/BKG1.PCX new file mode 100644 index 0000000..539db54 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX5/BKG1.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX5/BKG2.PCX b/Storm/SAMPLES/SDLG/DLGEX5/BKG2.PCX new file mode 100644 index 0000000..37352b0 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX5/BKG2.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX5/BKG3.PCX b/Storm/SAMPLES/SDLG/DLGEX5/BKG3.PCX new file mode 100644 index 0000000..105d203 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX5/BKG3.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX5/BKG4.PCX b/Storm/SAMPLES/SDLG/DLGEX5/BKG4.PCX new file mode 100644 index 0000000..f69bfd2 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX5/BKG4.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.CPP b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.CPP new file mode 100644 index 0000000..8e2e16a --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.CPP @@ -0,0 +1,134 @@ +/**************************************************************************** +* +* DLGEX5.CPP +* +* Adds button textures. +* +***/ + +#define STRICT +#include +#include +#include "resource.h" + +HINSTANCE instance = (HINSTANCE)0; + +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height); + +//=========================================================================== +BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_COMMAND: + switch (LOWORD(wparam)) { + + case IDOK: + SDlgEndDialog(window,1); + break; + + case IDCANCEL: + SDlgEndDialog(window,0); + break; + + case IDC_BUTTON1: + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + window, + DlgProc, + (LPARAM)GetProp(window,TEXT("RecursionDepth"))+1); + break; + + } + break; + + case WM_DESTROY: + if (GetProp(window,TEXT("BackgroundBitmap"))) + FREE((LPVOID)GetProp(window,TEXT("BackgroundBitmap"))); + break; + + case WM_INITDIALOG: + + // SAVE THE RECURSION DEPTH + SetProp(window,TEXT("RecursionDepth"),(HANDLE)lparam); + + // POSITION THE DIALOG BOX ON THE SCREEN + SetWindowPos(window,NULL,lparam*22,lparam*22,0,0,SWP_NOSIZE | SWP_NOZORDER); + + // LOAD THE BACKGROUND BITMAP + { + TCHAR filename[16]; + wsprintf(filename,TEXT("bkg%u.pcx"),(lparam & 3)+1); + int width, height; + LPBYTE backgroundbitmap = LoadBitmap(filename,&width,&height); + if (backgroundbitmap) { + SetProp(window,TEXT("BackgroundBitmap"),(HANDLE)backgroundbitmap); + SDlgSetBitmap(window, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + SDlgSetBitmap(NULL, + window, + TEXT("Button"), + SDLG_STYLE_ANYPUSHBUTTON, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + } + } + + return 1; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height) { + if (!SBmpLoadImage(filename,NULL,NULL,0,width,height)) + return NULL; + LPBYTE bitmapbits = (LPBYTE)ALLOC((*width)*(*height)); + if (!bitmapbits) + return NULL; + PALETTEENTRY pe[256]; + if (SBmpLoadImage(filename,&pe[0],bitmapbits,(*width)*(*height))) + SDrawUpdatePalette(10,236,&pe[10]); + return bitmapbits; +} + +//=========================================================================== +void CALLBACK OnEraseBkgnd (LPPARAMS params) { + params->useresult = 1; + params->result = 0; +} + +//=========================================================================== +void CALLBACK OnPaint (LPPARAMS params) { + PAINTSTRUCT ps; + HDC dc = SDlgBeginPaint(params->window,&ps); + SDlgEndPaint(params->window,&ps); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR, int) { + instance = passinstance; + if (!SDrawAutoInitialize(instance, + TEXT("DLGEX5"), + TEXT("Dialog Example 5"))) + return 1; + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + SDrawGetFrameWindow(), + DlgProc, + 0); + return 0; +} diff --git a/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.CS b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.EXE b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.EXE new file mode 100644 index 0000000..994a381 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.RC b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.RC new file mode 100644 index 0000000..b4aab45 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX5/DLGEX5.RC @@ -0,0 +1,98 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + PUSHBUTTON "&Create...",IDC_BUTTON1,129,41,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SDLG/DLGEX5/RESOURCE.H b/Storm/SAMPLES/SDLG/DLGEX5/RESOURCE.H new file mode 100644 index 0000000..342aec3 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX5/RESOURCE.H @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dlgex5.RC +// +#define IDD_DIALOG1 101 +#define IDC_BUTTON1 1000 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SDLG/DLGEX6/BKG.PCX b/Storm/SAMPLES/SDLG/DLGEX6/BKG.PCX new file mode 100644 index 0000000..01568e3 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX6/BKG.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX6/BKG1.PCX b/Storm/SAMPLES/SDLG/DLGEX6/BKG1.PCX new file mode 100644 index 0000000..539db54 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX6/BKG1.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX6/BKG2.PCX b/Storm/SAMPLES/SDLG/DLGEX6/BKG2.PCX new file mode 100644 index 0000000..37352b0 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX6/BKG2.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX6/BKG3.PCX b/Storm/SAMPLES/SDLG/DLGEX6/BKG3.PCX new file mode 100644 index 0000000..105d203 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX6/BKG3.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX6/BKG4.PCX b/Storm/SAMPLES/SDLG/DLGEX6/BKG4.PCX new file mode 100644 index 0000000..f69bfd2 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX6/BKG4.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.CPP b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.CPP new file mode 100644 index 0000000..a746298 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.CPP @@ -0,0 +1,154 @@ +/**************************************************************************** +* +* DLGEX6.CPP +* +* Demonstrates the use of a background bitmap. +* +***/ + +#define STRICT +#include +#include +#include "resource.h" + +HINSTANCE instance = (HINSTANCE)0; + +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height); + +//=========================================================================== +BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_COMMAND: + switch (LOWORD(wparam)) { + + case IDOK: + SDlgEndDialog(window,1); + break; + + case IDCANCEL: + SDlgEndDialog(window,0); + break; + + case IDC_BUTTON1: +Sleep(1000); + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + window, + DlgProc, + (LPARAM)GetProp(window,TEXT("RecursionDepth"))+1); + break; + + } + break; + + case WM_DESTROY: + if (GetProp(window,TEXT("BackgroundBitmap"))) + FREE((LPVOID)GetProp(window,TEXT("BackgroundBitmap"))); + break; + + case WM_INITDIALOG: + + // SAVE THE RECURSION DEPTH + SetProp(window,TEXT("RecursionDepth"),(HANDLE)lparam); + + // POSITION THE DIALOG BOX ON THE SCREEN + SetWindowPos(window,NULL,lparam*22,lparam*22,0,0,SWP_NOSIZE | SWP_NOZORDER); + + // LOAD THE BACKGROUND BITMAP + { + TCHAR filename[16]; + wsprintf(filename,TEXT("bkg%u.pcx"),(lparam & 3)+1); + int width, height; + LPBYTE backgroundbitmap = LoadBitmap(filename,&width,&height); + if (backgroundbitmap) { + SetProp(window,TEXT("BackgroundBitmap"),(HANDLE)backgroundbitmap); + SDlgSetBitmap(window, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + SDlgSetBitmap(NULL, + window, + TEXT("Button"), + SDLG_STYLE_ANYPUSHBUTTON, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + } + } + + return 1; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height) { + if (!SBmpLoadImage(filename,NULL,NULL,0,width,height)) + return NULL; + LPBYTE bitmapbits = (LPBYTE)ALLOC((*width)*(*height)); + if (!bitmapbits) + return NULL; + PALETTEENTRY pe[256]; + if (SBmpLoadImage(filename,&pe[0],bitmapbits,(*width)*(*height))) + SDrawUpdatePalette(10,236,&pe[10]); + return bitmapbits; +} + +//=========================================================================== +void CALLBACK OnEraseBkgnd (LPPARAMS params) { + params->useresult = 1; + params->result = 0; +} + +//=========================================================================== +void CALLBACK OnPaint (LPPARAMS params) { + PAINTSTRUCT ps; + HDC dc = SDlgBeginPaint(params->window,&ps); + SDlgEndPaint(params->window,&ps); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR, int) { + instance = passinstance; + if (!SDrawAutoInitialize(instance, + TEXT("DLGEX6"), + TEXT("Dialog Example 6"))) + return 1; + { + int width, height; + LPBYTE backgroundbitmap = LoadBitmap(TEXT("bkg.pcx"),&width,&height); + if (backgroundbitmap) { + SMsgRegisterMessage(NULL,WM_ERASEBKGND,OnEraseBkgnd); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SDlgSetBitmap(SDrawGetFrameWindow(), + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + } + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + SDrawGetFrameWindow(), + DlgProc, + 0); + if (backgroundbitmap) + FREE(backgroundbitmap); + } + return 0; +} diff --git a/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.CS b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.EXE b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.EXE new file mode 100644 index 0000000..83784bf Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.RC b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.RC new file mode 100644 index 0000000..b4aab45 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX6/DLGEX6.RC @@ -0,0 +1,98 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + PUSHBUTTON "&Create...",IDC_BUTTON1,129,41,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SDLG/DLGEX6/RESOURCE.H b/Storm/SAMPLES/SDLG/DLGEX6/RESOURCE.H new file mode 100644 index 0000000..9921dd2 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX6/RESOURCE.H @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dlgex6.RC +// +#define IDD_DIALOG1 101 +#define IDC_BUTTON1 1000 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SDLG/DLGEX7/BKG.PCX b/Storm/SAMPLES/SDLG/DLGEX7/BKG.PCX new file mode 100644 index 0000000..01568e3 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/BKG.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/BKG1.PCX b/Storm/SAMPLES/SDLG/DLGEX7/BKG1.PCX new file mode 100644 index 0000000..539db54 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/BKG1.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/BKG2.PCX b/Storm/SAMPLES/SDLG/DLGEX7/BKG2.PCX new file mode 100644 index 0000000..37352b0 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/BKG2.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/BKG3.PCX b/Storm/SAMPLES/SDLG/DLGEX7/BKG3.PCX new file mode 100644 index 0000000..105d203 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/BKG3.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/BKG4.PCX b/Storm/SAMPLES/SDLG/DLGEX7/BKG4.PCX new file mode 100644 index 0000000..f69bfd2 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/BKG4.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/CIMAGE.BMP b/Storm/SAMPLES/SDLG/DLGEX7/CIMAGE.BMP new file mode 100644 index 0000000..b4d02b6 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/CIMAGE.BMP differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/CIMAGE.PCX b/Storm/SAMPLES/SDLG/DLGEX7/CIMAGE.PCX new file mode 100644 index 0000000..7db4b97 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/CIMAGE.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/CMASK.BMP b/Storm/SAMPLES/SDLG/DLGEX7/CMASK.BMP new file mode 100644 index 0000000..23c7b10 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/CMASK.BMP differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/CMASK.PCX b/Storm/SAMPLES/SDLG/DLGEX7/CMASK.PCX new file mode 100644 index 0000000..f0ced17 Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/CMASK.PCX differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.CPP b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.CPP new file mode 100644 index 0000000..ad5cf0f --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.CPP @@ -0,0 +1,163 @@ +/**************************************************************************** +* +* DLGEX7.CPP +* +* Demonstrates the use of a cursor. +* +***/ + +#define STRICT +#include +#include +#include "resource.h" + +HINSTANCE instance = (HINSTANCE)0; + +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height); + +//=========================================================================== +BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_COMMAND: + switch (LOWORD(wparam)) { + + case IDOK: + SDlgEndDialog(window,1); + break; + + case IDCANCEL: + SDlgEndDialog(window,0); + break; + + case IDC_BUTTON1: + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + window, + DlgProc, + (LPARAM)GetProp(window,TEXT("RecursionDepth"))+1); + break; + + } + break; + + case WM_DESTROY: + if (GetProp(window,TEXT("BackgroundBitmap"))) + FREE((LPVOID)GetProp(window,TEXT("BackgroundBitmap"))); + break; + + case WM_INITDIALOG: + + // SAVE THE RECURSION DEPTH + SetProp(window,TEXT("RecursionDepth"),(HANDLE)lparam); + + // POSITION THE DIALOG BOX ON THE SCREEN + SetWindowPos(window,NULL,lparam*22,lparam*22,0,0,SWP_NOSIZE | SWP_NOZORDER); + + // LOAD THE BACKGROUND BITMAP + { + TCHAR filename[16]; + wsprintf(filename,TEXT("bkg%u.pcx"),(lparam & 3)+1); + int width, height; + LPBYTE backgroundbitmap = LoadBitmap(filename,&width,&height); + if (backgroundbitmap) { + SetProp(window,TEXT("BackgroundBitmap"),(HANDLE)backgroundbitmap); + SDlgSetBitmap(window, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + SDlgSetBitmap(NULL, + window, + TEXT("Button"), + SDLG_STYLE_ANYPUSHBUTTON, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + } + } + + return 1; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +LPBYTE LoadBitmap (LPCTSTR filename, int *width, int *height) { + if (!SBmpLoadImage(filename,NULL,NULL,0,width,height)) + return NULL; + LPBYTE bitmapbits = (LPBYTE)ALLOC((*width)*(*height)); + if (!bitmapbits) + return NULL; + PALETTEENTRY pe[256]; + if (SBmpLoadImage(filename,&pe[0],bitmapbits,(*width)*(*height))) + SDrawUpdatePalette(10,236,&pe[10]); + return bitmapbits; +} + +//=========================================================================== +void CALLBACK OnEraseBkgnd (LPPARAMS params) { + params->useresult = 1; + params->result = 0; +} + +//=========================================================================== +void CALLBACK OnPaint (LPPARAMS params) { + PAINTSTRUCT ps; + HDC dc = SDlgBeginPaint(params->window,&ps); + SDlgEndPaint(params->window,&ps); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR, int) { + instance = passinstance; + if (!SDrawAutoInitialize(instance, + TEXT("DLGEX7"), + TEXT("Dialog Example 7"))) + return 1; + ShowCursor(0); + { + int width, height; + LPBYTE backgroundbitmap = LoadBitmap(TEXT("bkg.pcx"),&width,&height); + if (backgroundbitmap) { + SMsgRegisterMessage(NULL,WM_ERASEBKGND,OnEraseBkgnd); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SDlgSetBitmap(SDrawGetFrameWindow(), + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + backgroundbitmap, + NULL, + width, + height); + } + SIZE cursorsize; + LPBYTE maskbitmap = LoadBitmap(TEXT("cmask.bmp") ,(int *)&cursorsize.cx,(int *)&cursorsize.cy); + LPBYTE imagebitmap = LoadBitmap(TEXT("cimage.bmp"),(int *)&cursorsize.cx,(int *)&cursorsize.cy); + SDlgSetSystemCursor(maskbitmap,imagebitmap,&cursorsize); + SDlgDialogBoxParam(instance, + MAKEINTRESOURCE(IDD_DIALOG1), + SDrawGetFrameWindow(), + DlgProc, + 0); + if (backgroundbitmap) + FREE(backgroundbitmap); + if (maskbitmap) + FREE(maskbitmap); + if (imagebitmap) + FREE(imagebitmap); + } + ShowCursor(1); + return 0; +} diff --git a/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.CS b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.EXE b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.EXE new file mode 100644 index 0000000..d3e150d Binary files /dev/null and b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.EXE differ diff --git a/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.RC b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.RC new file mode 100644 index 0000000..b4aab45 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX7/DLGEX7.RC @@ -0,0 +1,98 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + PUSHBUTTON "&Create...",IDC_BUTTON1,129,41,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SDLG/DLGEX7/RESOURCE.H b/Storm/SAMPLES/SDLG/DLGEX7/RESOURCE.H new file mode 100644 index 0000000..9921dd2 --- /dev/null +++ b/Storm/SAMPLES/SDLG/DLGEX7/RESOURCE.H @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dlgex6.RC +// +#define IDD_DIALOG1 101 +#define IDC_BUTTON1 1000 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.CPP b/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.CPP new file mode 100644 index 0000000..41f7b91 --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.CPP @@ -0,0 +1,63 @@ +/**************************************************************************** +* +* DDEX1.CPP +* +* This simple DirectDraw application loads a bitmap and draws it on the +* screen. +* +***/ + +#include +#include + +LPBYTE backgroundbitmap = NULL; +int backgroundwidth = 0; +int backgroundheight = 0; + +//=========================================================================== +BOOL LoadBackgroundBitmap () { + if (!SBmpLoadImage("..\\demodata\\flag.pcx",NULL,NULL,NULL,&backgroundwidth,&backgroundheight)) + return 0; + backgroundbitmap = (LPBYTE)ALLOC(backgroundwidth*backgroundheight); + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\flag.pcx",&pe[0],backgroundbitmap,backgroundwidth*backgroundheight)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbitmap); +} + +//=========================================================================== +void CALLBACK OnPaint (LPPARAMS) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + SGdiRectangle(videobuffer,0,0,639,479,PALETTEINDEX(255)); + SGdiBitBlt(videobuffer,0,0,backgroundbitmap,NULL,backgroundwidth,backgroundheight); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DDEX1"), + TEXT("DirectDraw Example 1"))) + FATALRESULT("SDrawAutoInitialize"); + if (!LoadBackgroundBitmap()) + FATALRESULT("LoadBackgroundBitmap"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(NULL); +} diff --git a/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.CS b/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.EXE b/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.EXE new file mode 100644 index 0000000..9b2b3e8 Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DDEX1/DDEX1.EXE differ diff --git a/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.CPP b/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.CPP new file mode 100644 index 0000000..8b55eca --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.CPP @@ -0,0 +1,67 @@ +/**************************************************************************** +* +* DDEX2.CPP +* +* This sample application loads a bitmap and repeatedly tiles it onto the +* screen, changing the tiling offset each frame. +* +***/ + +#include +#include + +LPBYTE backgroundbitmap = NULL; +int backgroundwidth = 0; +int backgroundheight = 0; +int tilingoffset = 0; + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + RECT destrect = {0,0,639,479}; + RECT sourcerect = {0,0,backgroundwidth-1,backgroundheight-1}; + SBltROP3Tiled(videobuffer,&destrect,pitch, + backgroundbitmap,&sourcerect,backgroundwidth, + tilingoffset,tilingoffset,0,SRCCOPY); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + tilingoffset += 4; + return 1; +} + +//=========================================================================== +BOOL LoadBackgroundBitmap () { + if (!SBmpLoadImage("..\\demodata\\flag.pcx",NULL,NULL,NULL,&backgroundwidth,&backgroundheight)) + return 0; + backgroundbitmap = (LPBYTE)ALLOC(backgroundwidth*backgroundheight); + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\flag.pcx",&pe[0],backgroundbitmap,backgroundwidth*backgroundheight)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbitmap); +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DDEX2"), + TEXT("DirectDraw Example 2"))) + FATALRESULT("SDrawAutoInitialize"); + if (!LoadBackgroundBitmap()) + FATALRESULT("LoadBackgroundBitmap"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.CS b/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.EXE b/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.EXE new file mode 100644 index 0000000..1f5c71d Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DDEX2/DDEX2.EXE differ diff --git a/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.CPP b/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.CPP new file mode 100644 index 0000000..322dfa1 --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.CPP @@ -0,0 +1,119 @@ +/**************************************************************************** +* +* DDEX3.CPP +* +* This sample application demonstrates the use of transparent bitmaps. +* For each frame, the application performs the following steps: +* +* 1. Draws the background on an offscreen video page +* 2. Overlays transparent bitmaps onto the background +* 3. Flips the video page +* +* The use of page flipping prevents tearing. +* +***/ + +#include +#include +#include + +#define SPRITES 4 + +#define SIN(a) sintable[((a) & 255)] +#define COS(a) sintable[(((a)+64) & 255)] + +LPBYTE backgroundbitmap = NULL; +int backgroundwidth = 0; +int backgroundheight = 0; +BYTE rotation = 0; +int sintable[256]; +HSTRANS sprite[SPRITES] = {0,0,0,0}; +int tilingoffset = 0; + +//=========================================================================== +void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_BACK,NULL,&videobuffer,&pitch)) { + RECT destrect = {0,0,639,479}; + RECT sourcerect = {0,0,backgroundwidth-1,backgroundheight-1}; + SBltROP3Tiled(videobuffer,&destrect,pitch, + backgroundbitmap,&sourcerect,backgroundwidth, + tilingoffset,tilingoffset,0,SRCCOPY); + for (int loop = 0; loop < SPRITES; ++loop) + STransBlt(videobuffer, + 170+SIN(rotation+64*loop), + 165+COS(rotation+64*loop), + pitch, + sprite[loop]); + SDrawUnlockSurface(SDRAW_SURFACE_BACK,videobuffer); + SDrawFlipPage(); + } + rotation += 3; + tilingoffset += 8; + return 1; +} + +//=========================================================================== +BOOL LoadBackgroundBitmap () { + if (!SBmpLoadImage("..\\demodata\\flag.pcx",NULL,NULL,NULL,&backgroundwidth,&backgroundheight)) + return 0; + backgroundbitmap = (LPBYTE)ALLOC(backgroundwidth*backgroundheight); + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\flag.pcx",&pe[0],backgroundbitmap,backgroundwidth*backgroundheight)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +BOOL LoadSprites () { + LPBYTE temp = (LPBYTE)ALLOC(300*500); + if (!SBmpLoadImage("..\\demodata\\sprites.pcx",NULL,temp,300*500)) + return 0; + for (int loop = 0; loop < SPRITES; ++loop) { + RECT rect = {0,loop*125,299,loop*125+124}; + if (!STransCreate(temp,300,500,8,&rect,PALETTEINDEX(*temp),&sprite[loop])) + return 0; + } + FREE(temp); + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbitmap); + for (int loop = 0; loop < SPRITES; ++loop) + STransDelete(sprite[loop]); +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + TEXT("DDEX3"), + TEXT("DirectDraw Example 3"), + NULL, + SDRAW_SERVICE_PAGEFLIP)) + FATALRESULT("SDrawAutoInitialize"); + if (!LoadBackgroundBitmap()) + FATALRESULT("LoadBackgroundBitmap"); + if (!LoadSprites()) + FATALRESULT("LoadSprites"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.CS b/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.EXE b/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.EXE new file mode 100644 index 0000000..ccde142 Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DDEX3/DDEX3.EXE differ diff --git a/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.CPP b/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.CPP new file mode 100644 index 0000000..107bdd6 --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.CPP @@ -0,0 +1,116 @@ +/**************************************************************************** +* +* DDEX4.CPP +* +* This sample application produces the same output as DDEX3, but it goes +* about it a different way. Instead of drawing to an offscreen page and +* then page flipping, it draws into system memory and the blts the entire +* screen at once onto video memory. This allows it to work on video cards +* that don't support page flipping in high-res mode. +* +***/ + +#include +#include +#include + +#define SPRITES 4 + +#define SIN(a) sintable[((a) & 255)] +#define COS(a) sintable[(((a)+64) & 255)] + +LPBYTE backgroundbitmap = NULL; +int backgroundwidth = 0; +int backgroundheight = 0; +BYTE rotation = 0; +int sintable[256]; +HSTRANS sprite[SPRITES] = {0,0,0,0}; +int tilingoffset = 0; + +//=========================================================================== +void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + sintable[loop] = (int)(sin(angle)*128); + } +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + LPBYTE systembuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_SYSTEM,NULL,&systembuffer,&pitch)) { + RECT destrect = {0,0,639,479}; + RECT sourcerect = {0,0,backgroundwidth-1,backgroundheight-1}; + SBltROP3Tiled(systembuffer,&destrect,pitch, + backgroundbitmap,&sourcerect,backgroundwidth, + tilingoffset,tilingoffset,0,SRCCOPY); + for (int loop = 0; loop < SPRITES; ++loop) + STransBlt(systembuffer, + 170+SIN(rotation+64*loop), + 165+COS(rotation+64*loop), + pitch, + sprite[loop]); + SDrawUnlockSurface(SDRAW_SURFACE_SYSTEM,systembuffer); + SDrawUpdateScreen(NULL); + } + rotation += 3; + tilingoffset += 8; + return 1; +} + +//=========================================================================== +BOOL LoadBackgroundBitmap () { + if (!SBmpLoadImage("..\\demodata\\flag.pcx",NULL,NULL,NULL,&backgroundwidth,&backgroundheight)) + return 0; + backgroundbitmap = (LPBYTE)ALLOC(backgroundwidth*backgroundheight); + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("..\\demodata\\flag.pcx",&pe[0],backgroundbitmap,backgroundwidth*backgroundheight)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + return 1; +} + +//=========================================================================== +BOOL LoadSprites () { + LPBYTE temp = (LPBYTE)ALLOC(300*500); + if (!SBmpLoadImage("..\\demodata\\sprites.pcx",NULL,temp,300*500)) + return 0; + for (int loop = 0; loop < SPRITES; ++loop) { + RECT rect = {0,loop*125,299,loop*125+124}; + if (!STransCreate(temp,300,500,8,&rect,PALETTEINDEX(*temp),&sprite[loop])) + return 0; + } + FREE(temp); + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS) { + FREE(backgroundbitmap); + for (int loop = 0; loop < SPRITES; ++loop) + STransDelete(sprite[loop]); +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + CreateSinTable(); + if (!SDrawAutoInitialize(instance, + TEXT("DDEX4"), + TEXT("DirectDraw Example 4"), + NULL, + SDRAW_SERVICE_DOUBLEBUFFER)) + FATALRESULT("SDrawAutoInitialize"); + if (!LoadBackgroundBitmap()) + FATALRESULT("LoadBackgroundBitmap"); + if (!LoadSprites()) + FATALRESULT("LoadSprites"); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.CS b/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.EXE b/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.EXE new file mode 100644 index 0000000..91dc91d Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DDEX4/DDEX4.EXE differ diff --git a/Storm/SAMPLES/SDRAW/DEMODATA/BKG.PCX b/Storm/SAMPLES/SDRAW/DEMODATA/BKG.PCX new file mode 100644 index 0000000..d24cdf1 Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DEMODATA/BKG.PCX differ diff --git a/Storm/SAMPLES/SDRAW/DEMODATA/FLAG.PCX b/Storm/SAMPLES/SDRAW/DEMODATA/FLAG.PCX new file mode 100644 index 0000000..c83f1b4 Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DEMODATA/FLAG.PCX differ diff --git a/Storm/SAMPLES/SDRAW/DEMODATA/OVERLAY.PCX b/Storm/SAMPLES/SDRAW/DEMODATA/OVERLAY.PCX new file mode 100644 index 0000000..e9a3e67 Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DEMODATA/OVERLAY.PCX differ diff --git a/Storm/SAMPLES/SDRAW/DEMODATA/SHIPS.PCX b/Storm/SAMPLES/SDRAW/DEMODATA/SHIPS.PCX new file mode 100644 index 0000000..3fc7727 Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DEMODATA/SHIPS.PCX differ diff --git a/Storm/SAMPLES/SDRAW/DEMODATA/SPRITES.PCX b/Storm/SAMPLES/SDRAW/DEMODATA/SPRITES.PCX new file mode 100644 index 0000000..f9dc3e2 Binary files /dev/null and b/Storm/SAMPLES/SDRAW/DEMODATA/SPRITES.PCX differ diff --git a/Storm/SAMPLES/SFILE/DDATEST/CDROM.PCX b/Storm/SAMPLES/SFILE/DDATEST/CDROM.PCX new file mode 100644 index 0000000..796c571 Binary files /dev/null and b/Storm/SAMPLES/SFILE/DDATEST/CDROM.PCX differ diff --git a/Storm/SAMPLES/SFILE/DDATEST/DDATEST.CPP b/Storm/SAMPLES/SFILE/DDATEST/DDATEST.CPP new file mode 100644 index 0000000..6380e30 --- /dev/null +++ b/Storm/SAMPLES/SFILE/DDATEST/DDATEST.CPP @@ -0,0 +1,250 @@ +/**************************************************************************** +* +* DDATEST.CPP +* +* This sample program demonstrates the use of direct digital audio streaming +* from a CD. +* +***/ + +#include +#include +#include + +#define ARCHIVE "e:\\diabdat.mpq" +#define SONGS 6 +#define TITLE "DDA Test" + +static const LPCSTR songname[SONGS] = {"sfx\\towners\\drunk25.wav", + "sfx\\towners\\witch40.wav", + "sfx\\towners\\bsmith47.wav", + "sfx\\towners\\healer39.wav", + "sfx\\towners\\wound01.wav", + "sfx\\towners\\deadguy2.wav"}; + +HSARCHIVE archive = (HSARCHIVE)0; +DWORD currsong = SONGS-1; +HSGDIFONT font = (HSGDIFONT)0; +DWORD iterations = 0; +LPDIRECTSOUND lpds = NULL; +HSFILE soundfile[SONGS] = {0}; +HSTRANS transparency = (HSTRANS)0; + +//=========================================================================== +BOOL LoadTransparency () { + LPBYTE bitmap = (LPBYTE)ALLOC(32*32); + if (!bitmap) + return 0; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("cdrom.pcx",&pe[0],bitmap,32*32)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + STransCreate(bitmap,32,32,8,NULL,PALETTEINDEX(*bitmap),&transparency); + FREE(bitmap); + return 1; +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 640)-20; + int top = (rand() % 420)+30; +#ifdef ALIGNED + left = (left >> 2) << 2; +#endif + STransBlt(videobuffer,left,top,pitch,transparency); + ++iterations; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL InitializeDirectSound () { + + // CREATE A DIRECTSOUND OBJECT + DirectSoundCreate(NULL,&lpds,NULL); + if (!lpds) + return 0; + + // CREATE A PRIMARY BUFFER + LPDIRECTSOUNDBUFFER primarybuffer = NULL; + { + DSBUFFERDESC desc; + ZeroMemory(&desc,sizeof(DSBUFFERDESC)); + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = DSBCAPS_PRIMARYBUFFER; + lpds->CreateSoundBuffer(&desc,&primarybuffer,NULL); + } + if (!primarybuffer) + return 0; + + // START PLAYING THE PRIMARY BUFFER + if (lpds->SetCooperativeLevel(SDrawGetFrameWindow(),DSSCL_EXCLUSIVE) != DS_OK) + return 0; + if (primarybuffer->Play(0,0,DSBPLAY_LOOPING) != DS_OK) + return 0; + + // GIVE OUR DIRECTSOUND POINTER TO STORM + SFileDdaInitialize(lpds); + + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + KillTimer(params->window,1); + SGdiDeleteObject(font); + STransDelete(transparency); + SFileCloseArchive(archive); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + + { + char outstr[64]; + wsprintf(outstr,"%u transparent bitblts per second",iterations); + RECT rect = {0,0,320,15}; + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + } + + if (soundfile[currsong]) { + DWORD position; + DWORD maxposition; + char outstr[64] = ""; + if (SFileDdaGetPos(soundfile[currsong],&position,&maxposition)) + wsprintf(outstr,"%u%% complete",position*100/maxposition); + RECT rect = {320,0,639,15}; + SGdiExtTextOut(videobuffer, + 320, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + } + + SGdiTextOut(videobuffer, 0,10,PALETTEINDEX(255),"[S] Start DDA playback"); + SGdiTextOut(videobuffer, 0,20,PALETTEINDEX(255),"[X] Terminate DDA playback"); + SGdiTextOut(videobuffer,320,10,PALETTEINDEX(255),"[L] Left [C] Center [R] Right"); + SGdiTextOut(videobuffer,320,20,PALETTEINDEX(255),"[Q] Toggle Quiet Mode"); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + iterations = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkC (LPPARAMS) { + SFileDdaSetVolume(soundfile[currsong],0x7FFFFFFF,0); +} + +//=========================================================================== +void CALLBACK OnVkL (LPPARAMS) { + SFileDdaSetVolume(soundfile[currsong],0x7FFFFFFF,10000); +} + +//=========================================================================== +void CALLBACK OnVkQ (LPPARAMS) { + LONG volume; + SFileDdaGetVolume(soundfile[currsong],&volume,NULL); + SFileDdaSetVolume(soundfile[currsong],volume ? 0 : -2000,0x7FFFFFFF); +} + +//=========================================================================== +void CALLBACK OnVkR (LPPARAMS) { + SFileDdaSetVolume(soundfile[currsong],0x7FFFFFFF,-10000); +} + +//=========================================================================== +void CALLBACK OnVkS (LPPARAMS) { + currsong = (currsong+1) % SONGS; + if (!soundfile[currsong]) + SFileOpenFile(songname[currsong],&soundfile[currsong]); + if (soundfile[currsong]) + if (!SFileDdaBegin(soundfile[currsong],0x40000,0)) { + SFileCloseFile(soundfile[currsong]); + soundfile[currsong] = (HSFILE)0; + } +} + + +//=========================================================================== +void CALLBACK OnVkX (LPPARAMS) { + if (soundfile[currsong]) + SFileDdaEnd(soundfile[currsong]); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DDATEST"), + TITLE)) { + SDrawMessageBox("Unable to initialize DirectDraw.",TITLE,0); + return 1; + } + if (!InitializeDirectSound()) { + SDrawMessageBox("Unable to initialize DirectSound.",TITLE,0); + return 1; + } + if (!SFileOpenArchive(ARCHIVE,0,0,&archive)) { + SDrawMessageBox("Unable to open MPQ data file.",TITLE,0); + return 0; + } + SFileEnableDirectAccess(1); + if (!LoadTransparency()) { + SDrawMessageBox("Unable to load transparency.",TITLE,0); + return 1; + } + if (!LoadFont()) { + SDrawMessageBox("Unable to load font.",TITLE,0); + return 1; + } + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,'C' ,OnVkC); + SMsgRegisterKeyDown(NULL,'L' ,OnVkL); + SMsgRegisterKeyDown(NULL,'Q' ,OnVkQ); + SMsgRegisterKeyDown(NULL,'R' ,OnVkR); + SMsgRegisterKeyDown(NULL,'S' ,OnVkS); + SMsgRegisterKeyDown(NULL,'X' ,OnVkX); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SFILE/DDATEST/DDATEST.CS b/Storm/SAMPLES/SFILE/DDATEST/DDATEST.CS new file mode 100644 index 0000000..cbe1fed --- /dev/null +++ b/Storm/SAMPLES/SFILE/DDATEST/DDATEST.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set extralib=%extralib% dsound.lib diff --git a/Storm/SAMPLES/SFILE/DDATEST/DDATEST.EXE b/Storm/SAMPLES/SFILE/DDATEST/DDATEST.EXE new file mode 100644 index 0000000..2a34b84 Binary files /dev/null and b/Storm/SAMPLES/SFILE/DDATEST/DDATEST.EXE differ diff --git a/Storm/SAMPLES/SGDI/RECT/RECT.CPP b/Storm/SAMPLES/SGDI/RECT/RECT.CPP new file mode 100644 index 0000000..3104f15 --- /dev/null +++ b/Storm/SAMPLES/SGDI/RECT/RECT.CPP @@ -0,0 +1,110 @@ +/**************************************************************************** +* +* RECT.CPP +* +* Benchmarks Storm's pattern blt performance. +* +***/ + +#include +#include + +#define ALIGNED + +HSGDIFONT font = (HSGDIFONT)0; +BOOL paused = 0; +DWORD iterations = 0; + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + static BYTE color = 0; + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 640)-20; + int top = (rand() % 450)+12; +#ifdef ALIGNED + left = (left >> 2) << 2; +#endif + SGdiSetPitch(pitch); + SGdiRectangle(videobuffer,left,top,left+40,top+40,PALETTEINDEX(color)); + ++color; + ++iterations; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + KillTimer(params->window,1); + SGdiDeleteObject(font); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + char outstr[64]; + wsprintf(outstr,"%u rectangles per second",iterations); + RECT rect = {0,0,320,12}; + SGdiSetPitch(pitch); + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + iterations = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DDBENCH"), + TEXT("Benchmark"))) + return 1; + if (!LoadFont()) + return 1; + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SGDI/RECT/RECT.CS b/Storm/SAMPLES/SGDI/RECT/RECT.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SGDI/RECT/RECT.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SGDI/RECT/RECT.EXE b/Storm/SAMPLES/SGDI/RECT/RECT.EXE new file mode 100644 index 0000000..2ed0cac Binary files /dev/null and b/Storm/SAMPLES/SGDI/RECT/RECT.EXE differ diff --git a/Storm/SAMPLES/SNET/CHAT/CHAT.CPP b/Storm/SAMPLES/SNET/CHAT/CHAT.CPP new file mode 100644 index 0000000..24431e3 --- /dev/null +++ b/Storm/SAMPLES/SNET/CHAT/CHAT.CPP @@ -0,0 +1,258 @@ +/**************************************************************************** +* +* CHAT.CPP +* +* This is a simple chat program which uses Storm's networking. +* It demonstrates enumerating and selecting a network service provider, +* enumerating and selecting a game, asynchronous messaging, and event +* handlers. +* +***/ + +#include +#include +#include +#include + +#define TITLE "Chat" +#define PROGRAMID 'Chat' +#define VERSIONID 1 +#define MAXPLAYERS 16 + +typedef struct _GAME { + int number; + DWORD id; + char name[SNET_MAXNAMELENGTH]; + _GAME *next; +} GAME, *GAMEPTR; + +typedef struct _PROVIDER { + int number; + DWORD id; + _PROVIDER *next; +} PROVIDER, *PROVIDERPTR; + +GAMEPTR gamehead = NULL; +int games = 0; +char playername[SNET_MAXNAMELENGTH] = ""; +char playerdesc[SNET_MAXDESCLENGTH] = ""; +PROVIDERPTR providerhead = NULL; +int providers = 0; + +//=========================================================================== +void Chat () { + printf("Press escape to exit.\n\n"); + for (;;) { + if (_kbhit()) { + char ch = _getch(); + if (ch == 27) + return; + SNetSendMessage(SNET_BROADCASTPLAYERID,&ch,sizeof(char)); + } + LPVOID data = NULL; + DWORD databytes = 0; + if (SNetReceiveMessage(NULL,&data,&databytes)) + if (data && (databytes == sizeof(char))) + if (*(char *)data == 13) + printf("\n"); + else + printf("%c",*(char *)data); + Sleep(1); + } +} + +//=========================================================================== +BOOL CALLBACK EnumGamesCallback (DWORD id, + LPCSTR name, + LPCSTR description) { + + // IF THIS GAME IS ALREADY IN THE LIST, IGNORE IT + GAMEPTR curr = gamehead; + while (curr) + if (curr->id == id) + return 1; + else + curr = curr->next; + + // ADD THE GAME TO THE LIST + GAME game; + game.number = ++games; + game.id = id; + strncpy(game.name,name,SNET_MAXNAMELENGTH); + LISTADDEND(&gamehead,&game); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK EnumProvidersCallback (DWORD id, + LPCSTR description, + LPCSTR requirements, + SNETCAPSPTR caps) { + PROVIDER provider; + provider.number = ++providers; + provider.id = id; + LISTADD(&providerhead,&provider); + printf("[%u] %s\n",providers,description); + return 1; +} + +//=========================================================================== +void GetPlayerName () { + char username[MAX_PATH] = ""; + char computername[MAX_PATH] = ""; + DWORD usernamelength = MAX_PATH; + DWORD computernamelength = MAX_PATH; + GetUserName(username,&usernamelength); + GetComputerName(computername,&computernamelength); + strncpy(playername,username,SNET_MAXNAMELENGTH); + if (usernamelength+computernamelength+14 < SNET_MAXDESCLENGTH) + sprintf(playerdesc,"%s on computer %s",username,computername); +} + +//=========================================================================== +BOOL InitializeProvider (DWORD providerid) { + SNETPROGRAMDATA programdata; + ZeroMemory(&programdata,sizeof(SNETPROGRAMDATA)); + programdata.size = sizeof(SNETPROGRAMDATA); + programdata.programname = TITLE; + programdata.programid = PROGRAMID; + programdata.versionid = VERSIONID; + programdata.maxplayers = MAXPLAYERS; + SNETPLAYERDATA playerdata; + ZeroMemory(&playerdata,sizeof(SNETPLAYERDATA)); + playerdata.size = sizeof(SNETPLAYERDATA); + playerdata.playername = playername; + playerdata.playerdescription = playerdesc; + return SNetInitializeProvider(providerid, + &programdata, + &playerdata, + NULL, + NULL); +} + +//=========================================================================== +void CALLBACK OnPlayerJoin (SNETEVENTPTR event) { + char name[SNET_MAXNAMELENGTH] = ""; + if (SNetGetPlayerName(event->playerid,name,SNET_MAXNAMELENGTH)) + printf("\n%s has entered the room.\n\n",name); +} + +//=========================================================================== +void CALLBACK OnPlayerLeave (SNETEVENTPTR) { + printf("\nSomeone has left the room.\n\n"); +} + +//=========================================================================== +int Select (int lowest, int highest) { + int selection; + do { + printf("Choice: "); + scanf("%u",&selection); + } while ((selection < lowest) || (selection > highest)); + printf("\n"); + return selection; +} + +//=========================================================================== +BOOL SelectGame () { + + // BUILD A LIST OF GAMES + DWORD hintnextcall = 0; + SNetEnumGames(0,0,EnumGamesCallback,&hintnextcall); + + // SLEEP FOR THE HINTED AMOUNT OF TIME TO MAKE SURE THAT THE PROVIDER'S + // LIST OF GAMES IS COMPLETE + Sleep(hintnextcall); + + // UPDATE THE LIST OF GAMES + SNetEnumGames(0,0,EnumGamesCallback,NULL); + + // DISPLAY THE LIST OF GAMES, ALONG WITH A CHOICE TO CREATE A GAME + printf("[0] Create Game\n"); + { + GAMEPTR curr = gamehead; + while (curr) { + printf("[%u] %s\n",curr->id,curr->name); + curr = curr->next; + } + } + + // GET THE SELECTION + int selection = Select(0,games); + + // IF THE USER SELECTED THE CREATE GAME OPTION, THEN CREATE A NEW GAME + // USING THE PLAYER NAME AND DESCRIPTION AS THE GAME NAME AND DESCRIPTION + BOOL success; + DWORD playerid = 0; + if (!selection) + success = SNetCreateGame(playername, + NULL, + playerdesc, + 0, + NULL, + 0, + MAXPLAYERS, + playername, + playerdesc, + &playerid); + + // OTHERWISE, JOIN THE GAME THAT THE USER SELECTED + else { + GAMEPTR curr = gamehead; + while (curr && (curr->number != selection)) + curr = curr->next; + if (curr) + success = SNetJoinGame(curr->id, + NULL, + NULL, + playername, + playerdesc, + &playerid); + } + + // FREE THE LIST OF GAMES + LISTCLEAR(&gamehead); + + return success; +} + +//=========================================================================== +DWORD SelectProvider () { + + // BUILD AND DISPLAY THE LIST OF PROVIDERS + if (!SNetEnumProviders(NULL,EnumProvidersCallback)) + return 0; + + // SELECT A PROVIDER FROM THE LIST + int selection = Select(0,providers); + + // FIND THE PROVIDER'S ID AND FREE THE LIST OF PROVIDERS + DWORD id = 0; + while (providerhead) { + if (providerhead->number == selection) + id = providerhead->id; + LISTFREE(&providerhead,providerhead); + } + + return id; +} + +//=========================================================================== +int __cdecl main () { + GetPlayerName(); + if (!InitializeProvider(SelectProvider())) { + printf("ERROR: Unable to initialize network provider\n"); + return 1; + } + if (!SelectGame()) { + printf("ERROR: Unable to join game\n"); + return 1; + } + SNetRegisterEventHandler(SNET_EVENT_PLAYERJOIN ,OnPlayerJoin); + SNetRegisterEventHandler(SNET_EVENT_PLAYERLEAVE,OnPlayerLeave); + Chat(); + SNetLeaveGame(0); + SNetDestroy(); + return 0; +} diff --git a/Storm/SAMPLES/SNET/CHAT/CHAT.CS b/Storm/SAMPLES/SNET/CHAT/CHAT.CS new file mode 100644 index 0000000..eb521a7 --- /dev/null +++ b/Storm/SAMPLES/SNET/CHAT/CHAT.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/SNET/CHAT/CHAT.EXE b/Storm/SAMPLES/SNET/CHAT/CHAT.EXE new file mode 100644 index 0000000..58eaab7 Binary files /dev/null and b/Storm/SAMPLES/SNET/CHAT/CHAT.EXE differ diff --git a/Storm/SAMPLES/SNET/JOIN/BKG.PCX b/Storm/SAMPLES/SNET/JOIN/BKG.PCX new file mode 100644 index 0000000..fa9417d Binary files /dev/null and b/Storm/SAMPLES/SNET/JOIN/BKG.PCX differ diff --git a/Storm/SAMPLES/SNET/JOIN/BNAD.PCX b/Storm/SAMPLES/SNET/JOIN/BNAD.PCX new file mode 100644 index 0000000..9d13d02 Binary files /dev/null and b/Storm/SAMPLES/SNET/JOIN/BNAD.PCX differ diff --git a/Storm/SAMPLES/SNET/JOIN/BNBKG.PCX b/Storm/SAMPLES/SNET/JOIN/BNBKG.PCX new file mode 100644 index 0000000..5b03842 Binary files /dev/null and b/Storm/SAMPLES/SNET/JOIN/BNBKG.PCX differ diff --git a/Storm/SAMPLES/SNET/JOIN/BNBUTTON.PCX b/Storm/SAMPLES/SNET/JOIN/BNBUTTON.PCX new file mode 100644 index 0000000..8788d73 Binary files /dev/null and b/Storm/SAMPLES/SNET/JOIN/BNBUTTON.PCX differ diff --git a/Storm/SAMPLES/SNET/JOIN/BNCACHE.DAT b/Storm/SAMPLES/SNET/JOIN/BNCACHE.DAT new file mode 100644 index 0000000..91aab1b Binary files /dev/null and b/Storm/SAMPLES/SNET/JOIN/BNCACHE.DAT differ diff --git a/Storm/SAMPLES/SNET/JOIN/BUTTON.PCX b/Storm/SAMPLES/SNET/JOIN/BUTTON.PCX new file mode 100644 index 0000000..86bdb14 Binary files /dev/null and b/Storm/SAMPLES/SNET/JOIN/BUTTON.PCX differ diff --git a/Storm/SAMPLES/SNET/JOIN/JOIN.CPP b/Storm/SAMPLES/SNET/JOIN/JOIN.CPP new file mode 100644 index 0000000..7169bf4 --- /dev/null +++ b/Storm/SAMPLES/SNET/JOIN/JOIN.CPP @@ -0,0 +1,100 @@ +/**************************************************************************** +* +* JOIN.CPP +* +* This program demonstrates the SNetUi functions used for selecting a +* network provider and joining a game. +* +***/ + +#include +#include + +#define TITLE "SNetUi Sample Program" +#define PROGRAMID 'Join' +#define VERSIONID 1 +#define MAXPLAYERS 8 + +//=========================================================================== +BOOL CALLBACK ArtCallback (DWORD providerid, + DWORD artid, + LPPALETTEENTRY pe, + LPBYTE buffer, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + char filename[MAX_PATH] = ""; + if (providerid == 'BTLN') + switch (artid) { + case SNET_ART_BACKGROUND: strcpy(filename,"bnbkg.pcx" ); break; + case SNET_ART_BUTTONTEXTURE: strcpy(filename,"bnbutton.pcx"); break; + } + else + switch (artid) { + case SNET_ART_BACKGROUND: strcpy(filename,"bkg.pcx" ); break; + case SNET_ART_BUTTONTEXTURE: strcpy(filename,"button.pcx" ); break; + } + if (filename[0]) + return SBmpLoadImage(filename,pe,buffer,buffersize,width,height,bitdepth); + else + return 0; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR cmdline, int) { + + // INITIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TITLE, + TITLE)) + return 1; + + // BUILD A PROGRAM DATA STRUCTURE + SNETPROGRAMDATA programdata; + ZeroMemory(&programdata,sizeof(SNETPROGRAMDATA)); + programdata.size = sizeof(SNETPROGRAMDATA); + programdata.programname = TITLE; + programdata.programid = PROGRAMID; + programdata.versionid = VERSIONID; + programdata.maxplayers = MAXPLAYERS; + + // BUILD A PLAYER DATA STRUCTURE + SNETPLAYERDATA playerdata; + ZeroMemory(&playerdata,sizeof(SNETPLAYERDATA)); + playerdata.size = sizeof(SNETPLAYERDATA); + playerdata.playername = "PlayerName"; + playerdata.playerdescription = "PlayerDesc"; + + // BUILD AN INTERFACE DATA STRUCTURE + SNETUIDATA interfacedata; + ZeroMemory(&interfacedata,sizeof(SNETUIDATA)); + interfacedata.size = sizeof(SNETUIDATA); + interfacedata.parentwindow = SDrawGetFrameWindow(); + interfacedata.artcallback = ArtCallback; + + // SELECT A NETWORK PROVIDER + DWORD providerid; + if (!SNetSelectProvider(NULL, + &programdata, + &playerdata, + &interfacedata, + NULL, + &providerid)) + return 1; + + // SELECT A GAME + DWORD playerid; + if (!SNetSelectGame(0, + &programdata, + &playerdata, + &interfacedata, + NULL, + &playerid)) + return 1; + + // SHUTDOWN + StormDestroy(); + + return 0; +} diff --git a/Storm/SAMPLES/SNET/JOIN/JOIN.CS b/Storm/SAMPLES/SNET/JOIN/JOIN.CS new file mode 100644 index 0000000..732d435 --- /dev/null +++ b/Storm/SAMPLES/SNET/JOIN/JOIN.CS @@ -0,0 +1,2 @@ +#include +set extralib=storm.lib diff --git a/Storm/SAMPLES/SNET/JOIN/JOIN.EXE b/Storm/SAMPLES/SNET/JOIN/JOIN.EXE new file mode 100644 index 0000000..1d5214d Binary files /dev/null and b/Storm/SAMPLES/SNET/JOIN/JOIN.EXE differ diff --git a/Storm/SAMPLES/SNET/PONG/ARTWORK.MPQ b/Storm/SAMPLES/SNET/PONG/ARTWORK.MPQ new file mode 100644 index 0000000..5a98ada Binary files /dev/null and b/Storm/SAMPLES/SNET/PONG/ARTWORK.MPQ differ diff --git a/Storm/SAMPLES/SNET/PONG/PONG.CPP b/Storm/SAMPLES/SNET/PONG/PONG.CPP new file mode 100644 index 0000000..964acce --- /dev/null +++ b/Storm/SAMPLES/SNET/PONG/PONG.CPP @@ -0,0 +1,724 @@ +/**************************************************************************** +* +* PONG.CPP +* +* This is a simple game which demonstrates the use of asynchronous +* messaging. It is sort of a cross between Pong and Breakout. Players +* bounce balls off of bricks in the center of the screen, and when they +* have eliminated enough bricks, they try to bounce their ball into the +* opponent's territory in the hopes he will miss it. +* +* Pong is actually a good example of a game in which it is very difficult to +* support an arbitrary latency network. You cannot simply model the ball +* locally and accept periodic updates from the remote player, because the +* ball's trajectory will change significantly every time the remote player +* hits it, depending on exactly where his paddle was at the moment of +* contact. Therefore, what this implementation does is take the ball +* out of play (make it invisible and nonmoving) when it gets to a point +* where it may or may not have collided with the opponent's paddle, and +* then waits for a message from the opponent telling whether he hit or +* missed, and what the new position and trajectory of the ball are. It can +* then model the ball locally until the next time it comes into possible +* contact with the opponent's paddle. +* +* Despite this, it is still possible for the game to become out of sync, +* because there are two balls in play. When one of them is taken out of +* play pending a message from the opponent, the other one continues to +* move. On a high latency network, the end result is that, one the local +* system, the ball that the local player just hit will tend to be slightly +* farther along than the ball the remote player just hit, and on the remote +* system, the inverse will be true. So if the two balls hit the same +* brick at the same time, each player will think that his own ball was +* deflected and the opponent's wasn't. If the balls are deflected straight +* back to the players and the players both miss, then each player might +* think that he missed but the opponent didn't. This is actually no big +* deal. Players send out messages saying they missed the ball when they +* do, and the recipient of the message will always take the player's word +* for it that he did, in fact, miss the ball. A worse situation happens +* if the balls are not deflected straight back to the players, but instead, +* each ball bounces off another brick and goes on to the opposing player. +* This would be more serious, as now each player would take the ball out of +* play while waiting for a message from the opposing player telling whether +* he hit or missed the ball. Since neither play would think that the ball +* came to him, neither player would ever send out such a message. Just in +* case this situation ever happens, what Pong does is send out a messsage +* whenever it thinks that the opponent needs to tell it whether he hit or +* missed the ball. When the opponent gets this message, if he finds that +* he is waiting for the same message from the other player, then he knows +* that a deadlock has occurred. He breaks the deadlock by putting the ball +* back into play with a new position and velocity, and sending that position +* and velocity to the other player. +* +***/ + +#include +#include +#include +#include + +#define PROGRAMID 'Pong' +#define VERSIONID 1 +#define MAXPLAYERS 2 +#define TITLE "Pong" + +#define BRICKCOLS 7 +#define BRICKROWS 24 + +#define SIN(a) sintable[((a) & 255)] +#define COS(a) sintable[(((a)+64) & 255)] + +#define NETID_BALLPOS 1 +#define NETID_CHECKSYNC 2 +#define NETID_MISSED 3 +#define NETID_PADDLEPOS 4 +#define NETID_QUIT 5 +#define NETID_RESTART 6 + +typedef BYTE ANGLE; +typedef LONG FIXEDINT; + +typedef struct _POINTF { + FIXEDINT x; + FIXEDINT y; +} POINTF; + +HSARCHIVE archive = (HSARCHIVE)0; +ANGLE ballangle[2]; +POINTF ballpos[2]; +SIZE ballsize = {5,5}; +int ballwait[2]; +BYTE brick[BRICKCOLS][BRICKROWS]; +BOOL computer = 0; +int lives[2]; +int missed[2]; +POINT paddle[2] = {{15,240},{624,240}}; +SIZE paddlesize = {5,40}; +DWORD player = 0; +FIXEDINT sintable[256]; +FIXEDINT speed[2]; +BOOL started = 0; + +BOOL CALLBACK CreateCallback (SNETCREATEDATAPTR createdata, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); +void CreateSinTable (); +FIXEDINT FixedMul (FIXEDINT a, FIXEDINT b); +BOOL ProcessNetworkMessages (); +void SendNetworkMessage (LPDWORD paramarray, DWORD paramcount); +void StartBall (int number, DWORD player); +void StartGame (); + +//=========================================================================== +BOOL CALLBACK ArtCallback (DWORD providerid, + DWORD artid, + LPPALETTEENTRY pe, + LPBYTE buffer, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + char filename[MAX_PATH] = ""; + switch (artid) { + case SNET_ART_BACKGROUND: strcpy(filename,"bkg.pcx" ); break; + case SNET_ART_BUTTONTEXTURE: strcpy(filename,"button.pcx"); break; + } + if (filename[0]) + return SBmpLoadImage(filename,pe,buffer,buffersize,width,height,bitdepth); + else + return 0; +} + +//=========================================================================== +BOOL Bounce (ANGLE *angle, int xdir, int ydir) { + BOOL bounced = 0; + if (((xdir < 0) && ((ANGLE)(64+*angle) < 128)) || + ((xdir > 0) && ((ANGLE)(64+*angle) > 128))) { + *angle = 192-(64+*angle); + bounced = 1; + } + if (((ydir < 0) && (*angle < 128)) || + ((ydir > 0) && (*angle > 128))) { + *angle = -*angle; + bounced = 1; + } + return bounced; +} + +//=========================================================================== +void ComputerMovePaddle () { + BOOL consider[2]; + int ball; + for (ball = 0; ball < 2; ++ball) + consider[ball] = ((ballwait[ball] < 0) && + ((ballpos[ball].x > 320*0x10000) == (int)player) && + (((ANGLE)(ballangle[ball]+64) < 128) == (int)player)); + if (!(consider[0] ^ consider[1])) + ball = ((ballpos[0].x > ballpos[1].x) == (int)player) ? 0 : 1; + else if (consider[0]) + ball = 0; + else + ball = 1; + if (ball >= 0) { + int y = ballpos[ball].y/0x10000; + y -= (y-240)*paddlesize.cy/240; + if (y < paddle[player].y) + paddle[player].y -= min(12,paddle[player].y-y); + else if (y > paddle[player].y) + paddle[player].y += min(12,y-paddle[player].y); + } +} + +//=========================================================================== +BOOL Connect () { + + // BUILD A PROGRAM DATA RECORD + SNETPROGRAMDATA programdata; + ZeroMemory(&programdata,sizeof(SNETPROGRAMDATA)); + programdata.size = sizeof(SNETPROGRAMDATA); + programdata.programname = TITLE; + programdata.programid = PROGRAMID; + programdata.versionid = VERSIONID; + programdata.maxplayers = MAXPLAYERS; + + // GENERATE A PLAYER NAME + char computername[MAX_COMPUTERNAME_LENGTH+1] = ""; + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + GetComputerName(computername,&size); + + // BUILD A PLAYER DATA RECORD + SNETPLAYERDATA playerdata; + ZeroMemory(&playerdata,sizeof(SNETPLAYERDATA)); + playerdata.size = sizeof(SNETPLAYERDATA); + playerdata.playername = computername; + + // BUILD AN INTERFACE DATA RECORD + SNETUIDATA interfacedata; + ZeroMemory(&interfacedata,sizeof(SNETUIDATA)); + interfacedata.size = sizeof(SNETUIDATA); + interfacedata.parentwindow = SDrawGetFrameWindow(); + interfacedata.artcallback = ArtCallback; + interfacedata.createcallback = CreateCallback; + + // SELECT A NETWORK PROVIDER + while (SNetSelectProvider(NULL, + &programdata, + &playerdata, + &interfacedata, + NULL, + NULL)) { + + // SELECT A GAME + if (SNetSelectGame(0, + &programdata, + &playerdata, + &interfacedata, + NULL, + &player)) + return 1; + + } + return 0; +} + +//=========================================================================== +void ConnectIdleProc () { + + // IF WE ARE STILL WAITING TO CONNECT, UPDATE THE WAITING BANNER AND RETURN + { + DWORD activeplayers = 0; + SNetGetNumPlayers(NULL,NULL,&activeplayers); + if (activeplayers < 2) { + static BYTE intensity = 0; + static int direction = 1; + PALETTEENTRY pe = {intensity,intensity,0x80+(intensity >> 1),0}; + SDrawUpdatePalette(128,1,&pe); + intensity += direction; + if (intensity >= 127) + direction = -1; + else if (!intensity) + direction = 1; + Sleep(1); + return; + } + } + + // START THE GAME + CreateSinTable(); + StartGame(); + started = 1; + +} + +//=========================================================================== +BOOL CALLBACK CreateCallback (SNETCREATEDATAPTR createdata, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + return SNetCreateGame(playerdata->playername, + NULL, + NULL, + 0, + NULL, + 0, + programdata->maxplayers, + playerdata->playername, + NULL, + playerid); +} + +//=========================================================================== +void CreateSinTable () { + for (int loop = 0; loop < 256; ++loop) { + double angle = (loop*3.14159265359)/128.0; + sintable[loop] = (FIXEDINT)(sin(angle)*0x10000); + } +} + +//=========================================================================== +void DrawScreen () { + LPBYTE videobuffer; + int videopitch; + SDrawClearSurface(SDRAW_SURFACE_BACK); + if (SDrawLockSurface(SDRAW_SURFACE_BACK,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + + // DRAW THE PADDLES + { + for (int loop = 0; loop <= 1; ++loop) + if (!missed[loop]) + SGdiRectangle(videobuffer, + paddle[loop].x-paddlesize.cx, + paddle[loop].y-paddlesize.cy, + paddle[loop].x+paddlesize.cx, + paddle[loop].y+paddlesize.cy, + PALETTEINDEX(255)); + } + + // DRAW THE BRICKS + { + for (int row = 0; row < BRICKROWS; ++row) + for (int col = 0; col < BRICKCOLS; ++col) + if (brick[col][row]) + SGdiRectangle(videobuffer, + col*25+240, + row*20+2, + col*25+250, + row*20+17, + PALETTEINDEX(248+col)); + } + + // DRAW THE BALLS + { + for (int loop = 0; loop <= 1; ++loop) + if (ballwait[loop] < 0) + SGdiRectangle(videobuffer, + (ballpos[loop].x/0x10000)-ballsize.cx, + (ballpos[loop].y/0x10000)-ballsize.cy, + (ballpos[loop].x/0x10000)+ballsize.cx, + (ballpos[loop].y/0x10000)+ballsize.cy, + PALETTEINDEX(255)); + } + + // DRAW LIVES LEFT + { + for (DWORD loop = 0; loop <= 1; ++loop) + if (missed[loop]) + if (lives[loop]) { + char buffer[64]; + wsprintf(buffer, + "%u %s LEFT", + lives[loop], + (lives[loop] == 1) ? "LIFE" : "LIVES"); + SGdiTextOut(videobuffer, + loop*400+100, + 235, + PALETTEINDEX(255), + buffer); + } + else if (loop == player) + SGdiTextOut(videobuffer, + loop*400+100, + 235, + PALETTEINDEX(255), + "LOSER!"); + else + SGdiTextOut(videobuffer, + (!loop)*400+100, + 235, + PALETTEINDEX(255), + "WINNER!"); + } + + SDrawUnlockSurface(SDRAW_SURFACE_BACK,videobuffer); + SDrawFlipPage(); + } +} + +//=========================================================================== +void ExecuteGameLoop () { + + // MOVE THE BALLS + { + for (int loop = 0; loop < 2; ++loop) + if (ballwait[loop] < 0) { + POINT lastpos = {ballpos[loop].x/0x10000, + ballpos[loop].y/0x10000}; + POINT nextpos = {(ballpos[loop].x+FixedMul(COS(ballangle[loop]),speed[loop]))/0x10000, + (ballpos[loop].y+FixedMul(SIN(ballangle[loop]),speed[loop]))/0x10000}; + + // IF THE BALL HAS MOVED TO WHERE IT MAY OR MAY NOT HAVE COLLIDED + // WITH THE REMOTE PLAYER'S PADDLE, PUT THE BALL ON HOLD UNTIL WE + // FIND OUT FROM THE REMOTE PLAYER WHAT HAPPENED + if (( player && (nextpos.x-ballsize.cx < paddle[0].x+paddlesize.cx)) || + ((!player) && (nextpos.x+ballsize.cx > paddle[1].x-paddlesize.cx))) { + ballwait[loop] = !player; + DWORD paramarray[2] = {NETID_CHECKSYNC,loop}; + SendNetworkMessage(¶marray[0],2); + continue; + } + + // CHECK FOR COLLISION WITH THE LOCAL PLAYER'S PADDLE + if ((!missed[player]) && + (nextpos.x-ballsize.cx < paddle[player].x+paddlesize.cx) && + (nextpos.x+ballsize.cx > paddle[player].x-paddlesize.cx) && + (nextpos.y-ballsize.cy < paddle[player].y+paddlesize.cy) && + (nextpos.y+ballsize.cy > paddle[player].y-paddlesize.cy)) { + int ydir = 0; + if (nextpos.y-ballsize.cy < paddle[player].y-paddlesize.cy) + ydir = -1; + else if (nextpos.y+ballsize.cy > paddle[player].y+paddlesize.cy) + ydir = 1; + if (Bounce(&ballangle[loop],player ? -1 : 1,ydir)) { + ANGLE target = (ANGLE)((nextpos.y-paddle[player].y)*32/paddlesize.cy); + if (player) + target = 128-target; + ballangle[loop] += ((char)(target-ballangle[loop]))/2; + DWORD paramarray[6] = {NETID_BALLPOS, + loop, + ballpos[loop].x, + ballpos[loop].y, + ballangle[loop], + speed[loop]}; + SendNetworkMessage(¶marray[0],6); + continue; + } + } + + // CHECK FOR COLLISION WITH THE EDGE OF THE SCREEN, INDICATING THAT + // THE PLAYER MISSED THE BALL + if (( player && (nextpos.x+ballsize.cx > 639)) || + ((!player) && (nextpos.x-ballsize.cx < 0))) { + ballwait[loop] = player; + if (missed[player]) + missed[player] = 30; + else { + --lives[player]; + missed[player] = 100; + } + DWORD paramarray[4] = {NETID_MISSED, + loop, + missed[player], + lives[player]}; + SendNetworkMessage(¶marray[0],4); + continue; + } + + // CHECK FOR COLLISION WITH THE TOP OR BOTTOM OF THE SCREEN + if (nextpos.y-ballsize.cy < 0) + Bounce(&ballangle[loop],0,1); + if (nextpos.y+ballsize.cy > 479) + Bounce(&ballangle[loop],0,-1); + + // CHECK FOR COLLISION WITH A BRICK + { + for (int col = 0; col < BRICKCOLS; ++col) + if ((nextpos.x-ballsize.cx <= col*25+250) && + (nextpos.x+ballsize.cx >= col*25+240)) + for (int row = 0; row < BRICKROWS; ++row) + if (brick[col][row] && + ((nextpos.y-ballsize.cy <= row*20+17) && + (nextpos.y+ballsize.cy >= row*20+2))) { + int xdir = 0; + int ydir = 0; + if ((lastpos.x+ballsize.cx < col*25+240) && + (nextpos.x+ballsize.cx >= col*25+240)) + xdir = -1; + else if ((lastpos.x-ballsize.cx > col*25+250) && + (nextpos.x-ballsize.cx <= col*25+250)) + xdir = 1; + if ((lastpos.y+ballsize.cy < row*20+2) && + (nextpos.y+ballsize.cy >= row*20+2)) + ydir = -1; + else if ((lastpos.y-ballsize.cy > row*20+17) && + (nextpos.y-ballsize.cy <= row*20+17)) + ydir = 1; + Bounce(&ballangle[loop],xdir,ydir); + brick[col][row] = 0; + } + } + + ballpos[loop].x += FixedMul(COS(ballangle[loop]),speed[loop]); + ballpos[loop].y += FixedMul(SIN(ballangle[loop]),speed[loop]); + speed[loop] += 48; + } + } + + // IF THE PLAYER RECENTLY MISSED THE BALL, CHECK TO SEE IF HE CAN + // REENTER THE GAME + if (missed[player]) + if (missed[player] > 1) + --missed[player]; + else { + DWORD side[2]; + for (int loop = 0; loop < 2; ++loop) { + if (ballwait[loop] >= 0) + side[loop] = -1; + else if ((ballpos[loop].x < 320*0x10000) && (COS(ballangle[loop]) < 0)) + side[loop] = 0; + else if ((ballpos[loop].x > 320*0x10000) && (COS(ballangle[loop]) > 0)) + side[loop] = 1; + else + side[loop] = -1; + } + if ((side[0] != player) && (side[1] != player)) { + missed[player] = 0; + if (ballwait[0] == (int)player) { + StartBall(0,player); + if (ballwait[1] == (int)player) + StartBall(1,!player); + } + else if (ballwait[1] == (int)player) + StartBall(1,player); + } + } + + // MOVE THE PLAYER'S PADDLE + if (computer) + ComputerMovePaddle(); + else { + POINT pt; + GetCursorPos(&pt); + paddle[player].y = pt.y; + } + paddle[player].y = max(paddlesize.cy,min(479-paddlesize.cy,paddle[player].y)); + +} + +//=========================================================================== +FIXEDINT FixedMul (FIXEDINT a, FIXEDINT b) { + return MulDiv(a,b,0x10000); +} + +//=========================================================================== +void GameIdleProc () { + DWORD currtime = GetTickCount(); + + // PROCESS NETWORK MESSAGES + BOOL processed = ProcessNetworkMessages(); + + // EXECUTE THE GAME LOOP 60 TIMES PER SECOND + if (lives[0] && lives[1]) { + static DWORD lasttime = GetTickCount(); + static DWORD cycle = 0; + if (currtime-lasttime > 1000) + lasttime = currtime; + else + while (currtime-lasttime >= 17) { + ExecuteGameLoop(); + processed = 1; + lasttime += cycle++ ? 17 : 16; + if (cycle > 2) + cycle = 0; + } + } + + // SEND OUT OUR PADDLE POSITION 10 TIMES PER SECOND + { + static DWORD lasttime = GetTickCount(); + if (currtime-lasttime > 1000) + lasttime = currtime; + else + while (currtime-lasttime >= 100) { + DWORD paramarray[2] = {NETID_PADDLEPOS,paddle[player].y}; + SendNetworkMessage(¶marray[0],2); + lasttime += 100; + } + } + + // UPDATE THE SCREEN + if (processed) + DrawScreen(); + +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (started) + GameIdleProc(); + else + ConnectIdleProc(); + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + HSGDIFONT font; + { + HFONT winfont = CreateFont(-17,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_ROMAN,TEXT("Times New Roman")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +void CALLBACK OnKeyDown (LPPARAMS params) { + if (params->wparam == VK_ESCAPE) { + if (started) { + DWORD param = NETID_QUIT; + SendNetworkMessage(¶m,1); + } + SDrawPostClose(); + } + else if (started && (!lives[0]) || (!lives[1])) { + DWORD param = NETID_RESTART; + SendNetworkMessage(¶m,1); + StartGame(); + } +} + +//=========================================================================== +void CALLBACK OnPaint (LPPARAMS params) { + if (!started) { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + SGdiRectangle(videobuffer,0,0,639,479,PALETTEINDEX(128)); + SGdiTextOut(videobuffer,240,235,PALETTEINDEX(255),"Waiting to connect..."); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + } +} + +//=========================================================================== +BOOL ProcessNetworkMessages () { + BOOL processed = 0; + LPVOID data = NULL; + DWORD databytes = 0; + while (SNetReceiveMessage(NULL,&data,&databytes)) + if (databytes >= sizeof(DWORD)) { + LPDWORD param = (LPDWORD)data; + switch (*param) { + + case NETID_BALLPOS: + ballpos[*(param+1)].x = *(param+2); + ballpos[*(param+1)].y = *(param+3); + ballangle[*(param+1)] = (ANGLE)*(param+4); + speed[*(param+1)] = *(param+5); + ballwait[*(param+1)] = -1; + missed[!player] = 0; + break; + + case NETID_CHECKSYNC: + if (ballwait[*(param+1)] == !player) + StartBall(*(param+1),player); + break; + + case NETID_MISSED: + ballwait[*(param+1)] = !player; + missed[!player] = *(param+2); + lives[!player] = *(param+3); + break; + + case NETID_PADDLEPOS: + paddle[!player].y = *(param+1); + break; + + case NETID_QUIT: + SDrawPostClose(); + break; + + case NETID_RESTART: + StartGame(); + break; + + } + processed = 1; + } + return processed; +} + +//=========================================================================== +void SendNetworkMessage (LPDWORD paramarray, DWORD paramcount) { + SNetSendMessage(!player, + paramarray, + paramcount*sizeof(DWORD)); +} + +//=========================================================================== +void StartBall (int number, DWORD player) { + ballangle[number] = (rand() & 63)+(player ? 224 : 96); + ballpos[number].x = (player ? 420 : 220)*0x10000; + int besty = paddle[player].y-(abs((ballpos[number].x >> 16)-paddle[player].x)*SIN(ballangle[number]) >> 16); + ballpos[number].y = max(0,min(479,besty))*0x10000; + ballwait[number] = -1; + DWORD paramarray[6] = {NETID_BALLPOS, + number, + ballpos[number].x, + ballpos[number].y, + ballangle[number], + speed[number]}; + SendNetworkMessage(¶marray[0],6); +} + +//=========================================================================== +void StartGame () { + srand(GetTickCount()); + FillMemory(brick,BRICKCOLS*BRICKROWS,1); + for (int loop = 0; loop < 2; ++loop) { + lives[loop] = 3; + missed[loop] = 0; + speed[loop] = 0x50000; + } + StartBall(player,player); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR cmdline, int) { + if (cmdline && *cmdline) + computer = 1; + if (!SDrawAutoInitialize(instance, + TITLE "_CLASS", + TITLE, + NULL, + SDRAW_SERVICE_PAGEFLIP)) { + SDrawMessageBox("Unable to initialize DirectDraw.",TITLE,0); + return 1; + } + if (!SFileOpenArchive("artwork.mpq",0,0,&archive)) { + SDrawMessageBox("Unable to open artwork.",TITLE,0); + return 1; + } + if (!Connect()) { + SDrawMessageBox("Unable to initialize networking.",TITLE,0); + return 1; + } + if (!LoadFont()) { + SDrawMessageBox("Unable to load font.",TITLE,0); + return 1; + } + SMsgRegisterMessage(NULL,WM_KEYDOWN,OnKeyDown); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SNET/PONG/PONG.CS b/Storm/SAMPLES/SNET/PONG/PONG.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SNET/PONG/PONG.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SNET/PONG/PONG.EXE b/Storm/SAMPLES/SNET/PONG/PONG.EXE new file mode 100644 index 0000000..4b317ed Binary files /dev/null and b/Storm/SAMPLES/SNET/PONG/PONG.EXE differ diff --git a/Storm/SAMPLES/SNET/README.TXT b/Storm/SAMPLES/SNET/README.TXT new file mode 100644 index 0000000..97c80f4 --- /dev/null +++ b/Storm/SAMPLES/SNET/README.TXT @@ -0,0 +1,7 @@ +The networking examples have not been updated recently, so they do not +include all of the necessary user interface callback functions and artwork. +This affects the create/join game process but does not affect the +functionality of the example games themselves. + +For sample implementations of all required user interface callback +functions, see the DiabloUI source code. diff --git a/Storm/SAMPLES/SNET/RPG/ART/CURSOR.PCX b/Storm/SAMPLES/SNET/RPG/ART/CURSOR.PCX new file mode 100644 index 0000000..488d3ca Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/ART/CURSOR.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/ART/MAP.PCX b/Storm/SAMPLES/SNET/RPG/ART/MAP.PCX new file mode 100644 index 0000000..b5f47f4 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/ART/MAP.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/ART/PLAYER.PCX b/Storm/SAMPLES/SNET/RPG/ART/PLAYER.PCX new file mode 100644 index 0000000..9fe13f3 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/ART/PLAYER.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/ART/TILESET.PCX b/Storm/SAMPLES/SNET/RPG/ART/TILESET.PCX new file mode 100644 index 0000000..7a98692 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/ART/TILESET.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/BNETART.H b/Storm/SAMPLES/SNET/RPG/BNETART.H new file mode 100644 index 0000000..bf6299e --- /dev/null +++ b/Storm/SAMPLES/SNET/RPG/BNETART.H @@ -0,0 +1,19 @@ +/**************************************************************************** +* +* bnetart.h +* +* This file should be included by an application that wants to provide +* battle.net-specific artwork in its art callback. +* +***/ + +enum _BATTLENET_ART { + SNET_ART_BATTLE_BTNS = 0x80000000, + SNET_ART_BATTLE_JOIN_BKG, + SNET_ART_BATTLE_HELP_BKG, + SNET_ART_BATTLE_LISTBOX, + SNET_ART_BATTLE_GREENLAG, + SNET_ART_BATTLE_YELLOWLAG, + SNET_ART_BATTLE_REDLAG, +}; + diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BKG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BKG.PCX new file mode 100644 index 0000000..10d285d Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BKG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BNBUTTNS.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BNBUTTNS.PCX new file mode 100644 index 0000000..bf07cec Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BNBUTTNS.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BNCREATE.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BNCREATE.PCX new file mode 100644 index 0000000..3933f50 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BNCREATE.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BNHELP.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BNHELP.PCX new file mode 100644 index 0000000..71f5da6 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BNHELP.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BNJOIN.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BNJOIN.PCX new file mode 100644 index 0000000..962e07d Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BNJOIN.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BNJOINBG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BNJOINBG.PCX new file mode 100644 index 0000000..c3a6bbf Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BNJOINBG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BNLIST.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BNLIST.PCX new file mode 100644 index 0000000..7652964 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BNLIST.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BNQUIT.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BNQUIT.PCX new file mode 100644 index 0000000..1b26038 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BNQUIT.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BUTTON.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BUTTON.PCX new file mode 100644 index 0000000..2d0986f Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BUTTON.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BUT_LRG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BUT_LRG.PCX new file mode 100644 index 0000000..c9e1682 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BUT_LRG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BUT_MED.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BUT_MED.PCX new file mode 100644 index 0000000..a4989f0 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BUT_MED.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BUT_SML.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BUT_SML.PCX new file mode 100644 index 0000000..27f2fb5 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BUT_SML.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/BUT_XSM.PCX b/Storm/SAMPLES/SNET/RPG/NETART/BUT_XSM.PCX new file mode 100644 index 0000000..018ca53 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/BUT_XSM.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/CHAT_BKG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/CHAT_BKG.PCX new file mode 100644 index 0000000..8deb560 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/CHAT_BKG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/CONNECT.PCX b/Storm/SAMPLES/SNET/RPG/NETART/CONNECT.PCX new file mode 100644 index 0000000..350dbe6 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/CONNECT.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/CREAHERO.PCX b/Storm/SAMPLES/SNET/RPG/NETART/CREAHERO.PCX new file mode 100644 index 0000000..10282d6 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/CREAHERO.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/CREAT_BG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/CREAT_BG.PCX new file mode 100644 index 0000000..38f2c98 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/CREAT_BG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/CREDITS.PCX b/Storm/SAMPLES/SNET/RPG/NETART/CREDITS.PCX new file mode 100644 index 0000000..2270e85 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/CREDITS.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/GREENLAG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/GREENLAG.PCX new file mode 100644 index 0000000..1533218 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/GREENLAG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/HEROS.PCX b/Storm/SAMPLES/SNET/RPG/NETART/HEROS.PCX new file mode 100644 index 0000000..7ded7e7 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/HEROS.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/IPX_BKG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/IPX_BKG.PCX new file mode 100644 index 0000000..440f69e Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/IPX_BKG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/LISTBOX.PCX b/Storm/SAMPLES/SNET/RPG/NETART/LISTBOX.PCX new file mode 100644 index 0000000..8a3af8b Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/LISTBOX.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/LIST_GRY.PCX b/Storm/SAMPLES/SNET/RPG/NETART/LIST_GRY.PCX new file mode 100644 index 0000000..68b16b4 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/LIST_GRY.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/LPOPUP.PCX b/Storm/SAMPLES/SNET/RPG/NETART/LPOPUP.PCX new file mode 100644 index 0000000..3cfbed5 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/LPOPUP.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/LRPOPUP.PCX b/Storm/SAMPLES/SNET/RPG/NETART/LRPOPUP.PCX new file mode 100644 index 0000000..441c1d7 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/LRPOPUP.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/MENU.PCX b/Storm/SAMPLES/SNET/RPG/NETART/MENU.PCX new file mode 100644 index 0000000..6eae183 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/MENU.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/PROG_BG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/PROG_BG.PCX new file mode 100644 index 0000000..1ae2df4 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/PROG_BG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/PROG_FIL.PCX b/Storm/SAMPLES/SNET/RPG/NETART/PROG_FIL.PCX new file mode 100644 index 0000000..3cb44a7 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/PROG_FIL.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/R1_GRY.PCX b/Storm/SAMPLES/SNET/RPG/NETART/R1_GRY.PCX new file mode 100644 index 0000000..ca710ca Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/R1_GRY.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/R3_GRY.PCX b/Storm/SAMPLES/SNET/RPG/NETART/R3_GRY.PCX new file mode 100644 index 0000000..17a7013 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/R3_GRY.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/RADIO1.PCX b/Storm/SAMPLES/SNET/RPG/NETART/RADIO1.PCX new file mode 100644 index 0000000..9963ae1 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/RADIO1.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/RADIO2.PCX b/Storm/SAMPLES/SNET/RPG/NETART/RADIO2.PCX new file mode 100644 index 0000000..d6b1be4 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/RADIO2.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/RADIO3.PCX b/Storm/SAMPLES/SNET/RPG/NETART/RADIO3.PCX new file mode 100644 index 0000000..78d2bac Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/RADIO3.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/RADIO4.PCX b/Storm/SAMPLES/SNET/RPG/NETART/RADIO4.PCX new file mode 100644 index 0000000..0331c72 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/RADIO4.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/REDLAG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/REDLAG.PCX new file mode 100644 index 0000000..7fdd67d Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/REDLAG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/SELHERO.PCX b/Storm/SAMPLES/SNET/RPG/NETART/SELHERO.PCX new file mode 100644 index 0000000..42faf9c Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/SELHERO.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/SPOPUP.PCX b/Storm/SAMPLES/SNET/RPG/NETART/SPOPUP.PCX new file mode 100644 index 0000000..0029f35 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/SPOPUP.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/SRPOPUP.PCX b/Storm/SAMPLES/SNET/RPG/NETART/SRPOPUP.PCX new file mode 100644 index 0000000..8216de5 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/SRPOPUP.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/TITLE.PCX b/Storm/SAMPLES/SNET/RPG/NETART/TITLE.PCX new file mode 100644 index 0000000..558b552 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/TITLE.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/YELLOLAG.PCX b/Storm/SAMPLES/SNET/RPG/NETART/YELLOLAG.PCX new file mode 100644 index 0000000..760a153 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/YELLOLAG.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/NETART/_BACKUP_.PCX b/Storm/SAMPLES/SNET/RPG/NETART/_BACKUP_.PCX new file mode 100644 index 0000000..1533218 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/NETART/_BACKUP_.PCX differ diff --git a/Storm/SAMPLES/SNET/RPG/RESOURCE.H b/Storm/SAMPLES/SNET/RPG/RESOURCE.H new file mode 100644 index 0000000..db969d3 --- /dev/null +++ b/Storm/SAMPLES/SNET/RPG/RESOURCE.H @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by rpg.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SAMPLES/SNET/RPG/RPG.CPP b/Storm/SAMPLES/SNET/RPG/RPG.CPP new file mode 100644 index 0000000..673ad48 --- /dev/null +++ b/Storm/SAMPLES/SNET/RPG/RPG.CPP @@ -0,0 +1,760 @@ +/**************************************************************************** +* +* RPG.CPP +* +* This is a simple game which demonstrates the use of synchonous networking. +* It is basically an Ultima IV style tiled graphics engine, with Warcraft +* style mouse controls. +* +* At the beginning of the game, each player sends out two null orders. +* During the game, players send out orders as they are received from the +* user (a sample order would be "move to this location"), and fabricate +* null orders as necessary to make sure there are always at least two in +* transit. +* +* Each turn, each player waits until he has received the next set of orders +* from all players, and then executes all orders, starting at the lowest +* player number. Since orders are processed at the same time and in the +* same order on every computer in the network, the game stays in sync. +* +***/ + +#include +#include +#include "bnetart.h" + +#define PROGRAMID 'RPG1' +#define VERSIONID 1 +#define MAXPLAYERS 8 +#define TITLE "RPG Example" +#define ARTDIR "art\\" +#define NETARTDIR "netart\\" + +#define ORDER_NULL 0 +#define ORDER_START 1 +#define ORDER_MOVE 2 +#define ORDER_QUIT 3 + +#define TILE_DEEPSEA 0 +#define TILE_SEA 1 +#define TILE_SHALLOWSEA 2 +#define TILE_SWAMP 3 +#define TILE_GRASS 4 +#define TILE_BRUSH 5 +#define TILE_FOREST 6 +#define TILE_HILLS 7 +#define TILE_MOUNTAINS 8 +#define TILE_DUNGEON 9 +#define TILE_TOWN 10 +#define TILE_CASTLE 11 +#define TILE_VILLAGE 12 + +#define SCREENCX 640 +#define SCREENCY 480 +#define SCREENTILESX 20 +#define SCREENTILESY 15 +#define SCROLLCX 672 +#define SCROLLCY 512 +#define SCROLLTILESX 21 +#define SCROLLTILESY 16 +#define TILES 16 +#define TILECX 32 +#define TILECY 32 +#define WORLDMAPCX 256 +#define WORLDMAPCY 256 + +LPBYTE cursor = NULL; +POINT cursorpos = {0,0}; +DWORD localplayer = 0; +POINT orderpos[MAXPLAYERS]; +PALETTEENTRY pe[256]; +LPBYTE player = NULL; +POINT playerpos[MAXPLAYERS]; +DWORD players = 0; +LPBYTE scrollbuffer = NULL; +POINT scrollpos; +POINT scrollvel = {0,0}; +BOOL started = 0; +LPBYTE tileset = NULL; +LPBYTE worldmap = NULL; + +BOOL CALLBACK CreateCallback (SNETCREATEDATAPTR createdata, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); +BOOL LoadGraphicsData (); +void MovePlayer (DWORD player); +void CALLBACK OnButtonDown (LPPARAMS params); +void CALLBACK OnClose (LPPARAMS params); +void CALLBACK OnEraseBkgnd (LPPARAMS params); +void CALLBACK OnPaint (LPPARAMS params); +void CALLBACK OnVkEscape (LPPARAMS params); +void CALLBACK OnVkSpace (LPPARAMS params); +BOOL ProcessOrders (); +BOOL UpdateScrollVelocity (); + +//=========================================================================== +BOOL CALLBACK ArtCallback (DWORD providerid, + DWORD artid, + LPPALETTEENTRY pe, + LPBYTE buffer, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + + char filename[MAX_PATH] = ""; + + if (providerid == 'BNET') { + // Check for battlenet specific art + switch (artid) { + + case SNET_ART_BACKGROUND: strcpy(filename,NETARTDIR "chat_bkg.pcx"); break; + case SNET_ART_BATTLE_LISTBOX: strcpy(filename, NETARTDIR "bnlist.pcx"); break; + + case SNET_ART_BATTLE_BTNS: strcpy(filename, NETARTDIR "bnbuttns.pcx"); break; + + case SNET_ART_BATTLE_HELP_BKG: strcpy(filename, NETARTDIR "lpopup.pcx"); break; + case SNET_ART_JOINBACKGROUND: strcpy(filename, NETARTDIR "bnjoinbg.pcx"); break; + + case SNET_ART_BATTLE_REDLAG: strcpy(filename, NETARTDIR "redlag.pcx"); break; + case SNET_ART_BATTLE_YELLOWLAG: strcpy(filename, NETARTDIR "yellolag.pcx"); break; + case SNET_ART_BATTLE_GREENLAG: strcpy(filename, NETARTDIR "greenlag.pcx"); break; + } + + } + else if ((providerid == 'IPXN') || (providerid == 'TEST')) { + switch (artid) { + case SNET_ART_BACKGROUND: strcpy(filename, NETARTDIR "ipx_bkg.pcx"); break; + } + } + else if (providerid == 0) { + switch (artid) { + case SNET_ART_BACKGROUND: strcpy(filename, NETARTDIR "connect.pcx"); break; + } + } + + if (!filename[0]) { + // Check for generic artwork + switch (artid) { + case SNET_ART_JOINBACKGROUND: // fall through + case SNET_ART_BACKGROUND: strcpy(filename,NETARTDIR "menu.pcx"); break; + case SNET_ART_BUTTONTEXTURE: strcpy(filename,NETARTDIR "but_lrg.pcx"); break; + case SNET_ART_POPUPBACKGROUND: strcpy(filename,NETARTDIR "lpopup.pcx"); break; + case SNET_ART_HELPBACKGROUND: strcpy(filename,NETARTDIR "lpopup.pcx"); break; + + case SNET_ART_BUTTON_XSML: strcpy(filename,NETARTDIR "but_xsm.pcx"); break; + case SNET_ART_BUTTON_SML: strcpy(filename,NETARTDIR "but_sml.pcx"); break; + case SNET_ART_BUTTON_MED: strcpy(filename,NETARTDIR "but_med.pcx"); break; + case SNET_ART_BUTTON_LRG: strcpy(filename,NETARTDIR "but_lrg.pcx"); break; + } + } + + if (filename[0]) + return SBmpLoadImage(filename,pe,buffer,buffersize,width,height,bitdepth); + else + return 0; + +} + +//=========================================================================== +void ChooseStartingLocations () { + for (DWORD loop = 0; loop < MAXPLAYERS; ++loop) { + BOOL found = 0; + while (!found) { + int x = rand() % WORLDMAPCX; + int y = rand() % WORLDMAPCY; + if (*(worldmap+y*WORLDMAPCX+x) == TILE_GRASS) { + found = 1; + for (DWORD loop2 = 1; loop2 < loop; ++loop2) + if ((playerpos[loop2].x == x) && (playerpos[loop2].y == y)) + found = 0; + if (found) { + orderpos[loop].x = x; + orderpos[loop].y = y; + playerpos[loop].x = x; + playerpos[loop].y = y; + } + } + } + } +} + +//=========================================================================== +BOOL Connect () { + + // BUILD A PROGRAM DATA RECORD + SNETPROGRAMDATA programdata; + ZeroMemory(&programdata,sizeof(SNETPROGRAMDATA)); + programdata.size = sizeof(SNETPROGRAMDATA); + programdata.programname = TITLE; + programdata.programid = PROGRAMID; + programdata.versionid = VERSIONID; + programdata.maxplayers = MAXPLAYERS; + + // GENERATE A PLAYER NAME + char computername[MAX_COMPUTERNAME_LENGTH+1] = ""; + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + GetComputerName(computername,&size); + + // BUILD A PLAYER DATA RECORD + SNETPLAYERDATA playerdata; + ZeroMemory(&playerdata,sizeof(SNETPLAYERDATA)); + playerdata.size = sizeof(SNETPLAYERDATA); + playerdata.playername = computername; + + // BUILD AN INTERFACE DATA RECORD + SNETUIDATA interfacedata; + ZeroMemory(&interfacedata,sizeof(SNETUIDATA)); + interfacedata.size = sizeof(SNETUIDATA); + interfacedata.parentwindow = SDrawGetFrameWindow(); + interfacedata.artcallback = ArtCallback; + interfacedata.createcallback = CreateCallback; + + // SELECT A NETWORK PROVIDER + while (SNetSelectProvider(NULL, + &programdata, + &playerdata, + &interfacedata, + NULL, + NULL)) { + + // SELECT A GAME + if (SNetSelectGame(0, + &programdata, + &playerdata, + &interfacedata, + NULL, + &localplayer)) + return 1; + + } + return 0; +} + +//=========================================================================== +BOOL CALLBACK ConnectIdleProc (DWORD) { + DWORD currtime = GetTickCount(); + + // TWICE A SECOND, UPDATE THE LIST OF PLAYERS + { + static DWORD lasttime = 0; + if (currtime-lasttime > 1000) + lasttime = currtime-500; + while (currtime-lasttime >= 500) { + + // DRAW THE LIST + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + SNetGetNumPlayers(NULL,&players,NULL); + ++players; + for (DWORD loop = 0; loop < players; ++loop) { + char buffer[SNET_MAXNAMELENGTH+2] = "0 "; + buffer[0] += (char)loop; + if (SNetGetPlayerName(loop,buffer+2,SNET_MAXNAMELENGTH)) + SGdiTextOut(videobuffer,4,loop*20,PALETTEINDEX(255-loop),buffer); + } + SGdiTextOut(videobuffer,440,20,PALETTEINDEX(255),"PRESS SPACE TO START"); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + + lasttime += 500; + } + } + + // FOUR TIMES A SECOND, PROCESS ORDERS + { + static DWORD lasttime = 0; + if (currtime-lasttime > 1000) + lasttime = currtime-250; + while (currtime-lasttime >= 250) { + if (ProcessOrders()) + lasttime += 250; + else + lasttime = GetTickCount(); + currtime = GetTickCount(); + } + } + + return 1; +} + +//=========================================================================== +BOOL CALLBACK CreateCallback (SNETCREATEDATAPTR createdata, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + return SNetCreateGame(playerdata->playername, + NULL, + NULL, + 0, + NULL, + 0, + createdata->maxplayers, + playerdata->playername, + NULL, + playerid); +} + +//=========================================================================== +BOOL CreateScrollBuffer () { + scrollbuffer = (LPBYTE)ALLOC(SCROLLTILESX*TILECX*SCROLLTILESY*TILECY); + return (scrollbuffer != NULL); +} + +//=========================================================================== +void Destroy () { + if (cursor) { + FREE(cursor); + cursor = NULL; + } + if (player) { + FREE(player); + player = NULL; + } + if (scrollbuffer) { + FREE(scrollbuffer); + scrollbuffer = NULL; + } + if (tileset) { + FREE(tileset); + tileset = NULL; + } + if (worldmap) { + FREE(worldmap); + worldmap = NULL; + } +} + +//=========================================================================== +void DrawScreen () { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_BACK,NULL,&videobuffer,&pitch)) { + int startx = scrollpos.x % SCROLLCX; + int starty = scrollpos.y % SCROLLCY; + + // BLT FROM THE SCROLL BUFFER ONTO THE BACK SURFACE + SBltROP3(videobuffer, + scrollbuffer+starty*SCROLLCX+startx, + min(SCREENCX,SCROLLCX-startx), + min(SCREENCY,SCROLLCY-starty), + pitch, + SCROLLCX, + 0, + SRCCOPY); + if (SCROLLCX-startx < SCREENCX) + SBltROP3(videobuffer+SCROLLCX-startx, + scrollbuffer+starty*SCROLLCX, + SCREENCX+startx-SCROLLCX, + min(SCREENCY,SCROLLCY-starty), + pitch, + SCROLLCX, + 0, + SRCCOPY); + if (SCROLLCY-starty < SCREENCY) + SBltROP3(videobuffer+(SCROLLCY-starty)*pitch, + scrollbuffer+startx, + min(SCREENCX,SCROLLCX-startx), + SCREENCY+starty-SCROLLCY, + pitch, + SCROLLCX, + 0, + SRCCOPY); + if ((SCROLLCX-startx < SCREENCX) && + (SCROLLCY-starty < SCREENCY)) + SBltROP3(videobuffer+(SCROLLCY-starty)*pitch+SCROLLCX-startx, + scrollbuffer, + SCREENCX+startx-SCROLLCX, + SCREENCY+starty-SCROLLCY, + pitch, + SCROLLCX, + 0, + SRCCOPY); + + // DRAW THE MOUSE CURSOR ONTO THE BACK SURFACE + if (started) { + GetCursorPos(&cursorpos); + SBltROP3(videobuffer+cursorpos.y*pitch+cursorpos.x, + cursor, + min(32,SCREENCX-cursorpos.x), + min(32,SCREENCY-cursorpos.y), + pitch, + 32, + 0, + SRCPAINT); + } + + SDrawUnlockSurface(SDRAW_SURFACE_BACK,videobuffer); + SDrawFlipPage(); + } +} + +//=========================================================================== +void FillScrollBuffer (LPRECT rect) { + int startxtile = scrollpos.x/TILECX; + int startytile = scrollpos.y/TILECY; + int startxpos = (scrollpos.x % SCROLLCX)/TILECX; + int startypos = (scrollpos.y % SCROLLCY)/TILECY; + for (int y = rect->top; y <= rect->bottom; ++y) { + int mapy = startytile+y+((y >= startypos) ? 0 : SCROLLTILESY)-startypos; + for (int x = rect->left; x <= rect->right; ++x) { + int mapx = startxtile+x+((x >= startxpos) ? 0 : SCROLLTILESX)-startxpos; + int tile = min(TILES-1,*(worldmap+mapy*WORLDMAPCX+mapx)); + SBltROP3(scrollbuffer+y*TILECY*SCROLLCX+x*TILECX, + tileset+tile*TILECX, + TILECX, + TILECY, + SCROLLCX, + TILES*TILECX, + 0, + SRCCOPY); + } + } + for (DWORD loop = 0; loop < players; ++loop) { + if ((playerpos[loop].x >= startxtile) && + (playerpos[loop].y >= startytile) && + (playerpos[loop].x < startxtile+SCROLLTILESX) && + (playerpos[loop].y < startytile+SCROLLTILESY)) { + int posx = (startxpos+(playerpos[loop].x-startxtile)) % SCROLLTILESX; + int posy = (startypos+(playerpos[loop].y-startytile)) % SCROLLTILESY; + if ((posx >= rect->left) && (posx <= rect->right) && + (posy >= rect->top) && (posy <= rect->bottom)) { + DWORD pattern = ((255-loop) << 24) | ((255-loop) << 16) | ((255-loop) << 8) | (255-loop); + // pattern 11110000 + // source 11001100 + // dest 10101010 + // -------- + // rop 11100010 = 0xE2 + SBltROP3(scrollbuffer+posy*TILECY*SCROLLCX+posx*TILECX, + player, + TILECX, + TILECY, + SCROLLCX, + TILECX, + pattern, + 0xE20746); + } + } + } +} + +//=========================================================================== +BOOL CALLBACK GameIdleProc (DWORD) { + DWORD currtime = GetTickCount(); + + // FOUR TIMES A SECOND, MOVE THE PLAYERS + { + static DWORD lasttime = GetTickCount(); + if (currtime-lasttime > 1000) + lasttime = currtime-250; + while (currtime-lasttime >= 250) { + for (DWORD loop = 0; loop < players; ++loop) + MovePlayer(loop); + RECT rect = {0,0,SCROLLTILESX-1,SCROLLTILESY-1}; + FillScrollBuffer(&rect); + lasttime += 250; + } + } + + // TWICE A SECOND, PROCESS ORDERS + { + static DWORD lasttime = GetTickCount(); + if (currtime-lasttime > 2000) + lasttime = currtime-500; + while (currtime-lasttime >= 500) { + if (ProcessOrders()) + lasttime += 500; + else + lasttime = GetTickCount(); + currtime = GetTickCount(); + } + } + + // PROCESS SCROLLING + if (UpdateScrollVelocity()) { + + // UPDATE THE SCROLL POSITION + POINT oldscrollpos = scrollpos; + scrollpos.x = max(0,min(WORLDMAPCX*TILECX-SCROLLCX,scrollpos.x+scrollvel.x)); + scrollpos.y = max(0,min(WORLDMAPCY*TILECY-SCROLLCY,scrollpos.y+scrollvel.y)); + + // UPDATE THE SCROLL BUFFER + if (scrollpos.x/TILECX != oldscrollpos.x/TILECX) { + int updatex = (scrollvel.x > 0) ? (oldscrollpos.x % SCROLLCX)/TILECX + : (scrollpos.x % SCROLLCX)/TILECX; + RECT rect = {updatex,0,updatex,SCROLLTILESY-1}; + FillScrollBuffer(&rect); + } + if (scrollpos.y/TILECY != oldscrollpos.y/TILECY) { + int updatey = (scrollvel.y > 0) ? (oldscrollpos.y % SCROLLCY)/TILECY + : (scrollpos.y % SCROLLCY)/TILECY; + RECT rect = {0,updatey,SCROLLTILESX-1,updatey}; + FillScrollBuffer(&rect); + } + + } + + // DRAW THE SCREEN + DrawScreen(); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD count) { + if (started) + return GameIdleProc(count); + else + return ConnectIdleProc(count); +} + +//=========================================================================== +void IssueOrder (LPDWORD paramarray, DWORD paramcount) { + SNetSendTurn(paramarray, + paramcount*sizeof(DWORD)); +} + +//=========================================================================== +BOOL Initialize (HINSTANCE instance) { + if (!SDrawAutoInitialize(instance, + TITLE "_CLASS", + TITLE, + NULL, + SDRAW_SERVICE_PAGEFLIP)) { + SDrawMessageBox("Unable to initialize DirectDraw.",TITLE,0); + return 0; + } + if (!LoadGraphicsData()) { + SDrawMessageBox("Unable to load graphics data.",TITLE,0); + return 0; + } + if (!CreateScrollBuffer()) { + SDrawMessageBox("Out of memory.",TITLE,0); + return 0; + } + SMsgRegisterMessage(NULL,WM_ERASEBKGND,OnEraseBkgnd); + if (!Connect()) + return 0; + ChooseStartingLocations(); + scrollpos.x = max(0,min(WORLDMAPCX*TILECX-SCROLLCX,playerpos[localplayer].x*TILECX-SCROLLCX/2)); + scrollpos.y = max(0,min(WORLDMAPCY*TILECY-SCROLLCY,playerpos[localplayer].y*TILECY-SCROLLCY/2)); + SDrawUpdatePalette(0,256,&pe[0]); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_LBUTTONDOWN,OnButtonDown); + SMsgRegisterMessage(NULL,WM_PAINT ,OnPaint); + SMsgRegisterMessage(NULL,WM_RBUTTONDOWN,OnButtonDown); + SMsgRegisterKeyDown(NULL,VK_ESCAPE ,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + return 1; +} + +//=========================================================================== +BOOL LoadGraphicsData () { + + // LOAD IN THE CURSOR + cursor = (LPBYTE)ALLOC(32*32); + if (!cursor) + return 0; + if (!SBmpLoadImage(ARTDIR "cursor.pcx",NULL,cursor,32*32)) + return 0; + + // LOAD IN THE PLAYER IMAGE + player = (LPBYTE)ALLOC(32*32); + if (!player) + return 0; + if (!SBmpLoadImage(ARTDIR "player.pcx",NULL,player,32*32)) + return 0; + + // LOAD IN THE WORLD MAP + worldmap = (LPBYTE)ALLOC(WORLDMAPCX*WORLDMAPCY); + if (!worldmap) + return 0; + if (!SBmpLoadImage(ARTDIR "map.pcx",NULL,worldmap,WORLDMAPCX*WORLDMAPCY)) + return 0; + + // LOAD IN THE GRAPHICS TILESET + tileset = (LPBYTE)ALLOC(TILES*TILECX*TILECY); + if (!tileset) + return 0; + if (!SBmpLoadImage(ARTDIR "tileset.pcx",&pe[0],tileset,TILES*TILECX*TILECY)) + return 0; + + // CREATE A FONT + HSGDIFONT font; + { + HFONT winfont = CreateFont(-17,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_ROMAN,TEXT("Times New Roman")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + + return 1; +} + +//=========================================================================== +void MovePlayer (DWORD player) { + int xdir = orderpos[player].x-playerpos[player].x; + xdir = (xdir > 0) ? 1 : xdir ? -1 : 0; + int ydir = orderpos[player].y-playerpos[player].y; + ydir = (ydir > 0) ? 1 : ydir ? -1 : 0; + if (xdir) { + BYTE tile = *(worldmap+playerpos[player].y*WORLDMAPCX+playerpos[player].x+xdir); + if ((tile >= TILE_GRASS) && (tile != TILE_MOUNTAINS)) + playerpos[player].x += xdir; + } + if (ydir) { + BYTE tile = *(worldmap+(playerpos[player].y+ydir)*WORLDMAPCX+playerpos[player].x); + if ((tile >= TILE_GRASS) && (tile != TILE_MOUNTAINS)) + playerpos[player].y += ydir; + } +} + +//=========================================================================== +void CALLBACK OnButtonDown (LPPARAMS params) { + if (started) { + DWORD order[3] = {ORDER_MOVE, + (scrollpos.x+LOWORD(params->lparam))/TILECX, + (scrollpos.y+HIWORD(params->lparam))/TILECY}; + IssueOrder(&order[0],3); + } +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS) { + Destroy(); +} + +//=========================================================================== +void CALLBACK OnEraseBkgnd (LPPARAMS params) { + params->useresult = 1; + params->result = 1; +} + +//=========================================================================== +void CALLBACK OnPaint (LPPARAMS params) { + if (scrollbuffer && tileset) { + RECT rect = {0,0,SCROLLTILESX-1,SCROLLTILESY-1}; + FillScrollBuffer(&rect); + DrawScreen(); + } +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + DWORD order = ORDER_QUIT; + IssueOrder(&order,1); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + if (!started) { + DWORD order = ORDER_START; + IssueOrder(&order,1); + } +} + +//=========================================================================== +BOOL ProcessOrders () { + + // MAKE SURE THERE ARE ALWAYS AT LEAST TWO ORDERS IN TRANSIT + { + DWORD turns; + if (SNetGetTurnsInTransit(&turns)) { + while (turns < 2) { + DWORD order = ORDER_NULL; + IssueOrder(&order,1); + ++turns; + } + } + } + + // GATHER ORDERS FROM ALL PLAYERS + LPDWORD data[MAXPLAYERS]; + DWORD databytes[MAXPLAYERS]; + DWORD playerstatus[MAXPLAYERS]; + BOOL insync = 1; + { + int timeout = 20; + while ((!SNetReceiveTurns(0,players,(LPVOID *)&data[0],&databytes[0],&playerstatus[0])) && + --timeout) { + insync = 0; + Sleep(50); + } + if (!timeout) { + SDrawMessageBox("network error",TITLE,0); + SDrawPostClose(); + } + } + + // PROCESS EACH PLAYER'S ORDERS + for (DWORD player = 0; player < players; ++player) + if (data[player] && databytes[player]) + switch (*data[player]) { + + case ORDER_START: + started = 1; + break; + + case ORDER_MOVE: + orderpos[player].x = *(data[player]+1); + orderpos[player].y = *(data[player]+2); + break; + + case ORDER_QUIT: + SDrawPostClose(); + break; + + } + + return insync; +} + +//=========================================================================== +BOOL UpdateScrollVelocity () { + + // DETERMINE THE SCROLL DIRECTION + POINT pos; + GetCursorPos(&pos); + int x = (pos.x == 639) ? 1 : pos.x ? 0 : -1; + int y = (pos.y == 479) ? 1 : pos.y ? 0 : -1; + int velx = (scrollvel.x > 0) ? 1 : scrollvel.x ? -1 : 0; + int vely = (scrollvel.y > 0) ? 1 : scrollvel.y ? -1 : 0; + + // UPDATE THE X VELOCITY + if (x) { + if ((velx != x) || (abs(scrollvel.x) < 24)) + scrollvel.x += (abs(scrollvel.x) > 12) ? 2*x : x; + } + else if (velx) + scrollvel.x -= velx; + + // UPDATE THE Y VELOCITY + if (y) { + if ((vely != y) || (abs(scrollvel.y) < 16)) + scrollvel.y += (abs(scrollvel.y) > 8) ? 2*y : y; + } + else if (vely) + scrollvel.y -= vely; + + return (scrollvel.x || scrollvel.y); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!Initialize(instance)) { + Destroy(); + return 1; + } + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/SNET/RPG/RPG.CS b/Storm/SAMPLES/SNET/RPG/RPG.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SNET/RPG/RPG.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SNET/RPG/RPG.EXE b/Storm/SAMPLES/SNET/RPG/RPG.EXE new file mode 100644 index 0000000..b483e4d Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/RPG.EXE differ diff --git a/Storm/SAMPLES/SNET/RPG/RPG.RC b/Storm/SAMPLES/SNET/RPG/RPG.RC new file mode 100644 index 0000000..9d9c0f3 --- /dev/null +++ b/Storm/SAMPLES/SNET/RPG/RPG.RC @@ -0,0 +1,105 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Blizzard Entertainment\0" + VALUE "FileDescription", "RPG Example\0" + VALUE "FileVersion", "1.0\0" + VALUE "InternalName", "RPG\0" + VALUE "LegalCopyright", "Copyright © 1996, Blizzard Entertainment\0" + VALUE "OriginalFilename", "RPG.exe\0" + VALUE "ProductName", "RPG Example\0" + VALUE "ProductVersion", "1.0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SAMPLES/SNET/RPG/STANDARD.SNP b/Storm/SAMPLES/SNET/RPG/STANDARD.SNP new file mode 100644 index 0000000..8366cf5 Binary files /dev/null and b/Storm/SAMPLES/SNET/RPG/STANDARD.SNP differ diff --git a/Storm/SAMPLES/SRGN/BENCH/BENCH.CPP b/Storm/SAMPLES/SRGN/BENCH/BENCH.CPP new file mode 100644 index 0000000..8a3b139 --- /dev/null +++ b/Storm/SAMPLES/SRGN/BENCH/BENCH.CPP @@ -0,0 +1,100 @@ +/**************************************************************************** +* +* BENCH.CPP +* +* This program benchmarks the performance of Storm's region manager. +* +***/ + +#include +#include +#include + +#define TESTRECTS 3 +#define MAXCOMBINEDRECS 64 + +const RECT testrect[TESTRECTS] = {{100,100,300,300}, + {200,200,400,400}, + {100,300,300,500}}; + +//=========================================================================== +static void TestStorm (BOOL print) { + CSRgn rgn; + + for (DWORD loop = 0; loop < TESTRECTS; ++loop) + rgn.AddRect(&testrect[loop],NULL); + + RECT rectarray[MAXCOMBINEDRECS]; + DWORD numrects = MAXCOMBINEDRECS; + rgn.GetRects(&numrects,&rectarray[0]); + + if (print) { + printf("Storm\n"); + for (DWORD loop = 0; loop < numrects; ++loop) + printf("%u (%d,%d)-(%d,%d)\n", + loop, + rectarray[loop].left, + rectarray[loop].top, + rectarray[loop].right, + rectarray[loop].bottom); + printf("\n"); + } +} + +//=========================================================================== +static void TestWindows (BOOL print) { + HRGN rgn = CreateRectRgn(testrect[0].left, + testrect[0].top, + testrect[0].right, + testrect[0].bottom); + + for (DWORD loop = 1; loop < TESTRECTS; ++loop) { + HRGN newrgn = CreateRectRgn(testrect[loop].left, + testrect[loop].top, + testrect[loop].right, + testrect[loop].bottom); + CombineRgn(rgn,rgn,newrgn,RGN_OR); + DeleteObject(newrgn); + } + +#define BUFFERSIZE sizeof(RGNDATA)+MAXCOMBINEDRECS*sizeof(RECT) + BYTE buffer[BUFFERSIZE]; + RGNDATA *data = (RGNDATA *)&buffer[0]; + DWORD numrects = GetRegionData(rgn,BUFFERSIZE,data); +#undef BUFFERSIZE + + if (print) { + printf("Windows\n"); + for (DWORD loop = 0; loop < data->rdh.nCount; ++loop) + printf("%u (%d,%d)-(%d,%d)\n", + loop, + (((LPRECT)&data->Buffer[0])+loop)->left, + (((LPRECT)&data->Buffer[0])+loop)->top, + (((LPRECT)&data->Buffer[0])+loop)->right, + (((LPRECT)&data->Buffer[0])+loop)->bottom); + printf("\n"); + } + + DeleteObject(rgn); +} + +//=========================================================================== +static DWORD Benchmark (void (*func)(BOOL)) { + DWORD iterations = 0; + DWORD start = GetTickCount(); + while (GetTickCount()-start < 1000) + for (DWORD loop = 0; loop < 10; ++loop) { + func(FALSE); + ++iterations; + } + return iterations; +} + +//=========================================================================== +int __cdecl main () { + TestStorm(TRUE); + TestWindows(TRUE); + printf("Storm: %u iterations/sec\n",Benchmark(TestStorm)); + printf("Windows: %u iterations/sec\n",Benchmark(TestWindows)); + return 0; +} diff --git a/Storm/SAMPLES/SRGN/BENCH/BENCH.CS b/Storm/SAMPLES/SRGN/BENCH/BENCH.CS new file mode 100644 index 0000000..eb521a7 --- /dev/null +++ b/Storm/SAMPLES/SRGN/BENCH/BENCH.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/SRGN/BENCH/BENCH.EXE b/Storm/SAMPLES/SRGN/BENCH/BENCH.EXE new file mode 100644 index 0000000..4ee3379 Binary files /dev/null and b/Storm/SAMPLES/SRGN/BENCH/BENCH.EXE differ diff --git a/Storm/SAMPLES/SSTR/BENCH/BENCH.CPP b/Storm/SAMPLES/SSTR/BENCH/BENCH.CPP new file mode 100644 index 0000000..910e554 --- /dev/null +++ b/Storm/SAMPLES/SSTR/BENCH/BENCH.CPP @@ -0,0 +1,57 @@ +/**************************************************************************** +* +* SSTR.CPP +* +* Benchmarks Storm's pattern blt performance. +* +***/ + +#include +#include +#include + +#define BENCHMARK(name,expr,reset) \ + do { \ + DWORD start = GetTickCount(); \ + DWORD curr; \ + while ((curr = GetTickCount()) == start) \ + ; \ + start = curr; \ + int dummy = 0; \ + DWORD iterations = 0; \ + while (GetTickCount()-start < 1000) { \ + for (int loop = 0; loop < 1000; ++loop) { \ + (expr); \ + (reset); \ + } \ + iterations += 1000; \ + } \ + printf("%-20s %7u/sec\n",(name),iterations); \ + } while (0) + + +//=========================================================================== +int __cdecl main () { + char buffer[] = "this is a test"; + char buffer2[256]; + BENCHMARK("strcpy()" ,strcpy(buffer2,buffer) ,0); + BENCHMARK("strncpy()" ,strncpy(buffer2,buffer,256) ,0); + BENCHMARK("lstrcpy()" ,lstrcpy(buffer2,buffer) ,0); + BENCHMARK("lstrcpyn()",lstrcpyn(buffer2,buffer,256),0); + BENCHMARK("SStrCopy()",SStrCopy(buffer2,buffer,256),0); + printf("\n"); + BENCHMARK("strcat()" ,strcat(buffer2,buffer) ,buffer2[14] = 0); + BENCHMARK("strncat()" ,strncat(buffer2,buffer,256-14),buffer2[14] = 0); + BENCHMARK("lstrcat()" ,lstrcat(buffer2,buffer) ,buffer2[14] = 0); + BENCHMARK("SStrPack()",SStrPack(buffer2,buffer,256) ,buffer2[14] = 0); + printf("\n"); + BENCHMARK("strlen()" ,dummy += strlen(buffer) ,0); + BENCHMARK("lstrlen()" ,dummy += lstrlen(buffer),0); + BENCHMARK("SStrLen()" ,dummy += SStrLen(buffer),0); + printf("\n"); + BENCHMARK("strchr()" ,dummy += (strchr(buffer,' ') != NULL) ,0); + BENCHMARK("SStrChr()" ,dummy += (SStrChr(buffer,' ') != NULL),0); + printf("\n"); + return 0; +} + diff --git a/Storm/SAMPLES/SSTR/BENCH/BENCH.CS b/Storm/SAMPLES/SSTR/BENCH/BENCH.CS new file mode 100644 index 0000000..eb521a7 --- /dev/null +++ b/Storm/SAMPLES/SSTR/BENCH/BENCH.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/SSTR/BENCH/BENCH.EXE b/Storm/SAMPLES/SSTR/BENCH/BENCH.EXE new file mode 100644 index 0000000..d1e04b1 Binary files /dev/null and b/Storm/SAMPLES/SSTR/BENCH/BENCH.EXE differ diff --git a/Storm/SAMPLES/SSTR/CHECK/CHECK.CPP b/Storm/SAMPLES/SSTR/CHECK/CHECK.CPP new file mode 100644 index 0000000..028c4b8 --- /dev/null +++ b/Storm/SAMPLES/SSTR/CHECK/CHECK.CPP @@ -0,0 +1,195 @@ +/**************************************************************************** +* +* CHECK.CPP +* +* Checks the functionality of SStr functions +* +***/ + +#include +#include +#include + +#define FILLCHAR1 0x11 +#define FILLCHAR2 0x22 +#define FINDCHAR 100 +#define MAXLEN 260 +#define BUFFERSIZE (MAXLEN+2*sizeof(DWORD)+2) +#define FMTSTRING "Checking %-12s " + +#define FATALERROR \ + do { \ + printf("FAILURE!\n" \ + " str1len=%u\n" \ + " str1ofs=%u\n" \ + " str2len=%u\n" \ + " str2ofs=%u\n", \ + str1len, \ + str1ofs, \ + str2len, \ + str2ofs); \ + for (DWORD loop = 0; loop < BUFFERSIZE; ++loop) { \ + printf("%02x ",(DWORD)(BYTE)str1[loop]); \ + if ((loop & 15) == 15) \ + printf("\n"); \ + } \ + exit(1); \ + } while (0) + +#define ALLOCBUF \ + LPTSTR str1 = (LPTSTR)ALLOC(BUFFERSIZE); \ + LPTSTR str2 = (LPTSTR)ALLOC(BUFFERSIZE); \ + LPTSTR src = (LPTSTR)ALLOC(BUFFERSIZE) + +#define FREEBUF \ + FREE(str1); \ + FREE(str2); \ + FREE(src) + +#define ITERATE_1LEVEL \ + DWORD str2len = 0; \ + DWORD str2ofs = 0; \ + for (DWORD str1len = 0; str1len < MAXLEN; ++str1len) \ + for (DWORD str1ofs = 0; str1ofs < sizeof(DWORD); ++str1ofs) + +#define ITERATE_2LEVEL \ + for (DWORD str1len = 0; str1len < MAXLEN; ++str1len) \ + for (DWORD str1ofs = 0; str1ofs < sizeof(DWORD); ++str1ofs) \ + for (DWORD str2len = 0; str2len < MAXLEN; ++str2len) \ + for (DWORD str2ofs = 0; str2ofs <= sizeof(DWORD); ++str2ofs) + +#define RESETBUF \ + FillMemory(str1,BUFFERSIZE,FILLCHAR1); \ + FillMemory(str2,BUFFERSIZE,FILLCHAR2) + +#define BUILDSOURCE \ + do { \ + for (DWORD loop = 0; loop < BUFFERSIZE; ++loop) \ + src[loop] = ' '+(BYTE)(loop & 0x3F); \ + } while (0) + +#define COPYSOURCE(buffer,length) \ + if (length > 0) \ + CopyMemory((buffer),src,(length)); \ + (buffer)[(length)] = 0 + +#define SHOWPROGRESS \ + static DWORD iterations; \ + if (!(++iterations & 0xFFFF)) \ + printf(".") + +#define CHECKBEGIN \ + DWORD check = 0; \ + DWORD checkstart + +#define CHECK_FILLCHAR(num) \ + for (checkstart = check; check < checkstart+(num); ++check) \ + if (str1[check] != FILLCHAR1) \ + FATALERROR + +#define CHECK_SOURCE(num) \ + for (checkstart = check; check+1 < checkstart+(num); ++check) \ + if (str1[check] != src[check-checkstart]) \ + FATALERROR + +#define CHECK_NULL(num) \ + for (checkstart = check; check < checkstart+(num); ++check) \ + if (str1[check]) \ + FATALERROR + +#define CHECKEND + +//=========================================================================== +static void CheckSStrChr () { + printf(FMTSTRING,"SStrChr()"); + ALLOCBUF; + BUILDSOURCE; + ITERATE_2LEVEL { + RESETBUF; + COPYSOURCE(str1+str1ofs,BUFFERSIZE-str1ofs-1); + str1[str1ofs+str1len] = FINDCHAR; + str1[str1ofs+str2len] = FINDCHAR; + LPTSTR first = str1+str1ofs+min(str1len,str2len); + LPTSTR last = str1+str1ofs+max(str1len,str2len); + if (SStrChr(str1+str1ofs,FINDCHAR) != first) + FATALERROR; + if (SStrChr(str1+str1ofs,FINDCHAR,TRUE) != last) + FATALERROR; + SHOWPROGRESS; + } + FREEBUF; + printf(" done\n"); +} + +//=========================================================================== +static void CheckSStrCopy () { + printf(FMTSTRING,"SStrCopy()"); + ALLOCBUF; + BUILDSOURCE; + ITERATE_2LEVEL { + RESETBUF; + COPYSOURCE(str2+str2ofs,str2len); + SStrCopy(str1+str1ofs,str2+str2ofs,str1len); + CHECKBEGIN; + CHECK_FILLCHAR(str1ofs); + CHECK_SOURCE(min(str1len,str2len+1)); + CHECK_NULL(str1len ? 1 : 0); + CHECK_FILLCHAR(BUFFERSIZE-checkstart); + CHECKEND; + SHOWPROGRESS; + } + FREEBUF; + printf(" done\n"); +} + +//=========================================================================== +static void CheckSStrLen () { + printf(FMTSTRING,"SStrLen()"); + ALLOCBUF; + BUILDSOURCE; + ITERATE_1LEVEL { + RESETBUF; + COPYSOURCE(str1+str1ofs,str1len); + if (SStrLen(str1+str1ofs) != str1len) + FATALERROR; + SHOWPROGRESS; + } + FREEBUF; + printf("done\n"); +} + +//=========================================================================== +static void CheckSStrPack () { + printf(FMTSTRING,"SStrPack()"); + ALLOCBUF; + BUILDSOURCE; + ITERATE_2LEVEL { + RESETBUF; + COPYSOURCE(str1+str1ofs,str1len); + COPYSOURCE(str2+str2ofs,str2len); + DWORD bufferlen = BUFFERSIZE-str1ofs; + SStrPack(str1+str1ofs,str2+str2ofs,bufferlen); + CHECKBEGIN; + CHECK_FILLCHAR(str1ofs); + CHECK_SOURCE(str1len+1); + CHECK_SOURCE(min(bufferlen-str1len,str2len+1)); + CHECK_NULL(1); + CHECK_FILLCHAR(BUFFERSIZE-checkstart-1); + if (check < BUFFERSIZE) + CHECK_NULL(1); + CHECKEND; + SHOWPROGRESS; + } + FREEBUF; + printf(" done\n"); +} + +//=========================================================================== +int __cdecl main () { + CheckSStrChr(); + CheckSStrCopy(); + CheckSStrLen(); + CheckSStrPack(); + printf("No errors detected.\n"); + return 0; +} diff --git a/Storm/SAMPLES/SSTR/CHECK/CHECK.CS b/Storm/SAMPLES/SSTR/CHECK/CHECK.CS new file mode 100644 index 0000000..eb521a7 --- /dev/null +++ b/Storm/SAMPLES/SSTR/CHECK/CHECK.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/SSTR/CHECK/CHECK.EXE b/Storm/SAMPLES/SSTR/CHECK/CHECK.EXE new file mode 100644 index 0000000..a87b14f Binary files /dev/null and b/Storm/SAMPLES/SSTR/CHECK/CHECK.EXE differ diff --git a/Storm/SAMPLES/STRANS/BENCH/BENCH.CPP b/Storm/SAMPLES/STRANS/BENCH/BENCH.CPP new file mode 100644 index 0000000..702afff --- /dev/null +++ b/Storm/SAMPLES/STRANS/BENCH/BENCH.CPP @@ -0,0 +1,130 @@ +/**************************************************************************** +* +* BENCH.CPP +* +* Benchmarks Storm's transparent bitblt performance. +* +***/ + +#include +#include + +#define ALIGNED + +HSGDIFONT font = (HSGDIFONT)0; +HSTRANS transparency[4] = {0,0,0,0}; +BOOL paused = 0; +DWORD iterations = 0; + +//=========================================================================== +BOOL LoadTransparency () { + LPBYTE bitmap = (LPBYTE)ALLOC(80*80); + if (!bitmap) + return 0; + PALETTEENTRY pe[256]; + if (!SBmpLoadImage("blizlogo.pcx",&pe[0],bitmap,80*80)) + return 0; + SDrawUpdatePalette(0,256,&pe[0]); + for (int loop = 0; loop < 4; ++loop) { + RECT rect = {loop*40,0,loop*40+39,39}; + STransCreate(bitmap,160,40,8,&rect,PALETTEINDEX(0),&transparency[loop]); + } + FREE(bitmap); + return 1; +} + +//=========================================================================== +BOOL LoadFont () { + { + HFONT winfont = CreateFont(-10,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + VARIABLE_PITCH | FF_SWISS,TEXT("Arial")); + if (!SGdiImportFont(winfont,&font)) + return 0; + DeleteObject(winfont); + } + if (!SGdiSelectObject(font)) + return 0; + return 1; +} + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (paused) + return 0; + + static DWORD transnumber = 0; + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + for (int loop = 0; loop < 100; ++loop) { + int left = (rand() % 640)-20; + int top = (rand() % 450)+12; +#ifdef ALIGNED + left = (left >> 2) << 2; +#endif + STransBlt(videobuffer,left,top,pitch,transparency[transnumber++ & 3]); + ++iterations; + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + KillTimer(params->window,1); + SGdiDeleteObject(font); + for (int loop = 0; loop < 4; ++loop) + STransDelete(transparency[loop]); +} + +//=========================================================================== +void CALLBACK OnTimer (LPPARAMS) { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + char outstr[64]; + wsprintf(outstr,"%u transparent bitblts per second",iterations); + RECT rect = {0,0,320,12}; + SGdiSetPitch(pitch); + SGdiExtTextOut(videobuffer, + 0, + 0, + &rect, + 0, + ETO_TEXT_WHITE, + ETO_BKG_BLACK, + outstr); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + iterations = 0; +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int) { + if (!SDrawAutoInitialize(instance, + TEXT("DDBENCH"), + TEXT("Benchmark"))) + return 1; + if (!LoadTransparency()) + return 1; + if (!LoadFont()) + return 1; + SetTimer(SDrawGetFrameWindow(),1,1000,NULL); + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterMessage(NULL,WM_TIMER ,OnTimer); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + return SMsgDoMessageLoop(IdleProc); +} diff --git a/Storm/SAMPLES/STRANS/BENCH/BENCH.CS b/Storm/SAMPLES/STRANS/BENCH/BENCH.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/STRANS/BENCH/BENCH.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/STRANS/BENCH/BENCH.EXE b/Storm/SAMPLES/STRANS/BENCH/BENCH.EXE new file mode 100644 index 0000000..21697e8 Binary files /dev/null and b/Storm/SAMPLES/STRANS/BENCH/BENCH.EXE differ diff --git a/Storm/SAMPLES/STRANS/BENCH/BLIZLOGO.PCX b/Storm/SAMPLES/STRANS/BENCH/BLIZLOGO.PCX new file mode 100644 index 0000000..e7eeaab Binary files /dev/null and b/Storm/SAMPLES/STRANS/BENCH/BLIZLOGO.PCX differ diff --git a/Storm/SAMPLES/SVID/MULTI/MULTI.CPP b/Storm/SAMPLES/SVID/MULTI/MULTI.CPP new file mode 100644 index 0000000..e2ee8a6 --- /dev/null +++ b/Storm/SAMPLES/SVID/MULTI/MULTI.CPP @@ -0,0 +1,85 @@ +/**************************************************************************** +* +* MULTI.CPP +* +* Demonstrates playing back multiple video streams simultaneously. +* +***/ + +#include +#include + +#define VIDEOS 4 + +DWORD started = 0; +HSVIDEO video[VIDEOS] = {0,0,0,0}; + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + + // CHECK WHETHER WE NEED TO START A NEW VIDEO + static DWORD lasttime = 0; + DWORD currtime = GetTickCount(); + if ((currtime-lasttime > 1000) && (started < VIDEOS)) { + RECT rect; + rect.left = (started & 1)*320; + rect.top = (started & 2)*120; + rect.right = rect.left+319; + rect.bottom = rect.top+143; + SVidPlayBegin(TEXT("blizzard.smk"), + NULL,&rect,NULL,NULL, + SVID_FLAG_TOSCREEN | SVID_FLAG_1XSIZE, + &video[started++]); + lasttime = currtime; + } + + // CONTINUE PLAYING VIDEOS + if (!SVidPlayContinue()) + SDrawPostClose(); + + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + for (int loop = 0; loop < VIDEOS; ++loop) + if (video[loop]) + SVidPlayEnd(video[loop]); +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS params) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR cmdline, int) { + + // INTIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("VIDEOCLASS"), + TEXT("Video Player"))) + return 1; + ShowCursor(0); + + // REGISTER WINDOW MESSAGES + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + + // INITIALIZE THE VIDEO PLAYER + if (!SVidInitialize(NULL)) + return 1; + + // PLAY VIDEOS, STARTING A NEW ONE EACH SECOND UNTIL THEY ARE ALL STARTED, + // CONTINUING UNTIL THEY ARE ALL FINISHED + SMsgDoMessageLoop(IdleProc); + + // CLOSE ALL VIDEOS + { + for (DWORD loop = 0; loop < started; ++loop) + SVidPlayEnd(video[loop]); + } + + ShowCursor(1); + return 0; +} diff --git a/Storm/SAMPLES/SVID/MULTI/MULTI.CS b/Storm/SAMPLES/SVID/MULTI/MULTI.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SVID/MULTI/MULTI.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SVID/MULTI/MULTI.EXE b/Storm/SAMPLES/SVID/MULTI/MULTI.EXE new file mode 100644 index 0000000..8423ad8 Binary files /dev/null and b/Storm/SAMPLES/SVID/MULTI/MULTI.EXE differ diff --git a/Storm/SAMPLES/SVID/PAN/PAN.CPP b/Storm/SAMPLES/SVID/PAN/PAN.CPP new file mode 100644 index 0000000..2b4419e --- /dev/null +++ b/Storm/SAMPLES/SVID/PAN/PAN.CPP @@ -0,0 +1,91 @@ +/**************************************************************************** +* +* PAN.CPP +* +* Demonstrates panning the sound for a video. +* +***/ + +#include +#include + +#define VIDEOS 2 + +HSVIDEO video[VIDEOS] = {0,0}; + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + + // CHECK WHETHER WE NEED TO START A NEW VIDEO + static DWORD laststart = 0; + DWORD currtime = GetTickCount(); + for (DWORD loop = 0; loop < VIDEOS; ++loop) + if (video[loop]) { + BOOL updated; + if (!SVidPlayContinueSingle(video[loop],FALSE,&updated)) { + SVidPlayEnd(video[loop]); + video[loop] = (HSVIDEO)0; + } + } + else if (currtime-laststart > 3000) { + laststart = currtime; + RECT rect; + rect.left = (loop & 1)*320; + rect.top = (loop & 1)*240; + rect.right = rect.left+319; + rect.bottom = rect.top+143; + SVidPlayBegin(TEXT("blizzard.smk"), + NULL,&rect,NULL,NULL, + SVID_FLAG_TOSCREEN + | SVID_FLAG_1XSIZE + | SVID_FLAG_NEEDPAN, + &video[loop]); + SVidSetVolume(video[loop], + 0, + loop ? 10000 : -10000); + } + + return TRUE; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + for (int loop = 0; loop < VIDEOS; ++loop) + if (video[loop]) + SVidPlayEnd(video[loop]); +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS params) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR cmdline, int) { + + // INTIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("VIDEOCLASS"), + TEXT("Video Player"))) + return 1; + ShowCursor(0); + + // REGISTER WINDOW MESSAGES + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + + // INITIALIZE THE VIDEO PLAYER + if (!SVidInitialize(NULL)) + return 1; + + // PLAY VIDEOS + SMsgDoMessageLoop(IdleProc); + + // CLOSE ALL VIDEOS + for (DWORD loop = 0; loop < VIDEOS; ++loop) + if (video[loop]) + SVidPlayEnd(video[loop]); + + ShowCursor(1); + return 0; +} diff --git a/Storm/SAMPLES/SVID/PAN/PAN.CS b/Storm/SAMPLES/SVID/PAN/PAN.CS new file mode 100644 index 0000000..ad5af12 --- /dev/null +++ b/Storm/SAMPLES/SVID/PAN/PAN.CS @@ -0,0 +1 @@ +#include "../../sample.cs" diff --git a/Storm/SAMPLES/SVID/PAN/PAN.EXE b/Storm/SAMPLES/SVID/PAN/PAN.EXE new file mode 100644 index 0000000..30725a8 Binary files /dev/null and b/Storm/SAMPLES/SVID/PAN/PAN.EXE differ diff --git a/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.CPP b/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.CPP new file mode 100644 index 0000000..bee7a3e --- /dev/null +++ b/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.CPP @@ -0,0 +1,103 @@ +/**************************************************************************** +* +* PLAYER2.CPP +* +* A simple video player. +* +***/ + +#include +#include +#include + +HSVIDEO video = (HSVIDEO)0; + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (!SVidPlayContinue()) + SDrawPostClose(); + return 1; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + if (video) + SVidPlayEnd(video); +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS params) { + SDrawPostClose(); +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR cmdline, int) { + + // CHECK THE COMMAND LINE + if (!(cmdline && *cmdline)) { + MessageBox(0, + "Usage: PLAYER1 filename.smk", + "Video Player", + MB_ICONSTOP); + return 1; + } + + // INITIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("VIDEOCLASS"), + TEXT("Video Player"))) + return 1; + + // INITIALIZE DIRECTSOUND + LPDIRECTSOUND lpds = NULL; + if (DirectSoundCreate(NULL,&lpds,NULL) == DS_OK) { + + // SET THE COOPERATIVE LEVEL + if (lpds->SetCooperativeLevel(SDrawGetFrameWindow(),DSSCL_PRIORITY) != DS_OK) + if (lpds->SetCooperativeLevel(SDrawGetFrameWindow(),DSSCL_NORMAL) != DS_OK) + return 1; + + // CREAT A PRIMARY SOUND BUFFER + DSBUFFERDESC desc; + ZeroMemory(&desc,sizeof(DSBUFFERDESC)); + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN; + LPDIRECTSOUNDBUFFER lpbuf; + lpds->CreateSoundBuffer(&desc,&lpbuf,NULL); + + // SET THE FORMAT OF THE PRIMARY SOUND BUFFER + WAVEFORMATEX format; + ZeroMemory(&format,sizeof(WAVEFORMATEX)); + format.wFormatTag = WAVE_FORMAT_PCM; + format.nChannels = 2; + format.nSamplesPerSec = 22050; + format.wBitsPerSample = 16; + format.nBlockAlign = (2*16)/8; // (nChannels*wBitsPerSample)/8 + format.nAvgBytesPerSec = ((2*16)/8)*22050; // nBlockAlign*nSamplesPerSec + format.cbSize = 0; + lpbuf->SetFormat(&format); + + } + + // REGISTER WINDOW MESSAGES + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + + // INITIALIZE THE VIDEO PLAYER + TCHAR dir[MAX_PATH] = TEXT(""); + GetCurrentDirectory(MAX_PATH,dir); + SFileSetBasePath(dir); + if (!SVidInitialize(lpds)) + return 1; + + // PLAY THE VIDEO + ShowCursor(0); + SVidPlayBegin(cmdline, + NULL,NULL,NULL,NULL, + SVID_AUTOCUTSCENE, + &video); + int result = SMsgDoMessageLoop(IdleProc); + ShowCursor(1); + + return result; +} diff --git a/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.CS b/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.CS new file mode 100644 index 0000000..f05ca5a --- /dev/null +++ b/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.CS @@ -0,0 +1,3 @@ +#include "../../sample.cs" +set extralib=dsound.lib + diff --git a/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.EXE b/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.EXE new file mode 100644 index 0000000..f07dbb8 Binary files /dev/null and b/Storm/SAMPLES/SVID/PLAYER1/PLAYER1.EXE differ diff --git a/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.CPP b/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.CPP new file mode 100644 index 0000000..27b17ef --- /dev/null +++ b/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.CPP @@ -0,0 +1,127 @@ +/**************************************************************************** +* +* PLAYER2.CPP +* +* A sample video player. This version allows the user to pause and to set +* the playback quality level. +* +***/ + +#include +#include +#include + +BOOL paused = 0; +HSVIDEO video = (HSVIDEO)0; + +//=========================================================================== +BOOL CALLBACK IdleProc (DWORD) { + if (!paused) { + if (!SVidPlayContinue()) + SDrawPostClose(); + } + return !paused; +} + +//=========================================================================== +void CALLBACK OnClose (LPPARAMS params) { + if (video) + SVidPlayEnd(video); +} + +//=========================================================================== +void CALLBACK OnVkEscape (LPPARAMS params) { + SDrawPostClose(); +} + +//=========================================================================== +void CALLBACK OnVkSpace (LPPARAMS params) { + paused = !paused; +} + +//=========================================================================== +int APIENTRY WinMain (HINSTANCE instance, HINSTANCE, LPSTR cmdline, int) { + + // PARSE THE COMMAND LINE + if (!(cmdline && *cmdline)) { + MessageBox(0, + "Usage: PLAYER2 [qualitylevel] filename.smk\n\n" + "Quality Levels:\n" + "1 = Low (skip scans)\n" + "2 = Low (zoom)\n" + "3 = High (skip scans)\n" + "4 = High (zoom)", + "Video Player", + MB_ICONSTOP); + return 1; + } + int qualitylevel = SVID_QUALITY_HIGH; + if (atoi(cmdline)) { + switch (atoi(cmdline)) { + case 1: qualitylevel = SVID_QUALITY_LOW_SKIPSCANS; break; + case 2: qualitylevel = SVID_QUALITY_LOW; break; + case 3: qualitylevel = SVID_QUALITY_HIGH_SKIPSCANS; break; + case 4: qualitylevel = SVID_QUALITY_HIGH; break; + } + if (strchr(cmdline,' ')) + cmdline = strchr(cmdline,' ')+1; + else + cmdline += strlen(cmdline); + } + + // INTIALIZE DIRECTDRAW + if (!SDrawAutoInitialize(instance, + TEXT("VIDEOCLASS"), + TEXT("Video Player"))) + return 1; + + // INITIALIZE DIRECTSOUND + LPDIRECTSOUND lpds = NULL; + if (DirectSoundCreate(NULL,&lpds,NULL) == DS_OK) { + + // SET THE COOPERATIVE LEVEL + lpds->SetCooperativeLevel(SDrawGetFrameWindow(), + DSSCL_NORMAL); + + // CREAT A PRIMARY SOUND BUFFER + DSBUFFERDESC desc; + ZeroMemory(&desc,sizeof(DSBUFFERDESC)); + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN; + LPDIRECTSOUNDBUFFER lpbuf; + lpds->CreateSoundBuffer(&desc,&lpbuf,NULL); + + // SET THE FORMAT OF THE PRIMARY SOUND BUFFER + WAVEFORMATEX format; + ZeroMemory(&format,sizeof(WAVEFORMATEX)); + format.wFormatTag = WAVE_FORMAT_PCM; + format.nChannels = 2; + format.nSamplesPerSec = 22050; + format.wBitsPerSample = 16; + format.nBlockAlign = (2*16)/8; // (nChannels*wBitsPerSample)/8 + format.nAvgBytesPerSec = ((2*16)/8)*22050; // nBlockAlign*nSamplesPerSec + format.cbSize = 0; + lpbuf->SetFormat(&format); + + } + + // REGISTER WINDOW MESSAGES + SMsgRegisterMessage(NULL,WM_CLOSE ,OnClose); + SMsgRegisterKeyDown(NULL,VK_ESCAPE,OnVkEscape); + SMsgRegisterKeyDown(NULL,VK_SPACE ,OnVkSpace); + + // INITIALIZE THE VIDEO PLAYER + if (!SVidInitialize(lpds)) + return 1; + + // PLAY THE VIDEO + ShowCursor(0); + SVidPlayBegin(cmdline, + NULL,NULL,NULL,NULL, + SVID_CUTSCENE | qualitylevel, + &video); + SMsgDoMessageLoop(IdleProc); + ShowCursor(1); + + return 0; +} diff --git a/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.CS b/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.CS new file mode 100644 index 0000000..a879725 --- /dev/null +++ b/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set extralib=dsound.lib diff --git a/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.EXE b/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.EXE new file mode 100644 index 0000000..db583f1 Binary files /dev/null and b/Storm/SAMPLES/SVID/PLAYER2/PLAYER2.EXE differ diff --git a/Storm/SAMPLES/TSLIST/BASIC/BASIC.CPP b/Storm/SAMPLES/TSLIST/BASIC/BASIC.CPP new file mode 100644 index 0000000..5e1ab5e --- /dev/null +++ b/Storm/SAMPLES/TSLIST/BASIC/BASIC.CPP @@ -0,0 +1,42 @@ +/**************************************************************************** +* +* BASIC.CPP +* +* This sample demonstrates basic linked list operation using Storm's +* list manager. +* +***/ + +#include +#include +#include + +NODEDECL(TEST) { + LPCSTR string; +} *TESTPTR; + +static LIST(TEST) s_list; + +#define TESTSTRINGS 5 + +static const LPCSTR s_teststring[TESTSTRINGS] = + {"one","two","three","four","five"}; + +//=========================================================================== +int __cdecl main () { + + // ALLOCATE AND INITIALIZE THE NODES + for (int loop = 0; loop < TESTSTRINGS; ++loop) { + TESTPTR newnode = s_list.NewNode(); + newnode->string = s_teststring[loop]; + } + + // DUMP THE LIST CONTENTS TO THE SCREEN + ITERATELIST(TEST,s_list,curr) + printf("%s\n",curr->string); + + // DELETE ALL NODES + s_list.Clear(); + + return 0; +} diff --git a/Storm/SAMPLES/TSLIST/BASIC/BASIC.CS b/Storm/SAMPLES/TSLIST/BASIC/BASIC.CS new file mode 100644 index 0000000..eb521a7 --- /dev/null +++ b/Storm/SAMPLES/TSLIST/BASIC/BASIC.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/TSLIST/BASIC/BASIC.EXE b/Storm/SAMPLES/TSLIST/BASIC/BASIC.EXE new file mode 100644 index 0000000..79d042d Binary files /dev/null and b/Storm/SAMPLES/TSLIST/BASIC/BASIC.EXE differ diff --git a/Storm/SAMPLES/TSLIST/MULTI/MULTI.CPP b/Storm/SAMPLES/TSLIST/MULTI/MULTI.CPP new file mode 100644 index 0000000..2492b60 --- /dev/null +++ b/Storm/SAMPLES/TSLIST/MULTI/MULTI.CPP @@ -0,0 +1,65 @@ +/**************************************************************************** +* +* MULTI.CPP +* +* This sample demonstrates the use of multiple links, allowing one node +* to be linked into more than one list. +* +***/ + +#include +#include +#include + +NODEDECLEX(TEST) { + LPCSTR string; + LINKEX(TEST) normallink; + LINKEX(TEST) sortedlink; +} *TESTPTR; + +static LISTEX(TEST,normallink) s_list; +static LISTEX(TEST,sortedlink) s_sortedlist; + +#define TESTSTRINGS 5 + +static const LPCSTR s_teststring[TESTSTRINGS] = + {"one","two","three","four","five"}; + +//=========================================================================== +static void DumpList (LISTPTREX(TEST) list) { + ITERATELISTPTR(TEST,list,curr) + printf("%s\n",curr->string); +} + +//=========================================================================== +int __cdecl main () { + + // ALLOCATE AND INITIALIZE THE NODES + for (int loop = 0; loop < TESTSTRINGS; ++loop) { + + // ALLOCATE A NEW NODE AND FILL IN ITS STRING + TESTPTR newnode = s_list.NewNode(); + newnode->string = s_teststring[loop]; + + // ADD IT TO THE SORTED LIST IN THE CORRECT ORDER + TESTPTR checknode = s_sortedlist.Head(); + while (checknode && (_stricmp(checknode->string,newnode->string) < 0)) + checknode = s_sortedlist.Next(checknode); + s_sortedlist.LinkNode(newnode,LIST_LINK_BEFORE,checknode); + + } + + // DUMP BOTH LISTS TO THE SCREEN + printf("List Sorted By Add Order\n"); + DumpList(&s_list); + printf("\nList Sorted Alphabetically\n"); + DumpList(&s_sortedlist); + + // DELETE ALL NODES + // (UPON DELETION, EACH NODE IS AUTOMATICALLY UNLINKED FROM EVERY LIST + // IT'S LINKED INTO, SO THERE'S NO NEED TO SEPARATELY PROCESS THE + // SORTED LIST) + s_list.Clear(); + + return 0; +} diff --git a/Storm/SAMPLES/TSLIST/MULTI/MULTI.CS b/Storm/SAMPLES/TSLIST/MULTI/MULTI.CS new file mode 100644 index 0000000..eb521a7 --- /dev/null +++ b/Storm/SAMPLES/TSLIST/MULTI/MULTI.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/TSLIST/MULTI/MULTI.EXE b/Storm/SAMPLES/TSLIST/MULTI/MULTI.EXE new file mode 100644 index 0000000..82d050c Binary files /dev/null and b/Storm/SAMPLES/TSLIST/MULTI/MULTI.EXE differ diff --git a/Storm/SAMPLES/TSLIST/TREE/TREE.CPP b/Storm/SAMPLES/TSLIST/TREE/TREE.CPP new file mode 100644 index 0000000..a85f4ff --- /dev/null +++ b/Storm/SAMPLES/TSLIST/TREE/TREE.CPP @@ -0,0 +1,63 @@ +/**************************************************************************** +* +* TREE.CPP +* +* This sample demonstrates using linked lists to implement a tree structure. +* +***/ + +#include +#include +#include + +NODEDECL(TEST) { + LPCSTR string; + LIST(TEST) children; + + ~TEST () { + children.Clear(); + } + +} *TESTPTR; + +static LIST(TEST) s_list; + +//=========================================================================== +static void DumpListRecursive (LISTPTR(TEST) list, int depth) { + ITERATELISTPTR(TEST,list,curr) { + printf("%*s%s\n",depth,"",curr->string); + DumpListRecursive(&curr->children,depth+1); + } +} + +//=========================================================================== +int __cdecl main () { + + // CREATE A TREE STRUCTURE FOR TESTING PURPOSES + TESTPTR one = s_list.NewNode(); + TESTPTR two = one->children.NewNode(); + TESTPTR three = one->children.NewNode(); + TESTPTR four = one->children.NewNode(); + TESTPTR five = three->children.NewNode(); + one->string = "one"; + two->string = "two"; + three->string = "three"; + four->string = "four"; + five->string = "five"; + + // DUMP THE TREE TO THE SCREEN + printf("Original Tree Structure\n"); + DumpListRecursive(&s_list,0); + + // DEMONSTRATE DELETING A NODE + delete three; + + // DUMP THE MODIFIED TREE TO THE SCREEN + printf("\nAfter Deleting Node Three\n"); + DumpListRecursive(&s_list,0); + + // DELETE ALL REMAINING NODES + s_list.Clear(); + + return 0; +} diff --git a/Storm/SAMPLES/TSLIST/TREE/TREE.CS b/Storm/SAMPLES/TSLIST/TREE/TREE.CS new file mode 100644 index 0000000..eb521a7 --- /dev/null +++ b/Storm/SAMPLES/TSLIST/TREE/TREE.CS @@ -0,0 +1,2 @@ +#include "../../sample.cs" +set subsystem=console diff --git a/Storm/SAMPLES/TSLIST/TREE/TREE.EXE b/Storm/SAMPLES/TSLIST/TREE/TREE.EXE new file mode 100644 index 0000000..d0c08f3 Binary files /dev/null and b/Storm/SAMPLES/TSLIST/TREE/TREE.EXE differ diff --git a/Storm/SAVE/STORM9~1.ZIP b/Storm/SAVE/STORM9~1.ZIP new file mode 100644 index 0000000..a049b04 Binary files /dev/null and b/Storm/SAVE/STORM9~1.ZIP differ diff --git a/Storm/SMACKER/BIN/SMACKW32.DLL b/Storm/SMACKER/BIN/SMACKW32.DLL new file mode 100644 index 0000000..0e9c4a0 Binary files /dev/null and b/Storm/SMACKER/BIN/SMACKW32.DLL differ diff --git a/Storm/SMACKER/H/RAD.H b/Storm/SMACKER/H/RAD.H new file mode 100644 index 0000000..480662e --- /dev/null +++ b/Storm/SMACKER/H/RAD.H @@ -0,0 +1,499 @@ +#ifndef __RAD__ +#define __RAD__ + +#define RADCOPYRIGHT "Copyright (C) 1994-97 RAD Game Tools, Inc." + +#ifndef __RADRES__ + +// __RADDOS__ means DOS code (16 or 32 bit) +// __RAD16__ means 16 bit code (Win16) +// __RAD32__ means 32 bit code (DOS, Win386, Win32s, Mac) +// __RADWIN__ means Windows code (Win16, Win386, Win32s) +// __RADWINEXT__ means Windows 386 extender (Win386) +// __RADNT__ means Win32s code +// __RADMAC__ means Macintosh +// __RAD68K__ means 68K Macintosh +// __RADPPC__ means PowerMac + + +#if defined(__MWERKS__) || defined(THINK_C) || defined(powerc) || defined(macintosh) || defined(__powerc) + + #define __RADMAC__ + #if defined(powerc) || defined(__powerc) + #define __RADPPC__ + #else + #define __RAD68K__ + #endif + + #define __RAD32__ + +#else + + #ifdef __DOS__ + #define __RADDOS__ + #endif + + #ifdef __386__ + #define __RAD32__ + #endif + + #ifdef _Windows //For Borland + #ifdef __WIN32__ + #define WIN32 + #else + #define __WINDOWS__ + #endif + #endif + + #ifdef _WINDOWS //For MS + #ifndef _WIN32 + #define __WINDOWS__ + #endif + #endif + + #ifdef _WIN32 + #define __RADWIN__ + #define __RADNT__ + #define __RAD32__ + #else + #ifdef __NT__ + #define __RADWIN__ + #define __RADNT__ + #define __RAD32__ + #else + #ifdef __WINDOWS_386__ + #define __RADWIN__ + #define __RADWINEXT__ + #define __RAD32__ + #else + #ifdef __WINDOWS__ + #define __RADWIN__ + #define __RAD16__ + #else + #ifdef WIN32 + #define __RADWIN__ + #define __RADNT__ + #define __RAD32__ + #endif + #endif + #endif + #endif + #endif + +#endif + +#if (!defined(__RADDOS__) && !defined(__RADWIN__) && !defined(__RADMAC__)) + #error RAD.H did not detect your platform. Define __DOS__, __WINDOWS__, WIN32, macintosh, or powerc. +#endif + +#ifdef __RADMAC__ + + // this define is for CodeWarrior 11's stupid new libs (even though + // we don't use longlong's). + + #define __MSL_LONGLONG_SUPPORT__ + + #define RADLINK + #define RADEXPLINK + + #ifdef __CFM68K__ + #ifdef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(export) + #else + #define RADEXPFUNC RADDEFFUNC __declspec(import) + #endif + #else + #define RADEXPFUNC RADDEFFUNC + #endif + #define RADASMLINK + +#else + + #ifdef __RADNT__ + #ifndef _WIN32 + #define _WIN32 + #endif + #ifndef WIN32 + #define WIN32 + #endif + #endif + + #ifdef __RADWIN__ + #ifdef __RAD32__ + #ifdef __RADNT__ + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + + #ifdef __RADINEXE__ + #define RADEXPFUNC RADDEFFUNC + #else + #ifndef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(dllimport) + #ifdef __BORLANDC__ + #if __BORLANDC__<=0x460 + #undef RADEXPFUNC + #define RADEXPFUNC RADDEFFUNC + #endif + #endif + #else + #define RADEXPFUNC RADDEFFUNC __declspec(dllexport) + #endif + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __far __pascal + #define RADEXPFUNC RADDEFFUNC + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __far __pascal __export + #define RADEXPFUNC RADDEFFUNC + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __pascal + #define RADEXPFUNC RADDEFFUNC + #endif + + #define RADASMLINK __cdecl + +#endif + +#ifdef __RADWIN__ + #ifndef _WINDOWS + #define _WINDOWS + #endif +#endif + +#ifdef __cplusplus + #define RADDEFFUNC extern "C" + #define RADDEFSTART extern "C" { + #define RADDEFEND } +#else + #define RADDEFFUNC + #define RADDEFSTART + #define RADDEFEND +#endif + + +RADDEFSTART + +#define s8 signed char +#define u8 unsigned char +#define u32 unsigned long +#define s32 signed long + +#ifdef __RAD32__ + #define PTR4 + + #define u16 unsigned short + #define s16 signed short + + #ifdef __RADMAC__ + + #include + #include + #include + + #define radstrlen strlen + + #define radmemset memset + + #define radmemcmp memcmp + + #define radmemcpy(dest,source,size) BlockMoveData((Ptr)(source),(Ptr)(dest),size) + + #define radmemcpydb(dest,source,size) BlockMoveData((Ptr)(source),(Ptr)(dest),size) + + #define radstrcpy strcpy + + #ifdef __RAD68K__ + + #pragma parameter __D0 mult64anddiv(__D0,__D1,__D2) + u32 mult64anddiv(u32 m1,u32 m2,u32 d) ={0x4C01,0x0C01,0x4C42,0x0C01}; + // muls.l d1,d1:d0 divs.l d2,d1:d0 + + #pragma parameter radconv32a(__A0,__D0) + void radconv32a(void* p,u32 n) ={0x4A80,0x600C,0x2210,0xE059,0x4841,0xE059,0x20C1,0x5380,0x6EF2}; + // tst.l d0 bra.s @loope @loop: move.l (a0),d1 ror.w #8,d1 swap d1 ror.w #8,d1 move.l d1,(a0)+ sub.l #1,d0 bgt.s @loop @loope: + + #else + + u32 mult64anddiv(u32 m1,u32 m2,u32 d); + + void radconv32a(void* p,u32 n); + + #endif + + #else + + #ifdef __WATCOMC__ + + u32 radsqr(s32 a); + #pragma aux radsqr = "mul eax" parm [eax] modify [EDX eax]; + + u32 mult64anddiv(u32 m1,u32 m2,u32 d); + #pragma aux mult64anddiv = "mul ecx" "div ebx" parm [eax] [ecx] [ebx] modify [EDX eax]; + + s32 radabs(s32 ab); + #pragma aux radabs = "test eax,eax" "jge skip" "neg eax" "skip:" parm [eax]; + + #define radabs32 radabs + + u32 DOSOut(const char* str); + #pragma aux DOSOut = "cld" "mov ecx,0xffffffff" "xor eax,eax" "mov edx,edi" "repne scasb" "not ecx" "dec ecx" "mov ebx,1" "mov ah,0x40" "int 0x21" parm [EDI] modify [EAX EBX ECX EDX EDI] value [ecx]; + + void DOSOutNum(const char* str,u32 len); + #pragma aux DOSOutNum = "mov ah,0x40" "mov ebx,1" "int 0x21" parm [edx] [ecx] modify [eax ebx]; + + u32 ErrOut(const char* str); + #pragma aux ErrOut = "cld" "mov ecx,0xffffffff" "xor eax,eax" "mov edx,edi" "repne scasb" "not ecx" "dec ecx" "xor ebx,ebx" "mov ah,0x40" "int 0x21" parm [EDI] modify [EAX EBX ECX EDX EDI] value [ecx]; + + void ErrOutNum(const char* str,u32 len); + #pragma aux ErrOutNum = "mov ah,0x40" "xor ebx,ebx" "int 0x21" parm [edx] [ecx] modify [eax ebx]; + + void radmemset16(void* dest,u16 value,u32 size); + #pragma aux radmemset16 = "cld" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,1" "rep stosd" "mov cl,bl" "and cl,1" "rep stosw" parm [EDI] [EAX] [ECX] modify [EAX EDX EBX ECX EDI]; + + void radmemset(void* dest,u8 value,u32 size); + #pragma aux radmemset = "cld" "mov ah,al" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,2" "and bl,3" "rep stosd" "mov cl,bl" "rep stosb" parm [EDI] [AL] [ECX] modify [EAX EDX EBX ECX EDI]; + + void radmemset32(void* dest,u32 value,u32 size); + #pragma aux radmemset32 = "cld" "rep stosd" parm [EDI] [EAX] [ECX] modify [EAX EDX EBX ECX EDI]; + + void radmemcpy(void* dest,const void* source,u32 size); + #pragma aux radmemcpy = "cld" "mov bl,cl" "shr ecx,2" "rep movsd" "mov cl,bl" "and cl,3" "rep movsb" parm [EDI] [ESI] [ECX] modify [EBX ECX EDI ESI]; + + void __far *radfmemcpy(void __far* dest,const void __far* source,u32 size); + #pragma aux radfmemcpy = "cld" "push es" "push ds" "mov es,cx" "mov ds,dx" "mov ecx,eax" "shr ecx,2" "rep movsd" "mov cl,al" "and cl,3" "rep movsb" "pop ds" "pop es" parm [CX EDI] [DX ESI] [EAX] modify [ECX EDI ESI] value [CX EDI]; + + void radmemcpydb(void* dest,const void* source,u32 size); //Destination bigger + #pragma aux radmemcpydb = "std" "mov bl,cl" "lea esi,[esi+ecx-4]" "lea edi,[edi+ecx-4]" "shr ecx,2" "rep movsd" "and bl,3" "jz dne" "add esi,3" "add edi,3" "mov cl,bl" "rep movsb" "dne:" "cld" parm [EDI] [ESI] [ECX] modify [EBX ECX EDI ESI]; + + char* radstrcpy(void* dest,const void* source); + #pragma aux radstrcpy = "cld" "mov edx,edi" "lp:" "mov al,[esi]" "inc esi" "mov [edi],al" "inc edi" "cmp al,0" "jne lp" parm [EDI] [ESI] modify [EAX EDX EDI ESI] value [EDX]; + + char __far* radfstrcpy(void __far* dest,const void __far* source); + #pragma aux radfstrcpy = "cld" "push es" "push ds" "mov es,cx" "mov ds,dx" "mov edx,edi" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "pop ds" "pop es" parm [CX EDI] [DX ESI] modify [EAX EDX EDI ESI] value [CX EDX]; + + char* radstpcpy(void* dest,const void* source); + #pragma aux radstpcpy = "cld" "lp:" "mov al,[esi]" "inc esi" "mov [edi],al" "inc edi" "cmp al,0" "jne lp" "dec edi" parm [EDI] [ESI] modify [EAX EDI ESI] value [EDI]; + + char* radstpcpyrs(void* dest,const void* source); + #pragma aux radstpcpyrs = "cld" "lp:" "mov al,[esi]" "inc esi" "mov [edi],al" "inc edi" "cmp al,0" "jne lp" "dec esi" parm [EDI] [ESI] modify [EAX EDI ESI] value [ESI]; + + u32 radstrlen(const void* dest); + #pragma aux radstrlen = "cld" "mov ecx,0xffffffff" "xor eax,eax" "repne scasb" "not ecx" "dec ecx" parm [EDI] modify [EAX ECX EDI] value [ECX]; + + char* radstrcat(void* dest,const void* source); + #pragma aux radstrcat = "cld" "mov ecx,0xffffffff" "mov edx,edi" "xor eax,eax" "repne scasb" "dec edi" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" \ + parm [EDI] [ESI] modify [EAX ECX EDI ESI] value [EDX]; + + char* radstrchr(const void* dest,char chr); + #pragma aux radstrchr = "cld" "lp:" "lodsb" "cmp al,dl" "je fnd" "cmp al,0" "jnz lp" "mov esi,1" "fnd:" "dec esi" parm [ESI] [DL] modify [EAX ESI] value [esi]; + + s8 radmemcmp(const void* s1,const void* s2,u32 len); + #pragma aux radmemcmp = "cld" "rep cmpsb" "setne al" "jbe end" "neg al" "end:" parm [EDI] [ESI] [ECX] modify [ECX EDI ESI]; + + s8 radstrcmp(const void* s1,const void* s2); + #pragma aux radstrcmp = "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,ah" "jne set" "cmp al,0" "je set" "inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" \ + parm [EDI] [ESI] modify [EAX EDI ESI]; + + s8 radstricmp(const void* s1,const void* s2); + #pragma aux radstricmp = "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" "cmp ah,'a'" "jb c2" "cmp ah,'z'" "ja c2" "sub ah,32" "c2:" "cmp al,ah" "jne set" "cmp al,0" "je set" \ + "inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" \ + parm [EDI] [ESI] modify [EAX EDI ESI]; + + s8 radstrnicmp(const void* s1,const void* s2,u32 len); + #pragma aux radstrnicmp = "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" "cmp ah,'a'" "jb c2" "cmp ah,'z'" "ja c2" "sub ah,32" "c2:" "cmp al,ah" "jne set" "cmp al,0" "je set" \ + "dec ecx" "jz set" "inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" \ + parm [EDI] [ESI] [ECX] modify [EAX ECX EDI ESI]; + + char* radstrupr(void* s1); + #pragma aux radstrupr = "mov ecx,edi" "lp:" "mov al,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub [edi],32" "c1:" "inc edi" "cmp al,0" "jne lp" parm [EDI] modify [EAX EDI] value [ecx]; + + char* radstrlwr(void* s1); + #pragma aux radstrlwr = "mov ecx,edi" "lp:" "mov al,[edi]" "cmp al,'A'" "jb c1" "cmp al,'Z'" "ja c1" "add [edi],32" "c1:" "inc edi" "cmp al,0" "jne lp" parm [EDI] modify [EAX EDI] value [ecx]; + + u32 radstru32(const void* dest); + #pragma aux radstru32 = "cld" "xor ecx,ecx" "xor ebx,ebx" "xor edi,edi" "lodsb" "cmp al,45" "jne skip2" "mov edi,1" "jmp skip" "lp:" "mov eax,10" "mul ecx" "lea ecx,[eax+ebx]" \ + "skip:" "lodsb" "skip2:" "cmp al,0x39" "ja dne" "cmp al,0x30" "jb dne" "mov bl,al" "sub bl,0x30" "jmp lp" "dne:" "test edi,1" "jz pos" "neg ecx" "pos:" \ + parm [ESI] modify [EAX EBX EDX EDI ESI] value [ecx]; + + u16 GetDS(); + #pragma aux GetDS = "mov ax,ds" value [ax]; + + #ifdef __RADWINEXT__ + + #define _16To32(ptr16) ((void*)(((GetSelectorBase((u16)(((u32)(ptr16))>>16))+((u16)(u32)(ptr16)))-GetSelectorBase(GetDS())))) + + #endif + + #ifndef __RADWIN__ + #define int86 int386 + #define int86x int386x + #endif + + #define u32regs x + #define u16regs w + + #else + + #define radstrcpy strcpy + #define radstrcat strcat + #define radmemcpy memcpy + #define radmemcpydb memmove + #define radmemcmp memcmp + #define radmemset memset + #define radstrlen strlen + #define radstrchr strchr + #define radtoupper toupper + #define radstru32(s) ((u32)atol(s)) + #define radstricmp _stricmp + #define radstrcmp strcmp + #define radstrupr _strupr + #define radstrlwr _strlwr + #define BreakPoint() _asm {int 3} + + #ifdef _MSC_VER + + #pragma warning( disable : 4035) + + typedef char* RADPCHAR; + + u32 __inline radsqr(u32 m){ _asm { _asm mov eax,[m] _asm mul eax } } + u32 __inline mult64anddiv(u32 m1,u32 m2, u32 d){ _asm { _asm mov eax,[m1] _asm mov ecx,[m2] _asm mul ecx _asm mov ecx,[d] _asm div ecx } } + s32 __inline radabs(s32 ab) { _asm { _asm mov eax,[ab] _asm test eax,eax _asm jge skip _asm neg eax _asm skip:} } + u8 __inline radinp(u16 p) { _asm { _asm mov dx,[p] _asm in al,dx } } + void __inline radoutp(u16 p,u8 v) { _asm { _asm mov dx,[p] _asm mov al,[v] _asm out dx,al } } + RADPCHAR __inline radstpcpy(char* p1, char* p2) { _asm { _asm mov edx,[p1] _asm mov ecx,[p2] _asm cld _asm lp: _asm mov al,[ecx] _asm inc ecx _asm mov [edx],al _asm inc edx _asm cmp al,0 _asm jne lp _asm dec edx _asm mov eax,edx } } + RADPCHAR __inline radstpcpyrs(char* p1, char* p2) { _asm { _asm mov edx,[p1] _asm mov ecx,[p2] _asm cld _asm lp: _asm mov al,[ecx] _asm inc ecx _asm mov [edx],al _asm inc edx _asm cmp al,0 _asm jne lp _asm dec ecx _asm mov eax,ecx } } + void __inline radmemset16(void* dest,u16 value,u32 sizeb) { _asm { _asm mov edi,[dest] _asm mov ax,[value] _asm mov ecx,[sizeb] _asm shl eax,16 _asm cld _asm mov ax,[value] _asm mov bl,cl _asm shr ecx,1 _asm rep stosd _asm mov cl,bl _asm and cl,1 _asm rep stosw } } + void __inline radmemset32(void* dest,u32 value,u32 sizeb) { _asm { _asm mov edi,[dest] _asm mov eax,[value] _asm mov ecx,[sizeb] _asm cld _asm rep stosd } } + + #pragma warning( default : 4035) + + #endif + + #endif + + #endif + +#else + + #define PTR4 __far + + #define u16 unsigned int + #define s16 signed int + + #ifdef __WATCOMC__ + + u32 radsqr(s32 a); + #pragma aux radsqr = "shl edx,16" "mov dx,ax" "mov eax,edx" "xor edx,edx" "mul eax" "shld edx,eax,16" parm [dx ax] modify [DX ax] value [dx ax]; + + s16 radabs(s16 ab); + #pragma aux radabs = "test ax,ax" "jge skip" "neg ax" "skip:" parm [ax] value [ax]; + + s32 radabs32(s32 ab); + #pragma aux radabs32 = "test dx,dx" "jge skip" "neg dx" "neg ax" "sbb dx,0" "skip:" parm [dx ax] value [dx ax]; + + u32 DOSOut(const char far* dest); + #pragma aux DOSOut = "cld" "and edi,0xffff" "mov dx,di" "mov ecx,0xffffffff" "xor eax,eax" 0x67 "repne scasb" "not ecx" "dec ecx" "mov bx,1" "push ds" "push es" "pop ds" "mov ah,0x40" "int 0x21" "pop ds" "movzx eax,cx" "shr ecx,16" \ + parm [ES DI] modify [AX BX CX DX DI ES] value [CX AX]; + + void DOSOutNum(const char far* str,u16 len); + #pragma aux DOSOutNum = "push ds" "mov ds,cx" "mov cx,bx" "mov ah,0x40" "mov bx,1" "int 0x21" "pop ds" parm [cx dx] [bx] modify [ax bx cx]; + + u32 ErrOut(const char far* dest); + #pragma aux ErrOut = "cld" "and edi,0xffff" "mov dx,di" "mov ecx,0xffffffff" "xor eax,eax" 0x67 "repne scasb" "not ecx" "dec ecx" "xor bx,bx" "push ds" "push es" "pop ds" "mov ah,0x40" "int 0x21" "pop ds" "movzx eax,cx" "shr ecx,16" \ + parm [ES DI] modify [AX BX CX DX DI ES] value [CX AX]; + + void ErrOutNum(const char far* str,u16 len); + #pragma aux ErrOutNum = "push ds" "mov ds,cx" "mov cx,bx" "mov ah,0x40" "xor bx,bx" "int 0x21" "pop ds" parm [cx dx] [bx] modify [ax bx cx]; + + void radmemset(void far *dest,u8 value,u32 size); + #pragma aux radmemset = "cld" "and edi,0ffffh" "shl ecx,16" "mov cx,bx" "mov ah,al" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,2" 0x67 "rep stosd" "mov cl,bl" "and cl,3" "rep stosb" parm [ES DI] [AL] [CX BX]; + + void radmemset16(void far* dest,u16 value,u32 size); + #pragma aux radmemset16 = "cld" "and edi,0ffffh" "shl ecx,16" "mov cx,bx" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,1" "rep stosd" "mov cl,bl" "and cl,1" "rep stosw" parm [ES DI] [AX] [CX BX]; + + void radmemcpy(void far* dest,const void far* source,u32 size); + #pragma aux radmemcpy = "cld" "push ds" "mov ds,dx" "and esi,0ffffh" "and edi,0ffffh" "shl ecx,16" "mov cx,bx" "shr ecx,2" 0x67 "rep movsd" "mov cl,bl" "and cl,3" "rep movsb" "pop ds" parm [ES DI] [DX SI] [CX BX] modify [CX SI DI ES]; + + s8 radmemcmp(const void far* s1,const void far* s2,u32 len); + #pragma aux radmemcmp = "cld" "push ds" "mov ds,dx" "shl ecx,16" "mov cx,bx" "rep cmpsb" "setne al" "jbe end" "neg al" "end:" "pop ds" parm [ES DI] [DX SI] [CX BX] modify [CX SI DI ES]; + + char far* radstrcpy(void far* dest,const void far* source); + #pragma aux radstrcpy = "cld" "push ds" "mov ds,dx" "and esi,0xffff" "and edi,0xffff" "mov dx,di" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "pop ds" parm [ES DI] [DX SI] modify [AX DX DI SI ES] value [es dx]; + + char far* radstpcpy(void far* dest,const void far* source); + #pragma aux radstpcpy = "cld" "push ds" "mov ds,dx" "and esi,0xffff" "and edi,0xffff" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "dec di" "pop ds" parm [ES DI] [DX SI] modify [DI SI ES] value [es di]; + + u32 radstrlen(const void far* dest); + #pragma aux radstrlen = "cld" "and edi,0xffff" "mov ecx,0xffffffff" "xor eax,eax" 0x67 "repne scasb" "not ecx" "dec ecx" "movzx eax,cx" "shr ecx,16" parm [ES DI] modify [AX CX DI ES] value [CX AX]; + + char far* radstrcat(void far* dest,const void far* source); + #pragma aux radstrcat = "cld" "and edi,0xffff" "mov ecx,0xffffffff" "and esi,0xffff" "push ds" "mov ds,dx" "mov dx,di" "xor eax,eax" 0x67 "repne scasb" "dec edi" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "pop ds" \ + parm [ES DI] [DX SI] modify [AX CX DI SI ES] value [es dx]; + + char far* radstrchr(const void far* dest,char chr); + #pragma aux radstrchr = "cld" "lp:" 0x26 "lodsb" "cmp al,dl" "je fnd" "cmp al,0" "jnz lp" "xor ax,ax" "mov es,ax" "mov si,1" "fnd:" "dec si" parm [ES SI] [DL] modify [AX SI ES] value [es si]; + + s8 radstricmp(const void far* s1,const void far* s2); + #pragma aux radstricmp = "and edi,0xffff" "push ds" "mov ds,dx" "and esi,0xffff" "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" \ + "cmp ah,'a'" "jb c2" "cmp ah,'z'" "ja c2" "sub ah,32" "c2:" "cmp al,ah" "jne set" "cmp al,0" "je set" \ + "inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" "pop ds" \ + parm [ES DI] [DX SI] modify [AX DI SI]; + + u32 radstru32(const void far* dest); + #pragma aux radstru32 = "cld" "xor ecx,ecx" "xor ebx,ebx" "xor edi,edi" 0x26 "lodsb" "cmp al,45" "jne skip2" "mov edi,1" "jmp skip" "lp:" "mov eax,10" "mul ecx" "lea ecx,[eax+ebx]" \ + "skip:" 0x26 "lodsb" "skip2:" "cmp al,0x39" "ja dne" "cmp al,0x30" "jb dne" "mov bl,al" "sub bl,0x30" "jmp lp" "dne:" "test edi,1" "jz pos" "neg ecx" "pos:" \ + "movzx eax,cx" "shr ecx,16" parm [ES SI] modify [AX BX DX DI SI] value [cx ax]; + + u32 mult64anddiv(u32 m1,u32 m2,u32 d); + #pragma aux mult64anddiv = "shl ecx,16" "mov cx,ax" "shrd eax,edx,16" "mov ax,si" "mul ecx" "shl edi,16" "mov di,bx" "div edi" "shld edx,eax,16" "and edx,0xffff" "and eax,0xffff" parm [cx ax] [dx si] [di bx] \ + modify [ax bx cx dx si di] value [dx ax]; + + #endif + +#endif + +RADDEFEND + +#define u32neg1 ((u32)(s32)-1) +#define RAD_align(var) var; u8 junk##var[4-(sizeof(var)&3)]; +#define RAD_align_after(var) u8 junk##var[4-(sizeof(var)&3)]={0}; +#define RAD_align_init(var,val) var=val; u8 junk##var[4-(sizeof(var)&3)]={0}; +#define RAD_align_array(var,num) var[num]; u8 junk##var[4-(sizeof(var)&3)]; +#define RAD_align_string(var,str) char var[]=str; u8 junk##var[4-(sizeof(var)&3)]={0}; + +RADEXPFUNC void PTR4* RADEXPLINK radmalloc(u32 numbytes); +RADEXPFUNC void RADEXPLINK radfree(void PTR4* ptr); + +#ifdef __WATCOMC__ + + char bkbhit(); + #pragma aux bkbhit = "mov ah,1" "int 0x16" "lahf" "shr eax,14" "and eax,1" "xor al,1" ; + + char bgetch(); + #pragma aux bgetch = "xor ah,ah" "int 0x16" "test al,0xff" "jnz done" "mov al,ah" "or al,0x80" "done:" modify [AX]; + + void BreakPoint(); + #pragma aux BreakPoint = "int 3"; + + u8 radinp(u16 p); + #pragma aux radinp = "in al,dx" parm [DX]; + + u8 radtoupper(u8 p); + #pragma aux radtoupper = "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" parm [al] value [al]; + + void radoutp(u16 p,u8 v); + #pragma aux radoutp = "out dx,al" parm [DX] [AL]; + +#endif + +#endif + +#endif + diff --git a/Storm/SMACKER/H/SMACK.H b/Storm/SMACKER/H/SMACK.H new file mode 100644 index 0000000..8ed535f --- /dev/null +++ b/Storm/SMACKER/H/SMACK.H @@ -0,0 +1,409 @@ +#ifndef SMACKH +#define SMACKH + +#define SMACKVERSION "3.1a" + +#ifndef __RADRES__ + + +#include "rad.h" + + +RADDEFSTART + +typedef struct SmackTag { + u32 Version; // SMK2 only right now + u32 Width; // Width (1 based, 640 for example) + u32 Height; // Height (1 based, 480 for example) + u32 Frames; // Number of frames (1 based, 100 = 100 frames) + u32 MSPerFrame; // Frame Rate + u32 SmackerType; // bit 0 set=ring frame + u32 LargestInTrack[7]; // Largest single size for each track + u32 tablesize; // Size of the init tables + u32 codesize; // Compression info + u32 absize; // ditto + u32 detailsize; // ditto + u32 typesize; // ditto + u32 TrackType[7]; // high byte=0x80-Comp,0x40-PCM data,0x20-16 bit,0x10-stereo + u32 extra; // extra value (should be zero) + u32 NewPalette; // set to one if the palette changed + u8 Palette[772]; // palette data + u32 PalType; // type of palette + u32 FrameNum; // Frame Number to be displayed + u32 FrameSize; // The current frame's size in bytes + u32 SndSize; // The current frame sound tracks' size in bytes + s32 LastRectx; // Rect set in from SmackToBufferRect (X coord) + s32 LastRecty; // Rect set in from SmackToBufferRect (Y coord) + s32 LastRectw; // Rect set in from SmackToBufferRect (Width) + s32 LastRecth; // Rect set in from SmackToBufferRect (Height) + u32 OpenFlags; // flags used on open + u32 LeftOfs; // Left Offset used in SmackTo + u32 TopOfs; // Top Offset used in SmackTo + u32 LargestFrameSize; // Largest frame size + u32 Highest1SecRate; // Highest 1 sec data rate + u32 Highest1SecFrame; // Highest 1 sec data rate starting frame + u32 ReadError; // Set to non-zero if a read error has ocurred + u32 addr32; // translated address for 16 bit interface +} Smack; + +#define SmackHeaderSize(smk) ((((u8*)&((smk)->extra))-((u8*)(smk)))+4) + +typedef struct SmackSumTag { + u32 TotalTime; // total time + u32 MS100PerFrame; // MS*100 per frame (100000/MS100PerFrame=Frames/Sec) + u32 TotalOpenTime; // Time to open and prepare for decompression + u32 TotalFrames; // Total Frames displayed + u32 SkippedFrames; // Total number of skipped frames + u32 SoundSkips; // Total number of sound skips + u32 TotalBlitTime; // Total time spent blitting + u32 TotalReadTime; // Total time spent reading + u32 TotalDecompTime; // Total time spent decompressing + u32 TotalBackReadTime; // Total time spent reading in background + u32 TotalReadSpeed; // Total io speed (bytes/second) + u32 SlowestFrameTime; // Slowest single frame time + u32 Slowest2FrameTime; // Second slowest single frame time + u32 SlowestFrameNum; // Slowest single frame number + u32 Slowest2FrameNum; // Second slowest single frame number + u32 AverageFrameSize; // Average size of the frame + u32 HighestMemAmount; // Highest amount of memory allocated + u32 TotalExtraMemory; // Total extra memory allocated + u32 HighestExtraUsed; // Highest extra memory actually used +} SmackSum; + + +//======================================================================= +#define SMACKNEEDPAN 0x00020L // Will be setting the pan +#define SMACKNEEDVOLUME 0x00040L // Will be setting the volume +#define SMACKFRAMERATE 0x00080L // Override fr (call SmackFrameRate first) +#define SMACKLOADEXTRA 0x00100L // Load the extra buffer during SmackOpen +#define SMACKPRELOADALL 0x00200L // Preload the entire animation +#define SMACKNOSKIP 0x00400L // Don't skip frames if falling behind +#define SMACKSIMULATE 0x00800L // Simulate the speed (call SmackSim first) +#define SMACKFILEHANDLE 0x01000L // Use when passing in a file handle +#define SMACKTRACK1 0x02000L // Play audio track 1 +#define SMACKTRACK2 0x04000L // Play audio track 2 +#define SMACKTRACK3 0x08000L // Play audio track 3 +#define SMACKTRACK4 0x10000L // Play audio track 4 +#define SMACKTRACK5 0x20000L // Play audio track 5 +#define SMACKTRACK6 0x40000L // Play audio track 6 +#define SMACKTRACK7 0x80000L // Play audio track 7 +#define SMACKTRACKS (SMACKTRACK1|SMACKTRACK2|SMACKTRACK3|SMACKTRACK4|SMACKTRACK5|SMACKTRACK6|SMACKTRACK7) + +#define SMACKBUFFERREVERSED 0x00000001 +#define SMACKBUFFER555 0x80000000 +#define SMACKBUFFER565 0xc0000000 +#define SMACKBUFFER16 (SMACKBUFFER555|SMACKBUFFER565) + +#define SMACKYINTERLACE 0x100000L // Force interleaving Y scaling +#define SMACKYDOUBLE 0x200000L // Force doubling Y scaling +#define SMACKYNONE (SMACKYINTERLACE|SMACKYDOUBLE) // Force normal Y scaling +#define SMACKFILEISSMK 0x2000000L // Internal flag for 16 to 32 bit thunking + +#define SMACKAUTOEXTRA 0xffffffffL // NOT A FLAG! - Use as extrabuf param +//======================================================================= + +#define SMACKSURFACEFAST 0 +#define SMACKSURFACESLOW 1 +#define SMACKSURFACEDIRECT 2 +#define SMACKSURFACEFASTWITHZERORECT 3 + + +RADEXPFUNC Smack PTR4* RADEXPLINK SmackOpen(const char PTR4* name,u32 flags,u32 extrabuf); + +#if defined(__RADMAC__) + #include + + RADEXPFUNC Smack PTR4* RADEXPLINK SmackMacOpen(FSSpec* fsp,u32 flags,u32 extrabuf); +#endif + +RADEXPFUNC u32 RADEXPLINK SmackDoFrame(Smack PTR4* smk); +RADEXPFUNC void RADEXPLINK SmackNextFrame(Smack PTR4* smk); +RADEXPFUNC u32 RADEXPLINK SmackWait(Smack PTR4* smk); +RADEXPFUNC void RADEXPLINK SmackClose(Smack PTR4* smk); + +RADEXPFUNC void RADEXPLINK SmackVolumePan(Smack PTR4* smk, u32 trackflag,u32 volume,u32 pan); + +RADEXPFUNC void RADEXPLINK SmackSummary(Smack PTR4* smk,SmackSum PTR4* sum); + +RADEXPFUNC u32 RADEXPLINK SmackSoundInTrack(Smack PTR4* smk,u32 trackflags); +RADEXPFUNC u32 RADEXPLINK SmackSoundOnOff(Smack PTR4* smk,u32 on); + +#ifndef __RADMAC__ +RADEXPFUNC void RADEXPLINK SmackToScreen(Smack PTR4* smk,u32 left,u32 top,u32 BytePS,const u16 PTR4* WinTbl,void* SetBank,u32 Flags); +#endif + +RADEXPFUNC void RADEXPLINK SmackToBuffer(Smack PTR4* smk,u32 left,u32 top,u32 Pitch,u32 destheight,const void PTR4* buf,u32 Flags); +RADEXPFUNC u32 RADEXPLINK SmackToBufferRect(Smack PTR4* smk, u32 SmackSurface); + +RADEXPFUNC void RADEXPLINK SmackGoto(Smack PTR4* smk,u32 frame); +RADEXPFUNC void RADEXPLINK SmackColorRemap(Smack PTR4* smk,const void PTR4* remappal,u32 numcolors,u32 paltype); +RADEXPFUNC void RADEXPLINK SmackColorTrans(Smack PTR4* smk,const void PTR4* trans); +RADEXPFUNC void RADEXPLINK SmackFrameRate(u32 forcerate); +RADEXPFUNC void RADEXPLINK SmackSimulate(u32 sim); + +RADEXPFUNC u32 RADEXPLINK SmackGetTrackData(Smack PTR4* smk,void PTR4* dest,u32 trackflag); + +RADEXPFUNC void RADEXPLINK SmackSoundCheck(void); + + +//====================================================================== + +// the functions for the new SmackBlit API + +typedef struct _SMACKBLIT PTR4* HSMACKBLIT; + +typedef struct _SMACKBLIT { + u32 Flags; + u8 PTR4* Palette; + u32 PalType; + u16 PTR4* SmoothTable; + u16 PTR4* Conv8to16Table; + u32 whichmode; + u32 palindex; + u32 t16index; + u32 smoothindex; + u32 smoothtype; +} SMACKBLIT; + +#define SMACKBLIT1X 1 +#define SMACKBLIT2X 2 +#define SMACKBLIT2XSMOOTHING 4 +#define SMACKBLIT2XINTERLACE 8 + +RADEXPFUNC HSMACKBLIT RADEXPLINK SmackBlitOpen(u32 flags); +RADEXPFUNC void RADEXPLINK SmackBlitSetPalette(HSMACKBLIT sblit, void PTR4* Palette,u32 PalType); +RADEXPFUNC u32 RADEXPLINK SmackBlitSetFlags(HSMACKBLIT sblit,u32 flags); +RADEXPFUNC void RADEXPLINK SmackBlit(HSMACKBLIT sblit,void PTR4* dest, u32 destpitch, u32 destx, u32 desty, void PTR4* src, u32 srcpitch, u32 srcx, u32 srcy, u32 srcw, u32 srch); +RADEXPFUNC void RADEXPLINK SmackBlitClear(HSMACKBLIT sblit,void PTR4* dest, u32 destpitch, u32 destx, u32 desty, u32 destw, u32 desth, s32 color); +RADEXPFUNC void RADEXPLINK SmackBlitClose(HSMACKBLIT sblit); +RADEXPFUNC void RADEXPLINK SmackBlitTrans(HSMACKBLIT sblit,void PTR4* dest, u32 destpitch, u32 destx, u32 desty, void PTR4* src, u32 srcpitch, u32 srcx, u32 srcy, u32 srcw, u32 srch, u32 trans); +RADEXPFUNC void RADEXPLINK SmackBlitMask(HSMACKBLIT sblit,void PTR4* dest, u32 destpitch, u32 destx, u32 desty, void PTR4* src, u32 srcpitch, u32 srcx, u32 srcy, u32 srcw, u32 srch, u32 trans,void PTR4* mask); +RADEXPFUNC void RADEXPLINK SmackBlitMerge(HSMACKBLIT sblit,void PTR4* dest, u32 destpitch, u32 destx, u32 desty, void PTR4* src, u32 srcpitch, u32 srcx, u32 srcy, u32 srcw, u32 srch, u32 trans,void PTR4* back); +RADEXPFUNC char PTR4* RADEXPLINK SmackBlitString(HSMACKBLIT sblit,char PTR4* dest); + +#ifndef __RADMAC__ +RADEXPFUNC u32 RADEXPLINK SmackUseMMX(u32 flag); //0=off, 1=on, 2=query current +#endif + +//====================================================================== +#ifdef __RADDOS__ + + #define SMACKSOUNDNONE -1 + + extern void* SmackTimerSetupAddr; + extern void* SmackTimerReadAddr; + extern void* SmackTimerDoneAddr; + + typedef void RADEXPLINK (*SmackTimerSetupType)(void); + typedef u32 RADEXPLINK (*SmackTimerReadType)(void); + typedef void RADEXPLINK (*SmackTimerDoneType)(void); + + #define SmackTimerSetup() ((SmackTimerSetupType)(SmackTimerSetupAddr))() + #define SmackTimerRead() ((SmackTimerReadType)(SmackTimerReadAddr))() + #define SmackTimerDone() ((SmackTimerDoneType)(SmackTimerDoneAddr))() + + RADEXPFUNC u8 RADEXPLINK SmackSoundUseMSS(void* DigDriver); + + #ifndef AIL_startup + #ifdef __SW_3R + extern s32 cdecl AIL_startup_reg(void); + #define AIL_startup AIL_startup_reg + #else + extern s32 cdecl AIL_startup_stack(void); + #define AIL_startup AIL_startup_stack + #endif + #endif + #define SmackSoundMSSLiteInit() SmackSoundMSSLiteInitWithStart(&AIL_startup); + RADEXPFUNC void RADEXPLINK SmackSoundMSSLiteInitWithStart(void* start); + RADEXPFUNC void RADEXPLINK SmackSoundMSSLiteDone(void); + + RADEXPFUNC u8 RADEXPLINK SmackSoundUseSOS3r(u32 SOSDriver,u32 MaxTimerSpeed); + RADEXPFUNC u8 RADEXPLINK SmackSoundUseSOS3s(u32 SOSDriver,u32 MaxTimerSpeed); + RADEXPFUNC u8 RADEXPLINK SmackSoundUseSOS4r(u32 SOSDriver,u32 MaxTimerSpeed); + RADEXPFUNC u8 RADEXPLINK SmackSoundUseSOS4s(u32 SOSDriver,u32 MaxTimerSpeed); + + #ifdef __SW_3R + #define SmackSoundUseSOS3 SmackSoundUseSOS3r + #define SmackSoundUseSOS4 SmackSoundUseSOS4r + #else + #define SmackSoundUseSOS3 SmackSoundUseSOS3s + #define SmackSoundUseSOS4 SmackSoundUseSOS4s + #endif + +#else + + #define SMACKRESRESET 0 + #define SMACKRES640X400 1 + #define SMACKRES640X480 2 + #define SMACKRES800X600 3 + #define SMACKRES1024X768 4 + + RADEXPFUNC u32 RADEXPLINK SmackSetSystemRes(u32 mode); // use SMACKRES* values + + #define SMACKNOCUSTOMBLIT 128 + #define SMACKSMOOTHBLIT 256 + #define SMACKINTERLACEBLIT 512 + + #ifdef __RADMAC__ + + #include + #include + #include + + #define SmackTimerSetup() + #define SmackTimerDone() + RADEXPFUNC u32 RADEXPLINK SmackTimerRead(void); + + RADEXPFUNC u32 RADEXPLINK SmackBufferUseGDevice( GDHandle gd ); + + #define SMACKAUTOBLIT 0 + #define SMACKDIRECTBLIT 1 + #define SMACKGWORLDBLIT 2 + + typedef struct SmackBufTag { + u32 Reversed; + u32 SurfaceType; // SMACKSURFACExxxxxx + u32 BlitType; // SMACKxxxxxBLIT + u32 Width; + u32 Height; + u32 Pitch; + u32 Zoomed; + u32 ZWidth; + u32 ZHeight; + u32 DispColors; // colors on screen + u32 MaxPalColors; + u32 PalColorsInUse; + u32 StartPalColor; + u32 EndPalColor; + void* Buffer; + void* Palette; + u32 PalType; + u32 cursortype; + + WindowPtr wp; + GWorldPtr gwp; + CTabHandle cth; + PaletteHandle palh; + } SmackBuf; + + #else + + #ifdef __RADWIN__ + + #define INCLUDE_MMSYSTEM_H + #include "windows.h" + #include "windowsx.h" + + #ifdef __RADNT__ // to combat WIN32_LEAN_AND_MEAN + + #include "mmsystem.h" + + RADEXPFUNC s32 RADEXPLINK SmackDDSurfaceType(void* lpDDS); + + #endif + + #define SMACKAUTOBLIT 0 + #define SMACKFULL320X240BLIT 1 + #define SMACKFULL320X200BLIT 2 + #define SMACKFULL320X200DIRECTBLIT 3 + #define SMACKSTANDARDBLIT 4 + #define SMACKWINGBLIT 5 + #define SMACKDIBSECTIONBLIT 5 + + #define WM_SMACKACTIVATE WM_USER+0x5678 + + typedef struct SmackBufTag { + u32 Reversed; // 1 if the buffer is upside down + u32 SurfaceType; // SMACKSURFACExxxx defines + u32 BlitType; // SMACKxxxxBLIT defines + u32 FullScreen; // 1 if full-screen + u32 Width; + u32 Height; + u32 Pitch; + u32 Zoomed; + u32 ZWidth; + u32 ZHeight; + u32 DispColors; // colors on the screen + u32 MaxPalColors; // total possible colors in palette (usually 256) + u32 PalColorsInUse; // Used colors in palette (usually 236) + u32 StartPalColor; // first usable color index (usually 10) + u32 EndPalColor; // last usable color index (usually 246) + RGBQUAD Palette[256]; + u32 PalType; + u32 forceredraw; // force a complete redraw on next blit (for >8bit) + u32 didapalette; // force an invalidate on the next palette change + + void PTR4* Buffer; + void PTR4* DIBRestore; + u32 OurBitmap; + u32 OrigBitmap; + u32 OurPalette; + u32 WinGDC; + u32 FullFocused; + u32 ParentHwnd; + u32 OldParWndProc; + u32 OldDispWndProc; + u32 DispHwnd; + u32 WinGBufHandle; + void PTR4* lpDD; + void PTR4* lpDDSP; + u32 DDSurfaceType; + HSMACKBLIT DDblit; + s32 ddSoftwarecur; + s32 didaddblit; + s32 lastwasdd; + RECT ddscreen; + } SmackBuf; + + RADEXPFUNC void RADEXPLINK SmackGet(Smack PTR4* smk,void PTR4* dest); + RADEXPFUNC void RADEXPLINK SmackBufferGet( SmackBuf PTR4* sbuf, void PTR4* dest); + + RADEXPFUNC u8 RADEXPLINK SmackSoundUseMSS(void PTR4* dd); + RADEXPFUNC u8 RADEXPLINK SmackSoundUseDirectSound(void PTR4* dd); // NULL=Create + RADEXPFUNC void RADEXPLINK SmackSoundSetDirectSoundHWND(HWND hw); + RADEXPFUNC u8 RADEXPLINK SmackSoundUseDW(u32 openfreq, u32 openbits, u32 openchans); + + #define SmackTimerSetup() + #define SmackTimerDone() + #define SmackTimerRead timeGetTime + + #endif + + #endif + + #ifdef __RADMAC__ + RADEXPFUNC SmackBuf PTR4* RADEXPLINK SmackBufferOpen( WindowPtr wp, u32 BlitType, u32 width, u32 height, u32 ZoomW, u32 ZoomH ); + RADEXPFUNC u32 RADEXPLINK SmackBufferBlit( SmackBuf PTR4* sbuf, s32 hwndx, s32 hwndy, s32 subx, s32 suby, s32 subw, s32 subh ); + RADEXPFUNC void RADEXPLINK SmackBufferFromScreen( SmackBuf PTR4* destbuf, s32 x, s32 y); + #else + RADEXPFUNC SmackBuf PTR4* RADEXPLINK SmackBufferOpen( HWND wnd, u32 BlitType, u32 width, u32 height, u32 ZoomW, u32 ZoomH ); + RADEXPFUNC u32 RADEXPLINK SmackBufferBlit( SmackBuf PTR4* sbuf, HDC dc, s32 hwndx, s32 hwndy, s32 subx, s32 suby, s32 subw, s32 subh ); + RADEXPFUNC void RADEXPLINK SmackBufferFromScreen( SmackBuf PTR4* destbuf, HWND hw, s32 x, s32 y); + RADEXPFUNC s32 RADEXPLINK SmackIsSoftwareCursor(void* lpDDSP,HCURSOR cur); + RADEXPFUNC s32 RADEXPLINK SmackCheckCursor(HWND wnd,s32 x,s32 y,s32 w,s32 h); + RADEXPFUNC void RADEXPLINK SmackRestoreCursor(s32 checkcount); + #endif + + RADEXPFUNC char PTR4* RADEXPLINK SmackBufferString(SmackBuf PTR4* sb,char PTR4* dest); + + RADEXPFUNC void RADEXPLINK SmackBufferNewPalette( SmackBuf PTR4* sbuf, const void PTR4* pal, u32 paltype ); + RADEXPFUNC u32 RADEXPLINK SmackBufferSetPalette( SmackBuf PTR4* sbuf ); + RADEXPFUNC void RADEXPLINK SmackBufferClose( SmackBuf PTR4* sbuf ); + + RADEXPFUNC void RADEXPLINK SmackBufferClear( SmackBuf PTR4* destbuf, u32 color); + + RADEXPFUNC void RADEXPLINK SmackBufferToBuffer( SmackBuf PTR4* destbuf, s32 destx, s32 desty, const SmackBuf PTR4* sourcebuf,s32 sourcex,s32 sourcey,s32 sourcew,s32 sourceh); + RADEXPFUNC void RADEXPLINK SmackBufferToBufferTrans( SmackBuf PTR4* destbuf, s32 destx, s32 desty, const SmackBuf PTR4* sourcebuf,s32 sourcex,s32 sourcey,s32 sourcew,s32 sourceh,u32 TransColor); + RADEXPFUNC void RADEXPLINK SmackBufferToBufferMask( SmackBuf PTR4* destbuf, s32 destx, s32 desty, const SmackBuf PTR4* sourcebuf,s32 sourcex,s32 sourcey,s32 sourcew,s32 sourceh,u32 TransColor,const SmackBuf PTR4* maskbuf); + RADEXPFUNC void RADEXPLINK SmackBufferToBufferMerge( SmackBuf PTR4* destbuf, s32 destx, s32 desty, const SmackBuf PTR4* sourcebuf,s32 sourcex,s32 sourcey,s32 sourcew,s32 sourceh,u32 TransColor,const SmackBuf PTR4* mergebuf); + RADEXPFUNC void RADEXPLINK SmackBufferCopyPalette( SmackBuf PTR4* destbuf, SmackBuf PTR4* sourcebuf, u32 remap); + + RADEXPFUNC u32 RADEXPLINK SmackBufferFocused( SmackBuf PTR4* sbuf); + +#endif + +RADDEFEND + +#endif + +#endif diff --git a/Storm/SMACKER/H/SVGA.H b/Storm/SMACKER/H/SVGA.H new file mode 100644 index 0000000..b9f51e9 --- /dev/null +++ b/Storm/SMACKER/H/SVGA.H @@ -0,0 +1,53 @@ +#ifndef SVGAH +#define SVGAH + +RADDEFSTART + + typedef void (SETBANKTYPE)(u16); + #pragma aux SETBANKTYPE "*" parm [eax] modify [eax]; + + typedef void (SETINITTYPE)(); + #pragma aux SETINITTYPE "*" modify [eax ebx ecx edx]; + + #define SVGAMode() (curmodetouse) + u8 RADLINK SVGASetup(u32 width,u32 height); + char* RADLINK SVGADetected(char* buf); + void RADLINK SVGASetText(); + void RADLINK SVGASetGraph(); + void RADLINK SVGAClear(u8 col); + void RADLINK SVGADetect(u32 flags); + u32 RADLINK SVGABytesPS(); + u16* RADLINK SVGAWinTbl(); + void* RADLINK SVGASetBank(); + u32 RADLINK SVGAFlags(); + + void RADASMLINK SVGABlit(void* buf,u32 bleft,u32 btop,u32 subbwidth,u32 subbheight,u32 bPitch,u32 screenleft,u32 screentop); + + void RADASMLINK SVGABlitTrans(void* buf,u32 bleft,u32 btop,u32 subbwidth,u32 subbheight,u32 bwidth,u32 screenleft,u32 screentop,u8 trans); + void RADASMLINK SVGABlitFrom (void* buf,u32 bleft,u32 btop,u32 subbwidth,u32 subbheight,u32 bwidth,u32 screenleft,u32 screentop); + void RADASMLINK SVGABlitMask (void* buf,u32 bleft,u32 btop,u32 subbwidth,u32 subbheight,u32 bwidth,u32 screenleft,u32 screentop,u8 maskcolor,void*backbuf); + void RADASMLINK SVGABlitMerge(void* buf,u32 bleft,u32 btop,u32 subbwidth,u32 subbheight,u32 bwidth,u32 screenleft,u32 screentop,u8 mergecolor,void*backbuf); + + void RADASMLINK SVGASetPalette(void PTR4* pal); + + extern u8 curmodetouse; + extern u32 BytesPerScanToUse; + extern u32 WidthToUse; + extern u32 HeightToUse; + extern SETBANKTYPE* SetBankToUse; + extern u16* WinTblToUse; + extern u32 FlagsToUse; + extern void* StartVGA; + extern void* EndVGA; + extern u32 VGASize; + extern u8 PaletteSkipZero; + extern u8 IsBanked; + extern u8 SVGAVESASetting; + + +#define SVGAFINDSVGA 1 +#define SVGAUSE16BIT 2 + +RADDEFEND + +#endif diff --git a/Storm/SMACKER/HISTORY.TXT b/Storm/SMACKER/HISTORY.TXT new file mode 100644 index 0000000..7830931 --- /dev/null +++ b/Storm/SMACKER/HISTORY.TXT @@ -0,0 +1,828 @@ + ============================================================================ + + This file contains most of the development history of Smacker. + + It contains changes, updates, and fixes in the Smacker Tools, the + Smacker SDK, and the Smacker Xtra. + +============================================================================ + +3.1 a - 9/29/97 +--------------- +Added MMX support throughout Smacker - playback can now be up to 200% + faster on MMX machines! +Added the new SmackBlit API for all Smacker platforms - gives SDK users a + high-performance, low-level blitting library. Supports 1x, 2x, + 2x smoothed, 2x interlaced to either 8-bit or 16-bit surfaces! See the + ExamSmkB.C example program for a nifty demo of this new API. +Added replacement blitters for machines where DirectDraw has been installed + with using the SmackBuffer API - now, whenever possible, Smacker does its + own direct to screen blitting rather than using DIBSections. +Added masked and merged blitting to the SmackBuffer, SmackBlit, and DOS + SVGA blit libraries (for much faster transparencies). +The front-end can now process a group of files one-by-one instead of only + as a group. +Added a cursor API for detecting software cursors and then easily hiding and + restoring them (for direct to screen blitting or playback). +Rewrote the DirectSound support code - should now have perfect synch and + work on most emulated sound drivers. +The Xtra and the scriptor now use the merging blitter for faster playback. +Added BitmapToBitmapMerge and BitmapToScreenMerge command to the scriptor. +Fixed a bug on the Mac when decompressing 16-bit, stereo sound. +Added a "Play Last" button on the player tab that will play the last Smacker + animation that was compressed, mixed, played, etc. Great for quickly + viewing the last animation that you created. +Made the Smacker PC Xtra not use DirectSound unless you call the new + SmackUseDirectSound global command. +Added a 2x playback mode to the Smacker Xtra (including interlaced and + smoothed modes). +Added a SmackHideVideo command to the Smacker Xtra which allows you to + hide the video without closing the Smacker object. +Added a SmackSetAlignment command to the Smacker Xtra to control how the + playback window is automatically aligned. +Added the SmackScreenMethod call to the PC Xtra. +Switched to MASM 6.11 for most of the assembly files. +Added error return codes to the SmackSetTransBackground in the Xtra. +Fixed a playback bug in the Xtra when using a cast member background. +Added Win95, Win95 OSR2, WinNT, MMX, and Pentium II detection to RADSI. +Merged the 16-bit and 32-bit blitters into one 32-bit module. +On NT and 95, SmackBuffers now always use top-down DIBSections (even when + standard DIBS are requested). + +3.0 r - 8/6/97 +-------------- +Fixed a nasty race condition in the DirectSound shutdown code. +Fixed the compressor to honor the height when it was larger than the input + height (pads with black pixels). + +3.0 q - 8/1/97 +-------------- +Fixed an optimizer crash in the compressor and graphic processor when + halftoning both 8 and 24 bit files together. +Fixed crash in graphics processor if the input and output filenames matched. +Added some extra debug dumping info in the DirectSound module. + +3.0 p - 7/25/97 (skipped "o") +----------------------------- +Fixed the filename quoting in the mixer when you used a wave file with a + space in it. +Fixed a bug in the Mac decompression code where one of the block types was + decoded incorrectly. +Fixed a bug in the summary window in the Mac 68K player. +Fixed a Mac Xtra bug where the palette wasn't being copied from the Smacker + frame. + +3.0 n - 7/15/97 +--------------- +Fixed a bug in the graphics file input routines that could cause a crash + when compressing or converting under NT 4. +Added a debug dumping facility in the SDK. (Add "debug=1" under [Smacker] + in the win.ini file to enable.) + +3.0 m - 6/25/97 +--------------- +Worked around an optimizer bug that caused list files not be saved correctly. +Added AVI files as an output file in the graphics processor. +Added a true color support to the graphics processor (it can now copy + directly from a true color input file to a true color output file). +Fixed crash in RAD system information utility. +Fixed the close button not working in the player. + +3.0 L - 6/20/97 +--------------- +Converted all the Win32 code to the Microsoft compiler - the tools now run + about 20% faster! +Improved the color quantizer slightly by using human vision color model. +Put all of the common internal Smacker APIs into a utility DLL - saved about + 400K after installation. +Fixed a crash in SmackOpen when the Smack file could not be found. +Fixed a crash in the 16-bit Smacker Xtra. +Fixed the ScreenWindowHWND command in the scriptor. +Removed the SmkW32MS.LIB file from the SDK - use SmackW32.LIB for both + Microsoft and Watcom compilers. + +3.0 k - 6/2/97 +-------------- +Added new Smacker file compiler - compile one or more Smks into an EXE. +Player tab can now view files other than Smacks (double-click). +Added many speed-ups in the Mac Xtra. +Cleaned-up some palette problems in the Mac Xtra. +Fixed the preload option in the Xtra on both PCs and Macs. +Added new SmackGetSummary command in the Xtra to report runtime performance. +Fixed return codes on the utilities. +Tools check for running out of disk space more frequently. +Fixed bug in 16-bit SDK when playing with a file handle. +Fixed a bug in the DOS player where playback could stick on the final frame. +Added a new example for 16-bit DirectDraw with 8-bit off-screen surface. +Updated to Delphi 3 for the Tools front-end. +Dropped the DOS based Tools (the DOS player, scriptor and SDK remain). + +3.0 j - 5/14/97 +-------------- +Fixed SmackGoto not setting the 16-bit palette. +Compressed the front-end executable. +Fixed the left offsets when playing into a 16-bit surface. +Finished the Mac Xtra for Director. + +3.0 i - 5/4/97 +-------------- +Smacker can decompress directly into a 16-bit buffer (on- or off-screen). +DirectDraw example programs now all support 16-bit surfaces. +Fixed the Windows and icons moving when changing the video mode in Win 95. +Changed the Mac version to try to allocate the GWorld in temp memory if + normal memory fails (helps in low mem situations). +Fixed scriptor FileFind command to return all files under Win 95 or Win NT. +Set the primary buffer format when NULL is passed to SmackSoundUseDirectSound. +Added 16-bit VESA support to SDK - use SVGAUSE16BIT in SVGADetect. +Added a flags parameter to the SmackToScreen call - you will usually just + pass SVGAFlags() - see Example.c for details. +Added a warning when the hint file could not be opened. +Fixed a problem in the front-end where compressing losslessly didn't always + work correctly. + +3.0 h - 4/14/97 +-------------- +Fixed a bug in high-color mode on the Mac. +Fixed a bug if SmackSoundOnOff was called when no sound was playing. +Fixed bug in Xtra destructor (it was harmless - but a bug nonetheless). +Added MSS Xtra support into the Smacker Xtra. + +3.0 g - 3/9/97 +-------------- +Fixed Xtra to not display a black frame when playback begins. +Switched to new Causeway extender. +Fixed a bug in the VESA linear address code when switching to a new VESA + mode without switching to text mode first. +Added ability to convert 4-bit (16 color AVIs) - these AVIs are very rare. +Fixed a DirectSound deadlock when you use MSS and Smacker both with + DirectSound - you should now call SmackSoundUseDirectSound only if + you are using Smacker without MSS - otherwise, always call + SmackSoundUseMSS. +Added CFM Smacker library to the Mac SDK. +Added an A4-relative library to the Mac SDK. + +3.0 f - 2/16/97 +--------------- +Fixed mixing error when mixing with very slow frame rates and very fast + sound data rates. +Fixed some Xtra problems with focus control and mouse clicking. +Fixed some Xtra weirdnesses with odd palette remapping modes. +Fixed some Xtra problems with full-screen mode. +Fixed Xtra playback in 16-bit color depth mode. +Improved quality of halftoned images. + +3.0 e - 1/28/97 +--------------- +Try to open a graphics file as a TGA before a JPEG to handle TGAs that + have "jpeg-ish" headers. +Made the maximum frame rate 10000 fps. +Added new mouse functions and display mode switching to the Smacker Xtra. + +3.0 d - 1/22/97 +--------------- +Fixed the front-end resizing when new screen size is too small for the + front-end window. +Fixed the front-end to allow negative frame rates (for ms per frame). +Fixed the front-end when clicking on the change frame rate button. +Fixed display of centered movies that exactly matched the current screen + size under Windows NT. +Fixed crash when displaying a Smacker summary with the Win32 player under + Windows 3.x. +Fixed crash in the 16-bit player under Windows NT 4.0 (worked around the + new, buggy DPMI host). +Added a simple RAW graphics import type for each Smacker input (call us for + the exact file format). +Fixed halftoning of 8-bit input files. + +3.0 c - 1/20/97 +--------------- +Added ability to directly Smack wave files into a sound-only Smk file. +Added a double-buffered DispDIB 320x200 mode in the SDK. +Speeded-up Smacker batch file processing. +Fixed batch file processing of very long commmand lines. +Updated copyright notices. +Fixed halftoning when processing list files. +Fixed Smacking of non-4x4 animation files. + +3.0 b - 1/10/97 +--------------- +Added the new help file. +Merged in the Xtra code changes. +Added a few const defines in the SDK. +Made the Smacker DLLs check to see if they are incorrectly installed + in the Windows or Windows system directory. +Added some hint text in the Expert sub-tab on the Smack tab. +Added a specific lossless compression mode in the Smack tab. +Fixed a crash in the DOS mixer. +Changed the auto-key frame default to 95%. +Made the main tab hook directly to our web page. +Updated the Mac SDK to 3.0b. +Fixed offset blitting in SmackBufferBlit on Mac. + +3.0 a - 1/8/97 +-------------- +Fixed processing of single image filenames that are zero-padded. +Switched to an hourglass when reading large directories. +Fixed the directory and drive properties window. +Made some small changes to the short-cuts in the front-end. + +2.2 k - 1/2/97 +-------------- +Added intelligent halftoning (tries to only halftone gradients). +Reversed the order of this history file. +Allow multiple calls to UseMSS under Windows NT. + +2.2 j - 12/17/96 +---------------- +The compressor can now process sound while it is compressing the video. +The front-end has new compression settings for sound in the Smack tab. +You can now use any data rate (not just 11025, 22050, and 44100) for sound. +Fixed a bug when encoding some Smacker palettes. +Fixed conversion of 32-bit AVIs (24-bit worked fine). +Fixed problem with Borland 4.5 and Smacker header file in SDK. +Added switch for the player to use DirectSound (/Z). +Added command for the scriptor to use DirectSound (SYSTEMUSEDIRECTSOUND). +The mixer and the sound processor can take a list of sound files. +Fixed border when compressing different sized list files with a ring frame. +Added ability to show frame numbers in the Windows player. + +2.2 i - 12/8/96 +--------------- +Fixed zooming with CreateDIBSection blitter. +Fixed error when playing extremely long movies with high data rate sound. +Improved frame timing slightly (should help on > 15 minute movies). +Added an option to the player to only show the differences between frames. +Added an option to the player to not pause the video when the focus is lost. + +2.2 h - 11/22/96 +---------------- +Changed the way file handles are read to work with all C compilers under + Windows - use _lopen for 16-bit, CreateFile for 32-bit. +Integrated Diamondware sound support to Windows version. +Added CreateDIBSection support for Win95 and WinNT - WinG is now only + necessary for 16-bit and Win32s playback. +Added a DirectDraw example that shows how to use Smacker with a 16-bit + color pimary surface (ExamDDP6.C and DoDDP6.BAT). + +2.2 g - 11/19/96 +---------------- +Fixed overly large frame compression on palette switches. +Fixed problem when compressing with "% of its size" option. +Fixed weird palette compression bug when rotating palette counter-clockwise. +Added raw output type to Sound Processor. +Fixed ring frame creation when using a non-final end frame. +Added non-sound mixing to SmackMixer. +Expanded compression ranges for "% of average" and "% of its size" (1-200%). +Fixed Smacker's support for DirectX II (DirectX III worked fine). +Smacker commands minimize nicer now. + +2.2 f - 11/15/96 +---------------- +Fixed every frame full window repaints on high-color video cards. +Removed the second parameter from SmackSoundUseMSS under DOS (wasn't + necessary anymore). +SmackMix can now take WAVs, AVIs or Smks as sound input files. +SmackMix can change the sound format type on the fly. +SmackMix mixes sound into Smacker files with ring frames correctly. +Major improvements in compressor quality over multiple frames. +Compressor is much faster with certain types of flics. +Smacker analysis tool doesn't count the first frame in the moving average. + +2.2 e - 11/11/96 +---------------- +Changed front-end notification message number to avoid control conflicts. +Fixed conversions of 24-bit still images. +Fixed left-over temp files when you cancel during SmackC. + +2.2 d - 11/07/96 +---------------- +Fixed AVI sound extraction. +Fixed focus order in Front-end. +Fixed click on same name from a different tab with no highlighting. +Changed the utility sub-windows to be 3D. +Changed the player utility window to be 3D and added several other + window styles (/I#). +Added new scriptor command to change window border type: + SCREENWINDOWBORDER type. 0=thick, 1=thin, 2=none. +Removed setting of thread priorities in Scriptor and player. + +2.2 c - 11/05/96 +---------------- +The Smacker compressor can now compress AVIs, BMPs, TGAs, GIFs, TIFs, + PCXs, JPGs and list files directly. +Fixed pop-up window after playing movie from Explorer in NT. +Added a list file editor to the front-end. +You can now highlight a group of files to create a list file from. +Added the new Sound Processor utility. It takes Wavs, Smks and AVIs + files as input and writes out wave files. It comes in both DOS + and Windows versions. +Sound Processor filters sound when scaling to different rates to avoid + the "tinny" sound when upscaling. +ToWav, SmackUnm, and SmackUnW have all been removed (replaced by the + general purpose sound processor. +OSmk2Flc removed and placed separately on ftp site. +Added starting and ending millisecond times to the Sound Processor. + +2.2 b - 10/23/96 +---------------- +Simplied front-end for converters. +Multimedia tab has been removed - just double-click on a file to play it. +Front-end has built-in viewers for bmp, gif, pcx, tif, tga, and jpg. +Graphics processor uses an improved color reduction method. +Graphics processor can take an input palette. +Graphics processor can overlay windows colors on conversion. +Graphics processor can extract portions of a frame (X,Y,W,H). +Graphics processor can take Smack files as input. +Graphics processor can take a list of files to convert. +Crash when converting single image files is fixed. +SmkInfo can display info on wav,avi,bmp,gif,pcx,tif,tga and jpg files. +FlicJoin and FlicCpy were dropped (GraphPr has these features now). +Graphics processor can save as BMPs, GIFs, PCXs, TIFs, TGAs or JPGs. +Added multiple Smacks example program (ExamMult.C) to SDK. +Smacker now requires 3.50F of MSS. +Fixed pause of Smacker animations on MSSW with large internal MSS buffers. +Made the Smacker decompressor tolerant of file i/o errors - when an read + error occurs, Smacker goes into a friendly skip mode. +Fixed crash when playing two flics in a row with the 320x200 and 320x240 + full screen modes. + +2.2 a - 9/23/96 +--------------- +Fixed scrolling in front end for goto and find editor commands. +Added web page button in front end. + +2.1 m - 9/20/96 +--------------- +Utilities 32-bit only - Win95 and Windows NT - no more Win3.x. +New 32-bit front end - long filenames. +SmackTune now built into the front end. +ToFlic now runs under NT and is much, much faster. +SmackC now has more compress types. +Fixed bug in SmackC when compressing multiple files. +Fixed error in calling SmackSoundOnOff back to on. +Added BitmapToBitmapMask and BitmapToScreenMask commands to scriptor. +Added SystemCurrentExe to scriptor. +Made scriptor clip when blitting, lines, rects, etc. +Fixed scriptor loosing current directory on FilePieces. + +2.1 l - 9/10/96 +--------------- +Fixed the return value of SmackDoFrame when SMACKNOSKIP is specified. + +2.1 k - 8/22/96 +--------------- +Rewrote compressor lossy engine to be data rate based +Added auto-key framing to compressor. +Raised limit on code overflows in compressor. +Add new frame skipping logic resulting in much fewer frame skips on low + data rate devices. +New cursor management code on Macs. +Fixed crashes in scriptor. +Added AnimationTracks command in the scriptor. +Added auto run feature to scriptor - rename script to autoexec.ss and they + run when scriptor is run without parameters. +Removed the SmackToScreen option from the Mac (use SmackBuffers with the + SMACKDIRECTBLIT option). + +2.1 j - 08/10/96 +---------------- +Switched to new MSS for DOS and Windows. +Fixed 16-bit sound on 68K Macs. +Switched to Microseconds call on Macs. +Switched to new 64-bit divide on Macs. +Fixed palette problems on Mac. +Fixed 44 Khz sound on Mac. +Improved 2x blitting on Mac by 8 times. +SmackBufferFocused uses process id to determine focus. +Added new blit type for Mac (it is the default on 8-bit): + SMACKGWORLDCUSTOMBLIT. +Blitters are 25% faster on Mac. + +2.1 i - 07/10/96 +---------------- +Allow multiple calls to SmackSoundUseMSS (make sure all smks are closed 1st). +RADSIW returns accurate Mhz for Pentium Pros. + +2.1 h - 06/21/96 +---------------- +Now query the VTD vxd device for timing info under Win3 and Win95 DOS boxes. + +2.1 g - 06/19/96 +---------------- +Fixed non-export of hook procedure in 16-bit DLL - cause full 320x200 to fail. +Fixed sync of 22Khz sound with MSS for DOS. +Removed outputdebugstring in directsound code. +Fixed odd-sized SmackBuffer problem (use Pitch in SmackToBuffer, BTW). + +2.1 f - 06/06/96 +---------------- +Fixed capitalization of the Unsmack function. +Made the 16-bit SmackW16 thunk to SmackW32 on WinNT. +Switched to the stdcall calling convention in SmackW32. +Use declspec imports in Smack.H to optimize Smacker calls. +The 16-bit DLL can switch modes under NT. +Fixed extra mode reset under Windows NT. +Now ship with Borland DEF file. +Fixed SmackFromScreen when hwnd is valid and not at 0,0. + +2.1 e - 05/25/96 +---------------- +Fixed SmkInfo opening files in read/write mode. +Fixed Mac looping of sound. +Improved sound synch on Mac. +Fixed ToFlic and MMInfo reading PCXs with TGA-style headers. +Fixed compressing palette fade-ins. +Fixed palette fades on >256 color cards. +Optimized palette fade-ins and fade-outs. +Rewrote low-level decompressor - up to 30% faster on 586, up to 12% on 486. +Added doubled playback along the y axis. +Fixed opening more than 32 Smackers in the 16-bit DLL. +Improved memory allocation code. +Made SmackSoundUseDirectSound take a DirectSound object instead of a HWND. +Fixed mixer sound type switches and descriptions in front end. +Added new compression and playback options to front end. +Added three directdraw example programs: examdds, examddp, and examddf. + +2.1 d - 04/25/96 +---------------- +Added interleaving to Smack compressor. +Compiled with Watcom 10.6. +Fixed stupid looping sound synch error for MSS and MSSW. +Change new palette logic to handle jumping to the same frame that you're on. +Fixed DirectSound volume control. +Use NewPtr and MultiFinder temporary memory instead on malloc on Mac. +Fixed looping of Smacker movies with sound on Mac. +Fixed looping of preloaded Smacker movies on Mac. + +2.1 c - 04/09/96 +---------------- +Made NULL buf in call to SmackToBuffer turn off video but leave sound on. +Adjusted mixer to be more tolerant of weird format headers in WAV files. +Fixed SOS code for new version of SOS 4 (must now have SOS4 1/26/96 version). +Mac memory allocation now uses NewPtr and NewSysPtr for memory allocation. + +2.1 b - 03/18/96 +---------------- +Added new switch to SmackPlay to force the extra buffer to be filled on open. +Fixed stupid clipping error in the sound mixer for 16 bit sound. + +2.1 a - 03/11/96 +---------------- +Fixed error when you changed the volume with SOS before the first frame. + +2.0 y - 02/27/96 +---------------- +Fixed leak if preloading a smack file, and not enough memory was available. +Fixed divide by zero error in the Miles Sound System code. +Fixed divide by zero error in the HMI code. +Fixed nasty overwrite bug in the background buffering code. +Fixed color palette weirdness on Mac Quadra AVs. + +2.0 x - 02/19/96 +---------------- +Used new Causeway extender. +Fixed a problem with offsets when zoomed on the Mac. +Adjusted the way ToFlic creates its palettes (weight green higher). +Fixed a problem with the smacker extra buffer when specified as zero. + +2.0 w - 02/07/96 +---------------- +Switched to new combined Win32/Win32s MSS DLL. + +2.0 v - 01/16/96 +---------------- +Fixed MSS and MSSW sync code. + +2.0 u - 01/09/96 +---------------- +Remerged final Mac SDK. +Major changes in sound subsystem - simplified third-pary lib use. +Fairly major changes for Windows DLLs - just the two DLLs now. +Half dozen or so minor SDK changes to match Mac. + +2.0 t - 01/02/96 +---------------- +Fixed buffer bug when using very tiny extra buffer amounts. +Add ability for player (/D##) and scriptor (WindowsDisplayResolution) to + set the screen display mode (under Win95 and NT only). +Fixed ToFlic converter leaving a DLL in memory. +Fixed ToFlic converter for mostly dark images. +Optimized skipping to a frame that is already in the read ahead buffer. +Added new Smacker DLL for WAIL with Win32s. + +2.0 s - 12/22/95 +---------------- +Major improvement in buffering system - will lower dropped frames by half. +Adjust VGA detection routine to allow for strange VGAs. +Fixed AIL too agressively dropping frames. + +2.0 r - 12/04/95 +---------------- +First Mac code integrated back into RAD.h Smack.h Rfile,h lowsnd.h + and Smackinp.cpp. +Header files pretty drastically modified (to add Mac support). +Upgraded to patch level 'a' for Watcom 10.5 - fixes several DOS problems. + +2.0 q - 11/28/95 +---------------- +Recompiled with WAIL 3.03D - you must update to this version for Smacker. +Fixed caption option in the 16-bit Smacker playback utility. +Optimized palette fade out compression. + +2.0 p - 11/27/95 +---------------- +Fixed nasty bug in 16-bit WAIL support code (good catch Illumina). +Tweaked DOS HMI timer code. + +2.0 o +----- +Speeded up looping of ring frames in scriptor. +Added new DebugFile command that dumps your script to a file as it runs. +Added new DebugText command that dumps to the DumpFile output. +Dialed in DirectSound synching code. + +2.0 n +----- +Fixed resync after loss of synch in WAIL. +Changed SmackToBufferRect param to a u32. + +2.0 m +----- +Tweaked WAIL synching code. +Added ability to set ms per frame down to hundredth of a ms to all utilities. +Remove BreakPoints from ToFlic and SmackW32.DLL. + +2.0 l +----- +Tweaking SmackBuffer close code. + +2.0 k +----- +Fixed stupid flag reversal in SmackBufferNewPalette code. +Fix Y coordinate in fliccpy. +Locked more of the AIL data structures for DOS under Win95. +Added example program that does its own i/o. +DirectSound support. + +2.0 j +----- +WAIL DLL unloaded problem fixed. +AIL under DOS locking problem fixed. +Added palette type for SmackBufferNewPalette (same flags as SmackColorRemap). +Added check for null pointers in all Smack functions. + +2.0 i +----- +Temporary DirectSound support for Zombie. + +2.0 h +----- +Fixed timer code for AIL under DOS. + +2.0 g +----- +Added WAIL support to the SDK. +Took out automatic timer slow down on SVGASetText and SVGASetGraphics. + +2.0 f +----- +Added mousemode command for absolute mouse devices under DOS. +Used the new dead code eliminator in Watcom 10.5 to make utilities smaller. +Minor optimizations to compressor and toflic converter. +Tweaked flic output code so that copies will byte compare as identical. +Fixed double-buffered playback under DOS with larger vesa modes. + +2.0 e +----- +Fixed stack error with HMI 4 (make sure you have HMI 4 from 9/11/95). +Fixed error in front end with blank switches. +Fixed error on exit from player after help displayed. +Fixed conversion of 16-bit images to flics. + +2.0 d +----- +Tweaked timer code. +Fixed looping error in scriptor. +Fixed button highlighting in scriptor tab. +Fixed file i/o in scriptor under Win386. +Added support in the SDK for HMI4. + +2.0 c +----- +Fixed bug when playing multiple sound Smacker file in a row with SmackPly. + +2.0 b +----- +Switched to Watcom 10.5 (files got smaller for some reason). +Added API support for Borland (Windows only - no powerpack). +Tweaked full-screen mode setting for 16-bit SmackBuffers. +Added SmackBufferFocused command. + +2.0 a +----- +Fixed palette clearing after mode set. +Added new fliccpy command. +Finished demo. +Keep fractional frame rates hidden in the flic file. +Fixed line and button settings on restore of edit tab in Scriptor tab. +Fixed saving current edit position in scriptor tab. +ESC on command to run in command tab will clear the line first. +Fixed Ctrl-PageDown in edit memo boxes. +Changed Multimedia tab, so that it doesn't automatically open the MCI file. +Fixed file highlight after a file find or recent file choice. +Fixed crash when sound interrupted under NT. +Fixed beeping under Win32s +Fixed loop around slowdown when using animationadvance to the end of a flic. +Updated help files. +Fixed a null region select in weird palette reselect cases. +Fixed GPF when using Recent Directories after running the scriptor. +Fixed multiple notification to parent from scriptor. +Created better default mouse for scriptor (12x20). +Fixed crash on looping under NT 3.51. +Fixed dragging on a lower priority for smoother dragging. +Switched to AIL-lite sound library for DOS version. +Switched to the Causeway extender for DOS version (compressed EXEs). +Major change to the DispDIB code for greater compatibility (changed API). +Improved ToFlic quantoning on darker colors. +Made palettes into keypalettes on keyframes. +Allow copy from the pop-up copy file option to a directory name. + +1.9 u +----- +Took thread priorities out of Smackinp - put into player and + scriptor directly. +Took out feature of calling SmackerW with SMK or SS - put into SMACKGO.EXE. +Fixed misspellings and always asking to install FFS, VFW or Win32s. +Fixed cursor on utility windows. +Fixed compressing flics directly from read-only media. +Fixed div error when mixed non-sound data. +Fixed new palette on input change error in toflic. +Fixed using SmackBuffers with SYSPAL_NOSTATIC turned on. +Fixed error using ".." with DirChange in scriptor. +Added SystemPaletteLock command in scriptor. +Fixed centering error on odd-sized flics under the DOS scriptor. + +1.9 t +----- +Cleaned up help significantly. +The front-end has context-sensitive help for the scriptor (Ctrl-F1). +Fixed locating file associations under Win95. +Fixed rare crash when compressing under Win32s. +First CD-based version. +All new set-up programs. +Can call SmackerW with an SMK or a SS to play. + +1.9 s +----- +Added help to front end. +Fixed scriptor problem where you move up to 640x480 then back to 320x200. +Fixed error passing in SMACKTRACKS to SmackVolume. + +1.9 r +----- +Renamed a few executables for consistency (ToFlicW6, SmkInfoW, MMInfoW). +Front-end figures out if it is running WinNT/Win95/Win32 and runs Win32s + versions of the utilities, otherwise it runs the 16 bit versions. +Fixed crash at end of toflic.exe under NT and Win95. +Fixed reversal of channels and quality flags in SmackUnmix. +Added the built-in SVGA (non-vesa) drivers from FastGraph. +Fixed too short entry for simulate and extra mem in front-end for player. +Fixed error where high indexes mapped to lower indexes in SmackC. +SmackOnOff releases the Windows waveout handle while it is off (SDK). +Fixed simulation speeds under Windows 3.11 with SmackPlay. +Fixed variable deletion when another variable holds same variable (scriptor). +Fixed palette loading in AnimationLoadToBitmap command. +Added VESA controls in player (/A option). +Added VESA control in DOS scriptor-SCREENSETTINGS num (num same as /A). +Added blitter control in Windows scriptor-SCREENSETTINGS num (num same as + /V in Windows player). +Added ScreenInfo command in scriptor - returns settings used for display. +Added frame specific settings in DOS and Windows. + +1.9 q +----- +Added ScreenWindowAutoPause command in SmackScript (pauses when lose focus). +Added ScreenWindowHasFocus (returns whether SmackScript has focus). +Fixed slow loading of the player from 16 bit apps under WinNT. +Bump up the thread priority automatically under NT and Win95. +Fixed support for VBEs that hose the top of the extended registers (UNIVBE). +Added support for VBE 2.0 32 bit bank switching. +Added support for VBE 2.0 32 bit linear frame buffering - very,very fast. +Fixed bug in playback of very large, or very unusual flics. +Removed support for FlashTek's X32. + +1.9 p +----- +Adjusted RAD.H for Microsoft. +Fixed SmackW32.DLL linker error. +Fixed file buffering for NT (fixes all sorts of weird errors on 3.51). +Fixed port calls to avoid NT exceptions. +Did import library for MSC 2 - nightmare city. +Added support for full-screen under Win95 - another nightmare city. +Made front-end icon show in title bar under Win95. +Made copy command in front-end retain the file times. +Fixed front-end not restoring with Win95 (bug in build 490 and below). +Fixed front-end error when sub-process sends finish flag at awkward time. + +1.9 o +----- +Fixed non-display of VESA modes with DOS radsi.exe. +Switched all of the windows utilities to Win32s versions (normal Windows + versions of the scriptor and player are still licenseable). This allows + the utilities to run well under Win NT and Win95. + +1.9 n +----- +Fixed directory command in SmackerW. +Fixed playback problem with extremely small Smks (less than 2K). +Added Recently used file and directory options. +Fixed error on directory with invalid file date/times. +Fixed error renaming/copying twice in a row. +Now allow more than one rename/copy window open at a time. +You can use wildcards in del, ren, copy. +Rename directory remembers where it is. +Can make Smacker Batch files (*.SBT files). +File attributes windows and command. +Find File command. +Batch file editor. +Fixed error holding down down arrow in command history. +Added Cls,SaveHist,type and edit commands in command line. +Handle switching away from default drive and back again. +Fixed problem where script files weren't being closed. +Fixed problem where utilities couldn't allocate a window. +Speeded up fades in the Windows scriptor. + +1.9 m +----- +Fixed SmackMixing into non-first frame . +Created SmackMix option to loop the sound over and over. +New front-end (tab based, written in Delphi). + +1.9 l +----- +Fixed blip that occurred when playing very short sound files. + +1.9 k +----- +Fixed 100* error in negative frame rates with SmackPly. +Finished sound extractor - can also convert between wav formats. + +1.9 j +----- +Changed the way the SmackBlw.DLL initializes palettes to account for + buggy Diamond display drivers. +Added replaceable font support in SmackScript . + (TEXTFONTFROMBITMAP bitmapvariable,charwidth,charheight,startcharnum,endcharnum) +Added easy loading bitmap support in SmackScript . + (opens a smk, allocs a bitmap, puts each frame into a bitmap) + (ANIMATIONLOADTOBITMAP smkname, bitmap1, bitmap2, etc). +Added BitmapWidth, BitmapHeight commands in SmackScript. +Switched to latest HMI version (2/5/95). +Set the blit mode when using STANDARDBLIT to COLORONCOLOR in Windows. + +1.9 i +----- +Fix divide by zero error when compressing unusual flics. +Palette fades compress better. + +1.9 h +----- +8/16 bit AVIs are handled by ToFlic. +TGA, PCX, BMP, GIF, TIF, and JPEG are handled by ToFlic. +Palette remapping has been improved - it is now the default on 256 cards. +Can specify key frames with SmackC. +SmackC handle negative frame rates correctly (as MS Per Frame). + +1.9 g +----- +Fixed off by one error on ScreenFilledBox when on reversed WinG screens. +Added file handle options on SmackOpen. + +1.9 f +----- +Windows front end updated. +New palette setting code. +Fixed bug in scriptor. +Scriptor sped up by 100%. +Fixed bug in Windows scriptor when playing a sound. + +1.9 d +----- +Scriptor added. +Most of the utilities slightly updated. + +1.8 s +----- +Fixed SmackScr when using unusual multiple VESA windows. + +1.8 q +----- +SmackScr will reset the mouse cursor on a mouse add. +SmackPlw will skip frames if it is falling behind the audio. + +1.8 p +----- +Smackc can take a list of flics to compressed instead of just one (useful + when your flics are huge and you don't want to join them.) +ToFlic gives info on PCX, GIF, TIF, TGA, JPG, and BMP files. + diff --git a/Storm/SMACKER/LIB/MSSLITE.LIB b/Storm/SMACKER/LIB/MSSLITE.LIB new file mode 100644 index 0000000..4c81134 Binary files /dev/null and b/Storm/SMACKER/LIB/MSSLITE.LIB differ diff --git a/Storm/SMACKER/LIB/SMACK.LIB b/Storm/SMACKER/LIB/SMACK.LIB new file mode 100644 index 0000000..5730d52 Binary files /dev/null and b/Storm/SMACKER/LIB/SMACK.LIB differ diff --git a/Storm/SMACKER/LIB/SMACKW16.LIB b/Storm/SMACKER/LIB/SMACKW16.LIB new file mode 100644 index 0000000..f8fa543 Binary files /dev/null and b/Storm/SMACKER/LIB/SMACKW16.LIB differ diff --git a/Storm/SMACKER/LIB/SMACKW32.LIB b/Storm/SMACKER/LIB/SMACKW32.LIB new file mode 100644 index 0000000..e70aa45 Binary files /dev/null and b/Storm/SMACKER/LIB/SMACKW32.LIB differ diff --git a/Storm/SOURCE/BATTLE/AD.CPP b/Storm/SOURCE/BATTLE/AD.CPP new file mode 100644 index 0000000..d44c1a5 --- /dev/null +++ b/Storm/SOURCE/BATTLE/AD.CPP @@ -0,0 +1,558 @@ +/*************************************************************************** +* +* ad.cpp +* Battle.net advertisement handling +* +* +* By Michael Morhaime +* +* NOTE: The advertisement window is implimented as a modeless dialog. Since the chatroom is a modal +* dialog, the bnetlogo dialog (the chatroom's parent) is disabled. If we were to impliment the +* ad window as a simple window and child of bnetlogo, the ad window also would be disabled and would +* never receive mouse click messages. +* +* Therefore, the advertisement window is, in fact, a modeless dialog with no child windows. Whenever +* it receives a mouse click, it processes the click without allowing the window to activate. +***/ + + +//**************************************************************************** +// Modification Log: +// +// Diablo Patch #1 +// 2/17/97 MM - Added call to SrvNotifyDisplayAd() upon successful display of ad. +// +// Starcraft Modifications +// 10/21/97 DML - Changed ad window to industry standard 468x60 pixels +// Will blt old ads clipped to this window +//**************************************************************************** + +#include "pch.h" + +//*************************************************************************** +#define MAX_URL_SIZE 1024 +#define BATTLE_HTML_FILE "battle.htm" +#define AD_TIMER_DELAY 50 // 20 fps is our max frame rate +#define AD_WIDTH 468 +#define AD_HEIGHT 60 + +#define PREFSKEY "Preferences" +#define PREFSVALUE_USEDLINK "Clicked Link" + +//*************************************************************************** +typedef struct _TADINFO { + DWORD dwAdId; + DWORD dwAdType; + char szAdURL[MAX_URL_SIZE]; + char szAdFilename[MAX_PATH]; +} TADINFO, *PTADINFO; + +//*************************************************************************** + +static HWND sghWndAd = NULL; + +static LPBYTE sgpAdData = NULL; +static SIZE sgAdSize; + +static HSVIDEO sghVideo = NULL; +static LPBYTE sgpAdAnimation = NULL; // Holds Smack flic +static UINT sgAdTimer = 0; + + +// Current ad information +static TADINFO sgCurrAdInfo = { 0 }; +static TADINFO sgNextAdInfo = { 0 }; + + +BOOL UiSetCustomArt (HWND hWnd, + PALETTEENTRY *pe, + int nFirstColor, + int nNumColorsUsed, + BOOL bSetPaletteNow, + LPBYTE data, + int nWidth, + int nHeight); + + + + +//*************************************************************************** +static void AdStopAd(void) { + // free any memory associated with the current Ad + sgCurrAdInfo.szAdURL[0] = 0; + sgCurrAdInfo.szAdFilename[0] = 0; + + if (sgAdTimer) { + SDlgKillTimer(sghWndAd, sgAdTimer); + sgAdTimer = 0; + } + + if (sghVideo) { + SVidPlayEnd(sghVideo); + sghVideo = NULL; + } + + if (sgpAdAnimation) { + FREE(sgpAdAnimation); + sgpAdAnimation = NULL; + } +} + +//*************************************************************************** +static BOOL AdInitWindow(HWND hWndAd, SNETGETARTPROC artcallback) { + RECT r; + LPBYTE pTemp = NULL; + SIZE tempSize; + int nSize; + + sghWndAd = hWndAd; + if (!sghWndAd) + return FALSE; + + + SetWindowPos( + sghWndAd, + NULL, + 0, 0, AD_WIDTH, AD_HEIGHT, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); + + GetClientRect(hWndAd, &r); + sgAdSize.cx = r.right; + sgAdSize.cy = r.bottom; + + // make sure window has double word width + sgAdSize.cx += (4 - sgAdSize.cx%4); + nSize = sgAdSize.cx * sgAdSize.cy; + sgpAdData = (LPBYTE)ALLOC(nSize); + if (sgpAdData == NULL) + return FALSE; + + // Init to blackness + ZeroMemory(sgpAdData, nSize); + + SDlgSetBitmap( + hWndAd, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + sgpAdData, + NULL, + sgAdSize.cx, + sgAdSize.cy); + + + UiLoadCustomArt( + artcallback, + NULL, + SNET_ART_BATTLE_WELCOME_AD, + 32, + 64, + TRUE, + &pTemp, + &tempSize); + + // Set up welcome ad to point to battle.net + strcpy(sgCurrAdInfo.szAdURL, "http://www.battle.net"); + + if (pTemp) { + // Copy bitmap to Ad buffer + SBltROP3(sgpAdData, pTemp, min(tempSize.cx, sgAdSize.cx), min(tempSize.cy, sgAdSize.cy), sgAdSize.cx, tempSize.cx, NULL, SRCCOPY); + + // Free bitmap + FREE(pTemp); + } + + return (TRUE); +} + +//*************************************************************************** +static void AdDestroyWindow(void) { + AdStopAd(); + + sghWndAd = NULL; + if (sgpAdData) { + FREE(sgpAdData); + sgpAdData = NULL; + } +} + + +//*************************************************************************** +void AdSetInfo(SNADINFOPTR pAdInfo) { + + // Set type of ad + sgNextAdInfo.dwAdType = pAdInfo->adtype; + sgNextAdInfo.dwAdId = pAdInfo->id; + + // Copy url string + if (strlen(pAdInfo->url) < sizeof(sgNextAdInfo.szAdURL)) + strcpy(sgNextAdInfo.szAdURL, pAdInfo->url); + else + sgNextAdInfo.szAdURL[0] = 0; + + // Copy filename string + if (strlen(pAdInfo->filename) < sizeof(sgNextAdInfo.szAdFilename)) + strcpy(sgNextAdInfo.szAdFilename, pAdInfo->filename); + else + sgNextAdInfo.szAdFilename[0] = 0; +} + + + +//*************************************************************************** +static BOOL AdDisplayPCX(LPBYTE pPCXData, DWORD dwSize) { + PALETTEENTRY pe[256]; + LPBYTE pBuffer; + DWORD dwBufferSize; + int nWidth, nHeight, nBitDepth; + + + if (!sghWndAd) + return FALSE; + + // Query decode function for dimensions of pcx + if (!SBmpDecodeImage(SBMP_IMAGETYPE_PCX, + pPCXData, + dwSize, + &pe[0], + NULL, + 0, + &nWidth, + &nHeight, + &nBitDepth)) + return 0; + + dwBufferSize = nWidth*nHeight*nBitDepth/8; + pBuffer = (LPBYTE)ALLOC(dwBufferSize); + if (pBuffer == NULL) + return 0; + + if (!SBmpDecodeImage(SBMP_IMAGETYPE_PCX, + pPCXData, + dwSize, + &pe[0], + pBuffer, + dwBufferSize, + &nWidth, + &nHeight, + &nBitDepth)) { + FREE(pBuffer); + return 0; + } + + + // Clear window before changing palette + RECT r; + GetClientRect(sghWndAd, &r); + SDlgBltToWindow( + sghWndAd, + NULL, + 0, 0, + pBuffer, // This isn't used, but can't be NULL anyways + &r, + (LPSIZE)&r.right, + 0xffffffff, + 0, + BLACKNESS); + + + + // Set this bitmap in the add window + if (!UiSetCustomArt(NULL, // This means just set palette entries (leave window bitmap ptr unchanged) + &pe[0], + 32, // FIRST AD COLOR + 64, // NUM AD COLORS + TRUE, // Set palette now + pBuffer, // Ad data + nWidth, + nHeight)) { + FREE(pBuffer); + return 0; + } + + // Copy bitmap to AdData ptr + SBltROP3(sgpAdData, + pBuffer, + min(nWidth, sgAdSize.cx), + min(nHeight, sgAdSize.cy), + sgAdSize.cx, + nWidth, + NULL, + SRCCOPY); + InvalidateRect(sghWndAd, NULL, FALSE); + + // Free bitmap + FREE(pBuffer); + return 1; +} + + +//*************************************************************************** +static void CALLBACK AdSMKTimer(HWND hWnd, UINT uMsg, UINT uID, DWORD dwTime) { + BOOL bUpdated = FALSE; + + if (sghVideo == NULL) + return; + + SVidPlayContinueSingle (sghVideo, FALSE, &bUpdated); + + if (bUpdated) + InvalidateRect(hWnd, NULL, FALSE); +} + +//*************************************************************************** +static BOOL AdDisplaySMK(LPBYTE pSMKData, DWORD dwSize) { +// @#@ resolve crash playing smacks to different sized buffer + return 0; + + RECT r; + SVIDPALETTEUSE paletteUse = { sizeof(SVIDPALETTEUSE), 32, 64 }; + + + if (!sghWndAd) + return FALSE; + + sgpAdAnimation = (LPBYTE)ALLOC(dwSize); + if (!sgpAdAnimation) + return FALSE; + + // Make our own copy of the animation + memcpy(sgpAdAnimation, pSMKData, dwSize); + + SetRect(&r, 0, 0, sgAdSize.cx-1, sgAdSize.cy-1); + SVidPlayBeginFromMemory(sgpAdAnimation, + dwSize, + sgpAdData, + &r, + &sgAdSize, + &paletteUse, + SVID_FLAG_TOBUFFER | SVID_FLAG_LOOP, + &sghVideo); + sgAdTimer = SDlgSetTimer(sghWndAd, 1, AD_TIMER_DELAY, AdSMKTimer); + + GetClientRect(sghWndAd, &r); + SDlgBltToWindow( + sghWndAd, + NULL, + 0, 0, + sgpAdAnimation, // This isn't used, but can't be NULL anyways + &r, + (LPSIZE)&r.right, + 0xffffffff, + 0, + BLACKNESS); + + return 1; +} + +//*************************************************************************** +void AdDisplay(LPVOID pData, DWORD dwSize) { + BOOL bSuccess; + + + if (!sghWndAd) + return; + + AdStopAd(); + + // Handle advertisement data based on ad type + switch(sgNextAdInfo.dwAdType) { + case ADTYPE_PCX: + bSuccess = AdDisplayPCX((LPBYTE) pData, dwSize); + break; + + case ADTYPE_SMK: + bSuccess = AdDisplaySMK((LPBYTE) pData, dwSize); + break; + } + + if (bSuccess) { + sgCurrAdInfo = sgNextAdInfo; + SrvNotifyDisplayAd(sgCurrAdInfo.dwAdId, sgCurrAdInfo.szAdFilename, sgCurrAdInfo.szAdURL); + } +} + + + +//*************************************************************************** +void AdNavigate(SNETUIDATAPTR interfacedata) { + char szText[256]; + char szTitle[32]; + char szBrowserApp[MAX_PATH]; + char szURLSave[MAX_URL_SIZE]; + FILE *fp; + BOOL bAdSuccess = TRUE; // Assume user will successful get to the internet + + if (sgCurrAdInfo.szAdURL[0] == 0) + return; + + if (interfacedata->soundcallback) + interfacedata->soundcallback(PROVIDERID, SNET_SND_CHANGEFOCUS, 0); + + // Save a copy of the url, in case it changes while user is viewing the message box + strcpy(szURLSave, sgCurrAdInfo.szAdURL); + + + + // Prompt user if they really want to launch their browser (only prompt the first time they click) + DWORD dwUsedLink = 0; + SRegLoadValue(PREFSKEY,PREFSVALUE_USEDLINK,SREG_FLAG_BATTLENET,&dwUsedLink); + if (dwUsedLink == 0) { + dwUsedLink = 1; + SRegSaveValue(PREFSKEY,PREFSVALUE_USEDLINK,SREG_FLAG_BATTLENET,dwUsedLink); + + LoadString(global_hinstance, IDS_QUERYBROWSEWEB, szText, sizeof(szText)); + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + if (IDOK != UiMessageBox(interfacedata->messageboxcallback, interfacedata->parentwindow, szText, szTitle, MB_OKCANCEL)) { + SrvNotifyClickAd(sgCurrAdInfo.dwAdId, FALSE); + return; + } + } + + + // Switching to the Desktop will cause us to be minimized and switch out of Direct Draw Mode. + // We'll want to minimize our app before calling ShellExecute(). + // SetForegroundWindow() works better than ShowWindow(SDrawGetFrameWindow(), SW_MINIMIZE), which causes the + // task bar (if auto hidden) to be drawn whenever the frame window is displayed. + SetForegroundWindow(GetDesktopWindow()); + + // First try to launch browser by just passing ShellExecute() a url + if (32 >= (unsigned int)ShellExecute( + SDrawGetFrameWindow(), + "open", + szURLSave, + NULL, + NULL, + SW_SHOWNORMAL)) { + + // Okay.. that didn't work. Let's run the browser explicitly + + // create dummy battle.htm file + fp = fopen(BATTLE_HTML_FILE, "wb"); + fclose(fp); + + if (32 >= (unsigned int)FindExecutable(BATTLE_HTML_FILE, NULL, szBrowserApp)) { + // Get focus back + UiRestoreApp(); + + // Display message + LoadString(global_hinstance, IDS_BROWSERERROR, szText, sizeof(szText)); + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + UiMessageBox(interfacedata->messageboxcallback, interfacedata->parentwindow, szText, szTitle, MB_OK | MB_ICONWARNING); + bAdSuccess = FALSE; + goto FILE_CLEANUP; + } + + + // Launch browser window + if (32 >= (unsigned int)ShellExecute( + SDrawGetFrameWindow(), + "open", + szBrowserApp, + szURLSave, + NULL, + SW_SHOWNORMAL)) { + + // Get focus back + UiRestoreApp(); + + // Display Error + LoadString(global_hinstance, IDS_BROWSERERROR, szText, sizeof(szText)); + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + UiMessageBox(interfacedata->messageboxcallback, interfacedata->parentwindow, szText, szTitle, MB_OK | MB_ICONWARNING); + bAdSuccess = FALSE; + goto FILE_CLEANUP; + } + + FILE_CLEANUP: + DeleteFile(BATTLE_HTML_FILE); + + } + + SrvNotifyClickAd(sgCurrAdInfo.dwAdId, bAdSuccess); +} + + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + + + +//=========================================================================== +BOOL CALLBACK AdDialogProc ( HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + static SNETUIDATAPTR sInterfacedata = NULL; + static HCURSOR shCursor; + static BOOL sbNavigating = 0; + + switch (message) { + case WM_DESTROY: + AdDestroyWindow(); + sInterfacedata = NULL; + DeleteObject(shCursor); + shCursor = NULL; + break; + + case WM_INITDIALOG: + RECT testrect; + GetClientRect(window,&testrect); + + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + sInterfacedata = (SNETUIDATAPTR)lparam; + + if (sInterfacedata == NULL) { + SDlgEndDialog(window, 0); + return 0; + } + + AdInitWindow(window, sInterfacedata->artcallback); + + // Get link cursor + if (sInterfacedata->getdatacallback) { + sInterfacedata->getdatacallback( + PROVIDERID, + SNET_DATA_CURSORLINK, + &shCursor, + sizeof(shCursor), + NULL); + } + + return 1; + + case WM_MOUSEACTIVATE: + // Don't activate window, but process the mouse click anyway + SetWindowLong(window, DWL_MSGRESULT, MA_NOACTIVATE); + return 1; + + case WM_LBUTTONDOWN: + // Protect this code + if (sbNavigating) + return 1; + + sbNavigating = 1; + AdNavigate(sInterfacedata); + sbNavigating = 0; + return 1; + + case WM_SETCURSOR: + // Ignore cursor, if we have already clicked on the ad. + if (sbNavigating) + break; + + if (shCursor && sgCurrAdInfo.szAdURL[0] != 0) + SetCursor(shCursor); + return 1; + } + + return SDlgDefDialogProc(window,message,wparam,lparam); +} + + diff --git a/Storm/SOURCE/BATTLE/BATTLE.CPP b/Storm/SOURCE/BATTLE/BATTLE.CPP new file mode 100644 index 0000000..5fb6840 --- /dev/null +++ b/Storm/SOURCE/BATTLE/BATTLE.CPP @@ -0,0 +1,103 @@ +/**************************************************************************** +* +* BATTLE.CPP +* battle.net network provider +* +* By Michael O'Brien (6/10/96) +* +***/ + +#include "pch.h" + +HINSTANCE global_hinstance = (HINSTANCE)0; +DWORD global_maxplayers = MAXPLAYERS; +DWORD global_programid = 0; +DWORD global_versionid = 0; + +/**************************************************************************** +* +* EXPORTED DATA AND FUNCTIONS +* +***/ + +DWORD bn_id = 'BNET'; +LPCSTR bn_desc = "Battle.net"; +LPCSTR bn_req = "An active connection to an Internet provider, or a " + "direct connection to the Internet."; +SNETCAPS bn_caps = {sizeof(SNETCAPS), // size +#ifdef _DEBUG + SNET_CAPS_DEBUGONLY, // flags +#else + SNET_CAPS_RETAILONLY, // flags +#endif + MAXMESSAGESIZE, // max message size + 16, // max queue size, + MAXPLAYERS, // max players, + 1500, // bytes per second + 500, // latency (ms) + 4, // default turns per second + 2}; // default turns in transit +SNETSPI bn_spi = {sizeof(SNETSPI), + SpiCompareNetAddresses, + SpiDestroy, + SpiFree, + SpiFreeExternalMessage, + SpiGetGameInfo, + SpiGetPerformanceData, + SpiInitialize, + SpiInitializeDevice, + SpiLockDeviceList, + SpiLockGameList, + (BOOL(__stdcall*)(LPVOID*,DWORD*,SNETADDRPTR*))SpiReceive, + SpiReceiveExternalMessage, + SpiSelectGame, + SpiSend, + SpiSendExternalMessage, + SpiStartAdvertisingGame, + SpiStopAdvertisingGame, + SpiUnlockDeviceList, + SpiUnlockGameList, + SpiGetLocalPlayerName}; + +//=========================================================================== +extern "C" BOOL APIENTRY SnpQuery (DWORD index, + DWORD *id, + LPCSTR *description, + LPCSTR *requirements, + SNETCAPSPTR *caps) { + if ((index != 0) || !(id && description && requirements && caps)) + return 0; + *id = bn_id; + *description = bn_desc; + *requirements = bn_req; + *caps = &bn_caps; + return 1; +} + +//=========================================================================== +extern "C" BOOL APIENTRY SnpBind (DWORD index, + SNETSPIPTR *spi) { + if ((index != 0) || !spi) + return 0; + *spi = &bn_spi; + return 1; +} + +//=========================================================================== +extern "C" BOOL APIENTRY DllMain (HINSTANCE instance, DWORD reason, LPVOID) { + + switch (reason) { + case DLL_PROCESS_ATTACH: + ComboRegisterClass(); + ScrollbarRegisterClass(); + break; + + case DLL_PROCESS_DETACH: + ScrollbarUnregisterClass(); + ComboUnregisterClass(); + break; + } + + global_hinstance = instance; + return 1; +} diff --git a/Storm/SOURCE/BATTLE/BATTLE.CS b/Storm/SOURCE/BATTLE/BATTLE.CS new file mode 100644 index 0000000..356a6e5 --- /dev/null +++ b/Storm/SOURCE/BATTLE/BATTLE.CS @@ -0,0 +1,18 @@ +#include +#include +set deffile=battle.def +set extralib=wsock32.lib shell32.lib +set linkopt=%linkopt% -base:0x19000000 + +// DETERMINE THE PROJECT NAME +if %debug% set project=%project%d +set outfile=%project%.snp + +// ADD THE CAPS SIGNATURE TO THE END OF THE FILE +!copy /b %project%.dll+caps.mpq > NUL: + +// RENAME IT TO .SNP AND COPY IT TO THE OUTPUT DIRECTORY +!if exist %outfile% del %outfile% +!rename %project%.dll %outfile% +!copy %outfile% ..\..\bin > NUL: +!if exist *.bak del *.bak diff --git a/Storm/SOURCE/BATTLE/BATTLE.DEF b/Storm/SOURCE/BATTLE/BATTLE.DEF new file mode 100644 index 0000000..e2987e5 --- /dev/null +++ b/Storm/SOURCE/BATTLE/BATTLE.DEF @@ -0,0 +1,3 @@ +EXPORTS +SnpBind +SnpQuery diff --git a/Storm/SOURCE/BATTLE/BATTLE.H b/Storm/SOURCE/BATTLE/BATTLE.H new file mode 100644 index 0000000..5b3c573 --- /dev/null +++ b/Storm/SOURCE/BATTLE/BATTLE.H @@ -0,0 +1,464 @@ +/**************************************************************************** +* +* COMMON DEFINES, TYPES AND STRUCTURES +* +***/ + +#define DATAPORT 6112 +#define MAXMESSAGESIZE 512 +#define MAXPLAYERS 256 +#define MAXSTRINGLENGTH SNETSPI_MAXSTRINGLENGTH +#define PROVIDERID 'BNET' + +#define STARCRAFT_BNBETA 1 // 0 in final + +#define PKT_GAMEDATA 0 +#define PKT_CLIENTREQ 3 +#define PKT_SERVERPING 5 + +/**************************************************************************** +* +* GLOBAL VARIABLES +* +***/ + +extern HINSTANCE global_hinstance; +extern DWORD global_maxplayers; +extern DWORD global_programid; +extern DWORD global_versionid; + +extern BOOL gbConnectionLost; + +/**************************************************************************** +* +* CACHE FUNCTIONS +* +***/ + +void CacheDestroy (); +BOOL CacheFree (LPVOID data, DWORD databytes); +BOOL CacheInitialize (); +BOOL CacheLoadFile (LPCSTR filename, + FILETIME *lastwritetime, + LPVOID *data, + DWORD *databytes); +BOOL CacheSaveFile (LPCSTR filename, + LPVOID data, + DWORD databytes, + FILETIME *lastwritetime, + DWORD minexpireseconds, + DWORD maxexpireseconds); + +/**************************************************************************** +* +* SERVICE PROVIDER INTERFACE FUNCTIONS +* +***/ + +void SpiAddGame (SNETSPI_GAMELISTPTR game); +BOOL CALLBACK SpiCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude); +BOOL CALLBACK SpiDestroy (); +BOOL CALLBACK SpiFree (SNETADDRPTR addr, + LPVOID data, + DWORD databytes); +BOOL CALLBACK SpiFreeExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR message); +BOOL CALLBACK SpiGetGameInfo (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + SNETSPI_GAMELIST *gameinfo); +BOOL CALLBACK SpiGetLocalPlayerName (LPSTR namebuffer, + DWORD namechars, + LPSTR descbuffer, + DWORD descchars); +BOOL CALLBACK SpiGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq); +BOOL CALLBACK SpiInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE event); +BOOL CALLBACK SpiInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +BOOL CALLBACK SpiLockDeviceList (SNETSPI_DEVICELISTPTR *devicelist); +BOOL CALLBACK SpiLockGameList (DWORD categorybits, + DWORD categorymask, + SNETSPI_GAMELISTPTR *gamelist); +void SpiQueueExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR message); +BOOL CALLBACK SpiReceive (SNETADDRPTR *addr, + LPVOID *data, + DWORD *databytes); +BOOL CALLBACK SpiReceiveExternalMessage (LPCSTR *senderpath, + LPCSTR *sendername, + LPCSTR *message); +BOOL CALLBACK SpiSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); +BOOL CALLBACK SpiSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes); +BOOL CALLBACK SpiSendExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR targetpath, + LPCSTR targetname, + LPCSTR message); +BOOL SpiSendSpecial (SNETADDRPTR addr, + DWORD packettype, + LPVOID data, + DWORD databytes); +BOOL CALLBACK SpiStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD gameage, + DWORD gamecategorybits, + DWORD optcategorybits, + LPCVOID clientdata, + DWORD clientdatabytes); +BOOL CALLBACK SpiStopAdvertisingGame (); +BOOL CALLBACK SpiUnlockDeviceList (SNETSPI_DEVICELISTPTR devicelist); +BOOL CALLBACK SpiUnlockGameList (SNETSPI_GAMELISTPTR gamelist, + DWORD *hintnextcall); + +/**************************************************************************** +* +* SERVER COMMUNICATION FUNCTIONS +* +***/ + +#define SN_ADDCHANNEL 1 // param = LPCSTR (channel name) +#define SN_DELETECHANNEL 2 // param = LPCSTR (channel name) +#define SN_JOINCHANNEL 3 // param = SNJOINCHANNELPTR +#define SN_ADDUSER 4 // param = SNADDUSERPTR +#define SN_DELETEUSER 5 // param = SNDELETEUSERPTR +#define SN_DISPLAYSTRING 6 // param = SNDISPLAYSTRINGPTR +#define SN_DOWNLOADINGUPGRADE 8 // param = LPDWORD (percent complete) +#define SN_DOWNLOADFAILED 9 // param = unused +#define SN_DOWNLOADSUCCEEDED 10 // param = unused +#define SN_FAILEDTOCONNECT 11 // param = LPDWORD (error code) +#define SN_USERNAME 12 // param = LPCSTR (user name) +#define SN_LOSTCONNECTION 13 // param = unused +#define SN_CHANGEUSERFLAGS 14 // param = SNCHANGEUSERFLAGSPTR +#define SN_UPDATEPINGTIME 15 // param = SNUPDATEPINGTIMEPTR +#define SN_CHANNELISFULL 16 // param = LPCSTR (channel name) +#define SN_CHANNELDOESNOTEXIST 17 // param = LPCSTR (channel name) +#define SN_CHANNELISRESTRICTED 18 // param = LPCSTR (channel name) +#define SN_SQUELCHUSER 19 // param = SNSQUELCHUSERPTR +#define SN_UNSQUELCHUSER 20 // param = SNSQUELCHUSERPTR +#define SN_BADCONNECTION 21 // param = unused +#define SN_SETADINFO 22 // param = SNADINFOPTR +#define SN_DISPLAYAD 23 // param = LPVOID (ad data) +#define SN_MESSAGEBOX 24 // param = SNMESSAGEBOXPTR + +#define SN_ERROR_UNREACHABLE 1 +#define SN_ERROR_NOTRESPONDING 2 +#define SN_ERROR_UNABLETOUPGRADE 3 +#define SN_ERROR_BADCONNECTION 4 + +#define SN_STRING_WHISPER 1 +#define SN_STRING_WHISPERSENT 2 +#define SN_STRING_TALK 3 +#define SN_STRING_BROADCAST 4 +#define SN_STRING_INFORMATION 5 +#define SN_STRING_ERROR 7 + +#define ADTYPE_PCX 0x7863702e +#define ADTYPE_SMK 0x6b6d732e + +#define CF_PUBLIC 0x00000001 +#define CF_MODERATED 0x00000002 +#define CF_RESTRICTED 0x00000004 + +#define UF_BLIZZARD SNET_DDPF_BLIZZARD +#define UF_MODERATOR SNET_DDPF_MODERATOR +#define UF_SPEAKER SNET_DDPF_SPEAKER +#define UF_SYSOP SNET_DDPF_SYSOP +#define UF_BADCONNECTION 0x00000010 +#define UF_SQUELCHED SNET_DDPF_SQUELCHED + +typedef struct _SNADDUSERREC { + LPCSTR name; + LPCSTR description; + DWORD flags; + BOOL notifyuser; +} SNADDUSERREC, *SNADDUSERPTR; + +typedef struct _SNADINFOREC { + DWORD id; + DWORD adtype; + LPCSTR filename; + LPCSTR url; +} SNADINFOREC, *SNADINFOPTR; + +typedef struct _SNCHANGEUSERFLAGSREC { + LPCSTR name; + DWORD flags; +} SNCHANGEUSERFLAGSREC, *SNCHANGEUSERFLAGSPTR; + +typedef struct _SNDELETEUSERREC { + LPCSTR name; + LPCSTR reason; + BOOL notifyuser; +} SNDELETEUSERREC, *SNDELETEUSERPTR; + +typedef struct _SNDISPLAYSTRINGREC { + LPCSTR sender; + DWORD senderflags; + DWORD stringtype; + LPCSTR string; +} SNDISPLAYSTRINGREC, *SNDISPLAYSTRINGPTR; + +typedef struct _SNJOINCHANNELREC { + LPCSTR name; + DWORD flags; +} SNJOINCHANNELREC, *SNJOINCHANNELPTR; + +typedef struct _SNMESSAGEBOXREC { + LPCSTR text; + LPCSTR caption; + DWORD type; +} SNMESSAGEBOXREC, *SNMESSAGEBOXPTR; + +typedef struct _SNSQUELCHUSERREC { + LPCSTR name; + DWORD flags; +} SNSQUELCHUSERREC, *SNSQUELCHUSERPTR; + +typedef struct _SNUPDATEPINGTIMEREC { + LPCSTR name; + DWORD pingtime; + BOOL relayed; +} SNUPDATEPINGTIMEREC, *SNUPDATEPINGTIMEPTR; + +BOOL SrvBeginChat (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + LPCSTR preferredchannel); +void SrvCancel (); +BOOL SrvCreateAccount (LPCSTR username, + LPCSTR password); +void SrvDestroy (); +BOOL SrvDisconnect (); +BOOL SrvEndChat (); +BOOL SrvGetGameList (LPCSTR gamename, + LPCSTR gamepassword, + DWORD categorybits, + DWORD categorymask, + DWORD maxitems); +BOOL SrvGetLatency (SNETADDRPTR addr, + DWORD *latency); +void SrvGetLocalPlayerDesc (LPSTR buffer, + DWORD bufferchars); +void SrvGetLocalPlayerName (LPSTR buffer, + DWORD bufferchars); +BOOL SrvGetUiNotification (DWORD *notifycode, + LPVOID *param, + DWORD *parambytes); +BOOL SrvInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETVERSIONDATAPTR versiondata); +BOOL SrvIsConnected (); +BOOL SrvIsWaitingForResponse (); +BOOL SrvJoinChannel (LPCSTR channel, + BOOL joinalways = 0); +BOOL SrvLogon (LPCSTR username, + LPCSTR password, + DWORD *errorcode); +void SrvMaintainAds (); +void SrvMaintainLatencies (); +void SrvNotifyClickAd (DWORD adid, + BOOL result); +void SrvNotifyDisplayAd (DWORD id, + LPCSTR filename, + LPCSTR url); +void SrvNotifyJoin (LPCSTR gamename, + LPCSTR gamepassword); +void SrvPingAddress (SNETADDRPTR addr); +void SrvProcessClientReq (SNETADDRPTR addr, + LPBYTE data, + DWORD databytes); +void SrvProcessServerPing (LPBYTE data, + DWORD databytes); +BOOL SrvSendChatString (LPCSTR command); +void SrvSetBetaId (DWORD betaid); +BOOL SrvStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD creationtime, + DWORD gamecategorybits, + DWORD optcategorybits); +BOOL SrvStopAdvertisingGame (); + +/**************************************************************************** +* +* USER INTERFACE FUNCTIONS +* +***/ + +//**************************************************************************** +// User Defined messages +//**************************************************************************** + +// chatchnnl.cpp +#define WM_CHANNEL_DOESNOTEXIST (WM_USER+100) +#define WM_CHANNEL_JOINED (WM_USER+101) +#define WM_CHANNEL_RESTRICTED (WM_USER+102) + +// bnetlogo.cpp +#define WM_ERR_NOTRESPONDING (WM_USER+103) + +// chatroom.cpp +#define WM_CHAT_PROCESS_MSG (WM_USER+104) //(wparam = msg color, lparam = (LPCSTR)szText) + +// ui.cpp..etc +#define WM_NOTIFICATION_WAITING (WM_USER+105) + +// scrollbar.cpp +#define WM_STORMSCROLL_INIT (WM_USER+106) // (lparam = (HWND)hWndParent) + +//**************************************************************************** +//**************************************************************************** + +typedef struct _UIPARAMS { + DWORD flags; + SNETPROGRAMDATAPTR programdata; + SNETPLAYERDATAPTR playerdata; + SNETUIDATAPTR interfacedata; + SNETVERSIONDATAPTR versiondata; + LPDWORD playeridptr; +} UIPARAMS, *UIPARAMSPTR; + + +#define MAX_CHANNEL_LEN 32 +typedef struct _CHANNEL_LIST { + char szChannel[MAX_CHANNEL_LEN]; + _CHANNEL_LIST *next; +} TCHANNEL_LIST, *PTCHANNEL_LIST; + +typedef struct _bmp { + LPBYTE data; + SIZE datasize; +} TBMP, * TPBMP; + + +BOOL CALLBACK BattleNetDialogProc(HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); + +BOOL UiInitialize(SNETUIDATAPTR interfacedata); +void UiDestroy(void); +BOOL UiBeginConnect (SNETPROGRAMDATAPTR programdata, + SNETUIDATAPTR interfacedata); +void UiEndConnect (BOOL connected); + +void UiRestoreApp(void); + +BOOL UiSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid); +BOOL UiLogon (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata); +BOOL UiDisconnect(void); +BOOL UiAskUpdate(SNETUIDATAPTR interfacedata); +void UiNotificationWaiting (); +BOOL UiPrepRestart(SNETUIDATAPTR interfacedata); +BOOL UiProcessWindowMessages (); +BOOL UiUpgradeMessage (); +void UiNotification(void); +void UiWSockErrMessage(void); + +BOOL UiMessageBox(SNETMESSAGEBOXPROC messageboxcallback, HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); + + + +typedef int (CALLBACK *PROGRESSFCN)(void); +HWND UiModelessProgressDialog(SNETUIDATAPTR interfacedata, + LPCSTR progresstext, + BOOL abortable, + PROGRESSFCN progressfcn, + DWORD callspersec); + + +void ColorPrefDestroy(void); +BOOL ColorPrefInit(SNETGETDATAPROC getdatacallback); +void ColorPrefActivate(BOOL bActivate); + + +//=========================================================================== +// Useful misc. routines +//=========================================================================== +BOOL UiLoadArtwork (SNETGETARTPROC artcallback, + HWND hWnd, + HWND hWndParent, + DWORD artid, + LPCTSTR controltype, + DWORD controlstyle, + LONG usageflags, + BOOL loadpalette, + BOOL prepfadein, + LPBYTE *data, + SIZE *size); + + +BOOL UiLoadCustomArt ( + SNETGETARTPROC artcallback, + HWND hWnd, + DWORD artid, + int nFirstColor, + int nNumColorsUsed, + BOOL bSetPaletteNow, + LPBYTE *data, + SIZE *size); + +BOOL UiGetData(SNETGETDATAPROC getdatacallback, + DWORD dataid, + LPBYTE *data, + DWORD *datasize); + +//* Fading routines +#define DEFAULT_STEPS 5 +#define FADE_TIMER_ID 10 +#define FADE_TIMER_DELAY 50 + +extern int gFadeStep; +void UiVidFade(int max, int curr); +void UiVidFadeOut(int steps); + +void UiLoadCursors(HWND hWnd, SNETUIDATAPTR interfacedata); + +// Scrollbar routines +void ScrollbarRegisterClass (void); +void ScrollbarUnregisterClass(void); +void ScrollbarLink(HWND hWndList, HWND hWndScroll); +void ListUpdateScrollbar(HWND hWndList); +void EditUpdateScrollbar(HWND hWndEdit); +int ScrollbarGetWidth(void); +void ScrollbarLoadArtwork(SNETGETARTPROC artcallback); +void ScrollbarDestroyArtwork(void); + +// ComboBox routines +void ComboRegisterClass (void); +void ComboUnregisterClass (void); +void ComboboxLoadArtwork(SNETGETARTPROC artcallback); +void ComboboxDestroyArtwork(void); + diff --git a/Storm/SOURCE/BATTLE/BATTLE.RC b/Storm/SOURCE/BATTLE/BATTLE.RC new file mode 100644 index 0000000..7399ab9 --- /dev/null +++ b/Storm/SOURCE/BATTLE/BATTLE.RC @@ -0,0 +1,602 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// TEXT +// + +CHAT_HELP TEXT MOVEABLE PURE "chathelp.txt" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "DIALOG_CHATROOM", DIALOG + BEGIN + LEFTMARGIN, 4 + RIGHTMARGIN, 247 + TOPMARGIN, 2 + BOTTOMMARGIN, 143 + END + + "DIALOG_JOIN_GAME", DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 244 + TOPMARGIN, 10 + BOTTOMMARGIN, 141 + END + + "DIALOG_CHAT_HELP", DIALOG + BEGIN + LEFTMARGIN, 18 + RIGHTMARGIN, 137 + TOPMARGIN, 4 + BOTTOMMARGIN, 110 + END + + "DIALOG_LOGON", DIALOG + BEGIN + LEFTMARGIN, 2 + VERTGUIDE, 22 + VERTGUIDE, 134 + VERTGUIDE, 180 + VERTGUIDE, 244 + VERTGUIDE, 248 + TOPMARGIN, 4 + BOTTOMMARGIN, 200 + HORZGUIDE, 4 + HORZGUIDE, 62 + HORZGUIDE, 74 + HORZGUIDE, 86 + HORZGUIDE, 112 + HORZGUIDE, 170 + END + + "DIALOG_CHAT_CHANNEL", DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 244 + TOPMARGIN, 8 + BOTTOMMARGIN, 136 + END + + "DIALOG_CONNECT_BG", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 249 + TOPMARGIN, 7 + BOTTOMMARGIN, 196 + END + + "DIALOG_PROGRESS", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 105 + TOPMARGIN, 7 + BOTTOMMARGIN, 52 + END + + "DIALOG_BATTLENET", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 249 + TOPMARGIN, 7 + BOTTOMMARGIN, 196 + END + + "DIALOG_CONNECT_CANCEL", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 105 + TOPMARGIN, 7 + BOTTOMMARGIN, 53 + END + + "DIALOG_AD", DIALOG + BEGIN + LEFTMARGIN, 1 + RIGHTMARGIN, 186 + TOPMARGIN, 1 + BOTTOMMARGIN, 23 + END + + "DIALOG_SET_PASSWORD", DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 142 + TOPMARGIN, 10 + BOTTOMMARGIN, 111 + END + + "DIALOG_ENTER_PASSWORD", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 147 + TOPMARGIN, 7 + BOTTOMMARGIN, 110 + END + + "DIALOG_RENAME_ACCOUNT", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 147 + TOPMARGIN, 7 + BOTTOMMARGIN, 110 + END + + "DIALOG_CREATE_NAME", DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 150 + TOPMARGIN, 5 + BOTTOMMARGIN, 115 + END + + "DIALOG_FILTER_JOIN_GAME", DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 244 + TOPMARGIN, 10 + BOTTOMMARGIN, 141 + END + + "DIALOG_NEW_ACCOUNT", DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 244 + VERTGUIDE, 23 + TOPMARGIN, 2 + BOTTOMMARGIN, 141 + HORZGUIDE, 32 + HORZGUIDE, 58 + HORZGUIDE, 83 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +DIALOG_CHATROOM DIALOGEX 0, 61, 256, 146 +STYLE WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_CHATEDIT,46,128,122,10,ES_AUTOHSCROLL | NOT + WS_BORDER + PUSHBUTTON "C&hannel",ID_CHATCHANNEL,4,2,34,30,BS_BOTTOM | + BS_MULTILINE + PUSHBUTTON "&Create",ID_CHATCREATE,4,39,34,30,BS_BOTTOM | + BS_MULTILINE + PUSHBUTTON "&Join",ID_CHATJOIN,4,76,34,30,BS_BOTTOM | BS_MULTILINE + PUSHBUTTON "&Quit",IDQUIT,4,113,34,30,BS_BOTTOM + LISTBOX IDC_USERLIST,184,27,57,92,LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | NOT WS_BORDER | WS_TABSTOP + LISTBOX IDC_CHATWINDOW,46,10,115,108,NOT LBS_NOTIFY | + LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_USETABSTOPS | + LBS_NOSEL | NOT WS_BORDER | WS_TABSTOP + PUSHBUTTON "&Send",IDOK,181,128,34,15 + PUSHBUTTON "&Whisper",ID_WHISPER,219,128,34,15 + CTEXT "",IDC_STATIC_CHANNEL,181,8,66,9 + CONTROL "",IDC_USERLIST_SCROLLBAR,"StormScrollbar",0x0,241,27,7, + 88 + CONTROL "",IDC_MSGLIST_SCROLLBAR,"StormScrollbar",0x0,161,10,7, + 106 + PUSHBUTTON "&Verbose",ID_VERBOSE,86,112,28,11,NOT WS_VISIBLE | NOT + WS_TABSTOP +END + +DIALOG_LADDER_CHATROOM DIALOGEX 0, 61, 256, 146 +STYLE WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_CHATEDIT,46,128,122,12,ES_AUTOHSCROLL | NOT + WS_BORDER + PUSHBUTTON "C&hannel",ID_CHATCHANNEL,4,2,34,23,BS_BOTTOM | + BS_MULTILINE + PUSHBUTTON "&Create",ID_CHATCREATE,4,31,34,23,BS_BOTTOM | + BS_MULTILINE + PUSHBUTTON "&Join",ID_CHATJOIN,4,60,34,23,BS_BOTTOM | BS_MULTILINE + PUSHBUTTON "&Ladder",ID_CHATLADDER,4,89,34,23,BS_BOTTOM | + BS_MULTILINE + PUSHBUTTON "&Quit",IDQUIT,4,118,34,23,BS_BOTTOM + LISTBOX IDC_USERLIST,184,27,57,92,LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | NOT WS_BORDER | WS_TABSTOP + LISTBOX IDC_CHATWINDOW,46,10,115,108,NOT LBS_NOTIFY | + LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_USETABSTOPS | + LBS_NOSEL | NOT WS_BORDER | WS_TABSTOP + PUSHBUTTON "&Send",IDOK,179,128,34,15 + PUSHBUTTON "&Whisper",ID_WHISPER,214,128,34,15 + CTEXT "",IDC_STATIC_CHANNEL,181,8,66,9 + CONTROL "",IDC_USERLIST_SCROLLBAR,"StormScrollbar",0x0,241,27,7, + 88 + CONTROL "",IDC_MSGLIST_SCROLLBAR,"StormScrollbar",0x0,161,10,7, + 106 + PUSHBUTTON "&Verbose",ID_VERBOSE,86,112,28,11,NOT WS_VISIBLE | NOT + WS_TABSTOP +END + +DIALOG_JOIN_GAME DIALOGEX 0, 61, 256, 146 +STYLE WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_NAME,168,50,76,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PASSWORD,168,69,76,12,ES_AUTOHSCROLL + LISTBOX IDC_GAMELIST,10,23,97,117,LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_USETABSTOPS | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,179,128,34,15 + PUSHBUTTON "Cancel",IDCANCEL,214,128,34,15 + CTEXT "Join Game",IDC_TITLE,130,8,114,9,0,WS_EX_TRANSPARENT + RTEXT "Name:",IDC_STATIC,130,50,36,12,0,WS_EX_TRANSPARENT + RTEXT "Password:",IDC_STATIC,130,69,36,12,0,WS_EX_TRANSPARENT + LTEXT "To Join a game, enter the game information below.", + IDC_STATIC,130,23,114,18,0,WS_EX_TRANSPARENT + CTEXT "Matching Public Games",IDC_STATIC,10,8,104,9,0, + WS_EX_TRANSPARENT + LTEXT "",IDC_GAMEDESCRIPTION,130,88,114,27 + CONTROL "",IDC_SCROLLBAR,"StormScrollbar",0x0,107,24,7,110 +END + +DIALOG_CHAT_HELP DIALOGEX 0, 0, 154, 118 +STYLE DS_CENTER | WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,56,95,34,15 + EDITTEXT IDC_EDIT1,18,16,112,70,ES_MULTILINE | ES_READONLY + CTEXT "Help",IDC_TITLE,18,4,119,9,0,WS_EX_TRANSPARENT + CONTROL "",IDC_SCROLLBAR,"StormScrollbar",0x0,130,16,7,70 + DEFPUSHBUTTON "Cancel",IDCANCEL,94,95,34,15 +END + +DIALOG_LOGON DIALOGEX 0, 0, 256, 203 +STYLE DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_PASSWORD,23,114,85,12,ES_PASSWORD | + ES_AUTOHSCROLL | WS_CLIPSIBLINGS + PUSHBUTTON "New Account",IDS_NEWACCOUNT,33,157,66,15 + CTEXT "Battle.net Login",IDC_TITLE,2,61,254,12,0, + WS_EX_TRANSPARENT + LTEXT "Name",IDC_STATIC,22,77,32,10,0,WS_EX_TRANSPARENT + LTEXT "Password",IDC_STATIC,22,103,32,10,0,WS_EX_TRANSPARENT + CONTROL "",IDC_COMBO_NAME,"StormComboBox",WS_CLIPSIBLINGS | + WS_TABSTOP,22,87,88,14,WS_EX_CONTROLPARENT + DEFPUSHBUTTON "Ok",IDOK,179,185,34,15 + PUSHBUTTON "Cancel",IDCANCEL,214,185,34,15 + LTEXT "Profile:",IDC_STATIC,134,76,114,10,0,WS_EX_TRANSPARENT + LTEXT "",IDC_PROFILE,134,85,110,86,WS_BORDER,WS_EX_TRANSPARENT +END + +DIALOG_CHAT_CHANNEL DIALOGEX 0, 61, 256, 146 +STYLE WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_NAME,168,50,76,12,ES_AUTOHSCROLL + LISTBOX IDC_CHANNELLIST,10,23,97,117,LBS_USETABSTOPS | + WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,179,128,34,15 + PUSHBUTTON "Cancel",IDCANCEL,214,128,34,15 + LTEXT "To join or create a Private Channel, enter a name below.", + IDC_STATIC,130,23,114,18,0,WS_EX_TRANSPARENT + CTEXT "Select Channel",IDC_TITLE,130,8,114,9,0, + WS_EX_TRANSPARENT + RTEXT "Channel:",IDC_STATIC,130,50,36,12,0,WS_EX_TRANSPARENT + CTEXT "Channels",IDC_STATIC,10,8,104,9,0,WS_EX_TRANSPARENT + CONTROL "",IDC_SCROLLBAR,"StormScrollbar",0x0,107,24,7,110 +END + +DIALOG_CONNECT_BG DIALOGEX 0, 0, 256, 203 +STYLE WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + CONTROL "",IDC_LOGO_ANIMATE,"Static",SS_BLACKFRAME,0,0,104,43 +END + +DIALOG_PROGRESS DIALOGEX 0, 0, 112, 61 +STYLE DS_CENTER | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + CTEXT "",IDC_PROGRESS_TEXT,0,4,112,18,0,WS_EX_TRANSPARENT + PUSHBUTTON "Cancel",IDCANCEL,34,42,44,12 + CONTROL "",IDC_UIGENERIC_PROGRESS,"Static",SS_BLACKFRAME,10,22, + 91,16 +END + +DIALOG_BATTLENET DIALOGEX 0, 0, 256, 203 +STYLE WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + CONTROL "",IDC_LOGO_ANIMATE,"Static",SS_BLACKFRAME,0,0,104,47 +END + +DIALOG_CONNECT_CANCEL DIALOGEX 0, 0, 112, 61 +STYLE DS_CENTER | WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + CTEXT "Searching for the fastest Battle.net server...", + IDC_TITLE,7,9,98,27 + PUSHBUTTON "Cancel",IDCANCEL,34,39,44,12 +END + +DIALOG_AD DIALOGEX 37, 29, 187, 25 +STYLE WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN +END + +DIALOG_SET_PASSWORD DIALOGEX 0, 0, 154, 118 +STYLE DS_CENTER | WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT1,32,73,92,12,ES_AUTOHSCROLL | NOT WS_BORDER + DEFPUSHBUTTON "OK",IDOK,42,90,34,15 + DEFPUSHBUTTON "Cancel",IDCANCEL,80,90,34,15 + CTEXT "Set Password",IDC_TITLE,10,10,132,9,0,WS_EX_TRANSPARENT + LTEXT "Please enter a password for your character. This will prevent other people from using your name on Battle.net.", + IDC_STATIC,10,27,132,42,0,WS_EX_TRANSPARENT +END + +DIALOG_ENTER_PASSWORD DIALOGEX 0, 0, 154, 117 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT1,32,73,92,12,ES_AUTOHSCROLL | NOT WS_BORDER + DEFPUSHBUTTON "OK",IDOK,55,92,44,12 + PUSHBUTTON "Cancel",IDCANCEL,103,92,44,12 + PUSHBUTTON "New Account",IDC_NEWACCOUNT,7,92,44,12 + CTEXT "Enter Password",IDC_TITLE,10,10,132,9,0, + WS_EX_TRANSPARENT + LTEXT "",IDC_STATIC,10,27,132,36,0,WS_EX_TRANSPARENT +END + +DIALOG_RENAME_ACCOUNT DIALOGEX 0, 0, 154, 117 +STYLE DS_MODALFRAME | WS_POPUP +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + CTEXT "Rename Character",IDC_TITLE,10,10,132,9,0, + WS_EX_TRANSPARENT + LTEXT "",IDC_STATIC,10,27,132,36,0,WS_EX_TRANSPARENT + DEFPUSHBUTTON "OK",IDOK,42,90,34,15 + DEFPUSHBUTTON "Cancel",IDCANCEL,80,90,34,15 + EDITTEXT IDC_EDIT1,32,73,92,12,ES_AUTOHSCROLL | NOT WS_BORDER +END + +DIALOG_CREATE_NAME DIALOGEX 0, 0, 154, 118 +STYLE DS_CENTER | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + CTEXT "Create Name",IDC_STATIC,4,5,146,12 + RTEXT "Name",IDC_STATIC,2,46,46,12 + RTEXT "Password",IDC_STATIC,2,69,46,12 + EDITTEXT IDC_EDIT_NAME,52,46,94,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PASSWORD,52,69,94,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "Accept",IDOK,26,98,40,15 + PUSHBUTTON "Cancel",IDESCAPE,88,98,40,15 +END + +DIALOG_FILTER_JOIN_GAME DIALOGEX 0, 61, 256, 146 +STYLE WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_NAME,168,50,76,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PASSWORD,168,69,76,12,ES_AUTOHSCROLL + LISTBOX IDC_GAMELIST,10,40,97,99,LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_USETABSTOPS | WS_CLIPSIBLINGS | + WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,179,128,34,15 + PUSHBUTTON "Cancel",IDCANCEL,214,128,34,15 + CTEXT "Join Game",IDC_TITLE,130,8,114,9,0,WS_EX_TRANSPARENT + RTEXT "Name:",IDC_STATIC,130,50,36,12,0,WS_EX_TRANSPARENT + RTEXT "Password:",IDC_STATIC,130,69,36,12,0,WS_EX_TRANSPARENT + LTEXT "To Join a game, enter the game information below.", + IDC_STATIC,130,23,114,18,0,WS_EX_TRANSPARENT + CTEXT "Matching Public Games",IDC_STATIC,10,8,104,9,0, + WS_EX_TRANSPARENT + LTEXT "",IDC_GAMEDESCRIPTION,130,88,114,27 + CONTROL "",IDC_SCROLLBAR,"StormScrollbar",WS_CLIPSIBLINGS,107,40, + 7,99 + CONTROL "",IDC_FILTER,"StormComboBox",WS_CLIPSIBLINGS | + WS_TABSTOP | 0x3,10,22,104,14 +END + +DIALOG_NEW_ACCOUNT DIALOGEX DISCARDABLE 0, 61, 256, 146 +STYLE WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,179,128,34,15 + PUSHBUTTON "Cancel",IDCANCEL,214,128,34,15 + EDITTEXT IDC_NAME,23,32,85,12,ES_AUTOHSCROLL + EDITTEXT IDC_PASS1,23,58,85,12,ES_AUTOHSCROLL|ES_PASSWORD + EDITTEXT IDC_PASS2,23,83,85,12,ES_AUTOHSCROLL|ES_PASSWORD + LTEXT "Password:",IDC_STATIC,23,50,72,8,0,WS_EX_TRANSPARENT + LTEXT "Name:",IDC_STATIC,23,24,72,8,0,WS_EX_TRANSPARENT + LTEXT "Repeat Password:",IDC_STATIC,23,75,72,8,0,WS_EX_TRANSPARENT + CTEXT "New Account",IDC_STATIC,10,4,234,10,0,WS_EX_TRANSPARENT +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1997,3,21,1 + PRODUCTVERSION 1997,3,21,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Blizzard Entertainment\0" + VALUE "FileDescription", "Battle.snp\0" + VALUE "FileVersion", "1.03\0" + VALUE "InternalName", "Battle.snp\0" + VALUE "LegalCopyright", "Copyright © 1997, Blizzard Entertainment\0" + VALUE "OriginalFilename", "Battle.snp\0" + VALUE "ProductName", "Battle.net Service Provider\0" + VALUE "ProductVersion", "1.03\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PASSWORD_MISMATCH "The passwords you have typed do not match. Please enter the same password twice." + IDS_CHAT_HELP_RES "chat_help" + IDS_NAME_REQUIRED "You must enter a name for the game." + IDS_ASK_UPDATE "There is a new version of software available. Battle.net requires that you use the latest version. Your software will be updated now." + IDS_PREP_RESTART "The update has been downloaded successfully. Your application will now restart." + IDS_CHAT_JOIN_ROOM "%cJoining channel: %s" + IDS_CHAT_PLAYER_LEFT_ROOM "%c%s has left the channel." + IDS_CHAT_PLAYER_ENTERED_ROOM "%c%s has joined the channel." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_JOIN_FAILED "You were unable to join the selected game." + IDS_ERR_UNREACHABLE "Battle.net is not responding, please wait and try connecting again later." + IDS_BATTLENET "Battle.net" + IDS_ERR_NOTRESPONDING "The connection to Battle.net has been interrupted. Please try again later." + IDS_ERR_UNABLETOUPGRADE "Battle.net was unable to properly identify your application version. Please reinstall the application from the CD and then reconnect to Battle.net." + IDS_ERR_DOWNLOADFAILED "The update has been interrupted. No changes were made. Please try this process again." + IDS_DOWNLOADPROGRESS "Downloading software upgrade." + IDS_WHISPER_FROM "From: " + IDS_WHISPER_TO "To: " + IDS_ERR_INVALIDBETAID "You have entered an Invalid ID." + IDS_ERR_CANTWHISPER "You have not chosen a player to whisper to. You must first select a player from the list. Then, click whisper to send your message only to that player." + IDS_CHANNEL_NAME_INVALID + "Invalid channel name. A channel name cannot contain reserved characters." + IDS_FIRST_NASTY "gvdl" + IDS_NASTY0 "dvou" + IDS_NASTY1 "tiju" + IDS_NASTY2 "cjudi" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_NASTY3 "bttipmf" + IDS_NASTY4 "ojhhfs" + IDS_NASTY5 "cmj{{bse" + IDS_LAST_NASTY "benjo" + IDS_ERR_CHATNOTHINGTOSEND + "To chat with other players, you must first type a message to send." + IDS_PROMPT_CREATECHANNEL + "The ""%s"" channel is currently empty. Do you want to create a new channel with this name?" + IDS_CHANNEL_FULL "The ""%s"" channel is currently full. Please try again later." + IDS_ERR_BADCONNECTION "Unable to connect to the Battle.net. If you are using a modem to access your service provider and are not configured for Dialup Networking, you may have to initiate the the connection manually." + IDS_ERR_BADSERVICEPROVIDER + "Your Internet connection is either very poor or is not processing UDP packets. Contact your service provider or your system administrator for assistance. When connected to Battle.net, you will be able to chat but will not be able to play games." + IDS_CHANNEL_FMT "%s (%d)" + IDS_USERUNSQUELCHED_FMT "%cAccepting messages from %s." + IDS_USERSQUELCHED_FMT "%cIgnoring messages from %s." + IDS_VERBOSE_FMT "%cEnter/Leave notifications: ON" + IDS_NONVERBOSE_FMT "%cEnter/Leave notifications: OFF" + IDS_ERR_NOWSOCK32 "Your system has not been configured to support 32 bit Internet applications or Dialup Networking has not been configured for Auto Dial. You may have to connect to your internet provider manually before logging into Battle.net." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_QUERYBROWSEWEB "You have clicked on a link to the Internet. Your web browser will now be launched. You can use the Windows Taskbar to return to Battle.net." + IDS_QUERYDISCONNECT "You have disconnected from Battle.net. Press OK to hangup the connection to %s. Press Cancel to stay connected." + IDS_BROWSERERROR "Battle.net was unable to launch your default browser." + IDS_ERR_HOST_UNREACHABLE + "You were unable to join. The game you have selected is not responding. " + IDS_ERR_GAME_FULL "You were unable to join. The game you have selected is currently full." + IDS_ENTERPASSWORD """%1"" is a registered Battle.net name. Please enter the password for ""%1"", or select New Account to choose a different name." + IDS_RENAMECHARACTER """%1"" is already registered as a unique Battle.net name. Please enter a new name for your character." + IDS_ERR_INVALIDPASSWORD "You have entered an incorrect password. If your character has not been on Battle.net for 3 months, or if you forgot your password, you can select ""New Account"" to choose a new name and password." + IDS_TITLE_INVALIDPASSWORD "Invalid Password" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SOURCE/BATTLE/BNETART.H b/Storm/SOURCE/BATTLE/BNETART.H new file mode 100644 index 0000000..9b902d9 --- /dev/null +++ b/Storm/SOURCE/BATTLE/BNETART.H @@ -0,0 +1,35 @@ +/**************************************************************************** +* +* bnetart.h +* +* This file should be included by an application that wants to provide +* battle.net-specific artwork in its art callback. +* +***/ + +enum _BATTLENET_ART { + SNET_ART_BATTLE_BTNS = 0x80000000, + SNET_ART_BATTLE_CHAT_BKG, + SNET_ART_BATTLE_GREENLAG, + SNET_ART_BATTLE_YELLOWLAG, + SNET_ART_BATTLE_REDLAG, + SNET_ART_BATTLE_CONNECT_BKG, + SNET_ART_BATTLE_SELECT_CHNL_BKG, + SNET_ART_BATTLE_LOGIN_BKG, + SNET_ART_BATTLE_NEW_ACCOUNT_BKG, + + SNET_ART_BATTLE_BADCONNECTION, + SNET_ART_BATTLE_WELCOME_AD, + SNET_ART_BATTLE_LRG_EDIT_POPUP_BKG, +}; + +#define SNET_ART_SCOMBOLEFT 19 +#define SNET_ART_SCOMBOMIDDLE 20 +#define SNET_ART_SCOMBORIGHT 21 + +#define SNET_UIFLAG_SUPPORTS_LADDER 0x00000001 + +enum _BATTLENET_DATA { + SNET_DATA_BATTLE_LOGODELAY = 0x80000000, // (DWORD) delay between frames +}; + diff --git a/Storm/SOURCE/BATTLE/BNETLOGO.CPP b/Storm/SOURCE/BATTLE/BNETLOGO.CPP new file mode 100644 index 0000000..7962cb2 --- /dev/null +++ b/Storm/SOURCE/BATTLE/BNETLOGO.CPP @@ -0,0 +1,307 @@ +/*************************************************************************** +* +* bnetlogo.cpp +* Battle.net parent dialog +* +* This routine displays the Battle.net game logo and advertisement while +* the user is logged into Battle.net. +* +* By Michael Morhaime +* +***/ + +#include "pch.h" + +extern HWND ghWndUiMainParent; +extern HWND ghWndChat; + +//*************************************************************************** +extern BOOL CALLBACK ChatRoomDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); + +extern BOOL LogoInit(HWND child, SNETGETARTPROC artcallback); +extern void LogoAnimate(HWND hWndParent, HWND hWndLogo); +extern void LogoFramesDestroy(void); +extern BOOL LogoSetTimer(HWND window, int nTimer, SNETGETDATAPROC getdatacallback); + +extern BOOL UiLoadCustomArt( + SNETGETARTPROC artcallback, + HWND hWnd, + DWORD artid, + int nFirstColor, + int nNumColorsUsed, + BOOL bSetPaletteNow, + LPBYTE *data, + SIZE *size); + +extern BOOL CALLBACK AdDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); + + +//*************************************************************************** + +#define LOGO_TIMER_ID 1 +#define SRVMAINTAIN_TIMER_ID 2 +#define SRVMAINTAIN_TIMER_DELAY 5000 // every 5 seconds + +static LPBYTE backgroundbitmap = NULL; + +//=========================================================================== +static void DestroyArtwork (HWND window) { + TPBMP tpBmp = (TPBMP) GetWindowLong(GetDlgItem(window, IDC_LOGO_ANIMATE), GWL_USERDATA); + + // tpBmp->data points to a sgBackgroundBmp, which will be freed below + if (tpBmp) + FREE(tpBmp); + + LogoFramesDestroy(); + + + if (backgroundbitmap) { + FREE(backgroundbitmap); + backgroundbitmap = NULL; + } + + // Free artwork for scrollbar + ScrollbarDestroyArtwork(); +} + +//=========================================================================== +static BOOL LoadArtwork (HWND window, SNETGETARTPROC artcallback) { + SIZE bgSize; + + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_BACKGROUND, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + TRUE, // Get palette from this artwork + TRUE, // Prep palette for 'fade in' + &backgroundbitmap, + &bgSize); + + + + // set up a TPBMP for the logo window, it will have information about the background bitmap + HWND hWndLogo = GetDlgItem(window, IDC_LOGO_ANIMATE); + + if (hWndLogo && backgroundbitmap) { + TPBMP tpBmp = (TPBMP) ALLOC(sizeof(TBMP)); + SetWindowLong(hWndLogo, GWL_USERDATA, (LONG) tpBmp); + if (tpBmp) { + tpBmp->data = backgroundbitmap; + tpBmp->datasize = bgSize; + } + + // set up the animating application logo + LogoInit(hWndLogo,artcallback); + LogoAnimate(window, hWndLogo); + } + + // Load Scrollbar art (shared by many children of this dialog) + ScrollbarLoadArtwork(artcallback); + return 0; +} + + + + +//=========================================================================== +static BOOL DoChatRoom (UIPARAMSPTR pUIparams, HWND hWndBattleNet) { + UIPARAMS UIparams; + SNETUIDATA interfacedata; + + // Create a copy of the UIparams and replace the parent window. + UIparams = *pUIparams; + interfacedata = *UIparams.interfacedata; + interfacedata.parentwindow = hWndBattleNet; + UIparams.interfacedata = &interfacedata; + + LPCTSTR pszTemplate = TEXT("DIALOG_CHATROOM"); + if (interfacedata.uiflags & SNET_UIFLAG_SUPPORTS_LADDER) + pszTemplate = TEXT("DIALOG_LADDER_CHATROOM"); + + return (1 == SDlgDialogBoxParam( + global_hinstance, + pszTemplate, + hWndBattleNet, + ChatRoomDialogProc, + (LPARAM)&UIparams)); +} + +//=========================================================================== +void KillChildWindows(HWND hWndParent, HWND hWndTop) { + HWND hWnd; + BOOL bKilledChat = FALSE; + + if (hWndTop != NULL) { + hWnd = hWndTop; + while (hWnd != hWndParent) { + if (hWnd == ghWndChat) + bKilledChat = TRUE; + + SDlgEndDialog(hWnd, 0); + hWnd = GetParent(hWnd); + } + } + + // Make sure chat room was killed (it might have hidden itself and started another child of the big window) + if (!bKilledChat) + SDlgEndDialog(ghWndChat, 0); +} + +//=========================================================================== +BOOL CALLBACK BattleNetDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + static UIPARAMSPTR uiparams = NULL; + + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case IDOK: { + HWND hWndAd = NULL; + SNETUIDATA Interfacedata; + + // First make sure window has been drawn + UpdateWindow(window); + + // This is our signal to launch the ChatRoom and the advertisement window. + if (uiparams) { + // Advertisement window is a modeless dialog. + Interfacedata = *(uiparams->interfacedata); + Interfacedata.parentwindow = window; + hWndAd = SDlgCreateDialogParam( + global_hinstance, + TEXT("DIALOG_AD"), + window, + AdDialogProc, + (LPARAM)&Interfacedata); + } + + + + // Once the chatroom returns, we are finished. + // Note that the WM_TIMER will continue firing, so we can display + // things like advertisements and continue animating the application logo. + SDlgEndDialog(window, DoChatRoom(uiparams, window)); + + if (hWndAd && IsWindow(hWndAd)) + DestroyWindow(hWndAd); + return 1; + } + } + break; + + case WM_ERR_NOTRESPONDING: { + char szText[256]; + char szTitle[32]; + + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + LoadString(global_hinstance, IDS_ERR_NOTRESPONDING, szText, sizeof(szText)); + UiMessageBox(uiparams->interfacedata->messageboxcallback, window, szText, szTitle, MB_OK | MB_ICONERROR); + return 1; + } + + case WM_TIMER: + if (wparam == LOGO_TIMER_ID) { + LogoAnimate(window, GetDlgItem(window, IDC_LOGO_ANIMATE)); + + // Make sure the connection is still active. + if (gbConnectionLost) { + char szText[256]; + char szTitle[32]; + + // Save current top level window for application + HWND hWnd = GetActiveWindow(); + + gbConnectionLost = FALSE; // Reset flag so we can continue animating logo while dialog is up. + + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + LoadString(global_hinstance, IDS_ERR_NOTRESPONDING, szText, sizeof(szText)); + UiMessageBox(uiparams->interfacedata->messageboxcallback, hWnd, szText, szTitle, MB_OK | MB_ICONERROR); + + // Kill off children dialogs + KillChildWindows(window, hWnd); + } + } + else if (wparam == SRVMAINTAIN_TIMER_ID) { + // Update lag counters in chat room + SrvMaintainLatencies(); + + // Download new ads + SrvMaintainAds(); + } + + return 0; + + case WM_NOTIFICATION_WAITING: + UiNotification(); + return 1; + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + + case WM_QUERYNEWPALETTE: { + // We are gaining focus, so set our own prefs + UpdateWindow(window); // draw window first.. syscolor stuff may take a while + ColorPrefActivate(TRUE); + break; + } + case WM_ACTIVATEAPP: + // If we are losing focus, restore windows system prefs + if (!wparam) + ColorPrefActivate(FALSE); + break; + + case WM_DESTROY: + ghWndUiMainParent = NULL; + + UiVidFadeOut(DEFAULT_STEPS*2); + + SDlgKillTimer(window, LOGO_TIMER_ID); + SDlgKillTimer(window, SRVMAINTAIN_TIMER_ID); + + DestroyArtwork(window); + break; + + case WM_INITDIALOG: + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + if (!uiparams) + return 1; + + LoadArtwork(window, uiparams->interfacedata->artcallback); + + LogoSetTimer(window, LOGO_TIMER_ID, uiparams->interfacedata->getdatacallback); + SDlgSetTimer(window, SRVMAINTAIN_TIMER_ID, SRVMAINTAIN_TIMER_DELAY, NULL); + + // Signal for us to launch the Chatroom. We launch it here, since the chatroom is modal. + PostMessage(window, WM_COMMAND, IDOK, (LPARAM)NULL); + + // This window will receive wm_notification_waiting message + ghWndUiMainParent = window; + + UiLoadCursors(window, uiparams->interfacedata); + + // Turn on colors + UiVidFade(1,1); + return 1; + } + + return SDlgDefDialogProc(window,message,wparam,lparam); + +} diff --git a/Storm/SOURCE/BATTLE/CACHE.CPP b/Storm/SOURCE/BATTLE/CACHE.CPP new file mode 100644 index 0000000..9a18071 --- /dev/null +++ b/Storm/SOURCE/BATTLE/CACHE.CPP @@ -0,0 +1,593 @@ +/**************************************************************************** +* +* CACHE.CPP +* battle.net file caching functions +* +* By Michael O'Brien (11/24/96) +* +***/ + +#include "pch.h" + +#define ARCHIVENAME "bncache.dat" +#define DEFENTRIES 1024 // must be a power of two +#define DEFLCID MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT) +#define MAXFILESIZE 0x01000000 +#define FILEFLAGS 0xC0000000 +#define SIGNATURE 0x1A434E42 +#define DEALLOCATED 0xFFFFFFFE +#define NOBLOCK 0xFFFFFFFF + +#define HASH_INDEX 0 +#define HASH_CHECK0 1 +#define HASH_CHECK1 2 +#define HASH_ENCRYPTKEY 3 +#define HASH_ENCRYPTDATA 4 + +typedef struct _ARCHIVEHEADER { + DWORD signature; + DWORD headersize; + DWORD archivesize; + DWORD version; + DWORD hashoffset; + DWORD blockoffset; + DWORD hashentries; + DWORD blockentries; +} ARCHIVEHEADER, *ARCHIVEHEADERPTR; + +typedef struct _HASHENTRY { + DWORD hashcheck[2]; + LCID lcid; + DWORD block; +} HASHENTRY, *HASHENTRYPTR; + +typedef struct _BLOCKENTRY { + DWORD offset; + DWORD sizealloc; + DWORD sizefile; + DWORD flags; +} BLOCKENTRY, *BLOCKENTRYPTR; + +typedef struct _FILEHEADER { + DWORD headersize; // must be first field + DWORD headerversion; + DWORD attributes; + DWORD reserved1; + FILETIME lastaccesstime; + FILETIME lastwritetime; + FILETIME creationtime; + FILETIME minexpiretime; + FILETIME maxexpiretime; + char filename[MAX_PATH]; +} FILEHEADER, *FILEHEADERPTR; + +static HANDLE cache_archivefile = INVALID_HANDLE_VALUE; +static ARCHIVEHEADERPTR cache_archiveheader = NULL; +static BLOCKENTRYPTR cache_blocktable = NULL; +static CCritSect cache_critsect; +static LPDWORD cache_hashsource = NULL; +static HASHENTRYPTR cache_hashtable = NULL; +static BOOL cache_initialized = 0; + +//=========================================================================== +static void inline Decrypt (LPDWORD data, DWORD bytes, DWORD key) { + DWORD adjust = 0xEEEEEEEE; + DWORD iter = bytes >> 2; + while (iter--) { + adjust += *(cache_hashsource+(HASH_ENCRYPTDATA << 8)+(key & 0xFF)); + adjust += (*data++ ^= adjust+key)+(adjust << 5)+3; + key = (key >> 11) | ((key << 21) ^ 0xFFE00000)+0x11111111; + } +} + +//=========================================================================== +static void inline Encrypt (LPDWORD data, DWORD bytes, DWORD key) { + DWORD adjust = 0xEEEEEEEE; + DWORD iter = bytes >> 2; + while (iter--) { + DWORD origdata = *data; + adjust += *(cache_hashsource+(HASH_ENCRYPTDATA << 8)+(key & 0xFF)); + *data++ = origdata ^ (adjust+key); + adjust += origdata + (adjust << 5)+3; + key = (key >> 11) | ((key << 21) ^ 0xFFE00000)+0x11111111; + } +} + +//=========================================================================== +static FILETIME *GetCurrentFileTime (DWORD offsetseconds) { + static FILETIME filetime; + static DWORD lastoffset = 0; + static DWORD lastcall = 0; + if ((offsetseconds != lastoffset) || + (GetTickCount() != lastcall)) { + SYSTEMTIME systime; + GetSystemTime(&systime); + SystemTimeToFileTime(&systime,&filetime); + __int64 offset = 10000000ul; + offset *= (__int64)offsetseconds; + *(__int64 *)&filetime += offset; + lastoffset = offsetseconds; + lastcall = GetTickCount(); + } + return &filetime; +} + +//=========================================================================== +static DWORD inline Hash (LPCSTR filename, int hashtype) { + DWORD result = 0x7FED7FED; + DWORD adjust = 0xEEEEEEEE; + while (filename && *filename) { + char origchar = toupper(*filename++); + result = (result+adjust) ^ *(cache_hashsource+(hashtype << 8)+origchar); + adjust += origchar+result+(adjust << 5)+3; + } + return result; +} + +//=========================================================================== +static void inline InitializeHashSource () { + if (cache_hashsource) { + DWORD seed = 0x100001; + for (int loop1 = 0; loop1 < 256; ++loop1) + for (int loop2 = 0; loop2 < 5; ++loop2) { + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand1 = seed & 0xFFFF; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand2 = seed & 0xFFFF; + *(cache_hashsource+(loop2 << 8)+loop1) = (rand1 << 16) | rand2; + } + } +} + +//=========================================================================== +static DWORD inline SearchHashTable (LPCSTR filename, LCID lcid) { + DWORD hashindex = Hash(filename,HASH_INDEX); + DWORD hashcheck0 = Hash(filename,HASH_CHECK0); + DWORD hashcheck1 = Hash(filename,HASH_CHECK1); + DWORD entry = hashindex & (cache_archiveheader->hashentries-1); + DWORD firstentry = entry; + DWORD found = 0xFFFFFFFF; + while ((cache_hashtable+entry)->block != NOBLOCK) { + if (((cache_hashtable+entry)->hashcheck[0] == hashcheck0) && + ((cache_hashtable+entry)->hashcheck[1] == hashcheck1) && + ((cache_hashtable+entry)->block != DEALLOCATED)) + if ((cache_hashtable+entry)->lcid == lcid) + return entry; + else if ((cache_hashtable+entry)->lcid == MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)) + found = entry; + entry = (entry+1) & (cache_archiveheader->hashentries-1); + if (entry == firstentry) + break; + } + return found; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +void CacheDestroy () { + cache_critsect.Enter(); + cache_initialized = 0; + if (cache_blocktable) { + FREE(cache_blocktable); + cache_blocktable = NULL; + } + if (cache_hashtable) { + FREE(cache_hashtable); + cache_hashtable = NULL; + } + if (cache_archiveheader) { + FREE(cache_archiveheader); + cache_archiveheader = NULL; + } + if (cache_archivefile) { + CloseHandle(cache_archivefile); + cache_archivefile = INVALID_HANDLE_VALUE; + } + if (cache_hashsource) { + FREE(cache_hashsource); + cache_hashsource = NULL; + } + cache_critsect.Leave(); +} + +//=========================================================================== +BOOL CacheFree (LPVOID data, DWORD databytes) { + if (!data) + return 0; + FREE(data); + return 1; +} + +//=========================================================================== +BOOL CacheInitialize () { + cache_critsect.Enter(); + if (cache_initialized) + CacheDestroy(); + __try { + + // INITIALIZE THE HASH TABLES + cache_hashsource = (LPDWORD)ALLOC(5*256*sizeof(DWORD)); + if (cache_hashsource) + InitializeHashSource(); + else + __leave; + + // DETERMINE THE PATH TO THE ARCHIVE FILE + TCHAR archivefilename[MAX_PATH] = ""; + GetModuleFileName(GetModuleHandle(NULL),archivefilename,MAX_PATH); + { + LPTSTR separator = strchr(archivefilename,'\\'); + while (separator && strchr(separator+1,'\\')) + separator = strchr(separator+1,'\\'); + if (separator) + *separator = 0; + } + strcat(archivefilename,"\\" ARCHIVENAME); + + // OPEN THE ARCHIVE FILE + cache_archivefile = CreateFile(archivefilename, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (cache_archivefile == INVALID_HANDLE_VALUE) + __leave; + + // LOAD THE ARCHIVE HEADER + cache_archiveheader = NEW(ARCHIVEHEADER); + if (!cache_archiveheader) + __leave; + { + DWORD bytesread = 0; + ReadFile(cache_archivefile,cache_archiveheader,sizeof(ARCHIVEHEADER),&bytesread,NULL); + } + if (cache_archiveheader->signature != SIGNATURE) { + ZeroMemory(cache_archiveheader,sizeof(ARCHIVEHEADER)); + cache_archiveheader->signature = SIGNATURE; + cache_archiveheader->headersize = sizeof(ARCHIVEHEADER); + } + + // LOAD THE HASH TABLE + DWORD hashentries = max(DEFENTRIES,cache_archiveheader->hashentries); + cache_hashtable = (HASHENTRYPTR)ALLOC(hashentries*sizeof(HASHENTRY)); + if (cache_hashtable) + ZeroMemory(cache_hashtable,hashentries*sizeof(HASHENTRY)); + else + __leave; + if (cache_archiveheader->hashoffset || cache_archiveheader->hashentries) { + SetFilePointer(cache_archivefile,cache_archiveheader->hashoffset,NULL,FILE_BEGIN); + DWORD bytesread; + ReadFile(cache_archivefile,cache_hashtable,hashentries*sizeof(HASHENTRY),&bytesread,NULL); + Decrypt((LPDWORD)cache_hashtable,hashentries*sizeof(HASHENTRY),Hash("(hash table)",HASH_ENCRYPTKEY)); + } + else { + cache_archiveheader->hashoffset = sizeof(ARCHIVEHEADER); + cache_archiveheader->hashentries = DEFENTRIES; + cache_archiveheader->archivesize = max(cache_archiveheader->archivesize, + cache_archiveheader->hashoffset + +DEFENTRIES*sizeof(HASHENTRY)); + for (DWORD loop = 0; loop < DEFENTRIES; ++loop) + (cache_hashtable+loop)->block = NOBLOCK; + } + + // LOAD THE BLOCK TABLE + DWORD blockentries = max(DEFENTRIES,cache_archiveheader->blockentries); + cache_blocktable = (BLOCKENTRYPTR)ALLOC(blockentries*sizeof(BLOCKENTRY)); + if (cache_blocktable) + ZeroMemory(cache_blocktable,DEFENTRIES*sizeof(BLOCKENTRY)); + else + __leave; + if (cache_archiveheader->blockoffset || cache_archiveheader->blockentries) { + SetFilePointer(cache_archivefile,cache_archiveheader->blockoffset,NULL,FILE_BEGIN); + DWORD bytesread; + ReadFile(cache_archivefile,cache_blocktable,blockentries*sizeof(BLOCKENTRY),&bytesread,NULL); + Decrypt((LPDWORD)cache_blocktable,blockentries*sizeof(BLOCKENTRY),Hash("(block table)",HASH_ENCRYPTKEY)); + } + else { + cache_archiveheader->blockoffset = sizeof(ARCHIVEHEADER)+DEFENTRIES*sizeof(HASHENTRY); + cache_archiveheader->archivesize = max(cache_archiveheader->archivesize, + cache_archiveheader->blockoffset + +DEFENTRIES*sizeof(BLOCKENTRY)); + } + + } + __finally { + if (cache_archiveheader && cache_blocktable && cache_hashtable) + cache_initialized = 1; + else + CacheDestroy(); + } + cache_critsect.Leave(); + return 1; +} + +//=========================================================================== +BOOL CacheLoadFile (LPCSTR filename, + FILETIME *lastwritetime, + LPVOID *data, + DWORD *databytes) { + if (lastwritetime) + ZeroMemory(lastwritetime,sizeof(FILETIME)); + if (data) + *data = NULL; + if (databytes) + *databytes = 0; + if (!(filename && *filename && data && databytes && cache_initialized)) + return 0; + cache_critsect.Enter(); + + // FIND THE REQUESTED FILE + DWORD index = SearchHashTable(filename,DEFLCID); + if (index == 0xFFFFFFFF) { + cache_critsect.Leave(); + return 0; + } + DWORD block = (cache_hashtable+index)->block; + if (block >= cache_archiveheader->blockentries) { + cache_critsect.Leave(); + return 0; + } + + // LOAD ITS DATA BLOCK + FILEHEADER fileheader; + ZeroMemory(&fileheader,sizeof(FILEHEADER)); + if ((cache_blocktable+block)->flags & FILEFLAGS) { + SetFilePointer(cache_archivefile, + (cache_blocktable+block)->offset, + NULL, + FILE_BEGIN); + DWORD bytesread; + ReadFile(cache_archivefile, + &fileheader.headersize, + sizeof(DWORD), + &bytesread, + NULL); + ReadFile(cache_archivefile, + &fileheader.headersize+1, + min(fileheader.headersize,sizeof(FILEHEADER))-sizeof(DWORD), + &bytesread, + NULL); + } + + // VERIFY THAT IT IS THE CORRECT FILE AND THAT IT HASN'T EXPIRED + if (_stricmp(filename,fileheader.filename)) { + cache_critsect.Leave(); + return 0; + } + if (CompareFileTime(GetCurrentFileTime(0),&fileheader.maxexpiretime) > 0) { + cache_critsect.Leave(); + return 0; + } + + // VERIFY THAT THE SIZE IS REASONABLE + if ((cache_blocktable+block)->sizefile > MAXFILESIZE) { + cache_critsect.Leave(); + return 0; + } + + // GET THE LAST WRITE TIME + if (lastwritetime) + CopyMemory(lastwritetime,&fileheader.lastwritetime,sizeof(FILETIME)); + + // UPDATE THE LAST ACCESS TIME + CopyMemory(&fileheader.lastaccesstime,GetCurrentFileTime(0),sizeof(FILETIME)); + SetFilePointer(cache_archivefile, + (cache_blocktable+block)->offset, + NULL, + FILE_BEGIN); + { + DWORD byteswritten; + WriteFile(cache_archivefile, + &fileheader, + min(sizeof(FILEHEADER),fileheader.headersize), + &byteswritten, + NULL); + } + + // ALLOCATE A BUFFER AND READ THE FILE DATA + *data = ALLOC((cache_blocktable+block)->sizefile); + if (!*data) { + cache_critsect.Leave(); + return 0; + } + SetFilePointer(cache_archivefile, + (cache_blocktable+block)->offset+fileheader.headersize, + NULL, + FILE_BEGIN); + ReadFile(cache_archivefile, + *data, + (cache_blocktable+block)->sizefile, + databytes, + NULL); + + cache_critsect.Leave(); + return 1; +} + +//=========================================================================== +BOOL CacheSaveFile (LPCSTR filename, + LPVOID data, + DWORD databytes, + FILETIME *lastwritetime, + DWORD minexpireseconds, + DWORD maxexpireseconds) { + if (!(filename && *filename && data && databytes && lastwritetime && + maxexpireseconds && cache_initialized)) + return 0; + cache_critsect.Enter(); + + // REMOVE ANY EXISTING INSTANCES OF THIS FILE + { + DWORD index = SearchHashTable(filename,DEFLCID); + while (index != 0xFFFFFFFF) { + DWORD block = (cache_hashtable+index)->block; + if (block < cache_archiveheader->blockentries) { + (cache_blocktable+block)->sizefile = 0; + (cache_blocktable+block)->flags = 0; + } + (cache_hashtable+index)->block = DEALLOCATED; + index = SearchHashTable(filename,DEFLCID); + } + } + + // SEARCH FOR A FREE BLOCK WHICH IS BIG ENOUGH TO STORE THE FILE + DWORD minalloc = sizeof(FILEHEADER)+databytes; + DWORD block = 0; + while ((block < cache_archiveheader->blockentries) && + ((cache_blocktable+block)->flags || + ((cache_blocktable+block)->sizealloc < minalloc))) + ++block; + + // IF WE DIDN'T FIND ONE, THEN SEARCH FOR A BLOCK WHICH IS PAST ITS + // MINIMUM EXPIRATION TIME AND IS BIG ENOUGH TO STORE THE FILE + if (block >= cache_archiveheader->blockentries) { + block = 0; + while (block < cache_archiveheader->blockentries) { + if ((cache_blocktable+block)->sizealloc >= minalloc) { + SetFilePointer(cache_archivefile, + (cache_blocktable+block)->offset, + NULL, + FILE_BEGIN); + FILEHEADER fileheader; + ZeroMemory(&fileheader,sizeof(FILEHEADER)); + DWORD bytesread; + ReadFile(cache_archivefile, + &fileheader.headersize, + sizeof(DWORD), + &bytesread, + NULL); + ReadFile(cache_archivefile, + &fileheader.headersize+1, + min(fileheader.headersize,sizeof(FILEHEADER))-sizeof(DWORD), + &bytesread, + NULL); + if (CompareFileTime(GetCurrentFileTime(0),&fileheader.minexpiretime) > 0) + break; + } + ++block; + } + } + + // IF WE FOUND A BLOCK TO USE, REMOVE ANY HASH TABLE REFERENCES TO IT + if (block < cache_archiveheader->blockentries) { + for (DWORD index = 0; index < cache_archiveheader->hashentries; ++index) + if ((cache_hashtable+index)->block == block) + (cache_hashtable+index)->block = DEALLOCATED; + } + + // OTHERWISE, TRY TO CREATE A NEW BLOCK + else { + if (block >= DEFENTRIES) + return 0; + else { + (cache_blocktable+block)->offset = cache_archiveheader->archivesize; + (cache_blocktable+block)->sizealloc = minalloc; + cache_archiveheader->archivesize += minalloc; + cache_archiveheader->blockentries = block+1; + } + } + + // ADD A HASH TABLE ENTRY FOR THE BLOCK + { + DWORD hashindex = Hash(filename,HASH_INDEX); + DWORD hashcheck0 = Hash(filename,HASH_CHECK0); + DWORD hashcheck1 = Hash(filename,HASH_CHECK1); + DWORD entry = hashindex & (cache_archiveheader->hashentries-1); + DWORD firstentry = entry; + DWORD found = NOBLOCK; + while (((cache_hashtable+entry)->block != NOBLOCK) && + ((cache_hashtable+entry)->block != DEALLOCATED)) { + entry = (entry+1) & (cache_archiveheader->hashentries-1); + if (entry == firstentry) + break; + } + if (((cache_hashtable+entry)->block == NOBLOCK) || + ((cache_hashtable+entry)->block == DEALLOCATED)) { + (cache_hashtable+entry)->hashcheck[0] = hashcheck0; + (cache_hashtable+entry)->hashcheck[1] = hashcheck1; + (cache_hashtable+entry)->lcid = DEFLCID; + (cache_hashtable+entry)->block = block; + } + else { + cache_critsect.Leave(); + return 0; + } + } + + // FILL IN THE FILE'S BLOCK ENTRY + (cache_blocktable+block)->sizefile = databytes; + (cache_blocktable+block)->flags = FILEFLAGS; + + // FILL IN THE FILE HEADER + FILEHEADER fileheader; + ZeroMemory(&fileheader,sizeof(FILEHEADER)); + fileheader.headersize = sizeof(FILEHEADER); + CopyMemory(&fileheader.creationtime ,GetCurrentFileTime(0) ,sizeof(FILETIME)); + CopyMemory(&fileheader.lastwritetime ,lastwritetime ,sizeof(FILETIME)); + CopyMemory(&fileheader.minexpiretime ,GetCurrentFileTime(minexpireseconds),sizeof(FILETIME)); + CopyMemory(&fileheader.maxexpiretime ,GetCurrentFileTime(maxexpireseconds),sizeof(FILETIME)); + CopyMemory(&fileheader.lastaccesstime,GetCurrentFileTime(0) ,sizeof(FILETIME)); + strcpy(fileheader.filename,filename); + + // SAVE THE FILE + SetFilePointer(cache_archivefile, + (cache_blocktable+block)->offset, + NULL, + FILE_BEGIN); + { + DWORD byteswritten; + WriteFile(cache_archivefile, + &fileheader, + sizeof(FILEHEADER), + &byteswritten, + NULL); + WriteFile(cache_archivefile, + data, + databytes, + &byteswritten, + NULL); + } + + // SAVE THE FILE SYSTEM DATA + { + DWORD byteswritten; + SetFilePointer(cache_archivefile,0,NULL,FILE_BEGIN); + WriteFile(cache_archivefile, + cache_archiveheader, + sizeof(ARCHIVEHEADER), + &byteswritten, + NULL); + DWORD hashsize = max(DEFENTRIES,cache_archiveheader->hashentries )*sizeof(HASHENTRY); + DWORD blocksize = max(DEFENTRIES,cache_archiveheader->blockentries)*sizeof(BLOCKENTRY); + LPVOID buffer = ALLOC(max(hashsize,blocksize)); + if (buffer) { + SetFilePointer(cache_archivefile,cache_archiveheader->hashoffset,NULL,FILE_BEGIN); + CopyMemory(buffer,cache_hashtable,hashsize); + Encrypt((LPDWORD)buffer,hashsize,Hash("(hash table)",HASH_ENCRYPTKEY)); + WriteFile(cache_archivefile, + buffer, + hashsize, + &byteswritten, + NULL); + SetFilePointer(cache_archivefile,cache_archiveheader->blockoffset,NULL,FILE_BEGIN); + CopyMemory(buffer,cache_blocktable,blocksize); + Encrypt((LPDWORD)buffer,blocksize,Hash("(block table)",HASH_ENCRYPTKEY)); + WriteFile(cache_archivefile, + buffer, + blocksize, + &byteswritten, + NULL); + FREE(buffer); + } + } + + cache_critsect.Leave(); + return 1; +} diff --git a/Storm/SOURCE/BATTLE/CANCEL.CPP b/Storm/SOURCE/BATTLE/CANCEL.CPP new file mode 100644 index 0000000..b2443d7 --- /dev/null +++ b/Storm/SOURCE/BATTLE/CANCEL.CPP @@ -0,0 +1,136 @@ +/**************************************************************************** +* +* cancel.CPP +* battle.net +* +* By Michael Morhaime +* +***/ + +#include "pch.h" + + + +//**************************************************************************** +//**************************************************************************** + +static LPBYTE sgBackgroundBmp = NULL; +static LPBYTE sgButtonBmp = NULL; + + +//=========================================================================== +static void DestroyArtwork (HWND window) { + if (sgBackgroundBmp) { + FREE(sgBackgroundBmp); + sgBackgroundBmp = NULL; + } + + if (sgButtonBmp) { + FREE(sgButtonBmp); + sgButtonBmp = NULL; + } +} + +//=========================================================================== +static BOOL LoadArtwork (HWND window, SNETGETARTPROC artcallback) { + int btn_ids[] = { + IDCANCEL, + 0 + }; + + int btn_static[] = { + IDC_TITLE, + 0 + }; + + SIZE sizeBtns; + SIZE bgSize; + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_POPUPBACKGROUND_SML, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, // Palette is already loaded + FALSE, + &sgBackgroundBmp, + &bgSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BUTTON_SML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgButtonBmp, + &sizeBtns); + + SDlgSetControlBitmaps (window, btn_ids, NULL, sgButtonBmp, &sizeBtns, SDLG_ADJUST_VERTICAL); + SDlgSetControlBitmaps (window, btn_static, NULL, sgBackgroundBmp, &bgSize, SDLG_ADJUST_CONTROLPOS); + + + return 1; +} + + + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + + + +//=========================================================================== +BOOL CALLBACK ConnectCancelDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + static SNETUIDATAPTR sInterfacedata; + static HWND shWndCancelDlg; + + switch (message) { + case WM_COMMAND: { + switch (LOWORD(wparam)) { + case IDOK: + case IDCANCEL: + SrvCancel(); + return 0; + } + break; + } + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + case WM_DESTROY: + DestroyArtwork(window); + break; + + case WM_INITDIALOG: + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + sInterfacedata = (SNETUIDATAPTR)lparam; + UiLoadCursors(window, sInterfacedata); + + if (sInterfacedata) + LoadArtwork(window, sInterfacedata->artcallback); + return 1; + + } + + return SDlgDefDialogProc(window,message,wparam,lparam); +} + + diff --git a/Storm/SOURCE/BATTLE/CAPS.DAT b/Storm/SOURCE/BATTLE/CAPS.DAT new file mode 100644 index 0000000..b47082b Binary files /dev/null and b/Storm/SOURCE/BATTLE/CAPS.DAT differ diff --git a/Storm/SOURCE/BATTLE/CAPS.MPQ b/Storm/SOURCE/BATTLE/CAPS.MPQ new file mode 100644 index 0000000..c3a821c Binary files /dev/null and b/Storm/SOURCE/BATTLE/CAPS.MPQ differ diff --git a/Storm/SOURCE/BATTLE/CHAT.H b/Storm/SOURCE/BATTLE/CHAT.H new file mode 100644 index 0000000..b32aa85 --- /dev/null +++ b/Storm/SOURCE/BATTLE/CHAT.H @@ -0,0 +1,33 @@ +/**************************************************************************** +* +* chat.h +* +* By Michael Morhaime +* +***/ + + +// If connection is so bad, disable ability to create/join games +extern BOOL gbConnectionSucks; + + +// Defined in Chat.cpp, and chatchnnl.cpp +void ChatAddUser (SNADDUSERPTR pAddUserRec); +void ChatDeleteUser(SNDELETEUSERPTR pDeleteUserRec); +void ChatReceiveMsg(SNDISPLAYSTRINGPTR pDispStringRec); +void ChatAddChannel(LPCSTR szChannel); +void ChatDeleteChannel(LPCSTR szChanell); +void ChatJoinChannel(SNJOINCHANNELPTR pJoinChannelRec); +void ChatUpdatePingTime(SNUPDATEPINGTIMEPTR pUpdatePingTimeRec); +void ChatChannelFull(LPCSTR szChannel); +void ChatChannelDoesNotExist(LPCSTR szChannel); +void ChatSetUserName(LPCSTR szUserName); +void ChatChangeUserFlags(SNCHANGEUSERFLAGSPTR pChangeUserFlagsRec); +void ChatChannelRestricted(LPCSTR szChannel); +void ChatSquelchUser(SNSQUELCHUSERPTR pSquelchUserRec); +void ChatUnsquelchUser(SNSQUELCHUSERPTR pSquelchUserRec); + + +// Defined in Ad.cpp +void AdSetInfo(SNADINFOPTR pAdInfo); +void AdDisplay(LPVOID pVoid, DWORD dwSize); diff --git a/Storm/SOURCE/BATTLE/CHATCHNL.CPP b/Storm/SOURCE/BATTLE/CHATCHNL.CPP new file mode 100644 index 0000000..2c4507f --- /dev/null +++ b/Storm/SOURCE/BATTLE/CHATCHNL.CPP @@ -0,0 +1,472 @@ +/**************************************************************************** +* +* chatchnl.cpp +* battle.net user interface functions +* +* By Michael Morhaime +* +***/ + +#include "pch.h" + +#define MAX_STRING_LEN 256 + +static HWND sghWndChannel = NULL; +static char sgszChannel[MAX_CHANNEL_LEN]; +static char *sgpszLastChannel; +static PTCHANNEL_LIST sgpChannelListHead = NULL; + +static LPBYTE sgBackgroundBmp = NULL; +static LPBYTE sgButtonBmp = NULL; +static SNETUIDATAPTR sgInterfacedata; + + + + +//=========================================================================== +// External Functions +//=========================================================================== +UINT ChatGetUserFlags(void); + +//=========================================================================== +static void DestroyArtwork (HWND window) { + if (sgBackgroundBmp) { + FREE(sgBackgroundBmp); + sgBackgroundBmp = NULL; + } + + if (sgButtonBmp) { + FREE(sgButtonBmp); + sgButtonBmp = NULL; + } +} + +//=========================================================================== +static BOOL LoadArtwork (HWND window, SNETGETARTPROC artcallback) { + int btn_ids[] = { + IDOK, + IDCANCEL, + 0 + }; + + int btn_desc[] = { + IDC_GAMEDESCRIPTION, + 0, + }; + + SIZE sizeBtns; + SIZE bgSize; + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_BATTLE_SELECT_CHNL_BKG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgBackgroundBmp, + &bgSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BUTTON_XSML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgButtonBmp, + &sizeBtns); + + SDlgSetControlBitmaps (window, btn_ids, NULL, sgButtonBmp, &sizeBtns, SDLG_ADJUST_VERTICAL); + SDlgSetControlBitmaps (window, btn_desc, NULL, sgBackgroundBmp, &bgSize, SDLG_ADJUST_CONTROLPOS); + return 1; +} + + +//=========================================================================== +static int ProcessName(LPSTR szName) { + char szTemp[MAX_CHANNEL_LEN]; + int nStart, nEnd; + + // Take the name and remove leading and trailing spaces + strcpy(szTemp, szName); + + + // Proceed until we find a non-space or null termination + for (nStart=0; ;nStart++) { + if (szTemp[nStart] != ' ') + break; + if (szTemp[nStart] == 0) + return 0; + } + + + // Now start at the end and look for a non-space character. Proceed until + // we reach the beginning + for (nEnd=strlen(szTemp)-1; ;nEnd--) { + + if (szTemp[nEnd] != ' ') + break; + + if (nEnd <= nStart) + return 0; + } + + szTemp[++nEnd] = 0; // NULL terminate string before trailing spaces + + strcpy(szName, &szTemp[nStart]); + return(nEnd - nStart); // Length of string not including NULL termination +} + + + +//**************************************************************************** +//**************************************************************************** +static void convert_nasty(LPSTR nasty) { + while (*nasty != 0) { + (*nasty)--; + nasty++; + } +} + +//**************************************************************************** +//**************************************************************************** +BOOL IsNastyName(LPCTSTR name) { + TCHAR tempname[MAX_CHANNEL_LEN]; + TCHAR nasty[MAX_CHANNEL_LEN]; + + strcpy(tempname, name); + _strlwr(tempname); + + for (int index = IDS_FIRST_NASTY; index <= IDS_LAST_NASTY; index++) { + LoadString(global_hinstance, index, nasty, MAX_CHANNEL_LEN); + convert_nasty(nasty); + _strlwr(nasty); + if (strstr(tempname, nasty)) { + return TRUE; + } + } + return FALSE; +} + + +//**************************************************************************** +// InvalidChars() +// +// NOTE: SPACE is not included as a bad char. SPACE and any other additional bad +// characters should be placed into the additional string. Things like GAME NAME +// may include spaces. +//**************************************************************************** +BOOL InvalidChars(LPCTSTR name, LPCTSTR additionalbad) { + LPTSTR basicbad = ",<>%&\\\"?*#/"; + unsigned char c; + + if (strpbrk(name, basicbad)) + return TRUE; + + if (strpbrk(name, additionalbad)) + return TRUE; + + while (0 != (c = *name)) { + if (c < ' ') return TRUE; + if ((c > '~') && (c < 0xc0)) return TRUE; + name++; + } + return FALSE; +} + + + +//=========================================================================== +static void AddChannels(HWND window) { + PTCHANNEL_LIST pCurr; + HWND hWndList; + + hWndList = GetDlgItem(window, IDC_CHANNELLIST); + if (!hWndList) + return; + + + // Add all the channels we know about to the linked list + pCurr = sgpChannelListHead; + while (pCurr) { + SendMessage(hWndList, LB_ADDSTRING, 0, (LPARAM)pCurr->szChannel); + pCurr = pCurr->next; + } + + // update our scroll bar + ListUpdateScrollbar(hWndList); +} + + +//=========================================================================== +// NOTE: szChannel will no longer be valid after hitting a PeekMessage loop +//=========================================================================== +void ChatChannelFull(LPCSTR szChannel) { + char szText[256]; + char szFmt[256]; + + // Protect this routine + if (!sghWndChannel || !sgInterfacedata) + return; + + LoadString(global_hinstance,IDS_CHANNEL_FULL,szFmt, sizeof(szFmt)); + sprintf(szText, szFmt, szChannel); + UiMessageBox(sgInterfacedata->messageboxcallback, sghWndChannel, szText, NULL, MB_OK); + + // Allow user to enter another channel name + EnableWindow(GetDlgItem(sghWndChannel, IDOK), TRUE); +} + + +//=========================================================================== +// NOTE: szChannel will no longer be valid after hitting a PeekMessage loop +//=========================================================================== +void ChatChannelDoesNotExist(LPCSTR szChannel) { + char szText[256]; + + // Make sure window is still around + if (!sghWndChannel) + return; + + // Make copy before sending this to a messagebox. + strcpy(szText, szChannel); + SendMessage(sghWndChannel, WM_CHANNEL_DOESNOTEXIST, 0, (LPARAM)szText); +} + +//=========================================================================== +// NOTE: szChannel will no longer be valid after hitting a PeekMessage loop +//=========================================================================== +void ChatChannelRestricted(LPCSTR szChannel) { + TCHAR szUserName[MAXSTRINGLENGTH]; + TCHAR szUserDesc[MAXSTRINGLENGTH]; + UINT nFlags; + char szError[256] = ""; + + if (!sghWndChannel) + return; + + if (sgInterfacedata->authcallback) { + SrvGetLocalPlayerName (szUserName,sizeof(szUserName)); + SrvGetLocalPlayerDesc (szUserDesc,sizeof(szUserDesc)); + nFlags = ChatGetUserFlags(); + + + if (!sgInterfacedata->authcallback(SNET_AUTHTYPE_CHANNEL, szUserName, szUserDesc, nFlags, szChannel, szError, sizeof(szError))) { + SendMessage(sghWndChannel, WM_CHANNEL_RESTRICTED, 0, (LPARAM)szError); + return; + } + + // Ok to join channel + SrvJoinChannel(szChannel, TRUE); + } + +} + +//=========================================================================== +void ChatChannelJoined(LPCSTR szChannel) { + if (!sghWndChannel) + return; + + SendMessage(sghWndChannel, WM_CHANNEL_JOINED, 0, 0); +} + +//=========================================================================== +BOOL CALLBACK ChannelDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case IDOK: { + char szText[MAX_STRING_LEN]; + + if (sgInterfacedata->soundcallback) + sgInterfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + SendDlgItemMessage(window, IDC_EDIT_NAME, WM_GETTEXT, MAX_CHANNEL_LEN, (LPARAM)(LPCSTR)szText); + + // Don't validate channel name if we selected a public channel from the list + if (LB_ERR == SendDlgItemMessage(window, IDC_CHANNELLIST, LB_GETCURSEL, 0, 0)) { + if (InvalidChars(szText, "") || !ProcessName(szText)) { + LoadString(global_hinstance,IDS_CHANNEL_NAME_INVALID,szText,MAX_STRING_LEN); + UiMessageBox(sgInterfacedata->messageboxcallback, window, szText, NULL, MB_OK | MB_ICONERROR); + return 1; + } + } + + // If user has requested the current channel, just exist the dialog + if (!strcmp(szText,sgpszLastChannel)) { + SDlgEndDialog(window, 0); + return 1; + } + + // Send request to join channel + SrvJoinChannel(szText, FALSE); + + // Name was okay, so save in the global channel string and return TRUE + strcpy(sgszChannel, szText); + + // Disable Window, until we know if we succeeded + EnableWindow((HWND)lparam, FALSE); + return 1; + } + + case IDCANCEL: + if (sgInterfacedata->soundcallback) + sgInterfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + sgszChannel[0] = 0; + SDlgEndDialog(window, 0); + return 1; + + case IDC_EDIT_NAME: + if (HIWORD(wparam) == EN_CHANGE) { + // If user types in name edit control, remove selection from list box. + if (GetFocus() == (HWND)lparam) + SendDlgItemMessage(window,IDC_CHANNELLIST,LB_SETCURSEL,(WPARAM)-1,0); + } + break; + + case IDC_CHANNELLIST: + if (HIWORD(wparam) == LBN_DBLCLK) { + HWND hWndChannelList = (HWND)lparam; + int nIndex; + + nIndex = SendMessage(hWndChannelList, LB_GETCURSEL, 0, 0); + if (nIndex != LB_ERR) { + // Make sure we update the edit control first + SendMessage(window,WM_COMMAND,MAKELONG(IDC_CHANNELLIST,LBN_SELCHANGE),(LPARAM)hWndChannelList); + + // Behave like OK was just pressed + SendMessage(window,WM_COMMAND,MAKELONG(IDOK,BN_CLICKED),(LPARAM)GetDlgItem(window, IDOK)); + } + } + else if (HIWORD(wparam) == LBN_SELCHANGE) { + HWND hWndChannelList = (HWND)lparam; + int nIndex = SendMessage(hWndChannelList, LB_GETCURSEL, 0, 0); + char szText[MAX_CHANNEL_LEN]; + + // Change text in Edit Control + if (nIndex != LB_ERR) { + SendMessage(hWndChannelList,LB_GETTEXT, nIndex, (LPARAM)(LPCSTR)szText); + SendDlgItemMessage(window, IDC_EDIT_NAME, WM_SETTEXT, 0, (LPARAM)(LPCSTR)szText); + } + + // update our scroll bar + ListUpdateScrollbar(hWndChannelList); + } + break; + } + break; + + case WM_CHANNEL_DOESNOTEXIST: { + char szText[256]; + char szFmt[256]; + int nResult; + + LoadString(global_hinstance,IDS_PROMPT_CREATECHANNEL,szFmt,sizeof(szFmt)); + sprintf(szText, szFmt, (LPCSTR)lparam); + nResult = (IDOK == UiMessageBox(sgInterfacedata->messageboxcallback, window, szText, NULL, MB_OKCANCEL)); + + if (!nResult) { + // If user said no, reenable OK button. + EnableWindow(GetDlgItem(window, IDOK), !nResult); + } + else { + // Send request to join channel, this time setting 'joinalways' flag + SrvJoinChannel((LPCSTR)lparam, TRUE); + } + + return 1; + } + + case WM_CHANNEL_RESTRICTED: { + UiMessageBox(sgInterfacedata->messageboxcallback, window, (LPCSTR)lparam, NULL, MB_OK | MB_ICONWARNING); + + // Allow user to select another channel + EnableWindow(GetDlgItem(window, IDOK), TRUE); + return 1; + } + + case WM_CHANNEL_JOINED: { + // This means that we have joined a channel + SDlgEndDialog(window, 1); + return 1; + } + + case WM_CTLCOLORSTATIC: + if (GetWindowLong((HWND)lparam, GWL_ID) == IDC_TITLE) { + SetTextColor((HDC) wparam, RGB(0xff, 0xff, 0x00)); + return (BOOL) GetStockObject(NULL_BRUSH); + } + break; + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + + case WM_DESTROY: + sghWndChannel = NULL; + DestroyArtwork(window); + break; + + + case WM_INITDIALOG: + sgInterfacedata = (SNETUIDATAPTR) lparam; + sghWndChannel = window; + + LoadArtwork(window, sgInterfacedata->artcallback); + + ScrollbarLink(GetDlgItem(window, IDC_CHANNELLIST), GetDlgItem(window, IDC_SCROLLBAR)); + + SetWindowText(GetDlgItem(window, IDC_EDIT_NAME), sgpszLastChannel); + SendDlgItemMessage(window, IDC_EDIT_NAME, EM_LIMITTEXT, MAX_CHANNEL_LEN-1, 0); + + // Set height of channel list items (some systems get strange heights) + SendDlgItemMessage(window, IDC_CHANNELLIST, LB_SETITEMHEIGHT, 0, 19); + + AddChannels(window); + return 1; + + } + + return SDlgDefDialogProc(window,message,wparam,lparam); + +} + + +//=========================================================================== +// Exported functions +//=========================================================================== + + +//=========================================================================== +BOOL ChatSelectChannel(SNETUIDATAPTR interfacedata, char *szChannel, PTCHANNEL_LIST pChannelListHead) { + int nResult; + + // Clear channel string + sgszChannel[0] = 0; + sgpszLastChannel = szChannel; // Save a pointer to the old channel + sgpChannelListHead = pChannelListHead; + + nResult = SDlgDialogBoxParam( + global_hinstance, + TEXT("DIALOG_CHAT_CHANNEL"), + (interfacedata) ? interfacedata->parentwindow : SDrawGetFrameWindow(), + ChannelDialogProc, + (LPARAM)interfacedata); + + return (nResult == 1); +} + diff --git a/Storm/SOURCE/BATTLE/CHATHELP.TXT b/Storm/SOURCE/BATTLE/CHATHELP.TXT new file mode 100644 index 0000000..14f42af --- /dev/null +++ b/Storm/SOURCE/BATTLE/CHATHELP.TXT @@ -0,0 +1,38 @@ +The buttons along the left side of the chat screen have the following functions: + +CHANNEL: Select a new channel to join or create a private channel. You will be prompted to choose either a Public Channel, or enter the name of a Private Channel that you wish to enter. To start a new Channel, enter the name of the Channel that you wish to create. + +CREATE: Create a new game for other players to join. You will be prompted to enter a name for this game and to choose a difficulty level at which you wish to play. You also have the option to make the game Private by assigning a password to the game. Other players who wish to join your game will need to know the password you have selected. + +JOIN: Enter an existing game. You can join either a Public or Private game. Public games can be joined any time they have less than four players within them. To join a Private game you will be required to enter the name of the game and its assigned password. + +QUIT: Exits the Battle.net Connection Screen and returns you to the previous screen. + + +The window on the right side of the chat screen displays the name of the Channel that you are currently in and lists the other members within that Channel. The portrait for each player displays the class and level of their character. To the right of the player's name is a colored bar that indicates their Internet latency. The longer the bar, the slower their connection. + +To communicate with other members of a Channel, type your message within the box at the bottom of the screen and then click on either the SEND or the WHISPER button. + +SEND will display your message to everyone in your Channel. + +WHISPER will send your message to the selected player only. + +To select the player to whom you wish to WHISPER, click on the player's name. Only the player whose name is highlighted will receive messages that you WHISPER. + +To toggle player joining/leaving notifications, press Alt. + + +Special Chat Commands: + +/whereis : Searches for another player in public chat rooms and games. + +/whisper : Sends a private message to this player. (Short form: /w or /msg) + +/squelch : Ignore messages from this player. + +/unsquelch : Turns off squelch for this player. + +To quickly enter a player's name, double click on the player's name from the list. + +\ +*** (Do not remove '\') *** diff --git a/Storm/SOURCE/BATTLE/CHATROOM.CPP b/Storm/SOURCE/BATTLE/CHATROOM.CPP new file mode 100644 index 0000000..8c84455 --- /dev/null +++ b/Storm/SOURCE/BATTLE/CHATROOM.CPP @@ -0,0 +1,2045 @@ +/*************************************************************************** +* +* chatroom.cpp +* battle.net chat room +* +* By Michael Morhaime +* +* +* 10/26/96 DML - added ladder button +* +***/ + +#include "pch.h" + +#define LADDER_BUTTON 0 // 1 in final +#define TEST_USERLIST 0 // 0 in final + +//*************************************************************************** +BOOL CALLBACK JoinGameDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); + + +void ChatChannelJoined(LPCSTR szChannel); + +//*************************************************************************** +#define MAX_NAME_LEN 128 +#define MAX_CHAT_LEN (MAX_MSG_LEN+MAX_NAME_LEN+3) //+3 is for "<> " around players name +#define MAX_MSG_LEN 256 +#define MAX_USERLIST_LEN (2*MAX_NAME_LEN+24) + +#define MAX_CHAT_LINES 5000 +#define PRIVATE_CHANNEL_INDEX 0 + +#define MAX_NET_LAG 6 +#define LAG_UNIT_WIDTH 3 +#define RED_THRESHOLD 5 +#define YELLOW_THRESHOLD 3 + +#define CHAT_INDENT 12 + +#define BEGIN_NAME_CHAR '<' +#define END_NAME_CHAR '>' + +#define PREFSKEY "Preferences" +#define PREFSVALUE_VERBOSE "Verbose" + +#define USER_OFFICIAL_MASK (UF_BLIZZARD|UF_MODERATOR|UF_SPEAKER|UF_SYSOP) +#define IsUserOfficial() (gnUserFlags & USER_OFFICIAL_MASK) + + + + + + HWND ghWndChat = NULL; +static HWND sghWndMsgList = NULL; +static HFONT sghChatFont = 0; + +static LPBYTE backgroundbitmap = NULL; +static LPBYTE bnBtnbitmap = NULL; +static LPBYTE SmlBtnbitmap = NULL; + +static LPBYTE redlagbitmap = NULL; +static LPBYTE yellowlagbitmap = NULL; +static LPBYTE greenlagbitmap = NULL; +static LPBYTE bmpBadConn = NULL; + +static SIZE redSize; +static SIZE yellowSize; +static SIZE greenSize; +static SIZE sizeBadConn; + +static SIZE sgBtnSize; + +static char gszCurrentChannel[MAX_MSG_LEN] = ""; +static BOOL sgbModeratedChannel = FALSE; + +static int sgnTab = CHAT_INDENT; +static BOOL sgbLadderEnabled; + +enum _hilite_colors { + FIRST_COLOR_CHAR = 0x10, + eCOLOR_NORMAL = FIRST_COLOR_CHAR, + eCOLOR_WHISPER, + eCOLOR_NOTIFY, + eCOLOR_USERNAME, + eCOLOR_MYNAME, + eCOLOR_BLIZZARD, + eCOLOR_SYSOP, + eCOLOR_MODERATOR, + eCOLOR_SPEAKER, + eCOLOR_BROADCAST, + eCOLOR_INFORMATION, + eCOLOR_ERROR, + LAST_COLOR_CHAR = eCOLOR_ERROR, +}; + +static COLORREF sgHiliteColors[] = { + RGB(0xff, 0xff, 0xff), // COLOR_NORMAL (white) + RGB(0x80, 0x80, 0x80), // COLOR_WHISPER (gray) + RGB(0, 0xff, 0), // COLOR_NOTIFY (green) + RGB(0xff, 0xff, 0), // COLOR_USERNAME (yellow) + RGB(0, 0xff, 0xff), // COLOR_MYNAME (cyan) + RGB(0, 0xff, 0xff), // COLOR_BLIZZARD (cyan) + RGB(0, 0xff, 0xff), // COLOR_SYSOP (cyan) + RGB(0xff, 0xff, 0xff), // COLOR_MODERATOR (white) + RGB(0xff, 0xff, 0), // COLOR_SPEAKER (yellow) + RGB(0xff, 0, 0), // COLOR_BROADCAST (red) + RGB(0xff, 0xff, 0), // COLOR_INFORMATION (yellow) + RGB(0xff, 0, 0), // COLOR_ERROR (red) +}; + + + +typedef struct _SQUELCH_LIST { + char szName[MAX_NAME_LEN]; + _SQUELCH_LIST *next; +} TSQUELCH_LIST, *PTSQUELCH_LIST; + +static PTCHANNEL_LIST sgpChannelListHead = NULL; +static PTSQUELCH_LIST sgpSquelchListHead = NULL; +static char sgszUserName[MAX_NAME_LEN] = ""; +static char sgszUserDesc[MAX_USERLIST_LEN]; +static DWORD sgdwVerboseMode = FALSE; // Default join/leave messages to OFF +static BOOL sgbFirstChannel = FALSE; +int gnUserFlags = 0; + +//=========================================================================== +// External Decl +//=========================================================================== +extern BOOL ChatSelectChannel(SNETUIDATAPTR interfacedata, char *szChannel, PTCHANNEL_LIST pChannelListHead); + +//=========================================================================== +// Forward Decl +//=========================================================================== +void ChatAddUser (SNADDUSERPTR pAddUserRec); +void ChatDeleteUser(SNDELETEUSERPTR pDeleteUserRec); +void ChatAddChannel(LPCSTR szChannel); +void ChatDeleteChannel(LPCSTR szChanell); +void ChatJoinChannel(SNJOINCHANNELPTR pJoinChannelRec); +void ChatReceiveMsg(SNDISPLAYSTRINGPTR pDispStringRec); + + + + + +//=========================================================================== +static void DestroyArtwork (HWND window) { + if (backgroundbitmap) { + FREE(backgroundbitmap); + backgroundbitmap = NULL; + } + + if (bnBtnbitmap) { + FREE(bnBtnbitmap); + bnBtnbitmap = NULL; + } + + if (SmlBtnbitmap) { + FREE(SmlBtnbitmap); + SmlBtnbitmap = NULL; + } + + if (redlagbitmap) { + FREE(redlagbitmap); + redlagbitmap = NULL; + } + + if (yellowlagbitmap) { + FREE(yellowlagbitmap); + yellowlagbitmap = NULL; + } + + if (greenlagbitmap) { + FREE(greenlagbitmap); + greenlagbitmap = NULL; + } + if (bmpBadConn) { + FREE(bmpBadConn); + bmpBadConn = NULL; + } +} + +//=========================================================================== +static BOOL LoadArtwork (HWND window, SNETGETARTPROC artcallback) { + int btn_ids[] = { + ID_CHATCHANNEL, + ID_CHATCREATE, + ID_CHATJOIN, + IDQUIT, + 0, + }; + int ladder_ids[] = { + ID_CHATCHANNEL, + ID_CHATCREATE, + ID_CHATJOIN, + ID_CHATLADDER, + IDQUIT, + 0, + }; + + int btn_small[] = { + IDOK, + ID_WHISPER, + 0, + }; + + int static_txt[] = { + IDC_STATIC_CHANNEL, + 0, + }; + + SIZE bnBtnSize; + SIZE SmlBtnSize; + SIZE bgSize; + + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_BATTLE_CHAT_BKG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, // Don't get palette from this artwork + FALSE, // Don't set pallete + &backgroundbitmap, + &bgSize); + + + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BATTLE_GREENLAG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &greenlagbitmap, + &greenSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BATTLE_YELLOWLAG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &yellowlagbitmap, + &yellowSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BATTLE_REDLAG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &redlagbitmap, + &redSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BATTLE_BTNS, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &bnBtnbitmap, + &bnBtnSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BUTTON_XSML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &SmlBtnbitmap, + &SmlBtnSize); + + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BATTLE_BADCONNECTION, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &bmpBadConn, + &sizeBadConn); + + if (sgbLadderEnabled) + SDlgSetControlBitmaps (window, + ladder_ids, + NULL, + bnBtnbitmap, + &bnBtnSize, + SDLG_ADJUST_VERTICAL); + else + SDlgSetControlBitmaps (window, + btn_ids, + NULL, + bnBtnbitmap, + &bnBtnSize, + SDLG_ADJUST_VERTICAL); + + SDlgSetControlBitmaps (window, btn_small, NULL, SmlBtnbitmap, &SmlBtnSize, SDLG_ADJUST_VERTICAL); + SDlgSetControlBitmaps (window, static_txt, NULL, backgroundbitmap, &bgSize, SDLG_ADJUST_CONTROLPOS); + + return 0; +} + + + + + + +//=========================================================================== +static BOOL CALLBACK ChatHelpDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + static UIPARAMSPTR uiparams = NULL; + static LPBYTE spHelpBmp = NULL; + static LPBYTE spHelpBtnsBmp = NULL; + static HGLOBAL hResource; + + + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case IDOK: + case IDCANCEL: + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + SDlgEndDialog(window, 0); + return 1; + } + + case WM_CTLCOLORSTATIC: + if (GetWindowLong((HWND)lparam, GWL_ID) == IDC_TITLE) { + SetTextColor((HDC) wparam, RGB(0xff, 0xff, 0x00)); + return (BOOL) GetStockObject(NULL_BRUSH); + } + break; + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + case WM_HELP: + // Prevent parent window from bringing up another help window + return 1; + + + case WM_DESTROY: + if (spHelpBmp) { + FREE(spHelpBmp); + spHelpBmp = NULL; + } + + if (spHelpBtnsBmp) { + FREE(spHelpBtnsBmp); + spHelpBtnsBmp = NULL; + } + + //This is not necessary in Win95 or WinNT + //FreeResource(hResource); + break; + + case WM_INITDIALOG: { + char szHelpRes[20]; + char *pText; + char *pSearch; + char *pHelpText; + int i; + + HRSRC hRsrc; + SIZE sizeBtns; + int nSize; + int btn_ids[] = { + IDOK, + IDCANCEL, + 0, + }; + + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + + // Load artwork from callback + UiLoadArtwork( + uiparams->interfacedata->artcallback, + window, + NULL, + SNET_ART_HELPBACKGROUND, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &spHelpBmp, + NULL); + + + UiLoadArtwork( + uiparams->interfacedata->artcallback, + NULL, + NULL, + SNET_ART_BUTTON_SML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &spHelpBtnsBmp, + &sizeBtns); + + SDlgSetControlBitmaps (window, btn_ids, NULL, spHelpBtnsBmp, &sizeBtns, SDLG_ADJUST_VERTICAL); + + + // Now load in help text + + LoadString(global_hinstance, IDS_CHAT_HELP_RES, szHelpRes, sizeof(szHelpRes)); + hRsrc = FindResource(global_hinstance, szHelpRes, "TEXT"); + hResource = LoadResource(global_hinstance, hRsrc); + + pText = (char *) LockResource(hResource); + nSize = SizeofResource(global_hinstance, hRsrc); + + // Make a copy of the resource, since Windows doesn't seem to + // like when we modify the original data. Not sure why. + pHelpText = (char *)ALLOC(nSize); + if (!pHelpText) + return 1; + + memcpy(pHelpText, pText, nSize); + for (i=0, pSearch=pHelpText; iparentwindow; + DWORD dwReturn; + + + // Hide the chat room so its controls don't get drawn when Select Channel Dlg disappears. + SetActiveWindow(hWndParent); + ShowWindow(ghWndChat, SW_HIDE); + + // Display the Select Channel Dlg + dwReturn = ChatSelectChannel(interfacedata, szChannel, pChannelListHead); + + // Restore Chatroom always + ShowWindow(ghWndChat, SW_SHOW); + + return dwReturn; +} +//=========================================================================== +static BOOL DoCreateGame (UIPARAMSPTR uiparams) { + DWORD dwReturn; + HWND hWndParent = uiparams->interfacedata->parentwindow; + + if (!uiparams->interfacedata->createcallback) + return 0; + + // BUILD A NEW INTERFACE DATA STRUCTURE CONTAINING OUR WINDOW HANDLE + SNETUIDATA interfacedata; + ZeroMemory(&interfacedata,sizeof(SNETUIDATA)); + if (uiparams->interfacedata) + CopyMemory(&interfacedata,uiparams->interfacedata,sizeof(SNETUIDATA)); + interfacedata.size = sizeof(SNETUIDATA); + interfacedata.parentwindow = hWndParent; + + // BUILD A CREATION DATA STRUCTURE + SNETCREATEDATA createdata; + ZeroMemory(&createdata,sizeof(SNETCREATEDATA)); + createdata.size = sizeof(SNETCREATEDATA); + createdata.providerid = PROVIDERID; + createdata.maxplayers = global_maxplayers; + createdata.createflags = SNET_CF_ALLOWPRIVATEGAMES; + + // Hide the chat room so its controls don't get drawn when Create Dlg disappears. + SetActiveWindow(hWndParent); + ShowWindow(ghWndChat, SW_HIDE); + + // CALL THE CREATE GAME CALLBACK + dwReturn = uiparams->interfacedata->createcallback(&createdata, + uiparams->programdata, + uiparams->playerdata, + &interfacedata, + uiparams->versiondata, + uiparams->playeridptr); + + + // If game was not created, restore chatroom. + if (!dwReturn) + ShowWindow(ghWndChat, SW_SHOW); + + return dwReturn; +} + + + +//=========================================================================== +static BOOL DoJoinGame (UIPARAMSPTR uiparams) { + DWORD dwReturn; + HWND hWndParent = uiparams->interfacedata->parentwindow; + + // Hide chat room so it's controls don't get drawn after Join Dialog disappears, unless we want + SetActiveWindow(hWndParent); + ShowWindow(ghWndChat, SW_HIDE); + + // Determine which join game dialog to display + TCHAR *pszTemplate = TEXT("DIALOG_JOIN_GAME"); + if (uiparams->interfacedata->categorylistcallback) + pszTemplate = TEXT("DIALOG_FILTER_JOIN_GAME"); + + dwReturn = SDlgDialogBoxParam( + global_hinstance, + pszTemplate, + hWndParent, + JoinGameDialogProc, + (LPARAM)uiparams); + + // Convert return value to BOOLEAN + dwReturn = (dwReturn == 1); + + // If user didn't join a game, restore chatroom. + if (!dwReturn) + ShowWindow(ghWndChat, SW_SHOW); + + return dwReturn; +} + + +//=========================================================================== +static HFONT SetChatFonts (HWND window) { + HFONT hFont = NULL; + LOGFONT lFont; + + if ((hFont = (HFONT) SendMessage(window, WM_GETFONT, 0, 0L))) { + // Start with dialog font and modify size and weight + if (GetObject(hFont, sizeof(LOGFONT), (LPSTR) &lFont)) { + lFont.lfHeight = -MulDiv(8, 96, 72); // height of 8 pixels + lFont.lfWidth = 0; // let Windows autosize width + lFont.lfWeight = FW_NORMAL; // change to non Bold + strcpy(lFont.lfFaceName, "Arial"); + + + if (hFont = CreateFontIndirect((LPLOGFONT) &lFont)) { + SendDlgItemMessage(window, IDC_USERLIST, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(window, IDC_CHATWINDOW, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(window, IDC_CHATEDIT, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(window, IDC_STATIC_CHANNEL, WM_SETFONT, (WPARAM)hFont, 0); + } + } + } + return hFont; +} + +//=========================================================================== +static void ToggleVerboseMode(void) { + char szText[256]; + char szFmt[128]; + + + sgdwVerboseMode = !sgdwVerboseMode; + LoadString( + global_hinstance, + (sgdwVerboseMode) ? IDS_VERBOSE_FMT : IDS_NONVERBOSE_FMT, + szFmt, + sizeof(szFmt)); + sprintf(szText, szFmt, eCOLOR_NOTIFY, szText); + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, eCOLOR_NOTIFY, (LPARAM)szText); + + SRegSaveValue(PREFSKEY,PREFSVALUE_VERBOSE,SREG_FLAG_BATTLENET,sgdwVerboseMode); +} + +//=========================================================================== +static void SendChatMsg(char *szText, BOOL bWhisper) { + if (bWhisper) { + // Fix up text string so that message goes only to the people specified + char szString[MAX_MSG_LEN*2]; + char szUser[128]; + char *pUserName; + int nIdx; + HWND hWndUserList; + + + hWndUserList = GetDlgItem(ghWndChat, IDC_USERLIST); + nIdx = SendMessage(hWndUserList, LB_GETCURSEL, 0, 0); + if (nIdx == LB_ERR) + return; + + // Send a whisper message to selected user + SendMessage(hWndUserList, LB_GETTEXT, nIdx, (LPARAM)(LPCSTR)szUser); + pUserName = strchr(szUser, '\t'); + if (!pUserName) + return; + + // NULL terminate name + *pUserName = 0; + sprintf(szString, "/whisper %s %s", szUser, szText); + SrvSendChatString(szString); + } + else + SrvSendChatString (szText); +} + + + +//**************************************************************************** +// ScrollToBtm(HWND) +// +//**************************************************************************** +static void ScrollToBtm(HWND hWnd) { + SCROLLINFO si; + int nPos = SendMessage(hWnd, LB_GETCOUNT, 0, 0)-1; + SendMessage(hWnd, LB_SETTOPINDEX, nPos, 0); + + // Update scrollbar that belongs to this listbox + HWND hWndScroll = (HWND)GetWindowLong(hWnd, GWL_USERDATA); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS; + si.nPos = nPos; + SendMessage(hWndScroll, SBM_SETSCROLLINFO, TRUE, (LPARAM)&si); +} + +//**************************************************************************** +// DisplayMsg(szMsg, bTextColor) +// +// bTextColor is the color that additional lines of text should be printed in. +//**************************************************************************** +static void DisplayMsg(LPCSTR szMsg, BYTE bTextColor) { + BYTE charSave; + char *pszText; + HDC hDC; + int nFit; + SIZE size; + RECT windowRect; + HFONT hOldFont; + BOOL bScrollToBtm = TRUE; // Normally, we'll want to always scroll to end of msg list + BOOL bDeletedLines = FALSE; + int nPixHt,nItems, nTopItem; + int nTotalLines; + + // make sure we are still in the chatroom + if (!sghWndMsgList) + return; + + hDC = GetDC(sghWndMsgList); + if (!hDC) + return; + + pszText = (char *)szMsg; + + hOldFont = (HFONT)SelectObject(hDC, sghChatFont); + + GetClientRect(sghWndMsgList, &windowRect); + + + // First set flag to indicate if list box is already scrolled to the end + nPixHt = SendMessage(sghWndMsgList, LB_GETITEMHEIGHT, 0, 0); + nItems = SendMessage(sghWndMsgList, LB_GETCOUNT, 0, 0); + nTopItem = SendMessage(sghWndMsgList, LB_GETTOPINDEX, 0, 0); + + // If user has scrolled up in list, we don't want to mess with the scroll position + if (nPixHt != LB_ERR && nItems != LB_ERR) { + if (nTopItem + windowRect.bottom/nPixHt < nItems) + bScrollToBtm = FALSE; + } + + + // Don't allow redraw until we have finished making changes to the listbox + SendMessage(sghWndMsgList, WM_SETREDRAW, FALSE, 0); + + // add message to list box + while (TRUE) { + int nStrLen; + int nLine; + int nRight; + char *p; + + + // GetTextExtentExPoint() doesn't take tabs into account, so adjust width of line manually. + nRight = windowRect.right; + p = pszText; + if (pszText[0] == '\t') { + nRight -= CHAT_INDENT; + p++; + } + + // If there is a color byte here, don't include it in the extent calculation + if (*p>=FIRST_COLOR_CHAR && *p<=LAST_COLOR_CHAR) + p++; + + nStrLen = strlen((const char *)p); + GetTextExtentExPoint( + hDC, + (const char *)p, + nStrLen, + nRight, + &nFit, + NULL, + &size); + + + // Search for a good place to end the line + if (nFit != nStrLen) { + for (nLine=nFit; nLine>0; nLine--) { + if (p[nLine] == ' ') { + nFit = nLine; + break; + } + } + } + + charSave = p[nFit]; + p[nFit] = 0; // null terminate first part of string + + // add the text line by line to the list box + nTotalLines = SendMessage(sghWndMsgList, LB_ADDSTRING, 0, (LPARAM) ((LPSTR)pszText)); + + + // did we get the whole string that time? + if (nStrLen == nFit) + break; + + // Skip past current line + pszText = p + nFit; + if (charSave == ' ') pszText++; // Don't print a space at the beginning of a line + else pszText[0] = charSave; + + // Indent start of next line + pszText-=2; + pszText[0] = '\t'; + pszText[1] = bTextColor; + } + + // Have we gone past our line limit? + if (nTotalLines >= MAX_CHAT_LINES) { + for ( ; nTotalLines >= MAX_CHAT_LINES; nTotalLines--) + // Remove oldest messages first + SendMessage(sghWndMsgList, LB_DELETESTRING, 0, 0); + bDeletedLines = TRUE; + } + + + // Update position in listbox + if (bScrollToBtm) + ScrollToBtm(sghWndMsgList); + else if (bDeletedLines) { + // restore scroll position after LB_DELETESTRING + SendMessage(sghWndMsgList, LB_SETTOPINDEX, max(0,nTopItem-1), 0); + } + + // Okay, now we're ready to redraw + SendMessage(sghWndMsgList, WM_SETREDRAW, TRUE, 0); + + // Update scrollbar that belongs to this listbox + ListUpdateScrollbar(sghWndMsgList); + + // Cleanup gdi objects + SelectObject(hDC, hOldFont); + ReleaseDC(sghWndMsgList, hDC); +} + + +//**************************************************************************** +#if TEST_USERLIST +void CreateDummyUsers(void) { + SNADDUSERREC AddUserRec; + char szName[128]; + char szDesc[128]; + + + AddUserRec.name = (LPSTR) szName; + AddUserRec.description = (LPSTR) szDesc; + AddUserRec.flags = 0; + + for (int i=0;i<50; i++) { + sprintf(szName, "Mike%d", i); + sprintf(szDesc, "%d %d 0 0 0 0 0", i, i%3); + ChatAddUser(&AddUserRec); + } + +} + +void AddDummyUser(void) { + SNADDUSERREC AddUserRec; + char szName[128]; + char szDesc[128]; + + + AddUserRec.name = (LPSTR) szName; + AddUserRec.description = (LPSTR) szDesc; + AddUserRec.flags = 0; + + static int i=0; + i++; + if (i>99) i=0; + sprintf(szName, "Mike%d", i); + sprintf(szDesc, "%d %d 0 0 0 0 0", i, i%3); + ChatAddUser(&AddUserRec); +} + +void DeleteDummyUser(void) { + SNDELETEUSERREC DeleteUserRec; + char szName[128]; + + DeleteUserRec.name = (LPSTR) szName; + DeleteUserRec.notifyuser = 1; + + static int i = 2; + i++; + if (i>99) i=0; + sprintf(szName, "Mike%d", i); + ChatDeleteUser(&DeleteUserRec); +} +#endif + + +//**************************************************************************** +//**************************************************************************** +int ListFindName(HWND hWndList, LPCSTR szName) { + int nItems; + BOOL bFound; + char *p; + int i; + + nItems = SendMessage(hWndList, LB_GETCOUNT, 0, 0); + if (nItems == LB_ERR) + return LB_ERR; + + bFound = FALSE; + for (i=0; i= sizeof(szText) || nLen == 0) + continue; + + SendMessage(hWndList, LB_GETTEXT, i, (LPARAM)(LPCSTR)szText); + + // A player name entry has a '\t' after the name before battle.net data + p = strchr(szText, '\t'); + if (p == NULL) + continue; + + // NULL terminate player name so we can do string compare. + *p = 0; + + if (!strcmp((char *)szText, szName)) { + bFound = TRUE; + break; + } + } + + if (!bFound) + i = LB_ERR; + + return i; +} + +//**************************************************************************** +//**************************************************************************** +static void BuildMsg(LPSTR pszMsg, LPCSTR pszFromTo, LPCSTR pszSender, LPCSTR pszString, BYTE bColorName, BYTE bColorString) { + sprintf(pszMsg, "%c%c%s%s%c %c%s", + bColorName, + BEGIN_NAME_CHAR, + pszFromTo, + pszSender, + END_NAME_CHAR, + bColorString, + pszString); +} + + + +//**************************************************************************** +//**************************************************************************** +static BOOL CopyNameToEditCtl(HWND hWndList, HWND hWndEdit) { + char szUser[128]; + char *pUserName; + int nIdx; + + + nIdx = SendMessage(hWndList, LB_GETCURSEL, 0, 0); + if (nIdx == LB_ERR) + return 0; + + SendMessage(hWndList, LB_GETTEXT, nIdx, (LPARAM)(LPSTR)szUser); + pUserName = strchr(szUser, '\t'); + if (!pUserName) + return 0; + + // NULL terminate name + *pUserName = 0; + + // Copy text to current cursor position + SendMessage(hWndEdit, EM_REPLACESEL, TRUE, (LPARAM)(LPSTR)szUser); + return 1; +} + +//**************************************************************************** +//**************************************************************************** +static BOOL IsUserSquelched(LPCSTR szName) { + PTSQUELCH_LIST pCurr; + + pCurr = sgpSquelchListHead; + while (pCurr) { + // Search for this name through tht squelch list + if (!strcmp(pCurr->szName, szName)) + return TRUE; + + pCurr = pCurr->next; + } + + // This guy is okay + return FALSE; +} + + +//**************************************************************************** +//**************************************************************************** +void ChannelWindowUpdate(void) { + char szText[256]; + char szFmt[64]; + int nUsers; + + // Update Channel description to include # of people in room + nUsers = SendMessage(GetDlgItem(ghWndChat, IDC_USERLIST), LB_GETCOUNT, 0, 0); + LoadString(global_hinstance, IDS_CHANNEL_FMT, szFmt, sizeof(szFmt)); + sprintf(szText, szFmt, gszCurrentChannel, nUsers); + SetWindowText(GetDlgItem(ghWndChat, IDC_STATIC_CHANNEL), szText); +} + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +UINT ChatGetUserFlags(void) { + return gnUserFlags; +} + + +//=========================================================================== +int NormalizeNetLag(DWORD dwMilliSec) { + // Assume if lag is <10millisecs, that we are dealing with the player himself + if (dwMilliSec < 10) + return 0; + + // divide millisec by 100 + dwMilliSec/=200; + + if (dwMilliSec >= MAX_NET_LAG) + return MAX_NET_LAG; + + // Best non-zero lag is a single green bar! + if (!dwMilliSec) + return 1; + + + return dwMilliSec; +} + + +//=========================================================================== +void DrawBadConnection(LPDRAWITEMSTRUCT lpdis) { + RECT srcRect; + + + // init source rect + SetRect(&srcRect, 0, 0, (LAG_UNIT_WIDTH*MAX_NET_LAG)-1, sizeBadConn.cy-1); + + // use this to center icon vertically + int vertOff = ((lpdis->rcItem.bottom - lpdis->rcItem.top + 1) - sizeBadConn.cy)/2; + + SDlgBltToWindow( + lpdis->hwndItem, + NULL, + lpdis->rcItem.right - (LAG_UNIT_WIDTH*(MAX_NET_LAG+1)), + lpdis->rcItem.top + vertOff, + bmpBadConn, + &srcRect, + &sizeBadConn); +} + + +//=========================================================================== +void DrawNetLag(int nNetLag, LPDRAWITEMSTRUCT lpdis) { + LPBYTE bmp; + SIZE size; + RECT srcRect; + + if (!nNetLag) + return; + + // Get netlag color + if (nNetLag >= RED_THRESHOLD) { + bmp = redlagbitmap; + size = redSize; + } + else if (nNetLag < YELLOW_THRESHOLD) { + bmp = greenlagbitmap; + size = greenSize; + } + else { + bmp = yellowlagbitmap; + size = yellowSize; + } + + // init source rect + srcRect.left = 0; + srcRect.right = LAG_UNIT_WIDTH*nNetLag - 1; + srcRect.top = 0; + srcRect.bottom = size.cy - 1; + + + // We'll use a rating of 1 to MAX_NET_LAG (MAX_NET_LAG being slowest) + int vertOff = ((lpdis->rcItem.bottom - lpdis->rcItem.top + 1) - size.cy)/2; + + + SDlgBltToWindow( + lpdis->hwndItem, + NULL, + lpdis->rcItem.right - (LAG_UNIT_WIDTH*(MAX_NET_LAG+1)), + lpdis->rcItem.top + vertOff, + bmp, + &srcRect, + &size); +} + + + +//**************************************************************************** +void ChatAddUser (SNADDUSERPTR pAddUserRec) { + HWND hWndList; + char szText[MAX_USERLIST_LEN]; + char szFmt[128]; + + if (!ghWndChat) + return; + + + hWndList = GetDlgItem(ghWndChat, IDC_USERLIST); + + // Make sure we haven't already added this person to the listbox + if (LB_ERR != ListFindName(hWndList, (LPCSTR)pAddUserRec->name)) + return; + + // Add squelched flag, if this user is squelched + if (IsUserSquelched(pAddUserRec->name)) + pAddUserRec->flags |= UF_SQUELCHED; + + sprintf(szText, "%s\t%d %d\t%s", + pAddUserRec->name, + pAddUserRec->flags, + 0, // Starting ping time + pAddUserRec->description); + + // Add player name to user list box (official users get added at the top of the list) + SendMessage( + hWndList, + (pAddUserRec->flags & USER_OFFICIAL_MASK) ? LB_INSERTSTRING : LB_ADDSTRING, + 0, + (LPARAM)(LPCSTR)szText); + + if (!sgbModeratedChannel && pAddUserRec->notifyuser && sgdwVerboseMode) { + // display "Johnny has entered" + LoadString(global_hinstance, IDS_CHAT_PLAYER_ENTERED_ROOM, szFmt, sizeof(szFmt)); + sprintf(szText, szFmt, eCOLOR_NOTIFY, pAddUserRec->name); + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, eCOLOR_NOTIFY, (LPARAM)szText); + } + + if (!strcmp(pAddUserRec->name, sgszUserName)) { + gnUserFlags = pAddUserRec->flags; + strcpy(sgszUserDesc, pAddUserRec->description); + } + + ChannelWindowUpdate(); + + // Update scrollbar that belongs to this listbox + ListUpdateScrollbar(hWndList); +} + +//**************************************************************************** +void ChatDeleteUser(SNDELETEUSERPTR pDeleteUserRec) { + HWND hWndList; + char szText[MAX_USERLIST_LEN]; + char szFmt[128]; + int nIndex; + int nTopIndex; + + + if (!ghWndChat) + return; + + // Remove player name from user list box + hWndList = GetDlgItem(ghWndChat, IDC_USERLIST); + nIndex = ListFindName(hWndList, (LPCSTR)pDeleteUserRec->name); + if (nIndex == LB_ERR) + return; + + // Delete the user from the list + nTopIndex = SendMessage(hWndList, LB_GETTOPINDEX, 0, 0); + SendMessage(hWndList, WM_SETREDRAW, FALSE, 0); + SendMessage(hWndList, LB_DELETESTRING, nIndex, 0); + SendMessage(hWndList, LB_SETTOPINDEX, nTopIndex, 0); // restore scroll position after LB_DELETESTRING + + SendMessage(hWndList, WM_SETREDRAW, TRUE, 0); + + if (!sgbModeratedChannel && pDeleteUserRec->notifyuser && sgdwVerboseMode) { + // display "Johnny has left" + LoadString(global_hinstance, IDS_CHAT_PLAYER_LEFT_ROOM, szFmt, sizeof(szFmt)); + sprintf(szText, szFmt, eCOLOR_NOTIFY, pDeleteUserRec->name); + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, eCOLOR_NOTIFY, (LPARAM)szText); + } + + // Update users in channel + ChannelWindowUpdate(); + + // Update scrollbar that belongs to this listbox + ListUpdateScrollbar(hWndList); +} + + +//**************************************************************************** +void ChatUpdatePingTime(SNUPDATEPINGTIMEPTR pUpdatePingTimeRec) { + HWND hWndList; + int nIndex, nCurSel, nTopIndex; + DWORD dwFlags, dwNewPingTime, dwOldPingTime; + + char szNewUserText[MAX_USERLIST_LEN]; + char szOldUserText[MAX_USERLIST_LEN]; + char *pszName; + char *pszInfo; + char *pszDesc; + + + if (!ghWndChat) + return; + + hWndList = GetDlgItem(ghWndChat, IDC_USERLIST); + nIndex = ListFindName(hWndList, (LPCSTR)pUpdatePingTimeRec->name); + if (nIndex == LB_ERR) + return; + + // Get current entry for this user + SendMessage(hWndList, LB_GETTEXT, nIndex, (LPARAM)(LPCSTR)szOldUserText); + + // Get pointer to user name + pszName = &szOldUserText[0]; + + // Get pointer to user info + pszInfo = strchr(szOldUserText, '\t'); + if (!pszInfo) + return; + *pszInfo++ = 0; // Null terminate name, and pointer to user info + + + // Get pointer to user description + pszDesc = strchr(pszInfo, '\t'); + if (!pszDesc) + return; + *pszDesc++ = 0; // Null terminate info and point to user description + + // Get old information about the player + if (2 != sscanf(pszInfo, "%d %d", &dwFlags, &dwOldPingTime)) + return; + + // Update new ping time + dwNewPingTime = NormalizeNetLag(pUpdatePingTimeRec->pingtime); + + // Check if ping time has changed + if (dwNewPingTime == dwOldPingTime) + return; + + // Now rebuild text string + sprintf(szNewUserText, "%s\t%d %d\t%s", + pszName, + dwFlags, + dwNewPingTime, + pszDesc); + + + // Save a couple of things for later + nTopIndex = SendMessage(hWndList, LB_GETTOPINDEX, 0, 0); + nCurSel = SendMessage(hWndList, LB_GETCURSEL, 0, 0); + + // Actually set the new user entry + SendMessage(hWndList, WM_SETREDRAW, FALSE, 0); + SendMessage(hWndList, LB_DELETESTRING, nIndex, 0); + SendMessage(hWndList, LB_INSERTSTRING, nIndex, (LPARAM)(LPCSTR)szNewUserText); + if (nCurSel == nIndex) + SendMessage(hWndList, LB_SETCURSEL, nCurSel, 0); + + // We need to restore the scrollbox position, since LB_DELETESTRING seems to scroll to the top. + SendMessage(hWndList, LB_SETTOPINDEX, nTopIndex, 0); + + SendMessage(hWndList, WM_SETREDRAW, TRUE, 0); + + // Update scrollbar that belongs to this listbox + ListUpdateScrollbar(hWndList); +} + + +//**************************************************************************** +void ChatSetUserName(LPCSTR szUserName) { + SrvGetLocalPlayerName(sgszUserName,MAX_NAME_LEN); +#if 0 + if (strlen(szUserName) >= sizeof(sgszUserName)) { + memcpy(sgszUserName, szUserName, sizeof(sgszUserName)); + sgszUserName[sizeof(sgszUserName)-1] = 0; + } + else + strcpy(sgszUserName, szUserName); +#endif +} + +//**************************************************************************** +void ChatChangeUserFlags(SNCHANGEUSERFLAGSPTR pChangeUserFlagsRec) { + HWND hWndList; + int nOldIndex, nNewIndex; + DWORD dwOldFlags, dwNewFlags, dwPingTime; + char szNewUserText[MAX_USERLIST_LEN]; + char szOldUserText[MAX_USERLIST_LEN]; + char *pszName; + char *pszInfo; + char *pszDesc; + BOOL bWasOfficial, bIsOfficial; + + + if (!ghWndChat) + return; + + hWndList = GetDlgItem(ghWndChat, IDC_USERLIST); + nOldIndex = ListFindName(hWndList, (LPCSTR)pChangeUserFlagsRec->name); + if (nOldIndex == LB_ERR) + return; + + // Get current entry for this user + SendMessage(hWndList, LB_GETTEXT, nOldIndex, (LPARAM)(LPCSTR)szOldUserText); + + // Get pointer to user name + pszName = &szOldUserText[0]; + + // Get pointer to user info + pszInfo = strchr(szOldUserText, '\t'); + if (!pszInfo) + return; + *pszInfo++ = 0; // Null terminate name, and pointer to user info + + + // Get pointer to user description + pszDesc = strchr(pszInfo, '\t'); + if (!pszDesc) + return; + *pszDesc++ = 0; // Null terminate info and point to user description + + // Get old information about the player + if (2 != sscanf(pszInfo, "%d %d", &dwOldFlags, &dwPingTime)) + return; + + // Check if flags have really changed + dwNewFlags = pChangeUserFlagsRec->flags; + if (IsUserSquelched(pChangeUserFlagsRec->name)) + dwNewFlags |= UF_SQUELCHED; + + if (dwNewFlags == dwOldFlags) + return; + + // Now rebuild text string + sprintf(szNewUserText, "%s\t%d %d\t%s", + pszName, + dwNewFlags, + dwPingTime, + pszDesc); + + // Save new user flags + if (!strcmp(pChangeUserFlagsRec->name, sgszUserName)) + gnUserFlags = dwNewFlags; + + bWasOfficial = (0 != (dwOldFlags & USER_OFFICIAL_MASK)); + bIsOfficial = (0 != (dwNewFlags & USER_OFFICIAL_MASK)); + + + // Actually set the new user entry + int nTopIndex = SendMessage(hWndList, LB_GETTOPINDEX, 0, 0); + int nCurSel = SendMessage(hWndList, LB_GETCURSEL, 0, 0); + SendMessage(hWndList, WM_SETREDRAW, FALSE, 0); + SendMessage(hWndList, LB_DELETESTRING, nOldIndex, 0); + + if (bWasOfficial == bIsOfficial) { + nNewIndex = SendMessage(hWndList, LB_INSERTSTRING, nOldIndex, (LPARAM)(LPCSTR)szNewUserText); + } + else { + // Move user to new position in list based on new flags + // (Special users get moved to the top, non-specials get moved to the bottom) + nNewIndex = SendMessage( + hWndList, + (bIsOfficial) ? LB_INSERTSTRING : LB_ADDSTRING, + 0, + (LPARAM)(LPCSTR)szNewUserText); + } + + + // LB_DELETESTRING moves the scroll position, so reset it to where it was + SendMessage(hWndList, LB_SETTOPINDEX, nTopIndex, 0); + if (nCurSel == nOldIndex) + SendMessage(hWndList, LB_SETCURSEL, nNewIndex, 0); + + SendMessage(hWndList, WM_SETREDRAW, TRUE, 0); + + // Update scrollbar that belongs to this listbox + ListUpdateScrollbar(hWndList); +} + +//**************************************************************************** +// NOTE: pJoinChannelRec will only be valid as long as we don't go into a peekmessage loop. +//**************************************************************************** +void ChatJoinChannel(SNJOINCHANNELPTR pJoinChannelRec) { + HWND hWndList; + char szText[MAX_CHAT_LEN]; + char szFmt[128]; + + // if this is the first channel we are entering, add this channel to our list of known channels + if (sgbFirstChannel) { + ChatAddChannel(pJoinChannelRec->name); + sgbFirstChannel = FALSE; + } + + // Save channel name + strcpy(gszCurrentChannel,pJoinChannelRec->name); + sgbModeratedChannel = pJoinChannelRec->flags & CF_MODERATED; + + if (ghWndChat) { + // Let select channel window know, in case user is waiting for confirmation + ChatChannelJoined(pJoinChannelRec->name); + + hWndList = GetDlgItem(ghWndChat, IDC_USERLIST); + + // Dump all users from list and prepare to add the new ones. + SendMessage(hWndList, LB_RESETCONTENT, 0, 0); + + // Display a message that we are in a new room now + LoadString(global_hinstance, IDS_CHAT_JOIN_ROOM, szFmt, sizeof(szFmt)); + sprintf(szText, szFmt, eCOLOR_NOTIFY, pJoinChannelRec->name); + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, eCOLOR_NOTIFY, (LPARAM)szText); + + // Update scrollbar that belongs to this listbox + ListUpdateScrollbar(hWndList); + + // Set button text to display new channel name + ChannelWindowUpdate(); + } + +} + + +//**************************************************************************** +void ChatAddChannel(LPCSTR szChannel) { + TCHANNEL_LIST ChannelList; + TCHANNEL_LIST *pCurr; + + strcpy(ChannelList.szChannel, szChannel); + + pCurr = sgpChannelListHead; + while (pCurr) { + // If this string already exists in our list, don't bother adding it again + if (!strcmp(pCurr->szChannel, szChannel)) + return; + + pCurr = pCurr->next; + } + + LISTADDEND(&sgpChannelListHead, &ChannelList); + return; +} + +//**************************************************************************** +void ChatDeleteChannel(LPCSTR szChannel) { + TCHANNEL_LIST *pCurr; + + pCurr = sgpChannelListHead; + while (pCurr) { + // If this string already exists in our list, don't bother adding it again + if (!strcmp(pCurr->szChannel, szChannel)) { + LISTFREE(&sgpChannelListHead, pCurr); + return; + } + + pCurr = pCurr->next; + } + + return; +} + + +//**************************************************************************** +void ChatSquelchUser(SNSQUELCHUSERPTR pSquelchUserRec) { + TSQUELCH_LIST SquelchList; + TSQUELCH_LIST *pCurr; + SNCHANGEUSERFLAGSREC ChangeUserFlagsRec; + char szText[256]; + char szFmt[128]; + + strcpy(SquelchList.szName, pSquelchUserRec->name); + + pCurr = sgpSquelchListHead; + while (pCurr) { + // If this string already exists in our list, don't bother adding it again + if (!strcmp(pCurr->szName, pSquelchUserRec->name)) + return; + + pCurr = pCurr->next; + } + + LISTADDEND(&sgpSquelchListHead, &SquelchList); + + ChangeUserFlagsRec.name = pSquelchUserRec->name; + ChangeUserFlagsRec.flags = pSquelchUserRec->flags | UF_SQUELCHED; + ChatChangeUserFlags(&ChangeUserFlagsRec); + + // Display a message that user is being squelched + LoadString(global_hinstance, IDS_USERSQUELCHED_FMT, szFmt, sizeof(szFmt)); + sprintf(szText, szFmt, eCOLOR_NOTIFY, pSquelchUserRec->name); + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, eCOLOR_NOTIFY, (LPARAM)szText); + + return; +} + +//**************************************************************************** +void ChatUnsquelchUser(SNSQUELCHUSERPTR pSquelchUserRec) { + SNCHANGEUSERFLAGSREC ChangeUserFlagsRec; + TSQUELCH_LIST *pCurr; + char szText[256]; + char szFmt[128]; + + pCurr = sgpSquelchListHead; + while (pCurr) { + // If this user is currently squelched, remove him from squelch list + if (!strcmp(pCurr->szName, pSquelchUserRec->name)) { + LISTFREE(&sgpSquelchListHead, pCurr); + break; + } + + pCurr = pCurr->next; + } + + ChangeUserFlagsRec.name = pSquelchUserRec->name; + ChangeUserFlagsRec.flags = pSquelchUserRec->flags; + ChatChangeUserFlags(&ChangeUserFlagsRec); + + // Display a message that user is no longer being squelched + LoadString(global_hinstance, IDS_USERUNSQUELCHED_FMT, szFmt, sizeof(szFmt)); + sprintf(szText, szFmt, eCOLOR_NOTIFY, pSquelchUserRec->name); + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, eCOLOR_NOTIFY, (LPARAM)szText); + return; +} + + +//**************************************************************************** +void ChatReceiveMsg(SNDISPLAYSTRINGPTR pDispStringRec) { + BYTE szFromTo[16]; + BYTE szMsg[MAX_CHAT_LEN+3+sizeof(szFromTo)]; + BYTE bColorName, bColorString; + BYTE bShowName = TRUE; + + + // Init this to null string, its only used when whispering is occuring + szFromTo[0] = 0; + + // Set colors + switch (pDispStringRec->stringtype) { + case SN_STRING_WHISPER: + // Ignore squelched people + if (IsUserSquelched(pDispStringRec->sender)) + return; + + bColorName = eCOLOR_USERNAME; + bColorString = eCOLOR_WHISPER; + LoadString(global_hinstance, IDS_WHISPER_FROM, (char *)szFromTo, sizeof(szFromTo)); + break; + + case SN_STRING_WHISPERSENT: + bColorName = eCOLOR_MYNAME; + bColorString = eCOLOR_WHISPER; + LoadString(global_hinstance, IDS_WHISPER_TO, (char *)szFromTo, sizeof(szFromTo)); + break; + + + case SN_STRING_BROADCAST: + bColorString = eCOLOR_BROADCAST; + bShowName = FALSE; + break; + + case SN_STRING_INFORMATION: + bColorString = eCOLOR_INFORMATION; + bShowName = FALSE; + break; + + case SN_STRING_ERROR: + bColorString = eCOLOR_ERROR; + bShowName = FALSE; + break; + + case SN_STRING_TALK: + // Ignore squelched people + if (IsUserSquelched(pDispStringRec->sender)) + return; + + if (pDispStringRec->senderflags & UF_BLIZZARD) { + bColorName = eCOLOR_BLIZZARD; + bColorString = eCOLOR_BLIZZARD; + break; + } + else if (pDispStringRec->senderflags & UF_SYSOP) { + bColorName = eCOLOR_SYSOP; + bColorString = eCOLOR_SYSOP; + break; + } + else if (pDispStringRec->senderflags & UF_SPEAKER) { + bColorName = eCOLOR_SPEAKER; + bColorString = eCOLOR_SPEAKER; + break; + } + else if (pDispStringRec->senderflags & UF_MODERATOR) { + bColorName = eCOLOR_MODERATOR; + bColorString = eCOLOR_MODERATOR; + break; + } + // fall through + default: + bColorName = eCOLOR_USERNAME; + bColorString = eCOLOR_NORMAL; + break; + } + + + + // Format string with sender's name in front + if (bShowName && pDispStringRec->sender[0]) + BuildMsg((LPSTR)szMsg, + (LPCSTR) szFromTo, + pDispStringRec->sender, + pDispStringRec->string, + bColorName, bColorString); + else + sprintf((char *)szMsg, "%c%s", + bColorString, + pDispStringRec->string); + + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, bColorString, (LPARAM)szMsg); +} + + + +//=========================================================================== +BOOL CALLBACK ChatRoomDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + static UIPARAMSPTR uiparams = NULL; + static HWND hWndEdit; + + + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case ID_WHISPER: { + char szTitle[32]; + char szText[256]; + + // make sure we have selected a user to whisper to + if (LB_ERR == SendDlgItemMessage(window, IDC_USERLIST, LB_GETCURSEL, 0, 0)) { + + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + LoadString(global_hinstance, IDS_ERR_CANTWHISPER, szText, sizeof(szText)); + + // Don't let user press whisper while error message is up + EnableWindow((HWND)lparam, FALSE); + uiparams->interfacedata->messageboxcallback( + window, + szText, + szTitle, + MB_OK | MB_ICONERROR); + EnableWindow((HWND)lparam, TRUE); + + return 1; + } + } + // Fall through to IDOK + // + // + case IDOK: { + char szText[MAX_CHAT_LEN]; + + // Get message from edit control. Only send the chat message, if the edit control contained text. + if (SendMessage(hWndEdit, WM_GETTEXT, MAX_MSG_LEN, (LPARAM)(LPSTR)szText) ) { + SendChatMsg((char *)szText, (LOWORD(wparam) == ID_WHISPER)); + + // Clear edit text + SendMessage(hWndEdit, WM_SETTEXT, 0, (LPARAM) ((LPSTR)"")); + + // Local echo, unless we are whispering or user typed a command string + if (LOWORD(wparam) == IDOK && szText[0] != '/') { + char szMsg[MAX_CHAT_LEN+3]; // include space for "< >" around name + char szPlayerName[MAX_NAME_LEN]; + int nTextColor; + + SrvGetLocalPlayerName(szPlayerName,MAX_NAME_LEN); + nTextColor = (sgbModeratedChannel && !IsUserOfficial()) ? + eCOLOR_WHISPER : eCOLOR_NORMAL; + BuildMsg((char *)szMsg, + "", + szPlayerName, + (LPCSTR)szText, + eCOLOR_MYNAME, + nTextColor); + + SendMessage(ghWndChat, WM_CHAT_PROCESS_MSG, nTextColor, (LPARAM)szMsg); + } + + ScrollToBtm(sghWndMsgList); + } + + // Give focus back to edit control + SetFocus(hWndEdit); + return 1; + + } + + case ID_VERBOSE: + ToggleVerboseMode(); + return 1; + + + case ID_CHATCHANNEL: { + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + DoChatSelectChannel(uiparams->interfacedata, gszCurrentChannel, sgpChannelListHead); + SetFocus(hWndEdit); + return 1; + } + + case IDC_USERLIST: { + if (HIWORD(wparam) == LBN_SELCHANGE) { + // Give the focus back to the edit control + SetFocus(hWndEdit); + + ListUpdateScrollbar((HWND) lparam); + } + else if (HIWORD(wparam) == LBN_DBLCLK) { + CopyNameToEditCtl((HWND)lparam, hWndEdit); + SetFocus(hWndEdit); + } + break; + } + + + case IDC_CHATWINDOW: + SetFocus(hWndEdit); + return 0; + + case ID_CHATCREATE: { + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + if (DoCreateGame(uiparams)) + SDlgEndDialog(window,1); + else + SetFocus(hWndEdit); + return 1; + } + + case ID_CHATJOIN: + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + if (DoJoinGame(uiparams)) + SDlgEndDialog(window, 1); + else + SetFocus(hWndEdit); + return 1; + + case IDQUIT: + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + SDlgEndDialog(window, 0); + return 1; + + } + break; + + case WM_CLOSE: + // Simulate a Quit button click so that we exit + SendDlgItemMessage(window, IDQUIT, BM_CLICK, 0, 0); + return 1; + + case WM_HELP: +#if TEST_USERLIST + { + // Get Users coming and going constantly (whenever a key is pressed) + for (int i=0; i<5000; i++) { + static BOOL sbAdd=FALSE; + if (sbAdd) + AddDummyUser(); + else + DeleteDummyUser(); + sbAdd = !sbAdd; + } + return 1; + } +#endif + + + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + SDlgDialogBoxParam( global_hinstance, + TEXT("DIALOG_CHAT_HELP"), + window, + ChatHelpDialogProc, + (LPARAM) uiparams); + SetFocus(hWndEdit); + return 1; + + + case WM_DRAWITEM: { + UINT idCtl = (UINT) wparam; // control identifier + LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lparam; // item-drawing information + char szString[256]; + BOOL bFirstLine = TRUE; + int nNetLag = 0; + DWORD dwItemFlags = 0; + + if (idCtl == IDC_CHATWINDOW) { + COLORREF oldTextColor, oldBkColor; + LPSTR pText = szString; + UINT nAlignMode; + POINT pt; + int nStartX; + + + // Get line of text + if (LB_ERR == SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)(LPCSTR)szString)) + return 0; + + // make sure we have something to draw + if (!szString[0] || !lpdis->hDC) + return 0; + + + oldTextColor = SetTextColor(lpdis->hDC, RGB(0xff, 0xff, 0xff)); + oldBkColor = SetBkColor(lpdis->hDC, RGB(0,0,0)); + + // manually indent string, if necessary + nStartX = lpdis->rcItem.left + 1; // +1 is so letters like W will not get clipped on the left + if (pText[0] == '\t') { + nStartX += CHAT_INDENT; + pText++; + bFirstLine = FALSE; + } + MoveToEx( + lpdis->hDC, + nStartX, + lpdis->rcItem.top, + &pt); + + nAlignMode = SetTextAlign(lpdis->hDC, TA_UPDATECP); + + // Print Text + while (*pText) { + int nCount; + + // Check for color control character + if (*pText >= FIRST_COLOR_CHAR && *pText <= LAST_COLOR_CHAR) { + SetTextColor(lpdis->hDC, sgHiliteColors[*pText - FIRST_COLOR_CHAR]); + pText++; + } + + // Count characters that are in this color + char *p = pText; + for (nCount = 0; *p != 0; nCount++, *p++) { + if (*p >= FIRST_COLOR_CHAR && *p <= LAST_COLOR_CHAR) + break; + } + + // Draw characters + TextOut(lpdis->hDC,0,0,pText,nCount); + + // Skip characters that we've drawn + pText+=nCount; + } + + + // Restore colors to hdc + SetTextColor(lpdis->hDC, oldTextColor); + SetBkColor(lpdis->hDC, oldBkColor); + + // Restore align mode + SetTextAlign(lpdis->hDC, nAlignMode); + + // restore position also + MoveToEx(lpdis->hDC, pt.x, pt.y, NULL); + return 1; + } + else if (idCtl == IDC_USERLIST) { + char *szDesc = ""; + char *szPlayerData = ""; + char *p; + + // Get user name/description + if (LB_ERR == SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)(LPCSTR)szString)) + return 0; + + // Get player data + p = strchr(szString,'\t'); + if (p) { + *p++ = 0; + szPlayerData = p; + + // Get player description + p = strchr(szPlayerData,'\t'); + if (p) { + *p++ = 0; + szDesc = p; + } + } + + // make sure we have something to draw + if (!szString[0] || !lpdis->hDC) + return 0; + + // If item count changes, change if constant + if (2 != sscanf(szPlayerData, "%d %d", &dwItemFlags, &nNetLag)) { +// #ifndef NDEBUG +// char txt[256]; +// sprintf(txt, "Info: %s", szPlayerData); +// MessageBox(SDrawGetFrameWindow(), txt, "", MB_OK); +// return 0; +// #endif + } + + // IF THE APPLICATION HAS REGISTERED A DRAW DESCRIPTION CALLBACK, + // LET IT DRAW THE DESCRIPTION + if (uiparams->interfacedata && uiparams->interfacedata->drawdesccallback) { + DWORD dwDrawFlags; + + dwDrawFlags = SNET_DDF_INCLUDENAME; + uiparams->interfacedata->drawdesccallback( + PROVIDERID, + SNET_DRAWTYPE_PLAYER, + szString, + szDesc, + dwItemFlags, + dwDrawFlags, + 0, + lpdis); + } + else { + // OTHERWISE, DRAW THE USER'S NAME OURSELF + COLORREF oldTextColor, oldBkColor; + BOOL bSelected = lpdis->itemState & ODS_SELECTED; + + // Draw username and net lag into list box + // Don't worry about text highlighting + oldTextColor = SetTextColor(lpdis->hDC, RGB(0xff, 0xff, 0xff)); + oldBkColor = SetBkColor(lpdis->hDC, (bSelected) ? GetSysColor(COLOR_HIGHLIGHT) : RGB(0, 0, 0)); + ExtTextOut( + lpdis->hDC, + lpdis->rcItem.left, + lpdis->rcItem.top, + ETO_CLIPPED | ETO_OPAQUE, + &lpdis->rcItem, + szString, + strlen(szString), + NULL); + + // Restore colors to hdc + SetTextColor(lpdis->hDC, oldTextColor); + SetBkColor(lpdis->hDC, oldBkColor); + } + + // Draw net lag + if (!(dwItemFlags & UF_BADCONNECTION)) + DrawNetLag(nNetLag, lpdis); + else + DrawBadConnection(lpdis); + + return 1; + } + + break; + } + + case WM_CHAT_PROCESS_MSG: + DisplayMsg((LPCSTR)lparam, wparam); + return 1; + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + + case WM_DESTROY: + SrvEndChat(); + DestroyArtwork(window); + if (sghChatFont) + DeleteObject(sghChatFont); + + ghWndChat = sghWndMsgList = NULL; + hWndEdit = NULL; + LISTCLEAR(&sgpChannelListHead); + LISTCLEAR(&sgpSquelchListHead); + break; + + + case WM_INITDIALOG: + + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + + sgbLadderEnabled = uiparams->interfacedata->uiflags & + SNET_UIFLAG_SUPPORTS_LADDER ? TRUE : FALSE; + LoadArtwork(window, uiparams->interfacedata->artcallback); + + sghChatFont = SetChatFonts(window); + + // save some window handles for later + ghWndChat = window; + sghWndMsgList = GetDlgItem(window, IDC_CHATWINDOW); + hWndEdit = GetDlgItem(window, IDC_CHATEDIT); + + // Link Userlist scrollbar to UserList Listbox + ScrollbarLink(GetDlgItem(window, IDC_USERLIST), GetDlgItem(window, IDC_USERLIST_SCROLLBAR)); + + // Link Messagelist scrollbar to msglist listbox + ScrollbarLink(sghWndMsgList, GetDlgItem(window, IDC_MSGLIST_SCROLLBAR)); + + + SendMessage(hWndEdit, EM_LIMITTEXT, MAX_MSG_LEN-1, 0L); + SendMessage(sghWndMsgList, LB_SETTABSTOPS, 1, (LPARAM) (int *) &sgnTab); + + // Set the height of the chat text list box items (so we can fit more lines in it) + SendMessage(sghWndMsgList, LB_SETITEMHEIGHT, 0, 14); + + // Set hight of userlist box items (some systems get strange heights) + SendDlgItemMessage(window, IDC_USERLIST, LB_SETITEMHEIGHT, 0, 16); + + // Set flag for first time + sgbFirstChannel = TRUE; + + // Get the local user's name + SrvGetLocalPlayerName(sgszUserName,MAX_NAME_LEN); + + if (!SrvBeginChat(uiparams->programdata, uiparams->playerdata, gszCurrentChannel)) { + // Have parent window display error message. + PostMessage(GetParent(sghWndMsgList), WM_ERR_NOTRESPONDING, 0, 0); + SDlgEndDialog(window, 0); + } + + + // Don't let player with bad connection do anything (encourage them to + // change their ISP). + if (gbConnectionSucks) { + EnableWindow(GetDlgItem(window, ID_CHATCREATE), FALSE); + EnableWindow(GetDlgItem(window, ID_CHATJOIN), FALSE); + } + + // Hide 'verbose' button. It will still generate a WM_COMMAND + // if user hits Alt-V hotkey. + ShowWindow(GetDlgItem(window, ID_VERBOSE), SW_HIDE); + + // Set Verbose preference + SRegLoadValue(PREFSKEY,PREFSVALUE_VERBOSE,SREG_FLAG_BATTLENET,&sgdwVerboseMode); + + UiLoadCursors(window, uiparams->interfacedata); + +#if TEST_USERLIST + CreateDummyUsers(); +#endif + return 1; + } + + return SDlgDefDialogProc(window,message,wparam,lparam); + +} diff --git a/Storm/SOURCE/BATTLE/CLRPREF.CPP b/Storm/SOURCE/BATTLE/CLRPREF.CPP new file mode 100644 index 0000000..f672517 --- /dev/null +++ b/Storm/SOURCE/BATTLE/CLRPREF.CPP @@ -0,0 +1,115 @@ +/**************************************************************************** +* +* CLRPREF.CPP +* +* Handle app specific system color preferences. +* By Michael Morhaime +* +***/ + +#include "pch.h" + + +typedef struct _prefcolors { + int nElements; + INT *pElements; + COLORREF *pAppValues; + COLORREF *pWindowsValues; +} TPREFCOLORS; +static TPREFCOLORS sgPrefColors = { 0, NULL, NULL, NULL }; + + + +//=========================================================================== +//=========================================================================== +static void ColorPrefRestoreWindowsColors(void) { + if (!sgPrefColors.nElements) + return; + + SetSysColors(sgPrefColors.nElements, sgPrefColors.pElements, sgPrefColors.pWindowsValues); +} + +//=========================================================================== +static void ColorPrefSetAppColors(void) { + if (!sgPrefColors.nElements) + return; + + SetSysColors(sgPrefColors.nElements, sgPrefColors.pElements, sgPrefColors.pAppValues); +} + + +//=========================================================================== +//=========================================================================== +//=========================================================================== +void ColorPrefDestroy(void) { + // Restore Windows system colors + ColorPrefRestoreWindowsColors(); + + // Free PrefColors table + if (sgPrefColors.pElements) { + FREE(sgPrefColors.pElements); + sgPrefColors.pElements = NULL; + } + + if (sgPrefColors.pAppValues) { + FREE(sgPrefColors.pAppValues); + sgPrefColors.pAppValues = NULL; + } + + if (sgPrefColors.pWindowsValues) { + FREE(sgPrefColors.pWindowsValues); + sgPrefColors.pWindowsValues = NULL; + } + + sgPrefColors.nElements = 0; +} + + +//=========================================================================== +BOOL ColorPrefInit(SNETGETDATAPROC getdatacallback) { + SNET_DATA_SYSCOLORTABLE *pSysColorTbl; + DWORD dwBytes; + int nEntries; + + if (!UiGetData(getdatacallback, SNET_DATA_SYSCOLORS, (LPBYTE *)&pSysColorTbl, &dwBytes)) + return 0; + + nEntries = dwBytes/sizeof(SNET_DATA_SYSCOLORTABLE); + if (!nEntries) + return 0; + + sgPrefColors.pElements = (INT *)ALLOC(nEntries*sizeof(int)); + sgPrefColors.pAppValues = (COLORREF *)ALLOC(nEntries*sizeof(COLORREF)); + sgPrefColors.pWindowsValues = (COLORREF *)ALLOC(nEntries*sizeof(COLORREF)); + + if ( sgPrefColors.pElements == NULL || + sgPrefColors.pAppValues == NULL || + sgPrefColors.pWindowsValues == NULL ) { + ColorPrefDestroy(); + FREE(pSysColorTbl); + return 0; + } + + // Fill in structure with actual values. + sgPrefColors.nElements = nEntries; + for (int i=0; i + +// these values depend on the artwork +#define BEVEL_THICKNESS 3 + +#define PROP_COMBOLBOX "ComboLbox" +#define PROP_COMBOEDIT "ComboEdit" +#define PROP_COMBOEDITBKG "ComboEditBkg" +#define PROP_COMBOARROWRCT "ComboArrowRct" +#define PROP_LBOXSCROLL "LboxScroll" +#define PROP_OLDPROC "OldProc" + +#define CUSTOM_EN_SCROLLDOWN (WM_USER+2032) +#define CUSTOM_EN_SCROLLUP (WM_USER+2033) + +#define EDIT_ID 7173 +#define LBOX_ID 7174 +#define SCROLL_ID 7175 + +//---------------------------------------------------------------------------// +// PRIVATE +//---------------------------------------------------------------------------// + +enum { + LEFT = 0, + MIDDLE, + RIGHT, + NUM_TILES +}; + +typedef struct _COMBOBMP { + LPBYTE bitmap; + SIZE size; +} COMBOBMP, *COMBOBMPPTR; + +// Allow more than one combobox to share artwork +static int sgnComboCnt = 0; +static LPBYTE sgComboBmp[3]; +static SIZE sgComboSize[3]; +static LPBYTE sgSComboBmp[3]; +static SIZE sgSComboSize[3]; +static BOOL sgbPopup = FALSE; + +//---------------------------------------------------------------------------// +static BOOL ClosePopup(HWND window) { + if (!sgbPopup) return FALSE; + sgbPopup = FALSE; + + HWND hLbox = (HWND)GetProp(window,PROP_COMBOLBOX); + RECT comboRect,lboxRect; + GetWindowRect(window,&comboRect); + GetWindowRect(hLbox,&lboxRect); + + ShowWindow(hLbox,SW_HIDE); + ShowWindow((HWND)GetProp(window,PROP_LBOXSCROLL),SW_HIDE); + + SetWindowPos(window, + 0, + 0, + 0, + comboRect.right - comboRect.left, + comboRect.bottom - comboRect.top - + (lboxRect.bottom - lboxRect.top + BEVEL_THICKNESS*2), + SWP_NOZORDER|SWP_NOMOVE); + + SendMessage(GetParent(window), + WM_COMMAND, + MAKEWPARAM(GetWindowLong(window,GWL_ID), + CBN_SELCHANGE), + (LPARAM)window); + return TRUE; +} + +//---------------------------------------------------------------------------// +static BOOL OpenPopup(HWND window) { + if (sgbPopup) return FALSE; + sgbPopup = TRUE; + + HWND hLbox = (HWND)GetProp(window,PROP_COMBOLBOX); + RECT comboRect,lboxRect; + GetWindowRect(window,&comboRect); + GetWindowRect(hLbox,&lboxRect); + + SetWindowPos(window, + HWND_TOP, + 0, + 0, + comboRect.right - comboRect.left, + comboRect.bottom - comboRect.top + + (lboxRect.bottom - lboxRect.top + BEVEL_THICKNESS*2), + SWP_NOMOVE); + + ShowWindow(hLbox,SW_SHOWNORMAL); + ShowWindow((HWND)GetProp(window,PROP_LBOXSCROLL),SW_SHOWNORMAL); + + SetFocus(hLbox); + SetCapture(hLbox); + return TRUE; +} + +//---------------------------------------------------------------------------// +static LRESULT CALLBACK ComboEditWndProc(HWND hEdit, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + WNDPROC oldProc = (WNDPROC)GetProp(hEdit,PROP_OLDPROC); + if (message == WM_KEYDOWN) { + HWND hCombo = GetParent(hEdit); + if (wparam == VK_UP) { + SendMessage(hCombo, + WM_COMMAND, + MAKEWPARAM(EDIT_ID,CUSTOM_EN_SCROLLUP), + (LPARAM)hEdit); + return 0; + } + else if (wparam == VK_DOWN) { + SendMessage(hCombo, + WM_COMMAND, + MAKEWPARAM(EDIT_ID,CUSTOM_EN_SCROLLDOWN), + (LPARAM)hEdit); + return 0; + } + } + return CallWindowProc(oldProc,hEdit,message,wparam,lparam); +} + +//---------------------------------------------------------------------------// +static LRESULT CALLBACK ComboLboxWndProc(HWND hLbox, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + static bool bInScroll = FALSE; + WNDPROC oldProc = (WNDPROC)GetProp(hLbox,PROP_OLDPROC); + switch (message) { + case WM_SHOWWINDOW: + bInScroll = FALSE; + break; + + case WM_LBUTTONDOWN: { + RECT lboxRect,scrollRect; + HWND hScroll = (HWND)GetProp(GetParent(hLbox),PROP_LBOXSCROLL); + + GetClientRect(hLbox,&lboxRect); + GetClientRect(hScroll,&scrollRect); + scrollRect.left += lboxRect.right; + scrollRect.right += lboxRect.right; + + POINT pt = { (short)LOWORD(lparam), (short)HIWORD(lparam) }; + if (PtInRect(&scrollRect,pt)) { + LPARAM newlparam = MAKELPARAM(pt.x - lboxRect.right, + pt.y - lboxRect.top); + return SendMessage(hScroll,message,wparam,newlparam); + } + if (!PtInRect(&lboxRect,pt)) { + ReleaseCapture(); + ClosePopup(GetParent(hLbox)); + return 0; + } + break; + } + + case WM_LBUTTONUP: { + LRESULT result = CallWindowProc(oldProc, + hLbox, + message, + wparam, + lparam); + ReleaseCapture(); + ClosePopup(GetParent(hLbox)); + return result; + } + + case WM_KILLFOCUS: + bInScroll = FALSE; + ReleaseCapture(); + ClosePopup(GetParent(hLbox)); + return 0; + } + return CallWindowProc(oldProc,hLbox,message,wparam,lparam); +} + +//---------------------------------------------------------------------------// +static void UpdateSelection(HWND hLbox, HWND hEdit) { + int idx = SendMessage(hLbox,LB_GETCURSEL,0,0); + if (idx == LB_ERR) return; + TCHAR szBuf[256]; + SendMessage(hLbox,LB_GETTEXT,(WPARAM)idx,(LPARAM)szBuf); + SendMessage(hEdit,WM_SETTEXT,0,(LPARAM)szBuf); + if (!(GetWindowLong(GetParent(hLbox),GWL_STYLE) & CBS_DROPDOWNLIST)) + SendMessage(hEdit,EM_SETSEL,0,(LPARAM)-1); + ListUpdateScrollbar(hLbox); +} + +//---------------------------------------------------------------------------// +static BOOL ComboCreate(HWND window) { + RECT comboRect,dlgRect,comboRelRect; + LPBYTE pBmp[3]; + LPSIZE pSize[3]; + int editHgt; + BOOL bUp = TRUE; + + GetWindowRect(GetParent(window),&dlgRect); + GetWindowRect(window,&comboRect); + GetClientRect(window,&comboRelRect); + + // + // Reposition the combo to its full size. We'll hide the popup + // (bottom) later. + // + + editHgt = comboRelRect.bottom - BEVEL_THICKNESS*2; + if (comboRect.top + sgComboSize[0].cy > GetSystemMetrics(SM_CYSCREEN)) { + // use short popup + comboRelRect.bottom = sgSComboSize[0].cy; + for (int i = 0; i < 3; ++i) { + pBmp[i] = sgSComboBmp[i]; + pSize[i] = &sgSComboSize[i]; + } + } + else { + comboRelRect.bottom = sgComboSize[0].cy; + for (int i = 0; i < 3; ++i) { + pBmp[i] = sgComboBmp[i]; + pSize[i] = &sgComboSize[i]; + } + } + + int mod; + if (0 != (mod = comboRelRect.right % pSize[0]->cx)) + comboRelRect.right += pSize[0]->cx - mod; + + SetWindowPos(window, + NULL, // z-order + 0, // x position + 0, // y position + comboRelRect.right, // width + comboRelRect.bottom, // height + SWP_NOMOVE|SWP_NOZORDER); + + // + // Create the backgrounds for the combo box. + // + + COMBOBMPPTR pComboBmp = (COMBOBMPPTR)ALLOC(sizeof(COMBOBMP)); + pComboBmp->size.cx = comboRelRect.right; + pComboBmp->size.cy = comboRelRect.bottom; + pComboBmp->bitmap = (LPBYTE)ALLOC(comboRelRect.right*comboRelRect.bottom); + SetProp(window,PROP_COMBOEDITBKG,(HANDLE)pComboBmp); + + // + // Draw left + SBltROP3(pComboBmp->bitmap, + pBmp[0], + pSize[0]->cx, + pSize[0]->cy, + pComboBmp->size.cx, + pSize[0]->cx, + NULL, + SRCCOPY); + + // + // Draw middle + for (int tile = comboRelRect.right/pSize[1]->cx - 2, + xoffset = pSize[1]->cx; + tile; + --tile, xoffset += pSize[1]->cx) + { + SBltROP3(pComboBmp->bitmap + xoffset, + pBmp[1], + pSize[1]->cx, + pSize[1]->cy, + pComboBmp->size.cx, + pSize[1]->cx, + NULL, + SRCCOPY); + } + + // + // Draw right + SBltROP3(pComboBmp->bitmap + xoffset, + pBmp[2], + pSize[2]->cx, + pSize[2]->cy, + pComboBmp->size.cx, + pSize[2]->cx, + NULL, + SRCCOPY); + + // + // Set as control background + SDlgSetBitmap(window, + GetParent(window), + TEXT("ComboBox"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + pComboBmp->bitmap, + NULL, + pComboBmp->size.cx, + pComboBmp->size.cy); + + SetWindowPos(window, + 0,0,0, // z,x,y + comboRelRect.right, + editHgt + BEVEL_THICKNESS*2, + SWP_NOMOVE|SWP_NOZORDER); + + // + // Create the edit box control + HWND hEdit = CreateWindow(GetWindowLong(window,GWL_STYLE) & + CBS_DROPDOWNLIST ? + TEXT("STATIC") : TEXT("EDIT"), + NULL, + WS_CHILD | WS_VISIBLE | WS_TABSTOP, + BEVEL_THICKNESS, + BEVEL_THICKNESS, + comboRelRect.right - pSize[2]->cx - + BEVEL_THICKNESS, + editHgt, + window, + (HMENU)EDIT_ID, + global_hinstance, + NULL); + + // Replace the wndproc so we can receive the arrow key msgs + WNDPROC oldProc = (WNDPROC)SetWindowLong(hEdit, + GWL_WNDPROC, + (LONG)ComboEditWndProc); + SetProp(hEdit,PROP_OLDPROC,(HANDLE)oldProc); + SetProp(window,PROP_COMBOEDIT,(HANDLE)hEdit); + + RECT lboxRect; + // pop DOWN + SetRect(&lboxRect, + comboRelRect.left + BEVEL_THICKNESS, + comboRelRect.top + editHgt + BEVEL_THICKNESS*2, + comboRelRect.right - BEVEL_THICKNESS - ScrollbarGetWidth(), + comboRelRect.bottom - BEVEL_THICKNESS); + + // + // Create the listbox + HWND hLbox = CreateWindowEx(0, + TEXT("LISTBOX"), + NULL, + WS_CHILD | WS_TABSTOP | + LBS_NOTIFY | WS_CLIPSIBLINGS | + LBS_NOINTEGRALHEIGHT, + lboxRect.left, + lboxRect.top, + lboxRect.right - lboxRect.left, + lboxRect.bottom - lboxRect.top, + window, + (HMENU)LBOX_ID, + global_hinstance, + NULL); + if (!hLbox) return FALSE; + SetProp(window,PROP_COMBOLBOX, (HANDLE)hLbox); + + // Replace the wndproc so we can receive the focus and capture msgs + oldProc = (WNDPROC)SetWindowLong(hLbox, + GWL_WNDPROC, + (LONG)ComboLboxWndProc); + SetProp(hLbox,PROP_OLDPROC,(HANDLE)oldProc); + + // + // Create the listbox scrollbar + HWND hScroll = CreateWindowEx(0, + TEXT("StormScrollbar"), + NULL, + WS_CHILD, + lboxRect.right, + lboxRect.top, + ScrollbarGetWidth(), + lboxRect.bottom - lboxRect.top, + window, + (HMENU)SCROLL_ID, + global_hinstance, + NULL); + if (!hScroll) return FALSE; + + // Link listbox scrollbar to combo listbox + ScrollbarLink(hLbox, hScroll); + SetProp(window,PROP_LBOXSCROLL,(HANDLE)hScroll); + + LPRECT pDropRect = (LPRECT)ALLOC(sizeof(RECT)); + SetRect(pDropRect, + (GetWindowLong(window,GWL_STYLE) & CBS_DROPDOWNLIST) ? + comboRelRect.left + BEVEL_THICKNESS : + comboRelRect.right - BEVEL_THICKNESS - ScrollbarGetWidth(), + comboRelRect.top + BEVEL_THICKNESS, + comboRelRect.right - BEVEL_THICKNESS, + comboRelRect.top + BEVEL_THICKNESS + editHgt); + SetProp(window,PROP_COMBOARROWRCT,(HANDLE)pDropRect); + + sgbPopup = FALSE; + return TRUE; +} + +//---------------------------------------------------------------------------// +static LRESULT CALLBACK StormComboWndProc(HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case EDIT_ID: + if (HIWORD(wparam) == EN_CHANGE) { + wparam = MAKEWPARAM(GetWindowLong(window,GWL_ID), + CBN_EDITCHANGE); + return SendMessage(GetParent(window), + message, + wparam, + (LPARAM)window); + } + else if (HIWORD(wparam) == CUSTOM_EN_SCROLLDOWN) { + HWND hLbox = (HWND)GetProp(window,PROP_COMBOLBOX); + int nSel = SendMessage(hLbox,LB_GETCURSEL,0,0); + if (nSel == LB_ERR) nSel = -1; + if (LB_ERR != SendMessage(hLbox, + LB_SETCURSEL, + (WPARAM)nSel + 1, + 0)) + { + UpdateSelection(hLbox, + (HWND)GetProp(window, + PROP_COMBOEDIT)); + } + return 0; + } + else if (HIWORD(wparam) == CUSTOM_EN_SCROLLUP) { + HWND hLbox = (HWND)GetProp(window,PROP_COMBOLBOX); + int nSel = SendMessage(hLbox,LB_GETCURSEL,0,0); + if (nSel == LB_ERR) nSel = 1; + if (nSel && LB_ERR != SendMessage(hLbox, + LB_SETCURSEL, + (WPARAM)nSel - 1, + 0)) + { + UpdateSelection(hLbox, + (HWND)GetProp(window, + PROP_COMBOEDIT)); + } + return 0; + } + break; + case LBOX_ID: + if (HIWORD(wparam) == LBN_SELCHANGE) { + UpdateSelection((HWND)lparam, + (HWND)GetProp(window,PROP_COMBOEDIT)); + return 0; + } + break; + } + break; + + case WM_CREATE: + if (!ComboCreate(window)) + return -1; + break; + + case WM_DESTROY: { + // free artwork + COMBOBMPPTR pBmp = + (COMBOBMPPTR)RemoveProp(window,PROP_COMBOEDITBKG); + + if (pBmp) { + if (pBmp->bitmap) FREE(pBmp->bitmap); + FREE(pBmp); + } + + RemoveProp(window,PROP_COMBOEDIT); + LPRECT pRect = (LPRECT)RemoveProp(window,PROP_COMBOARROWRCT); + if (pRect) FREE(pRect); + break; + } + + case WM_PAINT: { + PAINTSTRUCT ps; + HDC dc = BeginPaint(window,&ps); + + // PAINT THE BITMAP(S) + SDlgDrawBitmap(window,SDLG_USAGE_BACKGROUND,(HRGN)0); + EndPaint(window,&ps); + return 0; + } + + case WM_SETFOCUS: + SetFocus((HWND)GetProp(window,PROP_COMBOEDIT)); + return 0; + + case WM_LBUTTONDOWN: + SetCapture(window); + return 0; + + case WM_LBUTTONUP: { + if (window != GetCapture()) break; + ReleaseCapture(); + + if (ClosePopup(window)) return 0; + + HWND hLbox = (HWND)GetProp(window,PROP_COMBOLBOX); + POINT pt = { (short)LOWORD(lparam), (short)HIWORD(lparam) }; + if (PtInRect((LPRECT)GetProp(window,PROP_COMBOARROWRCT),pt)) + OpenPopup(window); + return 0; + } + + case WM_SETFONT: + SendMessage((HWND)GetProp(window,PROP_COMBOEDIT), + message, + wparam, + lparam); + SendMessage((HWND)GetProp(window,PROP_COMBOLBOX), + message, + wparam, + lparam); + break; + + case WM_CTLCOLORSTATIC: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLOREDIT: + SetTextColor((HDC)wparam,0xFFFFFF); + SetBkColor((HDC)wparam,0); + SetBkMode((HDC)wparam,OPAQUE); + return (BOOL)GetStockObject(BLACK_BRUSH); + + case CB_ADDSTRING: { + HWND hLbox = (HWND)GetProp(window,PROP_COMBOLBOX); + LRESULT result = SendMessage(hLbox,LB_ADDSTRING,wparam,lparam); + ListUpdateScrollbar(hLbox); + ShowWindow((HWND)GetProp(window,PROP_LBOXSCROLL),SW_HIDE); + return result; + } + case WM_SETTEXT: { + HWND hEdit = (HWND)GetProp(window,PROP_COMBOEDIT); + if (TRUE == SendMessage(hEdit,message,wparam,lparam)) { + if (GetWindowLong(window,GWL_STYLE) & CBS_DROPDOWNLIST) + return TRUE; + SendMessage(hEdit, + EM_SETSEL, + 0, + (LPARAM)_tcslen((LPCTSTR)lparam)); + return TRUE; + } + return CB_ERRSPACE; + } + case WM_GETTEXT: + case WM_GETTEXTLENGTH: + return SendMessage((HWND)GetProp(window,PROP_COMBOEDIT), + message, + wparam, + lparam); + case CB_GETCOUNT: + return SendMessage((HWND)GetProp(window,PROP_COMBOLBOX), + LB_GETCOUNT, + wparam, + lparam); + case CB_GETCURSEL: + return SendMessage((HWND)GetProp(window,PROP_COMBOLBOX), + LB_GETCURSEL, + wparam, + lparam); + case CB_GETITEMDATA: + return SendMessage((HWND)GetProp(window,PROP_COMBOLBOX), + LB_GETITEMDATA, + wparam, + lparam); + case CB_GETLBTEXT: + return SendMessage((HWND)GetProp(window,PROP_COMBOLBOX), + LB_GETTEXT, + wparam, + lparam); + case CB_LIMITTEXT: + message = EM_LIMITTEXT; + return SendMessage((HWND)GetProp(window,PROP_COMBOEDIT), + message, + wparam, + lparam); + case CB_SETCURSEL: { + HWND hLbox = (HWND)GetProp(window,PROP_COMBOLBOX); + SendMessage(hLbox,LB_SETCURSEL,wparam,lparam); + UpdateSelection(hLbox,(HWND)GetProp(window,PROP_COMBOEDIT)); + return (LRESULT)wparam; + } + case CB_SETEDITSEL: + message = EM_SETSEL; + return SendMessage((HWND)GetProp(window,PROP_COMBOEDIT), + message, + wparam, + lparam); + case CB_SETITEMDATA: + return SendMessage((HWND)GetProp(window,PROP_COMBOLBOX), + LB_SETITEMDATA, + wparam, + lparam); + case CB_RESETCONTENT: + return SendMessage((HWND)GetProp(window,PROP_COMBOLBOX), + LB_RESETCONTENT, + wparam, + lparam); + } + return DefWindowProc(window,message,wparam,lparam); +} + +//---------------------------------------------------------------------------// +// EXPORTED FUNCTIONS +//---------------------------------------------------------------------------// + +//---------------------------------------------------------------------------// +void ComboboxLoadArtwork(SNETGETARTPROC artcallback) { + if (!sgnComboCnt++) { + + static int COMBO_ARTID[3] = { + SNET_ART_COMBOLEFT, + SNET_ART_COMBOMIDDLE, + SNET_ART_COMBORIGHT + }; + static int SCOMBO_ARTID[3] = { + SNET_ART_SCOMBOLEFT, + SNET_ART_SCOMBOMIDDLE, + SNET_ART_SCOMBORIGHT + }; + + for (int pos = LEFT; pos < NUM_TILES; ++pos) { + UiLoadArtwork( + artcallback, + NULL, + NULL, + COMBO_ARTID[pos], + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgComboBmp[pos], + &sgComboSize[pos]); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SCOMBO_ARTID[pos], + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgSComboBmp[pos], + &sgSComboSize[pos]); + } + + } +} + +//---------------------------------------------------------------------------// +void ComboboxDestroyArtwork(void) { + // Only Destroy if this if the only combobox currently using the artwork + if (!--sgnComboCnt) { + for (int pos = LEFT; pos < NUM_TILES; ++pos) { + if (sgComboBmp[pos]) { + FREE(sgComboBmp[pos]); + sgComboBmp[pos] = NULL; + } + if (sgSComboBmp[pos]) { + FREE(sgSComboBmp[pos]); + sgSComboBmp[pos] = NULL; + } + } + } +} + +//---------------------------------------------------------------------------// +void ComboRegisterClass (void) { + WNDCLASS wndclass; + ZeroMemory(&wndclass,sizeof(WNDCLASS)); + wndclass.style = CS_GLOBALCLASS; + wndclass.lpfnWndProc = StormComboWndProc; + wndclass.hInstance = global_hinstance; + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.lpszClassName = "StormCombobox"; + RegisterClass(&wndclass); +} + +//---------------------------------------------------------------------------// +void ComboUnregisterClass (void) { + UnregisterClass("StormCombobox", global_hinstance); +} diff --git a/Storm/SOURCE/BATTLE/CONNECT.CPP b/Storm/SOURCE/BATTLE/CONNECT.CPP new file mode 100644 index 0000000..d9c4bfe --- /dev/null +++ b/Storm/SOURCE/BATTLE/CONNECT.CPP @@ -0,0 +1,421 @@ +/**************************************************************************** +* +* connect.CPP +* battle.net +* +* By Michael Morhaime +* +***/ + +#include "pch.h" + +#define PREVENT_MINIMIZE 0 // 0 in final + +//**************************************************************************** +//**************************************************************************** +#define MILLISEC_PER_SEC 1000 + +#define LOGO_TIMER_ID 1 +#define MAX_FRAMES 32 + + + +static HTRANS sgTransHandles[MAX_FRAMES]; +static int sgFrame; + +static LPBYTE sgBackgroundBmp = NULL; +static LPBYTE sgButtonBmp = NULL; +static LPBYTE sgLogoBmp = NULL; +static SIZE sgLogoBmpSize; + +static BOOL sgbPreventMinimize = FALSE; +static HWND sgRudeWindow = NULL; +static HWND sgRudeWindowParent = NULL; + +extern void UiHideConnectCancel(void); +extern BOOL UiProcessWindowMessages(void); +extern HWND ghWndUiMainParent; + + + +//**************************************************************************** +//**************************************************************************** +BOOL LogoSetTimer(HWND window, int nTimer, SNETGETDATAPROC getdatacallback) { + LPBYTE pData; + DWORD dwSize; + + if (UiGetData(getdatacallback, SNET_DATA_BATTLE_LOGODELAY, &pData, &dwSize)) { + if (dwSize == sizeof(DWORD)) { + DWORD dwDelay; + int nResult; + + dwDelay = *((DWORD *)pData); + nResult = SDlgSetTimer(window, nTimer, dwDelay, NULL); + FREE(pData); + return (nResult != NULL); + } + } + + return 0; +} + +//**************************************************************************** +//**************************************************************************** +void LogoAnimate(HWND window, HWND child) { + RECT rect; + + TPBMP tpBmp = (TPBMP) GetWindowLong(child, GWL_USERDATA); + + if (! child) return; + if (! tpBmp) return; + if (! sgLogoBmp) return; + if (! sgTransHandles[0]) return; + + + sgFrame++; + if ((! sgTransHandles[sgFrame]) || (sgFrame >= MAX_FRAMES)) + sgFrame = 0; + + + GetWindowRect(child, &rect); + ScreenToClient(window, (LPPOINT)&rect.left); + ScreenToClient(window, (LPPOINT)&rect.right); + + // Copy from Background bitmap to buffer for animating logo + SBltROP3 ( + sgLogoBmp, + tpBmp->data + (rect.top * tpBmp->datasize.cx) + rect.left, + sgLogoBmpSize.cx, + sgLogoBmpSize.cy, + sgLogoBmpSize.cx, + tpBmp->datasize.cx, + NULL, + SRCCOPY + ); + + STransBlt(sgLogoBmp, 0, 0, sgLogoBmpSize.cx, sgTransHandles[sgFrame]); + + InvalidateRect(child, NULL, FALSE); +} + + +//**************************************************************************** +//**************************************************************************** +void LogoFramesDestroy(void) { + for (int index = 0; index < MAX_FRAMES; index++) { + if (sgTransHandles[index]) { + STransDelete(sgTransHandles[index]); + sgTransHandles[index] = NULL; + } + } + + if (sgLogoBmp) { + FREE(sgLogoBmp); + sgLogoBmp = NULL; + } +} + + +//**************************************************************************** +//**************************************************************************** +BOOL LogoInit(HWND child, SNETGETARTPROC artcallback) { + RECT rect; + LPBYTE srcframes; + SIZE srcsize; + + GetClientRect(child, &rect); + sgLogoBmpSize.cx = rect.right; + sgLogoBmpSize.cy = rect.bottom; + + // Get logo animation + if (!UiLoadArtwork(artcallback, + NULL, + NULL, // don't register the artwork + SNET_ART_APP_LOGO_SML, + 0, + 0, + 0, + FALSE, + FALSE, + &srcframes, + &srcsize)) { + ShowWindow(child,SW_HIDE); + sgLogoBmp = NULL; + return FALSE; + } + + memset(sgTransHandles, 0, sizeof(sgTransHandles)); + if (srcframes && sgLogoBmpSize.cy) { + int frames = srcsize.cy / sgLogoBmpSize.cy; + if (frames > MAX_FRAMES) + frames = MAX_FRAMES; + // create an HTRANS for each frame in the animation + for (int index = 0; index < frames; index++) { + + rect.left = 0; + rect.right = sgLogoBmpSize.cx - 1; + rect.top = index * sgLogoBmpSize.cy; + rect.bottom = rect.top + sgLogoBmpSize.cy - 1; + + STransCreate( + srcframes, + sgLogoBmpSize.cx, + sgLogoBmpSize.cy, + 8, + &rect, + PALETTEINDEX(250), + &sgTransHandles[index] + ); + } + + FREE(srcframes); + } + sgFrame = 0; + + sgLogoBmp = (LPBYTE) ALLOC(rect.right * rect.bottom); + if (!sgLogoBmp) + return FALSE; + + SDlgSetBitmap( + child, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + sgLogoBmp, + NULL, + rect.right, + rect.bottom + ); + return TRUE; +} + + +//=========================================================================== +static void DestroyArtwork (HWND window) { + TPBMP tpBmp = (TPBMP) GetWindowLong(GetDlgItem(window, IDC_LOGO_ANIMATE), GWL_USERDATA); + + // tpBmp->data points to a sgBAckgroundBmp, which will be freed below + if (tpBmp) + FREE(tpBmp); + + if (sgBackgroundBmp) { + FREE(sgBackgroundBmp); + sgBackgroundBmp = NULL; + } + + if (sgButtonBmp) { + FREE(sgButtonBmp); + sgButtonBmp = NULL; + } + + LogoFramesDestroy(); +} + +//=========================================================================== +static BOOL LoadArtwork (HWND window, SNETGETARTPROC artcallback) { + int btn_ids[] = { + IDCANCEL, + 0 + }; + + int btn_static[] = { + IDC_STATIC_TEXT, + 0 + }; + + SIZE sizeBtns; + SIZE bgSize; + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_BATTLE_CONNECT_BKG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + TRUE, // Use palette from this art + TRUE, // Prep palette for a fade + &sgBackgroundBmp, + &bgSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BUTTON_SML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgButtonBmp, + &sizeBtns); + + SDlgSetControlBitmaps (window, btn_ids, NULL, sgButtonBmp, &sizeBtns, SDLG_ADJUST_VERTICAL); + SDlgSetControlBitmaps (window, btn_static, NULL, sgBackgroundBmp, &bgSize, SDLG_ADJUST_CONTROLPOS); + + + // set up a TPBMP for the logo window, it will have information about the background bitmap + HWND hWndLogo = GetDlgItem(window, IDC_LOGO_ANIMATE); + + if (hWndLogo && sgBackgroundBmp) { + TPBMP tpBmp = (TPBMP) ALLOC(sizeof(TBMP)); + SetWindowLong(hWndLogo, GWL_USERDATA, (LONG) tpBmp); + if (tpBmp) { + tpBmp->data = sgBackgroundBmp; + tpBmp->datasize = bgSize; + } + + // set up the animating diablo logo + LogoInit(hWndLogo,artcallback); + LogoAnimate(window, hWndLogo); + } + + return 1; +} + + +//**************************************************************************** +//**************************************************************************** +void ProtectMinimize(BOOL bEnable) { +#if PREVENT_MINIMIZE + static sOldStyle; + + // Protect this code + if (sgbPreventMinimize == bEnable) + return; + + sgbPreventMinimize = bEnable; + + HWND hWndFrame = SDrawGetFrameWindow(); + + if (bEnable) { + sgRudeWindow = NULL; + sgRudeWindowParent = NULL; + + sOldStyle = GetWindowLong(hWndFrame,GWL_EXSTYLE); + SetWindowLong(hWndFrame, GWL_EXSTYLE, sOldStyle & ~WS_EX_TOPMOST); + } + else if (sgRudeWindow) { + if (IsWindow(sgRudeWindow) && IsWindow(sgRudeWindowParent)) + SetParent(sgRudeWindow, sgRudeWindowParent); + + sgRudeWindow = NULL; + sgRudeWindowParent = NULL; + + SetWindowLong(hWndFrame, GWL_EXSTYLE, sOldStyle); + + // Give our application back the focus + SetForegroundWindow(GetActiveWindow()); + } +#else + + sgbPreventMinimize = bEnable; + if (!bEnable) + UiRestoreApp(); + +#endif +} + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + + + +//=========================================================================== +BOOL CALLBACK ConnectDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + static UIPARAMSPTR uiparams; + static HWND shWndCancelDlg; + + switch (message) { + case WM_TIMER: + if (wparam == LOGO_TIMER_ID) { + LogoAnimate(window, GetDlgItem(window, IDC_LOGO_ANIMATE)); + } + return 1; + +#if PREVENT_MINIMIZE + case WM_NCACTIVATE: + if (!sgbPreventMinimize) + break; + + if (wparam == FALSE) { + PostMessage(window, WM_USER+100, 0, 0); + + SetWindowLong(window, DWL_MSGRESULT, 0); // This means don't minimize this window + return 1; + } + break; + + case WM_USER+100: + // Make new window our child so it will draw on the directX surface + if (GetForegroundWindow() != GetActiveWindow()) { + sgRudeWindow = GetForegroundWindow(); + sgRudeWindowParent = GetParent(sgRudeWindow); + SetParent(sgRudeWindow, window); + + // Hide Connect Dialog. Dialup networking will provide its own. + UiHideConnectCancel(); + } + return 1; +#endif + + case WM_NOTIFICATION_WAITING: + UiNotification(); + return 1; + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + case WM_DESTROY: + ghWndUiMainParent = NULL; + + UiVidFadeOut(DEFAULT_STEPS*2); // Note that VidFadeOut also erase the screen + + ShowCursor(FALSE); // Leave cursor off + UiVidFade(1,1); // restore palette for parent window + + SDlgKillTimer(window, LOGO_TIMER_ID); + DestroyArtwork(window); + break; + + + + case WM_INITDIALOG: + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + if (!uiparams || !uiparams->interfacedata) + return 0; + + if (uiparams->interfacedata) + LoadArtwork(window, uiparams->interfacedata->artcallback); + + UiLoadCursors(window, uiparams->interfacedata); + + // Set timer to poll for messages + LogoSetTimer(window, LOGO_TIMER_ID, uiparams->interfacedata->getdatacallback); + + // Set this window up to process SN_NOTIFY messages + ghWndUiMainParent = window; + + UiVidFade(1,1); + + return 1; + } + + return SDlgDefDialogProc(window,message,wparam,lparam); +} + + diff --git a/Storm/SOURCE/BATTLE/DISCONN.CPP b/Storm/SOURCE/BATTLE/DISCONN.CPP new file mode 100644 index 0000000..a3a3f88 --- /dev/null +++ b/Storm/SOURCE/BATTLE/DISCONN.CPP @@ -0,0 +1,39 @@ +/**************************************************************************** +* +* disconn.CPP +* battle.net user interface functions +* +* By Michael Morhaime +* +***/ + +#include "pch.h" + + + +//******************************************** +//******************************************** +BOOL CALLBACK RasEnumCallback(LPCTSTR szEntryName, LPVOID rashandle, LPVOID lpContext) { + SNETUIDATAPTR interfacedata; + char szFmt[256]; + char szMsg[512]; + char szTitle[32]; + BOOL bResult; + + interfacedata = (SNETUIDATAPTR) lpContext; + + LoadString(global_hinstance, IDS_QUERYDISCONNECT, szFmt, sizeof(szFmt)); + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + sprintf(szMsg, szFmt, szEntryName); + + if (interfacedata->messageboxcallback && GetActiveWindow()) + bResult = UiMessageBox(interfacedata->messageboxcallback, GetActiveWindow(), szMsg, szTitle, MB_OKCANCEL); + else + bResult = MessageBox(GetActiveWindow(), szMsg, szTitle, MB_OKCANCEL); + + if (bResult == IDOK) + HangupRASConnection(rashandle); + + return 1; +} + diff --git a/Storm/SOURCE/BATTLE/Debug/AD.obj b/Storm/SOURCE/BATTLE/Debug/AD.obj new file mode 100644 index 0000000..f19e11a Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/AD.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/BATTLE.obj b/Storm/SOURCE/BATTLE/Debug/BATTLE.obj new file mode 100644 index 0000000..ee57b2a Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/BATTLE.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/BATTLE.res b/Storm/SOURCE/BATTLE/Debug/BATTLE.res new file mode 100644 index 0000000..bfb6fac Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/BATTLE.res differ diff --git a/Storm/SOURCE/BATTLE/Debug/BNETLOGO.obj b/Storm/SOURCE/BATTLE/Debug/BNETLOGO.obj new file mode 100644 index 0000000..2a46159 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/BNETLOGO.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/Battle.lastbuildstate b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/Battle.lastbuildstate new file mode 100644 index 0000000..de3d96e --- /dev/null +++ b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/Battle.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v145:VCToolArchitecture=Native32Bit:VCToolsVersion=14.50.35717:VCServicingVersionCompilers=14.50.35728:TargetPlatformVersion=10.0.26100.0:VcpkgTriplet=x86-windows: +Debug|Win32|D:\projects\Hellfire\| diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.command.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.command.1.tlog new file mode 100644 index 0000000..fb63cf9 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.command.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.read.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.read.1.tlog new file mode 100644 index 0000000..ddeda7b Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.read.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.write.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.write.1.tlog new file mode 100644 index 0000000..e491ce9 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/CL.write.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/Cl.items.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/Cl.items.tlog new file mode 100644 index 0000000..25a3c64 --- /dev/null +++ b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/Cl.items.tlog @@ -0,0 +1,20 @@ +D:\projects\Hellfire\Storm\SOURCE\BATTLE\AD.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\AD.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\BATTLE.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\BATTLE.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\BNETLOGO.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\BNETLOGO.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CACHE.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\CACHE.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CANCEL.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\CANCEL.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\CHATCHNL.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\CHATROOM.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CLRPREF.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\CLRPREF.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\COMBO.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\COMBO.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CONNECT.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\CONNECT.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\DISCONN.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\DISCONN.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\JOINGAME.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\JOINGAME.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\LOGON.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\LOGON.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\MESSAGE.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\MESSAGE.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\PROGRESS.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\PROGRESS.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\RASMGR.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\RASMGR.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SCRLLBAR.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\SCRLLBAR.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SPI.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\SPI.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\SRV.obj +D:\projects\Hellfire\Storm\SOURCE\BATTLE\UI.CPP;D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\UI.obj diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.command.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.command.1.tlog new file mode 100644 index 0000000..af1cb4c Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.command.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.read.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.read.1.tlog new file mode 100644 index 0000000..d4b688d Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.read.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.secondary.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.secondary.1.tlog new file mode 100644 index 0000000..b3d9d74 --- /dev/null +++ b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.secondary.1.tlog @@ -0,0 +1,4 @@ +^D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\AD.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\BATTLE.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\BATTLE.RES|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\BNETLOGO.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\CACHE.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\CANCEL.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\CHATCHNL.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\CHATROOM.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\CLRPREF.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\COMBO.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\CONNECT.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\DISCONN.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\JOINGAME.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\LOGON.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\MESSAGE.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\PROGRESS.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\RASMGR.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\SCRLLBAR.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\SPI.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\SRV.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\BATTLE\DEBUG\UI.OBJ|D:\PROJECTS\HELLFIRE\WINDEBUG\STORM.LIB +D:\projects\Hellfire\bin\battle.lib +D:\projects\Hellfire\bin\battle.EXP +D:\projects\Hellfire\Storm\SOURCE\BATTLE\Debug\battle.ilk diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.write.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.write.1.tlog new file mode 100644 index 0000000..54509e0 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/link.write.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.command.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.command.1.tlog new file mode 100644 index 0000000..d116cf9 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.command.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.read.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.read.1.tlog new file mode 100644 index 0000000..fc1a41b Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.read.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.write.1.tlog b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.write.1.tlog new file mode 100644 index 0000000..b889549 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/Battle.tlog/rc.write.1.tlog differ diff --git a/Storm/SOURCE/BATTLE/Debug/CACHE.obj b/Storm/SOURCE/BATTLE/Debug/CACHE.obj new file mode 100644 index 0000000..84bfbfc Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/CACHE.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/CANCEL.obj b/Storm/SOURCE/BATTLE/Debug/CANCEL.obj new file mode 100644 index 0000000..2c272cd Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/CANCEL.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/CHATCHNL.obj b/Storm/SOURCE/BATTLE/Debug/CHATCHNL.obj new file mode 100644 index 0000000..97c4977 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/CHATCHNL.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/CHATROOM.obj b/Storm/SOURCE/BATTLE/Debug/CHATROOM.obj new file mode 100644 index 0000000..92b5855 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/CHATROOM.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/CLRPREF.obj b/Storm/SOURCE/BATTLE/Debug/CLRPREF.obj new file mode 100644 index 0000000..a18318c Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/CLRPREF.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/COMBO.obj b/Storm/SOURCE/BATTLE/Debug/COMBO.obj new file mode 100644 index 0000000..27642f0 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/COMBO.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/CONNECT.obj b/Storm/SOURCE/BATTLE/Debug/CONNECT.obj new file mode 100644 index 0000000..759dc94 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/CONNECT.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/DISCONN.obj b/Storm/SOURCE/BATTLE/Debug/DISCONN.obj new file mode 100644 index 0000000..ee28c6a Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/DISCONN.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/JOINGAME.obj b/Storm/SOURCE/BATTLE/Debug/JOINGAME.obj new file mode 100644 index 0000000..514bb4e Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/JOINGAME.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/LOGON.obj b/Storm/SOURCE/BATTLE/Debug/LOGON.obj new file mode 100644 index 0000000..11ee0e6 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/LOGON.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/MESSAGE.obj b/Storm/SOURCE/BATTLE/Debug/MESSAGE.obj new file mode 100644 index 0000000..663f60c Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/MESSAGE.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/PROGRESS.obj b/Storm/SOURCE/BATTLE/Debug/PROGRESS.obj new file mode 100644 index 0000000..7195b8d Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/PROGRESS.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/RASMGR.obj b/Storm/SOURCE/BATTLE/Debug/RASMGR.obj new file mode 100644 index 0000000..be8787b Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/RASMGR.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/SCRLLBAR.obj b/Storm/SOURCE/BATTLE/Debug/SCRLLBAR.obj new file mode 100644 index 0000000..d24ca47 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/SCRLLBAR.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/SPI.obj b/Storm/SOURCE/BATTLE/Debug/SPI.obj new file mode 100644 index 0000000..32502d9 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/SPI.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/SRV.obj b/Storm/SOURCE/BATTLE/Debug/SRV.obj new file mode 100644 index 0000000..83baf96 Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/SRV.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/UI.obj b/Storm/SOURCE/BATTLE/Debug/UI.obj new file mode 100644 index 0000000..53e30ff Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/UI.obj differ diff --git a/Storm/SOURCE/BATTLE/Debug/battle.ilk b/Storm/SOURCE/BATTLE/Debug/battle.ilk new file mode 100644 index 0000000..aec9aea Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/battle.ilk differ diff --git a/Storm/SOURCE/BATTLE/Debug/battle.log b/Storm/SOURCE/BATTLE/Debug/battle.log new file mode 100644 index 0000000..797e774 --- /dev/null +++ b/Storm/SOURCE/BATTLE/Debug/battle.log @@ -0,0 +1,375 @@ +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + AD.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + BATTLE.CPP + BNETLOGO.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + CACHE.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + CANCEL.CPP + CHATCHNL.CPP + CHATROOM.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + CLRPREF.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + COMBO.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + CONNECT.CPP + DISCONN.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + JOINGAME.CPP + LOGON.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + MESSAGE.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + PROGRESS.CPP + RASMGR.CPP +cl : command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release + SCRLLBAR.CPP + SPI.CPP + SRV.CPP + UI.CPP +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'BNETLOGO.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'BNETLOGO.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'BNETLOGO.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'BNETLOGO.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'BATTLE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'BATTLE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'BATTLE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'BATTLE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'CACHE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'CACHE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CACHE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CACHE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'CLRPREF.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'CLRPREF.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CLRPREF.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CLRPREF.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CACHE.CPP(230,5): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CACHE.CPP(537,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'AD.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'AD.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'AD.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'AD.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'CONNECT.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'CONNECT.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CONNECT.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CONNECT.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'CANCEL.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'CANCEL.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CANCEL.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CANCEL.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\AD.CPP(156,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATROOM.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATROOM.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATROOM.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\AD.CPP(190,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\AD.CPP(196,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATROOM.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'RASMGR.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'RASMGR.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'RASMGR.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'RASMGR.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\AD.CPP(394,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\AD.CPP(432,8): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'MESSAGE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'LOGON.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'MESSAGE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'LOGON.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'MESSAGE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'MESSAGE.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'LOGON.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'LOGON.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATCHNL.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATCHNL.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATCHNL.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'CHATCHNL.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'JOINGAME.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'JOINGAME.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'JOINGAME.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'JOINGAME.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'DISCONN.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'DISCONN.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'DISCONN.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'DISCONN.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'COMBO.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'COMBO.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'COMBO.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'COMBO.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(594,4): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(620,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(650,3): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(916,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(982,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1108,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1124,3): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1130,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1168,3): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1221,11): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1232,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1314,11): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1326,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1386,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1400,3): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1418,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1460,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1479,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1509,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1602,3): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(98,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(123,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(144,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(145,2): warning C4996: '_strlwr': This function or variable may be unsafe. Consider using _strlwr_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(150,3): warning C4996: '_strlwr': This function or variable may be unsafe. Consider using _strlwr_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(220,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(239,2): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATROOM.CPP(1892,14): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(316,6): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\DISCONN.CPP(27,2): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\CHATCHNL.CPP(377,4): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'SPI.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'SPI.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SPI.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SPI.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'SRV.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'SRV.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SRV.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SRV.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'SCRLLBAR.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'SCRLLBAR.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SCRLLBAR.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SCRLLBAR.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\JOINGAME.CPP(181,6): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\JOINGAME.CPP(296,12): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\JOINGAME.CPP(305,6): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'PROGRESS.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'PROGRESS.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'PROGRESS.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'PROGRESS.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\JOINGAME.CPP(357,4): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\JOINGAME.CPP(429,4): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\LOGON.CPP(278,2): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\LOGON.CPP(299,5): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\LOGON.CPP(332,2): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SPI.CPP(98,20): warning C4996: 'GetVersion': was declared deprecated +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SPI.CPP(608,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SPI.CPP(609,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SPI.CPP(610,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(264,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(314,5): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(317,5): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(358,7): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(364,7): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\PROGRESS.CPP(296,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(470,7): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(472,7): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(475,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(481,20): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(494,16): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(521,7): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(526,22): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(539,18): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\H\storm.h(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'UI.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'UI.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'UI.CPP') + +D:\projects\Hellfire\Storm\H\storm.h(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'UI.CPP') + +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(973,42): warning C4244: '=': conversion from 'time_t' to 'DWORD', possible loss of data +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(977,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(980,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1012,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1161,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1232,7): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1375,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1376,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1408,3): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1409,3): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1588,33): warning C4244: '=': conversion from 'unsigned long' to 'WORD', possible loss of data +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1759,7): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1763,7): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1894,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1896,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(1898,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2156,7): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2255,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2298,31): warning C4244: '=': conversion from 'time_t' to 'DWORD', possible loss of data +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2379,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2381,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2401,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2403,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2515,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2517,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\BATTLE\SRV.CPP(2519,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. + Creating library D:\projects\Hellfire\Storm\SOURCE\BATTLE\..\..\..\bin\battle.lib and object D:\projects\Hellfire\Storm\SOURCE\BATTLE\..\..\..\bin\battle.exp + battle.vcxproj -> D:\projects\Hellfire\bin\battle.snp + 'pwsh.exe' is not recognized as an internal or external command, + operable program or batch file. diff --git a/Storm/SOURCE/BATTLE/Debug/battle.snp.recipe b/Storm/SOURCE/BATTLE/Debug/battle.snp.recipe new file mode 100644 index 0000000..4b8c298 --- /dev/null +++ b/Storm/SOURCE/BATTLE/Debug/battle.snp.recipe @@ -0,0 +1,14 @@ + + + + + D:\projects\Hellfire\Storm\Debug\stormdll.dll + + + D:\projects\Hellfire\bin\battle.snp + + + + + + \ No newline at end of file diff --git a/Storm/SOURCE/BATTLE/Debug/vc145.pdb b/Storm/SOURCE/BATTLE/Debug/vc145.pdb new file mode 100644 index 0000000..4aa81dc Binary files /dev/null and b/Storm/SOURCE/BATTLE/Debug/vc145.pdb differ diff --git a/Storm/SOURCE/BATTLE/Debug/vcpkg.applocal.log b/Storm/SOURCE/BATTLE/Debug/vcpkg.applocal.log new file mode 100644 index 0000000..e02abfc --- /dev/null +++ b/Storm/SOURCE/BATTLE/Debug/vcpkg.applocal.log @@ -0,0 +1 @@ + diff --git a/Storm/SOURCE/BATTLE/JOINGAME.CPP b/Storm/SOURCE/BATTLE/JOINGAME.CPP new file mode 100644 index 0000000..8e5a8f1 --- /dev/null +++ b/Storm/SOURCE/BATTLE/JOINGAME.CPP @@ -0,0 +1,815 @@ +/**************************************************************************** +* +* JOINGAME.CPP +* battle.net chat room +* +* By Michael Morhaime +* +***/ + +//**************************************************************************** +// Modification Log: +// +// Diablo Patch #1 +// 2/3/97 MM - Instead of calling UpdateGameList every 10 seconds, +// we now only call it once. Then, after waiting 3 seconds, +// we go through the list of games calling SpiGetGameInfo() +// for each game. +// +// 2/5/97 MM - Added better error messages for not being able to join a game. +// +// 2/17/97 MM - Added call to SrvNotifyJoin() when successfully joining a game. +// +// Diablo Patch #2 +// 3/21/97 MM - Added support for requesting a list of games by category. +//**************************************************************************** + +#include "pch.h" + +#define MAX_STRING_LEN 128 + +typedef struct _CATEGORYDATA { + DWORD categorybits; + DWORD categorymask; +} CATEGORYDATA, *CATEGORYDATAPTR; + +static LPBYTE sgBackgroundBmp = NULL; +static LPBYTE sgButtonBmp = NULL; +static LPBYTE sgListboxBmp = NULL; + +static char sgszGameName[MAX_STRING_LEN] = ""; +static char sgszGamePassword[MAX_STRING_LEN] = ""; + +//### MM Diablo Patch #2 3/21/97 +static DWORD sgdwCategoryBits; +static DWORD sgdwCategoryMask; + +static HWND sghFilterCombo; + +extern int gnUserFlags; +//=========================================================================== +// External routines +//=========================================================================== +int NormalizeNetLag(DWORD dwMilliSec); +void DrawNetLag(int nNetLag, LPDRAWITEMSTRUCT lpdis); +int ListFindName(HWND hWndList, LPCSTR szName); + +//=========================================================================== +static void DestroyArtwork (HWND window) { + if (sgBackgroundBmp) { + FREE(sgBackgroundBmp); + sgBackgroundBmp = NULL; + } + + if (sgButtonBmp) { + FREE(sgButtonBmp); + sgButtonBmp = NULL; + } + + + if (sgListboxBmp) { + FREE(sgListboxBmp); + sgListboxBmp = NULL; + } +} + +//=========================================================================== +static BOOL LoadArtwork (HWND window, SNETGETARTPROC artcallback) { + int btn_ids[] = { + IDOK, + IDCANCEL, + 0 + }; + + int btn_desc[] = { + IDC_GAMEDESCRIPTION, + 0, + }; + + SIZE sizeBtns; + SIZE bgSize; + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_JOINBACKGROUND, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgBackgroundBmp, + &bgSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BUTTON_XSML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgButtonBmp, + &sizeBtns); + + SDlgSetControlBitmaps (window, btn_ids, NULL, sgButtonBmp, &sizeBtns, SDLG_ADJUST_VERTICAL); + SDlgSetControlBitmaps (window, btn_desc, NULL, sgBackgroundBmp, &bgSize, SDLG_ADJUST_CONTROLPOS); + return 1; +} + + +//=========================================================================== +//=========================================================================== +static HFONT InitCustomFonts(HWND hWnd) { +#if 0 + HFONT hFont = NULL; + LOGFONT lFont; + + if ((hFont = (HFONT) SendMessage(hWnd, WM_GETFONT, 0, 0L))) { + // Start with dialog font and modify face name + if (GetObject(hFont, sizeof(LOGFONT), (LPSTR) &lFont)) { + //lFont.lfHeight = -MulDiv(8, 96, 72); // height of 8 pixels + //lFont.lfWidth = 0; // let Windows autosize width + //lFont.lfWeight = FW_NORMAL; // change to non Bold + strcpy(lFont.lfFaceName, "Arial"); + + + if (hFont = CreateFontIndirect((LPLOGFONT) &lFont)) { + SendDlgItemMessage(hWnd, IDC_GAMEDESCRIPTION, WM_SETFONT, (WPARAM)hFont, 0); + } + } + } + return hFont; +#else + return 0; +#endif + +} + +//=========================================================================== +static void UpdateGameList (HWND dialog, HWND listbox, BOOL bSelGame) { + + SNETSPI_GAMELISTPTR curr, gamelist; + int nIndex; + + + // Get current linked list of games + if (!SpiLockGameList(sgdwCategoryBits, sgdwCategoryMask, &gamelist)) //### MM Diablo Patch #2 3/21/97 + return; + + curr = gamelist; + + + // MAKE SURE ALL GAMES IN THE LINKED LIST ARE REPRESENTED IN THE LIST BOX + SendMessage(listbox, WM_SETREDRAW, FALSE, 0); + while (curr) { + // Ignore private games + if (curr->gamemode & SNET_GM_PRIVATE) { + curr = curr->next; + continue; + } + + nIndex = ListFindName(listbox, curr->gamename); + + char szString[2*SNETSPI_MAXSTRINGLENGTH]; + + //### PATCH 2/3/97 MM Added gameid to string. +// sprintf(szString,"%s\t%x %x\t%s",curr->gamename, NormalizeNetLag(curr->ownerlatency), curr->creationtime, curr->gamedescription); + sprintf(szString,"%s\t%x %x %x\t%s",curr->gamename, curr->gameid, NormalizeNetLag(curr->ownerlatency), curr->creationtime, curr->gamedescription); + + // Is this game in the list box at all? + if (nIndex == LB_ERR) { + SendMessage(listbox,LB_ADDSTRING,0,(LPARAM)szString); + + // If there is no current list box selection, and there is no text in the + // NAME control, select this item as the default selection. + if ( bSelGame && + SendMessage(listbox,LB_GETCURSEL,0,0) == LB_ERR && + SendDlgItemMessage(dialog,IDC_EDIT_NAME,WM_GETTEXTLENGTH,0,0) == 0) { + SendMessage(listbox,LB_SETCURSEL,0,0); + SendMessage(dialog,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)listbox); + } + } + else { + char szOldString[2*SNETSPI_MAXSTRINGLENGTH]; + + // Game is in the list box, but is the information still correct? + SendMessage(listbox,LB_GETTEXT,nIndex,(LPARAM)szOldString); + if (strcmp(szString, szOldString)) { + int nSelect; + + // Save current selection for later + nSelect = SendMessage(listbox, LB_GETCURSEL, 0, 0); + + // Set new game info + SendMessage(listbox, LB_DELETESTRING, nIndex, 0); + SendMessage(listbox, LB_INSERTSTRING, nIndex, (LPARAM)(LPCSTR)szString); + + // Restore selection if necessary + if (nSelect == nIndex) + SendMessage(listbox, LB_SETCURSEL, nIndex, 0); + } + } + curr = curr->next; + } + + // MAKE SURE THERE ARE NO GAMES IN THE LIST BOX THAT AREN'T IN THE LINKED LIST + + { + char liststring[2*SNETSPI_MAXSTRINGLENGTH]; + WPARAM index = 0; + + while (SendMessage(listbox,LB_GETTEXT,index,(LPARAM)liststring) != LB_ERR) { + char *p; + + curr = gamelist; + + // Add NULL termination following game name + p = strchr(liststring, '\t'); + if (p) *p = 0; + + while (curr) { + if (!strcmp(curr->gamename,liststring)) + break; + else + curr = curr->next; + } + if (!curr) { + if ((WPARAM)SendMessage(listbox,LB_GETCURSEL,0,0) == index) { + SendMessage(listbox,LB_SETCURSEL,index-1,0); + SendMessage(dialog,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)listbox); + } + SendMessage(listbox,LB_DELETESTRING,index,0); + } + else + ++index; + } + } + + SpiUnlockGameList(gamelist, NULL); + + //### PATCH MM 2/5/97 + SrvMaintainLatencies(); + + SendMessage(listbox, WM_SETREDRAW, TRUE, 0); + + // update our scroll bar + ListUpdateScrollbar(listbox); + + +} + + +//### PATCH MM 2/3/97 +//=========================================================================== +static void UpdateGameLags(HWND hWndList) { + SNETSPI_GAMELIST curr; + char szString[2*SNETSPI_MAXSTRINGLENGTH]; + int nCount; + int nGameId, nLag, nTime; + char *p; + DWORD dwLatency; + + // Update latency counters + SrvMaintainLatencies(); + SendMessage(hWndList, WM_SETREDRAW, FALSE, 0); + + nCount = SendMessage(hWndList, LB_GETCOUNT, 0, 0); + if (nCount == LB_ERR) + return; + + for (int i=0; iinterfacedata && uiparams->interfacedata->drawdesccallback) { + DWORD dwItemFlags, dwDrawFlags; + + dwItemFlags = 0; + dwDrawFlags = SNET_DDF_MULTILINE; + return uiparams->interfacedata->drawdesccallback( + PROVIDERID, + SNET_DRAWTYPE_GAME, + name, + description, + dwItemFlags, + dwDrawFlags, + nTime, + (LPDRAWITEMSTRUCT)lparam); + } + + // OTHERWISE, LET THE DEFAULT DIALOG BOX PROCEDURE DRAW (OR ERASE) THE + // DESCRIPTION FROM THE STATIC TEXT + else + goto DRAW_BREAK; + + } + else if (wparam == IDC_GAMELIST) { + char szString[2*SNETSPI_MAXSTRINGLENGTH]; + LPSTR szLag = ""; + LPSTR description = ""; + LPSTR p; + int nLag = 0; + int nTime = 0; + COLORREF oldTextColor, oldBkColor; + LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lparam; + BOOL bSelected = lpdis->itemState & ODS_SELECTED; + + // Get user name/description + if (LB_ERR == SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)(LPCSTR)szString)) + goto DRAW_BREAK; + + // make sure we have something to draw + if (!szString[0] || !lpdis->hDC) + goto DRAW_BREAK; + + if (NULL != (p = strchr(szString,'\t'))) { + //### PATCH MM 2/3/97 Added gameid to string. + int nGameId; + + *p++ = 0; + + // Get Lag and Creation Time + szLag = p; + + //### PATCH MM 2/3/97 Added gameid to string. + //sscanf(szLag, "%x %x", &nLag, &nTime); + sscanf(szLag, "%x %x %x", &nGameId, &nLag, &nTime); + + if (NULL != (p = strchr(szLag,'\t'))) { + description = p; + *description++ = 0; + } + } + + // Draw gamename and net lag into list box + + // If the app has registered a draw description callback, + // let it draw the game name in the listbox. + if (uiparams->interfacedata && uiparams->interfacedata->drawdesccallback) { + DWORD dwItemFlags, dwDrawFlags; + + dwItemFlags = 0; + dwDrawFlags = SNET_DDF_INCLUDENAME; + uiparams->interfacedata->drawdesccallback( + PROVIDERID, + SNET_DRAWTYPE_GAME, + szString, + description, + dwItemFlags, + dwDrawFlags, + nTime, + (LPDRAWITEMSTRUCT)lparam); + } + else { + oldTextColor = SetTextColor(lpdis->hDC, RGB(0xff, 0xff, 0xff)); + oldBkColor = SetBkColor(lpdis->hDC, (bSelected) ? GetSysColor(COLOR_HIGHLIGHT) : RGB(0, 0, 0)); + ExtTextOut( + lpdis->hDC, + lpdis->rcItem.left, + lpdis->rcItem.top, + ETO_CLIPPED | ETO_OPAQUE, + &lpdis->rcItem, + szString, + strlen(szString), + NULL); + + // Restore colors to hdc + SetTextColor(lpdis->hDC, oldTextColor); + SetBkColor(lpdis->hDC, oldBkColor); + } + + // Draw net lag + DrawNetLag(nLag, lpdis); + return 1; + } +DRAW_BREAK: + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +static void CALLBACK JoinAddCategory(LPCSTR pszCategoryName, + DWORD categorybits, + DWORD categorymask) +{ + if (!sghFilterCombo) return; + int nPos = SendMessage(sghFilterCombo, + CB_ADDSTRING, + 0, + (LPARAM)pszCategoryName); + if (nPos == CB_ERR) return; + CATEGORYDATAPTR data = (CATEGORYDATAPTR)ALLOC(sizeof(CATEGORYDATA)); + data->categorybits = categorybits; + data->categorymask = categorymask; + SendMessage(sghFilterCombo,CB_SETITEMDATA,(WPARAM)nPos,(LPARAM)data); +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL CALLBACK JoinGameDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + static UIPARAMSPTR uiparams = NULL; + static BOOL sbSecondTimerActive = FALSE; + static HFONT shCustomFont; + + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case IDOK: { + HWND hWndName, hWndPassword; + char szText[MAX_STRING_LEN]; + SNETSPI_GAMELIST GameInfo; + + + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + hWndName = GetDlgItem(window, IDC_EDIT_NAME); + hWndPassword = GetDlgItem(window, IDC_EDIT_PASSWORD); + + + + // First, verify user entered required information + if (!SendMessage(hWndName, WM_GETTEXTLENGTH, 0, 0L)) { + LoadString(global_hinstance,IDS_NAME_REQUIRED,szText,MAX_STRING_LEN); + UiMessageBox( + uiparams->interfacedata->messageboxcallback, + window, + szText, + "", + MB_OK | MB_ICONWARNING); + return 0; + } + + + // Fill create game structure + SendMessage(hWndName, WM_GETTEXT, sizeof(sgszGameName), (LPARAM)((LPSTR)sgszGameName)); + SendMessage(hWndPassword, WM_GETTEXT, sizeof(sgszGamePassword), (LPARAM)((LPSTR)sgszGamePassword)); + + // Don't let user click ok twice + EnableWindow((HWND)lparam, FALSE); + + // Get Game info + TCHAR szPlayerName[MAX_STRING_LEN]; + TCHAR szPlayerDesc[MAX_STRING_LEN]; + SrvGetLocalPlayerName(szPlayerName,MAX_STRING_LEN); + SrvGetLocalPlayerDesc(szPlayerDesc,MAX_STRING_LEN); + if (SpiGetGameInfo (0, sgszGameName, sgszGamePassword, &GameInfo)) { + // Are we authorized to join this game + if (!uiparams->interfacedata->authcallback( + SNET_AUTHTYPE_GAME, + szPlayerName, + szPlayerDesc, + gnUserFlags, + GameInfo.gamedescription, + szText, + sizeof(szText))) { + UiMessageBox(uiparams->interfacedata->messageboxcallback, window, szText, NULL, MB_ICONWARNING | MB_OK); + EnableWindow((HWND)lparam, TRUE); + return 0; + } + + if (SNetJoinGame(0, + sgszGameName, + sgszGamePassword, + szPlayerName, + szPlayerDesc, + uiparams->playeridptr)) { + char progvers[32]; + wsprintf(progvers,"%08x%08x",global_programid,global_versionid); + SRegSaveString("Recent Games",progvers,SREG_FLAG_BATTLENET,sgszGameName); + + SrvNotifyJoin(sgszGameName, sgszGamePassword); //### PATCH MM 2/17/97 + + SDlgEndDialog(window, TRUE); + return 0; + } + } + + //### PATCH MM 2/5/97 + // Either join failed, or we couldn't get GameInfo about it. + + int nError = GetLastError(); + int nMsg = IDS_JOIN_FAILED; // Default Message + + if (nError == SNET_ERROR_HOST_UNREACHABLE) + nMsg = IDS_ERR_HOST_UNREACHABLE; + else if (nError == SNET_ERROR_GAME_FULL) + nMsg = IDS_ERR_GAME_FULL; + + LoadString(global_hinstance,nMsg,szText,MAX_STRING_LEN); + //### END + + UiMessageBox(uiparams->interfacedata->messageboxcallback, window, szText, "", MB_OK | MB_ICONWARNING); + EnableWindow((HWND)lparam, TRUE); + return 0; + + } + case IDCANCEL: + if (uiparams->interfacedata->soundcallback) + uiparams->interfacedata->soundcallback(PROVIDERID, SNET_SND_SELECTITEM, 0); + + SDlgEndDialog(window, FALSE); + return 0; + + case IDC_EDIT_NAME: + if (HIWORD(wparam) == EN_CHANGE) { + HWND hWndGameList = GetDlgItem(window, IDC_GAMELIST); + + // If the focus is in the edit control, assume the user + // just modified it, so remove any selection from the list box. + if ((HWND) lparam == GetFocus()) { + SendMessage(hWndGameList,LB_SETCURSEL,(WPARAM)-1,0); + SendMessage(window,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)hWndGameList); + } + } + break; + + case IDC_GAMELIST: + if (HIWORD(wparam) == LBN_DBLCLK) { + HWND hWndGameList = (HWND)lparam; + int nIndex; + + nIndex = SendMessage(hWndGameList, LB_GETCURSEL, 0, 0); + if (nIndex != LB_ERR) { + // Make sure we update the edit control first + SendMessage(window,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)hWndGameList); + + // Behave like OK was just pressed + SendMessage(window,WM_COMMAND,MAKELONG(IDOK,BN_CLICKED),(LPARAM)GetDlgItem(window, IDOK)); + } + + } + else if (HIWORD(wparam) == LBN_SELCHANGE) { + HWND hWndGameList = (HWND)lparam; + int nIndex = SendMessage(hWndGameList, LB_GETCURSEL, 0, 0); + char szText[MAX_STRING_LEN]; + + // Change text in Edit Control + if (nIndex != LB_ERR) { + char *p; + + SendMessage(hWndGameList,LB_GETTEXT, nIndex, (LPARAM)(LPCSTR)szText); + + + // NULL terminate game name (chop of description, and latency) + if (p = strchr(szText,'\t')) + *p = 0; + + // Set name and reset password (public games don't have a password) + SendDlgItemMessage(window, IDC_EDIT_NAME, WM_SETTEXT, 0, (LPARAM)(LPCSTR)szText); + SendDlgItemMessage(window, IDC_EDIT_PASSWORD, WM_SETTEXT, 0, (LPARAM)(LPCSTR)""); + } + + InvalidateRect(GetDlgItem(window, IDC_GAMEDESCRIPTION), NULL, TRUE); + + // Update scrollbar in case user scrolled the list with the mouse + ListUpdateScrollbar(hWndGameList); + } + break; + + case IDC_FILTER: { + if (HIWORD(wparam) == CBN_SELCHANGE) { + int nPos = SendMessage((HWND)lparam,CB_GETCURSEL,0,0); + if (nPos == CB_ERR) break; + CATEGORYDATAPTR data = (CATEGORYDATAPTR)SendMessage((HWND)lparam, + CB_GETITEMDATA, + (WPARAM)nPos, + 0); + if (!data) break; + sgdwCategoryBits = data->categorybits; + sgdwCategoryMask = data->categorymask; + UpdateGameList(window, GetDlgItem(window, IDC_GAMELIST), TRUE); + } + break; + } + } + break; + + case WM_CTLCOLORSTATIC: + if (GetWindowLong((HWND)lparam, GWL_ID) == IDC_TITLE) { + SetTextColor((HDC) wparam, RGB(0xff, 0xff, 0x00)); + return (BOOL) GetStockObject(NULL_BRUSH); + } + break; + + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + + case WM_TIMER: + if (sbSecondTimerActive) { + SDlgKillTimer(window, 2); + sbSecondTimerActive = FALSE; + } + + //### PATCH MM 2/4/97 + //UpdateGameList(window, GetDlgItem(window, IDC_GAMELIST), uiparams->programdata->selectioncriteria, FALSE); + UpdateGameLags(GetDlgItem(window, IDC_GAMELIST)); + //### END + break; + + case WM_DRAWITEM: + return JoinDrawItem(uiparams,message,window,wparam,lparam); + + case WM_DESTROY: + DestroyArtwork(window); + + if (sghFilterCombo) { + int nItems = SendMessage(sghFilterCombo,CB_GETCOUNT,0,0); + while(nItems--) { + CATEGORYDATAPTR data = + (CATEGORYDATAPTR)SendMessage(sghFilterCombo, + CB_GETITEMDATA, + (WPARAM)nItems, + 0); + if (data) FREE(data); + } + } + + //### PATCH MM 2/4/97 + //SDlgKillTimer(window, 1); + + if (sbSecondTimerActive) + SDlgKillTimer(window, 2); + + if (shCustomFont) { + DeleteObject(shCustomFont); + shCustomFont = NULL; + } + break; + + case WM_INITDIALOG: { + HWND hWndGameList; + RECT rect; + + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + + sbSecondTimerActive = TRUE; + + LoadArtwork(window, uiparams->interfacedata->artcallback); + + hWndGameList = GetDlgItem(window, IDC_GAMELIST); + ScrollbarLink(hWndGameList, GetDlgItem(window, IDC_SCROLLBAR)); + + //### MM Diablo Patch #2 3/21/97 + //### Added category support + // DML 10/16/97 + // Made "cancel" out of category callback (filter) possible + if (uiparams->interfacedata->categorycallback && + !uiparams->interfacedata-> + categorycallback(FALSE, + uiparams->programdata, + uiparams->playerdata, + uiparams->interfacedata, + uiparams->versiondata, + &sgdwCategoryBits, + &sgdwCategoryMask)) + SDlgEndDialog(window, FALSE); + + if (uiparams->interfacedata->categorylistcallback && + NULL != (sghFilterCombo = GetDlgItem(window,IDC_FILTER))) + { + uiparams->interfacedata->categorylistcallback(uiparams->playerdata, + JoinAddCategory); + SendMessage(sghFilterCombo,CB_SETCURSEL,0,0); + SendMessage(window, + WM_COMMAND, + MAKEWPARAM(IDC_FILTER,CBN_SELCHANGE), + (LPARAM)sghFilterCombo); + // CBN_SELCHANGE will cause a call to UpdateGameList + } + else { + sghFilterCombo = NULL; + UpdateGameList(window, hWndGameList, TRUE); + } + + //### PATCH MM 2/4/97 + //### Moved timer stuff below first UpdateGameList() call. + //### Eliminated 10 second timer. + //SDlgSetTimer(window,1,10000,NULL); // Poll for game list every 10 seconds + //SDlgSetTimer(window,2,1000,NULL); // One Shot One Second timer (so we can get latency info on games) + + SDlgSetTimer(window, 2, 3000,NULL); // Update latencies after 3 seconds + //### END + + // SET TAB STOPS FOR LIST BOX WIDE ENOUGH TO HIDE ALL TABBED TEXT + GetClientRect(hWndGameList,&rect); + SendMessage(hWndGameList,LB_SETTABSTOPS,1,(LPARAM) &rect.right); + + // Set the height of the games list box items (so lines don't overlap) + SendMessage(hWndGameList, LB_SETITEMHEIGHT, 0, 20); + + shCustomFont = InitCustomFonts(window); + return 1; + } + + } + + return SDlgDefDialogProc(window,message,wparam,lparam); + +} diff --git a/Storm/SOURCE/BATTLE/LOGON.CPP b/Storm/SOURCE/BATTLE/LOGON.CPP new file mode 100644 index 0000000..61b7f0d --- /dev/null +++ b/Storm/SOURCE/BATTLE/LOGON.CPP @@ -0,0 +1,461 @@ +/**************************************************************************** +* +* Logon.CPP +* battle.net user interface functions +* +* By Dan Liebgold +* +***/ + +#include "pch.h" +#pragma hdrstop + +#include + +extern HWND ghWndUiMainParent; + +//=========================================================================== +#define MAX_NAME_LEN 30 +#define MAX_PASS_LEN 8 + +static LPBYTE sgBkgBmp; +static LPBYTE sgNewBkgBmp; +static LPBYTE sgButtonBmp; +static SIZE sgButtonSize; +static LPBYTE sgMedBtnBmp; +static SNETUIDATAPTR sgpInterfacedata; +static TCHAR sgszNewName[256]; +static TCHAR sgszPassword[256]; + +#define PLAYSELECTSND \ + if (sgpInterfacedata->soundcallback) \ + sgpInterfacedata->soundcallback(PROVIDERID, \ + SNET_SND_SELECTITEM, \ + 0) + + +//=========================================================================== +static void NewLoadArtwork(HWND window, SNETGETARTPROC artcallback) { + int btn_ids[] = { + IDOK, + IDCANCEL, + 0 + }; + + SIZE bgSize; + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_BATTLE_NEW_ACCOUNT_BKG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + TRUE, + FALSE, + &sgNewBkgBmp, + &bgSize); + + SDlgSetControlBitmaps(window, + btn_ids, + NULL, + sgButtonBmp, + &sgButtonSize, + SDLG_ADJUST_VERTICAL); +} + +//=========================================================================== +static BOOL CheckPassword(HWND window) { + TCHAR szPass2[256]; + + SendMessage(GetDlgItem(window,IDC_PASS1), + WM_GETTEXT, + (WPARAM)sizeof(sgszPassword), + (LPARAM)sgszPassword); + SendMessage(GetDlgItem(window,IDC_PASS2), + WM_GETTEXT, + (WPARAM)sizeof(szPass2), + (LPARAM)szPass2); + + if (_tcscmp(sgszPassword,szPass2)) return FALSE; + return TRUE; +} + +//=========================================================================== +static BOOL CALLBACK NewDialogProc(HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case IDOK: { + SendMessage(GetDlgItem(window,IDC_NAME), + WM_GETTEXT, + (WPARAM)sizeof(sgszNewName), + (LPARAM)sgszNewName); + + PLAYSELECTSND; + + if (CheckPassword(window)) { + SDlgEndDialog(window,TRUE); + return 0; + } + + char szPassErr[256]; + LoadString(global_hinstance, + IDS_PASSWORD_MISMATCH, + szPassErr, + sizeof(szPassErr)); + + UiMessageBox(sgpInterfacedata->messageboxcallback, + window, + szPassErr, + "", + MB_OK|MB_ICONWARNING); + break; + } + + case IDCANCEL: + PLAYSELECTSND; + SDlgEndDialog(window,FALSE); + break; + + + case IDC_PASS2: + if (HIWORD(wparam) == EN_CHANGE) { + int len = 0; + len += SendMessage(GetDlgItem(window, IDC_NAME), + WM_GETTEXTLENGTH, + 0,0); + len += SendMessage(GetDlgItem(window, IDC_PASS1), + WM_GETTEXTLENGTH, + 0,0); + len += SendMessage((HWND)lparam, + WM_GETTEXTLENGTH, + 0,0); + EnableWindow(GetDlgItem(window, IDOK), len); + } + break; + + } + break; + + case WM_DESTROY: + if (sgNewBkgBmp) { + FREE(sgNewBkgBmp); + sgNewBkgBmp = NULL; + } + break; + + case WM_INITDIALOG: + NewLoadArtwork(window, sgpInterfacedata->artcallback); + HWND name = GetDlgItem(window, IDC_NAME); + SetFocus(name); + SendMessage(name, EM_LIMITTEXT, MAX_NAME_LEN - 1, 0); + + EnableWindow(GetDlgItem(window, IDOK), FALSE); + + return 0; + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + + +//=========================================================================== +static void DestroyArtwork (HWND window) { + if (sgBkgBmp) { + FREE(sgBkgBmp); sgBkgBmp = NULL; + } + if (sgButtonBmp) { + FREE(sgButtonBmp); sgButtonBmp = NULL; + } + if (sgMedBtnBmp) { + FREE(sgMedBtnBmp); sgMedBtnBmp = NULL; + } +} + +//=========================================================================== +static BOOL LoadArtwork (HWND window, SNETGETARTPROC artcallback) { + int btn_ids[] = { + IDOK, + IDCANCEL, + 0 + }; + + int static_txt[] = { + IDC_TITLE, + 0 + }; + + SIZE bgSize; + SIZE medBtnSize; + + UiLoadArtwork( + artcallback, + window, + NULL, + SNET_ART_BATTLE_LOGIN_BKG, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + TRUE, + FALSE, + &sgBkgBmp, + &bgSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BUTTON_XSML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgButtonBmp, + &sgButtonSize); + + UiLoadArtwork( + artcallback, + GetDlgItem(window,IDS_NEWACCOUNT), + NULL, + SNET_ART_BUTTON_MED, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgMedBtnBmp, + &medBtnSize); + + SDlgSetControlBitmaps (window,btn_ids,NULL,sgButtonBmp,&sgButtonSize,SDLG_ADJUST_VERTICAL); + return 1; +} + +//=========================================================================== +static LPBYTE LogonGetNames(LPCTSTR key, LPCTSTR value, DWORD *pBytes) { + LPBYTE buffer = NULL; + DWORD bytesread = 0; + DWORD datatype = REG_MULTI_SZ; + DWORD dwNameLen = pBytes ? *pBytes : 0; + LONG lError; + for (int iter = 0; iter < 2; ++iter) { + HKEY keyhandle; + if (ERROR_SUCCESS == (lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + key, + 0, + KEY_READ, + &keyhandle))) + { + RegQueryValueEx(keyhandle, + value, + 0, + &datatype, + buffer, + &bytesread); + RegCloseKey(keyhandle); + if (!buffer) buffer = (LPBYTE)ALLOCZERO(bytesread + dwNameLen + 2); + } + else { + + } + } + if (pBytes) *pBytes = bytesread; + return buffer; +} + +//=========================================================================== +static void LogonRememberName(LPCSTR szName) { + TCHAR key[MAX_PATH]; + DWORD dwNameLen = _tcslen(szName); + BOOL success = 0; + + SRegGetBaseKey(SREG_FLAG_BATTLENET,key,MAX_PATH); + _tcscat(key,TEXT("Characters")); + TCHAR valuename[MAX_PATH] = TEXT("Names"); + + DWORD bytesread = _tcslen(szName); + LPBYTE buffer = LogonGetNames(key,valuename,&bytesread); + + if (!buffer) { + buffer = (LPBYTE)ALLOCZERO(dwNameLen + 2); + *buffer = 0; + } + + TCHAR *pszTemp = (TCHAR*)buffer,*pszName; + while (*pszTemp) { + pszName = pszTemp; + if (!_tcscmp(szName,pszName)) + goto REMEMBER_EXIT; // name is already there + pszTemp += _tcslen(pszName) + 1; + } + + // Add the name to front of list + memmove(buffer + dwNameLen + 1, buffer, bytesread); + _tcscpy((TCHAR*)buffer,szName); + *(buffer + dwNameLen) = 0; + + // Write the buffer back to the registry + HKEY keyhandle; + DWORD disposition; + if (!RegCreateKeyEx(HKEY_LOCAL_MACHINE, + key, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + &keyhandle, + &disposition)) { + success |= !RegSetValueEx(keyhandle, + valuename, + 0, + REG_MULTI_SZ, + (const BYTE *)buffer, + bytesread + dwNameLen + 2); + RegCloseKey(keyhandle); + } +REMEMBER_EXIT: + FREE(buffer); +} + + +//=========================================================================== +static void LogonGetNames(HWND combo) { + TCHAR key[MAX_PATH]; + + SRegGetBaseKey(SREG_FLAG_BATTLENET,key,MAX_PATH); + _tcscat(key,TEXT("Characters")); + TCHAR valuename[MAX_PATH] = TEXT("Names"); + + DWORD bytesread = 0; + LPBYTE buffer = LogonGetNames(key,valuename,&bytesread); + + if (!buffer) return; + + TCHAR *pszName = (TCHAR*)buffer; + while (*pszName) { + SendMessage(combo,CB_ADDSTRING,0,(LPARAM)pszName); + pszName += _tcslen(pszName) + 1; + } + + // select the first name + SendMessage(combo,CB_SETCURSEL,0,0); + FREE(buffer); +} + + +//=========================================================================== +BOOL CALLBACK LogonDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + switch (message) { + case WM_COMMAND: + switch (LOWORD(wparam)) { + case IDOK: + PLAYSELECTSND; + + TCHAR szName[MAX_NAME_LEN]; + TCHAR szPass[MAX_PASS_LEN]; + SendDlgItemMessage(window, IDC_COMBO_NAME, WM_GETTEXT, MAX_NAME_LEN, (LPARAM)(LPCSTR)szName); + SendDlgItemMessage(window, IDC_EDIT_PASSWORD, WM_GETTEXT, MAX_PASS_LEN, (LPARAM)(LPCSTR)szPass); + + DWORD errorcode; + if (SrvLogon (szName,szPass, &errorcode)) { + LogonRememberName(szName); + SDlgEndDialog(window, 1); + return 0; + } + + SDlgEndDialog(window, 0); + return 0; + + case IDCANCEL: + PLAYSELECTSND; + SDlgEndDialog(window, 0); + return 0; + + case IDS_NEWACCOUNT: + PLAYSELECTSND; + BOOL bRes; + bRes = SDlgDialogBox(global_hinstance, + TEXT("DIALOG_NEW_ACCOUNT"), + window, + (DLGPROC)NewDialogProc); + if (bRes) { + HWND combo = GetDlgItem(window,IDC_COMBO_NAME); + int nPos = SendMessage(combo, + CB_ADDSTRING, + 0, + (LPARAM)sgszNewName); + SendMessage(combo,CB_SETCURSEL,(WPARAM)nPos,0); + SendMessage(window, + WM_COMMAND, + MAKEWPARAM(IDC_COMBO_NAME,CBN_SELCHANGE), + (LPARAM)combo); + } + return 0; + + case IDC_COMBO_NAME: + if (HIWORD(wparam) == CBN_EDITCHANGE) { + EnableWindow( + GetDlgItem(window, IDOK), + (BOOL)SendMessage((HWND)LOWORD(lparam), WM_GETTEXTLENGTH, 0, 0)); + } + return 0; + } + break; + + case WM_CTLCOLORSTATIC: + if (GetWindowLong((HWND)lparam, GWL_ID) == IDC_TITLE) { + SetTextColor((HDC) wparam, RGB(0xff, 0xff, 0x00)); + return (BOOL) GetStockObject(NULL_BRUSH); + } + break; + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + case WM_DESTROY: + ghWndUiMainParent = NULL; + + UiVidFadeOut(DEFAULT_STEPS*2); // Note that VidFadeOut also erase the screen + + ShowCursor(FALSE); // Leave cursor off + UiVidFade(1,1); // restore palette for parent window + + DestroyArtwork(window); + break; + + + case WM_INITDIALOG: + ghWndUiMainParent = window; + + sgpInterfacedata = (SNETUIDATAPTR) lparam; + if (sgpInterfacedata->artcallback) + LoadArtwork(window, sgpInterfacedata->artcallback); + EnableWindow(GetDlgItem(window, IDOK), FALSE); + + HWND namecombo = GetDlgItem(window, IDC_COMBO_NAME); + SetFocus(namecombo); + SendMessage(namecombo, CB_LIMITTEXT, MAX_NAME_LEN - 1, 0); + + LogonGetNames(namecombo); + + UiLoadCursors(window, sgpInterfacedata); + + UiVidFade(1,1); + return 0; + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + + diff --git a/Storm/SOURCE/BATTLE/MESSAGE.CPP b/Storm/SOURCE/BATTLE/MESSAGE.CPP new file mode 100644 index 0000000..6ffd4f1 --- /dev/null +++ b/Storm/SOURCE/BATTLE/MESSAGE.CPP @@ -0,0 +1,31 @@ +/**************************************************************************** +* +* message.cpp +* +* MessageBox routines. +* +* By Michael Morhaime +* +***/ + +#include "pch.h" + + + + +//**************************************************************************** +BOOL UiMessageBox(SNETMESSAGEBOXPROC messageboxcallback, HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) { + BOOL bResult; + + // Make sure we have a visible cursor for the message box. + ShowCursor(TRUE); + + if (messageboxcallback) + bResult = messageboxcallback(hWnd, lpText, lpCaption, uType); + else + bResult = MessageBox(SDrawGetFrameWindow(), lpText, lpCaption, uType); + + ShowCursor(FALSE); + + return bResult; +} diff --git a/Storm/SOURCE/BATTLE/PCH.H b/Storm/SOURCE/BATTLE/PCH.H new file mode 100644 index 0000000..ada7ff4 --- /dev/null +++ b/Storm/SOURCE/BATTLE/PCH.H @@ -0,0 +1,19 @@ +#define OEMRESOURCE +#define STRICT +#define SDLG_USE_INCLUSIVE_RECTS +#define STRANS_USE_INCLUSIVE_RECTS +#include +#include +#include +#include +#include +#include +#include +#include "../../H/storm.h" +#include +#include "battle.h" +#include "bnetart.h" +#include "chat.h" +#include "rasmgr.h" +#include "resource.h" +#include "string.h" diff --git a/Storm/SOURCE/BATTLE/PROGRESS.CPP b/Storm/SOURCE/BATTLE/PROGRESS.CPP new file mode 100644 index 0000000..e220bf6 --- /dev/null +++ b/Storm/SOURCE/BATTLE/PROGRESS.CPP @@ -0,0 +1,309 @@ +//**************************************************************************** +// Progress.cpp +// Diablo UI progress bar popup dialog +// +// By Frank Pearce +// created 9.26.96 +//**************************************************************************** + + +#include "pch.h" + + +//**************************************************************************** +//**************************************************************************** + #define PROGRESS_TIMER_ID 1 + #define MILLISEC_PER_SEC 1000 + #define CALLS_PER_SEC 20 + #define USER_DELAY (MILLISEC_PER_SEC / sgCallsPerSec) + #define DEFAULT_DELAY (MILLISEC_PER_SEC / CALLS_PER_SEC) + + #define FILL_X 0 + #define FILL_Y 0 + + static LPBYTE sgBgBmp = NULL; + static LPBYTE sgBtnBmp = NULL; + + // the progress bar background + static LPBYTE sgProgBgBmp = NULL; + static SIZE sgProgBgSize; + + // the fill image for the progress bar + static LPBYTE sgProgFillBmp = NULL; + static SIZE sgProgFillSize; + + // the current image based on percent complete + static LPBYTE sgProgBmp = NULL; + static SIZE sgProgSize; + + static BOOL sgAbortable; + static DWORD sgCallsPerSec; + static PROGRESSFCN sgProgressFcn; + static char sgszProgressText[256]; + + +//**************************************************************************** +//**************************************************************************** +static void ProgressDraw(HWND window, int percent) { + RECT rect; + HWND child = GetDlgItem(window, IDC_UIGENERIC_PROGRESS); + + if (!sgProgBmp || !sgProgBgBmp) + return; + + // Bound percent + if (percent > 100) + percent = 100; + if (percent < 0) + percent = 0; + + + // draw the bg + SBltROP3( + sgProgBmp, + sgProgBgBmp, + sgProgSize.cx, + sgProgSize.cy, + sgProgSize.cx, + sgProgBgSize.cx, + NULL, + SRCCOPY + ); + + // draw the fill + SBltROP3( + sgProgBmp + (FILL_Y * sgProgSize.cx) + FILL_X, + sgProgFillBmp, + ((sgProgSize.cx - (2 * FILL_X)) * percent) / 100, + sgProgSize.cy - (2 * FILL_Y), + sgProgSize.cx, + sgProgFillSize.cx, + NULL, + SRCCOPY + ); + + // invalidate the region + GetWindowRect(child, &rect); + ScreenToClient(window, (LPPOINT)&rect.left); + ScreenToClient(window, (LPPOINT)&rect.right); + InvalidateRect(window, &rect, FALSE); +} + + +//**************************************************************************** +//**************************************************************************** +static void ProgressDestroy(HWND window) { + if (sgBgBmp) { + FREE(sgBgBmp); + sgBgBmp = NULL; + } + if (sgBtnBmp) { + FREE(sgBtnBmp); + sgBtnBmp = NULL; + } + if (sgProgBgBmp) { + FREE(sgProgBgBmp); + sgProgBgBmp = NULL; + } + if (sgProgFillBmp) { + FREE(sgProgFillBmp); + sgProgFillBmp = NULL; + } + if (sgProgBmp) { + FREE(sgProgBmp); + sgProgBmp = NULL; + } +} + + +//**************************************************************************** +//**************************************************************************** +static void ProgressInit(HWND window, SNETGETARTPROC artcallback) { + HWND child; + RECT rect; + SIZE btnsize; + int BtnIDs[] = { IDCANCEL, 0 }; + + if (sgCallsPerSec) + SDlgSetTimer(window,PROGRESS_TIMER_ID,USER_DELAY,NULL); + else + SDlgSetTimer(window,PROGRESS_TIMER_ID,DEFAULT_DELAY,NULL); + + + // load ctrl/dlg bmps + UiLoadArtwork( + artcallback, + window, + GetParent(window), + SNET_ART_POPUPBACKGROUND_SML, + TEXT("Popup"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgBgBmp, + NULL + ); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_BUTTON_SML, + TEXT("Button"), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgBtnBmp, + &btnsize); + + SDlgSetControlBitmaps (window, BtnIDs, NULL, sgBtnBmp, &btnsize, SDLG_ADJUST_VERTICAL); + + + // load progress bar textures + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_PROGRESS_BACKGROUND, + 0, + 0, + 0, + FALSE, + FALSE, + &sgProgBgBmp, + &sgProgBgSize); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_PROGRESS_FILLER, + 0, + 0, + 0, + FALSE, + FALSE, + &sgProgFillBmp, + &sgProgFillSize); + + + // alloc/create a bitmap for the progress indicator + child = GetDlgItem(window, IDC_UIGENERIC_PROGRESS); + GetClientRect(child, &rect); + + sgProgBmp = (LPBYTE) ALLOC(rect.right * rect.bottom); + sgProgSize.cx = rect.right; + sgProgSize.cy = rect.bottom; + + SDlgSetBitmap( + child, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + sgProgBmp, + NULL, + rect.right, + rect.bottom + ); + ProgressDraw(window, 0); + + // set the text describing what progress is being monitored + child = GetDlgItem(window, IDC_PROGRESS_TEXT); + SetWindowText(child, (LPCSTR)sgszProgressText); + + // show/hide cancel button based on abortable flag + child = GetDlgItem(window, IDCANCEL); + ShowWindow(child, (sgAbortable ? SW_SHOWNORMAL : SW_HIDE)); + EnableWindow(child, sgAbortable); +} + + +//**************************************************************************** +//**************************************************************************** +static void ProgressTimer(HWND window) { + int percent = 0; + + if (sgProgressFcn) + percent = sgProgressFcn(); + + ProgressDraw(window, percent); +} + + +//**************************************************************************** +//**************************************************************************** +static BOOL CALLBACK ProgressDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + static SNETUIDATAPTR interfacedata; + switch (message) { + + case WM_COMMAND: + if (LOWORD(wparam) == IDCANCEL) { + SrvCancel(); + SDlgEndDialog(window, 0); + return 0; + } + break; + + case WM_DESTROY: + SDlgKillTimer(window, PROGRESS_TIMER_ID); + ProgressDestroy(window); + break; + + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + SendMessage(SDrawGetFrameWindow(), message, wparam, lparam); + break; + + case WM_INITDIALOG: + interfacedata = (SNETUIDATAPTR) lparam; + ProgressInit(window, interfacedata->artcallback); + return 1; + + case WM_TIMER: + ProgressTimer(window); + break; + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + + +//**************************************************************************** +//* +//* EXPORTED FUNCTIONS +//* +//**************************************************************************** + + +//**************************************************************************** +//**************************************************************************** +HWND UiModelessProgressDialog(SNETUIDATAPTR interfacedata, + LPCSTR progresstext, + BOOL abortable, + PROGRESSFCN progressfcn, + DWORD callspersec +) { + sgProgressFcn = progressfcn; + sgAbortable = abortable; + sgCallsPerSec = callspersec; + + if (strlen(progresstext) < sizeof(sgszProgressText)) + strcpy((LPSTR)sgszProgressText, progresstext); + + if (!interfacedata) + return NULL; + + return SDlgCreateDialogParam( + global_hinstance, + TEXT("DIALOG_PROGRESS"), + interfacedata->parentwindow, + ProgressDialogProc, + (LPARAM) interfacedata + ); + +} diff --git a/Storm/SOURCE/BATTLE/RASMGR.CPP b/Storm/SOURCE/BATTLE/RASMGR.CPP new file mode 100644 index 0000000..3843c18 --- /dev/null +++ b/Storm/SOURCE/BATTLE/RASMGR.CPP @@ -0,0 +1,240 @@ +/**************************************************************************** +* +* RASMGR.CPP +* Remote Access Service Connection Manager +* +* By Jeff Strain (12/9/96) +* +***/ + +#include "pch.h" + +#define MAXACTIVECONNECTIONS 10 + +typedef DWORD (CALLBACK *RASHANGUP)(HRASCONN); +typedef DWORD (CALLBACK *RASENUMCONN)(LPRASCONN, LPDWORD, LPDWORD); +typedef DWORD (CALLBACK *RASGETSTATUS)(HRASCONN, LPRASCONNSTATUS); + +static HRASCONN sg_ahActiveConn[MAXACTIVECONNECTIONS] = {0}; +static HINSTANCE sg_hRasDLL = NULL; +static RASENUMCONN sg_pRasEnumConnections = NULL; +static RASHANGUP sg_pRasHangUp = NULL; +static RASGETSTATUS sg_pRasGetConnectStatus = NULL; + +/**************************************************************************** +* +* Private Functions +* +***/ + +// GETS A SAFE RASCONN STRUCTURE. IT IS UP TO THE CALLING FUNCTION TO +// FREE THE STRUCTURE WHEN IT IS DONE WITH IT! +static LPRASCONN WINAPI InternalRasEnumConnections(LPDWORD dwConnections) +{ + LPRASCONN lpRasConn = NULL; + DWORD dwBytes; + DWORD dwReturn; + + // FILL OUT A SINGLE RASCONN STRUCTURE + dwBytes = sizeof(RASCONN); + // LOOP UNTIL WE HAVE ALLOCATED A LARGE ENOUGH BUFFER TO HOLD ALL + // ACTIVE RAS CONNECTIONS + do { + if (lpRasConn) + LocalFree(lpRasConn); + lpRasConn = (LPRASCONN) LocalAlloc(LPTR, dwBytes); + ASSERT(lpRasConn); + if (!lpRasConn) + return NULL; + + lpRasConn[0].dwSize = sizeof(RASCONN); + dwReturn = sg_pRasEnumConnections(lpRasConn, &dwBytes, dwConnections); + + if (!(!dwReturn || dwReturn == ERROR_BUFFER_TOO_SMALL)) { + if (lpRasConn) + LocalFree(lpRasConn); + return NULL; + } + } while (dwReturn == ERROR_BUFFER_TOO_SMALL); + + return lpRasConn; +} + +/**************************************************************************** +* +* Public Session Management Functions +* +***/ + +// SHOULD BE CALLED ONE TIME ONLY AT STARTUP. STORES ALL ACTIVE +// RAS CONNECTIONS AND USES THIS AS A FILTER FOR ENUMNEWCALLS() +BOOL WINAPI InitRASManager() +{ + LPRASCONN lpRasConn = NULL; + DWORD dwConnections; + + // MANUALLY LOAD RAS DLL SINCE SYSTEMS WITHOUT DIALUP NETWORKING + // INSTALLED WON'T HAVE IT. + if (!sg_hRasDLL) { + sg_hRasDLL = LoadLibrary(TEXT("rasapi32")); + if (!sg_hRasDLL) + return FALSE; + } +#ifdef _UNICODE + sg_pRasEnumConnections = + (RASENUMCONN)GetProcAddress(sg_hRasDLL, TEXT("RasEnumConnectionsW")); + sg_pRasHangUp = + (RASHANGUP)GetProcAddress(sg_hRasDLL, TEXT("RasHangUpW")); + sg_pRasGetConnectStatus = + (RASGETSTATUS)GetProcAddress(sg_hRasDLL, TEXT("RasGetConnectStatusW")); +#else + sg_pRasEnumConnections = + (RASENUMCONN)GetProcAddress(sg_hRasDLL, TEXT("RasEnumConnectionsA")); + sg_pRasHangUp = + (RASHANGUP)GetProcAddress(sg_hRasDLL, TEXT("RasHangUpA")); + sg_pRasGetConnectStatus = + (RASGETSTATUS)GetProcAddress(sg_hRasDLL, TEXT("RasGetConnectStatusA")); +#endif + ASSERT(sg_pRasEnumConnections && sg_pRasHangUp && sg_pRasGetConnectStatus); + if (!(sg_pRasEnumConnections && sg_pRasHangUp && sg_pRasGetConnectStatus)) + return FALSE; + + lpRasConn = InternalRasEnumConnections(&dwConnections); + if (!lpRasConn) + return FALSE; + + for (DWORD i = 0; i < min(dwConnections, MAXACTIVECONNECTIONS); i++) + sg_ahActiveConn[i] = lpRasConn[i].hrasconn; + if (i < MAXACTIVECONNECTIONS) + sg_ahActiveConn[i] = NULL; + + if (lpRasConn) + LocalFree(lpRasConn); + + return TRUE; +} + +//=========================================================================== +DWORD WINAPI GetNumActiveRASConnections() +{ + LPRASCONN lpRasConn = NULL; + DWORD dwConnections; + + if (!sg_hRasDLL) + return 0; + + lpRasConn = InternalRasEnumConnections(&dwConnections); + ASSERT(lpRasConn); + if (!lpRasConn) + return 0; + + if (lpRasConn) + LocalFree(lpRasConn); + + return dwConnections; +} + +//=========================================================================== +BOOL WINAPI EnumNewRASConnections(LPRASENUMCALLBACK lpCallback, + LPVOID lpContext) +{ + LPRASCONN lpRasConn = NULL; + DWORD dwConnections; + + if (!sg_hRasDLL) + return FALSE; + + ASSERT(lpCallback); + if (!lpCallback) + return FALSE; + + lpRasConn = InternalRasEnumConnections(&dwConnections); + if (!lpRasConn) + return FALSE; + + // CALL THE CALLBACK WITH THE NAME AND HANDLE OF EACH RAS CONNECTION + BOOL bReturn; + for (DWORD i = 0; i < dwConnections; i++) { + for (DWORD j = 0; j < MAXACTIVECONNECTIONS; j++) { + if (!sg_ahActiveConn[j]) + break; + if (sg_ahActiveConn[j] == lpRasConn[i].hrasconn) + break; + } + if (j == MAXACTIVECONNECTIONS || !sg_ahActiveConn[j]) { + bReturn = lpCallback((LPCTSTR)lpRasConn[i].szEntryName, + (LPVOID)lpRasConn[i].hrasconn, lpContext); + if (bReturn) + break; + } + } + + if (lpRasConn) + LocalFree(lpRasConn); + + return TRUE; +} + +//=========================================================================== +BOOL WINAPI EnumActiveRASConnections(LPRASENUMCALLBACK lpCallback, + LPVOID lpContext) +{ + LPRASCONN lpRasConn = NULL; + DWORD dwConnections; + + if (!sg_hRasDLL) + return FALSE; + + ASSERT(lpCallback); + if (!lpCallback) + return FALSE; + + lpRasConn = InternalRasEnumConnections(&dwConnections); + ASSERT(lpRasConn); + if (!lpRasConn) + return FALSE; + + // CALL THE CALLBACK WITH THE NAME AND HANDLE OF EACH RAS CONNECTION + BOOL bReturn; + for (DWORD i = 0; i < dwConnections; i++) { + bReturn = lpCallback((LPCTSTR)lpRasConn[i].szEntryName, + (LPVOID)lpRasConn[i].hrasconn, lpContext); + if (bReturn) + break; + } + + if (lpRasConn) + LocalFree(lpRasConn); + + return TRUE; +} + +//=========================================================================== +// NOTE THAT THIS IS POTENTIALLY A BLOCKING CALL +BOOL WINAPI HangupRASConnection(LPVOID rasconn) +{ + DWORD dwReturn; + RASCONNSTATUS rcStatus; + HRASCONN hRasConn = (HRASCONN)rasconn; + + ASSERT(sg_hRasDLL); + if (!sg_hRasDLL) + return FALSE; + + ASSERT(hRasConn); + if (!hRasConn) + return FALSE; + + // HANGUP LINE + dwReturn = sg_pRasHangUp(hRasConn); + ASSERT(!dwReturn); + if (dwReturn) + return FALSE; + + // WAIT FOR STATE MACHINE TO RESET PORT PROPERLY + rcStatus.dwSize = sizeof(RASCONNSTATUS); + while (sg_pRasGetConnectStatus(hRasConn, &rcStatus) != ERROR_INVALID_HANDLE) + Sleep(0); + + return TRUE; +} diff --git a/Storm/SOURCE/BATTLE/RASMGR.H b/Storm/SOURCE/BATTLE/RASMGR.H new file mode 100644 index 0000000..5c6a127 --- /dev/null +++ b/Storm/SOURCE/BATTLE/RASMGR.H @@ -0,0 +1,41 @@ +#ifndef __RASMGR_H +#define __RASMGR_H + +/**************************************************************************** +* +* Session Management Functions +* +***/ + +// CALLBACK FOR EnumActiveRASConnections(). THE LPVOID RASHADLE +// PARAMETER SHOULD BE STORED AS AN OPAQUE POINTER AND PASSED +// TO HangupRASConnection(). THE FUNCTION SHOULD RETURN TRUE +// TO CONTINUE THE ENUMERATION, FALSE TO CANCEL. +typedef BOOL (APIENTRY *LPRASENUMCALLBACK)(LPCTSTR szEntryName, + LPVOID rashandle, + LPVOID lpContext); + +// INITIALIZES RAS MANAGER - CALL ONE TIME *BEFORE* DIALING +BOOL WINAPI InitRASManager(); + +// RETURNS THE NUMBER OF ACTIVE RAS CONNECTIONS +DWORD WINAPI GetNumActiveRASConnections(); + +// ENUMERATES ALL *ACTIVE* DIALUP CONNECTIONS. RETURN OF TRUE +// INDICATES THAT 0 - N CONNECTIONS WERE SUCCESSFULLY ENUMERATED, +// I.E. RETURN OF 0 DOES NOT INDICATE NO ACTIVE CONNECTIONS. +BOOL WINAPI EnumActiveRASConnections(LPRASENUMCALLBACK lpCallback, + LPVOID lpContext); + +// ENUMERATES ALL ACTIVE DIALUP CONNECTIONS THAT HAVE BEEN +// ESTABLISHED AFTER THE CALL TO InitRASManager(). RETURN OF TRUE +// INDICATES THAT 0 - N CONNECTIONS WERE SUCCESSFULLY ENUMERATED, +// I.E. RETURN OF 0 DOES NOT INDICATE NO ACTIVE CONNECTIONS. +BOOL WINAPI EnumNewRASConnections(LPRASENUMCALLBACK lpCallback, + LPVOID lpContext); + +// HANGS UP LINE. THIS FUNCTION WILL BLOCK UNTIL THE TAPI STATE +// MACHINE MANAGING THE COMM PORT HAS CLEANED UP THE PORT +BOOL WINAPI HangupRASConnection(LPVOID rashandle); + +#endif // __RASMGR_H diff --git a/Storm/SOURCE/BATTLE/RESOURCE.H b/Storm/SOURCE/BATTLE/RESOURCE.H new file mode 100644 index 0000000..f1ef531 --- /dev/null +++ b/Storm/SOURCE/BATTLE/RESOURCE.H @@ -0,0 +1,121 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by BATTLE.RC +// +#define IDD_DIALOG1 122 +#define ID_SCROLL_WINDOW 1000 +#define IDS_CHAT_HELP_RES 1000 +#define IDS_NAME_REQUIRED 1001 +#define IDC_AD 1001 +#define IDS_INVALID_ID 1002 +#define IDC_USERLIST 1003 +#define IDS_ASK_UPDATE 1003 +#define IDS_PREP_RESTART 1004 +#define IDC_CHATWINDOW 1005 +#define IDS_CHAT_JOIN_ROOM 1005 +#define IDC_CHATEDIT 1006 +#define IDS_CHAT_PLAYER_LEFT_ROOM 1006 +#define ID_CHATJOIN 1007 +#define IDS_CHAT_PLAYER_ENTERED_ROOM 1007 +#define ID_CHATCREATE 1008 +#define IDS_JOIN_FAILED 1008 +#define ID_SENDMSG 1009 +#define IDS_ERR_UNREACHABLE 1009 +#define ID_CHATLADDER 1009 +#define IDC_EDIT_NAME 1010 +#define IDS_BATTLENET 1010 +#define IDC_EDIT_PASSWORD 1011 +#define IDS_ERR_NOTRESPONDING 1011 +#define IDC_TYPE_PUBLIC 1012 +#define ID_CHAT_CHANNEL 1012 +#define IDS_ERR_UNABLETOUPGRADE 1012 +#define ID_CHATCHANNEL 1012 +#define IDC_TYPE_PRIVATE 1013 +#define IDS_ERR_DOWNLOADFAILED 1013 +#define IDS_DOWNLOADPROGRESS 1014 +#define IDS_WHISPER_FROM 1015 +#define IDS_WHISPER_TO 1016 +#define IDS_ERR_INVALIDBETAID 1017 +#define IDS_ERR_CANTWHISPER 1018 +#define IDS_CHANNEL_NAME_INVALID 1019 +#define IDC_COMBO1 1020 +#define IDC_CHAT_CHANNEL 1020 +#define IDS_FIRST_NASTY 1020 +#define IDC_COMBO_NAME 1020 +#define IDC_DIFFICULTY 1021 +#define IDS_NASTY0 1021 +#define IDC_EDIT1 1022 +#define IDS_NASTY1 1022 +#define IDC_GAMETYPE 1023 +#define IDS_NASTY2 1023 +#define IDC_PASS1 1023 +#define IDS_NASTY3 1024 +#define IDC_PASS2 1024 +#define IDS_NASTY4 1025 +#define IDS_NASTY5 1026 +#define IDC_LIST1 1027 +#define IDC_GAMELIST 1027 +#define IDS_LAST_NASTY 1027 +#define IDS_ERR_CHATNOTHINGTOSEND 1028 +#define IDC_STATIC_DESC 1029 +#define IDS_PROMPT_CREATECHANNEL 1029 +#define IDC_TITLE 1030 +#define IDS_CHANNEL_FULL 1030 +#define IDC_GAMEDESCRIPTION 1031 +#define IDS_CHANNEL_RESTRICTED 1031 +#define IDC_ANIMATE 1032 +#define IDS_ERR_BADCONNECTION 1032 +#define IDS_ERR_BADSERVICEPROVIDER 1033 +#define IDS_CHANNEL_FMT 1034 +#define ID_WHISPER 1035 +#define IDS_USERUNSQUELCHED_FMT 1035 +#define IDS_USERSQUELCHED_FMT 1036 +#define IDS_VERBOSE_FMT 1037 +#define IDC_EDIT_ID 1038 +#define IDS_NONVERBOSE_FMT 1038 +#define IDC_CHANNELLIST 1039 +#define IDS_ERR_NOWSOCK32 1039 +#define IDC_EDIT_ID2 1039 +#define IDC_LOGO_ANIMATE 1040 +#define IDS_QUERYBROWSEWEB 1040 +#define IDC_STATIC_TEXT 1041 +#define IDS_QUERYDISCONNECT 1041 +#define IDC_PROGRESS_TEXT 1042 +#define IDC_RADIO1 1042 +#define IDS_BROWSERERROR 1042 +#define IDC_UIGENERIC_PROGRESS 1043 +#define IDC_STATIC_DESC_HDR 1043 +#define IDS_ERR_HOST_UNREACHABLE 1043 +#define IDS_ERR_GAME_FULL 1044 +#define IDQUIT 1045 +#define IDS_ENTERPASSWORD 1045 +#define IDC_STATIC_CHANNEL 1046 +#define IDS_RENAMECHARACTER 1046 +#define IDS_ERR_INVALIDPASSWORD 1047 +#define IDC_SCROLLBAR1 1048 +#define IDS_TITLE_INVALIDPASSWORD 1048 +#define IDC_USERLIST_SCROLLBAR 1049 +#define IDC_MSGLIST_SCROLLBAR 1050 +#define ID_VERBOSE 1051 +#define IDC_SCROLLBAR 1052 +#define IDC_NEWACCOUNT 1054 +#define IDS_NEWACCOUNT 1055 +#define IDC_LOGIN_ATTR 1056 +#define IDESCAPE 1058 +#define IDC_CUSTOM_NAM 1058 +#define IDC_COMBO3 1061 +#define IDC_PROFILE 1062 +#define IDC_FILTER 1063 +#define IDC_NAME 1064 +#define IDS_PASSWORD_MISMATCH 1065 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1065 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SOURCE/BATTLE/SCRLLBAR.CPP b/Storm/SOURCE/BATTLE/SCRLLBAR.CPP new file mode 100644 index 0000000..63eebd2 --- /dev/null +++ b/Storm/SOURCE/BATTLE/SCRLLBAR.CPP @@ -0,0 +1,890 @@ +/*************************************************************************** +* +* scrllbar.cpp +* +* By Michael Morhaime +* +* Custom Scrollbar control used by listbox. +* +* +* +* NOTES: ScrollbarLink() must be called to setup the link between the scrollbar and the +* window that will receive notify messages. +* +* ListUpdateScrollbar() This routine should be called whenever the scroll position, +* scroll range, or page size changes. The scrollbar must +* be notified whenever the listbox generates LBN_SELCHANGE +* messages as they may be the result of a scroll. The scrollbar +* will query the listbox to get the appropriate information. +* You could also send the scrollbar SBM_SETSCROLLINFO messages +* manually if you wish. +* +* EditUpdateScrollbar() This is the equivalent of the above routine when the linked +* window is an Edittext control. +***/ + +#include "pch.h" + + + +#define NUM_ARROWS 4 // Number of arrows expected in art file (up/down) +#define REPEAT_RATE 100 // repeat every 100 millisec's + +static int sgnCreateCnt = 0; // Allow more than one scrollbar to share artwork +static LPBYTE sgBmpArrows = NULL; +static LPBYTE sgBmpThumb = NULL; +static LPBYTE sgBmpBar = NULL; + +static SIZE sgSizeArrows; +static SIZE sgSizeThumb; +static SIZE sgSizeBar; + +static int sgnArrowHgt; +static int sgnThumbHgt; +static int sgnBarHgt; + +static HWND sghPrevCapture; + +typedef struct _ScrollBmp { + LPBYTE data; + SIZE datasize; +} TSCROLLBMP, * PTSCROLLBMP; + +typedef struct _ScrollRects { + RECT rectArrowUp; + RECT rectArrowDown; + RECT rectThumb; + RECT rectBar; +} TSCROLLRECTS, * PTSCROLLRECTS; + +typedef struct _ScrollDrag { + union { + unsigned fModes; + struct _clicked { + unsigned ArrowUp :1; + unsigned ArrowDown :1; + unsigned PageUp :1; + unsigned PageDown :1; + unsigned Thumb :1; + } Clicked; + } dm; +} TSCROLLDRAG, * PTSCROLLDRAG; + +#define PROP_SCROLLBMP "ScrollBitmap" +#define PROP_SCROLLRECTS "ScrollRects" +#define PROP_SCROLLPARENT "ScrollParent" +#define PROP_SCROLLINFO "ScrollInfo" +#define PROP_SCROLLDRAG "ScrollDrag" + + +//**************************************************************************** +//**************************************************************************** +void ScrollbarLoadArtwork(SNETGETARTPROC artcallback) { + if (!sgnCreateCnt++) { + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_SCROLLBARARROWS, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgBmpArrows, + &sgSizeArrows); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_SCROLLTHUMB, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgBmpThumb, + &sgSizeThumb); + + UiLoadArtwork( + artcallback, + NULL, + NULL, + SNET_ART_SCROLLBAR, + TEXT(""), + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + FALSE, + FALSE, + &sgBmpBar, + &sgSizeBar); + + // Calculate pixel heights of components + sgnThumbHgt = sgSizeThumb.cy; + sgnArrowHgt = sgSizeArrows.cy/NUM_ARROWS; + sgnBarHgt = sgSizeBar.cy; + } + +} + +//**************************************************************************** +//**************************************************************************** +void ScrollbarDestroyArtwork(void) { + // Only Destroy if this if the only scrollbar currently using the artwork + if (--sgnCreateCnt) + return; + + if (sgBmpArrows) { + FREE(sgBmpArrows); + sgBmpArrows = NULL; + } + + if (sgBmpThumb) { + FREE(sgBmpThumb); + sgBmpThumb = NULL; + } + + if (sgBmpBar) { + FREE(sgBmpBar); + sgBmpBar = NULL; + } + +} +//**************************************************************************** +//**************************************************************************** +static BOOL ScrollbarCreate(HWND window) { + RECT rWnd; + PTSCROLLBMP pTBmp = NULL; + PTSCROLLRECTS pTRects = NULL; + LPSCROLLINFO pScrollInfo = NULL; + PTSCROLLDRAG pScrollDrag = NULL; + + + if (!sgBmpArrows || !sgBmpThumb | !sgBmpBar) + return 0; + + GetClientRect(window, &rWnd); + pTBmp = (PTSCROLLBMP) ALLOC(sizeof(TSCROLLBMP)); + if (!pTBmp) + return 0; + + pTBmp->data = (LPBYTE) ALLOC(rWnd.right*rWnd.bottom); + if (!pTBmp->data) { + FREE(pTBmp); + return 0; + } + + ZeroMemory(pTBmp->data, rWnd.right*rWnd.bottom); + memset(pTBmp->data, 2, rWnd.right*rWnd.bottom); //xxx del + + pTBmp->datasize.cx = rWnd.right; + pTBmp->datasize.cy = rWnd.bottom; + SetProp(window, PROP_SCROLLBMP, (HANDLE) pTBmp); + + + SDlgSetBitmap( + window, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + pTBmp->data, + NULL, + rWnd.right, + rWnd.bottom + ); + + + // Initialize hit detection rects + pTRects = (PTSCROLLRECTS) ALLOC(sizeof(TSCROLLRECTS)); + if (!pTRects) + return 0; + + SetRect(&pTRects->rectArrowUp, 0, 0, rWnd.right, sgnArrowHgt); + SetRect(&pTRects->rectArrowDown, 0, rWnd.bottom - sgnArrowHgt, rWnd.right, rWnd.bottom); + SetRect(&pTRects->rectThumb, 0, sgnArrowHgt, rWnd.right, sgnArrowHgt + sgnThumbHgt); + SetRect(&pTRects->rectBar, 0, sgnArrowHgt, rWnd.right, rWnd.bottom - sgnArrowHgt); + SetProp(window, PROP_SCROLLRECTS, (HANDLE) pTRects); + + + pScrollInfo = (SCROLLINFO *)ALLOC(sizeof(SCROLLINFO)); + if (!pScrollInfo) + return 0; + ZeroMemory(pScrollInfo, sizeof(SCROLLINFO)); + pScrollInfo->cbSize = sizeof(SCROLLINFO); + SetProp(window, PROP_SCROLLINFO, (HANDLE) pScrollInfo); + + + pScrollDrag = (PTSCROLLDRAG)ALLOC(sizeof(TSCROLLDRAG)); + if (!pScrollDrag) + return 0; + ZeroMemory(pScrollDrag, sizeof(TSCROLLDRAG)); + SetProp(window, PROP_SCROLLDRAG, (HANDLE) pScrollDrag); + + return 1; +} + + +//**************************************************************************** +//**************************************************************************** +static void ScrollbarDestroy(HWND window) { + PTSCROLLBMP pTBmp; + PTSCROLLRECTS pTRects; + PTSCROLLDRAG pScrollDrag; + SCROLLINFO *pScrollInfo; + + + pTBmp = (PTSCROLLBMP)RemoveProp(window, PROP_SCROLLBMP); + if (pTBmp) { + if (pTBmp->data) { + FREE(pTBmp->data); + } + FREE(pTBmp); + } + + pTRects = (PTSCROLLRECTS)RemoveProp(window, PROP_SCROLLRECTS); + if (pTRects) + FREE(pTRects); + + pScrollInfo = (SCROLLINFO *)RemoveProp(window, PROP_SCROLLINFO); + if (pScrollInfo) + FREE(pScrollInfo); + + pScrollDrag = (PTSCROLLDRAG)RemoveProp(window, PROP_SCROLLDRAG); + if (pScrollDrag) + FREE(pScrollDrag); + + RemoveProp(window, PROP_SCROLLPARENT); +} + +//**************************************************************************** +//**************************************************************************** +static void ScrollbarDraw (HWND window) { + PTSCROLLBMP pTBmp; + PTSCROLLRECTS pTRects; + + RECT r; + + pTBmp = (PTSCROLLBMP)GetProp(window, PROP_SCROLLBMP); + pTRects = (PTSCROLLRECTS)GetProp(window, PROP_SCROLLRECTS); + + if (!pTBmp || !pTRects) + return; + + // Draw Arrows + r = pTRects->rectArrowUp; + SBltROP3 ( + pTBmp->data + (r.top * pTBmp->datasize.cx) + r.left, + sgBmpArrows, + r.right - r.left, + r.bottom - r.top, + pTBmp->datasize.cx, + sgSizeArrows.cx, + NULL, + SRCCOPY + ); + + r = pTRects->rectArrowDown; + SBltROP3 ( + pTBmp->data + (r.top * pTBmp->datasize.cx) + r.left, + sgBmpArrows + (sgnArrowHgt*sgSizeArrows.cx), + r.right - r.left, + r.bottom - r.top, + pTBmp->datasize.cx, + sgSizeArrows.cx, + NULL, + SRCCOPY + ); + + RECT rSrc, rDst; + SetRect(&rSrc, 0, 0, pTBmp->datasize.cx, sgSizeBar.cy); + rDst = pTRects->rectBar; + + SBltROP3Tiled ( + pTBmp->data, + &rDst, + pTBmp->datasize.cx, + sgBmpBar, + &rSrc, + sgSizeBar.cx, + 0, + 0, + NULL, + SRCCOPY); + + r = pTRects->rectThumb; + SBltROP3 ( + pTBmp->data + (r.top * pTBmp->datasize.cx) + r.left, + sgBmpThumb, + r.right - r.left, + r.bottom - r.top, + pTBmp->datasize.cx, + sgSizeThumb.cx, + NULL, + SRCCOPY + ); +} + + +//**************************************************************************** +//**************************************************************************** +int MouseToScrollPos(POINT *pt, PTSCROLLRECTS pTRects, LPSCROLLINFO pScrollInfo) { + int nScrollRange; + int nPixRange; + int nScrollPos; + int y; + + + + nScrollRange = pScrollInfo->nMax - pScrollInfo->nMin; + if (nScrollRange == 0) + return 0; + + // Make sure we don't treat a negative y value as a large positive value. + y = (int)pt->y; + if (y < pTRects->rectBar.top) + y = pTRects->rectBar.top; + + nPixRange = pTRects->rectBar.bottom - pTRects->rectBar.top - sgnThumbHgt; + nScrollPos = (y - pTRects->rectBar.top) * nScrollRange / nPixRange; + nScrollPos += pScrollInfo->nMin; + + // bound scrollpos to scroll range + if (nScrollPos < pScrollInfo->nMin) + nScrollPos = pScrollInfo->nMin; + if (nScrollPos > pScrollInfo->nMax) + nScrollPos = pScrollInfo->nMax; + + return nScrollPos; +} + + +//**************************************************************************** +//**************************************************************************** +static void ScrollbarPaint (HWND window) { + PAINTSTRUCT ps; + HDC dc = BeginPaint(window,&ps); + + // PAINT THE BITMAP + SDlgDrawBitmap(window,SDLG_USAGE_BACKGROUND,(HRGN)0); + EndPaint(window,&ps); +} + + + +//**************************************************************************** +//**************************************************************************** +static void ScrollbarUpdate(HWND window) { + SCROLLINFO *pScrollInfo = (SCROLLINFO *) GetProp(window, PROP_SCROLLINFO); + PTSCROLLRECTS pTRects = (PTSCROLLRECTS) GetProp(window, PROP_SCROLLRECTS); + int nScrollRange, nPixRange; + int nNewPos; + + if (!pScrollInfo) + return; + + // Update Thumb position + nScrollRange = pScrollInfo->nMax - pScrollInfo->nMin; + if (nScrollRange == 0) { + ShowWindow(window, SW_HIDE); + return; + } + + nPixRange = pTRects->rectBar.bottom - pTRects->rectBar.top - sgnThumbHgt; + nNewPos = (pScrollInfo->nPos-pScrollInfo->nMin) * nPixRange / nScrollRange; + nNewPos += pTRects->rectBar.top; + if (nNewPos == pTRects->rectThumb.top) + return; + + OffsetRect(&pTRects->rectThumb, 0, nNewPos - pTRects->rectThumb.top); + ScrollbarDraw(window); + InvalidateRect(window, NULL, FALSE); +} + + +//**************************************************************************** +//**************************************************************************** +void ScrollDragThumb(HWND window, POINT *pt, PTSCROLLRECTS pTRects, LPSCROLLINFO pScrollInfo) { + int nTarget; + + // Position cursor in middle of thumb + pt->y -= sgnThumbHgt/2; + + // Move the thumb to where the mouse is. + if (pt->y < pTRects->rectBar.top) + nTarget = pTRects->rectBar.top; + else if (pt->y > pTRects->rectBar.bottom - sgnThumbHgt) + nTarget = pTRects->rectBar.bottom - sgnThumbHgt; + else + nTarget = pt->y; + + OffsetRect(&pTRects->rectThumb, 0, nTarget - pTRects->rectThumb.top); + ScrollbarDraw(window); + InvalidateRect(window, NULL, FALSE); //&pTRects->rectThumb, FALSE); +} + +//**************************************************************************** +//**************************************************************************** +static void ScrollbarScroll(HWND window, int nAmount) { + SCROLLINFO *pScrollInfo = (SCROLLINFO *) GetProp(window, PROP_SCROLLINFO); + int nPosSave; + + if (!pScrollInfo) + return; + + nPosSave = pScrollInfo->nPos; + pScrollInfo->nPos += nAmount; + if (pScrollInfo->nPos < pScrollInfo->nMin) + pScrollInfo->nPos = pScrollInfo->nMin; + if (pScrollInfo->nPos > pScrollInfo->nMax) + pScrollInfo->nPos = pScrollInfo->nMax; + + if (nPosSave != pScrollInfo->nPos) + ScrollbarUpdate(window); +} + + + +//**************************************************************************** +//**************************************************************************** +static BOOL ScrollbarSetPos(HWND window, int nPos, BOOL bRedraw) { + LPSCROLLINFO pScrollInfo = (LPSCROLLINFO) GetProp(window, PROP_SCROLLINFO); + int nPosSave; + + if (!pScrollInfo) + return 0; + + nPosSave = pScrollInfo->nPos; + pScrollInfo->nPos = nPos; + if (pScrollInfo->nPos < pScrollInfo->nMin) + pScrollInfo->nPos = pScrollInfo->nMin; + if (pScrollInfo->nPos > pScrollInfo->nMax) + pScrollInfo->nPos = pScrollInfo->nMax; + + if (nPosSave != pScrollInfo->nPos) { + ScrollbarUpdate(window); + return nPosSave; + } + + return 0; + +} + +//**************************************************************************** +//**************************************************************************** +static BOOL ScrollbarSetRange(HWND window, int nMin, int nMax) { + LPSCROLLINFO pScrollInfo = (LPSCROLLINFO) GetProp(window, PROP_SCROLLINFO); + int nSavePos; + + if (!pScrollInfo) + return 0; + + if (pScrollInfo->nMin == nMin && pScrollInfo->nMax == nMax) { + return 0; + } + + if (nMin == nMax && pScrollInfo->nMin != pScrollInfo->nMax) { + if (!(pScrollInfo->fMask & SIF_DISABLENOSCROLL)) + ShowWindow(window, SW_HIDE); + else + EnableWindow(window, FALSE); + } + else if (nMin != nMax && pScrollInfo->nMin == pScrollInfo->nMax) { + EnableWindow(window, TRUE); + ShowWindow(window, SW_SHOW); + } + + nSavePos = pScrollInfo->nPos; + pScrollInfo->nMin = nMin; + pScrollInfo->nMax = nMax; + if (pScrollInfo->nPos < pScrollInfo->nMin) + pScrollInfo->nPos = pScrollInfo->nMin; + if (pScrollInfo->nPos > pScrollInfo->nMax) + pScrollInfo->nPos = pScrollInfo->nMax; + ScrollbarUpdate(window); + return nSavePos; +} + +//**************************************************************************** +//**************************************************************************** +static BOOL ScrollbarSetInfo(HWND window, LPSCROLLINFO lpsi) { + LPSCROLLINFO pScrollInfo = (LPSCROLLINFO) GetProp(window, PROP_SCROLLINFO); + + if (!pScrollInfo) + return 0; + + if (lpsi->fMask & SIF_PAGE) + pScrollInfo->nPage = lpsi->nPage; + + if (lpsi->fMask & SIF_RANGE) + ScrollbarSetRange(window, lpsi->nMin, lpsi->nMax); + + if (lpsi->fMask & SIF_POS) + ScrollbarSetPos(window, lpsi->nPos, TRUE); + + + return pScrollInfo->nPos; +} + + +//**************************************************************************** +//**************************************************************************** +static void ScrollbarBtnDown(HWND window, int x, int y) { + PTSCROLLRECTS pTRects; + SCROLLINFO *pScrollInfo; + PTSCROLLDRAG pScrollDrag; + POINT pt; + HWND hWndParent; + int nNotify; + + // do hit detection + pTRects = (PTSCROLLRECTS) GetProp(window, PROP_SCROLLRECTS); + hWndParent = (HWND) GetProp(window, PROP_SCROLLPARENT); + pScrollInfo = (SCROLLINFO *) GetProp(window, PROP_SCROLLINFO); + pScrollDrag = (PTSCROLLDRAG) GetProp(window, PROP_SCROLLDRAG); + + if (!pTRects || !hWndParent || !pScrollInfo || !pScrollDrag) + return; + + + pt.x = x; + pt.y = y; + + // Capture the mouse until the user releases the button + if (window != GetCapture()) + sghPrevCapture = SetCapture(window); + else { + // Are we scrolling using the thumbnail? + if (pScrollDrag->dm.Clicked.Thumb) { + ScrollDragThumb(window, &pt, pTRects, pScrollInfo); + SendMessage( + hWndParent, + WM_VSCROLL, + MAKEWPARAM(SB_THUMBTRACK,MouseToScrollPos(&pt, pTRects, pScrollInfo)), + (LPARAM)window); + return; + } + } + + + + if (PtInRect(&pTRects->rectArrowUp, pt)) { + if (pScrollDrag->dm.fModes && !pScrollDrag->dm.Clicked.ArrowUp) + return; + + if (!pScrollDrag->dm.Clicked.ArrowUp) { + // Set repeat rate for scrolling, and set mode flag + SDlgSetTimer(window, 0, REPEAT_RATE, NULL); + pScrollDrag->dm.Clicked.ArrowUp = 1; + } + + ScrollbarScroll(window, -1); + nNotify = MAKEWPARAM(SB_LINEUP,0); + } + else if (PtInRect(&pTRects->rectArrowDown, pt)) { + if (pScrollDrag->dm.fModes && !pScrollDrag->dm.Clicked.ArrowDown) + return; + + if (!pScrollDrag->dm.Clicked.ArrowDown) { + // Set repeat rate for scrolling, and set mode flag + SDlgSetTimer(window, 0, REPEAT_RATE, NULL); + pScrollDrag->dm.Clicked.ArrowDown = 1; + } + + ScrollbarScroll(window, 1); + nNotify = MAKEWPARAM(SB_LINEDOWN,0); + } + else if (PtInRect(&pTRects->rectBar, pt)) { + if (PtInRect(&pTRects->rectThumb, pt)) { + if (!pScrollDrag->dm.fModes) { + // Thumb doesn't use timer, just set a flag, we'll get mousemove because of GetCapture() + pScrollDrag->dm.Clicked.Thumb = 1; + return; + } + } + else if (pt.y < pTRects->rectThumb.top) { + if (pScrollDrag->dm.fModes && !pScrollDrag->dm.Clicked.PageUp) + return; + + if (!pScrollDrag->dm.Clicked.PageUp) { + // Set repeat rate for scrolling, and set mode flag + SDlgSetTimer(window, 0, REPEAT_RATE, NULL); + pScrollDrag->dm.Clicked.PageUp = 1; + } + + ScrollbarScroll(window, -(int)pScrollInfo->nPage); + nNotify = MAKEWPARAM(SB_THUMBPOSITION,pScrollInfo->nPos); + } + else { + if (pScrollDrag->dm.fModes && !pScrollDrag->dm.Clicked.PageDown) + return; + + if (!pScrollDrag->dm.Clicked.PageDown) { + // Set repeat rate for scrolling, and set mode flag + SDlgSetTimer(window, 0, REPEAT_RATE, NULL); + pScrollDrag->dm.Clicked.PageDown = 1; + } + + // page down + ScrollbarScroll(window, pScrollInfo->nPage); + nNotify = MAKEWPARAM(SB_THUMBPOSITION,pScrollInfo->nPos); + } + } + else { + // User didn't click in any hot regions + return; + } + + + // Notify attached window what to do + SendMessage(hWndParent, WM_VSCROLL, nNotify, (LPARAM) window); +} + +//**************************************************************************** +//**************************************************************************** +static void ScrollbarBtnUp(HWND window, int x, int y) { + // End capture, + if (window == GetCapture()) { + PTSCROLLDRAG pScrollDrag; + LPSCROLLINFO pScrollInfo; + PTSCROLLRECTS pTRects; + HWND hWndParent; + + pScrollDrag = (PTSCROLLDRAG) GetProp(window, PROP_SCROLLDRAG); + pScrollInfo = (LPSCROLLINFO) GetProp(window, PROP_SCROLLINFO); + pTRects = (PTSCROLLRECTS) GetProp(window, PROP_SCROLLRECTS); + hWndParent = (HWND) GetProp(window, PROP_SCROLLPARENT); + + ReleaseCapture(); + if (sghPrevCapture) SetCapture(sghPrevCapture); + SDlgKillTimer(window, 0); + + if (!pScrollDrag || !pScrollInfo || !pTRects || !hWndParent) + return; + + if (pScrollDrag->dm.Clicked.Thumb) { + POINT pt; + pt.x = x; + pt.y = y; + + ScrollDragThumb(window, &pt, pTRects, pScrollInfo); + pScrollInfo->nPos = MouseToScrollPos(&pt, pTRects, pScrollInfo); + + SendMessage(hWndParent, WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL,pScrollInfo->nPos), (LPARAM) window); + } + + // Clear Drag Modes + pScrollDrag->dm.fModes = 0; + } + +} + + +//**************************************************************************** +//**************************************************************************** +static LRESULT CALLBACK StormScrollbarWndProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_COMMAND: + if (HIWORD(wparam) == LBN_SELCHANGE) { + ListUpdateScrollbar((HWND)lparam); + return 0; + } + break; + + case WM_CREATE: + if (!ScrollbarCreate(window)) + return -1; + + ScrollbarDraw(window); + break; + + case WM_DESTROY: + ScrollbarDestroy(window); + break; + + case WM_LBUTTONDOWN: + // cast mouse coords to short to force sign extension + ScrollbarBtnDown(window, (short)LOWORD(lparam), (short)HIWORD(lparam)); + return 0; + + case WM_LBUTTONUP: + // cast mouse coords to short to force sign extension + ScrollbarBtnUp(window, (short)LOWORD(lparam), (short)HIWORD(lparam)); + break; + + case WM_MOUSEMOVE: + if (window == GetCapture()) { + PTSCROLLDRAG pScrollDrag = (PTSCROLLDRAG) GetProp(window, PROP_SCROLLDRAG); + + if (!pScrollDrag) + break; + + // Only worry about MouseMove messages if we're dragging the thumb around + if (pScrollDrag->dm.Clicked.Thumb) { + // cast mouse coords to short to force sign extension + ScrollbarBtnDown(window, (short)LOWORD(lparam), (short)HIWORD(lparam)); + } + } + break; + + case WM_PAINT: + ScrollbarPaint(window); + return 0; + + case WM_STORMSCROLL_INIT: + SetProp(window, PROP_SCROLLPARENT, (HANDLE)lparam); + ShowWindow(window, SW_HIDE); // Default to hidden unless we support 'disabled' scrollbar + return 0; + + case WM_TIMER: + POINT pt; + + // Make sure we are still capturing the mouse + if (window != GetCapture()) + return 0; + GetCursorPos(&pt); + ScreenToClient(window, &pt); + ScrollbarBtnDown(window, pt.x, pt.y); + return 0; + + case SBM_GETPOS: + break; + + case SBM_GETRANGE: + break; + + case SBM_SETPOS: + return ScrollbarSetPos(window, wparam, (BOOL)lparam); + + case SBM_SETRANGE: + return ScrollbarSetRange(window, wparam, lparam); + + case SBM_SETRANGEREDRAW: + BOOL bReturn; + bReturn = ScrollbarSetRange(window, wparam, lparam); + return bReturn; + + + case SBM_SETSCROLLINFO: + return ScrollbarSetInfo(window, (LPSCROLLINFO)lparam); + + case SBM_GETSCROLLINFO: + return FALSE; + + + + } + return DefWindowProc(window,message,wparam,lparam); +} + + +//**************************************************************************** +//* +//* EXPORTED FUNCTIONS +//* +//**************************************************************************** + +//**************************************************************************** +int ScrollbarGetWidth(void) { + return (int)sgSizeArrows.cx; +} + +//**************************************************************************** +void ScrollbarLink(HWND hWndList, HWND hWndScroll) { + if (hWndList) { + SendMessage(hWndScroll, WM_STORMSCROLL_INIT, 0, (LPARAM)hWndList); + SetWindowLong(hWndList, GWL_USERDATA, (LONG)hWndScroll); + } +} + +//**************************************************************************** +void ListUpdateScrollbar(HWND hWndList) { + HWND hWndScroll; + RECT r; + int min, max; + int nPixHt, nItems, nItemsInWindow; + + hWndScroll = (HWND)GetWindowLong(hWndList, GWL_USERDATA); + if (hWndScroll == NULL) + return; + + GetClientRect(hWndList, &r); + nPixHt = SendMessage(hWndList, LB_GETITEMHEIGHT, 0, 0); + nItems = SendMessage(hWndList, LB_GETCOUNT, 0, 0); + if (!nPixHt) + return; + nItemsInWindow = r.bottom/nPixHt; + + GetClientRect(hWndList, &r); + + min = max = 0; + if (nPixHt != LB_ERR && nItems != LB_ERR) { + max = nItems - nItemsInWindow; + + if (max < 0) + max = 0; + } + else { + max = 0; + } + + + SCROLLINFO si; + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE; + si.nPos = SendMessage(hWndList, LB_GETTOPINDEX, 0, 0); + si.nMin = min; + si.nMax = max; + si.nPage = nItemsInWindow-1; + SendMessage(hWndScroll, SBM_SETSCROLLINFO, TRUE, (LPARAM)&si); +} + +//**************************************************************************** +void EditUpdateScrollbar(HWND hWndEdit) { + HWND hWndScroll; + int min, max; + int nItems; + + hWndScroll = (HWND)GetWindowLong(hWndEdit, GWL_USERDATA); + if (hWndScroll == NULL) + return; + + nItems = SendMessage(hWndEdit, EM_GETLINECOUNT, 0, 0); + + min = 0; + max = nItems-1; + + SCROLLINFO si; + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE; + si.nPos = 0; // don't know how to get current line from edit control! + si.nMin = min; + si.nMax = max; + si.nPage = 10; // arbitrary number + SendMessage(hWndScroll, SBM_SETSCROLLINFO, TRUE, (LPARAM)&si); +} + +//**************************************************************************** +//**************************************************************************** +void ScrollbarRegisterClass (void) { + WNDCLASS wndclass; + ZeroMemory(&wndclass,sizeof(WNDCLASS)); + wndclass.style = CS_GLOBALCLASS; + wndclass.lpfnWndProc = StormScrollbarWndProc; + wndclass.hInstance = global_hinstance; + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.lpszClassName = "StormScrollbar"; + RegisterClass(&wndclass); +} + +//**************************************************************************** +//**************************************************************************** +void ScrollbarUnregisterClass (void) { + UnregisterClass("StormScrollbar", global_hinstance); +} diff --git a/Storm/SOURCE/BATTLE/SPI.CPP b/Storm/SOURCE/BATTLE/SPI.CPP new file mode 100644 index 0000000..93f98f2 --- /dev/null +++ b/Storm/SOURCE/BATTLE/SPI.CPP @@ -0,0 +1,844 @@ +/**************************************************************************** +* +* SPI.CPP +* battle.net service provider interface functinos +* +* By Michael O'Brien (10/9/96) +* +***/ + +#include "pch.h" + +#define OVERHEADESTIMATE 39 // PPP, IP, and UDP headers + +#define PERF_PKTSENT 0 +#define PERF_PKTRECV 1 +#define PERF_BYTESSENT 2 +#define PERF_BYTESRECV 3 +#define PERFNUM 4 + +#define RECVDATATHREADS 2 + +typedef struct _EXTMSG { + char senderpath[SNETSPI_MAXSTRINGLENGTH]; // must be first field in structure + char sendername[SNETSPI_MAXSTRINGLENGTH]; + char message[MAXMESSAGESIZE]; + _EXTMSG *next; +} EXTMSG, *EXTMSGPTR; + +typedef struct _PACKET { + SNETADDR addr; // must be first field in structure + DWORD packettype; // must be immediately prior to data + BYTE data[MAXMESSAGESIZE]; + DWORD databytes; + _PACKET *next; +} PACKET, *PACKETPTR; + +typedef struct _THREAD { + unsigned id; + HANDLE handle; + _THREAD *next; +} THREAD, *THREADPTR; + +static SOCKET spi_datasocket = (SOCKET)0; +static CCritSect spi_extmsgcritsect; +static EXTMSGPTR spi_extmsghead = NULL; +static CCritSect spi_gamecritsect; +static SNETSPI_GAMELISTPTR spi_gamehead = NULL; +static CCritSect spi_packetcritsect; +static PACKETPTR spi_packethead = NULL; +static DWORD spi_perfdata[PERFNUM] = {0}; +static HANDLE spi_recvevent = (HANDLE)0; +static BOOL spi_shutdown = 0; +static THREADPTR spi_threadhead = NULL; + +static unsigned CALLBACK RecvDataThreadProc (LPVOID param); + +//=========================================================================== +static BOOL InitializeSockets () { + + // INITIALIZE THE RAS MANAGER + InitRASManager(); + + // INITIALIZE WINDOWS SOCKETS + { + WSADATA data; + if (WSAStartup(MAKEWORD(1,1),&data)) { + SpiDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + } + + // CREATE A LISTENING SOCKET + spi_datasocket = socket(AF_INET,SOCK_DGRAM,0); + if (!spi_datasocket) { + SpiDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + + // BIND TO THE SOCKET + { + sockaddr_in addr; + ZeroMemory(&addr,sizeof(sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(DATAPORT); + if (bind(spi_datasocket, + (const struct sockaddr *)&addr, + sizeof(sockaddr_in))) { + SpiDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + } + + // CREATE THREADS TO READ PACKETS FROM THE DATA SOCKET + { + BOOL win95 = GetVersion() & 0x80000000; + int threads = win95 ? 1 : RECVDATATHREADS; + for (int loop = 0; loop < threads; ++loop) { + THREAD thread; + thread.handle = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + RecvDataThreadProc, + NULL, + 0, + &thread.id); + if (thread.handle) { + SetThreadPriority(thread.handle,THREAD_PRIORITY_HIGHEST); + LISTADD(&spi_threadhead,&thread); + } + else { + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + } + + return 1; +} + +//=========================================================================== +static unsigned CALLBACK RecvDataThreadProc (LPVOID param) { + while (spi_datasocket && !spi_shutdown) { + + // ALLOCATE MEMORY FOR THE NEXT INCOMING PACKET + PACKETPTR pkt = NEW(PACKET); + + // RECEIVE A PACKET, BLOCKING IF ONE IS NOT AVAILABLE YET. WHEN THE + // NETWORK DRIVER HAS INCOMING DATA ON A PORT, IT WILL COPY IT DIRECTLY + // TO THE APPLICATION'S ADDRESS SPACE IF THE APPLICATION IS BLOCKING ON + // A READ. FOR THIS REASON, WE TRY TO ALWAYS HAVE AT LEAST ONE READ + // PENDING. + int addrsize = sizeof(sockaddr_in); + int bytesread = recvfrom(spi_datasocket, + (char *)&pkt->packettype, + sizeof(DWORD)+MAXMESSAGESIZE, + 0, + (sockaddr *)&pkt->addr, + &addrsize); + pkt->databytes = (bytesread >= sizeof(DWORD)) + ? (DWORD)bytesread-sizeof(DWORD) + : 0; + ZeroMemory(((LPBYTE)&pkt->addr)+min(8,addrsize),sizeof(SNETADDR)-min(8,addrsize)); + + // SINCE WE DON'T TIME OUT ON READS, THE ONLY WAY A READ CAN FAIL IS + // IF THE SOCKET WAS CLOSED. IN THIS CASE, SHUT DOWN THE THREAD. + if ((bytesread < 0) || spi_shutdown) { + FREE(pkt); + _endthreadex(0); + return 0; + } + + // ON A SUCCESSFUL READ, PROCESS THE PACKET + ++spi_perfdata[PERF_PKTRECV]; + spi_perfdata[PERF_BYTESRECV] += bytesread+OVERHEADESTIMATE; + switch (pkt->packettype) { + + case PKT_GAMEDATA: + spi_packetcritsect.Enter(); + LISTADDPTREND(&spi_packethead,pkt); + spi_packetcritsect.Leave(); + SetEvent(spi_recvevent); + break; + + case PKT_CLIENTREQ: + SrvProcessClientReq(&pkt->addr, + &pkt->data[0], + pkt->databytes); + FREE(pkt); + break; + + case PKT_SERVERPING: + SrvProcessServerPing(&pkt->data[0], + pkt->databytes); + FREE(pkt); + break; + + default: + FREE(pkt); + break; + + } + + } + _endthreadex(0); + return 0; +} + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +void SpiAddGame (SNETSPI_GAMELISTPTR game) { + + // CREATE A RECORD FOR THIS GAME + SNETSPI_GAMELISTPTR newgame = NEW(SNETSPI_GAMELIST); + if (!newgame) + return; + CopyMemory(newgame,game,sizeof(SNETSPI_GAMELIST)); + + // IF THIS GAME IS ALREADY IN THE LINKED LIST, REMOVE IT + spi_gamecritsect.Enter(); + SNETSPI_GAMELISTPTR *nextptr = &spi_gamehead; + while (*nextptr) + if (!memcmp(&(*nextptr)->owner,&newgame->owner,sizeof(sockaddr_in))) { + SNETSPI_GAMELISTPTR curr = *nextptr; + *nextptr = curr->next; + FREE(curr); + } + else + nextptr = &(*nextptr)->next; + + // ADD THIS GAME TO THE LINKED LIST OF GAMES + static DWORD idsequence = 0; + if (!(newgame->gameid = ++idsequence)) + newgame->gameid = ++idsequence; + newgame->next = NULL; + *nextptr = newgame; + spi_gamecritsect.Leave(); + +} + +//=========================================================================== +BOOL CALLBACK SpiCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude) { + if (diffmagnitude) + *diffmagnitude = 0; + if (!(addr1 && addr2 && diffmagnitude)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + sockaddr_in *inaddr1 = (sockaddr_in *)addr1; + sockaddr_in *inaddr2 = (sockaddr_in *)addr2; + if (inaddr1->sin_addr.S_un.S_un_b.s_b1 != + inaddr2->sin_addr.S_un.S_un_b.s_b1) + *diffmagnitude = 4; + else if (inaddr1->sin_addr.S_un.S_un_b.s_b2 != + inaddr2->sin_addr.S_un.S_un_b.s_b2) + *diffmagnitude = 3; + else if (inaddr1->sin_addr.S_un.S_un_b.s_b3 != + inaddr2->sin_addr.S_un.S_un_b.s_b3) + *diffmagnitude = 2; + else if (inaddr1->sin_addr.S_un.S_un_b.s_b4 != + inaddr2->sin_addr.S_un.S_un_b.s_b4) + *diffmagnitude = 1; + else + *diffmagnitude = 0; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiDestroy () { + + // START THE SHUTDOWN PROCESS + spi_shutdown = 1; + + // STOP ADVERTISING OUR GAME + SpiStopAdvertisingGame(); + + // DISCONNECT FROM THE BATTLENET SERVER + SrvDestroy(); + + // CLEAR THE EXTERNAL MESSAGE QUEUE + spi_extmsgcritsect.Enter(); + LISTCLEAR(&spi_extmsghead); + spi_extmsgcritsect.Leave(); + + // SEND DATA TO THE RECEIVE THREADS TO WAKE THEM UP + { + sockaddr_in addr; + ZeroMemory(&addr,sizeof(sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(DATAPORT); + addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); + char buffer[] = " "; + SOCKET newsocket = socket(AF_INET,SOCK_DGRAM,0); + for (int loop = 0; loop < RECVDATATHREADS; ++loop) + sendto(newsocket,buffer,1,0,(sockaddr *)&addr,sizeof(sockaddr_in)); + closesocket(newsocket); + } + + // WAIT FOR ALL THREADS TO TERMINATE + while (spi_threadhead) { + WaitForSingleObject(spi_threadhead->handle,INFINITE); + CloseHandle(spi_threadhead->handle); + LISTFREE(&spi_threadhead,spi_threadhead); + } + + // CLOSE THE DATA SOCKET + if (spi_datasocket) { + closesocket(spi_datasocket); + spi_datasocket = (SOCKET)0; + } + + // TAKE CONTROL OF THE PACKET CRITICAL SECTION + spi_packetcritsect.Enter(); + + // FREE ALL UNPROCESSED PACKETS + LISTCLEAR(&spi_packethead); + + // FREE THE GAME LIST + LISTCLEAR(&spi_gamehead); + + // CLEAN UP WINDOWS SOCKETS + WSACleanup(); + + // DESTROY OTHER MODULES + UiDestroy(); + CacheDestroy(); + + // LEAVE THE PACKET CRITICAL SECTION + spi_packetcritsect.Leave(); + + // FINISH THE SHUTDOWN PROCESS + spi_shutdown = 0; + + // ASK THE USER WHETHER HE WANTS TO HANG UP + UiDisconnect(); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiFree (SNETADDRPTR addr, + LPVOID data, + DWORD databytes) { + if (!(addr && data)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + FREE(addr); + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiFreeExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR message) { + if (!(senderpath && sendername && message)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + FREE((LPVOID)senderpath); + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiGetGameInfo (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + SNETSPI_GAMELIST *gameinfo) { + if (gameinfo) + ZeroMemory(gameinfo,sizeof(SNETSPI_GAMELIST)); + if (!(gamename && gameinfo && (gameid || *gamename))) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // CLEAR THE EXTERNAL MESSAGE QUEUE + spi_extmsgcritsect.Enter(); + LISTCLEAR(&spi_extmsghead); + spi_extmsgcritsect.Leave(); + + // ENTER THE CRITICAL SECTION + spi_gamecritsect.Enter(); + + // SEARCH FOR A GAME IN THE GAME LIST MATCHING THE QUERY PARAMETERS + SNETSPI_GAMELISTPTR found = NULL; + BOOL remove = 0; + { + SNETSPI_GAMELISTPTR curr = spi_gamehead; + while (curr) + if (((!gameid) || (gameid == curr->gameid)) && + ((!*gamename) || !_stricmp(gamename,curr->gamename))) { + found = curr; + break; + } + else + curr = curr->next; + } + + // IF WE DIDN'T FIND A MATCH, AND IF A GAME NAME BUT NO GAME ID WAS + // GIVEN, THEN REQUEST INFORMATION ABOUT THAT GAME FROM THE SERVER + // AND THEN SEARCH AGAIN. + if ((!found) && (gamename && !gameid)) { + if (!SrvIsWaitingForResponse()) { + spi_gamecritsect.Leave(); + SrvGetGameList(gamename,gamepassword,0,0,1); + spi_gamecritsect.Enter(); + } + SNETSPI_GAMELISTPTR curr = spi_gamehead; + while (curr) + if (!_stricmp(gamename,curr->gamename)) { + found = curr; + remove = 1; + break; + } + else + curr = curr->next; + } + + // IF WE FOUND A MATCH, COPY INFORMATION ABOUT THE MATCH INTO THE + // CALLER'S INFORMATION STRUCTURE + if (found) + CopyMemory(gameinfo,found,sizeof(SNETSPI_GAMELIST)); + if (remove) + LISTFREE(&spi_gamehead,found); + + // LEAVE THE GAME CRITICAL SECTION + spi_gamecritsect.Leave(); + + if (found) + return 1; + else { + SetLastError(SNET_ERROR_GAME_NOT_FOUND); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK SpiGetLocalPlayerName (LPSTR namebuffer, + DWORD namechars, + LPSTR descbuffer, + DWORD descchars) { + if (namebuffer && namechars) + SrvGetLocalPlayerName(namebuffer, + namechars); + if (descbuffer && descchars) + SrvGetLocalPlayerDesc(descbuffer, + descchars); + return TRUE; +} + + +//=========================================================================== +BOOL CALLBACK SpiGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + switch (counterid) { + + case SNET_PERFID_PKTSENTONWIRE: + *countervalue = spi_perfdata[PERF_PKTSENT]; + return 1; + + case SNET_PERFID_PKTRECVONWIRE: + *countervalue = spi_perfdata[PERF_PKTRECV]; + return 1; + + case SNET_PERFID_BYTESSENTONWIRE: + *countervalue = spi_perfdata[PERF_BYTESSENT]; + return 1; + + case SNET_PERFID_BYTESRECVONWIRE: + *countervalue = spi_perfdata[PERF_BYTESRECV]; + return 1; + + } + return 0; +} + +//=========================================================================== +BOOL CALLBACK SpiInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE event) { + + // SAVE THE PROGRAM AND VERSION IDS AND THE RECEIVE EVENT HANDLE + global_programid = programdata->programid; + global_versionid = programdata->versionid; + global_maxplayers = min(programdata->maxplayers,MAXPLAYERS); + spi_recvevent = event; + + // RESET PERFORMANCE DATA + ZeroMemory(&spi_perfdata[0],PERFNUM*sizeof(DWORD)); + + // INITIALIZE OTHER MODULES + CacheInitialize(); + UiInitialize(interfacedata); + + // BRING UP THE CONNECTION SCREEN + if (!UiBeginConnect(programdata, + interfacedata)) { + SrvDestroy(); + SpiDestroy(); + SetLastError(SNET_ERROR_INVALID_PARAMETER); + } + + // INITIALIZE SOCKETS + BOOL result = 1; + DWORD lasterror = 0; + UiProcessWindowMessages(); + if (!InitializeSockets()) { + UiWSockErrMessage(); + result = 0; + lasterror = GetLastError(); + } + + // CONNECT TO THE BATTLENET SERVER + if (result) { + UiProcessWindowMessages(); + if (!SrvInitialize(programdata,playerdata,versiondata)) { + result = 0; + lasterror = GetLastError(); + } + } + + // CLOSE THE CONNECTION SCREEN + UiEndConnect(result); + if (result) { + if (!UiLogon(programdata, + playerdata, + interfacedata, + versiondata)) { + lasterror = GetLastError(); + result = FALSE; + } + } + + // IF WE DIDN'T SUCCEED IN CONNECTING TO THE BATTLE.NET SERVER, + // SHUT DOWN THE SNP + if (!result) { + SpiDestroy(); + SetLastError(lasterror); + return 0; + } + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + + // WE NEVER RETURN ANY DEVICES, SO THIS FUNCTION SHOULD NEVER BE CALLED + return 0; +} + +//=========================================================================== +BOOL CALLBACK SpiLockDeviceList (SNETSPI_DEVICELISTPTR *devicelist) { + *devicelist = NULL; + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiLockGameList (DWORD categorybits, + DWORD categorymask, + SNETSPI_GAMELISTPTR *gamelist) { + if (!gamelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // CLEAR THE EXTERNAL MESSAGE QUEUE + spi_extmsgcritsect.Enter(); + LISTCLEAR(&spi_extmsghead); + spi_extmsgcritsect.Leave(); + + // GET A CURRENT LIST OF GAMES FROM THE SERVER + if (!SrvIsWaitingForResponse()) { + LISTCLEAR(&spi_gamehead); + char progvers[32]; + wsprintf(progvers,"%08x%08x",global_programid,global_versionid); + char lastgame[SNETSPI_MAXSTRINGLENGTH] = ""; + SRegLoadString("Recent Games",progvers,SREG_FLAG_BATTLENET,lastgame,SNETSPI_MAXSTRINGLENGTH); + if (lastgame[0]) + SrvGetGameList(lastgame,NULL,categorybits,categorymask,1); + SrvGetGameList(NULL,NULL,categorybits,categorymask,spi_gamehead ? 12 : 13); + } + + // ENTER THE GAME CRITICAL SECTION + spi_gamecritsect.Enter(); + + // UPDATE THE LATENCY FOR EACH GAME + { + SNETSPI_GAMELISTPTR curr = spi_gamehead; + while (curr) { + SrvGetLatency(&curr->owner,&curr->ownerlatency); + curr = curr->next; + } + } + + // RETURN THE GAME LIST TO THE CALLER + *gamelist = spi_gamehead; + + return 1; +} + +//=========================================================================== +void SpiQueueExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR message) { + spi_extmsgcritsect.Enter(); + EXTMSGPTR newptr = NEW(EXTMSG); + if (newptr) { + strncpy(newptr->senderpath,senderpath,SNETSPI_MAXSTRINGLENGTH); + strncpy(newptr->sendername,sendername,SNETSPI_MAXSTRINGLENGTH); + strncpy(newptr->message,message,MAXMESSAGESIZE); + newptr->senderpath[SNETSPI_MAXSTRINGLENGTH-1] = 0; + newptr->sendername[SNETSPI_MAXSTRINGLENGTH-1] = 0; + newptr->message[MAXMESSAGESIZE-1] = 0; + LISTADDPTREND(&spi_extmsghead,newptr); + } + spi_extmsgcritsect.Leave(); + SetEvent(spi_recvevent); +} + +//=========================================================================== +BOOL CALLBACK SpiReceive (SNETADDRPTR *addr, + LPVOID *data, + DWORD *databytes) { + if (addr) + *addr = NULL; + if (data) + *data = NULL; + if (databytes) + *databytes = NULL; + if (!(addr && data && databytes && spi_datasocket)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // IF THERE IS A PACKET QUEUED, REMOVE IT FROM THE QUEUE AND RETURN + // POINTERS TO THE CALLER. NOTE THAT WE UNLINK THE PACKET BUT DON'T + // FREE IT FROM MEMORY; IT IS THE CALLER'S RESPONSIBILITY TO CALL + // OUR FREE FUNCTION WHEN IT IS DONE WITH THE PACKET. + if (spi_packethead) { + spi_packetcritsect.Enter(); + *addr = &spi_packethead->addr; + *data = spi_packethead->data; + *databytes = spi_packethead->databytes; + spi_packethead = spi_packethead->next; + spi_packetcritsect.Leave(); + return 1; + } + else { + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK SpiReceiveExternalMessage (LPCSTR *senderpath, + LPCSTR *sendername, + LPCSTR *message) { + if (senderpath) + *senderpath = NULL; + if (sendername) + *sendername = NULL; + if (message) + *message = NULL; + if (!(senderpath && sendername && message)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // IF THERE IS A MESSAGE QUEUED, REMOVE IT FROM THE QUEUE AND RETURN + // POINTERS TO THE CALLER. NOTE THAT WE UNLINK THE MESSAGE BUT DON'T + // FREE IT FROM MEMORY; IT IS THE CALLER'S RESPONSIBILITY TO CALL + // OUR FREE FUNCTION WHEN IT IS DONE WITH THE PACKET. + if (spi_extmsghead) { + spi_extmsgcritsect.Enter(); + *senderpath = spi_extmsghead->senderpath; + *sendername = spi_extmsghead->sendername; + *message = spi_extmsghead->message; + spi_extmsghead = spi_extmsghead->next; + spi_extmsgcritsect.Leave(); + return 1; + } + else { + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK SpiSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + return UiSelectGame(flags, + programdata, + playerdata, + interfacedata, + versiondata, + playerid); +} + +//=========================================================================== +BOOL CALLBACK SpiSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes) { + if (!(addresses && + addrlist && data && databytes && (databytes <= MAXMESSAGESIZE) && + spi_datasocket)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // CREATE A FULLY FORMED PACKET + PACKET pkt; + pkt.packettype = PKT_GAMEDATA; + CopyMemory(&pkt.data[0],data,databytes); + + // SEND IT TO EACH TARGET ADDRESS + while (addresses--) { + sendto(spi_datasocket, + (const char *)&pkt.packettype, + sizeof(DWORD)+databytes, + 0, + (const sockaddr *)*(addrlist+addresses), + sizeof(sockaddr_in)); + ++spi_perfdata[PERF_PKTSENT]; + spi_perfdata[PERF_BYTESSENT] += sizeof(DWORD)+databytes+OVERHEADESTIMATE; + } + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiSendExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR targetpath, + LPCSTR targetname, + LPCSTR message) { + if ((!*targetpath) && (!*targetname)) + SrvSendChatString(message); + return 1; +} + +//=========================================================================== +BOOL SpiSendSpecial (SNETADDRPTR addr, + DWORD packettype, + LPVOID data, + DWORD databytes) { + if (!(addr && data && databytes && (databytes <= MAXMESSAGESIZE) && + spi_datasocket)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // CREATE A FULLY FORMED PACKET + PACKET pkt; + pkt.packettype = packettype; + CopyMemory(&pkt.data[0],data,databytes); + + // SEND IT TO THE TARGET ADDRESS + sendto(spi_datasocket, + (const char *)&pkt.packettype, + sizeof(DWORD)+databytes, + 0, + (const sockaddr *)addr, + sizeof(sockaddr_in)); + ++spi_perfdata[PERF_PKTSENT]; + spi_perfdata[PERF_BYTESSENT] += sizeof(DWORD)+databytes+OVERHEADESTIMATE; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD gameage, + DWORD gamecategorybits, + DWORD optcategorybits, + LPCVOID clientdata, + DWORD clientdatabytes) { + if (!(gamename && gamedescription)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // IF WE'RE NOT CONNECTED TO A BATTLENET SERVER, RETURN FAILURE + if (!SrvIsConnected()) { + SetLastError(SNET_ERROR_NOT_CONNECTED); + return 0; + } + + // SEND THE GAME INFORMATION TO THE BATTLENET SERVER + if (!SrvStartAdvertisingGame(gamename, + gamepassword, + gamedescription, + gamemode, + gameage, + gamecategorybits, + optcategorybits)) { + SetLastError(SNET_ERROR_ALREADY_EXISTS); + return 0; + } + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiStopAdvertisingGame () { + + // IF WE'RE NOT CONNECTED TO A BATTLENET SERVER, RETURN FAILURE + if (!SrvIsConnected()) { + SetLastError(SNET_ERROR_NOT_CONNECTED); + return 0; + } + + // TELL THE BATTLENET SERVER TO REMOVE THE GAME + SrvStopAdvertisingGame(); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiUnlockDeviceList (SNETSPI_DEVICELISTPTR devicelist) { + return 1; +} + +//=========================================================================== +BOOL CALLBACK SpiUnlockGameList (SNETSPI_GAMELISTPTR gamelist, + DWORD *hintnextcall) { + + // LEAVE THE GAME CRITICAL SECTION + spi_gamecritsect.Leave(); + + // TELL THE CALLER TO CALL BACK IN A SECOND TO GET AN UPDATED LIST + // OF LATENCIES + if (hintnextcall) + *hintnextcall = 1000; + + return 1; +} diff --git a/Storm/SOURCE/BATTLE/SRV.CPP b/Storm/SOURCE/BATTLE/SRV.CPP new file mode 100644 index 0000000..900c059 --- /dev/null +++ b/Storm/SOURCE/BATTLE/SRV.CPP @@ -0,0 +1,2546 @@ +/**************************************************************************** +* +* SRV.CPP +* battle.net server communication functions +* +* By Michael O'Brien (10/9/96) +* +***/ + +#include "pch.h" + +#ifdef _X86_ +#define PLATFORMID 'IX86' +#endif + +#define MAXLATENCY 2000 +#define PINGFREQUENCY 30000 +#define SERVERPORT 6112 +#define CONNTYPE_CLIENT 0x01 +#define CONNTYPE_FILE 0x02 +#define SERVERBUFFERSIZE 16384 +#define SERVERVERSION 1 +#define CONFIGREGKEY "Configuration" +#define CONFIGREGVALUE_PINGLIST "Ping List" +#define CONFIGREGVALUE_SERVERLIST "Server List" +#define CONFIGREGVALUE_SERVERVER "Server Version" +#define CONFIGREGVALUE_REGAUTH "Registration Authority" +#define CONFIGREGVALUE_REGVER "Registration Version" +#define CONFIGREGVALUE_CLIENTID "Client ID" +#define CONFIGREGVALUE_CLIENTCHECK "Client Token" +#define COOKIEREGKEY "Cookies" +#define PATCHREGKEY "Patch" +#define PATCHREGVALUE_LAUNCHER "Launcher" +#define PATCHREGVALUE_SRCDATA "SrcData" +#define PATCHREGVALUE_DSTDATA "DstData" +#define PATCHREGVALUE_PATCHES "Patches" + +#define CHAT_DISPLAYUSER 1 +#define CHAT_ADDUSER 2 +#define CHAT_REMOVEUSER 3 +#define CHAT_WHISPER 4 +#define CHAT_TALK 5 +#define CHAT_BROADCAST 6 +#define CHAT_JOINCHANNEL 7 +#define CHAT_USERFLAGS 9 +#define CHAT_WHISPERSENT 10 +#define CHAT_CHANNELISFULL 13 +#define CHAT_CHANNELDOESNOTEXIST 14 +#define CHAT_CHANNELISRESTRICTED 15 +#define CHAT_INFORMATION 18 +#define CHAT_ERROR 19 +#define CHAT_SQUELCH 21 +#define CHAT_UNSQUELCH 22 + +#define CLI_PING 0 +#define CLI_PINGRESPONSE 1 + +#define DOWNLOAD_VERSIONING 1 +#define DOWNLOAD_PATCH 2 +#define DOWNLOAD_AD 3 + +#define JCF_DEFAULTCHANNEL 0x00000001 +#define JCF_JOINALWAYS 0x00000002 + +#define SAVE_CACHE 0x00000001 +#define SAVE_DISK 0x00000002 + +#define SID_NULL 0x00 +#define SID_STARTADV 0x01 +#define SID_STOPADV 0x02 +#define SID_GETADVLIST 0x03 +#define SID_SERVERLIST 0x04 +#define SID_CLIENTID 0x05 +#define SID_STARTVERSIONING 0x06 +#define SID_REPORTVERSION 0x07 +#define SID_STARTADVEX 0x08 +#define SID_GETADVLISTEX 0x09 +#define SID_ENTERCHAT 0x0A +#define SID_GETCHANNELLIST 0x0B +#define SID_JOINCHANNEL 0x0C +#define SID_CHATCOMMAND 0x0E +#define SID_CHATEVENT 0x0F +#define SID_LEAVECHAT 0x10 +#define SID_LOCALEINFO 0x12 +#define SID_FLOODDETECTED 0x13 +#define SID_UDPPINGRESPONSE 0x14 +#define SID_CHECKAD 0x15 +#define SID_CLICKAD 0x16 +#define SID_QUERYMEM 0x17 +#define SID_QUERYREG 0x18 +#define SID_MESSAGEBOX 0x19 +#define SID_BROADCAST 0x20 +#define SID_DISPLAYAD 0x21 +#define SID_NOTIFYJOIN 0x22 +#define SID_SETCOOKIE 0x23 +#define SID_GETCOOKIE 0x24 +#define SID_PING 0x25 +#define SERVERIDS 0x26 + +#define VER_RESULT_BADVERSION 0 +#define VER_RESULT_UPGRADEREQUIRED 1 +#define VER_RESULT_CURRENT 2 + +#define WAIT_FLAG_INFINITE 0x00000001 +#define WAIT_FLAG_NOMESSAGELOOP 0x00000004 + +typedef struct _CONNECTREC { + SOCKET socket; + HANDLE thread; + _CONNECTREC *next; +} CONNECTREC, *CONNECTPTR; + +typedef struct _FILEREQ { + DWORD requestbytes; + DWORD platformid; + DWORD programid; + DWORD fileid; + DWORD filedatatype; + FILETIME filetime; + char filename[MAX_PATH]; + // the following fields are not sent to the server, and should not + // be reflected in requestbytes + char url[MAX_PATH]; + DWORD downloadtype; + DWORD savetype; +} FILEREQ, *FILEREQPTR; + +typedef struct _FILERESPONSE { + DWORD headerbytes; + DWORD filebytes; + DWORD fileid; + DWORD filedatatype; + FILETIME filetime; + char filename[MAX_PATH]; +} FILERESPONSE, *FILERESPONSEPTR; + +typedef struct _PINGREC { + sockaddr_in addr; + char username[SNETSPI_MAXSTRINGLENGTH]; + DWORD latency; + DWORD lastpingtime; + DWORD lastresponsetime; + _PINGREC *next; +} PINGREC, *PINGPTR; + +typedef struct _SRVMSG { + BYTE signature; + BYTE id; + WORD bytes; +} SRVMSG, *SRVMSGPTR; + +typedef struct _UINOTIFICATION { + DWORD notifycode; + LPVOID buffer; + DWORD parambytes; + _UINOTIFICATION *next; +} UINOTIFICATION, *UINOTIFICATIONPTR; + +static DWORD srv_adnumber = 0; +static DWORD srv_addisplaytime = 0; +static char srv_argstring[256] = ""; +static DWORD srv_authenticated = 0; +static BOOL srv_cancelwait = 0; +static CCritSect srv_connectcritsect; +static BOOL srv_connected = 0; +static CONNECTPTR srv_connecthead = NULL; +static LONG srv_connectthreads = 0; +static LONG srv_downloadthreads = 0; +static BOOL srv_inchat = 0; +static HANDLE srv_keepalivethread = (HANDLE)0; +static CCritSect srv_patchcritsect; +static char srv_patchfiles[256] = "\0"; +static DWORD srv_patchhighcomplete = 0; +static DWORD srv_patchpercent = 0; +static CCritSect srv_pingcritsect; +static PINGPTR srv_pinghead = NULL; +static BOOL srv_pingsuccess = 0; +static LONG srv_pingthreads = 0; +static BOOL srv_responded[SERVERIDS] = {0}; +static SOCKET srv_serversocket = (SOCKET)0; +static HANDLE srv_serverthread = (HANDLE)0; +static BOOL srv_shutdown = 0; +static HANDLE srv_shutdownevent = 0; +static BOOL srv_startadvsuccess = 0; +static DWORD srv_udppingdata = 0; +static CCritSect srv_uinotificationcritsect; +static UINOTIFICATIONPTR srv_uinotificationhead = NULL; +static LPVOID srv_uinotificationhold = NULL; +static char srv_userdesc[MAXSTRINGLENGTH] = ""; +static char srv_username[MAXSTRINGLENGTH] = ""; +static char srv_versionfile[MAX_PATH] = ""; +static HANDLE srv_waitevent = (HANDLE)0; +static LONG srv_waiting = 0; + +static void DeleteConnectThread (SOCKET socket); +static unsigned CALLBACK PingThreadProc (LPVOID param); +static void ProcessFile (DWORD downloadtype, + DWORD savetype, + DWORD fileid, + DWORD filedatatype, + FILETIME *filetime, + LPCSTR filename, + LPCSTR url, + LPVOID data, + DWORD databytes); +static void QueueUiNotification (DWORD notifycode, + LPVOID param, + DWORD parambytes, + LPCSTR *string1ptr, + LPCSTR *string2ptr); +static void RemovePingUser (LPCSTR username, sockaddr_in *addr); +static void RequestFile (DWORD downloadtype, + DWORD savetype, + DWORD fileid, + DWORD filedatatype, + FILETIME *filetime, + LPCSTR filename, + LPCSTR url); +static void SaveFile (LPCSTR filename, + LPVOID buffer, + DWORD bytes); +static BOOL SendServerMessage (BYTE id, LPVOID data, DWORD databytes); +static void UpdatePatchPercent (LPCSTR filename, + DWORD offset, + DWORD totalsize); +static BOOL WaitOnce (DWORD flags); + +//=========================================================================== +static void AddConnectThread (SOCKET socket) { + CONNECTPTR newptr = NEW(CONNECTREC); + if (!newptr) + return; + DuplicateHandle(GetCurrentProcess(), + GetCurrentThread(), + GetCurrentProcess(), + &newptr->thread, + 0, + 0, + DUPLICATE_SAME_ACCESS); + newptr->socket = socket; + srv_connectcritsect.Enter(); + LISTADDPTR(&srv_connecthead,newptr); + srv_connectcritsect.Leave(); +} + +//=========================================================================== +static void AddPingUser (LPCSTR username, sockaddr_in *addr) { + RemovePingUser(username,addr); + + // NORMALIZE THE ADDRESS TO POINT TO THE DATA PORT + sockaddr_in dataportaddr; + CopyMemory(&dataportaddr,addr,sizeof(sockaddr_in)); + dataportaddr.sin_port = htons(DATAPORT); + ZeroMemory(&dataportaddr.sin_zero[0],8); + + // CREATE A NEW RECORD FOR THIS USER + PINGPTR newptr = NEW(PINGREC); + if (newptr) + ZeroMemory(newptr,sizeof(PINGREC)); + else + return; + CopyMemory(&newptr->addr,&dataportaddr,sizeof(sockaddr_in)); + if (username) { + strncpy(newptr->username,username,SNETSPI_MAXSTRINGLENGTH); + newptr->username[SNETSPI_MAXSTRINGLENGTH-1] = 0; + } + newptr->lastpingtime = GetTickCount(); + + // ADD IT TO THE LINKED LIST OF PING USERS + srv_pingcritsect.Enter(); + newptr->next = srv_pinghead; + srv_pinghead = newptr; + srv_pingcritsect.Leave(); + + // SEND AN INITIAL PING MESSAGE TO THE USER + DWORD request = CLI_PING; + SpiSendSpecial((SNETADDRPTR)&dataportaddr, + PKT_CLIENTREQ, + &request, + sizeof(DWORD)); + +} + +//=========================================================================== +static BOOL CheckVersion (DWORD *revisionid, DWORD *checkvalue, LPSTR comment) { + if (revisionid) + *revisionid = 0; + if (checkvalue) + *checkvalue = 0; + if (comment) + *comment = 0; + + HSARCHIVE archive = (HSARCHIVE)0; + LPVOID buffer = NULL; + char dllname[MAX_PATH] = ""; + HSFILE file = (HSFILE)0; + HINSTANCE lib = (HINSTANCE)0; + BOOL success = 0; + + // OPEN THE MOPAQ ARCHIVE THAT WE JUST DOWNLOADED + if (!SFileOpenArchive(srv_versionfile,0,0,&archive)) + return 0; + + __try { + + // VERIFY THE SIGNATURE ON THE ARCHIVE FILE + DWORD authtype; + SFileAuthenticateArchive(archive,&authtype); + if ((authtype != SFILE_AUTH_UNABLETOAUTHENTICATE) && + (authtype < SFILE_AUTH_FIRSTAUTHENTIC)) + __leave; + + // EXTRACT THE EMBEDDED DLL + strcpy(dllname,srv_versionfile); + if (strchr(dllname,'.')) + *strchr(dllname,'.') = 0; + strcat(dllname,".dll"); + if (!SFileOpenFileEx(archive,dllname,0,&file)) + __leave; + DWORD size = SFileGetFileSize(file); + buffer = ALLOC(size); + if (!buffer) + __leave; + SFileReadFile(file,buffer,size,NULL,NULL); + { + HANDLE outfile = CreateFile(dllname, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (outfile != INVALID_HANDLE_VALUE) { + DWORD byteswritten; + WriteFile(outfile,buffer,size,&byteswritten,NULL); + CloseHandle(outfile); + } + else + __leave; + } + + // BIND TO THE DLL + lib = LoadLibrary(dllname); + if (!lib) + __leave; + BOOL (APIENTRY *checkrevision)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,DWORD *,DWORD *,LPSTR); + *(LPVOID *)&checkrevision = GetProcAddress(lib,"CheckRevision"); + if (!checkrevision) + __leave; + + // CALL THE REVISION CHECKING FUNCTION + char appfilename[MAX_PATH] = ""; + char stormfilename[MAX_PATH] = ""; + char providerfilename[MAX_PATH] = ""; + GetModuleFileName(GetModuleHandle(NULL),appfilename,MAX_PATH); + GetModuleFileName((HMODULE)global_hinstance,providerfilename,MAX_PATH); + { + strcpy(stormfilename,providerfilename); + LPSTR curr = stormfilename; + while (strchr(curr,':')) + curr = strchr(curr,':')+1; + while (strchr(curr,'\\')) + curr = strchr(curr,'\\')+1; + strcpy(curr,"storm.dll"); + } + success = checkrevision(appfilename, + stormfilename, + providerfilename, + srv_argstring, + revisionid, + checkvalue, + comment); + + } + __finally { + if (lib) + FreeLibrary(lib); + if (buffer) + FREE(buffer); + if (file) + SFileCloseFile(file); + if (archive) + SFileCloseArchive(archive); + DeleteFile(srv_versionfile); + if (dllname[0]) + DeleteFile(dllname); + } + + return success; +} + +//=========================================================================== +static unsigned CALLBACK ConnectThreadProc (LPVOID param) { + + // CREATE A NEW SOCKET + SOCKET newsocket = socket(PF_INET,SOCK_STREAM,0); + if (srv_serversocket || !newsocket) { + if (newsocket) + closesocket(newsocket); + InterlockedDecrement(&srv_connectthreads); + _endthreadex(0); + return 0; + } + AddConnectThread(newsocket); + + // PERFORM A DNS LOOKUP ON THIS SERVER + DWORD ipaddress; + if (isdigit(*(const char *)param)) + ipaddress = inet_addr((const char *)param); + else { + const hostent *host = gethostbyname((const char *)param); + if (srv_serversocket || !host) { + DeleteConnectThread(newsocket); + closesocket(newsocket); + InterlockedDecrement(&srv_connectthreads); + _endthreadex(0); + return 0; + } + ipaddress = *(LPDWORD)host->h_addr_list[0]; + } + + // CONNECT TO THE SERVER + { + sockaddr_in addr; + ZeroMemory(&addr,sizeof(sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SERVERPORT); + addr.sin_addr.S_un.S_addr = ipaddress; + if (connect(newsocket,(sockaddr *)&addr,sizeof(sockaddr_in))) { + DeleteConnectThread(newsocket); + closesocket(newsocket); + InterlockedDecrement(&srv_connectthreads); + _endthreadex(0); + return 0; + } + } + + // IF WE WERE THE FIRST THREAD TO CONNECT, SAVE THIS SOCKET. + // OTHERWISE, CLOSE IT. + static CCritSect critsect; + critsect.Enter(); + if (!srv_serversocket) + srv_serversocket = newsocket; + else + closesocket(newsocket); + critsect.Leave(); + + DeleteConnectThread(newsocket); + InterlockedDecrement(&srv_connectthreads); + _endthreadex(0); + return 0; +} + +//=========================================================================== +static BOOL ConnectToServer () { + + // CREATE A SHUTDOWN EVENT + srv_shutdownevent = CreateEvent(NULL,1,0,NULL); + + // READ THE CACHED LIST OF BATTLENET SERVERS FROM THE REGISTRY + static DWORD serverversion = 0; + static char serverlist[256] = ""; + SRegLoadValue(CONFIGREGKEY,CONFIGREGVALUE_SERVERVER,SREG_FLAG_BATTLENET,&serverversion); + if (serverversion == SERVERVERSION) + SRegLoadString(CONFIGREGKEY,CONFIGREGVALUE_SERVERLIST,SREG_FLAG_BATTLENET,serverlist,256); + + // IF THERE WASN'T A LIST IN THE REGISTRY, USE THE DEFAULT LIST + if (!serverlist[0]) + if (GetTickCount() & 1) + strcpy(serverlist,"206.79.254.192;exodus.battle.net"); + else + strcpy(serverlist,"206.79.254.193;exodus.battle.net"); + +#if STARCRAFT_BNBETA + strcpy(serverlist,"206.79.254.204"); +#endif + + // SPAWN THREADS TO ATTEMPT TO CONNECT SIMULTANEOUSLY TO EVERY SERVER + srv_connectthreads = 0; + { + char *server = strtok(serverlist," ,;"); + while (server && *server) { + unsigned threadid; + HANDLE threadhandle = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + ConnectThreadProc, + server, + 0, + &threadid); + if (threadhandle) { + InterlockedIncrement(&srv_connectthreads); + CloseHandle(threadhandle); + } + server = strtok(NULL," ,;"); + } + } + + // WAIT UNTIL ONE OF THE THREADS SUCCEEDS OR UNTIL ALL OF THE THREADS EXIT + while ((!srv_serversocket) && (srv_connectthreads > 0)) { + if (srv_cancelwait) { + srv_cancelwait = 0; + SetLastError(SNET_ERROR_CANCELLED); + return 0; + } + if (!UiProcessWindowMessages()) + return 0; + Sleep(10); + } + if (!srv_serversocket) { + srv_connectthreads = 0; + srv_pingsuccess = 0; + + // IF WE COULDN'T CONNECT, FIND OUT WHETHER IT'S BATTLE.NET'S FAULT + // OR A BAD NET CONNECTION BY TRYING TO CONNECT TO SOME OTHER WELL + // KNOWN SITES + static char pinglist[256] = ""; + SRegLoadString(CONFIGREGKEY,CONFIGREGVALUE_PINGLIST,SREG_FLAG_BATTLENET,pinglist,256); + + // IF THERE WASN'T A LIST IN THE REGISTRY, USE THE DEFAULT LIST + if (!pinglist[0]) + strcpy(pinglist,"206.79.254.116;206.79.240.58;38.8.8.2"); + + // SPAWN THREADS TO ATTEMPT TO CONNECT SIMULTANEOUSLY TO EVERY TARGET + srv_pingthreads = 0; + { + char *target = strtok(pinglist," ,;"); + while (target && *target) { + unsigned threadid; + HANDLE threadhandle = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + PingThreadProc, + target, + 0, + &threadid); + if (threadhandle) { + InterlockedIncrement(&srv_pingthreads); + CloseHandle(threadhandle); + } + target = strtok(NULL," ,;"); + } + } + + // WAIT UNTIL ALL OF THE THREADS EXIT + while (srv_pingthreads > 0) { + if (srv_cancelwait) { + srv_cancelwait = 0; + SetLastError(SNET_ERROR_CANCELLED); + return 0; + } + if (!UiProcessWindowMessages()) + return 0; + Sleep(10); + } + + // REPORT WHETHER WE WERE ABLE TO PING ANY OF THE TARGETS + DWORD error; + if (srv_pingsuccess) + error = SN_ERROR_UNREACHABLE; + else + error = SN_ERROR_BADCONNECTION; + QueueUiNotification(SN_FAILEDTOCONNECT,&error,sizeof(DWORD),NULL,NULL); + + return 0; + } + + return 1; +} + +//=========================================================================== +static void DeleteConnectThread (SOCKET socket) { + srv_connectcritsect.Enter(); + CONNECTPTR *nextptr = &srv_connecthead; + while (*nextptr) + if ((*nextptr)->socket == socket) { + CONNECTPTR curr = *nextptr; + *nextptr = curr->next; + FREE(curr); + } + else + nextptr = &(*nextptr)->next; + srv_connectcritsect.Leave(); +} + +//=========================================================================== +static void DestroyConnectThreads (DWORD phase) { + srv_connectcritsect.Enter(); + switch (phase) { + + case 1: + { + CONNECTPTR curr = srv_connecthead; + while (curr) { + closesocket(curr->socket); + curr = curr->next; + } + } + break; + + case 2: + while (srv_connecthead) { + TerminateThread(srv_connecthead->thread,0); + DeleteConnectThread(srv_connecthead->socket); + InterlockedDecrement(&srv_connectthreads); + } + break; + + } + srv_connectcritsect.Leave(); +} + +//=========================================================================== +static void DisconnectFromServer () { + srv_connected = 0; + if (srv_serversocket) { + closesocket(srv_serversocket); + srv_serversocket = (SOCKET)0; + } +} + +//=========================================================================== +static unsigned CALLBACK DownloadThreadProc (LPVOID param) { + LPBYTE buffer = NULL; + SOCKET newsocket = (SOCKET)0; + FILEREQPTR requestptr = (FILEREQPTR)param; + FILERESPONSEPTR responseptr = NULL; + __try { + + // GET THE ADDRESS OF THE SERVER WE'RE CONNECTED TO + sockaddr_in addr; + int addrlen = sizeof(sockaddr_in); + if ((!srv_serversocket) || + (getpeername(srv_serversocket,(sockaddr *)&addr,&addrlen) == SOCKET_ERROR)) + __leave; + + // CONNECT TO THE SERVER'S FILE DOWNLOAD PORT + addr.sin_port = htons(SERVERPORT); + ZeroMemory(&addr.sin_zero[0],8); + newsocket = socket(PF_INET,SOCK_STREAM,0); + if (!newsocket) + __leave; + if (connect(newsocket,(sockaddr *)&addr,sizeof(sockaddr_in))) + __leave; + + // SEND THE CONNECTION TYPE + BYTE conntype = CONNTYPE_FILE; + if (send(newsocket, + (const char *)&conntype, + sizeof(BYTE), + 0) != sizeof(BYTE)) + __leave; + + // SEND THE SERVER THE DOWNLOAD REQUEST + if (send(newsocket, + (const char *)requestptr, + requestptr->requestbytes, + 0) != (int)requestptr->requestbytes) + __leave; + + // WAIT FOR THE RETURNED FILE HEADER + DWORD headersize; + if (recv(newsocket, + (char *)&headersize, + sizeof(DWORD), + 0) != sizeof(DWORD)) + __leave; + responseptr = (FILERESPONSEPTR)ALLOC(headersize); + if (!responseptr) + __leave; + if (recv(newsocket, + ((char *)responseptr)+sizeof(DWORD), + headersize-sizeof(DWORD), + 0) != (int)(headersize-sizeof(DWORD))) + __leave; + + // ALLOCATE MEMORY FOR THE FILE + buffer = (LPBYTE)ALLOC(responseptr->filebytes); + if (!buffer) + __leave; + + // RECEIVE THE FILE + DWORD currpos = 0; + while (currpos < responseptr->filebytes) { + int bytes = recv(newsocket, + (char *)(buffer+currpos), + responseptr->filebytes-currpos, + 0); + if ((bytes == SOCKET_ERROR) || (bytes < 0)) + __leave; + currpos += (DWORD)bytes; + + // IF THIS IS A PATCH, UPDATE THE PERCENT COMPLETE + if (requestptr->downloadtype == DOWNLOAD_PATCH) + UpdatePatchPercent(responseptr->filename, + currpos, + responseptr->filebytes); + + } + + // SAVE IT + if (requestptr->savetype & SAVE_CACHE) + CacheSaveFile(responseptr->filename, + buffer, + responseptr->filebytes, + &responseptr->filetime, + 1296000, + 2592000); + if (requestptr->savetype & SAVE_DISK) + SaveFile(responseptr->filename, + buffer, + responseptr->filebytes); + + // PROCESS THE FILE + ProcessFile(requestptr->downloadtype, + requestptr->savetype, + responseptr->fileid, + responseptr->filedatatype, + &responseptr->filetime, + responseptr->filename, + requestptr->url, + buffer, + responseptr->filebytes); + + } + __finally { + if (buffer) + FREE(buffer); + if (responseptr) + FREE(responseptr); + if (newsocket) + closesocket(newsocket); + if (param) + FREE(param); + } + InterlockedDecrement(&srv_downloadthreads); + _endthreadex(0); + return 0; +} + +//=========================================================================== +static unsigned CALLBACK KeepAliveThreadProc (LPVOID) { + while (!srv_shutdown) + if (WaitForSingleObject(srv_shutdownevent,180000) != WAIT_OBJECT_0) + SendServerMessage(SID_NULL,NULL,0); + _endthreadex(0); + return 0; +} + +//=========================================================================== +static void OnBroadcast (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 1)) + return; + if (srv_inchat) { + SNDISPLAYSTRINGREC rec; + rec.sender = ""; + rec.senderflags = 0; + rec.string = (LPCSTR)data; + rec.stringtype = SN_STRING_BROADCAST; + QueueUiNotification(SN_DISPLAYSTRING,&rec,sizeof(SNDISPLAYSTRINGREC),&rec.sender,&rec.string); + } + else + SpiQueueExternalMessage("","",(LPCSTR)data); +} + +//=========================================================================== +static void OnChatEvent (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 2*sizeof(DWORD)+2)) + return; + DWORD eventid = *(LPDWORD)data; + DWORD flags = *((LPDWORD)data+1); + sockaddr_in *address = (sockaddr_in *)(data+2*sizeof(DWORD)); + LPCSTR username = (LPCSTR)data+sizeof(sockaddr_in)+2*sizeof(DWORD); + LPCSTR string = username+strlen(username)+1; + switch (eventid) { + + case CHAT_ADDUSER: + case CHAT_DISPLAYUSER: + { + SNADDUSERREC rec; + rec.name = username; + rec.description = string; + rec.flags = flags; + rec.notifyuser = (eventid == CHAT_ADDUSER); + QueueUiNotification(SN_ADDUSER,&rec,sizeof(SNADDUSERREC),&rec.name,&rec.description); + AddPingUser(username,address); + } + break; + + case CHAT_REMOVEUSER: + { + SNDELETEUSERREC rec; + rec.name = username; + rec.reason = string; + rec.notifyuser = 1; + QueueUiNotification(SN_DELETEUSER,&rec,sizeof(SNDELETEUSERREC),&rec.name,NULL); + RemovePingUser(username,address); + } + break; + + case CHAT_BROADCAST: + case CHAT_WHISPER: + case CHAT_TALK: + case CHAT_WHISPERSENT: + case CHAT_INFORMATION: + case CHAT_ERROR: + if (srv_inchat) { + SNDISPLAYSTRINGREC rec; + rec.sender = username; + rec.senderflags = flags; + rec.string = string; + rec.stringtype = 0; + switch (eventid) { + case CHAT_WHISPER: rec.stringtype = SN_STRING_WHISPER; break; + case CHAT_TALK: rec.stringtype = SN_STRING_TALK; break; + case CHAT_BROADCAST: rec.stringtype = SN_STRING_BROADCAST; break; + case CHAT_WHISPERSENT: rec.stringtype = SN_STRING_WHISPERSENT; break; + case CHAT_INFORMATION: rec.stringtype = SN_STRING_INFORMATION; break; + case CHAT_ERROR: rec.stringtype = SN_STRING_ERROR; break; + } + QueueUiNotification(SN_DISPLAYSTRING,&rec,sizeof(SNDISPLAYSTRINGREC),&rec.sender,&rec.string); + } + else + switch (eventid) { + + case CHAT_BROADCAST: + case CHAT_INFORMATION: + case CHAT_ERROR: + SpiQueueExternalMessage("","",string); + break; + + case CHAT_WHISPER: + { + char buffer[2*SNETSPI_MAXSTRINGLENGTH+16]; + wsprintf(buffer," %s",username,string); + SpiQueueExternalMessage("","",buffer); + } + break; + + case CHAT_WHISPERSENT: + { + char buffer[2*SNETSPI_MAXSTRINGLENGTH+16]; + wsprintf(buffer," %s",username,string); + SpiQueueExternalMessage("","",buffer); + } + break; + + } + break; + + case CHAT_JOINCHANNEL: + { + SNJOINCHANNELREC rec; + rec.name = string; + rec.flags = flags; + QueueUiNotification(SN_JOINCHANNEL,&rec,sizeof(SNJOINCHANNELREC),&rec.name,NULL); + RemovePingUser(NULL,NULL); + } + break; + + case CHAT_USERFLAGS: + { + SNCHANGEUSERFLAGSREC rec; + rec.name = username; + rec.flags = flags; + QueueUiNotification(SN_CHANGEUSERFLAGS,&rec,sizeof(SNCHANGEUSERFLAGSREC),&rec.name,NULL); + } + break; + + case CHAT_CHANNELISFULL: + QueueUiNotification(SN_CHANNELISFULL,(LPVOID)string,strlen(string)+1,NULL,NULL); + break; + + case CHAT_CHANNELDOESNOTEXIST: + QueueUiNotification(SN_CHANNELDOESNOTEXIST,(LPVOID)string,strlen(string)+1,NULL,NULL); + break; + + case CHAT_CHANNELISRESTRICTED: + QueueUiNotification(SN_CHANNELISRESTRICTED,(LPVOID)string,strlen(string)+1,NULL,NULL); + break; + + case CHAT_SQUELCH: + { + SNSQUELCHUSERREC rec; + rec.name = username; + rec.flags = flags; + QueueUiNotification(SN_SQUELCHUSER,&rec,sizeof(SNSQUELCHUSERREC),&rec.name,NULL); + } + break; + + case CHAT_UNSQUELCH: + { + SNSQUELCHUSERREC rec; + rec.name = username; + rec.flags = flags; + QueueUiNotification(SN_UNSQUELCHUSER,&rec,sizeof(SNSQUELCHUSERREC),&rec.name,NULL); + } + break; + + } +} + +//=========================================================================== +static void OnCheckAd (LPBYTE data, DWORD databytes) { + + // IF THE SERVER TOLD US TO KEEP DISPLAYING THE SAME AD WE'RE ALREADY + // DISPLAYING, JUST RETURN + if ((databytes < 2*sizeof(DWORD)+sizeof(FILETIME)+1) || + (*(LPDWORD)data == srv_adnumber)) + return; + srv_adnumber = *(LPDWORD)data; + + // OTHERWISE, PARSE THE REQUEST + DWORD newadnumber = *(LPDWORD)data; + DWORD newdatatype = *((LPDWORD)data+1); + FILETIME *newfiletime = (FILETIME *)((LPDWORD)data+2); + LPCSTR newfilename = (LPCSTR)(newfiletime+1); + LPCSTR newurl = newfilename+strlen(newfilename)+1; + if (!(*newfilename && *newurl)) + return; + + // GET THE FILE OUT OF OUR CACHE OR START DOWNLOADING IT + RequestFile(DOWNLOAD_AD, + SAVE_CACHE, + newadnumber, + newdatatype, + newfiletime, + newfilename, + newurl); + +} + +//=========================================================================== +static void OnClientId (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 4*sizeof(DWORD))) + return; + SRegSaveValue(CONFIGREGKEY,CONFIGREGVALUE_REGVER ,SREG_FLAG_BATTLENET,*(LPDWORD)data); + SRegSaveValue(CONFIGREGKEY,CONFIGREGVALUE_REGAUTH ,SREG_FLAG_BATTLENET,*((LPDWORD)data+1)); + SRegSaveValue(CONFIGREGKEY,CONFIGREGVALUE_CLIENTID ,SREG_FLAG_BATTLENET,*((LPDWORD)data+2)); + SRegSaveValue(CONFIGREGKEY,CONFIGREGVALUE_CLIENTCHECK,SREG_FLAG_BATTLENET,*((LPDWORD)data+3)); +} + +//=========================================================================== +static void OnEnterChat (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 1)) + return; + DWORD length = min(MAXSTRINGLENGTH-1,databytes); + CopyMemory(srv_username,data,length); + srv_username[length] = 0; +} + +//=========================================================================== +static void OnGetAdvListEx (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < sizeof(DWORD))) + return; + + // PROCESS ALL GAMES IN THIS PACKET + DWORD games = *(LPDWORD)data; + LPBYTE currptr = (LPBYTE)data+sizeof(DWORD); + while (games--) { + + // PARSE THE GAME RESPONSE + DWORD categorybits = *(LPDWORD)currptr; + DWORD relayinfo = *((LPDWORD)currptr+1); + sockaddr_in *address = (sockaddr_in *)((LPDWORD)currptr+2); + DWORD gamemode = *(LPDWORD)(currptr+sizeof(sockaddr_in)+2*sizeof(DWORD)); + DWORD gameage = *(LPDWORD)(currptr+sizeof(sockaddr_in)+3*sizeof(DWORD)); + LPCSTR namepassdesc = (LPCSTR)(currptr+sizeof(sockaddr_in)+4*sizeof(DWORD)); + + // FILL IN A GAME LIST STRUCTURE FOR THIS GAME + SNETSPI_GAMELIST newgame; + ZeroMemory(&newgame,sizeof(SNETSPI_GAMELIST)); + CopyMemory(&newgame.owner,address,sizeof(sockaddr_in)); + newgame.gamemode = gamemode; + newgame.creationtime = time(NULL)-gameage; + newgame.ownerlasttime = GetTickCount(); + newgame.gamecategorybits = categorybits; + SrvPingAddress((SNETADDRPTR)address); + strncpy(newgame.gamename,namepassdesc,SNETSPI_MAXSTRINGLENGTH); + namepassdesc += strlen(namepassdesc)+1; + namepassdesc += strlen(namepassdesc)+1; + strncpy(newgame.gamedescription,namepassdesc,SNETSPI_MAXSTRINGLENGTH); + namepassdesc += strlen(namepassdesc)+1; + currptr = (LPBYTE)namepassdesc; + + // ADD THIS GAME TO THE LINKED LIST OF GAMES + SpiAddGame(&newgame); + + } +} + +//=========================================================================== +static void OnGetChannelList (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 2)) + return; + LPSTR curr = (LPSTR)data; + while (*curr) { + QueueUiNotification(SN_ADDCHANNEL,curr,strlen(curr)+1,NULL,NULL); + curr += strlen(curr)+1; + } +} + +//=========================================================================== +static void OnGetCookie (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 2*sizeof(DWORD)+1)) + return; + struct { + DWORD flags; + DWORD queryid; + char namevalue[512]; + } req; + req.flags = *(LPDWORD)data; + req.queryid = *((LPDWORD)data+1); + strcpy(req.namevalue,(LPCSTR)data+2*sizeof(DWORD)); + LPSTR value = req.namevalue+strlen(req.namevalue)+1; + SRegLoadString(COOKIEREGKEY, + req.namevalue, + SREG_FLAG_BATTLENET, + value, + 256); + SendServerMessage(SID_GETCOOKIE, + &req, + 2*sizeof(DWORD) + +strlen(req.namevalue) + +strlen(value) + +2); +} + +//=========================================================================== +static void OnMessageBox (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < sizeof(DWORD)+2)) + return; + SNMESSAGEBOXREC rec; + rec.text = (LPCSTR)((LPDWORD)data+1); + rec.caption = rec.text+strlen(rec.text)+1; + rec.type = *(LPDWORD)data; + QueueUiNotification(SN_MESSAGEBOX,&rec,sizeof(SNMESSAGEBOXREC),&rec.text,&rec.caption); +} + +//=========================================================================== +static void OnPing (LPBYTE data, DWORD databytes) { + if (!data) + return; + SendServerMessage(SID_PING, + data, + databytes); +} + +//=========================================================================== +static void OnQueryMem (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 3*sizeof(DWORD))) + return; + DWORD queryid = *(LPDWORD)data; + LPVOID address = *((LPVOID *)data+1); + DWORD bytes = *((LPDWORD)data+2); + if (IsBadReadPtr(address,bytes)) + return; + LPVOID buffer = ALLOC(sizeof(DWORD)+bytes); + if (!buffer) + return; + *(LPDWORD)buffer = queryid; + CopyMemory((LPDWORD)buffer+1,address,bytes); + SendServerMessage(SID_QUERYMEM,buffer,sizeof(DWORD)+bytes); + FREE(buffer); +} + +//=========================================================================== +static void OnQueryReg (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 2*sizeof(DWORD)+2)) + return; + DWORD queryid = *(LPDWORD)data; + DWORD basekey = *((LPDWORD)data+1); + LPCSTR key = (LPCSTR)((LPDWORD)data+2); + LPCSTR value = key+strlen(key)+1; + HKEY keyhandle; + if (RegOpenKeyEx((HKEY)basekey, + key, + 0, + KEY_READ, + &keyhandle)) + return; + DWORD bytes = 0; + DWORD type = REG_SZ; + RegQueryValueEx(keyhandle, + value, + NULL, + &type, + NULL, + &bytes); + if (!bytes) + return; + LPVOID buffer = ALLOC(sizeof(DWORD)+bytes); + if (!buffer) + return; + *(LPDWORD)buffer = queryid; + RegQueryValueEx(keyhandle, + value, + NULL, + &type, + (LPBYTE)((LPDWORD)buffer+1), + &bytes); + RegCloseKey(keyhandle); + SendServerMessage(SID_QUERYREG,buffer,sizeof(DWORD)+bytes); + FREE(buffer); +} + +//=========================================================================== +static void OnReportVersion (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < sizeof(DWORD)+2)) + return; + srv_authenticated = *(LPDWORD)data; + if (srv_authenticated == VER_RESULT_UPGRADEREQUIRED) { + CopyMemory(srv_patchfiles,(LPCSTR)data+sizeof(DWORD),databytes-sizeof(DWORD)); + SRegSaveData(PATCHREGKEY, + PATCHREGVALUE_PATCHES, + SREG_FLAG_BATTLENET | SREG_FLAG_MULTISZ, + data+sizeof(DWORD), + databytes-sizeof(DWORD)); + LPCSTR curr = (LPCSTR)data+sizeof(DWORD); + while (*curr) { + FILETIME filetime = {0,0}; + RequestFile(DOWNLOAD_PATCH, + SAVE_DISK, + 0, + 0, + &filetime, + curr, + NULL); + curr += strlen(curr)+1; + } + } +} + +//=========================================================================== +static void OnServerList (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < sizeof(DWORD)+1)) + return; + SRegSaveValue(CONFIGREGKEY,CONFIGREGVALUE_SERVERVER,SREG_FLAG_BATTLENET,SERVERVERSION); + SRegSaveString(CONFIGREGKEY,CONFIGREGVALUE_SERVERLIST,SREG_FLAG_BATTLENET,(LPCSTR)data+sizeof(DWORD)); +} + +//=========================================================================== +static void OnSetCookie (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < 2*sizeof(DWORD)+2)) + return; + LPCSTR name = (LPCSTR)data+2*sizeof(DWORD); + LPCSTR value = name+strlen(name)+1; + SRegSaveString(COOKIEREGKEY,name,SREG_FLAG_BATTLENET,value); +} + +//=========================================================================== +static void OnStartAdvEx (LPBYTE data, DWORD databytes) { + if ((!data) || (databytes < sizeof(DWORD))) + return; + srv_startadvsuccess = *(LPDWORD)data; +} + +//=========================================================================== +static void OnStartVersioning (LPBYTE data, DWORD databytes) { + FILETIME *filetime = (FILETIME *)data; + LPCSTR filename = (LPCSTR)(filetime+1); + if (sizeof(FILETIME)+strlen(filename)+1 < databytes) { + strncpy(srv_argstring,filename+strlen(filename)+1,255); + srv_argstring[255] = 0; + } + RequestFile(DOWNLOAD_VERSIONING, + SAVE_CACHE | SAVE_DISK, + 0, + 0, + filetime, + filename, + NULL); +} + +//=========================================================================== +static unsigned CALLBACK PingThreadProc (LPVOID param) { + SOCKET s = socket(PF_INET,SOCK_STREAM,0); + AddConnectThread(s); + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(80); + addr.sin_addr.S_un.S_addr = inet_addr((const char *)param); + if (!connect(s,(sockaddr *)&addr,sizeof(sockaddr_in))) + srv_pingsuccess = 1; + closesocket(s); + DeleteConnectThread(s); + InterlockedDecrement(&srv_pingthreads); + _endthreadex(0); + return 0; +} + +//=========================================================================== +static void ProcessFile (DWORD downloadtype, + DWORD savetype, + DWORD fileid, + DWORD filedatatype, + FILETIME *filetime, + LPCSTR filename, + LPCSTR url, + LPVOID data, + DWORD databytes) { + switch (downloadtype) { + + case DOWNLOAD_AD: + { + SNADINFOREC rec; + rec.id = fileid; + rec.adtype = filedatatype; + rec.filename = filename; + rec.url = url; + QueueUiNotification(SN_SETADINFO,&rec,sizeof(SNADINFOREC),&rec.filename,&rec.url); + QueueUiNotification(SN_DISPLAYAD,data,databytes,NULL,NULL); + } + break; + + case DOWNLOAD_PATCH: + // IF THIS IS THE LAST OF THE SERIES OF PATCHES, REMOVE THE PATCH LIST. + // THIS ALSO SERVES TO INDICATE THE WAITING THREAD THAT ALL PATCHES HAVE + // BEEN DOWNLOADED. + { + srv_patchcritsect.Enter(); + LPCSTR curr = srv_patchfiles; + while (*curr && _stricmp(curr,filename)) + curr += strlen(curr)+1; + if ((!*curr) || (!*(curr+strlen(curr)+1))) { + srv_patchfiles[0] = 0; + srv_patchfiles[1] = 0; + } + srv_patchcritsect.Leave(); + } + break; + + case DOWNLOAD_VERSIONING: + strcpy(srv_versionfile,filename); + break; + + } +} + +//=========================================================================== +static void QueueUiNotification (DWORD notifycode, + LPVOID param, + DWORD parambytes, + LPCSTR *string1ptr, + LPCSTR *string2ptr) { + + // FIND THE STRINGS IN THE PARAMETER BLOCK + LPCSTR string1 = string1ptr ? *string1ptr : NULL; + LPCSTR string2 = string2ptr ? *string2ptr : NULL; + if (!string1) + string1 = ""; + if (!string2) + string2 = ""; + int string1len = strlen(string1); + int string2len = strlen(string2); + + // ALLOCATE A NEW NOTIFICATION STRUCTURE + UINOTIFICATIONPTR newnotification = NEW(UINOTIFICATION); + if (!newnotification) + return; + newnotification->notifycode = notifycode; + newnotification->parambytes = parambytes; + + // ALLOCATE AND FILL IN THE DATA BUFFER + newnotification->buffer = ALLOC(parambytes+string1len+string2len+2); + if (!newnotification->buffer) + return; + LPSTR newstring1 = (LPSTR)newnotification->buffer+parambytes; + LPSTR newstring2 = newstring1+string1len+1; + if (param && parambytes) + CopyMemory(newnotification->buffer,param,parambytes); + CopyMemory(newstring1,string1,string1len+1); + CopyMemory(newstring2,string2,string2len+1); + + // ADJUST THE STRING POINTERS IN THE DATA BLOCK TO POINT TO THE NEW + // STRING DATA + if (string1ptr && *string1ptr) { + int offset = ((LPBYTE)string1ptr)-(LPBYTE)param; + *(LPCSTR *)((LPBYTE)newnotification->buffer+offset) = newstring1; + } + if (string2ptr && *string2ptr) { + int offset = ((LPBYTE)string2ptr)-(LPBYTE)param; + *(LPCSTR *)((LPBYTE)newnotification->buffer+offset) = newstring2; + } + + // ADD THE NOTIFICATION TO OUR LINKED LIST + srv_uinotificationcritsect.Enter(); + UINOTIFICATIONPTR *nextptr = &srv_uinotificationhead; + while (*nextptr) + nextptr = &(*nextptr)->next; + *nextptr = newnotification; + newnotification->next = NULL; + srv_uinotificationcritsect.Leave(); + + // INFORM THE UI MODULE THAT THERE IS A NEW NOTIFICATION WAITING + UiNotificationWaiting(); + +} + +//=========================================================================== +static void RemovePingUser (LPCSTR username, sockaddr_in *addr) { + + // NORMALIZE THE ADDRESS TO POINT TO THE DATA PORT + sockaddr_in dataportaddr; + if (addr) { + CopyMemory(&dataportaddr,addr,sizeof(sockaddr_in)); + dataportaddr.sin_port = htons(DATAPORT); + ZeroMemory(&dataportaddr.sin_zero[0],8); + } + + // REMOVE ANY USER RECORDS THAT MATCH THIS USERNAME OR ADDRESS + srv_pingcritsect.Enter(); + PINGPTR *nextptr = &srv_pinghead; + while (*nextptr) + if (((!username) || (!_stricmp(username,(*nextptr)->username))) && + ((!addr) || (!memcmp(&dataportaddr,&(*nextptr)->addr,sizeof(sockaddr_in))))) { + PINGPTR curr = *nextptr; + *nextptr = curr->next; + FREE(curr); + } + else + nextptr = &(*nextptr)->next; + srv_pingcritsect.Leave(); + +} + +//=========================================================================== +static void RequestFile (DWORD downloadtype, + DWORD savetype, + DWORD fileid, + DWORD filedatatype, + FILETIME *filetime, + LPCSTR filename, + LPCSTR url) { + if (!(filename && *filename)) + return; + if (!url) + url = ""; + + // CHECK FOR THIS FILE IN OUR CACHE + FILETIME cachedfiletime; + LPVOID cacheddata; + DWORD cacheddatabytes; + if (CacheLoadFile(filename,&cachedfiletime,&cacheddata,&cacheddatabytes)) + if (!CompareFileTime(filetime,&cachedfiletime)) { + if (savetype & SAVE_DISK) + SaveFile(filename,cacheddata,cacheddatabytes); + ProcessFile(downloadtype, + savetype, + fileid, + filedatatype, + filetime, + filename, + url, + cacheddata, + cacheddatabytes); + CacheFree(cacheddata,cacheddatabytes); + return; + } + else + CacheFree(cacheddata,cacheddatabytes); + + // CREATE A DOWNLOAD REQUEST + FILEREQPTR newreq = NEW(FILEREQ); + if (newreq) + ZeroMemory(newreq,sizeof(FILEREQ)); + else + return; + newreq->requestbytes = 5*sizeof(DWORD)+sizeof(FILETIME)+strlen(filename)+1; + newreq->platformid = PLATFORMID; + newreq->programid = global_programid; + newreq->fileid = fileid; + newreq->filedatatype = filedatatype; + newreq->downloadtype = downloadtype; + newreq->savetype = savetype; + CopyMemory(&newreq->filetime,filetime,sizeof(FILETIME)); + strncpy(newreq->filename,filename,MAX_PATH); + strncpy(newreq->url,url,MAX_PATH); + + // START UP A NEW THREAD TO CONTACT THE SERVER, DOWNLOAD THE + // AD, STORE IT IN THE CACHE, AND SEND A UI NOTIFICATION MESSAGE + InterlockedIncrement(&srv_downloadthreads); + unsigned threadid; + HANDLE threadhandle = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + DownloadThreadProc, + newreq, + 0, + &threadid); + if (threadhandle) + CloseHandle(threadhandle); + +} + +//=========================================================================== +static void SaveFile (LPCSTR filename, + LPVOID buffer, + DWORD bytes) { + + // DETERMINE THE FULL PATHNAME + TCHAR fullpathname[MAX_PATH] = ""; + GetModuleFileName(GetModuleHandle(NULL),fullpathname,MAX_PATH); + { + LPTSTR separator = strchr(fullpathname,'\\'); + while (separator && strchr(separator+1,'\\')) + separator = strchr(separator+1,'\\'); + if (separator) + *separator = 0; + } + strcat(fullpathname,"\\"); + strcat(fullpathname,filename); + + // SAVE THE FILE + HANDLE file = CreateFile(filename, + GENERIC_WRITE, + 0, + (LPSECURITY_ATTRIBUTES)NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (file == INVALID_HANDLE_VALUE) + return; + DWORD byteswritten; + WriteFile(file, + buffer, + bytes, + &byteswritten, + NULL); + CloseHandle(file); + +} + +//=========================================================================== +static unsigned CALLBACK ServerThreadProc (LPVOID) { + + // ALLOCATE A RECEIVE BUFFER IF NECESSARY + DWORD serverbytes = 0; + LPBYTE serverdata = (LPBYTE)ALLOC(SERVERBUFFERSIZE); + + while (serverdata && srv_serversocket && !srv_shutdown) { + + // READ THE NEXT BLOCK OF DATA + int result = recv(srv_serversocket, + (char *)(serverdata+serverbytes), + SERVERBUFFERSIZE-serverbytes, + 0); + if ((result == SOCKET_ERROR) || !result) { + QueueUiNotification(SN_LOSTCONNECTION,NULL,0,NULL,NULL); + closesocket(srv_serversocket); + srv_serversocket = (SOCKET)0; + break; + } + else if (srv_shutdown) + break; + else + serverbytes += result; + + // PROCESS ALL MESSAGES CONTAINED IN THE DATA + DWORD lastoffset; + DWORD offset = 0; + do { + + // SKIP TO THE BEGINNING OF THE NEXT MESSAGE + while ((offset < serverbytes) && (*(serverdata+offset) != 0xFF)) + ++offset; + + // MAKE SURE THE ENTIRE MESSAGE HAS BEEN RECEIVED + SRVMSGPTR msgptr = (SRVMSGPTR)(serverdata+offset); + lastoffset = offset; + if ((serverbytes-offset >= sizeof(SRVMSG)) && + (serverbytes-offset >= msgptr->bytes)) { + + // PROCESS THE MESSAGE + LPBYTE data = (LPBYTE)(msgptr+1); + DWORD databytes = msgptr->bytes-sizeof(SRVMSG); + switch (msgptr->id) { + + case SID_BROADCAST: + OnBroadcast(data,databytes); + break; + + case SID_CHATEVENT: + OnChatEvent(data,databytes); + break; + + case SID_CHECKAD: + OnCheckAd(data,databytes); + break; + + case SID_CLIENTID: + OnClientId(data,databytes); + break; + + case SID_ENTERCHAT: + OnEnterChat(data,databytes); + break; + + case SID_GETADVLISTEX: + OnGetAdvListEx(data,databytes); + break; + + case SID_GETCHANNELLIST: + OnGetChannelList(data,databytes); + break; + + case SID_GETCOOKIE: + OnGetCookie(data,databytes); + break; + + case SID_MESSAGEBOX: + OnMessageBox(data,databytes); + break; + + case SID_PING: + OnPing(data,databytes); + break; + + case SID_QUERYMEM: + OnQueryMem(data,databytes); + break; + + case SID_QUERYREG: + OnQueryReg(data,databytes); + break; + + case SID_REPORTVERSION: + OnReportVersion(data,databytes); + break; + + case SID_SERVERLIST: + OnServerList(data,databytes); + break; + + case SID_SETCOOKIE: + OnSetCookie(data,databytes); + break; + + case SID_STARTADVEX: + OnStartAdvEx(data,databytes); + break; + + case SID_STARTVERSIONING: + OnStartVersioning(data,databytes); + + } + if (msgptr->id < SERVERIDS) + srv_responded[msgptr->id] = 1; + if (srv_waitevent) + SetEvent(srv_waitevent); + offset += max(sizeof(SRVMSG),msgptr->bytes); + + } + + } while (offset > lastoffset); + + // REMOVE ALL PROCESSED MESSAGES FROM THE RECEIVE BUFFER + if (offset) { + if (offset < serverbytes) + MoveMemory(serverdata, + serverdata+offset, + serverbytes-offset); + if (serverbytes > offset) + serverbytes -= offset; + else + serverbytes = 0; + } + + } + + // DISCONNECT FROM THE BATTLE.NET SERVER + DisconnectFromServer(); + + // FREE OUR RECEIVE BUFFER + FREE(serverdata); + + _endthreadex(0); + return 0; +} + +//=========================================================================== +static BOOL SendServerMessage (BYTE id, LPVOID data, DWORD databytes) { + if (!srv_serversocket) + return 0; + static CCritSect sendcritsect; + sendcritsect.Enter(); + srv_responded[id] = 0; + SRVMSG msg; + msg.signature = 0xFF; + msg.id = id; + msg.bytes = sizeof(SRVMSG)+databytes; + if (send(srv_serversocket,(const char *)&msg,sizeof(SRVMSG),0) != sizeof(SRVMSG)) { + DWORD error = SN_ERROR_UNREACHABLE; + QueueUiNotification(SN_FAILEDTOCONNECT,&error,sizeof(DWORD),NULL,NULL); + sendcritsect.Leave(); + return 0; + } + if (data && databytes) + if ((DWORD)send(srv_serversocket,(const char *)data,databytes,0) != databytes) { + DWORD error = SN_ERROR_UNREACHABLE; + QueueUiNotification(SN_FAILEDTOCONNECT,&error,sizeof(DWORD),NULL,NULL); + sendcritsect.Leave(); + return 0; + } + sendcritsect.Leave(); + return 1; +} + +//=========================================================================== +static void UpdatePatchPercent (LPCSTR filename, + DWORD offset, + DWORD totalsize) { + + // DETERMINE THE PATCH NUMBER OF THIS FILE + DWORD patchnumber = 0; + DWORD totalpatches = 0; + srv_patchcritsect.Enter(); + { + LPCSTR curr = srv_patchfiles; + while (*curr && _stricmp(curr,filename)) { + ++patchnumber; + ++totalpatches; + curr += strlen(curr)+1; + } + while (*curr) { + ++totalpatches; + curr += strlen(curr)+1; + } + } + srv_patchcritsect.Leave(); + + // VERIFY THAT THE SIZE IS NON-ZERO + if (!totalsize) + return; + + // IF THIS IS THE ONLY PATCH, BASE THE PERCENT COMPLETE ON THE OFFSET + if (totalpatches <= 1) + if (totalsize > 100) + srv_patchpercent = min(100,offset*100/totalsize); + else + srv_patchpercent = 100; + + // OTHERWISE, IF THIS IS THE FIRST INCOMPLETE PATCH, UPDATE THE PERCENT + if (patchnumber <= srv_patchhighcomplete) { + srv_patchpercent = min((patchnumber+1)*100/max(1,totalpatches), + (patchnumber*totalsize+offset)/max(1,totalpatches*totalsize/100)); + if (srv_patchpercent > 100) + srv_patchpercent = 100; + if (offset >= totalsize) + srv_patchhighcomplete = patchnumber+1; + } + +} + +//=========================================================================== +static BOOL WaitForServerResponse (DWORD sid, DWORD flags) { + InterlockedIncrement(&srv_waiting); + DWORD starttime = GetTickCount(); + while (!srv_responded[sid]) { + + // IF WE'VE EXCEEDED THE TIME TO WAIT, RETURN FAILURE + if ((GetTickCount()-starttime > 180000) && !(flags & WAIT_FLAG_INFINITE)) { + InterlockedDecrement(&srv_waiting); + DWORD error = SN_ERROR_UNREACHABLE; + QueueUiNotification(SN_FAILEDTOCONNECT,&error,sizeof(DWORD),NULL,NULL); + SetLastError(SNET_ERROR_HOST_UNREACHABLE); + return 0; + } + + // WAIT FOR AN EVENT, TIMER, OR WINDOW MESSAGE + if (!WaitOnce(flags)) { + // WAITONCE() IS RESPONSIBLE FOR CALLING SETLASTERROR() + InterlockedDecrement(&srv_waiting); + return 0; + } + + + } + srv_responded[sid] = 0; + InterlockedDecrement(&srv_waiting); + return 1; +} + +//=========================================================================== +static BOOL WaitOnce (DWORD flags) { + + // WAIT UNTIL WE NEED TO UPDATE THE TIMERS OR DISPATCH A MESSAGE + DWORD result; + if (flags & WAIT_FLAG_NOMESSAGELOOP) + result = WaitForSingleObject(srv_waitevent,1000); + else + result = MsgWaitForMultipleObjects(1, + &srv_waitevent, + 0, + 10, + QS_ALLINPUT); + + // DISPATCH ANY PENDING WINDOW MESSAGES + if ((result != WAIT_OBJECT_0) && + !(flags & WAIT_FLAG_NOMESSAGELOOP)) + if (!UiProcessWindowMessages()) { + SetLastError(SNET_ERROR_CANCELLED); + return 0; + } + + // IF THE SOCKET IS NOT CONNECTED ANYMORE, OR THE USER HAS CANCELLED THE + // OPERATION, RETURN FAILURE + if (srv_cancelwait) { + srv_cancelwait = 0; + SetLastError(SNET_ERROR_CANCELLED); + return 0; + } + if (!srv_serversocket) + return 0; + sockaddr_in addr; + int addrlen = sizeof(sockaddr_in); + if (getpeername(srv_serversocket,(sockaddr *)&addr,&addrlen) == SOCKET_ERROR) { + DWORD error = SN_ERROR_UNREACHABLE; + QueueUiNotification(SN_FAILEDTOCONNECT,&error,sizeof(DWORD),NULL,NULL); + SetLastError(SNET_ERROR_HOST_UNREACHABLE); + return 0; + } + + return 1; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL SrvBeginChat (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + LPCSTR preferredchannel) { + if (!srv_connected) + return 0; + srv_inchat = 1; + + // REQUEST THE ITEMS THAT WE NEED: + // - A UNIQUE USER NAME + // - A LIST OF CHANNELS + // - A STARTING CHANNEL TO JOIN + { + char namedesc[2*SNETSPI_MAXSTRINGLENGTH] = ""; + SStrCopy(namedesc,srv_username,SNETSPI_MAXSTRINGLENGTH); + SStrCopy(namedesc+strlen(namedesc)+1,srv_userdesc,SNETSPI_MAXSTRINGLENGTH); + if (!SendServerMessage(SID_ENTERCHAT,namedesc,strlen(namedesc)+strlen(namedesc+strlen(namedesc)+1)+2)) + return 0; + } + if (!SendServerMessage(SID_GETCHANNELLIST,&programdata->programid,sizeof(DWORD))) + return 0; + { + struct { + DWORD flags; + char channelname[SNETSPI_MAXSTRINGLENGTH]; + } req; + ZeroMemory(&req,sizeof(req)); + if (preferredchannel && *preferredchannel) { + req.flags = JCF_JOINALWAYS; + strncpy(req.channelname,preferredchannel,SNETSPI_MAXSTRINGLENGTH); + } + else { + req.flags = JCF_DEFAULTCHANNEL; + strncpy(req.channelname,programdata->programname,SNETSPI_MAXSTRINGLENGTH); + } + req.channelname[SNETSPI_MAXSTRINGLENGTH-1] = 0; + SendServerMessage(SID_JOINCHANNEL, + &req, + sizeof(DWORD)+strlen(req.channelname)+1); + } + + // WAIT FOR THE RESPONSES + if (!WaitForServerResponse(SID_ENTERCHAT,0)) + return 0; + if (!WaitForServerResponse(SID_GETCHANNELLIST,0)) + return 0; + if (!WaitForServerResponse(SID_CHATEVENT,0)) + return 0; + + return 1; +} + +//=========================================================================== +void SrvCancel () { + srv_cancelwait = 1; +} + +//=========================================================================== +BOOL SrvCreateAccount (LPCSTR username, + LPCSTR password) { + return TRUE; +} + +//=========================================================================== +void SrvDestroy () { + + // DESTROY THE THREADS + srv_shutdown = 1; + SetEvent(srv_shutdownevent); + { + DWORD phase = 0; + DWORD starttime = GetTickCount(); + do { + Sleep(10); + DWORD currtime = GetTickCount(); + DWORD newphase = (currtime-starttime)/500; + if (srv_connectthreads && (newphase != phase)) { + phase = newphase; + DestroyConnectThreads(phase); + } + } while (srv_connectthreads); + do + Sleep(10); + while (srv_downloadthreads); + } + SrvDisconnect(); + if (srv_keepalivethread) + WaitForSingleObject(srv_keepalivethread,INFINITE); + if (srv_serverthread) + WaitForSingleObject(srv_serverthread,INFINITE); + CloseHandle(srv_keepalivethread); + CloseHandle(srv_serverthread); + CloseHandle(srv_waitevent); + CloseHandle(srv_shutdownevent); + srv_keepalivethread = (HANDLE)0; + srv_serverthread = (HANDLE)0; + srv_waitevent = (HANDLE)0; + srv_shutdownevent = (HANDLE)0; + srv_shutdown = 0; + + // DESTROY THE LIST OF PING USERS + RemovePingUser(NULL,NULL); + + // DESTROY ALL PENDING UI NOTIFICATIONS + srv_uinotificationcritsect.Enter(); + while (srv_uinotificationhead) { + FREE(srv_uinotificationhead->buffer); + UINOTIFICATIONPTR next = srv_uinotificationhead->next; + FREE(srv_uinotificationhead); + srv_uinotificationhead = next; + } + if (srv_uinotificationhold) { + FREE(srv_uinotificationhold); + srv_uinotificationhold = NULL; + } + srv_uinotificationcritsect.Leave(); + + // RESET THE MODULE FOR THE NEXT INITIALIZATION + srv_serverthread = (HANDLE)0; + srv_waitevent = (HANDLE)0; + +} + +//=========================================================================== +BOOL SrvDisconnect () { + if (srv_connected || srv_serversocket) + DisconnectFromServer(); + return 1; +} + +//=========================================================================== +BOOL SrvEndChat () { + if (!srv_connected) + return 0; + if (!SendServerMessage(SID_LEAVECHAT,NULL,0)) + return 0; + srv_inchat = 0; + return 1; +} + +//=========================================================================== +BOOL SrvGetGameList (LPCSTR gamename, + LPCSTR gamepassword, + DWORD categorybits, + DWORD categorymask, + DWORD maxitems) { + if (!gamename) + gamename = ""; + if (!gamepassword) + gamepassword = ""; + + // REQUEST A LIST OF PUBLIC GAMES + struct { + DWORD categorybits; + DWORD categorymask; + DWORD reserved; + DWORD maxitems; + char namepasscriteria[3*SNETSPI_MAXSTRINGLENGTH]; + } req; + req.categorybits = categorybits; + req.categorymask = categorymask; + req.reserved = 0; + req.maxitems = maxitems; + LPSTR curr = req.namepasscriteria; + strncpy(curr,gamename,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + strncpy(curr,gamepassword,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + strncpy(curr,"",SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + DWORD length = 4*sizeof(DWORD)+curr-req.namepasscriteria; + if (!SendServerMessage(SID_GETADVLISTEX,&req,length)) + return 0; + + // WAIT FOR THE SERVER'S RESPONSE + if (!WaitForServerResponse(SID_GETADVLISTEX,0)) + return 0; + + return 1; +} + +//=========================================================================== +BOOL SrvGetLatency (SNETADDRPTR addr, + DWORD *latency) { + if (latency) + *latency = 0; + + // NORMALIZE THE ADDRESS TO POINT TO THE DATA PORT + sockaddr_in dataportaddr; + if (addr) { + CopyMemory(&dataportaddr,addr,sizeof(sockaddr_in)); + dataportaddr.sin_port = htons(DATAPORT); + ZeroMemory(&dataportaddr.sin_zero[0],8); + } + + // FIND THIS ADDRESS + srv_pingcritsect.Enter(); + PINGPTR curr = srv_pinghead; + while (curr && + memcmp(&dataportaddr,&curr->addr,sizeof(sockaddr_in))) + curr = curr->next; + if (curr) + *latency = curr->latency; + srv_pingcritsect.Leave(); + + return (curr != NULL); +} + +//=========================================================================== +void SrvGetLocalPlayerDesc (LPSTR buffer, + DWORD bufferchars) { + SStrCopy(buffer,srv_userdesc,bufferchars); +} + +//=========================================================================== +void SrvGetLocalPlayerName (LPSTR buffer, + DWORD bufferchars) { + SStrCopy(buffer,srv_username,bufferchars); +} + +//=========================================================================== +BOOL SrvGetUiNotification (DWORD *notifycode, + LPVOID *param, + DWORD *parambytes) { + if (notifycode) + *notifycode = 0; + if (param) + *param = NULL; + if (parambytes) + *parambytes = 0; + + // ENTER THE CRITICAL SECTION + srv_uinotificationcritsect.Enter(); + + // FREE THE LAST NOTIFICATION WE RETURNED + if (srv_uinotificationhold) { + FREE(srv_uinotificationhold); + srv_uinotificationhold = NULL; + } + + // CHECK TO SEE IF ANOTHER IS AVAILABLE + if (!srv_uinotificationhead) { + srv_uinotificationcritsect.Leave(); + return 0; + } + + // RETURN THE NEXT NOTIFICATION + *notifycode = srv_uinotificationhead->notifycode; + *param = srv_uinotificationhead->buffer; + *parambytes = srv_uinotificationhead->parambytes; + + // REMOVE THIS NOTIFICATION FROM THE LIST, AND PLACE ITS DATA IN THE + // HOLD AREA + srv_uinotificationhold = srv_uinotificationhead->buffer; + UINOTIFICATIONPTR freenotification = srv_uinotificationhead; + srv_uinotificationhead = freenotification->next; + FREE(freenotification); + + // LEAVE THE CRITICAL SECTION + srv_uinotificationcritsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL SrvInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETVERSIONDATAPTR versiondata) { +#define FAILOUT(uierr,sneterr) \ + do { \ + DWORD error = uierr; \ + QueueUiNotification(SN_FAILEDTOCONNECT, \ + &error, \ + sizeof(DWORD), \ + NULL, \ + NULL); \ + SetLastError(sneterr); \ + return 0; \ + } while (0) + + // CONNECT TO THE SERVER + if (!ConnectToServer()) + return 0; + + // CREATE AN EVENT FOR WAITING ON SERVER RESPONSS + srv_waitevent = CreateEvent(NULL,0,0,NULL); + + // CREATE A THREAD TO PROCESS SERVER DATA + unsigned threadid; + srv_serverthread = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + ServerThreadProc, + NULL, + 0, + &threadid); + if (!srv_serverthread) + return 0; + + // SEND THE CONNECTION TYPE TO BATTLE.NET + BYTE conntype = CONNTYPE_CLIENT; + if (send(srv_serversocket, + (const char *)&conntype, + sizeof(BYTE), + 0) != sizeof(BYTE)) + return 0; + + // SEND OUR CLIENT ID TO BATTLE.NET + { + struct { + DWORD registrationversion; + DWORD registrationauthority; + DWORD clientid; + DWORD checkvalue; + char computeraccount[SNETSPI_MAXSTRINGLENGTH+MAX_COMPUTERNAME_LENGTH+3]; + } req; + ZeroMemory(&req,sizeof(req)); + SRegLoadValue(CONFIGREGKEY,CONFIGREGVALUE_REGVER ,SREG_FLAG_BATTLENET,&req.registrationversion); + SRegLoadValue(CONFIGREGKEY,CONFIGREGVALUE_REGAUTH ,SREG_FLAG_BATTLENET,&req.registrationauthority); + SRegLoadValue(CONFIGREGKEY,CONFIGREGVALUE_CLIENTID ,SREG_FLAG_BATTLENET,&req.clientid); + SRegLoadValue(CONFIGREGKEY,CONFIGREGVALUE_CLIENTCHECK,SREG_FLAG_BATTLENET,&req.checkvalue); + DWORD size = MAX_COMPUTERNAME_LENGTH+1; + GetComputerName(req.computeraccount,&size); + req.computeraccount[MAX_COMPUTERNAME_LENGTH] = 0; + LPSTR curr = req.computeraccount+strlen(req.computeraccount)+1; + size = SNETSPI_MAXSTRINGLENGTH; + GetUserName(curr,&size); + curr += strlen(curr)+1; + if (!SendServerMessage(SID_CLIENTID, + &req, + 4*sizeof(DWORD)+curr-req.computeraccount)) + return 0; + } + + // SEND OUR LOCALE INFORMATION TO BATTLE.NET + { + TIME_ZONE_INFORMATION tzinfo; + ZeroMemory(&tzinfo,sizeof(TIME_ZONE_INFORMATION)); + GetTimeZoneInformation(&tzinfo); + SYSTEMTIME sysutctime; + SYSTEMTIME syslocaltime; + GetSystemTime(&sysutctime); + GetLocalTime(&syslocaltime); + struct { + FILETIME utctime; + FILETIME localtime; + LONG bias; + DWORD systemlcid; + DWORD userlcid; + DWORD languageid; + char strings[256]; + } req; + SystemTimeToFileTime(&sysutctime,&req.utctime); + SystemTimeToFileTime(&syslocaltime,&req.localtime); + req.bias = tzinfo.Bias; + req.systemlcid = GetSystemDefaultLCID(); + req.userlcid = GetUserDefaultLCID(); + req.languageid = GetUserDefaultLangID(); + req.strings[0] = 0; + LPSTR curr = req.strings; + GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SABBREVLANGNAME,curr,64); + curr += strlen(curr)+1; + GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_ICOUNTRY,curr,64); + curr += strlen(curr)+1; + GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SABBREVCTRYNAME,curr,64); + curr += strlen(curr)+1; + GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SENGCOUNTRY,curr,64); + curr += strlen(curr)+1; + DWORD length = 2*sizeof(FILETIME)+4*sizeof(DWORD)+curr-req.strings; + if (!SendServerMessage(SID_LOCALEINFO,&req,length)) + return 0; + } + + // SEND THE PLATFORM AND PROGRAM IDENTIFIERS TO THE BATTLE.NET SERVER + srv_versionfile[0] = 0; + srv_responded[SID_REPORTVERSION] = 0; + { + struct { + DWORD platformid; + DWORD programid; + DWORD versionid; + DWORD reserved; + } req; + ZeroMemory(&req,sizeof(req)); + req.platformid = PLATFORMID; + req.programid = programdata->programid; + req.versionid = programdata->versionid; + if (!SendServerMessage(SID_STARTVERSIONING,&req,sizeof(req))) + return 0; + } + + // WAIT FOR THE SERVER TO EITHER SEND US A VERSIONING FILENAME OR TO + // AUTHENTICATE US WITHOUT REQUIRING VERSIONING + while (!(srv_versionfile[0] || srv_responded[SID_REPORTVERSION])) + if (!WaitOnce(0)) + return 0; + if (!srv_responded[SID_REPORTVERSION]) { + + // DETERMINE THE VERSIONING INFORMATION + DWORD revisionid; + DWORD checkvalue; + char comment[256] = ""; + if (!CheckVersion(&revisionid,&checkvalue,comment)) + FAILOUT(SN_ERROR_UNABLETOUPGRADE,SNET_ERROR_HOST_UNREACHABLE); + + // RESET OUT PATCH STATUS, IN CASE THE SERVER NEEDS TO SEND US A PATCH + srv_patchfiles[0] = 0; + srv_patchfiles[1] = 0; + srv_patchhighcomplete = 0; + srv_patchpercent = 0; + + // SEND IT TO THE SERVER + { + struct { + DWORD platformid; + DWORD programid; + DWORD versionid; + DWORD revisionid; + DWORD checkvalue; + char comment[256]; + } req; + ZeroMemory(&req,sizeof(req)); + req.platformid = PLATFORMID; + req.programid = programdata->programid; + req.versionid = programdata->versionid; + req.revisionid = revisionid; + req.checkvalue = checkvalue; + strncpy(req.comment,comment,255); + req.comment[255] = 0; + if (!SendServerMessage(SID_REPORTVERSION,&req,5*sizeof(DWORD)+strlen(comment)+1)) + return 0; + } + + // WAIT FOR THE SERVER TO RESPOND WITH A CODE TELLING US WHETHER WE NEED + // TO UPGRADE + if (!WaitForServerResponse(SID_REPORTVERSION,0)) + return 0; + + } + + // IF THE SERVER REJECTED US, REPORT THAT TO THE USER + if (srv_authenticated == VER_RESULT_BADVERSION) + FAILOUT(SN_ERROR_UNABLETOUPGRADE,SNET_ERROR_HOST_UNREACHABLE); + + // IF THE SERVER REPORTED THAT WE NEED TO UPGRADE, ASK THE USER WHETHER + // TO UPGRADE NOW + if (srv_authenticated == VER_RESULT_UPGRADEREQUIRED) { + if (!UiUpgradeMessage()) { + SetLastError(SNET_ERROR_CANCELLED); + return 0; + } + + // DOWNLOAD THE UPGRADE + DWORD lastpercent = 0xFFFFFFFF; + while (srv_patchfiles[0]) + if (WaitOnce(0)) { + if (srv_patchpercent != lastpercent) { + lastpercent = srv_patchpercent; + QueueUiNotification(SN_DOWNLOADINGUPGRADE,&srv_patchpercent,sizeof(DWORD),NULL,NULL); + } + } + else + return 0; + + // IF THE METER NEVER DREW ON 100%, FORCE IT TO DO SO MOMENTARILY + { + srv_patchpercent = 100; + QueueUiNotification(SN_DOWNLOADINGUPGRADE,&srv_patchpercent,sizeof(DWORD),NULL,NULL); + DWORD starttime = GetTickCount(); + do + WaitOnce(0); + while (GetTickCount()-starttime < 200); + } + + // PROCEED WITH APPLYING THE PATCH + QueueUiNotification(SN_DOWNLOADSUCCEEDED,NULL,0,NULL,NULL); + SRegSaveString(PATCHREGKEY,PATCHREGVALUE_LAUNCHER,SREG_FLAG_BATTLENET,versiondata->executablefile); + SRegSaveString(PATCHREGKEY,PATCHREGVALUE_SRCDATA ,SREG_FLAG_BATTLENET,versiondata->originalarchivefile); + SRegSaveString(PATCHREGKEY,PATCHREGVALUE_DSTDATA ,SREG_FLAG_BATTLENET,versiondata->patcharchivefile); + SetLastError(SNET_ERROR_REQUIRES_UPGRADE); + return 0; + } + + // IF WE RECEIVED THE SERVER'S UDP PING, REPORT THE PING DATA BACK TO THE + // SERVER + if (srv_udppingdata) { + if (!SendServerMessage(SID_UDPPINGRESPONSE,&srv_udppingdata,sizeof(DWORD))) + return 0; + } + + // OTHERWISE, DISPLAY AN ERROR MESSAGE TO THE USER INFORMING HIM THAT + // HIS INTERNET CONNECTION IS BROKEN AND HE WON'T BE ABLE TO PLAY GAMES + else + QueueUiNotification(SN_BADCONNECTION,NULL,0,NULL,NULL); + + // CREATE A THREAD TO KEEP THE CONNECTION ALIVE + srv_keepalivethread = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + KeepAliveThreadProc, + NULL, + 0, + &threadid); + +#undef FAILOUT + srv_connected = 1; + return 1; +} + +//=========================================================================== +BOOL SrvIsConnected () { + return srv_connected; +} + +//=========================================================================== +BOOL SrvIsWaitingForResponse () { + return (srv_waiting != 0); +} + +//=========================================================================== +BOOL SrvJoinChannel (LPCSTR channel, BOOL joinalways) { + struct { + DWORD flags; + char channelname[SNETSPI_MAXSTRINGLENGTH]; + } req; + ZeroMemory(&req,sizeof(req)); + req.flags = joinalways ? JCF_JOINALWAYS : 0; + strncpy(req.channelname,channel,SNETSPI_MAXSTRINGLENGTH); + req.channelname[SNETSPI_MAXSTRINGLENGTH-1] = 0; + return SendServerMessage(SID_JOINCHANNEL, + &req, + sizeof(DWORD)+strlen(req.channelname)+1); +} + +//=========================================================================== +BOOL SrvLogon (LPCSTR username, + LPCSTR password, + DWORD *errorcode) { + SStrCopy(srv_username,username,MAXSTRINGLENGTH); + srv_userdesc[0] = 0; + *errorcode = 0; + return TRUE; +} + +//=========================================================================== +void SrvMaintainAds () { + +#if STARCRAFT_BNBETA + return; // current ads don't fit new ad size +#endif + + // CHECK THE AD STATE ONCE EVERY FIFTEEN SECONDS + DWORD currtime = GetTickCount(); + { + static DWORD lasttime = 0; + if (currtime-lasttime < 15000) + return; + lasttime = currtime; + } + + // SEND AN AD CHECK MESSAGE TO THE SERVER + struct { + DWORD platformid; + DWORD programid; + DWORD currentad; + DWORD runningtime; + } req; + req.platformid = PLATFORMID; + req.programid = global_programid; + req.currentad = srv_adnumber; + req.runningtime = time(NULL)-srv_addisplaytime; + SendServerMessage(SID_CHECKAD,&req,sizeof(req)); + +} + +//=========================================================================== +void SrvMaintainLatencies () { + DWORD currtime = GetTickCount(); + + // IF THERE ARE ANY USERS THAT WE HAVE NEVER RECEIVED A PING RESPONSE FROM, + // AND WHOSE PING WE SENT MORE THAN A SECOND AGO, MAX THEIR LATENCY OUT AT + // ONE SECOND + { + srv_pingcritsect.Enter(); + PINGPTR curr = srv_pinghead; + while (curr) { + if ((currtime-curr->lastpingtime > MAXLATENCY) && + !curr->lastresponsetime) { + curr->latency = MAXLATENCY; + curr->lastresponsetime = currtime; + SNUPDATEPINGTIMEREC rec; + rec.name = curr->username; + rec.pingtime = curr->latency; + rec.relayed = 0; + QueueUiNotification(SN_UPDATEPINGTIME,&rec,sizeof(SNUPDATEPINGTIMEREC),&rec.name,NULL); + } + curr = curr->next; + } + srv_pingcritsect.Leave(); + } + + // RE-PING THOSE USERS WHICH HAVE A USER NAME (MEANING THEY'RE IN A CHAT + // CHANNEL) AND WHICH WE LAST PINGED MORE THAN A MINUTE AGO + { + srv_pingcritsect.Enter(); + PINGPTR curr = srv_pinghead; + while (curr) { + if ((curr->username[0]) && + (currtime-curr->lastpingtime > PINGFREQUENCY)) { + curr->lastpingtime = currtime; + DWORD request = CLI_PING; + SpiSendSpecial((SNETADDRPTR)&curr->addr, + PKT_CLIENTREQ, + &request, + sizeof(DWORD)); + } + curr = curr->next; + } + srv_pingcritsect.Leave(); + } + +} + +//=========================================================================== +void SrvNotifyClickAd (DWORD adid, + BOOL result) { + struct { + DWORD adid; + DWORD action; + } req; + req.adid = adid; + req.action = (result != 0); + SendServerMessage(SID_CLICKAD,&req,sizeof(req)); +} + +//=========================================================================== +void SrvNotifyDisplayAd (DWORD id, + LPCSTR filename, + LPCSTR url) { + + // SEND THE MESSAGE TO THE SERVER + struct { + DWORD platformid; + DWORD programid; + DWORD adid; + char filenameurl[2*MAX_PATH]; + } req; + req.platformid = PLATFORMID; + req.programid = global_programid; + req.adid = id; + LPSTR curr = req.filenameurl; + strncpy(curr,filename,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + strncpy(curr,url,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + DWORD length = 3*sizeof(DWORD)+curr-req.filenameurl; + SendServerMessage(SID_DISPLAYAD,&req,length); + +} + +//=========================================================================== +void SrvNotifyJoin (LPCSTR gamename, + LPCSTR gamepassword) { + + // SEND THE MESSAGE TO THE SERVER + struct { + DWORD programid; + DWORD versionid; + char namepass[2*SNETSPI_MAXSTRINGLENGTH]; + } req; + req.programid = global_programid; + req.versionid = global_versionid; + LPSTR curr = req.namepass; + strncpy(curr,gamename,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + strncpy(curr,gamepassword,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + DWORD length = 2*sizeof(DWORD)+curr-req.namepass; + SendServerMessage(SID_NOTIFYJOIN,&req,length); + +} + +//=========================================================================== +void SrvPingAddress (SNETADDRPTR addr) { + + // DON'T PING THIS USER IF WE ALREADY HAVE A LATENCY FOR HIM + { + DWORD latency; + if (SrvGetLatency(addr,&latency)) + return; + } + + // ADD THE USER TO THE PING LIST + AddPingUser(NULL,(sockaddr_in *)addr); + +} + +//=========================================================================== +void SrvProcessClientReq (SNETADDRPTR addr, + LPBYTE data, + DWORD databytes) { + if (databytes < sizeof(DWORD)) + return; + DWORD req = *(LPDWORD)data; + data += sizeof(DWORD); + switch (req) { + + case CLI_PING: + { + DWORD response = CLI_PINGRESPONSE; + SpiSendSpecial(addr,PKT_CLIENTREQ,&response,sizeof(DWORD)); + } + break; + + case CLI_PINGRESPONSE: + { + srv_pingcritsect.Enter(); + PINGPTR userptr = srv_pinghead; + while (userptr && + memcmp(&userptr->addr,addr,sizeof(sockaddr_in))) + userptr = userptr->next; + if (userptr) { + DWORD currtime = GetTickCount(); + DWORD latency = currtime-userptr->lastpingtime; + if (userptr->latency) + userptr->latency = (userptr->latency*3+latency)/4; + else + userptr->latency = latency; + userptr->lastresponsetime = currtime; + if (userptr->username[0]) { + SNUPDATEPINGTIMEREC rec; + rec.name = userptr->username; + rec.pingtime = userptr->latency; + rec.relayed = 0; + QueueUiNotification(SN_UPDATEPINGTIME,&rec,sizeof(SNUPDATEPINGTIMEREC),&rec.name,NULL); + } + } + srv_pingcritsect.Leave(); + } + break; + + } +} + +//=========================================================================== +void SrvProcessServerPing (LPBYTE data, + DWORD databytes) { + if (databytes < sizeof(DWORD)) + return; + srv_udppingdata = *(LPDWORD)data; +} + +//=========================================================================== +BOOL SrvSendChatString (LPCSTR command) { + return SendServerMessage(SID_CHATCOMMAND,(LPVOID)command,strlen(command)+1); +} + +//=========================================================================== +void SrvSetBetaId (DWORD betaid) { + // this function is obsolete +} + +//=========================================================================== +BOOL SrvStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD gameage, + DWORD gamecategorybits, + DWORD optcategorybits) { + srv_startadvsuccess = 0; + + // SEND THE REQUEST TO THE SERVER + struct { + DWORD gamemode; + DWORD gameage; + DWORD categorybits; + DWORD optcategorybits; + DWORD reserved; + char namepassdesc[3*SNETSPI_MAXSTRINGLENGTH]; + } req; + req.gamemode = gamemode; + req.gameage = gameage; + req.categorybits = gamecategorybits; + req.optcategorybits = optcategorybits; + req.reserved = 0; + LPSTR curr = req.namepassdesc; + strncpy(curr,gamename,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + strncpy(curr,gamepassword,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + strncpy(curr,gamedescription,SNETSPI_MAXSTRINGLENGTH); + curr += strlen(curr)+1; + DWORD length = 5*sizeof(DWORD)+curr-req.namepassdesc; + if (!SendServerMessage(SID_STARTADVEX,&req,length)) + return 0; + + // IF THIS GAME HAS PREVIOUSLY BEEN ADVERTISED, ASSUME SUCCESS + if (gamemode & SNET_GM_ADVERTISED) + return 1; + + // OTHERWISE, WAIT FOR A RESPONSE FROM THE SERVER + if (!WaitForServerResponse(SID_STARTADVEX,WAIT_FLAG_NOMESSAGELOOP)) { + SetLastError(SNET_ERROR_HOST_UNREACHABLE); + return 0; + } + + if (!srv_startadvsuccess) + SetLastError(SNET_ERROR_ALREADY_EXISTS); + return srv_startadvsuccess; +} + +//=========================================================================== +BOOL SrvStopAdvertisingGame () { + if (!SendServerMessage(SID_STOPADV,NULL,0)) + return 0; + return 1; +} + diff --git a/Storm/SOURCE/BATTLE/UI.CPP b/Storm/SOURCE/BATTLE/UI.CPP new file mode 100644 index 0000000..75c59ee --- /dev/null +++ b/Storm/SOURCE/BATTLE/UI.CPP @@ -0,0 +1,882 @@ +/**************************************************************************** +* +* UI.CPP +* battle.net user interface functions +* +* By Michael Morhaime +* +***/ + +#include "pch.h" + +//**************************************************************************** +//**************************************************************************** +#define MESS_WITH_PARENT 1 // 1 in final + + +//**************************************************************************** +BOOL gbConnectionLost = FALSE; +BOOL gbConnectionSucks = FALSE; + +// This is the window that is currently ready to +// process the Battle.net nofication messages +HWND ghWndUiMainParent = (HWND) 0; + +static HWND sghDlgConnect = (HWND)0; +static HWND sghDlgCancel = (HWND)0; +static HWND sghDlgProgress = (HWND)0; + +static SNETUIDATA sgInterfacedata = { 0 }; +static int sgnDownloadProgress = 0; + +#define PALETTE_REGISTERS 256 + +static PALETTEENTRY sgPalette[PALETTE_REGISTERS]; +static PALETTEENTRY sgFadePal[PALETTE_REGISTERS]; + + + +//**************************************************************************** +static BOOL UiConnectMsg(SNETUIDATAPTR interfacedata, UINT nMessage, UINT flags); + +BOOL CALLBACK ConnectDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); +BOOL CALLBACK ConnectCancelDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); +BOOL CALLBACK LogonDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); + + +void ProtectMinimize(BOOL bEnable); +//**************************************************************************** +//**************************************************************************** +static void UiClearPalette(PALETTEENTRY * pe) { + for (int palreg = 0; palreg < PALETTE_REGISTERS; palreg++) { + pe[palreg].peRed = 0; + pe[palreg].peGreen = 0; + pe[palreg].peBlue = 0; + } +} + + + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + + +//**************************************************************************** +//**************************************************************************** +BOOL UiInitialize(SNETUIDATAPTR interfacedata) { + if (!interfacedata->artcallback) return FALSE; + + // Load scrollbar and combobox art (shared by many dialogs) + ScrollbarLoadArtwork(interfacedata->artcallback); + ComboboxLoadArtwork(interfacedata->artcallback); + return TRUE; +} + + +//**************************************************************************** +//**************************************************************************** +void UiDestroy(void) { + ScrollbarDestroyArtwork(); + ComboboxDestroyArtwork(); +} + + +//**************************************************************************** +//**************************************************************************** +void RestoreWindowsColors(void) { + HPALETTE hPal; + + // Get Windows Default colors from the system + hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE); + + GetPaletteEntries(hPal, 0, 10, &sgFadePal[0]); + GetPaletteEntries(hPal, 10, 10, &sgFadePal[PALETTE_REGISTERS-10]); + + SDrawUpdatePalette(0, PALETTE_REGISTERS, &sgFadePal[0], TRUE); +} + +//**************************************************************************** +//**************************************************************************** +int gFadeStep; +//**************************************************************************** +// an async fade function +//**************************************************************************** +void UiVidFade(int max, int curr) { + + if (max == curr) { + memcpy(sgFadePal, sgPalette, (PALETTE_REGISTERS * sizeof(PALETTEENTRY))); + ShowCursor(TRUE); + } + else if (curr == 0) { + memcpy(sgFadePal, sgPalette, (PALETTE_REGISTERS * sizeof(PALETTEENTRY))); + UiClearPalette(sgFadePal); + } + else { + for (int palreg = 0; palreg < PALETTE_REGISTERS; palreg++) { + sgFadePal[palreg].peRed = (sgPalette[palreg].peRed * curr) / max; + sgFadePal[palreg].peGreen = (sgPalette[palreg].peGreen * curr) / max; + sgFadePal[palreg].peBlue = (sgPalette[palreg].peBlue * curr) / max; + } + } + SDrawUpdatePalette(0, PALETTE_REGISTERS, sgFadePal, TRUE); +} + + +//**************************************************************************** +//**************************************************************************** +void UiVidFadeOut(int steps) { + ShowCursor(FALSE); + + memcpy(sgFadePal, sgPalette, (PALETTE_REGISTERS * sizeof(PALETTEENTRY))); + + for (int index = 0; index < steps; index++) { + for (int palreg = 0; palreg < PALETTE_REGISTERS; palreg++) { + sgFadePal[palreg].peRed -= (sgPalette[palreg].peRed / steps); + sgFadePal[palreg].peGreen -= (sgPalette[palreg].peGreen / steps); + sgFadePal[palreg].peBlue -= (sgPalette[palreg].peBlue / steps); + } + SDrawUpdatePalette(0, PALETTE_REGISTERS, sgFadePal, TRUE); + } + + UiClearPalette(sgFadePal); + SDrawUpdatePalette(0, PALETTE_REGISTERS, sgFadePal, TRUE); + + SDrawClearSurface(SDRAW_SURFACE_FRONT); + RestoreWindowsColors(); +} + +//=========================================================================== +// UiSetCursors() +// +// This routine must be called once the first time a dialog with a new class +// is displayed, so we can set the cursor for that particular class. +//=========================================================================== +void UiLoadCursors(HWND hWnd, SNETUIDATAPTR interfacedata) { + HCURSOR OldArrow = NULL; + HCURSOR OldIBeam = NULL; + + if (!interfacedata || !interfacedata->getdatacallback) + return; + +#if 0 + HCURSOR hCursor; + + // Get arrow cursor + if (interfacedata->getdatacallback( + PROVIDERID, + SNET_DATA_CURSORARROW, + &hCursor, + sizeof(hCursor), + NULL)) + SDlgSetCursor(hWnd, hCursor, OCR_NORMAL); + + + // Get ibeam cursor + if (interfacedata->getdatacallback( + PROVIDERID, + SNET_DATA_CURSORIBEAM, + &hCursor, + sizeof(hCursor), + NULL)) + SDlgSetCursor(hWnd, hCursor, OCR_IBEAM); +#else + + // Use System default cursors until we solve modal dialog issues. + // (whenever the mouse is over a disabled window (like the parent of a modal dialog) + // windows will display the default system cursor)). + SDlgSetCursor(hWnd, LoadCursor(NULL, IDC_ARROW), OCR_NORMAL, &OldArrow); + SDlgSetCursor(hWnd, LoadCursor(NULL, IDC_IBEAM), OCR_IBEAM, &OldIBeam); + +#endif +} + +//=========================================================================== +BOOL UiGetData(SNETGETDATAPROC getdatacallback, + DWORD dataid, + LPBYTE *data, + DWORD *datasize) { + + DWORD dwSize; + + *data = 0; + + if (!getdatacallback) + return 0; + + + // CALL THE GET DATA CALLBACK TO DETERMINE DATA SIZE + if (!getdatacallback(PROVIDERID, + dataid, + NULL, + 0, + &dwSize)) + return 0; + + + // ALLOCATE MEMORY FOR THE IMAGE + if (!(*data = (LPBYTE)ALLOC(dwSize))) + return 0; + + // LOAD THE DATA BLOCK + if (!getdatacallback(PROVIDERID, + dataid, + *data, + dwSize, + NULL)) { + FREE(*data); + *data = NULL; + return 0; + } + + *datasize = dwSize; + return 1; +} + +//=========================================================================== +BOOL UiLoadArtwork (SNETGETARTPROC artcallback, + HWND hWnd, + HWND hWndParent, + DWORD artid, + LPCTSTR controltype, + DWORD controlstyle, + LONG usageflags, + BOOL loadpalette, + BOOL prepfadein, + LPBYTE *data, + SIZE *size) { + PALETTEENTRY pe[256]; + + *data = 0; + + // VERIFY THAT THE APPLICATION HAS REGISTERED AN ARTWORK CALLBACK + if (!artcallback) + return 0; + + // CALL THE ARTWORK CALLBACK TO DETERMINE THE IMAGE DIMENSIONS + int width = 0; + int height = 0; + int bitdepth; + if (!artcallback(PROVIDERID, + artid, + NULL, + NULL, + 0, + &width, + &height, + &bitdepth)) + return 0; + if (size) { + size->cx = width; + size->cy = height; + } + + + // ALLOCATE MEMORY FOR THE IMAGE + DWORD bytes = width*height*bitdepth/8; + if (!(*data = (LPBYTE)ALLOC(bytes))) + return 0; + + // LOAD THE IMAGE + if (!artcallback(PROVIDERID, + artid, + &pe[0], + *data, + bytes, + &width, + &height, + &bitdepth)) { + FREE(*data); + *data = NULL; + return 0; + } + + + // IF THIS IS A SCREEN BACKGROUND, USE ITS PALETTE + if (loadpalette) { + HPALETTE hPal; + + // Get Windows Default colors from the system + hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE); + GetPaletteEntries(hPal, 0, 10, &pe[0]); + GetPaletteEntries(hPal, 10, 10, &pe[PALETTE_REGISTERS-10]); + memcpy(sgPalette, pe, (PALETTE_REGISTERS * sizeof(PALETTEENTRY))); + + if (!prepfadein) { + SDrawUpdatePalette(0, PALETTE_REGISTERS, &sgPalette[0], TRUE); + } + else { + UiClearPalette(pe); + SDrawUpdatePalette(0, PALETTE_REGISTERS, pe, TRUE); + gFadeStep = 0; + } + } + + + // If we have a window to associate it with, register the bitmap, + if (hWnd || hWndParent) { + SDlgSetBitmap( + hWnd, + hWndParent, + controltype, + controlstyle, + usageflags, + *data, + NULL, + width, + height); + } + + return 1; +} + + +//=========================================================================== +BOOL UiSetCustomArt (HWND hWnd, + PALETTEENTRY *pe, + int nFirstColor, + int nNumColorsUsed, + BOOL bSetPaletteNow, + LPBYTE data, + int nWidth, + int nHeight) { + + if (nNumColorsUsed) + memcpy(&sgPalette[nFirstColor], &pe[nFirstColor], (nNumColorsUsed * sizeof(PALETTEENTRY))); + + if (bSetPaletteNow) + SDrawUpdatePalette(nFirstColor, nNumColorsUsed, &sgPalette[nFirstColor]); + + // If we have a window to associate it with, register the bitmap, + if (hWnd) { + SDlgSetBitmap( + hWnd, + NULL, + NULL, + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + data, + NULL, + nWidth, + nHeight); + + InvalidateRect(hWnd, NULL, FALSE); + } + + return 1; +} + + +//=========================================================================== +BOOL UiLoadCustomArt ( + SNETGETARTPROC artcallback, + HWND hWnd, + DWORD artid, + int nFirstColor, + int nNumColorsUsed, + BOOL bSetPaletteNow, + LPBYTE *data, + SIZE *size) { + PALETTEENTRY pe[256]; + + *data = 0; + + // VERIFY THAT THE APPLICATION HAS REGISTERED AN ARTWORK CALLBACK + if (!artcallback) + return 0; + + // CALL THE ARTWORK CALLBACK TO DETERMINE THE IMAGE DIMENSIONS + int width = 0; + int height = 0; + int bitdepth; + if (!artcallback(PROVIDERID, + artid, + NULL, + NULL, + 0, + &width, + &height, + &bitdepth)) + return 0; + if (size) { + size->cx = width; + size->cy = height; + } + + + // ALLOCATE MEMORY FOR THE IMAGE + DWORD bytes = width*height*bitdepth/8; + if (!(*data = (LPBYTE)ALLOC(bytes))) + return 0; + + // LOAD THE IMAGE + if (!artcallback(PROVIDERID, + artid, + &pe[0], + *data, + bytes, + &width, + &height, + &bitdepth)) { + FREE(*data); + *data = NULL; + return 0; + } + + + UiSetCustomArt( + hWnd, + &pe[0], + nFirstColor, + nNumColorsUsed, + bSetPaletteNow, + *data, + width, + height); + + return 1; +} + +//=========================================================================== +BOOL UiLogon (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) +{ + return (1 == SDlgDialogBoxParam( + global_hinstance, + TEXT("DIALOG_LOGON"), + (interfacedata) ? interfacedata->parentwindow : SDrawGetFrameWindow(), + LogonDialogProc, + (LPARAM) interfacedata)); +} + + +//=========================================================================== +BOOL UiBeginConnect (SNETPROGRAMDATAPTR programdata, + SNETUIDATAPTR interfacedata) { + + static UIPARAMS suiparams; + HWND hWndParent; + + + ZeroMemory(&suiparams,sizeof(UIPARAMS)); + suiparams.flags = 0; + suiparams.programdata = programdata; + suiparams.playerdata = NULL; + suiparams.interfacedata = interfacedata; + suiparams.versiondata = 0; + suiparams.playeridptr = 0; + + gbConnectionLost = FALSE; // Make sure this is reset. + gbConnectionSucks = FALSE; // If it sucks, Storm will tell us. + + + // Display a popup of some sort that has some sort of + // connecting animation. + + if (!interfacedata) + return 0; + + hWndParent = interfacedata->parentwindow; + +#if MESS_WITH_PARENT + // Hide parent window before dialog can set palette (if parent is not the frame window) + if (SDrawGetFrameWindow() != hWndParent) { + SetActiveWindow(GetParent(hWndParent)); + ShowWindow(hWndParent, SW_HIDE); + } +#endif + + // Erase screen + SDrawClearSurface(SDRAW_SURFACE_FRONT); + + // DISPLAY THE DIALOG BOX + sghDlgConnect = SDlgCreateDialogParam( + global_hinstance, + TEXT("DIALOG_CONNECT_BG"), + hWndParent, + ConnectDialogProc, + (LPARAM)&suiparams); + + // Copy interfacedata for use later by children of connect dlg + sgInterfacedata = *interfacedata; + sgInterfacedata.parentwindow = sghDlgConnect; + + if (sghDlgConnect) { + // Display popup to allow user to cancel + sghDlgCancel = SDlgCreateDialogParam( + global_hinstance, + TEXT("DIALOG_CONNECT_CANCEL"), + sghDlgConnect, + ConnectCancelDialogProc, + (LPARAM)&sgInterfacedata); + + ProtectMinimize(TRUE); + } + + return (sghDlgConnect != (HWND)0); +} + +//=========================================================================== +void UiEndConnect (BOOL connected) { + if (sghDlgConnect) { + ProtectMinimize(FALSE); + +#if MESS_WITH_PARENT + if (SDrawGetFrameWindow() != GetParent(sghDlgConnect)) { + if (connected) { + // Parent is hidden right now. Make the frame window active so that + // we don't lose the focus completely when sghDlgConnect is destroyed. + SetActiveWindow(GetParent(GetParent(sghDlgConnect))); + } + else + ShowWindow(GetParent(sghDlgConnect), SW_SHOW); + } +#endif + + DestroyWindow(sghDlgConnect); + sghDlgConnect = (HWND) 0; + sghDlgCancel = (HWND) 0; // Cancel will be destroyed automatically + + } + + sgInterfacedata.parentwindow = NULL; +} + + +//**************************************************************************** +//**************************************************************************** +void UiRestoreApp(void) { + // Switch back to our app and do a restore + SetActiveWindow(SDrawGetFrameWindow()); + ShowWindow(SDrawGetFrameWindow(), SW_RESTORE); + + // Flush out messages before continuing to allow all our windows to + // know that we are back. + UiProcessWindowMessages(); +} + + +//******************************************** +//******************************************** +extern BOOL CALLBACK RasEnumCallback(LPCTSTR szEntryName, LPVOID rashandle, LPVOID lpContext); + +BOOL UiDisconnect(void) { + EnumNewRASConnections(RasEnumCallback, (LPVOID) &sgInterfacedata); + return 1; +} + +//=========================================================================== +static BOOL UiConnectMsg(SNETUIDATAPTR interfacedata, UINT nMessage, UINT flags) { + char szText[512]; + char szTitle[32]; + DWORD dwReturn; + + if (!interfacedata) + return 0; + + if (!interfacedata->messageboxcallback) + return 0; + + if (!interfacedata->parentwindow) + return 0; + + + LoadString(global_hinstance, IDS_BATTLENET, szTitle, sizeof(szTitle)); + LoadString(global_hinstance, nMessage, szText, sizeof(szText)); + + dwReturn = UiMessageBox( + interfacedata->messageboxcallback, + interfacedata->parentwindow, + szText, + szTitle, + flags); + + return (dwReturn == IDOK); +} + + +//=========================================================================== +static int CALLBACK GetDownloadProgress(void) { + return sgnDownloadProgress; +} + +//=========================================================================== +BOOL UiProcessWindowMessages (void) { + MSG message; + while (PeekMessage(&message,(HWND)0,0,0,PM_REMOVE)) { + if (message.message == WM_QUIT) { + PostMessage(message.hwnd,message.message,message.wParam,message.lParam); + return 0; + } + else if (((!sghDlgConnect) || (!IsDialogMessage(sghDlgConnect ,&message))) && + ((!sghDlgProgress) || (!IsDialogMessage(sghDlgProgress,&message))) && + ((!sghDlgCancel) || (!IsDialogMessage(sghDlgCancel ,&message)))) { + TranslateMessage(&message); + DispatchMessage(&message); + } + } + + SDlgCheckTimers(); + return 1; +} + +//=========================================================================== +void UiHideConnectCancel(void) { + // Hide cancel button when any popups are displayed + if (!sghDlgCancel) + return; + + // Get rid of Cancel Dlg + DestroyWindow(sghDlgCancel); + sghDlgCancel = NULL; +} + +//=========================================================================== +void UiWSockErrMessage(void) { + UiHideConnectCancel(); + UiConnectMsg(&sgInterfacedata, IDS_ERR_NOWSOCK32, MB_OK | MB_ICONWARNING); + return; +} + +//=========================================================================== +BOOL UiUpgradeMessage(void) { + UiHideConnectCancel(); + + // Okay minimization fears are over also + ProtectMinimize(FALSE); + return UiConnectMsg(&sgInterfacedata, IDS_ASK_UPDATE, MB_OKCANCEL); +} + + +//=========================================================================== +void UiNotificationWaiting(void) { + if (!ghWndUiMainParent) + return; + + PostMessage(ghWndUiMainParent, WM_NOTIFICATION_WAITING, 0, 0); +} + +//=========================================================================== +//=========================================================================== +void UiNotification (void) { + DWORD notifycode; + LPVOID paramdata; + DWORD parambytes; + + // NOTE: paramdata will no longer be valid after hitting a PeekMessage loop, + // All routines called from here must make sure that data from paramdata is + // copied before sent to a message box or to any routines that might yield control!!! + while (SrvGetUiNotification (¬ifycode, ¶mdata, ¶mbytes)) { + switch (notifycode) { + case SN_ADDCHANNEL: + ChatAddChannel((LPCSTR) paramdata); + break; + case SN_DELETECHANNEL: + ChatDeleteChannel((LPCSTR) paramdata); + break; + case SN_JOINCHANNEL: + ChatJoinChannel((SNJOINCHANNELPTR) paramdata); + break; + case SN_CHANNELISFULL: + ChatChannelFull((LPCSTR) paramdata); + break; + case SN_CHANNELDOESNOTEXIST: + ChatChannelDoesNotExist((LPCSTR) paramdata); + break; + case SN_CHANNELISRESTRICTED: + ChatChannelRestricted((LPCSTR) paramdata); + break; + + case SN_ADDUSER: + ChatAddUser((SNADDUSERPTR) paramdata); + break; + case SN_DELETEUSER: + ChatDeleteUser((SNDELETEUSERPTR) paramdata); + break; + case SN_USERNAME: + ChatSetUserName((LPCSTR) paramdata); + break; + + case SN_CHANGEUSERFLAGS: + ChatChangeUserFlags((SNCHANGEUSERFLAGSPTR) paramdata); + break; + + case SN_UPDATEPINGTIME: + ChatUpdatePingTime((SNUPDATEPINGTIMEPTR) paramdata); + break; + + case SN_DISPLAYSTRING: + // Got a message from someone + ChatReceiveMsg((SNDISPLAYSTRINGPTR) paramdata); + break; + + case SN_SQUELCHUSER: + ChatSquelchUser((SNSQUELCHUSERPTR) paramdata); + break; + + case SN_UNSQUELCHUSER: + ChatUnsquelchUser((SNSQUELCHUSERPTR) paramdata); + break; + + + case SN_BADCONNECTION: + UiConnectMsg(&sgInterfacedata, IDS_ERR_BADSERVICEPROVIDER, MB_OK | MB_ICONERROR); + gbConnectionSucks = TRUE; + break; + + case SN_SETADINFO: + AdSetInfo((SNADINFOPTR) paramdata); + break; + + case SN_DISPLAYAD: + AdDisplay((LPVOID) paramdata, parambytes); + break; + + case SN_DOWNLOADINGUPGRADE: { + DWORD *pDword = (DWORD *)paramdata; + sgnDownloadProgress = *pDword; + + if (!sghDlgProgress) { + char szText[128]; + + LoadString(global_hinstance, IDS_DOWNLOADPROGRESS, szText, sizeof(szText)); + sghDlgProgress = UiModelessProgressDialog( + &sgInterfacedata, + szText, + TRUE, // Allow user to abort + GetDownloadProgress, + 20); // Frequency of progress update (FPS) + } + + break; + } + + case SN_DOWNLOADFAILED: + if (sghDlgProgress) { + DestroyWindow(sghDlgProgress); + sghDlgProgress = NULL; + } + UiConnectMsg(&sgInterfacedata, IDS_ERR_DOWNLOADFAILED, MB_OK | MB_ICONERROR); + break; + + case SN_DOWNLOADSUCCEEDED: + if (sghDlgProgress) { + DestroyWindow(sghDlgProgress); + sghDlgProgress = NULL; + } + + UiConnectMsg(&sgInterfacedata, IDS_PREP_RESTART, MB_OK); + break; + + + case SN_FAILEDTOCONNECT: { + DWORD *pdwError = (DWORD *)paramdata; + int nMsgNo; + + switch (*pdwError) { + case SN_ERROR_NOTRESPONDING: + nMsgNo = IDS_ERR_NOTRESPONDING; + break; + + case SN_ERROR_BADCONNECTION: + nMsgNo = IDS_ERR_BADCONNECTION; + break; + + case SN_ERROR_UNABLETOUPGRADE: + nMsgNo = IDS_ERR_UNABLETOUPGRADE; + break; + + case SN_ERROR_UNREACHABLE: + nMsgNo = IDS_ERR_UNREACHABLE; + break; + + default: + nMsgNo = IDS_ERR_UNREACHABLE; + } + + UiHideConnectCancel(); + + // Okay minimization fears are over also + ProtectMinimize(FALSE); + UiConnectMsg(&sgInterfacedata, nMsgNo, MB_OK | MB_ICONERROR); + break; + } + case SN_LOSTCONNECTION: + // We can't display a message here, so set a flag to display a message. + // This will cause the chatroom to abort. + gbConnectionLost = TRUE; + break; + + case SN_MESSAGEBOX: { + SNMESSAGEBOXPTR ptr; + + ptr = (SNMESSAGEBOXPTR)paramdata; + if (!sgInterfacedata.messageboxcallback) + MessageBox(ghWndUiMainParent, ptr->text, ptr->caption, ptr->type); + else + sgInterfacedata.messageboxcallback(ghWndUiMainParent, ptr->text, ptr->caption, ptr->type); + + break; + } + + } // end switch + + } // end while + +} + + + +//=========================================================================== +BOOL UiSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + + // BUILD A USER INTERFACE DATA BLOCK + UIPARAMS uiparams; + ZeroMemory(&uiparams,sizeof(UIPARAMS)); + uiparams.flags = flags; + uiparams.programdata = programdata; + uiparams.playerdata = playerdata; + uiparams.interfacedata = interfacedata; + uiparams.versiondata = versiondata; + uiparams.playeridptr = playerid; + + + if (!interfacedata) + return 0; + + + // Take control of system colors using app preferences + ColorPrefInit(interfacedata->getdatacallback); + + + // DISPLAY THE DIALOG BOX + DWORD result = (DWORD)SDlgDialogBoxParam(global_hinstance, + TEXT("DIALOG_BATTLENET"), + interfacedata->parentwindow, + BattleNetDialogProc, + (LPARAM)&uiparams); + + // Restore Windows System Colors + ColorPrefDestroy(); + + return (result == 1); +} diff --git a/Storm/SOURCE/BATTLE/battle.vcxproj b/Storm/SOURCE/BATTLE/battle.vcxproj new file mode 100644 index 0000000..79d8d3c --- /dev/null +++ b/Storm/SOURCE/BATTLE/battle.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + 17.0 + Win32Proj + Battle + battle + 10.0 + {B4E1FEBB-C3BF-3A04-7233-143B85E3413E} + + + + DynamicLibrary + true + v145 + MultiByte + + + DynamicLibrary + false + v143 + true + MultiByte + + + + + + + + + + + + + $(ProjectDir)..\..\..\bin\ + $(ProjectDir)$(Configuration)\ + battle + .snp + false + + + true + + + false + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;BATTLE_EXPORTS;%(PreprocessorDefinitions) + NotUsing + PCH.H + ProgramDatabase + true + false + + + Windows + true + BATTLE.DEF + wsock32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;BATTLE_EXPORTS;%(PreprocessorDefinitions) + NotUsing + PCH.H + true + false + + + Windows + true + true + true + BATTLE.DEF + wsock32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {43dd7e96-bf0f-4e3b-85f4-1eeafa46583a} + + + + + \ No newline at end of file diff --git a/Storm/SOURCE/BATTLE/battle.vcxproj.user b/Storm/SOURCE/BATTLE/battle.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Storm/SOURCE/BATTLE/battle.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Storm/SOURCE/BLIZZARD.KEY b/Storm/SOURCE/BLIZZARD.KEY new file mode 100644 index 0000000..bcf2484 Binary files /dev/null and b/Storm/SOURCE/BLIZZARD.KEY differ diff --git a/Storm/SOURCE/BUILDMC.BAT b/Storm/SOURCE/BUILDMC.BAT new file mode 100644 index 0000000..7afc5a9 --- /dev/null +++ b/Storm/SOURCE/BUILDMC.BAT @@ -0,0 +1,4 @@ +@echo off +mc stormerr.mc +del stormerr.h +del stormerr.rc diff --git a/Storm/SOURCE/C.EXE b/Storm/SOURCE/C.EXE new file mode 100644 index 0000000..be3a0a4 Binary files /dev/null and b/Storm/SOURCE/C.EXE differ diff --git a/Storm/SOURCE/CRTDLL.LIB b/Storm/SOURCE/CRTDLL.LIB new file mode 100644 index 0000000..bdf4b59 Binary files /dev/null and b/Storm/SOURCE/CRTDLL.LIB differ diff --git a/Storm/SOURCE/EXPORTS.DEF b/Storm/SOURCE/EXPORTS.DEF new file mode 100644 index 0000000..bf3e133 --- /dev/null +++ b/Storm/SOURCE/EXPORTS.DEF @@ -0,0 +1,237 @@ +EXPORTS +; +; Network functions (101-131) +; +SNetCreateGame @101 NONAME +SNetDestroy @102 NONAME +SNetEnumDevices @103 NONAME +SNetEnumGames @104 NONAME +SNetEnumProviders @105 NONAME +SNetDropPlayer @106 NONAME +SNetGetGameInfo @107 NONAME +SNetGetNetworkLatency @108 NONAME +SNetGetNumPlayers @109 NONAME +SNetGetOwnerTurnsWaiting @110 NONAME +SNetGetPerformanceData @111 NONAME +SNetGetPlayerCaps @112 NONAME +SNetGetPlayerName @113 NONAME +SNetGetProviderCaps @114 NONAME +SNetGetTurnsInTransit @115 NONAME +SNetInitializeDevice @116 NONAME +SNetInitializeProvider @117 NONAME +SNetJoinGame @118 NONAME +SNetLeaveGame @119 NONAME +SNetPerformUpgrade @120 NONAME +SNetReceiveMessage @121 NONAME +SNetReceiveTurns @122 NONAME +SNetRegisterEventHandler @123 NONAME +SNetResetLatencyMeasurements @124 NONAME +SNetSelectGame @125 NONAME +SNetSelectProvider @126 NONAME +SNetSendMessage @127 NONAME +SNetSendTurn @128 NONAME +SNetSetBasePlayer @129 NONAME +SNetSetGameMode @130 NONAME +SNetUnregisterEventHandler @131 NONAME +SNetGetOwnerId @132 NONAME +SNetEnumGamesEx @133 NONAME +SNetSendServerChatCommand @134 NONAME +; +; Dialog manager functions (201-220) +; +SDlgBeginPaint @201 NONAME +SDlgBltToWindowI @202 NONAME +SDlgCheckTimers @203 NONAME +SDlgCreateDialogIndirectParam @204 NONAME +SDlgCreateDialogParam @205 NONAME +SDlgDefDialogProc @206 NONAME +SDlgDialogBoxIndirectParam @208 NONAME +SDlgDialogBoxParam @209 NONAME +SDlgDrawBitmap @210 NONAME +SDlgEndDialog @211 NONAME +SDlgEndPaint @212 NONAME +SDlgKillTimer @213 NONAME +SDlgSetBaseFont @214 NONAME +SDlgSetBitmapI @215 NONAME +SDlgSetControlBitmaps @216 NONAME +SDlgSetCursor @217 NONAME +SDlgSetSystemCursor @218 NONAME +SDlgSetTimer @219 NONAME +SDlgUpdateCursor @220 NONAME +SDlgBltToWindowE @221 NONAME +SDlgSetBitmapE @222 NONAME +; +; File I/O functions (251-272) +; +SFileAuthenticateArchive @251 NONAME +SFileCloseArchive @252 NONAME +SFileCloseFile @253 NONAME +SFileDdaBegin @254 NONAME +SFileDdaBeginEx @255 NONAME +SFileDdaDestroy @256 NONAME +SFileDdaEnd @257 NONAME +SFileDdaGetPos @258 NONAME +SFileDdaGetVolume @259 NONAME +SFileDdaInitialize @260 NONAME +SFileDdaSetVolume @261 NONAME +SFileEnableDirectAccess @263 NONAME +SFileGetFileArchive @264 NONAME +SFileGetFileSize @265 NONAME +SFileOpenArchive @266 NONAME +SFileOpenFile @267 NONAME +SFileOpenFileEx @268 NONAME +SFileReadFile @269 NONAME +SFileSetBasePath @270 NONAME +SFileSetFilePointer @271 NONAME +SFileSetLocale @272 NONAME +SFileGetBasePath @273 NONAME +SFileSetIoErrorMode @274 NONAME +SFileGetArchiveName @275 NONAME +SFileGetFileName @276 NONAME +SFileGetArchiveInfo @277 NONAME +; +; Other functions (301+) +; +StormDestroy @301 NONAME +SBltGetSCode @312 NONAME +SBltROP3 @313 NONAME +SBltROP3Clipped @314 NONAME +SBltROP3Tiled @315 NONAME +SBmpDecodeImage @321 NONAME +SBmpLoadImage @323 NONAME +SBmpSaveImage @324 NONAME +SBmpAllocLoadImage @325 NONAME +SCodeCompile @331 NONAME +SCodeDelete @332 NONAME +SCodeExecute @334 NONAME +SCodeGetPseudocode @335 NONAME +SDrawAutoInitialize @341 NONAME +SDrawCaptureScreen @342 NONAME +SDrawClearSurface @343 NONAME +SDrawDestroy @344 NONAME +SDrawFlipPage @345 NONAME +SDrawGetFrameWindow @346 NONAME +SDrawGetObjects @347 NONAME +SDrawGetScreenSize @348 NONAME +SDrawGetServiceLevel @349 NONAME +SDrawLockSurface @350 NONAME +SDrawManualInitialize @351 NONAME +SDrawMessageBox @352 NONAME +SDrawPostClose @353 NONAME +SDrawRealizePalette @354 NONAME +SDrawSelectGdiSurface @355 NONAME +SDrawUnlockSurface @356 NONAME +SDrawUpdatePalette @357 NONAME +SDrawUpdateScreen @358 NONAME +SEvtDispatch @372 NONAME +SEvtRegisterHandler @373 NONAME +SEvtUnregisterHandler @374 NONAME +SEvtUnregisterType @375 NONAME +SEvtPopState @376 NONAME +SEvtPushState @377 NONAME +SEvtBreakHandlerChain @378 NONAME +SGdiBitBlt @381 NONAME +SGdiCreateFont @382 NONAME +SGdiDeleteObject @383 NONAME +SGdiExtTextOut @385 NONAME +SGdiImportFont @386 NONAME +SGdiLoadFont @387 NONAME +SGdiRectangle @388 NONAME +SGdiSelectObject @389 NONAME +SGdiSetPitch @390 NONAME +SGdiTextOut @391 NONAME +SGdiSetTargetDimensions @392 NONAME +SGdiGetTextExtent @393 NONAME +SMemAlloc @401 NONAME +SMemFree @403 NONAME +SMsgDispatchMessage @412 NONAME +SMsgDoMessageLoop @413 NONAME +SMsgRegisterCommand @414 NONAME +SMsgRegisterKeyDown @415 NONAME +SMsgRegisterKeyUp @416 NONAME +SMsgRegisterMessage @417 NONAME +SMsgPopRegisterState @418 NONAME +SMsgPushRegisterState @419 NONAME +SRegLoadData @421 NONAME +SRegLoadString @422 NONAME +SRegLoadValue @423 NONAME +SRegSaveData @424 NONAME +SRegSaveString @425 NONAME +SRegSaveValue @426 NONAME +SRegGetBaseKey @427 NONAME +STransBlt @431 NONAME +STransBltUsingMask @432 NONAME +STransCreateI @433 NONAME +STransDelete @434 NONAME +STransDuplicate @436 NONAME +STransIntersectDirtyArray @437 NONAME +STransInvertMask @438 NONAME +STransLoadI @439 NONAME +STransSetDirtyArrayInfo @440 NONAME +STransUpdateDirtyArray @441 NONAME +STransIsPixelInMask @442 NONAME +STransCombineMasks @443 NONAME +STransCreateMaskI @444 NONAME +STransCreateE @445 NONAME +STransCreateMaskE @446 NONAME +STransLoadE @447 NONAME +SVidDestroy @451 NONAME +SVidGetSize @452 NONAME +SVidInitialize @453 NONAME +SVidPlayBegin @454 NONAME +SVidPlayBeginFromMemory @455 NONAME +SVidPlayContinue @456 NONAME +SVidPlayContinueSingle @457 NONAME +SVidPlayEnd @458 NONAME +SVidSetVolume @459 NONAME +SErrDisplayError @461 NONAME +SErrGetErrorStr @462 NONAME +SErrGetLastError @463 NONAME +SErrRegisterMessageSource @464 NONAME +SErrSetLastError @465 NONAME +SErrReportResourceLeak @467 NONAME +SErrSuppressErrors @468 NONAME +SCmdGetBool @472 NONAME +SCmdGetNum @473 NONAME +SCmdGetString @474 NONAME +SCmdProcess @475 NONAME +SCmdRegisterArgList @476 NONAME +SCmdRegisterArgument @477 NONAME +SCmdCheckId @478 NONAME +SMemFindNextBlock @481 NONAME +SMemFindNextHeap @482 NONAME +SMemGetHeapByCaller @483 NONAME +SMemGetHeapByPtr @484 NONAME +SMemHeapAlloc @485 NONAME +SMemHeapCreate @486 NONAME +SMemHeapDestroy @487 NONAME +SMemHeapFree @488 NONAME +SStrCopy @501 NONAME +SStrHash @502 NONAME +SStrPack @503 NONAME +SStrTokenize @504 NONAME +SStrChr @505 NONAME +SStrLen @506 NONAME +SMsgBreakHandlerChain @511 NONAME +SMsgUnregisterCommand @512 NONAME +SMsgUnregisterKeyDown @513 NONAME +SMsgUnregisterKeyUp @514 NONAME +SMsgUnregisterMessage @515 NONAME +SRgnClear @521 NONAME +SRgnCombineRect @523 NONAME +SRgnCreate @524 NONAME +SRgnDelete @525 NONAME +SRgnDuplicate @527 NONAME +SRgnGetRectParams @528 NONAME +SRgnGetRects @529 NONAME +SRgnGetBoundingRect @530 NONAME +SLogClose @541 NONAME +SLogCreate @542 NONAME +SLogDump @544 NONAME +SLogFlush @545 NONAME +SLogFlushAll @546 NONAME +SLogPend @547 NONAME +SLogWrite @548 NONAME +SCompCompress @551 NONAME +SCompDecompress @552 NONAME +SDirectDrawCreate @553 NONAME diff --git a/Storm/SOURCE/IPXTEST/IPXTEST.CPP b/Storm/SOURCE/IPXTEST/IPXTEST.CPP new file mode 100644 index 0000000..e0c9cf6 --- /dev/null +++ b/Storm/SOURCE/IPXTEST/IPXTEST.CPP @@ -0,0 +1,1445 @@ +/**************************************************************************** +* +* IPXTEST.CPP +* IPX test network provider +* +* By Michael O'Brien (9/25/96) +* +***/ + +#define STRICT +#include +#include +#include +#include +#include "resource.h" + +#define ADVPORT 6113 +#define MAINPORT 6114 +#define MAXMESSAGESIZE 504 +#define MAXPLAYERS 256 +#define PROVIDERID 'TEST' +#define RECVDATATHREADS 2 + +#define ADTYPE_GAMEINFO 0 +#define ADTYPE_REMOVE 1 +#define ADTYPE_REQUEST 2 + +typedef struct _ADVHEADER { + WORD checksum; // must be first field + WORD length; + WORD type; + WORD reserved; + DWORD programid; + DWORD versionid; + DWORD gamemode; +} ADVHEADER, *ADVHEADERPTR; + +typedef struct _ADVPACKET { + ADVHEADER header; + char strings[SNETSPI_MAXSTRINGLENGTH*2]; +} ADVPACKET, *ADVPACKETPTR; + +typedef struct _PACKET { + SNETADDR addr; // must be first field in structure + BYTE data[MAXMESSAGESIZE]; + DWORD databytes; + _PACKET *next; +} PACKET, *PACKETPTR; + +typedef struct _SENDREC { + DWORD sendtime; + SOCKET s; + SOCKADDR_IPX addr; + char *data; + int databytes; + _SENDREC *next; +} SENDREC, *SENDPTR; + +typedef struct _UIPARAMS { + DWORD flags; + SNETPROGRAMDATAPTR programdata; + SNETPLAYERDATAPTR playerdata; + SNETUIDATAPTR interfacedata; + SNETVERSIONDATAPTR versiondata; + LPDWORD playeridptr; +} UIPARAMS, *UIPARAMSPTR; + +typedef struct _THREAD { + DWORD id; + HANDLE handle; + _THREAD *next; +} THREAD, *THREADPTR; + +typedef struct _TESTPARMS { + DWORD mindelay; + DWORD maxdelay; + DWORD corruptpercent; +} TESTPARMS, *TESTPARMSPTR; + +static ADVPACKETPTR ipx_advgameinfo = NULL; +static SOCKET ipx_advsocket = (SOCKET)0; +static SOCKADDR_IPX ipx_broadcastaddr = {0}; +static CCritSect ipx_critsect; +static SNETSPI_GAMELISTPTR ipx_gamehead = NULL; +static HINSTANCE ipx_instance = (HINSTANCE)0; +static SOCKADDR_IPX ipx_localaddr = {0}; +static DWORD ipx_nextgameid = 0; +static SOCKET ipx_mainsocket = (SOCKET)0; +static DWORD ipx_maxplayers = MAXPLAYERS; +static PACKETPTR ipx_packethead = NULL; +static DWORD ipx_programid = 0; +static HANDLE ipx_recvevent = NULL; +static SENDPTR ipx_sendhead = NULL; +static BOOL ipx_shutdown = 0; +static TESTPARMS ipx_testparms = {200,300,5}; +static THREADPTR ipx_threadhead = NULL; +static DWORD ipx_versionid = 0; + +static void SendAdvertisement (); +static void SendRequest (); +static void TrimGameList (DWORD timeout); +static void UpdateGameList (HWND dialog, HWND listbox); +BOOL CALLBACK IpxCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude); +BOOL CALLBACK IpxStopAdvertisingGame (); + +//=========================================================================== +static WORD ComputeChecksum (LPVOID data, DWORD databytes) { + DWORD checkval1 = 0; + DWORD checkval2 = 0; + LPBYTE ptr = ((LPBYTE)data)+databytes-1; + while (databytes--) { + checkval1 += *ptr--; + if (checkval1 >= 0xFF) + checkval1 -= 0xFF; + checkval2 += checkval1; + } + checkval2 %= 255; + return MAKEWORD((checkval2 & 0xFF),(checkval1 & 0xFF)); +} + +//=========================================================================== +static WORD GenerateChecksum (LPVOID packet, DWORD bytes) { + + // COMPUTE THE CURRENT CHECKSUM FOR THE MESSAGE + WORD checksum = ComputeChecksum(((LPBYTE)packet)+sizeof(WORD), + bytes-sizeof(WORD)); + + // COMPUTE A NEW VALUE FOR THE CHECKSUM FIELD THAT WILL MAKE THE NEW + // CHECKSUM OF THE ENTIRE MESSAGE ZERO + BYTE hibyte = 0xFF-((checksum >> 8)+(checksum & 0xFF)) % 0xFF; + BYTE lobyte = 0xFF-((checksum >> 8)+hibyte) % 0xFF; + return MAKEWORD(lobyte,hibyte); +} + +//=========================================================================== +static BOOL LoadArtwork (SNETGETARTPROC artcallback, + DWORD providerid, + DWORD artid, + BOOL setpalette, + LPBYTE *data, + SIZE *size) { + *data = 0; + size->cx = 0; + size->cy = 0; + + // VERIFY THAT THE APPLICATION HAS REGISTERED AN ARTWORK CALLBACK + if (!artcallback) + return 0; + + // CALL THE ARTWORK CALLBACK TO DETERMINE THE IMAGE DIMENSIONS + int width; + int height; + int bitdepth; + if (!artcallback(providerid, + artid, + NULL, + NULL, + 0, + &width, + &height, + &bitdepth)) + return 0; + if (size) { + size->cx = width; + size->cy = height; + } + + // ALLOCATE MEMORY FOR THE IMAGE + DWORD bytes = width*height*bitdepth/8; + if (!(*data = (LPBYTE)ALLOC(bytes))) + return 0; + + // LOAD THE IMAGE + PALETTEENTRY pe[256]; + if (!artcallback(providerid, + artid, + &pe[0], + *data, + bytes, + &width, + &height, + &bitdepth)) { + FREE(*data); + *data = NULL; + return 0; + } + + // IF REQUESTED, UPDATE THE SYSTEM PALETTE + if (setpalette) + SDrawUpdatePalette(1,254,&pe[1]); + + return 1; +} + +//=========================================================================== +static DWORD PickRandomNumber () { + // RETURN A DWORD-SIZED RANDOM NUMBER. IT IS IMPORTANT THAT WE DON'T + // USE THE RUNTIME LIBRARY RANDOM GENERATOR, BECAUSE WE DON'T WANT TO + // INTERFERE WITH THE APPLICATION'S RANDOM SEQUENCE. + LARGE_INTEGER perfcount; + POINT pos; + QueryPerformanceCounter(&perfcount); + GetCursorPos(&pos); + + static DWORD seed = 0x100001; + seed ^= perfcount.LowPart ^ GetTickCount() ^ pos.x ^ pos.y; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand1 = seed & 0xFFFF; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand2 = seed & 0xFFFF; + return (rand1 << 16) | rand2; +} + +//=========================================================================== +static void ProcessIncomingAd (SOCKADDR_IPX *incomingaddr, + ADVPACKETPTR incomingad, + BOOL remove) { + + // FIX THE INCOMING ADDRESS SO IT POINTS TO THE MAIN PORT, + // NOT THE ADVERTISING PORT + incomingaddr->sa_socket = htons(MAINPORT); + + // ENTER THE CRITICAL SECTION + ipx_critsect.Enter(); + + // DELETE ALL GAMES IN OUR LIST FROM THIS ADDRESS + DWORD gameid = 0; + { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) + if (!memcmp(&curr->owner,incomingaddr,sizeof(SOCKADDR_IPX))) { + gameid = curr->gameid; + SNETSPI_GAMELISTPTR next = curr->next; + LISTFREE(&ipx_gamehead,curr); + curr = next; + } + else + curr = curr->next; + } + + // IF THIS GAME WAS NOT ALREADY IN THE LIST, ADD A NEW ID FOR IT. + // MAKE SURE WE NEVER ASSIGN AN ID OF ZERO. + if (!gameid) + gameid = ++ipx_nextgameid; + if (!gameid) + gameid = ++ipx_nextgameid; + + // IF THIS GAME MATCHES OUR PROGRAM ID AND VERSION ID, AND WE'RE NOT + // REMOVING, THEN ADD IT TO THE LIST + if ((incomingad->header.programid == ipx_programid) && + (incomingad->header.versionid == ipx_versionid) && + !remove) { + SNETSPI_GAMELIST game; + ZeroMemory(&game,sizeof(SNETSPI_GAMELIST)); + game.gameid = gameid; + CopyMemory(&game.owner,incomingaddr,sizeof(SOCKADDR_IPX)); + game.ownerlatency = 50; + game.ownerlasttime = GetTickCount(); + strncpy(game.gamename, + incomingad->strings, + SNETSPI_MAXSTRINGLENGTH); + strncpy(game.gamedescription, + incomingad->strings+strlen(incomingad->strings)+1, + SNETSPI_MAXSTRINGLENGTH); + LISTADD(&ipx_gamehead,&game); + } + + // LEAVE THE CRITICAL SECTION + ipx_critsect.Leave(); + +} + +//=========================================================================== +static void QueueSendTo (SOCKET s, + const char *buffer, + int length, + int flags, + const sockaddr *addr, + int addrlen) { + if (!(s && buffer && addr && (addrlen == sizeof(SOCKADDR_IPX)))) + return; + + // CREATE A NEW RECORD + SENDPTR newptr = NEW(SENDREC); + if (!newptr) + return; + newptr->data = (char *)ALLOC(length); + if (!newptr->data) { + FREE(newptr); + return; + } + newptr->s = s; + newptr->databytes = length; + CopyMemory(&newptr->addr,addr,sizeof(SOCKADDR_IPX)); + CopyMemory(newptr->data,buffer,length); + + // PERFORM RANDOM PACKET CORRUPTION + if ((PickRandomNumber() % 100) < ipx_testparms.corruptpercent) { + BOOL corrupted = 0; + DWORD corruptiontype = PickRandomNumber(); + + // TRUNCATE SOME PACKETS + if (newptr->databytes && !(corruptiontype & 0x0000000F)) { + newptr->databytes = PickRandomNumber() % newptr->databytes; + corrupted = 1; + } + + // OFFSET SOME PACKETS BY ONE BYTE + if (!(corruptiontype & 0x000000F0)) { + MoveMemory(newptr->data, + newptr->data+1, + newptr->databytes-1); + corrupted = 1; + } + if (!(corruptiontype & 0x00000F00)) { + MoveMemory(newptr->data+1, + newptr->data, + newptr->databytes-1); + corrupted = 1; + } + + // CORRUPT THE ADDRESS FOR SOME PACKETS + if (!(corruptiontype & 0x0000F000)) { + *(((LPBYTE)&newptr->addr)+(PickRandomNumber() & 0x0F)) += PickRandomNumber() & 0xFF; + corrupted = 1; + } + + // TOGGLE SINGLE BITS IN SOME PACKETS + if (newptr->databytes && + ((!corrupted) || !(corruptiontype & 0x000F0000))) { + DWORD bit = PickRandomNumber(); + DWORD bytenumber = (bit >> 3) % newptr->databytes; + BYTE bitvalue = (BYTE)(1 << (bit & 7)); + *((LPBYTE)newptr->data+bytenumber) ^= bitvalue; + } + + } + + // DETERMINE THE TIME AT WHICH THE PACKET SHOULD BE SENT + newptr->sendtime = GetTickCount() + +ipx_testparms.mindelay + +(PickRandomNumber() % (ipx_testparms.maxdelay-ipx_testparms.mindelay)); + + // ADD IT TO THE LINKED LIST + ipx_critsect.Enter(); + LISTADDPTREND(&ipx_sendhead,newptr); + ipx_critsect.Leave(); + +} + +//=========================================================================== +static DWORD CALLBACK RecvAdThreadProc (LPVOID param) { + + // SEND OUT A REQUEST FOR ADVERTISEMENTS + SendRequest(); + + // ALLOCATE MEMORY FOR INCOMING PACKETS + ADVPACKETPTR incomingad = NEW(ADVPACKET); + if (!incomingad) + return 0; + + while (ipx_advsocket && !ipx_shutdown) { + + // PROCESS ALL INCOMING ADVERTISEMENTS + SOCKADDR_IPX incomingaddr; + int addrsize = sizeof(SOCKADDR_IPX); + int bytesread = recvfrom(ipx_advsocket, + (char *)incomingad, + sizeof(ADVPACKET), + 0, + (sockaddr *)&incomingaddr, + &addrsize); + if ((bytesread >= sizeof(ADVHEADER)) && + (incomingad->header.length == bytesread) && + !ComputeChecksum(incomingad,incomingad->header.length)) + switch (incomingad->header.type) { + + case ADTYPE_GAMEINFO: + case ADTYPE_REMOVE: + ProcessIncomingAd(&incomingaddr, + incomingad, + (incomingad->header.type == ADTYPE_REMOVE)); + break; + + case ADTYPE_REQUEST: + SendAdvertisement(); + break; + + } + + } + + // FREE THE INCOMING GAME BUFFER + FREE(incomingad); + + // FREE THE LIST OF GAMES + LISTCLEAR(&ipx_gamehead); + + return 0; +} + +//=========================================================================== +static DWORD CALLBACK RecvDataThreadProc (LPVOID param) { + while (ipx_mainsocket && !ipx_shutdown) { + + // ALLOCATE MEMORY FOR THE NEXT INCOMING PACKET + PACKETPTR pkt = NEW(PACKET); + + // RECEIVE A PACKET, BLOCKING IF ONE IS NOT AVAILABLE YET. WHEN THE + // NETWORK DRIVER HAS INCOMING DATA ON A PORT, IT WILL COPY IT DIRECTLY + // TO THE APPLICATION'S ADDRESS SPACE IF THE APPLICATION IS BLOCKING ON + // A READ. FOR THIS REASON, WE TRY TO ALWAYS HAVE AT LEAST ONE READ + // PENDING. + int addrsize = sizeof(SOCKADDR_IPX); + int bytesread = recvfrom(ipx_mainsocket, + (char *)&pkt->data, + MAXMESSAGESIZE, + 0, + (sockaddr *)&pkt->addr, + &addrsize); + pkt->databytes = bytesread; + ZeroMemory(((LPBYTE)&pkt->addr)+addrsize,sizeof(SNETADDR)-addrsize); + + // SINCE WE DON'T TIME OUT ON READS, THE ONLY WAY A READ CAN FAIL IS + // IF THE SOCKET WAS CLOSED. IN THIS CASE, SHUT DOWN THE THREAD. + if ((bytesread < 0) || ipx_shutdown) { + FREE(pkt); + return 0; + } + + // ON A SUCCESSFUL READ, QUEUE THE PACKET + ipx_critsect.Enter(); + LISTADDPTREND(&ipx_packethead,pkt); + ipx_critsect.Leave(); + SetEvent(ipx_recvevent); + + } + return 0; +} + +//=========================================================================== +static DWORD CALLBACK SendThreadProc (LPVOID param) { + while (!ipx_shutdown) { + if (ipx_sendhead) { + ipx_critsect.Enter(); + + // TRAVERSE THE SEND QUEUE, LOOKING FOR PACKETS THAT ARE READY TO + // BE SENT + DWORD currtime = GetTickCount(); + SENDPTR *next = &ipx_sendhead; + while (*next) + if ((DWORD)(currtime-(*next)->sendtime) <= 0x7FFFFFFF) { + SENDPTR curr = *next; + + // SEND THE PACKET + sendto(curr->s, + curr->data, + curr->databytes, + 0, + (const sockaddr *)&curr->addr, + sizeof(SOCKADDR_IPX)); + + // UNLINK IT FROM THE QUEUE + *next = curr->next; + + // FREE THE RECORD AND PACKET DATA + FREE(curr->data); + FREE(curr); + + // SLEEP FOR ONE QUANTUM BEFORE PROCESSING THE NEXT PACKET + Sleep(1); + + } + else + next = &(*next)->next; + + ipx_critsect.Leave(); + } + Sleep(50); + } + return 0; +} + +//=========================================================================== +static BOOL CALLBACK SelectGameDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + static LPBYTE background = NULL; + static LPBYTE buttontexture = NULL; + static UIPARAMSPTR uiparams = NULL; + switch (message) { + + case WM_COMMAND: + + // IF THE USER CLICKED 'JOIN GAME', TRY TO JOIN THE SELECTED GAME + if (LOWORD(wparam) == IDOK) { + LPARAM cursel = SendDlgItemMessage(window,IDC_GAMELIST,LB_GETCURSEL,0,0); + if (cursel != LB_ERR) { + char fullname[2*SNETSPI_MAXSTRINGLENGTH] = ""; + SendDlgItemMessage(window,IDC_GAMELIST,LB_GETTEXT,cursel,(LPARAM)fullname); + if (fullname[0]) { + if (strchr(fullname,'\t')) + *strchr(fullname,'\t') = 0; + if (SNetJoinGame(0, + fullname, + NULL, + uiparams->playerdata->playername, + uiparams->playerdata->playerdescription, + uiparams->playeridptr)) { + KillTimer(window,1); + SDlgEndDialog(window,1); + } + else + uiparams->interfacedata->messageboxcallback(window, + "Unable to connect.", + uiparams->programdata->programname, + 0); + } + } + } + + // IF THE USER CLICKED 'CREATE GAME', CALL THE CREATE GAME CALLBACK + else if ((LOWORD(wparam) == IDC_CREATEGAME) && + uiparams->interfacedata->createcallback) { + + // BUILD A NEW INTERFACE DATA STRUCTURE CONTAINING OUR WINDOW HANDLE + SNETUIDATA interfacedata; + CopyMemory(&interfacedata,uiparams->interfacedata,sizeof(SNETUIDATA)); + interfacedata.size = sizeof(SNETUIDATA); + interfacedata.parentwindow = window; + + // BUILD A CREATION DATA STRUCTURE + SNETCREATEDATA createdata; + ZeroMemory(&createdata,sizeof(SNETCREATEDATA)); + createdata.size = sizeof(SNETCREATEDATA); + createdata.providerid = PROVIDERID; + createdata.maxplayers = ipx_maxplayers; + createdata.createflags = 0; + + // CALL THE CREATE GAME CALLBACK + if (uiparams->interfacedata->createcallback(&createdata, + uiparams->programdata, + uiparams->playerdata, + &interfacedata, + uiparams->versiondata, + uiparams->playeridptr)) { + KillTimer(window,1); + SDlgEndDialog(window,1); + } + + } + + // IF THE USER CLICKED 'DISCONNECT', END THE DIALOG + else if (LOWORD(wparam) == IDCANCEL) { + KillTimer(window,1); + SDlgEndDialog(window,0); + } + + // IF THE USER SELECTED A NEW LIST BOX ITEM, UPDATE THE GAME + // DESCRIPTION + else if ((LOWORD(wparam) == IDC_GAMELIST) && + (HIWORD(wparam) == LBN_SELCHANGE)) + InvalidateRect(GetDlgItem(window,IDC_GAMEDESCRIPTION),NULL,1); + + // IF THE USER DOUBLE-CLICKED A LIST BOX ITEM, POST AN 'OK' COMMAND + else if ((LOWORD(wparam) == IDC_GAMELIST) && + (HIWORD(wparam) == LBN_DBLCLK)) + PostMessage(window,WM_COMMAND,MAKELONG(IDOK,BN_CLICKED),(LPARAM)GetDlgItem(window,IDOK)); + + break; + + case WM_DESTROY: + if (background) { + FREE(background); + background = NULL; + } + if (buttontexture) { + FREE(buttontexture); + buttontexture = NULL; + } + uiparams = NULL; + break; + + case WM_DRAWITEM: + if (wparam == IDC_GAMEDESCRIPTION) { + + // GET THE GAME NAME AND DESCRIPTION + char name[256] = ""; + { + LRESULT sel = SendDlgItemMessage(window,IDC_GAMELIST,LB_GETCURSEL,0,0); + if (sel != LB_ERR) + SendDlgItemMessage(window,IDC_GAMELIST,LB_GETTEXT,sel,(LPARAM)name); + } + LPSTR description = ""; + if (strchr(name,'\t')) { + description = strchr(name,'\t'); + *description++ = 0; + } + + // UPDATE THE DESCRIPTION IN THE STATIC TEXT CONTROL + { + char buffer[256] = ""; + GetDlgItemText(window,IDC_GAMEDESCRIPTION,buffer,256); + buffer[255] = 0; + if (strcmp(buffer,description)) + SetDlgItemText(window,IDC_GAMEDESCRIPTION,description); + } + + // IF THE APPLICATION HAS REGISTERED A DRAW DESCRIPTION CALLBACK, + // LET IT DRAW THE DESCRIPTION + if (uiparams->interfacedata->drawdesccallback) + return uiparams->interfacedata->drawdesccallback(PROVIDERID, + SNET_DRAWTYPE_GAME, + name, + description, + 0, + 0, + SNET_DDF_MULTILINE, + (LPDRAWITEMSTRUCT)lparam); + + // OTHERWISE, LET THE DEFAULT DIALOG BOX PROCEDURE DRAW THE + // DESCRIPTION FROM THE STATIC TEXT + else + return 0; + + } + break; + + case WM_INITDIALOG: + + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + + // LOAD THE ARTWORK FOR THIS DIALOG + { + SIZE size; + if (LoadArtwork(uiparams->interfacedata->artcallback, + PROVIDERID, + SNET_ART_BACKGROUND, + 1, + &background, + &size)) { + SDlgSetBitmap(window, + NULL, + "", + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + background, + NULL, + size.cx, + size.cy); + int controllist[2] = {IDC_GAMEDESCRIPTION,0}; + SDlgSetControlBitmaps(window, + &controllist[0], + NULL, + background, + &size, + SDLG_ADJUST_CONTROLPOS); + } + if (LoadArtwork(uiparams->interfacedata->artcallback, + PROVIDERID, + SNET_ART_BUTTONTEXTURE, + 0, + &buttontexture, + &size)) { + int controllist[4] = {IDC_CREATEGAME,IDOK,IDCANCEL,0}; + SDlgSetControlBitmaps(window, + &controllist[0], + NULL, + buttontexture, + &size, + SDLG_ADJUST_VERTICAL); + } + } + + // DRAW THE PROGRAM DESCRIPTION + SetDlgItemTextA(window,IDC_PROGRAMDESCRIPTION,uiparams->programdata->programdescription); + + // SET THE FIRST TAB STOP FOR THE GAME LIST TO WIDER THAN THE LIST BOX, + // TO HIDE ALL TABBED TEXT + { + RECT rect; + GetClientRect(GetDlgItem(window,IDC_GAMELIST),&rect); + SendDlgItemMessage(window,IDC_GAMELIST,LB_SETTABSTOPS,1,(LPARAM)&rect.right); + } + + PostMessage(window,WM_USER,0,0); + SetTimer(window,1,500,NULL); + return 1; + + case WM_TIMER: + case WM_USER: + SendRequest(); + TrimGameList(3000); + UpdateGameList(window,GetDlgItem(window,IDC_GAMELIST)); + break; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +static void SendAdvertisement () { + ipx_critsect.Enter(); + if (ipx_advgameinfo) + QueueSendTo(ipx_advsocket, + (const char *)ipx_advgameinfo, + ipx_advgameinfo->header.length, + 0, + (const sockaddr *)&ipx_broadcastaddr, + sizeof(SOCKADDR_IPX)); + ipx_critsect.Leave(); +} + +//=========================================================================== +static void SendRequest () { + ADVHEADER request; + ZeroMemory(&request,sizeof(ADVHEADER)); + request.checksum = 0; + request.length = sizeof(ADVHEADER); + request.type = ADTYPE_REQUEST; + request.reserved = 0; + request.programid = ipx_programid; + request.versionid = ipx_versionid; + request.checksum = GenerateChecksum(&request,sizeof(ADVHEADER)); + QueueSendTo(ipx_advsocket, + (const char *)&request, + request.length, + 0, + (const sockaddr *)&ipx_broadcastaddr, + sizeof(SOCKADDR_IPX)); +} + +//=========================================================================== +static void TrimGameList (DWORD timeout) { + ipx_critsect.Enter(); + { + DWORD currtime = GetTickCount(); + SNETSPI_GAMELISTPTR *next = &ipx_gamehead; + while (*next) + if (currtime-(*next)->ownerlasttime > timeout) { + SNETSPI_GAMELISTPTR freeptr = *next; + *next = (*next)->next; + FREE(freeptr); + } + else + next = &(*next)->next; + } + ipx_critsect.Leave(); +} + +//=========================================================================== +static void UpdateGameList (HWND dialog, HWND listbox) { + ipx_critsect.Enter(); + + // MAKE SURE ALL GAMES IN THE LINKED LIST ARE REPRESENTED IN THE LIST BOX + { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) { + if (!(curr->gamemode & SNET_GM_PRIVATE)) { + char fullstring[2*SNETSPI_MAXSTRINGLENGTH]; + sprintf(fullstring,"%s\t%s",curr->gamename,curr->gamedescription); + if (SendMessage(listbox,LB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)fullstring) == LB_ERR) { + SendMessage(listbox,LB_ADDSTRING,0,(LPARAM)fullstring); + EnableWindow(GetDlgItem(dialog,IDOK),1); + if (SendMessage(listbox,LB_GETCURSEL,0,0) == LB_ERR) { + SendMessage(listbox,LB_SETCURSEL,0,0); + SendMessage(dialog,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)listbox); + } + } + } + curr = curr->next; + } + } + + // MAKE SURE THERE ARE NO GAME IN THE LIST BOX THAT AREN'T IN THE LINKED LIST + { + char liststring[2*SNETSPI_MAXSTRINGLENGTH]; + WPARAM index = 0; + while (SendMessage(listbox,LB_GETTEXT,index,(LPARAM)liststring) != LB_ERR) { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) { + if (!(curr->gamemode & SNET_GM_PRIVATE)) { + char fullstring[2*SNETSPI_MAXSTRINGLENGTH]; + sprintf(fullstring,"%s\t%s",curr->gamename,curr->gamedescription); + if (!strcmp(fullstring,liststring)) + break; + } + curr = curr->next; + } + if (!curr) { + if (SendMessage(listbox,LB_GETCURSEL,0,0) == index) { + SendMessage(listbox,LB_SETCURSEL,index-1,0); + SendMessage(dialog,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)listbox); + } + if (!SendMessage(listbox,LB_DELETESTRING,index,0)) + EnableWindow(GetDlgItem(dialog,IDOK),0); + } + else + ++index; + } + } + + ipx_critsect.Leave(); +} + +/**************************************************************************** +* +* SERVICE PROVIDER INTERFACE FUNCTIONS +* +***/ + +//=========================================================================== +BOOL CALLBACK IpxCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude) { + if (diffmagnitude) + *diffmagnitude = 0; + if (!(addr1 && addr2 && diffmagnitude)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // COMPARE THE ADDRESSES, AND RETURN: + // 2 IF THEY ARE ON DIFFERENT NETWORKS + // 1 IF THEY ARE DIFFERENT ADDRESSES ON THE SAME NETWORK + // 0 IF THEY ARE THE SAME ADDRESS + SOCKADDR_IPX *ipxaddr1 = (SOCKADDR_IPX *)addr1; + SOCKADDR_IPX *ipxaddr2 = (SOCKADDR_IPX *)addr2; + if ((*(DWORD *)&ipxaddr1->sa_netnum) != + (*(DWORD *)&ipxaddr2->sa_netnum)) + *diffmagnitude = 2; + else if (memcmp(ipxaddr1,ipxaddr2,sizeof(SOCKADDR_IPX))) + *diffmagnitude = 1; + else + *diffmagnitude = 0; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxDestroy () { + + // START THE SHUTDOWN PROCESS + ipx_shutdown = 1; + + // SEND DATA TO THE RECEIVE THREADS TO WAKE THEM UP + { + SOCKADDR_IPX sendaddr; + CopyMemory(&sendaddr,&ipx_broadcastaddr,sizeof(SOCKADDR_IPX)); + BYTE buffer[8] = {0x08,0xEF,0x08,0x00,0x00,0x00,0x00,0x00}; + sendaddr.sa_socket = htons(ADVPORT); + sendto(ipx_advsocket,(const char *)&buffer[0],8,0,(const sockaddr *)&sendaddr,sizeof(SOCKADDR_IPX)); + sendaddr.sa_socket = htons(MAINPORT); + for (int loop = 0; loop < RECVDATATHREADS; ++loop) + sendto(ipx_mainsocket,(const char *)&buffer[0],8,0,(sockaddr *)&sendaddr,sizeof(SOCKADDR_IPX)); + } + + // WAIT FOR ALL THREADS TO TERMINATE + while (ipx_threadhead) { + WaitForSingleObject(ipx_threadhead->handle,100); + CloseHandle(ipx_threadhead->handle); + LISTFREE(&ipx_threadhead,ipx_threadhead); + } + + // CLOSE THE SOCKETS + if (ipx_mainsocket) { + closesocket(ipx_mainsocket); + ipx_mainsocket = (SOCKET)0; + } + if (ipx_advsocket) { + closesocket(ipx_advsocket); + ipx_advsocket = (SOCKET)0; + } + + // TAKE CONTROL OF THE CRITICAL SECTION + ipx_critsect.Enter(); + + // FREE THE GAME INFO + IpxStopAdvertisingGame(); + + // CLEAR OUT THE SEND QUEUE + while (ipx_sendhead) { + FREE(ipx_sendhead->data); + LISTFREE(&ipx_sendhead,ipx_sendhead); + } + + // FREE ALL UNPROCESSED PACKETS + LISTCLEAR(&ipx_packethead); + + // CLEAN UP WINDOWS SOCKETS + WSACleanup(); + + // LEAVE THE CRITICAL SECTION + ipx_critsect.Leave(); + + // FINISH THE SHUTDOWN PROCESS + ipx_shutdown = 0; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxFree (SNETADDRPTR addr, + LPVOID data, + DWORD databytes) { + if (!(addr && data)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + FREE(addr); + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxFreeExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR mesage) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxGetGameInfo (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + SNETSPI_GAMELIST *gameinfo) { + if (gameinfo) + ZeroMemory(gameinfo,sizeof(SNETSPI_GAMELIST)); + if (!(gamename && gameinfo && (gameid || *gamename))) + return 0; + + // SEARCH FOR A GAME IN THE GAME LIST MATCHING THE QUERY PARAMETERS + ipx_critsect.Enter(); + { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) + if (((!gameid) || (gameid == curr->gameid)) && + ((!*gamename) || !_stricmp(gamename,curr->gamename))) { + CopyMemory(gameinfo,curr,sizeof(SNETSPI_GAMELIST)); + break; + } + else + curr = curr->next; + } + ipx_critsect.Leave(); + + if (gameinfo->gameid) + return 1; + else { + SetLastError(SNET_ERROR_GAME_NOT_FOUND); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK IpxGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE event) { + + // SAVE THE PROGRAM AND VERSION IDS AND THE RECEIVE EVENT HANDLE + ipx_programid = programdata->programid; + ipx_versionid = programdata->versionid; + ipx_maxplayers = min(programdata->maxplayers,MAXPLAYERS); + ipx_recvevent = event; + + // INITIALIZE WINDOWS SOCKETS + { + WSADATA data; + if (WSAStartup(MAKEWORD(1,1),&data)) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + } + + // CREATE TWO SOCKETS: ONE FOR APPLICATION DATA AND ONE FOR ADVERTISING + ipx_advsocket = socket(PF_NS,SOCK_DGRAM,NSPROTO_IPX); + ipx_mainsocket = socket(PF_NS,SOCK_DGRAM,NSPROTO_IPX); + if (!(ipx_advsocket && ipx_mainsocket)) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + + // DETERMINE THE BROADCAST ADDRESS + { + ZeroMemory(&ipx_broadcastaddr,sizeof(SOCKADDR_IPX)); + for (int loop = 0; loop < 6; ++loop) + ipx_broadcastaddr.sa_nodenum[loop] = 0xFF; + ipx_broadcastaddr.sa_family = AF_IPX; + ipx_broadcastaddr.sa_socket = htons(ADVPORT); + } + + // BIND TO THE MAIN SOCKET, DETERMINING OUR LOCAL ADDRESS + ZeroMemory(&ipx_localaddr,sizeof(SOCKADDR_IPX)); + ipx_localaddr.sa_family = AF_IPX; + ipx_localaddr.sa_socket = htons(MAINPORT); + if (bind(ipx_mainsocket, + (const struct sockaddr *)&ipx_localaddr, + sizeof(SOCKADDR_IPX))) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + + // BIND TO THE ADVERTISING SOCKET + { + SOCKADDR_IPX advaddr; + CopyMemory(&advaddr,&ipx_localaddr,sizeof(SOCKADDR_IPX)); + advaddr.sa_socket = htons(ADVPORT); + if (bind(ipx_advsocket, + (const struct sockaddr *)&advaddr, + sizeof(SOCKADDR_IPX))) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + } + + // ALLOW BROADCASTS TO BE SENT ON THE SOCKETS (DUE TO A BUG IN WINDOWS 95, + // THIS OPTION IS ALSO REQUIRED FOR RECEIVING BROADCASTS) + { + BOOL value = 1; + setsockopt(ipx_advsocket, + SOL_SOCKET, + SO_BROADCAST, + (const char *)&value, + sizeof(BOOL)); + setsockopt(ipx_mainsocket, + SOL_SOCKET, + SO_BROADCAST, + (const char *)&value, + sizeof(BOOL)); + } + + // CREATE A THREAD TO RECEIVE PACKETS ON THE ADVERTISING SOCKET + { + THREAD thread; + thread.handle = CreateThread((LPSECURITY_ATTRIBUTES)NULL, + 0, + RecvAdThreadProc, + NULL, + 0, + &thread.id); + if (thread.handle) { + SetThreadPriority(thread.handle,THREAD_PRIORITY_ABOVE_NORMAL); + LISTADD(&ipx_threadhead,&thread); + } + } + + // CREATE THREADS TO READ PACKETS FROM THE MAIN SOCKET + { + for (int loop = 0; loop < RECVDATATHREADS; ++loop) { + THREAD thread; + thread.handle = CreateThread((LPSECURITY_ATTRIBUTES)NULL, + 0, + RecvDataThreadProc, + NULL, + 0, + &thread.id); + if (thread.handle) { + SetThreadPriority(thread.handle,THREAD_PRIORITY_ABOVE_NORMAL); + LISTADD(&ipx_threadhead,&thread); + } + } + } + + // CREATE A THREAD TO DEQUEUE PACKETS FROM THE SEND QUEUE AND SEND THEM + // OUT ON THE WIRE + { + THREAD thread; + thread.handle = CreateThread((LPSECURITY_ATTRIBUTES)NULL, + 0, + SendThreadProc, + NULL, + 0, + &thread.id); + if (thread.handle) { + SetThreadPriority(thread.handle,THREAD_PRIORITY_ABOVE_NORMAL); + LISTADD(&ipx_threadhead,&thread); + } + } + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + + // WE NEVER RETURN ANY DEVICES, SO THIS FUNCTION SHOULD NEVER BE CALLED + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxLockDeviceList (SNETSPI_DEVICELISTPTR *devicelist) { + *devicelist = NULL; + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxLockGameList (LPCSTR selectioncriteria, + SNETSPI_GAMELISTPTR *gamelist) { + if (!gamelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // TRIM ANY GAMES THAT WE HAVEN'T HEARD FROM IN A WHILE + { + static DWORD lasttime = GetTickCount(); + DWORD currtime = GetTickCount(); + TrimGameList(max(3000,2*(currtime-lasttime))); + } + + // LOCK THE GAME LIST + ipx_critsect.Enter(); + *gamelist = ipx_gamehead; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxReceive (SNETADDRPTR *addr, + LPVOID *data, + DWORD *databytes) { + if (addr) + *addr = NULL; + if (data) + *data = NULL; + if (databytes) + *databytes = NULL; + if (!(addr && data && databytes && ipx_mainsocket)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // IF THERE IS A PACKET QUEUED, REMOVE IT FROM THE QUEUE AND RETURN + // POINTERS TO THE CALLER. NOTE THAT WE UNLINK THE PACKET BUT DON'T + // FREE IT FROM MEMORY; IT IS THE CALLER'S RESPONSIBILITY TO CALL + // OUR FREE FUNCTION WHEN IT IS DONE WITH THE PACKET. + if (ipx_packethead) { + ipx_critsect.Enter(); + *addr = &ipx_packethead->addr; + *data = ipx_packethead->data; + *databytes = ipx_packethead->databytes; + ipx_packethead = ipx_packethead->next; + ipx_critsect.Leave(); + return 1; + } + else { + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK IpxReceiveExternalMessage (LPCSTR *senderpath, + LPCSTR *sendername, + LPCSTR *message) { + if (senderpath) + *senderpath = NULL; + if (sendername) + *sendername = NULL; + if (message) + *message = NULL; + + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + + // BUILD A USER INTERFACE DATA BLOCK + UIPARAMS uiparams; + ZeroMemory(&uiparams,sizeof(UIPARAMS)); + uiparams.flags = flags; + uiparams.programdata = programdata; + uiparams.playerdata = playerdata; + uiparams.interfacedata = interfacedata; + uiparams.versiondata = versiondata; + uiparams.playeridptr = playerid; + + // DISPLAY THE DIALOG BOX + DWORD result = (DWORD)SDlgDialogBoxParam(ipx_instance, + "IPXSELECTGAME_DIALOG", + interfacedata ? interfacedata->parentwindow + : SDrawGetFrameWindow(), + SelectGameDialogProc, + (LPARAM)&uiparams); + + return (result != 0); +} + +//=========================================================================== +BOOL CALLBACK IpxSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes) { + if (!(addresses && addrlist && data && databytes && ipx_mainsocket)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // SEND THE PACKET + while (addresses--) + QueueSendTo(ipx_mainsocket, + (const char *)data, + databytes, + 0, + (const sockaddr *)*(addrlist+addresses), + sizeof(SOCKADDR_IPX)); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxSendExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR targetpath, + LPCSTR targetname, + LPCSTR message) { + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD creationtime) { + if (!(gamename && gamedescription)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // CREATE A STRUCTURE TO CONTAIN THE DATA WE NEED TO ADVERTISE + ipx_critsect.Enter(); + if (!ipx_advgameinfo) { + ipx_advgameinfo = NEW(ADVPACKET); + if (!ipx_advgameinfo) { + ipx_critsect.Leave(); + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + ZeroMemory(ipx_advgameinfo,sizeof(ADVPACKET)); + ipx_advgameinfo->header.checksum = 0; + ipx_advgameinfo->header.length = sizeof(ADVHEADER) + +strlen(gamename) + +strlen(gamedescription) + +2; + ipx_advgameinfo->header.type = ADTYPE_GAMEINFO; + ipx_advgameinfo->header.reserved = 0; + ipx_advgameinfo->header.programid = ipx_programid; + ipx_advgameinfo->header.versionid = ipx_versionid; + strncpy(ipx_advgameinfo->strings, + gamename, + SNETSPI_MAXSTRINGLENGTH); + strncpy(ipx_advgameinfo->strings + +min(SNETSPI_MAXSTRINGLENGTH,strlen(ipx_advgameinfo->strings)+1), + gamedescription, + SNETSPI_MAXSTRINGLENGTH); + ipx_advgameinfo->header.checksum = GenerateChecksum(ipx_advgameinfo, + ipx_advgameinfo->header.length); + ipx_critsect.Leave(); + + // SEND THE FIRST ADVERTISEMENT + SendAdvertisement(); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxStopAdvertisingGame () { + + // DELETE THE ADVERTISEMENT DATA AND SEND OUT A REMOVE GAME MESSAGE + ipx_critsect.Enter(); + if (ipx_advgameinfo) { + ipx_advgameinfo->header.checksum = 0; + ipx_advgameinfo->header.type = ADTYPE_REMOVE; + ipx_advgameinfo->header.checksum = GenerateChecksum(ipx_advgameinfo, + ipx_advgameinfo->header.length); + QueueSendTo(ipx_advsocket, + (const char *)ipx_advgameinfo, + ipx_advgameinfo->header.length, + 0, + (const sockaddr *)&ipx_broadcastaddr, + sizeof(SOCKADDR_IPX)); + FREE(ipx_advgameinfo); + ipx_advgameinfo = NULL; + } + ipx_critsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxUnlockDeviceList (SNETSPI_DEVICELISTPTR devicelist) { + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxUnlockGameList (SNETSPI_GAMELISTPTR gamelist, + DWORD *hintnextcall) { + if (gamelist != ipx_gamehead) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // UNLOCK THE GAME LIST + ipx_critsect.Leave(); + if (hintnextcall) + *hintnextcall = 1000; + + // SEND OUT A REQUEST FOR ADVERTISEMENTS, SO WE WILL HAVE UPDATED DATA + // THE NEXT TIME IT IS REQUESTED + { + static DWORD lasttime = 0; + DWORD currtime = GetTickCount(); + if (currtime-lasttime > 400) { + lasttime = currtime; + SendRequest(); + } + } + + return 1; +} + +/**************************************************************************** +* +* EXPORTED STRUCTURES +* +***/ + +DWORD ipx_id = PROVIDERID; +LPCSTR ipx_desc = "IPX Latency/Corrupt Test"; +LPCSTR ipx_req = "All computers must be connected to an IPX-compatible network."; +SNETCAPS ipx_caps = {sizeof(SNETCAPS), // size + SNET_CAPS_PAGELOCKEDBUFFERS // flags + | SNET_CAPS_BASICINTERFACE, + MAXMESSAGESIZE, // max message size + 16, // max queue size, + MAXPLAYERS, // max players, + 1500, // bytes per second + 500, // latency (ms) + 4, // default turns per second + 2}; // default turns in transit +SNETSPI ipx_spi = {sizeof(SNETSPI), + IpxCompareNetAddresses, + IpxDestroy, + IpxFree, + IpxFreeExternalMessage, + IpxGetGameInfo, + IpxGetPerformanceData, + IpxInitialize, + IpxInitializeDevice, + IpxLockDeviceList, + IpxLockGameList, + IpxReceive, + IpxReceiveExternalMessage, + IpxSelectGame, + IpxSend, + IpxSendExternalMessage, + IpxStartAdvertisingGame, + IpxStopAdvertisingGame, + IpxUnlockDeviceList, + IpxUnlockGameList}; + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +extern "C" BOOL APIENTRY Query (DWORD index, + DWORD *id, + LPCSTR *description, + LPCSTR *requirements, + SNETCAPSPTR *caps) { + if (!(id && description && requirements && caps)) + return 0; + switch (index) { + + case 0: + *id = ipx_id; + *description = ipx_desc; + *requirements = ipx_req; + *caps = &ipx_caps; + return 1; + + default: + return 0; + + } +} + +//=========================================================================== +extern "C" BOOL APIENTRY Bind (DWORD index, + SNETSPIPTR *spi) { + if (!spi) + return 0; + + switch (index) { + + case 0: + *spi = &ipx_spi; + return 1; + + default: + return 0; + + } +} + +//=========================================================================== +extern "C" BOOL APIENTRY DllMain (HINSTANCE passinstance, DWORD reason, LPVOID) { + if (reason == DLL_PROCESS_ATTACH) + ipx_instance = passinstance; + return 1; +} diff --git a/Storm/SOURCE/IPXTEST/IPXTEST.CS b/Storm/SOURCE/IPXTEST/IPXTEST.CS new file mode 100644 index 0000000..85552a3 --- /dev/null +++ b/Storm/SOURCE/IPXTEST/IPXTEST.CS @@ -0,0 +1,8 @@ +#include +set extralib=storm.lib wsock32.lib +set linkopt=%linkopt% -base:0x17000000 +!if exist %project%.snp del %project%.snp +!rename %project%.dll %project%.snp +!copy %project%.snp ..\..\bin > NUL: +!if %debug% copy %project%.snp ..\..\bin\debug > NUL: +!if exist *.bak del *.bak diff --git a/Storm/SOURCE/IPXTEST/IPXTEST.DEF b/Storm/SOURCE/IPXTEST/IPXTEST.DEF new file mode 100644 index 0000000..9b40e88 --- /dev/null +++ b/Storm/SOURCE/IPXTEST/IPXTEST.DEF @@ -0,0 +1,4 @@ +LIBRARY ipxtest +EXPORTS +Bind +Query diff --git a/Storm/SOURCE/IPXTEST/IPXTEST.RC b/Storm/SOURCE/IPXTEST/IPXTEST.RC new file mode 100644 index 0000000..d88e307 --- /dev/null +++ b/Storm/SOURCE/IPXTEST/IPXTEST.RC @@ -0,0 +1,105 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IPXSELECTGAME_DIALOG DIALOGEX 0, 0, 256, 203 +STYLE DS_3DLOOK | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700 +BEGIN + LTEXT "IPX Games Available",IDC_STATIC,10,62,124,10,0, + WS_EX_TRANSPARENT + LISTBOX IDC_GAMELIST,10,74,124,80,LBS_SORT | LBS_USETABSTOPS | + WS_VSCROLL | WS_TABSTOP + LTEXT "Description:",IDC_STATIC,10,152,124,10,0, + WS_EX_TRANSPARENT + LTEXT "",IDC_GAMEDESCRIPTION,10,162,124,30 + LTEXT "",IDC_PROGRAMDESCRIPTION,10,192,124,9,0, + WS_EX_TRANSPARENT + DEFPUSHBUTTON "&Join Game",IDOK,160,147,90,12,WS_DISABLED + PUSHBUTTON "&Create Game",IDC_CREATEGAME,160,161,90,12 + PUSHBUTTON "&Disconnect",IDCANCEL,160,175,90,12 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "SELECTGAME_DIALOG", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 250 + TOPMARGIN, 7 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SOURCE/IPXTEST/RESOURCE.H b/Storm/SOURCE/IPXTEST/RESOURCE.H new file mode 100644 index 0000000..efa17cc --- /dev/null +++ b/Storm/SOURCE/IPXTEST/RESOURCE.H @@ -0,0 +1,20 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by ipxtest.rc +// +#define IDC_CREATEGAME 3 +#define IDC_GAMELIST 1001 +#define IDC_STATIC -1 +#define IDC_GAMEDESCRIPTION 103 +#define IDC_PROGRAMDESCRIPTION 104 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SOURCE/MAIN.CPP b/Storm/SOURCE/MAIN.CPP new file mode 100644 index 0000000..267a02c --- /dev/null +++ b/Storm/SOURCE/MAIN.CPP @@ -0,0 +1,7 @@ + +#include + +int main(int argc, char *argv[]) +{ + return EXIT_SUCCESS; +} diff --git a/Storm/SOURCE/MSG00001.BIN b/Storm/SOURCE/MSG00001.BIN new file mode 100644 index 0000000..a00ce8c Binary files /dev/null and b/Storm/SOURCE/MSG00001.BIN differ diff --git a/Storm/SOURCE/PCH.H b/Storm/SOURCE/PCH.H new file mode 100644 index 0000000..839808e --- /dev/null +++ b/Storm/SOURCE/PCH.H @@ -0,0 +1,21 @@ +#define OEMRESOURCE +#define STRICT +#define _WIN32_WINNT 0x0400 +#define STORMSTATIC // see prototypes for initialize and destroy functions +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "storm.h" +#include "sintern.h" +#include "resource.h" diff --git a/Storm/SOURCE/RESOURCE.H b/Storm/SOURCE/RESOURCE.H new file mode 100644 index 0000000..cd634a7 --- /dev/null +++ b/Storm/SOURCE/RESOURCE.H @@ -0,0 +1,38 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by STORM.RC +// +#define IDS_BASE 0x5100 +#define IDS_ERROR 0x5100 +#define IDS_HEADER 0x5101 +#define IDS_PROGRAM 0x5102 +#define IDS_FILELINE 0x5103 +#define IDS_FUNCTION 0x5104 +#define IDS_OBJECT 0x5105 +#define IDS_HANDLE 0x5106 +#define IDS_EXPRESSION 0x5107 +#define IDS_DESCRIPTION 0x5108 +#define IDS_TERMINATE 0x5109 +#define IDS_RECOVERABLE 0x510A +#define IDS_FILE 0x510B +#define IDS_BADARGUMENT 0x5201 +#define IDS_NOTENOUGHARGUMENTS 0x5202 +#define IDS_OPENFAILED 0x5203 + +#define IDC_CREATEGAME 0x5180 +#define IDC_PROVIDERLIST 0x5181 +#define IDC_MAXPLAYERS 0x5182 +#define IDC_REQUIREMENTS 0x5183 +#define IDC_PROGRAMDESCRIPTION 0x5184 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SOURCE/SBLT.CPP b/Storm/SOURCE/SBLT.CPP new file mode 100644 index 0000000..9968ac3 --- /dev/null +++ b/Storm/SOURCE/SBLT.CPP @@ -0,0 +1,431 @@ +/**************************************************************************** +* +* SBLT.CPP +* Storm bitblt engine +* +* By Michael O'Brien (3/13/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define OPT_SRCCOPY 0 +#define OPT_PATCOPY 1 +#define OPTSTREAMS 2 + +#define UNROLL 180 + +typedef struct _OPTSTREAMDATA { + HSCODESTREAM stream; + LPBYTE *jumptable; + LPDWORD patchlocation; +} OPTSTREAMDATA, *OPTSTREAMDATAPTR; + +typedef struct _BLTINFO { + BOOL used; + HSCODESTREAM stream; + DWORD time; + DWORD reserved; +} BLTINFO, *BLTINFOPTR; + +static OPTSTREAMDATA s_optstream[OPTSTREAMS] = {{0},{0}}; +static BLTINFOPTR s_scode = NULL; + +//=========================================================================== +static BOOL InitOptStream (LPCSTR sourcestring, + OPTSTREAMDATAPTR optdata) { + if (!SCodeCompile(NULL,sourcestring,NULL,UNROLL,0,&optdata->stream)) + return FALSE; + if (!SCodeGetJumpTable(optdata->stream, + &optdata->jumptable, + NULL, + &optdata->patchlocation, + NULL)) + return FALSE; + return TRUE; +} + +//=========================================================================== +static void inline OptimizeROP3 (DWORD *rop, DWORD *pattern) { + switch (*rop) { + + case BLACKNESS: + *rop = PATCOPY; + *pattern = 0; + break; + + case WHITENESS: + *rop = PATCOPY; + *pattern = 0xFFFFFFFF; + break; + + case 0x000F0001: + *rop = PATCOPY; + *pattern = !*pattern; + break; + + } +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SBltDestroy () { + if (s_scode) { + int loop; + for (loop = 0; loop < OPTSTREAMS; ++loop) { + SCodeDelete(s_optstream[loop].stream); + ZeroMemory(&s_optstream[loop],sizeof(OPTSTREAMDATA)); + } + for (loop = 0; loop < 256; ++loop) + if ((s_scode+loop)->stream) + SCodeDelete((s_scode+loop)->stream); + FREE(s_scode); + s_scode = NULL; + } + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SBltGetSCode (DWORD rop3, + LPSTR buffer, + DWORD buffersize, + BOOL optimize) { + VALIDATEBEGIN; + VALIDATE(rop3); + VALIDATE(buffer); + VALIDATE(buffersize); + VALIDATEEND; + + // OPTIMIZE THE RASTER OPERATION CODE IF REQUESTED + if (optimize) { + DWORD pattern = 0; + OptimizeROP3(&rop3,&pattern); + } + + // DEFINE THE SOURCE AND OPERATION TEMPLATE STRINGS + static const char optemplate[] = "~^|&"; + static const char sourcetemplate[8][16] = {"SCDDDDDD", + "SCDSCDSC", + "SDCSDCSD", + "DDDDDDDD", + "DDDDDDDD", + "SASCADSS", + "SASCACDS", + "SASDACDS"}; + + // CREATE THE SOURCE STRING IN RPN ORDER + char sourcestring[16]; + SStrCopy(sourcestring,sourcetemplate[(rop3 >> 2) & 7]+(rop3 & 3),16); + + // CREATE THE OPERATION STRING + char opstring[16]; + { + DWORD currrop = rop3 >> 6; + for (int loop = 0; loop < 5; ++loop) { + opstring[loop] = optemplate[currrop & 3]; + currrop >>= 2; + } + opstring[loop] = 0; + if (rop3 & 32) + SStrPack(opstring,"~",16); + } + + // ELIMINATE REDUNDANT NOT OPERATIONS + while ((SStrLen(opstring) >= 2) && + (!strcmp(opstring+SStrLen(opstring)-2,"~~"))) + opstring[SStrLen(opstring)-2] = 0; + + // COUNT BINARY OPERATIONS + int binops = 0; + { + LPCSTR curr = opstring; + while (*curr) { + if (*curr != '~') + ++binops; + ++curr; + } + } + + // COMPUTE THE NUMBER OF SOURCES THAT WILL BE USED BY THE BINARY OPERATIONS + int sources = binops+1; + { + int loop = 0; + while (loop < sources) + if (sourcestring[loop++] == 'A') + ++sources; + } + + // COMPUTE THE SCODE STRING + char scode[32] = "# D="; + DWORD scodelen = 0; + { + char *curr = scode+SStrLen(scode); + char *currop = opstring; + BOOL savedval = 0; + *curr++ = *(sourcestring+(--sources)); + while (*currop) + if (*currop == '~') { + *curr++ = '^'; + *curr++ = '1'; + ++currop; + } + else if ((*(sourcestring+sources-1) == 'A') && !savedval) { + --sources; + scode[2] = 'A'; + *curr++ = ' '; + *curr++ = 'D'; + *curr++ = '='; + *curr++ = *(sourcestring+(--sources)); + savedval = 1; + } + else { + *curr++ = *currop++; + *curr++ = *(sourcestring+(--sources)); + } + *curr++ = 0; + scodelen = curr-scode; + } + + // COPY THE SCODE STRING INTO THE RESULT BUFFER + SStrCopy(buffer,scode,buffersize); + + return (scodelen <= buffersize); +} + +//=========================================================================== +BOOL APIENTRY SBltROP3 (LPBYTE dest, + LPBYTE source, + int width, + int height, + int destcx, + int sourcecx, + DWORD pattern, + DWORD rop3) { + // to minimize function call overhead for this time critical function, + // we use assert instead of validate so that the retail version has + // no parameter checking code + ASSERT(dest); + ASSERT(destcx >= width); + +//__asm int 0x3; + + // IGNORE ZERO-SIZED BLTS + if ((width <= 0) || (height <= 0)) + return TRUE; + + // INITIALIZE THIS MODULE IF NECESSARY + if (!s_scode) { + s_scode = (BLTINFOPTR)ALLOCZERO(256*sizeof(BLTINFO)); + if (!(InitOptStream("4 D=S",&s_optstream[OPT_SRCCOPY]) && + InitOptStream("4 D=A",&s_optstream[OPT_PATCOPY]))) { + SCodeDestroy(); + return FALSE; + } + } + + // FOR ALIGNED SRCCOPY AND PATCOPY OPERATIONS ON X86 SYSTEMS ONLY, + // PERFORM THE OPERATION DIRECTLY WITHOUT CALLING SCODEEXECUTE() AND + // WITHOUT WORRYING ABOUT BYTE OPERATIONS. THIS IS AN IMPORTANT + // OPTIMIZATION BECAUSE THESE BLT TYPES ARE VERY COMMON AND TEND TO BE + // THE MOST TIME CRITICAL BLTS IN A GAME. + +#ifdef _X86_ + if (((rop3 == SRCCOPY) || (rop3 == PATCOPY)) && !(((DWORD)dest | width) & 3)) { + DWORD adjustdest = destcx-width; + DWORD adjustsource = sourcecx-width; + LPBYTE retptr; + __asm mov retptr,OFFSET opt_loop + OPTSTREAMDATAPTR optdata = &s_optstream[rop3 == PATCOPY]; + LPBYTE jumpptr = *(optdata->jumptable+(width >> 2)); + *optdata->patchlocation = retptr-(LPBYTE)(optdata->patchlocation+1); + __asm { + push edi + push esi + + //int 0x3 + // mov eax,eax + + // FILL IN THE REGISTERS + mov edi,dest + mov esi,source + mov ebx,jumpptr + mov ecx,pattern + mov edx,height + + // EXECUTE THE FIRST SCAN LINE + jmp ebx + + // EXECUTE SUBSEQUENT SCAN LINES + align 16 + opt_loop: dec edx + jz opt_done + add edi,adjustdest + add esi,adjustsource + jmp ebx + + opt_done: pop esi + pop edi + } + + return TRUE; + } +#endif + + // CONVERT SELECTED RASTER OPERATIONS TO MORE EFFICIENT EQUIVALENTS + if ((rop3 != SRCCOPY) && (rop3 != PATCOPY)) + OptimizeROP3(&rop3,&pattern); + + // FIND OR CREATE TWO SCODE STREAMS TO CARRY OUT THIS RASTER OPERATION + DWORD index = (rop3 >> 16) & 0xFF; + if (!(s_scode+index)->used) { + DWORD currtime = GetTickCount(); +// note: write this +// FreeOldCodeStreams(currtime); + char scodestring[64] = ""; + SBltGetSCode(rop3,scodestring,64,0); + SCodeCompile(scodestring, + scodestring, + NULL, + UNROLL, + SCODE_CF_AUTOALIGNDWORD, + &(s_scode+index)->stream); + if ((s_scode+index)->stream) { + (s_scode+index)->used = 1; + (s_scode+index)->time = currtime; + } + else + return FALSE; + } + + // PERFORM THE BLT USING SCODE + SCODEEXECUTEDATA executedata; + executedata.size = sizeof(SCODEEXECUTEDATA); + executedata.flags = 0; + executedata.xiterations = width; + executedata.yiterations = height; + executedata.dest = dest; + executedata.source = source; + executedata.adjustdest = destcx-width; + executedata.adjustsource = sourcecx-width; + executedata.c = pattern; + return SCodeExecute((s_scode+index)->stream,&executedata); +} + +//=========================================================================== +BOOL APIENTRY SBltROP3Clipped (LPBYTE dest, + LPRECT destrect, + LPSIZE destsize, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + LPSIZE sourcesize, + int sourcepitch, + DWORD pattern, + DWORD rop3) { + // to minimize function call overhead for this time critical function, + // we use assert instead of validate so that the retail version has + // no parameter checking code + ASSERT(dest); + ASSERT(destpitch > 0); + + int destx = 0; + int desty = 0; + int destwidth = INT_MAX; + int destheight = INT_MAX; + int sourcex = 0; + int sourcey = 0; + int sourcewidth = INT_MAX; + int sourceheight = INT_MAX; + if (destrect) { + destx = max(0,destrect->left); + desty = max(0,destrect->top); + destwidth = destrect->right-destrect->left; + destheight = destrect->bottom-destrect->top; + } + if (destsize) { + destwidth = min(destwidth ,max(0,destsize->cx-destx)); + destheight = min(destheight,max(0,destsize->cy-desty)); + } + if (sourcerect) { + sourcex = max(0,sourcerect->left); + sourcey = max(0,sourcerect->top); + sourcewidth = sourcerect->right-sourcerect->left; + sourceheight = sourcerect->bottom-sourcerect->top; + } + if (sourcesize) { + sourcewidth = min(sourcewidth ,max(0,sourcesize->cx-sourcex)); + sourceheight = min(sourceheight,max(0,sourcesize->cy-sourcey)); + } + destwidth = min(destwidth ,sourcewidth ); + destheight = min(destheight,sourceheight); + if ((destwidth < 1) || (destheight < 1)) + return TRUE; + else + return SBltROP3(dest+desty*destpitch+destx, + source ? source+sourcey*sourcepitch+sourcex : NULL, + destwidth, + destheight, + destpitch, + sourcepitch, + pattern, + rop3); +} + +//=========================================================================== +BOOL APIENTRY SBltROP3Tiled (LPBYTE dest, + LPRECT destrect, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + int sourcepitch, + int sourceoffsetx, + int sourceoffsety, + DWORD pattern, + DWORD rop3) { + // to minimize function call overhead for this time critical function, + // we use assert instead of validate so that the retail version has + // no parameter checking code + ASSERT(dest); + ASSERT(destrect); + ASSERT(destpitch > 0); + + int sourcecx = sourcerect->right-sourcerect->left; + int sourcecy = sourcerect->bottom-sourcerect->top; + int y = destrect->top; + while (y < destrect->bottom) { + int tiley = sourcerect->top; + if (y == destrect->top) + tiley += (sourceoffsety+sourcecy) % sourcecy; + int tilecy = min(sourcerect->bottom-tiley, + destrect->bottom-y); + LPBYTE basedest = dest+y*destpitch; + LPBYTE basesource = source+tiley*sourcepitch; + int x = destrect->left; + while (x < destrect->right) { + int tilex = sourcerect->left; + if (x == destrect->left) + tilex += (sourceoffsetx+sourcecx) % sourcecx; + int tilecx = min(sourcerect->right-tilex, + destrect->right-x); + if (!SBltROP3(basedest+x, + basesource+tilex, + tilecx, + tilecy, + destpitch, + sourcepitch, + pattern, + rop3)) + return FALSE; + x += tilecx; + } + y += tilecy; + } + + return TRUE; +} diff --git a/Storm/SOURCE/SBMP.CPP b/Storm/SOURCE/SBMP.CPP new file mode 100644 index 0000000..b4cee46 --- /dev/null +++ b/Storm/SOURCE/SBMP.CPP @@ -0,0 +1,1137 @@ +/**************************************************************************** +* +* SBMP.CPP +* Storm bitmap functions +* +* By Michael O'Brien (2/8/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define BMPSIGNATURE 0x4D42 +#define PCXSIGNATURE 0x050A + + +/**************************************************************************** +* +* BMP ENCODER/DECODER +* +***/ + +static void FlipImage (LPBYTE dest, + LPBYTE source, + DWORD destbytes, + int destwidth, + int sourcewidth, + int height); + +//=========================================================================== +static BOOL DecodeBmpFile (HSFILE file, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + + // READ THE FILE HEADER + BITMAPFILEHEADER fileheader; + if (!SFileReadFile(file,&fileheader,sizeof(BITMAPFILEHEADER))) + return FALSE; + + // READ THE BITMAP INFO HEADER + BITMAPINFOHEADER infoheader; + if (!SFileReadFile(file,&infoheader,sizeof(BITMAPINFOHEADER))) + return FALSE; + if (width) + *width = infoheader.biWidth; + if (height) + *height = infoheader.biHeight; + if (bitdepth) + *bitdepth = infoheader.biBitCount; + + // READ THE PALETTE ENTRIES + if (infoheader.biBitCount > 8) + paletteentries = NULL; + if (paletteentries) { + RGBQUAD palettedata[256]; + if (!SFileReadFile(file,palettedata,256*sizeof(RGBQUAD))) + return FALSE; + + // CONVERT FROM RGBQUAD TO PALETTEENTRY FORMAT + for (int loop = 0; loop < 256; ++loop) { + (paletteentries+loop)->peRed = palettedata[loop].rgbRed; + (paletteentries+loop)->peGreen = palettedata[loop].rgbGreen; + (paletteentries+loop)->peBlue = palettedata[loop].rgbBlue; + (paletteentries+loop)->peFlags = 0; + } + } + + // READ THE BITMAP BITS + if (bitmapbits) { + SFileSetFilePointer(file, + fileheader.bfOffBits + -sizeof(BITMAPFILEHEADER) + -sizeof(BITMAPINFOHEADER) + -(paletteentries ? 256*sizeof(RGBQUAD) : 0), + NULL, + FILE_CURRENT); + DWORD bytesread = 0; + + { + LPBYTE temp = (LPBYTE)ALLOC(infoheader.biSizeImage); + SFileReadFile(file,temp,infoheader.biSizeImage,&bytesread); + int destwidth = (infoheader.biWidth*infoheader.biBitCount) >> 3; + int sourcewidth = destwidth; + if (sourcewidth & 3) + sourcewidth += 4-(sourcewidth & 3); + FlipImage(bitmapbits, + temp, + buffersize, + destwidth, + sourcewidth, + infoheader.biHeight); + FREE(temp); + } + + if (bytesread < infoheader.biSizeImage) + return FALSE; + } + + return TRUE; +} + +//=========================================================================== +static BOOL DecodeBmpMem (LPBYTE imagedata, + DWORD imagebytes, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + + // PROCESS THE HEADERS + LPBITMAPFILEHEADER fileheader = (LPBITMAPFILEHEADER)imagedata; + LPBITMAPINFOHEADER infoheader = (LPBITMAPINFOHEADER)(fileheader+1); + if (width) + *width = infoheader->biWidth; + if (height) + *height = infoheader->biHeight; + if (bitdepth) + *bitdepth = infoheader->biBitCount; + + // PROCESS THE PALETTE ENTRIES + if (infoheader->biBitCount > 8) + paletteentries = NULL; + if (paletteentries) { + RGBQUAD *palettedata = (RGBQUAD *)(infoheader+1); + for (int loop = 0; loop < 256; ++loop) { + (paletteentries+loop)->peRed = (palettedata+loop)->rgbRed; + (paletteentries+loop)->peGreen = (palettedata+loop)->rgbGreen; + (paletteentries+loop)->peBlue = (palettedata+loop)->rgbBlue; + (paletteentries+loop)->peFlags = 0; + } + } + + // PROCESS THE BITMAP BITS + if (bitmapbits) { + DWORD offset = fileheader->bfOffBits + -sizeof(BITMAPFILEHEADER) + -sizeof(BITMAPINFOHEADER) + -(paletteentries ? 256*sizeof(RGBQUAD) : 0); + int destwidth = (infoheader->biWidth*infoheader->biBitCount) >> 3; + int sourcewidth = destwidth; + if (sourcewidth & 3) + sourcewidth += 4-(sourcewidth & 3); + FlipImage(bitmapbits, + imagedata+offset, + buffersize, + destwidth, + sourcewidth, + infoheader->biHeight); + } + + return TRUE; +} + +//=========================================================================== +static BOOL EncodeBmp256File (HANDLE file, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + int width, + int height) { + + // WRITE THE FILE HEADER + { + BITMAPFILEHEADER fileheader; + ZeroMemory(&fileheader,sizeof(BITMAPFILEHEADER)); + fileheader.bfType = BMPSIGNATURE; + fileheader.bfOffBits = sizeof(BITMAPFILEHEADER) + +sizeof(BITMAPINFOHEADER) + +256*sizeof(RGBQUAD); + fileheader.bfSize = fileheader.bfOffBits+width*height; + DWORD byteswritten; + WriteFile(file,&fileheader,sizeof(BITMAPFILEHEADER),&byteswritten,NULL); + } + + // WRITE THE BITMAP INFO HEADER + { + BITMAPINFOHEADER infoheader; + ZeroMemory(&infoheader,sizeof(BITMAPINFOHEADER)); + infoheader.biSize = sizeof(BITMAPINFOHEADER); + infoheader.biWidth = width; + infoheader.biHeight = height; + infoheader.biPlanes = 1; + infoheader.biBitCount = 8; + infoheader.biCompression = BI_RGB; + infoheader.biSizeImage = width*height; + infoheader.biClrUsed = 256; + infoheader.biClrImportant = 256; + DWORD byteswritten; + WriteFile(file,&infoheader,sizeof(BITMAPINFOHEADER),&byteswritten,NULL); + } + + // WRITE THE PALETTE ENTRIES + { + RGBQUAD palettedata[256]; + for (int loop = 0; loop < 256; ++loop) { + palettedata[loop].rgbRed = (paletteentries+loop)->peRed; + palettedata[loop].rgbGreen = (paletteentries+loop)->peGreen; + palettedata[loop].rgbBlue = (paletteentries+loop)->peBlue; + palettedata[loop].rgbReserved = 0; + } + DWORD byteswritten; + WriteFile(file,palettedata,256*sizeof(RGBQUAD),&byteswritten,NULL); + } + + // WRITE THE BITMAP BITS + { + DWORD byteswritten; + int destwidth = width; + if (destwidth & 3) + destwidth += 4-(destwidth & 3); + LPBYTE temp = (LPBYTE)ALLOC(destwidth*height); + FlipImage(temp, + bitmapbits, + destwidth*height, + destwidth, + width, + height); + WriteFile(file,temp,destwidth*height,&byteswritten,NULL); + FREE(temp); + } + + return TRUE; +} + +//=========================================================================== +static void FlipImage (LPBYTE dest, + LPBYTE source, + DWORD destbytes, + int destwidth, + int sourcewidth, + int height) { + VALIDATEBEGIN; + VALIDATE(dest); + VALIDATE(source); + VALIDATE(destbytes); + VALIDATE(destwidth); + VALIDATE(sourcewidth); + VALIDATE(height); + VALIDATEENDVOID; + + source += (height-1)*sourcewidth; + + LPBYTE destterm = dest+destbytes; + while (height--) { + DWORD bytestocopy = min(destwidth,destterm-dest); + if (!bytestocopy) + break; + CopyMemory(dest,source,bytestocopy); + dest += bytestocopy; + source -= sourcewidth; + } + +} + + +/**************************************************************************** +* +* GIF ENCODER/DECODER +* +***/ + +typedef struct _GIFCOMPRESSREC { + int bits; + int max_code; + int init_bits; + int cur_accum; + int cur_bits; + + int waiting_code; + BOOL first_byte; + + int clearcode; + int EOFcode; + int freecode; + + int *hash_code; + int *hash_value; + + int bytesinpkt; + BYTE packetbuf[256]; +} GIFCOMPRESSREC; + +#pragma pack(1) +typedef struct _GIFHEADERREC { + char signature[6]; + WORD width; + WORD height; + BYTE flags; + BYTE bgidx; + BYTE reserved; +} GIFHEADERREC; +#pragma pack() + +typedef struct _GIFIMAGEDESCREC { + WORD x; + WORD y; + WORD width; + WORD height; + BYTE flags; + BYTE codesize; +} GIFIMAGEDESCREC; + +typedef struct _GIFPALREC { + struct { + BYTE red; + BYTE green; + BYTE blue; + } idx[256]; +} GIFPALREC; + +typedef struct _GIFMARKERREC { + char ch; +} GIFMARKERREC; + +#define HASH_ENTRY(prefix,suffix) ((((int) (prefix)) << 8) | (suffix)) +#define MAX_LZW_BITS 12 /* maximum LZW code size (4096 symbols) */ +#define LZW_TABLE_SIZE ((int) 1 << MAX_LZW_BITS) +#define HSIZE 5003 /* hash table size for 80% occupancy */ +#define MAXCODE(bits) (((int) 1 << (bits)) - 1) + +static inline void Output (GIFCOMPRESSREC *compress, + LPVOID *dest, + int code); + +//=========================================================================== +static void ClearBlock (GIFCOMPRESSREC *compress, + LPVOID *dest) { + ZeroMemory(compress->hash_code,HSIZE*sizeof(int)); + compress->freecode = compress->clearcode + 2; + Output(compress, + dest, + compress->clearcode); + compress->bits = compress->init_bits; /* reset code size */ + compress->max_code = MAXCODE(compress->bits); +} + +//=========================================================================== +static void FlushPacket (GIFCOMPRESSREC *compress, + LPVOID *dest) { + if (!compress->bytesinpkt) + return; + compress->packetbuf[0] = (BYTE)(compress->bytesinpkt++); + CopyMemory(*dest,compress->packetbuf,compress->bytesinpkt); + *dest = (LPBYTE)*dest + compress->bytesinpkt; + compress->bytesinpkt = 0; +} + +//=========================================================================== +static inline void Output (GIFCOMPRESSREC *compress, + LPVOID *dest, + int code) { + compress->cur_accum |= code << compress->cur_bits; + compress->cur_bits += compress->bits; + + while (compress->cur_bits >= 8) { + compress->packetbuf[++compress->bytesinpkt] = + (BYTE)(compress->cur_accum & 0xFF); + if (compress->bytesinpkt >= 255) + FlushPacket(compress, + dest); + compress->cur_accum >>= 8; + compress->cur_bits -= 8; + } + + /* + * If the next entry is going to be too big for the code size, + * then increase it, if possible. We do this here to ensure + * that it's done in sync with the decoder's codesize increases. + */ + if (compress->freecode > compress->max_code) { + compress->bits++; + if (compress->bits == MAX_LZW_BITS) + compress->max_code = LZW_TABLE_SIZE; /* freecode will never exceed this */ + else + compress->max_code = MAXCODE(compress->bits); + } +} + +//=========================================================================== +static inline void CompressGifByte (GIFCOMPRESSREC *compress, + LPVOID *dest, + int val) { + register int i; + register int disp; + register int probe_value; + + if (compress->first_byte) { /* need to initialize waiting_code */ + compress->waiting_code = val; + compress->first_byte = FALSE; + return; + } + + /* Probe hash table to see if a symbol exists for + * waiting_code followed by val. + * If so, replace waiting_code by that symbol and return. + */ + i = ((int) val << (MAX_LZW_BITS-8)) + compress->waiting_code; + /* i is less than twice 2**MAX_LZW_BITS, therefore less than twice HSIZE */ + if (i >= HSIZE) + i -= HSIZE; + + probe_value = HASH_ENTRY(compress->waiting_code, val); + + if (compress->hash_code[i] != 0) { /* is first probed slot empty? */ + if (compress->hash_value[i] == probe_value) { + compress->waiting_code = compress->hash_code[i]; + return; + } + if (i == 0) /* secondary hash (after G. Knott) */ + disp = 1; + else + disp = HSIZE - i; + for (;;) { + i -= disp; + if (i < 0) + i += HSIZE; + if (compress->hash_code[i] == 0) + break; /* hit empty slot */ + if (compress->hash_value[i] == probe_value) { + compress->waiting_code = compress->hash_code[i]; + return; + } + } + } + + /* here when hashtable[i] is an empty slot; desired symbol not in table */ + Output(compress, + dest, + compress->waiting_code); + if (compress->freecode < LZW_TABLE_SIZE) { + compress->hash_code[i] = compress->freecode++; /* add symbol to hashtable */ + compress->hash_value[i] = probe_value; + } else + ClearBlock(compress, + dest); + compress->waiting_code = val; +} + +//=========================================================================== +static DWORD CompressGifImage (LPVOID dest, + LPCVOID source, + DWORD sourcebytes) { + LPVOID basedest = dest; + + // INITIALIZE COMPRESSION + GIFCOMPRESSREC compress; + ZeroMemory(&compress,sizeof(GIFCOMPRESSREC)); + compress.bits = 9; + compress.init_bits = 9; + compress.max_code = MAXCODE(compress.bits); + compress.clearcode = 1 << (compress.bits-1); + compress.EOFcode = compress.clearcode+1; + compress.freecode = compress.clearcode+2; + compress.first_byte = TRUE; + compress.hash_code = (int *)ALLOCZERO(HSIZE*sizeof(int)); + compress.hash_value = (int *)ALLOCZERO(HSIZE*sizeof(int)); + Output(&compress, + &dest, + compress.clearcode); + + // COMPRESS THE IMAGE + while (sourcebytes--) { + CompressGifByte(&compress, + &dest, + *(LPBYTE)source); + source = (LPBYTE)source+1; + } + + // CLEANUP + if (!compress.first_byte) + Output(&compress, + &dest, + compress.waiting_code); + Output(&compress, + &dest, + compress.EOFcode); + if (compress.cur_bits > 0) + compress.packetbuf[++compress.bytesinpkt] = + (BYTE)(compress.cur_accum & 0xFF); + FlushPacket(&compress, + &dest); + + FREE(compress.hash_code); + FREE(compress.hash_value); + + return (LPBYTE)dest-(LPBYTE)basedest; +} + +//=========================================================================== +static BOOL EncodeGif256File (HANDLE file, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + int width, + int height) { + + // WRITE THE HEADER + { + GIFHEADERREC rec; + rec.signature[0] = 'G'; + rec.signature[1] = 'I'; + rec.signature[2] = 'F'; + rec.signature[3] = '8'; + rec.signature[4] = '7'; + rec.signature[5] = 'a'; + rec.width = (WORD)width; + rec.height = (WORD)height; + rec.flags = 0x80 // global color table + | 0x70 // 256 color image + | 0x07; // 256 colors in global color table; + rec.bgidx = 0; + rec.reserved = 0; + DWORD byteswritten; + WriteFile(file,&rec,sizeof(GIFHEADERREC),&byteswritten,NULL); + } + + // WRITE THE COLOR TABLE + { + GIFPALREC pal; + for (int loop = 0; loop < 256; ++loop) { + pal.idx[loop].red = (paletteentries+loop)->peRed; + pal.idx[loop].green = (paletteentries+loop)->peGreen; + pal.idx[loop].blue = (paletteentries+loop)->peBlue; + } + DWORD byteswritten; + WriteFile(file,&pal,sizeof(GIFPALREC),&byteswritten,NULL); + } + + // WRITE THE SEPARATOR + { + GIFMARKERREC rec; + rec.ch = ','; + DWORD byteswritten; + WriteFile(file,&rec,sizeof(GIFMARKERREC),&byteswritten,NULL); + } + + // WRITE THE IMAGE DESCRIPTOR + { + GIFIMAGEDESCREC rec; + rec.x = 0; + rec.y = 0; + rec.width = (WORD)width; + rec.height = (WORD)height; + rec.flags = 0; + rec.codesize = 8; + DWORD byteswritten; + WriteFile(file,&rec,sizeof(GIFIMAGEDESCREC),&byteswritten,NULL); + } + + // WRITE THE BITMAP BITS + { + LPBYTE compressed = (LPBYTE)ALLOC(width*height*2); + DWORD bytes = CompressGifImage(compressed, + bitmapbits, + width*height); + DWORD byteswritten; + WriteFile(file,compressed,bytes,&byteswritten,NULL); + FREE(compressed); + } + + // WRITE THE TERMINATOR + { + GIFMARKERREC rec; + rec.ch = 0; + DWORD byteswritten; + WriteFile(file,&rec,sizeof(GIFMARKERREC),&byteswritten,NULL); + rec.ch = ';'; + WriteFile(file,&rec,sizeof(GIFMARKERREC),&byteswritten,NULL); + } + + return TRUE; +} + + +/**************************************************************************** +* +* PCX ENCODER/DECODER +* +***/ + +typedef struct _PCXHEADERREC { + WORD signature; + BYTE encoding; + BYTE bitsperpixel; + WORD x1; + WORD y1; + WORD x2; + WORD y2; + WORD screenwidth; + WORD screenheight; +} PCXHEADERREC; + +typedef struct _PCXINFOREC { + BYTE mode; + BYTE planes; + WORD bytesperline; + BYTE unused[60]; +} PCXINFOREC; + +typedef struct _PCXRGBREC { + BYTE red; + BYTE green; + BYTE blue; +} PCXRGBREC; + +typedef struct _PCXFILEREC { + PCXHEADERREC header; + PCXRGBREC pal16[16]; + PCXINFOREC info; +} PCXFILEREC; + +typedef struct _PCXEXTPALREC { + BYTE number; + PCXRGBREC pal256[256]; +} PCXEXTPALREC; + +static void UncompressPcxImage (LPBYTE dest, + LPBYTE source, + DWORD destbytes, + DWORD sourcebytes); + +//=========================================================================== +static void CompressPcxRow (LPBYTE *dest, LPBYTE *source, int width) { + do { + BYTE ch = *(*source)++; + int count = 1; + --width; + while (width && (ch == **source) && (count < 63)) { + ++count; + --width; + ++*source; + } + if ((count > 1) || (ch >= 0xC0)) { + count |= 0xC0; + *(*dest)++ = (BYTE)(count & 0xFF); + } + *(*dest)++ = ch; + } while (width); +} + +//=========================================================================== +static BOOL DecodePcxFile (HSFILE file, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + + // READ THE HEADER + PCXFILEREC rec; + if (!SFileReadFile(file,&rec,sizeof(PCXFILEREC))) + return 0; + int imagewidth = rec.header.x2+1-rec.header.x1; + int imageheight = rec.header.y2+1-rec.header.y1; + int imagebitdepth = rec.header.bitsperpixel; + if (width) + *width = imagewidth; + if (height) + *height = imageheight; + if (bitdepth) + *bitdepth = imagebitdepth; + + // READ THE BITMAP BITS + if (bitmapbits) { + DWORD bytestoread = SFileGetFileSize(file)-SFileSetFilePointer(file,0,NULL,FILE_CURRENT); + LPBYTE compressed = (LPBYTE)ALLOC(bytestoread); + SFileReadFile(file,compressed,bytestoread); + UncompressPcxImage(bitmapbits, + compressed, + buffersize, + bytestoread); + FREE(compressed); + } + else + SFileSetFilePointer(file,0,NULL,FILE_END); + + // READ THE PALETTE ENTRIES + if (paletteentries && (imagebitdepth == 8)) { + PCXRGBREC paldata[256]; + SFileSetFilePointer(file,-256*(int)sizeof(PCXRGBREC),NULL,FILE_CURRENT); + SFileReadFile(file,paldata,256*sizeof(PCXRGBREC)); + + // CONVERT FROM PCXRGBREC TO PALETTEENTRY FORMAT + for (int loop = 0; loop < 256; ++loop) { + (paletteentries+loop)->peRed = paldata[loop].red; + (paletteentries+loop)->peGreen = paldata[loop].green; + (paletteentries+loop)->peBlue = paldata[loop].blue; + (paletteentries+loop)->peFlags = 0; + } + } + + return TRUE; +} + +//=========================================================================== +static BOOL DecodePcxMem (LPBYTE imagedata, + DWORD imagebytes, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + + // PROCESS THE HEADER + PCXFILEREC *rec = (PCXFILEREC *)imagedata; + int imagewidth = rec->header.x2+1-rec->header.x1; + int imageheight = rec->header.y2+1-rec->header.y1; + int imagebitdepth = rec->header.bitsperpixel; + if (width) + *width = imagewidth; + if (height) + *height = imageheight; + if (bitdepth) + *bitdepth = imagebitdepth; + + // PROCESS THE BITMAP BITS + if (bitmapbits) + UncompressPcxImage(bitmapbits, + (LPBYTE)(rec+1), + min(buffersize,(DWORD)(imagewidth*imageheight)), + imagebytes-sizeof(PCXFILEREC)); + + // PROCESS THE PALETTE ENTRIES + if (paletteentries && (imagebitdepth == 8)) { + PCXRGBREC *paldata = (PCXRGBREC *)(imagedata+imagebytes-256*sizeof(PCXRGBREC)); + for (int loop = 0; loop < 256; ++loop) { + (paletteentries+loop)->peRed = (paldata+loop)->red; + (paletteentries+loop)->peGreen = (paldata+loop)->green; + (paletteentries+loop)->peBlue = (paldata+loop)->blue; + (paletteentries+loop)->peFlags = 0; + } + } + + return TRUE; +} + +//=========================================================================== +static BOOL EncodePcx256File (HANDLE file, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + int width, + int height) { + + // WRITE THE HEADER + { + PCXFILEREC rec; + ZeroMemory(&rec,sizeof(PCXFILEREC)); + rec.header.signature = PCXSIGNATURE; + rec.header.encoding = 1; + rec.header.bitsperpixel = 8; + rec.header.x2 = width-1; + rec.header.y2 = height-1; + rec.header.screenwidth = width; + rec.header.screenheight = height; + rec.info.planes = 1; + rec.info.bytesperline = width; + DWORD byteswritten; + WriteFile(file,&rec,sizeof(PCXFILEREC),&byteswritten,NULL); + } + + // WRITE THE BITMAP BITS + { + LPBYTE compressed = (LPBYTE)ALLOC(width*height*2); + LPBYTE source = bitmapbits; + LPBYTE dest = compressed; + for (int loop = 0; loop < height; ++loop) + CompressPcxRow(&dest,&source,width); + DWORD byteswritten; + WriteFile(file,compressed,dest-compressed,&byteswritten,NULL); + FREE(compressed); + } + + // WRITE THE PALETTE ENTRIES + { + PCXEXTPALREC pal; + pal.number = 12; + for (int loop = 0; loop < 256; ++loop) { + pal.pal256[loop].red = (paletteentries+loop)->peRed; + pal.pal256[loop].green = (paletteentries+loop)->peGreen; + pal.pal256[loop].blue = (paletteentries+loop)->peBlue; + } + DWORD byteswritten; + WriteFile(file,&pal,sizeof(PCXEXTPALREC),&byteswritten,NULL); + } + + return TRUE; +} + +//=========================================================================== +static void UncompressPcxImage (LPBYTE dest, + LPBYTE source, + DWORD destbytes, + DWORD sourcebytes) { + LPBYTE destterm = dest+destbytes; + LPBYTE sourceterm = source+sourcebytes; + while ((dest < destterm) && (source < sourceterm)) { + BYTE val = *source++; + if (val >= 0xC0) { + DWORD count = val & 0x3F; + count = min(count,(DWORD)(destterm-dest)); + val = *source++; + FillMemory(dest,count,val); + dest += count; + } + else + *dest++ = val; + } +} + + +/**************************************************************************** +* +* SUPPORT FUNCTIONS +* +***/ + +//=========================================================================== +static LPCTSTR FindExtension (LPCTSTR filename) { + LPCTSTR result = filename; + while (SStrChr(result,'\\')) + result = SStrChr(result,'\\')+1; + while (SStrChr(result+1,'.')) + result = SStrChr(result+1,'.'); + return result; +} + +//=========================================================================== +static DWORD DetermineImageType (WORD signature) { + switch (signature) { + + case BMPSIGNATURE: + return SBMP_IMAGETYPE_BMP; + + case PCXSIGNATURE: + return SBMP_IMAGETYPE_PCX; + + default: + return 0; + + } +} + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SBmpAllocLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE *returnedbuffer, + int *width, + int *height, + int *bitdepth, + int requestedbitdepth, + SBMPALLOCPROC allocproc) { + if (returnedbuffer) + *returnedbuffer = NULL; + if (width) + *width = 0; + if (height) + *height = 0; + if (bitdepth) + *bitdepth = 0; + + VALIDATEBEGIN; + VALIDATE(filename); + VALIDATE(*filename); + VALIDATE(returnedbuffer); + VALIDATEEND; + + // OPEN THE FILE + HSFILE file; + if (!SFileOpenFile(filename,&file)) + return FALSE; + + // LOAD THE FILE INTO MEMORY + DWORD filesize = SFileGetFileSize(file); + LPBYTE filedata = (LPBYTE)ALLOC(filesize); + SFileReadFile(file, + filedata, + filesize); + SFileCloseFile(file); + + BOOL success = FALSE; + TRY { + + // DETERMINE THE SOURCE IMAGE DIMENSIONS + int localwidth, localheight, localbitdepth; + if (!SBmpDecodeImage(SBMP_IMAGETYPE_AUTO, + filedata, + filesize, + NULL, + NULL, + 0, + &localwidth, + &localheight, + &localbitdepth)) + LEAVE; + + // IF THE REQUESTED BIT DEPTH DOES NOT MATCH THE ACTUAL BIT DEPTH, + // RETURN AN ERROR, SINCE WE DO NOT CURRENTLY IMPLEMENT IMAGE FORMAT + // CONVERSION + if (!requestedbitdepth) + requestedbitdepth = localbitdepth; + if (requestedbitdepth != localbitdepth) + LEAVE; + + // ALLOCATE A BUFFER TO HOLD THE IMAGE + DWORD imagesize = localwidth*localheight*requestedbitdepth/8; + if (allocproc) + *returnedbuffer = (LPBYTE)allocproc(imagesize); + else + *returnedbuffer = (LPBYTE)SMemAlloc(imagesize, + filename, + SERR_LINECODE_FILE, + 0); + if (!*returnedbuffer) + LEAVE; + + // DECODE THE IMAGE INTO THE BUFFER + SBmpDecodeImage(SBMP_IMAGETYPE_AUTO, + filedata, + filesize, + paletteentries, + *returnedbuffer, + imagesize); + + // RETURN THE WIDTH, HEIGHT, AND BITDEPTH + if (width) + *width = localwidth; + if (height) + *height = localheight; + if (bitdepth) + *bitdepth = requestedbitdepth; + + success = TRUE; + } + FINALLY { + FREE(filedata); + } + + return success; +} + +//=========================================================================== +BOOL APIENTRY SBmpDecodeImage (DWORD imagetype, + LPBYTE imagedata, + DWORD imagebytes, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + if (width) + *width = 0; + if (height) + *height = 0; + if (bitdepth) + *bitdepth = 0; + + VALIDATEBEGIN; + VALIDATE(imagedata); + VALIDATE(imagebytes); + VALIDATE(buffersize || !bitmapbits); + VALIDATEEND; + + // IF NO IMAGE TYPE WAS GIVEN, TRY TO DETERMINE IT FROM THE SIGNATURE + if ((imagetype == SBMP_IMAGETYPE_AUTO) && + (imagebytes >= sizeof(WORD))) + imagetype = DetermineImageType(*(LPWORD)imagedata); + + // DECODE THE IMAGE + switch (imagetype) { + + case SBMP_IMAGETYPE_BMP: + return DecodeBmpMem(imagedata, + imagebytes, + paletteentries, + bitmapbits, + buffersize, + width, + height, + bitdepth); + + case SBMP_IMAGETYPE_PCX: + return DecodePcxMem(imagedata, + imagebytes, + paletteentries, + bitmapbits, + buffersize, + width, + height, + bitdepth); + + default: + return FALSE; + + } +} + +//=========================================================================== +BOOL APIENTRY SBmpLoadImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + DWORD buffersize, + int *width, + int *height, + int *bitdepth) { + if (width) + *width = 0; + if (height) + *height = 0; + if (bitdepth) + *bitdepth = 0; + + VALIDATEBEGIN; + VALIDATE(filename); + VALIDATE(*filename); + VALIDATE(buffersize || !bitmapbits); + VALIDATEEND; + + // OPEN THE FILE + HSFILE file; + if (!SFileOpenFile(filename,&file)) + return FALSE; + + // DETERMINE THE IMAGE TYPE + DWORD imagetype = 0; + { + WORD signature; + if (SFileReadFile(file,&signature,sizeof(WORD))) { + SFileSetFilePointer(file,-2,NULL,FILE_CURRENT); + imagetype = DetermineImageType(signature); + } + } + + // READ AND DECODE THE IMAGE + BOOL result = FALSE; + switch (imagetype) { + + case SBMP_IMAGETYPE_BMP: + result = DecodeBmpFile(file, + paletteentries, + bitmapbits, + buffersize, + width, + height, + bitdepth); + break; + + case SBMP_IMAGETYPE_PCX: + result = DecodePcxFile(file, + paletteentries, + bitmapbits, + buffersize, + width, + height, + bitdepth); + break; + + } + + // CLOSE THE FILE + SFileCloseFile(file); + + return result; +} + +//=========================================================================== +BOOL APIENTRY SBmpSaveImage (LPCTSTR filename, + LPPALETTEENTRY paletteentries, + LPBYTE bitmapbits, + int width, + int height, + int bitdepth) { + VALIDATEBEGIN; + VALIDATE(filename); + VALIDATE(*filename); + VALIDATE(paletteentries); + VALIDATE(bitmapbits); + VALIDATE(width > 0); + VALIDATE(height > 0); + VALIDATEEND; + + // STORM CURRENTLY ONLY SUPPORTS 256-COLOR MODE, SO FOR THE TIME BEING, + // REJECT ALL BIT DEPTHS EXCEPT 8BPP + if (bitdepth != 8) + return FALSE; + + // OPEN THE FILE + HANDLE file = CreateFile(filename, + GENERIC_WRITE, + 0, + (LPSECURITY_ATTRIBUTES)NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (file == INVALID_HANDLE_VALUE) + return FALSE; + + // WRITE THE IMAGE + LPCTSTR ext = FindExtension(filename); + BOOL result = 0; + if (ext && !_stricmp(ext,".pcx")) + result = EncodePcx256File(file, + paletteentries, + bitmapbits, + width, + height); + else if (ext && !_stricmp(ext,".gif")) + result = EncodeGif256File(file, + paletteentries, + bitmapbits, + width, + height); + else + result = EncodeBmp256File(file, + paletteentries, + bitmapbits, + width, + height); + + // CLOSE THE FILE + CloseHandle(file); + + return result; +} diff --git a/Storm/SOURCE/SCMD.CPP b/Storm/SOURCE/SCMD.CPP new file mode 100644 index 0000000..b847cd1 --- /dev/null +++ b/Storm/SOURCE/SCMD.CPP @@ -0,0 +1,686 @@ +/**************************************************************************** +* +* SCMD.CPP +* Storm command line parsing functions +* +* By Michael O'Brien (4/14/97) +* Based on cmdline.cpp by Patrick Wyatt (1/21/93) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define ARGVAL(f) ((f) & SCMD_ARG_MASK) +#define BOOLVAL(f) ((f) & SCMD_BOOL_MASK) +#define NUMVAL(f) ((f) & SCMD_NUM_MASK) +#define TYPEVAL(f) ((f) & SCMD_TYPE_MASK) + +#define MAXNAMELENGTH 16 +#define FLAGCHARS "-/" +#define WHITESPACE " ,;\"\t\n\r\x1A" + +#define STR_BADARGUMENT 0 +#define STR_NOTENOUGHARGUMENTS 1 +#define STR_OPENFAILED 2 +#define STRINGS 3 + +static const LPCTSTR s_errorstr[STRINGS] = + {"Invalid argument: %s", + "The syntax of the command is incorrect.", + "Unable to open response file: %s"}; + +NODEDECL(CMDDEF) { + DWORD flags; + DWORD id; + char name[MAXNAMELENGTH]; + int namelength; + DWORD setvalue; + DWORD setmask; + LPVOID variableptr; + DWORD variablebytes; + SCMDCALLBACK callback; + BOOL found; + union { + DWORD currvalue; + LPTSTR currvaluestr; + }; +} *CMDDEFPTR; + +typedef struct _PROCESSING { + CMDDEFPTR ptr; + char name[MAXNAMELENGTH]; + int namelength; +} PROCESSING, *PROCESSINGPTR; + +static BOOL s_addedoptional = FALSE; +static LIST(CMDDEF) s_arglist; +static LIST(CMDDEF) s_flaglist; + +static BOOL ProcessString (LPCTSTR *stringptr, + PROCESSINGPTR processing, + CMDDEFPTR *nextarg, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback); +static BOOL ProcessToken (LPCTSTR string, + BOOL quoted, + PROCESSINGPTR processing, + CMDDEFPTR *nextarg, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback); + +//=========================================================================== +static void ConvertBool (CMDDEFPTR ptr, + LPCTSTR string, + int *datachars) { + + // DETERMINE WHETHER THE FLAG WILL BE SET OR CLEARED + BOOL set; + if (*string == '-') { + set = FALSE; + *datachars = 1; + } + else if (*string == '+') { + set = TRUE; + *datachars = 1; + } + else if (BOOLVAL(ptr->flags) == SCMD_BOOL_CLEAR) + set = FALSE; + else + set = TRUE; + + // MODIFY IT LOCALLY + ptr->currvalue &= ~ptr->setmask; + if (set) + ptr->currvalue |= ptr->setvalue; + + // MODIFY IT IN THE APPLICATION'S MEMORY + if (ptr->variableptr) { + *(LPDWORD)ptr->variableptr &= ~ptr->setmask; + if (set) + *(LPDWORD)ptr->variableptr |= ptr->setvalue; + } + +} + +//=========================================================================== +static void ConvertNumber (CMDDEFPTR ptr, + LPCTSTR string, + int *datachars) { + + // DETERMINE THE NUMERIC VALUE + LPTSTR endptr = NULL; + if (NUMVAL(ptr->flags) == SCMD_NUM_SIGNED) + ptr->currvalue = (DWORD)strtol(string,&endptr,0); + else + ptr->currvalue = strtoul(string,&endptr,0); + if (endptr) + *datachars = endptr-string; + else + *datachars = SStrLen(string); + + // WRITE IT INTO THE APPLICATION'S MEMORY + if (ptr->variableptr) + CopyMemory(ptr->variableptr, + &ptr->currvalue, + min(sizeof(ptr->currvalue),ptr->variablebytes)); + +} + +//=========================================================================== +static void ConvertString (CMDDEFPTR ptr, + LPCTSTR string, + int *datachars) { + *datachars = SStrLen(string); + + // SAVE THE STRING + if (ptr->currvaluestr) + FREE(ptr->currvaluestr); + ptr->currvaluestr = (LPTSTR)ALLOC(SStrLen(string)+1); + SStrCopy(ptr->currvaluestr,string); + + // COPY THE STRING INTO THE APPLICATION'S MEMORY + if (ptr->variableptr) + SStrCopy((LPTSTR)ptr->variableptr, + string, + ptr->variablebytes); + +} + +//=========================================================================== +static CMDDEFPTR FindFlagDef (LPCTSTR string, + CMDDEFPTR firstdef, + int minlength) { + int strlength = SStrLen(string); + int bestlength = minlength-1; + CMDDEFPTR bestptr = NULL; + for (CMDDEFPTR curr = firstdef; + curr; + curr = curr->Next()) + if ((curr->namelength > bestlength) && + (curr->namelength <= strlength)) { + BOOL match = FALSE; + if (curr->flags & SCMD_CASESENSITIVE) + match = !strncmp(curr->name,string,curr->namelength); + else + match = !_strnicmp(curr->name,string,curr->namelength); + if (match) { + bestlength = curr->namelength; + bestptr = curr; + } + } + return bestptr; +} + +//=========================================================================== +static void GenerateError (SCMDERRORCALLBACK errorcallback, + DWORD errorcode, + LPCTSTR itemstring) { + + // GENERATE THE COMPLETE ERROR MESSAGE + char errorstr[256] = ""; + { + DWORD strid; + UINT resid; + switch (errorcode) { + + case SCMD_ERROR_BAD_ARGUMENT: + strid = STR_BADARGUMENT; + resid = IDS_BADARGUMENT; + break; + + case SCMD_ERROR_NOT_ENOUGH_ARGUMENTS: + strid = STR_NOTENOUGHARGUMENTS; + resid = IDS_NOTENOUGHARGUMENTS; + break; + + case SCMD_ERROR_OPEN_FAILED: + strid = STR_OPENFAILED; + resid = IDS_OPENFAILED; + break; + + default: + return; + + } + char buffer[256] = ""; + LoadString(StormGetInstance(),resid,buffer,256); + if (!buffer[0]) + SStrCopy(buffer,s_errorstr[strid],256); + if (strstr(buffer,"%s")) + wsprintf(errorstr,buffer,itemstring); + else + SStrCopy(errorstr,buffer,256); + if (errorstr[0]) + SStrPack(errorstr,"\n",256); + } + + // SET THE LAST ERROR CODE + SErrSetLastError(errorcode); + + // CALL THE APPLICATION'S CALLBACK FUNCTION + CMDERROR data; + data.errorcode = errorcode; + data.itemstr = itemstring; + data.errorstr = errorstr; + errorcallback(&data); + +} + +//=========================================================================== +static BOOL PerformConversion (CMDDEFPTR ptr, + LPCTSTR string, + int *datachars) { + + // PERFORM THE CONVERSION + *datachars = 0; + switch (TYPEVAL(ptr->flags)) { + + case SCMD_TYPE_BOOL: + ConvertBool(ptr,string,datachars); + break; + + case SCMD_TYPE_NUMERIC: + ConvertNumber(ptr,string,datachars); + break; + + case SCMD_TYPE_STRING: + ConvertString(ptr,string,datachars); + break; + + default: + return FALSE; + + } + + // MARK THE PARAMETER AS FOUND + ptr->found = TRUE; + + // CALL THE APPLICATION'S CALLBACK FUNCTION + if (ptr->callback) { + CMDPARAMS params; + params.flags = ptr->flags; + params.id = ptr->id; + params.name = ptr->name; + params.variable = ptr->variableptr; + params.setvalue = ptr->setvalue; + params.setmask = ptr->setmask; + params.unsignedvalue = ptr->currvalue; + if (!ptr->callback(¶ms,string)) + return FALSE; + } + + // PROPAGATE THE CURRENT VALUE TO ANY OTHER ARGUMENTS WITH THE SAME ID, + // SO THAT IF THE USER QUERIES THE VALUE BY ID THEN THE QUERY FUNCTION + // CAN SIMPLY RETURN THE FIRST HIT + for (BOOL flaglist = FALSE; flaglist <= TRUE; ++flaglist) + ITERATELIST(CMDDEF, + flaglist ? s_flaglist : s_arglist, + currptr) + if ((currptr->id == ptr->id) && + (TYPEVAL(currptr->flags) == TYPEVAL(ptr->flags)) && + (currptr != ptr)) { + currptr->found = TRUE; + if (TYPEVAL(currptr->flags) == SCMD_TYPE_STRING) { + if (currptr->currvaluestr) + FREE(currptr->currvaluestr); + currptr->currvaluestr = (LPTSTR)ALLOC(SStrLen(ptr->currvaluestr)+1); + SStrCopy(currptr->currvaluestr,ptr->currvaluestr); + } + else + currptr->currvalue = ptr->currvalue; + } + + return TRUE; +} + +//=========================================================================== +static BOOL ProcessCurrentFlag (LPCTSTR string, + PROCESSINGPTR processing, + int *datachars) { + *datachars = 0; + CMDDEFPTR ptr = processing->ptr; + processing->ptr = NULL; + while (ptr) { + int currdatachars; + if (!PerformConversion(ptr,string,&currdatachars)) + return FALSE; + *datachars = max(*datachars,currdatachars); + ptr = FindFlagDef(processing->name,ptr->Next(),processing->namelength); + } + return TRUE; +} + +//=========================================================================== +static BOOL ProcessFile (LPCTSTR filename, + PROCESSINGPTR processing, + CMDDEFPTR *nextarg, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback) { + + // OPEN THE FILE + HANDLE file = CreateFile(filename, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + NULL); + if (!file) { + if (errorcallback) + GenerateError(errorcallback,SCMD_ERROR_OPEN_FAILED,filename); + return FALSE; + } + + // READ IT INTO MEMORY + DWORD size = GetFileSize(file,NULL); + LPVOID buffer = ALLOC(size+1); + DWORD bytesread; + ReadFile(file,buffer,size,&bytesread,NULL); + CloseHandle(file); + + // NULL TERMINATE THE ENTIRE FILE + *((LPBYTE)buffer+bytesread) = 0; + + // PROCESS IT AS ONE LARGE STRING + LPCTSTR curr = (LPCTSTR)buffer; + BOOL success = ProcessString(&curr, + processing, + nextarg, + extracallback, + errorcallback); + + // FREE THE BUFFER + FREE(buffer); + + return success; +} + +//=========================================================================== +static BOOL ProcessFlags (LPCTSTR string, + PROCESSINGPTR processing, + SCMDERRORCALLBACK errorcallback) { + char lastflag[256] = ""; + while (*string) { + + // FIND THE BEST MATCHED FLAG DEFINITION, COMBINING THIS FLAG WITH THE + // HEADER CHARACTERS FROM THE LAST FLAG IN THIS TOKEN IF POSSIBLE + int strlength = SStrLen(string); + int lastflaglength = max(1,SStrLen(lastflag)); + CMDDEFPTR ptr = NULL; + while (lastflaglength--) + if (strlength+lastflaglength < 256) { + SStrCopy(lastflag+lastflaglength,string,256); + if ((ptr = FindFlagDef(lastflag,s_flaglist.Head(),0)) != NULL) { + lastflaglength = ptr->namelength; + lastflag[lastflaglength] = 0; + break; + } + } + if (!ptr) { + if (errorcallback) + GenerateError(errorcallback,SCMD_ERROR_BAD_ARGUMENT,string); + return FALSE; + } + + // MOVE THE STRING POINTER PAST THE FLAG NAME + string += lastflaglength; + + // SETUP THE PROCESSING STRUCTURE + processing->ptr = ptr; + processing->namelength = lastflaglength; + SStrCopy(processing->name,lastflag); + + // IF THERE IS NO DATA PAST THE FLAG NAME AND THIS IS A NON-BOOLEAN + // FLAG, DELAY PROCESSING UNTIL WE GET THE DATA FROM THE NEXT TOKEN + if ((!*string) && + (TYPEVAL(ptr->flags) != SCMD_TYPE_BOOL)) + return TRUE; + + // PROCESS ALL INSTANCES OF THE BEST MATCHED FLAG + int datachars; + if (!ProcessCurrentFlag(string,processing,&datachars)) + return FALSE; + + // MOVE THE STRING POINTER PAST THE FLAG DATA + string += datachars; + + } + return TRUE; +} + +//=========================================================================== +static BOOL ProcessString (LPCTSTR *stringptr, + PROCESSINGPTR processing, + CMDDEFPTR *nextarg, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback) { + + // PROCESS EACH TOKEN IN THE STRING + while (**stringptr) { + LPCTSTR nextptr = *stringptr; + char buffer[256] = ""; + BOOL quoted = FALSE; + SStrTokenize(&nextptr, + buffer, + 256, + WHITESPACE, + "ed); + if (!ProcessToken(buffer, + quoted, + processing, + nextarg, + extracallback, + errorcallback)) + break; + *stringptr = nextptr; + } + + // RETURN SUCCESS IF WE PROCESSED THE ENTIRE STRING + return !**stringptr; + +} + +//=========================================================================== +static BOOL ProcessToken (LPCTSTR string, + BOOL quoted, + PROCESSINGPTR processing, + CMDDEFPTR *nextarg, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback) { + + // IF THIS IS A RESPONSE FILE, PROCESS IT RECURSIVELY + if ((*string == '@') && !quoted) + return ProcessFile(string+1, + processing, + nextarg, + extracallback, + errorcallback); + + // IF THIS TOKEN CONTAINS FLAGS, PROCESS THEM + if (SStrChr(FLAGCHARS,*string) && !quoted) { + processing->ptr = NULL; + return ProcessFlags(string+1,processing,errorcallback); + } + + // IF WE ARE STILL PROCESSING A PREVIOUS ARGUMENT, USE THIS TOKEN + // AS DATA FOR THAT ARGUMENT + if (processing->ptr) { + int datachars; + return ProcessCurrentFlag(string,processing,&datachars); + } + + // IF THERE ARE ADDITIONAL REQUIRED/OPTIONAL ARGUMENTS TO FILL, + // USE THIS TOKEN AS ONE + if (*nextarg) { + int datachars; + if (!PerformConversion(*nextarg,string,&datachars)) + return FALSE; + *nextarg = (*nextarg)->Next(); + return TRUE; + } + + // IF THERE IS AN EXTRA CALLBACK DEFINED, PASS THIS TOKEN TO THE + // EXTRA CALLBACK + if (extracallback) + return extracallback(string); + + // OTHERWISE, DISPLAY AN ERROR AND RETURN FALSE TO STOP THE COMMAND + // LINE PARSING BECAUSE WE ARE UNABLE TO IDENTIFY OR PROCESS THE TOKEN + if (errorcallback) + GenerateError(errorcallback,SCMD_ERROR_BAD_ARGUMENT,string); + return FALSE; + +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SCmdCheckId (DWORD id) { + for (BOOL flaglist = FALSE; flaglist <= TRUE; ++flaglist) + ITERATELIST(CMDDEF, + flaglist ? s_flaglist : s_arglist, + currptr) + if (currptr->id == id) + return currptr->found; + return FALSE; +} + +//=========================================================================== +BOOL APIENTRY SCmdDestroy () { + for (BOOL flaglist = FALSE; flaglist <= TRUE; ++flaglist) + ITERATELIST(CMDDEF, + flaglist ? s_flaglist : s_arglist, + currptr) + if ((TYPEVAL(currptr->flags) == SCMD_TYPE_STRING) && + currptr->currvaluestr) { + FREE(currptr->currvaluestr); + currptr->currvaluestr = NULL; + } + s_arglist.Clear(); + s_flaglist.Clear(); + s_addedoptional = FALSE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCmdGetBool (DWORD id) { + return (SCmdGetNum(id) != 0); +} + +//=========================================================================== +DWORD APIENTRY SCmdGetNum (DWORD id) { + for (BOOL flaglist = FALSE; flaglist <= TRUE; ++flaglist) + ITERATELIST(CMDDEF, + flaglist ? s_flaglist : s_arglist, + currptr) + if (currptr->id == id) + return currptr->currvalue; + return 0; +} + +//=========================================================================== +BOOL APIENTRY SCmdGetString (DWORD id, + LPTSTR buffer, + DWORD bufferchars) { + if (buffer) + *buffer = 0; + + VALIDATEBEGIN; + VALIDATE(buffer); + VALIDATE(bufferchars); + VALIDATEEND; + + for (BOOL flaglist = FALSE; flaglist <= TRUE; ++flaglist) + ITERATELIST(CMDDEF, + flaglist ? s_flaglist : s_arglist, + currptr) + if (currptr->id == id) { + if (currptr->currvaluestr) + SStrCopy(buffer,currptr->currvaluestr,bufferchars); + return TRUE; + } + return FALSE; +} + +//=========================================================================== +BOOL APIENTRY SCmdProcess (LPCTSTR cmdline, + BOOL skipprogname, + SCMDEXTRACALLBACK extracallback, + SCMDERRORCALLBACK errorcallback) { + VALIDATEBEGIN; + VALIDATE(cmdline); + VALIDATEEND; + + // IF REQUESTED, SKIP PAST THE PROGRAM NAME AT THE START OF THE COMMAND + // LINE + if (skipprogname) + SStrTokenize(&cmdline, + NULL, + 0, + WHITESPACE, + NULL); + + // PROCESS EACH ARGUMENT + PROCESSING processing; + ZeroMemory(&processing,sizeof(PROCESSING)); + CMDDEFPTR nextarg = s_arglist.Head(); + if (!ProcessString(&cmdline, + &processing, + &nextarg, + extracallback, + errorcallback)) + return FALSE; + + // DETERMINE WHETHER ALL REQUIRED ARGUMENTS WERE FILLED IN + BOOL allfilled = TRUE; + while (nextarg && allfilled) + if (ARGVAL(nextarg->flags) == SCMD_ARG_REQUIRED) + allfilled = FALSE; + else + nextarg = nextarg->Next(); + if (errorcallback && !allfilled) + GenerateError(errorcallback,SCMD_ERROR_NOT_ENOUGH_ARGUMENTS,""); + + return allfilled; +} + +//=========================================================================== +BOOL APIENTRY SCmdRegisterArgList (const ARGLIST *listptr, + DWORD numargs) { + VALIDATEBEGIN; + VALIDATE(listptr); + VALIDATEEND; + + for (DWORD loop = 0; loop < numargs; ++loop) { + if (!SCmdRegisterArgument(listptr->flags, + listptr->id, + listptr->name, + NULL, + 0, + TRUE, + 0xFFFFFFFF, + listptr->callback)) + return FALSE; + ++listptr; + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCmdRegisterArgument (DWORD flags, + DWORD id, + LPCTSTR name, + LPVOID variableptr, + DWORD variablebytes, + DWORD setvalue, + DWORD setmask, + SCMDCALLBACK callback) { + if (!name) + name = ""; + int namelength = SStrLen(name); + + VALIDATEBEGIN; + VALIDATE(namelength < MAXNAMELENGTH); + VALIDATE((!variablebytes) || variableptr); + VALIDATE((ARGVAL(flags) != SCMD_ARG_REQUIRED) || (!s_addedoptional)); + VALIDATE((ARGVAL(flags) != SCMD_ARG_FLAGGED) || (namelength > 0)); + VALIDATE((TYPEVAL(flags) != SCMD_TYPE_BOOL) || (!variableptr) || (variablebytes == sizeof(DWORD))); + VALIDATEEND; + + // ADD THE ARGUMENT TO THE END OF THE APPROPRIATE LINKED LIST + CMDDEFPTR newptr; + if (ARGVAL(flags) == SCMD_ARG_FLAGGED) + newptr = s_flaglist.NewNode(); + else + newptr = s_arglist.NewNode(); + SStrCopy(newptr->name,name,MAXNAMELENGTH); + newptr->id = id; + newptr->namelength = namelength; + newptr->flags = flags; + newptr->variableptr = variableptr; + newptr->variablebytes = variablebytes; + newptr->setvalue = setvalue; + newptr->setmask = setmask; + newptr->callback = callback; + + // SET THE INITIAL VALUE + if ((TYPEVAL(flags) == SCMD_TYPE_BOOL) && + (BOOLVAL(flags) == SCMD_BOOL_CLEAR)) + newptr->currvalue = setvalue; + else + newptr->currvalue = 0; + + // IF THIS IS AN OPTIONAL ARGUMENT, KEEP TRACK OF THE FACT THAT WE'VE + // ADDED AT LEAST ONE OPTIONAL ARGUMENT SO THAT WE WILL REFUSE TO ADD + // ANY MORE REQUIRED ARGUMENTS IN THE FUTURE + if (ARGVAL(flags) == SCMD_ARG_OPTIONAL) + s_addedoptional = TRUE; + + return TRUE; +} diff --git a/Storm/SOURCE/SCODE.CPP b/Storm/SOURCE/SCODE.CPP new file mode 100644 index 0000000..ab8d3b5 --- /dev/null +++ b/Storm/SOURCE/SCODE.CPP @@ -0,0 +1,1312 @@ +/**************************************************************************** +* +* SCODE.CPP +* Storm S-Code compiler +* +* By Michael O'Brien (4/8/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define BUFFERSIZE 1024 + +#define EQUALITY "=" +#define OPERATIONS "&|^+-" +#define LOGICALOPS "&|^+-" +#define PORTIONS "1234" +#define REGISTERS "WSDTABC01" +#define INDEXREGS "WABC" +#define SIZES "124" + +#define REG_UNDEF 0 +#define REG_WORK 1 +#define REG_DEST 2 +#define REG_SOURCE 3 +#define REG_TABLE 4 +#define REG_A 5 +#define REG_B 6 +#define REG_C 7 +#define REG_CONST0 8 +#define REG_CONST1 9 +#define NUMREGS 10 + +#define OP_MOVE 0 +#define OP_AND 1 +#define OP_OR 2 +#define OP_XOR 3 +#define OP_ADD 4 +#define OP_SUB 5 +#define OP_NOT 6 +#define OP_SWAP 7 +#define NUMOPS 8 + +#define USE_UNUSED 0 +#define USE_INTER 1 +#define USE_CONST 2 +#define USE_POINTER 3 +#define USE_CACHE 4 + +#define CACHE_DEST 0 +#define CACHE_SOURCE 1 +#define CACHE_TABLE 2 +#define CACHE_CONST0 3 +#define CACHE_CONST1 4 +#define NUMCACHE 5 + +#define CHARTOID(c) (SStrChr(regidtable,(c))-regidtable) +#define COMPAREREGS(a,b) (*(LPDWORD)&(a) == *(LPDWORD)&(b)) +#define COPYREG(d,s) (*(LPDWORD)&(d) = *(LPDWORD)&(s)) +#define FATALERROR(c) do { \ + if (firsterror) \ + *firsterror = (c); \ + ClearQueue(); \ + return 0; \ + } while (0) +#define IDTOCHAR(i) regidtable[i] +#define OPTOID(c) (SStrChr(opidtable,(c))-opidtable) +#define ZEROREG(r) *(LPDWORD)&(r) = 0 + +typedef struct _BUF { + LPBYTE data; + DWORD bytes; +} BUF, *BUFPTR; + +typedef struct _REG { + BYTE id; + BYTE portion; + BYTE indexid; + BYTE indirect; +} REG, *REGPTR; + +NODEDECL(INST) { + REG dest; + REG source; + int op; + int opsize; +} *INSTPTR; + +NODEDECL(STREAM) { + BOOL flags; + DWORD checkvalue; + LPBYTE executeptr; + LPBYTE prologstreambase; + DWORD prologbytes; + LPBYTE prologstreamexec[4]; + LPBYTE epilogstreambase; + DWORD epilogbytes; + LPBYTE epilogstreamexec[4]; + LPBYTE loopstreambase; + DWORD loopbytes; + LPBYTE loopstreamexec[1]; +} *STREAMPTR; + +static BUF s_codebuf = {NULL,0}; +static LIST(INST) s_instlist; +static REG s_nullreg = {0,0,0,0}; +static BUF s_retbuf = {NULL,0}; +static LIST(STREAM) s_streamlist; + +/**************************************************************************** +* +* INTEL X86 CODE GENERATOR +* +***/ + +static const BYTE s_intelx86opencodetable[NUMOPS][3][2] = + {{{0x8B,0},{0x89,0},{0xC7,0}}, // = + {{0x23,0},{0x21,0},{0x81,4}}, // & + {{0x0B,0},{0x09,0},{0x81,1}}, // | + {{0x33,0},{0x31,0},{0x81,6}}, // ^ + {{0x03,0},{0x01,0},{0x81,0}}, // + + {{0x2B,0},{0x29,0},{0x81,5}}, // - + {{0xF7,2},{0xF7,2},{0xF7,2}}, // ~ + {{0xC1,1},{0xC1,1},{0xC1,1}}};// @ +static const BYTE s_intelx86regencodetable32[NUMREGS] = + {4,0,7,6,5,1,2,3,0,0}; +static const BYTE s_intelx86regencodetable8[NUMREGS][2] = + {{0,0},{0,4},{0,0},{0,0},{0,0}, + {1,5},{2,6},{3,7},{0,0},{0,0}}; + +//=========================================================================== +static LPBYTE IntelX86GenerateCode (LPBYTE dest, INSTPTR inst) { + + // PERFORM SPECIAL PROCESSING FOR INCREMENT INSTRUCTIONS + if ((inst->op == OP_ADD) && !inst->source.id) { + *dest++ = (inst->opsize > 1) ? 0x81 : 0xFF; + *dest++ = 0xC0 | s_intelx86regencodetable32[inst->dest.id]; + if (inst->opsize > 1) { + *(LPDWORD)dest = inst->opsize; + dest += sizeof(DWORD); + } + return dest; + } + + // REPLACE "R=0" WITH "R^=R", WHICH IS FEWER BYTES IN THE INTEL ARCHITECTURE + if ((inst->op == OP_MOVE) && + (inst->dest.id == REG_CONST0) && + (!inst->source.indirect) && + (!inst->source.indexid)) { + inst->op = OP_XOR; + COPYREG(inst->dest,s_nullreg); + } + + // DETERMINE THE INSTRUCTION ENCODING + int operandtype = 0; + if ((inst->source.id == REG_CONST0) || + (inst->source.id == REG_CONST1) || + !inst->source.id) + operandtype = 2; + else if (inst->dest.indirect || inst->dest.indexid) + operandtype = 1; + BYTE instenc = s_intelx86opencodetable[inst->op][operandtype][0]; + BYTE instreg = s_intelx86opencodetable[inst->op][operandtype][1]; + if (inst->opsize == 1) + instenc &= 0xFE; + + // DETERMINE THE VALUES OF THE MODR/M AND SIB BYTES + BYTE modrm = 0; + BYTE sib = 0; + BOOL usesib = 0; + { + REGPTR simplereg = operandtype ? &inst->source : &inst->dest; + REGPTR complexreg = operandtype ? &inst->dest : &inst->source; + if (complexreg->indirect && (!complexreg->indexid) && + ((complexreg->id == REG_SOURCE) || (complexreg->id == REG_DEST))) + modrm = s_intelx86regencodetable32[complexreg->id]; + else if (complexreg->indirect || complexreg->indexid) { + modrm = 4; + usesib = 1; + if (complexreg->id == REG_TABLE) + if (complexreg->indexid) + sib = s_intelx86regencodetable32[complexreg->indexid] + | (s_intelx86regencodetable32[REG_TABLE] << 3); + else + modrm = 0x45; + else + sib = s_intelx86regencodetable32[complexreg->id] + | (s_intelx86regencodetable32[complexreg->indexid] << 3); + } + else + modrm = 0xC0 | (complexreg->portion + ? s_intelx86regencodetable8[complexreg->id][complexreg->portion-1] + : s_intelx86regencodetable32[complexreg->id]); + if ((operandtype == 2) || instreg) + modrm |= (instreg << 3); + else + modrm |= simplereg->portion + ? (s_intelx86regencodetable8[simplereg->id][simplereg->portion-1] << 3) + : (s_intelx86regencodetable32[simplereg->id] << 3); + } + + // WRITE A SIZE OVERRIDE PREFIX IF WE ARE DEALING WITH TWO-BYTE DATA + if (inst->opsize == 2) + *dest++ = 0x66; + + // WRITE THE OPCODE, MODR/M BYTE, AND THE SIB BYTE IF NECESSARY + *dest++ = instenc; + *dest++ = modrm; + if (usesib) + *dest++ = sib; + + // WRITE A CONSTANT IF NECESSARY + if (inst->op == OP_SWAP) + *dest++ = 16; + else if ((inst->source.id == REG_CONST0) || (inst->source.id == REG_CONST1)) { + *(LPDWORD)dest = (inst->source.id == REG_CONST1) ? 0xFFFFFFFF : 0; + dest += inst->opsize; + } + + return dest; +} + +//=========================================================================== +static LPBYTE IntelX86GenerateReturn (LPBYTE dest) { + + // ON INTEL PROCESSORS, WE USE A JUMP INSTEAD OF A RETURN, AND FILL IN + // THE JUMP TARGET AT EXECUTE TIME + *dest++ = 0xE9; + *(LPDWORD)dest = 0; + dest += sizeof(DWORD); + + return dest; +} + +/**************************************************************************** +* +* TEXT CODE GENERATOR +* +***/ + +static const LPSTR s_textopencodetable[NUMOPS] = + {"move ","and ","or ","xor ", + "add ","sub ","not ","ror "}; +static const char s_textregencodetable[NUMREGS+1] = + "?wdstabc01"; + +//=========================================================================== +static LPBYTE TextGenerateCode (LPBYTE dest, INSTPTR inst) { + + // PERFORM SPECIAL PROCESSING FOR INCREMENT INSTRUCTIONS + if ((inst->op == OP_ADD) && !inst->source.id) { + wsprintf((LPSTR)dest, + "inc %c,%u\n", + s_textregencodetable[inst->dest.id], + inst->opsize); + return dest+SStrLen((LPSTR)dest); + } + + // ADD THE INSTRUCTION TEXT + dest += SStrCopy((LPSTR)dest,s_textopencodetable[inst->op]); + + // ADD THE TEXT FOR EACH REGISTER + for (int regnum = 1; regnum >= 0; --regnum) { + REGPTR reg = regnum ? &inst->dest : &inst->source; + if (reg->id) { + if (!regnum) + *dest++ = ','; + if (reg->indirect || reg->indexid) + *dest++ = '['; + + // ADD THE REGISTER BASE NAME + if (reg->id == REG_CONST1) { + switch (inst->opsize) { + case 1: dest += SStrCopy((LPSTR)dest,"0FFh"); break; + case 2: dest += SStrCopy((LPSTR)dest,"0FFFFh"); break; + case 4: dest += SStrCopy((LPSTR)dest,"0FFFFFFFFh"); break; + } + } + else + *dest++ = s_textregencodetable[reg->id]; + + // ADD THE PORTION IDENTIFIER + if ((inst->opsize < 4) && !(reg->indirect || reg->indexid)) + if (inst->opsize == 2) + *dest++ = 'x'; + else + *dest++ = (reg->portion == 1) ? 'l' : 'h'; + + // ADD THE INDEX REGISTER NAME + if (reg->indexid) { + *dest++ = '+'; + *dest++ = s_textregencodetable[reg->indexid]; + } + + if (reg->indirect || reg->indexid) + *dest++ = ']'; + } + } + + *dest++ = '\n'; + return dest; +} + +//=========================================================================== +static LPBYTE TextGenerateReturn (LPBYTE dest) { + return dest+SStrCopy((LPSTR)dest,"ret\n"); +} + +/**************************************************************************** +* +* COMPILER FRONT-END (PLATFORM INDEPENDENT) +* +***/ + +static const char cacheidtable[] = "DST01"; +static const char regidtable[] = " WDSTABC01"; +static const char opidtable[] = "=&|^+-~@"; + +static inline BOOL IsRegisterUsed (LPCSTR codestring, BYTE regnum, BOOL singleequation); +static void QueueInstruction (int opsize, REG dest, REG operand1, REG operand2, char operation); + +//=========================================================================== +static void ClearQueue () { + s_instlist.Clear(); +} + +//=========================================================================== +static int FindLargestUnindexedAccess (BYTE regid) { + int result = 0; + ITERATELIST(INST,s_instlist,curr) + if ((((curr->dest.id == regid) && + (!curr->dest.indexid) && + (curr->dest.indirect)) || + ((curr->source.id == regid) && + (!curr->source.indexid) && + (curr->source.indirect))) && + (curr->opsize > result)) + result = curr->opsize; + return result; +} + +//=========================================================================== +static BOOL GenerateCode (LPCSTR codestring, LPCSTR *firsterror, BOOL pseudocode) { + if (firsterror) + *firsterror = NULL; + + VALIDATEBEGIN; + VALIDATE(codestring); + VALIDATEEND; + + // VERIFY THAT THE CODE STRING IS IN A VALID FORMAT + if (SStrLen(codestring) < 3) + FATALERROR(codestring); + + // DETERMINE HOW EACH REGISTER IS USED IN THIS CODE STRING. A REGISTER + // MAY NOT BE USED AT ALL, OR IT MAY BE USED IN ONE OF THE FOLLOWING + // FOUR WAYS: + // 1. TO STORE INTERMEDIATE RESULTS (EX: A=S D=A) + // 2. TO STORE A CONSTANT VALUE (EX: D=S^A) + // 3. TO STORE A VALUE THAT IS USED AND MODIFIED IN EACH ITERATION OF + // THE LOOP (EX: A=A+B D=A) + // 4. TO STORE A POINTER (EX: D=S) + // THE SECOND AND THIRD CASES ARE TREATED THE SAME, BECAUSE THEY BOTH + // COMPLETELY PREVENT US FROM USING THE REGISTER AS A WORK REGISTER. + // WE IDENTIFY THESE CASES BY LOOKING FOR REGISTERS THAT ARE USED WITHOUT + // PREVIOUSLY HAVING BEEN SET. + int reguse[NUMREGS]; + { + for (int loop = 1; loop < NUMREGS; ++loop) { + BOOL foundany = FALSE; + BOOL foundpermanent = FALSE; + { + BOOL set = FALSE; + BOOL seteeq = FALSE; + LPCSTR curr = codestring; + while (*curr) { + if (*curr == regidtable[loop]) + if ((*(curr+1) == '=') || + (*(curr+1) && SStrChr(PORTIONS,*(curr+1)) && (*(curr+2) == '='))) { + foundany = TRUE; + seteeq = TRUE; + } + else { + foundany = TRUE; + if (!set) + foundpermanent = TRUE; + } + if (*curr == ' ') { + set = seteeq; + seteeq = FALSE; + } + ++curr; + } + } + switch (loop) { + + case REG_WORK: + reguse[loop] = USE_INTER; + break; + + case REG_SOURCE: + case REG_DEST: + case REG_TABLE: + reguse[loop] = foundany ? USE_POINTER : USE_UNUSED; + break; + + case REG_CONST0: + case REG_CONST1: + reguse[loop] = USE_CONST; + break; + + default: + reguse[loop] = foundany ? foundpermanent ? USE_CONST + : USE_INTER + : USE_UNUSED; + break; + + } + } + } + + // START TRAVERSING THE CODE STRING FROM LEFT TO RIGHT + ClearQueue(); + BYTE cache[NUMCACHE] = {0,0,0,0,0}; + LPCSTR curr = codestring; + REG destreg = {0,0,0,0}; + REG holdreg = {0,0,0,0}; + char holdop = 0; + int opsize = 4; + do { + + // IF WE HIT A SIZE CHARACTER, CHANGE THE CURRENT OPERATION SIZE + if ((*curr) && + ((curr == codestring) || (*(curr-1) == ' ')) && + SStrChr(SIZES,*curr)) + opsize = (*curr)-'0'; + + // IF WE HIT AN OPERATOR, SAVE IT AS THE NEXT OPERATION + else if ((*curr) && SStrChr(OPERATIONS,*curr)) + holdop = *curr; + + // IF WE HIT A REGISTER NAME, THEN PROCESS ANY BYTE MODIFIERS AND + // INDEXES, AND THEN: + // 1. SAVE IT AS THE DESTINATION REGISTER + // 2. SAVE IT AS THE SOURCE REGISTER FOR THE NEXT OPERATION, OR + // 3. PERFORM THE CURRENT OPERATION AND SAVE THE RESULT AS THE SOURCE + // REGISTER FOR THE NEXT OPERATION + // IF WE HIT WHITESPACE, THEN PERFORM A SPECIAL CASE OPERATION TO + // STORE THE RESULT. + else if ((!*curr) || (*curr == ' ') || + SStrChr(REGISTERS,*curr)) { + + // DECODE THE REGISTER, PORTION IDENTIFIERS, AND INDEX REGISTERS + BOOL retire = ((!*curr) || (*curr == ' ')); + REG reg = {0,0,0,0}; + if (!retire) { + reg.id = CHARTOID(*curr); + reg.indirect = (reguse[reg.id] == USE_POINTER); + BOOL again; + do { + again = FALSE; + if ((*(curr+1)) && SStrChr(INDEXREGS,*(curr+1))) { + reg.indexid = CHARTOID(*(curr+1)); + ++curr; + again = TRUE; + } + if ((*(curr+1)) && SStrChr(PORTIONS,*(curr+1))) { + reg.portion = *(curr+1)-'0'; + ++curr; + again = TRUE; + } + if (again && ((reg.id == REG_CONST0) || (reg.id == REG_CONST1))) + FATALERROR(curr); + } while (again); + } + + // IF WE DON'T YET HAVE A DESTINATION REGISTER OR A SOURCE REGISTER + // FOR THE NEXT OPERATION, SAVE THIS REGISTER + if (!destreg.id) + if (*(curr+1) == '=') + if ((reg.id == REG_CONST0) || (reg.id == REG_CONST1)) + FATALERROR(curr); + else { + ++curr; + COPYREG(destreg,reg); + ZEROREG(holdreg); + holdop = 0; + } + else { + if (!retire) + FATALERROR(curr+1); + } + else if (!holdreg.id) { + COPYREG(holdreg,reg); + holdop = 0; + } + + // OTHERWISE, PERFORM THE SAVED OPERATION + else { + + // IF EITHER THE SOURCE REGISTER OR DESTINATION REGISTER IS USED AS + // AN OPERAND, FIND A PLACE TO STORE THE RESULT OF THE INDIRECTION. + // SIMILARLY, IF A CONSTANT VALUE IS USED IN ANYTHING BUT A SIMPLE + // LOGICAL OPERATION, FIND A PLACE TO STORE THE VALUE. + // CACHE THE RESULT IF THERE IS A FREE REGISTER, THE VALUE WILL BE + // USED AGAIN, AND THERE IS NO INDEXING INVOLVED. + if ((!retire) || (reguse[destreg.id] == USE_POINTER)) { + for (int operandnum = 0; operandnum <= 1; ++operandnum) + for (int regnum = 0; regnum <= 3; ++regnum) { + REG *regptr = operandnum ? ® : &holdreg; + BYTE *cacheptr = &cache[regnum]; + int checkid; + int checkuse; + switch (regnum) { + case CACHE_DEST: checkid = REG_DEST; checkuse = USE_POINTER; break; + case CACHE_SOURCE: checkid = REG_SOURCE; checkuse = USE_POINTER; break; + case CACHE_TABLE: checkid = REG_TABLE; checkuse = USE_POINTER; break; + case CACHE_CONST0: checkid = REG_CONST0; checkuse = USE_CONST; break; + case CACHE_CONST1: checkid = REG_CONST1; checkuse = USE_CONST; break; + } + if ((regptr->id == checkid) && + (reguse[checkid] == checkuse) && + ((regnum == CACHE_DEST) || + (regnum == CACHE_SOURCE) || + (regnum == CACHE_TABLE) || + (!holdop) || + (!SStrChr(LOGICALOPS,holdop)))) + + // IF THIS VALUE IS ALREADY CACHED, USE THAT + if ((*cacheptr) && (!regptr->indexid)) { + regptr->id = *cacheptr; + regptr->indirect = 0; + } + else { + + // OTHERWISE, DETERMINE WHETHER WE WANT TO CACHE IT, BASED + // ON WHETHER IT IS USED AGAIN AND WHETHER AN INDEX IS + // BEING APPLIED + BOOL wanttocache = IsRegisterUsed(curr+1,checkid,0) + && !regptr->indexid; + + // IF WE DO WANT TO CACHE IT, FIND A PLACE TO DO SO + BYTE found = 0; + if (wanttocache || (holdreg.id == REG_WORK)) { + BYTE loop; + + // LOOK FOR UNUSED REGISTERS, OR REGISTERS USED FOR + // INTERMEDIATE VALUES WHICH WON'T BE USED AGAIN + for (loop = NUMREGS-1; loop >= 1; --loop) + if ((loop != REG_WORK) && + ((reguse[loop] == USE_UNUSED) || + ((reguse[loop] == USE_INTER) && + (!SStrChr(curr,regidtable[loop]))))) { + found = loop; + break; + } + + // LOOK FOR REGISTERS USED FOR CACHING VALUES THAT + // NO LONGER NEED TO BE CACHED + if (!found) + for (loop = NUMREGS-1; loop >= 1; --loop) + if (reguse[loop] == USE_CACHE) { + BYTE findreg = 0; + for (int loop2 = 0; loop2 < NUMCACHE; ++loop2) + if (cache[loop2] == loop) + findreg = CHARTOID(cacheidtable[loop2]); + if (findreg) + found = IsRegisterUsed(curr,findreg,0) ? 0 : loop; + } + + } + + // IF WE DON'T WANT TO CACHE IT OR COULDN'T FIND A PLACE, + // PUT THE VALUE IN EITHER THE DESTINATION REGISTER OR + // THE WORK REGISTER + if (!found) + if (destreg.id && + (!destreg.indexid) && + (!destreg.portion) && + (!destreg.indirect) && + (reguse[destreg.id] == USE_INTER) && + (holdreg.id != destreg.id) && + !IsRegisterUsed(curr,destreg.id,1)) + found = destreg.id; + else if (holdreg.id != REG_WORK) + found = REG_WORK; + else + FATALERROR(curr); + + // ADD AN INSTRUCTION TO MOVE THE VALUE INTO THE CACHE OR + // WORK REGISTER + REG storereg = {found,0,0,0}; + QueueInstruction(opsize,storereg,*regptr,s_nullreg,0); + + // SAVE THE NEW LOCATION OF THE VALUE + if (wanttocache && (found != REG_WORK)) { + *cacheptr = found; + reguse[*cacheptr] = USE_CACHE; + } + COPYREG(*regptr,storereg); + + } + } + } + + // DETERMINE WHETHER ONE OF THE OPERANDS OR THE DESTINATION REGISTER + // CAN BE USED FOR THE RESULT OF THE OPERATION. IF NOT, WE WILL USE + // THE WORK REGISTER FOR THE RESULT. + REG resultreg = {REG_WORK,0,0,0}; + if (retire) { + COPYREG(resultreg,destreg); + ZEROREG(destreg); + } + else { + + // THE DESTINATION REGISTER CAN BE USED FOR THE RESULT IF IT IS + // NOT USED AGAIN IN THIS EQUATION, AND IT IS NOT A POINTER + if ((!IsRegisterUsed(curr+1,destreg.id,1)) && + (reguse[destreg.id] != USE_POINTER) && + !(destreg.indexid || destreg.indirect)) + COPYREG(resultreg,destreg); + + // OTHERWISE, IF ONE OF THE OPERANDS IS THE WORK REGISTER, WE + // CAN USE THAT FOR THE RESULT + else if ((holdreg.id == REG_WORK) && !(holdreg.indexid || holdreg.indirect)) + COPYREG(resultreg,holdreg); + else if ((reg.id == REG_WORK) && !(reg.indexid || reg.indirect)) + COPYREG(resultreg,reg); + + // OTHERWISE, WE CAN STILL USE ONE OF THE OPERANDS IF WE CAN FIND + // ONE THAT IS NOT A POINTER, IS NOT USED AGAIN, AND IS USED ONLY + // FOR INTERMEDIATE RESULTS OR AS A CACHE + else { + for (int operand = 0; operand <= 1; ++operand) { + REG *regptr = operand ? ® : &holdreg; + if ((!(regptr->indexid || regptr->indirect)) && + ((reguse[regptr->id] == USE_INTER) || + (reguse[regptr->id] == USE_CACHE))) { + char findreg = regptr->id; + if (reguse[regptr->id] == USE_CACHE) { + for (int loop = 0; loop < NUMCACHE; ++loop) + if (cache[loop] == regptr->id) + findreg = CHARTOID(cacheidtable[loop]); + } + if (!IsRegisterUsed(curr+1,findreg,0)) + COPYREG(resultreg,*regptr); + } + } + } + + } + + // ENCODE THE OPERATION + if (retire) { + if ((resultreg.id != holdreg.id) || + (resultreg.portion != holdreg.portion)) + QueueInstruction(opsize,resultreg,holdreg,s_nullreg,0); + } + else + QueueInstruction(opsize,resultreg,holdreg,reg,holdop); + + // SAVE THE RESULT REGISTER FOR USE BY THE NEXT OPERATION + if (retire) + ZEROREG(holdreg); + else + COPYREG(holdreg,resultreg); + holdop = 0; + + } + + } + + // IF WE DIDN'T HIT ANY OF THE ABOVE, THEN REPORT AN ERROR IN THE + // CODE STRING + else + FATALERROR(curr); + + } while (*curr++); + if (s_instlist.IsEmpty()) + return FALSE; + + // SEARCH THE QUEUE FOR THE LARGEST UNINDEXED READ OR WRITE WE DID FOR EACH + // OF THE POINTERS, THEN INCREMENT THE POINTER BY THAT AMOUNT + { + int largestsource = FindLargestUnindexedAccess(REG_SOURCE); + int largesttable = FindLargestUnindexedAccess(REG_TABLE); + int largestdest = FindLargestUnindexedAccess(REG_DEST); + REG reg = {0,0,0,0}; + if (largestsource) { + reg.id = REG_SOURCE; + QueueInstruction(largestsource,reg,s_nullreg,s_nullreg,'+'); + } + if (largesttable) { + reg.id = REG_TABLE; + QueueInstruction(largesttable,reg,s_nullreg,s_nullreg,'+'); + } + if (largestdest) { + reg.id = REG_DEST; + QueueInstruction(largestdest,reg,s_nullreg,s_nullreg,'+'); + } + } + + // ADD ROTATE INSTRUCTIONS AS NECESSARY TO ELIMINATE ACCESSES TO + // INVIDIDUAL BYTES IN THE HIGH WORDS OF REGISTERS + { + ITERATELIST(INST,s_instlist,curr) + for (int operandnum = 0; operandnum <= 1; ++operandnum) { + REGPTR currreg = operandnum ? &curr->dest : &curr->source; + REGPTR otherreg = operandnum ? &curr->source : &curr->dest; + if (currreg->portion > 2) + if ((currreg->id == otherreg->indexid) || + ((currreg->id == otherreg->id) && (otherreg->portion <= 2))) + FATALERROR(codestring+SStrLen(codestring)); + else { + REG destreg = {currreg->id,0,0,0}; + for (BOOL after = FALSE; after <= TRUE; ++after) { + INSTPTR inst = s_instlist.NewNode(LIST_UNLINKED); + COPYREG(inst->dest,destreg); + COPYREG(inst->source,s_nullreg); + inst->op = OP_SWAP; + inst->opsize = 4; + s_instlist.LinkNode(inst, + after ? LIST_LINK_AFTER + : LIST_LINK_BEFORE, + curr); + } + currreg->portion -= 2; + if (otherreg->id == currreg->id) + otherreg->portion -= 2; + } + } + } + + // REMOVE DUPLICATE ROTATE INSTRUCTIONS + { + ITERATELIST(INST,s_instlist,curr) + if (curr->op == OP_SWAP) + ITERATEPARTIALLIST(INST,s_instlist,curr->Next(),search) + if ((search->op == OP_SWAP) && (search->dest.id == curr->dest.id)) { + s_instlist.DeleteNode(search); + s_instlist.DeleteNode(curr); + curr = s_instlist.Head(); + break; + } + else if ((search->dest.id == curr->dest.id) || + (search->source.id == curr->dest.id) || + (search->dest.indexid == curr->dest.id) || + (search->source.indexid == curr->dest.id)) + break; + } + + // SIMPLIFY INSTRUCTIONS INVOLVING CONSTANT VALUES. SOME EXAMPLES: + // 1. "W&=1" IS REMOVED + // 2. "W&=0" IS REPLACED WITH "W=0" + // 3. "W^=1" IS REPLACED WITH "W~=" + { + ITERATELIST(INST,s_instlist,curr) { + BOOL remove = FALSE; + BOOL setto0 = FALSE; + BOOL setto1 = FALSE; + BOOL usenot = FALSE; + if (curr->source.id == REG_CONST0) + switch (curr->op) { + case OP_MOVE: setto0 = TRUE; break; + case OP_AND : setto0 = TRUE; break; + case OP_OR : remove = TRUE; break; + case OP_XOR : remove = TRUE; break; + case OP_ADD : remove = TRUE; break; + case OP_SUB : remove = TRUE; break; + } + else if (curr->source.id == REG_CONST1) + switch (curr->op) { + case OP_MOVE: remove = TRUE; break; + case OP_OR : setto1 = TRUE; break; + case OP_XOR : usenot = TRUE; break; + } + if (remove) { + ITERATE_DELETE; + } + else if (setto0 || setto1) { + curr->op = OP_MOVE; + REG sourcereg = {setto1 ? REG_CONST1 : REG_CONST0,0,0,0}; + COPYREG(curr->source,sourcereg); + } + else if (usenot) { + curr->op = OP_NOT; + COPYREG(curr->source,s_nullreg); + } + } + } + + // OPTIMIZE THE INSTRUCTION ORDERING. TO DO THIS, WE FIND PAIRS OF + // INSTRUCTIONS WHICH ARE UNPAIRABLE BECAUSE OF DATA DEPENDENCE, THEN + // LOOK FOR OTHER INSTRUCTIONS WHICH CAN BE MOVED BETWEEN THEM. + { + INSTPTR last = s_instlist.Head(); + INSTPTR curr = last->Next(); + while (curr) { + if ((curr->source.id && (curr->source.id == last->dest.id)) || + (curr->source.indexid && (curr->source.indexid == last->dest.id)) || + (curr->dest.id && (curr->dest.id == last->dest.id) && curr->op)) { + + // WE FOUND TWO UNPAIRABLE INSTRUCTIONS; NOW START SEARCHING FOR + // SOMETHING TO SPLIT THEM UP + BOOL set[NUMREGS]; ZeroMemory(set,NUMREGS*sizeof(BOOL)); + BOOL used[NUMREGS]; ZeroMemory(used,NUMREGS*sizeof(BOOL)); + ITERATEPARTIALLIST(INST,s_instlist,curr,searchcurr) { + if ((searchcurr > curr) && + ((!searchcurr->source.id) || (!set[searchcurr->source.id])) && + ((!searchcurr->source.indexid) || (!set[searchcurr->source.indexid])) && + ((!searchcurr->dest.id) || + ((!set[searchcurr->dest.id]) && + (!used[searchcurr->dest.id])))) { + + // WE FOUND AN INSTRUCTION WHICH CAN BE USED TO SPLIT THESE TWO + // INSTRUCTIONS, SO MOVE IT BETWEEN THEM + s_instlist.LinkNode(searchcurr,LIST_LINK_BEFORE,curr); + + break; + } + set[searchcurr->dest.id] = TRUE; + used[searchcurr->source.id] = TRUE; + used[searchcurr->source.indexid] = TRUE; + } + + } + last = curr; + curr = curr->Next(); + } + } + + // ALLOCATE OUTPUT BUFFERS IF THEY HAVEN'T ALREADY BEEN ALLOCATED + if (!s_codebuf.data) + s_codebuf.data = (LPBYTE)ALLOC(BUFFERSIZE); + if (!s_retbuf.data) + s_retbuf.data = (LPBYTE)ALLOC(BUFFERSIZE); + + // GET POINTERS TO THE PROCESSOR-SPECIFIC PORTION OF THE CODE GENERATOR + LPBYTE (*addinst)(LPBYTE,INSTPTR) = NULL; + LPBYTE (*addret )(LPBYTE) = NULL; + if (pseudocode) { + addinst = TextGenerateCode; + addret = TextGenerateReturn; + } + else { +#ifdef _X86_ + addinst = IntelX86GenerateCode; + addret = IntelX86GenerateReturn; +#endif + } + if (!(addinst && addret)) + FATALERROR(codestring+SStrLen(codestring)); + + // GENERATE PROCESSOR-SPECIFIC CODE INTO THE OUTPUT BUFFERS + { + LPBYTE dest = s_codebuf.data; + ITERATELIST(INST,s_instlist,curr) + dest = addinst(dest,curr); + s_codebuf.bytes = dest-s_codebuf.data; + } + { + LPBYTE dest = addret(s_retbuf.data); + s_retbuf.bytes = dest-s_retbuf.data; + } + + ClearQueue(); + return TRUE; +} + +//=========================================================================== +static inline BOOL IsRegisterUsed (LPCSTR codestring, BYTE regnum, BOOL singleequation) { + char regid = regidtable[regnum]; + for (;;) + if ((!*codestring) || ((*codestring == ' ') && singleequation)) + return FALSE; + else if ((*codestring == regid) && (*(codestring+1) != '=')) + return TRUE; + else + ++codestring; +} + +//=========================================================================== +static void QueueInstruction (int opsize, REG dest, REG operand1, REG operand2, char operation) { + + // IF THE RESULT REGISTER OR EITHER OF THE OPERANDS CONTAIN A PORTION + // IDENTIFIER, TEMPORARILY SET THE OPERATION SIZE TO A SINGLE BYTE + if (dest.portion || operand1.portion || operand2.portion) + opsize = 1; + + // IF WE ARE USING SINGLE BYTE OPERATIONS, THEN FORCE ALL NON-POINTER + // OPERANDS TO USE PORTIONS + if (opsize == 1) { + if (!(dest.portion || dest.indexid || dest.indirect)) + if ((dest.id == operand1.id) && operand1.portion) + dest.portion = operand1.portion; + else if ((dest.id == operand2.id) && operand2.portion) + dest.portion = operand2.portion; + else + dest.portion = 1; + if (!(operand1.portion || operand1.indexid || operand1.indirect)) + operand1.portion = 1; + if (operand2.id && + !(operand2.portion || operand2.indexid || operand2.indirect)) + operand2.portion = 1; + } + + // IF THERE ARE TWO OPERANDS, NORMALIZE THE INSTRUCTION SO THAT: + // 1. IF ONE OF THE OPERANDS IS THE SAME AS THE RESULT REGISTER, IT IS + // ON THE LEFT + // 2. IF ONE OF THE OPERANDS IS A CONSTANT, IT IS ON THE RIGHT + if (operand2.id && operation && + (COMPAREREGS(dest,operand2) && !COMPAREREGS(dest,operand1)) || + (((operand1.id == REG_CONST0) || (operand1.id == REG_CONST1)) && + !((operand2.id == REG_CONST0) || (operand2.id == REG_CONST1)))) { + REG temp; + COPYREG(temp,operand1); + COPYREG(operand1,operand2); + COPYREG(operand2,temp); + } + + // SIMPLIFY THE INSTRUCTION SO THAT IT CAN BE EXPRESSED AS ONE OPERATION, + // ONE RESULT OPERAND, AND ONE SOURCE OPERAND. THIS MAY INVOLVE SPLITTING + // IT INTO TWO INSTRUCTIONS. SOME EXAMPLES: + // 1. "W=W^A" BECOMES "W^=A" + // 2. "W=A^B" BECOMES "W=A" FOLLOWED BY "W^=B" + if (operand2.id && operation && + (!COMPAREREGS(dest,operand1)) && (!COMPAREREGS(dest,operand2))) { + REG nullop = {0,0,0,0}; + QueueInstruction(opsize,dest,operand1,nullop,0); + COPYREG(operand1,dest); + } + + // QUEUE THE INSTRUCTION + INSTPTR inst = s_instlist.NewNode(); + COPYREG(inst->dest ,dest); + COPYREG(inst->source,operand2.id ? operand2 : operand1); + inst->op = operation ? OPTOID(operation) : OP_MOVE; + inst->opsize = opsize; + +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SCodeCompile (LPCSTR prologstring, + LPCSTR loopstring, + LPCSTR *firsterror, + DWORD maxiterations, + DWORD flags, + HSCODESTREAM *handle) { + if (firsterror) + *firsterror = NULL; + + VALIDATEBEGIN; + VALIDATE(loopstring); + VALIDATE(*loopstring); + VALIDATE(maxiterations >= 1); + VALIDATE(handle); + VALIDATEEND; + + // CREATE NORMALIZED VERSIONS OF THE STRINGS + BOOL align = (flags & SCODE_CF_AUTOALIGNDWORD) != 0; + char localprologstring[256] = "W=0 "; + char localloopstring[256] = ""; + char *userprologstring = localprologstring; + char *userloopstring = localloopstring; + if (prologstring) + if (align) + SStrCopy(localprologstring,prologstring); + else { + userprologstring += SStrLen(localprologstring); + SStrPack(localprologstring,prologstring,256); + } + if (loopstring) + SStrCopy(localloopstring,loopstring); + if (align) { + if (localprologstring[0] == '#') + localprologstring[0] = '1'; + if (localloopstring[0] == '#') + localloopstring[0] = '4'; + } + _strupr(localprologstring); + _strupr(localloopstring); + + // CREATE A NEW CODE STREAM BUFFER + STREAMPTR stream = s_streamlist.NewNode(LIST_HEAD,maxiterations*sizeof(LPBYTE)); + stream->flags = flags; + stream->checkvalue = 0xFFFFFFFF; + + // COMPILE AND UNROLL THE PROLOG/EPILOG S-CODE STRING + { + BOOL result = GenerateCode(localprologstring,firsterror,0); + if (firsterror && *firsterror) + *firsterror = prologstring+(*firsterror-userprologstring); + if (!result) + return SCodeDelete((HSCODESTREAM)stream); + DWORD iterations = align ? 3 : 1; + stream->prologbytes = s_codebuf.bytes*iterations+s_retbuf.bytes; + stream->prologstreambase = (LPBYTE)ALLOC(stream->prologbytes); + if (align) { + stream->epilogbytes = s_codebuf.bytes*iterations+s_retbuf.bytes; + stream->epilogstreambase = (LPBYTE)ALLOC(stream->epilogbytes); + } + LPBYTE prologdest = stream->prologstreambase; + LPBYTE epilogdest = stream->epilogstreambase; + DWORD loop; + for (loop = 0; loop < iterations; ++loop) { + CopyMemory(prologdest,s_codebuf.data,s_codebuf.bytes); + prologdest += s_codebuf.bytes; + if (align) { + CopyMemory(epilogdest,s_codebuf.data,s_codebuf.bytes); + epilogdest += s_codebuf.bytes; + } + } + CopyMemory(prologdest,s_retbuf.data,s_retbuf.bytes); + if (align) { + CopyMemory(epilogdest,s_retbuf.data,s_retbuf.bytes); + for (loop = 0; loop <= iterations; ++loop) { + stream->prologstreamexec[loop] = stream->prologstreambase + +(iterations-loop)*s_codebuf.bytes; + if (align) + stream->epilogstreamexec[loop] = stream->epilogstreambase + +(iterations-loop)*s_codebuf.bytes; + } + } + } + + // COMPILE AND UNROLL THE LOOP S-CODE STRING + { + BOOL result = GenerateCode(localloopstring,firsterror,0); + if (firsterror && *firsterror) + *firsterror = loopstring+(*firsterror-userloopstring); + if (!result) + return SCodeDelete((HSCODESTREAM)stream); + stream->loopbytes = s_codebuf.bytes*maxiterations+s_retbuf.bytes; + stream->loopstreambase = (LPBYTE)ALLOC(stream->loopbytes); + LPBYTE dest = stream->loopstreambase; + DWORD loop; + for (loop = 0; loop < maxiterations; ++loop) { + CopyMemory(dest,s_codebuf.data,s_codebuf.bytes); + dest += s_codebuf.bytes; + } + CopyMemory(dest,s_retbuf.data,s_retbuf.bytes); + for (loop = 0; loop <= maxiterations; ++loop) + stream->loopstreamexec[loop] = stream->loopstreambase + +(maxiterations-loop)*s_codebuf.bytes; + } + + *handle = (HSCODESTREAM)stream; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCodeDelete (HSCODESTREAM handle) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATEEND; + + // FREE THE CODE BUFFERS + STREAMPTR stream = (STREAMPTR)handle; + if (stream->prologstreambase) { + FREE(stream->prologstreambase); + stream->prologstreambase = NULL; + } + if (stream->epilogstreambase) { + FREE(stream->epilogstreambase); + stream->epilogstreambase = NULL; + } + if (stream->loopstreambase) { + FREE(stream->loopstreambase); + stream->loopstreambase = NULL; + } + + // UNLINK AND FREE THE NODE. THE MEMORY IS FREED EVEN IF THE NODE IS NOT + // FOUND IN THE LINKED LIST, WHICH WOULD BE THE CASE IF WE ARE BEING CALLED + // BECAUSE OF AN ERROR DURING COMPILATION. + s_streamlist.DeleteNode(stream); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCodeDestroy () { + + // DELETE ALL CODE STREAMS + while (!s_streamlist.IsEmpty()) { + REPORTRESOURCELEAK(HSCODESTREAM); + SCodeDelete((HSCODESTREAM)s_streamlist.Head()); + } + + // FREE THE CODE BUFFER AND RETURN BUFFER IF NECESSARY + if (s_codebuf.data) + FREE(s_codebuf.data); + ZeroMemory(&s_codebuf,sizeof(BUF)); + if (s_retbuf.data) + FREE(s_retbuf.data); + ZeroMemory(&s_retbuf,sizeof(BUF)); + + // CLEAR THE INSTRUCTION QUEUE IF NECESSARY + ClearQueue(); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCodeExecute (HSCODESTREAM handle, + SCODEEXECUTEDATAPTR executedata) { + STREAMPTR stream = (STREAMPTR)handle; + DWORD xiterations = executedata->xiterations; + + // IF WE ARE DOING AUTO-ALIGNMENT, FIX UP THE JUMP OFFSETS AS FOLLOWS: + // 1. EXECUTE PROLOG CODE FOR BYTE OPERATIONS, UP TO A DWORD BOUNDARY + // 2. EXECUTE LOOP CODE FOR WHOLE DWORD OPERATIONS + // 3. EXECUTE EPILOG CODE FOR FINAL BYTE OPERATIONS + // "XITERATIONS" REFERS TO THE TOTAL NUMBER OF BYTES TO PROCESS + if (stream->flags & SCODE_CF_AUTOALIGNDWORD) { + DWORD checkvalue = (xiterations << 2) ^ ((DWORD)executedata->dest & 3); + if (stream->checkvalue != checkvalue) { + stream->checkvalue = checkvalue; + DWORD align1 = (4-((DWORD)executedata->dest & 3)) & 3; + if (align1 > xiterations) + align1 = xiterations; + DWORD dwords = (xiterations -= align1) >> 2; + DWORD align2 = xiterations & 3; +#ifdef _X86_ + LPBYTE retptr1, retptr2; + __asm mov retptr1,OFFSET ex_loop1 + __asm mov retptr2,OFFSET ex_loop2 + if (align1 || align2) { + stream->executeptr = stream->prologstreamexec[align1]; + *(LPDWORD)(stream->prologstreambase+stream->prologbytes-sizeof(DWORD)) + = stream->loopstreamexec[dwords]-(stream->prologstreambase+stream->prologbytes); + *(LPDWORD)(stream->loopstreambase+stream->loopbytes-sizeof(DWORD)) + = stream->epilogstreamexec[align2] + -(stream->loopstreambase+stream->loopbytes); + *(LPDWORD)(stream->epilogstreambase+stream->epilogbytes-sizeof(DWORD)) + = ((stream->flags & SCODE_CF_USESALTADJUSTS) ? retptr2 : retptr1) + -(stream->epilogstreambase+stream->epilogbytes); + } + else { + stream->executeptr = stream->loopstreamexec[dwords]; + *(LPDWORD)(stream->loopstreambase+stream->loopbytes-sizeof(DWORD)) + = ((stream->flags & SCODE_CF_USESALTADJUSTS) ? retptr2 : retptr1) + -(stream->loopstreambase+stream->loopbytes); + } +#endif + } + } + + // OTHERWISE, FIX UP THE JUMP OFFSETS SO THAT WE CALL THE PROLOG CODE + // ONCE, FOLLOWED BY "XITERATIONS" ITERATIONS OF THE LOOP CODE + else { + if (stream->checkvalue != xiterations) { + stream->checkvalue = xiterations; +#ifdef _X86_ + LPBYTE retptr1, retptr2; + __asm mov retptr1,OFFSET ex_loop1 + __asm mov retptr2,OFFSET ex_loop2 + stream->executeptr = stream->prologstreambase; + *(LPDWORD)(stream->prologstreambase+stream->prologbytes-sizeof(DWORD)) + = stream->loopstreamexec[xiterations] + -(stream->prologstreambase+stream->prologbytes); + *(LPDWORD)(stream->loopstreambase+stream->loopbytes-sizeof(DWORD)) + = ((stream->flags & SCODE_CF_USESALTADJUSTS) ? retptr2 : retptr1) + -(stream->loopstreambase+stream->loopbytes); +#endif + } + } + + // EXECUTE THE LOOPS FOR INTEL X86 PROCESSORS +#ifdef _X86_ +#define LOCAL_JUMPPTR DWORD PTR [esp] +#define LOCAL_YCOUNT DWORD PTR [esp+4] +#define LOCAL_EXECUTEDATA DWORD PTR [esp+8] +#define LOCAL_ADJUSTSOURCE DWORD PTR [esp+12] +#define LOCAL_ADJUSTDEST DWORD PTR [esp+16] + __asm { + push edi + push esi + push ebp + + // PREPARE OUR LOCAL DATA AREA ON THE STACK + mov eax,executedata + mov ebx,stream + sub esp,20 + mov ecx,[eax]SCODEEXECUTEDATA.yiterations + mov esi,[eax]SCODEEXECUTEDATA.adjustsource + mov edi,[eax]SCODEEXECUTEDATA.adjustdest + mov ebx,[ebx]STREAM.executeptr + mov LOCAL_EXECUTEDATA,eax + mov LOCAL_JUMPPTR,ebx + mov LOCAL_YCOUNT,ecx + mov LOCAL_ADJUSTSOURCE,esi + mov LOCAL_ADJUSTDEST,edi + + // PREPARE THE REGISTERS + mov edi,[eax]SCODEEXECUTEDATA.dest + mov esi,[eax]SCODEEXECUTEDATA.source + mov ebp,[eax]SCODEEXECUTEDATA.table + mov ecx,[eax]SCODEEXECUTEDATA.a + mov edx,[eax]SCODEEXECUTEDATA.b + mov ebx,[eax]SCODEEXECUTEDATA.c + + // EXECUTE THE FIRST LOOP + mov eax,LOCAL_JUMPPTR + jmp eax + + // EXECUTE THE NEXT LOOP FOR TYPE 1 (STANDARD) + align 16 + ex_loop1: dec LOCAL_YCOUNT + mov eax,LOCAL_JUMPPTR + jz ex_done + add esi,LOCAL_ADJUSTSOURCE + add edi,LOCAL_ADJUSTDEST + jmp eax + + // EXECUTE THE NEXT LOOP FOR TYPE 2 (ALTERNATING) + align 16 + ex_loop2: test LOCAL_YCOUNT,1 + jnz ex_loop2odd + dec LOCAL_YCOUNT + mov eax,LOCAL_JUMPPTR + add esi,LOCAL_ADJUSTSOURCE + add edi,LOCAL_ADJUSTDEST + jmp eax + ex_loop2odd: dec LOCAL_YCOUNT + jz ex_done + mov eax,LOCAL_EXECUTEDATA + add esi,[eax]SCODEEXECUTEDATA.adjustsourcealt + add edi,[eax]SCODEEXECUTEDATA.adjustdestalt + mov eax,LOCAL_JUMPPTR + jmp eax + + // RESTORE THE STACK + ex_done: add esp,20 + pop ebp + pop esi + pop edi + + // SAVE THE VALUE OF EACH VARIABLE + mov eax,executedata + mov [eax]SCODEEXECUTEDATA.a,ecx + mov [eax]SCODEEXECUTEDATA.b,edx + mov [eax]SCODEEXECUTEDATA.c,ebx + + } +#undef LOCAL_JUMPPTR +#undef LOCAL_YCOUNT +#undef LOCAL_ADJUSTSOURCE +#undef LOCAL_ADJUSTDEST +#endif + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCodeGetJumpTable (HSCODESTREAM handle, + LPBYTE **jumptableptr, + LPDWORD *prologpatchlocation, + LPDWORD *looppatchlocation, + LPDWORD *epilogpatchlocation) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATEEND; + + STREAMPTR stream = (STREAMPTR)handle; + + if (jumptableptr) + *jumptableptr = &stream->loopstreamexec[0]; + if (prologpatchlocation) + *prologpatchlocation = (LPDWORD)(stream->prologstreambase+stream->prologbytes-sizeof(DWORD)); + if (looppatchlocation) + *looppatchlocation = (LPDWORD)(stream->loopstreambase+stream->loopbytes-sizeof(DWORD)); + if (epilogpatchlocation) + *epilogpatchlocation = (LPDWORD)(stream->epilogstreambase+stream->epilogbytes-sizeof(DWORD)); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCodeGetPseudocode (LPCSTR scodestring, + LPSTR buffer, + DWORD buffersize) { + VALIDATEBEGIN; + VALIDATE(scodestring); + VALIDATE(*scodestring); + VALIDATE(buffer); + VALIDATE(buffersize); + VALIDATEEND; + + // CREATE A NORMALIZED VERSION OF THE STRING + char localstring[256] = ""; + SStrCopy(localstring,scodestring,256); + _strupr(localstring); + + // COMPILE THE S-CODE INTO PSEUDOCODE + if (!GenerateCode(localstring,NULL,1)) { + *buffer = 0; + return FALSE; + } + *(s_codebuf.data+s_codebuf.bytes) = 0; + + // COPY THE PSEUDOCODE INTO THE BUFFER + SStrCopy(buffer,(LPSTR)s_codebuf.data,buffersize); + + return (s_codebuf.bytes < buffersize); +} diff --git a/Storm/SOURCE/SCOMP.CPP b/Storm/SOURCE/SCOMP.CPP new file mode 100644 index 0000000..a941ef5 --- /dev/null +++ b/Storm/SOURCE/SCOMP.CPP @@ -0,0 +1,1267 @@ +/**************************************************************************** +* +* SCOMP.CPP +* Storm compression functions +* +* By Michael O'Brien (10/17/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define SOURCESYMBOLS 256 +#define EOS 256 +#define ESCAPE 257 +#define SYMBOLS 258 + +static const BYTE s_probability[SCOMP_HINTS][SYMBOLS] = + { + + // BASIC PROBABILITY TABLE + {10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2}, + + // BINARY PROBABILITY TABLE + {84,22,22,13,12,8,6,5,6,5,6,3,4,4,3,5, + 14,11,20,19,19,9,11,6,5,4,3,2,3,2,2,2, + 13,7,9,6,6,4,3,2,4,3,3,3,3,3,2,2, + 9,6,4,4,4,4,3,2,3,2,2,2,2,3,2,4, + 8,3,4,7,9,5,3,3,3,3,2,2,2,3,2,2, + 3,2,2,2,2,2,2,2,2,1,1,1,2,1,2,2, + 6,10,8,8,6,7,4,3,4,4,2,2,4,2,3,3, + 4,3,7,7,9,6,4,3,3,2,1,2,2,2,2,2, + 10,2,2,3,2,2,1,1,2,2,2,6,3,5,2,3, + 2,1,1,1,1,1,1,1,1,1,1,2,3,1,1,1, + 2,1,1,1,1,1,1,2,4,4,4,7,9,8,12,2, + 1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,3, + 4,1,2,4,5,1,1,1,1,1,1,1,2,1,1,1, + 4,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1, + 2,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1, + 2,1,1,1,1,1,1,2,2,1,1,2,2,2,6,75}, + + // TEXT PROBABILITY TABLE + {0,0,0,0,0,0,0,0,0,3,39,0,0,35,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,1,1,1,1,1,1,1,2,2,1,1,6,14,16,4, + 6,8,5,4,4,3,3,2,2,3,3,1,1,2,1,1, + 1,4,2,4,2,2,2,1,1,4,1,1,2,3,3,2, + 3,1,3,6,4,1,1,1,1,1,1,2,1,2,1,1, + 1,41,7,22,18,64,10,10,17,37,1,3,23,16,38,42, + 16,1,35,35,47,16,6,7,2,9,1,1,1,1,1,0}, + + // EXECUTABLE PROBABILITY TABLE + {255,11,7,5,11,2,2,2,6,2,2,1,4,2,1,3, + 9,1,1,1,3,4,1,1,2,1,1,1,2,1,1,1, + 5,1,1,1,13,1,1,1,1,1,1,1,1,1,1,1, + 2,1,1,3,1,1,1,1,1,1,1,2,1,1,1,1, + 10,4,2,1,6,3,2,1,1,1,1,1,3,1,1,1, + 5,2,3,4,3,3,3,2,1,1,1,2,1,2,3,3, + 1,3,1,1,2,5,1,1,4,3,5,1,3,1,3,3, + 2,1,4,3,10,6,1,1,1,1,1,1,1,1,1,1, + 2,2,1,10,2,5,1,1,2,7,2,23,1,5,1,1, + 14,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 6,2,1,4,5,1,1,2,1,1,1,1,2,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,7,1,1,2,1,1,1,1, + 2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,17}, + + // ADPCM4 PROBABILITY TABLE + {255,251,152,154,132,133,99,100,62,62,34,34,19,19,24,23}, + + // ADPCM6 PROBABILITY TABLE + {255,241,157,158,154,155,154,151,147,147,140,142,134,136,128,130, + 124,124,114,115,105,107,95,96,85,86,74,75,64,65,55,55, + 47,47,39,39,33,33,27,28,23,23,19,19,16,16,13,13, + 11,11,9,9,8,8,7,7,6,5,5,4,4,4,25,24} + + }; + +/**************************************************************************** +* +* BITWISE I/O SUPPORT +* +***/ + +namespace { + +class CBitInput { + + private: + const DWORD *m_currsource; + DWORD m_rack; + DWORD m_rackbits; + + public: + CBitInput (LPCVOID source, + DWORD sourcebytes); + inline DWORD InputBit (); + inline DWORD InputBits (DWORD count, + DWORD mask); + inline DWORD PeekBits (DWORD count, + DWORD mask); + inline void RemoveBits (DWORD count); + +}; + +class CBitOutput { + + private: + LPBYTE m_basedest; + DWORD m_bytesleft; + LPBYTE m_currdest; + DWORD m_rack; + DWORD m_rackbits; + + public: + CBitOutput (LPVOID dest, + DWORD destsize); + DWORD GetTotalBytes (); + inline void OutputBits (DWORD value, + DWORD count); + void Pad (); + +}; + +//=========================================================================== +CBitInput::CBitInput (LPCVOID source, + DWORD sourcebytes) { + m_currsource = (const DWORD *)source; + m_rack = *m_currsource++; + m_rackbits = 32; +} + +//=========================================================================== +DWORD CBitInput::InputBit () { + DWORD result = (m_rack & 1); + m_rack >>= 1; + if (!--m_rackbits) { + m_rack = *m_currsource++; + m_rackbits = 32; + } + return result; +} + +//=========================================================================== +DWORD CBitInput::InputBits (DWORD count, + DWORD mask) { + DWORD result = PeekBits(count,mask); + RemoveBits(count); + return result; +} + +//=========================================================================== +DWORD CBitInput::PeekBits (DWORD count, + DWORD mask) { + while (m_rackbits <= count) { + m_rack |= *(LPBYTE)m_currsource << m_rackbits; + m_rackbits += 8; + m_currsource = (LPDWORD)((LPBYTE)m_currsource+1); + } + return m_rack & mask; +} + +//=========================================================================== +void CBitInput::RemoveBits (DWORD count) { + m_rack >>= count; + m_rackbits -= count; +} + +//=========================================================================== +CBitOutput::CBitOutput (LPVOID dest, + DWORD destsize) { + m_basedest = m_currdest = (LPBYTE)dest; + m_bytesleft = destsize; + m_rack = 0; + m_rackbits = 0; +} + +//=========================================================================== +DWORD CBitOutput::GetTotalBytes () { + return m_currdest-m_basedest; +} + +//=========================================================================== +void CBitOutput::OutputBits (DWORD value, + DWORD count) { + m_rack |= (value << m_rackbits); + m_rackbits += count; + while (m_rackbits >= 8) { + if (m_bytesleft) { + *m_currdest++ = (BYTE)m_rack; + --m_bytesleft; + } + m_rack >>= 8; + m_rackbits -= 8; + } +} + +//=========================================================================== +void CBitOutput::Pad () { + while (m_rackbits) { + if (m_bytesleft) { + *m_currdest++ = (BYTE)m_rack; + --m_bytesleft; + } + m_rack >>= 8; + m_rackbits -= min(8,m_rackbits); + } +} + +} // end of namespace + +/**************************************************************************** +* +* HUFFMAN ENCODER +* +***/ + +namespace { + +NODEDECL(HUFFNODE) { + int symbol; + DWORD weight; + HUFFNODE *parent; + HUFFNODE *child; +} *HUFFNODEPTR; + +class CHuffman { + + protected: + BOOL m_adaptive; + DWORD m_changesequence; + LIST(HUFFNODE) m_nodelist; + HUFFNODEPTR m_symbol[SYMBOLS]; + + void AddSymbol (int symbol); + void BuildTree (BYTE hint); + inline void IncrementWeight (HUFFNODEPTR node); + + public: + CHuffman (); + ~CHuffman (); + +}; + +class CHuffmanDecoder : public CHuffman { + + private: + DWORD m_cachebits[SYMBOLS]; + DWORD m_cachesequence[SYMBOLS]; + int m_cachesymbol[SYMBOLS]; + + inline int DecodeSymbol (CBitInput *input); + + public: + CHuffmanDecoder (); + DWORD Decompress (LPVOID dest, + CBitInput *input); + +}; + +class CHuffmanEncoder : public CHuffman { + + private: + inline void EncodeSymbol (CBitOutput *output, + int symbol); + + public: + DWORD Compress (CBitOutput *output, + LPCVOID source, + DWORD sourcesize, + BYTE hint); + +}; + +//=========================================================================== +CHuffman::CHuffman () { + m_changesequence = 1; +} + +//=========================================================================== +CHuffman::~CHuffman () { + m_nodelist.Clear(); +} + +//=========================================================================== +void CHuffman::AddSymbol (int symbol) { + + // CONVERT THE LIGHTEST WEIGHT LEAF NODE INTO A BRANCH + HUFFNODEPTR parent = m_nodelist.Head(); + HUFFNODEPTR oldchild = m_nodelist.NewNode(LIST_HEAD); + oldchild->symbol = parent->symbol; + oldchild->weight = parent->weight; + oldchild->parent = parent; + m_symbol[oldchild->symbol] = oldchild; + + // ALLOCATE A NEW LEAF NODE FOR THIS SYMBOL + HUFFNODEPTR newchild = m_nodelist.NewNode(LIST_HEAD); + newchild->symbol = symbol; + newchild->weight = 0; + newchild->parent = parent; + m_symbol[symbol] = newchild; + + // ATTACH THE PARENT NODE TO THESE TWO LEAF NODES + parent->child = newchild; + + // INCREMENT THE NEW LEAF NODE'S WEIGHT + IncrementWeight(newchild); + +} + +//=========================================================================== +void CHuffman::BuildTree (BYTE hint) { + + // REMOVE ALL NODES FROM THE EXISTING NODE LIST + m_nodelist.Clear(); + + // ADD LEAF NODES FOR EACH SYMBOL + ZeroMemory(m_symbol,SYMBOLS*sizeof(HUFFNODEPTR)); + DWORD maxweight = 0; + int symbol; + for (symbol = 0; symbol < SOURCESYMBOLS; ++symbol) + if (s_probability[hint][symbol]) { + + // CREATE A NEW NODE FOR THIS SYMBOL + HUFFNODEPTR newnode = m_symbol[symbol] = m_nodelist.NewNode(LIST_TAIL); + newnode->symbol = symbol; + newnode->weight = s_probability[hint][symbol]; + + // LINK IT INTO THE NODE LIST IN SORTED ORDER + if (newnode->weight >= maxweight) + maxweight = newnode->weight; + else { + HUFFNODEPTR checknode = m_nodelist.Head(); + while (checknode && (checknode->weight < newnode->weight)) + checknode = checknode->Next(); + m_nodelist.LinkNode(newnode,LIST_LINK_BEFORE,checknode); + } + + } + for (; symbol < SYMBOLS; ++symbol) { + HUFFNODEPTR newnode = m_symbol[symbol] = m_nodelist.NewNode(LIST_HEAD); + newnode->symbol = symbol; + newnode->weight = 1; + } + + // BUILD THE NODE TREE UP FROM THE LEAF NODES + for (HUFFNODEPTR currnode = m_nodelist.Head(), nextnode; + currnode && (nextnode = currnode->Next()); + currnode = nextnode->Next()) { + + // CREATE A NEW NODE TO BE THE PARENT OF THESE TWO NODES + HUFFNODEPTR newnode = m_nodelist.NewNode(LIST_TAIL); + newnode->weight = currnode->weight+nextnode->weight; + newnode->child = currnode; + + // SET EACH NODE'S PARENT TO THE NEW NODE + currnode->parent = newnode; + nextnode->parent = newnode; + + // LINK THE NEW NODE INTO THE LIST, SORTED BY WEIGHT + if (newnode->weight >= maxweight) + maxweight = newnode->weight; + else { + HUFFNODEPTR checknode = nextnode->Next(); + while (checknode && (checknode->weight < newnode->weight)) + checknode = checknode->Next(); + m_nodelist.LinkNode(newnode,LIST_LINK_BEFORE,checknode); + } + + } + + // INITIALIZE THE SEQUENCE NUMBER + m_changesequence = 1; + +} + +//=========================================================================== +void CHuffman::IncrementWeight (HUFFNODEPTR node) { + + // PROPAGATE THE WEIGHT CHANGE UP THE TREE + for (HUFFNODEPTR currnode = node; + currnode; + currnode = currnode->parent) { + + // UPDATE THIS NODE'S WEIGHT + ++currnode->weight; + + // CHECK TO SEE IF THIS NODE NEEDS TO BE MOVED UP THE TREE + HUFFNODEPTR checknode = currnode; + HUFFNODEPTR nextchecknode; + while ((nextchecknode = checknode->Next()) != NULL) + if (nextchecknode->weight < currnode->weight) + checknode = nextchecknode; + else + break; + + // IF IT DOES, THEN SWAP IT WITH THE NODE THAT HAS THE NEXT + // HIGHER WEIGHT + if (checknode != currnode) { + + // SWAP THE TWO NODES' POSITIONS IN THE LIST + m_nodelist.LinkNode(checknode,LIST_LINK_BEFORE,currnode); + m_nodelist.LinkNode(currnode,LIST_LINK_BEFORE,nextchecknode); + + // SWAP THE TWO NODES' PARENTS + HUFFNODEPTR currnodefirstchild = currnode->parent->child; + HUFFNODEPTR checknodefirstchild = checknode->parent->child; + if (currnodefirstchild == currnode) + currnode->parent->child = checknode; + if (checknodefirstchild == checknode) + checknode->parent->child = currnode; + SWAP(currnode->parent,checknode->parent); + + // INVALIDATE THE CACHE + ++m_changesequence; + + } + + } + +} + +//=========================================================================== +CHuffmanDecoder::CHuffmanDecoder () { + ZeroMemory(m_cachesequence,SYMBOLS*sizeof(DWORD)); +} + +//=========================================================================== +int CHuffmanDecoder::DecodeSymbol (CBitInput *input) { + + // CHECK TO SEE WHETHER THE DECODING OF THE NEXT SYMBOL IS CACHED + DWORD nextbyte = input->PeekBits(8,0xFF); + if (m_cachesequence[nextbyte] == m_changesequence) { + input->RemoveBits(m_cachebits[nextbyte]); + return m_cachesymbol[nextbyte];; + } + + // IF NOT, DECODE THE SYMBOL BY WALKING THE TREE, THEN ADD IT TO THE CACHE + DWORD bits = 0; + for (HUFFNODEPTR currnode = m_nodelist.Tail(); + currnode->child; + ++bits) { + currnode = currnode->child; + if (input->InputBit()) + currnode = currnode->Next(); + } + int symbol = currnode->symbol; + if (bits <= 8) { + m_cachebits[nextbyte] = bits; + m_cachesequence[nextbyte] = m_changesequence; + m_cachesymbol[nextbyte] = symbol; + } + return symbol; + +} + +//=========================================================================== +DWORD CHuffmanDecoder::Decompress (LPVOID dest, + CBitInput *input) { + + // INITIALIZE THE DECOMPRESSION TREE + BYTE hint = (BYTE)input->InputBits(8,0xFF); + BuildTree(hint); + m_adaptive = (hint == SCOMP_HINT_NONE); + + // DECOMPRESS THE DATA + LPBYTE currdest = (LPBYTE)dest; + for (;;) { + + // DECODE THE NEXT SYMBOL + int symbol = DecodeSymbol(input); + + // PROCESS THE SYMBOL + if (symbol == ESCAPE) { + symbol = (int)input->InputBits(8,0xFF); + AddSymbol(symbol); + if (!m_adaptive) + IncrementWeight(m_symbol[symbol]); + } + if (symbol == EOS) + break; + *currdest++ = (BYTE)symbol; + + // UPDATE SYMBOL'S WEIGHT + if (m_adaptive) + IncrementWeight(m_symbol[symbol]); + + } + + return currdest-(LPBYTE)dest; +} + +//=========================================================================== +DWORD CHuffmanEncoder::Compress (CBitOutput *output, + LPCVOID source, + DWORD sourcesize, + BYTE hint) { + + // INITIALIZE THE COMPRESSION TREE USING THE HINT, AND SAVE THE HINT + // TO THE DESTINATION BUFFER + BuildTree(hint); + m_adaptive = (hint == SCOMP_HINT_NONE); + output->OutputBits(hint,8); + + // COMPRESS THE DATA + const BYTE *currsource = (const BYTE *)source; + while (sourcesize--) { + int symbol = *currsource++; + + // IF THIS IS THE FIRST USE OF THIS SYMBOL, ENCODE AN ESCAPE SEQUENCE + if (!m_symbol[symbol]) { + EncodeSymbol(output,ESCAPE); + output->OutputBits(symbol,8); + AddSymbol(symbol); + if (!m_adaptive) + IncrementWeight(m_symbol[symbol]); + } + + // OTHERWISE, ENCODE THE SYMBOL + else + EncodeSymbol(output,symbol); + + // UPDATE SYMBOL'S WEIGHT + if (m_adaptive) + IncrementWeight(m_symbol[symbol]); + + } + + // ENCODE AN END-OF-STREAM SEQUENCE + EncodeSymbol(output,EOS); + output->Pad(); + + return output->GetTotalBytes(); +} + +//=========================================================================== +void CHuffmanEncoder::EncodeSymbol (CBitOutput *output, + int symbol) { + DWORD encoding = 0; + DWORD encodingbits = 0; + for (HUFFNODEPTR currnode = m_symbol[symbol], parent; + parent = currnode->parent; + currnode = parent) { + encoding <<= 1; + encoding |= (parent->child != currnode); + ++encodingbits; + } + output->OutputBits(encoding, + encodingbits); +} + +} // end of namespace + +/**************************************************************************** +* +* ADPCM ENCODER +* +***/ + +namespace { + +static const DWORD s_adpcm_2bit[2] = {51,102}; +static const DWORD s_adpcm_3bit[4] = {58,58,80,112}; +static const DWORD s_adpcm_4bit[8] = {58,58,58,58,77,102,128,154}; +static const DWORD s_adpcm_6bit[32] = {58,58,58,58,58,58,58,58, + 58,58,58,58,58,58,58,58, + 70,83,96,109,122,134,147,160, + 173,186,198,211,224,237,250,262}; + +class CAdpcm { + + protected: + const DWORD *m_adapttable; + DWORD m_bitspersample; + DWORD m_minadapt; + DWORD m_maxadapt; + DWORD m_steps; + + inline void AdjustValue (int *last, + DWORD *adapt, + DWORD scaleddelta, + BOOL negative); + void Initialize (DWORD bitspersample); + inline void PredictNextValue (int *last); + +}; + +class CAdpcmDecoder : public CAdpcm { + + public: + DWORD Decompress (short *dest, + const BYTE *source, + DWORD sourcesize, + DWORD channels); + +}; + +class CAdpcmEncoder : public CAdpcm { + + public: + DWORD Compress (LPBYTE dest, + const short *source, + DWORD sourcesize, + DWORD channels, + DWORD bitspersample); + +}; + +//=========================================================================== +void CAdpcm::AdjustValue (int *last, + DWORD *adapt, + DWORD scaleddelta, + BOOL negative) { + + // SAVE THE NEW VALUE, ADJUSTED BY THE SCALED DELTA, AS THE VALUE TO + // BE USED AS THE LAST VALUE FOR THE NEXT ITERATION OF THE LOOP + int quantdiff = (int)((scaleddelta+1)*(*adapt)+m_steps) >> m_bitspersample; + if (negative) { + *last -= quantdiff; + if (*last < -32768) + *last = -32768; + } + else { + *last += quantdiff; + if (*last > 32767) + *last = 32767; + } + + // ADJUST THE ADAPTATION FACTOR + *adapt = ((*adapt)*m_adapttable[scaleddelta]+128) >> 6; + if (*adapt < m_minadapt) + *adapt = m_minadapt; + if (*adapt > m_maxadapt) + *adapt = m_maxadapt; + +} + +//=========================================================================== +void CAdpcm::Initialize (DWORD bitspersample) { + + // SELECT THE ADAPTATION TABLE TO USE + switch (bitspersample) { + case 2: m_adapttable = s_adpcm_2bit; break; + case 3: m_adapttable = s_adpcm_3bit; break; + case 4: m_adapttable = s_adpcm_4bit; break; + case 6: m_adapttable = s_adpcm_6bit; break; + default: m_adapttable = NULL; break; + } + ASSERT(m_adapttable); + + // SAVE THE NUMBER OF BITS PER SAMPLE + m_bitspersample = bitspersample; + + // COMPUTE THE NUMBER OF STEPS IN THE ADAPTATION TABLE, AND THE MINIMUM + // AND MAXIMUM ADAPTATION VALUES + m_steps = (1 << m_bitspersample) / 2; + m_minadapt = 1 << m_bitspersample; + m_maxadapt = 131072; + +} + +//=========================================================================== +void CAdpcm::PredictNextValue (int *last) { + *last = (230*(*last)+128) >> 8; +} + +//=========================================================================== +DWORD CAdpcmDecoder::Decompress (short *dest, + const BYTE *source, + DWORD sourcesize, + DWORD channels) { + const BYTE *basesource = source; + short *basedest = dest; + DWORD loop; + + // READ THE BITRATE AND INITIALIZE ADPCM DECOMPRESSION + Initialize(*source++); + + // READ THE ACCUMULATED ERROR FOR THIS BLOCK FOR EACH CHANNEL + DWORD absaccumerror[2]; + DWORD negaccumerror[2]; + for (loop = 0; loop < channels; ++loop) { + BYTE code = *source++; + absaccumerror[loop] = code >> 1; + negaccumerror[loop] = code & 1; + } + + // READ THE STARTING ADAPTATION VALUE FOR EACH CHANNEL + DWORD adapt[2]; + for (loop = 0; loop < channels; ++loop) { + adapt[loop] = ((DWORD)(*(LPWORD)source)) << m_bitspersample; + source += 2; + } + + // READ THE INITIAL SAMPLE FOR EACH CHANNEL + int last[2]; + for (loop = 0; loop < channels; ++loop) { + last[loop] = *(const short *)source; + source += 2; + *dest++ = (short)last[loop]; + } + + // PROCESS ALL THE COMPRESSED SAMPLES IN THIS BLOCK + DWORD channel = 0; + for (loop = source-basesource; loop < sourcesize; ++loop) { + + // ADJUST THE LAST VALUE BY A CONSTANT SCALING FACTOR + PredictNextValue(&last[channel]); + + // READ THE NEXT COMPRESSED SAMPLE + BYTE code = *source++; + DWORD scaled = code >> 1; + BOOL neg = code & 1; + + // GENERATE THE VALUE OF THE UNCOMPRESSED SAMPLE, AND ADJUST THE + // ADAPTATION VALUE + AdjustValue(&last[channel], + &adapt[channel], + scaled, + neg); + + // IF WE ARE NEARING THE END OF THE BLOCK, ADD IN A LITTLE BIT OF + // THE ERROR TERM INTO EACH SAMPLE, SO THAT THE BLOCK WILL END ON + // EXACTLY THE CORRECT VALUE + int output = last[channel]; + DWORD samplesleft = (sourcesize-(loop+1)) >> (channels-1); + if (samplesleft < absaccumerror[channel]) + if (negaccumerror[channel]) { + output += absaccumerror[channel]-samplesleft; + if (output > 32767) + output = 32767; + } + else { + output -= absaccumerror[channel]-samplesleft; + if (output < -32768) + output = -32768; + } + *dest++ = (short)output; + + // ALTERNATE CHANNELS + if (channels == 2) + channel = !channel; + + } + + return (LPBYTE)dest-(LPBYTE)basedest; +} + +//=========================================================================== +DWORD CAdpcmEncoder::Compress (LPBYTE dest, + const short *source, + DWORD sourcesize, + DWORD channels, + DWORD bitspersample) { + LPBYTE basedest = dest; + DWORD loop; + + // INITIALIZE ADPCM COMPRESSION + Initialize(bitspersample); + + // SAVE THE NUMBER OF BITS PER SAMPLE + *dest++ = (BYTE)bitspersample; + + // RESERVE SPACE FOR THE ACCUMULATED ERROR FOR EACH CHANNEL + LPBYTE accumerrorptr[2]; + for (loop = 0; loop < channels; ++loop) + accumerrorptr[loop] = dest++; + + // COMPUTE AND SAVE THE STARTING ADAPTATION VALUE FOR EACH CHANNEL + DWORD adapt[2]; + for (loop = 0; loop < channels; ++loop) { + int last = source[loop]; + PredictNextValue(&last); + DWORD firstdiff = abs(source[loop+channels]-last) << m_bitspersample; + DWORD bestadapt = firstdiff*2/m_steps; + bestadapt = max(bestadapt,m_minadapt); + bestadapt = min(bestadapt,m_maxadapt); + DWORD savevalue = bestadapt >> m_bitspersample; + *(LPWORD)dest = (WORD)savevalue; + dest += 2; + adapt[loop] = savevalue << m_bitspersample; + } + + // SAVE THE VALUE OF THE FIRST SAMPLE FOR EACH CHANNEL + int last[2]; + for (loop = 0; loop < channels; ++loop) { + last[loop] = *source++; + *(short *)dest = (short)last[loop]; + dest += 2; + } + + // PROCESS EACH OF THE REMAINING SAMPLES + int val[2]; + DWORD channel = 0; + DWORD samples = sourcesize/2; + for (loop = channels; loop < samples; ++loop) { + + // ADJUST THE LAST VALUE BY A CONSTANT SCALING FACTOR + PredictNextValue(&last[channel]); + + // READ THE NEXT SAMPLE + val[channel] = *source++; + DWORD diff = abs(val[channel]-last[channel]); + BOOL neg = last[channel] > val[channel]; + + // PRODUCE A DELTA WHICH IS SCALED BY THE ADAPTATION FACTOR + DWORD unscaled = diff << bitspersample; + DWORD scaled = 0; + if (unscaled > adapt[channel]) + scaled = min((unscaled - (adapt[channel] >> 1)) / adapt[channel], + m_steps-1); + + // PACK THE SCALED NUMBER AND THE SIGN INTO THE DESIRED NUMBER OF BITS + *dest++ = (BYTE)((scaled << 1) | neg); + + // ADJUST THE ADAPTATION FACTOR, AND GENERATE THE VALUE OF THE + // COMPRESSED AND DECOMPRESSED SAMPLE, WHICH WE WILL USE AS THE + // VALUE OF THE LAST SAMPLE IN THE NEXT ITERATION OF THE LOOP + AdjustValue(&last[channel], + &adapt[channel], + scaled, + neg); + + // ALTERNATE CHANNELS + if (channels == 2) + channel = !channel; + + } + + // COMPUTE AND SAVE THE ACCUMULATED ERROR FOR EACH CHANNEL + for (loop = 0; loop < channels; ++loop) { + int accumerror = last[loop]-val[loop]; + DWORD absaccumerror = abs(accumerror); + BOOL negaccumerror = accumerror < 0; + absaccumerror = min(127,absaccumerror); + *accumerrorptr[loop] = (BYTE)(absaccumerror << 1) | negaccumerror; + } + + return dest-basedest; +} + +} // end of namespace + +/**************************************************************************** +* +* PKWARE ENCODER +* +***/ + +typedef struct _PKWAREINFO { + LPVOID dest; + DWORD destpos; + DWORD destsize; + LPCVOID source; + DWORD sourcepos; + DWORD sourcesize; +} PKWAREINFO, *PKWAREINFOPTR; + +//=========================================================================== +static UINT __cdecl PkwareBufferRead (LPSTR buffer, + UINT *size, + LPVOID param) { + PKWAREINFOPTR infoptr = (PKWAREINFOPTR)param; + UINT bytes = min(*size,infoptr->sourcesize-infoptr->sourcepos); + CopyMemory(buffer, + (const BYTE *)infoptr->source+infoptr->sourcepos, + bytes); + infoptr->sourcepos += bytes; + return bytes; +} + +//=========================================================================== +static void __cdecl PkwareBufferWrite (LPSTR buffer, + UINT *size, + LPVOID param) { + PKWAREINFOPTR infoptr = (PKWAREINFOPTR)param; + UINT bytes = min(*size,infoptr->destsize-infoptr->destpos); + CopyMemory((LPBYTE)infoptr->dest+infoptr->destpos, + buffer, + bytes); + infoptr->destpos += bytes; +} + +//=========================================================================== +static void PkwareCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD *hint, + DWORD optimization) { + + // CREATE A COMPRESSION BUFFER + LPSTR implodebuffer = (LPSTR)ALLOC(CMP_BUFFER_SIZE); + + // CREATE AN INFORMATION RECORD + PKWAREINFO info; + info.dest = dest; + info.destpos = 0; + info.destsize = *destsize; + info.source = source; + info.sourcepos = 0; + info.sourcesize = sourcesize; + + // DETERMINE THE SOURCE TYPE + unsigned type = (*hint == SCOMP_HINT_TEXT) + ? CMP_ASCII + : CMP_BINARY; + unsigned dictsize = (sourcesize >= 3072) + ? 4096 + : (sourcesize >= 1536) + ? 2048 + : 1024; + + // PERFORM THE DECOMPRESSION + implode(PkwareBufferRead, + PkwareBufferWrite, + (LPSTR)implodebuffer, + &info, + &type, + &dictsize); + + // FREE THE DECOMPRESSION BUFFER + FREE(implodebuffer); + + *destsize = info.destpos; + *hint = SCOMP_HINT_NONE; +} + +//=========================================================================== +static void PkwareDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize) { + + // CREATE A DECOMPRESSION BUFFER + LPSTR explodebuffer = (LPSTR)ALLOC(EXP_BUFFER_SIZE); + + // CREATE AN INFORMATION RECORD + PKWAREINFO info; + info.dest = dest; + info.destpos = 0; + info.destsize = *destsize; + info.source = source; + info.sourcepos = 0; + info.sourcesize = sourcesize; + + // PERFORM THE DECOMPRESSION + explode(PkwareBufferRead, + PkwareBufferWrite, + (LPSTR)explodebuffer, + &info); + + // FREE THE DECOMPRESSION BUFFER + FREE(explodebuffer); + + *destsize = info.destpos; +} + +/**************************************************************************** +* +* WRAPPER FUNCTIONS +* +***/ + +//=========================================================================== +static void AdpcmMonoCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD *hint, + DWORD optimization) { + CAdpcmEncoder adpcm; + *destsize = adpcm.Compress((LPBYTE)dest, + (const short *)source, + sourcesize, + 1, + (optimization == SCOMP_OPT_COMPRESSION) + ? 4 + : 6); + *hint = (optimization == SCOMP_OPT_COMPRESSION) + ? SCOMP_HINT_ADPCM4 + : SCOMP_HINT_ADPCM6; +} + +//=========================================================================== +static void AdpcmMonoDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize) { + CAdpcmDecoder adpcm; + *destsize = adpcm.Decompress((short *)dest, + (const BYTE *)source, + sourcesize, + 1); +} + +//=========================================================================== +static void AdpcmStereoCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD *hint, + DWORD optimization) { + CAdpcmEncoder adpcm; + *destsize = adpcm.Compress((LPBYTE)dest, + (const short *)source, + sourcesize, + 2, + (optimization == SCOMP_OPT_COMPRESSION) + ? 4 + : 6); + *hint = SCOMP_HINT_ADPCM6; +} + +//=========================================================================== +static void AdpcmStereoDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize) { + CAdpcmDecoder adpcm; + *destsize = adpcm.Decompress((short *)dest, + (const BYTE *)source, + sourcesize, + 2); +} + +//=========================================================================== +static void HuffmanCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD *hint, + DWORD optimization) { + CBitOutput output(dest,*destsize); + CHuffmanEncoder huff; + *destsize = huff.Compress(&output, + source, + sourcesize, + (BYTE)*hint); +} + +//=========================================================================== +static void HuffmanDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize) { + CBitInput input(source,sourcesize); + CHuffmanDecoder huff; + *destsize = huff.Decompress(dest,&input); +} + +/**************************************************************************** +* +* UTILITY FUNCTIONS +* +***/ + +//=========================================================================== +static inline BOOL BuffersOverlap (LPCVOID buf1, + LPCVOID buf2, + DWORD length) { + return (((LPBYTE)buf1+length > (LPBYTE)buf2) && + ((LPBYTE)buf2+length > (LPBYTE)buf1)); +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +#define ALGORITHMS 4 + +typedef void (*COMPRESSFUNC)(LPVOID,DWORD *,LPCVOID,DWORD,DWORD *,DWORD); +typedef void (*DECOMPRESSFUNC)(LPVOID,DWORD *,LPCVOID,DWORD); + +typedef struct _COMPRESSALGORITHM { + DWORD id; + COMPRESSFUNC func; +} COMPRESSALGORITHM; + +typedef struct _DECOMPRESSALGORITHM { + DWORD id; + DECOMPRESSFUNC func; +} DECOMPRESSALGORITHM; + +static const COMPRESSALGORITHM s_compressalgorithm[ALGORITHMS] = + {{SCOMP_TYPE_LOSSY_ADPCM_MONO ,AdpcmMonoCompress}, + {SCOMP_TYPE_LOSSY_ADPCM_STEREO,AdpcmStereoCompress}, + {SCOMP_TYPE_HUFFMAN ,HuffmanCompress}, + {SCOMP_TYPE_PKWARE ,PkwareCompress}}; +static const DECOMPRESSALGORITHM s_decompressalgorithm[ALGORITHMS] = + {{SCOMP_TYPE_LOSSY_ADPCM_MONO ,AdpcmMonoDecompress}, + {SCOMP_TYPE_LOSSY_ADPCM_STEREO,AdpcmStereoDecompress}, + {SCOMP_TYPE_HUFFMAN ,HuffmanDecompress}, + {SCOMP_TYPE_PKWARE ,PkwareDecompress}}; + +//=========================================================================== +BOOL APIENTRY SCompCompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize, + DWORD compressiontypes, + DWORD hint, + DWORD optimization) { + VALIDATEBEGIN; + VALIDATE(dest); + VALIDATE(destsize); + VALIDATE(*destsize >= sourcesize); + VALIDATE(source); + VALIDATEEND; + + // COUNT THE NUMBER OF OPERATIONS + DWORD operations = 0; + int loop; + for (loop = 0; loop < ALGORITHMS; ++loop) + if (compressiontypes & s_compressalgorithm[loop].id) + ++operations; + + // ALLOCATE A WORK BUFFER IF NECESSARY + LPVOID work = NULL; + if ((operations >= 2) || + (BuffersOverlap(dest,source,sourcesize) && operations)) + work = ALLOC(sourcesize); + + // APPLY EACH OPERATION + LPCVOID curr = source; + DWORD size = sourcesize; + for (loop = 0; loop < ALGORITHMS; ++loop) + if (compressiontypes & s_compressalgorithm[loop].id) { + --operations; + + // DETERMINE WHICH BUFFER WE WILL COMPRESS INTO FOR THIS OPERATION + LPVOID target = (operations & 1) ? work : ((LPBYTE)dest+1); + if (BuffersOverlap(target,curr,size)) + target = BuffersOverlap(target,work,size) ? ((LPBYTE)dest+1) : work; + + // PERFORM THE COMPRESSION OPERATION + DWORD targetsize = size-1; + s_compressalgorithm[loop].func(target, + &targetsize, + curr, + size, + &hint, + optimization); + + // IF THE OPERATION FAILED TO COMPRESS THE DATA, THEN DISCARD THE + // RESULT + if (targetsize+1 < size) { + curr = target; + size = targetsize; + } + else + compressiontypes &= ~s_compressalgorithm[loop].id; + + } + + // COPY THE FINAL RESULT TO THE DESTINATION BUFFER IF NECESSARY, AND + // SAVE THE COMPRESSION TYPES USED + if (curr != dest) + if (curr == (LPBYTE)dest+1) { + *(LPBYTE)dest = (BYTE)compressiontypes; + ++size; + } + else if (compressiontypes) { + CopyMemory((LPBYTE)dest+1,curr,size); + *(LPBYTE)dest = (BYTE)compressiontypes; + ++size; + } + else + CopyMemory(dest,curr,size); + *destsize = size; + + // FREE THE WORK BUFFER + FREEIFUSED(work); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SCompDecompress (LPVOID dest, + DWORD *destsize, + LPCVOID source, + DWORD sourcesize) { + VALIDATEBEGIN; + VALIDATE(dest); + VALIDATE(destsize); + VALIDATE(*destsize >= sourcesize); + VALIDATE(source); + VALIDATEEND; + + // IF THE DATA IS NOT COMPRESSED, JUST COPY IT TO THE DESTINATION BUFFER + // AND RETURN + if (sourcesize == *destsize) { + if (dest != source) + CopyMemory(dest,source,sourcesize); + return TRUE; + } + + // EXTRACT THE COMPRESSION TYPES + DWORD compressiontypes = *(LPBYTE)source; + source = (LPBYTE)source+1; + --sourcesize; + + // COUNT THE NUMBER OF OPERATIONS + DWORD operations = 0; + int loop; + for (loop = ALGORITHMS-1; loop >= 0; --loop) + if (compressiontypes & s_decompressalgorithm[loop].id) + ++operations; + + // ALLOCATE A WORK BUFFER IF NECESSARY + LPVOID work = NULL; + if ((operations >= 2) || + (BuffersOverlap(dest,source,sourcesize) && operations)) + work = ALLOC(*destsize); + + // APPLY EACH OPERATION + LPCVOID curr = source; + DWORD size = sourcesize; + for (loop = ALGORITHMS-1; loop >= 0; --loop) + if (compressiontypes & s_decompressalgorithm[loop].id) { + --operations; + + // DETERMINE WHICH BUFFER WE WILL DECOMPRESS INTO FOR THIS OPERATION + LPVOID target = (operations & 1) ? work : dest; + if (BuffersOverlap(target,curr,size)) + target = BuffersOverlap(target,work,size) ? dest : work; + + // PERFORM THE DECOMPRESSION OPERATION + DWORD targetsize = *destsize; + s_decompressalgorithm[loop].func(target, + &targetsize, + curr, + size); + curr = target; + size = targetsize; + + } + + // COPY THE FINAL RESULT TO THE DESTINATION BUFFER IF NECESSARY + if (curr != dest) + CopyMemory(dest,curr,size); + *destsize = size; + + // FREE THE WORK BUFFER + FREEIFUSED(work); + + return TRUE; +} diff --git a/Storm/SOURCE/SDLG.CPP b/Storm/SOURCE/SDLG.CPP new file mode 100644 index 0000000..02a7773 --- /dev/null +++ b/Storm/SOURCE/SDLG.CPP @@ -0,0 +1,2245 @@ +/**************************************************************************** +* +* SDLG.CPP +* Storm dialog box functions +* +* By Michael O'Brien (5/22/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define ANYBITMAP 0x0000FFFF +#define CONTROLTYPELENGTH 32 + +#define BLT_FLAG_TILED 0x00000001 +#define BLT_FLAG_LOCKSURFACE 0x00000002 +#define BLT_FLAG_DESTRECTCLIENTCOORDS 0x00000100 +#define BLT_FLAG_HIDECURSOR 0x00001000 +#define BLT_FLAG_RESTORECURSOR 0x00002000 + +#define CONVDLGX(x) (((x)*baseunitx)/4) +#define CONVDLGY(y) (((y)*baseunity)/8) + +#define NOTIFY(window,code) SendMessage(GetParent(window), \ + WM_COMMAND, \ + MAKELONG(GetDlgCtrlID(window),code), \ + (LPARAM)window) + +typedef struct _BASEFONT { + int pointsize; + int weight; + DWORD flags; + DWORD family; + char face[32]; +} BASEFONT, *BASEFONTPTR; + +NODEDECL(BITMAPREC) { + HWND window; + HWND parentwindow; + DWORD usage; + DWORD controlstyle; + LPBYTE bitmapbits; + RECT rect; + int width; + int height; + int offsetx; + int offsety; + char controltype[CONTROLTYPELENGTH]; +} *BITMAPPTR; + +NODEDECL(TIMERREC) { + HWND window; + UINT id; + DWORD elapse; + TIMERPROC callback; + DWORD lasttime; +} *TIMERPTR; + +static BASEFONTPTR s_basefont = NULL; +static LIST(BITMAPREC) s_bitmaplist; +static BOOL s_cursorhidden = FALSE; +static LPBYTE s_cursorimage = NULL; +static LPBYTE s_cursormask = NULL; +static POINT s_cursorpos = {-1,-1}; +static SIZE s_cursorsize = {32,32}; +static BOOL s_initialized = FALSE; +static int s_inpaint = 0; +static BOOL s_nodefproc = FALSE; +static LIST(TIMERREC) s_timerlist; + +static BOOL DrawButton (LPDRAWITEMSTRUCT item); +static BITMAPPTR FindBitmap (HWND window, DWORD usage); +static void IntersectRgnWithWindow (HWND updatewindow, + HRGN region, + HWND window); +static BOOL IsButton (HWND window, BOOL *ownerdraw); +static BOOL IsPointInWindow (LPPOINTS point, HWND window); +static void ParseDlgTemplate (LPCDLGTEMPLATE templatedata, + LPDLGTEMPLATE parsedtemplate, + LPCWSTR *title, + short *fontsize, + short *fontweight, + short *fontitalics, + LPCWSTR *fontname, + LPDLGITEMTEMPLATE *firstitem); +static void ParseDlgTemplateEx (LPCDLGTEMPLATE templatedata, + LPDLGTEMPLATE parsedtemplate, + LPCWSTR *title, + short *fontsize, + short *fontweight, + short *fontitalics, + LPCWSTR *fontname, + LPDLGITEMTEMPLATE *firstitem); +static LRESULT SendMessageNoDefProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam); + +//=========================================================================== +static void AdjustCursorPos (HWND window, int x, int y) { + if (window) { + DWORD processid; + GetWindowThreadProcessId(window,&processid); + if (processid == GetCurrentProcessId()) { + RECT cursorrect = {x,y,x+s_cursorsize.cx,y+s_cursorsize.cy}; + RECT windowrect; GetWindowRect(window,&windowrect); + RECT rect; + if (IntersectRect(&rect,&cursorrect,&windowrect)) { + ScreenToClient(window,(LPPOINT)&rect.left); + ScreenToClient(window,(LPPOINT)&rect.right); + InvalidateRect(window,&rect,0); + } + } + window = GetTopWindow(window); + while (window) { + AdjustCursorPos(window,x,y); + window = GetNextWindow(window,GW_HWNDNEXT); + } + } + else { + AdjustCursorPos(GetDesktopWindow(),s_cursorpos.x,s_cursorpos.y); + s_cursorpos.x = x; + s_cursorpos.y = y; + AdjustCursorPos(GetDesktopWindow(),s_cursorpos.x,s_cursorpos.y); + } +} + +//=========================================================================== +static void CheckCursorPos () { + POINT pt; + GetCursorPos(&pt); + if ((s_cursorpos.x >= 0) && + (s_cursorpos.y >= 0) && + ((pt.x != s_cursorpos.x) || + (pt.y != s_cursorpos.y))) + AdjustCursorPos((HWND)0,pt.x,pt.y); +} + +//=========================================================================== +static void ComputeBaseUnits (HFONT font, int *baseunitx, int *baseunity) { + HDC screendc = GetDC(GetDesktopWindow()); + HDC memdc = CreateCompatibleDC(screendc); + HFONT oldfont = (HFONT)SelectObject(memdc,font); + + // USE GETTEXTEXTENT() TO DETERMINE THE AVERAGE CHARACTER WIDTH + SIZE size; + if (GetTextExtentPoint32(memdc, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz", + 52, + &size)) + *baseunitx = (size.cx/26+1)/2; + + // USE GETTEXTMETRICS() TO DETERMINE THE CHARACTER HEIGHT + TEXTMETRIC tm; + if (GetTextMetrics(memdc,&tm)) + *baseunity = tm.tmHeight; + + SelectObject(memdc,oldfont); + DeleteDC(memdc); + ReleaseDC(GetDesktopWindow(),screendc); +} + +//=========================================================================== +static LRESULT CALLBACK ControlSubclassWndProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + LONG origstyle = 0; + + // PERFORM INTERNAL PROCESSING ON SOME MESSAGES + switch (message) { + + case BM_SETCHECK: + if (wparam == BST_CHECKED) + break; + // fall through to BM_SETSTATE + + case BM_SETSTATE: + case WM_PAINT: + if (IsButton(window,NULL)) { + DWORD style = GetWindowLong(window,GWL_STYLE); + if (((style & 0x0000000F) == BS_RADIOBUTTON) || + ((style & 0x0000000F) == BS_AUTORADIOBUTTON)) { + origstyle = GetWindowLong(window,GWL_STYLE); + SetWindowLong(window,GWL_STYLE,(origstyle & 0xFFFFFFF0) | BS_OWNERDRAW); + } + } + break; + + case WM_ERASEBKGND: + if ((GetWindowLong(window,GWL_EXSTYLE) & WS_EX_TRANSPARENT) || + FindBitmap(window,ANYBITMAP)) + return 0; + break; + + case WM_KEYUP: + if (wparam == VK_SNAPSHOT) { + SDrawCaptureScreen(); + SetFocus(window); + } + break; + + case WM_NCDESTROY: + RemoveProp(window,"SDlg_WndProc"); + if (GetProp(window,"SDlg_OrigStyle")) + RemoveProp(window,"SDlg_OrigStyle"); + break; + + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + SendMessage(GetParent(window),message,wparam,lparam); + break; + + } + + // CALL THE ORIGINAL WINDOW PROCEDURE + LRESULT result; + { + WNDPROC wndproc = NULL; + if (message != WM_NCDESTROY) + wndproc = (WNDPROC)GetProp(window,"SDlg_WndProc"); + if (wndproc) + result = CallWindowProc(wndproc,window,message,wparam,lparam); + else + result = DefWindowProc(window,message,wparam,lparam); + } + + if (origstyle) + SetWindowLong(window,GWL_STYLE,origstyle); + return result; +} + +//=========================================================================== +static LRESULT CALLBACK ControlStaticWndProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_DESTROY: + RemoveProp(window,"SDlg_Font"); + break; + + case WM_ERASEBKGND: + if ((GetWindowLong(window,GWL_EXSTYLE) & WS_EX_TRANSPARENT) || + FindBitmap(window,ANYBITMAP)) + return 0; + break; + + case WM_GETFONT: + return (LRESULT)GetProp(window,"SDlg_Font"); + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC dc = SDlgBeginPaint(window,&ps); + + // SELECT THE FONT + SelectObject(dc,(HFONT)GetProp(window,"SDlg_Font")); + SetBkMode(dc,TRANSPARENT); + + // SEND A WM_DRAWITEM MESSAGE, IN CASE THE APPLICATION WANTS TO + // DRAW THE TEXT MANUALLY + BOOL drawn = 0; + { + DRAWITEMSTRUCT drawitem; + ZeroMemory(&drawitem,sizeof(DRAWITEMSTRUCT)); + drawitem.CtlType = ODT_STATIC; + drawitem.CtlID = GetDlgCtrlID(window); + drawitem.itemAction = ODA_DRAWENTIRE; + drawitem.hwndItem = window; + drawitem.hDC = dc; + GetClientRect(window,&drawitem.rcItem); + drawn = (BOOL)SendMessageNoDefProc(GetParent(window), + WM_DRAWITEM, + GetDlgCtrlID(window), + (LPARAM)&drawitem); + } + + // IF THE APPLICATION DIDN'T DRAW THE TEXT, DO IT OURSELF + if (!drawn) { + int chars = GetWindowTextLength(window); + char *text = (char *)ALLOC(chars+1); + GetWindowText(window,text,chars+1); + + // DETERMINE THE FORMAT + DWORD format = DT_EXPANDTABS | DT_WORDBREAK; + { + DWORD style = (DWORD)GetWindowLong(window,GWL_STYLE); + if (style & SS_LEFT) + format |= DT_LEFT; + else if (style & SS_CENTER) + format |= DT_CENTER; + else if (style & SS_RIGHT) + format |= DT_RIGHT; + } + + // DRAW THE DROP SHADOW + { + RECT rect; + GetClientRect(window,&rect); + ++rect.left; + ++rect.top; + SetTextColor(dc,0); + DrawText(dc,text,chars,&rect,format); + } + + // DRAW THE TEXT + { + RECT rect; + GetClientRect(window,&rect); + --rect.right; + --rect.bottom; + SetTextColor(dc,0xFFFFFF); + SendMessage(GetParent(window),WM_CTLCOLORSTATIC,(WPARAM)dc,(LPARAM)window); + DrawText(dc,text,chars,&rect,format); + } + + FREE(text); + } + + SDlgEndPaint(window,&ps); + } + return 0; + + case WM_SETFONT: + SetProp(window,"SDlg_Font",(HANDLE)wparam); + if (lparam & 1) + InvalidateRect(window,NULL,1); + break; + + case WM_SETTEXT: + LRESULT r = DefWindowProc(window, message, wparam, lparam); + InvalidateRect(window, NULL, TRUE); + UpdateWindow(window); + return r; + + } + return DefWindowProc(window,message,wparam,lparam); +} + +//=========================================================================== +static void DeleteBitmaps (HWND window) { + + // DELETE ALL BITMAPS ASSOCIATED WITH THIS WINDOW + ITERATELIST(BITMAPREC,s_bitmaplist,curr) + if ((curr->window == window) || + (curr->parentwindow == window)) + ITERATE_DELETE; + + // RECURSE ALL CHILD WINDOWS + if ((window = GetTopWindow(window)) != (HWND)0) + do + DeleteBitmaps(window); + while ((window = GetNextWindow(window,GW_HWNDNEXT)) != (HWND)0); + +} + +//=========================================================================== +static BOOL CALLBACK DlgProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + + // PERFORM INTERNAL PROCESSING ON SOME MESSAGES + switch (message) { + + case WM_CREATE: + SetCursor(LoadCursor(0,IDC_ARROW)); + break; + + case WM_DESTROY: + RemoveProp(window,"SDlg_Font"); + DeleteBitmaps(window); + break; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT item = (LPDRAWITEMSTRUCT)lparam; + if (item->CtlType == ODT_BUTTON) + return DrawButton(item); + } + break; + + case WM_ERASEBKGND: + if ((GetWindowLong(window,GWL_EXSTYLE) & WS_EX_TRANSPARENT) || + FindBitmap(window,ANYBITMAP)) + return 0; + break; + + case WM_GETFONT: + return (LRESULT)GetProp(window,"SDlg_Font"); + + case WM_NCDESTROY: + { + HDC dc = GetDC(window); + SelectObject(dc,GetStockObject(SYSTEM_FONT)); + ReleaseDC(window,dc); + } + DeleteObject((HFONT)SendMessage(window,WM_GETFONT,0,0)); + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC dc = SDlgBeginPaint(window,&ps); + SDlgEndPaint(window,&ps); + } + if ((GetProp(window,"SDlg_Modal")) && + IsWindowEnabled(GetParent(window))) { + EnableWindow(GetParent(window),0); + if (GetActiveWindow() == GetParent(window)) + SetActiveWindow(window); + } + return 0; + + case WM_SETFONT: + SetProp(window,"SDlg_Font",(HANDLE)wparam); + break; + + case WM_SHOWWINDOW: + if ((!wparam) && + ((!lparam) || + (lparam == SW_PARENTCLOSING)) && + (GetProp(window,"SDlg_Modal"))) + EnableWindow(GetParent(window),1); + break; + + } + + // CALL THE DEFAULT DIALOG BOX PROCEDURE, WHICH WILL CALL THE + // APPLICATION'S DIALOG BOX PROCEDURE + BOOL result; + if (s_nodefproc) { + s_nodefproc = 0; + result = CallWindowProc((WNDPROC)GetWindowLong(window,DWL_DLGPROC),window,message,wparam,lparam); + } + else + result = DefDlgProc(window,message,wparam,lparam); + + // ON A WM_NCCREATE MESSAGE, SET THE POINTER TO THE APPLICATION'S + // DIALOG BOX PROCEDURE + if (message == WM_NCCREATE) + SetWindowLong(window,DWL_DLGPROC,(LONG)((LPCREATESTRUCT)lparam)->lpCreateParams); + + return result; +} + +//=========================================================================== +static BOOL DoMessageLoop (HWND dialogwindow) { + MSG message; + if (PeekMessage(&message,(HWND)0,0,0,PM_REMOVE)) { + if (message.message == WM_QUIT) + PostQuitMessage(message.wParam); + else if ((!dialogwindow) || + (!IsDialogMessage(dialogwindow,&message))) { + TranslateMessage(&message); + DispatchMessage(&message); + } + return TRUE; + } + else { + SDlgCheckTimers(); + SDlgUpdateCursor(); + return FALSE; + } +} + +//=========================================================================== +static BOOL DrawButton (LPDRAWITEMSTRUCT item) { + RECT clientrect; GetClientRect(item->hwndItem,&clientrect); + HDC dc = GetDC(item->hwndItem); + BOOL selected = ((item->itemState & ODS_SELECTED) != 0); + if (SendMessage(item->hwndItem,BM_GETSTATE,0,0) & BST_CHECKED) + selected = TRUE; + BOOL grayed = ((item->itemState & (ODS_DISABLED | ODS_GRAYED)) != 0); + DWORD style = (DWORD)GetWindowLong(item->hwndItem,GWL_STYLE); + if (GetProp(item->hwndItem,"SDlg_OrigStyle")) + style = (DWORD)GetProp(item->hwndItem,"SDlg_OrigStyle"); + BOOL pushbutton = ((style & 0x0000000F) == BS_PUSHBUTTON) || + ((style & 0x0000000F) == BS_DEFPUSHBUTTON) || + ((style & 0x0000000F) == BS_OWNERDRAW); + + // DETERMINE THE BOUNDING OFFSET + RECT boundingoffset = {0,0,0,0}; + if (!pushbutton) { + boundingoffset.left = 1; + boundingoffset.bottom = -1; + } + + // IF A BITMAP HAS BEEN REGISTERED SPECIFICALLY FOR THIS ITEM STATE, + // DRAW THAT + DWORD usage = selected + ? grayed + ? SDLG_USAGE_SELECTED_GRAYED + : (item->itemState & ODS_FOCUS) + ? SDLG_USAGE_SELECTED_FOCUSED + : SDLG_USAGE_SELECTED_UNFOCUSED + : grayed + ? SDLG_USAGE_NORMAL_GRAYED + : (item->itemState & ODS_FOCUS) + ? SDLG_USAGE_NORMAL_FOCUSED + : SDLG_USAGE_NORMAL_UNFOCUSED; + BITMAPPTR bitmap = FindBitmap(item->hwndItem,usage); + if (bitmap) + SDlgDrawBitmap(item->hwndItem, + usage, + (HRGN)0, + 0, + 0, + &boundingoffset, + pushbutton ? (SDLG_DBF_TILE | SDLG_DBF_VCENTER) : 0); + + // OTHERWISE, ERASE THE BACKGROUND AND DRAW A BEVEL AROUND IT + else { + SDlgDrawBitmap(item->hwndItem, + SDLG_USAGE_BACKGROUND, + (HRGN)0, + 1-selected, + 1-selected, + &boundingoffset, + pushbutton ? (SDLG_DBF_TILE | SDLG_DBF_VCENTER) : 0); + if (pushbutton) { + UINT edge = selected ? (BDR_SUNKENINNER | BDR_SUNKENOUTER) + : (BDR_RAISEDOUTER | BDR_RAISEDOUTER); + DrawEdge(dc,&clientrect,edge,BF_RECT); + } + } + + // DRAW THE TEXT + { + + // GET THE TEXT + int chars = GetWindowTextLength(item->hwndItem); + char *text = (char *)ALLOC(chars+1); + GetWindowText(item->hwndItem,text,chars+1); + + // SELECT THE FONT + SelectObject(dc,GetCurrentObject(item->hDC,OBJ_FONT)); + SetTextAlign(dc,TA_TOP | TA_LEFT); + SetBkMode(dc,TRANSPARENT); + + // DETERMINE THE TEXT LOCATION + RECT rect = {clientrect.left +3, + clientrect.top +3, + clientrect.right -1, + clientrect.bottom-1}; + if (pushbutton) { + DWORD style = (DWORD)GetWindowLong(item->hwndItem,GWL_STYLE); + SIZE size = {16,16}; + GetTextExtentPoint32(dc,"~,_Oy",5,&size); + if (style & BS_BOTTOM) + rect.top += rect.bottom-(size.cy+6); + else if ((style & BS_VCENTER) || !(style & BS_TOP)) + rect.top += (rect.bottom-(rect.top+size.cy))/2+1; + if (selected) { + ++rect.left; + ++rect.top; + ++rect.right; + ++rect.bottom; + } + } + else if (bitmap) { + rect.top -= 1; + rect.left += 6+bitmap->rect.right-bitmap->rect.left; + } + + // DRAW THE DROP SHADOW + SetTextColor(dc,0); + DrawText(dc,text,chars,&rect, + (pushbutton ? DT_CENTER : DT_LEFT) | DT_TOP); + + // DRAW THE TEXT + --rect.left; + --rect.top; + --rect.right; + --rect.bottom; + SetTextColor(dc,grayed ? 0x808080 : 0xFFFFFF); + DrawText(dc,text,chars,&rect, + (pushbutton ? DT_CENTER : DT_LEFT) | DT_TOP); + + FREE(text); + } + + // IF THIS IS A PUSHBUTTON, DRAW THE FOCUS RECTANGLE + if (pushbutton && + (item->itemState & ODS_FOCUS) && + !FindBitmap(item->hwndItem,SDLG_USAGE_NORMAL_FOCUSED | SDLG_USAGE_SELECTED_FOCUSED)) { + RECT rect = {clientrect.left +selected+4, + clientrect.top +selected+4, + clientrect.right +selected-3, + clientrect.bottom+selected-3}; + DrawFocusRect(dc,&rect); + } + + ReleaseDC(item->hwndItem,dc); + return TRUE; +} + +//=========================================================================== +static BITMAPPTR FindBitmap (HWND window, DWORD usage) { + + // FIND THE BITMAP FOR THIS WINDOW + BITMAPPTR curr = s_bitmaplist.Head(); + while (curr && + ((curr->window != window) || + (!(curr->usage & usage)))) + curr = curr->Next(); + + // IF THIS WINDOW DOESN'T HAVE ITS OWN BITMAP, FIND THE DEFAULT + // BITMAP FOR THIS CONTROL TYPE AND STYLE + if (!curr) { + HWND parentwindow = GetParent(window); + char classname[256] = ""; + GetClassName(window,classname,256); + LPCTSTR classnameptr = classname; + if (!_strnicmp(classnameptr,"SDlg",4)) + classnameptr += 4; + DWORD style = (DWORD)GetWindowLong(window,GWL_STYLE); + if (GetProp(window,"SDlg_OrigStyle")) + style = (DWORD)GetProp(window,"SDlg_OrigStyle"); + curr = s_bitmaplist.Head(); + while (curr && + (curr->window || + (curr->parentwindow && (curr->parentwindow != parentwindow)) || + (!(usage & curr->usage)) || + ((style & 0x0000000F) & ~curr->controlstyle) || + ((!(curr->controlstyle & 0x00010000)) && + ((style & curr->controlstyle) != curr->controlstyle)) || + _stricmp(curr->controltype,classnameptr))) + curr = curr->Next(); + } + + return curr; +} + +//=========================================================================== +static LPCDLGTEMPLATE GetTemplateData (HINSTANCE instance, + LPCTSTR templatename) { + HRSRC resourcehandle = FindResource(instance,templatename,RT_DIALOG); + if (!resourcehandle) + return NULL; + HGLOBAL resourcedata = LoadResource(instance,resourcehandle); + if (!resourcedata) + return NULL; + return (LPCDLGTEMPLATE)LockResource(resourcedata); +} + +//=========================================================================== +static BOOL InitializeDialogManager () { + s_initialized = TRUE; + + // REGISTER OUR OWN DIALOG BOX CLASS + { + WNDCLASS wndclass; + ZeroMemory(&wndclass,sizeof(WNDCLASS)); + wndclass.style = CS_DBLCLKS; + wndclass.lpfnWndProc = (WNDPROC)DlgProc; + wndclass.cbWndExtra = DLGWINDOWEXTRA; + wndclass.hInstance = (HINSTANCE)GetModuleHandle(NULL); + wndclass.hCursor = LoadCursor(0,IDC_ARROW); + wndclass.lpszClassName = "SDlgDialog"; + if (!RegisterClass(&wndclass)) + return FALSE; + } + + // REGISTER OUR OWN STATIC CONTROL CLASS + { + WNDCLASS wndclass; + ZeroMemory(&wndclass,sizeof(WNDCLASS)); + GetClassInfo((HINSTANCE)GetModuleHandle(NULL),"Static",&wndclass); + wndclass.lpfnWndProc = (WNDPROC)ControlStaticWndProc; + wndclass.hInstance = (HINSTANCE)GetModuleHandle(NULL); + wndclass.hCursor = LoadCursor(0,IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); + wndclass.lpszClassName = "SDlgStatic"; + if (!RegisterClass(&wndclass)) + return FALSE; + } + + return TRUE; +} + +//=========================================================================== +static BOOL InternalBltClippedToRgn (LPBYTE dest, + LPRECT destrect, + LPSIZE destsize, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + LPSIZE sourcesize, + int sourcepitch, + int sourceoffsetx, + int sourceoffsety, + DWORD pattern, + DWORD rop3, + LPPOINT clientpos, + HRGN region, + DWORD flags, + int surfacenumber, + int *cursorhidden) { + + // RETRIEVE A LIST OF RECTANGLES THAT MAKE UP THE CLIPPING REGION + LPRGNDATA data; + DWORD numrects; + LPRECT rectarray; + { + DWORD bytes = GetRegionData(region,0,NULL); + data = (LPRGNDATA)ALLOC(bytes); + GetRegionData(region,bytes,data); + numrects = data->rdh.nCount; + rectarray = (LPRECT)&data->Buffer[0]; + } + + // VERIFY THAT WE HAVE AT LEAST ONE RECTANGLE TO DRAW + if (!(numrects && rectarray)) { + if (data) + FREE(data); + return TRUE; + } + + // MODIFY THE RECTANGLES SO THAT THEY ARE IN SCREEN COORDINATES, THEN CLIP + // THEM AGAINST THE BOUNDING RECTANGLE. + { + for (DWORD loop = 0; loop < numrects; ++loop) { + (rectarray+loop)->left = max(destrect->left ,(rectarray+loop)->left +clientpos->x); + (rectarray+loop)->top = max(destrect->top ,(rectarray+loop)->top +clientpos->y); + (rectarray+loop)->right = min(destrect->right ,(rectarray+loop)->right +clientpos->x); + (rectarray+loop)->bottom = min(destrect->bottom,(rectarray+loop)->bottom+clientpos->y); + } + } + + // IF THE SYSTEM CURSOR IS VISIBLE AND IS WITHIN ONE OF THE RECTANGLES, + // AND WE ARE PROTECTING IT, THEN HIDE IT + int hidden = 0; + if (flags & BLT_FLAG_HIDECURSOR) { + POINT cursor; + GetCursorPos(&cursor); + for (DWORD loop = 0; loop < numrects; ++loop) + if ((cursor.x+32 >= (rectarray+loop)->left) && + (cursor.y+32 >= (rectarray+loop)->top) && + (cursor.x-32 <= (rectarray+loop)->right) && + (cursor.y-32 <= (rectarray+loop)->bottom)) { + do + ++hidden; + while (ShowCursor(0) >= 0); + break; + } + GdiFlush(); + } + + // IF NECESSARY, LOCK THE SURFACE + if (flags & BLT_FLAG_LOCKSURFACE) + SDrawLockSurface(surfacenumber,NULL,&dest,&destpitch); + + // PAINT THE REGION WITH THE SELECTED BITMAP, TILING IT IF NECESSARY + if (dest && destpitch) { + for (DWORD loop = 0; loop < numrects; ++loop) { + if (flags & BLT_FLAG_TILED) + SBltROP3Tiled(dest, + rectarray+loop, + destpitch, + source, + sourcerect, + sourcepitch, + (rectarray+loop)->left+sourceoffsetx-clientpos->x, + (rectarray+loop)->top +sourceoffsety-clientpos->y, + pattern, + rop3); + else { + RECT offsetsourcerect = {sourcerect->left, + sourcerect->top, + sourcerect->right, + sourcerect->bottom}; + offsetsourcerect.left += (rectarray+loop)->left+sourceoffsetx-destrect->left; + offsetsourcerect.top += (rectarray+loop)->top +sourceoffsety-destrect->top; + SBltROP3Clipped(dest, + rectarray+loop, + NULL, + destpitch, + source, + &offsetsourcerect, + sourcesize, + sourcepitch, + pattern, + rop3); + } + } + } + + // IF NECESSARY, UNLOCK THE SURFACE + if (flags & BLT_FLAG_LOCKSURFACE) + SDrawUnlockSurface(surfacenumber,dest,numrects,rectarray); + + // IF WE HID THE CURSOR, UNHIDE IT + if (flags & BLT_FLAG_RESTORECURSOR) + if (hidden) + do + ShowCursor(1); + while (--hidden); + if (cursorhidden) + *cursorhidden += hidden; + + // FREE THE LIST OF RECTANGLES + FREE(data); + + return TRUE; +} + +//=========================================================================== +static BOOL InternalBltClippedToWindow (LPBYTE dest, + LPRECT destrect, + LPSIZE destsize, + int destpitch, + LPBYTE source, + LPRECT sourcerect, + LPSIZE sourcesize, + int sourcepitch, + int sourceoffsetx, + int sourceoffsety, + DWORD pattern, + DWORD rop3, + HWND window, + HRGN region, + DWORD flags, + int surfacenumber, + int *cursorhidden) { + if (cursorhidden) + *cursorhidden = 0; + + VALIDATEBEGIN; + VALIDATE(destrect); + VALIDATE(window); + VALIDATEEND; + + if (!((flags & BLT_FLAG_LOCKSURFACE) || (dest && (destpitch > 0)))) + return FALSE; + + // INTERSECT THE DESTINATION RECTANGLE WITH THE DESTINATION SIZE + RECT moddestrect = {destrect->left,destrect->top,destrect->right,destrect->bottom}; + if (destsize) { + if ((moddestrect.right-moddestrect.left) > destsize->cx) + moddestrect.right = moddestrect.left+destsize->cx; + if ((moddestrect.bottom-moddestrect.top) > destsize->cy) + moddestrect.bottom = sourcerect->bottom+destsize->cy; + } + + // IF WE'RE NOT TILING, INTERSECT THE DESTINATION RECTANGLE WITH THE + // SOURCE SIZE + if (sourcerect && !(flags & BLT_FLAG_TILED)) { + if ((moddestrect.right-moddestrect.left) > (sourcerect->right-sourcerect->left)) + moddestrect.right = sourcerect->right+moddestrect.left-sourcerect->left; + if ((moddestrect.bottom-moddestrect.top) > (sourcerect->bottom-sourcerect->top)) + moddestrect.bottom = sourcerect->bottom+moddestrect.top-sourcerect->top; + } + + // GET THE TARGET WINDOW'S CLIENT RECTANGLE, IN SCREEN COORDINATES + RECT boundingrect; + GetClientRect(window,&boundingrect); + ClientToScreen(window,(LPPOINT)&boundingrect.left); + ClientToScreen(window,(LPPOINT)&boundingrect.right); + POINT clientpos = {boundingrect.left,boundingrect.top}; + + // IF NECESSARY, CONVERT THE DESTINATION RECTANGLE TO SCREEN COORDINATES + if (flags & BLT_FLAG_DESTRECTCLIENTCOORDS) { + moddestrect.left += clientpos.x; + moddestrect.top += clientpos.y; + moddestrect.right += clientpos.x; + moddestrect.bottom += clientpos.y; + } + + // INTERSECT THE CLIENT RECTANGLE WITH THE DESTINATION RECTANGLE + { + RECT intersectrect = {moddestrect.left, + moddestrect.top, + moddestrect.right, + moddestrect.bottom}; + IntersectRect(&boundingrect,&boundingrect,&intersectrect); + } + + // IF THE RESULTING RECTANGLE IS COMPLETELY CLIPPED OUT, RETURN WITHOUT + // ATTEMPTING TO DRAW + if ((boundingrect.right <= boundingrect.left) || + (boundingrect.bottom <= boundingrect.top)) + return 1; + + // CREATE A CLIPPING REGION THAT INITIALLY CONTAINS THE INTERSECTION OF + // THE REGION WE WERE PASSED (IF ANY) WITH THE CLIENT AREA OF THIS WINDOW + HRGN clipregion; + { + RECT clientrect; + GetClientRect(window,&clientrect); + clipregion = CreateRectRgn(clientrect.left, + clientrect.top, + clientrect.right, + clientrect.bottom); + if (!clipregion) + return FALSE; + if (region) + CombineRgn(clipregion,clipregion,region,RGN_AND); + } + + // REMOVE FROM THE CLIPPING REGION THOSE PORTIONS OF THE WINDOW COVERED BY + // OTHER OVERLAPPING, NON-TRANSPARENT WINDOWS + { + IntersectRgnWithWindow(window,clipregion,window); + HWND startwindow = window; + do { + HWND sibling = startwindow; + while ((sibling = GetNextWindow(sibling,GW_HWNDPREV)) != (HWND)0) + IntersectRgnWithWindow(window,clipregion,sibling); + if (GetWindowLong(startwindow,GWL_STYLE) & WS_CHILD) + startwindow = GetParent(startwindow); + else + startwindow = (HWND)0; + } while (startwindow && (startwindow != GetDesktopWindow())); + } + + // DETERMINE WHETHER WE'RE DISPLAYING A CUSTOM CURSOR + BOOL customcursor = (s_cursormask && s_cursorimage && + (s_cursorpos.x >= 0) && (s_cursorpos.y >= 0)); + + // SPLIT THE CLIPPING REGION INTO TWO DIFFERENT REGIONS: ONE THAT CONTAINS + // ONLY THE PORTION OF THE REGION WHICH IS COVERED BY THE CURSOR, AND ONE + // THAT CONTAINS EVERYTHING THAT IS NOT COVERED BY THE CURSOR + HRGN cursorregion; + if (customcursor) { + cursorregion = CreateRectRgn(s_cursorpos.x-clientpos.x, + s_cursorpos.y-clientpos.y, + s_cursorpos.x+s_cursorsize.cx-clientpos.x, + s_cursorpos.y+s_cursorsize.cy-clientpos.y); + HRGN normalregion = CreateRectRgn(0,0,1,1); + CombineRgn(normalregion,clipregion,cursorregion,RGN_DIFF); + CombineRgn(cursorregion,clipregion,cursorregion,RGN_AND); + DeleteObject(clipregion); + clipregion = normalregion; + } + + // BLT THE NON-CURSOR REGION ONTO THE SCREEN + InternalBltClippedToRgn(dest, + &boundingrect, + destsize, + destpitch, + source, + sourcerect, + sourcesize, + sourcepitch, + sourceoffsetx, + sourceoffsety, + pattern, + rop3, + &clientpos, + clipregion, + flags, + surfacenumber, + cursorhidden); + DeleteObject(clipregion); + + // IF WE'RE DISPLAYING A CUSTOM CURSOR THEN PROCESS THE CURSOR REGION + if (customcursor) { + + // ALLOCATE AN OFFSCREEN BUFFER TO HOLD THE COMPOSITE IMAGE + LPBYTE compositebuffer = (LPBYTE)ALLOC(s_cursorsize.cx*s_cursorsize.cy); + RECT cursorrect = {0,0,s_cursorsize.cx,s_cursorsize.cy}; + + // BLT THE CURSOR REGION ONTO THE OFFSCREEN BUFFER + POINT offset = {clientpos.x-s_cursorpos.x, + clientpos.y-s_cursorpos.y}; + InternalBltClippedToRgn(compositebuffer, + &cursorrect, + &s_cursorsize, + s_cursorsize.cx, + source, + sourcerect, + sourcesize, + sourcepitch, + sourceoffsetx, + sourceoffsety, + pattern, + rop3, + &offset, + cursorregion, + flags & BLT_FLAG_TILED, + surfacenumber, + NULL); + + // DRAW THE CURSOR ONTO THE OFFSCREEN BUFFER + SBltROP3(compositebuffer, + s_cursormask, + s_cursorsize.cx, + s_cursorsize.cy, + s_cursorsize.cx, + s_cursorsize.cx, + 0, + SRCAND); + SBltROP3(compositebuffer, + s_cursorimage, + s_cursorsize.cx, + s_cursorsize.cy, + s_cursorsize.cx, + s_cursorsize.cx, + 0, + SRCPAINT); + + // BLT THE OFFSCREEN BUFFER ONTO THE SCREEN + boundingrect.left = s_cursorpos.x; + boundingrect.top = s_cursorpos.y; + InternalBltClippedToRgn(dest, + &boundingrect, + destsize, + destpitch, + compositebuffer, + &cursorrect, + &s_cursorsize, + s_cursorsize.cx, + 0, + 0, + 0, + SRCCOPY, + &clientpos, + cursorregion, + flags & ~BLT_FLAG_TILED, + surfacenumber, + cursorhidden); + DeleteObject(cursorregion); + + // FREE THE OFFSCREEN BUFFER + FREE(compositebuffer); + + } + + return TRUE; +} + +//=========================================================================== +static HWND InternalCreateDialogBox (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam) { + + // IF NO PARENT WINDOW WAS GIVEN, THEN USE THE APPLICATION'S FRAME WINDOW + // AS THE PARENT. IT'S IMPORTANT TO HAVE A PARENT WINDOW BECAUSE IF + // WE CREATE A NEW TOP-LEVEL WINDOW WHILE A DIRECTDRAW APPLICATION IS + // ACTIVE IN EXCLUSIVE MODE, THE DIRECTDRAW APPLICATION WILL BE MINIMIZED. + HWND framewindow = SDrawGetFrameWindow(); + if (!parentwindow) + parentwindow = framewindow; + + // PARSE THE TEMPLATE + BOOL extendedformat = 0; + LPCWSTR title; + short fontsize; + short fontweight; + short fontitalics; + LPCWSTR fontname; + LPDLGITEMTEMPLATE firstitem; + DLGTEMPLATE parsedtemplate; + if (templatedata->style == 0xFFFF0001) { + extendedformat = 1; + ParseDlgTemplateEx(templatedata, + &parsedtemplate, + &title, + &fontsize, + &fontweight, + &fontitalics, + &fontname, + &firstitem); + } + else + ParseDlgTemplate(templatedata, + &parsedtemplate, + &title, + &fontsize, + &fontweight, + &fontitalics, + &fontname, + &firstitem); + + // CONVERT THE TITLE AND FONT NAME TO ANSI + char ansititle[256] = ""; + char ansifontname[256] = ""; + if (title && *title && (*title != 0xFFFF)) + wcstombs(ansititle,title,255); + if (fontname && *fontname && (*fontname != 0xFFFF)) + wcstombs(ansifontname,fontname,255); + + // CREATE A FONT FOR THE DIALOG BOX CONTROLS. WE USE A HARD-CODED VALUE OF + // 96 VERTICAL PIXELS PER LOGICAL INCH INSTEAD OF QUERYING THE DEVICE CAPS + // BECAUSE WE WANT OUR DIALOG BOXES TO LOOK EXACTLY THE SAME ON ALL + // DISPLAYS. + HFONT font = (HFONT)0; + if (ansifontname[0]) + if (s_basefont) + font = CreateFont(-MulDiv(s_basefont->pointsize,96,72),0,0,0, + s_basefont->weight,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + DEFAULT_PITCH | s_basefont->family, + s_basefont->face); + else + font = CreateFont(-MulDiv(fontsize,96,72),0,0,0,fontweight,fontitalics,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + DEFAULT_PITCH | FF_DONTCARE,ansifontname); + + // VERIFY THAT THE FONT WE CREATED WAS A TRUETYPE FONT, BECAUSE ONLY + // TRUETYPE FONTS BE SIZED THE SAME ON ALL SYSTEMS. IF THE FONT ISN'T A + // TRUETYPE FONT, DESTROY IT AND CREATE A DEFAULT TRUETYPE FONT. + if (font) { + BOOL truetype; + { + HDC parentdc = GetDC(parentwindow); + HDC memdc = CreateCompatibleDC(parentdc); + HFONT oldfont = (HFONT)SelectObject(memdc,font); + TEXTMETRIC tm; + ZeroMemory(&tm,sizeof(TEXTMETRIC)); + GetTextMetrics(memdc,&tm); + truetype = ((tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0); + SelectObject(memdc,oldfont); + DeleteDC(memdc); + ReleaseDC(parentwindow,parentdc); + } + if (!truetype) { + DeleteObject(font); + if (s_basefont) + font = CreateFont(-MulDiv(s_basefont->pointsize,96,72),0,0,0, + s_basefont->weight,0,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + DEFAULT_PITCH | FF_SWISS,"Arial"); + else + font = CreateFont(-MulDiv(fontsize,96,72),0,0,0,fontweight,fontitalics,0,0,ANSI_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + DEFAULT_PITCH | FF_SWISS,"Arial"); + } + } + + // DETERMINE THE FONT'S AVERAGE CHARACTER SIZE, WHICH WE USE FOR CONVERTING + // DIALOG UNITS TO SCREEN COORDINATES + int baseunitx = 8; + int baseunity = 16; + if (font) + ComputeBaseUnits(font,&baseunitx,&baseunity); + + // DETERMINE THE WINDOW STYLE + DWORD windowstyle = parsedtemplate.style & ~WS_VISIBLE; + DWORD windowexstyle = parsedtemplate.dwExtendedStyle + | WS_EX_CONTROLPARENT + | ((windowstyle & DS_MODALFRAME) ? WS_EX_DLGMODALFRAME + : 0); + + // DETERMINE THE WINDOW POSITION + RECT windowrect = {CONVDLGX(parsedtemplate.x), + CONVDLGY(parsedtemplate.y), + CONVDLGX(parsedtemplate.x)+CONVDLGX(parsedtemplate.cx)-1, + CONVDLGY(parsedtemplate.y)+CONVDLGY(parsedtemplate.cy)-1}; + AdjustWindowRectEx(&windowrect,windowstyle & 0xFFFF0000,0,windowexstyle); + int screencx; + int screency; + SDrawGetScreenSize(&screencx,&screency); + int windowcx = windowrect.right+1-windowrect.left; + int windowcy = windowrect.bottom+1-windowrect.top; + int windowx = (windowstyle & DS_CENTER) ? ((screencx-windowcx) >> 1) + : CONVDLGX(parsedtemplate.x); + int windowy = (windowstyle & DS_CENTER) ? ((screency-windowcy) >> 1) + : CONVDLGY(parsedtemplate.y); + windowx = max(0,min(windowx,screencx-windowcx)); + windowy = max(0,min(windowy,screency-windowcy)); + + // IF THE APPLICATION'S FRAME WINDOW IS MINIMIZED, RESTORE IT + { + if (framewindow && IsIconic(framewindow)) { + ShowWindow(framewindow,SW_SHOWMAXIMIZED); + while (DoMessageLoop((HWND)0)) + ; + SetActiveWindow(parentwindow); + SetFocus(parentwindow); + } + } + + // CREATE THE DIALOG BOX WINDOW + HWND dialogwindow = CreateWindowEx(windowexstyle, + "SDlgDialog", + ansititle, + windowstyle, + windowx, + windowy, + windowcx, + windowcy, + parentwindow, + (HMENU)0, + instance, + dialogproc); + if (!dialogwindow) + return dialogwindow; + + // SELECT THE FONT INTO THE DIALOG WINDOW + { + HDC dc = GetDC(dialogwindow); + SelectObject(dc,font); + ReleaseDC(dialogwindow,dc); + } + + // SET THE DEFAULT RETURN VALUE + SetProp(dialogwindow,"SDlg_EndDialog",(HANDLE)0); + SetProp(dialogwindow,"SDlg_EndResult",(HANDLE)0); + + // CREATE THE CONTROLS + HWND focuswindow = dialogwindow; + { + LPDLGITEMTEMPLATE itemdata = firstitem; + for (int itemnum = 0; itemnum < parsedtemplate.cdit; ++itemnum) { + + // ADVANCE TO THE NEXT DOUBLEWORD BOUNDARY + { + int misaligned = ((LPBYTE)itemdata-(LPBYTE)templatedata) & 3; + if (misaligned) + itemdata = (LPDLGITEMTEMPLATE)(((LPBYTE)itemdata)+4-misaligned); + } + + // PARSE THE CONTROL TEMPLATE + if (extendedformat) + itemdata = (LPDLGITEMTEMPLATE)(((LPBYTE)itemdata)+sizeof(DWORD)); + LPCWSTR controlclassname = (LPCWSTR)(itemdata+1); + if (extendedformat) + ++controlclassname; + LPCWSTR controltitle; + LPCVOID controldata; + if (*controlclassname == 0xFFFF) + controltitle = controlclassname+2; + else + controltitle = controlclassname+wcslen(controlclassname)+1; + if (*controltitle == 0xFFFF) + controldata = controltitle+3; + else + controldata = controltitle+wcslen(controltitle)+2; + + // CONVERT THE CLASS NAME AND TITLE TO ANSI + char ansicontrolclassname[256] = ""; + char ansicontroltitle[256] = ""; + if (*controlclassname == 0xFFFF) + switch (*(controlclassname+1)) { + case 0x0080: SStrCopy(ansicontrolclassname,"Button" ,256); break; + case 0x0081: SStrCopy(ansicontrolclassname,"Edit" ,256); break; + case 0x0082: SStrCopy(ansicontrolclassname,"SDlgStatic",256); break; + case 0x0083: SStrCopy(ansicontrolclassname,"Listbox" ,256); break; + case 0x0084: SStrCopy(ansicontrolclassname,"Scrollbar" ,256); break; + case 0x0085: SStrCopy(ansicontrolclassname,"Combobox" ,256); break; + } + else + wcstombs(ansicontrolclassname,controlclassname,255); + if (*controltitle != 0xFFFF) + wcstombs(ansicontroltitle,controltitle,255); + + // CREATE THE CONTROL WINDOW + DWORD style = extendedformat ? itemdata->dwExtendedStyle : itemdata->style; + DWORD exstyle = extendedformat ? itemdata->style : itemdata->dwExtendedStyle; + HWND window = CreateWindowEx(exstyle, + ansicontrolclassname, + ansicontroltitle, + style, + CONVDLGX(itemdata->x), + CONVDLGY(itemdata->y), + CONVDLGX(itemdata->cx), + CONVDLGY(itemdata->cy), + dialogwindow, + (HMENU)itemdata->id, + instance, + (LPVOID)controldata); + + // SUBCLASS THE CONTROL, SET ITS INTERNAL PROPERTIES, THEN SHOW IT + SetProp(window,"SDlg_WndProc",(HANDLE)GetWindowLong(window,GWL_WNDPROC)); + SetWindowLong(window,GWL_WNDPROC,(LONG)ControlSubclassWndProc); + if (window && font) + SendMessage(window,WM_SETFONT,(WPARAM)font,0); + ShowWindow(window,SW_SHOW); + + // DETERMINE WHETHER THIS CONTROL SHOULD RECEIVE THE KEYBOARD FOCUS + if (window && + (focuswindow == dialogwindow) && + (!(itemdata->style & WS_DISABLED)) && + _stricmp(ansicontrolclassname,"Static") && + _stricmp(ansicontrolclassname,"SDlgStatic")) + focuswindow = window; + + itemdata = (LPDLGITEMTEMPLATE)(((LPBYTE)controldata)+*((LPWORD)controldata-1)); + } + } + + // SEND THE WM_SETFONT MESSAGE + if (font) + SendMessage(dialogwindow,WM_SETFONT,(WPARAM)font,0); + + // SEND THE WM_INITDIALOG MESSAGE + if (!SendMessage(dialogwindow,WM_INITDIALOG,(WPARAM)focuswindow,initparam)) + focuswindow = (HWND)0; + + // TURN ON THE OWNER DRAW STYLE FOR ANY CONTROLS FOR WHICH WE HAVE TEXTURES + { + HWND window = GetTopWindow(dialogwindow); + while (window) { + if (FindBitmap(window,ANYBITMAP)) { + DWORD origstyle = (DWORD)GetWindowLong(window,GWL_STYLE); + SetProp(window,"SDlg_OrigStyle",(HANDLE)origstyle); + DWORD style = origstyle; + char classname[256] = ""; + GetClassName(window,classname,256); + if ((!_stricmp(classname,"Button")) && + (((origstyle & 0x0000000F) == BS_PUSHBUTTON) || + ((origstyle & 0x0000000F) == BS_DEFPUSHBUTTON))) + style |= BS_OWNERDRAW; + else if (!_stricmp(classname,"ComboBox")) + style |= CBS_OWNERDRAWFIXED; + else if (!_stricmp(classname,"ListBox")) + style |= LBS_OWNERDRAWFIXED; + if (style != origstyle) + SetWindowLong(window,GWL_STYLE,(LONG)style); + } + window = GetNextWindow(window,GW_HWNDNEXT); + } + } + + // UNLESS THE APPLICATION CALLED ENDDIALOG() DURING THE WM_INITDIALOG + // MESSAGE, SHOW THE DIALOG WINDOW AND SET THE FOCUS + if (!GetProp(dialogwindow,"SDlg_EndDialog")) { + ShowWindow(dialogwindow,SW_SHOWNORMAL); + RedrawWindow(dialogwindow, + NULL, + NULL, + RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN); + if (focuswindow) + SetFocus(focuswindow); + } + + return dialogwindow; +} + +//=========================================================================== +static void IntersectRgnWithWindow (HWND updatewindow, + HRGN region, + HWND window) { + VALIDATEBEGIN; + VALIDATE(updatewindow); + VALIDATE(region); + VALIDATE(window); + VALIDATEENDVOID; + + if (!IsWindowVisible(window)) + return; + + // INTERSECT THIS WINDOW WITH THE REGION + { + DWORD exstyle = GetWindowLong(window,GWL_EXSTYLE); + if ((window != updatewindow) && + !(exstyle & WS_EX_TRANSPARENT)) { + RECT rect; + GetWindowRect(window,&rect); + ScreenToClient(updatewindow,(LPPOINT)&rect.left); + ScreenToClient(updatewindow,(LPPOINT)&rect.right); + if (RectInRegion(region,&rect)) { + HRGN rectregion = CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom); + CombineRgn(region,region,rectregion,RGN_DIFF); + DeleteObject(rectregion); + } + } + } + + // RECURSIVELY INTERSECT CHILD WINDOWS + { + HWND childwindow = GetTopWindow(window); + while (childwindow) { + IntersectRgnWithWindow(updatewindow,region,childwindow); + childwindow = GetNextWindow(childwindow,GW_HWNDNEXT); + } + } + +} + +//=========================================================================== +static BOOL IsButton (HWND window, BOOL *ownerdraw) { + if (ownerdraw) + *ownerdraw = 0; + + // DETERMINE WHETHER THIS IS A BUTTON WINDOW + if (!IsWindow(window)) + return FALSE; + char classname[256] = ""; + GetClassName(window,classname,256); + if (_stricmp(classname,"Button")) + return FALSE; + + // DETERMINE WHETHER IT IS OWNER DRAWN + DWORD style = (DWORD)GetWindowLong(window,GWL_STYLE); + if (ownerdraw) + *ownerdraw = ((style & 0x0000000F) == BS_OWNERDRAW); + + return TRUE; +} + +//=========================================================================== +static BOOL IsPointInWindow (LPPOINTS point, HWND window) { + RECT rect; + GetClientRect(window,&rect); + return ((point->x >= rect.left) && + (point->x < rect.right) && + (point->y >= rect.top) && + (point->y < rect.bottom)); +} + +//=========================================================================== +static void ParseDlgTemplate (LPCDLGTEMPLATE templatedata, + LPDLGTEMPLATE parsedtemplate, + LPCWSTR *title, + short *fontsize, + short *fontweight, + short *fontitalics, + LPCWSTR *fontname, + LPDLGITEMTEMPLATE *firstitem) { + + // PREPARE THE PARSED TEMPLATE STRUCTURE + CopyMemory(parsedtemplate,templatedata,sizeof(DLGTEMPLATE)); + + // FIND THE TITLE + { + LPCWSTR menuname = (LPCWSTR)(templatedata+1); + LPCWSTR classname; + if ((*menuname == 0x0000) || (*menuname == 0xFFFF)) + classname = menuname+1; + else + classname = menuname+wcslen(menuname)+1; + if ((*classname == 0x0000) || (*classname == 0xFFFF)) + *title = classname+1; + else + *title = classname+wcslen(classname)+1; + } + + // FIND THE FONT INFORMATION + if (parsedtemplate->style & DS_SETFONT) { + *fontsize = *((*title)+wcslen(*title)+1); + *fontweight = 0; + *fontitalics = 0; + *fontname = (*title)+wcslen(*title)+2; + *firstitem = (LPDLGITEMTEMPLATE)((*fontname)+wcslen(*fontname)+1); + } + else { + *fontsize = 0; + *fontweight = 0; + *fontitalics = 0; + *fontname = NULL; + *firstitem = (LPDLGITEMTEMPLATE)((*title)+wcslen(*title)+1); + } + +} + +//=========================================================================== +static void ParseDlgTemplateEx (LPCDLGTEMPLATE templatedata, + LPDLGTEMPLATE parsedtemplate, + LPCWSTR *title, + short *fontsize, + short *fontweight, + short *fontitalics, + LPCWSTR *fontname, + LPDLGITEMTEMPLATE *firstitem) { + + // PREPARE THE PARSED TEMPLATE STRUCTURE + { + CopyMemory(parsedtemplate,((LPBYTE)templatedata)+8,sizeof(DLGTEMPLATE)); + DWORD temp = parsedtemplate->style; + parsedtemplate->style = parsedtemplate->dwExtendedStyle; + parsedtemplate->dwExtendedStyle = temp; + } + + // FIND THE TITLE + { + LPCWSTR menuname = (LPCWSTR)(((LPBYTE)templatedata)+26); + LPCWSTR classname; + if ((*menuname == 0x0000) || (*menuname == 0xFFFF)) + classname = menuname+1; + else + classname = menuname+wcslen(menuname)+1; + if ((*classname == 0x0000) || (*classname == 0xFFFF)) + *title = classname+1; + else + *title = classname+wcslen(classname)+1; + } + + // FIND THE FONT INFORMATION + if (parsedtemplate->style & DS_SETFONT) { + const short *ptr = (const short *)((*title)+wcslen(*title)+1); + *fontsize = *ptr++; + *fontweight = *ptr++; + *fontitalics = (*ptr++) & 1; + *fontname = (LPCWSTR)ptr; + *firstitem = (LPDLGITEMTEMPLATE)((*fontname)+wcslen(*fontname)+1); + } + else { + *fontsize = 0; + *fontweight = 0; + *fontitalics = 0; + *fontname = NULL; + *firstitem = (LPDLGITEMTEMPLATE)((*title)+wcslen(*title)+1); + } +} + +//=========================================================================== +static LRESULT SendMessageNoDefProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + s_nodefproc = 1; + return SendMessage(window,message,wparam,lparam); +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +HDC APIENTRY SDlgBeginPaint (HWND window, LPPAINTSTRUCT ps) { + VALIDATEBEGIN; + VALIDATE(window); + VALIDATE(ps); + VALIDATEEND; + + if (!IsWindow(window)) + return (HDC)0; + ++s_inpaint; + + // IF THIS WINDOW DOESN'T HAVE A SELECTED BACKGROUND, OR IF IT IS + // TRANSPARENT, JUST CALL THE NORMAL BEGINPAINT() FUNCTION AND LET IT + // PAINT THE BACKGROUND WITH THE BRUSH REGISTERED IN THE WINDOW CLASS + if ((GetWindowLong(window,GWL_EXSTYLE) & WS_EX_TRANSPARENT) || + !FindBitmap(window,SDLG_USAGE_BACKGROUND)) + return BeginPaint(window,ps); + + // SAVE THE UPDATE REGION FOR THIS WINDOW + HRGN region = CreateRectRgn(0,0,1,1); + GetUpdateRgn(window,region,0); + + // TEMPORARILY SAVE AND REMOVE THE BACKGROUND BRUSH FOR THIS WINDOW'S + // CLASS, SO THAT BEGINPAINT() WILL NOT TRY TO ERASE THE BACKGROUND + DWORD brush = GetClassLong(window,GCL_HBRBACKGROUND); + SetClassLong(window,GCL_HBRBACKGROUND,0); + + // CALL BEGINPAINT() + HDC dc = BeginPaint(window,ps); + + // RESTORE THE BACKGROUND BRUSH + SetClassLong(window,GCL_HBRBACKGROUND,brush); + + // ERASE THE BACKGROUND + SDlgDrawBitmap(window, + SDLG_USAGE_BACKGROUND, + region, + 0, + 0, + NULL, + SDLG_DBF_TILE | SDLG_DBF_VCENTER); + ps->fErase = 0; + + DeleteObject(region); + return dc; +} + +//=========================================================================== +BOOL APIENTRY SDlgBltToWindowE (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey, + DWORD pattern, + DWORD rop3) { + VALIDATEBEGIN; + VALIDATE(window); + VALIDATEEND; + + if (!(IsWindow(window) && IsWindowVisible(window) && !IsIconic(window))) + return FALSE; + + // REJECT ANY ATTEMPT TO SET A TRANSPARENCY COLOR, SINCE TRANSPARENCY + // IS NOT CURRENTLY IMPLEMENTED + if (colorkey != 0xFFFFFFFF) + return FALSE; + + // DETERMINE THE SCREEN DIMENSIONS + SIZE screensize; + SDrawGetScreenSize((int *)&screensize.cx,(int *)&screensize.cy); + + // DETERMINE THE DESTINATION LOCATION + RECT clientrect; + GetClientRect(window,&clientrect); + clientrect.left += x; + clientrect.top += y; + + // DETERMINE WHETHER WE WILL HIDE AND/OR RESTORE THE CURSOR + DWORD bltflags = BLT_FLAG_LOCKSURFACE | BLT_FLAG_DESTRECTCLIENTCOORDS; + if (!s_cursorhidden) { + bltflags |= BLT_FLAG_HIDECURSOR; + if (!s_inpaint) + bltflags |= BLT_FLAG_RESTORECURSOR; + } + + // PERFORM THE BITBLT + InternalBltClippedToWindow(NULL, + &clientrect, + &screensize, + 0, + bitmapbits, + bitmaprect, + bitmapsize, + bitmapsize->cx, + 0, + 0, + pattern, + rop3, + window, + region, + bltflags, + SDRAW_SURFACE_FRONT, + s_cursorhidden ? NULL : &s_cursorhidden); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDlgBltToWindowI (HWND window, + HRGN region, + int x, + int y, + LPBYTE bitmapbits, + LPRECT bitmaprect, + LPSIZE bitmapsize, + DWORD colorkey, + DWORD pattern, + DWORD rop3) { + RECT exclrect; + LPRECT exclrectptr = bitmaprect; + if (bitmaprect) { + exclrect.left = bitmaprect->left; + exclrect.top = bitmaprect->top; + exclrect.right = bitmaprect->right+1; + exclrect.bottom = bitmaprect->bottom+1; + exclrectptr = &exclrect; + } + return SDlgBltToWindowE(window, + region, + x, + y, + bitmapbits, + exclrectptr, + bitmapsize, + colorkey, + pattern, + rop3); +} + +//=========================================================================== +BOOL APIENTRY SDlgCheckTimers () { + TIMERPTR callback = NULL; + DWORD currtime = GetTickCount(); + ITERATELIST(TIMERREC,s_timerlist,curr) + if (currtime-curr->lasttime >= curr->elapse) { + if (currtime-curr->lasttime > 2*curr->elapse) + curr->lasttime = currtime; + else + curr->lasttime += curr->elapse; + if (curr->callback) { + callback = curr; + break; + } + else + PostMessage(curr->window,WM_TIMER,curr->id,0); + } + if (callback) + callback->callback(callback->window,WM_TIMER,callback->id,currtime); + return TRUE; +} + +//=========================================================================== +HWND APIENTRY SDlgCreateDialogIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam) { + if (!s_initialized) + if (!InitializeDialogManager()) + return (HWND)0; + + return InternalCreateDialogBox(instance, + templatedata, + parentwindow, + dialogproc, + initparam); +} + +//=========================================================================== +HWND APIENTRY SDlgCreateDialogParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam) { + LPCDLGTEMPLATE templatedata = GetTemplateData(instance,templatename); + if (!templatedata) + return (HWND)0; + + return SDlgCreateDialogIndirectParam((HINSTANCE)GetModuleHandle(NULL), + templatedata, + parentwindow, + dialogproc, + initparam); +} + +//=========================================================================== +BOOL APIENTRY SDlgDefDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + + case WM_CTLCOLORSTATIC: + { + char classname[256] = ""; + GetClassName((HWND)lparam,classname,256); + if (!_stricmp(classname,"SDlgStatic")) { + SetTextColor((HDC)wparam,0xFFFFFF); + SetBkMode((HDC)wparam,TRANSPARENT); + return (BOOL)GetStockObject(NULL_BRUSH); + } + } + // IF IT'S NOT A STATIC CONTROL, FALL THROUGH TO WM_CTLCOLOREDIT + + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + SetTextColor((HDC)wparam,0xFFFFFF); + SetBkColor((HDC)wparam,0); + SetBkMode((HDC)wparam,OPAQUE); + return (BOOL)GetStockObject(BLACK_BRUSH); + + case WM_INITDIALOG: + return 1; + + } + return 0; +} + +//=========================================================================== +BOOL APIENTRY SDlgDestroy () { + SDlgSetSystemCursor(NULL,NULL,NULL,OCR_NORMAL); + TIMERPTR curr; + while ((curr = s_timerlist.Head()) != NULL) + SDlgKillTimer(curr->window,curr->id); + s_bitmaplist.Clear(); + if (s_basefont) { + DEL(s_basefont); + s_basefont = NULL; + } + return TRUE; +} + +//=========================================================================== +int APIENTRY SDlgDialogBoxIndirectParam (HINSTANCE instance, + LPCDLGTEMPLATE templatedata, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam) { + if (!s_initialized) + if (!InitializeDialogManager()) + return -1; + + // CREATE THE DIALOG BOX + HWND dialogwindow = InternalCreateDialogBox(instance, + templatedata, + parentwindow, + dialogproc, + initparam); + if (!dialogwindow) + return -1; + + // FLAG THE DIALOG BOX AS MODAL AND DISABLE THE PARENT WINDOW + if (parentwindow && (parentwindow != GetDesktopWindow())) { + SetProp(dialogwindow,"SDlg_Modal",(HANDLE)1); + if (!IsIconic(parentwindow)) + EnableWindow(parentwindow,0); + } + + // ENTER THE MESSAGE LOOP + while (!GetProp(dialogwindow,"SDlg_EndDialog")) + DoMessageLoop(dialogwindow); + int result = (int)GetProp(dialogwindow,"SDlg_EndResult"); + RemoveProp(dialogwindow,"SDlg_EndDialog"); + RemoveProp(dialogwindow,"SDlg_EndResult"); + RemoveProp(dialogwindow,"SDlg_Modal"); + DestroyWindow(dialogwindow); + + // REENABLE THE PARENT WINDOW + if (parentwindow && (parentwindow != GetDesktopWindow())) + EnableWindow(parentwindow,1); + + // RETURN THE VALUE THAT WAS PASSED TO SDLGENDDIALOG() + return result; +} + +//=========================================================================== +int APIENTRY SDlgDialogBoxParam (HINSTANCE instance, + LPCTSTR templatename, + HWND parentwindow, + DLGPROC dialogproc, + LPARAM initparam) { + LPCDLGTEMPLATE templatedata = GetTemplateData(instance,templatename); + if (!templatedata) + return -1; + + return SDlgDialogBoxIndirectParam((HINSTANCE)GetModuleHandle(NULL), + templatedata, + parentwindow, + dialogproc, + initparam); +} + +//=========================================================================== +BOOL APIENTRY SDlgDrawBitmap (HWND window, + DWORD usage, + HRGN region, + int offsetx, + int offsety, + LPRECT boundingoffset, + DWORD flags) { + VALIDATEBEGIN; + VALIDATE(window); + VALIDATE(usage); + VALIDATEEND; + + if (!IsWindow(window)) + return FALSE; + if ((usage == SDLG_USAGE_BACKGROUND) && + (GetWindowLong(window,GWL_EXSTYLE) & WS_EX_TRANSPARENT)) + return TRUE; + + // FIND THE REQUESTED BITMAP + BITMAPPTR bitmap = FindBitmap(window,usage); + if (!bitmap) + return FALSE; + + // DETERMINE THE BOUNDING RECTANGLE, IN SCREEN COORDINATES, FOR THIS + // WINDOW'S CLIENT AREA + RECT boundingrect; + GetClientRect(window,&boundingrect); + ClientToScreen(window,(LPPOINT)&boundingrect.left); + ClientToScreen(window,(LPPOINT)&boundingrect.right); + + // APPLY ANY BOUNDING RECTANGLE OFFSETS + if (boundingoffset) { + boundingrect.left += max(0,boundingoffset->left); + boundingrect.top += max(0,boundingoffset->top); + boundingrect.right += min(0,boundingoffset->right); + boundingrect.bottom += min(0,boundingoffset->bottom); + } + + // IF WE'RE NOT TILING THEN CLIP THE SIZE OF THE BOUNDING RECTANGLE + // TO THE SIZE OF THE BITMAP + if (!(flags & SDLG_DBF_TILE)) { + boundingrect.right = min(boundingrect.right, + boundingrect.left+bitmap->rect.right-bitmap->rect.left); + if (flags & SDLG_DBF_VCENTER) { + int vertspace = ((boundingrect.bottom-boundingrect.top) + -(bitmap->rect.bottom-bitmap->rect.top))/2; + if (vertspace > 0) { + boundingrect.top += vertspace; + boundingrect.bottom = boundingrect.top+bitmap->rect.bottom-bitmap->rect.top; + } + } + else + boundingrect.bottom = min(boundingrect.bottom, + boundingrect.top+bitmap->rect.bottom-bitmap->rect.top); + } + + // DETERMINE THE BITMAP AND SCREEN DIMENSIONS + SIZE bitmapsize = {bitmap->width,bitmap->height}; + SIZE screensize; + SDrawGetScreenSize((int *)&screensize.cx,(int *)&screensize.cy); + + // DETERMINE WHETHER WE WILL HIDE AND/OR RESTORE THE CURSOR + DWORD bltflags = BLT_FLAG_LOCKSURFACE | BLT_FLAG_TILED; + if (!s_cursorhidden) { + bltflags |= BLT_FLAG_HIDECURSOR; + if (!s_inpaint) + bltflags |= BLT_FLAG_RESTORECURSOR; + } + + // PERFORM THE BITBLT + InternalBltClippedToWindow(NULL, + &boundingrect, + &screensize, + 0, + bitmap->bitmapbits, + &bitmap->rect, + &bitmapsize, + bitmap->width, + offsetx, + offsety, + 0, + SRCCOPY, + window, + region, + bltflags, + SDRAW_SURFACE_FRONT, + s_cursorhidden ? NULL : &s_cursorhidden); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SDlgEndDialog (HWND window, + int result) { + SetProp(window,"SDlg_EndDialog",(HANDLE)1); + SetProp(window,"SDlg_EndResult",(HANDLE)result); + return EndDialog(window,result); +} + +//=========================================================================== +BOOL APIENTRY SDlgEndPaint (HWND window, LPPAINTSTRUCT ps) { + if (s_cursorhidden) + do + ShowCursor(1); + while (--s_cursorhidden); + --s_inpaint; + return EndPaint(window,ps); +} + +//=========================================================================== +BOOL APIENTRY SDlgKillTimer (HWND window, + UINT event) { + BOOL found = FALSE; + ITERATELIST(TIMERREC,s_timerlist,curr) + if ((curr->window == window) && + (curr->id == event)) { + found = TRUE; + ITERATE_DELETE; + } + return found; +} + +//=========================================================================== +BOOL APIENTRY SDlgSetBaseFont (int pointsize, + int weight, + DWORD flags, + DWORD family, + LPCTSTR face) { + if (!(pointsize && weight && face && *face)) + return FALSE; + if (!s_basefont) + s_basefont = NEW(BASEFONT); + s_basefont->pointsize = pointsize; + s_basefont->weight = weight; + s_basefont->flags = flags; + s_basefont->family = family; + SStrCopy(s_basefont->face,face,32); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDlgSetBitmapE (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey) { + VALIDATEBEGIN; + VALIDATE(window || (controltype && *controltype)); + VALIDATE(usage); + VALIDATE(!(usage & ~ANYBITMAP)); + VALIDATEEND; + + if (!controltype) + controltype = ""; + + // REJECT ANY ATTEMPT TO SET A TRANSPARENCY COLOR, SINCE TRANSPARENCY + // IS NOT CURRENTLY IMPLEMENTED + if (colorkey != 0xFFFFFFFF) + return FALSE; + + // REMOVE ANY BITMAPS ASSOCIATED WITH WINDOWS THAT NO LONGER EXIST + { + ITERATELIST(BITMAPREC,s_bitmaplist,curr) + if ((curr->window && !IsWindow(curr->window)) || + (curr->parentwindow && !IsWindow(curr->parentwindow))) + ITERATE_DELETE; + } + + // REMOVE THE PREVIOUS BITMAP FOR THIS WINDOW + { + BITMAPPTR curr = s_bitmaplist.Head(); + while (curr && + ((curr->window != window) || + (curr->parentwindow != parentwindow) || + (curr->usage != usage) || + (curr->controlstyle != controlstyle) || + _stricmp(curr->controltype,controltype))) + curr = curr->Next(); + if (curr) + s_bitmaplist.DeleteNode(curr); + } + + // ADD A NEW RECORD FOR THIS BITMAP + if (bitmapbits && (width > 0) && (height > 0)) { + BITMAPPTR bitmap = s_bitmaplist.NewNode(LIST_HEAD); + bitmap->window = window; + bitmap->parentwindow = parentwindow; + bitmap->usage = usage; + bitmap->controlstyle = controlstyle; + bitmap->bitmapbits = bitmapbits; + bitmap->width = width; + bitmap->height = height; + bitmap->offsetx = 0; + bitmap->offsety = 0; + BOOL overflow = 0; + if (rect) { + bitmap->rect.left = rect->left % width; + bitmap->rect.top = rect->top % height; + bitmap->rect.right = bitmap->rect.left+rect->right-rect->left; + bitmap->rect.bottom = bitmap->rect.top+rect->bottom-rect->top; + if ((bitmap->rect.right > width) || + (bitmap->rect.bottom > height)) { + overflow = 1; + bitmap->offsetx = bitmap->rect.left; + bitmap->offsety = bitmap->rect.top; + } + } + if ((!rect) || overflow) { + bitmap->rect.left = 0; + bitmap->rect.top = 0; + bitmap->rect.right = width; + bitmap->rect.bottom = height; + } + SStrCopy(bitmap->controltype,controltype,CONTROLTYPELENGTH); + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDlgSetBitmapI (HWND window, + HWND parentwindow, + LPCTSTR controltype, + DWORD controlstyle, + DWORD usage, + LPBYTE bitmapbits, + LPRECT rect, + int width, + int height, + COLORREF colorkey) { + RECT exclrect; + LPRECT exclrectptr = rect; + if (rect) { + exclrect.left = rect->left; + exclrect.top = rect->top; + exclrect.right = rect->right+1; + exclrect.bottom = rect->bottom+1; + exclrectptr = &exclrect; + } + return SDlgSetBitmapE(window, + parentwindow, + controltype, + controlstyle, + usage, + bitmapbits, + exclrectptr, + width, + height, + colorkey); +} + +//=========================================================================== +BOOL APIENTRY SDlgSetControlBitmaps (HWND parentwindow, + LPINT controllist, + LPDWORD usagelist, + LPBYTE bitmapbits, + LPSIZE bitmapsize, + DWORD adjusttype, + DWORD colorkey) { + VALIDATEBEGIN; + VALIDATE(parentwindow); + VALIDATE(controllist); + VALIDATE(bitmapbits); + VALIDATE(bitmapsize); + VALIDATE(bitmapsize->cx > 0); + VALIDATE(bitmapsize->cy > 0); + VALIDATEEND; + + // IF THE USAGE LIST WAS NOT PROVIDED, SUPPLY A DEFAULT LIST + // BASED ON THE ADJUSTMENT TYPE + static const DWORD defaultcontrolposlist[2] = {SDLG_USAGE_BACKGROUND, + 0}; + static const DWORD defaultverticallist[6] = {SDLG_USAGE_NORMAL_UNFOCUSED, + SDLG_USAGE_SELECTED_UNFOCUSED, + SDLG_USAGE_NORMAL_FOCUSED, + SDLG_USAGE_SELECTED_FOCUSED, + SDLG_USAGE_GRAYED, + 0}; + if (!usagelist) + if (adjusttype == SDLG_ADJUST_VERTICAL) + usagelist = (LPDWORD)&defaultverticallist[0]; + else + usagelist = (LPDWORD)&defaultcontrolposlist[0]; + + // PROCESS ALL CONTROLS AND USAGE TYPES + RECT rect = {0,0,0,0}; + BOOL success = 1; + for (LPINT currcontrol = controllist; *currcontrol; ++currcontrol) { + HWND window = GetDlgItem(parentwindow,*currcontrol); + if (window) { + RECT clientrect; + RECT windowrect; + GetClientRect(window,&clientrect); + GetWindowRect(window,&windowrect); + for (LPDWORD currusage = usagelist; *currusage; ++currusage) { + + // IF REQUESTED, ADJUST THE RECTANGLE BASED ON THE CONTROL POSITION + if (adjusttype == SDLG_ADJUST_CONTROLPOS) { + rect.left = windowrect.left; + rect.top = windowrect.top; + ScreenToClient(parentwindow,(LPPOINT)&rect); + } + + // DETERMINE THE WIDTH AND HEIGHT OF THE RECTANGLE BASED ON THE + // SIZE OF THE WINDOW + rect.right = rect.left+clientrect.right-clientrect.left; + rect.bottom = rect.top+clientrect.bottom-clientrect.top; + + // REGISTER THE BITMAP + if (!SDlgSetBitmapE(window, + (HWND)0, + NULL, + SDLG_STYLE_ANY, + *currusage, + bitmapbits, + &rect, + bitmapsize->cx, + bitmapsize->cy, + colorkey)) + success = 0; + + // IF REQUESTED, OFFSET THE RECTANGLE VERTICALLY + if (adjusttype == SDLG_ADJUST_VERTICAL) { + rect.top = rect.bottom; + if (rect.top >= bitmapsize->cy) + rect.top = 0; + } + + } + } + else + success = 0; + } + + return success; +} + +//=========================================================================== +BOOL APIENTRY SDlgSetCursor (HWND window, + HCURSOR cursor, + DWORD id, + HCURSOR *oldcursor) { + if (oldcursor) + *oldcursor = (HCURSOR)0; + LPCSTR normalclasslist[6] = {"Button","SDlgStatic","ListBox","Scrollbar","ComboBox",NULL}; + LPCSTR ibeamclasslist[2] = {"Edit",NULL}; + LPCSTR *classlist; + switch (id) { + case OCR_NORMAL: classlist = normalclasslist; break; + case OCR_IBEAM: classlist = ibeamclasslist; break; + default: return 0; + } + if (id == OCR_NORMAL) { + if (oldcursor) + *oldcursor = (HCURSOR)GetClassLong(window,GCL_HCURSOR); + SetClassLong(window,GCL_HCURSOR,(LONG)cursor); + } + while (*classlist) { + HWND classwindow = FindWindowEx(window,(HWND)0,*classlist,NULL); + if (classwindow) { + if (oldcursor && (id != OCR_NORMAL)) + *oldcursor = (HCURSOR)GetClassLong(window,GCL_HCURSOR); + SetClassLong(classwindow,GCL_HCURSOR,(LONG)cursor); + } + ++classlist; + } + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDlgSetSystemCursor (LPBYTE maskbitmap, + LPBYTE imagebitmap, + LPSIZE size, + DWORD id) { + if (id != OCR_NORMAL) + return FALSE; + if (maskbitmap && imagebitmap) { + SDlgSetSystemCursor(NULL,NULL,NULL,id); + s_cursormask = maskbitmap; + s_cursorimage = imagebitmap; + s_cursorsize.cx = size->cx; + s_cursorsize.cy = size->cy; + POINT pt; + GetCursorPos(&pt); + AdjustCursorPos((HWND)0,pt.x,pt.y); + } + else { + s_cursormask = NULL; + s_cursorimage = NULL; + s_cursorpos.x = -1; + s_cursorpos.y = -1; + } + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDlgSetTimer (HWND window, + UINT event, + UINT elapse, + TIMERPROC timerfunc) { + SDlgKillTimer(window,event); + TIMERPTR ptr = s_timerlist.NewNode(); + ptr->window = window; + ptr->id = event; + ptr->elapse = elapse; + ptr->callback = timerfunc; + ptr->lasttime = GetTickCount(); + return event; +} + +//=========================================================================== +BOOL APIENTRY SDlgUpdateCursor () { + CheckCursorPos(); + return TRUE; +} diff --git a/Storm/SOURCE/SDRAW.CPP b/Storm/SOURCE/SDRAW.CPP new file mode 100644 index 0000000..dc8cc16 --- /dev/null +++ b/Storm/SOURCE/SDRAW.CPP @@ -0,0 +1,977 @@ +/**************************************************************************** +* +* SDRAW.CPP +* Storm DirectDraw functions +* +* By Michael O'Brien (2/8/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define SURFACES 4 + +#define REGKEY "Internal" +#define REGVAL_WINDOWMODE "Window Mode" + +typedef HRESULT (WINAPI *ddcreatetype)(GUID *,LPDIRECTDRAW *,IUnknown *); + +static DWORD s_asyncsystemblt = 0; +static BOOL s_autoinit = FALSE; +static BOOL s_createdgdipalette = FALSE; +static HCURSOR s_cursor = (HCURSOR)0; +static BOOL s_dlgactive = FALSE; +static HWND s_framewindow = (HWND)0; +static HPALETTE s_gdipalette = (HPALETTE)0; +static HINSTANCE s_libinst = (HINSTANCE)0; +static LPDIRECTDRAW s_lpdd = NULL; +static LPDIRECTDRAWPALETTE s_palette = NULL; +static PALETTEENTRY s_paletteentries[256] = {0}; +static BOOL s_redirectingprimary = FALSE; +static RECT s_redirectingrect = {0}; +static int s_screenbitdepth = 8; +static SIZE s_screensize = {640,480}; +static LPDIRECTDRAWSURFACE s_surface[SURFACES] = {NULL}; + +//=========================================================================== +static BOOL CheckUseWindowMode () { + static BOOL init = FALSE; + static DWORD window = 0; + if (!init) { + init = TRUE; + SRegLoadValue(REGKEY,REGVAL_WINDOWMODE,0,&window); +#ifdef _DEBUG + SRegSaveValue(REGKEY,REGVAL_WINDOWMODE,0,window); +#endif + } + return (window != 0); +} + +//=========================================================================== +static void CreateGdiPalette () { + if (s_palette) + s_palette->GetEntries(0,0,256,&s_paletteentries[0]); + { + LOGPALETTE *gdipal = (LOGPALETTE *)ALLOC(sizeof(LOGPALETTE)+255*sizeof(PALETTEENTRY)); + gdipal->palVersion = 0x300; + gdipal->palNumEntries = 256; + CopyMemory(gdipal->palPalEntry,&s_paletteentries[0],256*sizeof(PALETTEENTRY)); + s_gdipalette = CreatePalette(gdipal); + s_createdgdipalette = TRUE; + FREE(gdipal); + } + if (s_framewindow && s_gdipalette) { + HDC dc = GetDC(s_framewindow); + SelectPalette(dc,s_gdipalette,0); + ReleaseDC(s_framewindow,dc); + } +} + +//=========================================================================== +static BOOL inline IsRunningInWindow (HWND window) { + if (GetWindowLong(window,GWL_STYLE) & WS_MAXIMIZE) + return FALSE; + if (!(GetWindowLong(window,GWL_EXSTYLE) & WS_EX_TOPMOST)) + return TRUE; + RECT rect; + GetWindowRect(window,&rect); + return ((rect.right < GetSystemMetrics(SM_CXFULLSCREEN)) && + (rect.bottom < GetSystemMetrics(SM_CYFULLSCREEN))); +} + +//=========================================================================== +static void CALLBACK OnDestroy (LPPARAMS) { + SDrawDestroy(); + PostQuitMessage(0); +} + +//=========================================================================== +static void CALLBACK OnPaletteChanged (LPPARAMS params) { + if ((GetForegroundWindow() == SDrawGetFrameWindow()) && + ((HWND)(params->wparam) != SDrawGetFrameWindow())) + SDrawRealizePalette(); +} + +//=========================================================================== +static void CALLBACK OnQueryNewPalette (LPPARAMS params) { + SDrawRealizePalette(); + params->useresult = TRUE; + params->result = TRUE; +} + +//=========================================================================== +static void CALLBACK OnVkSnapshot (LPPARAMS) { + SDrawCaptureScreen(NULL); +} + +//=========================================================================== +static LRESULT CALLBACK WndProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + BOOL useresult = FALSE; + LRESULT result = 0; + if (SMsgDispatchMessage(window,message,wparam,lparam,&useresult,&result)) + if (useresult) + return result; + return DefWindowProc(window,message,wparam,lparam); +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SDrawAutoInitialize (HINSTANCE instance, + LPCTSTR classname, + LPCTSTR title, + WNDPROC wndproc, + int servicelevel, + int width, + int height, + int bitdepth) { + VALIDATEBEGIN; + VALIDATE(instance); + VALIDATE(classname); + VALIDATE(*classname); + VALIDATE(title); + VALIDATE(servicelevel > 0); + VALIDATE(servicelevel <= SDRAW_SERVICE_MAX); + VALIDATEEND; + + // STORE THE FACT THE WE AUTO-INITIALIZED DIRECTDRAW, SO THAT WE CAN + // UNDO EVERYTHING AT DESTRUCTION TIME + s_autoinit = TRUE; + s_dlgactive = FALSE; + + // CREATE A BLANK CURSOR + if (!s_cursor) { + int cursorcx = GetSystemMetrics(SM_CXCURSOR); + int cursorcy = GetSystemMetrics(SM_CYCURSOR); + int bytes = ((cursorcx+31)/32)*4*cursorcy; + LPVOID buffer1 = ALLOC(bytes); + LPVOID buffer2 = ALLOCZERO(bytes); + FillMemory(buffer1,bytes,0xFF); + s_cursor = CreateCursor(instance, + 0, + 0, + cursorcx, + cursorcy, + buffer1, + buffer2); + FREE(buffer1); + FREE(buffer2); + } + + // REGISTER THE FRAME WINDOW CLASS + { + WNDCLASS wndclass; + ZeroMemory(&wndclass,sizeof(WNDCLASS)); + wndclass.lpfnWndProc = wndproc ? wndproc : WndProc; + wndclass.hInstance = instance; + wndclass.hIcon = LoadIcon(0,IDI_APPLICATION); + wndclass.hCursor = s_cursor; + wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wndclass.lpszClassName = classname; + RegisterClass(&wndclass); + } + + // CREATE THE FRAME WINDOW + { + DWORD exstyle; + int windowwidth, windowheight; + if (CheckUseWindowMode()) { + exstyle = 0; + windowwidth = width; + windowheight = height; + } + else { + exstyle = WS_EX_TOPMOST; + windowwidth = GetSystemMetrics(SM_CXSCREEN); + windowheight = GetSystemMetrics(SM_CYSCREEN); + } + if (!(s_framewindow = CreateWindowEx(exstyle, + classname, + title, + WS_POPUP | WS_VISIBLE, + 0, + 0, + windowwidth, + windowheight, + (HWND)0, + (HMENU)0, + instance, + NULL))) + return FALSE; + } + + // REGISTER MESSAGES FOR THE FRAME WINDOW + SMsgRegisterMessage(s_framewindow,WM_DESTROY ,OnDestroy); + SMsgRegisterMessage(s_framewindow,WM_PALETTECHANGED ,OnPaletteChanged); + SMsgRegisterMessage(s_framewindow,WM_QUERYNEWPALETTE,OnQueryNewPalette); + SMsgRegisterKeyUp(s_framewindow,VK_SNAPSHOT,OnVkSnapshot); + SMsgPushRegisterState(s_framewindow); + + // LOAD THE DIRECTDRAW LIBRARY + if (!s_libinst) + s_libinst = LoadLibrary("ddraw.dll"); + + // INITIALIZE DIRECTDRAW + if (s_libinst) { + ddcreatetype ddcreatefunc = (ddcreatetype)SDirectDrawCreate; + if (ddcreatefunc) + ddcreatefunc(NULL,&s_lpdd,NULL); + if (s_lpdd) { + if (CheckUseWindowMode()) + s_lpdd->SetCooperativeLevel(s_framewindow,DDSCL_NORMAL); + else { + s_lpdd->SetCooperativeLevel(s_framewindow, + DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + s_lpdd->SetDisplayMode(width,height,bitdepth); + } + s_screenbitdepth = bitdepth; + s_screensize.cx = width; + s_screensize.cy = height; + } + } + + // IF WE FAILED TO LOAD THE LIBRARY OR INITIALIZE DIRECTDRAW, INFORM + // THE USER + if (!s_lpdd) { + MessageBox(s_framewindow, + "DirectDraw services are not available. You must install " + "Microsoft DirectX version 2.0 or higher. If you have " + "difficulty installing or using Microsoft DirectX on your " + "computer, please contact Microsoft Product Support " + "Services.", + title, + MB_SETFOREGROUND | MB_ICONSTOP); + return FALSE; + } + + // DETERMINE THE CAPABILITIES OF THE HARDWARE + s_asyncsystemblt = 0; + { + DDCAPS caps; + ZeroMemory(&caps,sizeof(DDCAPS)); + caps.dwSize = sizeof(DDCAPS); + if (s_lpdd->GetCaps(&caps,NULL) == DD_OK) + if ((caps.dwCaps & DDCAPS_CANBLTSYSMEM) && + (caps.dwSVBCaps & DDCAPS_BLTQUEUE)) + s_asyncsystemblt = 1; + } + + // CREATE THE VIDEO MEMORY SURFACES + { + DDSURFACEDESC desc; + ZeroMemory(&desc,sizeof(DDSURFACEDESC)); + desc.dwSize = sizeof(DDSURFACEDESC); + desc.dwFlags = DDSD_CAPS; + desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + if (servicelevel == SDRAW_SERVICE_PAGEFLIP) { + desc.dwFlags |= DDSD_BACKBUFFERCOUNT; + desc.dwBackBufferCount = 1; + desc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX; + } + if (s_lpdd->CreateSurface(&desc,&s_surface[SDRAW_SURFACE_FRONT],NULL) != DD_OK) + return FALSE; + if (servicelevel == SDRAW_SERVICE_PAGEFLIP) { + DDSCAPS caps; + ZeroMemory(&caps,sizeof(DDSCAPS)); + caps.dwCaps = DDSCAPS_BACKBUFFER; + if (s_surface[SDRAW_SURFACE_FRONT]) + s_surface[SDRAW_SURFACE_FRONT]->GetAttachedSurface(&caps,&s_surface[SDRAW_SURFACE_BACK]); + } + } + + // CREATE THE SYSTEM MEMORY SURFACE + if (servicelevel == SDRAW_SERVICE_DOUBLEBUFFER) { + DDSURFACEDESC desc; + ZeroMemory(&desc,sizeof(DDSURFACEDESC)); + desc.dwSize = sizeof(DDSURFACEDESC); + desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + desc.dwHeight = height; + desc.dwWidth = width; + s_lpdd->CreateSurface(&desc,&s_surface[SDRAW_SURFACE_SYSTEM],NULL); + } + + // VERIFY THAT ALL SURFACES WERE CREATED SUCCESSFULLY + { + if (!s_surface[SDRAW_SURFACE_FRONT]) + return FALSE; + if ((servicelevel == SDRAW_SERVICE_PAGEFLIP) && + !s_surface[SDRAW_SURFACE_BACK]) + return FALSE; + if ((servicelevel == SDRAW_SERVICE_DOUBLEBUFFER) && + !s_surface[SDRAW_SURFACE_SYSTEM]) + return FALSE; + } + + // ATTEMPT TO LOCK THE PRIMARY VIDEO SURFACE. IF WE'RE UNABLE TO LOCK + // IT, THEN CREATE A TEMPORARY SURFACE IN SYSTEM MEMORY TO BLT FROM. + { + DDSURFACEDESC desc; + ZeroMemory(&desc,sizeof(DDSURFACEDESC)); + desc.dwSize = sizeof(DDSURFACEDESC); + HRESULT result = s_surface[SDRAW_SURFACE_FRONT]->Lock(NULL, + &desc, + DDLOCK_WAIT, + NULL); + if (desc.lpSurface) + s_surface[SDRAW_SURFACE_FRONT]->Unlock(desc.lpSurface); + else if ((result != DDERR_SURFACELOST) && + (result != DDERR_WASSTILLDRAWING)) { + DDSURFACEDESC desc; + ZeroMemory(&desc,sizeof(DDSURFACEDESC)); + desc.dwSize = sizeof(DDSURFACEDESC); + desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + desc.dwHeight = height; + desc.dwWidth = width; + s_lpdd->CreateSurface(&desc,&s_surface[SDRAW_SURFACE_TEMPORARY],NULL); + } + } + + // CREATE A DIRECTDRAW PALETTE AND A MATCHING GDI PALETTE + if (bitdepth == 8) { + { + HDC dc = GetDC((HWND)0); + GetSystemPaletteEntries(dc,0,256,&s_paletteentries[0]); + ReleaseDC((HWND)0,dc); + } + { + for (int loop = 10; loop < 246; ++loop) + s_paletteentries[loop].peFlags = PC_RESERVED | PC_NOCOLLAPSE; + } + s_lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 + | DDPCAPS_INITIALIZE, + &s_paletteentries[0], + &s_palette, + NULL); + if (!s_palette) { + SDrawDestroy(); + return FALSE; + } + CreateGdiPalette(); + } + + // BLANK OUT THE NEWLY CREATED SURFACES, AND SELECT THE NEW PALETTE + // INTO EACH ONE + { + for (int loop = 0; loop < SURFACES; ++loop) + if (s_surface[loop]) { + SDrawClearSurface(loop); + if (s_palette) + s_surface[loop]->SetPalette(s_palette); + } + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawCaptureScreen (LPCTSTR filename) { + if (!(s_lpdd && + s_framewindow && + s_surface[SDRAW_SURFACE_FRONT])) + return FALSE; + if (s_screenbitdepth != 8) + return FALSE; + + // SWITCH TO THE GDI SCREEN IF NECESSARY + SDrawSelectGdiSurface(1,1); + + // SAVE THE CURRENT SURFACE + LPBYTE savebuffer = (LPBYTE)ALLOC(s_screensize.cx*s_screensize.cy); + if (s_palette) + s_palette->GetEntries(0,0,256,&s_paletteentries[0]); + { + LPBYTE videobuffer; + int pitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&pitch)) { + SBltROP3(savebuffer, + videobuffer, + s_screensize.cx, + s_screensize.cy, + s_screensize.cx, + pitch, + 0, + SRCCOPY); + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + } + + // IF NO FILENAME WAS PROVIDED, PROMPT THE USER FOR ONE + char localfilename[MAX_PATH] = ""; + if (filename && *filename) + SStrCopy(localfilename,filename,MAX_PATH); + else { + OPENFILENAME ofn; + ZeroMemory(&ofn,sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = s_framewindow; + ofn.hInstance = (HINSTANCE)GetModuleHandle(NULL); + ofn.lpstrFilter = "Graphics Interchange (*.gif)\0*.gif\0" + "PC Paintbrush (*.pcx)\0*.pcx\0" + "Windows Bitmap (*.bmp)\0*.bmp\0" + "All Files (*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = localfilename; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrTitle = "Save Screen Capture"; + ofn.Flags = OFN_HIDEREADONLY + | OFN_NOCHANGEDIR + | OFN_OVERWRITEPROMPT + | OFN_PATHMUSTEXIST; + ofn.lpstrDefExt = ".gif"; + s_dlgactive = 1; + BOOL result = GetSaveFileName(&ofn); + s_dlgactive = 0; + if (!result) { + FREE(savebuffer); + return FALSE; + } + } + + // SAVE THE FILE + SBmpSaveImage(localfilename, + &s_paletteentries[0], + savebuffer, + s_screensize.cx, + s_screensize.cy, + s_screenbitdepth); + + FREE(savebuffer); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawClearSurface (int surfacenumber) { + VALIDATEBEGIN; + VALIDATE(surfacenumber >= 0); + VALIDATE(surfacenumber < SURFACES); + VALIDATEEND; + + if ((!s_lpdd) || + (!s_surface[surfacenumber])) + return FALSE; + + // HIDE THE CURSOR IF IT IS VISIBLE + int hidden = 0; + do + ++hidden; + while (ShowCursor(0) >= 0); + + // CLEAR THE SURFACE + { + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(surfacenumber,NULL,&videobuffer,&videopitch)) { + SGdiSetPitch(videopitch); + SGdiRectangle(videobuffer, + 0, + 0, + s_screensize.cx, + s_screensize.cy, + PALETTEINDEX(0)); + SDrawUnlockSurface(surfacenumber,videobuffer); + } + } + + // RESTORE THE CURSOR + while (hidden--) + ShowCursor(1); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawDestroy () { + + // DESTROY OTHER MODULES WHICH RELY ON THIS MODULE + BOOL result = TRUE; +#ifndef STATICLIB + result &= SDlgDestroy(); + result &= SGdiDestroy(); + result &= SVidDestroy(); +#endif + + // DESTROY THE GDI PALETTE IF WE CREATED ONE + if (s_gdipalette && s_createdgdipalette) { + s_createdgdipalette = 0; + DeleteObject(s_gdipalette); + } + + // RETURN THE SCREEN DIMENSIONS TO THEIR DEFAULTS + s_screenbitdepth = 8; + s_screensize.cx = 640; + s_screensize.cy = 480; + + // IF DIRECTDRAW WAS INITIALIZED THROUGH SDRAWAUTOINITIALIZE(), RELEASE + // ALL DIRECTDRAW OBJECTS THAT WE CREATED + if (s_autoinit) { + s_autoinit = FALSE; + if (s_cursor) + DestroyCursor(s_cursor); + } + + // ZERO OUT ALL OBJECT POINTERS AND HANDLES + s_gdipalette = (HPALETTE)0; + s_palette = NULL; + for (int loop = SURFACES-1; loop >= 0; --loop) + s_surface[loop] = NULL; + s_lpdd = NULL; + s_framewindow = (HWND)0; + s_cursor = (HCURSOR)0; + + return result; +} + +//=========================================================================== +BOOL APIENTRY SDrawFlipPage () { + if (s_dlgactive || + !(s_lpdd && + s_surface[SDRAW_SURFACE_FRONT] && + s_surface[SDRAW_SURFACE_BACK])) + return FALSE; + + HRESULT result; + do { + result = s_surface[SDRAW_SURFACE_FRONT]->Flip(NULL,DDFLIP_WAIT); + if ((result == DDERR_SURFACELOST) && s_surface[SDRAW_SURFACE_FRONT]) + if (s_surface[SDRAW_SURFACE_FRONT]->Restore() == DD_OK) + InvalidateRect(s_framewindow,NULL,0); + else + return FALSE; + } while ((result == DDERR_WASSTILLDRAWING) || + (result == DDERR_SURFACELOST)); + + return TRUE; +} + +//=========================================================================== +HWND APIENTRY SDrawGetFrameWindow (HWND *window) { + if (window) + *window = s_framewindow; + return s_framewindow; +} + +//=========================================================================== +BOOL APIENTRY SDrawGetObjects (LPDIRECTDRAW *directdraw, + LPDIRECTDRAWSURFACE *frontbuffer, + LPDIRECTDRAWSURFACE *backbuffer, + LPDIRECTDRAWSURFACE *systembuffer, + LPDIRECTDRAWSURFACE *temporarybuffer, + LPDIRECTDRAWPALETTE *palette, + HPALETTE *gdipalette) { + if (directdraw) + *directdraw = s_lpdd; + if (frontbuffer) + *frontbuffer = s_surface[SDRAW_SURFACE_FRONT]; + if (backbuffer) + *backbuffer = s_surface[SDRAW_SURFACE_BACK]; + if (systembuffer) + *systembuffer = s_surface[SDRAW_SURFACE_SYSTEM]; + if (palette) + *palette = s_palette; + if (gdipalette) + *gdipalette = s_gdipalette; + return (s_lpdd != NULL); +} + +//=========================================================================== +BOOL APIENTRY SDrawGetScreenSize (int *width, + int *height, + int *bitdepth) { + if (width) + *width = s_lpdd ? s_screensize.cx : GetSystemMetrics(SM_CXSCREEN); + if (height) + *height = s_lpdd ? s_screensize.cy : GetSystemMetrics(SM_CYSCREEN); + if (bitdepth) + if (s_lpdd) + *bitdepth = s_screenbitdepth; + else { + HDC dc = GetDC(GetDesktopWindow()); + *bitdepth = GetDeviceCaps(dc,BITSPIXEL)*GetDeviceCaps(dc,PLANES); + ReleaseDC(GetDesktopWindow(),dc); + } + return (width || height || bitdepth); +} + +//=========================================================================== +BOOL APIENTRY SDrawGetServiceLevel (int *servicelevel) { + VALIDATEBEGIN; + VALIDATE(servicelevel); + VALIDATEEND; + + if (!s_surface[SDRAW_SURFACE_FRONT]) + return FALSE; + if (s_surface[SDRAW_SURFACE_SYSTEM]) + *servicelevel = SDRAW_SERVICE_DOUBLEBUFFER; + else if (s_surface[SDRAW_SURFACE_BACK]) + *servicelevel = SDRAW_SERVICE_PAGEFLIP; + else + *servicelevel = SDRAW_SERVICE_BASIC; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawLockSurface (int surfacenumber, + LPCRECT rect, + LPBYTE *ptr, + int *pitch, + DWORD flags) { + if (ptr) + *ptr = NULL; + if (pitch) + *pitch = 0; + + VALIDATEBEGIN; + VALIDATE(surfacenumber >= 0); + VALIDATE(surfacenumber < SURFACES); + VALIDATE(ptr); + VALIDATEEND; + + if ((!s_lpdd) || + (!s_surface[surfacenumber])) + return FALSE; + + // LOCK THE SURFACE AND RETURN A POINTER TO VIDEO MEMORY + { + DDSURFACEDESC desc; + ZeroMemory(&desc,sizeof(DDSURFACEDESC)); + desc.dwSize = sizeof(DDSURFACEDESC); + do { + HRESULT result = s_surface[surfacenumber]->Lock((LPRECT)rect, + &desc, + DDLOCK_WAIT, + NULL); + if ((result == DDERR_SURFACELOST) && s_surface[SDRAW_SURFACE_FRONT]) + if (s_surface[SDRAW_SURFACE_FRONT]->Restore() == DD_OK) + InvalidateRect(s_framewindow,NULL,0); + else + return FALSE; + else if ((result != DD_OK) && + (result != DDERR_WASSTILLDRAWING) && + !desc.lpSurface) { + + // IF WE COULDN'T LOCK THE PRIMARY SURFACE BUT WE HAVE BEEN GIVEN + // A TEMPORARY SURFACE, REDIRECT OUTPUT TO THE TEMPORARY SURFACE + if ((surfacenumber == SDRAW_SURFACE_FRONT) && + s_surface[SDRAW_SURFACE_TEMPORARY] && + !s_redirectingprimary) { + s_redirectingprimary = TRUE; + if (rect) + CopyMemory(&s_redirectingrect,rect,sizeof(RECT)); + else { + s_redirectingrect.left = 0; + s_redirectingrect.top = 0; + s_redirectingrect.right = s_screensize.cx; + s_redirectingrect.bottom = s_screensize.cy; + } + return SDrawLockSurface(SDRAW_SURFACE_TEMPORARY,rect,ptr,pitch,flags); + } + + return FALSE; + } + } while (!desc.lpSurface); + *ptr = (LPBYTE)desc.lpSurface; + if (pitch) + *pitch = desc.lPitch; + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawManualInitialize (HWND framewindow, + LPDIRECTDRAW directdraw, + LPDIRECTDRAWSURFACE frontbuffer, + LPDIRECTDRAWSURFACE backbuffer, + LPDIRECTDRAWSURFACE systembuffer, + LPDIRECTDRAWSURFACE temporarybuffer, + LPDIRECTDRAWPALETTE palette, + HPALETTE gdipalette) { + + // SAVE THE OBJECT HANDLES AND POINTERS + s_autoinit = 0; + s_dlgactive = 0; + s_framewindow = framewindow; + s_gdipalette = gdipalette; + s_lpdd = directdraw; + s_surface[SDRAW_SURFACE_FRONT] = frontbuffer; + s_surface[SDRAW_SURFACE_BACK] = backbuffer; + s_surface[SDRAW_SURFACE_SYSTEM] = systembuffer; + s_surface[SDRAW_SURFACE_TEMPORARY] = temporarybuffer; + s_palette = palette; + + // IF THE APPLICATION PASSED US A DIRECTDRAW PALETTE BUT NOT A GDI PALETTE, + // CREATE ONE OURSELF FOR USE BY SDLG + if (s_palette && !s_gdipalette) + CreateGdiPalette(); + + return TRUE; +} + +//=========================================================================== +int APIENTRY SDrawMessageBox (LPCTSTR text, + LPCTSTR title, + UINT flags) { + + // SWITCH TO THE GDI SCREEN IF NECESSARY + SDrawSelectGdiSurface(TRUE,TRUE); + + // IF THE APPLICATION IS CONTROLLING THE SYSTEM PALETTE DIRECTLY + // THROUGH DIRECTDRAW, NORMALIZE THE PALETTE SO THAT THE MESSAGEBOX() + // FUNCTION CAN DISPLAY ITS TEXT + PALETTEENTRY pe[256]; + if (s_palette) { + + // SAVE THE APPLICATION'S PALETTE + s_palette->GetEntries(0,0,256,&pe[0]); + + // MODIFY THE IMPORTANT SYSTEM COLORS TO USE ONLY BLACK AND WHITE + { + HRSRC resource = FindResource(StormGetInstance(),"SYSTEMPALETTE","#256"); + HGLOBAL handle = LoadResource(StormGetInstance(),resource); + DWORD bytes = SizeofResource(StormGetInstance(),resource); + LPBYTE ptr = (LPBYTE)LockResource(handle); + if (bytes && ptr) { + PALETTEENTRY modpe[256]; + SBmpDecodeImage(SBMP_IMAGETYPE_PCX, + ptr, + bytes, + &modpe[0], + NULL, + 0); + s_palette->SetEntries(0,0,256,&modpe[0]); + } + FreeResource(handle); + } + + } + + // DISPLAY THE MESSAGE BOX + s_dlgactive = TRUE; + int result = MessageBox(GetActiveWindow(), + text, + title, + flags); + s_dlgactive = FALSE; + + // RESTORE THE ORIGINAL PALETTE + if (s_palette) + s_palette->SetEntries(0,0,256,&pe[0]); + + return result; +} + +//=========================================================================== +BOOL APIENTRY SDrawPostClose () { + if (!s_framewindow) + return FALSE; + + PostMessage(s_framewindow,WM_CLOSE,0,0); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawRealizePalette () { + if ((!s_lpdd) || (!s_palette)) + return FALSE; + + // UPDATE THE DIRECTDRAW PALETTE + BOOL success = (s_palette->SetEntries(0,0,256,&s_paletteentries[0]) == DD_OK); + + // UPDATE THE GDI PALETTE + if (s_gdipalette) + SetPaletteEntries(s_gdipalette,0,256,&s_paletteentries[0]); + + // IF WE ARE RUNNING IN A WINDOW, REALIZE THE PALETTE THROUGH GDI + if (s_gdipalette && s_framewindow && + IsRunningInWindow(s_framewindow)) { + HDC dc = GetDC(s_framewindow); + SelectPalette(dc,s_gdipalette,0); + RealizePalette(dc); + ReleaseDC(s_framewindow,dc); + } + + return success; +} + +//=========================================================================== +BOOL APIENTRY SDrawSelectGdiSurface (BOOL select, BOOL copy) { + if (s_dlgactive || + !(s_lpdd && + s_surface[SDRAW_SURFACE_FRONT] && + s_surface[SDRAW_SURFACE_BACK])) + return FALSE; + + // IF THE GDI SURFACE IS NOT ALREADY IN THE REQUESTED POSITION, DO A + // PAGE FLIP + LPDIRECTDRAWSURFACE gdisurface = NULL; + s_lpdd->GetGDISurface(&gdisurface); + if ((gdisurface != s_surface[SDRAW_SURFACE_FRONT]) == (select != 0)) { + if (copy) + s_surface[SDRAW_SURFACE_BACK]->Blt(NULL, + s_surface[SDRAW_SURFACE_FRONT], + NULL, + 0, + NULL); + return SDrawFlipPage(); + } + else + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawUnlockSurface (int surfacenumber, + LPBYTE ptr, + DWORD numrects, + LPCRECT rectarray) { + VALIDATEBEGIN; + VALIDATE(surfacenumber >= 0); + VALIDATE(surfacenumber < SURFACES); + VALIDATEEND; + + if ((!s_lpdd) || + (!s_surface[surfacenumber])) + return FALSE; + + // PROCESS REDIRECTED CALLS TO LOCK THE PRIMARY SURFACE + if ((surfacenumber == SDRAW_SURFACE_FRONT) && + s_redirectingprimary) + surfacenumber = SDRAW_SURFACE_TEMPORARY; + + // UNLOCK THE SURFACE + if (s_surface[surfacenumber]->Unlock(ptr) != DD_OK) + return FALSE; + + // IF WE JUST UNLOCKED THE TEMPORARY SURFACE, AND WE WERE REDIRECTING + // OUTPUT TO THE TEMPORARY SURFACE BECAUSE WE WERE UNABLE TO LOCK THE + // PRIMARY SURFACE, THEN COPY THE MODIFIED CONTENTS OF THE TEMPORARY + // SURFACE INTO THE PRIMARY SURFACE + if ((surfacenumber == SDRAW_SURFACE_TEMPORARY) && + s_redirectingprimary) { + s_redirectingprimary = FALSE; + if (s_surface[SDRAW_SURFACE_FRONT]) + if (numrects) + for (DWORD loop = 0; loop < numrects; ++loop) + s_surface[SDRAW_SURFACE_FRONT]->Blt((LPRECT)&rectarray[loop], + s_surface[SDRAW_SURFACE_TEMPORARY], + (LPRECT)&rectarray[loop], + DDBLT_WAIT, + NULL); + else + s_surface[SDRAW_SURFACE_FRONT]->Blt(&s_redirectingrect, + s_surface[SDRAW_SURFACE_TEMPORARY], + &s_redirectingrect, + DDBLT_WAIT, + NULL); + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SDrawUpdatePalette (DWORD firstentry, + DWORD numentries, + LPPALETTEENTRY entries, + BOOL reservedentries) { + VALIDATEBEGIN; + VALIDATE(firstentry+numentries <= 256); + VALIDATE(entries); + VALIDATEEND; + + if ((!s_lpdd) || (!s_palette)) + return FALSE; + + // PREVENT THE APPLICATION FROM SETTING THE FIRST OR LAST PALETTE + // ENTRIES (BLACK AND WHITE) + if ((!firstentry) && !reservedentries) { + ++firstentry; + --numentries; + ++entries; + } + if ((firstentry+numentries == 256) && !reservedentries) + --numentries; + + // SAVE THE NEW PALETTE ENTRIES + CopyMemory(&s_paletteentries[firstentry],entries,numentries*sizeof(PALETTEENTRY)); + + // UPDATE THE DIRECTDRAW PALETTE + BOOL success = (s_palette->SetEntries(0,firstentry,numentries,entries) == DD_OK); + + // UPDATE THE GDI PALETTE + if (s_gdipalette) { + for (DWORD loop = 0; loop < numentries; ++loop) + (entries+loop)->peFlags = (((firstentry+loop) >= 10) && ((firstentry+loop) <= 245)) + ? PC_RESERVED | PC_NOCOLLAPSE + : 0; + SetPaletteEntries(s_gdipalette,firstentry,numentries,entries); + } + + // IF WE ARE RUNNING IN A WINDOW, REALIZE THE PALETTE THROUGH GDI + if (s_gdipalette && s_framewindow && + IsRunningInWindow(s_framewindow)) { + HDC dc = GetDC(s_framewindow); + SelectPalette(dc,s_gdipalette,0); + RealizePalette(dc); + ReleaseDC(s_framewindow,dc); + } + + return success; +} + +//=========================================================================== +BOOL APIENTRY SDrawUpdateScreen (LPCRECT rect) { + if (!(s_lpdd && + s_surface[SDRAW_SURFACE_FRONT] && + s_surface[SDRAW_SURFACE_SYSTEM])) + return FALSE; + + // IF THE HARDWARE IS CAPABLE OF DOING ASYNCHRONOUS BLTS FROM SYSTEM + // MEMORY, USE THE HARDWARE BLITTER + if (s_asyncsystemblt) { + DDBLTFX fx; + ZeroMemory(&fx,sizeof(DDBLTFX)); + fx.dwSize = sizeof(DDBLTFX); + fx.dwDDFX = DDBLTFX_NOTEARING; + return (s_surface[SDRAW_SURFACE_FRONT]->Blt((LPRECT)rect, + s_surface[SDRAW_SURFACE_SYSTEM], + (LPRECT)rect, + DDBLT_ASYNC | DDBLT_DDFX, + &fx) == DD_OK); + } + + // OTHERWISE, USE OUR OWN BLT FUNCTION, WHICH IS FASTER THAT DIRECTDRAW'S + else { + BOOL success = FALSE; + LPBYTE videobuffer; + int videopitch; + if (SDrawLockSurface(SDRAW_SURFACE_FRONT,NULL,&videobuffer,&videopitch)) { + LPBYTE systembuffer; + int systempitch; + if (SDrawLockSurface(SDRAW_SURFACE_SYSTEM,NULL,&systembuffer,&systempitch)) { + success = SBltROP3(videobuffer, + systembuffer, + (s_screenbitdepth == 8) + ? s_screensize.cx + : (s_screensize.cx*s_screenbitdepth) >> 3, + s_screensize.cy, + videopitch, + systempitch, + 0, + SRCCOPY); + SDrawUnlockSurface(SDRAW_SURFACE_SYSTEM,systembuffer); + } + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,videobuffer); + } + return success; + } + +} diff --git a/Storm/SOURCE/SERR.CPP b/Storm/SOURCE/SERR.CPP new file mode 100644 index 0000000..00a4b9a --- /dev/null +++ b/Storm/SOURCE/SERR.CPP @@ -0,0 +1,440 @@ +/**************************************************************************** +* +* SERR.CPP +* Storm error handling functions +* +* By Michael O'Brien (4/10/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define STR_ERROR 0 +#define STR_HEADER 1 +#define STR_PROGRAM 2 +#define STR_FILELINE 3 +#define STR_FUNCTION 4 +#define STR_OBJECT 5 +#define STR_HANDLE 6 +#define STR_EXPRESSION 7 +#define STR_DESCRIPTION 8 +#define STR_TERMINATE 9 +#define STR_RECOVERABLE 10 +#define STR_FILE 11 +#define STRINGS 12 + +static const LPCTSTR s_displaystr[STRINGS] = + {"ERROR #%u (0x%08x)", + "This application has encountered a critical error:\n\n%s\n", + "Program:\t%s\n", + "File:\t%s\nLine:\t%d\n", + "Function:\t%s\n", + "Object:\t%s\n", + "Handle:\t%s\n", + "Expr:\t%s\n\n", + "\n%s\n\n", + "Press OK to terminate the application.", + "Do you wish to terminate the application?", + "File:\t%s\n"}; + +typedef struct _MSGSRC { + WORD facility; + WORD reserved; + HMODULE module; + _MSGSRC *next; +} MSGSRC, *MSGSRCPTR; + +static CRITICAL_SECTION s_critsect; +static LONG s_critsectinit = -1; +static MSGSRCPTR s_msgsrchead = NULL; +static BOOL s_msgsrcinit = FALSE; +static BOOL s_suppress = FALSE; +//#ifdef _MAC +static DWORD s_lasterror = 0; +//#endif + +static void InternalEnterCriticalSection (); +static void InternalLeaveCriticalSection (); + +//=========================================================================== +static void AddStormFacility (WORD facility) { + + // ADD THE DEFINITION OF STORM'S ERROR CODES TO THE END OF THE LIST + MSGSRCPTR *nextptr = &s_msgsrchead; + while (*nextptr) + nextptr = &(*nextptr)->next; + *nextptr = (MSGSRCPTR)HeapAlloc(GetProcessHeap(), + HEAP_GENERATE_EXCEPTIONS, + sizeof(MSGSRC)); + (*nextptr)->facility = facility; + (*nextptr)->module = StormGetInstance(); + (*nextptr)->next = NULL; + +} + +//=========================================================================== +static void AddStormMessages () { + AddStormFacility(STORMFAC); +#ifdef _FACDD + AddStormFacility(_FACDD); +#else + AddStormFacility(0x876); +#endif +#ifdef _FACDS + AddStormFacility(_FACDS); +#else + AddstormFacility(0x878); +#endif +} + +//=========================================================================== +static LPCTSTR GetString (UINT id) { + static char buffer[256]; + if (LoadString(StormGetInstance(),IDS_BASE+id,buffer,256)) + return buffer; + else + return s_displaystr[id]; +} + +//=========================================================================== +static void InternalEnterCriticalSection () { + if (!InterlockedIncrement(&s_critsectinit)) + InitializeCriticalSection(&s_critsect); + else + InterlockedDecrement(&s_critsectinit); + EnterCriticalSection(&s_critsect); +} + +//=========================================================================== +static void InternalLeaveCriticalSection () { + LeaveCriticalSection(&s_critsect); +} + +//=========================================================================== +static BOOL UndecorateObjectName (LPCSTR source, + LPSTR dest, + DWORD destchars) { + + // THIS IS A NON-CRITICAL FUNCTION WHOSE ONLY PURPOSE IS TO MAKE THE + // DISPLAYED ERROR MESSAGES EASIER TO READ. SINCE NAME DECORATION IS + // PERFORMED DIFFERENTLY BY EACH COMPILER, THIS FUNCTION ONLY ATTEMPTS + // TO UNDECORATE NAMES UNDER MICROSOFT VISUAL C++. +#ifndef _MSC_VER + return FALSE; +#endif + + // CHECK THE SOURCE NAME TO VERIFY THAT IT APPEARS TO BE A STRUCTURE + // OR OBJECT + if ((SStrLen(source) < 6) || + (source[0] != '.') || + (source[3] != 'U') || + !strpbrk(source+4,"?@")) + return FALSE; + + // COPY THE SOURCE NAME, MINUS THE PREFIX, INTO THE DESTINATION BUFFER + SStrCopy(dest,source+4,destchars); + + // STRIP OFF THE DETAILED TYPE INFORMATION + LPSTR separator = strpbrk(dest,"?@"); + if (!separator) + return FALSE; + *separator-- = 0; + + // STRIP OFF ANY TRAILING UNDERSCORES + while ((separator >= dest) && + (*separator == '_')) + *separator-- = 0; + + return TRUE; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SErrDestroy () { + s_msgsrcinit = FALSE; + while (s_msgsrchead) { + MSGSRCPTR next = s_msgsrchead->next; + HeapFree(GetProcessHeap(),0,s_msgsrchead); + s_msgsrchead = next; + } + if (s_critsectinit != -1) { + DeleteCriticalSection(&s_critsect); + s_critsectinit = -1; + } + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SErrDisplayError (DWORD errorcode, + LPCTSTR filename, + int linenumber, + LPCTSTR description, + BOOL recoverable, + UINT exitcode) { + if (s_suppress) + return FALSE; + + // ENTER THE CRITICAL SECTION + InternalEnterCriticalSection(); + + // FLUSH ALL OPEN LOGS +#ifndef STATICLIB + SLogFlushAll(); +#endif + + // DETERMINE THE NAME OF THE APPLICATION + char appfilename[MAX_PATH] = ""; + char appname[MAX_PATH] = ""; + { + GetModuleFileName((HMODULE)0,appfilename,MAX_PATH); + WIN32_FIND_DATA finddata; + ZeroMemory(&finddata,sizeof(WIN32_FIND_DATA)); + HANDLE findhandle = FindFirstFile(appfilename,&finddata); + if (findhandle) + FindClose(findhandle); + SStrCopy(appname,finddata.cFileName,MAX_PATH); + if (SStrChr(appname,'.',TRUE)) + *SStrChr(appname,'.',TRUE) = 0; + } + + // GET THE ERROR STRING + char errorstr[256] = ""; + SErrGetErrorStr(errorcode, + errorstr, + 256); + if (!errorstr[0]) + wsprintf(errorstr,GetString(STR_ERROR),errorcode & 0xFFFF,errorcode); + + // UNDECORATE THE HANDLE OR OBJECT NAME IF APPLICABLE + char localnamebuffer[256]; + LPCSTR localnameptr = filename; + if (localnameptr && *localnameptr && + ((linenumber == SERR_LINECODE_OBJECT) || + (linenumber == SERR_LINECODE_HANDLE))) + if (UndecorateObjectName(localnameptr, + localnamebuffer, + 256)) + localnameptr = localnamebuffer; + + // LOG THE ERROR TO THE ACTIVE DEBUGGER IF APPLICABLE + char outstr[1024]; + LPSTR curr = outstr; + curr += SStrCopy(curr,localnameptr); + if (linenumber > 0) { + wsprintf(curr,"(%u)",linenumber); + curr += SStrLen(curr); + } + wsprintf(curr," : error %u: ",errorcode & 0xFFFF); + curr += SStrLen(curr); + SStrCopy(curr,errorstr); + OutputDebugString(outstr); + + // BUILD THE FULL ERROR MESSAGE + curr = outstr; + wsprintf(curr,GetString(STR_HEADER),errorstr); + curr += SStrLen(curr); + wsprintf(curr,GetString(STR_PROGRAM),appfilename); + curr += SStrLen(curr); + if (localnameptr && *localnameptr) { + switch (linenumber) { + + case SERR_LINECODE_FUNCTION: + wsprintf(curr,GetString(STR_FUNCTION),localnameptr); + break; + + case SERR_LINECODE_OBJECT: + wsprintf(curr,GetString(STR_OBJECT),localnameptr); + break; + + case SERR_LINECODE_HANDLE: + wsprintf(curr,GetString(STR_HANDLE),localnameptr); + break; + + case SERR_LINECODE_FILE: + wsprintf(curr,GetString(STR_FILE),localnameptr); + break; + + default: + wsprintf(curr,GetString(STR_FILELINE),localnameptr,linenumber); + break; + + } + curr += SStrLen(curr); + } + if (errorcode == STORM_ERROR_ASSERTION) + wsprintf(curr,GetString(STR_EXPRESSION),description ? description : ""); + else + wsprintf(curr,GetString(STR_DESCRIPTION),description ? description : ""); + curr += SStrLen(curr); + if (recoverable) + SStrCopy(curr,GetString(STR_RECOVERABLE)); + else + SStrCopy(curr,GetString(STR_TERMINATE)); + + // DISPLAY THE MESSAGE BOX + UINT buttons = recoverable ? MB_YESNOCANCEL + : MB_OKCANCEL; + UINT flags = MB_ICONSTOP + | MB_SETFOREGROUND + | MB_TASKMODAL + | MB_TOPMOST + | buttons; +#ifdef STATICLIB + int result = MessageBox((HWND)0,outstr,appname,flags); +#else + int result = SDrawMessageBox(outstr,appname,flags); +#endif + + // LEAVE THE CRITICAL SECTION + InternalLeaveCriticalSection(); + + // IF THE USER WANTS TO TRY TO RECOVER FROM THE ERROR THEN RETURN + // CONTROL TO THE APPLICATION + if (recoverable && (result == IDNO)) + return TRUE; + + // IF THE USER CLICKED CANCEL, GENERATE A DEBUG BREAK + if (result == IDCANCEL) +#ifdef _X86_ + __asm int 3; +#else + DebugBreak(); +#endif + + // OTHERWISE, ATTEMPT TO STOP THE PROCESS. WE USE TERMINATEPROCESS() + // RATHER THAN EXITPROCESS() TO PREVENT STORM FROM GETTING A + // DLL_PROCESS_DETACH NOTIFICATION AND POTENTIALLY RECURSING INTO ITS + // CLEANUP FUNCTIONS. IF WE ARE RUNNING ON A WIN95/98 SYSTEM AND THE + // PROCESS IS ALREADY BEING TERMINATED, THEN CALLING TERMINATEPROCESS() + // AGAIN WILL CAUSE A KERNEL EXCEPTION. IN THIS CASE, WE JUST SUPPRESS + // ALL ERROR MESSAGES AND LET THE CLEANUP PROCESS CONTINUE TO ITS + // CONCLUSION. + SErrSuppressErrors(TRUE); + { + DWORD terminationcode; + if ((!(GetVersion() & 0x80000000)) || + (!GetExitCodeProcess(GetCurrentProcess(),&terminationcode)) || + (terminationcode == STILL_ACTIVE)) + TerminateProcess(GetCurrentProcess(),exitcode); + } + + return FALSE; +} + +//=========================================================================== +BOOL APIENTRY SErrGetErrorStr (DWORD errorcode, + LPTSTR buffer, + DWORD bufferchars) { + VALIDATEBEGIN; + VALIDATE(buffer); + VALIDATE(bufferchars); + VALIDATEEND; + + // ENTER THE CRITICAL SECTION + InternalEnterCriticalSection(); + + // IF WE HAVEN'T ADDED OUR OWN MESSAGE FACILITIES TO THE MODULE LIST, + // DO SO NOW + if (!s_msgsrcinit) { + s_msgsrcinit = TRUE; + AddStormMessages(); + } + + // EXTRACT THE ERROR'S FACILITY CODE, AND LOOK UP THE MODULE CONTAINING + // ERROR STRINGS FOR THAT FACILITY + WORD facility = (WORD)((errorcode >> 16) & 0xFFF); + HMODULE module = (HMODULE)0; + { + MSGSRCPTR curr = s_msgsrchead; + while (curr && (curr->facility != facility)) + curr = curr->next; + if (curr) + module = curr->module; + } + + // LEAVE THE CRITICAL SECTION + InternalLeaveCriticalSection(); + + // EXTRACT AND RETURN THE ERROR STRING + *buffer = 0; + return (FormatMessage(module + ? FORMAT_MESSAGE_FROM_HMODULE + : FORMAT_MESSAGE_FROM_SYSTEM, + module, + errorcode, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + buffer, + bufferchars, + NULL) != 0); + +} + +//=========================================================================== +DWORD APIENTRY SErrGetLastError () { +//#ifdef _MAC + return s_lasterror; +//#else +// return GetLastError(); +//#endif +} + +//=========================================================================== +BOOL APIENTRY SErrRegisterMessageSource (WORD facility, + HMODULE module, + LPVOID reserved) { + InternalEnterCriticalSection(); + MSGSRCPTR ptr = (MSGSRCPTR)HeapAlloc(GetProcessHeap(), + HEAP_GENERATE_EXCEPTIONS, + sizeof(MSGSRC)); + ptr->facility = facility; + ptr->module = module; + ptr->next = s_msgsrchead; + s_msgsrchead = ptr; + InternalLeaveCriticalSection(); + return TRUE; +} + +//=========================================================================== +void APIENTRY SErrReportResourceLeak (LPCTSTR handlename) { + + // DETERMINE WHETHER MEMORY TRACKING IS ENABLED +#ifndef _DEBUG + static BOOL checked = FALSE; + static BOOL debugmode = FALSE; + if (!checked) { + checked = TRUE; + SRegLoadValue("Internal","Debug Memory",0,(LPDWORD)&debugmode); + } + if (!debugmode) + return; +#endif + + // DISPLAY THE ERROR + SErrDisplayError(STORM_ERROR_HANDLE_NEVER_RELEASED, + handlename, + SERR_LINECODE_HANDLE, + NULL, + TRUE); + +} + +//=========================================================================== +void APIENTRY SErrSetLastError (DWORD errorcode) { +//#ifdef _MAC + s_lasterror = errorcode; +//#else +// SetLastError(errorcode); +//#endif +} + +//=========================================================================== +void APIENTRY SErrSuppressErrors (BOOL suppress) { + s_suppress = suppress; +} + diff --git a/Storm/SOURCE/SEVT.CPP b/Storm/SOURCE/SEVT.CPP new file mode 100644 index 0000000..01db999 --- /dev/null +++ b/Storm/SOURCE/SEVT.CPP @@ -0,0 +1,482 @@ +/**************************************************************************** +* +* SEVT.CPP +* Storm event dispatching functions +* +* By Michael O'Brien (5/9/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +NODEDECL(BREAKCMD) { + LPVOID data; +} *BREAKCMDPTR; + +typedef struct _IDHASHENTRY { + DWORD id; + DWORD sequence; + SEVTHANDLER handler; + _IDHASHENTRY *next; +} IDHASHENTRY, *IDHASHENTRYPTR; + +typedef struct _IDHASHTABLE { + IDHASHENTRYPTR *data; + DWORD size; + DWORD used; + _IDHASHTABLE *next; +} IDHASHTABLE, *IDHASHTABLEPTR; + +typedef struct _TYPEHASHENTRY { + DWORD type; + DWORD subtype; + DWORD sequence; + IDHASHTABLEPTR idhashtable; + _TYPEHASHENTRY *next; +} TYPEHASHENTRY, *TYPEHASHENTRYPTR; + +static LIST(BREAKCMD) s_breakcmdlist; +static CCritSect s_critsect; +static LONG s_dispatchesinprogress = 0; +static BOOL s_modified; +static TYPEHASHENTRYPTR *s_typehashtable = NULL; +static DWORD s_typehashtablesize = 0; +static DWORD s_typehashtableused = 0; + +//=========================================================================== +static DWORD inline ComputeNewTableSize (DWORD currentused) { + DWORD newsize = 1; + while (newsize <= ((s_typehashtableused+1) << 1)) + newsize <<= 1; + return newsize; +} + +//=========================================================================== +static void CopyIdHashTable (IDHASHTABLEPTR dest, + IDHASHTABLEPTR source) { + + // ALLOCATE SPACE FOR THE TABLE + dest->size = source->size; + dest->used = source->used; + dest->data = (IDHASHENTRYPTR *)ALLOC(dest->size*sizeof(IDHASHENTRYPTR)); + + // FILL IN EACH TABLE SLOT + for (DWORD id = 0; id < source->size; ++id) { + IDHASHENTRYPTR sourcecurr = *(source->data+id); + IDHASHENTRYPTR *destnext = dest->data+id; + while (sourcecurr) { + *destnext = NEW(IDHASHENTRY); + CopyMemory(*destnext,sourcecurr,sizeof(IDHASHENTRY)); + sourcecurr = sourcecurr->next; + destnext = &(*destnext)->next; + } + *destnext = NULL; + } + +} + +//=========================================================================== +static void DeleteIdHashTable (IDHASHTABLEPTR idhashtable) { + for (DWORD id = 0; id < idhashtable->size; ++id) { + IDHASHENTRYPTR currid; + while ((currid = *(idhashtable->data+id)) != NULL) { + *(idhashtable->data+id) = currid->next; + DEL(currid); + } + } + FREE(idhashtable->data); + DEL(idhashtable); +} + +//=========================================================================== +static TYPEHASHENTRYPTR inline FindTypeHashEntry (DWORD type, DWORD subtype) { + if (!(s_typehashtable && s_typehashtablesize)) + return NULL; + + DWORD slot = (type ^ subtype) & (s_typehashtablesize-1); + TYPEHASHENTRYPTR ptr = *(s_typehashtable+slot); + while (ptr && ((ptr->type != type) || (ptr->subtype != subtype))) + ptr = ptr->next; + return ptr; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SEvtBreakHandlerChain (LPVOID data) { + s_critsect.Enter(); + BREAKCMDPTR newcmd = s_breakcmdlist.NewNode(); + newcmd->data = data; + s_critsect.Leave(); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SEvtDestroy () { + s_critsect.Enter(); + for (DWORD type = 0; type < s_typehashtablesize; ++type) { + TYPEHASHENTRYPTR currtype; + while ((currtype = *(s_typehashtable+type)) != NULL) { + IDHASHTABLEPTR currhashtable; + while ((currhashtable = currtype->idhashtable) != NULL) { + currtype->idhashtable = currhashtable->next; + DeleteIdHashTable(currhashtable); + } + *(s_typehashtable+type) = currtype->next; + DEL(currtype); + } + } + if (s_typehashtable) + DEL(s_typehashtable); + s_typehashtable = NULL; + s_typehashtablesize = 0; + s_typehashtableused = 0; + s_modified = TRUE; + s_critsect.Leave(); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SEvtDispatch (DWORD type, + DWORD subtype, + DWORD id, + LPVOID data) { + InterlockedIncrement(&s_dispatchesinprogress); + BOOL success = FALSE; + DWORD currsequence = 0xFFFFFFFF; + IDHASHENTRYPTR currptr = NULL; + for (;;) { + + // ENTER THE CRITICAL SECTION + s_critsect.Enter(); + + // IF THERE IS A BREAK COMMAND FOR THIS HANDLER, EXIT + BOOL breakcmd = FALSE; + ITERATELIST(BREAKCMD,s_breakcmdlist,curr) + if (curr->data == data) { + breakcmd = TRUE; + ITERATE_DELETEANDBREAK; + } + if (breakcmd) { + s_critsect.Leave(); + break; + } + + // IF WE DON'T HAVE A VALID POINTER TO THE NEXT HANDLER RECORD, + // FIND ONE USING THE TYPE, SUBTYPE, ID, AND SEQUENCE + if ((!currptr) || s_modified) { + currptr = NULL; + for (ONCE) { + + // FIND THE TYPE/SUBTYPE ENTRY IN THE TYPE HASH TABLE + TYPEHASHENTRYPTR typeentry = FindTypeHashEntry(type,subtype); + if (!typeentry) + break; + + // FIND THE SLOT FOR THIS ID IN THE TYPE'S ID HASH TABLE + if (!(typeentry->idhashtable->data && typeentry->idhashtable->size)) + break; + DWORD slot = id & (typeentry->idhashtable->size-1); + currptr = *(typeentry->idhashtable->data+slot); + + // FIND THE NEXT HANDLER AFTER THE CURRENT SEQUENCE + while (currptr && + ((currptr->id != id) || + (currptr->sequence >= currsequence))) + currptr = currptr->next; + + // IF WE ARE THE ONLY ACTIVE THREAD CURRENTLY DISPATCHING, THEN + // RESET THE MODIFIED VARIABLE + if (s_dispatchesinprogress == 1) + s_modified = FALSE; + + } + } + + // SAVE THE HANDLER FOR THIS POINTER, AND MOVE THE POINTER AND SEQUENCE + // NUMBER TO THE NEXT RECORD + SEVTHANDLER handler = NULL; + if (currptr) { + handler = currptr->handler; + currsequence = currptr->sequence; + do + currptr = currptr->next; + while (currptr && (currptr->id != id)); + } + + // LEAVE THE CRITICAL SECTION + s_critsect.Leave(); + + // DISPATCH THE EVENT + if (handler) { + success = TRUE; + handler(data); + } + + // IF THIS IS THE LAST HANDLER IN THE CHAIN, EXIT THE LOOP + if (!currptr) + break; + + } + InterlockedDecrement(&s_dispatchesinprogress); + + // CLEAR OUT ANY LEFT-OVER BREAK COMMANDS FOR THIS HANDLER CHAIN + if (s_breakcmdlist.Head()) { + s_critsect.Enter(); + ITERATELIST(BREAKCMD,s_breakcmdlist,curr) + if (curr->data == data) + ITERATE_DELETE; + s_critsect.Leave(); + } + + return success; +} + +//=========================================================================== +BOOL APIENTRY SEvtPopState (DWORD type, + DWORD subtype) { + BOOL success = FALSE; + s_critsect.Enter(); + for (ONCE) { + + // FIND THE TYPE/SUBTYPE ENTRY IN THE TYPE HASH TABLE + TYPEHASHENTRYPTR typeentry = FindTypeHashEntry(type,subtype); + if (!typeentry) + break; + + // CHECK FOR A STACK UNDERFLOW + if (!typeentry->idhashtable->next) { + success = SEvtUnregisterType(type,subtype); + break; + } + + // FREE THE ID HASH TABLE AT THE TOP OF THE STACK + IDHASHTABLEPTR next = typeentry->idhashtable->next; + DeleteIdHashTable(typeentry->idhashtable); + typeentry->idhashtable = next; + + } + s_modified = TRUE; + s_critsect.Leave(); + return success; +} + +//=========================================================================== +BOOL APIENTRY SEvtPushState (DWORD type, + DWORD subtype) { + BOOL success = FALSE; + s_critsect.Enter(); + for (ONCE) { + + // FIND THE TYPE/SUBTYPE ENTRY IN THE TYPE HASH TABLE + TYPEHASHENTRYPTR typeentry = FindTypeHashEntry(type,subtype); + if (!typeentry) + break; + + // MAKE A COPY OF THE ID HASH TABLE + IDHASHTABLEPTR newtable = NEW(IDHASHTABLE); + CopyIdHashTable(newtable,typeentry->idhashtable); + + // LINK IT AT THE HEAD OF THE LIST + newtable->next = typeentry->idhashtable; + typeentry->idhashtable = newtable; + + s_modified = TRUE; + success = TRUE; + } + s_critsect.Leave(); + return success; +} + +//=========================================================================== +BOOL APIENTRY SEvtRegisterHandler (DWORD type, + DWORD subtype, + DWORD id, + DWORD flags, + SEVTHANDLER handler) { + VALIDATEBEGIN; + VALIDATE(handler); + VALIDATE(!flags); + VALIDATEEND; + + s_critsect.Enter(); + + // FIND THE TYPE/SUBTYPE ENTRY IN THE TYPE HASH TABLE + TYPEHASHENTRYPTR typeentry = FindTypeHashEntry(type,subtype); + + // IF WE COULDN'T FIND AN ENTRY, ADD ONE + if (!typeentry) { + + // GROW THE TYPE HASH TABLE IF NECESSARY + if (s_typehashtableused >= (s_typehashtablesize >> 1)) { + + // ALLOCATE A NEW TABLE + DWORD newsize = ComputeNewTableSize(s_typehashtableused); + TYPEHASHENTRYPTR *newtable = (TYPEHASHENTRYPTR *)ALLOCZERO(newsize*sizeof(TYPEHASHENTRYPTR)); + + // REHASH THE OLD TABLE INTO THE NEW TABLE + if (s_typehashtable && s_typehashtablesize) + for (DWORD loop = 0; loop < s_typehashtablesize; ++loop) { + TYPEHASHENTRYPTR ptr = *(s_typehashtable+loop); + while (ptr) { + DWORD slot = (ptr->type ^ ptr->subtype) & (newsize-1); + TYPEHASHENTRYPTR next = ptr->next; + ptr->next = *(newtable+slot); + *(newtable+slot) = ptr; + ptr = next; + } + } + + // REPLACE THE OLD TABLE WITH THE NEW TABLE + if (s_typehashtable) + DEL(s_typehashtable); + s_typehashtable = newtable; + s_typehashtablesize = newsize; + + } + + // CREATE A NEW ENTRY FOR THIS TYPE/SUBTYPE + { + DWORD slot = (type ^ subtype) & (s_typehashtablesize-1); + TYPEHASHENTRYPTR entry = NEWZERO(TYPEHASHENTRY); + entry->type = type; + entry->subtype = subtype; + entry->idhashtable = NEWZERO(IDHASHTABLE); + entry->next = *(s_typehashtable+slot); + *(s_typehashtable+slot) = entry; + ++s_typehashtableused; + typeentry = *(s_typehashtable+slot); + } + + } + + // GROW THE TYPE'S ID HASH TABLE IF NECESSARY + if (typeentry->idhashtable->used >= (typeentry->idhashtable->size >> 1)) { + + // ALLOCATE A NEW TABLE + DWORD newsize = ComputeNewTableSize(typeentry->idhashtable->size); + IDHASHENTRYPTR *newtable = (IDHASHENTRYPTR *)ALLOCZERO(newsize*sizeof(IDHASHENTRYPTR)); + + // REHASH THE OLD TABLE INTO THE NEW TABLE + if (typeentry->idhashtable->data && typeentry->idhashtable->size) + for (DWORD loop = 0; loop < typeentry->idhashtable->size; ++loop) { + IDHASHENTRYPTR ptr = *(typeentry->idhashtable->data+loop); + while (ptr) { + DWORD slot = ptr->id & (newsize-1); + IDHASHENTRYPTR next = ptr->next; + ptr->next = *(newtable+slot); + *(newtable+slot) = ptr; + ptr = next; + } + } + + // REPLACE THE OLD TABLE WITH THE NEW TABLE + if (typeentry->idhashtable->data) + FREE(typeentry->idhashtable->data); + typeentry->idhashtable->data = newtable; + typeentry->idhashtable->size = newsize; + + } + + // CREATE A NEW ENTRY FOR THIS ID + { + DWORD slot = id & (typeentry->idhashtable->size-1); + IDHASHENTRYPTR entry = NEWZERO(IDHASHENTRY); + entry->id = id; + entry->sequence = ++typeentry->sequence; + entry->handler = handler; + entry->next = *(typeentry->idhashtable->data+slot); + *(typeentry->idhashtable->data+slot) = entry; + ++typeentry->idhashtable->used; + } + + s_modified = TRUE; + s_critsect.Leave(); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SEvtUnregisterHandler (DWORD type, + DWORD subtype, + DWORD id, + SEVTHANDLER handler) { + BOOL success = FALSE; + s_critsect.Enter(); + for (ONCE) { + + // FIND THE TYPE/SUBTYPE ENTRY IN THE TYPE HASH TABLE + TYPEHASHENTRYPTR typeentry = FindTypeHashEntry(type,subtype); + if (!typeentry) + return FALSE; + + // FIND THE SLOT FOR THIS ID IN THE TYPE'S ID HASH TABLE + if (!(typeentry->idhashtable->data && typeentry->idhashtable->size)) + return FALSE; + DWORD slot = id & (typeentry->idhashtable->size-1); + + // IF WE WERE GIVEN A POINTER TO A HANDLER, FREE THE ID ENTRY MATCHING + // THE ID AND HANDLER. OTHERWISE, FREE ALL ENTRIES MATCHING THE ID. + IDHASHENTRYPTR *nextptr = typeentry->idhashtable->data+slot; + while (*nextptr) + if (((*nextptr)->id == id) && + ((!handler) || ((*nextptr)->handler == handler))) { + IDHASHENTRYPTR curr = *nextptr; + *nextptr = curr->next; + DEL(curr); + s_modified = TRUE; + success = TRUE; + --typeentry->idhashtable->used; + } + else + nextptr = &(*nextptr)->next; + + } + s_critsect.Leave(); + return success; +} + +//=========================================================================== +BOOL APIENTRY SEvtUnregisterType (DWORD type, + DWORD subtype) { + BOOL success = FALSE; + s_critsect.Enter(); + for (ONCE) { + + // FIND THE TYPE/SUBTYPE ENTRY IN THE TYPE HASH TABLE + TYPEHASHENTRYPTR typeentry = FindTypeHashEntry(type,subtype); + if (!typeentry) + break; + + // FREE ALL ID ENTRIES AND THE ID HASH TABLE FOR THIS TYPE/SUBTYPE + { + IDHASHTABLEPTR currhashtable; + while ((currhashtable = typeentry->idhashtable) != NULL) { + typeentry->idhashtable = currhashtable->next; + DeleteIdHashTable(currhashtable); + } + } + + // FREE THE RECORD FOR THIS TYPE/SUBTYPE + DWORD slot = (type ^ subtype) & (s_typehashtablesize-1); + TYPEHASHENTRYPTR *nextptr = s_typehashtable+slot; + while (*nextptr) + if ((*nextptr) == typeentry) { + TYPEHASHENTRYPTR curr = *nextptr; + *nextptr = curr->next; + DEL(curr); + --s_typehashtableused; + } + else + nextptr = &(*nextptr)->next; + + s_modified = TRUE; + success = TRUE; + } + s_critsect.Leave(); + return success; +} diff --git a/Storm/SOURCE/SFILE.CPP b/Storm/SOURCE/SFILE.CPP new file mode 100644 index 0000000..6c850d2 --- /dev/null +++ b/Storm/SOURCE/SFILE.CPP @@ -0,0 +1,2642 @@ +/**************************************************************************** +* +* SFILE.CPP +* Storm file I/O functions +* +* By Michael O'Brien (6/23/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define CDROM_FALSE 0 +#define CDROM_USEDFORDDA 1 +#define CDROM_TRUE 2 + +#define FILL_UNREQUESTED 0 +#define FILL_REQUESTED 1 +#define FILL_PLAYING 2 +#define FILL_CLOSING 3 + +#define HASH_INDEX 0 +#define HASH_CHECK0 1 +#define HASH_CHECK1 2 +#define HASH_ENCRYPTKEY 3 +#define HASH_ENCRYPTDATA 4 + +#define MPQ_COMPRESSED_PKWARE 0x00000100 +#define MPQ_COMPRESSED_SCOMP 0x00000200 +#define MPQ_COMPRESSEDMASK 0x0000FF00 +#define MPQ_ENCRYPTED 0x00010000 +#define MPQ_ENCRYPTED_FIXLOC 0x00020000 +#define MPQ_ALLOCATED 0x80000000 + +#define RS_IDLE 0 +#define RS_READING 1 +#define RS_SEEKING 2 + +#define DEALLOCATED 0xFFFFFFFE +#define NOBLOCK 0xFFFFFFFF +#define SIGNATURE 0x1A51504D +#define DATACHUNKSIZE 0x20000 +#define WAVECHUNKSIZE 0x4000 +#define READAHEAD 0x1000 + +#define KEYCONTAINER "Blizzard_Storm" +#define SIGNATUREFILE "(signature)" +#define LISTFILE "(listfile)" +#define AUTHCOMPANIES 1 + +typedef struct _AUTHCOMPANYINFO { + LPCTSTR keyname; + DWORD authresult; +} AUTHCOMPANYINFO, *AUTHCOMPANYINFOPTR; + +typedef struct _CRYPTOAPI { + BOOL (APIENTRY *CryptAcquireContext )(HCRYPTPROV *,LPCTSTR,LPCTSTR,DWORD,DWORD); + BOOL (APIENTRY *CryptCreateHash )(HCRYPTPROV,ALG_ID,HCRYPTKEY,DWORD,HCRYPTHASH *); + BOOL (APIENTRY *CryptDestroyHash )(HCRYPTHASH); + BOOL (APIENTRY *CryptDestroyKey )(HCRYPTKEY); + BOOL (APIENTRY *CryptHashData )(HCRYPTHASH,BYTE *,DWORD,DWORD); + BOOL (APIENTRY *CryptImportKey )(HCRYPTPROV,BYTE *,DWORD,HCRYPTKEY,DWORD,HCRYPTKEY *); + BOOL (APIENTRY *CryptReleaseContext )(HCRYPTPROV,DWORD); + BOOL (APIENTRY *CryptSignHash )(HCRYPTHASH,DWORD,LPCTSTR,DWORD,BYTE *,DWORD *); + BOOL (APIENTRY *CryptVerifySignature)(HCRYPTHASH,BYTE *,DWORD,HCRYPTKEY,LPCTSTR,DWORD); +} CRYPTOAPI, *CRYPTOAPIPTR; + +typedef struct _SIGNATUREHEADER { + DWORD companyid; + DWORD reserved; +} SIGNATUREHEADER, *SIGNATUREHEADERPTR; + +typedef struct _FILEHEADER { + DWORD signature; + DWORD headersize; + DWORD filesize; + WORD version; + WORD sectorsizeid; + DWORD hashoffset; + DWORD blockoffset; + DWORD hashcount; + DWORD blockcount; +} FILEHEADER, *FILEHEADERPTR; + +typedef struct _HASHENTRY { + DWORD hashcheck[2]; + LCID lcid; + DWORD block; +} HASHENTRY, *HASHENTRYPTR; + +typedef struct _BLOCKENTRY { + DWORD offset; + DWORD sizealloc; + DWORD sizefile; + DWORD flags; +} BLOCKENTRY, *BLOCKENTRYPTR; + +NODEDECL(ARCHIVEREC) { + char name[MAX_PATH]; + HANDLE handle; + BOOL cdrom; + int priority; + LPVOID sectorfile; + DWORD sectorlocation; + DWORD sectorsize; + LPBYTE sectorbuffer; + DWORD sectorbytesread; + DWORD startinglocation; + BLOCKENTRYPTR blocktable; + FILEHEADERPTR fileheader; + HASHENTRYPTR hashtable; + DWORD lastlocation; +} *ARCHIVEPTR; + +NODEDECL(FILEREC) { + char name[MAX_PATH]; + HANDLE handle; + ARCHIVEPTR archive; + BLOCKENTRYPTR block; + DWORD key; + DWORD location; + DWORD lastlocation; + DWORD sectors; + LPDWORD sectoroffsettable; + BOOL sectoroffsettablevalid; + BOOL dda; + LPVOID readaheadbuffer; + DWORD readaheadoffset; + DWORD readaheadbytes; +} *FILEPTR; + +typedef struct CKINFO { + DWORD size; + DWORD offset; +} CKINFO; + +NODEDECL(AUDIOSTREAM) { + FILEPTR file; + DWORD nextwrite; + DWORD bytespersecond; + BOOL loop; + DWORD fillstatus; + DWORD bytespastend; + DWORD startinglocation; + DWORD totalsize; + LONG volume; + LONG pan; + LPDIRECTSOUNDBUFFER soundbuffer; + DWORD soundbuffersize; + BYTE fillvalue; +} *AUDIOSTREAMPTR; + +NODEDECL(REQUEST) { + HANDLE event; + FILEPTR file; + DWORD location; + DWORD approxarchivelocation; + DWORD requiredcompletiontime; + LPVOID buffer; + LPDIRECTSOUNDBUFFER soundbuffer; + DWORD soundbufferoffset; + AUDIOSTREAMPTR stream; + DWORD bytestoread; + BOOL autodelrequest; + DWORD bytesread; + DWORD sequence; + DWORD dependentsequence; +} *REQUESTPTR; + +static const AUTHCOMPANYINFO s_authcompany[AUTHCOMPANIES] = {{"BLIZZARDKEY",SFILE_AUTH_AUTHENTICBLIZZARD}}; + +static LIST(ARCHIVEREC) s_archivelist; +static char s_basepath[MAX_PATH] = ""; +static HANDLE s_cdevent = INVALID_HANDLE_VALUE; +static LIST(REQUEST) s_cdreqlist; +static BOOL s_cdshutdown = 0; +static HANDLE s_cdthread = INVALID_HANDLE_VALUE; +static CCritSect s_critsect; +static LPDIRECTSOUND s_directsound = NULL; +static BOOL s_enabledirect = 0; +static LPVOID s_explodebuffer = NULL; +static LIST(FILEREC) s_filelist; +static LPDWORD s_hashsource = NULL; +static DWORD s_ioerrormode = SFILE_ERRORMODE_FATAL; +static SFILEERRORPROC s_ioerrorproc = NULL; +static LCID s_lcid = MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT); +static LPVOID s_soundreadbuffer = NULL; +static LIST(AUDIOSTREAM) s_streamlist; + +#ifdef _DEBUG +static CSLog s_log("Internal","SFile Trace File"); +#define TRACEHANDLE s_log.GetHandle() +#define TRACEOUT SLogWrite +#else +#define TRACEHANDLE 0 +#define TRACEOUT +#endif + +/**************************************************************************** +* +* DATA DECOMPRESSION (PKWARE) SUPPORT +* +***/ + +typedef struct _DECOMPRESSIONINFO { + LPVOID sourcebuffer; + DWORD sourceoffset; + LPVOID destbuffer; + DWORD destoffset; + DWORD bytes; +} DECOMPRESSIONINFO, *DECOMPRESSIONPTR; + +//=========================================================================== +static UINT __cdecl DecompressLzw_BufferRead (LPSTR buffer, + UINT *size, + LPVOID param) { + DECOMPRESSIONPTR infoptr = (DECOMPRESSIONPTR)param; + UINT bytes = min(*size,infoptr->bytes-infoptr->sourceoffset); + CopyMemory(buffer,(LPSTR)infoptr->sourcebuffer+infoptr->sourceoffset,bytes); + infoptr->sourceoffset += bytes; + return bytes; +} + +//=========================================================================== +static void __cdecl DecompressLzw_BufferWrite (LPSTR buffer, + UINT *size, + LPVOID param) { + DECOMPRESSIONPTR infoptr = (DECOMPRESSIONPTR)param; + CopyMemory((LPSTR)infoptr->destbuffer+infoptr->destoffset,buffer,*size); + infoptr->destoffset += *size; +} + +//=========================================================================== +static BOOL DecompressLzw (LPBYTE dest, LPBYTE source, DWORD sourcebytes) { + + // CREATE A DECOMPRESSION BUFFER IF ONE DOES NOT ALREADY EXIST + if (!s_explodebuffer) + s_explodebuffer = ALLOC(EXP_BUFFER_SIZE); + + // CREATE AN INFORMATION RECORD + DECOMPRESSIONINFO info; + info.sourcebuffer = source; + info.sourceoffset = 0; + info.destbuffer = dest; + info.destoffset = 0; + info.bytes = sourcebytes; + + // PERFORM THE DECOMPRESSION + explode(DecompressLzw_BufferRead, + DecompressLzw_BufferWrite, + (LPSTR)s_explodebuffer, + &info); + + return 1; +} + +/**************************************************************************** +* +* DATA DECRYPTION SUPPORT +* +***/ + +//=========================================================================== +static void inline Decrypt (LPDWORD data, DWORD bytes, DWORD key) { + DWORD adjust = 0xEEEEEEEE; + DWORD iter = bytes >> 2; + while (iter--) { + adjust += *(s_hashsource+(HASH_ENCRYPTDATA << 8)+(key & 0xFF)); + adjust += (*data++ ^= adjust+key)+(adjust << 5)+3; + key = (key >> 11) | ((key << 21) ^ 0xFFE00000)+0x11111111; + } +} + +/**************************************************************************** +* +* MOPAQ FILE PROCESSING FUNCTIONS +* +***/ + +static BOOL ReadFileChecked (HANDLE file, + LPVOID buffer, + DWORD bytestoread, + DWORD *bytesread, + LPOVERLAPPED overlapped, + LPCTSTR filename); + +//=========================================================================== +static DWORD inline Hash (LPCSTR filename, int hashtype) { + DWORD result = 0x7FED7FED; + DWORD adjust = 0xEEEEEEEE; + while (filename && *filename) { + char origchar = toupper(*filename++); + result = (result+adjust) ^ *(s_hashsource+(hashtype << 8)+origchar); + adjust += origchar+result+(adjust << 5)+3; + } + return result; +} + +//=========================================================================== +static DWORD inline Hash (LPCWSTR filename, int hashtype) { + DWORD result = 0x7FED7FED; + DWORD adjust = 0xEEEEEEEE; + while (filename && *filename) { + char origchar = toupper((char)((*filename++) & 0xFF)); + result = (result+adjust) ^ *(s_hashsource+(hashtype << 8)+origchar); + adjust += origchar+result+(adjust << 5)+3; + } + return result; +} + +//=========================================================================== +static void inline InitializeHashSource () { + if (!s_hashsource) + return; + DWORD seed = 0x100001; + for (int loop1 = 0; loop1 < 256; ++loop1) + for (int loop2 = 0; loop2 < 5; ++loop2) { + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand1 = seed & 0xFFFF; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand2 = seed & 0xFFFF; + *(s_hashsource+(loop2 << 8)+loop1) = (rand1 << 16) | rand2; + } +} + +//=========================================================================== +static DWORD InternalReadAligned (FILEPTR file, + DWORD location, + LPVOID buffer, + DWORD bytes) { + + // ENSURE THAT THE READ IS SECTOR ALIGNED + VALIDATEBEGIN; + VALIDATE(!(location & (file->archive->sectorsize-1))); + VALIDATE(!(bytes & (file->archive->sectorsize-1))); + VALIDATEEND; + + // CHECK FOR A NULL READ + if (!bytes) + return FALSE; + + // IF THIS FILE IS COMPRESSED AND WE HAVEN'T YET READ THE SECTOR + // OFFSET TABLE, READ IT NOW + if ((file->block->flags & MPQ_COMPRESSEDMASK) && + !file->sectoroffsettablevalid) { + if (file->block->offset != file->archive->lastlocation) + SetFilePointer(file->archive->handle,file->block->offset,NULL,FILE_BEGIN); + DWORD bytesread = 0; + ReadFileChecked(file->archive->handle, + file->sectoroffsettable, + (file->sectors+1)*sizeof(DWORD), + &bytesread, + NULL, + file->archive->name); + if (file->block->flags & MPQ_ENCRYPTED) + Decrypt((LPDWORD)file->sectoroffsettable, + bytesread, + file->key+0xFFFFFFFF); + file->sectoroffsettablevalid = TRUE; + file->archive->lastlocation = file->block->offset+bytesread; + } + + // DETERMINE THE DISK LOCATION AND SIZE, GIVEN THE UNCOMPRESSED LOCATION + // AND SIZE + DWORD disklocation = location; + DWORD diskbytes = bytes; + if (file->block->flags & MPQ_COMPRESSEDMASK) { + disklocation = *(file->sectoroffsettable+location/file->archive->sectorsize); + diskbytes = *(file->sectoroffsettable+(location+bytes)/file->archive->sectorsize) + -disklocation; + } + + // PROVIDE A SECONDARY BUFFER IF NECESSARY FOR DECOMPRESSION + LPVOID diskbuffer = buffer; + if (file->block->flags & MPQ_COMPRESSEDMASK) + diskbuffer = ALLOC(diskbytes+sizeof(DWORD)); + + // SET THE ARCHIVE FILE POINTER IF NECESSARY + DWORD archivelocation = file->block->offset+disklocation; + if (archivelocation != file->archive->lastlocation) + SetFilePointer(file->archive->handle,archivelocation,NULL,FILE_BEGIN); + + // PERFORM THE READ + DWORD diskbytesread = 0; + ReadFileChecked(file->archive->handle, + diskbuffer, + diskbytes, + &diskbytesread, + NULL, + file->archive->name); + + // SAVE THE NEW ARCHIVE FILE POINTER + file->archive->lastlocation = archivelocation+diskbytesread; + + // IF WE WERE NOT ABLE TO READ THE ENTIRE REQUEST, DETERMINE A NUMBER OF + // UNCOMPRESSED BYTES THAT WE KNOW AT A MINIMUM WE READ SUCCESSFULLY + DWORD bytesread = bytes; + if (diskbytesread < diskbytes) + if (file->block->flags & MPQ_COMPRESSEDMASK) { + bytesread = 0; + DWORD checksector = location/file->archive->sectorsize+1; + while ((checksector <= file->sectors) && + (diskbytesread >= (*(file->sectoroffsettable+checksector)-disklocation))) { + ++checksector; + bytesread += file->archive->sectorsize; + } + } + else + bytesread = diskbytesread; + + // DECRYPT THE DATA IF NECESSARY + if (file->block->flags & MPQ_ENCRYPTED) { + DWORD offset = 0; + DWORD sector = location/file->archive->sectorsize; + DWORD sectors = (bytesread+file->archive->sectorsize-1)/file->archive->sectorsize; + while ((sector < file->sectors) && sectors--) { + DWORD processbytes; + if (file->block->flags & MPQ_COMPRESSEDMASK) + processbytes = *(file->sectoroffsettable+sector+1)-*(file->sectoroffsettable+sector); + else { + processbytes = min(file->archive->sectorsize,bytesread-offset); + if ((sector == file->sectors-1) && + (file->block->sizefile & (file->archive->sectorsize-1))) + processbytes = min(processbytes,file->block->sizefile & (file->archive->sectorsize-1)); + } + Decrypt((LPDWORD)((LPBYTE)diskbuffer+offset), + processbytes & 0xFFFFFFFC, + file->key+sector); + ++sector; + offset += processbytes; + } + } + + // DECOMPRESS THE DATA IF NECESSARY + if (file->block->flags & MPQ_COMPRESSEDMASK) { + DWORD destoffset = 0; + DWORD sourceoffset = 0; + DWORD sector = location/file->archive->sectorsize; + DWORD sectors = (bytesread+file->archive->sectorsize-1)/file->archive->sectorsize; + while ((sector < file->sectors) && sectors--) { + DWORD sourcebytes = *(file->sectoroffsettable+sector+1)-*(file->sectoroffsettable+sector); + DWORD targetbytes = (sector == file->sectors-1) + ? (file->block->sizefile && !(file->block->sizefile & (file->archive->sectorsize-1))) + ? file->archive->sectorsize + : (file->block->sizefile & (file->archive->sectorsize-1)) + : file->archive->sectorsize; + if (targetbytes > sourcebytes) + switch (file->block->flags & MPQ_COMPRESSEDMASK) { + + case MPQ_COMPRESSED_PKWARE: + DecompressLzw((LPBYTE)buffer+destoffset, + (LPBYTE)diskbuffer+sourceoffset, + sourcebytes); + break; + + case MPQ_COMPRESSED_SCOMP: + { + DWORD destsize = targetbytes; + SCompDecompress((LPBYTE)buffer+destoffset, + &destsize, + (LPBYTE)diskbuffer+sourceoffset, + sourcebytes); + } + break; + + } + else if (diskbuffer != buffer) + CopyMemory((LPBYTE)buffer+destoffset, + (LPBYTE)diskbuffer+sourceoffset, + targetbytes); + destoffset += targetbytes; + sourceoffset += sourcebytes; + ++sector; + } + } + + // FREE THE DECOMPRESSION BUFFER IF NECESSARY + if (diskbuffer != buffer) + FREE(diskbuffer); + + // RETURN THE NUMBER OF BYTES READ + return bytesread; +} + +//=========================================================================== +static DWORD InternalReadAlignedSector (FILEPTR file, + DWORD location) { + + // IF THIS SECTOR IS ALREADY IN THE SECTOR BUFFER, JUST RETURN THE + // PREVIOUS RESULTS + if ((file->archive->sectorfile == file) && + (file->archive->sectorlocation == location)) + return file->archive->sectorbytesread; + + // OTHERWISE, READ THE SECTOR + file->archive->sectorfile = file; + file->archive->sectorlocation = location; + file->archive->sectorbytesread = InternalReadAligned(file, + location, + file->archive->sectorbuffer, + file->archive->sectorsize); + + return file->archive->sectorbytesread; +} + +//=========================================================================== +static DWORD InternalReadUnaligned (FILEPTR file, + DWORD location, + LPVOID buffer, + DWORD bytes) { + + // CLIP THE READ SIZE AGAINST THE END OF THE FILE + if (file->block->sizefile <= location) + return 0; + else + bytes = min(bytes,file->block->sizefile-location); + + // READ THE FIRST SECTOR + DWORD firstbytesread = 0; + if (location & (file->archive->sectorsize-1)) { + DWORD sectorbytesread = InternalReadAlignedSector(file,location & ~(file->archive->sectorsize-1)); + DWORD unalignedbytes = min(bytes,file->archive->sectorsize-(location & (file->archive->sectorsize-1))); + CopyMemory(buffer, + file->archive->sectorbuffer+(location & (file->archive->sectorsize-1)), + unalignedbytes); + buffer = (LPBYTE)buffer+unalignedbytes; + bytes -= unalignedbytes; + if ((sectorbytesread != file->archive->sectorsize) || !bytes) + if (sectorbytesread < (location & (file->archive->sectorsize-1))) + return 0; + else + return min(unalignedbytes,sectorbytesread-(location & (file->archive->sectorsize-1))); + else + firstbytesread = unalignedbytes; + location += unalignedbytes; + } + + // READ IN THE MIDDLE SECTORS + DWORD middlebytesread = 0; + if (bytes) { + DWORD middlebytes = bytes & ~(file->archive->sectorsize-1); + middlebytesread = InternalReadAligned(file, + location, + buffer, + bytes & ~(file->archive->sectorsize-1)); + buffer = (LPBYTE)buffer+middlebytes; + bytes -= middlebytes; + location += middlebytes; + if ((middlebytes != middlebytesread) || !bytes) + return firstbytesread+middlebytesread; + } + + // READ IN THE LAST SECTOR + DWORD lastbytesread = 0; + if (bytes) { + DWORD sectorbytesread = InternalReadAlignedSector(file,location); + CopyMemory(buffer, + file->archive->sectorbuffer, + bytes); + lastbytesread = min(bytes,sectorbytesread); + } + + return firstbytesread+middlebytesread+lastbytesread; +} + +//=========================================================================== +static BOOL ReadFileChecked (HANDLE file, + LPVOID buffer, + DWORD bytestoread, + DWORD *bytesread, + LPOVERLAPPED overlapped, + LPCTSTR filename) { + for (;;) { + BOOL result = ReadFile(file, + buffer, + bytestoread, + bytesread, + overlapped); + if (result && (*bytesread == bytestoread)) + return TRUE; + DWORD errorcode = GetLastError(); + switch (s_ioerrormode) { + + case SFILE_ERRORMODE_RETURNCODE: + return result; + + case SFILE_ERRORMODE_CUSTOM: + if ((!s_ioerrorproc) || + (!s_ioerrorproc(filename,errorcode))) + return result; + break; + + case SFILE_ERRORMODE_FATAL: + SErrDisplayError(errorcode, + filename, + SERR_LINECODE_FILE, + NULL, + FALSE, + 1); + break; + + } + } +} + +//=========================================================================== +static DWORD inline SearchHashTable (ARCHIVEPTR archive, LPCTSTR filename, LCID lcid) { + DWORD hashindex = Hash(filename,HASH_INDEX); + DWORD hashcheck0 = Hash(filename,HASH_CHECK0); + DWORD hashcheck1 = Hash(filename,HASH_CHECK1); + DWORD entry = hashindex & (archive->fileheader->hashcount-1); + DWORD firstentry = entry; + DWORD found = 0xFFFFFFFF; + while ((archive->hashtable+entry)->block != NOBLOCK) { + if (((archive->hashtable+entry)->hashcheck[0] == hashcheck0) && + ((archive->hashtable+entry)->hashcheck[1] == hashcheck1) && + ((archive->hashtable+entry)->block != DEALLOCATED)) + if ((archive->hashtable+entry)->lcid == lcid) + return entry; + else if ((archive->hashtable+entry)->lcid == MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)) + found = entry; + entry = (entry+1) & (archive->fileheader->hashcount-1); + if (entry == firstentry) + break; + } + return found; +} + +/**************************************************************************** +* +* STREAMING AND OVERLAPPED I/O FUNCTIONS +* +***/ + +static REQUESTPTR IssueRequest (FILEPTR file, + DWORD locationoffset, + LPVOID buffer, + LPDIRECTSOUNDBUFFER soundbuffer, + DWORD soundbufferoffset, + AUDIOSTREAMPTR stream, + DWORD bytestoread, + DWORD requiredms, + DWORD dependentsequence, + HANDLE event, + BOOL autodelrequest, + BOOL triggerreadthread, + DWORD *sequence); + +//=========================================================================== +static inline BOOL CanProcessRequest (REQUESTPTR request) { + DWORD dependentsequence = request->dependentsequence; + if (dependentsequence) + ITERATELIST(REQUEST,s_cdreqlist,curr) + if (curr->sequence == dependentsequence) + return FALSE; + return TRUE; +} + +//=========================================================================== +static DWORD CALLBACK CdThreadProc (LPVOID) { + ARCHIVEPTR lastarchive = NULL; + DWORD lastarchivelocation = 0; + while (!s_cdshutdown) { + BOOL processed; + do { + processed = 0; + + // IF THERE ARE ANY ACTIVE AUDIO STREAMS, ISSUE READ REQUESTS AS + // NECESSARY TO KEEP THEIR BUFFERS FULL + s_critsect.Enter(); + { + AUDIOSTREAMPTR curr = s_streamlist.Head(); + while (curr) { + + // IF THIS STREAM HAS REACHED THE END OF THE WAVE FILE, EITHER LOOP + // OR WAIT UNTIL THE BUFFER IS DONE PLAYING BEFORE CLOSING THE + // STREAM + if ((curr->fillstatus == FILL_CLOSING) || + ((curr->fillstatus == FILL_PLAYING) && + (curr->file->location >= curr->totalsize))) + if (curr->loop) + curr->file->location = curr->startinglocation; + else { + DWORD playcursor = 0; + DWORD writecursor = 0; + curr->soundbuffer->GetCurrentPosition(&playcursor,&writecursor); + if (((playcursor-curr->nextwrite) % curr->soundbuffersize) >= WAVECHUNKSIZE) { + DWORD sizeneeded = min(WAVECHUNKSIZE,curr->soundbuffersize-curr->nextwrite); + LPVOID buffer = NULL; + DWORD bytes = sizeneeded; + if (curr->soundbuffer->Lock(curr->nextwrite, + sizeneeded, + &buffer, + &bytes, + NULL, + NULL, + 0) == DS_OK) { + FillMemory(buffer,bytes,curr->fillvalue); + curr->soundbuffer->Unlock(buffer, + bytes, + NULL, + 0); + curr->bytespastend += bytes; + curr->nextwrite += bytes; + if (curr->nextwrite >= curr->soundbuffersize) + curr->nextwrite -= curr->soundbuffersize; + } + } + curr->fillstatus = FILL_CLOSING; + } + + // IF THIS STREAM IS CURRENTLY PLAYING, CHECK WHETHER THERE IS ROOM + // TO LOAD ANOTHER CHUNK OF DATA + if (curr->fillstatus == FILL_PLAYING) { + DWORD playcursor = 0; + DWORD writecursor = 0; + curr->soundbuffer->GetCurrentPosition(&playcursor,&writecursor); + if (((playcursor-curr->nextwrite) % curr->soundbuffersize) >= WAVECHUNKSIZE) { + DWORD sizeneeded = min(WAVECHUNKSIZE,curr->soundbuffersize-curr->nextwrite); + sizeneeded = min(sizeneeded,curr->totalsize-curr->file->location); + IssueRequest(curr->file, + curr->file->location, + NULL, + curr->soundbuffer, + curr->nextwrite, + curr, + sizeneeded, + ((curr->soundbuffersize-0x20000)*1000)/curr->bytespersecond, + 0, + NULL, + TRUE, + FALSE, + NULL); + curr->file->location += sizeneeded; + curr->nextwrite += (curr->loop ? sizeneeded : WAVECHUNKSIZE); + if (curr->nextwrite >= curr->soundbuffersize) + curr->nextwrite -= curr->soundbuffersize; + } + } + + // IF THIS STREAM IS NOT YET PLAYING, ISSUE THE INITIAL REQUESTS + // TO FILL THE BUFFER + else if (curr->fillstatus == FILL_UNREQUESTED) { + DWORD offset = 0; + DWORD maxoffset = min(curr->soundbuffersize,curr->totalsize); + DWORD timeoffset = 0; + while (offset < maxoffset) { + IssueRequest(curr->file, + curr->file->location, + NULL, + curr->soundbuffer, + offset, + curr, + min(WAVECHUNKSIZE,maxoffset-offset), + 1000+(timeoffset += 500), + 0, + NULL, + TRUE, + FALSE, + NULL); + curr->file->location += WAVECHUNKSIZE; + offset += WAVECHUNKSIZE; + } + curr->fillstatus = FILL_REQUESTED; + curr->nextwrite = offset % curr->soundbuffersize; + } + + curr = curr->Next(); + } + } + + // FIND THE MOST URGENT REQUEST, AND THE REQUEST WHICH IS NEXT IN + // SEEK ORDER + REQUESTPTR nextreq = NULL; + REQUESTPTR urgentreq = NULL; + DWORD lowcompletetime = UINT_MAX; + { + DWORD lowseektime = UINT_MAX; + DWORD currtime = GetTickCount(); + ITERATELIST(REQUEST,s_cdreqlist,curr) + if (CanProcessRequest(curr)) { + + // CHECK THIS REQUEST FOR SEEK ORDER + { + DWORD adjlastlocation = 0; + if (lastarchivelocation > curr->file->archive->sectorsize) + adjlastlocation = lastarchivelocation-curr->file->archive->sectorsize; + DWORD seektime; + if (curr->file->archive == lastarchive) + if (curr->approxarchivelocation < adjlastlocation) + seektime = 0x8000000+curr->approxarchivelocation; + else + seektime = curr->approxarchivelocation-adjlastlocation; + else + seektime = UINT_MAX-1; + if (seektime <= lowseektime) { + lowseektime = seektime; + nextreq = curr; + } + } + + // CHECK THIS REQUEST FOR URGENCY + { + DWORD completetime; + if (currtime-curr->requiredcompletiontime < 0x7FFFFFFF) + completetime = 0; + else + completetime = curr->requiredcompletiontime-currtime; + if (completetime <= lowcompletetime) { + lowcompletetime = completetime; + urgentreq = curr; + } + } + + } + } + s_critsect.Leave(); + + // IF THE MOST URGENT REQUEST MUST COMPLETE IN THE NEXT + // 700 MILLISECONDS, PROCESS THAT REQUEST. OTHERWISE, PROCESS + // THE NEXT REQUEST IN SEEK ORDER + REQUESTPTR request = NULL; + if (urgentreq && (lowcompletetime <= 700)) + request = urgentreq; + else if (nextreq) + request = nextreq; + + // PERFORM THE REQUEST + if (request) { + + // READ THE DATA FROM CD + lastarchive = request->file->archive; + lastarchivelocation = request->approxarchivelocation; + LPVOID readbuffer = request->buffer; + if (request->soundbuffer) + readbuffer = s_soundreadbuffer; + if (readbuffer) + request->bytesread = InternalReadUnaligned(request->file, + request->location, + readbuffer, + request->bytestoread); + else + request->bytesread = 0; + + // IF THE DATA IS GOING INTO A SOUND BUFFER, LOCK THE SOUND BUFFER + // AND MOVE THE DATA + if (request->soundbuffer) { + request->soundbuffer->Lock(request->soundbufferoffset, + request->bytestoread, + &request->buffer, + &request->bytestoread, + NULL, + NULL, + 0); + CopyMemory(request->buffer,readbuffer,request->bytesread); + DWORD fullbytes = min(WAVECHUNKSIZE,request->stream->soundbuffersize-request->soundbufferoffset); + if ((request->bytesread < fullbytes) && !request->stream->loop) + FillMemory((LPBYTE)request->buffer+request->bytesread,fullbytes-request->bytesread,request->stream->fillvalue); + request->soundbuffer->Unlock(request->buffer, + request->bytestoread, + NULL, + 0); + if ((request->stream->fillstatus == FILL_REQUESTED) && + ((request->location+request->bytestoread >= request->stream->soundbuffersize) || + (request->location+request->bytestoread-request->stream->startinglocation >= request->stream->totalsize))) { + request->stream->soundbuffer->Play(0,0,DSBPLAY_LOOPING); + request->stream->fillstatus = FILL_PLAYING; + } + } + + // REMOVE THIS REQUEST + s_critsect.Enter(); + processed = TRUE; + HANDLE event = request->event; + if (request->autodelrequest) + s_cdreqlist.DeleteNode(request); + else + s_cdreqlist.UnlinkNode(request); + s_critsect.Leave(); + if (event) + SetEvent(event); + + } + + } while (processed); + WaitForSingleObject(s_cdevent,s_streamlist.IsEmpty() ? INFINITE : 250); + } + s_cdshutdown = FALSE; + _endthreadex(0); + return 0; +} + +//=========================================================================== +static void CreateCdThread () { + if (s_cdthread != INVALID_HANDLE_VALUE) + return; + s_cdevent = CreateEvent((LPSECURITY_ATTRIBUTES)NULL, + 0, + 0, + NULL); + DWORD threadid; + s_cdthread = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + CdThreadProc, + NULL, + 0, + &threadid); + SetThreadPriority(s_cdthread,THREAD_PRIORITY_ABOVE_NORMAL); +} + +//=========================================================================== +static REQUESTPTR IssueRequest (FILEPTR file, + DWORD offset, + LPVOID buffer, + LPDIRECTSOUNDBUFFER soundbuffer, + DWORD soundbufferoffset, + AUDIOSTREAMPTR stream, + DWORD bytestoread, + DWORD requiredms, + DWORD dependentsequence, + HANDLE event, + BOOL autodelrequest, + BOOL triggerreadthread, + DWORD *sequence) { + VALIDATEBEGIN; + VALIDATE(buffer || soundbuffer); + VALIDATEEND; + + // CREATE A REQUEST RECORD + s_critsect.Enter(); + static DWORD currsequence = 0; + REQUESTPTR request = s_cdreqlist.NewNode(); + DWORD requestsequence = 0; + request->event = event; + request->file = file; + request->location = offset; + request->approxarchivelocation = file->block->offset+offset/2; + request->requiredcompletiontime = GetTickCount()+requiredms; + request->buffer = buffer; + request->soundbuffer = soundbuffer; + request->soundbufferoffset = soundbufferoffset; + request->stream = stream; + request->bytestoread = bytestoread; + request->autodelrequest = autodelrequest; + request->dependentsequence = dependentsequence; + do + requestsequence = request->sequence = ++currsequence; + while (!requestsequence); + s_critsect.Leave(); + + // TRIGGER THE CD READ THREAD + if (triggerreadthread) + SetEvent(s_cdevent); + + if (sequence) + *sequence = requestsequence; + return request; +} + +/**************************************************************************** +* +* SUPPORT/UTILITY FUNCTIONS +* +***/ + +//=========================================================================== +static void BuildDefaultBasePath () { + GetModuleFileName(GetModuleHandle(NULL),s_basepath,MAX_PATH); + { + LPTSTR separator = SStrChr(s_basepath,'\\'); + while (separator && SStrChr(separator+1,'\\')) + separator = SStrChr(separator+1,'\\'); + if (separator) + *separator = 0; + } + SStrPack(s_basepath,"\\",MAX_PATH); +} + +//=========================================================================== +static BOOL CheckArchiveHandle (HSARCHIVE archive, ARCHIVEPTR *archiveptr) { + + // CONVERT THE FILE HANDLE INTO AN ARCHIVE POINTER + *archiveptr = (ARCHIVEPTR)archive; + + // DETERMINE WHETHER THE ARCHIVE POINTER IS VALID + BOOL valid = FALSE; + ITERATELIST(ARCHIVEREC,s_archivelist,currptr) + if (currptr == *archiveptr) { + valid = TRUE; + break; + } + + // IF IT IS VALID, RETURN SUCCESS + if (valid) + return TRUE; + + // OTHERWISE, SET THE ERROR CODE + SErrSetLastError(SFILE_ERROR_INVALID_HANDLE); + + // GENERATE AN ERROR MESSAGE + switch (s_ioerrormode) { + + case SFILE_ERRORMODE_CUSTOM: + if (s_ioerrorproc) + s_ioerrorproc("", + SFILE_ERROR_INVALID_HANDLE); + break; + + case SFILE_ERRORMODE_FATAL: + SErrDisplayError(SFILE_ERROR_INVALID_HANDLE, + "HSARCHIVE", + SERR_LINECODE_HANDLE, + NULL, + TRUE, + 1); + break; + + } + + return FALSE; +} + +//=========================================================================== +static BOOL CheckFileHandle (HSFILE file, FILEPTR *fileptr) { + + // CONVERT THE FILE HANDLE INTO A FILE POINTER + *fileptr = (FILEPTR)file; + + // DETERMINE WHETHER THE FILE POINTER IS VALID + BOOL valid = FALSE; + ITERATELIST(FILEREC,s_filelist,currptr) + if (currptr == *fileptr) { + valid = TRUE; + break; + } + + // IF IT IS VALID, RETURN SUCCESS + if (valid) + return TRUE; + + // OTHERWISE, SET THE ERROR CODE + SErrSetLastError(SFILE_ERROR_INVALID_HANDLE); + + // GENERATE AN ERROR MESSAGE + switch (s_ioerrormode) { + + case SFILE_ERRORMODE_CUSTOM: + if (s_ioerrorproc) + s_ioerrorproc("", + SFILE_ERROR_INVALID_HANDLE); + break; + + case SFILE_ERRORMODE_FATAL: + SErrDisplayError(SFILE_ERROR_INVALID_HANDLE, + "HSFILE", + SERR_LINECODE_HANDLE, + NULL, + TRUE, + 1); + break; + + } + + return FALSE; +} + +//=========================================================================== +static BOOL inline CheckForCdRom (LPCTSTR path) { + + // DETERMINE THE ROOT PATH OF THE DRIVE + char rootpath[4]; + SStrCopy(rootpath,path,4); + + // GET THE DRIVE TYPE + UINT drivetype = GetDriveType(rootpath); + + // GET THE FILE SYSTEM INFORMATION. RETURN FAILURE IF THERE IS NO MEDIA + // IN THE DRIVE. + DWORD fsflags = 0; + char fsname[MAX_PATH]; + ZeroMemory(fsname,MAX_PATH); + if (!GetVolumeInformation(rootpath,NULL,0,NULL,NULL,&fsflags,fsname,MAX_PATH)) + return 0; + + // GET THE SECTOR FORMAT AND NUMBER OF FREE SECTORS + DWORD sectorspercluster = 0; + DWORD bytespersector = 0; + DWORD freeclusters = 0; + DWORD totalclusters = 0; + if (!GetDiskFreeSpace(rootpath,§orspercluster,&bytespersector,&freeclusters,&totalclusters)) + return 0; + + // CONFIRM THAT: + // 1. THE DRIVE TYPE IS CD-ROM + // 2. THE FILE SYSTEM IS CDFS OR UNKNOWN (BLANK) + // 3. THE FILE SYSTEM DOES NOT SUPPORT UNICODE + // 4. THE SECTORS ARE 2048 BYTES EACH + // 5. THERE ARE NO FREE CLUSTERS ON THE DISK + DWORD value = drivetype ^ (*(LPDWORD)fsname) + ^ (fsflags & FS_UNICODE_STORED_ON_DISK) + ^ bytespersector + ^ freeclusters; + WORD check = LOWORD(value) ^ HIWORD(value); + return ((check == 0x1F00) || (check == 0x0805)); +} + +//=========================================================================== +static void ConvertRelativePathName (LPCTSTR inputpath, LPTSTR outputpath) { + + // DETERMINE THE BASE PATH + if (!s_basepath[0]) + BuildDefaultBasePath(); + + // COMBINE THE BASE PATH AND THE INPUT PATH TO FORM THE OUTPUT PATH + char absolutepath[MAX_PATH] = ""; + wsprintf(absolutepath,"%s%s",s_basepath,inputpath); + _fullpath(outputpath,absolutepath,MAX_PATH); + +} + +//=========================================================================== +static BOOL FindChunk (HSFILE handle, FOURCC ckid, CKINFO *pck) { + struct { + FOURCC ckid; + DWORD size; + } ckhdr; + + for (;;) { + if (!SFileReadFile(handle,&ckhdr,sizeof(ckhdr),NULL,NULL)) + return 0; + if (ckhdr.ckid == ckid) + break; + if (SFileSetFilePointer(handle,ckhdr.size,NULL,FILE_CURRENT) == 0xFFFFFFFF) + return 0; + } + + pck->size = ckhdr.size; + pck->offset = SFileSetFilePointer(handle,0,NULL,FILE_CURRENT); + return (pck->offset != 0xFFFFFFFF); +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SFileAuthenticateArchive (HSARCHIVE handle, + DWORD *extendedresult) { + TRACEOUT(TRACEHANDLE, + "SFileAuthenticateArchive(0x%x,*extendedresult)", + handle); + + if (extendedresult) + *extendedresult = SFILE_AUTH_UNABLETOAUTHENTICATE; + + // CHECK THE ARCHIVE HANDLE + ARCHIVEPTR archiveptr; + if (!CheckArchiveHandle(handle,&archiveptr)) + return FALSE; + + // DO A PRELIMINARY CHECK FOR A SIGNATURE BLOCK IN THIS ARCHIVE BEFORE + // WE GO TO ALL THE TROUBLE OF BINDING TO THE CRYPTO API AND SECURITY + // SUPPORT PROVIDER + LCID defaultlcid = MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT); + if (SearchHashTable(archiveptr,SIGNATUREFILE,defaultlcid) == 0xFFFFFFFF) { + if (extendedresult) + *extendedresult = SFILE_AUTH_NOSIGNATURE; + SErrSetLastError(SFILE_ERROR_NOT_AUTHENTICATED); + return 0; + } + + CRYPTOAPIPTR cryptoapi = NULL; + HCRYPTHASH hash = (HCRYPTHASH)0; + HCRYPTKEY key = (HCRYPTKEY)0; + HINSTANCE lib = (HINSTANCE)0; + HANDLE map = (HANDLE)0; + HCRYPTPROV provider = (HCRYPTPROV)0; + BOOL result = 0; + LPVOID view = NULL; + + TRY { + + // BIND TO THE CRYPTOGRAPHY LIBRARY + lib = LoadLibrary("advapi32.dll"); + if (!lib) + LEAVE; + cryptoapi = (CRYPTOAPIPTR)ALLOC(sizeof(CRYPTOAPI)); +#define BIND(a,b) *(void **)&cryptoapi->##a = GetProcAddress(lib,b); \ + if (!cryptoapi->##a) LEAVE; + BIND(CryptAcquireContext ,"CryptAcquireContextA" ); + BIND(CryptCreateHash ,"CryptCreateHash" ); + BIND(CryptDestroyHash ,"CryptDestroyHash" ); + BIND(CryptDestroyKey ,"CryptDestroyKey" ); + BIND(CryptHashData ,"CryptHashData" ); + BIND(CryptImportKey ,"CryptImportKey" ); + BIND(CryptReleaseContext ,"CryptReleaseContext" ); + BIND(CryptSignHash ,"CryptSignHashA" ); + BIND(CryptVerifySignature,"CryptVerifySignatureA"); +#undef BIND + + // INITIALIZE SECURITY SUPPORT + if (!cryptoapi->CryptAcquireContext(&provider,KEYCONTAINER,MS_DEF_PROV,PROV_RSA_FULL,0)) + if (!cryptoapi->CryptAcquireContext(&provider,KEYCONTAINER,MS_DEF_PROV,PROV_RSA_FULL,CRYPT_NEWKEYSET)) + LEAVE; + + // MAP THE ENTIRE ARCHIVE FILE INTO MEMORY + map = CreateFileMapping(archiveptr->handle,NULL,PAGE_READONLY | SEC_COMMIT,0,0,NULL); + if (!map) + LEAVE; + view = MapViewOfFile(map,FILE_MAP_READ,0,0,0); + if (!view) + LEAVE; + + // DETERMINE THE LOCATION OF THE SIGNATURE BLOCK + DWORD index = SearchHashTable(archiveptr,SIGNATUREFILE,defaultlcid); + if (index == 0xFFFFFFFF) + LEAVE; + BLOCKENTRYPTR block = archiveptr->blocktable+(archiveptr->hashtable+index)->block; + if ((block->flags & (MPQ_COMPRESSEDMASK | MPQ_ENCRYPTED)) || + (block->sizefile <= sizeof(SIGNATUREHEADER)) || + !block->offset) { + if (extendedresult) + *extendedresult = SFILE_AUTH_BADSIGNATURE; + LEAVE; + } + + // DETERMINE THE COMPANY ID + DWORD companyid = ((SIGNATUREHEADERPTR)((LPBYTE)view+block->offset))->companyid; + if (companyid >= AUTHCOMPANIES) { + if (extendedresult) + *extendedresult = SFILE_AUTH_UNKNOWNSIGNATURE; + LEAVE; + } + + // LOAD THE APPROPRIATE COMPANY'S PUBLIC KEY INTO THE KEY DATABASE + { + HRSRC resource = FindResource(StormGetInstance(),s_authcompany[companyid].keyname,"#256"); + HGLOBAL handle = LoadResource(StormGetInstance(),resource); + LPVOID ptr = LockResource(handle); + if (ptr) + cryptoapi->CryptImportKey(provider, + (LPBYTE)ptr, + SizeofResource(StormGetInstance(),resource), + NULL, + 0, + &key); + FreeResource(handle); + } + if (!key) + LEAVE; + + // HASH THE ARCHIVE FILE, REPLACING THE SIGNATURE BLOCK WITH ZEROES. + // IF THIS ARCHIVE FILE IS EMBEDDED IN A LARGER FILE, ONLY HASH THE + // MOPAQ PORTION. + if (!cryptoapi->CryptCreateHash(provider,CALG_MD5,NULL,0,&hash)) + LEAVE; + if (!cryptoapi->CryptHashData(hash, + (LPBYTE)view+archiveptr->startinglocation, + block->offset-archiveptr->startinglocation, + 0)) + LEAVE; + { + LPVOID zeroblock = ALLOCZERO(block->sizefile); + BOOL hashresult = cryptoapi->CryptHashData(hash, + (LPBYTE)zeroblock, + block->sizefile, + 0); + FREE(zeroblock); + if (!hashresult) + LEAVE; + } + if (block->offset+block->sizefile < archiveptr->startinglocation+archiveptr->fileheader->filesize) + if (!cryptoapi->CryptHashData(hash, + (LPBYTE)view+block->offset+block->sizefile, + archiveptr->startinglocation+archiveptr->fileheader->filesize + -(block->offset+block->sizefile), + 0)) + LEAVE; + + // VERIFY THE SIGNATURE BLOCK AGAINST THE HASH VALUE + if (cryptoapi->CryptVerifySignature(hash, + (LPBYTE)view+block->offset+sizeof(SIGNATUREHEADER), + block->sizefile-sizeof(SIGNATUREHEADER), + key, + NULL, + 0)) { + result = 1; + if (extendedresult) + *extendedresult = s_authcompany[companyid].authresult; + } + else if (extendedresult) + *extendedresult = SFILE_AUTH_BADSIGNATURE; + + } + FINALLY { + if (hash) + cryptoapi->CryptDestroyHash(hash); + if (key) + cryptoapi->CryptDestroyKey(key); + if (view) + UnmapViewOfFile(view); + if (map) + CloseHandle(map); + if (provider) { + cryptoapi->CryptReleaseContext(provider,0); + cryptoapi->CryptAcquireContext(&provider,KEYCONTAINER,MS_DEF_PROV,PROV_RSA_FULL,CRYPT_DELETEKEYSET); + } + if (cryptoapi) + FREE(cryptoapi); + if (lib) + FreeLibrary(lib); + } + + if (!result) + SErrSetLastError(SFILE_ERROR_NOT_AUTHENTICATED); + return result; +} + +//=========================================================================== +BOOL APIENTRY SFileCloseArchive (HSARCHIVE handle) { + TRACEOUT(TRACEHANDLE, + "SFileCloseArchive(0x%x)", + handle); + + // CHECK THE ARCHIVE HANDLE + ARCHIVEPTR archiveptr; + if (!CheckArchiveHandle(handle,&archiveptr)) + return FALSE; + + // CLOSE ALL FILES ASSOCIATED WITH THIS ARCHIVE + { + FILEPTR curr = s_filelist.Head(); + while (curr) { + FILEPTR next = curr->Next(); + if (curr->archive == archiveptr) + SFileCloseFile((HSFILE)curr); + curr = next; + } + } + + // FREE MEMORY + if (archiveptr->sectorbuffer) + FREE(archiveptr->sectorbuffer); + if (archiveptr->blocktable) + FREE(archiveptr->blocktable); + if (archiveptr->fileheader) + DEL(archiveptr->fileheader); + if (archiveptr->hashtable) + FREE(archiveptr->hashtable); + + // CLOSE THE ARCHIVE FILE + CloseHandle(archiveptr->handle); + + // UNLINK AND FREE THE ARCHIVE + s_critsect.Enter(); + s_archivelist.DeleteNode(archiveptr); + s_critsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileCloseFile (HSFILE handle) { + TRACEOUT(TRACEHANDLE, + "SFileCloseFile(0x%x)", + handle); + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return FALSE; + + // END ANY DDA STREAMS ASSOCIATED WITH THIS FILE + if (fileptr->dda) + SFileDdaEnd(handle); + + // WAIT UNTIL ALL OUTSTANDING READ OPERATIONS FOR THIS FILE COMPLETE. + // IF WE ARE IN DEBUG MODE, DISPLAY A WARNING IF THE APPLICATION TRIES + // TO CLOSE A FILE WHILE THERE ARE OUTSTANDING OVERLAPPED READ OPERATIONS + // ON THAT FILE. + s_critsect.Enter(); + for (;;) { + BOOL outstanding = FALSE; + ITERATELIST(REQUEST,s_cdreqlist,curr) + if (curr->file == fileptr) { + outstanding = TRUE; + break; + } + if (outstanding) { +#ifdef _DEBUG + SErrDisplayError(ERROR_IO_PENDING, + "SFileCloseFile()", + SERR_LINECODE_FUNCTION, + NULL, + TRUE); +#endif + Sleep(1); + } + else + break; + } + + // CLOSE THE FILE HANDLE IF USED + if (fileptr->handle != INVALID_HANDLE_VALUE) + CloseHandle(fileptr->handle); + + // CLEAR THE SECTOR CACHE + if (fileptr->archive) + fileptr->archive->sectorfile = NULL; + + // FREE THE SECTOR OFFSET TABLE + if (fileptr->sectoroffsettable) + FREE(fileptr->sectoroffsettable); + + // FREE THE READ AHEAD BUFFER + if (fileptr->readaheadbuffer) + FREE(fileptr->readaheadbuffer); + + // UNLINK AND FREE THE FILE + s_filelist.DeleteNode(fileptr); + s_critsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileDdaBegin (HSFILE handle, + DWORD buffersize, + DWORD flags) { + TRACEOUT(TRACEHANDLE, + "SFileDdaBegin(0x%x,%u,0x%x)", + handle,buffersize,flags); + + return SFileDdaBeginEx(handle, + buffersize, + flags, + 0, + 0x7FFFFFFF, + 0x7FFFFFFF, + NULL); +} + +//=========================================================================== +BOOL APIENTRY SFileDdaBeginEx (HSFILE handle, + DWORD buffersize, + DWORD flags, + DWORD offset, + LONG volume, + LONG pan, + LPVOID reserved) { + VALIDATEBEGIN; + VALIDATE(buffersize); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileDdaBeginEx(0x%x,%u,0x%x,%u,%d,%d,%u)", + handle,buffersize,flags,offset,volume,pan,reserved); + + if (!s_directsound) { + SErrSetLastError(SFILE_ERROR_NOT_INITIALIZED); + return 0; + } + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return FALSE; + + // STOP PLAYING THIS FILE IF IT IS ALREADY PLAYING + if (fileptr->dda) + SFileDdaEnd(handle); + + // ENSURE THAT THE FILE IS IN AN ARCHIVE + if ((fileptr->handle != INVALID_HANDLE_VALUE) || !fileptr->archive) { + SErrSetLastError(SFILE_ERROR_NOT_IN_ARCHIVE); + return 0; + } + + // MARK THIS FILE AS PLAYING + fileptr->dda = 1; + + // CREATE A SOUND READ BUFFER IF NECESSARY + if (!s_soundreadbuffer) + s_soundreadbuffer = ALLOC(WAVECHUNKSIZE); + + // IF THE FILE'S ARCHIVE IS NOT ON CD, START PROCESSING IT AS A CD ARCHIVE + // ANYWAY, BECAUSE THE CD READ THREAD DOES THE WORK OF READING BACKGROUND + // STREAM DATA + if (fileptr->archive->cdrom == CDROM_FALSE) { + fileptr->archive->cdrom = CDROM_USEDFORDDA; + if (s_cdthread == INVALID_HANDLE_VALUE) + CreateCdThread(); + } + + // ADJUST THE BUFFER SIZE SO IT IS A MULTIPLE OF 64K AND AT LEAST 128K + if (buffersize & (WAVECHUNKSIZE-1)) + buffersize += WAVECHUNKSIZE-(buffersize & (WAVECHUNKSIZE-1)); + if (buffersize < 2*WAVECHUNKSIZE) + buffersize = 2*WAVECHUNKSIZE; + + // READ THE WAVE FILE HEADER + WAVEFORMATEX format; + DWORD startinglocation; + DWORD totalsize; + { + SFileSetFilePointer(handle,0,NULL,FILE_BEGIN); + MMCKINFO mmck; + if (!SFileReadFile(handle,&mmck,sizeof(FOURCC)*2+sizeof(DWORD),NULL,NULL)) + return 0; + if ((mmck.ckid != FOURCC_RIFF) || (mmck.fccType != mmioFOURCC('W','A','V','E'))) { + SErrSetLastError(SFILE_ERROR_INVALID_DATA); + return 0; + } + CKINFO info; + if (!FindChunk(handle,mmioFOURCC('f','m','t',' '),&info)) { + SErrSetLastError(SFILE_ERROR_INVALID_DATA); + return 0; + } + if (info.size < sizeof(PCMWAVEFORMAT)) { + SErrSetLastError(SFILE_ERROR_INVALID_DATA); + return 0; + } + PCMWAVEFORMAT pcm; + if (!SFileReadFile(handle,&pcm,sizeof(PCMWAVEFORMAT),NULL,NULL)) + return 0; + if (SFileSetFilePointer(handle,info.size-sizeof(PCMWAVEFORMAT),NULL,FILE_CURRENT) == 0xFFFFFFFF) + return 0; + format.wFormatTag = pcm.wf.wFormatTag; + format.nChannels = pcm.wf.nChannels; + format.nSamplesPerSec = pcm.wf.nSamplesPerSec; + format.nAvgBytesPerSec = pcm.wf.nAvgBytesPerSec; + format.nBlockAlign = pcm.wf.nBlockAlign; + format.wBitsPerSample = pcm.wBitsPerSample; + format.cbSize = 0; + if (!FindChunk(handle,mmioFOURCC('d','a','t','a'),&info)) { + SErrSetLastError(SFILE_ERROR_INVALID_DATA); + return 0; + } + startinglocation = info.offset; + totalsize = info.size; + } + + // CREATE A STREAM RECORD + s_critsect.Enter(); + AUDIOSTREAMPTR stream = s_streamlist.NewNode(); + stream->file = fileptr; + stream->soundbuffersize = buffersize; + stream->bytespersecond = format.nAvgBytesPerSec; + stream->loop = ((flags & SFILE_DDA_LOOP) != 0); + stream->fillstatus = FILL_UNREQUESTED; + stream->startinglocation = startinglocation+min(offset,totalsize-startinglocation); + stream->totalsize = totalsize; + stream->volume = volume; + stream->pan = pan; + stream->fillvalue = (format.wBitsPerSample == 8) ? 0x80 : 0x00; + + // CREATE A SECONDARY SOUND BUFFER + { + DSBUFFERDESC desc; + ZeroMemory(&desc,sizeof(DSBUFFERDESC)); + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = (DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY); + desc.dwBufferBytes = buffersize; + desc.lpwfxFormat = &format; + s_directsound->CreateSoundBuffer(&desc,&stream->soundbuffer,NULL); + if (stream->soundbuffer) { + if (stream->volume != 0x7FFFFFFF) + stream->soundbuffer->SetVolume(stream->volume); + if (stream->pan != 0x7FFFFFFF) + stream->soundbuffer->SetPan(stream->pan); + } + } + s_critsect.Leave(); + + // TRIGGER THE CD READ THREAD + SetEvent(s_cdevent); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileDdaDestroy () { + TRACEOUT(TRACEHANDLE, + "SFileDdaDestroy()"); + + // FREE ALL STREAMS + s_critsect.Enter(); + { + AUDIOSTREAMPTR curr; + while ((curr = s_streamlist.Head()) != NULL) { + curr->file->dda = TRUE; + s_critsect.Leave(); + SFileDdaEnd((HSFILE)curr->file); + s_critsect.Enter(); + } + } + s_critsect.Leave(); + + // DELETE THE POINTER TO THE DIRECTSOUND OBJECT + s_directsound = NULL; + + // FREE THE SOUND READ BUFFER + if (s_soundreadbuffer) { + FREE(s_soundreadbuffer); + s_soundreadbuffer = NULL; + } + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileDdaEnd (HSFILE handle) { + TRACEOUT(TRACEHANDLE, + "SFileDdaEnd(0x%x)", + handle); + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return FALSE; + + // FREE ALL STREAMS ASSOCIATED WITH THIS FILE + BOOL again; + do { + again = FALSE; + s_critsect.Enter(); + AUDIOSTREAMPTR curr = s_streamlist.Head(); + while (curr) { + AUDIOSTREAMPTR next = curr->Next(); + if (curr->file == fileptr) { + curr->fillstatus = FILL_CLOSING; + + // CHECK WHETHER THERE ARE OUTSTANDING READ REQUESTS FOR THE STREAM + BOOL found = FALSE; + REQUESTPTR currreq = s_cdreqlist.Head(); + while (currreq && !found) { + if ((currreq->stream == curr) || + (currreq->soundbuffer == curr->soundbuffer)) + found = TRUE; + currreq = currreq->Next(); + } + + // IF NOT, DELETE THE STREAM + if (found) + again = TRUE; + else { + if (curr->soundbuffer) + curr->soundbuffer->Release(); + next = s_streamlist.DeleteNode(curr); + } + + } + curr = next; + } + s_critsect.Leave(); + if (again) + Sleep(1); + } while (again); + + fileptr->dda = FALSE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SFileDdaGetPos (HSFILE handle, + DWORD *position, + DWORD *maxposition) { + TRACEOUT(TRACEHANDLE, + "SFileDdaGetPos(0x%x,*position,*maxposition)", + handle); + + if (position) + *position = 0; + if (maxposition) + *maxposition = 0; + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return FALSE; + + // ENTER THE CRITICAL SECTION + s_critsect.Enter(); + + // FIND THE STREAM ASSOCIATED WITH THIS FILE + AUDIOSTREAMPTR curr = s_streamlist.Head(); + while (curr && (curr->file != fileptr)) + curr = curr->Next(); + if (!curr) { + s_critsect.Leave(); + SErrSetLastError(SFILE_ERROR_NOT_PLAYING); + return 0; + } + + // DETERMINE THE CURRENT PLAY POSITION + DWORD playposition = 0; + if ((curr->fillstatus == FILL_PLAYING) || + (curr->fillstatus == FILL_CLOSING)) { + DWORD playcursor = 0; + DWORD writecursor = 0; + curr->soundbuffer->GetCurrentPosition(&playcursor,&writecursor); + DWORD writeposition = curr->file->location+curr->bytespastend-curr->startinglocation; + playposition = (writeposition/curr->soundbuffersize)*curr->soundbuffersize+playcursor; + if (playposition >= writeposition) + if (playposition > curr->soundbuffersize) + playposition -= curr->soundbuffersize; + else + playposition = 0; + playposition = min(playposition,curr->totalsize-curr->startinglocation); + } + + // RETURN THE CURRENT POSITIONS + if (position) + *position = playposition; + if (maxposition) + *maxposition = curr->totalsize-curr->startinglocation; + + // LEAVE THE CRITICAL SECTION + s_critsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileDdaGetVolume (HSFILE handle, + LONG *volume, + LONG *pan) { + TRACEOUT(TRACEHANDLE, + "SFileDdaGetVolume(0x%x,*volume,*pan)", + handle); + + if (volume) + *volume = 0; + if (pan) + *pan = 0; + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return FALSE; + + // ENTER THE CRITICAL SECTION + s_critsect.Enter(); + + // FIND THE STREAM ASSOCIATED WITH THIS FILE + AUDIOSTREAMPTR curr = s_streamlist.Head(); + while (curr && (curr->file != fileptr)) + curr = curr->Next(); + if (!curr) { + s_critsect.Leave(); + SErrSetLastError(SFILE_ERROR_NOT_PLAYING); + return 0; + } + + // IF WE DON'T KNOW WHAT THE VOLUME OR PAN OF THIS AUDIO STREAM IS, + // DETERMINE IT NOW + if (curr->volume == 0x7FFFFFFF) + curr->soundbuffer->GetVolume(&curr->volume); + if (curr->pan == 0x7FFFFFFF) + curr->soundbuffer->GetPan(&curr->pan); + + // RETURN THE REQUESTED VALUES + if (volume) + *volume = curr->volume; + if (pan) + *pan = curr->pan; + + // LEAVE THE CRITICAL SECTION + s_critsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileDdaInitialize (LPDIRECTSOUND directsound) { + VALIDATEBEGIN; + VALIDATE(directsound); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileDdaInitialize(0x%x)", + directsound); + + s_directsound = directsound; + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileDdaSetVolume (HSFILE handle, + LONG volume, + LONG pan) { + TRACEOUT(TRACEHANDLE, + "SFileDdaSetVolume(0x%x,%d,%d)", + handle,volume,pan); + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return FALSE; + + // ENTER THE CRITICAL SECTION + s_critsect.Enter(); + + // FIND THE STREAM ASSOCIATED WITH THIS FILE + AUDIOSTREAMPTR curr = s_streamlist.Head(); + while (curr && (curr->file != fileptr)) + curr = curr->Next(); + if (!curr) { + s_critsect.Leave(); + SErrSetLastError(SFILE_ERROR_NOT_PLAYING); + return 0; + } + + // ADJUST THE SETTINGS + if ((volume != 0x7FFFFFFF) && (volume != curr->volume)) { + curr->volume = volume; + curr->soundbuffer->SetVolume(volume); + } + if ((pan != 0x7FFFFFFF) && (pan != curr->pan)) { + curr->pan = pan; + curr->soundbuffer->SetPan(pan); + } + + // LEAVE THE CRITICAL SECTION + s_critsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileDestroy () { + TRACEOUT(TRACEHANDLE, + "SFileDestroy()"); + + // WAIT FOR ALL OUTSTANDING REQUESTS TO COMPLETE + while (!s_cdreqlist.IsEmpty()) + Sleep(10); + + // SHUT DOWN THE CD THREAD READ ROUTINE + if (s_cdthread != INVALID_HANDLE_VALUE) { + s_cdshutdown = 1; + SetEvent(s_cdevent); + WaitForSingleObject(s_cdthread,INFINITE); + if (s_cdevent != INVALID_HANDLE_VALUE) { + CloseHandle(s_cdevent); + s_cdevent = INVALID_HANDLE_VALUE; + } + if (s_cdthread != INVALID_HANDLE_VALUE) { + CloseHandle(s_cdthread); + s_cdthread = INVALID_HANDLE_VALUE; + } + } + + // DESTROY DDA + SFileDdaDestroy(); + + // DELETE THE OPEN FILES AND ARCHIVES + { + FILEPTR curr; + while ((curr = s_filelist.Head()) != NULL) { + REPORTRESOURCELEAK(HSFILE); + SFileCloseFile((HSFILE)curr); + } + } + { + ARCHIVEPTR curr; + while ((curr = s_archivelist.Head()) != NULL) { + REPORTRESOURCELEAK(HSARCHIVE); + SFileCloseArchive((HSARCHIVE)curr); + } + } + + // DELETE THE HASH TABLES + if (s_hashsource) { + FREE(s_hashsource); + s_hashsource = NULL; + } + + // DELETE THE DECOMPRESSION DATA + if (s_explodebuffer) { + FREE(s_explodebuffer); + s_explodebuffer = NULL; + } + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileEnableDirectAccess (BOOL enable) { + TRACEOUT(TRACEHANDLE, + "SFileEnableDirectAccess(%u)", + enable); + + s_enabledirect = enable; + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileGetArchiveInfo (HSARCHIVE archive, + int *priority, + BOOL *cdrom) { + if (priority) + *priority = 0; + if (cdrom) + *cdrom = FALSE; + + // CHECK THE ARCHIVE HANDLE + ARCHIVEPTR archiveptr; + if (!CheckArchiveHandle(archive,&archiveptr)) + return FALSE; + + // RETURN THE INFORMATION + if (priority) + *priority = archiveptr->priority; + if (cdrom) + *cdrom = (archiveptr->cdrom == CDROM_TRUE); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SFileGetArchiveName (HSARCHIVE archive, + LPTSTR buffer, + DWORD bufferchars) { + VALIDATEBEGIN; + VALIDATEANDBLANK(buffer); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileGetArchiveName(0x%x,0x%x,%u)", + archive,buffer,bufferchars); + + // CHECK THE ARCHIVE HANDLE + ARCHIVEPTR archiveptr; + if (!CheckArchiveHandle(archive,&archiveptr)) + return FALSE; + + SStrCopy(buffer,archiveptr->name,bufferchars); + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileGetBasePath (LPTSTR buffer, + DWORD bufferchars) { + TRACEOUT(TRACEHANDLE, + "SFileGetBasePath(0x%x,%u)", + buffer,bufferchars); + + if (!s_basepath[0]) + BuildDefaultBasePath(); + SStrCopy(buffer,s_basepath,bufferchars); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SFileGetFileArchive (HSFILE file, + HSARCHIVE *archive) { + VALIDATEBEGIN; + VALIDATEANDBLANK(archive); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileGetFileArchive(0x%x,*archive)", + file); + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(file,&fileptr)) + return FALSE; + + *archive = (HSARCHIVE)(fileptr->archive); + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileGetFileName (HSFILE file, + LPTSTR buffer, + DWORD bufferchars) { + VALIDATEBEGIN; + VALIDATEANDBLANK(buffer); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileGetFileName(0x%x,0x%x,%u)", + file,buffer,bufferchars); + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(file,&fileptr)) + return FALSE; + + SStrCopy(buffer,fileptr->name,bufferchars); + return 1; +} + +//=========================================================================== +DWORD APIENTRY SFileGetFileSize (HSFILE handle, + LPDWORD filesizehigh) { + TRACEOUT(TRACEHANDLE, + "SFileGetFileSize(0x%x,*filesizehigh)", + handle); + + if (filesizehigh) + *filesizehigh = NULL; + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return 0xFFFFFFFF; + + // IF THIS HANDLE REPRESENTS A REAL FILE, FORWARD THE REQUEST TO THE + // STANDARD WIN32 API + if (fileptr->handle != INVALID_HANDLE_VALUE) + return GetFileSize(fileptr->handle,filesizehigh); + + // RETURN THE FILE SIZE + return fileptr->block->sizefile; +} + +//=========================================================================== +BOOL APIENTRY SFileOpenArchive (LPCTSTR archivename, + int priority, + BOOL cdonly, + HSARCHIVE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATE(archivename); + VALIDATE(*archivename); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileOpenArchive(\"%s\",%d,%u,*handle)", + archivename,priority,cdonly); + + // INITIALIZE THE HASH TABLES IF NECESSARY + if (!s_hashsource) { + s_hashsource = (LPDWORD)ALLOC(5*256*sizeof(DWORD)); + InitializeHashSource(); + } + + // IF THE ARCHIVE FILENAME DOES NOT CONTAIN AN ABSOLUTE PATH AND THE + // ARCHIVE DOES NOT EXIST IN THE GIVEN LOCATION RELATIVE TO THE CURRENT + // DIRECTORY, CHECK FOR IT IN THE GIVEN LOCATION RELATIVE TO THE + // EXECUTABLE DIRECTORY + char localarchivename[MAX_PATH]; + SStrCopy(localarchivename,archivename,MAX_PATH); + localarchivename[MAX_PATH-1] = 0; + if (GetFileAttributes(localarchivename) & FILE_ATTRIBUTE_DIRECTORY) + if ((*archivename == '\\') || + strstr(archivename,":\\") || + strstr(archivename,"\\\\")) + SStrCopy(localarchivename,archivename,MAX_PATH); + else + ConvertRelativePathName(archivename,localarchivename); + + // DETERMINE WHETHER THIS ARCHIVE IS ON A CD-ROM DRIVE + BOOL cdrom = CheckForCdRom(localarchivename); + if (cdonly && !cdrom) { + SErrSetLastError(SFILE_ERROR_INVALID_DRIVE); + return 0; + } + + // OPEN THE ARCHIVE FILE + HANDLE archivehandle = CreateFile(localarchivename, + GENERIC_READ, + FILE_SHARE_READ, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + 0, + NULL); + if (archivehandle == INVALID_HANDLE_VALUE) + return 0; + + // CREATE A RECORD FOR THIS ARCHIVE + ARCHIVEPTR archiveptr = s_archivelist.NewNode(LIST_UNLINKED); + SStrCopy(archiveptr->name,localarchivename,MAX_PATH); + archiveptr->handle = archivehandle; + archiveptr->cdrom = cdrom ? CDROM_TRUE : CDROM_FALSE; + archiveptr->priority = priority; + + // SINCE THE MOPAQ FILE MAY BE TACKED ON BELOW OTHER FILE DATA, SEARCH + // FOR THE SIGNATURE TO DETERMINE THE STARTING LOCATION OF THE MOPAQ + // FILE + archiveptr->fileheader = NEW(FILEHEADER); + DWORD bytesread; + archiveptr->startinglocation = 0; + do { + SetFilePointer(archivehandle,archiveptr->startinglocation,NULL,FILE_BEGIN); + bytesread = 0; + ReadFile(archivehandle, + archiveptr->fileheader, + sizeof(FILEHEADER), + &bytesread, + NULL); + if (bytesread != sizeof(FILEHEADER)) { + DEL(archiveptr->fileheader); + s_archivelist.DeleteNode(archiveptr); + CloseHandle(archivehandle); + SErrSetLastError(SFILE_ERROR_NOT_ARCHIVE); + return 0; + } + if (archiveptr->fileheader->signature != SIGNATURE) + archiveptr->startinglocation += 512; + } while (archiveptr->fileheader->signature != SIGNATURE); + + // DETERMINE THE SECTOR SIZE AND ALLOCATE A SECTOR BUFFER + archiveptr->sectorsize = (512 << archiveptr->fileheader->sectorsizeid); + archiveptr->sectorbuffer = (LPBYTE)ALLOC(archiveptr->sectorsize); + + // READ THE HASH TABLE + archiveptr->hashtable = (HASHENTRYPTR)ALLOC(archiveptr->fileheader->hashcount*sizeof(HASHENTRY)); + SetFilePointer(archivehandle,archiveptr->startinglocation+archiveptr->fileheader->hashoffset,NULL,FILE_BEGIN); + ReadFileChecked(archivehandle, + archiveptr->hashtable, + archiveptr->fileheader->hashcount*sizeof(HASHENTRY), + &bytesread, + NULL, + archiveptr->name); + Decrypt((LPDWORD)archiveptr->hashtable, + archiveptr->fileheader->hashcount*sizeof(HASHENTRY), + Hash("(hash table)",HASH_ENCRYPTKEY)); + + // READ THE BLOCK TABLE + archiveptr->blocktable = (BLOCKENTRYPTR)ALLOC(archiveptr->fileheader->blockcount*sizeof(BLOCKENTRY)); + SetFilePointer(archivehandle,archiveptr->startinglocation+archiveptr->fileheader->blockoffset,NULL,FILE_BEGIN); + ReadFileChecked(archivehandle, + archiveptr->blocktable, + archiveptr->fileheader->blockcount*sizeof(BLOCKENTRY), + &bytesread, + NULL, + archiveptr->name); + Decrypt((LPDWORD)archiveptr->blocktable, + archiveptr->fileheader->blockcount*sizeof(BLOCKENTRY), + Hash("(block table)",HASH_ENCRYPTKEY)); + + // IF THE STARTING LOCATION IS NOT ZERO, OFFSET ALL OF THE BLOCKS IN THE + // BLOCK TABLE + if (archiveptr->startinglocation) { + for (DWORD block = 0; block < archiveptr->fileheader->blockcount; ++block) + if ((archiveptr->blocktable+block)->offset) + (archiveptr->blocktable+block)->offset += archiveptr->startinglocation; + } + + // ADD THE ARCHIVE TO OUR LINKED LIST IN PRIORITY ORDER + s_critsect.Enter(); + { + ARCHIVEPTR curr = s_archivelist.Head(); + while (curr && (curr->priority > priority)) + curr = curr->Next(); + s_archivelist.LinkNode(archiveptr,LIST_LINK_BEFORE,curr); + } + s_critsect.Leave(); + + // IF THIS ARCHIVE IS ON A CD-ROM AND THERE IS NO CD-ROM READ THREAD YET, + // CREATE ONE + if (cdrom && (s_cdthread == INVALID_HANDLE_VALUE)) + CreateCdThread(); + else if (cdonly && !cdrom) { + SFileCloseArchive((HSARCHIVE)archiveptr); + SErrSetLastError(SFILE_ERROR_INVALID_DRIVE); + return 0; + } + + // RETURN A HANDLE TO THE ARCHIVE + *handle = (HSARCHIVE)archiveptr; + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileOpenFile (LPCTSTR filename, + HSFILE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATE(filename); + VALIDATE(*filename); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileOpenFile(\"%s\",*handle)", + filename); + + // IF THIS FILE IS AVAILABLE OUTSIDE OF AN ARCHIVE, OPEN IT DIRECTLY + if (s_enabledirect || s_archivelist.IsEmpty()) { + char localfilename[MAX_PATH] = ""; + if ((*filename == '\\') || + strstr(filename,":\\") || + strstr(filename,"\\\\")) + SStrCopy(localfilename,filename,MAX_PATH); + else + ConvertRelativePathName(filename,localfilename); + HANDLE filehandle = CreateFile(localfilename, + GENERIC_READ, + FILE_SHARE_READ, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + NULL); + if (filehandle != INVALID_HANDLE_VALUE) { + s_critsect.Enter(); + FILEPTR fileptr = s_filelist.NewNode(); + fileptr->handle = filehandle; + s_critsect.Leave(); + *handle = (HSFILE)fileptr; + return TRUE; + } + } + + // OTHERWISE, SEARCH FOR THE REQUESTED FILE IN THE CURRENTLY OPEN ARCHIVES + if (s_archivelist.IsEmpty() || !s_hashsource) { + SErrSetLastError(SFILE_ERROR_FILE_NOT_FOUND); + return 0; + } + ARCHIVEPTR archiveptr = s_archivelist.Head(); + DWORD index; + do { + index = SearchHashTable(archiveptr,filename,s_lcid); + if (index == 0xFFFFFFFF) + archiveptr = archiveptr->Next(); + } while (archiveptr && (index == 0xFFFFFFFF)); + if (!archiveptr) { + SErrSetLastError(SFILE_ERROR_FILE_NOT_FOUND); + return 0; + } + + return SFileOpenFileEx((HSARCHIVE)archiveptr,filename,0,handle); +} + +//=========================================================================== +BOOL APIENTRY SFileOpenFileEx (HSARCHIVE archivehandle, + LPCTSTR filename, + DWORD flags, + HSFILE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATE(filename); + VALIDATE(*filename); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileOpenFileEx(0x%x,\"%s\",0x%x,*handle)", + archivehandle,filename,flags); + + // CHECK THE ARCHIVE HANDLE + ARCHIVEPTR archiveptr; + if (!CheckArchiveHandle(archivehandle,&archiveptr)) + return FALSE; + + // DETERMINE THE HASH INDEX + DWORD index = SearchHashTable(archiveptr,filename,s_lcid); + if (index == 0xFFFFFFFF) { + SErrSetLastError(SFILE_ERROR_FILE_NOT_FOUND); + return 0; + } + + // DETERMINE THE BLOCK POINTER + BLOCKENTRYPTR block = archiveptr->blocktable+(archiveptr->hashtable+index)->block; + + // CONFIRM THAT THIS IS A VALID FILE + if ((!block->sizefile) || + !(block->flags & MPQ_ALLOCATED)) { + SErrSetLastError(SFILE_ERROR_FILE_INVALID); + return 0; + } + + // DETERMINE THE FILE NAME PORTION OF THE REQUESTED FILE + LPCTSTR name = filename; + while (SStrChr(name,':')) + name = SStrChr(name,':')+1; + while (SStrChr(name,'\\')) + name = SStrChr(name,'\\')+1; + + // CREATE A DECRYPTION KEY BASED ON THE FILE NAME + DWORD key = Hash(name,HASH_ENCRYPTKEY); + if (block->flags & MPQ_ENCRYPTED_FIXLOC) + key = (key + (block->offset-archiveptr->startinglocation)) ^ block->sizefile; + + // CREATE A RECORD FOR THE FILE + DWORD sectors = (block->sizefile+archiveptr->sectorsize-1)/archiveptr->sectorsize; + LPDWORD sectoroffsettable = NULL; + if (block->flags & MPQ_COMPRESSEDMASK) + sectoroffsettable = (LPDWORD)ALLOC((sectors+1)*sizeof(DWORD)); + s_critsect.Enter(); + FILEPTR fileptr = s_filelist.NewNode(); + SStrCopy(fileptr->name,filename,MAX_PATH); + fileptr->handle = INVALID_HANDLE_VALUE; + fileptr->archive = archiveptr; + fileptr->block = block; + fileptr->key = key; + fileptr->sectors = sectors; + fileptr->sectoroffsettable = sectoroffsettable; + fileptr->readaheadbuffer = ALLOC(READAHEAD); + s_critsect.Leave(); + + // RETURN A HANDLE TO THE FILE + *handle = (HSFILE)fileptr; + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileOpenFileWin32 (LPCTSTR filename, + HANDLE *handle) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATE(filename); + VALIDATE(*filename); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileOpenFileWin32(\"%s\",*handle)", + filename); + + // IF THIS FILE IS AVAILABLE OUTSIDE OF AN ARCHIVE, OPEN IT DIRECTLY + { + char localfilename[MAX_PATH] = ""; + if ((*filename == '\\') || + strstr(filename,":\\") || + strstr(filename,"\\\\")) + SStrCopy(localfilename,filename,MAX_PATH); + else + ConvertRelativePathName(filename,localfilename); + *handle = CreateFile(localfilename, + GENERIC_READ, + FILE_SHARE_READ, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + NULL); + if (*handle != INVALID_HANDLE_VALUE) + return 1; + } + + // OTHERWISE, SEARCH FOR THE REQUESTED FILE IN THE CURRENTLY OPEN ARCHIVES + if (s_archivelist.IsEmpty() || !s_hashsource) { + SErrSetLastError(SFILE_ERROR_FILE_NOT_FOUND); + return 0; + } + ARCHIVEPTR archiveptr = s_archivelist.Head(); + DWORD index; + do { + index = SearchHashTable(archiveptr,filename,s_lcid); + if (index == 0xFFFFFFFF) + archiveptr = archiveptr->Next(); + } while (archiveptr && (index == 0xFFFFFFFF)); + if (!archiveptr) { + SErrSetLastError(SFILE_ERROR_FILE_NOT_FOUND); + return 0; + } + + // DETERMINE THE BLOCK POINTER + BLOCKENTRYPTR block = archiveptr->blocktable+(archiveptr->hashtable+index)->block; + + // CONFIRM THAT THIS IS A VALID FILE, AND IS NOT COMPRESSED OR ENCRYPTED. + // WE CAN'T RETURN WIN32 HANDLES TO COMPRESSED OR ENCRYPTED FILES. + if ((!block->sizefile) || + (block->flags & (MPQ_COMPRESSEDMASK | MPQ_ENCRYPTED)) || + !(block->flags & MPQ_ALLOCATED)) { + SErrSetLastError(SFILE_ERROR_FILE_INVALID); + return 0; + } + + // OPEN THE ARCHIVE THAT CONTAINS THE FILE + *handle = CreateFile(archiveptr->name, + GENERIC_READ, + FILE_SHARE_READ, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + NULL); + if (*handle == INVALID_HANDLE_VALUE) + return 0; + + // SEEK TO THE BEGINNING OF THE FILE + SetFilePointer(*handle,block->offset,0,FILE_BEGIN); + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SFileReadFile (HSFILE handle, + LPVOID buffer, + DWORD bytestoread, + LPDWORD bytesread, + LPOVERLAPPED overlapped) { + if (bytesread) + *bytesread = 0; + + VALIDATEBEGIN; + VALIDATE(buffer); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileReadFile(0x%x,0x%x,%u,*bytesread,0x%x)", + handle,buffer,bytestoread,overlapped); + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return FALSE; + + if (!bytestoread) + return TRUE; + + // IF THIS HANDLE REPRESENTS A REAL FILE, FORWARD THE REQUEST TO THE + // STANDARD WIN32 API + if (fileptr->handle != INVALID_HANDLE_VALUE) { + DWORD localbytesread = 0; + HANDLE event = NULL; + if (overlapped) { + event = overlapped->hEvent; + overlapped->hEvent = NULL; + } + ReadFileChecked(fileptr->handle, + buffer, + bytestoread, + &localbytesread, + overlapped, + fileptr->name); + if (event) + SetEvent(event); + if (bytesread) + *bytesread = localbytesread; + return (localbytesread == bytestoread); + } + + // TRY TO SATISFY, OR PARTIALLY SATISFY, THIS REQUEST FROM THE READ + // AHEAD BUFFER + if (fileptr->readaheadbuffer && + (fileptr->readaheadoffset < fileptr->readaheadbytes) && + !overlapped) { + DWORD satisfybytes = min(bytestoread,fileptr->readaheadbytes-fileptr->readaheadoffset); + CopyMemory(buffer,(LPBYTE)fileptr->readaheadbuffer+fileptr->readaheadoffset,satisfybytes); + fileptr->location += satisfybytes; + fileptr->readaheadoffset += satisfybytes; + buffer = (LPBYTE)buffer+satisfybytes; + bytestoread -= satisfybytes; + if (bytesread) + *bytesread = satisfybytes; + if (!bytestoread) + return TRUE; + } + + // DETERMINE THE AMOUNT OF DATA TO READ + // (NO READ-AHEAD IS DONE FOR OVERLAPPED I/O, BECAUSE THE EVENT WILL + // BE TRIGGERED BEFORE WE HAVE A CHANCE TO DO THE BUFFER COPY) + LPVOID readbuffer = buffer; + DWORD readbytes = bytestoread; + if (!overlapped) { + DWORD desiredreadahead = min(READAHEAD, + fileptr->archive->sectorsize-(fileptr->location & (fileptr->archive->sectorsize-1))); + if (bytestoread < desiredreadahead) { + readbuffer = fileptr->readaheadbuffer; + readbytes = desiredreadahead; + } + } + + // IF THERE IS NOTHING TO READ, RETURN + if (!readbytes) + return TRUE; + + // IF THIS FILE IS ON A CD-ROM DRIVE, QUEUE THE REQUEST FOR THE CD-ROM + // I/O THREAD + DWORD location = overlapped ? overlapped->Offset : fileptr->location; + DWORD totalbytesread = 0; + if (fileptr->archive->cdrom != CDROM_FALSE) { + REQUESTPTR requestptr; + HANDLE event = overlapped ? overlapped->hEvent + : CreateEvent(NULL,TRUE,FALSE,NULL); + DWORD blocks = (readbytes+DATACHUNKSIZE-1)/DATACHUNKSIZE; + DWORD prevseq = 0; + DWORD loop; + for (loop = 0; loop < blocks; ++loop) { + BOOL lastblock = (loop == blocks-1); + DWORD offset = loop*DATACHUNKSIZE; + DWORD bytes = min(DATACHUNKSIZE,readbytes-offset); + requestptr = IssueRequest(fileptr, + location+loop*DATACHUNKSIZE, + (LPBYTE)readbuffer+offset, + NULL, + 0, + NULL, + bytes, + INT_MAX, + prevseq, + lastblock ? event : NULL, + overlapped || !lastblock, + lastblock, + &prevseq); + if (!lastblock) + totalbytesread += bytes; + } + if (overlapped) { + SErrSetLastError(ERROR_IO_PENDING); + return FALSE; + } + WaitForSingleObject(event,INFINITE); + CloseHandle(event); + totalbytesread += requestptr->bytesread; + FREE(requestptr); + } + + // OTHERWISE, READ THE REQUESTED DATA + else { + totalbytesread = InternalReadUnaligned(fileptr, + location, + readbuffer, + readbytes); + if (overlapped && overlapped->hEvent) + SetEvent(overlapped->hEvent); + } + + // COPY THE READ DATA TO THE USER'S BUFFER + DWORD userbytesread = min(bytestoread,totalbytesread); + if (readbuffer != buffer) { + CopyMemory(buffer,readbuffer,userbytesread); + fileptr->readaheadoffset = userbytesread; + fileptr->readaheadbytes = totalbytesread; + } + + // UPDATE THE FILE POINTER + if (!overlapped) + fileptr->location += userbytesread; + + // RETURN THE NUMBER OF BYTES READ + if (bytesread) + *bytesread += userbytesread; + + if (userbytesread == bytestoread) + return TRUE; + else { + SErrSetLastError(SFILE_ERROR_HANDLE_EOF); + return FALSE; + } +} + +//=========================================================================== +BOOL APIENTRY SFileSetBasePath (LPCTSTR path) { + VALIDATEBEGIN; + VALIDATE(path); + VALIDATEEND; + + TRACEOUT(TRACEHANDLE, + "SFileSetBasePath(\"%s\")", + path); + + // IF WE WERE GIVEN A NULL PATH, RESET THE BASE PATH VARIABLE. IT WILL + // BE AUTOMATICALLY SET ON NEXT USE TO THE PROGRAM PATH. + if (!*path) + s_basepath[0] = 0; + + // OTHERWISE, SET THE BASE PATH TO THE GIVEN PATH + else { + BOOL terminated = (*(path+SStrLen(path)-1) == '\\'); + if ((SStrLen(path)+1+!terminated) > MAX_PATH) { + SErrSetLastError(SFILE_ERROR_BAD_PATHNAME); + return 0; + } + SStrCopy(s_basepath,path,MAX_PATH); + if (!terminated) + SStrPack(s_basepath,"\\",MAX_PATH); + } + + return TRUE; +} + +//=========================================================================== +DWORD APIENTRY SFileSetFilePointer (HSFILE handle, + LONG distancetomove, + PLONG distancetomovehigh, + DWORD movemethod) { + TRACEOUT(TRACEHANDLE, + "SFileSetFilePointer(0x%x,%d,0x%x,%u)", + handle,distancetomove,distancetomovehigh,movemethod); + + if (distancetomovehigh && *distancetomovehigh) { + SErrSetLastError(SFILE_ERROR_INVALID_PARAMETER); + return 0xFFFFFFFF; + } + + // CHECK THE FILE HANDLE + FILEPTR fileptr; + if (!CheckFileHandle(handle,&fileptr)) + return 0xFFFFFFFF; + + // IF THIS HANDLE REPRESENTS A REAL FILE, FORWARD THE REQUEST TO THE + // STANDARD WIN32 API + if (fileptr->handle != INVALID_HANDLE_VALUE) + return SetFilePointer(fileptr->handle,distancetomove,NULL,movemethod); + + // SET THE NEW FILE LOCATION + switch (movemethod) { + + case FILE_BEGIN: + fileptr->location = distancetomove; + break; + + case FILE_CURRENT: + if ((distancetomove < 0) && (fileptr->location < (DWORD)-distancetomove)) + fileptr->location = 0; + else + fileptr->location += distancetomove; + break; + + case FILE_END: + if ((distancetomove < 0) && (fileptr->block->sizefile < (DWORD)-distancetomove)) + fileptr->location = 0; + else + fileptr->location = fileptr->block->sizefile+distancetomove; + break; + + } + fileptr->location = min(fileptr->location,fileptr->block->sizefile-1); + fileptr->readaheadoffset = 0; + fileptr->readaheadbytes = 0; + + // RETURN THE NEW LOCATION + return fileptr->location; +} + +//=========================================================================== +BOOL APIENTRY SFileSetIoErrorMode (DWORD errormode, + SFILEERRORPROC errorproc) { + TRACEOUT(TRACEHANDLE, + "SFileSetIoErrorMode(%u,0x%x)", + errormode,errorproc); + + s_ioerrormode = errormode; + s_ioerrorproc = errorproc; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SFileSetLocale (LCID lcid) { + TRACEOUT(TRACEHANDLE, + "SFileSetLocale(0x%x)", + lcid); + + s_lcid = lcid; + return 1; +} diff --git a/Storm/SOURCE/SGDI.CPP b/Storm/SOURCE/SGDI.CPP new file mode 100644 index 0000000..2310a49 --- /dev/null +++ b/Storm/SOURCE/SGDI.CPP @@ -0,0 +1,860 @@ +/**************************************************************************** +* +* SGDI.CPP +* Storm GDI functions +* (direct replacements for popular Windows GDI functions) +* +* By Michael O'Brien (2/21/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define SIGNATURE 0x4F4D + +#define TYPE_FONT 0 +#define NUMTYPES 1 + +// USE A PITCH TABLE TO AVOID INTEGER MULTIPLIES, EXCEPT ON POWERPC, WHERE +// AN INTEGER MULTIPLY IS FASTER THAN A MEMORY ACCESS +#if defined(powerc) || defined(__powerc) +#define USEPITCHTABLE 0 +#define LINEOFFSET(line) (s_pitch*(line)) +#define ISPITCHVALID (s_pitch != 0) +#else +#define USEPITCHTABLE 1 +#define LINEOFFSET(line) (*(s_pitchtable+(line))) +#define ISPITCHVALID (s_pitchtable != NULL) +#endif + +typedef struct _BITMAPINFO256 { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[256]; +} BITMAPINFO256, *LPBITMAPINFO256; + +NODEDECL(SGDIOBJ) { + WORD signature; + WORD type; + LPBYTE bits; +} *LPSGDIOBJ; + +typedef struct SGDIFONT : public SGDIOBJ { + int filecharwidth; + int filecharheight; + int filepitch; + int filecolumnand; + int filerowshift; + SIZE charsize[256]; +} *LPSGDIFONT; + +static LIST(SGDIOBJ) s_objectlist; +static int s_pitch = 640; +#if USEPITCHTABLE +static LPDWORD s_pitchtable = NULL; +static int s_pitchtablealloc = 0; +static int s_pitchtablelines = 0; +#endif +static int s_screenbpp = 8; +static int s_screenbppshift = 0; +static int s_screencx = 640; +static int s_screency = 480; +static LPSGDIOBJ s_selected[NUMTYPES] = {NULL}; +static LPBYTE s_tempbuffer = NULL; +static int s_tempbuffersize = 0; + +//=========================================================================== +static BOOL AllocateTempBuffer (int size) { + + // USE THE EXISTING BUFFER IF IT IS BIG ENOUGH + if (size && (size <= s_tempbuffersize)) + return 1; + + // OTHERWISE, FREE THE OLD BUFFER + if (s_tempbuffer) { + FREE(s_tempbuffer); + s_tempbuffer = NULL; + s_tempbuffersize = 0; + } + + // ALLOCATE A NEW BUFFER + if (size) { + s_tempbuffer = (LPBYTE)ALLOC(size); + s_tempbuffersize = size; + return TRUE; + } + + return FALSE; +} + +//=========================================================================== +static void inline ClipRectangle (LPRECT rect) { + if (rect->left < 0) + rect->left = 0; + if (rect->top < 0) + rect->top = 0; + if (rect->right > s_screencx) + rect->right = s_screencx; + if (rect->bottom > s_screency) + rect->bottom = s_screency; +} + +//=========================================================================== +static DWORD inline ConvertColorRefToPattern (COLORREF colorref) { + DWORD colordata = 0; + + // IF WE WERE GIVEN A PALETTE INDEX, USE IT + if (colorref & 0x01000000) + if (s_screenbpp == 8) + colordata = colorref & 0x00FFFFFF; + else + colordata = 0; + + // OTHERWISE, CONVERT THE COLOR TO THE CURRENT SCREEN FORMAT + else switch (s_screenbpp) { + + case 8: + colordata = 0; + break; + + case 16: + colordata = ((GetBValue(colorref) >> 3) << 10) + | ((GetGValue(colorref) >> 3) << 5) + | (GetRValue(colorref) >> 3); + break; + + } + + // PROPAGATE THE COLOR INTO THE PATTERN + switch (s_screenbpp) { + + case 8: + colordata |= (colordata << 8) | (colordata << 16) | (colordata << 24); + break; + + case 16: + colordata |= (colordata << 16); + break; + + } + + return colordata; +} + +//=========================================================================== +static LPSGDIOBJ InternalCreateGdiObject (int size, WORD type) { + LPSGDIOBJ ptr = s_objectlist.NewNode(LIST_HEAD,size-sizeof(SGDIOBJ)); + ptr->signature = SIGNATURE; + ptr->type = type; + ptr->bits = NULL; + return ptr; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SGdiBitBlt (LPBYTE videobuffer, + int destx, + int desty, + LPBYTE sourcedata, + LPRECT sourcerect, + int sourcecx, + int sourcecy, + COLORREF color, + DWORD rop) { + VALIDATEBEGIN; + VALIDATE(videobuffer); + VALIDATE(sourcedata); + VALIDATE(s_pitch); + VALIDATEEND; + + // MAKE LOCAL COPIES OF THE SOURCE AND DESTINATION RECTANGLES + RECT localdestrect = {destx,desty,4095,4095}; + SIZE localdestsize = {s_screencx,s_screency}; + SIZE localsourcesize = {sourcecx,sourcecy}; + RECT localsourcerect; + if (sourcerect) + CopyMemory(&localsourcerect,sourcerect,sizeof(RECT)); + + // IF NECESSARY, CONVERT THE COLORREF TO A PATTERN + DWORD localpattern = 0; + if (color && (rop != SRCCOPY)) + localpattern = ConvertColorRefToPattern(color); + + // IF WE ARE NOT IN 8-BIT MODE, CONVERT PIXELS TO BYTES + if (s_screenbppshift) { + localdestrect.left <<= s_screenbppshift; + localdestrect.right <<= s_screenbppshift; + localdestsize.cx <<= s_screenbppshift; + localsourcerect.left <<= s_screenbppshift; + localsourcerect.right <<= s_screenbppshift; + localsourcesize.cx <<= s_screenbppshift; + } + + // PERFORM THE BITBLT + return SBltROP3Clipped(videobuffer, + &localdestrect, + &localdestsize, + s_pitch, + sourcedata, + sourcerect ? &localsourcerect : NULL, + &localsourcesize, + sourcecx << s_screenbppshift, + localpattern, + rop); +} + +//=========================================================================== +BOOL APIENTRY SGdiCreateFont (LPBYTE bits, + int width, + int height, + int bitdepth, + int filecharwidth, + int filecharheight, + LPSIZE charsizetable, + HSGDIFONT *handle) { + if (handle) + *handle = (HSGDIFONT)0; + + VALIDATEBEGIN; + VALIDATE(bits); + VALIDATE(width); + VALIDATE(height); + VALIDATE(filecharwidth); + VALIDATE(filecharheight); + VALIDATE(charsizetable); + VALIDATE(handle); + VALIDATEEND; + + // CREATE A RECORD FOR THE FONT + LPSGDIFONT newptr = (LPSGDIFONT)InternalCreateGdiObject(sizeof(SGDIFONT), + TYPE_FONT); + if (!newptr) + return FALSE; + LPBYTE savebits = (LPBYTE)ALLOC((width*height*bitdepth) >> 3); + CopyMemory(savebits,bits,(width*height*bitdepth) >> 3); + CopyMemory(&newptr->charsize[0],charsizetable,256*sizeof(SIZE)); + newptr->bits = savebits; + newptr->filecharwidth = filecharwidth; + newptr->filecharheight = filecharheight; + newptr->filepitch = width; + newptr->filecolumnand = 1; + newptr->filerowshift = 0; + int charspercolumn = 1; + while (charspercolumn < width/filecharwidth) { + charspercolumn <<= 1; + newptr->filecolumnand <<= 1; + ++newptr->filerowshift; + } + --newptr->filecolumnand; + + // RETURN A HANDLE TO THE FONT + if (handle) + *handle = (HSGDIFONT)newptr; + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SGdiDeleteObject (HSGDIOBJ handle) { + + // GET A POINTER TO THE OBJECT + LPSGDIOBJ ptr = (LPSGDIOBJ)handle; + if ((!ptr) || (ptr->signature != SIGNATURE) || (ptr->type >= NUMTYPES)) + return FALSE; + + // UNSELECT THE OBJECT + if (s_selected[ptr->type] == ptr) + s_selected[ptr->type] = NULL; + + // FREE ANY DATA ALLOCATED FOR THIS OBJECT + if (ptr->bits) { + FREE(ptr->bits); + ptr->bits = NULL; + } + + // UNLINK AND FREE THE OBJECT + s_objectlist.DeleteNode(ptr); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SGdiDestroy () { + LPSGDIOBJ curr; + while ((curr = s_objectlist.Head()) != NULL) { + switch (curr->type) { + + case TYPE_FONT: + REPORTRESOURCELEAK(HSGDIFONT); + break; + + default: + REPORTRESOURCELEAK(HSGDIOBJ); + break; + + } + SGdiDeleteObject((HSGDIOBJ)curr); + } + AllocateTempBuffer(0); +#if USEPITCHTABLE + if (s_pitchtable) { + FREE(s_pitchtable); + s_pitchtable = NULL; + s_pitchtablealloc = 0; + s_pitchtablelines = 0; + } +#endif + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SGdiExtTextOut (LPBYTE videobuffer, + int x, + int y, + LPRECT rect, + COLORREF color, + int textcoloruse, + int bkgcoloruse, + LPCTSTR string, + int chars) { + VALIDATEBEGIN; + VALIDATE(videobuffer); + VALIDATE(rect); + VALIDATE(string); + VALIDATEEND; + + if (!(ISPITCHVALID && s_selected[TYPE_FONT])) + return FALSE; + if (chars < 0) + chars = SStrLen(string); + + // CLIP THE RECTANGLE AND COORDINATES AGAINST THE SCREEN + RECT clippedrect; + clippedrect.left = max(rect->left,0); + clippedrect.top = max(rect->top,0); + clippedrect.right = max(rect->left,min(rect->right,s_screencx)); + clippedrect.bottom = max(rect->top,min(rect->bottom,s_screency)); + x = max(clippedrect.left,min(x,s_screencx)); + y = max(clippedrect.top ,min(y,s_screency)); + + // IF THE TEXT AND BACKGROUND ARE TO BE THE SAME COLOR, USE THE RECTANGLE() + // FUNCTION INSTEAD + if (textcoloruse == bkgcoloruse) + if (textcoloruse == ETO_TEXT_TRANSPARENT) + return TRUE; + else + return SGdiRectangle(videobuffer, + clippedrect.left, + clippedrect.right, + clippedrect.top, + clippedrect.bottom, + (textcoloruse == ETO_TEXT_COLOR) + ? color + : (textcoloruse == ETO_TEXT_BLACK) + ? PALETTEINDEX(0x00) + : PALETTEINDEX(0xFF)); + + // DETERMINE THE PATTERN AND ROP CODE + DWORD pattern = ConvertColorRefToPattern(color); + DWORD rop = 0; + switch (textcoloruse) { + + case ETO_TEXT_TRANSPARENT: + switch (bkgcoloruse) { + case ETO_BKG_COLOR: rop = 0x00E20746; break; + case ETO_BKG_BLACK: rop = 0x00220326; break; + case ETO_BKG_WHITE: rop = 0x00EE0086; break; + } + break; + + case ETO_TEXT_COLOR: + switch (bkgcoloruse) { + case ETO_BKG_TRANSPARENT: rop = 0x00B8074A; break; + case ETO_BKG_BLACK: rop = 0x0030032A; break; + case ETO_BKG_WHITE: rop = 0x00FC008A; break; + } + break; + + case ETO_TEXT_BLACK: + switch (bkgcoloruse) { + case ETO_BKG_TRANSPARENT: rop = 0x008800C6; break; + case ETO_BKG_COLOR: rop = 0x00C000CA; break; + case ETO_BKG_WHITE: rop = 0x00CC0020; break; + } + break; + + case ETO_TEXT_WHITE: + switch (bkgcoloruse) { + case ETO_BKG_TRANSPARENT: rop = 0x00BB0226; break; + case ETO_BKG_COLOR: rop = 0x00F3022A; break; + case ETO_BKG_BLACK: rop = 0x00330008; break; + } + break; + + } + if (!rop) + return FALSE; + + // DRAW THE TEXT + LPSGDIFONT currfont = (LPSGDIFONT)s_selected[TYPE_FONT]; + int textx = x; + { + SIZE destsize = {s_screencx,s_screency}; + while (chars--) { + RECT sourcerect; + sourcerect.left = (int)(((BYTE)*string) & currfont->filecolumnand)*currfont->filecharwidth; + sourcerect.top = (int)(((BYTE)*string) >> currfont->filerowshift)*currfont->filecharheight; + sourcerect.right = sourcerect.left+min(clippedrect.right-textx, + currfont->filecharwidth); + sourcerect.bottom = sourcerect.top+min(clippedrect.bottom-y, + currfont->filecharheight); + SGdiBitBlt(videobuffer, + textx, + y, + currfont->bits, + &sourcerect, + currfont->filepitch, + 0x7FFF, + color, + rop); + textx += currfont->charsize[(BYTE)*(string++)].cx; + } + } + textx = min(textx,s_screencx-1); + + // IF THE BACKGROUND IS TRANSPARENT, RETURN NOW + if (bkgcoloruse == ETO_BKG_TRANSPARENT) + return TRUE; + + // DETERMINE A ROP CODE FOR DRAWING THE UNOBSTRUCTED BACKGROUND AREA + switch (bkgcoloruse) { + case ETO_BKG_COLOR: rop = PATCOPY; break; + case ETO_BKG_BLACK: rop = BLACKNESS; break; + case ETO_BKG_WHITE: rop = WHITENESS; break; + } + + // DRAW THE AREA TO THE LEFT OF THE TEXT + if (x > rect->left) + SBltROP3(videobuffer+LINEOFFSET(y)+rect->left, + NULL, + x-rect->left, + min(currfont->filecharheight,rect->bottom-y), + s_pitch, + 0, + pattern, + rop); + + // DRAW THE AREA TO THE RIGHT OF THE TEXT + if (textx < rect->right) + SBltROP3(videobuffer+LINEOFFSET(y)+textx, + NULL, + rect->right-textx, + min(currfont->filecharheight,rect->bottom-y), + s_pitch, + 0, + pattern, + rop); + + // DRAW THE AREA ABOVE THE TEXT + if (y > rect->top) + SBltROP3(videobuffer+LINEOFFSET(rect->top)+rect->left, + NULL, + rect->right-rect->left, + y-rect->top, + s_pitch, + 0, + pattern, + rop); + + // DRAW THE AREA BELOW THE TEXT + if (y+currfont->filecharheight < rect->bottom) + SBltROP3(videobuffer+LINEOFFSET(y+currfont->filecharheight)+rect->left, + NULL, + rect->right-rect->left, + rect->bottom-(y+currfont->filecharheight), + s_pitch, + 0, + pattern, + rop); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SGdiGetTextExtent (LPCTSTR string, + int chars, + LPSIZE size) { + if (size) { + size->cx = 0; + size->cy = 0; + } + + VALIDATEBEGIN; + VALIDATE(string); + VALIDATE(size); + VALIDATEEND; + + LPSGDIFONT currfont = (LPSGDIFONT)s_selected[TYPE_FONT]; + if (!currfont) + return FALSE; + if (chars < 0) + chars = SStrLen(string); + + while (chars--) { + size->cx += currfont->charsize[(BYTE)*string].cx; + size->cy = max(size->cy,currfont->charsize[(BYTE)*string].cy); + ++string; + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SGdiImportFont (HFONT windowsfont, + HSGDIFONT *handle) { + if (handle) + *handle = (HSGDIFONT)0; + + VALIDATEBEGIN; + VALIDATE(windowsfont); + VALIDATE(handle); + VALIDATEEND; + + HBITMAP bitmap = (HBITMAP)0; + LPSIZE charsizetable = NULL; + HDC dc = (HDC)0; + HDC memdc = (HDC)0; + HFONT oldfont = (HFONT)0; + LPBYTE packedbits = NULL; + BOOL success = FALSE; + LPBYTE unpackedbits = NULL; + + TRY { + + // CREATE A DC AND SELECT THE FONT INTO IT + dc = GetDC(GetDesktopWindow()); + memdc = CreateCompatibleDC(dc); + if (!(dc && memdc)) + LEAVE; + oldfont = (HFONT)SelectObject(memdc,windowsfont); + + // VERIFY THAT THE FONT IS A TRUETYPE FONT + { + TEXTMETRIC tm; + ZeroMemory(&tm,sizeof(TEXTMETRIC)); + GetTextMetrics(memdc,&tm); + if (!(tm.tmPitchAndFamily & TMPF_TRUETYPE)) + LEAVE; + } + + // BUILD THE CHARACTER SIZE TABLE, AND DETERMINE THE MAXIMUM SIZE OF ANY + // CHARACTER IN THE FONT, AS WELL AS THE MAXIMUM EXPECTED HEIGHT OF ANY + // COMBINATION OF CHARACTERS + SIZE maxsize = {0,0}; + { + LPCTSTR testchars = "W_y,|'"; + GetTextExtentPoint32(memdc,testchars,SStrLen(testchars),&maxsize); + maxsize.cx = 0; + } + charsizetable = (LPSIZE)ALLOC(256*sizeof(SIZE)); + { + for (int loop = 0; loop < 256; ++loop) { + char teststring[2] = {loop,0}; + GetTextExtentPoint32(memdc,teststring,1,charsizetable+loop); + maxsize.cx = max(maxsize.cx,(charsizetable+loop)->cx+1); + maxsize.cy = max(maxsize.cy,(charsizetable+loop)->cy+1); + } + } + if (!(maxsize.cx && maxsize.cy)) + LEAVE; + + // ADD ONE TO THE WIDTH TO LEAVE A SPACE BETWEEN CHARACTERS, AND ROUND + // THE RESULT UP TO A MULTIPLE OF FOUR PIXELS + if (maxsize.cx & 3) + maxsize.cx += 4-(maxsize.cx & 3); + SIZE bitmapsize = {maxsize.cx*16,maxsize.cy*16}; + + // PREPARE A BITMAP HEADER AND COLOR TABLE + BITMAPINFO256 info; + ZeroMemory(&info,sizeof(BITMAPINFO256)); + info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info.bmiHeader.biWidth = bitmapsize.cx; + info.bmiHeader.biHeight = bitmapsize.cy; + info.bmiHeader.biPlanes = 1; + info.bmiHeader.biBitCount = 1; + info.bmiHeader.biCompression = BI_RGB; + + // CREATE A DEVICE INDEPENDENT BITMAP AND SELECT IT INTO THE MEMORY DC + bitmap = CreateDIBitmap(memdc,&info.bmiHeader,0,NULL,(LPBITMAPINFO)&info,DIB_RGB_COLORS); + if (!bitmap) + LEAVE; + HBITMAP oldbitmap = (HBITMAP)SelectObject(memdc,bitmap); + + // BLANK OUT THE BITMAP + { + HBRUSH oldbrush = (HBRUSH)SelectObject(memdc,GetStockObject(WHITE_BRUSH)); + HPEN oldpen = (HPEN) SelectObject(memdc,GetStockObject(WHITE_PEN)); + Rectangle(memdc,0,0,bitmapsize.cx,bitmapsize.cy); + SelectObject(memdc,oldbrush); + SelectObject(memdc,oldpen); + } + + // DRAW THE FONT INTO THE BITMAP + SetTextAlign(memdc,TA_LEFT | TA_TOP); + SetTextColor(memdc,0); + SetBkColor(memdc,0xFFFFFF); + SetBkMode(memdc,OPAQUE); + { + char string[2] = "?"; + for (int y = 0; y < 16; ++y) + for (int x = 0; x < 16; ++x) { + string[0] = y*16+x; + RECT rect = {x*maxsize.cx, + y*maxsize.cy, + (x+1)*maxsize.cx, + (y+1)*maxsize.cy}; + ExtTextOut(memdc, + x*maxsize.cx+1, + y*maxsize.cy+1, + ETO_OPAQUE, + &rect, + string, + 1, + NULL); + } + } + + // UNSELECT THE BITMAP + SelectObject(memdc,oldbitmap); + + // GET THE BITMAP BITS + packedbits = (LPBYTE)ALLOC(bitmapsize.cx*bitmapsize.cy/8); + if (!GetDIBits(memdc,bitmap,0,bitmapsize.cy,packedbits,(LPBITMAPINFO)&info,DIB_RGB_COLORS)) + LEAVE; + + // UNPACK THE BITMAP BITS INTO 8-BIT TOP-DOWN FORMAT + unpackedbits = (LPBYTE)ALLOC(bitmapsize.cx*bitmapsize.cy); + { + LPBYTE source = packedbits+(bitmapsize.cy-1)*bitmapsize.cx/8; + LPBYTE dest = unpackedbits; + for (int y = 0; y < bitmapsize.cy; ++y) { + for (int x = 0; x < bitmapsize.cx/8; ++x) { + for (int bit = 128; bit; bit >>= 1) + *dest++ = ((*source) & bit) ? 0xFF : 0; + ++source; + } + source -= bitmapsize.cx/4; + } + } + + // CREATE A STORM FONT FROM THE BITMAP BITS + success = SGdiCreateFont(unpackedbits, + bitmapsize.cx, + bitmapsize.cy, + 8, + maxsize.cx, + maxsize.cy, + charsizetable, + handle); + + } + FINALLY { + if (unpackedbits) + FREE(unpackedbits); + if (packedbits) + FREE(packedbits); + if (charsizetable) + FREE(charsizetable); + if (memdc && oldfont) + SelectObject(memdc,oldfont); + if (bitmap) + DeleteObject(bitmap); + if (memdc) + DeleteDC(memdc); + if (dc) + ReleaseDC(GetDesktopWindow(),dc); + } + + return success; +} + +//=========================================================================== +BOOL APIENTRY SGdiLoadFont (LPCTSTR filename, + int filecharwidth, + int filecharheight, + int basecharwidth, + LPSIZE charsizetable, + HSGDIFONT *handle) { + VALIDATEBEGIN; + VALIDATE(filename); + VALIDATE(*filename); + VALIDATE(filecharwidth); + VALIDATE(filecharheight); + VALIDATE(basecharwidth || charsizetable); + VALIDATE(handle); + VALIDATEEND; + + // DETERMINE THE SIZE OF THE FONT FILE + int width; + int height; + int bitdepth; + if (!SBmpLoadImage(filename,NULL,NULL,0,&width,&height,&bitdepth)) + return FALSE; + + // ALLOCATE MEMORY FOR THE FONT BITS + if (!AllocateTempBuffer(width*height)) + return FALSE; + + // READ THE FONT BITS + if (!SBmpLoadImage(filename,NULL,s_tempbuffer,width*height)) + return FALSE; + + // IF WE WEREN'T PASSED A CHARACTER SIZE TABLE, CREATE ONE BASED ON THE + // BASE CHARACTER WIDTH + SIZE charsize[256]; + if (!charsizetable) + for (int loop = 0; loop < 256; ++loop) { + charsize[loop].cx = basecharwidth; + charsize[loop].cy = basecharwidth; + } + + // CREATE THE FONT + return SGdiCreateFont(s_tempbuffer, + width, + height, + bitdepth, + filecharwidth, + filecharheight, + charsizetable ? charsizetable : &charsize[0], + handle); +} + +//=========================================================================== +BOOL APIENTRY SGdiRectangle (LPBYTE videobuffer, + int left, + int top, + int right, + int bottom, + COLORREF color) { + VALIDATEBEGIN; + VALIDATE(videobuffer); + VALIDATEEND; + + if (!ISPITCHVALID) + return FALSE; + RECT destrect = {left,top,right,bottom}; + DWORD pattern = ConvertColorRefToPattern(color); + ClipRectangle(&destrect); + return SBltROP3(videobuffer+LINEOFFSET(destrect.top)+(destrect.left << s_screenbppshift), + NULL, + (destrect.right-destrect.left) << s_screenbppshift, + destrect.bottom-destrect.top, + s_pitch, + 0, + pattern, + PATCOPY); +} + +//=========================================================================== +BOOL APIENTRY SGdiSelectObject (HSGDIOBJ handle) { + + // GET A POINTER TO THE OBJECT + LPSGDIOBJ ptr = (LPSGDIOBJ)handle; + if ((!ptr) || (ptr->signature != SIGNATURE) || (ptr->type >= NUMTYPES)) + return FALSE; + + // SELECT THE OBJECT + s_selected[ptr->type] = ptr; + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SGdiSetPitch (int pitch) { + VALIDATEBEGIN; + VALIDATE(pitch > 0); + VALIDATEEND; + + SDrawGetScreenSize(&s_screencx, + &s_screency, + &s_screenbpp); + return SGdiSetTargetDimensions(s_screencx, + s_screency, + s_screenbpp, + pitch); +} + +//=========================================================================== +BOOL APIENTRY SGdiSetTargetDimensions (int width, + int height, + int bitdepth, + int pitch) { + + // UPDATE THE CACHED DIMENSIONS + s_screencx = width; + s_screency = height; + s_screenbpp = bitdepth; + s_screenbppshift = (s_screenbpp == 16); + + // DON'T RECOMPUTE THE PITCH IF IT HASN'T CHANGED + if ((pitch == s_pitch) && + (height == s_pitchtablelines) && + ISPITCHVALID) + return TRUE; + s_pitch = pitch; + +#if USEPITCHTABLE + + // REALLOCATE THE PITCH TABLE IF NECESSARY + if (s_screency > s_pitchtablealloc) { + if (s_pitchtable) + FREE(s_pitchtable); + s_pitchtablealloc = s_screency; + s_pitchtable = (LPDWORD)ALLOC(s_screency*sizeof(DWORD)); + } + + // BUILD THE NEW PITCH TABLE + s_pitchtablelines = s_screency; + { + DWORD offset = 0; + for (int loop = 0; loop < s_pitchtablelines; ++loop) { + *(s_pitchtable+loop) = offset; + offset += pitch; + } + } + +#endif + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SGdiTextOut (LPBYTE videobuffer, + int x, + int y, + COLORREF color, + LPCTSTR string, + int chars) { + int textcoloruse; + if (!color) + textcoloruse = ETO_TEXT_BLACK; + else if (color == PALETTEINDEX(0xFF)) + textcoloruse = ETO_TEXT_WHITE; + else + textcoloruse = ETO_TEXT_COLOR; + RECT rect = {0,0,INT_MAX,INT_MAX}; + return SGdiExtTextOut(videobuffer, + x, + y, + &rect, + color, + textcoloruse, + ETO_BKG_TRANSPARENT, + string, + chars); +} diff --git a/Storm/SOURCE/SINTERN.H b/Storm/SOURCE/SINTERN.H new file mode 100644 index 0000000..170d9b6 --- /dev/null +++ b/Storm/SOURCE/SINTERN.H @@ -0,0 +1,19 @@ +#define _beginthreadex CreateThread +#define _endthreadex(a) + +/**************************************************************************** +* +* Storm functions +* +***/ + +HINSTANCE StormGetInstance (); + +/**************************************************************************** +* +* SFile functions +* +***/ + +BOOL APIENTRY SFileOpenFileWin32 (LPCTSTR filename, + HANDLE *handle); diff --git a/Storm/SOURCE/SLOG.CPP b/Storm/SOURCE/SLOG.CPP new file mode 100644 index 0000000..31c20ce --- /dev/null +++ b/Storm/SOURCE/SLOG.CPP @@ -0,0 +1,387 @@ +/**************************************************************************** +* +* SLOG.CPP +* Storm logging functions +* +* By Michael O'Brien (10/14/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define BUFFERSIZE 0x10000 +#define FLUSHMARK 0xC000 +#define SLOTS 4 // must be a power of two + +DECLARE_STRICT_HANDLE(HLOCKEDLOG); + +typedef struct _LOG { + HSLOG log; + _LOG *next; + HANDLE file; + DWORD bufferused; + DWORD pendpoint; + char buffer[BUFFERSIZE]; +} LOG, *LOGPTR; + +static CRITICAL_SECTION s_critsect[SLOTS]; +static LOGPTR s_loghead[SLOTS]; +static HSLOG s_sequence; + +//=========================================================================== +static void FlushLog (LOGPTR logptr) { + if (!logptr->bufferused) + return; + DWORD byteswritten; + WriteFile(logptr->file, + logptr->buffer, + logptr->bufferused, + &byteswritten, + NULL); + logptr->bufferused = 0; + logptr->pendpoint = 0; +} + +//=========================================================================== +static LOGPTR LockLog (HSLOG log, + HLOCKEDLOG *lockedhandle, + BOOL createifnecessary) { + + // IF THE LOG HANDLE IS NULL, JUST RETURN A NULL POINTER, INDICATING TO + // THE CALLER THAT IT SHOULD SILENTLY FAIL. THIS ALLOWS APPLICATIONS + // TO USE THE SAME CODE WHETHER LOGGING IS ENABLED OR DISABLED. + if (!log) { + *lockedhandle = (HLOCKEDLOG)0xFFFFFFFF; + return NULL; + } + + // DETERMINE WHICH SLOT THE LOG RECORD SHOULD BE IN + DWORD slot = (DWORD)log & (SLOTS-1); + EnterCriticalSection(&s_critsect[slot]); + *lockedhandle = (HLOCKEDLOG)slot; + + // SEARCH FOR AN EXISTING LOG RECORD + LOGPTR *nextptr = &s_loghead[slot]; + LOGPTR currptr; + while ((currptr = *nextptr) != NULL) + if (currptr->log == log) + return currptr; + else + nextptr = &currptr->next; + + // IF WE DIDN'T FIND ONE, CREATE A NEW RECORD + if (!createifnecessary) { + LeaveCriticalSection(&s_critsect[slot]); + *lockedhandle = (HLOCKEDLOG)0xFFFFFFFF; + return NULL; + } + currptr = *nextptr = (LOGPTR)VirtualAlloc(NULL,sizeof(LOG),MEM_COMMIT,PAGE_READWRITE); + currptr->log = log; + currptr->next = NULL; + currptr->file = INVALID_HANDLE_VALUE; + currptr->bufferused = 0; + currptr->pendpoint = 0; + return currptr; + +} + +//=========================================================================== +static void OutputReturn (LOGPTR logptr) { + CopyMemory(logptr->buffer+logptr->bufferused,"\r\n",3); + logptr->bufferused += 2; +} + +//=========================================================================== +static void OutputTime (LOGPTR logptr, BOOL show) { + + // GENERATE A NEW TIME STRING IF NECESSARY + static char timestr[64] = ""; + static DWORD timestrlen = 0; + static DWORD lasttime = 0; + DWORD currtime = GetTickCount(); + if (currtime != lasttime) { + lasttime = currtime; + SYSTEMTIME systime; + GetLocalTime(&systime); + wsprintf(timestr, + "%u/%u %02u:%02u:%02u.%03u ", + systime.wMonth, + systime.wDay, + systime.wHour, + systime.wMinute, + systime.wSecond, + systime.wMilliseconds); + timestrlen = SStrLen(timestr); + } + + // COPY THE TIME STRING TO THE OUTPUT BUFFER + if (show) + CopyMemory(logptr->buffer+logptr->bufferused,timestr,timestrlen+1); + else { + FillMemory(logptr->buffer+logptr->bufferused,timestrlen,' '); + logptr->buffer[logptr->bufferused+timestrlen] = 0; + } + logptr->bufferused += timestrlen; + +} + +//=========================================================================== +static void UnlockDeleteLog (LOGPTR logptr, HLOCKEDLOG lockedhandle) { + DWORD slot = (DWORD)lockedhandle; + LOGPTR *nextptr = &s_loghead[slot]; + LOGPTR currptr; + while ((currptr = *nextptr) != NULL) + if (currptr == logptr) { + *nextptr = currptr->next; + VirtualFree(currptr,0,MEM_RELEASE); + break; + } + else + nextptr = &currptr->next; + LeaveCriticalSection(&s_critsect[slot]); +} + +//=========================================================================== +static void UnlockLog (HLOCKEDLOG lockedhandle) { + DWORD slot = (DWORD)lockedhandle; + LeaveCriticalSection(&s_critsect[slot]); +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +void APIENTRY SLogClose (HSLOG log) { + + // LOCK THE LOG RECORD + HLOCKEDLOG lockedhandle; + LOGPTR logptr = LockLog(log,&lockedhandle,FALSE); + if (!logptr) + return; + + // FLUSH THE LOG RECORD AND CLOSE THE FILE + FlushLog(logptr); + CloseHandle(logptr->file); + + // UNLOCK THE LOG RECORD + UnlockDeleteLog(logptr,lockedhandle); + +} + +//=========================================================================== +BOOL APIENTRY SLogCreate (LPCTSTR filename, + DWORD flags, + HSLOG *log) { + VALIDATEBEGIN; + VALIDATE(filename); + VALIDATE(*filename); + VALIDATEANDBLANK(log); + VALIDATEEND; + + // OPEN THE FILE + HANDLE file = CreateFile(filename, + GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (file == INVALID_HANDLE_VALUE) + return FALSE; + + // CREATE THE LOG RECORD + *log = s_sequence = (HSLOG)(((DWORD)s_sequence)+1); + HLOCKEDLOG lockedhandle; + LOGPTR logptr = LockLog(*log,&lockedhandle,TRUE); + logptr->file = file; + UnlockLog(lockedhandle); + + return TRUE; +} + +//=========================================================================== +void APIENTRY SLogDestroy () { + SLogFlushAll(); + for (DWORD slot = 0; slot < SLOTS; ++slot) { + EnterCriticalSection(&s_critsect[slot]); + while (s_loghead[slot]) { + SLogClose(s_loghead[slot]->log); + REPORTRESOURCELEAK(HSLOG); + } + LeaveCriticalSection(&s_critsect[slot]); + DeleteCriticalSection(&s_critsect[slot]); + } +} + +//=========================================================================== +void APIENTRY SLogDump (HSLOG log, + LPCVOID data, + DWORD bytes) { + + // LOCK THE LOG RECORD + HLOCKEDLOG lockedhandle; + LOGPTR logptr = LockLog(log,&lockedhandle,FALSE); + if (!logptr) + return; + +#define SPRINTFTOBUFFER(fmt,val) \ + do { \ + wsprintf(logptr->buffer+logptr->bufferused,(fmt),(val)); \ + logptr->bufferused += SStrLen(logptr->buffer+logptr->bufferused); \ + } while (0) +#define STRCPYTOBUFFER(str) \ + logptr->bufferused += SStrCopy(logptr->buffer+logptr->bufferused,(str)) + + // OUTPUT THE DATA TO THE LOG IN HEX FORMAT, EIGHT BYTES PER LINE + DWORD offset = 0; + while (offset < bytes) { + OutputTime(logptr,FALSE); + SPRINTFTOBUFFER("%04x ",offset); + DWORD loop; + for (loop = offset; loop < offset+8; ++loop) { + if (loop < bytes) + SPRINTFTOBUFFER("%02x ",(unsigned)*((LPBYTE)data+loop)); + else + STRCPYTOBUFFER(" "); + if ((loop & 3) == 3) + STRCPYTOBUFFER(" "); + } + for (loop = offset; loop < offset+8; ++loop) { + char value = (loop < bytes) ? *((char *)data+loop) : 0; + if ((value >= 32) && (value <= 126)) + SPRINTFTOBUFFER("%c",value); + else + STRCPYTOBUFFER(value ? "." : " "); + if ((loop & 7) == 3) + STRCPYTOBUFFER(" "); + } + OutputReturn(logptr); + offset += 8; + } + +#undef STRCPYTOBUFFER +#undef SPRINTFTOBUFFER + + // ADVANCE THE PENDING POINT + logptr->pendpoint = logptr->bufferused; + + // IF THE BUFFER IS GETTING FULL, FLUSH IT + if (logptr->bufferused >= FLUSHMARK) + FlushLog(logptr); + + // UNLOCK THE LOG RECORD + UnlockLog(lockedhandle); + +} + +//=========================================================================== +void APIENTRY SLogFlush (HSLOG log) { + + // LOCK THE LOG RECORD + HLOCKEDLOG lockedhandle; + LOGPTR logptr = LockLog(log,&lockedhandle,FALSE); + if (!logptr) + return; + + // FLUSH THE LOG + FlushLog(logptr); + + // UNLOCK THE LOG RECORD + UnlockLog(lockedhandle); + +} + +//=========================================================================== +void APIENTRY SLogFlushAll () { + for (DWORD slot = 0; slot < SLOTS; ++slot) { + EnterCriticalSection(&s_critsect[slot]); + LOGPTR curr = s_loghead[slot]; + while (curr) { + FlushLog(curr); + curr = curr->next; + } + LeaveCriticalSection(&s_critsect[slot]); + } +} + +//=========================================================================== +void APIENTRY SLogInitialize () { + for (DWORD slot = 0; slot < SLOTS; ++slot) + InitializeCriticalSection(&s_critsect[slot]); +} + +//=========================================================================== +void __cdecl SLogPend (HSLOG log, + LPCTSTR format, + ...) { + + // LOCK THE LOG RECORD + HLOCKEDLOG lockedhandle; + LOGPTR logptr = LockLog(log,&lockedhandle,FALSE); + if (!logptr) + return; + + // RESET THE OUTPUT LOCATION TO THE PENDING POINT + logptr->bufferused = logptr->pendpoint; + + // OUTPUT THE CURRENT TIME TO THE LOG + OutputTime(logptr,TRUE); + + // OUTPUT THE ARGUMENT STRING TO THE LOG + va_list arglist; + va_start(arglist,format); + vsprintf(logptr->buffer+logptr->bufferused, + format, + arglist); + va_end(arglist); + logptr->bufferused += SStrLen(logptr->buffer+logptr->bufferused); + + // OUTPUT A CARRIAGE RETURN TO THE LOG + OutputReturn(logptr); + + // UNLOCK THE LOG RECORD + UnlockLog(lockedhandle); + +} + +//=========================================================================== +void __cdecl SLogWrite (HSLOG log, + LPCTSTR format, + ...) { + + // LOCK THE LOG RECORD + HLOCKEDLOG lockedhandle; + LOGPTR logptr = LockLog(log,&lockedhandle,FALSE); + if (!logptr) + return; + + // OUTPUT THE CURRENT TIME TO THE LOG + OutputTime(logptr,TRUE); + + // OUTPUT THE ARGUMENT STRING TO THE LOG + va_list arglist; + va_start(arglist,format); + vsprintf(logptr->buffer+logptr->bufferused, + format, + arglist); + va_end(arglist); + logptr->bufferused += SStrLen(logptr->buffer+logptr->bufferused); + + // OUTPUT A CARRIAGE RETURN TO THE LOG + OutputReturn(logptr); + + // ADVANCE THE PENDING POINT + logptr->pendpoint = logptr->bufferused; + + // IF THE BUFFER IS GETTING FULL, FLUSH IT + if (logptr->bufferused >= FLUSHMARK) + FlushLog(logptr); + + // UNLOCK THE LOG RECORD + UnlockLog(lockedhandle); + +} diff --git a/Storm/SOURCE/SMEM.CPP b/Storm/SOURCE/SMEM.CPP new file mode 100644 index 0000000..a686906 --- /dev/null +++ b/Storm/SOURCE/SMEM.CPP @@ -0,0 +1,1316 @@ +/**************************************************************************** +* +* SMEM.CPP +* Storm memory manager +* +* By Michael O'Brien (3/18/97) +* +* This module cannot use constructors or destructors, because it is called +* by the runtime library startup code prior to construction and after +* destruction. +* +* The allocation functions implemented in this module are guaranteed not +* to return NULL. Storm always displays a fatal error if an allocation +* can not succeed, so that the application does not have to have failure +* code paths for each allocation. However, Storm does not display errors +* for failures to free memory unless debug mode is enabled. +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define FIRSTUSERHEAP 0x80000000 // must be a power of two +#define MAXALLOCSIZE (0xFFFF-(sizeof(HEAP)+MAX_PATH+sizeof(BLOCK)+2*sizeof(DWORD))) +#define MAXFREEMAINT 4 +#define MAXHEAPSIZE 0x7FFFFFFF +#define MINBLOCKSIZE (sizeof(BLOCK)+2*sizeof(DWORD)) +#define PAGESIZE 0x1000 // must be a power of two +#define RESERVESIZE 0x10000 +#define SIGNATURE1 0x6F6D +#define SIGNATURE2 0xB112 +#define TABLESIZE 256 // must be a power of two + +#define REGKEY "Internal" +#define REGVAL_DEBUG "Debug Memory" +#define REGVAL_GUARD "Protect Memory" +#define REGVAL_TRACEFILE "SMem Trace File" + +#define BF_BOUNDINGSIG 0x01 +#define BF_FREEBLOCK 0x02 +#define BF_LARGEALLOC 0x04 +#define BF_OUTSIDEHEAP 0x08 +#define BF_PRESERVE 0x80 + +typedef struct _BLOCK { + WORD bytes; + BYTE padding; + BYTE flags; + WORD heapaddr; + WORD signature1; +} BLOCK, *BLOCKPTR; + +typedef struct _FASTBLOCK { + WORD bytes; + BYTE padding; + BYTE flags; + DWORD addrsig; +} FASTBLOCK, *FASTBLOCKPTR; + +typedef struct _FREEBLOCK { + WORD bytes; + BYTE padding; + BYTE flags; + _FREEBLOCK *next; +} FREEBLOCK, *FREEBLOCKPTR; + +typedef struct _HEAP { + _HEAP *next; + HSHEAP handle; + DWORD slot; + DWORD addrsig; + BOOL active; + DWORD allocatedblocks; + BLOCKPTR firstblock; + BLOCKPTR termblock; + FREEBLOCKPTR firstfreeblock; + DWORD maintainfreelist; + DWORD chunksize; + DWORD committedbytes; + DWORD reservedbytes; + int linenumber; + char filename[1]; +} HEAP, *HEAPPTR; + +DECLARE_STRICT_HANDLE(HLOCKEDHEAP); + +static BOOL s_emptyheap[TABLESIZE]; +static CRITICAL_SECTION s_critsect[TABLESIZE]; +static BOOL s_debugmode; +static BOOL s_guardmode; +static HEAPPTR s_heaphead[TABLESIZE]; +static BOOL s_initialized; +static HEAPPTR s_lastemptyheap; +static DWORD s_pagesize; + +/**************************************************************************** +* +* TRACING FUNCTIONS +* +***/ + +#ifdef _DEBUG + +static CSLog s_log(REGKEY,REGVAL_TRACEFILE); + +//=========================================================================== +static inline void Trace (LPVOID ptr, + LPCTSTR funcname, + LPCTSTR filename, + int linenumber) { + if (!s_log.GetHandle()) + return; + SLogWrite(s_log.GetHandle(), + "[0x%08x] %-20s %s (%d)", + ptr, + funcname, + filename ? filename : "", + linenumber); +} + +#define TRACE Trace + +#else + +#define TRACE + +#endif + +/**************************************************************************** +* +* SYNCHRONIZATION AND CONVERSION FUNCTIONS +* +***/ + +//=========================================================================== +static inline BOOL CheckInitialized () { +#ifdef STATICLIB + if (!s_initialized) + SMemInitialize(); +#endif + return s_initialized; +} + +//=========================================================================== +static void FatalError (DWORD errorcode, + LPCSTR filename, + int linenumber) { + SErrDisplayError(errorcode, + filename, + linenumber, + NULL, + FALSE); + ExitProcess(1); +} + +//=========================================================================== +static inline BLOCKPTR GetBlockPtrByPtr (LPVOID ptr) { + if (!ptr) + return NULL; + BLOCKPTR blockptr = (BLOCKPTR)ptr-1; + if (blockptr->flags & BF_OUTSIDEHEAP) + blockptr = *(BLOCKPTR *)((LPBYTE)blockptr-sizeof(BLOCKPTR)); + return blockptr; +} + +//=========================================================================== +static inline HSHEAP GetHandleByBlockPtr (BLOCKPTR blockptr) { + HEAPPTR heapptr = (HEAPPTR)((DWORD)(blockptr->heapaddr) << 16); + return heapptr->handle; +} + +//=========================================================================== +static inline HSHEAP GetHandleByCaller (LPCSTR filename, + int linenumber) { + static BOOL cacheenabled = TRUE; + static DWORD lastchars = 0; + static int lastline = 0; + static LPCSTR lastptr = NULL; + static HSHEAP lasthandle = (HSHEAP)0; + + // IF CACHING IS ENABLED AND THIS CALLER MATCHES THE PREVIOUS ONE, + // RETURN THE PREVIOUSLY COMPUTED HANDLE + DWORD filenamechars = *(LPDWORD)filename; + if (cacheenabled && + (filename == lastptr) && + (linenumber == lastline)) { + + // VERIFY THAT THE CALLER IS NOT JUST CHANGING FILENAMES WITHIN A + // STATIC BUFFER BY CHECKING THE FIRST FOUR CHARACTERS. IF THEY + // ARE DIFFERENT FROM WHAT WE EXPECT, DISABLE CACHING. + if (filenamechars != lastchars) + cacheenabled = FALSE; + else + return lasthandle; + + } + + // OTHERWISE, COMPUTE THE HANDLE FOR THIS CALLER + DWORD hashval = SStrHash(filename, + TRUE, + (DWORD)linenumber); + HSHEAP handle = (HSHEAP)(hashval & (FIRSTUSERHEAP-1)); + if (!handle) + handle = (HSHEAP)1; + + // SAVE IT IN THE CACHE + lastchars = filenamechars; + lastptr = filename; + lastline = linenumber; + lasthandle = handle; + + return handle; +} + +//=========================================================================== +static inline LPVOID GetPtrByBlockPtr (BLOCKPTR blockptr) { + if (!blockptr) + return NULL; + LPVOID ptr = blockptr+1; + if (blockptr->flags & BF_LARGEALLOC) + ptr = *(LPVOID *)ptr; + return ptr; +} + +//=========================================================================== +static inline DWORD GetSlotByHandle (HSHEAP handle) { + return (DWORD)handle & (TABLESIZE-1); +} + +//=========================================================================== +static inline HEAPPTR LockHeapByBlockPtr (BLOCKPTR blockptr, + HLOCKEDHEAP *lockedhandle) { + + // CONVERT THE COMPACT FORM OF THE HEAP ADDRESS TO A FULL ADDRESS + HEAPPTR heapptr = (HEAPPTR)((DWORD)(blockptr->heapaddr) << 16); + + // LOCK THE HEAP'S CRITICAL SECTION + EnterCriticalSection(&s_critsect[heapptr->slot]); + *lockedhandle = (HLOCKEDHEAP)heapptr->slot; + + return heapptr; +} + +//=========================================================================== +static inline HEAPPTR LockHeapByHandle (HSHEAP handle, + HLOCKEDHEAP *lockedhandle, + BOOL heapmustexist) { + + // LOCK THE HEAP'S CRITICAL SECTION + DWORD slot = GetSlotByHandle(handle); + EnterCriticalSection(&s_critsect[slot]); + *lockedhandle = (HLOCKEDHEAP)slot; + + // FIND AND RETURN THE HEAP HEADER + HEAPPTR heapptr = s_heaphead[slot]; + while (heapptr) + if (heapptr->handle == handle) + return heapptr; + else + heapptr = heapptr->next; + + // IF WE DIDN'T FIND THE HEAP AND THE CALLER REQUIRES THAT THE HEAP + // EXIST, UNLOCK THE CRITICAL SECTION + if (heapmustexist) { + LeaveCriticalSection(&s_critsect[slot]); + *lockedhandle = (HLOCKEDHEAP)INVALID_HANDLE_VALUE; + } + + return NULL; +} + +//=========================================================================== +static void Warning (DWORD errorcode, + LPCSTR filename, + int linenumber) { + SErrSetLastError(errorcode); + if (s_debugmode) + SErrDisplayError(errorcode, + filename, + linenumber, + NULL, + TRUE); +} + +//=========================================================================== +static inline void UnlockHeap (HLOCKEDHEAP lockedhandle) { + DWORD slot = (DWORD)lockedhandle; + LeaveCriticalSection(&s_critsect[slot]); +} + +/**************************************************************************** +* +* BLOCK ALLOCATION/DEALLOCATION FUNCTIONS +* +***/ + +static void CombineFreeBlocks (HEAPPTR heapptr); +static void ComputePageSize (); +static void FreeHeap (HEAPPTR *nextptr); +static BOOL FreeHeapBlock (HEAPPTR heapptr, + BLOCKPTR block); + +//=========================================================================== +static HEAPPTR AllocateHeap (LPCSTR filename, + int linenumber, + HSHEAP handle, + DWORD slot, + DWORD chunksize, + DWORD commitsize, + DWORD reservesize) { + + // RESERVE MEMORY FOR THE NEW HEAP + HEAPPTR newheap = (HEAPPTR)VirtualAlloc(NULL, + reservesize, + MEM_RESERVE, + PAGE_NOACCESS); + + if (!newheap) + FatalError(ERROR_NOT_ENOUGH_MEMORY, + filename, + linenumber); + if (!VirtualAlloc(newheap, + commitsize, + MEM_COMMIT, + PAGE_READWRITE)) + FatalError(ERROR_NOT_ENOUGH_MEMORY, + filename, + linenumber); + + // DETERMINE THE SIZE OF THE NEW HEAP HEADER + DWORD filenamebytes = (filename ? SStrLen(filename) : 0)+1; + DWORD headerbytes = sizeof(HEAP)+filenamebytes-1; + if (headerbytes & 3) + headerbytes += 4-(headerbytes & 3); + + // FILL IN THE NEW HEAP HEADER + newheap->handle = handle; + newheap->next = s_heaphead[slot]; + newheap->slot = slot; + newheap->active = TRUE; + newheap->firstblock = (BLOCKPTR)((LPBYTE)newheap+headerbytes); + newheap->termblock = (BLOCKPTR)((LPBYTE)newheap+headerbytes); + newheap->firstfreeblock = NULL; + newheap->maintainfreelist = MAXFREEMAINT; + newheap->chunksize = chunksize; + newheap->committedbytes = commitsize; + newheap->reservedbytes = reservesize; + newheap->linenumber = linenumber; + + // FILL IN THE HEAP'S FILENAME + if (filename) + CopyMemory(newheap->filename,filename,filenamebytes); + else + newheap->filename[0] = 0; + + // FILL IN THE HEAP'S ADDRESS AND SIGNATURE OPTIMIZED DWORD + { + BLOCK block; + block.heapaddr = (WORD)((DWORD)newheap >> 16); + block.signature1 = SIGNATURE1; + FASTBLOCKPTR fastblockptr = (FASTBLOCKPTR)█ + newheap->addrsig = fastblockptr->addrsig; + } + + // ADD THE HEAP TO THE LIST OF HEAPS + s_heaphead[slot] = newheap; + + return newheap; +} + +//=========================================================================== +static LPVOID AllocateHeapBlock (HEAPPTR heapptr, + DWORD bytes, + BYTE baseflags) { + + // DETERMINE THE BLOCK SIZE REQUIRED TO SATISFY THIS ALLOCATION REQUEST + BOOL largealloc = s_guardmode || (bytes > MAXALLOCSIZE); + BOOL boundingsig = s_debugmode && !largealloc; + DWORD reqblocksize; + { + DWORD userbytes = largealloc ? sizeof(LPVOID) : bytes; + DWORD overhead = sizeof(BLOCK)+(boundingsig ? sizeof(WORD) : 0); + reqblocksize = userbytes+overhead; + } + DWORD blocksize = reqblocksize; + if (blocksize & 7) + blocksize += 8-(blocksize & 7); + + // REBUILD THIS HEAP'S FREE LIST IF NECESSARY + if (heapptr->firstfreeblock && + !heapptr->maintainfreelist) + CombineFreeBlocks(heapptr); + heapptr->maintainfreelist = MAXFREEMAINT; + + // SEARCH THIS HEAP FOR THE CLOSEST MATCHING FREE BLOCK WHICH IS + // LARGE ENOUGH TO SATISFY THE REQUEST + DWORD bestdelta = LONG_MAX; + FREEBLOCKPTR *bestfreeblock = NULL; + { + FREEBLOCKPTR *nextfreeblock = &heapptr->firstfreeblock; + while (*nextfreeblock) { + DWORD delta = (*nextfreeblock)->bytes-blocksize; + if (delta < bestdelta) { + bestdelta = delta; + bestfreeblock = nextfreeblock; + if (delta < MINBLOCKSIZE) + break; + } + nextfreeblock = &(*nextfreeblock)->next; + } + } + + // IF WE FOUND A FREE BLOCK THAT CAN SATISFY THE REQUEST, SUBDIVIDE IT + // AS NECESSARY AND USE IT + BLOCKPTR newblock; + if (bestfreeblock) { + newblock = (BLOCKPTR)*bestfreeblock; + if (bestdelta >= MINBLOCKSIZE) { + FREEBLOCKPTR newfreeblock = (FREEBLOCKPTR)((LPBYTE)newblock+blocksize); + newfreeblock->bytes = (WORD)bestdelta; + newfreeblock->padding = 0; + newfreeblock->flags = BF_FREEBLOCK; + newfreeblock->next = (*bestfreeblock)->next; + newblock->bytes = (WORD)blocksize; + *bestfreeblock = newfreeblock; + } + else + *bestfreeblock = (*bestfreeblock)->next; + } + + // OTHERWISE, ALLOCATE A NEW BLOCK ON THE END OF THE HEAP + else { + DWORD newheapsize = ((LPBYTE)heapptr->termblock-(LPBYTE)heapptr)+blocksize; + + // IF THIS NEW BLOCK WON'T FIT IN THE SPACE WE HAVE RESERVED FOR THIS + // HEAP, CREATE A NEW HEAP AND SET IT AS THE ACTIVE HEAP + if (newheapsize > heapptr->reservedbytes) { + DWORD newreservesize = (heapptr->reservedbytes < 0x10000000) + ? heapptr->reservedbytes*2 + : heapptr->reservedbytes; + DWORD newchunksize = newreservesize >> 3; + HEAPPTR newheapptr = AllocateHeap(heapptr->filename, + heapptr->linenumber, + heapptr->handle, + heapptr->slot, + newchunksize, + newchunksize, + newreservesize); + if (!newheapptr) + return NULL; + heapptr->active = FALSE; + heapptr = newheapptr; + newheapsize = ((LPBYTE)heapptr->termblock-(LPBYTE)heapptr)+blocksize; + } + + // IF WE HAVEN'T YET COMMITTED THE MEMORY THAT WILL BE NEEDED FOR THIS + // NEW BLOCK, DO SO NOW + if (newheapsize > heapptr->committedbytes) { + DWORD commitsize = newheapsize-heapptr->committedbytes; + if (commitsize & (heapptr->chunksize-1)) + commitsize += heapptr->chunksize-(commitsize & (heapptr->chunksize-1)); + if (heapptr->committedbytes+commitsize > heapptr->reservedbytes) + commitsize = heapptr->reservedbytes-heapptr->committedbytes; + VirtualAlloc((LPBYTE)heapptr+heapptr->committedbytes, + commitsize, + MEM_COMMIT, + PAGE_READWRITE); + heapptr->committedbytes += commitsize; + } + + // DETERMINE THE LOCATION AND SIZE OF THE NEW BLOCK + newblock = heapptr->termblock; + newblock->bytes = (WORD)blocksize; + + // CREATE A NEW TERMINATOR BLOCK + heapptr->termblock = (BLOCKPTR)((LPBYTE)newblock+blocksize); + + } + + // FILL IN THE NEW BLOCK'S HEADER + newblock->padding = (BYTE)(newblock->bytes-reqblocksize); + newblock->flags = baseflags | (largealloc ? BF_LARGEALLOC : 0); + ((FASTBLOCKPTR)newblock)->addrsig = heapptr->addrsig; + ++heapptr->allocatedblocks; + + // IF REQUESTED, ADD A SECOND SIGNATURE TO BOUND THE BLOCK + if (boundingsig) { + newblock->flags |= BF_BOUNDINGSIG; + *(LPWORD)((LPBYTE)newblock+reqblocksize-sizeof(WORD)) = SIGNATURE2; + } + + // IF THIS IS A LARGE ALLOCATION, THEN ALLOCATE A BLOCK OF USER MEMORY + // OUTSIDE THE HEAP, AND MAKE THE BLOCK INSIDE THE HEAP POINT TO THE + // EXTERNAL BLOCK. SAVE A POINTER TO THE USER PORTION OF THE EXTERNAL + // BLOCK. + LPVOID result; + if (largealloc) { + if (!s_pagesize) + ComputePageSize(); + DWORD largeallocbytes = sizeof(BLOCKPTR)+sizeof(BLOCK)+bytes; + DWORD largeallocoffset = 0; + + // IF WE ARE IN DEBUG MODE, ALIGN THE ALLOCATION AT THE END OF A PAGE, + // SO THAT IF THE APPLICATION OVERWRITES THE ALLOCATION IT WILL TRIGGER + // AN EXCEPTION. (HOWEVER, KEEP THE ALLOCATION ALIGNED ON A DWORD + // BOUNDARY.) + LPBYTE largeallocptr = NULL; + if (s_debugmode || s_guardmode) { + largeallocoffset = s_pagesize-(largeallocbytes & (s_pagesize-1)); + if (s_guardmode) + largeallocoffset &= (s_pagesize-1); + else + largeallocoffset &= (s_pagesize-4); + if (s_guardmode) + largeallocptr = (LPBYTE)VirtualAlloc(NULL, + largeallocbytes+largeallocoffset+4, + MEM_RESERVE, + PAGE_NOACCESS); + } + + largeallocptr = (LPBYTE)VirtualAlloc(largeallocptr, + largeallocbytes+largeallocoffset, + MEM_COMMIT, + PAGE_READWRITE); + if (!largeallocptr) { + FreeHeapBlock(heapptr,newblock); + return NULL; + } + largeallocptr = (LPBYTE)largeallocptr+largeallocoffset; + *(BLOCKPTR *)largeallocptr = newblock; + BLOCKPTR largeallocblock = (BLOCKPTR)((LPBYTE)largeallocptr+sizeof(BLOCKPTR)); + largeallocblock->bytes = (WORD)((bytes+0xFFFF) >> 16); + largeallocblock->padding = 0; + largeallocblock->flags = BF_LARGEALLOC | BF_OUTSIDEHEAP; + ((FASTBLOCKPTR)largeallocblock)->addrsig = heapptr->addrsig; + result = largeallocblock+1; + *(LPVOID *)(newblock+1) = result; + } + + // OTHERWISE, SAVE A POINTER TO THE USER PORTION OF THE HEAP BLOCK + else + result = newblock+1; + + return result; +} + +//=========================================================================== +static BOOL CheckValidBlock (LPVOID ptr, + BOOL displayerror, + LPCSTR filename, + int linenumber) { + + // VERIFY THAT THIS ISN'T A NULL POINTER + if (!ptr) { + if (displayerror) + Warning(STORM_ERROR_MEMORY_NULL_POINTER, + filename, + linenumber); + return FALSE; + } + + // VERIFY THAT THIS IS A VALID HEAP BLOCK + BLOCKPTR block = (BLOCKPTR)ptr-1; + if (block->signature1 != SIGNATURE1) { + if (displayerror) + Warning(STORM_ERROR_MEMORY_INVALID_BLOCK, + filename, + linenumber); + return FALSE; + } + + // VERIFY THAT THIS BLOCK IS ALLOCATED + if (block->flags & BF_FREEBLOCK) { + if (displayerror) + Warning(STORM_ERROR_MEMORY_ALREADY_FREED, + filename, + linenumber); + return FALSE; + } + + // IF THIS BLOCK HAS A BOUNDING SIGNATURE, VERIFY THAT IT IS INTACT + if ((block->flags & BF_BOUNDINGSIG) && + (*(LPWORD)((LPBYTE)block+block->bytes-block->padding-sizeof(WORD)) != SIGNATURE2) && + displayerror) + Warning(STORM_ERROR_MEMORY_CORRUPT, + filename, + linenumber); + + return TRUE; +} + +//=========================================================================== +static void CombineFreeBlocks (HEAPPTR heapptr) { + + // RESET THE LIST OF FREE BLOCKS + FREEBLOCKPTR prevfreeblock = NULL; + FREEBLOCKPTR *nextfreeblock = &heapptr->firstfreeblock; + + // SEARCH THE ENTIRE HEAP FOR FREE BLOCKS + for (BLOCKPTR blockptr = heapptr->firstblock; + blockptr != heapptr->termblock; + blockptr = (BLOCKPTR)((LPBYTE)blockptr+blockptr->bytes)) + if (blockptr->flags & BF_FREEBLOCK) { + FREEBLOCKPTR freeblockptr = (FREEBLOCKPTR)blockptr; + freeblockptr->next = NULL; + + // IF THIS FREE BLOCK IS ADJACENT TO THE PREVIOUS ONE, COMBINE THEM + if (prevfreeblock && + (freeblockptr == (FREEBLOCKPTR)((LPBYTE)prevfreeblock+prevfreeblock->bytes)) && + ((DWORD)freeblockptr->bytes+(DWORD)prevfreeblock->bytes <= 0xFFFF)) + prevfreeblock->bytes += freeblockptr->bytes; + + // OTHERWISE, ADD THIS FREE BLOCK TO THE LIST + else { + *nextfreeblock = freeblockptr; + nextfreeblock = &freeblockptr->next; + prevfreeblock = freeblockptr; + } + + } + + // TERMINATE THE LIST OF FREE BLOCKS + *nextfreeblock = NULL; + +} + +//=========================================================================== +static void ComputePageSize () { + + // GET THE SYSTEM'S PAGE SIZE + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + + // FORCE THE PAGE SIZE TO BE A POWER OF TWO (JUST IN CASE IT ISN'T ALREADY) + s_pagesize = 1; + while (s_pagesize < sysinfo.dwPageSize) + s_pagesize <<= 1; + +} + +//=========================================================================== +static HEAPPTR * DestroyHeap (HEAPPTR *nextptr) { + BOOL preserve = FALSE; + + // IF THERE ARE ANY ALLOCATED BLOCKS IN THIS HEAP WHICH AREN'T MARKED + // PRESERVE-ON-DESTROY, DISPLAY A WARNING AND DELETE THEM + BLOCKPTR blockptr = (*nextptr)->firstblock; + while (blockptr != (*nextptr)->termblock) + if (blockptr->flags & (BF_FREEBLOCK | BF_PRESERVE)) { + preserve |= (blockptr->flags & BF_PRESERVE); + blockptr = (BLOCKPTR)((LPBYTE)blockptr+blockptr->bytes); + } + else { + Warning(STORM_ERROR_MEMORY_NEVER_RELEASED, + (*nextptr)->filename, + (*nextptr)->linenumber); + FreeHeapBlock(*nextptr,blockptr); + blockptr = (*nextptr)->firstblock; + } + + // IF THERE WERE NO PRESERVE-ON-DESTROY BLOCKS, FREE THE HEAP + if (!preserve) { + FreeHeap(nextptr); + return nextptr; + } + else + return &(*nextptr)->next; + +} + +//=========================================================================== +static void FreeEmptyHeaps () { + s_lastemptyheap = NULL; + for (DWORD slot = 0; slot < TABLESIZE; ++slot) + if (s_emptyheap[slot]) { + EnterCriticalSection(&s_critsect[slot]); + s_emptyheap[slot] = FALSE; + HEAPPTR *nextheap = &s_heaphead[slot]; + while (*nextheap) + if ((!(*nextheap)->allocatedblocks) && + ((DWORD)((*nextheap)->handle) < FIRSTUSERHEAP)) + FreeHeap(nextheap); + else + nextheap = &(*nextheap)->next; + LeaveCriticalSection(&s_critsect[slot]); + } +} + +//=========================================================================== +static void FreeHeap (HEAPPTR *nextptr) { + + // UNLINK THE HEAP + HEAPPTR heapptr = *nextptr; + *nextptr = heapptr->next; + + // FREE THE HEAP + VirtualFree(heapptr,0,MEM_RELEASE); + +} + +//=========================================================================== +static BOOL FreeHeapBlock (HEAPPTR heapptr, + BLOCKPTR block) { + + // MARK THE BLOCK AS FREE + FREEBLOCKPTR freeblock = (FREEBLOCKPTR)block; + freeblock->flags = BF_FREEBLOCK; + freeblock->padding = 0; + freeblock->next = NULL; + + // IF WE ARE MAINTAING A FULLY COMBINED AND SORTED FREE LIST, THE COMBINE + // THIS BLOCK WITH CONTIGUOUS FREE BLOCKS AND ADD FIND THE CORRECT LOCATION + // FOR IT IN THE FREE LIST. OTHERWISE, JUST DO MINIMAL PROCESSING FOR NOW, + // DELAYING THE COMBINING AND SORTING OPERATIONS UNTIL THE NEXT BLOCK + // ALLOCATION ON THIS HEAP. + FREEBLOCKPTR endblock = (FREEBLOCKPTR)((LPBYTE)freeblock+freeblock->bytes); + FREEBLOCKPTR *nextfreeblock = &heapptr->firstfreeblock; + FREEBLOCKPTR currfreeblock; + if (heapptr->maintainfreelist) { + --heapptr->maintainfreelist; + for (;;) { + currfreeblock = *nextfreeblock; + if ((!currfreeblock) || (currfreeblock > endblock)) + break; + BOOL unlink = FALSE; + if ((DWORD)freeblock->bytes+(DWORD)currfreeblock->bytes <= 0xFFFF) + if (currfreeblock == endblock) { + freeblock->bytes += currfreeblock->bytes; + endblock = (FREEBLOCKPTR)((LPBYTE)block+block->bytes); + unlink = TRUE; + } + else if (((FREEBLOCKPTR)((LPBYTE)currfreeblock+currfreeblock->bytes)) == freeblock) { + currfreeblock->bytes += freeblock->bytes; + freeblock = currfreeblock; + unlink = TRUE; + } + if (unlink) + *nextfreeblock = currfreeblock->next; + else + nextfreeblock = &currfreeblock->next; + } + } + + // IF THIS BLOCK IS AT THE END OF THE HEAP, SHRINK THE HEAP + if (heapptr->termblock == (BLOCKPTR)endblock) + heapptr->termblock = (BLOCKPTR)freeblock; + + // OTHERWISE, ADD THIS BLOCK TO THE LINKED LIST OF FREE BLOCKS + else { + freeblock->next = currfreeblock; + *nextfreeblock = freeblock; + } + + // IF THIS HEAP IS NOW EMPTY, SET OURSELVES A REMINDER TO REMOVE IT DURING + // THE NEXT CLEANUP + --heapptr->allocatedblocks; + if ((!heapptr->allocatedblocks) && + ((DWORD)(heapptr->handle) < FIRSTUSERHEAP)) { + s_emptyheap[heapptr->slot] = TRUE; + s_lastemptyheap = heapptr; + } + + return TRUE; +} + +//=========================================================================== +static inline LPVOID SatisfyAllocRequest (HLOCKEDHEAP lockedhandle, + HEAPPTR heapptr, + DWORD flags, + DWORD bytes) { + + // ALLOCATE THE REQUESTED BLOCK OF MEMORY FROM THE CALLER'S HEAP + LPVOID result = NULL; + if (heapptr) { + BYTE baseflags = 0; + if (flags & SMEM_FLAG_PRESERVEONDESTROY) + baseflags |= BF_PRESERVE; + result = AllocateHeapBlock(heapptr, + bytes, + baseflags); + } + + // IF THERE IS AN EMPTY HEAP WAITING TO BE CLEANED UP, AND WE DIDN'T + // JUST ALLOCATE A BLOCK IN IT, THEN PERFORM THE CLEANUP + if (s_lastemptyheap && (s_lastemptyheap != heapptr)) + FreeEmptyHeaps(); + + // UNLOCK THE HEAP + UnlockHeap(lockedhandle); + + // IF THE ALLOCATION FAILED, DISPLAY A FATAL ERROR + if (!result) + if (heapptr->filename[0]) + FatalError(ERROR_NOT_ENOUGH_MEMORY, + heapptr->filename, + heapptr->linenumber); + else + FatalError(ERROR_NOT_ENOUGH_MEMORY, + "SMemHeapAlloc()", + SERR_LINECODE_FUNCTION); + + // FILL THE NEW BLOCK WITH ITS REQUIRED STARTING VALUE + if (flags & SMEM_FLAG_ZEROMEMORY) + ZeroMemory(result,bytes); + else if (s_debugmode) + FillMemory(result,bytes,0xEE); + + return result; +} + +//=========================================================================== +static inline BOOL SatisfyFreeRequest (HLOCKEDHEAP lockedhandle, + HEAPPTR heapptr, + LPVOID ptr, + BLOCKPTR blockptr) { + + // IF THIS IS A LARGE BLOCK ALLOCATED OUTSIDE OF A HEAP, FREE IT + if (blockptr->flags & BF_LARGEALLOC) { + LPVOID largeallocptr = (LPBYTE)ptr-sizeof(BLOCK)-sizeof(BLOCKPTR); + largeallocptr = (LPVOID)((DWORD)largeallocptr & ~(s_pagesize-1)); + VirtualFree(largeallocptr,0,MEM_RELEASE); + } + + // IF DEBUG MODE IS ENABLED AND THIS IS NOT A LARGE BLOCK ALLOCATED + // OUTSIDE THE HEAP, WIPE OUT THE USER PORTION OF THE DATA + else if (s_debugmode) { + DWORD userbytes = blockptr->bytes + -blockptr->padding + -sizeof(BLOCK) + -((blockptr->flags & BF_BOUNDINGSIG) ? sizeof(WORD) : 0); + FillMemory(ptr,userbytes,0xDD); + } + + // FREE THIS BLOCK FROM THE HEAP + BOOL success = FALSE; + if (heapptr) + success = FreeHeapBlock(heapptr,blockptr); + + // UNLOCK THE HEAP + UnlockHeap(lockedhandle); + + return success; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +#define CHECKINITIALIZED(name,errortype,retval) \ + do \ + if (!CheckInitialized()) { \ + errortype(STORM_ERROR_MEMORY_MANAGER_INACTIVE, \ + name, \ + SERR_LINECODE_FUNCTION); \ + return retval; \ + } \ + while (0) + +//=========================================================================== +LPVOID APIENTRY SMemAlloc (DWORD bytes, + LPCSTR filename, + int linenumber, + DWORD flags) { + CHECKINITIALIZED("SMemAlloc()",FatalError,NULL); + + // DETERMINE THE HEAP THAT WILL BE USED FOR THIS ALLOCATION + HSHEAP handle = GetHandleByCaller(filename, + linenumber); + + // LOCK THE HEAP + HLOCKEDHEAP lockedhandle; + HEAPPTR heapptr = LockHeapByHandle(handle, + &lockedhandle, + FALSE); + + // IF THE HEAP DOES NOT EXIST, ALLOCATE ONE. THE SLOT CONTAINING + // THE HEAP IS STILL LOCKED AFTER THE CALL TO LOCKHEAPBYHANDLE(). + if (!heapptr) + heapptr = AllocateHeap(filename, + linenumber, + handle, + GetSlotByHandle(handle), + PAGESIZE, + PAGESIZE, + RESERVESIZE); + + // ALLOCATE MEMORY AND UNLOCK THE HEAP + LPVOID result = SatisfyAllocRequest(lockedhandle, + heapptr, + flags, + bytes); + + // TRACE THE ALLOCATION IF NECESSARY + TRACE(result,"SMemAlloc()",filename,linenumber); + + return result; + +} + +//=========================================================================== +BOOL APIENTRY SMemDestroy () { + if (!s_initialized) + return TRUE; + s_initialized = FALSE; + + // REMOVE ALL EMPTY HEAPS, AND ALL CRITICAL SECTIONS + for (DWORD loop = 0; loop < TABLESIZE; ++loop) { + EnterCriticalSection(&s_critsect[loop]); + s_emptyheap[loop] = FALSE; + HEAPPTR *nextheap = &s_heaphead[loop]; + while (*nextheap) + if ((*nextheap)->allocatedblocks) + nextheap = DestroyHeap(nextheap); + else { + if ((*nextheap)->active && + ((DWORD)((*nextheap)->handle) >= FIRSTUSERHEAP)) + REPORTRESOURCELEAK(HSHEAP); + FreeHeap(nextheap); + } + LeaveCriticalSection(&s_critsect[loop]); + DeleteCriticalSection(&s_critsect[loop]); + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SMemFindNextBlock (HSHEAP heap, + LPVOID prevblock, + LPVOID *nextblock, + LPSMEMBLOCKDETAILS details) { + CHECKINITIALIZED("SMemFindNextBlock()",Warning,FALSE); + + VALIDATEBEGIN; + VALIDATE(heap); + VALIDATE(nextblock); + VALIDATE(details); + VALIDATE(details->size == sizeof(SMEMBLOCKDETAILS)); + VALIDATEEND; + + // BLANK OUT THE BLOCK DETAILS STRUCTURE + ZeroMemory((LPBYTE)details+sizeof(DWORD), + details->size-sizeof(DWORD)); + + // CLAIM THE CRITICAL SECTION FOR THE SLOT THAT CONTAINS THIS HEAP + DWORD slot = GetSlotByHandle(heap); + EnterCriticalSection(&s_critsect[slot]); + + // GENERATE A POINTER TO THE BLOCK HEADER OF THE PREVIOUS BLOCK + BLOCKPTR prevblockptr = GetBlockPtrByPtr(prevblock); + + // SEARCH ALL REGIONS OF THIS HEAP FOR THE NEXT BLOCK. SEARCH REGIONS + // IN REVERSE ORDER SO THAT BLOCKS WHICH WERE ALLOCATED FIRST WILL TEND + // TO BE LISTED FIRST. + BLOCKPTR lastblockptr = NULL; + BLOCKPTR blockptr = NULL; + BOOL found = FALSE; + HEAPPTR heapptr = s_heaphead[slot]; + while (heapptr && heapptr->next) + heapptr = heapptr->next; + while (heapptr && !found) { + + // IF THIS REGION IS PART OF THE HEAP, SEARCH ALL OF ITS BLOCKS + if (heapptr->handle == heap) { + blockptr = heapptr->firstblock; + while (blockptr != heapptr->termblock) { + if (lastblockptr == prevblockptr) { + found = TRUE; + break; + } + lastblockptr = blockptr; + blockptr = (BLOCKPTR)((LPBYTE)blockptr+blockptr->bytes); + } + } + + // MOVE TO THE PREVIOUS REGION + if (heapptr == s_heaphead[slot]) + break; + HEAPPTR lastheapptr = heapptr; + heapptr = s_heaphead[slot]; + while (heapptr->next != lastheapptr) + heapptr = heapptr->next; + + } + + // IF WE DIDN'T FIND ONE, RETURN FALSE TO INDICATE THE ITERATION IS + // COMPLETE + if (!found) { + *nextblock = NULL; + LeaveCriticalSection(&s_critsect[slot]); + return FALSE; + } + + // FILL IN INFORMATION ABOUT THE BLOCK + LPVOID ptr = GetPtrByBlockPtr(blockptr); + *nextblock = ptr; + details->ptr = ptr; + details->allocated = !(blockptr->flags & BF_FREEBLOCK); + details->valid = CheckValidBlock(ptr, + FALSE, + NULL, + 0); + if (blockptr->flags & BF_LARGEALLOC) { + BLOCKPTR largeblockptr = (BLOCKPTR)ptr-1; + DWORD largeblockoverhead = sizeof(BLOCKPTR)+sizeof(BLOCK); + MEMORY_BASIC_INFORMATION info; + VirtualQuery((LPBYTE)ptr-largeblockoverhead, + &info, + sizeof(MEMORY_BASIC_INFORMATION)); + details->bytes = info.RegionSize-largeblockoverhead; + details->overhead = sizeof(BLOCK)+sizeof(LPVOID)+blockptr->padding + +largeblockoverhead; + } + else { + details->overhead = sizeof(BLOCK)+blockptr->padding; + details->bytes = blockptr->bytes-details->overhead; + } + + // LEAVE THE CRITICAL SECTION + LeaveCriticalSection(&s_critsect[slot]); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SMemFindNextHeap (HSHEAP prevheap, + HSHEAP *nextheap, + LPSMEMHEAPDETAILS details) { + CHECKINITIALIZED("SMemFindNextHeap()",Warning,FALSE); + + VALIDATEBEGIN; + VALIDATE(nextheap); + VALIDATE(details); + VALIDATE(details->size == sizeof(SMEMHEAPDETAILS)); + VALIDATEEND; + + // BLANK OUT THE HEAP DETAILS STRUCTURE + ZeroMemory((LPBYTE)details+sizeof(DWORD), + details->size-sizeof(DWORD)); + + // DETERMINE THE FIRST SLOT TO CHECK + DWORD slot = 0; + if (prevheap) + slot = GetSlotByHandle(prevheap); + + // FIND THE NEXT HEAP + HSHEAP lastheap = (HSHEAP)0; + HEAPPTR heapptr = NULL; + for (; slot < TABLESIZE; ++slot) { + EnterCriticalSection(&s_critsect[slot]); + heapptr = s_heaphead[slot]; + while (heapptr) { + if (heapptr->active) { + if (lastheap == prevheap) + break; + lastheap = heapptr->handle; + } + heapptr = heapptr->next; + } + if (heapptr) + break; + LeaveCriticalSection(&s_critsect[slot]); + } + + // IF WE DIDN'T FIND ONE, RETURN FALSE TO INDICATE THE ITERATION IS + // COMPLETE + if (!heapptr) { + *nextheap = NULL; + return FALSE; + } + + // FILL IN INFORMATION ABOUT THE HEAP + *nextheap = heapptr->handle; + details->handle = heapptr->handle; + details->linenumber = heapptr->linenumber; + details->maximumsize = MAXHEAPSIZE; // note: change this + SStrCopy(details->filename,heapptr->filename,MAX_PATH); + + // SUM THE ALLOCATION STATISTICS FOR EACH REGION THAT MAKES UP THE HEAP + while (heapptr) { + CombineFreeBlocks(heapptr); + if (heapptr->handle == *nextheap) { + details->committedbytes += heapptr->committedbytes; + details->reservedbytes += heapptr->reservedbytes; + details->allocatedblocks += heapptr->allocatedblocks; + } + heapptr = heapptr->next; + } + + // LEAVE THE CRITICAL SECTION + LeaveCriticalSection(&s_critsect[slot]); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SMemFree (LPVOID ptr, + LPCSTR filename, + int linenumber, + DWORD flags) { + CHECKINITIALIZED("SMemFree()",Warning,FALSE); + + // TRACE THE DEALLOCATION IF NECESSARY + TRACE(ptr,"SMemFree()",filename,linenumber); + + // VERIFY THAT THIS BLOCK IS VALID AND ALLOCATED + if (!CheckValidBlock(ptr, + TRUE, + filename, + linenumber)) + return FALSE; + + // LOCK THE HEAP WHICH CONTAINS THE BLOCK + BLOCKPTR blockptr = GetBlockPtrByPtr(ptr); + HLOCKEDHEAP lockedhandle; + HEAPPTR heapptr = LockHeapByBlockPtr(blockptr,&lockedhandle); + + // FREE THIS MEMORY BLOCK AND UNLOCK THE HEAP + return SatisfyFreeRequest(lockedhandle, + heapptr, + ptr, + blockptr); +} + +//=========================================================================== +HSHEAP APIENTRY SMemGetHeapByCaller (LPCSTR filename, + int linenumber) { + CHECKINITIALIZED("SMemGetHeapByCaller()",Warning,(HSHEAP)0); + + return GetHandleByCaller(filename,linenumber); +} + +//=========================================================================== +HSHEAP APIENTRY SMemGetHeapByPtr (LPVOID ptr) { + CHECKINITIALIZED("SMemGetHeapByPtr()",Warning,(HSHEAP)0); + + BLOCKPTR blockptr = GetBlockPtrByPtr(ptr); + if (CheckValidBlock(blockptr, + FALSE, + NULL, + 0)) + return GetHandleByBlockPtr(blockptr); + else + return (HSHEAP)0; +} + +//=========================================================================== +LPVOID APIENTRY SMemHeapAlloc (HSHEAP handle, + DWORD flags, + DWORD bytes) { + CHECKINITIALIZED("SMemHeapAlloc()",FatalError,NULL); + + // LOCK THE HEAP + HLOCKEDHEAP lockedhandle; + HEAPPTR heapptr = LockHeapByHandle(handle, + &lockedhandle, + TRUE); + if (!heapptr) + FatalError(ERROR_INVALID_HANDLE, + "SMemHeapAlloc()", + SERR_LINECODE_FUNCTION); + + // ALLOCATE MEMORY AND UNLOCK THE HEAP + LPVOID result = SatisfyAllocRequest(lockedhandle, + heapptr, + flags, + bytes); + + // TRACE THE ALLOCATION IF NECESSARY + TRACE(result,"SMemHeapAlloc()",NULL,0); + + return result; +} + +//=========================================================================== +HSHEAP APIENTRY SMemHeapCreate (DWORD options, + DWORD initialsize, + DWORD maximumsize) { + CHECKINITIALIZED("SMemHeapCreate()",Warning,(HSHEAP)0); + + // VERIFY THAT THE RESERVED OPTIONS PARAMETER IS NOT BEING USED + if (options) { + Warning(ERROR_INVALID_PARAMETER, + "SMemHeapCreate()", + SERR_LINECODE_FUNCTION); + return FALSE; + } + + // ROUND THE REQUESTED INITIAL SIZE UP TO THE NEXT PAGE BOUNDARY + if (initialsize & (PAGESIZE-1)) + initialsize += PAGESIZE-(initialsize & (PAGESIZE-1)); + initialsize = max(initialsize,PAGESIZE); + maximumsize = max(maximumsize,initialsize); + + // FIND AN UNUSED HANDLE FOR THIS HEAP + static HSHEAP handle = (HSHEAP)FIRSTUSERHEAP; + for (;;) { + + // INCREMENT THE HANDLE SEQUENCE + handle = (HSHEAP)((DWORD)handle+1); + if (!handle) + handle = (HSHEAP)FIRSTUSERHEAP; + + // CHECK TO SEE IF THIS HANDLE IS IN USE + HLOCKEDHEAP lockedhandle = (HLOCKEDHEAP)INVALID_HANDLE_VALUE; + if (LockHeapByHandle(handle, + &lockedhandle, + TRUE)) + UnlockHeap(lockedhandle); + else + break; + + } + + // ALLOCATE THE HEAP + DWORD slot = GetSlotByHandle(handle); + EnterCriticalSection(&s_critsect[slot]); + AllocateHeap(NULL, + 0, + handle, + slot, + PAGESIZE, + initialsize, + RESERVESIZE); + LeaveCriticalSection(&s_critsect[slot]); + if (!handle) + Warning(ERROR_NOT_ENOUGH_MEMORY, + "SMemHeapCreate()", + SERR_LINECODE_FUNCTION); + + // RETURN THE HEAP HANDLE + return handle; +} + +//=========================================================================== +BOOL APIENTRY SMemHeapDestroy (HSHEAP handle) { + CHECKINITIALIZED("SMemHeapDestroy()",Warning,FALSE); + + // LOCK THE HEAP'S CRITICAL SECTION + DWORD slot = GetSlotByHandle(handle); + EnterCriticalSection(&s_critsect[slot]); + + // DESTROY ALL REGIONS OF THE HEAP + BOOL found = FALSE; + HEAPPTR *nextptr = &s_heaphead[slot]; + while (*nextptr) + if ((*nextptr)->handle == handle) { + found = TRUE; + nextptr = DestroyHeap(nextptr); + } + else + nextptr = &(*nextptr)->next; + + // UNLOCK THE CRITICAL SECTION + LeaveCriticalSection(&s_critsect[slot]); + + return found; +} + +//=========================================================================== +BOOL APIENTRY SMemHeapFree (HSHEAP handle, + DWORD flags, + LPVOID ptr) { + CHECKINITIALIZED("SMemHeapFree()",Warning,FALSE); + + // TRACE THE DEALLOCATION IF NECESSARY + TRACE(ptr,"SMemHeapFree()",NULL,0); + + // VERIFY THAT THIS BLOCK IS VALID AND ALLOCATED + if (!CheckValidBlock(ptr, + TRUE, + NULL, + 0)) + return FALSE; + + // VERIFY THAT THE HEAP HANDLE IS CORRECT + BLOCKPTR blockptr = GetBlockPtrByPtr(ptr); + if (GetHandleByBlockPtr(blockptr) != handle) + return FALSE; + + // LOCK THE HEAP WHICH CONTAINS THE BLOCK + HLOCKEDHEAP lockedhandle; + HEAPPTR heapptr = LockHeapByBlockPtr(blockptr,&lockedhandle); + + // FREE THIS MEMORY BLOCK AND UNLOCK THE HEAP + return SatisfyFreeRequest(lockedhandle, + heapptr, + ptr, + blockptr); +} + +//=========================================================================== +void APIENTRY SMemInitialize () { + if (s_initialized) + return; + + // DETERMINE WHETHER TO PERFORM HEAP CHECKS +#ifdef _DEBUG + s_debugmode = TRUE; +#endif + SRegLoadValue(REGKEY,REGVAL_DEBUG,0,(LPDWORD)&s_debugmode); + SRegLoadValue(REGKEY,REGVAL_GUARD,0,(LPDWORD)&s_guardmode); +#ifdef _DEBUG + SRegSaveValue(REGKEY,REGVAL_DEBUG,0,(DWORD)s_debugmode); + SRegSaveValue(REGKEY,REGVAL_GUARD,0,(DWORD)s_guardmode); + s_debugmode = TRUE; +#endif + + // INITIALIZE CRITICAL SECTIONS + for (DWORD loop = 0; loop < TABLESIZE; ++loop) + InitializeCriticalSection(&s_critsect[loop]); + + s_initialized = TRUE; +} diff --git a/Storm/SOURCE/SMSG.CPP b/Storm/SOURCE/SMSG.CPP new file mode 100644 index 0000000..613c98a --- /dev/null +++ b/Storm/SOURCE/SMSG.CPP @@ -0,0 +1,247 @@ +/**************************************************************************** +* +* SMSG.CPP +* Storm message processing and dispatching functions +* +* By Michael O'Brien (3/5/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define REGISTERTYPE_BASE 'SMSG' +#define REGISTERTYPE_MESSAGE (REGISTERTYPE_BASE+0) +#define REGISTERTYPE_COMMAND (REGISTERTYPE_BASE+1) +#define REGISTERTYPE_KEYDOWN (REGISTERTYPE_BASE+2) +#define REGISTERTYPE_KEYUP (REGISTERTYPE_BASE+3) + +NODEDECL(WNDREC) { + HWND window; +} *WNDPTR; + +static LIST(WNDREC) s_wndlist; + +//=========================================================================== +static void AddWindow (HWND window) { + s_wndlist.NewNode()->window = window; +} + +//=========================================================================== +static WNDPTR FindWindow (HWND window) { + ITERATELIST(WNDREC,s_wndlist,curr) + if (curr->window == window) + return curr; + return NULL; +} + +//=========================================================================== +static void DeleteWindow (HWND window) { + WNDPTR ptr = FindWindow(window); + if (ptr) { + SEvtUnregisterType(REGISTERTYPE_MESSAGE,(DWORD)window); + SEvtUnregisterType(REGISTERTYPE_COMMAND,(DWORD)window); + SEvtUnregisterType(REGISTERTYPE_KEYUP ,(DWORD)window); + SEvtUnregisterType(REGISTERTYPE_KEYDOWN,(DWORD)window); + s_wndlist.DeleteNode(ptr); + } +} + +//=========================================================================== +static BOOL InternalRegister (DWORD type, + HWND window, + DWORD id, + SMSGHANDLER handler) { + VALIDATEBEGIN; + VALIDATE(handler); + VALIDATEEND; + + // FIND THE WINDOW + if (!window) + SDrawGetFrameWindow(&window); + if (!FindWindow(window)) + AddWindow(window); + + // REGISTER THE MESSAGE + return SEvtRegisterHandler(type,(DWORD)window,id,0,(SEVTHANDLER)handler); +} + +//=========================================================================== +static BOOL InternalUnregister (DWORD type, + HWND window, + DWORD id, + SMSGHANDLER handler) { + VALIDATEBEGIN; + VALIDATE(handler); + VALIDATEEND; + + // FIND THE WINDOW + if (!window) + SDrawGetFrameWindow(&window); + if (!FindWindow(window)) + AddWindow(window); + + // UNREGISTER THE MESSAGE + return SEvtUnregisterHandler(type,(DWORD)window,id,(SEVTHANDLER)handler); +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SMsgBreakHandlerChain (LPPARAMS params) { + return SEvtBreakHandlerChain(params); +} + +//=========================================================================== +BOOL APIENTRY SMsgDestroy () { + while (!s_wndlist.IsEmpty()) + DeleteWindow(s_wndlist.Head()->window); + return 1; +} + +//=========================================================================== +BOOL APIENTRY SMsgDispatchMessage (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam, + BOOL *useresult, + LRESULT *result) { + if (useresult) + *useresult = 0; + if (result) + *result = 0; + + // CREATE A PARAMETER RECORD TO PASS TO THE HANDLER FUNCTION + PARAMS params; + params.window = window; + params.message = message; + params.wparam = wparam; + params.lparam = lparam; + params.notifycode = (message == WM_COMMAND) ? HIWORD(wparam) : 0; + params.useresult = 0; + params.result = 0; + + // DISPATCH THE MESSAGE + SEvtDispatch(REGISTERTYPE_MESSAGE,(DWORD)window,message,¶ms); + if (message == WM_COMMAND) + SEvtDispatch(REGISTERTYPE_COMMAND,(DWORD)window,LOWORD(wparam),¶ms); + else if (message == WM_KEYDOWN) + SEvtDispatch(REGISTERTYPE_KEYDOWN,(DWORD)window,wparam,¶ms); + else if (message == WM_KEYUP) + SEvtDispatch(REGISTERTYPE_KEYUP,(DWORD)window,wparam,¶ms); + + // IF THIS MESSAGE IS WM_NCDESTROY, DEALLOCATE THIS WINDOW'S RECORD + if (message == WM_NCDESTROY) + DeleteWindow(window); + + // RETURN THE DISPATCHING RESULTS + if (useresult) + *useresult = params.useresult; + if (result) + *result = params.result; + + return 1; +} + +//=========================================================================== +BOOL APIENTRY SMsgDoMessageLoop (SMSGIDLEPROC idleproc, + BOOL cleanuponquit) { + DWORD count = 0; + MSG message; + for (;;) + if (PeekMessage(&message,(HWND)0,0,0,PM_NOREMOVE) || + !(idleproc && idleproc(count++))) { + count = 0; + if (!GetMessage(&message,(HWND)0,0,0)) + break; + TranslateMessage(&message); + DispatchMessage(&message); + } +#ifndef STATICLIB + if (cleanuponquit) + StormDestroy(); +#endif + return message.wParam; +} + +//=========================================================================== +BOOL APIENTRY SMsgPopRegisterState (HWND window) { + if (!window) + SDrawGetFrameWindow(&window); + SEvtPopState(REGISTERTYPE_COMMAND,(DWORD)window); + SEvtPopState(REGISTERTYPE_KEYDOWN,(DWORD)window); + SEvtPopState(REGISTERTYPE_KEYUP ,(DWORD)window); + SEvtPopState(REGISTERTYPE_MESSAGE,(DWORD)window); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SMsgPushRegisterState (HWND window) { + if (!window) + SDrawGetFrameWindow(&window); + SEvtPushState(REGISTERTYPE_COMMAND,(DWORD)window); + SEvtPushState(REGISTERTYPE_KEYDOWN,(DWORD)window); + SEvtPushState(REGISTERTYPE_KEYUP ,(DWORD)window); + SEvtPushState(REGISTERTYPE_MESSAGE,(DWORD)window); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SMsgRegisterCommand (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalRegister(REGISTERTYPE_COMMAND,window,id,handler); +} + +//=========================================================================== +BOOL APIENTRY SMsgRegisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalRegister(REGISTERTYPE_KEYDOWN,window,id,handler); +} + +//=========================================================================== +BOOL APIENTRY SMsgRegisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalRegister(REGISTERTYPE_KEYUP,window,id,handler); +} + +//=========================================================================== +BOOL APIENTRY SMsgRegisterMessage (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalRegister(REGISTERTYPE_MESSAGE,window,id,handler); +} + +//=========================================================================== +BOOL APIENTRY SMsgUnregisterCommand (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalUnregister(REGISTERTYPE_COMMAND,window,id,handler); +} + +//=========================================================================== +BOOL APIENTRY SMsgUnregisterKeyDown (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalUnregister(REGISTERTYPE_KEYDOWN,window,id,handler); +} + +//=========================================================================== +BOOL APIENTRY SMsgUnregisterKeyUp (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalUnregister(REGISTERTYPE_KEYUP,window,id,handler); +} + +//=========================================================================== +BOOL APIENTRY SMsgUnregisterMessage (HWND window, + UINT id, + SMSGHANDLER handler) { + return InternalUnregister(REGISTERTYPE_MESSAGE,window,id,handler); +} diff --git a/Storm/SOURCE/SNET.CPP b/Storm/SOURCE/SNET.CPP new file mode 100644 index 0000000..0a76695 --- /dev/null +++ b/Storm/SOURCE/SNET.CPP @@ -0,0 +1,5261 @@ +/**************************************************************************** +* +* SNET.CPP +* Storm networking functions +* +* By Michael O'Brien (4/19/96) +* +* SNet implements multiple independent communication streams between each +* player. It guarantees delivery of all messages, using different +* techniques depending on the message type. +* +***/ + +#include "pch.h" +#pragma hdrstop + +#ifdef _DEBUG +#define TRACING +#define UNSIGNEDSNPS +#endif + +#pragma warning(disable:4200) // don't warn about zero-sized arrays + +#define MF_ACK 0x01 +#define MF_RESENDREQUEST 0x02 +#define MF_FORWARDED 0x04 + +#define PF_JOINING 0x00000004 +#define PF_LEAVING 0x00000008 + +#define NOPLAYER 0xFF + +#define ESTIMATEDPACKETOVERHEAD 64 +#define DELETECONNTIME 50000 +#define MINSPISIZE (20*sizeof(DWORD)) +#define PINGFREQUENCY 20000 + +#define REGISTERTYPE 'SNET' +#define REGISTERSUBTYPE_SNETEVENT 1 +#define REGISTERSUBTYPE_SYSEVENT 2 + +#define SENDBUFSIZE 8192 + +#define SNET_NETWORKVERSION 1 + +#define SYS_UNUSED 0 +#define SYS_INITIALCONTACT 1 +#define SYS_CIRCUITCHECK 2 +#define SYS_CIRCUITCHECKRESPONSE 3 +#define SYS_PING 4 +#define SYS_PINGRESPONSE 5 +#define SYS_PLAYERINFO 6 +#define SYS_PLAYERJOIN 7 +#define SYS_PLAYERJOIN_ACCEPTSTART 8 +#define SYS_PLAYERJOIN_ACCEPTDONE 9 +#define SYS_PLAYERJOIN_REJECT 10 +#define SYS_PLAYERLEAVE 11 +#define SYS_DROPPLAYER 12 +#define SYS_NEWGAMEOWNER 13 +#define SYSMSGS 14 + +#define TYPE_SYSTEM 0 +#define TYPE_MESSAGE 1 +#define TYPE_TURN 2 +#define TYPES 3 + +typedef struct _CLIENTDATA { + DWORD bytes; + DWORD numplayers; + DWORD maxplayers; +} CLIENTDATA, *CLIENTDATAPTR; + +typedef struct _HEADER { + WORD checksum; // checksum must be first field + WORD bytes; // bytes including header + WORD sequence; + WORD acksequence; + BYTE type; + BYTE subtype; + BYTE playerid; + BYTE flags; +} HEADER, *HEADERPTR; + +typedef struct _PACKET { + HEADER header; + BYTE data[0]; +} PACKET, *PACKETPTR; + +NODEDECL(MESSAGE) { + SNETADDRPTR addr; + PACKETPTR data; + DWORD databytes; + BOOL local; + DWORD sendtime; + DWORD resendtime; +} *MESSAGEPTR; + +NODEDECL(CONNREC) { + char name[SNETSPI_MAXSTRINGLENGTH]; + char desc[SNETSPI_MAXSTRINGLENGTH]; + SNETADDR addr; + DWORD flags; + DWORD lastreceivetime; // last time any packet was received + DWORD lastrequesttime; // last time we requested a turn + DWORD lastpingtime; // last time we sent a ping + DWORD latency; + DWORD peaklatency; + LIST(MESSAGE) outgoingqueue[TYPES]; // already sent; waiting for ack + LIST(MESSAGE) incomingqueue[TYPES]; // waiting to be processed + LIST(MESSAGE) processing[TYPES]; // given to app; valid until next call + LIST(MESSAGE) oldturns; // old turns from this player + WORD outgoingsequence[TYPES]; // (in case we need to send them + WORD incomingsequence[TYPES]; // to another player) + WORD lastprocessedturn; // last turn ack from this player + WORD availablesequence[TYPES]; // highest available incoming sequence + WORD acksequence[TYPES]; // last message we acked + DWORD acktime[TYPES]; // time of unacked message processing + BOOL gameowner; + BOOL establishing; + DWORD exitcode; + WORD finalsequence; + BYTE playerid; +} *CONNPTR; + +typedef struct _PERFDATAREC { + DWORD value; + DWORD type; + LONG scale; + BOOL providerspecific; +} PERFDATAREC, *PERFDATAPTR; + +NODEDECL(PROVIDERINFO) { + char filename[MAX_PATH]; + DWORD index; + DWORD id; + char desc[SNETSPI_MAXSTRINGLENGTH]; + char req[SNETSPI_MAXSTRINGLENGTH]; + SNETCAPS caps; +} *PROVIDERINFOPTR; + +typedef struct _UIPARAMS { + SNETCAPSPTR mincaps; + SNETPROGRAMDATAPTR programdata; + SNETPLAYERDATAPTR playerdata; + SNETUIDATAPTR interfacedata; + SNETVERSIONDATAPTR versiondata; +} UIPARAMS, *UIPARAMSPTR; + +NODEDECL(USEREVENT) { + SNETEVENT event; +} *USEREVENTPTR; + +typedef struct _SYSEVENT { + SNETADDRPTR senderaddr; + LPVOID data; + DWORD databytes; + BYTE senderplayerid; + BYTE eventid; +} SYSEVENT, *SYSEVENTPTR; + +typedef struct _SYSEVENTDATA_DROPPLAYER { + DWORD playerid; + DWORD finalsequence; + DWORD exitcode; +} SYSEVENTDATA_DROPPLAYER, *SYSEVENTDATA_DROPPLAYERPTR; + +typedef struct _SYSEVENTDATA_PLAYERJOIN { + char namedescpass[3*SNETSPI_MAXSTRINGLENGTH]; +} SYSEVENTDATA_PLAYERJOIN, *SYSEVENTDATA_PLAYERJOINPTR; + +typedef struct _SYSEVENTDATA_PLAYERJOIN_ACCEPTSTART { + DWORD playerid; + DWORD playersallowed; + DWORD nextturn; + DWORD gamemode; + DWORD runningtime; + char namedescpass[3*SNETSPI_MAXSTRINGLENGTH]; +} SYSEVENTDATA_PLAYERJOIN_ACCEPTSTART, *SYSEVENTDATA_PLAYERJOIN_ACCEPTSTARTPTR; + +typedef struct _SYSEVENTDATA_PLAYERINFO { + DWORD bytes; + DWORD playerid; + BOOL gameowner; + DWORD flags; + DWORD startingturn; + SNETADDR addr; + char namedesc[SNETSPI_MAXSTRINGLENGTH*2]; +} SYSEVENTDATA_PLAYERINFO, *SYSEVENTDATA_PLAYERINFOPTR; + +typedef struct _SYSEVENTDATA_PLAYERLEAVE { + DWORD finalsequence; + DWORD exitcode; +} SYSEVENTDATA_PLAYERLEAVE, *SYSEVENTDATA_PLAYERLEAVEPTR; + +typedef void (CALLBACK *SYSEVENTPROC)(SYSEVENTPTR); + +static CCritSect s_api_critsect; +static DWORD s_api_playeroffset = 0; + +static CONNPTR inline ConnFindByAddr (SNETADDRPTR addr); +static CONNPTR inline ConnFindLocal (); +static void ConnSetCurrentMessage (CONNPTR conn, BYTE type, MESSAGEPTR message); +static void RecvProcessExternalMessages (); +static void RecvProcessIncomingPackets (); +static void SysQueueUserEvent (DWORD eventid, + DWORD playerid, + LPVOID data, + DWORD databytes); +static void UiGetProgramDescription (LPCSTR programname, + SNETVERSIONDATAPTR versionptr, + LPSTR buffer, + DWORD buffersize); + +/**************************************************************************** +* +* TRACE FUNCTIONS +* +***/ + +#ifdef TRACING + +static CSLog s_trace_log("Internal","SNet Trace File"); + +//=========================================================================== +static void TraceDumpAddr (HSLOG log, + LPCSTR addrname, + SNETADDRPTR addr, + BYTE playerid) { + char outstr[80]; + wsprintf(outstr," %s=",addrname); + for (unsigned loop = 0; loop < sizeof(SNETADDR); ++loop) + wsprintf(outstr+SStrLen(outstr),"%02x",(DWORD)*((LPBYTE)addr+loop)); + wsprintf(outstr+SStrLen(outstr)," (%x)",(DWORD)playerid); + SLogWrite(log,outstr); +} + +//=========================================================================== +static void TraceDumpDataBlocks (HSLOG log, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + if (programdata && (programdata->size >= sizeof(SNETPROGRAMDATA))) { + SLogWrite(log," programdata.size = %u" ,programdata->size); + SLogWrite(log," programdata.programname = \"%s\"",programdata->programname); + SLogWrite(log," programdata.programdescription = \"%s\"",programdata->programdescription); + SLogWrite(log," programdata.programid = 0x%08x",programdata->programid); + SLogWrite(log," programdata.versionid = 0x%08x",programdata->versionid); + SLogWrite(log," programdata.reserved1 = %u" ,programdata->reserved1); + SLogWrite(log," programdata.maxplayers = %u" ,programdata->maxplayers); + SLogWrite(log," programdata.initdata = 0x%08x",programdata->initdata); + SLogWrite(log," programdata.initdatabytes = %u" ,programdata->initdatabytes); + SLogWrite(log," programdata.reserved2 = 0x%08x",programdata->reserved2); + SLogWrite(log," programdata.optcategorybits = 0x%08x",programdata->optcategorybits); + } + if (playerdata && (playerdata->size >= sizeof(SNETPLAYERDATA))) { + SLogWrite(log," playerdata.size = %u" ,playerdata->size); + SLogWrite(log," playerdata.playername = \"%s\"",playerdata->playername); + SLogWrite(log," playerdata.playerdescription = \"%s\"",playerdata->playerdescription); + } + if (interfacedata && (interfacedata->size >= sizeof(SNETUIDATA))) { + SLogWrite(log," interfacedata.size = %u" ,interfacedata->size); + SLogWrite(log," interfacedata.uiflags = 0x%08x",interfacedata->uiflags); + SLogWrite(log," interfacedata.parentwindow = 0x%08x",interfacedata->parentwindow); + SLogWrite(log," interfacedata.artcallback = 0x%08x",interfacedata->artcallback); + SLogWrite(log," interfacedata.authcallback = 0x%08x",interfacedata->authcallback); + SLogWrite(log," interfacedata.createcallback = 0x%08x",interfacedata->createcallback); + SLogWrite(log," interfacedata.drawdesccallback = 0x%08x",interfacedata->drawdesccallback); + SLogWrite(log," interfacedata.selectedcallback = 0x%08x",interfacedata->selectedcallback); + SLogWrite(log," interfacedata.messageboxcallback = 0x%08x",interfacedata->messageboxcallback); + SLogWrite(log," interfacedata.soundcallback = 0x%08x",interfacedata->soundcallback); + SLogWrite(log," interfacedata.statuscallback = 0x%08x",interfacedata->statuscallback); + SLogWrite(log," interfacedata.getdatacallback = 0x%08x",interfacedata->getdatacallback); + SLogWrite(log," interfacedata.categorycallback = 0x%08x",interfacedata->categorycallback); + } + if (versiondata && (versiondata->size >= sizeof(SNETVERSIONDATA))) { + SLogWrite(log," versiondata.size = %u" ,versiondata->size); + SLogWrite(log," versiondata.versionstring = \"%s\"",versiondata->versionstring); + SLogWrite(log," versiondata.executablefile = \"%s\"",versiondata->executablefile); + SLogWrite(log," versiondata.originalarchivefile = \"%s\"",versiondata->originalarchivefile); + SLogWrite(log," versiondata.patcharchivefile = \"%s\"",versiondata->patcharchivefile); + } +} + +//=========================================================================== +static void TraceDumpMsg (HSLOG log, + DWORD playerid, + DWORD sequence, + LPVOID data, + DWORD databytes) { + + // DUMP THE PLAYER ID + if (playerid != 0xFFFFFFFF) + SLogWrite(log, + "(from player %u, sequence=%u)\n", + playerid+s_api_playeroffset,sequence); + else if (sequence != 0xFFFFFFFF) + SLogWrite(log, + "(sequence=%u)\n",sequence); + + // DUMP THE DATA + SLogDump(log,data,databytes); + +} + +#define TRACEDUMP SLogDump +#define TRACEDUMPADDR TraceDumpAddr +#define TRACEDUMPDATABLOCKS TraceDumpDataBlocks +#define TRACEDUMPMSG TraceDumpMsg +#define TRACEHANDLE s_trace_log.GetHandle() +#define TRACEOUT SLogWrite +#define TRACEPEND SLogPend + +#else + +#define TRACEDUMP +#define TRACEDUMPADDR +#define TRACEDUMPDATABLOCKS +#define TRACEDUMPMSG +#define TRACEHANDLE 0 +#define TRACEOUT +#define TRACEPEND + +#endif + +/**************************************************************************** +* +* PERFORMANCE FUNCTIONS +* +***/ + +static PERFDATAREC s_perf_data[SNET_PERFIDNUM] + = {{0,0 , 0,0}, // unused + {0,SNET_PERFTYPE_RAWCOUNT,-1,0}, // SNET_PERFID_TURN + {0,0 , 0,0}, // unused + {0,0 , 0,0}, // unused + {0,SNET_PERFTYPE_COUNTER ,-1,0}, // SNET_PERFID_TURNSSENT + {0,SNET_PERFTYPE_COUNTER ,-1,0}, // SNET_PERFID_TURNSRECV + {0,SNET_PERFTYPE_COUNTER ,-1,0}, // SNET_PERFID_MSGSENT + {0,SNET_PERFTYPE_COUNTER ,-1,0}, // SNET_PERFID_MSGRECV + {0,SNET_PERFTYPE_COUNTER ,-4,0}, // SNET_PERFID_USERBYTESSENT + {0,SNET_PERFTYPE_COUNTER ,-4,0}, // SNET_PERFID_USERBYTESRECV + {0,SNET_PERFTYPE_COUNTER ,-4,0}, // SNET_PERFID_TOTALBYTESSENT + {0,SNET_PERFTYPE_COUNTER ,-4,0}, // SNET_PERFID_TOTALBYTESRECV + {0,SNET_PERFTYPE_COUNTER ,-1,1}, // SNET_PERFID_PKTSENTONWIRE + {0,SNET_PERFTYPE_COUNTER ,-1,1}, // SNET_PERFID_PKTRECVONWIRE + {0,SNET_PERFTYPE_COUNTER ,-4,1}, // SNET_PERFID_BYTESSENTONWIRE + {0,SNET_PERFTYPE_COUNTER ,-4,1}}; // SNET_PERFID_BYTESRECVONWIRE + +//=========================================================================== +static void inline PerfAdd (DWORD id, DWORD value) { + VALIDATEBEGIN; + VALIDATE(id < SNET_PERFIDNUM); + VALIDATEENDVOID; + + s_perf_data[id].value += value; +} + +//=========================================================================== +static void inline PerfDecrement (DWORD id) { + VALIDATEBEGIN; + VALIDATE(id < SNET_PERFIDNUM); + VALIDATEENDVOID; + + InterlockedDecrement((LONG *)&s_perf_data[id].value); +} + +//=========================================================================== +static void inline PerfIncrement (DWORD id) { + VALIDATEBEGIN; + VALIDATE(id < SNET_PERFIDNUM); + VALIDATEENDVOID; + + InterlockedIncrement((LONG *)&s_perf_data[id].value); +} + +//=========================================================================== +static void inline PerfSet (DWORD id, DWORD value) { + VALIDATEBEGIN; + VALIDATE(id < SNET_PERFIDNUM); + VALIDATEENDVOID; + + s_perf_data[id].value = value; +} + +/**************************************************************************** +* +* SERVICE PROVIDER MANAGEMENT FUNCTIONS +* +***/ + +static SNETSPIPTR s_spi = NULL; +static HINSTANCE s_spi_lib = (HINSTANCE)0; +static DWORD s_spi_outgoingtime = 0; +static LIST(PROVIDERINFO) s_spi_providerlist; +static PROVIDERINFOPTR s_spi_providerptr = NULL; +static BOOL s_spi_providersfound = FALSE; +static LPVOID s_spi_sendbuffer = NULL; +static DWORD s_spi_timetoackturn = 250; +static DWORD s_spi_timetoblock = 5000; +static DWORD s_spi_timetogiveup = 1000; +static DWORD s_spi_timetorequest = 25; +static DWORD s_spi_timetoresend = 50; + +static LPVOID SpiLoadCapsSignature (LPCSTR filename); + +//=========================================================================== +static LPVOID inline SpiExtractCaps (LPVOID capssig, + DWORD *id, + LPCSTR *desc, + LPCSTR *req, + SNETCAPSPTR *caps) { + VALIDATEBEGIN; + VALIDATE(capssig); + VALIDATEEND; + + DWORD bytes = *(LPDWORD)capssig; + LPCSTR start = (LPCSTR)capssig+sizeof(DWORD); + LPCSTR curr = start; + *id = *(LPDWORD)curr; + curr += sizeof(DWORD); + *desc = curr; + curr += SStrLen(curr)+1; + *req = curr; + curr += SStrLen(curr)+1; + *caps = (SNETCAPSPTR)curr; + curr += ((SNETCAPSPTR)curr)->size; + if ((DWORD)(curr-start) != bytes) + return NULL; + + return (LPVOID)curr; +} + +//=========================================================================== +static int inline SpiCheckProviderOrder (PROVIDERINFOPTR first, + PROVIDERINFOPTR second) { + + // CHECK WHETHER ONE OR BOTH OF THE PROVIDERS IN IN OUR PREFERRED LIST +#define BASENUM 6 + static const DWORD baseorder[BASENUM] = {'BNET','IPXN','IPXW','MODM','SCBL','MSDP'}; + int firstindex = 0x7FFFFFFF; + int secondindex = 0x7FFFFFFF; + for (int loop = 0; loop < BASENUM; ++loop) { + if (first->id == baseorder[loop]) + firstindex = loop; + if (second->id == baseorder[loop]) + secondindex = loop; + } +#undef BASENUM + + // IF SO, SORT BASED ON THE ORDER IN THE LIST + if ((firstindex != 0x7FFFFFFF) || (secondindex != 0x7FFFFFFF)) + return secondindex-firstindex; + + // OTHERWISE, SORT ON ALPHABETICAL ORDER + else + return _stricmp(first->desc,second->desc); + +} + +//=========================================================================== +static void SpiDestroy (BOOL clearproviderlist) { + + // CALL THE PROVIDER'S DESTROY FUNCTION + if (s_spi_lib && s_spi) { + TRACEOUT(TRACEHANDLE," spiDestroy()"); + s_spi->Destroy(); + } + + // UNBIND FROM THE CURRENT PROVIDER + if (s_spi_lib) { + FreeLibrary(s_spi_lib); + s_spi_lib = (HINSTANCE)0; + } + if (s_spi) { + DEL(s_spi); + s_spi = NULL; + } + + // FREE THE SEND BUFFER + if (s_spi_sendbuffer) { + VirtualUnlock(s_spi_sendbuffer,SENDBUFSIZE); + VirtualFree(s_spi_sendbuffer,0,MEM_RELEASE); + s_spi_sendbuffer = NULL; + } + + // DESTROY THE LIST OF PROVIDERS + if (clearproviderlist) { + s_spi_providerlist.Clear(); + s_spi_providersfound = FALSE; + } + +} + +//=========================================================================== +static void SpiFindAllProviders () { + + // MAKE SURE THIS FUNCTION IS NOT CALLED MORE THAN ONCE + if (s_spi_providersfound) + return; + else + s_spi_providersfound = TRUE; + + // CREATE THE SEARCH SPECIFICATION + char basepath[MAX_PATH] = ""; + GetModuleFileName((HMODULE)StormGetInstance(),basepath,MAX_PATH); + { + LPTSTR curr = basepath; + while (SStrChr(curr,'\\')) + curr = SStrChr(curr,'\\')+1; + *curr = 0; + } + char filespec[MAX_PATH] = ""; + wsprintf(filespec,"%s*.snp",basepath); + + // SEARCH FOR PROVIDER LIBRARIES + WIN32_FIND_DATA finddata; + HANDLE findhandle = FindFirstFile(filespec,&finddata); + if (findhandle == INVALID_HANDLE_VALUE) + return; + do { + + // BUILD THE COMPLETE FILENAME + char filename[MAX_PATH]; + wsprintf(filename,"%s%s",basepath,finddata.cFileName); + + // LOAD THE CAPABILITIES SIGNATURE BLOCK FOR THE NEXT LIBRARY + LPVOID capssig = NULL; +#ifndef UNSIGNEDSNPS + capssig = SpiLoadCapsSignature(filename); + if (!capssig) + continue; +#endif + + // LOAD THE NEXT LIBRARY + HINSTANCE lib = LoadLibrary(filename); + if (!lib) { + if (capssig) + FREE(capssig); + continue; + } + + // GET THE ADDRESS OF THE QUERY FUNCTION + SNETSPIQUERY query = (SNETSPIQUERY)GetProcAddress(lib,"SnpQuery"); + if (!query) { + if (capssig) + FREE(capssig); + FreeLibrary(lib); + continue; + } + + // QUERY ALL PROVIDER INTERFACES CONTAINED IN THIS LIBRARY + LPVOID currcapssig = capssig; + DWORD index = 0; + for (;;) { + + // QUERY THE PROVIDER'S CAPABILITIES TO DETERMINE WHETHER IT RETURNS + // SUCCESS OR FAILURE; HOWEVER, DON'T USE THE CAPABILITIES IT RETURNS, + // BECAUSE THEY'RE TOO EASY TO HACK +#ifndef UNSIGNEDSNPS + { +#endif + DWORD id; + LPCSTR desc; + LPCSTR req; + SNETCAPSPTR caps = NULL; + if (!query(index,&id,&desc,&req,&caps)) + break; + if (!(caps && (caps->size >= sizeof(SNETCAPS)))) + break; +#ifdef _DEBUG + if (caps->flags & SNET_CAPS_RETAILONLY) + break; +#else + if (caps->flags & SNET_CAPS_DEBUGONLY) + break; +#endif +#ifndef UNSIGNEDSNPS + } + + // RETRIEVE THE REAL CAPABILITIES FROM THE SIGNATURE DATA + DWORD id; + LPCSTR desc; + LPCSTR req; + SNETCAPSPTR caps = NULL; + currcapssig = SpiExtractCaps(currcapssig,&id,&desc,&req,&caps); + if (!currcapssig) + break; + if (!(caps && (caps->size >= sizeof(SNETCAPS)))) + break; +#endif + + // ALLOCATE A NEW PROVIDER STRUCTURE + PROVIDERINFOPTR info = s_spi_providerlist.NewNode(LIST_UNLINKED); + + // FILL OUT THE PROVIDER INFORMATION STRUCTURE + SStrCopy(info->filename,filename,MAX_PATH); + info->index = index; + info->id = id; + if (desc) + SStrCopy(info->desc,desc,SNETSPI_MAXSTRINGLENGTH); + if (req) + SStrCopy(info->req,req,SNETSPI_MAXSTRINGLENGTH); + CopyMemory(&info->caps,caps,sizeof(SNETCAPS)); + info->caps.maxmessagesize -= (sizeof(HEADER)+sizeof(DWORD)); + + // ADD IT TO THE LIST IN SORTED ORDER + PROVIDERINFOPTR curr = s_spi_providerlist.Head(); + while (curr && (SpiCheckProviderOrder(curr,info) <= 0)) + curr = curr->Next(); + s_spi_providerlist.LinkNode(info,LIST_LINK_BEFORE,curr); + + ++index; + } + + // FREE THE LIBRARY + FreeLibrary(lib); + + // FREE THE CAPABILITIES SIGNATURE + if (capssig) + FREE(capssig); + + } while (FindNextFile(findhandle,&finddata)); + FindClose(findhandle); +} + +//=========================================================================== +static BOOL SpiInitialize (DWORD providerid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE recvevent) { + + // DESTROY THE EXISTING PROVIDER IF ONE IS INITIALIZED + SpiDestroy(FALSE); + + // BUILD A LIST OF PROVIDERS IF WE DON'T ALREADY HAVE ONE + SpiFindAllProviders(); + + // FIND THE DESIRED PROVIDER + s_spi_providerptr = s_spi_providerlist.Head(); + while (s_spi_providerptr && (s_spi_providerptr->id != providerid)) + s_spi_providerptr = s_spi_providerptr->Next(); + if (!s_spi_providerptr) { + SpiDestroy(FALSE); + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + return FALSE; + } + + // DETERMINE TIMEOUTS BASED ON THE LATENCY OF THIS PROVIDER + s_spi_timetoackturn = max( 250, 5*s_spi_providerptr->caps.latencyms); + s_spi_timetoblock = max(5000,12*s_spi_providerptr->caps.latencyms); + s_spi_timetogiveup = max(1000, 4*s_spi_providerptr->caps.latencyms); + s_spi_timetorequest = max( 25,s_spi_providerptr->caps.latencyms/2); + s_spi_timetoresend = max( 50,s_spi_providerptr->caps.latencyms); + + // IF THIS PROVIDER REQUIRES PACKETS TO BE IN PAGE-LOCKED MEMORY, ALLOCATE + // A SEND BUFFER + if (s_spi_providerptr->caps.flags & SNET_CAPS_PAGELOCKEDBUFFERS) { + s_spi_sendbuffer = VirtualAlloc(NULL,SENDBUFSIZE,MEM_COMMIT,PAGE_READWRITE); + if (s_spi_sendbuffer) + VirtualLock(s_spi_sendbuffer,SENDBUFSIZE); + else { + SpiDestroy(FALSE); + SErrSetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + } + + // LOAD THE LIBRARY CONTAINING THE PROVIDER + s_spi_lib = LoadLibrary(s_spi_providerptr->filename); + if (!s_spi_lib) { + SpiDestroy(FALSE); + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + return FALSE; + } + + // GET A POINTER TO THE BIND FUNCTION + SNETSPIBIND bind = (SNETSPIBIND)GetProcAddress(s_spi_lib,"SnpBind"); + if (!bind) { + SpiDestroy(FALSE); + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + return FALSE; + } + + // BIND TO THE PROVIDER + SNETSPIPTR returnedspi = NULL; + bind(s_spi_providerptr->index,&returnedspi); + if ((!returnedspi) || (returnedspi->size < MINSPISIZE)) { + SpiDestroy(FALSE); + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + return FALSE; + } + + // SAVE THE PROVIDER INTERFACE POINTERS + if (!s_spi) + s_spi = NEW(SNETSPI); + ZeroMemory(s_spi,sizeof(SNETSPI)); + CopyMemory(s_spi,returnedspi,min(returnedspi->size,sizeof(SNETSPI))); + + // CALL THE PROVIDER'S INITIALIZE FUNCTION + TRACEOUT(TRACEHANDLE, + " spiInitialize(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x)", + programdata,playerdata,interfacedata,versiondata,recvevent); + if (!s_spi->Initialize(programdata, + playerdata, + interfacedata, + versiondata, + recvevent)) { + DWORD lasterror = SErrGetLastError(); + SpiDestroy(FALSE); + SErrSetLastError(lasterror); + return FALSE; + } + + return TRUE; +} + +//=========================================================================== +static LPVOID SpiLoadCapsSignature (LPCSTR filename) { + HSARCHIVE archive = (HSARCHIVE)0; + LPVOID buffer = NULL; + HSFILE file = (HSFILE)0; + TRY { + + // OPEN THE MPQ ARCHIVE EMBEDDED IN THE FILE + if (!SFileOpenArchive(filename,0,0,&archive)) + LEAVE; + + // AUTHENTICATE THE ARCHIVE + { + DWORD authtype; + SFileAuthenticateArchive(archive,&authtype); + if ((authtype != SFILE_AUTH_UNABLETOAUTHENTICATE) && + (authtype < SFILE_AUTH_FIRSTAUTHENTIC)) + LEAVE; + } + + // OPEN THE CAPABILITIES DATA FROM THE ARCHIVE + if (!SFileOpenFileEx(archive,"caps.dat",0,&file)) + LEAVE; + + // CREATE A BUFFER FOR THE CAPABILITIES DATA + DWORD bytes = SFileGetFileSize(file,NULL); + buffer = ALLOC(bytes); + + // READ THE CAPABILITIES DATA + { + DWORD bytesread; + SFileReadFile(file,buffer,bytes,&bytesread,NULL); + } + + } + FINALLY { + if (file) + SFileCloseFile(file); + if (archive) + SFileCloseArchive(archive); + } + return buffer; +} + +//=========================================================================== +static BOOL SpiMeetsMinimumCaps (SNETCAPSPTR curr, SNETCAPSPTR mincaps) { + if (!(curr && mincaps)) + return TRUE; + return (((mincaps->flags & curr->flags) == mincaps->flags) && + (mincaps->maxmessagesize <= curr->maxmessagesize) && + (mincaps->maxqueuesize <= curr->maxqueuesize ) && + (mincaps->maxplayers <= curr->maxplayers ) && + (mincaps->bytessec <= curr->bytessec ) && + ((!mincaps->latencyms) || + (mincaps->latencyms >= curr->latencyms))); +} + +//=========================================================================== +static BOOL SpiNormalizeDataBlocks (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + SNETPROGRAMDATAPTR modprogramdata, + SNETPLAYERDATAPTR modplayerdata, + SNETUIDATAPTR modinterfacedata, + SNETVERSIONDATAPTR modversiondata) { + + // NORMALIZE THE PROGRAM DATA + ZeroMemory(modprogramdata,sizeof(SNETPROGRAMDATA)); + if (programdata) + CopyMemory(modprogramdata,programdata,min(sizeof(SNETPROGRAMDATA),programdata->size)); + modprogramdata->size = sizeof(SNETPROGRAMDATA); + if (!modprogramdata->programname) + modprogramdata->programname = ""; + char generateddescription[256] = ""; + if (!modprogramdata->programdescription) { + UiGetProgramDescription(modprogramdata->programname, + versiondata, + generateddescription, + 256); + modprogramdata->programdescription = generateddescription; + } + + // NORMALIZE THE PLAYER DATA + ZeroMemory(modplayerdata,sizeof(SNETPLAYERDATA)); + if (playerdata) + CopyMemory(modplayerdata,playerdata,min(sizeof(SNETPLAYERDATA),playerdata->size)); + modplayerdata->size = sizeof(SNETPLAYERDATA); + if (!modplayerdata->playername) + modplayerdata->playername = ""; + if (!modplayerdata->playerdescription) + modplayerdata->playerdescription = ""; + + // NORMALIZE THE INTERFACE DATA + ZeroMemory(modinterfacedata,sizeof(SNETUIDATA)); + if (interfacedata) + CopyMemory(modinterfacedata,interfacedata,min(sizeof(SNETUIDATA),interfacedata->size)); + modinterfacedata->size = sizeof(SNETUIDATA); + if (!modinterfacedata->parentwindow) + modinterfacedata->parentwindow = SDrawGetFrameWindow(); + if (!modinterfacedata->messageboxcallback) + modinterfacedata->messageboxcallback = MessageBoxA; + + // NORMALIZE THE VERSION DATA + ZeroMemory(modversiondata,sizeof(SNETVERSIONDATA)); + if (versiondata) + CopyMemory(modversiondata,versiondata,min(sizeof(SNETVERSIONDATA),versiondata->size)); + modversiondata->size = sizeof(SNETVERSIONDATA); + + return TRUE; +} + +//=========================================================================== +static BOOL SpiSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes) { + if (!s_spi) + return FALSE; + + // UPDATE OUR ESTIMATE OF HOW LONG IT WILL TAKE TO SEND ALL THE OUTGOING + // DATA THAT WE HAVE QUEUED + { + DWORD currtime = GetTickCount(); + if (currtime-s_spi_outgoingtime < 0x7FFFFFFF) + s_spi_outgoingtime = currtime; + s_spi_outgoingtime += (addresses*(databytes+ESTIMATEDPACKETOVERHEAD)) + *1000 + /s_spi_providerptr->caps.bytessec; + } + + // IF THIS SERVICE PROVIDER REQUIRES ITS DATA TO BE PAGE LOCKED, MOVE + // THE ADDRESSES AND DATA INTO A PAGE LOCKED BUFFER + if (s_spi_sendbuffer) { + DWORD ptrbytes = 16*sizeof(SNETADDRPTR); + DWORD addrbytes = 16*sizeof(SNETADDR); + if ((addresses > 16) || (databytes > SENDBUFSIZE-addrbytes)) + return FALSE; + DWORD loop; + for (loop = 0; loop < addresses; ++loop) + *((SNETADDRPTR *)s_spi_sendbuffer+loop) = (SNETADDRPTR)((LPBYTE)s_spi_sendbuffer+ptrbytes+loop*sizeof(SNETADDR)); + for (loop = 0; loop < addresses; ++loop) + CopyMemory((LPBYTE)s_spi_sendbuffer+ptrbytes+loop*sizeof(SNETADDR),*(addrlist+loop),sizeof(SNETADDR)); + CopyMemory((LPBYTE)s_spi_sendbuffer+ptrbytes+addrbytes,data,databytes); + data = (LPBYTE)s_spi_sendbuffer+ptrbytes+addrbytes; + } + + // IF WE ARE IN DEBUG MODE, DUMP THE ADDRESSES AND PACKET DATA +#ifdef TRACING + TRACEOUT(TRACEHANDLE, + " spiSend(%u,*addrlist,0x%08x,%u)", + addresses,data,databytes); + for (DWORD loop = 0; loop < addresses; ++loop) { + CONNPTR targetconn = ConnFindByAddr(*(addrlist+loop)); + TRACEDUMPADDR(TRACEHANDLE, + "target", + *(addrlist+loop), + targetconn ? targetconn->playerid : NOPLAYER); + } + PACKETPTR pkt = (PACKETPTR)data; + TRACEDUMP(TRACEHANDLE,&pkt->header,min(databytes,sizeof(HEADER))); + if (databytes > sizeof(HEADER)) + TRACEDUMP(TRACEHANDLE,&pkt->data[0],databytes-sizeof(HEADER)); +#endif + + PerfAdd(SNET_PERFID_TOTALBYTESSENT,databytes); + return s_spi->Send(addresses,addrlist,data,databytes); +} + +/**************************************************************************** +* +* PACKET UTILITY FUNCTIONS +* +***/ + +//=========================================================================== +static void PktAllocateLocalMessage (SNETADDRPTR *addr, + LPVOID *data, + DWORD databytes) { + *addr = NEW(SNETADDR); + databytes += 4-(databytes & 3); + *data = ALLOC(max(4,databytes)); +} + +//=========================================================================== +static WORD PktComputeChecksum (LPVOID data, + DWORD databytes) { + DWORD checkval1 = 0; + DWORD checkval2 = 0; + LPBYTE ptr = ((LPBYTE)data)+databytes-1; + while (databytes--) { + checkval1 += *ptr--; + if (checkval1 >= 0xFF) + checkval1 -= 0xFF; + checkval2 += checkval1; + } + checkval2 %= 255; + return MAKEWORD((checkval2 & 0xFF),(checkval1 & 0xFF)); +} + +//=========================================================================== +static void PktFreeLocalMessage (SNETADDRPTR addr, + LPVOID data, + DWORD databytes) { + if (addr) + DEL(addr); + if (data) + FREE(data); +} + +//=========================================================================== +static WORD PktGenerateChecksum (PACKETPTR pkt) { + + // COMPUTE THE CURRENT CHECKSUM FOR THE MESSAGE + WORD checksum = PktComputeChecksum(((LPBYTE)pkt)+sizeof(WORD), + pkt->header.bytes-sizeof(WORD)); + + // COMPUTE A NEW VALUE FOR THE CHECKSUM FIELD THAT WILL MAKE THE NEW + // CHECKSUM OF THE ENTIRE MESSAGE ZERO + BYTE hibyte = 0xFF-((checksum >> 8)+(checksum & 0xFF)) % 0xFF; + BYTE lobyte = 0xFF-((checksum >> 8)+hibyte) % 0xFF; + return MAKEWORD(lobyte,hibyte); +} + +/**************************************************************************** +* +* CONNECTION MANAGEMENT FUNCTIONS +* +***/ + +static LIST(CONNREC) s_conn_connlist; +static LIST(CONNREC) s_conn_local; + +static void ConnFree (CONNPTR conn); +static BOOL ConnResendMessage (CONNPTR conn, + LPVOID data, + DWORD databytes); +static void ConnSendPacket (CONNPTR conn, + PACKETPTR pkt); +static MESSAGEPTR ConnSendMessage (CONNPTR target, + BYTE type, + BYTE subtype, + LPVOID data, + DWORD databytes); + +//=========================================================================== +static CONNPTR ConnAddRec (LISTPTR(CONNREC) list, SNETADDRPTR addr) { + TRACEDUMPADDR(TRACEHANDLE, + " ConnAddRec() addr", + addr,NOPLAYER); + CONNPTR newconn = list->NewNode(); + CopyMemory(&newconn->addr,addr,sizeof(SNETADDR)); + newconn->playerid = NOPLAYER; + newconn->lastreceivetime = GetTickCount(); + return newconn; +} + +//=========================================================================== +static void ConnClearOldTurns (CONNPTR onlyconn) { + CONNPTR localptr = ConnFindLocal(); + if (!localptr) + return; + + // DETERMINE THE SEQUENCE OF THE NEXT TURN WE WILL PROCESS + WORD sequence = localptr->incomingsequence[TYPE_TURN]; + + // DETERMINE THE EARLIEST POSSIBLE SEQUENCE FOR WHICH WE MAY STILL NEED + // TURN DATA FOR THE PURPOSES OF RESENDING TURNS ON BEHALF OF UNRESPONSIVE + // CLIENTS + WORD acksequence = sequence; + { + CONNPTR conn = s_conn_connlist.Head(); + while (conn) { + if ((WORD)(acksequence-conn->lastprocessedturn) < 0x7FFF) + acksequence = conn->lastprocessedturn; + conn = conn->Next(); + } + } + + // ITERATE THROUGH ALL CONNECTIONS + { + for (int local = 0; local <= 1; ++local) { + CONNPTR conn = local ? localptr : s_conn_connlist.Head(); + while (conn) { + if ((!onlyconn) || (conn == onlyconn)) { + + // IF THERE ARE ANY TURNS ON THIS CONNECTION'S INCOMING QUEUE + // WITH SEQUENCE NUMBERS PRIOR TO THE CURRENT SEQUENCE NUMBER, + // MOVE THEM TO THE OLD TURNS QUEUE + while ((!conn->incomingqueue[TYPE_TURN].IsEmpty()) && + ((WORD)(sequence-conn->incomingqueue[TYPE_TURN].Head()->data->header.sequence) > 0) && + ((WORD)(sequence-conn->incomingqueue[TYPE_TURN].Head()->data->header.sequence) <= 0x7FFF)) { + MESSAGEPTR message = conn->incomingqueue[TYPE_TURN].Head(); + conn->incomingqueue[TYPE_TURN].UnlinkNode(message); + ConnSetCurrentMessage(conn,TYPE_TURN,message); + } + + // IF THERE ARE ANY TURNS ON THIS CONNECTION'S OLD TURNS QUEUE + // WITH SEQUENCE NUMBERS PRIOR TO THE EARLIEST POSSIBLE NEEDED + // SEQUENCE, FREE THEM + while ((!conn->oldturns.IsEmpty()) && + ((WORD)(acksequence-conn->oldturns.Head()->data->header.sequence) > 0) && + ((WORD)(acksequence-conn->oldturns.Head()->data->header.sequence) <= 0x7FFF)) { + MESSAGEPTR message = conn->oldturns.Head(); + if (local) + PktFreeLocalMessage(message->addr,message->data,message->databytes); + else { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [all acks above turn sequence (%u>%u)]", + message->addr,message->data,message->databytes,acksequence,message->data->header.sequence); + s_spi->Free(message->addr,message->data,message->databytes); + } + conn->oldturns.DeleteNode(message); + } + + } + conn = conn->Next(); + } + } + } + +} + +//=========================================================================== +static void ConnDestroy () { + for (BOOL local = FALSE; local <= TRUE; ++local) { + LISTPTR(CONNREC) list = local ? &s_conn_local + : &s_conn_connlist; + CONNPTR currconn; + while ((currconn = list->Head()) != NULL) + ConnFree(currconn); + } +} + +//=========================================================================== +static void ConnDestroyQueue (LISTPTR(MESSAGE) queue) { + MESSAGEPTR currmsg; + while ((currmsg = queue->Head()) != NULL) { + if (currmsg->local) + PktFreeLocalMessage(currmsg->addr,currmsg->data,currmsg->databytes); + else if (s_spi) { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [closing connection]", + currmsg->addr,currmsg->data,currmsg->databytes); + s_spi->Free(currmsg->addr,currmsg->data,currmsg->databytes); + } + queue->DeleteNode(currmsg); + } +} + +//=========================================================================== +static CONNPTR inline ConnFindByAddr (SNETADDRPTR addr) { + CONNPTR curr = s_conn_connlist.Head(); + while (curr && memcmp(&curr->addr,addr,sizeof(SNETADDR))) + curr = curr->Next(); + if (!curr) + curr = ConnAddRec(&s_conn_connlist,addr); + return curr; +} + +//=========================================================================== +static CONNPTR inline ConnFindByPlayerId (DWORD playerid) { + if (playerid == NOPLAYER) + return NULL; + for (BOOL local = TRUE; local >= FALSE; --local) { + LISTPTR(CONNREC) list = local ? &s_conn_local + : &s_conn_connlist; + CONNPTR curr = list->Head(); + while (curr) + if (curr->playerid == (BYTE)playerid) + return curr; + else + curr = curr->Next(); + } + return NULL; +} + +//=========================================================================== +static CONNPTR inline ConnFindLocal () { + if (!s_conn_local.IsEmpty()) + return s_conn_local.Head(); + else { + SNETADDR addr; + ZeroMemory(&addr,sizeof(SNETADDR)); + return ConnAddRec(&s_conn_local,&addr); + } +} + +//=========================================================================== +static void ConnFree (CONNPTR conn) { + TRACEDUMPADDR(TRACEHANDLE, + " ConnFree() addr", + &conn->addr,conn->playerid); + for (int type = 0; type < TYPES; ++type) { + ConnDestroyQueue(&conn->outgoingqueue[type]); + ConnDestroyQueue(&conn->incomingqueue[type]); + ConnDestroyQueue(&conn->processing[type]); + } + ConnDestroyQueue(&conn->oldturns); + if (conn == s_conn_local.Head()) + s_conn_local.DeleteNode(conn); + else + s_conn_connlist.DeleteNode(conn); +} + +//=========================================================================== +static DWORD ConnMaintainConnections () { + DWORD currtime = GetTickCount(); + DWORD wait = INFINITE; + CONNPTR local = ConnFindLocal(); + CONNPTR conn = s_conn_connlist.Head(); + if (!(conn && local)) + return wait; + CONNPTR next; + do { + next = conn->Next(); + + // DELETE ANY CONNECTION WHICH WE HAVEN'T HEARD FROM IN FIFTY SECONDS + if ((conn->playerid == NOPLAYER) && + (currtime-conn->lastreceivetime >= DELETECONNTIME)) { + TRACEOUT(TRACEHANDLE, + " deleting unresponsive connection: player=%x", + conn->playerid); + ConnFree(conn); + continue; + } + + // DON'T SEND CONNECTION MAINTENANCE PACKETS TO PLAYERS WHO AREN'T + // IN THE GAME + if ((conn->playerid == NOPLAYER) && !conn->establishing) + continue; + + // PING EACH ESTABLISHED CONNECTION ONCE EVERY TWENTY SECONDS + if ((currtime-conn->lastpingtime >= PINGFREQUENCY) && + !conn->establishing) { + TRACEOUT(TRACEHANDLE, + " pinging: player=%x", + conn->playerid); + conn->lastpingtime = currtime; + ConnSendMessage(conn,TYPE_SYSTEM,SYS_PING,NULL,0); + } + + // SEND OUT RESEND REQUESTS AS NECESSARY + { + for (int type = 0; type < TYPES; ++type) { + WORD lastsequence = conn->incomingsequence[type]-1; + MESSAGEPTR message = conn->incomingqueue[type].Head(); + while (message) { + if (message->data->header.sequence-lastsequence > 1) { + if (message->resendtime && + ((LONG)(message->resendtime+s_spi_timetoresend-currtime) > 0)) + wait = min(wait,message->resendtime+s_spi_timetoresend-currtime); + else { + TRACEOUT(TRACEHANDLE, + " requesting resend: type=%u sequence=%04x player=%x", + type,lastsequence+1,conn->playerid); + message->resendtime = currtime; + PACKET pkt; + pkt.header.checksum = 0; + pkt.header.bytes = sizeof(HEADER); + pkt.header.sequence = lastsequence+1; + pkt.header.acksequence = conn->availablesequence[type]; + pkt.header.type = type; + pkt.header.subtype = 0; + pkt.header.playerid = local->playerid; + pkt.header.flags = MF_RESENDREQUEST; + pkt.header.checksum = PktGenerateChecksum(&pkt); + ConnSendPacket(conn,&pkt); + } + break; + } + lastsequence = message->data->header.sequence; + message = message->Next(); + } + } + } + + // AUTOMATICALLY RESEND UNACKNOWLEDGED SYSTEM MESSAGES AND USER + // ASYNCHRONOUS MESSAGES + // (THESE TYPES OF MESSAGES ARE NOT EXPECTED BY THE RECIPIENT, SO + // WE CAN'T RELY ON HIM TO REQUEST A RESEND) + { + for (int type = 0; type < TYPES; ++type) + if ((!conn->outgoingqueue[type].IsEmpty()) && + (type != TYPE_TURN)) { + + // DETERMINE HOW QUICKLY WE SHOULD EXPECT A RESPONSE TO THIS + // MESSAGE, BASED ON BOTH LATENCY AND BANDWIDTH + MESSAGEPTR message = conn->outgoingqueue[type].Head(); + DWORD bandwidth = s_spi_providerptr->caps.bytessec; + DWORD maxpacket = s_spi_providerptr->caps.maxmessagesize; + DWORD totaldata = message->databytes + +maxpacket + +2*ESTIMATEDPACKETOVERHEAD; + DWORD responsetime = 2*s_spi_timetoresend + +totaldata*1000/bandwidth + +200; + + // IF WE HAVEN'T RECEIVED A RESPONSE IN THE EXPECTED AMOUNT + // OF TIME, RESEND THE MESSAGE + if (message->resendtime && + ((LONG)(message->resendtime+responsetime-currtime) > 0)) + wait = min(wait,message->resendtime+responsetime-currtime); + else { + TRACEOUT(TRACEHANDLE, + " auto-resending: type=%u sequence=%04x player=%x", + type,message->data->header.sequence,conn->playerid); + message->resendtime = currtime; + ConnResendMessage(conn,message->data,message->databytes); + } + + } + } + + // SEND OUT EXPLICIT ACKNOWLEDGEMENT PACKETS TO THIS CONNECTION IF + // WE HAVEN'T SENT ANY EXPLICIT OR PIGGY-BACKED ACKNOWLEDGEMENTS RECENTLY + { + for (int type = 0; type < TYPES; ++type) { + DWORD acktime = (type == TYPE_TURN) ? s_spi_timetoackturn + : s_spi_timetorequest; + if ((conn->acksequence[type] != conn->availablesequence[type]) && + conn->acktime[type]) + if ((LONG)(conn->acktime[type]+acktime-currtime) > 0) + wait = min(wait,conn->acktime[type]+acktime-currtime); + else { + TRACEOUT(TRACEHANDLE, + " sending explicit ack: type=%u sequence=%04x player=%x", + type,conn->availablesequence[type],conn->playerid); + PACKET pkt; + pkt.header.checksum = 0; + pkt.header.bytes = sizeof(HEADER); + pkt.header.sequence = conn->availablesequence[type]; + pkt.header.acksequence = conn->availablesequence[type]; + pkt.header.type = type; + pkt.header.subtype = 0; + pkt.header.playerid = local->playerid; + pkt.header.flags = MF_ACK; + pkt.header.checksum = PktGenerateChecksum(&pkt); + SNETADDRPTR addr = &conn->addr; + ConnSendPacket(conn,&pkt); + } + } + } + + } while ((conn = next) != NULL); + return wait; +} + +//=========================================================================== +static void ConnProcessAck (CONNPTR conn, BYTE type, WORD acksequence) { + + // REMOVE ACKNOWLEDGED MESSAGES FROM THE OUTGOING QUEUE + BOOL found = FALSE; + while ((!conn->outgoingqueue[type].IsEmpty()) && + ((WORD)(acksequence-conn->outgoingqueue[type].Head()->data->header.sequence) > 0) && + ((WORD)(acksequence-conn->outgoingqueue[type].Head()->data->header.sequence) <= 0x7FFF)) { + found = TRUE; + MESSAGEPTR message = conn->outgoingqueue[type].Head(); + if (message->local) + PktFreeLocalMessage(message->addr,message->data,message->databytes); + else { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [acknowledged]", + message->addr, + message->data, + message->databytes); + s_spi->Free(message->addr,message->data,message->databytes); + } + conn->outgoingqueue[type].DeleteNode(message); + } + + // SAVE THE SEQUENCE OF THE LAST PROCESSED TURN + if (type == TYPE_TURN) + conn->lastprocessedturn = acksequence; + + // RESET THE TIME STAMP OF THE MESSAGE THAT IS NOW AT THE HEAD OF THE + // OUTGOING QUEUE, SO WE DON'T IMMEDIATELY RESEND IT + if (found && !conn->outgoingqueue[type].IsEmpty()) { + DWORD currtime = GetTickCount(); + if (currtime-conn->outgoingqueue[type].Head()->resendtime < 0x7FFFFFFF) + conn->outgoingqueue[type].Head()->resendtime = currtime; + } + +} + +//=========================================================================== +static BOOL ConnResendMessage (CONNPTR conn, + LPVOID data, + DWORD databytes) { + + // MAKE A COPY OF THE MESSAGE + PACKETPTR localpkt = (PACKETPTR)ALLOC(databytes); + CopyMemory(localpkt,data,databytes); + + // FILL IN THE CURRENT ACKNOWLEDGEMENT SEQUENCE + localpkt->header.acksequence = conn->availablesequence[localpkt->header.type]; + + // FILL IN THE NEW CHECKSUM + localpkt->header.checksum = PktGenerateChecksum(localpkt); + + // SEND THE MESSAGE + ConnSendPacket(conn,localpkt); + + // FREE THE COPY + FREE(localpkt); + + return TRUE; +} + +//=========================================================================== +static void ConnSendPacket (CONNPTR conn, + PACKETPTR pkt) { + SNETADDRPTR addr = &conn->addr; + SpiSend(1,&addr,pkt,pkt->header.bytes); + conn->acksequence[pkt->header.type] = pkt->header.acksequence; + conn->acktime[pkt->header.type] = 0; +} + +//=========================================================================== +static MESSAGEPTR ConnSendMessage (CONNPTR target, + BYTE type, + BYTE subtype, + LPVOID data, + DWORD databytes) { + + // GET A POINTER TO THE LOCAL PLAYER + CONNPTR local = ConnFindLocal(); + if (!local) + return NULL; + + // ALLOCATE MEMORY TO HOLD THE ADDRESS AND MESSAGE DATA + SNETADDRPTR pktaddr = NULL; + LPVOID pktdata = NULL; + DWORD pktdatabytes = sizeof(HEADER)+databytes; + PktAllocateLocalMessage(&pktaddr,&pktdata,pktdatabytes); + + // FILL IN THE ADDRESS + CopyMemory(pktaddr,&target->addr,sizeof(SNETADDR)); + + // FILL IN THE HEADER + PACKETPTR pkt = (PACKETPTR)pktdata; + pkt->header.bytes = (WORD)pktdatabytes; + pkt->header.acksequence = target->availablesequence[type]; + pkt->header.type = type; + pkt->header.subtype = subtype; + pkt->header.playerid = local->playerid; + pkt->header.flags = 0; + + // FILL IN THE SEQUENCE NUMBER FOR THIS MESSAGE + if ((type == TYPE_SYSTEM) && (subtype == SYS_INITIALCONTACT)) + pkt->header.sequence = 0; + else + pkt->header.sequence = target->outgoingsequence[type]++; + + // FILL IN THE DATA + if (data && databytes) + CopyMemory((LPBYTE)pktdata+sizeof(HEADER),data,databytes); + + // FILL IN THE CHECKSUM + pkt->header.checksum = PktGenerateChecksum(pkt); + + // ALLOCATE A MESSAGE RECORD + MESSAGEPTR msg; + if (target == local) + msg = target->incomingqueue[type].NewNode(); + else + msg = target->outgoingqueue[type].NewNode(); + + // FILL IN THE MESSAGE RECORD + msg->addr = pktaddr; + msg->data = (PACKETPTR)pktdata; + msg->databytes = pktdatabytes; + msg->local = TRUE; + msg->sendtime = GetTickCount(); + + // SEND THE MESSAGE + if (target != local) { + ConnSendPacket(target,pkt); + PerfAdd(SNET_PERFID_USERBYTESSENT,databytes); + } + + // INITIALIZE THE MESSAGE'S RESEND TIMER TO THE ESTIMATED TIME THAT + // THE COMPLETE MESSAGE WILL HIT THE WIRE + msg->resendtime = s_spi_outgoingtime; + + return msg; +} + +//=========================================================================== +static void ConnSetCurrentMessage (CONNPTR conn, BYTE type, MESSAGEPTR message) { + // message must be unlinked upon entry to this function + if (type == TYPE_TURN) + conn->oldturns.LinkNode(message,LIST_TAIL,NULL); + else { + if (!conn->processing[type].IsEmpty()) { + MESSAGEPTR processing = conn->processing[type].Head(); + if (processing->local) + PktFreeLocalMessage(processing->addr, + processing->data, + processing->databytes); + else { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [processed]", + processing->addr, + processing->data, + processing->databytes); + s_spi->Free(processing->addr, + processing->data, + processing->databytes); + } + conn->processing[type].DeleteNode(processing); + } + conn->processing[type].LinkNode(message,LIST_TAIL,NULL); + } +} + +/**************************************************************************** +* +* GAME/PLAYER MANAGEMENT FUNCTIONS +* +***/ + +static DWORD s_game_categorybits = 0; +static DWORD s_game_creationtime = 0; +static LPVOID s_game_initdata = NULL; +static DWORD s_game_initdatabytes = 0; +static char s_game_gamedesc[SNETSPI_MAXSTRINGLENGTH] = ""; +static DWORD s_game_gamemode = 0; +static char s_game_gamename[SNETSPI_MAXSTRINGLENGTH] = ""; +static char s_game_gamepass[SNETSPI_MAXSTRINGLENGTH] = ""; +static BOOL s_game_joining = FALSE; +static DWORD s_game_optcategorybits = 0; +static BYTE s_game_playerid = NOPLAYER; +static DWORD s_game_playersallowed = 0; + +//=========================================================================== +static void GameBuildClientData (LPVOID buffer, + DWORD *bytes) { + CLIENTDATAPTR ptr = (CLIENTDATAPTR)buffer; + ptr->bytes = sizeof(CLIENTDATA); + SNetGetNumPlayers(NULL,NULL,&ptr->numplayers); + ptr->maxplayers = s_game_playersallowed; + *bytes = ptr->bytes; +} + +//=========================================================================== +static void GameBuildGameData (SNETGAMEPTR dest, + SNETSPI_GAMELISTPTR source) { + ZeroMemory(dest,sizeof(SNETGAME)); + dest->size = sizeof(SNETGAMEPTR); + dest->id = source->gameid; + dest->gamename = source->gamename; + dest->gamedescription = source->gamedescription; + dest->categorybits = source->gamecategorybits; + CLIENTDATAPTR clientdata = (CLIENTDATAPTR)(source->clientdata); + if (clientdata) { + dest->numplayers = clientdata->numplayers; + dest->maxplayers = clientdata->maxplayers; + } +} + +//=========================================================================== +static void GameCopyGameList (DWORD categorybits, + DWORD categorymask, + SNETSPI_GAMELISTPTR *gamearray, + DWORD *games, + DWORD *hintnextcall) { + *games = 0; + + // LOCK THE GAME LIST + SNETSPI_GAMELISTPTR head; + TRACEOUT(TRACEHANDLE, + " spiLockGameList(0x%08x,0x%08x,*gamelist)", + categorybits,categorymask); + if (!s_spi->LockGameList(categorybits,categorymask,&head)) + return; + + // DETERMINE THE NUMBER OF MATCHING GAMES + *games = 0; + { + SNETSPI_GAMELISTPTR curr = head; + while (curr) { + if (!(curr->gamemode & SNET_GM_UNLISTEDMASK)) + ++*games; + curr = curr->next; + } + } + + // ALLOCATE AN ARRAY TO HOLD THE GAMES + if (*games) { + *gamearray = (SNETSPI_GAMELISTPTR)ALLOC((*games)*(sizeof(SNETSPI_GAMELIST)+SNETSPI_MAXCLIENTDATA)); + + // COPY THE GAMES + SNETSPI_GAMELISTPTR source = head; + LPBYTE dest = (LPBYTE)*gamearray; + SNETSPI_GAMELISTPTR lastdest = NULL; + while (source) { + if (!(source->gamemode & SNET_GM_UNLISTEDMASK)) { + + // LINK THE LAST RECORD TO THIS ONE + if (lastdest) + lastdest->next = (SNETSPI_GAMELISTPTR)dest; + lastdest = (SNETSPI_GAMELISTPTR)dest; + + // COPY THIS RECORD + CopyMemory(dest,source,sizeof(SNETSPI_GAMELIST)); + dest += sizeof(SNETSPI_GAMELIST); + + // COPY THE CLIENT DATA FOR THIS RECORD + if (source->clientdata) { + CopyMemory(dest,source->clientdata,source->clientdatabytes); + lastdest->clientdata = dest; + dest += source->clientdatabytes; + } + + } + source = source->next; + } + + } + + // UNLOCK THE GAME LIST + TRACEOUT(TRACEHANDLE, + " spiUnlockGameList(0x%08x,*hintnextcall)", + head); + s_spi->UnlockGameList(head,hintnextcall); + +} + +//=========================================================================== +static void GameDestroy () { + + // FREE THE GAME INITIALIZATION DATA + if (s_game_initdata) { + FREE(s_game_initdata); + s_game_initdata = NULL; + s_game_initdatabytes = 0; + } + + // RESET THE GAME INFORMATION + s_game_gamename[0] = 0; + s_game_gamedesc[0] = 0; + s_game_gamepass[0] = 0; + s_game_gamemode = 0; + + // RESET THE PLAYER INFORMATION + s_game_playerid = NOPLAYER; + s_game_playersallowed = 0; + + // DESTROY ALL CONNECTION RECORDS + ConnDestroy(); + +} + +//=========================================================================== +static void GameProcessLeavingPlayers () { + CONNPTR conn = s_conn_connlist.Head(); + CONNPTR local = ConnFindLocal(); + if (!local) + return; + while (conn) { + if ((conn->flags & PF_LEAVING) && + (conn->playerid != NOPLAYER)) { + + // IF WE HAVE PROCESSED THE FINAL TURN FOR THIS PLAYER, REMOVE HIM + if ((WORD)(conn->incomingsequence[TYPE_TURN]-conn->finalsequence) <= 0x7FFF) { + + // QUEUE A USER-LEVEL EVENT + SysQueueUserEvent(SNET_EVENT_PLAYERLEAVE,conn->playerid,&conn->exitcode,sizeof(DWORD)); + + // MARK THE PLAYER SLOT AS UNUSED + conn->flags = 0; + conn->playerid = NOPLAYER; + + // IF THE GAME OWNER JUST LEFT AND WE ARE NOW THE LOWEST NUMBERED + // PLAYER, TAKE OWNERSHIP OF THE GAME + if ((s_game_playerid != NOPLAYER) && + !local->gameowner) { + + // FIND THE LOWEST NUMBERED PLAYED BESIDES THE LOCAL PLAYER WHICH + // IS STILL IN THE GAME + DWORD lowestplayerid = 0xFFFFFFFF; + CONNPTR checkconn = s_conn_connlist.Head(); + while (checkconn) { + if (checkconn->playerid != NOPLAYER) { + if (checkconn->gameowner) + lowestplayerid = 0; + else if (checkconn->playerid < lowestplayerid) + lowestplayerid = checkconn->playerid; + } + checkconn = checkconn->Next(); + } + + // IF OUR PLAYER NUMBER IS LOWER, TAKE OWNERSHIP + if (s_game_playerid < lowestplayerid) { + + // LOG IT + TRACEOUT(TRACEHANDLE," taking ownership"); + + // MARK THE LOCAL PLAYER AS THE OWNER + local->gameowner = TRUE; + + // SEND MESSAGES TO ALL OTHER PLAYERS NOTIFYING THEM OF THE + // TRANSFER OF GAME OWNERSHIP + { + CONNPTR checkconn = s_conn_connlist.Head(); + while (checkconn) { + if (checkconn->playerid != NOPLAYER) { + DWORD playerid = s_game_playerid; + ConnSendMessage(checkconn, + TYPE_SYSTEM, + SYS_NEWGAMEOWNER, + &playerid, + sizeof(DWORD)); + } + checkconn = checkconn->Next(); + } + } + + } + } + + // IF THE GAME IS NO LONGER FULL, NOTIFY THE NETWORK PROVIDER BY + // CHANGING THE GAME MODE + { + CONNPTR local = ConnFindLocal(); + if (local && local->gameowner) { + DWORD activeplayers = 0; + SNetGetNumPlayers(NULL,NULL,&activeplayers); + if (activeplayers < s_game_playersallowed) + s_game_gamemode &= ~SNET_GM_FULL; + } + } + + // UPDATE THE SERVER WITH THE NEW GAME MODE, FULL VS NOT FULL, + // NUMBER OF PLAYERS, ETC. + SNetSetGameMode(s_game_gamemode); + + } + + } + conn = conn->Next(); + } +} + +/**************************************************************************** +* +* SYSTEM MESSAGE FUNCTIONS +* +***/ + +static LIST(USEREVENT) s_sys_usereventlist; +static BOOL s_sys_event[SYSMSGS]; + +//=========================================================================== +static DWORD SysBuildPlayerInfo (SYSEVENTDATA_PLAYERINFOPTR data, + CONNPTR conn, + DWORD startingturn) { + data->playerid = conn->playerid; + data->gameowner = conn->gameowner; + data->flags = conn->flags; + data->startingturn = startingturn; + CopyMemory(&data->addr,&conn->addr,sizeof(SNETADDR)); + LPTSTR curr = data->namedesc; + curr += SStrCopy(curr,conn->name,SNETSPI_MAXSTRINGLENGTH)+1; + curr += SStrCopy(curr,conn->desc,SNETSPI_MAXSTRINGLENGTH)+1; + data->bytes = (LPBYTE)curr-(LPBYTE)data; + return data->bytes; +} + +//=========================================================================== +static void SysDestroy () { + USEREVENTPTR curr; + while ((curr = s_sys_usereventlist.Head()) != NULL) { + if (curr->event.data) + FREE(curr->event.data); + s_sys_usereventlist.DeleteNode(curr); + } +} + +//=========================================================================== +static void SysDispatchUserEvents () { + USEREVENTPTR curr; + while ((curr = s_sys_usereventlist.Head()) != NULL) { + USEREVENT event; + CopyMemory(&event,curr,sizeof(USEREVENT)); + s_sys_usereventlist.DeleteNode(curr); + event.event.playerid += s_api_playeroffset; + TRACEOUT(TRACEHANDLE, + " dispatch event=%u player=%u data=0x%08x databytes=%u", + event.event.eventid,event.event.playerid,event.event.data,event.event.databytes); + SEvtDispatch(REGISTERTYPE, + REGISTERSUBTYPE_SNETEVENT, + event.event.eventid, + &event.event); + if (event.event.data) + FREE(event.event.data); + } +} + +//=========================================================================== +static void CALLBACK SysOnCircuitCheck (SYSEVENTPTR event) { + if ((event->databytes == sizeof(DWORD)) && + (*(LPDWORD)event->data == SNET_NETWORKVERSION)) + ConnSendMessage(ConnFindByAddr(event->senderaddr), + TYPE_SYSTEM, + SYS_CIRCUITCHECKRESPONSE, + event->data, + event->databytes); +} + +//=========================================================================== +static void CALLBACK SysOnDropPlayer (SYSEVENTPTR event) { + SYSEVENTDATA_DROPPLAYERPTR eventdataptr = (SYSEVENTDATA_DROPPLAYERPTR)event->data; + + // MARK THE PLAYER AS LEAVING. WE DON'T ACTUALLY REMOVE HIM FROM THE + // GAME, OR SEND A USER-LEVEL NOTIFICATION, UNTIL THE APPLICATION HAS + // PROCESSED ALL REMAINING MESSAGES FROM THIS PLAYER. + CONNPTR conn = ConnFindByPlayerId(eventdataptr->playerid); + if (conn && (conn->playerid != NOPLAYER)) { + conn->flags |= PF_LEAVING; + conn->finalsequence = (WORD)eventdataptr->finalsequence; + conn->exitcode = eventdataptr->exitcode; + } + +} + +//=========================================================================== +static void CALLBACK SysOnNewGameOwner (SYSEVENTPTR event) { + + // REMOVE OWNERSHIP FROM THE EXISTING GAME OWNER + for (BOOL local = TRUE; local >= FALSE; --local) { + LISTPTR(CONNREC) list = local ? &s_conn_local + : &s_conn_connlist; + ITERATELISTPTR(CONNREC,list,curr) + curr->gameowner = FALSE; + } + + // MAKE THE SENDER THE NEW GAME OWNER + DWORD playerid = *(LPDWORD)event->data; + CONNPTR conn = ConnFindByPlayerId(playerid); + if (conn) + conn->gameowner = TRUE; + +} + +//=========================================================================== +static void CALLBACK SysOnPing (SYSEVENTPTR event) { + ConnSendMessage(ConnFindByAddr(event->senderaddr), + TYPE_SYSTEM, + SYS_PINGRESPONSE, + event->data, + event->databytes); +} + +//=========================================================================== +static void CALLBACK SysOnPingResponse (SYSEVENTPTR event) { + CONNPTR conn = ConnFindByAddr(event->senderaddr); + DWORD currtime = GetTickCount(); + if (conn) { + conn->latency = currtime-conn->lastpingtime; + conn->peaklatency = max(conn->peaklatency,conn->latency); + } +} + +//=========================================================================== +static void CALLBACK SysOnPlayerInfo (SYSEVENTPTR event) { + SYSEVENTDATA_PLAYERINFOPTR eventdataptr = (SYSEVENTDATA_PLAYERINFOPTR)event->data; + SNETADDRPTR addr = &eventdataptr->addr; + + // IF THIS IS THE PLAYER INFO FOR THE SYSTEM SENDING THE PACKET, USE THE + // PACKET'S ORIGIN ADDRESS RATHER THAN THE ONE IN THE PLAYER INFORMATION, + // BECAUSE THE SENDER PRESUMABLY DOESN'T KNOW HIS OWN ADDRESS. + if (eventdataptr->playerid == event->senderplayerid) + addr = event->senderaddr; + + // OTHERWISE, IF THIS IS THE PLAYER INFO FOR A THIRD PARTY SYSTEM, THEN + // RESET THE CONNECTION RECORD FOR THAT SYSTEM. + else + ConnFree(ConnFindByAddr(addr)); + + // UPDATE THE PLAYER INFORMATION + CONNPTR conn = ConnFindByAddr(addr); + CONNPTR local = ConnFindLocal(); + if (conn && local) { + conn->flags = eventdataptr->flags; + conn->playerid = (BYTE)eventdataptr->playerid; + conn->gameowner = eventdataptr->gameowner; + conn->incomingsequence[TYPE_TURN] = (WORD)eventdataptr->startingturn; + conn->availablesequence[TYPE_TURN] = (WORD)eventdataptr->startingturn; + conn->outgoingsequence[TYPE_TURN] = local->outgoingsequence[TYPE_TURN]; + if ((conn->incomingsequence[TYPE_TURN] != local->incomingsequence[TYPE_TURN]) && + ((WORD)(conn->incomingsequence[TYPE_TURN]-local->incomingsequence[TYPE_TURN]) < 0x7FFF)) + conn->flags |= PF_JOINING; + CopyMemory(&conn->addr,addr,sizeof(SNETADDR)); + SStrCopy(conn->name, + eventdataptr->namedesc, + SNETSPI_MAXSTRINGLENGTH); + SStrCopy(conn->desc, + eventdataptr->namedesc+SStrLen(eventdataptr->namedesc)+1, + SNETSPI_MAXSTRINGLENGTH); + } + + // IF THIS IS A NEW PLAYER, SEND HIM ALL OF OUR TURNS FROM HIS STARTING + // TURN NUMBER + { + MESSAGEPTR currmsg; + currmsg = local->oldturns.Head(); + while (currmsg) { + if ((WORD)(currmsg->data->header.sequence-eventdataptr->startingturn) <= 0x7FFF) + ConnResendMessage(conn,currmsg->data,currmsg->databytes); + currmsg = currmsg->Next(); + } + currmsg = local->incomingqueue[TYPE_TURN].Head(); + while (currmsg) { + if ((WORD)(currmsg->data->header.sequence-eventdataptr->startingturn) <= 0x7FFF) + ConnResendMessage(conn,currmsg->data,currmsg->databytes); + currmsg = currmsg->Next(); + } + } + + // QUEUE A USER-LEVEL EVENT + if ((s_game_playerid != NOPLAYER) && + conn && + (!(conn->flags & PF_JOINING))) + SysQueueUserEvent(SNET_EVENT_PLAYERJOIN, + eventdataptr->playerid, + NULL, + 0); + +} + +//=========================================================================== +static void CALLBACK SysOnPlayerJoin (SYSEVENTPTR event) { + SYSEVENTDATA_PLAYERJOINPTR eventdataptr = (SYSEVENTDATA_PLAYERJOINPTR)event->data; + + // IF THE GAME IS FULL OR NOT JOINABLE, SEND BACK A REJECTION NOTICE + { + DWORD activeplayers = 0; + SNetGetNumPlayers(NULL,NULL,&activeplayers); + if ((activeplayers >= s_game_playersallowed) || + (s_game_gamemode & SNET_GM_UNJOINABLE)) { + ConnSendMessage(ConnFindByAddr(event->senderaddr), + TYPE_SYSTEM, + SYS_PLAYERJOIN_REJECT, + NULL, + 0); + return; + } + } + + // BREAK OUT THE NAME, DESCRIPTION, AND PASSWORD + LPCSTR playername = eventdataptr->namedescpass; + LPCSTR playerdesc = playername+SStrLen(playername)+1; + LPCSTR gamepass = playerdesc+SStrLen(playerdesc)+1; + + // IF THE PASSWORD IS WRONG, SEND BACK A REJECTION NOTICE + if (s_game_gamepass[0] && _stricmp(s_game_gamepass,gamepass)) { + ConnSendMessage(ConnFindByAddr(event->senderaddr), + TYPE_SYSTEM, + SYS_PLAYERJOIN_REJECT, + NULL, + 0); + return; + } + + // DETERMINE THE PLAYER'S ID + BYTE playerid = 0; + do { + if (!ConnFindByPlayerId(playerid)) + break; + } while (++playerid != NOPLAYER); + if ((playerid == NOPLAYER) || (playerid >= s_game_playersallowed)) { + ConnSendMessage(ConnFindByAddr(event->senderaddr), + TYPE_SYSTEM, + SYS_PLAYERJOIN_REJECT, + NULL, + 0); + return; + } + + // ADD THE PLAYER + CONNPTR local = ConnFindLocal(); + CONNPTR conn = ConnFindByAddr(event->senderaddr); + if (!(conn && local)) + return; + { + conn->flags = 0; + conn->playerid = playerid; + conn->establishing = FALSE; + SStrCopy(conn->name,playername,SNETSPI_MAXSTRINGLENGTH); + SStrCopy(conn->desc,playerdesc,SNETSPI_MAXSTRINGLENGTH); + conn->incomingsequence[TYPE_TURN] = local->outgoingsequence[TYPE_TURN]; + conn->availablesequence[TYPE_TURN] = local->outgoingsequence[TYPE_TURN]; + conn->outgoingsequence[TYPE_TURN] = local->outgoingsequence[TYPE_TURN]; + if ((conn->incomingsequence[TYPE_TURN] != local->incomingsequence[TYPE_TURN]) && + ((WORD)(conn->incomingsequence[TYPE_TURN]-local->incomingsequence[TYPE_TURN]) < 0x7FFF)) + conn->flags |= PF_JOINING; + } + + // NOTIFY THE NETWORK PROVIDER OF THE NEW NUMBER OF PLAYERS IN THE GAME + { + DWORD activeplayers = 0; + SNetGetNumPlayers(NULL,NULL,&activeplayers); + DWORD gamemode = s_game_gamemode; + if (activeplayers >= s_game_playersallowed) + gamemode |= SNET_GM_FULL; + SNetSetGameMode(gamemode); + } + + // SEND BACK AN ACCEPT START NOTICE + DWORD startingturn = local->outgoingsequence[TYPE_TURN]; + { + SYSEVENTDATA_PLAYERJOIN_ACCEPTSTART data; + data.playerid = playerid; + data.playersallowed = s_game_playersallowed; + data.nextturn = startingturn; + data.gamemode = s_game_gamemode; + data.runningtime = (GetTickCount()-s_game_creationtime)/1000; + LPSTR currptr = data.namedescpass; + currptr += SStrCopy(currptr,s_game_gamename,SNETSPI_MAXSTRINGLENGTH)+1; + currptr += SStrCopy(currptr,s_game_gamedesc,SNETSPI_MAXSTRINGLENGTH)+1; + currptr += SStrCopy(currptr,s_game_gamepass,SNETSPI_MAXSTRINGLENGTH)+1; + ConnSendMessage(conn, + TYPE_SYSTEM, + SYS_PLAYERJOIN_ACCEPTSTART, + &data, + (LPBYTE)currptr-(LPBYTE)&data); + } + + // SEND BACK INFORMATION ABOUT THE LOCAL PLAYER + { + SYSEVENTDATA_PLAYERINFO data; + DWORD databytes = SysBuildPlayerInfo(&data,local,startingturn); + ConnSendMessage(conn, + TYPE_SYSTEM, + SYS_PLAYERINFO, + &data, + databytes); + } + + // SEND BACK INFORMATION FOR EACH OTHER PLAYER IN THE GAME + { + CONNPTR sendconn = s_conn_connlist.Head(); + while (sendconn) { + if ((sendconn != conn) && (sendconn->playerid != NOPLAYER)) { + SYSEVENTDATA_PLAYERINFO data; + DWORD databytes = SysBuildPlayerInfo(&data,sendconn,startingturn); + ConnSendMessage(conn, + TYPE_SYSTEM, + SYS_PLAYERINFO, + &data, + databytes); + } + sendconn = sendconn->Next(); + } + } + + // SEND BACK AN ACCEPT DONE NOTICE + ConnSendMessage(conn, + TYPE_SYSTEM, + SYS_PLAYERJOIN_ACCEPTDONE, + s_game_initdata, + s_game_initdatabytes); + + // SEND AN UPDATE MESSAGE TO ALL OTHER PLAYERS IN THE GAME + { + CONNPTR destconn = s_conn_connlist.Head(); + while (destconn) { + if ((destconn != conn) && (destconn->playerid != NOPLAYER)) { + SYSEVENTDATA_PLAYERINFO data; + DWORD databytes = SysBuildPlayerInfo(&data,conn,startingturn); + ConnSendMessage(destconn, + TYPE_SYSTEM, + SYS_PLAYERINFO, + &data, + databytes); + } + destconn = destconn->Next(); + } + } + + // SEND THE NEW PLAYER A COPY OF ALL OUR UNPROCESSED TURNS + { + MESSAGEPTR currmsg = local->incomingqueue[TYPE_TURN].Head(); + while (currmsg) { + ConnResendMessage(conn,currmsg->data,currmsg->databytes); + currmsg = currmsg->Next(); + } + } + + // QUEUE A USER-LEVEL EVENT + if (!(conn->flags & PF_JOINING)) + SysQueueUserEvent(SNET_EVENT_PLAYERJOIN,playerid,NULL,0); + +} + +//=========================================================================== +static void CALLBACK SysOnPlayerJoinAcceptStart (SYSEVENTPTR event) { + SYSEVENTDATA_PLAYERJOIN_ACCEPTSTARTPTR eventdataptr + = (SYSEVENTDATA_PLAYERJOIN_ACCEPTSTARTPTR)event->data; + CONNPTR conn = ConnFindLocal(); + if (conn) { + conn->playerid = (BYTE)eventdataptr->playerid; + conn->incomingsequence[TYPE_TURN] = (WORD)eventdataptr->nextturn; + conn->availablesequence[TYPE_TURN] = (WORD)eventdataptr->nextturn; + conn->outgoingsequence[TYPE_TURN] = (WORD)eventdataptr->nextturn; + PerfSet(SNET_PERFID_TURN,eventdataptr->nextturn); + } + s_game_playersallowed = eventdataptr->playersallowed; + s_game_gamemode = eventdataptr->gamemode; + s_game_creationtime = GetTickCount()-eventdataptr->runningtime*1000; + LPCSTR currptr = eventdataptr->namedescpass; + currptr += SStrCopy(s_game_gamename,currptr,SNETSPI_MAXSTRINGLENGTH)+1; + currptr += SStrCopy(s_game_gamedesc,currptr,SNETSPI_MAXSTRINGLENGTH)+1; + currptr += SStrCopy(s_game_gamepass,currptr,SNETSPI_MAXSTRINGLENGTH)+1; +} + +//=========================================================================== +static void CALLBACK SysOnPlayerJoinAcceptDone (SYSEVENTPTR event) { + CONNPTR conn = ConnFindLocal(); + if (conn) + s_game_playerid = conn->playerid; + if (s_game_initdata) { + FREE(s_game_initdata); + s_game_initdata = NULL; + } + s_game_initdatabytes = 0; + if (event->data && event->databytes) { + s_game_initdata = ALLOC(event->databytes); + s_game_initdatabytes = event->databytes; + CopyMemory(s_game_initdata,event->data,s_game_initdatabytes); + SysQueueUserEvent(SNET_EVENT_INITDATA, + s_game_playerid, + s_game_initdata, + s_game_initdatabytes); + } +} + +//=========================================================================== +static void CALLBACK SysOnPlayerJoinReject (SYSEVENTPTR event) { +} + +//=========================================================================== +static void CALLBACK SysOnPlayerLeave (SYSEVENTPTR event) { + SYSEVENTDATA_PLAYERLEAVEPTR eventdataptr = + (SYSEVENTDATA_PLAYERLEAVEPTR)event->data; + + // MARK THE PLAYER AS LEAVING. WE DON'T ACTUALLY REMOVE HIM FROM THE + // GAME, OR SEND A USER-LEVEL NOTIFICATION, UNTIL THE APPLICATION HAS + // PROCESSED ALL REMAINING TURNS FROM THIS PLAYER. + CONNPTR conn = ConnFindByAddr(event->senderaddr); + if (conn && (conn->playerid != NOPLAYER)) { + conn->flags |= PF_LEAVING; + conn->finalsequence = (WORD)eventdataptr->finalsequence; + conn->exitcode = eventdataptr->exitcode; + } + +} + +//=========================================================================== +static void SysProcessIncomingMessages (CONNPTR conn) { + while ((!conn->incomingqueue[TYPE_SYSTEM].IsEmpty()) && + (conn->incomingqueue[TYPE_SYSTEM].Head()->data->header.sequence + == conn->incomingsequence[TYPE_SYSTEM])) { + MESSAGEPTR message = conn->incomingqueue[TYPE_SYSTEM].Head(); + PACKETPTR pkt = (PACKETPTR)message->data; + TRACEOUT(TRACEHANDLE, + " processing system message: sequence=%04x event=%u player=%x", + pkt->header.sequence,pkt->header.subtype,pkt->header.playerid); + + // SIGNAL THE EVENT + if (pkt->header.subtype < SYSMSGS) + s_sys_event[pkt->header.subtype] = TRUE; + + // CALL INTERNAL THE SYSTEM EVENT HANDLER FOR THIS EVENT TYPE + { + SYSEVENT eventdata; + eventdata.senderplayerid = pkt->header.playerid; + eventdata.senderaddr = message->addr; + eventdata.eventid = pkt->header.subtype; + eventdata.data = pkt->data; + eventdata.databytes = pkt->header.bytes-sizeof(HEADER); + SEvtDispatch(REGISTERTYPE, + REGISTERSUBTYPE_SYSEVENT, + eventdata.eventid, + &eventdata); + } + + // ADJUST THE INCOMING SEQUENCE NUMBER + ++(conn->incomingsequence[TYPE_SYSTEM]); + + // FREE THE MESSAGE DATA + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [system message]", + message->addr,message->data,message->databytes); + s_spi->Free(message->addr,message->data,message->databytes); + + // FREE THE MESSAGE RECORD + conn->incomingqueue[TYPE_SYSTEM].DeleteNode(message); + + } +} + +//=========================================================================== +static void SysQueueUserEvent (DWORD eventid, + DWORD playerid, + LPVOID data, + DWORD databytes) { + USEREVENTPTR userevent = s_sys_usereventlist.NewNode(); + userevent->event.eventid = eventid; + userevent->event.playerid = playerid; + if (data && databytes) { + userevent->event.data = ALLOC(databytes); + CopyMemory(userevent->event.data,data,databytes); + userevent->event.databytes = databytes; + } +} + +//=========================================================================== +static BOOL SysWaitForMultipleEvents (DWORD numevents, + LPDWORD eventlist, + BOOL waitforall, + DWORD timeout) { + + // BLANK OUT THE RECEIVED EVENT ARRAY + ZeroMemory(s_sys_event,SYSMSGS*sizeof(BOOL)); + + // LOOP UNTIL THE CONDITIONS ARE SATISFIED OR THE TIMEOUT HAS ELAPSED + DWORD starttime = GetTickCount(); + BOOL firstiter = TRUE; + do { + + // IF THIS IS NOT THE FIRST ITERATION, SLEEP FOR A CLOCK TICK + if (!firstiter) + Sleep(10); + firstiter = FALSE; + + // PROCESS INCOMING PACKETS + RecvProcessExternalMessages(); + RecvProcessIncomingPackets(); + + // MAINTAIN CONNECTIONS + ConnMaintainConnections(); + + // IF THE CONDITIONS HAVE BEEN SATISFIED, RETURN SUCCESS + { + DWORD signalled = 0; + for (DWORD loop = 0; loop < numevents; ++loop) + if ((*(eventlist+loop) < SYSMSGS) && + s_sys_event[*(eventlist+loop)]) + ++signalled; + if ((signalled >= numevents) || + (signalled && !waitforall)) + return TRUE; + } + + } while ((timeout == INFINITE) || + (GetTickCount()-starttime < timeout)); + + return FALSE; +} + +/**************************************************************************** +* +* RECEIVING THREAD +* +***/ + +static HANDLE s_recv_event = (HANDLE)0; +static BOOL s_recv_shutdown = FALSE; +static HANDLE s_recv_thread = (HANDLE)0; + +static DWORD CALLBACK RecvThreadProc (LPVOID param); + +//=========================================================================== +static void RecvDestroy () { + if (s_recv_event && s_recv_thread) { + s_recv_shutdown = TRUE; + SetEvent(s_recv_event); + WaitForSingleObject(s_recv_thread,INFINITE); + s_recv_shutdown = FALSE; + CloseHandle(s_recv_event); + CloseHandle(s_recv_thread); + s_recv_event = (HANDLE)0; + s_recv_thread = (HANDLE)0; + } +} + +//=========================================================================== +static BOOL RecvInitialize (HANDLE *eventptr) { + + // CREATE THE EVENT + if (!s_recv_event) + s_recv_event = CreateEvent((LPSECURITY_ATTRIBUTES)NULL, + 0, + 0, + NULL); + + // CREATE THE THREAD + if (!s_recv_thread) { + s_recv_shutdown = FALSE; + DWORD threadid; + s_recv_thread = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + RecvThreadProc, + NULL, + 0, + &threadid); + SetThreadPriority(s_recv_thread,THREAD_PRIORITY_HIGHEST); + } + + // RETURN A HANDLE TO THE EVENT + if (eventptr) + *eventptr = s_recv_event; + + return (s_recv_event && s_recv_thread); +} + +//=========================================================================== +static void RecvProcessExternalMessages () { + for (;;) { + LPCSTR senderpath = NULL; + LPCSTR sendername = NULL; + LPCSTR message = NULL; + TRACEOUT(TRACEHANDLE, + " spiReceiveExternalMessage(*senderpath,*sendername,*message)"); + if (!s_spi->ReceiveExternalMessage(&senderpath,&sendername,&message)) + break; + if (!(senderpath && sendername && message)) + break; + + if ((!*senderpath) && (!*sendername)) + SysQueueUserEvent(SNET_EVENT_SERVERMESSAGE, + SNET_BROADCASTPLAYERID, + (LPVOID)message, + SStrLen(message)+1); + + TRACEOUT(TRACEHANDLE, + " spiFreeExternalMessage(0x%08x,0x%08x,0x%08x)", + senderpath,sendername,message); + s_spi->FreeExternalMessage(senderpath,sendername,message); + } +} + +//=========================================================================== +static void RecvProcessIncomingPackets () { + for (;;) { + SNETADDRPTR addr = NULL; + LPVOID data = NULL; + DWORD databytes = 0; + TRACEOUT(TRACEHANDLE," spiReceive(*addr,*data,*databytes)"); +/* note: restore this + if (!s_spi->Receive(&addr,&data,&databytes)) + break; +*/ +if (!s_spi->Receive(&data,&databytes,&addr)) +break; + if (!(addr && data)) + break; + PACKETPTR pkt = (PACKETPTR)data; + + // IF WE ARE IN DEBUG MODE, PRINT TRACE INFO FOR THE MESSAGE +#ifdef TRACING + TRACEOUT(TRACEHANDLE, + " addr=0x%08x data=0x%08x databytes=%u", + addr,data,databytes); + TRACEDUMPADDR(TRACEHANDLE, + "sender", + addr, + (databytes >= sizeof(HEADER)) ? pkt->header.playerid : NOPLAYER); + TRACEDUMP(TRACEHANDLE,&pkt->header,min(databytes,sizeof(HEADER))); + if (databytes > sizeof(HEADER)) + TRACEDUMP(TRACEHANDLE,&pkt->data[0],databytes-sizeof(HEADER)); +#endif + PerfAdd(SNET_PERFID_TOTALBYTESRECV,databytes); + + // FIND THE CONNECTION RECORD FOR THE SENDER OF THIS MESSAGE + CONNPTR local = ConnFindLocal(); + CONNPTR conn = (pkt->header.flags & MF_FORWARDED) + ? ConnFindByPlayerId(pkt->header.playerid) + : ConnFindByAddr(addr); + if (!(conn && local)) { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [no connection]", + addr,data,databytes); + s_spi->Free(addr,data,databytes); + continue; + } + + // CONFIRM THAT THIS IS A VALID MESSAGE. WE PERFORM THE FOLLOWING + // CHECKS: + // - CHECK FOR MINIMUM PACKET SIZE + // - COMPARE LENGTH IN HEADER TO SIZE OF PACKET + // - CHECK FOR VALID MESSAGE TYPE + // - CHECK PLAYER NUMBER + // - COMPUTE CHECKSUM + // - COMPARE SENDER ADDRESS TO ADDRESS OF THE PLAYER NUMBER IN HEADER + if ((databytes < sizeof(HEADER)) || + (databytes < pkt->header.bytes) || + (pkt->header.type >= TYPES) || + PktComputeChecksum(data,pkt->header.bytes)) { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [invalid message: corrupt]", + addr,data,databytes); + s_spi->Free(addr,data,databytes); + continue; + } + if ((!s_game_joining) && + (pkt->header.playerid != NOPLAYER) && + (!(pkt->header.flags & MF_FORWARDED)) && + (ConnFindByPlayerId(pkt->header.playerid) != conn)) { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [invalid message: bad sender]", + addr,data,databytes); + s_spi->Free(addr,data,databytes); + continue; + } + + // IF THIS IS AN INITIAL CONTACT MESSAGE, RESET THE SENDER'S CONNECTION + // RECORD AND INITIATE A CIRCUIT CHECK + if ((pkt->header.type == TYPE_SYSTEM) && + (pkt->header.subtype == SYS_INITIALCONTACT)) { + ConnFree(ConnFindByAddr(addr)); + if ((pkt->header.bytes == sizeof(HEADER)+sizeof(DWORD)) && + (*(LPDWORD)&pkt->data[0] == SNET_NETWORKVERSION)) { + CONNPTR conn = ConnFindByAddr(addr); + if (conn) { + conn->establishing = TRUE; + conn->incomingsequence[TYPE_SYSTEM] = 1; + conn->availablesequence[TYPE_SYSTEM] = 1; + conn->outgoingsequence[TYPE_SYSTEM] = 1; + DWORD networkversion = SNET_NETWORKVERSION; + ConnSendMessage(conn, + TYPE_SYSTEM, + SYS_CIRCUITCHECK, + &networkversion, + sizeof(DWORD)); + } + } + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [initial contact]", + addr,data,databytes); + s_spi->Free(addr,data,databytes); + continue; + } + + // IF THIS MESSAGE WAS NOT FORWARDED THEN RESET THE "LAST HEARD FROM" + // TIME STAMP OF THE PLAYER WHO SENT IT + if (!(pkt->header.flags & MF_FORWARDED)) + conn->lastreceivetime = GetTickCount(); + + // IF THIS MESSAGE CONTAINS A PIGGY-BACKED ACKNOWLEDGEMENT THEN + // FREE MESSAGES THAT WE SENT TO THE OTHER COMPUTER UP TO THE + // ACKNOWLEDGEMENT SEQUENCE + if (!(pkt->header.flags & MF_FORWARDED)) + ConnProcessAck(conn,pkt->header.type,pkt->header.acksequence); + + // IF THIS MESSAGE CONTAINS ONLY AN ACKNOWLEDGEMENT, AND NO ACTUAL + // DATA, THEN FREE IT + if (pkt->header.flags & MF_ACK) { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [ack only]", + addr,data,databytes); + s_spi->Free(addr,data,databytes); + continue; + } + + // IF THIS MESSAGE IS A RESEND REQUEST THEN FIND AND RESEND THE + // REQUESTED MESSAGE + if (pkt->header.flags & MF_RESENDREQUEST) { + MESSAGEPTR currmsg = NULL; + + // PROCESS REQUESTS TO RESEND ONE OF OUR OWN MESSAGES OR TURNS + if ((pkt->header.bytes == sizeof(HEADER)) || + (pkt->data[0] == (s_game_playerid & 0xFF))) + if (pkt->header.type == TYPE_TURN) { + currmsg = local->incomingqueue[TYPE_TURN].Head(); + while (currmsg && (currmsg->data->header.sequence != pkt->header.sequence)) + currmsg = currmsg->Next(); + if (!currmsg) { + currmsg = local->oldturns.Head(); + while (currmsg && (currmsg->data->header.sequence != pkt->header.sequence)) + currmsg = currmsg->Next(); + } + } + else { + currmsg = conn->outgoingqueue[pkt->header.type].Head(); + while (currmsg && (currmsg->data->header.sequence != pkt->header.sequence)) + currmsg = currmsg->Next(); + } + + // PROCESS REQUESTS TO FORWARD A TURN FROM ANOTHER PLAYER + else if (pkt->header.type == TYPE_TURN) { + CONNPTR findconn = ConnFindByPlayerId(pkt->data[0]); + if (findconn) { + currmsg = findconn->incomingqueue[TYPE_TURN].Head(); + while (currmsg && (currmsg->data->header.sequence != pkt->header.sequence)) + currmsg = currmsg->Next(); + if (!currmsg) { + currmsg = findconn->oldturns.Head(); + while (currmsg && (currmsg->data->header.sequence != pkt->header.sequence)) + currmsg = currmsg->Next(); + } + } + if (currmsg) { + currmsg->data->header.checksum = 0; + currmsg->data->header.flags |= MF_FORWARDED; + currmsg->data->header.checksum = PktGenerateChecksum(currmsg->data); + } + } + + // IF WE FOUND THE REQUESTED DATA, RESEND IT + if (currmsg) + ConnResendMessage(conn,currmsg->data,currmsg->databytes); + + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [resend request]", + addr,data,databytes); + s_spi->Free(addr,data,databytes); + continue; + } + + // IF THIS MESSAGE HAS ALREADY BEEN PROCESSED, IGNORE IT AND MARK THIS + // CONNECTION AS REQUIRING ANOTHER EXPLICIT ACK + if (((WORD)(conn->incomingsequence[pkt->header.type]-pkt->header.sequence) > 0) && + ((WORD)(conn->incomingsequence[pkt->header.type]-pkt->header.sequence) < 0x7FFF)) { + if (pkt->header.type != TYPE_TURN) { + conn->acksequence[pkt->header.type] = conn->availablesequence[pkt->header.type]-1; + conn->acktime[pkt->header.type] = GetTickCount(); + } + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [already processed]", + addr,data,databytes); + s_spi->Free(addr,data,databytes); + continue; + } + + // CREATE A MESSAGE RECORD FOR THIS PACKET + MESSAGEPTR message = conn->incomingqueue[pkt->header.type].NewNode(LIST_UNLINKED); + message->addr = addr; + message->data = (PACKETPTR)data; + message->databytes = databytes; + message->sendtime = GetTickCount(); + message->resendtime = message->sendtime+s_spi_timetorequest-s_spi_timetoresend; + PerfAdd(SNET_PERFID_USERBYTESRECV,databytes-sizeof(HEADER)); + + // ADD THE MESSAGE TO THE APPROPRIATE INCOMING QUEUE IN SEQUENCE ORDER + { + MESSAGEPTR curr = conn->incomingqueue[pkt->header.type].Head(); + while (curr && + ((WORD)(pkt->header.sequence-curr->data->header.sequence) > 0) && + ((WORD)(pkt->header.sequence-curr->data->header.sequence) < 0x7FFF)) + curr = curr->Next(); + + // IF WE FOUND ANOTHER PACKET IN THE QUEUE WITH THE SAME SEQUENCE + // NUMBER, FREE THIS PACKET + if (curr && (pkt->header.sequence == curr->data->header.sequence)) { + TRACEOUT(TRACEHANDLE, + " spiFree(0x%08x,0x%08x,%u) [already received]", + addr,data,databytes); + conn->incomingqueue[pkt->header.type].DeleteNode(message); + s_spi->Free(addr,data,databytes); + continue; + } + + // OTHERWISE, LINK THIS PACKET INTO THE QUEUE + else + conn->incomingqueue[pkt->header.type].LinkNode(message,LIST_LINK_BEFORE,curr); + } + + // UPDATE THE AVAILABLE SEQUENCE NUMBER FOR THIS MESSAGE TYPE. + // IF THE AVAILABLE SEQUENCE NUMBER HAS CHANGED AND WE ARE NOT CURRENTLY + // SET TO SEND AN EXPLICIT ACKNOWLEDGEMENT, SET THE EXPLICIT ACK TIMER. + if (pkt->header.type != TYPE_TURN) { + WORD oldavailablesequence = conn->availablesequence[pkt->header.type]; + conn->availablesequence[pkt->header.type] = conn->incomingsequence[pkt->header.type]; + MESSAGEPTR curr = conn->incomingqueue[pkt->header.type].Head(); + while (curr && + (curr->data->header.sequence == conn->availablesequence[pkt->header.type])) { + conn->availablesequence[pkt->header.type]++; + curr = curr->Next(); + } + if ((conn->availablesequence[pkt->header.type] != oldavailablesequence) && + (!conn->acktime[pkt->header.type])) + conn->acktime[pkt->header.type] = GetTickCount(); + } + else { + + // FOR TURNS, WE DON'T ACKNOWLEDGE A TURN FROM ONE CONNECTION UNTIL + // WE HAVE RECEIVED IT FROM ALL CONNECTIONS. THAT WAY, OTHER COMPUTERS + // KEEP OLD TURNS AROUND SO THAT THEY CAN RESEND THEM ON BEHALF OF + // UNRESPONSIVE SYSTEMS. + WORD curravailablesequence = conn->availablesequence[pkt->header.type]; + { + BOOL receivedany; + BOOL receivedall; + do { + receivedany = FALSE; + receivedall = TRUE; + CONNPTR currconn = s_conn_connlist.Head(); + while (currconn) { + if ((currconn->playerid != NOPLAYER) && + ((!(currconn->flags & PF_JOINING)) || + ((LONG)(curravailablesequence-currconn->incomingsequence[TYPE_TURN]) >= 0))) { + MESSAGEPTR currmsg = currconn->incomingqueue[TYPE_TURN].Head(); + while (currmsg && + (currmsg->data->header.sequence != curravailablesequence)) + currmsg = currmsg->Next(); + if (currmsg) + receivedany = TRUE; + else + receivedall = FALSE; + } + currconn = currconn->Next(); + } + if (receivedany && receivedall) + ++curravailablesequence; + } while (receivedany && receivedall); + } + + // IF THE AVAILABLE SEQUENCE FOR TURNS HAS CHANGED, UPDATE ALL + // CONNECTIONS AND MARK EACH AS REQUIRING AN EXPLICIT ACKNOWLEDGEMENT. + { + CONNPTR currconn = s_conn_connlist.Head(); + while (currconn) { + if ((curravailablesequence != currconn->availablesequence[TYPE_TURN]) && + (currconn->playerid != NOPLAYER) && + ((!(currconn->flags & PF_JOINING)) || + ((LONG)(curravailablesequence-currconn->incomingsequence[TYPE_TURN]) >= 0))) { + currconn->availablesequence[TYPE_TURN] = curravailablesequence; + if (!currconn->acktime[TYPE_TURN]) + currconn->acktime[TYPE_TURN] = GetTickCount(); + } + currconn = currconn->Next(); + } + } + + } + + // IF THIS IS A SYSTEM MESSAGE, PROCESS SYSTEM MESSAGES IN ORDER + // FOR THIS CONNECTION + if (pkt->header.type == TYPE_SYSTEM) + SysProcessIncomingMessages(conn); + + } + +} + +//=========================================================================== +static DWORD CALLBACK RecvThreadProc (LPVOID param) { + DWORD wait = INFINITE; + for (;;) { + + // WAIT FOR AT LEAST ONE PACKET TO BE RECEIVED AND QUEUED + if (s_recv_shutdown) { + _endthreadex(0); + return 0; + } + BOOL msgwaiting = (WaitForSingleObject(s_recv_event,wait) == WAIT_OBJECT_0); + if (s_recv_shutdown) { + _endthreadex(0); + return 0; + } + + // ENTER THE API LOCK + s_api_critsect.Enter(); + if (!s_spi) { + s_api_critsect.Leave(); + _endthreadex(0); + return 0; + } + + // PROCESS ALL OUTSTANDING RECEIVED PACKETS + if (msgwaiting) { + TRACEOUT(TRACEHANDLE,"Background thread processing incoming packets:"); + RecvProcessExternalMessages(); + RecvProcessIncomingPackets(); + } + else + TRACEOUT(TRACEHANDLE,"Background thread maintaining connections:"); + + // MAINTAIN CONNECTIONS + wait = ConnMaintainConnections(); + + // LEAVE THE API LOCK + s_api_critsect.Leave(); + TRACEOUT(TRACEHANDLE," done"); + + } +} + +/**************************************************************************** +* +* USER INTERFACE FUNCTIONS +* +***/ + +//=========================================================================== +static PROVIDERINFOPTR UiFindProvider (LPCSTR desc) { + PROVIDERINFOPTR curr = s_spi_providerlist.Head(); + while (curr) + if (!strcmp(curr->desc,desc)) + return curr; + else + curr = curr->Next(); + return NULL; +} + +//=========================================================================== +static void UiGetProgramDescription (LPCSTR programname, + SNETVERSIONDATAPTR versionptr, + LPSTR buffer, + DWORD buffersize) { + + // ADD THE NAME OF THE PROGRAM + SStrCopy(buffer,programname,buffersize-2); + strcat(buffer," "); + + // DETERMINE THE NAME OF THIS PROGRAM'S EXE FILE + char programfilename[MAX_PATH] = ""; + GetModuleFileName((HMODULE)0,programfilename,MAX_PATH); + + // IF WE WERE GIVEN A HUMAN READABLE VERSION STRING, ADD THAT + if (versionptr && versionptr->versionstring && *versionptr->versionstring) + SStrPack(buffer,versionptr->versionstring,buffersize); + + // OTHERWISE, ADD THE HUMAN READABLE VERSION STRING FROM THE EXE FILE'S + // VERSION RESOURCE + else if (programfilename[0]) { + DWORD handle; + DWORD versioninfosize = GetFileVersionInfoSize((char *)programfilename,&handle); + LPVOID versioninfo = ALLOC(versioninfosize); + if (GetFileVersionInfo((char *)programfilename,handle,versioninfosize,versioninfo)) { + LPCTSTR info = NULL; + UINT bytes = 0; + if (VerQueryValueA(versioninfo, + "\\StringFileInfo\\040904b0\\ProductVersion", + (LPVOID *)&info, + &bytes) && + info && *info) + SStrPack(buffer,info,buffersize); + } + FREE(versioninfo); + } + +} + +//=========================================================================== +static BOOL UiLoadArtwork (SNETGETARTPROC artcallback, + DWORD providerid, + DWORD artid, + BOOL setpalette, + LPBYTE *data, + SIZE *size) { + *data = 0; + size->cx = 0; + size->cy = 0; + + // VERIFY THAT THE APPLICATION HAS REGISTERED AN ARTWORK CALLBACK + if (!artcallback) + return FALSE; + + // CALL THE ARTWORK CALLBACK TO DETERMINE THE IMAGE DIMENSIONS + int width; + int height; + int bitdepth; + if (!artcallback(providerid, + artid, + NULL, + NULL, + 0, + &width, + &height, + &bitdepth)) + return FALSE; + if (size) { + size->cx = width; + size->cy = height; + } + + // ALLOCATE MEMORY FOR THE IMAGE + DWORD bytes = width*height*bitdepth/8; + *data = (LPBYTE)ALLOC(bytes); + + // LOAD THE IMAGE + PALETTEENTRY pe[256]; + if (!artcallback(providerid, + artid, + &pe[0], + *data, + bytes, + &width, + &height, + &bitdepth)) { + FREE(*data); + *data = NULL; + return FALSE; + } + + // IF REQUESTED, UPDATE THE SYSTEM PALETTE + if (setpalette) + SDrawUpdatePalette(1,254,&pe[1]); + + return TRUE; +} + +//=========================================================================== +static BOOL CALLBACK UiSelectProviderDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + static LPBYTE background = NULL; + static LPBYTE buttontexture = NULL; + static UIPARAMSPTR uiparams = NULL; + switch (message) { + + case WM_COMMAND: + + // IF THE USER CLICKED THE CANCEL BUTTON, RETURN ZERO + if (LOWORD(wparam) == IDCANCEL) + SDlgEndDialog(window,0); + + // IF THE USER CLICKED THE CONNECT BUTTON, INITIALIZE THE SELECTED + // PROVIDER AND RETURNS ITS PROVIDER ID + else if (LOWORD(wparam) == IDOK) { + char buffer[256] = ""; + int cursel = SendDlgItemMessage(window,IDC_PROVIDERLIST,LB_GETCURSEL,0,0); + SendDlgItemMessageA(window,IDC_PROVIDERLIST,LB_GETTEXT,cursel,(LPARAM)(LPSTR)buffer); + PROVIDERINFOPTR ptr = UiFindProvider(buffer); + if (ptr) { + + // SAVE THIS AS THE NEW PREFERRED PROVIDER + SRegSaveValue("Network Providers","Preferred Provider",0,ptr->id); + + // BUILD A NEW INTERFACE DATA STRUCTURE CONTAINING OUR WINDOW + // HANDLE + SNETUIDATA interfacedata; + ZeroMemory(&interfacedata,sizeof(SNETUIDATA)); + if (uiparams->interfacedata) + CopyMemory(&interfacedata,uiparams->interfacedata,sizeof(SNETUIDATA)); + interfacedata.size = sizeof(SNETUIDATA); + interfacedata.parentwindow = window; + + // CALL THE SELECTED CALLBACK IF AVAILABLE + if (uiparams->interfacedata && uiparams->interfacedata->selectedcallback) + if (!uiparams->interfacedata->selectedcallback(ptr->id, + &ptr->caps, + &interfacedata, + uiparams->versiondata)) + break; + + // INITIALIZE THE PROVIDER + if (SNetInitializeProvider(ptr->id, + uiparams->programdata, + uiparams->playerdata, + &interfacedata, + uiparams->versiondata)) + SDlgEndDialog(window,ptr->id); + + } + } + + // IF THE USER HIGHLIGHTED A NEW LISTBOX ITEM, UPDATE + // THE STATIC TEXT. IF THE USER DOUBLE-CLICKED AN ITEM, + // POST AN 'OK' COMMAND. + else if (LOWORD(wparam) == IDC_PROVIDERLIST) + if (HIWORD(wparam) == LBN_SELCHANGE) + PostMessage(window,WM_USER,0,0); + else if (HIWORD(wparam) == LBN_DBLCLK) + PostMessage(window,WM_COMMAND,MAKELONG(IDOK,BN_CLICKED),(LPARAM)GetDlgItem(window,IDOK)); + + break; + + case WM_DESTROY: + if (background) { + FREE(background); + background = NULL; + } + if (buttontexture) { + FREE(buttontexture); + buttontexture = NULL; + } + break; + + case WM_INITDIALOG: + + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + + // LOAD THE ARTWORK FOR THIS DIALOG + { + SIZE size; + if (UiLoadArtwork(uiparams->interfacedata->artcallback, + 0, + SNET_ART_BACKGROUND, + 1, + &background, + &size)) { + SDlgSetBitmap(window, + NULL, + "", + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + background, + NULL, + size.cx, + size.cy); + int controllist[3] = {IDC_MAXPLAYERS,IDC_REQUIREMENTS,0}; + SDlgSetControlBitmaps(window, + &controllist[0], + NULL, + background, + &size, + SDLG_ADJUST_CONTROLPOS); + } + if (UiLoadArtwork(uiparams->interfacedata->artcallback, + 0, + SNET_ART_BUTTONTEXTURE, + 0, + &buttontexture, + &size)) { + int controllist[3] = {IDOK,IDCANCEL,0}; + SDlgSetControlBitmaps(window, + &controllist[0], + NULL, + buttontexture, + &size, + SDLG_ADJUST_VERTICAL); + } + } + + // FILL IN THE LIST BOX WITH THE LIST OF PROVIDERS + { + DWORD selectid = 0; + PROVIDERINFOPTR selectptr = NULL; + PROVIDERINFOPTR curr = s_spi_providerlist.Head(); + SRegLoadValue("Network Providers","Preferred Provider",0,&selectid); + while (curr) { + if (curr->id && + SpiMeetsMinimumCaps(&curr->caps,uiparams->mincaps)) { + SendDlgItemMessageA(window,IDC_PROVIDERLIST,LB_ADDSTRING,0,(LPARAM)(LPCSTR)curr->desc); + if (curr->id == selectid) + selectptr = curr; + } + curr = curr->Next(); + } + WPARAM selectindex = 0; + if (selectptr) + selectindex = (WPARAM)SendDlgItemMessage(window,IDC_PROVIDERLIST,LB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)selectptr->desc); + SendDlgItemMessage(window,IDC_PROVIDERLIST,LB_SETCURSEL,selectindex,0); + } + + // FILL IN THE PROGRAM DESCRIPTION + { + char buffer[256] = ""; + UiGetProgramDescription(uiparams->programdata->programname, + uiparams->versiondata, + buffer, + 256); + SetDlgItemTextA(window,IDC_PROGRAMDESCRIPTION,buffer); + } + + // UPDATE THE PLAYERS SUPPORTED AND REQUIREMENTS TEXT + PostMessage(window,WM_USER,0,0); + + return 1; + + case WM_USER: + { + + // FIND THE HIGHLIGHTED PROVIDER + char buffer[256] = ""; + int cursel = SendDlgItemMessage(window,IDC_PROVIDERLIST,LB_GETCURSEL,0,0); + SendDlgItemMessageA(window,IDC_PROVIDERLIST,LB_GETTEXT,cursel,(LPARAM)(LPSTR)buffer); + PROVIDERINFOPTR ptr = UiFindProvider(buffer); + if (!ptr) + break; + + // DISPLAY THE MAXIMUM NUMBER OF PLAYERS + { + char buffer[64]; + GetDlgItemTextA(window,IDC_MAXPLAYERS,buffer,63); + if (SStrChr(buffer,':')) + wsprintf(SStrChr(buffer,':')+1, + " %u", + min(uiparams->programdata->maxplayers,ptr->caps.maxplayers)); + SetDlgItemTextA(window,IDC_MAXPLAYERS,buffer); + } + + // DISPLAY THE REQUIREMENTS + { + char buffer[256]; + GetDlgItemTextA(window,IDC_REQUIREMENTS,buffer,255); + if (SStrChr(buffer,':')) + wsprintf(SStrChr(buffer,':')+1, + "\n%s", + ptr->req); + SetDlgItemTextA(window,IDC_REQUIREMENTS,buffer); + } + + } + break; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +#define ENTER_APILOCK_READ s_api_critsect.Enter() +#define ENTER_APILOCK_WRITE s_api_critsect.Enter() +#define FAILOUT_APILOCK_READ do { \ + TRACEOUT(TRACEHANDLE, \ + " [fail: %08x]", \ + SErrGetLastError()); \ + s_api_critsect.Leave(); \ + return FALSE; \ + } while (FALSE) +#define FAILOUT_APILOCK_WRITE do { \ + TRACEOUT(TRACEHANDLE, \ + " [fail: %08x]", \ + SErrGetLastError()); \ + s_api_critsect.Leave(); \ + return FALSE; \ + } while (FALSE) +#define LEAVE_APILOCK_READ s_api_critsect.Leave() +#define LEAVE_APILOCK_WRITE s_api_critsect.Leave() + +//=========================================================================== +BOOL APIENTRY SNetCreateGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamecategorybits, + LPVOID initdata, + DWORD initdatabytes, + DWORD maxplayers, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid) { + + // VALIDATE PARAMETERS + if (playerid) + *playerid = SNET_INVALIDPLAYERID+s_api_playeroffset; + + VALIDATEBEGIN; + VALIDATE(gamename); + VALIDATE(*gamename); + VALIDATE(maxplayers); + VALIDATE(playerid); + VALIDATEEND; + + // LOG THE CALL + ENTER_APILOCK_WRITE; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (!gamepassword) + gamepassword = ""; + if (!gamedescription) + gamedescription = ""; + if (!playername) + playername = ""; + if (!playerdescription) + playerdescription = ""; + TRACEOUT(TRACEHANDLE, + "SNetCreateGame(\"%s\",\"%s\",\"%s\",0x%08x,0x%08x,%u,%u,\"%s\",\"%s\",*playerid)", + gamename,gamepassword,gamedescription,gamecategorybits,initdata,initdatabytes,maxplayers,playername,playerdescription); + + // IF NO PLAYER NAME WAS PROVIDED, AND THE CURRENT NETWORK PROVIDER + // IS CAPABLE OF PROVIDING IT, THEN GET THE NAME OF THE LOGGED ON + // USER FROM THE NETWORK PROVIDER + char localplayername[SNETSPI_MAXSTRINGLENGTH] = ""; + char localplayerdesc[SNETSPI_MAXSTRINGLENGTH] = ""; + if ((!*playername) && s_spi->GetLocalPlayerName) { + s_spi->GetLocalPlayerName(localplayername, + SNETSPI_MAXSTRINGLENGTH, + localplayerdesc, + SNETSPI_MAXSTRINGLENGTH); + playername = localplayername; + playerdescription = localplayerdesc; + } + if (!*playername) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + return FALSE; + } + + // IF WE ARE ALREADY IN A GAME, LEAVE IT + if (s_game_playerid != NOPLAYER) + SNetLeaveGame(SNET_EXIT_AUTO_NEWGAME); + + // RESET THE CONNECTION TABLE + ConnDestroy(); + + // SET THE MAXIMUM NUMBER OF PLAYERS ALLOWED + s_game_playersallowed = maxplayers; + + // SAVE THE GAME NAME AND DESCRIPTION + SStrCopy(s_game_gamename,gamename,SNETSPI_MAXSTRINGLENGTH); + SStrCopy(s_game_gamedesc,gamedescription,SNETSPI_MAXSTRINGLENGTH); + SStrCopy(s_game_gamepass,gamepassword,SNETSPI_MAXSTRINGLENGTH); + s_game_creationtime = GetTickCount(); + s_game_categorybits = gamecategorybits; + + // SET THE GAME MODE + s_game_gamemode = 0; + if (*gamepassword) + s_game_gamemode |= SNET_GM_PRIVATE; + if (s_game_playersallowed <= 1) + s_game_gamemode |= SNET_GM_FULL; + + // SAVE THE INITIALIZATION DATA + if (s_game_initdata) + FREE(s_game_initdata); + s_game_initdata = ALLOC(initdatabytes); + s_game_initdatabytes = initdatabytes; + CopyMemory(s_game_initdata,initdata,initdatabytes); + + // ASSIGN THE LOCAL PLAYER A PLAYER ID, AND MARK HIM AS THE GAME OWNER + s_game_playerid = 0; + CONNPTR conn = ConnFindLocal(); + if (conn) { + conn->flags = 0; + conn->playerid = s_game_playerid; + conn->gameowner = TRUE; + SStrCopy(conn->name,playername ,SNETSPI_MAXSTRINGLENGTH); + SStrCopy(conn->desc,playerdescription,SNETSPI_MAXSTRINGLENGTH); + } + if (playerid) + *playerid = s_game_playerid+s_api_playeroffset; + + // BUILD THE CLIENT DATA BLOCK + BYTE clientdata[SNETSPI_MAXCLIENTDATA]; + DWORD clientdatabytes; + GameBuildClientData(clientdata, + &clientdatabytes); + + // START ADVERTISING THE GAME SO THAT OTHERS CAN JOIN IT + TRACEOUT(TRACEHANDLE, + " spiStartAdvertisingGame(\"%s\",\"%s\",\"%s\",%u,%u,0x%08x,0x%08x,0x%08x,%u)", + s_game_gamename, + s_game_gamepass, + s_game_gamedesc, + s_game_gamemode, + 0, + s_game_categorybits, + s_game_optcategorybits, + clientdata, + clientdatabytes); + if (!s_spi->StartAdvertisingGame(s_game_gamename, + s_game_gamepass, + s_game_gamedesc, + s_game_gamemode, + 0, + s_game_categorybits, + s_game_optcategorybits, + clientdata, + clientdatabytes)) { + // SERVICE PROVIDER IS RESPONSIBLE FOR CALLING SETLASTERROR() + DWORD lasterror = SErrGetLastError(); + SNetLeaveGame(SNET_EXIT_AUTO_JOINING); + SErrSetLastError(lasterror); + FAILOUT_APILOCK_WRITE; + } + + // MARK THE GAME AS ADVERTISED + s_game_gamemode |= SNET_GM_ADVERTISED; + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetDestroy () { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE,"SNetDestroy()"); + + // IF WE ARE IN A GAME, LEAVE IT + if (s_game_playerid != NOPLAYER) + SNetLeaveGame(SNET_EXIT_AUTO_SHUTDOWN); + + // TERMINATE THE RECEIVE THREAD + LEAVE_APILOCK_WRITE; + RecvDestroy(); + ENTER_APILOCK_WRITE; + + // REMOVE ALL MESSAGES FROM THE SYSTEM MESSAGE QUEUE + SysDestroy(); + + // UNREGISTER ALL EVENT HANDLERS + SEvtUnregisterType(REGISTERTYPE,REGISTERSUBTYPE_SNETEVENT); + SEvtUnregisterType(REGISTERTYPE,REGISTERSUBTYPE_SYSEVENT); + + // DESTROY ALL CONNECTIONS + ConnDestroy(); + + // UNBIND FROM THE SERVICE PROVIDER AND CLEAR THE PROVIDER LIST + SpiDestroy(TRUE); + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetDropPlayer (DWORD playerid, DWORD exitcode) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetDropPlayer(%u,0x%08x)", + playerid,exitcode); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if ((playerid == NOPLAYER) || + (playerid == s_game_playerid)) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // FIND THE REFERENCED PLAYER + CONNPTR conn = ConnFindByPlayerId(playerid); + if (!conn) { + SErrSetLastError(SNET_ERROR_INVALID_PLAYER); + FAILOUT_APILOCK_WRITE; + } + + // MARK THE PLAYER AS LEAVING + conn->flags |= PF_LEAVING; + conn->finalsequence = conn->incomingsequence[TYPE_TURN]; + conn->exitcode = exitcode; + + // SEND A DROP PLAYER MESSAGE TO ALL OTHER PLAYERS + { + CONNPTR checkconn = s_conn_connlist.Head(); + while (checkconn) { + if ((checkconn != conn) && + (checkconn->playerid != NOPLAYER)) { + SYSEVENTDATA_DROPPLAYER eventdata; + eventdata.playerid = playerid; + eventdata.finalsequence = conn->incomingsequence[TYPE_TURN]; + eventdata.exitcode = exitcode; + ConnSendMessage(checkconn, + TYPE_SYSTEM, + SYS_DROPPLAYER, + &eventdata, + sizeof(SYSEVENTDATA_DROPPLAYER)); + } + checkconn = checkconn->Next(); + } + } + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetEnumDevices (SNETENUMDEVICESPROC callback) { + VALIDATEBEGIN; + VALIDATE(callback); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetEnumDevices(0x%08x)", + callback); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + + // MAKE A LOCAL COPY OF ALL DEVICES + SNETSPI_DEVICELISTPTR devicearray = NULL; + DWORD devices = 0; + { + + // LOCK THE DEVICE LIST + SNETSPI_DEVICELISTPTR head; + TRACEOUT(TRACEHANDLE," spiLockDeviceList(*devicelist)"); + if (!s_spi->LockDeviceList(&head)) { + // SERVICE PROVIDER IS RESPONSIBLE FOR CALLING SETLASTERROR() + FAILOUT_APILOCK_READ; + } + + // DETERMINE THE TOTAL NUMBER OF DEVICES + { + SNETSPI_DEVICELISTPTR curr = head; + while (curr) { + ++devices; + curr = curr->next; + } + } + + // ALLOCATE AN ARRAY TO HOLD THE DEVICES + if (devices) { + devicearray = (SNETSPI_DEVICELISTPTR)ALLOC(devices*sizeof(SNETSPI_DEVICELIST)); + + // COPY THE DEVICES + SNETSPI_DEVICELISTPTR source = head; + SNETSPI_DEVICELISTPTR dest = devicearray; + while (source) { + CopyMemory(dest,source,sizeof(SNETSPI_DEVICELIST)); + dest->next = dest+1; + dest = dest->next; + source = source->next; + } + + } + + // UNLOCK THE DEVICE LIST + TRACEOUT(TRACEHANDLE, + " spiUnlockDeviceList(0x%08x)", + head); + s_spi->UnlockDeviceList(head); + + } + + // LEAVE THE API LOCK + LEAVE_APILOCK_READ; + + // IF THERE WERE NO DEVICES, RETURN NOW + if (!(devices && devicearray)) + return TRUE; + + // CALL THE ENUMERATION FUNCTION ONCE FOR EACH DEVICE + { + SNETSPI_DEVICELISTPTR curr = devicearray; + while (devices--) { + TRACEOUT(TRACEHANDLE, + " callback(0x%08x,\"%s\",\"%s\")", + curr->deviceid,curr->devicename,curr->devicedescription); + if (callback(curr->deviceid,curr->devicename,curr->devicedescription)) + curr = curr->next; + else + devices = 0; + } + } + + // FREE THE LOCAL COPY + FREE(devicearray); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetEnumGames (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESPROC callback, + DWORD *hintnextcall) { + VALIDATEBEGIN; + VALIDATE(callback); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetEnumGames(0x%08x,0x%08x,0x%08x,*hintnextcall)", + categorybits,categorymask,callback); + + // VALIDATE PARAMETERS + if (hintnextcall) + *hintnextcall = 0; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + + // MAKE A LOCAL COPY OF ALL MATCHING GAMES + SNETSPI_GAMELISTPTR gamearray = NULL; + DWORD games = 0; + GameCopyGameList(categorybits, + categorymask, + &gamearray, + &games, + hintnextcall); + + // LEAVE THE API LOCK + LEAVE_APILOCK_READ; + + // CALL THE ENUMERATION FUNCTION ONCE FOR EACH GAME + { + SNETSPI_GAMELISTPTR curr = gamearray; + while (games--) { + TRACEOUT(TRACEHANDLE, + " callback(0x%08x,\"%s\",\"%s\")", + curr->gameid,curr->gamename,curr->gamedescription); + TRACEDUMP(TRACEHANDLE,&curr->owner,sizeof(SNETADDR)); + if (callback(curr->gameid,curr->gamename,curr->gamedescription)) + curr = curr->next; + else + games = 0; + } + } + + // FREE THE LOCAL COPY + FREEIFUSED(gamearray); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetEnumGamesEx (DWORD categorybits, + DWORD categorymask, + SNETENUMGAMESEXPROC callback, + DWORD *hintnextcall) { + VALIDATEBEGIN; + VALIDATE(callback); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetEnumGamesEx(0x%08x,0x%08x,0x%08x,*hintnextcall)", + categorybits,categorymask,callback); + + // VALIDATE PARAMETERS + if (hintnextcall) + *hintnextcall = 0; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + + // MAKE A LOCAL COPY OF ALL MATCHING GAMES + SNETSPI_GAMELISTPTR gamearray = NULL; + DWORD games = 0; + GameCopyGameList(categorybits, + categorymask, + &gamearray, + &games, + hintnextcall); + + // LEAVE THE API LOCK + LEAVE_APILOCK_READ; + + // CALL THE ENUMERATION FUNCTION ONCE FOR EACH GAME + { + SNETSPI_GAMELISTPTR curr = gamearray; + SNETGAME gamedata; + while (games--) { + GameBuildGameData(&gamedata,curr); + TRACEOUT(TRACEHANDLE, + " callback(0x%08x)", + &gamedata); + TRACEDUMP(TRACEHANDLE,&curr->owner,sizeof(SNETADDR)); + if (callback(&gamedata)) + curr = curr->next; + else + games = 0; + } + } + + // FREE THE LOCAL COPY + FREEIFUSED(gamearray); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetEnumProviders (SNETCAPSPTR mincaps, + SNETENUMPROVIDERSPROC callback) { + VALIDATEBEGIN; + VALIDATE(callback); + VALIDATE((!mincaps) || (mincaps->size == sizeof(SNETCAPS))); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetEnumProviders(mincaps,0x%08x)", + callback); + + // BUILD A LIST OF PROVIDERS IF WE DON'T ALREADY HAVE ONE + SpiFindAllProviders(); + + // CALL THE CALLBACK FUNCTION ONCE FOR EACH PROVIDER IN THE LIST + // WHICH MEETS THE MINIMUM CAPABILITIES + PROVIDERINFOPTR curr = s_spi_providerlist.Head(); + while (curr) { + if (curr->id && curr->desc && *curr->desc && + SpiMeetsMinimumCaps(&curr->caps,mincaps)) { + TRACEOUT(TRACEHANDLE, + " callback(0x%08x,\"%s\",\"%s\",caps)", + curr->id,curr->desc,curr->req); + if (!callback(curr->id,curr->desc,curr->req,&curr->caps)) + curr = NULL; + } + if (s_spi_providersfound && (!s_spi_providerlist.IsEmpty()) && curr) + curr = curr->Next(); + else + curr = NULL; + } + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetGameInfo (DWORD index, + LPVOID buffer, + DWORD buffersize, + DWORD *byteswritten) { + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetGetGameInfo(%u,0x%08x,%u,*byteswritten)", + index,buffer,buffersize); + + // VALIDATE PARAMETERS + if (buffer && buffersize) + ZeroMemory(buffer,buffersize); + if (byteswritten) + *byteswritten = NULL; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_READ; + } + + // FIND THE REQUESTED INFORMATION + LPVOID info = NULL; + DWORD infobytes = 0; + BOOL nullterm = FALSE; + switch (index) { + + case SNET_INFO_GAMENAME: + info = s_game_gamename; + infobytes = SStrLen(s_game_gamename)+1; + nullterm = TRUE; + break; + + case SNET_INFO_GAMEPASSWORD: + info = s_game_gamepass; + infobytes = SStrLen(s_game_gamepass)+1; + nullterm = TRUE; + break; + + case SNET_INFO_GAMEDESCRIPTION: + info = s_game_gamedesc; + infobytes = SStrLen(s_game_gamedesc)+1; + nullterm = TRUE; + break; + + case SNET_INFO_GAMEMODE: + info = &s_game_gamemode; + infobytes = sizeof(s_game_gamemode); + break; + + case SNET_INFO_INITDATA: + info = s_game_initdata; + infobytes = s_game_initdatabytes; + break; + + case SNET_INFO_MAXPLAYERS: + info = &s_game_playersallowed; + infobytes = sizeof(s_game_playersallowed); + break; + + } + if (!info) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_READ; + } + + // IF THE USER DIDN'T PASS A BUFFER, SIMPLY RETURN THE NUMBER OF BYTES + // OF INFORMATION WE HAVE AVAILABLE + if (!(buffer && buffersize)) { + if (byteswritten) + *byteswritten = infobytes; + } + + // OTHERWISE, COPY THE INFORMATION INTO THE USER'S BUFFER + else { + CopyMemory(buffer,info,min(buffersize,infobytes)); + if (byteswritten) + *byteswritten = min(buffersize,infobytes); + if (nullterm) + *((LPSTR)buffer+buffersize-1) = 0; + } + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetNetworkLatency (DWORD measurementtype, + DWORD *result) { + VALIDATEBEGIN; + VALIDATE(result); + VALIDATE(measurementtype >= SNET_LMT_EXPECTED); + VALIDATE(measurementtype <= SNET_LMT_PEAK); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetGetNetworkLatency(%u,*result)", + measurementtype); + + // VALIDATE PARAMETERS + if (result) + *result = 0; + if (!(s_spi && s_spi_providerptr)) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + + // RETURN THE LATENCY + switch (measurementtype) { + + case SNET_LMT_EXPECTED: + *result = s_spi_providerptr->caps.latencyms; + break; + + case SNET_LMT_CURRENT: + case SNET_LMT_PEAK: + { + CONNPTR conn = s_conn_connlist.Head(); + while (conn) { + if (conn->playerid != NOPLAYER) { + DWORD latency = 0; + if (measurementtype == SNET_LMT_CURRENT) + latency = conn->peaklatency; + if (latency < conn->latency) + latency = conn->latency; + if (latency > *result) + *result = latency; + } + conn = conn->Next(); + } + } + break; + + default: + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_READ; + + } + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetNumPlayers (DWORD *firstplayerid, + DWORD *lastplayerid, + DWORD *activeplayers) { + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetGetNumPlayers(*firstplayerid,*lastplayerid,*activeplayers)"); + + // VALIDATE PARAMETERS + if (firstplayerid) + *firstplayerid = SNET_INVALIDPLAYERID+s_api_playeroffset; + if (lastplayerid) + *lastplayerid = SNET_INVALIDPLAYERID+s_api_playeroffset; + if (activeplayers) + *activeplayers = 0; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_READ; + } + + // START WITH THE LOCAL PLAYER + if (firstplayerid) + *firstplayerid = s_game_playerid+s_api_playeroffset; + if (lastplayerid) + *lastplayerid = s_game_playerid+s_api_playeroffset; + if (activeplayers) + *activeplayers = 1; + + // TAKE INTO ACCOUNT ALL OTHER ACTIVE PLAYERS + { + CONNPTR conn = s_conn_connlist.Head(); + while (conn) { + if (conn->playerid != NOPLAYER) { + if (firstplayerid) + *firstplayerid = min(conn->playerid+s_api_playeroffset,*firstplayerid); + if (lastplayerid) + *lastplayerid = max(conn->playerid+s_api_playeroffset,*lastplayerid); + if (activeplayers) + ++*activeplayers; + } + conn = conn->Next(); + } + } + + // LOG THE RETURNED INFORMATION + if (firstplayerid) + TRACEOUT(TRACEHANDLE," firstplayerid=%u",*firstplayerid); + if (lastplayerid) + TRACEOUT(TRACEHANDLE," lastplayerid=%u",*lastplayerid); + if (activeplayers) + TRACEOUT(TRACEHANDLE," activeplayers=%u",*activeplayers); + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetOwnerId (DWORD *playerid) { + VALIDATEBEGIN; + VALIDATE(playerid); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEPEND(TRACEHANDLE,"SNetGetOwnerId(*playerid)"); + + // VALIDATE PARAMETERS + *playerid = SNET_INVALIDPLAYERID+s_api_playeroffset; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // CHECK FOR TRANSFER OF OWNERSHIP + if (s_game_playerid != NOPLAYER) + GameProcessLeavingPlayers(); + + // FIND THE GAME OWNER + CONNPTR local = ConnFindLocal(); + if (!local) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + CONNPTR conn = local; + if (!(conn && conn->gameowner)) { + conn = s_conn_connlist.Head(); + while (conn && !conn->gameowner) + conn = conn->Next(); + } + if (!(conn && conn->gameowner)) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // RETURN THE GAME OWNER'S PLAYER ID + *playerid = conn->playerid+s_api_playeroffset; + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetOwnerTurnsWaiting (DWORD *turns) { + VALIDATEBEGIN; + VALIDATE(turns); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEPEND(TRACEHANDLE,"SNetGetOwnerTurnsWaiting(*turns)"); + *turns = 0; + + // GET THE PLAYER ID OF THE GAME OWNER + DWORD playerid; + if (!SNetGetOwnerId(&playerid)) { + // SNETGETOWNERID() IS RESPONSIBLE FOR CALLING SETLASTERROR() + FAILOUT_APILOCK_WRITE; + } + playerid -= s_api_playeroffset; + + // FIND THE CONNECTION RECORD ASSOCIATED WITH THE GAME OWNER + CONNPTR conn = ConnFindByPlayerId(playerid); + if (!(conn && conn->gameowner)) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // CLEAR OUT ANY UNNEEDED OR ALREADY PROCESSED TURNS FROM THE GAME OWNER + ConnClearOldTurns(conn); + + // DETERMINE THE NUMBER OF TURNS WE STILL HAVE QUEUED FROM THE GAME OWNER + MESSAGEPTR message = conn->incomingqueue[TYPE_TURN].Head(); + while (message) { + ++*turns; + message = message->Next(); + } + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetPerformanceData (DWORD counterid, + DWORD *countervalue, + DWORD *countertype, + LONG *counterscale, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + VALIDATEBEGIN; + VALIDATE(counterid); + VALIDATE(counterid < SNET_PERFIDNUM); + VALIDATE(countervalue); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetGetPerformanceData(%u,*countervalue,*countertype,*counterscale,*measurementtime,*measurementfreq)", + counterid); + + // SET THE VALUES BASED ON OUR INTERNAL PERFORMANCE DATA + *countervalue = s_perf_data[counterid].value; + if (countertype) + *countertype = s_perf_data[counterid].type; + if (counterscale) + *counterscale = s_perf_data[counterid].scale; + if (measurementtime) { + SYSTEMTIME systime; + GetSystemTime(&systime); + SystemTimeToFileTime(&systime,(FILETIME *)measurementtime); + } + if (measurementfreq) { + measurementfreq->LowPart = 10000000; + measurementfreq->HighPart = 0; + } + + // IF THIS COUNTER IS PROVIDER SPECIFIC, ALLOW THE CURRENT PROVIDER TO + // OVERWRITE OUR RESULTS + if (s_perf_data[counterid].providerspecific && s_spi) { + LARGE_INTEGER localtime; + LARGE_INTEGER localfreq; + if (!measurementtime) + measurementtime = &localtime; + if (!measurementfreq) + measurementfreq = &localfreq; + TRACEOUT(TRACEHANDLE, + " spiGetPerformanceData(%u,*countervalue,*measurementtime,*measurementfreq)", + counterid); + s_spi->GetPerformanceData(counterid,countervalue,measurementtime,measurementfreq); + } + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetPlayerCaps (DWORD playerid, + SNETCAPSPTR caps) { + VALIDATEBEGIN; + VALIDATE(caps); + VALIDATE(caps->size == sizeof(SNETCAPS)); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetGetPlayerCaps(%u,*caps)", + playerid); + + // VALIDATE PARAMETERS + ZeroMemory(((LPDWORD)caps)+1,sizeof(SNETCAPS)-sizeof(DWORD)); + if (!(s_spi && s_spi_providerptr)) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_READ; + } + + // FIND THE REQUESTED PLAYER + CONNPTR conn = ConnFindByPlayerId(playerid-s_api_playeroffset); + if (!conn) { + SErrSetLastError(SNET_ERROR_INVALID_PLAYER); + FAILOUT_APILOCK_READ; + } + + // COPY THE PROVIDER CAPS + CopyMemory(caps,&s_spi_providerptr->caps,sizeof(SNETCAPS)); + + // ADD THE USER'S LATENCY + if (conn->latency) + caps->latencyms = conn->latency; + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetPlayerName (DWORD playerid, + LPSTR buffer, + DWORD buffersize) { + VALIDATEBEGIN; + VALIDATE(buffer); + VALIDATE(buffersize); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetGetPlayerName(%u,0x%08x,%u)", + playerid,buffer,buffersize); + + // VALIDATE PARAMETERS + *buffer = 0; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_READ; + } + + // FIND THE REQUESTED PLAYER + CONNPTR conn = ConnFindByPlayerId(playerid-s_api_playeroffset); + if ((!conn) || (conn->flags & PF_JOINING)) { + SErrSetLastError(SNET_ERROR_INVALID_PLAYER); + FAILOUT_APILOCK_READ; + } + + // RETURN THE PLAYER'S NAME + SStrCopy(buffer,conn->name,buffersize); + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetProviderCaps (SNETCAPSPTR caps) { + VALIDATEBEGIN; + VALIDATE(caps); + VALIDATE(caps->size == sizeof(SNETCAPS)); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEOUT(TRACEHANDLE, + "SNetGetProviderCaps(*caps)"); + + // VALIDATE PARAMETERS + ZeroMemory(((LPDWORD)caps)+1,sizeof(SNETCAPS)-sizeof(DWORD)); + if (!(s_spi && s_spi_providerptr)) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + + // COPY THE PROVIDER CAPS + CopyMemory(caps,&s_spi_providerptr->caps,sizeof(SNETCAPS)); + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetGetTurnsInTransit (DWORD *turns) { + VALIDATEBEGIN; + VALIDATE(turns); + VALIDATEEND; + + ENTER_APILOCK_READ; + TRACEPEND(TRACEHANDLE,"SNetGetTurnsInTransit(*turns)"); + + // VALIDATE PARAMETERS + *turns = 0; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_READ; + } + + // FIND OUR PLAYER RECORD + CONNPTR conn = ConnFindLocal(); + if (!conn) { + SErrSetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + FAILOUT_APILOCK_READ; + } + + // DETERMINE THE NUMBER OF TURNS WE HAVE SENT OUT BEYOND WHAT WE HAVE + // PROCESSED + *turns = conn->outgoingsequence[TYPE_TURN] + -conn->incomingsequence[TYPE_TURN]; + + LEAVE_APILOCK_READ; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetInitializeDevice(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x)", + deviceid,programdata,playerdata,interfacedata,versiondata); + TRACEDUMPDATABLOCKS(TRACEHANDLE, + programdata,playerdata,interfacedata,versiondata); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_READ; + } + SNETPROGRAMDATA modprogramdata; + SNETPLAYERDATA modplayerdata; + SNETUIDATA modinterfacedata; + SNETVERSIONDATA modversiondata; + if (!SpiNormalizeDataBlocks(programdata,playerdata,interfacedata,versiondata, + &modprogramdata,&modplayerdata,&modinterfacedata,&modversiondata)) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_WRITE; + } + + // INITIALIZE THE DEVICE + if (!s_spi->InitializeDevice(deviceid, + &modprogramdata, + &modplayerdata, + &modinterfacedata, + &modversiondata)) { + // SERVICE PROVIDER IS RESPONSIBLE FOR CALLING SETLASTERROR() + FAILOUT_APILOCK_WRITE; + } + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetInitializeProvider (DWORD providerid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "(using Storm build " __DATE__ " " __TIME__ ")"); + TRACEOUT(TRACEHANDLE, + "SNetInitializeProvider(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x)", + providerid,programdata,playerdata,interfacedata,versiondata); + TRACEDUMPDATABLOCKS(TRACEHANDLE, + programdata,playerdata,interfacedata,versiondata); + + // VALIDATE PARAMETERS + SNETPROGRAMDATA modprogramdata; + SNETPLAYERDATA modplayerdata; + SNETUIDATA modinterfacedata; + SNETVERSIONDATA modversiondata; + if (!SpiNormalizeDataBlocks(programdata,playerdata,interfacedata,versiondata, + &modprogramdata,&modplayerdata,&modinterfacedata,&modversiondata)) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_WRITE; + } + + // UNREGISTER ALL EXISTING EVENT HANDLERS + SEvtUnregisterType(REGISTERTYPE,REGISTERSUBTYPE_SNETEVENT); + SEvtUnregisterType(REGISTERTYPE,REGISTERSUBTYPE_SYSEVENT); + + // REGISTER DEFAULT EVENT HANDLERS +#define REGISTER(a,b) SEvtRegisterHandler(REGISTERTYPE, \ + REGISTERSUBTYPE_SYSEVENT, \ + (a), \ + 0, \ + (SEVTHANDLER)(b)) + REGISTER(SYS_CIRCUITCHECK ,SysOnCircuitCheck); + REGISTER(SYS_DROPPLAYER ,SysOnDropPlayer); + REGISTER(SYS_NEWGAMEOWNER ,SysOnNewGameOwner); + REGISTER(SYS_PING ,SysOnPing); + REGISTER(SYS_PINGRESPONSE ,SysOnPingResponse); + REGISTER(SYS_PLAYERINFO ,SysOnPlayerInfo); + REGISTER(SYS_PLAYERJOIN ,SysOnPlayerJoin); + REGISTER(SYS_PLAYERJOIN_ACCEPTSTART,SysOnPlayerJoinAcceptStart); + REGISTER(SYS_PLAYERJOIN_ACCEPTDONE ,SysOnPlayerJoinAcceptDone); + REGISTER(SYS_PLAYERJOIN_REJECT ,SysOnPlayerJoinReject); + REGISTER(SYS_PLAYERLEAVE ,SysOnPlayerLeave); +#undef REGISTER + + // INITIALIZE THE RECEIVING THREAD + HANDLE event = (HANDLE)0; + if (!RecvInitialize(&event)) { + SErrSetLastError(SNET_ERROR_MAX_THRDS_REACHED); + FAILOUT_APILOCK_WRITE; + } + + // INITIALIZE THE PROVIDER + if (!SpiInitialize(providerid, + &modprogramdata, + &modplayerdata, + &modinterfacedata, + &modversiondata, + event)) { + // EITHER SPIINITIALIZE() OR THE SERVICE PROVIDER IS RESPONSIBLE + // FOR CALLING SETLASTERROR() + FAILOUT_APILOCK_WRITE; + } + + // SAVE THE CATEGORY OPTIMIZATION HINT + s_game_optcategorybits = modprogramdata.optcategorybits; + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetJoinGame (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR playername, + LPCSTR playerdescription, + DWORD *playerid) { + if (playerid) + *playerid = SNET_INVALIDPLAYERID+s_api_playeroffset; + + VALIDATEBEGIN; + VALIDATE(playerid); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetJoinGame(0x%08x,\"%s\",\"%s\",\"%s\",\"%s\",*playerid)", + gameid,gamename,gamepassword,playername,playerdescription); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (!gamename) + gamename = ""; + if (!gamepassword) + gamepassword = ""; + if (!playername) + playername = ""; + if (!playerdescription) + playerdescription = ""; + + // IF NO PLAYER NAME WAS PROVIDED, AND THE CURRENT NETWORK PROVIDER + // IS CAPABLE OF PROVIDING IT, THEN GET THE NAME OF THE LOGGED ON + // USER FROM THE NETWORK PROVIDER + char localplayername[SNETSPI_MAXSTRINGLENGTH] = ""; + char localplayerdesc[SNETSPI_MAXSTRINGLENGTH] = ""; + if ((!*playername) && s_spi->GetLocalPlayerName) { + s_spi->GetLocalPlayerName(localplayername, + SNETSPI_MAXSTRINGLENGTH, + localplayerdesc, + SNETSPI_MAXSTRINGLENGTH); + playername = localplayername; + playerdescription = localplayerdesc; + } + if (!*playername) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + return FALSE; + } + + // IF WE ARE ALREADY IN A GAME, LEAVE IT + if (s_game_playerid != NOPLAYER) + SNetLeaveGame(SNET_EXIT_AUTO_NEWGAME); + + // RESET THE CONNECTION TABLE + ConnDestroy(); + + // GET THE ADDRESS OF THE GAME OWNER + SNETSPI_GAMELIST gameinfo; + TRACEOUT(TRACEHANDLE, + " spiGetGameInfo(0x%08x,\"%s\",\"%s\",*gameinfo)", + gameid,gamename,gamepassword); + if (!s_spi->GetGameInfo(gameid,gamename,gamepassword,&gameinfo)) { + // SERVICE PROVIDER IS RESPONSIBLE FOR CALLING SETLASTERROR() + FAILOUT_APILOCK_WRITE; + } + + // CREATE A CONNECTION RECORD FOR THE GAME OWNER AND SEND HIM AN + // INITIAL CONTACT MESSAGE + s_game_joining = TRUE; + CONNPTR ownerconn = ConnFindByAddr(&gameinfo.owner); + if (!ownerconn) { + s_game_joining = FALSE; + TRACEOUT(TRACEHANDLE," out of memory"); + SNetLeaveGame(SNET_EXIT_AUTO_JOINING); + SErrSetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + FAILOUT_APILOCK_WRITE; + } + ownerconn->establishing = TRUE; + ownerconn->incomingsequence[TYPE_SYSTEM] = 1; + ownerconn->availablesequence[TYPE_SYSTEM] = 1; + ownerconn->outgoingsequence[TYPE_SYSTEM] = 1; + { + DWORD netversion = SNET_NETWORKVERSION; + MESSAGEPTR msg = ConnSendMessage(ownerconn, + TYPE_SYSTEM, + SYS_INITIALCONTACT, + &netversion, + sizeof(DWORD)); + if (msg) { + ConnResendMessage(ownerconn,msg->data,msg->databytes); + ConnResendMessage(ownerconn,msg->data,msg->databytes); + } + ConnProcessAck(ownerconn,TYPE_SYSTEM,1); + } + + // WAIT FOR THE CIRCUIT CHECK MESSAGE FROM THE GAME OWNER + { + DWORD events[1] = {SYS_CIRCUITCHECK}; + if (!SysWaitForMultipleEvents(1,events,0,s_spi_timetoblock)) { + s_game_joining = FALSE; + TRACEOUT(TRACEHANDLE," host unreachable"); + SNetLeaveGame(SNET_EXIT_AUTO_JOINING); + SErrSetLastError(SNET_ERROR_HOST_UNREACHABLE); + FAILOUT_APILOCK_WRITE; + } + } + + // SEND A REQUEST TO JOIN + { + SYSEVENTDATA_PLAYERJOIN data; + LPSTR currptr = data.namedescpass; + currptr += SStrCopy(currptr,playername,SNETSPI_MAXSTRINGLENGTH)+1; + currptr += SStrCopy(currptr,playerdescription,SNETSPI_MAXSTRINGLENGTH)+1; + currptr += SStrCopy(currptr,gamepassword,SNETSPI_MAXSTRINGLENGTH)+1; + ConnSendMessage(ConnFindByAddr(&gameinfo.owner), + TYPE_SYSTEM, + SYS_PLAYERJOIN, + &data, + (LPBYTE)currptr-(LPBYTE)&data); + } + + // WAIT FOR AN ACCEPT OR REJECT MESSAGE FROM THE OWNER + { + DWORD events[2] = {SYS_PLAYERJOIN_ACCEPTDONE, + SYS_PLAYERJOIN_REJECT}; + if (!SysWaitForMultipleEvents(2,events,0,s_spi_timetoblock)) { + ownerconn->establishing = FALSE; + s_game_joining = FALSE; + TRACEOUT(TRACEHANDLE," host unreachable"); + SNetLeaveGame(SNET_EXIT_AUTO_JOINING); + SErrSetLastError(SNET_ERROR_HOST_UNREACHABLE); + FAILOUT_APILOCK_WRITE; + } + } + + // IF WE WERE REJECTED, RETURN FAILURE + if (s_game_playerid == NOPLAYER) { + ownerconn->establishing = FALSE; + s_game_joining = FALSE; + TRACEOUT(TRACEHANDLE," rejected"); + SNetLeaveGame(SNET_EXIT_AUTO_JOINING); + SErrSetLastError(SNET_ERROR_GAME_FULL); + FAILOUT_APILOCK_WRITE; + } + + // OTHERWISE, SAVE THE GAME CATEGORY + s_game_categorybits = gameinfo.gamecategorybits; + + // SET OUR PLAYER INFORMATION + CONNPTR conn = ConnFindLocal(); + if (conn) { + conn->playerid = s_game_playerid; + SStrCopy(conn->name,playername,SNETSPI_MAXSTRINGLENGTH); + SStrCopy(conn->desc,playerdescription,SNETSPI_MAXSTRINGLENGTH); + } + *playerid = s_game_playerid+s_api_playeroffset; + TRACEOUT(TRACEHANDLE," joined as player %u",*playerid); + + // DISPATCH ANY PENDING EVENTS + LEAVE_APILOCK_WRITE; + SysDispatchUserEvents(); + ENTER_APILOCK_WRITE; + + // COMPLETE THE JOIN PROCESS + ownerconn->establishing = FALSE; + s_game_joining = FALSE; + + // MAKE SURE WE ARE STILL IN A GAME + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_GAME_TERMINATED); + FAILOUT_APILOCK_WRITE; + } + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetLeaveGame (DWORD exitcode) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetLeaveGame(0x%08x)", + exitcode); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + + // FIND OUR PLAYER RECORD + CONNPTR conn = ConnFindLocal(); + if (!conn) { + SErrSetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + FAILOUT_APILOCK_WRITE; + } + + // IF WE ARE THE GAME OWNER, STOP ADVERTISING THE GAME + if (conn->gameowner) { + TRACEOUT(TRACEHANDLE," spiStopAdvertisingGame()"); + s_spi->StopAdvertisingGame(); + } + + // SEND MESSAGES TO ALL OTHER PLAYERS INFORMING THEM THAT WE'RE DROPPING + // OUT OF THE GAME + { + CONNPTR checkconn = s_conn_connlist.Head(); + while (checkconn) { + if (checkconn->playerid != NOPLAYER) { + SYSEVENTDATA_PLAYERLEAVE data; + data.finalsequence = checkconn->outgoingsequence[TYPE_TURN]; + data.exitcode = exitcode; + MESSAGEPTR msg = ConnSendMessage(checkconn, + TYPE_SYSTEM, + SYS_PLAYERLEAVE, + &data, + sizeof(SYSEVENTDATA_PLAYERLEAVE)); + if (msg) { + ConnResendMessage(checkconn,msg->data,msg->databytes); + ConnResendMessage(checkconn,msg->data,msg->databytes); + } + } + checkconn = checkconn->Next(); + } + } + + // DESTROY THE GAME LOCALLY + GameDestroy(); + + // LEAVE THE API LOCK + LEAVE_APILOCK_WRITE; + + // DELAY A FRACTION OF A SECOND TO GIVE THE BACKGROUND THREAD TIME TO + // FINISH ANY PACKETS IT'S PROCESSING + Sleep(s_spi_timetoresend); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetPerformUpgrade (DWORD *upgradestatus) { + VALIDATEBEGIN; + VALIDATE(upgradestatus); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE,"SNetPerformUpgrade(*upgradestatus)"); + + // VERIFY THAT THERE IS AT LEAST ONE PATCH READY TO BE INSTALLED + char buffer[1024] = ""; + if (!SRegLoadData("Patch","Patches",SREG_FLAG_BATTLENET,buffer,1023,NULL)) { + *upgradestatus = SNET_UPGRADE_NOT_NEEDED; + FAILOUT_APILOCK_WRITE; + } + buffer[1022] = 0; + buffer[1023] = 0; + + // DETERMINE THE PROGRAM DIRECTORY + char directory[MAX_PATH] = ""; + GetModuleFileName((HMODULE)0,directory,MAX_PATH); + directory[MAX_PATH-1] = 0; + { + LPSTR curr = directory; + while (*curr && SStrChr(curr+1,'\\')) + curr = SStrChr(curr+1,'\\'); + *curr = 0; + } + + // CREATE A LIST OF FILES TO EXECUTE + char execute[1024] = ""; + LPSTR currexec = execute; + + // PREPROCESS EACH PATCH + { + LPSTR curr = buffer; + while (*curr) { + + // OPEN THE PATCH + HSARCHIVE archive; + if (!SFileOpenArchive(curr,0,0,&archive)) { + *upgradestatus = (DWORD)SNET_UPGRADE_FAILED; + FAILOUT_APILOCK_WRITE; + } + + // VERIFY ITS AUTHENTICITY + { + DWORD authtype; + SFileAuthenticateArchive(archive,&authtype); + if ((authtype != SFILE_AUTH_UNABLETOAUTHENTICATE) && + (authtype < SFILE_AUTH_FIRSTAUTHENTIC)) { + SFileCloseArchive(archive); + *upgradestatus = (DWORD)SNET_UPGRADE_FAILED; + FAILOUT_APILOCK_WRITE; + } + } + + // LOOK FOR A FILE CALLED 'PREPATCH.LST' INSIDE THE PATCH FILE + { + HSFILE listfile; + if (SFileOpenFileEx(archive,"Prepatch.lst",0,&listfile)) { + + // IF WE FOUND ONE, READ IT INTO MEMORY + DWORD bytes = SFileGetFileSize(listfile); + LPSTR buffer = (LPSTR)ALLOC(bytes); + if (SFileReadFile(listfile,buffer,bytes,NULL,NULL)) { + LPCSTR curr = buffer; + while ((DWORD)(curr-buffer) < bytes) { + + // EXTRACT THE NEXT LINE + char line[256] = ""; + { + LPSTR currout = line; + while (((DWORD)(curr-buffer) < bytes) && + (currout-line < 255) && + *curr && (*curr != '\r') && (*curr != '\n')) { + *currout++ = *curr++; + *currout = 0; + } + } + while (((DWORD)(curr-buffer) < bytes) && + ((*curr == '\r') || (*curr == '\n'))) + ++curr; + + // IF THIS LINE HAS A FILENAME ARGUMENT, TURN IT INTO A FULLY + // QUALIFIED FILENAME + char relpath[MAX_PATH] = ""; + char abspath[MAX_PATH] = ""; + if (SStrChr(line,' ')) { + LPCSTR currline = SStrChr(line,' ')+1; + while (*currline == ' ') + ++currline; + SStrCopy(relpath,currline,MAX_PATH); + wsprintf(abspath,"%s\\%s",directory,currline); + } + + // IF THIS LINE CONTAINS A DELETE COMMAND, DELETE THE FILE + if (!_strnicmp(line,"delete ",7)) + DeleteFile(abspath); + + // IF THIS LINE CONTAINS AN EXTRACT COMMAND, EXTRACT THE FILE + if (!_strnicmp(line,"extract ",8)) { + HSFILE extractfile; + if (SFileOpenFileEx(archive,relpath,0,&extractfile)) { + DWORD extractbytes = SFileGetFileSize(extractfile); + LPVOID extractbuffer = ALLOC(extractbytes); + if (SFileReadFile(extractfile,extractbuffer,extractbytes,NULL,NULL)) { + HANDLE outfile = CreateFile(abspath, + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (outfile != INVALID_HANDLE_VALUE) { + DWORD byteswritten; + WriteFile(outfile,extractbuffer,extractbytes,&byteswritten,NULL); + CloseHandle(outfile); + } + } + FREE(extractbuffer); + SFileCloseFile(extractfile); + } + } + + // IF THIS LINE CONTAINS AN EXECUTE COMMAND, ADD THE PROGRAM + // TO OUR LIST OF PROGRAMS TO EXECUTE + if (!_strnicmp(line,"execute ",8)) + currexec += SStrCopy(currexec,abspath)+1; + + } + + } + FREE(buffer); + + SFileCloseFile(listfile); + } + } + + // CLOSE THE PATCH + SFileCloseArchive(archive); + + curr += SStrLen(curr)+1; + } + } + + // IF THE EXECUTE LIST IS BLANK, ADD 'BNUPDATE' + if (currexec == execute) { + wsprintf(currexec,"%s\\bnupdate.exe",directory); + currexec += SStrLen(currexec)+1; + } + *currexec = 0; + + // RUN ALL OF THE PROGRAMS ON THE EXECUTE LIST + currexec = execute; + while (*currexec) { + STARTUPINFO startupinfo; + PROCESS_INFORMATION processinfo; + ZeroMemory(&startupinfo,sizeof(STARTUPINFO)); + startupinfo.cb = sizeof(STARTUPINFO); + if (CreateProcess(currexec, + NULL, + NULL, + NULL, + 0, + NORMAL_PRIORITY_CLASS, + NULL, + directory, + &startupinfo, + &processinfo)) { + CloseHandle(processinfo.hThread); + CloseHandle(processinfo.hProcess); + } + else { + *upgradestatus = (DWORD)SNET_UPGRADE_FAILED; + FAILOUT_APILOCK_WRITE; + } + currexec += SStrLen(currexec)+1; + } + + LEAVE_APILOCK_WRITE; + *upgradestatus = SNET_UPGRADING_TERMINATE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetReceiveMessage (DWORD *senderplayerid, + LPVOID *data, + DWORD *databytes) { + if (senderplayerid) + *senderplayerid = SNET_INVALIDPLAYERID+s_api_playeroffset; + if (data) + *data = NULL; + if (databytes) + *databytes = 0; + + VALIDATEBEGIN; + VALIDATE(data); + VALIDATE(databytes); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEPEND(TRACEHANDLE,"SNetReceiveMessage(*senderplayerid,*data,*databytes)"); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // CHECK FOR TRANSFER OF GAME OWNERSHIP + if (s_game_playerid != NOPLAYER) + GameProcessLeavingPlayers(); + + // DISPATCH ANY PENDING EVENTS + LEAVE_APILOCK_WRITE; + SysDispatchUserEvents(); + ENTER_APILOCK_WRITE; + + // MAKE SURE WE ARE STILL IN A GAME + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_GAME_TERMINATED); + FAILOUT_APILOCK_WRITE; + } + + // FIND A VALID MESSAGE THAT IS THE NEXT IN SEQUENCE FROM ITS SENDER. + // IF THERE IS MORE THAN ONE MESSAGE AVAILABLE, USE THE ONE THAT WAS + // RECEIVED EARLIEST. + { + DWORD currtime = GetTickCount(); + DWORD earliesttime = 0; + CONNPTR earliestconn = NULL; + for (int local = FALSE; local <= TRUE; ++local) { + CONNPTR conn = local ? ConnFindLocal() + : s_conn_connlist.Head(); + while (conn) { + if ((conn->playerid != NOPLAYER) && + (!conn->incomingqueue[TYPE_MESSAGE].IsEmpty()) && + (conn->incomingqueue[TYPE_MESSAGE].Head()->data->header.sequence + == conn->incomingsequence[TYPE_MESSAGE])) { + + // DETERMINE THE TIME STAMP OF THIS MESSAGE + MESSAGEPTR curr = conn->incomingqueue[TYPE_MESSAGE].Head(); + DWORD timestamp = curr->sendtime; + + // IF THIS MESSAGE'S TIME STAMP IS GREATER THAN ANY MESSAGES + // THAT WERE SENT LATER BY THE SAME PLAYER, UPDATE IT TO BE + // EARLIER + while (curr->Next()) { + curr = curr->Next(); + if (timestamp-curr->sendtime < 0x7FFFFFFF) + timestamp = curr->sendtime-1; + } + + // IF THIS MESSAGE IS NOW THE EARLIEST WE HAVE SEEN, MARK THIS + // CONNECTION AS THE NEW EARLIEST CONNECTION + if (currtime-timestamp >= earliesttime) { + earliesttime = currtime-timestamp; + earliestconn = conn; + } + + } + conn = conn->Next(); + } + } + + // RETURN THE NEXT MESSAGE IN SEQUENCE FROM THE EARLIEST CONNECTION + // TO THE USER + if (earliestconn) { + MESSAGEPTR message = earliestconn->incomingqueue[TYPE_MESSAGE].Head(); + earliestconn->incomingqueue[TYPE_MESSAGE].UnlinkNode(message); + ++(earliestconn->incomingsequence[TYPE_MESSAGE]); + ConnSetCurrentMessage(earliestconn,TYPE_MESSAGE,message); + if (senderplayerid) + *senderplayerid = earliestconn->playerid+s_api_playeroffset; + *data = message->data->data; + *databytes = message->data->header.bytes-sizeof(HEADER); + PerfIncrement(SNET_PERFID_MSGRECV); + TRACEDUMPMSG(TRACEHANDLE, + earliestconn->playerid, + message->data->header.sequence, + message->data->data, + message->data->header.bytes-sizeof(HEADER)); + LEAVE_APILOCK_WRITE; + return TRUE; + } + + } + + LEAVE_APILOCK_WRITE; + SErrSetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return FALSE; +} + +//=========================================================================== +BOOL APIENTRY SNetReceiveTurns (DWORD firstplayerid, + DWORD arraysize, + LPVOID *arraydata, + LPDWORD arraydatabytes, + LPDWORD arrayplayerstatus) { + if (arraysize && arraydata) + ZeroMemory(arraydata,arraysize*sizeof(LPVOID)); + if (arraysize && arraydatabytes) + ZeroMemory(arraydatabytes,arraysize*sizeof(DWORD)); + if (arraysize && arrayplayerstatus) + ZeroMemory(arrayplayerstatus,arraysize*sizeof(DWORD)); + + VALIDATEBEGIN; + VALIDATE(arraysize); + VALIDATE(arraydata); + VALIDATE(arraydatabytes); + VALIDATE(arrayplayerstatus); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetReceiveTurns(%u,%u,*arraydata,*arraydatabytes,*arrayplayerstatus)", + firstplayerid,arraysize); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + firstplayerid -= s_api_playeroffset; + + // CHECK FOR TRANSFER OF GAME OWNERSHIP + if (s_game_playerid != NOPLAYER) + GameProcessLeavingPlayers(); + + // DETERMINE THE SEQUENCE NUMBER TO RECEIVE + CONNPTR local = ConnFindLocal(); + if (!local) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + WORD sequence = local->incomingsequence[TYPE_TURN]; + + // CHECK ALL PLAYERS THAT ARE IN A JOINING STATE, MEANING THAT WE HAVEN'T + // CAUGHT UP TO THEIR FIRST EVER TURN, TO SEE IF THEY ARE READY TO SWITCH + // OVER TO ACTIVE STATE + { + CONNPTR conn = s_conn_connlist.Head(); + while (conn) { + if ((conn->flags & PF_JOINING) && + (conn->incomingsequence[TYPE_TURN] == sequence)) { + conn->flags &= ~PF_JOINING; + SysQueueUserEvent(SNET_EVENT_PLAYERJOIN, + conn->playerid, + NULL, + 0); + } + conn = conn->Next(); + } + } + + // DISPATCH ANY PENDING EVENTS + LEAVE_APILOCK_WRITE; + SysDispatchUserEvents(); + ENTER_APILOCK_WRITE; + + // MAKE SURE WE ARE STILL IN A GAME + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_GAME_TERMINATED); + FAILOUT_APILOCK_WRITE; + } + + // CLEAR OUT ANY UNNEEDED OR ALREADY PROCESSED TURNS + ConnClearOldTurns(NULL); + + // FILL IN THE PLAYER STATUS ARRAY + DWORD currtime = GetTickCount(); + BOOL ready = TRUE; +#ifdef TRACING + char outstr[256]; + wsprintf(outstr,"%u ",sequence); +#endif + { + for (DWORD playerid = firstplayerid; playerid < firstplayerid+arraysize; ++playerid) { + + // FIND THE CONNECTION RECORD FOR THIS PLAYER + CONNPTR conn; + if (playerid == s_game_playerid) + conn = local; + else + conn = ConnFindByPlayerId((BYTE)playerid); + + // IF THE PLAYER IS ACTIVE AND HAS COMPLETED JOINING THE GAME, FILL + // IN HIS STATUS FLAGS + DWORD statusflags = 0; + if (conn && !(conn->flags & PF_JOINING)) { + statusflags |= SNET_PSF_ACTIVE; + if ((!conn->incomingqueue[TYPE_TURN].IsEmpty()) && + (conn->incomingqueue[TYPE_TURN].Head()->data->header.sequence == sequence)) + statusflags |= SNET_PSF_TURNAVAILABLE; + else + ready = FALSE; + if ((playerid == s_game_playerid) || + (currtime-conn->lastreceivetime < s_spi_timetogiveup) || + ((conn->flags & PF_LEAVING) && (statusflags & SNET_PSF_TURNAVAILABLE))) + statusflags |= SNET_PSF_RESPONDING; + + // IF THIS IS A TRACING BUILD, LOG EACH PLAYER'S STATUS +#ifdef TRACING + char buffer[16]; + wsprintf(buffer,"%u?%u ",playerid,conn->incomingsequence[TYPE_TURN]); + if (statusflags & SNET_PSF_TURNAVAILABLE) + buffer[1] = '='; + else if (statusflags & SNET_PSF_RESPONDING) + buffer[1] = 'W'; + else + buffer[1] = 'X'; + SStrPack(outstr,buffer,256); +#endif + + } + *(arrayplayerstatus+playerid-firstplayerid) = statusflags; + } + } +#ifdef TRACING + TRACEOUT(TRACEHANDLE,outstr); +#endif + + // MAINTAIN ACTIVE CONNECTIONS + { + for (DWORD playerid = firstplayerid; playerid < firstplayerid+arraysize; ++playerid) + if (*(arrayplayerstatus+playerid-firstplayerid) & SNET_PSF_ACTIVE) { + + // FIND THE PLAYER RECORD + CONNPTR conn = NULL; + if (playerid != s_game_playerid) + conn = ConnFindByPlayerId((BYTE)playerid); + if (!conn) + continue; + + // IF WE ARE STILL WAITING FOR THIS PLAYER'S TURN AND MORE THAN THE + // RESEND TIME HAS ELAPSED, REQUEST A RESEND OF THIS TURN FROM ALL + // PLAYERS + if ((!((*(arrayplayerstatus+playerid-firstplayerid)) & SNET_PSF_TURNAVAILABLE)) && + ((!conn->lastrequesttime) || + ((currtime-conn->lastrequesttime >= s_spi_timetoresend) && + (currtime-conn->lastrequesttime <= 0x7FFFFFFF)))) { + PACKETPTR pkt = (PACKETPTR)ALLOC(sizeof(PACKET)+1); + conn->lastrequesttime = currtime; + CONNPTR otherconn = s_conn_connlist.Head(); + while (otherconn) { + if ((otherconn->playerid != NOPLAYER) && + ((conn->playerid != NOPLAYER) || (otherconn == conn))) { + TRACEOUT(TRACEHANDLE, + " requesting resend: type=%u sequence=%04x player=%x", + TYPE_TURN,conn->incomingsequence[TYPE_TURN],conn->playerid); + pkt->header.checksum = 0; + pkt->header.bytes = sizeof(HEADER); + pkt->header.sequence = conn->incomingsequence[TYPE_TURN]; + pkt->header.acksequence = otherconn->availablesequence[TYPE_TURN]; + pkt->header.type = TYPE_TURN; + pkt->header.subtype = 0; + pkt->header.playerid = local->playerid; + pkt->header.flags = MF_RESENDREQUEST; + if (otherconn != conn) { + pkt->header.bytes++; + pkt->data[0] = conn->playerid; + } + pkt->header.checksum = PktGenerateChecksum(pkt); + ConnSendPacket(otherconn,pkt); + } + otherconn = otherconn->Next(); + } + FREE(pkt); + } + + // IF WE'RE IN DANGER OF GIVING UP ON THIS PLAYER, SEND A PING + // REQUEST TO SEE IF HE'S STILL ALIVE. (OPTIMIZATION: IF THIS + // PLAYER ALREADY HAS UNACKNOWLEDGED SYSTEM MESSAGES THEN HE'S + // NOT GOING TO RESPOND TO A PING UNTIL HE PROCESSES THOSE, SO + // DON'T BOTHER TO SEND ONE.) + if ((conn->outgoingqueue[TYPE_SYSTEM].IsEmpty()) && + (currtime-conn->lastreceivetime >= s_spi_timetogiveup/2) && + (currtime-conn->lastpingtime >= s_spi_timetogiveup/2)) { + conn->lastpingtime = currtime; + ConnSendMessage(conn,TYPE_SYSTEM,SYS_PING,NULL,0); + } + + } + } + + // EXIT IF WE DON'T HAVE TURN DATA FOR ALL PLAYERS + if (!ready) { + SErrSetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + LEAVE_APILOCK_WRITE; + return FALSE; + } + + // FILL IN THE TURN DATA ARRAYS + { + for (DWORD playerid = firstplayerid; playerid < firstplayerid+arraysize; ++playerid) { + CONNPTR conn; + if (playerid == s_game_playerid) + conn = local; + else + conn = ConnFindByPlayerId((BYTE)playerid); + if (conn && + (*(arrayplayerstatus+playerid-firstplayerid) & SNET_PSF_TURNAVAILABLE)) { + MESSAGEPTR message = conn->incomingqueue[TYPE_TURN].Head(); + conn->incomingqueue[TYPE_TURN].UnlinkNode(message); + conn->incomingsequence[TYPE_TURN] = (WORD)(sequence+1); + ConnSetCurrentMessage(conn,TYPE_TURN,message); + *(arraydata +playerid-firstplayerid) = message->data->data; + *(arraydatabytes+playerid-firstplayerid) = message->data->header.bytes-sizeof(HEADER); + TRACEDUMPMSG(TRACEHANDLE, + conn->playerid, + message->data->header.sequence, + message->data->data, + message->data->header.bytes-sizeof(HEADER)); + } + else { + *(arraydata +playerid-firstplayerid) = NULL; + *(arraydatabytes+playerid-firstplayerid) = 0; + } + } + } + + // INCREMENT THE SEQUENCE NUMBER + local->incomingsequence[TYPE_TURN] = (WORD)(sequence+1); + PerfSet(SNET_PERFID_TURN,local->incomingsequence[TYPE_TURN]); + PerfIncrement(SNET_PERFID_TURNSRECV); + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetRegisterEventHandler (DWORD eventid, + SNETEVENTPROC callback) { + VALIDATEBEGIN; + VALIDATE(callback); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetRegisterEventHandler(%u,0x%08x)", + eventid,callback); + + // REGISTER THE EVENT HANDLER + BOOL success = SEvtRegisterHandler(REGISTERTYPE, + REGISTERSUBTYPE_SNETEVENT, + eventid, + 0, + (SEVTHANDLER)callback); + + LEAVE_APILOCK_WRITE; + if (!success) + SErrSetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return success; +} + +//=========================================================================== +BOOL APIENTRY SNetResetLatencyMeasurements () { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetResetLatencyMeasurements()"); + + CONNPTR conn = s_conn_connlist.Head(); + while (conn) { + conn->latency = 0; + conn->peaklatency = 0; + conn->lastpingtime = 0; + conn = conn->Next(); + } + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetSelectGame(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,*playerid)", + flags,programdata,playerdata,interfacedata,versiondata); + TRACEDUMPDATABLOCKS(TRACEHANDLE, + programdata,playerdata,interfacedata,versiondata); + + // VALIDATE PARAMETERS + if (playerid) + *playerid = 0; + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + SNETPROGRAMDATA modprogramdata; + SNETPLAYERDATA modplayerdata; + SNETUIDATA modinterfacedata; + SNETVERSIONDATA modversiondata; + if (!SpiNormalizeDataBlocks(programdata,playerdata,interfacedata,versiondata, + &modprogramdata,&modplayerdata,&modinterfacedata,&modversiondata)) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_WRITE; + } + + // SAVE A POINTER TO THE SELECT GAME FUNCTION AND LEAVE THE API LOCK + BOOL (CALLBACK *selectfunc)(DWORD,SNETPROGRAMDATAPTR,SNETPLAYERDATAPTR,SNETUIDATAPTR,SNETVERSIONDATAPTR,DWORD *); + selectfunc = s_spi->SelectGame; + LEAVE_APILOCK_WRITE; + + // CALL THE SELECT GAME FUNCTION + TRACEOUT(TRACEHANDLE, + " spiSelectGame(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,*playerid)", + flags,&modprogramdata,&modplayerdata,&modinterfacedata,&modversiondata); + BOOL success = selectfunc(flags, + &modprogramdata, + &modplayerdata, + &modinterfacedata, + &modversiondata, + playerid); + + TRACEOUT(TRACEHANDLE," spiSelectGame() returns %u",success); + return success; +} + +//=========================================================================== +BOOL APIENTRY SNetSelectProvider (SNETCAPSPTR mincaps, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *providerid) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetSelectProvider(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,*providerid)", + mincaps,programdata,playerdata,interfacedata,versiondata); + TRACEDUMPDATABLOCKS(TRACEHANDLE, + programdata,playerdata,interfacedata,versiondata); + + // VALIDATE PARAMETERS + if (providerid) + *providerid = 0; + SNETPROGRAMDATA modprogramdata; + SNETPLAYERDATA modplayerdata; + SNETUIDATA modinterfacedata; + SNETVERSIONDATA modversiondata; + if (!SpiNormalizeDataBlocks(programdata,playerdata,interfacedata,versiondata, + &modprogramdata,&modplayerdata,&modinterfacedata,&modversiondata)) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_WRITE; + } + + // BUILD A LIST OF PROVIDERS IF WE DON'T ALREADY HAVE ONE + SpiFindAllProviders(); + + // BUILD A USER INTERFACE PARAMETERS BLOCK + UIPARAMS uiparams; + ZeroMemory(&uiparams,sizeof(UIPARAMS)); + uiparams.mincaps = mincaps; + uiparams.programdata = &modprogramdata; + uiparams.playerdata = &modplayerdata; + uiparams.interfacedata = &modinterfacedata; + uiparams.versiondata = &modversiondata; + + // DISPLAY THE DIALOG BOX + DWORD result = (DWORD)SDlgDialogBoxParam(StormGetInstance(), + "SELECTPROVIDER_DIALOG", + SDrawGetFrameWindow(), + UiSelectProviderDialogProc, + (LPARAM)&uiparams); + if (providerid) + *providerid = result; + + LEAVE_APILOCK_WRITE; + return (result && (result != 0xFFFFFFFF)); +} + +//=========================================================================== +BOOL APIENTRY SNetSendMessage (DWORD targetplayerid, + LPVOID data, + DWORD databytes) { + VALIDATEBEGIN; + VALIDATE(data); + VALIDATE(databytes); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetSendMessage(%u,0x%08x,%u)", + targetplayerid,data,databytes); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + if ((targetplayerid != SNET_BROADCASTNONLOCALPLAYERID) && + (targetplayerid != SNET_BROADCASTPLAYERID)) + targetplayerid -= s_api_playeroffset; + + // IF THIS IS A BROADCAST, SEND IT TO ALL PLAYERS IN THE GAME, + // INCLUDING THE LOCAL PLAYER + if ((targetplayerid == SNET_BROADCASTNONLOCALPLAYERID) || + (targetplayerid == SNET_BROADCASTPLAYERID)) { + CONNPTR conn = s_conn_connlist.Head(); + while (conn) { + if (conn->playerid != NOPLAYER) { + TRACEDUMPMSG(TRACEHANDLE, + 0xFFFFFFFF, + conn->outgoingsequence[TYPE_MESSAGE], + data, + databytes); + ConnSendMessage(conn, + TYPE_MESSAGE, + 0, + data, + databytes); + } + conn = conn->Next(); + } + if (targetplayerid == SNET_BROADCASTPLAYERID) { + conn = ConnFindLocal(); + if (conn) { + TRACEDUMPMSG(TRACEHANDLE, + 0xFFFFFFFF, + conn->outgoingsequence[TYPE_MESSAGE], + data, + databytes); + ConnSendMessage(conn, + TYPE_MESSAGE, + 0, + data, + databytes); + } + } + } + + // OTHERWISE, SEND IT TO JUST THE REQUESTED PLAYER + else { + CONNPTR conn = ConnFindByPlayerId(targetplayerid); + if (conn) { + TRACEDUMPMSG(TRACEHANDLE, + 0xFFFFFFFF, + conn->outgoingsequence[TYPE_MESSAGE], + data, + databytes); + ConnSendMessage(conn, + TYPE_MESSAGE, + 0, + data, + databytes); + } + else { + SErrSetLastError(SNET_ERROR_INVALID_PLAYER); + FAILOUT_APILOCK_WRITE; + } + } + + PerfIncrement(SNET_PERFID_MSGSENT); + LEAVE_APILOCK_WRITE; + + // TRIGGER THE BACKGROUND RECEIVE THREAD SO IT WILL MAINTAIN CONNECTIONS + SetEvent(s_recv_event); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetSendServerChatCommand (LPCSTR command) { + VALIDATEBEGIN; + VALIDATE(command); + VALIDATE(*command); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetSetServerChatCommand(0x%08x)", + command); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + CONNPTR local = ConnFindLocal(); + if (!local) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // SEND THE MESSAGE TO THE SERVER + char senderpath[SNETSPI_MAXSTRINGLENGTH+16]; + wsprintf(senderpath,"\\\\.\\game\\%s",s_game_gamename); + BOOL result = s_spi->SendExternalMessage(senderpath, + local->name, + "", + "", + command); + + LEAVE_APILOCK_WRITE; + return result; +} + +//=========================================================================== +BOOL APIENTRY SNetSendTurn (LPVOID data, + DWORD databytes) { + VALIDATEBEGIN; + VALIDATE(data); + VALIDATE(databytes); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetSendTurn(0x%08x,%u)", + data,databytes); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_BAD_PROVIDER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + CONNPTR local = ConnFindLocal(); + if (!local) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // SEND THE TURN TO ALL PLAYERS IN THE GAME, INCLUDING THE LOCAL PLAYER + { + CONNPTR conn = s_conn_connlist.Head(); + while (conn) { + if ((conn->playerid != NOPLAYER) && + (conn->outgoingsequence[TYPE_TURN] == local->outgoingsequence[TYPE_TURN])) { + TRACEDUMPMSG(TRACEHANDLE, + 0xFFFFFFFF, + conn->outgoingsequence[TYPE_TURN], + data, + databytes); + ConnSendMessage(conn, + TYPE_TURN, + 0, + data, + databytes); + } + conn = conn->Next(); + } + TRACEDUMPMSG(TRACEHANDLE, + 0xFFFFFFFF, + local->outgoingsequence[TYPE_TURN], + data, + databytes); + ConnSendMessage(local, + TYPE_TURN, + 0, + data, + databytes); + } + + PerfIncrement(SNET_PERFID_TURNSSENT); + LEAVE_APILOCK_WRITE; + + // TRIGGER THE BACKGROUND RECEIVE THREAD SO IT WILL MAINTAIN CONNECTIONS + SetEvent(s_recv_event); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetSetBasePlayer (DWORD playerid) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetSetBasePlayer(%u)", + playerid); + + s_api_playeroffset = playerid; + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetSetGameMode (DWORD modeflags) { + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetSetGameMode(0x%08x)", + modeflags); + + // VALIDATE PARAMETERS + if (!s_spi) { + SErrSetLastError(SNET_ERROR_INVALID_PARAMETER); + FAILOUT_APILOCK_WRITE; + } + if (s_game_playerid == NOPLAYER) { + SErrSetLastError(SNET_ERROR_NOT_IN_GAME); + FAILOUT_APILOCK_WRITE; + } + + // IF WE ARE NOT THE GAME OWNER, RETURN FAILURE + { + CONNPTR local = ConnFindLocal(); + if (!(local && local->gameowner)) { + SErrSetLastError(SNET_ERROR_NOT_OWNER); + FAILOUT_APILOCK_WRITE; + } + } + + // SET THE NEW GAME MODE + s_game_gamemode = modeflags; + + // BUILD THE CLIENT DATA BLOCK + BYTE clientdata[SNETSPI_MAXCLIENTDATA]; + DWORD clientdatabytes; + GameBuildClientData(clientdata, + &clientdatabytes); + + // START ADVERTISING WITH THE NEW MODE + DWORD gameage = (GetTickCount()-s_game_creationtime)/1000; + TRACEOUT(TRACEHANDLE, + " spiStartAdvertisingGame(\"%s\",\"%s\",\"%s\",%u,%u,0x%08x,0x%08x,0x%08x,%u)", + s_game_gamename, + s_game_gamepass, + s_game_gamedesc, + s_game_gamemode, + gameage, + s_game_categorybits, + s_game_optcategorybits, + clientdata, + clientdatabytes); + if (!s_spi->StartAdvertisingGame(s_game_gamename, + s_game_gamepass, + s_game_gamedesc, + s_game_gamemode, + gameage, + s_game_categorybits, + s_game_optcategorybits, + clientdata, + clientdatabytes)) + FAILOUT_APILOCK_WRITE; + + // note: broadcast the new mode to other players + + LEAVE_APILOCK_WRITE; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SNetUnregisterEventHandler (DWORD eventid, + SNETEVENTPROC callback) { + VALIDATEBEGIN; + VALIDATE(callback); + VALIDATEEND; + + ENTER_APILOCK_WRITE; + TRACEOUT(TRACEHANDLE, + "SNetUnregisterEventHandler(%u,0x%08x)", + eventid,callback); + + // UNREGISTER THE EVENT HANDLER + BOOL success = SEvtUnregisterHandler(REGISTERTYPE, + REGISTERSUBTYPE_SNETEVENT, + eventid, + (SEVTHANDLER)callback); + + LEAVE_APILOCK_WRITE; + if (!success) + SErrSetLastError(SNET_ERROR_NOT_REGISTERED); + return success; +} diff --git a/Storm/SOURCE/SREG.CPP b/Storm/SOURCE/SREG.CPP new file mode 100644 index 0000000..d2fe106 --- /dev/null +++ b/Storm/SOURCE/SREG.CPP @@ -0,0 +1,289 @@ +/**************************************************************************** +* +* SREG.CPP +* Storm registry functions +* +* By Michael O'Brien (9/28/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define BASEKEY "Software\\Blizzard Entertainment\\" +#define BATTLENETKEY "Software\\Battle.net\\" + +//=========================================================================== +static BOOL InternalLoadEntry (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD *datatype, + LPVOID buffer, + DWORD bytes, + DWORD *bytesread) { + *bytesread = 0; + BOOL success = 0; + { + char fullkeyname[MAX_PATH]; + SRegGetBaseKey(flags,fullkeyname,MAX_PATH); + SStrPack(fullkeyname,keyname,MAX_PATH); + HKEY keyhandle; + if (!RegOpenKeyEx((flags & SREG_FLAG_USERSPECIFIC) + ? HKEY_CURRENT_USER + : HKEY_LOCAL_MACHINE, + fullkeyname, + 0, + KEY_READ, + &keyhandle)) { + *bytesread = bytes; + success = !RegQueryValueEx(keyhandle, + valuename, + 0, + datatype, + (LPBYTE)buffer, + bytesread); + RegCloseKey(keyhandle); + } + } + return success; +} + +//=========================================================================== +static BOOL InternalSaveEntry (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD datatype, + LPCVOID buffer, + DWORD bytes) { + BOOL success = 0; + { + char fullkeyname[MAX_PATH]; + if (flags & SREG_FLAG_BATTLENET) + SStrCopy(fullkeyname,BATTLENETKEY,MAX_PATH); + else + SStrCopy(fullkeyname,BASEKEY,MAX_PATH); + SStrPack(fullkeyname,keyname,MAX_PATH); + HKEY keyhandle; + DWORD disposition; + if (!RegCreateKeyEx((flags & SREG_FLAG_USERSPECIFIC) + ? HKEY_CURRENT_USER + : HKEY_LOCAL_MACHINE, + fullkeyname, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + &keyhandle, + &disposition)) { + success = !RegSetValueEx(keyhandle, + valuename, + 0, + datatype, + (const BYTE *)buffer, + bytes); + if (flags & SREG_FLAG_FLUSHTODISK) + RegFlushKey(keyhandle); + RegCloseKey(keyhandle); + } + } + return success; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SRegGetBaseKey (DWORD flags, + LPSTR buffer, + DWORD buffersize) { + VALIDATEBEGIN; + VALIDATE(buffer); + VALIDATE(buffersize); + VALIDATEEND; + + if (flags & SREG_FLAG_BATTLENET) + SStrCopy(buffer,BATTLENETKEY,buffersize); + else + SStrCopy(buffer,BASEKEY,buffersize); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SRegLoadData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID buffer, + DWORD buffersize, + DWORD *bytesread) { + VALIDATEBEGIN; + VALIDATE(keyname); + VALIDATE(*keyname); + VALIDATE(valuename); + VALIDATE(*valuename); + VALIDATEEND; + + DWORD datatype; + DWORD localbytesread; + if (!bytesread) + bytesread = &localbytesread; + return InternalLoadEntry(keyname, + valuename, + flags, + &datatype, + buffer, + buffersize, + bytesread); +} + +//=========================================================================== +BOOL APIENTRY SRegLoadString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPTSTR buffer, + DWORD bufferchars) { + VALIDATEBEGIN; + VALIDATE(keyname); + VALIDATE(*keyname); + VALIDATE(valuename); + VALIDATE(*valuename); + VALIDATE(buffer); + VALIDATE(bufferchars); + VALIDATEEND; + + DWORD datatype; + DWORD bytesread; + if (!InternalLoadEntry(keyname, + valuename, + flags, + &datatype, + buffer, + bufferchars, + &bytesread)) + return FALSE; + + switch (datatype) { + + case REG_DWORD: + { + DWORD value = *(LPDWORD)buffer; + wsprintf(buffer,"%u",value); + } + break; + + case REG_SZ: + *(buffer+min(bufferchars-1,bytesread)) = 0; + break; + + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SRegLoadValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD *value) { + VALIDATEBEGIN; + VALIDATE(keyname); + VALIDATE(*keyname); + VALIDATE(valuename); + VALIDATE(*valuename); + VALIDATE(value); + VALIDATEEND; + + DWORD datatype; + char buffer[256] = ""; + DWORD bytesread; + if (!InternalLoadEntry(keyname, + valuename, + flags, + &datatype, + buffer, + 256, + &bytesread)) + return FALSE; + + switch (datatype) { + + case REG_DWORD: + *value = *(LPDWORD)buffer; + break; + + case REG_SZ: + *value = strtoul(buffer,NULL,0); + break; + + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SRegSaveData (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPVOID data, + DWORD databytes) { + VALIDATEBEGIN; + VALIDATE(keyname); + VALIDATE(*keyname); + VALIDATE(valuename); + VALIDATE(*valuename); + VALIDATEEND; + + return InternalSaveEntry(keyname, + valuename, + flags, + (flags & SREG_FLAG_MULTISZ) + ? REG_MULTI_SZ + : REG_BINARY, + data ? data : "", + databytes); +} + +//=========================================================================== +BOOL APIENTRY SRegSaveString (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + LPCTSTR string) { + VALIDATEBEGIN; + VALIDATE(keyname); + VALIDATE(*keyname); + VALIDATE(valuename); + VALIDATE(*valuename); + VALIDATE(string); + VALIDATEEND; + + return InternalSaveEntry(keyname, + valuename, + flags, + REG_SZ, + string, + SStrLen(string)+1); +} + +//=========================================================================== +BOOL APIENTRY SRegSaveValue (LPCTSTR keyname, + LPCTSTR valuename, + DWORD flags, + DWORD value) { + VALIDATEBEGIN; + VALIDATE(keyname); + VALIDATE(*keyname); + VALIDATE(valuename); + VALIDATE(*valuename); + VALIDATEEND; + + return InternalSaveEntry(keyname, + valuename, + flags, + REG_DWORD, + &value, + sizeof(DWORD)); +} diff --git a/Storm/SOURCE/SRGN.CPP b/Storm/SOURCE/SRGN.CPP new file mode 100644 index 0000000..a50f0a7 --- /dev/null +++ b/Storm/SOURCE/SRGN.CPP @@ -0,0 +1,765 @@ +/**************************************************************************** +* +* SRGN.CPP +* Storm region manager +* +* By Michael O'Brien (9/3/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +DECLARE_STRICT_HANDLE(HLOCKEDRGN); + +#define SF_ADDING 0x00000001 +#define SF_OVERLAPS 0x00000002 +#define SF_TEMPMASK 0x00000003 +#define SF_PARAMONLY 0x00010000 + +typedef struct _SOURCE { + RECT rect; + LPVOID param; + int sequence; + DWORD flags; +} SOURCE, *SOURCEPTR; + +typedef struct _FOUNDPARAM { + LPVOID param; + int sequence; +} FOUNDPARAM, *FOUNDPARAMPTR; + +EXPORTOBJECTDECL(RGN) { + ARRAY(SOURCE) source; + ARRAY(RECT) combined; + ARRAY(FOUNDPARAM) foundparams; + RECT foundparamsrect; + int sequence; + BOOL dirty; +} *RGNPTR; + +typedef EXPORTTABLEREUSE(RGN,HSRGN,HLOCKEDRGN,SYNC_ALWAYS) RGNTABLE; + +static RGNTABLE s_rgntable; + +static inline void DeleteCombinedRect (ARRAYPTR(RECT) combinedarray, + DWORD index); +static inline void DeleteRect (LPRECT rect); +static inline BOOL IsNullRect (LPCRECT rect); +static int __cdecl SortFoundParamsCallback (const void *elem1, + const void *elem2); +static int __cdecl SortRectCallback (const void *elem1, + const void *elem2); + +//=========================================================================== +static inline void AddCombinedRect (ARRAYPTR(RECT) combinedarray, + LPCRECT rect) { + LPRECT newrect = combinedarray->NewElement(); + CopyMemory(newrect,rect,sizeof(RECT)); +} + +//=========================================================================== +static inline void AddSourceRect (ARRAYPTR(SOURCE) sourcearray, + LPCRECT rect, + LPVOID param, + int sequence, + DWORD flags) { + SOURCEPTR newptr = sourcearray->NewElement(); + CopyMemory(&newptr->rect,rect,sizeof(RECT)); + newptr->param = param; + newptr->sequence = sequence; + newptr->flags = flags; +} + +//=========================================================================== +static inline BOOL CheckForIntersection (LPCRECT sourcerect, + LPCRECT targetrect) { + return (sourcerect->left < targetrect->right) && + (sourcerect->top < targetrect->bottom) && + (sourcerect->right > targetrect->left) && + (sourcerect->bottom > targetrect->top); +} + +//=========================================================================== +static void ClearRegion (RGNPTR rgnptr) { + rgnptr->source.SetNumElements(0); + rgnptr->combined.SetNumElements(0); + rgnptr->foundparams.SetNumElements(0); + DeleteRect(&rgnptr->foundparamsrect); + rgnptr->sequence = 0; + rgnptr->dirty = FALSE; +} + +//=========================================================================== +static void CombineRectangles (ARRAYPTR(RECT) combinedarray) { + for (DWORD loop0 = 1; loop0 < combinedarray->NumElements(); ++loop0) + for (DWORD loop1 = 0; loop1 < loop0; ++loop1) { + LPRECT rect[2] = {&(*combinedarray)[loop0], + &(*combinedarray)[loop1]}; + + // IF THESE TWO RECTANGLES ARE VERTICALLY ADJACENT AND LINE UP + // HORIZONTALLY, COMBINE THEM + if ((rect[0]->left == rect[1]->left) && + (rect[0]->right == rect[1]->right) && + ((rect[0]->top == rect[1]->bottom) || + (rect[1]->top == rect[0]->bottom))) { + rect[0]->top = min(rect[0]->top ,rect[1]->top); + rect[0]->bottom = max(rect[0]->bottom,rect[1]->bottom); + DeleteRect(rect[1]); + break; + } + + // IF THESE TWO RECTANGLES ARE NOT HORIZONTALLY ADJACENT, GO TO + // THE NEXT PAIR + if ((rect[0]->left != rect[1]->right) && + (rect[1]->left != rect[0]->right)) + continue; + + // IF THESE TWO RECTANGLES LINE UP VERTICALLY, COMBINE THEM + if ((rect[0]->top == rect[1]->top) && + (rect[0]->bottom == rect[1]->bottom)) { + rect[0]->left = min(rect[0]->left ,rect[1]->left); + rect[0]->right = max(rect[0]->right,rect[1]->right); + DeleteRect(rect[1]); + break; + } + + // OTHERWISE, IF THEY DON'T LINE UP BUT DO AT LEAST TOUCH EACH OTHER, + // THEN SPLIT THEM AS NECESSARY TO CREATE ONE WIDE RECTANGLE + else if ((rect[0]->top < rect[1]->bottom) && + (rect[1]->top < rect[0]->bottom)) { + RECT newrect[5] = {{rect[0]->left, + rect[0]->top, + rect[0]->right, + rect[1]->top}, + {rect[1]->left, + rect[1]->top, + rect[1]->right, + rect[0]->top}, + {rect[0]->left, + rect[1]->bottom, + rect[0]->right, + rect[0]->bottom}, + {rect[1]->left, + rect[0]->bottom, + rect[1]->right, + rect[1]->bottom}, + {min(rect[0]->left ,rect[1]->left), + max(rect[0]->top ,rect[1]->top), + max(rect[0]->right ,rect[1]->right), + min(rect[0]->bottom,rect[1]->bottom)}}; + for (DWORD loop = 0; loop < 5; ++loop) + if (!IsNullRect(&newrect[loop])) + AddCombinedRect(combinedarray, + &newrect[loop]); + DeleteCombinedRect(combinedarray, + loop0); + DeleteCombinedRect(combinedarray, + loop1); + break; + } + + } +} + +//=========================================================================== +static inline BOOL CompareRects (LPCRECT rect1, + LPCRECT rect2) { + return !memcmp(rect1,rect2,sizeof(RECT)); +} + +//=========================================================================== +static inline void DeleteCombinedRect (ARRAYPTR(RECT) combinedarray, + DWORD index) { + LPRECT rect = &(*combinedarray)[index]; + DeleteRect(rect); +} + +//=========================================================================== +static inline void DeleteRect (LPRECT rect) { + rect->left = INT_MAX; + rect->top = INT_MAX; + rect->right = INT_MAX; + rect->bottom = INT_MAX; +} + +//=========================================================================== +static inline void DeleteSourceRect (ARRAYPTR(SOURCE) sourcearray, + DWORD index) { + SOURCEPTR sourceptr = &(*sourcearray)[index]; + DeleteRect(&sourceptr->rect); + sourceptr->param = NULL; + sourceptr->sequence = -1; + sourceptr->flags = 0; +} + +//=========================================================================== +static void FindSourceParams (RGNPTR rgnptr, + LPCRECT rect) { + + // IF THE RESULTS FOR THIS SEARCH ARE ALREADY CACHED, JUST RETURN + if (CompareRects(rect,&rgnptr->foundparamsrect)) + return; + + // OTHERWISE, RESET THE SEARCH RESULTS + rgnptr->foundparams.SetNumElements(0); + + // FIND ALL SOURCE PARAMETERS WHICH MATCH THE GIVEN RECTANGLE + DWORD sourcerects = rgnptr->source.NumElements(); + DWORD params = 0; + for (DWORD loop1 = 0; loop1 < sourcerects; ++loop1) + if (CheckForIntersection(rect,&rgnptr->source[loop1].rect)) { + int sequence = rgnptr->source[loop1].sequence; + BOOL found = FALSE; + for (DWORD loop2 = 0; loop2 < params; ++loop2) { + FOUNDPARAMPTR checkptr = &rgnptr->foundparams[loop2]; + if (checkptr->sequence == sequence) { + found = TRUE; + break; + } + } + if (!found) { + FOUNDPARAMPTR newptr = rgnptr->foundparams.NewElement(); + newptr->param = rgnptr->source[loop1].param; + newptr->sequence = sequence; + ++params; + } + } + + // SORT THE PARAMETERS + qsort(rgnptr->foundparams.Ptr(), + rgnptr->foundparams.NumElements(), + sizeof(FOUNDPARAM), + SortFoundParamsCallback); + + // SAVE THIS RECTANGLE AS THE RECTANGLE TO WHICH THE CACHE NOW APPLIES + CopyMemory(&rgnptr->foundparamsrect, + rect, + sizeof(RECT)); + +} + +//=========================================================================== +static void FragmentCombinedRectangles (ARRAYPTR(RECT) combinedarray, + DWORD firstindex, + DWORD lastindex, + LPCRECT rect) { + for (DWORD index = firstindex; index < lastindex; ++index) { + LPCRECT checkrect = &(*combinedarray)[index]; + if (CheckForIntersection(rect,checkrect)) { + RECT newrect[4] = {{rect->left, + rect->top, + rect->right, + checkrect->top}, + {rect->left, + checkrect->bottom, + rect->right, + rect->bottom}, + {rect->left, + max(rect->top,checkrect->top), + checkrect->left, + min(rect->bottom,checkrect->bottom)}, + {checkrect->right, + max(rect->top,checkrect->top), + rect->right, + min(rect->bottom,checkrect->bottom)}}; + for (DWORD loop = 0; loop < 4; ++loop) + if (!IsNullRect(&newrect[loop])) + FragmentCombinedRectangles(combinedarray, + index+1, + lastindex, + &newrect[loop]); + return; + } + } + AddCombinedRect(combinedarray, + rect); +} + +//=========================================================================== +static void FragmentSourceRectangles (ARRAYPTR(SOURCE) sourcearray, + DWORD firstindex, + DWORD lastindex, + BOOL previousoverlap, + LPCRECT rect, + LPVOID param, + int sequence) { + + // IF THIS RECTANGLE INTERSECTS ANY OTHER RECTANGLE IN THE ARRAY, + // BREAK UP EITHER OR BOTH OF THE RECTANGLES TO ELIMINATE OVERLAP, + // AND CALL THIS FUNCTION RECURSIVELY WITH EACH PIECE. + BOOL overlapsexisting = previousoverlap; + for (DWORD index = firstindex; index < lastindex; ++index) { + LPCRECT checkrect = &(*sourcearray)[index].rect; + if (CheckForIntersection(rect,checkrect)) { + + // IF THE TWO RECTANGLES ARE IDENTICAL, DON'T TREAT THIS AS AN + // INTERSECTION + if (CompareRects(rect,checkrect)) { + (*sourcearray)[index].flags |= SF_OVERLAPS; + overlapsexisting = TRUE; + continue; + } + + // OTHERWISE, BUILD NEW RECTANGLES WHICH EACH EITHER COMPLETELY + // OVERLAP OR DON'T OVERLAP AT ALL + LPCRECT overlaprect[2] = {rect,checkrect}; + int minleft = (int)(overlaprect[0]->left > overlaprect[1]->left); + int maxleft = (int)(overlaprect[1]->left > overlaprect[0]->left); + int mintop = (int)(overlaprect[0]->top > overlaprect[1]->top); + int maxtop = (int)(overlaprect[1]->top > overlaprect[0]->top); + int minright = (int)(overlaprect[0]->right > overlaprect[1]->right); + int maxright = (int)(overlaprect[1]->right > overlaprect[0]->right); + int minbottom = (int)(overlaprect[0]->bottom > overlaprect[1]->bottom); + int maxbottom = (int)(overlaprect[1]->bottom > overlaprect[0]->bottom); + RECT newrect[5] = {{overlaprect[mintop]->left, + overlaprect[mintop]->top, + overlaprect[mintop]->right, + overlaprect[maxtop]->top}, + {overlaprect[maxbottom]->left, + overlaprect[minbottom]->bottom, + overlaprect[maxbottom]->right, + overlaprect[maxbottom]->bottom}, + {overlaprect[minleft]->left, + overlaprect[maxtop]->top, + overlaprect[maxleft]->left, + overlaprect[minbottom]->bottom}, + {overlaprect[minright]->right, + overlaprect[maxtop]->top, + overlaprect[maxright]->right, + overlaprect[minbottom]->bottom}, + {overlaprect[maxleft]->left, + overlaprect[maxtop]->top, + overlaprect[minright]->right, + overlaprect[minbottom]->bottom}}; + + // DETERMINE WHICH NEW RECTANGLES OVERLAP WHICH OF THE ORIGINAL + // RECTANGLES + BOOL overlaps[5][2]; + { + for (DWORD loop1 = 0; loop1 < 5; ++loop1) + if (IsNullRect(&newrect[loop1])) + overlaps[loop1][0] = overlaps[loop1][1] = FALSE; + else + for (DWORD loop2 = 0; loop2 < 2; ++loop2) + overlaps[loop1][loop2] = CheckForIntersection(&newrect[loop1], + overlaprect[loop2]); + } + + // ADD THE NEW RECTANGLES TO THE ARRAY. (OUR POINTERS TO THE SOURCE + // RECTANGLES BECOME INVALID AT THIS POINT BECAUSE THE ARRAY MAY BE + // RESIZED, CAUSING IT TO MOVE IN MEMORY.) + for (DWORD loop = 0; loop < 5; ++loop) { + if (overlaps[loop][0]) + FragmentSourceRectangles(sourcearray, + index+1, + lastindex, + overlapsexisting || overlaps[loop][1], + &newrect[loop], + param, + sequence); + if (overlaps[loop][1]) + AddSourceRect(sourcearray, + &newrect[loop], + (*sourcearray)[index].param, + (*sourcearray)[index].sequence, + ((*sourcearray)[index].flags & ~SF_TEMPMASK) + | (overlaps[loop][0] ? SF_OVERLAPS : 0)); + } + + // REMOVE THE ORIGINAL RECTANGLES FROM THE ARRAY AND RETURN + DeleteSourceRect(sourcearray,index); + return; + + } + } + + // IF THIS RECTANGLE DIDN'T PARTIALLY OVERLAP ANY OTHER RECTANGLE, + // ADD IT TO THE ARRAY, KEEPING TRACK OF WHETHER OR NOT IT FULLY + // OVERLAPPED ANY OTHER RECTANGLE. + AddSourceRect(sourcearray, + rect, + param, + sequence, + SF_ADDING | (overlapsexisting ? SF_OVERLAPS : 0)); + +} + +//=========================================================================== +static inline BOOL IsNullRect (LPCRECT rect) { + return ((rect->left >= rect->right) || + (rect->top >= rect->bottom)); +} + +//=========================================================================== +static void OptimizeSource (ARRAYPTR(SOURCE) sourcearray) { + + // REMOVE NULL RECTANGLES + DWORD index = 0; + DWORD numelements; + while (index < (numelements = sourcearray->NumElements())) + if (IsNullRect(&(*sourcearray)[index].rect)) { + CopyMemory(&(*sourcearray)[index], + &(*sourcearray)[numelements-1], + sizeof(SOURCE)); + sourcearray->SetNumElements(numelements-1); + } + else + ++index; + +} + +//=========================================================================== +static void ProcessBooleanOperation (ARRAYPTR(SOURCE) sourcearray, + LPCRECT rect, + int combinemode) { + for (DWORD index = 0; index < sourcearray->NumElements(); ++index) { + SOURCEPTR sourceptr = &(*sourcearray)[index]; + BOOL remove = FALSE; + switch (combinemode) { + + case SRGN_AND: + remove = !(sourceptr->flags & SF_OVERLAPS); + break; + + case SRGN_COPY: + remove = (sourceptr->flags & SF_ADDING); + break; + + case SRGN_DIFF: + remove = (sourceptr->flags & (SF_ADDING | SF_OVERLAPS)); + break; + + case SRGN_XOR: + remove = (sourceptr->flags & SF_OVERLAPS); + break; + + } + if (remove) + DeleteSourceRect(sourcearray,index); + sourceptr->flags = 0; + } +} + +//=========================================================================== +static void ProduceCombinedRectangles (RGNPTR rgnptr) { + DWORD sourcerects = rgnptr->source.NumElements(); + rgnptr->combined.SetNumElements(0); + + // FRAGMENT THE SOURCE RECTANGLES INTO SMALLER NON-OVERLAPPING RECTANGLES + { + SOURCEPTR sourcearray = rgnptr->source.Ptr(); + for (DWORD loop = 0; loop < sourcerects; ++loop) + if (!(sourcearray[loop].flags & SF_PARAMONLY)) + FragmentCombinedRectangles(&rgnptr->combined, + 0, + rgnptr->combined.NumElements(), + &sourcearray[loop].rect); + } + + // RECOMBINE ADJACENT RECTANGLES + CombineRectangles(&rgnptr->combined); + + // SORT THE RECTANGLES VERTICALLY + qsort(rgnptr->combined.Ptr(), + rgnptr->combined.NumElements(), + sizeof(RECT), + SortRectCallback); + + // REMOVE ANY DELETED RECTANGLES (WHICH WILL HAVE BEEN SORTED TO THE + // BOTTOM OF THE ARRAY) + DWORD numrects; + while ((numrects = rgnptr->combined.NumElements()) != 0) + if (IsNullRect(&rgnptr->combined[--numrects])) + rgnptr->combined.SetNumElements(numrects); + else + break; + +} + +//=========================================================================== +static int __cdecl SortFoundParamsCallback (const void *elem1, + const void *elem2) { + FOUNDPARAMPTR ptr1 = (FOUNDPARAMPTR)elem1; + FOUNDPARAMPTR ptr2 = (FOUNDPARAMPTR)elem2; + return (ptr1->sequence-ptr2->sequence); +} + +//=========================================================================== +static int __cdecl SortRectCallback (const void *elem1, + const void *elem2) { + LPRECT rect1 = (LPRECT)elem1; + LPRECT rect2 = (LPRECT)elem2; + if (rect1->top == rect2->top) + return rect1->left-rect2->left; + else + return rect1->top-rect2->top; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +void APIENTRY SRgnClear (HSRGN handle) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATEENDVOID; + + // LOCK THE REGION + HLOCKEDRGN lockedhandle; + RGNPTR rgnptr = s_rgntable.Lock(handle,&lockedhandle); + if (!rgnptr) + return; + + // CLEAR THE REGION + ClearRegion(rgnptr); + + // UNLOCK THE REGION + s_rgntable.Unlock(lockedhandle); + +} + +//=========================================================================== +void APIENTRY SRgnCombineRect (HSRGN handle, + LPCRECT rect, + LPVOID param, + int combinemode) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(rect); + VALIDATE(combinemode >= SRGN_MIN); + VALIDATE(combinemode <= SRGN_MAX); + VALIDATEENDVOID; + + // LOCK THE REGION + HLOCKEDRGN lockedhandle; + RGNPTR rgnptr = s_rgntable.Lock(handle,&lockedhandle); + if (!rgnptr) + return; + + // IF THIS IS A SIMPLE 'OR' OPERATION, SKIP THE ITERSECTION STEP AND JUST + // ADD THE RECTANGLE TO THE REGION + if ((combinemode == SRGN_OR) || + (combinemode == SRGN_PARAMONLY)) { + if (!IsNullRect(rect)) + AddSourceRect(&rgnptr->source, + rect, + param, + ++rgnptr->sequence, + (combinemode == SRGN_PARAMONLY) + ? SF_PARAMONLY + : 0); + } + + // OTHERWISE, PERFORM AN INTERSECTION, PROCESS THE BOOLEAN OPERATOR ON + // THE RESULTING SOURCE ELEMENTS, AND ADD OR REMOVE THEM AS NECESSARY + else { + if (!IsNullRect(rect)) + FragmentSourceRectangles(&rgnptr->source, + 0, + rgnptr->source.NumElements(), + FALSE, + rect, + param, + ++rgnptr->sequence); + ProcessBooleanOperation(&rgnptr->source, + rect, + combinemode); + OptimizeSource(&rgnptr->source); + } + + // MARK THE REGION AS DIRTY + rgnptr->dirty = TRUE; + + // INVALIDATE THE CACHE OF FOUND PARAMETERS + DeleteRect(&rgnptr->foundparamsrect); + + // UNLOCK THE REGION + s_rgntable.Unlock(lockedhandle); + +} + +//=========================================================================== +void APIENTRY SRgnCreate (HSRGN *handle, + DWORD reserved) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATE(!reserved); + VALIDATEENDVOID; + + HLOCKEDRGN lockedhandle; + RGNPTR rgnptr = s_rgntable.NewLock(handle,&lockedhandle); + ClearRegion(rgnptr); + s_rgntable.Unlock(lockedhandle); +} + +//=========================================================================== +void APIENTRY SRgnDelete (HSRGN handle) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATEENDVOID; + + s_rgntable.Delete(handle); +} + +//=========================================================================== +void APIENTRY SRgnDestroy () { + s_rgntable.Destroy(); +} + +//=========================================================================== +void APIENTRY SRgnDuplicate (HSRGN orighandle, + HSRGN *handle, + DWORD reserved) { + VALIDATEBEGIN; + VALIDATEANDBLANK(handle); + VALIDATE(orighandle); + VALIDATE(!reserved); + VALIDATEENDVOID; + + HLOCKEDRGN origlockedhandle; + RGNPTR origrgnptr = s_rgntable.Lock(orighandle,&origlockedhandle); + if (!origrgnptr) + return; + + HLOCKEDRGN lockedhandle; + RGNPTR rgnptr = s_rgntable.NewLock(handle,&lockedhandle); + *rgnptr = *origrgnptr; + s_rgntable.Unlock(lockedhandle); + s_rgntable.Unlock(origlockedhandle); +} + +//=========================================================================== +void APIENTRY SRgnGetBoundingRect (HSRGN handle, + LPRECT rect) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(rect); + VALIDATEENDVOID; + + rect->left = INT_MAX; + rect->top = INT_MAX; + rect->right = INT_MIN; + rect->bottom = INT_MIN; + + // LOCK THE REGION + HLOCKEDRGN lockedhandle; + RGNPTR rgnptr = s_rgntable.Lock(handle,&lockedhandle); + if (!rgnptr) + return; + + // ADJUST THE BOUNDING RECTANGLE FOR EACH SOURCE RECTANGLE IN THE REGION + SOURCEPTR sourcearray = rgnptr->source.Ptr(); + DWORD sourcerects = rgnptr->source.NumElements(); + for (DWORD loop = 0; loop < sourcerects; ++loop) + if (!(sourcearray[loop].flags & SF_PARAMONLY)) { + rect->left = min(rect->left ,sourcearray[loop].rect.left ); + rect->top = min(rect->top ,sourcearray[loop].rect.top ); + rect->right = max(rect->right ,sourcearray[loop].rect.right ); + rect->bottom = max(rect->bottom,sourcearray[loop].rect.bottom); + } + + // UNLOCK THE REGION + s_rgntable.Unlock(lockedhandle); + + // IF THE BOUNDING RECTANGLE IS EMPTY, SET IT TO A NORMALIZED EMPTY + // RECTANGLE + if (IsNullRect(rect)) + ZeroMemory(rect,sizeof(RECT)); + +} + +//=========================================================================== +void APIENTRY SRgnGetRectParams (HSRGN handle, + LPCRECT rect, + DWORD *numparams, + LPVOID *buffer) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(rect); + VALIDATE(numparams); + VALIDATEENDVOID; + + // VERIFY THAT THE RECTANGLE IS VALID + if (IsNullRect(rect)) { + *numparams = 0; + return; + } + + // LOCK THE REGION + HLOCKEDRGN lockedhandle; + RGNPTR rgnptr = s_rgntable.Lock(handle,&lockedhandle); + if (!rgnptr) { + *numparams = 0; + return; + } + + // COMBINE THE SOURCE ELEMENTS INTO AN ARRAY OF NONOVERLAPPING RECTANGLES + if (rgnptr->dirty) { + ProduceCombinedRectangles(rgnptr); + rgnptr->dirty = FALSE; + } + + // FIND ALL SOURCE PARAMETERS WHICH OVERLAP THE GIVEN RECTANGLE + FindSourceParams(rgnptr,rect); + + // DETERMINE THE NUMBER OF SOURCE PARAMETERS TO COPY + if (buffer) + *numparams = min(*numparams,rgnptr->foundparams.NumElements()); + else + *numparams = rgnptr->foundparams.NumElements(); + + // COPY THE SOURCE PARAMETERS + if (buffer) { + FOUNDPARAMPTR foundarray = rgnptr->foundparams.Ptr(); + for (DWORD loop = 0; loop < *numparams; ++loop) + *buffer++ = (foundarray++)->param; + } + + // UNLOCK THE REGION + s_rgntable.Unlock(lockedhandle); + +} + +//=========================================================================== +void APIENTRY SRgnGetRects (HSRGN handle, + DWORD *numrects, + LPRECT buffer) { + VALIDATEBEGIN; + VALIDATE(handle); + VALIDATE(numrects); + VALIDATEENDVOID; + + // LOCK THE REGION + HLOCKEDRGN lockedhandle; + RGNPTR rgnptr = s_rgntable.Lock(handle,&lockedhandle); + if (!rgnptr) { + *numrects = 0; + return; + } + + // COMBINE THE SOURCE ELEMENTS INTO AN ARRAY OF NONOVERLAPPING RECTANGLES + if (rgnptr->dirty) { + ProduceCombinedRectangles(rgnptr); + rgnptr->dirty = FALSE; + } + + // DETERMINE THE NUMBER OF RECTANGLES TO COPY + if (buffer) + *numrects = min(*numrects,rgnptr->combined.NumElements()); + else + *numrects = rgnptr->combined.NumElements(); + + // COPY THE RECTANGLES + if (buffer) + CopyMemory(buffer, + rgnptr->combined.Ptr(), + (*numrects)*sizeof(RECT)); + + // UNLOCK THE REGION + s_rgntable.Unlock(lockedhandle); + +} diff --git a/Storm/SOURCE/SRTL.CPP b/Storm/SOURCE/SRTL.CPP new file mode 100644 index 0000000..660348a --- /dev/null +++ b/Storm/SOURCE/SRTL.CPP @@ -0,0 +1,168 @@ +/**************************************************************************** +* +* SRTL.CPP +* Replacements for select C runtime library functions +* +* By Michael O'Brien (3/6/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#ifndef STATICLIB +#define REPLACESTARTUP 1 +#define REPLACETYPEINFO 1 +#endif + +/**************************************************************************** +* +* STARTUP AND SHUTDOWN FUNCTIONS +* +***/ + +#if REPLACESTARTUP + +typedef void (__cdecl *_PVFV)(void); + +#pragma data_seg(".CRT$XIA") +_PVFV __xi_a[] = { NULL }; // C initializers (begin) +#pragma data_seg(".CRT$XIZ") +_PVFV __xi_z[] = { NULL }; // C initializers (end) +#pragma data_seg(".CRT$XCA") +_PVFV __xc_a[] = { NULL }; // C++ initializers (begin) +#pragma data_seg(".CRT$XCZ") +_PVFV __xc_z[] = { NULL }; // C++ initializers (end) +#pragma data_seg() + +static CRITICAL_SECTION s_critsect; +static DWORD s_termalloc = 0; +static _PVFV *s_termlist = NULL; +static DWORD s_termused = 0; + +extern BOOL APIENTRY DllMain (HINSTANCE, DWORD, LPVOID); + +//=========================================================================== +static void CallInitList (_PVFV *begin, _PVFV *end) { + while (begin < end) { + if (*begin) + (**begin)(); + ++begin; + } +} + +//=========================================================================== +static void RtlDestroy () { + + // CALL REGISTERED EXIT PROCEDURES (INCLUDING DESTRUCTORS FOR STATIC + // OBJECTS) IN LIFO ORDER + while (s_termused) + (**(s_termlist+(--s_termused)))(); + + // CLEAR THE LIST OF EXIT PROCEDURES + VirtualFree(s_termlist,0,MEM_RELEASE); + s_termalloc = 0; + s_termlist = NULL; + + // DESTROY LOW-LEVEL MODULES. THESE ARE DESTROYED NOW RATHER THAN DURING + // DLLMAIN() SO THAT THEY CAN BE USED BY DESTRUCTORS. + SMemDestroy(); + SErrDestroy(); + SLogDestroy(); + + // DELETE OUR CRITICAL SECTION + DeleteCriticalSection(&s_critsect); + +} + +//=========================================================================== +static void RtlInitialize () { + + // INITIALIZE OUR CRITICAL SECTION + InitializeCriticalSection(&s_critsect); + + // INITIALIZE STORM'S LOG AND MEMORY MANAGERS, SO THAT THEY CAN BE USED BY + // CLASS CONSTRUCTORS + SLogInitialize(); + SMemInitialize(); + + // CALL C/C++ INITIALIZERS (INCLUDING CONSTRUCTORS FOR STATIC OBJECTS) + CallInitList(__xi_a,__xi_z); + CallInitList(__xc_a,__xc_z); + +} + +//=========================================================================== +extern "C" BOOL APIENTRY _DllMainCRTStartup (HINSTANCE instance, + DWORD reason, + LPVOID reserved) { + if (reason == DLL_PROCESS_ATTACH) + RtlInitialize(); + BOOL result = DllMain(instance,reason,reserved); + if ((reason == DLL_PROCESS_DETACH) || + ((reason == DLL_PROCESS_ATTACH) && !result)) + RtlDestroy(); + return result; +} + +#endif // if REPLACESTARTUP + +/**************************************************************************** +* +* EXPORTED STARTUP/SHUTDOWN FUNCTIONS +* +***/ + +#if REPLACESTARTUP + +//=========================================================================== +int __cdecl atexit (_PVFV func) { + EnterCriticalSection(&s_critsect); + + // GROW THE TERMINATOR LIST IF NECESSARY + if (s_termused >= s_termalloc) { + DWORD newalloc = s_termalloc+1024; + _PVFV *newlist = (_PVFV *)VirtualAlloc(NULL,newalloc*sizeof(_PVFV),MEM_COMMIT,PAGE_READWRITE); + if (!newlist) { + LeaveCriticalSection(&s_critsect); + return EXIT_FAILURE; + } + if (s_termlist) { + CopyMemory(newlist,s_termlist,s_termalloc*sizeof(_PVFV)); + VirtualFree(s_termlist,0,MEM_RELEASE); + } + s_termalloc = newalloc; + s_termlist = newlist; + } + + // ADD THIS ENTRY TO THE TERMINATOR LIST + *(s_termlist+s_termused++) = func; + + LeaveCriticalSection(&s_critsect); + return EXIT_SUCCESS; +} + +#endif // if REPLACESTARTUP + +/**************************************************************************** +* +* EXPORTED TYPEINFO FUNCTIONS +* +***/ + +#if REPLACETYPEINFO + +//=========================================================================== +type_info::type_info (const type_info& rhs) { +} + +//=========================================================================== +type_info::~type_info() { +} + +//=========================================================================== +type_info& type_info::operator= (const type_info& rhs) { + return *this; +} + +#endif // if REPLACETYPEINFO diff --git a/Storm/SOURCE/SSTR.CPP b/Storm/SOURCE/SSTR.CPP new file mode 100644 index 0000000..1d0d5b1 --- /dev/null +++ b/Storm/SOURCE/SSTR.CPP @@ -0,0 +1,396 @@ +/**************************************************************************** +* +* SSTR.CPP +* String manipulation functions +* +* By Michael O'Brien (5/29/97) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define QUOTECHAR '\"' + +typedef union _PACKED { + DWORD dword; + BYTE byte[4]; +} PACKED, *PACKEDPTR; + +static const DWORD s_hashtable[16] = {0x486e26ee,0xdcaa16b3,0xe1918eef,0x202dafdb, + 0x341c7dc7,0x1c365303,0x40ef2d37,0x65fd5e49, + 0xd6057177,0x904ece93,0x1c38024f,0x98fd323b, + 0xe3061ae7,0xa39b0fa1,0x9797f25f,0xe4444563}; + +/**************************************************************************** +* +* MACROS +* +* These macros implement routines to copy strings either a byte or dword at +* at time, and to search for null terminators either a byte or dword at a +* time. +* +* To check a dword for a null terminator, the macros add the 32-bit +* constant 0x7EFEFEFF to the dword value. This causes an overflow in each +* byte in the dword unless that byte is zero. The macros then xor the +* result with the original to see which bits have changed, in order to +* determine whether there were any bytes that didn't overflow. This test is +* fast (it executes in three clock cycles on an Intel system) and 100% +* accurate in identifying null terminators where they exist. There is one +* case (0x80010101) where it falsely identifies a null terminator where none +* exists, so the code in the macros that is executed in response to a +* positive result has to test all four bytes for a null terminator, not just +* three. +* +* These macros are designed to give good performance on all systems, but are +* especially tweaked for MSVC on Intel systems, where they generate code +* that is the same as the most efficient possible assembly language +* implementation of the algorithm. This tweaking adds some complexity to +* the code, as follows: +* +* - The code to handle a dword with a null terminator in it is placed +* in a separate loop from the code that handles non-terminating dwords, +* rather than a separate "if" statement in the same loop, because +* Microsoft's compiler always generates an unconditional jump rather +* than a conditional one to a target address that can be reached from +* two or more jump statements. +* +* - The code that tests for overflows in the byte components of a dword +* tricks the compiler into thinking that the result of the test is used +* for more than just the conditional jump, so that the compiler will +* generate an "and" rather than a "test" instruction, because "and" is +* fully pairable on a Pentium processor while "test" with an immediate +* is not. +* +* - The code that checks for null bytes in a dword also emulates a "not" +* instruction by subtracting the value from 0xFFFFFFFF. Subtracting a +* value from a register and then restoring the contents of that register +* requires a total of one clock cycle on a Pentium, which is the same as +* a "not" instruction; however, it increases the opportunities for the +* compiler to reshuffle code in order to avoid delays caused by data +* dependence, and that makes a critical speed difference in this case. +* +* - The same code also tricks the compiler into thinking that the constant +* 0xFFFFFFFF might be changed at some point, so that it will store it +* in a register rather than using it as an immediate value, because +* otherwise MSVC generates code to load the immediate value into a +* register once for each iteration of the loop. +* +* Most of these tweaks are separated out in an Intel-specific macro, so that +* a more straightforward implementation of the algorithm gets used on non- +* Intel systems. +* +***/ + +//=========================================================================== +#ifdef _X86_ + static DWORD s_check_markresultused; + #define INITDWORDOPERATIONS \ + DWORD check_modnum; \ + DWORD check_notnum = 0xFFFFFFFF + #define CHECKFORNULLBYTES(num) \ + (check_modnum = (num)+0x7EFEFEFF, \ + check_notnum -= (num), \ + check_modnum ^= check_notnum, \ + check_notnum |= (num), \ + check_modnum &= 0x81010101) + #define CHECK_ENDLOOP \ + s_check_markresultused = check_modnum +#else + #define INITDWORDOPERATIONS + #define CHECKFORNULLBYTES(num) \ + (((((num)+0x7EFEFEFF) ^ (num)) & 0x81010100) != 0x81010100) + #define CHECK_ENDLOOP +#endif + +//=========================================================================== +#ifdef _X86_ + #define CHECKFORNULLBYTE0(packed) (!packed.byte[0]) + #define CHECKFORNULLBYTE1(packed) (!packed.byte[1]) + #define CHECKFORNULLBYTE2(packed) (!(packed.dword & 0x00FF0000)) + #define CHECKFORNULLBYTE3(packed) (!(packed.dword & 0xFF000000)) +#else + #define CHECKFORNULLBYTE0(packed) (!packed.byte[0]) + #define CHECKFORNULLBYTE1(packed) (!packed.byte[1]) + #define CHECKFORNULLBYTE2(packed) (!packed.byte[2]) + #define CHECKFORNULLBYTE3(packed) (!packed.byte[3]) +#endif + +//=========================================================================== +#define BEGINSKIP + +//=========================================================================== +#define SKIPLEADINGBYTES \ + for (; \ + (DWORD)currdest & 3; \ + ++currdest) \ + if (!*currdest) \ + goto endskip + +//=========================================================================== +#define SKIPALIGNEDDWORDS \ + do { \ + PACKED packed = *(PACKEDPTR)currdest; \ + currdest += sizeof(PACKED); \ + if (!CHECKFORNULLBYTES(packed.dword)) \ + continue; \ + if (CHECKFORNULLBYTE0(packed)) { \ + currdest -= 4; \ + goto endskip; \ + } \ + if (CHECKFORNULLBYTE1(packed)) { \ + currdest -= 3; \ + goto endskip; \ + } \ + if (CHECKFORNULLBYTE2(packed)) { \ + currdest -= 2; \ + goto endskip; \ + } \ + if (CHECKFORNULLBYTE3(packed)) { \ + currdest -= 1; \ + goto endskip; \ + } \ + CHECK_ENDLOOP; \ + } while (1) + +//=========================================================================== +#define ENDSKIP \ + endskip: + +//=========================================================================== +#define BEGINCOPY \ + DWORD negoffset = (DWORD)-(int)(destsize-(currdest-dest)) + +//=========================================================================== +#define COPYLEADINGBYTES \ + while (((DWORD)source & 3) && negoffset) \ + if (!(*(enddest+negoffset++) = *source++)) \ + goto endcopy; + +//=========================================================================== +#define COPYALIGNEDDWORDS \ + if ((int)(negoffset += 3) < 0) { \ + enddest -= 3; \ + \ + PACKED packed = *(PACKEDPTR)source; \ + source += sizeof(PACKED); \ + while (!CHECKFORNULLBYTES(packed.dword)) { \ + *(PACKEDPTR)(enddest+negoffset) = packed; \ + if ((int)(negoffset += 4) >= 0) \ + goto donealigned; \ + packed = *(PACKEDPTR)source; \ + source += sizeof(PACKED); \ + } \ + for (;;) { \ + if (CHECKFORNULLBYTE0(packed)) { \ + *(enddest+negoffset) = packed.byte[0]; \ + negoffset += 1; \ + goto endcopy; \ + } \ + if (CHECKFORNULLBYTE1(packed)) { \ + *(LPWORD)(enddest+negoffset) = (WORD)(packed.dword); \ + negoffset += 2; \ + goto endcopy; \ + } \ + if (CHECKFORNULLBYTE2(packed)) { \ + *(LPWORD)(enddest+negoffset) = (WORD)(packed.dword); \ + *(enddest+negoffset+2) = 0; \ + negoffset += 3; \ + goto endcopy; \ + } \ + *(PACKEDPTR)(enddest+negoffset) = packed; \ + negoffset += sizeof(PACKED); \ + if (CHECKFORNULLBYTE3(packed)) \ + goto endcopy; \ + CHECK_ENDLOOP; \ + if ((int)negoffset >= 0) \ + goto donealigned; \ + packed = *(PACKEDPTR)source; \ + source += sizeof(PACKED); \ + } \ + \ + donealigned: \ + enddest += 3; \ + } \ + negoffset -= 3 + +//=========================================================================== +#define COPYTRAILINGBYTES \ + while (negoffset) \ + if (!(*(enddest+negoffset++) = *source++)) \ + goto endcopy; \ + *enddest = 0 + +//=========================================================================== +#define ENDCOPY \ + endcopy: \ + currdest = enddest+(negoffset-1); + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +LPTSTR APIENTRY SStrChr (LPCTSTR string, + char ch, + BOOL reverse) { + LPTSTR last = NULL; + if (reverse) { + for (LPCTSTR curr = string; *curr; ++curr) + if (*curr == ch) + last = (LPTSTR)curr; + } + else { + for (LPCTSTR curr = string; *curr; ++curr) + if (*curr == ch) + return (LPTSTR)curr; + } + return last; +} + +//=========================================================================== +DWORD APIENTRY SStrCopy (LPTSTR dest, + LPCTSTR source, + DWORD destsize) { + if (!destsize--) + return 0; + + INITDWORDOPERATIONS; + LPTSTR currdest = dest; + LPTSTR enddest = dest+destsize; + + BEGINCOPY; + COPYLEADINGBYTES; + COPYALIGNEDDWORDS; + COPYTRAILINGBYTES; + ENDCOPY; + + return currdest-dest; +} + +//=========================================================================== +DWORD APIENTRY SStrHash (LPCTSTR string, + DWORD flags, + DWORD seed) { + DWORD result = seed ? seed : 0x7FED7FED; + DWORD adjust = 0xEEEEEEEE; + DWORD ch; + if (flags & SSTR_HASH_CASESENSITIVE) + while ((ch = (DWORD)(BYTE)*(string++)) != 0) { + result = (result+adjust) ^ (s_hashtable[ch >> 4] - s_hashtable[ch & 0x0F]); + adjust += ch+result+(adjust << 5)+3; + } + else + while ((ch = (DWORD)(BYTE)*(string++)) != 0) { + if ((ch >= (DWORD)'a') && (ch <= (DWORD)'z')) + ch = ch+(DWORD)'A'-(DWORD)'a'; + if (ch == (DWORD)'/') + ch = (DWORD)'\\'; + result = (result+adjust) ^ (s_hashtable[ch >> 4] - s_hashtable[ch & 0x0F]); + adjust += ch+result+(adjust << 5)+3; + } + if (!result) + ++result; + return result; +} + +//=========================================================================== +DWORD APIENTRY SStrLen (LPCTSTR string) { + + INITDWORDOPERATIONS; + LPCTSTR currdest = string; + + BEGINSKIP; + SKIPLEADINGBYTES; + SKIPALIGNEDDWORDS; + ENDSKIP; + + return currdest-string; +} + +//=========================================================================== +void APIENTRY SStrPack (LPTSTR dest, + LPCTSTR source, + DWORD destsize) { + if (!destsize--) + return; + + INITDWORDOPERATIONS; + LPTSTR currdest = dest; + LPTSTR enddest = dest+destsize; + + // FORCE THE DESTINATION BUFFER TO BE NULL TERMINATED + if (destsize != SSTR_UNBOUNDED) + *enddest = 0; + + BEGINSKIP; + SKIPLEADINGBYTES; + SKIPALIGNEDDWORDS; + ENDSKIP; + + BEGINCOPY; + COPYLEADINGBYTES; + COPYALIGNEDDWORDS; + COPYTRAILINGBYTES; + ENDCOPY; + +} + +//=========================================================================== +void APIENTRY SStrTokenize (LPCTSTR *string, + LPTSTR buffer, + DWORD bufferchars, + LPCTSTR whitespace, + BOOL *quoted) { + BOOL checkquotes = (SStrChr(whitespace,QUOTECHAR) != NULL); + BOOL inquotes = FALSE; + BOOL usedquotes = FALSE; + LPCTSTR currsource = *string; + + // SKIP PAST ALL LEADING WHITESPACE + while ((*currsource) && SStrChr(whitespace,*currsource)) { + if (checkquotes && (*currsource == QUOTECHAR)) { + usedquotes = TRUE; + inquotes = !inquotes; + } + ++currsource; + } + + // COPY THE TOKEN + DWORD destchars = 0; + char ch; + while ((ch = *currsource) != 0) + if (checkquotes && (ch == QUOTECHAR)) { + if (destchars && !inquotes) + break; + usedquotes = TRUE; + inquotes = !inquotes; + ++currsource; + if (!inquotes) + break; + } + else if (inquotes || !SStrChr(whitespace,ch)) { + if (destchars+1 < bufferchars) + buffer[destchars++] = ch; + ++currsource; + } + else { + ++currsource; + break; + } + + // NULL TERMINATE THE BUFFER + if (destchars < bufferchars) + buffer[destchars] = 0; + + // RETURN AN UPDATED POINTER INTO THE SOURCE STRING + *string = currsource; + + // RETURN TO THE APPLICATION A BOOLEAN TELLING WHETHER THIS TOKEN + // WAS IN QUOTES + if (quoted) + *quoted = usedquotes; + +} diff --git a/Storm/SOURCE/STANDARD/CAPS.DAT b/Storm/SOURCE/STANDARD/CAPS.DAT new file mode 100644 index 0000000..b65b837 Binary files /dev/null and b/Storm/SOURCE/STANDARD/CAPS.DAT differ diff --git a/Storm/SOURCE/STANDARD/CAPS.MPQ b/Storm/SOURCE/STANDARD/CAPS.MPQ new file mode 100644 index 0000000..b19306e Binary files /dev/null and b/Storm/SOURCE/STANDARD/CAPS.MPQ differ diff --git a/Storm/SOURCE/STANDARD/Debug/IPX.obj b/Storm/SOURCE/STANDARD/Debug/IPX.obj new file mode 100644 index 0000000..7855002 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/IPX.obj differ diff --git a/Storm/SOURCE/STANDARD/Debug/MODEM.obj b/Storm/SOURCE/STANDARD/Debug/MODEM.obj new file mode 100644 index 0000000..bdcb7f1 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/MODEM.obj differ diff --git a/Storm/SOURCE/STANDARD/Debug/NULL.obj b/Storm/SOURCE/STANDARD/Debug/NULL.obj new file mode 100644 index 0000000..9b5857d Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/NULL.obj differ diff --git a/Storm/SOURCE/STANDARD/Debug/PERF.obj b/Storm/SOURCE/STANDARD/Debug/PERF.obj new file mode 100644 index 0000000..271d49e Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/PERF.obj differ diff --git a/Storm/SOURCE/STANDARD/Debug/SERIAL.obj b/Storm/SOURCE/STANDARD/Debug/SERIAL.obj new file mode 100644 index 0000000..4e282d3 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/SERIAL.obj differ diff --git a/Storm/SOURCE/STANDARD/Debug/STANDARD.obj b/Storm/SOURCE/STANDARD/Debug/STANDARD.obj new file mode 100644 index 0000000..1059455 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/STANDARD.obj differ diff --git a/Storm/SOURCE/STANDARD/Debug/STANDARD.res b/Storm/SOURCE/STANDARD/Debug/STANDARD.res new file mode 100644 index 0000000..9b18850 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/STANDARD.res differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.ilk b/Storm/SOURCE/STANDARD/Debug/Standard.ilk new file mode 100644 index 0000000..e84944e Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.ilk differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.log b/Storm/SOURCE/STANDARD/Debug/Standard.log new file mode 100644 index 0000000..bf6b08a --- /dev/null +++ b/Storm/SOURCE/STANDARD/Debug/Standard.log @@ -0,0 +1,122 @@ + IPX.CPP +D:\projects\Hellfire\Storm\H\STORM.H(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'IPX.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'IPX.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'IPX.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'IPX.CPP') + +D:\projects\Hellfire\Storm\SOURCE\STANDARD\IPX.CPP(276,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\IPX.CPP(280,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\IPX.CPP(702,9): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\IPX.CPP(725,11): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\IPX.CPP(1035,20): warning C4996: 'GetVersion': was declared deprecated +D:\projects\Hellfire\Storm\SOURCE\STANDARD\IPX.CPP(1244,41): warning C4267: '=': conversion from 'size_t' to 'WORD', possible loss of data + MODEM.CPP +D:\projects\Hellfire\Storm\H\STORM.H(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'MODEM.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'MODEM.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'MODEM.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'MODEM.CPP') + +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP(373,87): warning C4244: '=': conversion from 'unsigned long' to 'BYTE', possible loss of data +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP(497,13): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP(498,13): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP(1236,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP(1588,3): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP(2123,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP(2124,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. + NULL.CPP +D:\projects\Hellfire\Storm\H\STORM.H(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'NULL.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'NULL.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'NULL.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'NULL.CPP') + + PERF.CPP +D:\projects\Hellfire\Storm\H\STORM.H(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'PERF.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'PERF.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'PERF.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'PERF.CPP') + + SERIAL.CPP +D:\projects\Hellfire\Storm\H\STORM.H(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'SERIAL.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'SERIAL.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SERIAL.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SERIAL.CPP') + +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP(333,15): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP(334,15): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP(408,87): warning C4244: '=': conversion from 'unsigned long' to 'BYTE', possible loss of data +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP(955,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP(956,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP(962,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP(963,3): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. + STANDARD.CPP +D:\projects\Hellfire\Storm\H\STORM.H(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/STANDARD.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/STANDARD.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/STANDARD.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/STANDARD.CPP') + + TRACE.CPP +D:\projects\Hellfire\Storm\H\STORM.H(970,21): warning C4595: 'operator delete': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/TRACE.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(975,23): warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/TRACE.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(981,21): warning C4595: 'operator delete[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/TRACE.CPP') + +D:\projects\Hellfire\Storm\H\STORM.H(986,23): warning C4595: 'operator new[]': non-member operator new or delete functions may not be declared inline + (compiling source file 'SOURCE/STANDARD/TRACE.CPP') + +D:\projects\Hellfire\Storm\SOURCE\STANDARD\TRACE.CPP(36,18): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\TRACE.CPP(73,3): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\TRACE.CPP(76,5): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\TRACE.CPP(109,3): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\TRACE.CPP(112,3): warning C4996: 'vsprintf': This function or variable may be unsafe. Consider using vsprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +D:\projects\Hellfire\Storm\SOURCE\STANDARD\TRACE.CPP(114,3): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. + Generating Code... + Creating library D:\projects\Hellfire\Storm\SOURCE\STANDARD\..\..\..\bin\Standard.lib and object D:\projects\Hellfire\Storm\SOURCE\STANDARD\..\..\..\bin\Standard.exp + Standard.vcxproj -> D:\projects\Hellfire\bin\Standard.snp + 'pwsh.exe' is not recognized as an internal or external command, + operable program or batch file. diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.snp.recipe b/Storm/SOURCE/STANDARD/Debug/Standard.snp.recipe new file mode 100644 index 0000000..84d75d6 --- /dev/null +++ b/Storm/SOURCE/STANDARD/Debug/Standard.snp.recipe @@ -0,0 +1,14 @@ + + + + + D:\projects\Hellfire\Storm\Debug\stormdll.dll + + + D:\projects\Hellfire\bin\Standard.snp + + + + + + \ No newline at end of file diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.command.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.command.1.tlog new file mode 100644 index 0000000..3467360 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.command.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.read.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.read.1.tlog new file mode 100644 index 0000000..befd96e Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.read.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.write.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.write.1.tlog new file mode 100644 index 0000000..f65906a Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/CL.write.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/Cl.items.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/Cl.items.tlog new file mode 100644 index 0000000..0b63e0a --- /dev/null +++ b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/Cl.items.tlog @@ -0,0 +1,7 @@ +D:\projects\Hellfire\Storm\SOURCE\STANDARD\IPX.CPP;D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\IPX.obj +D:\projects\Hellfire\Storm\SOURCE\STANDARD\MODEM.CPP;D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\MODEM.obj +D:\projects\Hellfire\Storm\SOURCE\STANDARD\NULL.CPP;D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\NULL.obj +D:\projects\Hellfire\Storm\SOURCE\STANDARD\PERF.CPP;D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\PERF.obj +D:\projects\Hellfire\Storm\SOURCE\STANDARD\SERIAL.CPP;D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\SERIAL.obj +D:\projects\Hellfire\Storm\SOURCE\STANDARD\STANDARD.CPP;D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\STANDARD.obj +D:\projects\Hellfire\Storm\SOURCE\STANDARD\TRACE.CPP;D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\TRACE.obj diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/Standard.lastbuildstate b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/Standard.lastbuildstate new file mode 100644 index 0000000..de3d96e --- /dev/null +++ b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/Standard.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v145:VCToolArchitecture=Native32Bit:VCToolsVersion=14.50.35717:VCServicingVersionCompilers=14.50.35728:TargetPlatformVersion=10.0.26100.0:VcpkgTriplet=x86-windows: +Debug|Win32|D:\projects\Hellfire\| diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.command.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.command.1.tlog new file mode 100644 index 0000000..e5f7a47 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.command.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.read.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.read.1.tlog new file mode 100644 index 0000000..53e74f5 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.read.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.secondary.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.secondary.1.tlog new file mode 100644 index 0000000..ed98b84 --- /dev/null +++ b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.secondary.1.tlog @@ -0,0 +1,4 @@ +^D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\IPX.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\MODEM.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\NULL.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\PERF.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\SERIAL.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\STANDARD.OBJ|D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\STANDARD.RES|D:\PROJECTS\HELLFIRE\STORM\SOURCE\STANDARD\DEBUG\TRACE.OBJ|D:\PROJECTS\HELLFIRE\WINDEBUG\STORM.LIB +D:\projects\Hellfire\bin\Standard.LIB +D:\projects\Hellfire\bin\Standard.EXP +D:\projects\Hellfire\Storm\SOURCE\STANDARD\Debug\Standard.ilk diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.write.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.write.1.tlog new file mode 100644 index 0000000..240df5a Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/link.write.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.command.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.command.1.tlog new file mode 100644 index 0000000..647ff62 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.command.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.read.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.read.1.tlog new file mode 100644 index 0000000..8b910e7 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.read.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.write.1.tlog b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.write.1.tlog new file mode 100644 index 0000000..ca13cbc Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/Standard.tlog/rc.write.1.tlog differ diff --git a/Storm/SOURCE/STANDARD/Debug/TRACE.obj b/Storm/SOURCE/STANDARD/Debug/TRACE.obj new file mode 100644 index 0000000..857c4e2 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/TRACE.obj differ diff --git a/Storm/SOURCE/STANDARD/Debug/vc145.idb b/Storm/SOURCE/STANDARD/Debug/vc145.idb new file mode 100644 index 0000000..799de6c Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/vc145.idb differ diff --git a/Storm/SOURCE/STANDARD/Debug/vc145.pdb b/Storm/SOURCE/STANDARD/Debug/vc145.pdb new file mode 100644 index 0000000..3e2bdd6 Binary files /dev/null and b/Storm/SOURCE/STANDARD/Debug/vc145.pdb differ diff --git a/Storm/SOURCE/STANDARD/Debug/vcpkg.applocal.log b/Storm/SOURCE/STANDARD/Debug/vcpkg.applocal.log new file mode 100644 index 0000000..e02abfc --- /dev/null +++ b/Storm/SOURCE/STANDARD/Debug/vcpkg.applocal.log @@ -0,0 +1 @@ + diff --git a/Storm/SOURCE/STANDARD/IPX.CPP b/Storm/SOURCE/STANDARD/IPX.CPP new file mode 100644 index 0000000..95ea837 --- /dev/null +++ b/Storm/SOURCE/STANDARD/IPX.CPP @@ -0,0 +1,1374 @@ +/**************************************************************************** +* +* IPX.CPP +* IPX network provider +* +* By Michael O'Brien (4/22/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define ADVPORT 6111 +#define MAINPORT 6112 +#define MAXMESSAGESIZE 504 +#define MAXPLAYERS 256 +#define PROVIDERID 'IPXN' +#define RECVDATATHREADS 2 + +#define ADTYPE_GAMEINFO 0 +#define ADTYPE_REMOVE 1 +#define ADTYPE_REQUEST 2 + +typedef struct _ADVHEADER { + WORD checksum; // must be first field + WORD length; + WORD type; + WORD reserved; + DWORD programid; + DWORD versionid; + DWORD gamemode; +} ADVHEADER, *ADVHEADERPTR; + +typedef struct _ADVPACKET { + ADVHEADER header; + char strings[SNETSPI_MAXSTRINGLENGTH*2]; + BYTE clientdatabuffer[SNETSPI_MAXCLIENTDATA]; +} ADVPACKET, *ADVPACKETPTR; + +typedef struct _PACKET { + SNETADDR addr; // must be first field in structure + BYTE data[MAXMESSAGESIZE]; + DWORD databytes; + _PACKET *next; +} PACKET, *PACKETPTR; + +typedef struct _UIPARAMS { + DWORD flags; + SNETPROGRAMDATAPTR programdata; + SNETPLAYERDATAPTR playerdata; + SNETUIDATAPTR interfacedata; + SNETVERSIONDATAPTR versiondata; + LPDWORD playeridptr; +} UIPARAMS, *UIPARAMSPTR; + +typedef struct _THREAD { + unsigned id; + HANDLE handle; + _THREAD *next; +} THREAD, *THREADPTR; + +typedef struct _WINSOCKAPI { + int (APIENTRY *bind )(SOCKET,const sockaddr *,int); + int (APIENTRY *closesocket)(SOCKET); + u_short (APIENTRY *htons )(u_short); + int (APIENTRY *recvfrom )(SOCKET,char *,int,int,sockaddr *,int *); + int (APIENTRY *sendto )(SOCKET,const char *,int,int,const sockaddr *,int); + int (APIENTRY *setsockopt )(SOCKET,int,int,const char *,int); + SOCKET (APIENTRY *socket )(int,int,int); + int (APIENTRY *WSAStartup )(WORD,LPWSADATA); + int (APIENTRY *WSACleanup )(); +} WINSOCKAPI, *WINSOCKAPIPTR; + +static ADVPACKETPTR ipx_advgameinfo = NULL; +static SOCKET ipx_advsocket = (SOCKET)0; +static SOCKADDR_IPX ipx_broadcastaddr = {0}; +static CCritSect ipx_critsect; +static SNETSPI_GAMELISTPTR ipx_gamehead = NULL; +static SOCKADDR_IPX ipx_localaddr = {0}; +static DWORD ipx_nextgameid = 0; +static SOCKET ipx_mainsocket = (SOCKET)0; +static DWORD ipx_maxplayers = MAXPLAYERS; +static PACKETPTR ipx_packethead = NULL; +static PACKETPTR ipx_pendingreadpkt[RECVDATATHREADS] = {NULL,NULL}; +static DWORD ipx_programid = 0; +static HANDLE ipx_recvevent = NULL; +static BOOL ipx_shutdown = 0; +static THREADPTR ipx_threadhead = NULL; +static DWORD ipx_versionid = 0; +static WINSOCKAPIPTR ipx_winsockapi = NULL; +static HINSTANCE ipx_winsocklib = (HINSTANCE)0; + +static void SendAdvertisement (SOCKADDR_IPX *addr); +static void SendRequest (); +static void TrimGameList (DWORD timeout); +static void UpdateGameList (HWND dialog, HWND listbox); +BOOL CALLBACK IpxCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude); +BOOL CALLBACK IpxStopAdvertisingGame (); + +//=========================================================================== +static BOOL inline BindToWinsock () { + + // LOAD THE WINSOCK LIBRARY + if (!ipx_winsocklib) { + ipx_winsocklib = LoadLibrary(TEXT("wsock32.dll")); + if (!ipx_winsocklib) + return 0; + } + + // ALLOCATE AN API STRUCTURE + if (!ipx_winsockapi) { + ipx_winsockapi = NEW(WINSOCKAPI); + if (!ipx_winsockapi) + return 0; + } + + // BIND TO THE INDIVIDUAL FUNCTIONS + BOOL success = 1; +#define BIND(a,b) *(void **)&ipx_winsockapi->##a \ + = GetProcAddress(ipx_winsocklib,(LPCSTR)MAKELONG((b),0)); \ + if (!ipx_winsockapi->##a) \ + success = 0; + BIND(bind ,2); + BIND(closesocket,3); + BIND(htons ,9); + BIND(recvfrom ,17); + BIND(sendto ,20); + BIND(setsockopt ,21); + BIND(socket ,23); + BIND(WSAStartup ,115); + BIND(WSACleanup ,116); +#undef BIND + return success; +} + +//=========================================================================== +static WORD ComputeChecksum (LPVOID data, DWORD databytes) { + DWORD checkval1 = 0; + DWORD checkval2 = 0; + LPBYTE ptr = ((LPBYTE)data)+databytes-1; + while (databytes--) { + checkval1 += *ptr--; + if (checkval1 >= 0xFF) + checkval1 -= 0xFF; + checkval2 += checkval1; + } + checkval2 %= 255; + return MAKEWORD((checkval2 & 0xFF),(checkval1 & 0xFF)); +} + +//=========================================================================== +static WORD GenerateChecksum (LPVOID packet, DWORD bytes) { + + // COMPUTE THE CURRENT CHECKSUM FOR THE MESSAGE + WORD checksum = ComputeChecksum(((LPBYTE)packet)+sizeof(WORD), + bytes-sizeof(WORD)); + + // COMPUTE A NEW VALUE FOR THE CHECKSUM FIELD THAT WILL MAKE THE NEW + // CHECKSUM OF THE ENTIRE MESSAGE ZERO + BYTE hibyte = 0xFF-((checksum >> 8)+(checksum & 0xFF)) % 0xFF; + BYTE lobyte = 0xFF-((checksum >> 8)+hibyte) % 0xFF; + return MAKEWORD(lobyte,hibyte); +} + +//=========================================================================== +static BOOL LoadArtwork (SNETGETARTPROC artcallback, + DWORD providerid, + DWORD artid, + BOOL setpalette, + LPBYTE *data, + SIZE *size) { + *data = 0; + size->cx = 0; + size->cy = 0; + + // VERIFY THAT THE APPLICATION HAS REGISTERED AN ARTWORK CALLBACK + if (!artcallback) + return 0; + + // CALL THE ARTWORK CALLBACK TO DETERMINE THE IMAGE DIMENSIONS + int width; + int height; + int bitdepth; + if (!artcallback(providerid, + artid, + NULL, + NULL, + 0, + &width, + &height, + &bitdepth)) + return 0; + if (size) { + size->cx = width; + size->cy = height; + } + + // ALLOCATE MEMORY FOR THE IMAGE + DWORD bytes = width*height*bitdepth/8; + if (!(*data = (LPBYTE)ALLOC(bytes))) + return 0; + + // LOAD THE IMAGE + PALETTEENTRY pe[256]; + if (!artcallback(providerid, + artid, + &pe[0], + *data, + bytes, + &width, + &height, + &bitdepth)) { + FREE(*data); + *data = NULL; + return 0; + } + + // IF REQUESTED, UPDATE THE SYSTEM PALETTE + if (setpalette) + SDrawUpdatePalette(1,254,&pe[1]); + + return 1; +} + +//=========================================================================== +static void ProcessIncomingAd (SOCKADDR_IPX *incomingaddr, + ADVPACKETPTR incomingad, + BOOL remove) { + + // FIX THE INCOMING ADDRESS SO IT POINTS TO THE MAIN PORT, + // NOT THE ADVERTISING PORT + if (ipx_winsockapi && ipx_winsockapi->htons) + incomingaddr->sa_socket = ipx_winsockapi->htons(MAINPORT); + + // ENTER THE CRITICAL SECTION + ipx_critsect.Enter(); + + // DELETE ALL GAMES IN OUR LIST FROM THIS ADDRESS + DWORD gameid = 0; + { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) + if (!memcmp(&curr->owner,incomingaddr,sizeof(SOCKADDR_IPX))) { + gameid = curr->gameid; + SNETSPI_GAMELISTPTR next = curr->next; + FREEIFUSED(curr->clientdata); + LISTFREE(&ipx_gamehead,curr); + curr = next; + } + else + curr = curr->next; + } + + // IF THIS GAME WAS NOT ALREADY IN THE LIST, ADD A NEW ID FOR IT. + // MAKE SURE WE NEVER ASSIGN AN ID OF ZERO. + if (!gameid) + gameid = ++ipx_nextgameid; + if (!gameid) + gameid = ++ipx_nextgameid; + + // IF THIS GAME MATCHES OUR PROGRAM ID AND VERSION ID, AND WE'RE NOT + // REMOVING, THEN ADD IT TO THE LIST + if ((incomingad->header.programid == ipx_programid) && + (incomingad->header.versionid == ipx_versionid) && + !remove) { + SNETSPI_GAMELIST game; + ZeroMemory(&game,sizeof(SNETSPI_GAMELIST)); + game.gameid = gameid; + game.gamemode = incomingad->header.gamemode; + CopyMemory(&game.owner,incomingaddr,sizeof(SOCKADDR_IPX)); + game.ownerlatency = 50; + game.ownerlasttime = GetTickCount(); + LPSTR currptr = incomingad->strings; + strncpy(game.gamename, + currptr, + SNETSPI_MAXSTRINGLENGTH); + currptr += strlen(currptr)+1; + strncpy(game.gamedescription, + currptr, + SNETSPI_MAXSTRINGLENGTH); + currptr += strlen(currptr)+1; + game.clientdatabytes = (incomingad->header.length-(currptr-(LPSTR)incomingad)); + game.clientdata = ALLOC(game.clientdatabytes); + CopyMemory(game.clientdata,currptr,game.clientdatabytes); + LISTADD(&ipx_gamehead,&game); + } + + // LEAVE THE CRITICAL SECTION + ipx_critsect.Leave(); + +} + +//=========================================================================== +static unsigned CALLBACK RecvAdThreadProc (LPVOID param) { + if (!(ipx_winsockapi && ipx_winsockapi->recvfrom)) { + _endthreadex(0); + return 0; + } + + // SEND OUT A REQUEST FOR ADVERTISEMENTS + SendRequest(); + + ADVPACKET incomingad; + while (ipx_advsocket && !ipx_shutdown) { + + // PROCESS ALL INCOMING ADVERTISEMENTS + SOCKADDR_IPX incomingaddr; + int addrsize = sizeof(SOCKADDR_IPX); + int bytesread = 0; + bytesread = ipx_winsockapi->recvfrom(ipx_advsocket, + (char *)&incomingad, + sizeof(ADVPACKET), + 0, + (sockaddr *)&incomingaddr, + &addrsize); + PerfIncrement(PERF_PKTRECV); + PerfAdd(PERF_BYTESRECV,bytesread); + if ((bytesread >= sizeof(ADVHEADER)) && + (incomingad.header.length == bytesread) && + !ComputeChecksum(&incomingad,incomingad.header.length)) + switch (incomingad.header.type) { + + case ADTYPE_GAMEINFO: + case ADTYPE_REMOVE: + ProcessIncomingAd(&incomingaddr, + &incomingad, + (incomingad.header.type == ADTYPE_REMOVE)); + break; + + case ADTYPE_REQUEST: + SendAdvertisement(&incomingaddr); + break; + + } + + } + + // FREE THE LIST OF GAMES + { + SNETSPI_GAMELISTPTR curr; + while ((curr = ipx_gamehead) != NULL) { + FREEIFUSED(curr->clientdata); + LISTFREE(&ipx_gamehead,curr); + } + } + + _endthreadex(0); + return 0; +} + +//=========================================================================== +static unsigned CALLBACK RecvDataThreadProc (LPVOID param) { + if (!(ipx_winsockapi && ipx_winsockapi->recvfrom)) { + _endthreadex(0); + return 0; + } + while (ipx_mainsocket && !ipx_shutdown) { + + // ALLOCATE MEMORY FOR THE NEXT INCOMING PACKET + PACKETPTR pkt = NEW(PACKET); + int loop; + ipx_critsect.Enter(); + for (loop = 0; loop < RECVDATATHREADS; ++loop) + if (!ipx_pendingreadpkt[loop]) { + ipx_pendingreadpkt[loop] = pkt; + break; + } + ipx_critsect.Leave(); + + // RECEIVE A PACKET, BLOCKING IF ONE IS NOT AVAILABLE YET. WHEN THE + // NETWORK DRIVER HAS INCOMING DATA ON A PORT, IT WILL COPY IT DIRECTLY + // TO THE APPLICATION'S ADDRESS SPACE IF THE APPLICATION IS BLOCKING ON + // A READ. FOR THIS REASON, WE TRY TO ALWAYS HAVE AT LEAST ONE READ + // PENDING. + int addrsize = sizeof(SOCKADDR_IPX); + int bytesread = 0; + bytesread = ipx_winsockapi->recvfrom(ipx_mainsocket, + (char *)&pkt->data, + MAXMESSAGESIZE, + 0, + (sockaddr *)&pkt->addr, + &addrsize); + PerfIncrement(PERF_PKTRECV); + PerfAdd(PERF_BYTESRECV,bytesread); + pkt->databytes = bytesread; + ZeroMemory(((LPBYTE)&pkt->addr)+addrsize,sizeof(SNETADDR)-addrsize); + + // ON A SUCCESSFUL READ, QUEUE THE PACKET. SINCE WE DON'T TIME OUT ON + // READS, THE ONLY WAY A READ CAN FAIL IS IF THE SOCKET WAS CLOSED. + // IN THIS CASE, SHUT DOWN THE THREAD. + ipx_critsect.Enter(); + for (loop = 0; loop < RECVDATATHREADS; ++loop) + if (ipx_pendingreadpkt[loop] == pkt) { + ipx_pendingreadpkt[loop] = NULL; + break; + } + BOOL success = (bytesread >= 0) && !ipx_shutdown; + if (success) + LISTADDPTREND(&ipx_packethead,pkt); + else + FREE(pkt); + ipx_critsect.Leave(); + + if (success) + SetEvent(ipx_recvevent); + else { + _endthreadex(0); + return 0; + } + + + } + return 0; +} + +//=========================================================================== +static BOOL CALLBACK SelectGameDialogProc (HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) { + static LPBYTE background = NULL; + static LPBYTE buttontexture = NULL; + static UIPARAMSPTR uiparams = NULL; + switch (message) { + + case WM_COMMAND: + + // IF THE USER CLICKED 'JOIN GAME', TRY TO JOIN THE SELECTED GAME + if (LOWORD(wparam) == IDOK) { + LPARAM cursel = SendDlgItemMessage(window,IDC_GAMELIST,LB_GETCURSEL,0,0); + if (cursel != LB_ERR) { + char fullname[2*SNETSPI_MAXSTRINGLENGTH] = ""; + SendDlgItemMessage(window,IDC_GAMELIST,LB_GETTEXT,cursel,(LPARAM)fullname); + if (fullname[0]) { + if (strchr(fullname,'\t')) + *strchr(fullname,'\t') = 0; + if (SNetJoinGame(0, + fullname, + NULL, + uiparams->playerdata->playername, + uiparams->playerdata->playerdescription, + uiparams->playeridptr)) { + KillTimer(window,1); + SDlgEndDialog(window,1); + } + else + uiparams->interfacedata->messageboxcallback(window, + "Unable to connect.", + uiparams->programdata->programname, + 0); + } + } + } + + // IF THE USER CLICKED 'CREATE GAME', CALL THE CREATE GAME CALLBACK + else if ((LOWORD(wparam) == IDC_CREATEGAME) && + uiparams->interfacedata->createcallback) { + + // BUILD A NEW INTERFACE DATA STRUCTURE CONTAINING OUR WINDOW HANDLE + SNETUIDATA interfacedata; + CopyMemory(&interfacedata,uiparams->interfacedata,sizeof(SNETUIDATA)); + interfacedata.size = sizeof(SNETUIDATA); + interfacedata.parentwindow = window; + + // BUILD A CREATION DATA STRUCTURE + SNETCREATEDATA createdata; + ZeroMemory(&createdata,sizeof(SNETCREATEDATA)); + createdata.size = sizeof(SNETCREATEDATA); + createdata.providerid = PROVIDERID; + createdata.maxplayers = ipx_maxplayers; + createdata.createflags = 0; + + // CALL THE CREATE GAME CALLBACK + if (uiparams->interfacedata->createcallback(&createdata, + uiparams->programdata, + uiparams->playerdata, + &interfacedata, + uiparams->versiondata, + uiparams->playeridptr)) { + KillTimer(window,1); + SDlgEndDialog(window,1); + } + + } + + // IF THE USER CLICKED 'DISCONNECT', END THE DIALOG + else if (LOWORD(wparam) == IDCANCEL) { + KillTimer(window,1); + SDlgEndDialog(window,0); + } + + // IF THE USER SELECTED A NEW LIST BOX ITEM, UPDATE THE GAME + // DESCRIPTION + else if ((LOWORD(wparam) == IDC_GAMELIST) && + (HIWORD(wparam) == LBN_SELCHANGE)) + InvalidateRect(GetDlgItem(window,IDC_GAMEDESCRIPTION),NULL,1); + + // IF THE USER DOUBLE-CLICKED A LIST BOX ITEM, POST AN 'OK' COMMAND + else if ((LOWORD(wparam) == IDC_GAMELIST) && + (HIWORD(wparam) == LBN_DBLCLK)) + PostMessage(window,WM_COMMAND,MAKELONG(IDOK,BN_CLICKED),(LPARAM)GetDlgItem(window,IDOK)); + + break; + + case WM_DESTROY: + if (background) { + FREE(background); + background = NULL; + } + if (buttontexture) { + FREE(buttontexture); + buttontexture = NULL; + } + uiparams = NULL; + break; + + case WM_DRAWITEM: + if (wparam == IDC_GAMEDESCRIPTION) { + + // GET THE GAME NAME AND DESCRIPTION + char name[256] = ""; + { + LRESULT sel = SendDlgItemMessage(window,IDC_GAMELIST,LB_GETCURSEL,0,0); + if (sel != LB_ERR) + SendDlgItemMessage(window,IDC_GAMELIST,LB_GETTEXT,sel,(LPARAM)name); + } + LPSTR description = ""; + if (strchr(name,'\t')) { + description = strchr(name,'\t'); + *description++ = 0; + } + + // UPDATE THE DESCRIPTION IN THE STATIC TEXT CONTROL + { + char buffer[256] = ""; + GetDlgItemText(window,IDC_GAMEDESCRIPTION,buffer,256); + buffer[255] = 0; + if (strcmp(buffer,description)) + SetDlgItemText(window,IDC_GAMEDESCRIPTION,description); + } + + // IF THE APPLICATION HAS REGISTERED A DRAW DESCRIPTION CALLBACK, + // LET IT DRAW THE DESCRIPTION + if (uiparams->interfacedata->drawdesccallback) + return uiparams->interfacedata->drawdesccallback(PROVIDERID, + SNET_DRAWTYPE_GAME, + name, + description, + 0, + 0, + SNET_DDF_MULTILINE, + (LPDRAWITEMSTRUCT)lparam); + + // OTHERWISE, LET THE DEFAULT DIALOG BOX PROCEDURE DRAW THE + // DESCRIPTION FROM THE STATIC TEXT + else + return 0; + + } + break; + + case WM_INITDIALOG: + + // SAVE A POINTER TO THE USER INTERFACE PARAMETERS + uiparams = (UIPARAMSPTR)lparam; + + // LOAD THE ARTWORK FOR THIS DIALOG + { + SIZE size; + if (LoadArtwork(uiparams->interfacedata->artcallback, + PROVIDERID, + SNET_ART_BACKGROUND, + 1, + &background, + &size)) { + SDlgSetBitmap(window, + NULL, + "", + SDLG_STYLE_ANY, + SDLG_USAGE_BACKGROUND, + background, + NULL, + size.cx, + size.cy); + int controllist[2] = {IDC_GAMEDESCRIPTION,0}; + SDlgSetControlBitmaps(window, + &controllist[0], + NULL, + background, + &size, + SDLG_ADJUST_CONTROLPOS); + } + if (LoadArtwork(uiparams->interfacedata->artcallback, + PROVIDERID, + SNET_ART_BUTTONTEXTURE, + 0, + &buttontexture, + &size)) { + int controllist[4] = {IDC_CREATEGAME,IDOK,IDCANCEL,0}; + SDlgSetControlBitmaps(window, + &controllist[0], + NULL, + buttontexture, + &size, + SDLG_ADJUST_VERTICAL); + } + } + + // DRAW THE PROGRAM DESCRIPTION + SetDlgItemTextA(window,IDC_PROGRAMDESCRIPTION,uiparams->programdata->programdescription); + + // SET THE FIRST TAB STOP FOR THE GAME LIST TO WIDER THAN THE LIST BOX, + // TO HIDE ALL TABBED TEXT + { + RECT rect; + GetClientRect(GetDlgItem(window,IDC_GAMELIST),&rect); + SendDlgItemMessage(window,IDC_GAMELIST,LB_SETTABSTOPS,1,(LPARAM)&rect.right); + } + + PostMessage(window,WM_USER,0,0); + SetTimer(window,1,500,NULL); + return 1; + + case WM_TIMER: + case WM_USER: + SendRequest(); + TrimGameList(3000); + UpdateGameList(window,GetDlgItem(window,IDC_GAMELIST)); + break; + + } + return SDlgDefDialogProc(window,message,wparam,lparam); +} + +//=========================================================================== +static void SendAdvertisement (SOCKADDR_IPX *addr) { + ipx_critsect.Enter(); + if (ipx_advgameinfo && ipx_winsockapi && ipx_winsockapi->sendto) { + ipx_winsockapi->sendto(ipx_advsocket, + (const char *)ipx_advgameinfo, + ipx_advgameinfo->header.length, + 0, + (const sockaddr *)(addr ? addr : &ipx_broadcastaddr), + sizeof(SOCKADDR_IPX)); + PerfIncrement(PERF_PKTSENT); + PerfAdd(PERF_BYTESSENT,ipx_advgameinfo->header.length); + } + ipx_critsect.Leave(); +} + +//=========================================================================== +static void SendRequest () { + ADVHEADER request; + ZeroMemory(&request,sizeof(ADVHEADER)); + request.length = sizeof(ADVHEADER); + request.type = ADTYPE_REQUEST; + request.programid = ipx_programid; + request.versionid = ipx_versionid; + request.checksum = GenerateChecksum(&request,sizeof(ADVHEADER)); + if (ipx_winsockapi && ipx_winsockapi->sendto) + ipx_winsockapi->sendto(ipx_advsocket, + (const char *)&request, + request.length, + 0, + (const sockaddr *)&ipx_broadcastaddr, + sizeof(SOCKADDR_IPX)); + PerfIncrement(PERF_PKTSENT); + PerfAdd(PERF_BYTESSENT,request.length); +} + +//=========================================================================== +static void TrimGameList (DWORD timeout) { + ipx_critsect.Enter(); + { + DWORD currtime = GetTickCount(); + SNETSPI_GAMELISTPTR *next = &ipx_gamehead; + while (*next) + if (currtime-(*next)->ownerlasttime > timeout) { + SNETSPI_GAMELISTPTR freeptr = *next; + *next = (*next)->next; + FREEIFUSED(freeptr->clientdata); + FREE(freeptr); + } + else + next = &(*next)->next; + } + ipx_critsect.Leave(); +} + +//=========================================================================== +static void UpdateGameList (HWND dialog, HWND listbox) { + ipx_critsect.Enter(); + + // MAKE SURE ALL GAMES IN THE LINKED LIST ARE REPRESENTED IN THE LIST BOX + { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) { + if (!(curr->gamemode & SNET_GM_UNLISTEDMASK)) { + char fullstring[2*SNETSPI_MAXSTRINGLENGTH]; + sprintf(fullstring,"%s\t%s",curr->gamename,curr->gamedescription); + if (SendMessage(listbox,LB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)fullstring) == LB_ERR) { + SendMessage(listbox,LB_ADDSTRING,0,(LPARAM)fullstring); + EnableWindow(GetDlgItem(dialog,IDOK),1); + if (SendMessage(listbox,LB_GETCURSEL,0,0) == LB_ERR) { + SendMessage(listbox,LB_SETCURSEL,0,0); + SendMessage(dialog,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)listbox); + } + } + } + curr = curr->next; + } + } + + // MAKE SURE THERE ARE NO GAME IN THE LIST BOX THAT AREN'T IN THE LINKED LIST + { + char liststring[2*SNETSPI_MAXSTRINGLENGTH]; + WPARAM index = 0; + while (SendMessage(listbox,LB_GETTEXT,index,(LPARAM)liststring) != LB_ERR) { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) { + if (!(curr->gamemode & SNET_GM_UNLISTEDMASK)) { + char fullstring[2*SNETSPI_MAXSTRINGLENGTH]; + sprintf(fullstring,"%s\t%s",curr->gamename,curr->gamedescription); + if (!strcmp(fullstring,liststring)) + break; + } + curr = curr->next; + } + if (!curr) { + if (SendMessage(listbox,LB_GETCURSEL,0,0) == (LRESULT)index) { + SendMessage(listbox,LB_SETCURSEL,index-1,0); + SendMessage(dialog,WM_COMMAND,MAKELONG(IDC_GAMELIST,LBN_SELCHANGE),(LPARAM)listbox); + } + if (!SendMessage(listbox,LB_DELETESTRING,index,0)) + EnableWindow(GetDlgItem(dialog,IDOK),0); + } + else + ++index; + } + } + + ipx_critsect.Leave(); +} + +/**************************************************************************** +* +* SERVICE PROVIDER INTERFACE FUNCTIONS +* +***/ + +//=========================================================================== +BOOL CALLBACK IpxCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude) { + if (diffmagnitude) + *diffmagnitude = 0; + if (!(addr1 && addr2 && diffmagnitude)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // COMPARE THE ADDRESSES, AND RETURN: + // 2 IF THEY ARE ON DIFFERENT NETWORKS + // 1 IF THEY ARE DIFFERENT ADDRESSES ON THE SAME NETWORK + // 0 IF THEY ARE THE SAME ADDRESS + SOCKADDR_IPX *ipxaddr1 = (SOCKADDR_IPX *)addr1; + SOCKADDR_IPX *ipxaddr2 = (SOCKADDR_IPX *)addr2; + if ((*(DWORD *)&ipxaddr1->sa_netnum) != + (*(DWORD *)&ipxaddr2->sa_netnum)) + *diffmagnitude = 2; + else if (memcmp(ipxaddr1,ipxaddr2,sizeof(SOCKADDR_IPX))) + *diffmagnitude = 1; + else + *diffmagnitude = 0; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxDestroy () { + + // START THE SHUTDOWN PROCESS + ipx_shutdown = TRUE; + + // SEND DATA TO THE RECEIVE THREADS TO WAKE THEM UP + { + SOCKADDR_IPX sendaddr; + CopyMemory(&sendaddr,&ipx_broadcastaddr,sizeof(SOCKADDR_IPX)); + BYTE buffer[8] = {0x08,0xEF,0x08,0x00,0x00,0x00,0x00,0x00}; + if (ipx_winsockapi && ipx_winsockapi->htons) + sendaddr.sa_socket = ipx_winsockapi->htons(ADVPORT); + if (ipx_winsockapi && ipx_winsockapi->sendto) + ipx_winsockapi->sendto(ipx_advsocket,(const char *)&buffer[0],8,0,(const sockaddr *)&sendaddr,sizeof(SOCKADDR_IPX)); + if (ipx_winsockapi && ipx_winsockapi->htons) + sendaddr.sa_socket = ipx_winsockapi->htons(MAINPORT); + if (ipx_winsockapi && ipx_winsockapi->sendto) + for (int loop = 0; loop < RECVDATATHREADS; ++loop) + ipx_winsockapi->sendto(ipx_mainsocket,(const char *)&buffer[0],8,0,(sockaddr *)&sendaddr,sizeof(SOCKADDR_IPX)); + } + + // WAIT FOR ALL THREADS TO TERMINATE + while (ipx_threadhead) { + WaitForSingleObject(ipx_threadhead->handle,100); + CloseHandle(ipx_threadhead->handle); + LISTFREE(&ipx_threadhead,ipx_threadhead); + } + + // CLOSE THE SOCKETS + if (ipx_mainsocket) { + if (ipx_winsockapi && ipx_winsockapi->closesocket) + ipx_winsockapi->closesocket(ipx_mainsocket); + ipx_mainsocket = (SOCKET)0; + } + if (ipx_advsocket) { + if (ipx_winsockapi && ipx_winsockapi->closesocket) + ipx_winsockapi->closesocket(ipx_advsocket); + ipx_advsocket = (SOCKET)0; + } + + // TAKE CONTROL OF THE CRITICAL SECTION + ipx_critsect.Enter(); + + // FREE THE GAME INFO + IpxStopAdvertisingGame(); + { + SNETSPI_GAMELISTPTR curr; + while ((curr = ipx_gamehead) != NULL) { + FREEIFUSED(curr->clientdata); + LISTFREE(&ipx_gamehead,curr); + } + } + + // FREE ALL UNPROCESSED PACKETS + LISTCLEAR(&ipx_packethead); + for (int loop = 0; loop < RECVDATATHREADS; ++loop) + if (ipx_pendingreadpkt[loop]) + FREE(ipx_pendingreadpkt[loop]); + + // CLEAN UP WINDOWS SOCKETS + if (ipx_winsockapi && ipx_winsockapi->WSACleanup) + ipx_winsockapi->WSACleanup(); + if (ipx_winsockapi) { + FREE(ipx_winsockapi); + ipx_winsockapi = NULL; + } + if (ipx_winsocklib) { + FreeLibrary(ipx_winsocklib); + ipx_winsocklib = (HINSTANCE)0; + } + + // LEAVE THE CRITICAL SECTION + ipx_critsect.Leave(); + + // FINISH THE SHUTDOWN PROCESS + ipx_shutdown = 0; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxFree (SNETADDRPTR addr, + LPVOID data, + DWORD databytes) { + if (!(addr && data)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + FREE(addr); + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxFreeExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR mesage) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxGetGameInfo (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + SNETSPI_GAMELIST *gameinfo) { + if (gameinfo) + ZeroMemory(gameinfo,sizeof(SNETSPI_GAMELIST)); + if (!(gamename && gameinfo && (gameid || *gamename))) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // SEARCH FOR A GAME IN THE GAME LIST MATCHING THE QUERY PARAMETERS + ipx_critsect.Enter(); + { + SNETSPI_GAMELISTPTR curr = ipx_gamehead; + while (curr) + if (((!gameid) || (gameid == curr->gameid)) && + ((!*gamename) || !_stricmp(gamename,curr->gamename))) { + CopyMemory(gameinfo,curr,sizeof(SNETSPI_GAMELIST)); + break; + } + else + curr = curr->next; + } + ipx_critsect.Leave(); + + if (gameinfo->gameid) + return 1; + else { + SetLastError(SNET_ERROR_GAME_NOT_FOUND); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK IpxGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + return PerfGetPerformanceData(counterid, + countervalue, + measurementtime, + measurementfreq); +} + +//=========================================================================== +BOOL CALLBACK IpxInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE event) { + + // SAVE THE PROGRAM AND VERSION IDS AND THE RECEIVE EVENT HANDLE + ipx_programid = programdata->programid; + ipx_versionid = programdata->versionid; + ipx_maxplayers = min(programdata->maxplayers,MAXPLAYERS); + ipx_recvevent = event; + + // RESET PERFORMANCE DATA + PerfReset(); + + // BIND TO WINSOCK + if (!BindToWinsock()) + return 0; + + // INITIALIZE WINDOWS SOCKETS + { + WSADATA data; + if (ipx_winsockapi->WSAStartup(MAKEWORD(1,1),&data)) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + } + + // CREATE TWO SOCKETS: ONE FOR APPLICATION DATA AND ONE FOR ADVERTISING + ipx_advsocket = ipx_winsockapi->socket(PF_NS,SOCK_DGRAM,NSPROTO_IPX); + ipx_mainsocket = ipx_winsockapi->socket(PF_NS,SOCK_DGRAM,NSPROTO_IPX); + if (!(ipx_advsocket && ipx_mainsocket)) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + + // DETERMINE THE BROADCAST ADDRESS + { + ZeroMemory(&ipx_broadcastaddr,sizeof(SOCKADDR_IPX)); + for (int loop = 0; loop < 6; ++loop) + ipx_broadcastaddr.sa_nodenum[loop] = (BYTE)0xFF; + ipx_broadcastaddr.sa_family = AF_IPX; + ipx_broadcastaddr.sa_socket = ipx_winsockapi->htons(ADVPORT); + } + + // BIND TO THE MAIN SOCKET, DETERMINING OUR LOCAL ADDRESS + ZeroMemory(&ipx_localaddr,sizeof(SOCKADDR_IPX)); + ipx_localaddr.sa_family = AF_IPX; + ipx_localaddr.sa_socket = ipx_winsockapi->htons(MAINPORT); + if (ipx_winsockapi->bind(ipx_mainsocket, + (const struct sockaddr *)&ipx_localaddr, + sizeof(SOCKADDR_IPX))) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + + // BIND TO THE ADVERTISING SOCKET + { + SOCKADDR_IPX advaddr; + CopyMemory(&advaddr,&ipx_localaddr,sizeof(SOCKADDR_IPX)); + advaddr.sa_socket = ipx_winsockapi->htons(ADVPORT); + if (ipx_winsockapi->bind(ipx_advsocket, + (const struct sockaddr *)&advaddr, + sizeof(SOCKADDR_IPX))) { + IpxDestroy(); + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + } + + // ALLOW BROADCASTS TO BE SENT ON THE SOCKETS (DUE TO A BUG IN WINDOWS 95, + // THIS OPTION IS ALSO REQUIRED FOR RECEIVING BROADCASTS) + { + BOOL value = 1; + ipx_winsockapi->setsockopt(ipx_advsocket, + SOL_SOCKET, + SO_BROADCAST, + (const char *)&value, + sizeof(BOOL)); + ipx_winsockapi->setsockopt(ipx_mainsocket, + SOL_SOCKET, + SO_BROADCAST, + (const char *)&value, + sizeof(BOOL)); + } + + // CREATE A THREAD TO RECEIVE PACKETS ON THE ADVERTISING SOCKET + { + THREAD thread; + thread.handle = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + RecvAdThreadProc, + NULL, + 0, + &thread.id); + if (thread.handle) { + SetThreadPriority(thread.handle,THREAD_PRIORITY_ABOVE_NORMAL); + LISTADD(&ipx_threadhead,&thread); + } + } + + // CREATE THREADS TO READ PACKETS FROM THE MAIN SOCKET + { + BOOL win95 = GetVersion() & 0x80000000; + int threads = win95 ? 1 : RECVDATATHREADS; + for (int loop = 0; loop < threads; ++loop) { + THREAD thread; + thread.handle = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES)NULL, + 0, + RecvDataThreadProc, + NULL, + 0, + &thread.id); + if (thread.handle) { + SetThreadPriority(thread.handle,THREAD_PRIORITY_HIGHEST); + LISTADD(&ipx_threadhead,&thread); + } + } + } + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + + // WE NEVER RETURN ANY DEVICES, SO THIS FUNCTION SHOULD NEVER BE CALLED + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxLockDeviceList (SNETSPI_DEVICELISTPTR *devicelist) { + *devicelist = NULL; + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxLockGameList (DWORD categorybits, + DWORD categorymask, + SNETSPI_GAMELISTPTR *gamelist) { + if (!gamelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // TRIM ANY GAMES THAT WE HAVEN'T HEARD FROM IN A WHILE + { + static DWORD lasttime = GetTickCount(); + DWORD currtime = GetTickCount(); + TrimGameList(max(3000,2*(currtime-lasttime))); + } + + // LOCK THE GAME LIST + ipx_critsect.Enter(); + *gamelist = ipx_gamehead; + + return 1; +} + +//=========================================================================== +/* +BOOL CALLBACK IpxReceive (SNETADDRPTR *addr, + LPVOID *data, + DWORD *databytes) { +*/ +BOOL CALLBACK IpxReceive (LPVOID *data, + DWORD *databytes, + SNETADDRPTR *addr) { + if (addr) + *addr = NULL; + if (data) + *data = NULL; + if (databytes) + *databytes = NULL; + if (!(addr && data && databytes && ipx_mainsocket)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // IF THERE IS A PACKET QUEUED, REMOVE IT FROM THE QUEUE AND RETURN + // POINTERS TO THE CALLER. NOTE THAT WE UNLINK THE PACKET BUT DON'T + // FREE IT FROM MEMORY; IT IS THE CALLER'S RESPONSIBILITY TO CALL + // OUR FREE FUNCTION WHEN IT IS DONE WITH THE PACKET. + if (ipx_packethead) { + ipx_critsect.Enter(); + *addr = &ipx_packethead->addr; + *data = ipx_packethead->data; + *databytes = ipx_packethead->databytes; + ipx_packethead = ipx_packethead->next; + ipx_critsect.Leave(); + return 1; + } + else { + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK IpxReceiveExternalMessage (LPCSTR *senderpath, + LPCSTR *sendername, + LPCSTR *message) { + if (senderpath) + *senderpath = NULL; + if (sendername) + *sendername = NULL; + if (message) + *message = NULL; + + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + + // BUILD A USER INTERFACE DATA BLOCK + UIPARAMS uiparams; + ZeroMemory(&uiparams,sizeof(UIPARAMS)); + uiparams.flags = flags; + uiparams.programdata = programdata; + uiparams.playerdata = playerdata; + uiparams.interfacedata = interfacedata; + uiparams.versiondata = versiondata; + uiparams.playeridptr = playerid; + + // DISPLAY THE DIALOG BOX + DWORD result = (DWORD)SDlgDialogBoxParam(global_instance, + "IPXSELECTGAME_DIALOG", + interfacedata ? interfacedata->parentwindow + : SDrawGetFrameWindow(), + SelectGameDialogProc, + (LPARAM)&uiparams); + + return (result && (result != 0xFFFFFFFF)); +} + +//=========================================================================== +BOOL CALLBACK IpxSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes) { + if (!(addresses && addrlist && data && databytes && ipx_mainsocket)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // SEND THE PACKET + if (ipx_winsockapi && ipx_winsockapi->sendto) + while (addresses--) { + ipx_winsockapi->sendto(ipx_mainsocket, + (const char *)data, + databytes, + 0, + (const sockaddr *)*(addrlist+addresses), + sizeof(SOCKADDR_IPX)); + PerfIncrement(PERF_PKTSENT); + PerfAdd(PERF_BYTESSENT,databytes); + } + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxSendExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR targetpath, + LPCSTR targetname, + LPCSTR message) { + return 0; +} + +//=========================================================================== +BOOL CALLBACK IpxStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD gameage, + DWORD gamecategorybits, + DWORD optcategorybits, + LPCVOID clientdata, + DWORD clientdatabytes) { + if (!(gamename && gamedescription)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // CREATE A STRUCTURE TO CONTAIN THE DATA WE NEED TO ADVERTISE + ipx_critsect.Enter(); + if (!ipx_advgameinfo) { + ipx_advgameinfo = NEW(ADVPACKET); + if (!ipx_advgameinfo) { + ipx_critsect.Leave(); + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + ZeroMemory(ipx_advgameinfo,sizeof(ADVPACKET)); + ipx_advgameinfo->header.checksum = 0; + ipx_advgameinfo->header.length = sizeof(ADVHEADER) + +strlen(gamename) + +strlen(gamedescription) + +2 + +clientdatabytes; + ipx_advgameinfo->header.type = ADTYPE_GAMEINFO; + ipx_advgameinfo->header.reserved = 0; + ipx_advgameinfo->header.programid = ipx_programid; + ipx_advgameinfo->header.versionid = ipx_versionid; + ipx_advgameinfo->header.gamemode = gamemode; + LPSTR currptr = ipx_advgameinfo->strings; + SStrCopy(currptr, + gamename, + SNETSPI_MAXSTRINGLENGTH); + currptr += strlen(currptr)+1; + SStrCopy(currptr, + gamedescription, + SNETSPI_MAXSTRINGLENGTH); + currptr += strlen(currptr)+1; + CopyMemory(currptr, + clientdata, + clientdatabytes); + ipx_advgameinfo->header.checksum = GenerateChecksum(ipx_advgameinfo, + ipx_advgameinfo->header.length); + ipx_critsect.Leave(); + + // SEND THE FIRST ADVERTISEMENT + SendAdvertisement(NULL); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxStopAdvertisingGame () { + + // DELETE THE ADVERTISEMENT DATA AND SEND OUT A REMOVE GAME MESSAGE + ipx_critsect.Enter(); + if (ipx_advgameinfo) { + ipx_advgameinfo->header.checksum = 0; + ipx_advgameinfo->header.type = ADTYPE_REMOVE; + ipx_advgameinfo->header.checksum = GenerateChecksum(ipx_advgameinfo, + ipx_advgameinfo->header.length); + if (ipx_winsockapi && ipx_winsockapi->sendto) + ipx_winsockapi->sendto(ipx_advsocket, + (const char *)ipx_advgameinfo, + ipx_advgameinfo->header.length, + 0, + (const sockaddr *)&ipx_broadcastaddr, + sizeof(SOCKADDR_IPX)); + PerfIncrement(PERF_PKTSENT); + PerfAdd(PERF_BYTESSENT,ipx_advgameinfo->header.length); + FREE(ipx_advgameinfo); + ipx_advgameinfo = NULL; + } + ipx_critsect.Leave(); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxUnlockDeviceList (SNETSPI_DEVICELISTPTR devicelist) { + return 1; +} + +//=========================================================================== +BOOL CALLBACK IpxUnlockGameList (SNETSPI_GAMELISTPTR gamelist, + DWORD *hintnextcall) { + if (gamelist != ipx_gamehead) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // UNLOCK THE GAME LIST + ipx_critsect.Leave(); + if (hintnextcall) + *hintnextcall = 500; + + // SEND OUT A REQUEST FOR ADVERTISEMENTS, SO WE WILL HAVE UPDATED DATA + // THE NEXT TIME IT IS REQUESTED + { + static DWORD lasttime = 0; + DWORD currtime = GetTickCount(); + if (currtime-lasttime > 400) { + lasttime = currtime; + SendRequest(); + } + } + + return 1; +} + +/**************************************************************************** +* +* EXPORTED STRUCTURES +* +***/ + +DWORD ipx_id = PROVIDERID; +LPCSTR ipx_desc = "Local Area Network (IPX)"; +LPCSTR ipx_req = "All computers must be connected to an IPX-compatible network."; +SNETCAPS ipx_caps = {sizeof(SNETCAPS), // size + SNET_CAPS_PAGELOCKEDBUFFERS // flags + | SNET_CAPS_BASICINTERFACE +#ifdef _DEBUG + | SNET_CAPS_DEBUGONLY, +#else + | SNET_CAPS_RETAILONLY, +#endif + MAXMESSAGESIZE, // max message size + 16, // max queue size, + MAXPLAYERS, // max players, + 100000, // bytes per second + 50, // latency (ms) + 8, // default turns per second + 2}; // default turns in transit +SNETSPI ipx_spi = {sizeof(SNETSPI), + IpxCompareNetAddresses, + IpxDestroy, + IpxFree, + IpxFreeExternalMessage, + IpxGetGameInfo, + IpxGetPerformanceData, + IpxInitialize, + IpxInitializeDevice, + IpxLockDeviceList, + IpxLockGameList, + IpxReceive, + IpxReceiveExternalMessage, + IpxSelectGame, + IpxSend, + IpxSendExternalMessage, + IpxStartAdvertisingGame, + IpxStopAdvertisingGame, + IpxUnlockDeviceList, + IpxUnlockGameList}; diff --git a/Storm/SOURCE/STANDARD/MODEM.CPP b/Storm/SOURCE/STANDARD/MODEM.CPP new file mode 100644 index 0000000..ac56347 --- /dev/null +++ b/Storm/SOURCE/STANDARD/MODEM.CPP @@ -0,0 +1,2218 @@ +/**************************************************************************** +* +* MODEM.CPP +* Modem provider +* +* By Jeff Strain (11/21/96) +* +* File History: +* 11/28/96 1.00 (js) Initial version +* 02/03/97 1.10 (js) Fixes for shitty non-error correcting modems +* and noisy lines +* (js) Now returning unique busy status +* (js) Full packet signatures +* (js) Pulse dialing +* +***/ + +#include "pch.h" + +#pragma comment(lib, "tapi32.lib") + +// This is just so that functions will show up in the globals list in +// MSDEV Studio. +#define STATIC static + +// Prevents compilation of internal UI code +#define PROVIDERUI + +// CATCHES INTERNAL TEST VERSIONS +// EXPIRES MARCH 01, 1997 +// #define EXPIRATION {1997, 3, 0, 1} // YEAR, MONTH, NULL, DAY + +// Need this when compiling under NT4 - otherwise does not generate +// a Win95 compatible TAPI version, This *must* be included before +// tapi.h! +#define TAPI_CURRENT_VERSION 0x00010004 +#include + +#include + +// MAX TIME (MS) BETWEEN CLIENT AND HOST CONNECTION NOTIFICATIONS +#define MAX_CONNECT_DIFFERENTIAL 10000 + +#define HANDSHAKE_TIMEOUT 5000 +#define ANSWERTIMEOUT INFINITE + +// Time in ms to wait for game info after connection +#define FINDGAMETIMEOUT MAX_CONNECT_DIFFERENTIAL + HANDSHAKE_TIMEOUT + +#define READTIMEOUT 25 // in ms + +#define MAXMESSAGESIZE 180 // BE CAREFUL NOT TO FALL BELOW THE APP MIN +#define MAXPLAYERS 2 +#define PORTS 1 +#define PROVIDERID 'MODM' +#define READBUFFERSIZE 64 +#define HEADER_KEY_SEQ {'N','R','M','L'} +#define HEADER_KEYS 4 + +#define STATE_NOGAME 0 +#define STATE_SHUTDOWN 1 + +#define TAPISTATE_SHUTDOWN 0 +#define TAPISTATE_ACTIVE 1 + +#define TYPE_USERDATA 0 +#define TYPE_SYSTEMDATA 1 +#define TYPE_LASTDATA 1 + +#define SYS_UNUSED 0 +#define SYS_QUERYID 1 +#define SYS_ASSERTID 2 +#define SYS_QUERYGAME 9 +#define SYS_GAMEINFO 10 +#define SYS_REMOVE 11 + +// SYSTEM MESSAGE SYMBOLS FOR 2-WAY HANDSHAKE. THIS IS NECCESSARY +// SINCE THERE CAN BE A DIFFERENTIAL IN CONNECTION NOTIFICATION +// BETWEEN CALLER AND HOST OF UP TO 5 SECONDS AND THE QUERY +// GAME CAN BE LOST. NOTE THAT A 3-WAY HANDSHAKE IS NOT NECCESSARY +// SINCE WE DO NOT NEED TO TEST THE LINE, JUST THE STARTUP OF THE +// REMOTE SYSEM. +#define SYS_QUERYLINE 3 +#define SYS_ASSERTLINE 4 + +// Possible return error for resynchronization functions. +#define WAITERR_WAITABORTED 1 +#define WAITERR_WAITTIMEDOUT 2 + +// LOCAL DATA TYPES + +typedef struct _UIPARAMS { + DWORD flags; + SNETPROGRAMDATAPTR programdata; + SNETPLAYERDATAPTR playerdata; + SNETUIDATAPTR interfacedata; + SNETVERSIONDATAPTR versiondata; + LPDWORD playeridptr; +} UIPARAMS, *UIPARAMSPTR; + +typedef struct _ADVREC { + DWORD networkid; + DWORD programid; + DWORD versionid; + char strings[SNETSPI_MAXSTRINGLENGTH*2]; + DWORD bytes; +} ADVREC, *ADVPTR; + +typedef struct _PACKETHEADER { + BYTE key_sequence[HEADER_KEYS]; // must be first field + BYTE sizedwords; // must be second field + BYTE startbyte_type; + BYTE targetmask; + union { + struct { + BYTE fromid:4; + BYTE timetolive:4; + }; + struct { + BYTE sysmsgtype:4; + BYTE timetolive:4; + }; + }; +} PACKETHEADER, *PACKETHEADERPTR; + +typedef struct _MESSAGEREC { + SNETADDR addr; // must be first field + PACKETHEADER header; // must immediately precede data + BYTE data[MAXMESSAGESIZE]; + DWORD bytesneeded; + DWORD bytesread; + DWORD inport; + _MESSAGEREC *next; +} MESSAGEREC, *MESSAGEPTR; + +typedef struct _MESSAGEDATAREC { + PACKETHEADER header; // must immediately precede data + BYTE data[MAXMESSAGESIZE]; +} MESSAGEDATAREC, *MESSAGEDATAPTR; + +typedef struct _PORTREC { + HANDLE handle; + OVERLAPPED overlapped; + BYTE readbuffer[READBUFFERSIZE]; + DWORD bytesread; + MESSAGEPTR partialmessage; + BYTE networkids; +} PORTREC, *PORTPTR; + +typedef BOOL (CALLBACK *DEVENUMPROC)(LPLINEDEVCAPS, DWORD, LPARAM); +typedef BOOL (CALLBACK *LOCENUMPROC)(LPLINETRANSLATECAPS, + LPLINELOCATIONENTRY, LPARAM); +typedef BOOL (CALLBACK *COUNTRYENUMPROC)(LPLINECOUNTRYLIST, + LPLINECOUNTRYENTRY, LPARAM); + +// GLOBAL STATIC VARIABLES + +static BYTE gs_arrHeaderKeys[HEADER_KEYS] = HEADER_KEY_SEQ; +#ifdef EXPIRATION +static SYSTEMTIME sg_expDate = EXPIRATION; +#endif +static CCritSect modem_critsect; +static HANDLE modem_event[PORTS] = {0}; +static ADVPTR modem_gameadvinfo = NULL; +static SNETSPI_GAMELISTPTR modem_gamelist = NULL; +static DWORD modem_maxplayers = MAXPLAYERS; +static MESSAGEPTR modem_messagehead = NULL; +static BOOL modem_lineconfirmed = 0; +static BOOL modem_lineestablished = 0; +static BYTE modem_networkid = 0; +static BOOL modem_networkidlocked = 0; +static PORTPTR modem_port[PORTS] = {0}; +static DWORD modem_programid = 0; +static HANDLE modem_recvevent = NULL; +static HANDLE modem_TAPIHangupEvent = NULL; +static HANDLE modem_TAPIHangupNotify = NULL; +static HANDLE modem_TAPIAnswerEvent = NULL; +static HANDLE modem_TAPIEvent = NULL; +static HANDLE modem_TAPINotifyEvent = NULL; +static HANDLE modem_TAPICallStateEvent = NULL; +static HANDLE modem_TAPITerminateEvent = NULL; +static HANDLE modem_TAPILineReplyEvent = NULL; +static DWORD modem_routeloopcheck = 0; +static DWORD modem_state = STATE_NOGAME; +static DWORD modem_tapistate = TAPISTATE_SHUTDOWN; +static HANDLE modem_readthread = NULL; +static HANDLE modem_tapithread = NULL; +static HANDLE modem_tapianswerthread = NULL; +static HANDLE modem_tapihangupthread = NULL; +static DWORD modem_versionid = 0; +static BOOL modem_versionmismatch = 0; +static DWORD modem_callstatus = NO_ERROR; +static SNETSTATUSPROC modem_status = NULL; + +// TAPI GLOBALS + +static HLINEAPP g_hLineApp = NULL; +static HCALL g_hCall = NULL; +static HLINE g_hLine = NULL; +static DWORD g_dwNumDevices = 0; +static DWORD g_dwDeviceID = 0; + +static LONG g_lRequestedID; +static LONG g_lAsyncReply; +static DWORD g_dwCallState; +static DWORD g_dwDesiredCallState; + +// FORWARD DECLARATIONS + +static BOOL StartCom(); +static void StopCom(); +static BOOL HangupCall(); +static BOOL SendDataMessage (BYTE sysmsgtype, + BYTE targetmask, + LPVOID data, + DWORD databytes); +BOOL CALLBACK ModemDestroy(); +BOOL CALLBACK ModemStopAdvertisingGame(); +static LONG WaitForReply(LONG lRequestedID); +static LONG WaitForCallState(DWORD dwDesiredCallState, DWORD dwWaitTime); +static BOOL TakeCall(); +static void InsertHeaderKey(PACKETHEADERPTR header); + +//=========================================================================== +static DWORD PickRandomNumber () { + // RETURN A DWORD-SIZED RANDOM NUMBER. IT IS IMPORTANT THAT WE DON'T + // USE THE RUNTIME LIBRARY RANDOM GENERATOR, BECAUSE WE DON'T WANT TO + // INTERFERE WITH THE APPLICATION'S RANDOM SEQUENCE. + LARGE_INTEGER perfcount; + POINT pos; + QueryPerformanceCounter(&perfcount); + GetCursorPos(&pos); + + static DWORD seed = 0x100001; + seed ^= perfcount.LowPart ^ GetTickCount() ^ pos.x ^ pos.y; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand1 = seed & 0xFFFF; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand2 = seed & 0xFFFF; + return (rand1 << 16) | rand2; +} + +//=========================================================================== +static BOOL FindNetworkId () { + DWORD timeout = 16; + while (timeout--) { + + // PICK A RANDOM NUMBER WHICH WE CAN USE TO RECOGNIZE AND DISCARD OUR + // OWN PACKETS IN THE CASE OF A ROUTING LOOP. MAKE SURE THE NUMBER IS + // NOT ZERO, BECAUSE COMPUTERS WITH ESTABLISHED NETWORK IDS WILL USE ZERO. + modem_routeloopcheck = 0; + while (!modem_routeloopcheck) + modem_routeloopcheck = PickRandomNumber(); + + // PICK A NETWORK ID AT RANDOM, AND SEND OUT A QUERY TO SEE IF ANYONE + // ELSE IS USING IT. IF WE ARE THE GAME OWNER WE CANNOT QUERY SINCE WE + // HAVE ALREADY RETURNED A NETWORK ID IN ModemStartAdvertisingGame(). + if (!modem_networkidlocked) { + modem_critsect.Enter(); + modem_networkid = 0; + while (!modem_networkid) + modem_networkid = (BYTE)((PickRandomNumber() % MAXPLAYERS) + 1); + modem_critsect.Leave(); + DWORD messagedata[2] = {modem_networkid,modem_routeloopcheck}; + TraceOut("Snd: SYS_QUERYID"); + SendDataMessage(SYS_QUERYID,0xFF,&messagedata[0],2*sizeof(DWORD)); + + // WAIT 1000 MILLISECONDS FOR A RESPONSE. IF ANY OTHER COMPUTER ASSERTS + // THAT IT IS USING THE ID WE PICKED, OR IF ANY OTHER COMPUTER QUERIES + // FOR THE SAME ID, THEN GIVE UP THAT ID AND PICK A NEW ONE. + DWORD starttime = GetTickCount(); + while (modem_networkid && (GetTickCount()-starttime < 1000)) + Sleep(10); + + // IF SOMEONE CONTESTED OUR ID, DUMP IT AND TRY AGAIN. + if (!modem_networkid) + continue; + } + + // NO OTHER COMPUTER CONTESTED OUR NETWORK ID. LOCK IT DOWN, ASSERT IT + // ON THE NETWORK, AND RETURN SUCCESS. + modem_critsect.Enter(); + modem_networkidlocked = 1; + modem_routeloopcheck = 0; + modem_critsect.Leave(); + TraceOut("Snd: SYS_ASSERTID %d", modem_networkid); + SendDataMessage(SYS_ASSERTID,0xFF,&modem_networkid,sizeof(DWORD)); + return 1; + } // while (timeout--) + return 0; +} + +//=========================================================================== +static void SendFormedMessage (MESSAGEDATAPTR messageptr, + DWORD exceptport, + BOOL wait) { + BOOL systemmessage = (messageptr->header.startbyte_type == TYPE_SYSTEMDATA); + + // IF THIS IS A SYSTEM MESSAGE, WRITE IT OUT ON ALL ACTIVE PORTS. + // OTHERWISE, WRITE IT OUT ON ALL PORTS WHICH LEAD TO ANY OF THE + // DESIRED NETWORK IDS. + HANDLE event[PORTS]; + OVERLAPPED overlapped[PORTS]; + DWORD byteswritten[PORTS]; + DWORD numsends = 0; + BOOL bIOResult; + ZeroMemory(&event[0],PORTS*sizeof(HANDLE)); + + for (DWORD port = 0; port < PORTS; ++port) { + if ((port != exceptport) && modem_port[port] && + (modem_port[port]->handle != INVALID_HANDLE_VALUE) && + (systemmessage || + (modem_port[port]->networkids & messageptr->header.targetmask))) { + ZeroMemory(&overlapped[numsends],sizeof(OVERLAPPED)); + + if (wait) + event[numsends] = CreateEvent(NULL,0,0,NULL); + ASSERT(event[numsends]); + if (!event[numsends]) + return; + + overlapped[numsends].hEvent = event[numsends]; + bIOResult = WriteFile(modem_port[port]->handle, + messageptr, + messageptr->header.sizedwords*sizeof(DWORD), + &byteswritten[numsends], + &overlapped[numsends]); + + TraceDumpAddr("write data", messageptr, messageptr->header.sizedwords*sizeof(DWORD)); + // If WriteFile() sets the last error to something other than + // ERROR_IO_PENDING we probably have a bad file handle, which + // means that the remote party dropped the line. In this case + // we do not want to wait on the event, so don't increment numsends + if (bIOResult || GetLastError() == ERROR_IO_PENDING) { + PerfIncrement(PERF_PKTSENT); + PerfAdd(PERF_BYTESSENT,messageptr->header.sizedwords*sizeof(DWORD)); + ++numsends; + } + else if (wait && event[numsends]) + CloseHandle(event[numsends]); + } // if ((port != exceptport) && modem_port[port] && ... + } // for (DWORD port = 0; port < PORTS; ++port) + if (numsends && wait) { + // WAIT FOR ALL WRITES TO COMPLETE + WaitForMultipleObjects(numsends,&event[0],1,INFINITE); + } + while (numsends--) + CloseHandle(event[numsends]); +} + +//=========================================================================== +static BOOL SendDataMessage (BYTE sysmsgtype, + BYTE targetmask, + LPVOID data, + DWORD databytes) { + BOOL systemmessage = (sysmsgtype != SYS_UNUSED); + if (systemmessage) + targetmask = 0xFF; + + // DON'T SEND DATA WITHOUT A VALID CONNECTION + if (!modem_lineestablished) + return 0; + + // REFUSE TO SEND A NON-SYSTEM MESSAGE IF WE DON'T HAVE A VALID NETWORK ID + if ((sysmsgtype == SYS_UNUSED) && (!(modem_networkid && modem_networkidlocked))) + return 0; + + // CREATE A FULLY-FORMED MESSAGE + MESSAGEDATAREC messagedata; + ZeroMemory(&messagedata,sizeof(MESSAGEDATAREC)); + InsertHeaderKey(&messagedata.header); + messagedata.header.startbyte_type = (sysmsgtype == SYS_UNUSED) ? TYPE_USERDATA : TYPE_SYSTEMDATA; + messagedata.header.sizedwords = (sizeof(PACKETHEADER)+databytes+sizeof(DWORD)-1)/sizeof(DWORD); + messagedata.header.timetolive = MAXPLAYERS; + messagedata.header.targetmask = targetmask; + if (systemmessage) + messagedata.header.sysmsgtype = sysmsgtype; + else + messagedata.header.fromid = modem_networkid; + if (data && databytes) + CopyMemory(&messagedata.data[0],data,databytes); + + // SEND IT + SendFormedMessage(&messagedata,0xFFFFFFFF,1); + + return 1; +} + +//=========================================================================== +static void ProcessIncomingMessage (DWORD port, MESSAGEPTR messageptr) { + BOOL systemmessage = (messageptr->header.startbyte_type == TYPE_SYSTEMDATA); + BYTE origtargetmask = messageptr->header.targetmask; + + TraceOut("ProcessIncomingMessage()"); + PerfIncrement(PERF_PKTRECV); + PerfAdd(PERF_BYTESRECV,messageptr->bytesread); + + // VALIDATE THE PORT NUMBER + if (port >= PORTS) { + FREE(messageptr); + return; + } + + // VERIFY THAT WE ARE A RECIPIENT OF THIS MESSAGE, AND NOT THE SENDER + if (modem_networkid && modem_networkidlocked && + ((!(origtargetmask & (1 << modem_networkid))) || + ((!systemmessage) && + (messageptr->header.fromid == modem_networkid)))) { + FREE(messageptr); + return; + } + + // PROCESS USER MESSAGES + if (!systemmessage) { + TraceOut("USER MESSAGE"); + if (modem_networkid && modem_networkidlocked) { + *(LPBYTE)&messageptr->addr = messageptr->header.fromid; + LISTADDPTREND(&modem_messagehead,messageptr); + if (modem_recvevent) + SetEvent(modem_recvevent); + } + else + FREE(messageptr); + } + + // PROCESS SYSTEM MESSAGES + else { + TraceOut("SYSTEM MESSAGE"); + switch (messageptr->header.sysmsgtype) { + + case SYS_QUERYLINE: + TraceOut("Rcv: SYS_QUERYLINE"); + TraceOut("Snd: SYS_ASSERTLINE"); + SendDataMessage(SYS_ASSERTLINE,0xFF,NULL,0); + modem_critsect.Enter(); + modem_lineconfirmed = 1; + modem_critsect.Leave(); + break; + + case SYS_ASSERTLINE: + TraceOut("Rcv: SYS_ASSERTLINE"); + modem_critsect.Enter(); + modem_lineconfirmed = 1; + modem_critsect.Leave(); + break; + + case SYS_QUERYID: + TraceOut("Rcv: SYS_QUERYID"); + if (messageptr->bytesread >= sizeof(PACKETHEADER)+2*sizeof(DWORD)) { + DWORD networkid = *(LPDWORD)&messageptr->data[0]; + DWORD routeloopcheck = *(LPDWORD)&messageptr->data[sizeof(DWORD)]; + if (routeloopcheck != modem_routeloopcheck) { + if (modem_networkidlocked) { + TraceOut("Snd: SYS_ASSERTID"); + SendDataMessage(SYS_ASSERTID,0xFF,&modem_networkid,sizeof(DWORD)); + } + else if (networkid == modem_networkid) + modem_networkid = 0; + } + } + break; + + case SYS_ASSERTID: + TraceOut("Rcv: SYS_ASSERTID"); + if (messageptr->bytesread >= sizeof(PACKETHEADER)+sizeof(DWORD)) { + DWORD networkid = *(LPDWORD)&messageptr->data[0]; + modem_port[port]->networkids |= (1 << networkid); + if ((!modem_networkidlocked) && (networkid == modem_networkid)) + modem_networkid = 0; + } + break; + + case SYS_QUERYGAME: + TraceOut("Rcv: SYS_QUERYGAME"); + if (modem_gameadvinfo) { + TraceOut("Snd: SYS_GAMEINFO"); + SendDataMessage(SYS_GAMEINFO,0xFF,modem_gameadvinfo,modem_gameadvinfo->bytes); + } + break; + + case SYS_GAMEINFO: + TraceOut("Rcv: SYS_GAMEINFO"); + { + modem_critsect.Enter(); + ADVPTR advinfo = (ADVPTR)&messageptr->data[0]; + if ((advinfo->programid == modem_programid) && + (advinfo->versionid == modem_versionid)) { + if (!modem_gamelist) { + modem_gamelist = NEW(SNETSPI_GAMELIST); + ASSERT(modem_gamelist); + if (!modem_gamelist) + break; + ZeroMemory(modem_gamelist,sizeof(SNETSPI_GAMELIST)); + } + *(LPBYTE)&modem_gamelist->owner = (BYTE)advinfo->networkid; + modem_gamelist->gameid = 1; + strcpy(modem_gamelist->gamename,advinfo->strings); + strcpy(modem_gamelist->gamedescription,advinfo->strings+strlen(advinfo->strings)+1); + } + else + modem_versionmismatch = 1; + modem_critsect.Leave(); + } + break; + + case SYS_REMOVE: + TraceOut("Rcv: SYS_REMOVE"); + modem_critsect.Enter(); + ADVPTR advinfo = (ADVPTR)&messageptr->data[0]; + if (modem_networkid != advinfo->networkid && modem_gamelist) { + FREE(modem_gamelist); + modem_gamelist = NULL; + } + modem_critsect.Leave(); + break; + } + FREE(messageptr); + } +} + +//=========================================================================== +BOOL CALLBACK CancelCall() +{ + modem_critsect.Enter(); + modem_callstatus = SNET_ERROR_CANCELLED; + modem_critsect.Leave(); + TraceOut("CancelCall()"); + SetEvent(modem_TAPIHangupEvent); + return 1; +} + +//=========================================================================== +static void UpdateCallStatus(DWORD dwStringResource) +{ + char buf[SNETSPI_MAXSTRINGLENGTH]; + if (!modem_status) + return; + int ret = LoadString(global_instance, dwStringResource, buf, + SNETSPI_MAXSTRINGLENGTH); + ASSERT(ret); + if (!ret) + return; + modem_status(buf, 0, 0, 0, CancelCall); +} + +//=========================================================================== +static void HandleLineCallState( + DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance, + DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) +{ + // dwParam1 is the specific CALLSTATE change that is occurring. + g_dwCallState = dwParam1; + if (g_dwCallState == g_dwDesiredCallState) + SetEvent(modem_TAPICallStateEvent); + TraceOut("LINE_CALLSTATE: %d", g_dwCallState); + switch (dwParam1) + { + // ANSWER NEW CALL + case LINECALLSTATE_OFFERING: + modem_critsect.Enter(); + g_hCall = (HCALL)dwDevice; + modem_critsect.Leave(); + SetEvent(modem_TAPIAnswerEvent); + break; + + case LINECALLSTATE_IDLE: + TraceOut("LINECALLSTATE_IDLE"); + break; + + case LINECALLSTATE_BUSY: + TraceOut("LINECALLSTATE_BUSY"); + break; + + case LINECALLSTATE_DISCONNECTED: + switch (dwParam2) + { + case LINEDISCONNECTMODE_NORMAL: + TraceOut("LINEDISCONNECTMODE_NORMAL"); + break; + + case LINEDISCONNECTMODE_BUSY: + modem_critsect.Enter(); + modem_callstatus = SNET_ERROR_NETWORK_BUSY; + modem_critsect.Leave(); + break; + + case LINEDISCONNECTMODE_NOANSWER: + modem_critsect.Enter(); + modem_callstatus = SNET_ERROR_NOT_CONNECTED; + modem_critsect.Leave(); + break; + + case LINEDISCONNECTMODE_NODIALTONE: + modem_critsect.Enter(); + modem_callstatus = SNET_ERROR_NO_NETWORK; + modem_critsect.Leave(); + break; + + case LINEDISCONNECTMODE_BADADDRESS: + case LINEDISCONNECTMODE_UNREACHABLE: + case LINEDISCONNECTMODE_CONGESTION: + case LINEDISCONNECTMODE_INCOMPATIBLE: + case LINEDISCONNECTMODE_UNAVAIL: + case LINEDISCONNECTMODE_UNKNOWN: + case LINEDISCONNECTMODE_REJECT: + case LINEDISCONNECTMODE_PICKUP: + case LINEDISCONNECTMODE_FORWARDED: + default: + break; + } + // THERE ARE 3 CASES HERE: + // 1) WE WERE THE ORIGINAL GAME OWNER, AND THE CALLER DROPPED + // THE LINE. IN THIS CASE WE WILL RECONFIGURE THE LINE TO + // ACCEPT CALLS + // 2) WE ARE THE CALLER, AND THE SERVER DROPPED. WE HAVE + // RECEIVED THIS ASYNC MESSAGE BEFORE SPISTARTADVERTISE. + // IN THIS CASE WE DO NOT CONFIGURE FOR CALL RECEIPT SINCE + // WE DO NOT TECHNICALLY KNOW WE ARE NOW THE GAME OWNER, I.E. + // THERE IS NO VALID ADVINFO RECORD. SPISTARTADVERTISE WILL + // DO THIS ON FINDING TAPI SHUTDOWN AFTER OUR HANGUP CALL. + // 3) AS ABOVE, BUT WE ARE HERE AFTER THE SPISTARTADVERTISE. + // THE MODEM WAS NOT CONFIGURED THERE SINCE TAPI WAS STILL + // RUNNING, SO WE NEED TO START IT UP! + + SetEvent(modem_TAPIHangupEvent); + break; + + case LINECALLSTATE_CONNECTED: + TraceOut("LINECALLSTATE_CONNECTED"); + StartCom(); + UpdateCallStatus(IDS_CONNECTING); + break; + + case LINECALLSTATE_DIALING: + UpdateCallStatus(IDS_DIALING); + break; + + case LINECALLSTATE_RINGBACK: + UpdateCallStatus(IDS_RINGING); + break; + + case LINECALLSTATE_PROCEEDING: + UpdateCallStatus(IDS_PROCEEDING); + break; + + case LINECALLSTATE_DIALTONE: + UpdateCallStatus(IDS_DIALTONE); + break; + + case LINECALLSTATE_SPECIALINFO: + default: + break; + } +} + +//=========================================================================== +static void CALLBACK TAPIEventCallback ( + DWORD hDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3 + ) +{ + + // Handle the line messages. + switch(dwMsg) + { + case LINE_CALLSTATE: + HandleLineCallState(hDevice, dwMsg, dwCallbackInstance, + dwParam1, dwParam2, dwParam3); + break; + + case LINE_CLOSE: + TraceOut("LINE_CLOSE"); + // Line has been shut down. + break; + + case LINE_REPLY: + TraceOut("LINE_REPLY"); + modem_critsect.Enter(); + if (g_lRequestedID == (LONG)dwParam1) { + g_lAsyncReply = (LONG)dwParam2; + SetEvent(modem_TAPILineReplyEvent); + } + modem_critsect.Leave(); + break; + + case LINE_CREATE: + default: + break; + } + return; +} + +//=========================================================================== +static DWORD CALLBACK TAPIProc(LPVOID) { + + HANDLE events[] = {modem_TAPITerminateEvent, modem_TAPIEvent}; + DWORD dwEvent; + MSG msg; + + modem_critsect.Enter(); + LONG result = lineInitialize(&g_hLineApp, global_instance, + TAPIEventCallback, NULL, &g_dwNumDevices); + modem_critsect.Leave(); + ASSERT(!result); + // NOTIFY OF INIT COMPLETION + SetEvent(modem_TAPINotifyEvent); + + while (1) { + if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + ResetEvent(modem_TAPIEvent); + dwEvent = MsgWaitForMultipleObjects(2, events, FALSE, INFINITE, QS_ALLINPUT); + TraceOut("TAPIProc awake"); + if (dwEvent == WAIT_FAILED || !(dwEvent - WAIT_OBJECT_0)) + break; + } + ExitThread(0); + return 0; +} + +//=========================================================================== +static DWORD CALLBACK TAPIAnswerProc(LPVOID) { + HANDLE events[] = {modem_TAPITerminateEvent, modem_TAPIAnswerEvent}; + DWORD dwEvent; + LONG lResult; + + while (1) { + ResetEvent(modem_TAPIAnswerEvent); + dwEvent = WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (dwEvent == WAIT_FAILED || !(dwEvent - WAIT_OBJECT_0)) + break; + + lResult = WaitForReply(lineAnswer(g_hCall, NULL, 0)); + if (lResult) + continue; + + // THIS MAY NOT BE NECESSARY, BUT IT MIGHT BE NICE TO DETECT IF + // THE CALLER IS RUNNING DIABLO AND HAGUP IF NOT, SO GO AHEAD + // AND LEAVE THIS AS A SEPARATE THREAD +#if 0 + // TIMEOUT IF THE CALLER HUNG UP + lResult = WaitForCallState(LINECALLSTATE_CONNECTED, ANSWERTIMEOUT); + if (lResult) + continue; +#endif + } + ExitThread(0); + return 0; +} + +//=========================================================================== +static DWORD CALLBACK TAPIHangupProc(LPVOID) { + HANDLE events[] = {modem_TAPITerminateEvent, modem_TAPIHangupEvent}; + DWORD dwEvent; + while (1) { + ResetEvent(modem_TAPIHangupEvent); + dwEvent = WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (dwEvent == WAIT_FAILED || !(dwEvent - WAIT_OBJECT_0)) + break; + HangupCall(); + SetEvent(modem_TAPIHangupNotify); + if (modem_gameadvinfo) + TakeCall(); + } + ExitThread(0); + return 0; +} + +//=========================================================================== +static void InsertHeaderKey(PACKETHEADERPTR header) +{ + ASSERT(header); + if (!header) + return; + CopyMemory(header->key_sequence, gs_arrHeaderKeys, HEADER_KEYS); +} + +//=========================================================================== +static BOOL ScanForHeader(LPDWORD bytesleft, LPBYTE *dataptr) +{ + ASSERT(bytesleft && *dataptr); + if (!(bytesleft && *dataptr)) + return FALSE; + + static int matchlevel = 0; + while (*bytesleft && matchlevel < HEADER_KEYS) { + if (**dataptr == gs_arrHeaderKeys[matchlevel]) + matchlevel++; + else if (matchlevel) { + matchlevel = 0; + TraceOut("Reset Match"); + continue; + } + (*bytesleft)--; + (*dataptr)++; + } + if (matchlevel == HEADER_KEYS) { + matchlevel = 0; + return TRUE; + } + return FALSE; +} + +//=========================================================================== +unsigned CALLBACK ThreadProc (LPVOID) { + while (modem_state != STATE_SHUTDOWN) { + TraceOut("Read Thread Awake"); + modem_critsect.Enter(); + for (DWORD port = 0; port < PORTS; ++port) { + + if (modem_port[port]->handle == INVALID_HANDLE_VALUE) + continue; + + // CHECK TO SEE IF AN I/O OPERATION HAS COMPLETED ON THIS PORT + if (!GetOverlappedResult(modem_port[port]->handle, + &modem_port[port]->overlapped, + &modem_port[port]->bytesread, + 0)) { + if (GetLastError() == ERROR_OPERATION_ABORTED) + ResetEvent(modem_event[port]); + continue; + } + + // IF SO, PARSE THE INCOMING DATA + DWORD bytesleft = modem_port[port]->bytesread; + LPBYTE dataptr = &modem_port[port]->readbuffer[0]; + TraceDumpAddr("read data", dataptr, bytesleft); + + MESSAGEPTR messageptr; + while (bytesleft) { + messageptr = NULL; + if (modem_port[port]->partialmessage) { + TraceOut("Partial Message"); + messageptr = modem_port[port]->partialmessage; + } + else if (ScanForHeader(&bytesleft, &dataptr)) { + // ALLOCATE NEW RECORD + messageptr = NEW(MESSAGEREC); + ASSERT(messageptr); + if (!messageptr) { + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + TraceOut("NEW(MESSAGEREC)"); + ZeroMemory(messageptr, sizeof(MESSAGEREC)); + messageptr->inport = port; + + // INSERT MULTIBYTE HEADER KEY + InsertHeaderKey(&messageptr->header); + messageptr->bytesread = HEADER_KEYS; + modem_port[port]->partialmessage = messageptr; + } + + // PROCESS NEW AND PARTIAL PACKETS + if (!bytesleft) + continue; + + if (!messageptr->bytesneeded) { + messageptr->bytesneeded = (*dataptr) * sizeof(DWORD); + if (messageptr->bytesneeded > sizeof(PACKETHEADER) + MAXMESSAGESIZE) { + TraceOut("Bogus Packet"); + FREE(messageptr); + modem_port[port]->partialmessage = NULL; + continue; + } + } + LPBYTE writeptr = (LPBYTE)&messageptr->header; + DWORD bytestocopy = + min(bytesleft, messageptr->bytesneeded - messageptr->bytesread); + CopyMemory(writeptr + messageptr->bytesread, dataptr, bytestocopy); + messageptr->bytesread += bytestocopy; + dataptr += bytestocopy; + bytesleft -= bytestocopy; + if (!(messageptr->bytesread < messageptr->bytesneeded)) { + ProcessIncomingMessage(port, messageptr); + modem_port[port]->partialmessage = NULL; + } + } // while (bytesleft) + + // RETURN THIS PORT'S EVENT TO A NONSIGNALED STATE + ResetEvent(modem_event[port]); + + // POST ANOTHER OVERLAPPED READ FOR THIS PORT + ReadFile(modem_port[port]->handle, + modem_port[port]->readbuffer, + READBUFFERSIZE, + &modem_port[port]->bytesread, + &modem_port[port]->overlapped); + } // for (DWORD port = 0; port < PORTS; ++port) + modem_critsect.Leave(); + WaitForMultipleObjects(PORTS,&modem_event[0],0,INFINITE); + } // while (modem_state != STATE_SHUTDOWN) + modem_state = STATE_NOGAME; + _endthreadex(0); + return 0; +} + +//=========================================================================== +static void CleanupEvents() +{ + // CLEANUP EVENTS + if (modem_TAPITerminateEvent) { + CloseHandle(modem_TAPITerminateEvent); + modem_TAPITerminateEvent = NULL; + } + if (modem_TAPIEvent) { + CloseHandle(modem_TAPIEvent); + modem_TAPIEvent = NULL; + } + if (modem_TAPINotifyEvent) { + CloseHandle(modem_TAPINotifyEvent); + modem_TAPINotifyEvent = NULL; + } + if (modem_TAPIHangupEvent) { + CloseHandle(modem_TAPIHangupEvent); + modem_TAPIHangupEvent = NULL; + } + if (modem_TAPIHangupNotify) { + CloseHandle(modem_TAPIHangupNotify); + modem_TAPIHangupNotify = NULL; + } + if (modem_TAPIAnswerEvent) { + CloseHandle(modem_TAPIAnswerEvent); + modem_TAPIAnswerEvent = NULL; + } + if (modem_TAPICallStateEvent) { + CloseHandle(modem_TAPICallStateEvent); + modem_TAPICallStateEvent = NULL; + } + if (modem_TAPILineReplyEvent) { + CloseHandle(modem_TAPILineReplyEvent); + modem_TAPILineReplyEvent = NULL; + } +} + +//=========================================================================== +static BOOL ShutdownTAPI() +{ + long lReturn; + + // If we aren't initialized, then Shutdown is unnecessary. + if (!g_hLineApp) + return TRUE; + + // POST HANGUP AND SHUTDOWN THREADS. HANGUPPROC WILL ALWAYS GIVE + // PREFERENCE TO HANGUP EVENTS OVER DESTROY EVENTS, SO WE KNOW THE + // LINE IS CLEAN AFTER THE WAIT. + + SetEvent(modem_TAPIHangupEvent); + ResetEvent(modem_TAPIHangupNotify); + WaitForSingleObject(modem_TAPIHangupNotify, 2000); + + SetEvent(modem_TAPITerminateEvent); + HANDLE hHarray[] = {modem_tapithread, modem_tapianswerthread, + modem_tapihangupthread}; + WaitForMultipleObjects(3, hHarray, TRUE, 2000); + modem_tapithread = NULL; + modem_tapianswerthread = NULL; + modem_tapihangupthread = NULL; + + CleanupEvents(); + + // SHUTDOWN TAPI INTERFACE + if (g_hLineApp) { + lReturn = lineShutdown(g_hLineApp); + g_hLineApp = NULL; + } + + return TRUE; +} + +//=========================================================================== +static BOOL StartupTAPI() +{ + // If we aren initialized, then Startup is unnecessary. + if (g_hLineApp) + return TRUE; + + modem_TAPITerminateEvent = CreateEvent(NULL, 1, 0, NULL); + modem_TAPIEvent = CreateEvent(NULL, 1, 0, NULL); + modem_TAPINotifyEvent = CreateEvent(NULL, 1, 0, NULL); + modem_TAPIAnswerEvent = CreateEvent(NULL, 1, 0, NULL); + modem_TAPIHangupEvent = CreateEvent(NULL, 1, 0, NULL); + modem_TAPIHangupNotify = CreateEvent(NULL, 1, 0, NULL); + modem_TAPICallStateEvent = CreateEvent(NULL, 1, 0, NULL); + modem_TAPILineReplyEvent = CreateEvent(NULL, 1, 0, NULL); + + // CREATE A THREAD TO HANDLE TAPI MESSAGES. THIS IS NECESSARY + // SINCE MANY SPI FUNCTIONS REQUIRE BLOCKING, AND THIS BRAIN DEAD + // VERSION OF TAPI USES A MESSAGE LOOP FOR STATUS. + ResetEvent(modem_TAPINotifyEvent); + if (modem_TAPIEvent && !modem_tapithread) { + DWORD threadid; + modem_tapithread = CreateThread(NULL, 0, TAPIProc, + NULL, 0, &threadid); + ASSERT(modem_tapithread); + if (!modem_tapithread) { + SetEvent(modem_TAPITerminateEvent); + modem_tapithread = NULL; + SetLastError(SNET_ERROR_MAX_THRDS_REACHED); + return 0; + } + } + WaitForSingleObject(modem_TAPINotifyEvent, INFINITE); + if (!g_hLineApp) { + SetEvent(modem_TAPITerminateEvent); + WaitForSingleObject(modem_tapithread, INFINITE); + modem_tapithread = NULL; + CleanupEvents(); + return 0; + } + + // CREATE THE ANSWER THREAD + if (modem_TAPIAnswerEvent && !modem_tapianswerthread) { + DWORD threadid; + modem_tapianswerthread = CreateThread(NULL, 0, TAPIAnswerProc, + NULL, 0, &threadid); + ASSERT(modem_tapianswerthread); + if (!modem_tapianswerthread) { + SetEvent(modem_TAPITerminateEvent); + modem_tapianswerthread = NULL; + SetLastError(SNET_ERROR_MAX_THRDS_REACHED); + return 0; + } + } + + // CREATE THE HANGUP THREAD + if (modem_TAPIHangupEvent && modem_TAPIHangupNotify && + !modem_tapihangupthread) { + DWORD threadid; + modem_tapihangupthread = CreateThread(NULL, 0, TAPIHangupProc, + NULL, 0, &threadid); + ASSERT(modem_tapihangupthread); + if (!modem_tapihangupthread) { + SetEvent(modem_TAPITerminateEvent); + modem_tapihangupthread = NULL; + SetLastError(SNET_ERROR_MAX_THRDS_REACHED); + return 0; + } + } + + return 1; +} + +//=========================================================================== +static LONG WaitForReply(LONG lRequestedID) +{ + if (!(lRequestedID > 0)) + return lRequestedID; + + modem_critsect.Enter(); + g_lRequestedID = lRequestedID; + g_lAsyncReply = lRequestedID; + ResetEvent(modem_TAPILineReplyEvent); + modem_critsect.Leave(); + WaitForSingleObject(modem_TAPILineReplyEvent, INFINITE); + + return g_lAsyncReply; +} + +//=========================================================================== +static LONG WaitForCallState(DWORD dwDesiredCallState, DWORD dwWaitTime) +{ + modem_critsect.Enter(); + g_dwDesiredCallState = dwDesiredCallState; + ResetEvent(modem_TAPICallStateEvent); + modem_critsect.Leave(); + DWORD dwRes = WaitForSingleObject(modem_TAPICallStateEvent, dwWaitTime); + + if (dwRes == WAIT_TIMEOUT) + return WAITERR_WAITTIMEDOUT; + if (g_dwDesiredCallState != dwDesiredCallState) + return WAITERR_WAITABORTED; + + return 0; +} + +//=========================================================================== +static BOOL HangupCall() +{ + LPLINECALLSTATUS pLineCallStatus = NULL; + long lReturn; + + TraceOut("HangupCall()"); + + StopCom(); + + // SET WAIT EVENTS SO THAT ANY THREAD WAITING ON TAPI EVENTS WILL + // TERMINATE CLEANLY + modem_critsect.Enter(); + g_dwDesiredCallState = LINECALLSTATE_DISCONNECTED; + SetEvent(modem_TAPICallStateEvent); + SetEvent(modem_TAPILineReplyEvent); + modem_critsect.Leave(); + + // If there is a call in progress, drop and deallocate it. + if (g_hCall) { + + pLineCallStatus = (LPLINECALLSTATUS)LocalAlloc(LPTR, sizeof(LINECALLSTATUS)); + ASSERT(pLineCallStatus); + if (!pLineCallStatus) + return FALSE; + lReturn = lineGetCallStatus(g_hCall, pLineCallStatus); + + // Only drop the call when the line is not IDLE. + if (!((pLineCallStatus->dwCallState) & LINECALLSTATE_IDLE)) { + lReturn = WaitForReply(lineDrop(g_hCall, NULL, 0)); + ASSERT(!lReturn); + if (lReturn) + return FALSE; + } + + // Need to free buffer returned from lineGetCallStatus + if (pLineCallStatus) + LocalFree(pLineCallStatus); + + modem_critsect.Enter(); + lReturn = lineDeallocateCall(g_hCall); + ASSERT(!lReturn); + if (lReturn) { + modem_critsect.Leave(); + return FALSE; + } + g_hCall = NULL; + modem_critsect.Leave(); + } + + // if we have a line open, close it. + if (g_hLine) { + modem_critsect.Enter(); + lReturn = lineClose(g_hLine); + ASSERT(!lReturn); + if (lReturn) { + modem_critsect.Leave(); + return FALSE; + } + g_hLine = NULL; + modem_critsect.Leave(); + } + + if (modem_gamelist) { + modem_critsect.Enter(); + FREE(modem_gamelist); + modem_gamelist = NULL; + modem_critsect.Leave(); + } + return TRUE; +} + +//=========================================================================== +static BOOL GetDeviceAPIVersion(DWORD id, LPDWORD lpdwTAPIVersion) +{ + LINEEXTENSIONID lineExtId; + + ASSERT(g_hLineApp && g_dwNumDevices); + LONG lReturn = lineNegotiateAPIVersion(g_hLineApp, id, + TAPI_CURRENT_VERSION, + TAPI_CURRENT_VERSION, + lpdwTAPIVersion, + &lineExtId); + return (!lReturn); +} + +//=========================================================================== +static LPLINEDEVCAPS GetDeviceCaps(DWORD id, DWORD dwTAPIVersion) +{ + LINEDEVCAPS tmpLineDevCaps; + LPLINEDEVCAPS lpLineDevCaps; + LONG lReturn; + + ASSERT(g_hLineApp && g_dwNumDevices); + + tmpLineDevCaps.dwTotalSize = sizeof(tmpLineDevCaps); + lReturn = lineGetDevCaps(g_hLineApp, id, dwTAPIVersion, 0, &tmpLineDevCaps); + if (lReturn) { + return NULL; + } + + lpLineDevCaps = (LPLINEDEVCAPS)LocalAlloc(LPTR, tmpLineDevCaps.dwNeededSize); + ASSERT(lpLineDevCaps); + if (!lpLineDevCaps) { + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + lpLineDevCaps->dwTotalSize = tmpLineDevCaps.dwNeededSize; + lReturn = lineGetDevCaps(g_hLineApp, id, dwTAPIVersion, 0, lpLineDevCaps); + if (lReturn) { + LocalFree(lpLineDevCaps); + return NULL; + } + return lpLineDevCaps; +} + +//=========================================================================== +static LPLINECALLPARAMS CreateCallParams(LPCSTR szAddress) +{ + LPLINECALLPARAMS lpCallParams = NULL; + DWORD dwAddressSize; + + ASSERT(szAddress && *szAddress); + + dwAddressSize = strlen(szAddress) + 1; + + lpCallParams = (LPLINECALLPARAMS)LocalAlloc(LPTR, sizeof(LINECALLPARAMS) + + dwAddressSize); + ASSERT(lpCallParams); + if (!lpCallParams) { + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + lpCallParams->dwTotalSize = sizeof(LINECALLPARAMS) + dwAddressSize; + // This is where we configure the line. + lpCallParams->dwBearerMode = LINEBEARERMODE_VOICE; + lpCallParams->dwMediaMode = LINEMEDIAMODE_DATAMODEM; + + // This specifies that we want to use only IDLE calls and + // don't want to cut into a call that might not be IDLE (ie, in use). + lpCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE; + + // if there are multiple addresses on line, use first anyway. + // It will take a more complex application than a simple tty app + // to use multiple addresses on a line anyway. + lpCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID; + + // Address we are dialing. + lpCallParams->dwDisplayableAddressOffset = sizeof(LINECALLPARAMS); + lpCallParams->dwDisplayableAddressSize = dwAddressSize; + strcpy((LPSTR)lpCallParams + sizeof(LINECALLPARAMS), szAddress); + + return lpCallParams; +} + +//=========================================================================== +static LPLINETRANSLATEOUTPUT TranslateAddress( + DWORD id, DWORD dwTAPIVersion, LPCTSTR szAddress) +{ + LPLINETRANSLATEOUTPUT lpOutput = NULL; + DWORD dwSize; + LONG lReturn; + + ASSERT(g_hLineApp && g_dwNumDevices); + + // LOOP UNTIL WE HAVE ALLOCATED A STRUCTURE LARGE ENOUGH TO + // HOLD THE ENTIRE ADDRESS INFORMATION BLOCK + dwSize = sizeof(LINETRANSLATEOUTPUT); + do { + if (lpOutput) { + dwSize = lpOutput->dwNeededSize; + LocalFree(lpOutput); + } + lpOutput = (LPLINETRANSLATEOUTPUT)LocalAlloc(LPTR, dwSize); + ASSERT(lpOutput); + if (!lpOutput) { + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + lpOutput->dwTotalSize = dwSize; + + lReturn = lineTranslateAddress(g_hLineApp, id, dwTAPIVersion, + szAddress, 0, 0, lpOutput); + ASSERT(!lReturn); + if (lReturn) { + LocalFree(lpOutput); + return NULL; + } + } while (lpOutput->dwTotalSize < lpOutput->dwNeededSize); + + return lpOutput; +} + +//=========================================================================== +static BOOL MakeCall(LPCSTR szAddress) +{ + BOOL bVal; + DWORD dwTAPIVersion; + LPLINEDEVCAPS lpLineDevCaps = NULL; + LPLINECALLPARAMS lpCallParams = NULL; + LPLINETRANSLATEOUTPUT lpOutput = NULL; + LPCTSTR lpDialString = NULL; + LONG lResult; + + TraceOut("MakeCall()"); + + // MAKE SURE LINE SUPPORTS DIAL-OUT + bVal = GetDeviceAPIVersion(g_dwDeviceID, &dwTAPIVersion); + ASSERT(bVal); + if (!bVal) + return 0; + + lpLineDevCaps = GetDeviceCaps(g_dwDeviceID, dwTAPIVersion); + ASSERT(lpLineDevCaps); + if (!lpLineDevCaps) + return 0; + + if (!(lpLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL)) + return 0; + + if (lpLineDevCaps) + LocalFree(lpLineDevCaps); + + modem_critsect.Enter(); + lResult = lineOpen(g_hLineApp, g_dwDeviceID, &g_hLine, dwTAPIVersion, 0, 0, + LINECALLPRIVILEGE_NONE, LINEMEDIAMODE_DATAMODEM, NULL); + modem_critsect.Leave(); + ASSERT(!lResult); + if (lResult == LINEERR_ALLOCATED) + return 0; + if (lResult) + return 0; + + lpCallParams = CreateCallParams(szAddress); + ASSERT(lpCallParams); + if (!lpCallParams) + return 0; + + // CALL TRANSLATE ADDRESS TO CAPTURE ANY LINE PROPERITES SUCH + // AS PULSE DIALING. NOTE THAT COUNTRY AND AREA CODES ARE NOT + // HANDLED - IT IS UP TO THE USER TO ENTER A FULLY QUALIFIED + // DIALING STRING + lpOutput = TranslateAddress(g_dwDeviceID, dwTAPIVersion, szAddress); + ASSERT(lpOutput); + if (!lpOutput) + return 0; + lpDialString = (LPCTSTR)lpOutput + lpOutput->dwDialableStringOffset; + TraceOut("Dialing %s", lpDialString); + + lResult = WaitForReply(lineMakeCall(g_hLine, &g_hCall, lpDialString, + 0, lpCallParams)); + + if (lpCallParams) + LocalFree(lpCallParams); + if (lpOutput) + LocalFree(lpOutput); + + return (!lResult); +} + +//=========================================================================== +static BOOL TakeCall() +{ + BOOL bVal; + DWORD dwTAPIVersion; + LONG lResult; + + TraceOut("TakeCall()"); + bVal = GetDeviceAPIVersion(g_dwDeviceID, &dwTAPIVersion); + if (!bVal) + return 0; + + modem_critsect.Enter(); + lResult = lineOpen(g_hLineApp, g_dwDeviceID, &g_hLine, dwTAPIVersion, 0, 0, + LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_DATAMODEM, NULL); + modem_critsect.Leave(); + ASSERT(!lResult); + if (lResult) + return 0; + + return 1; +} + +//=========================================================================== +static LPVARSTRING GetVarString() +{ + VARSTRING tmpVarString; + LPVARSTRING lpVarString = NULL; + long lReturn; + + ASSERT(g_hCall); + if (!g_hCall) + return NULL; + + tmpVarString.dwTotalSize = sizeof(tmpVarString); + lReturn = lineGetID(0, 0, g_hCall, LINECALLSELECT_CALL, &tmpVarString, + "comm/datamodem"); + ASSERT(!lReturn); + if (lReturn) + return NULL; + + lpVarString = (LPVARSTRING)LocalAlloc(LPTR, tmpVarString.dwNeededSize); + ASSERT(lpVarString); + if (!lpVarString) + return NULL; + + lpVarString->dwTotalSize = tmpVarString.dwNeededSize; + lReturn = lineGetID(0, 0, g_hCall, LINECALLSELECT_CALL, lpVarString, + "comm/datamodem"); + ASSERT(!lReturn); + if (lReturn) { + LocalFree(lpVarString); + return NULL; + } + return lpVarString; +} + +//=========================================================================== +static BOOL InitializePort (DWORD port) { + + // ALLOCATE MEMORY FOR THE PORT RECORD + ASSERT(!modem_port[port]); + if (!modem_port[port]) { + modem_port[port] = NEW(PORTREC); + ASSERT(modem_port[port]); + if (!modem_port[port]) + return 0; + ZeroMemory(modem_port[port],sizeof(PORTREC)); + TraceOut("Allocated port %d", port); + } + + // CREATE AN EVENT FOR OVERLAPPED I/O + ASSERT(!modem_event[port]); + if (!modem_event[port]) { + modem_event[port] = CreateEvent(NULL,1,0,NULL); + if (!modem_event[port]) + return 0; + modem_port[port]->overlapped.hEvent = modem_event[port]; + } + + // Get the handle to the comm port from the driver so we can start + // communicating. This is returned in a LPVARSTRING structure. + LPVARSTRING lpVarString = GetVarString(); + ASSERT(lpVarString); + if (!lpVarString) + return 0; + + // Again, the handle to the comm port is contained in a + // LPVARSTRING structure. Thus, the handle is the very first + // thing after the end of the structure. Note that the name of + // the comm port is right after the handle, but I don't want it. + modem_port[port]->handle = *((LPHANDLE)((LPBYTE)lpVarString + + lpVarString->dwStringOffset)); + ASSERT(modem_port[port]->handle); + + if (lpVarString) + LocalFree(lpVarString); + + // IF WE COULDN'T OPEN THE PORT THEN IT IS PROBABLY UNCONFIGURED OR IN + // USE BY ANOTHER APPLICATION. RETURN SUCCESS BECAUSE THIS ISN'T A FATAL + // ERROR; WE WILL JUST NOT USE THIS PARTICULAR PORT. + if (modem_port[port]->handle == INVALID_HANDLE_VALUE) + return 1; + + // SET THE COMMUNICATIONS TIMEOUT VALUES + { + COMMTIMEOUTS timeouts; + ZeroMemory(&timeouts,sizeof(COMMTIMEOUTS)); + timeouts.ReadIntervalTimeout = READTIMEOUT; + SetCommTimeouts(modem_port[port]->handle, &timeouts); + } + + // fAbortOnError is the only DCB dependancy in TapiComm. + // Can't guarentee that the SP will set this to what we expect. + { + DCB dcb; + GetCommState(modem_port[port]->handle, &dcb); + dcb.fAbortOnError = FALSE; + SetCommState(modem_port[port]->handle, &dcb); + } + + // EXECUTE AN OVERLAPPED READ + ReadFile(modem_port[port]->handle, + modem_port[port]->readbuffer, + READBUFFERSIZE, + &modem_port[port]->bytesread, + &modem_port[port]->overlapped); + + return 1; +} + +//=========================================================================== +static void StopCom() +{ + DWORD port; + + TraceOut("StopCom()"); + // TERMINATE THE READ THREAD + if (!modem_lineestablished) + return; + + modem_state = STATE_SHUTDOWN; + for (port = 0; port < PORTS; ++port) + if (modem_port[port] && modem_port[port]->handle != INVALID_HANDLE_VALUE) + SetEvent(modem_port[port]->overlapped.hEvent); + WaitForSingleObject(modem_readthread,INFINITE); + modem_readthread = NULL; + + // CLOSE AND FREE ALL PORTS + for (port = 0; port < PORTS; ++port) { + if (modem_event[port]) { + CloseHandle(modem_event[port]); + modem_event[port] = NULL; + } + if (modem_port[port]) { + if (modem_port[port]->handle != INVALID_HANDLE_VALUE) + CloseHandle(modem_port[port]->handle); + if (modem_port[port]->partialmessage) + FREE(modem_port[port]->partialmessage); + FREE(modem_port[port]); + modem_port[port] = NULL; + } + } + modem_lineconfirmed = 0; + modem_lineestablished = 0; +} + +//=========================================================================== +static BOOL StartCom() +{ + // Very first, make sure this isn't a duplicated message. + // A CALLSTATE message can be sent whenever there is a + // change to the capabilities of a line, meaning that it is + // possible to receive multiple CONNECTED messages per call. + // The CONNECTED CALLSTATE message is the only one in TapiComm + // where it would cause problems if it where sent more + // than once. + + TraceOut("StartCom()"); + if (modem_lineestablished) + return 1; + + modem_critsect.Enter(); + // INITIALIZE THE SERIAL PORTS + for (DWORD loop = 0; loop < PORTS; ++loop) + if (!InitializePort(loop)) { + // Free the previously allocated port memory + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + SetEvent(modem_TAPIHangupEvent); + return 0; + } + + // CREATE A THREAD TO PROCESS INCOMING PACKETS + ASSERT(!modem_readthread); + if (!modem_readthread) { + unsigned threadid; + modem_readthread = (HANDLE)_beginthreadex(NULL, + 0, + ThreadProc, + NULL, + 0, + &threadid); + ASSERT(modem_readthread); + if (!modem_readthread) { + SetEvent(modem_TAPIHangupEvent); + SetLastError(SNET_ERROR_MAX_THRDS_REACHED); + return 0; + } + SetThreadPriority(modem_readthread,THREAD_PRIORITY_HIGHEST); + } + modem_critsect.Leave(); + + modem_lineestablished = 1; + SendDataMessage(SYS_QUERYLINE,0xFF,NULL,0); + DWORD starttime = GetTickCount(); + while (!modem_lineconfirmed && (GetTickCount() - starttime < MAX_CONNECT_DIFFERENTIAL)) + Sleep(10); + if (!modem_lineconfirmed) + return 0; + + // FIND AN UNUSED NETWORK ID + TraceOut("Finding ID"); + if (!FindNetworkId()) { + TraceOut("Finding ID: Failed!"); + SetEvent(modem_TAPIHangupEvent); + SetLastError(SNET_ERROR_TOO_MANY_NAMES); + return 0; + } + + // SEND OUT A QUERY FOR ACTIVE GAMES + TraceOut("Sending SYS_QUERYGAME"); + SendDataMessage(SYS_QUERYGAME,0xFF,NULL,0); + return 1; +} + +//=========================================================================== +static BOOL CALLBACK DevFillDeviceList(LPLINEDEVCAPS lpLineDevCaps, DWORD dwDevID, + LPARAM appData) +{ + SNETSPI_DEVICELISTPTR *devicelist = (SNETSPI_DEVICELISTPTR*)appData; + SNETSPI_DEVICELIST device; + + strncpy(device.devicename, + ((LPCTSTR)lpLineDevCaps) + lpLineDevCaps->dwLineNameOffset, + SNETSPI_MAXSTRINGLENGTH); + device.deviceid = dwDevID; + LISTADD(devicelist, &device); + return 1; +} + +//=========================================================================== +static void EnumerateDevices(DEVENUMPROC func, LPARAM appData) +{ + LPLINEDEVCAPS lpLineDevCaps = NULL; + DWORD dwTAPIVersion; + DWORD i; + BOOL bVal; + + ASSERT(func); + if (!func) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return; + } + + for (i = 0; i < g_dwNumDevices; i++) { + // Check that we can talk to this TAPI version + bVal = GetDeviceAPIVersion(i, &dwTAPIVersion); + if (!bVal) + continue; + + lpLineDevCaps = GetDeviceCaps(i, dwTAPIVersion); + if (!lpLineDevCaps) + continue; + if (func && !func(lpLineDevCaps, i, appData)) + break; + if (lpLineDevCaps) + LocalFree(lpLineDevCaps); + } +} + +//=========================================================================== +static void EnumerateLocations(LOCENUMPROC func, LPARAM appData) +{ + LINETRANSLATECAPS tmpTranslateCaps; + LPLINETRANSLATECAPS lpTranslateCaps = NULL; + long lReturn; + DWORD dwCounter; + LPLINELOCATIONENTRY lpLocationEntry = NULL; + + // First, get the TRANSLATECAPS + ZeroMemory(&tmpTranslateCaps, sizeof(tmpTranslateCaps)); + tmpTranslateCaps.dwTotalSize = sizeof(tmpTranslateCaps); + lReturn = lineGetTranslateCaps(g_hLineApp, TAPI_CURRENT_VERSION, + &tmpTranslateCaps); + ASSERT(!(lReturn < 0)); + if(lReturn < 0) + return; + lpTranslateCaps = (LPLINETRANSLATECAPS) + LocalAlloc(0, tmpTranslateCaps.dwNeededSize); + ASSERT(lpTranslateCaps); + if(!lpTranslateCaps) + return; + ZeroMemory(lpTranslateCaps, tmpTranslateCaps.dwNeededSize); + lpTranslateCaps->dwTotalSize = tmpTranslateCaps.dwNeededSize; + lReturn = lineGetTranslateCaps(g_hLineApp, TAPI_CURRENT_VERSION, + lpTranslateCaps); + ASSERT(!(lReturn < 0)); + if(lReturn < 0) { + if (lpTranslateCaps) + LocalFree(lpTranslateCaps); + return; + } + + // Find the location information in the TRANSLATECAPS + lpLocationEntry = (LPLINELOCATIONENTRY) + (((LPBYTE) lpTranslateCaps) + lpTranslateCaps->dwLocationListOffset); + + // enumerate all the locations + for (dwCounter = 0; dwCounter < lpTranslateCaps->dwNumLocations; + dwCounter++) { + if (func && !func(lpTranslateCaps, lpLocationEntry + dwCounter, appData)) + break; + } +} + +//=========================================================================== +static void EnumerateCountries(DWORD dwCountryID, COUNTRYENUMPROC func, + LPARAM appData) +{ + LINECOUNTRYLIST tmpLineCountryList; + LPLINECOUNTRYLIST lpLineCountryList = NULL; + DWORD dwSizeofCountryList = sizeof(LINECOUNTRYLIST); + long lReturn; + LPLINECOUNTRYENTRY lpLineCountryEntries = NULL; + DWORD dwCountry; + + // Get the country information stored in TAPI + ZeroMemory(&tmpLineCountryList, sizeof(tmpLineCountryList)); + tmpLineCountryList.dwTotalSize = sizeof(tmpLineCountryList); + lReturn = lineGetCountry (dwCountryID, TAPI_CURRENT_VERSION, + &tmpLineCountryList); + ASSERT(!(lReturn < 0)); + if(lReturn < 0) + return; + lpLineCountryList = (LPLINECOUNTRYLIST) + LocalAlloc(0, tmpLineCountryList.dwNeededSize); + ASSERT(lpLineCountryList); + if(!lpLineCountryList) + return; + ZeroMemory(lpLineCountryList, tmpLineCountryList.dwNeededSize); + lpLineCountryList->dwTotalSize = tmpLineCountryList.dwNeededSize; + lReturn = lineGetCountry (dwCountryID, TAPI_CURRENT_VERSION, + lpLineCountryList); + ASSERT(!(lReturn < 0)); + if(lReturn < 0) { + if (lpLineCountryList) + LocalFree(lpLineCountryList); + return; + } + + lpLineCountryEntries = (LPLINECOUNTRYENTRY)(((LPBYTE)lpLineCountryList) + + lpLineCountryList->dwCountryListOffset); + + // Now enumerate through all the countries + for (dwCountry = 0; dwCountry < lpLineCountryList->dwNumCountries; + dwCountry++) { + if (func && !func(lpLineCountryList, lpLineCountryEntries + dwCountry, + appData)) + break; + } +} + +/**************************************************************************** +* +* SERVICE PROVIDER INTERFACE FUNCTIONS +* +***/ + +//=========================================================================== +BOOL CALLBACK ModemCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude) { + if (diffmagnitude) + *diffmagnitude = 0; + if (!(addr1 && addr2)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + *diffmagnitude = (memcmp(addr1,addr2,sizeof(SNETADDR)) != 0); + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemDestroy() { + + TraceOut("ModemDestroy()"); + // STOP ADVERTISING GAMES + ModemStopAdvertisingGame(); + + // KILL ALL TAPI RELATED THREADS + ShutdownTAPI(); + + // FREE ALL MESSAGES + LISTCLEAR(&modem_messagehead); + + // FREE THE GAME LIST + if (modem_gamelist) { + FREE(modem_gamelist); + modem_gamelist = NULL; + } + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemFree (SNETADDRPTR addr, + LPVOID data, + DWORD databytes) { + if (!(addr && data)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + FREE(addr); + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemFreeExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR mesage) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; +} + +//=========================================================================== +BOOL CALLBACK ModemGetGameInfo (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + SNETSPI_GAMELIST *gameinfo) { + LONG lResult; + + if (!(gamename && gameinfo && (gameid || *gamename))) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + if (gameinfo) + ZeroMemory(gameinfo,sizeof(SNETSPI_GAMELIST)); + + if (!modem_lineestablished) { + modem_networkidlocked = 0; + if (!MakeCall(gamename)) { + SetEvent(modem_TAPIHangupEvent); + SetLastError(SNET_ERROR_BAD_PROVIDER); + return 0; + } + + lResult = WaitForCallState(LINECALLSTATE_CONNECTED, INFINITE); + if (lResult) { + SetLastError(modem_callstatus); + return 0; + } + + // Wait up to FINDGAMETIMEOUT milliseconds for a game + DWORD starttime = GetTickCount(); + while (!modem_gamelist && (GetTickCount() - starttime < FINDGAMETIMEOUT)) + Sleep(10); + } + + if (modem_versionmismatch) { + SetLastError(SNET_ERROR_VERSION_MISMATCH); + return 0; + } + + // IF THE GAME IN THE GAME LIST MATCHES THE QUERY PARAMETERS, RETURN + // ITS INFORMATION + modem_critsect.Enter(); + if (modem_gamelist) + CopyMemory(gameinfo,modem_gamelist,sizeof(SNETSPI_GAMELIST)); + modem_critsect.Leave(); + + if (!gameinfo->gameid) { + SetEvent(modem_TAPIHangupEvent); + SetLastError(SNET_ERROR_GAME_NOT_FOUND); + return 0; + } + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + return PerfGetPerformanceData(counterid, + countervalue, + measurementtime, + measurementfreq); +} + +//=========================================================================== +BOOL CALLBACK ModemInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE event) { + +#ifdef EXPIRATION + SYSTEMTIME sysTime; + GetLocalTime(&sysTime); + if (sysTime.wYear > sg_expDate.wYear || + (sysTime.wYear == sg_expDate.wYear && sysTime.wMonth > sg_expDate.wMonth) || + (sysTime.wYear == sg_expDate.wYear && sysTime.wMonth == sg_expDate.wMonth && + !(sysTime.wDay < sg_expDate.wDay))) { + char buf[256]; + LoadString(global_instance, IDS_EXPIRATION, buf, 256); + SDrawMessageBox(buf, "Version Error", MB_ICONEXCLAMATION); + return 0; + } +#endif + + // SAVE THE PROGRAM AND VERSION IDS AND THE RECEIVE EVENT HANDLE + modem_programid = programdata->programid; + modem_versionid = programdata->versionid; + modem_maxplayers = min(programdata->maxplayers,MAXPLAYERS); + modem_recvevent = event; + + // RESET PERFORMANCE DATA + PerfReset(); + + return StartupTAPI(); +} + +//=========================================================================== +BOOL CALLBACK ModemInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + BOOL bVal; + LPLINEDEVCAPS lpLineDevCaps; + DWORD dwTAPIVersion; + + ASSERT(g_hLineApp && g_dwNumDevices); + + ASSERT(interfacedata->statuscallback); + modem_critsect.Enter(); + modem_status = interfacedata->statuscallback; + modem_critsect.Leave(); + + // Make sure that the line is available and supports data capabilities + bVal = GetDeviceAPIVersion(deviceid, &dwTAPIVersion); + if (!bVal) + return 0; + + lpLineDevCaps = GetDeviceCaps(deviceid, dwTAPIVersion); + if (!lpLineDevCaps) + return 0; + if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM)) { + SetLastError(SNET_ERROR_BAD_PROVIDER); + return 0; + } + if (lpLineDevCaps) + LocalFree(lpLineDevCaps); + + modem_critsect.Enter(); + g_dwDeviceID = deviceid; + modem_critsect.Leave(); + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemLockDeviceList (SNETSPI_DEVICELISTPTR *devicelist) { + ASSERT(devicelist); + if (!devicelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + *devicelist = NULL; + EnumerateDevices(DevFillDeviceList, (LPARAM)devicelist); + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemLockGameList (DWORD categorybits, + DWORD categorymask, + SNETSPI_GAMELISTPTR *gamelist) { + if (!gamelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + // IF WE ARE NOT CURRENTLY CONNECTED RETURN FAIL SO THAT THE + // PROVIDER KNOWS TO BYPASS THE GAME SELECTION SCREEN AND + // DISPLAY THE PHONEBOOK IF AVAILABLE + if (!modem_lineestablished) { + SetLastError(SNET_ERROR_NO_NETWORK); + *gamelist = NULL; + return 0; + } + modem_critsect.Enter(); + *gamelist = modem_gamelist; + return 1; +} + +//=========================================================================== +/* +BOOL CALLBACK ModemReceive (SNETADDRPTR *addr, + LPVOID *data, + DWORD *databytes) { +*/ +BOOL CALLBACK ModemReceive (LPVOID *data, + DWORD *databytes, + SNETADDRPTR *addr) { + if (addr) + *addr = NULL; + if (data) + *data = NULL; + if (databytes) + *databytes = NULL; + if (!(addr && data && databytes)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + if (modem_messagehead) { + modem_critsect.Enter(); + *addr = &modem_messagehead->addr; + *data = &modem_messagehead->data[0]; + *databytes = modem_messagehead->bytesread-sizeof(PACKETHEADER); + LISTFREEPTR(&modem_messagehead,modem_messagehead); + modem_critsect.Leave(); + return 1; + } + else { + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK ModemReceiveExternalMessage (LPCSTR *senderpath, + LPCSTR *sendername, + LPCSTR *message) { + if (senderpath) + *senderpath = NULL; + if (sendername) + *sendername = NULL; + if (message) + *message = NULL; + + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; +} + +//=========================================================================== +BOOL CALLBACK ModemSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { +#ifdef PROVIDERUI + return 0; + +#else + + // BUILD A USER INTERFACE DATA BLOCK + UIPARAMS uiparams; + ZeroMemory(&uiparams,sizeof(UIPARAMS)); + uiparams.flags = flags; + uiparams.programdata = programdata; + uiparams.playerdata = playerdata; + uiparams.interfacedata = interfacedata; + uiparams.versiondata = versiondata; + uiparams.playeridptr = playerid; + + // DISPLAY THE DIALOG BOX + DWORD result = (DWORD)SDlgDialogBoxParam(global_instance, + "MODEM_DIALOG", + interfacedata ? + interfacedata->parentwindow : + SDrawGetFrameWindow(), + ModemDialogProc, + (LPARAM)&uiparams); + result = + ASSERT(!(result == -1)); + if (result == -1) + return 0; + + if (result == IDCANCEL) + return 0; + + // Add capabilities checking here! + + if (result == IDC_MODEMCREATE) { + ASSERT(interfacedata && interfacedata->createcallback); + if (!(interfacedata && interfacedata->createcallback)) + return 0; + // return ModemCreateGame(interfacedata->createcallback); + return 1; + } + return (!(result == -1)); +#endif +} + +//=========================================================================== +BOOL CALLBACK ModemSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes) { + if (!(addresses && addrlist && data && databytes)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // BUILD A TARGET MASK OUT OF THE LIST OF ADDRESSES + BYTE targetmask = 0; + while (addresses--) + targetmask |= (1 << *(LPBYTE)*(addrlist+addresses)); + + // SEND THE MESSAGE + return SendDataMessage(SYS_UNUSED,targetmask,data,databytes); +} + +//=========================================================================== +BOOL CALLBACK ModemSendExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR targetpath, + LPCSTR targetname, + LPCSTR message) { + return 0; +} + +//=========================================================================== +BOOL CALLBACK ModemStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD gameage, + DWORD gamecategorybits, + DWORD optcategorybits, + LPCVOID clientdata, + DWORD clientdatabytes) { + TraceOut("ModemStartAdvertisingGame()"); + if (!(gamename && gamedescription)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // STOP ADVERTISING ANY GAME WE ARE CURRENTLY ADVERTISING + if (modem_gameadvinfo) + ModemStopAdvertisingGame(); + + modem_critsect.Enter(); + // CREATE RECORDS TO ADVERTISE THE GAME + modem_gameadvinfo = NEW(ADVREC); + ASSERT(modem_gameadvinfo); + if (!modem_gameadvinfo) { + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + modem_critsect.Leave(); + return 0; + } + ZeroMemory(modem_gameadvinfo,sizeof(ADVREC)); + + // PICK AN INITIAL ID. THIS WILL NOT BE NEGOTIABLE FOR THE RECEIVING + // MACHINE SINCE WE NEED IT FOR SPISTARTADVERTISINGGAME(). DO NOT INIT + // THIS TO 0 IF WE ARE STARTING TO ADVERTIZE ON AN EXISTING + // CONNECTION + if (!modem_lineestablished) { + modem_networkid = 0; + while (!modem_networkid) + modem_networkid = (BYTE)((PickRandomNumber() % MAXPLAYERS) + 1); + modem_networkidlocked = 1; + } + + // FILL IN THE ADVERTISING INFORMATION + modem_gameadvinfo->networkid = modem_networkid; + modem_gameadvinfo->programid = modem_programid; + modem_gameadvinfo->versionid = modem_versionid; + strcpy(modem_gameadvinfo->strings,gamename); + strcpy(modem_gameadvinfo->strings+strlen(gamename)+1,gamedescription); + modem_gameadvinfo->bytes = 2*sizeof(DWORD)+strlen(gamename)+strlen(gamedescription)+2; + + modem_critsect.Leave(); + + // IF WE ARE TRYING TO TAKE OVER A GAME FROM A DROPPED SERVER, + // WE WILL CONFIGURE THE LINE TO RECEIVE CALLS IN THE UPCOMING + // LINESTATUS_DISCONNECT + if (!modem_lineestablished) { + if (!TakeCall()) { + SetLastError(SNET_ERROR_NO_NETWORK); + return 0; + } + } + else + SendDataMessage(SYS_GAMEINFO,0xFF,modem_gameadvinfo,modem_gameadvinfo->bytes); + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemStopAdvertisingGame () { + TraceOut("ModemStopAdvertisingGame enter"); + if (!modem_gameadvinfo) { + SetLastError(SNET_ERROR_NOT_OWNER); + return 0; + } + SendDataMessage(SYS_REMOVE,0xFF,modem_gameadvinfo,modem_gameadvinfo->bytes); + modem_critsect.Enter(); + if (modem_gameadvinfo) { + FREE(modem_gameadvinfo); + modem_gameadvinfo = NULL; + } + modem_critsect.Leave(); + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemUnlockDeviceList (SNETSPI_DEVICELISTPTR devicelist) { + if (devicelist) + LISTCLEAR(&devicelist); + return 1; +} + +//=========================================================================== +BOOL CALLBACK ModemUnlockGameList (SNETSPI_GAMELISTPTR gamelist, + DWORD *hintnextcall) { + modem_critsect.Leave(); + if (hintnextcall) + *hintnextcall = 1000; + SendDataMessage(SYS_QUERYGAME,0xFF,NULL,0); + return 1; +} + +/**************************************************************************** +* +* EXPORTED STRUCTURES +* +***/ + +DWORD modem_id = PROVIDERID; +LPCSTR modem_desc = "Modem"; +LPCSTR modem_req = "Two computers, each with its own modem and phone line."; +SNETCAPS modem_caps = {sizeof(SNETCAPS), // size +#ifdef _DEBUG + SNET_CAPS_DEBUGONLY, +#else + SNET_CAPS_RETAILONLY, +#endif + MAXMESSAGESIZE, // max message size + 16, // max queue size, + MAXPLAYERS, // max players, + 1000, // bytes per second + 250, // latency (ms) + 4, // default turns per second + 2}; // default turns in transit +SNETSPI modem_spi = {sizeof(SNETSPI), + ModemCompareNetAddresses, + ModemDestroy, + ModemFree, + ModemFreeExternalMessage, + ModemGetGameInfo, + ModemGetPerformanceData, + ModemInitialize, + ModemInitializeDevice, + ModemLockDeviceList, + ModemLockGameList, + ModemReceive, + ModemReceiveExternalMessage, + ModemSelectGame, + ModemSend, + ModemSendExternalMessage, + ModemStartAdvertisingGame, + ModemStopAdvertisingGame, + ModemUnlockDeviceList, + ModemUnlockGameList}; diff --git a/Storm/SOURCE/STANDARD/NULL.CPP b/Storm/SOURCE/STANDARD/NULL.CPP new file mode 100644 index 0000000..aeffe0b --- /dev/null +++ b/Storm/SOURCE/STANDARD/NULL.CPP @@ -0,0 +1,261 @@ +/**************************************************************************** +* +* NULL.CPP +* Null provider +* +* By Michael O'Brien (6/27/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define MAXMESSAGESIZE 512 + +/**************************************************************************** +* +* SERVICE PROVIDER INTERFACE FUNCTIONS +* +***/ + +//=========================================================================== +BOOL CALLBACK NullCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude) { + if (diffmagnitude) + *diffmagnitude = 0; + if (!(addr1 && addr2)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + if (diffmagnitude) + *diffmagnitude = !memcmp(addr1,addr2,sizeof(SNETADDR)); + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullDestroy () { + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullFree (SNETADDRPTR addr, + LPVOID data, + DWORD databytes) { + if (!(addr && data)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullFreeExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR mesage) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; +} + +//=========================================================================== +BOOL CALLBACK NullGetGameInfo (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + SNETSPI_GAMELIST *gameinfo) { + SetLastError(SNET_ERROR_GAME_NOT_FOUND); + return 0; +} + +//=========================================================================== +BOOL CALLBACK NullGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + return PerfGetPerformanceData(counterid, + countervalue, + measurementtime, + measurementfreq); +} + +//=========================================================================== +BOOL CALLBACK NullInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE event) { + PerfReset(); + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + + // WE NEVER RETURN ANY DEVICES, SO THIS FUNCTION SHOULD NEVER BE CALLED + return 0; +} + +//=========================================================================== +BOOL CALLBACK NullLockDeviceList (SNETSPI_DEVICELISTPTR *devicelist) { + *devicelist = NULL; + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullLockGameList (DWORD categorybits, + DWORD categorymask, + SNETSPI_GAMELISTPTR *gamelist) { + if (gamelist) + *gamelist = NULL; + if (!gamelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + return 1; +} + +//=========================================================================== +/* +BOOL CALLBACK NullReceive (SNETADDRPTR *addr, + LPVOID *data, + DWORD *databytes) { +*/ +BOOL CALLBACK NullReceive (LPVOID *data, + DWORD *databytes, + SNETADDRPTR *addr) { + if (addr) + *addr = NULL; + if (data) + *data = NULL; + if (databytes) + *databytes = NULL; + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; +} + +//=========================================================================== +BOOL CALLBACK NullReceiveExternalMessage (LPCSTR *senderpath, + LPCSTR *sendername, + LPCSTR *message) { + if (senderpath) + *senderpath = NULL; + if (sendername) + *sendername = NULL; + if (message) + *message = NULL; + + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; +} + +//=========================================================================== +BOOL CALLBACK NullSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + return 0; +} + +//=========================================================================== +BOOL CALLBACK NullSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes) { + if (!(addresses && addrlist && data && databytes)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullSendExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR targetpath, + LPCSTR targetname, + LPCSTR message) { + return 0; +} + +//=========================================================================== +BOOL CALLBACK NullStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD gameage, + DWORD gamecategorybits, + DWORD optcategorybits, + LPCVOID clientdata, + DWORD clientdatabytes) { + if (!(gamename && gamedescription)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullStopAdvertisingGame () { + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullUnlockDeviceList (SNETSPI_DEVICELISTPTR devicelist) { + return 1; +} + +//=========================================================================== +BOOL CALLBACK NullUnlockGameList (SNETSPI_GAMELISTPTR gamelist, + DWORD *hintnextcall) { + if (hintnextcall) + *hintnextcall = 0; + return 1; +} + +/**************************************************************************** +* +* EXPORTED STRUCTURES +* +***/ + +DWORD null_id = 0; +LPCSTR null_desc = ""; +LPCSTR null_req = ""; +SNETCAPS null_caps = {sizeof(SNETCAPS), // size +#ifdef _DEBUG + SNET_CAPS_DEBUGONLY, +#else + SNET_CAPS_RETAILONLY, +#endif + MAXMESSAGESIZE, // max message size + 16, // max queue size, + 1, // max players, + 0x300000, // bytes per second + 0, // latency (ms) + 30, // default turns per second + 0}; // default turns in transit +SNETSPI null_spi = {sizeof(SNETSPI), + NullCompareNetAddresses, + NullDestroy, + NullFree, + NullFreeExternalMessage, + NullGetGameInfo, + NullGetPerformanceData, + NullInitialize, + NullInitializeDevice, + NullLockDeviceList, + NullLockGameList, + NullReceive, + NullReceiveExternalMessage, + NullSelectGame, + NullSend, + NullSendExternalMessage, + NullStartAdvertisingGame, + NullStopAdvertisingGame, + NullUnlockDeviceList, + NullUnlockGameList}; diff --git a/Storm/SOURCE/STANDARD/PCH.H b/Storm/SOURCE/STANDARD/PCH.H new file mode 100644 index 0000000..a3e37f6 --- /dev/null +++ b/Storm/SOURCE/STANDARD/PCH.H @@ -0,0 +1,9 @@ +#define STRICT +#include +#include +#include +#include +#include "../../H/STORM.H" +#include "standard.h" +#include "trace.h" +#include "resource.h" diff --git a/Storm/SOURCE/STANDARD/PERF.CPP b/Storm/SOURCE/STANDARD/PERF.CPP new file mode 100644 index 0000000..9c2a041 --- /dev/null +++ b/Storm/SOURCE/STANDARD/PERF.CPP @@ -0,0 +1,63 @@ +/**************************************************************************** +* +* PERF.CPP +* Common performance monitoring functions +* +* By Michael O'Brien (12/1/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +static DWORD perfdata[PERFNUM] = {0}; + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +void PerfAdd (DWORD id, DWORD value) { + if (id < PERFNUM) + perfdata[id] += value; +} + +//=========================================================================== +BOOL PerfGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + switch (counterid) { + + case SNET_PERFID_PKTSENTONWIRE: + *countervalue = perfdata[PERF_PKTSENT]; + return 1; + + case SNET_PERFID_PKTRECVONWIRE: + *countervalue = perfdata[PERF_PKTRECV]; + return 1; + + case SNET_PERFID_BYTESSENTONWIRE: + *countervalue = perfdata[PERF_BYTESSENT]; + return 1; + + case SNET_PERFID_BYTESRECVONWIRE: + *countervalue = perfdata[PERF_BYTESRECV]; + return 1; + + } + return 0; +} + +//=========================================================================== +void PerfIncrement (DWORD id) { + if (id < PERFNUM) + InterlockedIncrement((LONG *)&perfdata[id]); +} + +//=========================================================================== +void PerfReset () { + ZeroMemory(&perfdata[0],PERFNUM*sizeof(DWORD)); +} diff --git a/Storm/SOURCE/STANDARD/RESOURCE.H b/Storm/SOURCE/STANDARD/RESOURCE.H new file mode 100644 index 0000000..5d81a3a --- /dev/null +++ b/Storm/SOURCE/STANDARD/RESOURCE.H @@ -0,0 +1,59 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by standard.RC +// +#define IDS_PBADD 1 +#define IDS_PBEDIT 2 +#define IDC_CREATEGAME 3 +#define IDC_MODEMJOIN 3 +#define IDS_NODEVICES 3 +#define IDS_NOLOCATIONS 4 +#define IDS_DIALING 5 +#define IDS_RINGING 6 +#define IDS_CONNECTING 7 +#define IDS_PROCEEDING 8 +#define IDS_DIALTONE 9 +#define IDC_GAMEDESCRIPTION 103 +#define IDC_PROGRAMDESCRIPTION 104 +#define IDD_DIALOG1 104 +#define IDD_DIALOG2 105 +#define IDC_GAMELIST 1001 +#define IDC_EDIT1 1002 +#define IDC_LIST1 1003 +#define IDC_LOCATION 1003 +#define IDC_PHONEBOOK 1003 +#define IDC_EDIT2 1004 +#define IDC_LIST2 1005 +#define IDC_COMBO1 1006 +#define IDC_COUNTRYCODE 1006 +#define IDC_CALL 1008 +#define IDC_CANCEL 1009 +#define IDC_CHECK1 1010 +#define IDC_MODEMCREATE 1011 +#define IDC_DEVICELIST 1013 +#define IDC_CALLINGCARD 1014 +#define IDC_CHANGELOCATION 1015 +#define IDC_CHANGEMODEM 1016 +#define IDC_PHONEBOOKADD 1017 +#define IDC_PHONEBOOKREMOVE 1018 +#define IDC_CURRENTMODEM 1019 +#define IDC_CURRENTLOCATION 1020 +#define IDC_PHONEBOOKEDIT 1021 +#define IDC_PBNAME 1021 +#define IDC_AREACODE 1022 +#define IDC_PBNUMBER 1023 +#define IDC_PBOPERATION 1025 +#define IDC_LOCLIST 1026 +#define IDC_COUNTRY 1026 +#define IDC_CHANGECOUNTRY 1027 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1028 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Storm/SOURCE/STANDARD/SERIAL.CPP b/Storm/SOURCE/STANDARD/SERIAL.CPP new file mode 100644 index 0000000..17abcd6 --- /dev/null +++ b/Storm/SOURCE/STANDARD/SERIAL.CPP @@ -0,0 +1,1053 @@ +/**************************************************************************** +* +* SERIAL.CPP +* Serial provider +* +* By Michael O'Brien (8/29/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define MAXMESSAGESIZE 512 +#define MAXPLAYERS 4 +#define PORTS 8 +#define PROVIDERID 'SCBL' +#define READBUFFERSIZE 64 +#define STARTBYTE 0xFE + +#define STATE_NOGAME 0 +#define STATE_FOUNDGAME 1 +#define STATE_INGAME 2 +#define STATE_SHUTDOWN 3 + +#define TYPE_USERDATA 0 +#define TYPE_SYSTEMDATA 1 + +#define SYS_UNUSED 0 +#define SYS_QUERYID 1 +#define SYS_ASSERTID 2 +#define SYS_QUERYGAME 9 +#define SYS_GAMEINFO 10 + +typedef struct _ADVREC { + DWORD networkid; + DWORD programid; + DWORD versionid; + char strings[SNETSPI_MAXSTRINGLENGTH*2]; + DWORD bytes; +} ADVREC, *ADVPTR; + +typedef struct _PACKETHEADER { + BYTE startbyte_type; // must be first field + BYTE sizedwords; // must be second field + BYTE targetmask; + union { + struct { + BYTE fromid:4; + BYTE timetolive:4; + }; + struct { + BYTE sysmsgtype:4; + BYTE timetolive:4; + }; + }; +} PACKETHEADER, *PACKETHEADERPTR; + +typedef struct _MESSAGEREC { + SNETADDR addr; // must be first field + PACKETHEADER header; // must immediately precede data + BYTE data[MAXMESSAGESIZE]; + DWORD bytesneeded; + DWORD bytesread; + DWORD inport; + _MESSAGEREC *next; +} MESSAGEREC, *MESSAGEPTR; + +typedef struct _MESSAGEDATAREC { + PACKETHEADER header; // must immediately precede data + BYTE data[MAXMESSAGESIZE]; +} MESSAGEDATAREC, *MESSAGEDATAPTR; + +typedef struct _PORTREC { + HANDLE handle; + OVERLAPPED overlapped; + BYTE readbuffer[READBUFFERSIZE]; + DWORD bytesread; + MESSAGEPTR partialmessage; + BYTE networkids; +} PORTREC, *PORTPTR; + +static CCritSect serial_critsect; +static HANDLE serial_event[PORTS] = {0}; +static ADVPTR serial_gameadvinfo = NULL; +static SNETSPI_GAMELISTPTR serial_gamelist = NULL; +static DWORD serial_maxplayers = MAXPLAYERS; +static MESSAGEPTR serial_messagehead = NULL; +static BYTE serial_networkid = 0; +static BOOL serial_networkidlocked = 0; +static PORTPTR serial_port[PORTS] = {0}; +static DWORD serial_programid = 0; +static HANDLE serial_recvevent = NULL; +static DWORD serial_routeloopcheck = 0; +static DWORD serial_state = STATE_NOGAME; +static HANDLE serial_thread = NULL; +static DWORD serial_versionid = 0; +static BOOL serial_versionmismatch = 0; + +static DWORD PickRandomNumber (); +static void SendFormedMessage (MESSAGEDATAPTR messageptr, + DWORD exceptport, + BOOL wait); +static BOOL SendMessage (BYTE sysmsgtype, + BYTE targetmask, + LPVOID data, + DWORD databytes); +BOOL CALLBACK SerialStopAdvertisingGame (); + +//=========================================================================== +static BOOL FindNetworkId () { + DWORD timeout = 16; + while (timeout--) { + + // PICK A RANDOM NUMBER WHICH WE CAN USE TO RECOGNIZE AND DISCARD OUR + // OWN PACKETS IN THE CASE OF A ROUTING LOOP. MAKE SURE THE NUMBER IS + // NOT ZERO, BECAUSE COMPUTERS WITH ESTABLISHED NETWORK IDS WILL USE ZERO. + serial_routeloopcheck = 0; + while (!serial_routeloopcheck) + serial_routeloopcheck = PickRandomNumber(); + + // PICK A NETWORK ID AT RANDOM, AND SEND OUT A QUERY TO SEE IF ANYONE + // ELSE IS USING IT. + serial_networkid = 0; + while (!serial_networkid) + serial_networkid = (BYTE)(PickRandomNumber() & 7); + DWORD messagedata[2] = {serial_networkid,serial_routeloopcheck}; + SendMessage(SYS_QUERYID,0xFF,&messagedata[0],2*sizeof(DWORD)); + + // WAIT 500 MILLISECONDS FOR A RESPONSE. IF ANY OTHER COMPUTER ASSERTS + // THAT IT IS USING THE ID WE PICKED, OR IF ANY OTHER COMPUTER QUERIES + // FOR THE SAME ID, THEN GIVE UP THAT ID AND PICK A NEW ONE. + DWORD starttime = GetTickCount(); + while (serial_networkid && (GetTickCount()-starttime < 500)) + Sleep(1); + if (!serial_networkid) + continue; + + // NO OTHER COMPUTER CONTESTED OUR NETWORK ID. LOCK IT DOWN, ASSERT IT + // ON THE NETWORK, AND RETURN SUCCESS. + serial_networkidlocked = 1; + serial_routeloopcheck = 0; + SendMessage(SYS_ASSERTID,0xFF,&serial_networkid,sizeof(DWORD)); + return 1; + + } + return 0; +} + +//=========================================================================== +static BOOL InitializePort (DWORD port) { + + // ALLOCATE MEMORY FOR THE PORT RECORD + if (!serial_port[port]) { + serial_port[port] = NEW(PORTREC); + if (serial_port[port]) + ZeroMemory(serial_port[port],sizeof(PORTREC)); + else + return 0; + } + + // CREATE AN EVENT FOR OVERLAPPED I/O + if (!serial_event[port]) { + serial_event[port] = CreateEvent(NULL,1,0,NULL); + if (serial_event[port]) + serial_port[port]->overlapped.hEvent = serial_event[port]; + else + return 0; + } + + // OPEN THE COMMUNICATIONS PORT + { + TCHAR portname[16]; + wsprintf(portname,TEXT("\\\\.\\COM%u"),(port+1)); + serial_port[port]->handle = CreateFile(portname, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + } + + // IF WE COULDN'T OPEN THE PORT THEN IT IS PROBABLY UNCONFIGURED OR IN + // USE BY ANOTHER APPLICATION. RETURN SUCCESS BECAUSE THIS ISN'T A FATAL + // ERROR; WE WILL JUST NOT USE THIS PARTICULAR PORT. + if (serial_port[port]->handle == INVALID_HANDLE_VALUE) + return 1; + + // SET THE COMMUNICATIONS STATE + // (WE DO THIS THE HARD WAY BECAUSE BUILDCOMMDCB() DOESN'T WORK RIGHT + // ON WINDOWS 95) + { + DCB dcb; + ZeroMemory(&dcb,sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + dcb.BaudRate = CBR_56000; + SRegLoadValue("Network Providers\\Serial","Baud Rate",0,&dcb.BaudRate); + dcb.fBinary = 1; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + dcb.ErrorChar = 63; + dcb.EofChar = 26; + SetCommState(serial_port[port]->handle,&dcb); + } + + // SET THE COMMUNICATIONS TIMEOUT VALUES + { + COMMTIMEOUTS timeouts; + ZeroMemory(&timeouts,sizeof(COMMTIMEOUTS)); + timeouts.ReadIntervalTimeout = 5; + SetCommTimeouts(serial_port[port]->handle,&timeouts); + } + + // EXECUTE AN OVERLAPPED READ + ReadFile(serial_port[port]->handle, + serial_port[port]->readbuffer, + READBUFFERSIZE, + &serial_port[port]->bytesread, + &serial_port[port]->overlapped); + + return 1; +} + +//=========================================================================== +static DWORD PickRandomNumber () { + // RETURN A DWORD-SIZED RANDOM NUMBER. IT IS IMPORTANT THAT WE DON'T + // USE THE RUNTIME LIBRARY RANDOM GENERATOR, BECAUSE WE DON'T WANT TO + // INTERFERE WITH THE APPLICATION'S RANDOM SEQUENCE. + LARGE_INTEGER perfcount; + POINT pos; + QueryPerformanceCounter(&perfcount); + GetCursorPos(&pos); + + static DWORD seed = 0x100001; + seed ^= perfcount.LowPart ^ GetTickCount() ^ pos.x ^ pos.y; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand1 = seed & 0xFFFF; + seed = (seed*0x7D+3) % 0x2AAAAB; + DWORD rand2 = seed & 0xFFFF; + return (rand1 << 16) | rand2; +} + +//=========================================================================== +static void ProcessIncomingMessage (DWORD port, MESSAGEPTR messageptr) { + PerfIncrement(PERF_PKTRECV); + PerfAdd(PERF_BYTESRECV,messageptr->bytesread); + BOOL systemmessage = (messageptr->header.startbyte_type-STARTBYTE == TYPE_SYSTEMDATA); + + // VALIDATE THE PORT NUMBER + if (port >= PORTS) { + FREE(messageptr); + return; + } + + // IF THIS MESSAGE HAS A NON-ZERO TIME TO LIVE AND HAS ADDITIONAL + // RECIPIENTS, SEND IT OUT ON ALL ACTIVE PORTS WHICH LEAD TO THE + // OTHER TARGET RECIPIENTS, EXCEPT THE PORT THE MESSAGE CAME IN ON + BYTE origtargetmask = messageptr->header.targetmask; + if (messageptr->header.timetolive--) { + if (serial_networkid && serial_networkidlocked) + messageptr->header.targetmask &= ~(1 << serial_networkid); + if (messageptr->header.targetmask) + SendFormedMessage((MESSAGEDATAPTR)&messageptr->header, + port, + 1); + } + + // VERIFY THAT WE ARE A RECIPIENT OF THIS MESSAGE, AND NOT THE SENDER + if (serial_networkid && serial_networkidlocked && + ((!(origtargetmask & (1 << serial_networkid))) || + ((!systemmessage) && + (messageptr->header.fromid == serial_networkid)))) { + FREE(messageptr); + return; + } + + // PROCESS USER MESSAGES + if (!systemmessage) + if (serial_networkid && serial_networkidlocked) { + *(LPBYTE)&messageptr->addr = messageptr->header.fromid; + LISTADDPTREND(&serial_messagehead,messageptr); + if (serial_recvevent) + SetEvent(serial_recvevent); + } + else + FREE(messageptr); + + // PROCESS SYSTEM MESSAGES + else { + switch (messageptr->header.sysmsgtype) { + + case SYS_QUERYID: + if (messageptr->bytesread >= sizeof(PACKETHEADER)+2*sizeof(DWORD)) { + DWORD networkid = *(LPDWORD)&messageptr->data[0]; + DWORD routeloopcheck = *(LPDWORD)&messageptr->data[sizeof(DWORD)]; + if (routeloopcheck != serial_routeloopcheck) + if (serial_networkidlocked) + SendMessage(SYS_ASSERTID,0xFF,&serial_networkid,sizeof(DWORD)); + else if (networkid == serial_networkid) + serial_networkid = 0; + } + break; + + case SYS_ASSERTID: + if (messageptr->bytesread >= sizeof(PACKETHEADER)+sizeof(DWORD)) { + DWORD networkid = *(LPDWORD)&messageptr->data[0]; + serial_port[port]->networkids |= (1 << networkid); + if ((!serial_networkidlocked) && (networkid == serial_networkid)) + serial_networkid = 0; + } + break; + + case SYS_QUERYGAME: + if (serial_gameadvinfo) + SendMessage(SYS_GAMEINFO,0xFF,serial_gameadvinfo,serial_gameadvinfo->bytes); + break; + + case SYS_GAMEINFO: + { + ADVPTR advinfo = (ADVPTR)&messageptr->data[0]; + if ((advinfo->programid == serial_programid) && + (advinfo->versionid == serial_versionid)) { + if (!serial_gamelist) { + serial_gamelist = NEW(SNETSPI_GAMELIST); + ZeroMemory(serial_gamelist,sizeof(SNETSPI_GAMELIST)); + } + if (serial_gamelist) { + *(LPBYTE)&serial_gamelist->owner = (BYTE)advinfo->networkid; + serial_gamelist->gameid = 1; + strcpy(serial_gamelist->gamename,advinfo->strings); + strcpy(serial_gamelist->gamedescription,advinfo->strings+strlen(advinfo->strings)+1); + } + } + else + serial_versionmismatch = 1; + } + break; + + } + FREE(messageptr); + } + +} + +//=========================================================================== +static void SendFormedMessage (MESSAGEDATAPTR messageptr, + DWORD exceptport, + BOOL wait) { + BOOL systemmessage = (messageptr->header.startbyte_type == STARTBYTE+TYPE_SYSTEMDATA); + + // IF THIS IS A SYSTEM MESSAGE, WRITE IT OUT ON ALL ACTIVE PORTS. + // OTHERWISE, WRITE IT OUT ON ALL PORTS WHICH LEAD TO ANY OF THE + // DESIRED NETWORK IDS. + HANDLE event[PORTS]; + OVERLAPPED overlapped[PORTS]; + DWORD byteswritten[PORTS]; + DWORD numsends = 0; + { + for (DWORD port = 0; port < PORTS; ++port) + if ((port != exceptport) && + (serial_port[port]->handle != INVALID_HANDLE_VALUE) && + (systemmessage || + (serial_port[port]->networkids & messageptr->header.targetmask))) { + ZeroMemory(&overlapped[numsends],sizeof(OVERLAPPED)); + if (wait) + event[numsends] = CreateEvent(NULL,0,0,NULL); + overlapped[numsends].hEvent = event[numsends]; + WriteFile(serial_port[port]->handle, + messageptr, + messageptr->header.sizedwords*sizeof(DWORD), + &byteswritten[numsends], + &overlapped[numsends]); + ++numsends; + PerfIncrement(PERF_PKTSENT); + PerfAdd(PERF_BYTESSENT,messageptr->header.sizedwords*sizeof(DWORD)); + } + } + + // WAIT FOR ALL WRITES TO COMPLETE + if (numsends && wait) { + WaitForMultipleObjects(numsends,&event[0],1,INFINITE); + while (numsends--) + CloseHandle(event[numsends]); + } + +} + +//=========================================================================== +static BOOL SendMessage (BYTE sysmsgtype, + BYTE targetmask, + LPVOID data, + DWORD databytes) { + BOOL systemmessage = (sysmsgtype != SYS_UNUSED); + if (systemmessage) + targetmask = 0xFF; + + // REFUSE TO SEND A NON-SYSTEM MESSAGE IF WE DON'T HAVE A VALID NETWORK ID + if ((sysmsgtype == SYS_UNUSED) && (!(serial_networkid && serial_networkidlocked))) + return 0; + + // CREATE A FULLY-FORMED MESSAGE + MESSAGEDATAREC messagedata; + ZeroMemory(&messagedata,sizeof(MESSAGEDATAREC)); + messagedata.header.startbyte_type = STARTBYTE+((sysmsgtype == SYS_UNUSED) ? TYPE_USERDATA : TYPE_SYSTEMDATA); + messagedata.header.sizedwords = (sizeof(PACKETHEADER)+databytes+sizeof(DWORD)-1)/sizeof(DWORD); + messagedata.header.timetolive = MAXPLAYERS; + messagedata.header.targetmask = targetmask; + if (systemmessage) + messagedata.header.sysmsgtype = sysmsgtype; + else + messagedata.header.fromid = serial_networkid; + if (data && databytes) + CopyMemory(&messagedata.data[0],data,databytes); + + // SEND IT + SendFormedMessage(&messagedata,0xFFFFFFFF,1); + + return 1; +} + +//=========================================================================== +static unsigned CALLBACK ThreadProc (LPVOID) { + while (serial_state != STATE_SHUTDOWN) { + serial_critsect.Enter(); + for (DWORD port = 0; port < PORTS; ++port) + if (serial_port[port]->handle != INVALID_HANDLE_VALUE) { + + // CHECK TO SEE IF AN I/O OPERATION HAS COMPLETED ON THIS PORT + if (GetOverlappedResult(serial_port[port]->handle, + &serial_port[port]->overlapped, + &serial_port[port]->bytesread, + 0)) { + + // IF SO, PARSE THE INCOMING DATA + DWORD bytesleft = serial_port[port]->bytesread; + LPBYTE dataptr = &serial_port[port]->readbuffer[0]; + while (bytesleft) { + + // IF WE HAVE A PARTIAL MESSAGE WAITING, TRY TO COMPLETE THE + // MESSAGE + if (serial_port[port]->partialmessage) { + if (!serial_port[port]->partialmessage->bytesneeded) + serial_port[port]->partialmessage->bytesneeded + = min(sizeof(PACKETHEADER)+MAXMESSAGESIZE, + (*dataptr)*sizeof(DWORD)); + LPBYTE writeptr = (LPBYTE)&serial_port[port]->partialmessage->header; + DWORD bytestocopy = min(bytesleft, + serial_port[port]->partialmessage->bytesneeded + -serial_port[port]->partialmessage->bytesread); + CopyMemory(writeptr+serial_port[port]->partialmessage->bytesread, + dataptr, + bytestocopy); + serial_port[port]->partialmessage->bytesread += bytestocopy; + dataptr += bytestocopy; + bytesleft -= bytestocopy; + if (serial_port[port]->partialmessage->bytesread >= serial_port[port]->partialmessage->bytesneeded) { + ProcessIncomingMessage(port,serial_port[port]->partialmessage); + serial_port[port]->partialmessage = NULL; + } + } + + // SCAN TO THE BEGINNING OF THE NEXT MESSAGE + while (bytesleft && (*dataptr < STARTBYTE)) { + ++dataptr; + --bytesleft; + } + + // IF A MESSAGE IS AVAILABLE, CREATE A NEW MESSAGE RECORD TO + // HOLD IT + if (bytesleft) { + MESSAGEPTR messageptr = NEW(MESSAGEREC); + if (messageptr) { + ZeroMemory(messageptr,sizeof(MESSAGEREC)); + messageptr->inport = port; + messageptr->bytesneeded = (bytesleft >= 2) ? (*(dataptr+1))*sizeof(DWORD) + : 0; + if (messageptr->bytesneeded > sizeof(PACKETHEADER)+MAXMESSAGESIZE) + messageptr->bytesneeded = sizeof(PACKETHEADER)+MAXMESSAGESIZE; + DWORD bytestocopy = messageptr->bytesneeded ? min(bytesleft,messageptr->bytesneeded) + : 1; + LPBYTE writeptr = (LPBYTE)&messageptr->header; + CopyMemory(writeptr,dataptr,bytestocopy); + dataptr += bytestocopy; + bytesleft -= bytestocopy; + messageptr->bytesread = bytestocopy; + if (messageptr->bytesneeded && + (messageptr->bytesread >= messageptr->bytesneeded)) + ProcessIncomingMessage(port,messageptr); + else + serial_port[port]->partialmessage = messageptr; + } + else + bytesleft = 0; + } + + } + + // RETURN THIS PORT'S EVENT TO A NONSIGNALED STATE + ResetEvent(serial_event[port]); + + // POST ANOTHER OVERLAPPED READ FOR THIS PORT + ReadFile(serial_port[port]->handle, + serial_port[port]->readbuffer, + READBUFFERSIZE, + &serial_port[port]->bytesread, + &serial_port[port]->overlapped); + + } + + } + serial_critsect.Leave(); + WaitForMultipleObjects(PORTS,&serial_event[0],0,INFINITE); + } + serial_state = STATE_NOGAME; + _endthreadex(0); + return 0; +} + +/**************************************************************************** +* +* SERVICE PROVIDER INTERFACE FUNCTIONS +* +***/ + +//=========================================================================== +BOOL CALLBACK SerialCompareNetAddresses (SNETADDRPTR addr1, + SNETADDRPTR addr2, + DWORD *diffmagnitude) { + if (diffmagnitude) + *diffmagnitude = 0; + if (!(addr1 && addr2)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + *diffmagnitude = (memcmp(addr1,addr2,sizeof(SNETADDR)) != 0); + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialDestroy () { + + // TERMINATE THE READ THREAD + if (serial_thread) { + serial_state = STATE_SHUTDOWN; + for (DWORD port = 0; port < PORTS; ++port) + if (serial_port[port]->handle != INVALID_HANDLE_VALUE) + SetEvent(serial_port[port]->overlapped.hEvent); + WaitForSingleObject(serial_thread,INFINITE); + serial_thread = NULL; + } + + // WRITE A FINAL CR/LF TO EVERY PORT WE OPENED, TO PUT ANY MODEMS WE MAY + // HAVE SENT GARBAGE TO DURING THE AUTO-DETECTION PROCESS BACK INTO A + // KNOWN STATE + { + HANDLE event[PORTS]; + OVERLAPPED overlapped[PORTS]; + DWORD byteswritten[PORTS]; + DWORD numsends = 0; + { + for (DWORD port = 0; port < PORTS; ++port) + if (serial_port[port]->handle != INVALID_HANDLE_VALUE) { + ZeroMemory(&overlapped[numsends],sizeof(OVERLAPPED)); + event[numsends] = CreateEvent(NULL,0,0,NULL); + overlapped[numsends].hEvent = event[numsends]; + WriteFile(serial_port[port]->handle, + "\n", + 2, + &byteswritten[numsends], + &overlapped[numsends]); + ++numsends; + PerfIncrement(PERF_PKTSENT); + PerfAdd(PERF_BYTESSENT,2); + } + } + if (numsends) { + WaitForMultipleObjects(numsends,&event[0],1,INFINITE); + while (numsends--) + CloseHandle(event[numsends]); + } + } + + // CLOSE AND FREE ALL PORTS + for (DWORD port = 0; port < PORTS; ++port) { + CloseHandle(serial_event[port]); + if (serial_port[port]->handle != INVALID_HANDLE_VALUE) + CloseHandle(serial_port[port]->handle); + if (serial_port[port]->partialmessage) + FREE(serial_port[port]->partialmessage); + FREE(serial_port[port]); + serial_port[port] = NULL; + } + + // STOP ADVERTISING GAMES + SerialStopAdvertisingGame(); + + // FREE ALL MESSAGES + LISTCLEAR(&serial_messagehead); + + // FREE THE GAME LIST + if (serial_gamelist) { + FREE(serial_gamelist); + serial_gamelist = NULL; + } + + // RESET OUR NETWORK ID + serial_networkid = 0; + serial_networkidlocked = 0; + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialFree (SNETADDRPTR addr, + LPVOID data, + DWORD databytes) { + if (!(addr && data)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + FREE(addr); + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialFreeExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR mesage) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; +} + +//=========================================================================== +BOOL CALLBACK SerialGetGameInfo (DWORD gameid, + LPCSTR gamename, + LPCSTR gamepassword, + SNETSPI_GAMELIST *gameinfo) { + if (gameinfo) + ZeroMemory(gameinfo,sizeof(SNETSPI_GAMELIST)); + if (!(gamename && gameinfo && (gameid || *gamename))) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // IF THE GAME IN THE GAME LIST MATCHES THE QUERY PARAMETERS, RETURN + // ITS INFORMATION + serial_critsect.Enter(); + if (serial_gamelist && + ((!gameid) || (gameid == serial_gamelist->gameid)) && + ((!*gamename) || !_stricmp(gamename,serial_gamelist->gamename))) + CopyMemory(gameinfo,serial_gamelist,sizeof(SNETSPI_GAMELIST)); + serial_critsect.Leave(); + + if (gameinfo->gameid) + return 1; + else { + SetLastError(SNET_ERROR_GAME_NOT_FOUND); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK SerialGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq) { + return PerfGetPerformanceData(counterid, + countervalue, + measurementtime, + measurementfreq); +} + +//=========================================================================== +BOOL CALLBACK SerialInitialize (SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + HANDLE event) { + + // SAVE THE PROGRAM AND VERSION IDS AND THE RECEIVE EVENT HANDLE + serial_programid = programdata->programid; + serial_versionid = programdata->versionid; + serial_maxplayers = min(programdata->maxplayers,MAXPLAYERS); + serial_recvevent = event; + + // RESET PERFORMANCE DATA + PerfReset(); + + // INITIALIZE THE SERIAL PORTS + { + for (DWORD loop = 0; loop < PORTS; ++loop) + if (!InitializePort(loop)) { + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + + // CREATE A THREAD TO PROCESS INCOMING PACKETS + if (!serial_thread) { + unsigned threadid; + serial_thread = (HANDLE)_beginthreadex(NULL, + 0, + ThreadProc, + NULL, + 0, + &threadid); + if (serial_thread) + SetThreadPriority(serial_thread,THREAD_PRIORITY_HIGHEST); + else { + SerialDestroy(); + SetLastError(SNET_ERROR_MAX_THRDS_REACHED); + return 0; + } + } + + // FIND AN UNUSED NETWORK ID + if (!FindNetworkId()) { + SetLastError(SNET_ERROR_TOO_MANY_NAMES); + return 0; + } + + // SEND OUT A QUERY FOR ACTIVE GAMES + SendMessage(SYS_QUERYGAME,0xFF,NULL,0); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialInitializeDevice (DWORD deviceid, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata) { + + // WE NEVER RETURN ANY DEVICES, SO THIS FUNCTION SHOULD NEVER BE CALLED + return 0; +} + +//=========================================================================== +BOOL CALLBACK SerialLockDeviceList (SNETSPI_DEVICELISTPTR *devicelist) { + if (!devicelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + *devicelist = NULL; + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialLockGameList (DWORD categorybits, + DWORD categorymask, + SNETSPI_GAMELISTPTR *gamelist) { + if (!gamelist) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + if (serial_versionmismatch) { + SetLastError(SNET_ERROR_VERSION_MISMATCH); + return 0; + } + serial_critsect.Enter(); + *gamelist = serial_gamelist; + return 1; +} + +//=========================================================================== +/* +BOOL CALLBACK SerialReceive (SNETADDRPTR *addr, + LPVOID *data, + DWORD *databytes) { +*/ +BOOL CALLBACK SerialReceive (LPVOID *data, + DWORD *databytes, + SNETADDRPTR *addr) { + if (addr) + *addr = NULL; + if (data) + *data = NULL; + if (databytes) + *databytes = NULL; + if (!(addr && data && databytes)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + if (serial_messagehead) { + serial_critsect.Enter(); + *addr = &serial_messagehead->addr; + *data = &serial_messagehead->data[0]; + *databytes = serial_messagehead->bytesread-sizeof(PACKETHEADER); + LISTFREEPTR(&serial_messagehead,serial_messagehead); + serial_critsect.Leave(); + return 1; + } + else { + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; + } +} + +//=========================================================================== +BOOL CALLBACK SerialReceiveExternalMessage (LPCSTR *senderpath, + LPCSTR *sendername, + LPCSTR *message) { + if (senderpath) + *senderpath = NULL; + if (sendername) + *sendername = NULL; + if (message) + *message = NULL; + + SetLastError(SNET_ERROR_NO_MESSAGES_WAITING); + return 0; +} + +//=========================================================================== +BOOL CALLBACK SerialSelectGame (DWORD flags, + SNETPROGRAMDATAPTR programdata, + SNETPLAYERDATAPTR playerdata, + SNETUIDATAPTR interfacedata, + SNETVERSIONDATAPTR versiondata, + DWORD *playerid) { + + // IF WE DON'T YET KNOW OF ANY GAMES, WAIT A REASONABLE AMOUNT OF TIME + // FOR ADVERTISEMENTS TO COME IN + if (!serial_gamelist) + Sleep(500); + + // GET THE GAME INFORMATION FROM THE FIRST (AND ONLY) GAME IN THE + // GAME LIST + SNETSPI_GAMELIST gameinfo; + serial_critsect.Enter(); + if (serial_gamelist) + CopyMemory(&gameinfo,serial_gamelist,sizeof(SNETSPI_GAMELIST)); + else + ZeroMemory(&gameinfo,sizeof(SNETSPI_GAMELIST)); + serial_critsect.Leave(); + + // IF THERE IS A COMPATIBLE GAME IN THE GAME LIST, JOIN IT + if (serial_gamelist) + return SNetJoinGame(gameinfo.gameid, + gameinfo.gamename, + NULL, + playerdata->playername, + playerdata->playerdescription, + playerid); + + // OTHERWISE, CALL THE CREATE GAME CALLBACK TO CREATE A NEW ONE + else if (interfacedata && interfacedata->createcallback) { + SNETCREATEDATA createdata; + ZeroMemory(&createdata,sizeof(SNETCREATEDATA)); + createdata.size = sizeof(SNETCREATEDATA); + createdata.providerid = PROVIDERID; + createdata.maxplayers = serial_maxplayers; + createdata.createflags = 0; + return interfacedata->createcallback(&createdata, + programdata, + playerdata, + interfacedata, + versiondata, + playerid); + } + else + return 0; + +} + +//=========================================================================== +BOOL CALLBACK SerialSend (DWORD addresses, + SNETADDRPTR *addrlist, + LPVOID data, + DWORD databytes) { + if (!(addresses && addrlist && data && databytes)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // BUILD A TARGET MASK OUT OF THE LIST OF ADDRESSES + BYTE targetmask = 0; + while (addresses--) + targetmask |= (1 << *(LPBYTE)*(addrlist+addresses)); + + // SEND THE MESSAGE + return SendMessage(SYS_UNUSED,targetmask,data,databytes); +} + +//=========================================================================== +BOOL CALLBACK SerialSendExternalMessage (LPCSTR senderpath, + LPCSTR sendername, + LPCSTR targetpath, + LPCSTR targetname, + LPCSTR message) { + return 0; +} + +//=========================================================================== +BOOL CALLBACK SerialStartAdvertisingGame (LPCSTR gamename, + LPCSTR gamepassword, + LPCSTR gamedescription, + DWORD gamemode, + DWORD gameage, + DWORD gamecategorybits, + DWORD optcategorybits, + LPCVOID clientdata, + DWORD clientdatabytes) { + if (!(gamename && gamedescription)) { + SetLastError(SNET_ERROR_INVALID_PARAMETER); + return 0; + } + + // STOP ADVERTISING ANY GAME WE ARE CURRENTLY ADVERTISING + if (serial_gameadvinfo) + SerialStopAdvertisingGame(); + + // REFUSE TO ADVERTISE A NEW GAME IF ANY OTHER GAME IS BEING + // ADVERTISED ON THIS SERIAL NETWORK + if (serial_gamelist) + if (gamemode & SNET_GM_ADVERTISED) { + FREE(serial_gamelist); + serial_gamelist = NULL; + } + else { + SetLastError(SNET_ERROR_TOO_MANY_NAMES); + return 0; + } + + // CREATE RECORDS TO ADVERTISE THE GAME + serial_gameadvinfo = NEW(ADVREC); + serial_gamelist = NEW(SNETSPI_GAMELIST); + if (serial_gameadvinfo && serial_gamelist) { + ZeroMemory(serial_gameadvinfo,sizeof(ADVREC)); + ZeroMemory(serial_gamelist ,sizeof(SNETSPI_GAMELIST)); + } + else { + if (serial_gameadvinfo) { + FREE(serial_gameadvinfo); + serial_gameadvinfo = NULL; + } + if (serial_gamelist) { + FREE(serial_gamelist); + serial_gamelist = NULL; + } + SetLastError(SNET_ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + // FILL IN THE ADVERTISING INFORMATION + serial_critsect.Enter(); + serial_gameadvinfo->networkid = serial_networkid; + serial_gameadvinfo->programid = serial_programid; + serial_gameadvinfo->versionid = serial_versionid; + strcpy(serial_gameadvinfo->strings,gamename); + strcpy(serial_gameadvinfo->strings+strlen(gamename)+1,gamedescription); + serial_gameadvinfo->bytes = 2*sizeof(DWORD)+strlen(gamename)+strlen(gamedescription)+2; + + // FILL IN THE GAME LIST + serial_gamelist->gameid = 1; + *(LPBYTE)&serial_gamelist->owner = serial_networkid; + strcpy(serial_gamelist->gamename,gamename); + strcpy(serial_gamelist->gamedescription,gamedescription); + serial_critsect.Leave(); + + // SEND OUT THE GAME INFORMATION + SendMessage(SYS_GAMEINFO,0xFF,serial_gameadvinfo,serial_gameadvinfo->bytes); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialStopAdvertisingGame () { + if (!serial_gameadvinfo) { + SetLastError(SNET_ERROR_NOT_OWNER); + return 0; + } + + // STOP ADVERTISING THE GAME + serial_critsect.Enter(); + if (serial_gameadvinfo) { + FREE(serial_gameadvinfo); + serial_gameadvinfo = NULL; + } + if (serial_gamelist) { + FREE(serial_gamelist); + serial_gamelist = NULL; + } + serial_critsect.Leave(); + + // SEND OUT A NEW QUERY + Sleep(500); + SendMessage(SYS_QUERYGAME,0xFF,NULL,0); + + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialUnlockDeviceList (SNETSPI_DEVICELISTPTR devicelist) { + return 1; +} + +//=========================================================================== +BOOL CALLBACK SerialUnlockGameList (SNETSPI_GAMELISTPTR gamelist, + DWORD *hintnextcall) { + serial_critsect.Leave(); + if (hintnextcall) + *hintnextcall = gamelist ? 0 : 500; + return 1; +} + +/**************************************************************************** +* +* EXPORTED STRUCTURES +* +***/ + +DWORD serial_id = PROVIDERID; +LPCSTR serial_desc = "Direct Cable Connection"; +LPCSTR serial_req = "Two or more computers connected together with serial cables and null-modems."; +SNETCAPS serial_caps = {sizeof(SNETCAPS), // size +#ifdef _DEBUG + SNET_CAPS_DEBUGONLY, +#else + SNET_CAPS_RETAILONLY, +#endif + MAXMESSAGESIZE, // max message size + 16, // max queue size, + MAXPLAYERS, // max players, + 1500, // bytes per second + 500, // latency (ms) + 4, // default turns per second + 2}; // default turns in transit +SNETSPI serial_spi = {sizeof(SNETSPI), + SerialCompareNetAddresses, + SerialDestroy, + SerialFree, + SerialFreeExternalMessage, + SerialGetGameInfo, + SerialGetPerformanceData, + SerialInitialize, + SerialInitializeDevice, + SerialLockDeviceList, + SerialLockGameList, + SerialReceive, + SerialReceiveExternalMessage, + SerialSelectGame, + SerialSend, + SerialSendExternalMessage, + SerialStartAdvertisingGame, + SerialStopAdvertisingGame, + SerialUnlockDeviceList, + SerialUnlockGameList}; diff --git a/Storm/SOURCE/STANDARD/STANDARD.CPP b/Storm/SOURCE/STANDARD/STANDARD.CPP new file mode 100644 index 0000000..15fad8c --- /dev/null +++ b/Storm/SOURCE/STANDARD/STANDARD.CPP @@ -0,0 +1,94 @@ +/**************************************************************************** +* +* STANDARD.CPP +* Standard storm network providers +* +* By Michael O'Brien (4/22/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +HINSTANCE global_instance = (HINSTANCE)0; + +//=========================================================================== +extern "C" BOOL APIENTRY SnpQuery (DWORD index, + DWORD *id, + LPCSTR *description, + LPCSTR *requirements, + SNETCAPSPTR *caps) { + if (!(id && description && requirements && caps)) + return 0; + switch (index) { + + case 0: + *id = ipx_id; + *description = ipx_desc; + *requirements = ipx_req; + *caps = &ipx_caps; + return 1; + + case 1: + *id = serial_id; + *description = serial_desc; + *requirements = serial_req; + *caps = &serial_caps; + return 1; + + case 2: + *id = null_id; + *description = null_desc; + *requirements = null_req; + *caps = &null_caps; + return 1; + + case 3: + *id = modem_id; + *description = modem_desc; + *requirements = modem_req; + *caps = &modem_caps; + return 1; + + default: + return 0; + + } +} + +//=========================================================================== +extern "C" BOOL APIENTRY SnpBind (DWORD index, + SNETSPIPTR *spi) { + if (!spi) + return 0; + + switch (index) { + + case 0: + *spi = &ipx_spi; + return 1; + + case 1: + *spi = &serial_spi; + return 1; + + case 2: + *spi = &null_spi; + return 1; + + case 3: + *spi = &modem_spi; + return 1; + + default: + return 0; + + } +} + +//=========================================================================== +extern "C" BOOL APIENTRY DllMain (HINSTANCE passinstance, DWORD reason, LPVOID) { + if (reason == DLL_PROCESS_ATTACH) + global_instance = passinstance; + return 1; +} diff --git a/Storm/SOURCE/STANDARD/STANDARD.CS b/Storm/SOURCE/STANDARD/STANDARD.CS new file mode 100644 index 0000000..7cfdb47 --- /dev/null +++ b/Storm/SOURCE/STANDARD/STANDARD.CS @@ -0,0 +1,18 @@ +#include +#include +set deffile=standard.def +set extralib=wsock32.lib tapi32.lib +set linkopt=%linkopt% -base:0x18000000 + +// DETERMINE THE PROJECT NAME +if %debug% set project=%project%d +set outfile=%project%.snp + +// ADD THE CAPS SIGNATURE TO THE END OF THE FILE +!copy /b %project%.dll+caps.mpq > NUL: + +// RENAME IT TO .SNP AND COPY IT TO THE OUTPUT DIRECTORY +!if exist %outfile% del %outfile% +!rename %project%.dll %outfile% +!copy %outfile% ..\..\bin > NUL: +!if exist *.bak del *.bak diff --git a/Storm/SOURCE/STANDARD/STANDARD.DEF b/Storm/SOURCE/STANDARD/STANDARD.DEF new file mode 100644 index 0000000..e2987e5 --- /dev/null +++ b/Storm/SOURCE/STANDARD/STANDARD.DEF @@ -0,0 +1,3 @@ +EXPORTS +SnpBind +SnpQuery diff --git a/Storm/SOURCE/STANDARD/STANDARD.H b/Storm/SOURCE/STANDARD/STANDARD.H new file mode 100644 index 0000000..16364ff --- /dev/null +++ b/Storm/SOURCE/STANDARD/STANDARD.H @@ -0,0 +1,57 @@ +/**************************************************************************** +* +* GLOBAL VARIABLES +* +***/ + +extern HINSTANCE global_instance; + +/**************************************************************************** +* +* EXPORTED STRUCTURES +* +***/ + +extern DWORD ipx_id; +extern LPCSTR ipx_desc; +extern LPCSTR ipx_req; +extern SNETCAPS ipx_caps; +extern SNETSPI ipx_spi; + +extern DWORD modem_id; +extern LPCSTR modem_desc; +extern LPCSTR modem_req; +extern SNETCAPS modem_caps; +extern SNETSPI modem_spi; + +extern DWORD serial_id; +extern LPCSTR serial_desc; +extern LPCSTR serial_req; +extern SNETCAPS serial_caps; +extern SNETSPI serial_spi; + +extern DWORD null_id; +extern LPCSTR null_desc; +extern LPCSTR null_req; +extern SNETCAPS null_caps; +extern SNETSPI null_spi; + +/**************************************************************************** +* +* COMMON PERFORMANCE MONITORING FUNCTIONS +* +***/ + +#define PERF_PKTSENT 0 +#define PERF_PKTRECV 1 +#define PERF_BYTESSENT 2 +#define PERF_BYTESRECV 3 +#define PERFNUM 4 + +void PerfAdd (DWORD id, DWORD value); +BOOL PerfGetPerformanceData (DWORD counterid, + DWORD *countervalue, + LARGE_INTEGER *measurementtime, + LARGE_INTEGER *measurementfreq); +void PerfIncrement (DWORD id); +void PerfReset (); diff --git a/Storm/SOURCE/STANDARD/STANDARD.RC b/Storm/SOURCE/STANDARD/STANDARD.RC new file mode 100644 index 0000000..fadf8b6 --- /dev/null +++ b/Storm/SOURCE/STANDARD/STANDARD.RC @@ -0,0 +1,271 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IPXSELECTGAME_DIALOG DIALOGEX 0, 0, 256, 203 +STYLE DS_3DLOOK | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman Bold", 0, 0, 0x1 +BEGIN + LTEXT "IPX Games Available",IDC_STATIC,10,62,124,10,0, + WS_EX_TRANSPARENT + LISTBOX IDC_GAMELIST,10,74,124,80,LBS_SORT | LBS_USETABSTOPS | + WS_VSCROLL | WS_TABSTOP + LTEXT "Description:",IDC_STATIC,10,152,124,10,0, + WS_EX_TRANSPARENT + LTEXT "",IDC_GAMEDESCRIPTION,10,162,124,30 + LTEXT "",IDC_PROGRAMDESCRIPTION,10,192,124,9,0, + WS_EX_TRANSPARENT + DEFPUSHBUTTON "&Join Game",IDOK,160,147,90,12,WS_DISABLED + PUSHBUTTON "&Create Game",IDC_CREATEGAME,160,161,90,12 + PUSHBUTTON "&Disconnect",IDCANCEL,160,175,90,12 +END + +TAPI_DEV_DIALOG DIALOGEX 0, 0, 256, 203 +STYLE DS_3DLOOK | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman Bold", 0, 0, 0x1 +BEGIN + LISTBOX IDC_DEVICELIST,8,55,181,83,LBS_SORT | LBS_USETABSTOPS | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "&OK",IDOK,155,163,90,12,WS_DISABLED,WS_EX_TRANSPARENT + PUSHBUTTON "Cancel",IDCANCEL,155,178,90,12,0,WS_EX_TRANSPARENT + LTEXT "Modem Devices Available",IDC_STATIC,8,44,113,8,0, + WS_EX_TRANSPARENT +END + +TAPI_LOC_DIALOG DIALOGEX 0, 0, 256, 203 +STYLE DS_3DLOOK | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman Bold", 0, 0, 0x1 +BEGIN + LISTBOX IDC_LOCLIST,8,55,181,83,LBS_SORT | LBS_USETABSTOPS | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "&OK",IDOK,155,163,90,12,WS_DISABLED,WS_EX_TRANSPARENT + PUSHBUTTON "Cancel",IDCANCEL,155,178,90,12,0,WS_EX_TRANSPARENT + LTEXT "Select Location",IDC_STATIC,8,44,113,8,0, + WS_EX_TRANSPARENT +END + +MODEM_ADDNUM_DIALOG DIALOGEX 0, 0, 256, 203 +STYLE DS_3DLOOK | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman Bold", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_PBNAME,62,35,182,12,ES_AUTOHSCROLL + EDITTEXT IDC_AREACODE,62,87,48,12,ES_AUTOHSCROLL, + WS_EX_TRANSPARENT + EDITTEXT IDC_PBNUMBER,62,113,100,12,ES_AUTOHSCROLL, + WS_EX_TRANSPARENT + DEFPUSHBUTTON "&OK",IDOK,153,158,90,12,WS_DISABLED,WS_EX_TRANSPARENT + PUSHBUTTON "Cancel",IDCANCEL,153,177,90,12,0,WS_EX_TRANSPARENT + RTEXT "Area Code:",IDC_STATIC,6,90,48,8,0,WS_EX_TRANSPARENT + RTEXT "Number:",IDC_STATIC,6,116,48,8,0,WS_EX_TRANSPARENT + RTEXT "Country Code:",IDC_STATIC,6,64,48,8,0,WS_EX_TRANSPARENT + RTEXT "Name:",IDC_STATIC,6,38,48,8,0,WS_EX_TRANSPARENT + LTEXT "",IDC_PBOPERATION,13,16,137,8,0,WS_EX_TRANSPARENT + LTEXT "United States of America",IDC_COUNTRY,62,64,103,8,0, + WS_EX_TRANSPARENT + PUSHBUTTON "Change &Country...",IDC_CHANGECOUNTRY,178,60,66,15 +END + +MODEM_DIALOG DIALOGEX 0, 0, 256, 203 +STYLE DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_BORDER +FONT 13, "Times New Roman Bold" +BEGIN + DEFPUSHBUTTON "&Create Game",IDC_MODEMCREATE,148,139,90,12,WS_DISABLED, + WS_EX_TRANSPARENT + LISTBOX IDC_PHONEBOOK,14,102,121,67,LBS_SORT | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "&Join Game",IDC_MODEMJOIN,148,157,90,12,WS_DISABLED, + WS_EX_TRANSPARENT + PUSHBUTTON "Cancel",IDCANCEL,148,175,90,12 + PUSHBUTTON "Change &Modem...",IDC_CHANGEMODEM,172,26,66,15 + PUSHBUTTON "Change &Location...",IDC_CHANGELOCATION,172,64,66,15 + PUSHBUTTON "&Add...",IDC_PHONEBOOKADD,14,173,34,15 + PUSHBUTTON "&Edit",IDC_PHONEBOOKEDIT,57,173,34,15,WS_DISABLED + PUSHBUTTON "&Remove",IDC_PHONEBOOKREMOVE,100,173,34,15,WS_DISABLED + LTEXT "Current Modem:",IDC_STATIC,14,15,65,8,0, + WS_EX_TRANSPARENT + LTEXT "Current Location:",IDC_STATIC,14,54,65,8,0, + WS_EX_TRANSPARENT + LTEXT "",IDC_CURRENTLOCATION,14,67,151,8,0,WS_EX_TRANSPARENT + LTEXT "",IDC_CURRENTMODEM,14,29,151,8,0,WS_EX_TRANSPARENT + LTEXT "Phonebook Entries",IDC_STATIC,14,88,62,8,0, + WS_EX_TRANSPARENT +END + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + +IDD_DIALOG2 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "MODEM_DIALOG", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 249 + TOPMARGIN, 7 + BOTTOMMARGIN, 196 + END + + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END + + IDD_DIALOG2, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PBADD "Add New Phonebook Entry" + IDS_PBEDIT "Edit Phonebook Entry" + IDS_NODEVICES "No Modem Devices Configured" + IDS_NOLOCATIONS "No Locations Defined" + IDS_DIALING "Dialing number..." + IDS_RINGING "Ringing..." + IDS_CONNECTING "Establishing connection..." + IDS_PROCEEDING "Contacting remote computer..." + IDS_DIALTONE "Dialtone..." +END + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1997,3,29,1 + PRODUCTVERSION 1997,3,29,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Blizzard Entertainment\0" + VALUE "FileDescription", "Standard.snp\0" + VALUE "FileVersion", "1.03\0" + VALUE "InternalName", "Standard.snp\0" + VALUE "LegalCopyright", "Copyright © 1997, Blizzard Entertainment\0" + VALUE "OriginalFilename", "Standard.snp\0" + VALUE "ProductName", "Standard.snp\0" + VALUE "ProductVersion", "1.03\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200, 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SOURCE/STANDARD/Standard.vcxproj b/Storm/SOURCE/STANDARD/Standard.vcxproj new file mode 100644 index 0000000..c8c1659 --- /dev/null +++ b/Storm/SOURCE/STANDARD/Standard.vcxproj @@ -0,0 +1,127 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + 17.0 + Win32Proj + Standard + Standard + 10.0 + {AB148FBE-6646-95E7-67E4-1C1A8173D447} + + + + DynamicLibrary + true + v145 + MultiByte + false + + + DynamicLibrary + false + v143 + true + MultiByte + false + + + + + + + + + + + + + $(ProjectDir)..\..\..\bin\ + $(ProjectDir)$(Configuration)\ + Standard + .snp + true + + + + Level3 + Disabled + WIN32;_WINDOWS;_USRDLL;STANDARD_EXPORTS;_DEBUG;%(PreprocessorDefinitions) + NotUsing + PCH.H + MultiThreadedDebugDLL + + + Windows + true + STANDARD.DEF + $(OutDir)$(TargetName)$(TargetExt) + + + _DEBUG;%(PreprocessorDefinitions) + + + + + Level3 + MaxSpeed + true + true + WIN32;_WINDOWS;_USRDLL;STANDARD_EXPORTS;NDEBUG;%(PreprocessorDefinitions) + Use + PCH.H + MultiThreadedDLL + + + Windows + true + true + true + STANDARD.DEF + $(OutDir)$(TargetName)$(TargetExt) + + + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {43dd7e96-bf0f-4e3b-85f4-1eeafa46583a} + + + + + \ No newline at end of file diff --git a/Storm/SOURCE/STANDARD/Standard.vcxproj.user b/Storm/SOURCE/STANDARD/Standard.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Storm/SOURCE/STANDARD/Standard.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Storm/SOURCE/STANDARD/TRACE.CPP b/Storm/SOURCE/STANDARD/TRACE.CPP new file mode 100644 index 0000000..526a24b --- /dev/null +++ b/Storm/SOURCE/STANDARD/TRACE.CPP @@ -0,0 +1,118 @@ +/**************************************************************************** +* +* TRACE.CPP +* Modem trace functions +* +* Written by Mike O'Brien +* Modified by Jeff Strain (1/9/97) +* +***/ + +#include "pch.h" +#pragma hdrstop +#include "trace.h" + +// DEFAULT DATA FILE FOR ALL TRACE COMMANDS +#define TRACEFILE "c:\\mdmtrace.txt" + +/**************************************************************************** +* +* TRACE FUNCTIONS +* +***/ + +static CCritSect trace_critsect; +static FILE *trace_file = NULL; +static DWORD trace_init = 0; +static DWORD trace_pendcount = 0; +static char trace_pending[256] = ""; + +//=========================================================================== +void TraceBegin (BOOL writepending) { +#ifdef _DEBUG + + // OPEN THE FILE + if (!trace_file) { + trace_file = fopen(TRACEFILE,trace_init ? "at" : "wt"); + if (!trace_file) + return; + else if (!trace_init) + trace_init = GetTickCount(); + } + + // WRITE AND CLEAR ANY PENDING LINES + if (trace_pending[0]) { + if (trace_pendcount > 1) + fprintf(trace_file," [...]\n"); + if (writepending) + fprintf(trace_file,"%s",trace_pending); + trace_pendcount = 0; + trace_pending[0] = 0; + } + +#endif +} + +//=========================================================================== +void TraceDestroy () { +#ifdef _DEBUG + trace_critsect.Enter(); + if (trace_file) { + fclose(trace_file); + trace_file = NULL; + } + trace_critsect.Leave(); +#endif +} + +//=========================================================================== +void TraceDumpAddr (LPCSTR addrname, LPVOID addr, unsigned size) { +#ifdef _DEBUG +#define LINESIZE 80 + char outstr[LINESIZE + 1]; + sprintf(outstr," %s=", addrname); + size = min(size, (LINESIZE - strlen(outstr)) / 2); + for (unsigned loop = 0; loop < size; ++loop) + sprintf(outstr+strlen(outstr),"%02x",(DWORD)*((LPBYTE)addr+loop)); + TraceOut(outstr); +#endif +} + +//=========================================================================== +void __cdecl TraceOut (const char *format, ...) { +#ifdef _DEBUG + trace_critsect.Enter(); + TraceBegin((strlen(format) > 1) && (format[0] == ' ')); + + // WRITE THE LINE + DWORD eventtime = GetTickCount()-trace_init; + fprintf(trace_file,"%4u.%02u ",eventtime/1000,(eventtime % 1000)/10); + va_list arglist; + va_start(arglist,format); + vfprintf(trace_file,format,arglist); + va_end(arglist); + fprintf(trace_file,"\n"); + fflush(trace_file); + + trace_critsect.Leave(); +#endif +} + +//=========================================================================== +void __cdecl TracePend (const char *format, ...) { +#ifdef _DEBUG + trace_critsect.Enter(); + + // SAVE THE LINE + ++trace_pendcount; + DWORD eventtime = GetTickCount()-trace_init; + sprintf(trace_pending,"%4u.%02u ",eventtime/1000,(eventtime % 1000)/10); + va_list arglist; + va_start(arglist,format); + vsprintf(trace_pending+strlen(trace_pending),format,arglist); + va_end(arglist); + strcat(trace_pending,"\n"); + + trace_critsect.Leave(); +#endif +} diff --git a/Storm/SOURCE/STANDARD/TRACE.H b/Storm/SOURCE/STANDARD/TRACE.H new file mode 100644 index 0000000..0936aa9 --- /dev/null +++ b/Storm/SOURCE/STANDARD/TRACE.H @@ -0,0 +1,14 @@ +/**************************************************************************** +* +* TRACE.H +* Modem trace public interface +* +* Written by Jeff Strain (1/9/97) +* +***/ + +void TraceBegin (BOOL writepending); +void TraceDestroy (); +void TraceDumpAddr (LPCSTR addrname, LPVOID addr, unsigned size); +void __cdecl TraceOut (const char *format, ...); +void __cdecl TracePend (const char *format, ...); diff --git a/Storm/SOURCE/STORM.APS b/Storm/SOURCE/STORM.APS new file mode 100644 index 0000000..bed0fad Binary files /dev/null and b/Storm/SOURCE/STORM.APS differ diff --git a/Storm/SOURCE/STORM.CPP b/Storm/SOURCE/STORM.CPP new file mode 100644 index 0000000..4e25098 --- /dev/null +++ b/Storm/SOURCE/STORM.CPP @@ -0,0 +1,92 @@ +/**************************************************************************** +* +* STORM.CPP +* Storm main module +* +* By Michael O'Brien (2/8/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +static HINSTANCE s_instance = (HINSTANCE)0; +static LPTOP_LEVEL_EXCEPTION_FILTER s_oldfilter = NULL; + +LONG CALLBACK ExceptionFilter (EXCEPTION_POINTERS *exceptinfo); + +//=========================================================================== +#ifndef STATICLIB +extern "C" BOOL APIENTRY DllMain (HINSTANCE instance, + DWORD reason, + LPVOID) { + if (reason == DLL_PROCESS_ATTACH) { + s_instance = instance; + s_oldfilter = SetUnhandledExceptionFilter(ExceptionFilter); + } + else if (reason == DLL_PROCESS_DETACH) { + SetUnhandledExceptionFilter(s_oldfilter); + StormDestroy(); + } + return TRUE; +} +#endif + +//=========================================================================== +LONG CALLBACK ExceptionFilter (EXCEPTION_POINTERS *exceptinfo) { + SErrSuppressErrors(TRUE); + SLogFlushAll(); + if (s_oldfilter) + s_oldfilter(exceptinfo); + return EXCEPTION_CONTINUE_SEARCH; +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +#ifndef STATICLIB +BOOL APIENTRY StormDestroy () { + + // DESTROY MODULES WHICH DEPEND ON SDRAW + SDlgDestroy(); + SGdiDestroy(); + SVidDestroy(); + SDrawDestroy(); + + // DESTROY MODULES WHICH DEPEND ON SRGN + SRgnDestroy(); + + // DESTROY MODULES WHICH DEPEND ON SEVT + SMsgDestroy(); + SNetDestroy(); + SEvtDestroy(); + + // DESTROY MODULES WHICH DEPEND ON SCODE + SBltDestroy(); + SCodeDestroy(); + + // DESTROY OTHER HIGH LEVEL MODULES + SCmdDestroy(); + SFileDestroy(); + STransDestroy(); + + // THE MEMORY MANAGER, ERROR HANDLER, AND LOGGING MODULE ARE NOT + // DESTROYED UNTIL AFTER ALL DESTRUCTORS HAVE BEEN CALLED BY THE + // RUNTIME LIBRARY CLEANUP CODE + + return TRUE; +} +#endif + +//=========================================================================== +HINSTANCE StormGetInstance () { +#ifdef STATICLIB + return (HINSTANCE)GetModuleHandle(NULL); +#else + return s_instance; +#endif +} diff --git a/Storm/SOURCE/STORM.CS b/Storm/SOURCE/STORM.CS new file mode 100644 index 0000000..dbc6db5 --- /dev/null +++ b/Storm/SOURCE/STORM.CS @@ -0,0 +1,15 @@ +#include +set crtlib=crtdll.lib +set deffile=exports.def +set extralib=comdlg32.lib implode.lib version.lib +set linkopt=%linkopt% -base:0x15000000 +set .obj=.dll + +// DETERMINE THE PROJECT NAME +if %debug% set project=%project%d + +// COPY THE FILES TO THE OUTPUT DIRECTORIES +!copy %project%.lib ..\lib > NUL: +!copy %project%.dll ..\bin > NUL: +!if exist *.bak del *.bak +!if exist %project%.dll del %project%.dll diff --git a/Storm/SOURCE/STORM.RC b/Storm/SOURCE/STORM.RC new file mode 100644 index 0000000..9151a6e --- /dev/null +++ b/Storm/SOURCE/STORM.RC @@ -0,0 +1,184 @@ +//Microsoft Developer Studio generated resource script. +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.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 ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Message Table +// + +1 MESSAGETABLE MSG00001.bin + +///////////////////////////////////////////////////////////////////////////// +// +// 256 +// + +BLIZZARDKEY 256 MOVEABLE PURE "blizzard.key" +SYSTEMPALETTE 256 MOVEABLE PURE "syspal.pcx" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +SELECTPROVIDER_DIALOG DIALOGEX 0, 0, 256, 203 +STYLE DS_3DLOOK | WS_POPUP | WS_VISIBLE +FONT 13, "Times New Roman", 700, 0, 0x1 +BEGIN + LTEXT "Select Connection Method",IDC_STATIC,10,62,124,10,0, + WS_EX_TRANSPARENT + LISTBOX IDC_PROVIDERLIST,10,74,124,60,LBS_SORT | WS_VSCROLL | + WS_TABSTOP + LTEXT "Players supported: ",IDC_MAXPLAYERS,10,134,124,9 + LTEXT "Requirements: ",IDC_REQUIREMENTS,10,143,124,50 + LTEXT "",IDC_PROGRAMDESCRIPTION,10,192,124,9,0, + WS_EX_TRANSPARENT + DEFPUSHBUTTON "&Connect",IDOK,160,147,90,12 + PUSHBUTTON "&Previous Menu",IDCANCEL,160,161,90,12 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "SELECTPROVIDER_DIALOG", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 250 + TOPMARGIN, 7 + END +END +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +#ifndef STATICLIB +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1997,9,7,1 + PRODUCTVERSION 1997,9,7,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Author", "Mike O'Brien\0" + VALUE "CompanyName", "Blizzard Entertainment\0" + VALUE "FileDescription", "Storm Library\0" + VALUE "FileVersion", "1.05\0" + VALUE "LegalCopyright", "Copyright © 1997, Blizzard Entertainment\0" + VALUE "OriginalFilename", "Storm.dll\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !STATICLIB +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ERROR "ERROR #%u (0x%08x)" + IDS_HEADER "This application has encountered a critical error:\n\n%s\n" + IDS_PROGRAM "Program:\t%s\n" + IDS_FILELINE "File:\t%s\nLine:\t%d\n" + IDS_FUNCTION "Function:\t%s\n" + IDS_OBJECT "Object:\t%s\n" + IDS_HANDLE "Handle:\t%s\n" + IDS_EXPRESSION "Expr:\t%s\n\n" + IDS_DESCRIPTION "\n%s\n\n" + IDS_TERMINATE "Press OK to terminate the application." + IDS_RECOVERABLE "Do you wish to terminate the application?" + IDS_FILE "File:\t%s\n" + IDS_BADARGUMENT "Invalid argument: %s" + IDS_NOTENOUGHARGUMENTS "The syntax of the command is incorrect." + IDS_OPENFAILED "Unable to open response file: %s" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Storm/SOURCE/STORMERR.MC b/Storm/SOURCE/STORMERR.MC new file mode 100644 index 0000000..3de1084 --- /dev/null +++ b/Storm/SOURCE/STORMERR.MC @@ -0,0 +1,678 @@ +FacilityNames=(STORM=0x510 DDERR=0x876 DSERR=0x878) +SeverityNames=(Success=0 Informational=1 Warning=2 Error=3) + +MessageId=0 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_ASSERTION Language=English +ASSERTION! +. + +MessageId=101 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_BAD_ARGUMENT Language=English +STORM_ERROR_BAD_ARGUMENT +. + +MessageId=102 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_GAME_ALREADY_STARTED Language=English +STORM_ERROR_GAME_ALREADY_STARTED +. + +MessageId=103 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_GAME_FULL Language=English +STORM_ERROR_GAME_FULL +. + +MessageId=104 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_GAME_NOT_FOUND Language=English +STORM_ERROR_GAME_NOT_FOUND +. + +MessageId=105 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_GAME_TERMINATED Language=English +STORM_ERROR_GAME_TERMINATED +. + +MessageId=106 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_INVALID_PLAYER Language=English +STORM_ERROR_INVALID_PLAYER +. + +MessageId=107 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NO_MESSAGES_WAITING Language=English +STORM_ERROR_NO_MESSAGES_WAITING +. + +MessageId=108 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_ARCHIVE Language=English +STORM_ERROR_NOT_ARCHIVE +. + +MessageId=109 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_ENOUGH_ARGUMENTS Language=English +STORM_ERROR_NOT_ENOUGH_ARGUMENTS +. + +MessageId=110 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_IMPLEMENTED Language=English +STORM_ERROR_NOT_IMPLEMENTED +. + +MessageId=111 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_IN_ARCHIVE Language=English +STORM_ERROR_NOT_IN_ARCHIVE +. + +MessageId=112 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_IN_GAME Language=English +STORM_ERROR_NOT_IN_GAME +. + +MessageId=113 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_INITIALIZED Language=English +STORM_ERROR_NOT_INITIALIZED +. + +MessageId=114 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_PLAYING Language=English +STORM_ERROR_NOT_PLAYING +. + +MessageId=115 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_NOT_REGISTERED Language=English +STORM_ERROR_NOT_REGISTERED +. + +MessageId=116 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_REQUIRES_CODEC Language=English +STORM_ERROR_REQUIRES_CODEC +. + +MessageId=117 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_REQUIRES_DDRAW Language=English +STORM_ERROR_REQUIRES_CODEC +. + +MessageId=118 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_REQUIRES_DSOUND Language=English +STORM_ERROR_REQUIRES_CODEC +. + +MessageId=119 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_REQUIRES_UPGRADE Language=English +STORM_ERROR_REQUIRES_UPGRADE +. + +MessageId=120 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_STILL_ACTIVE Language=English +STORM_ERROR_STILL_ACTIVE +. + +MessageId=121 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_VERSION_MISMATCH Language=English +STORM_ERROR_VERSION_MISMATCH +. + +MessageId=122 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_MEMORY_ALREADY_FREED Language=English +Attempt to free a memory block which is not currently allocated. +. + +MessageId=123 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_MEMORY_CORRUPT Language=English +This memory block has been corrupted by an out-of-bounds memory write. +. + +MessageId=124 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_MEMORY_INVALID_BLOCK Language=English +Attempt to free an invalid memory block. +. + +MessageId=125 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_MEMORY_MANAGER_INACTIVE Language=English +This function call is invalid because the memory manager is not currently initialized. +. + +MessageId=126 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_MEMORY_NEVER_RELEASED Language=English +A block of memory was allocated but never freed. +. + +MessageId=127 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_HANDLE_NEVER_RELEASED Language=English +A resource handle was obtained but never released. +. + +MessageId=128 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_ACCESS_OUT_OF_BOUNDS Language=English +Attempt to access beyond the bounds of an array. +. + +MessageId=129 Severity=Warning Facility=STORM +SymbolicName=STORM_ERROR_MEMORY_NULL_POINTER Language=English +Attempt to free a NULL pointer. +. + +MessageId=5 Severity=Warning Facility=DDERR +SymbolicName=DDERR_ALREADYINITIALIZED Language=English +DDERR_ALREADYINITIALIZED +. + +MessageId=10 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CANNOTATTACHSURFACE Language=English +DDERR_CANNOTATTACHSURFACE +. + +MessageId=20 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CANNOTDETACHSURFACE Language=English +DDERR_CANNOTDETACHSURFACE +. + +MessageId=40 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CURRENTLYNOTAVAIL Language=English +DDERR_CURRENTLYNOTAVAIL +. + +MessageId=55 Severity=Warning Facility=DDERR +SymbolicName=DDERR_EXCEPTION Language=English +DDERR_EXCEPTION +. + +MessageId=90 Severity=Warning Facility=DDERR +SymbolicName=DDERR_HEIGHTALIGN Language=English +DDERR_HEIGHTALIGN +. + +MessageId=95 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INCOMPATIBLEPRIMARY Language=English +DDERR_INCOMPATIBLEPRIMARY +. + +MessageId=100 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDCAPS Language=English +DDERR_INVALIDCAPS +. + +MessageId=110 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDCLIPLIST Language=English +DDERR_INVALIDCLIPLIST +. + +MessageId=120 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDMODE Language=English +DDERR_INVALIDMODE +. + +MessageId=130 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDOBJECT Language=English +DDERR_INVALIDOBJECT +. + +MessageId=145 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDPIXELFORMAT Language=English +DDERR_INVALIDPIXELFORMAT +. + +MessageId=150 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDRECT Language=English +DDERR_INVALIDRECT +. + +MessageId=160 Severity=Warning Facility=DDERR +SymbolicName=DDERR_LOCKEDSURFACES Language=English +DDERR_LOCKEDSURFACES +. + +MessageId=170 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NO3D Language=English +DDERR_NO3D +. + +MessageId=180 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOALPHAHW Language=English +DDERR_NOALPHAHW +. + +MessageId=205 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOCLIPLIST Language=English +DDERR_NOCLIPLIST +. + +MessageId=210 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOCOLORCONVHW Language=English +DDERR_NOCOLORCONVHW +. + +MessageId=212 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOCOOPERATIVELEVELSET Language=English +DDERR_NOCOOPERATIVELEVELSET +. + +MessageId=215 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOCOLORKEY Language=English +DDERR_NOCOLORKEY +. + +MessageId=220 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOCOLORKEYHW Language=English +DDERR_NOCOLORKEYHW +. + +MessageId=222 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NODIRECTDRAWSUPPORT Language=English +DDERR_NODIRECTDRAWSUPPORT +. + +MessageId=225 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOEXCLUSIVEMODE Language=English +DDERR_NOEXCLUSIVEMODE +. + +MessageId=230 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOFLIPHW Language=English +DDERR_NOFLIPHW +. + +MessageId=240 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOGDI Language=English +DDERR_NOGDI +. + +MessageId=250 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOMIRRORHW Language=English +DDERR_NOMIRRORHW +. + +MessageId=255 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOTFOUND Language=English +DDERR_NOTFOUND +. + +MessageId=260 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOOVERLAYHW Language=English +DDERR_NOOVERLAYHW +. + +MessageId=280 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NORASTEROPHW Language=English +DDERR_NORASTEROPHW +. + +MessageId=290 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOROTATIONHW Language=English +DDERR_NOROTATIONHW +. + +MessageId=310 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOSTRETCHHW Language=English +DDERR_NOSTRETCHHW +. + +MessageId=316 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOT4BITCOLOR Language=English +DDERR_NOT4BITCOLOR +. + +MessageId=317 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOT4BITCOLORINDEX Language=English +DDERR_NOT4BITCOLORINDEX +. + +MessageId=320 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOT8BITCOLOR Language=English +DDERR_NOT8BITCOLOR +. + +MessageId=330 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOTEXTUREHW Language=English +DDERR_NOTEXTUREHW +. + +MessageId=335 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOVSYNCHW Language=English +DDERR_NOVSYNCHW +. + +MessageId=340 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOZBUFFERHW Language=English +DDERR_NOZBUFFERHW +. + +MessageId=350 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOZOVERLAYHW Language=English +DDERR_NOZOVERLAYHW +. + +MessageId=360 Severity=Warning Facility=DDERR +SymbolicName=DDERR_OUTOFCAPS Language=English +DDERR_OUTOFCAPS +. + +MessageId=380 Severity=Warning Facility=DDERR +SymbolicName=DDERR_OUTOFVIDEOMEMORY Language=English +DDERR_OUTOFVIDEOMEMORY +. + +MessageId=382 Severity=Warning Facility=DDERR +SymbolicName=DDERR_OVERLAYCANTCLIP Language=English +DDERR_OVERLAYCANTCLIP +. + +MessageId=384 Severity=Warning Facility=DDERR +SymbolicName=DDERR_OVERLAYCOLORKEYONLYONEACTIVE Language=English +DDERR_OVERLAYCOLORKEYONLYONEACTIVE +. + +MessageId=387 Severity=Warning Facility=DDERR +SymbolicName=DDERR_PALETTEBUSY Language=English +DDERR_PALETTEBUSY +. + +MessageId=400 Severity=Warning Facility=DDERR +SymbolicName=DDERR_COLORKEYNOTSET Language=English +DDERR_COLORKEYNOTSET +. + +MessageId=410 Severity=Warning Facility=DDERR +SymbolicName=DDERR_SURFACEALREADYATTACHED Language=English +DDERR_SURFACEALREADYATTACHED +. + +MessageId=420 Severity=Warning Facility=DDERR +SymbolicName=DDERR_SURFACEALREADYDEPENDENT Language=English +DDERR_SURFACEALREADYDEPENDENT +. + +MessageId=430 Severity=Warning Facility=DDERR +SymbolicName=DDERR_SURFACEBUSY Language=English +DDERR_SURFACEBUSY +. + +MessageId=435 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CANTLOCKSURFACE Language=English +DDERR_CANTLOCKSURFACE +. + +MessageId=440 Severity=Warning Facility=DDERR +SymbolicName=DDERR_SURFACEISOBSCURED Language=English +DDERR_SURFACEISOBSCURED +. + +MessageId=450 Severity=Warning Facility=DDERR +SymbolicName=DDERR_SURFACELOST Language=English +DDERR_SURFACELOST +. + +MessageId=460 Severity=Warning Facility=DDERR +SymbolicName=DDERR_SURFACENOTATTACHED Language=English +DDERR_SURFACENOTATTACHED +. + +MessageId=470 Severity=Warning Facility=DDERR +SymbolicName=DDERR_TOOBIGHEIGHT Language=English +DDERR_TOOBIGHEIGHT +. + +MessageId=480 Severity=Warning Facility=DDERR +SymbolicName=DDERR_TOOBIGSIZE Language=English +DDERR_TOOBIGSIZE +. + +MessageId=490 Severity=Warning Facility=DDERR +SymbolicName=DDERR_TOOBIGWIDTH Language=English +DDERR_TOOBIGWIDTH +. + +MessageId=510 Severity=Warning Facility=DDERR +SymbolicName=DDERR_UNSUPPORTEDFORMAT Language=English +DDERR_UNSUPPORTEDFORMAT +. + +MessageId=520 Severity=Warning Facility=DDERR +SymbolicName=DDERR_UNSUPPORTEDMASK Language=English +DDERR_UNSUPPORTEDMASK +. + +MessageId=537 Severity=Warning Facility=DDERR +SymbolicName=DDERR_VERTICALBLANKINPROGRESS Language=English +DDERR_VERTICALBLANKINPROGRESS +. + +MessageId=540 Severity=Warning Facility=DDERR +SymbolicName=DDERR_WASSTILLDRAWING Language=English +DDERR_WASSTILLDRAWING +. + +MessageId=560 Severity=Warning Facility=DDERR +SymbolicName=DDERR_XALIGN Language=English +DDERR_XALIGN +. + +MessageId=561 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDDIRECTDRAWGUID Language=English +DDERR_INVALIDDIRECTDRAWGUID +. + +MessageId=562 Severity=Warning Facility=DDERR +SymbolicName=DDERR_DIRECTDRAWALREADYCREATED Language=English +DDERR_DIRECTDRAWALREADYCREATED +. + +MessageId=563 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NODIRECTDRAWHW Language=English +DDERR_NODIRECTDRAWHW +. + +MessageId=564 Severity=Warning Facility=DDERR +SymbolicName=DDERR_PRIMARYSURFACEALREADYEXISTS Language=English +DDERR_PRIMARYSURFACEALREADYEXISTS +. + +MessageId=565 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOEMULATION Language=English +DDERR_NOEMULATION +. + +MessageId=566 Severity=Warning Facility=DDERR +SymbolicName=DDERR_REGIONTOOSMALL Language=English +DDERR_REGIONTOOSMALL +. + +MessageId=567 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CLIPPERISUSINGHWND Language=English +DDERR_CLIPPERISUSINGHWND +. + +MessageId=568 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOCLIPPERATTACHED Language=English +DDERR_NOCLIPPERATTACHED +. + +MessageId=569 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOHWND Language=English +DDERR_NOHWND +. + +MessageId=570 Severity=Warning Facility=DDERR +SymbolicName=DDERR_HWNDSUBCLASSED Language=English +DDERR_HWNDSUBCLASSED +. + +MessageId=571 Severity=Warning Facility=DDERR +SymbolicName=DDERR_HWNDALREADYSET Language=English +DDERR_HWNDALREADYSET +. + +MessageId=572 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOPALETTEATTACHED Language=English +DDERR_NOPALETTEATTACHED +. + +MessageId=573 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOPALETTEHW Language=English +DDERR_NOPALETTEHW +. + +MessageId=574 Severity=Warning Facility=DDERR +SymbolicName=DDERR_BLTFASTCANTCLIP Language=English +DDERR_BLTFASTCANTCLIP +. + +MessageId=575 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOBLTHW Language=English +DDERR_NOBLTHW +. + +MessageId=576 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NODDROPSHW Language=English +DDERR_NODDROPSHW +. + +MessageId=577 Severity=Warning Facility=DDERR +SymbolicName=DDERR_OVERLAYNOTVISIBLE Language=English +DDERR_OVERLAYNOTVISIBLE +. + +MessageId=578 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOOVERLAYDEST Language=English +DDERR_NOOVERLAYDEST +. + +MessageId=579 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDPOSITION Language=English +DDERR_INVALIDPOSITION +. + +MessageId=580 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOTAOVERLAYSURFACE Language=English +DDERR_NOTAOVERLAYSURFACE +. + +MessageId=581 Severity=Warning Facility=DDERR +SymbolicName=DDERR_EXCLUSIVEMODEALREADYSET Language=English +DDERR_EXCLUSIVEMODEALREADYSET +. + +MessageId=582 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOTFLIPPABLE Language=English +DDERR_NOTFLIPPABLE +. + +MessageId=583 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CANTDUPLICATE Language=English +DDERR_CANTDUPLICATE +. + +MessageId=584 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOTLOCKED Language=English +DDERR_NOTLOCKED +. + +MessageId=585 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CANTCREATEDC Language=English +DDERR_CANTCREATEDC +. + +MessageId=586 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NODC Language=English +DDERR_NODC +. + +MessageId=587 Severity=Warning Facility=DDERR +SymbolicName=DDERR_WRONGMODE Language=English +DDERR_WRONGMODE +. + +MessageId=588 Severity=Warning Facility=DDERR +SymbolicName=DDERR_IMPLICITLYCREATED Language=English +DDERR_IMPLICITLYCREATED +. + +MessageId=589 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOTPALETTIZED Language=English +DDERR_NOTPALETTIZED +. + +MessageId=590 Severity=Warning Facility=DDERR +SymbolicName=DDERR_UNSUPPORTEDMODE Language=English +DDERR_UNSUPPORTEDMODE +. + +MessageId=591 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOMIPMAPHW Language=English +DDERR_NOMIPMAPHW +. + +MessageId=592 Severity=Warning Facility=DDERR +SymbolicName=DDERR_INVALIDSURFACETYPE Language=English +DDERR_INVALIDSURFACETYPE +. + +MessageId=620 Severity=Warning Facility=DDERR +SymbolicName=DDERR_DCALREADYCREATED Language=English +DDERR_DCALREADYCREATED +. + +MessageId=640 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CANTPAGELOCK Language=English +DDERR_CANTPAGELOCK +. + +MessageId=660 Severity=Warning Facility=DDERR +SymbolicName=DDERR_CANTPAGEUNLOCK Language=English +DDERR_CANTPAGEUNLOCK +. + +MessageId=680 Severity=Warning Facility=DDERR +SymbolicName=DDERR_NOTPAGELOCKED Language=English +DDERR_NOTPAGELOCKED +. + +MessageId=10 Severity=Warning Facility=DSERR +SymbolicName=DSERR_ALLOCATED Language=English +DSERR_ALLOCATED +. + +MessageId=30 Severity=Warning Facility=DSERR +SymbolicName=DSERR_CONTROLUNAVAIL Language=English +DSERR_CONTROLUNAVAIL +. + +MessageId=50 Severity=Warning Facility=DSERR +SymbolicName=DSERR_INVALIDCALL Language=English +DSERR_INVALIDCALL +. + +MessageId=70 Severity=Warning Facility=DSERR +SymbolicName=DSERR_PRIOLEVELNEEDED Language=English +DSERR_PRIOLEVELNEEDED +. + +MessageId=100 Severity=Warning Facility=DSERR +SymbolicName=DSERR_BADFORMAT Language=English +DSERR_BADFORMAT +. + +MessageId=120 Severity=Warning Facility=DSERR +SymbolicName=DSERR_NODRIVER Language=English +DSERR_NODRIVER +. + +MessageId=130 Severity=Warning Facility=DSERR +SymbolicName=DSERR_ALREADYINITIALIZED Language=English +DSERR_ALREADYINITIALIZED +. + +MessageId=150 Severity=Warning Facility=DSERR +SymbolicName=DSERR_BUFFERLOST Language=English +DSERR_BUFFERLOST +. + +MessageId=160 Severity=Warning Facility=DSERR +SymbolicName=DSERR_OTHERAPPHASPRIO Language=English +DSERR_OTHERAPPHASPRIO +. + +MessageId=170 Severity=Warning Facility=DSERR +SymbolicName=DSERR_UNINITIALIZED Language=English +DSERR_UNINITIALIZED +. + diff --git a/Storm/SOURCE/STORMST.CS b/Storm/SOURCE/STORMST.CS new file mode 100644 index 0000000..bde95a3 --- /dev/null +++ b/Storm/SOURCE/STORMST.CS @@ -0,0 +1,11 @@ +#include +if %debug% set clopt=-DSTATICLIB -D_DEBUG -Zi +if not %debug% set clopt=-DSTATICLIB -DNDEBUG -O1 -GBFry +set extralib=implode.lib +set .def= +set .obj=.lib +!copy %project%.lib ..\lib > NUL: +!copy storm.res ..\lib\stormst.res > NUL: +!if exist *.bak del *.bak +!if exist *.res del *.res +!if exist %project%.lib del %project%.lib \ No newline at end of file diff --git a/Storm/SOURCE/STRANS.CPP b/Storm/SOURCE/STRANS.CPP new file mode 100644 index 0000000..4c4710a --- /dev/null +++ b/Storm/SOURCE/STRANS.CPP @@ -0,0 +1,1350 @@ +/**************************************************************************** +* +* STRANS.CPP +* Storm transparency functions +* +* By Michael O'Brien (6/19/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define COPY 0 +#define SKIP 1 +#define MAXSPANLENGTH 0xFC + +typedef struct _BUFFER { + LPBYTE data; + DWORD bytesalloc; + DWORD bytesused; + DWORD chunksize; +} BUFFER, *BUFFERPTR; + +typedef union _INSTPTR { + LPBYTE byteptr; + LPWORD wordptr; +} INSTPTR; + +typedef union _SPANPAIR { + BYTE span[2]; + WORD pair; +} SPANPAIR; + +NODEDECL(TRANS) { + LPBYTE data; + DWORD dataalloc; + DWORD databytes; + DWORD instructionoffset; + int width; + int height; + RECT boundrect; +} *TRANSPTR; + +static LPDWORD s_dirtyoffset = NULL; +static SIZE s_dirtysize = {40,30}; +static int s_dirtyxshift = 4; +static int s_dirtyxsize = 16; +static int s_dirtyyshift = 4; +static int s_dirtyysize = 16; +static LPBYTE s_savedata = NULL; +static int s_savedataalloc = 0; +static LIST(TRANS) s_translist; + +//=========================================================================== +static inline void BufferCreate (BUFFERPTR buffer) { + buffer->chunksize = 4096; + buffer->bytesused = 0; + if (s_savedata) { + buffer->data = s_savedata; + buffer->bytesalloc = s_savedataalloc; + s_savedata = NULL; + s_savedataalloc = 0; + } + else { + buffer->bytesalloc = 4096; + buffer->data = (LPBYTE)ALLOC(buffer->bytesalloc); + } +} + +//=========================================================================== +static inline void BufferReserve (BUFFERPTR buffer, + DWORD bytes, + LPBYTE *adjptr1, + LPBYTE *adjptr2) { + DWORD newalloc = buffer->bytesalloc; + while ((buffer->bytesused+bytes) > newalloc) + newalloc += buffer->chunksize; + if (newalloc != buffer->bytesalloc) { + LPBYTE newdata = (LPBYTE)ALLOC(newalloc); + CopyMemory(newdata,buffer->data,buffer->bytesused); + FREE(buffer->data); + if (adjptr1 && *adjptr1) + *adjptr1 = newdata+((*adjptr1)-buffer->data); + if (adjptr2 && *adjptr2) + *adjptr2 = newdata+((*adjptr2)-buffer->data); + buffer->bytesalloc = newalloc; + buffer->data = newdata; + } +} + +//=========================================================================== +static void ConvertBitmapToTransparency (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + LPRECT boundrect, + BYTE colorkey, + BOOL maskonly, + LPBYTE data, + DWORD *databytes, + DWORD *instructionoffset) { + DWORD size = 0; + + // DETERMINE THE SOURCE BITMAP LOCATION AND EXTENTS + LPBYTE start = bits+(rect ? rect->top*width+rect->left : 0); + int cx = rect ? rect->right-rect->left : width; + int cy = rect ? rect->bottom-rect->top : height; + int adjust = width-cx; + + // INITIALIZE THE BOUNDING RECTANGLE + boundrect->left = INT_MAX; + boundrect->top = INT_MAX; + boundrect->right = 0; + boundrect->bottom = 0; + + // STORE ALL OF THE NON-TRANSPARENT BITMAP BITS IN THE BUFFER + if (!maskonly) { + LPBYTE source = start; + for (int y = 0; y < cy; ++y) { + BOOL found = 0; + for (int x = 0; x < cx; ++x) { + if (*source != colorkey) { + ++size; + if (data) + *(data++) = *source; + if (x < boundrect->left) + boundrect->left = x; + if (x >= boundrect->right) + boundrect->right = x+1; + found = 1; + } + ++source; + } + if (found) { + if (y < boundrect->top) + boundrect->top = y; + if (y >= boundrect->bottom) + boundrect->bottom = y+1; + } + source += adjust; + } + } + if (boundrect->left > boundrect->right) + boundrect->left = boundrect->right; + if (boundrect->top > boundrect->bottom) + boundrect->top = boundrect->bottom; + + // SAVE THE OFFSET TO THE INSTRUCTION STREAM + if (size & 3) { + if (data) + data += 4-(size & 3); + size += 4-(size & 3); + } + if (instructionoffset) + *instructionoffset = size; + + // CREATE THE INSTRUCTION STREAM. EACH INSTRUCTION CONSISTS OF A BYTE + // SPECIFYING THE NUMBER OF BYTES TO COPY, FOLLOWED BY A BYTE SPECIFYING + // THE NUMBER OF BYTES TO SKIP. A PAIR OF ZEROES IS USED TO INDICATE THE + // END OF THE CURRENT SCAN LINE. + { + LPBYTE source = start; + int y = cy; + while (y--) { + BYTE copybytes = 0; + BYTE skipbytes = 0; + BOOL copymode = TRUE; + int x = cx; + while (x--) { + BOOL output = FALSE; + if ((*(source++) != colorkey) == copymode) + if (copymode) + ++copybytes; + else + ++skipbytes; + else + if (copymode) { + copymode = FALSE; + ++skipbytes; + } + else { + output = TRUE; + --source; + ++x; + } + if (output || + (copybytes == MAXSPANLENGTH) || + (skipbytes == MAXSPANLENGTH) || + !x) { + size += 2; + if (data) { + *(data++) = copybytes; + *(data++) = skipbytes; + } + copybytes = 0; + skipbytes = 0; + copymode = TRUE; + } + } + size += 2; + if (data) { + *(data++) = 0; + *(data++) = 0; + } + source += adjust; + } + } + + // RETURN THE NUMBER OF BYTES WRITTEN + if (databytes) + *databytes = size; +} + +//=========================================================================== +static DWORD ConvertColorRefToColorData (COLORREF colorref, int bitdepth) { + if (colorref & 0x01000000) + return (colorref & 0x00FFFFFF); + + return 0; +} + +//=========================================================================== +static TRANSPTR CreateTransparencyRecord (TRANSPTR baseptr) { + TRANSPTR transptr = s_translist.NewNode(); + if (baseptr) { + transptr->dataalloc = baseptr->dataalloc; + transptr->databytes = baseptr->databytes; + transptr->instructionoffset = baseptr->instructionoffset; + transptr->width = baseptr->width; + transptr->height = baseptr->height; + transptr->boundrect = baseptr->boundrect; + } + return transptr; +} + +//=========================================================================== +static BOOL DetermineShift (int value, int *shift) { + int bits = 0; + int curr = 1; + while (curr < value) { + ++bits; + curr <<= 1; + } + *shift = bits; + return (curr == value); +} + +//=========================================================================== +static BOOL InternalCreateTransparency (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + BOOL maskonly, + HSTRANS *handle) { + + // STORM CURRENTLY ONLY SUPPORTS 256-COLOR MODE, SO FOR THE TIME BEING, + // REJECT ALL BIT DEPTHS EXCEPT 8BPP + if (bitdepth != 8) + return FALSE; + BYTE paletteindex = (BYTE)ConvertColorRefToColorData(colorkey,bitdepth); + + // DETERMINE THE SIZE OF THE TRANSPARENCY DATA + DWORD transbytes = 0; + DWORD instructionoffset = 0; + RECT boundrect; + ConvertBitmapToTransparency(bits,width,height,bitdepth,rect,&boundrect,paletteindex, + maskonly,NULL,&transbytes,&instructionoffset); + + // ALLOCATE MEMORY FOR THE TRANSPARENCY DATA + LPBYTE transdata = (LPBYTE)ALLOC(transbytes); + + // GENERATE THE TRANSPARENCY DATA + ConvertBitmapToTransparency(bits,width,height,bitdepth,rect,&boundrect,paletteindex, + maskonly,transdata,NULL,NULL); + + // CREATE A RECORD FOR THE TRANSPARENCY + TRANSPTR newptr = CreateTransparencyRecord(NULL); + CopyMemory(&newptr->boundrect,&boundrect,sizeof(RECT)); + newptr->data = transdata; + newptr->dataalloc = transbytes; + newptr->databytes = transbytes; + newptr->instructionoffset = instructionoffset; + newptr->width = rect ? rect->right-rect->left : width; + newptr->height = rect ? rect->bottom-rect->top : height; + + // RETURN A HANDLE TO THE TRANSPARENCY + *handle = (HSTRANS)newptr; + + return TRUE; +} + +//=========================================================================== +static void inline InternalDrawTransparency (TRANSPTR trans, + LPBYTE dest, + int destadjust) { + LPBYTE sourcedata = trans->data; + LPBYTE sourceinst = trans->data+trans->instructionoffset; + int cy = trans->height; +#ifdef _X86_ + __asm { + + // SETUP REGISTERS + mov edx,[cy] + mov ebx,[sourceinst] + mov esi,[sourcedata] + mov edi,[dest] + xor eax,eax + xor ecx,ecx + test edx,edx + jz dt_done + jmp dt_nextinst + + // PERFORM THE COPY + dt_copy: cmp al,3 + jbe dt_done4 + + // IF NECESSARY, MOVE A SINGLE BYTE TO WORD-ALIGN THE + // DESTINATION + test edi,1 + jz dt_aligned2 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec al + dt_aligned2: + + // IF NECESSARY, MOVE A SINGLE WORD TO DWORD-ALIGN THE + // DESTINATION + test edi,2 + jz dt_aligned4 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + sub al,2 + dt_aligned4: + + // MOVE AS MANY ALIGNED DWORDS AS POSSIBLE + mov ecx,eax + and ecx,0FCh + shr ecx,2 + rep movsd + dt_done4: + + // MOVE ONE MORE WORD IF NECESSARY + test al,2 + jz dt_done2 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + dt_done2: + + // MOVE ONE MORE BYTE IF NECESSARY + test al,1 + jz dt_done1 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dt_done1: + + // PERFORM THE SKIP + xor ecx,ecx + mov cl,ah + add edi,ecx + + // LOAD IN THE NEXT SET OF COPY/SKIP LENGTHS + dt_nextinst: xor eax,eax + mov ax,[ebx] + add ebx,2 + test eax,eax + jnz dt_copy + + // IF THIS LINE IS COMPLETE, MOVE TO THE NEXT LINE + add edi,[destadjust] + dec edx + jnz dt_nextinst + + dt_done: + } +#else + + // DRAW EACH LINE AS DEFINED IN THE INSTRUCTION STREAM + while (cy--) { + BYTE copybytes = *(sourceinst++); + BYTE skipbytes = *(sourceinst++); + while (copybytes || skipbytes) { + + // IF WE ARE COPYING AT LEAST SEVEN BYTES, ARRANGE THE BLT SO WE CAN + // DO AS MANY ALIGNED DWORD MOVES AS POSSIBLE + if (copybytes >= 7) { + while ((DWORD)dest & 3) { + *(dest++) = *(sourcedata++); + --copybytes; + } + while (copybytes >= 4) { + *(LPDWORD)dest = *(LPDWORD)sourcedata; + dest += 4; + sourcedata += 4; + copybytes -= 4; + } + } + + // OTHERWISE, JUST DO BYTE MOVES + while (copybytes) { + *(dest++) = *(sourcedata++); + --copybytes; + } + + // SKIP PAST THE NEXT TRANSPARENCY SPAN + dest += skipbytes; + + // LOAD IN THE NEXT SPAN DATA + copybytes = *(sourceinst++); + skipbytes = *(sourceinst++); + + } + dest += destadjust; + } + +#endif +} + +//=========================================================================== +static void inline InternalDrawTransparencyFromSource (TRANSPTR trans, + LPBYTE dest, + LPBYTE source, + int destadjust, + int sourceadjust) { + LPBYTE sourceinst = trans->data+trans->instructionoffset; + int cy = trans->height; +#ifdef _X86_ + __asm { + + // SETUP REGISTERS + mov edx,[cy] + mov ebx,[sourceinst] + mov esi,[source] + mov edi,[dest] + xor eax,eax + xor ecx,ecx + test edx,edx + jz dt_done + jmp dt_nextinst + + // PERFORM THE COPY + dt_copy: cmp al,3 + jbe dt_done4 + + // IF NECESSARY, MOVE A SINGLE BYTE TO WORD-ALIGN THE + // DESTINATION + test edi,1 + jz dt_aligned2 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec al + dt_aligned2: + + // IF NECESSARY, MOVE A SINGLE WORD TO DWORD-ALIGN THE + // DESTINATION + test edi,2 + jz dt_aligned4 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + sub al,2 + dt_aligned4: + + // MOVE AS MANY ALIGNED DWORDS AS POSSIBLE + mov ecx,eax + and ecx,0FCh + shr ecx,2 + rep movsd + dt_done4: + + // MOVE ONE MORE WORD IF NECESSARY + test al,2 + jz dt_done2 + mov cx,[esi] + add esi,2 + mov [edi],cx + add edi,2 + dt_done2: + + // MOVE ONE MORE BYTE IF NECESSARY + test al,1 + jz dt_done1 + mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dt_done1: + + // PERFORM THE SKIP + xor ecx,ecx + mov cl,ah + add esi,ecx + add edi,ecx + + // LOAD IN THE NEXT SET OF COPY/SKIP LENGTHS + dt_nextinst: xor eax,eax + mov ax,[ebx] + add ebx,2 + test eax,eax + jnz dt_copy + + // IF THIS LINE IS COMPLETE, MOVE TO THE NEXT LINE + add edi,[destadjust] + add esi,[sourceadjust] + dec edx + jnz dt_nextinst + + dt_done: + } +#else + + // DRAW EACH LINE AS DEFINED IN THE INSTRUCTION STREAM + while (cy--) { + BYTE copybytes = *(sourceinst++); + BYTE skipbytes = *(sourceinst++); + while (copybytes || skipbytes) { + + // IF WE ARE COPYING AT LEAST SEVEN BYTES, ARRANGE THE BLT SO WE CAN + // DO AS MANY ALIGNED DWORD MOVES AS POSSIBLE + if (copybytes >= 7) { + while ((DWORD)dest & 3) { + *(dest++) = *(source++); + --copybytes; + } + while (copybytes >= 4) { + *(LPDWORD)dest = *(LPDWORD)source; + dest += 4; + source += 4; + copybytes -= 4; + } + } + + // OTHERWISE, JUST DO BYTE MOVES + while (copybytes) { + *(dest++) = *(source++); + --copybytes; + } + + // SKIP PAST THE NEXT TRANSPARENCY SPAN + dest += skipbytes; + source += skipbytes; + + // LOAD IN THE NEXT SPAN DATA + copybytes = *(sourceinst++); + skipbytes = *(sourceinst++); + + } + dest += destadjust; + source += sourceadjust; + } + +#endif +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY STransBlt (LPBYTE dest, + int destx, + int desty, + int destpitch, + HSTRANS transparency) { + // to minimize function call overhead for this time critical function, + // we use assert instead of validate so that the retail version has + // no parameter checking code + ASSERT(dest); + ASSERT(destpitch > 0); + ASSERT(transparency); + + TRANSPTR transptr = (TRANSPTR)transparency; + ASSERT(transptr->instructionoffset); + + // COMPUTE THE DESTINATION X ADJUSTMENT FOR EACH SCAN LINE + int xadjust = destpitch-transptr->width; + + // DRAW THE TRANSPARENCY + InternalDrawTransparency(transptr, + dest+(desty*destpitch)+destx, + xadjust); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransBltUsingMask (LPBYTE dest, + LPBYTE source, + int destpitch, + int sourcepitch, + HSTRANS mask) { + // to minimize function call overhead for this time critical function, + // we use assert instead of validate so that the retail version has + // no parameter checking code + ASSERT(dest); + ASSERT(source); + ASSERT(destpitch > 0); + ASSERT(mask); + + TRANSPTR transptr = (TRANSPTR)mask; + + // COMPUTE THE X ADJUSTMENTS FOR EACH SCAN LINE + int destadjust = destpitch-transptr->width; + int sourceadjust = sourcepitch ? sourcepitch-transptr->width : 0; + + // DRAW USING THE TRANSPARENCY MASK + InternalDrawTransparencyFromSource(transptr, + dest, + source, + destadjust, + sourceadjust); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransCreateE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle) { + if (handle) + *handle = (HSTRANS)0; + + VALIDATEBEGIN; + VALIDATE(bits); + VALIDATE(width); + VALIDATE(height); + VALIDATE(handle); + VALIDATEEND; + + return InternalCreateTransparency(bits, + width, + height, + bitdepth, + rect, + colorkey, + FALSE, + handle); +} + +//=========================================================================== +BOOL APIENTRY STransCreateI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle) { + RECT exclrect; + LPRECT exclrectptr = rect; + if (rect) { + exclrect.left = rect->left; + exclrect.top = rect->top; + exclrect.right = rect->right+1; + exclrect.bottom = rect->bottom+1; + exclrectptr = &exclrect; + } + return STransCreateE(bits, + width, + height, + bitdepth, + exclrectptr, + colorkey, + handle); +} + +//=========================================================================== +BOOL APIENTRY STransCreateMaskE (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle) { + if (handle) + *handle = (HSTRANS)0; + + VALIDATEBEGIN; + VALIDATE(bits); + VALIDATE(width); + VALIDATE(height); + VALIDATE(handle); + VALIDATEEND; + + return InternalCreateTransparency(bits, + width, + height, + bitdepth, + rect, + colorkey, + TRUE, + handle); +} + +//=========================================================================== +BOOL APIENTRY STransCreateMaskI (LPBYTE bits, + int width, + int height, + int bitdepth, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle) { + RECT exclrect; + LPRECT exclrectptr = rect; + if (rect) { + exclrect.left = rect->left; + exclrect.top = rect->top; + exclrect.right = rect->right+1; + exclrect.bottom = rect->bottom+1; + exclrectptr = &exclrect; + } + return STransCreateMaskI(bits, + width, + height, + bitdepth, + exclrectptr, + colorkey, + handle); +} + +//=========================================================================== +BOOL APIENTRY STransDelete (HSTRANS handle) { + TRANSPTR transptr = (TRANSPTR)handle; + if (transptr->data) { + if (s_savedata) + FREE(s_savedata); + s_savedata = transptr->data; + s_savedataalloc = transptr->dataalloc; + transptr->data = NULL; + transptr->dataalloc = 0; + } + s_translist.DeleteNode(transptr); + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransDestroy () { + TRANSPTR curr; + while ((curr = s_translist.Head()) != NULL) { + REPORTRESOURCELEAK(HSTRANS); + STransDelete((HSTRANS)curr); + } + if (s_dirtyoffset) { + FREE(s_dirtyoffset); + s_dirtyoffset = NULL; + } + if (s_savedata) { + FREE(s_savedata); + s_savedata = NULL; + s_savedataalloc = 0; + } + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransDuplicate (HSTRANS source, + HSTRANS *handle) { + if (handle) + *handle = (HSTRANS)0; + + VALIDATEBEGIN; + VALIDATE(source); + VALIDATE(handle); + VALIDATEEND; + + TRANSPTR sourceptr = (TRANSPTR)source; + LPBYTE data = (LPBYTE)ALLOC(sourceptr->dataalloc); + CopyMemory(data,sourceptr->data,sourceptr->databytes); + TRANSPTR newptr = CreateTransparencyRecord(sourceptr); + newptr->data = data; + *handle = (HSTRANS)newptr; + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransInvertMask (HSTRANS sourcemask, + HSTRANS *handle) { + if (handle) + *handle = (HSTRANS)0; + + VALIDATEBEGIN; + VALIDATE(sourcemask); + VALIDATE(handle); + VALIDATEEND; + + TRANSPTR sourceptr = (TRANSPTR)sourcemask; + + // ALLOCATE MEMORY FOR THE NEW MASK DATA + DWORD dataalloc = (sourceptr->databytes-sourceptr->instructionoffset) + +2*sourceptr->height; + LPBYTE data = (LPBYTE)ALLOC(dataalloc); + + // COPY THE SOURCE MASK DATA, INVERTED, INTO THE DESTINATION BUFFER + DWORD bytes = 0; + { + LPBYTE source = sourceptr->data+sourceptr->instructionoffset; + LPBYTE dest = data; + int cy = sourceptr->height; + while (cy--) { + BYTE copybytes = 0; + BYTE skipbytes = 0; + do { + skipbytes = *(source++); + if (copybytes || skipbytes) { + *(dest++) = copybytes; + *(dest++) = skipbytes; + bytes += 2; + } + copybytes = *(source++); + } while (copybytes || skipbytes); + *(dest++) = 0; + *(dest++) = 0; + bytes += 2; + } + } + + // CREATE A RECORD FOR THE TRANSPARENCY + TRANSPTR newptr = CreateTransparencyRecord(sourceptr); + newptr->data = data; + newptr->dataalloc = dataalloc; + newptr->databytes = bytes; + newptr->instructionoffset = 0; + + // RETURN A HANDLE TO THE TRANSPARENCY + *handle = (HSTRANS)newptr; + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransIntersectDirtyArray (HSTRANS sourcemask, + LPBYTE dirtyarray, + BYTE dirtyarraymask, + HSTRANS *handle) { + if (handle) + *handle = (HSTRANS)0; + + VALIDATEBEGIN; + VALIDATE(sourcemask); + VALIDATE(dirtyarray); + VALIDATE(dirtyarraymask); + VALIDATE(handle); + VALIDATEEND; + + if (!s_dirtyoffset) + return FALSE; + TRANSPTR sourceptr = (TRANSPTR)sourcemask; + + // ALLOCATE MEMORY FOR THE RESULT + BUFFER buffer; + BufferCreate(&buffer); + + // PERFORM THE INTERSECTION + { + LPBYTE source = sourceptr->data+sourceptr->instructionoffset; + LPBYTE dest = buffer.data; + LPBYTE lastsource = source; + LPBYTE lastdest = dest; + int y = 0; + while (y < sourceptr->height) { + + // MAKE SURE THERE IS ENOUGH MEMORY IN THE DESTINATION BUFFER FOR + // THE LINE + BufferReserve(&buffer, + sourceptr->width*2+2, + &dest, + &lastdest); + + // IF THIS LINE MATCHES THE PREVIOUS ONE, JUST COPY THE RESULT + if ((y & (s_dirtyysize-1)) && + (*(LPDWORD)source == *(LPDWORD)lastsource) && + !memcmp(source+4,lastsource+4,source-lastsource-4)) { + DWORD sourcebytes = source-lastsource; + DWORD destbytes = dest-lastdest; + CopyMemory(dest,lastdest,destbytes); + lastsource = source; + lastdest = dest; + source += sourcebytes; + dest += destbytes; + buffer.bytesused += destbytes; + } + + // OTHERWISE, EXAMINE EACH SPAN FOR THIS LINE, SPLITTING COPY SPANS + // AND TURNING PORTIONS OF THEM INTO SKIP SPANS AS NECESSARY + else { + lastsource = source; + lastdest = dest; + LPBYTE dirty = dirtyarray+*(s_dirtyoffset+(y >> s_dirtyyshift)); + DWORD xoffset = 0; + BYTE copybytes; + BYTE skipbytes; + do { + copybytes = *(source++); + skipbytes = *(source++); + if (copybytes) { + BYTE bytesleft = copybytes; + BYTE length = 0; + BOOL copymode = TRUE; + while (bytesleft || length) + if (bytesleft && (((*dirty & dirtyarraymask) != 0) == copymode)) { + DWORD cellleft = s_dirtyxsize-xoffset; + if (bytesleft < cellleft) { + length += bytesleft; + xoffset += bytesleft; + bytesleft = 0; + } + else { + length += (BYTE)cellleft; + bytesleft -= (BYTE)cellleft; + xoffset = 0; + ++dirty; + } + } + else { + *(dest++) = length; + buffer.bytesused++; + length = 0; + copymode = !copymode; + } + if (skipbytes || !copymode) { + if (copymode) { + *(dest++) = 0; + buffer.bytesused++; + } + *(dest++) = skipbytes; + buffer.bytesused++; + } + } + else { + *(dest++) = 0; + *(dest++) = skipbytes; + buffer.bytesused += 2; + } + if (skipbytes) { + xoffset += skipbytes; + dirty += (xoffset >> s_dirtyxshift); + xoffset &= (s_dirtyxsize-1); + } + } while (copybytes || skipbytes); + } + + ++y; + } + } + + // CREATE A RECORD FOR THE TRANSPARENCY + TRANSPTR newptr = CreateTransparencyRecord(sourceptr); + newptr->data = buffer.data; + newptr->dataalloc = buffer.bytesalloc; + newptr->databytes = buffer.bytesused; + newptr->instructionoffset = 0; + + // RETURN A HANDLE TO THE TRANSPARENCY + *handle = (HSTRANS)newptr; + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransCombineMasks (HSTRANS basemask, + HSTRANS secondmask, + int offsetx, + int offsety, + DWORD flags, + HSTRANS *handle) { + if (handle) + *handle = (HSTRANS)0; + + VALIDATEBEGIN; + VALIDATE(basemask); + VALIDATE(secondmask); + VALIDATE(handle); + VALIDATEEND; + + // PARSE THE FLAGS + BOOL intersect = ((flags & 0x00000001) != 0); + BOOL invertsecond = ((flags & 0x00000002) != 0); + + // GENERATE A TRUTH TABLE TO DEFINE WHICH SOURCE SPANS WILL BE COMBINED INTO WHICH + // OUTPUT SPANS + BOOL usespan[2][2][2]; + { + for (int spantype0 = COPY; spantype0 <= SKIP; ++spantype0) + for (int spantypedest = COPY; spantypedest <= SKIP; ++spantypedest) + if (intersect) { + usespan[spantype0][spantypedest][invertsecond ? SKIP : COPY] = (spantype0 == spantypedest); + usespan[spantype0][spantypedest][invertsecond ? COPY : SKIP] = (spantypedest == SKIP); + } + else { + usespan[spantype0][spantypedest][invertsecond ? SKIP : COPY] = (spantypedest == COPY); + usespan[spantype0][spantypedest][invertsecond ? COPY : SKIP] = (spantype0 == spantypedest); + } + } + + // GET POINTERS TO THE SOURCE TRANSPARENCY INFORMATION + TRANSPTR sourceptr[2] = {(TRANSPTR)basemask, + (TRANSPTR)secondmask}; + INSTPTR instptr[2]; + instptr[0].byteptr = sourceptr[0]->data+sourceptr[0]->instructionoffset; + instptr[1].byteptr = sourceptr[1]->data+sourceptr[1]->instructionoffset; + + // SKIP PAST ANY SCAN LINES IN THE SECOND MASK WHICH ARE ABOVE THE TOP + // OF THE BASE MASK + if (offsety < 0) + for (int line = offsety; line < 0; ++line) + while (*instptr[1].wordptr++) + ; + + // ALLOCATE MEMORY FOR THE RESULT + BUFFER buffer; + BufferCreate(&buffer); + INSTPTR dest; + dest.byteptr = buffer.data; + + // PROCESS EACH SCAN LINE + for (int line = 0; line < sourceptr[0]->height; ++line) { + + // MAKE SURE THERE IS ENOUGH MEMORY IN THE DESTINATION BUFFER FOR + // THE LINE + BufferReserve(&buffer, + sourceptr[0]->width*2+2, + &dest.byteptr, + NULL); + + // IF THIS LINE IS NOT WITHIN THE RANGE THAT THE SECOND MASK INTERSECTS, + // THEN GENERATE A COMPLETE DUPLICATE OR A COMPLETE INTERSECTION OF THE + // BASE MASK + if ((line < offsety) || + (line > offsety+sourceptr[1]->height-1)) + if (intersect == invertsecond) { + do + buffer.bytesused += 2; + while ((*dest.wordptr++ = *instptr[0].wordptr++) != 0); + } + else { + int width = sourceptr[0]->width; + while (width) { + int skipspan = min(MAXSPANLENGTH,width); + *dest.byteptr++ = 0; + *dest.byteptr++ = (BYTE)skipspan; + buffer.bytesused += 2; + width -= skipspan; + } + *dest.wordptr++ = 0; + buffer.bytesused += 2; + while (*instptr[0].wordptr++) + ; + } + + // OTHERWISE, BUILD NEW INSTRUCTIONS FOR THIS SCAN LINE BY COMBINING THE + // INSTRUCTIONS FROM THE BASE AND SECOND MASKS + else { + int span[2][2] = {{0,0},{0,max(0,offsetx)}}; + BOOL hitend = FALSE; + + // SKIP PAST ANY PORTIONS OF THE SECOND MASK WHICH ARE ENTIRELY + // TO THE LEFT OF THE BASE MASK + if (offsetx < 0) { + int bytesleft = -offsetx; + while (bytesleft) { + span[1][COPY] = *instptr[1].byteptr++; + span[1][SKIP] = *instptr[1].byteptr++; + if (!(span[1][COPY] || span[1][SKIP])) { + span[1][SKIP] = INT_MAX; + hitend = TRUE; + break; + } + for (int adjustremaining = COPY; adjustremaining <= SKIP; ++adjustremaining) { + int adjustment = min(bytesleft,span[1][adjustremaining]); + span[1][adjustremaining] -= adjustment; + bytesleft -= adjustment; + } + } + } + + + // COMBINE THE BASE AND SECOND MASKS UNTIL THE BASE MASK IS EXHAUSTED + for (;;) { + + // LOAD THE NEXT COPY/SKIP PAIR FROM THE FIRST MASK + span[0][COPY] = *instptr[0].byteptr++; + span[0][SKIP] = *instptr[0].byteptr++; + if (!(span[0][COPY] || span[0][SKIP])) { + *dest.wordptr++ = 0; + buffer.bytesused += 2; + break; + } + + // COMBINE IT WITH INFORMATION FROM THE SECOND MASK STARTING + // AT THE CURRENT COPY/SKIP POSITION + for (int spantype0 = COPY; spantype0 <= SKIP; ++spantype0) + while (span[0][spantype0]) { + + // IF WE'VE USED UP THE CURRENT SET OF SPANS FROM THE SECOND MASK, + // LOAD THE NEXT SET + if (!(span[1][COPY] || span[1][SKIP])) { + span[1][COPY] = *instptr[1].byteptr++; + span[1][SKIP] = *instptr[1].byteptr++; + if (!(span[1][COPY] || span[1][SKIP])) { + span[1][SKIP] = INT_MAX; + hitend = TRUE; + } + } + + // GENERATE A NEW COPY SPAN AND A NEW SKIP SPAN + SPANPAIR inst; + for (int spantypedest = COPY; spantypedest <= SKIP; ++spantypedest) { + int spanlength = 0; + if (usespan[spantype0][spantypedest][COPY]) + spanlength = span[1][COPY]; + if (usespan[spantype0][spantypedest][SKIP] && + (usespan[spantype0][spantypedest][COPY] || !span[1][COPY])) + spanlength += span[1][SKIP]; + spanlength = min(spanlength,span[0][spantype0]); + inst.span[spantypedest] = (BYTE)spanlength; + span[0][spantype0] -= spanlength; + for (int adjustremaining = COPY; adjustremaining <= SKIP; ++adjustremaining) + if (usespan[adjustremaining]) { + int adjustment = min(spanlength,span[1][adjustremaining]); + span[1][adjustremaining] -= adjustment; + spanlength -= adjustment; + } + } + if (inst.pair) { + *dest.wordptr++ = inst.pair; + buffer.bytesused += 2; + } + + } + + } + if (!hitend) + while (*instptr[1].wordptr++) + ; + } + + } + + // CREATE A RECORD FOR THE TRANSPARENCY + TRANSPTR newptr = CreateTransparencyRecord(sourceptr[0]); + newptr->data = buffer.data; + newptr->dataalloc = buffer.bytesalloc; + newptr->databytes = buffer.bytesused; + newptr->instructionoffset = 0; + + // RETURN A HANDLE TO THE TRANSPARENCY + *handle = (HSTRANS)newptr; + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransIsPixelInMask (HSTRANS mask, + int offsetx, + int offsety) { + VALIDATEBEGIN; + VALIDATE(mask); + VALIDATEEND; + + // MAKE SURE THAT THE OFFSETS ARE WITHIN THE BOUNDS OF THE TRANSPARENCY + TRANSPTR transptr = (TRANSPTR)mask; + if ((offsetx < 0) || + (offsety < 0) || + (offsetx >= transptr->width) || + (offsety >= transptr->height)) + return FALSE; + + // SKIP TO THE CORRECT SCAN LINE + LPWORD instwordptr = (LPWORD)(transptr->data+transptr->instructionoffset); + while (offsety--) + while (*instwordptr++) + ; + + // SKIP TO THE CORRECT PIXEL + LPBYTE instbyteptr = (LPBYTE)instwordptr; + for (;;) { + BYTE copybytes = *instbyteptr++; + BYTE skipbytes = *instbyteptr++; + + // IF WE HIT THE END OF THE SCAN LINE, RETURN FALSE + if (!(copybytes || skipbytes)) + return FALSE; + + // IF THE REQUESTED PIXEL FALLS WITHIN A COPY SPAN, RETURN TRUE + if (copybytes > offsetx) + return TRUE; + offsetx -= copybytes; + + // IF THE REQUESTED PIXEL FALLS WITHIN A SKIP SPAN, RETURN FALSE + if (skipbytes > offsetx) + return FALSE; + offsetx -= skipbytes; + + } + +} + +//=========================================================================== +BOOL APIENTRY STransLoadE (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle) { + if (handle) + *handle = (HSTRANS)0; + + VALIDATEBEGIN; + VALIDATE(filename); + VALIDATE(*filename); + VALIDATE(handle); + VALIDATEEND; + + // DETERMINE THE SIZE OF THE BITMAP FILE + int width = 0; + int height = 0; + if (!SBmpLoadImage(filename,NULL,NULL,0,&width,&height)) + return FALSE; + + // READ THE BITMAP BITS + LPBYTE buffer = (LPBYTE)ALLOC(width*height); + if (!SBmpLoadImage(filename,NULL,buffer,width*height)) + return FALSE; + + // CREATE THE TRANSPARENCY + STransCreate(buffer, + width, + height, + 8, + rect, + colorkey, + handle); + + // FREE THE BITMAP BITS + FREE(buffer); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransLoadI (LPCTSTR filename, + LPRECT rect, + COLORREF colorkey, + HSTRANS *handle) { + RECT exclrect; + LPRECT exclrectptr = rect; + if (rect) { + exclrect.left = rect->left; + exclrect.top = rect->top; + exclrect.right = rect->right+1; + exclrect.bottom = rect->bottom+1; + exclrectptr = &exclrect; + } + return STransLoadE(filename, + exclrectptr, + colorkey, + handle); +} + +//=========================================================================== +BOOL APIENTRY STransSetDirtyArrayInfo (int screencx, + int screency, + int cellcx, + int cellcy) { + + // FREE THE OLD DIRTY ARRAY OFFSET TABLE + if (s_dirtyoffset) { + FREE(s_dirtyoffset); + s_dirtyoffset = NULL; + } + + // SAVE THE NEW CELL SIZES AND SHIFT VALUES + if (!DetermineShift(cellcx,&s_dirtyxshift)) + return 0; + if (!DetermineShift(cellcy,&s_dirtyyshift)) + return 0; + s_dirtysize.cx = (screencx+(1 << s_dirtyxshift)-1) >> s_dirtyxshift; + s_dirtysize.cy = (screency+(1 << s_dirtyyshift)-1) >> s_dirtyyshift; + s_dirtyxsize = cellcx; + s_dirtyysize = cellcy; + + // CREATE A NEW DIRTY ARRAY OFFSET TABLE + s_dirtyoffset = (LPDWORD)ALLOC(s_dirtysize.cy*sizeof(DWORD)); + DWORD offset = 0; + for (int loop = 0; loop < s_dirtysize.cy; ++loop) { + *(s_dirtyoffset+loop) = offset; + offset += s_dirtysize.cx; + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY STransUpdateDirtyArray (LPBYTE dirtyarray, + BYTE dirtyvalue, + int destx, + int desty, + HSTRANS transparency, + BOOL tracecontour) { + VALIDATEBEGIN; + VALIDATE(dirtyarray); + VALIDATE(dirtyvalue); + VALIDATE(transparency); + VALIDATEEND; + + if (!s_dirtyoffset) + return FALSE; + TRANSPTR transptr = (TRANSPTR)transparency; + if (!((transptr->width > 0) && (transptr->height > 0))) + return FALSE; + + // IF WE HAVE BEEN ASKED TO TRACE THE CONTOUR, THEN ONLY UPDATE THE VALUES + // OF THOSE CELLS THAT ARE TOUCHED BY A NON-TRANSPARENT PORTION OF THE + // TRANSPARENCY + if (tracecontour) { + // note: write this + return FALSE; + } + + // OTHERWISE, UPDATE THE WHOLE RECTANGLE CONTAINING THE TRANSPARENCY + else { + int lastx = (destx+transptr->boundrect.right) >> s_dirtyxshift; + int lasty = (desty+transptr->boundrect.bottom) >> s_dirtyyshift; + destx = (destx+transptr->boundrect.left) >> s_dirtyxshift; + desty = (desty+transptr->boundrect.top) >> s_dirtyyshift; + for (int y = desty; y < lasty; ++y) { + LPBYTE dirty = dirtyarray+*(s_dirtyoffset+y)+destx; + for (int x = destx; x < lastx; ++x) + *(dirty++) |= dirtyvalue; + } + } + + return TRUE; +} diff --git a/Storm/SOURCE/SVID.CPP b/Storm/SOURCE/SVID.CPP new file mode 100644 index 0000000..3a7ff33 --- /dev/null +++ b/Storm/SOURCE/SVID.CPP @@ -0,0 +1,1012 @@ +/**************************************************************************** +* +* SVID.CPP +* Storm video playback functions +* +* By Michael O'Brien (3/28/96) +* +***/ + +#include "pch.h" +#pragma hdrstop + +#define BENCHMARKVERSION 3 +#define MAXSOURCEWIDTH 320 +#define TOLERANCE 768 + +#define COL_RED 0 +#define COL_GREEN 1 +#define COL_BLUE 2 + +#define REGKEY "Video Player" +#define REGVALUE_MODE "Mode" + +typedef struct _COLORNODE { + _COLORNODE *next; + BYTE color; +} COLORNODE, *COLORNODEPTR; + +typedef struct _SCODE { + HSCODESTREAM horizontalinterpolate; + HSCODESTREAM verticalinterpolate; + HSCODESTREAM pixeldouble; +} SCODEREC, *SCODEPTR; + +typedef struct _SMACKERAPI { + void (RADEXPLINK *SmackBufferClose)(SmackBuf *); + void (RADEXPLINK *SmackBufferNewPalette)(SmackBuf *,void *,u32); + SmackBuf * (RADEXPLINK *SmackBufferOpen)(HWND,u32,u32,u32,u32,u32); + void (RADEXPLINK *SmackClose)(Smack *); + u32 (RADEXPLINK *SmackDoFrame)(Smack *); + void (RADEXPLINK *SmackGoto)(Smack *,u32); + void (RADEXPLINK *SmackNextFrame)(Smack *); + Smack * (RADEXPLINK *SmackOpen)(char *,u32,u32); + u8 (RADEXPLINK *SmackSoundUseDirectSound)(LPVOID); + void (RADEXPLINK *SmackToBuffer)(Smack *,u32,u32,u32,u32,void *,u32); + u32 (RADEXPLINK *SmackToBufferRect)(Smack *,u32); + void (RADEXPLINK *SmackVolumePan)(Smack *,u32,u32,u32); + u32 (RADEXPLINK *SmackWait)(Smack *); +} SMACKERAPI, *SMACKERAPIPTR; + +typedef struct _SMACKERDATA { + SmackBuf *buffer; + Smack *file; + int top; +} SMACKERDATA, *SMACKERDATAPTR; + +NODEDECL(VIDEOREC) { + HANDLE filehandle; + SCODEEXECUTEDATA executedata; + LPBYTE interptable; + DWORD palettefirstentry; + DWORD palettenumentries; + SMACKERDATAPTR smackerdata; + LPBYTE destbuffer; + RECT destrect; + LPCRECT ddrect; + SIZE destsize; + LPBYTE lockedbuffer; + DWORD flags; + BOOL vertzoom; + BOOL vertinterp; + int altline; + CSRgn rgn[2]; + DWORD allocrects; + DWORD numrects; + LPRECT rect; +} *VIDEOPTR; + +static SCODEPTR s_scode = NULL; +static SMACKERAPIPTR s_smackerapi = NULL; +static HINSTANCE s_smackerlib = (HINSTANCE)0; +static LIST(VIDEOREC) s_videolist; + +static void UnlockBuffer (VIDEOPTR video); + +//=========================================================================== +static void AdjustGamma (LPPALETTEENTRY pe, double gamma) { + for (int loop = 0; loop < 256; ++loop) { + double red = 256.0*pow(((double)(pe+loop)->peRed )/256.0,gamma); + double green = 256.0*pow(((double)(pe+loop)->peGreen)/256.0,gamma); + double blue = 256.0*pow(((double)(pe+loop)->peBlue )/256.0,gamma); + (pe+loop)->peRed = (red > 255.0) ? 255 : (BYTE)red; + (pe+loop)->peGreen = (green > 255.0) ? 255 : (BYTE)green; + (pe+loop)->peBlue = (blue > 255.0) ? 255 : (BYTE)blue; + } +} + +//=========================================================================== +static BOOL inline BindToSmacker () { + + // LOAD THE SMACKER LIBRARY + if (!s_smackerlib) { + s_smackerlib = LoadLibrary("smackw32.dll"); + if (!s_smackerlib) + return FALSE; + } + + // ALLOCATE AN API STRUCTURE + if (!s_smackerapi) + s_smackerapi = NEW(SMACKERAPI); + + // BIND TO THE INDIVIDUAL FUNCTIONS + BOOL success = TRUE; +#define BIND(a,b) *(void **)&s_smackerapi->##a \ + = GetProcAddress(s_smackerlib,b); \ + if (!s_smackerapi->##a) \ + success = FALSE; + BIND(SmackBufferClose ,"_SmackBufferClose@4"); + BIND(SmackBufferNewPalette ,"_SmackBufferNewPalette@12"); + BIND(SmackBufferOpen ,"_SmackBufferOpen@24"); + BIND(SmackClose ,"_SmackClose@4"); + BIND(SmackDoFrame ,"_SmackDoFrame@4"); + BIND(SmackGoto ,"_SmackGoto@8"); + BIND(SmackNextFrame ,"_SmackNextFrame@4"); + BIND(SmackOpen ,"_SmackOpen@12"); + BIND(SmackSoundUseDirectSound,"_SmackSoundUseDirectSound@4"); + BIND(SmackToBuffer ,"_SmackToBuffer@28"); + BIND(SmackToBufferRect ,"_SmackToBufferRect@8"); + BIND(SmackVolumePan ,"_SmackVolumePan@16"); + BIND(SmackWait ,"_SmackWait@4"); +#undef BIND + return success; +} + +//=========================================================================== +static BOOL CreateLinearInterpolationTable (VIDEOPTR video, LPPALETTEENTRY pe) { + + // ALLOCATE 64K FOR THE INTERPOLATION TABLE IF IT'S NOT ALREADY ALLOCATED + if (!video->interptable) { + video->interptable = (LPBYTE)ALLOC(0x10000); + video->executedata.table = video->interptable; + } + + // BUILD A SQUARE TABLE + static DWORD squaretable[511]; + static BOOL squareinit = FALSE; + if (!squareinit) { + squareinit = TRUE; + for (int loop = -255; loop <= 255; ++loop) + squaretable[loop+255] = (DWORD)(loop*loop); + } + + // BUILD A SET OF POINTERS INTO THE SQUARE TABLE FOR EACH PALETTE ENTRY + LPBYTE palcolor[3][256]; + DWORD loop; + for (loop = 0; loop < 256; ++loop) { + palcolor[COL_RED ][loop] = (LPBYTE)&squaretable[255+(pe+loop)->peRed]; + palcolor[COL_GREEN][loop] = (LPBYTE)&squaretable[255+(pe+loop)->peGreen]; + palcolor[COL_BLUE ][loop] = (LPBYTE)&squaretable[255+(pe+loop)->peBlue]; + } + + // FILL IN THE COLOR MATCHING TABLE + COLORNODEPTR interpcolortable[18][18][18]; + COLORNODE interpnode[256]; + ZeroMemory(&interpcolortable,18*18*18*sizeof(COLORNODEPTR)); + for (loop = 0; loop < 256; ++loop) { + if (loop && + ((pe+loop)->peRed == (pe+loop-1)->peRed) && + ((pe+loop)->peGreen == (pe+loop-1)->peGreen) && + ((pe+loop)->peBlue == (pe+loop-1)->peBlue)) + continue; + DWORD red = ((DWORD)(pe+loop)->peRed >> 4)+1; + DWORD green = ((DWORD)(pe+loop)->peGreen >> 4)+1; + DWORD blue = ((DWORD)(pe+loop)->peBlue >> 4)+1; + interpnode[loop].color = (BYTE)loop; + interpnode[loop].next = interpcolortable[red][green][blue]; + interpcolortable[red][green][blue] = &interpnode[loop]; + } + + // BUILD THE INTERPOLATION TABLE. FOR EVERY PAIR OF COLORS, WE LOOK + // FOR A COLOR THAT IS AS CLOSE AS POSSIBLE TO EQUIDISTANT BETWEEN THE + // TWO COLORS. + for (DWORD loop1 = 0; loop1 < 256; ++loop1) { + for (DWORD loop2 = 0; loop2 < loop1; ++loop2) { + BYTE minnum = (BYTE)max(loop1,loop2); + DWORD mindist = UINT_MAX; + + // FIND THE DESIRED COLOR + DWORD red = ((DWORD)(pe+loop1)->peRed +(DWORD)(pe+loop2)->peRed ) >> 1; + DWORD green = ((DWORD)(pe+loop1)->peGreen+(DWORD)(pe+loop2)->peGreen) >> 1; + DWORD blue = ((DWORD)(pe+loop1)->peBlue +(DWORD)(pe+loop2)->peBlue ) >> 1; + + // FIND THE SLOT IN THE COLOR MATCHING TABLE WHICH WOULD CONTAIN + // THE DESIRED COLOR + DWORD redslot = (red >> 4)+1; + DWORD greenslot = (green >> 4)+1; + DWORD blueslot = (blue >> 4)+1; + + // ADJUST THE COLOR VALUES OF THE DESIRED COLOR SO THEY CAN BE + // USED AS BYTE POINTERS + red <<= 2; + green <<= 2; + blue <<= 2; + + // IF THERE IS AT LEAST ONE COLOR IN THE COLOR MATCHING TABLE + // FOR THE TARGET AREA, USE ONLY COLORS FROM THAT AREA. + COLORNODEPTR curr = interpcolortable[redslot][greenslot][blueslot]; + if (curr) + if (curr->next) + while (curr) { + DWORD dist = *(LPDWORD)(palcolor[COL_RED][curr->color]-red) + +*(LPDWORD)(palcolor[COL_GREEN][curr->color]-green) + +*(LPDWORD)(palcolor[COL_BLUE][curr->color]-blue); + if (dist < mindist) { + mindist = dist; + minnum = curr->color; + } + curr = curr->next; + } + else + minnum = curr->color; + + // OTHERWISE, SEARCH A 3X3X3 GRID IN THE COLOR MATCHING TABLE. + else { + static const int offs[26][3] = {{-1,0,0},{0,-1,0},{0,0,-1}, + {1,0,0},{0,1,0},{0,0,1}, + {-1,1,0},{-1,0,1}, + {1,-1,0},{0,-1,1}, + {1,0,-1},{0,1,-1}, + {-1,-1,0},{-1,0,-1},{0,-1,-1}, + {1,1,0},{1,0,1},{0,1,1}, + {-1,-1,1},{-1,1,-1},{1,-1,-1}, + {1,1,-1},{1,-1,1},{-1,1,1}, + {-1,-1,-1},{1,1,1}}; + for (BYTE loop = 0; (loop < 26) && (mindist > TOLERANCE); ++loop) { + curr = interpcolortable[redslot +offs[loop][0]] + [greenslot+offs[loop][1]] + [blueslot +offs[loop][2]]; + while (curr) { + DWORD dist = *(LPDWORD)(palcolor[COL_RED][curr->color]-red) + +*(LPDWORD)(palcolor[COL_GREEN][curr->color]-green) + +*(LPDWORD)(palcolor[COL_BLUE][curr->color]-blue); + if (dist < mindist) { + mindist = dist; + minnum = curr->color; + } + curr = curr->next; + } + } + } + + *(video->interptable+(loop1 << 8)+loop2) = (BYTE)minnum; + *(video->interptable+(loop2 << 8)+loop1) = (BYTE)minnum; + } + *(video->interptable+(loop1 << 8)+loop1) = (BYTE)loop1; + } + + return TRUE; +} + +//=========================================================================== +static inline void ExtractRects (VIDEOPTR videoptr, + CSRgn *rgn) { + rgn->GetRects(&videoptr->numrects,NULL); + if (videoptr->numrects > videoptr->allocrects) { + FREEIFUSED(videoptr->rect); + videoptr->allocrects = videoptr->numrects; + videoptr->rect = (LPRECT)ALLOC(videoptr->allocrects*sizeof(RECT)); + } + rgn->GetRects(&videoptr->numrects,videoptr->rect); +} + +//=========================================================================== +static BOOL IsValidVideoHandle (HSVIDEO handle) { + ITERATELIST(VIDEOREC,s_videolist,currvideo) + if (currvideo == (VIDEOPTR)handle) + return TRUE; + return FALSE; +} + +//=========================================================================== +static BOOL LockBuffer (VIDEOPTR video, LPBYTE *buffer, LPSIZE size) { + if (video->flags & SVID_FLAG_TOSCREEN) { + size->cx = 640; + size->cy = 480; + SDrawGetScreenSize((int *)&size->cx,(int *)&size->cy); + BOOL result = SDrawLockSurface(SDRAW_SURFACE_FRONT, + video->ddrect, + &video->lockedbuffer, + (int *)&size->cx); + *buffer = video->lockedbuffer+video->smackerdata->top*size->cx; + if ((!video->ddrect) && (video->flags & SVID_FLAG_1XSIZE)) + *buffer += (min(640,size->cx)-video->smackerdata->file->Width) >> 1; + return result; + } + else { + *buffer = video->destbuffer + +(video->destrect.top*video->destsize.cx) + +video->destrect.left; + size->cx = video->destsize.cx; + size->cy = video->destsize.cy; + return TRUE; + } +} + +//=========================================================================== +static BOOL ProcessFrameDirect (VIDEOPTR videoptr) { + BOOL skip = TRUE; + LPBYTE videobuffer; + SIZE videosize; + if (LockBuffer(videoptr,&videobuffer,&videosize)) { + s_smackerapi->SmackToBuffer(videoptr->smackerdata->file, + 0, + 0, + videosize.cx, + videosize.cy, + videobuffer, + 0); + skip = s_smackerapi->SmackDoFrame(videoptr->smackerdata->file); + UnlockBuffer(videoptr); + } + return skip; +} + +//=========================================================================== +static void ProcessFrameEffects (VIDEOPTR videoptr) { + + // SAVE POINTERS TO COMMONLY ACCESSED DATA STRUCTURES + SCODEEXECUTEDATA *exec = &videoptr->executedata; + LPBYTE source = (LPBYTE)videoptr->smackerdata->buffer->Buffer; + SIZE sourcesz = {videoptr->smackerdata->buffer->Width, + videoptr->smackerdata->buffer->Height}; + BOOL vertzoom = videoptr->vertzoom; + BOOL vertinterp = videoptr->vertinterp; + BOOL horzinterp = ((videoptr->flags & SVID_FLAG_INTERPOLATE) != 0); + BOOL skip = vertzoom && !(videoptr->flags & SVID_FLAG_DOUBLESCANS); + BOOL interlace = (videoptr->flags & SVID_FLAG_INTERLACE) && !skip; + + // IF WE ARE INTERLACING, ALTERNATE THE SCAN LINE ADJUSTMENT + if (interlace) + videoptr->altline = !videoptr->altline; + int altline = videoptr->altline; + + // UNCOMPRESS THE FRAME INTO THE OFFSCREEN BUFFER, AND BUILD A REGION + // CONTAINING ALL OF THE RECTANGLES THAT WERE MODIFIED DURING THE + // DECOMPRESSION PROCESS + videoptr->rgn[altline].Clear(); + while (s_smackerapi->SmackToBufferRect(videoptr->smackerdata->file, + SMACKSURFACEFAST)) { + RECT rect = {videoptr->smackerdata->file->LastRectx, + videoptr->smackerdata->file->LastRecty, + videoptr->smackerdata->file->LastRectx + +videoptr->smackerdata->file->LastRectw, + videoptr->smackerdata->file->LastRecty + +videoptr->smackerdata->file->LastRecth}; + videoptr->rgn[altline].AddRect(&rect,NULL); + } + + // IF WE ARE INTERLACING, THEN ADD ALL THE RECTANGLES FROM THE PREVIOUS + // FRAME + CSRgn *rgn; + if (interlace) { + rgn = new CSRgn(videoptr->rgn[altline]); + ExtractRects(videoptr,&videoptr->rgn[!altline]); + for (DWORD num = 0; num < videoptr->numrects; ++num) + rgn->AddRect(&videoptr->rect[num],NULL); + } + else + rgn = &videoptr->rgn[altline]; + + // EXTRACT AN ARRAY OF RECTANGLES FROM THE REGION + ExtractRects(videoptr,rgn); + if (interlace) + delete rgn; + + // LOCK THE VIDEO BUFFER + LPBYTE dest; + SIZE destsz; + if (!LockBuffer(videoptr,&dest,&destsz)) + return; + + // PROCESS EACH RECTANGLE + for (DWORD num = 0; num < videoptr->numrects; ++num) { + POINT pos = {videoptr->rect[num].left, + videoptr->rect[num].top}; + SIZE sz = {videoptr->rect[num].right-videoptr->rect[num].left, + videoptr->rect[num].bottom-videoptr->rect[num].top}; + if ((sz.cx < 2) || (sz.cy < 2)) + continue; + + // PERFORM VERTICAL INTERPOLATION IF NECESSARY + if (vertinterp) { + exec->xiterations = sz.cx; + exec->yiterations = sz.cy-1; + exec->source = source+(pos.y*sourcesz.cx)+pos.x; + exec->dest = source+(pos.y*sourcesz.cx)+pos.x+(sourcesz.cx/2); + exec->adjustsource = sourcesz.cx-sz.cx; + exec->adjustdest = sourcesz.cx-sz.cx; + exec->c = sourcesz.cx; + if (pos.y) { + exec->yiterations++; + exec->source = (LPBYTE)exec->source-sourcesz.cx; + exec->dest = (LPBYTE)exec->dest-sourcesz.cx; + } + SCodeExecute(s_scode->verticalinterpolate,exec); + } + + // SETUP THE OPERATION TO BLT THE OFFSCREEN BUFFER ONTO THE SCREEN + exec->xiterations = sz.cx; + exec->yiterations = sz.cy; + exec->source = source+pos.y*sourcesz.cx+pos.x; + exec->dest = dest+pos.y*destsz.cx+pos.x*2; + exec->adjustsource = sourcesz.cx-sz.cx; + exec->adjustdest = destsz.cx-sz.cx*2; + + // ADJUST THE OPERATION FOR HORIZONTAL INTERPOLATION + exec->xiterations -= horzinterp; + + // ADJUST THE OPERATION FOR VERTICAL ZOOMING + if (vertzoom) { + exec->dest = (LPBYTE)exec->dest+pos.y*destsz.cx; + exec->yiterations *= 2; + } + + // ADJUST THE OPERATION FOR VERTICAL INTERPOLATION + if (vertinterp) { + exec->adjustsource -= sourcesz.cx/2; + if (interlace && altline && (pos.y >= 2)) { + exec->yiterations += 2; + exec->source = (LPBYTE)exec->source-sourcesz.cx; + exec->dest = (LPBYTE)exec->dest-destsz.cx*2; + } + else if ((!interlace) && pos.y) { + exec->yiterations++; + exec->source = (LPBYTE)exec->source-sourcesz.cx/2; + exec->dest = (LPBYTE)exec->dest-destsz.cx; + } + } + + // ADJUST THE OPERATION FOR SCAN LINE SKIPPING + if (skip) { + exec->yiterations /= 2; + exec->adjustdest += destsz.cx; + } + + // ADJUST THE OPERATION FOR INTERLACING + if (interlace) { + exec->yiterations /= 2; + exec->adjustdest += destsz.cx; + if (altline && (vertinterp || !vertzoom)) + exec->source = (LPBYTE)exec->source+(sourcesz.cx >> vertinterp); + if (altline) + exec->dest = (LPBYTE)exec->dest+destsz.cx; + if (vertinterp) + exec->adjustsource += sourcesz.cx/2; + else if (!vertzoom) + exec->adjustsource += sourcesz.cx; + } + + // ADJUST THE OPERATION FOR LINE DOUBLING + exec->adjustsourcealt = exec->adjustsource; + exec->adjustdestalt = exec->adjustdest; + if (vertzoom && !(vertinterp || skip || interlace)) + exec->adjustsource = -sz.cx; + + // PERFORM THE BLT + SCodeExecute(horzinterp + ? s_scode->horizontalinterpolate + : s_scode->pixeldouble, + exec); + + + } + + // UNLOCK THE VIDEO BUFFER + UnlockBuffer(videoptr); + +} + +//=========================================================================== +static void UnlockBuffer (VIDEOPTR video) { + if (video->flags & SVID_FLAG_TOSCREEN) { + SDrawUnlockSurface(SDRAW_SURFACE_FRONT,video->lockedbuffer); + video->lockedbuffer = NULL; + } +} + +/**************************************************************************** +* +* EXPORTED FUNCTIONS +* +***/ + +//=========================================================================== +BOOL APIENTRY SVidDestroy () { + + // CLOSE ALL ACTIVE VIDEOS + VIDEOPTR curr; + while ((curr = s_videolist.Head()) != NULL) { + REPORTRESOURCELEAK(HSVIDEO); + SVidPlayEnd((HSVIDEO)curr); + } + + // DELETE S-CODE STREAMS + if (s_scode) { + SCodeDelete(s_scode->horizontalinterpolate); + SCodeDelete(s_scode->verticalinterpolate); + SCodeDelete(s_scode->pixeldouble); + FREE(s_scode); + s_scode = NULL; + } + + // UNBIND FROM SMACKER + if (s_smackerapi) { + FREE(s_smackerapi); + s_smackerapi = NULL; + } + if (s_smackerlib) { + FreeLibrary(s_smackerlib); + s_smackerlib = (HINSTANCE)0; + } + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SVidGetSize (HSVIDEO video, + int *width, + int *height, + int *bitdepth) { + if (width) + *width = 0; + if (height) + *height = 0; + if (bitdepth) + *bitdepth = 8; + + VALIDATEBEGIN; + VALIDATE(video); + VALIDATEEND; + + if (!IsValidVideoHandle(video)) + return FALSE; + VIDEOPTR videoptr = (VIDEOPTR)video; + if (width) + *width = videoptr->smackerdata->file->Width; + if (height) + *height = videoptr->smackerdata->file->Height; + return (width || height || bitdepth); +} + +//=========================================================================== +BOOL APIENTRY SVidInitialize (LPVOID directsound) { + + // BIND TO SMACKER + if (!BindToSmacker()) + return FALSE; + + // CREATE S-CODE STREAMS FOR THE INNER LOOPS + if (!s_scode) { + s_scode = NEW(SCODEREC); + SCodeCompile("1 W2=S W1=W2 2 D=W","1 W1=W2 W2=S W1=TW 2 D=W",NULL, + MAXSOURCEWIDTH, + 0, + &s_scode->horizontalinterpolate); + SCodeCompile(NULL,"1 W1=S W2=SC D=TW",NULL, + MAXSOURCEWIDTH, + 0, + &s_scode->verticalinterpolate); + SCodeCompile(NULL,"1 W1=S W2=W1 2 D=W",NULL, + MAXSOURCEWIDTH, + SCODE_CF_USESALTADJUSTS, + &s_scode->pixeldouble); + } + if (!(s_scode->horizontalinterpolate && + s_scode->verticalinterpolate && + s_scode->pixeldouble)) + return FALSE; + + // INITIALIZE SOUND + s_smackerapi->SmackSoundUseDirectSound(directsound); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SVidPlayBegin (LPCTSTR filename, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle) { + if (handle) + *handle = (HSVIDEO)0; + + VALIDATEBEGIN; + VALIDATE(filename); + VALIDATE(handle); + VALIDATE(destbuffer || !(flags & SVID_FLAG_TOBUFFER)); + VALIDATE(destsize || !destbuffer); + VALIDATE((!paletteuse) || (paletteuse->size == sizeof(SVIDPALETTEUSE))); + VALIDATEEND; + + // DETERMINE THE SCREEN SIZE, WHICH IS NEEDED BY MANY OF THE SIZING AND + // POSITIONING CALCULATIONS PERFORMED BY THIS FUNCTION + int screencx, screency; + SDrawGetScreenSize(&screencx,&screency); + + // IF THE AUTOSIZE OR AUTOQUALITY FLAGS ARE SET, READ THE CURRENT VIDEO + // MODE OUT OF THE REGISTRY, OR DEFAULT TO HIGH QUALITY MODE + if (flags & (SVID_FLAG_AUTOSIZE | SVID_FLAG_AUTOQUALITY)) { + + // LOAD THE BASE SETTING FROM THE REGISTRY + DWORD newflags = 0; + SRegLoadValue(REGKEY,REGVALUE_MODE,0,&newflags); + + // ADJUST IT TO THE DEFAULT QUALITY LEVEL + if (!(newflags & SVID_FLAG_1XSIZE)) + newflags = SVID_QUALITY_HIGH; + + // ADJUST THE FLAGS + if (flags & SVID_FLAG_AUTOSIZE) { + flags &= ~(SVID_FLAG_1XSIZE | SVID_FLAG_2XSIZE); + flags |= (newflags & (SVID_FLAG_1XSIZE | SVID_FLAG_2XSIZE)); + } + if (flags & SVID_FLAG_AUTOQUALITY) { + flags &= ~(SVID_FLAG_DOUBLESCANS | SVID_FLAG_INTERPOLATE | SVID_FLAG_INTERLACE); + flags |= (newflags & (SVID_FLAG_DOUBLESCANS | SVID_FLAG_INTERPOLATE | SVID_FLAG_INTERLACE)); + } + + } + + // INITIALIZE THIS MODULE IF NECESSARY + if (!(s_smackerlib && s_smackerapi && s_scode)) + if (!SVidInitialize(NULL)) + return FALSE; + + // ALLOCATE A NEW VIDEO RECORD + VIDEOPTR videoptr = s_videolist.NewNode(); + videoptr->filehandle = INVALID_HANDLE_VALUE; + + // PERFORM INITIAL PROCESSING ON THE FLAGS + flags = (flags & ~SVID_FLAG_TOSCREEN) + | ((flags & SVID_FLAG_TOBUFFER) ? 0 : SVID_FLAG_TOSCREEN); + if (flags & SVID_FLAG_TOBUFFER) + flags &= ~SVID_FLAG_FULLSCREEN; + if (flags & SVID_FLAG_TOSCREEN) + destbuffer = NULL; + + // PROCESS AND SAVE THE DESTINATION + videoptr->destbuffer = (LPBYTE)destbuffer; + if (destrect) { + CopyMemory(&videoptr->destrect,destrect,sizeof(RECT)); + videoptr->ddrect = &videoptr->destrect; + } + if (destsize) + CopyMemory(&videoptr->destsize,destsize,sizeof(SIZE)); + + // PROCESS AND SAVE THE PALETTE INFORMATION + if (paletteuse) { + videoptr->palettefirstentry = paletteuse->firstentry; + videoptr->palettenumentries = paletteuse->numentries; + } + else { + videoptr->palettefirstentry = 1; + videoptr->palettenumentries = 254; + } + + // ALLOCATE A SMACKER DATA RECORD + videoptr->smackerdata = NEWZERO(SMACKERDATA); + + // OPEN THE FILE + { + DWORD smackerflags = SMACKFILEHANDLE | SMACKTRACKS; + HANDLE filehandle = INVALID_HANDLE_VALUE; + if (flags & SVID_FLAG_PRELOAD) + smackerflags |= SMACKPRELOADALL; + if (flags & SVID_FLAG_NOSKIP) + smackerflags |= SMACKNOSKIP; + if (flags & SVID_FLAG_NEEDPAN) + smackerflags |= SMACKNEEDPAN; + if (flags & SVID_FLAG_NEEDVOLUME) + smackerflags |= SMACKNEEDVOLUME; + if (flags & SVID_FLAG_FILEHANDLE) + filehandle = (HANDLE)filename; + else if (SFileOpenFileWin32(filename,&filehandle)) + videoptr->filehandle = filehandle; + else { + SVidPlayEnd((HSVIDEO)videoptr); + return FALSE; + } + if (!(videoptr->smackerdata->file = s_smackerapi->SmackOpen((char *)filehandle, + smackerflags, + SMACKAUTOEXTRA))) { + SVidPlayEnd((HSVIDEO)videoptr); + return FALSE; + } + } + + // COMPARE THE VIDEO SIZE TO THE SCREEN SIZE, AND FORCE OFF VERTICAL ZOOMING + // AND/OR HORIZONTAL ZOOMING AS NECESSARY TO FIT THE VIDEO ON THE SCREEN + if ((int)videoptr->smackerdata->file->Width*2 > screencx) + flags &= ~SVID_FLAG_2XSIZE; + videoptr->vertzoom = ((flags & SVID_FLAG_2XSIZE) != 0); + if ((int)videoptr->smackerdata->file->Height*2 > screency) + videoptr->vertzoom = FALSE; + + // DETERMINE THE TOP OUTPUT SCAN LINE + if (flags & SVID_FLAG_FULLSCREEN) + videoptr->smackerdata->top = (screency-(videoptr->smackerdata->file->Height*(videoptr->vertzoom+1)))/2; + else + videoptr->smackerdata->top = 0; + + // CREATE A SMACKER OFFSCREEN BUFFER + if (flags & SVID_FLAG_2XSIZE) { + videoptr->vertinterp = videoptr->vertzoom && + (flags & SVID_FLAG_DOUBLESCANS) && + (flags & SVID_FLAG_INTERPOLATE); + if (!(videoptr->smackerdata->buffer = + s_smackerapi->SmackBufferOpen((HWND)0, + SMACKSTANDARDBLIT, + videoptr->smackerdata->file->Width*(videoptr->vertinterp+1), + videoptr->smackerdata->file->Height, + videoptr->smackerdata->file->Width*(videoptr->vertinterp+1), + videoptr->smackerdata->file->Height))) { + SVidPlayEnd((HSVIDEO)videoptr); + return FALSE; + } + s_smackerapi->SmackToBuffer(videoptr->smackerdata->file, + 0, + 0, + videoptr->smackerdata->file->Width*(videoptr->vertinterp+1), + videoptr->smackerdata->file->Height, + videoptr->smackerdata->buffer->Buffer, + 0); + } + else + videoptr->vertinterp = FALSE; + + // PROCESS AND SAVE THE FINAL FLAGS + flags = (flags & ~SVID_FLAG_1XSIZE) + | ((flags & SVID_FLAG_2XSIZE) ? 0 : SVID_FLAG_1XSIZE); + if (flags & SVID_FLAG_1XSIZE) + flags &= ~(SVID_FLAG_DOUBLESCANS | SVID_FLAG_INTERPOLATE | SVID_FLAG_INTERLACE); + videoptr->flags = flags; + + // IF WE HAVE BEEN ASKED TO LINEAR INTERPOLATE BUT HAVE NOT BEEN GIVEN + // AUTHORITY TO MODIFY THE PALETTE, THEN CREATE A LINEAR INTERPOLATION + // TABLE BASED ON THE CURRENT PALETTE + if ((flags & (SVID_FLAG_INTERPOLATE | SVID_FLAG_USECURRENTPALETTE)) + == (SVID_FLAG_INTERPOLATE | SVID_FLAG_USECURRENTPALETTE) && + SDrawGetFrameWindow()) { + HDC dc = GetDC(SDrawGetFrameWindow()); + PALETTEENTRY pe[256]; + GetSystemPaletteEntries(dc,0,256,&pe[0]); + ReleaseDC(SDrawGetFrameWindow(),dc); + CreateLinearInterpolationTable(videoptr,&pe[0]); + } + + // INITIALIZE THE EXECUTE DATA + videoptr->executedata.size = sizeof(SCODEEXECUTEDATA); + + // RETURN A HANDLE TO THE VIDEO + *handle = (HSVIDEO)videoptr; + + // CLEAR THE VIDEO SURFACE + if (flags & SVID_FLAG_CLEARSCREEN) + SDrawClearSurface(SDRAW_SURFACE_FRONT); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SVidPlayBeginFromMemory (LPVOID sourceptr, + DWORD sourcebytes, + LPVOID destbuffer, + LPCRECT destrect, + LPSIZE destsize, + SVIDPALETTEUSEPTR paletteuse, + DWORD flags, + HSVIDEO *handle) { + if (handle) + *handle = (HSVIDEO)0; + + VALIDATEBEGIN; + VALIDATE(sourceptr); + VALIDATE(sourcebytes); + VALIDATE(destbuffer || !(flags & SVID_FLAG_TOBUFFER)); + VALIDATE(destsize || !destbuffer); + VALIDATE((!paletteuse) || (paletteuse->size == sizeof(SVIDPALETTEUSE))); + VALIDATEEND; + + // SMACKER DOESN'T HAVE THE CAPABILITY TO PLAY FROM MEMORY, SO WE + // SAVE THE DATA TO A TEMPORARY FILE ON DISK AND THEN ASK SMACKER + // TO PLAY THAT. + char temppath[MAX_PATH] = "."; + char tempfilename[MAX_PATH] = ""; + GetTempPath(MAX_PATH,temppath); + GetTempFileName(temppath,"Vid",0,tempfilename); + HANDLE tempfile = CreateFile(tempfilename, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + NULL); + if (tempfile == INVALID_HANDLE_VALUE) + return FALSE; + DWORD byteswritten; + WriteFile(tempfile,sourceptr,sourcebytes,&byteswritten,NULL); + SetFilePointer(tempfile,0,NULL,FILE_BEGIN); + BOOL result = SVidPlayBegin((LPCTSTR)tempfile, + destbuffer, + destrect, + destsize, + paletteuse, + flags | SVID_FLAG_FILEHANDLE | SVID_FLAG_PRELOAD, + handle); + CloseHandle(tempfile); + DeleteFile(tempfilename); + + return result; +} + +//=========================================================================== +BOOL APIENTRY SVidPlayContinue () { + BOOL moreframes = FALSE; + VIDEOPTR currvideo = s_videolist.Head(); + while (currvideo) { + VIDEOPTR nextvideo = currvideo->Next(); + if (SVidPlayContinueSingle((HSVIDEO)currvideo,0,NULL)) + moreframes = TRUE; + currvideo = nextvideo; + } + return moreframes; +} + +//=========================================================================== +BOOL APIENTRY SVidPlayContinueSingle (HSVIDEO video, + BOOL forceupdate, + BOOL *updated) { + if (updated) + *updated = 0; + + VALIDATEBEGIN; + VALIDATE(video); + VALIDATEEND; + + if (!IsValidVideoHandle(video)) + return FALSE; + VIDEOPTR videoptr = (VIDEOPTR)video; + if (!(videoptr->smackerdata && videoptr->smackerdata->file)) + return FALSE; + + // UNLESS THE FORCE UPDATE FLAG IS ON, DO NOT PLAY THE NEXT FRAME + // UNTIL THE REQUIRED DELAY HAS ELAPSED + if ((!forceupdate) && + s_smackerapi->SmackWait(videoptr->smackerdata->file)) + return TRUE; + + // IF THE PALETTE HAS CHANGED, PROCESS THE NEW PALETTE + LPPALETTEENTRY newpalette = NULL; + if (videoptr->smackerdata->file->NewPalette && + !(videoptr->flags & SVID_FLAG_USECURRENTPALETTE)) { + if (videoptr->smackerdata->buffer) + s_smackerapi->SmackBufferNewPalette(videoptr->smackerdata->buffer, + videoptr->smackerdata->file->Palette, + 0); + PALETTEENTRY pe[256]; + int index = 0; + for (int loop = 0; loop < 256; ++loop) { + pe[loop].peRed = videoptr->smackerdata->file->Palette[index++]; + pe[loop].peGreen = videoptr->smackerdata->file->Palette[index++]; + pe[loop].peBlue = videoptr->smackerdata->file->Palette[index++]; + } + newpalette = &pe[0]; + if (videoptr->flags & SVID_FLAG_CLEARSCREEN) + SDrawClearSurface(SDRAW_SURFACE_FRONT); + if ((videoptr->flags & (SVID_FLAG_2XSIZE | SVID_FLAG_DOUBLESCANS)) == SVID_FLAG_2XSIZE) + AdjustGamma(newpalette,0.8); + if (videoptr->flags & SVID_FLAG_INTERPOLATE) + CreateLinearInterpolationTable(videoptr,newpalette); + } + + // UNCOMPRESS THE FRAME AND SET ITS PALETTE + BOOL skip; + if (videoptr->flags & SVID_FLAG_2XSIZE) { + skip = s_smackerapi->SmackDoFrame(videoptr->smackerdata->file); + if (newpalette) + SDrawUpdatePalette(videoptr->palettefirstentry, + videoptr->palettenumentries, + newpalette+videoptr->palettefirstentry); + } + else { + if (newpalette) + SDrawUpdatePalette(videoptr->palettefirstentry, + videoptr->palettenumentries, + newpalette+videoptr->palettefirstentry); + skip = ProcessFrameDirect(videoptr); + } + if (updated && !skip) + *updated = TRUE; + + // IF WE JUST SKIPPED A FRAME AND STORM IS IN CHARGE OF SETTING THE + // QUALITY, DEGRADE THE CURRENT QUALITY SETTING + if (skip) + if (videoptr->flags & SVID_FLAG_INTERPOLATE) { + videoptr->flags &= ~SVID_FLAG_INTERPOLATE; + videoptr->vertinterp = FALSE; + } + else + videoptr->flags |= SVID_FLAG_INTERLACE; + + // IF THIS FRAME WAS NOT SKIPPED AND WAS NOT UNCOMPRESSED DIRECTLY + // ONTO THE SCREEN, UPDATE THE SCREEN + if ((videoptr->flags & SVID_FLAG_2XSIZE) && !skip) + ProcessFrameEffects(videoptr); + + // STEP TO THE NEXT FRAME, AND RETURN A BOOLEAN TELLING WHETHER THERE + // ARE MORE FRAMES TO BE PROCESSED + if ((videoptr->smackerdata->file->FrameNum+1 < videoptr->smackerdata->file->Frames) || + (videoptr->flags & SVID_FLAG_LOOP)) { + s_smackerapi->SmackNextFrame(videoptr->smackerdata->file); + return TRUE; + } + else { + SVidPlayEnd((HSVIDEO)videoptr); + return FALSE; + } +} + +//=========================================================================== +BOOL APIENTRY SVidPlayEnd (HSVIDEO video) { + VALIDATEBEGIN; + VALIDATE(video); + VALIDATEEND; + + if (!IsValidVideoHandle(video)) + return FALSE; + VIDEOPTR videoptr = (VIDEOPTR)video; + if (!videoptr->smackerdata) + return FALSE; + + // CLOSE THE FILE + if (videoptr->smackerdata->buffer) + s_smackerapi->SmackBufferClose(videoptr->smackerdata->buffer); + if (videoptr->smackerdata->file) + s_smackerapi->SmackClose(videoptr->smackerdata->file); + FREE(videoptr->smackerdata); + videoptr->smackerdata = NULL; + if (videoptr->filehandle != INVALID_HANDLE_VALUE) { + CloseHandle(videoptr->filehandle); + videoptr->filehandle = INVALID_HANDLE_VALUE; + } + + // DELETE THE INTERPOLATION TABLE + if (videoptr->interptable) { + FREE(videoptr->interptable); + videoptr->interptable = NULL; + videoptr->executedata.table = NULL; + } + + // DELETE THE ARRAY OF RECTANGLES + FREEIFUSED(videoptr->rect); + + // REMOVE THE VIDEO RECORD FROM OUR LIST + s_videolist.DeleteNode(videoptr); + + return TRUE; +} + +//=========================================================================== +BOOL APIENTRY SVidSetVolume (HSVIDEO video, + LONG volume, + LONG pan, + DWORD track) { + VALIDATEBEGIN; + VALIDATE(video); + VALIDATEEND; + + if (!IsValidVideoHandle(video)) + return FALSE; + VIDEOPTR videoptr = (VIDEOPTR)video; + if (!videoptr->smackerdata) + return FALSE; + + // CONVERT THE VOLUME AND PAN PARAMETERS TO SMACKER FORMAT + DWORD smackervolume = (DWORD)(volume+10000)*65536/20000; + DWORD smackerpan = (DWORD)(pan +10000)*65536/20000; + + // CONVERT THE TRACK PARAMETER TO SMACKER FORMAT + DWORD smackertracks; + switch (track) { + case 1: smackertracks = SMACKTRACK1; break; + case 2: smackertracks = SMACKTRACK2; break; + case 3: smackertracks = SMACKTRACK3; break; + case 4: smackertracks = SMACKTRACK4; break; + case 5: smackertracks = SMACKTRACK5; break; + case 6: smackertracks = SMACKTRACK6; break; + case 7: smackertracks = SMACKTRACK7; break; + default: smackertracks = SMACKTRACKS; break; + } + + // CALL SMACKER TO SET THE VOLUME AND PAN FOR THE REQUESTED TRACK(S) + s_smackerapi->SmackVolumePan(videoptr->smackerdata->file, + smackertracks, + smackervolume, + smackerpan); + + return TRUE; +} diff --git a/Storm/SOURCE/SYSPAL.PCX b/Storm/SOURCE/SYSPAL.PCX new file mode 100644 index 0000000..fe66a80 Binary files /dev/null and b/Storm/SOURCE/SYSPAL.PCX differ diff --git a/Storm/SOURCE/WIN32.CS b/Storm/SOURCE/WIN32.CS new file mode 100644 index 0000000..a72e225 --- /dev/null +++ b/Storm/SOURCE/WIN32.CS @@ -0,0 +1,46 @@ +// IF THE USER TRIES TO RUN THIS SCRIPT DIRECTLY, INSTEAD OF USING THIS +// SCRIPT BY INCLUDING IT FROM ANOTHER ONE, DISPLAY AN ERROR +if not %project%==win32 goto start +echo You must specify a project script. +echo Type "C /?" for help. +halt +:start + +// SET UP AUTO-DEPENDENCY CHECKING +set -autodependencies =.c;.cpp;.h;.hpp +set -ignoredependencies=windows.h;windowsx.h;ole2.h;rpc.h;ddraw.h;dsound.h + +// SET THE DEFAULT COMMAND LINE OPTIONS FOR THE COMPILER AND LINKER +if %debug% set clopt=-D_DEBUG -Zi +if %debug% set linkopt=-debug -debugtype:cv -pdb:none +if %debug% set crtlib=libcmtd.lib +if %debug% set debugchar=d +if not %debug% set clopt=-DNDEBUG -Ox -GBFry +if not %debug% set crtlib=libcmt.lib +if not %debug% set debugchar= +set mlopt=-Cx +set subsystem=windows +set baselib=%baselib% kernel32.lib user32.lib gdi32.lib advapi32.lib + +// CREATE A TEMPORARY DIRECTORY TO USE FOR PRECOMPILED HEADERS +if not exist %temp%\pch\. md %temp%\pch +if not exist %temp%\pch\%username%\. md %temp%\pch\%username% +set precompileddir=%temp%\pch\%username% + +// SET THE DEFAULT BUILD RULES +set .asm=.obj +set .c =.obj +set .cpp=.obj +set .def=.exp +set .rc =.res +if exist %project%.def set .obj=.dll +if exist %project%.def set deffile=%project%.def +if not exist %project%.def set .obj=.exe +set .asm.obj=ml -nologo -c -coff %mlopt% %file% +set .c.obj =cl -nologo -c -D_X86_ -D_MT -DWIN32 %clopt% -W3 -Fp%precompileddir%\%project%.pch -YX %file% +set .cpp.obj=cl -nologo -c -D_X86_ -D_MT -DWIN32 %clopt% -W3 -Fp%precompileddir%\%project%.pch -YX %file% +set .def.exp=lib -nologo -machine:i386 -def:%deffile% -name:%project%.dll -out:%project%.lib *.obj +set .rc.res =rc -r %rcopt% %file% +set .obj.lib=lib -nologo -machine:i386 -out:%project%.lib *.obj *.res %extralib% +set .obj.dll=link -nologo -machine:i386 -subsystem:%subsystem% %linkopt% -map -dll -out:%project%.dll *.obj *.res %project%.exp %extraobj% -nod %crtlib% %baselib% %extralib% +set .obj.exe=link -nologo -machine:i386 -subsystem:%subsystem% %linkopt% -map -out:%project%.exe *.obj *.res %extraobj% -nod %crtlib% %baselib% %extralib% diff --git a/Storm/SOURCE/ddraw/DirectDrawClipperWrapper.cpp b/Storm/SOURCE/ddraw/DirectDrawClipperWrapper.cpp new file mode 100644 index 0000000..d5cd692 --- /dev/null +++ b/Storm/SOURCE/ddraw/DirectDrawClipperWrapper.cpp @@ -0,0 +1,245 @@ +#include "DirectDrawWrapper.h" + +/******************* +**IUnknown methods** +********************/ + +// Retrieves pointers to the supported interfaces on an object. +HRESULT __stdcall IDirectDrawClipperWrapper::QueryInterface(REFIID riid, LPVOID FAR * ppvObj) +{ + debugMessage(1, "IDirectDrawClipperWrapper::QueryInterface", "Partially Implemented"); + + // Provide the directdraw interface for all versions up to 7 + if(riid == IID_IDirectDrawClipper) + { + // Set pointer to this interface + ppvObj = (LPVOID *)this; + // Increment reference count + AddRef(); + // Return success + return S_OK; + } + + // Interface not supported + return E_NOINTERFACE; +} + +// Increments the reference count for an interface on an object. +ULONG __stdcall IDirectDrawClipperWrapper::AddRef() +{ + debugMessage(1, "IDirectDrawClipperWrapper::AddRef", "Partially Implemented"); + + // Increment reference count + ReferenceCount++; + // Return current reference count + return ReferenceCount; +} + +// Decrements the reference count for an interface on an object. +ULONG __stdcall IDirectDrawClipperWrapper::Release() +{ + debugMessage(1, "IDirectDrawClipperWrapper::Release", "Partially Implemented"); + + // Decrement reference count + ReferenceCount--; + // If reference count reaches 0 then free object + if(ReferenceCount == 0) + { + // Free objects here, skip for now + } + // Return new reference count + return ReferenceCount; +} + +/***************************** +**IDirectDrawClipper methods** +******************************/ + +// Retrieves a copy of the clip list that is associated with a DirectDrawClipper +// object. To select a subset of the clip list, you can pass a rectangle that clips +// the clip list. +HRESULT __stdcall IDirectDrawClipperWrapper::GetClipList(LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize) +{ + // ***Unimplemented*** + debugMessage(0, "IDirectDrawClipperWrapper::GetClipList", "Not Implemented"); + + if(lpClipList == NULL) + { + if(lpRect == NULL) { + // lpdwSize = memory required to hold entire clip list + } + else + { + // lpdwSize = memory required to clip list in region lpRect + } + } + else + { + if(lpRect == NULL) { + // lpClipList = RGNDATA structure that receives the resulting copy of the entire clip list. + } + else + { + // lpClipList = RGNDATA structure that receives the resulting copy of the clip list in region lpRect + } + + } + + return DDERR_GENERIC; + + /* + DDERR_GENERIC + DDERR_INVALIDCLIPLIST + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOCLIPLIST + DDERR_REGIONTOOSMALL + */ +} + +// Retrieves the window handle that was previously associated with this +// DirectDrawClipper object by the IDirectDrawClipper::SetHWnd method. +HRESULT __stdcall IDirectDrawClipperWrapper::GetHWnd(HWND FAR *lphWnd) +{ + debugMessage(1, "IDirectDrawClipperWrapper::GetHWnd", "Partially Implemented"); + + // lphWnd cannot be null + if(lphWnd == NULL) return DDERR_INVALIDPARAMS; + + // Set lphWnd to associated window handle + *lphWnd = hWnd; + + // Success + return DD_OK; +} + +// Initializes a DirectDrawClipper object that was created by using the +// CoCreateInstance COM function. +HRESULT __stdcall IDirectDrawClipperWrapper::Initialize(LPDIRECTDRAW lpDD, DWORD dwFlags) +{ + debugMessage(1, "IDirectDrawClipperWrapper::Initialize", "Partially Implemented"); + if(lpDD == NULL) + { + // An independent DirectDrawClipper object is initialized; a call of this + // type is equivalent to using the DirectDrawCreateClipper function. + } + else + { + // Call constructor + } + + // Overload to already init + return DDERR_ALREADYINITIALIZED; + + /* + DDERR_ALREADYINITIALIZED + DDERR_INVALIDPARAMS + */ +} + +// Retrieves the status of the clip list if a window handle is associated +// with a DirectDrawClipper object. +HRESULT __stdcall IDirectDrawClipperWrapper::IsClipListChanged(BOOL FAR *lpbChanged) +{ + // ***Unimplemented*** + debugMessage(0, "IDirectDrawClipperWrapper::Initialize", "Not Implemented"); + + // lpbChanged cannot be null + if(lpbChanged == NULL) return DDERR_INVALIDPARAMS; + + // lpbChanged is TRUE if the clip list has changed, and FALSE otherwise. + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + */ +} + +// Sets or deletes the clip list that is used by the IDirectDrawSurface7::Blt, +// IDirectDrawSurface7::BltBatch, and IDirectDrawSurface7::UpdateOverlay methods +// on surfaces to which the parent DirectDrawClipper object is attached. +HRESULT __stdcall IDirectDrawClipperWrapper::SetClipList(LPRGNDATA lpClipList, DWORD dwFlags) +{ + // ***Unimplemented*** + debugMessage(0, "IDirectDrawClipperWrapper::SetClipList", "Not Implemented"); + + //You cannot set the clip list if a window handle is already associated + // with the DirectDrawClipper objet. + if(hasHwnd) + { + return DDERR_CLIPPERISUSINGHWND; + } + + // ******NOTE: If you call IDirectDrawSurface7::BltFast on a surface with an attached + // clipper, it returns DDERR_UNSUPPORTED. + if(lpClipList == NULL) + { + // Delete associated clip list if it exists + } + else + { + // Set clip list to lpClipList + } + + return DDERR_GENERIC; + + /* + DDERR_INVALIDCLIPLIST + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_OUTOFMEMORY + */ +} + +// Sets the window handle that the clipper object uses to obtain clipping information +HRESULT __stdcall IDirectDrawClipperWrapper::SetHWnd(DWORD dwFlags, HWND in_hWnd) +{ + debugMessage(1, "IDirectDrawClipperWrapper::SetHWnd", "Partially Implemented"); + + hasHwnd = true; + hWnd = in_hWnd; + + // Load clip list from window + + return DD_OK; + + /* + DDERR_INVALIDCLIPLIST + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_OUTOFMEMORY + */ +} + +// Default constructor +IDirectDrawClipperWrapper::IDirectDrawClipperWrapper() +{ + // Init variables + hasHwnd = false; + hWnd = NULL; + + ReferenceCount = 0; + + // Add reference + AddRef(); + + debugMessage(2, "IDirectDrawClipperWrapper::IDirectDrawClipperWrapper", "Created"); +} + +// Default destructor +IDirectDrawClipperWrapper::~IDirectDrawClipperWrapper() +{ + // Release reference + Release(); + + debugMessage(2, "IDirectDrawClipperWrapper::~IDirectDrawClipperWrapper", "Destroyed"); +} + +// Initialize wrapper function +HRESULT IDirectDrawClipperWrapper::WrapperInitialize(DWORD dwFlags) +{ + debugMessage(2, "IDirectDrawClipperWrapper::WrapperInitialize", "Initialized"); + return DD_OK; +} \ No newline at end of file diff --git a/Storm/SOURCE/ddraw/DirectDrawPaletteWrapper.cpp b/Storm/SOURCE/ddraw/DirectDrawPaletteWrapper.cpp new file mode 100644 index 0000000..3eb89d1 --- /dev/null +++ b/Storm/SOURCE/ddraw/DirectDrawPaletteWrapper.cpp @@ -0,0 +1,288 @@ +#include "DirectDrawWrapper.h" + +/******************* +**IUnknown methods** +********************/ + +// Retrieves pointers to the supported interfaces on an object. +HRESULT __stdcall IDirectDrawPaletteWrapper::QueryInterface(REFIID riid, LPVOID FAR * ppvObj) +{ + debugMessage(1, "IDirectDrawPaletteWrapper::QueryInterface", "Partially Implemented"); + + // Provide the directdraw interface for all versions up to 7 + if(riid == IID_IDirectDrawPalette) + { + // Set pointer to this interface + ppvObj = (LPVOID *)this; + // Increment reference count + AddRef(); + // Return success + return S_OK; + } + + // Interface not supported + return E_NOINTERFACE; +} + +// Increments the reference count for an interface on an object. +ULONG __stdcall IDirectDrawPaletteWrapper::AddRef() +{ + debugMessage(1, "IDirectDrawPaletteWrapper::AddRef", "Partially Implemented"); + + // Increment reference count + ReferenceCount++; + // Return current reference count + return ReferenceCount; +} + +// Decrements the reference count for an interface on an object. +ULONG __stdcall IDirectDrawPaletteWrapper::Release() +{ + debugMessage(1, "IDirectDrawPaletteWrapper::Release", "Partially Implemented"); + + // Decrement reference count + ReferenceCount--; + // If reference count reaches 0 then free object + if(ReferenceCount == 0) + { + // Free objects + if(rawPalette != NULL) delete rawPalette; + if(rgbPalette != NULL) delete rgbPalette; + } + // Return new reference count + return ReferenceCount; +} + +/***************************** +**IDirectDrawPalette methods** +******************************/ + +// Retrieves the capabilities of the palette object. +HRESULT __stdcall IDirectDrawPaletteWrapper::GetCaps(LPDWORD lpdwCaps) +{ + debugMessage(1, "IDirectDrawPaletteWrapper::GetCaps", "Partially Implemented"); + + // lpdwCaps cannot be null + if(lpdwCaps == NULL) return DDERR_INVALIDPARAMS; + + // set return data to current palette caps + *lpdwCaps = paletteCaps; + + return DD_OK; +} + +// Retrieves palette values from a DirectDrawPalette object. +HRESULT __stdcall IDirectDrawPaletteWrapper::GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) +{ + // lpEntries cannot be null and dwFlags must be 0 + if(lpEntries == NULL) return DDERR_INVALIDPARAMS; + + // Copy raw palette entries to lpEntries(size dwNumEntries) starting at dwBase + memcpy(lpEntries, &(rawPalette[dwBase]), sizeof(PALETTEENTRY) * min(dwNumEntries, entryCount - dwBase)); + + /* + // NOTE: Debugging disabled for performance + debugMessage(2, "IDirectDrawPaletteWrapper::GetEntries", "Retrieved Palette Entries"); + + char message[2048] = "\0"; + sprintf_s(message, 2048, "dwBase: %d, dwNumEntries: %d", dwBase, dwNumEntries); + debugMessage(2, "IDirectDrawPaletteWrapper::GetEntries", message); + */ + + // dwNumEntries is the number of palette entries that can fit in the array that lpEntries + // specifies. The colors of the palette entries are returned in sequence, from the value + // of the dwStartingEntry parameter through the value of the dwCount parameter minus 1. + // (These parameters are set by IDirectDrawPalette::SetEntries.) + + return DD_OK; +} + +// Initializes the DirectDrawPalette object. +HRESULT __stdcall IDirectDrawPaletteWrapper::Initialize(LPDIRECTDRAW lpDDW, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable) +{ + debugMessage(1, "IDirectDrawPaletteWrapper::Initialize", "Partially Implemented"); + + // This method always returns already initialized + return DDERR_ALREADYINITIALIZED; +} + +// Changes entries in a DirectDrawPalette object immediately. +HRESULT __stdcall IDirectDrawPaletteWrapper::SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) +{ + // lpEntries cannot be null and dwFlags must be 0 + if(lpEntries == NULL) return DDERR_INVALIDPARAMS; + + // Copy raw palette entries from dwStartingEntry and of count dwCount + memcpy(&(rawPalette[dwStartingEntry]), lpEntries, sizeof(PALETTEENTRY) * min(dwCount, entryCount - dwStartingEntry)); + + // Translate new raw pallete entries to RGB(make sure not to go off the end of the memory) + for(int i = dwStartingEntry; i < min(dwStartingEntry + dwCount, entryCount - dwStartingEntry); i++) + { + // Translate the raw palette to ARGB + if(hasAlpha) + { + // Include peFlags as 8bit alpha + rgbPalette[i] = rawPalette[i].peFlags << 24; + rgbPalette[i] |= rawPalette[i].peRed << 16; + rgbPalette[i] |= rawPalette[i].peGreen << 8; + rgbPalette[i] |= rawPalette[i].peBlue; + } + else + { + // Alpha is always 255 + rgbPalette[i] = 0xFF000000; + rgbPalette[i] |= rawPalette[i].peRed << 16; + rgbPalette[i] |= rawPalette[i].peGreen << 8; + rgbPalette[i] |= rawPalette[i].peBlue; + } + } + + /* + // NOTE: Debugging disabled for performance + debugMessage(2, "IDirectDrawPaletteWrapper::SetEntries", "Set Palette Entries"); + + char message[2048] = "\0"; + sprintf_s(message, 2048, "dwStartingEntry: %d, dwCount: %d", dwStartingEntry, dwCount); + debugMessage(2, "IDirectDrawPaletteWrapper::SetEntries", message); */ + + return DD_OK; +} + +// Default constructor +IDirectDrawPaletteWrapper::IDirectDrawPaletteWrapper() +{ + // Init vars + rgbPalette = NULL; + rawPalette = NULL; + + ReferenceCount = 0; + paletteCaps = 0; + + entryCount = 0; + hasAlpha = false; + + // Create with flags + AddRef(); + + debugMessage(2, "IDirectDrawPaletteWrapper::IDirectDrawPaletteWrapper", "Created"); +} + +// Default destructor +IDirectDrawPaletteWrapper::~IDirectDrawPaletteWrapper() +{ + // Free used memory + if(rgbPalette != NULL) + { + delete rgbPalette; + rgbPalette = NULL; + } + if(rawPalette != NULL) + { + delete rawPalette; + rawPalette = NULL; + } + + // Clean up + Release(); + + debugMessage(2, "IDirectDrawPaletteWrapper::~IDirectDrawPaletteWrapper", "Destroyed"); +} + +// Initialize wrapper function +HRESULT IDirectDrawPaletteWrapper::WrapperInitialize(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR *lplpDDPalette) +{ + // Save palette caps + paletteCaps = dwFlags; + + // Default to 256 entries + entryCount = 256; + + // Create palette of requested bit size + if(dwFlags & DDPCAPS_1BIT) + { + entryCount = 2; + } + else if(dwFlags & DDPCAPS_2BIT) + { + entryCount = 4; + } + else if(dwFlags & DDPCAPS_4BIT) + { + entryCount = 16; + } + else if(dwFlags & DDPCAPS_8BIT || dwFlags & DDPCAPS_ALLOW256) + { + entryCount = 256; + } + + // Allocate raw ddraw palette + rawPalette = new PALETTEENTRY[entryCount]; + // Memory failed to allocate, return out of memory + if(rawPalette == NULL) + { + debugMessage(0, "IDirectDrawPaletteWrapper::WrapperInitialize", "Failed to allocate raw palette memory"); + return DDERR_OUTOFMEMORY; + } + + // Copy inital palette into raw palette + memcpy(rawPalette, lpDDColorArray, sizeof(PALETTEENTRY) * entryCount); + + // Check flags for alpha + if(dwFlags & DDPCAPS_ALPHA) + { + hasAlpha = true; + } + else + { + hasAlpha = false; + } + + // Allocate rgb palette + rgbPalette = new UINT32[entryCount]; + // Memory failed to allocate, return out of memory + if(rgbPalette == NULL) + { + debugMessage(0, "IDirectDrawPaletteWrapper::WrapperInitialize", "Failed to allocate RGB palette memory"); + return DDERR_OUTOFMEMORY; + } + + // For all entries + for(int i = 0; i < entryCount; i++) + { + // Translate the raw palette to ARGB + if(hasAlpha) + { + // Include peFlags as 8bit alpha + rgbPalette[i] = rawPalette[i].peFlags << 24; + rgbPalette[i] |= rawPalette[i].peRed << 16; + rgbPalette[i] |= rawPalette[i].peGreen << 8; + rgbPalette[i] |= rawPalette[i].peBlue; + } + else + { + // Alpha is always 255 + rgbPalette[i] = 0xFF000000; + rgbPalette[i] |= rawPalette[i].peRed << 16; + rgbPalette[i] |= rawPalette[i].peGreen << 8; + rgbPalette[i] |= rawPalette[i].peBlue; + } + } + + char message[2048] = "\0"; + sprintf_s(message, 2048, "Initialized"); + if(dwFlags & DDPCAPS_1BIT) strcat_s(message, 2048, ", DDPCAPS_1BIT"); + if(dwFlags & DDPCAPS_2BIT) strcat_s(message, 2048, ", DDPCAPS_2BIT"); + if(dwFlags & DDPCAPS_4BIT) strcat_s(message, 2048, ", DDPCAPS_4BIT"); + if(dwFlags & DDPCAPS_8BIT) strcat_s(message, 2048, ", DDPCAPS_8BIT"); + if(dwFlags & DDPCAPS_8BITENTRIES) strcat_s(message, 2048, ", DDPCAPS_8BITENTRIES"); + if(dwFlags & DDPCAPS_ALPHA) strcat_s(message, 2048, ", DDPCAPS_ALPHA"); + if(dwFlags & DDPCAPS_ALLOW256) strcat_s(message, 2048, ", DDPCAPS_ALLOW256"); + if(dwFlags & DDPCAPS_INITIALIZE) strcat_s(message, 2048, ", DDPCAPS_INITIALIZE"); + if(dwFlags & DDPCAPS_PRIMARYSURFACE) strcat_s(message, 2048, ", DDPCAPS_PRIMARYSURFACE"); + if(dwFlags & DDPCAPS_PRIMARYSURFACELEFT) strcat_s(message, 2048, ", DDPCAPS_PRIMARYSURFACELEFT"); + if(dwFlags & DDPCAPS_VSYNC) strcat_s(message, 2048, ", DDPCAPS_VSYNC"); + debugMessage(2, "IDirectDrawPaletteWrapper::WrapperInitialize", message); + + // Success + return DD_OK; +} \ No newline at end of file diff --git a/Storm/SOURCE/ddraw/DirectDrawSurfaceWrapper.cpp b/Storm/SOURCE/ddraw/DirectDrawSurfaceWrapper.cpp new file mode 100644 index 0000000..1e63369 --- /dev/null +++ b/Storm/SOURCE/ddraw/DirectDrawSurfaceWrapper.cpp @@ -0,0 +1,1693 @@ +#include "DirectDrawWrapper.h" +#include + +/******************* +**IUnknown methods** +********************/ + +// Retrieves pointers to the supported interfaces on an object. +HRESULT __stdcall IDirectDrawSurfaceWrapper::QueryInterface(REFIID riid, LPVOID FAR * ppvObj) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::QueryInterface", "Partially Implemented"); + + // Provide the directdraw interface for all versions up to 7 + if(riid == IID_IDirectDrawPalette) + { + // Set pointer to this interface + ppvObj = (LPVOID *)this; + // Increment reference count + AddRef(); + // Return success + return S_OK; + } + + // Interface not supported + return E_NOINTERFACE; +} + +// Increments the reference count for an interface on an object. +ULONG __stdcall IDirectDrawSurfaceWrapper::AddRef() +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::AddRef", "Partially Implemented"); + + // Increment reference count + ReferenceCount++; + // Return current reference count + return ReferenceCount; +} + +// Decrements the reference count for an interface on an object. +ULONG __stdcall IDirectDrawSurfaceWrapper::Release() +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::Release", "Partially Implemented"); + + // Decrement reference count + ReferenceCount--; + // If reference count reaches 0 then free object + if(ReferenceCount == 0) + { + //Free objects + } + // Return new reference count + return ReferenceCount; +} + +/***************************** +**IDirectDrawSurface methods** +******************************/ + +// Attaches the specified z-buffer surface to this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSurface) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::Release", "Not Implemented"); + + //lpDDSurface cannot be null + if(lpDDSurface == NULL) return DDERR_INVALIDPARAMS; + + // Attach z-buffer lpDDSurface to this surface + + // Increment ref count + //((IDirectDrawSurfaceWrapper*)lpDDSurface)->AddRef(); + + return DDERR_GENERIC; + + /* + DDERR_CANNOTATTACHSURFACE + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_SURFACEALREADYATTACHED + DDERR_SURFACELOST + DDERR_WASSTILLDRAWING + */ +} + +// The IDirectDrawSurface7::AddOverlayDirtyRect method is not currently implemented. +HRESULT __stdcall IDirectDrawSurfaceWrapper::AddOverlayDirtyRect(LPRECT lpRect) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::Release", "Unsupported in DirectDraw"); + return DDERR_UNSUPPORTED; +} + +// Performs a bit block transfer (bitblt). This method does not support z-buffering +// or alpha blending during bitblt operations. +HRESULT __stdcall IDirectDrawSurfaceWrapper::Blt(LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::Blt", "Not Implemented"); + + //lpDDSrcSurface cannot be null + if(lpDDSrcSurface == NULL) return DDERR_INVALIDPARAMS; + + //DDBLT_ALPHA and DDBLT_ZBUFFER flags are unsupported + if(dwFlags & DDBLT_ZBUFFER) return DDERR_UNSUPPORTED; + + RECT destRect; + if(lpDestRect == NULL) + { + // Fill destRect with bounds of this surface + } + else + { + // Copy dest rect + memcpy(&destRect, lpDestRect, sizeof(RECT)); + } + RECT srcRect; + if(lpSrcRect == NULL) + { + // Fill srcRect with bounds of lpDDSrcSurface + } + else + { + // Copy source rect + memcpy(&srcRect, lpSrcRect, sizeof(RECT)); + } + + /* + DDBLT_COLORFILL + Uses the dwFillColor member of the DDBLTFX structure as the RGB color that fills the destination rectangle on the destination surface. + + DDBLT_DDFX + Uses the dwDDFX member of the DDBLTFX structure to specify the effects to use for this bitblt. + + DDBLT_DDROPS + Uses the dwDDROP member of the DDBLTFX structure to specify the raster operations (ROPS) that are not part of the Win32 API. + + DDBLT_DEPTHFILL + Uses the dwFillDepth member of the DDBLTFX structure as the depth value with which to fill the destination rectangle on the destination z-buffer surface. + + DDBLT_KEYDESTOVERRIDE + Uses the ddckDestColorkey member of the DDBLTFX structure as the color key for the destination surface. + + DDBLT_KEYSRCOVERRIDE + Uses the ddckSrcColorkey member of the DDBLTFX structure as the color key for the source surface. + + DDBLT_ROP + Uses the dwROP member of the DDBLTFX structure for the ROP for this bitblt. These ROPs are the same as those defined in the Win32 API. + + DDBLT_ROTATIONANGLE + Uses the dwRotationAngle member of the DDBLTFX structure as the rotation angle (specified in 1/100s of a degree) for the surface. + + *Color key flags* + DDBLT_KEYDEST + Uses the color key that is associated with the destination surface. + + DDBLT_KEYSRC + Uses the color key that is associated with the source surface. + + *Behavior flags* + DDBLT_ASYNC + Performs this bitblt asynchronously through the first in, first out (FIFO) hardware in the order received. If no room is available in the FIFO hardware, the call fails. + + DDBLT_DONOTWAIT + Returns without bitbltting and also returns DDERR_WASSTILLDRAWING if the bitbltter is busy. + + DDBLT_WAIT + Postpones the DDERR_WASSTILLDRAWING return value if the bitbltter is busy, and returns as soon as the bitblt can be set up or another error occurs + */ + + return DDERR_GENERIC; + + /* + DDERR_GENERIC + DDERR_INVALIDCLIPLIST + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDRECT + DDERR_NOALPHAHW + DDERR_NOBLTHW + DDERR_NOCLIPLIST + DDERR_NODDROPSHW + DDERR_NOMIRRORHW + DDERR_NORASTEROPHW + DDERR_NOROTATIONHW + DDERR_NOSTRETCHHW + DDERR_NOZBUFFERHW + DDERR_SURFACEBUSY + DDERR_SURFACELOST + DDERR_UNSUPPORTED + DDERR_WASSTILLDRAWING + */ +} + +// The IDirectDrawSurface7::BltBatch method is not currently implemented. +HRESULT __stdcall IDirectDrawSurfaceWrapper::BltBatch(LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::BltBatch", "Unsupported in DirectDraw"); + return DDERR_UNSUPPORTED; +} + +// Performs a source copy bitblt or transparent bitblt by using a source color +// key or destination color key. (no scaling) +HRESULT __stdcall IDirectDrawSurfaceWrapper::BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::BltFast", "Not Implemented"); + + if(lpDDSrcSurface == NULL) return DDERR_INVALIDPARAMS; + + // BltFast works only on display memory surfaces and cannot clip when + // it performs a bitblt operation. If you use this method on a surface + // with an attached clipper, the call fails, and the method returns DDERR_UNSUPPORTED. + + /* + DDBLTFAST_DESTCOLORKEY + A transparent bitblt that uses the destination color key. + + DDBLTFAST_NOCOLORKEY + A normal copy bitblt with no transparency. + + DDBLTFAST_SRCCOLORKEY + A transparent bitblt that uses the source color key. + + DDBLTFAST_WAIT + Postpones the DDERR_WASSTILLDRAWING message if the bitbltter is busy, and returns as soon as the bitblt can be set up or another error occurs + */ + + return DDERR_GENERIC; + + /* + DDERR_EXCEPTION + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDRECT + DDERR_NOBLTHW + DDERR_SURFACEBUSY + DDERR_SURFACELOST + DDERR_UNSUPPORTED + DDERR_WASSTILLDRAWING + */ +} + +// Detaches one or more attached surfaces. +HRESULT __stdcall IDirectDrawSurfaceWrapper::DeleteAttachedSurface(DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::DeleteAttachedSurface", "Not Implemented"); + + if(lpDDSAttachedSurface == NULL) + { + // Unattach all surfaces and decrement ref counts + } + else + { + // Unattach lpDDSAttachedSurface and decrement ref count + } + + /* + Implicit attachments, those formed by DirectDraw rather than the IDirectDrawSurface7::AddAttachedSurface + method, cannot be detached. + + Detaching surfaces from a flipping chain can alter other surfaces in the chain. If a front buffer is detached from + a flipping chain, the next surface in the chain becomes the front buffer, and the following surface becomes the back + buffer. If a back buffer is detached from a chain, the following surface becomes a back buffer. If a plain surface + is detached from a chain, the chain simply becomes shorter. If a flipping chain has only two surfaces and they are + detached, the chain is destroyed, and both surfaces return to their previous designation + */ + + return DDERR_GENERIC; + + /* + DDERR_CANNOTDETACHSURFACE + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_SURFACELOST + DDERR_SURFACENOTATTACHED + */ +} + +// Enumerates all the surfaces that are attached to this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::EnumAttachedSurfaces(LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::EnumAttachedSurfaces", "Not Implemented"); + + if(lpEnumSurfacesCallback == NULL) return DDERR_INVALIDPARAMS; + + //for each surface attached to this surface + //{ + //HRESULT res = lpEnumSurfacesCallback(current surface interface, DDSURFACEDESC2 of the current surface, lpContext); + //if(res == DDENUMRET_CANCEL) break; + //} + + /* + EnumAttachedSurfaces enumerates only those surfaces that are directly attached to this surface. For example, in a flipping + chain of three or more surfaces, only one surface is enumerated because each surface is attached only to the next surface + in the flipping chain. In such a configuration, you can call EnumAttachedSurfaces on each successive surface to walk the + entire flipping chain. + + EnumAttachedSurfaces differs from its counterparts in previous interface versions in that it accepts a pointer to an + EnumSurfacesCallback7 function, rather than an EnumSurfacesCallback or EnumSurfacesCallback2 function. + */ + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_SURFACELOST + */ +} + +// Enumerates the overlay surfaces on the specified destination. You can enumerate the overlays +// in front-to-back or back-to-front order. +HRESULT __stdcall IDirectDrawSurfaceWrapper::EnumOverlayZOrders(DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::EnumOverlayZOrders", "Not Implemented"); + + if(lpfnCallback == NULL) return DDERR_INVALIDPARAMS; + + /* + DDENUMOVERLAYZ_BACKTOFRONT + Enumerates overlays back to front. + + DDENUMOVERLAYZ_FRONTTOBACK + Enumerates overlays front to back. + */ + + //for each overlay surface attached to this surface + //{ + //HRESULT res = lpEnumSurfacesCallback(current surface interface, DDSURFACEDESC2 of the current surface, lpContext); + //if(res == DDENUMRET_CANCEL) break; + //} + + return DDERR_GENERIC; + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + */ +} + +// Makes the surface memory that is associated with the DDSCAPS_BACKBUFFER surface become associated +// with the front-buffer surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DWORD dwFlags) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::Flip", "Not Implemented"); + + if(lpDDSurfaceTargetOverride == NULL) + { + //flip to next buffer in the chain + } + else + { + //flip to surfacelpDDSurfaceTargetOverride + } + + /* + DDFLIP_DONOTWAIT + On IDirectDrawSurface7 interfaces, the default is DDFLIP_WAIT. If you want to override the default and use time when the + accelerator is busy (as denoted by the DDERR_WASSTILLDRAWING return value), use DDFLIP_DONOTWAIT. + + DDFLIP_EVEN + For use only when displaying video in an overlay surface. The new surface contains data from the even field of a video signal. + This flag cannot be used with the DDFLIP_ODD flag. + + DDFLIP_STEREO + DirectDraw flips and displays a main stereo surface. When this flag is set, stereo autoflipping is enabled. + The hardware automatically flips between the left and right buffers during each screen refresh. + + DDFLIP_INTERVAL2 + DDFLIP_INTERVAL3 + DDFLIP_INTERVAL4 + The DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, and DDFLIP_INTERVAL4 flags indicate how many vertical retraces to wait between each flip. The default is 1. + DirectDraw returns DERR_WASSTILLDRAWING for each surface involved in the flip until the specified number of vertical retraces has occurred. + If DDFLIP_INTERVAL2 is set, DirectDraw flips on every second vertical sync; if DDFLIP_INTERVAL3, on every third sync; and if DDFLIP_INTERVAL4, + on every fourth sync. + These flags are effective only if DDCAPS2_FLIPINTERVAL bit is set in the dwCaps2 member of the DDCAPS structure that is returned for the display hardware. + + DDFLIP_NOVSYNC + Causes DirectDraw to perform the physical flip as close as possible to the next scan line. Subsequent operations that + involve the two flipped surfaces do not check whether the physical flip has finished—that is, they do not return + DDERR_WASSTILLDRAWING for that reason (but might for other reasons). This allows an application to perform flips at + a higher frequency than the monitor refresh rate, but might introduce visible artifacts. + If DDCAPS2_FLIPNOVSYNC is not set in the dwCaps2 member of the DDCAPS structure that is returned for the display hardware, DDFLIP_NOVSYNC has no effect. + + DDFLIP_ODD + For use only when displaying video in an overlay surface. The new surface contains data from the odd field of a video signal. + This flag cannot be used with the DDFLIP_EVEN flag. + + DDFLIP_WAIT + Typically, if the flip cannot be set up because the state of the display hardware is not appropriate, the DDERR_WASSTILLDRAWING + error returns immediately, and no flip occurs. Setting this flag causes Flip to continue trying to flip if it receives the + DDERR_WASSTILLDRAWING error from the hardware abstraction layer (HAL). Flip does not return until the flipping operation + has been successfully set up or another error, such as DDERR_SURFACEBUSY, is returne + */ + + return DDERR_GENERIC; + + /* + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOFLIPHW + DDERR_NOTFLIPPABLE + DDERR_SURFACEBUSY + DDERR_SURFACELOST + DDERR_UNSUPPORTED + DDERR_WASSTILLDRAWING + */ +} + +// Obtains the attached surface that has the specified capabilities, and increments the +// reference count of the retrieved interface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE FAR *lplpDDAttachedSurface) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::GetAttachedSurface", "Not Implemented"); + + + //lplpDDAttachedSurface cannot be null + if(lplpDDAttachedSurface == NULL) return DDERR_INVALIDPARAMS; + + /* + Attachments are used to connect multiple DirectDrawSurface objects into complex structures, like the complex structures required to + support 3-D page flipping with z-buffers. GetAttachedSurface fails if more than one surface is attached that matches the capabilities + requested. In this case, the application must use the IDirectDrawSurface7::EnumAttachedSurfaces method to obtain the attached surfaces. + */ + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOTFOUND + DDERR_SURFACELOST + */ +} + +// Obtains status about a bit block transfer (bitblt) operation. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetBltStatus(DWORD dwFlags) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::GetBltStatus", "Not Implemented"); + + /* + DDGBS_CANBLT + Inquires whether a bitblt that involves this surface can occur immediately, and returns DD_OK if the bitblt can be completed. + + IS_ISBLTDONE + Inquires whether the bitblt is done, and returns DD_OK if the last bitblt on this surface has completed. + */ + + return DDERR_GENERIC; + + /* + If it fails, the method returns DDERR_WASSTILLDRAWING if the bitbltter is busy, DDERR_NOBLTHW if there is no bitbltter, or one of the following error values: + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOBLTHW + DDERR_SURFACEBUSY + DDERR_SURFACELOST + DDERR_UNSUPPORTED + DDERR_WASSTILLDRAWING + */ +} + +// Retrieves the capabilities of this surface. These capabilities are not necessarily related +// to the capabilities of the display device. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetCaps(LPDDSCAPS lpDDSCaps) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::GetCaps", "Partially Implemented"); + + //lpDDSCaps cannot be NULL + if(lpDDSCaps == NULL) return DDERR_INVALIDPARAMS; + + memcpy(lpDDSCaps, &surfaceDesc.ddsCaps, sizeof(DDSCAPS)); + + /* + The IDirectDrawSurface7::GetCaps method differs from its counterpart in the IDirectDrawSurface3 interface in that + it accepts a pointer to a DDSCAPS2 structure, rather than the legacy DDSCAPS structure. + */ + + return DD_OK; +} + +// Retrieves the DirectDrawClipper object that is associated with this surface, and increments +// the reference count of the returned clipper. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetClipper(LPDIRECTDRAWCLIPPER FAR *lplpDDClipper) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::GetClipper", "Not Implemented"); + + //lplpDDClipper cannot be null + if(lplpDDClipper == NULL) return DDERR_INVALIDPARAMS; + + return DDERR_GENERIC; + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOCLIPPERATTACHED + */ +} + +// Retrieves the color key value for this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetColorKey(DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::GetColorKey", "Partially Implemented"); + + //lpDDColorKey cannot be null + if(lpDDColorKey == NULL) return DDERR_INVALIDPARAMS; + + if(dwFlags & DDCKEY_DESTBLT) + { + memcpy(lpDDColorKey, &colorKeys[0], sizeof(DDCOLORKEY)); + } + else if(dwFlags & DDCKEY_DESTOVERLAY) + { + memcpy(lpDDColorKey, &colorKeys[1], sizeof(DDCOLORKEY)); + } + else if(dwFlags & DDCKEY_SRCBLT) + { + memcpy(lpDDColorKey, &colorKeys[2], sizeof(DDCOLORKEY)); + } + if(dwFlags & DDCKEY_SRCOVERLAY) + { + memcpy(lpDDColorKey, &colorKeys[3], sizeof(DDCOLORKEY)); + } + + /* + DDCKEY_DESTBLT + A color key or color space to be used as a destination color key for bit block transfer (bitblt) operations. + + DDCKEY_DESTOVERLAY + A color key or color space to be used as a destination color key for overlay operations. + + DDCKEY_SRCBLT + A color key or color space to be used as a source color key for bitblt operations. + + DDCKEY_SRCOVERLAY + A color key or color space to be used as a source color key for overlay operations. + */ + + return DD_OK; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOCOLORKEY + DDERR_NOCOLORKEYHW + DDERR_SURFACELOST + DDERR_UNSUPPORTED + */ +} + +// Creates a GDI-compatible handle of a device context for this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetDC(HDC FAR *lphDC) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::GetDC", "Not Implemented"); + + // lphDC cannot but null + if(lphDC == NULL) return DDERR_INVALIDPARAMS; + + // Create GDI-compatible handle device context for this surface and set lphDC to it + + return DDERR_GENERIC; + + /* + DDERR_DCALREADYCREATED + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDSURFACETYPE + DDERR_SURFACELOST + DDERR_UNSUPPORTED + DDERR_WASSTILLDRAWING + */ +} + +// Retrieves status about whether this surface has finished its flipping process. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetFlipStatus(DWORD dwFlags) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::GetFlipStatus", "Not Implemented"); + + /* + DDGFS_CANFLIP + Inquires whether this surface can be flipped immediately, and returns DD_OK if the flip can be completed. + + DDGFS_ISFLIPDONE + Inquires whether the flip has finished, and returns DD_OK if the last flip on this surface has completed. + */ + + return DDERR_GENERIC; + + /* + If it fails, the method can return DDERR_WASSTILLDRAWING if the surface has not finished its flipping process, or one of the following error values: + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDSURFACETYPE + DDERR_SURFACEBUSY + DDERR_SURFACELOST + DDERR_UNSUPPORTED + DDERR_WASSTILLDRAWING + */ +} + +// Retrieves the display coordinates of this surface. This method is used on a visible, +// active overlay surface (that is, a surface that has the DDSCAPS_OVERLAY flag set). +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetOverlayPosition(LPLONG lplX, LPLONG lplY) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::GetOverlayPosition", "Partially Implemented"); + + //lplX and lplY cannot be null + if(lplX == NULL || lplY == NULL) return DDERR_INVALIDPARAMS; + + //set lplX and lplY to X,Y of this overlay surface + *lplX = overlayX; + *lplY = overlayY; + + return DD_OK; + + /* + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDPOSITION + DDERR_NOOVERLAYDEST + DDERR_NOTAOVERLAYSURFACE + DDERR_OVERLAYNOTVISIBLE + DDERR_SURFACELOST + */ +} + +// Retrieves the DirectDrawPalette object that is associated with this surface, +// and increments the reference count of the returned palette. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetPalette(LPDIRECTDRAWPALETTE FAR *lplpDDPalette) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::GetPalette", "Partially Implemented"); + + // lplpDDPalette cannot be null + if(lplpDDPalette == NULL) return DDERR_INVALIDPARAMS; + + // No palette attached + if(attachedPalette == NULL) return DDERR_NOPALETTEATTACHED; + + // Check exclusive mode + + // Return attached palette + *lplpDDPalette = (LPDIRECTDRAWPALETTE)attachedPalette; + // Increment ref count + attachedPalette->AddRef(); + + // Success + return DD_OK; + + /* + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOEXCLUSIVEMODE + DDERR_NOPALETTEATTACHED + DDERR_SURFACELOST + DDERR_UNSUPPORTED + */ +} + +// Retrieves the color and pixel format of this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::GetPixelFormat", "Partially Implemented"); + + // lpDDPixelFormat cannot be null + if(lpDDPixelFormat == NULL) return DDERR_INVALIDPARAMS; + + // lpDDPixelFormat receives a detailed description of the current pixel and + // color space format of this surface. + + // Copy pixel format to lpDDPixelFormat + memcpy(lpDDPixelFormat, &surfaceDesc.ddpfPixelFormat, sizeof(DDPIXELFORMAT)); + + return DD_OK; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDSURFACETYPE + */ +} + +// Retrieves a description of this surface in its current condition. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::GetSurfaceDesc", "Partially Implemented"); + + // lpDDSurfaceDesc cannot be null + if(lpDDSurfaceDesc == NULL) return DDERR_INVALIDPARAMS; + + // Fill lpDDSurfaceDesc with this surface description + + // Copy surfacedesc to lpDDSurfaceDesc + memcpy(lpDDSurfaceDesc, &surfaceDesc, sizeof(DDSURFACEDESC)); + + return DD_OK; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + */ +} + +// Initializes a DirectDrawSurface object. +HRESULT __stdcall IDirectDrawSurfaceWrapper::Initialize(LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::Initialize", "Partially Implemented"); + + // Because the DirectDrawSurface object is initialized when it is created, + // this method always returns DDERR_ALREADYINITIALIZED. + return DDERR_ALREADYINITIALIZED; +} + +//Determines whether the surface memory that is associated with a DirectDrawSurface object has been freed. +HRESULT __stdcall IDirectDrawSurfaceWrapper::IsLost() +{ + // NOTE: Disabled for performance + // debugMessage(2, "IDirectDrawSurfaceWrapper::IsLost", "Partially Implemented(Not Required)"); + + // You can use this method to determine when you need to reallocate surface memory. + // When a DirectDrawSurface object loses its surface memory, most methods return + // DDERR_SURFACELOST and perform no other action. + + // Check if surface is lost or not, if not return OK + + // Surface never lost + return DD_OK; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_SURFACELOST + */ +} + +// Obtains a pointer to the surface memory. +HRESULT __stdcall IDirectDrawSurfaceWrapper::Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) +{ + // lpDDSurfaceDesc cannot be null + if(lpDDSurfaceDesc == NULL) return DDERR_INVALIDPARAMS; + + char message[2048] = "\0"; + + // Check for destination rect + //if(lpDestRect == NULL) + //{ + // Copy desc to passed in desc + memcpy(lpDDSurfaceDesc, &surfaceDesc, sizeof(DDSURFACEDESC)); + // Set video memory and pitch + lpDDSurfaceDesc->lpSurface = (LPVOID)rawVideoMem; + lpDDSurfaceDesc->dwFlags |= DDSD_LPSURFACE; + lpDDSurfaceDesc->lPitch = surfaceWidth; + lpDDSurfaceDesc->dwFlags |= DDSD_PITCH; + //sprintf_s(message, 2048, "INF IDirectDrawSurfaceWrapper::Lock lpDestRect: NULL"); + //} + //else + //{ + // sprintf_s(message, 2048, "Unsupported lpDestRect[%d,%d,%d,%d]", lpDestRect->left, lpDestRect->top, lpDestRect->right, lpDestRect->bottom); + //} + + // NOTE: Disabled for performance + /*if(dwFlags & DDLOCK_DONOTWAIT) strcat_s(message, 2048, ", DDLOCK_DONOTWAIT"); + if(dwFlags & DDLOCK_EVENT) strcat_s(message, 2048, ", DDLOCK_EVENT"); + if(dwFlags & DDLOCK_NOOVERWRITE) strcat_s(message, 2048, ", DDLOCK_NOOVERWRITE"); + if(dwFlags & DDLOCK_NOSYSLOCK) strcat_s(message, 2048, ", DDLOCK_NOSYSLOCK"); + if(dwFlags & DDLOCK_DISCARDCONTENTS) strcat_s(message, 2048, ", DDLOCK_DISCARDCONTENTS"); + if(dwFlags & DDLOCK_OKTOSWAP) strcat_s(message, 2048, ", DDLOCK_OKTOSWAP"); + if(dwFlags & DDLOCK_READONLY) strcat_s(message, 2048, ", DDLOCK_READONLY"); + if(dwFlags & DDLOCK_SURFACEMEMORYPTR) strcat_s(message, 2048, ", DDLOCK_SURFACEMEMORYPTR"); + if(dwFlags & DDLOCK_WAIT) strcat_s(message, 2048, ", DDLOCK_WAIT"); + if(dwFlags & DDLOCK_WRITEONLY) strcat_s(message, 2048, ", DDLOCK_WRITEONLY"); + + if(lpDestRect == NULL) + { + debugMessage(2, "IDirectDrawSurfaceWrapper::Lock", message); + } + else + / + debugMessage(0, "IDirectDrawSurfaceWrapper::Lock", message); + // Is error, unsupported + return DDERR_GENERIC; + }*/ + + /* + DDLOCK_DONOTWAIT + On IDirectDrawSurface7 interfaces, the default is DDLOCK_WAIT. If you want to override the default and use time when the accelerator is busy (as denoted by the DDERR_WASSTILLDRAWING return value), use DDLOCK_DONOTWAIT. + + DDLOCK_EVENT + Not currently implemented. + + DDLOCK_NOOVERWRITE + New for DirectX 7.0. Used only with Direct3D vertex-buffer locks. Indicates that no vertices that were referred to in a draw operation since the start of the frame (or the last lock without this flag) are modified during the lock. This can be useful when you want only to append data to the vertex buffer. + + DDLOCK_NOSYSLOCK + Do not take the Win16Mutex (also known as Win16Lock). This flag is ignored when locking the primary surface. + + DDLOCK_DISCARDCONTENTS + New for DirectX 7.0. Used only with Direct3D vertex-buffer locks. Indicates that no assumptions are made about the contents of the vertex buffer during this lock. This enables Direct3D or the driver to provide an alternative memory area as the vertex buffer. This is useful when you plan to clear the contents of the vertex buffer and fill in new data. + + DDLOCK_OKTOSWAP + This flag is obsolete and was replaced by the DDLOCK_DISCARDCONTENTS flag. + + DDLOCK_READONLY + Indicates that the surface being locked can only be read. + + DDLOCK_SURFACEMEMORYPTR + Indicates that a valid memory pointer to the top of the specified rectangle should be returned. If no rectangle is specified, a pointer to the top of the surface is returned. This is the default. + + DDLOCK_WAIT + If a lock cannot be obtained because a bit block transfer (bitblt) operation is in progress, Lock retries until a lock is obtained or another error occurs, such as DDERR_SURFACEBUSY. + + DDLOCK_WRITEONLY + Indicates that the surface being locked is write-enabled. + */ + + return DD_OK; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_OUTOFMEMORY + DDERR_SURFACEBUSY + DDERR_SURFACELOST + DDERR_WASSTILLDRAWING + */ +} + +// Releases the handle of a device context that was previously obtained by using the +// IDirectDrawSurface7::GetDC method. +HRESULT __stdcall IDirectDrawSurfaceWrapper::ReleaseDC(HDC hDC) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::ReleaseDC", "Not Implemented"); + + // Free hDc which is the handle of a device context that was previously obtained + // by IDirectDrawSurface7::GetDC. + + return DDERR_GENERIC; + + /* + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_SURFACELOST + DDERR_UNSUPPORTED + */ +} + +// Restores a surface that has been lost. This occurs when the surface memory that is +// associated with the DirectDrawSurface object has been freed. +HRESULT __stdcall IDirectDrawSurfaceWrapper::Restore() +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::Restore", "Not Implemented"); + + //restore this surface if it's been lost + + /* + Restore restores the memory that was allocated for a surface, but does not reload any bitmaps that might have existed in the + surface before it was lost. + + A single call to Restore restores a DirectDrawSurface object's associated implicit surfaces (back buffers, and so on). + An attempt to restore an implicitly created surface results in an error. Restore does not work across explicit attachments + that were created by using the IDirectDrawSurface7::AddAttachedSurface method—each of these surfaces must be restored + individually. + */ + + return DDERR_GENERIC; + /* + DDERR_GENERIC + DDERR_IMPLICITLYCREATED + DDERR_INCOMPATIBLEPRIMARY + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOEXCLUSIVEMODE + DDERR_OUTOFMEMORY + DDERR_UNSUPPORTED + DDERR_WRONGMODE + */ +} + +// Attaches a clipper object to, or deletes one from, this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::SetClipper", "Not Implemented"); + + //if no clipper was passed in + /*if(lpDDClipper == NULL) + { + //no clipper attached + if(attachedClipper == NULL) return DDERR_NOCLIPPERATTACHED; + //release attached clipper + attachedClipper->Release(); + //no clipper attached + attachedClipper = NULL; + } + else + { + //no clipper attached + if(attachedClipper == NULL) + { + //check surface type for DDERR_INVALIDSURFACETYPE + + //attach the clipper + attachedClipper = (IDirectDrawClipperWrapper *)lpDDClipper; + //increment ref count + attachedClipper->AddRef(); + } + else + { + //I don't know what to do here, ignore? + } + }*/ + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDSURFACETYPE + DDERR_NOCLIPPERATTACHED + */ +} + +// Sets the color key value for the DirectDrawSurface object if the hardware supports +// color keys on a per-surface basis. +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetColorKey(DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::SetColorKey", "Partially Implemented"); + + // lpDDColorKey cannot be null + if(lpDDColorKey == NULL) return DDERR_INVALIDPARAMS; + + /* + DDCKEY_COLORSPACE + The structure contains a color space. Not set if the structure contains a single color key. + */ + + //store color key information for the appropriate color key + if(dwFlags & DDCKEY_DESTBLT) + { + memcpy(&colorKeys[0], lpDDColorKey, sizeof(DDCOLORKEY)); + } + else if(dwFlags & DDCKEY_DESTOVERLAY) + { + memcpy(&colorKeys[1], lpDDColorKey, sizeof(DDCOLORKEY)); + } + else if(dwFlags & DDCKEY_SRCBLT) + { + memcpy(&colorKeys[2], lpDDColorKey, sizeof(DDCOLORKEY)); + } + if(dwFlags & DDCKEY_SRCOVERLAY) + { + memcpy(&colorKeys[3], lpDDColorKey, sizeof(DDCOLORKEY)); + } + + return DD_OK; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOCOLORKEYHW + DDERR_SURFACELOST + DDERR_UNSUPPORTED + */ +} + +//Changes the display coordinates of an overlay surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetOverlayPosition(LONG lX, LONG lY) +{ + debugMessage(1, "IDirectDrawSurfaceWrapper::SetOverlayPosition", "Partially Implemented"); + + // Store the new overlay position + overlayX = lX; + overlayY = lY; + + return DD_OK; + + /* + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDPOSITION + DDERR_NOOVERLAYDEST + DDERR_NOTAOVERLAYSURFACE + DDERR_OVERLAYNOTVISIBLE + DDERR_SURFACELOST + DDERR_UNSUPPORTED + */ +} + +// Attaches a palette object to (or detaches one from) a surface. The surface uses this palette +// for all subsequent operations. The palette change takes place immediately, without regard to +// refresh timing. +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) +{ + char message[2048] = "\0"; + sprintf_s(message, 2048, "lpDDPalette: 0x%x", lpDDPalette); + debugMessage(2, "IDirectDrawSurfaceWrapper::SetPalette", message); + + // if lpDDPalette is NULL then detach the current palette + if(lpDDPalette == NULL) + { + // Decrement ref count + if(attachedPalette->Release() == 0) delete attachedPalette; + // Detach + attachedPalette = NULL; + } + + // When you call SetPalette to set a palette to a surface for the first time, + // SetPalette increments the palette's reference count; subsequent calls to + // SetPalette do not affect the palette's reference count. + + attachedPalette = (IDirectDrawPaletteWrapper *)lpDDPalette; + + return DD_OK; + + /* + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDPIXELFORMAT + DDERR_INVALIDSURFACETYPE + DDERR_NOEXCLUSIVEMODE + DDERR_NOPALETTEATTACHED + DDERR_NOPALETTEHW + DDERR_NOT8BITCOLOR + DDERR_SURFACELOST + DDERR_UNSUPPORTED + */ +} + +// Notifies DirectDraw that the direct surface manipulations are complete. +HRESULT __stdcall IDirectDrawSurfaceWrapper::Unlock(LPVOID lpRect) +{ + char message[2048] = "\0"; + + // NOTE: Disabled for performance + /*if(lpRect != 0) + { + sprintf_s(message, 2048, "Unsupported lpRect[%d,%d,%d,%d]", ((LPRECT)lpRect)->left, ((LPRECT)lpRect)->top, ((LPRECT)lpRect)->right, ((LPRECT)lpRect)->bottom); + debugMessage(0, "IDirectDrawSurfaceWrapper::Unlock", message); + } + else + { + //sprintf_s(message, 2048, "lpRect: NULL"); + //debugMessage(2, "IDirectDrawSurfaceWrapper::Unlock", message); + }*/ + + // Always unlock full rect(fix) + + // Translate all of raw video memory to rgb video memory with palette + for(long i = 0; i < surfaceWidth * surfaceHeight; i++) + { + rgbVideoMem[i] = attachedPalette->rgbPalette[rawVideoMem[i]]; + } + + /* + A pointer to a RECT structure that was used to lock the surface in the corresponding + call to the IDirectDrawSurface7::Lock method. This parameter can be NULL only if the + entire surface was locked by passing NULL in the lpDestRect parameter of the corresponding + call to the IDirectDrawSurface7::Lock method. + + Because you can call IDirectDrawSurface7::Lock multiple times for the same surface with + different destination rectangles, the pointer in lpRect links the calls to the + IDirectDrawSurface7::Lock and IDirectDrawSurface7::Unlock methods. + */ + + // Present the surface + if(!ddrawParent->Present()) + { + // Failed to presnt the surface, error reporting handled previously + return DDERR_GENERIC; + } + + // Success + return DD_OK; + + /* + DDERR_GENERIC + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDRECT + DDERR_NOTLOCKED + DDERR_SURFACELOST + */ +} + +// Repositions or modifies the visual attributes of an overlay surface. These +// surfaces must have the DDSCAPS_OVERLAY flag set. +HRESULT __stdcall IDirectDrawSurfaceWrapper::UpdateOverlay(LPRECT lpSrcRect, LPDIRECTDRAWSURFACE lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::UpdateOverlay", "Not Implemented"); + + /* + lpSrcRect [in] + A pointer to a RECT structure that defines the x, y, width, and height of the region on the source surface being used as the overlay. This parameter can be NULL to hide an overlay or to indicate that the entire overlay surface is to be used and that the overlay surface conforms to any boundary and size-alignment restrictions imposed by the device driver. + + lpDDDestSurface [in] + A pointer to the IDirectDrawSurface7 interface for the DirectDrawSurface object that is being overlaid. + + lpDestRect [in] + A pointer to a RECT structure that defines the width, x, and height, y, of the region on the destination surface that the overlay should be moved to. This parameter can be NULL to hide the overlay. + + dwFlags [in] + A combination of the following flags that determine the overlay update: + + DDOVER_ADDDIRTYRECT + Adds a dirty rectangle to an emulated overlay surface. + DDOVER_ALPHADEST + Obsolete. + DDOVER_ALPHADESTCONSTOVERRIDE + Uses the dwAlphaDestConst member of the DDOVERLAYFX structure as the destination alpha channel for this overlay. + DDOVER_ALPHADESTNEG + Indicates that the destination surface becomes more transparent as the alpha value increases (0 is opaque). + DDOVER_ALPHADESTSURFACEOVERRIDE + Uses the lpDDSAlphaDest member of the DDOVERLAYFX structure as the alpha channel destination for this overlay. + DDOVER_ALPHAEDGEBLEND + Uses the dwAlphaEdgeBlend member of the DDOVERLAYFX structure as the alpha channel for the edges of the image that border the color key colors. + DDOVER_ALPHASRC + Uses either the alpha information in pixel format or the alpha channel surface attached to the source surface as the source alpha channel for this overlay. + DDOVER_ALPHASRCCONSTOVERRIDE + Uses the dwAlphaSrcConst member of the DDOVERLAYFX structure as the source alpha channel for this overlay. + DDOVER_ALPHASRCNEG + Indicates that the source surface becomes more transparent as the alpha value increases (0 is opaque). + DDOVER_ALPHASRCSURFACEOVERRIDE + Uses the lpDDSAlphaSrc member of the DDOVERLAYFX structure as the alpha channel source for this overlay. + DDOVER_ARGBSCALEFACTORS + New for DirectX 7.0. Indicates that the DDOVERLAYFX structure contains valid ARGB scaling factors. + DDOVER_AUTOFLIP + Automatically flips to the next surface in the flipping chain each time that a video port VSYNC occurs. + DDOVER_BOB + Displays each field of the interlaced video stream individually without causing any artifacts to display. + DDOVER_BOBHARDWARE + Bob operations are performed by using hardware, rather than by using software or being emulated. This flag must be used with the DDOVER_BOB flag. + DDOVER_DDFX + Uses the overlay FX flags in the lpDDOverlayFx parameter to define special overlay effects. + DDOVER_DEGRADEARGBSCALING + New for DirectX 7.0. ARGB scaling factors can be degraded to fit driver capabilities. + DDOVER_HIDE + Turns off this overlay. + DDOVER_INTERLEAVED + The surface memory is composed of interleaved fields. + DDOVER_KEYDEST + Uses the color key associated with the destination surface. + DDOVER_KEYDESTOVERRIDE + Uses the dckDestColorkey member of the DDOVERLAYFX structure as the color key for the destination surface. + DDOVER_KEYSRC + Uses the color key associated with the source surface. + DDOVER_KEYSRCOVERRIDE + Uses the dckSrcColorkey member of the DDOVERLAYFX structure as the color key for the source surface. + DDOVER_OVERRIDEBOBWEAVE + Bob and weave decisions should not be overridden by other interfaces. + DDOVER_REFRESHALL + Redraws the entire surface on an emulated overlayed surface. + DDOVER_REFRESHDIRTYRECTS + Redraws all dirty rectangles on an emulated overlayed surface. + DDOVER_SHOW + Turns on this overlay. + + lpDDOverlayFx [in] + A pointer to the DDOVERLAYFX structure that describes the effects to be used. Can be NULL if the DDOVER_DDFX flag is not specified. + */ + + return DDERR_GENERIC; + + /* + DDERR_DEVICEDOESNTOWNSURFACE + DDERR_GENERIC + DDERR_HEIGHTALIGN + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_INVALIDRECT + DDERR_INVALIDSURFACETYPE + DDERR_NOSTRETCHHW + DDERR_NOTAOVERLAYSURFACE + DDERR_OUTOFCAPS + DDERR_SURFACELOST + DDERR_UNSUPPORTED + DDERR_XALIGN + */ +} + +// The IDirectDrawSurface7::UpdateOverlayDisplay method is not currently implemented +HRESULT __stdcall IDirectDrawSurfaceWrapper::UpdateOverlayDisplay(DWORD dwFlags) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::UpdateOverlayDisplay", "Not Supported in DirectDraw"); + // Not supported + return DDERR_UNSUPPORTED; +} + +// Sets the z-order of an overlay. +HRESULT __stdcall IDirectDrawSurfaceWrapper::UpdateOverlayZOrder(DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSReference) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::UpdateOverlayZOrder", "Not Implemented"); + + /* + DDOVERZ_INSERTINBACKOF + Inserts this overlay in the overlay chain behind the reference overlay. + + DDOVERZ_INSERTINFRONTOF + Inserts this overlay in the overlay chain in front of the reference overlay. + + DDOVERZ_MOVEBACKWARD + Moves this overlay one position backward in the overlay chain. + + DDOVERZ_MOVEFORWARD + Moves this overlay one position forward in the overlay chain. + + DDOVERZ_SENDTOBACK + Moves this overlay to the back of the overlay chain. + + DDOVERZ_SENDTOFRONT + Moves this overlay to the front of the overlay chain. + + lpDDSReference [in] + A pointer to the IDirectDrawSurface7 interface for the DirectDraw surface to be used as a relative position in the + overlay chain. This parameter is needed only for the DDOVERZ_INSERTINBACKOF and DDOVERZ_INSERTINFRONTOF flags. + + */ + + return DDERR_GENERIC; + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOTAOVERLAYSURFACE + */ +} + +/**************************** +**Added in the V2 interface** +*****************************/ + +// Retrieves an interface to the DirectDraw object that was used to create this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetDDInterface(LPVOID FAR *lplpDD) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::GetDDInterface", "Not Implemented"); + + // lplpDD cannot be null + if(lplpDD == NULL) return DDERR_INVALIDPARAMS; + + // Set lplpDD to directdraw object that created this surface + *lplpDD = (IDirectDraw *)ddrawParent; + + return DD_OK; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAM + */ +} + +// Prevents a system-memory surface from being paged out while a bit block +// transfer (bitblt) operation that uses direct memory access (DMA) transfers +// to or from system memory is in progress. +HRESULT __stdcall IDirectDrawSurfaceWrapper::PageLock(DWORD dwFlags) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::PageLock", "Not Implemented"); + + //dwFlags currently not used and must be set to 0. + + return DDERR_GENERIC; + /* + DDERR_CANTPAGELOCK + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_SURFACELOST + */ +} + +// Unlocks a system-memory surface, which then allows it to be paged out. +HRESULT __stdcall IDirectDrawSurfaceWrapper::PageUnlock(DWORD dwFlags) +{ + //***Unimplemented*** + debugMessage(0, "IDirectDrawSurfaceWrapper::PageUnlock", "Not Implemented"); + + // dwFlags currently not used and must be set to 0. + + return DDERR_GENERIC; + + /* + DDERR_CANTPAGEUNLOCK + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOTPAGELOCKED + DDERR_SURFACELOST + */ +} + +/**************************** +**Added in the V3 interface** +*****************************/ + +// Sets the characteristics of an existing surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetSurfaceDesc(LPDDSURFACEDESC2 lpDDsd2, DWORD dwFlags) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::SetSurfaceDesc", "Not Implemented"); + + /* + lpDDsd2 [in] + A pointer to a DDSURFACEDESC2 structure that contains the new surface characteristics. + + dwFlags [in] + Currently not used and must be set to 0. + */ + + return DDERR_GENERIC; + + /* + DDERR_INVALIDPARAMS + DDERR_INVALIDOBJECT + DDERR_SURFACELOST + DDERR_SURFACEBUSY + DDERR_INVALIDSURFACETYPE + DDERR_INVALIDPIXELFORMAT + DDERR_INVALIDCAPS + DDERR_UNSUPPORTED + DDERR_GENERIC + */ +} + +/**************************** +**Added in the V4 interface** +*****************************/ + +// Manually updates the uniqueness value for this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::ChangeUniquenessValue() +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::ChangeUniquenessValue", "Not Implemented"); + + // DirectDraw automatically updates uniqueness values whenever the contents of a surface change. + + return DDERR_GENERIC; + + /* + DDERR_EXCEPTION + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + */ +} + +// Frees the specified private data that is associated with this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::FreePrivateData(REFGUID guidTag) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::FreePrivateData", "Not Implemented"); + + //guidTag is a reference to (C++) or address of (C) the globally unique identifier + //that identifies the private data to be free + + //If the private data was set by using the DDSPD_IUNKNOWNPOINTER flag, + //FreePrivateData calls the IUnknown::Release method on the associated interface. + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_NOTFOUND + */ +} + +// Copies the private data that is associated with this surface to a provided buffer. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetPrivateData(REFGUID guidTag, LPVOID lpBuffer, LPDWORD lpcbBufferSize) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::GetPrivateData", "Not Implemented"); + + /* + guidTag [in] + Reference to (C++) or address of (C) the globally unique identifier that identifies the private data to be retrieved. + lpBuffer [out] + A pointer to a previously allocated buffer that receives the requested private data if the call succeeds. The application that calls this method must allocate and release this buffer. + lpcbBufferSize [in, out] + A pointer to a variable that contains the size value of the buffer at lpBuffer, in bytes. If this value is less than the actual size of the private data (such as 0), GetPrivateData sets the variable to the required buffer size, and then returns DDERR_MOREDATA. + */ + + return DDERR_GENERIC; + + /* + DDERR_EXPIRED + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_MOREDATA + DDERR_NOTFOUND + DDERR_OUTOFMEMORY + */ +} + +// Retrieves the current uniqueness value for this surface. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetUniquenessValue(LPDWORD lpValue) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::GetUniquenessValue", "Not Implemented"); + + /* + lpValue [out] + A pointer to a variable that receives the surface's current uniqueness value if the call succeeds. + */ + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + */ +} + +// +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetPrivateData(REFGUID guidTag, LPVOID lpData, DWORD cbSize, DWORD dwFlags) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::SetPrivateData", "Not Implemented"); + + /* + guidTag [in] + Reference to (C++) or address of (C) the globally unique identifier that identifies the private data to be set. + lpData [in] + A pointer to a buffer that contains the data to be associated with the surface. + cbSize [in] + The size value of the buffer at lpData, in bytes. + dwFlags [in] + A value that can be set to one of the following flags. These flags describe the type of data being passed or request that the data be invalidated when the surface changes. + (none) + If no flags are specified, DirectDraw allocates memory to hold the data within the buffer and copies the data into the new buffer. The buffer allocated by DirectDraw is automatically freed, as appropriate. + DDSPD_IUNKNOWNPOINTER + The data at lpData is a pointer to an IUnknown interface. DirectDraw automatically calls the IUnknown::AddRef method of this interface. When this data is no longer needed, DirectDraw automatically calls the IUnknown::Release method of this interface. + DDSPD_VOLATILE + The buffer at lpData is only valid while the surface remains unchanged. If the surface's contents change, subsequent calls to the IDirectDrawSurface7::GetPrivateData method return DDERR_EXPIRED. + */ + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + DDERR_OUTOFMEMORY + */ +} + +/******************* +**Texture7 Methods** +********************/ + +// Assigns the texture-management priority for this texture. This method +// succeeds only on managed textures. +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetPriority(DWORD dwPriority) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::SetPriority", "Not Implemented"); + + /* + dwPriority [in] + A value that specifies the new texture-management priority for the texture. + */ + + return DDERR_GENERIC; + + /* + If it fails, the return value is an error. The method returns DDERR_INVALIDOBJECT + if the parameter is invalid or if the texture is not managed by Direct3D. + */ + +} + +// Retrieves the texture-management priority for this texture. This method +// succeeds only on managed textures. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetPriority(LPDWORD lpdwPriority) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::GetPriority", "Not Implemented"); + + /* + lpdwPriority [out] + A pointer to a variable that receives the texture priority if the call succeeds. + */ + + return DDERR_GENERIC; + + /* + If it fails, the return value is an error. The method returns DDERR_INVALIDOBJECT + if the parameter is invalid or if the texture is not managed by Direct3D. + */ +} + +// Sets the maximum level of detail (LOD) for a managed mipmap surface. This method +// succeeds only on managed textures. +HRESULT __stdcall IDirectDrawSurfaceWrapper::SetLOD(LPDWORD lpdwMaxLOD) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::SetLOD", "Not Implemented"); + + /* + dwMaxLOD [in] + The maximum LOD value to be set for the mipmap chain if the call succeeds. + */ + + return DDERR_GENERIC; + + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + */ +} + +// Retrieves the maximum level of detail (LOD) currently set for a managed mipmap +// surface. This method succeeds only on managed textures. +HRESULT __stdcall IDirectDrawSurfaceWrapper::GetLOD(DWORD dwMaxLOD) +{ + debugMessage(0, "IDirectDrawSurfaceWrapper::GetLOD", "Not Implemented"); + + /* + lpdwMaxLOD [out] + A pointer to a variable that receives the maximum LOD value if the call succeeds + */ + + return DDERR_GENERIC; + /* + DDERR_INVALIDOBJECT + DDERR_INVALIDPARAMS + */ +} + +// Default constructo +IDirectDrawSurfaceWrapper::IDirectDrawSurfaceWrapper(IDirectDrawWrapper* parent) +{ + // Set parent + ddrawParent = parent; + + // Init color keys + for(int i = 0; i < 4; i++) + { + memset(&colorKeys[i], 0, sizeof(DDCOLORKEY)); + } + // Init overlay + overlayX = 0; + overlayY = 0; + + // Init video memory pointers + rawVideoMem = NULL; + rgbVideoMem = NULL; + + // Add reference + AddRef(); + + debugMessage(2, "IDirectDrawSurfaceWrapper::IDirectDrawSurfaceWrapper", "Created"); +} + +// Default destructor +IDirectDrawSurfaceWrapper::~IDirectDrawSurfaceWrapper() +{ + // Free memory for internal structures + if(rawVideoMem != NULL) { + delete rawVideoMem; + rawVideoMem = NULL; + } + if(rgbVideoMem != NULL) { + delete rawVideoMem; + rgbVideoMem = NULL; + } + + // Release reference + Release(); + + debugMessage(2, "IDirectDrawSurfaceWrapper::~IDirectDrawSurfaceWrapper", "Destroyed"); +} + +// Helper funtion to reallocate memory if display resolution changes +BOOL IDirectDrawSurfaceWrapper::ReInitialize(DWORD displayWidth, DWORD displayHeight) +{ + char message[2048] = "\0"; + + //store old memory pointer + BYTE* oldMem = rawVideoMem; + // Allocate new raw video memory to fit resolution + rawVideoMem = new BYTE[displayWidth * displayHeight]; + if(rawVideoMem == NULL) + { + debugMessage(0, "IDirectDrawSurfaceWrapper::ReInitialize", "Failed to allocate new raw video memory"); + return false; + } + // Clear new video memory + ZeroMemory(rawVideoMem, displayWidth * displayHeight * sizeof(BYTE)); + // If we have old memory + if(oldMem != NULL) + { + // Copy from old to new only in the area of the surface + memcpy(rawVideoMem, oldMem, surfaceWidth * surfaceHeight); + // Delete old mem + delete oldMem; + } + + sprintf_s(message, 2048, "displayWidth: %d, displayHeight: %d", displayWidth, displayHeight); + debugMessage(2, "IDirectDrawSurfaceWrapper::ReInitialize", message); + + return true; +} + +// Initialize wrapper function +HRESULT IDirectDrawSurfaceWrapper::WrapperInitialize(LPDDSURFACEDESC lpDDSurfaceDesc, DWORD displayModeWidth, DWORD displayModeHeight, DWORD displayWidth, DWORD displayHeight) +{ + //set width and height + /*if(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) + { + surfaceWidth = lpDDSurfaceDesc->dwWidth; + } + else + { + surfaceWidth = displayModeWidth; + } + if(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) + { + surfaceHeight = lpDDSurfaceDesc->dwHeight; + } + else + { + surfaceHeight = displayModeHeight; + } + + //allocate virtual video memory raw + double indexSize = 1; + if(lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1) + { + indexSize = 0.125; + } + else if(lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2) + { + indexSize = 0.25; + } + else if(lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) + { + indexSize = 0.5; + } + else if(lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 | lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXEDTO8) + { + indexSize = 1; + }*/ + + surfaceWidth = displayModeWidth; + surfaceHeight = displayModeHeight; + + //Overallocate the memory to prevent access outside of memory range by the exe + //if(!ReInitialize(displayWidth, displayHeight)) return DDERR_OUTOFMEMORY; + //maximum supported resolution is 1920x1440 + rawVideoMem = new BYTE[1920 * 1440]; + if(rawVideoMem == NULL) + { + debugMessage(0, "IDirectDrawSurfaceWrapper::WrapperInitialize", "Failed to allocate raw video memory"); + return DDERR_OUTOFMEMORY; + } + // Clear raw memory + ZeroMemory(rawVideoMem, 1920 * 1440 * sizeof(BYTE)); + + // Allocate virtual video memory RGB + rgbVideoMem = new UINT32[surfaceWidth * surfaceHeight]; + if(rgbVideoMem == NULL) + { + debugMessage(0, "IDirectDrawSurfaceWrapper::WrapperInitialize", "Failed to allocate rgb video memory"); + return DDERR_OUTOFMEMORY; + } + // Clear rgb memory + ZeroMemory(rgbVideoMem, surfaceWidth * surfaceHeight * sizeof(UINT32)); + + // Copy surface description + memcpy(&surfaceDesc, lpDDSurfaceDesc, sizeof(DDSURFACEDESC)); + + char message[2048] = "\0"; + sprintf_s(message, 2048, "Initialized displayModeWidth: %d, displayModeHeight: %d, displayWidth: %d, displayHeight: %d", displayModeWidth, displayModeHeight, displayWidth, displayHeight); + if(lpDDSurfaceDesc->dwFlags & DDSD_ALL) strcat_s(message, 2048, ", DDSD_ALL"); + if(lpDDSurfaceDesc->dwFlags & DDSD_ALPHABITDEPTH) strcat_s(message, 2048, ", DDSD_ALPHABITDEPTH"); + if(lpDDSurfaceDesc->dwFlags & DDSD_CAPS) strcat_s(message, 2048, ", DDSD_CAPS"); + if(lpDDSurfaceDesc->dwFlags & DDSD_CKDESTBLT) strcat_s(message, 2048, ", DDSD_CKDESTBLT"); + if(lpDDSurfaceDesc->dwFlags & DDSD_CKDESTOVERLAY) strcat_s(message, 2048, ", DDSD_CKDESTOVERLAY"); + if(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) strcat_s(message, 2048, ", DDSD_HEIGHT"); + if(lpDDSurfaceDesc->dwFlags & DDSD_LINEARSIZE) strcat_s(message, 2048, ", DDSD_LINEARSIZE"); + if(lpDDSurfaceDesc->dwFlags & DDSD_LPSURFACE) strcat_s(message, 2048, ", DDSD_LPSURFACE"); + if(lpDDSurfaceDesc->dwFlags & DDSD_MIPMAPCOUNT) strcat_s(message, 2048, ", DDSD_MIPMAPCOUNT"); + if(lpDDSurfaceDesc->dwFlags & DDSD_PITCH) strcat_s(message, 2048, ", DDSD_PITCH"); + if(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) strcat_s(message, 2048, ", DDSD_PIXELFORMAT"); + if(lpDDSurfaceDesc->dwFlags & DDSD_REFRESHRATE) strcat_s(message, 2048, ", DDSD_REFRESHRATE"); + if(lpDDSurfaceDesc->dwFlags & DDSD_TEXTURESTAGE) strcat_s(message, 2048, ", DDSD_TEXTURESTAGE"); + if(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) strcat_s(message, 2048, ", DDSD_WIDTH"); + if(lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) strcat_s(message, 2048, ", DDSD_ZBUFFERBITDEPTH"); + debugMessage(2, "IDirectDrawSurfaceWrapper::WrapperInitialize", message); + + return DD_OK; +} \ No newline at end of file diff --git a/Storm/SOURCE/ddraw/DirectDrawWrapper.cpp b/Storm/SOURCE/ddraw/DirectDrawWrapper.cpp new file mode 100644 index 0000000..37b4d27 --- /dev/null +++ b/Storm/SOURCE/ddraw/DirectDrawWrapper.cpp @@ -0,0 +1,2366 @@ +#include "DirectDrawWrapper.h" +#include "resource.h" + +#include +#include +#include +#include +#include + +#include + +#pragma comment(lib, "d3d11.lib") +#pragma comment(lib, "dxgi.lib") +#pragma comment(lib, "d3dcompiler.lib") +#pragma comment(lib, "windowscodecs.lib") + +using Microsoft::WRL::ComPtr; + +#ifndef SAFE_DELETE_ARRAY +#define SAFE_DELETE_ARRAY(x) do { if ((x) != NULL) { delete[] (x); (x) = NULL; } } while (0) +#endif + +#ifndef SAFE_DELETE +#define SAFE_DELETE(x) do { if ((x) != NULL) { delete (x); (x) = NULL; } } while (0) +#endif + +#ifndef DD_OK +#define DD_OK S_OK +#endif + +static const char* g_BlitVS_HLSL = R"( +struct VS_IN +{ + float3 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +struct VS_OUT +{ + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; +}; + +VS_OUT main(VS_IN input) +{ + VS_OUT o; + o.pos = float4(input.pos, 1.0f); + o.uv = input.uv; + return o; +} +)"; +static const char* g_BlitPS_HLSL = R"( +Texture2D tex0 : register(t0); +SamplerState samp0 : register(s0); + +struct PS_IN +{ + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; +}; + +float Luma(float3 c) +{ + return dot(c, float3(0.299f, 0.587f, 0.114f)); +} + +float3 SoftContrast(float3 c) +{ + return saturate(c * c * (3.0f - 2.0f * c)); +} + +float Vignette(float2 uv) +{ + float2 p = uv * 2.0f - 1.0f; + float r2 = dot(p, p); + return saturate(1.0f - r2 * 0.22f); +} + +float GrainRand(float2 p) +{ + return frac(sin(dot(p, float2(127.1f, 311.7f))) * 43758.5453123f); +} + +float GrainValue(float2 p) +{ + float2 i = floor(p); + float2 f = frac(p); + + float a = GrainRand(i); + float b = GrainRand(i + float2(1.0f, 0.0f)); + float c = GrainRand(i + float2(0.0f, 1.0f)); + float d = GrainRand(i + float2(1.0f, 1.0f)); + + float2 u = f * f * (3.0f - 2.0f * f); + + return lerp(lerp(a, b, u.x), lerp(c, d, u.x), u.y); +} + +float FilmGrain(float2 uv, float2 resolution) +{ + float2 p = uv * resolution; + + float g1 = GrainValue(p * 0.75f); + float g2 = GrainValue(p * 1.50f); + float g3 = GrainValue(p * 3.00f); + + float grain = g1 * 0.55f + g2 * 0.30f + g3 * 0.15f; + return grain - 0.5f; +} + +float3 BrightPass(float3 c, float lo, float hi) +{ + float lum = Luma(c); + float mask = smoothstep(lo, hi, lum); + return c * mask; +} + +float4 main(PS_IN input) : SV_Target +{ + uint texWidth, texHeight; + tex0.GetDimensions(texWidth, texHeight); + + float2 px = float2(1.0f / (float)texWidth, 1.0f / (float)texHeight); + float2 uv = input.uv; + + // baked constants + const float sharpenStrength = 0.95f; + const float contrastStrength = 0.62f; + + // denoise tuning + const float denoiseStrength = 0.22f; + const float denoiseSigma = 24.0f; + + // dark-area tuning + const float darkStart = 0.42f; + const float darkEnd = 0.10f; + const float darkStrength = 0.12f; + + // smart brightness tuning + const float brightnessLift = 0.20f; + const float brightnessLowMax = 0.85f; + + // bloom tuning + const float bloomStrength = 0.78f; + const float bloomThresholdLo = 0.18f; + const float bloomThresholdHi = 0.96f; + + // pseudo-AO tuning + const float aoStrength = 0.58f; + const float aoRadius1 = 1.5f; + const float aoRadius2 = 3.0f; + const float aoDarkBoost = 0.65f; + + // 3x3 neighborhood + float3 c00 = tex0.Sample(samp0, uv + float2(-px.x, -px.y)).rgb; + float3 c10 = tex0.Sample(samp0, uv + float2( 0.0f, -px.y)).rgb; + float3 c20 = tex0.Sample(samp0, uv + float2( px.x, -px.y)).rgb; + + float3 c01 = tex0.Sample(samp0, uv + float2(-px.x, 0.0f)).rgb; + float3 c11 = tex0.Sample(samp0, uv).rgb; + float3 c21 = tex0.Sample(samp0, uv + float2( px.x, 0.0f)).rgb; + + float3 c02 = tex0.Sample(samp0, uv + float2(-px.x, px.y)).rgb; + float3 c12 = tex0.Sample(samp0, uv + float2( 0.0f, px.y)).rgb; + float3 c22 = tex0.Sample(samp0, uv + float2( px.x, px.y)).rgb; + + // Luma values + float l00 = Luma(c00); + float l10 = Luma(c10); + float l20 = Luma(c20); + float l01 = Luma(c01); + float l11 = Luma(c11); + float l21 = Luma(c21); + float l02 = Luma(c02); + float l12 = Luma(c12); + float l22 = Luma(c22); + + // ------------------------------------------------------------------------- + // Edge-aware denoise + // ------------------------------------------------------------------------- + float invSigma = 1.0f / denoiseSigma; + + float w00 = 1.0f / (1.0f + abs(l00 - l11) * invSigma); + float w10 = 1.0f / (1.0f + abs(l10 - l11) * invSigma); + float w20 = 1.0f / (1.0f + abs(l20 - l11) * invSigma); + float w01 = 1.0f / (1.0f + abs(l01 - l11) * invSigma); + float w21 = 1.0f / (1.0f + abs(l21 - l11) * invSigma); + float w02 = 1.0f / (1.0f + abs(l02 - l11) * invSigma); + float w12 = 1.0f / (1.0f + abs(l12 - l11) * invSigma); + float w22 = 1.0f / (1.0f + abs(l22 - l11) * invSigma); + + float wCenter = 4.0f; + + float3 denoised = + c00 * w00 + c10 * w10 + c20 * w20 + + c01 * w01 + c11 * wCenter + c21 * w21 + + c02 * w02 + c12 * w12 + c22 * w22; + + float wSum = + w00 + w10 + w20 + + w01 + wCenter + w21 + + w02 + w12 + w22; + + denoised /= max(wSum, 1e-5f); + + float3 baseColor = lerp(c11, denoised, denoiseStrength); + float baseLuma = Luma(baseColor); + + // ------------------------------------------------------------------------- + // Blur / sharpen pipeline + // ------------------------------------------------------------------------- + float3 blur = + (c00 + 2.0f * c10 + c20 + + 2.0f * c01 + 4.0f * baseColor + 2.0f * c21 + + c02 + 2.0f * c12 + c22) / 16.0f; + + float lBlur = + (l00 + 2.0f * l10 + l20 + + 2.0f * l01 + 4.0f * baseLuma + 2.0f * l21 + + l02 + 2.0f * l12 + l22) / 16.0f; + + float detail = baseLuma - lBlur; + + float edge = + abs(l10 - l12) + + abs(l01 - l21) + + 0.5f * abs(l00 - l22) + + 0.5f * abs(l20 - l02); + + float adapt = 1.0f - saturate(edge * 4.0f); + adapt = adapt * adapt; + + float amount = sharpenStrength * adapt; + + float3 color = baseColor + detail.xxx * amount; + + // Mild contrast boost + float3 contrasted = SoftContrast(saturate(color)); + color = lerp(color, contrasted, contrastStrength); + + // ------------------------------------------------------------------------- + // Pseudo AO from neighborhood enclosure / crevices + // ------------------------------------------------------------------------- + { + float2 r1 = px * aoRadius1; + float2 r2 = px * aoRadius2; + + float3 a0 = tex0.Sample(samp0, uv + float2(-r1.x, 0.0f)).rgb; + float3 a1 = tex0.Sample(samp0, uv + float2( r1.x, 0.0f)).rgb; + float3 a2 = tex0.Sample(samp0, uv + float2( 0.0f, -r1.y)).rgb; + float3 a3 = tex0.Sample(samp0, uv + float2( 0.0f, r1.y)).rgb; + float3 a4 = tex0.Sample(samp0, uv + float2(-r1.x, -r1.y)).rgb; + float3 a5 = tex0.Sample(samp0, uv + float2( r1.x, -r1.y)).rgb; + float3 a6 = tex0.Sample(samp0, uv + float2(-r1.x, r1.y)).rgb; + float3 a7 = tex0.Sample(samp0, uv + float2( r1.x, r1.y)).rgb; + + float3 b0 = tex0.Sample(samp0, uv + float2(-r2.x, 0.0f)).rgb; + float3 b1 = tex0.Sample(samp0, uv + float2( r2.x, 0.0f)).rgb; + float3 b2 = tex0.Sample(samp0, uv + float2( 0.0f, -r2.y)).rgb; + float3 b3 = tex0.Sample(samp0, uv + float2( 0.0f, r2.y)).rgb; + + float la0 = Luma(a0); + float la1 = Luma(a1); + float la2 = Luma(a2); + float la3 = Luma(a3); + float la4 = Luma(a4); + float la5 = Luma(a5); + float la6 = Luma(a6); + float la7 = Luma(a7); + + float lb0 = Luma(b0); + float lb1 = Luma(b1); + float lb2 = Luma(b2); + float lb3 = Luma(b3); + + float nearAvg = (la0 + la1 + la2 + la3 + la4 + la5 + la6 + la7) * (1.0f / 8.0f); + float farAvg = (lb0 + lb1 + lb2 + lb3) * 0.25f; + + // if center is darker than nearby samples, treat as enclosed/occluded + float enclosedNear = saturate((nearAvg - baseLuma) * 2.4f); + float enclosedFar = saturate((farAvg - baseLuma) * 1.8f); + + // strengthen inside little crevices and cracks + float creviceAO = saturate((-detail) * 7.0f); + + // stronger in darker regions, weaker in highlights + float darkAO = 1.0f - smoothstep(0.18f, 0.80f, baseLuma); + + float ao = enclosedNear * 0.50f + + enclosedFar * 0.25f + + creviceAO * 0.25f; + + ao *= lerp(1.0f, darkAO, aoDarkBoost); + ao = saturate(ao); + ao *= ao; // softer rolloff + + color *= (1.0f - ao * aoStrength); + } + + // Dark-region deepening + float lum = Luma(saturate(color)); + float darkMask = 1.0f - smoothstep(darkEnd, darkStart, lum); + darkMask *= darkMask; + + float creviceMask = saturate((-detail) * 6.0f); + darkMask *= lerp(1.0f, creviceMask, 0.65f); + + color *= (1.0f - darkMask * darkStrength); + + // Slight desaturation for grimier Diablo-like look + color = lerp(color, Luma(color).xxx, 0.12f); + + // Cool shadows / warm mids + { + float gradedLum = Luma(color); + float shadowMask = 1.0f - smoothstep(0.05f, 0.35f, gradedLum); + float midMask = smoothstep(0.18f, 0.55f, gradedLum) * + (1.0f - smoothstep(0.55f, 0.85f, gradedLum)); + + color = lerp(color, color * float3(0.92f, 0.95f, 1.04f), shadowMask * 0.18f); + color = lerp(color, color * float3(1.04f, 1.00f, 0.94f), midMask * 0.10f); + } + + // Slight highlight softening so bright areas don't feel too modern/clean + { + float hl = smoothstep(0.65f, 1.0f, Luma(color)); + color = lerp(color, blur, hl * 0.08f); + } + + // Smart brightness lift + { + float brightLum = Luma(saturate(color)); + float brightMask = 1.0f - smoothstep(0.0f, brightnessLowMax, brightLum); + brightMask = 0.35f + brightMask * 0.65f; + + color *= (1.0f + brightnessLift * brightMask); + } + + // ------------------------------------------------------------------------- + // Advanced multi-radius bloom + // ------------------------------------------------------------------------- + { + float2 off1 = px * 4.0f; + float2 off2 = px * 8.0f; + float2 off3 = px * 10.0f; + + float3 bloomAccum = 0.0f.xxx; + float bloomWeight = 0.0f; + + { + float3 s = BrightPass(c11, bloomThresholdLo, bloomThresholdHi); + bloomAccum += s * 1.20f; + bloomWeight += 1.20f; + } + + { + float3 s0 = BrightPass(tex0.Sample(samp0, uv + float2(-off1.x, 0.0f)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s1 = BrightPass(tex0.Sample(samp0, uv + float2( off1.x, 0.0f)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s2 = BrightPass(tex0.Sample(samp0, uv + float2(0.0f, -off1.y)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s3 = BrightPass(tex0.Sample(samp0, uv + float2(0.0f, off1.y)).rgb, bloomThresholdLo, bloomThresholdHi); + + bloomAccum += (s0 + s1 + s2 + s3) * 0.90f; + bloomWeight += 4.0f * 0.90f; + } + + { + float3 s0 = BrightPass(tex0.Sample(samp0, uv + float2(-off1.x, -off1.y)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s1 = BrightPass(tex0.Sample(samp0, uv + float2( off1.x, -off1.y)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s2 = BrightPass(tex0.Sample(samp0, uv + float2(-off1.x, off1.y)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s3 = BrightPass(tex0.Sample(samp0, uv + float2( off1.x, off1.y)).rgb, bloomThresholdLo, bloomThresholdHi); + + bloomAccum += (s0 + s1 + s2 + s3) * 0.72f; + bloomWeight += 4.0f * 0.72f; + } + + { + float3 s0 = BrightPass(tex0.Sample(samp0, uv + float2(-off2.x, 0.0f)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s1 = BrightPass(tex0.Sample(samp0, uv + float2( off2.x, 0.0f)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s2 = BrightPass(tex0.Sample(samp0, uv + float2(0.0f, -off2.y)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s3 = BrightPass(tex0.Sample(samp0, uv + float2(0.0f, off2.y)).rgb, bloomThresholdLo, bloomThresholdHi); + + bloomAccum += (s0 + s1 + s2 + s3) * 0.52f; + bloomWeight += 4.0f * 0.52f; + } + + { + float3 s0 = BrightPass(tex0.Sample(samp0, uv + float2(-off3.x, 0.0f)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s1 = BrightPass(tex0.Sample(samp0, uv + float2( off3.x, 0.0f)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s2 = BrightPass(tex0.Sample(samp0, uv + float2(0.0f, -off3.y)).rgb, bloomThresholdLo, bloomThresholdHi); + float3 s3 = BrightPass(tex0.Sample(samp0, uv + float2(0.0f, off3.y)).rgb, bloomThresholdLo, bloomThresholdHi); + + bloomAccum += (s0 + s1 + s2 + s3) * 0.30f; + bloomWeight += 4.0f * 0.30f; + } + + float3 bloom = bloomAccum / max(bloomWeight, 1e-5f); + + bloom *= float3(1.10f, 1.02f, 0.90f); + + float bloomLum = Luma(bloom); + float bloomMask = smoothstep(0.02f, 0.75f, bloomLum); + bloom *= (0.65f + bloomMask * 0.35f); + + color += bloom * bloomStrength; + } + + // Film-style grain + { + float2 resolution = float2((float)texWidth, (float)texHeight); + float grain = FilmGrain(uv, resolution); + + float lumNow = Luma(saturate(color)); + float grainMask = 1.0f - smoothstep(0.35f, 0.90f, lumNow); + grainMask = 0.35f + grainMask * 0.65f; + + color += grain.xxx * (0.052f * grainMask); + } + + // Subtle vignette for enclosed dungeon feel + color *= Vignette(uv); + + return float4(saturate(color), 1.0f); +} +)"; + +static bool CompileShaderSource(const char* source, const char* entry, const char* target, ID3DBlob** blobOut) +{ + if (!source || !entry || !target || !blobOut) + return false; + + UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; +#ifdef _DEBUG + flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; +#endif + + ComPtr shaderBlob; + ComPtr errorBlob; + + HRESULT hr = D3DCompile( + source, + strlen(source), + nullptr, + nullptr, + nullptr, + entry, + target, + flags, + 0, + &shaderBlob, + &errorBlob); + + if (FAILED(hr)) + { + if (errorBlob) + OutputDebugStringA((const char*)errorBlob->GetBufferPointer()); + return false; + } + + *blobOut = shaderBlob.Detach(); + return true; +} + +static inline float PixelToNdcX(float x, float width) +{ + return (x / width) * 2.0f - 1.0f; +} + +static inline float PixelToNdcY(float y, float height) +{ + return 1.0f - (y / height) * 2.0f; +} + +static bool SaveBGRA8TextureToPng( + ID3D11Device* device, + ID3D11DeviceContext* context, + ID3D11Texture2D* texture, + const wchar_t* filename) +{ + if (!device || !context || !texture || !filename) + return false; + + D3D11_TEXTURE2D_DESC srcDesc = {}; + texture->GetDesc(&srcDesc); + + D3D11_TEXTURE2D_DESC stagingDesc = srcDesc; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + ComPtr staging; + HRESULT hr = device->CreateTexture2D(&stagingDesc, nullptr, &staging); + if (FAILED(hr)) + return false; + + context->CopyResource(staging.Get(), texture); + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + hr = context->Map(staging.Get(), 0, D3D11_MAP_READ, 0, &mapped); + if (FAILED(hr)) + return false; + + ComPtr factory; + hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&factory)); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + ComPtr stream; + hr = factory->CreateStream(&stream); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + hr = stream->InitializeFromFilename(filename, GENERIC_WRITE); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + ComPtr encoder; + hr = factory->CreateEncoder(GUID_ContainerFormatPng, nullptr, &encoder); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + hr = encoder->Initialize(stream.Get(), WICBitmapEncoderNoCache); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + ComPtr frame; + ComPtr props; + hr = encoder->CreateNewFrame(&frame, &props); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + hr = frame->Initialize(props.Get()); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + hr = frame->SetSize(srcDesc.Width, srcDesc.Height); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + WICPixelFormatGUID format = GUID_WICPixelFormat32bppBGRA; + hr = frame->SetPixelFormat(&format); + if (FAILED(hr)) + { + context->Unmap(staging.Get(), 0); + return false; + } + + hr = frame->WritePixels( + srcDesc.Height, + mapped.RowPitch, + mapped.RowPitch * srcDesc.Height, + reinterpret_cast(mapped.pData)); + + context->Unmap(staging.Get(), 0); + + if (FAILED(hr)) + return false; + + hr = frame->Commit(); + if (FAILED(hr)) + return false; + + hr = encoder->Commit(); + if (FAILED(hr)) + return false; + + return true; +} + +/******************* +**IUnknown methods** +********************/ + +HRESULT __stdcall IDirectDrawWrapper::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) +{ + debugMessage(1, "IDirectDrawWrapper::QueryInterface", "Partially Implemented"); + + if (ppvObj == NULL) + return E_POINTER; + + *ppvObj = NULL; + + if (riid == IID_IUnknown || + riid == IID_IDirectDraw || + riid == IID_IDirectDraw2 || + riid == IID_IDirectDraw4 || + riid == IID_IDirectDraw7) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG __stdcall IDirectDrawWrapper::AddRef() +{ + debugMessage(1, "IDirectDrawWrapper::AddRef", "Partially Implemented"); + ReferenceCount++; + return ReferenceCount; +} + +ULONG __stdcall IDirectDrawWrapper::Release() +{ + debugMessage(1, "IDirectDrawWrapper::Release", "Partially Implemented"); + + if (ReferenceCount > 0) + ReferenceCount--; + + if (ReferenceCount == 0) + { + delete this; + return 0; + } + + return ReferenceCount; +} + +/********************** +**IDirectDraw methods** +***********************/ + +HRESULT __stdcall IDirectDrawWrapper::Compact() +{ + debugMessage(0, "IDirectDrawWrapper::Compact", "Unsupported in DirectDraw"); + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter) +{ + UNREFERENCED_PARAMETER(pUnkOuter); + + char message[2048] = "\0"; + sprintf_s(message, 2048, "Partially Supported dwFlags: %u", dwFlags); + debugMessage(1, "IDirectDrawWrapper::CreateClipper", message); + + if (lplpDDClipper == NULL) + return DDERR_INVALIDPARAMS; + + IDirectDrawClipperWrapper* lpDDClipper = new IDirectDrawClipperWrapper(); + if (lpDDClipper == NULL) + return DDERR_OUTOFMEMORY; + + HRESULT hr = lpDDClipper->WrapperInitialize(dwFlags); + if (hr != DD_OK) + { + delete lpDDClipper; + return hr; + } + + *lplpDDClipper = (LPDIRECTDRAWCLIPPER)lpDDClipper; + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::CreatePalette(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR* lplpDDPalette, IUnknown FAR* pUnkOuter) +{ + UNREFERENCED_PARAMETER(pUnkOuter); + + char message[2048] = "\0"; + sprintf_s(message, 2048, "Created dwFlags: %u", dwFlags); + + if (lplpDDPalette == NULL) + return DDERR_INVALIDPARAMS; + + IDirectDrawPaletteWrapper* lpDDPalette = new IDirectDrawPaletteWrapper(); + if (lpDDPalette == NULL) + return DDERR_OUTOFMEMORY; + + HRESULT hr = lpDDPalette->WrapperInitialize(dwFlags, lpDDColorArray, lplpDDPalette); + if (hr != DD_OK) + { + delete lpDDPalette; + return hr; + } + + *lplpDDPalette = (LPDIRECTDRAWPALETTE)lpDDPalette; + + debugMessage(2, "IDirectDrawWrapper::CreatePalette", message); + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR* lplpDDSurface, IUnknown FAR* pUnkOuter) +{ + UNREFERENCED_PARAMETER(pUnkOuter); + + if (lpDDSurfaceDesc == NULL || lplpDDSurface == NULL) + return DDERR_INVALIDPARAMS; + + char message[2048] = "\0"; + sprintf_s(message, 2048, "lpDDSurfaceDesc->dwFlags:: %u", lpDDSurfaceDesc->dwFlags); + + if (lpAttachedSurface != NULL) + { + delete lpAttachedSurface; + lpAttachedSurface = NULL; + } + + lpAttachedSurface = new IDirectDrawSurfaceWrapper(this); + if (lpAttachedSurface == NULL) + return DDERR_OUTOFMEMORY; + + HRESULT hr = lpAttachedSurface->WrapperInitialize(lpDDSurfaceDesc, displayModeWidth, displayModeHeight, displayWidth, displayHeight); + if (hr != DD_OK) + return hr; + + *lplpDDSurface = (LPDIRECTDRAWSURFACE)lpAttachedSurface; + + debugMessage(2, "IDirectDrawWrapper::CreateSurface", message); + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE FAR* lplpDupDDSurface) +{ + UNREFERENCED_PARAMETER(lpDDSurface); + UNREFERENCED_PARAMETER(lplpDupDDSurface); + debugMessage(0, "DirectDrawWrapper::DuplicateSurface", "Not Implemented"); + return DDERR_GENERIC; +} + +HRESULT __stdcall IDirectDrawWrapper::EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) +{ + UNREFERENCED_PARAMETER(dwFlags); + UNREFERENCED_PARAMETER(lpDDSurfaceDesc); + UNREFERENCED_PARAMETER(lpContext); + UNREFERENCED_PARAMETER(lpEnumModesCallback); + + debugMessage(0, "IDirectDrawWrapper::EnumDisplayModes", "Not Implemented"); + return DDERR_GENERIC; +} + +HRESULT __stdcall IDirectDrawWrapper::EnumSurfaces(DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) +{ + UNREFERENCED_PARAMETER(dwFlags); + UNREFERENCED_PARAMETER(lpDDSD); + UNREFERENCED_PARAMETER(lpContext); + UNREFERENCED_PARAMETER(lpEnumSurfacesCallback); + + debugMessage(0, "IDirectDrawWrapper::EnumSurfaces", "Not Implemented"); + return DDERR_GENERIC; +} + +HRESULT __stdcall IDirectDrawWrapper::FlipToGDISurface() +{ + debugMessage(0, "IDirectDrawWrapper::FlipToGDISurface", "Not Implemented"); + return DDERR_GENERIC; +} + +HRESULT __stdcall IDirectDrawWrapper::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) +{ + debugMessage(0, "IDirectDrawWrapper::GetCaps", "Partially Implemented"); + + if (lpDDDriverCaps == NULL && lpDDHELCaps == NULL) + return DDERR_INVALIDPARAMS; + + if (lpDDDriverCaps != NULL) + { + ZeroMemory(lpDDDriverCaps, lpDDDriverCaps->dwSize); + lpDDDriverCaps->dwCaps = DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_GDI; + lpDDDriverCaps->dwVidMemTotal = 64 * 1024 * 1024; + lpDDDriverCaps->dwVidMemFree = 64 * 1024 * 1024; + } + + if (lpDDHELCaps != NULL) + { + ZeroMemory(lpDDHELCaps, lpDDHELCaps->dwSize); + lpDDHELCaps->dwCaps = DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_GDI; + lpDDHELCaps->dwVidMemTotal = 64 * 1024 * 1024; + lpDDHELCaps->dwVidMemFree = 64 * 1024 * 1024; + } + + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) +{ + debugMessage(0, "IDirectDrawWrapper::GetDisplayMode", "Partially Implemented"); + + if (lpDDSurfaceDesc == NULL) + return DDERR_INVALIDPARAMS; + + ZeroMemory(lpDDSurfaceDesc, sizeof(DDSURFACEDESC)); + lpDDSurfaceDesc->dwSize = sizeof(DDSURFACEDESC); + lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_PITCH; + lpDDSurfaceDesc->dwWidth = displayModeWidth; + lpDDSurfaceDesc->dwHeight = displayModeHeight; + lpDDSurfaceDesc->lPitch = displayModeWidth * 4; + + lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 32; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF; + + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::GetFourCCCodes(LPDWORD lpNumCodes, LPDWORD lpCodes) +{ + debugMessage(0, "IDirectDrawWrapper::GetFourCCCodes", "Partially Implemented"); + + if (lpNumCodes == NULL) + return DDERR_INVALIDPARAMS; + + if (lpCodes == NULL) + { + *lpNumCodes = 0; + } + else + { + *lpNumCodes = 0; + } + + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::GetGDISurface(LPDIRECTDRAWSURFACE FAR* lplpGDIDDSSurface) +{ + debugMessage(0, "IDirectDrawWrapper::GetGDISurface", "Partially Implemented"); + + if (lplpGDIDDSSurface == NULL) + return DDERR_INVALIDPARAMS; + + if (lpAttachedSurface == NULL) + return DDERR_NOTFOUND; + + *lplpGDIDDSSurface = (LPDIRECTDRAWSURFACE)lpAttachedSurface; + lpAttachedSurface->AddRef(); + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::GetMonitorFrequency(LPDWORD lpdwFrequency) +{ + debugMessage(0, "IDirectDrawWrapper::GetMonitorFrequency", "Partially Implemented"); + + if (lpdwFrequency == NULL) + return DDERR_INVALIDPARAMS; + + *lpdwFrequency = refreshRate; + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::GetScanLine(LPDWORD lpdwScanLine) +{ + debugMessage(0, "IDirectDrawWrapper::GetScanLine", "Not Implemented"); + + if (lpdwScanLine == NULL) + return DDERR_INVALIDPARAMS; + + *lpdwScanLine = 0; + return DDERR_UNSUPPORTED; +} + +HRESULT __stdcall IDirectDrawWrapper::GetVerticalBlankStatus(LPBOOL lpbIsInVB) +{ + if (lpbIsInVB == NULL) + return DDERR_INVALIDPARAMS; + + *lpbIsInVB = FALSE; + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::Initialize(GUID FAR* lpGUID) +{ + UNREFERENCED_PARAMETER(lpGUID); + debugMessage(1, "IDirectDrawWrapper::Initialize", "Partially Implemented"); + return DDERR_ALREADYINITIALIZED; +} + +HRESULT __stdcall IDirectDrawWrapper::RestoreDisplayMode() +{ + debugMessage(0, "IDirectDrawWrapper::RestoreDisplayMode", "Partially Implemented"); + + isWindowed = true; + displayWidth = displayWidthWindowed; + displayHeight = displayHeightWindowed; + AdjustWindow(); + ReinitDevice(); + + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::SetCooperativeLevel(HWND in_hWnd, DWORD dwFlags) +{ + char message[2048] = "\0"; + sprintf_s(message, 2048, "Completed in_hWnd: 0x%p, dwFlags: %u", in_hWnd, dwFlags); + + if (in_hWnd == NULL) + { + debugMessage(0, "IDirectDrawWrapper::SetCooperativeLevel", "Unimplemented for NULL window handle"); + return DDERR_GENERIC; + } + + cooperativeFlags = dwFlags; + hWnd = in_hWnd; + +#ifdef _WIN64 + lpPrevWndFunc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC); + if (SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc) == 0) +#else + lpPrevWndFunc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC); + if (SetWindowLong(hWnd, GWL_WNDPROC, (LONG)WndProc) == 0) +#endif + { + debugMessage(0, "IDirectDrawWrapper::SetCooperativeLevel", "Failed to overload WNDPROC"); + } + + AdjustWindow(); + + if (!CreateD3DDevice()) + { + MessageBox(NULL, TEXT("Error creating Direct3D11 Device"), TEXT("Error"), MB_OK | MB_ICONERROR); + return DDERR_GENERIC; + } + + debugMessage(2, "IDirectDrawWrapper::SetCooperativeLevel", message); + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) +{ + char message[2048] = "\0"; + sprintf_s(message, "Complete dwWidth: %u, dwHeight: %u, dwBPP: %u", dwWidth, dwHeight, dwBPP); + + displayModeWidth = dwWidth; + displayModeHeight = dwHeight; + + if (!CreateSurfaceTexture()) + { + MessageBox(NULL, TEXT("Error creating Direct3D11 surface texture"), TEXT("Error"), MB_OK | MB_ICONERROR); + return DDERR_GENERIC; + } + + debugMessage(2, "IDirectDrawWrapper::SetDisplayMode", message); + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::WaitForVerticalBlank(DWORD dwFlags, HANDLE hEvent) +{ + UNREFERENCED_PARAMETER(hEvent); + + if (dwFlags & DDWAITVB_BLOCKBEGINEVENT) + return DDERR_UNSUPPORTED; + + return DD_OK; +} + +/**************************** +**Added in the V2 interface** +*****************************/ + +HRESULT __stdcall IDirectDrawWrapper::GetAvailableVideoMem(LPDDSCAPS2 lpDDSCaps2, LPDWORD lpdwTotal, LPDWORD lpdwFree) +{ + UNREFERENCED_PARAMETER(lpDDSCaps2); + + debugMessage(0, "IDirectDrawWrapper::GetAvailableVideoMem", "Partially Implemented"); + + if (lpDDSCaps2 == NULL || lpdwTotal == NULL || lpdwFree == NULL) + return DDERR_INVALIDPARAMS; + + *lpdwTotal = 64 * 1024 * 1024; + *lpdwFree = 64 * 1024 * 1024; + return DD_OK; +} + +/**************************** +**Added in the V4 interface** +*****************************/ + +HRESULT __stdcall IDirectDrawWrapper::EvaluateMode(DWORD dwFlags, DWORD* pSecondsUntilTimeout) +{ + UNREFERENCED_PARAMETER(dwFlags); + debugMessage(0, "IDirectDrawWrapper::EvaluateMode", "Not Implemented"); + + if (pSecondsUntilTimeout == NULL) + return DDERR_INVALIDPARAMS; + + *pSecondsUntilTimeout = 0; + return DDERR_GENERIC; +} + +HRESULT __stdcall IDirectDrawWrapper::GetDeviceIdentifier(LPDDDEVICEIDENTIFIER2 lpdddi, DWORD dwFlags) +{ + UNREFERENCED_PARAMETER(dwFlags); + + debugMessage(0, "IDirectDrawWrapper::GetDeviceIdentifier", "Partially Implemented"); + + if (lpdddi == NULL) + return DDERR_INVALIDPARAMS; + + ZeroMemory(lpdddi, sizeof(DDDEVICEIDENTIFIER2)); + strcpy_s(lpdddi->szDriver, "D3D11Wrapper"); + strcpy_s(lpdddi->szDescription, "DirectDraw to Direct3D11 Wrapper"); + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::GetSurfaceFromDC(HDC hdc, LPDIRECTDRAWSURFACE7* lpDDS) +{ + UNREFERENCED_PARAMETER(hdc); + + debugMessage(0, "IDirectDrawWrapper::GetSurfaceFromDC", "Not Implemented"); + + if (lpDDS == NULL) + return DDERR_INVALIDPARAMS; + + return DDERR_GENERIC; +} + +HRESULT __stdcall IDirectDrawWrapper::RestoreAllSurfaces() +{ + debugMessage(0, "IDirectDrawWrapper::RestoreAllSurfaces", "Partially Implemented"); + + if (lpAttachedSurface != NULL) + lpAttachedSurface->Restore(); + + return DD_OK; +} + +HRESULT __stdcall IDirectDrawWrapper::StartModeTest(LPSIZE lpModesToTest, DWORD dwNumEntries, DWORD dwFlags) +{ + UNREFERENCED_PARAMETER(lpModesToTest); + UNREFERENCED_PARAMETER(dwNumEntries); + UNREFERENCED_PARAMETER(dwFlags); + + debugMessage(0, "IDirectDrawWrapper::StartModeTest", "Not Implemented"); + return DDERR_GENERIC; +} + +HRESULT __stdcall IDirectDrawWrapper::TestCooperativeLevel() +{ + debugMessage(0, "IDirectDrawWrapper::TestCooperativeLevel", "Partially Implemented"); + + if (!d3d11Device || !swapChain) + return DDERR_GENERIC; + + return DD_OK; +} + +// Default constructor +IDirectDrawWrapper::IDirectDrawWrapper() +{ + hWnd = NULL; + WndProc = NULL; + lpPrevWndFunc = NULL; + hModule = NULL; + + cooperativeFlags = 0; + ReferenceCount = 0; + + lpAttachedSurface = NULL; + + inMenu = false; + curMenu = 0; + + curMenuFrame = 0; + menuTextureWidth = 512; + menuTextureHeight = 512; + + menuLocations[0] = 117; + menuLocations[1] = 162; + menuLocations[2] = 208; + menuLocations[3] = 253; + menuLocations[4] = 298; + + menuSprites[0].left = 0; + menuSprites[0].top = 0; + menuSprites[0].right = 30; + menuSprites[0].bottom = 32; + + menuSprites[1].left = menuSprites[0].right; + menuSprites[1].top = 0; + menuSprites[1].right = menuSprites[1].left + 14; + menuSprites[1].bottom = 32; + + menuSprites[2].left = menuSprites[1].right; + menuSprites[2].top = 0; + menuSprites[2].right = menuSprites[2].left + 22; + menuSprites[2].bottom = 32; + + menuSprites[3].left = menuSprites[2].right; + menuSprites[3].top = 0; + menuSprites[3].right = menuSprites[3].left + 21; + menuSprites[3].bottom = 32; + + menuSprites[4].left = menuSprites[3].right; + menuSprites[4].top = 0; + menuSprites[4].right = menuSprites[4].left + 23; + menuSprites[4].bottom = 32; + + menuSprites[5].left = menuSprites[4].right; + menuSprites[5].top = 0; + menuSprites[5].right = menuSprites[5].left + 21; + menuSprites[5].bottom = 32; + + menuSprites[6].left = menuSprites[5].right; + menuSprites[6].top = 0; + menuSprites[6].right = menuSprites[6].left + 20; + menuSprites[6].bottom = 32; + + menuSprites[7].left = menuSprites[6].right; + menuSprites[7].top = 0; + menuSprites[7].right = menuSprites[7].left + 21; + menuSprites[7].bottom = 32; + + menuSprites[8].left = menuSprites[7].right; + menuSprites[8].top = 0; + menuSprites[8].right = menuSprites[8].left + 20; + menuSprites[8].bottom = 32; + + menuSprites[9].left = menuSprites[8].right; + menuSprites[9].top = 0; + menuSprites[9].right = menuSprites[9].left + 21; + menuSprites[9].bottom = 32; + + menuSprites[10].left = menuSprites[9].right; + menuSprites[10].top = 0; + menuSprites[10].right = menuSprites[10].left + 25; + menuSprites[10].bottom = 32; + + menuSprites[11].left = 0; + menuSprites[11].top = 32; + menuSprites[11].right = 246; + menuSprites[11].bottom = 64; + + menuSprites[12].left = 0; + menuSprites[12].top = 64; + menuSprites[12].right = 243; + menuSprites[12].bottom = 96; + + menuSprites[13].left = 0; + menuSprites[13].top = 96; + menuSprites[13].right = 144; + menuSprites[13].bottom = 128; + + menuSprites[14].left = 0; + menuSprites[14].top = 128; + menuSprites[14].right = 151; + menuSprites[14].bottom = 160; + + menuSprites[15].left = 160; + menuSprites[15].top = 96; + menuSprites[15].right = menuSprites[15].left + 55; + menuSprites[15].bottom = 128; + + menuSprites[16].left = 160; + menuSprites[16].top = 128; + menuSprites[16].right = menuSprites[15].left + 69; + menuSprites[16].bottom = 160; + + menuSprites[17].left = 0; + menuSprites[17].top = 256; + menuSprites[17].right = 295; + menuSprites[17].bottom = 356; + + windowedResolutions = new POINT[10]; + windowedResolutionCount = 10; + windowedResolutions[0].x = 640; windowedResolutions[0].y = 480; + windowedResolutions[1].x = 800; windowedResolutions[1].y = 600; + windowedResolutions[2].x = 960; windowedResolutions[2].y = 720; + windowedResolutions[3].x = 1024; windowedResolutions[3].y = 768; + windowedResolutions[4].x = 1152; windowedResolutions[4].y = 864; + windowedResolutions[5].x = 1280; windowedResolutions[5].y = 960; + windowedResolutions[6].x = 1400; windowedResolutions[6].y = 1050; + windowedResolutions[7].x = 1440; windowedResolutions[7].y = 1080; + windowedResolutions[8].x = 1600; windowedResolutions[8].y = 1200; + windowedResolutions[9].x = 1920; windowedResolutions[9].y = 1440; + + fullscreenResolutionCount = 0; + fullscreenResolutions = NULL; + fullscreenRefreshes = NULL; + + displayModeWidth = 640; + displayModeHeight = 480; + + displayWidthWindowed = 640; + displayHeightWindowed = 480; + displayWidthFullscreen = 640; + displayHeightFullscreen = 480; + + displayWidth = 640; + displayHeight = 480; + + refreshRate = 60; + isWindowed = true; + vSync = true; + + menuWindowed = true; + menuvSync = true; + menuWindowedResolution = 0; + menuFullscreenResolution = 0; + + lastPosition.x = 100; + lastPosition.y = 100; + + ZeroMemory(&swapDesc, sizeof(swapDesc)); + + CoInitialize(NULL); + + wchar_t curPath[MAX_PATH]; + wchar_t filename[MAX_PATH]; + wchar_t temp[1024]; + + GetCurrentDirectory(MAX_PATH, curPath); + wsprintf(filename, TEXT("%s\\hellfire_settings.ini"), curPath); + + GetPrivateProfileString(TEXT("video"), TEXT("windowedResolution"), TEXT("640x480"), temp, 1024, filename); + for (int i = 0; i < 1024 && temp[i] != TEXT('\0'); i++) + { + if (temp[i] == TEXT('x') || temp[i] == TEXT('X')) + { + temp[i] = TEXT('\0'); + displayWidthWindowed = _wtoi(temp); + displayHeightWindowed = _wtoi(&(temp[i + 1])); + if (displayWidthWindowed == 0 || displayHeightWindowed == 0) + { + displayWidthWindowed = 640; + displayHeightWindowed = 480; + } + break; + } + } + + GetPrivateProfileString(TEXT("video"), TEXT("fullscreenResolution"), TEXT("640x480"), temp, 1024, filename); + for (int i = 0; i < 1024 && temp[i] != TEXT('\0'); i++) + { + if (temp[i] == TEXT('x') || temp[i] == TEXT('X')) + { + temp[i] = TEXT('\0'); + displayWidthFullscreen = _wtoi(temp); + displayHeightFullscreen = _wtoi(&(temp[i + 1])); + if (displayWidthFullscreen == 0 || displayHeightFullscreen == 0) + { + displayWidthFullscreen = 640; + displayHeightFullscreen = 480; + } + break; + } + } + + GetPrivateProfileString(TEXT("video"), TEXT("fullscreen"), TEXT("0"), temp, 1024, filename); + if (temp[0] == TEXT('1')) + isWindowed = false; + else + isWindowed = true; + + if (isWindowed) + { + displayWidth = displayWidthWindowed; + displayHeight = displayHeightWindowed; + } + else + { + displayWidth = displayWidthFullscreen; + displayHeight = displayHeightFullscreen; + } + + GetPrivateProfileString(TEXT("video"), TEXT("vsync"), TEXT("1"), temp, 1024, filename); + if (temp[0] == TEXT('1')) + vSync = true; + else + vSync = false; + + GetPrivateProfileString(TEXT("video"), TEXT("refresh"), TEXT("60"), temp, 1024, filename); + refreshRate = _wtoi(temp); + if (refreshRate == 0) + refreshRate = 60; + + AddRef(); + + debugMessage(2, "IDirectDrawWrapper::IDirectDrawWrapper", "Created"); +} + +IDirectDrawWrapper::~IDirectDrawWrapper() +{ + if (d3d11Context) + { + d3d11Context->ClearState(); + d3d11Context->Flush(); + } + + if (lpAttachedSurface != NULL) + { + delete lpAttachedSurface; + lpAttachedSurface = NULL; + } + + menuSRV.Reset(); + menuTexture.Reset(); + menuVertexBuffer.Reset(); + + surfaceSRV.Reset(); + surfaceTexture.Reset(); + + vertexBuffer.Reset(); + inputLayout.Reset(); + blitVS.Reset(); + blitPS.Reset(); + samplerLinear.Reset(); + alphaBlendState.Reset(); + rasterState.Reset(); + renderTargetView.Reset(); + swapChain.Reset(); + d3d11Context.Reset(); + d3d11Device.Reset(); + + SAFE_DELETE_ARRAY(windowedResolutions); + windowedResolutionCount = 0; + + SAFE_DELETE_ARRAY(fullscreenResolutions); + fullscreenResolutionCount = 0; + + SAFE_DELETE_ARRAY(fullscreenRefreshes); + + CoUninitialize(); + + debugMessage(2, "IDirectDrawWrapper::~IDirectDrawWrapper", "Destroyed"); +} + +HRESULT IDirectDrawWrapper::WrapperInitialize(WNDPROC wp, HMODULE hMod) +{ + WndProc = wp; + hModule = hMod; + + ZeroMemory(&swapDesc, sizeof(swapDesc)); + + debugMessage(2, "IDirectDrawWrapper::WrapperInitialize", "Initialized"); + return DD_OK; +} + +bool IDirectDrawWrapper::CreateRenderTarget() +{ + renderTargetView.Reset(); + + ComPtr backBuffer; + HRESULT hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuffer.GetAddressOf()); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateRenderTarget", "GetBuffer failed"); + return false; + } + + hr = d3d11Device->CreateRenderTargetView(backBuffer.Get(), nullptr, &renderTargetView); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateRenderTarget", "CreateRenderTargetView failed"); + return false; + } + + return true; +} + +bool IDirectDrawWrapper::CreateShaders() +{ + ComPtr vsBlob; + ComPtr psBlob; + + if (!CompileShaderSource(g_BlitVS_HLSL, "main", "vs_4_0", &vsBlob)) + { + debugMessage(0, "IDirectDrawWrapper::CreateShaders", "Vertex shader compile failed"); + return false; + } + + if (!CompileShaderSource(g_BlitPS_HLSL, "main", "ps_4_0", &psBlob)) + { + debugMessage(0, "IDirectDrawWrapper::CreateShaders", "Pixel shader compile failed"); + return false; + } + + HRESULT hr = d3d11Device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &blitVS); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateShaders", "CreateVertexShader failed"); + return false; + } + + hr = d3d11Device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &blitPS); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateShaders", "CreatePixelShader failed"); + return false; + } + + D3D11_INPUT_ELEMENT_DESC layout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(TLVERTEX11, x), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(TLVERTEX11, u), D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + + hr = d3d11Device->CreateInputLayout( + layout, + _countof(layout), + vsBlob->GetBufferPointer(), + vsBlob->GetBufferSize(), + &inputLayout); + + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateShaders", "CreateInputLayout failed"); + return false; + } + + return true; +} + +bool IDirectDrawWrapper::CreateMenuVertexBuffer() +{ + menuVertexBuffer.Reset(); + + D3D11_BUFFER_DESC vbDesc = {}; + vbDesc.ByteWidth = sizeof(SpriteVertex11) * 4; + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + HRESULT hr = d3d11Device->CreateBuffer(&vbDesc, nullptr, &menuVertexBuffer); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateMenuVertexBuffer", "CreateBuffer failed"); + return false; + } + + return true; +} + +bool IDirectDrawWrapper::CreateD3DDevice() +{ + if (d3d11Context) + { + d3d11Context->ClearState(); + d3d11Context->Flush(); + } + + menuSRV.Reset(); + menuTexture.Reset(); + menuVertexBuffer.Reset(); + + surfaceSRV.Reset(); + surfaceTexture.Reset(); + vertexBuffer.Reset(); + + inputLayout.Reset(); + blitVS.Reset(); + blitPS.Reset(); + samplerLinear.Reset(); + alphaBlendState.Reset(); + rasterState.Reset(); + renderTargetView.Reset(); + swapChain.Reset(); + d3d11Context.Reset(); + d3d11Device.Reset(); + + SAFE_DELETE_ARRAY(fullscreenResolutions); + SAFE_DELETE_ARRAY(fullscreenRefreshes); + fullscreenResolutionCount = 0; + + ComPtr dxgiFactory; + ComPtr adapter; + ComPtr output; + + HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)dxgiFactory.GetAddressOf()); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "CreateDXGIFactory failed"); + return false; + } + + hr = dxgiFactory->EnumAdapters(0, &adapter); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "EnumAdapters failed"); + return false; + } + + hr = adapter->EnumOutputs(0, &output); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "EnumOutputs failed"); + return false; + } + + UINT modeCount = 0; + hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &modeCount, nullptr); + if (FAILED(hr) || modeCount == 0) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "GetDisplayModeList count failed"); + return false; + } + + DXGI_MODE_DESC* modes = new DXGI_MODE_DESC[modeCount]; + hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &modeCount, modes); + if (FAILED(hr)) + { + SAFE_DELETE_ARRAY(modes); + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "GetDisplayModeList failed"); + return false; + } + + fullscreenResolutions = new POINT[modeCount]; + fullscreenRefreshes = new UINT[modeCount]; + + bool modeFound = false; + for (UINT i = 0; i < modeCount; i++) + { + const DXGI_MODE_DESC& m = modes[i]; + UINT refresh = 60; + if (m.RefreshRate.Denominator != 0) + refresh = m.RefreshRate.Numerator / m.RefreshRate.Denominator; + + if (m.Width == (UINT)displayWidth && m.Height == (UINT)displayHeight && refresh == refreshRate) + { + modeFound = true; + menuFullscreenResolution = fullscreenResolutionCount; + } + + if (m.Width < 1920 && m.Height < 1440) + { + fullscreenResolutions[fullscreenResolutionCount].x = (LONG)m.Width; + fullscreenResolutions[fullscreenResolutionCount].y = (LONG)m.Height; + fullscreenRefreshes[fullscreenResolutionCount] = refresh; + fullscreenResolutionCount++; + } + } + + SAFE_DELETE_ARRAY(modes); + + ZeroMemory(&swapDesc, sizeof(swapDesc)); + swapDesc.BufferCount = 1; + swapDesc.BufferDesc.Width = isWindowed ? 0 : displayWidth; + swapDesc.BufferDesc.Height = isWindowed ? 0 : displayHeight; + swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapDesc.BufferDesc.RefreshRate.Numerator = vSync ? refreshRate : 0; + swapDesc.BufferDesc.RefreshRate.Denominator = vSync ? 1 : 0; + swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapDesc.OutputWindow = hWnd; + swapDesc.SampleDesc.Count = 1; + swapDesc.SampleDesc.Quality = 0; + swapDesc.Windowed = isWindowed ? TRUE : FALSE; + swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + UINT createFlags = 0; +#ifdef _DEBUG + createFlags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + D3D_FEATURE_LEVEL featureLevelOut = D3D_FEATURE_LEVEL_11_0; + D3D_FEATURE_LEVEL levels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; + + hr = D3D11CreateDeviceAndSwapChain( + nullptr, + D3D_DRIVER_TYPE_HARDWARE, + nullptr, + createFlags, + levels, + _countof(levels), + D3D11_SDK_VERSION, + &swapDesc, + &swapChain, + &d3d11Device, + &featureLevelOut, + &d3d11Context); + + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "D3D11CreateDeviceAndSwapChain failed"); + MessageBox(NULL, TEXT("Failed to create Direct3D11 device."), TEXT("Direct3D11 Device Error"), MB_OK); + return false; + } + + if (!isWindowed && modeFound) + swapChain->SetFullscreenState(TRUE, nullptr); + else + swapChain->SetFullscreenState(FALSE, nullptr); + + if (!CreateRenderTarget()) + return false; + + D3D11_VIEWPORT vp = {}; + vp.TopLeftX = 0.0f; + vp.TopLeftY = 0.0f; + vp.Width = (FLOAT)displayWidth; + vp.Height = (FLOAT)displayHeight; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + d3d11Context->RSSetViewports(1, &vp); + + if (!CreateShaders()) + return false; + + D3D11_SAMPLER_DESC samp = {}; + samp.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samp.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + samp.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + samp.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + samp.MinLOD = 0.0f; + samp.MaxLOD = D3D11_FLOAT32_MAX; + + hr = d3d11Device->CreateSamplerState(&samp, &samplerLinear); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "CreateSamplerState failed"); + return false; + } + + D3D11_BLEND_DESC blend = {}; + blend.RenderTarget[0].BlendEnable = TRUE; + blend.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blend.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blend.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blend.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + blend.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blend.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + hr = d3d11Device->CreateBlendState(&blend, &alphaBlendState); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "CreateBlendState failed"); + return false; + } + + D3D11_RASTERIZER_DESC rs = {}; + rs.FillMode = D3D11_FILL_SOLID; + rs.CullMode = D3D11_CULL_NONE; + rs.ScissorEnable = FALSE; + rs.DepthClipEnable = TRUE; + + hr = d3d11Device->CreateRasterizerState(&rs, &rasterState); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateD3DDevice", "CreateRasterizerState failed"); + return false; + } + + d3d11Context->RSSetState(rasterState.Get()); + + if (!CreateMenuVertexBuffer()) + return false; + + debugMessage(2, "IDirectDrawWrapper::CreateD3DDevice", "Create D3D11 Object"); + return true; +} + +bool IDirectDrawWrapper::CreateSurfaceTexture() +{ + surfaceSRV.Reset(); + surfaceTexture.Reset(); + vertexBuffer.Reset(); + + if (!d3d11Device) + { + debugMessage(0, "IDirectDrawWrapper::CreateSurfaceTexture", "No D3D11 device"); + return false; + } + + D3D11_TEXTURE2D_DESC texDesc = {}; + texDesc.Width = displayModeWidth; + texDesc.Height = displayModeHeight; + texDesc.MipLevels = 1; + texDesc.ArraySize = 1; + texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + texDesc.SampleDesc.Count = 1; + texDesc.Usage = D3D11_USAGE_DYNAMIC; + texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + HRESULT hr = d3d11Device->CreateTexture2D(&texDesc, nullptr, &surfaceTexture); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateSurfaceTexture", "Unable to create surface texture"); + return false; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Format = texDesc.Format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = 1; + + hr = d3d11Device->CreateShaderResourceView(surfaceTexture.Get(), &srvDesc, &surfaceSRV); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateSurfaceTexture", "Unable to create SRV"); + return false; + } + + TLVERTEX11 vertices[4]; + vertices[0] = { -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; + vertices[1] = { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f }; + vertices[2] = { -1.0f, -1.0f, 0.0f, 0.0f, 1.0f }; + vertices[3] = { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f }; + + D3D11_BUFFER_DESC vbDesc = {}; + vbDesc.ByteWidth = sizeof(vertices); + vbDesc.Usage = D3D11_USAGE_IMMUTABLE; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + + D3D11_SUBRESOURCE_DATA initData = {}; + initData.pSysMem = vertices; + + hr = d3d11Device->CreateBuffer(&vbDesc, &initData, &vertexBuffer); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::CreateSurfaceTexture", "Unable to create vertex buffer"); + return false; + } + + debugMessage(2, "IDirectDrawWrapper::CreateSurfaceTexture", "D3D11 Texture Created"); + return true; +} + +HRESULT IDirectDrawWrapper::Present() +{ + if (!d3d11Device || !d3d11Context || !swapChain) + { + debugMessage(0, "IDirectDrawWrapper::Present", "Present called when D3D11 device doesn't exist"); + return false; + } + + if (!surfaceTexture || !surfaceSRV) + { + debugMessage(0, "IDirectDrawWrapper::Present", "Present called when texture doesn't exist"); + return false; + } + + if (lpAttachedSurface != NULL) + { + D3D11_MAPPED_SUBRESOURCE mapped = {}; + HRESULT hr = d3d11Context->Map(surfaceTexture.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::Present", "Failed to map texture memory"); + return false; + } + + for (DWORD y = 0; y < displayModeHeight; y++) + { + memcpy( + (BYTE*)mapped.pData + (y * mapped.RowPitch), + &lpAttachedSurface->rgbVideoMem[y * displayModeWidth], + displayModeWidth * sizeof(UINT32)); + } + + d3d11Context->Unmap(surfaceTexture.Get(), 0); + } + else + { + debugMessage(1, "IDirectDrawWrapper::Present", "Attempt to Present with no attached surface"); + } + + float clearColor[4] = { 0, 0, 0, 1 }; + d3d11Context->OMSetRenderTargets(1, renderTargetView.GetAddressOf(), nullptr); + d3d11Context->ClearRenderTargetView(renderTargetView.Get(), clearColor); + + D3D11_VIEWPORT vp = {}; + vp.TopLeftX = 0.0f; + vp.TopLeftY = 0.0f; + vp.Width = (FLOAT)displayWidth; + vp.Height = (FLOAT)displayHeight; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + d3d11Context->RSSetViewports(1, &vp); + + UINT stride = sizeof(TLVERTEX11); + UINT offset = 0; + + d3d11Context->IASetInputLayout(inputLayout.Get()); + d3d11Context->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset); + d3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + d3d11Context->VSSetShader(blitVS.Get(), nullptr, 0); + d3d11Context->PSSetShader(blitPS.Get(), nullptr, 0); + d3d11Context->PSSetShaderResources(0, 1, surfaceSRV.GetAddressOf()); + d3d11Context->PSSetSamplers(0, 1, samplerLinear.GetAddressOf()); + + float blendFactor[4] = { 0, 0, 0, 0 }; + d3d11Context->OMSetBlendState(nullptr, blendFactor, 0xFFFFFFFF); + + d3d11Context->Draw(4, 0); + + if (inMenu) + RenderMenuD3D11(); + + HRESULT hr = swapChain->Present(vSync ? 1 : 0, 0); + if (FAILED(hr)) + { + if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) + { + debugMessage(1, "IDirectDrawWrapper::Present", "Device removed/reset"); + return ReinitDevice(); + } + + debugMessage(0, "IDirectDrawWrapper::Present", "Failed to present scene"); + return false; + } + + return true; +} + +BOOL IDirectDrawWrapper::MenuKey(WPARAM vKey) +{ + if (vKey == VK_OEM_3) + { + if (inMenu == TRUE) + { + inMenu = FALSE; + } + else + { + curMenu = 0; + menuWindowed = isWindowed; + menuvSync = vSync; + menuWindowedResolution = 0; + menuFullscreenResolution = 0; + + for (int i = 0; i < windowedResolutionCount; i++) + { + if (windowedResolutions[i].x == displayWidthWindowed && windowedResolutions[i].y == displayHeightWindowed) + { + menuWindowedResolution = i; + break; + } + } + + for (int i = 0; i < fullscreenResolutionCount; i++) + { + if (fullscreenResolutions[i].x == displayWidthFullscreen && + fullscreenResolutions[i].y == displayHeightFullscreen && + fullscreenRefreshes[i] == refreshRate) + { + menuFullscreenResolution = i; + break; + } + } + + inMenu = TRUE; + } + + Present(); + } + else if (vKey == VK_ESCAPE) + { + inMenu = FALSE; + Present(); + } + else if (vKey == VK_DOWN) + { + curMenu++; + if (curMenu > 3) curMenu = 0; + Present(); + } + else if (vKey == VK_UP) + { + curMenu--; + if (curMenu < 0) curMenu = 3; + Present(); + } + else if (vKey == VK_RIGHT) + { + if (curMenu == 0) + { + if (menuWindowed) + { + menuWindowedResolution++; + if (menuWindowedResolution >= windowedResolutionCount) + menuWindowedResolution = 0; + } + else + { + menuFullscreenResolution++; + if (menuFullscreenResolution >= fullscreenResolutionCount) + menuFullscreenResolution = 0; + } + } + else if (curMenu == 1) + { + menuWindowed = !menuWindowed; + } + else if (curMenu == 2) + { + menuvSync = !menuvSync; + } + Present(); + } + else if (vKey == VK_LEFT) + { + if (curMenu == 0) + { + if (menuWindowed) + { + menuWindowedResolution--; + if (menuWindowedResolution < 0) + menuWindowedResolution = windowedResolutionCount - 1; + } + else + { + menuFullscreenResolution--; + if (menuFullscreenResolution < 0) + menuFullscreenResolution = fullscreenResolutionCount - 1; + } + } + else if (curMenu == 1) + { + menuWindowed = !menuWindowed; + } + else if (curMenu == 2) + { + menuvSync = !menuvSync; + } + Present(); + } + else if (vKey == VK_RETURN) + { + inMenu = false; + + isWindowed = menuWindowed; + + if (menuWindowed) + { + displayWidth = windowedResolutions[menuWindowedResolution].x; + displayHeight = windowedResolutions[menuWindowedResolution].y; + displayWidthWindowed = displayWidth; + displayHeightWindowed = displayHeight; + } + else + { + if (fullscreenResolutionCount > 0) + { + displayWidth = fullscreenResolutions[menuFullscreenResolution].x; + displayHeight = fullscreenResolutions[menuFullscreenResolution].y; + refreshRate = fullscreenRefreshes[menuFullscreenResolution]; + displayWidthFullscreen = displayWidth; + displayHeightFullscreen = displayHeight; + } + } + + vSync = menuvSync; + + AdjustWindow(); + + if (swapChain) + swapChain->SetFullscreenState(isWindowed ? FALSE : TRUE, nullptr); + + ReinitDevice(); + Present(); + + wchar_t curPath[MAX_PATH]; + wchar_t filename[MAX_PATH]; + wchar_t temp[1024]; + + GetCurrentDirectory(MAX_PATH, curPath); + wsprintf(filename, TEXT("%s\\ddraw_settings.ini"), curPath); + + wsprintf(temp, TEXT("%dx%d"), displayWidthWindowed, displayHeightWindowed); + WritePrivateProfileString(TEXT("video"), TEXT("windowedResolution"), temp, filename); + + wsprintf(temp, TEXT("%dx%d"), displayWidthFullscreen, displayHeightFullscreen); + WritePrivateProfileString(TEXT("video"), TEXT("fullscreenResolution"), temp, filename); + + wsprintf(temp, TEXT("%d"), refreshRate); + WritePrivateProfileString(TEXT("video"), TEXT("refresh"), temp, filename); + + wsprintf(temp, TEXT("%d"), isWindowed ? 0 : 1); + WritePrivateProfileString(TEXT("video"), TEXT("fullscreen"), temp, filename); + + wsprintf(temp, TEXT("%d"), vSync ? 1 : 0); + WritePrivateProfileString(TEXT("video"), TEXT("vsync"), temp, filename); + } + + return inMenu; +} + +void IDirectDrawWrapper::ToggleFullscreen() +{ + if (isWindowed) + { + isWindowed = false; + displayWidth = displayWidthFullscreen; + displayHeight = displayHeightFullscreen; + } + else + { + isWindowed = true; + displayWidth = displayWidthWindowed; + displayHeight = displayHeightWindowed; + } + + AdjustWindow(); + + if (swapChain) + swapChain->SetFullscreenState(isWindowed ? FALSE : TRUE, nullptr); + + ReinitDevice(); + Present(); +} + +void IDirectDrawWrapper::DoSnapshot() +{ + if (!surfaceTexture || !d3d11Device || !d3d11Context) + { + debugMessage(0, "IDirectDrawWrapper::DoSnapshot", "No surface texture to save."); + return; + } + + wchar_t curPath[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, curPath); + + wchar_t filename[MAX_PATH]; + SYSTEMTIME sysTime; + GetSystemTime(&sysTime); + + wchar_t title[1024]; + GetWindowText(hWnd, title, 1024); + + wsprintf( + filename, + TEXT("%s\\%s_%.4d%.2d%.2d_%.2d%.2d%.2d.png"), + curPath, + title, + sysTime.wYear, sysTime.wMonth, sysTime.wDay, + sysTime.wHour, sysTime.wMinute, sysTime.wSecond); + + WIN32_FIND_DATA findData; + HANDLE findHandle = FindFirstFile(filename, &findData); + int curFileNum = 1; + while (findHandle != INVALID_HANDLE_VALUE) + { + FindClose(findHandle); + wsprintf( + filename, + TEXT("%s\\Diablo_%.4d%.2d%.2d_%.2d%.2d%.2d(%d).png"), + curPath, + sysTime.wYear, sysTime.wMonth, sysTime.wDay, + sysTime.wHour, sysTime.wMinute, sysTime.wSecond, + curFileNum); + curFileNum++; + findHandle = FindFirstFile(filename, &findData); + } + + if (!SaveBGRA8TextureToPng(d3d11Device.Get(), d3d11Context.Get(), surfaceTexture.Get(), filename)) + { + debugMessage(0, "IDirectDrawWrapper::DoSnapshot", "Error saving texture to file."); + return; + } + + debugMessage(2, "IDirectDrawWrapper::DoSnapshot", "Saved Screenshot"); +} + +void IDirectDrawWrapper::AdjustWindow() +{ + if (hWnd == NULL) + return; + + if (isWindowed) + { +#ifdef _WIN64 + SetWindowLongPtr(hWnd, GWL_STYLE, WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); +#else + SetWindowLong(hWnd, GWL_STYLE, WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); +#endif + + RECT rc = { 0, 0, displayWidth, displayHeight }; + AdjustWindowRect(&rc, GetWindowLong(hWnd, GWL_STYLE), FALSE); + + SetWindowPos( + hWnd, + NULL, + lastPosition.x, + lastPosition.y, + rc.right - rc.left, + rc.bottom - rc.top, + SWP_NOZORDER | SWP_FRAMECHANGED); + } + else + { +#ifdef _WIN64 + SetWindowLongPtr(hWnd, GWL_STYLE, WS_VISIBLE | WS_POPUP); +#else + SetWindowLong(hWnd, GWL_STYLE, WS_VISIBLE | WS_POPUP); +#endif + + SetWindowPos( + hWnd, + NULL, + 0, + 0, + displayWidth, + displayHeight, + SWP_NOZORDER | SWP_FRAMECHANGED); + } + + debugMessage(2, "IDirectDrawWrapper::AdjustWindow", "Complete"); +} + +bool IDirectDrawWrapper::DrawMenuSprite(const RECT& srcRect, float dstX, float dstY, float dstW, float dstH) +{ + if (!menuVertexBuffer || !menuSRV) + return false; + + float screenW = (float)displayWidth; + float screenH = (float)displayHeight; + + float x0 = PixelToNdcX(dstX, screenW); + float y0 = PixelToNdcY(dstY, screenH); + float x1 = PixelToNdcX(dstX + dstW, screenW); + float y1 = PixelToNdcY(dstY + dstH, screenH); + + float u0 = (float)srcRect.left / (float)menuTextureWidth; + float v0 = (float)srcRect.top / (float)menuTextureHeight; + float u1 = (float)srcRect.right / (float)menuTextureWidth; + float v1 = (float)srcRect.bottom / (float)menuTextureHeight; + + SpriteVertex11 verts[4] = + { + { x0, y0, 0.0f, u0, v0 }, + { x1, y0, 0.0f, u1, v0 }, + { x0, y1, 0.0f, u0, v1 }, + { x1, y1, 0.0f, u1, v1 } + }; + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + HRESULT hr = d3d11Context->Map(menuVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + if (FAILED(hr)) + return false; + + memcpy(mapped.pData, verts, sizeof(verts)); + d3d11Context->Unmap(menuVertexBuffer.Get(), 0); + + UINT stride = sizeof(SpriteVertex11); + UINT offset = 0; + + d3d11Context->IASetInputLayout(inputLayout.Get()); + d3d11Context->IASetVertexBuffers(0, 1, menuVertexBuffer.GetAddressOf(), &stride, &offset); + d3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + d3d11Context->VSSetShader(blitVS.Get(), nullptr, 0); + d3d11Context->PSSetShader(blitPS.Get(), nullptr, 0); + d3d11Context->PSSetShaderResources(0, 1, menuSRV.GetAddressOf()); + d3d11Context->PSSetSamplers(0, 1, samplerLinear.GetAddressOf()); + + float blendFactor[4] = { 0, 0, 0, 0 }; + d3d11Context->OMSetBlendState(alphaBlendState.Get(), blendFactor, 0xFFFFFFFF); + + d3d11Context->Draw(4, 0); + return true; +} + +void IDirectDrawWrapper::RenderMenuD3D11() +{ + if (!menuSRV) + return; + + float sx = (float)displayWidth / 640.0f; + float sy = (float)displayHeight / 480.0f; + + int selectionLeft = 0; + int selectionRight = 0; + + { + RECT r = menuSprites[17]; + float x = (640.0f - (float)(r.right - r.left)) / 2.0f; + float y = 3.0f; + DrawMenuSprite(r, x * sx, y * sy, (r.right - r.left) * sx, (r.bottom - r.top) * sy); + } + + { + RECT r = menuSprites[11]; + float x = (640.0f - (float)(r.right - r.left)) / 2.0f; + float y = (float)menuLocations[0]; + DrawMenuSprite(r, x * sx, y * sy, (r.right - r.left) * sx, (r.bottom - r.top) * sy); + } + + { + char temp[1024]; + if (menuWindowed) + sprintf_s(temp, 1024, "%dx%d", windowedResolutions[menuWindowedResolution].x, windowedResolutions[menuWindowedResolution].y); + else if (fullscreenResolutionCount > 0) + sprintf_s(temp, 1024, "%dx%dx%d", fullscreenResolutions[menuFullscreenResolution].x, fullscreenResolutions[menuFullscreenResolution].y, fullscreenRefreshes[menuFullscreenResolution]); + else + sprintf_s(temp, 1024, "%dx%d", displayWidth, displayHeight); + + int resolutionStringWidth = 0; + for (size_t i = 0; i < strlen(temp); i++) + { + if (temp[i] != 'x') + resolutionStringWidth += menuSprites[temp[i] - '0'].right - menuSprites[temp[i] - '0'].left; + else + resolutionStringWidth += menuSprites[10].right - menuSprites[10].left; + } + + float x = (640.0f - (float)resolutionStringWidth) / 2.0f; + float y = (float)menuLocations[1]; + + if (curMenu == 0) + { + selectionLeft = (int)x - 52; + selectionRight = (int)x + resolutionStringWidth + 10; + } + + for (size_t i = 0; i < strlen(temp); i++) + { + RECT r = (temp[i] != 'x') ? menuSprites[temp[i] - '0'] : menuSprites[10]; + float w = (float)(r.right - r.left); + float h = (float)(r.bottom - r.top); + DrawMenuSprite(r, x * sx, y * sy, w * sx, h * sy); + x += w; + } + } + + { + RECT label = menuSprites[12]; + float labelX = (640.0f - ((float)(menuSprites[12].right - menuSprites[12].left) + (float)(menuSprites[16].right - menuSprites[16].left) + 10.0f)) / 2.0f; + float y = (float)menuLocations[2]; + + if (curMenu == 1) + { + selectionLeft = (int)labelX - 52; + selectionRight = (int)labelX + (menuSprites[12].right - menuSprites[12].left) + (menuSprites[16].right - menuSprites[16].left) + 20; + } + + DrawMenuSprite(label, labelX * sx, y * sy, (label.right - label.left) * sx, (label.bottom - label.top) * sy); + + if (menuWindowed) + { + RECT offRect = menuSprites[16]; + float x = labelX + (menuSprites[12].right - menuSprites[12].left) + 10.0f; + DrawMenuSprite(offRect, x * sx, y * sy, (offRect.right - offRect.left) * sx, (offRect.bottom - offRect.top) * sy); + } + else + { + RECT onRect = menuSprites[15]; + float x = labelX + (menuSprites[12].right - menuSprites[12].left) + 10.0f + 14.0f; + DrawMenuSprite(onRect, x * sx, y * sy, (onRect.right - onRect.left) * sx, (onRect.bottom - onRect.top) * sy); + } + } + + { + RECT label = menuSprites[13]; + float labelX = (640.0f - ((float)(menuSprites[13].right - menuSprites[13].left) + (float)(menuSprites[16].right - menuSprites[16].left) + 10.0f)) / 2.0f; + float y = (float)menuLocations[3]; + + if (curMenu == 2) + { + selectionLeft = (int)labelX - 52; + selectionRight = (int)labelX + (menuSprites[13].right - menuSprites[13].left) + (menuSprites[16].right - menuSprites[16].left) + 20; + } + + DrawMenuSprite(label, labelX * sx, y * sy, (label.right - label.left) * sx, (label.bottom - label.top) * sy); + + if (!menuvSync) + { + RECT offRect = menuSprites[16]; + float x = labelX + (menuSprites[13].right - menuSprites[13].left) + 10.0f; + DrawMenuSprite(offRect, x * sx, y * sy, (offRect.right - offRect.left) * sx, (offRect.bottom - offRect.top) * sy); + } + else + { + RECT onRect = menuSprites[15]; + float x = labelX + (menuSprites[13].right - menuSprites[13].left) + 10.0f + 14.0f; + DrawMenuSprite(onRect, x * sx, y * sy, (onRect.right - onRect.left) * sx, (onRect.bottom - onRect.top) * sy); + } + } + + { + RECT r = menuSprites[14]; + float x = (640.0f - (float)(r.right - r.left)) / 2.0f; + float y = (float)menuLocations[4]; + + if (curMenu == 3) + { + selectionLeft = (int)x - 52; + selectionRight = (int)x + (r.right - r.left) + 10; + } + + DrawMenuSprite(r, x * sx, y * sy, (r.right - r.left) * sx, (r.bottom - r.top) * sy); + } + + { + RECT sLoc; + sLoc.left = 42 * (curMenuFrame % 4); + sLoc.top = 160 + (42 * (int)(curMenuFrame / 4)); + sLoc.right = sLoc.left + 42; + sLoc.bottom = sLoc.top + 42; + + curMenuFrame++; + if (curMenuFrame > 7) + curMenuFrame = 0; + + float x = (float)selectionLeft; + float y = (float)menuLocations[curMenu + 1] - 5.0f; + DrawMenuSprite(sLoc, x * sx, y * sy, 42.0f * sx, 42.0f * sy); + + x = (float)selectionRight; + DrawMenuSprite(sLoc, x * sx, y * sy, 42.0f * sx, 42.0f * sy); + } +} + +bool IDirectDrawWrapper::ReinitDevice() +{ + if (!swapChain || !d3d11Context) + return CreateD3DDevice(); + + d3d11Context->ClearState(); + d3d11Context->Flush(); + + renderTargetView.Reset(); + + HRESULT hr = swapChain->ResizeBuffers( + 1, + isWindowed ? 0 : displayWidth, + isWindowed ? 0 : displayHeight, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH); + + if (FAILED(hr)) + { + debugMessage(0, "IDirectDrawWrapper::ReinitDevice", "ResizeBuffers failed"); + return false; + } + + if (!CreateRenderTarget()) + return false; + + D3D11_VIEWPORT vp = {}; + vp.TopLeftX = 0.0f; + vp.TopLeftY = 0.0f; + vp.Width = (FLOAT)displayWidth; + vp.Height = (FLOAT)displayHeight; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + d3d11Context->RSSetViewports(1, &vp); + + debugMessage(2, "IDirectDrawWrapper::ReinitDevice", "Reset device, now create texture"); + + return CreateSurfaceTexture(); +} \ No newline at end of file diff --git a/Storm/SOURCE/ddraw/DirectDrawWrapper.h b/Storm/SOURCE/ddraw/DirectDrawWrapper.h new file mode 100644 index 0000000..5012cf0 --- /dev/null +++ b/Storm/SOURCE/ddraw/DirectDrawWrapper.h @@ -0,0 +1,442 @@ +#define VC_EXTRALEAN +#define UNICODE +#define _UNICODE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef H_DDW +#define H_DDW + +// Global function def +void debugMessage(int, char*, char*); + +// Forward class declarations +class FAR IDirectDrawWrapper; +class FAR IDirectDrawPaletteWrapper; +class FAR IDirectDrawClipperWrapper; +class FAR IDirectDrawSurfaceWrapper; +class FAR IDirectDrawColorControlWrapper; +class FAR IDirectDrawGammaControlWrapper; + +using Microsoft::WRL::ComPtr; + +// D3D11 fullscreen blit vertex +struct TLVERTEX11 +{ + float x; + float y; + float z; + float u; + float v; +}; + +// D3D11 menu sprite vertex +struct SpriteVertex11 +{ + float x; + float y; + float z; + float u; + float v; +}; + +/* + * IDirectDrawWrapper Class + */ +class FAR IDirectDrawWrapper : public IDirectDraw +{ + // Implemented interfaces +public: + /*** IUnknown methods ***/ + HRESULT __stdcall QueryInterface(REFIID riid, LPVOID FAR* ppvObj); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + + /*** IDirectDraw methods ***/ + HRESULT __stdcall Compact(); + HRESULT __stdcall CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter); + HRESULT __stdcall CreatePalette(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR* lplpDDPalette, IUnknown FAR* pUnkOuter); + HRESULT __stdcall CreateSurface(LPDDSURFACEDESC lpDDSurfaceDes, LPDIRECTDRAWSURFACE FAR* lplpDDSurface, IUnknown FAR* pUnkOuter); + HRESULT __stdcall DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE FAR* lplpDupDDSurface); + HRESULT __stdcall EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback); + HRESULT __stdcall EnumSurfaces(DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback); + HRESULT __stdcall FlipToGDISurface(); + HRESULT __stdcall GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps); + HRESULT __stdcall GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc); + HRESULT __stdcall GetFourCCCodes(LPDWORD lpNumCodes, LPDWORD lpCodes); + HRESULT __stdcall GetGDISurface(LPDIRECTDRAWSURFACE FAR* lplpGDIDDSSurface); + HRESULT __stdcall GetMonitorFrequency(LPDWORD lpdwFrequency); + HRESULT __stdcall GetScanLine(LPDWORD lpdwScanLine); + HRESULT __stdcall GetVerticalBlankStatus(LPBOOL lpbIsInVB); + HRESULT __stdcall Initialize(GUID FAR* lpGUID); + HRESULT __stdcall RestoreDisplayMode(); + HRESULT __stdcall SetCooperativeLevel(HWND hWnd, DWORD dwFlags); + HRESULT __stdcall SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP); + HRESULT __stdcall WaitForVerticalBlank(DWORD dwFlags, HANDLE hEvent); + + /*** Added in the v2 interface ***/ + HRESULT __stdcall GetAvailableVideoMem(LPDDSCAPS2 lpDDSCaps2, LPDWORD lpdwTotal, LPDWORD lpdwFree); + + /*** Added in the V4 Interface ***/ + HRESULT __stdcall EvaluateMode(DWORD dwFlags, DWORD* pSecondsUntilTimeout); + HRESULT __stdcall GetDeviceIdentifier(LPDDDEVICEIDENTIFIER2 lpdddi, DWORD dwFlags); + HRESULT __stdcall GetSurfaceFromDC(HDC hdc, LPDIRECTDRAWSURFACE7* lpDDS); + HRESULT __stdcall RestoreAllSurfaces(); + HRESULT __stdcall StartModeTest(LPSIZE lpModesToTest, DWORD dwNumEntries, DWORD dwFlags); + HRESULT __stdcall TestCooperativeLevel(); + + // Constructor/destructor + IDirectDrawWrapper(); + ~IDirectDrawWrapper(); + + // Helper functions + HRESULT WrapperInitialize(WNDPROC wp, HMODULE hMod); + HRESULT Present(); + BOOL MenuKey(WPARAM vKey); + void DoSnapshot(); + void ToggleFullscreen(); + + // Display window handle + HWND hWnd; + WNDPROC lpPrevWndFunc; + WNDPROC WndProc; + HMODULE hModule; + + // Current display mode + bool isWindowed; + + // Application display mode + DWORD displayModeWidth; + DWORD displayModeHeight; + + // Display resolution + UINT displayWidth; + UINT displayHeight; + + // Saved display resolutions for fullscreen and windowed + UINT displayWidthWindowed; + UINT displayHeightWindowed; + UINT displayWidthFullscreen; + UINT displayHeightFullscreen; + + // Menu settings + bool menuWindowed; + bool menuvSync; + + // Custom functions and variables +private: + // Helper functions + void AdjustWindow(); + bool CreateD3DDevice(); + bool CreateSurfaceTexture(); + bool ReinitDevice(); + bool CreateRenderTarget(); + bool CreateShaders(); + bool CreateMenuVertexBuffer(); + bool DrawMenuSprite(const RECT& srcRect, float dstX, float dstY, float dstW, float dstH); + void RenderMenuD3D11(); + + IDirectDrawSurfaceWrapper* lpAttachedSurface; + + // Reference count + ULONG ReferenceCount; + + // Cooperative level flags + DWORD cooperativeFlags; + + // D3D11 / DXGI objects + ComPtr d3d11Device; + ComPtr d3d11Context; + ComPtr swapChain; + ComPtr renderTargetView; + + ComPtr surfaceTexture; + ComPtr surfaceSRV; + ComPtr vertexBuffer; + + ComPtr blitVS; + ComPtr blitPS; + ComPtr inputLayout; + ComPtr samplerLinear; + ComPtr alphaBlendState; + ComPtr rasterState; + + ComPtr menuTexture; + ComPtr menuSRV; + ComPtr menuVertexBuffer; + + DXGI_SWAP_CHAIN_DESC swapDesc; + + // Menu sprite info + int curMenuFrame; + int menuLocations[5]; + RECT menuSprites[18]; + int menuTextureWidth; + int menuTextureHeight; + + // Flags and settings + BOOL inMenu; + int curMenu; + int menuWindowedResolution; + int windowedResolutionCount; + POINT* windowedResolutions; + int menuFullscreenResolution; + int fullscreenResolutionCount; + POINT* fullscreenResolutions; + UINT* fullscreenRefreshes; + + // Last window position + POINT lastPosition; + + // Vsync enabled + bool vSync; + + // Refresh rate for fullscreen + UINT refreshRate; +}; + +/* + * IDirectDrawPalette Wrapper + */ +class FAR IDirectDrawPaletteWrapper : public IDirectDrawPalette +{ + // Implemented interfaces +public: + /*** IUnknown methods ***/ + HRESULT __stdcall QueryInterface(REFIID riid, LPVOID FAR* ppvObj); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + + /*** IDirectDrawPalette methods ***/ + HRESULT __stdcall GetCaps(LPDWORD lpdwCaps); + HRESULT __stdcall GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries); + HRESULT __stdcall Initialize(LPDIRECTDRAW lpDDW, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable); + HRESULT __stdcall SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries); + + // Constructor/destructor + IDirectDrawPaletteWrapper(); + ~IDirectDrawPaletteWrapper(); + + // Helper functions + HRESULT WrapperInitialize(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR* lplpDDPalette); + + // Rgb translated palette + uint32_t* rgbPalette; + + // Raw palette data + LPPALETTEENTRY rawPalette; + + // Custom functions and variables +private: + // Reference count + ULONG ReferenceCount; + + // Palette flags + DWORD paletteCaps; + + // Number of palette entries + int entryCount; + + // Raw palette has alpha data + bool hasAlpha; +}; + +/* + * IDirectDrawClipper Wrapper + */ +class FAR IDirectDrawClipperWrapper : public IDirectDrawClipper +{ + // Implemented interfaces +public: + /*** IUnknown methods ***/ + HRESULT __stdcall QueryInterface(REFIID riid, LPVOID FAR* ppvObj); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + + /*** IDirectDrawClipper methods ***/ + HRESULT __stdcall GetClipList(LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize); + HRESULT __stdcall GetHWnd(HWND FAR* lphWnd); + HRESULT __stdcall Initialize(LPDIRECTDRAW lpDD, DWORD dwFlags); + HRESULT __stdcall IsClipListChanged(BOOL FAR* lpbChanged); + HRESULT __stdcall SetClipList(LPRGNDATA lpClipList, DWORD dwFlags); + HRESULT __stdcall SetHWnd(DWORD dwFlags, HWND hWnd); + + // Constructor/destructor + IDirectDrawClipperWrapper(); + ~IDirectDrawClipperWrapper(); + + // Helper functions + HRESULT WrapperInitialize(DWORD dwFlags); + + // Custom functions and variables +private: + // Reference count + ULONG ReferenceCount; + + // Associated hwnd + bool hasHwnd; + HWND hWnd; +}; + +/* + * IDirectDrawSurface Wrapper + */ +class FAR IDirectDrawSurfaceWrapper : public IDirectDrawSurface +{ + // Implemented interfaces +public: + /*** IUnknown methods ***/ + HRESULT __stdcall QueryInterface(REFIID riid, LPVOID FAR* ppvObj); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + + /*** IDirectDrawSurface methods ***/ + HRESULT __stdcall AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSurface); + HRESULT __stdcall AddOverlayDirtyRect(LPRECT lpRect); + HRESULT __stdcall Blt(LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx); + HRESULT __stdcall BltBatch(LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags); + HRESULT __stdcall BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags); + HRESULT __stdcall DeleteAttachedSurface(DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface); + HRESULT __stdcall EnumAttachedSurfaces(LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback); + HRESULT __stdcall EnumOverlayZOrders(DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback); + HRESULT __stdcall Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DWORD dwFlags); + HRESULT __stdcall GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE FAR* lplpDDAttachedSurface); + HRESULT __stdcall GetBltStatus(DWORD dwFlags); + HRESULT __stdcall GetCaps(LPDDSCAPS lpDDSCaps); + HRESULT __stdcall GetClipper(LPDIRECTDRAWCLIPPER FAR* lplpDDClipper); + HRESULT __stdcall GetColorKey(DWORD dwFlags, LPDDCOLORKEY lpDDColorKey); + HRESULT __stdcall GetDC(HDC FAR* lphDC); + HRESULT __stdcall GetFlipStatus(DWORD dwFlags); + HRESULT __stdcall GetOverlayPosition(LPLONG lplX, LPLONG lplY); + HRESULT __stdcall GetPalette(LPDIRECTDRAWPALETTE FAR* lplpDDPalette); + HRESULT __stdcall GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat); + HRESULT __stdcall GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc); + HRESULT __stdcall Initialize(LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc); + HRESULT __stdcall IsLost(); + HRESULT __stdcall Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent); + HRESULT __stdcall ReleaseDC(HDC hDC); + HRESULT __stdcall Restore(); + HRESULT __stdcall SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper); + HRESULT __stdcall SetColorKey(DWORD dwFlags, LPDDCOLORKEY lpDDColorKey); + HRESULT __stdcall SetOverlayPosition(LONG lX, LONG lY); + HRESULT __stdcall SetPalette(LPDIRECTDRAWPALETTE lpDDPalette); + HRESULT __stdcall Unlock(LPVOID lpRect); + HRESULT __stdcall Unlock(LPRECT lpRect); + HRESULT __stdcall UpdateOverlay(LPRECT lpSrcRect, LPDIRECTDRAWSURFACE lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx); + HRESULT __stdcall UpdateOverlayDisplay(DWORD dwFlags); + HRESULT __stdcall UpdateOverlayZOrder(DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSReference); + + /*** Added in the v2 interface ***/ + HRESULT __stdcall GetDDInterface(LPVOID FAR* lplpDD); + HRESULT __stdcall PageLock(DWORD dwFlags); + HRESULT __stdcall PageUnlock(DWORD dwFlags); + + /*** Added in the v3 interface ***/ + HRESULT __stdcall SetSurfaceDesc(LPDDSURFACEDESC2 lpDDsd2, DWORD dwFlags); + + /*** Added in the v4 interface ***/ + HRESULT __stdcall ChangeUniquenessValue(); + HRESULT __stdcall FreePrivateData(REFGUID guidTag); + HRESULT __stdcall GetPrivateData(REFGUID guidTag, LPVOID lpBuffer, LPDWORD lpcbBufferSize); + HRESULT __stdcall GetUniquenessValue(LPDWORD lpValue); + HRESULT __stdcall SetPrivateData(REFGUID guidTag, LPVOID lpData, DWORD cbSize, DWORD dwFlags); + + /*** Texture7 methods ***/ + HRESULT __stdcall SetPriority(DWORD dwPriority); + HRESULT __stdcall GetPriority(LPDWORD lpdwPriority); + HRESULT __stdcall SetLOD(LPDWORD lpdwMaxLOD); + HRESULT __stdcall GetLOD(DWORD dwMaxLOD); + + // Constructor/destructor + IDirectDrawSurfaceWrapper(IDirectDrawWrapper* parent); + ~IDirectDrawSurfaceWrapper(); + + // Helper functions + HRESULT WrapperInitialize(LPDDSURFACEDESC lpDDSurfaceDesc, DWORD displayModeWidth, DWORD displayModeHeight, DWORD displayWidth, DWORD displayHeight); + BOOL ReInitialize(DWORD displayWidth, DWORD displayHeight); + + // RGB video memory + uint32_t* rgbVideoMem; + + //Custom functions and variables +private: + // Reference count + ULONG ReferenceCount; + + // Directdraw object that created this surface + IDirectDrawWrapper* ddrawParent; + + // Associated palette + IDirectDrawPaletteWrapper* attachedPalette; + + // Surface description + DDSURFACEDESC surfaceDesc; + LONG surfaceWidth; + LONG surfaceHeight; + + // Color keys(DDCKEY_DESTBLT, DDCKEY_DESTOVERLAY, DDCKEY_SRCBLT, DDCKEY_SRCOVERLAY) + DDCOLORKEY colorKeys[4]; + LONG overlayX, overlayY; + + // Virtual video memory + BYTE* rawVideoMem; +}; + +/* + * IDirectDrawColorControl + */ +class FAR IDirectDrawColorControlWrapper : public IDirectDrawColorControl +{ + //implemented interfaces +public: + /*** IUnknown methods ***/ + HRESULT __stdcall QueryInterface(REFIID riid, LPVOID FAR* ppvObj); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + + /*** IDirectDrawColorControl methods ***/ + HRESULT __stdcall GetColorControls(LPDDCOLORCONTROL lpColorControl); + HRESULT __stdcall SetColorControls(LPDDCOLORCONTROL lpColorControl); + + // Constructor/destructor + IDirectDrawColorControlWrapper(); + ~IDirectDrawColorControlWrapper(); + + // Custom functions and variables +private: +}; + +/* + * IDirectDrawGammaControl + */ +class FAR IDirectDrawGammaControlWrapper : public IDirectDrawGammaControl +{ + // Implemented interfaces +public: + /*** IUnknown methods ***/ + HRESULT __stdcall QueryInterface(REFIID riid, LPVOID FAR* ppvObj); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + + /*** IDirectDrawGammaControl methods ***/ + HRESULT __stdcall GetGammaRamp(DWORD dwFlags, LPDDGAMMARAMP lpRampData); + HRESULT __stdcall SetGammaRamp(DWORD dwFlags, LPDDGAMMARAMP lpRampData); + + // Constructor/destructor + IDirectDrawGammaControlWrapper(); + ~IDirectDrawGammaControlWrapper(); + + // Custom functions and variables +private: +}; + +#endif \ No newline at end of file diff --git a/Storm/SOURCE/ddraw/ddraw.cpp b/Storm/SOURCE/ddraw/ddraw.cpp new file mode 100644 index 0000000..17dc688 --- /dev/null +++ b/Storm/SOURCE/ddraw/ddraw.cpp @@ -0,0 +1,109 @@ +#include "DirectDrawWrapper.h" +#include "resource.h" + +#include +#include + +// Main thread ddrawwrapper object +IDirectDrawWrapper *lpDD = NULL; +// Original setcursorpos function pointer +static BOOL (WINAPI *TrueSetCursorPos)(int,int) = SetCursorPos; +static HMODULE (WINAPI *TrueLoadLibraryA)(LPCSTR) = GetModuleHandleA; + +// Are we in the settings menu +BOOL inMenu; +// Dll start time +DWORD start_time; +// The level of debug to display +int debugLevel; +//debug display mode (-1 = none, 0 = console, 1 = file) +int debugDisplay; +//the debug file handle +FILE *debugFile; + +// Dll hmodule +HMODULE hMod; + +/* Helper function for throwing debug/error messages + * + * int level - Debug level + * char *location - Message location + * char *message - Message + */ +void debugMessage(int level, char *location, char *message) +{ + // If above the current level then skip totally + if(level > debugLevel) return; + + // Calculate HMS + DWORD cur_time = GetTickCount() - start_time; + long hours = (long)floor((double)cur_time / (double)3600000.0); + cur_time -= (hours * 3600000); + int minutes = (int)floor((double)cur_time / (double)60000.0); + cur_time -= (minutes * 60000); + double seconds = (double)cur_time / (double)1000.0; + + // Build error message + char text[4096] = "\0"; + if(level == 0) + { + sprintf_s(text, 4096, "%d:%d:%#.1f ERR %s %s\n", hours, minutes, seconds, location, message); + } + else if(level == 1) + { + sprintf_s(text, 4096, "%d:%d:%#.1f WRN %s %s\n", hours, minutes, seconds, location, message); + } + else if(level == 2) + { + sprintf_s(text, 4096, "%d:%d:%#.1f INF %s %s\n", hours, minutes, seconds, location, message); + } + // Output and flush + printf_s(text); + fflush(stdout); +} + +// Override function for cursor position +BOOL WINAPI OverrideSetCursorPos(int X, int Y) +{ + // If ddraw object exists and windowed mode + if(lpDD != NULL && lpDD->isWindowed) + { + // X,Y are relative to client area within the code + // Get client area location + POINT cpos; + cpos.x = 0; + cpos.y = 0; + ClientToScreen(lpDD->hWnd, &cpos); + + // Calculate correct cursor offset and move + BOOL res = TrueSetCursorPos(cpos.x + X, cpos.y + Y); + return res; + } + return TrueSetCursorPos(X, Y); +} + +// Override function for load library +/*HMODULE WINAPI OverrideLoadLibraryA(LPCSTR lpModuleName) +{ + printf_s("%s\n", lpModuleName); + return TrueLoadLibraryA(lpModuleName); +}*/ + +// Emulated direct draw create +extern "C" BOOL APIENTRY SDirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter) +{ + // Create directdraw object + lpDD = new IDirectDrawWrapper(); + if(lpDD == NULL) + { + debugMessage(0, "DirectDrawCreate", "Failed to create IDirectDrawWrapper."); + return DDERR_OUTOFMEMORY; // Simulate OOM error + } + + // Set return pointer to the newly created DirectDrawWrapper interface + *lplpDD = (LPDIRECTDRAW)lpDD; + lpDD->WrapperInitialize(NULL, GetModuleHandleA(NULL)); + + // Return success + return DD_OK; +} \ No newline at end of file diff --git a/Storm/SOURCE/ddraw/resource.h b/Storm/SOURCE/ddraw/resource.h new file mode 100644 index 0000000..8cebc81 --- /dev/null +++ b/Storm/SOURCE/ddraw/resource.h @@ -0,0 +1 @@ +#define SPRITEDATA 300 diff --git a/Storm/STORM.DSW b/Storm/STORM.DSW new file mode 100644 index 0000000..785a776 --- /dev/null +++ b/Storm/STORM.DSW @@ -0,0 +1,17 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/Storm/STORM.NCB b/Storm/STORM.NCB new file mode 100644 index 0000000..d948343 Binary files /dev/null and b/Storm/STORM.NCB differ diff --git a/Storm/STORM.OPT b/Storm/STORM.OPT new file mode 100644 index 0000000..7dbba8f Binary files /dev/null and b/Storm/STORM.OPT differ diff --git a/Storm/STORMDLL.DSP b/Storm/STORMDLL.DSP new file mode 100644 index 0000000..27ce4ce --- /dev/null +++ b/Storm/STORMDLL.DSP @@ -0,0 +1,270 @@ +# Microsoft Developer Studio Project File - Name="stormdll" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=stormdll - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "stormdll.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "stormdll.mak" CFG="stormdll - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "stormdll - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "stormdll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "stormdll - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "h" /I "smacker\h" /I "pkware\h" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib comdlg32.lib version.lib implode.lib oldnames.lib msvcrtd.lib /nologo /subsystem:windows /dll /machine:I386 /nodefaultlib:"crtdll.lib" /nodefaultlib /libpath:"source" /libpath:"pkware\lib" + +!ELSEIF "$(CFG)" == "stormdll - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "h" /I "smacker\h" /I "pkware\h" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"./debug/" /Fp"./debug/stormdll.pch" /YX /Fo"./debug/" /Fd"./debug/" /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /fo"../windebug/Storm.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /o"../windebug/stormdll.bsc" +# SUBTRACT BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib comdlg32.lib version.lib implode.lib oldnames.lib msvcrtd.lib /nologo /base:"0x15000000" /subsystem:windows /dll /incremental:no /pdb:"../windebug/storm.pdb" /map:"../windebug/storm.map" /debug /machine:I386 /nodefaultlib:"crtdll.lib" /nodefaultlib /def:".\Source\Exports.def" /out:"../windebug/storm.dll" /implib:"../windebug/storm.lib" /pdbtype:sept /libpath:"source" /libpath:"pkware\lib" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "stormdll - Win32 Release" +# Name "stormdll - Win32 Debug" +# Begin Group "source" + +# PROP Default_Filter ".cpp" +# Begin Source File + +SOURCE=.\Source\Exports.def + +!IF "$(CFG)" == "stormdll - Win32 Release" + +!ELSEIF "$(CFG)" == "stormdll - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Source\Sblt.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sbmp.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Scmd.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Scode.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Scomp.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sdlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sdraw.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Serr.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sevt.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sfile.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sgdi.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Slog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Smem.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\SMsg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Snet.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sreg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Srgn.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Srtl.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Sstr.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Storm.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Storm.rc +# End Source File +# Begin Source File + +SOURCE=.\Source\STrans.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Svid.cpp +# End Source File +# End Group +# Begin Group "include" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=.\Source\Pch.h +# End Source File +# Begin Source File + +SOURCE=.\Source\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\Source\SIntern.h +# End Source File +# End Group +# Begin Group "h" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=.\H\Bnetart.h +# End Source File +# Begin Source File + +SOURCE=.\H\Storm.h +# End Source File +# End Group +# Begin Group "pkware" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\pkware\Obj\Crc32.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Crcfast.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Crcstd.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Expfast.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Explode.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Expstd.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Impfast.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Implode.obj +# End Source File +# Begin Source File + +SOURCE=.\pkware\Obj\Impstd.obj +# End Source File +# End Group +# End Target +# End Project diff --git a/Storm/STORMDLL.DSW b/Storm/STORMDLL.DSW new file mode 100644 index 0000000..a1f89cf --- /dev/null +++ b/Storm/STORMDLL.DSW @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "stormdll"=.\stormdll.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/Storm/STORMDLL.OPT b/Storm/STORMDLL.OPT new file mode 100644 index 0000000..c1ca1e7 Binary files /dev/null and b/Storm/STORMDLL.OPT differ diff --git a/Storm/STORMDLL.ncb b/Storm/STORMDLL.ncb new file mode 100644 index 0000000..4df7c2d Binary files /dev/null and b/Storm/STORMDLL.ncb differ diff --git a/Storm/STORMDLL.sln b/Storm/STORMDLL.sln new file mode 100644 index 0000000..0eb3ee5 --- /dev/null +++ b/Storm/STORMDLL.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stormdll", "stormdll.vcproj", "{43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Debug|Win32.ActiveCfg = Debug|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Debug|Win32.Build.0 = Debug|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Release|Win32.ActiveCfg = Release|Win32 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Storm/STORMDLL.suo b/Storm/STORMDLL.suo new file mode 100644 index 0000000..1a5f4bf Binary files /dev/null and b/Storm/STORMDLL.suo differ diff --git a/Storm/TESTAPP.DSP b/Storm/TESTAPP.DSP new file mode 100644 index 0000000..0d0e475 --- /dev/null +++ b/Storm/TESTAPP.DSP @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="testapp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=testapp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "testapp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testapp.mak" CFG="testapp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testapp - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "testapp - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "testapp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "testapp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "testapp_" +# PROP BASE Intermediate_Dir "testapp_" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "testapp_" +# PROP Intermediate_Dir "testapp_" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "testapp - Win32 Release" +# Name "testapp - Win32 Debug" +# End Target +# End Project diff --git a/Storm/TESTAPP_/TESTAPP.PCH b/Storm/TESTAPP_/TESTAPP.PCH new file mode 100644 index 0000000..8047c7d Binary files /dev/null and b/Storm/TESTAPP_/TESTAPP.PCH differ diff --git a/Storm/TESTAPP_/VC50.IDB b/Storm/TESTAPP_/VC50.IDB new file mode 100644 index 0000000..1647f6c Binary files /dev/null and b/Storm/TESTAPP_/VC50.IDB differ diff --git a/Storm/TESTAPP_/VC50.PDB b/Storm/TESTAPP_/VC50.PDB new file mode 100644 index 0000000..1cbc896 Binary files /dev/null and b/Storm/TESTAPP_/VC50.PDB differ diff --git a/Storm/UPDATE.BAT b/Storm/UPDATE.BAT new file mode 100644 index 0000000..6e7d727 --- /dev/null +++ b/Storm/UPDATE.BAT @@ -0,0 +1,13 @@ +@echo off +copy o:\h\*.h p:\dev\h\ /v +del o:\source\*.exp +c /ads o:\source\battle\battle.cs +c /aos o:\source\battle\battle.cs +c /ads o:\source\standard\standard.cs +c /aos o:\source\standard\standard.cs +c /aos o:\source\stormst.cs +c /ads o:\source\storm.cs +c /aos o:\source\storm.cs +ss checkin -i- -k -r $/Storm +copy o:\lib\*.lib p:\dev\lib\ /v +copy o:\lib\*.res p:\dev\lib\ /v diff --git a/Storm/VC50.PCH b/Storm/VC50.PCH new file mode 100644 index 0000000..ba1a064 Binary files /dev/null and b/Storm/VC50.PCH differ diff --git a/Storm/stormdll.vcproj b/Storm/stormdll.vcproj new file mode 100644 index 0000000..0c6f043 --- /dev/null +++ b/Storm/stormdll.vcproj @@ -0,0 +1,819 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Storm/stormdll.vcproj.DESKTOP-B2JDPBG.Justin.user b/Storm/stormdll.vcproj.DESKTOP-B2JDPBG.Justin.user new file mode 100644 index 0000000..a1438bc --- /dev/null +++ b/Storm/stormdll.vcproj.DESKTOP-B2JDPBG.Justin.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/Storm/stormdll.vcxproj b/Storm/stormdll.vcxproj new file mode 100644 index 0000000..9712d14 --- /dev/null +++ b/Storm/stormdll.vcxproj @@ -0,0 +1,210 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + 18.0 + {43DD7E96-BF0F-4E3B-85F4-1EEAFA46583A} + + + + DynamicLibrary + v145 + false + + + DynamicLibrary + v145 + false + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>18.0.11512.103 + + + .\Debug\ + .\Debug\ + false + + + .\Release\ + .\Release\ + false + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/stormdll.tlb + + + + Disabled + h;smacker\h;pkware\h;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDebugDLL + true + .\Debug/stormdll.pch + .\Debug/ + .\Debug/ + .\Debug/ + true + Level3 + true + EditAndContinue + false + stdcpp14 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ../windebug/Storm.res + + + ucrtd.lib;vcruntime.lib;legacy_stdio_definitions.lib;version.lib;implode.lib;oldnames.lib;%(AdditionalDependencies) + ../bin/storm.dll + true + source;pkware\lib;%(AdditionalLibraryDirectories) + false + libc.lib + .\Source\Exports.def + true + ../windebug/storm.pdb + true + ../windebug/storm.map + Windows + 0x15000000 + ../windebug/storm.lib + MachineX86 + false + + + ../windebug/stormdll.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/stormdll.tlb + + + + MaxSpeed + OnlyExplicitInline + h;smacker\h;pkware\h;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/stormdll.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + libcmt.lib;version.lib;implode.lib;oldnames.lib;msvcrtd.lib;%(AdditionalDependencies) + ../bin/storm.dll + true + source;pkware\lib;%(AdditionalLibraryDirectories) + false + libc.lib;%(IgnoreSpecificDefaultLibraries) + .\Source\Exports.def + .\Release/stormdll.pdb + Windows + .\Release/stormdll.lib + MachineX86 + false + + + true + .\Release/stormdll.bsc + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Source;%(AdditionalIncludeDirectories) + Source;%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Storm/stormdll.vcxproj.filters b/Storm/stormdll.vcxproj.filters new file mode 100644 index 0000000..248a90e --- /dev/null +++ b/Storm/stormdll.vcxproj.filters @@ -0,0 +1,112 @@ + + + + + {f916e068-d065-4d1c-ac83-07ac036e87d1} + .cpp + + + {cccabf07-098a-48f9-927b-2b15020af66c} + *.h + + + {5d611d0f-929d-421f-8199-f84167f5481e} + *.h + + + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + + + source + + + + + include + + + include + + + include + + + h + + + h + + + + + source + + + \ No newline at end of file diff --git a/Storm/stormdll.vcxproj.user b/Storm/stormdll.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Storm/stormdll.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TEXTDAT.CPP b/TEXTDAT.CPP new file mode 100644 index 0000000..eb27594 --- /dev/null +++ b/TEXTDAT.CPP @@ -0,0 +1,2243 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Miniquest Text file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "minitext.h" +#include "textdat.h" +#include "effects.h" + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Skeleton King Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char King1[] = " Ahh, the story of our King, is it? The tragic fall of " +"Leoric was a harsh blow to this land. The people always loved the King, " +"and now they live in mortal fear of him. The question that I keep asking " +"myself is how he could have fallen so far from the Light, as Leoric had " +"always been the holiest of men. Only the vilest powers of Hell could so " +"utterly destroy a man from within... |"; + +//quest init +static char King2[] = "The village needs your help, good master! Some months " +"ago King Leoric's son, Prince Albrecht, was kidnapped. The King went into " +"a rage and scoured the village for his missing child. With each passing " +"day, Leoric seemed to slip deeper into madness. He sought to blame " +"innocent townsfolk for the boy's disappearance and had them brutally " +"executed. Less than half of us survived his insanity...\n \n" +"The King's Knights and Priests tried to placate him, but he turned " +"against them and sadly, they were forced to kill him. With his dying " +"breath the King called down a terrible curse upon his former followers. " +"He vowed that they would serve him in darkness forever...\n \n" +"This is where things take an even darker twist than I thought possible! " +"Our former King has risen from his eternal sleep and now commands a legion " +"of undead minions within the Labyrinth. His body was buried in a tomb " +"three levels beneath the Cathedral. Please, good master, put his soul " +"at ease by destroying his now cursed form... |"; + +//If the hero returns before completing the quest +static char King3[] = "As I told you, good master, the King was entombed " +"three levels below. He's down there, waiting in the putrid darkness " +"for his chance to destroy this land... |"; + +//If the hero returns after completing the quest +static char King4[] = "The curse of our King has passed, but I fear that it " +"was only part of a greater evil at work. However, we may yet be saved " +"from the darkness that consumes our land, for your victory is a good " +"omen. May Light guide you on your way, good master. |"; + +static char King5[] = "The loss of his son was too much for King Leoric. I " +"did what I could to ease his madness, but in the end it overcame him. " +"A black curse has hung over this kingdom from that day forward, but " +"perhaps if you were to free his spirit from his earthly prison, the " +"curse would be lifted... |"; + +static char King6[] = "I don't like to think about how the King died. I " +"like to remember him for the kind and just ruler that he was. His death " +"was so sad and seemed very wrong, somehow. |"; + +static char King7[] = "I made many of the weapons and most of the armor " +"that King Leoric used to outfit his knights. I even crafted a huge " +"two-handed sword of the finest mithril for him, as well as a field " +"crown to match. I still cannot believe how he died, but it must have " +"been some sinister force that drove him insane! |"; + +static char King8[] = "I don't care about that. Listen, no skeleton is gonna " +"be MY king. Leoric is King. King, so you hear me? HAIL TO THE KING! |"; + +static char King9[] = "The dead who walk among the living follow the cursed " +"King. He holds the power to raise yet more warriors for an ever growing " +"army of the undead. If you do not stop his reign, he will surely march " +"across this land and slay all who still live here. |"; + +static char King10[] = "Look, I'm running a business here. I don't sell " +"information, and I don't care about some King that's been dead longer " +"than I've been alive. If you need something to use against this King " +"of the undead, then I can help you out... |"; + +//When the hero enters the Skeleton King Chamber +static char King11[] = "The warmth of life has entered my tomb. Prepare " +"yourself, mortal, to serve my Master for eternity! |"; +#endif + +/*-----------------------------------------------------------------------** +** Banner of Light Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Banner1[] = "I see that this strange behavior puzzles you as " +"well. I would surmise that since many demons fear the light of the sun " +"and believe that it holds great power, it may be that the rising sun " +"depicted on the sign you speak of has led them to believe that it too holds " +"some arcane powers. Hmm, perhaps they are not all as smart as we had " +"feared... |"; + +//quest init +static char Banner2[] = "Master, I have a strange experience to relate. " +"I know that you have a great knowledge of those monstrosities that " +"inhabit the labyrinth, and this is something that I cannot understand " +"for the very life of me... " +"I was awakened during the night by a scraping sound just outside of " +"my tavern. When I looked out from my bedroom, I saw the shapes of " +"small demon-like creatures in the inn yard. After a short time, " +"they ran off, but not before stealing the sign to my inn. I don't " +"know why the demons would steal my sign but leave my family " +"in peace... 'tis strange, no? |"; + +//If hero returns the sign to the tavern +static char Banner3[] = "Oh, you didn't have to bring back my sign, but I " +"suppose that it does save me the expense of having another one made. Well, let me see, " +"what could I give you as a fee for finding it? Hmmm, what have we " +"here... ah, yes! This cap was left in one of the rooms by a magician " +"who stayed here some time ago. Perhaps it may be of some value to you. |"; + +static char Banner4[] = "My goodness, demons running about the village at " +"night, pillaging our homes - is nothing sacred? I hope that Ogden and " +"Garda are all right. I suppose that they would come to see me if they " +"were hurt... |"; + +static char Banner5[] = "Oh my! Is that where the sign went? My " +"Grandmother and I must have slept right through the whole thing. Thank " +"the Light that those monsters didn't attack the inn. |"; + +static char Banner6[] = "Demons stole Ogden's sign, you say? That doesn't " +"sound much like the atrocities I've heard of - or seen. \n \n" +"Demons are " +"concerned with ripping out your heart, not your signpost. |"; + +static char Banner7[] = "You know what I think? Somebody took that sign, " +"and they gonna want lots of money for it. If I was Ogden... and I'm not, " +"but if I was... I'd just buy a new sign with some pretty drawing on it. " +"Maybe a nice mug of ale or a piece of cheese... |"; + +static char Banner8[] = "No mortal can truly understand the mind of the demon. \n \n" +"Never let their erratic actions confuse you, as that too may be their " +"plan. |"; + +static char Banner9[] = "What - is he saying I took that? I suppose that " +"Griswold is on his side, too. \n \n" +"Look, I got over simple sign stealing " +"months ago. You can't turn a profit on a piece of wood. |"; + +//Within the labyrinth +static char Banner10[] = "Hey - You that one that kill all! You get me " +"Magic Banner or we attack! You no leave with life! You kill big uglies " +"and give back Magic. Go past corner and door, find uglies. You give, " +"you go! |"; + +//If hero returns empty-handed +static char Banner11[] = "You kill uglies, get banner. You bring to me, " +"or else... |"; + +//If hero returns with sign +static char Banner12[] = "You give! Yes, good! Go now, we strong. We kill " +"all with big Magic! |"; +#endif + +/*-----------------------------------------------------------------------** +** Vile Betrayer Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +// quest init +static char Vile1[] = "This does not bode well, for it confirms my " +"darkest fears. While I did not allow myself to believe the ancient " +"legends, I cannot deny them now. Perhaps the time has come to reveal " +"who I am.\n \n" +"My true name is Deckard Cain the Elder, and I am the last descendant " +"of an ancient Brotherhood that was dedicated to safeguarding the secrets " +"of a timeless evil. An evil that quite obviously has now been released.\n \n" +"The Archbishop Lazarus, once King Leoric's most trusted advisor, led a " +"party of simple townsfolk into the Labyrinth to find the King's missing " +"son, Albrecht. Quite some time passed before they returned, and only a " +"few of them escaped with their lives.\n \n" +"Curse me for a fool! I should have suspected his veiled treachery then. " +"It must have been Lazarus himself who kidnapped Albrecht and has since " +"hidden him within the Labyrinth. I do not understand why the Archbishop " +"turned to the darkness, or what his interest is in the child, unless he " +"means to sacrifice him to his dark masters!\n \n" +"That must be what he has planned! The survivors of his 'rescue party' " +"say that Lazarus was last seen running into the deepest bowels of the " +"labyrinth. You must hurry and save the prince from the sacrificial blade " +"of this demented fiend! |"; + +// quest not done +static char Vile2[] = "You must hurry and rescue Albrecht from the hands " +"of Lazarus. The prince and the people of this kingdom are counting on you! |"; + +// quest done +static char Vile3[] = "Your story is quite grim, my friend. Lazarus will " +"surely burn in Hell for his horrific deed. The boy that you describe is " +"not our prince, but I believe that Albrecht may yet be in danger. The " +"symbol of power that you speak of must be a portal in the very heart of " +"the labyrinth.\n \n" +"Know this, my friend - The evil that you move against is the dark Lord " +"of Terror. He is known to mortal men as Diablo. It was he who was " +"imprisoned within the Labyrinth many centuries ago and I fear that he " +"seeks to once again sow chaos in the realm of mankind. You must venture " +"through the portal and destroy Diablo before it is too late! |"; + +static char Vile4[] = "Lazarus was the Archbishop who led many of the " +"townspeople into the labyrinth. I lost many good friends that day, " +"and Lazarus never returned. I suppose he was killed along with most " +"of the others. If you would do me a favor, good master - please do " +"not talk to Farnham about that day. |"; + +static char Vile5[] = "|"; + +static char Vile6[] = "|"; + +static char Vile7[] = "I was shocked when I heard of what the townspeople " +"were planning to do that night. I thought that of all people, Lazarus " +"would have had more sense than that. He was an Archbishop, and always " +"seemed to care so much for the townsfolk of Tristram. So many were " +"injured, I could not save them all... |"; + +static char Vile8[] = "I remember Lazarus as being a very kind and giving " +"man. He spoke at my mother's funeral, and was supportive of my " +"grandmother and myself in a very troubled time. I pray every night " +"that somehow, he is still alive and safe. |"; + +static char Vile9[] = "I was there when Lazarus led us into the labyrinth. " +"He spoke of holy retribution, but when we started fighting those " +"hellspawn, he did not so much as lift his mace against them. He just " +"ran deeper into the dim, endless chambers that were filled with the " +"servants of darkness! |"; + +static char Vile10[] = "They stab, then bite, then they're all around you. " +"Liar! LIAR! They're all dead! Dead! Do you hear me? They just keep " +"falling and falling... their blood spilling out all over the floor... " +"all his fault... |"; + +static char Vile11[] = "I did not know this Lazarus of whom you speak, but " +"I do sense a great conflict within his being. He poses a great danger, " +"and will stop at nothing to serve the powers of darkness which have " +"claimed him as theirs. |"; + +static char Vile12[] = "Yes, the righteous Lazarus, who was sooo effective " +"against those monsters down there. Didn't help save my leg, did it? " +"Look, I'll give you a free piece of advice. Ask Farnham, he was there. |"; + +//If the hero meets Lazarus after the sacrifice +static char Vile13[] = "Abandon your foolish quest. All that awaits you " +"is the wrath of my Master! You are too late to save the child. Now you will " +"join him in Hell! |"; + +//deleted +static char Vile14[] = " |"; +#endif + +/*-----------------------------------------------------------------------** +** Poisoned Water Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Poison1[] = "Hmm, I don't know what I can really tell you about " +"this that will be of any help. The water that fills our wells comes " +"from an underground spring. I have heard of a tunnel that leads to a " +"great lake - perhaps they are one and the same. Unfortunately, I do not " +"know what would cause our water supply to be tainted. |"; + +static char Poison2[] = "I have always tried to keep a large supply of " +"foodstuffs and drink in our storage cellar, but with the entire town " +"having no source of fresh water, even our stores will soon run dry. \n \n" +"Please, do what you can or I don't know what we will do. |"; + +static char Poison3[] = "I'm glad I caught up to you in time! Our wells " +"have become brackish and stagnant and some of the townspeople have " +"become ill drinking from them. Our reserves of fresh water are " +"quickly running dry. I believe that there is a passage that leads to " +"the springs that serve our town. Please find what has caused this " +"calamity, or we all will surely perish. |"; + +//If the hero returns before completing the quest +static char Poison4[] = "Please, you must hurry. Every hour that passes " +"brings us closer to having no water to drink. \n \n" +"We cannot survive for " +"long without your help. |"; + +//If the hero completes the quest +static char Poison5[] = "What's that you say - the mere presence of the " +"demons had caused the water to become tainted? Oh, truly a great evil " +"lurks beneath our town, but your perseverance and courage gives us " +"hope. Please take this ring - perhaps it will aid you in the " +"destruction of such vile creatures. |"; + +static char Poison6[] = "My grandmother is very weak, and Garda says " +"that we cannot drink the water from the wells. Please, can you do something " +"to help us? |"; + +static char Poison7[] = "Pepin has told you the truth. We will need fresh " +"water badly, and soon. I have tried to clear one of the smaller wells, " +"but it reeks of stagnant filth. It must be getting clogged at the source. |"; + +static char Poison8[] = "You drink water? |"; + +static char Poison9[] = "The people of Tristram will die if you cannot " +"restore fresh water to their wells. \n \n" +"Know this - demons are at the heart " +"of this matter, but they remain ignorant of what they have spawned. |"; + +static char Poison10[] = "For once, I'm with you. My business runs dry - so " +"to speak - if I have no market to sell to. You better find out what is " +"going on, and soon! |"; +#endif + +/*-----------------------------------------------------------------------** +** The Chamber of Bone Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Bone1[] = "A book that speaks of a chamber of human bones? Well, " +"a Chamber of Bone is mentioned in certain archaic writings that I " +"studied in the libraries of the East. These tomes inferred that when " +"the Lords of the underworld desired to protect great treasures, they " +"would create domains where those who died in the attempt to steal that " +"treasure would be forever bound to defend it. A twisted, but strangely " +"fitting, end? |"; + +static char Bone2[] = "I am afraid that I don't know anything about that, " +"good master. Cain has many books that may be of some help. |"; + +static char Bone3[] = "This sounds like a very dangerous place. If you " +"venture there, please take great care. |"; + +static char Bone4[] = "I am afraid that I haven't heard anything about " +"that. Perhaps Cain the Storyteller could be of some help. |"; + +static char Bone5[] = "I know nothing of this place, but you may try " +"asking Cain. He talks about many things, and it would not surprise " +"me if he had some answers to your question. |"; + +static char Bone6[] = "Okay, so listen. There's this chamber of wood, " +"see. And his wife, you know - her - tells the tree... cause you gotta " +"wait. Then I says, that might work against him, but if you think I'm " +"gonna PAY for this... you... uh... yeah. |"; + +static char Bone7[] = "You will become an eternal servant of the dark " +"lords should you perish within this cursed domain. \n \n" +"Enter the Chamber " +"of Bone at your own peril. |"; + +static char Bone8[] = "A vast and mysterious treasure, you say? Maybe I " +"could be interested in picking up a few things from you... or better " +"yet, don't you need some rare and expensive supplies to get you through " +"this ordeal? |"; +#endif + +/*-----------------------------------------------------------------------** +** The Butcher Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Butch1[] = "It seems that the Archbishop Lazarus goaded many " +"of the townsmen into venturing into the Labyrinth to find the King's " +"missing son. He played upon their fears and whipped them into a " +"frenzied mob. None of them were prepared for what lay within the cold " +"earth... Lazarus abandoned them down there - left in the clutches of " +"unspeakable horrors - to die. |"; + +static char Butch2[] = "Yes, Farnham has mumbled something about a hulking " +"brute who wielded a fierce weapon. I believe he called him a butcher. |"; + +static char Butch3[] = "By the Light, I know of this vile demon. There were " +"many that bore the scars of his wrath upon their bodies when the few " +"survivors of the charge led by Lazarus crawled from the Cathedral. I " +"don't know what he used to slice open his victims, but it could not " +"have been of this world. It left wounds festering with disease and " +"even I found them almost impossible to treat. Beware if you plan to " +"battle this fiend... |"; + +static char Butch4[] = "When Farnham said something about a butcher killing " +"people, I immediately discounted it. But since you brought it up, maybe " +"it is true. |"; + +static char Butch5[] = "I saw what Farnham calls the Butcher as it swathed " +"a path through the bodies of my friends. He swung a cleaver as large " +"as an axe, hewing limbs and cutting down brave men where they stood. I " +"was separated from the fray by a host of small screeching demons and " +"somehow found the stairway leading out. I never saw that hideous beast " +"again, but his blood-stained visage haunts me to this day. |"; + +static char Butch6[] = "Big! Big cleaver killing all my friends. Couldn't " +"stop him, had to run away, couldn't save them. Trapped in a room with " +"so many bodies... so many friends... NOOOOOOOOOO! |"; + +static char Butch7[] = "The Butcher is a sadistic creature that delights " +"in the torture and pain of others. You have seen his handiwork in the " +"drunkard Farnham. His destruction will do much to ensure the safety of " +"this village. |"; + +static char Butch8[] = "I know more than you'd think about that grisly " +"fiend. His little friends got a hold of me and managed to get my leg " +"before Griswold pulled me out of that hole. \n \n" +"I'll put it bluntly - " +"kill him before he kills you and adds your corpse to his collection. |"; + +//wounded townsman +static char Butch9[] = "Please, listen to me. The Archbishop " +"Lazarus, he led us down here to find the lost prince. The bastard " +"led us into a trap! Now everyone is dead... killed by a demon he " +"called the Butcher. Avenge us! Find this Butcher and slay him so " +"that our souls may finally rest... |"; + +//butcher +static char Butch10[] = " |"; +#endif + +/*-----------------------------------------------------------------------** +** Halls of the Blind Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Blind1[] = "You recite an interesting rhyme written in a style " +"that reminds me of other works. Let me think now - what was it?\n \n" +"...Darkness shrouds the Hidden. Eyes glowing unseen with only the " +"sounds of razor claws briefly scraping to torment those poor souls who " +"have been made sightless for all eternity. The prison for those so " +"damned is named the Halls of the Blind... |"; + +static char Blind2[] = "I never much cared for poetry. Occasionally, I had " +"cause to hire minstrels when the inn was doing well, but that seems " +"like such a long time ago now. \n \n" +"What? Oh, yes... uh, well, I suppose you " +"could see what someone else knows. |"; + +static char Blind3[] = "This does seem familiar, somehow. I seem to recall " +"reading something very much like that poem while researching the " +"history of demonic afflictions. It spoke of a place of great evil " +"that... wait - you're not going there are you? |"; + +static char Blind4[] = "If you have questions about blindness, you should " +"talk to Pepin. I know that he gave my grandmother a potion that helped " +"clear her vision, so maybe he can help you, too. |"; + +static char Blind5[] = "I am afraid that I have neither heard nor seen a " +"place that matches your vivid description, my friend. Perhaps Cain " +"the Storyteller could be of some help. |"; + +static char Blind6[] = "Look here... that's pretty funny, huh? " +"Get it? Blind - look here? |"; + +static char Blind7[] = "This is a place of great anguish and terror, and " +"so serves its master well. \n \n" +"Tread carefully or you may yourself " +"be staying much longer than you had anticipated. |"; + +static char Blind8[] = "Lets see, am I selling you something? No. Are you " +"giving me money to tell you about this? No. Are you now leaving and " +"going to talk to the storyteller who lives for this kind of thing? " +"Yes. |"; +#endif + +/*-----------------------------------------------------------------------** +** Veil of Steel Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Veil1[] = "You claim to have spoken with Lachdanan? He was a " +"great hero during his life. Lachdanan was an honorable and just man " +"who served his King faithfully for years. But of course, you already " +"know that.\n \n" +"Of those who were caught within the grasp of the King's " +"Curse, Lachdanan would be the least likely to submit to the darkness " +"without a fight, so I suppose that your story could be true. If I were " +"in your place, my friend, I would find a way to release him from his " +"torture. |"; + +static char Veil2[] = "You speak of a brave warrior long dead! I'll have " +"no such talk of speaking with departed souls in my inn yard, thank you " +"very much. |"; + +static char Veil3[] = "A golden elixir, you say. I have never concocted a " +"potion of that color before, so I can't tell you how it would effect " +"you if you were to try to drink it. As your healer, I strongly advise " +"that should you find such an elixir, do as Lachdanan asks and " +"DO NOT try to use it. |"; + +static char Veil4[] = "I've never heard of a Lachdanan before. I'm sorry, but " +"I don't think that I can be of much help to you. |"; + +static char Veil5[] = "If it is actually Lachdanan that you have met, then " +"I would advise that you aid him. I dealt with him on several occasions " +"and found him to be honest and loyal in nature. The curse that fell " +"upon the followers of King Leoric would fall especially hard upon him. |"; + +static char Veil6[] = " Lachdanan is dead. Everybody knows that, and you " +"can't fool me into thinking any other way. You can't talk to the dead. " +"I know! |"; + +static char Veil7[] = "You may meet people who are trapped within the " +"Labyrinth, such as Lachdanan. \n \n" +"I sense in him honor and great guilt. " +"Aid him, and you aid all of Tristram. |"; + +static char Veil8[] = "Wait, let me guess. Cain was swallowed up in a " +"gigantic fissure that opened beneath him. He was incinerated in a ball " +"of hellfire, and can't answer your questions anymore. Oh, that isn't " +"what happened? Then I guess you'll be buying something or you'll be " +"on your way. |"; + +//upon meeting the captain +static char Veil9[] = "Please, don't kill me, just hear me out. I was once " +"Captain of King Leoric's Knights, upholding the laws of this land with " +"justice and honor. Then his dark Curse fell upon us for the role we " +"played in his tragic death. As my fellow Knights succumbed to their " +"twisted fate, I fled from the King's burial chamber, searching for " +"some way to free myself from the Curse. I failed...\n \n" +"I have heard of a Golden Elixir that could lift the Curse and allow " +"my soul to rest, but I have been unable to find it. My strength now " +"wanes, and with it the last of my humanity as well. Please aid me and " +"find the Elixir. I will repay your efforts - I swear upon my honor. |"; + +//If the hero returns without the Elixir +static char Veil10[] = "You have not found the Golden Elixir. I fear that " +"I am doomed for eternity. Please, keep trying... |"; + +//If the hero returns with the Elixir +static char Veil11[] = "You have saved my soul from damnation, and for " +"that I am in your debt. If there is ever a way that I can repay you " +"from beyond the grave I will find it, but for now - take my helm. On " +"the journey I am about to take I will have little use for it. May it " +"protect you against the dark powers below. Go with the Light, my " +"friend... |"; +#endif + +/*-----------------------------------------------------------------------** +** The Anvil of Fury Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Anvil1[] = "Griswold speaks of The Anvil of Fury - a legendary " +"artifact long searched for, but never found. Crafted from the metallic " +"bones of the Razor Pit demons, the Anvil of Fury was smelt around the " +"skulls of the five most powerful magi of the underworld. Carved with " +"runes of power and chaos, any weapon or armor forged upon this Anvil " +"will be immersed into the realm of Chaos, imbedding it with magical " +"properties. It is said that the unpredictable nature of Chaos makes " +"it difficult to know what the outcome of this smithing will be... |"; + +static char Anvil2[] = "Don't you think that Griswold would be a better " +"person to ask about this? He's quite handy, you know. |"; + +static char Anvil3[] = "If you had been looking for information on the " +"Pestle of Curing or the Silver Chalice of Purification, I could have " +"assisted you, my friend. However, in this matter, you would be better " +"served to speak to either Griswold or Cain. |"; + +static char Anvil4[] = "Griswold's father used to tell some of us when we " +"were growing up about a giant anvil that was used to make mighty " +"weapons. He said that when a hammer was struck upon this anvil, the " +"ground would shake with a great fury. Whenever the earth moves, I " +"always remember that story. |"; + +static char Anvil5[] = "Greetings! It's always a pleasure to see one of " +"my best customers! I know that you have been venturing deeper into " +"the Labyrinth, and there is a story I was told that you may find worth " +"the time to listen to...\n \n" +"One of the men who returned from the Labyrinth told me about a mystic " +"anvil that he came across during his escape. His description reminded " +"me of legends I had heard in my youth about the burning Hellforge where " +"powerful weapons of magic are crafted. The legend had it that deep " +"within the Hellforge rested the Anvil of Fury! This Anvil contained " +"within it the very essence of the demonic underworld...\n \n" +"It is said that any weapon crafted upon the burning Anvil is imbued " +"with great power. If this anvil is indeed the Anvil of Fury, I may " +"be able to make you a weapon capable of defeating even the darkest " +"lord of Hell! \n \n" +"Find the Anvil for me, and I'll get to work! |"; + +//If the hero returns without the Anvil +static char Anvil6[] = "Nothing yet, eh? Well, keep searching. A weapon " +"forged upon the Anvil could be your best hope, and I am sure that I " +"can make you one of legendary proportions. |"; + +//If the hero returns with the Anvil +static char Anvil7[] = "I can hardly believe it! This is the Anvil of Fury " +"- good work, my friend. Now we'll show those bastards that there are " +"no weapons in Hell more deadly than those made by men! Take this and " +"may Light protect you. |"; + +static char Anvil8[] = "Griswold can't sell his anvil. What will he do " +"then? And I'd be angry too if someone took my anvil! |"; + +static char Anvil9[] = "There are many artifacts within the Labyrinth " +"that hold powers beyond the comprehension of mortals. Some of these " +"hold fantastic power that can be used by either the Light or the " +"Darkness. Securing the Anvil from below could shift the course of " +"the Sin War towards the Light. |"; + +static char Anvil10[] = "If you were to find this artifact for Griswold, " +"it could put a serious damper on my business here. Awwww, you'll never " +"find it. |"; +#endif + +/*-----------------------------------------------------------------------** +** Stones of Blood Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Blood1[] = "The Gateway of Blood and the Halls of Fire are " +"landmarks of mystic origin. Wherever this book you read from resides it is " +"surely a place of great power.\n \n" +"Legends speak of a pedestal that is carved from obsidian stone and " +"has a pool of boiling blood atop its bone encrusted surface. There " +"are also allusions to Stones of Blood that will open a door that " +"guards an ancient treasure...\n \n" +"The nature of this treasure is shrouded in speculation, my friend, " +"but it is said that the ancient hero Arkaine placed the holy armor " +"Valor in a secret vault. Arkaine was the first mortal to turn the " +"tide of the Sin War and chase the legions of darkness back to the " +"Burning Hells.\n \n" +"Just before Arkaine died, his armor was hidden away " +"in a secret vault. It is said that when this holy armor is again " +"needed, a hero will arise to don Valor once more. Perhaps you are " +"that hero... |"; + +static char Blood2[] = "Every child hears the story of the warrior Arkaine " +"and his mystic armor known as Valor. If you could find its resting " +"place, you would be well protected against the evil in the " +"Labyrinth. |"; + +static char Blood3[] = "Hmm... it sounds like something I should remember, " +"but I've been so busy learning new cures and creating better elixirs " +"that I must have forgotten. Sorry... |"; + +static char Blood4[] = "The story of the magic armor called Valor is " +"something I often heard the boys talk about. You had better ask one " +"of the men in the village. |"; + +static char Blood5[] = "The armor known as Valor could be what tips the " +"scales in your favor. I will tell you that many have looked for it - " +"including myself. Arkaine hid it well, my friend, and it will take " +"more than a bit of luck to unlock the secrets that have kept it " +"concealed oh, lo these many years. |"; + +static char Blood6[] = "Zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz... |"; + +static char Blood7[] = "Should you find these Stones of Blood, use them " +"carefully. \n \n" +"The way is fraught with danger and your only hope rests " +"within your self trust. |"; + +static char Blood8[] = "You intend to find the armor known as Valor? \n \n" +"No " +"one has ever figured out where Arkaine stashed the stuff, and if my " +"contacts couldn't find it, I seriously doubt you ever will either. |"; +#endif + +/*-----------------------------------------------------------------------** +** Warlord of Blood Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Warlrd1[] = "I know of only one legend that speaks of such a " +"warrior as you describe. His story is found within the ancient " +"chronicles of the Sin War...\n \n" +"Stained by a thousand years of war, blood and death, the Warlord of " +"Blood stands upon a mountain of his tattered victims. His dark blade " +"screams a black curse to the living; a tortured invitation to any who " +"would stand before this Executioner of Hell.\n \n" +"It is also written that " +"although he was once a mortal who fought beside the Legion of Darkness " +"during the Sin War, he lost his humanity to his insatiable hunger for " +"blood. |"; + +static char Warlrd2[] = "I am afraid that I haven't heard anything about " +"such a vicious warrior, good master. I hope that you do not have to fight " +"him, for he sounds extremely dangerous. |"; + +static char Warlrd3[] = "Cain would be able to tell you much more about " +"something like this than I would ever wish to know. |"; + +static char Warlrd4[] = "If you are to battle such a fierce opponent, may " +"Light be your guide and your defender. I will keep you in my thoughts. |"; + +static char Warlrd5[] = "Dark and wicked legends surrounds the one Warlord " +"of Blood. Be well prepared, my friend, for he shows no mercy or quarter. |"; + +static char Warlrd6[] = "Always you gotta talk about Blood? What about " +"flowers, and sunshine, and that pretty girl that brings the drinks. " +"Listen here, friend - you're obsessive, you know that? |"; + +static char Warlrd7[] = "His prowess with the blade is awesome, and he " +"has lived for thousands of years knowing only warfare. I am sorry... " +"I can not see if you will defeat him. |"; + +static char Warlrd8[] = "I haven't ever dealt with this Warlord you speak " +"of, but he sounds like he's going through a lot of swords. Wouldn't mind " +"supplying his armies... |"; + +static char Warlrd9[] = "My blade sings for your blood, mortal, and by my " +"dark masters it shall not be denied. |"; +#endif + +/*-----------------------------------------------------------------------** +** Ring of Infravision Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Infra1[] = "Griswold speaks of the Heaven Stone that was " +"destined for the enclave located in the east. It was being taken " +"there for further study. This stone glowed with an energy that " +"somehow granted vision beyond that which a normal man could possess. " +"I do not know what secrets it holds, my friend, but finding this " +"stone would certainly prove most valuable. |"; + +static char Infra2[] = "The caravan stopped here to take on some supplies " +"for their journey to the east. I sold them quite an array of fresh " +"fruits and some excellent sweetbreads that Garda has just finished " +"baking. Shame what happened to them... |"; + +static char Infra3[] = "I don't know what it is that they thought they " +"could see with that rock, but I will say this. If rocks are falling " +"from the sky, you had better be careful! |"; + +static char Infra4[] = "Well, a caravan of some very important people did " +"stop here, but that was quite a while ago. They had strange accents " +"and were starting on a long journey, as I recall. \n \n" +"I don't see how you " +"could hope to find anything that they would have been carrying. |"; + +static char Infra5[] = "Stay for a moment - I have a story you might find " +"interesting. A caravan that was bound for the eastern kingdoms passed " +"through here some time ago. It was supposedly carrying a piece of the " +"heavens that had fallen to earth! The caravan was ambushed by cloaked " +"riders just north of here along the roadway. I searched the wreckage " +"for this sky rock, but it was nowhere to be found. If you should find " +"it, I believe that I can fashion something useful from it. |"; + +//If the hero returns before completing the quest +static char Infra6[] = "I am still waiting for you to bring me that stone " +"from the heavens. I know that I can make something powerful out of it. |"; + +//If the hero returns before completing the quest +static char Infra7[] = "Let me see that - aye... aye, it is as I believed. Give me " +"a moment...\n \n" +"Ah, Here you are. I arranged pieces of the stone within a silver ring " +"that my father left me. I hope it serves you well. |"; + +static char Infra8[] = "I used to have a nice ring; it was a really " +"expensive one, with blue and green and red and silver. Don't remember " +"what happened to it, though. I really miss that ring... |"; + +static char Infra9[] = "The Heaven Stone is very powerful, and were it " +"any but Griswold who bid you find it, I would prevent it. He will " +"harness its powers and its use will be for the good of us all. |"; + +static char Infra10[] = "If anyone can make something out of that rock, " +"Griswold can. He knows what he is doing, and as much as I try to " +"steal his customers, I respect the quality of his work. |"; +#endif + +/*-----------------------------------------------------------------------** +** Black Mushroom Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Mush1[] = "The witch Adria seeks a black mushroom? I know as " +"much about Black Mushrooms as I do about Red Herrings. Perhaps " +"Pepin the Healer could tell you more, but this is something that " +"cannot be found in any of my stories or books. |"; + +//Tavern guy +static char Mush2[] = "Let me just say this. Both Garda and I would never, " +"EVER serve black mushrooms to our honored guests. If Adria wants some " +"mushrooms in her stew, then that is her business, but I can't help you " +"find any. Black mushrooms... disgusting! |"; + +//If the hero goes to the healer without the brain +static char Mush3[] = "The witch told me that you were searching for the " +"brain of a demon to assist me in creating my elixir. It should be of " +"great value to the many who are injured by those foul beasts, if I can " +"just unlock the secrets I suspect that its alchemy holds. If you can " +"remove the brain of a demon when you kill it, I would be grateful if " +"you could bring it to me. |"; + +//If the hero brings a brain to the healer +static char Mush4[] = "Excellent, this is just what I had in mind. I was " +"able to finish the elixir without this, but it can't hurt to have this " +"to study. Would you please carry this to the witch? I believe that she " +"is expecting it. |"; + +static char Mush5[] = "I think Ogden might have some mushrooms in the " +"storage cellar. Why don't you ask him? |"; + +static char Mush6[] = "If Adria doesn't have one of these, you can bet " +"that's a rare thing indeed. I can offer you no more help than that, " +"but it sounds like... a huge, gargantuan, swollen, bloated mushroom! " +"Well, good hunting, I suppose. |"; + +static char Mush7[] = "Ogden mixes a MEAN black mushroom, but I get sick " +"if I drink that. Listen, listen... here's the secret - moderation is " +"the key! |"; + +//If hero brings the Fungal Tome to the Witch +static char Mush8[] = "What do we have here? Interesting, it looks like a " +"book of reagents. Keep your eyes open for a black mushroom. It should " +"be fairly large and easy to identify. If you find it, bring it to me, " +"won't you? |"; + +//If hero returns without the mushroom +static char Mush9[] = "It's a big, black mushroom that I need. Now run off " +"and get it for me so that I can use it for a special concoction that " +"I am working on. |"; + +//If hero brings the mushroom to the witch +static char Mush10[] = "Yes, this will be perfect for a brew that I am " +"creating. By the way, the healer is looking for the brain of some " +"demon or another so he can treat those who have been afflicted by " +"their poisonous venom. I believe that he intends to make an elixir " +"from it. If you help him find what he needs, please see if you can " +"get a sample of the elixir for me. |"; + +//If hero brings the brain to the witch +static char Mush11[] = "Why have you brought that here? I have no need " +"for a demon's brain at this time. I do need some of the elixir that " +"the Healer is working on. He needs that grotesque organ that you " +"are holding, and then bring me the elixir. Simple when you think about " +"it, isn't it? |"; + +//If the hero takes the elixir to the witch +static char Mush12[] = "What? Now you bring me that elixir from the healer? " +"I was able to finish my brew without it. Why don't you just keep it... |"; + +static char Mush13[] = "I don't have any mushrooms of any size or color " +"for sale. How about something a bit more useful? |"; +#endif + +/*-----------------------------------------------------------------------** +** Map of Doom Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Doom1[] = "So, the legend of the Map is real. Even I never " +"truly believed any of it! I suppose it is time that I told you the " +"truth about who I am, my friend. You see, I am not all that I seem...\n \n" +"My true name is Deckard Cain the Elder, and I am the last descendant " +"of an ancient Brotherhood that was dedicated to keeping and safeguarding " +"the secrets of a timeless evil. An evil that quite obviously has now " +"been released...\n \n" +"The evil that you move against is the dark Lord of Terror - known to " +"mortal men as Diablo. It was he who was imprisoned within the Labyrinth " +"many centuries ago. The Map that you hold now was created ages ago to " +"mark the time when Diablo would rise again from his imprisonment. When " +"the two stars on that map align, Diablo will be at the height of his " +"power. He will be all but invincible...\n \n" +"You are now in a race against time, my friend! Find Diablo and destroy " +"him before the stars align, for we may never have a chance to rid the " +"world of his evil again! |"; + +//If the hero returns before the stars align and Diablo is Alive +static char Doom2[] = "Our time is running short! I sense his dark power " +"building and only you can stop him from attaining his full might. |"; + +//If the hero returns after the stars align and Diablo is Alive +static char Doom3[] = "I am sure that you tried your best, but I fear that " +"even your strength and will may not be enough. Diablo is now at the " +"height of his earthly power, and you will need all your courage and " +"strength to defeat him. May the Light protect and guide you, my friend. " +"I will help in any way that I am able. |"; + +static char Doom4[] = "If the witch can't help you and suggests you see Cain, " +"what makes you think that I would know anything? It sounds like this is a " +"very serious matter. You should hurry along and see the storyteller as " +"Adria suggests. |"; + +static char Doom5[] = "I can't make much of the writing on this map, but " +"perhaps Adria or Cain could help you decipher what this refers to. \n \n" +"I can see that it is a map of the stars in our sky, but any more than " +"that is beyond my talents. |"; + +static char Doom6[] = "The best person to ask about that sort of thing " +"would be our storyteller. \n \n" +"Cain is very knowledgeable about ancient " +"writings, and that is easily the oldest looking piece of paper that " +"I have ever seen. |"; + +static char Doom7[] = "I have never seen a map of this sort before. Where'd you get it? " +"Although I have no idea how to read this, Cain or Adria may be able " +"to provide the answers that you seek. |"; + +static char Doom8[] = "Listen here, come close. I don't know if you know " +"what I know, but you have really got somethin' here. That's a map. |"; + +static char Doom9[] = "Oh, I'm afraid this does not bode well at all. This map " +"of the stars portends great disaster, but its secrets are not mine to " +"tell. The time has come for you to have a very serious conversation " +"with the Storyteller... |"; + +static char Doom10[] = "I've been looking for a map, but that certainly " +"isn't it. You should show that to Adria - she can probably tell you " +"what it is. I'll say one thing; it looks old, and old usually means " +"valuable. |"; +#endif + +/*-----------------------------------------------------------------------** +** Garbud the Weak Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +//Gharbad the Weak Encounter +static char Garbud1[] = "Pleeeease, no hurt. No Kill. Keep alive and next " +"time good bring to you. |"; + +//When the hero finds Gharbad again +static char Garbud2[] = "Something for you I am making. Again, not kill " +"Gharbad. Live and give good. \n \n" +"You take this as proof I keep word... |"; + +//When the hero finds Gharbad again +static char Garbud3[] = "Nothing yet! Almost done. \n \n" +"Very powerful, very " +"strong. Live! Live! \n \n" +"No pain and promise I keep! |"; + +//When the hero finds Gharbad again +static char Garbud4[] = "This too good for you. Very Powerful! You want - " +"you take! |"; +#endif + +/*-----------------------------------------------------------------------** +** Zhar the Mad Quest +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +//Zhar the Mad Encounter +static char Zhar1[] = "What?! Why are you here? All these interruptions " +"are enough to make one insane. Here, take this and leave me to my work. " +"Trouble me no more! |"; + +//If the hero bothers him again +static char Zhar2[] = "Arrrrgh! Your curiosity will be the death of you!!! |"; +#endif + +/*-----------------------------------------------------------------------** +// TOWNSPEOPLE'S NONQUEST +**-----------------------------------------------------------------------*/ +// Deckard Cain +static char Story1[] = "Hello, my friend. Stay awhile and listen... |"; + +#if !IS_VERSION(SHAREWARE) +static char Story2[] = "While you are venturing deeper into the Labyrinth " +"you may find tomes of great knowledge hidden there. \n \n" +"Read them carefully " +"for they can tell you things that even I cannot. |"; + +static char Story3[] = "I know of many myths and legends that may contain " +"answers to questions that may arise in your journeys into the Labyrinth. " +"If you come across challenges and questions to which you seek knowledge, " +"seek me out and I will tell you what I can. |"; + +static char Story4[] = "Griswold - a man of great action and great courage. " +"I bet he never told you about the time he went into the Labyrinth to " +"save Wirt, did he? He knows his fair share of the dangers to be found " +"there, but then again - so do you. He is a skilled craftsman, and if " +"he claims to be able to help you in any way, you can count on his " +"honesty and his skill. |"; + +static char Story5[] = "Ogden has owned and run the Rising Sun Inn and " +"Tavern for almost four years now. He purchased it just a few short " +"months before everything here went to hell. He and his wife Garda do " +"not have the money to leave as they invested all they had in making " +"a life for themselves here. He is a good man with a deep sense of " +"responsibility. |"; + + +static char Story6[] = "Poor Farnham. He is a disquieting reminder of the " +"doomed assembly that entered into the Cathedral with Lazarus on that " +"dark day. He escaped with his life, but his courage and much of his " +"sanity were left in some dark pit. He finds comfort only at the bottom " +"of his tankard nowadays, but there are occasional bits of truth buried " +"within his constant ramblings. |"; + +static char Story7[] = "The witch, Adria, is an anomaly here in Tristram. " +"She arrived shortly after the Cathedral was desecrated while most " +"everyone else was fleeing. She had a small hut constructed at the " +"edge of town, seemingly overnight, and has access to many strange " +"and arcane artifacts and tomes of knowledge that even I have never " +"seen before. |"; + +static char Story9[] = "The story of Wirt is a frightening and tragic one. " +"He was taken from the arms of his mother " +"and dragged into the labyrinth by the small, foul demons that wield " +"wicked spears. There were many other children taken that day, including " +"the son of King Leoric. The Knights of the palace went below, but " +"never returned. The Blacksmith found the boy, but only after the foul " +"beasts had begun to torture him for their sadistic pleasures. |"; + +static char Story10[] = "Ah, Pepin. I count him as a true friend - perhaps " +"the closest I have here. He is a bit addled at times, but never a more " +"caring or considerate soul has existed. His knowledge and skills are " +"equaled by few, and his door is always open. |"; + +static char Story11[] = "Gillian is a fine woman. Much adored for her high " +"spirits and her quick laugh, she holds a special place in my heart. She " +"stays on at the tavern to support her elderly grandmother who is too " +"sick to travel. I sometimes fear for her safety, but I know that any man " +"in the village would rather die than see her harmed. |"; +#endif + +// Ogden +static char Ogden1[] = "Greetings, good master. Welcome to the Tavern of " +"the Rising Sun! |"; + +#if !IS_VERSION(SHAREWARE) +static char Ogden2[] = "Many adventurers have graced the tables of my tavern, " +"and ten times as many stories have been told over as much ale. The only " +"thing that I ever heard any of them agree on was this old axiom. Perhaps " +"it will help you. " +"You can cut the flesh, but you must crush the bone. |"; + +static char Ogden3[] = "Griswold the blacksmith is extremely knowledgeable " +"about weapons and armor. If you ever need work done on your gear, he is " +"definitely the man to see. |"; + +static char Ogden4[] = "Farnham spends far too much time here, drowning his " +"sorrows in cheap ale. I would make him leave, but he did suffer so during " +"his time in the Labyrinth. |"; + +static char Ogden5[] = "Adria is wise beyond her years, but I must admit - " +"she frightens me a little. \n \n" +"Well, no matter. If you ever have need to " +"trade in items of sorcery, she maintains a strangely well-stocked hut " +"just across the river. |"; + +static char Ogden6[] = "If you want to know more about the history of our " +"village, the storyteller Cain knows quite a bit about the past. |"; + +static char Ogden8[] = "Wirt is a rapscallion and a little scoundrel. He " +"was always getting into trouble, and it's no surprise what happened to " +"him. \n \n" +"He probably went fooling about someplace that he shouldn't have " +"been. I feel sorry for the boy, but I don't abide the company that he keeps. |"; + +static char Ogden9[] = "Pepin is a good man - and certainly the most " +"generous in the village. He is always attending to the needs of others, " +"but trouble of some sort or another does seem to follow him wherever he " +"goes... |"; + +static char Ogden10[] = "Gillian, my Barmaid? If it were not for her sense " +"of duty to her grand-dam, she would have fled from here long ago. \n \n" +"Goodness knows I begged her to leave, telling her that I would watch " +"after the old woman, but she is too sweet and caring to have done so. |"; +#endif + +// Pepin +static char Pepin1[] = "What ails you, my friend? |"; + +#if !IS_VERSION(SHAREWARE) +static char Pepin2[] = "I have made a very interesting discovery. Unlike " +"us, the creatures in the Labyrinth can heal themselves without the aid " +"of potions or magic. If you hurt one of the monsters, make sure it is " +"dead or it very well may regenerate itself. |"; + +static char Pepin3[] = "Before it was taken over by, well, whatever lurks " +"below, the Cathedral was a place of great learning. There are many " +"books to be found there. If you find any, you should read them all, " +"for some may hold secrets to the workings of the Labyrinth. |"; + +static char Pepin4[] = "Griswold knows as much about the art of war as I " +"do about the art of healing. He is a shrewd merchant, but his work is " +"second to none. Oh, I suppose that may be because he is the only " +"blacksmith left here. |"; + +static char Pepin5[] = "Cain is a true friend and a wise sage. He maintains " +"a vast library and has an innate ability to discern the true nature of " +"many things. If you ever have any questions, he is the person to go to. |"; + +static char Pepin6[] = "Even my skills have been unable to fully heal " +"Farnham. Oh, I have been able to mend his body, but his mind and spirit " +"are beyond anything I can do. |"; + +static char Pepin7[] = "While I use some limited forms of magic to create " +"the potions and elixirs I store here, Adria is a true sorceress. She " +"never seems to sleep, and she always has access to many mystic tomes " +"and artifacts. I believe her hut may be much more than the hovel " +"it appears to be, but I can never seem to get inside the place. |"; + +static char Pepin9[] = "Poor Wirt. I did all that was possible for the " +"child, but I know he despises that wooden peg that I was forced to " +"attach to his leg. His wounds were hideous. No one - and especially " +"such a young child - should have to suffer the way he did. |"; + +static char Pepin10[] = "I really don't understand why Ogden stays here " +"in Tristram. He suffers from a slight nervous condition, but he is an " +"intelligent and industrious man who would do very well wherever he " +"went. I suppose it may be the fear of the many murders that happen in " +"the surrounding countryside, or perhaps the wishes of his wife that " +"keep him and his family where they are. |"; + +static char Pepin11[] = "Ogden's barmaid is a sweet girl. Her grandmother " +"is quite ill, and suffers from delusions. \n \n" +"She claims that they are " +"visions, but I have no proof of that one way or the other. |"; +#endif + +// Gillian +static char Gillian1[] = "Good day! How may I serve you? |"; + +#if !IS_VERSION(SHAREWARE) +static char Gillian2[] = "My grandmother had a dream that you would come " +"and talk to me. She has visions, you know and can see into the future. |"; + +static char Gillian3[] = "The woman at the edge of town is a witch! She " +"seems nice enough, and her name, Adria, is very pleasing to the ear, " +"but I am very afraid of her. \n \n" +"It would take someone quite brave, like " +"you, to see what she is doing out there. |"; + +static char Gillian4[] = "Our Blacksmith is a point of pride to the people " +"of Tristram. Not only is he a master craftsman who has won many " +"contests within his guild, but he received praises from our King " +"Leoric himself - may his soul rest in peace. Griswold is also a great hero; just " +"ask Cain. |"; + +static char Gillian5[] = "Cain has been the storyteller of Tristram for " +"as long as I can remember. He knows so much, and can tell you just " +"about anything about almost everything. |"; + +static char Gillian6[] = "Farnham is a drunkard who fills his belly with " +"ale and everyone else's ears with nonsense. \n \n" +"I know that both Pepin " +"and Ogden feel sympathy for him, but I get so frustrated watching him " +"slip farther and farther into a befuddled stupor every night. |"; + +static char Gillian7[] = "Pepin saved my grandmother's life, and I know " +"that I can never repay him for that. His ability to heal any sickness " +"is more powerful than the mightiest sword and more mysterious than any spell you " +"can name. If you ever are in need of healing, Pepin can help you. |"; + +static char Gillian9[] = "I grew up with Wirt's mother, Canace. Although " +"she was only slightly hurt when those hideous creatures stole him, " +"she never recovered. I think she died of a broken heart. Wirt has " +"become a mean-spirited youngster, looking only to profit from the " +"sweat of others. I know that he suffered and has seen horrors that " +"I cannot even imagine, but some of that darkness hangs over him still. |"; + +static char Gillian10[] = "Ogden and his wife have taken me and my " +"grandmother into their home and have even let me earn a few gold " +"pieces by working at the inn. I owe so much to them, and hope one " +"day to leave this place and help them start a grand hotel in the east. |"; +#endif + +// Griswold +static char Griswold1[] = "Well, what can I do for ya? |"; + +#if !IS_VERSION(SHAREWARE) +static char Griswold2[] = "If you're looking for a good weapon, let me show " +"this to you. Take your basic blunt weapon, such as a mace. Works like " +"a charm against most of those undying horrors down there, and there's " +"nothing better to shatter skinny little skeletons! |"; + +static char Griswold3[] = "The axe? Aye, that's a good weapon, balanced against any " +"foe. Look how it cleaves the air, and then imagine a nice fat demon " +"head in its path. Keep in mind, however, that it is slow to swing - " +"but talk about dealing a heavy blow! |"; + +static char Griswold4[] = "Look at that edge, that balance. A sword in " +"the right hands, and against the right foe, is the master of all " +"weapons. Its keen blade finds little to hack or pierce on the undead, " +"but against a living, breathing enemy, a sword will better slice their " +"flesh! |"; + +static char Griswold5[] = "Your weapons and armor will show the signs of " +"your struggles against the Darkness. If you bring them to me, with a " +"bit of work and a hot forge, I can restore them to top fighting form. |"; + +static char Griswold6[] = "While I have to practically smuggle in the " +"metals and tools I need from caravans that skirt the edges of our " +"damned town, that witch, Adria, always seems to get whatever she needs. " +"If I knew even the smallest bit about how to harness magic as she did, " +"I could make some truly incredible things. |"; + +static char Griswold7[] = "Gillian is a nice lass. Shame that her gammer " +"is in such poor health or I would arrange to get both of them out of " +"here on one of the trading caravans. |"; + +static char Griswold8[] = "Sometimes I think that Cain talks too much, " +"but I guess that is his calling in life. If I could bend steel as " +"well as he can bend your ear, I could make a suit of court plate " +"good enough for an Emperor! |"; + +static char Griswold9[] = "I was with Farnham that night that Lazarus " +"led us into Labyrinth. I never saw the Archbishop again, and I may " +"not have survived if Farnham was not at my side. I fear that the " +"attack left his soul as crippled as, well, another did my leg. I " +"cannot fight this battle for him now, but I would if I could. |"; + +static char Griswold10[] = "A good man who puts the needs of others above " +"his own. You won't find anyone left in Tristram - or anywhere else " +"for that matter - who has a bad thing to say about the healer. |"; + +static char Griswold12[] = "That lad is going to get himself into serious " +"trouble... or I guess I should say, again. I've tried to interest him " +"in working here and learning an honest trade, but he prefers the high " +"profits of dealing in goods of dubious origin. I cannot hold that " +"against him after what happened to him, but I do wish he would at " +"least be careful. |"; + +static char Griswold13[] = "The Innkeeper has little business and no real " +"way of turning a profit. He manages to make ends meet by providing " +"food and lodging for those who occasionally drift through the " +"village, but they are as likely to sneak off into the night as they " +"are to pay him. If it weren't for the stores of grains and dried " +"meats he kept in his cellar, why, most of us would have starved during " +"that first year when the entire countryside was overrun by demons. |"; +#endif + +// Farnham +static char Farnham1[] = "Can't a fella drink in peace? |"; + +#if !IS_VERSION(SHAREWARE) +static char Farnham2[] = "The gal who brings the drinks? Oh, yeah, what a " +"pretty lady. So nice, too. |"; + +static char Farnham3[] = "Why don't that old crone do somethin' for a " +"change. Sure, sure, she's got stuff, but you listen to me... she's " +"unnatural. I ain't never seen her eat or drink - and you can't trust " +"somebody who doesn't drink at least a little. |"; + +static char Farnham4[] = "Cain isn't what he says he is. Sure, sure, he " +"talks a good story... some of 'em are real scary or funny... but I think " +"he knows more than he knows he knows. |"; + +static char Farnham5[] = "Griswold? Good old Griswold. I love him like " +"a brother! We fought together, you know, back when... we... Lazarus... " +" Lazarus... Lazarus!!! |"; + +static char Farnham6[] = "Hehehe, I like Pepin. He really tries, you know. " +"Listen here, you should make sure you get to know him. Good fella like " +"that with people always wantin' help. Hey, I guess that would be kinda " +"like you, huh hero? I was a hero too... |"; + +static char Farnham8[] = "Wirt is a kid with more problems than even me, " +"and I know all about problems. Listen here - that kid is gotta sweet " +"deal, but he's been there, you know? Lost a leg! Gotta walk around on " +"a piece of wood. So sad, so sad... |"; + +static char Farnham9[] = "Ogden is the best man in town. I don't think his " +"wife likes me much, but as long as she keeps tappin' kegs, I'll like " +"her just fine. Seems like I been spendin' more time with Ogden than " +"most, but he's so good to me... |"; + +static char Farnham10[] = "I wanna tell ya sumthin', 'cause I know all about this " +"stuff. It's my specialty. This here is " +"the best... theeeee best! That other ale ain't no good since " +"those stupid dogs... |"; + +static char Farnham11[] = "No one ever lis... listens to me. Somewhere - " +"I ain't too sure - but somewhere under the church is a whole pile o' " +"gold. Gleamin' and shinin' and just waitin' for someone to get it. |"; + +static char Farnham12[] = "I know you gots your own ideas, and I know you're " +"not gonna believe this, but that weapon you got there - it just ain't " +"no good against those big brutes! Oh, I don't care what Griswold " +"says, they can't make anything like they used to in the old days... |"; + +static char Farnham13[] = "If I was you... and I ain't... but if I was, I'd " +"sell all that stuff you got and get out of here. That boy out there... " +"He's always got somethin good, but you gotta give him some gold or " +"he won't even show you what he's got. |"; +#endif + +// Adria +static char Adria1[] = "I sense a soul in search of answers... |"; + +#if !IS_VERSION(SHAREWARE) +static char Adria2[] = "Wisdom is earned, not given. If you discover a " +"tome of knowledge, devour its words. Should you already have knowledge " +"of the arcane mysteries scribed within a book, remember - that level of " +"mastery can always increase. |"; + +static char Adria3[] = "The greatest power is often the shortest lived. " +"You may find ancient words of power written upon scrolls of parchment. " +"The strength of these scrolls lies in the ability of either apprentice " +"or adept to cast them with equal ability. Their weakness is that they " +"must first be read aloud and can never be kept at the ready in your " +"mind. Know also that these scrolls can be read but once, so use them " +"with care. |"; + +static char Adria4[] = "Though the heat of the sun is beyond measure, the " +"mere flame of a candle is of greater danger. No energies, no matter how " +"great, can be used without the proper focus. For many spells, " +"ensorcelled Staves may be charged with magical energies many times " +"over. I have the ability to restore their power - but know that nothing " +"is done without a price. |"; + +static char Adria5[] = "The sum of our knowledge is in the sum of its " +"people. Should you find a book or scroll that you cannot decipher, do " +"not hesitate to bring it to me. If I can make sense of it I will share " +"what I find. |"; + +static char Adria6[] = "To a man who only knows Iron, there is no greater " +"magic than Steel. The blacksmith Griswold is more of a sorcerer than " +"he knows. His ability to meld fire and metal is unequaled in this land. |"; + +static char Adria7[] = "Corruption has the strength of deceit, but innocence " +"holds the power of purity. The young woman Gillian has a pure heart, " +"placing the needs of her matriarch over her own. She fears me, but it is " +"only because she does not understand me. |"; + +static char Adria8[] = "A chest opened in darkness holds no greater treasure " +"than when it is opened in the light. The storyteller Cain is an enigma, " +"but only to those who do not look. His knowledge of what lies beneath " +"the cathedral is far greater than even he allows himself to realize. |"; + +static char Adria9[] = "The higher you place your faith in one man, the " +"farther it has to fall. Farnham has lost his soul, but not to any demon. " +"It was lost when he saw his fellow townspeople betrayed by the " +"Archbishop Lazarus. He has knowledge to be gleaned, but you must " +"separate fact from fantasy. |"; + +static char Adria10[] = "The hand, the heart and the mind can perform " +"miracles when they are in perfect harmony. The healer Pepin sees into " +"the body in a way that even I cannot. His ability to restore the sick " +"and injured is magnified by his understanding of the creation of " +"elixirs and potions. He is as great an ally as you have in Tristram. |"; + +static char Adria12[] = "There is much about the future we cannot see, but " +"when it comes it will be the children who wield it. The boy Wirt has " +"a blackness upon his soul, but he poses no threat to the town or its " +"people. His secretive dealings with the urchins and unspoken guilds " +"of nearby towns gain him access to many devices that cannot be easily " +"found in Tristram. While his methods may be reproachful, Wirt can " +"provide assistance for your battle against the encroaching Darkness. |"; + +static char Adria13[] = "Earthen walls and thatched canopy do not a home " +"create. The innkeeper Ogden serves more of a purpose in this town than " +"many understand. He provides shelter for Gillian and her matriarch, " +"maintains what life Farnham has left to him, and provides an anchor " +"for all who are left in the town to what Tristram once was. His tavern, " +"and the simple pleasures that can still be found there, provide a " +"glimpse of a life that the people here remember. It is that memory " +"that continues to feed their hopes for your success. |"; +#endif + +// Wirt +static char Wirt1[] = "Pssst... over here... |"; + +#if !IS_VERSION(SHAREWARE) +static char Wirt2[] = "Not everyone in Tristram has a use - or a market - " +"for everything you will find in the labyrinth. Not even me, as hard " +"as that is to believe. \n \n" +"Sometimes, only you will be able to find a " +"purpose for some things. |"; + +static char Wirt3[] = "Don't trust everything the drunk says. Too many " +"ales have fogged his vision and his good sense. |"; + +static char Wirt4[] = "In case you haven't noticed, I don't buy anything " +"from Tristram. I am an importer of quality goods. If you want to " +"peddle junk, you'll have to see Griswold, Pepin or that witch, " +"Adria. I'm sure that they will snap up whatever you can bring them... |"; + +static char Wirt5[] = "I guess I owe the blacksmith my life - what there " +"is of it. Sure, Griswold offered me an apprenticeship at the smithy, " +"and he is a nice enough guy, but I'll never get enough money to... " +"well, let's just say that I have definite plans that require a large " +"amount of gold. |"; + +static char Wirt6[] = "If I were a few years older, I would shower her " +"with whatever riches I could muster, and let me assure you I can get " +"my hands on some very nice stuff. Gillian is a beautiful girl who " +"should get out of Tristram as soon as it is safe. Hmmm... maybe I'll " +"take her with me when I go... |"; + +static char Wirt7[] = "Cain knows too much. He scares the life out of me " +"- even more than that woman across the river. He keeps telling me " +"about how lucky I am to be alive, and how my story is foretold in " +"legend. I think he's off his crock. |"; + +static char Wirt8[] = "Farnham - now there is a man with serious problems, " +"and I know all about how serious problems can be. He trusted too much " +"in the integrity of one man, and Lazarus led him into the very jaws of " +"death. Oh, I know what it's like down there, so don't even start " +"telling me about your plans to destroy the evil that dwells in that " +"Labyrinth. Just watch your legs... |"; + +static char Wirt9[] = "As long as you don't need anything reattached, " +"old Pepin is as good as they come. \n \n" +"If I'd have had some of those " +"potions he brews, I might still have my leg... |"; + +static char Wirt11[] = "Adria truly bothers me. Sure, Cain is creepy in " +"what he can tell you about the past, but that witch can see into " +"your past. She always has some way to get whatever she needs, too. " +"Adria gets her hands on more merchandise than I've seen pass through " +"the gates of the King's Bazaar during High Festival. |"; + +static char Wirt12[] = "Ogden is a fool for staying here. I could get " +"him out of town for a very reasonable price, but he insists on trying " +"to make a go of it with that stupid tavern. I guess at the least he " +"gives Gillian a place to work, and his wife Garda does make a superb " +"Shepherd's pie... |"; +#endif + +/*-----------------------------------------------------------------------** +// BOOKS and SCROLLS as read by the heroes +**-----------------------------------------------------------------------*/ + +static char Cow1[] = " |"; + +/*-----------------------------------------------------------------------** +// BOOKS and SCROLLS as read by the heroes +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +// Warrior, Sorceror, Rogue +//SKELETAL TOME (TRIGGERS THE QUEST): +static char Boner[] = "Beyond the Hall of Heroes lies the Chamber of " +"Bone. Eternal death awaits any who would seek to steal the treasures " +"secured within this room. So speaks the Lord of Terror, and so it is " +"written. |"; + +//BOOK OF BLOOD: +static char Bloody[] = "...and so, locked beyond the Gateway of Blood and " +"past the Hall of Fire, Valor awaits for the Hero of Light to awaken... |"; + +//BOOK OF THE BLIND (TRIGGERS QUEST): +static char Blinding[] = "I can see what you see not.\n" +"Vision milky then eyes rot.\n" +"When you turn they will be gone,\n" +"Whispering their hidden song.\n" +"Then you see what cannot be,\n" +"Shadows move where light should be.\n" +"Out of darkness, out of mind,\n" +"Cast down into the Halls of the Blind. |\n"; + +//STEEL TOME (TRIGGERS QUEST): +static char Bloodwar[] = "The armories of Hell are home to the Warlord of " +"Blood. In his wake lay the mutilated bodies of thousands. Angels and " +"man alike have been cut down to fulfill his endless sacrifices to the " +"Dark ones who scream for one thing - blood. |"; +#endif + +/*-----------------------------------------------------------------------** +** The Librium of the Horadrim (White Books) +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Book11[] = "Take heed and bear witness to the truths that lie herein, for they are the " +"last legacy of the Horadrim. There is a war that rages on even now, beyond the fields that " +"we know - between the utopian kingdoms of the High Heavens and the chaotic pits of the " +"Burning Hells. This war is known as the Great Conflict, and it has raged and burned " +"longer than any of the stars in the sky. Neither side ever gains sway for long as the " +"forces of Light and Darkness constantly vie for control over all creation. |"; + +static char Book12[] = "Take heed and bear witness to the truths that lie herein, for they are the " +"last legacy of the Horadrim. When the Eternal Conflict between the High Heavens and the " +"Burning Hells falls upon mortal soil, it is called the Sin War. Angels and Demons walk " +"amongst humanity in disguise, fighting in secret, away from the prying eyes of mortals. " +"Some daring, powerful mortals have even allied themselves with either side, and helped " +"to dictate the course of the Sin War. |"; + +static char Book13[] = "Take heed and bear witness to the truths that lie herein, for they are the " +"last legacy of the Horadrim. Nearly three hundred years ago, it came to be known that the " +"Three Prime Evils of the Burning Hells had mysteriously come to our world. The Three " +"Brothers ravaged the lands of the east for decades, while humanity was left trembling " +"in their wake. Our Order - the Horadrim - was founded by a group of secretive magi to " +"hunt down and capture the Three Evils once and for all.\n \n" +"The original Horadrim captured two of the Three within powerful artifacts known as " +"Soulstones and buried them deep beneath the desolate eastern sands. The third Evil " +"escaped capture and fled to the west with many of the Horadrim in pursuit. The Third " +"Evil - known as Diablo, the Lord of Terror - was eventually captured, his essence set " +"in a Soulstone and buried within this Labyrinth.\n \n" +"Be warned that the soulstone must be kept from discovery by those not of the faith. If " +"Diablo were to be released, he would seek a body that is easily controlled as he would " +"be very weak - perhaps that of an old man or a child. |"; +#endif + +/*-----------------------------------------------------------------------** +** Grimoire of the Burning Hells (Red Books) +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Book21[] = "So it came to be that there was a great revolution within the Burning " +"Hells known as The Dark Exile. The Lesser Evils overthrew the Three Prime Evils and banished " +"their spirit forms to the mortal realm. The demons Belial (the Lord of Lies) and " +"Azmodan (the Lord of Sin) fought to claim rulership of Hell during the absence of " +"the Three Brothers. All of Hell polarized between the factions of Belial and Azmodan " +"while the forces of the High Heavens continually battered upon the very Gates of Hell. |"; + +static char Book22[] = "Many demons traveled to the mortal realm in search of the " +"Three Brothers. These " +"demons were followed to the mortal plane by Angels who hunted them throughout the vast " +"cities of the East. The Angels allied themselves with a secretive Order of mortal magi " +"named the Horadrim, who quickly became adept at hunting demons. They also made many dark " +"enemies in the underworlds. |"; + +static char Book23[] = "So it came to be that the Three Prime Evils were banished in spirit form " +"to the mortal realm and after sewing chaos across the East for decades, they were " +"hunted down by the cursed Order of the mortal Horadrim. The Horadrim used artifacts " +"called Soulstones to contain the essence of Mephisto, the Lord of Hatred and his " +"brother Baal, the Lord of Destruction. The youngest brother - Diablo, the Lord of " +"Terror - escaped to the west.\n \n" +"Eventually the Horadrim captured Diablo within a Soulstone as well, and buried him " +"under an ancient, forgotten Cathedral. There, the Lord of Terror sleeps and awaits the " +"time of his rebirth. Know ye that he will seek a body of youth and power to possess - " +"one that is innocent and easily controlled. He will then arise to free his Brothers " +"and once more fan the flames of the Sin War... |"; +#endif + +/*-----------------------------------------------------------------------** +** The Journals of Lazarus the Betrayer (Normal Book Color) +**-----------------------------------------------------------------------*/ +#if !IS_VERSION(SHAREWARE) +static char Book31[] = "All praises to Diablo - Lord of Terror and Survivor of The Dark Exile. " +"When he awakened from his long slumber, my Lord and Master spoke to me of secrets " +"that few mortals know. He told me the kingdoms of the High Heavens and the pits of " +"the Burning Hells engage in an eternal war. He revealed the powers that have brought " +"this discord to the realms of man. My lord has named the battle for this world and " +"all who exist here the Sin War. |"; + +static char Book32[] = "Glory and Approbation to Diablo - Lord of Terror and Leader of the Three. " +"My Lord spoke to me of his two Brothers, Mephisto and Baal, who were banished to this " +"world long ago. My Lord wishes to bide his time and harness his awesome power so that " +"he may free his captive brothers from their tombs beneath the sands of the east. Once " +"my Lord releases his Brothers, the Sin War will once again know the fury of the Three. |"; + +static char Book33[] = "Hail and Sacrifice to Diablo - Lord of Terror and Destroyer of Souls. " +"When I awoke my Master from his sleep, he attempted to possess a mortal's form. Diablo " +"attempted to claim the body of King Leoric, but my Master was too weak from his " +"imprisonment. My Lord required a simple and innocent anchor to this world, and so " +"found the boy Albrecht to be perfect for the task. While the good King Leoric was " +"left maddened by Diablo's unsuccessful possession, I kidnapped his son Albrecht " +"and brought him before my Master. I now await Diablo's call and pray that I will " +"be rewarded when he at last emerges as the Lord of this world. |"; +#endif + +static char Intro[] = "Thank goodness you've returned!\n" +"Much has changed since you lived here, my friend. " +"All was peaceful until the dark riders came and destroyed " +"our village. Many were cut down where they stood, and those who " +"took up arms were slain or dragged away to become slaves - or worse. " +"The church at the edge of town has been desecrated and is being used " +"for dark rituals. The screams that echo in the night are inhuman, but " +"some of our townsfolk may yet survive. Follow the path that lies " +"between my tavern and the blacksmith shop to find the church and " +"save who you can. \n \n" +"Perhaps I can tell you more if we speak again. Good luck.|"; + +// JKEQUEST Place text here + +static char CryptMap1[] = "Maintain your quest. Finding a treasure that is lost is not " +"easy. Finding a treasure that is hidden less so. I will leave you with this. Do not " +"let the sands of time confuse your search.|"; + +static char CryptMap2[] = "A what?! This is foolishness. There's no treasure buried " +"here in Tristram. Let me see that!! Ah, Look these drawings are inaccurate. They " +"don't match our town at all. I'd keep my mind on what lies below the cathedral and not " +"what lies below our topsoil.|"; + +static char CryptMap3[] = "I really don't have time to discuss some map you are looking " +"for. I have many sick people that require my help and yours as well.|"; + +static char CryptMap4[] = "The once proud Iswall is trapped deep beneath the surface of " +"this world. His honor stripped and his visage altered. He is trapped in immortal " +"torment. Charged to conceal the very thing that could free him.|"; + +static char CryptMap5[] = "I'll bet that Wirt saw you coming and put on an act just so " +"he could laugh at you later when you were running around the town with your nose in the " +"dirt. I'd ignore it.|"; + +static char CryptMap6[] = "There was a time when this town was a frequent stop for " +"travelers from far and wide. Much has changed since then. But hidden caves and buried " +"treasure are common fantasies of any child. Wirt seldom indulges in youthful games. " +"So it may just be his imagination.|"; + +static char CryptMap7[] = "Listen here. Come close. I don't know if you know what I " +"know, but you've have really got something here. That's a map.|"; + +static char CryptMap8[] = "My grandmother often tells me stories about the strange forces " +"that inhabit the graveyard outside of the church. And it may well interest you to hear " +"one of them. She said that if you were to leave the proper offering in the cemetary, " +"enter the cathedral to pray for the dead, and then return, the offering would be altered " +"in some strange way. I don't know if this is just the talk of an old sick woman, but " +"anything seems possible these days.|"; + +static char CryptMap9[] = "Hmmm. A vast and mysterious treasure you say. Mmmm. " +"Maybe I could be interested in picking up a few things from you. Or better yet, don't " +"you need some rare and expensive supplies to get you through this ordeal?|"; + + +static char Cowsuit1[] = "Moo.|"; + +static char Cowsuit2[] = "I said, Moo.|"; + +static char Cowsuit3[] = "Look I'm just a cow, OK?|"; + +static char Cowsuit4[] = "All right, all right. I'm not really a cow. I don't normally go " +"around like this; but, I was sitting at home minding my own business and all of a sudden " +"these bugs & vines & bulbs & stuff started coming out of the floor... it was horrible! " +"If only I had something normal to wear, it wouldn't be so bad. Hey! Could you go back to " +"my place and get my suit for me? The brown one, not the gray one, that's for evening wear. " +"I'd do it myself, but I don't want anyone seeing me like this. Here, take this, you " +"might need it... to kill those things that have overgrown everything. You can't miss my " +"house, it's just south of the fork in the river... you know... the one with the overgrown " +"vegetable garden.|"; + +static char Cowsuit4A[] = "All right, I'll cut the bull. I didn't mean to steer you wrong. " +"I was sitting at home, feeling moo-dy, when things got really un-stable; a whole stampede " +"of monsters came out of the floor! I just cowed. I just happened to be wearing this Jersey " +"when I ran out the door, and now I look udderly ridiculous. If only I had something normal " +"to wear, it wouldn't be so bad. Hey! Can you go back to my place and get my suit for me? " +"The brown one, not the gray one, that's for evening wear. I'd do it myself, but I don't " +"want anyone seeing me like this. Here, take this, you might need it... to kill those things " +"that have overgrown everything. You can't miss my house, it's just south of the fork in " +"the river... you know... the one with the overgrown vegetable garden.|"; + +static char Cowsuit5[] = "What are you wasting time for? Go get my suit! And hurry! That Holstein " +"over there keeps winking at me! |"; + +static char Cowsuit6[] = "Hey, have you got my suit there? Quick, pass it over! These ears " +"itch like you wouldn't believe!|"; + +static char Cowsuit7[] = "No no no no! This is my GRAY suit! It's for evening wear! " +"Formal occasions! I can't wear THIS. What are you, some kind of weirdo? I need the " +"BROWN suit.|"; + +static char Cowsuit8[] = "Ahh, that's MUCH better. Whew! At last, some dignity! Are my " +"antlers on straight? Good. Look, thanks a lot for helping me out. Here, take this as a " +"gift; and, you know... a little fashion tip... you could use a little... you could use a " +"new... yknowwhatImean? The whole adventurer motif is just so... retro. Just a word of " +"advice, eh? Ciao.|"; + +static char Cowsuit9[] = "Look. I'm a cow. And you, you're monster bait. " +"Get some experience under your belt! We'll talk...|"; + +static char Cowsuit10[] = "Me, I'm a self-made cow. Make something of " +"yourself, and... then we'll talk.|"; + +static char Cowsuit11[] = "I don't have to explain myself to every tourist " +"that walks by! Don't you have some monsters to kill? Maybe we'll talk " +"later. If you live...|"; + +static char Cowsuit12[] = "Quit bugging me. I'm looking for someone really " +"heroic. And you're not it. I can't trust you, you're going to get eaten " +"by monsters any day now... I need someone who's an experienced hero.|"; + +static char Cornerstone1[] = "And in the year of the Golden Light, it was so decreed " +"that a great Cathedral be raised. The cornerstone of this holy place was to be " +"carved from the translucent stone Antyrael, named for the Angel who shared his power " +"with the Horadrim. \n \nIn the Year of Drawing Shadows, the ground shook and the Cathedral " +"shattered and fell. As the building of catacombs and castles began and man stood " +"against the ravages of the Sin War, the ruins were scavenged for their stones. And " +"so it was that the cornerstone vanished from the eyes of man. \n \nThe stone was of this " +"world -- and of all worlds -- as the Light is both within all things and beyond all " +"things. Light and unity are the products of this holy foundation, a unity of purpose " +"and a unity of possession.|"; + +/*"And in the year of Golden Light, it was so " +"decreed that a great cathedral should be raised, for the glory of Heaven. " +"And for the cornerstone was brought from the Holy Land a block of " +"translucent stone. And the stone was of this world, and of all worlds, as " +"the spirit of Light is both within and beyond us, in all things. " +"The stone brought all it touched to all the worlds, uniting them in Light. " +"In the Year of the Drawing Shadows, the ground shook, and the cathedral " +"tumbled and shattered. And in the time that followed, of the building of " +"catacombs and castles against the ravages of the Sin War, the ruins were " +"taken for their stones. And so it was that the Cornerstone vanished from " +"the eyes of man, lost, perhaps forever.|";*/ + + +static char Theo1[] = "Waaaah! (sniff) Waaaah! (sniff)|"; + +static char Theo2[] = "I lost Theo! I lost my best friend! We were playing over by the " +"river, and Theo said he wanted to go look at the big green thing. I said we " +"shouldn't, but we snuck over there, and then suddenly this BUG came out! We ran away but " +"Theo fell down and the bug GRABBED him and took him away!|"; + +static char Theo3[] = "Didja find him? You gotta find Theodore, please! " +"He's just little. He can't take care of himself! Please!|"; + +static char Theo4[] = "You found him! You found him! Thank you! Oh Theo, " +"did those nasty bugs scare you? Hey! Ugh! There's something stuck to " +"your fur! Ick! Come on, Theo, let's go home! Thanks again, hero person!|"; + +static char Farmer1[] = "So, you're the hero everyone's been talking " +"about. Perhaps you could help a poor, simple farmer out of a terrible " +"mess? At the edge of my orchard, just south of here, there's a horrible " +"thing swelling out of the ground! I can't get to my crops or my bales " +"of hay, and my poor cows will starve. The witch gave this to me and " +"said that it would blast that thing out of my field. If you could " +"destroy it, I would be forever grateful. I'd do it myself, but someone " +"has to stay here with the cows...|"; + +/*"Here, you're that hero everyone's talking about! " +"You're just the type to help a poor farmer out of a terrible fix! You " +"see, right at the border of my orchard, just south of here, there's a " +"horrible thing swelling out of the ground! I daren't go near me own " +"land! So I got an alchemist to make a magic doo-hickey that'll " +"blast that thing. All you gotta do is take it over and drop it in. " +"I'd do it myself, but my leg's acting up, my lumbago, old war wounds, " +"you know. |";*/ + +static char Farmer2[] = "I knew that it couldn't be as simple as that " +"witch made it sound. It's a sad world when you can't even trust your " +"neighbors.|"; + +/*"You ain't done that measly little thing for me " +"yet? You're young! Never a thought for a poor common peasant... " +"it's a sad world.|";*/ + +static char Farmer2a[] = "It must truly be a fearsome task I've set " +"before you. If there was just some way that I could... would a flagon " +"of some nice, fresh milk help?|"; + +/*"Please, can you get that snarkfarbin' thing outta " +"myfield? It's blockin' the path to me privy!|";*/ + +static char Farmer3[] = "Is it gone? Did you send it back to the dark " +"recesses of Hades that spawned it? You what? Oh, don't tell me you lost " +"it! Those things don't come cheap, you know. You've got to find it, " +"and then blast that horror out of our town.|"; + +/*"You don't have that doo-hickey no more, but I " +"didn't hear any kaboom! Don't tell me you lost it! Those things don't " +"come cheap! You gotta find it, and blast that slimy-lookin' thing outta " +"there!|";*/ + +static char Farmer4[] = "I heard the explosion from here! Many thanks " +"to you, kind stranger. What with all these things comin' out of the " +"ground, monsters taking over the church, and so forth, these are trying " +"times. I am but a poor farmer, but here -- take this with my great " +"thanks.|"; + +/*"You blasted the sucker, eh? Many thanks to you, you're so kind, " +"many thanks. I don't know, things comin' out of the ground, monsters taking over the church, " +"these are hard times... I'm a poor man, I ain't got much, but... take this, take this with my" +" great thanks.|";*/ + +static char Farmer5[] = "Oh, such a trouble I have...maybe...No, I " +"couldn't impose on you, what with all the other troubles. Maybe after " +"you've cleansed the church of some of those creatures you could come " +"back... and spare a little time to help a poor farmer?|"; + +/*"Oh, such a trouble I have... maybe... Nah, you're just a kid, " +"still wet behind the ears! I can't ask you to do this. If only you were a little better " +"prepared.|";*/ + +static char Farmer6[] = "Oh, I could use your help, but perhaps after " +"you've saved the catacombs from the desecration of those beasts.|"; + +/*"Off with you! What I need done would take a real hero... maybe " +"someday you'll qualify.|";*/ + +static char Farmer7[] = "I need something done, but I couldn't impose " +"on a perfect stranger. Perhaps after you've been here a while I might " +"feel more comfortable asking a favor.|"; + +/*"I need something done, but how do I know you won't just skip town " +"on me? Make a name for yourself, kid, and then come find me.|";*/ + +static char Farmer8[] = "I see in you the potential for greatness. " +"Perhaps sometime while you are fulfilling your destiny, you could " +"stop by and do a little favor for me?|"; + +/*"Talk of the town is that you show real promise! Maybe if you live " +"up to the rumors... someday, I might have a little job for you.|";*/ + +static char Farmer9[] = "I think you could probably help me, but perhaps " +"after you've gotten a little more powerful. I wouldn't want to injure " +"the village's only chance to destroy the menace in the church!|"; + +/*"Busy fighting evil, huh? Well, if you live long enough to know " +"what you're doing, look me up, I got a little job you might be interested in.|";*/ + +static char Skulljrnl1[] = "Cloudy and cooler today. Casting the nets of necromancy across " +"the void landed two new subspecies of flying horror; a good day's work. Must remember to " +"order some more bat guano and black candles from Adria; I'm running a bit low.|"; + +static char Skulljrnl2[] = "I have tried spells, threats, abjuration and bargaining with " +"this foul creature -- to no avail. My methods of enslaving lesser demons seem to have no " +"effect on this fearsome beast.|"; + +/*"I have tried spells, threats, abjuration and bargaining with " +"the new creature. My means which have enslaved many lesser demons have no effect on this " +"fearsome beast; it only leers at me in a most unpleasant fashion. |";*/ + +static char Skulljrnl3[] = "My home is slowly becoming corrupted by the vileness of this " +"unwanted prisoner. The crypts are full of shadows that move just beyond the corners of " +"my vision. The faint scrabble of claws dances at the edges of my hearing. They are " +"searching, I think, for this journal.|"; + +/*"The trapped creature's howls of fury keep me from sleep-- it " +"rages and curses the name of the one who sent it to the void, and against myself, for " +"trapping it here. Its words fill my heart with terror, yet I cannot block out its voice.|";*/ + +static char Skulljrnl4[] = "In its ranting, the creature has let slip its name -- " +"Na-Krul. I have attempted to research the name, but the smaller demons have somehow " +"destroyed my library. Na-Krul... The name fills me with a cold dread. I prefer to " +"think of it only as The Creature rather than ponder its true name.|"; + +/*"My home is coming alive, corrupted by the darkness of my " +"unwanted prisoner... The crypts are full of shadows... I see things at the corners of my " +"vision, hear the sounds of claws, and of searching. Searching, I think, for me. For " +"this journal. They must not learn the secret! The creature must not be released!|";*/ + +static char Skulljrnl5[] = "The entrapped creature's howls of fury keep me from gaining " +"much needed sleep. It rages against the one who sent it to the Void, and it " +"calls foul curses upon me for trapping it here. Its words fill my heart with terror, " +"and yet I cannot block out its voice.|"; + +/*"In its ranting, the creature has let slip its name. It calls " +"itself Na-Krul. The name is familiar to me... I wish I could research it, but the smaller " +"horrors have destroyed my library in their endless searching. Still, the syllables fill " +"me with a cold dread... I prefer to think of it only as the creature rather than ponder " +"its true name.|";*/ + +static char Skulljrnl6[] = "My time is quickly running out. I must record the ways to " +"weaken the demon, and then conceal that text, lest his minions find some way to use " +"my knowledge to free their lord. I hope that whoever finds this journal will seek the " +"knowledge.|"; + +/*"Time is running out. With my last entry I must reveal the way " +"to defeat the demon, then conceal that text, lest the demon-creatures find some way to " +"use my knowledge to free their lord. I have kept my athame, at least; when all is lost " +"I would rather meet my death at the end of a dagger, than at the claws of a demon.|";*/ + +static char Skulljrnl7[] = "Whoever finds this scroll is charged with stopping the demonic " +"creature that lies within these walls. My time is over. Even now, its hellish minions " +"claw at the frail door behind which I hide. \n \nI have hobbled the demon with arcane " +"magic and encased it within great walls, but I fear that will not be enough. " +"\n \nThe spells found in my three grimoires will provide you protected entrance to his " +"domain, but only if cast in their proper sequence. The levers at the entryway " +"will remove the barriers and free the demon; touch them not! Use only these spells to " +"gain entry or his power may be too great for you to defeat.|"; + +/*"Whoever finds this, you must stop this demon creature. It is " +"too late for me now; its hellish minions are clawing at this last door behind which I " +"cower. I have hobbled the creature by powerful spells and encased it behind thick walls, " +"yet it will not be enough. You will need the power of the spells in my three grimoires, " +"cast only in their proper sequence. The levers at the entry will remove the barriers and " +"free the demon; touch them not! Use only the spells! The spells in the correct sequence " +"will open the magical doorways, and allow you to face the demon and, I hope, defeat it. " +"May the Heavens have mercy on us all.|";*/ + +static char Defiler1[] = "Ahh, mammal, welcome. Such a... tasty planet you have. My Nest shall spread " +"across this land, and you and your species shall serve as food for our colony. I'm sure " +"our meeting will be quite... delicious. |"; + +static char Defiler2[] = "Have you been enjoying yourself, little mammal? How pathetic. " +"Your little world will be no challenge at all.|"; + +static char Defiler3[] = "Come closer, morsel...come find me, the Defiler. I have waited " +"thousands of years...do not try my patience any further. |"; + +static char Defiler4[] = "Ah, I can smell you...you are close! Close! Ssss...the scent " +"of blood and fear...how enticing...|"; + +static char Defiler6[] = "We have long lain dormant, and the time to " +"awaken has come. After our long sleep, we are filled with great hunger. " +"Soon, now, we shall feed...|"; + +static char Defiler7[] = "These lands shall be defiled, and our brood " +"shall overrun the fields that men call home. Our tendrils shall envelop " +"this world, and we will feast on the flesh of its denizens. Man shall " +"become our chattel and sustenance.|"; + +static char Defiler8[] = "Come closer, morsel! I smell your terror, " +"and I hunger.|"; + +static char Trader1[] = "|"; + +static char Spell1[] = "In Spiritu Sanctum. |"; + +static char Spell2[] = "Praedictum Otium. |"; + +static char Spell3[] = "Efficio Obitus Ut Inimicus. |"; + +#if IS_VERSION(SHAREWARE) +static char szShareware[] = "Nice try... "; +#endif + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// QST() --> quest in retail version ONLY +// sQST() --> quest in retail or shareware version -- most greetings +#if IS_VERSION(SHAREWARE) + // make regular quest text into "fake" text + #define QST(a,b,c,d) { &szShareware[0], FALSE, FALSE, TSFX_TAVERN36 } + #define sQST(a,b,c,d) { a,b,c,d } +#else + #define QST(a,b,c,d) { a,b,c,d } + #define sQST(a,b,c,d) { a,b,c,d } +#endif + +// * NOTE * Quest text scrolling rate 1 = slowest, 5 = normal, 9 = fastest + +const TextDataStruct alltext[] = { + QST( &King1[0], TRUE, 5, TSFX_STORY1 ), // 0 + QST( &King2[0], TRUE, 5, TSFX_TAVERN21 ), // 1 + QST( &King3[0], TRUE, 6, TSFX_TAVERN22 ), // 2 + QST( &King4[0], TRUE, 5, TSFX_TAVERN23 ), // 3 + QST( &King5[0], TRUE, 5, TSFX_HEALER1 ), // 4 + QST( &King6[0], TRUE, 6, TSFX_BMAID1 ), // 5 + QST( &King7[0], TRUE, 5, TSFX_SMITH1 ), // 6 + QST( &King8[0], TRUE, 5, TSFX_DRUNK1 ), // 7 + QST( &King9[0], TRUE, 5, TSFX_WITCH1 ), // 8 + QST( &King10[0], TRUE, 5, TSFX_PEGBOY1 ), // 9 + QST( &King11[0], FALSE, 5, USFX_SKING1 ), // 10 + QST( &Banner1[0], TRUE, 5, TSFX_STORY2 ), // 11 + QST( &Banner2[0], TRUE, 5, TSFX_TAVERN24 ), // 12 + QST( &Banner3[0], TRUE, 5, TSFX_TAVERN25 ), // 13 + QST( &Banner4[0], TRUE, 5, TSFX_HEALER2 ), // 14 + QST( &Banner5[0], TRUE, 6, TSFX_BMAID2 ), // 15 + QST( &Banner6[0], TRUE, 6, TSFX_SMITH2 ), // 16 + QST( &Banner7[0], TRUE, 5, TSFX_DRUNK2 ), // 17 + QST( &Banner8[0], TRUE, 6, TSFX_WITCH2 ), // 18 + QST( &Banner9[0], TRUE, 6, TSFX_PEGBOY2 ), // 19 + QST( &Banner10[0], TRUE, 5, USFX_SNOT1 ), // 20 + QST( &Banner11[0], TRUE, 6, USFX_SNOT2 ), // 21 + QST( &Banner12[0], TRUE, 6, USFX_SNOT3 ), // 22 + QST( &Vile1[0], TRUE, 3, TSFX_STORY36 ), // 23 + QST( &Vile2[0], TRUE, 5, TSFX_STORY37 ), // 24 + QST( &Vile3[0], TRUE, 5, TSFX_STORY38 ), // 25 + QST( &Vile4[0], TRUE, 6, TSFX_TAVERN1 ), // 26 + QST( &Vile5[0], TRUE, 5, TSFX_STORY38 ), // 27 not in + QST( &Vile6[0], TRUE, 5, TSFX_STORY38 ), // 28 not in + QST( &Vile7[0], TRUE, 5, TSFX_HEALER3 ), // 29 + QST( &Vile8[0], TRUE, 5, TSFX_BMAID3 ), // 30 + QST( &Vile9[0], TRUE, 5, TSFX_SMITH3 ), // 31 + QST( &Vile10[0], TRUE, 5, TSFX_DRUNK3 ), // 32 + QST( &Vile11[0], TRUE, 5, TSFX_WITCH3 ), // 33 + QST( &Vile12[0], TRUE, 5, TSFX_PEGBOY3 ), // 34 + QST( &Vile13[0], FALSE, 5, USFX_LAZ1 ), // 35 + QST( &Vile14[0], FALSE, 5, USFX_LAZ1 ), // 36 + QST( &Poison1[0], TRUE, 5, TSFX_STORY4 ), // 37 + QST( &Poison2[0], TRUE, 6, TSFX_TAVERN2 ), // 38 + QST( &Poison3[0], TRUE, 5, TSFX_HEALER20 ), // 39 + QST( &Poison4[0], TRUE, 6, TSFX_HEALER21 ), // 40 + QST( &Poison5[0], TRUE, 5, TSFX_HEALER22 ), // 41 + QST( &Poison6[0], TRUE, 6, TSFX_BMAID4 ), // 42 + QST( &Poison7[0], TRUE, 5, TSFX_SMITH4 ), // 43 + QST( &Poison8[0], TRUE, 8, TSFX_DRUNK4 ), // 44 + QST( &Poison9[0], TRUE, 6, TSFX_WITCH4 ), // 45 + QST( &Poison10[0], TRUE, 6, TSFX_PEGBOY4 ), // 46 + QST( &Bone1[0], TRUE, 4, TSFX_STORY7 ), // 47 + QST( &Bone2[0], TRUE, 6, TSFX_TAVERN5 ), // 48 + QST( &Bone3[0], TRUE, 6, TSFX_HEALER5 ), // 49 + QST( &Bone4[0], TRUE, 6, TSFX_BMAID6 ), // 50 + QST( &Bone5[0], TRUE, 6, TSFX_SMITH7 ), // 51 + QST( &Bone6[0], TRUE, 5, TSFX_DRUNK7 ), // 52 + QST( &Bone7[0], TRUE, 6, TSFX_WITCH7 ), // 53 + QST( &Bone8[0], TRUE, 5, TSFX_PEGBOY7 ), // 54 + QST( &Butch1[0], TRUE, 5, TSFX_STORY10 ), // 55 + QST( &Butch2[0], TRUE, 6, TSFX_TAVERN8 ), // 56 + QST( &Butch3[0], TRUE, 5, TSFX_HEALER8 ), // 57 + QST( &Butch4[0], TRUE, 6, TSFX_BMAID8 ), // 58 + QST( &Butch5[0], TRUE, 5, TSFX_SMITH10 ), // 59 + QST( &Butch6[0], TRUE, 5, TSFX_DRUNK10 ), // 60 + QST( &Butch7[0], TRUE, 5, TSFX_WITCH10 ), // 61 + QST( &Butch8[0], TRUE, 6, TSFX_PEGBOY10 ), // 62 + QST( &Butch9[0], TRUE, 5, TSFX_WOUND ), // 63 + QST( &Butch10[0], TRUE, 5, USFX_CLEAVER ), // 64 + QST( &Blind1[0], TRUE, 5, TSFX_STORY12 ), // 65 + QST( &Blind2[0], TRUE, 6, TSFX_TAVERN10 ), // 66 + QST( &Blind3[0], TRUE, 5, TSFX_HEALER10 ), // 67 + QST( &Blind4[0], TRUE, 6, TSFX_BMAID10 ), // 68 + QST( &Blind5[0], TRUE, 6, TSFX_SMITH12 ), // 69 + QST( &Blind6[0], TRUE, 6, TSFX_DRUNK12 ), // 70 + QST( &Blind7[0], TRUE, 6, TSFX_WITCH12 ), // 71 + QST( &Blind8[0], TRUE, 5, TSFX_PEGBOY11 ), // 72 + QST( &Veil1[0], TRUE, 5, TSFX_STORY13 ), // 73 + QST( &Veil2[0], TRUE, 6, TSFX_TAVERN11 ), // 74 + QST( &Veil3[0], TRUE, 5, TSFX_HEALER11 ), // 75 + QST( &Veil4[0], TRUE, 7, TSFX_BMAID11 ), // 76 + QST( &Veil5[0], TRUE, 5, TSFX_SMITH13 ), // 77 + QST( &Veil6[0], TRUE, 5, TSFX_DRUNK13 ), // 78 + QST( &Veil7[0], TRUE, 6, TSFX_WITCH13 ), // 79 + QST( &Veil8[0], TRUE, 5, TSFX_PEGBOY12 ), // 80 + QST( &Veil9[0], TRUE, 3, USFX_LACH1 ), // 81 + QST( &Veil10[0], TRUE, 6, USFX_LACH2 ), // 82 + QST( &Veil11[0], TRUE, 4, USFX_LACH3 ), // 83 + QST( &Anvil1[0], TRUE, 4, TSFX_STORY14 ), // 84 + QST( &Anvil2[0], TRUE, 7, TSFX_TAVERN12 ), // 85 + QST( &Anvil3[0], TRUE, 6, TSFX_HEALER12 ), // 86 + QST( &Anvil4[0], TRUE, 5, TSFX_BMAID12 ), // 87 + QST( &Anvil5[0], TRUE, 5, TSFX_SMITH21 ), // 88 + QST( &Anvil6[0], TRUE, 5, TSFX_SMITH22 ), // 89 + QST( &Anvil7[0], TRUE, 5, TSFX_SMITH23 ), // 90 + QST( &Anvil8[0], TRUE, 6, TSFX_DRUNK14 ), // 91 + QST( &Anvil9[0], TRUE, 5, TSFX_WITCH14 ), // 92 + QST( &Anvil10[0], TRUE, 6, TSFX_PEGBOY13 ), // 93 + QST( &Blood1[0], TRUE, 3, TSFX_STORY15 ), // 94 + QST( &Blood2[0], TRUE, 6, TSFX_TAVERN13 ), // 95 + QST( &Blood3[0], TRUE, 6, TSFX_HEALER13 ), // 96 + QST( &Blood4[0], TRUE, 6, TSFX_BMAID13 ), // 97 + QST( &Blood5[0], TRUE, 5, TSFX_SMITH14 ), // 98 + QST( &Blood6[0], TRUE, 7, TSFX_DRUNK15 ), // 99 + QST( &Blood7[0], TRUE, 6, TSFX_WITCH15 ), // 100 + QST( &Blood8[0], TRUE, 6, TSFX_PEGBOY14 ), // 101 + QST( &Warlrd1[0], TRUE, 5, TSFX_STORY18 ), // 102 + QST( &Warlrd2[0], TRUE, 6, TSFX_TAVERN16 ), // 103 + QST( &Warlrd3[0], TRUE, 7, TSFX_HEALER16 ), // 104 + QST( &Warlrd4[0], TRUE, 6, TSFX_BMAID16 ), // 105 + QST( &Warlrd5[0], TRUE, 6, TSFX_SMITH17 ), // 106 + QST( &Warlrd6[0], TRUE, 5, TSFX_DRUNK17 ), // 107 + QST( &Warlrd7[0], TRUE, 5, TSFX_WITCH18 ), // 108 + QST( &Warlrd8[0], TRUE, 6, TSFX_PEGBOY17 ), // 109 + QST( &Warlrd9[0], FALSE, 6, USFX_WARLRD1 ), // 110 + QST( &Infra1[0], TRUE, 5, TSFX_STORY20 ), // 111 + QST( &Infra2[0], TRUE, 6, TSFX_TAVERN18 ), // 112 + QST( &Infra3[0], TRUE, 6, TSFX_HEALER18 ), // 113 + QST( &Infra4[0], TRUE, 6, TSFX_BMAID18 ), // 114 + QST( &Infra5[0], TRUE, 5, TSFX_SMITH24 ), // 115 + QST( &Infra6[0], TRUE, 6, TSFX_SMITH25 ), // 116 + QST( &Infra7[0], TRUE, 5, TSFX_SMITH26 ), // 117 + QST( &Infra8[0], TRUE, 5, TSFX_DRUNK19 ), // 118 + QST( &Infra9[0], TRUE, 5, TSFX_WITCH20 ), // 119 + QST( &Infra10[0], TRUE, 6, TSFX_PEGBOY18 ), // 120 + QST( &Mush1[0], TRUE, 5, TSFX_STORY21 ), // 121 + QST( &Mush2[0], TRUE, 5, TSFX_TAVERN19 ), // 122 + QST( &Mush3[0], TRUE, 5, TSFX_HEALER26 ), // 123 + QST( &Mush4[0], TRUE, 5, TSFX_HEALER27 ), // 124 + QST( &Mush5[0], TRUE, 7, TSFX_BMAID19 ), // 125 + QST( &Mush6[0], TRUE, 5, TSFX_SMITH19 ), // 126 + QST( &Mush7[0], TRUE, 5, TSFX_DRUNK20 ), // 127 + QST( &Mush8[0], TRUE, 5, TSFX_WITCH22 ), // 128 + QST( &Mush9[0], TRUE, 6, TSFX_WITCH23 ), // 129 + QST( &Mush10[0], TRUE, 5, TSFX_WITCH24 ), // 130 + QST( &Mush11[0], TRUE, 5, TSFX_WITCH25 ), // 131 + QST( &Mush12[0], TRUE, 6, TSFX_WITCH26 ), // 132 + QST( &Mush13[0], TRUE, 6, TSFX_PEGBOY19 ), // 133 + QST( &Doom1[0], TRUE, 2, TSFX_STORY22 ), // 134 + QST( &Doom2[0], TRUE, 6, TSFX_STORY23 ), // 135 + QST( &Doom3[0], TRUE, 5, TSFX_STORY24 ), // 136 + QST( &Doom4[0], TRUE, 6, TSFX_TAVERN20 ), // 137 + QST( &Doom5[0], TRUE, 6, TSFX_HEALER19 ), // 138 + QST( &Doom6[0], TRUE, 6, TSFX_BMAID20 ), // 139 + QST( &Doom7[0], TRUE, 6, TSFX_SMITH20 ), // 140 + QST( &Doom8[0], TRUE, 5, TSFX_DRUNK21 ), // 141 + QST( &Doom9[0], TRUE, 5, TSFX_WITCH21 ), // 142 + QST( &Doom10[0], TRUE, 5, TSFX_PEGBOY20 ), // 143 + QST( &Garbud1[0], TRUE, 6, USFX_GARBUD1 ), // 144 + QST( &Garbud2[0], TRUE, 6, USFX_GARBUD2 ), // 145 + QST( &Garbud3[0], TRUE, 6, USFX_GARBUD3 ), // 146 + QST( &Garbud4[0], TRUE, 6, USFX_GARBUD4 ), // 147 + QST( &Zhar1[0], TRUE, 6, USFX_ZHAR1 ), // 148 + QST( &Zhar2[0], TRUE, 7, USFX_ZHAR2 ), // 149 + sQST( &Story1[0], FALSE, 5, TSFX_STORY25 ), // 150 + QST( &Story2[0], TRUE, 6, TSFX_STORY26 ), // 151 + QST( &Story3[0], TRUE, 5, TSFX_STORY27 ), // 152 + QST( &Story4[0], TRUE, 5, TSFX_STORY28 ), // 153 + QST( &Story5[0], TRUE, 5, TSFX_STORY29 ), // 154 + QST( &Story6[0], TRUE, 5, TSFX_STORY30 ), // 155 + QST( &Story7[0], TRUE, 5, TSFX_STORY31 ), // 156 + QST( &Story9[0], TRUE, 5, TSFX_STORY33 ), // 157 + QST( &Story10[0], TRUE, 5, TSFX_STORY34 ), // 158 + QST( &Story11[0], TRUE, 5, TSFX_STORY35 ), // 159 + sQST( &Ogden1[0], FALSE, 5, TSFX_TAVERN36 ), // 160 + QST( &Ogden2[0], TRUE, 5, TSFX_TAVERN37 ), // 161 + QST( &Ogden3[0], TRUE, 6, TSFX_TAVERN38 ), // 162 + QST( &Ogden4[0], TRUE, 6, TSFX_TAVERN39 ), // 163 + QST( &Ogden5[0], TRUE, 6, TSFX_TAVERN40 ), // 164 + QST( &Ogden6[0], TRUE, 6, TSFX_TAVERN41 ), // 165 + QST( &Ogden8[0], TRUE, 6, TSFX_TAVERN43 ), // 166 + QST( &Ogden9[0], TRUE, 6, TSFX_TAVERN44 ), // 167 + QST( &Ogden10[0], TRUE, 6, TSFX_TAVERN45 ), // 168 + sQST( &Pepin1[0], FALSE, 5, TSFX_HEALER37 ), // 169 + QST( &Pepin2[0], TRUE, 5, TSFX_HEALER38 ), // 170 + QST( &Pepin3[0], TRUE, 5, TSFX_HEALER39 ), // 171 + QST( &Pepin4[0], TRUE, 5, TSFX_HEALER40 ), // 172 + QST( &Pepin5[0], TRUE, 5, TSFX_HEALER41 ), // 173 + QST( &Pepin6[0], TRUE, 5, TSFX_HEALER42 ), // 174 + QST( &Pepin7[0], TRUE, 5, TSFX_HEALER43 ), // 175 + QST( &Pepin9[0], TRUE, 5, TSFX_HEALER45 ), // 176 + QST( &Pepin10[0], TRUE, 5, TSFX_HEALER46 ), // 177 + QST( &Pepin11[0], TRUE, 6, TSFX_HEALER47 ), // 178 + sQST( &Gillian1[0], FALSE, 5, TSFX_BMAID31 ), // 179 + QST( &Gillian2[0], TRUE, 6, TSFX_BMAID32 ), // 180 + QST( &Gillian3[0], TRUE, 6, TSFX_BMAID33 ), // 181 + QST( &Gillian4[0], TRUE, 5, TSFX_BMAID34 ), // 182 + QST( &Gillian5[0], TRUE, 6, TSFX_BMAID35 ), // 183 + QST( &Gillian6[0], TRUE, 6, TSFX_BMAID36 ), // 184 + QST( &Gillian7[0], TRUE, 5, TSFX_BMAID37 ), // 185 + QST( &Gillian9[0], TRUE, 5, TSFX_BMAID39 ), // 186 + QST( &Gillian10[0], TRUE, 5, TSFX_BMAID40 ), // 187 + sQST( &Griswold1[0], FALSE, 5, TSFX_SMITH44 ), // 188 + QST( &Griswold2[0], TRUE, 5, TSFX_SMITH45 ), // 189 + QST( &Griswold3[0], TRUE, 5, TSFX_SMITH46 ), // 190 + QST( &Griswold4[0], TRUE, 5, TSFX_SMITH47 ), // 191 + QST( &Griswold5[0], TRUE, 6, TSFX_SMITH48 ), // 192 + QST( &Griswold6[0], TRUE, 5, TSFX_SMITH49 ), // 193 + QST( &Griswold7[0], TRUE, 6, TSFX_SMITH50 ), // 194 + QST( &Griswold8[0], TRUE, 5, TSFX_SMITH51 ), // 195 + QST( &Griswold9[0], TRUE, 5, TSFX_SMITH52 ), // 196 + QST( &Griswold10[0], TRUE, 6, TSFX_SMITH53 ), // 197 + QST( &Griswold12[0], TRUE, 5, TSFX_SMITH55 ), // 198 + QST( &Griswold13[0], TRUE, 5, TSFX_SMITH56 ), // 199 + sQST( &Farnham1[0], FALSE, 5, TSFX_DRUNK27 ), // 200 + QST( &Farnham2[0], TRUE, 6, TSFX_DRUNK28 ), // 201 + QST( &Farnham3[0], TRUE, 5, TSFX_DRUNK29 ), // 202 + QST( &Farnham4[0], TRUE, 5, TSFX_DRUNK30 ), // 203 + QST( &Farnham5[0], TRUE, 5, TSFX_DRUNK31 ), // 204 + QST( &Farnham6[0], TRUE, 5, TSFX_DRUNK32 ), // 205 + QST( &Farnham8[0], TRUE, 5, TSFX_DRUNK34 ), // 206 + QST( &Farnham9[0], TRUE, 5, TSFX_DRUNK35 ), // 207 + QST( &Farnham10[0], TRUE, 5, TSFX_DRUNK23 ), // 208 + QST( &Farnham11[0], TRUE, 5, TSFX_DRUNK24 ), // 209 + QST( &Farnham12[0], TRUE, 5, TSFX_DRUNK25 ), // 210 + QST( &Farnham13[0], TRUE, 5, TSFX_DRUNK26 ), // 211 + sQST( &Adria1[0], FALSE, 5, TSFX_WITCH38 ), // 212 + QST( &Adria2[0], TRUE, 5, TSFX_WITCH39 ), // 213 + QST( &Adria3[0], TRUE, 5, TSFX_WITCH40 ), // 214 + QST( &Adria4[0], TRUE, 5, TSFX_WITCH41 ), // 215 + QST( &Adria5[0], TRUE, 5, TSFX_WITCH42 ), // 216 + QST( &Adria6[0], TRUE, 5, TSFX_WITCH43 ), // 217 + QST( &Adria7[0], TRUE, 5, TSFX_WITCH44 ), // 218 + QST( &Adria8[0], TRUE, 5, TSFX_WITCH45 ), // 219 + QST( &Adria9[0], TRUE, 5, TSFX_WITCH46 ), // 220 + QST( &Adria10[0], TRUE, 5, TSFX_WITCH47 ), // 221 + QST( &Adria12[0], TRUE, 4, TSFX_WITCH49 ), // 222 + QST( &Adria13[0], TRUE, 4, TSFX_WITCH50 ), // 223 + sQST( &Wirt1[0], FALSE, 5, TSFX_PEGBOY32 ), // 224 + QST( &Wirt2[0], TRUE, 6, TSFX_PEGBOY33 ), // 225 + QST( &Wirt3[0], TRUE, 6, TSFX_PEGBOY34 ), // 226 + QST( &Wirt4[0], TRUE, 5, TSFX_PEGBOY35 ), // 227 + QST( &Wirt5[0], TRUE, 5, TSFX_PEGBOY36 ), // 228 + QST( &Wirt6[0], TRUE, 5, TSFX_PEGBOY37 ), // 229 + QST( &Wirt7[0], TRUE, 5, TSFX_PEGBOY38 ), // 230 + QST( &Wirt8[0], TRUE, 5, TSFX_PEGBOY39 ), // 231 + QST( &Wirt9[0], TRUE, 6, TSFX_PEGBOY40 ), // 232 + QST( &Wirt11[0], TRUE, 5, TSFX_PEGBOY42 ), // 233 + QST( &Wirt12[0], TRUE, 5, TSFX_PEGBOY43 ), // 234 + QST( &Boner[0], TRUE, 5, PS_WARR1 ), // 235 + QST( &Bloody[0], TRUE, 6, PS_WARR10 ), // 236 + QST( &Blinding[0], TRUE, 5, PS_WARR11 ), // 237 + QST( &Bloodwar[0], TRUE, 5, PS_WARR12 ), // 238 + QST( &Boner[0], TRUE, 5, PS_MAGE1 ), // 239 + QST( &Bloody[0], TRUE, 6, PS_MAGE10 ), // 240 + QST( &Blinding[0], TRUE, 4, PS_MAGE11 ), // 241 + QST( &Bloodwar[0], TRUE, 5, PS_MAGE12 ), // 242 + QST( &Boner[0], TRUE, 5, PS_ROGUE1 ), // 243 + QST( &Bloody[0], TRUE, 5, PS_ROGUE10 ), // 244 + QST( &Blinding[0], TRUE, 5, PS_ROGUE11 ), // 245 + QST( &Bloodwar[0], TRUE, 5, PS_ROGUE12 ), // 246 + sQST( &Cow1[0], FALSE, 5, TSFX_COW1 ), // 247 + sQST( &Cow1[0], FALSE, 5, TSFX_COW2 ), // 248 + QST( &Book11[0], TRUE, 5, PS_NAR1 ), // 249 + QST( &Book12[0], TRUE, 4, PS_NAR2 ), // 250 + QST( &Book13[0], TRUE, 3, PS_NAR3 ), // 251 + QST( &Book21[0], TRUE, 4, PS_NAR4 ), // 252 + QST( &Book22[0], TRUE, 5, PS_NAR5 ), // 253 + QST( &Book23[0], TRUE, 3, PS_NAR6 ), // 254 + QST( &Book31[0], TRUE, 4, PS_NAR7 ), // 255 + QST( &Book32[0], TRUE, 4, PS_NAR8 ), // 256 + QST( &Book33[0], TRUE, 3, PS_NAR9 ), // 257 + sQST( &Intro[0], TRUE, 5, TSFX_TAVERN0 ), // 258 + QST( &Boner[0], TRUE, 5, PS_MONK1 ), // 259 + QST( &Bloody[0], TRUE, 5, PS_MONK10 ), // 260 + QST( &Blinding[0], TRUE, 5, PS_MONK11 ), // 261 + QST( &Bloodwar[0], TRUE, 5, PS_MONK12 ), // 262 + QST( &Boner[0], TRUE, 5, PS_BARD1 ), // 263 + QST( &Bloody[0], TRUE, 5, PS_BARD10 ), // 264 + QST( &Blinding[0], TRUE, 5, PS_BARD11 ), // 265 + +// Link Text and Sound here JKEQUEST + QST( &Bloodwar[0], TRUE, 5, PS_BARD12 ), // 266 + QST( &CryptMap1[0], TRUE, 5, TSFX_WITCH19 ), // 267 + QST( &CryptMap2[0], TRUE, 5, TSFX_SMITH18 ), // 268 + QST( &CryptMap3[0], TRUE, 5, TSFX_HEALER17 ), // 269 + QST( &CryptMap4[0], TRUE, 5, TSFX_WITCH9 ), // 270 + QST( &CryptMap5[0], TRUE, 5, TSFX_TAVERN17 ), // 271 + QST( &CryptMap6[0], TRUE, 5, TSFX_STORY19 ), // 272 + QST( &CryptMap7[0], TRUE, 5, TSFX_DRUNK21 ), // 273 + QST( &CryptMap8[0], TRUE, 5, TSFX_BMAID27 ), // 274 + QST( &CryptMap9[0], TRUE, 5, TSFX_PEGBOY7 ), // 275 + QST( &CryptMap4[0], TRUE, 5, TSFX_WITCH9 ), // 276 + + QST( &Farmer1[0], TRUE, 3, HSFX_FARMER1 ), // 277 + QST( &Farmer2[0], TRUE, 5, HSFX_FARMER2 ), // 278 + QST( &Farmer3[0], TRUE, 5, HSFX_FARMER3 ), // 279 + QST( &Farmer4[0], TRUE, 5, HSFX_FARMER4 ), // 280 + QST( &Farmer5[0], TRUE, 5, HSFX_FARMER5 ), // 281 + + QST( &Theo1[0], TRUE, 5, HSFX_THEO1 ), // 282 + QST( &Theo2[0], TRUE, 5, HSFX_THEO2 ), // 283 + QST( &Theo3[0], TRUE, 5, HSFX_THEO3 ), // 284 + QST( &Theo4[0], TRUE, 5, HSFX_THEO4 ), // 285 + + QST( &Defiler6[0], TRUE, 5, HSFX_DEFILER6 ), // 286 + QST( &Defiler2[0], TRUE, 5, HSFX_DEFILER2 ), // 287 + QST( &Defiler7[0], TRUE, 5, HSFX_DEFILER7 ), // 288 + QST( &Defiler4[0], TRUE, 5, HSFX_DEFILER4 ), // 289 + QST( &Cow1[0], TRUE, 5, HSFX_DEFILER5 ), // 290 + + QST( &Cow1[0], TRUE, 5, HSFX_NA_KRUL1 ), // 291 + QST( &Cow1[0], TRUE, 5, HSFX_NA_KRUL2 ), // 292 + QST( &Cow1[0], TRUE, 5, HSFX_NA_KRUL3 ), // 293 + QST( &Cow1[0], TRUE, 5, HSFX_NA_KRUL4 ), // 294 + QST( &Cow1[0], TRUE, 5, HSFX_NA_KRUL5 ), // 295 + + QST( &Cornerstone1[0], TRUE, 2, HSFX_CORNERSTONE1), // 296 + + QST( &Cowsuit1[0], TRUE, 5, HSFX_COWSUIT1 ), // 297 + QST( &Cowsuit2[0], TRUE, 5, HSFX_COWSUIT2 ), // 298 + QST( &Cowsuit3[0], TRUE, 5, HSFX_COWSUIT3 ), // 299 + QST( &Cowsuit4[0], TRUE, 5, HSFX_COWSUIT4 ), // 300 + QST( &Cowsuit5[0], TRUE, 5, HSFX_COWSUIT5 ), // 301 + QST( &Cowsuit6[0], TRUE, 5, HSFX_COWSUIT6 ), // 302 + QST( &Cowsuit7[0], TRUE, 5, HSFX_COWSUIT7 ), // 303 + QST( &Cowsuit8[0], TRUE, 5, HSFX_COWSUIT8 ), // 304 + QST( &Cowsuit9[0], TRUE, 5, HSFX_COWSUIT9 ), // 305 + + QST( &Trader1[0], TRUE, 5, HSFX_TRADER1 ), // 306 + + QST( &Farmer2a[0], TRUE, 5, HSFX_FARMER2A ), // 307 + QST( &Farmer6[0], TRUE, 5, HSFX_FARMER6 ), // 308 + QST( &Farmer7[0], TRUE, 5, HSFX_FARMER7 ), // 309 + QST( &Farmer8[0], TRUE, 5, HSFX_FARMER8 ), // 310 + QST( &Farmer9[0], TRUE, 5, HSFX_FARMER9 ), // 311 + + QST( &Cowsuit10[0], TRUE, 5, HSFX_COWSUIT10 ), // 312 + QST( &Cowsuit11[0], TRUE, 5, HSFX_COWSUIT11 ), // 313 + QST( &Cowsuit12[0], TRUE, 5, HSFX_COWSUIT12 ), // 314 + QST( &Cowsuit4A[0], TRUE, 5, HSFX_COWSUIT4A ), // 315 + + QST( &Skulljrnl1[0], TRUE, 5, HSFX_SKULLJRNL1 ), // 316 + QST( &Skulljrnl2[0], TRUE, 5, HSFX_SKULLJRNL2 ), // 317 + QST( &Skulljrnl3[0], TRUE, 5, HSFX_SKULLJRNL3 ), // 318 + QST( &Skulljrnl4[0], TRUE, 5, HSFX_SKULLJRNL4 ), // 319 + QST( &Skulljrnl5[0], TRUE, 5, HSFX_SKULLJRNL5 ), // 320 + QST( &Skulljrnl6[0], TRUE, 5, HSFX_SKULLJRNL6 ), // 321 + QST( &Skulljrnl7[0], TRUE, 2, HSFX_SKULLJRNL7 ), // 322 + + QST( &Spell1[0], TRUE, 5, PS_WARR54 ), // 323 + QST( &Spell2[0], TRUE, 5, PS_WARR55 ), // 324 + QST( &Spell3[0], TRUE, 5, PS_WARR56 ), // 325 + + QST( &Spell1[0], TRUE, 5, PS_MONK54 ), // 323 + QST( &Spell2[0], TRUE, 5, PS_MONK55 ), // 324 + QST( &Spell3[0], TRUE, 5, PS_MONK56 ), // 325 + + QST( &Spell1[0], TRUE, 5, PS_MAGE54 ), // 323 + QST( &Spell2[0], TRUE, 5, PS_MAGE55 ), // 324 + QST( &Spell3[0], TRUE, 5, PS_MAGE56 ), // 325 + + QST( &Spell1[0], TRUE, 5, PS_ROGUE54 ), // 323 + QST( &Spell2[0], TRUE, 5, PS_ROGUE55 ), // 324 + QST( &Spell3[0], TRUE, 5, PS_ROGUE56 ), // 325 + + QST( &Spell1[0], TRUE, 5, PS_BARD54 ), // 323 + QST( &Spell2[0], TRUE, 5, PS_BARD55 ), // 324 + QST( &Spell3[0], TRUE, 5, PS_BARD56 ), // 325 + +}; + +const DWORD gdwAllTextEntries = sizeof(alltext) / sizeof(alltext[0]); diff --git a/TEXTDAT.H b/TEXTDAT.H new file mode 100644 index 0000000..21ad435 --- /dev/null +++ b/TEXTDAT.H @@ -0,0 +1,536 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ +// STORYTELLER ST +// TAVERN OWNER TO +// PRIEST P +// HEALER H +// BARMAID BM +// BLACKSMITH BS +// TOWN DRUNK TD +// WITCH W +// PEG-LEGGED BOY PB +/*-----------------------------------------------------------------------** +// QUESTS +**-----------------------------------------------------------------------*/ +// Skeleton King Quest +#define TXT_KINGST1 0 // ST +#define TXT_KINGTO1 1 // TO quest init +#define TXT_KINGTO2 2 // TO return before end +#define TXT_KINGTO3 3 // TO return upon completion +// P +#define TXT_KINGH1 4 // H +#define TXT_KINGBM1 5 // BM +#define TXT_KINGBS1 6 // BS +#define TXT_KINGTD1 7 // TD +#define TXT_KINGW1 8 // W +#define TXT_KINGPB1 9 // PB + +#define TXT_KING1 10 // Skeleton King + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Banner of Light Quest +#define TXT_BOLST1 11 // ST +#define TXT_BOLTO1 12 // TO quest init +#define TXT_BOLTO2 13 // TO return sign +// P +#define TXT_BOLH1 14 // H +#define TXT_BOLBM1 15 // BM +#define TXT_BOLBS1 16 // BS +#define TXT_BOLTD1 17 // TD +#define TXT_BOLW1 18 // W +#define TXT_BOLPB1 19 // PB + +#define TXT_BOL1 20 // Snotspil first time +#define TXT_BOL2 21 // Snotspil empty handed +#define TXT_BOL3 22 // Snotspil with sign + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Vile Betrayer Quest +#define TXT_VBST1 23 // ST quest not done +#define TXT_VBST2 24 // ST quest init +#define TXT_VBST3 25 // ST quest done +#define TXT_VBTO1 26 // TO +#define TXT_VBP3 27 // not in +#define TXT_VBP4 28 // not in +#define TXT_VBH1 29 // H +#define TXT_VBBM1 30 // BM +#define TXT_VBBS1 31 // BS +#define TXT_VBTD1 32 // TD +#define TXT_VBW1 33 // W +#define TXT_VBPB1 34 // PB + +#define TXT_VB1 35 // Lazurus before sacrafice +#define TXT_VB2 36 // Lazurus after sacrafice + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Poisoned Water Quest +#define TXT_PWST1 37 // ST +#define TXT_PWTO1 38 // TO +// P +#define TXT_PWH1 39 // H quest init +#define TXT_PWH2 40 // H return before done +#define TXT_PWH3 41 // H quest done +#define TXT_PWBM1 42 // BM +#define TXT_PWBS1 43 // BS +#define TXT_PWTD1 44 // TD +#define TXT_PWW1 45 // W +#define TXT_PWPB1 46 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// The Chamber of Bone Quest +#define TXT_BONEST1 47 // ST +#define TXT_BONETO1 48 // TO +// P +#define TXT_BONEH1 49 // H +#define TXT_BONEBM1 50 // BM +#define TXT_BONEBS1 51 // BS +#define TXT_BONETD1 52 // TD +#define TXT_BONEW1 53 // W +#define TXT_BONEPB1 54 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// The Butcher Quest +#define TXT_BUTCHST1 55 // ST +#define TXT_BUTCHTO1 56 // TO +// P +#define TXT_BUTCHH1 57 // H +#define TXT_BUTCHBM1 58 // BM +#define TXT_BUTCHBS1 59 // BS +#define TXT_BUTCHTD1 60 // TD +#define TXT_BUTCHW1 61 // W +#define TXT_BUTCHPB1 62 // PB + +#define TXT_BUTCH1 63 // Wounded Townsman +#define TXT_BUTCH2 64 // Butcher + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Halls of the Blind Quest +#define TXT_BLINDST1 65 // ST +#define TXT_BLINDTO1 66 // TO +// P +#define TXT_BLINDH1 67 // H +#define TXT_BLINDBM1 68 // BM +#define TXT_BLINDBS1 69 // BS +#define TXT_BLINDTD1 70 // TD +#define TXT_BLINDW1 71 // W +#define TXT_BLINDPB1 72 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Veil of Steel Quest +#define TXT_VEILST1 73 // ST +#define TXT_VEILTO1 74 // TO +// P +#define TXT_VEILH1 75 // H +#define TXT_VEILBM1 76 // BM +#define TXT_VEILBS1 77 // BS +#define TXT_VEILTD1 78 // TD +#define TXT_VEILW1 79 // W +#define TXT_VEILPB1 80 // PB + +#define TXT_VEIL1 81 // Lachdanan first time +#define TXT_VEIL2 82 // Lachdanan without elixir +#define TXT_VEIL3 83 // Lachdanan with elixir + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// The Anvil of Fury Quest +#define TXT_ANVILST1 84 // ST +#define TXT_ANVILTO1 85 // TO +// P +#define TXT_ANVILH1 86 // H +#define TXT_ANVILBM1 87 // BM +#define TXT_ANVILBS1 88 // BS +#define TXT_ANVILBS2 89 // BS +#define TXT_ANVILBS3 90 // BS +#define TXT_ANVILTD1 91 // TD +#define TXT_ANVILW1 92 // W +#define TXT_ANVILPB1 93 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Stones of Blood Quest +#define TXT_BLOODST1 94 // ST +#define TXT_BLOODTO1 95 // TO +// P +#define TXT_BLOODH1 96 // H +#define TXT_BLOODBM1 97 // BM +#define TXT_BLOODBS1 98 // BS +#define TXT_BLOODTD1 99 // TD +#define TXT_BLOODW1 100 // W +#define TXT_BLOODPB1 101 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Warlord of Blood Quest +#define TXT_WARLRDST1 102 // ST +#define TXT_WARLRDTO1 103 // TO +// P +#define TXT_WARLRDH1 104 // H +#define TXT_WARLRDBM1 105 // BM +#define TXT_WARLRDBS1 106 // BS +#define TXT_WARLRDTD1 107 // TD +#define TXT_WARLRDW1 108 // W +#define TXT_WARLRDPB1 109 // PB + +#define TXT_WARLRD1 110 // Warlord of the Blood + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Ring of Infravision Quest +#define TXT_INFRAST1 111 // ST +#define TXT_INFRATO1 112 // TO +// P +#define TXT_INFRAH1 113 // H +#define TXT_INFRABM1 114 // BM +#define TXT_INFRABS1 115 // BS +#define TXT_INFRABS2 116 // BS +#define TXT_INFRABS3 117 // BS +#define TXT_INFRATD1 118 // TD +#define TXT_INFRAW1 119 // W +#define TXT_INFRAPB1 120 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Black Mushroom Quest +#define TXT_BLKMST1 121 // ST +#define TXT_BLKMTO1 122 // TO +// P +#define TXT_BLKMH1 123 // H no brain +#define TXT_BLKMH2 124 // H with brain +#define TXT_BLKMBM1 125 // BM +#define TXT_BLKMBS1 126 // BS +#define TXT_BLKMTD1 127 // TD +#define TXT_BLKMW1 128 // W +#define TXT_BLKMW2 129 // W +#define TXT_BLKMW3 130 // W +#define TXT_BLKMW4 131 // W +#define TXT_BLKMW5 132 // W +#define TXT_BLKMPB1 133 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Map of Doom Quest +#define TXT_MODST1 134 // ST quest init +#define TXT_MODST2 135 // ST return before stars align and Diablo alive +#define TXT_MODST3 136 // ST return after stars align and Diablo alive +#define TXT_MODTO1 137 // TO +// P +#define TXT_MODH1 138 // H +#define TXT_MODBM1 139 // BM +#define TXT_MODBS1 140 // BS +#define TXT_MODTD1 141 // TD +#define TXT_MODW1 142 // W +#define TXT_MODPB1 143 // PB + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Garbud the Weak Quest + +#define TXT_GARB1 144 // Garbud first time +#define TXT_GARB2 145 // Garbud 2nd time +#define TXT_GARB3 146 // Garbud 3rd time +#define TXT_GARB4 147 // Garbud 4th time + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Zhar the Mad Quest + +#define TXT_ZHAR1 148 // Zhar 1st time +#define TXT_ZHAR2 149 // Zhar 2nd time + + +/*-----------------------------------------------------------------------** +// TOWNSPEOPLE'S NONQUEST +**-----------------------------------------------------------------------*/ +// Deckard Cain +#define TXT_STORY1 150 +#define TXT_STORY2 151 +#define TXT_STORY3 152 +#define TXT_STORY4 153 +#define TXT_STORY5 154 +#define TXT_STORY6 155 +#define TXT_STORY7 156 +#define TXT_STORY9 157 +#define TXT_STORY10 158 +#define TXT_STORY11 159 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Ogden +#define TXT_OGDEN1 160 +#define TXT_OGDEN2 161 +#define TXT_OGDEN3 162 +#define TXT_OGDEN4 163 +#define TXT_OGDEN5 164 +#define TXT_OGDEN6 165 +#define TXT_OGDEN8 166 +#define TXT_OGDEN9 167 +#define TXT_OGDEN10 168 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Pepin +#define TXT_PEPIN1 169 +#define TXT_PEPIN2 170 +#define TXT_PEPIN3 171 +#define TXT_PEPIN4 172 +#define TXT_PEPIN5 173 +#define TXT_PEPIN6 174 +#define TXT_PEPIN7 175 +#define TXT_PEPIN9 176 +#define TXT_PEPIN10 177 +#define TXT_PEPIN11 178 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Gillian +#define TXT_GILIAN1 179 +#define TXT_GILIAN2 180 +#define TXT_GILIAN3 181 +#define TXT_GILIAN4 182 +#define TXT_GILIAN5 183 +#define TXT_GILIAN6 184 +#define TXT_GILIAN7 185 +#define TXT_GILIAN9 186 +#define TXT_GILIAN10 187 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Griswold +#define TXT_GRIS1 188 +#define TXT_GRIS2 189 +#define TXT_GRIS3 190 +#define TXT_GRIS4 191 +#define TXT_GRIS5 192 +#define TXT_GRIS6 193 +#define TXT_GRIS7 194 +#define TXT_GRIS8 195 +#define TXT_GRIS9 196 +#define TXT_GRIS10 197 +#define TXT_GRIS12 198 +#define TXT_GRIS13 199 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Farnham +#define TXT_FARN1 200 +#define TXT_FARN2 201 +#define TXT_FARN3 202 +#define TXT_FARN4 203 +#define TXT_FARN5 204 +#define TXT_FARN6 205 +#define TXT_FARN8 206 +#define TXT_FARN9 207 +#define TXT_FARN10 208 +#define TXT_FARN11 209 +#define TXT_FARN12 210 +#define TXT_FARN13 211 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Adria +#define TXT_ADRIA1 212 +#define TXT_ADRIA2 213 +#define TXT_ADRIA3 214 +#define TXT_ADRIA4 215 +#define TXT_ADRIA5 216 +#define TXT_ADRIA6 217 +#define TXT_ADRIA7 218 +#define TXT_ADRIA8 219 +#define TXT_ADRIA9 220 +#define TXT_ADRIA10 221 +#define TXT_ADRIA12 222 +#define TXT_ADRIA13 223 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// Wirt +#define TXT_WIRT1 224 +#define TXT_WIRT2 225 +#define TXT_WIRT3 226 +#define TXT_WIRT4 227 +#define TXT_WIRT5 228 +#define TXT_WIRT6 229 +#define TXT_WIRT7 230 +#define TXT_WIRT8 231 +#define TXT_WIRT9 232 +#define TXT_WIRT11 233 +#define TXT_WIRT12 234 + + +/*-----------------------------------------------------------------------** +// BOOKS and SCROLLS as read by the heroes +**-----------------------------------------------------------------------*/ +// Warrior +#define TXT_WARBONE 235 // Skeletal Tome +#define TXT_WARBLOOD 236 // Book of Blood +#define TXT_WARBLIND 237 // Book of the Blind +#define TXT_WARLORD 238 // Steel Tome + +// Sorcerer +#define TXT_SORBONE 239 // Skeletal Tome +#define TXT_SORBLOOD 240 // Book of Blood +#define TXT_SORBLIND 241 // Book of the Blind +#define TXT_SORLORD 242 // Steel Tome + +// Rogue +#define TXT_ROGBONE 243 // Skeletal Tome +#define TXT_ROGBLOOD 244 // Book of Blood +#define TXT_ROGBLIND 245 // Book of the Blind +#define TXT_ROGLORD 246 // Steel Tome + +// Monk +// GWP Fix these if new quests are added. +#define TXT_MNKBONE 259 // Skeletal Tome +#define TXT_MNKBLOOD 260 // Book of Blood +#define TXT_MNKBLIND 261 // Book of the Blind +#define TXT_MNKLORD 262 // Steel Tome + +// Bard +#define TXT_BRDBONE 263 // Skeletal Tome +#define TXT_BRDBLOOD 264 // Book of Blood +#define TXT_BRDBLIND 265 // Book of the Blind +#define TXT_BRDLORD 266 // Steel Tome + +// Barbarian +#define TXT_BARBONE TXT_WARBONE +#define TXT_BARBLOOD TXT_WARBLOOD +#define TXT_BARBLIND TXT_WARBLIND +#define TXT_BARLORD TXT_WARLORD + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define TXT_COW1 247 // Cow1 +#define TXT_COW2 248 // Cow2 + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +#define TXT_BOOK11 249 // Story Book Set 1, Book 1 +#define TXT_BOOK12 250 // Story Book Set 1, Book 2 +#define TXT_BOOK13 251 // Story Book Set 1, Book 3 +#define TXT_BOOK21 252 // Story Book Set 2, Book 1 +#define TXT_BOOK22 253 // Story Book Set 2, Book 2 +#define TXT_BOOK23 254 // Story Book Set 2, Book 3 +#define TXT_BOOK31 255 // Story Book Set 3, Book 1 +#define TXT_BOOK32 256 // Story Book Set 3, Book 2 +#define TXT_BOOK33 257 // Story Book Set 3, Book 3 + +#define TXT_INTRO 258 // Tavern owner intro + + +//----------------------------------------------------------------------- +// START OUR QUEST TEXT DEFINES HERE - JKEQUEST +//----------------------------------------------------------------------- +#define TXT_CRYPTMAP1 267 // Init text for crypt quest JKE +#define TXT_CRYPTMAP2 268 +#define TXT_CRYPTMAP3 269 +#define TXT_CRYPTMAP4 270 +#define TXT_CRYPTMAP5 271 +#define TXT_CRYPTMAP6 272 +#define TXT_CRYPTMAP7 273 +#define TXT_CRYPTMAP8 274 +#define TXT_CRYPTMAP9 275 +#define TXT_CRYPTMAP10 276 + +#define TXT_FARMER1 277 // Farmer explosion thing JKE +#define TXT_FARMER2 278 +#define TXT_FARMER3 279 +#define TXT_FARMER4 280 +#define TXT_FARMER5 281 +#define TXT_FARMER2A 307 +#define TXT_FARMER6 308 +#define TXT_FARMER7 309 +#define TXT_FARMER8 310 +#define TXT_FARMER9 311 + + +#define TXT_THEO1 282 // Theo the teddy bear +#define TXT_THEO2 283 +#define TXT_THEO3 284 +#define TXT_THEO4 285 + +#define TXT_DEFILER1 286 // The Defiler +#define TXT_DEFILER2 287 +#define TXT_DEFILER3 288 +#define TXT_DEFILER4 289 +#define TXT_DEFILER5 290 + +#define TXT_NA_KRUL1 291 // Na-Krul +#define TXT_NA_KRUL2 292 +#define TXT_NA_KRUL3 293 +#define TXT_NA_KRUL4 294 +#define TXT_NA_KRUL5 295 + +#define TXT_CORNERSTONE1 296 // Cornerstone of the world + +#define TXT_COWSUIT1 297 // Cow suit guy +#define TXT_COWSUIT2 298 +#define TXT_COWSUIT3 299 +#define TXT_COWSUIT4 300 +#define TXT_COWSUIT4A 315 +#define TXT_COWSUIT5 301 +#define TXT_COWSUIT6 302 +#define TXT_COWSUIT7 303 +#define TXT_COWSUIT8 304 +#define TXT_COWSUIT9 305 +#define TXT_COWSUIT10 312 +#define TXT_COWSUIT11 313 +#define TXT_COWSUIT12 314 + +#define TXT_TRADER1 306 + +#define TXT_SKULLJRNL1 316 +#define TXT_SKULLJRNL2 317 +#define TXT_SKULLJRNL3 318 +#define TXT_SKULLJRNL4 319 +#define TXT_SKULLJRNL5 320 +#define TXT_SKULLJRNL6 321 +#define TXT_SKULLJRNL7 322 + +#define TXT_SPELL1 323 +#define TXT_SPELL2 324 +#define TXT_SPELL3 325 + +#define TXT_M_SPELL1 326 +#define TXT_M_SPELL2 327 +#define TXT_M_SPELL3 328 + +#define TXT_S_SPELL1 329 +#define TXT_S_SPELL2 330 +#define TXT_S_SPELL3 331 + +#define TXT_R_SPELL1 332 +#define TXT_R_SPELL2 333 +#define TXT_R_SPELL3 334 + +#define TXT_B_SPELL1 335 +#define TXT_B_SPELL2 336 +#define TXT_B_SPELL3 337 + +#define TXT_C_SPELL1 TXT_SPELL1 +#define TXT_C_SPELL2 TXT_SPELL2 +#define TXT_C_SPELL3 TXT_SPELL3 + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ +extern const TextDataStruct alltext[]; +extern const DWORD gdwAllTextEntries; diff --git a/THEMES.CPP b/THEMES.CPP new file mode 100644 index 0000000..61cffb4 --- /dev/null +++ b/THEMES.CPP @@ -0,0 +1,1063 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Thematic rooms file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/THEMES.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "themes.h" +#include "gendung.h" +#include "engine.h" + +#include "objects.h" +#include "objdat.h" +#include "monster.h" +#include "monstdat.h" +#include "items.h" +#include "quests.h" +#include "trigs.h" + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +#define TOTAL_THEMES 17 + +#define THEME_NONE -1 +#define THEME_BARREL 0 +#define THEME_SHRINE 1 +#define THEME_MONSTPIT 2 +#define THEME_SKELRM 3 +#define THEME_TREASURE 4 +#define THEME_LIBRARY 5 +#define THEME_TORTURE 6 +#define THEME_BLOODFTN 7 +#define THEME_DECAP 8 +#define THEME_PURIFYINGFTN 9 +#define THEME_ARMORSTAND 10 +#define THEME_GOATSHRINE 11 +#define THEME_CAULDRON 12 +#define THEME_MURKYFTN 13 +#define THEME_TEARFTN 14 +#define THEME_BRNCROSS 15 +#define THEME_WEAPONRACK 16 + +/*-----------------------------------------------------------------------** +** Global variables +**-----------------------------------------------------------------------*/ + +ThemeStruct theme[MAXTHEMES]; +int numthemes; +int zharlib; + +int themex, themey; +int themeVar1; + +//Theme flags +BOOL armorFlag; +BOOL bFountainFlag; +BOOL cauldronFlag; +BOOL mFountainFlag; +BOOL pFountainFlag; +BOOL tFountainFlag; +BOOL treasureFlag; +BOOL bCrossFlag; +BOOL weaponFlag; + +/*-----------------------------------------------------------------------*/ +// List of themes that it trys to fit first + +#define THEME_NUMGOOD 4 + +int ThemeGood[THEME_NUMGOOD] = { + THEME_GOATSHRINE, + THEME_SHRINE, + THEME_SKELRM, + THEME_LIBRARY, +}; + +BOOL ThemeGoodIn[THEME_NUMGOOD]; + +/*-----------------------------------------------------------------------*/ + +// 5x5 area offsets +int trm5x[] = { -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2 }; +int trm5y[] = { -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 }; + +// 3x3 area offsets +int trm3x[] = { -1, 0, 1, -1, 0, 1, -1, 0, 1 }; +int trm3y[] = { -1, -1, -1, 0, 0, 0, 1, 1, 1 }; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL TFit_Shrine(int i) +{ + int xp, yp, found; + + app_assert((DWORD)i < MAXTHEMES); + xp = 0; + yp = 0; + found = 0; + while (!found) { + if (dTransVal[xp][yp] == theme[i].ttval) { + if ((nTrapTable[dPiece[xp][yp-1]]) && + (!nSolidTable[dPiece[xp-1][yp]]) && + (!nSolidTable[dPiece[xp+1][yp]]) && + (dTransVal[xp-1][yp] == theme[i].ttval) && + (dTransVal[xp+1][yp] == theme[i].ttval) && + (dObject[xp-1][yp-1] == 0) && + (dObject[xp+1][yp-1] == 0)) found = 1; + if (!found) { + if ((nTrapTable[dPiece[xp-1][yp]]) && + (!nSolidTable[dPiece[xp][yp-1]]) && + (!nSolidTable[dPiece[xp][yp+1]]) && + (dTransVal[xp][yp-1] == theme[i].ttval) && + (dTransVal[xp][yp+1] == theme[i].ttval) && + (dObject[xp-1][yp-1] == 0) && + (dObject[xp-1][yp+1] == 0)) found = 2; + } + } + if (!found) { + xp++; + if (xp == DMAXX) { + xp = 0; + yp++; + if (yp == DMAXY) return(FALSE); + } + } + } + themex = xp; + themey = yp; + themeVar1 = found; + return(TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL TFit_Obj5(int t) +{ + int xp, yp; + int i, r, rs; + BOOL found; + + app_assert((DWORD)t < MAXTHEMES); + xp = 0; + yp = 0; + r = random(0, 5) + 1; + rs = r; + while (r > 0) { + found = FALSE; + if ((dTransVal[xp][yp] == theme[t].ttval) && (!nSolidTable[dPiece[xp][yp]])) { + found = TRUE; + for (i = 0; (found && (i < 25)); i++) { + if (nSolidTable[dPiece[xp+trm5x[i]][yp+trm5y[i]]]) found = FALSE; + if (dTransVal[xp+trm5x[i]][yp+trm5y[i]] != theme[t].ttval) found = FALSE; + } + } + if (!found) { + xp++; + if (xp == DMAXX) { + xp = 0; + yp++; + if (yp == DMAXY) { + if (r == rs) return(FALSE); + else yp = 0; + } + } + } else r--; + } + themex = xp; + themey = yp; + return(TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL TFit_SkelRoom(int t) +{ + int i; + + if (leveltype == 1 || leveltype == 2) + { + for (i = 0; i < nummtypes; i++) { + if (IsSkel(Monsters[i].mtype)) { + //Initialize themeVar1 to monster type skeleton + themeVar1 = i; + return TFit_Obj5(t); + } + } + } + + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL TFit_GoatShrine(int t) +{ + int i; + + for (i = 0; i < nummtypes; i++) { + if (IsGoat(Monsters[i].mtype)) { + //Initialize themeVar1 to monster type goat + themeVar1 = i; + return TFit_Obj5(t); + } + } + + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL CheckThemeObj3(int xp, int yp, int t, int f) +{ + app_assert((DWORD)t < MAXTHEMES); + for (int i = 0; i < 9; i++) { + if (xp+trm3x[i] < 0 || yp+trm3y[i] < 0) + return FALSE; + if (nSolidTable[dPiece[xp+trm3x[i]][yp+trm3y[i]]]) + return FALSE; + if (dTransVal[xp+trm3x[i]][yp+trm3y[i]] != theme[t].ttval) + return FALSE; + if (dObject[xp+trm3x[i]][yp+trm3y[i]] != 0) + return FALSE; + if (f != -1 && random(0, f) == 0) + return FALSE; + } + return TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL TFit_Obj3(int t) +{ + int xp, yp; + char objrnd[4] = { 4, 4, 3, 5 }; + + for (yp = 1; yp < DMAXY-1; yp++) { + for (xp = 1; xp < DMAXX-1; xp++) { + if (CheckThemeObj3(xp, yp, t, objrnd[leveltype-1])) { + themex = xp; + themey = yp; + return TRUE; + } + } + } + return FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL CheckThemeReqs(int t) +/*-----------------------------------------------------------------------** +** Description: Checks theme room requirements, such as themes for specific +** levels or themes which can only be used once per level. +** Input: None +** Return: TRUE = All requirements met +**-----------------------------------------------------------------------*/ +{ + BOOL rv = TRUE; + + switch(t) { + case THEME_SHRINE: + case THEME_LIBRARY: + if (leveltype == 3 || leveltype == 4) rv = FALSE; + break; + case THEME_SKELRM: + if (leveltype == 3 || leveltype == 4) rv = FALSE; + break; + case THEME_BLOODFTN: + if (!bFountainFlag) rv = FALSE; + break; + case THEME_PURIFYINGFTN: + if (!pFountainFlag) rv = FALSE; + break; + case THEME_MURKYFTN: + if (!mFountainFlag) rv = FALSE; + break; + case THEME_TEARFTN: + if (!tFountainFlag) rv = FALSE; + break; + case THEME_ARMORSTAND: + case THEME_WEAPONRACK: + if (leveltype == 1) rv = FALSE; + break; + case THEME_CAULDRON: + if ((leveltype != 4) || (!cauldronFlag)) rv = FALSE; + break; + } + + return rv; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL SpecialThemeFit(int i, int t) +{ + BOOL rv = TRUE; + + rv = CheckThemeReqs(t); + + switch(t) { + case THEME_SHRINE: + case THEME_LIBRARY: + if (rv) rv = TFit_Shrine(i); + break; + case THEME_SKELRM: + if (rv) rv = TFit_SkelRoom(i); + break; + case THEME_BLOODFTN: + if (rv) rv = TFit_Obj5(i); + //This is set so we only get one blood fountain per level + if (rv) bFountainFlag = FALSE; + break; + case THEME_PURIFYINGFTN: + if (rv) rv = TFit_Obj5(i); + //This is set so we only get one purifying fountain per level + if (rv) pFountainFlag = FALSE; + break; + case THEME_MURKYFTN: + if (rv) rv = TFit_Obj5(i); + //This is set so we only get one murky fountain per level + if (rv) mFountainFlag = FALSE; + break; + case THEME_TEARFTN: + if (rv) rv = TFit_Obj5(i); + //This is set so we only get one tear fountain per level + if (rv) tFountainFlag = FALSE; + break; + case THEME_CAULDRON: + if (rv) rv = TFit_Obj5(i); + //This is set so we only get one cauldron room per level + if (rv) cauldronFlag = FALSE; + break; + case THEME_GOATSHRINE: + if (rv) rv = TFit_GoatShrine(i); + break; + case THEME_DECAP: + case THEME_TORTURE: + case THEME_ARMORSTAND: + case THEME_BRNCROSS: + case THEME_WEAPONRACK: + if (rv) rv = TFit_Obj3(i); + break; + case THEME_TREASURE: + rv = treasureFlag; + //This is set so we only get one treasure room per level + if (rv) treasureFlag = FALSE; + break; + } + + return(rv); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL CheckThemeRoom(int tv) +{ + int i, j; + int tarea; + + for (i = 0; i < numtrigs; i++) { + if (dTransVal[trigs[i]._tx][trigs[i]._ty] == tv) return(FALSE); + } + + // Check area requirements + tarea = 0; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dTransVal[i][j] == tv) { + if (dFlags[i][j] & BFLAG_SETPC) return(FALSE); + tarea++; + } + } + } + + if (leveltype == 1) { + if ((tarea < 9) || (tarea > 100)) return(FALSE); + } + + // Make sure it is a solid room + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if ((dTransVal[i][j] == tv) && (!nSolidTable[dPiece[i][j]])) { + if ((dTransVal[i-1][j] != tv) && (!nSolidTable[dPiece[i-1][j]])) return(FALSE); + if ((dTransVal[i+1][j] != tv) && (!nSolidTable[dPiece[i+1][j]])) return(FALSE); + if ((dTransVal[i][j-1] != tv) && (!nSolidTable[dPiece[i][j-1]])) return(FALSE); + if ((dTransVal[i][j+1] != tv) && (!nSolidTable[dPiece[i][j+1]])) return(FALSE); + } + } + } + return(TRUE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitThemes() +{ + int i, t; + + numthemes = 0; + zharlib = -1; + //Initialize theme flags + armorFlag = TRUE; + bFountainFlag = TRUE; + cauldronFlag = TRUE; + mFountainFlag = TRUE; + pFountainFlag = TRUE; + tFountainFlag = TRUE; + treasureFlag = TRUE; + bCrossFlag = FALSE; + weaponFlag = TRUE; + + if (currlevel == 16) return; + + //Find L1 theme room types + if (leveltype == 1) { + for (i = 0; i < THEME_NUMGOOD; i++) ThemeGoodIn[i] = FALSE; + for (i = 0; (i < 256) && (numthemes < MAXTHEMES); i++) { + if (CheckThemeRoom(i)) { + theme[numthemes].ttval = i; + t = ThemeGood[random(0, THEME_NUMGOOD)]; // Normal + while (!SpecialThemeFit(numthemes, t)) t = random(0, TOTAL_THEMES); + theme[numthemes].ttype = t; + numthemes++; + } + } + } + + //Find L2, L3, L4 theme room types + if (leveltype == 2 || leveltype == 3 || leveltype == 4) + { + //Initialize theme room types + app_assert((DWORD)themeCount < MAXTHEMES); + for (i = 0; i < themeCount; i++) { + theme[i].ttype = THEME_NONE; + } + + //Special Quest + if (QuestStatus(Q_ZHAR)) { + for (i = 0; i < themeCount; i++) { + theme[i].ttval = themeLoc[i].ttval; + if (SpecialThemeFit(i, THEME_LIBRARY)) { + theme[i].ttype = THEME_LIBRARY; + zharlib = i; + break; + } + } + } + + //Add themeLoc array to general theme array + for (i = 0; i < themeCount; i++) { + if (theme[i].ttype == THEME_NONE) { + theme[i].ttval = themeLoc[i].ttval; + t = ThemeGood[random(0, THEME_NUMGOOD)]; + while (!SpecialThemeFit(i, t)) t = random(0, TOTAL_THEMES); + theme[i].ttype = t; + } + } + //Add L2 theme count to general theme count + numthemes += themeCount; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void HoldThemeRooms() +{ + int i, x, y; + char tv; + + if (currlevel == 16) return; + + app_assert((DWORD)numthemes < MAXTHEMES); + if (leveltype == 1) { + for (i = 0; i < numthemes; i++) { + tv = theme[i].ttval; + for (y = 0; y < DMAXY; y++) { + for (x = 0; x < DMAXX; x++) { + if (dTransVal[x][y] == tv) dFlags[x][y] |= BFLAG_SETPC; + } + } + } + } else { + //Hold L2,L3,L4 + DRLG_HoldThemeRooms(); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PlaceThemeMonsts(int t, int f) +{ + int xp, yp, mtype; + int scattertypes[LASTMT]; + int numscattypes = 0; + int i; + + app_assert((DWORD)t < MAXTHEMES); + for (i = 0; i < nummtypes; i++) + { + if (Monsters[i].mPlaceFlags & MPFLAG_SCATTER) + scattertypes[numscattypes++] = i; + } + mtype = scattertypes[random(0, numscattypes)]; + + for (yp = 0; yp < DMAXY; yp++) { + for (xp = 0; xp < DMAXX; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && + (!nSolidTable[dPiece[xp][yp]]) && + (dItem[xp][yp] == 0) && + (dObject[xp][yp] == 0)) { + if (random(0, f) == 0) AddMonster(xp, yp, random(0, 8), mtype, TRUE); + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void PlaceSpecificThemeMonsts(int t, int f, int mtype) +{ + int xp, yp; + + app_assert((DWORD)t < MAXTHEMES); + for (yp = 0; yp < DMAXY; yp++) { + for (xp = 0; xp < DMAXX; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && + (!nSolidTable[dPiece[xp][yp]]) && + (dItem[xp][yp] == 0) && + (dObject[xp][yp] == 0)) { + if (random(0, f) == 0) AddMonster(xp, yp, random(0, 8), mtype, TRUE); + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_Barrel(int t) +{ + int xp, yp, r; + char barrnd[4] = { 2, 6, 4, 8 }; + char monstrnd[4] = { 5, 7, 3, 9 }; + + app_assert((DWORD)t < MAXTHEMES); + for (yp = 0; yp < DMAXY; yp++) { + for (xp = 0; xp < DMAXX; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && (!nSolidTable[dPiece[xp][yp]])) { + if (!random(0, barrnd[leveltype-1])) { + if (!random(0, barrnd[leveltype-1])) r = OBJ_BARREL; + else r = OBJ_BARRELEX; + AddObject(r, xp, yp); + } + } + } + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_Shrine(int t) +{ + char monstrnd[4] = { 6, 6, 3, 9 }; + + TFit_Shrine(t); + if (themeVar1 == 1) { + AddObject(OBJ_CANDLE2, themex-1, themey); + AddObject(OBJ_SHRINER, themex, themey); + AddObject(OBJ_CANDLE2, themex+1, themey); + } else { + AddObject(OBJ_CANDLE2, themex, themey-1); + AddObject(OBJ_SHRINEL, themex, themey); + AddObject(OBJ_CANDLE2, themex, themey+1); + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_MonstPit(int t) +{ + int r, ixp, iyp; + char monstrnd[4] = { 6, 7, 3, 9 }; + + app_assert((DWORD)t < MAXTHEMES); + r = random(0, 100)+1; + ixp = 0; + iyp = 0; + while (r > 0) { + if ((dTransVal[ixp][iyp] == theme[t].ttval) && (!nSolidTable[dPiece[ixp][iyp]])) r--; + if (r > 0) { + ixp++; + if (ixp == DMAXX) { + ixp = 0; + iyp++; + if (iyp == DMAXY) iyp = 0; + } + } + } + CreateRndItem(ixp, iyp, TRUE, FALSE, TRUE); // Create a good item + ItemNoFlippy(); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_SkelRoom(int t) +{ + int mt; + int xp, yp; + int ii; + char monstrnd[4] = { 6, 7, 3, 9 }; + + TFit_SkelRoom(t); + mt = themeVar1; + xp = themex; + yp = themey; + + AddObject(OBJ_SKFIRE, xp, yp); + if (random(0, monstrnd[leveltype-1])) { + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp-1, yp-1); + } else AddObject(OBJ_BANNERL, xp-1, yp-1); + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp, yp-1); + if (random(0, monstrnd[leveltype-1])) { + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp+1, yp-1); + } else AddObject(OBJ_BANNERR, xp+1, yp-1); + if (random(0, monstrnd[leveltype-1])) { + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp-1, yp); + } else AddObject(OBJ_BANNERM, xp-1, yp); + if (random(0, monstrnd[leveltype-1])) { + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp+1, yp); + } else AddObject(OBJ_BANNERM, xp+1, yp); + if (random(0, monstrnd[leveltype-1])) { + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp-1, yp+1); + } else AddObject(OBJ_BANNERR, xp-1, yp+1); + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp, yp+1); + if (random(0, monstrnd[leveltype-1])) { + ii = PreSpawnSkeleton(); + SpawnSkeleton(ii, xp+1, yp+1); + } else AddObject(OBJ_BANNERL, xp+1, yp+1); + + if (dObject[xp][yp-3] == 0) AddObject(OBJ_SKELBOOK, xp, yp-2); + if (dObject[xp][yp+3] == 0) AddObject(OBJ_SKELBOOK, xp, yp+2); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_Treasure(int t) +{ + int xp, yp, i; + char treasrnd[4] = { 4, 9, 7, 10 }; + char monstrnd[4] = { 6, 8, 3, 7 }; + + app_assert((DWORD)t < MAXTHEMES); + int rs = GetRndSeed(); + for (yp = 0; yp < DMAXY; yp++) + { + for (xp = 0; xp < DMAXX; xp++) + { + if ((dTransVal[xp][yp] == theme[t].ttval) && + (!nSolidTable[dPiece[xp][yp]])) + { + int rv = random(0, treasrnd[leveltype-1]); + if (!(random(0, treasrnd[leveltype-1])*2)) { + CreateTypeItem(xp, yp, FALSE, IT_GOLD, 0, FALSE, TRUE); + ItemNoFlippy(); + } + if (rv == 0) { + CreateRndItem(xp, yp, FALSE, FALSE, TRUE); + ItemNoFlippy(); + } + if ((rv == 0) || (rv >= (treasrnd[leveltype-1]-2))) { + i = ItemNoFlippy(); + if (rv >= (treasrnd[leveltype-1]-2) && leveltype != 1) + item[i]._ivalue = item[i]._ivalue >> 1; + } + } + } + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_Library(int t) +{ + int xp, yp, oi; + char librnd[4] = { 1, 2, 2, 5 }; + char monstrnd[4] = { 5, 7, 3, 9 }; + + TFit_Shrine(t); + if (themeVar1 == 1) { + AddObject(OBJ_BOOKCANDLE, themex-1, themey); + AddObject(OBJ_BOOKCASER, themex, themey); + AddObject(OBJ_BOOKCANDLE, themex+1, themey); + } else { + AddObject(OBJ_BOOKCANDLE, themex, themey-1); + AddObject(OBJ_BOOKCASEL, themex, themey); + AddObject(OBJ_BOOKCANDLE, themex, themey+1); + } + + for (yp = 1; yp < DMAXY-1; yp++) { + for (xp = 1; xp < DMAXX-1; xp++) { + if (CheckThemeObj3(xp, yp, t, -1) && + (dMonster[xp][yp] == 0) && // Zhar the mad fix + (!random(0, librnd[leveltype-1]))) { + AddObject(OBJ_BOOKSTAND, xp, yp); + // Pre used? + if (random(0, (librnd[leveltype-1] << 1))) { + oi = dObject[xp][yp]-1; + object[oi]._oSelFlag = OSEL_NONE; + object[oi]._oAnimFrame += 2; + } + } + } + } + + //special quest + if (QuestStatus(Q_ZHAR)) { + if (t != zharlib) PlaceThemeMonsts(t, monstrnd[leveltype]); + } + else PlaceThemeMonsts(t, monstrnd[leveltype]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_Torture(int t) +{ + int xp, yp; + char tortrnd[4] = { 6, 8, 3, 8 }; + char monstrnd[4] = { 6, 8, 3, 9 }; + + app_assert((DWORD)t < MAXTHEMES); + //Add tortured body + for (yp = 1; yp < DMAXY-1; yp++) { + for (xp = 1; xp < DMAXX-1; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && (!nSolidTable[dPiece[xp][yp]])) { + if (CheckThemeObj3(xp, yp, t, -1) && (!random(0, tortrnd[leveltype-1]))) + AddObject(OBJ_TNUDEM2, xp, yp); + } + } + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_BloodFountain(int t) +{ + char monstrnd[4] = { 6, 8, 3, 9 }; + + TFit_Obj5(t); + AddObject(OBJ_BLOODFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_Decap(int t) +{ + int xp, yp; + char decaprnd[4] = { 6, 8, 3, 8 }; + char monstrnd[4] = { 6, 8, 3, 9 }; + + app_assert((DWORD)t < MAXTHEMES); + //Add decapitated body + for (yp = 1; yp < DMAXY-1; yp++) { + for (xp = 1; xp < DMAXX-1; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && (!nSolidTable[dPiece[xp][yp]])) { + if (CheckThemeObj3(xp, yp, t, -1) && (!random(0, decaprnd[leveltype-1]))) + AddObject(OBJ_DECAP, xp, yp); + } + } + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_PurifyingFountain(int t) +{ + char monstrnd[4] = { 6, 7, 3, 9 }; + + TFit_Obj5(t); + AddObject(OBJ_PURIFYINGFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_ArmorStand(int t) +{ + int xp, yp; + char armorrnd[4] = { 6, 8, 3, 8 }; + char monstrnd[4] = { 6, 7, 3, 9 }; + + app_assert((DWORD)t < MAXTHEMES); + //Add functional stand w/ armor + if(armorFlag) { + TFit_Obj3(t); + AddObject(OBJ_ARMORSTAND, themex, themey); + } + //Add stand only + for (yp = 0; yp < DMAXY; yp++) { + for (xp = 0; xp < DMAXX; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && (!nSolidTable[dPiece[xp][yp]])) { + if (CheckThemeObj3(xp, yp, t, -1) && (!random(0, armorrnd[leveltype-1]))) + AddObject(OBJ_ARMORSTANDN, xp, yp); + } + } + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); + //This is set so we only get one functional armor stand per level + armorFlag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_GoatShrine(int t) +{ + int xx, yy; + + app_assert((DWORD)t < MAXTHEMES); + TFit_GoatShrine(t); + AddObject(OBJ_GOATSHRINE, themex, themey); + //Add goat monsters around shrine + for (yy = themey-1; yy <= themey+1; yy++) { + for (xx = themex-1; xx <= themex+1; xx++) { + if ((dTransVal[xx][yy] == theme[t].ttval) && + (!nSolidTable[dPiece[xx][yy]])) { + //Skip center monster since shrine is in the center + if (xx == themex && yy == themey) continue; + else AddMonster(xx, yy, 1, themeVar1, TRUE); + } + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_Cauldron(int t) +{ + char monstrnd[4] = { 6, 7, 3, 9 }; + + TFit_Obj5(t); + AddObject(OBJ_CAULDRON, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_MurkyFountain(int t) +{ + char monstrnd[4] = { 6, 7, 3, 9 }; + + TFit_Obj5(t); + AddObject(OBJ_MURKYFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_TearFountain(int t) +{ + char monstrnd[4] = { 6, 7, 3, 9 }; + + TFit_Obj5(t); + AddObject(OBJ_TEARFTN, themex, themey); + PlaceThemeMonsts(t, monstrnd[leveltype-1]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_BrnCross(int t) +{ + int xp, yp; + + char monstrnd[4] = { 6, 8, 3, 9 }; + char bcrossrnd[4] = { 5, 7, 3, 8 }; + + app_assert((DWORD)t < MAXTHEMES); + for (yp = 0; yp < DMAXY; yp++) { + for (xp = 0; xp < DMAXX; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && (!nSolidTable[dPiece[xp][yp]])) { + if (CheckThemeObj3(xp, yp, t, -1) && (!random(0, bcrossrnd[leveltype-1]))) + AddObject(OBJ_TBCROSS, xp, yp); + } + } + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); + //Set so we know a burning cross theme room has been created on the level. + bCrossFlag = TRUE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void Theme_WeaponRack(int t) +{ + int xp, yp; + char weaponrnd[4] = { 6, 8, 5, 8 }; + char monstrnd[4] = { 6, 7, 3, 9 }; + + app_assert((DWORD)t < MAXTHEMES); + //Add functional rack w/ weapon + if(weaponFlag) { + TFit_Obj3(t); + AddObject(OBJ_WEAPONRACK, themex, themey); + } + //Add rack only + for (yp = 0; yp < DMAXY; yp++) { + for (xp = 0; xp < DMAXX; xp++) { + if ((dTransVal[xp][yp] == theme[t].ttval) && (!nSolidTable[dPiece[xp][yp]])) { + if (CheckThemeObj3(xp, yp, t, -1) && (!random(0, weaponrnd[leveltype-1]))) + AddObject(OBJ_WEAPONRACKN, xp, yp); + } + } + } + PlaceThemeMonsts(t, monstrnd[leveltype-1]); + //This is set so we only get one functional weapon rack per level + weaponFlag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void UpdateL4Trans() +{ + int i, j; + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dTransVal[i][j] != 0) + dTransVal[i][j] = 1; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CreateThemeRooms() +{ + int i; + + if (currlevel == 16) return; + + InitObjFlag = TRUE; + app_assert((DWORD)numthemes < MAXTHEMES); + for (i = 0; i < numthemes; i++) { + themex = 0; + themey = 0; + switch(theme[i].ttype) { + case THEME_BARREL: + Theme_Barrel(i); + break; + case THEME_SHRINE: + Theme_Shrine(i); + break; + case THEME_MONSTPIT: + Theme_MonstPit(i); + break; + case THEME_SKELRM: + Theme_SkelRoom(i); + break; + case THEME_TREASURE: + Theme_Treasure(i); + break; + case THEME_LIBRARY: + Theme_Library(i); + break; + case THEME_TORTURE: + Theme_Torture(i); + break; + case THEME_BLOODFTN: + Theme_BloodFountain(i); + break; + case THEME_DECAP: + Theme_Decap(i); + break; + case THEME_PURIFYINGFTN: + Theme_PurifyingFountain(i); + break; + case THEME_ARMORSTAND: + Theme_ArmorStand(i); + break; + case THEME_GOATSHRINE: + Theme_GoatShrine(i); + break; + case THEME_CAULDRON: + Theme_Cauldron(i); + break; + case THEME_TEARFTN: + Theme_TearFountain(i); + break; + case THEME_MURKYFTN: + Theme_MurkyFountain(i); + break; + case THEME_BRNCROSS: + Theme_BrnCross(i); + break; + case THEME_WEAPONRACK: + Theme_WeaponRack(i); + break; + } + } + InitObjFlag = FALSE; + + //Update L4 trans values to get rid of blinking + if (leveltype == 4 && themeCount > 0) UpdateL4Trans(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + + diff --git a/THEMES.H b/THEMES.H new file mode 100644 index 0000000..2cb039e --- /dev/null +++ b/THEMES.H @@ -0,0 +1,43 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/THEMES.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAXTHEMES 50 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + char ttype; + int ttval; +} ThemeStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern ThemeStruct theme[MAXTHEMES]; +extern int numthemes; +extern int zharlib; +extern BOOL armorFlag; +extern BOOL bCrossFlag; +extern BOOL weaponFlag; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitThemes(); +void HoldThemeRooms(); +void CreateThemeRooms(); diff --git a/TMSG.CPP b/TMSG.CPP new file mode 100644 index 0000000..ef95bdc --- /dev/null +++ b/TMSG.CPP @@ -0,0 +1,88 @@ +//****************************************************************** +// tmsg.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "engine.h" + + +//****************************************************************** +// timed messages +//****************************************************************** +typedef struct TTimedMsg { + struct TTimedMsg * pNext; + long lTime; + BYTE bLen; + BYTE bData[1]; +} TTimedMsg; + +#define TIMED_MSG_DELAY 500 // ticks +static TTimedMsg * sgpTimedMsgHead; + + +//****************************************************************** +//****************************************************************** +DWORD tmsg_get(BYTE * pbMsg,DWORD dwMaxLen) { + app_assert(pbMsg); + + // any msgs? + if (! sgpTimedMsgHead) return 0; + + // is it time to get this msg? + if (sgpTimedMsgHead->lTime - (long) GetTickCount() >= 0) return 0; + + // dequeue msg + TTimedMsg * ptMsg = sgpTimedMsgHead; + sgpTimedMsgHead = sgpTimedMsgHead->pNext; + + // get msg data + BYTE bLen = ptMsg->bLen; + app_assert(bLen); + app_assert(bLen <= dwMaxLen); + CopyMemory(pbMsg,ptMsg->bData,bLen); + + // free msg + DiabloFreePtr(ptMsg); + + return bLen; +} + + +//****************************************************************** +//****************************************************************** +void tmsg_add(const BYTE * pbMsg,BYTE bLen) { + app_assert(pbMsg); + app_assert(bLen); + + // allocate a new message buffer for this message + TTimedMsg * ptMsg = (TTimedMsg *) DiabloAllocPtrSig(sizeof(TTimedMsg) + bLen,'TMSG'); + ptMsg->pNext = NULL; + ptMsg->lTime = (long) GetTickCount() + TIMED_MSG_DELAY; + ptMsg->bLen = bLen; + CopyMemory(ptMsg->bData,pbMsg,bLen); + + // add to tail of list + TTimedMsg ** ppMsg = &sgpTimedMsgHead; + while (*ppMsg) ppMsg = &(*ppMsg)->pNext; + *ppMsg = ptMsg; +} + + +//****************************************************************** +//****************************************************************** +void tmsg_init() { + app_assert(! sgpTimedMsgHead); +} + + +//****************************************************************** +//****************************************************************** +void tmsg_free() { + while (sgpTimedMsgHead) { + TTimedMsg * pNext = sgpTimedMsgHead->pNext; + DiabloFreePtr(sgpTimedMsgHead); + sgpTimedMsgHead = pNext; + } +} diff --git a/TOWN.CPP b/TOWN.CPP new file mode 100644 index 0000000..461bca0 --- /dev/null +++ b/TOWN.CPP @@ -0,0 +1,1808 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Town file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/TOWN.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "engine.h" +#include "scrollrt.h" +#include "scrlasm.h" +#include "gendung.h" + +#include "items.h" +#include "cursor.h" +#include "trigs.h" +#include "control.h" +#include "gamemenu.h" + +#include "player.h" +#include "monster.h" + +#include "town.h" +#include "towners.h" +#include "inv.h" +#include "quests.h" +#include "minitext.h" +#include "stores.h" +#include "effects.h" + +#include "automap.h" +#include "help.h" +#include "error.h" +#include "doom.h" +#include "multi.h" + +#define T_POUTC 165 + +// #define TESTINGCRYPT // JKE set this to keep the crypt open + +#if RLE_DRAW +void DrawUnit (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend); +void DrawUnitClipped (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend); +void DrawUnitOutline(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend); +void DrawUnitOutlineClipped(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend); +#endif + +static void T_DrawHTLXsub (BYTE *pTo, int sx, int sy, int xp, int yp, BOOL chflag); +static void T_DrawHTLXsub2 (BYTE *pTo, int sx, int sy, int sv, int sv2, int xp, int yp, BOOL chflag); +static void T_DrawHTLXsub3 (BYTE *pTo, int sx, int sy, int ev, int ev2, int xp, int yp, BOOL chflag); +void plrmsg_draw(); + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TDrawBlankMini(BYTE *pDecodeTo) +{ + app_assert(gpBuffer); + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov edx,30 + mov ebx,1 + xor eax,eax + //mov eax,0d3d3d3d3h +_BLp1: cmp edi,dword ptr [glClipY] + jb _Done + add edi,edx + mov ecx,ebx + rep stosd + add edi,edx + sub edi,NBUFFW64 + or edx,edx + jz _Bb + sub edx,2 + inc ebx + jmp _BLp1 + +_Bb: mov edx,2 + mov ebx,15 +_BLp2: cmp edi,dword ptr [glClipY] + jb _Done + add edi,edx + mov ecx,ebx + rep stosd + add edi,edx + sub edi,NBUFFW64 + dec ebx + add edx,2 + cmp edx,32 + jnz _BLp2 +_Done: nop + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TCDrawBlankMini(BYTE *pDecodeTo) +{ + app_assert(gpBuffer); + __asm { + mov edi,dword ptr [pDecodeTo] // Dest + + mov edx,30 + mov ebx,1 + xor eax,eax + //mov eax,0d3d3d3d3h +_BLp1: cmp edi,dword ptr [glClipY] + jb _C1 + add edi,64 + jmp _C2 +_C1: add edi,edx + mov ecx,ebx + rep stosd + add edi,edx +_C2: sub edi,NBUFFW64 + or edx,edx + jz _Bb + sub edx,2 + inc ebx + jmp _BLp1 + +_Bb: mov edx,2 + mov ebx,15 +_BLp2: cmp edi,dword ptr [glClipY] + jb _C3 + add edi,64 + jmp _C4 +_C3: add edi,edx + mov ecx,ebx + rep stosd + add edi,edx +_C4: sub edi,NBUFFW64 + dec ebx + add edx,2 + cmp edx,32 + jnz _BLp2 + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_CDrawSpecial(BYTE *pTo, long nCel) +{ +/* + long RLELen; + long nBufferW; + app_assert(gpBuffer); + __asm { + mov ebx,dword ptr [pSpecialCels] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + mov esi,dword ptr [pSpecialCels] + add esi,dword ptr [ebx] + + mov edi,dword ptr [pTo] // Dest + + mov eax,832 // Increase width + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [RLELen] + add ebx,esi + +_T1Lp1: mov edx,64 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [glClipY] + jb _T1C1 + add esi,eax + add edi,eax + jmp _T1x +_T1C1: mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 + } +*/ +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawSpecial(BYTE *pTo, int nCel) +{ +/* + long RLELen; + long nBufferW; + app_assert(gpBuffer); + __asm { + mov ebx,dword ptr [pSpecialCels] + mov eax,dword ptr [nCel] + shl eax,2 + add ebx,eax + mov eax,dword ptr [ebx+4] + sub eax,dword ptr [ebx] + mov dword ptr [RLELen],eax + mov esi,dword ptr [pSpecialCels] + add esi,dword ptr [ebx] + + mov edi,dword ptr [pTo] // Dest + + mov eax,832 // Increase width + mov dword ptr [nBufferW],eax + + mov ebx,dword ptr [RLELen] + add ebx,esi + +_T1Lp1: mov edx,64 + +_T1Lp2: xor eax,eax // Load control byte + lodsb + or al,al + js _T1J + + sub edx,eax + cmp edi,dword ptr [glClipY] + jb _Done + mov ecx,eax + shr ecx,1 + jnc _T1w + movsb + jecxz _T1x +_T1w: shr ecx,1 + jnc _T1Lp3 + movsw + jecxz _T1x +_T1Lp3: rep movsd +_T1x: or edx,edx + jz _T1Nxt + jmp _T1Lp2 + +_T1J: neg al // Do jump + add edi,eax + sub edx,eax + jnz _T1Lp2 +_T1Nxt: sub edi,dword ptr [nBufferW] + cmp ebx,esi + jnz _T1Lp1 +_Done: nop + } +*/ +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawEFlag1(BYTE *pTo2, int sx, int sy, int xp, int yp) +{ + BYTE *pTo; + int t; + WORD *mt; + + pTo = pTo2; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + for(t = 0; t < 12; t += 2) + { + if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[t+1]) DrawMTileClipBottom (pTo+32); + pTo -= NBUFFWSL5; + } + + T_DrawHTLXsub (pTo2, sx, sy, xp, yp, FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void T_DrawHTLXsub (BYTE *pTo, int sx, int sy, int xp, int yp, BOOL chflag) +{ + int pxp,pyp; + char bv; + int mi; + + app_assert(gpBuffer); + pTo = gpBuffer + nBuffWTbl[yp] + xp; + if (dItem[sx][sy] != 0) { + bv = dItem[sx][sy] - 1; + pxp = xp - item[bv]._iAnimWidth2; + if (bv == cursitem) COutlineSlabCel(181, pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, 8); + CDrawSlabCel(pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, 8); + } + if ((dFlags[sx][sy] & BFLAG_MONSTLR) != 0) { + mi = -(dMonster[sx][sy-1] + 1); + pxp = xp - towner[mi]._tAnimWidth2; + pyp = yp; + if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + } + if (dMonster[sx][sy] > 0) { + mi = dMonster[sx][sy] - 1; + pxp = xp - towner[mi]._tAnimWidth2; + pyp = yp; + if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8); + } + if ((dFlags[sx][sy] & BFLAG_PLRLR) != 0) { + bv = -(dPlayer[sx][sy-1] + 1); + pxp = plr[bv]._pxoff + xp - plr[bv]._pAnimWidth2; + pyp = plr[bv]._pyoff + yp; + + #if RLE_DRAW + if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + DrawUnitClipped(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + #else + if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + CDrawSlabCel(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + #endif + + if (chflag) + { +// if (plr[bv]._peflag == 2) T_DrawEFlag1(pTo-NBUFFWSL4+96, sx-2, sy+1, xp-96, yp-16); + if (plr[bv]._peflag != 0) T_DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp); + } + } + if (dFlags[sx][sy] & BFLAG_DEADPLR) + DrawDeadPlr(sx, sy, xp, yp, 0, 8, TRUE); + if (dPlayer[sx][sy] > 0) { + bv = dPlayer[sx][sy] - 1; + pxp = plr[bv]._pxoff + xp - plr[bv]._pAnimWidth2; + pyp = plr[bv]._pyoff + yp; + + #if RLE_DRAW + if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + DrawUnitClipped(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + #else + if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + CDrawSlabCel(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8); + #endif + + if (chflag) + { +// if (plr[bv]._peflag == 2) T_DrawEFlag1(pTo-NBUFFWSL4+96, sx-2, sy+1, xp-96, yp-16); + if (plr[bv]._peflag != 0) T_DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp); + } + } + if ((dFlags[sx][sy] & BFLAG_MISSILE) != 0) CDrawMissile(sx, sy, xp, yp, 0, 8, FALSE); + if (dSpecial[sx][sy]) T_CDrawSpecial(pTo, dSpecial[sx][sy]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawHTileLineX (int sx, int sy, int xp, int yp, int nd, int halfflag) +{ + int i; + BYTE *pTo; + int t; + WORD *mt; + + app_assert(gpBuffer); + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + if (gdwPNum = dPiece[sx][sy]) { + pTo = gpBuffer + nBuffWTbl[yp] + xp + 32; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 1; t < 17; t += 2) + { + if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + } + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub (pTo, sx, sy, xp, yp, FALSE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + sx++; + sy--; + xp += 64; + } + + nd -= halfflag; + for (i = 0; i < nd; i++) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gdwPNum = dPiece[sx][sy]; + if (gdwPNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 16; t+= 2) + { + if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[t+1]) DrawMTileClipBottom (pTo+32); + pTo -= NBUFFWSL5; + } + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub (pTo, sx, sy, xp, yp, TRUE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + sx++; + sy--; + xp += 64; + } + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gdwPNum = dPiece[sx][sy]; + if (gdwPNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 16; t+= 2) + { + if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + } + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub (pTo, sx, sy, xp, yp, FALSE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawEFlag2(BYTE *pTo2, int sx, int sy, int sv, int sv2, int xp, int yp) +{ + BYTE *pTo; + int t; + WORD *mt; + + if (sv == 0) pTo = pTo2; + else + pTo = pTo2 + (NBUFFWSL5 * sv); + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 6; t++) + { + if (sv <= t) { + if (gdwPNum = mt[2*t+2]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[2*t+3]) DrawMTileClipBottom (pTo+32); + } + pTo -= NBUFFWSL5; + } + + if (sv2 < 8) { + T_DrawHTLXsub2 (pTo2, sx, sy, sv, sv2, xp, yp, FALSE); + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +static void T_DrawHTLXsub2 (BYTE *pTo, int sx, int sy, int sv, int sv2, int xp, int yp, BOOL chflag) +{ + int pxp,pyp; + char bv; + int mi; + + if (dItem[sx][sy] != 0) { + bv = dItem[sx][sy] - 1; + pxp = xp - item[bv]._iAnimWidth2; + if (bv == cursitem) COutlineSlabCel(181, pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, sv2, 8); + CDrawSlabCel(pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, sv2, 8); + } + if ((dFlags[sx][sy] & BFLAG_MONSTLR) != 0) { + mi = -(dMonster[sx][sy-1] + 1); + pxp = xp - towner[mi]._tAnimWidth2; + pyp = yp; + if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8); + CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8); + } + if (dMonster[sx][sy] > 0) { + mi = dMonster[sx][sy] - 1; + pxp = xp - towner[mi]._tAnimWidth2; + pyp = yp; + if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8); + CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8); + } + if ((dFlags[sx][sy] & BFLAG_PLRLR) != 0) { + bv = -(dPlayer[sx][sy-1] + 1); + pxp = plr[bv]._pxoff + xp - plr[bv]._pAnimWidth2; + pyp = plr[bv]._pyoff + yp; + + #if RLE_DRAW + if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + DrawUnitClipped(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + #else + if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + CDrawSlabCel(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + #endif + + if (chflag) + { +// if (plr[bv]._peflag == 2) T_DrawEFlag2(pTo-NBUFFWSL4+96, sx-2, sy+1, sv, sv2, xp-96, yp-16); + if (plr[bv]._peflag != 0) T_DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp); + } + } + if (dFlags[sx][sy] & BFLAG_DEADPLR) + DrawDeadPlr(sx, sy, xp, yp, sv2, 8, TRUE); + if (dPlayer[sx][sy] > 0) { + bv = dPlayer[sx][sy] - 1; + pxp = plr[bv]._pxoff + xp - plr[bv]._pAnimWidth2; + pyp = plr[bv]._pyoff + yp; + + #if RLE_DRAW + if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + DrawUnitClipped(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + #else + if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + CDrawSlabCel(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8); + #endif + + if (chflag) + { +// if (plr[bv]._peflag == 2) T_DrawEFlag2(pTo-NBUFFWSL4+96, sx-2, sy+1, sv, sv2, xp-96, yp-16); + if (plr[bv]._peflag != 0) T_DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp); + } + } + if ((dFlags[sx][sy] & BFLAG_MISSILE) != 0) CDrawMissile(sx, sy, xp, yp, sv2, 8, FALSE); + if (dSpecial[sx][sy]) T_CDrawSpecial(pTo+nBuffWTbl[sv2<<4], dSpecial[sx][sy]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawHTLX2 (int sx, int sy, int xp, int yp, int nd, int sv, int halfflag) +{ + int i; + BYTE *pTo; + int sv2; + int t; + WORD *mt; + + app_assert(gpBuffer); + sv2 = (sv + 1) << 1; + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + if (gdwPNum = dPiece[sx][sy]) { + pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5 + 32; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 7; t++) + { + if ((sv <= t) && (gdwPNum = mt[2*t+3])) DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + } + + if (sv2 < 8) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, FALSE); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + sx++; + sy--; + xp += 64; + } + + nd -= halfflag; + for (i = 0; i < nd; i++) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gdwPNum = dPiece[sx][sy]; + if (gdwPNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + for(t = 0; t < 7; t++) + { + if (sv <= t) { + if (gdwPNum = mt[2*t+2]) DrawMTileClipBottom (pTo); + if (gdwPNum = mt[2*t+3]) DrawMTileClipBottom (pTo+32); + } + pTo -= NBUFFWSL5; + } + + if (sv2 < 8) { + pTo = gpBuffer + nBuffWTbl[yp] + xp - (sv2 * NBUFFWSL4); + T_DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, TRUE); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + sx++; + sy--; + xp += 64; + } + + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gdwPNum = dPiece[sx][sy]; + if (gdwPNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 7; t++) + { + if ((sv <= t) && (gdwPNum = mt[2*t+2])) DrawMTileClipBottom (pTo); + pTo -= NBUFFWSL5; + } + + if (sv2 < 8) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, FALSE); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TCDrawBlankMini(pTo); + } + } + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawEFlag3(BYTE *pTo2, int sx, int sy, int ev, int ev2, int xp, int yp) +{ + BYTE *pTo; + int t; + WORD *mt; + + pTo = pTo2; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 7; t++) + { + if (ev >= t) { + if (gdwPNum = mt[2*t]) DrawMTileClipTop (pTo); + if (gdwPNum = mt[2*t+1]) DrawMTileClipTop (pTo+32); + } + pTo -= NBUFFWSL5; + } + + T_DrawHTLXsub3 (pTo2, sx, sy, ev, ev2, xp, yp, FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +static void T_DrawHTLXsub3 (BYTE *pTo, int sx, int sy, int ev, int ev2, int xp, int yp, BOOL chflag) +{ + int pxp,pyp; + char bv; + int mi; + + if (dItem[sx][sy] != 0) { + bv = dItem[sx][sy] - 1; + pxp = xp - item[bv]._iAnimWidth2; + if (bv == cursitem) OutlineSlabCel(181, pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, ev2); + app_assert(item[bv]._iAnimData); + DrawSlabCel(pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, ev2); + } + if ((dFlags[sx][sy] & BFLAG_MONSTLR) != 0) { + mi = -(dMonster[sx][sy-1] + 1); + pxp = xp - towner[mi]._tAnimWidth2; + pyp = yp; + if (mi == cursmonst) OutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2); + app_assert(towner[mi]._tAnimData); + DrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2); + } + if (dMonster[sx][sy] > 0) { + mi = dMonster[sx][sy] - 1; + pxp = xp - towner[mi]._tAnimWidth2; + pyp = yp; + if (mi == cursmonst) OutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2); + app_assert(towner[mi]._tAnimData); + DrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2); + } + if ((dFlags[sx][sy] & BFLAG_PLRLR) != 0) { + bv = -(dPlayer[sx][sy-1] + 1); + pxp = plr[bv]._pxoff + xp - plr[bv]._pAnimWidth2; + pyp = plr[bv]._pyoff + yp; + + #if RLE_DRAW + if (bv == cursplr) DrawUnitOutline(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + app_assert(plr[bv]._pAnimData); + DrawUnit(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + #else + if (bv == cursplr) OutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + app_assert(plr[bv]._pAnimData); + DrawSlabCel(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + #endif + + if (chflag) + { +// if (plr[bv]._peflag == 2) T_DrawEFlag3(pTo-NBUFFWSL4-96, sx-2, sy+1, ev, ev2, xp-96, yp-16); + if (plr[bv]._peflag != 0) T_DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp); + } + } + if (dFlags[sx][sy] & BFLAG_DEADPLR) + DrawDeadPlr(sx, sy, xp, yp, 0, ev2, FALSE); + if (dPlayer[sx][sy] > 0) { + bv = dPlayer[sx][sy] - 1; + pxp = plr[bv]._pxoff + xp - plr[bv]._pAnimWidth2; + pyp = plr[bv]._pyoff + yp; + + #if RLE_DRAW + if (bv == cursplr) DrawUnitOutline(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + app_assert(plr[bv]._pAnimData); + DrawUnit(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + #else + if (bv == cursplr) OutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + app_assert(plr[bv]._pAnimData); + DrawSlabCel(pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2); + #endif + + if (chflag) + { +// if (plr[bv]._peflag == 2) T_DrawEFlag3(pTo-NBUFFWSL4-96, sx-2, sy+1, ev, ev2, xp-96, yp-16); + if (plr[bv]._peflag != 0) T_DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp); + } + } + if ((dFlags[sx][sy] & BFLAG_MISSILE) != 0) DrawMissile(sx, sy, xp, yp, 0, ev2, FALSE); + if (dSpecial[sx][sy]) T_DrawSpecial(pTo, dSpecial[sx][sy]); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawHTLX3 (int sx, int sy, int xp, int yp, int nd, int ev, int halfflag) +{ + int i; + BYTE *pTo; + int ev2; + int t; + WORD *mt; + + app_assert(gpBuffer); + ev2 = (ev + 1) << 1; + if (ev2 > 8) ev2 = 8; + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + if (gdwPNum = dPiece[sx][sy]) { + pTo = gpBuffer + nBuffWTbl[yp] + xp + 32; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 7; t++) + { + if ((ev >= t) && (gdwPNum = mt[2*t+1])) DrawMTileClipTop (pTo); + pTo -= NBUFFWSL5; + } + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, FALSE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TDrawBlankMini(pTo); + } + sx++; + sy--; + xp += 64; + } + + nd -= halfflag; + for (i = 0; i < nd; i++) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gdwPNum = dPiece[sx][sy]; + if (gdwPNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + for(t = 0; t < 7; t++) + { + if (ev >= t) { + if (gdwPNum = mt[2*t]) DrawMTileClipTop (pTo); + if (gdwPNum = mt[2*t+1]) DrawMTileClipTop (pTo+32); + } + pTo -= NBUFFWSL5; + } + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, TRUE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TDrawBlankMini(pTo); + } + sx++; + sy--; + xp += 64; + } + + if (halfflag != 0) { + if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) { + gdwPNum = dPiece[sx][sy]; + if (gdwPNum != 0) { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + mt = &dMT2[CalcRot(sx,sy)].mt[0]; + + for(t = 0; t < 7; t++) + { + if ((ev >= t) && (gdwPNum = mt[2*t])) DrawMTileClipTop (pTo); + pTo -= NBUFFWSL5; + } + + pTo = gpBuffer + nBuffWTbl[yp] + xp; + T_DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, FALSE); + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TDrawBlankMini(pTo); + } + } else { + pTo = gpBuffer + nBuffWTbl[yp] + xp; + TDrawBlankMini(pTo); + } + } + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_SVGADrawView (int StartX, int StartY) +{ + int xpos, ypos; + int i; + int width,height; + + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + + xpos = 64 + ScrollInfo._sxoff; + ypos = 175 + ScrollInfo._syoff; + StartX -= 10; + StartY -= 1; + width = 10; + height = 5; + + if (chrflag || questlog) { + StartX += 2; + StartY -= 2; + xpos += 288; + width = 6; + } + if (invflag || sbookflag) { + StartX += 2; + StartY -= 2; + xpos -= 32; + width = 6; + } + + switch (ScrollInfo._sdir) { + case SCRL_NONE : + break; + case SCRL_U : + ypos -= 32; + StartX--; + StartY--; + height++; + break; + case SCRL_UR : + ypos -= 32; + StartX--; + StartY--; + width++; + height++; + break; + case SCRL_R : + width++; + break; + case SCRL_DR : + width++; + height++; + break; + case SCRL_D : + height++; + break; + case SCRL_DL : + xpos -= 64; + StartX--; + StartY++; + width++; + height++; + break; + case SCRL_L : + xpos -= 64; + StartX--; + StartY++; + width++; + break; + case SCRL_UL : + xpos -= 64; + ypos -= 32; + StartX -= 2; + width++; + height++; + break; + } + + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[160]; + for (i = 0; i < 7; i++) { + T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 0); + StartY++; + xpos -= 32; + ypos += 16; + T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 1); + StartX++; + xpos += 32; + ypos += 16; + } + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[512]; + for (i = 0; i < height; i++) { + T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 0); + StartY++; + xpos -= 32; + ypos += 16; + T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 1); + StartX++; + xpos += 32; + ypos += 16; + } + for (i = 0; i < 7; i++) { + T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 0); + StartY++; + xpos -= 32; + ypos += 16; + T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 1); + StartX++; + xpos += 32; + ypos += 16; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_VGADrawView (int StartX, int StartY) +{ + int xpos, ypos; + int i; + int width,height; + long csrc, cdest, cw; + + ViewDX = 384; + ViewDY = 192; + ViewBX = 6; + ViewBY = 6; + + xpos = 64 + ScrollInfo._sxoff; + ypos = 143 + ScrollInfo._syoff; + StartX -= 6; + StartY -= 1; + width = 6; + height = 0; + + switch (ScrollInfo._sdir) { + case SCRL_NONE : + break; + case SCRL_U : + ypos -= 32; + StartX--; + StartY--; + height++; + break; + case SCRL_UR : + ypos -= 32; + StartX--; + StartY--; + width++; + height++; + break; + case SCRL_R : + width++; + break; + case SCRL_DR : + width++; + height++; + break; + case SCRL_D : + height++; + break; + case SCRL_DL : + xpos -= 64; + StartX--; + StartY++; + width++; + height++; + break; + case SCRL_L : + xpos -= 64; + StartX--; + StartY++; + width++; + break; + case SCRL_UL : + xpos -= 64; + ypos -= 32; + StartX -= 2; + width++; + height++; + break; + } + + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[143]; + for (i = 0; i < 7; i++) { + T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 0); + StartY++; + xpos -= 32; + ypos += 16; + T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 1); + StartX++; + xpos += 32; + ypos += 16; + } + app_assert(gpBuffer); + glClipY = (long)gpBuffer + nBuffWTbl[320]; + for (i = 0; i < height; i++) { + T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 0); + StartY++; + xpos -= 32; + ypos += 16; + T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 1); + StartX++; + xpos += 32; + ypos += 16; + } + for (i = 0; i < 7; i++) { + T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 0); + StartY++; + xpos -= 32; + ypos += 16; + T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 1); + StartX++; + xpos += 32; + ypos += 16; + } + + if (chrflag || questlog) { + csrc = 245168; + cdest = 392064; + cw = 160; + } else { + if (invflag || sbookflag) { + csrc = 245168; + cdest = 391744; + cw = 160; + } else { + csrc = 245088; + cdest = 391744; + cw = 320; + } + } + // Double res copy + app_assert(gpBuffer); + __asm { + mov esi,[gpBuffer] + mov edx,[cdest] + mov edi,esi + mov ecx,[csrc] + add edi,edx + add esi,ecx + mov ebx,edi + add ebx,768 + + mov edx,176 +_YLp: + mov ecx,[cw] +_XLp: + mov al,[esi] + inc esi + mov ah,al + mov [edi],ax + mov [ebx],ax + add edi,2 + add ebx,2 + dec ecx + jnz _XLp + mov eax,768 + add eax,[cw] + sub esi,eax + add eax,eax + sub ebx,eax + sub edi,eax + dec edx + jnz _YLp + } +/* // Double res copy (Old) + app_assert(gpBuffer); + __asm { + mov esi,dword ptr [gpBuffer] + mov edi,esi + add esi,dword ptr [csrc] + add edi,dword ptr [cdest] + mov ebx,edi + add ebx,768 + + mov edx,176 +_YLp: mov ecx,dword ptr [cw] +_XLp: lodsb + mov ah,al + stosw + mov word ptr [ebx],ax + add ebx,2 + loop _XLp + mov eax,768 + add eax,dword ptr [cw] + sub esi,eax + add eax,eax + sub ebx,eax + sub edi,eax + dec edx + jnz _YLp + }*/ +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_DrawView (int StartX, int StartY) +{ +/* __asm { + mov edi,dword ptr [gpBuffer] + add edi,122944 + + mov edx,352 + mov eax,092929292h // yellow + //xor eax,eax // black +_YLp: mov ecx,160 + rep stosd + add edi,128 + dec edx + jnz _YLp + }*/ + + // Non-town draw routines use nLVal and nTrans as global params, + // but in town all tiles are fully lit, and there are no transparent + // walls, so we set them here once for the whole screen + nLVal = 0; + nTrans = 0; + + if (svgamode) T_SVGADrawView (StartX, StartY); + else T_VGADrawView (StartX, StartY); + if (automapflag) DrawAutomap(); + if ((stextflag) && (!qtextflag)) DrawSText(); + if (invflag) DrawInv(); + else if (sbookflag) DrawSpellBook(); + + DrawDurIcon(); + + if (chrflag) DrawChr(); + else if (questlog) DrawQuestLog(); + else if ((plr[myplr]._pStatPts != 0) && (!spselflag)) DrawLevelUpIcon(); + + if (uitemflag) DrawUniqueInfo(); + if (qtextflag) DrawQText(); + if (spselflag) DrawSpellList(); + if (dropGoldFlag) DrawGoldBox(dropGoldValue); + if (helpflag) DrawHelp(); + if (msgflag) DrawDiabloMsg(); + if (PauseMode && !deathflag) DrawPause(); + + plrmsg_draw(); + + gmenu_draw(); + + DrawMapOfDoom(); + + DrawInfoBox(); + DrawHealthTop(); + DrawManaTop(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_SetDungeonMicros() +{ + int wv; + int i,j; + int t; + WORD *mtsource; + WORD *mt; + + // Init the light values for each piece + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + wv = dPiece[i][j]; + mt = &dMT2[CalcRot(i,j)].mt[0]; + if (wv != 0) { + wv--; + mtsource = (WORD *)(pMiniTiles + 32*wv); + for(t = 0; t < 16; t++) + // MiniTiles array uses opposite y direction + // hence wierd index on next line + mt[t] = mtsource[14-(t&0xe)+(t&1)]; + } else { + for(t = 0; t < 16; t++) + mt[t] = 0; + } + } + } + +#if 0 + int xmp,ymp,nPNum; + int s; + WORD tempmt[16]; + + // Zero micro tile values for each piece + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + mt = &dMT2[CalcRot(i,j)].mt[0]; + for(t = 0; t < 16; t++) + tempmt[t] = 0; + + nPNum = mt[0]; + if (((nPNum & 0x7000) == 0x4000) && (nPNum)) tempmt[0] = 1; + nPNum = mt[1]; + if (((nPNum & 0x7000) == 0x5000) && (nPNum != 0)) tempmt[1] = 1; + + for(t = 2; t < 16; t++) + { + nPNum = mt[t]; + if (((nPNum & 0x7000) == 0) && nPNum) + { + tempmt[t] = 1; + xmp = i; + ymp = j; + for(s = t-2; s >= 0 && xmp > 0 && ymp > 0; s -= 2) + { + xmp--; + ymp--; + dMT2[CalcRot(xmp,ymp)].mt[s] = 0; + } + } + } + + for(t = 0; t < 13; t += 2) + { + if(tempmt[t] && tempmt[t+2]) + { + xmp = i-1; + ymp = j; + for(s = t+1; s >= 0 && xmp >= 0 && ymp >= 0; s -= 2) + { + dMT2[CalcRot(xmp,ymp)].mt[s] = 0; + xmp--; + ymp--; + } + } + } + for(t = 1; t < 14; t += 2) + { + if(tempmt[t] && tempmt[t+2]) + { + xmp = i; + ymp = j-1; + for(s = t+1; s >= 0 && xmp >= 0 && ymp >= 0; s -= 2) + { + dMT2[CalcRot(xmp,ymp)].mt[s] = 0; + xmp--; + ymp--; + } + } + } + + } + } +#endif + + if (svgamode) { + ViewDX = 640; + ViewDY = 352; + ViewBX = 10; + ViewBY = 11; + } else { + ViewDX = 384; + ViewDY = 224; + ViewBX = 6; + ViewBY = 7; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_FillSector (BYTE *P3Tiles, BYTE *pSector, int xi, int yi, int w, int h) +{ + int i,j,xx,yy; + long v1,v2,v3,v4,ii; + + // Convert dungeon mega tiles to mini tiles + ii = 4; + yy = yi; + for (j = 0; j < h; j++) { + xx = xi; + for (i = 0; i < w; i++) { + __asm { + mov esi,dword ptr [pSector] + mov eax,dword ptr [ii] + add esi,eax + xor eax,eax + lodsw + or eax,eax + jz _Zero + dec eax + mov esi,dword ptr [P3Tiles] + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + jmp _Done +_Zero: mov dword ptr [v1],eax + mov dword ptr [v2],eax + mov dword ptr [v3],eax + mov dword ptr [v4],eax +_Done: nop + } + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; + xx += 2; + ii += 2; + } + yy += 2; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void T_FillTile(BYTE *P3Tiles, int xx, int yy, int t) +{ + long v1,v2,v3,v4; + + // Convert dungeon mega tiles to mini tiles + __asm { + mov eax,dword ptr [t] + dec eax + mov esi,dword ptr [P3Tiles] + shl eax,3 + add esi,eax + xor eax,eax + lodsw + inc eax + mov dword ptr [v1],eax + lodsw + inc eax + mov dword ptr [v2],eax + lodsw + inc eax + mov dword ptr [v3],eax + lodsw + inc eax + mov dword ptr [v4],eax + jmp _Done + mov dword ptr [v1],eax + mov dword ptr [v2],eax + mov dword ptr [v3],eax + mov dword ptr [v4],eax +_Done: nop + } + dPiece[xx][yy] = (int) v1; + dPiece[xx+1][yy] = (int) v2; + dPiece[xx][yy+1] = (int) v3; + dPiece[xx+1][yy+1] = (int) v4; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void OpenNest() +{ + dPiece[78][60] = 1162; // shadow at fork + dPiece[79][60] = 1163; + dPiece[78][61] = 1164; + dPiece[79][61] = 1294; + + dPiece[78][62] = 1262; // bridge + dPiece[78][63] = 1264; + dPiece[79][62] = 1296; + dPiece[79][63] = 1297; + + dPiece[79][64] = 1298; // second shadow + dPiece[78][64] = 282; + dPiece[78][65] = 284; + dPiece[79][65] = 285; + + dPiece[80][60] = 1299; // start tile of thing + dPiece[80][61] = 1301; + dPiece[81][61] = 1302; + + dPiece[82][60] = 1303; // second tile of thing + dPiece[83][60] = 1304; + dPiece[82][61] = 1305; + dPiece[83][61] = 1306; + + dPiece[80][62] = 1307; // third tile of thing + dPiece[81][62] = 1308; + dPiece[80][63] = 1309; + dPiece[81][63] = 1310; + + dPiece[80][64] = 1311; // forth tile of thing + dPiece[81][64] = 1312; + dPiece[80][65] = 1313; + dPiece[81][65] = 1314; + + dPiece[82][64] = 1319; // fifth tile of thing + dPiece[83][64] = 1320; + dPiece[82][65] = 1321; + dPiece[83][65] = 1322; + + dPiece[82][62] = 1315; // sixth tile of thing + dPiece[83][62] = 1316; + dPiece[82][63] = 1317; + dPiece[83][63] = 1318; + + dPiece[84][61] = 280; // remove tree + dPiece[84][62] = 280; + dPiece[84][63] = 280; +// dPiece[85][59] = 11; + dPiece[85][60] = 280; + dPiece[85][61] = 280; + dPiece[85][62] = 8; + dPiece[85][63] = 8; + dPiece[85][64] = 8; + dPiece[86][60] = 217; + dPiece[86][61] = 24; + dPiece[85][62] = 19; +// dPiece[86][62] = 11; +// dPiece[86][63] = 11; +// dPiece[86][64] = 11; + dPiece[84][64] = 280; +// dPiece[86][65] = 11; + T_SetDungeonMicros(); +} +void CloseNest() +{ + dPiece[78][60] = 1162; // shadow at fork + dPiece[79][60] = 1259; + dPiece[78][61] = 1260; + dPiece[79][61] = 1261; + + dPiece[78][62] = 1262; // bridge + dPiece[79][62] = 1263; + dPiece[78][63] = 1264; + dPiece[79][63] = 1265; + + dPiece[78][64] = 1266; // second shadow + dPiece[79][64] = 1267; + dPiece[78][65] = 1268; + + dPiece[80][60] = 1269; // start tile of thing + dPiece[81][60] = 1270; + dPiece[80][61] = 1271; + dPiece[81][61] = 1272; + + dPiece[82][60] = 1273; // second tile of thing + dPiece[83][60] = 1274; + dPiece[82][61] = 1275; + dPiece[83][61] = 1276; + + dPiece[80][62] = 1277; // third tile of thing + dPiece[81][62] = 1278; + dPiece[80][63] = 1279; + dPiece[81][63] = 1280; + + dPiece[80][64] = 1281; // forth tile of thing + dPiece[81][64] = 1282; + dPiece[80][65] = 1283; + dPiece[81][65] = 1284; + + dPiece[82][64] = 1289; // fifth tile of thing + dPiece[83][64] = 1290; + dPiece[82][65] = 1291; + dPiece[83][65] = 1292; + + dPiece[82][62] = 1285; // sixth tile of thing + dPiece[83][62] = 1286; + dPiece[82][63] = 1287; + dPiece[83][63] = 1288; + + dPiece[84][61] = 280; // remove tree + dPiece[84][62] = 280; + dPiece[84][63] = 280; +// dPiece[85][59] = 11; + dPiece[85][60] = 280; + dPiece[85][61] = 280; + dPiece[85][62] = 8; + dPiece[85][63] = 8; + dPiece[85][64] = 8; + dPiece[86][60] = 217; + dPiece[86][61] = 24; + dPiece[85][62] = 19; +// dPiece[86][62] = 11; +// dPiece[86][63] = 11; +// dPiece[86][64] = 11; + dPiece[84][64] = 280; +// dPiece[86][65] = 11; + T_SetDungeonMicros(); +} + +void CloseCrypt() +{ + dPiece[36][21] = 1323; + dPiece[37][21] = 1324; + dPiece[36][22] = 1325; + dPiece[37][22] = 1326; + + dPiece[36][23] = 1327; + dPiece[37][23] = 1328; + dPiece[36][24] = 1329; + dPiece[37][24] = 1330; + + dPiece[35][21] = 1339; + dPiece[34][21] = 1340; +// dPiece[34][22] = 1341; +// dPiece[35][22] = 1342; + + + T_SetDungeonMicros(); +} + +void OpenCrypt() +{ + dPiece[36][21] = 1331; + dPiece[37][21] = 1332; + dPiece[36][22] = 1333; + dPiece[37][22] = 1334; + + dPiece[36][23] = 1335; + dPiece[37][23] = 1336; + dPiece[36][24] = 1337; + dPiece[37][24] = 1338; + + dPiece[35][21] = 1339; + dPiece[34][21] = 1340; +// dPiece[34][22] = 1341; +// dPiece[35][22] = 1342; + + + T_SetDungeonMicros(); +} + +void T_Pass3() +{ + BYTE *P3Tiles; + BYTE *pSector; + int xx,yy; + + // Init Dungeon to blank + for (yy = 0; yy < DMAXY; yy+=2) { + for (xx = 0; xx < DMAXX; xx+=2) { + dPiece[xx][yy] = 0; + dPiece[xx+1][yy] = 0; + dPiece[xx][yy+1] = 0; + dPiece[xx+1][yy+1] = 0; + } + } + + // Load convertion tiles + P3Tiles = LoadFileInMemSig("Levels\\TownData\\Town.TIL",NULL,'TOWN'); + + // Load map sector + pSector = LoadFileInMemSig("Levels\\TownData\\Sector1s.DUN",NULL,'TOWN'); + T_FillSector(P3Tiles, pSector, 46, 46, 25, 25); + DiabloFreePtr(pSector); + + pSector = LoadFileInMemSig("Levels\\TownData\\Sector2s.DUN",NULL,'TOWN'); + T_FillSector(P3Tiles, pSector, 46, 0, 25, 23); + DiabloFreePtr(pSector); + + pSector = LoadFileInMemSig("Levels\\TownData\\Sector3s.DUN",NULL,'TOWN'); + T_FillSector(P3Tiles, pSector, 0, 46, 23, 25); + DiabloFreePtr(pSector); + + pSector = LoadFileInMemSig("Levels\\TownData\\Sector4s.DUN",NULL,'TOWN'); + T_FillSector(P3Tiles, pSector, 0, 0, 23, 23); + DiabloFreePtr(pSector); + +#ifdef TESTINGCRYPT + quests[Q_CRYPTMAP]._qactive = QUEST_DONE; +#endif + + +#if IS_VERSION(SHAREWARE) + // Close Maus shortcut + T_FillTile(P3Tiles, 48, 20, 320); + // Close cave shortcut + T_FillTile(P3Tiles, 16, 68, 332); + T_FillTile(P3Tiles, 16, 70, 331); + // Close crev shortcut + for (xx = 36; xx < 46; xx++) T_FillTile(P3Tiles, xx, 78, random(0,4)+1); +#else + if (gbMaxPlayers == 1) { + if ((quests[Q_FARMER]._qactive == QUEST_DONE) || (quests[Q_FARMER]._qactive == QUEST_REALLYDONE) + || (quests[Q_COWSUIT]._qactive == QUEST_DONE) || (quests[Q_COWSUIT]._qactive == QUEST_REALLYDONE)) + { + OpenNest(); + } + else + { + CloseNest(); + } + + if ((quests[Q_CRYPTMAP]._qactive != QUEST_DONE) && (!plr[myplr]._pLvlVisited[CRYPTSTART])) + CloseCrypt(); + else + OpenCrypt(); + + + // Close Maus shortcut + if (!((plr[myplr].pTownWarps & 0x01) || plr[myplr]._pLevel >= 10)) + T_FillTile(P3Tiles, 48, 20, 320); + // Close cave shortcut + if (!((plr[myplr].pTownWarps & 0x02) || plr[myplr]._pLevel >= 15)) + { + T_FillTile(P3Tiles, 16, 68, 332); + T_FillTile(P3Tiles, 16, 70, 331); + } + // Close crev shortcut or open or close or whatever is asked today + if (!((plr[myplr].pTownWarps & 0x04) || plr[myplr]._pLevel >= 20)) +// if (!(plr[myplr].pTownWarps & 0x04)) + { + for (xx = 36; xx < 46; xx++) + T_FillTile(P3Tiles, xx, 78, random(0,4)+1); + } + } + else + { + if ((quests[Q_FARMER]._qactive == QUEST_DONE) || (quests[Q_FARMER]._qactive == QUEST_REALLYDONE) + || (quests[Q_COWSUIT]._qactive == QUEST_DONE) || (quests[Q_COWSUIT]._qactive == QUEST_REALLYDONE)) + { + OpenNest(); + } + else + { + CloseNest(); + } + + if ((quests[Q_CRYPTMAP]._qactive != QUEST_DONE) && (!plr[myplr]._pLvlVisited[CRYPTSTART])) + CloseCrypt(); + else + OpenCrypt(); + } + +#endif + + if ((quests[Q_PWATER]._qactive == QUEST_DONE) || (quests[Q_PWATER]._qactive == QUEST_NOTAVAIL)) + T_FillTile(P3Tiles, 60, 70, 71); + else + T_FillTile(P3Tiles, 60, 70, 342); + + DiabloFreePtr(P3Tiles); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +extern int TWarpFrom; + +void CreateTown(int entry) +{ + int i,j; + + dminx = 10; + dminy = 10; + dmaxx = 84; + dmaxy = 84; + + if (entry == LVL_DOWN) { + ViewX = 75; // Your house + ViewY = 68; + } else { + if (entry == LVL_UP) { + ViewX = 25; // Near church + ViewY = 31; + } else { + if (entry == LVL_TWARPUP) { + if (TWarpFrom == 5) { + ViewX = 49; // Maus warp + ViewY = 22; + } + if (TWarpFrom == 9) { + ViewX = 18; // Cave warp + ViewY = 69; + } + if (TWarpFrom == 13) { + ViewX = 41; // Hell warp + ViewY = 81; + }// JKE add level up here. + if (TWarpFrom == CRYPTSTART) { + ViewX = 36; + ViewY = 25; + } + if (TWarpFrom == HIVESTART) { + ViewX = 79; + ViewY = 62; + } + } + } + } + + T_Pass3(); + + // Init the light values for each piece + ZeroMemory(dLight,sizeof(dLight)); + ZeroMemory(dFlags,sizeof(dFlags)); + ZeroMemory(dPlayer,sizeof(dPlayer)); + ZeroMemory(dMonster,sizeof(dMonster)); + ZeroMemory(dObject,sizeof(dObject)); + ZeroMemory(dItem,sizeof(dItem)); + ZeroMemory(dSpecial,sizeof(dSpecial)); + + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + int nPiece = dPiece[i][j]; + if (nPiece == 360) dSpecial[i][j] = 1; + else if (nPiece == 358) dSpecial[i][j] = 2; + else if (nPiece == 129) dSpecial[i][j] = 6; + else if (nPiece == 130) dSpecial[i][j] = 7; + else if (nPiece == 128) dSpecial[i][j] = 8; + else if (nPiece == 117) dSpecial[i][j] = 9; + else if (nPiece == 157) dSpecial[i][j] = 10; + else if (nPiece == 158) dSpecial[i][j] = 11; + else if (nPiece == 156) dSpecial[i][j] = 12; + else if (nPiece == 162) dSpecial[i][j] = 13; + else if (nPiece == 160) dSpecial[i][j] = 14; + else if (nPiece == 214) dSpecial[i][j] = 15; + else if (nPiece == 212) dSpecial[i][j] = 16; + else if (nPiece == 217) dSpecial[i][j] = 17; + else if (nPiece == 216) dSpecial[i][j] = 18; + } + } + + T_SetDungeonMicros(); +} diff --git a/TOWN.H b/TOWN.H new file mode 100644 index 0000000..817b8a6 --- /dev/null +++ b/TOWN.H @@ -0,0 +1,17 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/TOWN.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void CreateTown(int); + +void T_DrawView(int, int); diff --git a/TOWNERS.CPP b/TOWNERS.CPP new file mode 100644 index 0000000..19862cf --- /dev/null +++ b/TOWNERS.CPP @@ -0,0 +1,1458 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Town file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/TOWNERS.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "sound.h" +#include "engine.h" +#include "gendung.h" +#include "palette.h" + +#include "items.h" +#include "itemdat.h" +#include "inv.h" + +#include "player.h" +#include "monster.h" + +#include "town.h" +#include "quests.h" +#include "towners.h" +#include "minitext.h" +#include "textdat.h" +#include "stores.h" +#include "effects.h" +#include "multi.h" + +#include "cursor.h" +#include "msg.h" + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void SpawnSomething(int, int, int); +TownerStruct towner[MAX_TOWNERS]; +int numtowners; +BOOL storeflag; +BOOL boyloadflag; +BOOL bannerflag; + +char AnimOrder[6][148] = { +{ 5,6,7,8,9,10,11,12,13,14,14,13,12,11,10,9,8,7,6,5,5,6,7,8,9,10,11,12,13,14,14,13,12,11,10,9,8,7,6,5,5,6,7,8,9,10,11,12,13,14,14,13,12,11,10,9,8,7,6,5,5,6,7,8,9,10,11,12,13,14,14,13,12,11,10,9,8,7,6,5,5,6,7,8,9,10,11,12,13,14,14,13,12,11,10,9,8,7,6,5,5,6,7,8,9,10,11,12,13,14,15,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,4,-1 }, // Blacksmith +{ 1,2,3,3,2,1,20,19,19,20,1,2,3,3,2,1,20,19,19,20,1,2,3,3,2,1,20,19,19,20,1,2,3,3,2,1,20,19,19,20,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,15,14,13,12,11,10,9,8,7,6,5,4,5,6,7,8,9,10,11,12,13,14,15,16,15,14,13,12,11,10,9,8,7,6,5,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,-1 }, // Healer +{ 1,1,25,25,24,23,22,21,20,19,18,17,16,15,16,17,18,19,20,21,22,23,24,25,25,25,1,1,1,25,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,-1 }, // Storyteller +{ 1,2,3,3,2,1,16,15,14,14,16,1,2,3,3,2,1,16,15,14,14,15,16,1,2,3,3,2,1,16,15,14,14,15,16,1,2,3,3,2,1,16,15,14,14,15,16,1,2,3,3,2,1,16,15,14,14,15,16,1,2,3,3,2,1,16,15,14,14,15,16,1,2,3,3,2,1,16,15,14,14,15,16,1,2,3,2,1,16,15,14,14,15,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,-1 }, // Innkeeper +{ 1,1,1,2,3,4,5,6,7,8,9,10,11,11,11,11,12,13,14,15,16,17,18,18,1,1,1,18,17,16,15,14,13,12,11,10,11,12,13,14,15,16,17,18,1,2,3,4,5,5,5,4,3,2,-1 }, // Towndrunk +{ 4,4,4,5,6,6,6,5,4,15,14,13,13,13,14,15,4,5,6,6,6,5,4,4,4,5,6,6,6,5,4,15,14,13,13,13,14,15,4,5,6,6,6,5,4,4,4,5,6,6,6,5,4,15,14,13,13,13,14,15,4,5,6,6,6,5,4,3,2,1,19,18,19,1,2,1,19,18,19,1,2,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,15,14,13,13,13,13,14,15,15,15,14,13,12,12,12,11,10,10,10,9,8,9,10,10,11,12,13,14,15,16,17,18,19,1,2,1,19,18,19,1,2,1,2,3,-1 } // Witch +}; + +/*-----------------------------------------------------------------------*/ + +#define TOWN_NUMCOWS 3 + + +#define COW // turns off cow quest JKECOW + +BYTE *pCowCels; +int TownCowX[] = { 58, 56, 59 }; +int TownCowY[] = { 16, 14, 20 }; +int TownCowDir[] = { DIR_DL, DIR_UL, DIR_U }; + +int cowoffx[8] = { -1, 0, -1, -1, -1, 0, -1, -1 }; +int cowoffy[8] = { -1, -1, -1, 0, -1, -1, -1, 0 }; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +int Qtalklist[14][MAXQUESTS] = { +// Q_ROCK Q_BKMUSHRM Q_GARBUD Q_ZHAR Q_VEIL Q_DIABLO Q_BUTCHER Q_LTBANNER Q_BLIND Q_BLOOD Q_ANVIL Q_WARLORD Q_SKELKING Q_PWATER Q_SCHAMB Q_BETRAYER Q_CRYPTMAP Q_FARMER Q_THEO Q_TRADER Q_DEFILER Q_NA_KRUL Q_CORNERSTONE Q_COWSUIT + { TXT_INFRABS2, TXT_BLKMBS1, -1, -1, TXT_VEILBS1, -1, TXT_BUTCHBS1, TXT_BOLBS1, TXT_BLINDBS1, TXT_BLOODBS1, TXT_ANVILBS2, TXT_WARLRDBS1, TXT_KINGBS1, TXT_PWBS1, TXT_BONEBS1, TXT_VBBS1, TXT_CRYPTMAP2, -1, -1, -1, -1, -1, -1, -1 }, // black smith + { TXT_INFRAH1, -1, -1, -1, TXT_VEILH1, -1, TXT_BUTCHH1, TXT_BOLH1, TXT_BLINDH1, TXT_BLOODH1, TXT_ANVILH1, TXT_WARLRDH1, TXT_KINGH1, TXT_PWH2, TXT_BONEH1, TXT_VBH1, TXT_CRYPTMAP3, -1, -1, -1, -1, -1, -1, -1 }, // healer + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // dead guy + { TXT_INFRATO1, TXT_BLKMTO1, -1, -1, TXT_VEILTO1, -1, TXT_BUTCHTO1, -1, TXT_BLINDTO1, TXT_BLOODTO1, TXT_ANVILTO1, TXT_WARLRDTO1, TXT_KINGTO2, TXT_PWTO1, TXT_BONETO1, TXT_VBTO1, TXT_CRYPTMAP5, -1, -1, -1, -1, -1, -1, -1 }, // tavern owner + { TXT_INFRAST1, TXT_BLKMST1, -1, -1, TXT_VEILST1, TXT_VBST3, TXT_BUTCHST1, TXT_BOLST1, TXT_BLINDST1, TXT_BLOODST1, TXT_ANVILST1, TXT_WARLRDST1, TXT_KINGST1, TXT_PWST1, TXT_BONEST1, TXT_VBST2, TXT_CRYPTMAP6, -1, -1, -1, -1, -1, -1, -1 }, // storyteller + { TXT_INFRATD1, TXT_BLKMTD1, -1, -1, TXT_VEILTD1, -1, TXT_BUTCHTD1, TXT_BOLTD1, TXT_BLINDTD1, TXT_BLOODTD1, TXT_ANVILTD1, TXT_WARLRDTD1, TXT_KINGTD1, TXT_PWTD1, TXT_BONETD1, TXT_VBTD1, TXT_CRYPTMAP7, -1, -1, -1, -1, -1, -1, -1 }, // town drunk + { TXT_INFRAW1, TXT_BLKMW2, -1, -1, TXT_VEILW1, -1, TXT_BUTCHW1, TXT_BOLW1, TXT_BLINDW1, TXT_BLOODW1, TXT_ANVILW1, TXT_WARLRDW1, TXT_KINGW1, TXT_PWW1, TXT_BONEW1, TXT_VBW1, TXT_CRYPTMAP1, -1, -1, -1, -1, -1, -1, -1 }, // witch + { TXT_INFRABM1, TXT_BLKMBM1, -1, -1, TXT_VEILBM1, -1, TXT_BUTCHBM1, TXT_BOLBM1, TXT_BLINDBM1, TXT_BLOODBM1, TXT_ANVILBM1, TXT_WARLRDBM1, TXT_KINGBM1, TXT_PWBM1, TXT_BONEBM1, TXT_VBBM1, TXT_CRYPTMAP8, -1, -1, -1, -1, -1, -1, -1 }, // barmaid + { TXT_INFRAPB1, TXT_BLKMPB1, -1, -1, TXT_VEILPB1, -1, TXT_BUTCHPB1, TXT_BOLPB1, TXT_BLINDPB1, TXT_BLOODPB1, TXT_ANVILPB1, TXT_WARLRDPB1, TXT_KINGPB1, TXT_PWPB1, TXT_BONEPB1, TXT_VBPB1, TXT_CRYPTMAP9, -1, -1, -1, -1, -1, -1, -1 }, // peg-legged boy + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // cow + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Farmer + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Little Girl + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // cow suit guy + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // traveling salesman +}; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +int GetActiveTowner(int t) { + for (int i = 0; i < numtowners; i++) { + if (towner[i]._ttype == t) return(i); + } + return(-1); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void SetTownerGPtrs(BYTE *pData, BYTE *pAnim[]) { + BYTE *p; + int i; + + for (i = 0; i < 8; i++) { + p = pData; + __asm { + mov eax,dword ptr [p] + mov ebx,eax + mov edx,dword ptr [i] + shl edx,2 + add ebx,edx + mov edx,dword ptr [ebx] + add eax,edx + mov dword ptr [p],eax + } + pAnim[i] = p; + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void NewTownerAnim(int tnum, BYTE *pAnim, int numFrames, int Delay) +{ + app_assert(pAnim); + towner[tnum]._tAnimData = pAnim; + towner[tnum]._tAnimLen = numFrames; + towner[tnum]._tAnimFrame = 1; + towner[tnum]._tAnimCnt = 0; + towner[tnum]._tAnimDelay = Delay; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void InitTownerInfo(int i, long w, BOOL sel, int t, int x, int y, char ao, int tp) +{ + ZeroMemory(&towner[i],sizeof(TownerStruct)); + towner[i]._tSelFlag = sel; + towner[i]._tAnimWidth = w; + towner[i]._tAnimWidth2 = (w - 64) >> 1; + towner[i]._tMsgSaid = FALSE; + towner[i]._ttype = t; + towner[i]._tx = x; + towner[i]._ty = y; + dMonster[x][y] = i + 1; + towner[i]._tAnimOrder = ao; + towner[i]._tTenPer = tp; + towner[i]._tSeed = GetRndSeed(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitQstSnds(int i) +{ + int j = i; + + if (boyloadflag) j = i+1; + for (int quest = 0; quest < MAXQUESTS; quest++) { + towner[i].qsts[quest]._qsttype = quests[quest]._qtype; + towner[i].qsts[quest]._qstmsg = Qtalklist[j][quest]; + if (Qtalklist[j][quest] != -1) towner[i].qsts[quest]._qstmsgact = QSTMSG_AVAIL; + else towner[i].qsts[quest]._qstmsgact = QSTMSG_NOTAVAIL; + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitSmith() +{ + InitTownerInfo(numtowners, 96, TRUE, TWN_BLKSMITH, 62, 63, 0, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Smith\\SmithN.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 16; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_DL], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Griswold the Blacksmith"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitBarOwner() +{ + bannerflag = FALSE; + InitTownerInfo(numtowners, 96, TRUE, TWN_BAROWNER, 55, 62, 3, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\TwnF\\TwnFN.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 16; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_DL], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Ogden the Tavern owner"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitTownDead() { + InitTownerInfo(numtowners, 96, TRUE, TWN_DEAD, 24, 32, -1, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Butch\\Deadguy.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 8; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_U], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Wounded Townsman"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitWitch() { + InitTownerInfo(numtowners, 96, TRUE, TWN_WITCH, 80, 20, 5, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\TownWmn1\\Witch.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 19; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_D], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Adria the Witch"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitBarmaid() { + InitTownerInfo(numtowners, 96, TRUE, TWN_BARMAID, 43, 66, -1, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\TownWmn1\\WmnN.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 18; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_D], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Gillian the Barmaid"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitBoy() { + boyloadflag = TRUE; + InitTownerInfo(numtowners, 96, TRUE, TWN_BOY, 11, 53, -1, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\TownBoy\\PegKid1.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 20; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_D], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Wirt the Peg-legged boy"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitHealer() { + InitTownerInfo(numtowners, 96, TRUE, TWN_HEALER, 55, 79, 1, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Healer\\Healer.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 20; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_DR], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Pepin the Healer"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitTeller() +{ + InitTownerInfo(numtowners, 96, TRUE, TWN_TELLER, 62, 71, 2, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Strytell\\Strytell.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 25; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_D], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Cain the Elder"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitDrunk() { + InitTownerInfo(numtowners, 96, TRUE, TWN_DRUNK, 71, 84, 4, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Drunk\\TwnDrunk.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 18; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_D], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Farnham the Drunk"); + numtowners++; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void InitCows() +{ + int i, x, y, d, x2, y2; + + app_assert(! pCowCels); + pCowCels = LoadFileInMemSig("Towners\\Animals\\Cow.CEL",NULL,'TOWN'); + + for (i = 0; i < TOWN_NUMCOWS; i++) { + x = TownCowX[i]; + y = TownCowY[i]; + d = TownCowDir[i]; + InitTownerInfo(numtowners, 128, FALSE, TWN_COW, x, y, -1, 10); + towner[numtowners]._tNData = pCowCels; + SetTownerGPtrs(towner[numtowners]._tNData, towner[numtowners]._tNAnim); + towner[numtowners]._tNFrames = 12; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[d], towner[numtowners]._tNFrames, 3); + towner[numtowners]._tAnimFrame = random(0,11) + 1; + towner[numtowners]._tSelFlag = TRUE; + strcpy(towner[numtowners]._tName, "Cow"); + x2 = x + cowoffx[d]; + y2 = y + cowoffy[d]; + if (dMonster[x][y2] == 0) dMonster[x][y2] = -(numtowners + 1); + if (dMonster[x2][y] == 0) dMonster[x2][y] = -(numtowners + 1); + if (dMonster[x2][y2] == 0) dMonster[x2][y2] = -(numtowners + 1); + numtowners++; + } +} + +// JKENEWTOWNER INIT INFO HERE +void InitFarmer() +{ + InitTownerInfo(numtowners, 96, TRUE, TWN_FARMER, 62, 16, -1, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Farmer\\Farmrn2.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 15; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_D], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Lester the farmer"); + numtowners++; +} +void InitCowsuit() +{ + InitTownerInfo(numtowners, 96, TRUE, TWN_COWSUIT, 61, 22, -1, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + if(quests[Q_COWSUIT]._qactive != QUEST_DONE) + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Farmer\\cfrmrn2.CEL",NULL,'TOWN'); + else + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Farmer\\mfrmrn2.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 15; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_DL], towner[numtowners]._tNFrames, 3); + strcpy(towner[numtowners]._tName, "Complete Nut"); + numtowners++; + +} +void InitGirl() +{ + InitTownerInfo(numtowners, 96, TRUE, TWN_GIRL, 77, 43, -1, 10); + app_assert(! towner[numtowners]._tNData); + InitQstSnds(numtowners); + if (quests[Q_THEO]._qactive != QUEST_DONE) + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Girl\\Girlw1.CEL",NULL,'TOWN'); + else + towner[numtowners]._tNData = LoadFileInMemSig("Towners\\Girl\\Girls1.CEL",NULL,'TOWN'); + for (int i = 0; i < 8; i++) towner[numtowners]._tNAnim[i] = towner[numtowners]._tNData; + towner[numtowners]._tNFrames = 20; + NewTownerAnim(numtowners, towner[numtowners]._tNAnim[DIR_D], towner[numtowners]._tNFrames, 6); + strcpy(towner[numtowners]._tName, "Celia"); + numtowners++; +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitTowners() //when adding any towners add the init in order of the defines +{ + numtowners = 0; + boyloadflag = FALSE; + InitSmith(); + InitHealer(); + if (quests[Q_BUTCHER]._qactive != QUEST_NOTAVAIL && quests[Q_BUTCHER]._qactive != QUEST_DONE) + InitTownDead(); + InitBarOwner(); + InitTeller(); + InitDrunk(); + InitWitch(); + InitBarmaid(); + InitBoy(); + // From here down, not controled, only animated + InitCows(); + // HELLFIRE INIT JKENEWTOWNERS + + if (gbCowsuit) + { + InitCowsuit(); + } + else + { + if (quests[Q_FARMER]._qactive != QUEST_REALLYDONE) + InitFarmer(); + } + + if (gbTheo) + if (plr[0]._pLvlVisited[HIVESTART]) + InitGirl(); + +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void FreeTownerGFX() { + int i; + + for (i = 0; i < MAX_TOWNERS; i++) { + if (towner[i]._tNData == pCowCels) { + // don't free + towner[i]._tNData = NULL; + } + else if (towner[i]._tNData) { + DiabloFreePtr(towner[i]._tNData); + } + } + + // now free cow cels + DiabloFreePtr(pCowCels); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownCtrlMsg(int i) +{ + if (towner[i]._tbtcnt != 0) { + int const p = towner[i]._tVar1; + int const dx = abs(towner[i]._tx - plr[p]._px); + int const dy = abs(towner[i]._ty - plr[p]._py); + if ((dx >= 2) || (dy >= 2)) + { + towner[i]._tbtcnt = 0; + qtextflag = FALSE; + stream_stop(); + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownBlackSmith() +{ + int const tidx = GetActiveTowner(TWN_BLKSMITH); + TownCtrlMsg(tidx); +#if 0 + if ((!qtextflag) && quests[Q_ROCK]._qactive == QUEST_DONE) { + int const x = towner[tidx]._tx; + int const y = towner[tidx]._ty + 1; + if (dPlayer[x][y] > 0) x++; + } +#endif +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownBarOwner() +{ + int const tidx = GetActiveTowner(TWN_BAROWNER); + TownCtrlMsg(tidx); +#if 0 + if ((!qtextflag) && (quests[Q_LTBANNER]._qactive == QUEST_DONE) && (bannerflag)) { + int const x = towner[tidx]._tx; + int const y = towner[tidx]._ty + 1; + if (dPlayer[x][y] > 0) x++; + } +#endif +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownDead() +{ + int const tidx = GetActiveTowner(TWN_DEAD); + TownCtrlMsg(tidx); + if (!qtextflag) { + if ((quests[Q_BUTCHER]._qactive == QUEST_NOTDONE) && (!quests[Q_BUTCHER]._qlog)) return; + if (quests[Q_BUTCHER]._qactive != QUEST_NOTACTIVE) { + towner[tidx]._tAnimDelay = 1000; + towner[tidx]._tAnimFrame = 1; + strcpy(towner[tidx]._tName, "Slain Townsman"); + } + } + if (quests[Q_BUTCHER]._qactive != QUEST_NOTACTIVE) towner[tidx]._tAnimCnt = 0; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownHealer() +{ + int const tidx = GetActiveTowner(TWN_HEALER); + TownCtrlMsg(tidx); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownStory() +{ + + int const tidx = GetActiveTowner(TWN_TELLER); + TownCtrlMsg(tidx); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownDrunk() +{ + + int const tidx = GetActiveTowner(TWN_DRUNK); + TownCtrlMsg(tidx); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownBoy() +{ + + int const tidx = GetActiveTowner(TWN_BOY); + TownCtrlMsg(tidx); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownWitch() +{ + + int const tidx = GetActiveTowner(TWN_WITCH); + TownCtrlMsg(tidx); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownBarMaid() +{ + int const tidx = GetActiveTowner(TWN_BARMAID); + TownCtrlMsg(tidx); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void TownCow() +{ + + int const tidx = GetActiveTowner(TWN_COW); + TownCtrlMsg(tidx); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +// add helfire characters here + +void Farmer() +{ + int const tidx = GetActiveTowner(TWN_FARMER); + TownCtrlMsg(tidx); +} + +void Cowsuit() +{ + int const tidx = GetActiveTowner(TWN_COWSUIT); + TownCtrlMsg(tidx); +} + +void Girl() +{ + int const tidx = GetActiveTowner(TWN_GIRL); + TownCtrlMsg(tidx); +} + + +void ProcessTowners() +{ + int i; + + for (i = 0; i < MAX_TOWNERS; ++i) { + switch (towner[i]._ttype) { + case TWN_BLKSMITH : + TownBlackSmith(); + break; + case TWN_HEALER : + TownHealer(); + break; + case TWN_DEAD : + TownDead(); + break; + case TWN_BAROWNER : + TownBarOwner(); + break; + case TWN_TELLER : + TownStory(); + break; + case TWN_DRUNK : + TownDrunk(); + break; + case TWN_BOY : + TownBoy(); + break; + case TWN_WITCH : + TownWitch(); + break; + case TWN_BARMAID : + TownBarMaid(); + break; + case TWN_COW : + TownCow(); + break; + case TWN_FARMER: + Farmer(); + break; + case TWN_GIRL: + Girl(); + break; + case TWN_COWSUIT: + Cowsuit(); + break; + } + + // Animate Towner + ++towner[i]._tAnimCnt; + if (towner[i]._tAnimCnt >= towner[i]._tAnimDelay) { + towner[i]._tAnimCnt = 0; + if (towner[i]._tAnimOrder >= 0) { + int const ao = towner[i]._tAnimOrder; + ++towner[i]._tAnimFrameCnt; + if (AnimOrder[ao][towner[i]._tAnimFrameCnt] == -1) towner[i]._tAnimFrameCnt = 0; + towner[i]._tAnimFrame = AnimOrder[ao][towner[i]._tAnimFrameCnt]; + } else { + ++towner[i]._tAnimFrame; + if (towner[i]._tAnimFrame > towner[i]._tAnimLen) towner[i]._tAnimFrame = 1; + } + } + } +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +ItemStruct *PlrHasItem(int pnum, int item, int &i) +{ + for (i = 0; i < plr[pnum]._pNumInv; ++i) { + if (plr[pnum].InvList[i].IDidx == item) + return &plr[pnum].InvList[i]; + } + return FALSE; +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +static DWORD sgdwCowClicks; +static int sgnCowMsg; +static void CowSFX(int pnum) { + #if !IS_VERSION(SHAREWARE) + #define NUM_COW_SFX 3 + static const int snSFX[NUM_COW_SFX][NUM_CLASSES] = { + { PS_WARR52, PS_ROGUE52, PS_MAGE52, PS_MONK52, PS_BARD52 }, // yup, that's a cow + { PS_WARR49, PS_ROGUE49, PS_MAGE49, PS_MONK49, PS_BARD49 }, // I'm not thirsty + { PS_WARR50, PS_ROGUE50, PS_MAGE50, PS_MONK50, PS_BARD50 }, // I'm no milkmaid + }; + #endif + + // make sure we're not still playing the last cow SFX + static int snLastCowSFX = -1; + BOOL effect_is_playing(int nSFX); + if (snLastCowSFX != -1 && effect_is_playing(snLastCowSFX)) + return; + + // next cow sound + sgdwCowClicks++; + #if !IS_VERSION(SHAREWARE) + if (sgdwCowClicks >= 8) { + // play cow in background + PlaySfxLoc(TSFX_COW1, plr[pnum]._px, plr[pnum]._py + 5); + + // reset cow counter + sgdwCowClicks = 4; + + // choose player cow sfx + snLastCowSFX = snSFX[sgnCowMsg][plr[pnum]._pClass]; + if (++sgnCowMsg >= NUM_COW_SFX) sgnCowMsg = 0; + } + else + #endif + if (sgdwCowClicks == 4) { + #if IS_VERSION(SHAREWARE) + sgdwCowClicks = 0; + #endif + snLastCowSFX = TSFX_COW2; + } + else { + snLastCowSFX = TSFX_COW1; + } + + PlaySfxLoc(snLastCowSFX,plr[pnum]._px,plr[pnum]._py); +} + + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ +void TownerTalk(int first, int t) +{ + // reset cow counter + sgdwCowClicks = 0; + sgnCowMsg = 0; + + storeflag = TRUE; + InitQTextMsg(first); +} + +/*-----------------------------------------------------------------------* +**-----------------------------------------------------------------------*/ + +void TalkToTowner(int p, int t) +{ + int i; + int dx, dy; + int r3, r4, r5; + ItemStruct *Item; + + r3 = random(6, 3); + r4 = random(6, 4); + r5 = random(6, 5); + dx = abs(plr[p]._px - towner[t]._tx); + dy = abs(plr[p]._py - towner[t]._ty); +#if CHEATS + if ((!davedebug) && ((dx >= 2) || (dy >= 2))) return; +#else + if ((dx >= 2) || (dy >= 2)) return; +#endif + if (qtextflag) return; + towner[t]._tMsgSaid = FALSE; + + //Does player have item in hand? If so, drop it before talking to town person. + if (curs >= ICSTART) { + if(!DropItemBeforeTrig()) return; + } + +/*-----Tavern Owner------------------------------------------------------*/ + if (t == GetActiveTowner(TWN_BAROWNER)) { + if (!(plr[p]._pLvlVisited[0]) && !(towner[t]._tMsgSaid)) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_INTRO); + towner[t]._tMsgSaid = TRUE; + } + if ((plr[p]._pLvlVisited[2] || plr[p]._pLvlVisited[4]) && (quests[Q_SKELKING]._qactive != QUEST_NOTAVAIL)) { + // skel king init + if ((quests[Q_SKELKING]._qactive != QUEST_NOTAVAIL) && (quests[Q_SKELKING]._qvar2 == 0) && (!towner[t]._tMsgSaid)) { + quests[Q_SKELKING]._qvar2 = 1; + quests[Q_SKELKING]._qlog = TRUE; + if (quests[Q_SKELKING]._qactive == QUEST_NOTACTIVE) { + quests[Q_SKELKING]._qactive = QUEST_NOTDONE; + quests[Q_SKELKING]._qvar1 = 1; // state of quest + } + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_KINGTO1); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_SKELKING); + } + // skel king finished + if ((quests[Q_SKELKING]._qactive == QUEST_DONE) && (quests[Q_SKELKING]._qvar2 == 1) && (!towner[t]._tMsgSaid)) { + quests[Q_SKELKING]._qvar2 = 2; + quests[Q_SKELKING]._qvar1 = 2; // state of quest + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_KINGTO3); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_SKELKING); + } + } + + if (gbMaxPlayers == 1) { + // banner of light init + if ((plr[p]._pLvlVisited[3]) && (quests[Q_LTBANNER]._qactive != QUEST_NOTAVAIL)) { + if ((quests[Q_LTBANNER]._qactive == QUEST_NOTACTIVE) || (quests[Q_LTBANNER]._qactive == QUEST_NOTDONE)) { + if ((quests[Q_LTBANNER]._qvar2 == 0) && (!towner[t]._tMsgSaid)) { + quests[Q_LTBANNER]._qvar2 = 1; + if (quests[Q_LTBANNER]._qactive == QUEST_NOTACTIVE) { + quests[Q_LTBANNER]._qvar1 = 1; // state of quest + quests[Q_LTBANNER]._qactive = QUEST_NOTDONE; + } + quests[Q_LTBANNER]._qlog = TRUE; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_BOLTO1); + towner[t]._tMsgSaid = TRUE; + } + } + } + // banner of light finished + if ((!towner[t]._tMsgSaid) && PlrHasItem(p, IDI_BANNER, i)) { + quests[Q_LTBANNER]._qactive = QUEST_DONE; + quests[Q_LTBANNER]._qvar1 = 3; + RemoveInvItem(p, i); + CreateItem(UID_HARCREST, towner[t]._tx, towner[t]._ty + 1); // Harlequin Crest + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_BOLTO2); + towner[t]._tMsgSaid = TRUE; + } + } + if (!qtextflag) { + TownerTalk(TXT_OGDEN1, t); + if(storeflag) StartStore(STORE_TAVERN); + } + } + +/*-----Nearly dead guy---------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_DEAD)) { + if ((quests[Q_BUTCHER]._qactive == QUEST_NOTDONE) && (quests[Q_BUTCHER]._qvar1 == 1)) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_BUTCHER]._qvar1 = 1; + #if !IS_VERSION(SHAREWARE) + BOOL effect_is_playing(int nSFX); + if ((plr[p]._pClass == CLASS_WARRIOR) && !effect_is_playing(PS_WARR8)) PlaySFX(PS_WARR8); + else if ((plr[p]._pClass == CLASS_ROGUE) && !effect_is_playing(PS_ROGUE8)) PlaySFX(PS_ROGUE8); + else if ((plr[p]._pClass == CLASS_SORCEROR) && !effect_is_playing(PS_MAGE8)) PlaySFX(PS_MAGE8); + else if ((plr[p]._pClass == CLASS_MONK) && !effect_is_playing(PS_MONK8)) PlaySFX(PS_MONK8); + else if ((plr[p]._pClass == CLASS_BARD) && !effect_is_playing(PS_BARD8)) PlaySFX(PS_BARD8); + else if ((plr[p]._pClass == CLASS_BARBARIAN) && !effect_is_playing(PS_BARBARIAN8)) PlaySFX(PS_BARBARIAN8); + #endif + towner[t]._tMsgSaid = TRUE; + } + else if ((quests[Q_BUTCHER]._qactive == QUEST_DONE) && (quests[Q_BUTCHER]._qvar1 == 1)) { + /* #if !IS_VERSION(SHAREWARE) + BOOL effect_is_playing(int nSFX); + if ((plr[p]._pClass == CLASS_WARRIOR) && !effect_is_playing(PS_WARR9)) PlaySFX(PS_WARR9); + else if ((plr[p]._pClass == CLASS_ROGUE) && !effect_is_playing(PS_ROGUE9)) PlaySFX(PS_ROGUE9); + else if ((plr[p]._pClass == CLASS_SORCEROR) && !effect_is_playing(PS_MAGE9)) PlaySFX(PS_MAGE9); + else if ((plr[p]._pClass == CLASS_MONK) && !effect_is_playing(PS_MONK9)) PlaySFX(PS_MONK9); + else if ((plr[p]._pClass == CLASS_BARD) && !effect_is_playing(PS_BARD9)) PlaySFX(PS_BARD9); + else if ((plr[p]._pClass == CLASS_BARBARIAN) && !effect_is_playing(PS_BARBARIAN9)) PlaySFX(PS_BARBARIAN9); + #endif + */ + //InitQTextMsg(5); + quests[Q_BUTCHER]._qvar1 = 1; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + towner[t]._tMsgSaid = TRUE; + } + + else if ((quests[Q_BUTCHER]._qactive == QUEST_NOTACTIVE) || + ((quests[Q_BUTCHER]._qactive == QUEST_NOTDONE) && (!quests[Q_BUTCHER]._qvar1))) { + quests[Q_BUTCHER]._qactive = QUEST_NOTDONE; + quests[Q_BUTCHER]._qlog = TRUE; + quests[Q_BUTCHER]._qmsg = TXT_BUTCH1; + quests[Q_BUTCHER]._qvar1 = 1; + towner[t]._tbtcnt = 50; + towner[t]._tVar1 = p; + towner[t]._tVar2 = 3; + InitQTextMsg(TXT_BUTCH1); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_BUTCHER); + } + } +/*-----Blacksmith-------------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_BLKSMITH)) { + if (gbMaxPlayers == 1) { + // magic rock init + if ((plr[p]._pLvlVisited[4]) && (quests[Q_ROCK]._qactive != QUEST_NOTAVAIL)) { + if ((quests[Q_ROCK]._qactive != QUEST_NOTAVAIL) && (quests[Q_ROCK]._qvar2 == 0)) { + quests[Q_ROCK]._qvar2 = 1; + quests[Q_ROCK]._qlog = TRUE; + if (quests[Q_ROCK]._qactive == QUEST_NOTACTIVE) { + quests[Q_ROCK]._qactive = QUEST_NOTDONE; + quests[Q_ROCK]._qvar1 = 1; // state + } + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_INFRABS1); + towner[t]._tMsgSaid = TRUE; + } + } + // magic rock finished + if ((!towner[t]._tMsgSaid) && PlrHasItem(p, IDI_ROCK, i)) + { + quests[Q_ROCK]._qactive = QUEST_DONE; + quests[Q_ROCK]._qvar2 = 2; + quests[Q_ROCK]._qvar1 = 2; + RemoveInvItem(p, i); + CreateItem(UID_INFRARING, towner[t]._tx, towner[t]._ty + 1); // Ring of Infravision + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_INFRABS3); + towner[t]._tMsgSaid = TRUE; + } + + // anvil init + if ((plr[p]._pLvlVisited[9]) && (quests[Q_ANVIL]._qactive != QUEST_NOTAVAIL)) { + if ((quests[Q_ANVIL]._qactive == QUEST_NOTACTIVE) || (quests[Q_ANVIL]._qactive == QUEST_NOTDONE)) { + if ((quests[Q_ANVIL]._qvar2 == 0) && (!towner[t]._tMsgSaid)) { + if ((quests[Q_ROCK]._qvar2 == 2) + || ((quests[Q_ROCK]._qactive == QUEST_NOTDONE) && (quests[Q_ROCK]._qvar2 == 1))) { + quests[Q_ANVIL]._qvar2 = 1; + quests[Q_ANVIL]._qlog = TRUE; + if (quests[Q_ANVIL]._qactive == QUEST_NOTACTIVE) { + quests[Q_ANVIL]._qactive = QUEST_NOTDONE; + quests[Q_ANVIL]._qvar1 = 1; + } + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_ANVILBS1); + towner[t]._tMsgSaid = TRUE; + } + } + } + } + // anvil finished + if ((!towner[t]._tMsgSaid) && PlrHasItem(p, IDI_ANVIL, i)) { + quests[Q_ANVIL]._qactive = QUEST_DONE; + quests[Q_ANVIL]._qvar2 = 2; + quests[Q_ANVIL]._qvar1 = 2; + RemoveInvItem(p, i); + CreateItem(UID_GRISWOLD, towner[t]._tx, towner[t]._ty + 1); // Griswolds edge + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_ANVILBS3); + towner[t]._tMsgSaid = TRUE; + } + } + if (!qtextflag) { + TownerTalk(TXT_GRIS1, t); + if(storeflag) StartStore(STORE_SMITH); + } + } + +/*-----Witch-------------------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_WITCH)) { + if (quests[Q_BKMUSHRM]._qactive == QUEST_NOTACTIVE + && PlrHasItem(p, IDI_FUNGALTM, i)) { + // got fungal tome + RemoveInvItem(p, i); + quests[Q_BKMUSHRM]._qactive = QUEST_NOTDONE; + quests[Q_BKMUSHRM]._qlog = TRUE; + quests[Q_BKMUSHRM]._qvar1 = QS_TOMEGIVEN; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_BLKMW1); + towner[t]._tMsgSaid = TRUE; + } else if (quests[Q_BKMUSHRM]._qactive == QUEST_NOTDONE) { + if (quests[Q_BKMUSHRM]._qvar1 >= QS_TOMEGIVEN + && quests[Q_BKMUSHRM]._qvar1 <= QS_MUSHPICKED) { + // waiting for mushroom + if (PlrHasItem(p, IDI_MUSHROOM, i)) { + RemoveInvItem(p, i); + quests[Q_BKMUSHRM]._qvar1 = QS_MUSHGIVEN; + Qtalklist[TWN_HEALER][Q_BKMUSHRM] = TXT_BLKMH1; + Qtalklist[TWN_WITCH][Q_BKMUSHRM] = -1; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_BKMUSHRM]._qmsg = TXT_BLKMW3; + InitQTextMsg(TXT_BLKMW3); + towner[t]._tMsgSaid = TRUE; + } + else if (quests[Q_BKMUSHRM]._qmsg != TXT_BLKMW2) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_BKMUSHRM]._qmsg = TXT_BLKMW2; + InitQTextMsg(TXT_BLKMW2); + towner[t]._tMsgSaid = TRUE; + } + } + else { + // waiting for elixir + if (Item = PlrHasItem(p, IDI_SPECELIX, i)) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_BLKMW5); + quests[Q_BKMUSHRM]._qactive = QUEST_DONE; + towner[t]._tMsgSaid = TRUE; + AllItemsList[Item->IDidx].iUsable = TRUE; + } + else if (PlrHasItem(p, IDI_BRAIN, i) + && quests[Q_BKMUSHRM]._qvar2 != TXT_BLKMW4) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + quests[Q_BKMUSHRM]._qvar2 = TXT_BLKMW4; + InitQTextMsg(TXT_BLKMW4); + towner[t]._tMsgSaid = TRUE; + } + } + } + if (!qtextflag) { + TownerTalk(TXT_ADRIA1, t); + if(storeflag) StartStore(STORE_WITCH); + } + } + +/*-----BarMaid-------------------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_BARMAID)) { + if ((!plr[p]._pLvlVisited[CRYPTSTART]) && (PlrHasItem(p, IDI_MAPOFDOOM, i))) + { + quests[Q_CRYPTMAP]._qactive = QUEST_NOTDONE; + quests[Q_CRYPTMAP]._qlog = TRUE; + quests[Q_CRYPTMAP]._qmsg = TXT_CRYPTMAP8; + InitQTextMsg(TXT_CRYPTMAP8); + towner[t]._tMsgSaid = TRUE; + } + if (!qtextflag) { + TownerTalk(TXT_GILIAN1, t); + if(storeflag) StartStore(STORE_BARMAID); + } + } +/*-----Drunk-------------------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_DRUNK)) { + if (!qtextflag) { + TownerTalk(TXT_FARN1, t); + if(storeflag) StartStore(STORE_DRUNK); + } + } +/*-----Healer------------------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_HEALER)) { + if (gbMaxPlayers == 1) { + if (plr[p]._pLvlVisited[1] || plr[p]._pLvlVisited[5]) { + if (!towner[t]._tMsgSaid) { + if (quests[Q_PWATER]._qactive == QUEST_NOTACTIVE) { + quests[Q_PWATER]._qactive = QUEST_NOTDONE; + quests[Q_PWATER]._qlog = TRUE; + quests[Q_PWATER]._qmsg = TXT_PWH1; + quests[Q_PWATER]._qvar1 = 1; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_PWH1); + towner[t]._tMsgSaid = TRUE; + } + else if ((quests[Q_PWATER]._qactive == QUEST_DONE) && (quests[Q_PWATER]._qvar1 != 2)) { + quests[Q_PWATER]._qvar1 = 2; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_PWH3); + CreateItem(UID_TRING, towner[t]._tx, towner[t]._ty + 1); // Ring of truth + towner[t]._tMsgSaid = TRUE; + } + } + } + if (quests[Q_BKMUSHRM]._qactive == QUEST_NOTDONE + && quests[Q_BKMUSHRM]._qmsg == TXT_BLKMW3) { + if (PlrHasItem(p, IDI_BRAIN, i)) { + RemoveInvItem(p, i); + // pop out spectral elixir + SpawnQuestItem(IDI_SPECELIX, towner[t]._tx, towner[t]._ty + 1, FALSE, ISEL_NONE); + InitQTextMsg(TXT_BLKMH2); + quests[Q_BKMUSHRM]._qvar1 = QS_BRAINGIVEN; + Qtalklist[TWN_HEALER][Q_BKMUSHRM] = -1; + } + } + } + if (!qtextflag) { + TownerTalk(TXT_PEPIN1, t); + if(storeflag) StartStore(STORE_HEALER); + } + } +/*-----Peg-legged Boy----------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_BOY)) { + if (!qtextflag) { + TownerTalk(TXT_WIRT1, t); + if(storeflag) StartStore(STORE_BOY); + } + } +/*-----Story Teller------------------------------------------------------*/ + else if (t == GetActiveTowner(TWN_TELLER)) { + if (gbMaxPlayers == 1) { + if ((quests[Q_BETRAYER]._qactive == QUEST_NOTACTIVE) && (PlrHasItem(p, IDI_LAZSTAFF, i))) { + RemoveInvItem(p, i); + quests[Q_BETRAYER]._qvar1 = 2; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_VBST1); + towner[t]._tMsgSaid = TRUE; + quests[Q_BETRAYER]._qactive = QUEST_NOTDONE; + quests[Q_BETRAYER]._qlog = TRUE; + } + else if ((quests[Q_BETRAYER]._qactive == QUEST_DONE) && (quests[Q_BETRAYER]._qvar1 == 7)) { + quests[Q_BETRAYER]._qvar1 = 8; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_VBST3); + towner[t]._tMsgSaid = TRUE; + quests[Q_DIABLO]._qlog = TRUE; + } + } + if (gbMaxPlayers != 1) { + if ((quests[Q_BETRAYER]._qactive == QUEST_NOTDONE) && (quests[Q_BETRAYER]._qlog == FALSE)) { + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_VBST1); + towner[t]._tMsgSaid = TRUE; + quests[Q_BETRAYER]._qlog = TRUE; + NetSendCmdQuest(TRUE, Q_BETRAYER); + } + else if ((quests[Q_BETRAYER]._qactive == QUEST_DONE) && (quests[Q_BETRAYER]._qvar1 == 7)) { + quests[Q_BETRAYER]._qvar1 = 8; + towner[t]._tbtcnt = 150; + towner[t]._tVar1 = p; + InitQTextMsg(TXT_VBST3); + towner[t]._tMsgSaid = TRUE; + NetSendCmdQuest(TRUE, Q_BETRAYER); + quests[Q_DIABLO]._qlog = TRUE; + NetSendCmdQuest(TRUE, Q_DIABLO); + } + } + if (!qtextflag) { + TownerTalk(TXT_STORY1, t); + if(storeflag) StartStore(STORE_STORYTLR); + } + } +/*-----Cow-------------------------------------------------------------------------*/ + + else if (towner[t]._ttype == TWN_COW) { + if (! qtextflag) CowSFX(p); + } +/*-------------N E W T O W N E R S JKENEWTOWNER -------------------------------- */ + + else if (towner[t]._ttype == TWN_FARMER) + { + if (! qtextflag) + { + int message = TXT_FARMER1; +// int textflag = FALSE; + int textflag = TRUE; + switch (quests[Q_FARMER]._qactive) + { + case QUEST_NOTAVAIL: + if (PlrHasItem(p, IDI_RUNEBOMB, i)) + { + message = TXT_FARMER2; + quests[Q_FARMER]._qactive = QUEST_NOTDONE; + quests[Q_FARMER]._qvar1 = 1; + quests[Q_FARMER]._qlog = TRUE; + quests[Q_FARMER]._qmsg = TXT_FARMER1; + break; + } + else + if (!(plr[myplr]._pLvlVisited[9] || + plr[myplr]._pLevel >= 15)) + { + message = TXT_FARMER7; + if (plr[myplr]._pLvlVisited[2]) + message = TXT_FARMER5; + if (plr[myplr]._pLvlVisited[5]) + message = TXT_FARMER6; + if (plr[myplr]._pLvlVisited[7]) + message = TXT_FARMER8; + + +/* int respond; + respond = random(0,5) + 5; + switch (respond) + { + case 5: + message = TXT_FARMER5; + break; + case 6: + message = TXT_FARMER6; + break; + case 7: + message = TXT_FARMER7; + break; + case 8: + message = TXT_FARMER8; + break; + default: + message = TXT_FARMER9; + }*/ + } + else + { + message = TXT_FARMER1; + quests[Q_FARMER]._qactive = QUEST_NOTDONE; + quests[Q_FARMER]._qvar1 = 1; + quests[Q_FARMER]._qlog = TRUE; + quests[Q_FARMER]._qmsg = TXT_FARMER1; + SpawnBomb(towner[t]._tx + 1, towner[t]._ty); + textflag = TRUE; + break; + } + case QUEST_NOTDONE: + if(PlrHasItem(p, IDI_RUNEBOMB, i)) + message = TXT_FARMER2; + else + message = TXT_FARMER3; + break; + case QUEST_NOTACTIVE: + if (PlrHasItem(p, IDI_RUNEBOMB, i)) + { + message = TXT_FARMER2; + quests[Q_FARMER]._qactive = QUEST_NOTDONE; + quests[Q_FARMER]._qvar1 = 1; + quests[Q_FARMER]._qmsg = TXT_FARMER1; + quests[Q_FARMER]._qlog = TRUE; + break; + } + else if (!(plr[myplr]._pLvlVisited[9] || + plr[myplr]._pLevel >= 15)) + { + + message = TXT_FARMER7; + if (plr[myplr]._pLvlVisited[2]) + message = TXT_FARMER5; + if (plr[myplr]._pLvlVisited[5]) + message = TXT_FARMER6; + if (plr[myplr]._pLvlVisited[7]) + message = TXT_FARMER8; + +/* int respond; + respond = random(0,5) + 5; + switch (respond) + { + case 5: + message = TXT_FARMER5; + break; + case 6: + message = TXT_FARMER6; + break; + case 7: + message = TXT_FARMER7; + break; + case 8: + message = TXT_FARMER8; + break; + default: + message = TXT_FARMER9; + }*/ + break; + } + else + { + message = TXT_FARMER1; + quests[Q_FARMER]._qactive = QUEST_NOTDONE; + quests[Q_FARMER]._qvar1 = 1; + quests[Q_FARMER]._qlog = TRUE; + quests[Q_FARMER]._qmsg = TXT_FARMER1; + SpawnBomb(towner[t]._tx + 1, towner[t]._ty); + textflag = TRUE; + break; + } + case QUEST_DONE: + message = TXT_FARMER4; + //SpawnUnique(UID_INFRARING, towner[t]._tx, towner[t]._ty + 1); + SpawnSomething(IDI_AURIC, towner[t]._tx + 1, towner[t]._ty); + quests[Q_FARMER]._qactive = QUEST_REALLYDONE; + quests[Q_FARMER]._qlog = FALSE; + textflag = TRUE; + break; + case QUEST_REALLYDONE: + message = -1; + break; + default: + message = TXT_FARMER4; + quests[Q_FARMER]._qactive = QUEST_NOTAVAIL; + + + } + + if (message != -1) + { + if (textflag) + InitQTextMsg(message); + else + PlaySFX(alltext[message].sfxnr); + } + if (gbMaxPlayers != 1) + NetSendCmdQuest(TRUE, Q_FARMER); + + } // JKENEWTOWNER + } + + else if (towner[t]._ttype == TWN_COWSUIT) + { + if (! qtextflag) + { + int message = TXT_COWSUIT1; + int textflag = TRUE; + if (PlrHasItem(p, IDI_SUITGREY, i)) + { + message = TXT_COWSUIT7; + RemoveInvItem(p, i); + } + else if (PlrHasItem(p, IDI_SUITBRWN, i)) + { + CreateItem(UID_ARMRCOW,towner[t]._tx + 1, towner[t]._ty); + RemoveInvItem(p, i); + message = TXT_COWSUIT8; + quests[Q_COWSUIT]._qactive = QUEST_DONE; + } + else if (PlrHasItem(p, IDI_RUNEBOMB, i)) + { + message = TXT_COWSUIT5; + quests[Q_COWSUIT]._qactive = QUEST_NOTDONE; + quests[Q_COWSUIT]._qvar1 = 1; + quests[Q_COWSUIT]._qmsg = TXT_COWSUIT4; + quests[Q_COWSUIT]._qlog = TRUE; + } + else + { + switch (quests[Q_COWSUIT]._qactive) + { + case QUEST_NOTAVAIL: + message = TXT_COWSUIT1; + quests[Q_COWSUIT]._qactive = QUEST_PASS1; + break; + case QUEST_PASS1: + message = TXT_COWSUIT2; + quests[Q_COWSUIT]._qactive = QUEST_PASS2; + break; + case QUEST_PASS2: + message = TXT_COWSUIT3; + quests[Q_COWSUIT]._qactive = QUEST_PASS3; + break; + case QUEST_PASS3: + if (!(plr[myplr]._pLvlVisited[9] || plr[myplr]._pLevel >= 15)) + { + int respond; + respond = random(0,4) + 9; + switch (respond) + { + case 9: + message = TXT_COWSUIT9; + break; + case 10: + message = TXT_COWSUIT10; + break; + case 11: + message = TXT_COWSUIT11; + break; + default: + message = TXT_COWSUIT12; + } + break; + } + else + { + message = TXT_COWSUIT4; + quests[Q_COWSUIT]._qactive = QUEST_NOTDONE; + quests[Q_COWSUIT]._qvar1 = 1; + quests[Q_COWSUIT]._qmsg = TXT_COWSUIT4; + quests[Q_COWSUIT]._qlog = TRUE; + SpawnBomb(towner[t]._tx + 1, towner[t]._ty); + textflag = TRUE; + break; + } + case QUEST_NOTDONE: + message = TXT_COWSUIT5; + break; + case QUEST_DONE: + message = TXT_COWSUIT1; + break; + case QUEST_NOTACTIVE: + message = TXT_COWSUIT1; + quests[Q_COWSUIT]._qactive = QUEST_PASS1; + break; + default: + message = TXT_COWSUIT5; + quests[Q_COWSUIT]._qactive = QUEST_NOTAVAIL; + + + } + } + + if (message != -1) + { + if (textflag) + InitQTextMsg(message); + else + PlaySFX(alltext[message].sfxnr); + } + if (gbMaxPlayers != 1) + NetSendCmdQuest(TRUE, Q_COWSUIT); + + } // borrow this JKENEWTOWNER + } + else if (towner[t]._ttype == TWN_GIRL) + { + if (! qtextflag) + { + int message = TXT_THEO1; + int textflag = FALSE; + if((PlrHasItem(p, IDI_THEODORE, i)) && (quests[Q_THEO]._qactive != QUEST_DONE)) + { + message = TXT_THEO4; + RemoveInvItem(p, i); + //SpawnSomething(IDI_AURIC, towner[t]._tx, towner[t]._ty + 1); + CreateAmulet(towner[t]._tx, towner[t]._ty, 13, FALSE, TRUE); + quests[Q_THEO]._qactive = QUEST_DONE; + quests[Q_THEO]._qlog = FALSE; + textflag = TRUE; + } + else + switch (quests[Q_THEO]._qactive) + { + case QUEST_NOTAVAIL: + message = TXT_THEO2; + quests[Q_THEO]._qactive = QUEST_NOTDONE; + quests[Q_THEO]._qvar1 = 1; + quests[Q_THEO]._qlog = TRUE; + quests[Q_THEO]._qmsg = TXT_THEO2; + textflag = TRUE; + break; + case QUEST_NOTDONE: + message = TXT_THEO3; + textflag = TRUE; + break; + case QUEST_DONE: + message = -1; + break; + case QUEST_NOTACTIVE: + message = TXT_THEO2; + quests[Q_THEO]._qvar1 = 1; + quests[Q_THEO]._qlog = TRUE; + quests[Q_THEO]._qmsg = TXT_THEO2; + quests[Q_THEO]._qactive = QUEST_NOTDONE; + textflag = TRUE; + break; + default: + message = TXT_THEO1; + quests[Q_THEO]._qactive = QUEST_NOTAVAIL; + + + } + + if (message != -1) + { + if (textflag) + InitQTextMsg(message); + else + PlaySFX(alltext[message].sfxnr); + } + if (gbMaxPlayers != 1) + NetSendCmdQuest(TRUE, Q_THEO); + + + } // JKENEWTOWNER + } +} + diff --git a/TOWNERS.H b/TOWNERS.H new file mode 100644 index 0000000..d85ce0c --- /dev/null +++ b/TOWNERS.H @@ -0,0 +1,130 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/TOWNERS.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +#include "quests.h" + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +#define MAX_TOWNERS 16 + +//#define TALKQUESTS 17 + +// These are interactive people in town, so @ beginning of towner list +#define TWN_BLKSMITH 0 +#define TWN_HEALER 1 +#define TWN_DEAD 2 +#define TWN_BAROWNER 3 +#define TWN_TELLER 4 +#define TWN_DRUNK 5 +#define TWN_WITCH 6 +#define TWN_BARMAID 7 +#define TWN_BOY 8 +#define TWN_COW 9 +#define TWN_FARMER 10 +#define TWN_GIRL 11 +#define TWN_COWSUIT 12 + +#define QSTMSG_NOTAVAIL 0 +#define QSTMSG_AVAIL 1 +#define QSTMSG_SAID 2 +#define QSTMSG_NOTSAID 3 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + byte _qsttype; // Quest type + byte _qstmsg; // Quest message + byte _qstmsgact; // Quest message flag +} TNQ; + +typedef struct { + int _tmode; // towners current mode + int _ttype; // towner type + int _tx; // plr map x + int _ty; // plr map y + long _txoff; // offset x from left of map tile + long _tyoff; // offset y from bottom of map tile + long _txvel; // current x rate + long _tyvel; // current y rate + int _tdir; // current towner direction + BYTE *_tAnimData; // Data pointer to anim tables + int _tAnimDelay; // anim delay amount + int _tAnimCnt; // current anim delay value + int _tAnimLen; // number of anim frames + int _tAnimFrame; // current anim frame + int _tAnimFrameCnt; // current anim frame count into AnimOrder + char _tAnimOrder; // Animation order or not + long _tAnimWidth; // width of anim frames + long _tAnimWidth2; // (width - 64) / 2 of towner for drawing + int _tTenPer; // Ten percent of time (special message said) + int _teflag; // draw extra tile to left for walk fix (flag) + int _tbtcnt; // Big text count + BOOL _tSelFlag; // Is the town person selectable? + BOOL _tMsgSaid; // Has the towner given his talk this trip to town? + TNQ qsts[MAXQUESTS];// quest struct for talking about quests + + int _tSeed; + + long _tVar1; // scratch var 1 + long _tVar2; // scratch var 2 + long _tVar3; // scratch var 3 + long _tVar4; // scratch var 4 + + char _tName[32]; // Towners name + + BYTE *_tNAnim[8]; // Neutral anims + int _tNFrames; // Number of neutral frames + + // Anything below this will not be saved or sent during a sync + BYTE *_tNData; // Neutral anim memory +} TownerStruct; + + +typedef struct { + int _qinfra; // Infravision + int _qblkm; // Black Mushroom + int _qgarb; + int _qzhar; + int _qveil; // Veil of Steel + int _qmod; // Map of Doom + int _qbutch; // Butcher + int _qbol; // Banner of Light + int _qblind; // Halls of Blind + int _qblood; // Stones of Blood + int _qanvil; // Anvil of Fury + int _qwarlrd; // Warlord of Blood + int _qking; // Skeleton King + int _qpw; // Poison Water + int _qbone; // Chamber of Bone + int _qvb; // Vile Betrayer +} QuestTalkData; + + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern TownerStruct towner[MAX_TOWNERS]; +extern int Qtalklist[14][MAXQUESTS]; // use define JKENEWTOWNERS +extern void SpawnBomb(int,int); + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void InitTowners(); +void FreeTownerGFX(); +void ProcessTowners(); +void TalkToTowner(int, int); +ItemStruct *PlrHasItem(int pnum, int item, int &i); diff --git a/TRACK.CPP b/TRACK.CPP new file mode 100644 index 0000000..1ca9e44 --- /dev/null +++ b/TRACK.CPP @@ -0,0 +1,115 @@ +//****************************************************************** +// track.cpp +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "msg.h" +#include "items.h" +#include "gendung.h" +#include "player.h" +#include "cursor.h" + + +//****************************************************************** +// compiler constants +//****************************************************************** +#define STOP_ON_MOUSEUP 0 // 0 in final +#define TRACKING_CURSOR 0 // 1 in final + + +//****************************************************************** +// private +//****************************************************************** + // track state on/off + static BOOL sgbMouseDown; + static BYTE sgbTrackMode; + + // time tracking last performed + #define TRACK_START_DELAY 250 // milliseconds + #define TRACK_LOOP_DELAY 300 // milliseconds + static long sglTrackTime; + + +//****************************************************************** +//****************************************************************** +void TrackMouse() { + // don't track if the mouse isn't down + if (! sgbMouseDown) return; + + // don't track if the cursor is out of range + if (cursmx < 0) return; + if (cursmx >= DMAXX - 1) return; + if (cursmy < 0) return; + if (cursmy >= DMAXY - 1) return; + + // don't track if the player isn't in a stand state or late walk + if (plr[myplr]._pVar8 <= 6 && plr[myplr]._pmode != PM_STAND) return; + + // don't track if mouse still on same target + if (cursmx == plr[myplr]._ptargx && cursmy == plr[myplr]._ptargy) return; + + // don't track if it hasn't been long enough since we last tracked + long lCurrTime = (long) GetTickCount(); + long lDelta = lCurrTime - sglTrackTime; + if (lDelta < TRACK_LOOP_DELAY) return; + sglTrackTime = lCurrTime; + + // track! + NetSendCmdLoc(TRUE,CMD_WALKXY,cursmx,cursmy); + + if (! sgbTrackMode) { + sgbTrackMode = TRUE; + #if TRACKING_CURSOR + if (curs == GLOVE_CURS) SetCursor(TARGET_CURS); + #endif + } +} + + +//****************************************************************** +//****************************************************************** +void TrackInit(BOOL bMouseDown) { + // are we already in desired state? + if (sgbMouseDown == bMouseDown) return; + sgbMouseDown = bMouseDown; + + if (sgbMouseDown) { + // indicate we haven't moved from click mode to track mode yet + sgbTrackMode = FALSE; + + // make next track time occur after TRACK_START_DELAY + // instead of TRACK_LOOP_DELAY + sglTrackTime = (long) GetTickCount(); + sglTrackTime += TRACK_START_DELAY; + sglTrackTime -= TRACK_LOOP_DELAY; + + // start tracking immediately by pumping a command into queue + NetSendCmdLoc(TRUE,CMD_WALKXY,cursmx,cursmy); + } + else if (sgbTrackMode) { + // turn off track mode + sgbTrackMode = FALSE; + + #if STOP_ON_MOUSEUP + // the user clicked on a map coordinate and held the mouse down + // long enough to indicate tracking rather than clicking, so + // since the mouse is up, stop the player at current coordinate + NetSendCmdLoc(TRUE,CMD_WALKXY,plr[myplr]._pfutx,plr[myplr]._pfuty); + #endif + + // restore cursor + #if TRACKING_CURSOR + if (curs == TARGET_CURS) SetCursor(GLOVE_CURS); + #endif + } +} + + +//****************************************************************** +//****************************************************************** +BOOL IsTracking() { + return sgbTrackMode; +} \ No newline at end of file diff --git a/TRIGS.CPP b/TRIGS.CPP new file mode 100644 index 0000000..612a314 --- /dev/null +++ b/TRIGS.CPP @@ -0,0 +1,1102 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Triggers file +** +** (C)1995 Condor, Inc. All rights reserved. +** +**-----------------------------------------------------------------------** +** $Header: /Diablo/TRIGS.CPP 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------** +** +** File Routines +**-----------------------------------------------------------------------*/ + +#include "diablo.h" +#pragma hdrstop +#include "trigs.h" +#include "palette.h" +#include "gendung.h" +#include "items.h" +#include "player.h" +#include "quests.h" +#include "cursor.h" +#include "control.h" +#include "effects.h" +#include "msg.h" +#include "multi.h" +#include "error.h" +#include "inv.h" +#include "setmaps.h" + +//#define JIM + + +/*-----------------------------------------------------------------------* +** Global Variables +**-----------------------------------------------------------------------*/ + +TriggerStruct trigs[MAXTRIGGERS]; +int numtrigs; +int TWarpFrom; + +int TownDownList[] = { 716, 715, 719, 720, 721, 723, 724, 725, 726, 727, -1 }; +int TownWarp1List[] = { 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1181, 1183, 1185, -1 }; + +//HellFire patch JKE +int TownCryptList[] = { 1331,1332,1333,1334,1335,1336,1337,1338, -1}; // Tag for info box +int TownHiveList[] = { 1307,1308,1309,1310, -1}; +//end of patch JKE + +int L1UpList[] = { 127, 129, 130, 131, 132, 133, 135, 137, 138, 139, 140, -1 }; +int L1DownList[] = { 106, 107, 108, 109, 110, 112, 114, 115, 118, -1 }; +int L2UpList[] = { 266, 267, -1 }; +int L2DownList[] = { 269, 270, 271, 272, -1 }; +int L2TWarpUpList[] = { 558, 559, -1 }; +int L3UpList[] = { 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, -1 }; +int L3DownList[] = { 162, 163, 164, 165, 166, 167, 168, 169, -1 }; +int L3TWarpUpList[] = { 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, -1 }; +//int L4UpList[] = { 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, -1 }; +//int L4DownList[] = { 118, 120, 126, 127, 131, 132, 133, 134, 135, 137, 139, 140, 142, -1 }; +//int L4TWarpUpList[] = { 425, 427, 429, 430, 431, 432, 433, 434, 435, 439, -1 }; +int L4UpList[] = { 82, 83, 90, -1 }; +int L4DownList[] = { 120, 130, 131, 132, 133, -1 }; +int L4TWarpUpList[] = { 421, 422, 429, -1 }; +int L4PentaList[] = { 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, -1 }; + +// JKE new warp list for L5 CRYPT +int L5TWarpUpList[] = {172,173,174,175,176,177,178,179,184,-1}; +//int L5UpList[] = {159,-1}; +int L5UpList[] = {149,150,151,152,153,154,155,157,158,159,-1}; +//int L5DownList[] = {125,126,129,130,131,132,135,136,140,142,-1}; +int L5DownList[] = {125, 126, 129, 131, 132, 135, 136, 140, 142,-1}; + +// JKE new warp list for L6 +int L6TWarpUpList[] = {79,80,81,82,83,84,85,86,87,88,89,90,91,92,-1}; +int L6UpList[] = {65,66,67,68,69,70,71,72,73,74,75,76,77,78,-1}; +int L6DownList[] = {57,58,59,60,61,62,63,64,-1}; + +BOOL trigflag; +BOOL townwarps[3]; + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitNoTriggers() +{ + numtrigs = 0; + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitTownTriggers() +{ + trigs[0]._tx = 25; + trigs[0]._ty = 29; + trigs[0]._tmsg = WM_DIABNEXTLVL; + numtrigs = 1; +#if IS_VERSION(SHAREWARE) + for (int i = 0; i < (MAX_PLRS - 1); i++) townwarps[i] = FALSE; + trigflag = FALSE; + return; +#endif + if (gbMaxPlayers == MAX_PLRS) { + for (int i = 0; i < 3; i++) townwarps[i] = TRUE; + trigs[1]._tx = 49; + trigs[1]._ty = 21; + trigs[1]._tmsg = WM_DIABTOWNWARP; + trigs[1]._tlvl = 5; +#if CHEATS + extern BOOL trigdebug; + if (trigdebug) + trigs[1]._tlvl = trigdebug; +#endif + numtrigs++; + trigs[2]._tx = 17; + trigs[2]._ty = 69; + trigs[2]._tmsg = WM_DIABTOWNWARP; + trigs[2]._tlvl = 9; + numtrigs++; + trigs[3]._tx = 41; + trigs[3]._ty = 80; + trigs[3]._tmsg = WM_DIABTOWNWARP; + trigs[3]._tlvl = 13; + numtrigs++; + trigs[4]._tx = 36; + trigs[4]._ty = 24; + trigs[4]._tmsg = WM_DIABTOWNWARP; + trigs[4]._tlvl = CRYPTSTART; + numtrigs++; + trigs[5]._tx = 80; + trigs[5]._ty = 62; + trigs[5]._tmsg = WM_DIABTOWNWARP; + trigs[5]._tlvl = HIVESTART; + numtrigs++; + } else { + for (int i = 0; i < (MAX_PLRS - 1); i++) townwarps[i] = FALSE; + if (plr[myplr].pTownWarps & 0x01 || plr[myplr]._pLevel >= 10) { + trigs[numtrigs]._tx = 49; + trigs[numtrigs]._ty = 21; + trigs[numtrigs]._tmsg = WM_DIABTOWNWARP; + trigs[numtrigs]._tlvl = 5; + numtrigs++; + townwarps[0] = TRUE; + } + if (plr[myplr].pTownWarps & 0x02 || plr[myplr]._pLevel >= 15) { + trigs[numtrigs]._tx = 17; + trigs[numtrigs]._ty = 69; + trigs[numtrigs]._tmsg = WM_DIABTOWNWARP; + trigs[numtrigs]._tlvl = 9; + numtrigs++; + townwarps[1] = TRUE; + } + if (plr[myplr].pTownWarps & 0x04 || plr[myplr]._pLevel >= 20) { + trigs[numtrigs]._tx = 41; + trigs[numtrigs]._ty = 80; + trigs[numtrigs]._tmsg = WM_DIABTOWNWARP; + trigs[numtrigs]._tlvl = 13; + numtrigs++; + townwarps[2] = TRUE; + } +// This will all have to be ifed with whatever we want to trigger with. + // for now I've assumed it is last and always active. JKE + + if (quests[Q_CRYPTMAP]._qactive == QUEST_DONE) + { + trigs[numtrigs]._tx = 36; + trigs[numtrigs]._ty = 24; + trigs[numtrigs]._tmsg = WM_DIABTOWNWARP; + trigs[numtrigs]._tlvl = CRYPTSTART; + ++numtrigs; + } + + trigs[numtrigs]._tx = 80; + trigs[numtrigs]._ty = 62; + trigs[numtrigs]._tmsg = WM_DIABTOWNWARP; + trigs[numtrigs]._tlvl = HIVESTART; + ++numtrigs; + } + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitL1Triggers() +{ + int i,j; + + numtrigs = 0; + if (currlevel < HIVESTART) + { + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + // if ((dPiece[i][j] == 129) && (currlevel == CRYPTSTART)) { // cheat to add level up for crypt very temporary JKE + // trigs[numtrigs]._tx = i; + // trigs[numtrigs]._ty = j; + // trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + // trigs[numtrigs]._tlvl = 0; + // numtrigs++; + // } else { + if (dPiece[i][j] == 129) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + // } + if (dPiece[i][j] == 115) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + } + else + { + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 184) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + trigs[numtrigs]._tlvl = 0; + numtrigs++; + } + if (dPiece[i][j] == 158) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + + if (dPiece[i][j] == 126) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + } + + + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitL2Triggers() +{ + int i,j; + + numtrigs = 0; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 267) { + if ((i != quests[Q_SCHAMB]._qtx) || (j != quests[Q_SCHAMB]._qty)) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + } + if (dPiece[i][j] == 559) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + trigs[numtrigs]._tlvl = 0; + numtrigs++; + } + if (dPiece[i][j] == 271) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitL3Triggers() +{ + int i,j; + + if (currlevel < HIVESTART) + { + numtrigs = 0; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 171) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if (dPiece[i][j] == 168) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + if (dPiece[i][j] == 549) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + numtrigs++; + } + } + } + } + else + { + numtrigs = 0; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 66) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if (dPiece[i][j] == 63) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + if (dPiece[i][j] == 80) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + numtrigs++; + } + } + } + } + + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitL4Triggers() +{ + int i,j; + + numtrigs = 0; + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 83) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if (dPiece[i][j] == 422) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + trigs[numtrigs]._tlvl = 0; + numtrigs++; + } + if (dPiece[i][j] == 120) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + // this will ensure that the first trigger is not the trigger down to 16 + for (j = 0; j < DMAXY; j++) { + for (i = 0; i < DMAXX; i++) { + if (dPiece[i][j] == 370) { + if (quests[Q_BETRAYER]._qactive == QUEST_DONE) { + trigs[numtrigs]._tx = i; + trigs[numtrigs]._ty = j; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + } + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitSKingTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 82; + trigs[0]._ty = 42; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitSChambTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 70; + trigs[0]._ty = 39; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitPWaterTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 30; + trigs[0]._ty = 83; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void InitVPTriggers() +{ + numtrigs = 1; + trigs[0]._tx = 35; + trigs[0]._ty = 32; + trigs[0]._tmsg = WM_DIABRTNLVL; + trigflag = FALSE; +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL ForceTownTrig() +{ + int i; +#ifdef JIM // debug only + char mystr[10]; +#endif + +// HellFire patch JKE + for (i = 0; TownCryptList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == TownCryptList[i]) { + strcpy(infostr, "Down to Crypt"); +#ifdef JIM // debug only + _itoa(dPiece[cursmx][cursmy],mystr,10); + strcat(infostr,mystr); + +#endif // END + cursmx = 36; + cursmy = 24; + return(TRUE); + } + } + for (i = 0; TownHiveList [i] != -1; i++) { + if (dPiece[cursmx][cursmy] == TownHiveList[i]) { + strcpy(infostr, "Down to Hive"); + cursmx = 80; + cursmy = 62; + return(TRUE); + } + } +// end patch JKE + + for (i = 0; TownDownList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == TownDownList[i]) { + strcpy(infostr, "Down to dungeon"); + + // JIM info bit +#ifdef JIM + _itoa(dPiece[cursmx][cursmy],mystr,10); + strcat(infostr,mystr); +#endif + // END + cursmx = 25; + cursmy = 29; + return(TRUE); + } + } + if (townwarps[0]) { + for (i = 0; TownWarp1List[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == TownWarp1List[i]) { + strcpy(infostr, "Down to catacombs"); + // JIM info bit +#ifdef JIM + _itoa(dPiece[cursmx][cursmy],mystr,10); + strcat(infostr,mystr); +#endif + // END + cursmx = 49; + cursmy = 21; + return(TRUE); + } + } + } + if (townwarps[1]) { + for (i = 1199; i <= 1220; i++) { + if (dPiece[cursmx][cursmy] == i) { + strcpy(infostr, "Down to caves"); + // JIM info bit +#ifdef JIM + _itoa(dPiece[cursmx][cursmy],mystr,10); + strcat(infostr,mystr); +#endif + // END + cursmx = 17; + cursmy = 69; + return(TRUE); + } + } + } + if (townwarps[2]) { + for (i = 1240; i <= 1255; i++) { + if (dPiece[cursmx][cursmy] == i) { + strcpy(infostr, "Down to hell"); + // JIM info bit +#ifdef JIM + _itoa(dPiece[cursmx][cursmy],mystr,10); + strcat(infostr,mystr); +#endif + // END + cursmx = 41; + cursmy = 80; + return(TRUE); + } + } + } + // JIM info bit +#ifdef JIM + sprintf(infostr,"X: %d, Y: %d, dPiece: %d", cursmx, cursmy,dPiece[cursmx][cursmy]); + return (TRUE); +#endif + // END + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +BOOL ForceL1Trig() { + int i, j, dx, dy; + + if (currlevel < HIVESTART) + { + for (i = 0; L1UpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L1UpList[i]) { + if (currlevel > 1) sprintf(infostr, "Up to level %i",currlevel - 1); + else strcpy(infostr, "Up to town"); +// Total hack up just cause I aint got art. JKE +// if (currlevel == 17) { +// strcpy(infostr, "Warp to town"); +// if (trigs[j]._tmsg == WM_DIABTWARPUP) { +// cursmx = trigs[j]._tx; +// cursmy = trigs[j]._ty; +// return(TRUE); +// } +// } +// end of hack + + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + + for (i = 0; L1DownList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L1DownList[i]) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + else + { + for (i = 0; L5UpList[i] != -1; i++) + { + if (dPiece[cursmx][cursmy] == L5UpList[i]) + { + sprintf(infostr, "Up to Crypt level %i", currlevel - 21); + for (j = 0; j < numtrigs; j++) + { + if (trigs[j]._tmsg == WM_DIABPREVLVL) + { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + if (dPiece[cursmx][cursmy] == 317) // cornerstone + { + strcpy (infostr, "Cornerstone of the World"); + return(TRUE); + } + for (i = 0; L5DownList[i] != -1; i++) + { + if (dPiece[cursmx][cursmy] == L5DownList[i]) + { + sprintf(infostr, "Down to Crypt level %i", currlevel - 19); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + + if (currlevel == CRYPTSTART) { + for (i = 0; L5TWarpUpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L5TWarpUpList[i]) { + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if ((dx < 4) && (dy < 4)) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + } + } + // JIM info bit +#ifdef JIM + sprintf(infostr,"X: %d, Y: %d, dPiece: %d", cursmx, cursmy,dPiece[cursmx][cursmy]); + return (TRUE); +#endif + // END + return(FALSE); +} + + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL ForceL2Trig() +{ + int i, j, dx, dy; + + for (i = 0; L2UpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L2UpList[i]) { + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if ((dx < 4) && (dy < 4)) { + sprintf(infostr, "Up to level %i", currlevel - 1); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + for (i = 0; L2DownList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L2DownList[i]) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + if (currlevel == 5) { + for (i = 0; L2TWarpUpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L2TWarpUpList[i]) { + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if ((dx < 4) && (dy < 4)) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL ForceL3Trig() +{ + int i, j, dx, dy; + +// JKE level 6 stuff + if (currlevel < HIVESTART) + { + for (i = 0; L3UpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L3UpList[i]) { + sprintf(infostr, "Up to level %i", currlevel - 1); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + for (i = 0; L3DownList[i] != -1; i++) { + if ((dPiece[cursmx][cursmy] == L3DownList[i]) || + (dPiece[cursmx+1][cursmy] == L3DownList[i]) || + (dPiece[cursmx+2][cursmy] == L3DownList[i])) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + else + { + for (i = 0; L6UpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L6UpList[i]) { + sprintf(infostr, "Up to Nest level %i", currlevel - 17); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + for (i = 0; L6DownList[i] != -1; i++) { + if ((dPiece[cursmx][cursmy] == L6DownList[i]) || + (dPiece[cursmx+1][cursmy] == L6DownList[i]) || + (dPiece[cursmx+2][cursmy] == L6DownList[i])) { + sprintf(infostr, "Down to level %i", currlevel - 15); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + + if (currlevel == 9) { + for (i = 0; L3TWarpUpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L3TWarpUpList[i]) { + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if ((dx < 4) && (dy < 4)) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + } + if (currlevel == HIVESTART) { + for (i = 0; L6TWarpUpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L6TWarpUpList[i]) { + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if ((dx < 4) && (dy < 4)) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL ForceL4Trig() +{ + int i, j, dx, dy; + + for (i = 0; L4UpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L4UpList[i]) { + sprintf(infostr, "Up to level %i", currlevel - 1); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + for (i = 0; L4DownList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L4DownList[i]) { + sprintf(infostr, "Down to level %i", currlevel + 1); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + if (currlevel == 13) { + for (i = 0; L4TWarpUpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L4TWarpUpList[i]) { + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABTWARPUP) { + dx = abs(trigs[j]._tx - cursmx); + dy = abs(trigs[j]._ty - cursmy); + if ((dx < 4) && (dy < 4)) { + strcpy(infostr, "Up to town"); + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + } + if (currlevel == 15) { + for (i = 0; L4PentaList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L4PentaList[i]) { + strcpy(infostr, "Down to Diablo"); + for (j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursmx = trigs[j]._tx; + cursmy = trigs[j]._ty; + return(TRUE); + } + } + } + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void Freeupstairs() +{ + int j, tx, ty, xx, yy; + + for (j = 0; j < numtrigs; j++) { + tx = trigs[j]._tx; + ty = trigs[j]._ty; + for (yy = -2; yy <= 2; yy++) { + for (xx = -2; xx <= 2; xx++) + dFlags[tx+xx][ty+yy] |= BFLAG_SETPC; + } + } +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL ForceSKingTrig() +{ + int i; + + for (i = 0; L1UpList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L1UpList[i]) { + sprintf(infostr, "Back to Level %i", quests[Q_SKELKING]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return(TRUE); + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL ForceSChambTrig() +{ + int i; + + for (i = 0; L2DownList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L2DownList[i]) { + sprintf(infostr, "Back to Level %i", quests[Q_SCHAMB]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return(TRUE); + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +BOOL ForcePWaterTrig() +{ + int i; + + for (i = 0; L3DownList[i] != -1; i++) { + if (dPiece[cursmx][cursmy] == L3DownList[i]) { + sprintf(infostr, "Back to Level %i", quests[Q_PWATER]._qlevel); + cursmx = trigs[0]._tx; + cursmy = trigs[0]._ty; + return(TRUE); + } + } + return(FALSE); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ + +void CheckTrigForce() +{ + trigflag = FALSE; + if (MouseY > 351) return; + if (!setlevel) { + switch (leveltype) { + case 0: + trigflag = ForceTownTrig(); + break; + case 1: + trigflag = ForceL1Trig(); + break; + case 2: + trigflag = ForceL2Trig(); + break; + case 3: + trigflag = ForceL3Trig(); + break; + case 4: + trigflag = ForceL4Trig(); + break; + } + if (leveltype && !trigflag) + trigflag = ForceQuests(); + } else { + switch (setlvlnum) { + case SL_SKELKING: + trigflag = ForceSKingTrig(); + break; + case SL_BONECHAMB: + trigflag = ForceSChambTrig(); + break; + case SL_POISONWATER: + trigflag = ForcePWaterTrig(); + break; +/* case SL_VILEBETRAYER: + trigflag = ForceVBetTrig(); + break;*/ + } + } + if (trigflag) ClearPanel(); +} + +/*-----------------------------------------------------------------------** +**-----------------------------------------------------------------------*/ +void CheckTriggers() { + + // player can only work triggers in stand mode + if (plr[myplr]._pmode != PM_STAND) + return; + + for (int i = 0; i < numtrigs; i++) { + if (plr[myplr]._px != trigs[i]._tx) continue; + if (plr[myplr]._py != trigs[i]._ty) continue; + + switch (trigs[i]._tmsg) { + case WM_DIABNEXTLVL: + #if IS_VERSION(SHAREWARE) + if (currlevel >= 2) { + NetSendCmdLoc(TRUE,CMD_WALKXY,plr[myplr]._px,plr[myplr]._py+1); + PlaySFX(PS_WARR18); // "no way" + InitDiabloMsg(MSG_SHAREWARE); + break; + } + #endif + //Does player have item in hand? If so, drop it before going down level. + if (curs >= ICSTART) { + if(DropItemBeforeTrig()) return; + } + StartNewLvl(myplr,trigs[i]._tmsg,currlevel + 1); + break; + + case WM_DIABPREVLVL: + //Does player have item in hand? If so, drop it before going up level. + if (curs >= ICSTART) { + if(DropItemBeforeTrig()) return; + } + StartNewLvl(myplr,trigs[i]._tmsg,currlevel - 1); + break; + + case WM_DIABTOWNWARP: + if (gbMaxPlayers != 1) { + BOOL abortflag = FALSE; + int dx,dy; + char m; + if ((trigs[i]._tlvl == 5) && (plr[myplr]._pLevel < 8)) { + abortflag = TRUE; + dx = plr[myplr]._px; + dy = plr[myplr]._py+1; + m = MSG_TRIG1; + } + if ((trigs[i]._tlvl == 9) && (plr[myplr]._pLevel < 13)) { + abortflag = TRUE; + dx = plr[myplr]._px+1; + dy = plr[myplr]._py; + m = MSG_TRIG2; + } + if ((trigs[i]._tlvl == 13) && (plr[myplr]._pLevel < 17)) { + abortflag = TRUE; + dx = plr[myplr]._px; + dy = plr[myplr]._py+1; + m = MSG_TRIG3; + } + if (abortflag) { + if (plr[myplr]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR43); + #if !IS_VERSION(SHAREWARE) + else if (plr[myplr]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE43); + else if (plr[myplr]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE43); + else if (plr[myplr]._pClass == CLASS_MONK) PlaySFX(PS_MONK43); + else if (plr[myplr]._pClass == CLASS_BARD) PlaySFX(PS_BARD43); + else if (plr[myplr]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN43); + #endif + InitDiabloMsg(m); + NetSendCmdLoc(TRUE,CMD_WALKXY,dx,dy); + return; + } + } + StartNewLvl(myplr,trigs[i]._tmsg,trigs[i]._tlvl); + break; + + case WM_DIABTWARPUP: + TWarpFrom = currlevel; + StartNewLvl(myplr,trigs[i]._tmsg,0); + break; + + case WM_DIABRTNLVL: + // doesn't work for multiplayer + app_assert(gbMaxPlayers == 1); + StartNewLvl(myplr,trigs[i]._tmsg,ReturnLvl); + break; + + default: + app_fatal("Unknown trigger msg"); + break; + } + } + +} + \ No newline at end of file diff --git a/TRIGS.H b/TRIGS.H new file mode 100644 index 0000000..16f416c --- /dev/null +++ b/TRIGS.H @@ -0,0 +1,63 @@ +/*-----------------------------------------------------------------------** +** Diablo +** +** Constants and Variables +** +** (C)1995 Condor, Inc. All rights reserved. +**-----------------------------------------------------------------------** +** $Header: /Diablo/TRIGS.H 2 1/23/97 12:21p Jmorin $ +**-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------** +** Defines +**-----------------------------------------------------------------------*/ + +//#define MAXTRIGGERS 5 +#define MAXTRIGGERS 7 // to add crypt and hive JKE + +#define LVL_DOWN 0 +#define LVL_UP 1 +#define LVL_SET 2 +#define LVL_RTN 3 +#define LVL_NODIR 4 +#define LVL_WARP 5 +#define LVL_TWARPDN 6 +#define LVL_TWARPUP 7 + +/*-----------------------------------------------------------------------** +** Structures +**-----------------------------------------------------------------------*/ + +typedef struct { + int _tx; + int _ty; + unsigned int _tmsg; + int _tlvl; +} TriggerStruct; + +/*-----------------------------------------------------------------------** +** Externs +**-----------------------------------------------------------------------*/ + +extern BOOL trigflag; +extern TriggerStruct trigs[MAXTRIGGERS]; +extern int numtrigs; + +/*-----------------------------------------------------------------------** +** Prototypes +**-----------------------------------------------------------------------*/ + +void CheckTriggers(); +void InitTownTriggers(); +void InitL1Triggers(); +void InitL2Triggers(); +void InitL3Triggers(); +void InitL4Triggers(); +void InitSKingTriggers(); +void InitSChambTriggers(); +void InitPWaterTriggers(); +void InitNoTriggers(); +void InitVPTriggers(); + +void CheckTrigForce(); +void Freeupstairs(); \ No newline at end of file diff --git a/UNIQUES.TXT b/UNIQUES.TXT new file mode 100644 index 0000000..9e8a078 --- /dev/null +++ b/UNIQUES.TXT @@ -0,0 +1,13 @@ +------------Donald------------ + +Re: Mr. Tsang Could you Please... from Donald Tsang (donaldtsang), Wed Jan 28 15:47:19 US/Pacific 1998 In-reply-to To Mister Tsang. + +(please call me Donald; "Mr. Tsang" makes me feel old. :) + +Okay, so the random item generator has determined that you may deserve a random unique of a certain type (say, rings). + +Now it goes through the list of uniques, and sees if there are any that you're allowed to have on that dungeon level (plus a few if you're getting this from a unique critter) that you haven't already found this session. + +It then takes the last one of those it finds (which is, presumably, the highest-level-and-therefore-best), and gives it to you. + +Me, I would've made that last step just a random pick from the list (perhaps weighted toward the highest-level one), but what do I know? \ No newline at end of file diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 0000000..b26b747 --- /dev/null +++ b/UpgradeLog.htm @@ -0,0 +1,306 @@ + + + + Migration Report +

+ Migration Report - DIABLO

Overview

ProjectPathErrorsWarningsMessages
uiUISRC\UI\ui.vcproj083
DiabloDiablo.vcproj0103
SolutionDIABLO.sln012

Solution and projects

ui

Message
UISRC\UI\ui.vcproj: + This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.
UISRC\UI\ui.vcproj: + VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.
UISRC\UI\ui.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Uisrc\UI\debug\ui.dll') does not match the Librarian's OutputFile property value '.\debug\ui.dll' ('D:\projects\Hellfire\debug\ui.dll') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).
UISRC\UI\ui.vcproj: + MSB8012: $(TargetName) ('ui') does not match the Linker's OutputFile property value '..\..\windebug\hellfrui.dll' ('hellfrui') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).
UISRC\UI\ui.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Uisrc\UI\debug\ui.dll') does not match the Linker's OutputFile property value '..\..\windebug\hellfrui.dll' ('D:\windebug\hellfrui.dll') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
UISRC\UI\ui.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Uisrc\UI\Release\ui.dll') does not match the Librarian's OutputFile property value '.\Release\ui.dll' ('D:\projects\Hellfire\Release\ui.dll') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).
UISRC\UI\ui.vcproj: + MSB8012: $(TargetName) ('ui') does not match the Linker's OutputFile property value '..\..\windebug\hellfrui.dll' ('hellfrui') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).
UISRC\UI\ui.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Uisrc\UI\Release\ui.dll') does not match the Linker's OutputFile property value '..\..\windebug\hellfrui.dll' ('D:\windebug\hellfrui.dll') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
+ Show 3 additional messages +
UISRC\UI\ui.vcproj: + Converting project file 'D:\projects\Hellfire\UISRC\UI\ui.vcproj'.
UISRC\UI\ui.vcproj: + Web deployment to the local IIS server is no longer supported. The Web Deployment build tool has been removed from your project settings.
UISRC\UI\ui.vcproj: + Done converting to new project file 'D:\projects\Hellfire\UISRC\UI\ui.vcxproj'.
+ Hide 3 additional messages +

Diablo

Message
Diablo.vcproj: + This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.
Diablo.vcproj: + VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.
Diablo.vcproj: + MSB8012: $(TargetName) ('Diablo') does not match the Linker's OutputFile property value '.\WinFinal/Hellfire.exe' ('Hellfire') in project configuration 'FinalFinal|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).
Diablo.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\WinFinal\Diablo.exe') does not match the Linker's OutputFile property value '.\WinFinal/Hellfire.exe' ('D:\projects\Hellfire\WinFinal/Hellfire.exe') in project configuration 'FinalFinal|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
Diablo.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\SRel\Diablo.exe') does not match the Linker's OutputFile property value '.\SRel/Diablo.exe' ('D:\projects\Hellfire\SRel/Diablo.exe') in project configuration 'Shareware Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
Diablo.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\SFinal\Diablo.exe') does not match the Linker's OutputFile property value '.\SFinal/Diablo.exe' ('D:\projects\Hellfire\SFinal/Diablo.exe') in project configuration 'Shareware FinalFinal|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
Diablo.vcproj: + MSB8012: $(TargetName) ('Diablo') does not match the Linker's OutputFile property value './bin/Hellfire.exe' ('Hellfire') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).
Diablo.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\WinDebug\Diablo.exe') does not match the Linker's OutputFile property value './bin/Hellfire.exe' ('D:\projects\Hellfire\./bin/Hellfire.exe') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
Diablo.vcproj: + MSB8012: $(TargetName) ('Diablo') does not match the Linker's OutputFile property value '.\WinRel/hellfire.exe' ('hellfire') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).
Diablo.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\WinRel\Diablo.exe') does not match the Linker's OutputFile property value '.\WinRel/hellfire.exe' ('D:\projects\Hellfire\WinRel/hellfire.exe') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
+ Show 3 additional messages +
Diablo.vcproj: + Converting project file 'D:\projects\Hellfire\Diablo.vcproj'.
Diablo.vcproj: + Web deployment to the local IIS server is no longer supported. The Web Deployment build tool has been removed from your project settings.
Diablo.vcproj: + Done converting to new project file 'D:\projects\Hellfire\Diablo.vcxproj'.
+ Hide 3 additional messages +

Solution

Message
DIABLO.sln: + Visual Studio needs to make non-functional changes to this project in order to enable the project to open in released versions of Visual Studio newer than Visual Studio 2010 SP1 without impacting project behavior.
+ Show 2 additional messages +
DIABLO.sln: + File successfully backed up as D:\projects\Hellfire\Backup\DIABLO.sln
DIABLO.sln: + Solution migrated successfully
+ Hide 2 additional messages +
\ No newline at end of file diff --git a/UpgradeLog2.htm b/UpgradeLog2.htm new file mode 100644 index 0000000..a3c641c --- /dev/null +++ b/UpgradeLog2.htm @@ -0,0 +1,281 @@ + + + + Migration Report +

+ Migration Report - DIABLO

Overview

ProjectPathErrorsWarningsMessages
stormdllStorm\stormdll.vcproj073

Solution and projects

stormdll

Message
Storm\stormdll.vcproj: + This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.
Storm\stormdll.vcproj: + VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.
Storm\stormdll.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Storm\Debug\stormdll.dll') does not match the Librarian's OutputFile property value '.\Debug\stormdll.dll' ('D:\projects\Hellfire\Debug\stormdll.dll') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).
Storm\stormdll.vcproj: + MSB8012: $(TargetName) ('stormdll') does not match the Linker's OutputFile property value '../windebug/storm.dll' ('storm') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).
Storm\stormdll.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Storm\Debug\stormdll.dll') does not match the Linker's OutputFile property value '../windebug/storm.dll' ('D:\projects\Hellfire\../windebug/storm.dll') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
Storm\stormdll.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Storm\Release\stormdll.dll') does not match the Librarian's OutputFile property value '.\Release\stormdll.dll' ('D:\projects\Hellfire\Release\stormdll.dll') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).
Storm\stormdll.vcproj: + MSB8012: $(TargetPath) ('D:\projects\Hellfire\Storm\Release\stormdll.dll') does not match the Linker's OutputFile property value '.\Release/stormdll.dll' ('D:\projects\Hellfire\Release/stormdll.dll') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
+ Show 3 additional messages +
Storm\stormdll.vcproj: + Converting project file 'D:\projects\Hellfire\Storm\stormdll.vcproj'.
Storm\stormdll.vcproj: + Web deployment to the local IIS server is no longer supported. The Web Deployment build tool has been removed from your project settings.
Storm\stormdll.vcproj: + Done converting to new project file 'D:\projects\Hellfire\Storm\stormdll.vcxproj'.
+ Hide 3 additional messages +
\ No newline at end of file diff --git a/WAVE.CPP b/WAVE.CPP new file mode 100644 index 0000000..a241ed9 --- /dev/null +++ b/WAVE.CPP @@ -0,0 +1,341 @@ +//****************************************************************** +// wave.cpp +// created 10.18.96 +// written by Patrick Wyatt +//****************************************************************** + + +#include "diablo.h" +#pragma hdrstop +#include "storm/h/storm.h" +#include "sound.h" +#include "engine.h" + + +//****************************************************************** +// externs +//****************************************************************** +extern HSARCHIVE ghsMainArchive; +void FileErrorDlg(const char * pszName); +// pjw.patch1.start.1/13/97 +BOOL InsertCDDlg(); +// pjw.patch1.end.1/13/97 + + +//****************************************************************** +//****************************************************************** +static void reinsert_cd(HSFILE hsFile,DWORD * pdwTryCount,const char * pszFile) { + HSARCHIVE hsArchive; + + // fatal if we've tried to many times + if (*pdwTryCount >= 5) FileErrorDlg(pszFile); + + if (hsFile && SFileGetFileArchive(hsFile,&hsArchive) && (hsArchive != ghsMainArchive)) { + // wait for transient disk error to disappear + Sleep(20); + *pdwTryCount += 1; + } + else { + // pjw.patch1.start.1/13/97 + if (! InsertCDDlg()) FileErrorDlg(pszFile); + // pjw.patch1.end.1/13/97 + } +} + + + +//****************************************************************** +//****************************************************************** +void patSFileCloseFile(HSFILE handle) { + SFileCloseFile(handle); +} + + +//****************************************************************** +//****************************************************************** +DWORD patSFileGetFileSize(HSFILE handle,LPDWORD filesizehigh) { + DWORD dwSize; + DWORD dwTryCount = 0; + while (0 == (dwSize = SFileGetFileSize(handle,filesizehigh))) + reinsert_cd(handle,&dwTryCount,NULL); + return dwSize; +} + + +//****************************************************************** +//****************************************************************** +BOOL patSFileOpenFile(LPCTSTR filename,HSFILE *handle,BOOL bCanFail) { + DWORD dwTryCount = 0; + while (1) { + if (SFileOpenFile(filename,handle)) return TRUE; + if (bCanFail && GetLastError() == SFILE_ERROR_FILE_NOT_FOUND) + return FALSE; + reinsert_cd(NULL,&dwTryCount,filename); + } +} + + +//****************************************************************** +//****************************************************************** +// pjw.patch1.start.1/13/97 +void patSFileReadFile(HSFILE handle,LPVOID buffer,DWORD bytestoread) { + +/* --- old code --- + BOOL bResult; + DWORD dwTryCount = 0; + while (bytestoread) { + DWORD dwBytes; + bResult = SFileReadFile(handle,buffer,bytestoread,&dwBytes,NULL); + if (bResult) return; + + // hopefully we got some bytes + buffer = (LPVOID) ((LPBYTE) buffer + dwBytes); + bytestoread -= dwBytes; + + reinsert_cd(handle,&dwTryCount,NULL); + } +*/ + DWORD dwBytes; + DWORD dwTryCount = 0; + DWORD dwPos = patSFileSetFilePointer(handle,0,NULL,FILE_CURRENT); + while (! SFileReadFile(handle,buffer,bytestoread,&dwBytes,NULL)) { + reinsert_cd(handle,&dwTryCount,NULL); + patSFileSetFilePointer(handle,dwPos,NULL,FILE_BEGIN); + } + app_assert(bytestoread == dwBytes); +} +// pjw.patch1.end.1/13/97 + + +//****************************************************************** +//****************************************************************** +DWORD patSFileSetFilePointer(HSFILE handle,LONG distancetomove,PLONG distancetomovehigh,DWORD movemethod) { + DWORD dwTryCount = 0; + while (1) { + DWORD dwResult = SFileSetFilePointer(handle,distancetomove,distancetomovehigh,movemethod); + if (dwResult != 0xffffffff) + return dwResult; + reinsert_cd(handle,&dwTryCount,NULL); + } +} + + +//****************************************************************** +//****************************************************************** +typedef struct TMemFile { + DWORD dwFileSize; // total file size + DWORD dwFileOffset; // offset in file + DWORD dwBufSize; // buffer size + DWORD dwBufPos; // position in buffer + DWORD dwBufLeft; // bytes left in buffer + LPBYTE lpBuf; // buffer + HSFILE hsFile; // file handle +} TMemFile; +#define MIN_BUF_SIZE 4096 + + +//****************************************************************** +//****************************************************************** +static void MemFileFillBuf(TMemFile * pMemFile) { + app_assert(pMemFile); + + // move to current file position + patSFileSetFilePointer( + pMemFile->hsFile, + pMemFile->dwFileOffset, + 0, + FILE_BEGIN + ); + + // read min(buffer size,file bytes left) + DWORD dwRead = pMemFile->dwFileSize - pMemFile->dwFileOffset; + dwRead = min(pMemFile->dwBufSize,dwRead); + if (dwRead) patSFileReadFile(pMemFile->hsFile,pMemFile->lpBuf,dwRead); + + // update buffer status + pMemFile->dwBufLeft = dwRead; + pMemFile->dwBufPos = 0; +} + + +//****************************************************************** +//****************************************************************** +static void MemFileLoad(HSFILE hsFile,TMemFile * pMemFile,DWORD dwBufSize = 0xffffffff) { + // validate parameters + app_assert(hsFile); + app_assert(pMemFile); + ZeroMemory(pMemFile,sizeof(*pMemFile)); + + // create a buffer for file data no larger than total file size + pMemFile->dwFileSize = patSFileGetFileSize(hsFile); + pMemFile->dwBufSize = max(dwBufSize,MIN_BUF_SIZE); + pMemFile->dwBufSize = min(pMemFile->dwBufSize,pMemFile->dwFileSize); + pMemFile->lpBuf = DiabloAllocPtrSig(pMemFile->dwBufSize,'SNDt'); + pMemFile->hsFile = hsFile; +} + + +//****************************************************************** +//****************************************************************** +static void MemFileFree(TMemFile * pMemFile) { + app_assert(pMemFile); + DiabloFreePtr(pMemFile->lpBuf); +} + + +//****************************************************************** +//****************************************************************** +static BOOL MemFileRead(TMemFile * pMemFile,LPVOID lpBuf,DWORD dwBytes) { + app_assert(pMemFile); + app_assert(lpBuf); + + while (dwBytes) { + // re-fill buffer if required + if (! pMemFile->dwBufLeft) + MemFileFillBuf(pMemFile); + + // copy bytes from buffer + DWORD dwRead = min(dwBytes,pMemFile->dwBufLeft); + if (! dwRead) return FALSE; + CopyMemory(lpBuf,pMemFile->lpBuf + pMemFile->dwBufPos,dwRead); + + // update file + pMemFile->dwFileOffset += dwRead; + pMemFile->dwBufPos += dwRead; + pMemFile->dwBufLeft -= dwRead; + + // update bytes to read + dwBytes -= dwRead; + } + + return TRUE; +} + + +//****************************************************************** +//****************************************************************** +static DWORD MemFileSeek(TMemFile * pMemFile,LONG lDist,DWORD dwMethod) { + // @@ fix this stuff later if these routines get re-used + app_assert(dwMethod == FILE_CURRENT); + app_assert(lDist >= 0); + + if ((DWORD) lDist < pMemFile->dwBufLeft) { + pMemFile->dwBufLeft -= lDist; + pMemFile->dwBufPos += lDist; + } + else { + pMemFile->dwBufLeft = 0; + } + + pMemFile->dwFileOffset += lDist; + return pMemFile->dwFileOffset; +} + + +//****************************************************************** +//****************************************************************** +static BOOL find_chunk(TMemFile * pMemFile,FOURCC ckID,CKINFO * pck) { + struct { + FOURCC ckID; + DWORD dwSize; + } ckHdr; + + while (1) { + + // read chunk header + if (! MemFileRead(pMemFile,&ckHdr,sizeof(ckHdr))) + return FALSE; + + // does it match? + if (ckHdr.ckID == ckID) + break; + + // skip over this chunk + if (0xffffFFFF == MemFileSeek(pMemFile,ckHdr.dwSize,FILE_CURRENT)) + return FALSE; + } + + // get chunk size and position + pck->dwSize = ckHdr.dwSize; + pck->dwOffset = MemFileSeek(pMemFile,0,FILE_CURRENT); + return (pck->dwOffset != 0xffffFFFF); +} + + +//****************************************************************** +//****************************************************************** +static BOOL read_header(TMemFile * pMemFile,WAVEFORMATEX * pwfx,CKINFO * pWaveInfo) { + app_assert(pMemFile); + app_assert(pwfx); + CKINFO fmtInfo; + + // read "RIFF" DWORD=len "WAVE" + MMCKINFO mmck; + if (! MemFileRead(pMemFile,&mmck,sizeof(FOURCC)*2 + sizeof(DWORD))) + return FALSE; + + if ((mmck.ckid != FOURCC_RIFF) || (mmck.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) + return FALSE; + + // Search the input file for for the 'fmt ' chunk + if (! find_chunk(pMemFile,mmioFOURCC('f', 'm', 't', ' '),&fmtInfo)) + return FALSE; + + // Expect 'fmt' chunk to be at least as large as + if (fmtInfo.dwSize < sizeof(PCMWAVEFORMAT)) + return FALSE; + + // Read the 'fmt ' chunk into + PCMWAVEFORMAT pcm; + if (! MemFileRead(pMemFile,&pcm,sizeof(pcm))) + return FALSE; + + // seek over any additional junk in the 'fmt ' chunk + if (0xffffFFFF == MemFileSeek(pMemFile,fmtInfo.dwSize - sizeof(pcm),FILE_CURRENT)) + return FALSE; + + // copy the bytes from the pcm structure to the waveformatex structure + pwfx->wFormatTag = pcm.wf.wFormatTag; + pwfx->nChannels = pcm.wf.nChannels; + pwfx->nSamplesPerSec = pcm.wf.nSamplesPerSec; + pwfx->nAvgBytesPerSec = pcm.wf.nAvgBytesPerSec; + pwfx->nBlockAlign = pcm.wf.nBlockAlign; + pwfx->wBitsPerSample = pcm.wBitsPerSample; + pwfx->cbSize = 0; + + // do we need to find the body info? + if (! pWaveInfo) return TRUE; + return find_chunk(pMemFile,mmioFOURCC('d', 'a', 't', 'a'),pWaveInfo); +} + + +//****************************************************************** +//****************************************************************** +BOOL wave_read_header(HSFILE hsFile,WAVEFORMATEX * pwfx) { + TMemFile memFile; + MemFileLoad(hsFile,&memFile,0); + BOOL bResult = read_header(&memFile,pwfx,NULL); + MemFileFree(&memFile); + return bResult; +} + + +//****************************************************************** +//****************************************************************** +LPBYTE wave_load_file(HSFILE hsFile,WAVEFORMATEX * pwfx,CKINFO * pWaveInfo) { + TMemFile memFile; + MemFileLoad(hsFile,&memFile); + if (! read_header(&memFile,pwfx,pWaveInfo)) { + MemFileFree(&memFile); + return NULL; + } + + return memFile.lpBuf; +} + + +//****************************************************************** +//****************************************************************** +void wave_free_file(LPBYTE lpWave) { + DiabloFreePtr(lpWave); +} diff --git a/Z.BAT b/Z.BAT new file mode 100644 index 0000000..30bdd4b --- /dev/null +++ b/Z.BAT @@ -0,0 +1 @@ +nmake -f diablo.mak diff --git a/ZF.BAT b/ZF.BAT new file mode 100644 index 0000000..bf9e8a1 --- /dev/null +++ b/ZF.BAT @@ -0,0 +1,2 @@ +@set cfg=Diablo - Win32 FinalFinal +@nmake -f diablo.mak %1 diff --git a/_IANIMDA b/_IANIMDA new file mode 100644 index 0000000..019435c --- /dev/null +++ b/_IANIMDA @@ -0,0 +1,5 @@ +control.cpp +gamemenu.cpp +gmenu.cpp +msg.cpp +scrollrt.cpp diff --git a/battle.exp b/battle.exp new file mode 100644 index 0000000..4dba09d Binary files /dev/null and b/battle.exp differ diff --git a/battle.pdb b/battle.pdb new file mode 100644 index 0000000..17e8469 Binary files /dev/null and b/battle.pdb differ diff --git a/dxsdk/Include/D2D1.h b/dxsdk/Include/D2D1.h new file mode 100644 index 0000000..e8768df --- /dev/null +++ b/dxsdk/Include/D2D1.h @@ -0,0 +1,6996 @@ +//--------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file is automatically generated. Please do not edit it directly. +// +// File name: D2D1.h +//--------------------------------------------------------------------------- +#pragma once + + +#ifndef _D2D1_H_ +#define _D2D1_H_ + +#ifndef COM_NO_WINDOWS_H +#include +#endif // #ifndef COM_NO_WINDOWS_H +#include +#include +#include +#include +#include +#ifndef D2D_NO_INCLUDE_D3D10 +#include +#endif // #ifndef D2D_NO_INCLUDE_D3D10 + +#ifndef D2D_USE_C_DEFINITIONS + +// +// We use the 'C' definitions if C++ is not defined +// +#ifndef __cplusplus +#define D2D_USE_C_DEFINITIONS +#endif + +#endif // #ifndef D2D_USE_C_DEFINITIONS + +#ifndef D2D1_DECLARE_INTERFACE +#define D2D1_DECLARE_INTERFACE(X) DECLSPEC_UUID(X) DECLSPEC_NOVTABLE +#endif + +// +// Forward declarations here +// + +typedef interface IDWriteTextFormat IDWriteTextFormat; +typedef interface IDWriteTextLayout IDWriteTextLayout; +typedef interface IDWriteRenderingParams IDWriteRenderingParams; +typedef interface IDXGISurface IDXGISurface; +typedef interface IWICBitmap IWICBitmap; +typedef interface IWICBitmapSource IWICBitmapSource; + +typedef struct DWRITE_GLYPH_RUN DWRITE_GLYPH_RUN; + +#ifndef D2D_USE_C_DEFINITIONS + +interface ID2D1Factory; +interface ID2D1RenderTarget; +interface ID2D1BitmapRenderTarget; +interface ID2D1SimplifiedGeometrySink; +interface ID2D1TessellationSink; +interface ID2D1Geometry; +interface ID2D1Brush; + +#else + +typedef interface ID2D1Factory ID2D1Factory; +typedef interface ID2D1RenderTarget ID2D1RenderTarget; +typedef interface ID2D1BitmapRenderTarget ID2D1BitmapRenderTarget; +typedef interface ID2D1SimplifiedGeometrySink ID2D1SimplifiedGeometrySink;; +typedef interface ID2D1TessellationSink ID2D1TessellationSink; +typedef interface ID2D1Geometry ID2D1Geometry; +typedef interface ID2D1Brush ID2D1Brush; + +#endif + +#define D2D1_INVALID_TAG ULONGLONG_MAX +#define D2D1_DEFAULT_FLATTENING_TOLERANCE (0.25f) + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_ALPHA_MODE +// +// Synopsis: +// Qualifies how alpha is to be treated in a bitmap or render target containing +// alpha. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_ALPHA_MODE +{ + + // + // Alpha mode should be determined implicitly. Some target surfaces do not supply + // or imply this information in which case alpha must be specified. + // + D2D1_ALPHA_MODE_UNKNOWN = 0, + + // + // Treat the alpha as premultipled. + // + D2D1_ALPHA_MODE_PREMULTIPLIED = 1, + + // + // Opacity is in the 'A' component only. + // + D2D1_ALPHA_MODE_STRAIGHT = 2, + + // + // Ignore any alpha channel information. + // + D2D1_ALPHA_MODE_IGNORE = 3, + D2D1_ALPHA_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_ALPHA_MODE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_GAMMA +// +// Synopsis: +// This determines what gamma is used for interpolation/blending. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_GAMMA +{ + + // + // Colors are manipulated in 2.2 gamma color space. + // + D2D1_GAMMA_2_2 = 0, + + // + // Colors are manipulated in 1.0 gamma color space. + // + D2D1_GAMMA_1_0 = 1, + D2D1_GAMMA_FORCE_DWORD = 0xffffffff + +} D2D1_GAMMA; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_OPACITY_MASK_CONTENT +// +// Synopsis: +// Specifies what the contents are of an opacity mask. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_OPACITY_MASK_CONTENT +{ + + // + // The mask contains geometries or bitmaps. + // + D2D1_OPACITY_MASK_CONTENT_GRAPHICS = 0, + + // + // The mask contains text rendered using one of the natural text modes. + // + D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL = 1, + + // + // The mask contains text rendered using one of the GDI compatible text modes. + // + D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE = 2, + D2D1_OPACITY_MASK_CONTENT_FORCE_DWORD = 0xffffffff + +} D2D1_OPACITY_MASK_CONTENT; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_EXTEND_MODE +// +// Synopsis: +// Enum which descibes how to sample from a source outside it's base tile. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_EXTEND_MODE +{ + + // + // Extend the edges of the source out by clamping sample points outside the source + // to the edges. + // + D2D1_EXTEND_MODE_CLAMP = 0, + + // + // The base tile is drawn untransformed and the remainder are filled by repeating + // the base tile. + // + D2D1_EXTEND_MODE_WRAP = 1, + + // + // The same as wrap, but alternate tiles are flipped The base tile is drawn + // untransformed. + // + D2D1_EXTEND_MODE_MIRROR = 2, + D2D1_EXTEND_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_EXTEND_MODE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_ANTIALIAS_MODE +// +// Synopsis: +// Enum which descibes the manner in which we render edges of non-text primitives. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_ANTIALIAS_MODE +{ + + // + // The edges of each primitive are antialiased sequentially. + // + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE = 0, + + // + // Each pixel is rendered if its pixel center is contained by the geometry. + // + D2D1_ANTIALIAS_MODE_ALIASED = 1, + D2D1_ANTIALIAS_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_ANTIALIAS_MODE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_TEXT_ANTIALIAS_MODE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_TEXT_ANTIALIAS_MODE +{ + + // + // Render text using the current system setting. + // + D2D1_TEXT_ANTIALIAS_MODE_DEFAULT = 0, + + // + // Render text using ClearType. + // + D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE = 1, + + // + // Render text using gray-scale. + // + D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE = 2, + + // + // Render text aliased. + // + D2D1_TEXT_ANTIALIAS_MODE_ALIASED = 3, + D2D1_TEXT_ANTIALIAS_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_TEXT_ANTIALIAS_MODE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_BITMAP_INTERPOLATION_MODE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_BITMAP_INTERPOLATION_MODE +{ + + // + // Nearest Neighbor filtering. Also known as nearest pixel or nearest point + // sampling. + // + D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR = 0, + + // + // Linear filtering. + // + D2D1_BITMAP_INTERPOLATION_MODE_LINEAR = 1, + D2D1_BITMAP_INTERPOLATION_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_BITMAP_INTERPOLATION_MODE; + + +//+----------------------------------------------------------------------------- +// +// Flag: +// D2D1_DRAW_TEXT_OPTIONS +// +// Synopsis: +// Modifications made to the draw text call that influence how the text is +// rendered. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_DRAW_TEXT_OPTIONS +{ + + // + // Do not snap the baseline of the text vertically. + // + D2D1_DRAW_TEXT_OPTIONS_NO_SNAP = 0x00000001, + + // + // Clip the text to the content bounds. + // + D2D1_DRAW_TEXT_OPTIONS_CLIP = 0x00000002, + D2D1_DRAW_TEXT_OPTIONS_NONE = 0x00000000, + D2D1_DRAW_TEXT_OPTIONS_FORCE_DWORD = 0xffffffff + +} D2D1_DRAW_TEXT_OPTIONS; + +DEFINE_ENUM_FLAG_OPERATORS(D2D1_DRAW_TEXT_OPTIONS); + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_PIXEL_FORMAT +// +//------------------------------------------------------------------------------ +typedef struct D2D1_PIXEL_FORMAT +{ + DXGI_FORMAT format; + D2D1_ALPHA_MODE alphaMode; + +} D2D1_PIXEL_FORMAT; + +typedef D2D_POINT_2U D2D1_POINT_2U; +typedef D2D_POINT_2F D2D1_POINT_2F; +typedef D2D_RECT_F D2D1_RECT_F; +typedef D2D_RECT_U D2D1_RECT_U; +typedef D2D_SIZE_F D2D1_SIZE_F; +typedef D2D_SIZE_U D2D1_SIZE_U; +typedef D2D_COLOR_F D2D1_COLOR_F; +typedef D2D_MATRIX_3X2_F D2D1_MATRIX_3X2_F; +typedef UINT64 D2D1_TAG; + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_BITMAP_PROPERTIES +// +//------------------------------------------------------------------------------ +typedef struct D2D1_BITMAP_PROPERTIES +{ + D2D1_PIXEL_FORMAT pixelFormat; + FLOAT dpiX; + FLOAT dpiY; + +} D2D1_BITMAP_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_GRADIENT_STOP +// +//------------------------------------------------------------------------------ +typedef struct D2D1_GRADIENT_STOP +{ + FLOAT position; + D2D1_COLOR_F color; + +} D2D1_GRADIENT_STOP; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_BRUSH_PROPERTIES +// +//------------------------------------------------------------------------------ +typedef struct D2D1_BRUSH_PROPERTIES +{ + FLOAT opacity; + D2D1_MATRIX_3X2_F transform; + +} D2D1_BRUSH_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_BITMAP_BRUSH_PROPERTIES +// +//------------------------------------------------------------------------------ +typedef struct D2D1_BITMAP_BRUSH_PROPERTIES +{ + D2D1_EXTEND_MODE extendModeX; + D2D1_EXTEND_MODE extendModeY; + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode; + +} D2D1_BITMAP_BRUSH_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES +// +//------------------------------------------------------------------------------ +typedef struct D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES +{ + D2D1_POINT_2F startPoint; + D2D1_POINT_2F endPoint; + +} D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES +// +//------------------------------------------------------------------------------ +typedef struct D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES +{ + D2D1_POINT_2F center; + D2D1_POINT_2F gradientOriginOffset; + FLOAT radiusX; + FLOAT radiusY; + +} D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_ARC_SIZE +// +// Synopsis: +// Differentiates which of the two possible arcs could match the given arc +// parameters. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_ARC_SIZE +{ + D2D1_ARC_SIZE_SMALL = 0, + D2D1_ARC_SIZE_LARGE = 1, + D2D1_ARC_SIZE_FORCE_DWORD = 0xffffffff + +} D2D1_ARC_SIZE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_CAP_STYLE +// +// Synopsis: +// Enum which descibes the drawing of the ends of a line. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_CAP_STYLE +{ + + // + // Flat line cap. + // + D2D1_CAP_STYLE_FLAT = 0, + + // + // Square line cap. + // + D2D1_CAP_STYLE_SQUARE = 1, + + // + // Round line cap. + // + D2D1_CAP_STYLE_ROUND = 2, + + // + // Triangle line cap. + // + D2D1_CAP_STYLE_TRIANGLE = 3, + D2D1_CAP_STYLE_FORCE_DWORD = 0xffffffff + +} D2D1_CAP_STYLE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_DASH_STYLE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_DASH_STYLE +{ + D2D1_DASH_STYLE_SOLID = 0, + D2D1_DASH_STYLE_DASH = 1, + D2D1_DASH_STYLE_DOT = 2, + D2D1_DASH_STYLE_DASH_DOT = 3, + D2D1_DASH_STYLE_DASH_DOT_DOT = 4, + D2D1_DASH_STYLE_CUSTOM = 5, + D2D1_DASH_STYLE_FORCE_DWORD = 0xffffffff + +} D2D1_DASH_STYLE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_LINE_JOIN +// +// Synopsis: +// Enum which descibes the drawing of the corners on the line. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_LINE_JOIN +{ + + // + // Miter join. + // + D2D1_LINE_JOIN_MITER = 0, + + // + // Bevel join. + // + D2D1_LINE_JOIN_BEVEL = 1, + + // + // Round join. + // + D2D1_LINE_JOIN_ROUND = 2, + + // + // Miter/Bevel join. + // + D2D1_LINE_JOIN_MITER_OR_BEVEL = 3, + D2D1_LINE_JOIN_FORCE_DWORD = 0xffffffff + +} D2D1_LINE_JOIN; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_COMBINE_MODE +// +// Synopsis: +// This enumeration describes the type of combine operation to be performed. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_COMBINE_MODE +{ + + // + // Produce a geometry representing the set of points contained in either + // the first or the second geometry. + // + D2D1_COMBINE_MODE_UNION = 0, + + // + // Produce a geometry representing the set of points common to the first + // and the second geometries. + // + D2D1_COMBINE_MODE_INTERSECT = 1, + + // + // Produce a geometry representing the set of points contained in the + // first geometry or the second geometry, but not both. + // + D2D1_COMBINE_MODE_XOR = 2, + + // + // Produce a geometry representing the set of points contained in the + // first geometry but not the second geometry. + // + D2D1_COMBINE_MODE_EXCLUDE = 3, + D2D1_COMBINE_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_COMBINE_MODE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_GEOMETRY_RELATION +// +//------------------------------------------------------------------------------ +typedef enum D2D1_GEOMETRY_RELATION +{ + + // + // The relation between the geometries couldn't be determined. This value is never + // returned by any D2D method. + // + D2D1_GEOMETRY_RELATION_UNKNOWN = 0, + + // + // The two geometries do not intersect at all. + // + D2D1_GEOMETRY_RELATION_DISJOINT = 1, + + // + // The passed in geometry is entirely contained by the object. + // + D2D1_GEOMETRY_RELATION_IS_CONTAINED = 2, + + // + // The object entirely contains the passed in geometry. + // + D2D1_GEOMETRY_RELATION_CONTAINS = 3, + + // + // The two geometries overlap but neither completely contains the other. + // + D2D1_GEOMETRY_RELATION_OVERLAP = 4, + D2D1_GEOMETRY_RELATION_FORCE_DWORD = 0xffffffff + +} D2D1_GEOMETRY_RELATION; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_GEOMETRY_SIMPLIFICATION_OPTION +// +// Synopsis: +// Specifies how simple the output of a simplified geometry sink should be. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_GEOMETRY_SIMPLIFICATION_OPTION +{ + D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES = 0, + D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES = 1, + D2D1_GEOMETRY_SIMPLIFICATION_OPTION_FORCE_DWORD = 0xffffffff + +} D2D1_GEOMETRY_SIMPLIFICATION_OPTION; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_FIGURE_BEGIN +// +// Synopsis: +// Indicates whether the given figure is filled or hollow. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_FIGURE_BEGIN +{ + D2D1_FIGURE_BEGIN_FILLED = 0, + D2D1_FIGURE_BEGIN_HOLLOW = 1, + D2D1_FIGURE_BEGIN_FORCE_DWORD = 0xffffffff + +} D2D1_FIGURE_BEGIN; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_FIGURE_END +// +// Synopsis: +// Indicates whether the figure ir open or closed on its end point. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_FIGURE_END +{ + D2D1_FIGURE_END_OPEN = 0, + D2D1_FIGURE_END_CLOSED = 1, + D2D1_FIGURE_END_FORCE_DWORD = 0xffffffff + +} D2D1_FIGURE_END; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_BEZIER_SEGMENT +// +// Synopsis: +// Describes a cubic bezier in a path. +// +//------------------------------------------------------------------------------ +typedef struct D2D1_BEZIER_SEGMENT +{ + D2D1_POINT_2F point1; + D2D1_POINT_2F point2; + D2D1_POINT_2F point3; + +} D2D1_BEZIER_SEGMENT; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_TRIANGLE +// +// Synopsis: +// Describes a triangle. +// +//------------------------------------------------------------------------------ +typedef struct D2D1_TRIANGLE +{ + D2D1_POINT_2F point1; + D2D1_POINT_2F point2; + D2D1_POINT_2F point3; + +} D2D1_TRIANGLE; + + +//+----------------------------------------------------------------------------- +// +// Flag: +// D2D1_PATH_SEGMENT +// +// Synopsis: +// Indicates whether the given segment should be stroked, or, if the join between +// this segment and the previous one should be smooth. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_PATH_SEGMENT +{ + D2D1_PATH_SEGMENT_NONE = 0x00000000, + D2D1_PATH_SEGMENT_FORCE_UNSTROKED = 0x00000001, + D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN = 0x00000002, + D2D1_PATH_SEGMENT_FORCE_DWORD = 0xffffffff + +} D2D1_PATH_SEGMENT; + +DEFINE_ENUM_FLAG_OPERATORS(D2D1_PATH_SEGMENT); + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_SWEEP_DIRECTION +// +//------------------------------------------------------------------------------ +typedef enum D2D1_SWEEP_DIRECTION +{ + D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE = 0, + D2D1_SWEEP_DIRECTION_CLOCKWISE = 1, + D2D1_SWEEP_DIRECTION_FORCE_DWORD = 0xffffffff + +} D2D1_SWEEP_DIRECTION; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_FILL_MODE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_FILL_MODE +{ + D2D1_FILL_MODE_ALTERNATE = 0, + D2D1_FILL_MODE_WINDING = 1, + D2D1_FILL_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_FILL_MODE; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_ARC_SEGMENT +// +// Synopsis: +// Describes an arc that is defined as part of a path. +// +//------------------------------------------------------------------------------ +typedef struct D2D1_ARC_SEGMENT +{ + D2D1_POINT_2F point; + D2D1_SIZE_F size; + FLOAT rotationAngle; + D2D1_SWEEP_DIRECTION sweepDirection; + D2D1_ARC_SIZE arcSize; + +} D2D1_ARC_SEGMENT; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_QUADRATIC_BEZIER_SEGMENT +// +//------------------------------------------------------------------------------ +typedef struct D2D1_QUADRATIC_BEZIER_SEGMENT +{ + D2D1_POINT_2F point1; + D2D1_POINT_2F point2; + +} D2D1_QUADRATIC_BEZIER_SEGMENT; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_ELLIPSE +// +//------------------------------------------------------------------------------ +typedef struct D2D1_ELLIPSE +{ + D2D1_POINT_2F point; + FLOAT radiusX; + FLOAT radiusY; + +} D2D1_ELLIPSE; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_ROUNDED_RECT +// +//------------------------------------------------------------------------------ +typedef struct D2D1_ROUNDED_RECT +{ + D2D1_RECT_F rect; + FLOAT radiusX; + FLOAT radiusY; + +} D2D1_ROUNDED_RECT; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_STROKE_STYLE_PROPERTIES +// +// Synopsis: +// Properties, aside from the width, that allow geometric penning to be specified. +// +//------------------------------------------------------------------------------ +typedef struct D2D1_STROKE_STYLE_PROPERTIES +{ + D2D1_CAP_STYLE startCap; + D2D1_CAP_STYLE endCap; + D2D1_CAP_STYLE dashCap; + D2D1_LINE_JOIN lineJoin; + FLOAT miterLimit; + D2D1_DASH_STYLE dashStyle; + FLOAT dashOffset; + +} D2D1_STROKE_STYLE_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Flag: +// D2D1_LAYER_OPTIONS +// +// Synopsis: +// Specified options that can be applied when a layer resource is applied to create +// a layer. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_LAYER_OPTIONS +{ + D2D1_LAYER_OPTIONS_NONE = 0x00000000, + + // + // The layer will render correctly for ClearType text. If the render target was set + // to ClearType previously, the layer will continue to render ClearType. If the + // render target was set to ClearType and this option is not specified, the render + // target will be set to render gray-scale until the layer is popped. The caller + // can override this default by calling SetTextAntialiasMode while within the + // layer. This flag is slightly slower than the default. + // + D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE = 0x00000001, + D2D1_LAYER_OPTIONS_FORCE_DWORD = 0xffffffff + +} D2D1_LAYER_OPTIONS; + +DEFINE_ENUM_FLAG_OPERATORS(D2D1_LAYER_OPTIONS); + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_LAYER_PARAMETERS +// +//------------------------------------------------------------------------------ +typedef struct D2D1_LAYER_PARAMETERS +{ + + // + // The rectangular clip that will be applied to the layer. The clip is affected by + // the world transform. Content outside of the content bounds will not render. + // + D2D1_RECT_F contentBounds; + + // + // A general mask that can be optionally applied to the content. Content not inside + // the fill of the mask will not be rendered. + // + __field_ecount_opt(1) ID2D1Geometry *geometricMask; + + // + // Specifies whether the mask should be aliased or antialiased. + // + D2D1_ANTIALIAS_MODE maskAntialiasMode; + + // + // An additional transform that may be applied to the mask in addition to the + // current world transform. + // + D2D1_MATRIX_3X2_F maskTransform; + + // + // The opacity with which all of the content in the layer will be blended back to + // the target when the layer is popped. + // + FLOAT opacity; + + // + // An additional brush that can be applied to the layer. Only the opacity channel + // is sampled from this brush and multiplied both with the layer content and the + // over-all layer opacity. + // + __field_ecount_opt(1) ID2D1Brush *opacityBrush; + + // + // Specifies if ClearType will be rendered into the layer. + // + D2D1_LAYER_OPTIONS layerOptions; + +} D2D1_LAYER_PARAMETERS; + + +//+----------------------------------------------------------------------------- +// +// Flag: +// D2D1_WINDOW_STATE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_WINDOW_STATE +{ + D2D1_WINDOW_STATE_NONE = 0x0000000, + D2D1_WINDOW_STATE_OCCLUDED = 0x0000001, + D2D1_WINDOW_STATE_FORCE_DWORD = 0xffffffff + +} D2D1_WINDOW_STATE; + +DEFINE_ENUM_FLAG_OPERATORS(D2D1_WINDOW_STATE); + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_RENDER_TARGET_TYPE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_RENDER_TARGET_TYPE +{ + + // + // D2D is free to choose the render target type for the caller. + // + D2D1_RENDER_TARGET_TYPE_DEFAULT = 0, + + // + // The render target will render using the CPU. + // + D2D1_RENDER_TARGET_TYPE_SOFTWARE = 1, + + // + // The render target will render using the GPU. + // + D2D1_RENDER_TARGET_TYPE_HARDWARE = 2, + D2D1_RENDER_TARGET_TYPE_FORCE_DWORD = 0xffffffff + +} D2D1_RENDER_TARGET_TYPE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_FEATURE_LEVEL +// +//------------------------------------------------------------------------------ +typedef enum D2D1_FEATURE_LEVEL +{ + + // + // The caller does not require a particular underlying D3D device level. + // + D2D1_FEATURE_LEVEL_DEFAULT = 0, + + // + // The D3D device level is DX9 compatible. + // + D2D1_FEATURE_LEVEL_9 = D3D10_FEATURE_LEVEL_9_1, + + // + // The D3D device level is DX10 compatible. + // + D2D1_FEATURE_LEVEL_10 = D3D10_FEATURE_LEVEL_10_0, + D2D1_FEATURE_LEVEL_FORCE_DWORD = 0xffffffff + +} D2D1_FEATURE_LEVEL; + + +//+----------------------------------------------------------------------------- +// +// Flag: +// D2D1_RENDER_TARGET_USAGE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_RENDER_TARGET_USAGE +{ + D2D1_RENDER_TARGET_USAGE_NONE = 0x00000000, + + // + // Rendering will occur locally, if a terminal-services session is established, the + // bitmap updates will be sent to the terminal services client. + // + D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING = 0x00000001, + + // + // The render target will allow a call to GetDC on the IGdiInteropRenderTarget + // interface. Rendering will also occur locally. + // + D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE = 0x00000002, + D2D1_RENDER_TARGET_USAGE_FORCE_DWORD = 0xffffffff + +} D2D1_RENDER_TARGET_USAGE; + +DEFINE_ENUM_FLAG_OPERATORS(D2D1_RENDER_TARGET_USAGE); + + +//+----------------------------------------------------------------------------- +// +// Flag: +// D2D1_PRESENT_OPTIONS +// +// Synopsis: +// Describes how present should behave. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_PRESENT_OPTIONS +{ + D2D1_PRESENT_OPTIONS_NONE = 0x00000000, + + // + // Keep the target contents intact through present. + // + D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS = 0x00000001, + + // + // Do not wait for display refresh to commit changes to display. + // + D2D1_PRESENT_OPTIONS_IMMEDIATELY = 0x00000002, + D2D1_PRESENT_OPTIONS_FORCE_DWORD = 0xffffffff + +} D2D1_PRESENT_OPTIONS; + +DEFINE_ENUM_FLAG_OPERATORS(D2D1_PRESENT_OPTIONS); + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_RENDER_TARGET_PROPERTIES +// +//------------------------------------------------------------------------------ +typedef struct D2D1_RENDER_TARGET_PROPERTIES +{ + D2D1_RENDER_TARGET_TYPE type; + D2D1_PIXEL_FORMAT pixelFormat; + FLOAT dpiX; + FLOAT dpiY; + D2D1_RENDER_TARGET_USAGE usage; + D2D1_FEATURE_LEVEL minLevel; + +} D2D1_RENDER_TARGET_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_HWND_RENDER_TARGET_PROPERTIES +// +//------------------------------------------------------------------------------ +typedef struct D2D1_HWND_RENDER_TARGET_PROPERTIES +{ + HWND hwnd; + D2D1_SIZE_U pixelSize; + D2D1_PRESENT_OPTIONS presentOptions; + +} D2D1_HWND_RENDER_TARGET_PROPERTIES; + + +//+----------------------------------------------------------------------------- +// +// Flag: +// D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS +// +//------------------------------------------------------------------------------ +typedef enum D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS +{ + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE = 0x00000000, + + // + // The compatible render target will allow a call to GetDC on the + // IGdiInteropRenderTarget interface. This can be specified even if the parent + // render target is not GDI compatible. + // + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE = 0x00000001, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_FORCE_DWORD = 0xffffffff + +} D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS; + +DEFINE_ENUM_FLAG_OPERATORS(D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS); + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_DRAWING_STATE_DESCRIPTION +// +// Synopsis: +// Allows the drawing state to be atomically created. This also specifies the +// drawing state that is saved into an IDrawingStateBlock object. +// +//------------------------------------------------------------------------------ +typedef struct D2D1_DRAWING_STATE_DESCRIPTION +{ + D2D1_ANTIALIAS_MODE antialiasMode; + D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode; + D2D1_TAG tag1; + D2D1_TAG tag2; + D2D1_MATRIX_3X2_F transform; + +} D2D1_DRAWING_STATE_DESCRIPTION; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_DC_INITIALIZE_MODE +// +//------------------------------------------------------------------------------ +typedef enum D2D1_DC_INITIALIZE_MODE +{ + + // + // The contents of the D2D render target will be copied to the DC. + // + D2D1_DC_INITIALIZE_MODE_COPY = 0, + + // + // The contents of the DC will be cleared. + // + D2D1_DC_INITIALIZE_MODE_CLEAR = 1, + D2D1_DC_INITIALIZE_MODE_FORCE_DWORD = 0xffffffff + +} D2D1_DC_INITIALIZE_MODE; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_DEBUG_LEVEL +// +// Synopsis: +// Indicates the debug level to be outputed by the debug layer. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_DEBUG_LEVEL +{ + D2D1_DEBUG_LEVEL_NONE = 0, + D2D1_DEBUG_LEVEL_ERROR = 1, + D2D1_DEBUG_LEVEL_WARNING = 2, + D2D1_DEBUG_LEVEL_INFORMATION = 3, + D2D1_DEBUG_LEVEL_FORCE_DWORD = 0xffffffff + +} D2D1_DEBUG_LEVEL; + + +//+----------------------------------------------------------------------------- +// +// Enum: +// D2D1_FACTORY_TYPE +// +// Synopsis: +// Specifies the threading model of the created factory and all of its derived +// resources. +// +//------------------------------------------------------------------------------ +typedef enum D2D1_FACTORY_TYPE +{ + + // + // The resulting factory and derived resources may only be invoked serially. + // Reference counts on resources are interlocked, however, resource and render + // target state is not protected from multi-threaded access. + // + D2D1_FACTORY_TYPE_SINGLE_THREADED = 0, + + // + // The resulting factory may be invoked from multiple threads. Returned resources + // use interlocked reference counting and their state is protected. + // + D2D1_FACTORY_TYPE_MULTI_THREADED = 1, + D2D1_FACTORY_TYPE_FORCE_DWORD = 0xffffffff + +} D2D1_FACTORY_TYPE; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D1_FACTORY_OPTIONS +// +// Synopsis: +// Allows additional parameters for factory creation. +// +//------------------------------------------------------------------------------ +typedef struct D2D1_FACTORY_OPTIONS +{ + + // + // Requests a certain level of debugging information from the debug layer. This + // parameter is ignored if the debug layer DLL is not present. + // + D2D1_DEBUG_LEVEL debugLevel; + +} D2D1_FACTORY_OPTIONS; + + +#ifndef D2D_USE_C_DEFINITIONS + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1Resource +// +// Synopsis: +// The root interface for all resources in D2D. +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd90691-12e2-11dc-9fed-001143a055f9") ID2D1Resource : public IUnknown +{ + + + // + // Retrieve the factory associated with this resource. + // + STDMETHOD_(void, GetFactory)( + __deref_out ID2D1Factory **factory + ) CONST PURE; +}; // interface ID2D1Resource + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1Bitmap +// +// Synopsis: +// Root bitmap resource, linearly scaled on a draw call. +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("a2296057-ea42-4099-983b-539fb6505426") ID2D1Bitmap : public ID2D1Resource +{ + + + // + // Returns the size of the bitmap in resolution independent units. + // + STDMETHOD_(D2D1_SIZE_F, GetSize)( + ) CONST PURE; + + + // + // Returns the size of the bitmap in resolution dependent units, (pixels). + // + STDMETHOD_(D2D1_SIZE_U, GetPixelSize)( + ) CONST PURE; + + + // + // Retrieve the format of the bitmap. + // + STDMETHOD_(D2D1_PIXEL_FORMAT, GetPixelFormat)( + ) CONST PURE; + + + // + // Return the DPI of the bitmap. + // + STDMETHOD_(void, GetDpi)( + __out FLOAT *dpiX, + __out FLOAT *dpiY + ) CONST PURE; + + STDMETHOD(CopyFromBitmap)( + __in_opt CONST D2D1_POINT_2U *destPoint, + __in ID2D1Bitmap *bitmap, + __in_opt CONST D2D1_RECT_U *srcRect + ) PURE; + + STDMETHOD(CopyFromRenderTarget)( + __in_opt CONST D2D1_POINT_2U *destPoint, + __in ID2D1RenderTarget *renderTarget, + __in_opt CONST D2D1_RECT_U *srcRect + ) PURE; + + STDMETHOD(CopyFromMemory)( + __in_opt CONST D2D1_RECT_U *dstRect, + __in CONST void *srcData, + UINT32 pitch + ) PURE; +}; // interface ID2D1Bitmap + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1GradientStopCollection +// +// Synopsis: +// Represents an collection of gradient stops that can then be the source resource +// for either a linear or radial gradient brush. +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a7-12e2-11dc-9fed-001143a055f9") ID2D1GradientStopCollection : public ID2D1Resource +{ + + + // + // Returns the number of stops in the gradient. + // + STDMETHOD_(UINT32, GetGradientStopCount)( + ) CONST PURE; + + + // + // Copies the gradient stops from the collection into the caller's interface. + // + STDMETHOD_(void, GetGradientStops)( + __out_ecount(gradientStopsCount) D2D1_GRADIENT_STOP *gradientStops, + UINT gradientStopsCount + ) CONST PURE; + + + // + // Returns whether the interpolation occurs with 1.0 or 2.2 gamma. + // + STDMETHOD_(D2D1_GAMMA, GetColorInterpolationGamma)( + ) CONST PURE; + + STDMETHOD_(D2D1_EXTEND_MODE, GetExtendMode)( + ) CONST PURE; +}; // interface ID2D1GradientStopCollection + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1Brush +// +// Synopsis: +// The root brush interface. All brushes can be used to fill or pen a geometry. +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a8-12e2-11dc-9fed-001143a055f9") ID2D1Brush : public ID2D1Resource +{ + + + // + // Sets the opacity for when the brush is drawn over the entire fill of the brush. + // + STDMETHOD_(void, SetOpacity)( + FLOAT opacity + ) PURE; + + + // + // Sets the transform that applies to everything drawn by the brush. + // + STDMETHOD_(void, SetTransform)( + __in CONST D2D1_MATRIX_3X2_F *transform + ) PURE; + + STDMETHOD_(FLOAT, GetOpacity)( + ) CONST PURE; + + STDMETHOD_(void, GetTransform)( + __out D2D1_MATRIX_3X2_F *transform + ) CONST PURE; + + void + SetTransform( + CONST D2D1_MATRIX_3X2_F &transform + ) + { + SetTransform(&transform); + } +}; // interface ID2D1Brush + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1BitmapBrush +// +// Synopsis: +// A bitmap brush allows a bitmap to be used to fill a geometry. +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906aa-12e2-11dc-9fed-001143a055f9") ID2D1BitmapBrush : public ID2D1Brush +{ + + + // + // Sets how the bitmap is to be treated outside of its natural extent on the X + // axis. + // + STDMETHOD_(void, SetExtendModeX)( + D2D1_EXTEND_MODE extendModeX + ) PURE; + + + // + // Sets how the bitmap is to be treated outside of its natural extent on the X + // axis. + // + STDMETHOD_(void, SetExtendModeY)( + D2D1_EXTEND_MODE extendModeY + ) PURE; + + + // + // Sets the interpolation mode used when this brush is used. + // + STDMETHOD_(void, SetInterpolationMode)( + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode + ) PURE; + + + // + // Sets the bitmap associated as the source of this brush. + // + STDMETHOD_(void, SetBitmap)( + __in ID2D1Bitmap *bitmap + ) PURE; + + STDMETHOD_(D2D1_EXTEND_MODE, GetExtendModeX)( + ) CONST PURE; + + STDMETHOD_(D2D1_EXTEND_MODE, GetExtendModeY)( + ) CONST PURE; + + STDMETHOD_(D2D1_BITMAP_INTERPOLATION_MODE, GetInterpolationMode)( + ) CONST PURE; + + STDMETHOD_(void, GetBitmap)( + __deref_out ID2D1Bitmap **bitmap + ) CONST PURE; +}; // interface ID2D1BitmapBrush + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1SolidColorBrush +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a9-12e2-11dc-9fed-001143a055f9") ID2D1SolidColorBrush : public ID2D1Brush +{ + + STDMETHOD_(void, SetColor)( + __in CONST D2D1_COLOR_F *color + ) PURE; + + STDMETHOD_(D2D1_COLOR_F, GetColor)( + ) CONST PURE; + + void + SetColor( + CONST D2D1_COLOR_F &color + ) + { + SetColor(&color); + } +}; // interface ID2D1SolidColorBrush + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1LinearGradientBrush +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906ab-12e2-11dc-9fed-001143a055f9") ID2D1LinearGradientBrush : public ID2D1Brush +{ + + STDMETHOD_(void, SetStartPoint)( + D2D1_POINT_2F startPoint + ) PURE; + + + // + // Sets the end point of the gradient in local coordinate space. This is not + // influenced by the geometry being filled. + // + STDMETHOD_(void, SetEndPoint)( + D2D1_POINT_2F endPoint + ) PURE; + + STDMETHOD_(D2D1_POINT_2F, GetStartPoint)( + ) CONST PURE; + + STDMETHOD_(D2D1_POINT_2F, GetEndPoint)( + ) CONST PURE; + + STDMETHOD_(void, GetGradientStopCollection)( + __deref_out ID2D1GradientStopCollection **gradientStopCollection + ) CONST PURE; +}; // interface ID2D1LinearGradientBrush + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1RadialGradientBrush +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906ac-12e2-11dc-9fed-001143a055f9") ID2D1RadialGradientBrush : public ID2D1Brush +{ + + + // + // Sets the center of the radial gradient. This will be in local coordinates and + // will not depend on the geometry being filled. + // + STDMETHOD_(void, SetCenter)( + D2D1_POINT_2F center + ) PURE; + + + // + // Sets offset of the origin relative to the radial gradient center. + // + STDMETHOD_(void, SetGradientOriginOffset)( + D2D1_POINT_2F gradientOriginOffset + ) PURE; + + STDMETHOD_(void, SetRadiusX)( + FLOAT radiusX + ) PURE; + + STDMETHOD_(void, SetRadiusY)( + FLOAT radiusY + ) PURE; + + STDMETHOD_(D2D1_POINT_2F, GetCenter)( + ) CONST PURE; + + STDMETHOD_(D2D1_POINT_2F, GetGradientOriginOffset)( + ) CONST PURE; + + STDMETHOD_(FLOAT, GetRadiusX)( + ) CONST PURE; + + STDMETHOD_(FLOAT, GetRadiusY)( + ) CONST PURE; + + STDMETHOD_(void, GetGradientStopCollection)( + __deref_out ID2D1GradientStopCollection **gradientStopCollection + ) CONST PURE; +}; // interface ID2D1RadialGradientBrush + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1StrokeStyle +// +// Synopsis: +// Resource interface that holds pen style properties. +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd9069d-12e2-11dc-9fed-001143a055f9") ID2D1StrokeStyle : public ID2D1Resource +{ + + STDMETHOD_(D2D1_CAP_STYLE, GetStartCap)( + ) CONST PURE; + + STDMETHOD_(D2D1_CAP_STYLE, GetEndCap)( + ) CONST PURE; + + STDMETHOD_(D2D1_CAP_STYLE, GetDashCap)( + ) CONST PURE; + + STDMETHOD_(FLOAT, GetMiterLimit)( + ) CONST PURE; + + STDMETHOD_(D2D1_LINE_JOIN, GetLineJoin)( + ) CONST PURE; + + STDMETHOD_(FLOAT, GetDashOffset)( + ) CONST PURE; + + STDMETHOD_(D2D1_DASH_STYLE, GetDashStyle)( + ) CONST PURE; + + STDMETHOD_(UINT32, GetDashesCount)( + ) CONST PURE; + + + // + // Returns the dashes from the object into a user allocated array. The user must + // call GetDashesCount to retrieve the required size. + // + STDMETHOD_(void, GetDashes)( + __out_ecount(dashesCount) FLOAT *dashes, + UINT dashesCount + ) CONST PURE; +}; // interface ID2D1StrokeStyle + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1Geometry +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a1-12e2-11dc-9fed-001143a055f9") ID2D1Geometry : public ID2D1Resource +{ + + + // + // Retrieve the bounds of the geometry, with an optional applied transform. + // + STDMETHOD(GetBounds)( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out D2D1_RECT_F *bounds + ) CONST PURE; + + + // + // Get the bounds of the corresponding geometry after it has been widened or have + // an optional pen style applied. + // + STDMETHOD(GetWidenedBounds)( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out D2D1_RECT_F *bounds + ) CONST PURE; + + + // + // Checks to see whether the corresponding penned and widened geometry contains the + // given point. + // + STDMETHOD(StrokeContainsPoint)( + D2D1_POINT_2F point, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out BOOL *contains + ) CONST PURE; + + + // + // Test whether the given fill of this geometry would contain this point. + // + STDMETHOD(FillContainsPoint)( + D2D1_POINT_2F point, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out BOOL *contains + ) CONST PURE; + + + // + // Compare how one geometry intersects or contains another geometry. + // + STDMETHOD(CompareWithGeometry)( + __in ID2D1Geometry *inputGeometry, + __in_opt CONST D2D1_MATRIX_3X2_F *inputGeometryTransform, + FLOAT flatteningTolerance, + __out D2D1_GEOMETRY_RELATION *relation + ) CONST PURE; + + + // + // Converts a geometry to a simplified geometry that has arcs and quadratic beziers + // removed. + // + STDMETHOD(Simplify)( + D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST PURE; + + + // + // Tessellates a geometry into triangles. + // + STDMETHOD(Tessellate)( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1TessellationSink *tessellationSink + ) CONST PURE; + + + // + // Performs a combine operation between the two geometries to produce a resulting + // geometry. + // + STDMETHOD(CombineWithGeometry)( + __in ID2D1Geometry *inputGeometry, + D2D1_COMBINE_MODE combineMode, + __in_opt CONST D2D1_MATRIX_3X2_F *inputGeometryTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST PURE; + + + // + // Computes the outline of the geometry. The result is written back into a + // simplified geometry sink. + // + STDMETHOD(Outline)( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST PURE; + + + // + // Computes the area of the geometry. + // + STDMETHOD(ComputeArea)( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out FLOAT *area + ) CONST PURE; + + + // + // Computes the length of the geometry. + // + STDMETHOD(ComputeLength)( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out FLOAT *length + ) CONST PURE; + + + // + // Computes the point and tangent a given distance along the path. + // + STDMETHOD(ComputePointAtLength)( + FLOAT length, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out_opt D2D1_POINT_2F *point, + __out_opt D2D1_POINT_2F *unitTangentVector + ) CONST PURE; + + + // + // Get the geometry and widen it as well as apply an optional pen style. + // + STDMETHOD(Widen)( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST PURE; + + + // + // Retrieve the bounds of the geometry, with an optional applied transform. + // + HRESULT + GetBounds( + CONST D2D1_MATRIX_3X2_F &worldTransform, + __out D2D1_RECT_F *bounds + ) CONST + { + return GetBounds(&worldTransform, bounds); + } + + + // + // Get the bounds of the corresponding geometry after it has been widened or have + // an optional pen style applied. + // + HRESULT + GetWidenedBounds( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __out D2D1_RECT_F *bounds + ) CONST + { + return GetWidenedBounds(strokeWidth, strokeStyle, &worldTransform, flatteningTolerance, bounds); + } + + + // + // Get the bounds of the corresponding geometry after it has been widened or have + // an optional pen style applied. + // + HRESULT + GetWidenedBounds( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out D2D1_RECT_F *bounds + ) CONST + { + return GetWidenedBounds(strokeWidth, strokeStyle, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, bounds); + } + + + // + // Get the bounds of the corresponding geometry after it has been widened or have + // an optional pen style applied. + // + HRESULT + GetWidenedBounds( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + CONST D2D1_MATRIX_3X2_F &worldTransform, + __out D2D1_RECT_F *bounds + ) CONST + { + return GetWidenedBounds(strokeWidth, strokeStyle, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, bounds); + } + + HRESULT + StrokeContainsPoint( + D2D1_POINT_2F point, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __out BOOL *contains + ) CONST + { + return StrokeContainsPoint(point, strokeWidth, strokeStyle, &worldTransform, flatteningTolerance, contains); + } + + + // + // Checks to see whether the corresponding penned and widened geometry contains the + // given point. + // + HRESULT + StrokeContainsPoint( + D2D1_POINT_2F point, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out BOOL *contains + ) CONST + { + return StrokeContainsPoint(point, strokeWidth, strokeStyle, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains); + } + + HRESULT + StrokeContainsPoint( + D2D1_POINT_2F point, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + CONST D2D1_MATRIX_3X2_F &worldTransform, + __out BOOL *contains + ) CONST + { + return StrokeContainsPoint(point, strokeWidth, strokeStyle, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains); + } + + HRESULT + FillContainsPoint( + D2D1_POINT_2F point, + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __out BOOL *contains + ) CONST + { + return FillContainsPoint(point, &worldTransform, flatteningTolerance, contains); + } + + + // + // Test whether the given fill of this geometry would contain this point. + // + HRESULT + FillContainsPoint( + D2D1_POINT_2F point, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out BOOL *contains + ) CONST + { + return FillContainsPoint(point, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains); + } + + HRESULT + FillContainsPoint( + D2D1_POINT_2F point, + CONST D2D1_MATRIX_3X2_F &worldTransform, + __out BOOL *contains + ) CONST + { + return FillContainsPoint(point, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains); + } + + + // + // Compare how one geometry intersects or contains another geometry. + // + HRESULT + CompareWithGeometry( + __in ID2D1Geometry *inputGeometry, + CONST D2D1_MATRIX_3X2_F &inputGeometryTransform, + FLOAT flatteningTolerance, + __out D2D1_GEOMETRY_RELATION *relation + ) CONST + { + return CompareWithGeometry(inputGeometry, &inputGeometryTransform, flatteningTolerance, relation); + } + + + // + // Compare how one geometry intersects or contains another geometry. + // + HRESULT + CompareWithGeometry( + __in ID2D1Geometry *inputGeometry, + __in_opt CONST D2D1_MATRIX_3X2_F *inputGeometryTransform, + __out D2D1_GEOMETRY_RELATION *relation + ) CONST + { + return CompareWithGeometry(inputGeometry, inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, relation); + } + + + // + // Compare how one geometry intersects or contains another geometry. + // + HRESULT + CompareWithGeometry( + __in ID2D1Geometry *inputGeometry, + CONST D2D1_MATRIX_3X2_F &inputGeometryTransform, + __out D2D1_GEOMETRY_RELATION *relation + ) CONST + { + return CompareWithGeometry(inputGeometry, &inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, relation); + } + + + // + // Converts a geometry to a simplified geometry that has arcs and quadratic beziers + // removed. + // + HRESULT + Simplify( + D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Simplify(simplificationOption, &worldTransform, flatteningTolerance, geometrySink); + } + + + // + // Converts a geometry to a simplified geometry that has arcs and quadratic beziers + // removed. + // + HRESULT + Simplify( + D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Simplify(simplificationOption, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } + + + // + // Converts a geometry to a simplified geometry that has arcs and quadratic beziers + // removed. + // + HRESULT + Simplify( + D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, + CONST D2D1_MATRIX_3X2_F &worldTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Simplify(simplificationOption, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } + + + // + // Tessellates a geometry into triangles. + // + HRESULT + Tessellate( + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __in ID2D1TessellationSink *tessellationSink + ) CONST + { + return Tessellate(&worldTransform, flatteningTolerance, tessellationSink); + } + + + // + // Tessellates a geometry into triangles. + // + HRESULT + Tessellate( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __in ID2D1TessellationSink *tessellationSink + ) CONST + { + return Tessellate(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, tessellationSink); + } + + + // + // Tessellates a geometry into triangles. + // + HRESULT + Tessellate( + CONST D2D1_MATRIX_3X2_F &worldTransform, + __in ID2D1TessellationSink *tessellationSink + ) CONST + { + return Tessellate(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, tessellationSink); + } + + + // + // Performs a combine operation between the two geometries to produce a resulting + // geometry. + // + HRESULT + CombineWithGeometry( + __in ID2D1Geometry *inputGeometry, + D2D1_COMBINE_MODE combineMode, + CONST D2D1_MATRIX_3X2_F &inputGeometryTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return CombineWithGeometry(inputGeometry, combineMode, &inputGeometryTransform, flatteningTolerance, geometrySink); + } + + + // + // Performs a combine operation between the two geometries to produce a resulting + // geometry. + // + HRESULT + CombineWithGeometry( + __in ID2D1Geometry *inputGeometry, + D2D1_COMBINE_MODE combineMode, + __in_opt CONST D2D1_MATRIX_3X2_F *inputGeometryTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return CombineWithGeometry(inputGeometry, combineMode, inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } + + + // + // Performs a combine operation between the two geometries to produce a resulting + // geometry. + // + HRESULT + CombineWithGeometry( + __in ID2D1Geometry *inputGeometry, + D2D1_COMBINE_MODE combineMode, + CONST D2D1_MATRIX_3X2_F &inputGeometryTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return CombineWithGeometry(inputGeometry, combineMode, &inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } + + + // + // Computes the outline of the geometry. The result is written back into a + // simplified geometry sink. + // + HRESULT + Outline( + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Outline(&worldTransform, flatteningTolerance, geometrySink); + } + + + // + // Computes the outline of the geometry. The result is written back into a + // simplified geometry sink. + // + HRESULT + Outline( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Outline(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } + + + // + // Computes the outline of the geometry. The result is written back into a + // simplified geometry sink. + // + HRESULT + Outline( + CONST D2D1_MATRIX_3X2_F &worldTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Outline(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } + + + // + // Computes the area of the geometry. + // + HRESULT + ComputeArea( + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __out FLOAT *area + ) CONST + { + return ComputeArea(&worldTransform, flatteningTolerance, area); + } + + + // + // Computes the area of the geometry. + // + HRESULT + ComputeArea( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out FLOAT *area + ) CONST + { + return ComputeArea(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, area); + } + + + // + // Computes the area of the geometry. + // + HRESULT + ComputeArea( + CONST D2D1_MATRIX_3X2_F &worldTransform, + __out FLOAT *area + ) CONST + { + return ComputeArea(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, area); + } + + + // + // Computes the length of the geometry. + // + HRESULT + ComputeLength( + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __out FLOAT *length + ) CONST + { + return ComputeLength(&worldTransform, flatteningTolerance, length); + } + + + // + // Computes the length of the geometry. + // + HRESULT + ComputeLength( + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out FLOAT *length + ) CONST + { + return ComputeLength(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, length); + } + + + // + // Computes the length of the geometry. + // + HRESULT + ComputeLength( + CONST D2D1_MATRIX_3X2_F &worldTransform, + __out FLOAT *length + ) CONST + { + return ComputeLength(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, length); + } + + + // + // Computes the point and tangent a given distance along the path. + // + HRESULT + ComputePointAtLength( + FLOAT length, + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __out_opt D2D1_POINT_2F *point, + __out_opt D2D1_POINT_2F *unitTangentVector + ) CONST + { + return ComputePointAtLength(length, &worldTransform, flatteningTolerance, point, unitTangentVector); + } + + + // + // Computes the point and tangent a given distance along the path. + // + HRESULT + ComputePointAtLength( + FLOAT length, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out_opt D2D1_POINT_2F *point, + __out_opt D2D1_POINT_2F *unitTangentVector + ) CONST + { + return ComputePointAtLength(length, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, point, unitTangentVector); + } + + + // + // Computes the point and tangent a given distance along the path. + // + HRESULT + ComputePointAtLength( + FLOAT length, + CONST D2D1_MATRIX_3X2_F &worldTransform, + __out_opt D2D1_POINT_2F *point, + __out_opt D2D1_POINT_2F *unitTangentVector + ) CONST + { + return ComputePointAtLength(length, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, point, unitTangentVector); + } + + + // + // Get the geometry and widen it as well as apply an optional pen style. + // + HRESULT + Widen( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + CONST D2D1_MATRIX_3X2_F &worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Widen(strokeWidth, strokeStyle, &worldTransform, flatteningTolerance, geometrySink); + } + + + // + // Get the geometry and widen it as well as apply an optional pen style. + // + HRESULT + Widen( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Widen(strokeWidth, strokeStyle, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } + + + // + // Get the geometry and widen it as well as apply an optional pen style. + // + HRESULT + Widen( + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + CONST D2D1_MATRIX_3X2_F &worldTransform, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) CONST + { + return Widen(strokeWidth, strokeStyle, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink); + } +}; // interface ID2D1Geometry + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1RectangleGeometry +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a2-12e2-11dc-9fed-001143a055f9") ID2D1RectangleGeometry : public ID2D1Geometry +{ + + STDMETHOD_(void, GetRect)( + __out D2D1_RECT_F *rect + ) CONST PURE; +}; // interface ID2D1RectangleGeometry + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1RoundedRectangleGeometry +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a3-12e2-11dc-9fed-001143a055f9") ID2D1RoundedRectangleGeometry : public ID2D1Geometry +{ + + STDMETHOD_(void, GetRoundedRect)( + __out D2D1_ROUNDED_RECT *roundedRect + ) CONST PURE; +}; // interface ID2D1RoundedRectangleGeometry + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1EllipseGeometry +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a4-12e2-11dc-9fed-001143a055f9") ID2D1EllipseGeometry : public ID2D1Geometry +{ + + STDMETHOD_(void, GetEllipse)( + __out D2D1_ELLIPSE *ellipse + ) CONST PURE; +}; // interface ID2D1EllipseGeometry + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1GeometryGroup +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a6-12e2-11dc-9fed-001143a055f9") ID2D1GeometryGroup : public ID2D1Geometry +{ + + STDMETHOD_(D2D1_FILL_MODE, GetFillMode)( + ) CONST PURE; + + STDMETHOD_(UINT32, GetSourceGeometryCount)( + ) CONST PURE; + + STDMETHOD_(void, GetSourceGeometries)( + __out_ecount(geometriesCount) ID2D1Geometry **geometries, + UINT geometriesCount + ) CONST PURE; +}; // interface ID2D1GeometryGroup + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1TransformedGeometry +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906bb-12e2-11dc-9fed-001143a055f9") ID2D1TransformedGeometry : public ID2D1Geometry +{ + + STDMETHOD_(void, GetSourceGeometry)( + __deref_out ID2D1Geometry **sourceGeometry + ) CONST PURE; + + STDMETHOD_(void, GetTransform)( + __out D2D1_MATRIX_3X2_F *transform + ) CONST PURE; +}; // interface ID2D1TransformedGeometry + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1SimplifiedGeometrySink +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd9069e-12e2-11dc-9fed-001143a055f9") ID2D1SimplifiedGeometrySink : public IUnknown +{ + + STDMETHOD_(void, SetFillMode)( + D2D1_FILL_MODE fillMode + ) PURE; + + STDMETHOD_(void, SetSegmentFlags)( + D2D1_PATH_SEGMENT vertexFlags + ) PURE; + + STDMETHOD_(void, BeginFigure)( + D2D1_POINT_2F startPoint, + D2D1_FIGURE_BEGIN figureBegin + ) PURE; + + STDMETHOD_(void, AddLines)( + __in_ecount(pointsCount) CONST D2D1_POINT_2F *points, + UINT pointsCount + ) PURE; + + STDMETHOD_(void, AddBeziers)( + __in_ecount(beziersCount) CONST D2D1_BEZIER_SEGMENT *beziers, + UINT beziersCount + ) PURE; + + STDMETHOD_(void, EndFigure)( + D2D1_FIGURE_END figureEnd + ) PURE; + + STDMETHOD(Close)( + ) PURE; +}; // interface ID2D1SimplifiedGeometrySink + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1GeometrySink +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd9069f-12e2-11dc-9fed-001143a055f9") ID2D1GeometrySink : public ID2D1SimplifiedGeometrySink +{ + + STDMETHOD_(void, AddLine)( + D2D1_POINT_2F point + ) PURE; + + STDMETHOD_(void, AddBezier)( + __in CONST D2D1_BEZIER_SEGMENT *bezier + ) PURE; + + STDMETHOD_(void, AddQuadraticBezier)( + __in CONST D2D1_QUADRATIC_BEZIER_SEGMENT *bezier + ) PURE; + + STDMETHOD_(void, AddQuadraticBeziers)( + __in_ecount(beziersCount) CONST D2D1_QUADRATIC_BEZIER_SEGMENT *beziers, + UINT beziersCount + ) PURE; + + STDMETHOD_(void, AddArc)( + __in CONST D2D1_ARC_SEGMENT *arc + ) PURE; + + void + AddBezier( + CONST D2D1_BEZIER_SEGMENT &bezier + ) + { + AddBezier(&bezier); + } + + void + AddQuadraticBezier( + CONST D2D1_QUADRATIC_BEZIER_SEGMENT &bezier + ) + { + AddQuadraticBezier(&bezier); + } + + void + AddArc( + CONST D2D1_ARC_SEGMENT &arc + ) + { + AddArc(&arc); + } +}; // interface ID2D1GeometrySink + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1TessellationSink +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906c1-12e2-11dc-9fed-001143a055f9") ID2D1TessellationSink : public IUnknown +{ + + STDMETHOD_(void, AddTriangles)( + __in_ecount(trianglesCount) CONST D2D1_TRIANGLE *triangles, + UINT trianglesCount + ) PURE; + + STDMETHOD(Close)( + ) PURE; +}; // interface ID2D1TessellationSink + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1PathGeometry +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906a5-12e2-11dc-9fed-001143a055f9") ID2D1PathGeometry : public ID2D1Geometry +{ + + + // + // Opens a geometry sink that will be used to create this path geometry. + // + STDMETHOD(Open)( + __deref_out ID2D1GeometrySink **geometrySink + ) PURE; + + + // + // Retrieve the contents of this geometry. The caller passes an implementation of a + // ID2D1GeometrySink interface to receive the data. + // + STDMETHOD(Stream)( + __in ID2D1GeometrySink *geometrySink + ) CONST PURE; + + STDMETHOD(GetSegmentCount)( + __out UINT32 *count + ) CONST PURE; + + STDMETHOD(GetFigureCount)( + __out UINT32 *count + ) CONST PURE; +}; // interface ID2D1PathGeometry + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1Mesh +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd906c2-12e2-11dc-9fed-001143a055f9") ID2D1Mesh : public ID2D1Resource +{ + + + // + // Opens the mesh for population. + // + STDMETHOD(Open)( + __deref_out ID2D1TessellationSink **tessellationSink + ) PURE; +}; // interface ID2D1Mesh + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1Layer +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd9069b-12e2-11dc-9fed-001143a055f9") ID2D1Layer : public ID2D1Resource +{ + + STDMETHOD_(D2D1_SIZE_F, GetSize)( + ) CONST PURE; +}; // interface ID2D1Layer + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1DrawingStateBlock +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("28506e39-ebf6-46a1-bb47-fd85565ab957") ID2D1DrawingStateBlock : public ID2D1Resource +{ + + + // + // Retrieves the state currently contained within this state block resource. + // + STDMETHOD_(void, GetDescription)( + __out D2D1_DRAWING_STATE_DESCRIPTION *stateDescription + ) CONST PURE; + + + // + // Sets the state description of this state block resource. + // + STDMETHOD_(void, SetDescription)( + __in CONST D2D1_DRAWING_STATE_DESCRIPTION *stateDescription + ) PURE; + + + // + // Sets the text rendering parameters of this state block resource. + // + STDMETHOD_(void, SetTextRenderingParams)( + __in_opt IDWriteRenderingParams *textRenderingParams = NULL + ) PURE; + + + // + // Retrieves the text rendering parameters contained within this state block + // resource. If a NULL text rendering parameter was specified, NULL will be + // returned. + // + STDMETHOD_(void, GetTextRenderingParams)( + __deref_out_opt IDWriteRenderingParams **textRenderingParams + ) CONST PURE; + + void + SetDescription( + CONST D2D1_DRAWING_STATE_DESCRIPTION &stateDescription + ) + { + SetDescription(&stateDescription); + } +}; // interface ID2D1DrawingStateBlock + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1RenderTarget +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd90694-12e2-11dc-9fed-001143a055f9") ID2D1RenderTarget : public ID2D1Resource +{ + + + // + // Create a D2D bitmap by copying from memory, or create uninitialized. + // + STDMETHOD(CreateBitmap)( + D2D1_SIZE_U size, + __in_opt CONST void *srcData, + UINT32 pitch, + __in CONST D2D1_BITMAP_PROPERTIES *bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) PURE; + + + // + // Create a D2D bitmap by copying a WIC bitmap. + // + STDMETHOD(CreateBitmapFromWicBitmap)( + __in IWICBitmapSource *wicBitmapSource, + __in_opt CONST D2D1_BITMAP_PROPERTIES *bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) PURE; + + + // + // Create a D2D bitmap by sharing bits from another resource. The bitmap must be + // compatible with the render target for the call to succeed. + // For example, an IWICBitmap can be shared with a software target, or a DXGI + // surface can be shared with a DXGI render target. + // + STDMETHOD(CreateSharedBitmap)( + __in REFIID riid, + __inout void *data, + __in_opt CONST D2D1_BITMAP_PROPERTIES *bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) PURE; + + + // + // Creates a bitmap brush. The bitmap is scaled, rotated, skewed or tiled to fill + // or pen a geometry. + // + STDMETHOD(CreateBitmapBrush)( + __in ID2D1Bitmap *bitmap, + __in_opt CONST D2D1_BITMAP_BRUSH_PROPERTIES *bitmapBrushProperties, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __deref_out ID2D1BitmapBrush **bitmapBrush + ) PURE; + + STDMETHOD(CreateSolidColorBrush)( + __in CONST D2D1_COLOR_F *color, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __deref_out ID2D1SolidColorBrush **solidColorBrush + ) PURE; + + + // + // A gradient stop collection represents a set of stops in an ideal unit length. + // This is the source resource for a linear gradient and radial gradient brush. + // + STDMETHOD(CreateGradientStopCollection)( + __in_ecount(gradientStopsCount) CONST D2D1_GRADIENT_STOP *gradientStops, + __range(>=,1) UINT gradientStopsCount, + + // + // Specifies which space the color interpolation occurs in. + // + D2D1_GAMMA colorInterpolationGamma, + + // + // Specifies how the gradient will be extended outside of the unit length. + // + D2D1_EXTEND_MODE extendMode, + __deref_out ID2D1GradientStopCollection **gradientStopCollection + ) PURE; + + STDMETHOD(CreateLinearGradientBrush)( + __in CONST D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *linearGradientBrushProperties, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1LinearGradientBrush **linearGradientBrush + ) PURE; + + STDMETHOD(CreateRadialGradientBrush)( + __in CONST D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *radialGradientBrushProperties, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1RadialGradientBrush **radialGradientBrush + ) PURE; + + + // + // Creates a bitmap render target whose bitmap can be used as a source for + // rendering in the API. + // + STDMETHOD(CreateCompatibleRenderTarget)( + + // + // The requested size of the target in DIPs. If the pixel size is not specified, + // the DPI is inherited from the parent target. However, the render target will + // never contain a fractional number of pixels. + // + __in_opt CONST D2D1_SIZE_F *desiredSize, + + // + // The requested size of the render target in pixels. If the DIP size is also + // specified, the DPI is calculated from these two values. If the desired size is + // not specified, the DPI is inherited from the parent render target. If neither + // value is specified, the compatible render target will be the same size and have + // the same DPI as the parent target. + // + __in_opt CONST D2D1_SIZE_U *desiredPixelSize, + + // + // The desired pixel format. The format must be compatible with the parent render + // target type. If the format is not specified, it will be inherited from the + // parent render target. + // + __in_opt CONST D2D1_PIXEL_FORMAT *desiredFormat, + + // + // Allows the caller to retrieve a GDI compatible render target. + // + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, + + // + // The returned bitmap render target. + // + __deref_out ID2D1BitmapRenderTarget **bitmapRenderTarget + ) PURE; + + + // + // Creates a layer resource that can be used on any target and which will resize + // under the covers if necessary. + // + STDMETHOD(CreateLayer)( + + // + // The resolution independent minimum size hint for the layer resource. Specify + // this to prevent unwanted reallocation of the layer backing store. The size is in + // DIPs, but, it is unaffected by the current world transform. If the size is + // unspecified, the returned resource is a placeholder and the backing store will + // be allocated to be the minimum size that can hold the content when the layer is + // pushed. + // + __in_opt CONST D2D1_SIZE_F *size, + __deref_out ID2D1Layer **layer + ) PURE; + + + // + // Create a D2D mesh. + // + STDMETHOD(CreateMesh)( + __deref_out ID2D1Mesh **mesh + ) PURE; + + STDMETHOD_(void, DrawLine)( + D2D1_POINT_2F point0, + D2D1_POINT_2F point1, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) PURE; + + STDMETHOD_(void, DrawRectangle)( + __in CONST D2D1_RECT_F *rect, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) PURE; + + STDMETHOD_(void, FillRectangle)( + __in CONST D2D1_RECT_F *rect, + __in ID2D1Brush *brush + ) PURE; + + STDMETHOD_(void, DrawRoundedRectangle)( + __in CONST D2D1_ROUNDED_RECT *roundedRect, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) PURE; + + STDMETHOD_(void, FillRoundedRectangle)( + __in CONST D2D1_ROUNDED_RECT *roundedRect, + __in ID2D1Brush *brush + ) PURE; + + STDMETHOD_(void, DrawEllipse)( + __in CONST D2D1_ELLIPSE *ellipse, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) PURE; + + STDMETHOD_(void, FillEllipse)( + __in CONST D2D1_ELLIPSE *ellipse, + __in ID2D1Brush *brush + ) PURE; + + STDMETHOD_(void, DrawGeometry)( + __in ID2D1Geometry *geometry, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) PURE; + + STDMETHOD_(void, FillGeometry)( + __in ID2D1Geometry *geometry, + __in ID2D1Brush *brush, + + // + // An optionally specified opacity brush. Only the alpha channel of the + // corresponding brush will be sampled and will be applied to the entire fill of + // the geometry. If this brush is specified, the fill brush must be a bitmap brush + // with an extend mode of D2D1_EXTEND_MODE_CLAMP. + // + __in_opt ID2D1Brush *opacityBrush = NULL + ) PURE; + + + // + // Fill a mesh. Since meshes can only render aliased content, the render target + // antialiasing mode must be set to aliased. + // + STDMETHOD_(void, FillMesh)( + __in ID2D1Mesh *mesh, + __in ID2D1Brush *brush + ) PURE; + + + // + // Fill using the opacity channel of the supplied bitmap as a mask. The alpha + // channel of the bitmap is used to represent the coverage of the geometry at each + // pixel, and this is filled appropriately with the brush. The render target + // antialiasing mode must be set to aliased. + // + STDMETHOD_(void, FillOpacityMask)( + __in ID2D1Bitmap *opacityMask, + __in ID2D1Brush *brush, + D2D1_OPACITY_MASK_CONTENT content, + __in_opt CONST D2D1_RECT_F *destinationRectangle = NULL, + __in_opt CONST D2D1_RECT_F *sourceRectangle = NULL + ) PURE; + + STDMETHOD_(void, DrawBitmap)( + __in ID2D1Bitmap *bitmap, + __in_opt CONST D2D1_RECT_F *destinationRectangle = NULL, + FLOAT opacity = 1.0f, + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, + __in_opt CONST D2D1_RECT_F *sourceRectangle = NULL + ) PURE; + + + // + // Draws the text within the given layout rectangle and by default also snaps and + // clips it to the content bounds. + // + STDMETHOD_(void, DrawText)( + __in_ecount(stringLength) CONST WCHAR *string, + UINT stringLength, + __in IDWriteTextFormat *textFormat, + __in CONST D2D1_RECT_F *layoutRect, + __in ID2D1Brush *defaultForegroundBrush, + D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE, + DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL + ) PURE; + + + // + // Draw a snapped text layout object. Since the layout is not subsequently changed, + // this can be more effecient than DrawText when drawing the same layout + // repeatedly. + // + STDMETHOD_(void, DrawTextLayout)( + D2D1_POINT_2F origin, + __in IDWriteTextLayout *textLayout, + __in ID2D1Brush *defaultForegroundBrush, + + // + // The specified text options. NOTE: By default the text is clipped to the layout + // bounds. This is derived from the origin and the layout bounds of the + // corresponding IDWriteTextLayout object. + // + D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE + ) PURE; + + STDMETHOD_(void, DrawGlyphRun)( + D2D1_POINT_2F baselineOrigin, + __in CONST DWRITE_GLYPH_RUN *glyphRun, + __in ID2D1Brush *foregroundBrush, + DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL + ) PURE; + + STDMETHOD_(void, SetTransform)( + __in CONST D2D1_MATRIX_3X2_F *transform + ) PURE; + + STDMETHOD_(void, GetTransform)( + __out D2D1_MATRIX_3X2_F *transform + ) CONST PURE; + + STDMETHOD_(void, SetAntialiasMode)( + D2D1_ANTIALIAS_MODE antialiasMode + ) PURE; + + STDMETHOD_(D2D1_ANTIALIAS_MODE, GetAntialiasMode)( + ) CONST PURE; + + STDMETHOD_(void, SetTextAntialiasMode)( + D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode + ) PURE; + + STDMETHOD_(D2D1_TEXT_ANTIALIAS_MODE, GetTextAntialiasMode)( + ) CONST PURE; + + STDMETHOD_(void, SetTextRenderingParams)( + __in_opt IDWriteRenderingParams *textRenderingParams = NULL + ) PURE; + + + // + // Retrieve the text render parameters. NOTE: If NULL is specified to + // SetTextRenderingParameters, NULL will be returned. + // + STDMETHOD_(void, GetTextRenderingParams)( + __deref_out_opt IDWriteRenderingParams **textRenderingParams + ) CONST PURE; + + + // + // Set a tag to correspond to the succeeding primitives. If an error occurs + // rendering a primtive, the tags can be returned from the Flush or EndDraw call. + // + STDMETHOD_(void, SetTags)( + D2D1_TAG tag1, + D2D1_TAG tag2 + ) PURE; + + + // + // Retrieves the currently set tags. This does not retrieve the tags corresponding + // to any primitive that is in error. + // + STDMETHOD_(void, GetTags)( + __out_opt D2D1_TAG *tag1 = NULL, + __out_opt D2D1_TAG *tag2 = NULL + ) CONST PURE; + + + // + // Start a layer of drawing calls. The way in which the layer must be resolved is + // specified first as well as the logical resource that stores the layer + // parameters. The supplied layer resource might grow if the specified content + // cannot fit inside it. The layer will grow monitonically on each axis. + // + STDMETHOD_(void, PushLayer)( + __in CONST D2D1_LAYER_PARAMETERS *layerParameters, + __in ID2D1Layer *layer + ) PURE; + + + // + // Ends a layer that was defined with particular layer resources. + // + STDMETHOD_(void, PopLayer)( + ) PURE; + + STDMETHOD(Flush)( + __out_opt D2D1_TAG *tag1 = NULL, + __out_opt D2D1_TAG *tag2 = NULL + ) PURE; + + + // + // Gets the current drawing state and saves it into the supplied + // IDrawingStatckBlock. + // + STDMETHOD_(void, SaveDrawingState)( + __inout ID2D1DrawingStateBlock *drawingStateBlock + ) CONST PURE; + + + // + // Copies the state stored in the block interface. + // + STDMETHOD_(void, RestoreDrawingState)( + __in ID2D1DrawingStateBlock *drawingStateBlock + ) PURE; + + + // + // Pushes a clip. The clip can be antialiased. The clip must be axis aligned. If + // the current world transform is not axis preserving, then the bounding box of the + // transformed clip rect will be used. The clip will remain in effect until a + // PopAxisAligned clip call is made. + // + STDMETHOD_(void, PushAxisAlignedClip)( + __in CONST D2D1_RECT_F *clipRect, + D2D1_ANTIALIAS_MODE antialiasMode + ) PURE; + + STDMETHOD_(void, PopAxisAlignedClip)( + ) PURE; + + STDMETHOD_(void, Clear)( + __in_opt CONST D2D1_COLOR_F *clearColor = NULL + ) PURE; + + + // + // Start drawing on this render target. Draw calls can only be issued between a + // BeginDraw and EndDraw call. + // + STDMETHOD_(void, BeginDraw)( + ) PURE; + + + // + // Ends drawing on the render target, error results can be retrieved at this time, + // or when calling flush. + // + STDMETHOD(EndDraw)( + __out_opt D2D1_TAG *tag1 = NULL, + __out_opt D2D1_TAG *tag2 = NULL + ) PURE; + + STDMETHOD_(D2D1_PIXEL_FORMAT, GetPixelFormat)( + ) CONST PURE; + + + // + // Sets the DPI on the render target. This results in the render target being + // interpretted to a different scale. Neither DPI can be negative. If zero is + // specified for both, the system DPI is chosen. If one is zero and the other + // unspecified, the DPI is not changed. + // + STDMETHOD_(void, SetDpi)( + FLOAT dpiX, + FLOAT dpiY + ) PURE; + + + // + // Return the current DPI from the target. + // + STDMETHOD_(void, GetDpi)( + __out FLOAT *dpiX, + __out FLOAT *dpiY + ) CONST PURE; + + + // + // Returns the size of the render target in DIPs. + // + STDMETHOD_(D2D1_SIZE_F, GetSize)( + ) CONST PURE; + + + // + // Returns the size of the render target in pixels. + // + STDMETHOD_(D2D1_SIZE_U, GetPixelSize)( + ) CONST PURE; + + + // + // Returns the maximum bitmap and render target size that is guaranteed to be + // supported by the render target. + // + STDMETHOD_(UINT32, GetMaximumBitmapSize)( + ) CONST PURE; + + + // + // Returns true if the given properties are supported by this render target. The + // DPI is ignored. NOTE: If the render target type is software, then neither + // D2D1_FEATURE_LEVEL_9 nor D2D1_FEATURE_LEVEL_10 will be considered to be + // supported. + // + STDMETHOD_(BOOL, IsSupported)( + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties + ) CONST PURE; + + HRESULT + CreateBitmap( + D2D1_SIZE_U size, + __in_opt CONST void *srcData, + UINT32 pitch, + CONST D2D1_BITMAP_PROPERTIES &bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) + { + return CreateBitmap(size, srcData, pitch, &bitmapProperties, bitmap); + } + + HRESULT + CreateBitmap( + D2D1_SIZE_U size, + CONST D2D1_BITMAP_PROPERTIES &bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) + { + return CreateBitmap(size, NULL, 0, &bitmapProperties, bitmap); + } + + + // + // Create a D2D bitmap by copying a WIC bitmap. + // + HRESULT + CreateBitmapFromWicBitmap( + __in IWICBitmapSource *wicBitmapSource, + CONST D2D1_BITMAP_PROPERTIES &bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) + { + return CreateBitmapFromWicBitmap(wicBitmapSource, &bitmapProperties, bitmap); + } + + + // + // Create a D2D bitmap by copying a WIC bitmap. + // + HRESULT + CreateBitmapFromWicBitmap( + __in IWICBitmapSource *wicBitmapSource, + __deref_out ID2D1Bitmap **bitmap + ) + { + return CreateBitmapFromWicBitmap(wicBitmapSource, NULL, bitmap); + } + + + // + // Creates a bitmap brush. The bitmap is scaled, rotated, skewed or tiled to fill + // or pen a geometry. + // + HRESULT + CreateBitmapBrush( + __in ID2D1Bitmap *bitmap, + __deref_out ID2D1BitmapBrush **bitmapBrush + ) + { + return CreateBitmapBrush(bitmap, NULL, NULL, bitmapBrush); + } + + + // + // Creates a bitmap brush. The bitmap is scaled, rotated, skewed or tiled to fill + // or pen a geometry. + // + HRESULT + CreateBitmapBrush( + __in ID2D1Bitmap *bitmap, + CONST D2D1_BITMAP_BRUSH_PROPERTIES &bitmapBrushProperties, + __deref_out ID2D1BitmapBrush **bitmapBrush + ) + { + return CreateBitmapBrush(bitmap, &bitmapBrushProperties, NULL, bitmapBrush); + } + + + // + // Creates a bitmap brush. The bitmap is scaled, rotated, skewed or tiled to fill + // or pen a geometry. + // + HRESULT + CreateBitmapBrush( + __in ID2D1Bitmap *bitmap, + CONST D2D1_BITMAP_BRUSH_PROPERTIES &bitmapBrushProperties, + CONST D2D1_BRUSH_PROPERTIES &brushProperties, + __deref_out ID2D1BitmapBrush **bitmapBrush + ) + { + return CreateBitmapBrush(bitmap, &bitmapBrushProperties, &brushProperties, bitmapBrush); + } + + HRESULT + CreateSolidColorBrush( + CONST D2D1_COLOR_F &color, + __deref_out ID2D1SolidColorBrush **solidColorBrush + ) + { + return CreateSolidColorBrush(&color, NULL, solidColorBrush); + } + + HRESULT + CreateSolidColorBrush( + CONST D2D1_COLOR_F &color, + CONST D2D1_BRUSH_PROPERTIES &brushProperties, + __deref_out ID2D1SolidColorBrush **solidColorBrush + ) + { + return CreateSolidColorBrush(&color, &brushProperties, solidColorBrush); + } + + HRESULT + CreateGradientStopCollection( + __in_ecount(gradientStopsCount) CONST D2D1_GRADIENT_STOP *gradientStops, + UINT gradientStopsCount, + __deref_out ID2D1GradientStopCollection **gradientStopCollection + ) + { + return CreateGradientStopCollection(gradientStops, gradientStopsCount, D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, gradientStopCollection); + } + + HRESULT + CreateLinearGradientBrush( + CONST D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES &linearGradientBrushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1LinearGradientBrush **linearGradientBrush + ) + { + return CreateLinearGradientBrush(&linearGradientBrushProperties, NULL, gradientStopCollection, linearGradientBrush); + } + + HRESULT + CreateLinearGradientBrush( + CONST D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES &linearGradientBrushProperties, + CONST D2D1_BRUSH_PROPERTIES &brushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1LinearGradientBrush **linearGradientBrush + ) + { + return CreateLinearGradientBrush(&linearGradientBrushProperties, &brushProperties, gradientStopCollection, linearGradientBrush); + } + + HRESULT + CreateRadialGradientBrush( + CONST D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES &radialGradientBrushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1RadialGradientBrush **radialGradientBrush + ) + { + return CreateRadialGradientBrush(&radialGradientBrushProperties, NULL, gradientStopCollection, radialGradientBrush); + } + + HRESULT + CreateRadialGradientBrush( + CONST D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES &radialGradientBrushProperties, + CONST D2D1_BRUSH_PROPERTIES &brushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1RadialGradientBrush **radialGradientBrush + ) + { + return CreateRadialGradientBrush(&radialGradientBrushProperties, &brushProperties, gradientStopCollection, radialGradientBrush); + } + + HRESULT + CreateCompatibleRenderTarget( + __deref_out ID2D1BitmapRenderTarget **bitmapRenderTarget + ) + { + return CreateCompatibleRenderTarget(NULL, NULL, NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, bitmapRenderTarget); + } + + HRESULT + CreateCompatibleRenderTarget( + D2D1_SIZE_F desiredSize, + __deref_out ID2D1BitmapRenderTarget **bitmapRenderTarget + ) + { + return CreateCompatibleRenderTarget(&desiredSize, NULL, NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, bitmapRenderTarget); + } + + HRESULT + CreateCompatibleRenderTarget( + D2D1_SIZE_F desiredSize, + D2D1_SIZE_U desiredPixelSize, + __deref_out ID2D1BitmapRenderTarget **bitmapRenderTarget + ) + { + return CreateCompatibleRenderTarget(&desiredSize, &desiredPixelSize, NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, bitmapRenderTarget); + } + + HRESULT + CreateCompatibleRenderTarget( + D2D1_SIZE_F desiredSize, + D2D1_SIZE_U desiredPixelSize, + D2D1_PIXEL_FORMAT desiredFormat, + __deref_out ID2D1BitmapRenderTarget **bitmapRenderTarget + ) + { + return CreateCompatibleRenderTarget(&desiredSize, &desiredPixelSize, &desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, bitmapRenderTarget); + } + + HRESULT + CreateCompatibleRenderTarget( + D2D1_SIZE_F desiredSize, + D2D1_SIZE_U desiredPixelSize, + D2D1_PIXEL_FORMAT desiredFormat, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, + __deref_out ID2D1BitmapRenderTarget **bitmapRenderTarget + ) + { + return CreateCompatibleRenderTarget(&desiredSize, &desiredPixelSize, &desiredFormat, options, bitmapRenderTarget); + } + + HRESULT + CreateLayer( + D2D1_SIZE_F size, + __deref_out ID2D1Layer **layer + ) + { + return CreateLayer(&size, layer); + } + + HRESULT + CreateLayer( + __deref_out ID2D1Layer **layer + ) + { + return CreateLayer(NULL, layer); + } + + void + DrawRectangle( + CONST D2D1_RECT_F &rect, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) + { + DrawRectangle(&rect, brush, strokeWidth, strokeStyle); + } + + void + FillRectangle( + CONST D2D1_RECT_F &rect, + __in ID2D1Brush *brush + ) + { + FillRectangle(&rect, brush); + } + + void + DrawRoundedRectangle( + CONST D2D1_ROUNDED_RECT &roundedRect, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) + { + DrawRoundedRectangle(&roundedRect, brush, strokeWidth, strokeStyle); + } + + void + FillRoundedRectangle( + CONST D2D1_ROUNDED_RECT &roundedRect, + __in ID2D1Brush *brush + ) + { + FillRoundedRectangle(&roundedRect, brush); + } + + void + DrawEllipse( + CONST D2D1_ELLIPSE &ellipse, + __in ID2D1Brush *brush, + FLOAT strokeWidth = 1.0f, + __in_opt ID2D1StrokeStyle *strokeStyle = NULL + ) + { + DrawEllipse(&ellipse, brush, strokeWidth, strokeStyle); + } + + void + FillEllipse( + CONST D2D1_ELLIPSE &ellipse, + __in ID2D1Brush *brush + ) + { + FillEllipse(&ellipse, brush); + } + + void + FillOpacityMask( + __in ID2D1Bitmap *opacityMask, + __in ID2D1Brush *brush, + D2D1_OPACITY_MASK_CONTENT content, + CONST D2D1_RECT_F &destinationRectangle, + CONST D2D1_RECT_F &sourceRectangle + ) + { + FillOpacityMask(opacityMask, brush, content, &destinationRectangle, &sourceRectangle); + } + + void + DrawBitmap( + __in ID2D1Bitmap *bitmap, + CONST D2D1_RECT_F &destinationRectangle, + FLOAT opacity = 1.0f, + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, + __in_opt CONST D2D1_RECT_F *sourceRectangle = NULL + ) + { + DrawBitmap(bitmap, &destinationRectangle, opacity, interpolationMode, sourceRectangle); + } + + void + DrawBitmap( + __in ID2D1Bitmap *bitmap, + CONST D2D1_RECT_F &destinationRectangle, + FLOAT opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode, + CONST D2D1_RECT_F &sourceRectangle + ) + { + DrawBitmap(bitmap, &destinationRectangle, opacity, interpolationMode, &sourceRectangle); + } + + void + SetTransform( + CONST D2D1_MATRIX_3X2_F &transform + ) + { + SetTransform(&transform); + } + + void + PushLayer( + CONST D2D1_LAYER_PARAMETERS &layerParameters, + __in ID2D1Layer *layer + ) + { + PushLayer(&layerParameters, layer); + } + + void + PushAxisAlignedClip( + CONST D2D1_RECT_F &clipRect, + D2D1_ANTIALIAS_MODE antialiasMode + ) + { + return PushAxisAlignedClip(&clipRect, antialiasMode); + } + + void + Clear( + CONST D2D1_COLOR_F &clearColor + ) + { + return Clear(&clearColor); + } + + + // + // Draws the text within the given layout rectangle and by default also snaps and + // clips it. + // + void + DrawText( + __in_ecount(stringLength) CONST WCHAR *string, + UINT stringLength, + __in IDWriteTextFormat *textFormat, + CONST D2D1_RECT_F &layoutRect, + __in ID2D1Brush *defaultForegroundBrush, + D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE, + DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL + ) + { + return DrawText(string, stringLength, textFormat, &layoutRect, defaultForegroundBrush, options, measuringMode); + } + + BOOL + IsSupported( + CONST D2D1_RENDER_TARGET_PROPERTIES &renderTargetProperties + ) CONST + { + return IsSupported(&renderTargetProperties); + } +}; // interface ID2D1RenderTarget + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1BitmapRenderTarget +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd90695-12e2-11dc-9fed-001143a055f9") ID2D1BitmapRenderTarget : public ID2D1RenderTarget +{ + + STDMETHOD(GetBitmap)( + __deref_out ID2D1Bitmap **bitmap + ) PURE; +}; // interface ID2D1BitmapRenderTarget + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1HwndRenderTarget +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("2cd90698-12e2-11dc-9fed-001143a055f9") ID2D1HwndRenderTarget : public ID2D1RenderTarget +{ + + STDMETHOD_(D2D1_WINDOW_STATE, CheckWindowState)( + ) PURE; + + + // + // Resize the buffer underlying the render target. This operation might fail if + // there is insufficent video memory or system memory, or if the render target is + // resized beyond the maximum bitmap size. If the method fails, the render target + // will be placed in a zombie state and D2DERR_RECREATE_TARGET will be returned + // from it when EndDraw is called. In addition an appropriate failure result will + // be returned from Resize. + // + STDMETHOD(Resize)( + __in CONST D2D1_SIZE_U *pixelSize + ) PURE; + + STDMETHOD_(HWND, GetHwnd)( + ) CONST PURE; + + HRESULT + Resize( + CONST D2D1_SIZE_U &pixelSize + ) + { + return Resize(&pixelSize); + } +}; // interface ID2D1HwndRenderTarget + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1GdiInteropRenderTarget +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("e0db51c3-6f77-4bae-b3d5-e47509b35838") ID2D1GdiInteropRenderTarget : public IUnknown +{ + + STDMETHOD(GetDC)( + D2D1_DC_INITIALIZE_MODE mode, + __out HDC *hdc + ) PURE; + + STDMETHOD(ReleaseDC)( + __in_opt CONST RECT *update + ) PURE; +}; // interface ID2D1GdiInteropRenderTarget + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1DCRenderTarget +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("1c51bc64-de61-46fd-9899-63a5d8f03950") ID2D1DCRenderTarget : public ID2D1RenderTarget +{ + + STDMETHOD(BindDC)( + __in CONST HDC hDC, + __in CONST RECT *pSubRect + ) PURE; +}; // interface ID2D1DCRenderTarget + + + +//+----------------------------------------------------------------------------- +// +// Interface: +// ID2D1Factory +// +// Synopsis: +// The root factory interface for all of D2D's objects. +// +//------------------------------------------------------------------------------ +interface D2D1_DECLARE_INTERFACE("06152247-6f50-465a-9245-118bfd3b6007") ID2D1Factory : public IUnknown +{ + + + // + // Cause the factory to refresh any system metrics that it might have been snapped + // on factory creation. + // + STDMETHOD(ReloadSystemMetrics)( + ) PURE; + + + // + // Retrieves the current desktop DPI. To refresh this, call ReloadSystemMetrics. + // + STDMETHOD_(void, GetDesktopDpi)( + __out FLOAT *dpiX, + __out FLOAT *dpiY + ) PURE; + + STDMETHOD(CreateRectangleGeometry)( + __in CONST D2D1_RECT_F *rectangle, + __deref_out ID2D1RectangleGeometry **rectangleGeometry + ) PURE; + + STDMETHOD(CreateRoundedRectangleGeometry)( + __in CONST D2D1_ROUNDED_RECT *roundedRectangle, + __deref_out ID2D1RoundedRectangleGeometry **roundedRectangleGeometry + ) PURE; + + STDMETHOD(CreateEllipseGeometry)( + __in CONST D2D1_ELLIPSE *ellipse, + __deref_out ID2D1EllipseGeometry **ellipseGeometry + ) PURE; + + + // + // Create a geometry which holds other geometries. + // + STDMETHOD(CreateGeometryGroup)( + D2D1_FILL_MODE fillMode, + __in_ecount(geometriesCount) ID2D1Geometry **geometries, + UINT geometriesCount, + __deref_out ID2D1GeometryGroup **geometryGroup + ) PURE; + + STDMETHOD(CreateTransformedGeometry)( + __in ID2D1Geometry *sourceGeometry, + __in CONST D2D1_MATRIX_3X2_F *transform, + __deref_out ID2D1TransformedGeometry **transformedGeometry + ) PURE; + + + // + // Returns an initially empty path geometry interface. A geometry sink is created + // off the interface to populate it. + // + STDMETHOD(CreatePathGeometry)( + __deref_out ID2D1PathGeometry **pathGeometry + ) PURE; + + + // + // Allows a non-default stroke style to be specified for a given geometry at draw + // time. + // + STDMETHOD(CreateStrokeStyle)( + __in CONST D2D1_STROKE_STYLE_PROPERTIES *strokeStyleProperties, + __in_ecount_opt(dashesCount) CONST FLOAT *dashes, + UINT dashesCount, + __deref_out ID2D1StrokeStyle **strokeStyle + ) PURE; + + + // + // Creates a new drawing state block, this can be used in subsequent + // SaveDrawingState and RestoreDrawingState operations on the render target. + // + STDMETHOD(CreateDrawingStateBlock)( + __in_opt CONST D2D1_DRAWING_STATE_DESCRIPTION *drawingStateDescription, + __in_opt IDWriteRenderingParams *textRenderingParams, + __deref_out ID2D1DrawingStateBlock **drawingStateBlock + ) PURE; + + + // + // Creates a render target which is a source of bitmaps. + // + STDMETHOD(CreateWicBitmapRenderTarget)( + __in IWICBitmap *target, + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __deref_out ID2D1RenderTarget **renderTarget + ) PURE; + + + // + // Creates a render target that appears on the display. + // + STDMETHOD(CreateHwndRenderTarget)( + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __in CONST D2D1_HWND_RENDER_TARGET_PROPERTIES *hwndRenderTargetProperties, + __deref_out ID2D1HwndRenderTarget **hwndRenderTarget + ) PURE; + + + // + // Creates a render target that draws to a DXGI Surface. The device that owns the + // surface is used for rendering. + // + STDMETHOD(CreateDxgiSurfaceRenderTarget)( + __in IDXGISurface *dxgiSurface, + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __deref_out ID2D1RenderTarget **renderTarget + ) PURE; + + + // + // Creates a render target that draws to a GDI device context. + // + STDMETHOD(CreateDCRenderTarget)( + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __deref_out ID2D1DCRenderTarget **dcRenderTarget + ) PURE; + + HRESULT + CreateRectangleGeometry( + CONST D2D1_RECT_F &rectangle, + __deref_out ID2D1RectangleGeometry **rectangleGeometry + ) + { + return CreateRectangleGeometry(&rectangle, rectangleGeometry); + } + + HRESULT + CreateRoundedRectangleGeometry( + CONST D2D1_ROUNDED_RECT &roundedRectangle, + __deref_out ID2D1RoundedRectangleGeometry **roundedRectangleGeometry + ) + { + return CreateRoundedRectangleGeometry(&roundedRectangle, roundedRectangleGeometry); + } + + HRESULT + CreateEllipseGeometry( + CONST D2D1_ELLIPSE &ellipse, + __deref_out ID2D1EllipseGeometry **ellipseGeometry + ) + { + return CreateEllipseGeometry(&ellipse, ellipseGeometry); + } + + HRESULT + CreateTransformedGeometry( + __in ID2D1Geometry *sourceGeometry, + CONST D2D1_MATRIX_3X2_F &transform, + __deref_out ID2D1TransformedGeometry **transformedGeometry + ) + { + return CreateTransformedGeometry(sourceGeometry, &transform, transformedGeometry); + } + + HRESULT + CreateStrokeStyle( + CONST D2D1_STROKE_STYLE_PROPERTIES &strokeStyleProperties, + __in_ecount(dashesCount) CONST FLOAT *dashes, + UINT dashesCount, + __deref_out ID2D1StrokeStyle **strokeStyle + ) + { + return CreateStrokeStyle(&strokeStyleProperties, dashes, dashesCount, strokeStyle); + } + + HRESULT + CreateDrawingStateBlock( + CONST D2D1_DRAWING_STATE_DESCRIPTION &drawingStateDescription, + __deref_out ID2D1DrawingStateBlock **drawingStateBlock + ) + { + return CreateDrawingStateBlock(&drawingStateDescription, NULL, drawingStateBlock); + } + + HRESULT + CreateDrawingStateBlock( + __deref_out ID2D1DrawingStateBlock **drawingStateBlock + ) + { + return CreateDrawingStateBlock(NULL, NULL, drawingStateBlock); + } + + HRESULT + CreateWicBitmapRenderTarget( + __in IWICBitmap *target, + CONST D2D1_RENDER_TARGET_PROPERTIES &renderTargetProperties, + __deref_out ID2D1RenderTarget **renderTarget + ) + { + return CreateWicBitmapRenderTarget(target, &renderTargetProperties, renderTarget); + } + + HRESULT + CreateHwndRenderTarget( + CONST D2D1_RENDER_TARGET_PROPERTIES &renderTargetProperties, + CONST D2D1_HWND_RENDER_TARGET_PROPERTIES &hwndRenderTargetProperties, + __deref_out ID2D1HwndRenderTarget **hwndRenderTarget + ) + { + return CreateHwndRenderTarget(&renderTargetProperties, &hwndRenderTargetProperties, hwndRenderTarget); + } + + HRESULT + CreateDxgiSurfaceRenderTarget( + __in IDXGISurface *dxgiSurface, + CONST D2D1_RENDER_TARGET_PROPERTIES &renderTargetProperties, + __deref_out ID2D1RenderTarget **renderTarget + ) + { + return CreateDxgiSurfaceRenderTarget(dxgiSurface, &renderTargetProperties, renderTarget); + } +}; // interface ID2D1Factory + + + +#endif + + +EXTERN_C CONST IID IID_ID2D1Resource; +EXTERN_C CONST IID IID_ID2D1Bitmap; +EXTERN_C CONST IID IID_ID2D1GradientStopCollection; +EXTERN_C CONST IID IID_ID2D1Brush; +EXTERN_C CONST IID IID_ID2D1BitmapBrush; +EXTERN_C CONST IID IID_ID2D1SolidColorBrush; +EXTERN_C CONST IID IID_ID2D1LinearGradientBrush; +EXTERN_C CONST IID IID_ID2D1RadialGradientBrush; +EXTERN_C CONST IID IID_ID2D1StrokeStyle; +EXTERN_C CONST IID IID_ID2D1Geometry; +EXTERN_C CONST IID IID_ID2D1RectangleGeometry; +EXTERN_C CONST IID IID_ID2D1RoundedRectangleGeometry; +EXTERN_C CONST IID IID_ID2D1EllipseGeometry; +EXTERN_C CONST IID IID_ID2D1GeometryGroup; +EXTERN_C CONST IID IID_ID2D1TransformedGeometry; +EXTERN_C CONST IID IID_ID2D1SimplifiedGeometrySink; +EXTERN_C CONST IID IID_ID2D1GeometrySink; +EXTERN_C CONST IID IID_ID2D1TessellationSink; +EXTERN_C CONST IID IID_ID2D1PathGeometry; +EXTERN_C CONST IID IID_ID2D1Mesh; +EXTERN_C CONST IID IID_ID2D1Layer; +EXTERN_C CONST IID IID_ID2D1DrawingStateBlock; +EXTERN_C CONST IID IID_ID2D1RenderTarget; +EXTERN_C CONST IID IID_ID2D1BitmapRenderTarget; +EXTERN_C CONST IID IID_ID2D1HwndRenderTarget; +EXTERN_C CONST IID IID_ID2D1GdiInteropRenderTarget; +EXTERN_C CONST IID IID_ID2D1DCRenderTarget; +EXTERN_C CONST IID IID_ID2D1Factory; + + +#ifdef D2D_USE_C_DEFINITIONS + + +typedef interface ID2D1Resource ID2D1Resource; + +typedef struct ID2D1ResourceVtbl +{ + + IUnknownVtbl Base; + + + STDMETHOD_(void, GetFactory)( + ID2D1Resource *This, + __deref_out ID2D1Factory **factory + ) PURE; +} ID2D1ResourceVtbl; + +interface ID2D1Resource +{ + CONST struct ID2D1ResourceVtbl *lpVtbl; +}; + + +#define ID2D1Resource_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1Resource_AddRef(This) \ + ((This)->lpVtbl->Base.AddRef((IUnknown *)This)) + +#define ID2D1Resource_Release(This) \ + ((This)->lpVtbl->Base.Release((IUnknown *)This)) + +#define ID2D1Resource_GetFactory(This, factory) \ + ((This)->lpVtbl->GetFactory(This, factory)) + +typedef interface ID2D1Bitmap ID2D1Bitmap; + +typedef struct ID2D1BitmapVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD_(D2D1_SIZE_F, GetSize)( + ID2D1Bitmap *This + ) PURE; + + STDMETHOD_(D2D1_SIZE_U, GetPixelSize)( + ID2D1Bitmap *This + ) PURE; + + STDMETHOD_(D2D1_PIXEL_FORMAT, GetPixelFormat)( + ID2D1Bitmap *This + ) PURE; + + STDMETHOD_(void, GetDpi)( + ID2D1Bitmap *This, + __out FLOAT *dpiX, + __out FLOAT *dpiY + ) PURE; + + STDMETHOD(CopyFromBitmap)( + ID2D1Bitmap *This, + __in_opt CONST D2D1_POINT_2U *destPoint, + __in ID2D1Bitmap *bitmap, + __in_opt CONST D2D1_RECT_U *srcRect + ) PURE; + + STDMETHOD(CopyFromRenderTarget)( + ID2D1Bitmap *This, + __in_opt CONST D2D1_POINT_2U *destPoint, + __in ID2D1RenderTarget *renderTarget, + __in_opt CONST D2D1_RECT_U *srcRect + ) PURE; + + STDMETHOD(CopyFromMemory)( + ID2D1Bitmap *This, + __in_opt CONST D2D1_RECT_U *dstRect, + __in CONST void *srcData, + UINT32 pitch + ) PURE; +} ID2D1BitmapVtbl; + +interface ID2D1Bitmap +{ + CONST struct ID2D1BitmapVtbl *lpVtbl; +}; + + +#define ID2D1Bitmap_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1Bitmap_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1Bitmap_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1Bitmap_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1Bitmap_GetSize(This) \ + ((This)->lpVtbl->GetSize(This)) + +#define ID2D1Bitmap_GetPixelSize(This) \ + ((This)->lpVtbl->GetPixelSize(This)) + +#define ID2D1Bitmap_GetPixelFormat(This) \ + ((This)->lpVtbl->GetPixelFormat(This)) + +#define ID2D1Bitmap_GetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->GetDpi(This, dpiX, dpiY)) + +#define ID2D1Bitmap_CopyFromBitmap(This, destPoint, bitmap, srcRect) \ + ((This)->lpVtbl->CopyFromBitmap(This, destPoint, bitmap, srcRect)) + +#define ID2D1Bitmap_CopyFromRenderTarget(This, destPoint, renderTarget, srcRect) \ + ((This)->lpVtbl->CopyFromRenderTarget(This, destPoint, renderTarget, srcRect)) + +#define ID2D1Bitmap_CopyFromMemory(This, dstRect, srcData, pitch) \ + ((This)->lpVtbl->CopyFromMemory(This, dstRect, srcData, pitch)) + +typedef interface ID2D1GradientStopCollection ID2D1GradientStopCollection; + +typedef struct ID2D1GradientStopCollectionVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD_(UINT32, GetGradientStopCount)( + ID2D1GradientStopCollection *This + ) PURE; + + STDMETHOD_(void, GetGradientStops)( + ID2D1GradientStopCollection *This, + __out_ecount(gradientStopsCount) D2D1_GRADIENT_STOP *gradientStops, + UINT gradientStopsCount + ) PURE; + + STDMETHOD_(D2D1_GAMMA, GetColorInterpolationGamma)( + ID2D1GradientStopCollection *This + ) PURE; + + STDMETHOD_(D2D1_EXTEND_MODE, GetExtendMode)( + ID2D1GradientStopCollection *This + ) PURE; +} ID2D1GradientStopCollectionVtbl; + +interface ID2D1GradientStopCollection +{ + CONST struct ID2D1GradientStopCollectionVtbl *lpVtbl; +}; + + +#define ID2D1GradientStopCollection_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1GradientStopCollection_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1GradientStopCollection_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1GradientStopCollection_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1GradientStopCollection_GetGradientStopCount(This) \ + ((This)->lpVtbl->GetGradientStopCount(This)) + +#define ID2D1GradientStopCollection_GetGradientStops(This, gradientStops, gradientStopsCount) \ + ((This)->lpVtbl->GetGradientStops(This, gradientStops, gradientStopsCount)) + +#define ID2D1GradientStopCollection_GetColorInterpolationGamma(This) \ + ((This)->lpVtbl->GetColorInterpolationGamma(This)) + +#define ID2D1GradientStopCollection_GetExtendMode(This) \ + ((This)->lpVtbl->GetExtendMode(This)) + +typedef interface ID2D1Brush ID2D1Brush; + +typedef struct ID2D1BrushVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD_(void, SetOpacity)( + ID2D1Brush *This, + FLOAT opacity + ) PURE; + + STDMETHOD_(void, SetTransform)( + ID2D1Brush *This, + __in CONST D2D1_MATRIX_3X2_F *transform + ) PURE; + + STDMETHOD_(FLOAT, GetOpacity)( + ID2D1Brush *This + ) PURE; + + STDMETHOD_(void, GetTransform)( + ID2D1Brush *This, + __out D2D1_MATRIX_3X2_F *transform + ) PURE; +} ID2D1BrushVtbl; + +interface ID2D1Brush +{ + CONST struct ID2D1BrushVtbl *lpVtbl; +}; + + +#define ID2D1Brush_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1Brush_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1Brush_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1Brush_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1Brush_SetOpacity(This, opacity) \ + ((This)->lpVtbl->SetOpacity(This, opacity)) + +#define ID2D1Brush_SetTransform(This, transform) \ + ((This)->lpVtbl->SetTransform(This, transform)) + +#define ID2D1Brush_GetOpacity(This) \ + ((This)->lpVtbl->GetOpacity(This)) + +#define ID2D1Brush_GetTransform(This, transform) \ + ((This)->lpVtbl->GetTransform(This, transform)) + +typedef interface ID2D1BitmapBrush ID2D1BitmapBrush; + +typedef struct ID2D1BitmapBrushVtbl +{ + + ID2D1BrushVtbl Base; + + + STDMETHOD_(void, SetExtendModeX)( + ID2D1BitmapBrush *This, + D2D1_EXTEND_MODE extendModeX + ) PURE; + + STDMETHOD_(void, SetExtendModeY)( + ID2D1BitmapBrush *This, + D2D1_EXTEND_MODE extendModeY + ) PURE; + + STDMETHOD_(void, SetInterpolationMode)( + ID2D1BitmapBrush *This, + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode + ) PURE; + + STDMETHOD_(void, SetBitmap)( + ID2D1BitmapBrush *This, + __in ID2D1Bitmap *bitmap + ) PURE; + + STDMETHOD_(D2D1_EXTEND_MODE, GetExtendModeX)( + ID2D1BitmapBrush *This + ) PURE; + + STDMETHOD_(D2D1_EXTEND_MODE, GetExtendModeY)( + ID2D1BitmapBrush *This + ) PURE; + + STDMETHOD_(D2D1_BITMAP_INTERPOLATION_MODE, GetInterpolationMode)( + ID2D1BitmapBrush *This + ) PURE; + + STDMETHOD_(void, GetBitmap)( + ID2D1BitmapBrush *This, + __deref_out ID2D1Bitmap **bitmap + ) PURE; +} ID2D1BitmapBrushVtbl; + +interface ID2D1BitmapBrush +{ + CONST struct ID2D1BitmapBrushVtbl *lpVtbl; +}; + + +#define ID2D1BitmapBrush_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1BitmapBrush_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1BitmapBrush_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1BitmapBrush_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1BitmapBrush_SetOpacity(This, opacity) \ + ((This)->lpVtbl->Base.SetOpacity((ID2D1Brush *)This, opacity)) + +#define ID2D1BitmapBrush_SetTransform(This, transform) \ + ((This)->lpVtbl->Base.SetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1BitmapBrush_GetOpacity(This) \ + ((This)->lpVtbl->Base.GetOpacity((ID2D1Brush *)This)) + +#define ID2D1BitmapBrush_GetTransform(This, transform) \ + ((This)->lpVtbl->Base.GetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1BitmapBrush_SetExtendModeX(This, extendModeX) \ + ((This)->lpVtbl->SetExtendModeX(This, extendModeX)) + +#define ID2D1BitmapBrush_SetExtendModeY(This, extendModeY) \ + ((This)->lpVtbl->SetExtendModeY(This, extendModeY)) + +#define ID2D1BitmapBrush_SetInterpolationMode(This, interpolationMode) \ + ((This)->lpVtbl->SetInterpolationMode(This, interpolationMode)) + +#define ID2D1BitmapBrush_SetBitmap(This, bitmap) \ + ((This)->lpVtbl->SetBitmap(This, bitmap)) + +#define ID2D1BitmapBrush_GetExtendModeX(This) \ + ((This)->lpVtbl->GetExtendModeX(This)) + +#define ID2D1BitmapBrush_GetExtendModeY(This) \ + ((This)->lpVtbl->GetExtendModeY(This)) + +#define ID2D1BitmapBrush_GetInterpolationMode(This) \ + ((This)->lpVtbl->GetInterpolationMode(This)) + +#define ID2D1BitmapBrush_GetBitmap(This, bitmap) \ + ((This)->lpVtbl->GetBitmap(This, bitmap)) + +typedef interface ID2D1SolidColorBrush ID2D1SolidColorBrush; + +typedef struct ID2D1SolidColorBrushVtbl +{ + + ID2D1BrushVtbl Base; + + + STDMETHOD_(void, SetColor)( + ID2D1SolidColorBrush *This, + __in CONST D2D1_COLOR_F *color + ) PURE; + + STDMETHOD_(D2D1_COLOR_F, GetColor)( + ID2D1SolidColorBrush *This + ) PURE; +} ID2D1SolidColorBrushVtbl; + +interface ID2D1SolidColorBrush +{ + CONST struct ID2D1SolidColorBrushVtbl *lpVtbl; +}; + + +#define ID2D1SolidColorBrush_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1SolidColorBrush_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1SolidColorBrush_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1SolidColorBrush_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1SolidColorBrush_SetOpacity(This, opacity) \ + ((This)->lpVtbl->Base.SetOpacity((ID2D1Brush *)This, opacity)) + +#define ID2D1SolidColorBrush_SetTransform(This, transform) \ + ((This)->lpVtbl->Base.SetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1SolidColorBrush_GetOpacity(This) \ + ((This)->lpVtbl->Base.GetOpacity((ID2D1Brush *)This)) + +#define ID2D1SolidColorBrush_GetTransform(This, transform) \ + ((This)->lpVtbl->Base.GetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1SolidColorBrush_SetColor(This, color) \ + ((This)->lpVtbl->SetColor(This, color)) + +#define ID2D1SolidColorBrush_GetColor(This) \ + ((This)->lpVtbl->GetColor(This)) + +typedef interface ID2D1LinearGradientBrush ID2D1LinearGradientBrush; + +typedef struct ID2D1LinearGradientBrushVtbl +{ + + ID2D1BrushVtbl Base; + + + STDMETHOD_(void, SetStartPoint)( + ID2D1LinearGradientBrush *This, + D2D1_POINT_2F startPoint + ) PURE; + + STDMETHOD_(void, SetEndPoint)( + ID2D1LinearGradientBrush *This, + D2D1_POINT_2F endPoint + ) PURE; + + STDMETHOD_(D2D1_POINT_2F, GetStartPoint)( + ID2D1LinearGradientBrush *This + ) PURE; + + STDMETHOD_(D2D1_POINT_2F, GetEndPoint)( + ID2D1LinearGradientBrush *This + ) PURE; + + STDMETHOD_(void, GetGradientStopCollection)( + ID2D1LinearGradientBrush *This, + __deref_out ID2D1GradientStopCollection **gradientStopCollection + ) PURE; +} ID2D1LinearGradientBrushVtbl; + +interface ID2D1LinearGradientBrush +{ + CONST struct ID2D1LinearGradientBrushVtbl *lpVtbl; +}; + + +#define ID2D1LinearGradientBrush_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1LinearGradientBrush_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1LinearGradientBrush_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1LinearGradientBrush_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1LinearGradientBrush_SetOpacity(This, opacity) \ + ((This)->lpVtbl->Base.SetOpacity((ID2D1Brush *)This, opacity)) + +#define ID2D1LinearGradientBrush_SetTransform(This, transform) \ + ((This)->lpVtbl->Base.SetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1LinearGradientBrush_GetOpacity(This) \ + ((This)->lpVtbl->Base.GetOpacity((ID2D1Brush *)This)) + +#define ID2D1LinearGradientBrush_GetTransform(This, transform) \ + ((This)->lpVtbl->Base.GetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1LinearGradientBrush_SetStartPoint(This, startPoint) \ + ((This)->lpVtbl->SetStartPoint(This, startPoint)) + +#define ID2D1LinearGradientBrush_SetEndPoint(This, endPoint) \ + ((This)->lpVtbl->SetEndPoint(This, endPoint)) + +#define ID2D1LinearGradientBrush_GetStartPoint(This) \ + ((This)->lpVtbl->GetStartPoint(This)) + +#define ID2D1LinearGradientBrush_GetEndPoint(This) \ + ((This)->lpVtbl->GetEndPoint(This)) + +#define ID2D1LinearGradientBrush_GetGradientStopCollection(This, gradientStopCollection) \ + ((This)->lpVtbl->GetGradientStopCollection(This, gradientStopCollection)) + +typedef interface ID2D1RadialGradientBrush ID2D1RadialGradientBrush; + +typedef struct ID2D1RadialGradientBrushVtbl +{ + + ID2D1BrushVtbl Base; + + + STDMETHOD_(void, SetCenter)( + ID2D1RadialGradientBrush *This, + D2D1_POINT_2F center + ) PURE; + + STDMETHOD_(void, SetGradientOriginOffset)( + ID2D1RadialGradientBrush *This, + D2D1_POINT_2F gradientOriginOffset + ) PURE; + + STDMETHOD_(void, SetRadiusX)( + ID2D1RadialGradientBrush *This, + FLOAT radiusX + ) PURE; + + STDMETHOD_(void, SetRadiusY)( + ID2D1RadialGradientBrush *This, + FLOAT radiusY + ) PURE; + + STDMETHOD_(D2D1_POINT_2F, GetCenter)( + ID2D1RadialGradientBrush *This + ) PURE; + + STDMETHOD_(D2D1_POINT_2F, GetGradientOriginOffset)( + ID2D1RadialGradientBrush *This + ) PURE; + + STDMETHOD_(FLOAT, GetRadiusX)( + ID2D1RadialGradientBrush *This + ) PURE; + + STDMETHOD_(FLOAT, GetRadiusY)( + ID2D1RadialGradientBrush *This + ) PURE; + + STDMETHOD_(void, GetGradientStopCollection)( + ID2D1RadialGradientBrush *This, + __deref_out ID2D1GradientStopCollection **gradientStopCollection + ) PURE; +} ID2D1RadialGradientBrushVtbl; + +interface ID2D1RadialGradientBrush +{ + CONST struct ID2D1RadialGradientBrushVtbl *lpVtbl; +}; + + +#define ID2D1RadialGradientBrush_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1RadialGradientBrush_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1RadialGradientBrush_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1RadialGradientBrush_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1RadialGradientBrush_SetOpacity(This, opacity) \ + ((This)->lpVtbl->Base.SetOpacity((ID2D1Brush *)This, opacity)) + +#define ID2D1RadialGradientBrush_SetTransform(This, transform) \ + ((This)->lpVtbl->Base.SetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1RadialGradientBrush_GetOpacity(This) \ + ((This)->lpVtbl->Base.GetOpacity((ID2D1Brush *)This)) + +#define ID2D1RadialGradientBrush_GetTransform(This, transform) \ + ((This)->lpVtbl->Base.GetTransform((ID2D1Brush *)This, transform)) + +#define ID2D1RadialGradientBrush_SetCenter(This, center) \ + ((This)->lpVtbl->SetCenter(This, center)) + +#define ID2D1RadialGradientBrush_SetGradientOriginOffset(This, gradientOriginOffset) \ + ((This)->lpVtbl->SetGradientOriginOffset(This, gradientOriginOffset)) + +#define ID2D1RadialGradientBrush_SetRadiusX(This, radiusX) \ + ((This)->lpVtbl->SetRadiusX(This, radiusX)) + +#define ID2D1RadialGradientBrush_SetRadiusY(This, radiusY) \ + ((This)->lpVtbl->SetRadiusY(This, radiusY)) + +#define ID2D1RadialGradientBrush_GetCenter(This) \ + ((This)->lpVtbl->GetCenter(This)) + +#define ID2D1RadialGradientBrush_GetGradientOriginOffset(This) \ + ((This)->lpVtbl->GetGradientOriginOffset(This)) + +#define ID2D1RadialGradientBrush_GetRadiusX(This) \ + ((This)->lpVtbl->GetRadiusX(This)) + +#define ID2D1RadialGradientBrush_GetRadiusY(This) \ + ((This)->lpVtbl->GetRadiusY(This)) + +#define ID2D1RadialGradientBrush_GetGradientStopCollection(This, gradientStopCollection) \ + ((This)->lpVtbl->GetGradientStopCollection(This, gradientStopCollection)) + +typedef interface ID2D1StrokeStyle ID2D1StrokeStyle; + +typedef struct ID2D1StrokeStyleVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD_(D2D1_CAP_STYLE, GetStartCap)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(D2D1_CAP_STYLE, GetEndCap)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(D2D1_CAP_STYLE, GetDashCap)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(FLOAT, GetMiterLimit)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(D2D1_LINE_JOIN, GetLineJoin)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(FLOAT, GetDashOffset)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(D2D1_DASH_STYLE, GetDashStyle)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(UINT32, GetDashesCount)( + ID2D1StrokeStyle *This + ) PURE; + + STDMETHOD_(void, GetDashes)( + ID2D1StrokeStyle *This, + __out_ecount(dashesCount) FLOAT *dashes, + UINT dashesCount + ) PURE; +} ID2D1StrokeStyleVtbl; + +interface ID2D1StrokeStyle +{ + CONST struct ID2D1StrokeStyleVtbl *lpVtbl; +}; + + +#define ID2D1StrokeStyle_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1StrokeStyle_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1StrokeStyle_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1StrokeStyle_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1StrokeStyle_GetStartCap(This) \ + ((This)->lpVtbl->GetStartCap(This)) + +#define ID2D1StrokeStyle_GetEndCap(This) \ + ((This)->lpVtbl->GetEndCap(This)) + +#define ID2D1StrokeStyle_GetDashCap(This) \ + ((This)->lpVtbl->GetDashCap(This)) + +#define ID2D1StrokeStyle_GetMiterLimit(This) \ + ((This)->lpVtbl->GetMiterLimit(This)) + +#define ID2D1StrokeStyle_GetLineJoin(This) \ + ((This)->lpVtbl->GetLineJoin(This)) + +#define ID2D1StrokeStyle_GetDashOffset(This) \ + ((This)->lpVtbl->GetDashOffset(This)) + +#define ID2D1StrokeStyle_GetDashStyle(This) \ + ((This)->lpVtbl->GetDashStyle(This)) + +#define ID2D1StrokeStyle_GetDashesCount(This) \ + ((This)->lpVtbl->GetDashesCount(This)) + +#define ID2D1StrokeStyle_GetDashes(This, dashes, dashesCount) \ + ((This)->lpVtbl->GetDashes(This, dashes, dashesCount)) + +typedef interface ID2D1Geometry ID2D1Geometry; + +typedef struct ID2D1GeometryVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD(GetBounds)( + ID2D1Geometry *This, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + __out D2D1_RECT_F *bounds + ) PURE; + + STDMETHOD(GetWidenedBounds)( + ID2D1Geometry *This, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out D2D1_RECT_F *bounds + ) PURE; + + STDMETHOD(StrokeContainsPoint)( + ID2D1Geometry *This, + D2D1_POINT_2F point, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out BOOL *contains + ) PURE; + + STDMETHOD(FillContainsPoint)( + ID2D1Geometry *This, + D2D1_POINT_2F point, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out BOOL *contains + ) PURE; + + STDMETHOD(CompareWithGeometry)( + ID2D1Geometry *This, + __in ID2D1Geometry *inputGeometry, + __in_opt CONST D2D1_MATRIX_3X2_F *inputGeometryTransform, + FLOAT flatteningTolerance, + __out D2D1_GEOMETRY_RELATION *relation + ) PURE; + + STDMETHOD(Simplify)( + ID2D1Geometry *This, + D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) PURE; + + STDMETHOD(Tessellate)( + ID2D1Geometry *This, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1TessellationSink *tessellationSink + ) PURE; + + STDMETHOD(CombineWithGeometry)( + ID2D1Geometry *This, + __in ID2D1Geometry *inputGeometry, + D2D1_COMBINE_MODE combineMode, + __in_opt CONST D2D1_MATRIX_3X2_F *inputGeometryTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) PURE; + + STDMETHOD(Outline)( + ID2D1Geometry *This, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) PURE; + + STDMETHOD(ComputeArea)( + ID2D1Geometry *This, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out FLOAT *area + ) PURE; + + STDMETHOD(ComputeLength)( + ID2D1Geometry *This, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out FLOAT *length + ) PURE; + + STDMETHOD(ComputePointAtLength)( + ID2D1Geometry *This, + FLOAT length, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __out_opt D2D1_POINT_2F *point, + __out_opt D2D1_POINT_2F *unitTangentVector + ) PURE; + + STDMETHOD(Widen)( + ID2D1Geometry *This, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle, + __in_opt CONST D2D1_MATRIX_3X2_F *worldTransform, + FLOAT flatteningTolerance, + __in ID2D1SimplifiedGeometrySink *geometrySink + ) PURE; +} ID2D1GeometryVtbl; + +interface ID2D1Geometry +{ + CONST struct ID2D1GeometryVtbl *lpVtbl; +}; + + +#define ID2D1Geometry_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1Geometry_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1Geometry_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1Geometry_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1Geometry_GetBounds(This, worldTransform, bounds) \ + ((This)->lpVtbl->GetBounds(This, worldTransform, bounds)) + +#define ID2D1Geometry_GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds) \ + ((This)->lpVtbl->GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds)) + +#define ID2D1Geometry_StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains)) + +#define ID2D1Geometry_FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains)) + +#define ID2D1Geometry_CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation) \ + ((This)->lpVtbl->CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation)) + +#define ID2D1Geometry_Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1Geometry_Tessellate(This, worldTransform, flatteningTolerance, tessellationSink) \ + ((This)->lpVtbl->Tessellate(This, worldTransform, flatteningTolerance, tessellationSink)) + +#define ID2D1Geometry_CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink)) + +#define ID2D1Geometry_Outline(This, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Outline(This, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1Geometry_ComputeArea(This, worldTransform, flatteningTolerance, area) \ + ((This)->lpVtbl->ComputeArea(This, worldTransform, flatteningTolerance, area)) + +#define ID2D1Geometry_ComputeLength(This, worldTransform, flatteningTolerance, length) \ + ((This)->lpVtbl->ComputeLength(This, worldTransform, flatteningTolerance, length)) + +#define ID2D1Geometry_ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector) \ + ((This)->lpVtbl->ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector)) + +#define ID2D1Geometry_Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink)) + +typedef interface ID2D1RectangleGeometry ID2D1RectangleGeometry; + +typedef struct ID2D1RectangleGeometryVtbl +{ + + ID2D1GeometryVtbl Base; + + + STDMETHOD_(void, GetRect)( + ID2D1RectangleGeometry *This, + __out D2D1_RECT_F *rect + ) PURE; +} ID2D1RectangleGeometryVtbl; + +interface ID2D1RectangleGeometry +{ + CONST struct ID2D1RectangleGeometryVtbl *lpVtbl; +}; + + +#define ID2D1RectangleGeometry_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1RectangleGeometry_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1RectangleGeometry_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1RectangleGeometry_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1RectangleGeometry_GetBounds(This, worldTransform, bounds) \ + ((This)->lpVtbl->Base.GetBounds((ID2D1Geometry *)This, worldTransform, bounds)) + +#define ID2D1RectangleGeometry_GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds) \ + ((This)->lpVtbl->Base.GetWidenedBounds((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds)) + +#define ID2D1RectangleGeometry_StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.StrokeContainsPoint((ID2D1Geometry *)This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains)) + +#define ID2D1RectangleGeometry_FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.FillContainsPoint((ID2D1Geometry *)This, point, worldTransform, flatteningTolerance, contains)) + +#define ID2D1RectangleGeometry_CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation) \ + ((This)->lpVtbl->Base.CompareWithGeometry((ID2D1Geometry *)This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation)) + +#define ID2D1RectangleGeometry_Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Simplify((ID2D1Geometry *)This, simplificationOption, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RectangleGeometry_Tessellate(This, worldTransform, flatteningTolerance, tessellationSink) \ + ((This)->lpVtbl->Base.Tessellate((ID2D1Geometry *)This, worldTransform, flatteningTolerance, tessellationSink)) + +#define ID2D1RectangleGeometry_CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.CombineWithGeometry((ID2D1Geometry *)This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RectangleGeometry_Outline(This, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Outline((ID2D1Geometry *)This, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RectangleGeometry_ComputeArea(This, worldTransform, flatteningTolerance, area) \ + ((This)->lpVtbl->Base.ComputeArea((ID2D1Geometry *)This, worldTransform, flatteningTolerance, area)) + +#define ID2D1RectangleGeometry_ComputeLength(This, worldTransform, flatteningTolerance, length) \ + ((This)->lpVtbl->Base.ComputeLength((ID2D1Geometry *)This, worldTransform, flatteningTolerance, length)) + +#define ID2D1RectangleGeometry_ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector) \ + ((This)->lpVtbl->Base.ComputePointAtLength((ID2D1Geometry *)This, length, worldTransform, flatteningTolerance, point, unitTangentVector)) + +#define ID2D1RectangleGeometry_Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Widen((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RectangleGeometry_GetRect(This, rect) \ + ((This)->lpVtbl->GetRect(This, rect)) + +typedef interface ID2D1RoundedRectangleGeometry ID2D1RoundedRectangleGeometry; + +typedef struct ID2D1RoundedRectangleGeometryVtbl +{ + + ID2D1GeometryVtbl Base; + + + STDMETHOD_(void, GetRoundedRect)( + ID2D1RoundedRectangleGeometry *This, + __out D2D1_ROUNDED_RECT *roundedRect + ) PURE; +} ID2D1RoundedRectangleGeometryVtbl; + +interface ID2D1RoundedRectangleGeometry +{ + CONST struct ID2D1RoundedRectangleGeometryVtbl *lpVtbl; +}; + + +#define ID2D1RoundedRectangleGeometry_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1RoundedRectangleGeometry_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1RoundedRectangleGeometry_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1RoundedRectangleGeometry_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1RoundedRectangleGeometry_GetBounds(This, worldTransform, bounds) \ + ((This)->lpVtbl->Base.GetBounds((ID2D1Geometry *)This, worldTransform, bounds)) + +#define ID2D1RoundedRectangleGeometry_GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds) \ + ((This)->lpVtbl->Base.GetWidenedBounds((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds)) + +#define ID2D1RoundedRectangleGeometry_StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.StrokeContainsPoint((ID2D1Geometry *)This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains)) + +#define ID2D1RoundedRectangleGeometry_FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.FillContainsPoint((ID2D1Geometry *)This, point, worldTransform, flatteningTolerance, contains)) + +#define ID2D1RoundedRectangleGeometry_CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation) \ + ((This)->lpVtbl->Base.CompareWithGeometry((ID2D1Geometry *)This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation)) + +#define ID2D1RoundedRectangleGeometry_Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Simplify((ID2D1Geometry *)This, simplificationOption, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RoundedRectangleGeometry_Tessellate(This, worldTransform, flatteningTolerance, tessellationSink) \ + ((This)->lpVtbl->Base.Tessellate((ID2D1Geometry *)This, worldTransform, flatteningTolerance, tessellationSink)) + +#define ID2D1RoundedRectangleGeometry_CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.CombineWithGeometry((ID2D1Geometry *)This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RoundedRectangleGeometry_Outline(This, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Outline((ID2D1Geometry *)This, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RoundedRectangleGeometry_ComputeArea(This, worldTransform, flatteningTolerance, area) \ + ((This)->lpVtbl->Base.ComputeArea((ID2D1Geometry *)This, worldTransform, flatteningTolerance, area)) + +#define ID2D1RoundedRectangleGeometry_ComputeLength(This, worldTransform, flatteningTolerance, length) \ + ((This)->lpVtbl->Base.ComputeLength((ID2D1Geometry *)This, worldTransform, flatteningTolerance, length)) + +#define ID2D1RoundedRectangleGeometry_ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector) \ + ((This)->lpVtbl->Base.ComputePointAtLength((ID2D1Geometry *)This, length, worldTransform, flatteningTolerance, point, unitTangentVector)) + +#define ID2D1RoundedRectangleGeometry_Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Widen((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1RoundedRectangleGeometry_GetRoundedRect(This, roundedRect) \ + ((This)->lpVtbl->GetRoundedRect(This, roundedRect)) + +typedef interface ID2D1EllipseGeometry ID2D1EllipseGeometry; + +typedef struct ID2D1EllipseGeometryVtbl +{ + + ID2D1GeometryVtbl Base; + + + STDMETHOD_(void, GetEllipse)( + ID2D1EllipseGeometry *This, + __out D2D1_ELLIPSE *ellipse + ) PURE; +} ID2D1EllipseGeometryVtbl; + +interface ID2D1EllipseGeometry +{ + CONST struct ID2D1EllipseGeometryVtbl *lpVtbl; +}; + + +#define ID2D1EllipseGeometry_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1EllipseGeometry_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1EllipseGeometry_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1EllipseGeometry_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1EllipseGeometry_GetBounds(This, worldTransform, bounds) \ + ((This)->lpVtbl->Base.GetBounds((ID2D1Geometry *)This, worldTransform, bounds)) + +#define ID2D1EllipseGeometry_GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds) \ + ((This)->lpVtbl->Base.GetWidenedBounds((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds)) + +#define ID2D1EllipseGeometry_StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.StrokeContainsPoint((ID2D1Geometry *)This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains)) + +#define ID2D1EllipseGeometry_FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.FillContainsPoint((ID2D1Geometry *)This, point, worldTransform, flatteningTolerance, contains)) + +#define ID2D1EllipseGeometry_CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation) \ + ((This)->lpVtbl->Base.CompareWithGeometry((ID2D1Geometry *)This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation)) + +#define ID2D1EllipseGeometry_Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Simplify((ID2D1Geometry *)This, simplificationOption, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1EllipseGeometry_Tessellate(This, worldTransform, flatteningTolerance, tessellationSink) \ + ((This)->lpVtbl->Base.Tessellate((ID2D1Geometry *)This, worldTransform, flatteningTolerance, tessellationSink)) + +#define ID2D1EllipseGeometry_CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.CombineWithGeometry((ID2D1Geometry *)This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink)) + +#define ID2D1EllipseGeometry_Outline(This, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Outline((ID2D1Geometry *)This, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1EllipseGeometry_ComputeArea(This, worldTransform, flatteningTolerance, area) \ + ((This)->lpVtbl->Base.ComputeArea((ID2D1Geometry *)This, worldTransform, flatteningTolerance, area)) + +#define ID2D1EllipseGeometry_ComputeLength(This, worldTransform, flatteningTolerance, length) \ + ((This)->lpVtbl->Base.ComputeLength((ID2D1Geometry *)This, worldTransform, flatteningTolerance, length)) + +#define ID2D1EllipseGeometry_ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector) \ + ((This)->lpVtbl->Base.ComputePointAtLength((ID2D1Geometry *)This, length, worldTransform, flatteningTolerance, point, unitTangentVector)) + +#define ID2D1EllipseGeometry_Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Widen((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1EllipseGeometry_GetEllipse(This, ellipse) \ + ((This)->lpVtbl->GetEllipse(This, ellipse)) + +typedef interface ID2D1GeometryGroup ID2D1GeometryGroup; + +typedef struct ID2D1GeometryGroupVtbl +{ + + ID2D1GeometryVtbl Base; + + + STDMETHOD_(D2D1_FILL_MODE, GetFillMode)( + ID2D1GeometryGroup *This + ) PURE; + + STDMETHOD_(UINT32, GetSourceGeometryCount)( + ID2D1GeometryGroup *This + ) PURE; + + STDMETHOD_(void, GetSourceGeometries)( + ID2D1GeometryGroup *This, + __out_ecount(geometriesCount) ID2D1Geometry **geometries, + UINT geometriesCount + ) PURE; +} ID2D1GeometryGroupVtbl; + +interface ID2D1GeometryGroup +{ + CONST struct ID2D1GeometryGroupVtbl *lpVtbl; +}; + + +#define ID2D1GeometryGroup_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1GeometryGroup_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1GeometryGroup_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1GeometryGroup_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1GeometryGroup_GetBounds(This, worldTransform, bounds) \ + ((This)->lpVtbl->Base.GetBounds((ID2D1Geometry *)This, worldTransform, bounds)) + +#define ID2D1GeometryGroup_GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds) \ + ((This)->lpVtbl->Base.GetWidenedBounds((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds)) + +#define ID2D1GeometryGroup_StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.StrokeContainsPoint((ID2D1Geometry *)This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains)) + +#define ID2D1GeometryGroup_FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.FillContainsPoint((ID2D1Geometry *)This, point, worldTransform, flatteningTolerance, contains)) + +#define ID2D1GeometryGroup_CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation) \ + ((This)->lpVtbl->Base.CompareWithGeometry((ID2D1Geometry *)This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation)) + +#define ID2D1GeometryGroup_Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Simplify((ID2D1Geometry *)This, simplificationOption, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1GeometryGroup_Tessellate(This, worldTransform, flatteningTolerance, tessellationSink) \ + ((This)->lpVtbl->Base.Tessellate((ID2D1Geometry *)This, worldTransform, flatteningTolerance, tessellationSink)) + +#define ID2D1GeometryGroup_CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.CombineWithGeometry((ID2D1Geometry *)This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink)) + +#define ID2D1GeometryGroup_Outline(This, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Outline((ID2D1Geometry *)This, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1GeometryGroup_ComputeArea(This, worldTransform, flatteningTolerance, area) \ + ((This)->lpVtbl->Base.ComputeArea((ID2D1Geometry *)This, worldTransform, flatteningTolerance, area)) + +#define ID2D1GeometryGroup_ComputeLength(This, worldTransform, flatteningTolerance, length) \ + ((This)->lpVtbl->Base.ComputeLength((ID2D1Geometry *)This, worldTransform, flatteningTolerance, length)) + +#define ID2D1GeometryGroup_ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector) \ + ((This)->lpVtbl->Base.ComputePointAtLength((ID2D1Geometry *)This, length, worldTransform, flatteningTolerance, point, unitTangentVector)) + +#define ID2D1GeometryGroup_Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Widen((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1GeometryGroup_GetFillMode(This) \ + ((This)->lpVtbl->GetFillMode(This)) + +#define ID2D1GeometryGroup_GetSourceGeometryCount(This) \ + ((This)->lpVtbl->GetSourceGeometryCount(This)) + +#define ID2D1GeometryGroup_GetSourceGeometries(This, geometries, geometriesCount) \ + ((This)->lpVtbl->GetSourceGeometries(This, geometries, geometriesCount)) + +typedef interface ID2D1TransformedGeometry ID2D1TransformedGeometry; + +typedef struct ID2D1TransformedGeometryVtbl +{ + + ID2D1GeometryVtbl Base; + + + STDMETHOD_(void, GetSourceGeometry)( + ID2D1TransformedGeometry *This, + __deref_out ID2D1Geometry **sourceGeometry + ) PURE; + + STDMETHOD_(void, GetTransform)( + ID2D1TransformedGeometry *This, + __out D2D1_MATRIX_3X2_F *transform + ) PURE; +} ID2D1TransformedGeometryVtbl; + +interface ID2D1TransformedGeometry +{ + CONST struct ID2D1TransformedGeometryVtbl *lpVtbl; +}; + + +#define ID2D1TransformedGeometry_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1TransformedGeometry_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1TransformedGeometry_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1TransformedGeometry_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1TransformedGeometry_GetBounds(This, worldTransform, bounds) \ + ((This)->lpVtbl->Base.GetBounds((ID2D1Geometry *)This, worldTransform, bounds)) + +#define ID2D1TransformedGeometry_GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds) \ + ((This)->lpVtbl->Base.GetWidenedBounds((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds)) + +#define ID2D1TransformedGeometry_StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.StrokeContainsPoint((ID2D1Geometry *)This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains)) + +#define ID2D1TransformedGeometry_FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.FillContainsPoint((ID2D1Geometry *)This, point, worldTransform, flatteningTolerance, contains)) + +#define ID2D1TransformedGeometry_CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation) \ + ((This)->lpVtbl->Base.CompareWithGeometry((ID2D1Geometry *)This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation)) + +#define ID2D1TransformedGeometry_Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Simplify((ID2D1Geometry *)This, simplificationOption, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1TransformedGeometry_Tessellate(This, worldTransform, flatteningTolerance, tessellationSink) \ + ((This)->lpVtbl->Base.Tessellate((ID2D1Geometry *)This, worldTransform, flatteningTolerance, tessellationSink)) + +#define ID2D1TransformedGeometry_CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.CombineWithGeometry((ID2D1Geometry *)This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink)) + +#define ID2D1TransformedGeometry_Outline(This, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Outline((ID2D1Geometry *)This, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1TransformedGeometry_ComputeArea(This, worldTransform, flatteningTolerance, area) \ + ((This)->lpVtbl->Base.ComputeArea((ID2D1Geometry *)This, worldTransform, flatteningTolerance, area)) + +#define ID2D1TransformedGeometry_ComputeLength(This, worldTransform, flatteningTolerance, length) \ + ((This)->lpVtbl->Base.ComputeLength((ID2D1Geometry *)This, worldTransform, flatteningTolerance, length)) + +#define ID2D1TransformedGeometry_ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector) \ + ((This)->lpVtbl->Base.ComputePointAtLength((ID2D1Geometry *)This, length, worldTransform, flatteningTolerance, point, unitTangentVector)) + +#define ID2D1TransformedGeometry_Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Widen((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1TransformedGeometry_GetSourceGeometry(This, sourceGeometry) \ + ((This)->lpVtbl->GetSourceGeometry(This, sourceGeometry)) + +#define ID2D1TransformedGeometry_GetTransform(This, transform) \ + ((This)->lpVtbl->GetTransform(This, transform)) + +typedef interface ID2D1SimplifiedGeometrySink ID2D1SimplifiedGeometrySink; + +typedef struct ID2D1SimplifiedGeometrySinkVtbl +{ + + IUnknownVtbl Base; + + + STDMETHOD_(void, SetFillMode)( + ID2D1SimplifiedGeometrySink *This, + D2D1_FILL_MODE fillMode + ) PURE; + + STDMETHOD_(void, SetSegmentFlags)( + ID2D1SimplifiedGeometrySink *This, + D2D1_PATH_SEGMENT vertexFlags + ) PURE; + + STDMETHOD_(void, BeginFigure)( + ID2D1SimplifiedGeometrySink *This, + D2D1_POINT_2F startPoint, + D2D1_FIGURE_BEGIN figureBegin + ) PURE; + + STDMETHOD_(void, AddLines)( + ID2D1SimplifiedGeometrySink *This, + __in_ecount(pointsCount) CONST D2D1_POINT_2F *points, + UINT pointsCount + ) PURE; + + STDMETHOD_(void, AddBeziers)( + ID2D1SimplifiedGeometrySink *This, + __in_ecount(beziersCount) CONST D2D1_BEZIER_SEGMENT *beziers, + UINT beziersCount + ) PURE; + + STDMETHOD_(void, EndFigure)( + ID2D1SimplifiedGeometrySink *This, + D2D1_FIGURE_END figureEnd + ) PURE; + + STDMETHOD(Close)( + ID2D1SimplifiedGeometrySink *This + ) PURE; +} ID2D1SimplifiedGeometrySinkVtbl; + +interface ID2D1SimplifiedGeometrySink +{ + CONST struct ID2D1SimplifiedGeometrySinkVtbl *lpVtbl; +}; + + +#define ID2D1SimplifiedGeometrySink_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1SimplifiedGeometrySink_AddRef(This) \ + ((This)->lpVtbl->Base.AddRef((IUnknown *)This)) + +#define ID2D1SimplifiedGeometrySink_Release(This) \ + ((This)->lpVtbl->Base.Release((IUnknown *)This)) + +#define ID2D1SimplifiedGeometrySink_SetFillMode(This, fillMode) \ + ((This)->lpVtbl->SetFillMode(This, fillMode)) + +#define ID2D1SimplifiedGeometrySink_SetSegmentFlags(This, vertexFlags) \ + ((This)->lpVtbl->SetSegmentFlags(This, vertexFlags)) + +#define ID2D1SimplifiedGeometrySink_BeginFigure(This, startPoint, figureBegin) \ + ((This)->lpVtbl->BeginFigure(This, startPoint, figureBegin)) + +#define ID2D1SimplifiedGeometrySink_AddLines(This, points, pointsCount) \ + ((This)->lpVtbl->AddLines(This, points, pointsCount)) + +#define ID2D1SimplifiedGeometrySink_AddBeziers(This, beziers, beziersCount) \ + ((This)->lpVtbl->AddBeziers(This, beziers, beziersCount)) + +#define ID2D1SimplifiedGeometrySink_EndFigure(This, figureEnd) \ + ((This)->lpVtbl->EndFigure(This, figureEnd)) + +#define ID2D1SimplifiedGeometrySink_Close(This) \ + ((This)->lpVtbl->Close(This)) + +typedef interface ID2D1GeometrySink ID2D1GeometrySink; + +typedef struct ID2D1GeometrySinkVtbl +{ + + ID2D1SimplifiedGeometrySinkVtbl Base; + + + STDMETHOD_(void, AddLine)( + ID2D1GeometrySink *This, + D2D1_POINT_2F point + ) PURE; + + STDMETHOD_(void, AddBezier)( + ID2D1GeometrySink *This, + __in CONST D2D1_BEZIER_SEGMENT *bezier + ) PURE; + + STDMETHOD_(void, AddQuadraticBezier)( + ID2D1GeometrySink *This, + __in CONST D2D1_QUADRATIC_BEZIER_SEGMENT *bezier + ) PURE; + + STDMETHOD_(void, AddQuadraticBeziers)( + ID2D1GeometrySink *This, + __in_ecount(beziersCount) CONST D2D1_QUADRATIC_BEZIER_SEGMENT *beziers, + UINT beziersCount + ) PURE; + + STDMETHOD_(void, AddArc)( + ID2D1GeometrySink *This, + __in CONST D2D1_ARC_SEGMENT *arc + ) PURE; +} ID2D1GeometrySinkVtbl; + +interface ID2D1GeometrySink +{ + CONST struct ID2D1GeometrySinkVtbl *lpVtbl; +}; + + +#define ID2D1GeometrySink_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1GeometrySink_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1GeometrySink_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1GeometrySink_SetFillMode(This, fillMode) \ + ((This)->lpVtbl->Base.SetFillMode((ID2D1SimplifiedGeometrySink *)This, fillMode)) + +#define ID2D1GeometrySink_SetSegmentFlags(This, vertexFlags) \ + ((This)->lpVtbl->Base.SetSegmentFlags((ID2D1SimplifiedGeometrySink *)This, vertexFlags)) + +#define ID2D1GeometrySink_BeginFigure(This, startPoint, figureBegin) \ + ((This)->lpVtbl->Base.BeginFigure((ID2D1SimplifiedGeometrySink *)This, startPoint, figureBegin)) + +#define ID2D1GeometrySink_AddLines(This, points, pointsCount) \ + ((This)->lpVtbl->Base.AddLines((ID2D1SimplifiedGeometrySink *)This, points, pointsCount)) + +#define ID2D1GeometrySink_AddBeziers(This, beziers, beziersCount) \ + ((This)->lpVtbl->Base.AddBeziers((ID2D1SimplifiedGeometrySink *)This, beziers, beziersCount)) + +#define ID2D1GeometrySink_EndFigure(This, figureEnd) \ + ((This)->lpVtbl->Base.EndFigure((ID2D1SimplifiedGeometrySink *)This, figureEnd)) + +#define ID2D1GeometrySink_Close(This) \ + ((This)->lpVtbl->Base.Close((ID2D1SimplifiedGeometrySink *)This)) + +#define ID2D1GeometrySink_AddLine(This, point) \ + ((This)->lpVtbl->AddLine(This, point)) + +#define ID2D1GeometrySink_AddBezier(This, bezier) \ + ((This)->lpVtbl->AddBezier(This, bezier)) + +#define ID2D1GeometrySink_AddQuadraticBezier(This, bezier) \ + ((This)->lpVtbl->AddQuadraticBezier(This, bezier)) + +#define ID2D1GeometrySink_AddQuadraticBeziers(This, beziers, beziersCount) \ + ((This)->lpVtbl->AddQuadraticBeziers(This, beziers, beziersCount)) + +#define ID2D1GeometrySink_AddArc(This, arc) \ + ((This)->lpVtbl->AddArc(This, arc)) + +typedef interface ID2D1TessellationSink ID2D1TessellationSink; + +typedef struct ID2D1TessellationSinkVtbl +{ + + IUnknownVtbl Base; + + + STDMETHOD_(void, AddTriangles)( + ID2D1TessellationSink *This, + __in_ecount(trianglesCount) CONST D2D1_TRIANGLE *triangles, + UINT trianglesCount + ) PURE; + + STDMETHOD(Close)( + ID2D1TessellationSink *This + ) PURE; +} ID2D1TessellationSinkVtbl; + +interface ID2D1TessellationSink +{ + CONST struct ID2D1TessellationSinkVtbl *lpVtbl; +}; + + +#define ID2D1TessellationSink_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1TessellationSink_AddRef(This) \ + ((This)->lpVtbl->Base.AddRef((IUnknown *)This)) + +#define ID2D1TessellationSink_Release(This) \ + ((This)->lpVtbl->Base.Release((IUnknown *)This)) + +#define ID2D1TessellationSink_AddTriangles(This, triangles, trianglesCount) \ + ((This)->lpVtbl->AddTriangles(This, triangles, trianglesCount)) + +#define ID2D1TessellationSink_Close(This) \ + ((This)->lpVtbl->Close(This)) + +typedef interface ID2D1PathGeometry ID2D1PathGeometry; + +typedef struct ID2D1PathGeometryVtbl +{ + + ID2D1GeometryVtbl Base; + + + STDMETHOD(Open)( + ID2D1PathGeometry *This, + __deref_out ID2D1GeometrySink **geometrySink + ) PURE; + + STDMETHOD(Stream)( + ID2D1PathGeometry *This, + __in ID2D1GeometrySink *geometrySink + ) PURE; + + STDMETHOD(GetSegmentCount)( + ID2D1PathGeometry *This, + __out UINT32 *count + ) PURE; + + STDMETHOD(GetFigureCount)( + ID2D1PathGeometry *This, + __out UINT32 *count + ) PURE; +} ID2D1PathGeometryVtbl; + +interface ID2D1PathGeometry +{ + CONST struct ID2D1PathGeometryVtbl *lpVtbl; +}; + + +#define ID2D1PathGeometry_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1PathGeometry_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1PathGeometry_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1PathGeometry_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1PathGeometry_GetBounds(This, worldTransform, bounds) \ + ((This)->lpVtbl->Base.GetBounds((ID2D1Geometry *)This, worldTransform, bounds)) + +#define ID2D1PathGeometry_GetWidenedBounds(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds) \ + ((This)->lpVtbl->Base.GetWidenedBounds((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, bounds)) + +#define ID2D1PathGeometry_StrokeContainsPoint(This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.StrokeContainsPoint((ID2D1Geometry *)This, point, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, contains)) + +#define ID2D1PathGeometry_FillContainsPoint(This, point, worldTransform, flatteningTolerance, contains) \ + ((This)->lpVtbl->Base.FillContainsPoint((ID2D1Geometry *)This, point, worldTransform, flatteningTolerance, contains)) + +#define ID2D1PathGeometry_CompareWithGeometry(This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation) \ + ((This)->lpVtbl->Base.CompareWithGeometry((ID2D1Geometry *)This, inputGeometry, inputGeometryTransform, flatteningTolerance, relation)) + +#define ID2D1PathGeometry_Simplify(This, simplificationOption, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Simplify((ID2D1Geometry *)This, simplificationOption, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1PathGeometry_Tessellate(This, worldTransform, flatteningTolerance, tessellationSink) \ + ((This)->lpVtbl->Base.Tessellate((ID2D1Geometry *)This, worldTransform, flatteningTolerance, tessellationSink)) + +#define ID2D1PathGeometry_CombineWithGeometry(This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.CombineWithGeometry((ID2D1Geometry *)This, inputGeometry, combineMode, inputGeometryTransform, flatteningTolerance, geometrySink)) + +#define ID2D1PathGeometry_Outline(This, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Outline((ID2D1Geometry *)This, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1PathGeometry_ComputeArea(This, worldTransform, flatteningTolerance, area) \ + ((This)->lpVtbl->Base.ComputeArea((ID2D1Geometry *)This, worldTransform, flatteningTolerance, area)) + +#define ID2D1PathGeometry_ComputeLength(This, worldTransform, flatteningTolerance, length) \ + ((This)->lpVtbl->Base.ComputeLength((ID2D1Geometry *)This, worldTransform, flatteningTolerance, length)) + +#define ID2D1PathGeometry_ComputePointAtLength(This, length, worldTransform, flatteningTolerance, point, unitTangentVector) \ + ((This)->lpVtbl->Base.ComputePointAtLength((ID2D1Geometry *)This, length, worldTransform, flatteningTolerance, point, unitTangentVector)) + +#define ID2D1PathGeometry_Widen(This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink) \ + ((This)->lpVtbl->Base.Widen((ID2D1Geometry *)This, strokeWidth, strokeStyle, worldTransform, flatteningTolerance, geometrySink)) + +#define ID2D1PathGeometry_Open(This, geometrySink) \ + ((This)->lpVtbl->Open(This, geometrySink)) + +#define ID2D1PathGeometry_Stream(This, geometrySink) \ + ((This)->lpVtbl->Stream(This, geometrySink)) + +#define ID2D1PathGeometry_GetSegmentCount(This, count) \ + ((This)->lpVtbl->GetSegmentCount(This, count)) + +#define ID2D1PathGeometry_GetFigureCount(This, count) \ + ((This)->lpVtbl->GetFigureCount(This, count)) + +typedef interface ID2D1Mesh ID2D1Mesh; + +typedef struct ID2D1MeshVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD(Open)( + ID2D1Mesh *This, + __deref_out ID2D1TessellationSink **tessellationSink + ) PURE; +} ID2D1MeshVtbl; + +interface ID2D1Mesh +{ + CONST struct ID2D1MeshVtbl *lpVtbl; +}; + + +#define ID2D1Mesh_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1Mesh_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1Mesh_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1Mesh_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1Mesh_Open(This, tessellationSink) \ + ((This)->lpVtbl->Open(This, tessellationSink)) + +typedef interface ID2D1Layer ID2D1Layer; + +typedef struct ID2D1LayerVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD_(D2D1_SIZE_F, GetSize)( + ID2D1Layer *This + ) PURE; +} ID2D1LayerVtbl; + +interface ID2D1Layer +{ + CONST struct ID2D1LayerVtbl *lpVtbl; +}; + + +#define ID2D1Layer_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1Layer_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1Layer_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1Layer_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1Layer_GetSize(This) \ + ((This)->lpVtbl->GetSize(This)) + +typedef interface ID2D1DrawingStateBlock ID2D1DrawingStateBlock; + +typedef struct ID2D1DrawingStateBlockVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD_(void, GetDescription)( + ID2D1DrawingStateBlock *This, + __out D2D1_DRAWING_STATE_DESCRIPTION *stateDescription + ) PURE; + + STDMETHOD_(void, SetDescription)( + ID2D1DrawingStateBlock *This, + __in CONST D2D1_DRAWING_STATE_DESCRIPTION *stateDescription + ) PURE; + + STDMETHOD_(void, SetTextRenderingParams)( + ID2D1DrawingStateBlock *This, + __in_opt IDWriteRenderingParams *textRenderingParams + ) PURE; + + STDMETHOD_(void, GetTextRenderingParams)( + ID2D1DrawingStateBlock *This, + __deref_out_opt IDWriteRenderingParams **textRenderingParams + ) PURE; +} ID2D1DrawingStateBlockVtbl; + +interface ID2D1DrawingStateBlock +{ + CONST struct ID2D1DrawingStateBlockVtbl *lpVtbl; +}; + + +#define ID2D1DrawingStateBlock_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1DrawingStateBlock_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1DrawingStateBlock_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1DrawingStateBlock_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1DrawingStateBlock_GetDescription(This, stateDescription) \ + ((This)->lpVtbl->GetDescription(This, stateDescription)) + +#define ID2D1DrawingStateBlock_SetDescription(This, stateDescription) \ + ((This)->lpVtbl->SetDescription(This, stateDescription)) + +#define ID2D1DrawingStateBlock_SetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->SetTextRenderingParams(This, textRenderingParams)) + +#define ID2D1DrawingStateBlock_GetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->GetTextRenderingParams(This, textRenderingParams)) + +typedef interface ID2D1RenderTarget ID2D1RenderTarget; + +typedef struct ID2D1RenderTargetVtbl +{ + + ID2D1ResourceVtbl Base; + + + STDMETHOD(CreateBitmap)( + ID2D1RenderTarget *This, + D2D1_SIZE_U size, + __in_opt CONST void *srcData, + UINT32 pitch, + __in CONST D2D1_BITMAP_PROPERTIES *bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) PURE; + + STDMETHOD(CreateBitmapFromWicBitmap)( + ID2D1RenderTarget *This, + __in IWICBitmapSource *wicBitmapSource, + __in_opt CONST D2D1_BITMAP_PROPERTIES *bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) PURE; + + STDMETHOD(CreateSharedBitmap)( + ID2D1RenderTarget *This, + __in REFIID riid, + __inout void *data, + __in_opt CONST D2D1_BITMAP_PROPERTIES *bitmapProperties, + __deref_out ID2D1Bitmap **bitmap + ) PURE; + + STDMETHOD(CreateBitmapBrush)( + ID2D1RenderTarget *This, + __in ID2D1Bitmap *bitmap, + __in_opt CONST D2D1_BITMAP_BRUSH_PROPERTIES *bitmapBrushProperties, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __deref_out ID2D1BitmapBrush **bitmapBrush + ) PURE; + + STDMETHOD(CreateSolidColorBrush)( + ID2D1RenderTarget *This, + __in CONST D2D1_COLOR_F *color, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __deref_out ID2D1SolidColorBrush **solidColorBrush + ) PURE; + + STDMETHOD(CreateGradientStopCollection)( + ID2D1RenderTarget *This, + __in_ecount(gradientStopsCount) CONST D2D1_GRADIENT_STOP *gradientStops, + __range(>=,1) UINT gradientStopsCount, + D2D1_GAMMA colorInterpolationGamma, + D2D1_EXTEND_MODE extendMode, + __deref_out ID2D1GradientStopCollection **gradientStopCollection + ) PURE; + + STDMETHOD(CreateLinearGradientBrush)( + ID2D1RenderTarget *This, + __in CONST D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *linearGradientBrushProperties, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1LinearGradientBrush **linearGradientBrush + ) PURE; + + STDMETHOD(CreateRadialGradientBrush)( + ID2D1RenderTarget *This, + __in CONST D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *radialGradientBrushProperties, + __in_opt CONST D2D1_BRUSH_PROPERTIES *brushProperties, + __in ID2D1GradientStopCollection *gradientStopCollection, + __deref_out ID2D1RadialGradientBrush **radialGradientBrush + ) PURE; + + STDMETHOD(CreateCompatibleRenderTarget)( + ID2D1RenderTarget *This, + __in_opt CONST D2D1_SIZE_F *desiredSize, + __in_opt CONST D2D1_SIZE_U *desiredPixelSize, + __in_opt CONST D2D1_PIXEL_FORMAT *desiredFormat, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, + __deref_out ID2D1BitmapRenderTarget **bitmapRenderTarget + ) PURE; + + STDMETHOD(CreateLayer)( + ID2D1RenderTarget *This, + __in_opt CONST D2D1_SIZE_F *size, + __deref_out ID2D1Layer **layer + ) PURE; + + STDMETHOD(CreateMesh)( + ID2D1RenderTarget *This, + __deref_out ID2D1Mesh **mesh + ) PURE; + + STDMETHOD_(void, DrawLine)( + ID2D1RenderTarget *This, + D2D1_POINT_2F point0, + D2D1_POINT_2F point1, + __in ID2D1Brush *brush, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle + ) PURE; + + STDMETHOD_(void, DrawRectangle)( + ID2D1RenderTarget *This, + __in CONST D2D1_RECT_F *rect, + __in ID2D1Brush *brush, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle + ) PURE; + + STDMETHOD_(void, FillRectangle)( + ID2D1RenderTarget *This, + __in CONST D2D1_RECT_F *rect, + __in ID2D1Brush *brush + ) PURE; + + STDMETHOD_(void, DrawRoundedRectangle)( + ID2D1RenderTarget *This, + __in CONST D2D1_ROUNDED_RECT *roundedRect, + __in ID2D1Brush *brush, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle + ) PURE; + + STDMETHOD_(void, FillRoundedRectangle)( + ID2D1RenderTarget *This, + __in CONST D2D1_ROUNDED_RECT *roundedRect, + __in ID2D1Brush *brush + ) PURE; + + STDMETHOD_(void, DrawEllipse)( + ID2D1RenderTarget *This, + __in CONST D2D1_ELLIPSE *ellipse, + __in ID2D1Brush *brush, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle + ) PURE; + + STDMETHOD_(void, FillEllipse)( + ID2D1RenderTarget *This, + __in CONST D2D1_ELLIPSE *ellipse, + __in ID2D1Brush *brush + ) PURE; + + STDMETHOD_(void, DrawGeometry)( + ID2D1RenderTarget *This, + __in ID2D1Geometry *geometry, + __in ID2D1Brush *brush, + FLOAT strokeWidth, + __in_opt ID2D1StrokeStyle *strokeStyle + ) PURE; + + STDMETHOD_(void, FillGeometry)( + ID2D1RenderTarget *This, + __in ID2D1Geometry *geometry, + __in ID2D1Brush *brush, + __in_opt ID2D1Brush *opacityBrush + ) PURE; + + STDMETHOD_(void, FillMesh)( + ID2D1RenderTarget *This, + __in ID2D1Mesh *mesh, + __in ID2D1Brush *brush + ) PURE; + + STDMETHOD_(void, FillOpacityMask)( + ID2D1RenderTarget *This, + __in ID2D1Bitmap *opacityMask, + __in ID2D1Brush *brush, + D2D1_OPACITY_MASK_CONTENT content, + __in_opt CONST D2D1_RECT_F *destinationRectangle, + __in_opt CONST D2D1_RECT_F *sourceRectangle + ) PURE; + + STDMETHOD_(void, DrawBitmap)( + ID2D1RenderTarget *This, + __in ID2D1Bitmap *bitmap, + __in_opt CONST D2D1_RECT_F *destinationRectangle, + FLOAT opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode, + __in_opt CONST D2D1_RECT_F *sourceRectangle + ) PURE; + + STDMETHOD_(void, DrawText)( + ID2D1RenderTarget *This, + __in_ecount(stringLength) CONST WCHAR *string, + UINT stringLength, + __in IDWriteTextFormat *textFormat, + __in CONST D2D1_RECT_F *layoutRect, + __in ID2D1Brush *defaultForegroundBrush, + D2D1_DRAW_TEXT_OPTIONS options, + DWRITE_MEASURING_MODE measuringMode + ) PURE; + + STDMETHOD_(void, DrawTextLayout)( + ID2D1RenderTarget *This, + D2D1_POINT_2F origin, + __in IDWriteTextLayout *textLayout, + __in ID2D1Brush *defaultForegroundBrush, + D2D1_DRAW_TEXT_OPTIONS options + ) PURE; + + STDMETHOD_(void, DrawGlyphRun)( + ID2D1RenderTarget *This, + D2D1_POINT_2F baselineOrigin, + __in CONST DWRITE_GLYPH_RUN *glyphRun, + __in ID2D1Brush *foregroundBrush, + DWRITE_MEASURING_MODE measuringMode + ) PURE; + + STDMETHOD_(void, SetTransform)( + ID2D1RenderTarget *This, + __in CONST D2D1_MATRIX_3X2_F *transform + ) PURE; + + STDMETHOD_(void, GetTransform)( + ID2D1RenderTarget *This, + __out D2D1_MATRIX_3X2_F *transform + ) PURE; + + STDMETHOD_(void, SetAntialiasMode)( + ID2D1RenderTarget *This, + D2D1_ANTIALIAS_MODE antialiasMode + ) PURE; + + STDMETHOD_(D2D1_ANTIALIAS_MODE, GetAntialiasMode)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD_(void, SetTextAntialiasMode)( + ID2D1RenderTarget *This, + D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode + ) PURE; + + STDMETHOD_(D2D1_TEXT_ANTIALIAS_MODE, GetTextAntialiasMode)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD_(void, SetTextRenderingParams)( + ID2D1RenderTarget *This, + __in_opt IDWriteRenderingParams *textRenderingParams + ) PURE; + + STDMETHOD_(void, GetTextRenderingParams)( + ID2D1RenderTarget *This, + __deref_out_opt IDWriteRenderingParams **textRenderingParams + ) PURE; + + STDMETHOD_(void, SetTags)( + ID2D1RenderTarget *This, + D2D1_TAG tag1, + D2D1_TAG tag2 + ) PURE; + + STDMETHOD_(void, GetTags)( + ID2D1RenderTarget *This, + __out_opt D2D1_TAG *tag1, + __out_opt D2D1_TAG *tag2 + ) PURE; + + STDMETHOD_(void, PushLayer)( + ID2D1RenderTarget *This, + __in CONST D2D1_LAYER_PARAMETERS *layerParameters, + __in ID2D1Layer *layer + ) PURE; + + STDMETHOD_(void, PopLayer)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD(Flush)( + ID2D1RenderTarget *This, + __out_opt D2D1_TAG *tag1, + __out_opt D2D1_TAG *tag2 + ) PURE; + + STDMETHOD_(void, SaveDrawingState)( + ID2D1RenderTarget *This, + __inout ID2D1DrawingStateBlock *drawingStateBlock + ) PURE; + + STDMETHOD_(void, RestoreDrawingState)( + ID2D1RenderTarget *This, + __in ID2D1DrawingStateBlock *drawingStateBlock + ) PURE; + + STDMETHOD_(void, PushAxisAlignedClip)( + ID2D1RenderTarget *This, + __in CONST D2D1_RECT_F *clipRect, + D2D1_ANTIALIAS_MODE antialiasMode + ) PURE; + + STDMETHOD_(void, PopAxisAlignedClip)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD_(void, Clear)( + ID2D1RenderTarget *This, + __in_opt CONST D2D1_COLOR_F *clearColor + ) PURE; + + STDMETHOD_(void, BeginDraw)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD(EndDraw)( + ID2D1RenderTarget *This, + __out_opt D2D1_TAG *tag1, + __out_opt D2D1_TAG *tag2 + ) PURE; + + STDMETHOD_(D2D1_PIXEL_FORMAT, GetPixelFormat)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD_(void, SetDpi)( + ID2D1RenderTarget *This, + FLOAT dpiX, + FLOAT dpiY + ) PURE; + + STDMETHOD_(void, GetDpi)( + ID2D1RenderTarget *This, + __out FLOAT *dpiX, + __out FLOAT *dpiY + ) PURE; + + STDMETHOD_(D2D1_SIZE_F, GetSize)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD_(D2D1_SIZE_U, GetPixelSize)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD_(UINT32, GetMaximumBitmapSize)( + ID2D1RenderTarget *This + ) PURE; + + STDMETHOD_(BOOL, IsSupported)( + ID2D1RenderTarget *This, + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties + ) PURE; +} ID2D1RenderTargetVtbl; + +interface ID2D1RenderTarget +{ + CONST struct ID2D1RenderTargetVtbl *lpVtbl; +}; + + +#define ID2D1RenderTarget_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1RenderTarget_AddRef(This) \ + ((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1RenderTarget_Release(This) \ + ((This)->lpVtbl->Base.Base.Release((IUnknown *)This)) + +#define ID2D1RenderTarget_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1RenderTarget_CreateBitmap(This, size, srcData, pitch, bitmapProperties, bitmap) \ + ((This)->lpVtbl->CreateBitmap(This, size, srcData, pitch, bitmapProperties, bitmap)) + +#define ID2D1RenderTarget_CreateBitmapFromWicBitmap(This, wicBitmapSource, bitmapProperties, bitmap) \ + ((This)->lpVtbl->CreateBitmapFromWicBitmap(This, wicBitmapSource, bitmapProperties, bitmap)) + +#define ID2D1RenderTarget_CreateSharedBitmap(This, riid, data, bitmapProperties, bitmap) \ + ((This)->lpVtbl->CreateSharedBitmap(This, riid, data, bitmapProperties, bitmap)) + +#define ID2D1RenderTarget_CreateBitmapBrush(This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush) \ + ((This)->lpVtbl->CreateBitmapBrush(This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush)) + +#define ID2D1RenderTarget_CreateSolidColorBrush(This, color, brushProperties, solidColorBrush) \ + ((This)->lpVtbl->CreateSolidColorBrush(This, color, brushProperties, solidColorBrush)) + +#define ID2D1RenderTarget_CreateGradientStopCollection(This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection) \ + ((This)->lpVtbl->CreateGradientStopCollection(This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection)) + +#define ID2D1RenderTarget_CreateLinearGradientBrush(This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush) \ + ((This)->lpVtbl->CreateLinearGradientBrush(This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush)) + +#define ID2D1RenderTarget_CreateRadialGradientBrush(This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush) \ + ((This)->lpVtbl->CreateRadialGradientBrush(This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush)) + +#define ID2D1RenderTarget_CreateCompatibleRenderTarget(This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget) \ + ((This)->lpVtbl->CreateCompatibleRenderTarget(This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget)) + +#define ID2D1RenderTarget_CreateLayer(This, size, layer) \ + ((This)->lpVtbl->CreateLayer(This, size, layer)) + +#define ID2D1RenderTarget_CreateMesh(This, mesh) \ + ((This)->lpVtbl->CreateMesh(This, mesh)) + +#define ID2D1RenderTarget_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle)) + +#define ID2D1RenderTarget_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->DrawRectangle(This, rect, brush, strokeWidth, strokeStyle)) + +#define ID2D1RenderTarget_FillRectangle(This, rect, brush) \ + ((This)->lpVtbl->FillRectangle(This, rect, brush)) + +#define ID2D1RenderTarget_DrawRoundedRectangle(This, roundedRect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->DrawRoundedRectangle(This, roundedRect, brush, strokeWidth, strokeStyle)) + +#define ID2D1RenderTarget_FillRoundedRectangle(This, roundedRect, brush) \ + ((This)->lpVtbl->FillRoundedRectangle(This, roundedRect, brush)) + +#define ID2D1RenderTarget_DrawEllipse(This, ellipse, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->DrawEllipse(This, ellipse, brush, strokeWidth, strokeStyle)) + +#define ID2D1RenderTarget_FillEllipse(This, ellipse, brush) \ + ((This)->lpVtbl->FillEllipse(This, ellipse, brush)) + +#define ID2D1RenderTarget_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle)) + +#define ID2D1RenderTarget_FillGeometry(This, geometry, brush, opacityBrush) \ + ((This)->lpVtbl->FillGeometry(This, geometry, brush, opacityBrush)) + +#define ID2D1RenderTarget_FillMesh(This, mesh, brush) \ + ((This)->lpVtbl->FillMesh(This, mesh, brush)) + +#define ID2D1RenderTarget_FillOpacityMask(This, opacityMask, brush, content, destinationRectangle, sourceRectangle) \ + ((This)->lpVtbl->FillOpacityMask(This, opacityMask, brush, content, destinationRectangle, sourceRectangle)) + +#define ID2D1RenderTarget_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle) \ + ((This)->lpVtbl->DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle)) + +#define ID2D1RenderTarget_DrawText(This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode) \ + ((This)->lpVtbl->DrawText(This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode)) + +#define ID2D1RenderTarget_DrawTextLayout(This, origin, textLayout, defaultForegroundBrush, options) \ + ((This)->lpVtbl->DrawTextLayout(This, origin, textLayout, defaultForegroundBrush, options)) + +#define ID2D1RenderTarget_DrawGlyphRun(This, baselineOrigin, glyphRun, foregroundBrush, measuringMode) \ + ((This)->lpVtbl->DrawGlyphRun(This, baselineOrigin, glyphRun, foregroundBrush, measuringMode)) + +#define ID2D1RenderTarget_SetTransform(This, transform) \ + ((This)->lpVtbl->SetTransform(This, transform)) + +#define ID2D1RenderTarget_GetTransform(This, transform) \ + ((This)->lpVtbl->GetTransform(This, transform)) + +#define ID2D1RenderTarget_SetAntialiasMode(This, antialiasMode) \ + ((This)->lpVtbl->SetAntialiasMode(This, antialiasMode)) + +#define ID2D1RenderTarget_GetAntialiasMode(This) \ + ((This)->lpVtbl->GetAntialiasMode(This)) + +#define ID2D1RenderTarget_SetTextAntialiasMode(This, textAntialiasMode) \ + ((This)->lpVtbl->SetTextAntialiasMode(This, textAntialiasMode)) + +#define ID2D1RenderTarget_GetTextAntialiasMode(This) \ + ((This)->lpVtbl->GetTextAntialiasMode(This)) + +#define ID2D1RenderTarget_SetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->SetTextRenderingParams(This, textRenderingParams)) + +#define ID2D1RenderTarget_GetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->GetTextRenderingParams(This, textRenderingParams)) + +#define ID2D1RenderTarget_SetTags(This, tag1, tag2) \ + ((This)->lpVtbl->SetTags(This, tag1, tag2)) + +#define ID2D1RenderTarget_GetTags(This, tag1, tag2) \ + ((This)->lpVtbl->GetTags(This, tag1, tag2)) + +#define ID2D1RenderTarget_PushLayer(This, layerParameters, layer) \ + ((This)->lpVtbl->PushLayer(This, layerParameters, layer)) + +#define ID2D1RenderTarget_PopLayer(This) \ + ((This)->lpVtbl->PopLayer(This)) + +#define ID2D1RenderTarget_Flush(This, tag1, tag2) \ + ((This)->lpVtbl->Flush(This, tag1, tag2)) + +#define ID2D1RenderTarget_SaveDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->SaveDrawingState(This, drawingStateBlock)) + +#define ID2D1RenderTarget_RestoreDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->RestoreDrawingState(This, drawingStateBlock)) + +#define ID2D1RenderTarget_PushAxisAlignedClip(This, clipRect, antialiasMode) \ + ((This)->lpVtbl->PushAxisAlignedClip(This, clipRect, antialiasMode)) + +#define ID2D1RenderTarget_PopAxisAlignedClip(This) \ + ((This)->lpVtbl->PopAxisAlignedClip(This)) + +#define ID2D1RenderTarget_Clear(This, clearColor) \ + ((This)->lpVtbl->Clear(This, clearColor)) + +#define ID2D1RenderTarget_BeginDraw(This) \ + ((This)->lpVtbl->BeginDraw(This)) + +#define ID2D1RenderTarget_EndDraw(This, tag1, tag2) \ + ((This)->lpVtbl->EndDraw(This, tag1, tag2)) + +#define ID2D1RenderTarget_GetPixelFormat(This) \ + ((This)->lpVtbl->GetPixelFormat(This)) + +#define ID2D1RenderTarget_SetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->SetDpi(This, dpiX, dpiY)) + +#define ID2D1RenderTarget_GetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->GetDpi(This, dpiX, dpiY)) + +#define ID2D1RenderTarget_GetSize(This) \ + ((This)->lpVtbl->GetSize(This)) + +#define ID2D1RenderTarget_GetPixelSize(This) \ + ((This)->lpVtbl->GetPixelSize(This)) + +#define ID2D1RenderTarget_GetMaximumBitmapSize(This) \ + ((This)->lpVtbl->GetMaximumBitmapSize(This)) + +#define ID2D1RenderTarget_IsSupported(This, renderTargetProperties) \ + ((This)->lpVtbl->IsSupported(This, renderTargetProperties)) + +typedef interface ID2D1BitmapRenderTarget ID2D1BitmapRenderTarget; + +typedef struct ID2D1BitmapRenderTargetVtbl +{ + + ID2D1RenderTargetVtbl Base; + + + STDMETHOD(GetBitmap)( + ID2D1BitmapRenderTarget *This, + __deref_out ID2D1Bitmap **bitmap + ) PURE; +} ID2D1BitmapRenderTargetVtbl; + +interface ID2D1BitmapRenderTarget +{ + CONST struct ID2D1BitmapRenderTargetVtbl *lpVtbl; +}; + + +#define ID2D1BitmapRenderTarget_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1BitmapRenderTarget_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1BitmapRenderTarget_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1BitmapRenderTarget_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1BitmapRenderTarget_CreateBitmap(This, size, srcData, pitch, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateBitmap((ID2D1RenderTarget *)This, size, srcData, pitch, bitmapProperties, bitmap)) + +#define ID2D1BitmapRenderTarget_CreateBitmapFromWicBitmap(This, wicBitmapSource, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateBitmapFromWicBitmap((ID2D1RenderTarget *)This, wicBitmapSource, bitmapProperties, bitmap)) + +#define ID2D1BitmapRenderTarget_CreateSharedBitmap(This, riid, data, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateSharedBitmap((ID2D1RenderTarget *)This, riid, data, bitmapProperties, bitmap)) + +#define ID2D1BitmapRenderTarget_CreateBitmapBrush(This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush) \ + ((This)->lpVtbl->Base.CreateBitmapBrush((ID2D1RenderTarget *)This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush)) + +#define ID2D1BitmapRenderTarget_CreateSolidColorBrush(This, color, brushProperties, solidColorBrush) \ + ((This)->lpVtbl->Base.CreateSolidColorBrush((ID2D1RenderTarget *)This, color, brushProperties, solidColorBrush)) + +#define ID2D1BitmapRenderTarget_CreateGradientStopCollection(This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection) \ + ((This)->lpVtbl->Base.CreateGradientStopCollection((ID2D1RenderTarget *)This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection)) + +#define ID2D1BitmapRenderTarget_CreateLinearGradientBrush(This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush) \ + ((This)->lpVtbl->Base.CreateLinearGradientBrush((ID2D1RenderTarget *)This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush)) + +#define ID2D1BitmapRenderTarget_CreateRadialGradientBrush(This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush) \ + ((This)->lpVtbl->Base.CreateRadialGradientBrush((ID2D1RenderTarget *)This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush)) + +#define ID2D1BitmapRenderTarget_CreateCompatibleRenderTarget(This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget) \ + ((This)->lpVtbl->Base.CreateCompatibleRenderTarget((ID2D1RenderTarget *)This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget)) + +#define ID2D1BitmapRenderTarget_CreateLayer(This, size, layer) \ + ((This)->lpVtbl->Base.CreateLayer((ID2D1RenderTarget *)This, size, layer)) + +#define ID2D1BitmapRenderTarget_CreateMesh(This, mesh) \ + ((This)->lpVtbl->Base.CreateMesh((ID2D1RenderTarget *)This, mesh)) + +#define ID2D1BitmapRenderTarget_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawLine((ID2D1RenderTarget *)This, point0, point1, brush, strokeWidth, strokeStyle)) + +#define ID2D1BitmapRenderTarget_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawRectangle((ID2D1RenderTarget *)This, rect, brush, strokeWidth, strokeStyle)) + +#define ID2D1BitmapRenderTarget_FillRectangle(This, rect, brush) \ + ((This)->lpVtbl->Base.FillRectangle((ID2D1RenderTarget *)This, rect, brush)) + +#define ID2D1BitmapRenderTarget_DrawRoundedRectangle(This, roundedRect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush, strokeWidth, strokeStyle)) + +#define ID2D1BitmapRenderTarget_FillRoundedRectangle(This, roundedRect, brush) \ + ((This)->lpVtbl->Base.FillRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush)) + +#define ID2D1BitmapRenderTarget_DrawEllipse(This, ellipse, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawEllipse((ID2D1RenderTarget *)This, ellipse, brush, strokeWidth, strokeStyle)) + +#define ID2D1BitmapRenderTarget_FillEllipse(This, ellipse, brush) \ + ((This)->lpVtbl->Base.FillEllipse((ID2D1RenderTarget *)This, ellipse, brush)) + +#define ID2D1BitmapRenderTarget_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawGeometry((ID2D1RenderTarget *)This, geometry, brush, strokeWidth, strokeStyle)) + +#define ID2D1BitmapRenderTarget_FillGeometry(This, geometry, brush, opacityBrush) \ + ((This)->lpVtbl->Base.FillGeometry((ID2D1RenderTarget *)This, geometry, brush, opacityBrush)) + +#define ID2D1BitmapRenderTarget_FillMesh(This, mesh, brush) \ + ((This)->lpVtbl->Base.FillMesh((ID2D1RenderTarget *)This, mesh, brush)) + +#define ID2D1BitmapRenderTarget_FillOpacityMask(This, opacityMask, brush, content, destinationRectangle, sourceRectangle) \ + ((This)->lpVtbl->Base.FillOpacityMask((ID2D1RenderTarget *)This, opacityMask, brush, content, destinationRectangle, sourceRectangle)) + +#define ID2D1BitmapRenderTarget_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle) \ + ((This)->lpVtbl->Base.DrawBitmap((ID2D1RenderTarget *)This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle)) + +#define ID2D1BitmapRenderTarget_DrawText(This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode) \ + ((This)->lpVtbl->Base.DrawText((ID2D1RenderTarget *)This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode)) + +#define ID2D1BitmapRenderTarget_DrawTextLayout(This, origin, textLayout, defaultForegroundBrush, options) \ + ((This)->lpVtbl->Base.DrawTextLayout((ID2D1RenderTarget *)This, origin, textLayout, defaultForegroundBrush, options)) + +#define ID2D1BitmapRenderTarget_DrawGlyphRun(This, baselineOrigin, glyphRun, foregroundBrush, measuringMode) \ + ((This)->lpVtbl->Base.DrawGlyphRun((ID2D1RenderTarget *)This, baselineOrigin, glyphRun, foregroundBrush, measuringMode)) + +#define ID2D1BitmapRenderTarget_SetTransform(This, transform) \ + ((This)->lpVtbl->Base.SetTransform((ID2D1RenderTarget *)This, transform)) + +#define ID2D1BitmapRenderTarget_GetTransform(This, transform) \ + ((This)->lpVtbl->Base.GetTransform((ID2D1RenderTarget *)This, transform)) + +#define ID2D1BitmapRenderTarget_SetAntialiasMode(This, antialiasMode) \ + ((This)->lpVtbl->Base.SetAntialiasMode((ID2D1RenderTarget *)This, antialiasMode)) + +#define ID2D1BitmapRenderTarget_GetAntialiasMode(This) \ + ((This)->lpVtbl->Base.GetAntialiasMode((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_SetTextAntialiasMode(This, textAntialiasMode) \ + ((This)->lpVtbl->Base.SetTextAntialiasMode((ID2D1RenderTarget *)This, textAntialiasMode)) + +#define ID2D1BitmapRenderTarget_GetTextAntialiasMode(This) \ + ((This)->lpVtbl->Base.GetTextAntialiasMode((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_SetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->Base.SetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams)) + +#define ID2D1BitmapRenderTarget_GetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->Base.GetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams)) + +#define ID2D1BitmapRenderTarget_SetTags(This, tag1, tag2) \ + ((This)->lpVtbl->Base.SetTags((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1BitmapRenderTarget_GetTags(This, tag1, tag2) \ + ((This)->lpVtbl->Base.GetTags((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1BitmapRenderTarget_PushLayer(This, layerParameters, layer) \ + ((This)->lpVtbl->Base.PushLayer((ID2D1RenderTarget *)This, layerParameters, layer)) + +#define ID2D1BitmapRenderTarget_PopLayer(This) \ + ((This)->lpVtbl->Base.PopLayer((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_Flush(This, tag1, tag2) \ + ((This)->lpVtbl->Base.Flush((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1BitmapRenderTarget_SaveDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->Base.SaveDrawingState((ID2D1RenderTarget *)This, drawingStateBlock)) + +#define ID2D1BitmapRenderTarget_RestoreDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->Base.RestoreDrawingState((ID2D1RenderTarget *)This, drawingStateBlock)) + +#define ID2D1BitmapRenderTarget_PushAxisAlignedClip(This, clipRect, antialiasMode) \ + ((This)->lpVtbl->Base.PushAxisAlignedClip((ID2D1RenderTarget *)This, clipRect, antialiasMode)) + +#define ID2D1BitmapRenderTarget_PopAxisAlignedClip(This) \ + ((This)->lpVtbl->Base.PopAxisAlignedClip((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_Clear(This, clearColor) \ + ((This)->lpVtbl->Base.Clear((ID2D1RenderTarget *)This, clearColor)) + +#define ID2D1BitmapRenderTarget_BeginDraw(This) \ + ((This)->lpVtbl->Base.BeginDraw((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_EndDraw(This, tag1, tag2) \ + ((This)->lpVtbl->Base.EndDraw((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1BitmapRenderTarget_GetPixelFormat(This) \ + ((This)->lpVtbl->Base.GetPixelFormat((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_SetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->Base.SetDpi((ID2D1RenderTarget *)This, dpiX, dpiY)) + +#define ID2D1BitmapRenderTarget_GetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->Base.GetDpi((ID2D1RenderTarget *)This, dpiX, dpiY)) + +#define ID2D1BitmapRenderTarget_GetSize(This) \ + ((This)->lpVtbl->Base.GetSize((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_GetPixelSize(This) \ + ((This)->lpVtbl->Base.GetPixelSize((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_GetMaximumBitmapSize(This) \ + ((This)->lpVtbl->Base.GetMaximumBitmapSize((ID2D1RenderTarget *)This)) + +#define ID2D1BitmapRenderTarget_IsSupported(This, renderTargetProperties) \ + ((This)->lpVtbl->Base.IsSupported((ID2D1RenderTarget *)This, renderTargetProperties)) + +#define ID2D1BitmapRenderTarget_GetBitmap(This, bitmap) \ + ((This)->lpVtbl->GetBitmap(This, bitmap)) + +typedef interface ID2D1HwndRenderTarget ID2D1HwndRenderTarget; + +typedef struct ID2D1HwndRenderTargetVtbl +{ + + ID2D1RenderTargetVtbl Base; + + + STDMETHOD_(D2D1_WINDOW_STATE, CheckWindowState)( + ID2D1HwndRenderTarget *This + ) PURE; + + STDMETHOD(Resize)( + ID2D1HwndRenderTarget *This, + __in CONST D2D1_SIZE_U *pixelSize + ) PURE; + + STDMETHOD_(HWND, GetHwnd)( + ID2D1HwndRenderTarget *This + ) PURE; +} ID2D1HwndRenderTargetVtbl; + +interface ID2D1HwndRenderTarget +{ + CONST struct ID2D1HwndRenderTargetVtbl *lpVtbl; +}; + + +#define ID2D1HwndRenderTarget_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1HwndRenderTarget_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1HwndRenderTarget_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1HwndRenderTarget_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1HwndRenderTarget_CreateBitmap(This, size, srcData, pitch, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateBitmap((ID2D1RenderTarget *)This, size, srcData, pitch, bitmapProperties, bitmap)) + +#define ID2D1HwndRenderTarget_CreateBitmapFromWicBitmap(This, wicBitmapSource, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateBitmapFromWicBitmap((ID2D1RenderTarget *)This, wicBitmapSource, bitmapProperties, bitmap)) + +#define ID2D1HwndRenderTarget_CreateSharedBitmap(This, riid, data, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateSharedBitmap((ID2D1RenderTarget *)This, riid, data, bitmapProperties, bitmap)) + +#define ID2D1HwndRenderTarget_CreateBitmapBrush(This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush) \ + ((This)->lpVtbl->Base.CreateBitmapBrush((ID2D1RenderTarget *)This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush)) + +#define ID2D1HwndRenderTarget_CreateSolidColorBrush(This, color, brushProperties, solidColorBrush) \ + ((This)->lpVtbl->Base.CreateSolidColorBrush((ID2D1RenderTarget *)This, color, brushProperties, solidColorBrush)) + +#define ID2D1HwndRenderTarget_CreateGradientStopCollection(This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection) \ + ((This)->lpVtbl->Base.CreateGradientStopCollection((ID2D1RenderTarget *)This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection)) + +#define ID2D1HwndRenderTarget_CreateLinearGradientBrush(This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush) \ + ((This)->lpVtbl->Base.CreateLinearGradientBrush((ID2D1RenderTarget *)This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush)) + +#define ID2D1HwndRenderTarget_CreateRadialGradientBrush(This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush) \ + ((This)->lpVtbl->Base.CreateRadialGradientBrush((ID2D1RenderTarget *)This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush)) + +#define ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget) \ + ((This)->lpVtbl->Base.CreateCompatibleRenderTarget((ID2D1RenderTarget *)This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget)) + +#define ID2D1HwndRenderTarget_CreateLayer(This, size, layer) \ + ((This)->lpVtbl->Base.CreateLayer((ID2D1RenderTarget *)This, size, layer)) + +#define ID2D1HwndRenderTarget_CreateMesh(This, mesh) \ + ((This)->lpVtbl->Base.CreateMesh((ID2D1RenderTarget *)This, mesh)) + +#define ID2D1HwndRenderTarget_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawLine((ID2D1RenderTarget *)This, point0, point1, brush, strokeWidth, strokeStyle)) + +#define ID2D1HwndRenderTarget_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawRectangle((ID2D1RenderTarget *)This, rect, brush, strokeWidth, strokeStyle)) + +#define ID2D1HwndRenderTarget_FillRectangle(This, rect, brush) \ + ((This)->lpVtbl->Base.FillRectangle((ID2D1RenderTarget *)This, rect, brush)) + +#define ID2D1HwndRenderTarget_DrawRoundedRectangle(This, roundedRect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush, strokeWidth, strokeStyle)) + +#define ID2D1HwndRenderTarget_FillRoundedRectangle(This, roundedRect, brush) \ + ((This)->lpVtbl->Base.FillRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush)) + +#define ID2D1HwndRenderTarget_DrawEllipse(This, ellipse, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawEllipse((ID2D1RenderTarget *)This, ellipse, brush, strokeWidth, strokeStyle)) + +#define ID2D1HwndRenderTarget_FillEllipse(This, ellipse, brush) \ + ((This)->lpVtbl->Base.FillEllipse((ID2D1RenderTarget *)This, ellipse, brush)) + +#define ID2D1HwndRenderTarget_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawGeometry((ID2D1RenderTarget *)This, geometry, brush, strokeWidth, strokeStyle)) + +#define ID2D1HwndRenderTarget_FillGeometry(This, geometry, brush, opacityBrush) \ + ((This)->lpVtbl->Base.FillGeometry((ID2D1RenderTarget *)This, geometry, brush, opacityBrush)) + +#define ID2D1HwndRenderTarget_FillMesh(This, mesh, brush) \ + ((This)->lpVtbl->Base.FillMesh((ID2D1RenderTarget *)This, mesh, brush)) + +#define ID2D1HwndRenderTarget_FillOpacityMask(This, opacityMask, brush, content, destinationRectangle, sourceRectangle) \ + ((This)->lpVtbl->Base.FillOpacityMask((ID2D1RenderTarget *)This, opacityMask, brush, content, destinationRectangle, sourceRectangle)) + +#define ID2D1HwndRenderTarget_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle) \ + ((This)->lpVtbl->Base.DrawBitmap((ID2D1RenderTarget *)This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle)) + +#define ID2D1HwndRenderTarget_DrawText(This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode) \ + ((This)->lpVtbl->Base.DrawText((ID2D1RenderTarget *)This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode)) + +#define ID2D1HwndRenderTarget_DrawTextLayout(This, origin, textLayout, defaultForegroundBrush, options) \ + ((This)->lpVtbl->Base.DrawTextLayout((ID2D1RenderTarget *)This, origin, textLayout, defaultForegroundBrush, options)) + +#define ID2D1HwndRenderTarget_DrawGlyphRun(This, baselineOrigin, glyphRun, foregroundBrush, measuringMode) \ + ((This)->lpVtbl->Base.DrawGlyphRun((ID2D1RenderTarget *)This, baselineOrigin, glyphRun, foregroundBrush, measuringMode)) + +#define ID2D1HwndRenderTarget_SetTransform(This, transform) \ + ((This)->lpVtbl->Base.SetTransform((ID2D1RenderTarget *)This, transform)) + +#define ID2D1HwndRenderTarget_GetTransform(This, transform) \ + ((This)->lpVtbl->Base.GetTransform((ID2D1RenderTarget *)This, transform)) + +#define ID2D1HwndRenderTarget_SetAntialiasMode(This, antialiasMode) \ + ((This)->lpVtbl->Base.SetAntialiasMode((ID2D1RenderTarget *)This, antialiasMode)) + +#define ID2D1HwndRenderTarget_GetAntialiasMode(This) \ + ((This)->lpVtbl->Base.GetAntialiasMode((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_SetTextAntialiasMode(This, textAntialiasMode) \ + ((This)->lpVtbl->Base.SetTextAntialiasMode((ID2D1RenderTarget *)This, textAntialiasMode)) + +#define ID2D1HwndRenderTarget_GetTextAntialiasMode(This) \ + ((This)->lpVtbl->Base.GetTextAntialiasMode((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_SetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->Base.SetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams)) + +#define ID2D1HwndRenderTarget_GetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->Base.GetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams)) + +#define ID2D1HwndRenderTarget_SetTags(This, tag1, tag2) \ + ((This)->lpVtbl->Base.SetTags((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1HwndRenderTarget_GetTags(This, tag1, tag2) \ + ((This)->lpVtbl->Base.GetTags((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1HwndRenderTarget_PushLayer(This, layerParameters, layer) \ + ((This)->lpVtbl->Base.PushLayer((ID2D1RenderTarget *)This, layerParameters, layer)) + +#define ID2D1HwndRenderTarget_PopLayer(This) \ + ((This)->lpVtbl->Base.PopLayer((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_Flush(This, tag1, tag2) \ + ((This)->lpVtbl->Base.Flush((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1HwndRenderTarget_SaveDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->Base.SaveDrawingState((ID2D1RenderTarget *)This, drawingStateBlock)) + +#define ID2D1HwndRenderTarget_RestoreDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->Base.RestoreDrawingState((ID2D1RenderTarget *)This, drawingStateBlock)) + +#define ID2D1HwndRenderTarget_PushAxisAlignedClip(This, clipRect, antialiasMode) \ + ((This)->lpVtbl->Base.PushAxisAlignedClip((ID2D1RenderTarget *)This, clipRect, antialiasMode)) + +#define ID2D1HwndRenderTarget_PopAxisAlignedClip(This) \ + ((This)->lpVtbl->Base.PopAxisAlignedClip((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_Clear(This, clearColor) \ + ((This)->lpVtbl->Base.Clear((ID2D1RenderTarget *)This, clearColor)) + +#define ID2D1HwndRenderTarget_BeginDraw(This) \ + ((This)->lpVtbl->Base.BeginDraw((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_EndDraw(This, tag1, tag2) \ + ((This)->lpVtbl->Base.EndDraw((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1HwndRenderTarget_GetPixelFormat(This) \ + ((This)->lpVtbl->Base.GetPixelFormat((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_SetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->Base.SetDpi((ID2D1RenderTarget *)This, dpiX, dpiY)) + +#define ID2D1HwndRenderTarget_GetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->Base.GetDpi((ID2D1RenderTarget *)This, dpiX, dpiY)) + +#define ID2D1HwndRenderTarget_GetSize(This) \ + ((This)->lpVtbl->Base.GetSize((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_GetPixelSize(This) \ + ((This)->lpVtbl->Base.GetPixelSize((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_GetMaximumBitmapSize(This) \ + ((This)->lpVtbl->Base.GetMaximumBitmapSize((ID2D1RenderTarget *)This)) + +#define ID2D1HwndRenderTarget_IsSupported(This, renderTargetProperties) \ + ((This)->lpVtbl->Base.IsSupported((ID2D1RenderTarget *)This, renderTargetProperties)) + +#define ID2D1HwndRenderTarget_CheckWindowState(This) \ + ((This)->lpVtbl->CheckWindowState(This)) + +#define ID2D1HwndRenderTarget_Resize(This, pixelSize) \ + ((This)->lpVtbl->Resize(This, pixelSize)) + +#define ID2D1HwndRenderTarget_GetHwnd(This) \ + ((This)->lpVtbl->GetHwnd(This)) + +typedef interface ID2D1GdiInteropRenderTarget ID2D1GdiInteropRenderTarget; + +typedef struct ID2D1GdiInteropRenderTargetVtbl +{ + + IUnknownVtbl Base; + + + STDMETHOD(GetDC)( + ID2D1GdiInteropRenderTarget *This, + D2D1_DC_INITIALIZE_MODE mode, + __out HDC *hdc + ) PURE; + + STDMETHOD(ReleaseDC)( + ID2D1GdiInteropRenderTarget *This, + __in_opt CONST RECT *update + ) PURE; +} ID2D1GdiInteropRenderTargetVtbl; + +interface ID2D1GdiInteropRenderTarget +{ + CONST struct ID2D1GdiInteropRenderTargetVtbl *lpVtbl; +}; + + +#define ID2D1GdiInteropRenderTarget_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1GdiInteropRenderTarget_AddRef(This) \ + ((This)->lpVtbl->Base.AddRef((IUnknown *)This)) + +#define ID2D1GdiInteropRenderTarget_Release(This) \ + ((This)->lpVtbl->Base.Release((IUnknown *)This)) + +#define ID2D1GdiInteropRenderTarget_GetDC(This, mode, hdc) \ + ((This)->lpVtbl->GetDC(This, mode, hdc)) + +#define ID2D1GdiInteropRenderTarget_ReleaseDC(This, update) \ + ((This)->lpVtbl->ReleaseDC(This, update)) + +typedef interface ID2D1DCRenderTarget ID2D1DCRenderTarget; + +typedef struct ID2D1DCRenderTargetVtbl +{ + + ID2D1RenderTargetVtbl Base; + + + STDMETHOD(BindDC)( + ID2D1DCRenderTarget *This, + __in CONST HDC hDC, + __in CONST RECT *pSubRect + ) PURE; +} ID2D1DCRenderTargetVtbl; + +interface ID2D1DCRenderTarget +{ + CONST struct ID2D1DCRenderTargetVtbl *lpVtbl; +}; + + +#define ID2D1DCRenderTarget_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1DCRenderTarget_AddRef(This) \ + ((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This)) + +#define ID2D1DCRenderTarget_Release(This) \ + ((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This)) + +#define ID2D1DCRenderTarget_GetFactory(This, factory) \ + ((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory)) + +#define ID2D1DCRenderTarget_CreateBitmap(This, size, srcData, pitch, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateBitmap((ID2D1RenderTarget *)This, size, srcData, pitch, bitmapProperties, bitmap)) + +#define ID2D1DCRenderTarget_CreateBitmapFromWicBitmap(This, wicBitmapSource, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateBitmapFromWicBitmap((ID2D1RenderTarget *)This, wicBitmapSource, bitmapProperties, bitmap)) + +#define ID2D1DCRenderTarget_CreateSharedBitmap(This, riid, data, bitmapProperties, bitmap) \ + ((This)->lpVtbl->Base.CreateSharedBitmap((ID2D1RenderTarget *)This, riid, data, bitmapProperties, bitmap)) + +#define ID2D1DCRenderTarget_CreateBitmapBrush(This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush) \ + ((This)->lpVtbl->Base.CreateBitmapBrush((ID2D1RenderTarget *)This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush)) + +#define ID2D1DCRenderTarget_CreateSolidColorBrush(This, color, brushProperties, solidColorBrush) \ + ((This)->lpVtbl->Base.CreateSolidColorBrush((ID2D1RenderTarget *)This, color, brushProperties, solidColorBrush)) + +#define ID2D1DCRenderTarget_CreateGradientStopCollection(This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection) \ + ((This)->lpVtbl->Base.CreateGradientStopCollection((ID2D1RenderTarget *)This, gradientStops, gradientStopsCount, colorInterpolationGamma, extendMode, gradientStopCollection)) + +#define ID2D1DCRenderTarget_CreateLinearGradientBrush(This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush) \ + ((This)->lpVtbl->Base.CreateLinearGradientBrush((ID2D1RenderTarget *)This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush)) + +#define ID2D1DCRenderTarget_CreateRadialGradientBrush(This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush) \ + ((This)->lpVtbl->Base.CreateRadialGradientBrush((ID2D1RenderTarget *)This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush)) + +#define ID2D1DCRenderTarget_CreateCompatibleRenderTarget(This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget) \ + ((This)->lpVtbl->Base.CreateCompatibleRenderTarget((ID2D1RenderTarget *)This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget)) + +#define ID2D1DCRenderTarget_CreateLayer(This, size, layer) \ + ((This)->lpVtbl->Base.CreateLayer((ID2D1RenderTarget *)This, size, layer)) + +#define ID2D1DCRenderTarget_CreateMesh(This, mesh) \ + ((This)->lpVtbl->Base.CreateMesh((ID2D1RenderTarget *)This, mesh)) + +#define ID2D1DCRenderTarget_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawLine((ID2D1RenderTarget *)This, point0, point1, brush, strokeWidth, strokeStyle)) + +#define ID2D1DCRenderTarget_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawRectangle((ID2D1RenderTarget *)This, rect, brush, strokeWidth, strokeStyle)) + +#define ID2D1DCRenderTarget_FillRectangle(This, rect, brush) \ + ((This)->lpVtbl->Base.FillRectangle((ID2D1RenderTarget *)This, rect, brush)) + +#define ID2D1DCRenderTarget_DrawRoundedRectangle(This, roundedRect, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush, strokeWidth, strokeStyle)) + +#define ID2D1DCRenderTarget_FillRoundedRectangle(This, roundedRect, brush) \ + ((This)->lpVtbl->Base.FillRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush)) + +#define ID2D1DCRenderTarget_DrawEllipse(This, ellipse, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawEllipse((ID2D1RenderTarget *)This, ellipse, brush, strokeWidth, strokeStyle)) + +#define ID2D1DCRenderTarget_FillEllipse(This, ellipse, brush) \ + ((This)->lpVtbl->Base.FillEllipse((ID2D1RenderTarget *)This, ellipse, brush)) + +#define ID2D1DCRenderTarget_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \ + ((This)->lpVtbl->Base.DrawGeometry((ID2D1RenderTarget *)This, geometry, brush, strokeWidth, strokeStyle)) + +#define ID2D1DCRenderTarget_FillGeometry(This, geometry, brush, opacityBrush) \ + ((This)->lpVtbl->Base.FillGeometry((ID2D1RenderTarget *)This, geometry, brush, opacityBrush)) + +#define ID2D1DCRenderTarget_FillMesh(This, mesh, brush) \ + ((This)->lpVtbl->Base.FillMesh((ID2D1RenderTarget *)This, mesh, brush)) + +#define ID2D1DCRenderTarget_FillOpacityMask(This, opacityMask, brush, content, destinationRectangle, sourceRectangle) \ + ((This)->lpVtbl->Base.FillOpacityMask((ID2D1RenderTarget *)This, opacityMask, brush, content, destinationRectangle, sourceRectangle)) + +#define ID2D1DCRenderTarget_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle) \ + ((This)->lpVtbl->Base.DrawBitmap((ID2D1RenderTarget *)This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle)) + +#define ID2D1DCRenderTarget_DrawText(This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode) \ + ((This)->lpVtbl->Base.DrawText((ID2D1RenderTarget *)This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode)) + +#define ID2D1DCRenderTarget_DrawTextLayout(This, origin, textLayout, defaultForegroundBrush, options) \ + ((This)->lpVtbl->Base.DrawTextLayout((ID2D1RenderTarget *)This, origin, textLayout, defaultForegroundBrush, options)) + +#define ID2D1DCRenderTarget_DrawGlyphRun(This, baselineOrigin, glyphRun, foregroundBrush, measuringMode) \ + ((This)->lpVtbl->Base.DrawGlyphRun((ID2D1RenderTarget *)This, baselineOrigin, glyphRun, foregroundBrush, measuringMode)) + +#define ID2D1DCRenderTarget_SetTransform(This, transform) \ + ((This)->lpVtbl->Base.SetTransform((ID2D1RenderTarget *)This, transform)) + +#define ID2D1DCRenderTarget_GetTransform(This, transform) \ + ((This)->lpVtbl->Base.GetTransform((ID2D1RenderTarget *)This, transform)) + +#define ID2D1DCRenderTarget_SetAntialiasMode(This, antialiasMode) \ + ((This)->lpVtbl->Base.SetAntialiasMode((ID2D1RenderTarget *)This, antialiasMode)) + +#define ID2D1DCRenderTarget_GetAntialiasMode(This) \ + ((This)->lpVtbl->Base.GetAntialiasMode((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_SetTextAntialiasMode(This, textAntialiasMode) \ + ((This)->lpVtbl->Base.SetTextAntialiasMode((ID2D1RenderTarget *)This, textAntialiasMode)) + +#define ID2D1DCRenderTarget_GetTextAntialiasMode(This) \ + ((This)->lpVtbl->Base.GetTextAntialiasMode((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_SetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->Base.SetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams)) + +#define ID2D1DCRenderTarget_GetTextRenderingParams(This, textRenderingParams) \ + ((This)->lpVtbl->Base.GetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams)) + +#define ID2D1DCRenderTarget_SetTags(This, tag1, tag2) \ + ((This)->lpVtbl->Base.SetTags((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1DCRenderTarget_GetTags(This, tag1, tag2) \ + ((This)->lpVtbl->Base.GetTags((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1DCRenderTarget_PushLayer(This, layerParameters, layer) \ + ((This)->lpVtbl->Base.PushLayer((ID2D1RenderTarget *)This, layerParameters, layer)) + +#define ID2D1DCRenderTarget_PopLayer(This) \ + ((This)->lpVtbl->Base.PopLayer((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_Flush(This, tag1, tag2) \ + ((This)->lpVtbl->Base.Flush((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1DCRenderTarget_SaveDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->Base.SaveDrawingState((ID2D1RenderTarget *)This, drawingStateBlock)) + +#define ID2D1DCRenderTarget_RestoreDrawingState(This, drawingStateBlock) \ + ((This)->lpVtbl->Base.RestoreDrawingState((ID2D1RenderTarget *)This, drawingStateBlock)) + +#define ID2D1DCRenderTarget_PushAxisAlignedClip(This, clipRect, antialiasMode) \ + ((This)->lpVtbl->Base.PushAxisAlignedClip((ID2D1RenderTarget *)This, clipRect, antialiasMode)) + +#define ID2D1DCRenderTarget_PopAxisAlignedClip(This) \ + ((This)->lpVtbl->Base.PopAxisAlignedClip((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_Clear(This, clearColor) \ + ((This)->lpVtbl->Base.Clear((ID2D1RenderTarget *)This, clearColor)) + +#define ID2D1DCRenderTarget_BeginDraw(This) \ + ((This)->lpVtbl->Base.BeginDraw((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_EndDraw(This, tag1, tag2) \ + ((This)->lpVtbl->Base.EndDraw((ID2D1RenderTarget *)This, tag1, tag2)) + +#define ID2D1DCRenderTarget_GetPixelFormat(This) \ + ((This)->lpVtbl->Base.GetPixelFormat((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_SetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->Base.SetDpi((ID2D1RenderTarget *)This, dpiX, dpiY)) + +#define ID2D1DCRenderTarget_GetDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->Base.GetDpi((ID2D1RenderTarget *)This, dpiX, dpiY)) + +#define ID2D1DCRenderTarget_GetSize(This) \ + ((This)->lpVtbl->Base.GetSize((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_GetPixelSize(This) \ + ((This)->lpVtbl->Base.GetPixelSize((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_GetMaximumBitmapSize(This) \ + ((This)->lpVtbl->Base.GetMaximumBitmapSize((ID2D1RenderTarget *)This)) + +#define ID2D1DCRenderTarget_IsSupported(This, renderTargetProperties) \ + ((This)->lpVtbl->Base.IsSupported((ID2D1RenderTarget *)This, renderTargetProperties)) + +#define ID2D1DCRenderTarget_BindDC(This, hDC, pSubRect) \ + ((This)->lpVtbl->BindDC(This, hDC, pSubRect)) + +typedef interface ID2D1Factory ID2D1Factory; + +typedef struct ID2D1FactoryVtbl +{ + + IUnknownVtbl Base; + + + STDMETHOD(ReloadSystemMetrics)( + ID2D1Factory *This + ) PURE; + + STDMETHOD_(void, GetDesktopDpi)( + ID2D1Factory *This, + __out FLOAT *dpiX, + __out FLOAT *dpiY + ) PURE; + + STDMETHOD(CreateRectangleGeometry)( + ID2D1Factory *This, + __in CONST D2D1_RECT_F *rectangle, + __deref_out ID2D1RectangleGeometry **rectangleGeometry + ) PURE; + + STDMETHOD(CreateRoundedRectangleGeometry)( + ID2D1Factory *This, + __in CONST D2D1_ROUNDED_RECT *roundedRectangle, + __deref_out ID2D1RoundedRectangleGeometry **roundedRectangleGeometry + ) PURE; + + STDMETHOD(CreateEllipseGeometry)( + ID2D1Factory *This, + __in CONST D2D1_ELLIPSE *ellipse, + __deref_out ID2D1EllipseGeometry **ellipseGeometry + ) PURE; + + STDMETHOD(CreateGeometryGroup)( + ID2D1Factory *This, + D2D1_FILL_MODE fillMode, + __in_ecount(geometriesCount) ID2D1Geometry **geometries, + UINT geometriesCount, + __deref_out ID2D1GeometryGroup **geometryGroup + ) PURE; + + STDMETHOD(CreateTransformedGeometry)( + ID2D1Factory *This, + __in ID2D1Geometry *sourceGeometry, + __in CONST D2D1_MATRIX_3X2_F *transform, + __deref_out ID2D1TransformedGeometry **transformedGeometry + ) PURE; + + STDMETHOD(CreatePathGeometry)( + ID2D1Factory *This, + __deref_out ID2D1PathGeometry **pathGeometry + ) PURE; + + STDMETHOD(CreateStrokeStyle)( + ID2D1Factory *This, + __in CONST D2D1_STROKE_STYLE_PROPERTIES *strokeStyleProperties, + __in_ecount_opt(dashesCount) CONST FLOAT *dashes, + UINT dashesCount, + __deref_out ID2D1StrokeStyle **strokeStyle + ) PURE; + + STDMETHOD(CreateDrawingStateBlock)( + ID2D1Factory *This, + __in_opt CONST D2D1_DRAWING_STATE_DESCRIPTION *drawingStateDescription, + __in_opt IDWriteRenderingParams *textRenderingParams, + __deref_out ID2D1DrawingStateBlock **drawingStateBlock + ) PURE; + + STDMETHOD(CreateWicBitmapRenderTarget)( + ID2D1Factory *This, + __in IWICBitmap *target, + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __deref_out ID2D1RenderTarget **renderTarget + ) PURE; + + STDMETHOD(CreateHwndRenderTarget)( + ID2D1Factory *This, + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __in CONST D2D1_HWND_RENDER_TARGET_PROPERTIES *hwndRenderTargetProperties, + __deref_out ID2D1HwndRenderTarget **hwndRenderTarget + ) PURE; + + STDMETHOD(CreateDxgiSurfaceRenderTarget)( + ID2D1Factory *This, + __in IDXGISurface *dxgiSurface, + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __deref_out ID2D1RenderTarget **renderTarget + ) PURE; + + STDMETHOD(CreateDCRenderTarget)( + ID2D1Factory *This, + __in CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, + __deref_out ID2D1DCRenderTarget **dcRenderTarget + ) PURE; +} ID2D1FactoryVtbl; + +interface ID2D1Factory +{ + CONST struct ID2D1FactoryVtbl *lpVtbl; +}; + + +#define ID2D1Factory_QueryInterface(This, riid, ppv) \ + ((This)->lpVtbl->Base.QueryInterface((IUnknown *)This, riid, ppv)) + +#define ID2D1Factory_AddRef(This) \ + ((This)->lpVtbl->Base.AddRef((IUnknown *)This)) + +#define ID2D1Factory_Release(This) \ + ((This)->lpVtbl->Base.Release((IUnknown *)This)) + +#define ID2D1Factory_ReloadSystemMetrics(This) \ + ((This)->lpVtbl->ReloadSystemMetrics(This)) + +#define ID2D1Factory_GetDesktopDpi(This, dpiX, dpiY) \ + ((This)->lpVtbl->GetDesktopDpi(This, dpiX, dpiY)) + +#define ID2D1Factory_CreateRectangleGeometry(This, rectangle, rectangleGeometry) \ + ((This)->lpVtbl->CreateRectangleGeometry(This, rectangle, rectangleGeometry)) + +#define ID2D1Factory_CreateRoundedRectangleGeometry(This, roundedRectangle, roundedRectangleGeometry) \ + ((This)->lpVtbl->CreateRoundedRectangleGeometry(This, roundedRectangle, roundedRectangleGeometry)) + +#define ID2D1Factory_CreateEllipseGeometry(This, ellipse, ellipseGeometry) \ + ((This)->lpVtbl->CreateEllipseGeometry(This, ellipse, ellipseGeometry)) + +#define ID2D1Factory_CreateGeometryGroup(This, fillMode, geometries, geometriesCount, geometryGroup) \ + ((This)->lpVtbl->CreateGeometryGroup(This, fillMode, geometries, geometriesCount, geometryGroup)) + +#define ID2D1Factory_CreateTransformedGeometry(This, sourceGeometry, transform, transformedGeometry) \ + ((This)->lpVtbl->CreateTransformedGeometry(This, sourceGeometry, transform, transformedGeometry)) + +#define ID2D1Factory_CreatePathGeometry(This, pathGeometry) \ + ((This)->lpVtbl->CreatePathGeometry(This, pathGeometry)) + +#define ID2D1Factory_CreateStrokeStyle(This, strokeStyleProperties, dashes, dashesCount, strokeStyle) \ + ((This)->lpVtbl->CreateStrokeStyle(This, strokeStyleProperties, dashes, dashesCount, strokeStyle)) + +#define ID2D1Factory_CreateDrawingStateBlock(This, drawingStateDescription, textRenderingParams, drawingStateBlock) \ + ((This)->lpVtbl->CreateDrawingStateBlock(This, drawingStateDescription, textRenderingParams, drawingStateBlock)) + +#define ID2D1Factory_CreateWicBitmapRenderTarget(This, target, renderTargetProperties, renderTarget) \ + ((This)->lpVtbl->CreateWicBitmapRenderTarget(This, target, renderTargetProperties, renderTarget)) + +#define ID2D1Factory_CreateHwndRenderTarget(This, renderTargetProperties, hwndRenderTargetProperties, hwndRenderTarget) \ + ((This)->lpVtbl->CreateHwndRenderTarget(This, renderTargetProperties, hwndRenderTargetProperties, hwndRenderTarget)) + +#define ID2D1Factory_CreateDxgiSurfaceRenderTarget(This, dxgiSurface, renderTargetProperties, renderTarget) \ + ((This)->lpVtbl->CreateDxgiSurfaceRenderTarget(This, dxgiSurface, renderTargetProperties, renderTarget)) + +#define ID2D1Factory_CreateDCRenderTarget(This, renderTargetProperties, dcRenderTarget) \ + ((This)->lpVtbl->CreateDCRenderTarget(This, renderTargetProperties, dcRenderTarget)) + + +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + + // + // This export cannot be in a namespace because compiler name mangling isn't consistent + // also, this must be 'C' callable. + // + HRESULT WINAPI + D2D1CreateFactory( + __in D2D1_FACTORY_TYPE factoryType, + __in REFIID riid, + __in_opt CONST D2D1_FACTORY_OPTIONS *pFactoryOptions, + __out void **ppIFactory + ); + + + void WINAPI + D2D1MakeRotateMatrix( + __in FLOAT angle, + __in D2D1_POINT_2F center, + __out D2D1_MATRIX_3X2_F *matrix + ); + + void WINAPI + D2D1MakeSkewMatrix( + __in FLOAT angleX, + __in FLOAT angleY, + __in D2D1_POINT_2F center, + __out D2D1_MATRIX_3X2_F *matrix + ); + + BOOL WINAPI + D2D1IsMatrixInvertible( + __in CONST D2D1_MATRIX_3X2_F *matrix + ); + + BOOL WINAPI + D2D1InvertMatrix( + __inout D2D1_MATRIX_3X2_F *matrix + ); + +#ifdef __cplusplus +} +#endif + +#ifndef D2D1FORCEINLINE +#define D2D1FORCEINLINE FORCEINLINE +#endif // #ifndef D2D1FORCEINLINE + + +#include + + +#ifndef D2D_USE_C_DEFINITIONS + +inline +HRESULT +D2D1CreateFactory( + __in D2D1_FACTORY_TYPE factoryType, + __in REFIID riid, + __out void **factory + ) +{ + return + D2D1CreateFactory( + factoryType, + riid, + NULL, + factory); +} + + +template +HRESULT +D2D1CreateFactory( + __in D2D1_FACTORY_TYPE factoryType, + __out Factory **factory + ) +{ + return + D2D1CreateFactory( + factoryType, + __uuidof(Factory), + reinterpret_cast(factory)); +} + +template +HRESULT +D2D1CreateFactory( + __in D2D1_FACTORY_TYPE factoryType, + __in CONST D2D1_FACTORY_OPTIONS &factoryOptions, + __out Factory **ppFactory + ) +{ + return + D2D1CreateFactory( + factoryType, + __uuidof(Factory), + &factoryOptions, + reinterpret_cast(ppFactory)); +} + +#endif // #ifndef D2D_USE_C_DEFINITIONS +#endif // #ifndef _D2D1_H_ diff --git a/dxsdk/Include/D2D1Helper.h b/dxsdk/Include/D2D1Helper.h new file mode 100644 index 0000000..2f54ea2 --- /dev/null +++ b/dxsdk/Include/D2D1Helper.h @@ -0,0 +1,948 @@ + +/*=========================================================================*\ + + Copyright (c) Microsoft Corporation. All rights reserved. + + File: D2D1helper.h + + Module Name: D2D + + Description: Helper files over the D2D interfaces and APIs. + +\*=========================================================================*/ +#pragma once + +#ifndef _D2D1_HELPER_H_ +#define _D2D1_HELPER_H_ + +#ifndef _D2D1_H_ +#include +#endif // #ifndef _D2D1_H_ + +#ifndef D2D_USE_C_DEFINITIONS + +namespace D2D1 +{ + // + // Forward declared IdentityMatrix function to allow matrix class to use + // these constructors. + // + D2D1FORCEINLINE + D2D1_MATRIX_3X2_F + IdentityMatrix(); + + // + // The default trait type for objects in D2D is float. + // + template + struct TypeTraits + { + typedef D2D1_POINT_2F Point; + typedef D2D1_SIZE_F Size; + typedef D2D1_RECT_F Rect; + }; + + template<> + struct TypeTraits + { + typedef D2D1_POINT_2U Point; + typedef D2D1_SIZE_U Size; + typedef D2D1_RECT_U Rect; + }; + + static inline + FLOAT FloatMax() + { + #ifdef FLT_MAX + return FLT_MAX; + #else + return 3.402823466e+38F; + #endif + } + + // + // Construction helpers + // + template + D2D1FORCEINLINE + typename TypeTraits::Point + Point2( + Type x, + Type y + ) + { + typename TypeTraits::Point point = { x, y }; + + return point; + } + + D2D1FORCEINLINE + D2D1_POINT_2F + Point2F( + FLOAT x = 0.f, + FLOAT y = 0.f + ) + { + return Point2(x, y); + } + + D2D1FORCEINLINE + D2D1_POINT_2U + Point2U( + UINT32 x = 0, + UINT32 y = 0 + ) + { + return Point2(x, y); + } + + template + D2D1FORCEINLINE + typename TypeTraits::Size + Size( + Type width, + Type height + ) + { + typename TypeTraits::Size size = { width, height }; + + return size; + } + + D2D1FORCEINLINE + D2D1_SIZE_F + SizeF( + FLOAT width = 0.f, + FLOAT height = 0.f + ) + { + return Size(width, height); + } + + D2D1FORCEINLINE + D2D1_SIZE_U + SizeU( + UINT32 width = 0, + UINT32 height = 0 + ) + { + return Size(width, height); + } + + template + D2D1FORCEINLINE + typename TypeTraits::Rect + Rect( + Type left, + Type top, + Type right, + Type bottom + ) + { + typename TypeTraits::Rect rect = { left, top, right, bottom }; + + return rect; + } + + D2D1FORCEINLINE + D2D1_RECT_F + RectF( + FLOAT left = 0.f, + FLOAT top = 0.f, + FLOAT right = 0.f, + FLOAT bottom = 0.f + ) + { + return Rect(left, top, right, bottom); + } + + D2D1FORCEINLINE + D2D1_RECT_U + RectU( + UINT32 left = 0, + UINT32 top = 0, + UINT32 right = 0, + UINT32 bottom = 0 + ) + { + return Rect(left, top, right, bottom); + } + + D2D1FORCEINLINE + D2D1_RECT_F + InfiniteRect() + { + D2D1_RECT_F rect = { -FloatMax(), -FloatMax(), FloatMax(), FloatMax() }; + + return rect; + } + + D2D1FORCEINLINE + D2D1_ARC_SEGMENT + ArcSegment( + __in CONST D2D1_POINT_2F &point, + __in CONST D2D1_SIZE_F &size, + __in FLOAT rotationAngle, + __in D2D1_SWEEP_DIRECTION sweepDirection, + __in D2D1_ARC_SIZE arcSize + ) + { + D2D1_ARC_SEGMENT arcSegment = { point, size, rotationAngle, sweepDirection, arcSize }; + + return arcSegment; + } + + D2D1FORCEINLINE + D2D1_BEZIER_SEGMENT + BezierSegment( + __in CONST D2D1_POINT_2F &point1, + __in CONST D2D1_POINT_2F &point2, + __in CONST D2D1_POINT_2F &point3 + ) + { + D2D1_BEZIER_SEGMENT bezierSegment = { point1, point2, point3 }; + + return bezierSegment; + } + + D2D1FORCEINLINE + D2D1_ELLIPSE + Ellipse( + __in CONST D2D1_POINT_2F ¢er, + FLOAT radiusX, + FLOAT radiusY + ) + { + D2D1_ELLIPSE ellipse; + + ellipse.point = center; + ellipse.radiusX = radiusX; + ellipse.radiusY = radiusY; + + return ellipse; + } + + D2D1FORCEINLINE + D2D1_ROUNDED_RECT + RoundedRect( + __in CONST D2D1_RECT_F &rect, + FLOAT radiusX, + FLOAT radiusY + ) + { + D2D1_ROUNDED_RECT roundedRect; + + roundedRect.rect = rect; + roundedRect.radiusX = radiusX; + roundedRect.radiusY = radiusY; + + return roundedRect; + } + + D2D1FORCEINLINE + D2D1_BRUSH_PROPERTIES + BrushProperties( + __in FLOAT opacity = 1.0, + __in CONST D2D1_MATRIX_3X2_F &transform = D2D1::IdentityMatrix() + ) + { + D2D1_BRUSH_PROPERTIES brushProperties; + + brushProperties.opacity = opacity; + brushProperties.transform = transform; + + return brushProperties; + } + + D2D1FORCEINLINE + D2D1_GRADIENT_STOP + GradientStop( + FLOAT position, + __in CONST D2D1_COLOR_F &color + ) + { + D2D1_GRADIENT_STOP gradientStop = { position, color }; + + return gradientStop; + } + + D2D1FORCEINLINE + D2D1_QUADRATIC_BEZIER_SEGMENT + QuadraticBezierSegment( + __in CONST D2D1_POINT_2F &point1, + __in CONST D2D1_POINT_2F &point2 + ) + { + D2D1_QUADRATIC_BEZIER_SEGMENT quadraticBezier = { point1, point2 }; + + return quadraticBezier; + } + + D2D1FORCEINLINE + D2D1_STROKE_STYLE_PROPERTIES + StrokeStyleProperties( + D2D1_CAP_STYLE startCap = D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE endCap = D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE dashCap = D2D1_CAP_STYLE_FLAT, + D2D1_LINE_JOIN lineJoin = D2D1_LINE_JOIN_MITER, + FLOAT miterLimit = 10.0f, + D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID, + FLOAT dashOffset = 0.0f + ) + { + D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties; + + strokeStyleProperties.startCap = startCap; + strokeStyleProperties.endCap = endCap; + strokeStyleProperties.dashCap = dashCap; + strokeStyleProperties.lineJoin = lineJoin; + strokeStyleProperties.miterLimit = miterLimit; + strokeStyleProperties.dashStyle = dashStyle; + strokeStyleProperties.dashOffset = dashOffset; + + return strokeStyleProperties; + } + + D2D1FORCEINLINE + D2D1_BITMAP_BRUSH_PROPERTIES + BitmapBrushProperties( + D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP, + D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP, + D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR + ) + { + D2D1_BITMAP_BRUSH_PROPERTIES bitmapBrushProperties; + + bitmapBrushProperties.extendModeX = extendModeX; + bitmapBrushProperties.extendModeY = extendModeY; + bitmapBrushProperties.interpolationMode = interpolationMode; + + return bitmapBrushProperties; + } + + D2D1FORCEINLINE + D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES + LinearGradientBrushProperties( + __in CONST D2D1_POINT_2F &startPoint, + __in CONST D2D1_POINT_2F &endPoint + ) + { + D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties; + + linearGradientBrushProperties.startPoint = startPoint; + linearGradientBrushProperties.endPoint = endPoint; + + return linearGradientBrushProperties; + } + + D2D1FORCEINLINE + D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES + RadialGradientBrushProperties( + __in CONST D2D1_POINT_2F ¢er, + __in CONST D2D1_POINT_2F &gradientOriginOffset, + FLOAT radiusX, + FLOAT radiusY + ) + { + D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties; + + radialGradientBrushProperties.center = center; + radialGradientBrushProperties.gradientOriginOffset = gradientOriginOffset; + radialGradientBrushProperties.radiusX = radiusX; + radialGradientBrushProperties.radiusY = radiusY; + + return radialGradientBrushProperties; + } + + // + // PixelFormat + // + D2D1FORCEINLINE + D2D1_PIXEL_FORMAT + PixelFormat( + __in DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN, + __in D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_UNKNOWN + ) + { + D2D1_PIXEL_FORMAT pixelFormat; + + pixelFormat.format = dxgiFormat; + pixelFormat.alphaMode = alphaMode; + + return pixelFormat; + } + + // + // Bitmaps + // + D2D1FORCEINLINE + D2D1_BITMAP_PROPERTIES + BitmapProperties( + CONST D2D1_PIXEL_FORMAT &pixelFormat = D2D1::PixelFormat(), + FLOAT dpiX = 96.0f, + FLOAT dpiY = 96.0f + ) + { + D2D1_BITMAP_PROPERTIES bitmapProperties; + + bitmapProperties.pixelFormat = pixelFormat; + bitmapProperties.dpiX = dpiX; + bitmapProperties.dpiY = dpiY; + + return bitmapProperties; + } + + // + // Render Targets + // + D2D1FORCEINLINE + D2D1_RENDER_TARGET_PROPERTIES + RenderTargetProperties( + D2D1_RENDER_TARGET_TYPE type = D2D1_RENDER_TARGET_TYPE_DEFAULT, + __in CONST D2D1_PIXEL_FORMAT &pixelFormat = D2D1::PixelFormat(), + FLOAT dpiX = 0.0, + FLOAT dpiY = 0.0, + D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE, + D2D1_FEATURE_LEVEL minLevel = D2D1_FEATURE_LEVEL_DEFAULT + ) + { + D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties; + + renderTargetProperties.type = type; + renderTargetProperties.pixelFormat = pixelFormat; + renderTargetProperties.dpiX = dpiX; + renderTargetProperties.dpiY = dpiY; + renderTargetProperties.usage = usage; + renderTargetProperties.minLevel = minLevel; + + return renderTargetProperties; + } + + D2D1FORCEINLINE + D2D1_HWND_RENDER_TARGET_PROPERTIES + HwndRenderTargetProperties( + __in HWND hwnd, + __in D2D1_SIZE_U pixelSize = D2D1::Size(static_cast(0), static_cast(0)), + __in D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE + ) + { + D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderTargetProperties; + + hwndRenderTargetProperties.hwnd = hwnd; + hwndRenderTargetProperties.pixelSize = pixelSize; + hwndRenderTargetProperties.presentOptions = presentOptions; + + return hwndRenderTargetProperties; + } + + D2D1FORCEINLINE + D2D1_LAYER_PARAMETERS + LayerParameters( + __in CONST D2D1_RECT_F &contentBounds = D2D1::InfiniteRect(), + __in_opt ID2D1Geometry *geometricMask = NULL, + D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, + D2D1_MATRIX_3X2_F maskTransform = D2D1::IdentityMatrix(), + FLOAT opacity = 1.0, + __in_opt ID2D1Brush *opacityBrush = NULL, + D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE + ) + { + D2D1_LAYER_PARAMETERS layerParameters = { 0 }; + + layerParameters.contentBounds = contentBounds; + layerParameters.geometricMask = geometricMask; + layerParameters.maskAntialiasMode = maskAntialiasMode; + layerParameters.maskTransform = maskTransform; + layerParameters.opacity = opacity; + layerParameters.opacityBrush = opacityBrush; + layerParameters.layerOptions = layerOptions; + + return layerParameters; + } + + D2D1FORCEINLINE + D2D1_DRAWING_STATE_DESCRIPTION + DrawingStateDescription( + D2D1_ANTIALIAS_MODE antialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, + D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, + D2D1_TAG tag1 = 0, + D2D1_TAG tag2 = 0, + __in const D2D1_MATRIX_3X2_F &transform = D2D1::IdentityMatrix() + ) + { + D2D1_DRAWING_STATE_DESCRIPTION drawingStateDescription; + + drawingStateDescription.antialiasMode = antialiasMode; + drawingStateDescription.textAntialiasMode = textAntialiasMode; + drawingStateDescription.tag1 = tag1; + drawingStateDescription.tag2 = tag2; + drawingStateDescription.transform = transform; + + return drawingStateDescription; + } + + // + // Colors, this enum defines a set of predefined colors. + // + class ColorF : public D2D1_COLOR_F + { + public: + + enum Enum + { + AliceBlue = 0xF0F8FF, + AntiqueWhite = 0xFAEBD7, + Aqua = 0x00FFFF, + Aquamarine = 0x7FFFD4, + Azure = 0xF0FFFF, + Beige = 0xF5F5DC, + Bisque = 0xFFE4C4, + Black = 0x000000, + BlanchedAlmond = 0xFFEBCD, + Blue = 0x0000FF, + BlueViolet = 0x8A2BE2, + Brown = 0xA52A2A, + BurlyWood = 0xDEB887, + CadetBlue = 0x5F9EA0, + Chartreuse = 0x7FFF00, + Chocolate = 0xD2691E, + Coral = 0xFF7F50, + CornflowerBlue = 0x6495ED, + Cornsilk = 0xFFF8DC, + Crimson = 0xDC143C, + Cyan = 0x00FFFF, + DarkBlue = 0x00008B, + DarkCyan = 0x008B8B, + DarkGoldenrod = 0xB8860B, + DarkGray = 0xA9A9A9, + DarkGreen = 0x006400, + DarkKhaki = 0xBDB76B, + DarkMagenta = 0x8B008B, + DarkOliveGreen = 0x556B2F, + DarkOrange = 0xFF8C00, + DarkOrchid = 0x9932CC, + DarkRed = 0x8B0000, + DarkSalmon = 0xE9967A, + DarkSeaGreen = 0x8FBC8F, + DarkSlateBlue = 0x483D8B, + DarkSlateGray = 0x2F4F4F, + DarkTurquoise = 0x00CED1, + DarkViolet = 0x9400D3, + DeepPink = 0xFF1493, + DeepSkyBlue = 0x00BFFF, + DimGray = 0x696969, + DodgerBlue = 0x1E90FF, + Firebrick = 0xB22222, + FloralWhite = 0xFFFAF0, + ForestGreen = 0x228B22, + Fuchsia = 0xFF00FF, + Gainsboro = 0xDCDCDC, + GhostWhite = 0xF8F8FF, + Gold = 0xFFD700, + Goldenrod = 0xDAA520, + Gray = 0x808080, + Green = 0x008000, + GreenYellow = 0xADFF2F, + Honeydew = 0xF0FFF0, + HotPink = 0xFF69B4, + IndianRed = 0xCD5C5C, + Indigo = 0x4B0082, + Ivory = 0xFFFFF0, + Khaki = 0xF0E68C, + Lavender = 0xE6E6FA, + LavenderBlush = 0xFFF0F5, + LawnGreen = 0x7CFC00, + LemonChiffon = 0xFFFACD, + LightBlue = 0xADD8E6, + LightCoral = 0xF08080, + LightCyan = 0xE0FFFF, + LightGoldenrodYellow = 0xFAFAD2, + LightGreen = 0x90EE90, + LightGray = 0xD3D3D3, + LightPink = 0xFFB6C1, + LightSalmon = 0xFFA07A, + LightSeaGreen = 0x20B2AA, + LightSkyBlue = 0x87CEFA, + LightSlateGray = 0x778899, + LightSteelBlue = 0xB0C4DE, + LightYellow = 0xFFFFE0, + Lime = 0x00FF00, + LimeGreen = 0x32CD32, + Linen = 0xFAF0E6, + Magenta = 0xFF00FF, + Maroon = 0x800000, + MediumAquamarine = 0x66CDAA, + MediumBlue = 0x0000CD, + MediumOrchid = 0xBA55D3, + MediumPurple = 0x9370DB, + MediumSeaGreen = 0x3CB371, + MediumSlateBlue = 0x7B68EE, + MediumSpringGreen = 0x00FA9A, + MediumTurquoise = 0x48D1CC, + MediumVioletRed = 0xC71585, + MidnightBlue = 0x191970, + MintCream = 0xF5FFFA, + MistyRose = 0xFFE4E1, + Moccasin = 0xFFE4B5, + NavajoWhite = 0xFFDEAD, + Navy = 0x000080, + OldLace = 0xFDF5E6, + Olive = 0x808000, + OliveDrab = 0x6B8E23, + Orange = 0xFFA500, + OrangeRed = 0xFF4500, + Orchid = 0xDA70D6, + PaleGoldenrod = 0xEEE8AA, + PaleGreen = 0x98FB98, + PaleTurquoise = 0xAFEEEE, + PaleVioletRed = 0xDB7093, + PapayaWhip = 0xFFEFD5, + PeachPuff = 0xFFDAB9, + Peru = 0xCD853F, + Pink = 0xFFC0CB, + Plum = 0xDDA0DD, + PowderBlue = 0xB0E0E6, + Purple = 0x800080, + Red = 0xFF0000, + RosyBrown = 0xBC8F8F, + RoyalBlue = 0x4169E1, + SaddleBrown = 0x8B4513, + Salmon = 0xFA8072, + SandyBrown = 0xF4A460, + SeaGreen = 0x2E8B57, + SeaShell = 0xFFF5EE, + Sienna = 0xA0522D, + Silver = 0xC0C0C0, + SkyBlue = 0x87CEEB, + SlateBlue = 0x6A5ACD, + SlateGray = 0x708090, + Snow = 0xFFFAFA, + SpringGreen = 0x00FF7F, + SteelBlue = 0x4682B4, + Tan = 0xD2B48C, + Teal = 0x008080, + Thistle = 0xD8BFD8, + Tomato = 0xFF6347, + Turquoise = 0x40E0D0, + Violet = 0xEE82EE, + Wheat = 0xF5DEB3, + White = 0xFFFFFF, + WhiteSmoke = 0xF5F5F5, + Yellow = 0xFFFF00, + YellowGreen = 0x9ACD32, + }; + + // + // Construct a color, note that the alpha value from the "rgb" component + // is never used. + // + D2D1FORCEINLINE + ColorF( + UINT32 rgb, + FLOAT a = 1.0 + ) + { + Init(rgb, a); + } + + D2D1FORCEINLINE + ColorF( + Enum knownColor, + FLOAT a = 1.0 + ) + { + Init(knownColor, a); + } + + D2D1FORCEINLINE + ColorF( + FLOAT r, + FLOAT g, + FLOAT b, + FLOAT a = 1.0 + ) + { + this->r = r; + this->g = g; + this->b = b; + this->a = a; + } + + private: + + D2D1FORCEINLINE + void + Init( + UINT32 rgb, + FLOAT a + ) + { + this->r = static_cast((rgb & sc_redMask) >> sc_redShift) / 255.f; + this->g = static_cast((rgb & sc_greenMask) >> sc_greenShift) / 255.f; + this->b = static_cast((rgb & sc_blueMask) >> sc_blueShift) / 255.f; + this->a = a; + } + + static const UINT32 sc_redShift = 16; + static const UINT32 sc_greenShift = 8; + static const UINT32 sc_blueShift = 0; + + static const UINT32 sc_redMask = 0xff << sc_redShift; + static const UINT32 sc_greenMask = 0xff << sc_greenShift; + static const UINT32 sc_blueMask = 0xff << sc_blueShift; + }; + + class Matrix3x2F : public D2D1_MATRIX_3X2_F + { + public: + + D2D1FORCEINLINE + Matrix3x2F( + FLOAT _11, + FLOAT _12, + FLOAT _21, + FLOAT _22, + FLOAT _31, + FLOAT _32 + ) + { + this->_11 = _11; + this->_12 = _12; + this->_21 = _21; + this->_22 = _22; + this->_31 = _31; + this->_32 = _32; + } + + // + // Creates an identity matrix + // + D2D1FORCEINLINE + Matrix3x2F( + ) + { + } + + // + // Named quasi-constructors + // + static D2D1FORCEINLINE + Matrix3x2F + Identity() + { + Matrix3x2F identity; + + identity._11 = 1.f; + identity._12 = 0.f; + identity._21 = 0.f; + identity._22 = 1.f; + identity._31 = 0.f; + identity._32 = 0.f; + + return identity; + } + + static D2D1FORCEINLINE + Matrix3x2F + Translation( + D2D1_SIZE_F size + ) + { + Matrix3x2F translation; + + translation._11 = 1.0; translation._12 = 0.0; + translation._21 = 0.0; translation._22 = 1.0; + translation._31 = size.width; translation._32 = size.height; + + return translation; + } + + static D2D1FORCEINLINE + Matrix3x2F + Translation( + FLOAT x, + FLOAT y + ) + { + return Translation(SizeF(x, y)); + } + + + static D2D1FORCEINLINE + Matrix3x2F + Scale( + D2D1_SIZE_F size, + D2D1_POINT_2F center = D2D1::Point2F() + ) + { + Matrix3x2F scale; + + scale._11 = size.width; scale._12 = 0.0; + scale._21 = 0.0; scale._22 = size.height; + scale._31 = center.x - size.width * center.x; + scale._32 = center.y - size.height * center.y; + + return scale; + } + + static D2D1FORCEINLINE + Matrix3x2F + Scale( + FLOAT x, + FLOAT y, + D2D1_POINT_2F center = D2D1::Point2F() + ) + { + return Scale(SizeF(x, y), center); + } + + static D2D1FORCEINLINE + Matrix3x2F + Rotation( + FLOAT angle, + D2D1_POINT_2F center = D2D1::Point2F() + ) + { + Matrix3x2F rotation; + + D2D1MakeRotateMatrix(angle, center, &rotation); + + return rotation; + } + + static D2D1FORCEINLINE + Matrix3x2F + Skew( + FLOAT angleX, + FLOAT angleY, + D2D1_POINT_2F center = D2D1::Point2F() + ) + { + Matrix3x2F skew; + + D2D1MakeSkewMatrix(angleX, angleY, center, &skew); + + return skew; + } + + // + // Functions for convertion from the base D2D1_MATRIX_3X2_F to this type + // without making a copy + // + static inline const Matrix3x2F* ReinterpretBaseType(const D2D1_MATRIX_3X2_F *pMatrix) + { + return static_cast(pMatrix); + } + + static inline Matrix3x2F* ReinterpretBaseType(D2D1_MATRIX_3X2_F *pMatrix) + { + return static_cast(pMatrix); + } + + inline + FLOAT + Determinant() const + { + return (_11 * _22) - (_12 * _21); + } + + inline + bool + IsInvertible() const + { + return !!D2D1IsMatrixInvertible(this); + } + + inline + bool + Invert() + { + return !!D2D1InvertMatrix(this); + } + + inline + bool + IsIdentity() const + { + return _11 == 1.f && _12 == 0.f + && _21 == 0.f && _22 == 1.f + && _31 == 0.f && _32 == 0.f; + } + + inline + void SetProduct( + const Matrix3x2F &a, + const Matrix3x2F &b + ) + { + _11 = a._11 * b._11 + a._12 * b._21; + _12 = a._11 * b._12 + a._12 * b._22; + _21 = a._21 * b._11 + a._22 * b._21; + _22 = a._21 * b._12 + a._22 * b._22; + _31 = a._31 * b._11 + a._32 * b._21 + b._31; + _32 = a._31 * b._12 + a._32 * b._22 + b._32; + } + + D2D1FORCEINLINE + Matrix3x2F + operator*( + const Matrix3x2F &matrix + ) const + { + Matrix3x2F result; + + result.SetProduct(*this, matrix); + + return result; + } + + D2D1FORCEINLINE + D2D1_POINT_2F + TransformPoint( + D2D1_POINT_2F point + ) const + { + D2D1_POINT_2F result = + { + point.x * _11 + point.y * _21 + _31, + point.x * _12 + point.y * _22 + _32 + }; + + return result; + } + }; + + D2D1FORCEINLINE + D2D1_POINT_2F + operator*( + const D2D1_POINT_2F &point, + const D2D1_MATRIX_3X2_F &matrix + ) + { + return Matrix3x2F::ReinterpretBaseType(&matrix)->TransformPoint(point); + } + + D2D1_MATRIX_3X2_F + IdentityMatrix() + { + return Matrix3x2F::Identity(); + } + +} // namespace D2D1 + +D2D1FORCEINLINE +D2D1_MATRIX_3X2_F +operator*( + const D2D1_MATRIX_3X2_F &matrix1, + const D2D1_MATRIX_3X2_F &matrix2 + ) +{ + return + (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix1)) * + (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix2)); +} + +#endif // #ifndef D2D_USE_C_DEFINITIONS + +#endif // #ifndef _D2D1_HELPER_H_ + diff --git a/dxsdk/Include/D2DBaseTypes.h b/dxsdk/Include/D2DBaseTypes.h new file mode 100644 index 0000000..c2ff5bb --- /dev/null +++ b/dxsdk/Include/D2DBaseTypes.h @@ -0,0 +1,145 @@ +//--------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file is automatically generated. Please do not edit it directly. +// +// File name: D2DBaseTypes.h +//--------------------------------------------------------------------------- +#pragma once + + +#ifndef _D2DBASETYPES_INCLUDED +#define _D2DBASETYPES_INCLUDED + +#ifndef COM_NO_WINDOWS_H +#include +#endif // #ifndef COM_NO_WINDOWS_H + +#ifndef D3DCOLORVALUE_DEFINED + +//+----------------------------------------------------------------------------- +// +// Struct: +// D3DCOLORVALUE +// +//------------------------------------------------------------------------------ +typedef struct D3DCOLORVALUE +{ + FLOAT r; + FLOAT g; + FLOAT b; + FLOAT a; + +} D3DCOLORVALUE; + +#define D3DCOLORVALUE_DEFINED +#endif + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D_POINT_2U +// +//------------------------------------------------------------------------------ +typedef struct D2D_POINT_2U +{ + UINT32 x; + UINT32 y; + +} D2D_POINT_2U; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D_POINT_2F +// +//------------------------------------------------------------------------------ +typedef struct D2D_POINT_2F +{ + FLOAT x; + FLOAT y; + +} D2D_POINT_2F; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D_RECT_F +// +//------------------------------------------------------------------------------ +typedef struct D2D_RECT_F +{ + FLOAT left; + FLOAT top; + FLOAT right; + FLOAT bottom; + +} D2D_RECT_F; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D_RECT_U +// +//------------------------------------------------------------------------------ +typedef struct D2D_RECT_U +{ + UINT32 left; + UINT32 top; + UINT32 right; + UINT32 bottom; + +} D2D_RECT_U; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D_SIZE_F +// +//------------------------------------------------------------------------------ +typedef struct D2D_SIZE_F +{ + FLOAT width; + FLOAT height; + +} D2D_SIZE_F; + + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D_SIZE_U +// +//------------------------------------------------------------------------------ +typedef struct D2D_SIZE_U +{ + UINT32 width; + UINT32 height; + +} D2D_SIZE_U; + +typedef D3DCOLORVALUE D2D_COLOR_F; + +//+----------------------------------------------------------------------------- +// +// Struct: +// D2D_MATRIX_3X2_F +// +//------------------------------------------------------------------------------ +typedef struct D2D_MATRIX_3X2_F +{ + FLOAT _11; + FLOAT _12; + FLOAT _21; + FLOAT _22; + FLOAT _31; + FLOAT _32; + +} D2D_MATRIX_3X2_F; + +#endif // #ifndef _D2DBASETYPES_INCLUDED diff --git a/dxsdk/Include/D2Derr.h b/dxsdk/Include/D2Derr.h new file mode 100644 index 0000000..afbaa36 --- /dev/null +++ b/dxsdk/Include/D2Derr.h @@ -0,0 +1,206 @@ +/*=========================================================================*\ + + Copyright (c) Microsoft Corporation. All rights reserved. + +\*=========================================================================*/ + +#pragma once + +/*=========================================================================*\ + D2D Status Codes +\*=========================================================================*/ + +#define FACILITY_D2D 0x899 + +#define MAKE_D2DHR( sev, code )\ + MAKE_HRESULT( sev, FACILITY_D2D, (code) ) + +#define MAKE_D2DHR_ERR( code )\ + MAKE_D2DHR( 1, code ) + + +//+---------------------------------------------------------------------------- +// +// D2D error codes +// +//------------------------------------------------------------------------------ + +// +// Error codes shared with WINCODECS +// + +// +// The pixel format is not supported. +// +#define D2DERR_UNSUPPORTED_PIXEL_FORMAT WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT + +// +// Error codes that were already returned in prior versions and were part of the +// MIL facility. + +// +// Error codes mapped from WIN32 where there isn't already another HRESULT based +// define +// + +// +// The supplied buffer was too small to accomodate the data. +// +#define D2DERR_INSUFFICIENT_BUFFER HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) + + +// +// D2D specific codes +// + +// +// The object was not in the correct state to process the method. +// +#define D2DERR_WRONG_STATE MAKE_D2DHR_ERR(0x001) + +// +// The object has not yet been initialized. +// +#define D2DERR_NOT_INITIALIZED MAKE_D2DHR_ERR(0x002) + +// +// The requested opertion is not supported. +// +#define D2DERR_UNSUPPORTED_OPERATION MAKE_D2DHR_ERR(0x003) + +// +// The geomery scanner failed to process the data. +// +#define D2DERR_SCANNER_FAILED MAKE_D2DHR_ERR(0x004) + +// +// D2D could not access the screen. +// +#define D2DERR_SCREEN_ACCESS_DENIED MAKE_D2DHR_ERR(0x005) + +// +// A valid display state could not be determined. +// +#define D2DERR_DISPLAY_STATE_INVALID MAKE_D2DHR_ERR(0x006) + +// +// The supplied vector is vero. +// +#define D2DERR_ZERO_VECTOR MAKE_D2DHR_ERR(0x007) + +// +// An internal error (D2D bug) occurred. On checked builds, we would assert. +// +// The application should close this instance of D2D and should consider +// restarting its process. +// +#define D2DERR_INTERNAL_ERROR MAKE_D2DHR_ERR(0x008) + +// +// The display format we need to render is not supported by the +// hardware device. +// +#define D2DERR_DISPLAY_FORMAT_NOT_SUPPORTED MAKE_D2DHR_ERR(0x009) + +// +// A call to this method is invalid. +// +#define D2DERR_INVALID_CALL MAKE_D2DHR_ERR(0x00A) + +// +// No HW rendering device is available for this operation. +// +#define D2DERR_NO_HARDWARE_DEVICE MAKE_D2DHR_ERR(0x00B) + +// +// There has been a presentation error that may be recoverable. The caller +// needs to recreate, rerender the entire frame, and reattempt present. +// +#define D2DERR_RECREATE_TARGET MAKE_D2DHR_ERR(0x00C) + +// +// Shader construction failed because it was too complex. +// +#define D2DERR_TOO_MANY_SHADER_ELEMENTS MAKE_D2DHR_ERR(0x00D) + +// +// Shader compilation failed. +// +#define D2DERR_SHADER_COMPILE_FAILED MAKE_D2DHR_ERR(0x00E) + +// +// Requested DX surface size exceeded maximum texture size. +// +#define D2DERR_MAX_TEXTURE_SIZE_EXCEEDED MAKE_D2DHR_ERR(0x00F) + +// +// The requested D2D version is not supported. +// +#define D2DERR_UNSUPPORTED_VERSION MAKE_D2DHR_ERR(0x010) + +// +// Invalid number. +// +#define D2DERR_BAD_NUMBER MAKE_D2DHR_ERR(0x0011) + +// +// Objects used together must be created from the same factory instance. +// +#define D2DERR_WRONG_FACTORY MAKE_D2DHR_ERR(0x012) + +// +// A layer resource can only be in use once at any point in time. +// +#define D2DERR_LAYER_ALREADY_IN_USE MAKE_D2DHR_ERR(0x013) + +// +// The pop call did not match the corresponding push call +// +#define D2DERR_POP_CALL_DID_NOT_MATCH_PUSH MAKE_D2DHR_ERR(0x014) + +// +// The resource was realized on the wrong render target +// +#define D2DERR_WRONG_RESOURCE_DOMAIN MAKE_D2DHR_ERR(0x015) + +// +// The push and pop calls were unbalanced +// +#define D2DERR_PUSH_POP_UNBALANCED MAKE_D2DHR_ERR(0x016) + +// +// Attempt to copy from a render target while a layer or clip rect is applied +// +#define D2DERR_RENDER_TARGET_HAS_LAYER_OR_CLIPRECT MAKE_D2DHR_ERR(0x017) + +// +// The brush types are incompatible for the call. +// +#define D2DERR_INCOMPATIBLE_BRUSH_TYPES MAKE_D2DHR_ERR(0x018) + +// +// An unknown win32 failure occurred. +// +#define D2DERR_WIN32_ERROR MAKE_D2DHR_ERR(0x019) + +// +// The render target is not compatible with GDI +// +#define D2DERR_TARGET_NOT_GDI_COMPATIBLE MAKE_D2DHR_ERR(0x01A) + +// +// A text client drawing effect object is of the wrong type +// +#define D2DERR_TEXT_EFFECT_IS_WRONG_TYPE MAKE_D2DHR_ERR(0x01B) + +// +// The application is holding a reference to the IDWriteTextRenderer interface +// after the corresponding DrawText or DrawTextLayout call has returned. The +// IDWriteTextRenderer instance will be zombied. +// +#define D2DERR_TEXT_RENDERER_NOT_RELEASED MAKE_D2DHR_ERR(0x01C) + +// +// The requested size is larger than the guaranteed supported texture size. +// +#define D2DERR_EXCEEDS_MAX_BITMAP_SIZE MAKE_D2DHR_ERR(0x01D) diff --git a/dxsdk/Include/D3D10.h b/dxsdk/Include/D3D10.h new file mode 100644 index 0000000..248999f --- /dev/null +++ b/dxsdk/Include/D3D10.h @@ -0,0 +1,6723 @@ +/*------------------------------------------------------------------------------------- + * + * Copyright (c) Microsoft Corporation + * + *-------------------------------------------------------------------------------------*/ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3d10_h__ +#define __d3d10_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D10DeviceChild_FWD_DEFINED__ +#define __ID3D10DeviceChild_FWD_DEFINED__ +typedef interface ID3D10DeviceChild ID3D10DeviceChild; +#endif /* __ID3D10DeviceChild_FWD_DEFINED__ */ + + +#ifndef __ID3D10DepthStencilState_FWD_DEFINED__ +#define __ID3D10DepthStencilState_FWD_DEFINED__ +typedef interface ID3D10DepthStencilState ID3D10DepthStencilState; +#endif /* __ID3D10DepthStencilState_FWD_DEFINED__ */ + + +#ifndef __ID3D10BlendState_FWD_DEFINED__ +#define __ID3D10BlendState_FWD_DEFINED__ +typedef interface ID3D10BlendState ID3D10BlendState; +#endif /* __ID3D10BlendState_FWD_DEFINED__ */ + + +#ifndef __ID3D10RasterizerState_FWD_DEFINED__ +#define __ID3D10RasterizerState_FWD_DEFINED__ +typedef interface ID3D10RasterizerState ID3D10RasterizerState; +#endif /* __ID3D10RasterizerState_FWD_DEFINED__ */ + + +#ifndef __ID3D10Resource_FWD_DEFINED__ +#define __ID3D10Resource_FWD_DEFINED__ +typedef interface ID3D10Resource ID3D10Resource; +#endif /* __ID3D10Resource_FWD_DEFINED__ */ + + +#ifndef __ID3D10Buffer_FWD_DEFINED__ +#define __ID3D10Buffer_FWD_DEFINED__ +typedef interface ID3D10Buffer ID3D10Buffer; +#endif /* __ID3D10Buffer_FWD_DEFINED__ */ + + +#ifndef __ID3D10Texture1D_FWD_DEFINED__ +#define __ID3D10Texture1D_FWD_DEFINED__ +typedef interface ID3D10Texture1D ID3D10Texture1D; +#endif /* __ID3D10Texture1D_FWD_DEFINED__ */ + + +#ifndef __ID3D10Texture2D_FWD_DEFINED__ +#define __ID3D10Texture2D_FWD_DEFINED__ +typedef interface ID3D10Texture2D ID3D10Texture2D; +#endif /* __ID3D10Texture2D_FWD_DEFINED__ */ + + +#ifndef __ID3D10Texture3D_FWD_DEFINED__ +#define __ID3D10Texture3D_FWD_DEFINED__ +typedef interface ID3D10Texture3D ID3D10Texture3D; +#endif /* __ID3D10Texture3D_FWD_DEFINED__ */ + + +#ifndef __ID3D10View_FWD_DEFINED__ +#define __ID3D10View_FWD_DEFINED__ +typedef interface ID3D10View ID3D10View; +#endif /* __ID3D10View_FWD_DEFINED__ */ + + +#ifndef __ID3D10ShaderResourceView_FWD_DEFINED__ +#define __ID3D10ShaderResourceView_FWD_DEFINED__ +typedef interface ID3D10ShaderResourceView ID3D10ShaderResourceView; +#endif /* __ID3D10ShaderResourceView_FWD_DEFINED__ */ + + +#ifndef __ID3D10RenderTargetView_FWD_DEFINED__ +#define __ID3D10RenderTargetView_FWD_DEFINED__ +typedef interface ID3D10RenderTargetView ID3D10RenderTargetView; +#endif /* __ID3D10RenderTargetView_FWD_DEFINED__ */ + + +#ifndef __ID3D10DepthStencilView_FWD_DEFINED__ +#define __ID3D10DepthStencilView_FWD_DEFINED__ +typedef interface ID3D10DepthStencilView ID3D10DepthStencilView; +#endif /* __ID3D10DepthStencilView_FWD_DEFINED__ */ + + +#ifndef __ID3D10VertexShader_FWD_DEFINED__ +#define __ID3D10VertexShader_FWD_DEFINED__ +typedef interface ID3D10VertexShader ID3D10VertexShader; +#endif /* __ID3D10VertexShader_FWD_DEFINED__ */ + + +#ifndef __ID3D10GeometryShader_FWD_DEFINED__ +#define __ID3D10GeometryShader_FWD_DEFINED__ +typedef interface ID3D10GeometryShader ID3D10GeometryShader; +#endif /* __ID3D10GeometryShader_FWD_DEFINED__ */ + + +#ifndef __ID3D10PixelShader_FWD_DEFINED__ +#define __ID3D10PixelShader_FWD_DEFINED__ +typedef interface ID3D10PixelShader ID3D10PixelShader; +#endif /* __ID3D10PixelShader_FWD_DEFINED__ */ + + +#ifndef __ID3D10InputLayout_FWD_DEFINED__ +#define __ID3D10InputLayout_FWD_DEFINED__ +typedef interface ID3D10InputLayout ID3D10InputLayout; +#endif /* __ID3D10InputLayout_FWD_DEFINED__ */ + + +#ifndef __ID3D10SamplerState_FWD_DEFINED__ +#define __ID3D10SamplerState_FWD_DEFINED__ +typedef interface ID3D10SamplerState ID3D10SamplerState; +#endif /* __ID3D10SamplerState_FWD_DEFINED__ */ + + +#ifndef __ID3D10Asynchronous_FWD_DEFINED__ +#define __ID3D10Asynchronous_FWD_DEFINED__ +typedef interface ID3D10Asynchronous ID3D10Asynchronous; +#endif /* __ID3D10Asynchronous_FWD_DEFINED__ */ + + +#ifndef __ID3D10Query_FWD_DEFINED__ +#define __ID3D10Query_FWD_DEFINED__ +typedef interface ID3D10Query ID3D10Query; +#endif /* __ID3D10Query_FWD_DEFINED__ */ + + +#ifndef __ID3D10Predicate_FWD_DEFINED__ +#define __ID3D10Predicate_FWD_DEFINED__ +typedef interface ID3D10Predicate ID3D10Predicate; +#endif /* __ID3D10Predicate_FWD_DEFINED__ */ + + +#ifndef __ID3D10Counter_FWD_DEFINED__ +#define __ID3D10Counter_FWD_DEFINED__ +typedef interface ID3D10Counter ID3D10Counter; +#endif /* __ID3D10Counter_FWD_DEFINED__ */ + + +#ifndef __ID3D10Device_FWD_DEFINED__ +#define __ID3D10Device_FWD_DEFINED__ +typedef interface ID3D10Device ID3D10Device; +#endif /* __ID3D10Device_FWD_DEFINED__ */ + + +#ifndef __ID3D10Multithread_FWD_DEFINED__ +#define __ID3D10Multithread_FWD_DEFINED__ +typedef interface ID3D10Multithread ID3D10Multithread; +#endif /* __ID3D10Multithread_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "dxgi.h" +#include "d3dcommon.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3d10_0000_0000 */ +/* [local] */ + +#ifndef _D3D10_CONSTANTS +#define _D3D10_CONSTANTS +#define D3D10_16BIT_INDEX_STRIP_CUT_VALUE ( 0xffff ) + +#define D3D10_32BIT_INDEX_STRIP_CUT_VALUE ( 0xffffffff ) + +#define D3D10_8BIT_INDEX_STRIP_CUT_VALUE ( 0xff ) + +#define D3D10_ARRAY_AXIS_ADDRESS_RANGE_BIT_COUNT ( 9 ) + +#define D3D10_CLIP_OR_CULL_DISTANCE_COUNT ( 8 ) + +#define D3D10_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT ( 2 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ( 14 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_COMPONENTS ( 4 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT ( 15 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT ( 15 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_COMMONSHADER_FLOWCONTROL_NESTING_LIMIT ( 64 ) + +#define D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COUNT ( 1 ) + +#define D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_COMMONSHADER_IMMEDIATE_VALUE_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_COMPONENTS ( 1 ) + +#define D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT ( 128 ) + +#define D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_READS_PER_INST ( 1 ) + +#define D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT ( 128 ) + +#define D3D10_COMMONSHADER_SAMPLER_REGISTER_COMPONENTS ( 1 ) + +#define D3D10_COMMONSHADER_SAMPLER_REGISTER_COUNT ( 16 ) + +#define D3D10_COMMONSHADER_SAMPLER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D10_COMMONSHADER_SAMPLER_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT ( 16 ) + +#define D3D10_COMMONSHADER_SUBROUTINE_NESTING_LIMIT ( 32 ) + +#define D3D10_COMMONSHADER_TEMP_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_COMMONSHADER_TEMP_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_COMMONSHADER_TEMP_REGISTER_COUNT ( 4096 ) + +#define D3D10_COMMONSHADER_TEMP_REGISTER_READS_PER_INST ( 3 ) + +#define D3D10_COMMONSHADER_TEMP_REGISTER_READ_PORTS ( 3 ) + +#define D3D10_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MAX ( 10 ) + +#define D3D10_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MIN ( -10 ) + +#define D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE ( -8 ) + +#define D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE ( 7 ) + +#define D3D10_DEFAULT_BLEND_FACTOR_ALPHA ( 1.0f ) +#define D3D10_DEFAULT_BLEND_FACTOR_BLUE ( 1.0f ) +#define D3D10_DEFAULT_BLEND_FACTOR_GREEN ( 1.0f ) +#define D3D10_DEFAULT_BLEND_FACTOR_RED ( 1.0f ) +#define D3D10_DEFAULT_BORDER_COLOR_COMPONENT ( 0.0f ) +#define D3D10_DEFAULT_DEPTH_BIAS ( 0 ) + +#define D3D10_DEFAULT_DEPTH_BIAS_CLAMP ( 0.0f ) +#define D3D10_DEFAULT_MAX_ANISOTROPY ( 16.0f ) +#define D3D10_DEFAULT_MIP_LOD_BIAS ( 0.0f ) +#define D3D10_DEFAULT_RENDER_TARGET_ARRAY_INDEX ( 0 ) + +#define D3D10_DEFAULT_SAMPLE_MASK ( 0xffffffff ) + +#define D3D10_DEFAULT_SCISSOR_ENDX ( 0 ) + +#define D3D10_DEFAULT_SCISSOR_ENDY ( 0 ) + +#define D3D10_DEFAULT_SCISSOR_STARTX ( 0 ) + +#define D3D10_DEFAULT_SCISSOR_STARTY ( 0 ) + +#define D3D10_DEFAULT_SLOPE_SCALED_DEPTH_BIAS ( 0.0f ) +#define D3D10_DEFAULT_STENCIL_READ_MASK ( 0xff ) + +#define D3D10_DEFAULT_STENCIL_REFERENCE ( 0 ) + +#define D3D10_DEFAULT_STENCIL_WRITE_MASK ( 0xff ) + +#define D3D10_DEFAULT_VIEWPORT_AND_SCISSORRECT_INDEX ( 0 ) + +#define D3D10_DEFAULT_VIEWPORT_HEIGHT ( 0 ) + +#define D3D10_DEFAULT_VIEWPORT_MAX_DEPTH ( 0.0f ) +#define D3D10_DEFAULT_VIEWPORT_MIN_DEPTH ( 0.0f ) +#define D3D10_DEFAULT_VIEWPORT_TOPLEFTX ( 0 ) + +#define D3D10_DEFAULT_VIEWPORT_TOPLEFTY ( 0 ) + +#define D3D10_DEFAULT_VIEWPORT_WIDTH ( 0 ) + +#define D3D10_FLOAT16_FUSED_TOLERANCE_IN_ULP ( 0.6 ) +#define D3D10_FLOAT32_MAX ( 3.402823466e+38f ) +#define D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ( 0.6f ) +#define D3D10_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR ( 2.4f ) +#define D3D10_FLOAT_TO_SRGB_EXPONENT_NUMERATOR ( 1.0f ) +#define D3D10_FLOAT_TO_SRGB_OFFSET ( 0.055f ) +#define D3D10_FLOAT_TO_SRGB_SCALE_1 ( 12.92f ) +#define D3D10_FLOAT_TO_SRGB_SCALE_2 ( 1.055f ) +#define D3D10_FLOAT_TO_SRGB_THRESHOLD ( 0.0031308f ) +#define D3D10_FTOI_INSTRUCTION_MAX_INPUT ( 2147483647.999f ) +#define D3D10_FTOI_INSTRUCTION_MIN_INPUT ( -2147483648.999f ) +#define D3D10_FTOU_INSTRUCTION_MAX_INPUT ( 4294967295.999f ) +#define D3D10_FTOU_INSTRUCTION_MIN_INPUT ( 0.0f ) +#define D3D10_GS_INPUT_PRIM_CONST_REGISTER_COMPONENTS ( 1 ) + +#define D3D10_GS_INPUT_PRIM_CONST_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_GS_INPUT_PRIM_CONST_REGISTER_COUNT ( 1 ) + +#define D3D10_GS_INPUT_PRIM_CONST_REGISTER_READS_PER_INST ( 2 ) + +#define D3D10_GS_INPUT_PRIM_CONST_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_GS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_GS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_GS_INPUT_REGISTER_COUNT ( 16 ) + +#define D3D10_GS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D10_GS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_GS_INPUT_REGISTER_VERTICES ( 6 ) + +#define D3D10_GS_OUTPUT_ELEMENTS ( 32 ) + +#define D3D10_GS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_GS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_GS_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D10_IA_DEFAULT_INDEX_BUFFER_OFFSET_IN_BYTES ( 0 ) + +#define D3D10_IA_DEFAULT_PRIMITIVE_TOPOLOGY ( 0 ) + +#define D3D10_IA_DEFAULT_VERTEX_BUFFER_OFFSET_IN_BYTES ( 0 ) + +#define D3D10_IA_INDEX_INPUT_RESOURCE_SLOT_COUNT ( 1 ) + +#define D3D10_IA_INSTANCE_ID_BIT_COUNT ( 32 ) + +#define D3D10_IA_INTEGER_ARITHMETIC_BIT_COUNT ( 32 ) + +#define D3D10_IA_PRIMITIVE_ID_BIT_COUNT ( 32 ) + +#define D3D10_IA_VERTEX_ID_BIT_COUNT ( 32 ) + +#define D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT ( 16 ) + +#define D3D10_IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS ( 64 ) + +#define D3D10_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ( 16 ) + +#define D3D10_INTEGER_DIVIDE_BY_ZERO_QUOTIENT ( 0xffffffff ) + +#define D3D10_INTEGER_DIVIDE_BY_ZERO_REMAINDER ( 0xffffffff ) + +#define D3D10_LINEAR_GAMMA ( 1.0f ) +#define D3D10_MAX_BORDER_COLOR_COMPONENT ( 1.0f ) +#define D3D10_MAX_DEPTH ( 1.0f ) +#define D3D10_MAX_MAXANISOTROPY ( 16 ) + +#define D3D10_MAX_MULTISAMPLE_SAMPLE_COUNT ( 32 ) + +#define D3D10_MAX_POSITION_VALUE ( 3.402823466e+34f ) +#define D3D10_MAX_TEXTURE_DIMENSION_2_TO_EXP ( 17 ) + +#define D3D10_MIN_BORDER_COLOR_COMPONENT ( 0.0f ) +#define D3D10_MIN_DEPTH ( 0.0f ) +#define D3D10_MIN_MAXANISOTROPY ( 0 ) + +#define D3D10_MIP_LOD_BIAS_MAX ( 15.99f ) +#define D3D10_MIP_LOD_BIAS_MIN ( -16.0f ) +#define D3D10_MIP_LOD_FRACTIONAL_BIT_COUNT ( 6 ) + +#define D3D10_MIP_LOD_RANGE_BIT_COUNT ( 8 ) + +#define D3D10_MULTISAMPLE_ANTIALIAS_LINE_WIDTH ( 1.4f ) +#define D3D10_NONSAMPLE_FETCH_OUT_OF_RANGE_ACCESS_RESULT ( 0 ) + +#define D3D10_PIXEL_ADDRESS_RANGE_BIT_COUNT ( 13 ) + +#define D3D10_PRE_SCISSOR_PIXEL_ADDRESS_RANGE_BIT_COUNT ( 15 ) + +#define D3D10_PS_FRONTFACING_DEFAULT_VALUE ( 0xffffffff ) + +#define D3D10_PS_FRONTFACING_FALSE_VALUE ( 0 ) + +#define D3D10_PS_FRONTFACING_TRUE_VALUE ( 0xffffffff ) + +#define D3D10_PS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_PS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_PS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D10_PS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D10_PS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_PS_LEGACY_PIXEL_CENTER_FRACTIONAL_COMPONENT ( 0.0f ) +#define D3D10_PS_OUTPUT_DEPTH_REGISTER_COMPONENTS ( 1 ) + +#define D3D10_PS_OUTPUT_DEPTH_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_PS_OUTPUT_DEPTH_REGISTER_COUNT ( 1 ) + +#define D3D10_PS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_PS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_PS_OUTPUT_REGISTER_COUNT ( 8 ) + +#define D3D10_PS_PIXEL_CENTER_FRACTIONAL_COMPONENT ( 0.5f ) +#define D3D10_REQ_BLEND_OBJECT_COUNT_PER_CONTEXT ( 4096 ) + +#define D3D10_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP ( 27 ) + +#define D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT ( 4096 ) + +#define D3D10_REQ_DEPTH_STENCIL_OBJECT_COUNT_PER_CONTEXT ( 4096 ) + +#define D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP ( 32 ) + +#define D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP ( 32 ) + +#define D3D10_REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION ( 8192 ) + +#define D3D10_REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT ( 1024 ) + +#define D3D10_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT ( 4096 ) + +#define D3D10_REQ_MAXANISOTROPY ( 16 ) + +#define D3D10_REQ_MIP_LEVELS ( 14 ) + +#define D3D10_REQ_MULTI_ELEMENT_STRUCTURE_SIZE_IN_BYTES ( 2048 ) + +#define D3D10_REQ_RASTERIZER_OBJECT_COUNT_PER_CONTEXT ( 4096 ) + +#define D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH ( 8192 ) + +#define D3D10_REQ_RESOURCE_SIZE_IN_MEGABYTES ( 128 ) + +#define D3D10_REQ_RESOURCE_VIEW_COUNT_PER_CONTEXT_2_TO_EXP ( 20 ) + +#define D3D10_REQ_SAMPLER_OBJECT_COUNT_PER_CONTEXT ( 4096 ) + +#define D3D10_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION ( 512 ) + +#define D3D10_REQ_TEXTURE1D_U_DIMENSION ( 8192 ) + +#define D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION ( 512 ) + +#define D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION ( 8192 ) + +#define D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION ( 2048 ) + +#define D3D10_REQ_TEXTURECUBE_DIMENSION ( 8192 ) + +#define D3D10_RESINFO_INSTRUCTION_MISSING_COMPONENT_RETVAL ( 0 ) + +#define D3D10_SHADER_MAJOR_VERSION ( 4 ) + +#define D3D10_SHADER_MINOR_VERSION ( 0 ) + +#define D3D10_SHIFT_INSTRUCTION_PAD_VALUE ( 0 ) + +#define D3D10_SHIFT_INSTRUCTION_SHIFT_VALUE_BIT_COUNT ( 5 ) + +#define D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT ( 8 ) + +#define D3D10_SO_BUFFER_MAX_STRIDE_IN_BYTES ( 2048 ) + +#define D3D10_SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES ( 256 ) + +#define D3D10_SO_BUFFER_SLOT_COUNT ( 4 ) + +#define D3D10_SO_DDI_REGISTER_INDEX_DENOTING_GAP ( 0xffffffff ) + +#define D3D10_SO_MULTIPLE_BUFFER_ELEMENTS_PER_BUFFER ( 1 ) + +#define D3D10_SO_SINGLE_BUFFER_COMPONENT_LIMIT ( 64 ) + +#define D3D10_SRGB_GAMMA ( 2.2f ) +#define D3D10_SRGB_TO_FLOAT_DENOMINATOR_1 ( 12.92f ) +#define D3D10_SRGB_TO_FLOAT_DENOMINATOR_2 ( 1.055f ) +#define D3D10_SRGB_TO_FLOAT_EXPONENT ( 2.4f ) +#define D3D10_SRGB_TO_FLOAT_OFFSET ( 0.055f ) +#define D3D10_SRGB_TO_FLOAT_THRESHOLD ( 0.04045f ) +#define D3D10_SRGB_TO_FLOAT_TOLERANCE_IN_ULP ( 0.5f ) +#define D3D10_STANDARD_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_STANDARD_COMPONENT_BIT_COUNT_DOUBLED ( 64 ) + +#define D3D10_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE ( 4 ) + +#define D3D10_STANDARD_PIXEL_COMPONENT_COUNT ( 128 ) + +#define D3D10_STANDARD_PIXEL_ELEMENT_COUNT ( 32 ) + +#define D3D10_STANDARD_VECTOR_SIZE ( 4 ) + +#define D3D10_STANDARD_VERTEX_ELEMENT_COUNT ( 16 ) + +#define D3D10_STANDARD_VERTEX_TOTAL_COMPONENT_COUNT ( 64 ) + +#define D3D10_SUBPIXEL_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D10_SUBTEXEL_FRACTIONAL_BIT_COUNT ( 6 ) + +#define D3D10_TEXEL_ADDRESS_RANGE_BIT_COUNT ( 18 ) + +#define D3D10_UNBOUND_MEMORY_ACCESS_RESULT ( 0 ) + +#define D3D10_VIEWPORT_AND_SCISSORRECT_MAX_INDEX ( 15 ) + +#define D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE ( 16 ) + +#define D3D10_VIEWPORT_BOUNDS_MAX ( 16383 ) + +#define D3D10_VIEWPORT_BOUNDS_MIN ( -16384 ) + +#define D3D10_VS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_VS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_VS_INPUT_REGISTER_COUNT ( 16 ) + +#define D3D10_VS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D10_VS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D10_VS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D10_VS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_VS_OUTPUT_REGISTER_COUNT ( 16 ) + +#define D3D10_WHQL_CONTEXT_COUNT_FOR_RESOURCE_LIMIT ( 10 ) + +#define D3D10_WHQL_DRAWINDEXED_INDEX_COUNT_2_TO_EXP ( 25 ) + +#define D3D10_WHQL_DRAW_VERTEX_COUNT_2_TO_EXP ( 25 ) + +#define D3D_MAJOR_VERSION ( 10 ) + +#define D3D_MINOR_VERSION ( 0 ) + +#define D3D_SPEC_DATE_DAY ( 8 ) + +#define D3D_SPEC_DATE_MONTH ( 8 ) + +#define D3D_SPEC_DATE_YEAR ( 2006 ) + +#define D3D_SPEC_VERSION ( 1.050005 ) +#endif +#if !defined( __d3d10_1_h__ ) && !(D3D10_HEADER_MINOR_VERSION >= 1) +#define D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT D3D10_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT +#define D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT D3D10_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT +#endif +#define _FACD3D10 ( 0x879 ) + +#define _FACD3D10DEBUG ( ( _FACD3D10 + 1 ) ) + +#define MAKE_D3D10_HRESULT( code ) MAKE_HRESULT( 1, _FACD3D10, code ) +#define MAKE_D3D10_STATUS( code ) MAKE_HRESULT( 0, _FACD3D10, code ) +#define D3D10_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS MAKE_D3D10_HRESULT(1) +#define D3D10_ERROR_FILE_NOT_FOUND MAKE_D3D10_HRESULT(2) +#if __SAL_H_FULL_VER < 140050727 +#undef __in_range +#undef __in_xcount_opt +#define __in_range(x, y) +#define __in_xcount_opt(x) +#endif +typedef +enum D3D10_INPUT_CLASSIFICATION + { D3D10_INPUT_PER_VERTEX_DATA = 0, + D3D10_INPUT_PER_INSTANCE_DATA = 1 + } D3D10_INPUT_CLASSIFICATION; + +#define D3D10_APPEND_ALIGNED_ELEMENT ( 0xffffffff ) + +typedef struct D3D10_INPUT_ELEMENT_DESC + { + LPCSTR SemanticName; + UINT SemanticIndex; + DXGI_FORMAT Format; + UINT InputSlot; + UINT AlignedByteOffset; + D3D10_INPUT_CLASSIFICATION InputSlotClass; + UINT InstanceDataStepRate; + } D3D10_INPUT_ELEMENT_DESC; + +typedef +enum D3D10_FILL_MODE + { D3D10_FILL_WIREFRAME = 2, + D3D10_FILL_SOLID = 3 + } D3D10_FILL_MODE; + +typedef D3D_PRIMITIVE_TOPOLOGY D3D10_PRIMITIVE_TOPOLOGY; + +typedef D3D_PRIMITIVE D3D10_PRIMITIVE; + +typedef +enum D3D10_CULL_MODE + { D3D10_CULL_NONE = 1, + D3D10_CULL_FRONT = 2, + D3D10_CULL_BACK = 3 + } D3D10_CULL_MODE; + +typedef struct D3D10_SO_DECLARATION_ENTRY + { + LPCSTR SemanticName; + UINT SemanticIndex; + BYTE StartComponent; + BYTE ComponentCount; + BYTE OutputSlot; + } D3D10_SO_DECLARATION_ENTRY; + +typedef struct D3D10_VIEWPORT + { + INT TopLeftX; + INT TopLeftY; + UINT Width; + UINT Height; + FLOAT MinDepth; + FLOAT MaxDepth; + } D3D10_VIEWPORT; + +typedef +enum D3D10_RESOURCE_DIMENSION + { D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D10_RESOURCE_DIMENSION_BUFFER = 1, + D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4 + } D3D10_RESOURCE_DIMENSION; + +typedef D3D_SRV_DIMENSION D3D10_SRV_DIMENSION; + +typedef +enum D3D10_DSV_DIMENSION + { D3D10_DSV_DIMENSION_UNKNOWN = 0, + D3D10_DSV_DIMENSION_TEXTURE1D = 1, + D3D10_DSV_DIMENSION_TEXTURE1DARRAY = 2, + D3D10_DSV_DIMENSION_TEXTURE2D = 3, + D3D10_DSV_DIMENSION_TEXTURE2DARRAY = 4, + D3D10_DSV_DIMENSION_TEXTURE2DMS = 5, + D3D10_DSV_DIMENSION_TEXTURE2DMSARRAY = 6 + } D3D10_DSV_DIMENSION; + +typedef +enum D3D10_RTV_DIMENSION + { D3D10_RTV_DIMENSION_UNKNOWN = 0, + D3D10_RTV_DIMENSION_BUFFER = 1, + D3D10_RTV_DIMENSION_TEXTURE1D = 2, + D3D10_RTV_DIMENSION_TEXTURE1DARRAY = 3, + D3D10_RTV_DIMENSION_TEXTURE2D = 4, + D3D10_RTV_DIMENSION_TEXTURE2DARRAY = 5, + D3D10_RTV_DIMENSION_TEXTURE2DMS = 6, + D3D10_RTV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D10_RTV_DIMENSION_TEXTURE3D = 8 + } D3D10_RTV_DIMENSION; + +typedef +enum D3D10_USAGE + { D3D10_USAGE_DEFAULT = 0, + D3D10_USAGE_IMMUTABLE = 1, + D3D10_USAGE_DYNAMIC = 2, + D3D10_USAGE_STAGING = 3 + } D3D10_USAGE; + +typedef +enum D3D10_BIND_FLAG + { D3D10_BIND_VERTEX_BUFFER = 0x1L, + D3D10_BIND_INDEX_BUFFER = 0x2L, + D3D10_BIND_CONSTANT_BUFFER = 0x4L, + D3D10_BIND_SHADER_RESOURCE = 0x8L, + D3D10_BIND_STREAM_OUTPUT = 0x10L, + D3D10_BIND_RENDER_TARGET = 0x20L, + D3D10_BIND_DEPTH_STENCIL = 0x40L + } D3D10_BIND_FLAG; + +typedef +enum D3D10_CPU_ACCESS_FLAG + { D3D10_CPU_ACCESS_WRITE = 0x10000L, + D3D10_CPU_ACCESS_READ = 0x20000L + } D3D10_CPU_ACCESS_FLAG; + +typedef +enum D3D10_RESOURCE_MISC_FLAG + { D3D10_RESOURCE_MISC_GENERATE_MIPS = 0x1L, + D3D10_RESOURCE_MISC_SHARED = 0x2L, + D3D10_RESOURCE_MISC_TEXTURECUBE = 0x4L, + D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x10L, + D3D10_RESOURCE_MISC_GDI_COMPATIBLE = 0x20L + } D3D10_RESOURCE_MISC_FLAG; + +typedef +enum D3D10_MAP + { D3D10_MAP_READ = 1, + D3D10_MAP_WRITE = 2, + D3D10_MAP_READ_WRITE = 3, + D3D10_MAP_WRITE_DISCARD = 4, + D3D10_MAP_WRITE_NO_OVERWRITE = 5 + } D3D10_MAP; + +typedef +enum D3D10_MAP_FLAG + { D3D10_MAP_FLAG_DO_NOT_WAIT = 0x100000L + } D3D10_MAP_FLAG; + +typedef +enum D3D10_RAISE_FLAG + { D3D10_RAISE_FLAG_DRIVER_INTERNAL_ERROR = 0x1L + } D3D10_RAISE_FLAG; + +typedef +enum D3D10_CLEAR_FLAG + { D3D10_CLEAR_DEPTH = 0x1L, + D3D10_CLEAR_STENCIL = 0x2L + } D3D10_CLEAR_FLAG; + +typedef RECT D3D10_RECT; + +typedef struct D3D10_BOX + { + UINT left; + UINT top; + UINT front; + UINT right; + UINT bottom; + UINT back; + } D3D10_BOX; + + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D10DeviceChild_INTERFACE_DEFINED__ +#define __ID3D10DeviceChild_INTERFACE_DEFINED__ + +/* interface ID3D10DeviceChild */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10DeviceChild; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C00-342C-4106-A19F-4F2704F689F0") + ID3D10DeviceChild : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE GetDevice( + /* [annotation] */ + __out ID3D10Device **ppDevice) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10DeviceChildVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10DeviceChild * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10DeviceChild * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10DeviceChild * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10DeviceChild * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10DeviceChild * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10DeviceChild * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10DeviceChild * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D10DeviceChildVtbl; + + interface ID3D10DeviceChild + { + CONST_VTBL struct ID3D10DeviceChildVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10DeviceChild_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10DeviceChild_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10DeviceChild_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10DeviceChild_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10DeviceChild_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10DeviceChild_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10DeviceChild_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10DeviceChild_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0001 */ +/* [local] */ + +typedef +enum D3D10_COMPARISON_FUNC + { D3D10_COMPARISON_NEVER = 1, + D3D10_COMPARISON_LESS = 2, + D3D10_COMPARISON_EQUAL = 3, + D3D10_COMPARISON_LESS_EQUAL = 4, + D3D10_COMPARISON_GREATER = 5, + D3D10_COMPARISON_NOT_EQUAL = 6, + D3D10_COMPARISON_GREATER_EQUAL = 7, + D3D10_COMPARISON_ALWAYS = 8 + } D3D10_COMPARISON_FUNC; + +typedef +enum D3D10_DEPTH_WRITE_MASK + { D3D10_DEPTH_WRITE_MASK_ZERO = 0, + D3D10_DEPTH_WRITE_MASK_ALL = 1 + } D3D10_DEPTH_WRITE_MASK; + +typedef +enum D3D10_STENCIL_OP + { D3D10_STENCIL_OP_KEEP = 1, + D3D10_STENCIL_OP_ZERO = 2, + D3D10_STENCIL_OP_REPLACE = 3, + D3D10_STENCIL_OP_INCR_SAT = 4, + D3D10_STENCIL_OP_DECR_SAT = 5, + D3D10_STENCIL_OP_INVERT = 6, + D3D10_STENCIL_OP_INCR = 7, + D3D10_STENCIL_OP_DECR = 8 + } D3D10_STENCIL_OP; + +typedef struct D3D10_DEPTH_STENCILOP_DESC + { + D3D10_STENCIL_OP StencilFailOp; + D3D10_STENCIL_OP StencilDepthFailOp; + D3D10_STENCIL_OP StencilPassOp; + D3D10_COMPARISON_FUNC StencilFunc; + } D3D10_DEPTH_STENCILOP_DESC; + +typedef struct D3D10_DEPTH_STENCIL_DESC + { + BOOL DepthEnable; + D3D10_DEPTH_WRITE_MASK DepthWriteMask; + D3D10_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D10_DEPTH_STENCILOP_DESC FrontFace; + D3D10_DEPTH_STENCILOP_DESC BackFace; + } D3D10_DEPTH_STENCIL_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0001_v0_0_s_ifspec; + +#ifndef __ID3D10DepthStencilState_INTERFACE_DEFINED__ +#define __ID3D10DepthStencilState_INTERFACE_DEFINED__ + +/* interface ID3D10DepthStencilState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10DepthStencilState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2B4B1CC8-A4AD-41f8-8322-CA86FC3EC675") + ID3D10DepthStencilState : public ID3D10DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_DEPTH_STENCIL_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10DepthStencilStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10DepthStencilState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10DepthStencilState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10DepthStencilState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10DepthStencilState * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10DepthStencilState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10DepthStencilState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10DepthStencilState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10DepthStencilState * This, + /* [annotation] */ + __out D3D10_DEPTH_STENCIL_DESC *pDesc); + + END_INTERFACE + } ID3D10DepthStencilStateVtbl; + + interface ID3D10DepthStencilState + { + CONST_VTBL struct ID3D10DepthStencilStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10DepthStencilState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10DepthStencilState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10DepthStencilState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10DepthStencilState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10DepthStencilState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10DepthStencilState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10DepthStencilState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10DepthStencilState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10DepthStencilState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0002 */ +/* [local] */ + +typedef +enum D3D10_BLEND + { D3D10_BLEND_ZERO = 1, + D3D10_BLEND_ONE = 2, + D3D10_BLEND_SRC_COLOR = 3, + D3D10_BLEND_INV_SRC_COLOR = 4, + D3D10_BLEND_SRC_ALPHA = 5, + D3D10_BLEND_INV_SRC_ALPHA = 6, + D3D10_BLEND_DEST_ALPHA = 7, + D3D10_BLEND_INV_DEST_ALPHA = 8, + D3D10_BLEND_DEST_COLOR = 9, + D3D10_BLEND_INV_DEST_COLOR = 10, + D3D10_BLEND_SRC_ALPHA_SAT = 11, + D3D10_BLEND_BLEND_FACTOR = 14, + D3D10_BLEND_INV_BLEND_FACTOR = 15, + D3D10_BLEND_SRC1_COLOR = 16, + D3D10_BLEND_INV_SRC1_COLOR = 17, + D3D10_BLEND_SRC1_ALPHA = 18, + D3D10_BLEND_INV_SRC1_ALPHA = 19 + } D3D10_BLEND; + +typedef +enum D3D10_BLEND_OP + { D3D10_BLEND_OP_ADD = 1, + D3D10_BLEND_OP_SUBTRACT = 2, + D3D10_BLEND_OP_REV_SUBTRACT = 3, + D3D10_BLEND_OP_MIN = 4, + D3D10_BLEND_OP_MAX = 5 + } D3D10_BLEND_OP; + +typedef +enum D3D10_COLOR_WRITE_ENABLE + { D3D10_COLOR_WRITE_ENABLE_RED = 1, + D3D10_COLOR_WRITE_ENABLE_GREEN = 2, + D3D10_COLOR_WRITE_ENABLE_BLUE = 4, + D3D10_COLOR_WRITE_ENABLE_ALPHA = 8, + D3D10_COLOR_WRITE_ENABLE_ALL = ( ( ( D3D10_COLOR_WRITE_ENABLE_RED | D3D10_COLOR_WRITE_ENABLE_GREEN ) | D3D10_COLOR_WRITE_ENABLE_BLUE ) | D3D10_COLOR_WRITE_ENABLE_ALPHA ) + } D3D10_COLOR_WRITE_ENABLE; + +typedef struct D3D10_BLEND_DESC + { + BOOL AlphaToCoverageEnable; + BOOL BlendEnable[ 8 ]; + D3D10_BLEND SrcBlend; + D3D10_BLEND DestBlend; + D3D10_BLEND_OP BlendOp; + D3D10_BLEND SrcBlendAlpha; + D3D10_BLEND DestBlendAlpha; + D3D10_BLEND_OP BlendOpAlpha; + UINT8 RenderTargetWriteMask[ 8 ]; + } D3D10_BLEND_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0002_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0002_v0_0_s_ifspec; + +#ifndef __ID3D10BlendState_INTERFACE_DEFINED__ +#define __ID3D10BlendState_INTERFACE_DEFINED__ + +/* interface ID3D10BlendState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10BlendState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("EDAD8D19-8A35-4d6d-8566-2EA276CDE161") + ID3D10BlendState : public ID3D10DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_BLEND_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10BlendStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10BlendState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10BlendState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10BlendState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10BlendState * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10BlendState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10BlendState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10BlendState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10BlendState * This, + /* [annotation] */ + __out D3D10_BLEND_DESC *pDesc); + + END_INTERFACE + } ID3D10BlendStateVtbl; + + interface ID3D10BlendState + { + CONST_VTBL struct ID3D10BlendStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10BlendState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10BlendState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10BlendState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10BlendState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10BlendState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10BlendState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10BlendState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10BlendState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10BlendState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0003 */ +/* [local] */ + +typedef struct D3D10_RASTERIZER_DESC + { + D3D10_FILL_MODE FillMode; + D3D10_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + INT DepthBias; + FLOAT DepthBiasClamp; + FLOAT SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL ScissorEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; + } D3D10_RASTERIZER_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0003_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0003_v0_0_s_ifspec; + +#ifndef __ID3D10RasterizerState_INTERFACE_DEFINED__ +#define __ID3D10RasterizerState_INTERFACE_DEFINED__ + +/* interface ID3D10RasterizerState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10RasterizerState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A2A07292-89AF-4345-BE2E-C53D9FBB6E9F") + ID3D10RasterizerState : public ID3D10DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_RASTERIZER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10RasterizerStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10RasterizerState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10RasterizerState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10RasterizerState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10RasterizerState * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10RasterizerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10RasterizerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10RasterizerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10RasterizerState * This, + /* [annotation] */ + __out D3D10_RASTERIZER_DESC *pDesc); + + END_INTERFACE + } ID3D10RasterizerStateVtbl; + + interface ID3D10RasterizerState + { + CONST_VTBL struct ID3D10RasterizerStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10RasterizerState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10RasterizerState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10RasterizerState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10RasterizerState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10RasterizerState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10RasterizerState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10RasterizerState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10RasterizerState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10RasterizerState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0004 */ +/* [local] */ + +#if !defined( D3D10_NO_HELPERS ) && defined( __cplusplus ) +inline UINT D3D10CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT MipLevels ) +{ return MipSlice + ArraySlice * MipLevels; } +#endif +typedef struct D3D10_SUBRESOURCE_DATA + { + const void *pSysMem; + UINT SysMemPitch; + UINT SysMemSlicePitch; + } D3D10_SUBRESOURCE_DATA; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0004_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0004_v0_0_s_ifspec; + +#ifndef __ID3D10Resource_INTERFACE_DEFINED__ +#define __ID3D10Resource_INTERFACE_DEFINED__ + +/* interface ID3D10Resource */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Resource; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C01-342C-4106-A19F-4F2704F689F0") + ID3D10Resource : public ID3D10DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetType( + /* [annotation] */ + __out D3D10_RESOURCE_DIMENSION *rType) = 0; + + virtual void STDMETHODCALLTYPE SetEvictionPriority( + /* [annotation] */ + __in UINT EvictionPriority) = 0; + + virtual UINT STDMETHODCALLTYPE GetEvictionPriority( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10ResourceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Resource * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Resource * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Resource * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Resource * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Resource * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Resource * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Resource * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D10Resource * This, + /* [annotation] */ + __out D3D10_RESOURCE_DIMENSION *rType); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D10Resource * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D10Resource * This); + + END_INTERFACE + } ID3D10ResourceVtbl; + + interface ID3D10Resource + { + CONST_VTBL struct ID3D10ResourceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Resource_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Resource_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Resource_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Resource_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Resource_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Resource_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Resource_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Resource_GetType(This,rType) \ + ( (This)->lpVtbl -> GetType(This,rType) ) + +#define ID3D10Resource_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D10Resource_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Resource_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0005 */ +/* [local] */ + +typedef struct D3D10_BUFFER_DESC + { + UINT ByteWidth; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + } D3D10_BUFFER_DESC; + +#if !defined( D3D10_NO_HELPERS ) && defined( __cplusplus ) +struct CD3D10_BUFFER_DESC : public D3D10_BUFFER_DESC +{ + CD3D10_BUFFER_DESC() + {} + explicit CD3D10_BUFFER_DESC( const D3D10_BUFFER_DESC& o ) : + D3D10_BUFFER_DESC( o ) + {} + explicit CD3D10_BUFFER_DESC( + UINT byteWidth, + UINT bindFlags, + D3D10_USAGE usage = D3D10_USAGE_DEFAULT, + UINT cpuaccessFlags = 0, + UINT miscFlags = 0 ) + { + ByteWidth = byteWidth; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags ; + MiscFlags = miscFlags; + } + ~CD3D10_BUFFER_DESC() {} + operator const D3D10_BUFFER_DESC&() const { return *this; } +}; +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0005_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0005_v0_0_s_ifspec; + +#ifndef __ID3D10Buffer_INTERFACE_DEFINED__ +#define __ID3D10Buffer_INTERFACE_DEFINED__ + +/* interface ID3D10Buffer */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Buffer; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C02-342C-4106-A19F-4F2704F689F0") + ID3D10Buffer : public ID3D10Resource + { + public: + virtual HRESULT STDMETHODCALLTYPE Map( + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out void **ppData) = 0; + + virtual void STDMETHODCALLTYPE Unmap( void) = 0; + + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_BUFFER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10BufferVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Buffer * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Buffer * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Buffer * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Buffer * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Buffer * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Buffer * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Buffer * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D10Buffer * This, + /* [annotation] */ + __out D3D10_RESOURCE_DIMENSION *rType); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D10Buffer * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D10Buffer * This); + + HRESULT ( STDMETHODCALLTYPE *Map )( + ID3D10Buffer * This, + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out void **ppData); + + void ( STDMETHODCALLTYPE *Unmap )( + ID3D10Buffer * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10Buffer * This, + /* [annotation] */ + __out D3D10_BUFFER_DESC *pDesc); + + END_INTERFACE + } ID3D10BufferVtbl; + + interface ID3D10Buffer + { + CONST_VTBL struct ID3D10BufferVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Buffer_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Buffer_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Buffer_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Buffer_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Buffer_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Buffer_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Buffer_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Buffer_GetType(This,rType) \ + ( (This)->lpVtbl -> GetType(This,rType) ) + +#define ID3D10Buffer_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D10Buffer_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D10Buffer_Map(This,MapType,MapFlags,ppData) \ + ( (This)->lpVtbl -> Map(This,MapType,MapFlags,ppData) ) + +#define ID3D10Buffer_Unmap(This) \ + ( (This)->lpVtbl -> Unmap(This) ) + +#define ID3D10Buffer_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Buffer_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0006 */ +/* [local] */ + +typedef struct D3D10_TEXTURE1D_DESC + { + UINT Width; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + } D3D10_TEXTURE1D_DESC; + +#if !defined( D3D10_NO_HELPERS ) && defined( __cplusplus ) +struct CD3D10_TEXTURE1D_DESC : public D3D10_TEXTURE1D_DESC +{ + CD3D10_TEXTURE1D_DESC() + {} + explicit CD3D10_TEXTURE1D_DESC( const D3D10_TEXTURE1D_DESC& o ) : + D3D10_TEXTURE1D_DESC( o ) + {} + explicit CD3D10_TEXTURE1D_DESC( + DXGI_FORMAT format, + UINT width, + UINT arraySize = 1, + UINT mipLevels = 0, + UINT bindFlags = D3D10_BIND_SHADER_RESOURCE, + D3D10_USAGE usage = D3D10_USAGE_DEFAULT, + UINT cpuaccessFlags= 0, + UINT miscFlags = 0 ) + { + Width = width; + MipLevels = mipLevels; + ArraySize = arraySize; + Format = format; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags; + MiscFlags = miscFlags; + } + ~CD3D10_TEXTURE1D_DESC() {} + operator const D3D10_TEXTURE1D_DESC&() const { return *this; } +}; +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0006_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0006_v0_0_s_ifspec; + +#ifndef __ID3D10Texture1D_INTERFACE_DEFINED__ +#define __ID3D10Texture1D_INTERFACE_DEFINED__ + +/* interface ID3D10Texture1D */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Texture1D; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C03-342C-4106-A19F-4F2704F689F0") + ID3D10Texture1D : public ID3D10Resource + { + public: + virtual HRESULT STDMETHODCALLTYPE Map( + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out void **ppData) = 0; + + virtual void STDMETHODCALLTYPE Unmap( + /* [annotation] */ + __in UINT Subresource) = 0; + + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_TEXTURE1D_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10Texture1DVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Texture1D * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Texture1D * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Texture1D * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Texture1D * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Texture1D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Texture1D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Texture1D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D10Texture1D * This, + /* [annotation] */ + __out D3D10_RESOURCE_DIMENSION *rType); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D10Texture1D * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D10Texture1D * This); + + HRESULT ( STDMETHODCALLTYPE *Map )( + ID3D10Texture1D * This, + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out void **ppData); + + void ( STDMETHODCALLTYPE *Unmap )( + ID3D10Texture1D * This, + /* [annotation] */ + __in UINT Subresource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10Texture1D * This, + /* [annotation] */ + __out D3D10_TEXTURE1D_DESC *pDesc); + + END_INTERFACE + } ID3D10Texture1DVtbl; + + interface ID3D10Texture1D + { + CONST_VTBL struct ID3D10Texture1DVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Texture1D_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Texture1D_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Texture1D_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Texture1D_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Texture1D_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Texture1D_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Texture1D_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Texture1D_GetType(This,rType) \ + ( (This)->lpVtbl -> GetType(This,rType) ) + +#define ID3D10Texture1D_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D10Texture1D_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D10Texture1D_Map(This,Subresource,MapType,MapFlags,ppData) \ + ( (This)->lpVtbl -> Map(This,Subresource,MapType,MapFlags,ppData) ) + +#define ID3D10Texture1D_Unmap(This,Subresource) \ + ( (This)->lpVtbl -> Unmap(This,Subresource) ) + +#define ID3D10Texture1D_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Texture1D_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0007 */ +/* [local] */ + +typedef struct D3D10_TEXTURE2D_DESC + { + UINT Width; + UINT Height; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + } D3D10_TEXTURE2D_DESC; + +#if !defined( D3D10_NO_HELPERS ) && defined( __cplusplus ) +struct CD3D10_TEXTURE2D_DESC : public D3D10_TEXTURE2D_DESC +{ + CD3D10_TEXTURE2D_DESC() + {} + explicit CD3D10_TEXTURE2D_DESC( const D3D10_TEXTURE2D_DESC& o ) : + D3D10_TEXTURE2D_DESC( o ) + {} + explicit CD3D10_TEXTURE2D_DESC( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT arraySize = 1, + UINT mipLevels = 0, + UINT bindFlags = D3D10_BIND_SHADER_RESOURCE, + D3D10_USAGE usage = D3D10_USAGE_DEFAULT, + UINT cpuaccessFlags = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + UINT miscFlags = 0 ) + { + Width = width; + Height = height; + MipLevels = mipLevels; + ArraySize = arraySize; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags; + MiscFlags = miscFlags; + } + ~CD3D10_TEXTURE2D_DESC() {} + operator const D3D10_TEXTURE2D_DESC&() const { return *this; } +}; +#endif +typedef struct D3D10_MAPPED_TEXTURE2D + { + void *pData; + UINT RowPitch; + } D3D10_MAPPED_TEXTURE2D; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0007_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0007_v0_0_s_ifspec; + +#ifndef __ID3D10Texture2D_INTERFACE_DEFINED__ +#define __ID3D10Texture2D_INTERFACE_DEFINED__ + +/* interface ID3D10Texture2D */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Texture2D; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C04-342C-4106-A19F-4F2704F689F0") + ID3D10Texture2D : public ID3D10Resource + { + public: + virtual HRESULT STDMETHODCALLTYPE Map( + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out D3D10_MAPPED_TEXTURE2D *pMappedTex2D) = 0; + + virtual void STDMETHODCALLTYPE Unmap( + /* [annotation] */ + __in UINT Subresource) = 0; + + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_TEXTURE2D_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10Texture2DVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Texture2D * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Texture2D * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Texture2D * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Texture2D * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Texture2D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Texture2D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Texture2D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D10Texture2D * This, + /* [annotation] */ + __out D3D10_RESOURCE_DIMENSION *rType); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D10Texture2D * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D10Texture2D * This); + + HRESULT ( STDMETHODCALLTYPE *Map )( + ID3D10Texture2D * This, + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out D3D10_MAPPED_TEXTURE2D *pMappedTex2D); + + void ( STDMETHODCALLTYPE *Unmap )( + ID3D10Texture2D * This, + /* [annotation] */ + __in UINT Subresource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10Texture2D * This, + /* [annotation] */ + __out D3D10_TEXTURE2D_DESC *pDesc); + + END_INTERFACE + } ID3D10Texture2DVtbl; + + interface ID3D10Texture2D + { + CONST_VTBL struct ID3D10Texture2DVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Texture2D_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Texture2D_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Texture2D_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Texture2D_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Texture2D_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Texture2D_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Texture2D_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Texture2D_GetType(This,rType) \ + ( (This)->lpVtbl -> GetType(This,rType) ) + +#define ID3D10Texture2D_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D10Texture2D_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D10Texture2D_Map(This,Subresource,MapType,MapFlags,pMappedTex2D) \ + ( (This)->lpVtbl -> Map(This,Subresource,MapType,MapFlags,pMappedTex2D) ) + +#define ID3D10Texture2D_Unmap(This,Subresource) \ + ( (This)->lpVtbl -> Unmap(This,Subresource) ) + +#define ID3D10Texture2D_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Texture2D_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0008 */ +/* [local] */ + +typedef struct D3D10_TEXTURE3D_DESC + { + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + DXGI_FORMAT Format; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + } D3D10_TEXTURE3D_DESC; + +#if !defined( D3D10_NO_HELPERS ) && defined( __cplusplus ) +struct CD3D10_TEXTURE3D_DESC : public D3D10_TEXTURE3D_DESC +{ + CD3D10_TEXTURE3D_DESC() + {} + explicit CD3D10_TEXTURE3D_DESC( const D3D10_TEXTURE3D_DESC& o ) : + D3D10_TEXTURE3D_DESC( o ) + {} + explicit CD3D10_TEXTURE3D_DESC( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT mipLevels = 0, + UINT bindFlags = D3D10_BIND_SHADER_RESOURCE, + D3D10_USAGE usage = D3D10_USAGE_DEFAULT, + UINT cpuaccessFlags = 0, + UINT miscFlags = 0 ) + { + Width = width; + Height = height; + Depth = depth; + MipLevels = mipLevels; + Format = format; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags; + MiscFlags = miscFlags; + } + ~CD3D10_TEXTURE3D_DESC() {} + operator const D3D10_TEXTURE3D_DESC&() const { return *this; } +}; +#endif +typedef struct D3D10_MAPPED_TEXTURE3D + { + void *pData; + UINT RowPitch; + UINT DepthPitch; + } D3D10_MAPPED_TEXTURE3D; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0008_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0008_v0_0_s_ifspec; + +#ifndef __ID3D10Texture3D_INTERFACE_DEFINED__ +#define __ID3D10Texture3D_INTERFACE_DEFINED__ + +/* interface ID3D10Texture3D */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Texture3D; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C05-342C-4106-A19F-4F2704F689F0") + ID3D10Texture3D : public ID3D10Resource + { + public: + virtual HRESULT STDMETHODCALLTYPE Map( + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out D3D10_MAPPED_TEXTURE3D *pMappedTex3D) = 0; + + virtual void STDMETHODCALLTYPE Unmap( + /* [annotation] */ + __in UINT Subresource) = 0; + + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_TEXTURE3D_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10Texture3DVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Texture3D * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Texture3D * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Texture3D * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Texture3D * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Texture3D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Texture3D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Texture3D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D10Texture3D * This, + /* [annotation] */ + __out D3D10_RESOURCE_DIMENSION *rType); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D10Texture3D * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D10Texture3D * This); + + HRESULT ( STDMETHODCALLTYPE *Map )( + ID3D10Texture3D * This, + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D10_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out D3D10_MAPPED_TEXTURE3D *pMappedTex3D); + + void ( STDMETHODCALLTYPE *Unmap )( + ID3D10Texture3D * This, + /* [annotation] */ + __in UINT Subresource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10Texture3D * This, + /* [annotation] */ + __out D3D10_TEXTURE3D_DESC *pDesc); + + END_INTERFACE + } ID3D10Texture3DVtbl; + + interface ID3D10Texture3D + { + CONST_VTBL struct ID3D10Texture3DVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Texture3D_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Texture3D_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Texture3D_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Texture3D_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Texture3D_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Texture3D_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Texture3D_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Texture3D_GetType(This,rType) \ + ( (This)->lpVtbl -> GetType(This,rType) ) + +#define ID3D10Texture3D_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D10Texture3D_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D10Texture3D_Map(This,Subresource,MapType,MapFlags,pMappedTex3D) \ + ( (This)->lpVtbl -> Map(This,Subresource,MapType,MapFlags,pMappedTex3D) ) + +#define ID3D10Texture3D_Unmap(This,Subresource) \ + ( (This)->lpVtbl -> Unmap(This,Subresource) ) + +#define ID3D10Texture3D_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Texture3D_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0009 */ +/* [local] */ + +typedef +enum D3D10_TEXTURECUBE_FACE + { D3D10_TEXTURECUBE_FACE_POSITIVE_X = 0, + D3D10_TEXTURECUBE_FACE_NEGATIVE_X = 1, + D3D10_TEXTURECUBE_FACE_POSITIVE_Y = 2, + D3D10_TEXTURECUBE_FACE_NEGATIVE_Y = 3, + D3D10_TEXTURECUBE_FACE_POSITIVE_Z = 4, + D3D10_TEXTURECUBE_FACE_NEGATIVE_Z = 5 + } D3D10_TEXTURECUBE_FACE; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0009_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0009_v0_0_s_ifspec; + +#ifndef __ID3D10View_INTERFACE_DEFINED__ +#define __ID3D10View_INTERFACE_DEFINED__ + +/* interface ID3D10View */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10View; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C902B03F-60A7-49BA-9936-2A3AB37A7E33") + ID3D10View : public ID3D10DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetResource( + /* [annotation] */ + __out ID3D10Resource **ppResource) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10ViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10View * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10View * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10View * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10View * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10View * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10View * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10View * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D10View * This, + /* [annotation] */ + __out ID3D10Resource **ppResource); + + END_INTERFACE + } ID3D10ViewVtbl; + + interface ID3D10View + { + CONST_VTBL struct ID3D10ViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10View_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10View_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10View_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10View_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10View_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10View_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10View_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10View_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10View_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0010 */ +/* [local] */ + +typedef struct D3D10_BUFFER_SRV + { + union + { + UINT FirstElement; + UINT ElementOffset; + } ; + union + { + UINT NumElements; + UINT ElementWidth; + } ; + } D3D10_BUFFER_SRV; + +typedef struct D3D10_TEX1D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D10_TEX1D_SRV; + +typedef struct D3D10_TEX1D_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX1D_ARRAY_SRV; + +typedef struct D3D10_TEX2D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D10_TEX2D_SRV; + +typedef struct D3D10_TEX2D_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX2D_ARRAY_SRV; + +typedef struct D3D10_TEX3D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D10_TEX3D_SRV; + +typedef struct D3D10_TEXCUBE_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D10_TEXCUBE_SRV; + +typedef struct D3D10_TEX2DMS_SRV + { + UINT UnusedField_NothingToDefine; + } D3D10_TEX2DMS_SRV; + +typedef struct D3D10_TEX2DMS_ARRAY_SRV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX2DMS_ARRAY_SRV; + +typedef struct D3D10_SHADER_RESOURCE_VIEW_DESC + { + DXGI_FORMAT Format; + D3D10_SRV_DIMENSION ViewDimension; + union + { + D3D10_BUFFER_SRV Buffer; + D3D10_TEX1D_SRV Texture1D; + D3D10_TEX1D_ARRAY_SRV Texture1DArray; + D3D10_TEX2D_SRV Texture2D; + D3D10_TEX2D_ARRAY_SRV Texture2DArray; + D3D10_TEX2DMS_SRV Texture2DMS; + D3D10_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D10_TEX3D_SRV Texture3D; + D3D10_TEXCUBE_SRV TextureCube; + } ; + } D3D10_SHADER_RESOURCE_VIEW_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0010_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0010_v0_0_s_ifspec; + +#ifndef __ID3D10ShaderResourceView_INTERFACE_DEFINED__ +#define __ID3D10ShaderResourceView_INTERFACE_DEFINED__ + +/* interface ID3D10ShaderResourceView */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10ShaderResourceView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C07-342C-4106-A19F-4F2704F689F0") + ID3D10ShaderResourceView : public ID3D10View + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10ShaderResourceViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10ShaderResourceView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10ShaderResourceView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10ShaderResourceView * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10ShaderResourceView * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10ShaderResourceView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10ShaderResourceView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10ShaderResourceView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D10ShaderResourceView * This, + /* [annotation] */ + __out ID3D10Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10ShaderResourceView * This, + /* [annotation] */ + __out D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc); + + END_INTERFACE + } ID3D10ShaderResourceViewVtbl; + + interface ID3D10ShaderResourceView + { + CONST_VTBL struct ID3D10ShaderResourceViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10ShaderResourceView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10ShaderResourceView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10ShaderResourceView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10ShaderResourceView_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10ShaderResourceView_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10ShaderResourceView_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10ShaderResourceView_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10ShaderResourceView_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D10ShaderResourceView_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10ShaderResourceView_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0011 */ +/* [local] */ + +typedef struct D3D10_BUFFER_RTV + { + union + { + UINT FirstElement; + UINT ElementOffset; + } ; + union + { + UINT NumElements; + UINT ElementWidth; + } ; + } D3D10_BUFFER_RTV; + +typedef struct D3D10_TEX1D_RTV + { + UINT MipSlice; + } D3D10_TEX1D_RTV; + +typedef struct D3D10_TEX1D_ARRAY_RTV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX1D_ARRAY_RTV; + +typedef struct D3D10_TEX2D_RTV + { + UINT MipSlice; + } D3D10_TEX2D_RTV; + +typedef struct D3D10_TEX2DMS_RTV + { + UINT UnusedField_NothingToDefine; + } D3D10_TEX2DMS_RTV; + +typedef struct D3D10_TEX2D_ARRAY_RTV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX2D_ARRAY_RTV; + +typedef struct D3D10_TEX2DMS_ARRAY_RTV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX2DMS_ARRAY_RTV; + +typedef struct D3D10_TEX3D_RTV + { + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; + } D3D10_TEX3D_RTV; + +typedef struct D3D10_RENDER_TARGET_VIEW_DESC + { + DXGI_FORMAT Format; + D3D10_RTV_DIMENSION ViewDimension; + union + { + D3D10_BUFFER_RTV Buffer; + D3D10_TEX1D_RTV Texture1D; + D3D10_TEX1D_ARRAY_RTV Texture1DArray; + D3D10_TEX2D_RTV Texture2D; + D3D10_TEX2D_ARRAY_RTV Texture2DArray; + D3D10_TEX2DMS_RTV Texture2DMS; + D3D10_TEX2DMS_ARRAY_RTV Texture2DMSArray; + D3D10_TEX3D_RTV Texture3D; + } ; + } D3D10_RENDER_TARGET_VIEW_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0011_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0011_v0_0_s_ifspec; + +#ifndef __ID3D10RenderTargetView_INTERFACE_DEFINED__ +#define __ID3D10RenderTargetView_INTERFACE_DEFINED__ + +/* interface ID3D10RenderTargetView */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10RenderTargetView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C08-342C-4106-A19F-4F2704F689F0") + ID3D10RenderTargetView : public ID3D10View + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_RENDER_TARGET_VIEW_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10RenderTargetViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10RenderTargetView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10RenderTargetView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10RenderTargetView * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10RenderTargetView * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10RenderTargetView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10RenderTargetView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10RenderTargetView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D10RenderTargetView * This, + /* [annotation] */ + __out ID3D10Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10RenderTargetView * This, + /* [annotation] */ + __out D3D10_RENDER_TARGET_VIEW_DESC *pDesc); + + END_INTERFACE + } ID3D10RenderTargetViewVtbl; + + interface ID3D10RenderTargetView + { + CONST_VTBL struct ID3D10RenderTargetViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10RenderTargetView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10RenderTargetView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10RenderTargetView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10RenderTargetView_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10RenderTargetView_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10RenderTargetView_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10RenderTargetView_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10RenderTargetView_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D10RenderTargetView_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10RenderTargetView_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0012 */ +/* [local] */ + +typedef struct D3D10_TEX1D_DSV + { + UINT MipSlice; + } D3D10_TEX1D_DSV; + +typedef struct D3D10_TEX1D_ARRAY_DSV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX1D_ARRAY_DSV; + +typedef struct D3D10_TEX2D_DSV + { + UINT MipSlice; + } D3D10_TEX2D_DSV; + +typedef struct D3D10_TEX2D_ARRAY_DSV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX2D_ARRAY_DSV; + +typedef struct D3D10_TEX2DMS_DSV + { + UINT UnusedField_NothingToDefine; + } D3D10_TEX2DMS_DSV; + +typedef struct D3D10_TEX2DMS_ARRAY_DSV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D10_TEX2DMS_ARRAY_DSV; + +typedef struct D3D10_DEPTH_STENCIL_VIEW_DESC + { + DXGI_FORMAT Format; + D3D10_DSV_DIMENSION ViewDimension; + union + { + D3D10_TEX1D_DSV Texture1D; + D3D10_TEX1D_ARRAY_DSV Texture1DArray; + D3D10_TEX2D_DSV Texture2D; + D3D10_TEX2D_ARRAY_DSV Texture2DArray; + D3D10_TEX2DMS_DSV Texture2DMS; + D3D10_TEX2DMS_ARRAY_DSV Texture2DMSArray; + } ; + } D3D10_DEPTH_STENCIL_VIEW_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0012_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0012_v0_0_s_ifspec; + +#ifndef __ID3D10DepthStencilView_INTERFACE_DEFINED__ +#define __ID3D10DepthStencilView_INTERFACE_DEFINED__ + +/* interface ID3D10DepthStencilView */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10DepthStencilView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C09-342C-4106-A19F-4F2704F689F0") + ID3D10DepthStencilView : public ID3D10View + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_DEPTH_STENCIL_VIEW_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10DepthStencilViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10DepthStencilView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10DepthStencilView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10DepthStencilView * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10DepthStencilView * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10DepthStencilView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10DepthStencilView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10DepthStencilView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D10DepthStencilView * This, + /* [annotation] */ + __out ID3D10Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10DepthStencilView * This, + /* [annotation] */ + __out D3D10_DEPTH_STENCIL_VIEW_DESC *pDesc); + + END_INTERFACE + } ID3D10DepthStencilViewVtbl; + + interface ID3D10DepthStencilView + { + CONST_VTBL struct ID3D10DepthStencilViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10DepthStencilView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10DepthStencilView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10DepthStencilView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10DepthStencilView_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10DepthStencilView_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10DepthStencilView_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10DepthStencilView_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10DepthStencilView_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D10DepthStencilView_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10DepthStencilView_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10VertexShader_INTERFACE_DEFINED__ +#define __ID3D10VertexShader_INTERFACE_DEFINED__ + +/* interface ID3D10VertexShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10VertexShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C0A-342C-4106-A19F-4F2704F689F0") + ID3D10VertexShader : public ID3D10DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D10VertexShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10VertexShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10VertexShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10VertexShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10VertexShader * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10VertexShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10VertexShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10VertexShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D10VertexShaderVtbl; + + interface ID3D10VertexShader + { + CONST_VTBL struct ID3D10VertexShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10VertexShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10VertexShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10VertexShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10VertexShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10VertexShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10VertexShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10VertexShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10VertexShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10GeometryShader_INTERFACE_DEFINED__ +#define __ID3D10GeometryShader_INTERFACE_DEFINED__ + +/* interface ID3D10GeometryShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10GeometryShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6316BE88-54CD-4040-AB44-20461BC81F68") + ID3D10GeometryShader : public ID3D10DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D10GeometryShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10GeometryShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10GeometryShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10GeometryShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10GeometryShader * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10GeometryShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10GeometryShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10GeometryShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D10GeometryShaderVtbl; + + interface ID3D10GeometryShader + { + CONST_VTBL struct ID3D10GeometryShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10GeometryShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10GeometryShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10GeometryShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10GeometryShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10GeometryShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10GeometryShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10GeometryShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10GeometryShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10PixelShader_INTERFACE_DEFINED__ +#define __ID3D10PixelShader_INTERFACE_DEFINED__ + +/* interface ID3D10PixelShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10PixelShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4968B601-9D00-4cde-8346-8E7F675819B6") + ID3D10PixelShader : public ID3D10DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D10PixelShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10PixelShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10PixelShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10PixelShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10PixelShader * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10PixelShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10PixelShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10PixelShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D10PixelShaderVtbl; + + interface ID3D10PixelShader + { + CONST_VTBL struct ID3D10PixelShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10PixelShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10PixelShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10PixelShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10PixelShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10PixelShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10PixelShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10PixelShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10PixelShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10InputLayout_INTERFACE_DEFINED__ +#define __ID3D10InputLayout_INTERFACE_DEFINED__ + +/* interface ID3D10InputLayout */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10InputLayout; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C0B-342C-4106-A19F-4F2704F689F0") + ID3D10InputLayout : public ID3D10DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D10InputLayoutVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10InputLayout * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10InputLayout * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10InputLayout * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10InputLayout * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10InputLayout * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10InputLayout * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10InputLayout * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D10InputLayoutVtbl; + + interface ID3D10InputLayout + { + CONST_VTBL struct ID3D10InputLayoutVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10InputLayout_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10InputLayout_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10InputLayout_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10InputLayout_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10InputLayout_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10InputLayout_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10InputLayout_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10InputLayout_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0017 */ +/* [local] */ + +typedef +enum D3D10_FILTER + { D3D10_FILTER_MIN_MAG_MIP_POINT = 0, + D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x1, + D3D10_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x4, + D3D10_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x5, + D3D10_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, + D3D10_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, + D3D10_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, + D3D10_FILTER_MIN_MAG_MIP_LINEAR = 0x15, + D3D10_FILTER_ANISOTROPIC = 0x55, + D3D10_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, + D3D10_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, + D3D10_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, + D3D10_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, + D3D10_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, + D3D10_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, + D3D10_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, + D3D10_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, + D3D10_FILTER_COMPARISON_ANISOTROPIC = 0xd5, + D3D10_FILTER_TEXT_1BIT = 0x80000000 + } D3D10_FILTER; + +typedef +enum D3D10_FILTER_TYPE + { D3D10_FILTER_TYPE_POINT = 0, + D3D10_FILTER_TYPE_LINEAR = 1 + } D3D10_FILTER_TYPE; + +#define D3D10_FILTER_TYPE_MASK ( 0x3 ) + +#define D3D10_MIN_FILTER_SHIFT ( 4 ) + +#define D3D10_MAG_FILTER_SHIFT ( 2 ) + +#define D3D10_MIP_FILTER_SHIFT ( 0 ) + +#define D3D10_COMPARISON_FILTERING_BIT ( 0x80 ) + +#define D3D10_ANISOTROPIC_FILTERING_BIT ( 0x40 ) + +#define D3D10_TEXT_1BIT_BIT ( 0x80000000 ) + +#define D3D10_ENCODE_BASIC_FILTER( min, mag, mip, bComparison ) \ + ( ( D3D10_FILTER ) ( \ + ( ( bComparison ) ? D3D10_COMPARISON_FILTERING_BIT : 0 ) | \ + ( ( ( min ) & D3D10_FILTER_TYPE_MASK ) << D3D10_MIN_FILTER_SHIFT ) | \ + ( ( ( mag ) & D3D10_FILTER_TYPE_MASK ) << D3D10_MAG_FILTER_SHIFT ) | \ + ( ( ( mip ) & D3D10_FILTER_TYPE_MASK ) << D3D10_MIP_FILTER_SHIFT ) ) ) +#define D3D10_ENCODE_ANISOTROPIC_FILTER( bComparison ) \ + ( ( D3D10_FILTER ) ( \ + D3D10_ANISOTROPIC_FILTERING_BIT | \ + D3D10_ENCODE_BASIC_FILTER( D3D10_FILTER_TYPE_LINEAR, \ + D3D10_FILTER_TYPE_LINEAR, \ + D3D10_FILTER_TYPE_LINEAR, \ + bComparison ) ) ) +#define D3D10_DECODE_MIN_FILTER( d3d10Filter ) \ + ( ( D3D10_FILTER_TYPE ) \ + ( ( ( d3d10Filter ) >> D3D10_MIN_FILTER_SHIFT ) & D3D10_FILTER_TYPE_MASK ) ) +#define D3D10_DECODE_MAG_FILTER( d3d10Filter ) \ + ( ( D3D10_FILTER_TYPE ) \ + ( ( ( d3d10Filter ) >> D3D10_MAG_FILTER_SHIFT ) & D3D10_FILTER_TYPE_MASK ) ) +#define D3D10_DECODE_MIP_FILTER( d3d10Filter ) \ + ( ( D3D10_FILTER_TYPE ) \ + ( ( ( d3d10Filter ) >> D3D10_MIP_FILTER_SHIFT ) & D3D10_FILTER_TYPE_MASK ) ) +#define D3D10_DECODE_IS_COMPARISON_FILTER( d3d10Filter ) \ + ( ( d3d10Filter ) & D3D10_COMPARISON_FILTERING_BIT ) +#define D3D10_DECODE_IS_ANISOTROPIC_FILTER( d3d10Filter ) \ + ( ( ( d3d10Filter ) & D3D10_ANISOTROPIC_FILTERING_BIT ) && \ + ( D3D10_FILTER_TYPE_LINEAR == D3D10_DECODE_MIN_FILTER( d3d10Filter ) ) && \ + ( D3D10_FILTER_TYPE_LINEAR == D3D10_DECODE_MAG_FILTER( d3d10Filter ) ) && \ + ( D3D10_FILTER_TYPE_LINEAR == D3D10_DECODE_MIP_FILTER( d3d10Filter ) ) ) +#define D3D10_DECODE_IS_TEXT_1BIT_FILTER( d3d10Filter ) \ + ( ( d3d10Filter ) == D3D10_TEXT_1BIT_BIT ) +typedef +enum D3D10_TEXTURE_ADDRESS_MODE + { D3D10_TEXTURE_ADDRESS_WRAP = 1, + D3D10_TEXTURE_ADDRESS_MIRROR = 2, + D3D10_TEXTURE_ADDRESS_CLAMP = 3, + D3D10_TEXTURE_ADDRESS_BORDER = 4, + D3D10_TEXTURE_ADDRESS_MIRROR_ONCE = 5 + } D3D10_TEXTURE_ADDRESS_MODE; + +typedef struct D3D10_SAMPLER_DESC + { + D3D10_FILTER Filter; + D3D10_TEXTURE_ADDRESS_MODE AddressU; + D3D10_TEXTURE_ADDRESS_MODE AddressV; + D3D10_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D10_COMPARISON_FUNC ComparisonFunc; + FLOAT BorderColor[ 4 ]; + FLOAT MinLOD; + FLOAT MaxLOD; + } D3D10_SAMPLER_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0017_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0017_v0_0_s_ifspec; + +#ifndef __ID3D10SamplerState_INTERFACE_DEFINED__ +#define __ID3D10SamplerState_INTERFACE_DEFINED__ + +/* interface ID3D10SamplerState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10SamplerState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C0C-342C-4106-A19F-4F2704F689F0") + ID3D10SamplerState : public ID3D10DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_SAMPLER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10SamplerStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10SamplerState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10SamplerState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10SamplerState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10SamplerState * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10SamplerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10SamplerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10SamplerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10SamplerState * This, + /* [annotation] */ + __out D3D10_SAMPLER_DESC *pDesc); + + END_INTERFACE + } ID3D10SamplerStateVtbl; + + interface ID3D10SamplerState + { + CONST_VTBL struct ID3D10SamplerStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10SamplerState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10SamplerState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10SamplerState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10SamplerState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10SamplerState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10SamplerState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10SamplerState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10SamplerState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10SamplerState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0018 */ +/* [local] */ + +typedef +enum D3D10_FORMAT_SUPPORT + { D3D10_FORMAT_SUPPORT_BUFFER = 0x1, + D3D10_FORMAT_SUPPORT_IA_VERTEX_BUFFER = 0x2, + D3D10_FORMAT_SUPPORT_IA_INDEX_BUFFER = 0x4, + D3D10_FORMAT_SUPPORT_SO_BUFFER = 0x8, + D3D10_FORMAT_SUPPORT_TEXTURE1D = 0x10, + D3D10_FORMAT_SUPPORT_TEXTURE2D = 0x20, + D3D10_FORMAT_SUPPORT_TEXTURE3D = 0x40, + D3D10_FORMAT_SUPPORT_TEXTURECUBE = 0x80, + D3D10_FORMAT_SUPPORT_SHADER_LOAD = 0x100, + D3D10_FORMAT_SUPPORT_SHADER_SAMPLE = 0x200, + D3D10_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON = 0x400, + D3D10_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT = 0x800, + D3D10_FORMAT_SUPPORT_MIP = 0x1000, + D3D10_FORMAT_SUPPORT_MIP_AUTOGEN = 0x2000, + D3D10_FORMAT_SUPPORT_RENDER_TARGET = 0x4000, + D3D10_FORMAT_SUPPORT_BLENDABLE = 0x8000, + D3D10_FORMAT_SUPPORT_DEPTH_STENCIL = 0x10000, + D3D10_FORMAT_SUPPORT_CPU_LOCKABLE = 0x20000, + D3D10_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE = 0x40000, + D3D10_FORMAT_SUPPORT_DISPLAY = 0x80000, + D3D10_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT = 0x100000, + D3D10_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET = 0x200000, + D3D10_FORMAT_SUPPORT_MULTISAMPLE_LOAD = 0x400000, + D3D10_FORMAT_SUPPORT_SHADER_GATHER = 0x800000, + D3D10_FORMAT_SUPPORT_BACK_BUFFER_CAST = 0x1000000 + } D3D10_FORMAT_SUPPORT; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0018_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0018_v0_0_s_ifspec; + +#ifndef __ID3D10Asynchronous_INTERFACE_DEFINED__ +#define __ID3D10Asynchronous_INTERFACE_DEFINED__ + +/* interface ID3D10Asynchronous */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Asynchronous; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C0D-342C-4106-A19F-4F2704F689F0") + ID3D10Asynchronous : public ID3D10DeviceChild + { + public: + virtual void STDMETHODCALLTYPE Begin( void) = 0; + + virtual void STDMETHODCALLTYPE End( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetData( + /* [annotation] */ + __out_bcount_opt(DataSize) void *pData, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in UINT GetDataFlags) = 0; + + virtual UINT STDMETHODCALLTYPE GetDataSize( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10AsynchronousVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Asynchronous * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Asynchronous * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Asynchronous * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Asynchronous * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Asynchronous * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Asynchronous * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Asynchronous * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *Begin )( + ID3D10Asynchronous * This); + + void ( STDMETHODCALLTYPE *End )( + ID3D10Asynchronous * This); + + HRESULT ( STDMETHODCALLTYPE *GetData )( + ID3D10Asynchronous * This, + /* [annotation] */ + __out_bcount_opt(DataSize) void *pData, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in UINT GetDataFlags); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D10Asynchronous * This); + + END_INTERFACE + } ID3D10AsynchronousVtbl; + + interface ID3D10Asynchronous + { + CONST_VTBL struct ID3D10AsynchronousVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Asynchronous_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Asynchronous_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Asynchronous_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Asynchronous_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Asynchronous_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Asynchronous_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Asynchronous_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Asynchronous_Begin(This) \ + ( (This)->lpVtbl -> Begin(This) ) + +#define ID3D10Asynchronous_End(This) \ + ( (This)->lpVtbl -> End(This) ) + +#define ID3D10Asynchronous_GetData(This,pData,DataSize,GetDataFlags) \ + ( (This)->lpVtbl -> GetData(This,pData,DataSize,GetDataFlags) ) + +#define ID3D10Asynchronous_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Asynchronous_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0019 */ +/* [local] */ + +typedef +enum D3D10_ASYNC_GETDATA_FLAG + { D3D10_ASYNC_GETDATA_DONOTFLUSH = 0x1 + } D3D10_ASYNC_GETDATA_FLAG; + +typedef +enum D3D10_QUERY + { D3D10_QUERY_EVENT = 0, + D3D10_QUERY_OCCLUSION = ( D3D10_QUERY_EVENT + 1 ) , + D3D10_QUERY_TIMESTAMP = ( D3D10_QUERY_OCCLUSION + 1 ) , + D3D10_QUERY_TIMESTAMP_DISJOINT = ( D3D10_QUERY_TIMESTAMP + 1 ) , + D3D10_QUERY_PIPELINE_STATISTICS = ( D3D10_QUERY_TIMESTAMP_DISJOINT + 1 ) , + D3D10_QUERY_OCCLUSION_PREDICATE = ( D3D10_QUERY_PIPELINE_STATISTICS + 1 ) , + D3D10_QUERY_SO_STATISTICS = ( D3D10_QUERY_OCCLUSION_PREDICATE + 1 ) , + D3D10_QUERY_SO_OVERFLOW_PREDICATE = ( D3D10_QUERY_SO_STATISTICS + 1 ) + } D3D10_QUERY; + +typedef +enum D3D10_QUERY_MISC_FLAG + { D3D10_QUERY_MISC_PREDICATEHINT = 0x1 + } D3D10_QUERY_MISC_FLAG; + +typedef struct D3D10_QUERY_DESC + { + D3D10_QUERY Query; + UINT MiscFlags; + } D3D10_QUERY_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0019_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0019_v0_0_s_ifspec; + +#ifndef __ID3D10Query_INTERFACE_DEFINED__ +#define __ID3D10Query_INTERFACE_DEFINED__ + +/* interface ID3D10Query */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Query; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C0E-342C-4106-A19F-4F2704F689F0") + ID3D10Query : public ID3D10Asynchronous + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_QUERY_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10QueryVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Query * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Query * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Query * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Query * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Query * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Query * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Query * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *Begin )( + ID3D10Query * This); + + void ( STDMETHODCALLTYPE *End )( + ID3D10Query * This); + + HRESULT ( STDMETHODCALLTYPE *GetData )( + ID3D10Query * This, + /* [annotation] */ + __out_bcount_opt(DataSize) void *pData, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in UINT GetDataFlags); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D10Query * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10Query * This, + /* [annotation] */ + __out D3D10_QUERY_DESC *pDesc); + + END_INTERFACE + } ID3D10QueryVtbl; + + interface ID3D10Query + { + CONST_VTBL struct ID3D10QueryVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Query_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Query_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Query_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Query_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Query_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Query_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Query_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Query_Begin(This) \ + ( (This)->lpVtbl -> Begin(This) ) + +#define ID3D10Query_End(This) \ + ( (This)->lpVtbl -> End(This) ) + +#define ID3D10Query_GetData(This,pData,DataSize,GetDataFlags) \ + ( (This)->lpVtbl -> GetData(This,pData,DataSize,GetDataFlags) ) + +#define ID3D10Query_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + + +#define ID3D10Query_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Query_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10Predicate_INTERFACE_DEFINED__ +#define __ID3D10Predicate_INTERFACE_DEFINED__ + +/* interface ID3D10Predicate */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Predicate; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C10-342C-4106-A19F-4F2704F689F0") + ID3D10Predicate : public ID3D10Query + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D10PredicateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Predicate * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Predicate * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Predicate * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Predicate * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Predicate * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Predicate * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Predicate * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *Begin )( + ID3D10Predicate * This); + + void ( STDMETHODCALLTYPE *End )( + ID3D10Predicate * This); + + HRESULT ( STDMETHODCALLTYPE *GetData )( + ID3D10Predicate * This, + /* [annotation] */ + __out_bcount_opt(DataSize) void *pData, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in UINT GetDataFlags); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D10Predicate * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10Predicate * This, + /* [annotation] */ + __out D3D10_QUERY_DESC *pDesc); + + END_INTERFACE + } ID3D10PredicateVtbl; + + interface ID3D10Predicate + { + CONST_VTBL struct ID3D10PredicateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Predicate_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Predicate_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Predicate_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Predicate_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Predicate_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Predicate_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Predicate_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Predicate_Begin(This) \ + ( (This)->lpVtbl -> Begin(This) ) + +#define ID3D10Predicate_End(This) \ + ( (This)->lpVtbl -> End(This) ) + +#define ID3D10Predicate_GetData(This,pData,DataSize,GetDataFlags) \ + ( (This)->lpVtbl -> GetData(This,pData,DataSize,GetDataFlags) ) + +#define ID3D10Predicate_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + + +#define ID3D10Predicate_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Predicate_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0021 */ +/* [local] */ + +typedef struct D3D10_QUERY_DATA_TIMESTAMP_DISJOINT + { + UINT64 Frequency; + BOOL Disjoint; + } D3D10_QUERY_DATA_TIMESTAMP_DISJOINT; + +typedef struct D3D10_QUERY_DATA_PIPELINE_STATISTICS + { + UINT64 IAVertices; + UINT64 IAPrimitives; + UINT64 VSInvocations; + UINT64 GSInvocations; + UINT64 GSPrimitives; + UINT64 CInvocations; + UINT64 CPrimitives; + UINT64 PSInvocations; + } D3D10_QUERY_DATA_PIPELINE_STATISTICS; + +typedef struct D3D10_QUERY_DATA_SO_STATISTICS + { + UINT64 NumPrimitivesWritten; + UINT64 PrimitivesStorageNeeded; + } D3D10_QUERY_DATA_SO_STATISTICS; + +typedef +enum D3D10_COUNTER + { D3D10_COUNTER_GPU_IDLE = 0, + D3D10_COUNTER_VERTEX_PROCESSING = ( D3D10_COUNTER_GPU_IDLE + 1 ) , + D3D10_COUNTER_GEOMETRY_PROCESSING = ( D3D10_COUNTER_VERTEX_PROCESSING + 1 ) , + D3D10_COUNTER_PIXEL_PROCESSING = ( D3D10_COUNTER_GEOMETRY_PROCESSING + 1 ) , + D3D10_COUNTER_OTHER_GPU_PROCESSING = ( D3D10_COUNTER_PIXEL_PROCESSING + 1 ) , + D3D10_COUNTER_HOST_ADAPTER_BANDWIDTH_UTILIZATION = ( D3D10_COUNTER_OTHER_GPU_PROCESSING + 1 ) , + D3D10_COUNTER_LOCAL_VIDMEM_BANDWIDTH_UTILIZATION = ( D3D10_COUNTER_HOST_ADAPTER_BANDWIDTH_UTILIZATION + 1 ) , + D3D10_COUNTER_VERTEX_THROUGHPUT_UTILIZATION = ( D3D10_COUNTER_LOCAL_VIDMEM_BANDWIDTH_UTILIZATION + 1 ) , + D3D10_COUNTER_TRIANGLE_SETUP_THROUGHPUT_UTILIZATION = ( D3D10_COUNTER_VERTEX_THROUGHPUT_UTILIZATION + 1 ) , + D3D10_COUNTER_FILLRATE_THROUGHPUT_UTILIZATION = ( D3D10_COUNTER_TRIANGLE_SETUP_THROUGHPUT_UTILIZATION + 1 ) , + D3D10_COUNTER_VS_MEMORY_LIMITED = ( D3D10_COUNTER_FILLRATE_THROUGHPUT_UTILIZATION + 1 ) , + D3D10_COUNTER_VS_COMPUTATION_LIMITED = ( D3D10_COUNTER_VS_MEMORY_LIMITED + 1 ) , + D3D10_COUNTER_GS_MEMORY_LIMITED = ( D3D10_COUNTER_VS_COMPUTATION_LIMITED + 1 ) , + D3D10_COUNTER_GS_COMPUTATION_LIMITED = ( D3D10_COUNTER_GS_MEMORY_LIMITED + 1 ) , + D3D10_COUNTER_PS_MEMORY_LIMITED = ( D3D10_COUNTER_GS_COMPUTATION_LIMITED + 1 ) , + D3D10_COUNTER_PS_COMPUTATION_LIMITED = ( D3D10_COUNTER_PS_MEMORY_LIMITED + 1 ) , + D3D10_COUNTER_POST_TRANSFORM_CACHE_HIT_RATE = ( D3D10_COUNTER_PS_COMPUTATION_LIMITED + 1 ) , + D3D10_COUNTER_TEXTURE_CACHE_HIT_RATE = ( D3D10_COUNTER_POST_TRANSFORM_CACHE_HIT_RATE + 1 ) , + D3D10_COUNTER_DEVICE_DEPENDENT_0 = 0x40000000 + } D3D10_COUNTER; + +typedef +enum D3D10_COUNTER_TYPE + { D3D10_COUNTER_TYPE_FLOAT32 = 0, + D3D10_COUNTER_TYPE_UINT16 = ( D3D10_COUNTER_TYPE_FLOAT32 + 1 ) , + D3D10_COUNTER_TYPE_UINT32 = ( D3D10_COUNTER_TYPE_UINT16 + 1 ) , + D3D10_COUNTER_TYPE_UINT64 = ( D3D10_COUNTER_TYPE_UINT32 + 1 ) + } D3D10_COUNTER_TYPE; + +typedef struct D3D10_COUNTER_DESC + { + D3D10_COUNTER Counter; + UINT MiscFlags; + } D3D10_COUNTER_DESC; + +typedef struct D3D10_COUNTER_INFO + { + D3D10_COUNTER LastDeviceDependentCounter; + UINT NumSimultaneousCounters; + UINT8 NumDetectableParallelUnits; + } D3D10_COUNTER_INFO; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0021_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0021_v0_0_s_ifspec; + +#ifndef __ID3D10Counter_INTERFACE_DEFINED__ +#define __ID3D10Counter_INTERFACE_DEFINED__ + +/* interface ID3D10Counter */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Counter; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C11-342C-4106-A19F-4F2704F689F0") + ID3D10Counter : public ID3D10Asynchronous + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D10_COUNTER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10CounterVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Counter * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Counter * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Counter * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10Counter * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Counter * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Counter * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Counter * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *Begin )( + ID3D10Counter * This); + + void ( STDMETHODCALLTYPE *End )( + ID3D10Counter * This); + + HRESULT ( STDMETHODCALLTYPE *GetData )( + ID3D10Counter * This, + /* [annotation] */ + __out_bcount_opt(DataSize) void *pData, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in UINT GetDataFlags); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D10Counter * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10Counter * This, + /* [annotation] */ + __out D3D10_COUNTER_DESC *pDesc); + + END_INTERFACE + } ID3D10CounterVtbl; + + interface ID3D10Counter + { + CONST_VTBL struct ID3D10CounterVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Counter_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Counter_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Counter_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Counter_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10Counter_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Counter_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Counter_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10Counter_Begin(This) \ + ( (This)->lpVtbl -> Begin(This) ) + +#define ID3D10Counter_End(This) \ + ( (This)->lpVtbl -> End(This) ) + +#define ID3D10Counter_GetData(This,pData,DataSize,GetDataFlags) \ + ( (This)->lpVtbl -> GetData(This,pData,DataSize,GetDataFlags) ) + +#define ID3D10Counter_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + + +#define ID3D10Counter_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Counter_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10Device_INTERFACE_DEFINED__ +#define __ID3D10Device_INTERFACE_DEFINED__ + +/* interface ID3D10Device */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Device; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C0F-342C-4106-A19F-4F2704F689F0") + ID3D10Device : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE VSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE PSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE PSSetShader( + /* [annotation] */ + __in_opt ID3D10PixelShader *pPixelShader) = 0; + + virtual void STDMETHODCALLTYPE PSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE VSSetShader( + /* [annotation] */ + __in_opt ID3D10VertexShader *pVertexShader) = 0; + + virtual void STDMETHODCALLTYPE DrawIndexed( + /* [annotation] */ + __in UINT IndexCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation) = 0; + + virtual void STDMETHODCALLTYPE Draw( + /* [annotation] */ + __in UINT VertexCount, + /* [annotation] */ + __in UINT StartVertexLocation) = 0; + + virtual void STDMETHODCALLTYPE PSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE IASetInputLayout( + /* [annotation] */ + __in_opt ID3D10InputLayout *pInputLayout) = 0; + + virtual void STDMETHODCALLTYPE IASetVertexBuffers( + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppVertexBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pStrides, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pOffsets) = 0; + + virtual void STDMETHODCALLTYPE IASetIndexBuffer( + /* [annotation] */ + __in_opt ID3D10Buffer *pIndexBuffer, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT Offset) = 0; + + virtual void STDMETHODCALLTYPE DrawIndexedInstanced( + /* [annotation] */ + __in UINT IndexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation) = 0; + + virtual void STDMETHODCALLTYPE DrawInstanced( + /* [annotation] */ + __in UINT VertexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation) = 0; + + virtual void STDMETHODCALLTYPE GSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE GSSetShader( + /* [annotation] */ + __in_opt ID3D10GeometryShader *pShader) = 0; + + virtual void STDMETHODCALLTYPE IASetPrimitiveTopology( + /* [annotation] */ + __in D3D10_PRIMITIVE_TOPOLOGY Topology) = 0; + + virtual void STDMETHODCALLTYPE VSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE VSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE SetPredication( + /* [annotation] */ + __in_opt ID3D10Predicate *pPredicate, + /* [annotation] */ + __in BOOL PredicateValue) = 0; + + virtual void STDMETHODCALLTYPE GSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE GSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE OMSetRenderTargets( + /* [annotation] */ + __in_range( 0, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __in_ecount_opt(NumViews) ID3D10RenderTargetView *const *ppRenderTargetViews, + /* [annotation] */ + __in_opt ID3D10DepthStencilView *pDepthStencilView) = 0; + + virtual void STDMETHODCALLTYPE OMSetBlendState( + /* [annotation] */ + __in_opt ID3D10BlendState *pBlendState, + /* [annotation] */ + __in const FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __in UINT SampleMask) = 0; + + virtual void STDMETHODCALLTYPE OMSetDepthStencilState( + /* [annotation] */ + __in_opt ID3D10DepthStencilState *pDepthStencilState, + /* [annotation] */ + __in UINT StencilRef) = 0; + + virtual void STDMETHODCALLTYPE SOSetTargets( + /* [annotation] */ + __in_range( 0, D3D10_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, + /* [annotation] */ + __in_ecount_opt(NumBuffers) ID3D10Buffer *const *ppSOTargets, + /* [annotation] */ + __in_ecount_opt(NumBuffers) const UINT *pOffsets) = 0; + + virtual void STDMETHODCALLTYPE DrawAuto( void) = 0; + + virtual void STDMETHODCALLTYPE RSSetState( + /* [annotation] */ + __in_opt ID3D10RasterizerState *pRasterizerState) = 0; + + virtual void STDMETHODCALLTYPE RSSetViewports( + /* [annotation] */ + __in_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + /* [annotation] */ + __in_ecount_opt(NumViewports) const D3D10_VIEWPORT *pViewports) = 0; + + virtual void STDMETHODCALLTYPE RSSetScissorRects( + /* [annotation] */ + __in_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + /* [annotation] */ + __in_ecount_opt(NumRects) const D3D10_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE CopySubresourceRegion( + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in UINT DstX, + /* [annotation] */ + __in UINT DstY, + /* [annotation] */ + __in UINT DstZ, + /* [annotation] */ + __in ID3D10Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in_opt const D3D10_BOX *pSrcBox) = 0; + + virtual void STDMETHODCALLTYPE CopyResource( + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in ID3D10Resource *pSrcResource) = 0; + + virtual void STDMETHODCALLTYPE UpdateSubresource( + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in_opt const D3D10_BOX *pDstBox, + /* [annotation] */ + __in const void *pSrcData, + /* [annotation] */ + __in UINT SrcRowPitch, + /* [annotation] */ + __in UINT SrcDepthPitch) = 0; + + virtual void STDMETHODCALLTYPE ClearRenderTargetView( + /* [annotation] */ + __in ID3D10RenderTargetView *pRenderTargetView, + /* [annotation] */ + __in const FLOAT ColorRGBA[ 4 ]) = 0; + + virtual void STDMETHODCALLTYPE ClearDepthStencilView( + /* [annotation] */ + __in ID3D10DepthStencilView *pDepthStencilView, + /* [annotation] */ + __in UINT ClearFlags, + /* [annotation] */ + __in FLOAT Depth, + /* [annotation] */ + __in UINT8 Stencil) = 0; + + virtual void STDMETHODCALLTYPE GenerateMips( + /* [annotation] */ + __in ID3D10ShaderResourceView *pShaderResourceView) = 0; + + virtual void STDMETHODCALLTYPE ResolveSubresource( + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in ID3D10Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in DXGI_FORMAT Format) = 0; + + virtual void STDMETHODCALLTYPE VSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE PSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE PSGetShader( + /* [annotation] */ + __out ID3D10PixelShader **ppPixelShader) = 0; + + virtual void STDMETHODCALLTYPE PSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE VSGetShader( + /* [annotation] */ + __out ID3D10VertexShader **ppVertexShader) = 0; + + virtual void STDMETHODCALLTYPE PSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE IAGetInputLayout( + /* [annotation] */ + __out ID3D10InputLayout **ppInputLayout) = 0; + + virtual void STDMETHODCALLTYPE IAGetVertexBuffers( + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D10Buffer **ppVertexBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pStrides, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets) = 0; + + virtual void STDMETHODCALLTYPE IAGetIndexBuffer( + /* [annotation] */ + __out_opt ID3D10Buffer **pIndexBuffer, + /* [annotation] */ + __out_opt DXGI_FORMAT *Format, + /* [annotation] */ + __out_opt UINT *Offset) = 0; + + virtual void STDMETHODCALLTYPE GSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE GSGetShader( + /* [annotation] */ + __out ID3D10GeometryShader **ppGeometryShader) = 0; + + virtual void STDMETHODCALLTYPE IAGetPrimitiveTopology( + /* [annotation] */ + __out D3D10_PRIMITIVE_TOPOLOGY *pTopology) = 0; + + virtual void STDMETHODCALLTYPE VSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE VSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE GetPredication( + /* [annotation] */ + __out_opt ID3D10Predicate **ppPredicate, + /* [annotation] */ + __out_opt BOOL *pPredicateValue) = 0; + + virtual void STDMETHODCALLTYPE GSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE GSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE OMGetRenderTargets( + /* [annotation] */ + __in_range( 0, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __out_ecount_opt(NumViews) ID3D10RenderTargetView **ppRenderTargetViews, + /* [annotation] */ + __out_opt ID3D10DepthStencilView **ppDepthStencilView) = 0; + + virtual void STDMETHODCALLTYPE OMGetBlendState( + /* [annotation] */ + __out_opt ID3D10BlendState **ppBlendState, + /* [annotation] */ + __out_opt FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __out_opt UINT *pSampleMask) = 0; + + virtual void STDMETHODCALLTYPE OMGetDepthStencilState( + /* [annotation] */ + __out_opt ID3D10DepthStencilState **ppDepthStencilState, + /* [annotation] */ + __out_opt UINT *pStencilRef) = 0; + + virtual void STDMETHODCALLTYPE SOGetTargets( + /* [annotation] */ + __in_range( 0, D3D10_SO_BUFFER_SLOT_COUNT ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D10Buffer **ppSOTargets, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets) = 0; + + virtual void STDMETHODCALLTYPE RSGetState( + /* [annotation] */ + __out ID3D10RasterizerState **ppRasterizerState) = 0; + + virtual void STDMETHODCALLTYPE RSGetViewports( + /* [annotation] */ + __inout /*_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *NumViewports, + /* [annotation] */ + __out_ecount_opt(*NumViewports) D3D10_VIEWPORT *pViewports) = 0; + + virtual void STDMETHODCALLTYPE RSGetScissorRects( + /* [annotation] */ + __inout /*_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *NumRects, + /* [annotation] */ + __out_ecount_opt(*NumRects) D3D10_RECT *pRects) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetExceptionMode( + UINT RaiseFlags) = 0; + + virtual UINT STDMETHODCALLTYPE GetExceptionMode( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData) = 0; + + virtual void STDMETHODCALLTYPE ClearState( void) = 0; + + virtual void STDMETHODCALLTYPE Flush( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateBuffer( + /* [annotation] */ + __in const D3D10_BUFFER_DESC *pDesc, + /* [annotation] */ + __in_opt const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D10Buffer **ppBuffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateTexture1D( + /* [annotation] */ + __in const D3D10_TEXTURE1D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture1D **ppTexture1D) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateTexture2D( + /* [annotation] */ + __in const D3D10_TEXTURE2D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture2D **ppTexture2D) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateTexture3D( + /* [annotation] */ + __in const D3D10_TEXTURE3D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture3D **ppTexture3D) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView( + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10ShaderResourceView **ppSRView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRenderTargetView( + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_RENDER_TARGET_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10RenderTargetView **ppRTView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilView( + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_DEPTH_STENCIL_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10DepthStencilView **ppDepthStencilView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateInputLayout( + /* [annotation] */ + __in_ecount(NumElements) const D3D10_INPUT_ELEMENT_DESC *pInputElementDescs, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ) UINT NumElements, + /* [annotation] */ + __in const void *pShaderBytecodeWithInputSignature, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10InputLayout **ppInputLayout) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateVertexShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10VertexShader **ppVertexShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateGeometryShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10GeometryShader **ppGeometryShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_ecount_opt(NumEntries) const D3D10_SO_DECLARATION_ENTRY *pSODeclaration, + /* [annotation] */ + __in_range( 0, D3D10_SO_SINGLE_BUFFER_COMPONENT_LIMIT ) UINT NumEntries, + /* [annotation] */ + __in UINT OutputStreamStride, + /* [annotation] */ + __out_opt ID3D10GeometryShader **ppGeometryShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreatePixelShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10PixelShader **ppPixelShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateBlendState( + /* [annotation] */ + __in const D3D10_BLEND_DESC *pBlendStateDesc, + /* [annotation] */ + __out_opt ID3D10BlendState **ppBlendState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilState( + /* [annotation] */ + __in const D3D10_DEPTH_STENCIL_DESC *pDepthStencilDesc, + /* [annotation] */ + __out_opt ID3D10DepthStencilState **ppDepthStencilState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState( + /* [annotation] */ + __in const D3D10_RASTERIZER_DESC *pRasterizerDesc, + /* [annotation] */ + __out_opt ID3D10RasterizerState **ppRasterizerState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateSamplerState( + /* [annotation] */ + __in const D3D10_SAMPLER_DESC *pSamplerDesc, + /* [annotation] */ + __out_opt ID3D10SamplerState **ppSamplerState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateQuery( + /* [annotation] */ + __in const D3D10_QUERY_DESC *pQueryDesc, + /* [annotation] */ + __out_opt ID3D10Query **ppQuery) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreatePredicate( + /* [annotation] */ + __in const D3D10_QUERY_DESC *pPredicateDesc, + /* [annotation] */ + __out_opt ID3D10Predicate **ppPredicate) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCounter( + /* [annotation] */ + __in const D3D10_COUNTER_DESC *pCounterDesc, + /* [annotation] */ + __out_opt ID3D10Counter **ppCounter) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckFormatSupport( + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __out UINT *pFormatSupport) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels( + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT SampleCount, + /* [annotation] */ + __out UINT *pNumQualityLevels) = 0; + + virtual void STDMETHODCALLTYPE CheckCounterInfo( + /* [annotation] */ + __out D3D10_COUNTER_INFO *pCounterInfo) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckCounter( + /* [annotation] */ + __in const D3D10_COUNTER_DESC *pDesc, + /* [annotation] */ + __out D3D10_COUNTER_TYPE *pType, + /* [annotation] */ + __out UINT *pActiveCounters, + /* [annotation] */ + __out_ecount_opt(*pNameLength) LPSTR szName, + /* [annotation] */ + __inout_opt UINT *pNameLength, + /* [annotation] */ + __out_ecount_opt(*pUnitsLength) LPSTR szUnits, + /* [annotation] */ + __inout_opt UINT *pUnitsLength, + /* [annotation] */ + __out_ecount_opt(*pDescriptionLength) LPSTR szDescription, + /* [annotation] */ + __inout_opt UINT *pDescriptionLength) = 0; + + virtual UINT STDMETHODCALLTYPE GetCreationFlags( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE OpenSharedResource( + /* [annotation] */ + __in HANDLE hResource, + /* [annotation] */ + __in REFIID ReturnedInterface, + /* [annotation] */ + __out_opt void **ppResource) = 0; + + virtual void STDMETHODCALLTYPE SetTextFilterSize( + /* [annotation] */ + __in UINT Width, + /* [annotation] */ + __in UINT Height) = 0; + + virtual void STDMETHODCALLTYPE GetTextFilterSize( + /* [annotation] */ + __out_opt UINT *pWidth, + /* [annotation] */ + __out_opt UINT *pHeight) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10DeviceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Device * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Device * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Device * This); + + void ( STDMETHODCALLTYPE *VSSetConstantBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *PSSetShaderResources )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *PSSetShader )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10PixelShader *pPixelShader); + + void ( STDMETHODCALLTYPE *PSSetSamplers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *VSSetShader )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10VertexShader *pVertexShader); + + void ( STDMETHODCALLTYPE *DrawIndexed )( + ID3D10Device * This, + /* [annotation] */ + __in UINT IndexCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation); + + void ( STDMETHODCALLTYPE *Draw )( + ID3D10Device * This, + /* [annotation] */ + __in UINT VertexCount, + /* [annotation] */ + __in UINT StartVertexLocation); + + void ( STDMETHODCALLTYPE *PSSetConstantBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *IASetInputLayout )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10InputLayout *pInputLayout); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppVertexBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pStrides, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pOffsets); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10Buffer *pIndexBuffer, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT Offset); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D10Device * This, + /* [annotation] */ + __in UINT IndexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D10Device * This, + /* [annotation] */ + __in UINT VertexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *GSSetConstantBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *GSSetShader )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10GeometryShader *pShader); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D10Device * This, + /* [annotation] */ + __in D3D10_PRIMITIVE_TOPOLOGY Topology); + + void ( STDMETHODCALLTYPE *VSSetShaderResources )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *VSSetSamplers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10Predicate *pPredicate, + /* [annotation] */ + __in BOOL PredicateValue); + + void ( STDMETHODCALLTYPE *GSSetShaderResources )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *GSSetSamplers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __in_ecount_opt(NumViews) ID3D10RenderTargetView *const *ppRenderTargetViews, + /* [annotation] */ + __in_opt ID3D10DepthStencilView *pDepthStencilView); + + void ( STDMETHODCALLTYPE *OMSetBlendState )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10BlendState *pBlendState, + /* [annotation] */ + __in const FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __in UINT SampleMask); + + void ( STDMETHODCALLTYPE *OMSetDepthStencilState )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10DepthStencilState *pDepthStencilState, + /* [annotation] */ + __in UINT StencilRef); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, + /* [annotation] */ + __in_ecount_opt(NumBuffers) ID3D10Buffer *const *ppSOTargets, + /* [annotation] */ + __in_ecount_opt(NumBuffers) const UINT *pOffsets); + + void ( STDMETHODCALLTYPE *DrawAuto )( + ID3D10Device * This); + + void ( STDMETHODCALLTYPE *RSSetState )( + ID3D10Device * This, + /* [annotation] */ + __in_opt ID3D10RasterizerState *pRasterizerState); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D10Device * This, + /* [annotation] */ + __in_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + /* [annotation] */ + __in_ecount_opt(NumViewports) const D3D10_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D10Device * This, + /* [annotation] */ + __in_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + /* [annotation] */ + __in_ecount_opt(NumRects) const D3D10_RECT *pRects); + + void ( STDMETHODCALLTYPE *CopySubresourceRegion )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in UINT DstX, + /* [annotation] */ + __in UINT DstY, + /* [annotation] */ + __in UINT DstZ, + /* [annotation] */ + __in ID3D10Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in_opt const D3D10_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in ID3D10Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *UpdateSubresource )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in_opt const D3D10_BOX *pDstBox, + /* [annotation] */ + __in const void *pSrcData, + /* [annotation] */ + __in UINT SrcRowPitch, + /* [annotation] */ + __in UINT SrcDepthPitch); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10RenderTargetView *pRenderTargetView, + /* [annotation] */ + __in const FLOAT ColorRGBA[ 4 ]); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10DepthStencilView *pDepthStencilView, + /* [annotation] */ + __in UINT ClearFlags, + /* [annotation] */ + __in FLOAT Depth, + /* [annotation] */ + __in UINT8 Stencil); + + void ( STDMETHODCALLTYPE *GenerateMips )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10ShaderResourceView *pShaderResourceView); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in ID3D10Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *VSGetConstantBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *PSGetShaderResources )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *PSGetShader )( + ID3D10Device * This, + /* [annotation] */ + __out ID3D10PixelShader **ppPixelShader); + + void ( STDMETHODCALLTYPE *PSGetSamplers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *VSGetShader )( + ID3D10Device * This, + /* [annotation] */ + __out ID3D10VertexShader **ppVertexShader); + + void ( STDMETHODCALLTYPE *PSGetConstantBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *IAGetInputLayout )( + ID3D10Device * This, + /* [annotation] */ + __out ID3D10InputLayout **ppInputLayout); + + void ( STDMETHODCALLTYPE *IAGetVertexBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D10Buffer **ppVertexBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pStrides, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets); + + void ( STDMETHODCALLTYPE *IAGetIndexBuffer )( + ID3D10Device * This, + /* [annotation] */ + __out_opt ID3D10Buffer **pIndexBuffer, + /* [annotation] */ + __out_opt DXGI_FORMAT *Format, + /* [annotation] */ + __out_opt UINT *Offset); + + void ( STDMETHODCALLTYPE *GSGetConstantBuffers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *GSGetShader )( + ID3D10Device * This, + /* [annotation] */ + __out ID3D10GeometryShader **ppGeometryShader); + + void ( STDMETHODCALLTYPE *IAGetPrimitiveTopology )( + ID3D10Device * This, + /* [annotation] */ + __out D3D10_PRIMITIVE_TOPOLOGY *pTopology); + + void ( STDMETHODCALLTYPE *VSGetShaderResources )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *VSGetSamplers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *GetPredication )( + ID3D10Device * This, + /* [annotation] */ + __out_opt ID3D10Predicate **ppPredicate, + /* [annotation] */ + __out_opt BOOL *pPredicateValue); + + void ( STDMETHODCALLTYPE *GSGetShaderResources )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *GSGetSamplers )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *OMGetRenderTargets )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __out_ecount_opt(NumViews) ID3D10RenderTargetView **ppRenderTargetViews, + /* [annotation] */ + __out_opt ID3D10DepthStencilView **ppDepthStencilView); + + void ( STDMETHODCALLTYPE *OMGetBlendState )( + ID3D10Device * This, + /* [annotation] */ + __out_opt ID3D10BlendState **ppBlendState, + /* [annotation] */ + __out_opt FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __out_opt UINT *pSampleMask); + + void ( STDMETHODCALLTYPE *OMGetDepthStencilState )( + ID3D10Device * This, + /* [annotation] */ + __out_opt ID3D10DepthStencilState **ppDepthStencilState, + /* [annotation] */ + __out_opt UINT *pStencilRef); + + void ( STDMETHODCALLTYPE *SOGetTargets )( + ID3D10Device * This, + /* [annotation] */ + __in_range( 0, D3D10_SO_BUFFER_SLOT_COUNT ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D10Buffer **ppSOTargets, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets); + + void ( STDMETHODCALLTYPE *RSGetState )( + ID3D10Device * This, + /* [annotation] */ + __out ID3D10RasterizerState **ppRasterizerState); + + void ( STDMETHODCALLTYPE *RSGetViewports )( + ID3D10Device * This, + /* [annotation] */ + __inout /*_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *NumViewports, + /* [annotation] */ + __out_ecount_opt(*NumViewports) D3D10_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSGetScissorRects )( + ID3D10Device * This, + /* [annotation] */ + __inout /*_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *NumRects, + /* [annotation] */ + __out_ecount_opt(*NumRects) D3D10_RECT *pRects); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D10Device * This); + + HRESULT ( STDMETHODCALLTYPE *SetExceptionMode )( + ID3D10Device * This, + UINT RaiseFlags); + + UINT ( STDMETHODCALLTYPE *GetExceptionMode )( + ID3D10Device * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Device * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Device * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Device * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D10Device * This); + + void ( STDMETHODCALLTYPE *Flush )( + ID3D10Device * This); + + HRESULT ( STDMETHODCALLTYPE *CreateBuffer )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_BUFFER_DESC *pDesc, + /* [annotation] */ + __in_opt const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D10Buffer **ppBuffer); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture1D )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_TEXTURE1D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture1D **ppTexture1D); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture2D )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_TEXTURE2D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture2D **ppTexture2D); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture3D )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_TEXTURE3D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture3D **ppTexture3D); + + HRESULT ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10ShaderResourceView **ppSRView); + + HRESULT ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_RENDER_TARGET_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10RenderTargetView **ppRTView); + + HRESULT ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D10Device * This, + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_DEPTH_STENCIL_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10DepthStencilView **ppDepthStencilView); + + HRESULT ( STDMETHODCALLTYPE *CreateInputLayout )( + ID3D10Device * This, + /* [annotation] */ + __in_ecount(NumElements) const D3D10_INPUT_ELEMENT_DESC *pInputElementDescs, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ) UINT NumElements, + /* [annotation] */ + __in const void *pShaderBytecodeWithInputSignature, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10InputLayout **ppInputLayout); + + HRESULT ( STDMETHODCALLTYPE *CreateVertexShader )( + ID3D10Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10VertexShader **ppVertexShader); + + HRESULT ( STDMETHODCALLTYPE *CreateGeometryShader )( + ID3D10Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10GeometryShader **ppGeometryShader); + + HRESULT ( STDMETHODCALLTYPE *CreateGeometryShaderWithStreamOutput )( + ID3D10Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_ecount_opt(NumEntries) const D3D10_SO_DECLARATION_ENTRY *pSODeclaration, + /* [annotation] */ + __in_range( 0, D3D10_SO_SINGLE_BUFFER_COMPONENT_LIMIT ) UINT NumEntries, + /* [annotation] */ + __in UINT OutputStreamStride, + /* [annotation] */ + __out_opt ID3D10GeometryShader **ppGeometryShader); + + HRESULT ( STDMETHODCALLTYPE *CreatePixelShader )( + ID3D10Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10PixelShader **ppPixelShader); + + HRESULT ( STDMETHODCALLTYPE *CreateBlendState )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_BLEND_DESC *pBlendStateDesc, + /* [annotation] */ + __out_opt ID3D10BlendState **ppBlendState); + + HRESULT ( STDMETHODCALLTYPE *CreateDepthStencilState )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_DEPTH_STENCIL_DESC *pDepthStencilDesc, + /* [annotation] */ + __out_opt ID3D10DepthStencilState **ppDepthStencilState); + + HRESULT ( STDMETHODCALLTYPE *CreateRasterizerState )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_RASTERIZER_DESC *pRasterizerDesc, + /* [annotation] */ + __out_opt ID3D10RasterizerState **ppRasterizerState); + + HRESULT ( STDMETHODCALLTYPE *CreateSamplerState )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_SAMPLER_DESC *pSamplerDesc, + /* [annotation] */ + __out_opt ID3D10SamplerState **ppSamplerState); + + HRESULT ( STDMETHODCALLTYPE *CreateQuery )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_QUERY_DESC *pQueryDesc, + /* [annotation] */ + __out_opt ID3D10Query **ppQuery); + + HRESULT ( STDMETHODCALLTYPE *CreatePredicate )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_QUERY_DESC *pPredicateDesc, + /* [annotation] */ + __out_opt ID3D10Predicate **ppPredicate); + + HRESULT ( STDMETHODCALLTYPE *CreateCounter )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_COUNTER_DESC *pCounterDesc, + /* [annotation] */ + __out_opt ID3D10Counter **ppCounter); + + HRESULT ( STDMETHODCALLTYPE *CheckFormatSupport )( + ID3D10Device * This, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __out UINT *pFormatSupport); + + HRESULT ( STDMETHODCALLTYPE *CheckMultisampleQualityLevels )( + ID3D10Device * This, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT SampleCount, + /* [annotation] */ + __out UINT *pNumQualityLevels); + + void ( STDMETHODCALLTYPE *CheckCounterInfo )( + ID3D10Device * This, + /* [annotation] */ + __out D3D10_COUNTER_INFO *pCounterInfo); + + HRESULT ( STDMETHODCALLTYPE *CheckCounter )( + ID3D10Device * This, + /* [annotation] */ + __in const D3D10_COUNTER_DESC *pDesc, + /* [annotation] */ + __out D3D10_COUNTER_TYPE *pType, + /* [annotation] */ + __out UINT *pActiveCounters, + /* [annotation] */ + __out_ecount_opt(*pNameLength) LPSTR szName, + /* [annotation] */ + __inout_opt UINT *pNameLength, + /* [annotation] */ + __out_ecount_opt(*pUnitsLength) LPSTR szUnits, + /* [annotation] */ + __inout_opt UINT *pUnitsLength, + /* [annotation] */ + __out_ecount_opt(*pDescriptionLength) LPSTR szDescription, + /* [annotation] */ + __inout_opt UINT *pDescriptionLength); + + UINT ( STDMETHODCALLTYPE *GetCreationFlags )( + ID3D10Device * This); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedResource )( + ID3D10Device * This, + /* [annotation] */ + __in HANDLE hResource, + /* [annotation] */ + __in REFIID ReturnedInterface, + /* [annotation] */ + __out_opt void **ppResource); + + void ( STDMETHODCALLTYPE *SetTextFilterSize )( + ID3D10Device * This, + /* [annotation] */ + __in UINT Width, + /* [annotation] */ + __in UINT Height); + + void ( STDMETHODCALLTYPE *GetTextFilterSize )( + ID3D10Device * This, + /* [annotation] */ + __out_opt UINT *pWidth, + /* [annotation] */ + __out_opt UINT *pHeight); + + END_INTERFACE + } ID3D10DeviceVtbl; + + interface ID3D10Device + { + CONST_VTBL struct ID3D10DeviceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Device_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Device_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Device_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Device_VSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> VSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device_PSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> PSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device_PSSetShader(This,pPixelShader) \ + ( (This)->lpVtbl -> PSSetShader(This,pPixelShader) ) + +#define ID3D10Device_PSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> PSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device_VSSetShader(This,pVertexShader) \ + ( (This)->lpVtbl -> VSSetShader(This,pVertexShader) ) + +#define ID3D10Device_DrawIndexed(This,IndexCount,StartIndexLocation,BaseVertexLocation) \ + ( (This)->lpVtbl -> DrawIndexed(This,IndexCount,StartIndexLocation,BaseVertexLocation) ) + +#define ID3D10Device_Draw(This,VertexCount,StartVertexLocation) \ + ( (This)->lpVtbl -> Draw(This,VertexCount,StartVertexLocation) ) + +#define ID3D10Device_PSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> PSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device_IASetInputLayout(This,pInputLayout) \ + ( (This)->lpVtbl -> IASetInputLayout(This,pInputLayout) ) + +#define ID3D10Device_IASetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) ) + +#define ID3D10Device_IASetIndexBuffer(This,pIndexBuffer,Format,Offset) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pIndexBuffer,Format,Offset) ) + +#define ID3D10Device_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D10Device_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D10Device_GSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> GSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device_GSSetShader(This,pShader) \ + ( (This)->lpVtbl -> GSSetShader(This,pShader) ) + +#define ID3D10Device_IASetPrimitiveTopology(This,Topology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,Topology) ) + +#define ID3D10Device_VSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> VSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device_VSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> VSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device_SetPredication(This,pPredicate,PredicateValue) \ + ( (This)->lpVtbl -> SetPredication(This,pPredicate,PredicateValue) ) + +#define ID3D10Device_GSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> GSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device_GSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> GSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device_OMSetRenderTargets(This,NumViews,ppRenderTargetViews,pDepthStencilView) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumViews,ppRenderTargetViews,pDepthStencilView) ) + +#define ID3D10Device_OMSetBlendState(This,pBlendState,BlendFactor,SampleMask) \ + ( (This)->lpVtbl -> OMSetBlendState(This,pBlendState,BlendFactor,SampleMask) ) + +#define ID3D10Device_OMSetDepthStencilState(This,pDepthStencilState,StencilRef) \ + ( (This)->lpVtbl -> OMSetDepthStencilState(This,pDepthStencilState,StencilRef) ) + +#define ID3D10Device_SOSetTargets(This,NumBuffers,ppSOTargets,pOffsets) \ + ( (This)->lpVtbl -> SOSetTargets(This,NumBuffers,ppSOTargets,pOffsets) ) + +#define ID3D10Device_DrawAuto(This) \ + ( (This)->lpVtbl -> DrawAuto(This) ) + +#define ID3D10Device_RSSetState(This,pRasterizerState) \ + ( (This)->lpVtbl -> RSSetState(This,pRasterizerState) ) + +#define ID3D10Device_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D10Device_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D10Device_CopySubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,DstZ,pSrcResource,SrcSubresource,pSrcBox) \ + ( (This)->lpVtbl -> CopySubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,DstZ,pSrcResource,SrcSubresource,pSrcBox) ) + +#define ID3D10Device_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D10Device_UpdateSubresource(This,pDstResource,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) \ + ( (This)->lpVtbl -> UpdateSubresource(This,pDstResource,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) ) + +#define ID3D10Device_ClearRenderTargetView(This,pRenderTargetView,ColorRGBA) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,pRenderTargetView,ColorRGBA) ) + +#define ID3D10Device_ClearDepthStencilView(This,pDepthStencilView,ClearFlags,Depth,Stencil) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,pDepthStencilView,ClearFlags,Depth,Stencil) ) + +#define ID3D10Device_GenerateMips(This,pShaderResourceView) \ + ( (This)->lpVtbl -> GenerateMips(This,pShaderResourceView) ) + +#define ID3D10Device_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D10Device_VSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> VSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device_PSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> PSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device_PSGetShader(This,ppPixelShader) \ + ( (This)->lpVtbl -> PSGetShader(This,ppPixelShader) ) + +#define ID3D10Device_PSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> PSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device_VSGetShader(This,ppVertexShader) \ + ( (This)->lpVtbl -> VSGetShader(This,ppVertexShader) ) + +#define ID3D10Device_PSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> PSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device_IAGetInputLayout(This,ppInputLayout) \ + ( (This)->lpVtbl -> IAGetInputLayout(This,ppInputLayout) ) + +#define ID3D10Device_IAGetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) \ + ( (This)->lpVtbl -> IAGetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) ) + +#define ID3D10Device_IAGetIndexBuffer(This,pIndexBuffer,Format,Offset) \ + ( (This)->lpVtbl -> IAGetIndexBuffer(This,pIndexBuffer,Format,Offset) ) + +#define ID3D10Device_GSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> GSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device_GSGetShader(This,ppGeometryShader) \ + ( (This)->lpVtbl -> GSGetShader(This,ppGeometryShader) ) + +#define ID3D10Device_IAGetPrimitiveTopology(This,pTopology) \ + ( (This)->lpVtbl -> IAGetPrimitiveTopology(This,pTopology) ) + +#define ID3D10Device_VSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> VSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device_VSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> VSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device_GetPredication(This,ppPredicate,pPredicateValue) \ + ( (This)->lpVtbl -> GetPredication(This,ppPredicate,pPredicateValue) ) + +#define ID3D10Device_GSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> GSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device_GSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> GSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device_OMGetRenderTargets(This,NumViews,ppRenderTargetViews,ppDepthStencilView) \ + ( (This)->lpVtbl -> OMGetRenderTargets(This,NumViews,ppRenderTargetViews,ppDepthStencilView) ) + +#define ID3D10Device_OMGetBlendState(This,ppBlendState,BlendFactor,pSampleMask) \ + ( (This)->lpVtbl -> OMGetBlendState(This,ppBlendState,BlendFactor,pSampleMask) ) + +#define ID3D10Device_OMGetDepthStencilState(This,ppDepthStencilState,pStencilRef) \ + ( (This)->lpVtbl -> OMGetDepthStencilState(This,ppDepthStencilState,pStencilRef) ) + +#define ID3D10Device_SOGetTargets(This,NumBuffers,ppSOTargets,pOffsets) \ + ( (This)->lpVtbl -> SOGetTargets(This,NumBuffers,ppSOTargets,pOffsets) ) + +#define ID3D10Device_RSGetState(This,ppRasterizerState) \ + ( (This)->lpVtbl -> RSGetState(This,ppRasterizerState) ) + +#define ID3D10Device_RSGetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSGetViewports(This,NumViewports,pViewports) ) + +#define ID3D10Device_RSGetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSGetScissorRects(This,NumRects,pRects) ) + +#define ID3D10Device_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D10Device_SetExceptionMode(This,RaiseFlags) \ + ( (This)->lpVtbl -> SetExceptionMode(This,RaiseFlags) ) + +#define ID3D10Device_GetExceptionMode(This) \ + ( (This)->lpVtbl -> GetExceptionMode(This) ) + +#define ID3D10Device_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Device_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Device_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D10Device_ClearState(This) \ + ( (This)->lpVtbl -> ClearState(This) ) + +#define ID3D10Device_Flush(This) \ + ( (This)->lpVtbl -> Flush(This) ) + +#define ID3D10Device_CreateBuffer(This,pDesc,pInitialData,ppBuffer) \ + ( (This)->lpVtbl -> CreateBuffer(This,pDesc,pInitialData,ppBuffer) ) + +#define ID3D10Device_CreateTexture1D(This,pDesc,pInitialData,ppTexture1D) \ + ( (This)->lpVtbl -> CreateTexture1D(This,pDesc,pInitialData,ppTexture1D) ) + +#define ID3D10Device_CreateTexture2D(This,pDesc,pInitialData,ppTexture2D) \ + ( (This)->lpVtbl -> CreateTexture2D(This,pDesc,pInitialData,ppTexture2D) ) + +#define ID3D10Device_CreateTexture3D(This,pDesc,pInitialData,ppTexture3D) \ + ( (This)->lpVtbl -> CreateTexture3D(This,pDesc,pInitialData,ppTexture3D) ) + +#define ID3D10Device_CreateShaderResourceView(This,pResource,pDesc,ppSRView) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,ppSRView) ) + +#define ID3D10Device_CreateRenderTargetView(This,pResource,pDesc,ppRTView) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,ppRTView) ) + +#define ID3D10Device_CreateDepthStencilView(This,pResource,pDesc,ppDepthStencilView) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,ppDepthStencilView) ) + +#define ID3D10Device_CreateInputLayout(This,pInputElementDescs,NumElements,pShaderBytecodeWithInputSignature,BytecodeLength,ppInputLayout) \ + ( (This)->lpVtbl -> CreateInputLayout(This,pInputElementDescs,NumElements,pShaderBytecodeWithInputSignature,BytecodeLength,ppInputLayout) ) + +#define ID3D10Device_CreateVertexShader(This,pShaderBytecode,BytecodeLength,ppVertexShader) \ + ( (This)->lpVtbl -> CreateVertexShader(This,pShaderBytecode,BytecodeLength,ppVertexShader) ) + +#define ID3D10Device_CreateGeometryShader(This,pShaderBytecode,BytecodeLength,ppGeometryShader) \ + ( (This)->lpVtbl -> CreateGeometryShader(This,pShaderBytecode,BytecodeLength,ppGeometryShader) ) + +#define ID3D10Device_CreateGeometryShaderWithStreamOutput(This,pShaderBytecode,BytecodeLength,pSODeclaration,NumEntries,OutputStreamStride,ppGeometryShader) \ + ( (This)->lpVtbl -> CreateGeometryShaderWithStreamOutput(This,pShaderBytecode,BytecodeLength,pSODeclaration,NumEntries,OutputStreamStride,ppGeometryShader) ) + +#define ID3D10Device_CreatePixelShader(This,pShaderBytecode,BytecodeLength,ppPixelShader) \ + ( (This)->lpVtbl -> CreatePixelShader(This,pShaderBytecode,BytecodeLength,ppPixelShader) ) + +#define ID3D10Device_CreateBlendState(This,pBlendStateDesc,ppBlendState) \ + ( (This)->lpVtbl -> CreateBlendState(This,pBlendStateDesc,ppBlendState) ) + +#define ID3D10Device_CreateDepthStencilState(This,pDepthStencilDesc,ppDepthStencilState) \ + ( (This)->lpVtbl -> CreateDepthStencilState(This,pDepthStencilDesc,ppDepthStencilState) ) + +#define ID3D10Device_CreateRasterizerState(This,pRasterizerDesc,ppRasterizerState) \ + ( (This)->lpVtbl -> CreateRasterizerState(This,pRasterizerDesc,ppRasterizerState) ) + +#define ID3D10Device_CreateSamplerState(This,pSamplerDesc,ppSamplerState) \ + ( (This)->lpVtbl -> CreateSamplerState(This,pSamplerDesc,ppSamplerState) ) + +#define ID3D10Device_CreateQuery(This,pQueryDesc,ppQuery) \ + ( (This)->lpVtbl -> CreateQuery(This,pQueryDesc,ppQuery) ) + +#define ID3D10Device_CreatePredicate(This,pPredicateDesc,ppPredicate) \ + ( (This)->lpVtbl -> CreatePredicate(This,pPredicateDesc,ppPredicate) ) + +#define ID3D10Device_CreateCounter(This,pCounterDesc,ppCounter) \ + ( (This)->lpVtbl -> CreateCounter(This,pCounterDesc,ppCounter) ) + +#define ID3D10Device_CheckFormatSupport(This,Format,pFormatSupport) \ + ( (This)->lpVtbl -> CheckFormatSupport(This,Format,pFormatSupport) ) + +#define ID3D10Device_CheckMultisampleQualityLevels(This,Format,SampleCount,pNumQualityLevels) \ + ( (This)->lpVtbl -> CheckMultisampleQualityLevels(This,Format,SampleCount,pNumQualityLevels) ) + +#define ID3D10Device_CheckCounterInfo(This,pCounterInfo) \ + ( (This)->lpVtbl -> CheckCounterInfo(This,pCounterInfo) ) + +#define ID3D10Device_CheckCounter(This,pDesc,pType,pActiveCounters,szName,pNameLength,szUnits,pUnitsLength,szDescription,pDescriptionLength) \ + ( (This)->lpVtbl -> CheckCounter(This,pDesc,pType,pActiveCounters,szName,pNameLength,szUnits,pUnitsLength,szDescription,pDescriptionLength) ) + +#define ID3D10Device_GetCreationFlags(This) \ + ( (This)->lpVtbl -> GetCreationFlags(This) ) + +#define ID3D10Device_OpenSharedResource(This,hResource,ReturnedInterface,ppResource) \ + ( (This)->lpVtbl -> OpenSharedResource(This,hResource,ReturnedInterface,ppResource) ) + +#define ID3D10Device_SetTextFilterSize(This,Width,Height) \ + ( (This)->lpVtbl -> SetTextFilterSize(This,Width,Height) ) + +#define ID3D10Device_GetTextFilterSize(This,pWidth,pHeight) \ + ( (This)->lpVtbl -> GetTextFilterSize(This,pWidth,pHeight) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Device_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10Multithread_INTERFACE_DEFINED__ +#define __ID3D10Multithread_INTERFACE_DEFINED__ + +/* interface ID3D10Multithread */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Multithread; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4E00-342C-4106-A19F-4F2704F689F0") + ID3D10Multithread : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE Enter( void) = 0; + + virtual void STDMETHODCALLTYPE Leave( void) = 0; + + virtual BOOL STDMETHODCALLTYPE SetMultithreadProtected( + /* [annotation] */ + __in BOOL bMTProtect) = 0; + + virtual BOOL STDMETHODCALLTYPE GetMultithreadProtected( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10MultithreadVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Multithread * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Multithread * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Multithread * This); + + void ( STDMETHODCALLTYPE *Enter )( + ID3D10Multithread * This); + + void ( STDMETHODCALLTYPE *Leave )( + ID3D10Multithread * This); + + BOOL ( STDMETHODCALLTYPE *SetMultithreadProtected )( + ID3D10Multithread * This, + /* [annotation] */ + __in BOOL bMTProtect); + + BOOL ( STDMETHODCALLTYPE *GetMultithreadProtected )( + ID3D10Multithread * This); + + END_INTERFACE + } ID3D10MultithreadVtbl; + + interface ID3D10Multithread + { + CONST_VTBL struct ID3D10MultithreadVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Multithread_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Multithread_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Multithread_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Multithread_Enter(This) \ + ( (This)->lpVtbl -> Enter(This) ) + +#define ID3D10Multithread_Leave(This) \ + ( (This)->lpVtbl -> Leave(This) ) + +#define ID3D10Multithread_SetMultithreadProtected(This,bMTProtect) \ + ( (This)->lpVtbl -> SetMultithreadProtected(This,bMTProtect) ) + +#define ID3D10Multithread_GetMultithreadProtected(This) \ + ( (This)->lpVtbl -> GetMultithreadProtected(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Multithread_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_0000_0024 */ +/* [local] */ + +typedef +enum D3D10_CREATE_DEVICE_FLAG + { D3D10_CREATE_DEVICE_SINGLETHREADED = 0x1, + D3D10_CREATE_DEVICE_DEBUG = 0x2, + D3D10_CREATE_DEVICE_SWITCH_TO_REF = 0x4, + D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS = 0x8, + D3D10_CREATE_DEVICE_ALLOW_NULL_FROM_MAP = 0x10, + D3D10_CREATE_DEVICE_BGRA_SUPPORT = 0x20, + D3D10_CREATE_DEVICE_STRICT_VALIDATION = 0x200 + } D3D10_CREATE_DEVICE_FLAG; + + +#define D3D10_SDK_VERSION ( 29 ) + +#if !defined( D3D10_IGNORE_SDK_LAYERS ) +#include "d3d10sdklayers.h" +#endif +#include "d3d10misc.h" +#include "d3d10shader.h" +#include "d3d10effect.h" +DEFINE_GUID(IID_ID3D10DeviceChild,0x9B7E4C00,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DepthStencilState,0x2B4B1CC8,0xA4AD,0x41f8,0x83,0x22,0xCA,0x86,0xFC,0x3E,0xC6,0x75); +DEFINE_GUID(IID_ID3D10BlendState,0xEDAD8D19,0x8A35,0x4d6d,0x85,0x66,0x2E,0xA2,0x76,0xCD,0xE1,0x61); +DEFINE_GUID(IID_ID3D10RasterizerState,0xA2A07292,0x89AF,0x4345,0xBE,0x2E,0xC5,0x3D,0x9F,0xBB,0x6E,0x9F); +DEFINE_GUID(IID_ID3D10Resource,0x9B7E4C01,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Buffer,0x9B7E4C02,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture1D,0x9B7E4C03,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture2D,0x9B7E4C04,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture3D,0x9B7E4C05,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10View,0xC902B03F,0x60A7,0x49BA,0x99,0x36,0x2A,0x3A,0xB3,0x7A,0x7E,0x33); +DEFINE_GUID(IID_ID3D10ShaderResourceView,0x9B7E4C07,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10RenderTargetView,0x9B7E4C08,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DepthStencilView,0x9B7E4C09,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10VertexShader,0x9B7E4C0A,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10GeometryShader,0x6316BE88,0x54CD,0x4040,0xAB,0x44,0x20,0x46,0x1B,0xC8,0x1F,0x68); +DEFINE_GUID(IID_ID3D10PixelShader,0x4968B601,0x9D00,0x4cde,0x83,0x46,0x8E,0x7F,0x67,0x58,0x19,0xB6); +DEFINE_GUID(IID_ID3D10InputLayout,0x9B7E4C0B,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10SamplerState,0x9B7E4C0C,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Asynchronous,0x9B7E4C0D,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Query,0x9B7E4C0E,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Predicate,0x9B7E4C10,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Counter,0x9B7E4C11,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Device,0x9B7E4C0F,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Multithread,0x9B7E4E00,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0024_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_0000_0024_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/dxsdk/Include/D3D10_1.h b/dxsdk/Include/D3D10_1.h new file mode 100644 index 0000000..17a8ec5 --- /dev/null +++ b/dxsdk/Include/D3D10_1.h @@ -0,0 +1,1775 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3d10_1_h__ +#define __d3d10_1_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D10BlendState1_FWD_DEFINED__ +#define __ID3D10BlendState1_FWD_DEFINED__ +typedef interface ID3D10BlendState1 ID3D10BlendState1; +#endif /* __ID3D10BlendState1_FWD_DEFINED__ */ + + +#ifndef __ID3D10ShaderResourceView1_FWD_DEFINED__ +#define __ID3D10ShaderResourceView1_FWD_DEFINED__ +typedef interface ID3D10ShaderResourceView1 ID3D10ShaderResourceView1; +#endif /* __ID3D10ShaderResourceView1_FWD_DEFINED__ */ + + +#ifndef __ID3D10Device1_FWD_DEFINED__ +#define __ID3D10Device1_FWD_DEFINED__ +typedef interface ID3D10Device1 ID3D10Device1; +#endif /* __ID3D10Device1_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3d10_1_0000_0000 */ +/* [local] */ + +#if defined( __d3d10_h__ ) && !defined( D3D10_ARBITRARY_HEADER_ORDERING ) +#error d3d10.h is included before d3d10_1.h, and it will confuse tools that honor SAL annotations. \ +If possibly targeting d3d10.1, include d3d10_1.h instead of d3d10.h, or ensure d3d10_1.h is included before d3d10.h +#endif +#ifndef _D3D10_1_CONSTANTS +#define _D3D10_1_CONSTANTS +#define D3D10_1_DEFAULT_SAMPLE_MASK ( 0xffffffff ) + +#define D3D10_1_FLOAT16_FUSED_TOLERANCE_IN_ULP ( 0.6 ) +#define D3D10_1_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ( 0.6f ) +#define D3D10_1_GS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT ( 32 ) + +#define D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS ( 128 ) + +#define D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ( 32 ) + +#define D3D10_1_PS_OUTPUT_MASK_REGISTER_COMPONENTS ( 1 ) + +#define D3D10_1_PS_OUTPUT_MASK_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D10_1_PS_OUTPUT_MASK_REGISTER_COUNT ( 1 ) + +#define D3D10_1_SHADER_MAJOR_VERSION ( 4 ) + +#define D3D10_1_SHADER_MINOR_VERSION ( 1 ) + +#define D3D10_1_SO_BUFFER_MAX_STRIDE_IN_BYTES ( 2048 ) + +#define D3D10_1_SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES ( 256 ) + +#define D3D10_1_SO_BUFFER_SLOT_COUNT ( 4 ) + +#define D3D10_1_SO_MULTIPLE_BUFFER_ELEMENTS_PER_BUFFER ( 1 ) + +#define D3D10_1_SO_SINGLE_BUFFER_COMPONENT_LIMIT ( 64 ) + +#define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT ( 32 ) + +#define D3D10_1_SUBPIXEL_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D10_1_VS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D10_1_VS_OUTPUT_REGISTER_COUNT ( 32 ) + +#endif +#include "d3d10.h" // + +typedef +enum D3D10_FEATURE_LEVEL1 + { D3D10_FEATURE_LEVEL_10_0 = 0xa000, + D3D10_FEATURE_LEVEL_10_1 = 0xa100, + D3D10_FEATURE_LEVEL_9_1 = 0x9100, + D3D10_FEATURE_LEVEL_9_2 = 0x9200, + D3D10_FEATURE_LEVEL_9_3 = 0x9300 + } D3D10_FEATURE_LEVEL1; + +typedef struct D3D10_RENDER_TARGET_BLEND_DESC1 + { + BOOL BlendEnable; + D3D10_BLEND SrcBlend; + D3D10_BLEND DestBlend; + D3D10_BLEND_OP BlendOp; + D3D10_BLEND SrcBlendAlpha; + D3D10_BLEND DestBlendAlpha; + D3D10_BLEND_OP BlendOpAlpha; + UINT8 RenderTargetWriteMask; + } D3D10_RENDER_TARGET_BLEND_DESC1; + +typedef struct D3D10_BLEND_DESC1 + { + BOOL AlphaToCoverageEnable; + BOOL IndependentBlendEnable; + D3D10_RENDER_TARGET_BLEND_DESC1 RenderTarget[ 8 ]; + } D3D10_BLEND_DESC1; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D10BlendState1_INTERFACE_DEFINED__ +#define __ID3D10BlendState1_INTERFACE_DEFINED__ + +/* interface ID3D10BlendState1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10BlendState1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("EDAD8D99-8A35-4d6d-8566-2EA276CDE161") + ID3D10BlendState1 : public ID3D10BlendState + { + public: + virtual void STDMETHODCALLTYPE GetDesc1( + /* [annotation] */ + __out D3D10_BLEND_DESC1 *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10BlendState1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10BlendState1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10BlendState1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10BlendState1 * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10BlendState1 * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10BlendState1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10BlendState1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10BlendState1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10BlendState1 * This, + /* [annotation] */ + __out D3D10_BLEND_DESC *pDesc); + + void ( STDMETHODCALLTYPE *GetDesc1 )( + ID3D10BlendState1 * This, + /* [annotation] */ + __out D3D10_BLEND_DESC1 *pDesc); + + END_INTERFACE + } ID3D10BlendState1Vtbl; + + interface ID3D10BlendState1 + { + CONST_VTBL struct ID3D10BlendState1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10BlendState1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10BlendState1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10BlendState1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10BlendState1_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10BlendState1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10BlendState1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10BlendState1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10BlendState1_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + + +#define ID3D10BlendState1_GetDesc1(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc1(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10BlendState1_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_1_0000_0001 */ +/* [local] */ + +typedef struct D3D10_TEXCUBE_ARRAY_SRV1 + { + UINT MostDetailedMip; + UINT MipLevels; + UINT First2DArrayFace; + UINT NumCubes; + } D3D10_TEXCUBE_ARRAY_SRV1; + +typedef D3D_SRV_DIMENSION D3D10_SRV_DIMENSION1; + +typedef struct D3D10_SHADER_RESOURCE_VIEW_DESC1 + { + DXGI_FORMAT Format; + D3D10_SRV_DIMENSION1 ViewDimension; + union + { + D3D10_BUFFER_SRV Buffer; + D3D10_TEX1D_SRV Texture1D; + D3D10_TEX1D_ARRAY_SRV Texture1DArray; + D3D10_TEX2D_SRV Texture2D; + D3D10_TEX2D_ARRAY_SRV Texture2DArray; + D3D10_TEX2DMS_SRV Texture2DMS; + D3D10_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D10_TEX3D_SRV Texture3D; + D3D10_TEXCUBE_SRV TextureCube; + D3D10_TEXCUBE_ARRAY_SRV1 TextureCubeArray; + } ; + } D3D10_SHADER_RESOURCE_VIEW_DESC1; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0001_v0_0_s_ifspec; + +#ifndef __ID3D10ShaderResourceView1_INTERFACE_DEFINED__ +#define __ID3D10ShaderResourceView1_INTERFACE_DEFINED__ + +/* interface ID3D10ShaderResourceView1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10ShaderResourceView1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C87-342C-4106-A19F-4F2704F689F0") + ID3D10ShaderResourceView1 : public ID3D10ShaderResourceView + { + public: + virtual void STDMETHODCALLTYPE GetDesc1( + /* [annotation] */ + __out D3D10_SHADER_RESOURCE_VIEW_DESC1 *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10ShaderResourceView1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10ShaderResourceView1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10ShaderResourceView1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10ShaderResourceView1 * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D10ShaderResourceView1 * This, + /* [annotation] */ + __out ID3D10Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10ShaderResourceView1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10ShaderResourceView1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10ShaderResourceView1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D10ShaderResourceView1 * This, + /* [annotation] */ + __out ID3D10Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D10ShaderResourceView1 * This, + /* [annotation] */ + __out D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc); + + void ( STDMETHODCALLTYPE *GetDesc1 )( + ID3D10ShaderResourceView1 * This, + /* [annotation] */ + __out D3D10_SHADER_RESOURCE_VIEW_DESC1 *pDesc); + + END_INTERFACE + } ID3D10ShaderResourceView1Vtbl; + + interface ID3D10ShaderResourceView1 + { + CONST_VTBL struct ID3D10ShaderResourceView1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10ShaderResourceView1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10ShaderResourceView1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10ShaderResourceView1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10ShaderResourceView1_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D10ShaderResourceView1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10ShaderResourceView1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10ShaderResourceView1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D10ShaderResourceView1_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D10ShaderResourceView1_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + + +#define ID3D10ShaderResourceView1_GetDesc1(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc1(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10ShaderResourceView1_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_1_0000_0002 */ +/* [local] */ + +typedef +enum D3D10_STANDARD_MULTISAMPLE_QUALITY_LEVELS + { D3D10_STANDARD_MULTISAMPLE_PATTERN = 0xffffffff, + D3D10_CENTER_MULTISAMPLE_PATTERN = 0xfffffffe + } D3D10_STANDARD_MULTISAMPLE_QUALITY_LEVELS; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0002_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0002_v0_0_s_ifspec; + +#ifndef __ID3D10Device1_INTERFACE_DEFINED__ +#define __ID3D10Device1_INTERFACE_DEFINED__ + +/* interface ID3D10Device1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Device1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4C8F-342C-4106-A19F-4F2704F689F0") + ID3D10Device1 : public ID3D10Device + { + public: + virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView1( + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_SHADER_RESOURCE_VIEW_DESC1 *pDesc, + /* [annotation] */ + __out_opt ID3D10ShaderResourceView1 **ppSRView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateBlendState1( + /* [annotation] */ + __in const D3D10_BLEND_DESC1 *pBlendStateDesc, + /* [annotation] */ + __out_opt ID3D10BlendState1 **ppBlendState) = 0; + + virtual D3D10_FEATURE_LEVEL1 STDMETHODCALLTYPE GetFeatureLevel( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10Device1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Device1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Device1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Device1 * This); + + void ( STDMETHODCALLTYPE *VSSetConstantBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *PSSetShaderResources )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *PSSetShader )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10PixelShader *pPixelShader); + + void ( STDMETHODCALLTYPE *PSSetSamplers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *VSSetShader )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10VertexShader *pVertexShader); + + void ( STDMETHODCALLTYPE *DrawIndexed )( + ID3D10Device1 * This, + /* [annotation] */ + __in UINT IndexCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation); + + void ( STDMETHODCALLTYPE *Draw )( + ID3D10Device1 * This, + /* [annotation] */ + __in UINT VertexCount, + /* [annotation] */ + __in UINT StartVertexLocation); + + void ( STDMETHODCALLTYPE *PSSetConstantBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *IASetInputLayout )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10InputLayout *pInputLayout); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppVertexBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pStrides, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pOffsets); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10Buffer *pIndexBuffer, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT Offset); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D10Device1 * This, + /* [annotation] */ + __in UINT IndexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D10Device1 * This, + /* [annotation] */ + __in UINT VertexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *GSSetConstantBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D10Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *GSSetShader )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10GeometryShader *pShader); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D10Device1 * This, + /* [annotation] */ + __in D3D10_PRIMITIVE_TOPOLOGY Topology); + + void ( STDMETHODCALLTYPE *VSSetShaderResources )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *VSSetSamplers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10Predicate *pPredicate, + /* [annotation] */ + __in BOOL PredicateValue); + + void ( STDMETHODCALLTYPE *GSSetShaderResources )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D10ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *GSSetSamplers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D10SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __in_ecount_opt(NumViews) ID3D10RenderTargetView *const *ppRenderTargetViews, + /* [annotation] */ + __in_opt ID3D10DepthStencilView *pDepthStencilView); + + void ( STDMETHODCALLTYPE *OMSetBlendState )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10BlendState *pBlendState, + /* [annotation] */ + __in const FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __in UINT SampleMask); + + void ( STDMETHODCALLTYPE *OMSetDepthStencilState )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10DepthStencilState *pDepthStencilState, + /* [annotation] */ + __in UINT StencilRef); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, + /* [annotation] */ + __in_ecount_opt(NumBuffers) ID3D10Buffer *const *ppSOTargets, + /* [annotation] */ + __in_ecount_opt(NumBuffers) const UINT *pOffsets); + + void ( STDMETHODCALLTYPE *DrawAuto )( + ID3D10Device1 * This); + + void ( STDMETHODCALLTYPE *RSSetState )( + ID3D10Device1 * This, + /* [annotation] */ + __in_opt ID3D10RasterizerState *pRasterizerState); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + /* [annotation] */ + __in_ecount_opt(NumViewports) const D3D10_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + /* [annotation] */ + __in_ecount_opt(NumRects) const D3D10_RECT *pRects); + + void ( STDMETHODCALLTYPE *CopySubresourceRegion )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in UINT DstX, + /* [annotation] */ + __in UINT DstY, + /* [annotation] */ + __in UINT DstZ, + /* [annotation] */ + __in ID3D10Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in_opt const D3D10_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in ID3D10Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *UpdateSubresource )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in_opt const D3D10_BOX *pDstBox, + /* [annotation] */ + __in const void *pSrcData, + /* [annotation] */ + __in UINT SrcRowPitch, + /* [annotation] */ + __in UINT SrcDepthPitch); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10RenderTargetView *pRenderTargetView, + /* [annotation] */ + __in const FLOAT ColorRGBA[ 4 ]); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10DepthStencilView *pDepthStencilView, + /* [annotation] */ + __in UINT ClearFlags, + /* [annotation] */ + __in FLOAT Depth, + /* [annotation] */ + __in UINT8 Stencil); + + void ( STDMETHODCALLTYPE *GenerateMips )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10ShaderResourceView *pShaderResourceView); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in ID3D10Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *VSGetConstantBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *PSGetShaderResources )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *PSGetShader )( + ID3D10Device1 * This, + /* [annotation] */ + __out ID3D10PixelShader **ppPixelShader); + + void ( STDMETHODCALLTYPE *PSGetSamplers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *VSGetShader )( + ID3D10Device1 * This, + /* [annotation] */ + __out ID3D10VertexShader **ppVertexShader); + + void ( STDMETHODCALLTYPE *PSGetConstantBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *IAGetInputLayout )( + ID3D10Device1 * This, + /* [annotation] */ + __out ID3D10InputLayout **ppInputLayout); + + void ( STDMETHODCALLTYPE *IAGetVertexBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D10Buffer **ppVertexBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pStrides, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets); + + void ( STDMETHODCALLTYPE *IAGetIndexBuffer )( + ID3D10Device1 * This, + /* [annotation] */ + __out_opt ID3D10Buffer **pIndexBuffer, + /* [annotation] */ + __out_opt DXGI_FORMAT *Format, + /* [annotation] */ + __out_opt UINT *Offset); + + void ( STDMETHODCALLTYPE *GSGetConstantBuffers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D10Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *GSGetShader )( + ID3D10Device1 * This, + /* [annotation] */ + __out ID3D10GeometryShader **ppGeometryShader); + + void ( STDMETHODCALLTYPE *IAGetPrimitiveTopology )( + ID3D10Device1 * This, + /* [annotation] */ + __out D3D10_PRIMITIVE_TOPOLOGY *pTopology); + + void ( STDMETHODCALLTYPE *VSGetShaderResources )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *VSGetSamplers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *GetPredication )( + ID3D10Device1 * This, + /* [annotation] */ + __out_opt ID3D10Predicate **ppPredicate, + /* [annotation] */ + __out_opt BOOL *pPredicateValue); + + void ( STDMETHODCALLTYPE *GSGetShaderResources )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D10ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *GSGetSamplers )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D10SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *OMGetRenderTargets )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __out_ecount_opt(NumViews) ID3D10RenderTargetView **ppRenderTargetViews, + /* [annotation] */ + __out_opt ID3D10DepthStencilView **ppDepthStencilView); + + void ( STDMETHODCALLTYPE *OMGetBlendState )( + ID3D10Device1 * This, + /* [annotation] */ + __out_opt ID3D10BlendState **ppBlendState, + /* [annotation] */ + __out_opt FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __out_opt UINT *pSampleMask); + + void ( STDMETHODCALLTYPE *OMGetDepthStencilState )( + ID3D10Device1 * This, + /* [annotation] */ + __out_opt ID3D10DepthStencilState **ppDepthStencilState, + /* [annotation] */ + __out_opt UINT *pStencilRef); + + void ( STDMETHODCALLTYPE *SOGetTargets )( + ID3D10Device1 * This, + /* [annotation] */ + __in_range( 0, D3D10_SO_BUFFER_SLOT_COUNT ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D10Buffer **ppSOTargets, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets); + + void ( STDMETHODCALLTYPE *RSGetState )( + ID3D10Device1 * This, + /* [annotation] */ + __out ID3D10RasterizerState **ppRasterizerState); + + void ( STDMETHODCALLTYPE *RSGetViewports )( + ID3D10Device1 * This, + /* [annotation] */ + __inout /*_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *NumViewports, + /* [annotation] */ + __out_ecount_opt(*NumViewports) D3D10_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSGetScissorRects )( + ID3D10Device1 * This, + /* [annotation] */ + __inout /*_range(0, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *NumRects, + /* [annotation] */ + __out_ecount_opt(*NumRects) D3D10_RECT *pRects); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D10Device1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetExceptionMode )( + ID3D10Device1 * This, + UINT RaiseFlags); + + UINT ( STDMETHODCALLTYPE *GetExceptionMode )( + ID3D10Device1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D10Device1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D10Device1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D10Device1 * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D10Device1 * This); + + void ( STDMETHODCALLTYPE *Flush )( + ID3D10Device1 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateBuffer )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_BUFFER_DESC *pDesc, + /* [annotation] */ + __in_opt const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D10Buffer **ppBuffer); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture1D )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_TEXTURE1D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture1D **ppTexture1D); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture2D )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_TEXTURE2D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture2D **ppTexture2D); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture3D )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_TEXTURE3D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels) const D3D10_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out ID3D10Texture3D **ppTexture3D); + + HRESULT ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10ShaderResourceView **ppSRView); + + HRESULT ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_RENDER_TARGET_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10RenderTargetView **ppRTView); + + HRESULT ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_DEPTH_STENCIL_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D10DepthStencilView **ppDepthStencilView); + + HRESULT ( STDMETHODCALLTYPE *CreateInputLayout )( + ID3D10Device1 * This, + /* [annotation] */ + __in_ecount(NumElements) const D3D10_INPUT_ELEMENT_DESC *pInputElementDescs, + /* [annotation] */ + __in_range( 0, D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ) UINT NumElements, + /* [annotation] */ + __in const void *pShaderBytecodeWithInputSignature, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10InputLayout **ppInputLayout); + + HRESULT ( STDMETHODCALLTYPE *CreateVertexShader )( + ID3D10Device1 * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10VertexShader **ppVertexShader); + + HRESULT ( STDMETHODCALLTYPE *CreateGeometryShader )( + ID3D10Device1 * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10GeometryShader **ppGeometryShader); + + HRESULT ( STDMETHODCALLTYPE *CreateGeometryShaderWithStreamOutput )( + ID3D10Device1 * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_ecount_opt(NumEntries) const D3D10_SO_DECLARATION_ENTRY *pSODeclaration, + /* [annotation] */ + __in_range( 0, D3D10_SO_SINGLE_BUFFER_COMPONENT_LIMIT ) UINT NumEntries, + /* [annotation] */ + __in UINT OutputStreamStride, + /* [annotation] */ + __out_opt ID3D10GeometryShader **ppGeometryShader); + + HRESULT ( STDMETHODCALLTYPE *CreatePixelShader )( + ID3D10Device1 * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D10PixelShader **ppPixelShader); + + HRESULT ( STDMETHODCALLTYPE *CreateBlendState )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_BLEND_DESC *pBlendStateDesc, + /* [annotation] */ + __out_opt ID3D10BlendState **ppBlendState); + + HRESULT ( STDMETHODCALLTYPE *CreateDepthStencilState )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_DEPTH_STENCIL_DESC *pDepthStencilDesc, + /* [annotation] */ + __out_opt ID3D10DepthStencilState **ppDepthStencilState); + + HRESULT ( STDMETHODCALLTYPE *CreateRasterizerState )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_RASTERIZER_DESC *pRasterizerDesc, + /* [annotation] */ + __out_opt ID3D10RasterizerState **ppRasterizerState); + + HRESULT ( STDMETHODCALLTYPE *CreateSamplerState )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_SAMPLER_DESC *pSamplerDesc, + /* [annotation] */ + __out_opt ID3D10SamplerState **ppSamplerState); + + HRESULT ( STDMETHODCALLTYPE *CreateQuery )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_QUERY_DESC *pQueryDesc, + /* [annotation] */ + __out_opt ID3D10Query **ppQuery); + + HRESULT ( STDMETHODCALLTYPE *CreatePredicate )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_QUERY_DESC *pPredicateDesc, + /* [annotation] */ + __out_opt ID3D10Predicate **ppPredicate); + + HRESULT ( STDMETHODCALLTYPE *CreateCounter )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_COUNTER_DESC *pCounterDesc, + /* [annotation] */ + __out_opt ID3D10Counter **ppCounter); + + HRESULT ( STDMETHODCALLTYPE *CheckFormatSupport )( + ID3D10Device1 * This, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __out UINT *pFormatSupport); + + HRESULT ( STDMETHODCALLTYPE *CheckMultisampleQualityLevels )( + ID3D10Device1 * This, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT SampleCount, + /* [annotation] */ + __out UINT *pNumQualityLevels); + + void ( STDMETHODCALLTYPE *CheckCounterInfo )( + ID3D10Device1 * This, + /* [annotation] */ + __out D3D10_COUNTER_INFO *pCounterInfo); + + HRESULT ( STDMETHODCALLTYPE *CheckCounter )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_COUNTER_DESC *pDesc, + /* [annotation] */ + __out D3D10_COUNTER_TYPE *pType, + /* [annotation] */ + __out UINT *pActiveCounters, + /* [annotation] */ + __out_ecount_opt(*pNameLength) LPSTR szName, + /* [annotation] */ + __inout_opt UINT *pNameLength, + /* [annotation] */ + __out_ecount_opt(*pUnitsLength) LPSTR szUnits, + /* [annotation] */ + __inout_opt UINT *pUnitsLength, + /* [annotation] */ + __out_ecount_opt(*pDescriptionLength) LPSTR szDescription, + /* [annotation] */ + __inout_opt UINT *pDescriptionLength); + + UINT ( STDMETHODCALLTYPE *GetCreationFlags )( + ID3D10Device1 * This); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedResource )( + ID3D10Device1 * This, + /* [annotation] */ + __in HANDLE hResource, + /* [annotation] */ + __in REFIID ReturnedInterface, + /* [annotation] */ + __out_opt void **ppResource); + + void ( STDMETHODCALLTYPE *SetTextFilterSize )( + ID3D10Device1 * This, + /* [annotation] */ + __in UINT Width, + /* [annotation] */ + __in UINT Height); + + void ( STDMETHODCALLTYPE *GetTextFilterSize )( + ID3D10Device1 * This, + /* [annotation] */ + __out_opt UINT *pWidth, + /* [annotation] */ + __out_opt UINT *pHeight); + + HRESULT ( STDMETHODCALLTYPE *CreateShaderResourceView1 )( + ID3D10Device1 * This, + /* [annotation] */ + __in ID3D10Resource *pResource, + /* [annotation] */ + __in_opt const D3D10_SHADER_RESOURCE_VIEW_DESC1 *pDesc, + /* [annotation] */ + __out_opt ID3D10ShaderResourceView1 **ppSRView); + + HRESULT ( STDMETHODCALLTYPE *CreateBlendState1 )( + ID3D10Device1 * This, + /* [annotation] */ + __in const D3D10_BLEND_DESC1 *pBlendStateDesc, + /* [annotation] */ + __out_opt ID3D10BlendState1 **ppBlendState); + + D3D10_FEATURE_LEVEL1 ( STDMETHODCALLTYPE *GetFeatureLevel )( + ID3D10Device1 * This); + + END_INTERFACE + } ID3D10Device1Vtbl; + + interface ID3D10Device1 + { + CONST_VTBL struct ID3D10Device1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Device1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Device1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Device1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Device1_VSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> VSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device1_PSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> PSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device1_PSSetShader(This,pPixelShader) \ + ( (This)->lpVtbl -> PSSetShader(This,pPixelShader) ) + +#define ID3D10Device1_PSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> PSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device1_VSSetShader(This,pVertexShader) \ + ( (This)->lpVtbl -> VSSetShader(This,pVertexShader) ) + +#define ID3D10Device1_DrawIndexed(This,IndexCount,StartIndexLocation,BaseVertexLocation) \ + ( (This)->lpVtbl -> DrawIndexed(This,IndexCount,StartIndexLocation,BaseVertexLocation) ) + +#define ID3D10Device1_Draw(This,VertexCount,StartVertexLocation) \ + ( (This)->lpVtbl -> Draw(This,VertexCount,StartVertexLocation) ) + +#define ID3D10Device1_PSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> PSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device1_IASetInputLayout(This,pInputLayout) \ + ( (This)->lpVtbl -> IASetInputLayout(This,pInputLayout) ) + +#define ID3D10Device1_IASetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) ) + +#define ID3D10Device1_IASetIndexBuffer(This,pIndexBuffer,Format,Offset) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pIndexBuffer,Format,Offset) ) + +#define ID3D10Device1_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D10Device1_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D10Device1_GSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> GSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device1_GSSetShader(This,pShader) \ + ( (This)->lpVtbl -> GSSetShader(This,pShader) ) + +#define ID3D10Device1_IASetPrimitiveTopology(This,Topology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,Topology) ) + +#define ID3D10Device1_VSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> VSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device1_VSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> VSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device1_SetPredication(This,pPredicate,PredicateValue) \ + ( (This)->lpVtbl -> SetPredication(This,pPredicate,PredicateValue) ) + +#define ID3D10Device1_GSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> GSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device1_GSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> GSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device1_OMSetRenderTargets(This,NumViews,ppRenderTargetViews,pDepthStencilView) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumViews,ppRenderTargetViews,pDepthStencilView) ) + +#define ID3D10Device1_OMSetBlendState(This,pBlendState,BlendFactor,SampleMask) \ + ( (This)->lpVtbl -> OMSetBlendState(This,pBlendState,BlendFactor,SampleMask) ) + +#define ID3D10Device1_OMSetDepthStencilState(This,pDepthStencilState,StencilRef) \ + ( (This)->lpVtbl -> OMSetDepthStencilState(This,pDepthStencilState,StencilRef) ) + +#define ID3D10Device1_SOSetTargets(This,NumBuffers,ppSOTargets,pOffsets) \ + ( (This)->lpVtbl -> SOSetTargets(This,NumBuffers,ppSOTargets,pOffsets) ) + +#define ID3D10Device1_DrawAuto(This) \ + ( (This)->lpVtbl -> DrawAuto(This) ) + +#define ID3D10Device1_RSSetState(This,pRasterizerState) \ + ( (This)->lpVtbl -> RSSetState(This,pRasterizerState) ) + +#define ID3D10Device1_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D10Device1_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D10Device1_CopySubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,DstZ,pSrcResource,SrcSubresource,pSrcBox) \ + ( (This)->lpVtbl -> CopySubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,DstZ,pSrcResource,SrcSubresource,pSrcBox) ) + +#define ID3D10Device1_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D10Device1_UpdateSubresource(This,pDstResource,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) \ + ( (This)->lpVtbl -> UpdateSubresource(This,pDstResource,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) ) + +#define ID3D10Device1_ClearRenderTargetView(This,pRenderTargetView,ColorRGBA) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,pRenderTargetView,ColorRGBA) ) + +#define ID3D10Device1_ClearDepthStencilView(This,pDepthStencilView,ClearFlags,Depth,Stencil) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,pDepthStencilView,ClearFlags,Depth,Stencil) ) + +#define ID3D10Device1_GenerateMips(This,pShaderResourceView) \ + ( (This)->lpVtbl -> GenerateMips(This,pShaderResourceView) ) + +#define ID3D10Device1_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D10Device1_VSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> VSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device1_PSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> PSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device1_PSGetShader(This,ppPixelShader) \ + ( (This)->lpVtbl -> PSGetShader(This,ppPixelShader) ) + +#define ID3D10Device1_PSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> PSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device1_VSGetShader(This,ppVertexShader) \ + ( (This)->lpVtbl -> VSGetShader(This,ppVertexShader) ) + +#define ID3D10Device1_PSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> PSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device1_IAGetInputLayout(This,ppInputLayout) \ + ( (This)->lpVtbl -> IAGetInputLayout(This,ppInputLayout) ) + +#define ID3D10Device1_IAGetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) \ + ( (This)->lpVtbl -> IAGetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) ) + +#define ID3D10Device1_IAGetIndexBuffer(This,pIndexBuffer,Format,Offset) \ + ( (This)->lpVtbl -> IAGetIndexBuffer(This,pIndexBuffer,Format,Offset) ) + +#define ID3D10Device1_GSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> GSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D10Device1_GSGetShader(This,ppGeometryShader) \ + ( (This)->lpVtbl -> GSGetShader(This,ppGeometryShader) ) + +#define ID3D10Device1_IAGetPrimitiveTopology(This,pTopology) \ + ( (This)->lpVtbl -> IAGetPrimitiveTopology(This,pTopology) ) + +#define ID3D10Device1_VSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> VSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device1_VSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> VSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device1_GetPredication(This,ppPredicate,pPredicateValue) \ + ( (This)->lpVtbl -> GetPredication(This,ppPredicate,pPredicateValue) ) + +#define ID3D10Device1_GSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> GSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D10Device1_GSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> GSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D10Device1_OMGetRenderTargets(This,NumViews,ppRenderTargetViews,ppDepthStencilView) \ + ( (This)->lpVtbl -> OMGetRenderTargets(This,NumViews,ppRenderTargetViews,ppDepthStencilView) ) + +#define ID3D10Device1_OMGetBlendState(This,ppBlendState,BlendFactor,pSampleMask) \ + ( (This)->lpVtbl -> OMGetBlendState(This,ppBlendState,BlendFactor,pSampleMask) ) + +#define ID3D10Device1_OMGetDepthStencilState(This,ppDepthStencilState,pStencilRef) \ + ( (This)->lpVtbl -> OMGetDepthStencilState(This,ppDepthStencilState,pStencilRef) ) + +#define ID3D10Device1_SOGetTargets(This,NumBuffers,ppSOTargets,pOffsets) \ + ( (This)->lpVtbl -> SOGetTargets(This,NumBuffers,ppSOTargets,pOffsets) ) + +#define ID3D10Device1_RSGetState(This,ppRasterizerState) \ + ( (This)->lpVtbl -> RSGetState(This,ppRasterizerState) ) + +#define ID3D10Device1_RSGetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSGetViewports(This,NumViewports,pViewports) ) + +#define ID3D10Device1_RSGetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSGetScissorRects(This,NumRects,pRects) ) + +#define ID3D10Device1_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D10Device1_SetExceptionMode(This,RaiseFlags) \ + ( (This)->lpVtbl -> SetExceptionMode(This,RaiseFlags) ) + +#define ID3D10Device1_GetExceptionMode(This) \ + ( (This)->lpVtbl -> GetExceptionMode(This) ) + +#define ID3D10Device1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D10Device1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D10Device1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D10Device1_ClearState(This) \ + ( (This)->lpVtbl -> ClearState(This) ) + +#define ID3D10Device1_Flush(This) \ + ( (This)->lpVtbl -> Flush(This) ) + +#define ID3D10Device1_CreateBuffer(This,pDesc,pInitialData,ppBuffer) \ + ( (This)->lpVtbl -> CreateBuffer(This,pDesc,pInitialData,ppBuffer) ) + +#define ID3D10Device1_CreateTexture1D(This,pDesc,pInitialData,ppTexture1D) \ + ( (This)->lpVtbl -> CreateTexture1D(This,pDesc,pInitialData,ppTexture1D) ) + +#define ID3D10Device1_CreateTexture2D(This,pDesc,pInitialData,ppTexture2D) \ + ( (This)->lpVtbl -> CreateTexture2D(This,pDesc,pInitialData,ppTexture2D) ) + +#define ID3D10Device1_CreateTexture3D(This,pDesc,pInitialData,ppTexture3D) \ + ( (This)->lpVtbl -> CreateTexture3D(This,pDesc,pInitialData,ppTexture3D) ) + +#define ID3D10Device1_CreateShaderResourceView(This,pResource,pDesc,ppSRView) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,ppSRView) ) + +#define ID3D10Device1_CreateRenderTargetView(This,pResource,pDesc,ppRTView) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,ppRTView) ) + +#define ID3D10Device1_CreateDepthStencilView(This,pResource,pDesc,ppDepthStencilView) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,ppDepthStencilView) ) + +#define ID3D10Device1_CreateInputLayout(This,pInputElementDescs,NumElements,pShaderBytecodeWithInputSignature,BytecodeLength,ppInputLayout) \ + ( (This)->lpVtbl -> CreateInputLayout(This,pInputElementDescs,NumElements,pShaderBytecodeWithInputSignature,BytecodeLength,ppInputLayout) ) + +#define ID3D10Device1_CreateVertexShader(This,pShaderBytecode,BytecodeLength,ppVertexShader) \ + ( (This)->lpVtbl -> CreateVertexShader(This,pShaderBytecode,BytecodeLength,ppVertexShader) ) + +#define ID3D10Device1_CreateGeometryShader(This,pShaderBytecode,BytecodeLength,ppGeometryShader) \ + ( (This)->lpVtbl -> CreateGeometryShader(This,pShaderBytecode,BytecodeLength,ppGeometryShader) ) + +#define ID3D10Device1_CreateGeometryShaderWithStreamOutput(This,pShaderBytecode,BytecodeLength,pSODeclaration,NumEntries,OutputStreamStride,ppGeometryShader) \ + ( (This)->lpVtbl -> CreateGeometryShaderWithStreamOutput(This,pShaderBytecode,BytecodeLength,pSODeclaration,NumEntries,OutputStreamStride,ppGeometryShader) ) + +#define ID3D10Device1_CreatePixelShader(This,pShaderBytecode,BytecodeLength,ppPixelShader) \ + ( (This)->lpVtbl -> CreatePixelShader(This,pShaderBytecode,BytecodeLength,ppPixelShader) ) + +#define ID3D10Device1_CreateBlendState(This,pBlendStateDesc,ppBlendState) \ + ( (This)->lpVtbl -> CreateBlendState(This,pBlendStateDesc,ppBlendState) ) + +#define ID3D10Device1_CreateDepthStencilState(This,pDepthStencilDesc,ppDepthStencilState) \ + ( (This)->lpVtbl -> CreateDepthStencilState(This,pDepthStencilDesc,ppDepthStencilState) ) + +#define ID3D10Device1_CreateRasterizerState(This,pRasterizerDesc,ppRasterizerState) \ + ( (This)->lpVtbl -> CreateRasterizerState(This,pRasterizerDesc,ppRasterizerState) ) + +#define ID3D10Device1_CreateSamplerState(This,pSamplerDesc,ppSamplerState) \ + ( (This)->lpVtbl -> CreateSamplerState(This,pSamplerDesc,ppSamplerState) ) + +#define ID3D10Device1_CreateQuery(This,pQueryDesc,ppQuery) \ + ( (This)->lpVtbl -> CreateQuery(This,pQueryDesc,ppQuery) ) + +#define ID3D10Device1_CreatePredicate(This,pPredicateDesc,ppPredicate) \ + ( (This)->lpVtbl -> CreatePredicate(This,pPredicateDesc,ppPredicate) ) + +#define ID3D10Device1_CreateCounter(This,pCounterDesc,ppCounter) \ + ( (This)->lpVtbl -> CreateCounter(This,pCounterDesc,ppCounter) ) + +#define ID3D10Device1_CheckFormatSupport(This,Format,pFormatSupport) \ + ( (This)->lpVtbl -> CheckFormatSupport(This,Format,pFormatSupport) ) + +#define ID3D10Device1_CheckMultisampleQualityLevels(This,Format,SampleCount,pNumQualityLevels) \ + ( (This)->lpVtbl -> CheckMultisampleQualityLevels(This,Format,SampleCount,pNumQualityLevels) ) + +#define ID3D10Device1_CheckCounterInfo(This,pCounterInfo) \ + ( (This)->lpVtbl -> CheckCounterInfo(This,pCounterInfo) ) + +#define ID3D10Device1_CheckCounter(This,pDesc,pType,pActiveCounters,szName,pNameLength,szUnits,pUnitsLength,szDescription,pDescriptionLength) \ + ( (This)->lpVtbl -> CheckCounter(This,pDesc,pType,pActiveCounters,szName,pNameLength,szUnits,pUnitsLength,szDescription,pDescriptionLength) ) + +#define ID3D10Device1_GetCreationFlags(This) \ + ( (This)->lpVtbl -> GetCreationFlags(This) ) + +#define ID3D10Device1_OpenSharedResource(This,hResource,ReturnedInterface,ppResource) \ + ( (This)->lpVtbl -> OpenSharedResource(This,hResource,ReturnedInterface,ppResource) ) + +#define ID3D10Device1_SetTextFilterSize(This,Width,Height) \ + ( (This)->lpVtbl -> SetTextFilterSize(This,Width,Height) ) + +#define ID3D10Device1_GetTextFilterSize(This,pWidth,pHeight) \ + ( (This)->lpVtbl -> GetTextFilterSize(This,pWidth,pHeight) ) + + +#define ID3D10Device1_CreateShaderResourceView1(This,pResource,pDesc,ppSRView) \ + ( (This)->lpVtbl -> CreateShaderResourceView1(This,pResource,pDesc,ppSRView) ) + +#define ID3D10Device1_CreateBlendState1(This,pBlendStateDesc,ppBlendState) \ + ( (This)->lpVtbl -> CreateBlendState1(This,pBlendStateDesc,ppBlendState) ) + +#define ID3D10Device1_GetFeatureLevel(This) \ + ( (This)->lpVtbl -> GetFeatureLevel(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Device1_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10_1_0000_0003 */ +/* [local] */ + +#define D3D10_1_SDK_VERSION ( ( 0 + 0x20 ) ) + +#include "d3d10_1shader.h" + +/////////////////////////////////////////////////////////////////////////// +// D3D10CreateDevice1 +// ------------------ +// +// pAdapter +// If NULL, D3D10CreateDevice1 will choose the primary adapter and +// create a new instance from a temporarily created IDXGIFactory. +// If non-NULL, D3D10CreateDevice1 will register the appropriate +// device, if necessary (via IDXGIAdapter::RegisterDrver), before +// creating the device. +// DriverType +// Specifies the driver type to be created: hardware, reference or +// null. +// Software +// HMODULE of a DLL implementing a software rasterizer. Must be NULL for +// non-Software driver types. +// Flags +// Any of those documented for D3D10CreateDeviceAndSwapChain1. +// HardwareLevel +// Any of those documented for D3D10CreateDeviceAndSwapChain1. +// SDKVersion +// SDK version. Use the D3D10_1_SDK_VERSION macro. +// ppDevice +// Pointer to returned interface. +// +// Return Values +// Any of those documented for +// CreateDXGIFactory +// IDXGIFactory::EnumAdapters +// IDXGIAdapter::RegisterDriver +// D3D10CreateDevice1 +// +/////////////////////////////////////////////////////////////////////////// +typedef HRESULT (WINAPI* PFN_D3D10_CREATE_DEVICE1)(IDXGIAdapter *, + D3D10_DRIVER_TYPE, HMODULE, UINT, D3D10_FEATURE_LEVEL1, UINT, ID3D10Device1**); + +HRESULT WINAPI D3D10CreateDevice1( + IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + D3D10_FEATURE_LEVEL1 HardwareLevel, + UINT SDKVersion, + ID3D10Device1 **ppDevice); + +/////////////////////////////////////////////////////////////////////////// +// D3D10CreateDeviceAndSwapChain1 +// ------------------------------ +// +// ppAdapter +// If NULL, D3D10CreateDevice1 will choose the primary adapter and +// create a new instance from a temporarily created IDXGIFactory. +// If non-NULL, D3D10CreateDevice1 will register the appropriate +// device, if necessary (via IDXGIAdapter::RegisterDrver), before +// creating the device. +// DriverType +// Specifies the driver type to be created: hardware, reference or +// null. +// Software +// HMODULE of a DLL implementing a software rasterizer. Must be NULL for +// non-Software driver types. +// Flags +// Any of those documented for D3D10CreateDevice1. +// HardwareLevel +// Any of: +// D3D10_CREATE_LEVEL_10_0 +// D3D10_CREATE_LEVEL_10_1 +// SDKVersion +// SDK version. Use the D3D10_1_SDK_VERSION macro. +// pSwapChainDesc +// Swap chain description, may be NULL. +// ppSwapChain +// Pointer to returned interface. May be NULL. +// ppDevice +// Pointer to returned interface. +// +// Return Values +// Any of those documented for +// CreateDXGIFactory +// IDXGIFactory::EnumAdapters +// IDXGIAdapter::RegisterDriver +// D3D10CreateDevice1 +// IDXGIFactory::CreateSwapChain +// +/////////////////////////////////////////////////////////////////////////// +typedef HRESULT (WINAPI* PFN_D3D10_CREATE_DEVICE_AND_SWAP_CHAIN1)(IDXGIAdapter *, + D3D10_DRIVER_TYPE, HMODULE, UINT, D3D10_FEATURE_LEVEL1, UINT, DXGI_SWAP_CHAIN_DESC *, IDXGISwapChain **, ID3D10Device1 **); + +HRESULT WINAPI D3D10CreateDeviceAndSwapChain1( + IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + D3D10_FEATURE_LEVEL1 HardwareLevel, + UINT SDKVersion, + DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + IDXGISwapChain **ppSwapChain, + ID3D10Device1 **ppDevice); +DEFINE_GUID(IID_ID3D10BlendState1,0xEDAD8D99,0x8A35,0x4d6d,0x85,0x66,0x2E,0xA2,0x76,0xCD,0xE1,0x61); +DEFINE_GUID(IID_ID3D10ShaderResourceView1,0x9B7E4C87,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Device1,0x9B7E4C8F,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0003_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10_1_0000_0003_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/dxsdk/Include/D3D10_1shader.h b/dxsdk/Include/D3D10_1shader.h new file mode 100644 index 0000000..2726f8f --- /dev/null +++ b/dxsdk/Include/D3D10_1shader.h @@ -0,0 +1,301 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3D10_1Shader.h +// Content: D3D10.1 Shader Types and APIs +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3D10_1SHADER_H__ +#define __D3D10_1SHADER_H__ + +#include "d3d10shader.h" + +//---------------------------------------------------------------------------- +// Shader debugging structures +//---------------------------------------------------------------------------- + +typedef enum _D3D10_SHADER_DEBUG_REGTYPE +{ + D3D10_SHADER_DEBUG_REG_INPUT, + D3D10_SHADER_DEBUG_REG_OUTPUT, + D3D10_SHADER_DEBUG_REG_CBUFFER, + D3D10_SHADER_DEBUG_REG_TBUFFER, + D3D10_SHADER_DEBUG_REG_TEMP, + D3D10_SHADER_DEBUG_REG_TEMPARRAY, + D3D10_SHADER_DEBUG_REG_TEXTURE, + D3D10_SHADER_DEBUG_REG_SAMPLER, + D3D10_SHADER_DEBUG_REG_IMMEDIATECBUFFER, + D3D10_SHADER_DEBUG_REG_LITERAL, + D3D10_SHADER_DEBUG_REG_UNUSED, + D3D11_SHADER_DEBUG_REG_INTERFACE_POINTERS, + D3D11_SHADER_DEBUG_REG_UAV, + D3D10_SHADER_DEBUG_REG_FORCE_DWORD = 0x7fffffff, +} D3D10_SHADER_DEBUG_REGTYPE; + +typedef enum _D3D10_SHADER_DEBUG_SCOPETYPE +{ + D3D10_SHADER_DEBUG_SCOPE_GLOBAL, + D3D10_SHADER_DEBUG_SCOPE_BLOCK, + D3D10_SHADER_DEBUG_SCOPE_FORLOOP, + D3D10_SHADER_DEBUG_SCOPE_STRUCT, + D3D10_SHADER_DEBUG_SCOPE_FUNC_PARAMS, + D3D10_SHADER_DEBUG_SCOPE_STATEBLOCK, + D3D10_SHADER_DEBUG_SCOPE_NAMESPACE, + D3D10_SHADER_DEBUG_SCOPE_ANNOTATION, + D3D10_SHADER_DEBUG_SCOPE_FORCE_DWORD = 0x7fffffff, +} D3D10_SHADER_DEBUG_SCOPETYPE; + +typedef enum _D3D10_SHADER_DEBUG_VARTYPE +{ + D3D10_SHADER_DEBUG_VAR_VARIABLE, + D3D10_SHADER_DEBUG_VAR_FUNCTION, + D3D10_SHADER_DEBUG_VAR_FORCE_DWORD = 0x7fffffff, +} D3D10_SHADER_DEBUG_VARTYPE; + +///////////////////////////////////////////////////////////////////// +// These are the serialized structures that get written to the file +///////////////////////////////////////////////////////////////////// + +typedef struct _D3D10_SHADER_DEBUG_TOKEN_INFO +{ + UINT File; // offset into file list + UINT Line; // line # + UINT Column; // column # + + UINT TokenLength; + UINT TokenId; // offset to LPCSTR of length TokenLength in string datastore +} D3D10_SHADER_DEBUG_TOKEN_INFO; + +// Variable list +typedef struct _D3D10_SHADER_DEBUG_VAR_INFO +{ + // Index into token list for declaring identifier + UINT TokenId; + D3D10_SHADER_VARIABLE_TYPE Type; + // register and component for this variable, only valid/necessary for arrays + UINT Register; + UINT Component; + // gives the original variable that declared this variable + UINT ScopeVar; + // this variable's offset in its ScopeVar + UINT ScopeVarOffset; +} D3D10_SHADER_DEBUG_VAR_INFO; + +typedef struct _D3D10_SHADER_DEBUG_INPUT_INFO +{ + // index into array of variables of variable to initialize + UINT Var; + // input, cbuffer, tbuffer + D3D10_SHADER_DEBUG_REGTYPE InitialRegisterSet; + // set to cbuffer or tbuffer slot, geometry shader input primitive #, + // identifying register for indexable temp, or -1 + UINT InitialBank; + // -1 if temp, otherwise gives register in register set + UINT InitialRegister; + // -1 if temp, otherwise gives component + UINT InitialComponent; + // initial value if literal + UINT InitialValue; +} D3D10_SHADER_DEBUG_INPUT_INFO; + +typedef struct _D3D10_SHADER_DEBUG_SCOPEVAR_INFO +{ + // Index into variable token + UINT TokenId; + + D3D10_SHADER_DEBUG_VARTYPE VarType; // variable or function (different namespaces) + D3D10_SHADER_VARIABLE_CLASS Class; + UINT Rows; // number of rows (matrices) + UINT Columns; // number of columns (vectors and matrices) + + // In an array of structures, one struct member scope is provided, and + // you'll have to add the array stride times the index to the variable + // index you find, then find that variable in this structure's list of + // variables. + + // gives a scope to look up struct members. -1 if not a struct + UINT StructMemberScope; + + // number of array indices + UINT uArrayIndices; // a[3][2][1] has 3 indices + // maximum array index for each index + // offset to UINT[uArrayIndices] in UINT datastore + UINT ArrayElements; // a[3][2][1] has {3, 2, 1} + // how many variables each array index moves + // offset to UINT[uArrayIndices] in UINT datastore + UINT ArrayStrides; // a[3][2][1] has {2, 1, 1} + + UINT uVariables; + // index of the first variable, later variables are offsets from this one + UINT uFirstVariable; +} D3D10_SHADER_DEBUG_SCOPEVAR_INFO; + +// scope data, this maps variable names to debug variables (useful for the watch window) +typedef struct _D3D10_SHADER_DEBUG_SCOPE_INFO +{ + D3D10_SHADER_DEBUG_SCOPETYPE ScopeType; + UINT Name; // offset to name of scope in strings list + UINT uNameLen; // length of name string + UINT uVariables; + UINT VariableData; // Offset to UINT[uVariables] indexing the Scope Variable list +} D3D10_SHADER_DEBUG_SCOPE_INFO; + +// instruction outputs +typedef struct _D3D10_SHADER_DEBUG_OUTPUTVAR +{ + // index variable being written to, if -1 it's not going to a variable + UINT Var; + // range data that the compiler expects to be true + UINT uValueMin, uValueMax; + INT iValueMin, iValueMax; + FLOAT fValueMin, fValueMax; + + BOOL bNaNPossible, bInfPossible; +} D3D10_SHADER_DEBUG_OUTPUTVAR; + +typedef struct _D3D10_SHADER_DEBUG_OUTPUTREG_INFO +{ + // Only temp, indexable temp, and output are valid here + D3D10_SHADER_DEBUG_REGTYPE OutputRegisterSet; + // -1 means no output + UINT OutputReg; + // if a temp array, identifier for which one + UINT TempArrayReg; + // -1 means masked out + UINT OutputComponents[4]; + D3D10_SHADER_DEBUG_OUTPUTVAR OutputVars[4]; + // when indexing the output, get the value of this register, then add + // that to uOutputReg. If uIndexReg is -1, then there is no index. + // find the variable whose register is the sum (by looking in the ScopeVar) + // and component matches, then set it. This should only happen for indexable + // temps and outputs. + UINT IndexReg; + UINT IndexComp; +} D3D10_SHADER_DEBUG_OUTPUTREG_INFO; + +// per instruction data +typedef struct _D3D10_SHADER_DEBUG_INST_INFO +{ + UINT Id; // Which instruction this is in the bytecode + UINT Opcode; // instruction type + + // 0, 1, or 2 + UINT uOutputs; + + // up to two outputs per instruction + D3D10_SHADER_DEBUG_OUTPUTREG_INFO pOutputs[2]; + + // index into the list of tokens for this instruction's token + UINT TokenId; + + // how many function calls deep this instruction is + UINT NestingLevel; + + // list of scopes from outer-most to inner-most + // Number of scopes + UINT Scopes; + UINT ScopeInfo; // Offset to UINT[uScopes] specifying indices of the ScopeInfo Array + + // list of variables accessed by this instruction + // Number of variables + UINT AccessedVars; + UINT AccessedVarsInfo; // Offset to UINT[AccessedVars] specifying indices of the ScopeVariableInfo Array +} D3D10_SHADER_DEBUG_INST_INFO; + +typedef struct _D3D10_SHADER_DEBUG_FILE_INFO +{ + UINT FileName; // Offset to LPCSTR for file name + UINT FileNameLen; // Length of file name + UINT FileData; // Offset to LPCSTR of length FileLen + UINT FileLen; // Length of file +} D3D10_SHADER_DEBUG_FILE_INFO; + +typedef struct _D3D10_SHADER_DEBUG_INFO +{ + UINT Size; // sizeof(D3D10_SHADER_DEBUG_INFO) + UINT Creator; // Offset to LPCSTR for compiler version + UINT EntrypointName; // Offset to LPCSTR for Entry point name + UINT ShaderTarget; // Offset to LPCSTR for shader target + UINT CompileFlags; // flags used to compile + UINT Files; // number of included files + UINT FileInfo; // Offset to D3D10_SHADER_DEBUG_FILE_INFO[Files] + UINT Instructions; // number of instructions + UINT InstructionInfo; // Offset to D3D10_SHADER_DEBUG_INST_INFO[Instructions] + UINT Variables; // number of variables + UINT VariableInfo; // Offset to D3D10_SHADER_DEBUG_VAR_INFO[Variables] + UINT InputVariables; // number of variables to initialize before running + UINT InputVariableInfo; // Offset to D3D10_SHADER_DEBUG_INPUT_INFO[InputVariables] + UINT Tokens; // number of tokens to initialize + UINT TokenInfo; // Offset to D3D10_SHADER_DEBUG_TOKEN_INFO[Tokens] + UINT Scopes; // number of scopes + UINT ScopeInfo; // Offset to D3D10_SHADER_DEBUG_SCOPE_INFO[Scopes] + UINT ScopeVariables; // number of variables declared + UINT ScopeVariableInfo; // Offset to D3D10_SHADER_DEBUG_SCOPEVAR_INFO[Scopes] + UINT UintOffset; // Offset to the UINT datastore, all UINT offsets are from this offset + UINT StringOffset; // Offset to the string datastore, all string offsets are from this offset +} D3D10_SHADER_DEBUG_INFO; + +//---------------------------------------------------------------------------- +// ID3D10ShaderReflection1: +//---------------------------------------------------------------------------- + +// +// Interface definitions +// + +typedef interface ID3D10ShaderReflection1 ID3D10ShaderReflection1; +typedef interface ID3D10ShaderReflection1 *LPD3D10SHADERREFLECTION1; + +// {C3457783-A846-47CE-9520-CEA6F66E7447} +DEFINE_GUID(IID_ID3D10ShaderReflection1, +0xc3457783, 0xa846, 0x47ce, 0x95, 0x20, 0xce, 0xa6, 0xf6, 0x6e, 0x74, 0x47); + +#undef INTERFACE +#define INTERFACE ID3D10ShaderReflection1 + +DECLARE_INTERFACE_(ID3D10ShaderReflection1, IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD(GetResourceBindingDesc)(THIS_ UINT ResourceIndex, D3D10_SHADER_INPUT_BIND_DESC *pDesc) PURE; + + STDMETHOD(GetInputParameterDesc)(THIS_ UINT ParameterIndex, D3D10_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + STDMETHOD(GetOutputParameterDesc)(THIS_ UINT ParameterIndex, D3D10_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10ShaderReflectionVariable*, GetVariableByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD(GetResourceBindingDescByName)(THIS_ LPCSTR Name, D3D10_SHADER_INPUT_BIND_DESC *pDesc) PURE; + + STDMETHOD(GetMovInstructionCount)(THIS_ UINT* pCount) PURE; + STDMETHOD(GetMovcInstructionCount)(THIS_ UINT* pCount) PURE; + STDMETHOD(GetConversionInstructionCount)(THIS_ UINT* pCount) PURE; + STDMETHOD(GetBitwiseInstructionCount)(THIS_ UINT* pCount) PURE; + + STDMETHOD(GetGSInputPrimitive)(THIS_ D3D10_PRIMITIVE* pPrim) PURE; + STDMETHOD(IsLevel9Shader)(THIS_ BOOL* pbLevel9Shader) PURE; + STDMETHOD(IsSampleFrequencyShader)(THIS_ BOOL* pbSampleFrequency) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3D10_1SHADER_H__ + diff --git a/dxsdk/Include/D3D10effect.h b/dxsdk/Include/D3D10effect.h new file mode 100644 index 0000000..7387854 --- /dev/null +++ b/dxsdk/Include/D3D10effect.h @@ -0,0 +1,1455 @@ + +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3D10Effect.h +// Content: D3D10 Stateblock/Effect Types & APIs +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3D10EFFECT_H__ +#define __D3D10EFFECT_H__ + +#include "d3d10.h" + +////////////////////////////////////////////////////////////////////////////// +// File contents: +// +// 1) Stateblock enums, structs, interfaces, flat APIs +// 2) Effect enums, structs, interfaces, flat APIs +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3D10_DEVICE_STATE_TYPES: +// +// Used in ID3D10StateBlockMask function calls +// +//---------------------------------------------------------------------------- + +typedef enum _D3D10_DEVICE_STATE_TYPES +{ + + D3D10_DST_SO_BUFFERS=1, // Single-value state (atomical gets/sets) + D3D10_DST_OM_RENDER_TARGETS, // Single-value state (atomical gets/sets) + D3D10_DST_OM_DEPTH_STENCIL_STATE, // Single-value state + D3D10_DST_OM_BLEND_STATE, // Single-value state + + D3D10_DST_VS, // Single-value state + D3D10_DST_VS_SAMPLERS, // Count: D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT + D3D10_DST_VS_SHADER_RESOURCES, // Count: D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT + D3D10_DST_VS_CONSTANT_BUFFERS, // Count: + + D3D10_DST_GS, // Single-value state + D3D10_DST_GS_SAMPLERS, // Count: D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT + D3D10_DST_GS_SHADER_RESOURCES, // Count: D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT + D3D10_DST_GS_CONSTANT_BUFFERS, // Count: D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT + + D3D10_DST_PS, // Single-value state + D3D10_DST_PS_SAMPLERS, // Count: D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT + D3D10_DST_PS_SHADER_RESOURCES, // Count: D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT + D3D10_DST_PS_CONSTANT_BUFFERS, // Count: D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT + + D3D10_DST_IA_VERTEX_BUFFERS, // Count: D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT + D3D10_DST_IA_INDEX_BUFFER, // Single-value state + D3D10_DST_IA_INPUT_LAYOUT, // Single-value state + D3D10_DST_IA_PRIMITIVE_TOPOLOGY, // Single-value state + + D3D10_DST_RS_VIEWPORTS, // Single-value state (atomical gets/sets) + D3D10_DST_RS_SCISSOR_RECTS, // Single-value state (atomical gets/sets) + D3D10_DST_RS_RASTERIZER_STATE, // Single-value state + + D3D10_DST_PREDICATION, // Single-value state +} D3D10_DEVICE_STATE_TYPES; + +//---------------------------------------------------------------------------- +// D3D10_DEVICE_STATE_TYPES: +// +// Used in ID3D10StateBlockMask function calls +// +//---------------------------------------------------------------------------- + +#ifndef D3D10_BYTES_FROM_BITS +#define D3D10_BYTES_FROM_BITS(x) (((x) + 7) / 8) +#endif // D3D10_BYTES_FROM_BITS + +typedef struct _D3D10_STATE_BLOCK_MASK +{ + BYTE VS; + BYTE VSSamplers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT)]; + BYTE VSShaderResources[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE VSConstantBuffers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)]; + + BYTE GS; + BYTE GSSamplers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT)]; + BYTE GSShaderResources[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE GSConstantBuffers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)]; + + BYTE PS; + BYTE PSSamplers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT)]; + BYTE PSShaderResources[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE PSConstantBuffers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)]; + + BYTE IAVertexBuffers[D3D10_BYTES_FROM_BITS(D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE IAIndexBuffer; + BYTE IAInputLayout; + BYTE IAPrimitiveTopology; + + BYTE OMRenderTargets; + BYTE OMDepthStencilState; + BYTE OMBlendState; + + BYTE RSViewports; + BYTE RSScissorRects; + BYTE RSRasterizerState; + + BYTE SOBuffers; + + BYTE Predication; +} D3D10_STATE_BLOCK_MASK; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10StateBlock ////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10StateBlock ID3D10StateBlock; +typedef interface ID3D10StateBlock *LPD3D10STATEBLOCK; + +// {0803425A-57F5-4dd6-9465-A87570834A08} +DEFINE_GUID(IID_ID3D10StateBlock, +0x803425a, 0x57f5, 0x4dd6, 0x94, 0x65, 0xa8, 0x75, 0x70, 0x83, 0x4a, 0x8); + +#undef INTERFACE +#define INTERFACE ID3D10StateBlock + +DECLARE_INTERFACE_(ID3D10StateBlock, IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD(Capture)(THIS) PURE; + STDMETHOD(Apply)(THIS) PURE; + STDMETHOD(ReleaseAllDeviceObjects)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ ID3D10Device **ppDevice) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//---------------------------------------------------------------------------- +// D3D10_STATE_BLOCK_MASK and manipulation functions +// ------------------------------------------------- +// +// These functions exist to facilitate working with the D3D10_STATE_BLOCK_MASK +// structure. +// +// D3D10_STATE_BLOCK_MASK *pResult or *pMask +// The state block mask to operate on +// +// D3D10_STATE_BLOCK_MASK *pA, *pB +// The source state block masks for the binary union/intersect/difference +// operations. +// +// D3D10_DEVICE_STATE_TYPES StateType +// The specific state type to enable/disable/query +// +// UINT RangeStart, RangeLength, Entry +// The specific bit or range of bits for a given state type to operate on. +// Consult the comments for D3D10_DEVICE_STATE_TYPES and +// D3D10_STATE_BLOCK_MASK for information on the valid bit ranges for +// each state. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10StateBlockMaskUnion(D3D10_STATE_BLOCK_MASK *pA, D3D10_STATE_BLOCK_MASK *pB, D3D10_STATE_BLOCK_MASK *pResult); +HRESULT WINAPI D3D10StateBlockMaskIntersect(D3D10_STATE_BLOCK_MASK *pA, D3D10_STATE_BLOCK_MASK *pB, D3D10_STATE_BLOCK_MASK *pResult); +HRESULT WINAPI D3D10StateBlockMaskDifference(D3D10_STATE_BLOCK_MASK *pA, D3D10_STATE_BLOCK_MASK *pB, D3D10_STATE_BLOCK_MASK *pResult); +HRESULT WINAPI D3D10StateBlockMaskEnableCapture(D3D10_STATE_BLOCK_MASK *pMask, D3D10_DEVICE_STATE_TYPES StateType, UINT RangeStart, UINT RangeLength); +HRESULT WINAPI D3D10StateBlockMaskDisableCapture(D3D10_STATE_BLOCK_MASK *pMask, D3D10_DEVICE_STATE_TYPES StateType, UINT RangeStart, UINT RangeLength); +HRESULT WINAPI D3D10StateBlockMaskEnableAll(D3D10_STATE_BLOCK_MASK *pMask); +HRESULT WINAPI D3D10StateBlockMaskDisableAll(D3D10_STATE_BLOCK_MASK *pMask); +BOOL WINAPI D3D10StateBlockMaskGetSetting(D3D10_STATE_BLOCK_MASK *pMask, D3D10_DEVICE_STATE_TYPES StateType, UINT Entry); + +//---------------------------------------------------------------------------- +// D3D10CreateStateBlock +// --------------------- +// +// Creates a state block object based on the mask settings specified +// in a D3D10_STATE_BLOCK_MASK structure. +// +// ID3D10Device *pDevice +// The device interface to associate with this state block +// +// D3D10_STATE_BLOCK_MASK *pStateBlockMask +// A bit mask whose settings are used to generate a state block +// object. +// +// ID3D10StateBlock **ppStateBlock +// The resulting state block object. This object will save/restore +// only those pieces of state that were set in the state block +// bit mask +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10CreateStateBlock(ID3D10Device *pDevice, D3D10_STATE_BLOCK_MASK *pStateBlockMask, ID3D10StateBlock **ppStateBlock); + +#ifdef __cplusplus +} +#endif //__cplusplus + +//---------------------------------------------------------------------------- +// D3D10_COMPILE & D3D10_EFFECT flags: +// ------------------------------------- +// +// These flags are passed in when creating an effect, and affect +// either compilation behavior or runtime effect behavior +// +// D3D10_EFFECT_COMPILE_CHILD_EFFECT +// Compile this .fx file to a child effect. Child effects have no initializers +// for any shared values as these are initialied in the master effect (pool). +// +// D3D10_EFFECT_COMPILE_ALLOW_SLOW_OPS +// By default, performance mode is enabled. Performance mode disallows +// mutable state objects by preventing non-literal expressions from appearing in +// state object definitions. Specifying this flag will disable the mode and allow +// for mutable state objects. +// +// D3D10_EFFECT_SINGLE_THREADED +// Do not attempt to synchronize with other threads loading effects into the +// same pool. +// +//---------------------------------------------------------------------------- + +#define D3D10_EFFECT_COMPILE_CHILD_EFFECT (1 << 0) +#define D3D10_EFFECT_COMPILE_ALLOW_SLOW_OPS (1 << 1) +#define D3D10_EFFECT_SINGLE_THREADED (1 << 3) + + +//---------------------------------------------------------------------------- +// D3D10_EFFECT_VARIABLE flags: +// ---------------------------- +// +// These flags describe an effect variable (global or annotation), +// and are returned in D3D10_EFFECT_VARIABLE_DESC::Flags. +// +// D3D10_EFFECT_VARIABLE_POOLED +// Indicates that the this variable or constant buffer resides +// in an effect pool. If this flag is not set, then the variable resides +// in a standalone effect (if ID3D10Effect::GetPool returns NULL) +// or a child effect (if ID3D10Effect::GetPool returns non-NULL) +// +// D3D10_EFFECT_VARIABLE_ANNOTATION +// Indicates that this is an annotation on a technique, pass, or global +// variable. Otherwise, this is a global variable. Annotations cannot +// be shared. +// +// D3D10_EFFECT_VARIABLE_EXPLICIT_BIND_POINT +// Indicates that the variable has been explicitly bound using the +// register keyword. +//---------------------------------------------------------------------------- + +#define D3D10_EFFECT_VARIABLE_POOLED (1 << 0) +#define D3D10_EFFECT_VARIABLE_ANNOTATION (1 << 1) +#define D3D10_EFFECT_VARIABLE_EXPLICIT_BIND_POINT (1 << 2) + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectType ////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3D10_EFFECT_TYPE_DESC: +// +// Retrieved by ID3D10EffectType::GetDesc() +//---------------------------------------------------------------------------- + +typedef struct _D3D10_EFFECT_TYPE_DESC +{ + LPCSTR TypeName; // Name of the type + // (e.g. "float4" or "MyStruct") + + D3D10_SHADER_VARIABLE_CLASS Class; // (e.g. scalar, vector, object, etc.) + D3D10_SHADER_VARIABLE_TYPE Type; // (e.g. float, texture, vertexshader, etc.) + + UINT Elements; // Number of elements in this type + // (0 if not an array) + UINT Members; // Number of members + // (0 if not a structure) + UINT Rows; // Number of rows in this type + // (0 if not a numeric primitive) + UINT Columns; // Number of columns in this type + // (0 if not a numeric primitive) + + UINT PackedSize; // Number of bytes required to represent + // this data type, when tightly packed + UINT UnpackedSize; // Number of bytes occupied by this data + // type, when laid out in a constant buffer + UINT Stride; // Number of bytes to seek between elements, + // when laid out in a constant buffer +} D3D10_EFFECT_TYPE_DESC; + +typedef interface ID3D10EffectType ID3D10EffectType; +typedef interface ID3D10EffectType *LPD3D10EFFECTTYPE; + +// {4E9E1DDC-CD9D-4772-A837-00180B9B88FD} +DEFINE_GUID(IID_ID3D10EffectType, +0x4e9e1ddc, 0xcd9d, 0x4772, 0xa8, 0x37, 0x0, 0x18, 0xb, 0x9b, 0x88, 0xfd); + +#undef INTERFACE +#define INTERFACE ID3D10EffectType + +DECLARE_INTERFACE(ID3D10EffectType) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_TYPE_DESC *pDesc) PURE; + STDMETHOD_(ID3D10EffectType*, GetMemberTypeByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectType*, GetMemberTypeByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectType*, GetMemberTypeBySemantic)(THIS_ LPCSTR Semantic) PURE; + STDMETHOD_(LPCSTR, GetMemberName)(THIS_ UINT Index) PURE; + STDMETHOD_(LPCSTR, GetMemberSemantic)(THIS_ UINT Index) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectVariable ////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3D10_EFFECT_VARIABLE_DESC: +// +// Retrieved by ID3D10EffectVariable::GetDesc() +//---------------------------------------------------------------------------- + +typedef struct _D3D10_EFFECT_VARIABLE_DESC +{ + LPCSTR Name; // Name of this variable, annotation, + // or structure member + LPCSTR Semantic; // Semantic string of this variable + // or structure member (NULL for + // annotations or if not present) + + UINT Flags; // D3D10_EFFECT_VARIABLE_* flags + UINT Annotations; // Number of annotations on this variable + // (always 0 for annotations) + + UINT BufferOffset; // Offset into containing cbuffer or tbuffer + // (always 0 for annotations or variables + // not in constant buffers) + + UINT ExplicitBindPoint; // Used if the variable has been explicitly bound + // using the register keyword. Check Flags for + // D3D10_EFFECT_VARIABLE_EXPLICIT_BIND_POINT; +} D3D10_EFFECT_VARIABLE_DESC; + +typedef interface ID3D10EffectVariable ID3D10EffectVariable; +typedef interface ID3D10EffectVariable *LPD3D10EFFECTVARIABLE; + +// {AE897105-00E6-45bf-BB8E-281DD6DB8E1B} +DEFINE_GUID(IID_ID3D10EffectVariable, +0xae897105, 0xe6, 0x45bf, 0xbb, 0x8e, 0x28, 0x1d, 0xd6, 0xdb, 0x8e, 0x1b); + +#undef INTERFACE +#define INTERFACE ID3D10EffectVariable + +// Forward defines +typedef interface ID3D10EffectScalarVariable ID3D10EffectScalarVariable; +typedef interface ID3D10EffectVectorVariable ID3D10EffectVectorVariable; +typedef interface ID3D10EffectMatrixVariable ID3D10EffectMatrixVariable; +typedef interface ID3D10EffectStringVariable ID3D10EffectStringVariable; +typedef interface ID3D10EffectShaderResourceVariable ID3D10EffectShaderResourceVariable; +typedef interface ID3D10EffectRenderTargetViewVariable ID3D10EffectRenderTargetViewVariable; +typedef interface ID3D10EffectDepthStencilViewVariable ID3D10EffectDepthStencilViewVariable; +typedef interface ID3D10EffectConstantBuffer ID3D10EffectConstantBuffer; +typedef interface ID3D10EffectShaderVariable ID3D10EffectShaderVariable; +typedef interface ID3D10EffectBlendVariable ID3D10EffectBlendVariable; +typedef interface ID3D10EffectDepthStencilVariable ID3D10EffectDepthStencilVariable; +typedef interface ID3D10EffectRasterizerVariable ID3D10EffectRasterizerVariable; +typedef interface ID3D10EffectSamplerVariable ID3D10EffectSamplerVariable; + +DECLARE_INTERFACE(ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectScalarVariable //////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectScalarVariable ID3D10EffectScalarVariable; +typedef interface ID3D10EffectScalarVariable *LPD3D10EFFECTSCALARVARIABLE; + +// {00E48F7B-D2C8-49e8-A86C-022DEE53431F} +DEFINE_GUID(IID_ID3D10EffectScalarVariable, +0xe48f7b, 0xd2c8, 0x49e8, 0xa8, 0x6c, 0x2, 0x2d, 0xee, 0x53, 0x43, 0x1f); + +#undef INTERFACE +#define INTERFACE ID3D10EffectScalarVariable + +DECLARE_INTERFACE_(ID3D10EffectScalarVariable, ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT ByteOffset, UINT ByteCount) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT ByteOffset, UINT ByteCount) PURE; + + STDMETHOD(SetFloat)(THIS_ float Value) PURE; + STDMETHOD(GetFloat)(THIS_ float *pValue) PURE; + + STDMETHOD(SetFloatArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetFloatArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(SetInt)(THIS_ int Value) PURE; + STDMETHOD(GetInt)(THIS_ int *pValue) PURE; + + STDMETHOD(SetIntArray)(THIS_ int *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetIntArray)(THIS_ int *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(SetBool)(THIS_ BOOL Value) PURE; + STDMETHOD(GetBool)(THIS_ BOOL *pValue) PURE; + + STDMETHOD(SetBoolArray)(THIS_ BOOL *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetBoolArray)(THIS_ BOOL *pData, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectVectorVariable //////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectVectorVariable ID3D10EffectVectorVariable; +typedef interface ID3D10EffectVectorVariable *LPD3D10EFFECTVECTORVARIABLE; + +// {62B98C44-1F82-4c67-BCD0-72CF8F217E81} +DEFINE_GUID(IID_ID3D10EffectVectorVariable, +0x62b98c44, 0x1f82, 0x4c67, 0xbc, 0xd0, 0x72, 0xcf, 0x8f, 0x21, 0x7e, 0x81); + +#undef INTERFACE +#define INTERFACE ID3D10EffectVectorVariable + +DECLARE_INTERFACE_(ID3D10EffectVectorVariable, ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT ByteOffset, UINT ByteCount) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT ByteOffset, UINT ByteCount) PURE; + + STDMETHOD(SetBoolVector) (THIS_ BOOL *pData) PURE; + STDMETHOD(SetIntVector) (THIS_ int *pData) PURE; + STDMETHOD(SetFloatVector)(THIS_ float *pData) PURE; + + STDMETHOD(GetBoolVector) (THIS_ BOOL *pData) PURE; + STDMETHOD(GetIntVector) (THIS_ int *pData) PURE; + STDMETHOD(GetFloatVector)(THIS_ float *pData) PURE; + + STDMETHOD(SetBoolVectorArray) (THIS_ BOOL *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(SetIntVectorArray) (THIS_ int *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(SetFloatVectorArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(GetBoolVectorArray) (THIS_ BOOL *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetIntVectorArray) (THIS_ int *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetFloatVectorArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectMatrixVariable //////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectMatrixVariable ID3D10EffectMatrixVariable; +typedef interface ID3D10EffectMatrixVariable *LPD3D10EFFECTMATRIXVARIABLE; + +// {50666C24-B82F-4eed-A172-5B6E7E8522E0} +DEFINE_GUID(IID_ID3D10EffectMatrixVariable, +0x50666c24, 0xb82f, 0x4eed, 0xa1, 0x72, 0x5b, 0x6e, 0x7e, 0x85, 0x22, 0xe0); + +#undef INTERFACE +#define INTERFACE ID3D10EffectMatrixVariable + +DECLARE_INTERFACE_(ID3D10EffectMatrixVariable, ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT ByteOffset, UINT ByteCount) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT ByteOffset, UINT ByteCount) PURE; + + STDMETHOD(SetMatrix)(THIS_ float *pData) PURE; + STDMETHOD(GetMatrix)(THIS_ float *pData) PURE; + + STDMETHOD(SetMatrixArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(SetMatrixTranspose)(THIS_ float *pData) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ float *pData) PURE; + + STDMETHOD(SetMatrixTransposeArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ float *pData, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectStringVariable //////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectStringVariable ID3D10EffectStringVariable; +typedef interface ID3D10EffectStringVariable *LPD3D10EFFECTSTRINGVARIABLE; + +// {71417501-8DF9-4e0a-A78A-255F9756BAFF} +DEFINE_GUID(IID_ID3D10EffectStringVariable, +0x71417501, 0x8df9, 0x4e0a, 0xa7, 0x8a, 0x25, 0x5f, 0x97, 0x56, 0xba, 0xff); + +#undef INTERFACE +#define INTERFACE ID3D10EffectStringVariable + +DECLARE_INTERFACE_(ID3D10EffectStringVariable, ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(GetString)(THIS_ LPCSTR *ppString) PURE; + STDMETHOD(GetStringArray)(THIS_ LPCSTR *ppStrings, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectShaderResourceVariable //////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectShaderResourceVariable ID3D10EffectShaderResourceVariable; +typedef interface ID3D10EffectShaderResourceVariable *LPD3D10EFFECTSHADERRESOURCEVARIABLE; + +// {C0A7157B-D872-4b1d-8073-EFC2ACD4B1FC} +DEFINE_GUID(IID_ID3D10EffectShaderResourceVariable, +0xc0a7157b, 0xd872, 0x4b1d, 0x80, 0x73, 0xef, 0xc2, 0xac, 0xd4, 0xb1, 0xfc); + + +#undef INTERFACE +#define INTERFACE ID3D10EffectShaderResourceVariable + +DECLARE_INTERFACE_(ID3D10EffectShaderResourceVariable, ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(SetResource)(THIS_ ID3D10ShaderResourceView *pResource) PURE; + STDMETHOD(GetResource)(THIS_ ID3D10ShaderResourceView **ppResource) PURE; + + STDMETHOD(SetResourceArray)(THIS_ ID3D10ShaderResourceView **ppResources, UINT Offset, UINT Count) PURE; + STDMETHOD(GetResourceArray)(THIS_ ID3D10ShaderResourceView **ppResources, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectRenderTargetViewVariable ////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectRenderTargetViewVariable ID3D10EffectRenderTargetViewVariable; +typedef interface ID3D10EffectRenderTargetViewVariable *LPD3D10EFFECTRENDERTARGETVIEWVARIABLE; + +// {28CA0CC3-C2C9-40bb-B57F-67B737122B17} +DEFINE_GUID(IID_ID3D10EffectRenderTargetViewVariable, +0x28ca0cc3, 0xc2c9, 0x40bb, 0xb5, 0x7f, 0x67, 0xb7, 0x37, 0x12, 0x2b, 0x17); + +#undef INTERFACE +#define INTERFACE ID3D10EffectRenderTargetViewVariable + +DECLARE_INTERFACE_(ID3D10EffectRenderTargetViewVariable, ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(SetRenderTarget)(THIS_ ID3D10RenderTargetView *pResource) PURE; + STDMETHOD(GetRenderTarget)(THIS_ ID3D10RenderTargetView **ppResource) PURE; + + STDMETHOD(SetRenderTargetArray)(THIS_ ID3D10RenderTargetView **ppResources, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRenderTargetArray)(THIS_ ID3D10RenderTargetView **ppResources, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectDepthStencilViewVariable ////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectDepthStencilViewVariable ID3D10EffectDepthStencilViewVariable; +typedef interface ID3D10EffectDepthStencilViewVariable *LPD3D10EFFECTDEPTHSTENCILVIEWVARIABLE; + +// {3E02C918-CC79-4985-B622-2D92AD701623} +DEFINE_GUID(IID_ID3D10EffectDepthStencilViewVariable, +0x3e02c918, 0xcc79, 0x4985, 0xb6, 0x22, 0x2d, 0x92, 0xad, 0x70, 0x16, 0x23); + +#undef INTERFACE +#define INTERFACE ID3D10EffectDepthStencilViewVariable + +DECLARE_INTERFACE_(ID3D10EffectDepthStencilViewVariable, ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(SetDepthStencil)(THIS_ ID3D10DepthStencilView *pResource) PURE; + STDMETHOD(GetDepthStencil)(THIS_ ID3D10DepthStencilView **ppResource) PURE; + + STDMETHOD(SetDepthStencilArray)(THIS_ ID3D10DepthStencilView **ppResources, UINT Offset, UINT Count) PURE; + STDMETHOD(GetDepthStencilArray)(THIS_ ID3D10DepthStencilView **ppResources, UINT Offset, UINT Count) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectConstantBuffer //////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectConstantBuffer ID3D10EffectConstantBuffer; +typedef interface ID3D10EffectConstantBuffer *LPD3D10EFFECTCONSTANTBUFFER; + +// {56648F4D-CC8B-4444-A5AD-B5A3D76E91B3} +DEFINE_GUID(IID_ID3D10EffectConstantBuffer, +0x56648f4d, 0xcc8b, 0x4444, 0xa5, 0xad, 0xb5, 0xa3, 0xd7, 0x6e, 0x91, 0xb3); + +#undef INTERFACE +#define INTERFACE ID3D10EffectConstantBuffer + +DECLARE_INTERFACE_(ID3D10EffectConstantBuffer, ID3D10EffectVariable) +{ + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(SetConstantBuffer)(THIS_ ID3D10Buffer *pConstantBuffer) PURE; + STDMETHOD(GetConstantBuffer)(THIS_ ID3D10Buffer **ppConstantBuffer) PURE; + + STDMETHOD(SetTextureBuffer)(THIS_ ID3D10ShaderResourceView *pTextureBuffer) PURE; + STDMETHOD(GetTextureBuffer)(THIS_ ID3D10ShaderResourceView **ppTextureBuffer) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectShaderVariable //////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3D10_EFFECT_SHADER_DESC: +// +// Retrieved by ID3D10EffectShaderVariable::GetShaderDesc() +//---------------------------------------------------------------------------- + +typedef struct _D3D10_EFFECT_SHADER_DESC +{ + CONST BYTE *pInputSignature; // Passed into CreateInputLayout, + // valid on VS and GS only + + BOOL IsInline; // Is this an anonymous shader variable + // resulting from an inline shader assignment? + + + // -- The following fields are not valid after Optimize() -- + CONST BYTE *pBytecode; // Shader bytecode + UINT BytecodeLength; + + LPCSTR SODecl; // Stream out declaration string (for GS with SO) + + UINT NumInputSignatureEntries; // Number of entries in the input signature + UINT NumOutputSignatureEntries; // Number of entries in the output signature +} D3D10_EFFECT_SHADER_DESC; + + +typedef interface ID3D10EffectShaderVariable ID3D10EffectShaderVariable; +typedef interface ID3D10EffectShaderVariable *LPD3D10EFFECTSHADERVARIABLE; + +// {80849279-C799-4797-8C33-0407A07D9E06} +DEFINE_GUID(IID_ID3D10EffectShaderVariable, +0x80849279, 0xc799, 0x4797, 0x8c, 0x33, 0x4, 0x7, 0xa0, 0x7d, 0x9e, 0x6); + +#undef INTERFACE +#define INTERFACE ID3D10EffectShaderVariable + +DECLARE_INTERFACE_(ID3D10EffectShaderVariable, ID3D10EffectVariable) +{ + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(GetShaderDesc)(THIS_ UINT ShaderIndex, D3D10_EFFECT_SHADER_DESC *pDesc) PURE; + + STDMETHOD(GetVertexShader)(THIS_ UINT ShaderIndex, ID3D10VertexShader **ppVS) PURE; + STDMETHOD(GetGeometryShader)(THIS_ UINT ShaderIndex, ID3D10GeometryShader **ppGS) PURE; + STDMETHOD(GetPixelShader)(THIS_ UINT ShaderIndex, ID3D10PixelShader **ppPS) PURE; + + STDMETHOD(GetInputSignatureElementDesc)(THIS_ UINT ShaderIndex, UINT Element, D3D10_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + STDMETHOD(GetOutputSignatureElementDesc)(THIS_ UINT ShaderIndex, UINT Element, D3D10_SIGNATURE_PARAMETER_DESC *pDesc) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectBlendVariable ///////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectBlendVariable ID3D10EffectBlendVariable; +typedef interface ID3D10EffectBlendVariable *LPD3D10EFFECTBLENDVARIABLE; + +// {1FCD2294-DF6D-4eae-86B3-0E9160CFB07B} +DEFINE_GUID(IID_ID3D10EffectBlendVariable, +0x1fcd2294, 0xdf6d, 0x4eae, 0x86, 0xb3, 0xe, 0x91, 0x60, 0xcf, 0xb0, 0x7b); + +#undef INTERFACE +#define INTERFACE ID3D10EffectBlendVariable + +DECLARE_INTERFACE_(ID3D10EffectBlendVariable, ID3D10EffectVariable) +{ + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(GetBlendState)(THIS_ UINT Index, ID3D10BlendState **ppBlendState) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT Index, D3D10_BLEND_DESC *pBlendDesc) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectDepthStencilVariable ////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectDepthStencilVariable ID3D10EffectDepthStencilVariable; +typedef interface ID3D10EffectDepthStencilVariable *LPD3D10EFFECTDEPTHSTENCILVARIABLE; + +// {AF482368-330A-46a5-9A5C-01C71AF24C8D} +DEFINE_GUID(IID_ID3D10EffectDepthStencilVariable, +0xaf482368, 0x330a, 0x46a5, 0x9a, 0x5c, 0x1, 0xc7, 0x1a, 0xf2, 0x4c, 0x8d); + +#undef INTERFACE +#define INTERFACE ID3D10EffectDepthStencilVariable + +DECLARE_INTERFACE_(ID3D10EffectDepthStencilVariable, ID3D10EffectVariable) +{ + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(GetDepthStencilState)(THIS_ UINT Index, ID3D10DepthStencilState **ppDepthStencilState) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT Index, D3D10_DEPTH_STENCIL_DESC *pDepthStencilDesc) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectRasterizerVariable //////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectRasterizerVariable ID3D10EffectRasterizerVariable; +typedef interface ID3D10EffectRasterizerVariable *LPD3D10EFFECTRASTERIZERVARIABLE; + +// {21AF9F0E-4D94-4ea9-9785-2CB76B8C0B34} +DEFINE_GUID(IID_ID3D10EffectRasterizerVariable, +0x21af9f0e, 0x4d94, 0x4ea9, 0x97, 0x85, 0x2c, 0xb7, 0x6b, 0x8c, 0xb, 0x34); + +#undef INTERFACE +#define INTERFACE ID3D10EffectRasterizerVariable + +DECLARE_INTERFACE_(ID3D10EffectRasterizerVariable, ID3D10EffectVariable) +{ + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(GetRasterizerState)(THIS_ UINT Index, ID3D10RasterizerState **ppRasterizerState) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT Index, D3D10_RASTERIZER_DESC *pRasterizerDesc) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectSamplerVariable /////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectSamplerVariable ID3D10EffectSamplerVariable; +typedef interface ID3D10EffectSamplerVariable *LPD3D10EFFECTSAMPLERVARIABLE; + +// {6530D5C7-07E9-4271-A418-E7CE4BD1E480} +DEFINE_GUID(IID_ID3D10EffectSamplerVariable, +0x6530d5c7, 0x7e9, 0x4271, 0xa4, 0x18, 0xe7, 0xce, 0x4b, 0xd1, 0xe4, 0x80); + +#undef INTERFACE +#define INTERFACE ID3D10EffectSamplerVariable + +DECLARE_INTERFACE_(ID3D10EffectSamplerVariable, ID3D10EffectVariable) +{ + STDMETHOD_(ID3D10EffectType*, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetMemberByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetMemberBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetElement)(THIS_ UINT Index) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE; + + STDMETHOD_(ID3D10EffectScalarVariable*, AsScalar)(THIS) PURE; + STDMETHOD_(ID3D10EffectVectorVariable*, AsVector)(THIS) PURE; + STDMETHOD_(ID3D10EffectMatrixVariable*, AsMatrix)(THIS) PURE; + STDMETHOD_(ID3D10EffectStringVariable*, AsString)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE; + STDMETHOD_(ID3D10EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(ID3D10EffectShaderVariable*, AsShader)(THIS) PURE; + STDMETHOD_(ID3D10EffectBlendVariable*, AsBlend)(THIS) PURE; + STDMETHOD_(ID3D10EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE; + STDMETHOD_(ID3D10EffectRasterizerVariable*, AsRasterizer)(THIS) PURE; + STDMETHOD_(ID3D10EffectSamplerVariable*, AsSampler)(THIS) PURE; + + STDMETHOD(SetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *pData, UINT Offset, UINT Count) PURE; + + STDMETHOD(GetSampler)(THIS_ UINT Index, ID3D10SamplerState **ppSampler) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT Index, D3D10_SAMPLER_DESC *pSamplerDesc) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectPass ////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3D10_PASS_DESC: +// +// Retrieved by ID3D10EffectPass::GetDesc() +//---------------------------------------------------------------------------- + +typedef struct _D3D10_PASS_DESC +{ + LPCSTR Name; // Name of this pass (NULL if not anonymous) + UINT Annotations; // Number of annotations on this pass + + BYTE *pIAInputSignature; // Signature from VS or GS (if there is no VS) + // or NULL if neither exists + SIZE_T IAInputSignatureSize; // Singature size in bytes + + UINT StencilRef; // Specified in SetDepthStencilState() + UINT SampleMask; // Specified in SetBlendState() + FLOAT BlendFactor[4]; // Specified in SetBlendState() +} D3D10_PASS_DESC; + +//---------------------------------------------------------------------------- +// D3D10_PASS_SHADER_DESC: +// +// Retrieved by ID3D10EffectPass::Get**ShaderDesc() +//---------------------------------------------------------------------------- + +typedef struct _D3D10_PASS_SHADER_DESC +{ + ID3D10EffectShaderVariable *pShaderVariable; // The variable that this shader came from. + // If this is an inline shader assignment, + // the returned interface will be an + // anonymous shader variable, which is + // not retrievable any other way. It's + // name in the variable description will + // be "$Anonymous". + // If there is no assignment of this type in + // the pass block, pShaderVariable != NULL, + // but pShaderVariable->IsValid() == FALSE. + + UINT ShaderIndex; // The element of pShaderVariable (if an array) + // or 0 if not applicable +} D3D10_PASS_SHADER_DESC; + +typedef interface ID3D10EffectPass ID3D10EffectPass; +typedef interface ID3D10EffectPass *LPD3D10EFFECTPASS; + +// {5CFBEB89-1A06-46e0-B282-E3F9BFA36A54} +DEFINE_GUID(IID_ID3D10EffectPass, +0x5cfbeb89, 0x1a06, 0x46e0, 0xb2, 0x82, 0xe3, 0xf9, 0xbf, 0xa3, 0x6a, 0x54); + +#undef INTERFACE +#define INTERFACE ID3D10EffectPass + +DECLARE_INTERFACE(ID3D10EffectPass) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_PASS_DESC *pDesc) PURE; + + STDMETHOD(GetVertexShaderDesc)(THIS_ D3D10_PASS_SHADER_DESC *pDesc) PURE; + STDMETHOD(GetGeometryShaderDesc)(THIS_ D3D10_PASS_SHADER_DESC *pDesc) PURE; + STDMETHOD(GetPixelShaderDesc)(THIS_ D3D10_PASS_SHADER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD(Apply)(THIS_ UINT Flags) PURE; + + STDMETHOD(ComputeStateBlockMask)(THIS_ D3D10_STATE_BLOCK_MASK *pStateBlockMask) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectTechnique ///////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3D10_TECHNIQUE_DESC: +// +// Retrieved by ID3D10EffectTechnique::GetDesc() +//---------------------------------------------------------------------------- + +typedef struct _D3D10_TECHNIQUE_DESC +{ + LPCSTR Name; // Name of this technique (NULL if not anonymous) + UINT Passes; // Number of passes contained within + UINT Annotations; // Number of annotations on this technique +} D3D10_TECHNIQUE_DESC; + +typedef interface ID3D10EffectTechnique ID3D10EffectTechnique; +typedef interface ID3D10EffectTechnique *LPD3D10EFFECTTECHNIQUE; + +// {DB122CE8-D1C9-4292-B237-24ED3DE8B175} +DEFINE_GUID(IID_ID3D10EffectTechnique, +0xdb122ce8, 0xd1c9, 0x4292, 0xb2, 0x37, 0x24, 0xed, 0x3d, 0xe8, 0xb1, 0x75); + +#undef INTERFACE +#define INTERFACE ID3D10EffectTechnique + +DECLARE_INTERFACE(ID3D10EffectTechnique) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_TECHNIQUE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetAnnotationByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectPass*, GetPassByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectPass*, GetPassByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD(ComputeStateBlockMask)(THIS_ D3D10_STATE_BLOCK_MASK *pStateBlockMask) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10Effect ////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3D10_EFFECT_DESC: +// +// Retrieved by ID3D10Effect::GetDesc() +//---------------------------------------------------------------------------- + +typedef struct _D3D10_EFFECT_DESC +{ + + BOOL IsChildEffect; // TRUE if this is a child effect, + // FALSE if this is standalone or an effect pool. + + UINT ConstantBuffers; // Number of constant buffers in this effect, + // excluding the effect pool. + UINT SharedConstantBuffers; // Number of constant buffers shared in this + // effect's pool. + + UINT GlobalVariables; // Number of global variables in this effect, + // excluding the effect pool. + UINT SharedGlobalVariables; // Number of global variables shared in this + // effect's pool. + + UINT Techniques; // Number of techniques in this effect, + // excluding the effect pool. +} D3D10_EFFECT_DESC; + +typedef interface ID3D10Effect ID3D10Effect; +typedef interface ID3D10Effect *LPD3D10EFFECT; + +// {51B0CA8B-EC0B-4519-870D-8EE1CB5017C7} +DEFINE_GUID(IID_ID3D10Effect, +0x51b0ca8b, 0xec0b, 0x4519, 0x87, 0xd, 0x8e, 0xe1, 0xcb, 0x50, 0x17, 0xc7); + +#undef INTERFACE +#define INTERFACE ID3D10Effect + +DECLARE_INTERFACE_(ID3D10Effect, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(BOOL, IsPool)(THIS) PURE; + + // Managing D3D Device + STDMETHOD(GetDevice)(THIS_ ID3D10Device** ppDevice) PURE; + + // New Reflection APIs + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10EffectConstantBuffer*, GetConstantBufferByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectConstantBuffer*, GetConstantBufferByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD_(ID3D10EffectVariable*, GetVariableByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetVariableByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(ID3D10EffectVariable*, GetVariableBySemantic)(THIS_ LPCSTR Semantic) PURE; + + STDMETHOD_(ID3D10EffectTechnique*, GetTechniqueByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10EffectTechnique*, GetTechniqueByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD(Optimize)(THIS) PURE; + STDMETHOD_(BOOL, IsOptimized)(THIS) PURE; + +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3D10EffectPool ////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D10EffectPool ID3D10EffectPool; +typedef interface ID3D10EffectPool *LPD3D10EFFECTPOOL; + +// {9537AB04-3250-412e-8213-FCD2F8677933} +DEFINE_GUID(IID_ID3D10EffectPool, +0x9537ab04, 0x3250, 0x412e, 0x82, 0x13, 0xfc, 0xd2, 0xf8, 0x67, 0x79, 0x33); + +#undef INTERFACE +#define INTERFACE ID3D10EffectPool + +DECLARE_INTERFACE_(ID3D10EffectPool, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD_(ID3D10Effect*, AsEffect)(THIS) PURE; + + // No public methods +}; + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//---------------------------------------------------------------------------- +// D3D10CreateEffectFromXXXX: +// -------------------------- +// Creates an effect from a binary effect or file +// +// Parameters: +// +// [in] +// +// +// pData +// Blob of effect data, either ASCII (uncompiled, for D3D10CompileEffectFromMemory) or binary (compiled, for D3D10CreateEffect*) +// DataLength +// Length of the data blob +// +// pSrcFileName +// Name of the ASCII Effect file pData was obtained from +// +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// HLSLFlags +// Compilation flags pertaining to shaders and data types, honored by +// the HLSL compiler +// FXFlags +// Compilation flags pertaining to Effect compilation, honored +// by the Effect compiler +// pDevice +// Pointer to the D3D10 device on which to create Effect resources +// pEffectPool +// Pointer to an Effect pool to share variables with or NULL +// +// [out] +// +// ppEffect +// Address of the newly created Effect interface +// ppEffectPool +// Address of the newly created Effect pool interface +// ppErrors +// If non-NULL, address of a buffer with error messages that occurred +// during parsing or compilation +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10CompileEffectFromMemory(void *pData, SIZE_T DataLength, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, UINT HLSLFlags, UINT FXFlags, + ID3D10Blob **ppCompiledEffect, ID3D10Blob **ppErrors); + +HRESULT WINAPI D3D10CreateEffectFromMemory(void *pData, SIZE_T DataLength, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, ID3D10Effect **ppEffect); + +HRESULT WINAPI D3D10CreateEffectPoolFromMemory(void *pData, SIZE_T DataLength, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool **ppEffectPool); + + +//---------------------------------------------------------------------------- +// D3D10DisassembleEffect: +// ----------------------- +// Takes an effect interface, and returns a buffer containing text assembly. +// +// Parameters: +// pEffect +// Pointer to the runtime effect interface. +// EnableColorCode +// Emit HTML tags for color coding the output? +// ppDisassembly +// Returns a buffer containing the disassembled effect. +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10DisassembleEffect(ID3D10Effect *pEffect, BOOL EnableColorCode, ID3D10Blob **ppDisassembly); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3D10EFFECT_H__ + + diff --git a/dxsdk/Include/D3D10shader.h b/dxsdk/Include/D3D10shader.h new file mode 100644 index 0000000..d5a8a7f --- /dev/null +++ b/dxsdk/Include/D3D10shader.h @@ -0,0 +1,534 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3D10Shader.h +// Content: D3D10 Shader Types and APIs +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3D10SHADER_H__ +#define __D3D10SHADER_H__ + +#include "d3d10.h" + + +//--------------------------------------------------------------------------- +// D3D10_TX_VERSION: +// -------------- +// Version token used to create a procedural texture filler in effects +// Used by D3D10Fill[]TX functions +//--------------------------------------------------------------------------- +#define D3D10_TX_VERSION(_Major,_Minor) (('T' << 24) | ('X' << 16) | ((_Major) << 8) | (_Minor)) + + +//---------------------------------------------------------------------------- +// D3D10SHADER flags: +// ----------------- +// D3D10_SHADER_DEBUG +// Insert debug file/line/type/symbol information. +// +// D3D10_SHADER_SKIP_VALIDATION +// Do not validate the generated code against known capabilities and +// constraints. This option is only recommended when compiling shaders +// you KNOW will work. (ie. have compiled before without this option.) +// Shaders are always validated by D3D before they are set to the device. +// +// D3D10_SHADER_SKIP_OPTIMIZATION +// Instructs the compiler to skip optimization steps during code generation. +// Unless you are trying to isolate a problem in your code using this option +// is not recommended. +// +// D3D10_SHADER_PACK_MATRIX_ROW_MAJOR +// Unless explicitly specified, matrices will be packed in row-major order +// on input and output from the shader. +// +// D3D10_SHADER_PACK_MATRIX_COLUMN_MAJOR +// Unless explicitly specified, matrices will be packed in column-major +// order on input and output from the shader. This is generally more +// efficient, since it allows vector-matrix multiplication to be performed +// using a series of dot-products. +// +// D3D10_SHADER_PARTIAL_PRECISION +// Force all computations in resulting shader to occur at partial precision. +// This may result in faster evaluation of shaders on some hardware. +// +// D3D10_SHADER_FORCE_VS_SOFTWARE_NO_OPT +// Force compiler to compile against the next highest available software +// target for vertex shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3D10_SHADER_FORCE_PS_SOFTWARE_NO_OPT +// Force compiler to compile against the next highest available software +// target for pixel shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3D10_SHADER_NO_PRESHADER +// Disables Preshaders. Using this flag will cause the compiler to not +// pull out static expression for evaluation on the host cpu +// +// D3D10_SHADER_AVOID_FLOW_CONTROL +// Hint compiler to avoid flow-control constructs where possible. +// +// D3D10_SHADER_PREFER_FLOW_CONTROL +// Hint compiler to prefer flow-control constructs where possible. +// +// D3D10_SHADER_ENABLE_STRICTNESS +// By default, the HLSL/Effect compilers are not strict on deprecated syntax. +// Specifying this flag enables the strict mode. Deprecated syntax may be +// removed in a future release, and enabling syntax is a good way to make sure +// your shaders comply to the latest spec. +// +// D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY +// This enables older shaders to compile to 4_0 targets. +// +//---------------------------------------------------------------------------- + +#define D3D10_SHADER_DEBUG (1 << 0) +#define D3D10_SHADER_SKIP_VALIDATION (1 << 1) +#define D3D10_SHADER_SKIP_OPTIMIZATION (1 << 2) +#define D3D10_SHADER_PACK_MATRIX_ROW_MAJOR (1 << 3) +#define D3D10_SHADER_PACK_MATRIX_COLUMN_MAJOR (1 << 4) +#define D3D10_SHADER_PARTIAL_PRECISION (1 << 5) +#define D3D10_SHADER_FORCE_VS_SOFTWARE_NO_OPT (1 << 6) +#define D3D10_SHADER_FORCE_PS_SOFTWARE_NO_OPT (1 << 7) +#define D3D10_SHADER_NO_PRESHADER (1 << 8) +#define D3D10_SHADER_AVOID_FLOW_CONTROL (1 << 9) +#define D3D10_SHADER_PREFER_FLOW_CONTROL (1 << 10) +#define D3D10_SHADER_ENABLE_STRICTNESS (1 << 11) +#define D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY (1 << 12) +#define D3D10_SHADER_IEEE_STRICTNESS (1 << 13) +#define D3D10_SHADER_WARNINGS_ARE_ERRORS (1 << 18) + + +// optimization level flags +#define D3D10_SHADER_OPTIMIZATION_LEVEL0 (1 << 14) +#define D3D10_SHADER_OPTIMIZATION_LEVEL1 0 +#define D3D10_SHADER_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15)) +#define D3D10_SHADER_OPTIMIZATION_LEVEL3 (1 << 15) + + + + +typedef D3D_SHADER_MACRO D3D10_SHADER_MACRO; +typedef D3D10_SHADER_MACRO* LPD3D10_SHADER_MACRO; + + +typedef D3D_SHADER_VARIABLE_CLASS D3D10_SHADER_VARIABLE_CLASS; +typedef D3D10_SHADER_VARIABLE_CLASS* LPD3D10_SHADER_VARIABLE_CLASS; + +typedef D3D_SHADER_VARIABLE_FLAGS D3D10_SHADER_VARIABLE_FLAGS; +typedef D3D10_SHADER_VARIABLE_FLAGS* LPD3D10_SHADER_VARIABLE_FLAGS; + +typedef D3D_SHADER_VARIABLE_TYPE D3D10_SHADER_VARIABLE_TYPE; +typedef D3D10_SHADER_VARIABLE_TYPE* LPD3D10_SHADER_VARIABLE_TYPE; + +typedef D3D_SHADER_INPUT_FLAGS D3D10_SHADER_INPUT_FLAGS; +typedef D3D10_SHADER_INPUT_FLAGS* LPD3D10_SHADER_INPUT_FLAGS; + +typedef D3D_SHADER_INPUT_TYPE D3D10_SHADER_INPUT_TYPE; +typedef D3D10_SHADER_INPUT_TYPE* LPD3D10_SHADER_INPUT_TYPE; + +typedef D3D_SHADER_CBUFFER_FLAGS D3D10_SHADER_CBUFFER_FLAGS; +typedef D3D10_SHADER_CBUFFER_FLAGS* LPD3D10_SHADER_CBUFFER_FLAGS; + +typedef D3D_CBUFFER_TYPE D3D10_CBUFFER_TYPE; +typedef D3D10_CBUFFER_TYPE* LPD3D10_CBUFFER_TYPE; + +typedef D3D_NAME D3D10_NAME; + +typedef D3D_RESOURCE_RETURN_TYPE D3D10_RESOURCE_RETURN_TYPE; + +typedef D3D_REGISTER_COMPONENT_TYPE D3D10_REGISTER_COMPONENT_TYPE; + +typedef D3D_INCLUDE_TYPE D3D10_INCLUDE_TYPE; + +// ID3D10Include has been made version-neutral and moved to d3dcommon.h. +typedef interface ID3DInclude ID3D10Include; +typedef interface ID3DInclude* LPD3D10INCLUDE; +#define IID_ID3D10Include IID_ID3DInclude + + +//---------------------------------------------------------------------------- +// ID3D10ShaderReflection: +//---------------------------------------------------------------------------- + +// +// Structure definitions +// + +typedef struct _D3D10_SHADER_DESC +{ + UINT Version; // Shader version + LPCSTR Creator; // Creator string + UINT Flags; // Shader compilation/parse flags + + UINT ConstantBuffers; // Number of constant buffers + UINT BoundResources; // Number of bound resources + UINT InputParameters; // Number of parameters in the input signature + UINT OutputParameters; // Number of parameters in the output signature + + UINT InstructionCount; // Number of emitted instructions + UINT TempRegisterCount; // Number of temporary registers used + UINT TempArrayCount; // Number of temporary arrays used + UINT DefCount; // Number of constant defines + UINT DclCount; // Number of declarations (input + output) + UINT TextureNormalInstructions; // Number of non-categorized texture instructions + UINT TextureLoadInstructions; // Number of texture load instructions + UINT TextureCompInstructions; // Number of texture comparison instructions + UINT TextureBiasInstructions; // Number of texture bias instructions + UINT TextureGradientInstructions; // Number of texture gradient instructions + UINT FloatInstructionCount; // Number of floating point arithmetic instructions used + UINT IntInstructionCount; // Number of signed integer arithmetic instructions used + UINT UintInstructionCount; // Number of unsigned integer arithmetic instructions used + UINT StaticFlowControlCount; // Number of static flow control instructions used + UINT DynamicFlowControlCount; // Number of dynamic flow control instructions used + UINT MacroInstructionCount; // Number of macro instructions used + UINT ArrayInstructionCount; // Number of array instructions used + UINT CutInstructionCount; // Number of cut instructions used + UINT EmitInstructionCount; // Number of emit instructions used + D3D10_PRIMITIVE_TOPOLOGY GSOutputTopology; // Geometry shader output topology + UINT GSMaxOutputVertexCount; // Geometry shader maximum output vertex count +} D3D10_SHADER_DESC; + +typedef struct _D3D10_SHADER_BUFFER_DESC +{ + LPCSTR Name; // Name of the constant buffer + D3D10_CBUFFER_TYPE Type; // Indicates that this is a CBuffer or TBuffer + UINT Variables; // Number of member variables + UINT Size; // Size of CB (in bytes) + UINT uFlags; // Buffer description flags +} D3D10_SHADER_BUFFER_DESC; + +typedef struct _D3D10_SHADER_VARIABLE_DESC +{ + LPCSTR Name; // Name of the variable + UINT StartOffset; // Offset in constant buffer's backing store + UINT Size; // Size of variable (in bytes) + UINT uFlags; // Variable flags + LPVOID DefaultValue; // Raw pointer to default value +} D3D10_SHADER_VARIABLE_DESC; + +typedef struct _D3D10_SHADER_TYPE_DESC +{ + D3D10_SHADER_VARIABLE_CLASS Class; // Variable class (e.g. object, matrix, etc.) + D3D10_SHADER_VARIABLE_TYPE Type; // Variable type (e.g. float, sampler, etc.) + UINT Rows; // Number of rows (for matrices, 1 for other numeric, 0 if not applicable) + UINT Columns; // Number of columns (for vectors & matrices, 1 for other numeric, 0 if not applicable) + UINT Elements; // Number of elements (0 if not an array) + UINT Members; // Number of members (0 if not a structure) + UINT Offset; // Offset from the start of structure (0 if not a structure member) +} D3D10_SHADER_TYPE_DESC; + +typedef struct _D3D10_SHADER_INPUT_BIND_DESC +{ + LPCSTR Name; // Name of the resource + D3D10_SHADER_INPUT_TYPE Type; // Type of resource (e.g. texture, cbuffer, etc.) + UINT BindPoint; // Starting bind point + UINT BindCount; // Number of contiguous bind points (for arrays) + + UINT uFlags; // Input binding flags + D3D10_RESOURCE_RETURN_TYPE ReturnType; // Return type (if texture) + D3D10_SRV_DIMENSION Dimension; // Dimension (if texture) + UINT NumSamples; // Number of samples (0 if not MS texture) +} D3D10_SHADER_INPUT_BIND_DESC; + +typedef struct _D3D10_SIGNATURE_PARAMETER_DESC +{ + LPCSTR SemanticName; // Name of the semantic + UINT SemanticIndex; // Index of the semantic + UINT Register; // Number of member variables + D3D10_NAME SystemValueType;// A predefined system value, or D3D10_NAME_UNDEFINED if not applicable + D3D10_REGISTER_COMPONENT_TYPE ComponentType;// Scalar type (e.g. uint, float, etc.) + BYTE Mask; // Mask to indicate which components of the register + // are used (combination of D3D10_COMPONENT_MASK values) + BYTE ReadWriteMask; // Mask to indicate whether a given component is + // never written (if this is an output signature) or + // always read (if this is an input signature). + // (combination of D3D10_COMPONENT_MASK values) + +} D3D10_SIGNATURE_PARAMETER_DESC; + + +// +// Interface definitions +// + +typedef interface ID3D10ShaderReflectionType ID3D10ShaderReflectionType; +typedef interface ID3D10ShaderReflectionType *LPD3D10SHADERREFLECTIONTYPE; + +// {C530AD7D-9B16-4395-A979-BA2ECFF83ADD} +DEFINE_GUID(IID_ID3D10ShaderReflectionType, +0xc530ad7d, 0x9b16, 0x4395, 0xa9, 0x79, 0xba, 0x2e, 0xcf, 0xf8, 0x3a, 0xdd); + +#undef INTERFACE +#define INTERFACE ID3D10ShaderReflectionType + +DECLARE_INTERFACE(ID3D10ShaderReflectionType) +{ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_TYPE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10ShaderReflectionType*, GetMemberTypeByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10ShaderReflectionType*, GetMemberTypeByName)(THIS_ LPCSTR Name) PURE; + STDMETHOD_(LPCSTR, GetMemberTypeName)(THIS_ UINT Index) PURE; +}; + +typedef interface ID3D10ShaderReflectionVariable ID3D10ShaderReflectionVariable; +typedef interface ID3D10ShaderReflectionVariable *LPD3D10SHADERREFLECTIONVARIABLE; + +// {1BF63C95-2650-405d-99C1-3636BD1DA0A1} +DEFINE_GUID(IID_ID3D10ShaderReflectionVariable, +0x1bf63c95, 0x2650, 0x405d, 0x99, 0xc1, 0x36, 0x36, 0xbd, 0x1d, 0xa0, 0xa1); + +#undef INTERFACE +#define INTERFACE ID3D10ShaderReflectionVariable + +DECLARE_INTERFACE(ID3D10ShaderReflectionVariable) +{ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10ShaderReflectionType*, GetType)(THIS) PURE; +}; + +typedef interface ID3D10ShaderReflectionConstantBuffer ID3D10ShaderReflectionConstantBuffer; +typedef interface ID3D10ShaderReflectionConstantBuffer *LPD3D10SHADERREFLECTIONCONSTANTBUFFER; + +// {66C66A94-DDDD-4b62-A66A-F0DA33C2B4D0} +DEFINE_GUID(IID_ID3D10ShaderReflectionConstantBuffer, +0x66c66a94, 0xdddd, 0x4b62, 0xa6, 0x6a, 0xf0, 0xda, 0x33, 0xc2, 0xb4, 0xd0); + +#undef INTERFACE +#define INTERFACE ID3D10ShaderReflectionConstantBuffer + +DECLARE_INTERFACE(ID3D10ShaderReflectionConstantBuffer) +{ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_BUFFER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10ShaderReflectionVariable*, GetVariableByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10ShaderReflectionVariable*, GetVariableByName)(THIS_ LPCSTR Name) PURE; +}; + +typedef interface ID3D10ShaderReflection ID3D10ShaderReflection; +typedef interface ID3D10ShaderReflection *LPD3D10SHADERREFLECTION; + +// {D40E20B6-F8F7-42ad-AB20-4BAF8F15DFAA} +DEFINE_GUID(IID_ID3D10ShaderReflection, +0xd40e20b6, 0xf8f7, 0x42ad, 0xab, 0x20, 0x4b, 0xaf, 0x8f, 0x15, 0xdf, 0xaa); + +#undef INTERFACE +#define INTERFACE ID3D10ShaderReflection + +DECLARE_INTERFACE_(ID3D10ShaderReflection, IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D10ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ UINT Index) PURE; + STDMETHOD_(ID3D10ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ LPCSTR Name) PURE; + + STDMETHOD(GetResourceBindingDesc)(THIS_ UINT ResourceIndex, D3D10_SHADER_INPUT_BIND_DESC *pDesc) PURE; + + STDMETHOD(GetInputParameterDesc)(THIS_ UINT ParameterIndex, D3D10_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + STDMETHOD(GetOutputParameterDesc)(THIS_ UINT ParameterIndex, D3D10_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + +}; + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3D10CompileShader: +// ------------------ +// Compiles a shader. +// +// Parameters: +// pSrcFile +// Source file name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module. +// pSrcData +// Pointer to source code. +// SrcDataLen +// Size of source code, in bytes. +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pFunctionName +// Name of the entrypoint function where execution should begin. +// pProfile +// Instruction set to be used when generating code. The D3D10 entry +// point currently supports only "vs_4_0", "ps_4_0", and "gs_4_0". +// Flags +// See D3D10_SHADER_xxx flags. +// ppShader +// Returns a buffer containing the created shader. This buffer contains +// the compiled shader code, as well as any embedded debug and symbol +// table info. (See D3D10GetShaderConstantTable) +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during the compile. If you are running in a debugger, +// these are the same messages you will see in your debug output. +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10CompileShader(LPCSTR pSrcData, SIZE_T SrcDataLen, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs); + +//---------------------------------------------------------------------------- +// D3D10DisassembleShader: +// ---------------------- +// Takes a binary shader, and returns a buffer containing text assembly. +// +// Parameters: +// pShader +// Pointer to the shader byte code. +// BytecodeLength +// Size of the shader byte code in bytes. +// EnableColorCode +// Emit HTML tags for color coding the output? +// pComments +// Pointer to a comment string to include at the top of the shader. +// ppDisassembly +// Returns a buffer containing the disassembled shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10DisassembleShader(CONST void *pShader, SIZE_T BytecodeLength, BOOL EnableColorCode, LPCSTR pComments, ID3D10Blob** ppDisassembly); + + +//---------------------------------------------------------------------------- +// D3D10GetPixelShaderProfile/D3D10GetVertexShaderProfile/D3D10GetGeometryShaderProfile: +// ----------------------------------------------------- +// Returns the name of the HLSL profile best suited to a given device. +// +// Parameters: +// pDevice +// Pointer to the device in question +//---------------------------------------------------------------------------- + +LPCSTR WINAPI D3D10GetPixelShaderProfile(ID3D10Device *pDevice); + +LPCSTR WINAPI D3D10GetVertexShaderProfile(ID3D10Device *pDevice); + +LPCSTR WINAPI D3D10GetGeometryShaderProfile(ID3D10Device *pDevice); + +//---------------------------------------------------------------------------- +// D3D10ReflectShader: +// ------------------ +// Creates a shader reflection object that can be used to retrieve information +// about a compiled shader +// +// Parameters: +// pShaderBytecode +// Pointer to a compiled shader (same pointer that is passed into +// ID3D10Device::CreateShader) +// BytecodeLength +// Length of the shader bytecode buffer +// ppReflector +// [out] Returns a ID3D10ShaderReflection object that can be used to +// retrieve shader resource and constant buffer information +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10ReflectShader(CONST void *pShaderBytecode, SIZE_T BytecodeLength, ID3D10ShaderReflection **ppReflector); + +//---------------------------------------------------------------------------- +// D3D10PreprocessShader +// --------------------- +// Creates a shader reflection object that can be used to retrieve information +// about a compiled shader +// +// Parameters: +// pSrcData +// Pointer to source code +// SrcDataLen +// Size of source code, in bytes +// pFileName +// Source file name (used for error output) +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when assembling +// from file, and will error when assembling from resource or memory. +// ppShaderText +// Returns a buffer containing a single large string that represents +// the resulting formatted token stream +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during assembly. If you are running in a debugger, +// these are the same messages you will see in your debug output. +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10PreprocessShader(LPCSTR pSrcData, SIZE_T SrcDataSize, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs); + +////////////////////////////////////////////////////////////////////////// +// +// Shader blob manipulation routines +// --------------------------------- +// +// void *pShaderBytecode - a buffer containing the result of an HLSL +// compilation. Typically this opaque buffer contains several +// discrete sections including the shader executable code, the input +// signature, and the output signature. This can typically be retrieved +// by calling ID3D10Blob::GetBufferPointer() on the returned blob +// from HLSL's compile APIs. +// +// UINT BytecodeLength - the length of pShaderBytecode. This can +// typically be retrieved by calling ID3D10Blob::GetBufferSize() +// on the returned blob from HLSL's compile APIs. +// +// ID3D10Blob **ppSignatureBlob(s) - a newly created buffer that +// contains only the signature portions of the original bytecode. +// This is a copy; the original bytecode is not modified. You may +// specify NULL for this parameter to have the bytecode validated +// for the presence of the corresponding signatures without actually +// copying them and creating a new blob. +// +// Returns E_INVALIDARG if any required parameters are NULL +// Returns E_FAIL is the bytecode is corrupt or missing signatures +// Returns S_OK on success +// +////////////////////////////////////////////////////////////////////////// + +HRESULT WINAPI D3D10GetInputSignatureBlob(CONST void *pShaderBytecode, SIZE_T BytecodeLength, ID3D10Blob **ppSignatureBlob); +HRESULT WINAPI D3D10GetOutputSignatureBlob(CONST void *pShaderBytecode, SIZE_T BytecodeLength, ID3D10Blob **ppSignatureBlob); +HRESULT WINAPI D3D10GetInputAndOutputSignatureBlob(CONST void *pShaderBytecode, SIZE_T BytecodeLength, ID3D10Blob **ppSignatureBlob); + +//---------------------------------------------------------------------------- +// D3D10GetShaderDebugInfo: +// ----------------------- +// Gets shader debug info. Debug info is generated by D3D10CompileShader and is +// embedded in the body of the shader. +// +// Parameters: +// pShaderBytecode +// Pointer to the function bytecode +// BytecodeLength +// Length of the shader bytecode buffer +// ppDebugInfo +// Buffer used to return debug info. For information about the layout +// of this buffer, see definition of D3D10_SHADER_DEBUG_INFO above. +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3D10GetShaderDebugInfo(CONST void *pShaderBytecode, SIZE_T BytecodeLength, ID3D10Blob** ppDebugInfo); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3D10SHADER_H__ + diff --git a/dxsdk/Include/D3D11.h b/dxsdk/Include/D3D11.h new file mode 100644 index 0000000..680cf80 --- /dev/null +++ b/dxsdk/Include/D3D11.h @@ -0,0 +1,10227 @@ +/*------------------------------------------------------------------------------------- + * + * Copyright (c) Microsoft Corporation + * + *-------------------------------------------------------------------------------------*/ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3d11_h__ +#define __d3d11_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D11DeviceChild_FWD_DEFINED__ +#define __ID3D11DeviceChild_FWD_DEFINED__ +typedef interface ID3D11DeviceChild ID3D11DeviceChild; +#endif /* __ID3D11DeviceChild_FWD_DEFINED__ */ + + +#ifndef __ID3D11DepthStencilState_FWD_DEFINED__ +#define __ID3D11DepthStencilState_FWD_DEFINED__ +typedef interface ID3D11DepthStencilState ID3D11DepthStencilState; +#endif /* __ID3D11DepthStencilState_FWD_DEFINED__ */ + + +#ifndef __ID3D11BlendState_FWD_DEFINED__ +#define __ID3D11BlendState_FWD_DEFINED__ +typedef interface ID3D11BlendState ID3D11BlendState; +#endif /* __ID3D11BlendState_FWD_DEFINED__ */ + + +#ifndef __ID3D11RasterizerState_FWD_DEFINED__ +#define __ID3D11RasterizerState_FWD_DEFINED__ +typedef interface ID3D11RasterizerState ID3D11RasterizerState; +#endif /* __ID3D11RasterizerState_FWD_DEFINED__ */ + + +#ifndef __ID3D11Resource_FWD_DEFINED__ +#define __ID3D11Resource_FWD_DEFINED__ +typedef interface ID3D11Resource ID3D11Resource; +#endif /* __ID3D11Resource_FWD_DEFINED__ */ + + +#ifndef __ID3D11Buffer_FWD_DEFINED__ +#define __ID3D11Buffer_FWD_DEFINED__ +typedef interface ID3D11Buffer ID3D11Buffer; +#endif /* __ID3D11Buffer_FWD_DEFINED__ */ + + +#ifndef __ID3D11Texture1D_FWD_DEFINED__ +#define __ID3D11Texture1D_FWD_DEFINED__ +typedef interface ID3D11Texture1D ID3D11Texture1D; +#endif /* __ID3D11Texture1D_FWD_DEFINED__ */ + + +#ifndef __ID3D11Texture2D_FWD_DEFINED__ +#define __ID3D11Texture2D_FWD_DEFINED__ +typedef interface ID3D11Texture2D ID3D11Texture2D; +#endif /* __ID3D11Texture2D_FWD_DEFINED__ */ + + +#ifndef __ID3D11Texture3D_FWD_DEFINED__ +#define __ID3D11Texture3D_FWD_DEFINED__ +typedef interface ID3D11Texture3D ID3D11Texture3D; +#endif /* __ID3D11Texture3D_FWD_DEFINED__ */ + + +#ifndef __ID3D11View_FWD_DEFINED__ +#define __ID3D11View_FWD_DEFINED__ +typedef interface ID3D11View ID3D11View; +#endif /* __ID3D11View_FWD_DEFINED__ */ + + +#ifndef __ID3D11ShaderResourceView_FWD_DEFINED__ +#define __ID3D11ShaderResourceView_FWD_DEFINED__ +typedef interface ID3D11ShaderResourceView ID3D11ShaderResourceView; +#endif /* __ID3D11ShaderResourceView_FWD_DEFINED__ */ + + +#ifndef __ID3D11RenderTargetView_FWD_DEFINED__ +#define __ID3D11RenderTargetView_FWD_DEFINED__ +typedef interface ID3D11RenderTargetView ID3D11RenderTargetView; +#endif /* __ID3D11RenderTargetView_FWD_DEFINED__ */ + + +#ifndef __ID3D11DepthStencilView_FWD_DEFINED__ +#define __ID3D11DepthStencilView_FWD_DEFINED__ +typedef interface ID3D11DepthStencilView ID3D11DepthStencilView; +#endif /* __ID3D11DepthStencilView_FWD_DEFINED__ */ + + +#ifndef __ID3D11UnorderedAccessView_FWD_DEFINED__ +#define __ID3D11UnorderedAccessView_FWD_DEFINED__ +typedef interface ID3D11UnorderedAccessView ID3D11UnorderedAccessView; +#endif /* __ID3D11UnorderedAccessView_FWD_DEFINED__ */ + + +#ifndef __ID3D11VertexShader_FWD_DEFINED__ +#define __ID3D11VertexShader_FWD_DEFINED__ +typedef interface ID3D11VertexShader ID3D11VertexShader; +#endif /* __ID3D11VertexShader_FWD_DEFINED__ */ + + +#ifndef __ID3D11HullShader_FWD_DEFINED__ +#define __ID3D11HullShader_FWD_DEFINED__ +typedef interface ID3D11HullShader ID3D11HullShader; +#endif /* __ID3D11HullShader_FWD_DEFINED__ */ + + +#ifndef __ID3D11DomainShader_FWD_DEFINED__ +#define __ID3D11DomainShader_FWD_DEFINED__ +typedef interface ID3D11DomainShader ID3D11DomainShader; +#endif /* __ID3D11DomainShader_FWD_DEFINED__ */ + + +#ifndef __ID3D11GeometryShader_FWD_DEFINED__ +#define __ID3D11GeometryShader_FWD_DEFINED__ +typedef interface ID3D11GeometryShader ID3D11GeometryShader; +#endif /* __ID3D11GeometryShader_FWD_DEFINED__ */ + + +#ifndef __ID3D11PixelShader_FWD_DEFINED__ +#define __ID3D11PixelShader_FWD_DEFINED__ +typedef interface ID3D11PixelShader ID3D11PixelShader; +#endif /* __ID3D11PixelShader_FWD_DEFINED__ */ + + +#ifndef __ID3D11ComputeShader_FWD_DEFINED__ +#define __ID3D11ComputeShader_FWD_DEFINED__ +typedef interface ID3D11ComputeShader ID3D11ComputeShader; +#endif /* __ID3D11ComputeShader_FWD_DEFINED__ */ + + +#ifndef __ID3D11InputLayout_FWD_DEFINED__ +#define __ID3D11InputLayout_FWD_DEFINED__ +typedef interface ID3D11InputLayout ID3D11InputLayout; +#endif /* __ID3D11InputLayout_FWD_DEFINED__ */ + + +#ifndef __ID3D11SamplerState_FWD_DEFINED__ +#define __ID3D11SamplerState_FWD_DEFINED__ +typedef interface ID3D11SamplerState ID3D11SamplerState; +#endif /* __ID3D11SamplerState_FWD_DEFINED__ */ + + +#ifndef __ID3D11Asynchronous_FWD_DEFINED__ +#define __ID3D11Asynchronous_FWD_DEFINED__ +typedef interface ID3D11Asynchronous ID3D11Asynchronous; +#endif /* __ID3D11Asynchronous_FWD_DEFINED__ */ + + +#ifndef __ID3D11Query_FWD_DEFINED__ +#define __ID3D11Query_FWD_DEFINED__ +typedef interface ID3D11Query ID3D11Query; +#endif /* __ID3D11Query_FWD_DEFINED__ */ + + +#ifndef __ID3D11Predicate_FWD_DEFINED__ +#define __ID3D11Predicate_FWD_DEFINED__ +typedef interface ID3D11Predicate ID3D11Predicate; +#endif /* __ID3D11Predicate_FWD_DEFINED__ */ + + +#ifndef __ID3D11Counter_FWD_DEFINED__ +#define __ID3D11Counter_FWD_DEFINED__ +typedef interface ID3D11Counter ID3D11Counter; +#endif /* __ID3D11Counter_FWD_DEFINED__ */ + + +#ifndef __ID3D11ClassInstance_FWD_DEFINED__ +#define __ID3D11ClassInstance_FWD_DEFINED__ +typedef interface ID3D11ClassInstance ID3D11ClassInstance; +#endif /* __ID3D11ClassInstance_FWD_DEFINED__ */ + + +#ifndef __ID3D11ClassLinkage_FWD_DEFINED__ +#define __ID3D11ClassLinkage_FWD_DEFINED__ +typedef interface ID3D11ClassLinkage ID3D11ClassLinkage; +#endif /* __ID3D11ClassLinkage_FWD_DEFINED__ */ + + +#ifndef __ID3D11CommandList_FWD_DEFINED__ +#define __ID3D11CommandList_FWD_DEFINED__ +typedef interface ID3D11CommandList ID3D11CommandList; +#endif /* __ID3D11CommandList_FWD_DEFINED__ */ + + +#ifndef __ID3D11DeviceContext_FWD_DEFINED__ +#define __ID3D11DeviceContext_FWD_DEFINED__ +typedef interface ID3D11DeviceContext ID3D11DeviceContext; +#endif /* __ID3D11DeviceContext_FWD_DEFINED__ */ + + +#ifndef __ID3D11Device_FWD_DEFINED__ +#define __ID3D11Device_FWD_DEFINED__ +typedef interface ID3D11Device ID3D11Device; +#endif /* __ID3D11Device_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "dxgi.h" +#include "d3dcommon.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3d11_0000_0000 */ +/* [local] */ + +#ifndef _D3D11_CONSTANTS +#define _D3D11_CONSTANTS +#define D3D11_16BIT_INDEX_STRIP_CUT_VALUE ( 0xffff ) + +#define D3D11_32BIT_INDEX_STRIP_CUT_VALUE ( 0xffffffff ) + +#define D3D11_8BIT_INDEX_STRIP_CUT_VALUE ( 0xff ) + +#define D3D11_ARRAY_AXIS_ADDRESS_RANGE_BIT_COUNT ( 9 ) + +#define D3D11_CLIP_OR_CULL_DISTANCE_COUNT ( 8 ) + +#define D3D11_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT ( 2 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ( 14 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENTS ( 4 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT ( 15 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT ( 15 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_COMMONSHADER_FLOWCONTROL_NESTING_LIMIT ( 64 ) + +#define D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COUNT ( 1 ) + +#define D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_COMMONSHADER_IMMEDIATE_VALUE_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT ( 128 ) + +#define D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_READS_PER_INST ( 1 ) + +#define D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT ( 128 ) + +#define D3D11_COMMONSHADER_SAMPLER_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_COMMONSHADER_SAMPLER_REGISTER_COUNT ( 16 ) + +#define D3D11_COMMONSHADER_SAMPLER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D11_COMMONSHADER_SAMPLER_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT ( 16 ) + +#define D3D11_COMMONSHADER_SUBROUTINE_NESTING_LIMIT ( 32 ) + +#define D3D11_COMMONSHADER_TEMP_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_COMMONSHADER_TEMP_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_COMMONSHADER_TEMP_REGISTER_COUNT ( 4096 ) + +#define D3D11_COMMONSHADER_TEMP_REGISTER_READS_PER_INST ( 3 ) + +#define D3D11_COMMONSHADER_TEMP_REGISTER_READ_PORTS ( 3 ) + +#define D3D11_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MAX ( 10 ) + +#define D3D11_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MIN ( -10 ) + +#define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE ( -8 ) + +#define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE ( 7 ) + +#define D3D11_CS_4_X_BUCKET00_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 256 ) + +#define D3D11_CS_4_X_BUCKET00_MAX_NUM_THREADS_PER_GROUP ( 64 ) + +#define D3D11_CS_4_X_BUCKET01_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 240 ) + +#define D3D11_CS_4_X_BUCKET01_MAX_NUM_THREADS_PER_GROUP ( 68 ) + +#define D3D11_CS_4_X_BUCKET02_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 224 ) + +#define D3D11_CS_4_X_BUCKET02_MAX_NUM_THREADS_PER_GROUP ( 72 ) + +#define D3D11_CS_4_X_BUCKET03_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 208 ) + +#define D3D11_CS_4_X_BUCKET03_MAX_NUM_THREADS_PER_GROUP ( 76 ) + +#define D3D11_CS_4_X_BUCKET04_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 192 ) + +#define D3D11_CS_4_X_BUCKET04_MAX_NUM_THREADS_PER_GROUP ( 84 ) + +#define D3D11_CS_4_X_BUCKET05_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 176 ) + +#define D3D11_CS_4_X_BUCKET05_MAX_NUM_THREADS_PER_GROUP ( 92 ) + +#define D3D11_CS_4_X_BUCKET06_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 160 ) + +#define D3D11_CS_4_X_BUCKET06_MAX_NUM_THREADS_PER_GROUP ( 100 ) + +#define D3D11_CS_4_X_BUCKET07_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 144 ) + +#define D3D11_CS_4_X_BUCKET07_MAX_NUM_THREADS_PER_GROUP ( 112 ) + +#define D3D11_CS_4_X_BUCKET08_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 128 ) + +#define D3D11_CS_4_X_BUCKET08_MAX_NUM_THREADS_PER_GROUP ( 128 ) + +#define D3D11_CS_4_X_BUCKET09_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 112 ) + +#define D3D11_CS_4_X_BUCKET09_MAX_NUM_THREADS_PER_GROUP ( 144 ) + +#define D3D11_CS_4_X_BUCKET10_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 96 ) + +#define D3D11_CS_4_X_BUCKET10_MAX_NUM_THREADS_PER_GROUP ( 168 ) + +#define D3D11_CS_4_X_BUCKET11_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 80 ) + +#define D3D11_CS_4_X_BUCKET11_MAX_NUM_THREADS_PER_GROUP ( 204 ) + +#define D3D11_CS_4_X_BUCKET12_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 64 ) + +#define D3D11_CS_4_X_BUCKET12_MAX_NUM_THREADS_PER_GROUP ( 256 ) + +#define D3D11_CS_4_X_BUCKET13_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 48 ) + +#define D3D11_CS_4_X_BUCKET13_MAX_NUM_THREADS_PER_GROUP ( 340 ) + +#define D3D11_CS_4_X_BUCKET14_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 32 ) + +#define D3D11_CS_4_X_BUCKET14_MAX_NUM_THREADS_PER_GROUP ( 512 ) + +#define D3D11_CS_4_X_BUCKET15_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 16 ) + +#define D3D11_CS_4_X_BUCKET15_MAX_NUM_THREADS_PER_GROUP ( 768 ) + +#define D3D11_CS_4_X_DISPATCH_MAX_THREAD_GROUPS_IN_Z_DIMENSION ( 1 ) + +#define D3D11_CS_4_X_RAW_UAV_BYTE_ALIGNMENT ( 256 ) + +#define D3D11_CS_4_X_THREAD_GROUP_MAX_THREADS_PER_GROUP ( 768 ) + +#define D3D11_CS_4_X_THREAD_GROUP_MAX_X ( 768 ) + +#define D3D11_CS_4_X_THREAD_GROUP_MAX_Y ( 768 ) + +#define D3D11_CS_4_X_UAV_REGISTER_COUNT ( 1 ) + +#define D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION ( 65535 ) + +#define D3D11_CS_TGSM_REGISTER_COUNT ( 8192 ) + +#define D3D11_CS_TGSM_REGISTER_READS_PER_INST ( 1 ) + +#define D3D11_CS_TGSM_RESOURCE_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_CS_TGSM_RESOURCE_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP ( 1024 ) + +#define D3D11_CS_THREAD_GROUP_MAX_X ( 1024 ) + +#define D3D11_CS_THREAD_GROUP_MAX_Y ( 1024 ) + +#define D3D11_CS_THREAD_GROUP_MAX_Z ( 64 ) + +#define D3D11_CS_THREAD_GROUP_MIN_X ( 1 ) + +#define D3D11_CS_THREAD_GROUP_MIN_Y ( 1 ) + +#define D3D11_CS_THREAD_GROUP_MIN_Z ( 1 ) + +#define D3D11_CS_THREAD_LOCAL_TEMP_REGISTER_POOL ( 16384 ) + +#define D3D11_DEFAULT_BLEND_FACTOR_ALPHA ( 1.0f ) +#define D3D11_DEFAULT_BLEND_FACTOR_BLUE ( 1.0f ) +#define D3D11_DEFAULT_BLEND_FACTOR_GREEN ( 1.0f ) +#define D3D11_DEFAULT_BLEND_FACTOR_RED ( 1.0f ) +#define D3D11_DEFAULT_BORDER_COLOR_COMPONENT ( 0.0f ) +#define D3D11_DEFAULT_DEPTH_BIAS ( 0 ) + +#define D3D11_DEFAULT_DEPTH_BIAS_CLAMP ( 0.0f ) +#define D3D11_DEFAULT_MAX_ANISOTROPY ( 16 ) +#define D3D11_DEFAULT_MIP_LOD_BIAS ( 0.0f ) +#define D3D11_DEFAULT_RENDER_TARGET_ARRAY_INDEX ( 0 ) + +#define D3D11_DEFAULT_SAMPLE_MASK ( 0xffffffff ) + +#define D3D11_DEFAULT_SCISSOR_ENDX ( 0 ) + +#define D3D11_DEFAULT_SCISSOR_ENDY ( 0 ) + +#define D3D11_DEFAULT_SCISSOR_STARTX ( 0 ) + +#define D3D11_DEFAULT_SCISSOR_STARTY ( 0 ) + +#define D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS ( 0.0f ) +#define D3D11_DEFAULT_STENCIL_READ_MASK ( 0xff ) + +#define D3D11_DEFAULT_STENCIL_REFERENCE ( 0 ) + +#define D3D11_DEFAULT_STENCIL_WRITE_MASK ( 0xff ) + +#define D3D11_DEFAULT_VIEWPORT_AND_SCISSORRECT_INDEX ( 0 ) + +#define D3D11_DEFAULT_VIEWPORT_HEIGHT ( 0 ) + +#define D3D11_DEFAULT_VIEWPORT_MAX_DEPTH ( 0.0f ) +#define D3D11_DEFAULT_VIEWPORT_MIN_DEPTH ( 0.0f ) +#define D3D11_DEFAULT_VIEWPORT_TOPLEFTX ( 0 ) + +#define D3D11_DEFAULT_VIEWPORT_TOPLEFTY ( 0 ) + +#define D3D11_DEFAULT_VIEWPORT_WIDTH ( 0 ) + +#define D3D11_DS_INPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS ( 3968 ) + +#define D3D11_DS_INPUT_CONTROL_POINT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_DS_INPUT_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_DS_INPUT_CONTROL_POINT_REGISTER_COUNT ( 32 ) + +#define D3D11_DS_INPUT_CONTROL_POINT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_DS_INPUT_CONTROL_POINT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENTS ( 3 ) + +#define D3D11_DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_DS_INPUT_DOMAIN_POINT_REGISTER_COUNT ( 1 ) + +#define D3D11_DS_INPUT_DOMAIN_POINT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_DS_INPUT_DOMAIN_POINT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_DS_INPUT_PATCH_CONSTANT_REGISTER_COUNT ( 32 ) + +#define D3D11_DS_INPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_DS_INPUT_PATCH_CONSTANT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_DS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_DS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_DS_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_FLOAT16_FUSED_TOLERANCE_IN_ULP ( 0.6 ) +#define D3D11_FLOAT32_MAX ( 3.402823466e+38f ) +#define D3D11_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ( 0.6f ) +#define D3D11_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR ( 2.4f ) +#define D3D11_FLOAT_TO_SRGB_EXPONENT_NUMERATOR ( 1.0f ) +#define D3D11_FLOAT_TO_SRGB_OFFSET ( 0.055f ) +#define D3D11_FLOAT_TO_SRGB_SCALE_1 ( 12.92f ) +#define D3D11_FLOAT_TO_SRGB_SCALE_2 ( 1.055f ) +#define D3D11_FLOAT_TO_SRGB_THRESHOLD ( 0.0031308f ) +#define D3D11_FTOI_INSTRUCTION_MAX_INPUT ( 2147483647.999f ) +#define D3D11_FTOI_INSTRUCTION_MIN_INPUT ( -2147483648.999f ) +#define D3D11_FTOU_INSTRUCTION_MAX_INPUT ( 4294967295.999f ) +#define D3D11_FTOU_INSTRUCTION_MIN_INPUT ( 0.0f ) +#define D3D11_GS_INPUT_INSTANCE_ID_READS_PER_INST ( 2 ) + +#define D3D11_GS_INPUT_INSTANCE_ID_READ_PORTS ( 1 ) + +#define D3D11_GS_INPUT_INSTANCE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_GS_INPUT_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_GS_INPUT_INSTANCE_ID_REGISTER_COUNT ( 1 ) + +#define D3D11_GS_INPUT_PRIM_CONST_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_GS_INPUT_PRIM_CONST_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_GS_INPUT_PRIM_CONST_REGISTER_COUNT ( 1 ) + +#define D3D11_GS_INPUT_PRIM_CONST_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_GS_INPUT_PRIM_CONST_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_GS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_GS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_GS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_GS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_GS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_GS_INPUT_REGISTER_VERTICES ( 32 ) + +#define D3D11_GS_MAX_INSTANCE_COUNT ( 32 ) + +#define D3D11_GS_MAX_OUTPUT_VERTEX_COUNT_ACROSS_INSTANCES ( 1024 ) + +#define D3D11_GS_OUTPUT_ELEMENTS ( 32 ) + +#define D3D11_GS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_GS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_GS_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_HS_CONTROL_POINT_PHASE_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_HS_CONTROL_POINT_PHASE_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_HS_CONTROL_POINT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_HS_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_HS_CONTROL_POINT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_HS_CONTROL_POINT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_HS_FORK_PHASE_INSTANCE_COUNT_UPPER_BOUND ( 0xffffffff ) + +#define D3D11_HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_HS_INPUT_FORK_INSTANCE_ID_REGISTER_COUNT ( 1 ) + +#define D3D11_HS_INPUT_FORK_INSTANCE_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_HS_INPUT_FORK_INSTANCE_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COUNT ( 1 ) + +#define D3D11_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_HS_INPUT_PRIMITIVE_ID_REGISTER_COUNT ( 1 ) + +#define D3D11_HS_INPUT_PRIMITIVE_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_HS_INPUT_PRIMITIVE_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_HS_JOIN_PHASE_INSTANCE_COUNT_UPPER_BOUND ( 0xffffffff ) + +#define D3D11_HS_MAXTESSFACTOR_LOWER_BOUND ( 1.0f ) +#define D3D11_HS_MAXTESSFACTOR_UPPER_BOUND ( 64.0f ) +#define D3D11_HS_OUTPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS ( 3968 ) + +#define D3D11_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COUNT ( 1 ) + +#define D3D11_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COUNT ( 32 ) + +#define D3D11_HS_OUTPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_HS_OUTPUT_PATCH_CONSTANT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_IA_DEFAULT_INDEX_BUFFER_OFFSET_IN_BYTES ( 0 ) + +#define D3D11_IA_DEFAULT_PRIMITIVE_TOPOLOGY ( 0 ) + +#define D3D11_IA_DEFAULT_VERTEX_BUFFER_OFFSET_IN_BYTES ( 0 ) + +#define D3D11_IA_INDEX_INPUT_RESOURCE_SLOT_COUNT ( 1 ) + +#define D3D11_IA_INSTANCE_ID_BIT_COUNT ( 32 ) + +#define D3D11_IA_INTEGER_ARITHMETIC_BIT_COUNT ( 32 ) + +#define D3D11_IA_PATCH_MAX_CONTROL_POINT_COUNT ( 32 ) + +#define D3D11_IA_PRIMITIVE_ID_BIT_COUNT ( 32 ) + +#define D3D11_IA_VERTEX_ID_BIT_COUNT ( 32 ) + +#define D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT ( 32 ) + +#define D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS ( 128 ) + +#define D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ( 32 ) + +#define D3D11_INTEGER_DIVIDE_BY_ZERO_QUOTIENT ( 0xffffffff ) + +#define D3D11_INTEGER_DIVIDE_BY_ZERO_REMAINDER ( 0xffffffff ) + +#define D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL ( 0xffffffff ) + +#define D3D11_KEEP_UNORDERED_ACCESS_VIEWS ( 0xffffffff ) + +#define D3D11_LINEAR_GAMMA ( 1.0f ) +#define D3D11_MAJOR_VERSION ( 11 ) + +#define D3D11_MAX_BORDER_COLOR_COMPONENT ( 1.0f ) +#define D3D11_MAX_DEPTH ( 1.0f ) +#define D3D11_MAX_MAXANISOTROPY ( 16 ) + +#define D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT ( 32 ) + +#define D3D11_MAX_POSITION_VALUE ( 3.402823466e+34f ) +#define D3D11_MAX_TEXTURE_DIMENSION_2_TO_EXP ( 17 ) + +#define D3D11_MINOR_VERSION ( 0 ) + +#define D3D11_MIN_BORDER_COLOR_COMPONENT ( 0.0f ) +#define D3D11_MIN_DEPTH ( 0.0f ) +#define D3D11_MIN_MAXANISOTROPY ( 0 ) + +#define D3D11_MIP_LOD_BIAS_MAX ( 15.99f ) +#define D3D11_MIP_LOD_BIAS_MIN ( -16.0f ) +#define D3D11_MIP_LOD_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D11_MIP_LOD_RANGE_BIT_COUNT ( 8 ) + +#define D3D11_MULTISAMPLE_ANTIALIAS_LINE_WIDTH ( 1.4f ) +#define D3D11_NONSAMPLE_FETCH_OUT_OF_RANGE_ACCESS_RESULT ( 0 ) + +#define D3D11_PIXEL_ADDRESS_RANGE_BIT_COUNT ( 15 ) + +#define D3D11_PRE_SCISSOR_PIXEL_ADDRESS_RANGE_BIT_COUNT ( 16 ) + +#define D3D11_PS_CS_UAV_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_PS_CS_UAV_REGISTER_COUNT ( 8 ) + +#define D3D11_PS_CS_UAV_REGISTER_READS_PER_INST ( 1 ) + +#define D3D11_PS_CS_UAV_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_PS_FRONTFACING_DEFAULT_VALUE ( 0xffffffff ) + +#define D3D11_PS_FRONTFACING_FALSE_VALUE ( 0 ) + +#define D3D11_PS_FRONTFACING_TRUE_VALUE ( 0xffffffff ) + +#define D3D11_PS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_PS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_PS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_PS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_PS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_PS_LEGACY_PIXEL_CENTER_FRACTIONAL_COMPONENT ( 0.0f ) +#define D3D11_PS_OUTPUT_DEPTH_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_PS_OUTPUT_DEPTH_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_PS_OUTPUT_DEPTH_REGISTER_COUNT ( 1 ) + +#define D3D11_PS_OUTPUT_MASK_REGISTER_COMPONENTS ( 1 ) + +#define D3D11_PS_OUTPUT_MASK_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_PS_OUTPUT_MASK_REGISTER_COUNT ( 1 ) + +#define D3D11_PS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_PS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_PS_OUTPUT_REGISTER_COUNT ( 8 ) + +#define D3D11_PS_PIXEL_CENTER_FRACTIONAL_COMPONENT ( 0.5f ) +#define D3D11_RAW_UAV_SRV_BYTE_ALIGNMENT ( 16 ) + +#define D3D11_REQ_BLEND_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP ( 27 ) + +#define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT ( 4096 ) + +#define D3D11_REQ_DEPTH_STENCIL_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP ( 32 ) + +#define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP ( 32 ) + +#define D3D11_REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION ( 16384 ) + +#define D3D11_REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT ( 1024 ) + +#define D3D11_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT ( 4096 ) + +#define D3D11_REQ_MAXANISOTROPY ( 16 ) + +#define D3D11_REQ_MIP_LEVELS ( 15 ) + +#define D3D11_REQ_MULTI_ELEMENT_STRUCTURE_SIZE_IN_BYTES ( 2048 ) + +#define D3D11_REQ_RASTERIZER_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH ( 16384 ) + +#define D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM ( 128 ) + +#define D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_B_TERM ( 0.25f ) +#define D3D11_REQ_RESOURCE_VIEW_COUNT_PER_DEVICE_2_TO_EXP ( 20 ) + +#define D3D11_REQ_SAMPLER_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION ( 2048 ) + +#define D3D11_REQ_TEXTURE1D_U_DIMENSION ( 16384 ) + +#define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION ( 2048 ) + +#define D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION ( 16384 ) + +#define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION ( 2048 ) + +#define D3D11_REQ_TEXTURECUBE_DIMENSION ( 16384 ) + +#define D3D11_RESINFO_INSTRUCTION_MISSING_COMPONENT_RETVAL ( 0 ) + +#define D3D11_SHADER_MAJOR_VERSION ( 5 ) + +#define D3D11_SHADER_MAX_INSTANCES ( 65535 ) + +#define D3D11_SHADER_MAX_INTERFACES ( 253 ) + +#define D3D11_SHADER_MAX_INTERFACE_CALL_SITES ( 4096 ) + +#define D3D11_SHADER_MAX_TYPES ( 65535 ) + +#define D3D11_SHADER_MINOR_VERSION ( 0 ) + +#define D3D11_SHIFT_INSTRUCTION_PAD_VALUE ( 0 ) + +#define D3D11_SHIFT_INSTRUCTION_SHIFT_VALUE_BIT_COUNT ( 5 ) + +#define D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT ( 8 ) + +#define D3D11_SO_BUFFER_MAX_STRIDE_IN_BYTES ( 2048 ) + +#define D3D11_SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES ( 512 ) + +#define D3D11_SO_BUFFER_SLOT_COUNT ( 4 ) + +#define D3D11_SO_DDI_REGISTER_INDEX_DENOTING_GAP ( 0xffffffff ) + +#define D3D11_SO_NO_RASTERIZED_STREAM ( 0xffffffff ) + +#define D3D11_SO_OUTPUT_COMPONENT_COUNT ( 128 ) + +#define D3D11_SO_STREAM_COUNT ( 4 ) + +#define D3D11_SPEC_DATE_DAY ( 04 ) + +#define D3D11_SPEC_DATE_MONTH ( 06 ) + +#define D3D11_SPEC_DATE_YEAR ( 2009 ) + +#define D3D11_SPEC_VERSION ( 1.0 ) +#define D3D11_SRGB_GAMMA ( 2.2f ) +#define D3D11_SRGB_TO_FLOAT_DENOMINATOR_1 ( 12.92f ) +#define D3D11_SRGB_TO_FLOAT_DENOMINATOR_2 ( 1.055f ) +#define D3D11_SRGB_TO_FLOAT_EXPONENT ( 2.4f ) +#define D3D11_SRGB_TO_FLOAT_OFFSET ( 0.055f ) +#define D3D11_SRGB_TO_FLOAT_THRESHOLD ( 0.04045f ) +#define D3D11_SRGB_TO_FLOAT_TOLERANCE_IN_ULP ( 0.5f ) +#define D3D11_STANDARD_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_STANDARD_COMPONENT_BIT_COUNT_DOUBLED ( 64 ) + +#define D3D11_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE ( 4 ) + +#define D3D11_STANDARD_PIXEL_COMPONENT_COUNT ( 128 ) + +#define D3D11_STANDARD_PIXEL_ELEMENT_COUNT ( 32 ) + +#define D3D11_STANDARD_VECTOR_SIZE ( 4 ) + +#define D3D11_STANDARD_VERTEX_ELEMENT_COUNT ( 32 ) + +#define D3D11_STANDARD_VERTEX_TOTAL_COMPONENT_COUNT ( 64 ) + +#define D3D11_SUBPIXEL_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D11_SUBTEXEL_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D11_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR ( 64 ) + +#define D3D11_TESSELLATOR_MAX_ISOLINE_DENSITY_TESSELLATION_FACTOR ( 64 ) + +#define D3D11_TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR ( 63 ) + +#define D3D11_TESSELLATOR_MAX_TESSELLATION_FACTOR ( 64 ) + +#define D3D11_TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR ( 2 ) + +#define D3D11_TESSELLATOR_MIN_ISOLINE_DENSITY_TESSELLATION_FACTOR ( 1 ) + +#define D3D11_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR ( 1 ) + +#define D3D11_TEXEL_ADDRESS_RANGE_BIT_COUNT ( 16 ) + +#define D3D11_UNBOUND_MEMORY_ACCESS_RESULT ( 0 ) + +#define D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX ( 15 ) + +#define D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE ( 16 ) + +#define D3D11_VIEWPORT_BOUNDS_MAX ( 32767 ) + +#define D3D11_VIEWPORT_BOUNDS_MIN ( -32768 ) + +#define D3D11_VS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_VS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_VS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_VS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D11_VS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D11_VS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D11_VS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D11_VS_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D11_WHQL_CONTEXT_COUNT_FOR_RESOURCE_LIMIT ( 10 ) + +#define D3D11_WHQL_DRAWINDEXED_INDEX_COUNT_2_TO_EXP ( 25 ) + +#define D3D11_WHQL_DRAW_VERTEX_COUNT_2_TO_EXP ( 25 ) + +#endif +#define _FACD3D11 ( 0x87c ) + +#define _FACD3D11DEBUG ( ( _FACD3D11 + 1 ) ) + +#define MAKE_D3D11_HRESULT( code ) MAKE_HRESULT( 1, _FACD3D11, code ) +#define MAKE_D3D11_STATUS( code ) MAKE_HRESULT( 0, _FACD3D11, code ) +#define D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS MAKE_D3D11_HRESULT(1) +#define D3D11_ERROR_FILE_NOT_FOUND MAKE_D3D11_HRESULT(2) +#define D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS MAKE_D3D11_HRESULT(3) +#define D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD MAKE_D3D11_HRESULT(4) +#if __SAL_H_FULL_VER < 140050727 +#undef __in_range +#undef __in_xcount_opt +#define __in_range(x, y) +#define __in_xcount_opt(x) +#endif +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3D11_DEFAULT D3D11_DEFAULT; +extern "C"{ +#endif +typedef +enum D3D11_INPUT_CLASSIFICATION + { D3D11_INPUT_PER_VERTEX_DATA = 0, + D3D11_INPUT_PER_INSTANCE_DATA = 1 + } D3D11_INPUT_CLASSIFICATION; + +#define D3D11_APPEND_ALIGNED_ELEMENT ( 0xffffffff ) + +typedef struct D3D11_INPUT_ELEMENT_DESC + { + LPCSTR SemanticName; + UINT SemanticIndex; + DXGI_FORMAT Format; + UINT InputSlot; + UINT AlignedByteOffset; + D3D11_INPUT_CLASSIFICATION InputSlotClass; + UINT InstanceDataStepRate; + } D3D11_INPUT_ELEMENT_DESC; + +typedef +enum D3D11_FILL_MODE + { D3D11_FILL_WIREFRAME = 2, + D3D11_FILL_SOLID = 3 + } D3D11_FILL_MODE; + +typedef D3D_PRIMITIVE_TOPOLOGY D3D11_PRIMITIVE_TOPOLOGY; + +typedef D3D_PRIMITIVE D3D11_PRIMITIVE; + +typedef +enum D3D11_CULL_MODE + { D3D11_CULL_NONE = 1, + D3D11_CULL_FRONT = 2, + D3D11_CULL_BACK = 3 + } D3D11_CULL_MODE; + +typedef struct D3D11_SO_DECLARATION_ENTRY + { + UINT Stream; + LPCSTR SemanticName; + UINT SemanticIndex; + BYTE StartComponent; + BYTE ComponentCount; + BYTE OutputSlot; + } D3D11_SO_DECLARATION_ENTRY; + +typedef struct D3D11_VIEWPORT + { + FLOAT TopLeftX; + FLOAT TopLeftY; + FLOAT Width; + FLOAT Height; + FLOAT MinDepth; + FLOAT MaxDepth; + } D3D11_VIEWPORT; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +inline bool operator==( const D3D11_VIEWPORT& l, const D3D11_VIEWPORT& r ) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} +inline bool operator!=( const D3D11_VIEWPORT& l, const D3D11_VIEWPORT& r ) +{ return !( l == r ); } +extern "C"{ +#endif +typedef +enum D3D11_RESOURCE_DIMENSION + { D3D11_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D11_RESOURCE_DIMENSION_BUFFER = 1, + D3D11_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D11_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D11_RESOURCE_DIMENSION_TEXTURE3D = 4 + } D3D11_RESOURCE_DIMENSION; + +typedef D3D_SRV_DIMENSION D3D11_SRV_DIMENSION; + +typedef +enum D3D11_DSV_DIMENSION + { D3D11_DSV_DIMENSION_UNKNOWN = 0, + D3D11_DSV_DIMENSION_TEXTURE1D = 1, + D3D11_DSV_DIMENSION_TEXTURE1DARRAY = 2, + D3D11_DSV_DIMENSION_TEXTURE2D = 3, + D3D11_DSV_DIMENSION_TEXTURE2DARRAY = 4, + D3D11_DSV_DIMENSION_TEXTURE2DMS = 5, + D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY = 6 + } D3D11_DSV_DIMENSION; + +typedef +enum D3D11_RTV_DIMENSION + { D3D11_RTV_DIMENSION_UNKNOWN = 0, + D3D11_RTV_DIMENSION_BUFFER = 1, + D3D11_RTV_DIMENSION_TEXTURE1D = 2, + D3D11_RTV_DIMENSION_TEXTURE1DARRAY = 3, + D3D11_RTV_DIMENSION_TEXTURE2D = 4, + D3D11_RTV_DIMENSION_TEXTURE2DARRAY = 5, + D3D11_RTV_DIMENSION_TEXTURE2DMS = 6, + D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D11_RTV_DIMENSION_TEXTURE3D = 8 + } D3D11_RTV_DIMENSION; + +typedef +enum D3D11_UAV_DIMENSION + { D3D11_UAV_DIMENSION_UNKNOWN = 0, + D3D11_UAV_DIMENSION_BUFFER = 1, + D3D11_UAV_DIMENSION_TEXTURE1D = 2, + D3D11_UAV_DIMENSION_TEXTURE1DARRAY = 3, + D3D11_UAV_DIMENSION_TEXTURE2D = 4, + D3D11_UAV_DIMENSION_TEXTURE2DARRAY = 5, + D3D11_UAV_DIMENSION_TEXTURE3D = 8 + } D3D11_UAV_DIMENSION; + +typedef +enum D3D11_USAGE + { D3D11_USAGE_DEFAULT = 0, + D3D11_USAGE_IMMUTABLE = 1, + D3D11_USAGE_DYNAMIC = 2, + D3D11_USAGE_STAGING = 3 + } D3D11_USAGE; + +typedef +enum D3D11_BIND_FLAG + { D3D11_BIND_VERTEX_BUFFER = 0x1L, + D3D11_BIND_INDEX_BUFFER = 0x2L, + D3D11_BIND_CONSTANT_BUFFER = 0x4L, + D3D11_BIND_SHADER_RESOURCE = 0x8L, + D3D11_BIND_STREAM_OUTPUT = 0x10L, + D3D11_BIND_RENDER_TARGET = 0x20L, + D3D11_BIND_DEPTH_STENCIL = 0x40L, + D3D11_BIND_UNORDERED_ACCESS = 0x80L + } D3D11_BIND_FLAG; + +typedef +enum D3D11_CPU_ACCESS_FLAG + { D3D11_CPU_ACCESS_WRITE = 0x10000L, + D3D11_CPU_ACCESS_READ = 0x20000L + } D3D11_CPU_ACCESS_FLAG; + +typedef +enum D3D11_RESOURCE_MISC_FLAG + { D3D11_RESOURCE_MISC_GENERATE_MIPS = 0x1L, + D3D11_RESOURCE_MISC_SHARED = 0x2L, + D3D11_RESOURCE_MISC_TEXTURECUBE = 0x4L, + D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS = 0x10L, + D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS = 0x20L, + D3D11_RESOURCE_MISC_BUFFER_STRUCTURED = 0x40L, + D3D11_RESOURCE_MISC_RESOURCE_CLAMP = 0x80L, + D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x100L, + D3D11_RESOURCE_MISC_GDI_COMPATIBLE = 0x200L + } D3D11_RESOURCE_MISC_FLAG; + +typedef +enum D3D11_MAP + { D3D11_MAP_READ = 1, + D3D11_MAP_WRITE = 2, + D3D11_MAP_READ_WRITE = 3, + D3D11_MAP_WRITE_DISCARD = 4, + D3D11_MAP_WRITE_NO_OVERWRITE = 5 + } D3D11_MAP; + +typedef +enum D3D11_MAP_FLAG + { D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L + } D3D11_MAP_FLAG; + +typedef +enum D3D11_RAISE_FLAG + { D3D11_RAISE_FLAG_DRIVER_INTERNAL_ERROR = 0x1L + } D3D11_RAISE_FLAG; + +typedef +enum D3D11_CLEAR_FLAG + { D3D11_CLEAR_DEPTH = 0x1L, + D3D11_CLEAR_STENCIL = 0x2L + } D3D11_CLEAR_FLAG; + +typedef RECT D3D11_RECT; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_RECT : public D3D11_RECT +{ + CD3D11_RECT() + {} + explicit CD3D11_RECT( const D3D11_RECT& o ) : + D3D11_RECT( o ) + {} + explicit CD3D11_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } + ~CD3D11_RECT() {} + operator const D3D11_RECT&() const { return *this; } +}; +inline bool operator==( const D3D11_RECT& l, const D3D11_RECT& r ) +{ + return l.left == r.left && l.top == r.top && + l.right == r.right && l.bottom == r.bottom; +} +inline bool operator!=( const D3D11_RECT& l, const D3D11_RECT& r ) +{ return !( l == r ); } +extern "C"{ +#endif +typedef struct D3D11_BOX + { + UINT left; + UINT top; + UINT front; + UINT right; + UINT bottom; + UINT back; + } D3D11_BOX; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_BOX : public D3D11_BOX +{ + CD3D11_BOX() + {} + explicit CD3D11_BOX( const D3D11_BOX& o ) : + D3D11_BOX( o ) + {} + explicit CD3D11_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) + { + left = Left; + top = Top; + front = Front; + right = Right; + bottom = Bottom; + back = Back; + } + ~CD3D11_BOX() {} + operator const D3D11_BOX&() const { return *this; } +}; +inline bool operator==( const D3D11_BOX& l, const D3D11_BOX& r ) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D11_BOX& l, const D3D11_BOX& r ) +{ return !( l == r ); } +extern "C"{ +#endif + + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D11DeviceChild_INTERFACE_DEFINED__ +#define __ID3D11DeviceChild_INTERFACE_DEFINED__ + +/* interface ID3D11DeviceChild */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11DeviceChild; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1841e5c8-16b0-489b-bcc8-44cfb0d5deae") + ID3D11DeviceChild : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE GetDevice( + /* [annotation] */ + __out ID3D11Device **ppDevice) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11DeviceChildVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11DeviceChild * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11DeviceChild * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11DeviceChild * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11DeviceChild * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11DeviceChild * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11DeviceChild * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11DeviceChild * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11DeviceChildVtbl; + + interface ID3D11DeviceChild + { + CONST_VTBL struct ID3D11DeviceChildVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11DeviceChild_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11DeviceChild_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11DeviceChild_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11DeviceChild_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11DeviceChild_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11DeviceChild_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11DeviceChild_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11DeviceChild_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0001 */ +/* [local] */ + +typedef +enum D3D11_COMPARISON_FUNC + { D3D11_COMPARISON_NEVER = 1, + D3D11_COMPARISON_LESS = 2, + D3D11_COMPARISON_EQUAL = 3, + D3D11_COMPARISON_LESS_EQUAL = 4, + D3D11_COMPARISON_GREATER = 5, + D3D11_COMPARISON_NOT_EQUAL = 6, + D3D11_COMPARISON_GREATER_EQUAL = 7, + D3D11_COMPARISON_ALWAYS = 8 + } D3D11_COMPARISON_FUNC; + +typedef +enum D3D11_DEPTH_WRITE_MASK + { D3D11_DEPTH_WRITE_MASK_ZERO = 0, + D3D11_DEPTH_WRITE_MASK_ALL = 1 + } D3D11_DEPTH_WRITE_MASK; + +typedef +enum D3D11_STENCIL_OP + { D3D11_STENCIL_OP_KEEP = 1, + D3D11_STENCIL_OP_ZERO = 2, + D3D11_STENCIL_OP_REPLACE = 3, + D3D11_STENCIL_OP_INCR_SAT = 4, + D3D11_STENCIL_OP_DECR_SAT = 5, + D3D11_STENCIL_OP_INVERT = 6, + D3D11_STENCIL_OP_INCR = 7, + D3D11_STENCIL_OP_DECR = 8 + } D3D11_STENCIL_OP; + +typedef struct D3D11_DEPTH_STENCILOP_DESC + { + D3D11_STENCIL_OP StencilFailOp; + D3D11_STENCIL_OP StencilDepthFailOp; + D3D11_STENCIL_OP StencilPassOp; + D3D11_COMPARISON_FUNC StencilFunc; + } D3D11_DEPTH_STENCILOP_DESC; + +typedef struct D3D11_DEPTH_STENCIL_DESC + { + BOOL DepthEnable; + D3D11_DEPTH_WRITE_MASK DepthWriteMask; + D3D11_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D11_DEPTH_STENCILOP_DESC FrontFace; + D3D11_DEPTH_STENCILOP_DESC BackFace; + } D3D11_DEPTH_STENCIL_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_DEPTH_STENCIL_DESC : public D3D11_DEPTH_STENCIL_DESC +{ + CD3D11_DEPTH_STENCIL_DESC() + {} + explicit CD3D11_DEPTH_STENCIL_DESC( const D3D11_DEPTH_STENCIL_DESC& o ) : + D3D11_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3D11_DEPTH_STENCIL_DESC( CD3D11_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D11_COMPARISON_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + const D3D11_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3D11_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D11_DEPTH_WRITE_MASK depthWriteMask, + D3D11_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D11_STENCIL_OP frontStencilFailOp, + D3D11_STENCIL_OP frontStencilDepthFailOp, + D3D11_STENCIL_OP frontStencilPassOp, + D3D11_COMPARISON_FUNC frontStencilFunc, + D3D11_STENCIL_OP backStencilFailOp, + D3D11_STENCIL_OP backStencilDepthFailOp, + D3D11_STENCIL_OP backStencilPassOp, + D3D11_COMPARISON_FUNC backStencilFunc ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } + ~CD3D11_DEPTH_STENCIL_DESC() {} + operator const D3D11_DEPTH_STENCIL_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0001_v0_0_s_ifspec; + +#ifndef __ID3D11DepthStencilState_INTERFACE_DEFINED__ +#define __ID3D11DepthStencilState_INTERFACE_DEFINED__ + +/* interface ID3D11DepthStencilState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11DepthStencilState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("03823efb-8d8f-4e1c-9aa2-f64bb2cbfdf1") + ID3D11DepthStencilState : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_DEPTH_STENCIL_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11DepthStencilStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11DepthStencilState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11DepthStencilState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11DepthStencilState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11DepthStencilState * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11DepthStencilState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11DepthStencilState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11DepthStencilState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11DepthStencilState * This, + /* [annotation] */ + __out D3D11_DEPTH_STENCIL_DESC *pDesc); + + END_INTERFACE + } ID3D11DepthStencilStateVtbl; + + interface ID3D11DepthStencilState + { + CONST_VTBL struct ID3D11DepthStencilStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11DepthStencilState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11DepthStencilState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11DepthStencilState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11DepthStencilState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11DepthStencilState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11DepthStencilState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11DepthStencilState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11DepthStencilState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11DepthStencilState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0002 */ +/* [local] */ + +typedef +enum D3D11_BLEND + { D3D11_BLEND_ZERO = 1, + D3D11_BLEND_ONE = 2, + D3D11_BLEND_SRC_COLOR = 3, + D3D11_BLEND_INV_SRC_COLOR = 4, + D3D11_BLEND_SRC_ALPHA = 5, + D3D11_BLEND_INV_SRC_ALPHA = 6, + D3D11_BLEND_DEST_ALPHA = 7, + D3D11_BLEND_INV_DEST_ALPHA = 8, + D3D11_BLEND_DEST_COLOR = 9, + D3D11_BLEND_INV_DEST_COLOR = 10, + D3D11_BLEND_SRC_ALPHA_SAT = 11, + D3D11_BLEND_BLEND_FACTOR = 14, + D3D11_BLEND_INV_BLEND_FACTOR = 15, + D3D11_BLEND_SRC1_COLOR = 16, + D3D11_BLEND_INV_SRC1_COLOR = 17, + D3D11_BLEND_SRC1_ALPHA = 18, + D3D11_BLEND_INV_SRC1_ALPHA = 19 + } D3D11_BLEND; + +typedef +enum D3D11_BLEND_OP + { D3D11_BLEND_OP_ADD = 1, + D3D11_BLEND_OP_SUBTRACT = 2, + D3D11_BLEND_OP_REV_SUBTRACT = 3, + D3D11_BLEND_OP_MIN = 4, + D3D11_BLEND_OP_MAX = 5 + } D3D11_BLEND_OP; + +typedef +enum D3D11_COLOR_WRITE_ENABLE + { D3D11_COLOR_WRITE_ENABLE_RED = 1, + D3D11_COLOR_WRITE_ENABLE_GREEN = 2, + D3D11_COLOR_WRITE_ENABLE_BLUE = 4, + D3D11_COLOR_WRITE_ENABLE_ALPHA = 8, + D3D11_COLOR_WRITE_ENABLE_ALL = ( ( ( D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN ) | D3D11_COLOR_WRITE_ENABLE_BLUE ) | D3D11_COLOR_WRITE_ENABLE_ALPHA ) + } D3D11_COLOR_WRITE_ENABLE; + +typedef struct D3D11_RENDER_TARGET_BLEND_DESC + { + BOOL BlendEnable; + D3D11_BLEND SrcBlend; + D3D11_BLEND DestBlend; + D3D11_BLEND_OP BlendOp; + D3D11_BLEND SrcBlendAlpha; + D3D11_BLEND DestBlendAlpha; + D3D11_BLEND_OP BlendOpAlpha; + UINT8 RenderTargetWriteMask; + } D3D11_RENDER_TARGET_BLEND_DESC; + +typedef struct D3D11_BLEND_DESC + { + BOOL AlphaToCoverageEnable; + BOOL IndependentBlendEnable; + D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[ 8 ]; + } D3D11_BLEND_DESC; + +/* Note, the array size for RenderTarget[] above is D3D11_SIMULTANEOUS_RENDERTARGET_COUNT. + IDL processing/generation of this header replaces the define; this comment is merely explaining what happened. */ +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_BLEND_DESC : public D3D11_BLEND_DESC +{ + CD3D11_BLEND_DESC() + {} + explicit CD3D11_BLEND_DESC( const D3D11_BLEND_DESC& o ) : + D3D11_BLEND_DESC( o ) + {} + explicit CD3D11_BLEND_DESC( CD3D11_DEFAULT ) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D11_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE, + D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, + D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, + D3D11_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } + ~CD3D11_BLEND_DESC() {} + operator const D3D11_BLEND_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0002_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0002_v0_0_s_ifspec; + +#ifndef __ID3D11BlendState_INTERFACE_DEFINED__ +#define __ID3D11BlendState_INTERFACE_DEFINED__ + +/* interface ID3D11BlendState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11BlendState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("75b68faa-347d-4159-8f45-a0640f01cd9a") + ID3D11BlendState : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_BLEND_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11BlendStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11BlendState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11BlendState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11BlendState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11BlendState * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11BlendState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11BlendState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11BlendState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11BlendState * This, + /* [annotation] */ + __out D3D11_BLEND_DESC *pDesc); + + END_INTERFACE + } ID3D11BlendStateVtbl; + + interface ID3D11BlendState + { + CONST_VTBL struct ID3D11BlendStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11BlendState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11BlendState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11BlendState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11BlendState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11BlendState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11BlendState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11BlendState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11BlendState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11BlendState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0003 */ +/* [local] */ + +typedef struct D3D11_RASTERIZER_DESC + { + D3D11_FILL_MODE FillMode; + D3D11_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + INT DepthBias; + FLOAT DepthBiasClamp; + FLOAT SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL ScissorEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; + } D3D11_RASTERIZER_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_RASTERIZER_DESC : public D3D11_RASTERIZER_DESC +{ + CD3D11_RASTERIZER_DESC() + {} + explicit CD3D11_RASTERIZER_DESC( const D3D11_RASTERIZER_DESC& o ) : + D3D11_RASTERIZER_DESC( o ) + {} + explicit CD3D11_RASTERIZER_DESC( CD3D11_DEFAULT ) + { + FillMode = D3D11_FILL_SOLID; + CullMode = D3D11_CULL_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D11_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + ScissorEnable = FALSE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + } + explicit CD3D11_RASTERIZER_DESC( + D3D11_FILL_MODE fillMode, + D3D11_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL scissorEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable ) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + ScissorEnable = scissorEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + } + ~CD3D11_RASTERIZER_DESC() {} + operator const D3D11_RASTERIZER_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0003_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0003_v0_0_s_ifspec; + +#ifndef __ID3D11RasterizerState_INTERFACE_DEFINED__ +#define __ID3D11RasterizerState_INTERFACE_DEFINED__ + +/* interface ID3D11RasterizerState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11RasterizerState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9bb4ab81-ab1a-4d8f-b506-fc04200b6ee7") + ID3D11RasterizerState : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_RASTERIZER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11RasterizerStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11RasterizerState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11RasterizerState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11RasterizerState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11RasterizerState * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11RasterizerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11RasterizerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11RasterizerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11RasterizerState * This, + /* [annotation] */ + __out D3D11_RASTERIZER_DESC *pDesc); + + END_INTERFACE + } ID3D11RasterizerStateVtbl; + + interface ID3D11RasterizerState + { + CONST_VTBL struct ID3D11RasterizerStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11RasterizerState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11RasterizerState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11RasterizerState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11RasterizerState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11RasterizerState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11RasterizerState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11RasterizerState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11RasterizerState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11RasterizerState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0004 */ +/* [local] */ + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +inline UINT D3D11CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT MipLevels ) +{ return MipSlice + ArraySlice * MipLevels; } +extern "C"{ +#endif +typedef struct D3D11_SUBRESOURCE_DATA + { + const void *pSysMem; + UINT SysMemPitch; + UINT SysMemSlicePitch; + } D3D11_SUBRESOURCE_DATA; + +typedef struct D3D11_MAPPED_SUBRESOURCE + { + void *pData; + UINT RowPitch; + UINT DepthPitch; + } D3D11_MAPPED_SUBRESOURCE; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0004_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0004_v0_0_s_ifspec; + +#ifndef __ID3D11Resource_INTERFACE_DEFINED__ +#define __ID3D11Resource_INTERFACE_DEFINED__ + +/* interface ID3D11Resource */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Resource; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("dc8e63f3-d12b-4952-b47b-5e45026a862d") + ID3D11Resource : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetType( + /* [annotation] */ + __out D3D11_RESOURCE_DIMENSION *pResourceDimension) = 0; + + virtual void STDMETHODCALLTYPE SetEvictionPriority( + /* [annotation] */ + __in UINT EvictionPriority) = 0; + + virtual UINT STDMETHODCALLTYPE GetEvictionPriority( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11ResourceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Resource * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Resource * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Resource * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Resource * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Resource * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Resource * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Resource * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D11Resource * This, + /* [annotation] */ + __out D3D11_RESOURCE_DIMENSION *pResourceDimension); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D11Resource * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D11Resource * This); + + END_INTERFACE + } ID3D11ResourceVtbl; + + interface ID3D11Resource + { + CONST_VTBL struct ID3D11ResourceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Resource_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Resource_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Resource_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Resource_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Resource_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Resource_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Resource_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Resource_GetType(This,pResourceDimension) \ + ( (This)->lpVtbl -> GetType(This,pResourceDimension) ) + +#define ID3D11Resource_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D11Resource_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Resource_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0005 */ +/* [local] */ + +typedef struct D3D11_BUFFER_DESC + { + UINT ByteWidth; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + UINT StructureByteStride; + } D3D11_BUFFER_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_BUFFER_DESC : public D3D11_BUFFER_DESC +{ + CD3D11_BUFFER_DESC() + {} + explicit CD3D11_BUFFER_DESC( const D3D11_BUFFER_DESC& o ) : + D3D11_BUFFER_DESC( o ) + {} + explicit CD3D11_BUFFER_DESC( + UINT byteWidth, + UINT bindFlags, + D3D11_USAGE usage = D3D11_USAGE_DEFAULT, + UINT cpuaccessFlags = 0, + UINT miscFlags = 0, + UINT structureByteStride = 0 ) + { + ByteWidth = byteWidth; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags ; + MiscFlags = miscFlags; + StructureByteStride = structureByteStride; + } + ~CD3D11_BUFFER_DESC() {} + operator const D3D11_BUFFER_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0005_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0005_v0_0_s_ifspec; + +#ifndef __ID3D11Buffer_INTERFACE_DEFINED__ +#define __ID3D11Buffer_INTERFACE_DEFINED__ + +/* interface ID3D11Buffer */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Buffer; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("48570b85-d1ee-4fcd-a250-eb350722b037") + ID3D11Buffer : public ID3D11Resource + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_BUFFER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11BufferVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Buffer * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Buffer * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Buffer * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Buffer * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Buffer * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Buffer * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Buffer * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D11Buffer * This, + /* [annotation] */ + __out D3D11_RESOURCE_DIMENSION *pResourceDimension); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D11Buffer * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D11Buffer * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11Buffer * This, + /* [annotation] */ + __out D3D11_BUFFER_DESC *pDesc); + + END_INTERFACE + } ID3D11BufferVtbl; + + interface ID3D11Buffer + { + CONST_VTBL struct ID3D11BufferVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Buffer_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Buffer_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Buffer_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Buffer_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Buffer_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Buffer_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Buffer_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Buffer_GetType(This,pResourceDimension) \ + ( (This)->lpVtbl -> GetType(This,pResourceDimension) ) + +#define ID3D11Buffer_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D11Buffer_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D11Buffer_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Buffer_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0006 */ +/* [local] */ + +typedef struct D3D11_TEXTURE1D_DESC + { + UINT Width; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + } D3D11_TEXTURE1D_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_TEXTURE1D_DESC : public D3D11_TEXTURE1D_DESC +{ + CD3D11_TEXTURE1D_DESC() + {} + explicit CD3D11_TEXTURE1D_DESC( const D3D11_TEXTURE1D_DESC& o ) : + D3D11_TEXTURE1D_DESC( o ) + {} + explicit CD3D11_TEXTURE1D_DESC( + DXGI_FORMAT format, + UINT width, + UINT arraySize = 1, + UINT mipLevels = 0, + UINT bindFlags = D3D11_BIND_SHADER_RESOURCE, + D3D11_USAGE usage = D3D11_USAGE_DEFAULT, + UINT cpuaccessFlags= 0, + UINT miscFlags = 0 ) + { + Width = width; + MipLevels = mipLevels; + ArraySize = arraySize; + Format = format; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags; + MiscFlags = miscFlags; + } + ~CD3D11_TEXTURE1D_DESC() {} + operator const D3D11_TEXTURE1D_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0006_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0006_v0_0_s_ifspec; + +#ifndef __ID3D11Texture1D_INTERFACE_DEFINED__ +#define __ID3D11Texture1D_INTERFACE_DEFINED__ + +/* interface ID3D11Texture1D */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Texture1D; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("f8fb5c27-c6b3-4f75-a4c8-439af2ef564c") + ID3D11Texture1D : public ID3D11Resource + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_TEXTURE1D_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11Texture1DVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Texture1D * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Texture1D * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Texture1D * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Texture1D * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Texture1D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Texture1D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Texture1D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D11Texture1D * This, + /* [annotation] */ + __out D3D11_RESOURCE_DIMENSION *pResourceDimension); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D11Texture1D * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D11Texture1D * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11Texture1D * This, + /* [annotation] */ + __out D3D11_TEXTURE1D_DESC *pDesc); + + END_INTERFACE + } ID3D11Texture1DVtbl; + + interface ID3D11Texture1D + { + CONST_VTBL struct ID3D11Texture1DVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Texture1D_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Texture1D_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Texture1D_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Texture1D_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Texture1D_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Texture1D_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Texture1D_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Texture1D_GetType(This,pResourceDimension) \ + ( (This)->lpVtbl -> GetType(This,pResourceDimension) ) + +#define ID3D11Texture1D_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D11Texture1D_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D11Texture1D_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Texture1D_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0007 */ +/* [local] */ + +typedef struct D3D11_TEXTURE2D_DESC + { + UINT Width; + UINT Height; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + } D3D11_TEXTURE2D_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_TEXTURE2D_DESC : public D3D11_TEXTURE2D_DESC +{ + CD3D11_TEXTURE2D_DESC() + {} + explicit CD3D11_TEXTURE2D_DESC( const D3D11_TEXTURE2D_DESC& o ) : + D3D11_TEXTURE2D_DESC( o ) + {} + explicit CD3D11_TEXTURE2D_DESC( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT arraySize = 1, + UINT mipLevels = 0, + UINT bindFlags = D3D11_BIND_SHADER_RESOURCE, + D3D11_USAGE usage = D3D11_USAGE_DEFAULT, + UINT cpuaccessFlags = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + UINT miscFlags = 0 ) + { + Width = width; + Height = height; + MipLevels = mipLevels; + ArraySize = arraySize; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags; + MiscFlags = miscFlags; + } + ~CD3D11_TEXTURE2D_DESC() {} + operator const D3D11_TEXTURE2D_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0007_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0007_v0_0_s_ifspec; + +#ifndef __ID3D11Texture2D_INTERFACE_DEFINED__ +#define __ID3D11Texture2D_INTERFACE_DEFINED__ + +/* interface ID3D11Texture2D */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Texture2D; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6f15aaf2-d208-4e89-9ab4-489535d34f9c") + ID3D11Texture2D : public ID3D11Resource + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_TEXTURE2D_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11Texture2DVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Texture2D * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Texture2D * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Texture2D * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Texture2D * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Texture2D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Texture2D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Texture2D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D11Texture2D * This, + /* [annotation] */ + __out D3D11_RESOURCE_DIMENSION *pResourceDimension); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D11Texture2D * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D11Texture2D * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11Texture2D * This, + /* [annotation] */ + __out D3D11_TEXTURE2D_DESC *pDesc); + + END_INTERFACE + } ID3D11Texture2DVtbl; + + interface ID3D11Texture2D + { + CONST_VTBL struct ID3D11Texture2DVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Texture2D_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Texture2D_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Texture2D_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Texture2D_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Texture2D_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Texture2D_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Texture2D_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Texture2D_GetType(This,pResourceDimension) \ + ( (This)->lpVtbl -> GetType(This,pResourceDimension) ) + +#define ID3D11Texture2D_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D11Texture2D_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D11Texture2D_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Texture2D_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0008 */ +/* [local] */ + +typedef struct D3D11_TEXTURE3D_DESC + { + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + DXGI_FORMAT Format; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + } D3D11_TEXTURE3D_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_TEXTURE3D_DESC : public D3D11_TEXTURE3D_DESC +{ + CD3D11_TEXTURE3D_DESC() + {} + explicit CD3D11_TEXTURE3D_DESC( const D3D11_TEXTURE3D_DESC& o ) : + D3D11_TEXTURE3D_DESC( o ) + {} + explicit CD3D11_TEXTURE3D_DESC( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT mipLevels = 0, + UINT bindFlags = D3D11_BIND_SHADER_RESOURCE, + D3D11_USAGE usage = D3D11_USAGE_DEFAULT, + UINT cpuaccessFlags = 0, + UINT miscFlags = 0 ) + { + Width = width; + Height = height; + Depth = depth; + MipLevels = mipLevels; + Format = format; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuaccessFlags; + MiscFlags = miscFlags; + } + ~CD3D11_TEXTURE3D_DESC() {} + operator const D3D11_TEXTURE3D_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0008_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0008_v0_0_s_ifspec; + +#ifndef __ID3D11Texture3D_INTERFACE_DEFINED__ +#define __ID3D11Texture3D_INTERFACE_DEFINED__ + +/* interface ID3D11Texture3D */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Texture3D; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("037e866e-f56d-4357-a8af-9dabbe6e250e") + ID3D11Texture3D : public ID3D11Resource + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_TEXTURE3D_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11Texture3DVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Texture3D * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Texture3D * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Texture3D * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Texture3D * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Texture3D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Texture3D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Texture3D * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetType )( + ID3D11Texture3D * This, + /* [annotation] */ + __out D3D11_RESOURCE_DIMENSION *pResourceDimension); + + void ( STDMETHODCALLTYPE *SetEvictionPriority )( + ID3D11Texture3D * This, + /* [annotation] */ + __in UINT EvictionPriority); + + UINT ( STDMETHODCALLTYPE *GetEvictionPriority )( + ID3D11Texture3D * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11Texture3D * This, + /* [annotation] */ + __out D3D11_TEXTURE3D_DESC *pDesc); + + END_INTERFACE + } ID3D11Texture3DVtbl; + + interface ID3D11Texture3D + { + CONST_VTBL struct ID3D11Texture3DVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Texture3D_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Texture3D_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Texture3D_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Texture3D_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Texture3D_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Texture3D_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Texture3D_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Texture3D_GetType(This,pResourceDimension) \ + ( (This)->lpVtbl -> GetType(This,pResourceDimension) ) + +#define ID3D11Texture3D_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define ID3D11Texture3D_GetEvictionPriority(This) \ + ( (This)->lpVtbl -> GetEvictionPriority(This) ) + + +#define ID3D11Texture3D_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Texture3D_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0009 */ +/* [local] */ + +typedef +enum D3D11_TEXTURECUBE_FACE + { D3D11_TEXTURECUBE_FACE_POSITIVE_X = 0, + D3D11_TEXTURECUBE_FACE_NEGATIVE_X = 1, + D3D11_TEXTURECUBE_FACE_POSITIVE_Y = 2, + D3D11_TEXTURECUBE_FACE_NEGATIVE_Y = 3, + D3D11_TEXTURECUBE_FACE_POSITIVE_Z = 4, + D3D11_TEXTURECUBE_FACE_NEGATIVE_Z = 5 + } D3D11_TEXTURECUBE_FACE; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0009_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0009_v0_0_s_ifspec; + +#ifndef __ID3D11View_INTERFACE_DEFINED__ +#define __ID3D11View_INTERFACE_DEFINED__ + +/* interface ID3D11View */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11View; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("839d1216-bb2e-412b-b7f4-a9dbebe08ed1") + ID3D11View : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetResource( + /* [annotation] */ + __out ID3D11Resource **ppResource) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11ViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11View * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11View * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11View * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11View * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11View * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11View * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11View * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D11View * This, + /* [annotation] */ + __out ID3D11Resource **ppResource); + + END_INTERFACE + } ID3D11ViewVtbl; + + interface ID3D11View + { + CONST_VTBL struct ID3D11ViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11View_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11View_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11View_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11View_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11View_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11View_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11View_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11View_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11View_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0010 */ +/* [local] */ + +typedef struct D3D11_BUFFER_SRV + { + union + { + UINT FirstElement; + UINT ElementOffset; + } ; + union + { + UINT NumElements; + UINT ElementWidth; + } ; + } D3D11_BUFFER_SRV; + +typedef +enum D3D11_BUFFEREX_SRV_FLAG + { D3D11_BUFFEREX_SRV_FLAG_RAW = 0x1 + } D3D11_BUFFEREX_SRV_FLAG; + +typedef struct D3D11_BUFFEREX_SRV + { + UINT FirstElement; + UINT NumElements; + UINT Flags; + } D3D11_BUFFEREX_SRV; + +typedef struct D3D11_TEX1D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D11_TEX1D_SRV; + +typedef struct D3D11_TEX1D_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX1D_ARRAY_SRV; + +typedef struct D3D11_TEX2D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D11_TEX2D_SRV; + +typedef struct D3D11_TEX2D_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX2D_ARRAY_SRV; + +typedef struct D3D11_TEX3D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D11_TEX3D_SRV; + +typedef struct D3D11_TEXCUBE_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + } D3D11_TEXCUBE_SRV; + +typedef struct D3D11_TEXCUBE_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT First2DArrayFace; + UINT NumCubes; + } D3D11_TEXCUBE_ARRAY_SRV; + +typedef struct D3D11_TEX2DMS_SRV + { + UINT UnusedField_NothingToDefine; + } D3D11_TEX2DMS_SRV; + +typedef struct D3D11_TEX2DMS_ARRAY_SRV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX2DMS_ARRAY_SRV; + +typedef struct D3D11_SHADER_RESOURCE_VIEW_DESC + { + DXGI_FORMAT Format; + D3D11_SRV_DIMENSION ViewDimension; + union + { + D3D11_BUFFER_SRV Buffer; + D3D11_TEX1D_SRV Texture1D; + D3D11_TEX1D_ARRAY_SRV Texture1DArray; + D3D11_TEX2D_SRV Texture2D; + D3D11_TEX2D_ARRAY_SRV Texture2DArray; + D3D11_TEX2DMS_SRV Texture2DMS; + D3D11_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D11_TEX3D_SRV Texture3D; + D3D11_TEXCUBE_SRV TextureCube; + D3D11_TEXCUBE_ARRAY_SRV TextureCubeArray; + D3D11_BUFFEREX_SRV BufferEx; + } ; + } D3D11_SHADER_RESOURCE_VIEW_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_SHADER_RESOURCE_VIEW_DESC : public D3D11_SHADER_RESOURCE_VIEW_DESC +{ + CD3D11_SHADER_RESOURCE_VIEW_DESC() + {} + explicit CD3D11_SHADER_RESOURCE_VIEW_DESC( const D3D11_SHADER_RESOURCE_VIEW_DESC& o ) : + D3D11_SHADER_RESOURCE_VIEW_DESC( o ) + {} + explicit CD3D11_SHADER_RESOURCE_VIEW_DESC( + D3D11_SRV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mostDetailedMip = 0, // FirstElement for BUFFER + UINT mipLevels = -1, // NumElements for BUFFER + UINT firstArraySlice = 0, // First2DArrayFace for TEXTURECUBEARRAY + UINT arraySize = -1, // NumCubes for TEXTURECUBEARRAY + UINT flags = 0 ) // BUFFEREX only + { + Format = format; + ViewDimension = viewDimension; + switch (viewDimension) + { + case D3D11_SRV_DIMENSION_BUFFER: + Buffer.FirstElement = mostDetailedMip; + Buffer.NumElements = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURE1D: + Texture1D.MostDetailedMip = mostDetailedMip; + Texture1D.MipLevels = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MostDetailedMip = mostDetailedMip; + Texture1DArray.MipLevels = mipLevels; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + case D3D11_SRV_DIMENSION_TEXTURE2D: + Texture2D.MostDetailedMip = mostDetailedMip; + Texture2D.MipLevels = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MostDetailedMip = mostDetailedMip; + Texture2DArray.MipLevels = mipLevels; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + Texture2DMSArray.FirstArraySlice = firstArraySlice; + Texture2DMSArray.ArraySize = arraySize; + break; + case D3D11_SRV_DIMENSION_TEXTURE3D: + Texture3D.MostDetailedMip = mostDetailedMip; + Texture3D.MipLevels = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURECUBE: + TextureCube.MostDetailedMip = mostDetailedMip; + TextureCube.MipLevels = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + TextureCubeArray.MostDetailedMip = mostDetailedMip; + TextureCubeArray.MipLevels = mipLevels; + TextureCubeArray.First2DArrayFace = firstArraySlice; + TextureCubeArray.NumCubes = arraySize; + break; + case D3D11_SRV_DIMENSION_BUFFEREX: + BufferEx.FirstElement = mostDetailedMip; + BufferEx.NumElements = mipLevels; + BufferEx.Flags = flags; + break; + default: break; + } + } + explicit CD3D11_SHADER_RESOURCE_VIEW_DESC( + __in ID3D11Buffer*, + DXGI_FORMAT format, + UINT firstElement, + UINT numElements, + UINT flags = 0 ) + { + Format = format; + ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX; + BufferEx.FirstElement = firstElement; + BufferEx.NumElements = numElements; + BufferEx.Flags = flags; + } + explicit CD3D11_SHADER_RESOURCE_VIEW_DESC( + __in ID3D11Texture1D* pTex1D, + D3D11_SRV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mostDetailedMip = 0, + UINT mipLevels = -1, + UINT firstArraySlice = 0, + UINT arraySize = -1 ) + { + ViewDimension = viewDimension; + if (DXGI_FORMAT_UNKNOWN == format || -1 == mipLevels || + (-1 == arraySize && D3D11_SRV_DIMENSION_TEXTURE1DARRAY == viewDimension)) + { + D3D11_TEXTURE1D_DESC TexDesc; + pTex1D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == mipLevels) mipLevels = TexDesc.MipLevels - mostDetailedMip; + if (-1 == arraySize) arraySize = TexDesc.ArraySize - firstArraySlice; + } + Format = format; + switch (viewDimension) + { + case D3D11_SRV_DIMENSION_TEXTURE1D: + Texture1D.MostDetailedMip = mostDetailedMip; + Texture1D.MipLevels = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MostDetailedMip = mostDetailedMip; + Texture1DArray.MipLevels = mipLevels; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + default: break; + } + } + explicit CD3D11_SHADER_RESOURCE_VIEW_DESC( + __in ID3D11Texture2D* pTex2D, + D3D11_SRV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mostDetailedMip = 0, + UINT mipLevels = -1, + UINT firstArraySlice = 0, // First2DArrayFace for TEXTURECUBEARRAY + UINT arraySize = -1 ) // NumCubes for TEXTURECUBEARRAY + { + ViewDimension = viewDimension; + if (DXGI_FORMAT_UNKNOWN == format || + (-1 == mipLevels && + D3D11_SRV_DIMENSION_TEXTURE2DMS != viewDimension && + D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY != viewDimension) || + (-1 == arraySize && + (D3D11_SRV_DIMENSION_TEXTURE2DARRAY == viewDimension || + D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY == viewDimension || + D3D11_SRV_DIMENSION_TEXTURECUBEARRAY == viewDimension))) + { + D3D11_TEXTURE2D_DESC TexDesc; + pTex2D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == mipLevels) mipLevels = TexDesc.MipLevels - mostDetailedMip; + if (-1 == arraySize) + { + arraySize = TexDesc.ArraySize - firstArraySlice; + if (D3D11_SRV_DIMENSION_TEXTURECUBEARRAY == viewDimension) arraySize /= 6; + } + } + Format = format; + switch (viewDimension) + { + case D3D11_SRV_DIMENSION_TEXTURE2D: + Texture2D.MostDetailedMip = mostDetailedMip; + Texture2D.MipLevels = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MostDetailedMip = mostDetailedMip; + Texture2DArray.MipLevels = mipLevels; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + Texture2DMSArray.FirstArraySlice = firstArraySlice; + Texture2DMSArray.ArraySize = arraySize; + break; + case D3D11_SRV_DIMENSION_TEXTURECUBE: + TextureCube.MostDetailedMip = mostDetailedMip; + TextureCube.MipLevels = mipLevels; + break; + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + TextureCubeArray.MostDetailedMip = mostDetailedMip; + TextureCubeArray.MipLevels = mipLevels; + TextureCubeArray.First2DArrayFace = firstArraySlice; + TextureCubeArray.NumCubes = arraySize; + break; + default: break; + } + } + explicit CD3D11_SHADER_RESOURCE_VIEW_DESC( + __in ID3D11Texture3D* pTex3D, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mostDetailedMip = 0, + UINT mipLevels = -1 ) + { + ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + if (DXGI_FORMAT_UNKNOWN == format || -1 == mipLevels) + { + D3D11_TEXTURE3D_DESC TexDesc; + pTex3D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == mipLevels) mipLevels = TexDesc.MipLevels - mostDetailedMip; + } + Format = format; + Texture3D.MostDetailedMip = mostDetailedMip; + Texture3D.MipLevels = mipLevels; + } + ~CD3D11_SHADER_RESOURCE_VIEW_DESC() {} + operator const D3D11_SHADER_RESOURCE_VIEW_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0010_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0010_v0_0_s_ifspec; + +#ifndef __ID3D11ShaderResourceView_INTERFACE_DEFINED__ +#define __ID3D11ShaderResourceView_INTERFACE_DEFINED__ + +/* interface ID3D11ShaderResourceView */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11ShaderResourceView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b0e06fe0-8192-4e1a-b1ca-36d7414710b2") + ID3D11ShaderResourceView : public ID3D11View + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11ShaderResourceViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11ShaderResourceView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11ShaderResourceView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11ShaderResourceView * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11ShaderResourceView * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11ShaderResourceView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11ShaderResourceView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11ShaderResourceView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D11ShaderResourceView * This, + /* [annotation] */ + __out ID3D11Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11ShaderResourceView * This, + /* [annotation] */ + __out D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc); + + END_INTERFACE + } ID3D11ShaderResourceViewVtbl; + + interface ID3D11ShaderResourceView + { + CONST_VTBL struct ID3D11ShaderResourceViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11ShaderResourceView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11ShaderResourceView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11ShaderResourceView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11ShaderResourceView_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11ShaderResourceView_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11ShaderResourceView_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11ShaderResourceView_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11ShaderResourceView_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D11ShaderResourceView_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11ShaderResourceView_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0011 */ +/* [local] */ + +typedef struct D3D11_BUFFER_RTV + { + union + { + UINT FirstElement; + UINT ElementOffset; + } ; + union + { + UINT NumElements; + UINT ElementWidth; + } ; + } D3D11_BUFFER_RTV; + +typedef struct D3D11_TEX1D_RTV + { + UINT MipSlice; + } D3D11_TEX1D_RTV; + +typedef struct D3D11_TEX1D_ARRAY_RTV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX1D_ARRAY_RTV; + +typedef struct D3D11_TEX2D_RTV + { + UINT MipSlice; + } D3D11_TEX2D_RTV; + +typedef struct D3D11_TEX2DMS_RTV + { + UINT UnusedField_NothingToDefine; + } D3D11_TEX2DMS_RTV; + +typedef struct D3D11_TEX2D_ARRAY_RTV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX2D_ARRAY_RTV; + +typedef struct D3D11_TEX2DMS_ARRAY_RTV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX2DMS_ARRAY_RTV; + +typedef struct D3D11_TEX3D_RTV + { + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; + } D3D11_TEX3D_RTV; + +typedef struct D3D11_RENDER_TARGET_VIEW_DESC + { + DXGI_FORMAT Format; + D3D11_RTV_DIMENSION ViewDimension; + union + { + D3D11_BUFFER_RTV Buffer; + D3D11_TEX1D_RTV Texture1D; + D3D11_TEX1D_ARRAY_RTV Texture1DArray; + D3D11_TEX2D_RTV Texture2D; + D3D11_TEX2D_ARRAY_RTV Texture2DArray; + D3D11_TEX2DMS_RTV Texture2DMS; + D3D11_TEX2DMS_ARRAY_RTV Texture2DMSArray; + D3D11_TEX3D_RTV Texture3D; + } ; + } D3D11_RENDER_TARGET_VIEW_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_RENDER_TARGET_VIEW_DESC : public D3D11_RENDER_TARGET_VIEW_DESC +{ + CD3D11_RENDER_TARGET_VIEW_DESC() + {} + explicit CD3D11_RENDER_TARGET_VIEW_DESC( const D3D11_RENDER_TARGET_VIEW_DESC& o ) : + D3D11_RENDER_TARGET_VIEW_DESC( o ) + {} + explicit CD3D11_RENDER_TARGET_VIEW_DESC( + D3D11_RTV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, // FirstElement for BUFFER + UINT firstArraySlice = 0, // NumElements for BUFFER, FirstWSlice for TEXTURE3D + UINT arraySize = -1 ) // WSize for TEXTURE3D + { + Format = format; + ViewDimension = viewDimension; + switch (viewDimension) + { + case D3D11_RTV_DIMENSION_BUFFER: + Buffer.FirstElement = mipSlice; + Buffer.NumElements = firstArraySlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE1D: + Texture1D.MipSlice = mipSlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MipSlice = mipSlice; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + case D3D11_RTV_DIMENSION_TEXTURE2D: + Texture2D.MipSlice = mipSlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MipSlice = mipSlice; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + break; + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + Texture2DMSArray.FirstArraySlice = firstArraySlice; + Texture2DMSArray.ArraySize = arraySize; + break; + case D3D11_RTV_DIMENSION_TEXTURE3D: + Texture3D.MipSlice = mipSlice; + Texture3D.FirstWSlice = firstArraySlice; + Texture3D.WSize = arraySize; + break; + default: break; + } + } + explicit CD3D11_RENDER_TARGET_VIEW_DESC( + __in ID3D11Buffer*, + DXGI_FORMAT format, + UINT firstElement, + UINT numElements ) + { + Format = format; + ViewDimension = D3D11_RTV_DIMENSION_BUFFER; + Buffer.FirstElement = firstElement; + Buffer.NumElements = numElements; + } + explicit CD3D11_RENDER_TARGET_VIEW_DESC( + __in ID3D11Texture1D* pTex1D, + D3D11_RTV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstArraySlice = 0, + UINT arraySize = -1 ) + { + ViewDimension = viewDimension; + if (DXGI_FORMAT_UNKNOWN == format || + (-1 == arraySize && D3D11_RTV_DIMENSION_TEXTURE1DARRAY == viewDimension)) + { + D3D11_TEXTURE1D_DESC TexDesc; + pTex1D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == arraySize) arraySize = TexDesc.ArraySize - firstArraySlice; + } + Format = format; + switch (viewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE1D: + Texture1D.MipSlice = mipSlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MipSlice = mipSlice; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + default: break; + } + } + explicit CD3D11_RENDER_TARGET_VIEW_DESC( + __in ID3D11Texture2D* pTex2D, + D3D11_RTV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstArraySlice = 0, + UINT arraySize = -1 ) + { + ViewDimension = viewDimension; + if (DXGI_FORMAT_UNKNOWN == format || + (-1 == arraySize && + (D3D11_RTV_DIMENSION_TEXTURE2DARRAY == viewDimension || + D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY == viewDimension))) + { + D3D11_TEXTURE2D_DESC TexDesc; + pTex2D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == arraySize) arraySize = TexDesc.ArraySize - firstArraySlice; + } + Format = format; + switch (viewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE2D: + Texture2D.MipSlice = mipSlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MipSlice = mipSlice; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + break; + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + Texture2DMSArray.FirstArraySlice = firstArraySlice; + Texture2DMSArray.ArraySize = arraySize; + break; + default: break; + } + } + explicit CD3D11_RENDER_TARGET_VIEW_DESC( + __in ID3D11Texture3D* pTex3D, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstWSlice = 0, + UINT wSize = -1 ) + { + ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + if (DXGI_FORMAT_UNKNOWN == format || -1 == wSize) + { + D3D11_TEXTURE3D_DESC TexDesc; + pTex3D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == wSize) wSize = TexDesc.Depth - firstWSlice; + } + Format = format; + Texture3D.MipSlice = mipSlice; + Texture3D.FirstWSlice = firstWSlice; + Texture3D.WSize = wSize; + } + ~CD3D11_RENDER_TARGET_VIEW_DESC() {} + operator const D3D11_RENDER_TARGET_VIEW_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0011_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0011_v0_0_s_ifspec; + +#ifndef __ID3D11RenderTargetView_INTERFACE_DEFINED__ +#define __ID3D11RenderTargetView_INTERFACE_DEFINED__ + +/* interface ID3D11RenderTargetView */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11RenderTargetView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("dfdba067-0b8d-4865-875b-d7b4516cc164") + ID3D11RenderTargetView : public ID3D11View + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_RENDER_TARGET_VIEW_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11RenderTargetViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11RenderTargetView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11RenderTargetView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11RenderTargetView * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11RenderTargetView * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11RenderTargetView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11RenderTargetView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11RenderTargetView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D11RenderTargetView * This, + /* [annotation] */ + __out ID3D11Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11RenderTargetView * This, + /* [annotation] */ + __out D3D11_RENDER_TARGET_VIEW_DESC *pDesc); + + END_INTERFACE + } ID3D11RenderTargetViewVtbl; + + interface ID3D11RenderTargetView + { + CONST_VTBL struct ID3D11RenderTargetViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11RenderTargetView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11RenderTargetView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11RenderTargetView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11RenderTargetView_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11RenderTargetView_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11RenderTargetView_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11RenderTargetView_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11RenderTargetView_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D11RenderTargetView_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11RenderTargetView_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0012 */ +/* [local] */ + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_VIEWPORT : public D3D11_VIEWPORT +{ + CD3D11_VIEWPORT() + {} + explicit CD3D11_VIEWPORT( const D3D11_VIEWPORT& o ) : + D3D11_VIEWPORT( o ) + {} + explicit CD3D11_VIEWPORT( + FLOAT topLeftX, + FLOAT topLeftY, + FLOAT width, + FLOAT height, + FLOAT minDepth = D3D11_MIN_DEPTH, + FLOAT maxDepth = D3D11_MAX_DEPTH ) + { + TopLeftX = topLeftX; + TopLeftY = topLeftY; + Width = width; + Height = height; + MinDepth = minDepth; + MaxDepth = maxDepth; + } + explicit CD3D11_VIEWPORT( + __in ID3D11Buffer*, + __in ID3D11RenderTargetView* pRTView, + FLOAT topLeftX = 0.0f, + FLOAT minDepth = D3D11_MIN_DEPTH, + FLOAT maxDepth = D3D11_MAX_DEPTH ) + { + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; + pRTView->GetDesc( &RTVDesc ); + UINT NumElements = 0; + switch (RTVDesc.ViewDimension) + { + case D3D11_RTV_DIMENSION_BUFFER: + NumElements = RTVDesc.Buffer.NumElements; + break; + default: break; + } + TopLeftX = topLeftX; + TopLeftY = 0.0f; + Width = NumElements - topLeftX; + Height = 1.0f; + MinDepth = minDepth; + MaxDepth = maxDepth; + } + explicit CD3D11_VIEWPORT( + __in ID3D11Texture1D* pTex1D, + __in ID3D11RenderTargetView* pRTView, + FLOAT topLeftX = 0.0f, + FLOAT minDepth = D3D11_MIN_DEPTH, + FLOAT maxDepth = D3D11_MAX_DEPTH ) + { + D3D11_TEXTURE1D_DESC TexDesc; + pTex1D->GetDesc( &TexDesc ); + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; + pRTView->GetDesc( &RTVDesc ); + UINT MipSlice = 0; + switch (RTVDesc.ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE1D: + MipSlice = RTVDesc.Texture1D.MipSlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + MipSlice = RTVDesc.Texture1DArray.MipSlice; + break; + default: break; + } + const UINT SubResourceWidth = TexDesc.Width / (UINT( 1 ) << MipSlice); + TopLeftX = topLeftX; + TopLeftY = 0.0f; + Width = (SubResourceWidth ? SubResourceWidth : 1) - topLeftX; + Height = 1.0f; + MinDepth = minDepth; + MaxDepth = maxDepth; + } + explicit CD3D11_VIEWPORT( + __in ID3D11Texture2D* pTex2D, + __in ID3D11RenderTargetView* pRTView, + FLOAT topLeftX = 0.0f, + FLOAT topLeftY = 0.0f, + FLOAT minDepth = D3D11_MIN_DEPTH, + FLOAT maxDepth = D3D11_MAX_DEPTH ) + { + D3D11_TEXTURE2D_DESC TexDesc; + pTex2D->GetDesc( &TexDesc ); + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; + pRTView->GetDesc( &RTVDesc ); + UINT MipSlice = 0; + switch (RTVDesc.ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE2D: + MipSlice = RTVDesc.Texture2D.MipSlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + MipSlice = RTVDesc.Texture2DArray.MipSlice; + break; + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + break; + default: break; + } + const UINT SubResourceWidth = TexDesc.Width / (UINT( 1 ) << MipSlice); + const UINT SubResourceHeight = TexDesc.Height / (UINT( 1 ) << MipSlice); + TopLeftX = topLeftX; + TopLeftY = topLeftY; + Width = (SubResourceWidth ? SubResourceWidth : 1) - topLeftX; + Height = (SubResourceHeight ? SubResourceHeight : 1) - topLeftY; + MinDepth = minDepth; + MaxDepth = maxDepth; + } + explicit CD3D11_VIEWPORT( + __in ID3D11Texture3D* pTex3D, + __in ID3D11RenderTargetView* pRTView, + FLOAT topLeftX = 0.0f, + FLOAT topLeftY = 0.0f, + FLOAT minDepth = D3D11_MIN_DEPTH, + FLOAT maxDepth = D3D11_MAX_DEPTH ) + { + D3D11_TEXTURE3D_DESC TexDesc; + pTex3D->GetDesc( &TexDesc ); + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; + pRTView->GetDesc( &RTVDesc ); + UINT MipSlice = 0; + switch (RTVDesc.ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE3D: + MipSlice = RTVDesc.Texture3D.MipSlice; + break; + default: break; + } + const UINT SubResourceWidth = TexDesc.Width / (UINT( 1 ) << MipSlice); + const UINT SubResourceHeight = TexDesc.Height / (UINT( 1 ) << MipSlice); + TopLeftX = topLeftX; + TopLeftY = topLeftY; + Width = (SubResourceWidth ? SubResourceWidth : 1) - topLeftX; + Height = (SubResourceHeight ? SubResourceHeight : 1) - topLeftY; + MinDepth = minDepth; + MaxDepth = maxDepth; + } + ~CD3D11_VIEWPORT() {} + operator const D3D11_VIEWPORT&() const { return *this; } +}; +extern "C"{ +#endif +typedef struct D3D11_TEX1D_DSV + { + UINT MipSlice; + } D3D11_TEX1D_DSV; + +typedef struct D3D11_TEX1D_ARRAY_DSV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX1D_ARRAY_DSV; + +typedef struct D3D11_TEX2D_DSV + { + UINT MipSlice; + } D3D11_TEX2D_DSV; + +typedef struct D3D11_TEX2D_ARRAY_DSV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX2D_ARRAY_DSV; + +typedef struct D3D11_TEX2DMS_DSV + { + UINT UnusedField_NothingToDefine; + } D3D11_TEX2DMS_DSV; + +typedef struct D3D11_TEX2DMS_ARRAY_DSV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX2DMS_ARRAY_DSV; + +typedef +enum D3D11_DSV_FLAG + { D3D11_DSV_READ_ONLY_DEPTH = 0x1L, + D3D11_DSV_READ_ONLY_STENCIL = 0x2L + } D3D11_DSV_FLAG; + +typedef struct D3D11_DEPTH_STENCIL_VIEW_DESC + { + DXGI_FORMAT Format; + D3D11_DSV_DIMENSION ViewDimension; + UINT Flags; + union + { + D3D11_TEX1D_DSV Texture1D; + D3D11_TEX1D_ARRAY_DSV Texture1DArray; + D3D11_TEX2D_DSV Texture2D; + D3D11_TEX2D_ARRAY_DSV Texture2DArray; + D3D11_TEX2DMS_DSV Texture2DMS; + D3D11_TEX2DMS_ARRAY_DSV Texture2DMSArray; + } ; + } D3D11_DEPTH_STENCIL_VIEW_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_DEPTH_STENCIL_VIEW_DESC : public D3D11_DEPTH_STENCIL_VIEW_DESC +{ + CD3D11_DEPTH_STENCIL_VIEW_DESC() + {} + explicit CD3D11_DEPTH_STENCIL_VIEW_DESC( const D3D11_DEPTH_STENCIL_VIEW_DESC& o ) : + D3D11_DEPTH_STENCIL_VIEW_DESC( o ) + {} + explicit CD3D11_DEPTH_STENCIL_VIEW_DESC( + D3D11_DSV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstArraySlice = 0, + UINT arraySize = -1, + UINT flags = 0 ) + { + Format = format; + ViewDimension = viewDimension; + Flags = flags; + switch (viewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1D: + Texture1D.MipSlice = mipSlice; + break; + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MipSlice = mipSlice; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + case D3D11_DSV_DIMENSION_TEXTURE2D: + Texture2D.MipSlice = mipSlice; + break; + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MipSlice = mipSlice; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + break; + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + Texture2DMSArray.FirstArraySlice = firstArraySlice; + Texture2DMSArray.ArraySize = arraySize; + break; + default: break; + } + } + explicit CD3D11_DEPTH_STENCIL_VIEW_DESC( + __in ID3D11Texture1D* pTex1D, + D3D11_DSV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstArraySlice = 0, + UINT arraySize = -1, + UINT flags = 0 ) + { + ViewDimension = viewDimension; + Flags = flags; + if (DXGI_FORMAT_UNKNOWN == format || + (-1 == arraySize && D3D11_DSV_DIMENSION_TEXTURE1DARRAY == viewDimension)) + { + D3D11_TEXTURE1D_DESC TexDesc; + pTex1D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == arraySize) arraySize = TexDesc.ArraySize - firstArraySlice; + } + Format = format; + switch (viewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1D: + Texture1D.MipSlice = mipSlice; + break; + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MipSlice = mipSlice; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + default: break; + } + } + explicit CD3D11_DEPTH_STENCIL_VIEW_DESC( + __in ID3D11Texture2D* pTex2D, + D3D11_DSV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstArraySlice = 0, + UINT arraySize = -1, + UINT flags = 0 ) + { + ViewDimension = viewDimension; + Flags = flags; + if (DXGI_FORMAT_UNKNOWN == format || + (-1 == arraySize && + (D3D11_DSV_DIMENSION_TEXTURE2DARRAY == viewDimension || + D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY == viewDimension))) + { + D3D11_TEXTURE2D_DESC TexDesc; + pTex2D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == arraySize) arraySize = TexDesc.ArraySize - firstArraySlice; + } + Format = format; + switch (viewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE2D: + Texture2D.MipSlice = mipSlice; + break; + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MipSlice = mipSlice; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + break; + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + Texture2DMSArray.FirstArraySlice = firstArraySlice; + Texture2DMSArray.ArraySize = arraySize; + break; + default: break; + } + } + ~CD3D11_DEPTH_STENCIL_VIEW_DESC() {} + operator const D3D11_DEPTH_STENCIL_VIEW_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0012_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0012_v0_0_s_ifspec; + +#ifndef __ID3D11DepthStencilView_INTERFACE_DEFINED__ +#define __ID3D11DepthStencilView_INTERFACE_DEFINED__ + +/* interface ID3D11DepthStencilView */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11DepthStencilView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9fdac92a-1876-48c3-afad-25b94f84a9b6") + ID3D11DepthStencilView : public ID3D11View + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11DepthStencilViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11DepthStencilView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11DepthStencilView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11DepthStencilView * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11DepthStencilView * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11DepthStencilView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11DepthStencilView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11DepthStencilView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D11DepthStencilView * This, + /* [annotation] */ + __out ID3D11Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11DepthStencilView * This, + /* [annotation] */ + __out D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc); + + END_INTERFACE + } ID3D11DepthStencilViewVtbl; + + interface ID3D11DepthStencilView + { + CONST_VTBL struct ID3D11DepthStencilViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11DepthStencilView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11DepthStencilView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11DepthStencilView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11DepthStencilView_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11DepthStencilView_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11DepthStencilView_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11DepthStencilView_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11DepthStencilView_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D11DepthStencilView_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11DepthStencilView_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0013 */ +/* [local] */ + +typedef +enum D3D11_BUFFER_UAV_FLAG + { D3D11_BUFFER_UAV_FLAG_RAW = 0x1, + D3D11_BUFFER_UAV_FLAG_APPEND = 0x2, + D3D11_BUFFER_UAV_FLAG_COUNTER = 0x4 + } D3D11_BUFFER_UAV_FLAG; + +typedef struct D3D11_BUFFER_UAV + { + UINT FirstElement; + UINT NumElements; + UINT Flags; + } D3D11_BUFFER_UAV; + +typedef struct D3D11_TEX1D_UAV + { + UINT MipSlice; + } D3D11_TEX1D_UAV; + +typedef struct D3D11_TEX1D_ARRAY_UAV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX1D_ARRAY_UAV; + +typedef struct D3D11_TEX2D_UAV + { + UINT MipSlice; + } D3D11_TEX2D_UAV; + +typedef struct D3D11_TEX2D_ARRAY_UAV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D11_TEX2D_ARRAY_UAV; + +typedef struct D3D11_TEX3D_UAV + { + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; + } D3D11_TEX3D_UAV; + +typedef struct D3D11_UNORDERED_ACCESS_VIEW_DESC + { + DXGI_FORMAT Format; + D3D11_UAV_DIMENSION ViewDimension; + union + { + D3D11_BUFFER_UAV Buffer; + D3D11_TEX1D_UAV Texture1D; + D3D11_TEX1D_ARRAY_UAV Texture1DArray; + D3D11_TEX2D_UAV Texture2D; + D3D11_TEX2D_ARRAY_UAV Texture2DArray; + D3D11_TEX3D_UAV Texture3D; + } ; + } D3D11_UNORDERED_ACCESS_VIEW_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_UNORDERED_ACCESS_VIEW_DESC : public D3D11_UNORDERED_ACCESS_VIEW_DESC +{ + CD3D11_UNORDERED_ACCESS_VIEW_DESC() + {} + explicit CD3D11_UNORDERED_ACCESS_VIEW_DESC( const D3D11_UNORDERED_ACCESS_VIEW_DESC& o ) : + D3D11_UNORDERED_ACCESS_VIEW_DESC( o ) + {} + explicit CD3D11_UNORDERED_ACCESS_VIEW_DESC( + D3D11_UAV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, // FirstElement for BUFFER + UINT firstArraySlice = 0, // NumElements for BUFFER, FirstWSlice for TEXTURE3D + UINT arraySize = -1, // WSize for TEXTURE3D + UINT flags = 0 ) // BUFFER only + { + Format = format; + ViewDimension = viewDimension; + switch (viewDimension) + { + case D3D11_UAV_DIMENSION_BUFFER: + Buffer.FirstElement = mipSlice; + Buffer.NumElements = firstArraySlice; + Buffer.Flags = flags; + break; + case D3D11_UAV_DIMENSION_TEXTURE1D: + Texture1D.MipSlice = mipSlice; + break; + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MipSlice = mipSlice; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + case D3D11_UAV_DIMENSION_TEXTURE2D: + Texture2D.MipSlice = mipSlice; + break; + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MipSlice = mipSlice; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + case D3D11_UAV_DIMENSION_TEXTURE3D: + Texture3D.MipSlice = mipSlice; + Texture3D.FirstWSlice = firstArraySlice; + Texture3D.WSize = arraySize; + break; + default: break; + } + } + explicit CD3D11_UNORDERED_ACCESS_VIEW_DESC( + __in ID3D11Buffer*, + DXGI_FORMAT format, + UINT firstElement, + UINT numElements, + UINT flags = 0 ) + { + Format = format; + ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + Buffer.FirstElement = firstElement; + Buffer.NumElements = numElements; + Buffer.Flags = flags; + } + explicit CD3D11_UNORDERED_ACCESS_VIEW_DESC( + __in ID3D11Texture1D* pTex1D, + D3D11_UAV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstArraySlice = 0, + UINT arraySize = -1 ) + { + ViewDimension = viewDimension; + if (DXGI_FORMAT_UNKNOWN == format || + (-1 == arraySize && D3D11_UAV_DIMENSION_TEXTURE1DARRAY == viewDimension)) + { + D3D11_TEXTURE1D_DESC TexDesc; + pTex1D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == arraySize) arraySize = TexDesc.ArraySize - firstArraySlice; + } + Format = format; + switch (viewDimension) + { + case D3D11_UAV_DIMENSION_TEXTURE1D: + Texture1D.MipSlice = mipSlice; + break; + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: + Texture1DArray.MipSlice = mipSlice; + Texture1DArray.FirstArraySlice = firstArraySlice; + Texture1DArray.ArraySize = arraySize; + break; + default: break; + } + } + explicit CD3D11_UNORDERED_ACCESS_VIEW_DESC( + __in ID3D11Texture2D* pTex2D, + D3D11_UAV_DIMENSION viewDimension, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstArraySlice = 0, + UINT arraySize = -1 ) + { + ViewDimension = viewDimension; + if (DXGI_FORMAT_UNKNOWN == format || + (-1 == arraySize && D3D11_UAV_DIMENSION_TEXTURE2DARRAY == viewDimension)) + { + D3D11_TEXTURE2D_DESC TexDesc; + pTex2D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == arraySize) arraySize = TexDesc.ArraySize - firstArraySlice; + } + Format = format; + switch (viewDimension) + { + case D3D11_UAV_DIMENSION_TEXTURE2D: + Texture2D.MipSlice = mipSlice; + break; + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + Texture2DArray.MipSlice = mipSlice; + Texture2DArray.FirstArraySlice = firstArraySlice; + Texture2DArray.ArraySize = arraySize; + break; + default: break; + } + } + explicit CD3D11_UNORDERED_ACCESS_VIEW_DESC( + __in ID3D11Texture3D* pTex3D, + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, + UINT mipSlice = 0, + UINT firstWSlice = 0, + UINT wSize = -1 ) + { + ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; + if (DXGI_FORMAT_UNKNOWN == format || -1 == wSize) + { + D3D11_TEXTURE3D_DESC TexDesc; + pTex3D->GetDesc( &TexDesc ); + if (DXGI_FORMAT_UNKNOWN == format) format = TexDesc.Format; + if (-1 == wSize) wSize = TexDesc.Depth - firstWSlice; + } + Format = format; + Texture3D.MipSlice = mipSlice; + Texture3D.FirstWSlice = firstWSlice; + Texture3D.WSize = wSize; + } + ~CD3D11_UNORDERED_ACCESS_VIEW_DESC() {} + operator const D3D11_UNORDERED_ACCESS_VIEW_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0013_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0013_v0_0_s_ifspec; + +#ifndef __ID3D11UnorderedAccessView_INTERFACE_DEFINED__ +#define __ID3D11UnorderedAccessView_INTERFACE_DEFINED__ + +/* interface ID3D11UnorderedAccessView */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11UnorderedAccessView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("28acf509-7f5c-48f6-8611-f316010a6380") + ID3D11UnorderedAccessView : public ID3D11View + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11UnorderedAccessViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11UnorderedAccessView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11UnorderedAccessView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11UnorderedAccessView * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11UnorderedAccessView * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11UnorderedAccessView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11UnorderedAccessView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11UnorderedAccessView * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetResource )( + ID3D11UnorderedAccessView * This, + /* [annotation] */ + __out ID3D11Resource **ppResource); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11UnorderedAccessView * This, + /* [annotation] */ + __out D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc); + + END_INTERFACE + } ID3D11UnorderedAccessViewVtbl; + + interface ID3D11UnorderedAccessView + { + CONST_VTBL struct ID3D11UnorderedAccessViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11UnorderedAccessView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11UnorderedAccessView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11UnorderedAccessView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11UnorderedAccessView_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11UnorderedAccessView_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11UnorderedAccessView_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11UnorderedAccessView_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11UnorderedAccessView_GetResource(This,ppResource) \ + ( (This)->lpVtbl -> GetResource(This,ppResource) ) + + +#define ID3D11UnorderedAccessView_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11UnorderedAccessView_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11VertexShader_INTERFACE_DEFINED__ +#define __ID3D11VertexShader_INTERFACE_DEFINED__ + +/* interface ID3D11VertexShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11VertexShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3b301d64-d678-4289-8897-22f8928b72f3") + ID3D11VertexShader : public ID3D11DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11VertexShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11VertexShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11VertexShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11VertexShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11VertexShader * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11VertexShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11VertexShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11VertexShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11VertexShaderVtbl; + + interface ID3D11VertexShader + { + CONST_VTBL struct ID3D11VertexShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11VertexShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11VertexShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11VertexShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11VertexShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11VertexShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11VertexShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11VertexShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11VertexShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11HullShader_INTERFACE_DEFINED__ +#define __ID3D11HullShader_INTERFACE_DEFINED__ + +/* interface ID3D11HullShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11HullShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8e5c6061-628a-4c8e-8264-bbe45cb3d5dd") + ID3D11HullShader : public ID3D11DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11HullShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11HullShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11HullShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11HullShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11HullShader * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11HullShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11HullShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11HullShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11HullShaderVtbl; + + interface ID3D11HullShader + { + CONST_VTBL struct ID3D11HullShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11HullShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11HullShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11HullShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11HullShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11HullShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11HullShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11HullShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11HullShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11DomainShader_INTERFACE_DEFINED__ +#define __ID3D11DomainShader_INTERFACE_DEFINED__ + +/* interface ID3D11DomainShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11DomainShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("f582c508-0f36-490c-9977-31eece268cfa") + ID3D11DomainShader : public ID3D11DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11DomainShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11DomainShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11DomainShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11DomainShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11DomainShader * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11DomainShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11DomainShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11DomainShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11DomainShaderVtbl; + + interface ID3D11DomainShader + { + CONST_VTBL struct ID3D11DomainShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11DomainShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11DomainShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11DomainShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11DomainShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11DomainShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11DomainShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11DomainShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11DomainShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11GeometryShader_INTERFACE_DEFINED__ +#define __ID3D11GeometryShader_INTERFACE_DEFINED__ + +/* interface ID3D11GeometryShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11GeometryShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("38325b96-effb-4022-ba02-2e795b70275c") + ID3D11GeometryShader : public ID3D11DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11GeometryShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11GeometryShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11GeometryShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11GeometryShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11GeometryShader * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11GeometryShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11GeometryShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11GeometryShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11GeometryShaderVtbl; + + interface ID3D11GeometryShader + { + CONST_VTBL struct ID3D11GeometryShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11GeometryShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11GeometryShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11GeometryShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11GeometryShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11GeometryShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11GeometryShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11GeometryShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11GeometryShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11PixelShader_INTERFACE_DEFINED__ +#define __ID3D11PixelShader_INTERFACE_DEFINED__ + +/* interface ID3D11PixelShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11PixelShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ea82e40d-51dc-4f33-93d4-db7c9125ae8c") + ID3D11PixelShader : public ID3D11DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11PixelShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11PixelShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11PixelShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11PixelShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11PixelShader * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11PixelShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11PixelShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11PixelShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11PixelShaderVtbl; + + interface ID3D11PixelShader + { + CONST_VTBL struct ID3D11PixelShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11PixelShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11PixelShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11PixelShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11PixelShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11PixelShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11PixelShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11PixelShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11PixelShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11ComputeShader_INTERFACE_DEFINED__ +#define __ID3D11ComputeShader_INTERFACE_DEFINED__ + +/* interface ID3D11ComputeShader */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11ComputeShader; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4f5b196e-c2bd-495e-bd01-1fded38e4969") + ID3D11ComputeShader : public ID3D11DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11ComputeShaderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11ComputeShader * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11ComputeShader * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11ComputeShader * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11ComputeShader * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11ComputeShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11ComputeShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11ComputeShader * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11ComputeShaderVtbl; + + interface ID3D11ComputeShader + { + CONST_VTBL struct ID3D11ComputeShaderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11ComputeShader_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11ComputeShader_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11ComputeShader_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11ComputeShader_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11ComputeShader_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11ComputeShader_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11ComputeShader_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11ComputeShader_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11InputLayout_INTERFACE_DEFINED__ +#define __ID3D11InputLayout_INTERFACE_DEFINED__ + +/* interface ID3D11InputLayout */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11InputLayout; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e4819ddc-4cf0-4025-bd26-5de82a3e07b7") + ID3D11InputLayout : public ID3D11DeviceChild + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11InputLayoutVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11InputLayout * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11InputLayout * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11InputLayout * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11InputLayout * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11InputLayout * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11InputLayout * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11InputLayout * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + END_INTERFACE + } ID3D11InputLayoutVtbl; + + interface ID3D11InputLayout + { + CONST_VTBL struct ID3D11InputLayoutVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11InputLayout_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11InputLayout_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11InputLayout_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11InputLayout_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11InputLayout_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11InputLayout_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11InputLayout_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11InputLayout_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0021 */ +/* [local] */ + +typedef +enum D3D11_FILTER + { D3D11_FILTER_MIN_MAG_MIP_POINT = 0, + D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x1, + D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x4, + D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x5, + D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, + D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, + D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, + D3D11_FILTER_MIN_MAG_MIP_LINEAR = 0x15, + D3D11_FILTER_ANISOTROPIC = 0x55, + D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, + D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, + D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, + D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, + D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, + D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, + D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, + D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, + D3D11_FILTER_COMPARISON_ANISOTROPIC = 0xd5 + } D3D11_FILTER; + +typedef +enum D3D11_FILTER_TYPE + { D3D11_FILTER_TYPE_POINT = 0, + D3D11_FILTER_TYPE_LINEAR = 1 + } D3D11_FILTER_TYPE; + +#define D3D11_FILTER_TYPE_MASK ( 0x3 ) + +#define D3D11_MIN_FILTER_SHIFT ( 4 ) + +#define D3D11_MAG_FILTER_SHIFT ( 2 ) + +#define D3D11_MIP_FILTER_SHIFT ( 0 ) + +#define D3D11_COMPARISON_FILTERING_BIT ( 0x80 ) + +#define D3D11_ANISOTROPIC_FILTERING_BIT ( 0x40 ) + +#define D3D11_ENCODE_BASIC_FILTER( min, mag, mip, bComparison ) \ + ( ( D3D11_FILTER ) ( \ + ( ( bComparison ) ? D3D11_COMPARISON_FILTERING_BIT : 0 ) | \ + ( ( ( min ) & D3D11_FILTER_TYPE_MASK ) << D3D11_MIN_FILTER_SHIFT ) | \ + ( ( ( mag ) & D3D11_FILTER_TYPE_MASK ) << D3D11_MAG_FILTER_SHIFT ) | \ + ( ( ( mip ) & D3D11_FILTER_TYPE_MASK ) << D3D11_MIP_FILTER_SHIFT ) ) ) +#define D3D11_ENCODE_ANISOTROPIC_FILTER( bComparison ) \ + ( ( D3D11_FILTER ) ( \ + D3D11_ANISOTROPIC_FILTERING_BIT | \ + D3D11_ENCODE_BASIC_FILTER( D3D11_FILTER_TYPE_LINEAR, \ + D3D11_FILTER_TYPE_LINEAR, \ + D3D11_FILTER_TYPE_LINEAR, \ + bComparison ) ) ) +#define D3D11_DECODE_MIN_FILTER( d3d11Filter ) \ + ( ( D3D11_FILTER_TYPE ) \ + ( ( ( d3d11Filter ) >> D3D11_MIN_FILTER_SHIFT ) & D3D11_FILTER_TYPE_MASK ) ) +#define D3D11_DECODE_MAG_FILTER( d3d11Filter ) \ + ( ( D3D11_FILTER_TYPE ) \ + ( ( ( d3d11Filter ) >> D3D11_MAG_FILTER_SHIFT ) & D3D11_FILTER_TYPE_MASK ) ) +#define D3D11_DECODE_MIP_FILTER( d3d11Filter ) \ + ( ( D3D11_FILTER_TYPE ) \ + ( ( ( d3d11Filter ) >> D3D11_MIP_FILTER_SHIFT ) & D3D11_FILTER_TYPE_MASK ) ) +#define D3D11_DECODE_IS_COMPARISON_FILTER( d3d11Filter ) \ + ( ( d3d11Filter ) & D3D11_COMPARISON_FILTERING_BIT ) +#define D3D11_DECODE_IS_ANISOTROPIC_FILTER( d3d11Filter ) \ + ( ( ( d3d11Filter ) & D3D11_ANISOTROPIC_FILTERING_BIT ) && \ + ( D3D11_FILTER_TYPE_LINEAR == D3D11_DECODE_MIN_FILTER( d3d11Filter ) ) && \ + ( D3D11_FILTER_TYPE_LINEAR == D3D11_DECODE_MAG_FILTER( d3d11Filter ) ) && \ + ( D3D11_FILTER_TYPE_LINEAR == D3D11_DECODE_MIP_FILTER( d3d11Filter ) ) ) +typedef +enum D3D11_TEXTURE_ADDRESS_MODE + { D3D11_TEXTURE_ADDRESS_WRAP = 1, + D3D11_TEXTURE_ADDRESS_MIRROR = 2, + D3D11_TEXTURE_ADDRESS_CLAMP = 3, + D3D11_TEXTURE_ADDRESS_BORDER = 4, + D3D11_TEXTURE_ADDRESS_MIRROR_ONCE = 5 + } D3D11_TEXTURE_ADDRESS_MODE; + +typedef struct D3D11_SAMPLER_DESC + { + D3D11_FILTER Filter; + D3D11_TEXTURE_ADDRESS_MODE AddressU; + D3D11_TEXTURE_ADDRESS_MODE AddressV; + D3D11_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D11_COMPARISON_FUNC ComparisonFunc; + FLOAT BorderColor[ 4 ]; + FLOAT MinLOD; + FLOAT MaxLOD; + } D3D11_SAMPLER_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_SAMPLER_DESC : public D3D11_SAMPLER_DESC +{ + CD3D11_SAMPLER_DESC() + {} + explicit CD3D11_SAMPLER_DESC( const D3D11_SAMPLER_DESC& o ) : + D3D11_SAMPLER_DESC( o ) + {} + explicit CD3D11_SAMPLER_DESC( CD3D11_DEFAULT ) + { + Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + MipLODBias = 0; + MaxAnisotropy = 1; + ComparisonFunc = D3D11_COMPARISON_NEVER; + BorderColor[ 0 ] = 1.0f; + BorderColor[ 1 ] = 1.0f; + BorderColor[ 2 ] = 1.0f; + BorderColor[ 3 ] = 1.0f; + MinLOD = -3.402823466e+38F; // -FLT_MAX + MaxLOD = 3.402823466e+38F; // FLT_MAX + } + explicit CD3D11_SAMPLER_DESC( + D3D11_FILTER filter, + D3D11_TEXTURE_ADDRESS_MODE addressU, + D3D11_TEXTURE_ADDRESS_MODE addressV, + D3D11_TEXTURE_ADDRESS_MODE addressW, + FLOAT mipLODBias, + UINT maxAnisotropy, + D3D11_COMPARISON_FUNC comparisonFunc, + __in_ecount_opt( 4 ) const FLOAT* borderColor, // RGBA + FLOAT minLOD, + FLOAT maxLOD ) + { + Filter = filter; + AddressU = addressU; + AddressV = addressV; + AddressW = addressW; + MipLODBias = mipLODBias; + MaxAnisotropy = maxAnisotropy; + ComparisonFunc = comparisonFunc; + const float defaultColor[ 4 ] = { 1.0f, 1.0f, 1.0f, 1.0f }; + if (!borderColor) borderColor = defaultColor; + BorderColor[ 0 ] = borderColor[ 0 ]; + BorderColor[ 1 ] = borderColor[ 1 ]; + BorderColor[ 2 ] = borderColor[ 2 ]; + BorderColor[ 3 ] = borderColor[ 3 ]; + MinLOD = minLOD; + MaxLOD = maxLOD; + } + ~CD3D11_SAMPLER_DESC() {} + operator const D3D11_SAMPLER_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0021_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0021_v0_0_s_ifspec; + +#ifndef __ID3D11SamplerState_INTERFACE_DEFINED__ +#define __ID3D11SamplerState_INTERFACE_DEFINED__ + +/* interface ID3D11SamplerState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11SamplerState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("da6fea51-564c-4487-9810-f0d0f9b4e3a5") + ID3D11SamplerState : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_SAMPLER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11SamplerStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11SamplerState * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11SamplerState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11SamplerState * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11SamplerState * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11SamplerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11SamplerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11SamplerState * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11SamplerState * This, + /* [annotation] */ + __out D3D11_SAMPLER_DESC *pDesc); + + END_INTERFACE + } ID3D11SamplerStateVtbl; + + interface ID3D11SamplerState + { + CONST_VTBL struct ID3D11SamplerStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11SamplerState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11SamplerState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11SamplerState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11SamplerState_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11SamplerState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11SamplerState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11SamplerState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11SamplerState_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11SamplerState_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0022 */ +/* [local] */ + +typedef +enum D3D11_FORMAT_SUPPORT + { D3D11_FORMAT_SUPPORT_BUFFER = 0x1, + D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER = 0x2, + D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER = 0x4, + D3D11_FORMAT_SUPPORT_SO_BUFFER = 0x8, + D3D11_FORMAT_SUPPORT_TEXTURE1D = 0x10, + D3D11_FORMAT_SUPPORT_TEXTURE2D = 0x20, + D3D11_FORMAT_SUPPORT_TEXTURE3D = 0x40, + D3D11_FORMAT_SUPPORT_TEXTURECUBE = 0x80, + D3D11_FORMAT_SUPPORT_SHADER_LOAD = 0x100, + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE = 0x200, + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON = 0x400, + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT = 0x800, + D3D11_FORMAT_SUPPORT_MIP = 0x1000, + D3D11_FORMAT_SUPPORT_MIP_AUTOGEN = 0x2000, + D3D11_FORMAT_SUPPORT_RENDER_TARGET = 0x4000, + D3D11_FORMAT_SUPPORT_BLENDABLE = 0x8000, + D3D11_FORMAT_SUPPORT_DEPTH_STENCIL = 0x10000, + D3D11_FORMAT_SUPPORT_CPU_LOCKABLE = 0x20000, + D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE = 0x40000, + D3D11_FORMAT_SUPPORT_DISPLAY = 0x80000, + D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT = 0x100000, + D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET = 0x200000, + D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD = 0x400000, + D3D11_FORMAT_SUPPORT_SHADER_GATHER = 0x800000, + D3D11_FORMAT_SUPPORT_BACK_BUFFER_CAST = 0x1000000, + D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW = 0x2000000, + D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON = 0x4000000 + } D3D11_FORMAT_SUPPORT; + +typedef +enum D3D11_FORMAT_SUPPORT2 + { D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD = 0x1, + D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS = 0x2, + D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 0x4, + D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE = 0x8, + D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX = 0x10, + D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 0x20, + D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x40, + D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x80 + } D3D11_FORMAT_SUPPORT2; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0022_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0022_v0_0_s_ifspec; + +#ifndef __ID3D11Asynchronous_INTERFACE_DEFINED__ +#define __ID3D11Asynchronous_INTERFACE_DEFINED__ + +/* interface ID3D11Asynchronous */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Asynchronous; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4b35d0cd-1e15-4258-9c98-1b1333f6dd3b") + ID3D11Asynchronous : public ID3D11DeviceChild + { + public: + virtual UINT STDMETHODCALLTYPE GetDataSize( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11AsynchronousVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Asynchronous * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Asynchronous * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Asynchronous * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Asynchronous * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Asynchronous * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Asynchronous * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Asynchronous * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D11Asynchronous * This); + + END_INTERFACE + } ID3D11AsynchronousVtbl; + + interface ID3D11Asynchronous + { + CONST_VTBL struct ID3D11AsynchronousVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Asynchronous_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Asynchronous_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Asynchronous_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Asynchronous_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Asynchronous_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Asynchronous_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Asynchronous_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Asynchronous_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Asynchronous_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0023 */ +/* [local] */ + +typedef +enum D3D11_ASYNC_GETDATA_FLAG + { D3D11_ASYNC_GETDATA_DONOTFLUSH = 0x1 + } D3D11_ASYNC_GETDATA_FLAG; + +typedef +enum D3D11_QUERY + { D3D11_QUERY_EVENT = 0, + D3D11_QUERY_OCCLUSION = ( D3D11_QUERY_EVENT + 1 ) , + D3D11_QUERY_TIMESTAMP = ( D3D11_QUERY_OCCLUSION + 1 ) , + D3D11_QUERY_TIMESTAMP_DISJOINT = ( D3D11_QUERY_TIMESTAMP + 1 ) , + D3D11_QUERY_PIPELINE_STATISTICS = ( D3D11_QUERY_TIMESTAMP_DISJOINT + 1 ) , + D3D11_QUERY_OCCLUSION_PREDICATE = ( D3D11_QUERY_PIPELINE_STATISTICS + 1 ) , + D3D11_QUERY_SO_STATISTICS = ( D3D11_QUERY_OCCLUSION_PREDICATE + 1 ) , + D3D11_QUERY_SO_OVERFLOW_PREDICATE = ( D3D11_QUERY_SO_STATISTICS + 1 ) , + D3D11_QUERY_SO_STATISTICS_STREAM0 = ( D3D11_QUERY_SO_OVERFLOW_PREDICATE + 1 ) , + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0 = ( D3D11_QUERY_SO_STATISTICS_STREAM0 + 1 ) , + D3D11_QUERY_SO_STATISTICS_STREAM1 = ( D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0 + 1 ) , + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1 = ( D3D11_QUERY_SO_STATISTICS_STREAM1 + 1 ) , + D3D11_QUERY_SO_STATISTICS_STREAM2 = ( D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1 + 1 ) , + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2 = ( D3D11_QUERY_SO_STATISTICS_STREAM2 + 1 ) , + D3D11_QUERY_SO_STATISTICS_STREAM3 = ( D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2 + 1 ) , + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3 = ( D3D11_QUERY_SO_STATISTICS_STREAM3 + 1 ) + } D3D11_QUERY; + +typedef +enum D3D11_QUERY_MISC_FLAG + { D3D11_QUERY_MISC_PREDICATEHINT = 0x1 + } D3D11_QUERY_MISC_FLAG; + +typedef struct D3D11_QUERY_DESC + { + D3D11_QUERY Query; + UINT MiscFlags; + } D3D11_QUERY_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_QUERY_DESC : public D3D11_QUERY_DESC +{ + CD3D11_QUERY_DESC() + {} + explicit CD3D11_QUERY_DESC( const D3D11_QUERY_DESC& o ) : + D3D11_QUERY_DESC( o ) + {} + explicit CD3D11_QUERY_DESC( + D3D11_QUERY query, + UINT miscFlags = 0 ) + { + Query = query; + MiscFlags = miscFlags; + } + ~CD3D11_QUERY_DESC() {} + operator const D3D11_QUERY_DESC&() const { return *this; } +}; +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0023_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0023_v0_0_s_ifspec; + +#ifndef __ID3D11Query_INTERFACE_DEFINED__ +#define __ID3D11Query_INTERFACE_DEFINED__ + +/* interface ID3D11Query */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Query; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("d6c00747-87b7-425e-b84d-44d108560afd") + ID3D11Query : public ID3D11Asynchronous + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_QUERY_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11QueryVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Query * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Query * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Query * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Query * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Query * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Query * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Query * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D11Query * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11Query * This, + /* [annotation] */ + __out D3D11_QUERY_DESC *pDesc); + + END_INTERFACE + } ID3D11QueryVtbl; + + interface ID3D11Query + { + CONST_VTBL struct ID3D11QueryVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Query_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Query_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Query_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Query_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Query_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Query_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Query_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Query_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + + +#define ID3D11Query_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Query_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11Predicate_INTERFACE_DEFINED__ +#define __ID3D11Predicate_INTERFACE_DEFINED__ + +/* interface ID3D11Predicate */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Predicate; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9eb576dd-9f77-4d86-81aa-8bab5fe490e2") + ID3D11Predicate : public ID3D11Query + { + public: + }; + +#else /* C style interface */ + + typedef struct ID3D11PredicateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Predicate * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Predicate * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Predicate * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Predicate * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Predicate * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Predicate * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Predicate * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D11Predicate * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11Predicate * This, + /* [annotation] */ + __out D3D11_QUERY_DESC *pDesc); + + END_INTERFACE + } ID3D11PredicateVtbl; + + interface ID3D11Predicate + { + CONST_VTBL struct ID3D11PredicateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Predicate_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Predicate_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Predicate_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Predicate_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Predicate_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Predicate_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Predicate_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Predicate_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + + +#define ID3D11Predicate_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Predicate_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0025 */ +/* [local] */ + +typedef struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT + { + UINT64 Frequency; + BOOL Disjoint; + } D3D11_QUERY_DATA_TIMESTAMP_DISJOINT; + +typedef struct D3D11_QUERY_DATA_PIPELINE_STATISTICS + { + UINT64 IAVertices; + UINT64 IAPrimitives; + UINT64 VSInvocations; + UINT64 GSInvocations; + UINT64 GSPrimitives; + UINT64 CInvocations; + UINT64 CPrimitives; + UINT64 PSInvocations; + UINT64 HSInvocations; + UINT64 DSInvocations; + UINT64 CSInvocations; + } D3D11_QUERY_DATA_PIPELINE_STATISTICS; + +typedef struct D3D11_QUERY_DATA_SO_STATISTICS + { + UINT64 NumPrimitivesWritten; + UINT64 PrimitivesStorageNeeded; + } D3D11_QUERY_DATA_SO_STATISTICS; + +typedef +enum D3D11_COUNTER + { D3D11_COUNTER_DEVICE_DEPENDENT_0 = 0x40000000 + } D3D11_COUNTER; + +typedef +enum D3D11_COUNTER_TYPE + { D3D11_COUNTER_TYPE_FLOAT32 = 0, + D3D11_COUNTER_TYPE_UINT16 = ( D3D11_COUNTER_TYPE_FLOAT32 + 1 ) , + D3D11_COUNTER_TYPE_UINT32 = ( D3D11_COUNTER_TYPE_UINT16 + 1 ) , + D3D11_COUNTER_TYPE_UINT64 = ( D3D11_COUNTER_TYPE_UINT32 + 1 ) + } D3D11_COUNTER_TYPE; + +typedef struct D3D11_COUNTER_DESC + { + D3D11_COUNTER Counter; + UINT MiscFlags; + } D3D11_COUNTER_DESC; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +struct CD3D11_COUNTER_DESC : public D3D11_COUNTER_DESC +{ + CD3D11_COUNTER_DESC() + {} + explicit CD3D11_COUNTER_DESC( const D3D11_COUNTER_DESC& o ) : + D3D11_COUNTER_DESC( o ) + {} + explicit CD3D11_COUNTER_DESC( + D3D11_COUNTER counter, + UINT miscFlags = 0 ) + { + Counter = counter; + MiscFlags = miscFlags; + } + ~CD3D11_COUNTER_DESC() {} + operator const D3D11_COUNTER_DESC&() const { return *this; } +}; +extern "C"{ +#endif +typedef struct D3D11_COUNTER_INFO + { + D3D11_COUNTER LastDeviceDependentCounter; + UINT NumSimultaneousCounters; + UINT8 NumDetectableParallelUnits; + } D3D11_COUNTER_INFO; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0025_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0025_v0_0_s_ifspec; + +#ifndef __ID3D11Counter_INTERFACE_DEFINED__ +#define __ID3D11Counter_INTERFACE_DEFINED__ + +/* interface ID3D11Counter */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Counter; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6e8c49fb-a371-4770-b440-29086022b741") + ID3D11Counter : public ID3D11Asynchronous + { + public: + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_COUNTER_DESC *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11CounterVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Counter * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Counter * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Counter * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11Counter * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Counter * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Counter * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Counter * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + UINT ( STDMETHODCALLTYPE *GetDataSize )( + ID3D11Counter * This); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11Counter * This, + /* [annotation] */ + __out D3D11_COUNTER_DESC *pDesc); + + END_INTERFACE + } ID3D11CounterVtbl; + + interface ID3D11Counter + { + CONST_VTBL struct ID3D11CounterVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Counter_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Counter_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Counter_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Counter_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11Counter_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Counter_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Counter_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11Counter_GetDataSize(This) \ + ( (This)->lpVtbl -> GetDataSize(This) ) + + +#define ID3D11Counter_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Counter_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0026 */ +/* [local] */ + +typedef +enum D3D11_STANDARD_MULTISAMPLE_QUALITY_LEVELS + { D3D11_STANDARD_MULTISAMPLE_PATTERN = 0xffffffff, + D3D11_CENTER_MULTISAMPLE_PATTERN = 0xfffffffe + } D3D11_STANDARD_MULTISAMPLE_QUALITY_LEVELS; + +typedef +enum D3D11_DEVICE_CONTEXT_TYPE + { D3D11_DEVICE_CONTEXT_IMMEDIATE = 0, + D3D11_DEVICE_CONTEXT_DEFERRED = ( D3D11_DEVICE_CONTEXT_IMMEDIATE + 1 ) + } D3D11_DEVICE_CONTEXT_TYPE; + +typedef struct D3D11_CLASS_INSTANCE_DESC + { + UINT InstanceId; + UINT InstanceIndex; + UINT TypeId; + UINT ConstantBuffer; + UINT BaseConstantBufferOffset; + UINT BaseTexture; + UINT BaseSampler; + BOOL Created; + } D3D11_CLASS_INSTANCE_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0026_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0026_v0_0_s_ifspec; + +#ifndef __ID3D11ClassInstance_INTERFACE_DEFINED__ +#define __ID3D11ClassInstance_INTERFACE_DEFINED__ + +/* interface ID3D11ClassInstance */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11ClassInstance; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a6cd7faa-b0b7-4a2f-9436-8662a65797cb") + ID3D11ClassInstance : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE GetClassLinkage( + /* [annotation] */ + __out ID3D11ClassLinkage **ppLinkage) = 0; + + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_CLASS_INSTANCE_DESC *pDesc) = 0; + + virtual void STDMETHODCALLTYPE GetInstanceName( + /* [annotation] */ + __out_ecount_opt(*pBufferLength) LPSTR pInstanceName, + /* [annotation] */ + __inout SIZE_T *pBufferLength) = 0; + + virtual void STDMETHODCALLTYPE GetTypeName( + /* [annotation] */ + __out_ecount_opt(*pBufferLength) LPSTR pTypeName, + /* [annotation] */ + __inout SIZE_T *pBufferLength) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11ClassInstanceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11ClassInstance * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11ClassInstance * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11ClassInstance * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11ClassInstance * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11ClassInstance * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11ClassInstance * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11ClassInstance * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *GetClassLinkage )( + ID3D11ClassInstance * This, + /* [annotation] */ + __out ID3D11ClassLinkage **ppLinkage); + + void ( STDMETHODCALLTYPE *GetDesc )( + ID3D11ClassInstance * This, + /* [annotation] */ + __out D3D11_CLASS_INSTANCE_DESC *pDesc); + + void ( STDMETHODCALLTYPE *GetInstanceName )( + ID3D11ClassInstance * This, + /* [annotation] */ + __out_ecount_opt(*pBufferLength) LPSTR pInstanceName, + /* [annotation] */ + __inout SIZE_T *pBufferLength); + + void ( STDMETHODCALLTYPE *GetTypeName )( + ID3D11ClassInstance * This, + /* [annotation] */ + __out_ecount_opt(*pBufferLength) LPSTR pTypeName, + /* [annotation] */ + __inout SIZE_T *pBufferLength); + + END_INTERFACE + } ID3D11ClassInstanceVtbl; + + interface ID3D11ClassInstance + { + CONST_VTBL struct ID3D11ClassInstanceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11ClassInstance_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11ClassInstance_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11ClassInstance_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11ClassInstance_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11ClassInstance_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11ClassInstance_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11ClassInstance_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11ClassInstance_GetClassLinkage(This,ppLinkage) \ + ( (This)->lpVtbl -> GetClassLinkage(This,ppLinkage) ) + +#define ID3D11ClassInstance_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#define ID3D11ClassInstance_GetInstanceName(This,pInstanceName,pBufferLength) \ + ( (This)->lpVtbl -> GetInstanceName(This,pInstanceName,pBufferLength) ) + +#define ID3D11ClassInstance_GetTypeName(This,pTypeName,pBufferLength) \ + ( (This)->lpVtbl -> GetTypeName(This,pTypeName,pBufferLength) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11ClassInstance_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11ClassLinkage_INTERFACE_DEFINED__ +#define __ID3D11ClassLinkage_INTERFACE_DEFINED__ + +/* interface ID3D11ClassLinkage */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11ClassLinkage; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ddf57cba-9543-46e4-a12b-f207a0fe7fed") + ID3D11ClassLinkage : public ID3D11DeviceChild + { + public: + virtual HRESULT STDMETHODCALLTYPE GetClassInstance( + /* [annotation] */ + __in LPCSTR pClassInstanceName, + /* [annotation] */ + __in UINT InstanceIndex, + /* [annotation] */ + __out ID3D11ClassInstance **ppInstance) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateClassInstance( + /* [annotation] */ + __in LPCSTR pClassTypeName, + /* [annotation] */ + __in UINT ConstantBufferOffset, + /* [annotation] */ + __in UINT ConstantVectorOffset, + /* [annotation] */ + __in UINT TextureOffset, + /* [annotation] */ + __in UINT SamplerOffset, + /* [annotation] */ + __out ID3D11ClassInstance **ppInstance) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11ClassLinkageVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11ClassLinkage * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11ClassLinkage * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11ClassLinkage * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11ClassLinkage * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11ClassLinkage * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11ClassLinkage * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11ClassLinkage * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *GetClassInstance )( + ID3D11ClassLinkage * This, + /* [annotation] */ + __in LPCSTR pClassInstanceName, + /* [annotation] */ + __in UINT InstanceIndex, + /* [annotation] */ + __out ID3D11ClassInstance **ppInstance); + + HRESULT ( STDMETHODCALLTYPE *CreateClassInstance )( + ID3D11ClassLinkage * This, + /* [annotation] */ + __in LPCSTR pClassTypeName, + /* [annotation] */ + __in UINT ConstantBufferOffset, + /* [annotation] */ + __in UINT ConstantVectorOffset, + /* [annotation] */ + __in UINT TextureOffset, + /* [annotation] */ + __in UINT SamplerOffset, + /* [annotation] */ + __out ID3D11ClassInstance **ppInstance); + + END_INTERFACE + } ID3D11ClassLinkageVtbl; + + interface ID3D11ClassLinkage + { + CONST_VTBL struct ID3D11ClassLinkageVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11ClassLinkage_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11ClassLinkage_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11ClassLinkage_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11ClassLinkage_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11ClassLinkage_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11ClassLinkage_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11ClassLinkage_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11ClassLinkage_GetClassInstance(This,pClassInstanceName,InstanceIndex,ppInstance) \ + ( (This)->lpVtbl -> GetClassInstance(This,pClassInstanceName,InstanceIndex,ppInstance) ) + +#define ID3D11ClassLinkage_CreateClassInstance(This,pClassTypeName,ConstantBufferOffset,ConstantVectorOffset,TextureOffset,SamplerOffset,ppInstance) \ + ( (This)->lpVtbl -> CreateClassInstance(This,pClassTypeName,ConstantBufferOffset,ConstantVectorOffset,TextureOffset,SamplerOffset,ppInstance) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11ClassLinkage_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11CommandList_INTERFACE_DEFINED__ +#define __ID3D11CommandList_INTERFACE_DEFINED__ + +/* interface ID3D11CommandList */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11CommandList; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a24bc4d1-769e-43f7-8013-98ff566c18e2") + ID3D11CommandList : public ID3D11DeviceChild + { + public: + virtual UINT STDMETHODCALLTYPE GetContextFlags( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11CommandListVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11CommandList * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11CommandList * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11CommandList * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11CommandList * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11CommandList * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11CommandList * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11CommandList * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + UINT ( STDMETHODCALLTYPE *GetContextFlags )( + ID3D11CommandList * This); + + END_INTERFACE + } ID3D11CommandListVtbl; + + interface ID3D11CommandList + { + CONST_VTBL struct ID3D11CommandListVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11CommandList_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11CommandList_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11CommandList_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11CommandList_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11CommandList_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11CommandList_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11CommandList_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11CommandList_GetContextFlags(This) \ + ( (This)->lpVtbl -> GetContextFlags(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11CommandList_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0029 */ +/* [local] */ + +typedef +enum D3D11_FEATURE + { D3D11_FEATURE_THREADING = 0, + D3D11_FEATURE_DOUBLES = ( D3D11_FEATURE_THREADING + 1 ) , + D3D11_FEATURE_FORMAT_SUPPORT = ( D3D11_FEATURE_DOUBLES + 1 ) , + D3D11_FEATURE_FORMAT_SUPPORT2 = ( D3D11_FEATURE_FORMAT_SUPPORT + 1 ) , + D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS = ( D3D11_FEATURE_FORMAT_SUPPORT2 + 1 ) + } D3D11_FEATURE; + +typedef struct D3D11_FEATURE_DATA_THREADING + { + BOOL DriverConcurrentCreates; + BOOL DriverCommandLists; + } D3D11_FEATURE_DATA_THREADING; + +typedef struct D3D11_FEATURE_DATA_DOUBLES + { + BOOL DoublePrecisionFloatShaderOps; + } D3D11_FEATURE_DATA_DOUBLES; + +typedef struct D3D11_FEATURE_DATA_FORMAT_SUPPORT + { + DXGI_FORMAT InFormat; + UINT OutFormatSupport; + } D3D11_FEATURE_DATA_FORMAT_SUPPORT; + +typedef struct D3D11_FEATURE_DATA_FORMAT_SUPPORT2 + { + DXGI_FORMAT InFormat; + UINT OutFormatSupport2; + } D3D11_FEATURE_DATA_FORMAT_SUPPORT2; + +typedef struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS + { + BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; + } D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0029_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0029_v0_0_s_ifspec; + +#ifndef __ID3D11DeviceContext_INTERFACE_DEFINED__ +#define __ID3D11DeviceContext_INTERFACE_DEFINED__ + +/* interface ID3D11DeviceContext */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11DeviceContext; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c0bfa96c-e089-44fb-8eaf-26f8796190da") + ID3D11DeviceContext : public ID3D11DeviceChild + { + public: + virtual void STDMETHODCALLTYPE VSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE PSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE PSSetShader( + /* [annotation] */ + __in_opt ID3D11PixelShader *pPixelShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE PSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE VSSetShader( + /* [annotation] */ + __in_opt ID3D11VertexShader *pVertexShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE DrawIndexed( + /* [annotation] */ + __in UINT IndexCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation) = 0; + + virtual void STDMETHODCALLTYPE Draw( + /* [annotation] */ + __in UINT VertexCount, + /* [annotation] */ + __in UINT StartVertexLocation) = 0; + + virtual HRESULT STDMETHODCALLTYPE Map( + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D11_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out D3D11_MAPPED_SUBRESOURCE *pMappedResource) = 0; + + virtual void STDMETHODCALLTYPE Unmap( + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in UINT Subresource) = 0; + + virtual void STDMETHODCALLTYPE PSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE IASetInputLayout( + /* [annotation] */ + __in_opt ID3D11InputLayout *pInputLayout) = 0; + + virtual void STDMETHODCALLTYPE IASetVertexBuffers( + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppVertexBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pStrides, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pOffsets) = 0; + + virtual void STDMETHODCALLTYPE IASetIndexBuffer( + /* [annotation] */ + __in_opt ID3D11Buffer *pIndexBuffer, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT Offset) = 0; + + virtual void STDMETHODCALLTYPE DrawIndexedInstanced( + /* [annotation] */ + __in UINT IndexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation) = 0; + + virtual void STDMETHODCALLTYPE DrawInstanced( + /* [annotation] */ + __in UINT VertexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation) = 0; + + virtual void STDMETHODCALLTYPE GSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE GSSetShader( + /* [annotation] */ + __in_opt ID3D11GeometryShader *pShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE IASetPrimitiveTopology( + /* [annotation] */ + __in D3D11_PRIMITIVE_TOPOLOGY Topology) = 0; + + virtual void STDMETHODCALLTYPE VSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE VSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE Begin( + /* [annotation] */ + __in ID3D11Asynchronous *pAsync) = 0; + + virtual void STDMETHODCALLTYPE End( + /* [annotation] */ + __in ID3D11Asynchronous *pAsync) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetData( + /* [annotation] */ + __in ID3D11Asynchronous *pAsync, + /* [annotation] */ + __out_bcount_opt( DataSize ) void *pData, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in UINT GetDataFlags) = 0; + + virtual void STDMETHODCALLTYPE SetPredication( + /* [annotation] */ + __in_opt ID3D11Predicate *pPredicate, + /* [annotation] */ + __in BOOL PredicateValue) = 0; + + virtual void STDMETHODCALLTYPE GSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE GSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE OMSetRenderTargets( + /* [annotation] */ + __in_range( 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __in_ecount_opt(NumViews) ID3D11RenderTargetView *const *ppRenderTargetViews, + /* [annotation] */ + __in_opt ID3D11DepthStencilView *pDepthStencilView) = 0; + + virtual void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( + /* [annotation] */ + __in UINT NumRTVs, + /* [annotation] */ + __in_ecount_opt(NumRTVs) ID3D11RenderTargetView *const *ppRenderTargetViews, + /* [annotation] */ + __in_opt ID3D11DepthStencilView *pDepthStencilView, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT UAVStartSlot, + /* [annotation] */ + __in UINT NumUAVs, + /* [annotation] */ + __in_ecount_opt(NumUAVs) ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + /* [annotation] */ + __in_ecount_opt(NumUAVs) const UINT *pUAVInitialCounts) = 0; + + virtual void STDMETHODCALLTYPE OMSetBlendState( + /* [annotation] */ + __in_opt ID3D11BlendState *pBlendState, + /* [annotation] */ + __in_opt const FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __in UINT SampleMask) = 0; + + virtual void STDMETHODCALLTYPE OMSetDepthStencilState( + /* [annotation] */ + __in_opt ID3D11DepthStencilState *pDepthStencilState, + /* [annotation] */ + __in UINT StencilRef) = 0; + + virtual void STDMETHODCALLTYPE SOSetTargets( + /* [annotation] */ + __in_range( 0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, + /* [annotation] */ + __in_ecount_opt(NumBuffers) ID3D11Buffer *const *ppSOTargets, + /* [annotation] */ + __in_ecount_opt(NumBuffers) const UINT *pOffsets) = 0; + + virtual void STDMETHODCALLTYPE DrawAuto( void) = 0; + + virtual void STDMETHODCALLTYPE DrawIndexedInstancedIndirect( + /* [annotation] */ + __in ID3D11Buffer *pBufferForArgs, + /* [annotation] */ + __in UINT AlignedByteOffsetForArgs) = 0; + + virtual void STDMETHODCALLTYPE DrawInstancedIndirect( + /* [annotation] */ + __in ID3D11Buffer *pBufferForArgs, + /* [annotation] */ + __in UINT AlignedByteOffsetForArgs) = 0; + + virtual void STDMETHODCALLTYPE Dispatch( + /* [annotation] */ + __in UINT ThreadGroupCountX, + /* [annotation] */ + __in UINT ThreadGroupCountY, + /* [annotation] */ + __in UINT ThreadGroupCountZ) = 0; + + virtual void STDMETHODCALLTYPE DispatchIndirect( + /* [annotation] */ + __in ID3D11Buffer *pBufferForArgs, + /* [annotation] */ + __in UINT AlignedByteOffsetForArgs) = 0; + + virtual void STDMETHODCALLTYPE RSSetState( + /* [annotation] */ + __in_opt ID3D11RasterizerState *pRasterizerState) = 0; + + virtual void STDMETHODCALLTYPE RSSetViewports( + /* [annotation] */ + __in_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + /* [annotation] */ + __in_ecount_opt(NumViewports) const D3D11_VIEWPORT *pViewports) = 0; + + virtual void STDMETHODCALLTYPE RSSetScissorRects( + /* [annotation] */ + __in_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + /* [annotation] */ + __in_ecount_opt(NumRects) const D3D11_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE CopySubresourceRegion( + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in UINT DstX, + /* [annotation] */ + __in UINT DstY, + /* [annotation] */ + __in UINT DstZ, + /* [annotation] */ + __in ID3D11Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in_opt const D3D11_BOX *pSrcBox) = 0; + + virtual void STDMETHODCALLTYPE CopyResource( + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in ID3D11Resource *pSrcResource) = 0; + + virtual void STDMETHODCALLTYPE UpdateSubresource( + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in_opt const D3D11_BOX *pDstBox, + /* [annotation] */ + __in const void *pSrcData, + /* [annotation] */ + __in UINT SrcRowPitch, + /* [annotation] */ + __in UINT SrcDepthPitch) = 0; + + virtual void STDMETHODCALLTYPE CopyStructureCount( + /* [annotation] */ + __in ID3D11Buffer *pDstBuffer, + /* [annotation] */ + __in UINT DstAlignedByteOffset, + /* [annotation] */ + __in ID3D11UnorderedAccessView *pSrcView) = 0; + + virtual void STDMETHODCALLTYPE ClearRenderTargetView( + /* [annotation] */ + __in ID3D11RenderTargetView *pRenderTargetView, + /* [annotation] */ + __in const FLOAT ColorRGBA[ 4 ]) = 0; + + virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewUint( + /* [annotation] */ + __in ID3D11UnorderedAccessView *pUnorderedAccessView, + /* [annotation] */ + __in const UINT Values[ 4 ]) = 0; + + virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewFloat( + /* [annotation] */ + __in ID3D11UnorderedAccessView *pUnorderedAccessView, + /* [annotation] */ + __in const FLOAT Values[ 4 ]) = 0; + + virtual void STDMETHODCALLTYPE ClearDepthStencilView( + /* [annotation] */ + __in ID3D11DepthStencilView *pDepthStencilView, + /* [annotation] */ + __in UINT ClearFlags, + /* [annotation] */ + __in FLOAT Depth, + /* [annotation] */ + __in UINT8 Stencil) = 0; + + virtual void STDMETHODCALLTYPE GenerateMips( + /* [annotation] */ + __in ID3D11ShaderResourceView *pShaderResourceView) = 0; + + virtual void STDMETHODCALLTYPE SetResourceMinLOD( + /* [annotation] */ + __in ID3D11Resource *pResource, + FLOAT MinLOD) = 0; + + virtual FLOAT STDMETHODCALLTYPE GetResourceMinLOD( + /* [annotation] */ + __in ID3D11Resource *pResource) = 0; + + virtual void STDMETHODCALLTYPE ResolveSubresource( + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in ID3D11Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in DXGI_FORMAT Format) = 0; + + virtual void STDMETHODCALLTYPE ExecuteCommandList( + /* [annotation] */ + __in ID3D11CommandList *pCommandList, + BOOL RestoreContextState) = 0; + + virtual void STDMETHODCALLTYPE HSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE HSSetShader( + /* [annotation] */ + __in_opt ID3D11HullShader *pHullShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE HSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE HSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE DSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE DSSetShader( + /* [annotation] */ + __in_opt ID3D11DomainShader *pDomainShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE DSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE DSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE CSSetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE CSSetUnorderedAccessViews( + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - StartSlot ) UINT NumUAVs, + /* [annotation] */ + __in_ecount(NumUAVs) ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + /* [annotation] */ + __in_ecount(NumUAVs) const UINT *pUAVInitialCounts) = 0; + + virtual void STDMETHODCALLTYPE CSSetShader( + /* [annotation] */ + __in_opt ID3D11ComputeShader *pComputeShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE CSSetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE CSSetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE VSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE PSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE PSGetShader( + /* [annotation] */ + __out ID3D11PixelShader **ppPixelShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE PSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE VSGetShader( + /* [annotation] */ + __out ID3D11VertexShader **ppVertexShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE PSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE IAGetInputLayout( + /* [annotation] */ + __out ID3D11InputLayout **ppInputLayout) = 0; + + virtual void STDMETHODCALLTYPE IAGetVertexBuffers( + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D11Buffer **ppVertexBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pStrides, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets) = 0; + + virtual void STDMETHODCALLTYPE IAGetIndexBuffer( + /* [annotation] */ + __out_opt ID3D11Buffer **pIndexBuffer, + /* [annotation] */ + __out_opt DXGI_FORMAT *Format, + /* [annotation] */ + __out_opt UINT *Offset) = 0; + + virtual void STDMETHODCALLTYPE GSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE GSGetShader( + /* [annotation] */ + __out ID3D11GeometryShader **ppGeometryShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE IAGetPrimitiveTopology( + /* [annotation] */ + __out D3D11_PRIMITIVE_TOPOLOGY *pTopology) = 0; + + virtual void STDMETHODCALLTYPE VSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE VSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE GetPredication( + /* [annotation] */ + __out_opt ID3D11Predicate **ppPredicate, + /* [annotation] */ + __out_opt BOOL *pPredicateValue) = 0; + + virtual void STDMETHODCALLTYPE GSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE GSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE OMGetRenderTargets( + /* [annotation] */ + __in_range( 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __out_ecount_opt(NumViews) ID3D11RenderTargetView **ppRenderTargetViews, + /* [annotation] */ + __out_opt ID3D11DepthStencilView **ppDepthStencilView) = 0; + + virtual void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews( + /* [annotation] */ + __in_range( 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumRTVs, + /* [annotation] */ + __out_ecount_opt(NumRTVs) ID3D11RenderTargetView **ppRenderTargetViews, + /* [annotation] */ + __out_opt ID3D11DepthStencilView **ppDepthStencilView, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT UAVStartSlot, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - UAVStartSlot ) UINT NumUAVs, + /* [annotation] */ + __out_ecount_opt(NumUAVs) ID3D11UnorderedAccessView **ppUnorderedAccessViews) = 0; + + virtual void STDMETHODCALLTYPE OMGetBlendState( + /* [annotation] */ + __out_opt ID3D11BlendState **ppBlendState, + /* [annotation] */ + __out_opt FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __out_opt UINT *pSampleMask) = 0; + + virtual void STDMETHODCALLTYPE OMGetDepthStencilState( + /* [annotation] */ + __out_opt ID3D11DepthStencilState **ppDepthStencilState, + /* [annotation] */ + __out_opt UINT *pStencilRef) = 0; + + virtual void STDMETHODCALLTYPE SOGetTargets( + /* [annotation] */ + __in_range( 0, D3D11_SO_BUFFER_SLOT_COUNT ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppSOTargets) = 0; + + virtual void STDMETHODCALLTYPE RSGetState( + /* [annotation] */ + __out ID3D11RasterizerState **ppRasterizerState) = 0; + + virtual void STDMETHODCALLTYPE RSGetViewports( + /* [annotation] */ + __inout /*_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *pNumViewports, + /* [annotation] */ + __out_ecount_opt(*pNumViewports) D3D11_VIEWPORT *pViewports) = 0; + + virtual void STDMETHODCALLTYPE RSGetScissorRects( + /* [annotation] */ + __inout /*_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *pNumRects, + /* [annotation] */ + __out_ecount_opt(*pNumRects) D3D11_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE HSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE HSGetShader( + /* [annotation] */ + __out ID3D11HullShader **ppHullShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE HSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE HSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE DSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE DSGetShader( + /* [annotation] */ + __out ID3D11DomainShader **ppDomainShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE DSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE DSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE CSGetShaderResources( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews) = 0; + + virtual void STDMETHODCALLTYPE CSGetUnorderedAccessViews( + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - StartSlot ) UINT NumUAVs, + /* [annotation] */ + __out_ecount(NumUAVs) ID3D11UnorderedAccessView **ppUnorderedAccessViews) = 0; + + virtual void STDMETHODCALLTYPE CSGetShader( + /* [annotation] */ + __out ID3D11ComputeShader **ppComputeShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances) = 0; + + virtual void STDMETHODCALLTYPE CSGetSamplers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers) = 0; + + virtual void STDMETHODCALLTYPE CSGetConstantBuffers( + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers) = 0; + + virtual void STDMETHODCALLTYPE ClearState( void) = 0; + + virtual void STDMETHODCALLTYPE Flush( void) = 0; + + virtual D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetContextFlags( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE FinishCommandList( + BOOL RestoreDeferredContextState, + /* [annotation] */ + __out_opt ID3D11CommandList **ppCommandList) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11DeviceContextVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11DeviceContext * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11DeviceContext * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11DeviceContext * This); + + void ( STDMETHODCALLTYPE *GetDevice )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11Device **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + void ( STDMETHODCALLTYPE *VSSetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *PSSetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *PSSetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11PixelShader *pPixelShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + + void ( STDMETHODCALLTYPE *PSSetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *VSSetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11VertexShader *pVertexShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + + void ( STDMETHODCALLTYPE *DrawIndexed )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in UINT IndexCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation); + + void ( STDMETHODCALLTYPE *Draw )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in UINT VertexCount, + /* [annotation] */ + __in UINT StartVertexLocation); + + HRESULT ( STDMETHODCALLTYPE *Map )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in UINT Subresource, + /* [annotation] */ + __in D3D11_MAP MapType, + /* [annotation] */ + __in UINT MapFlags, + /* [annotation] */ + __out D3D11_MAPPED_SUBRESOURCE *pMappedResource); + + void ( STDMETHODCALLTYPE *Unmap )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in UINT Subresource); + + void ( STDMETHODCALLTYPE *PSSetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *IASetInputLayout )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11InputLayout *pInputLayout); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppVertexBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pStrides, + /* [annotation] */ + __in_ecount(NumBuffers) const UINT *pOffsets); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11Buffer *pIndexBuffer, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT Offset); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in UINT IndexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartIndexLocation, + /* [annotation] */ + __in INT BaseVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in UINT VertexCountPerInstance, + /* [annotation] */ + __in UINT InstanceCount, + /* [annotation] */ + __in UINT StartVertexLocation, + /* [annotation] */ + __in UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *GSSetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *GSSetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11GeometryShader *pShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in D3D11_PRIMITIVE_TOPOLOGY Topology); + + void ( STDMETHODCALLTYPE *VSSetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *VSSetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *Begin )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Asynchronous *pAsync); + + void ( STDMETHODCALLTYPE *End )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Asynchronous *pAsync); + + HRESULT ( STDMETHODCALLTYPE *GetData )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Asynchronous *pAsync, + /* [annotation] */ + __out_bcount_opt( DataSize ) void *pData, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in UINT GetDataFlags); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11Predicate *pPredicate, + /* [annotation] */ + __in BOOL PredicateValue); + + void ( STDMETHODCALLTYPE *GSSetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *GSSetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __in_ecount_opt(NumViews) ID3D11RenderTargetView *const *ppRenderTargetViews, + /* [annotation] */ + __in_opt ID3D11DepthStencilView *pDepthStencilView); + + void ( STDMETHODCALLTYPE *OMSetRenderTargetsAndUnorderedAccessViews )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in UINT NumRTVs, + /* [annotation] */ + __in_ecount_opt(NumRTVs) ID3D11RenderTargetView *const *ppRenderTargetViews, + /* [annotation] */ + __in_opt ID3D11DepthStencilView *pDepthStencilView, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT UAVStartSlot, + /* [annotation] */ + __in UINT NumUAVs, + /* [annotation] */ + __in_ecount_opt(NumUAVs) ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + /* [annotation] */ + __in_ecount_opt(NumUAVs) const UINT *pUAVInitialCounts); + + void ( STDMETHODCALLTYPE *OMSetBlendState )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11BlendState *pBlendState, + /* [annotation] */ + __in_opt const FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __in UINT SampleMask); + + void ( STDMETHODCALLTYPE *OMSetDepthStencilState )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11DepthStencilState *pDepthStencilState, + /* [annotation] */ + __in UINT StencilRef); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, + /* [annotation] */ + __in_ecount_opt(NumBuffers) ID3D11Buffer *const *ppSOTargets, + /* [annotation] */ + __in_ecount_opt(NumBuffers) const UINT *pOffsets); + + void ( STDMETHODCALLTYPE *DrawAuto )( + ID3D11DeviceContext * This); + + void ( STDMETHODCALLTYPE *DrawIndexedInstancedIndirect )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Buffer *pBufferForArgs, + /* [annotation] */ + __in UINT AlignedByteOffsetForArgs); + + void ( STDMETHODCALLTYPE *DrawInstancedIndirect )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Buffer *pBufferForArgs, + /* [annotation] */ + __in UINT AlignedByteOffsetForArgs); + + void ( STDMETHODCALLTYPE *Dispatch )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in UINT ThreadGroupCountX, + /* [annotation] */ + __in UINT ThreadGroupCountY, + /* [annotation] */ + __in UINT ThreadGroupCountZ); + + void ( STDMETHODCALLTYPE *DispatchIndirect )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Buffer *pBufferForArgs, + /* [annotation] */ + __in UINT AlignedByteOffsetForArgs); + + void ( STDMETHODCALLTYPE *RSSetState )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11RasterizerState *pRasterizerState); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + /* [annotation] */ + __in_ecount_opt(NumViewports) const D3D11_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + /* [annotation] */ + __in_ecount_opt(NumRects) const D3D11_RECT *pRects); + + void ( STDMETHODCALLTYPE *CopySubresourceRegion )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in UINT DstX, + /* [annotation] */ + __in UINT DstY, + /* [annotation] */ + __in UINT DstZ, + /* [annotation] */ + __in ID3D11Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in_opt const D3D11_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in ID3D11Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *UpdateSubresource )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in_opt const D3D11_BOX *pDstBox, + /* [annotation] */ + __in const void *pSrcData, + /* [annotation] */ + __in UINT SrcRowPitch, + /* [annotation] */ + __in UINT SrcDepthPitch); + + void ( STDMETHODCALLTYPE *CopyStructureCount )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Buffer *pDstBuffer, + /* [annotation] */ + __in UINT DstAlignedByteOffset, + /* [annotation] */ + __in ID3D11UnorderedAccessView *pSrcView); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11RenderTargetView *pRenderTargetView, + /* [annotation] */ + __in const FLOAT ColorRGBA[ 4 ]); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewUint )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11UnorderedAccessView *pUnorderedAccessView, + /* [annotation] */ + __in const UINT Values[ 4 ]); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewFloat )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11UnorderedAccessView *pUnorderedAccessView, + /* [annotation] */ + __in const FLOAT Values[ 4 ]); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11DepthStencilView *pDepthStencilView, + /* [annotation] */ + __in UINT ClearFlags, + /* [annotation] */ + __in FLOAT Depth, + /* [annotation] */ + __in UINT8 Stencil); + + void ( STDMETHODCALLTYPE *GenerateMips )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11ShaderResourceView *pShaderResourceView); + + void ( STDMETHODCALLTYPE *SetResourceMinLOD )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pResource, + FLOAT MinLOD); + + FLOAT ( STDMETHODCALLTYPE *GetResourceMinLOD )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pResource); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11Resource *pDstResource, + /* [annotation] */ + __in UINT DstSubresource, + /* [annotation] */ + __in ID3D11Resource *pSrcResource, + /* [annotation] */ + __in UINT SrcSubresource, + /* [annotation] */ + __in DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *ExecuteCommandList )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in ID3D11CommandList *pCommandList, + BOOL RestoreContextState); + + void ( STDMETHODCALLTYPE *HSSetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *HSSetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11HullShader *pHullShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + + void ( STDMETHODCALLTYPE *HSSetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *HSSetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *DSSetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *DSSetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11DomainShader *pDomainShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + + void ( STDMETHODCALLTYPE *DSSetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *DSSetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *CSSetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __in_ecount(NumViews) ID3D11ShaderResourceView *const *ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *CSSetUnorderedAccessViews )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - StartSlot ) UINT NumUAVs, + /* [annotation] */ + __in_ecount(NumUAVs) ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + /* [annotation] */ + __in_ecount(NumUAVs) const UINT *pUAVInitialCounts); + + void ( STDMETHODCALLTYPE *CSSetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_opt ID3D11ComputeShader *pComputeShader, + /* [annotation] */ + __in_ecount_opt(NumClassInstances) ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + + void ( STDMETHODCALLTYPE *CSSetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __in_ecount(NumSamplers) ID3D11SamplerState *const *ppSamplers); + + void ( STDMETHODCALLTYPE *CSSetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __in_ecount(NumBuffers) ID3D11Buffer *const *ppConstantBuffers); + + void ( STDMETHODCALLTYPE *VSGetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *PSGetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *PSGetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11PixelShader **ppPixelShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances); + + void ( STDMETHODCALLTYPE *PSGetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *VSGetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11VertexShader **ppVertexShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances); + + void ( STDMETHODCALLTYPE *PSGetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *IAGetInputLayout )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11InputLayout **ppInputLayout); + + void ( STDMETHODCALLTYPE *IAGetVertexBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) ID3D11Buffer **ppVertexBuffers, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pStrides, + /* [annotation] */ + __out_ecount_opt(NumBuffers) UINT *pOffsets); + + void ( STDMETHODCALLTYPE *IAGetIndexBuffer )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out_opt ID3D11Buffer **pIndexBuffer, + /* [annotation] */ + __out_opt DXGI_FORMAT *Format, + /* [annotation] */ + __out_opt UINT *Offset); + + void ( STDMETHODCALLTYPE *GSGetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *GSGetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11GeometryShader **ppGeometryShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances); + + void ( STDMETHODCALLTYPE *IAGetPrimitiveTopology )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out D3D11_PRIMITIVE_TOPOLOGY *pTopology); + + void ( STDMETHODCALLTYPE *VSGetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *VSGetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *GetPredication )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out_opt ID3D11Predicate **ppPredicate, + /* [annotation] */ + __out_opt BOOL *pPredicateValue); + + void ( STDMETHODCALLTYPE *GSGetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *GSGetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *OMGetRenderTargets )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumViews, + /* [annotation] */ + __out_ecount_opt(NumViews) ID3D11RenderTargetView **ppRenderTargetViews, + /* [annotation] */ + __out_opt ID3D11DepthStencilView **ppDepthStencilView); + + void ( STDMETHODCALLTYPE *OMGetRenderTargetsAndUnorderedAccessViews )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT ) UINT NumRTVs, + /* [annotation] */ + __out_ecount_opt(NumRTVs) ID3D11RenderTargetView **ppRenderTargetViews, + /* [annotation] */ + __out_opt ID3D11DepthStencilView **ppDepthStencilView, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT UAVStartSlot, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - UAVStartSlot ) UINT NumUAVs, + /* [annotation] */ + __out_ecount_opt(NumUAVs) ID3D11UnorderedAccessView **ppUnorderedAccessViews); + + void ( STDMETHODCALLTYPE *OMGetBlendState )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out_opt ID3D11BlendState **ppBlendState, + /* [annotation] */ + __out_opt FLOAT BlendFactor[ 4 ], + /* [annotation] */ + __out_opt UINT *pSampleMask); + + void ( STDMETHODCALLTYPE *OMGetDepthStencilState )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out_opt ID3D11DepthStencilState **ppDepthStencilState, + /* [annotation] */ + __out_opt UINT *pStencilRef); + + void ( STDMETHODCALLTYPE *SOGetTargets )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_SO_BUFFER_SLOT_COUNT ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppSOTargets); + + void ( STDMETHODCALLTYPE *RSGetState )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11RasterizerState **ppRasterizerState); + + void ( STDMETHODCALLTYPE *RSGetViewports )( + ID3D11DeviceContext * This, + /* [annotation] */ + __inout /*_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *pNumViewports, + /* [annotation] */ + __out_ecount_opt(*pNumViewports) D3D11_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSGetScissorRects )( + ID3D11DeviceContext * This, + /* [annotation] */ + __inout /*_range(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE )*/ UINT *pNumRects, + /* [annotation] */ + __out_ecount_opt(*pNumRects) D3D11_RECT *pRects); + + void ( STDMETHODCALLTYPE *HSGetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *HSGetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11HullShader **ppHullShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances); + + void ( STDMETHODCALLTYPE *HSGetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *HSGetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *DSGetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *DSGetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11DomainShader **ppDomainShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances); + + void ( STDMETHODCALLTYPE *DSGetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *DSGetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *CSGetShaderResources )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot ) UINT NumViews, + /* [annotation] */ + __out_ecount(NumViews) ID3D11ShaderResourceView **ppShaderResourceViews); + + void ( STDMETHODCALLTYPE *CSGetUnorderedAccessViews )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_PS_CS_UAV_REGISTER_COUNT - StartSlot ) UINT NumUAVs, + /* [annotation] */ + __out_ecount(NumUAVs) ID3D11UnorderedAccessView **ppUnorderedAccessViews); + + void ( STDMETHODCALLTYPE *CSGetShader )( + ID3D11DeviceContext * This, + /* [annotation] */ + __out ID3D11ComputeShader **ppComputeShader, + /* [annotation] */ + __out_ecount_opt(*pNumClassInstances) ID3D11ClassInstance **ppClassInstances, + /* [annotation] */ + __inout_opt UINT *pNumClassInstances); + + void ( STDMETHODCALLTYPE *CSGetSamplers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot ) UINT NumSamplers, + /* [annotation] */ + __out_ecount(NumSamplers) ID3D11SamplerState **ppSamplers); + + void ( STDMETHODCALLTYPE *CSGetConstantBuffers )( + ID3D11DeviceContext * This, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1 ) UINT StartSlot, + /* [annotation] */ + __in_range( 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot ) UINT NumBuffers, + /* [annotation] */ + __out_ecount(NumBuffers) ID3D11Buffer **ppConstantBuffers); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D11DeviceContext * This); + + void ( STDMETHODCALLTYPE *Flush )( + ID3D11DeviceContext * This); + + D3D11_DEVICE_CONTEXT_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D11DeviceContext * This); + + UINT ( STDMETHODCALLTYPE *GetContextFlags )( + ID3D11DeviceContext * This); + + HRESULT ( STDMETHODCALLTYPE *FinishCommandList )( + ID3D11DeviceContext * This, + BOOL RestoreDeferredContextState, + /* [annotation] */ + __out_opt ID3D11CommandList **ppCommandList); + + END_INTERFACE + } ID3D11DeviceContextVtbl; + + interface ID3D11DeviceContext + { + CONST_VTBL struct ID3D11DeviceContextVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11DeviceContext_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11DeviceContext_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11DeviceContext_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11DeviceContext_GetDevice(This,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,ppDevice) ) + +#define ID3D11DeviceContext_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11DeviceContext_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11DeviceContext_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + + +#define ID3D11DeviceContext_VSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> VSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_PSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> PSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_PSSetShader(This,pPixelShader,ppClassInstances,NumClassInstances) \ + ( (This)->lpVtbl -> PSSetShader(This,pPixelShader,ppClassInstances,NumClassInstances) ) + +#define ID3D11DeviceContext_PSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> PSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_VSSetShader(This,pVertexShader,ppClassInstances,NumClassInstances) \ + ( (This)->lpVtbl -> VSSetShader(This,pVertexShader,ppClassInstances,NumClassInstances) ) + +#define ID3D11DeviceContext_DrawIndexed(This,IndexCount,StartIndexLocation,BaseVertexLocation) \ + ( (This)->lpVtbl -> DrawIndexed(This,IndexCount,StartIndexLocation,BaseVertexLocation) ) + +#define ID3D11DeviceContext_Draw(This,VertexCount,StartVertexLocation) \ + ( (This)->lpVtbl -> Draw(This,VertexCount,StartVertexLocation) ) + +#define ID3D11DeviceContext_Map(This,pResource,Subresource,MapType,MapFlags,pMappedResource) \ + ( (This)->lpVtbl -> Map(This,pResource,Subresource,MapType,MapFlags,pMappedResource) ) + +#define ID3D11DeviceContext_Unmap(This,pResource,Subresource) \ + ( (This)->lpVtbl -> Unmap(This,pResource,Subresource) ) + +#define ID3D11DeviceContext_PSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> PSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_IASetInputLayout(This,pInputLayout) \ + ( (This)->lpVtbl -> IASetInputLayout(This,pInputLayout) ) + +#define ID3D11DeviceContext_IASetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) ) + +#define ID3D11DeviceContext_IASetIndexBuffer(This,pIndexBuffer,Format,Offset) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pIndexBuffer,Format,Offset) ) + +#define ID3D11DeviceContext_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D11DeviceContext_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D11DeviceContext_GSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> GSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_GSSetShader(This,pShader,ppClassInstances,NumClassInstances) \ + ( (This)->lpVtbl -> GSSetShader(This,pShader,ppClassInstances,NumClassInstances) ) + +#define ID3D11DeviceContext_IASetPrimitiveTopology(This,Topology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,Topology) ) + +#define ID3D11DeviceContext_VSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> VSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_VSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> VSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_Begin(This,pAsync) \ + ( (This)->lpVtbl -> Begin(This,pAsync) ) + +#define ID3D11DeviceContext_End(This,pAsync) \ + ( (This)->lpVtbl -> End(This,pAsync) ) + +#define ID3D11DeviceContext_GetData(This,pAsync,pData,DataSize,GetDataFlags) \ + ( (This)->lpVtbl -> GetData(This,pAsync,pData,DataSize,GetDataFlags) ) + +#define ID3D11DeviceContext_SetPredication(This,pPredicate,PredicateValue) \ + ( (This)->lpVtbl -> SetPredication(This,pPredicate,PredicateValue) ) + +#define ID3D11DeviceContext_GSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> GSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_GSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> GSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_OMSetRenderTargets(This,NumViews,ppRenderTargetViews,pDepthStencilView) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumViews,ppRenderTargetViews,pDepthStencilView) ) + +#define ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(This,NumRTVs,ppRenderTargetViews,pDepthStencilView,UAVStartSlot,NumUAVs,ppUnorderedAccessViews,pUAVInitialCounts) \ + ( (This)->lpVtbl -> OMSetRenderTargetsAndUnorderedAccessViews(This,NumRTVs,ppRenderTargetViews,pDepthStencilView,UAVStartSlot,NumUAVs,ppUnorderedAccessViews,pUAVInitialCounts) ) + +#define ID3D11DeviceContext_OMSetBlendState(This,pBlendState,BlendFactor,SampleMask) \ + ( (This)->lpVtbl -> OMSetBlendState(This,pBlendState,BlendFactor,SampleMask) ) + +#define ID3D11DeviceContext_OMSetDepthStencilState(This,pDepthStencilState,StencilRef) \ + ( (This)->lpVtbl -> OMSetDepthStencilState(This,pDepthStencilState,StencilRef) ) + +#define ID3D11DeviceContext_SOSetTargets(This,NumBuffers,ppSOTargets,pOffsets) \ + ( (This)->lpVtbl -> SOSetTargets(This,NumBuffers,ppSOTargets,pOffsets) ) + +#define ID3D11DeviceContext_DrawAuto(This) \ + ( (This)->lpVtbl -> DrawAuto(This) ) + +#define ID3D11DeviceContext_DrawIndexedInstancedIndirect(This,pBufferForArgs,AlignedByteOffsetForArgs) \ + ( (This)->lpVtbl -> DrawIndexedInstancedIndirect(This,pBufferForArgs,AlignedByteOffsetForArgs) ) + +#define ID3D11DeviceContext_DrawInstancedIndirect(This,pBufferForArgs,AlignedByteOffsetForArgs) \ + ( (This)->lpVtbl -> DrawInstancedIndirect(This,pBufferForArgs,AlignedByteOffsetForArgs) ) + +#define ID3D11DeviceContext_Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) \ + ( (This)->lpVtbl -> Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) ) + +#define ID3D11DeviceContext_DispatchIndirect(This,pBufferForArgs,AlignedByteOffsetForArgs) \ + ( (This)->lpVtbl -> DispatchIndirect(This,pBufferForArgs,AlignedByteOffsetForArgs) ) + +#define ID3D11DeviceContext_RSSetState(This,pRasterizerState) \ + ( (This)->lpVtbl -> RSSetState(This,pRasterizerState) ) + +#define ID3D11DeviceContext_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D11DeviceContext_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D11DeviceContext_CopySubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,DstZ,pSrcResource,SrcSubresource,pSrcBox) \ + ( (This)->lpVtbl -> CopySubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,DstZ,pSrcResource,SrcSubresource,pSrcBox) ) + +#define ID3D11DeviceContext_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D11DeviceContext_UpdateSubresource(This,pDstResource,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) \ + ( (This)->lpVtbl -> UpdateSubresource(This,pDstResource,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) ) + +#define ID3D11DeviceContext_CopyStructureCount(This,pDstBuffer,DstAlignedByteOffset,pSrcView) \ + ( (This)->lpVtbl -> CopyStructureCount(This,pDstBuffer,DstAlignedByteOffset,pSrcView) ) + +#define ID3D11DeviceContext_ClearRenderTargetView(This,pRenderTargetView,ColorRGBA) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,pRenderTargetView,ColorRGBA) ) + +#define ID3D11DeviceContext_ClearUnorderedAccessViewUint(This,pUnorderedAccessView,Values) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewUint(This,pUnorderedAccessView,Values) ) + +#define ID3D11DeviceContext_ClearUnorderedAccessViewFloat(This,pUnorderedAccessView,Values) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewFloat(This,pUnorderedAccessView,Values) ) + +#define ID3D11DeviceContext_ClearDepthStencilView(This,pDepthStencilView,ClearFlags,Depth,Stencil) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,pDepthStencilView,ClearFlags,Depth,Stencil) ) + +#define ID3D11DeviceContext_GenerateMips(This,pShaderResourceView) \ + ( (This)->lpVtbl -> GenerateMips(This,pShaderResourceView) ) + +#define ID3D11DeviceContext_SetResourceMinLOD(This,pResource,MinLOD) \ + ( (This)->lpVtbl -> SetResourceMinLOD(This,pResource,MinLOD) ) + +#define ID3D11DeviceContext_GetResourceMinLOD(This,pResource) \ + ( (This)->lpVtbl -> GetResourceMinLOD(This,pResource) ) + +#define ID3D11DeviceContext_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D11DeviceContext_ExecuteCommandList(This,pCommandList,RestoreContextState) \ + ( (This)->lpVtbl -> ExecuteCommandList(This,pCommandList,RestoreContextState) ) + +#define ID3D11DeviceContext_HSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> HSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_HSSetShader(This,pHullShader,ppClassInstances,NumClassInstances) \ + ( (This)->lpVtbl -> HSSetShader(This,pHullShader,ppClassInstances,NumClassInstances) ) + +#define ID3D11DeviceContext_HSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> HSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_HSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> HSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_DSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> DSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_DSSetShader(This,pDomainShader,ppClassInstances,NumClassInstances) \ + ( (This)->lpVtbl -> DSSetShader(This,pDomainShader,ppClassInstances,NumClassInstances) ) + +#define ID3D11DeviceContext_DSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> DSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_DSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> DSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_CSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> CSSetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_CSSetUnorderedAccessViews(This,StartSlot,NumUAVs,ppUnorderedAccessViews,pUAVInitialCounts) \ + ( (This)->lpVtbl -> CSSetUnorderedAccessViews(This,StartSlot,NumUAVs,ppUnorderedAccessViews,pUAVInitialCounts) ) + +#define ID3D11DeviceContext_CSSetShader(This,pComputeShader,ppClassInstances,NumClassInstances) \ + ( (This)->lpVtbl -> CSSetShader(This,pComputeShader,ppClassInstances,NumClassInstances) ) + +#define ID3D11DeviceContext_CSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> CSSetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_CSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> CSSetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_VSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> VSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_PSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> PSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_PSGetShader(This,ppPixelShader,ppClassInstances,pNumClassInstances) \ + ( (This)->lpVtbl -> PSGetShader(This,ppPixelShader,ppClassInstances,pNumClassInstances) ) + +#define ID3D11DeviceContext_PSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> PSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_VSGetShader(This,ppVertexShader,ppClassInstances,pNumClassInstances) \ + ( (This)->lpVtbl -> VSGetShader(This,ppVertexShader,ppClassInstances,pNumClassInstances) ) + +#define ID3D11DeviceContext_PSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> PSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_IAGetInputLayout(This,ppInputLayout) \ + ( (This)->lpVtbl -> IAGetInputLayout(This,ppInputLayout) ) + +#define ID3D11DeviceContext_IAGetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) \ + ( (This)->lpVtbl -> IAGetVertexBuffers(This,StartSlot,NumBuffers,ppVertexBuffers,pStrides,pOffsets) ) + +#define ID3D11DeviceContext_IAGetIndexBuffer(This,pIndexBuffer,Format,Offset) \ + ( (This)->lpVtbl -> IAGetIndexBuffer(This,pIndexBuffer,Format,Offset) ) + +#define ID3D11DeviceContext_GSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> GSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_GSGetShader(This,ppGeometryShader,ppClassInstances,pNumClassInstances) \ + ( (This)->lpVtbl -> GSGetShader(This,ppGeometryShader,ppClassInstances,pNumClassInstances) ) + +#define ID3D11DeviceContext_IAGetPrimitiveTopology(This,pTopology) \ + ( (This)->lpVtbl -> IAGetPrimitiveTopology(This,pTopology) ) + +#define ID3D11DeviceContext_VSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> VSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_VSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> VSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_GetPredication(This,ppPredicate,pPredicateValue) \ + ( (This)->lpVtbl -> GetPredication(This,ppPredicate,pPredicateValue) ) + +#define ID3D11DeviceContext_GSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> GSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_GSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> GSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_OMGetRenderTargets(This,NumViews,ppRenderTargetViews,ppDepthStencilView) \ + ( (This)->lpVtbl -> OMGetRenderTargets(This,NumViews,ppRenderTargetViews,ppDepthStencilView) ) + +#define ID3D11DeviceContext_OMGetRenderTargetsAndUnorderedAccessViews(This,NumRTVs,ppRenderTargetViews,ppDepthStencilView,UAVStartSlot,NumUAVs,ppUnorderedAccessViews) \ + ( (This)->lpVtbl -> OMGetRenderTargetsAndUnorderedAccessViews(This,NumRTVs,ppRenderTargetViews,ppDepthStencilView,UAVStartSlot,NumUAVs,ppUnorderedAccessViews) ) + +#define ID3D11DeviceContext_OMGetBlendState(This,ppBlendState,BlendFactor,pSampleMask) \ + ( (This)->lpVtbl -> OMGetBlendState(This,ppBlendState,BlendFactor,pSampleMask) ) + +#define ID3D11DeviceContext_OMGetDepthStencilState(This,ppDepthStencilState,pStencilRef) \ + ( (This)->lpVtbl -> OMGetDepthStencilState(This,ppDepthStencilState,pStencilRef) ) + +#define ID3D11DeviceContext_SOGetTargets(This,NumBuffers,ppSOTargets) \ + ( (This)->lpVtbl -> SOGetTargets(This,NumBuffers,ppSOTargets) ) + +#define ID3D11DeviceContext_RSGetState(This,ppRasterizerState) \ + ( (This)->lpVtbl -> RSGetState(This,ppRasterizerState) ) + +#define ID3D11DeviceContext_RSGetViewports(This,pNumViewports,pViewports) \ + ( (This)->lpVtbl -> RSGetViewports(This,pNumViewports,pViewports) ) + +#define ID3D11DeviceContext_RSGetScissorRects(This,pNumRects,pRects) \ + ( (This)->lpVtbl -> RSGetScissorRects(This,pNumRects,pRects) ) + +#define ID3D11DeviceContext_HSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> HSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_HSGetShader(This,ppHullShader,ppClassInstances,pNumClassInstances) \ + ( (This)->lpVtbl -> HSGetShader(This,ppHullShader,ppClassInstances,pNumClassInstances) ) + +#define ID3D11DeviceContext_HSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> HSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_HSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> HSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_DSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> DSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_DSGetShader(This,ppDomainShader,ppClassInstances,pNumClassInstances) \ + ( (This)->lpVtbl -> DSGetShader(This,ppDomainShader,ppClassInstances,pNumClassInstances) ) + +#define ID3D11DeviceContext_DSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> DSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_DSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> DSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_CSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) \ + ( (This)->lpVtbl -> CSGetShaderResources(This,StartSlot,NumViews,ppShaderResourceViews) ) + +#define ID3D11DeviceContext_CSGetUnorderedAccessViews(This,StartSlot,NumUAVs,ppUnorderedAccessViews) \ + ( (This)->lpVtbl -> CSGetUnorderedAccessViews(This,StartSlot,NumUAVs,ppUnorderedAccessViews) ) + +#define ID3D11DeviceContext_CSGetShader(This,ppComputeShader,ppClassInstances,pNumClassInstances) \ + ( (This)->lpVtbl -> CSGetShader(This,ppComputeShader,ppClassInstances,pNumClassInstances) ) + +#define ID3D11DeviceContext_CSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) \ + ( (This)->lpVtbl -> CSGetSamplers(This,StartSlot,NumSamplers,ppSamplers) ) + +#define ID3D11DeviceContext_CSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) \ + ( (This)->lpVtbl -> CSGetConstantBuffers(This,StartSlot,NumBuffers,ppConstantBuffers) ) + +#define ID3D11DeviceContext_ClearState(This) \ + ( (This)->lpVtbl -> ClearState(This) ) + +#define ID3D11DeviceContext_Flush(This) \ + ( (This)->lpVtbl -> Flush(This) ) + +#define ID3D11DeviceContext_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + +#define ID3D11DeviceContext_GetContextFlags(This) \ + ( (This)->lpVtbl -> GetContextFlags(This) ) + +#define ID3D11DeviceContext_FinishCommandList(This,RestoreDeferredContextState,ppCommandList) \ + ( (This)->lpVtbl -> FinishCommandList(This,RestoreDeferredContextState,ppCommandList) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11DeviceContext_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11Device_INTERFACE_DEFINED__ +#define __ID3D11Device_INTERFACE_DEFINED__ + +/* interface ID3D11Device */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Device; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("db6f6ddb-ac77-4e88-8253-819df9bbf140") + ID3D11Device : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE CreateBuffer( + /* [annotation] */ + __in const D3D11_BUFFER_DESC *pDesc, + /* [annotation] */ + __in_opt const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Buffer **ppBuffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateTexture1D( + /* [annotation] */ + __in const D3D11_TEXTURE1D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Texture1D **ppTexture1D) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateTexture2D( + /* [annotation] */ + __in const D3D11_TEXTURE2D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Texture2D **ppTexture2D) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateTexture3D( + /* [annotation] */ + __in const D3D11_TEXTURE3D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels) const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Texture3D **ppTexture3D) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView( + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11ShaderResourceView **ppSRView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView( + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11UnorderedAccessView **ppUAView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRenderTargetView( + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11RenderTargetView **ppRTView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilView( + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11DepthStencilView **ppDepthStencilView) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateInputLayout( + /* [annotation] */ + __in_ecount(NumElements) const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ) UINT NumElements, + /* [annotation] */ + __in const void *pShaderBytecodeWithInputSignature, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D11InputLayout **ppInputLayout) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateVertexShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11VertexShader **ppVertexShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateGeometryShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11GeometryShader **ppGeometryShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_ecount_opt(NumEntries) const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, + /* [annotation] */ + __in_range( 0, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT ) UINT NumEntries, + /* [annotation] */ + __in_ecount_opt(NumStrides) const UINT *pBufferStrides, + /* [annotation] */ + __in_range( 0, D3D11_SO_BUFFER_SLOT_COUNT ) UINT NumStrides, + /* [annotation] */ + __in UINT RasterizedStream, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11GeometryShader **ppGeometryShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreatePixelShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11PixelShader **ppPixelShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateHullShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11HullShader **ppHullShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDomainShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11DomainShader **ppDomainShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateComputeShader( + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11ComputeShader **ppComputeShader) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateClassLinkage( + /* [annotation] */ + __out ID3D11ClassLinkage **ppLinkage) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateBlendState( + /* [annotation] */ + __in const D3D11_BLEND_DESC *pBlendStateDesc, + /* [annotation] */ + __out_opt ID3D11BlendState **ppBlendState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilState( + /* [annotation] */ + __in const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, + /* [annotation] */ + __out_opt ID3D11DepthStencilState **ppDepthStencilState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState( + /* [annotation] */ + __in const D3D11_RASTERIZER_DESC *pRasterizerDesc, + /* [annotation] */ + __out_opt ID3D11RasterizerState **ppRasterizerState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateSamplerState( + /* [annotation] */ + __in const D3D11_SAMPLER_DESC *pSamplerDesc, + /* [annotation] */ + __out_opt ID3D11SamplerState **ppSamplerState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateQuery( + /* [annotation] */ + __in const D3D11_QUERY_DESC *pQueryDesc, + /* [annotation] */ + __out_opt ID3D11Query **ppQuery) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreatePredicate( + /* [annotation] */ + __in const D3D11_QUERY_DESC *pPredicateDesc, + /* [annotation] */ + __out_opt ID3D11Predicate **ppPredicate) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCounter( + /* [annotation] */ + __in const D3D11_COUNTER_DESC *pCounterDesc, + /* [annotation] */ + __out_opt ID3D11Counter **ppCounter) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext( + UINT ContextFlags, + /* [annotation] */ + __out_opt ID3D11DeviceContext **ppDeferredContext) = 0; + + virtual HRESULT STDMETHODCALLTYPE OpenSharedResource( + /* [annotation] */ + __in HANDLE hResource, + /* [annotation] */ + __in REFIID ReturnedInterface, + /* [annotation] */ + __out_opt void **ppResource) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckFormatSupport( + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __out UINT *pFormatSupport) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels( + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT SampleCount, + /* [annotation] */ + __out UINT *pNumQualityLevels) = 0; + + virtual void STDMETHODCALLTYPE CheckCounterInfo( + /* [annotation] */ + __out D3D11_COUNTER_INFO *pCounterInfo) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckCounter( + /* [annotation] */ + __in const D3D11_COUNTER_DESC *pDesc, + /* [annotation] */ + __out D3D11_COUNTER_TYPE *pType, + /* [annotation] */ + __out UINT *pActiveCounters, + /* [annotation] */ + __out_ecount_opt(*pNameLength) LPSTR szName, + /* [annotation] */ + __inout_opt UINT *pNameLength, + /* [annotation] */ + __out_ecount_opt(*pUnitsLength) LPSTR szUnits, + /* [annotation] */ + __inout_opt UINT *pUnitsLength, + /* [annotation] */ + __out_ecount_opt(*pDescriptionLength) LPSTR szDescription, + /* [annotation] */ + __inout_opt UINT *pDescriptionLength) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport( + D3D11_FEATURE Feature, + /* [annotation] */ + __out_bcount(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData) = 0; + + virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetCreationFlags( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason( void) = 0; + + virtual void STDMETHODCALLTYPE GetImmediateContext( + /* [annotation] */ + __out ID3D11DeviceContext **ppImmediateContext) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetExceptionMode( + UINT RaiseFlags) = 0; + + virtual UINT STDMETHODCALLTYPE GetExceptionMode( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11DeviceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Device * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Device * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Device * This); + + HRESULT ( STDMETHODCALLTYPE *CreateBuffer )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_BUFFER_DESC *pDesc, + /* [annotation] */ + __in_opt const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Buffer **ppBuffer); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture1D )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_TEXTURE1D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Texture1D **ppTexture1D); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture2D )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_TEXTURE2D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels * pDesc->ArraySize) const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Texture2D **ppTexture2D); + + HRESULT ( STDMETHODCALLTYPE *CreateTexture3D )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_TEXTURE3D_DESC *pDesc, + /* [annotation] */ + __in_xcount_opt(pDesc->MipLevels) const D3D11_SUBRESOURCE_DATA *pInitialData, + /* [annotation] */ + __out_opt ID3D11Texture3D **ppTexture3D); + + HRESULT ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D11Device * This, + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11ShaderResourceView **ppSRView); + + HRESULT ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D11Device * This, + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11UnorderedAccessView **ppUAView); + + HRESULT ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D11Device * This, + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11RenderTargetView **ppRTView); + + HRESULT ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D11Device * This, + /* [annotation] */ + __in ID3D11Resource *pResource, + /* [annotation] */ + __in_opt const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, + /* [annotation] */ + __out_opt ID3D11DepthStencilView **ppDepthStencilView); + + HRESULT ( STDMETHODCALLTYPE *CreateInputLayout )( + ID3D11Device * This, + /* [annotation] */ + __in_ecount(NumElements) const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, + /* [annotation] */ + __in_range( 0, D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ) UINT NumElements, + /* [annotation] */ + __in const void *pShaderBytecodeWithInputSignature, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __out_opt ID3D11InputLayout **ppInputLayout); + + HRESULT ( STDMETHODCALLTYPE *CreateVertexShader )( + ID3D11Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11VertexShader **ppVertexShader); + + HRESULT ( STDMETHODCALLTYPE *CreateGeometryShader )( + ID3D11Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11GeometryShader **ppGeometryShader); + + HRESULT ( STDMETHODCALLTYPE *CreateGeometryShaderWithStreamOutput )( + ID3D11Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_ecount_opt(NumEntries) const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, + /* [annotation] */ + __in_range( 0, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT ) UINT NumEntries, + /* [annotation] */ + __in_ecount_opt(NumStrides) const UINT *pBufferStrides, + /* [annotation] */ + __in_range( 0, D3D11_SO_BUFFER_SLOT_COUNT ) UINT NumStrides, + /* [annotation] */ + __in UINT RasterizedStream, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11GeometryShader **ppGeometryShader); + + HRESULT ( STDMETHODCALLTYPE *CreatePixelShader )( + ID3D11Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11PixelShader **ppPixelShader); + + HRESULT ( STDMETHODCALLTYPE *CreateHullShader )( + ID3D11Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11HullShader **ppHullShader); + + HRESULT ( STDMETHODCALLTYPE *CreateDomainShader )( + ID3D11Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11DomainShader **ppDomainShader); + + HRESULT ( STDMETHODCALLTYPE *CreateComputeShader )( + ID3D11Device * This, + /* [annotation] */ + __in const void *pShaderBytecode, + /* [annotation] */ + __in SIZE_T BytecodeLength, + /* [annotation] */ + __in_opt ID3D11ClassLinkage *pClassLinkage, + /* [annotation] */ + __out_opt ID3D11ComputeShader **ppComputeShader); + + HRESULT ( STDMETHODCALLTYPE *CreateClassLinkage )( + ID3D11Device * This, + /* [annotation] */ + __out ID3D11ClassLinkage **ppLinkage); + + HRESULT ( STDMETHODCALLTYPE *CreateBlendState )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_BLEND_DESC *pBlendStateDesc, + /* [annotation] */ + __out_opt ID3D11BlendState **ppBlendState); + + HRESULT ( STDMETHODCALLTYPE *CreateDepthStencilState )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, + /* [annotation] */ + __out_opt ID3D11DepthStencilState **ppDepthStencilState); + + HRESULT ( STDMETHODCALLTYPE *CreateRasterizerState )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_RASTERIZER_DESC *pRasterizerDesc, + /* [annotation] */ + __out_opt ID3D11RasterizerState **ppRasterizerState); + + HRESULT ( STDMETHODCALLTYPE *CreateSamplerState )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_SAMPLER_DESC *pSamplerDesc, + /* [annotation] */ + __out_opt ID3D11SamplerState **ppSamplerState); + + HRESULT ( STDMETHODCALLTYPE *CreateQuery )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_QUERY_DESC *pQueryDesc, + /* [annotation] */ + __out_opt ID3D11Query **ppQuery); + + HRESULT ( STDMETHODCALLTYPE *CreatePredicate )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_QUERY_DESC *pPredicateDesc, + /* [annotation] */ + __out_opt ID3D11Predicate **ppPredicate); + + HRESULT ( STDMETHODCALLTYPE *CreateCounter )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_COUNTER_DESC *pCounterDesc, + /* [annotation] */ + __out_opt ID3D11Counter **ppCounter); + + HRESULT ( STDMETHODCALLTYPE *CreateDeferredContext )( + ID3D11Device * This, + UINT ContextFlags, + /* [annotation] */ + __out_opt ID3D11DeviceContext **ppDeferredContext); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedResource )( + ID3D11Device * This, + /* [annotation] */ + __in HANDLE hResource, + /* [annotation] */ + __in REFIID ReturnedInterface, + /* [annotation] */ + __out_opt void **ppResource); + + HRESULT ( STDMETHODCALLTYPE *CheckFormatSupport )( + ID3D11Device * This, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __out UINT *pFormatSupport); + + HRESULT ( STDMETHODCALLTYPE *CheckMultisampleQualityLevels )( + ID3D11Device * This, + /* [annotation] */ + __in DXGI_FORMAT Format, + /* [annotation] */ + __in UINT SampleCount, + /* [annotation] */ + __out UINT *pNumQualityLevels); + + void ( STDMETHODCALLTYPE *CheckCounterInfo )( + ID3D11Device * This, + /* [annotation] */ + __out D3D11_COUNTER_INFO *pCounterInfo); + + HRESULT ( STDMETHODCALLTYPE *CheckCounter )( + ID3D11Device * This, + /* [annotation] */ + __in const D3D11_COUNTER_DESC *pDesc, + /* [annotation] */ + __out D3D11_COUNTER_TYPE *pType, + /* [annotation] */ + __out UINT *pActiveCounters, + /* [annotation] */ + __out_ecount_opt(*pNameLength) LPSTR szName, + /* [annotation] */ + __inout_opt UINT *pNameLength, + /* [annotation] */ + __out_ecount_opt(*pUnitsLength) LPSTR szUnits, + /* [annotation] */ + __inout_opt UINT *pUnitsLength, + /* [annotation] */ + __out_ecount_opt(*pDescriptionLength) LPSTR szDescription, + /* [annotation] */ + __inout_opt UINT *pDescriptionLength); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D11Device * This, + D3D11_FEATURE Feature, + /* [annotation] */ + __out_bcount(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D11Device * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D11Device * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D11Device * This, + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData); + + D3D_FEATURE_LEVEL ( STDMETHODCALLTYPE *GetFeatureLevel )( + ID3D11Device * This); + + UINT ( STDMETHODCALLTYPE *GetCreationFlags )( + ID3D11Device * This); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D11Device * This); + + void ( STDMETHODCALLTYPE *GetImmediateContext )( + ID3D11Device * This, + /* [annotation] */ + __out ID3D11DeviceContext **ppImmediateContext); + + HRESULT ( STDMETHODCALLTYPE *SetExceptionMode )( + ID3D11Device * This, + UINT RaiseFlags); + + UINT ( STDMETHODCALLTYPE *GetExceptionMode )( + ID3D11Device * This); + + END_INTERFACE + } ID3D11DeviceVtbl; + + interface ID3D11Device + { + CONST_VTBL struct ID3D11DeviceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Device_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Device_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Device_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Device_CreateBuffer(This,pDesc,pInitialData,ppBuffer) \ + ( (This)->lpVtbl -> CreateBuffer(This,pDesc,pInitialData,ppBuffer) ) + +#define ID3D11Device_CreateTexture1D(This,pDesc,pInitialData,ppTexture1D) \ + ( (This)->lpVtbl -> CreateTexture1D(This,pDesc,pInitialData,ppTexture1D) ) + +#define ID3D11Device_CreateTexture2D(This,pDesc,pInitialData,ppTexture2D) \ + ( (This)->lpVtbl -> CreateTexture2D(This,pDesc,pInitialData,ppTexture2D) ) + +#define ID3D11Device_CreateTexture3D(This,pDesc,pInitialData,ppTexture3D) \ + ( (This)->lpVtbl -> CreateTexture3D(This,pDesc,pInitialData,ppTexture3D) ) + +#define ID3D11Device_CreateShaderResourceView(This,pResource,pDesc,ppSRView) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,ppSRView) ) + +#define ID3D11Device_CreateUnorderedAccessView(This,pResource,pDesc,ppUAView) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pDesc,ppUAView) ) + +#define ID3D11Device_CreateRenderTargetView(This,pResource,pDesc,ppRTView) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,ppRTView) ) + +#define ID3D11Device_CreateDepthStencilView(This,pResource,pDesc,ppDepthStencilView) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,ppDepthStencilView) ) + +#define ID3D11Device_CreateInputLayout(This,pInputElementDescs,NumElements,pShaderBytecodeWithInputSignature,BytecodeLength,ppInputLayout) \ + ( (This)->lpVtbl -> CreateInputLayout(This,pInputElementDescs,NumElements,pShaderBytecodeWithInputSignature,BytecodeLength,ppInputLayout) ) + +#define ID3D11Device_CreateVertexShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppVertexShader) \ + ( (This)->lpVtbl -> CreateVertexShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppVertexShader) ) + +#define ID3D11Device_CreateGeometryShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppGeometryShader) \ + ( (This)->lpVtbl -> CreateGeometryShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppGeometryShader) ) + +#define ID3D11Device_CreateGeometryShaderWithStreamOutput(This,pShaderBytecode,BytecodeLength,pSODeclaration,NumEntries,pBufferStrides,NumStrides,RasterizedStream,pClassLinkage,ppGeometryShader) \ + ( (This)->lpVtbl -> CreateGeometryShaderWithStreamOutput(This,pShaderBytecode,BytecodeLength,pSODeclaration,NumEntries,pBufferStrides,NumStrides,RasterizedStream,pClassLinkage,ppGeometryShader) ) + +#define ID3D11Device_CreatePixelShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppPixelShader) \ + ( (This)->lpVtbl -> CreatePixelShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppPixelShader) ) + +#define ID3D11Device_CreateHullShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppHullShader) \ + ( (This)->lpVtbl -> CreateHullShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppHullShader) ) + +#define ID3D11Device_CreateDomainShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppDomainShader) \ + ( (This)->lpVtbl -> CreateDomainShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppDomainShader) ) + +#define ID3D11Device_CreateComputeShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppComputeShader) \ + ( (This)->lpVtbl -> CreateComputeShader(This,pShaderBytecode,BytecodeLength,pClassLinkage,ppComputeShader) ) + +#define ID3D11Device_CreateClassLinkage(This,ppLinkage) \ + ( (This)->lpVtbl -> CreateClassLinkage(This,ppLinkage) ) + +#define ID3D11Device_CreateBlendState(This,pBlendStateDesc,ppBlendState) \ + ( (This)->lpVtbl -> CreateBlendState(This,pBlendStateDesc,ppBlendState) ) + +#define ID3D11Device_CreateDepthStencilState(This,pDepthStencilDesc,ppDepthStencilState) \ + ( (This)->lpVtbl -> CreateDepthStencilState(This,pDepthStencilDesc,ppDepthStencilState) ) + +#define ID3D11Device_CreateRasterizerState(This,pRasterizerDesc,ppRasterizerState) \ + ( (This)->lpVtbl -> CreateRasterizerState(This,pRasterizerDesc,ppRasterizerState) ) + +#define ID3D11Device_CreateSamplerState(This,pSamplerDesc,ppSamplerState) \ + ( (This)->lpVtbl -> CreateSamplerState(This,pSamplerDesc,ppSamplerState) ) + +#define ID3D11Device_CreateQuery(This,pQueryDesc,ppQuery) \ + ( (This)->lpVtbl -> CreateQuery(This,pQueryDesc,ppQuery) ) + +#define ID3D11Device_CreatePredicate(This,pPredicateDesc,ppPredicate) \ + ( (This)->lpVtbl -> CreatePredicate(This,pPredicateDesc,ppPredicate) ) + +#define ID3D11Device_CreateCounter(This,pCounterDesc,ppCounter) \ + ( (This)->lpVtbl -> CreateCounter(This,pCounterDesc,ppCounter) ) + +#define ID3D11Device_CreateDeferredContext(This,ContextFlags,ppDeferredContext) \ + ( (This)->lpVtbl -> CreateDeferredContext(This,ContextFlags,ppDeferredContext) ) + +#define ID3D11Device_OpenSharedResource(This,hResource,ReturnedInterface,ppResource) \ + ( (This)->lpVtbl -> OpenSharedResource(This,hResource,ReturnedInterface,ppResource) ) + +#define ID3D11Device_CheckFormatSupport(This,Format,pFormatSupport) \ + ( (This)->lpVtbl -> CheckFormatSupport(This,Format,pFormatSupport) ) + +#define ID3D11Device_CheckMultisampleQualityLevels(This,Format,SampleCount,pNumQualityLevels) \ + ( (This)->lpVtbl -> CheckMultisampleQualityLevels(This,Format,SampleCount,pNumQualityLevels) ) + +#define ID3D11Device_CheckCounterInfo(This,pCounterInfo) \ + ( (This)->lpVtbl -> CheckCounterInfo(This,pCounterInfo) ) + +#define ID3D11Device_CheckCounter(This,pDesc,pType,pActiveCounters,szName,pNameLength,szUnits,pUnitsLength,szDescription,pDescriptionLength) \ + ( (This)->lpVtbl -> CheckCounter(This,pDesc,pType,pActiveCounters,szName,pNameLength,szUnits,pUnitsLength,szDescription,pDescriptionLength) ) + +#define ID3D11Device_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D11Device_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D11Device_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D11Device_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D11Device_GetFeatureLevel(This) \ + ( (This)->lpVtbl -> GetFeatureLevel(This) ) + +#define ID3D11Device_GetCreationFlags(This) \ + ( (This)->lpVtbl -> GetCreationFlags(This) ) + +#define ID3D11Device_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D11Device_GetImmediateContext(This,ppImmediateContext) \ + ( (This)->lpVtbl -> GetImmediateContext(This,ppImmediateContext) ) + +#define ID3D11Device_SetExceptionMode(This,RaiseFlags) \ + ( (This)->lpVtbl -> SetExceptionMode(This,RaiseFlags) ) + +#define ID3D11Device_GetExceptionMode(This) \ + ( (This)->lpVtbl -> GetExceptionMode(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Device_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11_0000_0031 */ +/* [local] */ + +typedef +enum D3D11_CREATE_DEVICE_FLAG + { D3D11_CREATE_DEVICE_SINGLETHREADED = 0x1, + D3D11_CREATE_DEVICE_DEBUG = 0x2, + D3D11_CREATE_DEVICE_SWITCH_TO_REF = 0x4, + D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS = 0x8, + D3D11_CREATE_DEVICE_BGRA_SUPPORT = 0x20 + } D3D11_CREATE_DEVICE_FLAG; + +#define D3D11_SDK_VERSION ( 7 ) + +#include "d3d10_1.h" +#if !defined( D3D11_IGNORE_SDK_LAYERS ) +#include "d3d11sdklayers.h" +#endif +#include "d3d10misc.h" +#include "d3d10shader.h" +#include "d3d10effect.h" +#include "d3d10_1shader.h" + +/////////////////////////////////////////////////////////////////////////// +// D3D11CreateDevice +// ------------------ +// +// pAdapter +// If NULL, D3D11CreateDevice will choose the primary adapter and +// create a new instance from a temporarily created IDXGIFactory. +// If non-NULL, D3D11CreateDevice will register the appropriate +// device, if necessary (via IDXGIAdapter::RegisterDrver), before +// creating the device. +// DriverType +// Specifies the driver type to be created: hardware, reference or +// null. +// Software +// HMODULE of a DLL implementing a software rasterizer. Must be NULL for +// non-Software driver types. +// Flags +// Any of those documented for D3D11CreateDeviceAndSwapChain. +// pFeatureLevels +// Any of those documented for D3D11CreateDeviceAndSwapChain. +// FeatureLevels +// Size of feature levels array. +// SDKVersion +// SDK version. Use the D3D11_SDK_VERSION macro. +// ppDevice +// Pointer to returned interface. May be NULL. +// pFeatureLevel +// Pointer to returned feature level. May be NULL. +// ppImmediateContext +// Pointer to returned interface. May be NULL. +// +// Return Values +// Any of those documented for +// CreateDXGIFactory1 +// IDXGIFactory::EnumAdapters +// IDXGIAdapter::RegisterDriver +// D3D11CreateDevice +// +/////////////////////////////////////////////////////////////////////////// +typedef HRESULT (WINAPI* PFN_D3D11_CREATE_DEVICE)( __in_opt IDXGIAdapter*, + D3D_DRIVER_TYPE, HMODULE, UINT, + __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL*, + UINT FeatureLevels, UINT, __out_opt ID3D11Device**, + __out_opt D3D_FEATURE_LEVEL*, __out_opt ID3D11DeviceContext** ); + +HRESULT WINAPI D3D11CreateDevice( + __in_opt IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + __out_opt ID3D11Device** ppDevice, + __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, + __out_opt ID3D11DeviceContext** ppImmediateContext ); + +/////////////////////////////////////////////////////////////////////////// +// D3D11CreateDeviceAndSwapChain +// ------------------------------ +// +// ppAdapter +// If NULL, D3D11CreateDevice will choose the primary adapter and +// create a new instance from a temporarily created IDXGIFactory. +// If non-NULL, D3D11CreateDevice will register the appropriate +// device, if necessary (via IDXGIAdapter::RegisterDrver), before +// creating the device. +// DriverType +// Specifies the driver type to be created: hardware, reference or +// null. +// Software +// HMODULE of a DLL implementing a software rasterizer. Must be NULL for +// non-Software driver types. +// Flags +// Any of those documented for D3D11CreateDevice. +// pFeatureLevels +// Array of any of the following: +// D3D_FEATURE_LEVEL_11_0 +// D3D_FEATURE_LEVEL_10_1 +// D3D_FEATURE_LEVEL_10_0 +// D3D_FEATURE_LEVEL_9_3 +// D3D_FEATURE_LEVEL_9_2 +// D3D_FEATURE_LEVEL_9_1 +// Order indicates sequence in which instantiation will be attempted. If +// NULL, then the implied order is the same as previously listed (i.e. +// prefer most features available). +// FeatureLevels +// Size of feature levels array. +// SDKVersion +// SDK version. Use the D3D11_SDK_VERSION macro. +// pSwapChainDesc +// Swap chain description, may be NULL. +// ppSwapChain +// Pointer to returned interface. May be NULL. +// ppDevice +// Pointer to returned interface. May be NULL. +// pFeatureLevel +// Pointer to returned feature level. May be NULL. +// ppImmediateContext +// Pointer to returned interface. May be NULL. +// +// Return Values +// Any of those documented for +// CreateDXGIFactory1 +// IDXGIFactory::EnumAdapters +// IDXGIAdapter::RegisterDriver +// D3D11CreateDevice +// IDXGIFactory::CreateSwapChain +// +/////////////////////////////////////////////////////////////////////////// +typedef HRESULT (WINAPI* PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)( __in_opt IDXGIAdapter*, + D3D_DRIVER_TYPE, HMODULE, UINT, + __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL*, + UINT FeatureLevels, UINT, __in_opt CONST DXGI_SWAP_CHAIN_DESC*, + __out_opt IDXGISwapChain**, __out_opt ID3D11Device**, + __out_opt D3D_FEATURE_LEVEL*, __out_opt ID3D11DeviceContext** ); + +HRESULT WINAPI D3D11CreateDeviceAndSwapChain( + __in_opt IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + __out_opt IDXGISwapChain** ppSwapChain, + __out_opt ID3D11Device** ppDevice, + __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, + __out_opt ID3D11DeviceContext** ppImmediateContext ); + +DEFINE_GUID(IID_ID3D11DeviceChild,0x1841e5c8,0x16b0,0x489b,0xbc,0xc8,0x44,0xcf,0xb0,0xd5,0xde,0xae); +DEFINE_GUID(IID_ID3D11DepthStencilState,0x03823efb,0x8d8f,0x4e1c,0x9a,0xa2,0xf6,0x4b,0xb2,0xcb,0xfd,0xf1); +DEFINE_GUID(IID_ID3D11BlendState,0x75b68faa,0x347d,0x4159,0x8f,0x45,0xa0,0x64,0x0f,0x01,0xcd,0x9a); +DEFINE_GUID(IID_ID3D11RasterizerState,0x9bb4ab81,0xab1a,0x4d8f,0xb5,0x06,0xfc,0x04,0x20,0x0b,0x6e,0xe7); +DEFINE_GUID(IID_ID3D11Resource,0xdc8e63f3,0xd12b,0x4952,0xb4,0x7b,0x5e,0x45,0x02,0x6a,0x86,0x2d); +DEFINE_GUID(IID_ID3D11Buffer,0x48570b85,0xd1ee,0x4fcd,0xa2,0x50,0xeb,0x35,0x07,0x22,0xb0,0x37); +DEFINE_GUID(IID_ID3D11Texture1D,0xf8fb5c27,0xc6b3,0x4f75,0xa4,0xc8,0x43,0x9a,0xf2,0xef,0x56,0x4c); +DEFINE_GUID(IID_ID3D11Texture2D,0x6f15aaf2,0xd208,0x4e89,0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c); +DEFINE_GUID(IID_ID3D11Texture3D,0x037e866e,0xf56d,0x4357,0xa8,0xaf,0x9d,0xab,0xbe,0x6e,0x25,0x0e); +DEFINE_GUID(IID_ID3D11View,0x839d1216,0xbb2e,0x412b,0xb7,0xf4,0xa9,0xdb,0xeb,0xe0,0x8e,0xd1); +DEFINE_GUID(IID_ID3D11ShaderResourceView,0xb0e06fe0,0x8192,0x4e1a,0xb1,0xca,0x36,0xd7,0x41,0x47,0x10,0xb2); +DEFINE_GUID(IID_ID3D11RenderTargetView,0xdfdba067,0x0b8d,0x4865,0x87,0x5b,0xd7,0xb4,0x51,0x6c,0xc1,0x64); +DEFINE_GUID(IID_ID3D11DepthStencilView,0x9fdac92a,0x1876,0x48c3,0xaf,0xad,0x25,0xb9,0x4f,0x84,0xa9,0xb6); +DEFINE_GUID(IID_ID3D11UnorderedAccessView,0x28acf509,0x7f5c,0x48f6,0x86,0x11,0xf3,0x16,0x01,0x0a,0x63,0x80); +DEFINE_GUID(IID_ID3D11VertexShader,0x3b301d64,0xd678,0x4289,0x88,0x97,0x22,0xf8,0x92,0x8b,0x72,0xf3); +DEFINE_GUID(IID_ID3D11HullShader,0x8e5c6061,0x628a,0x4c8e,0x82,0x64,0xbb,0xe4,0x5c,0xb3,0xd5,0xdd); +DEFINE_GUID(IID_ID3D11DomainShader,0xf582c508,0x0f36,0x490c,0x99,0x77,0x31,0xee,0xce,0x26,0x8c,0xfa); +DEFINE_GUID(IID_ID3D11GeometryShader,0x38325b96,0xeffb,0x4022,0xba,0x02,0x2e,0x79,0x5b,0x70,0x27,0x5c); +DEFINE_GUID(IID_ID3D11PixelShader,0xea82e40d,0x51dc,0x4f33,0x93,0xd4,0xdb,0x7c,0x91,0x25,0xae,0x8c); +DEFINE_GUID(IID_ID3D11ComputeShader,0x4f5b196e,0xc2bd,0x495e,0xbd,0x01,0x1f,0xde,0xd3,0x8e,0x49,0x69); +DEFINE_GUID(IID_ID3D11InputLayout,0xe4819ddc,0x4cf0,0x4025,0xbd,0x26,0x5d,0xe8,0x2a,0x3e,0x07,0xb7); +DEFINE_GUID(IID_ID3D11SamplerState,0xda6fea51,0x564c,0x4487,0x98,0x10,0xf0,0xd0,0xf9,0xb4,0xe3,0xa5); +DEFINE_GUID(IID_ID3D11Asynchronous,0x4b35d0cd,0x1e15,0x4258,0x9c,0x98,0x1b,0x13,0x33,0xf6,0xdd,0x3b); +DEFINE_GUID(IID_ID3D11Query,0xd6c00747,0x87b7,0x425e,0xb8,0x4d,0x44,0xd1,0x08,0x56,0x0a,0xfd); +DEFINE_GUID(IID_ID3D11Predicate,0x9eb576dd,0x9f77,0x4d86,0x81,0xaa,0x8b,0xab,0x5f,0xe4,0x90,0xe2); +DEFINE_GUID(IID_ID3D11Counter,0x6e8c49fb,0xa371,0x4770,0xb4,0x40,0x29,0x08,0x60,0x22,0xb7,0x41); +DEFINE_GUID(IID_ID3D11ClassInstance,0xa6cd7faa,0xb0b7,0x4a2f,0x94,0x36,0x86,0x62,0xa6,0x57,0x97,0xcb); +DEFINE_GUID(IID_ID3D11ClassLinkage,0xddf57cba,0x9543,0x46e4,0xa1,0x2b,0xf2,0x07,0xa0,0xfe,0x7f,0xed); +DEFINE_GUID(IID_ID3D11CommandList,0xa24bc4d1,0x769e,0x43f7,0x80,0x13,0x98,0xff,0x56,0x6c,0x18,0xe2); +DEFINE_GUID(IID_ID3D11DeviceContext,0xc0bfa96c,0xe089,0x44fb,0x8e,0xaf,0x26,0xf8,0x79,0x61,0x90,0xda); +DEFINE_GUID(IID_ID3D11Device,0xdb6f6ddb,0xac77,0x4e88,0x82,0x53,0x81,0x9d,0xf9,0xbb,0xf1,0x40); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0031_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11_0000_0031_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/dxsdk/Include/D3D11SDKLayers.h b/dxsdk/Include/D3D11SDKLayers.h new file mode 100644 index 0000000..5970f81 --- /dev/null +++ b/dxsdk/Include/D3D11SDKLayers.h @@ -0,0 +1,1669 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* Compiler settings for d3d11sdklayers.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 7.00.0555 + protocol : all , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3d11sdklayers_h__ +#define __d3d11sdklayers_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D11Debug_FWD_DEFINED__ +#define __ID3D11Debug_FWD_DEFINED__ +typedef interface ID3D11Debug ID3D11Debug; +#endif /* __ID3D11Debug_FWD_DEFINED__ */ + + +#ifndef __ID3D11SwitchToRef_FWD_DEFINED__ +#define __ID3D11SwitchToRef_FWD_DEFINED__ +typedef interface ID3D11SwitchToRef ID3D11SwitchToRef; +#endif /* __ID3D11SwitchToRef_FWD_DEFINED__ */ + + +#ifndef __ID3D11InfoQueue_FWD_DEFINED__ +#define __ID3D11InfoQueue_FWD_DEFINED__ +typedef interface ID3D11InfoQueue ID3D11InfoQueue; +#endif /* __ID3D11InfoQueue_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "d3d11.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3d11sdklayers_0000_0000 */ +/* [local] */ + +#define D3D11_SDK_LAYERS_VERSION ( 1 ) + +#define D3D11_DEBUG_FEATURE_FLUSH_PER_RENDER_OP ( 0x1 ) + +#define D3D11_DEBUG_FEATURE_FINISH_PER_RENDER_OP ( 0x2 ) + +#define D3D11_DEBUG_FEATURE_PRESENT_PER_RENDER_OP ( 0x4 ) + +typedef +enum D3D11_RLDO_FLAGS + { D3D11_RLDO_SUMMARY = 0x1, + D3D11_RLDO_DETAIL = 0x2 + } D3D11_RLDO_FLAGS; + +#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus ) +} +inline D3D11_RLDO_FLAGS operator~( D3D11_RLDO_FLAGS a ) +{ return D3D11_RLDO_FLAGS( ~UINT( a ) ); } +inline D3D11_RLDO_FLAGS operator&( D3D11_RLDO_FLAGS a, D3D11_RLDO_FLAGS b ) +{ return D3D11_RLDO_FLAGS( UINT( a ) & UINT( b ) ); } +inline D3D11_RLDO_FLAGS operator|( D3D11_RLDO_FLAGS a, D3D11_RLDO_FLAGS b ) +{ return D3D11_RLDO_FLAGS( UINT( a ) | UINT( b ) ); } +inline D3D11_RLDO_FLAGS operator^( D3D11_RLDO_FLAGS a, D3D11_RLDO_FLAGS b ) +{ return D3D11_RLDO_FLAGS( UINT( a ) ^ UINT( b ) ); } +inline D3D11_RLDO_FLAGS& operator&=( D3D11_RLDO_FLAGS& a, D3D11_RLDO_FLAGS b ) +{ a = a & b; return a; } +inline D3D11_RLDO_FLAGS& operator|=( D3D11_RLDO_FLAGS& a, D3D11_RLDO_FLAGS b ) +{ a = a | b; return a; } +inline D3D11_RLDO_FLAGS& operator^=( D3D11_RLDO_FLAGS& a, D3D11_RLDO_FLAGS b ) +{ a = a ^ b; return a; } +extern "C"{ +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11sdklayers_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11sdklayers_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D11Debug_INTERFACE_DEFINED__ +#define __ID3D11Debug_INTERFACE_DEFINED__ + +/* interface ID3D11Debug */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11Debug; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("79cf2233-7536-4948-9d36-1e4692dc5760") + ID3D11Debug : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetFeatureMask( + UINT Mask) = 0; + + virtual UINT STDMETHODCALLTYPE GetFeatureMask( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPresentPerRenderOpDelay( + UINT Milliseconds) = 0; + + virtual UINT STDMETHODCALLTYPE GetPresentPerRenderOpDelay( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetSwapChain( + /* [annotation] */ + __in_opt IDXGISwapChain *pSwapChain) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSwapChain( + /* [annotation] */ + __out IDXGISwapChain **ppSwapChain) = 0; + + virtual HRESULT STDMETHODCALLTYPE ValidateContext( + /* [annotation] */ + __in ID3D11DeviceContext *pContext) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects( + D3D11_RLDO_FLAGS Flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE ValidateContextForDispatch( + /* [annotation] */ + __in ID3D11DeviceContext *pContext) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11DebugVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11Debug * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11Debug * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11Debug * This); + + HRESULT ( STDMETHODCALLTYPE *SetFeatureMask )( + ID3D11Debug * This, + UINT Mask); + + UINT ( STDMETHODCALLTYPE *GetFeatureMask )( + ID3D11Debug * This); + + HRESULT ( STDMETHODCALLTYPE *SetPresentPerRenderOpDelay )( + ID3D11Debug * This, + UINT Milliseconds); + + UINT ( STDMETHODCALLTYPE *GetPresentPerRenderOpDelay )( + ID3D11Debug * This); + + HRESULT ( STDMETHODCALLTYPE *SetSwapChain )( + ID3D11Debug * This, + /* [annotation] */ + __in_opt IDXGISwapChain *pSwapChain); + + HRESULT ( STDMETHODCALLTYPE *GetSwapChain )( + ID3D11Debug * This, + /* [annotation] */ + __out IDXGISwapChain **ppSwapChain); + + HRESULT ( STDMETHODCALLTYPE *ValidateContext )( + ID3D11Debug * This, + /* [annotation] */ + __in ID3D11DeviceContext *pContext); + + HRESULT ( STDMETHODCALLTYPE *ReportLiveDeviceObjects )( + ID3D11Debug * This, + D3D11_RLDO_FLAGS Flags); + + HRESULT ( STDMETHODCALLTYPE *ValidateContextForDispatch )( + ID3D11Debug * This, + /* [annotation] */ + __in ID3D11DeviceContext *pContext); + + END_INTERFACE + } ID3D11DebugVtbl; + + interface ID3D11Debug + { + CONST_VTBL struct ID3D11DebugVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11Debug_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11Debug_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11Debug_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11Debug_SetFeatureMask(This,Mask) \ + ( (This)->lpVtbl -> SetFeatureMask(This,Mask) ) + +#define ID3D11Debug_GetFeatureMask(This) \ + ( (This)->lpVtbl -> GetFeatureMask(This) ) + +#define ID3D11Debug_SetPresentPerRenderOpDelay(This,Milliseconds) \ + ( (This)->lpVtbl -> SetPresentPerRenderOpDelay(This,Milliseconds) ) + +#define ID3D11Debug_GetPresentPerRenderOpDelay(This) \ + ( (This)->lpVtbl -> GetPresentPerRenderOpDelay(This) ) + +#define ID3D11Debug_SetSwapChain(This,pSwapChain) \ + ( (This)->lpVtbl -> SetSwapChain(This,pSwapChain) ) + +#define ID3D11Debug_GetSwapChain(This,ppSwapChain) \ + ( (This)->lpVtbl -> GetSwapChain(This,ppSwapChain) ) + +#define ID3D11Debug_ValidateContext(This,pContext) \ + ( (This)->lpVtbl -> ValidateContext(This,pContext) ) + +#define ID3D11Debug_ReportLiveDeviceObjects(This,Flags) \ + ( (This)->lpVtbl -> ReportLiveDeviceObjects(This,Flags) ) + +#define ID3D11Debug_ValidateContextForDispatch(This,pContext) \ + ( (This)->lpVtbl -> ValidateContextForDispatch(This,pContext) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11Debug_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D11SwitchToRef_INTERFACE_DEFINED__ +#define __ID3D11SwitchToRef_INTERFACE_DEFINED__ + +/* interface ID3D11SwitchToRef */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11SwitchToRef; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1ef337e3-58e7-4f83-a692-db221f5ed47e") + ID3D11SwitchToRef : public IUnknown + { + public: + virtual BOOL STDMETHODCALLTYPE SetUseRef( + BOOL UseRef) = 0; + + virtual BOOL STDMETHODCALLTYPE GetUseRef( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11SwitchToRefVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11SwitchToRef * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11SwitchToRef * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11SwitchToRef * This); + + BOOL ( STDMETHODCALLTYPE *SetUseRef )( + ID3D11SwitchToRef * This, + BOOL UseRef); + + BOOL ( STDMETHODCALLTYPE *GetUseRef )( + ID3D11SwitchToRef * This); + + END_INTERFACE + } ID3D11SwitchToRefVtbl; + + interface ID3D11SwitchToRef + { + CONST_VTBL struct ID3D11SwitchToRefVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11SwitchToRef_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11SwitchToRef_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11SwitchToRef_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11SwitchToRef_SetUseRef(This,UseRef) \ + ( (This)->lpVtbl -> SetUseRef(This,UseRef) ) + +#define ID3D11SwitchToRef_GetUseRef(This) \ + ( (This)->lpVtbl -> GetUseRef(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11SwitchToRef_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11sdklayers_0000_0002 */ +/* [local] */ + +typedef +enum D3D11_MESSAGE_CATEGORY + { D3D11_MESSAGE_CATEGORY_APPLICATION_DEFINED = 0, + D3D11_MESSAGE_CATEGORY_MISCELLANEOUS = ( D3D11_MESSAGE_CATEGORY_APPLICATION_DEFINED + 1 ) , + D3D11_MESSAGE_CATEGORY_INITIALIZATION = ( D3D11_MESSAGE_CATEGORY_MISCELLANEOUS + 1 ) , + D3D11_MESSAGE_CATEGORY_CLEANUP = ( D3D11_MESSAGE_CATEGORY_INITIALIZATION + 1 ) , + D3D11_MESSAGE_CATEGORY_COMPILATION = ( D3D11_MESSAGE_CATEGORY_CLEANUP + 1 ) , + D3D11_MESSAGE_CATEGORY_STATE_CREATION = ( D3D11_MESSAGE_CATEGORY_COMPILATION + 1 ) , + D3D11_MESSAGE_CATEGORY_STATE_SETTING = ( D3D11_MESSAGE_CATEGORY_STATE_CREATION + 1 ) , + D3D11_MESSAGE_CATEGORY_STATE_GETTING = ( D3D11_MESSAGE_CATEGORY_STATE_SETTING + 1 ) , + D3D11_MESSAGE_CATEGORY_RESOURCE_MANIPULATION = ( D3D11_MESSAGE_CATEGORY_STATE_GETTING + 1 ) , + D3D11_MESSAGE_CATEGORY_EXECUTION = ( D3D11_MESSAGE_CATEGORY_RESOURCE_MANIPULATION + 1 ) + } D3D11_MESSAGE_CATEGORY; + +typedef +enum D3D11_MESSAGE_SEVERITY + { D3D11_MESSAGE_SEVERITY_CORRUPTION = 0, + D3D11_MESSAGE_SEVERITY_ERROR = ( D3D11_MESSAGE_SEVERITY_CORRUPTION + 1 ) , + D3D11_MESSAGE_SEVERITY_WARNING = ( D3D11_MESSAGE_SEVERITY_ERROR + 1 ) , + D3D11_MESSAGE_SEVERITY_INFO = ( D3D11_MESSAGE_SEVERITY_WARNING + 1 ) + } D3D11_MESSAGE_SEVERITY; + +typedef +enum D3D11_MESSAGE_ID + { D3D11_MESSAGE_ID_UNKNOWN = 0, + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_HAZARD = ( D3D11_MESSAGE_ID_UNKNOWN + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SOSETTARGETS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_STRING_FROM_APPLICATION = ( D3D11_MESSAGE_ID_DEVICE_SOSETTARGETS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_THIS = ( D3D11_MESSAGE_ID_STRING_FROM_APPLICATION + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER1 = ( D3D11_MESSAGE_ID_CORRUPTED_THIS + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER2 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER1 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER3 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER2 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER4 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER3 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER5 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER4 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER6 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER5 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER7 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER6 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER8 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER7 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER9 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER8 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER10 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER9 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER11 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER10 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER12 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER11 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER13 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER12 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER14 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER13 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER15 = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER14 + 1 ) , + D3D11_MESSAGE_ID_CORRUPTED_MULTITHREADING = ( D3D11_MESSAGE_ID_CORRUPTED_PARAMETER15 + 1 ) , + D3D11_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CORRUPTED_MULTITHREADING + 1 ) , + D3D11_MESSAGE_ID_IASETINPUTLAYOUT_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_IASETINPUTLAYOUT_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_IASETINDEXBUFFER_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_VSSETSHADER_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_IASETINDEXBUFFER_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_VSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_VSSETSHADER_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_VSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_VSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_VSSETSAMPLERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_VSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_GSSETSHADER_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_VSSETSAMPLERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_GSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_GSSETSHADER_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_GSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_GSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_GSSETSAMPLERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_GSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_SOSETTARGETS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_GSSETSAMPLERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_PSSETSHADER_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_SOSETTARGETS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_PSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_PSSETSHADER_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_PSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_PSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_PSSETSAMPLERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_PSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_RSSETSTATE_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_PSSETSAMPLERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_OMSETBLENDSTATE_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_RSSETSTATE_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_OMSETDEPTHSTENCILSTATE_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_OMSETBLENDSTATE_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_OMSETDEPTHSTENCILSTATE_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_SETPREDICATION_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_OMSETRENDERTARGETS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_GETPRIVATEDATA_MOREDATA = ( D3D11_MESSAGE_ID_SETPREDICATION_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA = ( D3D11_MESSAGE_ID_GETPRIVATEDATA_MOREDATA + 1 ) , + D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN = ( D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA + 1 ) , + D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS = ( D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN + 1 ) , + D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS = ( D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY = ( D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDSAMPLES = ( D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDUSAGE = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDSAMPLES + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDUSAGE + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDINITIALDATA = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDINITIALDATA + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDMIPLEVELS = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDMIPLEVELS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_NULLDESC = ( D3D11_MESSAGE_ID_CREATEBUFFER_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDCONSTANTBUFFERBINDINGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_LARGEALLOCATION = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDCONSTANTBUFFERBINDINGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_CREATEBUFFER_LARGEALLOCATION + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNSUPPORTEDFORMAT = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDSAMPLES = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_UNSUPPORTEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDUSAGE = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDSAMPLES + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDUSAGE + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDINITIALDATA = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDINITIALDATA + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDMIPLEVELS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDMIPLEVELS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_NULLDESC = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE1D_LARGEALLOCATION = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_CREATETEXTURE1D_LARGEALLOCATION + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNSUPPORTEDFORMAT = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDSAMPLES = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_UNSUPPORTEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDUSAGE = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDSAMPLES + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDUSAGE + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDINITIALDATA = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDINITIALDATA + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDMIPLEVELS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDMIPLEVELS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_NULLDESC = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE2D_LARGEALLOCATION = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_CREATETEXTURE2D_LARGEALLOCATION + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNSUPPORTEDFORMAT = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDSAMPLES = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_UNSUPPORTEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDUSAGE = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDSAMPLES + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDUSAGE + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDCPUACCESSFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDBINDFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDCPUACCESSFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDINITIALDATA = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDBINDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDINITIALDATA + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDMIPLEVELS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDMIPLEVELS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_NULLDESC = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATETEXTURE3D_LARGEALLOCATION = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_CREATETEXTURE3D_LARGEALLOCATION + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_NULLDESC = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT + 1 ) , + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE = ( D3D11_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE = ( D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX + 1 ) , + D3D11_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE + 1 ) , + D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE = ( D3D11_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE = ( D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE = ( D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC + 1 ) , + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDQUERY = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDMISCFLAGS = ( D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDQUERY + 1 ) , + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_UNEXPECTEDMISCFLAG = ( D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDMISCFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_NULLDESC = ( D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_UNEXPECTEDMISCFLAG + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED = ( D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED = ( D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED + 1 ) , + D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_OFFSET_TOO_LARGE = ( D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_OFFSET_TOO_LARGE + 1 ) , + D3D11_MESSAGE_ID_IASETINDEXBUFFER_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_FORMAT_INVALID = ( D3D11_MESSAGE_ID_IASETINDEXBUFFER_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_TOO_LARGE = ( D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_FORMAT_INVALID + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_UNALIGNED = ( D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_TOO_LARGE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_VSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_VSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_VSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_GSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_GSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_SOSETTARGETS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_GSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SOSETTARGETS_OFFSET_UNALIGNED = ( D3D11_MESSAGE_ID_SOSETTARGETS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_SOSETTARGETS_OFFSET_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_PSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_PSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT = ( D3D11_MESSAGE_ID_DEVICE_PSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR = ( D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT + 1 ) , + D3D11_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH = ( D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR + 1 ) , + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH = ( D3D11_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH + 1 ) , + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID = ( D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IAGETVERTEXBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_IAGETVERTEXBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_VSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_VSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_VSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_VSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_GSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_GSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SOGETTARGETS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_GSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_SOGETTARGETS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_PSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_PSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_PSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSGETVIEWPORTS_VIEWPORTS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_PSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSGETSCISSORRECTS_RECTS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_RSGETVIEWPORTS_VIEWPORTS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GENERATEMIPS_RESOURCE_INVALID = ( D3D11_MESSAGE_ID_DEVICE_RSGETSCISSORRECTS_RECTS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSUBRESOURCE = ( D3D11_MESSAGE_ID_DEVICE_GENERATEMIPS_RESOURCE_INVALID + 1 ) , + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESUBRESOURCE = ( D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCEBOX = ( D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCE = ( D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCEBOX + 1 ) , + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSTATE = ( D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCE + 1 ) , + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESTATE = ( D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSTATE + 1 ) , + D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE = ( D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESTATE + 1 ) , + D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE = ( D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE + 1 ) , + D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE = ( D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE + 1 ) , + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE = ( D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE + 1 ) , + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX = ( D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE = ( D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID = ( D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID = ( D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID = ( D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID = ( D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID = ( D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID + 1 ) , + D3D11_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE = ( D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID + 1 ) , + D3D11_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS = ( D3D11_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE + 1 ) , + D3D11_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED = ( D3D11_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN = ( D3D11_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED + 1 ) , + D3D11_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED = ( D3D11_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE = ( D3D11_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED + 1 ) , + D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS = ( D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED = ( D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN = ( D3D11_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED + 1 ) , + D3D11_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D11_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED = ( D3D11_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE = ( D3D11_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED + 1 ) , + D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS = ( D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED = ( D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN = ( D3D11_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED + 1 ) , + D3D11_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D11_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED = ( D3D11_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE = ( D3D11_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED + 1 ) , + D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS = ( D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED = ( D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN = ( D3D11_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED + 1 ) , + D3D11_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D11_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED = ( D3D11_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED = ( D3D11_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED + 1 ) , + D3D11_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED = ( D3D11_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED + 1 ) , + D3D11_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS = ( D3D11_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED + 1 ) , + D3D11_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS + 1 ) , + D3D11_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN = ( D3D11_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE = ( D3D11_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN + 1 ) , + D3D11_MESSAGE_ID_REF_THREADING_MODE = ( D3D11_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE + 1 ) , + D3D11_MESSAGE_ID_REF_UMDRIVER_EXCEPTION = ( D3D11_MESSAGE_ID_REF_THREADING_MODE + 1 ) , + D3D11_MESSAGE_ID_REF_KMDRIVER_EXCEPTION = ( D3D11_MESSAGE_ID_REF_UMDRIVER_EXCEPTION + 1 ) , + D3D11_MESSAGE_ID_REF_HARDWARE_EXCEPTION = ( D3D11_MESSAGE_ID_REF_KMDRIVER_EXCEPTION + 1 ) , + D3D11_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE = ( D3D11_MESSAGE_ID_REF_HARDWARE_EXCEPTION + 1 ) , + D3D11_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER = ( D3D11_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE + 1 ) , + D3D11_MESSAGE_ID_REF_OUT_OF_MEMORY = ( D3D11_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER + 1 ) , + D3D11_MESSAGE_ID_REF_INFO = ( D3D11_MESSAGE_ID_REF_OUT_OF_MEMORY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW = ( D3D11_MESSAGE_ID_REF_INFO + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX = ( D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE = ( D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK = ( D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE = ( D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS = ( D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_INPUTLAYOUT_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_DRAW_INPUTLAYOUT_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL = ( D3D11_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_SHADERRESOURCEVIEW_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VIEW_DIMENSION_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_SHADERRESOURCEVIEW_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VIEW_DIMENSION_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_FORMAT_INVALID = ( D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL = ( D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_FORMAT_INVALID + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_GS_INPUT_PRIMITIVE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_GS_INPUT_PRIMITIVE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_POSITION_NOT_PRESENT = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_DRAW_POSITION_NOT_PRESENT + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_BOUND_RESOURCE_MAPPED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_INVALID_PRIMITIVETOPOLOGY = ( D3D11_MESSAGE_ID_DEVICE_DRAW_BOUND_RESOURCE_MAPPED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_OFFSET_UNALIGNED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_INVALID_PRIMITIVETOPOLOGY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_STRIDE_UNALIGNED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_OFFSET_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_OFFSET_UNALIGNED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_STRIDE_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_OFFSET_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_SO_STRIDE_LARGER_THAN_BUFFER = ( D3D11_MESSAGE_ID_DEVICE_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING = ( D3D11_MESSAGE_ID_DEVICE_DRAW_SO_STRIDE_LARGER_THAN_BUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 = ( D3D11_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING + 1 ) , + D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT = ( D3D11_MESSAGE_ID_DEVICE_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 + 1 ) , + D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT = ( D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT + 1 ) , + D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT = ( D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT + 1 ) , + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT + 1 ) , + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN = ( D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC = ( D3D11_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC + 1 ) , + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW = ( D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY = ( D3D11_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY + 1 ) , + D3D11_MESSAGE_ID_CREATEQUERY_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY + 1 ) , + D3D11_MESSAGE_ID_CREATEPREDICATE_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATEQUERY_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATECOUNTER_OUTOFRANGE_COUNTER = ( D3D11_MESSAGE_ID_CREATEPREDICATE_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATECOUNTER_SIMULTANEOUS_ACTIVE_COUNTERS_EXHAUSTED = ( D3D11_MESSAGE_ID_CREATECOUNTER_OUTOFRANGE_COUNTER + 1 ) , + D3D11_MESSAGE_ID_CREATECOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER = ( D3D11_MESSAGE_ID_CREATECOUNTER_SIMULTANEOUS_ACTIVE_COUNTERS_EXHAUSTED + 1 ) , + D3D11_MESSAGE_ID_CREATECOUNTER_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATECOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER + 1 ) , + D3D11_MESSAGE_ID_CREATECOUNTER_NONEXCLUSIVE_RETURN = ( D3D11_MESSAGE_ID_CREATECOUNTER_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATECOUNTER_NULLDESC = ( D3D11_MESSAGE_ID_CREATECOUNTER_NONEXCLUSIVE_RETURN + 1 ) , + D3D11_MESSAGE_ID_CHECKCOUNTER_OUTOFRANGE_COUNTER = ( D3D11_MESSAGE_ID_CREATECOUNTER_NULLDESC + 1 ) , + D3D11_MESSAGE_ID_CHECKCOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER = ( D3D11_MESSAGE_ID_CHECKCOUNTER_OUTOFRANGE_COUNTER + 1 ) , + D3D11_MESSAGE_ID_SETPREDICATION_INVALID_PREDICATE_STATE = ( D3D11_MESSAGE_ID_CHECKCOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER + 1 ) , + D3D11_MESSAGE_ID_QUERY_BEGIN_UNSUPPORTED = ( D3D11_MESSAGE_ID_SETPREDICATION_INVALID_PREDICATE_STATE + 1 ) , + D3D11_MESSAGE_ID_PREDICATE_BEGIN_DURING_PREDICATION = ( D3D11_MESSAGE_ID_QUERY_BEGIN_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_QUERY_BEGIN_DUPLICATE = ( D3D11_MESSAGE_ID_PREDICATE_BEGIN_DURING_PREDICATION + 1 ) , + D3D11_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS = ( D3D11_MESSAGE_ID_QUERY_BEGIN_DUPLICATE + 1 ) , + D3D11_MESSAGE_ID_PREDICATE_END_DURING_PREDICATION = ( D3D11_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS + 1 ) , + D3D11_MESSAGE_ID_QUERY_END_ABANDONING_PREVIOUS_RESULTS = ( D3D11_MESSAGE_ID_PREDICATE_END_DURING_PREDICATION + 1 ) , + D3D11_MESSAGE_ID_QUERY_END_WITHOUT_BEGIN = ( D3D11_MESSAGE_ID_QUERY_END_ABANDONING_PREVIOUS_RESULTS + 1 ) , + D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_DATASIZE = ( D3D11_MESSAGE_ID_QUERY_END_WITHOUT_BEGIN + 1 ) , + D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_FLAGS = ( D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_DATASIZE + 1 ) , + D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_CALL = ( D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_FLAGS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH = ( D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_CALL + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE = ( D3D11_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE = ( D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT = ( D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT + 1 ) , + D3D11_MESSAGE_ID_D3D10_MESSAGES_END = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_D3D10L9_MESSAGES_START = 0x100000, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_STENCIL_NO_TWO_SIDED = ( D3D11_MESSAGE_ID_D3D10L9_MESSAGES_START + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_DepthBiasClamp_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_STENCIL_NO_TWO_SIDED + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NO_COMPARISON_SUPPORT = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_DepthBiasClamp_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_EXCESSIVE_ANISOTROPY = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NO_COMPARISON_SUPPORT + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_OUT_OF_RANGE = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_EXCESSIVE_ANISOTROPY + 1 ) , + D3D11_MESSAGE_ID_VSSETSAMPLERS_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_OUT_OF_RANGE + 1 ) , + D3D11_MESSAGE_ID_VSSETSAMPLERS_TOO_MANY_SAMPLERS = ( D3D11_MESSAGE_ID_VSSETSAMPLERS_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_PSSETSAMPLERS_TOO_MANY_SAMPLERS = ( D3D11_MESSAGE_ID_VSSETSAMPLERS_TOO_MANY_SAMPLERS + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NO_ARRAYS = ( D3D11_MESSAGE_ID_PSSETSAMPLERS_TOO_MANY_SAMPLERS + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NO_VB_AND_IB_BIND = ( D3D11_MESSAGE_ID_CREATERESOURCE_NO_ARRAYS + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NO_TEXTURE_1D = ( D3D11_MESSAGE_ID_CREATERESOURCE_NO_VB_AND_IB_BIND + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_DIMENSION_OUT_OF_RANGE = ( D3D11_MESSAGE_ID_CREATERESOURCE_NO_TEXTURE_1D + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_SHADER_RESOURCE = ( D3D11_MESSAGE_ID_CREATERESOURCE_DIMENSION_OUT_OF_RANGE + 1 ) , + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_TOO_MANY_RENDER_TARGETS = ( D3D11_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_SHADER_RESOURCE + 1 ) , + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_NO_DIFFERING_BIT_DEPTHS = ( D3D11_MESSAGE_ID_OMSETRENDERTARGETS_TOO_MANY_RENDER_TARGETS + 1 ) , + D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_BAD_BUFFER_INDEX = ( D3D11_MESSAGE_ID_OMSETRENDERTARGETS_NO_DIFFERING_BIT_DEPTHS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_TOO_MANY_VIEWPORTS = ( D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_BAD_BUFFER_INDEX + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_ADJACENCY_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_TOO_MANY_VIEWPORTS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_TOO_MANY_SCISSORS = ( D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_ADJACENCY_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_COPYRESOURCE_ONLY_TEXTURE_2D_WITHIN_GPU_MEMORY = ( D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_TOO_MANY_SCISSORS + 1 ) , + D3D11_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_3D_READBACK = ( D3D11_MESSAGE_ID_COPYRESOURCE_ONLY_TEXTURE_2D_WITHIN_GPU_MEMORY + 1 ) , + D3D11_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_ONLY_READBACK = ( D3D11_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_3D_READBACK + 1 ) , + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_UNSUPPORTED_FORMAT = ( D3D11_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_ONLY_READBACK + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_ALPHA_TO_COVERAGE = ( D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_UNSUPPORTED_FORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_DepthClipEnable_MUST_BE_TRUE = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_ALPHA_TO_COVERAGE + 1 ) , + D3D11_MESSAGE_ID_DRAWINDEXED_STARTINDEXLOCATION_MUST_BE_POSITIVE = ( D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_DepthClipEnable_MUST_BE_TRUE + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_MUST_USE_LOWEST_LOD = ( D3D11_MESSAGE_ID_DRAWINDEXED_STARTINDEXLOCATION_MUST_BE_POSITIVE + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_MINLOD_MUST_NOT_BE_FRACTIONAL = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_MUST_USE_LOWEST_LOD + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_MAXLOD_MUST_BE_FLT_MAX = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_MINLOD_MUST_NOT_BE_FRACTIONAL + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_FIRSTARRAYSLICE_MUST_BE_ZERO = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_MAXLOD_MUST_BE_FLT_MAX + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_CUBES_MUST_HAVE_6_SIDES = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_FIRSTARRAYSLICE_MUST_BE_ZERO + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_RENDER_TARGET = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_CUBES_MUST_HAVE_6_SIDES + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NO_DWORD_INDEX_BUFFER = ( D3D11_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_RENDER_TARGET + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_MSAA_PRECLUDES_SHADER_RESOURCE = ( D3D11_MESSAGE_ID_CREATERESOURCE_NO_DWORD_INDEX_BUFFER + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_PRESENTATION_PRECLUDES_SHADER_RESOURCE = ( D3D11_MESSAGE_ID_CREATERESOURCE_MSAA_PRECLUDES_SHADER_RESOURCE + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_BLEND_ENABLE = ( D3D11_MESSAGE_ID_CREATERESOURCE_PRESENTATION_PRECLUDES_SHADER_RESOURCE + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_WRITE_MASKS = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_BLEND_ENABLE + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NO_STREAM_OUT = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_WRITE_MASKS + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_ONLY_VB_IB_FOR_BUFFERS = ( D3D11_MESSAGE_ID_CREATERESOURCE_NO_STREAM_OUT + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NO_AUTOGEN_FOR_VOLUMES = ( D3D11_MESSAGE_ID_CREATERESOURCE_ONLY_VB_IB_FOR_BUFFERS + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_DXGI_FORMAT_R8G8B8A8_CANNOT_BE_SHARED = ( D3D11_MESSAGE_ID_CREATERESOURCE_NO_AUTOGEN_FOR_VOLUMES + 1 ) , + D3D11_MESSAGE_ID_VSSHADERRESOURCES_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_CREATERESOURCE_DXGI_FORMAT_R8G8B8A8_CANNOT_BE_SHARED + 1 ) , + D3D11_MESSAGE_ID_GEOMETRY_SHADER_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_VSSHADERRESOURCES_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_STREAM_OUT_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_GEOMETRY_SHADER_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_TEXT_FILTER_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_STREAM_OUT_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_SEPARATE_ALPHA_BLEND = ( D3D11_MESSAGE_ID_TEXT_FILTER_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_MRT_BLEND = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_SEPARATE_ALPHA_BLEND + 1 ) , + D3D11_MESSAGE_ID_CREATEBLENDSTATE_OPERATION_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_MRT_BLEND + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NO_MIRRORONCE = ( D3D11_MESSAGE_ID_CREATEBLENDSTATE_OPERATION_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DRAWINSTANCED_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NO_MIRRORONCE + 1 ) , + D3D11_MESSAGE_ID_DRAWINDEXEDINSTANCED_NOT_SUPPORTED_BELOW_9_3 = ( D3D11_MESSAGE_ID_DRAWINSTANCED_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DRAWINDEXED_POINTLIST_UNSUPPORTED = ( D3D11_MESSAGE_ID_DRAWINDEXEDINSTANCED_NOT_SUPPORTED_BELOW_9_3 + 1 ) , + D3D11_MESSAGE_ID_SETBLENDSTATE_SAMPLE_MASK_CANNOT_BE_ZERO = ( D3D11_MESSAGE_ID_DRAWINDEXED_POINTLIST_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_DIMENSION_EXCEEDS_FEATURE_LEVEL_DEFINITION = ( D3D11_MESSAGE_ID_SETBLENDSTATE_SAMPLE_MASK_CANNOT_BE_ZERO + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_ONLY_SINGLE_MIP_LEVEL_DEPTH_STENCIL_SUPPORTED = ( D3D11_MESSAGE_ID_CREATERESOURCE_DIMENSION_EXCEEDS_FEATURE_LEVEL_DEFINITION + 1 ) , + D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_NEGATIVESCISSOR = ( D3D11_MESSAGE_ID_CREATERESOURCE_ONLY_SINGLE_MIP_LEVEL_DEPTH_STENCIL_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_SLOT_ZERO_MUST_BE_D3D10_INPUT_PER_VERTEX_DATA = ( D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_NEGATIVESCISSOR + 1 ) , + D3D11_MESSAGE_ID_CREATERESOURCE_NON_POW_2_MIPMAP = ( D3D11_MESSAGE_ID_SLOT_ZERO_MUST_BE_D3D10_INPUT_PER_VERTEX_DATA + 1 ) , + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_CREATERESOURCE_NON_POW_2_MIPMAP + 1 ) , + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_NO_SRGB_MRT = ( D3D11_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_D3D10L9_MESSAGES_END = ( D3D11_MESSAGE_ID_OMSETRENDERTARGETS_NO_SRGB_MRT + 1 ) , + D3D11_MESSAGE_ID_D3D11_MESSAGES_START = 0x200000, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFLAGS = ( D3D11_MESSAGE_ID_D3D11_MESSAGES_START + 1 ) , + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDCLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDCLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTREAMS = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAMTORASTERIZER = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTREAMS + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTREAMS = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAMTORASTERIZER + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTREAMS + 1 ) , + D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDCLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALID_COMMANDLISTFLAGS = ( D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_SINGLETHREADED = ( D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALID_COMMANDLISTFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_SINGLETHREADED + 1 ) , + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALID_CALL_RETURN = ( D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALID_CALL_RETURN + 1 ) , + D3D11_MESSAGE_ID_FINISHDISPLAYLIST_ONIMMEDIATECONTEXT = ( D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_FINISHDISPLAYLIST_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_FINISHDISPLAYLIST_ONIMMEDIATECONTEXT + 1 ) , + D3D11_MESSAGE_ID_FINISHDISPLAYLIST_INVALID_CALL_RETURN = ( D3D11_MESSAGE_ID_FINISHDISPLAYLIST_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAM = ( D3D11_MESSAGE_ID_FINISHDISPLAYLIST_INVALID_CALL_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDENTRIES = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAM + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTRIDES = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDENTRIES + 1 ) , + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTRIDES = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTRIDES + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSSETSHADERRESOURCES_HAZARD = ( D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTRIDES + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSSETCONSTANTBUFFERS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_HSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D11_MESSAGE_ID_HSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_DEVICE_HSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_HSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_HSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDCALL = ( D3D11_MESSAGE_ID_HSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATEHULLSHADER_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDCALL + 1 ) , + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERBYTECODE = ( D3D11_MESSAGE_ID_CREATEHULLSHADER_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERTYPE = ( D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDCLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERTYPE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_HSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_HSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_HSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_HSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_HSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_HSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_HSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_HSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSSETSHADERRESOURCES_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_HSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSSETCONSTANTBUFFERS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_DSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_DEVICE_DSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_DSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCALL = ( D3D11_MESSAGE_ID_DSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCALL + 1 ) , + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERBYTECODE = ( D3D11_MESSAGE_ID_CREATEDOMAINSHADER_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERTYPE = ( D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERTYPE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_DSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_DSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_DSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_DSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_DSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_DSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_XOR_DS_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEFERRED_CONTEXT_REMOVAL_PROCESS_AT_FAULT = ( D3D11_MESSAGE_ID_DEVICE_DRAW_HS_XOR_DS_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_INVALID_ARG_BUFFER = ( D3D11_MESSAGE_ID_DEFERRED_CONTEXT_REMOVAL_PROCESS_AT_FAULT + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_UNALIGNED = ( D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_INVALID_ARG_BUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDMAPTYPE = ( D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDMAPTYPE + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDFLAGS = ( D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_MAP_ALREADYMAPPED = ( D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_MAP_DEVICEREMOVED_RETURN = ( D3D11_MESSAGE_ID_RESOURCE_MAP_ALREADYMAPPED + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_MAP_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_RESOURCE_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_MAP_WITHOUT_INITIAL_DISCARD = ( D3D11_MESSAGE_ID_RESOURCE_MAP_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_UNMAP_INVALIDSUBRESOURCE = ( D3D11_MESSAGE_ID_RESOURCE_MAP_WITHOUT_INITIAL_DISCARD + 1 ) , + D3D11_MESSAGE_ID_RESOURCE_UNMAP_NOTMAPPED = ( D3D11_MESSAGE_ID_RESOURCE_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_RASTERIZING_CONTROL_POINTS = ( D3D11_MESSAGE_ID_RESOURCE_UNMAP_NOTMAPPED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_DRAW_RASTERIZING_CONTROL_POINTS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_SIGNATURE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_SIGNATURE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_CONTROL_POINT_COUNT_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_TESSELLATOR_DOMAIN_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_CONTROL_POINT_COUNT_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_CREATE_CONTEXT = ( D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_TESSELLATOR_DOMAIN_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_LIVE_CONTEXT = ( D3D11_MESSAGE_ID_CREATE_CONTEXT + 1 ) , + D3D11_MESSAGE_ID_DESTROY_CONTEXT = ( D3D11_MESSAGE_ID_LIVE_CONTEXT + 1 ) , + D3D11_MESSAGE_ID_CREATE_BUFFER = ( D3D11_MESSAGE_ID_DESTROY_CONTEXT + 1 ) , + D3D11_MESSAGE_ID_LIVE_BUFFER = ( D3D11_MESSAGE_ID_CREATE_BUFFER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_BUFFER = ( D3D11_MESSAGE_ID_LIVE_BUFFER + 1 ) , + D3D11_MESSAGE_ID_CREATE_TEXTURE1D = ( D3D11_MESSAGE_ID_DESTROY_BUFFER + 1 ) , + D3D11_MESSAGE_ID_LIVE_TEXTURE1D = ( D3D11_MESSAGE_ID_CREATE_TEXTURE1D + 1 ) , + D3D11_MESSAGE_ID_DESTROY_TEXTURE1D = ( D3D11_MESSAGE_ID_LIVE_TEXTURE1D + 1 ) , + D3D11_MESSAGE_ID_CREATE_TEXTURE2D = ( D3D11_MESSAGE_ID_DESTROY_TEXTURE1D + 1 ) , + D3D11_MESSAGE_ID_LIVE_TEXTURE2D = ( D3D11_MESSAGE_ID_CREATE_TEXTURE2D + 1 ) , + D3D11_MESSAGE_ID_DESTROY_TEXTURE2D = ( D3D11_MESSAGE_ID_LIVE_TEXTURE2D + 1 ) , + D3D11_MESSAGE_ID_CREATE_TEXTURE3D = ( D3D11_MESSAGE_ID_DESTROY_TEXTURE2D + 1 ) , + D3D11_MESSAGE_ID_LIVE_TEXTURE3D = ( D3D11_MESSAGE_ID_CREATE_TEXTURE3D + 1 ) , + D3D11_MESSAGE_ID_DESTROY_TEXTURE3D = ( D3D11_MESSAGE_ID_LIVE_TEXTURE3D + 1 ) , + D3D11_MESSAGE_ID_CREATE_SHADERRESOURCEVIEW = ( D3D11_MESSAGE_ID_DESTROY_TEXTURE3D + 1 ) , + D3D11_MESSAGE_ID_LIVE_SHADERRESOURCEVIEW = ( D3D11_MESSAGE_ID_CREATE_SHADERRESOURCEVIEW + 1 ) , + D3D11_MESSAGE_ID_DESTROY_SHADERRESOURCEVIEW = ( D3D11_MESSAGE_ID_LIVE_SHADERRESOURCEVIEW + 1 ) , + D3D11_MESSAGE_ID_CREATE_RENDERTARGETVIEW = ( D3D11_MESSAGE_ID_DESTROY_SHADERRESOURCEVIEW + 1 ) , + D3D11_MESSAGE_ID_LIVE_RENDERTARGETVIEW = ( D3D11_MESSAGE_ID_CREATE_RENDERTARGETVIEW + 1 ) , + D3D11_MESSAGE_ID_DESTROY_RENDERTARGETVIEW = ( D3D11_MESSAGE_ID_LIVE_RENDERTARGETVIEW + 1 ) , + D3D11_MESSAGE_ID_CREATE_DEPTHSTENCILVIEW = ( D3D11_MESSAGE_ID_DESTROY_RENDERTARGETVIEW + 1 ) , + D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILVIEW = ( D3D11_MESSAGE_ID_CREATE_DEPTHSTENCILVIEW + 1 ) , + D3D11_MESSAGE_ID_DESTROY_DEPTHSTENCILVIEW = ( D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILVIEW + 1 ) , + D3D11_MESSAGE_ID_CREATE_VERTEXSHADER = ( D3D11_MESSAGE_ID_DESTROY_DEPTHSTENCILVIEW + 1 ) , + D3D11_MESSAGE_ID_LIVE_VERTEXSHADER = ( D3D11_MESSAGE_ID_CREATE_VERTEXSHADER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_VERTEXSHADER = ( D3D11_MESSAGE_ID_LIVE_VERTEXSHADER + 1 ) , + D3D11_MESSAGE_ID_CREATE_HULLSHADER = ( D3D11_MESSAGE_ID_DESTROY_VERTEXSHADER + 1 ) , + D3D11_MESSAGE_ID_LIVE_HULLSHADER = ( D3D11_MESSAGE_ID_CREATE_HULLSHADER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_HULLSHADER = ( D3D11_MESSAGE_ID_LIVE_HULLSHADER + 1 ) , + D3D11_MESSAGE_ID_CREATE_DOMAINSHADER = ( D3D11_MESSAGE_ID_DESTROY_HULLSHADER + 1 ) , + D3D11_MESSAGE_ID_LIVE_DOMAINSHADER = ( D3D11_MESSAGE_ID_CREATE_DOMAINSHADER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_DOMAINSHADER = ( D3D11_MESSAGE_ID_LIVE_DOMAINSHADER + 1 ) , + D3D11_MESSAGE_ID_CREATE_GEOMETRYSHADER = ( D3D11_MESSAGE_ID_DESTROY_DOMAINSHADER + 1 ) , + D3D11_MESSAGE_ID_LIVE_GEOMETRYSHADER = ( D3D11_MESSAGE_ID_CREATE_GEOMETRYSHADER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_GEOMETRYSHADER = ( D3D11_MESSAGE_ID_LIVE_GEOMETRYSHADER + 1 ) , + D3D11_MESSAGE_ID_CREATE_PIXELSHADER = ( D3D11_MESSAGE_ID_DESTROY_GEOMETRYSHADER + 1 ) , + D3D11_MESSAGE_ID_LIVE_PIXELSHADER = ( D3D11_MESSAGE_ID_CREATE_PIXELSHADER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_PIXELSHADER = ( D3D11_MESSAGE_ID_LIVE_PIXELSHADER + 1 ) , + D3D11_MESSAGE_ID_CREATE_INPUTLAYOUT = ( D3D11_MESSAGE_ID_DESTROY_PIXELSHADER + 1 ) , + D3D11_MESSAGE_ID_LIVE_INPUTLAYOUT = ( D3D11_MESSAGE_ID_CREATE_INPUTLAYOUT + 1 ) , + D3D11_MESSAGE_ID_DESTROY_INPUTLAYOUT = ( D3D11_MESSAGE_ID_LIVE_INPUTLAYOUT + 1 ) , + D3D11_MESSAGE_ID_CREATE_SAMPLER = ( D3D11_MESSAGE_ID_DESTROY_INPUTLAYOUT + 1 ) , + D3D11_MESSAGE_ID_LIVE_SAMPLER = ( D3D11_MESSAGE_ID_CREATE_SAMPLER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_SAMPLER = ( D3D11_MESSAGE_ID_LIVE_SAMPLER + 1 ) , + D3D11_MESSAGE_ID_CREATE_BLENDSTATE = ( D3D11_MESSAGE_ID_DESTROY_SAMPLER + 1 ) , + D3D11_MESSAGE_ID_LIVE_BLENDSTATE = ( D3D11_MESSAGE_ID_CREATE_BLENDSTATE + 1 ) , + D3D11_MESSAGE_ID_DESTROY_BLENDSTATE = ( D3D11_MESSAGE_ID_LIVE_BLENDSTATE + 1 ) , + D3D11_MESSAGE_ID_CREATE_DEPTHSTENCILSTATE = ( D3D11_MESSAGE_ID_DESTROY_BLENDSTATE + 1 ) , + D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILSTATE = ( D3D11_MESSAGE_ID_CREATE_DEPTHSTENCILSTATE + 1 ) , + D3D11_MESSAGE_ID_DESTROY_DEPTHSTENCILSTATE = ( D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILSTATE + 1 ) , + D3D11_MESSAGE_ID_CREATE_RASTERIZERSTATE = ( D3D11_MESSAGE_ID_DESTROY_DEPTHSTENCILSTATE + 1 ) , + D3D11_MESSAGE_ID_LIVE_RASTERIZERSTATE = ( D3D11_MESSAGE_ID_CREATE_RASTERIZERSTATE + 1 ) , + D3D11_MESSAGE_ID_DESTROY_RASTERIZERSTATE = ( D3D11_MESSAGE_ID_LIVE_RASTERIZERSTATE + 1 ) , + D3D11_MESSAGE_ID_CREATE_QUERY = ( D3D11_MESSAGE_ID_DESTROY_RASTERIZERSTATE + 1 ) , + D3D11_MESSAGE_ID_LIVE_QUERY = ( D3D11_MESSAGE_ID_CREATE_QUERY + 1 ) , + D3D11_MESSAGE_ID_DESTROY_QUERY = ( D3D11_MESSAGE_ID_LIVE_QUERY + 1 ) , + D3D11_MESSAGE_ID_CREATE_PREDICATE = ( D3D11_MESSAGE_ID_DESTROY_QUERY + 1 ) , + D3D11_MESSAGE_ID_LIVE_PREDICATE = ( D3D11_MESSAGE_ID_CREATE_PREDICATE + 1 ) , + D3D11_MESSAGE_ID_DESTROY_PREDICATE = ( D3D11_MESSAGE_ID_LIVE_PREDICATE + 1 ) , + D3D11_MESSAGE_ID_CREATE_COUNTER = ( D3D11_MESSAGE_ID_DESTROY_PREDICATE + 1 ) , + D3D11_MESSAGE_ID_LIVE_COUNTER = ( D3D11_MESSAGE_ID_CREATE_COUNTER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_COUNTER = ( D3D11_MESSAGE_ID_LIVE_COUNTER + 1 ) , + D3D11_MESSAGE_ID_CREATE_COMMANDLIST = ( D3D11_MESSAGE_ID_DESTROY_COUNTER + 1 ) , + D3D11_MESSAGE_ID_LIVE_COMMANDLIST = ( D3D11_MESSAGE_ID_CREATE_COMMANDLIST + 1 ) , + D3D11_MESSAGE_ID_DESTROY_COMMANDLIST = ( D3D11_MESSAGE_ID_LIVE_COMMANDLIST + 1 ) , + D3D11_MESSAGE_ID_CREATE_CLASSINSTANCE = ( D3D11_MESSAGE_ID_DESTROY_COMMANDLIST + 1 ) , + D3D11_MESSAGE_ID_LIVE_CLASSINSTANCE = ( D3D11_MESSAGE_ID_CREATE_CLASSINSTANCE + 1 ) , + D3D11_MESSAGE_ID_DESTROY_CLASSINSTANCE = ( D3D11_MESSAGE_ID_LIVE_CLASSINSTANCE + 1 ) , + D3D11_MESSAGE_ID_CREATE_CLASSLINKAGE = ( D3D11_MESSAGE_ID_DESTROY_CLASSINSTANCE + 1 ) , + D3D11_MESSAGE_ID_LIVE_CLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATE_CLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_DESTROY_CLASSLINKAGE = ( D3D11_MESSAGE_ID_LIVE_CLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_LIVE_DEVICE = ( D3D11_MESSAGE_ID_DESTROY_CLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_LIVE_OBJECT_SUMMARY = ( D3D11_MESSAGE_ID_LIVE_DEVICE + 1 ) , + D3D11_MESSAGE_ID_CREATE_COMPUTESHADER = ( D3D11_MESSAGE_ID_LIVE_OBJECT_SUMMARY + 1 ) , + D3D11_MESSAGE_ID_LIVE_COMPUTESHADER = ( D3D11_MESSAGE_ID_CREATE_COMPUTESHADER + 1 ) , + D3D11_MESSAGE_ID_DESTROY_COMPUTESHADER = ( D3D11_MESSAGE_ID_LIVE_COMPUTESHADER + 1 ) , + D3D11_MESSAGE_ID_CREATE_UNORDEREDACCESSVIEW = ( D3D11_MESSAGE_ID_DESTROY_COMPUTESHADER + 1 ) , + D3D11_MESSAGE_ID_LIVE_UNORDEREDACCESSVIEW = ( D3D11_MESSAGE_ID_CREATE_UNORDEREDACCESSVIEW + 1 ) , + D3D11_MESSAGE_ID_DESTROY_UNORDEREDACCESSVIEW = ( D3D11_MESSAGE_ID_LIVE_UNORDEREDACCESSVIEW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INTERFACES_FEATURELEVEL = ( D3D11_MESSAGE_ID_DESTROY_UNORDEREDACCESSVIEW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INTERFACE_COUNT_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_INTERFACES_FEATURELEVEL + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_INTERFACE_COUNT_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_INDEX = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_TYPE = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_INDEX + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_DATA = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_TYPE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_UNBOUND_INSTANCE_DATA = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_DATA + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INSTANCE_DATA_BINDINGS = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_UNBOUND_INSTANCE_DATA + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATESHADER_CLASSLINKAGE_FULL = ( D3D11_MESSAGE_ID_DEVICE_SETSHADER_INSTANCE_DATA_BINDINGS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_UNRECOGNIZED_FEATURE = ( D3D11_MESSAGE_ID_DEVICE_CREATESHADER_CLASSLINKAGE_FULL + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_MISMATCHED_DATA_SIZE = ( D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_UNRECOGNIZED_FEATURE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_MISMATCHED_DATA_SIZE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_HAZARD = ( D3D11_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D11_MESSAGE_ID_CSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_CSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_CSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCALL = ( D3D11_MESSAGE_ID_CSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_OUTOFMEMORY = ( D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCALL + 1 ) , + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERBYTECODE = ( D3D11_MESSAGE_ID_CREATECOMPUTESHADER_OUTOFMEMORY + 1 ) , + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERTYPE = ( D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCLASSLINKAGE = ( D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERTYPE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D11_MESSAGE_ID_CSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D11_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_CSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_CSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_CSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_CSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_CSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDSTRUCTURESTRIDE = ( D3D11_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFLAGS = ( D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDSTRUCTURESTRIDE + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDRESOURCE = ( D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDESC = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDRESOURCE + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFORMAT = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDESC + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDIMENSIONS = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFORMAT + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_UNRECOGNIZEDFORMAT = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDIMENSIONS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_HAZARD = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_OVERLAPPING_OLD_SLOTS = ( D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_NO_OP = ( D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_OVERLAPPING_OLD_SLOTS + 1 ) , + D3D11_MESSAGE_ID_CSSETUNORDEREDACCESSVIEWS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_NO_OP + 1 ) , + D3D11_MESSAGE_ID_PSSETUNORDEREDACCESSVIEWS_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_CSSETUNORDEREDACCESSVIEWS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDARG_RETURN = ( D3D11_MESSAGE_ID_PSSETUNORDEREDACCESSVIEWS_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_OUTOFMEMORY_RETURN = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDARG_RETURN + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_HAZARD = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_DENORMFLUSH = ( D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_HAZARD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSS_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_DENORMFLUSH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSGETUNORDEREDACCESSS_VIEWS_EMPTY = ( D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSS_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFLAGS = ( D3D11_MESSAGE_ID_DEVICE_CSGETUNORDEREDACCESSS_VIEWS_EMPTY + 1 ) , + D3D11_MESSAGE_ID_CREATESHADERRESESOURCEVIEW_TOOMANYOBJECTS = ( D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFLAGS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_INVALID_ARG_BUFFER = ( D3D11_MESSAGE_ID_CREATESHADERRESESOURCEVIEW_TOOMANYOBJECTS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_UNALIGNED = ( D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_INVALID_ARG_BUFFER + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_UNALIGNED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDCONTEXT = ( D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDRESOURCE = ( D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDCONTEXT + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDMINLOD = ( D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDRESOURCE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GETRESOURCEMINLOD_INVALIDCONTEXT = ( D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDMINLOD + 1 ) , + D3D11_MESSAGE_ID_DEVICE_GETRESOURCEMINLOD_INVALIDRESOURCE = ( D3D11_MESSAGE_ID_DEVICE_GETRESOURCEMINLOD_INVALIDCONTEXT + 1 ) , + D3D11_MESSAGE_ID_OMSETDEPTHSTENCIL_UNBINDDELETINGOBJECT = ( D3D11_MESSAGE_ID_DEVICE_GETRESOURCEMINLOD_INVALIDRESOURCE + 1 ) , + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DEPTH_READONLY = ( D3D11_MESSAGE_ID_OMSETDEPTHSTENCIL_UNBINDDELETINGOBJECT + 1 ) , + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_STENCIL_READONLY = ( D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DEPTH_READONLY + 1 ) , + D3D11_MESSAGE_ID_CHECKFEATURESUPPORT_FORMAT_DEPRECATED = ( D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_STENCIL_READONLY + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RETURN_TYPE_MISMATCH = ( D3D11_MESSAGE_ID_CHECKFEATURESUPPORT_FORMAT_DEPRECATED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RETURN_TYPE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DRAW_UNORDEREDACCESSVIEW_RENDERTARGETVIEW_OVERLAP = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_DIMENSION_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DRAW_UNORDEREDACCESSVIEW_RENDERTARGETVIEW_OVERLAP + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_APPEND_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_DIMENSION_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMICS_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_APPEND_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_STRUCTURE_STRIDE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMICS_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_BUFFER_TYPE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_STRUCTURE_STRIDE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RAW_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_BUFFER_TYPE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_LD_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RAW_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_STORE_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_LD_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_ADD_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_STORE_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_BITWISE_OPS_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_ADD_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_CMPSTORE_CMPEXCHANGE_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_BITWISE_OPS_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_EXCHANGE_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_CMPSTORE_CMPEXCHANGE_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_SIGNED_MINMAX_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_EXCHANGE_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_UNSIGNED_MINMAX_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_SIGNED_MINMAX_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCH_BOUND_RESOURCE_MAPPED = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_UNSIGNED_MINMAX_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_OVERFLOW = ( D3D11_MESSAGE_ID_DEVICE_DISPATCH_BOUND_RESOURCE_MAPPED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_ZERO = ( D3D11_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_OVERFLOW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_STRUCTURE_STRIDE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_ZERO + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_BUFFER_TYPE_MISMATCH = ( D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_STRUCTURE_STRIDE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_RAW_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_BUFFER_TYPE_MISMATCH + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCH_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_RAW_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_UNSUPPORTED = ( D3D11_MESSAGE_ID_DEVICE_DISPATCH_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDOFFSET = ( D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_LARGEOFFSET = ( D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDOFFSET + 1 ) , + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDDESTINATIONSTATE = ( D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_LARGEOFFSET + 1 ) , + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDSOURCESTATE = ( D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDDESTINATIONSTATE + 1 ) , + D3D11_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_NOT_SUPPORTED = ( D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDSOURCESTATE + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_INVALIDVIEW = ( D3D11_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_NOT_SUPPORTED + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_INVALIDOFFSET = ( D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_INVALIDVIEW + 1 ) , + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_TOOMANYVIEWS = ( D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_INVALIDOFFSET + 1 ) , + D3D11_MESSAGE_ID_CLEARUNORDEREDACCESSVIEWFLOAT_INVALIDFORMAT = ( D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_TOOMANYVIEWS + 1 ) , + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_COUNTER_UNSUPPORTED = ( D3D11_MESSAGE_ID_CLEARUNORDEREDACCESSVIEWFLOAT_INVALIDFORMAT + 1 ) , + D3D11_MESSAGE_ID_REF_WARNING = ( D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_COUNTER_UNSUPPORTED + 1 ) , + D3D11_MESSAGE_ID_D3D11_MESSAGES_END = ( D3D11_MESSAGE_ID_REF_WARNING + 1 ) + } D3D11_MESSAGE_ID; + +typedef struct D3D11_MESSAGE + { + D3D11_MESSAGE_CATEGORY Category; + D3D11_MESSAGE_SEVERITY Severity; + D3D11_MESSAGE_ID ID; + const char *pDescription; + SIZE_T DescriptionByteLength; + } D3D11_MESSAGE; + +typedef struct D3D11_INFO_QUEUE_FILTER_DESC + { + UINT NumCategories; + D3D11_MESSAGE_CATEGORY *pCategoryList; + UINT NumSeverities; + D3D11_MESSAGE_SEVERITY *pSeverityList; + UINT NumIDs; + D3D11_MESSAGE_ID *pIDList; + } D3D11_INFO_QUEUE_FILTER_DESC; + +typedef struct D3D11_INFO_QUEUE_FILTER + { + D3D11_INFO_QUEUE_FILTER_DESC AllowList; + D3D11_INFO_QUEUE_FILTER_DESC DenyList; + } D3D11_INFO_QUEUE_FILTER; + +#define D3D11_INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT 1024 + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11sdklayers_0000_0002_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11sdklayers_0000_0002_v0_0_s_ifspec; + +#ifndef __ID3D11InfoQueue_INTERFACE_DEFINED__ +#define __ID3D11InfoQueue_INTERFACE_DEFINED__ + +/* interface ID3D11InfoQueue */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D11InfoQueue; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") + ID3D11InfoQueue : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetMessageCountLimit( + /* [annotation] */ + __in UINT64 MessageCountLimit) = 0; + + virtual void STDMETHODCALLTYPE ClearStoredMessages( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetMessage( + /* [annotation] */ + __in UINT64 MessageIndex, + /* [annotation] */ + __out_bcount_opt(*pMessageByteLength) D3D11_MESSAGE *pMessage, + /* [annotation] */ + __inout SIZE_T *pMessageByteLength) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesAllowedByStorageFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDeniedByStorageFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessages( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessagesAllowedByRetrievalFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDiscardedByMessageCountLimit( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetMessageCountLimit( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddStorageFilterEntries( + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStorageFilter( + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D11_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength) = 0; + + virtual void STDMETHODCALLTYPE ClearStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushEmptyStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushCopyOfStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushStorageFilter( + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual void STDMETHODCALLTYPE PopStorageFilter( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetStorageFilterStackSize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddRetrievalFilterEntries( + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRetrievalFilter( + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D11_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength) = 0; + + virtual void STDMETHODCALLTYPE ClearRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushEmptyRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushCopyOfRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushRetrievalFilter( + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual void STDMETHODCALLTYPE PopRetrievalFilter( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetRetrievalFilterStackSize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddMessage( + /* [annotation] */ + __in D3D11_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in D3D11_MESSAGE_ID ID, + /* [annotation] */ + __in LPCSTR pDescription) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddApplicationMessage( + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in LPCSTR pDescription) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnCategory( + /* [annotation] */ + __in D3D11_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in BOOL bEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnSeverity( + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in BOOL bEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnID( + /* [annotation] */ + __in D3D11_MESSAGE_ID ID, + /* [annotation] */ + __in BOOL bEnable) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnCategory( + /* [annotation] */ + __in D3D11_MESSAGE_CATEGORY Category) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnSeverity( + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnID( + /* [annotation] */ + __in D3D11_MESSAGE_ID ID) = 0; + + virtual void STDMETHODCALLTYPE SetMuteDebugOutput( + /* [annotation] */ + __in BOOL bMute) = 0; + + virtual BOOL STDMETHODCALLTYPE GetMuteDebugOutput( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D11InfoQueueVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D11InfoQueue * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D11InfoQueue * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *SetMessageCountLimit )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in UINT64 MessageCountLimit); + + void ( STDMETHODCALLTYPE *ClearStoredMessages )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *GetMessage )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in UINT64 MessageIndex, + /* [annotation] */ + __out_bcount_opt(*pMessageByteLength) D3D11_MESSAGE *pMessage, + /* [annotation] */ + __inout SIZE_T *pMessageByteLength); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesAllowedByStorageFilter )( + ID3D11InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesDeniedByStorageFilter )( + ID3D11InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumStoredMessages )( + ID3D11InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumStoredMessagesAllowedByRetrievalFilter )( + ID3D11InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesDiscardedByMessageCountLimit )( + ID3D11InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetMessageCountLimit )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddStorageFilterEntries )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter); + + HRESULT ( STDMETHODCALLTYPE *GetStorageFilter )( + ID3D11InfoQueue * This, + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D11_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength); + + void ( STDMETHODCALLTYPE *ClearStorageFilter )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushEmptyStorageFilter )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushCopyOfStorageFilter )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushStorageFilter )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter); + + void ( STDMETHODCALLTYPE *PopStorageFilter )( + ID3D11InfoQueue * This); + + UINT ( STDMETHODCALLTYPE *GetStorageFilterStackSize )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddRetrievalFilterEntries )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter); + + HRESULT ( STDMETHODCALLTYPE *GetRetrievalFilter )( + ID3D11InfoQueue * This, + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D11_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength); + + void ( STDMETHODCALLTYPE *ClearRetrievalFilter )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushEmptyRetrievalFilter )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushCopyOfRetrievalFilter )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushRetrievalFilter )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_INFO_QUEUE_FILTER *pFilter); + + void ( STDMETHODCALLTYPE *PopRetrievalFilter )( + ID3D11InfoQueue * This); + + UINT ( STDMETHODCALLTYPE *GetRetrievalFilterStackSize )( + ID3D11InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddMessage )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in D3D11_MESSAGE_ID ID, + /* [annotation] */ + __in LPCSTR pDescription); + + HRESULT ( STDMETHODCALLTYPE *AddApplicationMessage )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in LPCSTR pDescription); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnCategory )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in BOOL bEnable); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnSeverity )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in BOOL bEnable); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnID )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_ID ID, + /* [annotation] */ + __in BOOL bEnable); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnCategory )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_CATEGORY Category); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnSeverity )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_SEVERITY Severity); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnID )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in D3D11_MESSAGE_ID ID); + + void ( STDMETHODCALLTYPE *SetMuteDebugOutput )( + ID3D11InfoQueue * This, + /* [annotation] */ + __in BOOL bMute); + + BOOL ( STDMETHODCALLTYPE *GetMuteDebugOutput )( + ID3D11InfoQueue * This); + + END_INTERFACE + } ID3D11InfoQueueVtbl; + + interface ID3D11InfoQueue + { + CONST_VTBL struct ID3D11InfoQueueVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D11InfoQueue_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D11InfoQueue_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D11InfoQueue_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D11InfoQueue_SetMessageCountLimit(This,MessageCountLimit) \ + ( (This)->lpVtbl -> SetMessageCountLimit(This,MessageCountLimit) ) + +#define ID3D11InfoQueue_ClearStoredMessages(This) \ + ( (This)->lpVtbl -> ClearStoredMessages(This) ) + +#define ID3D11InfoQueue_GetMessage(This,MessageIndex,pMessage,pMessageByteLength) \ + ( (This)->lpVtbl -> GetMessage(This,MessageIndex,pMessage,pMessageByteLength) ) + +#define ID3D11InfoQueue_GetNumMessagesAllowedByStorageFilter(This) \ + ( (This)->lpVtbl -> GetNumMessagesAllowedByStorageFilter(This) ) + +#define ID3D11InfoQueue_GetNumMessagesDeniedByStorageFilter(This) \ + ( (This)->lpVtbl -> GetNumMessagesDeniedByStorageFilter(This) ) + +#define ID3D11InfoQueue_GetNumStoredMessages(This) \ + ( (This)->lpVtbl -> GetNumStoredMessages(This) ) + +#define ID3D11InfoQueue_GetNumStoredMessagesAllowedByRetrievalFilter(This) \ + ( (This)->lpVtbl -> GetNumStoredMessagesAllowedByRetrievalFilter(This) ) + +#define ID3D11InfoQueue_GetNumMessagesDiscardedByMessageCountLimit(This) \ + ( (This)->lpVtbl -> GetNumMessagesDiscardedByMessageCountLimit(This) ) + +#define ID3D11InfoQueue_GetMessageCountLimit(This) \ + ( (This)->lpVtbl -> GetMessageCountLimit(This) ) + +#define ID3D11InfoQueue_AddStorageFilterEntries(This,pFilter) \ + ( (This)->lpVtbl -> AddStorageFilterEntries(This,pFilter) ) + +#define ID3D11InfoQueue_GetStorageFilter(This,pFilter,pFilterByteLength) \ + ( (This)->lpVtbl -> GetStorageFilter(This,pFilter,pFilterByteLength) ) + +#define ID3D11InfoQueue_ClearStorageFilter(This) \ + ( (This)->lpVtbl -> ClearStorageFilter(This) ) + +#define ID3D11InfoQueue_PushEmptyStorageFilter(This) \ + ( (This)->lpVtbl -> PushEmptyStorageFilter(This) ) + +#define ID3D11InfoQueue_PushCopyOfStorageFilter(This) \ + ( (This)->lpVtbl -> PushCopyOfStorageFilter(This) ) + +#define ID3D11InfoQueue_PushStorageFilter(This,pFilter) \ + ( (This)->lpVtbl -> PushStorageFilter(This,pFilter) ) + +#define ID3D11InfoQueue_PopStorageFilter(This) \ + ( (This)->lpVtbl -> PopStorageFilter(This) ) + +#define ID3D11InfoQueue_GetStorageFilterStackSize(This) \ + ( (This)->lpVtbl -> GetStorageFilterStackSize(This) ) + +#define ID3D11InfoQueue_AddRetrievalFilterEntries(This,pFilter) \ + ( (This)->lpVtbl -> AddRetrievalFilterEntries(This,pFilter) ) + +#define ID3D11InfoQueue_GetRetrievalFilter(This,pFilter,pFilterByteLength) \ + ( (This)->lpVtbl -> GetRetrievalFilter(This,pFilter,pFilterByteLength) ) + +#define ID3D11InfoQueue_ClearRetrievalFilter(This) \ + ( (This)->lpVtbl -> ClearRetrievalFilter(This) ) + +#define ID3D11InfoQueue_PushEmptyRetrievalFilter(This) \ + ( (This)->lpVtbl -> PushEmptyRetrievalFilter(This) ) + +#define ID3D11InfoQueue_PushCopyOfRetrievalFilter(This) \ + ( (This)->lpVtbl -> PushCopyOfRetrievalFilter(This) ) + +#define ID3D11InfoQueue_PushRetrievalFilter(This,pFilter) \ + ( (This)->lpVtbl -> PushRetrievalFilter(This,pFilter) ) + +#define ID3D11InfoQueue_PopRetrievalFilter(This) \ + ( (This)->lpVtbl -> PopRetrievalFilter(This) ) + +#define ID3D11InfoQueue_GetRetrievalFilterStackSize(This) \ + ( (This)->lpVtbl -> GetRetrievalFilterStackSize(This) ) + +#define ID3D11InfoQueue_AddMessage(This,Category,Severity,ID,pDescription) \ + ( (This)->lpVtbl -> AddMessage(This,Category,Severity,ID,pDescription) ) + +#define ID3D11InfoQueue_AddApplicationMessage(This,Severity,pDescription) \ + ( (This)->lpVtbl -> AddApplicationMessage(This,Severity,pDescription) ) + +#define ID3D11InfoQueue_SetBreakOnCategory(This,Category,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnCategory(This,Category,bEnable) ) + +#define ID3D11InfoQueue_SetBreakOnSeverity(This,Severity,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnSeverity(This,Severity,bEnable) ) + +#define ID3D11InfoQueue_SetBreakOnID(This,ID,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnID(This,ID,bEnable) ) + +#define ID3D11InfoQueue_GetBreakOnCategory(This,Category) \ + ( (This)->lpVtbl -> GetBreakOnCategory(This,Category) ) + +#define ID3D11InfoQueue_GetBreakOnSeverity(This,Severity) \ + ( (This)->lpVtbl -> GetBreakOnSeverity(This,Severity) ) + +#define ID3D11InfoQueue_GetBreakOnID(This,ID) \ + ( (This)->lpVtbl -> GetBreakOnID(This,ID) ) + +#define ID3D11InfoQueue_SetMuteDebugOutput(This,bMute) \ + ( (This)->lpVtbl -> SetMuteDebugOutput(This,bMute) ) + +#define ID3D11InfoQueue_GetMuteDebugOutput(This) \ + ( (This)->lpVtbl -> GetMuteDebugOutput(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D11InfoQueue_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d11sdklayers_0000_0003 */ +/* [local] */ + +#define D3D11_REGKEY_PATH __TEXT("Software\\Microsoft\\Direct3D") +#define D3D11_MUTE_DEBUG_OUTPUT __TEXT("MuteDebugOutput") +#define D3D11_ENABLE_BREAK_ON_MESSAGE __TEXT("EnableBreakOnMessage") +#define D3D11_INFOQUEUE_STORAGE_FILTER_OVERRIDE __TEXT("InfoQueueStorageFilterOverride") +#define D3D11_MUTE_CATEGORY __TEXT("Mute_CATEGORY_%s") +#define D3D11_MUTE_SEVERITY __TEXT("Mute_SEVERITY_%s") +#define D3D11_MUTE_ID_STRING __TEXT("Mute_ID_%s") +#define D3D11_MUTE_ID_DECIMAL __TEXT("Mute_ID_%d") +#define D3D11_UNMUTE_SEVERITY_INFO __TEXT("Unmute_SEVERITY_INFO") +#define D3D11_BREAKON_CATEGORY __TEXT("BreakOn_CATEGORY_%s") +#define D3D11_BREAKON_SEVERITY __TEXT("BreakOn_SEVERITY_%s") +#define D3D11_BREAKON_ID_STRING __TEXT("BreakOn_ID_%s") +#define D3D11_BREAKON_ID_DECIMAL __TEXT("BreakOn_ID_%d") +#define D3D11_APPSIZE_STRING __TEXT("Size") +#define D3D11_APPNAME_STRING __TEXT("Name") +DEFINE_GUID(IID_ID3D11Debug,0x79cf2233,0x7536,0x4948,0x9d,0x36,0x1e,0x46,0x92,0xdc,0x57,0x60); +DEFINE_GUID(IID_ID3D11SwitchToRef,0x1ef337e3,0x58e7,0x4f83,0xa6,0x92,0xdb,0x22,0x1f,0x5e,0xd4,0x7e); +DEFINE_GUID(IID_ID3D11InfoQueue,0x6543dbb6,0x1b48,0x42f5,0xab,0x82,0xe9,0x7e,0xc7,0x43,0x26,0xf6); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d11sdklayers_0000_0003_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d11sdklayers_0000_0003_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/dxsdk/Include/D3D11Shader.h b/dxsdk/Include/D3D11Shader.h new file mode 100644 index 0000000..f91897c --- /dev/null +++ b/dxsdk/Include/D3D11Shader.h @@ -0,0 +1,296 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3D11Shader.h +// Content: D3D11 Shader Types and APIs +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3D11SHADER_H__ +#define __D3D11SHADER_H__ + +#include "d3dcommon.h" + + +typedef enum D3D11_SHADER_VERSION_TYPE +{ + D3D11_SHVER_PIXEL_SHADER = 0, + D3D11_SHVER_VERTEX_SHADER = 1, + D3D11_SHVER_GEOMETRY_SHADER = 2, + + // D3D11 Shaders + D3D11_SHVER_HULL_SHADER = 3, + D3D11_SHVER_DOMAIN_SHADER = 4, + D3D11_SHVER_COMPUTE_SHADER = 5, +} D3D11_SHADER_VERSION_TYPE; + +#define D3D11_SHVER_GET_TYPE(_Version) \ + (((_Version) >> 16) & 0xffff) +#define D3D11_SHVER_GET_MAJOR(_Version) \ + (((_Version) >> 4) & 0xf) +#define D3D11_SHVER_GET_MINOR(_Version) \ + (((_Version) >> 0) & 0xf) + +typedef D3D_RESOURCE_RETURN_TYPE D3D11_RESOURCE_RETURN_TYPE; + +typedef D3D_CBUFFER_TYPE D3D11_CBUFFER_TYPE; + + +typedef struct _D3D11_SIGNATURE_PARAMETER_DESC +{ + LPCSTR SemanticName; // Name of the semantic + UINT SemanticIndex; // Index of the semantic + UINT Register; // Number of member variables + D3D_NAME SystemValueType;// A predefined system value, or D3D_NAME_UNDEFINED if not applicable + D3D_REGISTER_COMPONENT_TYPE ComponentType;// Scalar type (e.g. uint, float, etc.) + BYTE Mask; // Mask to indicate which components of the register + // are used (combination of D3D10_COMPONENT_MASK values) + BYTE ReadWriteMask; // Mask to indicate whether a given component is + // never written (if this is an output signature) or + // always read (if this is an input signature). + // (combination of D3D10_COMPONENT_MASK values) + UINT Stream; // Stream index +} D3D11_SIGNATURE_PARAMETER_DESC; + +typedef struct _D3D11_SHADER_BUFFER_DESC +{ + LPCSTR Name; // Name of the constant buffer + D3D_CBUFFER_TYPE Type; // Indicates type of buffer content + UINT Variables; // Number of member variables + UINT Size; // Size of CB (in bytes) + UINT uFlags; // Buffer description flags +} D3D11_SHADER_BUFFER_DESC; + +typedef struct _D3D11_SHADER_VARIABLE_DESC +{ + LPCSTR Name; // Name of the variable + UINT StartOffset; // Offset in constant buffer's backing store + UINT Size; // Size of variable (in bytes) + UINT uFlags; // Variable flags + LPVOID DefaultValue; // Raw pointer to default value + UINT StartTexture; // First texture index (or -1 if no textures used) + UINT TextureSize; // Number of texture slots possibly used. + UINT StartSampler; // First sampler index (or -1 if no textures used) + UINT SamplerSize; // Number of sampler slots possibly used. +} D3D11_SHADER_VARIABLE_DESC; + +typedef struct _D3D11_SHADER_TYPE_DESC +{ + D3D_SHADER_VARIABLE_CLASS Class; // Variable class (e.g. object, matrix, etc.) + D3D_SHADER_VARIABLE_TYPE Type; // Variable type (e.g. float, sampler, etc.) + UINT Rows; // Number of rows (for matrices, 1 for other numeric, 0 if not applicable) + UINT Columns; // Number of columns (for vectors & matrices, 1 for other numeric, 0 if not applicable) + UINT Elements; // Number of elements (0 if not an array) + UINT Members; // Number of members (0 if not a structure) + UINT Offset; // Offset from the start of structure (0 if not a structure member) + LPCSTR Name; // Name of type, can be NULL +} D3D11_SHADER_TYPE_DESC; + +typedef D3D_TESSELLATOR_DOMAIN D3D11_TESSELLATOR_DOMAIN; + +typedef D3D_TESSELLATOR_PARTITIONING D3D11_TESSELLATOR_PARTITIONING; + +typedef D3D_TESSELLATOR_OUTPUT_PRIMITIVE D3D11_TESSELLATOR_OUTPUT_PRIMITIVE; + +typedef struct _D3D11_SHADER_DESC +{ + UINT Version; // Shader version + LPCSTR Creator; // Creator string + UINT Flags; // Shader compilation/parse flags + + UINT ConstantBuffers; // Number of constant buffers + UINT BoundResources; // Number of bound resources + UINT InputParameters; // Number of parameters in the input signature + UINT OutputParameters; // Number of parameters in the output signature + + UINT InstructionCount; // Number of emitted instructions + UINT TempRegisterCount; // Number of temporary registers used + UINT TempArrayCount; // Number of temporary arrays used + UINT DefCount; // Number of constant defines + UINT DclCount; // Number of declarations (input + output) + UINT TextureNormalInstructions; // Number of non-categorized texture instructions + UINT TextureLoadInstructions; // Number of texture load instructions + UINT TextureCompInstructions; // Number of texture comparison instructions + UINT TextureBiasInstructions; // Number of texture bias instructions + UINT TextureGradientInstructions; // Number of texture gradient instructions + UINT FloatInstructionCount; // Number of floating point arithmetic instructions used + UINT IntInstructionCount; // Number of signed integer arithmetic instructions used + UINT UintInstructionCount; // Number of unsigned integer arithmetic instructions used + UINT StaticFlowControlCount; // Number of static flow control instructions used + UINT DynamicFlowControlCount; // Number of dynamic flow control instructions used + UINT MacroInstructionCount; // Number of macro instructions used + UINT ArrayInstructionCount; // Number of array instructions used + UINT CutInstructionCount; // Number of cut instructions used + UINT EmitInstructionCount; // Number of emit instructions used + D3D_PRIMITIVE_TOPOLOGY GSOutputTopology; // Geometry shader output topology + UINT GSMaxOutputVertexCount; // Geometry shader maximum output vertex count + D3D_PRIMITIVE InputPrimitive; // GS/HS input primitive + UINT PatchConstantParameters; // Number of parameters in the patch constant signature + UINT cGSInstanceCount; // Number of Geometry shader instances + UINT cControlPoints; // Number of control points in the HS->DS stage + D3D_TESSELLATOR_OUTPUT_PRIMITIVE HSOutputPrimitive; // Primitive output by the tessellator + D3D_TESSELLATOR_PARTITIONING HSPartitioning; // Partitioning mode of the tessellator + D3D_TESSELLATOR_DOMAIN TessellatorDomain; // Domain of the tessellator (quad, tri, isoline) + // instruction counts + UINT cBarrierInstructions; // Number of barrier instructions in a compute shader + UINT cInterlockedInstructions; // Number of interlocked instructions + UINT cTextureStoreInstructions; // Number of texture writes +} D3D11_SHADER_DESC; + +typedef struct _D3D11_SHADER_INPUT_BIND_DESC +{ + LPCSTR Name; // Name of the resource + D3D_SHADER_INPUT_TYPE Type; // Type of resource (e.g. texture, cbuffer, etc.) + UINT BindPoint; // Starting bind point + UINT BindCount; // Number of contiguous bind points (for arrays) + + UINT uFlags; // Input binding flags + D3D_RESOURCE_RETURN_TYPE ReturnType; // Return type (if texture) + D3D_SRV_DIMENSION Dimension; // Dimension (if texture) + UINT NumSamples; // Number of samples (0 if not MS texture) +} D3D11_SHADER_INPUT_BIND_DESC; + + +////////////////////////////////////////////////////////////////////////////// +// Interfaces //////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3D11ShaderReflectionType ID3D11ShaderReflectionType; +typedef interface ID3D11ShaderReflectionType *LPD3D11SHADERREFLECTIONTYPE; + +typedef interface ID3D11ShaderReflectionVariable ID3D11ShaderReflectionVariable; +typedef interface ID3D11ShaderReflectionVariable *LPD3D11SHADERREFLECTIONVARIABLE; + +typedef interface ID3D11ShaderReflectionConstantBuffer ID3D11ShaderReflectionConstantBuffer; +typedef interface ID3D11ShaderReflectionConstantBuffer *LPD3D11SHADERREFLECTIONCONSTANTBUFFER; + +typedef interface ID3D11ShaderReflection ID3D11ShaderReflection; +typedef interface ID3D11ShaderReflection *LPD3D11SHADERREFLECTION; + +// {6E6FFA6A-9BAE-4613-A51E-91652D508C21} +DEFINE_GUID(IID_ID3D11ShaderReflectionType, +0x6e6ffa6a, 0x9bae, 0x4613, 0xa5, 0x1e, 0x91, 0x65, 0x2d, 0x50, 0x8c, 0x21); + +#undef INTERFACE +#define INTERFACE ID3D11ShaderReflectionType + +DECLARE_INTERFACE(ID3D11ShaderReflectionType) +{ + STDMETHOD(GetDesc)(THIS_ __out D3D11_SHADER_TYPE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D11ShaderReflectionType*, GetMemberTypeByIndex)(THIS_ __in UINT Index) PURE; + STDMETHOD_(ID3D11ShaderReflectionType*, GetMemberTypeByName)(THIS_ __in LPCSTR Name) PURE; + STDMETHOD_(LPCSTR, GetMemberTypeName)(THIS_ __in UINT Index) PURE; + + STDMETHOD(IsEqual)(THIS_ __in ID3D11ShaderReflectionType* pType) PURE; + STDMETHOD_(ID3D11ShaderReflectionType*, GetSubType)(THIS) PURE; + STDMETHOD_(ID3D11ShaderReflectionType*, GetBaseClass)(THIS) PURE; + STDMETHOD_(UINT, GetNumInterfaces)(THIS) PURE; + STDMETHOD_(ID3D11ShaderReflectionType*, GetInterfaceByIndex)(THIS_ __in UINT uIndex) PURE; + STDMETHOD(IsOfType)(THIS_ __in ID3D11ShaderReflectionType* pType) PURE; + STDMETHOD(ImplementsInterface)(THIS_ __in ID3D11ShaderReflectionType* pBase) PURE; +}; + +// {51F23923-F3E5-4BD1-91CB-606177D8DB4C} +DEFINE_GUID(IID_ID3D11ShaderReflectionVariable, +0x51f23923, 0xf3e5, 0x4bd1, 0x91, 0xcb, 0x60, 0x61, 0x77, 0xd8, 0xdb, 0x4c); + +#undef INTERFACE +#define INTERFACE ID3D11ShaderReflectionVariable + +DECLARE_INTERFACE(ID3D11ShaderReflectionVariable) +{ + STDMETHOD(GetDesc)(THIS_ __out D3D11_SHADER_VARIABLE_DESC *pDesc) PURE; + + STDMETHOD_(ID3D11ShaderReflectionType*, GetType)(THIS) PURE; + STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetBuffer)(THIS) PURE; + + STDMETHOD_(UINT, GetInterfaceSlot)(THIS_ __in UINT uArrayIndex) PURE; +}; + +// {EB62D63D-93DD-4318-8AE8-C6F83AD371B8} +DEFINE_GUID(IID_ID3D11ShaderReflectionConstantBuffer, +0xeb62d63d, 0x93dd, 0x4318, 0x8a, 0xe8, 0xc6, 0xf8, 0x3a, 0xd3, 0x71, 0xb8); + +#undef INTERFACE +#define INTERFACE ID3D11ShaderReflectionConstantBuffer + +DECLARE_INTERFACE(ID3D11ShaderReflectionConstantBuffer) +{ + STDMETHOD(GetDesc)(THIS_ D3D11_SHADER_BUFFER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D11ShaderReflectionVariable*, GetVariableByIndex)(THIS_ __in UINT Index) PURE; + STDMETHOD_(ID3D11ShaderReflectionVariable*, GetVariableByName)(THIS_ __in LPCSTR Name) PURE; +}; + +// The ID3D11ShaderReflection IID may change from SDK version to SDK version +// if the reflection API changes. This prevents new code with the new API +// from working with an old binary. Recompiling with the new header +// will pick up the new IID. + +// 0a233719-3960-4578-9d7c-203b8b1d9cc1 +DEFINE_GUID(IID_ID3D11ShaderReflection, +0x0a233719, 0x3960, 0x4578, 0x9d, 0x7c, 0x20, 0x3b, 0x8b, 0x1d, 0x9c, 0xc1); + +#undef INTERFACE +#define INTERFACE ID3D11ShaderReflection + +DECLARE_INTERFACE_(ID3D11ShaderReflection, IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ __in REFIID iid, + __out LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD(GetDesc)(THIS_ __out D3D11_SHADER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ __in UINT Index) PURE; + STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ __in LPCSTR Name) PURE; + + STDMETHOD(GetResourceBindingDesc)(THIS_ __in UINT ResourceIndex, + __out D3D11_SHADER_INPUT_BIND_DESC *pDesc) PURE; + + STDMETHOD(GetInputParameterDesc)(THIS_ __in UINT ParameterIndex, + __out D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + STDMETHOD(GetOutputParameterDesc)(THIS_ __in UINT ParameterIndex, + __out D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + STDMETHOD(GetPatchConstantParameterDesc)(THIS_ __in UINT ParameterIndex, + __out D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE; + + STDMETHOD_(ID3D11ShaderReflectionVariable*, GetVariableByName)(THIS_ __in LPCSTR Name) PURE; + + STDMETHOD(GetResourceBindingDescByName)(THIS_ __in LPCSTR Name, + __out D3D11_SHADER_INPUT_BIND_DESC *pDesc) PURE; + + STDMETHOD_(UINT, GetMovInstructionCount)(THIS) PURE; + STDMETHOD_(UINT, GetMovcInstructionCount)(THIS) PURE; + STDMETHOD_(UINT, GetConversionInstructionCount)(THIS) PURE; + STDMETHOD_(UINT, GetBitwiseInstructionCount)(THIS) PURE; + + STDMETHOD_(D3D_PRIMITIVE, GetGSInputPrimitive)(THIS) PURE; + STDMETHOD_(BOOL, IsSampleFrequencyShader)(THIS) PURE; + + STDMETHOD_(UINT, GetNumInterfaceSlots)(THIS) PURE; + STDMETHOD(GetMinFeatureLevel)(THIS_ __out enum D3D_FEATURE_LEVEL* pLevel) PURE; + + STDMETHOD_(UINT, GetThreadGroupSize)(THIS_ + __out_opt UINT* pSizeX, + __out_opt UINT* pSizeY, + __out_opt UINT* pSizeZ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3D11SHADER_H__ + diff --git a/dxsdk/Include/D3DCSX.h b/dxsdk/Include/D3DCSX.h new file mode 100644 index 0000000..240cdbb --- /dev/null +++ b/dxsdk/Include/D3DCSX.h @@ -0,0 +1,409 @@ + +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3DX11GPGPU.h +// Content: D3DX11 General Purpose GPU computing algorithms +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx11.h" + +#ifndef __D3DX11GPGPU_H__ +#define __D3DX11GPGPU_H__ + +// Current name of the DLL shipped in the same SDK as this header. + + +#define D3DCSX_DLL_W L"d3dcsx_43.dll" +#define D3DCSX_DLL_A "d3dcsx_43.dll" + +#ifdef UNICODE + #define D3DCSX_DLL D3DCSX_DLL_W +#else + #define D3DCSX_DLL D3DCSX_DLL_A +#endif + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + + + + + +////////////////////////////////////////////////////////////////////////////// + +typedef enum D3DX11_SCAN_DATA_TYPE +{ + D3DX11_SCAN_DATA_TYPE_FLOAT = 1, + D3DX11_SCAN_DATA_TYPE_INT, + D3DX11_SCAN_DATA_TYPE_UINT, +} D3DX11_SCAN_DATA_TYPE; + +typedef enum D3DX11_SCAN_OPCODE +{ + D3DX11_SCAN_OPCODE_ADD = 1, + D3DX11_SCAN_OPCODE_MIN, + D3DX11_SCAN_OPCODE_MAX, + D3DX11_SCAN_OPCODE_MUL, + D3DX11_SCAN_OPCODE_AND, + D3DX11_SCAN_OPCODE_OR, + D3DX11_SCAN_OPCODE_XOR, +} D3DX11_SCAN_OPCODE; + +typedef enum D3DX11_SCAN_DIRECTION +{ + D3DX11_SCAN_DIRECTION_FORWARD = 1, + D3DX11_SCAN_DIRECTION_BACKWARD, +} D3DX11_SCAN_DIRECTION; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX11Scan: +////////////////////////////////////////////////////////////////////////////// + +// {5089b68f-e71d-4d38-be8e-f363b95a9405} +DEFINE_GUID(IID_ID3DX11Scan, 0x5089b68f, 0xe71d, 0x4d38, 0xbe, 0x8e, 0xf3, 0x63, 0xb9, 0x5a, 0x94, 0x05); + +#undef INTERFACE +#define INTERFACE ID3DX11Scan + +DECLARE_INTERFACE_(ID3DX11Scan, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX11Scan + + STDMETHOD(SetScanDirection)(THIS_ D3DX11_SCAN_DIRECTION Direction) PURE; + + //============================================================================= + // Performs an unsegmented scan of a sequence in-place or out-of-place + // ElementType element type + // OpCode binary operation + // Direction scan direction + // ElementScanSize size of scan, in elements + // pSrc input sequence on the device. pSrc==pDst for in-place scans + // pDst output sequence on the device + //============================================================================= + STDMETHOD(Scan)( THIS_ + D3DX11_SCAN_DATA_TYPE ElementType, + D3DX11_SCAN_OPCODE OpCode, + UINT ElementScanSize, + __in ID3D11UnorderedAccessView* pSrc, + __in ID3D11UnorderedAccessView* pDst + ) PURE; + + //============================================================================= + // Performs a multiscan of a sequence in-place or out-of-place + // ElementType element type + // OpCode binary operation + // Direction scan direction + // ElementScanSize size of scan, in elements + // ElementScanPitch pitch of the next scan, in elements + // ScanCount number of scans in a multiscan + // pSrc input sequence on the device. pSrc==pDst for in-place scans + // pDst output sequence on the device + //============================================================================= + STDMETHOD(Multiscan)( THIS_ + D3DX11_SCAN_DATA_TYPE ElementType, + D3DX11_SCAN_OPCODE OpCode, + UINT ElementScanSize, + UINT ElementScanPitch, + UINT ScanCount, + __in ID3D11UnorderedAccessView* pSrc, + __in ID3D11UnorderedAccessView* pDst + ) PURE; +}; + + +//============================================================================= +// Creates a scan context +// pDevice the device context +// MaxElementScanSize maximum single scan size, in elements (FLOAT, UINT, or INT) +// MaxScanCount maximum number of scans in multiscan +// ppScanContext new scan context +//============================================================================= +HRESULT WINAPI D3DX11CreateScan( + __in ID3D11DeviceContext* pDeviceContext, + UINT MaxElementScanSize, + UINT MaxScanCount, + __out ID3DX11Scan** ppScan ); + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX11SegmentedScan: +////////////////////////////////////////////////////////////////////////////// + +// {a915128c-d954-4c79-bfe1-64db923194d6} +DEFINE_GUID(IID_ID3DX11SegmentedScan, 0xa915128c, 0xd954, 0x4c79, 0xbf, 0xe1, 0x64, 0xdb, 0x92, 0x31, 0x94, 0xd6); + +#undef INTERFACE +#define INTERFACE ID3DX11SegmentedScan + +DECLARE_INTERFACE_(ID3DX11SegmentedScan, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX11SegmentedScan + + STDMETHOD(SetScanDirection)(THIS_ D3DX11_SCAN_DIRECTION Direction) PURE; + + //============================================================================= + // Performs a segscan of a sequence in-place or out-of-place + // ElementType element type + // OpCode binary operation + // Direction scan direction + // pSrcElementFlags compact array of bits, one per element of pSrc. A set value + // indicates the start of a new segment. + // ElementScanSize size of scan, in elements + // pSrc input sequence on the device. pSrc==pDst for in-place scans + // pDst output sequence on the device + //============================================================================= + STDMETHOD(SegScan)( THIS_ + D3DX11_SCAN_DATA_TYPE ElementType, + D3DX11_SCAN_OPCODE OpCode, + UINT ElementScanSize, + __in_opt ID3D11UnorderedAccessView* pSrc, + __in ID3D11UnorderedAccessView* pSrcElementFlags, + __in ID3D11UnorderedAccessView* pDst + ) PURE; +}; + + +//============================================================================= +// Creates a segmented scan context +// pDevice the device context +// MaxElementScanSize maximum single scan size, in elements (FLOAT, UINT, or INT) +// ppScanContext new scan context +//============================================================================= +HRESULT WINAPI D3DX11CreateSegmentedScan( + __in ID3D11DeviceContext* pDeviceContext, + UINT MaxElementScanSize, + __out ID3DX11SegmentedScan** ppScan ); + + + +////////////////////////////////////////////////////////////////////////////// + +#define D3DX11_FFT_MAX_PRECOMPUTE_BUFFERS 4 +#define D3DX11_FFT_MAX_TEMP_BUFFERS 4 +#define D3DX11_FFT_MAX_DIMENSIONS 32 + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX11FFT: +////////////////////////////////////////////////////////////////////////////// + +// {b3f7a938-4c93-4310-a675-b30d6de50553} +DEFINE_GUID(IID_ID3DX11FFT, 0xb3f7a938, 0x4c93, 0x4310, 0xa6, 0x75, 0xb3, 0x0d, 0x6d, 0xe5, 0x05, 0x53); + +#undef INTERFACE +#define INTERFACE ID3DX11FFT + +DECLARE_INTERFACE_(ID3DX11FFT, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX11FFT + + // scale for forward transform (defaults to 1 if set to 0) + STDMETHOD(SetForwardScale)(THIS_ FLOAT ForwardScale) PURE; + STDMETHOD_(FLOAT, GetForwardScale)(THIS) PURE; + + // scale for inverse transform (defaults to 1/N if set to 0, where N is + // the product of the transformed dimension lengths + STDMETHOD(SetInverseScale)(THIS_ FLOAT InverseScale) PURE; + STDMETHOD_(FLOAT, GetInverseScale)(THIS) PURE; + + //------------------------------------------------------------------------------ + // Attaches buffers to the context and performs any required precomputation. + // The buffers must be no smaller than the corresponding buffer sizes returned + // by D3DX11CreateFFT*(). Temp buffers may beshared between multiple contexts, + // though care should be taken to concurrently execute multiple FFTs which share + // temp buffers. + // + // NumTempBuffers number of buffers in ppTempBuffers + // ppTempBuffers temp buffers to attach + // NumPrecomputeBuffers number of buffers in ppPrecomputeBufferSizes + // ppPrecomputeBufferSizes buffers to hold precomputed data + STDMETHOD(AttachBuffersAndPrecompute)( THIS_ + __in_range(0,D3DX11_FFT_MAX_TEMP_BUFFERS) UINT NumTempBuffers, + __in_ecount(NumTempBuffers) ID3D11UnorderedAccessView*const* ppTempBuffers, + __in_range(0,D3DX11_FFT_MAX_PRECOMPUTE_BUFFERS) UINT NumPrecomputeBuffers, + __in_ecount(NumPrecomputeBuffers) ID3D11UnorderedAccessView*const* ppPrecomputeBufferSizes ) PURE; + + //------------------------------------------------------------------------------ + // Call after buffers have been attached to the context, pInput and *ppOuput can + // be one of the temp buffers. If *ppOutput == NULL, then the computation will ping-pong + // between temp buffers and the last buffer written to is stored at *ppOutput. + // Otherwise, *ppOutput is used as the output buffer (which may incur an extra copy). + // + // The format of complex data is interleaved components, e.g. (Real0, Imag0), + // (Real1, Imag1) ... etc. Data is stored in row major order + // + // pInputBuffer view onto input buffer + // ppOutpuBuffert pointer to view of output buffer + STDMETHOD(ForwardTransform)( THIS_ + __in const ID3D11UnorderedAccessView* pInputBuffer, + __inout ID3D11UnorderedAccessView** ppOutputBuffer ) PURE; + + STDMETHOD(InverseTransform)( THIS_ + __in const ID3D11UnorderedAccessView* pInputBuffer, + __inout ID3D11UnorderedAccessView** ppOutputBuffer ) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX11FFT Creation Routines +////////////////////////////////////////////////////////////////////////////// + +typedef enum D3DX11_FFT_DATA_TYPE +{ + D3DX11_FFT_DATA_TYPE_REAL, + D3DX11_FFT_DATA_TYPE_COMPLEX, +} D3DX11_FFT_DATA_TYPE; + +typedef enum D3DX11_FFT_DIM_MASK +{ + D3DX11_FFT_DIM_MASK_1D = 0x1, + D3DX11_FFT_DIM_MASK_2D = 0x3, + D3DX11_FFT_DIM_MASK_3D = 0x7, +} D3DX11_FFT_DIM_MASK; + +typedef struct D3DX11_FFT_DESC +{ + UINT NumDimensions; // number of dimensions + UINT ElementLengths[D3DX11_FFT_MAX_DIMENSIONS]; // length of each dimension + UINT DimensionMask; // a bit set for each dimensions to transform + // (see D3DX11_FFT_DIM_MASK for common masks) + D3DX11_FFT_DATA_TYPE Type; // type of the elements in spatial domain +} D3DX11_FFT_DESC; + + +//------------------------------------------------------------------------------ +// NumTempBufferSizes Number of temporary buffers needed +// pTempBufferSizes Minimum sizes (in FLOATs) of temporary buffers +// NumPrecomputeBufferSizes Number of precompute buffers needed +// pPrecomputeBufferSizes minimum sizes (in FLOATs) for precompute buffers +//------------------------------------------------------------------------------ + +typedef struct D3DX11_FFT_BUFFER_INFO +{ + __range(0,D3DX11_FFT_MAX_TEMP_BUFFERS) UINT NumTempBufferSizes; + UINT TempBufferFloatSizes[D3DX11_FFT_MAX_TEMP_BUFFERS]; + __range(0,D3DX11_FFT_MAX_PRECOMPUTE_BUFFERS) UINT NumPrecomputeBufferSizes; + UINT PrecomputeBufferFloatSizes[D3DX11_FFT_MAX_PRECOMPUTE_BUFFERS]; +} D3DX11_FFT_BUFFER_INFO; + + +typedef enum D3DX11_FFT_CREATE_FLAG +{ + D3DX11_FFT_CREATE_FLAG_NO_PRECOMPUTE_BUFFERS = 0x01L, // do not precompute values and store into buffers +} D3DX11_FFT_CREATE_FLAG; + + +//------------------------------------------------------------------------------ +// Creates an ID3DX11FFT COM interface object and returns a pointer to it at *ppFFT. +// The descriptor describes the shape of the data as well as the scaling factors +// that should be used for forward and inverse transforms. +// The FFT computation may require temporaries that act as ping-pong buffers +// and for other purposes. aTempSizes is a list of the sizes required for +// temporaries. Likewise, some data may need to be precomputed and the sizes +// of those sizes are returned in aPrecomputedBufferSizes. +// +// To perform a computation, follow these steps: +// 1) Create the FFT context object +// 2) Precompute (and Attach temp working buffers of at least the required size) +// 3) Call Compute() on some input data +// +// Compute() may be called repeatedly with different inputs and transform +// directions. When finished with the FFT work, release the FFT interface() +// +// Device Direct3DDeviceContext to use in +// pDesc Descriptor for FFT transform in +// Count the number of 1D FFTs to perform in +// Flags See D3DX11_FFT_CREATE_FLAG in +// pBufferInfo Pointer to BUFFER_INFO struct, filled by funciton out +// ppFFT Pointer to returned context pointer out +//------------------------------------------------------------------------------ + +HRESULT WINAPI D3DX11CreateFFT( + ID3D11DeviceContext* pDeviceContext, + __in const D3DX11_FFT_DESC* pDesc, + UINT Flags, + __out D3DX11_FFT_BUFFER_INFO* pBufferInfo, + __out ID3DX11FFT** ppFFT + ); + +HRESULT WINAPI D3DX11CreateFFT1DReal( + ID3D11DeviceContext* pDeviceContext, + UINT X, + UINT Flags, + __out D3DX11_FFT_BUFFER_INFO* pBufferInfo, + __out ID3DX11FFT** ppFFT + ); +HRESULT WINAPI D3DX11CreateFFT1DComplex( + ID3D11DeviceContext* pDeviceContext, + UINT X, + UINT Flags, + __out D3DX11_FFT_BUFFER_INFO* pBufferInfo, + __out ID3DX11FFT** ppFFT + ); +HRESULT WINAPI D3DX11CreateFFT2DReal( + ID3D11DeviceContext* pDeviceContext, + UINT X, + UINT Y, + UINT Flags, + __out D3DX11_FFT_BUFFER_INFO* pBufferInfo, + __out ID3DX11FFT** ppFFT + ); +HRESULT WINAPI D3DX11CreateFFT2DComplex( + ID3D11DeviceContext* pDeviceContext, + UINT X, + UINT Y, + UINT Flags, + __out D3DX11_FFT_BUFFER_INFO* pBufferInfo, + __out ID3DX11FFT** ppFFT + ); +HRESULT WINAPI D3DX11CreateFFT3DReal( + ID3D11DeviceContext* pDeviceContext, + UINT X, + UINT Y, + UINT Z, + UINT Flags, + __out D3DX11_FFT_BUFFER_INFO* pBufferInfo, + __out ID3DX11FFT** ppFFT + ); +HRESULT WINAPI D3DX11CreateFFT3DComplex( + ID3D11DeviceContext* pDeviceContext, + UINT X, + UINT Y, + UINT Z, + UINT Flags, + __out D3DX11_FFT_BUFFER_INFO* pBufferInfo, + __out ID3DX11FFT** ppFFT + ); + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX11GPGPU_H__ + + diff --git a/dxsdk/Include/D3DX10.h b/dxsdk/Include/D3DX10.h new file mode 100644 index 0000000..5cdcd51 --- /dev/null +++ b/dxsdk/Include/D3DX10.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx10.h +// Content: D3DX10 utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __D3DX10_INTERNAL__ +#error Incorrect D3DX10 header used +#endif + +#ifndef __D3DX10_H__ +#define __D3DX10_H__ + + +// Defines +#include +#include + +#define D3DX10_DEFAULT ((UINT) -1) +#define D3DX10_FROM_FILE ((UINT) -3) +#define DXGI_FORMAT_FROM_FILE ((DXGI_FORMAT) -3) + +#ifndef D3DX10INLINE +#ifdef _MSC_VER + #if (_MSC_VER >= 1200) + #define D3DX10INLINE __forceinline + #else + #define D3DX10INLINE __inline + #endif +#else + #ifdef __cplusplus + #define D3DX10INLINE inline + #else + #define D3DX10INLINE + #endif +#endif +#endif + + + +// Includes +#include "d3d10.h" +#include "d3dx10.h" +#include "d3dx10math.h" +#include "d3dx10core.h" +#include "d3dx10tex.h" +#include "d3dx10mesh.h" +#include "d3dx10async.h" + + +// Errors +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +enum _D3DX10_ERR { + D3DX10_ERR_CANNOT_MODIFY_INDEX_BUFFER = MAKE_DDHRESULT(2900), + D3DX10_ERR_INVALID_MESH = MAKE_DDHRESULT(2901), + D3DX10_ERR_CANNOT_ATTR_SORT = MAKE_DDHRESULT(2902), + D3DX10_ERR_SKINNING_NOT_SUPPORTED = MAKE_DDHRESULT(2903), + D3DX10_ERR_TOO_MANY_INFLUENCES = MAKE_DDHRESULT(2904), + D3DX10_ERR_INVALID_DATA = MAKE_DDHRESULT(2905), + D3DX10_ERR_LOADED_MESH_HAS_NO_DATA = MAKE_DDHRESULT(2906), + D3DX10_ERR_DUPLICATE_NAMED_FRAGMENT = MAKE_DDHRESULT(2907), + D3DX10_ERR_CANNOT_REMOVE_LAST_ITEM = MAKE_DDHRESULT(2908), +}; + + +#endif //__D3DX10_H__ + diff --git a/dxsdk/Include/D3DX10core.h b/dxsdk/Include/D3DX10core.h new file mode 100644 index 0000000..290a004 --- /dev/null +++ b/dxsdk/Include/D3DX10core.h @@ -0,0 +1,444 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx10core.h +// Content: D3DX10 core types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx10.h" + +#ifndef __D3DX10CORE_H__ +#define __D3DX10CORE_H__ + +// Current name of the DLL shipped in the same SDK as this header. + + +#define D3DX10_DLL_W L"d3dx10_43.dll" +#define D3DX10_DLL_A "d3dx10_43.dll" + +#ifdef UNICODE + #define D3DX10_DLL D3DX10_DLL_W +#else + #define D3DX10_DLL D3DX10_DLL_A +#endif + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +/////////////////////////////////////////////////////////////////////////// +// D3DX10_SDK_VERSION: +// ----------------- +// This identifier is passed to D3DX10CheckVersion in order to ensure that an +// application was built against the correct header files and lib files. +// This number is incremented whenever a header (or other) change would +// require applications to be rebuilt. If the version doesn't match, +// D3DX10CreateVersion will return FALSE. (The number itself has no meaning.) +/////////////////////////////////////////////////////////////////////////// + + +#define D3DX10_SDK_VERSION 43 + + +/////////////////////////////////////////////////////////////////////////// +// D3DX10CreateDevice +// D3DX10CreateDeviceAndSwapChain +// D3DX10GetFeatureLevel1 +/////////////////////////////////////////////////////////////////////////// +HRESULT WINAPI D3DX10CreateDevice(IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + ID3D10Device **ppDevice); + +HRESULT WINAPI D3DX10CreateDeviceAndSwapChain(IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + IDXGISwapChain **ppSwapChain, + ID3D10Device **ppDevice); + +typedef interface ID3D10Device1 ID3D10Device1; +HRESULT WINAPI D3DX10GetFeatureLevel1(ID3D10Device *pDevice, ID3D10Device1 **ppDevice1); + + +#ifdef D3D_DIAG_DLL +BOOL WINAPI D3DX10DebugMute(BOOL Mute); +#endif +HRESULT WINAPI D3DX10CheckVersion(UINT D3DSdkVersion, UINT D3DX10SdkVersion); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +////////////////////////////////////////////////////////////////////////////// +// D3DX10_SPRITE flags: +// ----------------- +// D3DX10_SPRITE_SAVE_STATE +// Specifies device state should be saved and restored in Begin/End. +// D3DX10SPRITE_SORT_TEXTURE +// Sprites are sorted by texture prior to drawing. This is recommended when +// drawing non-overlapping sprites of uniform depth. For example, drawing +// screen-aligned text with ID3DX10Font. +// D3DX10SPRITE_SORT_DEPTH_FRONT_TO_BACK +// Sprites are sorted by depth front-to-back prior to drawing. This is +// recommended when drawing opaque sprites of varying depths. +// D3DX10SPRITE_SORT_DEPTH_BACK_TO_FRONT +// Sprites are sorted by depth back-to-front prior to drawing. This is +// recommended when drawing transparent sprites of varying depths. +// D3DX10SPRITE_ADDREF_TEXTURES +// AddRef/Release all textures passed in to DrawSpritesBuffered +////////////////////////////////////////////////////////////////////////////// + +typedef enum _D3DX10_SPRITE_FLAG +{ + D3DX10_SPRITE_SORT_TEXTURE = 0x01, + D3DX10_SPRITE_SORT_DEPTH_BACK_TO_FRONT = 0x02, + D3DX10_SPRITE_SORT_DEPTH_FRONT_TO_BACK = 0x04, + D3DX10_SPRITE_SAVE_STATE = 0x08, + D3DX10_SPRITE_ADDREF_TEXTURES = 0x10, +} D3DX10_SPRITE_FLAG; + +typedef struct _D3DX10_SPRITE +{ + D3DXMATRIX matWorld; + + D3DXVECTOR2 TexCoord; + D3DXVECTOR2 TexSize; + + D3DXCOLOR ColorModulate; + + ID3D10ShaderResourceView *pTexture; + UINT TextureIndex; +} D3DX10_SPRITE; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX10Sprite: +// ------------ +// This object intends to provide an easy way to drawing sprites using D3D. +// +// Begin - +// Prepares device for drawing sprites. +// +// Draw - +// Draws a sprite +// +// Flush - +// Forces all batched sprites to submitted to the device. +// +// End - +// Restores device state to how it was when Begin was called. +// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DX10Sprite ID3DX10Sprite; +typedef interface ID3DX10Sprite *LPD3DX10SPRITE; + + +// {BA0B762D-8D28-43ec-B9DC-2F84443B0614} +DEFINE_GUID(IID_ID3DX10Sprite, +0xba0b762d, 0x8d28, 0x43ec, 0xb9, 0xdc, 0x2f, 0x84, 0x44, 0x3b, 0x6, 0x14); + + +#undef INTERFACE +#define INTERFACE ID3DX10Sprite + +DECLARE_INTERFACE_(ID3DX10Sprite, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX10Sprite + STDMETHOD(Begin)(THIS_ UINT flags) PURE; + + STDMETHOD(DrawSpritesBuffered)(THIS_ D3DX10_SPRITE *pSprites, UINT cSprites) PURE; + STDMETHOD(Flush)(THIS) PURE; + + STDMETHOD(DrawSpritesImmediate)(THIS_ D3DX10_SPRITE *pSprites, UINT cSprites, UINT cbSprite, UINT flags) PURE; + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(GetViewTransform)(THIS_ D3DXMATRIX *pViewTransform) PURE; + STDMETHOD(SetViewTransform)(THIS_ D3DXMATRIX *pViewTransform) PURE; + STDMETHOD(GetProjectionTransform)(THIS_ D3DXMATRIX *pProjectionTransform) PURE; + STDMETHOD(SetProjectionTransform)(THIS_ D3DXMATRIX *pProjectionTransform) PURE; + + STDMETHOD(GetDevice)(THIS_ ID3D10Device** ppDevice) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DX10CreateSprite( + ID3D10Device* pDevice, + UINT cDeviceBufferSize, + LPD3DX10SPRITE* ppSprite); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX10ThreadPump: +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DX10DataLoader + +DECLARE_INTERFACE(ID3DX10DataLoader) +{ + STDMETHOD(Load)(THIS) PURE; + STDMETHOD(Decompress)(THIS_ void **ppData, SIZE_T *pcBytes) PURE; + STDMETHOD(Destroy)(THIS) PURE; +}; + +#undef INTERFACE +#define INTERFACE ID3DX10DataProcessor + +DECLARE_INTERFACE(ID3DX10DataProcessor) +{ + STDMETHOD(Process)(THIS_ void *pData, SIZE_T cBytes) PURE; + STDMETHOD(CreateDeviceObject)(THIS_ void **ppDataObject) PURE; + STDMETHOD(Destroy)(THIS) PURE; +}; + +// {C93FECFA-6967-478a-ABBC-402D90621FCB} +DEFINE_GUID(IID_ID3DX10ThreadPump, +0xc93fecfa, 0x6967, 0x478a, 0xab, 0xbc, 0x40, 0x2d, 0x90, 0x62, 0x1f, 0xcb); + +#undef INTERFACE +#define INTERFACE ID3DX10ThreadPump + +DECLARE_INTERFACE_(ID3DX10ThreadPump, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX10ThreadPump + STDMETHOD(AddWorkItem)(THIS_ ID3DX10DataLoader *pDataLoader, ID3DX10DataProcessor *pDataProcessor, HRESULT *pHResult, void **ppDeviceObject) PURE; + STDMETHOD_(UINT, GetWorkItemCount)(THIS) PURE; + + STDMETHOD(WaitForAllItems)(THIS) PURE; + STDMETHOD(ProcessDeviceWorkItems)(THIS_ UINT iWorkItemCount); + + STDMETHOD(PurgeAllItems)(THIS) PURE; + STDMETHOD(GetQueueStatus)(THIS_ UINT *pIoQueue, UINT *pProcessQueue, UINT *pDeviceQueue) PURE; + +}; + +HRESULT WINAPI D3DX10CreateThreadPump(UINT cIoThreads, UINT cProcThreads, ID3DX10ThreadPump **ppThreadPump); + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX10Font: +// ---------- +// Font objects contain the textures and resources needed to render a specific +// font on a specific device. +// +// GetGlyphData - +// Returns glyph cache data, for a given glyph. +// +// PreloadCharacters/PreloadGlyphs/PreloadText - +// Preloads glyphs into the glyph cache textures. +// +// DrawText - +// Draws formatted text on a D3D device. Some parameters are +// surprisingly similar to those of GDI's DrawText function. See GDI +// documentation for a detailed description of these parameters. +// If pSprite is NULL, an internal sprite object will be used. +// +////////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DX10_FONT_DESCA +{ + INT Height; + UINT Width; + UINT Weight; + UINT MipLevels; + BOOL Italic; + BYTE CharSet; + BYTE OutputPrecision; + BYTE Quality; + BYTE PitchAndFamily; + CHAR FaceName[LF_FACESIZE]; + +} D3DX10_FONT_DESCA, *LPD3DX10_FONT_DESCA; + +typedef struct _D3DX10_FONT_DESCW +{ + INT Height; + UINT Width; + UINT Weight; + UINT MipLevels; + BOOL Italic; + BYTE CharSet; + BYTE OutputPrecision; + BYTE Quality; + BYTE PitchAndFamily; + WCHAR FaceName[LF_FACESIZE]; + +} D3DX10_FONT_DESCW, *LPD3DX10_FONT_DESCW; + +#ifdef UNICODE +typedef D3DX10_FONT_DESCW D3DX10_FONT_DESC; +typedef LPD3DX10_FONT_DESCW LPD3DX10_FONT_DESC; +#else +typedef D3DX10_FONT_DESCA D3DX10_FONT_DESC; +typedef LPD3DX10_FONT_DESCA LPD3DX10_FONT_DESC; +#endif + + +typedef interface ID3DX10Font ID3DX10Font; +typedef interface ID3DX10Font *LPD3DX10FONT; + + +// {D79DBB70-5F21-4d36-BBC2-FF525C213CDC} +DEFINE_GUID(IID_ID3DX10Font, +0xd79dbb70, 0x5f21, 0x4d36, 0xbb, 0xc2, 0xff, 0x52, 0x5c, 0x21, 0x3c, 0xdc); + + +#undef INTERFACE +#define INTERFACE ID3DX10Font + +DECLARE_INTERFACE_(ID3DX10Font, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX10Font + STDMETHOD(GetDevice)(THIS_ ID3D10Device** ppDevice) PURE; + STDMETHOD(GetDescA)(THIS_ D3DX10_FONT_DESCA *pDesc) PURE; + STDMETHOD(GetDescW)(THIS_ D3DX10_FONT_DESCW *pDesc) PURE; + STDMETHOD_(BOOL, GetTextMetricsA)(THIS_ TEXTMETRICA *pTextMetrics) PURE; + STDMETHOD_(BOOL, GetTextMetricsW)(THIS_ TEXTMETRICW *pTextMetrics) PURE; + + STDMETHOD_(HDC, GetDC)(THIS) PURE; + STDMETHOD(GetGlyphData)(THIS_ UINT Glyph, ID3D10ShaderResourceView** ppTexture, RECT *pBlackBox, POINT *pCellInc) PURE; + + STDMETHOD(PreloadCharacters)(THIS_ UINT First, UINT Last) PURE; + STDMETHOD(PreloadGlyphs)(THIS_ UINT First, UINT Last) PURE; + STDMETHOD(PreloadTextA)(THIS_ LPCSTR pString, INT Count) PURE; + STDMETHOD(PreloadTextW)(THIS_ LPCWSTR pString, INT Count) PURE; + + STDMETHOD_(INT, DrawTextA)(THIS_ LPD3DX10SPRITE pSprite, LPCSTR pString, INT Count, LPRECT pRect, UINT Format, D3DXCOLOR Color) PURE; + STDMETHOD_(INT, DrawTextW)(THIS_ LPD3DX10SPRITE pSprite, LPCWSTR pString, INT Count, LPRECT pRect, UINT Format, D3DXCOLOR Color) PURE; + +#ifdef __cplusplus +#ifdef UNICODE + HRESULT WINAPI_INLINE GetDesc(D3DX10_FONT_DESCW *pDesc) { return GetDescW(pDesc); } + HRESULT WINAPI_INLINE PreloadText(LPCWSTR pString, INT Count) { return PreloadTextW(pString, Count); } +#else + HRESULT WINAPI_INLINE GetDesc(D3DX10_FONT_DESCA *pDesc) { return GetDescA(pDesc); } + HRESULT WINAPI_INLINE PreloadText(LPCSTR pString, INT Count) { return PreloadTextA(pString, Count); } +#endif +#endif //__cplusplus +}; + +#ifndef GetTextMetrics +#ifdef UNICODE +#define GetTextMetrics GetTextMetricsW +#else +#define GetTextMetrics GetTextMetricsA +#endif +#endif + +#ifndef DrawText +#ifdef UNICODE +#define DrawText DrawTextW +#else +#define DrawText DrawTextA +#endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DX10CreateFontA( + ID3D10Device* pDevice, + INT Height, + UINT Width, + UINT Weight, + UINT MipLevels, + BOOL Italic, + UINT CharSet, + UINT OutputPrecision, + UINT Quality, + UINT PitchAndFamily, + LPCSTR pFaceName, + LPD3DX10FONT* ppFont); + +HRESULT WINAPI + D3DX10CreateFontW( + ID3D10Device* pDevice, + INT Height, + UINT Width, + UINT Weight, + UINT MipLevels, + BOOL Italic, + UINT CharSet, + UINT OutputPrecision, + UINT Quality, + UINT PitchAndFamily, + LPCWSTR pFaceName, + LPD3DX10FONT* ppFont); + +#ifdef UNICODE +#define D3DX10CreateFont D3DX10CreateFontW +#else +#define D3DX10CreateFont D3DX10CreateFontA +#endif + + +HRESULT WINAPI + D3DX10CreateFontIndirectA( + ID3D10Device* pDevice, + CONST D3DX10_FONT_DESCA* pDesc, + LPD3DX10FONT* ppFont); + +HRESULT WINAPI + D3DX10CreateFontIndirectW( + ID3D10Device* pDevice, + CONST D3DX10_FONT_DESCW* pDesc, + LPD3DX10FONT* ppFont); + +#ifdef UNICODE +#define D3DX10CreateFontIndirect D3DX10CreateFontIndirectW +#else +#define D3DX10CreateFontIndirect D3DX10CreateFontIndirectA +#endif + +HRESULT WINAPI D3DX10UnsetAllDeviceObjects(ID3D10Device *pDevice); + +#ifdef __cplusplus +} +#endif //__cplusplus + +/////////////////////////////////////////////////////////////////////////// + +#define _FACD3D 0x876 +#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) +#define MAKE_D3DSTATUS( code ) MAKE_HRESULT( 0, _FACD3D, code ) + +#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) +#define D3DERR_WASSTILLDRAWING MAKE_D3DHRESULT(540) + +#endif //__D3DX10CORE_H__ + diff --git a/dxsdk/Include/D3DX10math.h b/dxsdk/Include/D3DX10math.h new file mode 100644 index 0000000..a4b8e2d --- /dev/null +++ b/dxsdk/Include/D3DX10math.h @@ -0,0 +1,1866 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: D3DX10math.h +// Content: D3DX10 math types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "D3DX10.h" + +// D3DX10 and D3DX9 math look the same. You can include either one into your project. +// We are intentionally using the header define from D3DX9 math to prevent double-inclusion. +#ifndef __D3DX9MATH_H__ +#define __D3DX9MATH_H__ + +#include +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4201) // anonymous unions warning + +//=========================================================================== +// +// Type definitions from D3D9 +// +//=========================================================================== + +#ifndef D3DVECTOR_DEFINED +typedef struct _D3DVECTOR { + float x; + float y; + float z; +} D3DVECTOR; +#define D3DVECTOR_DEFINED +#endif + +#ifndef D3DMATRIX_DEFINED +typedef struct _D3DMATRIX { + union { + struct { + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; + + }; + float m[4][4]; + }; +} D3DMATRIX; +#define D3DMATRIX_DEFINED +#endif + +//=========================================================================== +// +// General purpose utilities +// +//=========================================================================== +#define D3DX_PI (3.14159265358979323846) +#define D3DX_1BYPI ( 1.0 / D3DX_PI ) + +#define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0)) +#define D3DXToDegree( radian ) ((radian) * (180.0 / D3DX_PI)) + + + +//=========================================================================== +// +// 16 bit floating point numbers +// +//=========================================================================== + +#define D3DX_16F_DIG 3 // # of decimal digits of precision +#define D3DX_16F_EPSILON 4.8875809e-4f // smallest such that 1.0 + epsilon != 1.0 +#define D3DX_16F_MANT_DIG 11 // # of bits in mantissa +#define D3DX_16F_MAX 6.550400e+004 // max value +#define D3DX_16F_MAX_10_EXP 4 // max decimal exponent +#define D3DX_16F_MAX_EXP 15 // max binary exponent +#define D3DX_16F_MIN 6.1035156e-5f // min positive value +#define D3DX_16F_MIN_10_EXP (-4) // min decimal exponent +#define D3DX_16F_MIN_EXP (-14) // min binary exponent +#define D3DX_16F_RADIX 2 // exponent radix +#define D3DX_16F_ROUNDS 1 // addition rounding: near +#define D3DX_16F_SIGN_MASK 0x8000 +#define D3DX_16F_EXP_MASK 0x7C00 +#define D3DX_16F_FRAC_MASK 0x03FF + +typedef struct D3DXFLOAT16 +{ +#ifdef __cplusplus +public: + D3DXFLOAT16() {}; + D3DXFLOAT16( FLOAT ); + D3DXFLOAT16( CONST D3DXFLOAT16& ); + + // casting + operator FLOAT (); + + // binary operators + BOOL operator == ( CONST D3DXFLOAT16& ) const; + BOOL operator != ( CONST D3DXFLOAT16& ) const; + +protected: +#endif //__cplusplus + WORD value; +} D3DXFLOAT16, *LPD3DXFLOAT16; + + + +//=========================================================================== +// +// Vectors +// +//=========================================================================== + + +//-------------------------- +// 2D Vector +//-------------------------- +typedef struct D3DXVECTOR2 +{ +#ifdef __cplusplus +public: + D3DXVECTOR2() {}; + D3DXVECTOR2( CONST FLOAT * ); + D3DXVECTOR2( CONST D3DXFLOAT16 * ); + D3DXVECTOR2( FLOAT x, FLOAT y ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR2& operator += ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator -= ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator *= ( FLOAT ); + D3DXVECTOR2& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR2 operator + () const; + D3DXVECTOR2 operator - () const; + + // binary operators + D3DXVECTOR2 operator + ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator - ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator * ( FLOAT ) const; + D3DXVECTOR2 operator / ( FLOAT ) const; + + friend D3DXVECTOR2 operator * ( FLOAT, CONST D3DXVECTOR2& ); + + BOOL operator == ( CONST D3DXVECTOR2& ) const; + BOOL operator != ( CONST D3DXVECTOR2& ) const; + + +public: +#endif //__cplusplus + FLOAT x, y; +} D3DXVECTOR2, *LPD3DXVECTOR2; + + + +//-------------------------- +// 2D Vector (16 bit) +//-------------------------- + +typedef struct D3DXVECTOR2_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR2_16F() {}; + D3DXVECTOR2_16F( CONST FLOAT * ); + D3DXVECTOR2_16F( CONST D3DXFLOAT16 * ); + D3DXVECTOR2_16F( CONST D3DXFLOAT16 &x, CONST D3DXFLOAT16 &y ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR2_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR2_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y; + +} D3DXVECTOR2_16F, *LPD3DXVECTOR2_16F; + + + +//-------------------------- +// 3D Vector +//-------------------------- +#ifdef __cplusplus +typedef struct D3DXVECTOR3 : public D3DVECTOR +{ +public: + D3DXVECTOR3() {}; + D3DXVECTOR3( CONST FLOAT * ); + D3DXVECTOR3( CONST D3DVECTOR& ); + D3DXVECTOR3( CONST D3DXFLOAT16 * ); + D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator *= ( FLOAT ); + D3DXVECTOR3& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR3 operator + () const; + D3DXVECTOR3 operator - () const; + + // binary operators + D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator * ( FLOAT ) const; + D3DXVECTOR3 operator / ( FLOAT ) const; + + friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& ); + + BOOL operator == ( CONST D3DXVECTOR3& ) const; + BOOL operator != ( CONST D3DXVECTOR3& ) const; + +} D3DXVECTOR3, *LPD3DXVECTOR3; + +#else //!__cplusplus +typedef struct _D3DVECTOR D3DXVECTOR3, *LPD3DXVECTOR3; +#endif //!__cplusplus + + + +//-------------------------- +// 3D Vector (16 bit) +//-------------------------- +typedef struct D3DXVECTOR3_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR3_16F() {}; + D3DXVECTOR3_16F( CONST FLOAT * ); + D3DXVECTOR3_16F( CONST D3DVECTOR& ); + D3DXVECTOR3_16F( CONST D3DXFLOAT16 * ); + D3DXVECTOR3_16F( CONST D3DXFLOAT16 &x, CONST D3DXFLOAT16 &y, CONST D3DXFLOAT16 &z ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR3_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR3_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y, z; + +} D3DXVECTOR3_16F, *LPD3DXVECTOR3_16F; + + + +//-------------------------- +// 4D Vector +//-------------------------- +typedef struct D3DXVECTOR4 +{ +#ifdef __cplusplus +public: + D3DXVECTOR4() {}; + D3DXVECTOR4( CONST FLOAT* ); + D3DXVECTOR4( CONST D3DXFLOAT16* ); + D3DXVECTOR4( CONST D3DVECTOR& xyz, FLOAT w ); + D3DXVECTOR4( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR4& operator += ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator -= ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator *= ( FLOAT ); + D3DXVECTOR4& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR4 operator + () const; + D3DXVECTOR4 operator - () const; + + // binary operators + D3DXVECTOR4 operator + ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator - ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator * ( FLOAT ) const; + D3DXVECTOR4 operator / ( FLOAT ) const; + + friend D3DXVECTOR4 operator * ( FLOAT, CONST D3DXVECTOR4& ); + + BOOL operator == ( CONST D3DXVECTOR4& ) const; + BOOL operator != ( CONST D3DXVECTOR4& ) const; + +public: +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXVECTOR4, *LPD3DXVECTOR4; + + +//-------------------------- +// 4D Vector (16 bit) +//-------------------------- +typedef struct D3DXVECTOR4_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR4_16F() {}; + D3DXVECTOR4_16F( CONST FLOAT * ); + D3DXVECTOR4_16F( CONST D3DXFLOAT16* ); + D3DXVECTOR4_16F( CONST D3DXVECTOR3_16F& xyz, CONST D3DXFLOAT16& w ); + D3DXVECTOR4_16F( CONST D3DXFLOAT16& x, CONST D3DXFLOAT16& y, CONST D3DXFLOAT16& z, CONST D3DXFLOAT16& w ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR4_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR4_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y, z, w; + +} D3DXVECTOR4_16F, *LPD3DXVECTOR4_16F; + + + +//=========================================================================== +// +// Matrices +// +//=========================================================================== +#ifdef __cplusplus +typedef struct D3DXMATRIX : public D3DMATRIX +{ +public: + D3DXMATRIX() {}; + D3DXMATRIX( CONST FLOAT * ); + D3DXMATRIX( CONST D3DMATRIX& ); + D3DXMATRIX( CONST D3DXFLOAT16 * ); + D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); + + + // access grants + FLOAT& operator () ( UINT Row, UINT Col ); + FLOAT operator () ( UINT Row, UINT Col ) const; + + // casting operators + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXMATRIX& operator *= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator += ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator -= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator *= ( FLOAT ); + D3DXMATRIX& operator /= ( FLOAT ); + + // unary operators + D3DXMATRIX operator + () const; + D3DXMATRIX operator - () const; + + // binary operators + D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator * ( FLOAT ) const; + D3DXMATRIX operator / ( FLOAT ) const; + + friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& ); + + BOOL operator == ( CONST D3DXMATRIX& ) const; + BOOL operator != ( CONST D3DXMATRIX& ) const; + +} D3DXMATRIX, *LPD3DXMATRIX; + +#else //!__cplusplus +typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX; +#endif //!__cplusplus + + +//--------------------------------------------------------------------------- +// Aligned Matrices +// +// This class helps keep matrices 16-byte aligned as preferred by P4 cpus. +// It aligns matrices on the stack and on the heap or in global scope. +// It does this using __declspec(align(16)) which works on VC7 and on VC 6 +// with the processor pack. Unfortunately there is no way to detect the +// latter so this is turned on only on VC7. On other compilers this is the +// the same as D3DXMATRIX. +// +// Using this class on a compiler that does not actually do the alignment +// can be dangerous since it will not expose bugs that ignore alignment. +// E.g if an object of this class in inside a struct or class, and some code +// memcopys data in it assuming tight packing. This could break on a compiler +// that eventually start aligning the matrix. +//--------------------------------------------------------------------------- +#ifdef __cplusplus +typedef struct _D3DXMATRIXA16 : public D3DXMATRIX +{ + _D3DXMATRIXA16() {}; + _D3DXMATRIXA16( CONST FLOAT * ); + _D3DXMATRIXA16( CONST D3DMATRIX& ); + _D3DXMATRIXA16( CONST D3DXFLOAT16 * ); + _D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); + + // new operators + void* operator new ( size_t ); + void* operator new[] ( size_t ); + + // delete operators + void operator delete ( void* ); // These are NOT virtual; Do not + void operator delete[] ( void* ); // cast to D3DXMATRIX and delete. + + // assignment operators + _D3DXMATRIXA16& operator = ( CONST D3DXMATRIX& ); + +} _D3DXMATRIXA16; + +#else //!__cplusplus +typedef D3DXMATRIX _D3DXMATRIXA16; +#endif //!__cplusplus + + + +#if _MSC_VER >= 1300 // VC7 +#define D3DX_ALIGN16 __declspec(align(16)) +#else +#define D3DX_ALIGN16 // Earlier compiler may not understand this, do nothing. +#endif + +typedef D3DX_ALIGN16 _D3DXMATRIXA16 D3DXMATRIXA16, *LPD3DXMATRIXA16; + + + +//=========================================================================== +// +// Quaternions +// +//=========================================================================== +typedef struct D3DXQUATERNION +{ +#ifdef __cplusplus +public: + D3DXQUATERNION() {}; + D3DXQUATERNION( CONST FLOAT * ); + D3DXQUATERNION( CONST D3DXFLOAT16 * ); + D3DXQUATERNION( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXQUATERNION& operator += ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator -= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( FLOAT ); + D3DXQUATERNION& operator /= ( FLOAT ); + + // unary operators + D3DXQUATERNION operator + () const; + D3DXQUATERNION operator - () const; + + // binary operators + D3DXQUATERNION operator + ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator - ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( FLOAT ) const; + D3DXQUATERNION operator / ( FLOAT ) const; + + friend D3DXQUATERNION operator * (FLOAT, CONST D3DXQUATERNION& ); + + BOOL operator == ( CONST D3DXQUATERNION& ) const; + BOOL operator != ( CONST D3DXQUATERNION& ) const; + +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXQUATERNION, *LPD3DXQUATERNION; + + +//=========================================================================== +// +// Planes +// +//=========================================================================== +typedef struct D3DXPLANE +{ +#ifdef __cplusplus +public: + D3DXPLANE() {}; + D3DXPLANE( CONST FLOAT* ); + D3DXPLANE( CONST D3DXFLOAT16* ); + D3DXPLANE( FLOAT a, FLOAT b, FLOAT c, FLOAT d ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXPLANE& operator *= ( FLOAT ); + D3DXPLANE& operator /= ( FLOAT ); + + // unary operators + D3DXPLANE operator + () const; + D3DXPLANE operator - () const; + + // binary operators + D3DXPLANE operator * ( FLOAT ) const; + D3DXPLANE operator / ( FLOAT ) const; + + friend D3DXPLANE operator * ( FLOAT, CONST D3DXPLANE& ); + + BOOL operator == ( CONST D3DXPLANE& ) const; + BOOL operator != ( CONST D3DXPLANE& ) const; + +#endif //__cplusplus + FLOAT a, b, c, d; +} D3DXPLANE, *LPD3DXPLANE; + + +//=========================================================================== +// +// Colors +// +//=========================================================================== + +typedef struct D3DXCOLOR +{ +#ifdef __cplusplus +public: + D3DXCOLOR() {}; + D3DXCOLOR( UINT argb ); + D3DXCOLOR( CONST FLOAT * ); + D3DXCOLOR( CONST D3DXFLOAT16 * ); + D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a ); + + // casting + operator UINT () const; + + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXCOLOR& operator += ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator -= ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator *= ( FLOAT ); + D3DXCOLOR& operator /= ( FLOAT ); + + // unary operators + D3DXCOLOR operator + () const; + D3DXCOLOR operator - () const; + + // binary operators + D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator * ( FLOAT ) const; + D3DXCOLOR operator / ( FLOAT ) const; + + friend D3DXCOLOR operator * ( FLOAT, CONST D3DXCOLOR& ); + + BOOL operator == ( CONST D3DXCOLOR& ) const; + BOOL operator != ( CONST D3DXCOLOR& ) const; + +#endif //__cplusplus + FLOAT r, g, b, a; +} D3DXCOLOR, *LPD3DXCOLOR; + + + +//=========================================================================== +// +// D3DX math functions: +// +// NOTE: +// * All these functions can take the same object as in and out parameters. +// +// * Out parameters are typically also returned as return values, so that +// the output of one function may be used as a parameter to another. +// +//=========================================================================== + +//-------------------------- +// Float16 +//-------------------------- + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Converts an array 32-bit floats to 16-bit floats +D3DXFLOAT16* WINAPI D3DXFloat32To16Array + ( D3DXFLOAT16 *pOut, CONST FLOAT *pIn, UINT n ); + +// Converts an array 16-bit floats to 32-bit floats +FLOAT* WINAPI D3DXFloat16To32Array + ( __out_ecount(n) FLOAT *pOut, __in_ecount(n) CONST D3DXFLOAT16 *pIn, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 2D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec2Length + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2LengthSq + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2Dot + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Z component of ((x1,y1,0) cross (x2,y2,0)) +FLOAT D3DXVec2CCW + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Add + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Subtract + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2) +D3DXVECTOR2* D3DXVec2Minimize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2) +D3DXVECTOR2* D3DXVec2Maximize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Scale + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR2* D3DXVec2Lerp + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR2* WINAPI D3DXVec2Normalize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR2* WINAPI D3DXVec2Hermite + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pT1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR2* WINAPI D3DXVec2CatmullRom + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV0, CONST D3DXVECTOR2 *pV1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR2* WINAPI D3DXVec2BaryCentric + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + CONST D3DXVECTOR2 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, 0, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec2Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 1) by matrix, project result back into w=1. +D3DXVECTOR2* WINAPI D3DXVec2TransformCoord + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 0) by matrix. +D3DXVECTOR2* WINAPI D3DXVec2TransformNormal + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform Array (x, y, 0, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec2TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n); + +// Transform Array (x, y, 0, 1) by matrix, project result back into w=1. +D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray + ( D3DXVECTOR2 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform Array (x, y, 0, 0) by matrix. +D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray + ( D3DXVECTOR2 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + + + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 3D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec3Length + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3LengthSq + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3Dot + ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Cross + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Add + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Subtract + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR3* D3DXVec3Minimize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR3* D3DXVec3Maximize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Scale + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR3* D3DXVec3Lerp + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR3* WINAPI D3DXVec3Normalize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR3* WINAPI D3DXVec3Hermite + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pT1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR3* WINAPI D3DXVec3CatmullRom + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV0, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR3* WINAPI D3DXVec3BaryCentric + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, z, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec3Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 1) by matrix, project result back into w=1. +D3DXVECTOR3* WINAPI D3DXVec3TransformCoord + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the +// transpose of the inverse of the matrix you would use to transform a coord. +D3DXVECTOR3* WINAPI D3DXVec3TransformNormal + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + + +// Transform Array (x, y, z, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec3TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform Array (x, y, z, 1) by matrix, project result back into w=1. +D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the +// transpose of the inverse of the matrix you would use to transform a coord. +D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Project vector from object space into screen space +D3DXVECTOR3* WINAPI D3DXVec3Project + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3D10_VIEWPORT *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +// Project vector from screen space into object space +D3DXVECTOR3* WINAPI D3DXVec3Unproject + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3D10_VIEWPORT *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +// Project vector Array from object space into screen space +D3DXVECTOR3* WINAPI D3DXVec3ProjectArray + ( D3DXVECTOR3 *pOut, UINT OutStride,CONST D3DXVECTOR3 *pV, UINT VStride,CONST D3D10_VIEWPORT *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld, UINT n); + +// Project vector Array from screen space into object space +D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3D10_VIEWPORT *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld, UINT n); + + +#ifdef __cplusplus +} +#endif + + + +//-------------------------- +// 4D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec4Length + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4LengthSq + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4Dot + ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ); + +D3DXVECTOR4* D3DXVec4Add + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Subtract + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR4* D3DXVec4Minimize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR4* D3DXVec4Maximize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Scale + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR4* D3DXVec4Lerp + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Cross-product in 4 dimensions. +D3DXVECTOR4* WINAPI D3DXVec4Cross + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3); + +D3DXVECTOR4* WINAPI D3DXVec4Normalize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR4* WINAPI D3DXVec4Hermite + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pT1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR4* WINAPI D3DXVec4CatmullRom + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV0, CONST D3DXVECTOR4 *pV1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR4* WINAPI D3DXVec4BaryCentric + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3, FLOAT f, FLOAT g); + +// Transform vector by matrix. +D3DXVECTOR4* WINAPI D3DXVec4Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); + +// Transform vector array by matrix. +D3DXVECTOR4* WINAPI D3DXVec4TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR4 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 4D Matrix +//-------------------------- + +// inline + +D3DXMATRIX* D3DXMatrixIdentity + ( D3DXMATRIX *pOut ); + +BOOL D3DXMatrixIsIdentity + ( CONST D3DXMATRIX *pM ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +FLOAT WINAPI D3DXMatrixDeterminant + ( CONST D3DXMATRIX *pM ); + +HRESULT WINAPI D3DXMatrixDecompose + ( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation, + D3DXVECTOR3 *pOutTranslation, CONST D3DXMATRIX *pM ); + +D3DXMATRIX* WINAPI D3DXMatrixTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); + +// Matrix multiplication. The result represents the transformation M2 +// followed by the transformation M1. (Out = M1 * M2) +D3DXMATRIX* WINAPI D3DXMatrixMultiply + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Matrix multiplication, followed by a transpose. (Out = T(M1 * M2)) +D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Calculate inverse of matrix. Inversion my fail, in which case NULL will +// be returned. The determinant of pM is also returned it pfDeterminant +// is non-NULL. +D3DXMATRIX* WINAPI D3DXMatrixInverse + ( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); + +// Build a matrix which scales by (sx, sy, sz) +D3DXMATRIX* WINAPI D3DXMatrixScaling + ( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz ); + +// Build a matrix which translates by (x, y, z) +D3DXMATRIX* WINAPI D3DXMatrixTranslation + ( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); + +// Build a matrix which rotates around the X axis +D3DXMATRIX* WINAPI D3DXMatrixRotationX + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Y axis +D3DXMATRIX* WINAPI D3DXMatrixRotationY + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Z axis +D3DXMATRIX* WINAPI D3DXMatrixRotationZ + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around an arbitrary axis +D3DXMATRIX* WINAPI D3DXMatrixRotationAxis + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Build a matrix from a quaternion +D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion + ( D3DXMATRIX *pOut, CONST D3DXQUATERNION *pQ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXMATRIX* WINAPI D3DXMatrixRotationYawPitchRoll + ( D3DXMATRIX *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + +// Build transformation matrix. NULL arguments are treated as identity. +// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixTransformation + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pScalingCenter, + CONST D3DXQUATERNION *pScalingRotation, CONST D3DXVECTOR3 *pScaling, + CONST D3DXVECTOR3 *pRotationCenter, CONST D3DXQUATERNION *pRotation, + CONST D3DXVECTOR3 *pTranslation); + +// Build 2D transformation matrix in XY plane. NULL arguments are treated as identity. +// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixTransformation2D + ( D3DXMATRIX *pOut, CONST D3DXVECTOR2* pScalingCenter, + FLOAT ScalingRotation, CONST D3DXVECTOR2* pScaling, + CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, + CONST D3DXVECTOR2* pTranslation); + +// Build affine transformation matrix. NULL arguments are treated as identity. +// Mout = Ms * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR3 *pRotationCenter, + CONST D3DXQUATERNION *pRotation, CONST D3DXVECTOR3 *pTranslation); + +// Build 2D affine transformation matrix in XY plane. NULL arguments are treated as identity. +// Mout = Ms * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR2* pRotationCenter, + FLOAT Rotation, CONST D3DXVECTOR2* pTranslation); + +// Build a lookat matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtRH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a lookat matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtLH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a matrix which flattens geometry into a plane, as if casting +// a shadow from a light. +D3DXMATRIX* WINAPI D3DXMatrixShadow + ( D3DXMATRIX *pOut, CONST D3DXVECTOR4 *pLight, + CONST D3DXPLANE *pPlane ); + +// Build a matrix which reflects the coordinate system about a plane +D3DXMATRIX* WINAPI D3DXMatrixReflect + ( D3DXMATRIX *pOut, CONST D3DXPLANE *pPlane ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Quaternion +//-------------------------- + +// inline + +FLOAT D3DXQuaternionLength + ( CONST D3DXQUATERNION *pQ ); + +// Length squared, or "norm" +FLOAT D3DXQuaternionLengthSq + ( CONST D3DXQUATERNION *pQ ); + +FLOAT D3DXQuaternionDot + ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ); + +// (0, 0, 0, 1) +D3DXQUATERNION* D3DXQuaternionIdentity + ( D3DXQUATERNION *pOut ); + +BOOL D3DXQuaternionIsIdentity + ( CONST D3DXQUATERNION *pQ ); + +// (-x, -y, -z, w) +D3DXQUATERNION* D3DXQuaternionConjugate + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Compute a quaternin's axis and angle of rotation. Expects unit quaternions. +void WINAPI D3DXQuaternionToAxisAngle + ( CONST D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, FLOAT *pAngle ); + +// Build a quaternion from a rotation matrix. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix + ( D3DXQUATERNION *pOut, CONST D3DXMATRIX *pM); + +// Rotation about arbitrary axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis + ( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll + ( D3DXQUATERNION *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + +// Quaternion multiplication. The result represents the rotation Q2 +// followed by the rotation Q1. (Out = Q2 * Q1) +D3DXQUATERNION* WINAPI D3DXQuaternionMultiply + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2 ); + +D3DXQUATERNION* WINAPI D3DXQuaternionNormalize + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Conjugate and re-norm +D3DXQUATERNION* WINAPI D3DXQuaternionInverse + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects unit quaternions. +// if q = (cos(theta), sin(theta) * v); ln(q) = (0, theta * v) +D3DXQUATERNION* WINAPI D3DXQuaternionLn + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects pure quaternions. (w == 0) w is ignored in calculation. +// if q = (0, theta * v); exp(q) = (cos(theta), sin(theta) * v) +D3DXQUATERNION* WINAPI D3DXQuaternionExp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Spherical linear interpolation between Q1 (t == 0) and Q2 (t == 1). +// Expects unit quaternions. +D3DXQUATERNION* WINAPI D3DXQuaternionSlerp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, FLOAT t ); + +// Spherical quadrangle interpolation. +// Slerp(Slerp(Q1, C, t), Slerp(A, B, t), 2t(1-t)) +D3DXQUATERNION* WINAPI D3DXQuaternionSquad + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pA, CONST D3DXQUATERNION *pB, + CONST D3DXQUATERNION *pC, FLOAT t ); + +// Setup control points for spherical quadrangle interpolation +// from Q1 to Q2. The control points are chosen in such a way +// to ensure the continuity of tangents with adjacent segments. +void WINAPI D3DXQuaternionSquadSetup + ( D3DXQUATERNION *pAOut, D3DXQUATERNION *pBOut, D3DXQUATERNION *pCOut, + CONST D3DXQUATERNION *pQ0, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3 ); + +// Barycentric interpolation. +// Slerp(Slerp(Q1, Q2, f+g), Slerp(Q1, Q3, f+g), g/(f+g)) +D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3, + FLOAT f, FLOAT g ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Plane +//-------------------------- + +// inline + +// ax + by + cz + dw +FLOAT D3DXPlaneDot + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV); + +// ax + by + cz + d +FLOAT D3DXPlaneDotCoord + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +// ax + by + cz +FLOAT D3DXPlaneDotNormal + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +D3DXPLANE* D3DXPlaneScale + (D3DXPLANE *pOut, CONST D3DXPLANE *pP, FLOAT s); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Normalize plane (so that |a,b,c| == 1) +D3DXPLANE* WINAPI D3DXPlaneNormalize + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP); + +// Find the intersection between a plane and a line. If the line is +// parallel to the plane, NULL is returned. +D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine + ( D3DXVECTOR3 *pOut, CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2); + +// Construct a plane from a point and a normal +D3DXPLANE* WINAPI D3DXPlaneFromPointNormal + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pPoint, CONST D3DXVECTOR3 *pNormal); + +// Construct a plane from 3 points +D3DXPLANE* WINAPI D3DXPlaneFromPoints + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3); + +// Transform a plane by a matrix. The vector (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +D3DXPLANE* WINAPI D3DXPlaneTransform + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); + +// Transform an array of planes by a matrix. The vectors (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +D3DXPLANE* WINAPI D3DXPlaneTransformArray + ( D3DXPLANE *pOut, UINT OutStride, CONST D3DXPLANE *pP, UINT PStride, CONST D3DXMATRIX *pM, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Color +//-------------------------- + +// inline + +// (1-r, 1-g, 1-b, a) +D3DXCOLOR* D3DXColorNegative + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC); + +D3DXCOLOR* D3DXColorAdd + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorSubtract + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorScale + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// (r1*r2, g1*g2, b1*b2, a1*a2) +D3DXCOLOR* D3DXColorModulate + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +// Linear interpolation of r,g,b, and a. C1 + s(C2-C1) +D3DXCOLOR* D3DXColorLerp + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Interpolate r,g,b between desaturated color and color. +// DesaturatedColor + s(Color - DesaturatedColor) +D3DXCOLOR* WINAPI D3DXColorAdjustSaturation + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// Interpolate r,g,b between 50% grey and color. Grey + s(Color - Grey) +D3DXCOLOR* WINAPI D3DXColorAdjustContrast + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT c); + +#ifdef __cplusplus +} +#endif + + + + +//-------------------------- +// Misc +//-------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +// Calculate Fresnel term given the cosine of theta (likely obtained by +// taking the dot of two normals), and the refraction index of the material. +FLOAT WINAPI D3DXFresnelTerm + (FLOAT CosTheta, FLOAT RefractionIndex); + +#ifdef __cplusplus +} +#endif + + + +//=========================================================================== +// +// Matrix Stack +// +//=========================================================================== + +typedef interface ID3DXMatrixStack ID3DXMatrixStack; +typedef interface ID3DXMatrixStack *LPD3DXMATRIXSTACK; + +// {C7885BA7-F990-4fe7-922D-8515E477DD85} +DEFINE_GUID(IID_ID3DXMatrixStack, +0xc7885ba7, 0xf990, 0x4fe7, 0x92, 0x2d, 0x85, 0x15, 0xe4, 0x77, 0xdd, 0x85); + + +#undef INTERFACE +#define INTERFACE ID3DXMatrixStack + +DECLARE_INTERFACE_(ID3DXMatrixStack, IUnknown) +{ + // + // IUnknown methods + // + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + // + // ID3DXMatrixStack methods + // + + // Pops the top of the stack, returns the current top + // *after* popping the top. + STDMETHOD(Pop)(THIS) PURE; + + // Pushes the stack by one, duplicating the current matrix. + STDMETHOD(Push)(THIS) PURE; + + // Loads identity in the current matrix. + STDMETHOD(LoadIdentity)(THIS) PURE; + + // Loads the given matrix into the current matrix + STDMETHOD(LoadMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right-Multiplies the given matrix to the current matrix. + // (transformation is about the current world origin) + STDMETHOD(MultMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Left-Multiplies the given matrix to the current matrix + // (transformation is about the local origin of the object) + STDMETHOD(MultMatrixLocal)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the current world origin) + STDMETHOD(RotateAxis) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + STDMETHOD(RotateAxisLocal) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // current world origin) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRoll) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // local origin of the object) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRollLocal) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Right multiply the current matrix with the computed scale + // matrix. (transformation is about the current world origin) + STDMETHOD(Scale)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Left multiply the current matrix with the computed scale + // matrix. (transformation is about the local origin of the object) + STDMETHOD(ScaleLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Right multiply the current matrix with the computed translation + // matrix. (transformation is about the current world origin) + STDMETHOD(Translate)(THIS_ FLOAT x, FLOAT y, FLOAT z ) PURE; + + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + STDMETHOD(TranslateLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Obtain the current matrix at the top of the stack + STDMETHOD_(D3DXMATRIX*, GetTop)(THIS) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI + D3DXCreateMatrixStack( + UINT Flags, + LPD3DXMATRIXSTACK* ppStack); + +#ifdef __cplusplus +} +#endif + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================ +// +// Basic Spherical Harmonic math routines +// +//============================================================================ + +#define D3DXSH_MINORDER 2 +#define D3DXSH_MAXORDER 6 + +//============================================================================ +// +// D3DXSHEvalDirection: +// -------------------- +// Evaluates the Spherical Harmonic basis functions +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction to evaluate in - assumed to be normalized +// +//============================================================================ + +FLOAT* WINAPI D3DXSHEvalDirection + ( FLOAT *pOut, UINT Order, CONST D3DXVECTOR3 *pDir ); + +//============================================================================ +// +// D3DXSHRotate: +// -------------------- +// Rotates SH vector by a rotation matrix +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned (should not alias with pIn.) +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pMatrix +// Matrix used for rotation - rotation sub matrix should be orthogonal +// and have a unit determinant. +// pIn +// Input SH coeffs (rotated), incorect results if this is also output. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHRotate + ( __out_ecount(Order*Order) FLOAT *pOut, UINT Order, CONST D3DXMATRIX *pMatrix, CONST FLOAT *pIn ); + +//============================================================================ +// +// D3DXSHRotateZ: +// -------------------- +// Rotates the SH vector in the Z axis by an angle +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned (should not alias with pIn.) +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// Angle +// Angle in radians to rotate around the Z axis. +// pIn +// Input SH coeffs (rotated), incorect results if this is also output. +// +//============================================================================ + + +FLOAT* WINAPI D3DXSHRotateZ + ( FLOAT *pOut, UINT Order, FLOAT Angle, CONST FLOAT *pIn ); + +//============================================================================ +// +// D3DXSHAdd: +// -------------------- +// Adds two SH vectors, pOut[i] = pA[i] + pB[i]; +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pA +// Input SH coeffs. +// pB +// Input SH coeffs (second vector.) +// +//============================================================================ + +FLOAT* WINAPI D3DXSHAdd + ( __out_ecount(Order*Order) FLOAT *pOut, UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); + +//============================================================================ +// +// D3DXSHScale: +// -------------------- +// Adds two SH vectors, pOut[i] = pA[i]*Scale; +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pIn +// Input SH coeffs. +// Scale +// Scale factor. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHScale + ( __out_ecount(Order*Order) FLOAT *pOut, UINT Order, CONST FLOAT *pIn, CONST FLOAT Scale ); + +//============================================================================ +// +// D3DXSHDot: +// -------------------- +// Computes the dot product of two SH vectors +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pA +// Input SH coeffs. +// pB +// Second set of input SH coeffs. +// +//============================================================================ + +FLOAT WINAPI D3DXSHDot + ( UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); + +//============================================================================ +// +// D3DXSHMultiply[O]: +// -------------------- +// Computes the product of two functions represented using SH (f and g), where: +// pOut[i] = int(y_i(s) * f(s) * g(s)), where y_i(s) is the ith SH basis +// function, f(s) and g(s) are SH functions (sum_i(y_i(s)*c_i)). The order O +// determines the lengths of the arrays, where there should always be O^2 +// coefficients. In general the product of two SH functions of order O generates +// and SH function of order 2*O - 1, but we truncate the result. This means +// that the product commutes (f*g == g*f) but doesn't associate +// (f*(g*h) != (f*g)*h. +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// pF +// Input SH coeffs for first function. +// pG +// Second set of input SH coeffs. +// +//============================================================================ + +__out_ecount(4) FLOAT* WINAPI D3DXSHMultiply2(__out_ecount(4) FLOAT *pOut,__in_ecount(4) CONST FLOAT *pF,__in_ecount(4) CONST FLOAT *pG); +__out_ecount(9) FLOAT* WINAPI D3DXSHMultiply3(__out_ecount(9) FLOAT *pOut,__in_ecount(9) CONST FLOAT *pF,__in_ecount(9) CONST FLOAT *pG); +__out_ecount(16) FLOAT* WINAPI D3DXSHMultiply4(__out_ecount(16) FLOAT *pOut,__in_ecount(16) CONST FLOAT *pF,__in_ecount(16) CONST FLOAT *pG); +__out_ecount(25) FLOAT* WINAPI D3DXSHMultiply5(__out_ecount(25) FLOAT *pOut,__in_ecount(25) CONST FLOAT *pF,__in_ecount(25) CONST FLOAT *pG); +__out_ecount(36) FLOAT* WINAPI D3DXSHMultiply6(__out_ecount(36) FLOAT *pOut,__in_ecount(36) CONST FLOAT *pF,__in_ecount(36) CONST FLOAT *pG); + + +//============================================================================ +// +// Basic Spherical Harmonic lighting routines +// +//============================================================================ + +//============================================================================ +// +// D3DXSHEvalDirectionalLight: +// -------------------- +// Evaluates a directional light and returns spectral SH data. The output +// vector is computed so that if the intensity of R/G/B is unit the resulting +// exit radiance of a point directly under the light on a diffuse object with +// an albedo of 1 would be 1.0. This will compute 3 spectral samples, pROut +// has to be specified, while pGout and pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction light is coming from (assumed to be normalized.) +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalDirectionalLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + __out_ecount_opt(Order*Order) FLOAT *pROut, + __out_ecount_opt(Order*Order) FLOAT *pGOut, + __out_ecount_opt(Order*Order) FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalSphericalLight: +// -------------------- +// Evaluates a spherical light and returns spectral SH data. There is no +// normalization of the intensity of the light like there is for directional +// lights, care has to be taken when specifiying the intensities. This will +// compute 3 spectral samples, pROut has to be specified, while pGout and +// pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pPos +// Position of light - reciever is assumed to be at the origin. +// Radius +// Radius of the spherical light source. +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalSphericalLight + ( UINT Order, CONST D3DXVECTOR3 *pPos, FLOAT Radius, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + __out_ecount_opt(Order*Order) FLOAT *pROut, + __out_ecount_opt(Order*Order) FLOAT *pGOut, + __out_ecount_opt(Order*Order) FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalConeLight: +// -------------------- +// Evaluates a light that is a cone of constant intensity and returns spectral +// SH data. The output vector is computed so that if the intensity of R/G/B is +// unit the resulting exit radiance of a point directly under the light oriented +// in the cone direction on a diffuse object with an albedo of 1 would be 1.0. +// This will compute 3 spectral samples, pROut has to be specified, while pGout +// and pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction light is coming from (assumed to be normalized.) +// Radius +// Radius of cone in radians. +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalConeLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, FLOAT Radius, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + __out_ecount_opt(Order*Order) FLOAT *pROut, + __out_ecount_opt(Order*Order) FLOAT *pGOut, + __out_ecount_opt(Order*Order) FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalHemisphereLight: +// -------------------- +// Evaluates a light that is a linear interpolant between two colors over the +// sphere. The interpolant is linear along the axis of the two points, not +// over the surface of the sphere (ie: if the axis was (0,0,1) it is linear in +// Z, not in the azimuthal angle.) The resulting spherical lighting function +// is normalized so that a point on a perfectly diffuse surface with no +// shadowing and a normal pointed in the direction pDir would result in exit +// radiance with a value of 1 if the top color was white and the bottom color +// was black. This is a very simple model where Top represents the intensity +// of the "sky" and Bottom represents the intensity of the "ground". +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Axis of the hemisphere. +// Top +// Color of the upper hemisphere. +// Bottom +// Color of the lower hemisphere. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green +// pBOut +// Output SH vector for Blue +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalHemisphereLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, D3DXCOLOR Top, D3DXCOLOR Bottom, + __out_ecount_opt(Order*Order) FLOAT *pROut, + __out_ecount_opt(Order*Order) FLOAT *pGOut, + __out_ecount_opt(Order*Order) FLOAT *pBOut ); + +// Math intersection functions + +BOOL WINAPI D3DXIntersectTri +( + CONST D3DXVECTOR3 *p0, // Triangle vertex 0 position + CONST D3DXVECTOR3 *p1, // Triangle vertex 1 position + CONST D3DXVECTOR3 *p2, // Triangle vertex 2 position + CONST D3DXVECTOR3 *pRayPos, // Ray origin + CONST D3DXVECTOR3 *pRayDir, // Ray direction + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist); // Ray-Intersection Parameter Distance + +BOOL WINAPI + D3DXSphereBoundProbe( + CONST D3DXVECTOR3 *pCenter, + FLOAT Radius, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + +BOOL WINAPI + D3DXBoxBoundProbe( + CONST D3DXVECTOR3 *pMin, + CONST D3DXVECTOR3 *pMax, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + +HRESULT WINAPI + D3DXComputeBoundingSphere( + CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position + DWORD NumVertices, + DWORD dwStride, // count in bytes to subsequent position vectors + D3DXVECTOR3 *pCenter, + FLOAT *pRadius); + +HRESULT WINAPI + D3DXComputeBoundingBox( + CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position + DWORD NumVertices, + DWORD dwStride, // count in bytes to subsequent position vectors + D3DXVECTOR3 *pMin, + D3DXVECTOR3 *pMax); + + +/////////////////////////////////////////////////////////////////////////// +// CPU Optimization: +/////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------- +// D3DX_CPU_OPTIMIZATION flags: +// ---------------------------- +// D3DX_NOT_OPTIMIZED Use Intel Pentium optimizations +// D3DX_3DNOW_OPTIMIZED Use AMD 3DNow optimizations +// D3DX_SSE_OPTIMIZED Use Intel Pentium III SSE optimizations +// D3DX_SSE2_OPTIMIZED Use Intel Pentium IV SSE2 optimizations +//------------------------------------------------------------------------- + + +typedef enum _D3DX_CPU_OPTIMIZATION +{ + D3DX_NOT_OPTIMIZED = 0, + D3DX_3DNOW_OPTIMIZED, + D3DX_SSE2_OPTIMIZED, + D3DX_SSE_OPTIMIZED +} D3DX_CPU_OPTIMIZATION; + + +//------------------------------------------------------------------------- +// D3DXCpuOptimizations: +// --------------------- +// Enables or disables CPU optimizations. Returns the type of CPU, which +// was detected, and for which optimizations exist. +// +// Parameters: +// Enable +// TRUE to enable CPU optimizations. FALSE to disable. +//------------------------------------------------------------------------- + +D3DX_CPU_OPTIMIZATION WINAPI + D3DXCpuOptimizations(BOOL Enable); + +#ifdef __cplusplus +} +#endif + + +#include "D3DX10math.inl" + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4201) +#endif + +#endif // __D3DX9MATH_H__ + diff --git a/dxsdk/Include/D3DX10math.inl b/dxsdk/Include/D3DX10math.inl new file mode 100644 index 0000000..56f1163 --- /dev/null +++ b/dxsdk/Include/D3DX10math.inl @@ -0,0 +1,2228 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx10math.inl +// Content: D3DX10 math inline functions +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DXMATH_INL__ +#define __D3DXMATH_INL__ + + +//=========================================================================== +// +// Inline Class Methods +// +//=========================================================================== + +#ifdef __cplusplus + +//-------------------------- +// Float16 +//-------------------------- + +D3DX10INLINE +D3DXFLOAT16::D3DXFLOAT16( FLOAT f ) +{ + D3DXFloat32To16Array(this, &f, 1); +} + +D3DX10INLINE +D3DXFLOAT16::D3DXFLOAT16( CONST D3DXFLOAT16& f ) +{ + value = f.value; +} + +// casting +D3DX10INLINE +D3DXFLOAT16::operator FLOAT () +{ + FLOAT f; + D3DXFloat16To32Array(&f, this, 1); + return f; +} + +// binary operators +D3DX10INLINE BOOL +D3DXFLOAT16::operator == ( CONST D3DXFLOAT16& f ) const +{ + // At least one is NaN + if(((value & D3DX_16F_EXP_MASK) == D3DX_16F_EXP_MASK && (value & D3DX_16F_FRAC_MASK)) + || ((f.value & D3DX_16F_EXP_MASK) == D3DX_16F_EXP_MASK && (f.value & D3DX_16F_FRAC_MASK))) + return false; + // +/- Zero + else if((value & ~D3DX_16F_SIGN_MASK) == 0 && (f.value & ~D3DX_16F_SIGN_MASK) == 0) + return true; + else + return value == f.value; +} + +D3DX10INLINE BOOL +D3DXFLOAT16::operator != ( CONST D3DXFLOAT16& f ) const +{ + // At least one is NaN + if(((value & D3DX_16F_EXP_MASK) == D3DX_16F_EXP_MASK && (value & D3DX_16F_FRAC_MASK)) + || ((f.value & D3DX_16F_EXP_MASK) == D3DX_16F_EXP_MASK && (f.value & D3DX_16F_FRAC_MASK))) + return true; + // +/- Zero + else if((value & ~D3DX_16F_SIGN_MASK) == 0 && (f.value & ~D3DX_16F_SIGN_MASK) == 0) + return false; + else + return value != f.value; +} + + +//-------------------------- +// 2D Vector +//-------------------------- + +D3DX10INLINE +D3DXVECTOR2::D3DXVECTOR2( CONST FLOAT *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; +} + +D3DX10INLINE +D3DXVECTOR2::D3DXVECTOR2( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 2); +} + +D3DX10INLINE +D3DXVECTOR2::D3DXVECTOR2( FLOAT fx, FLOAT fy ) +{ + x = fx; + y = fy; +} + + +// casting +D3DX10INLINE +D3DXVECTOR2::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DX10INLINE +D3DXVECTOR2::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DX10INLINE D3DXVECTOR2& +D3DXVECTOR2::operator += ( CONST D3DXVECTOR2& v ) +{ + x += v.x; + y += v.y; + return *this; +} + +D3DX10INLINE D3DXVECTOR2& +D3DXVECTOR2::operator -= ( CONST D3DXVECTOR2& v ) +{ + x -= v.x; + y -= v.y; + return *this; +} + +D3DX10INLINE D3DXVECTOR2& +D3DXVECTOR2::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + return *this; +} + +D3DX10INLINE D3DXVECTOR2& +D3DXVECTOR2::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + return *this; +} + + +// unary operators +D3DX10INLINE D3DXVECTOR2 +D3DXVECTOR2::operator + () const +{ + return *this; +} + +D3DX10INLINE D3DXVECTOR2 +D3DXVECTOR2::operator - () const +{ + return D3DXVECTOR2(-x, -y); +} + + +// binary operators +D3DX10INLINE D3DXVECTOR2 +D3DXVECTOR2::operator + ( CONST D3DXVECTOR2& v ) const +{ + return D3DXVECTOR2(x + v.x, y + v.y); +} + +D3DX10INLINE D3DXVECTOR2 +D3DXVECTOR2::operator - ( CONST D3DXVECTOR2& v ) const +{ + return D3DXVECTOR2(x - v.x, y - v.y); +} + +D3DX10INLINE D3DXVECTOR2 +D3DXVECTOR2::operator * ( FLOAT f ) const +{ + return D3DXVECTOR2(x * f, y * f); +} + +D3DX10INLINE D3DXVECTOR2 +D3DXVECTOR2::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR2(x * fInv, y * fInv); +} + +D3DX10INLINE D3DXVECTOR2 +operator * ( FLOAT f, CONST D3DXVECTOR2& v ) +{ + return D3DXVECTOR2(f * v.x, f * v.y); +} + +D3DX10INLINE BOOL +D3DXVECTOR2::operator == ( CONST D3DXVECTOR2& v ) const +{ + return x == v.x && y == v.y; +} + +D3DX10INLINE BOOL +D3DXVECTOR2::operator != ( CONST D3DXVECTOR2& v ) const +{ + return x != v.x || y != v.y; +} + + + +//-------------------------- +// 2D Vector (16 bit) +//-------------------------- + +D3DX10INLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 2); +} + +D3DX10INLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + *((UINT *) &x) = *((UINT *) &pf[0]); +} + +D3DX10INLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy ) +{ + x = fx; + y = fy; +} + + +// casting +D3DX10INLINE +D3DXVECTOR2_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DX10INLINE +D3DXVECTOR2_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DX10INLINE BOOL +D3DXVECTOR2_16F::operator == ( CONST D3DXVECTOR2_16F &v ) const +{ + return x == v.x && y == v.y; +} + +D3DX10INLINE BOOL +D3DXVECTOR2_16F::operator != ( CONST D3DXVECTOR2_16F &v ) const +{ + return x != v.x || y != v.y; +} + + +//-------------------------- +// 3D Vector +//-------------------------- +D3DX10INLINE +D3DXVECTOR3::D3DXVECTOR3( CONST FLOAT *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; +} + +D3DX10INLINE +D3DXVECTOR3::D3DXVECTOR3( CONST D3DVECTOR& v ) +{ + x = v.x; + y = v.y; + z = v.z; +} + +D3DX10INLINE +D3DXVECTOR3::D3DXVECTOR3( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 3); +} + +D3DX10INLINE +D3DXVECTOR3::D3DXVECTOR3( FLOAT fx, FLOAT fy, FLOAT fz ) +{ + x = fx; + y = fy; + z = fz; +} + + +// casting +D3DX10INLINE +D3DXVECTOR3::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DX10INLINE +D3DXVECTOR3::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DX10INLINE D3DXVECTOR3& +D3DXVECTOR3::operator += ( CONST D3DXVECTOR3& v ) +{ + x += v.x; + y += v.y; + z += v.z; + return *this; +} + +D3DX10INLINE D3DXVECTOR3& +D3DXVECTOR3::operator -= ( CONST D3DXVECTOR3& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + return *this; +} + +D3DX10INLINE D3DXVECTOR3& +D3DXVECTOR3::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + return *this; +} + +D3DX10INLINE D3DXVECTOR3& +D3DXVECTOR3::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + return *this; +} + + +// unary operators +D3DX10INLINE D3DXVECTOR3 +D3DXVECTOR3::operator + () const +{ + return *this; +} + +D3DX10INLINE D3DXVECTOR3 +D3DXVECTOR3::operator - () const +{ + return D3DXVECTOR3(-x, -y, -z); +} + + +// binary operators +D3DX10INLINE D3DXVECTOR3 +D3DXVECTOR3::operator + ( CONST D3DXVECTOR3& v ) const +{ + return D3DXVECTOR3(x + v.x, y + v.y, z + v.z); +} + +D3DX10INLINE D3DXVECTOR3 +D3DXVECTOR3::operator - ( CONST D3DXVECTOR3& v ) const +{ + return D3DXVECTOR3(x - v.x, y - v.y, z - v.z); +} + +D3DX10INLINE D3DXVECTOR3 +D3DXVECTOR3::operator * ( FLOAT f ) const +{ + return D3DXVECTOR3(x * f, y * f, z * f); +} + +D3DX10INLINE D3DXVECTOR3 +D3DXVECTOR3::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR3(x * fInv, y * fInv, z * fInv); +} + + +D3DX10INLINE D3DXVECTOR3 +operator * ( FLOAT f, CONST struct D3DXVECTOR3& v ) +{ + return D3DXVECTOR3(f * v.x, f * v.y, f * v.z); +} + + +D3DX10INLINE BOOL +D3DXVECTOR3::operator == ( CONST D3DXVECTOR3& v ) const +{ + return x == v.x && y == v.y && z == v.z; +} + +D3DX10INLINE BOOL +D3DXVECTOR3::operator != ( CONST D3DXVECTOR3& v ) const +{ + return x != v.x || y != v.y || z != v.z; +} + + + +//-------------------------- +// 3D Vector (16 bit) +//-------------------------- + +D3DX10INLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 3); +} + +D3DX10INLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DVECTOR& v ) +{ + D3DXFloat32To16Array(&x, &v.x, 1); + D3DXFloat32To16Array(&y, &v.y, 1); + D3DXFloat32To16Array(&z, &v.z, 1); +} + +D3DX10INLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + *((UINT *) &x) = *((UINT *) &pf[0]); + *((WORD *) &z) = *((WORD *) &pf[2]); +} + +D3DX10INLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy, CONST D3DXFLOAT16 &fz ) +{ + x = fx; + y = fy; + z = fz; +} + + +// casting +D3DX10INLINE +D3DXVECTOR3_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DX10INLINE +D3DXVECTOR3_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DX10INLINE BOOL +D3DXVECTOR3_16F::operator == ( CONST D3DXVECTOR3_16F &v ) const +{ + return x == v.x && y == v.y && z == v.z; +} + +D3DX10INLINE BOOL +D3DXVECTOR3_16F::operator != ( CONST D3DXVECTOR3_16F &v ) const +{ + return x != v.x || y != v.y || z != v.z; +} + + +//-------------------------- +// 4D Vector +//-------------------------- +D3DX10INLINE +D3DXVECTOR4::D3DXVECTOR4( CONST FLOAT *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; + w = pf[3]; +} + +D3DX10INLINE +D3DXVECTOR4::D3DXVECTOR4( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 4); +} + +D3DX10INLINE +D3DXVECTOR4::D3DXVECTOR4( CONST D3DVECTOR& v, FLOAT f ) +{ + x = v.x; + y = v.y; + z = v.z; + w = f; +} + +D3DX10INLINE +D3DXVECTOR4::D3DXVECTOR4( FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DX10INLINE +D3DXVECTOR4::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DX10INLINE +D3DXVECTOR4::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DX10INLINE D3DXVECTOR4& +D3DXVECTOR4::operator += ( CONST D3DXVECTOR4& v ) +{ + x += v.x; + y += v.y; + z += v.z; + w += v.w; + return *this; +} + +D3DX10INLINE D3DXVECTOR4& +D3DXVECTOR4::operator -= ( CONST D3DXVECTOR4& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + return *this; +} + +D3DX10INLINE D3DXVECTOR4& +D3DXVECTOR4::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + w *= f; + return *this; +} + +D3DX10INLINE D3DXVECTOR4& +D3DXVECTOR4::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + w *= fInv; + return *this; +} + + +// unary operators +D3DX10INLINE D3DXVECTOR4 +D3DXVECTOR4::operator + () const +{ + return *this; +} + +D3DX10INLINE D3DXVECTOR4 +D3DXVECTOR4::operator - () const +{ + return D3DXVECTOR4(-x, -y, -z, -w); +} + + +// binary operators +D3DX10INLINE D3DXVECTOR4 +D3DXVECTOR4::operator + ( CONST D3DXVECTOR4& v ) const +{ + return D3DXVECTOR4(x + v.x, y + v.y, z + v.z, w + v.w); +} + +D3DX10INLINE D3DXVECTOR4 +D3DXVECTOR4::operator - ( CONST D3DXVECTOR4& v ) const +{ + return D3DXVECTOR4(x - v.x, y - v.y, z - v.z, w - v.w); +} + +D3DX10INLINE D3DXVECTOR4 +D3DXVECTOR4::operator * ( FLOAT f ) const +{ + return D3DXVECTOR4(x * f, y * f, z * f, w * f); +} + +D3DX10INLINE D3DXVECTOR4 +D3DXVECTOR4::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR4(x * fInv, y * fInv, z * fInv, w * fInv); +} + +D3DX10INLINE D3DXVECTOR4 +operator * ( FLOAT f, CONST D3DXVECTOR4& v ) +{ + return D3DXVECTOR4(f * v.x, f * v.y, f * v.z, f * v.w); +} + + +D3DX10INLINE BOOL +D3DXVECTOR4::operator == ( CONST D3DXVECTOR4& v ) const +{ + return x == v.x && y == v.y && z == v.z && w == v.w; +} + +D3DX10INLINE BOOL +D3DXVECTOR4::operator != ( CONST D3DXVECTOR4& v ) const +{ + return x != v.x || y != v.y || z != v.z || w != v.w; +} + + + +//-------------------------- +// 4D Vector (16 bit) +//-------------------------- + +D3DX10INLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 4); +} + +D3DX10INLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + *((UINT *) &x) = *((UINT *) &pf[0]); + *((UINT *) &z) = *((UINT *) &pf[2]); +} + +D3DX10INLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXVECTOR3_16F& v, CONST D3DXFLOAT16& f ) +{ + x = v.x; + y = v.y; + z = v.z; + w = f; +} + +D3DX10INLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy, CONST D3DXFLOAT16 &fz, CONST D3DXFLOAT16 &fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DX10INLINE +D3DXVECTOR4_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DX10INLINE +D3DXVECTOR4_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DX10INLINE BOOL +D3DXVECTOR4_16F::operator == ( CONST D3DXVECTOR4_16F &v ) const +{ + return x == v.x && y == v.y && z == v.z && w == v.w; +} + +D3DX10INLINE BOOL +D3DXVECTOR4_16F::operator != ( CONST D3DXVECTOR4_16F &v ) const +{ + return x != v.x || y != v.y || z != v.z || w != v.w; +} + + +//-------------------------- +// Matrix +//-------------------------- +D3DX10INLINE +D3DXMATRIX::D3DXMATRIX( CONST FLOAT* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + memcpy(&_11, pf, sizeof(D3DXMATRIX)); +} + +D3DX10INLINE +D3DXMATRIX::D3DXMATRIX( CONST D3DMATRIX& mat ) +{ + memcpy(&_11, &mat, sizeof(D3DXMATRIX)); +} + +D3DX10INLINE +D3DXMATRIX::D3DXMATRIX( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&_11, pf, 16); +} + +D3DX10INLINE +D3DXMATRIX::D3DXMATRIX( FLOAT f11, FLOAT f12, FLOAT f13, FLOAT f14, + FLOAT f21, FLOAT f22, FLOAT f23, FLOAT f24, + FLOAT f31, FLOAT f32, FLOAT f33, FLOAT f34, + FLOAT f41, FLOAT f42, FLOAT f43, FLOAT f44 ) +{ + _11 = f11; _12 = f12; _13 = f13; _14 = f14; + _21 = f21; _22 = f22; _23 = f23; _24 = f24; + _31 = f31; _32 = f32; _33 = f33; _34 = f34; + _41 = f41; _42 = f42; _43 = f43; _44 = f44; +} + + + +// access grants +D3DX10INLINE FLOAT& +D3DXMATRIX::operator () ( UINT iRow, UINT iCol ) +{ + return m[iRow][iCol]; +} + +D3DX10INLINE FLOAT +D3DXMATRIX::operator () ( UINT iRow, UINT iCol ) const +{ + return m[iRow][iCol]; +} + + +// casting operators +D3DX10INLINE +D3DXMATRIX::operator FLOAT* () +{ + return (FLOAT *) &_11; +} + +D3DX10INLINE +D3DXMATRIX::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &_11; +} + + +// assignment operators +D3DX10INLINE D3DXMATRIX& +D3DXMATRIX::operator *= ( CONST D3DXMATRIX& mat ) +{ + D3DXMatrixMultiply(this, this, &mat); + return *this; +} + +D3DX10INLINE D3DXMATRIX& +D3DXMATRIX::operator += ( CONST D3DXMATRIX& mat ) +{ + _11 += mat._11; _12 += mat._12; _13 += mat._13; _14 += mat._14; + _21 += mat._21; _22 += mat._22; _23 += mat._23; _24 += mat._24; + _31 += mat._31; _32 += mat._32; _33 += mat._33; _34 += mat._34; + _41 += mat._41; _42 += mat._42; _43 += mat._43; _44 += mat._44; + return *this; +} + +D3DX10INLINE D3DXMATRIX& +D3DXMATRIX::operator -= ( CONST D3DXMATRIX& mat ) +{ + _11 -= mat._11; _12 -= mat._12; _13 -= mat._13; _14 -= mat._14; + _21 -= mat._21; _22 -= mat._22; _23 -= mat._23; _24 -= mat._24; + _31 -= mat._31; _32 -= mat._32; _33 -= mat._33; _34 -= mat._34; + _41 -= mat._41; _42 -= mat._42; _43 -= mat._43; _44 -= mat._44; + return *this; +} + +D3DX10INLINE D3DXMATRIX& +D3DXMATRIX::operator *= ( FLOAT f ) +{ + _11 *= f; _12 *= f; _13 *= f; _14 *= f; + _21 *= f; _22 *= f; _23 *= f; _24 *= f; + _31 *= f; _32 *= f; _33 *= f; _34 *= f; + _41 *= f; _42 *= f; _43 *= f; _44 *= f; + return *this; +} + +D3DX10INLINE D3DXMATRIX& +D3DXMATRIX::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + _11 *= fInv; _12 *= fInv; _13 *= fInv; _14 *= fInv; + _21 *= fInv; _22 *= fInv; _23 *= fInv; _24 *= fInv; + _31 *= fInv; _32 *= fInv; _33 *= fInv; _34 *= fInv; + _41 *= fInv; _42 *= fInv; _43 *= fInv; _44 *= fInv; + return *this; +} + + +// unary operators +D3DX10INLINE D3DXMATRIX +D3DXMATRIX::operator + () const +{ + return *this; +} + +D3DX10INLINE D3DXMATRIX +D3DXMATRIX::operator - () const +{ + return D3DXMATRIX(-_11, -_12, -_13, -_14, + -_21, -_22, -_23, -_24, + -_31, -_32, -_33, -_34, + -_41, -_42, -_43, -_44); +} + + +// binary operators +D3DX10INLINE D3DXMATRIX +D3DXMATRIX::operator * ( CONST D3DXMATRIX& mat ) const +{ + D3DXMATRIX matT; + D3DXMatrixMultiply(&matT, this, &mat); + return matT; +} + +D3DX10INLINE D3DXMATRIX +D3DXMATRIX::operator + ( CONST D3DXMATRIX& mat ) const +{ + return D3DXMATRIX(_11 + mat._11, _12 + mat._12, _13 + mat._13, _14 + mat._14, + _21 + mat._21, _22 + mat._22, _23 + mat._23, _24 + mat._24, + _31 + mat._31, _32 + mat._32, _33 + mat._33, _34 + mat._34, + _41 + mat._41, _42 + mat._42, _43 + mat._43, _44 + mat._44); +} + +D3DX10INLINE D3DXMATRIX +D3DXMATRIX::operator - ( CONST D3DXMATRIX& mat ) const +{ + return D3DXMATRIX(_11 - mat._11, _12 - mat._12, _13 - mat._13, _14 - mat._14, + _21 - mat._21, _22 - mat._22, _23 - mat._23, _24 - mat._24, + _31 - mat._31, _32 - mat._32, _33 - mat._33, _34 - mat._34, + _41 - mat._41, _42 - mat._42, _43 - mat._43, _44 - mat._44); +} + +D3DX10INLINE D3DXMATRIX +D3DXMATRIX::operator * ( FLOAT f ) const +{ + return D3DXMATRIX(_11 * f, _12 * f, _13 * f, _14 * f, + _21 * f, _22 * f, _23 * f, _24 * f, + _31 * f, _32 * f, _33 * f, _34 * f, + _41 * f, _42 * f, _43 * f, _44 * f); +} + +D3DX10INLINE D3DXMATRIX +D3DXMATRIX::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXMATRIX(_11 * fInv, _12 * fInv, _13 * fInv, _14 * fInv, + _21 * fInv, _22 * fInv, _23 * fInv, _24 * fInv, + _31 * fInv, _32 * fInv, _33 * fInv, _34 * fInv, + _41 * fInv, _42 * fInv, _43 * fInv, _44 * fInv); +} + + +D3DX10INLINE D3DXMATRIX +operator * ( FLOAT f, CONST D3DXMATRIX& mat ) +{ + return D3DXMATRIX(f * mat._11, f * mat._12, f * mat._13, f * mat._14, + f * mat._21, f * mat._22, f * mat._23, f * mat._24, + f * mat._31, f * mat._32, f * mat._33, f * mat._34, + f * mat._41, f * mat._42, f * mat._43, f * mat._44); +} + + +D3DX10INLINE BOOL +D3DXMATRIX::operator == ( CONST D3DXMATRIX& mat ) const +{ + return 0 == memcmp(this, &mat, sizeof(D3DXMATRIX)); +} + +D3DX10INLINE BOOL +D3DXMATRIX::operator != ( CONST D3DXMATRIX& mat ) const +{ + return 0 != memcmp(this, &mat, sizeof(D3DXMATRIX)); +} + + + +//-------------------------- +// Aligned Matrices +//-------------------------- + +D3DX10INLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST FLOAT* f ) : + D3DXMATRIX( f ) +{ +} + +D3DX10INLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST D3DMATRIX& m ) : + D3DXMATRIX( m ) +{ +} + +D3DX10INLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST D3DXFLOAT16* f ) : + D3DXMATRIX( f ) +{ +} + +D3DX10INLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ) : + D3DXMATRIX(_11, _12, _13, _14, + _21, _22, _23, _24, + _31, _32, _33, _34, + _41, _42, _43, _44) +{ +} + +#ifndef SIZE_MAX +#define SIZE_MAX ((SIZE_T)-1) +#endif + +D3DX10INLINE void* +_D3DXMATRIXA16::operator new( size_t s ) +{ + if (s > (SIZE_MAX-16)) + return NULL; + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; +} + +D3DX10INLINE void* +_D3DXMATRIXA16::operator new[]( size_t s ) +{ + if (s > (SIZE_MAX-16)) + return NULL; + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; +} + +D3DX10INLINE void +_D3DXMATRIXA16::operator delete(void* p) +{ + if(p) + { + BYTE* pb = static_cast(p); + pb -= pb[-1]; + ::delete [] pb; + } +} + +D3DX10INLINE void +_D3DXMATRIXA16::operator delete[](void* p) +{ + if(p) + { + BYTE* pb = static_cast(p); + pb -= pb[-1]; + ::delete [] pb; + } +} + +D3DX10INLINE _D3DXMATRIXA16& +_D3DXMATRIXA16::operator=(CONST D3DXMATRIX& rhs) +{ + memcpy(&_11, &rhs, sizeof(D3DXMATRIX)); + return *this; +} + + +//-------------------------- +// Quaternion +//-------------------------- + +D3DX10INLINE +D3DXQUATERNION::D3DXQUATERNION( CONST FLOAT* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; + w = pf[3]; +} + +D3DX10INLINE +D3DXQUATERNION::D3DXQUATERNION( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 4); +} + +D3DX10INLINE +D3DXQUATERNION::D3DXQUATERNION( FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DX10INLINE +D3DXQUATERNION::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DX10INLINE +D3DXQUATERNION::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DX10INLINE D3DXQUATERNION& +D3DXQUATERNION::operator += ( CONST D3DXQUATERNION& q ) +{ + x += q.x; + y += q.y; + z += q.z; + w += q.w; + return *this; +} + +D3DX10INLINE D3DXQUATERNION& +D3DXQUATERNION::operator -= ( CONST D3DXQUATERNION& q ) +{ + x -= q.x; + y -= q.y; + z -= q.z; + w -= q.w; + return *this; +} + +D3DX10INLINE D3DXQUATERNION& +D3DXQUATERNION::operator *= ( CONST D3DXQUATERNION& q ) +{ + D3DXQuaternionMultiply(this, this, &q); + return *this; +} + +D3DX10INLINE D3DXQUATERNION& +D3DXQUATERNION::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + w *= f; + return *this; +} + +D3DX10INLINE D3DXQUATERNION& +D3DXQUATERNION::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + w *= fInv; + return *this; +} + + +// unary operators +D3DX10INLINE D3DXQUATERNION +D3DXQUATERNION::operator + () const +{ + return *this; +} + +D3DX10INLINE D3DXQUATERNION +D3DXQUATERNION::operator - () const +{ + return D3DXQUATERNION(-x, -y, -z, -w); +} + + +// binary operators +D3DX10INLINE D3DXQUATERNION +D3DXQUATERNION::operator + ( CONST D3DXQUATERNION& q ) const +{ + return D3DXQUATERNION(x + q.x, y + q.y, z + q.z, w + q.w); +} + +D3DX10INLINE D3DXQUATERNION +D3DXQUATERNION::operator - ( CONST D3DXQUATERNION& q ) const +{ + return D3DXQUATERNION(x - q.x, y - q.y, z - q.z, w - q.w); +} + +D3DX10INLINE D3DXQUATERNION +D3DXQUATERNION::operator * ( CONST D3DXQUATERNION& q ) const +{ + D3DXQUATERNION qT; + D3DXQuaternionMultiply(&qT, this, &q); + return qT; +} + +D3DX10INLINE D3DXQUATERNION +D3DXQUATERNION::operator * ( FLOAT f ) const +{ + return D3DXQUATERNION(x * f, y * f, z * f, w * f); +} + +D3DX10INLINE D3DXQUATERNION +D3DXQUATERNION::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXQUATERNION(x * fInv, y * fInv, z * fInv, w * fInv); +} + + +D3DX10INLINE D3DXQUATERNION +operator * (FLOAT f, CONST D3DXQUATERNION& q ) +{ + return D3DXQUATERNION(f * q.x, f * q.y, f * q.z, f * q.w); +} + + +D3DX10INLINE BOOL +D3DXQUATERNION::operator == ( CONST D3DXQUATERNION& q ) const +{ + return x == q.x && y == q.y && z == q.z && w == q.w; +} + +D3DX10INLINE BOOL +D3DXQUATERNION::operator != ( CONST D3DXQUATERNION& q ) const +{ + return x != q.x || y != q.y || z != q.z || w != q.w; +} + + + +//-------------------------- +// Plane +//-------------------------- + +D3DX10INLINE +D3DXPLANE::D3DXPLANE( CONST FLOAT* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + a = pf[0]; + b = pf[1]; + c = pf[2]; + d = pf[3]; +} + +D3DX10INLINE +D3DXPLANE::D3DXPLANE( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&a, pf, 4); +} + +D3DX10INLINE +D3DXPLANE::D3DXPLANE( FLOAT fa, FLOAT fb, FLOAT fc, FLOAT fd ) +{ + a = fa; + b = fb; + c = fc; + d = fd; +} + + +// casting +D3DX10INLINE +D3DXPLANE::operator FLOAT* () +{ + return (FLOAT *) &a; +} + +D3DX10INLINE +D3DXPLANE::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &a; +} + + +// assignment operators +D3DX10INLINE D3DXPLANE& +D3DXPLANE::operator *= ( FLOAT f ) +{ + a *= f; + b *= f; + c *= f; + d *= f; + return *this; +} + +D3DX10INLINE D3DXPLANE& +D3DXPLANE::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + a *= fInv; + b *= fInv; + c *= fInv; + d *= fInv; + return *this; +} + + +// unary operators +D3DX10INLINE D3DXPLANE +D3DXPLANE::operator + () const +{ + return *this; +} + +D3DX10INLINE D3DXPLANE +D3DXPLANE::operator - () const +{ + return D3DXPLANE(-a, -b, -c, -d); +} + + +// binary operators +D3DX10INLINE D3DXPLANE +D3DXPLANE::operator * ( FLOAT f ) const +{ + return D3DXPLANE(a * f, b * f, c * f, d * f); +} + +D3DX10INLINE D3DXPLANE +D3DXPLANE::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXPLANE(a * fInv, b * fInv, c * fInv, d * fInv); +} + +D3DX10INLINE D3DXPLANE +operator * (FLOAT f, CONST D3DXPLANE& p ) +{ + return D3DXPLANE(f * p.a, f * p.b, f * p.c, f * p.d); +} + +D3DX10INLINE BOOL +D3DXPLANE::operator == ( CONST D3DXPLANE& p ) const +{ + return a == p.a && b == p.b && c == p.c && d == p.d; +} + +D3DX10INLINE BOOL +D3DXPLANE::operator != ( CONST D3DXPLANE& p ) const +{ + return a != p.a || b != p.b || c != p.c || d != p.d; +} + + + + +//-------------------------- +// Color +//-------------------------- + +D3DX10INLINE +D3DXCOLOR::D3DXCOLOR( UINT dw ) +{ + CONST FLOAT f = 1.0f / 255.0f; + r = f * (FLOAT) (unsigned char) (dw >> 16); + g = f * (FLOAT) (unsigned char) (dw >> 8); + b = f * (FLOAT) (unsigned char) (dw >> 0); + a = f * (FLOAT) (unsigned char) (dw >> 24); +} + +D3DX10INLINE +D3DXCOLOR::D3DXCOLOR( CONST FLOAT* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + r = pf[0]; + g = pf[1]; + b = pf[2]; + a = pf[3]; +} + +D3DX10INLINE +D3DXCOLOR::D3DXCOLOR( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX10_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&r, pf, 4); +} + +D3DX10INLINE +D3DXCOLOR::D3DXCOLOR( FLOAT fr, FLOAT fg, FLOAT fb, FLOAT fa ) +{ + r = fr; + g = fg; + b = fb; + a = fa; +} + + +// casting +D3DX10INLINE +D3DXCOLOR::operator UINT () const +{ + UINT dwR = r >= 1.0f ? 0xff : r <= 0.0f ? 0x00 : (UINT) (r * 255.0f + 0.5f); + UINT dwG = g >= 1.0f ? 0xff : g <= 0.0f ? 0x00 : (UINT) (g * 255.0f + 0.5f); + UINT dwB = b >= 1.0f ? 0xff : b <= 0.0f ? 0x00 : (UINT) (b * 255.0f + 0.5f); + UINT dwA = a >= 1.0f ? 0xff : a <= 0.0f ? 0x00 : (UINT) (a * 255.0f + 0.5f); + + return (dwA << 24) | (dwR << 16) | (dwG << 8) | (dwB << 0); +} + + +D3DX10INLINE +D3DXCOLOR::operator FLOAT * () +{ + return (FLOAT *) &r; +} + +D3DX10INLINE +D3DXCOLOR::operator CONST FLOAT * () const +{ + return (CONST FLOAT *) &r; +} + +// assignment operators +D3DX10INLINE D3DXCOLOR& +D3DXCOLOR::operator += ( CONST D3DXCOLOR& c ) +{ + r += c.r; + g += c.g; + b += c.b; + a += c.a; + return *this; +} + +D3DX10INLINE D3DXCOLOR& +D3DXCOLOR::operator -= ( CONST D3DXCOLOR& c ) +{ + r -= c.r; + g -= c.g; + b -= c.b; + a -= c.a; + return *this; +} + +D3DX10INLINE D3DXCOLOR& +D3DXCOLOR::operator *= ( FLOAT f ) +{ + r *= f; + g *= f; + b *= f; + a *= f; + return *this; +} + +D3DX10INLINE D3DXCOLOR& +D3DXCOLOR::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + r *= fInv; + g *= fInv; + b *= fInv; + a *= fInv; + return *this; +} + + +// unary operators +D3DX10INLINE D3DXCOLOR +D3DXCOLOR::operator + () const +{ + return *this; +} + +D3DX10INLINE D3DXCOLOR +D3DXCOLOR::operator - () const +{ + return D3DXCOLOR(-r, -g, -b, -a); +} + + +// binary operators +D3DX10INLINE D3DXCOLOR +D3DXCOLOR::operator + ( CONST D3DXCOLOR& c ) const +{ + return D3DXCOLOR(r + c.r, g + c.g, b + c.b, a + c.a); +} + +D3DX10INLINE D3DXCOLOR +D3DXCOLOR::operator - ( CONST D3DXCOLOR& c ) const +{ + return D3DXCOLOR(r - c.r, g - c.g, b - c.b, a - c.a); +} + +D3DX10INLINE D3DXCOLOR +D3DXCOLOR::operator * ( FLOAT f ) const +{ + return D3DXCOLOR(r * f, g * f, b * f, a * f); +} + +D3DX10INLINE D3DXCOLOR +D3DXCOLOR::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXCOLOR(r * fInv, g * fInv, b * fInv, a * fInv); +} + + +D3DX10INLINE D3DXCOLOR +operator * (FLOAT f, CONST D3DXCOLOR& c ) +{ + return D3DXCOLOR(f * c.r, f * c.g, f * c.b, f * c.a); +} + + +D3DX10INLINE BOOL +D3DXCOLOR::operator == ( CONST D3DXCOLOR& c ) const +{ + return r == c.r && g == c.g && b == c.b && a == c.a; +} + +D3DX10INLINE BOOL +D3DXCOLOR::operator != ( CONST D3DXCOLOR& c ) const +{ + return r != c.r || g != c.g || b != c.b || a != c.a; +} + + +#endif //__cplusplus + + + +//=========================================================================== +// +// Inline functions +// +//=========================================================================== + + +//-------------------------- +// 2D Vector +//-------------------------- + +D3DX10INLINE FLOAT D3DXVec2Length + ( CONST D3DXVECTOR2 *pV ) +{ +#ifdef D3DX10_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y); +#endif +} + +D3DX10INLINE FLOAT D3DXVec2LengthSq + ( CONST D3DXVECTOR2 *pV ) +{ +#ifdef D3DX10_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y; +} + +D3DX10INLINE FLOAT D3DXVec2Dot + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y; +} + +D3DX10INLINE FLOAT D3DXVec2CCW + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->y - pV1->y * pV2->x; +} + +D3DX10INLINE D3DXVECTOR2* D3DXVec2Add + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + return pOut; +} + +D3DX10INLINE D3DXVECTOR2* D3DXVec2Subtract + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + return pOut; +} + +D3DX10INLINE D3DXVECTOR2* D3DXVec2Minimize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + return pOut; +} + +D3DX10INLINE D3DXVECTOR2* D3DXVec2Maximize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + return pOut; +} + +D3DX10INLINE D3DXVECTOR2* D3DXVec2Scale + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + return pOut; +} + +D3DX10INLINE D3DXVECTOR2* D3DXVec2Lerp + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + FLOAT s ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + return pOut; +} + + +//-------------------------- +// 3D Vector +//-------------------------- + +D3DX10INLINE FLOAT D3DXVec3Length + ( CONST D3DXVECTOR3 *pV ) +{ +#ifdef D3DX10_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z); +#endif +} + +D3DX10INLINE FLOAT D3DXVec3LengthSq + ( CONST D3DXVECTOR3 *pV ) +{ +#ifdef D3DX10_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y + pV->z * pV->z; +} + +D3DX10INLINE FLOAT D3DXVec3Dot + ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z; +} + +D3DX10INLINE D3DXVECTOR3* D3DXVec3Cross + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + D3DXVECTOR3 v; + +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + v.x = pV1->y * pV2->z - pV1->z * pV2->y; + v.y = pV1->z * pV2->x - pV1->x * pV2->z; + v.z = pV1->x * pV2->y - pV1->y * pV2->x; + + *pOut = v; + return pOut; +} + +D3DX10INLINE D3DXVECTOR3* D3DXVec3Add + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + pOut->z = pV1->z + pV2->z; + return pOut; +} + +D3DX10INLINE D3DXVECTOR3* D3DXVec3Subtract + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + return pOut; +} + +D3DX10INLINE D3DXVECTOR3* D3DXVec3Minimize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z < pV2->z ? pV1->z : pV2->z; + return pOut; +} + +D3DX10INLINE D3DXVECTOR3* D3DXVec3Maximize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z > pV2->z ? pV1->z : pV2->z; + return pOut; +} + +D3DX10INLINE D3DXVECTOR3* D3DXVec3Scale + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + pOut->z = pV->z * s; + return pOut; +} + +D3DX10INLINE D3DXVECTOR3* D3DXVec3Lerp + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + FLOAT s ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + pOut->z = pV1->z + s * (pV2->z - pV1->z); + return pOut; +} + + +//-------------------------- +// 4D Vector +//-------------------------- + +D3DX10INLINE FLOAT D3DXVec4Length + ( CONST D3DXVECTOR4 *pV ) +{ +#ifdef D3DX10_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w); +#endif +} + +D3DX10INLINE FLOAT D3DXVec4LengthSq + ( CONST D3DXVECTOR4 *pV ) +{ +#ifdef D3DX10_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w; +} + +D3DX10INLINE FLOAT D3DXVec4Dot + ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ) +{ +#ifdef D3DX10_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z + pV1->w * pV2->w; +} + +D3DX10INLINE D3DXVECTOR4* D3DXVec4Add + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + pOut->z = pV1->z + pV2->z; + pOut->w = pV1->w + pV2->w; + return pOut; +} + +D3DX10INLINE D3DXVECTOR4* D3DXVec4Subtract + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + pOut->w = pV1->w - pV2->w; + return pOut; +} + +D3DX10INLINE D3DXVECTOR4* D3DXVec4Minimize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z < pV2->z ? pV1->z : pV2->z; + pOut->w = pV1->w < pV2->w ? pV1->w : pV2->w; + return pOut; +} + +D3DX10INLINE D3DXVECTOR4* D3DXVec4Maximize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z > pV2->z ? pV1->z : pV2->z; + pOut->w = pV1->w > pV2->w ? pV1->w : pV2->w; + return pOut; +} + +D3DX10INLINE D3DXVECTOR4* D3DXVec4Scale + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + pOut->z = pV->z * s; + pOut->w = pV->w * s; + return pOut; +} + +D3DX10INLINE D3DXVECTOR4* D3DXVec4Lerp + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + FLOAT s ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + pOut->z = pV1->z + s * (pV2->z - pV1->z); + pOut->w = pV1->w + s * (pV2->w - pV1->w); + return pOut; +} + + +//-------------------------- +// 4D Matrix +//-------------------------- + +D3DX10INLINE D3DXMATRIX* D3DXMatrixIdentity + ( D3DXMATRIX *pOut ) +{ +#ifdef D3DX10_DEBUG + if(!pOut) + return NULL; +#endif + + pOut->m[0][1] = pOut->m[0][2] = pOut->m[0][3] = + pOut->m[1][0] = pOut->m[1][2] = pOut->m[1][3] = + pOut->m[2][0] = pOut->m[2][1] = pOut->m[2][3] = + pOut->m[3][0] = pOut->m[3][1] = pOut->m[3][2] = 0.0f; + + pOut->m[0][0] = pOut->m[1][1] = pOut->m[2][2] = pOut->m[3][3] = 1.0f; + return pOut; +} + + +D3DX10INLINE BOOL D3DXMatrixIsIdentity + ( CONST D3DXMATRIX *pM ) +{ +#ifdef D3DX10_DEBUG + if(!pM) + return FALSE; +#endif + + return pM->m[0][0] == 1.0f && pM->m[0][1] == 0.0f && pM->m[0][2] == 0.0f && pM->m[0][3] == 0.0f && + pM->m[1][0] == 0.0f && pM->m[1][1] == 1.0f && pM->m[1][2] == 0.0f && pM->m[1][3] == 0.0f && + pM->m[2][0] == 0.0f && pM->m[2][1] == 0.0f && pM->m[2][2] == 1.0f && pM->m[2][3] == 0.0f && + pM->m[3][0] == 0.0f && pM->m[3][1] == 0.0f && pM->m[3][2] == 0.0f && pM->m[3][3] == 1.0f; +} + + +//-------------------------- +// Quaternion +//-------------------------- + +D3DX10INLINE FLOAT D3DXQuaternionLength + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX10_DEBUG + if(!pQ) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w); +#else + return (FLOAT) sqrt(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w); +#endif +} + +D3DX10INLINE FLOAT D3DXQuaternionLengthSq + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX10_DEBUG + if(!pQ) + return 0.0f; +#endif + + return pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w; +} + +D3DX10INLINE FLOAT D3DXQuaternionDot + ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ) +{ +#ifdef D3DX10_DEBUG + if(!pQ1 || !pQ2) + return 0.0f; +#endif + + return pQ1->x * pQ2->x + pQ1->y * pQ2->y + pQ1->z * pQ2->z + pQ1->w * pQ2->w; +} + + +D3DX10INLINE D3DXQUATERNION* D3DXQuaternionIdentity + ( D3DXQUATERNION *pOut ) +{ +#ifdef D3DX10_DEBUG + if(!pOut) + return NULL; +#endif + + pOut->x = pOut->y = pOut->z = 0.0f; + pOut->w = 1.0f; + return pOut; +} + +D3DX10INLINE BOOL D3DXQuaternionIsIdentity + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX10_DEBUG + if(!pQ) + return FALSE; +#endif + + return pQ->x == 0.0f && pQ->y == 0.0f && pQ->z == 0.0f && pQ->w == 1.0f; +} + + +D3DX10INLINE D3DXQUATERNION* D3DXQuaternionConjugate + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pQ) + return NULL; +#endif + + pOut->x = -pQ->x; + pOut->y = -pQ->y; + pOut->z = -pQ->z; + pOut->w = pQ->w; + return pOut; +} + + +//-------------------------- +// Plane +//-------------------------- + +D3DX10INLINE FLOAT D3DXPlaneDot + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV) +{ +#ifdef D3DX10_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d * pV->w; +} + +D3DX10INLINE FLOAT D3DXPlaneDotCoord + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV) +{ +#ifdef D3DX10_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d; +} + +D3DX10INLINE FLOAT D3DXPlaneDotNormal + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV) +{ +#ifdef D3DX10_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z; +} + +D3DX10INLINE D3DXPLANE* D3DXPlaneScale + (D3DXPLANE *pOut, CONST D3DXPLANE *pP, FLOAT s) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pP) + return NULL; +#endif + + pOut->a = pP->a * s; + pOut->b = pP->b * s; + pOut->c = pP->c * s; + pOut->d = pP->d * s; + return pOut; +} + + +//-------------------------- +// Color +//-------------------------- + +D3DX10INLINE D3DXCOLOR* D3DXColorNegative + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pC) + return NULL; +#endif + + pOut->r = 1.0f - pC->r; + pOut->g = 1.0f - pC->g; + pOut->b = 1.0f - pC->b; + pOut->a = pC->a; + return pOut; +} + +D3DX10INLINE D3DXCOLOR* D3DXColorAdd + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r + pC2->r; + pOut->g = pC1->g + pC2->g; + pOut->b = pC1->b + pC2->b; + pOut->a = pC1->a + pC2->a; + return pOut; +} + +D3DX10INLINE D3DXCOLOR* D3DXColorSubtract + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r - pC2->r; + pOut->g = pC1->g - pC2->g; + pOut->b = pC1->b - pC2->b; + pOut->a = pC1->a - pC2->a; + return pOut; +} + +D3DX10INLINE D3DXCOLOR* D3DXColorScale + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pC) + return NULL; +#endif + + pOut->r = pC->r * s; + pOut->g = pC->g * s; + pOut->b = pC->b * s; + pOut->a = pC->a * s; + return pOut; +} + +D3DX10INLINE D3DXCOLOR* D3DXColorModulate + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r * pC2->r; + pOut->g = pC1->g * pC2->g; + pOut->b = pC1->b * pC2->b; + pOut->a = pC1->a * pC2->a; + return pOut; +} + +D3DX10INLINE D3DXCOLOR* D3DXColorLerp + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s) +{ +#ifdef D3DX10_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r + s * (pC2->r - pC1->r); + pOut->g = pC1->g + s * (pC2->g - pC1->g); + pOut->b = pC1->b + s * (pC2->b - pC1->b); + pOut->a = pC1->a + s * (pC2->a - pC1->a); + return pOut; +} + + +#endif // __D3DXMATH_INL__ + diff --git a/dxsdk/Include/D3DX10mesh.h b/dxsdk/Include/D3DX10mesh.h new file mode 100644 index 0000000..e5fed8f --- /dev/null +++ b/dxsdk/Include/D3DX10mesh.h @@ -0,0 +1,286 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx10mesh.h +// Content: D3DX10 mesh types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx10.h" + +#ifndef __D3DX10MESH_H__ +#define __D3DX10MESH_H__ + +// {7ED943DD-52E8-40b5-A8D8-76685C406330} +DEFINE_GUID(IID_ID3DX10BaseMesh, +0x7ed943dd, 0x52e8, 0x40b5, 0xa8, 0xd8, 0x76, 0x68, 0x5c, 0x40, 0x63, 0x30); + +// {04B0D117-1041-46b1-AA8A-3952848BA22E} +DEFINE_GUID(IID_ID3DX10MeshBuffer, +0x4b0d117, 0x1041, 0x46b1, 0xaa, 0x8a, 0x39, 0x52, 0x84, 0x8b, 0xa2, 0x2e); + +// {4020E5C2-1403-4929-883F-E2E849FAC195} +DEFINE_GUID(IID_ID3DX10Mesh, +0x4020e5c2, 0x1403, 0x4929, 0x88, 0x3f, 0xe2, 0xe8, 0x49, 0xfa, 0xc1, 0x95); + +// {8875769A-D579-4088-AAEB-534D1AD84E96} +DEFINE_GUID(IID_ID3DX10PMesh, +0x8875769a, 0xd579, 0x4088, 0xaa, 0xeb, 0x53, 0x4d, 0x1a, 0xd8, 0x4e, 0x96); + +// {667EA4C7-F1CD-4386-B523-7C0290B83CC5} +DEFINE_GUID(IID_ID3DX10SPMesh, +0x667ea4c7, 0xf1cd, 0x4386, 0xb5, 0x23, 0x7c, 0x2, 0x90, 0xb8, 0x3c, 0xc5); + +// {3CE6CC22-DBF2-44f4-894D-F9C34A337139} +DEFINE_GUID(IID_ID3DX10PatchMesh, +0x3ce6cc22, 0xdbf2, 0x44f4, 0x89, 0x4d, 0xf9, 0xc3, 0x4a, 0x33, 0x71, 0x39); + + +// Mesh options - lower 3 bytes only, upper byte used by _D3DX10MESHOPT option flags +enum _D3DX10_MESH { + D3DX10_MESH_32_BIT = 0x001, // If set, then use 32 bit indices, if not set use 16 bit indices. + D3DX10_MESH_GS_ADJACENCY = 0x004, // If set, mesh contains GS adjacency info. Not valid on input. + +}; + +typedef struct _D3DX10_ATTRIBUTE_RANGE +{ + UINT AttribId; + UINT FaceStart; + UINT FaceCount; + UINT VertexStart; + UINT VertexCount; +} D3DX10_ATTRIBUTE_RANGE; + +typedef D3DX10_ATTRIBUTE_RANGE* LPD3DX10_ATTRIBUTE_RANGE; + +typedef enum _D3DX10_MESH_DISCARD_FLAGS +{ + D3DX10_MESH_DISCARD_ATTRIBUTE_BUFFER = 0x01, + D3DX10_MESH_DISCARD_ATTRIBUTE_TABLE = 0x02, + D3DX10_MESH_DISCARD_POINTREPS = 0x04, + D3DX10_MESH_DISCARD_ADJACENCY = 0x08, + D3DX10_MESH_DISCARD_DEVICE_BUFFERS = 0x10, + +} D3DX10_MESH_DISCARD_FLAGS; + +typedef struct _D3DX10_WELD_EPSILONS +{ + FLOAT Position; // NOTE: This does NOT replace the epsilon in GenerateAdjacency + // in general, it should be the same value or greater than the one passed to GeneratedAdjacency + FLOAT BlendWeights; + FLOAT Normal; + FLOAT PSize; + FLOAT Specular; + FLOAT Diffuse; + FLOAT Texcoord[8]; + FLOAT Tangent; + FLOAT Binormal; + FLOAT TessFactor; +} D3DX10_WELD_EPSILONS; + +typedef D3DX10_WELD_EPSILONS* LPD3DX10_WELD_EPSILONS; + +typedef struct _D3DX10_INTERSECT_INFO +{ + UINT FaceIndex; // index of face intersected + FLOAT U; // Barycentric Hit Coordinates + FLOAT V; // Barycentric Hit Coordinates + FLOAT Dist; // Ray-Intersection Parameter Distance +} D3DX10_INTERSECT_INFO, *LPD3DX10_INTERSECT_INFO; + +// ID3DX10MeshBuffer is used by D3DX10Mesh vertex and index buffers +#undef INTERFACE +#define INTERFACE ID3DX10MeshBuffer + +DECLARE_INTERFACE_(ID3DX10MeshBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX10MeshBuffer + STDMETHOD(Map)(THIS_ void **ppData, SIZE_T *pSize) PURE; + STDMETHOD(Unmap)(THIS) PURE; + STDMETHOD_(SIZE_T, GetSize)(THIS) PURE; +}; + +// D3DX10 Mesh interfaces +#undef INTERFACE +#define INTERFACE ID3DX10Mesh + +DECLARE_INTERFACE_(ID3DX10Mesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX10Mesh + STDMETHOD_(UINT, GetFaceCount)(THIS) PURE; + STDMETHOD_(UINT, GetVertexCount)(THIS) PURE; + STDMETHOD_(UINT, GetVertexBufferCount)(THIS) PURE; + STDMETHOD_(UINT, GetFlags)(THIS) PURE; + STDMETHOD(GetVertexDescription)(THIS_ CONST D3D10_INPUT_ELEMENT_DESC **ppDesc, UINT *pDeclCount) PURE; + + STDMETHOD(SetVertexData)(THIS_ UINT iBuffer, CONST void *pData) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ UINT iBuffer, ID3DX10MeshBuffer **ppVertexBuffer) PURE; + + STDMETHOD(SetIndexData)(THIS_ CONST void *pData, UINT cIndices) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ ID3DX10MeshBuffer **ppIndexBuffer) PURE; + + STDMETHOD(SetAttributeData)(THIS_ CONST UINT *pData) PURE; + STDMETHOD(GetAttributeBuffer)(THIS_ ID3DX10MeshBuffer **ppAttributeBuffer) PURE; + + STDMETHOD(SetAttributeTable)(THIS_ CONST D3DX10_ATTRIBUTE_RANGE *pAttribTable, UINT cAttribTableSize) PURE; + STDMETHOD(GetAttributeTable)(THIS_ D3DX10_ATTRIBUTE_RANGE *pAttribTable, UINT *pAttribTableSize) PURE; + + STDMETHOD(GenerateAdjacencyAndPointReps)(THIS_ FLOAT Epsilon) PURE; + STDMETHOD(GenerateGSAdjacency)(THIS) PURE; + + STDMETHOD(SetAdjacencyData)(THIS_ CONST UINT *pAdjacency) PURE; + STDMETHOD(GetAdjacencyBuffer)(THIS_ ID3DX10MeshBuffer **ppAdjacency) PURE; + + STDMETHOD(SetPointRepData)(THIS_ CONST UINT *pPointReps) PURE; + STDMETHOD(GetPointRepBuffer)(THIS_ ID3DX10MeshBuffer **ppPointReps) PURE; + + STDMETHOD(Discard)(THIS_ D3DX10_MESH_DISCARD_FLAGS dwDiscard) PURE; + STDMETHOD(CloneMesh)(THIS_ UINT Flags, LPCSTR pPosSemantic, CONST D3D10_INPUT_ELEMENT_DESC *pDesc, UINT DeclCount, ID3DX10Mesh** ppCloneMesh) PURE; + + STDMETHOD(Optimize)(THIS_ UINT Flags, UINT * pFaceRemap, LPD3D10BLOB *ppVertexRemap) PURE; + STDMETHOD(GenerateAttributeBufferFromTable)(THIS) PURE; + + STDMETHOD(Intersect)(THIS_ D3DXVECTOR3 *pRayPos, D3DXVECTOR3 *pRayDir, + UINT *pHitCount, UINT *pFaceIndex, float *pU, float *pV, float *pDist, ID3D10Blob **ppAllHits); + STDMETHOD(IntersectSubset)(THIS_ UINT AttribId, D3DXVECTOR3 *pRayPos, D3DXVECTOR3 *pRayDir, + UINT *pHitCount, UINT *pFaceIndex, float *pU, float *pV, float *pDist, ID3D10Blob **ppAllHits); + + // ID3DX10Mesh - Device functions + STDMETHOD(CommitToDevice)(THIS) PURE; + STDMETHOD(DrawSubset)(THIS_ UINT AttribId) PURE; + STDMETHOD(DrawSubsetInstanced)(THIS_ UINT AttribId, UINT InstanceCount, UINT StartInstanceLocation) PURE; + + STDMETHOD(GetDeviceVertexBuffer)(THIS_ UINT iBuffer, ID3D10Buffer **ppVertexBuffer) PURE; + STDMETHOD(GetDeviceIndexBuffer)(THIS_ ID3D10Buffer **ppIndexBuffer) PURE; +}; + + +// Flat API +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DX10CreateMesh( + ID3D10Device *pDevice, + CONST D3D10_INPUT_ELEMENT_DESC *pDeclaration, + UINT DeclCount, + LPCSTR pPositionSemantic, + UINT VertexCount, + UINT FaceCount, + UINT Options, + ID3DX10Mesh **ppMesh); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +// ID3DX10Mesh::Optimize options - upper byte only, lower 3 bytes used from _D3DX10MESH option flags +enum _D3DX10_MESHOPT { + D3DX10_MESHOPT_COMPACT = 0x01000000, + D3DX10_MESHOPT_ATTR_SORT = 0x02000000, + D3DX10_MESHOPT_VERTEX_CACHE = 0x04000000, + D3DX10_MESHOPT_STRIP_REORDER = 0x08000000, + D3DX10_MESHOPT_IGNORE_VERTS = 0x10000000, // optimize faces only, don't touch vertices + D3DX10_MESHOPT_DO_NOT_SPLIT = 0x20000000, // do not split vertices shared between attribute groups when attribute sorting + D3DX10_MESHOPT_DEVICE_INDEPENDENT = 0x00400000, // Only affects VCache. uses a static known good cache size for all cards + + // D3DX10_MESHOPT_SHAREVB has been removed, please use D3DX10MESH_VB_SHARE instead + +}; + + +////////////////////////////////////////////////////////////////////////// +// ID3DXSkinInfo +////////////////////////////////////////////////////////////////////////// + +// {420BD604-1C76-4a34-A466-E45D0658A32C} +DEFINE_GUID(IID_ID3DX10SkinInfo, +0x420bd604, 0x1c76, 0x4a34, 0xa4, 0x66, 0xe4, 0x5d, 0x6, 0x58, 0xa3, 0x2c); + +// scaling modes for ID3DX10SkinInfo::Compact() & ID3DX10SkinInfo::UpdateMesh() +#define D3DX10_SKININFO_NO_SCALING 0 +#define D3DX10_SKININFO_SCALE_TO_1 1 +#define D3DX10_SKININFO_SCALE_TO_TOTAL 2 + +typedef struct _D3DX10_SKINNING_CHANNEL +{ + UINT SrcOffset; + UINT DestOffset; + BOOL IsNormal; +} D3DX10_SKINNING_CHANNEL; + +#undef INTERFACE +#define INTERFACE ID3DX10SkinInfo + +typedef struct ID3DX10SkinInfo *LPD3DX10SKININFO; + +DECLARE_INTERFACE_(ID3DX10SkinInfo, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD_(UINT , GetNumVertices)(THIS) PURE; + STDMETHOD_(UINT , GetNumBones)(THIS) PURE; + STDMETHOD_(UINT , GetMaxBoneInfluences)(THIS) PURE; + + STDMETHOD(AddVertices)(THIS_ UINT Count) PURE; + STDMETHOD(RemapVertices)(THIS_ UINT NewVertexCount, UINT *pVertexRemap) PURE; + + STDMETHOD(AddBones)(THIS_ UINT Count) PURE; + STDMETHOD(RemoveBone)(THIS_ UINT Index) PURE; + STDMETHOD(RemapBones)(THIS_ UINT NewBoneCount, UINT *pBoneRemap) PURE; + + STDMETHOD(AddBoneInfluences)(THIS_ UINT BoneIndex, UINT InfluenceCount, UINT *pIndices, float *pWeights) PURE; + STDMETHOD(ClearBoneInfluences)(THIS_ UINT BoneIndex) PURE; + STDMETHOD_(UINT , GetBoneInfluenceCount)(THIS_ UINT BoneIndex) PURE; + STDMETHOD(GetBoneInfluences)(THIS_ UINT BoneIndex, UINT Offset, UINT Count, UINT *pDestIndices, float *pDestWeights) PURE; + STDMETHOD(FindBoneInfluenceIndex)(THIS_ UINT BoneIndex, UINT VertexIndex, UINT *pInfluenceIndex) PURE; + STDMETHOD(SetBoneInfluence)(THIS_ UINT BoneIndex, UINT InfluenceIndex, float Weight) PURE; + STDMETHOD(GetBoneInfluence)(THIS_ UINT BoneIndex, UINT InfluenceIndex, float *pWeight) PURE; + + STDMETHOD(Compact)(THIS_ UINT MaxPerVertexInfluences, UINT ScaleMode, float MinWeight) PURE; + STDMETHOD(DoSoftwareSkinning)(UINT StartVertex, UINT VertexCount, void *pSrcVertices, UINT SrcStride, void *pDestVertices, UINT DestStride, D3DXMATRIX *pBoneMatrices, D3DXMATRIX *pInverseTransposeBoneMatrices, D3DX10_SKINNING_CHANNEL *pChannelDescs, UINT NumChannels) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DX10CreateSkinInfo(LPD3DX10SKININFO* ppSkinInfo); + +#ifdef __cplusplus +} +#endif //__cplusplus + +typedef struct _D3DX10_ATTRIBUTE_WEIGHTS +{ + FLOAT Position; + FLOAT Boundary; + FLOAT Normal; + FLOAT Diffuse; + FLOAT Specular; + FLOAT Texcoord[8]; + FLOAT Tangent; + FLOAT Binormal; +} D3DX10_ATTRIBUTE_WEIGHTS, *LPD3DX10_ATTRIBUTE_WEIGHTS; + +#endif //__D3DX10MESH_H__ + + diff --git a/dxsdk/Include/D3DX10tex.h b/dxsdk/Include/D3DX10tex.h new file mode 100644 index 0000000..a6d8bb9 --- /dev/null +++ b/dxsdk/Include/D3DX10tex.h @@ -0,0 +1,766 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx10tex.h +// Content: D3DX10 texturing APIs +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx10.h" + +#ifndef __D3DX10TEX_H__ +#define __D3DX10TEX_H__ + + +//---------------------------------------------------------------------------- +// D3DX10_FILTER flags: +// ------------------ +// +// A valid filter must contain one of these values: +// +// D3DX10_FILTER_NONE +// No scaling or filtering will take place. Pixels outside the bounds +// of the source image are assumed to be transparent black. +// D3DX10_FILTER_POINT +// Each destination pixel is computed by sampling the nearest pixel +// from the source image. +// D3DX10_FILTER_LINEAR +// Each destination pixel is computed by linearly interpolating between +// the nearest pixels in the source image. This filter works best +// when the scale on each axis is less than 2. +// D3DX10_FILTER_TRIANGLE +// Every pixel in the source image contributes equally to the +// destination image. This is the slowest of all the filters. +// D3DX10_FILTER_BOX +// Each pixel is computed by averaging a 2x2(x2) box pixels from +// the source image. Only works when the dimensions of the +// destination are half those of the source. (as with mip maps) +// +// And can be OR'd with any of these optional flags: +// +// D3DX10_FILTER_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX10_FILTER_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX10_FILTER_MIRROR_W +// Indicates that pixels off the edge of the texture on the W-axis +// should be mirrored, not wraped. +// D3DX10_FILTER_MIRROR +// Same as specifying D3DX10_FILTER_MIRROR_U | D3DX10_FILTER_MIRROR_V | +// D3DX10_FILTER_MIRROR_V +// D3DX10_FILTER_DITHER +// Dithers the resulting image using a 4x4 order dither pattern. +// D3DX10_FILTER_SRGB_IN +// Denotes that the input data is in sRGB (gamma 2.2) colorspace. +// D3DX10_FILTER_SRGB_OUT +// Denotes that the output data is in sRGB (gamma 2.2) colorspace. +// D3DX10_FILTER_SRGB +// Same as specifying D3DX10_FILTER_SRGB_IN | D3DX10_FILTER_SRGB_OUT +// +//---------------------------------------------------------------------------- + +typedef enum D3DX10_FILTER_FLAG +{ + D3DX10_FILTER_NONE = (1 << 0), + D3DX10_FILTER_POINT = (2 << 0), + D3DX10_FILTER_LINEAR = (3 << 0), + D3DX10_FILTER_TRIANGLE = (4 << 0), + D3DX10_FILTER_BOX = (5 << 0), + + D3DX10_FILTER_MIRROR_U = (1 << 16), + D3DX10_FILTER_MIRROR_V = (2 << 16), + D3DX10_FILTER_MIRROR_W = (4 << 16), + D3DX10_FILTER_MIRROR = (7 << 16), + + D3DX10_FILTER_DITHER = (1 << 19), + D3DX10_FILTER_DITHER_DIFFUSION= (2 << 19), + + D3DX10_FILTER_SRGB_IN = (1 << 21), + D3DX10_FILTER_SRGB_OUT = (2 << 21), + D3DX10_FILTER_SRGB = (3 << 21), +} D3DX10_FILTER_FLAG; + +//---------------------------------------------------------------------------- +// D3DX10_NORMALMAP flags: +// --------------------- +// These flags are used to control how D3DX10ComputeNormalMap generates normal +// maps. Any number of these flags may be OR'd together in any combination. +// +// D3DX10_NORMALMAP_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX10_NORMALMAP_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX10_NORMALMAP_MIRROR +// Same as specifying D3DX10_NORMALMAP_MIRROR_U | D3DX10_NORMALMAP_MIRROR_V +// D3DX10_NORMALMAP_INVERTSIGN +// Inverts the direction of each normal +// D3DX10_NORMALMAP_COMPUTE_OCCLUSION +// Compute the per pixel Occlusion term and encodes it into the alpha. +// An Alpha of 1 means that the pixel is not obscured in anyway, and +// an alpha of 0 would mean that the pixel is completly obscured. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX10_NORMALMAP_FLAG +{ + D3DX10_NORMALMAP_MIRROR_U = (1 << 16), + D3DX10_NORMALMAP_MIRROR_V = (2 << 16), + D3DX10_NORMALMAP_MIRROR = (3 << 16), + D3DX10_NORMALMAP_INVERTSIGN = (8 << 16), + D3DX10_NORMALMAP_COMPUTE_OCCLUSION = (16 << 16), +} D3DX10_NORMALMAP_FLAG; + +//---------------------------------------------------------------------------- +// D3DX10_CHANNEL flags: +// ------------------- +// These flags are used by functions which operate on or more channels +// in a texture. +// +// D3DX10_CHANNEL_RED +// Indicates the red channel should be used +// D3DX10_CHANNEL_BLUE +// Indicates the blue channel should be used +// D3DX10_CHANNEL_GREEN +// Indicates the green channel should be used +// D3DX10_CHANNEL_ALPHA +// Indicates the alpha channel should be used +// D3DX10_CHANNEL_LUMINANCE +// Indicates the luminaces of the red green and blue channels should be +// used. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX10_CHANNEL_FLAG +{ + D3DX10_CHANNEL_RED = (1 << 0), + D3DX10_CHANNEL_BLUE = (1 << 1), + D3DX10_CHANNEL_GREEN = (1 << 2), + D3DX10_CHANNEL_ALPHA = (1 << 3), + D3DX10_CHANNEL_LUMINANCE = (1 << 4), +} D3DX10_CHANNEL_FLAG; + + + +//---------------------------------------------------------------------------- +// D3DX10_IMAGE_FILE_FORMAT: +// --------------------- +// This enum is used to describe supported image file formats. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX10_IMAGE_FILE_FORMAT +{ + D3DX10_IFF_BMP = 0, + D3DX10_IFF_JPG = 1, + D3DX10_IFF_PNG = 3, + D3DX10_IFF_DDS = 4, + D3DX10_IFF_TIFF = 10, + D3DX10_IFF_GIF = 11, + D3DX10_IFF_WMP = 12, + D3DX10_IFF_FORCE_DWORD = 0x7fffffff + +} D3DX10_IMAGE_FILE_FORMAT; + + +//---------------------------------------------------------------------------- +// D3DX10_SAVE_TEXTURE_FLAG: +// --------------------- +// This enum is used to support texture saving options. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX10_SAVE_TEXTURE_FLAG +{ + D3DX10_STF_USEINPUTBLOB = 0x0001, +} D3DX10_SAVE_TEXTURE_FLAG; + + + +//---------------------------------------------------------------------------- +// D3DX10_IMAGE_INFO: +// --------------- +// This structure is used to return a rough description of what the +// the original contents of an image file looked like. +// +// Width +// Width of original image in pixels +// Height +// Height of original image in pixels +// Depth +// Depth of original image in pixels +// ArraySize +// Array size in textures +// MipLevels +// Number of mip levels in original image +// MiscFlags +// Miscellaneous flags +// Format +// D3D format which most closely describes the data in original image +// ResourceDimension +// D3D10_RESOURCE_DIMENSION representing the dimension of texture stored in the file. +// D3D10_RESOURCE_DIMENSION_TEXTURE1D, 2D, 3D +// ImageFileFormat +// D3DX10_IMAGE_FILE_FORMAT representing the format of the image file. +//---------------------------------------------------------------------------- + +typedef struct D3DX10_IMAGE_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT ArraySize; + UINT MipLevels; + UINT MiscFlags; + DXGI_FORMAT Format; + D3D10_RESOURCE_DIMENSION ResourceDimension; + D3DX10_IMAGE_FILE_FORMAT ImageFileFormat; +} D3DX10_IMAGE_INFO; + + + + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// Image File APIs /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DX10_IMAGE_LOAD_INFO: +// --------------- +// This structure can be optionally passed in to texture loader APIs to +// control how textures get loaded. Pass in D3DX10_DEFAULT for any of these +// to have D3DX automatically pick defaults based on the source file. +// +// Width +// Rescale texture to Width texels wide +// Height +// Rescale texture to Height texels high +// Depth +// Rescale texture to Depth texels deep +// FirstMipLevel +// First mip level to load +// MipLevels +// Number of mip levels to load after the first level +// Usage +// D3D10_USAGE flag for the new texture +// BindFlags +// D3D10 Bind flags for the new texture +// CpuAccessFlags +// D3D10 CPU Access flags for the new texture +// MiscFlags +// Reserved. Must be 0 +// Format +// Resample texture to the specified format +// Filter +// Filter the texture using the specified filter (only when resampling) +// MipFilter +// Filter the texture mip levels using the specified filter (only if +// generating mips) +// pSrcInfo +// (optional) pointer to a D3DX10_IMAGE_INFO structure that will get +// populated with source image information +//---------------------------------------------------------------------------- + + +typedef struct D3DX10_IMAGE_LOAD_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT FirstMipLevel; + UINT MipLevels; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CpuAccessFlags; + UINT MiscFlags; + DXGI_FORMAT Format; + UINT Filter; + UINT MipFilter; + D3DX10_IMAGE_INFO* pSrcInfo; + +#ifdef __cplusplus + D3DX10_IMAGE_LOAD_INFO() + { + Width = D3DX10_DEFAULT; + Height = D3DX10_DEFAULT; + Depth = D3DX10_DEFAULT; + FirstMipLevel = D3DX10_DEFAULT; + MipLevels = D3DX10_DEFAULT; + Usage = (D3D10_USAGE) D3DX10_DEFAULT; + BindFlags = D3DX10_DEFAULT; + CpuAccessFlags = D3DX10_DEFAULT; + MiscFlags = D3DX10_DEFAULT; + Format = DXGI_FORMAT_FROM_FILE; + Filter = D3DX10_DEFAULT; + MipFilter = D3DX10_DEFAULT; + pSrcInfo = NULL; + } +#endif + +} D3DX10_IMAGE_LOAD_INFO; + +//------------------------------------------------------------------------------- +// GetImageInfoFromFile/Resource/Memory: +// ------------------------------ +// Fills in a D3DX10_IMAGE_INFO struct with information about an image file. +// +// Parameters: +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name. +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pPump +// Optional pointer to a thread pump object to use. +// pSrcInfo +// Pointer to a D3DX10_IMAGE_INFO structure to be filled in with the +// description of the data in the source image file. +// pHResult +// Pointer to a memory location to receive the return value upon completion. +// Maybe NULL if not needed. +// If pPump != NULL, pHResult must be a valid memory location until the +// the asynchronous execution completes. +//------------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX10GetImageInfoFromFileA( + LPCSTR pSrcFile, + ID3DX10ThreadPump* pPump, + D3DX10_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX10GetImageInfoFromFileW( + LPCWSTR pSrcFile, + ID3DX10ThreadPump* pPump, + D3DX10_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10GetImageInfoFromFile D3DX10GetImageInfoFromFileW +#else +#define D3DX10GetImageInfoFromFile D3DX10GetImageInfoFromFileA +#endif + + +HRESULT WINAPI + D3DX10GetImageInfoFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + ID3DX10ThreadPump* pPump, + D3DX10_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX10GetImageInfoFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + ID3DX10ThreadPump* pPump, + D3DX10_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10GetImageInfoFromResource D3DX10GetImageInfoFromResourceW +#else +#define D3DX10GetImageInfoFromResource D3DX10GetImageInfoFromResourceA +#endif + + +HRESULT WINAPI + D3DX10GetImageInfoFromMemory( + LPCVOID pSrcData, + SIZE_T SrcDataSize, + ID3DX10ThreadPump* pPump, + D3DX10_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + + +////////////////////////////////////////////////////////////////////////////// +// Create/Save Texture APIs ////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DX10CreateTextureFromFile/Resource/Memory: +// D3DX10CreateShaderResourceViewFromFile/Resource/Memory: +// ----------------------------------- +// Create a texture object from a file or resource. +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// pSrcFile +// File name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pvSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pLoadInfo +// Optional pointer to a D3DX10_IMAGE_LOAD_INFO structure that +// contains additional loader parameters. +// pPump +// Optional pointer to a thread pump object to use. +// ppTexture +// [out] Created texture object. +// ppShaderResourceView +// [out] Shader resource view object created. +// pHResult +// Pointer to a memory location to receive the return value upon completion. +// Maybe NULL if not needed. +// If pPump != NULL, pHResult must be a valid memory location until the +// the asynchronous execution completes. +// +//---------------------------------------------------------------------------- + + +// FromFile + +HRESULT WINAPI + D3DX10CreateShaderResourceViewFromFileA( + ID3D10Device* pDevice, + LPCSTR pSrcFile, + D3DX10_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX10CreateShaderResourceViewFromFileW( + ID3D10Device* pDevice, + LPCWSTR pSrcFile, + D3DX10_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10CreateShaderResourceViewFromFile D3DX10CreateShaderResourceViewFromFileW +#else +#define D3DX10CreateShaderResourceViewFromFile D3DX10CreateShaderResourceViewFromFileA +#endif + +HRESULT WINAPI + D3DX10CreateTextureFromFileA( + ID3D10Device* pDevice, + LPCSTR pSrcFile, + D3DX10_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10Resource** ppTexture, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX10CreateTextureFromFileW( + ID3D10Device* pDevice, + LPCWSTR pSrcFile, + D3DX10_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10Resource** ppTexture, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10CreateTextureFromFile D3DX10CreateTextureFromFileW +#else +#define D3DX10CreateTextureFromFile D3DX10CreateTextureFromFileA +#endif + + +// FromResource (resources in dll/exes) + +HRESULT WINAPI + D3DX10CreateShaderResourceViewFromResourceA( + ID3D10Device* pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + D3DX10_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX10CreateShaderResourceViewFromResourceW( + ID3D10Device* pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + D3DX10_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10CreateShaderResourceViewFromResource D3DX10CreateShaderResourceViewFromResourceW +#else +#define D3DX10CreateShaderResourceViewFromResource D3DX10CreateShaderResourceViewFromResourceA +#endif + +HRESULT WINAPI + D3DX10CreateTextureFromResourceA( + ID3D10Device* pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + D3DX10_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10Resource** ppTexture, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX10CreateTextureFromResourceW( + ID3D10Device* pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + D3DX10_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10Resource** ppTexture, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10CreateTextureFromResource D3DX10CreateTextureFromResourceW +#else +#define D3DX10CreateTextureFromResource D3DX10CreateTextureFromResourceA +#endif + + +// FromFileInMemory + +HRESULT WINAPI + D3DX10CreateShaderResourceViewFromMemory( + ID3D10Device* pDevice, + LPCVOID pSrcData, + SIZE_T SrcDataSize, + D3DX10_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX10CreateTextureFromMemory( + ID3D10Device* pDevice, + LPCVOID pSrcData, + SIZE_T SrcDataSize, + D3DX10_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX10ThreadPump* pPump, + ID3D10Resource** ppTexture, + HRESULT* pHResult); + + +////////////////////////////////////////////////////////////////////////////// +// Misc Texture APIs ///////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DX10_TEXTURE_LOAD_INFO: +// ------------------------ +// +//---------------------------------------------------------------------------- + +typedef struct _D3DX10_TEXTURE_LOAD_INFO +{ + D3D10_BOX *pSrcBox; + D3D10_BOX *pDstBox; + UINT SrcFirstMip; + UINT DstFirstMip; + UINT NumMips; + UINT SrcFirstElement; + UINT DstFirstElement; + UINT NumElements; + UINT Filter; + UINT MipFilter; + +#ifdef __cplusplus + _D3DX10_TEXTURE_LOAD_INFO() + { + pSrcBox = NULL; + pDstBox = NULL; + SrcFirstMip = 0; + DstFirstMip = 0; + NumMips = D3DX10_DEFAULT; + SrcFirstElement = 0; + DstFirstElement = 0; + NumElements = D3DX10_DEFAULT; + Filter = D3DX10_DEFAULT; + MipFilter = D3DX10_DEFAULT; + } +#endif + +} D3DX10_TEXTURE_LOAD_INFO; + + +//---------------------------------------------------------------------------- +// D3DX10LoadTextureFromTexture: +// ---------------------------- +// Load a texture from a texture. +// +// Parameters: +// +//---------------------------------------------------------------------------- + + +HRESULT WINAPI + D3DX10LoadTextureFromTexture( + ID3D10Resource *pSrcTexture, + D3DX10_TEXTURE_LOAD_INFO *pLoadInfo, + ID3D10Resource *pDstTexture); + + +//---------------------------------------------------------------------------- +// D3DX10FilterTexture: +// ------------------ +// Filters mipmaps levels of a texture. +// +// Parameters: +// pBaseTexture +// The texture object to be filtered +// SrcLevel +// The level whose image is used to generate the subsequent levels. +// MipFilter +// D3DX10_FILTER flags controlling how each miplevel is filtered. +// Or D3DX10_DEFAULT for D3DX10_FILTER_BOX, +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX10FilterTexture( + ID3D10Resource *pTexture, + UINT SrcLevel, + UINT MipFilter); + + +//---------------------------------------------------------------------------- +// D3DX10SaveTextureToFile: +// ---------------------- +// Save a texture to a file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DX10_IMAGE_FILE_FORMAT specifying file format to use when saving. +// pSrcTexture +// Source texture, containing the image to be saved +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX10SaveTextureToFileA( + ID3D10Resource *pSrcTexture, + D3DX10_IMAGE_FILE_FORMAT DestFormat, + LPCSTR pDestFile); + +HRESULT WINAPI + D3DX10SaveTextureToFileW( + ID3D10Resource *pSrcTexture, + D3DX10_IMAGE_FILE_FORMAT DestFormat, + LPCWSTR pDestFile); + +#ifdef UNICODE +#define D3DX10SaveTextureToFile D3DX10SaveTextureToFileW +#else +#define D3DX10SaveTextureToFile D3DX10SaveTextureToFileA +#endif + + +//---------------------------------------------------------------------------- +// D3DX10SaveTextureToMemory: +// ---------------------- +// Save a texture to a blob. +// +// Parameters: +// pSrcTexture +// Source texture, containing the image to be saved +// DestFormat +// D3DX10_IMAGE_FILE_FORMAT specifying file format to use when saving. +// ppDestBuf +// address of a d3dxbuffer pointer to return the image data +// Flags +// optional flags +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX10SaveTextureToMemory( + ID3D10Resource* pSrcTexture, + D3DX10_IMAGE_FILE_FORMAT DestFormat, + LPD3D10BLOB* ppDestBuf, + UINT Flags); + + +//---------------------------------------------------------------------------- +// D3DX10ComputeNormalMap: +// --------------------- +// Converts a height map into a normal map. The (x,y,z) components of each +// normal are mapped to the (r,g,b) channels of the output texture. +// +// Parameters +// pSrcTexture +// Pointer to the source heightmap texture +// Flags +// D3DX10_NORMALMAP flags +// Channel +// D3DX10_CHANNEL specifying source of height information +// Amplitude +// The constant value which the height information is multiplied by. +// pDestTexture +// Pointer to the destination texture +//--------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX10ComputeNormalMap( + ID3D10Texture2D *pSrcTexture, + UINT Flags, + UINT Channel, + FLOAT Amplitude, + ID3D10Texture2D *pDestTexture); + + +//---------------------------------------------------------------------------- +// D3DX10SHProjectCubeMap: +// ---------------------- +// Projects a function represented in a cube map into spherical harmonics. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pCubeMap +// CubeMap that is going to be projected into spherical harmonics +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green +// pBOut +// Output SH vector for Blue +// +//--------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX10SHProjectCubeMap( + __in_range(2,6) UINT Order, + ID3D10Texture2D *pCubeMap, + __out_ecount(Order*Order) FLOAT *pROut, + __out_ecount_opt(Order*Order) FLOAT *pGOut, + __out_ecount_opt(Order*Order) FLOAT *pBOut); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX10TEX_H__ + diff --git a/dxsdk/Include/D3DX11.h b/dxsdk/Include/D3DX11.h new file mode 100644 index 0000000..103c782 --- /dev/null +++ b/dxsdk/Include/D3DX11.h @@ -0,0 +1,74 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx11.h +// Content: D3DX11 utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __D3DX11_INTERNAL__ +#error Incorrect D3DX11 header used +#endif + +#ifndef __D3DX11_H__ +#define __D3DX11_H__ + + +// Defines +#include +#include + +#ifdef ALLOW_THROWING_NEW +#include +#endif + +#define D3DX11_DEFAULT ((UINT) -1) +#define D3DX11_FROM_FILE ((UINT) -3) +#define DXGI_FORMAT_FROM_FILE ((DXGI_FORMAT) -3) + +#ifndef D3DX11INLINE +#ifdef _MSC_VER + #if (_MSC_VER >= 1200) + #define D3DX11INLINE __forceinline + #else + #define D3DX11INLINE __inline + #endif +#else + #ifdef __cplusplus + #define D3DX11INLINE inline + #else + #define D3DX11INLINE + #endif +#endif +#endif + + + +// Includes +#include "d3d11.h" +#include "d3dx11.h" +#include "d3dx11core.h" +#include "d3dx11tex.h" +#include "d3dx11async.h" + + +// Errors +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +enum _D3DX11_ERR { + D3DX11_ERR_CANNOT_MODIFY_INDEX_BUFFER = MAKE_DDHRESULT(2900), + D3DX11_ERR_INVALID_MESH = MAKE_DDHRESULT(2901), + D3DX11_ERR_CANNOT_ATTR_SORT = MAKE_DDHRESULT(2902), + D3DX11_ERR_SKINNING_NOT_SUPPORTED = MAKE_DDHRESULT(2903), + D3DX11_ERR_TOO_MANY_INFLUENCES = MAKE_DDHRESULT(2904), + D3DX11_ERR_INVALID_DATA = MAKE_DDHRESULT(2905), + D3DX11_ERR_LOADED_MESH_HAS_NO_DATA = MAKE_DDHRESULT(2906), + D3DX11_ERR_DUPLICATE_NAMED_FRAGMENT = MAKE_DDHRESULT(2907), + D3DX11_ERR_CANNOT_REMOVE_LAST_ITEM = MAKE_DDHRESULT(2908), +}; + + +#endif //__D3DX11_H__ + diff --git a/dxsdk/Include/D3DX11async.h b/dxsdk/Include/D3DX11async.h new file mode 100644 index 0000000..4586c55 --- /dev/null +++ b/dxsdk/Include/D3DX11async.h @@ -0,0 +1,164 @@ + +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3DX11Async.h +// Content: D3DX11 Asynchronous Shader loaders / compilers +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX11ASYNC_H__ +#define __D3DX11ASYNC_H__ + +#include "d3dx11.h" + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3DX11Compile: +// ------------------ +// Compiles an effect or shader. +// +// Parameters: +// pSrcFile +// Source file name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module. +// pSrcData +// Pointer to source code. +// SrcDataLen +// Size of source code, in bytes. +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pFunctionName +// Name of the entrypoint function where execution should begin. +// pProfile +// Instruction set to be used when generating code. Currently supported +// profiles are "vs_1_1", "vs_2_0", "vs_2_a", "vs_2_sw", "vs_3_0", +// "vs_3_sw", "vs_4_0", "vs_4_1", +// "ps_2_0", "ps_2_a", "ps_2_b", "ps_2_sw", "ps_3_0", +// "ps_3_sw", "ps_4_0", "ps_4_1", +// "gs_4_0", "gs_4_1", +// "tx_1_0", +// "fx_4_0", "fx_4_1" +// Note that this entrypoint does not compile fx_2_0 targets, for that +// you need to use the D3DX9 function. +// Flags1 +// See D3D10_SHADER_xxx flags. +// Flags2 +// See D3D10_EFFECT_xxx flags. +// ppShader +// Returns a buffer containing the created shader. This buffer contains +// the compiled shader code, as well as any embedded debug and symbol +// table info. (See D3D10GetShaderConstantTable) +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during the compile. If you are running in a debugger, +// these are the same messages you will see in your debug output. +// pHResult +// Pointer to a memory location to receive the return value upon completion. +// Maybe NULL if not needed. +// If pPump != NULL, pHResult must be a valid memory location until the +// the asynchronous execution completes. +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3DX11CompileFromFileA(LPCSTR pSrcFile,CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX11CompileFromFileW(LPCWSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11CompileFromFile D3DX11CompileFromFileW +#else +#define D3DX11CompileFromFile D3DX11CompileFromFileA +#endif + +HRESULT WINAPI D3DX11CompileFromResourceA(HMODULE hSrcModule, LPCSTR pSrcResource, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX11CompileFromResourceW(HMODULE hSrcModule, LPCWSTR pSrcResource, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11CompileFromResource D3DX11CompileFromResourceW +#else +#define D3DX11CompileFromResource D3DX11CompileFromResourceA +#endif + +HRESULT WINAPI D3DX11CompileFromMemory(LPCSTR pSrcData, SIZE_T SrcDataLen, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX11PreprocessShaderFromFileA(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX11PreprocessShaderFromFileW(LPCWSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX11PreprocessShaderFromMemory(LPCSTR pSrcData, SIZE_T SrcDataSize, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX11PreprocessShaderFromResourceA(HMODULE hModule, LPCSTR pResourceName, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX11PreprocessShaderFromResourceW(HMODULE hModule, LPCWSTR pResourceName, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11PreprocessShaderFromFile D3DX11PreprocessShaderFromFileW +#define D3DX11PreprocessShaderFromResource D3DX11PreprocessShaderFromResourceW +#else +#define D3DX11PreprocessShaderFromFile D3DX11PreprocessShaderFromFileA +#define D3DX11PreprocessShaderFromResource D3DX11PreprocessShaderFromResourceA +#endif + +//---------------------------------------------------------------------------- +// Async processors +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3DX11CreateAsyncCompilerProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, + ID3D10Blob **ppCompiledShader, ID3D10Blob **ppErrorBuffer, ID3DX11DataProcessor **ppProcessor); + +HRESULT WINAPI D3DX11CreateAsyncShaderPreprocessProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + ID3D10Blob** ppShaderText, ID3D10Blob **ppErrorBuffer, ID3DX11DataProcessor **ppProcessor); + +//---------------------------------------------------------------------------- +// D3DX11 Asynchronous texture I/O (advanced mode) +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3DX11CreateAsyncFileLoaderW(LPCWSTR pFileName, ID3DX11DataLoader **ppDataLoader); +HRESULT WINAPI D3DX11CreateAsyncFileLoaderA(LPCSTR pFileName, ID3DX11DataLoader **ppDataLoader); +HRESULT WINAPI D3DX11CreateAsyncMemoryLoader(LPCVOID pData, SIZE_T cbData, ID3DX11DataLoader **ppDataLoader); +HRESULT WINAPI D3DX11CreateAsyncResourceLoaderW(HMODULE hSrcModule, LPCWSTR pSrcResource, ID3DX11DataLoader **ppDataLoader); +HRESULT WINAPI D3DX11CreateAsyncResourceLoaderA(HMODULE hSrcModule, LPCSTR pSrcResource, ID3DX11DataLoader **ppDataLoader); + +#ifdef UNICODE +#define D3DX11CreateAsyncFileLoader D3DX11CreateAsyncFileLoaderW +#define D3DX11CreateAsyncResourceLoader D3DX11CreateAsyncResourceLoaderW +#else +#define D3DX11CreateAsyncFileLoader D3DX11CreateAsyncFileLoaderA +#define D3DX11CreateAsyncResourceLoader D3DX11CreateAsyncResourceLoaderA +#endif + +HRESULT WINAPI D3DX11CreateAsyncTextureProcessor(ID3D11Device *pDevice, D3DX11_IMAGE_LOAD_INFO *pLoadInfo, ID3DX11DataProcessor **ppDataProcessor); +HRESULT WINAPI D3DX11CreateAsyncTextureInfoProcessor(D3DX11_IMAGE_INFO *pImageInfo, ID3DX11DataProcessor **ppDataProcessor); +HRESULT WINAPI D3DX11CreateAsyncShaderResourceViewProcessor(ID3D11Device *pDevice, D3DX11_IMAGE_LOAD_INFO *pLoadInfo, ID3DX11DataProcessor **ppDataProcessor); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX11ASYNC_H__ + + diff --git a/dxsdk/Include/D3DX11core.h b/dxsdk/Include/D3DX11core.h new file mode 100644 index 0000000..18e9935 --- /dev/null +++ b/dxsdk/Include/D3DX11core.h @@ -0,0 +1,128 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx11core.h +// Content: D3DX11 core types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx11.h" + +#ifndef __D3DX11CORE_H__ +#define __D3DX11CORE_H__ + +// Current name of the DLL shipped in the same SDK as this header. + + +#define D3DX11_DLL_W L"d3dx11_43.dll" +#define D3DX11_DLL_A "d3dx11_43.dll" + +#ifdef UNICODE + #define D3DX11_DLL D3DX11_DLL_W +#else + #define D3DX11_DLL D3DX11_DLL_A +#endif + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +/////////////////////////////////////////////////////////////////////////// +// D3DX11_SDK_VERSION: +// ----------------- +// This identifier is passed to D3DX11CheckVersion in order to ensure that an +// application was built against the correct header files and lib files. +// This number is incremented whenever a header (or other) change would +// require applications to be rebuilt. If the version doesn't match, +// D3DX11CreateVersion will return FALSE. (The number itself has no meaning.) +/////////////////////////////////////////////////////////////////////////// + + +#define D3DX11_SDK_VERSION 43 + + +#ifdef D3D_DIAG_DLL +BOOL WINAPI D3DX11DebugMute(BOOL Mute); +#endif +HRESULT WINAPI D3DX11CheckVersion(UINT D3DSdkVersion, UINT D3DX11SdkVersion); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DX11ThreadPump: +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DX11DataLoader + +DECLARE_INTERFACE(ID3DX11DataLoader) +{ + STDMETHOD(Load)(THIS) PURE; + STDMETHOD(Decompress)(THIS_ void **ppData, SIZE_T *pcBytes) PURE; + STDMETHOD(Destroy)(THIS) PURE; +}; + +#undef INTERFACE +#define INTERFACE ID3DX11DataProcessor + +DECLARE_INTERFACE(ID3DX11DataProcessor) +{ + STDMETHOD(Process)(THIS_ void *pData, SIZE_T cBytes) PURE; + STDMETHOD(CreateDeviceObject)(THIS_ void **ppDataObject) PURE; + STDMETHOD(Destroy)(THIS) PURE; +}; + +// {C93FECFA-6967-478a-ABBC-402D90621FCB} +DEFINE_GUID(IID_ID3DX11ThreadPump, +0xc93fecfa, 0x6967, 0x478a, 0xab, 0xbc, 0x40, 0x2d, 0x90, 0x62, 0x1f, 0xcb); + +#undef INTERFACE +#define INTERFACE ID3DX11ThreadPump + +DECLARE_INTERFACE_(ID3DX11ThreadPump, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DX11ThreadPump + STDMETHOD(AddWorkItem)(THIS_ ID3DX11DataLoader *pDataLoader, ID3DX11DataProcessor *pDataProcessor, HRESULT *pHResult, void **ppDeviceObject) PURE; + STDMETHOD_(UINT, GetWorkItemCount)(THIS) PURE; + + STDMETHOD(WaitForAllItems)(THIS) PURE; + STDMETHOD(ProcessDeviceWorkItems)(THIS_ UINT iWorkItemCount); + + STDMETHOD(PurgeAllItems)(THIS) PURE; + STDMETHOD(GetQueueStatus)(THIS_ UINT *pIoQueue, UINT *pProcessQueue, UINT *pDeviceQueue) PURE; + +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI D3DX11CreateThreadPump(UINT cIoThreads, UINT cProcThreads, ID3DX11ThreadPump **ppThreadPump); + +HRESULT WINAPI D3DX11UnsetAllDeviceObjects(ID3D11DeviceContext *pContext); + +#ifdef __cplusplus +} +#endif //__cplusplus + +/////////////////////////////////////////////////////////////////////////// + +#define _FACD3D 0x876 +#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) +#define MAKE_D3DSTATUS( code ) MAKE_HRESULT( 0, _FACD3D, code ) + +#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) +#define D3DERR_WASSTILLDRAWING MAKE_D3DHRESULT(540) + +#endif //__D3DX11CORE_H__ + diff --git a/dxsdk/Include/D3DX11tex.h b/dxsdk/Include/D3DX11tex.h new file mode 100644 index 0000000..16c0409 --- /dev/null +++ b/dxsdk/Include/D3DX11tex.h @@ -0,0 +1,772 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx11tex.h +// Content: D3DX11 texturing APIs +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx11.h" + +#ifndef __D3DX11TEX_H__ +#define __D3DX11TEX_H__ + + +//---------------------------------------------------------------------------- +// D3DX11_FILTER flags: +// ------------------ +// +// A valid filter must contain one of these values: +// +// D3DX11_FILTER_NONE +// No scaling or filtering will take place. Pixels outside the bounds +// of the source image are assumed to be transparent black. +// D3DX11_FILTER_POINT +// Each destination pixel is computed by sampling the nearest pixel +// from the source image. +// D3DX11_FILTER_LINEAR +// Each destination pixel is computed by linearly interpolating between +// the nearest pixels in the source image. This filter works best +// when the scale on each axis is less than 2. +// D3DX11_FILTER_TRIANGLE +// Every pixel in the source image contributes equally to the +// destination image. This is the slowest of all the filters. +// D3DX11_FILTER_BOX +// Each pixel is computed by averaging a 2x2(x2) box pixels from +// the source image. Only works when the dimensions of the +// destination are half those of the source. (as with mip maps) +// +// And can be OR'd with any of these optional flags: +// +// D3DX11_FILTER_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX11_FILTER_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX11_FILTER_MIRROR_W +// Indicates that pixels off the edge of the texture on the W-axis +// should be mirrored, not wraped. +// D3DX11_FILTER_MIRROR +// Same as specifying D3DX11_FILTER_MIRROR_U | D3DX11_FILTER_MIRROR_V | +// D3DX11_FILTER_MIRROR_V +// D3DX11_FILTER_DITHER +// Dithers the resulting image using a 4x4 order dither pattern. +// D3DX11_FILTER_SRGB_IN +// Denotes that the input data is in sRGB (gamma 2.2) colorspace. +// D3DX11_FILTER_SRGB_OUT +// Denotes that the output data is in sRGB (gamma 2.2) colorspace. +// D3DX11_FILTER_SRGB +// Same as specifying D3DX11_FILTER_SRGB_IN | D3DX11_FILTER_SRGB_OUT +// +//---------------------------------------------------------------------------- + +typedef enum D3DX11_FILTER_FLAG +{ + D3DX11_FILTER_NONE = (1 << 0), + D3DX11_FILTER_POINT = (2 << 0), + D3DX11_FILTER_LINEAR = (3 << 0), + D3DX11_FILTER_TRIANGLE = (4 << 0), + D3DX11_FILTER_BOX = (5 << 0), + + D3DX11_FILTER_MIRROR_U = (1 << 16), + D3DX11_FILTER_MIRROR_V = (2 << 16), + D3DX11_FILTER_MIRROR_W = (4 << 16), + D3DX11_FILTER_MIRROR = (7 << 16), + + D3DX11_FILTER_DITHER = (1 << 19), + D3DX11_FILTER_DITHER_DIFFUSION= (2 << 19), + + D3DX11_FILTER_SRGB_IN = (1 << 21), + D3DX11_FILTER_SRGB_OUT = (2 << 21), + D3DX11_FILTER_SRGB = (3 << 21), +} D3DX11_FILTER_FLAG; + +//---------------------------------------------------------------------------- +// D3DX11_NORMALMAP flags: +// --------------------- +// These flags are used to control how D3DX11ComputeNormalMap generates normal +// maps. Any number of these flags may be OR'd together in any combination. +// +// D3DX11_NORMALMAP_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX11_NORMALMAP_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX11_NORMALMAP_MIRROR +// Same as specifying D3DX11_NORMALMAP_MIRROR_U | D3DX11_NORMALMAP_MIRROR_V +// D3DX11_NORMALMAP_INVERTSIGN +// Inverts the direction of each normal +// D3DX11_NORMALMAP_COMPUTE_OCCLUSION +// Compute the per pixel Occlusion term and encodes it into the alpha. +// An Alpha of 1 means that the pixel is not obscured in anyway, and +// an alpha of 0 would mean that the pixel is completly obscured. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX11_NORMALMAP_FLAG +{ + D3DX11_NORMALMAP_MIRROR_U = (1 << 16), + D3DX11_NORMALMAP_MIRROR_V = (2 << 16), + D3DX11_NORMALMAP_MIRROR = (3 << 16), + D3DX11_NORMALMAP_INVERTSIGN = (8 << 16), + D3DX11_NORMALMAP_COMPUTE_OCCLUSION = (16 << 16), +} D3DX11_NORMALMAP_FLAG; + +//---------------------------------------------------------------------------- +// D3DX11_CHANNEL flags: +// ------------------- +// These flags are used by functions which operate on or more channels +// in a texture. +// +// D3DX11_CHANNEL_RED +// Indicates the red channel should be used +// D3DX11_CHANNEL_BLUE +// Indicates the blue channel should be used +// D3DX11_CHANNEL_GREEN +// Indicates the green channel should be used +// D3DX11_CHANNEL_ALPHA +// Indicates the alpha channel should be used +// D3DX11_CHANNEL_LUMINANCE +// Indicates the luminaces of the red green and blue channels should be +// used. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX11_CHANNEL_FLAG +{ + D3DX11_CHANNEL_RED = (1 << 0), + D3DX11_CHANNEL_BLUE = (1 << 1), + D3DX11_CHANNEL_GREEN = (1 << 2), + D3DX11_CHANNEL_ALPHA = (1 << 3), + D3DX11_CHANNEL_LUMINANCE = (1 << 4), +} D3DX11_CHANNEL_FLAG; + + + +//---------------------------------------------------------------------------- +// D3DX11_IMAGE_FILE_FORMAT: +// --------------------- +// This enum is used to describe supported image file formats. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX11_IMAGE_FILE_FORMAT +{ + D3DX11_IFF_BMP = 0, + D3DX11_IFF_JPG = 1, + D3DX11_IFF_PNG = 3, + D3DX11_IFF_DDS = 4, + D3DX11_IFF_TIFF = 10, + D3DX11_IFF_GIF = 11, + D3DX11_IFF_WMP = 12, + D3DX11_IFF_FORCE_DWORD = 0x7fffffff + +} D3DX11_IMAGE_FILE_FORMAT; + + +//---------------------------------------------------------------------------- +// D3DX11_SAVE_TEXTURE_FLAG: +// --------------------- +// This enum is used to support texture saving options. +// +//---------------------------------------------------------------------------- + +typedef enum D3DX11_SAVE_TEXTURE_FLAG +{ + D3DX11_STF_USEINPUTBLOB = 0x0001, +} D3DX11_SAVE_TEXTURE_FLAG; + + +//---------------------------------------------------------------------------- +// D3DX11_IMAGE_INFO: +// --------------- +// This structure is used to return a rough description of what the +// the original contents of an image file looked like. +// +// Width +// Width of original image in pixels +// Height +// Height of original image in pixels +// Depth +// Depth of original image in pixels +// ArraySize +// Array size in textures +// MipLevels +// Number of mip levels in original image +// MiscFlags +// Miscellaneous flags +// Format +// D3D format which most closely describes the data in original image +// ResourceDimension +// D3D11_RESOURCE_DIMENSION representing the dimension of texture stored in the file. +// D3D11_RESOURCE_DIMENSION_TEXTURE1D, 2D, 3D +// ImageFileFormat +// D3DX11_IMAGE_FILE_FORMAT representing the format of the image file. +//---------------------------------------------------------------------------- + +typedef struct D3DX11_IMAGE_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT ArraySize; + UINT MipLevels; + UINT MiscFlags; + DXGI_FORMAT Format; + D3D11_RESOURCE_DIMENSION ResourceDimension; + D3DX11_IMAGE_FILE_FORMAT ImageFileFormat; +} D3DX11_IMAGE_INFO; + + + + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// Image File APIs /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DX11_IMAGE_LOAD_INFO: +// --------------- +// This structure can be optionally passed in to texture loader APIs to +// control how textures get loaded. Pass in D3DX11_DEFAULT for any of these +// to have D3DX automatically pick defaults based on the source file. +// +// Width +// Rescale texture to Width texels wide +// Height +// Rescale texture to Height texels high +// Depth +// Rescale texture to Depth texels deep +// FirstMipLevel +// First mip level to load +// MipLevels +// Number of mip levels to load after the first level +// Usage +// D3D11_USAGE flag for the new texture +// BindFlags +// D3D11 Bind flags for the new texture +// CpuAccessFlags +// D3D11 CPU Access flags for the new texture +// MiscFlags +// Reserved. Must be 0 +// Format +// Resample texture to the specified format +// Filter +// Filter the texture using the specified filter (only when resampling) +// MipFilter +// Filter the texture mip levels using the specified filter (only if +// generating mips) +// pSrcInfo +// (optional) pointer to a D3DX11_IMAGE_INFO structure that will get +// populated with source image information +//---------------------------------------------------------------------------- + + +typedef struct D3DX11_IMAGE_LOAD_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT FirstMipLevel; + UINT MipLevels; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CpuAccessFlags; + UINT MiscFlags; + DXGI_FORMAT Format; + UINT Filter; + UINT MipFilter; + D3DX11_IMAGE_INFO* pSrcInfo; + +#ifdef __cplusplus + D3DX11_IMAGE_LOAD_INFO() + { + Width = D3DX11_DEFAULT; + Height = D3DX11_DEFAULT; + Depth = D3DX11_DEFAULT; + FirstMipLevel = D3DX11_DEFAULT; + MipLevels = D3DX11_DEFAULT; + Usage = (D3D11_USAGE) D3DX11_DEFAULT; + BindFlags = D3DX11_DEFAULT; + CpuAccessFlags = D3DX11_DEFAULT; + MiscFlags = D3DX11_DEFAULT; + Format = DXGI_FORMAT_FROM_FILE; + Filter = D3DX11_DEFAULT; + MipFilter = D3DX11_DEFAULT; + pSrcInfo = NULL; + } +#endif + +} D3DX11_IMAGE_LOAD_INFO; + +//------------------------------------------------------------------------------- +// GetImageInfoFromFile/Resource/Memory: +// ------------------------------ +// Fills in a D3DX11_IMAGE_INFO struct with information about an image file. +// +// Parameters: +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name. +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pPump +// Optional pointer to a thread pump object to use. +// pSrcInfo +// Pointer to a D3DX11_IMAGE_INFO structure to be filled in with the +// description of the data in the source image file. +// pHResult +// Pointer to a memory location to receive the return value upon completion. +// Maybe NULL if not needed. +// If pPump != NULL, pHResult must be a valid memory location until the +// the asynchronous execution completes. +//------------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX11GetImageInfoFromFileA( + LPCSTR pSrcFile, + ID3DX11ThreadPump* pPump, + D3DX11_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX11GetImageInfoFromFileW( + LPCWSTR pSrcFile, + ID3DX11ThreadPump* pPump, + D3DX11_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11GetImageInfoFromFile D3DX11GetImageInfoFromFileW +#else +#define D3DX11GetImageInfoFromFile D3DX11GetImageInfoFromFileA +#endif + + +HRESULT WINAPI + D3DX11GetImageInfoFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + ID3DX11ThreadPump* pPump, + D3DX11_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX11GetImageInfoFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + ID3DX11ThreadPump* pPump, + D3DX11_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11GetImageInfoFromResource D3DX11GetImageInfoFromResourceW +#else +#define D3DX11GetImageInfoFromResource D3DX11GetImageInfoFromResourceA +#endif + + +HRESULT WINAPI + D3DX11GetImageInfoFromMemory( + LPCVOID pSrcData, + SIZE_T SrcDataSize, + ID3DX11ThreadPump* pPump, + D3DX11_IMAGE_INFO* pSrcInfo, + HRESULT* pHResult); + + +////////////////////////////////////////////////////////////////////////////// +// Create/Save Texture APIs ////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DX11CreateTextureFromFile/Resource/Memory: +// D3DX11CreateShaderResourceViewFromFile/Resource/Memory: +// ----------------------------------- +// Create a texture object from a file or resource. +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// pSrcFile +// File name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pvSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pLoadInfo +// Optional pointer to a D3DX11_IMAGE_LOAD_INFO structure that +// contains additional loader parameters. +// pPump +// Optional pointer to a thread pump object to use. +// ppTexture +// [out] Created texture object. +// ppShaderResourceView +// [out] Shader resource view object created. +// pHResult +// Pointer to a memory location to receive the return value upon completion. +// Maybe NULL if not needed. +// If pPump != NULL, pHResult must be a valid memory location until the +// the asynchronous execution completes. +// +//---------------------------------------------------------------------------- + + +// FromFile + +HRESULT WINAPI + D3DX11CreateShaderResourceViewFromFileA( + ID3D11Device* pDevice, + LPCSTR pSrcFile, + D3DX11_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX11CreateShaderResourceViewFromFileW( + ID3D11Device* pDevice, + LPCWSTR pSrcFile, + D3DX11_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11CreateShaderResourceViewFromFile D3DX11CreateShaderResourceViewFromFileW +#else +#define D3DX11CreateShaderResourceViewFromFile D3DX11CreateShaderResourceViewFromFileA +#endif + +HRESULT WINAPI + D3DX11CreateTextureFromFileA( + ID3D11Device* pDevice, + LPCSTR pSrcFile, + D3DX11_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11Resource** ppTexture, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX11CreateTextureFromFileW( + ID3D11Device* pDevice, + LPCWSTR pSrcFile, + D3DX11_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11Resource** ppTexture, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11CreateTextureFromFile D3DX11CreateTextureFromFileW +#else +#define D3DX11CreateTextureFromFile D3DX11CreateTextureFromFileA +#endif + + +// FromResource (resources in dll/exes) + +HRESULT WINAPI + D3DX11CreateShaderResourceViewFromResourceA( + ID3D11Device* pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + D3DX11_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX11CreateShaderResourceViewFromResourceW( + ID3D11Device* pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + D3DX11_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11CreateShaderResourceViewFromResource D3DX11CreateShaderResourceViewFromResourceW +#else +#define D3DX11CreateShaderResourceViewFromResource D3DX11CreateShaderResourceViewFromResourceA +#endif + +HRESULT WINAPI + D3DX11CreateTextureFromResourceA( + ID3D11Device* pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + D3DX11_IMAGE_LOAD_INFO *pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11Resource** ppTexture, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX11CreateTextureFromResourceW( + ID3D11Device* pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + D3DX11_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11Resource** ppTexture, + HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX11CreateTextureFromResource D3DX11CreateTextureFromResourceW +#else +#define D3DX11CreateTextureFromResource D3DX11CreateTextureFromResourceA +#endif + + +// FromFileInMemory + +HRESULT WINAPI + D3DX11CreateShaderResourceViewFromMemory( + ID3D11Device* pDevice, + LPCVOID pSrcData, + SIZE_T SrcDataSize, + D3DX11_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11ShaderResourceView** ppShaderResourceView, + HRESULT* pHResult); + +HRESULT WINAPI + D3DX11CreateTextureFromMemory( + ID3D11Device* pDevice, + LPCVOID pSrcData, + SIZE_T SrcDataSize, + D3DX11_IMAGE_LOAD_INFO* pLoadInfo, + ID3DX11ThreadPump* pPump, + ID3D11Resource** ppTexture, + HRESULT* pHResult); + + +////////////////////////////////////////////////////////////////////////////// +// Misc Texture APIs ///////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DX11_TEXTURE_LOAD_INFO: +// ------------------------ +// +//---------------------------------------------------------------------------- + +typedef struct _D3DX11_TEXTURE_LOAD_INFO +{ + D3D11_BOX *pSrcBox; + D3D11_BOX *pDstBox; + UINT SrcFirstMip; + UINT DstFirstMip; + UINT NumMips; + UINT SrcFirstElement; + UINT DstFirstElement; + UINT NumElements; + UINT Filter; + UINT MipFilter; + +#ifdef __cplusplus + _D3DX11_TEXTURE_LOAD_INFO() + { + pSrcBox = NULL; + pDstBox = NULL; + SrcFirstMip = 0; + DstFirstMip = 0; + NumMips = D3DX11_DEFAULT; + SrcFirstElement = 0; + DstFirstElement = 0; + NumElements = D3DX11_DEFAULT; + Filter = D3DX11_DEFAULT; + MipFilter = D3DX11_DEFAULT; + } +#endif + +} D3DX11_TEXTURE_LOAD_INFO; + + +//---------------------------------------------------------------------------- +// D3DX11LoadTextureFromTexture: +// ---------------------------- +// Load a texture from a texture. +// +// Parameters: +// +//---------------------------------------------------------------------------- + + +HRESULT WINAPI + D3DX11LoadTextureFromTexture( + ID3D11DeviceContext *pContext, + ID3D11Resource *pSrcTexture, + D3DX11_TEXTURE_LOAD_INFO *pLoadInfo, + ID3D11Resource *pDstTexture); + + +//---------------------------------------------------------------------------- +// D3DX11FilterTexture: +// ------------------ +// Filters mipmaps levels of a texture. +// +// Parameters: +// pBaseTexture +// The texture object to be filtered +// SrcLevel +// The level whose image is used to generate the subsequent levels. +// MipFilter +// D3DX11_FILTER flags controlling how each miplevel is filtered. +// Or D3DX11_DEFAULT for D3DX11_FILTER_BOX, +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX11FilterTexture( + ID3D11DeviceContext *pContext, + ID3D11Resource *pTexture, + UINT SrcLevel, + UINT MipFilter); + + +//---------------------------------------------------------------------------- +// D3DX11SaveTextureToFile: +// ---------------------- +// Save a texture to a file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DX11_IMAGE_FILE_FORMAT specifying file format to use when saving. +// pSrcTexture +// Source texture, containing the image to be saved +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX11SaveTextureToFileA( + ID3D11DeviceContext *pContext, + ID3D11Resource *pSrcTexture, + D3DX11_IMAGE_FILE_FORMAT DestFormat, + LPCSTR pDestFile); + +HRESULT WINAPI + D3DX11SaveTextureToFileW( + ID3D11DeviceContext *pContext, + ID3D11Resource *pSrcTexture, + D3DX11_IMAGE_FILE_FORMAT DestFormat, + LPCWSTR pDestFile); + +#ifdef UNICODE +#define D3DX11SaveTextureToFile D3DX11SaveTextureToFileW +#else +#define D3DX11SaveTextureToFile D3DX11SaveTextureToFileA +#endif + + +//---------------------------------------------------------------------------- +// D3DX11SaveTextureToMemory: +// ---------------------- +// Save a texture to a blob. +// +// Parameters: +// pSrcTexture +// Source texture, containing the image to be saved +// DestFormat +// D3DX11_IMAGE_FILE_FORMAT specifying file format to use when saving. +// ppDestBuf +// address of a d3dxbuffer pointer to return the image data +// Flags +// optional flags +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX11SaveTextureToMemory( + ID3D11DeviceContext *pContext, + ID3D11Resource* pSrcTexture, + D3DX11_IMAGE_FILE_FORMAT DestFormat, + ID3D10Blob** ppDestBuf, + UINT Flags); + + +//---------------------------------------------------------------------------- +// D3DX11ComputeNormalMap: +// --------------------- +// Converts a height map into a normal map. The (x,y,z) components of each +// normal are mapped to the (r,g,b) channels of the output texture. +// +// Parameters +// pSrcTexture +// Pointer to the source heightmap texture +// Flags +// D3DX11_NORMALMAP flags +// Channel +// D3DX11_CHANNEL specifying source of height information +// Amplitude +// The constant value which the height information is multiplied by. +// pDestTexture +// Pointer to the destination texture +//--------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX11ComputeNormalMap( + ID3D11DeviceContext *pContext, + ID3D11Texture2D *pSrcTexture, + UINT Flags, + UINT Channel, + FLOAT Amplitude, + ID3D11Texture2D *pDestTexture); + + +//---------------------------------------------------------------------------- +// D3DX11SHProjectCubeMap: +// ---------------------- +// Projects a function represented in a cube map into spherical harmonics. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pCubeMap +// CubeMap that is going to be projected into spherical harmonics +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green +// pBOut +// Output SH vector for Blue +// +//--------------------------------------------------------------------------- + +HRESULT WINAPI + D3DX11SHProjectCubeMap( + ID3D11DeviceContext *pContext, + __in_range(2,6) UINT Order, + ID3D11Texture2D *pCubeMap, + __out_ecount(Order*Order) FLOAT *pROut, + __out_ecount_opt(Order*Order) FLOAT *pGOut, + __out_ecount_opt(Order*Order) FLOAT *pBOut); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX11TEX_H__ + diff --git a/dxsdk/Include/D3DX_DXGIFormatConvert.inl b/dxsdk/Include/D3DX_DXGIFormatConvert.inl new file mode 100644 index 0000000..1cfba72 --- /dev/null +++ b/dxsdk/Include/D3DX_DXGIFormatConvert.inl @@ -0,0 +1,800 @@ +//============================================================================= +// D3D11 HLSL Routines for Manual Pack/Unpack of 32-bit DXGI_FORMAT_* +//============================================================================= +// +// This file contains format conversion routines for use in the +// Compute Shader or Pixel Shader on D3D11 Hardware. +// +// Skip to the end of this comment to see a summary of the routines +// provided. The rest of the text below explains why they are needed +// and how to use them. +// +// The scenario where these can be useful is if your application +// needs to simultaneously both read and write texture - i.e. in-place +// image editing. +// +// D3D11's Unordered Access View (UAV) of a Texture1D/2D/3D resource +// allows random access reads and writes to memory from a Compute Shader +// or Pixel Shader. However, the only texture format that supports this +// is DXGI_FORMAT_R32_UINT. e.g. Other more interesting formats like +// DXGI_FORMAT_R8G8B8A8_UNORM do not support simultaneous read and +// write. You can use such formats for random access writing only +// using a UAV, or reading only using a Shader Resource View (SRV). +// But for simultaneous read+write, the format conversion hardware is +// not available. +// +// There is a workaround to this limitation, involving casting the texture +// to R32_UINT when creating a UAV, as long as the original format of the +// resource supports it (most 32 bit per element formats). This allows +// simultaneous read+write as long as the shader does manual format +// unpacking on read and packing on write. +// +// The benefit is that later on, other views such as RenderTarget Views +// or ShaderResource Views on the same texture can be used with the +// proper format (e.g. DXGI_FORMAT_R16G16_FLOAT) so the hardware can +// do the usual automatic format unpack/pack and do texture filtering etc. +// where there are no hardware limitations. +// +// The sequence of actions for an application is the following: +// +// Suppose you want to make a texture than you can use a Pixel Shader +// or Compute Shader to perform in-place editing, and that the format +// you want the data to be stored in happens to be a descendent +// of of one of these formats: +// +// DXGI_FORMAT_R10G10B10A2_TYPELESS +// DXGI_FORMAT_R8G8B8A8_TYPELESS +// DXGI_FORMAT_B8G8R8A8_TYPELESS +// DXGI_FORMAT_B8G8R8X8_TYPELESS +// DXGI_FORMAT_R16G16_TYPELESS +// +// e.g. DXGI_FORMAT_R10G10B10A2_UNORM is a descendent of +// DXGI_FORMAT_R10G10B10A2_TYPELESS, so it supports the +// usage pattern described here. +// +// (Formats descending from DXGI_FORMAT_R32_TYPELESS, such as +// DXGI_FORMAT_R32_FLOAT, are trivially supported without +// needing any of the format conversion help provided here.) +// +// Steps: +// +// (1) Create a texture with the appropriate _TYPELESS format above +// along with the needed bind flags, such as +// D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE. +// +// (2) For in-place image editing, create a UAV with the format +// DXGI_FORMAT_R32_UINT. D3D normally doesn't allow casting +// between different format "families", but the API makes +// an exception here. +// +// (3) In the Compute Shader or Pixel Shader, use the appropriate +// format pack/unpack routines provided in this file. +// For example if the DXGI_FORMAT_R32_UINT UAV really holds +// DXGI_FORMAT_R10G10B10A2_UNORM data, then, after reading a +// uint from the UAV into the shader, unpack by calling: +// +// XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput) +// +// Then to write to the UAV in the same shader, call the following +// to pack shader data into a uint that can be written out: +// +// UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput) +// +// (4) Other views, such as SRVs, can be created with the desired format; +// e.g. DXGI_FORMAT_R10G10B10A2_UNORM if the resource was created as +// DXGI_FORMAT_R10G10B10A2_TYPELESS. When that view is accessed by a +// shader, the hardware can do automatic type conversion as usual. +// +// Note, again, that if the shader only needs to write to a UAV, or read +// as an SRV, then none of this is needed - fully typed UAV or SRVs can +// be used. Only if simultaneous reading and writing to a UAV of a texture +// is needed are the format conversion routines provided here potentially +// useful. +// +// The following is the list of format conversion routines included in this +// file, categorized by the DXGI_FORMAT they unpack/pack. Each of the +// formats supported descends from one of the TYPELESS formats listed +// above, and supports casting to DXGI_FORMAT_R32_UINT as a UAV. +// +// DXGI_FORMAT_R10G10B10A2_UNORM: +// +// XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput) +// UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput) +// +// DXGI_FORMAT_R10G10B10A2_UINT: +// +// XMUINT4 D3DX_R10G10B10A2_UINT_to_UINT4(UINT packedInput) +// UINT D3DX_UINT4_to_R10G10B10A2_UINT(XMUINT4 unpackedInput) +// +// DXGI_FORMAT_R8G8B8A8_UNORM: +// +// XMFLOAT4 D3DX_R8G8B8A8_UNORM_to_FLOAT4(UINT packedInput) +// UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput) +// +// DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: +// +// XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) * +// XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput) +// UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput) +// +// * The "_inexact" function above uses shader instructions that don't +// have high enough precision to give the exact answer, albeit close. +// The alternative function uses a lookup table stored in the shader +// to give an exact SRGB->float conversion. +// +// DXGI_FORMAT_R8G8B8A8_UINT: +// +// XMUINT4 D3DX_R8G8B8A8_UINT_to_UINT4(UINT packedInput) +// XMUINT D3DX_UINT4_to_R8G8B8A8_UINT(XMUINT4 unpackedInput) +// +// DXGI_FORMAT_R8G8B8A8_SNORM: +// +// XMFLOAT4 D3DX_R8G8B8A8_SNORM_to_FLOAT4(UINT packedInput) +// UINT D3DX_FLOAT4_to_R8G8B8A8_SNORM(hlsl_precise XMFLOAT4 unpackedInput) +// +// DXGI_FORMAT_R8G8B8A8_SINT: +// +// XMINT4 D3DX_R8G8B8A8_SINT_to_INT4(UINT packedInput) +// UINT D3DX_INT4_to_R8G8B8A8_SINT(XMINT4 unpackedInput) +// +// DXGI_FORMAT_B8G8R8A8_UNORM: +// +// XMFLOAT4 D3DX_B8G8R8A8_UNORM_to_FLOAT4(UINT packedInput) +// UINT D3DX_FLOAT4_to_B8G8R8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput) +// +// DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: +// +// XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) * +// XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput) +// UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput) +// +// * The "_inexact" function above uses shader instructions that don't +// have high enough precision to give the exact answer, albeit close. +// The alternative function uses a lookup table stored in the shader +// to give an exact SRGB->float conversion. +// +// DXGI_FORMAT_B8G8R8X8_UNORM: +// +// XMFLOAT3 D3DX_B8G8R8X8_UNORM_to_FLOAT3(UINT packedInput) +// UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM(hlsl_precise XMFLOAT3 unpackedInput) +// +// DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: +// +// XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3_inexact(UINT packedInput) * +// XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3(UINT packedInput) +// UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM_SRGB(hlsl_precise XMFLOAT3 unpackedInput) +// +// * The "_inexact" function above uses shader instructions that don't +// have high enough precision to give the exact answer, albeit close. +// The alternative function uses a lookup table stored in the shader +// to give an exact SRGB->float conversion. +// +// DXGI_FORMAT_R16G16_FLOAT: +// +// XMFLOAT2 D3DX_R16G16_FLOAT_to_FLOAT2(UINT packedInput) +// UINT D3DX_FLOAT2_to_R16G16_FLOAT(hlsl_precise XMFLOAT2 unpackedInput) +// +// DXGI_FORMAT_R16G16_UNORM: +// +// XMFLOAT2 D3DX_R16G16_UNORM_to_FLOAT2(UINT packedInput) +// UINT D3DX_FLOAT2_to_R16G16_UNORM(hlsl_precise FLOAT2 unpackedInput) +// +// DXGI_FORMAT_R16G16_UINT: +// +// XMUINT2 D3DX_R16G16_UINT_to_UINT2(UINT packedInput) +// UINT D3DX_UINT2_to_R16G16_UINT(XMUINT2 unpackedInput) +// +// DXGI_FORMAT_R16G16_SNORM: +// +// XMFLOAT2 D3DX_R16G16_SNORM_to_FLOAT2(UINT packedInput) +// UINT D3DX_FLOAT2_to_R16G16_SNORM(hlsl_precise XMFLOAT2 unpackedInput) +// +// DXGI_FORMAT_R16G16_SINT: +// +// XMINT2 D3DX_R16G16_SINT_to_INT2(UINT packedInput) +// UINT D3DX_INT2_to_R16G16_SINT(XMINT2 unpackedInput) +// +//============================================================================= + +#ifndef __D3DX_DXGI_FORMAT_CONVERT_INL___ +#define __D3DX_DXGI_FORMAT_CONVERT_INL___ + +#if HLSL_VERSION > 0 + +#define D3DX11INLINE + +typedef int INT; +typedef uint UINT; + +typedef float2 XMFLOAT2; +typedef float3 XMFLOAT3; +typedef float4 XMFLOAT4; +typedef int2 XMINT2; +typedef int4 XMINT4; +typedef uint2 XMUINT2; +typedef uint4 XMUINT4; + +#define hlsl_precise precise + +#define D3DX_Saturate_FLOAT(_V) saturate(_V) +#define D3DX_IsNan(_V) isnan(_V) +#define D3DX_Truncate_FLOAT(_V) trunc(_V) + +#else // HLSL_VERSION > 0 + +#ifndef __cplusplus +#error C++ compilation required +#endif + +#include +#include + +#define hlsl_precise + +D3DX11INLINE FLOAT D3DX_Saturate_FLOAT(FLOAT _V) +{ + return min(max(_V, 0), 1); +} +D3DX11INLINE bool D3DX_IsNan(FLOAT _V) +{ + return _V != _V; +} +D3DX11INLINE FLOAT D3DX_Truncate_FLOAT(FLOAT _V) +{ + return _V >= 0 ? floor(_V) : ceil(_V); +} + +// 2D Vector; 32 bit signed integer components +typedef struct _XMINT2 +{ + INT x; + INT y; +} XMINT2; + +// 2D Vector; 32 bit unsigned integer components +typedef struct _XMUINT2 +{ + UINT x; + UINT y; +} XMUINT2; + +// 4D Vector; 32 bit signed integer components +typedef struct _XMINT4 +{ + INT x; + INT y; + INT z; + INT w; +} XMINT4; + +// 4D Vector; 32 bit unsigned integer components +typedef struct _XMUINT4 +{ + UINT x; + UINT y; + UINT z; + UINT w; +} XMUINT4; + +#endif // HLSL_VERSION > 0 + +//============================================================================= +// SRGB Helper Functions Called By Conversions Further Below. +//============================================================================= +// SRGB_to_FLOAT_inexact is imprecise due to precision of pow implementations. +// If exact SRGB->float conversion is needed, a table lookup is provided +// further below. +D3DX11INLINE FLOAT D3DX_SRGB_to_FLOAT_inexact(hlsl_precise FLOAT val) +{ + if( val < 0.04045f ) + val /= 12.92f; + else + val = pow((val + 0.055f)/1.055f,2.4f); + return val; +} + +static const UINT D3DX_SRGBTable[] = +{ + 0x00000000,0x399f22b4,0x3a1f22b4,0x3a6eb40e,0x3a9f22b4,0x3ac6eb61,0x3aeeb40e,0x3b0b3e5d, + 0x3b1f22b4,0x3b33070b,0x3b46eb61,0x3b5b518d,0x3b70f18d,0x3b83e1c6,0x3b8fe616,0x3b9c87fd, + 0x3ba9c9b7,0x3bb7ad6f,0x3bc63549,0x3bd56361,0x3be539c1,0x3bf5ba70,0x3c0373b5,0x3c0c6152, + 0x3c15a703,0x3c1f45be,0x3c293e6b,0x3c3391f7,0x3c3e4149,0x3c494d43,0x3c54b6c7,0x3c607eb1, + 0x3c6ca5df,0x3c792d22,0x3c830aa8,0x3c89af9f,0x3c9085db,0x3c978dc5,0x3c9ec7c2,0x3ca63433, + 0x3cadd37d,0x3cb5a601,0x3cbdac20,0x3cc5e639,0x3cce54ab,0x3cd6f7d5,0x3cdfd010,0x3ce8ddb9, + 0x3cf2212c,0x3cfb9ac1,0x3d02a569,0x3d0798dc,0x3d0ca7e6,0x3d11d2af,0x3d171963,0x3d1c7c2e, + 0x3d21fb3c,0x3d2796b2,0x3d2d4ebb,0x3d332380,0x3d39152b,0x3d3f23e3,0x3d454fd1,0x3d4b991c, + 0x3d51ffef,0x3d58846a,0x3d5f26b7,0x3d65e6fe,0x3d6cc564,0x3d73c20f,0x3d7add29,0x3d810b67, + 0x3d84b795,0x3d887330,0x3d8c3e4a,0x3d9018f6,0x3d940345,0x3d97fd4a,0x3d9c0716,0x3da020bb, + 0x3da44a4b,0x3da883d7,0x3daccd70,0x3db12728,0x3db59112,0x3dba0b3b,0x3dbe95b5,0x3dc33092, + 0x3dc7dbe2,0x3dcc97b6,0x3dd1641f,0x3dd6412c,0x3ddb2eef,0x3de02d77,0x3de53cd5,0x3dea5d19, + 0x3def8e52,0x3df4d091,0x3dfa23e8,0x3dff8861,0x3e027f07,0x3e054280,0x3e080ea3,0x3e0ae378, + 0x3e0dc105,0x3e10a754,0x3e13966b,0x3e168e52,0x3e198f10,0x3e1c98ad,0x3e1fab30,0x3e22c6a3, + 0x3e25eb09,0x3e29186c,0x3e2c4ed0,0x3e2f8e41,0x3e32d6c4,0x3e362861,0x3e39831e,0x3e3ce703, + 0x3e405416,0x3e43ca5f,0x3e4749e4,0x3e4ad2ae,0x3e4e64c2,0x3e520027,0x3e55a4e6,0x3e595303, + 0x3e5d0a8b,0x3e60cb7c,0x3e6495e0,0x3e6869bf,0x3e6c4720,0x3e702e0c,0x3e741e84,0x3e781890, + 0x3e7c1c38,0x3e8014c2,0x3e82203c,0x3e84308d,0x3e8645ba,0x3e885fc5,0x3e8a7eb2,0x3e8ca283, + 0x3e8ecb3d,0x3e90f8e1,0x3e932b74,0x3e9562f8,0x3e979f71,0x3e99e0e2,0x3e9c274e,0x3e9e72b7, + 0x3ea0c322,0x3ea31892,0x3ea57308,0x3ea7d289,0x3eaa3718,0x3eaca0b7,0x3eaf0f69,0x3eb18333, + 0x3eb3fc18,0x3eb67a18,0x3eb8fd37,0x3ebb8579,0x3ebe12e1,0x3ec0a571,0x3ec33d2d,0x3ec5da17, + 0x3ec87c33,0x3ecb2383,0x3ecdd00b,0x3ed081cd,0x3ed338cc,0x3ed5f50b,0x3ed8b68d,0x3edb7d54, + 0x3ede4965,0x3ee11ac1,0x3ee3f16b,0x3ee6cd67,0x3ee9aeb6,0x3eec955d,0x3eef815d,0x3ef272ba, + 0x3ef56976,0x3ef86594,0x3efb6717,0x3efe6e02,0x3f00bd2d,0x3f02460e,0x3f03d1a7,0x3f055ff9, + 0x3f06f106,0x3f0884cf,0x3f0a1b56,0x3f0bb49b,0x3f0d50a0,0x3f0eef67,0x3f1090f1,0x3f12353e, + 0x3f13dc51,0x3f15862b,0x3f1732cd,0x3f18e239,0x3f1a946f,0x3f1c4971,0x3f1e0141,0x3f1fbbdf, + 0x3f21794e,0x3f23398e,0x3f24fca0,0x3f26c286,0x3f288b41,0x3f2a56d3,0x3f2c253d,0x3f2df680, + 0x3f2fca9e,0x3f31a197,0x3f337b6c,0x3f355820,0x3f3737b3,0x3f391a26,0x3f3aff7c,0x3f3ce7b5, + 0x3f3ed2d2,0x3f40c0d4,0x3f42b1be,0x3f44a590,0x3f469c4b,0x3f4895f1,0x3f4a9282,0x3f4c9201, + 0x3f4e946e,0x3f5099cb,0x3f52a218,0x3f54ad57,0x3f56bb8a,0x3f58ccb0,0x3f5ae0cd,0x3f5cf7e0, + 0x3f5f11ec,0x3f612eee,0x3f634eef,0x3f6571e9,0x3f6797e3,0x3f69c0d6,0x3f6beccd,0x3f6e1bbf, + 0x3f704db8,0x3f7282af,0x3f74baae,0x3f76f5ae,0x3f7933b9,0x3f7b74c6,0x3f7db8e0,0x3f800000 +}; + +D3DX11INLINE FLOAT D3DX_SRGB_to_FLOAT(UINT val) +{ +#if HLSL_VERSION > 0 + return asfloat(D3DX_SRGBTable[val]); +#else + return *(FLOAT*)&D3DX_SRGBTable[val]; +#endif +} + +D3DX11INLINE FLOAT D3DX_FLOAT_to_SRGB(hlsl_precise FLOAT val) +{ + if( val < 0.0031308f ) + val *= 12.92f; + else + val = 1.055f * pow(val,1.0f/2.4f) - 0.055f; + return val; +} + +D3DX11INLINE FLOAT D3DX_SaturateSigned_FLOAT(FLOAT _V) +{ + if (D3DX_IsNan(_V)) + { + return 0; + } + + return min(max(_V, -1), 1); +} + +D3DX11INLINE UINT D3DX_FLOAT_to_UINT(FLOAT _V, + FLOAT _Scale) +{ + return (UINT)floor(_V * _Scale + 0.5f); +} + +D3DX11INLINE FLOAT D3DX_INT_to_FLOAT(INT _V, + FLOAT _Scale) +{ + FLOAT Scaled = (FLOAT)_V / _Scale; + // The integer is a two's-complement signed + // number so the negative range is slightly + // larger than the positive range, meaning + // the scaled value can be slight less than -1. + // Clamp to keep the float range [-1, 1]. + return max(Scaled, -1.0f); +} + +D3DX11INLINE INT D3DX_FLOAT_to_INT(FLOAT _V, + FLOAT _Scale) +{ + return (INT)D3DX_Truncate_FLOAT(_V * _Scale + (_V >= 0 ? 0.5f : -0.5f)); +} + +//============================================================================= +// Conversion routines +//============================================================================= +//----------------------------------------------------------------------------- +// R10B10G10A2_UNORM <-> FLOAT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.x = (FLOAT) (packedInput & 0x000003ff) / 1023; + unpackedOutput.y = (FLOAT)(((packedInput>>10) & 0x000003ff)) / 1023; + unpackedOutput.z = (FLOAT)(((packedInput>>20) & 0x000003ff)) / 1023; + unpackedOutput.w = (FLOAT)(((packedInput>>30) & 0x00000003)) / 3; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput) +{ + UINT packedOutput; + packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 1023)) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 1023)<<10) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 1023)<<20) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.w), 3)<<30) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R10B10G10A2_UINT <-> UINT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMUINT4 D3DX_R10G10B10A2_UINT_to_UINT4(UINT packedInput) +{ + XMUINT4 unpackedOutput; + unpackedOutput.x = packedInput & 0x000003ff; + unpackedOutput.y = (packedInput>>10) & 0x000003ff; + unpackedOutput.z = (packedInput>>20) & 0x000003ff; + unpackedOutput.w = (packedInput>>30) & 0x00000003; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_UINT4_to_R10G10B10A2_UINT(XMUINT4 unpackedInput) +{ + UINT packedOutput; + unpackedInput.x = min(unpackedInput.x, 0x000003ff); + unpackedInput.y = min(unpackedInput.y, 0x000003ff); + unpackedInput.z = min(unpackedInput.z, 0x000003ff); + unpackedInput.w = min(unpackedInput.w, 0x00000003); + packedOutput = ( (unpackedInput.x) | + ((unpackedInput.y)<<10) | + ((unpackedInput.z)<<20) | + ((unpackedInput.w)<<30) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R8G8B8A8_UNORM <-> FLOAT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_UNORM_to_FLOAT4(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.x = (FLOAT) (packedInput & 0x000000ff) / 255; + unpackedOutput.y = (FLOAT)(((packedInput>> 8) & 0x000000ff)) / 255; + unpackedOutput.z = (FLOAT)(((packedInput>>16) & 0x000000ff)) / 255; + unpackedOutput.w = (FLOAT) (packedInput>>24) / 255; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput) +{ + UINT packedOutput; + packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 255)) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 255)<< 8) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 255)<<16) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.w), 255)<<24) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R8G8B8A8_UNORM_SRGB <-> FLOAT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.x = D3DX_SRGB_to_FLOAT_inexact(((FLOAT) (packedInput & 0x000000ff) )/255); + unpackedOutput.y = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>> 8) & 0x000000ff)))/255); + unpackedOutput.z = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>>16) & 0x000000ff)))/255); + unpackedOutput.w = (FLOAT)(packedInput>>24) / 255; + return unpackedOutput; +} + +D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.x = D3DX_SRGB_to_FLOAT( (packedInput & 0x000000ff) ); + unpackedOutput.y = D3DX_SRGB_to_FLOAT((((packedInput>> 8) & 0x000000ff))); + unpackedOutput.z = D3DX_SRGB_to_FLOAT((((packedInput>>16) & 0x000000ff))); + unpackedOutput.w = (FLOAT)(packedInput>>24) / 255; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput) +{ + UINT packedOutput; + unpackedInput.x = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.x)); + unpackedInput.y = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.y)); + unpackedInput.z = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.z)); + unpackedInput.w = D3DX_Saturate_FLOAT(unpackedInput.w); + packedOutput = ( (D3DX_FLOAT_to_UINT(unpackedInput.x, 255)) | + (D3DX_FLOAT_to_UINT(unpackedInput.y, 255)<< 8) | + (D3DX_FLOAT_to_UINT(unpackedInput.z, 255)<<16) | + (D3DX_FLOAT_to_UINT(unpackedInput.w, 255)<<24) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R8G8B8A8_UINT <-> UINT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMUINT4 D3DX_R8G8B8A8_UINT_to_UINT4(UINT packedInput) +{ + XMUINT4 unpackedOutput; + unpackedOutput.x = packedInput & 0x000000ff; + unpackedOutput.y = (packedInput>> 8) & 0x000000ff; + unpackedOutput.z = (packedInput>>16) & 0x000000ff; + unpackedOutput.w = packedInput>>24; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_UINT4_to_R8G8B8A8_UINT(XMUINT4 unpackedInput) +{ + UINT packedOutput; + unpackedInput.x = min(unpackedInput.x, 0x000000ff); + unpackedInput.y = min(unpackedInput.y, 0x000000ff); + unpackedInput.z = min(unpackedInput.z, 0x000000ff); + unpackedInput.w = min(unpackedInput.w, 0x000000ff); + packedOutput = ( unpackedInput.x | + (unpackedInput.y<< 8) | + (unpackedInput.z<<16) | + (unpackedInput.w<<24) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R8G8B8A8_SNORM <-> FLOAT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_SNORM_to_FLOAT4(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + XMINT4 signExtendedBits; + signExtendedBits.x = (INT)(packedInput << 24) >> 24; + signExtendedBits.y = (INT)((packedInput << 16) & 0xff000000) >> 24; + signExtendedBits.z = (INT)((packedInput << 8) & 0xff000000) >> 24; + signExtendedBits.w = (INT)(packedInput & 0xff000000) >> 24; + unpackedOutput.x = D3DX_INT_to_FLOAT(signExtendedBits.x, 127); + unpackedOutput.y = D3DX_INT_to_FLOAT(signExtendedBits.y, 127); + unpackedOutput.z = D3DX_INT_to_FLOAT(signExtendedBits.z, 127); + unpackedOutput.w = D3DX_INT_to_FLOAT(signExtendedBits.w, 127); + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT4_to_R8G8B8A8_SNORM(hlsl_precise XMFLOAT4 unpackedInput) +{ + UINT packedOutput; + packedOutput = ( (D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.x), 127) & 0x000000ff) | + ((D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.y), 127) & 0x000000ff)<< 8) | + ((D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.z), 127) & 0x000000ff)<<16) | + ((D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.w), 127)) <<24) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R8G8B8A8_SINT <-> INT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMINT4 D3DX_R8G8B8A8_SINT_to_INT4(UINT packedInput) +{ + XMINT4 unpackedOutput; + unpackedOutput.x = (INT)(packedInput << 24) >> 24; + unpackedOutput.y = (INT)((packedInput << 16) & 0xff000000) >> 24; + unpackedOutput.z = (INT)((packedInput << 8) & 0xff000000) >> 24; + unpackedOutput.w = (INT)(packedInput & 0xff000000) >> 24; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_INT4_to_R8G8B8A8_SINT(XMINT4 unpackedInput) +{ + UINT packedOutput; + unpackedInput.x = max(min(unpackedInput.x,127),-128); + unpackedInput.y = max(min(unpackedInput.y,127),-128); + unpackedInput.z = max(min(unpackedInput.z,127),-128); + unpackedInput.w = max(min(unpackedInput.w,127),-128); + packedOutput = ( (unpackedInput.x & 0x000000ff) | + ((unpackedInput.y & 0x000000ff)<< 8) | + ((unpackedInput.z & 0x000000ff)<<16) | + (unpackedInput.w <<24) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// B8G8R8A8_UNORM <-> FLOAT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT4 D3DX_B8G8R8A8_UNORM_to_FLOAT4(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.z = (FLOAT) (packedInput & 0x000000ff) / 255; + unpackedOutput.y = (FLOAT)(((packedInput>> 8) & 0x000000ff)) / 255; + unpackedOutput.x = (FLOAT)(((packedInput>>16) & 0x000000ff)) / 255; + unpackedOutput.w = (FLOAT) (packedInput>>24) / 255; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT4_to_B8G8R8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput) +{ + UINT packedOutput; + packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 255)) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 255)<< 8) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 255)<<16) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.w), 255)<<24) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// B8G8R8A8_UNORM_SRGB <-> FLOAT4 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.z = D3DX_SRGB_to_FLOAT_inexact(((FLOAT) (packedInput & 0x000000ff) )/255); + unpackedOutput.y = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>> 8) & 0x000000ff)))/255); + unpackedOutput.x = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>>16) & 0x000000ff)))/255); + unpackedOutput.w = (FLOAT)(packedInput>>24) / 255; + return unpackedOutput; +} + +D3DX11INLINE XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput) +{ + hlsl_precise XMFLOAT4 unpackedOutput; + unpackedOutput.z = D3DX_SRGB_to_FLOAT( (packedInput & 0x000000ff) ); + unpackedOutput.y = D3DX_SRGB_to_FLOAT((((packedInput>> 8) & 0x000000ff))); + unpackedOutput.x = D3DX_SRGB_to_FLOAT((((packedInput>>16) & 0x000000ff))); + unpackedOutput.w = (FLOAT)(packedInput>>24) / 255; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT4_to_B8G8R8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput) +{ + UINT packedOutput; + unpackedInput.z = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.z)); + unpackedInput.y = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.y)); + unpackedInput.x = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.x)); + unpackedInput.w = D3DX_Saturate_FLOAT(unpackedInput.w); + packedOutput = ( (D3DX_FLOAT_to_UINT(unpackedInput.z, 255)) | + (D3DX_FLOAT_to_UINT(unpackedInput.y, 255)<< 8) | + (D3DX_FLOAT_to_UINT(unpackedInput.x, 255)<<16) | + (D3DX_FLOAT_to_UINT(unpackedInput.w, 255)<<24) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// B8G8R8X8_UNORM <-> FLOAT3 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT3 D3DX_B8G8R8X8_UNORM_to_FLOAT3(UINT packedInput) +{ + hlsl_precise XMFLOAT3 unpackedOutput; + unpackedOutput.z = (FLOAT) (packedInput & 0x000000ff) / 255; + unpackedOutput.y = (FLOAT)(((packedInput>> 8) & 0x000000ff)) / 255; + unpackedOutput.x = (FLOAT)(((packedInput>>16) & 0x000000ff)) / 255; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM(hlsl_precise XMFLOAT3 unpackedInput) +{ + UINT packedOutput; + packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 255)) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 255)<< 8) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 255)<<16) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// B8G8R8X8_UNORM_SRGB <-> FLOAT3 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3_inexact(UINT packedInput) +{ + hlsl_precise XMFLOAT3 unpackedOutput; + unpackedOutput.z = D3DX_SRGB_to_FLOAT_inexact(((FLOAT) (packedInput & 0x000000ff) )/255); + unpackedOutput.y = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>> 8) & 0x000000ff)))/255); + unpackedOutput.x = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>>16) & 0x000000ff)))/255); + return unpackedOutput; +} + +D3DX11INLINE XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3(UINT packedInput) +{ + hlsl_precise XMFLOAT3 unpackedOutput; + unpackedOutput.z = D3DX_SRGB_to_FLOAT( (packedInput & 0x000000ff) ); + unpackedOutput.y = D3DX_SRGB_to_FLOAT((((packedInput>> 8) & 0x000000ff))); + unpackedOutput.x = D3DX_SRGB_to_FLOAT((((packedInput>>16) & 0x000000ff))); + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM_SRGB(hlsl_precise XMFLOAT3 unpackedInput) +{ + UINT packedOutput; + unpackedInput.z = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.z)); + unpackedInput.y = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.y)); + unpackedInput.x = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.x)); + packedOutput = ( (D3DX_FLOAT_to_UINT(unpackedInput.z, 255)) | + (D3DX_FLOAT_to_UINT(unpackedInput.y, 255)<< 8) | + (D3DX_FLOAT_to_UINT(unpackedInput.x, 255)<<16) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R16G16_FLOAT <-> FLOAT2 +//----------------------------------------------------------------------------- + +#if HLSL_VERSION > 0 + +D3DX11INLINE XMFLOAT2 D3DX_R16G16_FLOAT_to_FLOAT2(UINT packedInput) +{ + hlsl_precise XMFLOAT2 unpackedOutput; + unpackedOutput.x = f16tof32(packedInput&0x0000ffff); + unpackedOutput.y = f16tof32(packedInput>>16); + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT2_to_R16G16_FLOAT(hlsl_precise XMFLOAT2 unpackedInput) +{ + UINT packedOutput; + packedOutput = asuint(f32tof16(unpackedInput.x)) | + (asuint(f32tof16(unpackedInput.y)) << 16); + return packedOutput; +} + +#endif // HLSL_VERSION > 0 + +//----------------------------------------------------------------------------- +// R16G16_UNORM <-> FLOAT2 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT2 D3DX_R16G16_UNORM_to_FLOAT2(UINT packedInput) +{ + hlsl_precise XMFLOAT2 unpackedOutput; + unpackedOutput.x = (FLOAT) (packedInput & 0x0000ffff) / 65535; + unpackedOutput.y = (FLOAT) (packedInput>>16) / 65535; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT2_to_R16G16_UNORM(hlsl_precise XMFLOAT2 unpackedInput) +{ + UINT packedOutput; + packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 65535)) | + (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 65535)<< 16) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R16G16_UINT <-> UINT2 +//----------------------------------------------------------------------------- +D3DX11INLINE XMUINT2 D3DX_R16G16_UINT_to_UINT2(UINT packedInput) +{ + XMUINT2 unpackedOutput; + unpackedOutput.x = packedInput & 0x0000ffff; + unpackedOutput.y = packedInput>>16; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_UINT2_to_R16G16_UINT(XMUINT2 unpackedInput) +{ + UINT packedOutput; + unpackedInput.x = min(unpackedInput.x,0x0000ffff); + unpackedInput.y = min(unpackedInput.y,0x0000ffff); + packedOutput = ( unpackedInput.x | + (unpackedInput.y<<16) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R16G16_SNORM <-> FLOAT2 +//----------------------------------------------------------------------------- +D3DX11INLINE XMFLOAT2 D3DX_R16G16_SNORM_to_FLOAT2(UINT packedInput) +{ + hlsl_precise XMFLOAT2 unpackedOutput; + XMINT2 signExtendedBits; + signExtendedBits.x = (INT)(packedInput << 16) >> 16; + signExtendedBits.y = (INT)(packedInput & 0xffff0000) >> 16; + unpackedOutput.x = D3DX_INT_to_FLOAT(signExtendedBits.x, 32767); + unpackedOutput.y = D3DX_INT_to_FLOAT(signExtendedBits.y, 32767); + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_FLOAT2_to_R16G16_SNORM(hlsl_precise XMFLOAT2 unpackedInput) +{ + UINT packedOutput; + packedOutput = ( (D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.x), 32767) & 0x0000ffff) | + (D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.y), 32767) <<16) ); + return packedOutput; +} + +//----------------------------------------------------------------------------- +// R16G16_SINT <-> INT2 +//----------------------------------------------------------------------------- +D3DX11INLINE XMINT2 D3DX_R16G16_SINT_to_INT2(UINT packedInput) +{ + XMINT2 unpackedOutput; + unpackedOutput.x = (INT)(packedInput << 16) >> 16; + unpackedOutput.y = (INT)(packedInput & 0xffff0000) >> 16; + return unpackedOutput; +} + +D3DX11INLINE UINT D3DX_INT2_to_R16G16_SINT(XMINT2 unpackedInput) +{ + UINT packedOutput; + unpackedInput.x = max(min(unpackedInput.x,32767),-32768); + unpackedInput.y = max(min(unpackedInput.y,32767),-32768); + packedOutput = ( (unpackedInput.x & 0x0000ffff) | + (unpackedInput.y <<16) ); + return packedOutput; +} + +#endif // __D3DX_DXGI_FORMAT_CONVERT_INL___ diff --git a/dxsdk/Include/D3Dcommon.h b/dxsdk/Include/D3Dcommon.h new file mode 100644 index 0000000..032b8b5 --- /dev/null +++ b/dxsdk/Include/D3Dcommon.h @@ -0,0 +1,787 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3dcommon_h__ +#define __d3dcommon_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D10Blob_FWD_DEFINED__ +#define __ID3D10Blob_FWD_DEFINED__ +typedef interface ID3D10Blob ID3D10Blob; +#endif /* __ID3D10Blob_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3dcommon_0000_0000 */ +/* [local] */ + +typedef +enum D3D_DRIVER_TYPE + { D3D_DRIVER_TYPE_UNKNOWN = 0, + D3D_DRIVER_TYPE_HARDWARE = ( D3D_DRIVER_TYPE_UNKNOWN + 1 ) , + D3D_DRIVER_TYPE_REFERENCE = ( D3D_DRIVER_TYPE_HARDWARE + 1 ) , + D3D_DRIVER_TYPE_NULL = ( D3D_DRIVER_TYPE_REFERENCE + 1 ) , + D3D_DRIVER_TYPE_SOFTWARE = ( D3D_DRIVER_TYPE_NULL + 1 ) , + D3D_DRIVER_TYPE_WARP = ( D3D_DRIVER_TYPE_SOFTWARE + 1 ) + } D3D_DRIVER_TYPE; + +typedef +enum D3D_FEATURE_LEVEL + { D3D_FEATURE_LEVEL_9_1 = 0x9100, + D3D_FEATURE_LEVEL_9_2 = 0x9200, + D3D_FEATURE_LEVEL_9_3 = 0x9300, + D3D_FEATURE_LEVEL_10_0 = 0xa000, + D3D_FEATURE_LEVEL_10_1 = 0xa100, + D3D_FEATURE_LEVEL_11_0 = 0xb000 + } D3D_FEATURE_LEVEL; + +typedef +enum D3D_PRIMITIVE_TOPOLOGY + { D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1, + D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5, + D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13, + D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33, + D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34, + D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35, + D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36, + D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = 37, + D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = 38, + D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = 39, + D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = 40, + D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = 41, + D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = 42, + D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = 43, + D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = 44, + D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = 45, + D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = 46, + D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = 47, + D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = 48, + D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = 49, + D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = 50, + D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = 51, + D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = 52, + D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = 53, + D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = 54, + D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = 55, + D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = 56, + D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = 57, + D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = 58, + D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = 59, + D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = 60, + D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = 61, + D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = 62, + D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = 63, + D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64, + D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, + D3D10_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, + D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST + } D3D_PRIMITIVE_TOPOLOGY; + +typedef +enum D3D_PRIMITIVE + { D3D_PRIMITIVE_UNDEFINED = 0, + D3D_PRIMITIVE_POINT = 1, + D3D_PRIMITIVE_LINE = 2, + D3D_PRIMITIVE_TRIANGLE = 3, + D3D_PRIMITIVE_LINE_ADJ = 6, + D3D_PRIMITIVE_TRIANGLE_ADJ = 7, + D3D_PRIMITIVE_1_CONTROL_POINT_PATCH = 8, + D3D_PRIMITIVE_2_CONTROL_POINT_PATCH = 9, + D3D_PRIMITIVE_3_CONTROL_POINT_PATCH = 10, + D3D_PRIMITIVE_4_CONTROL_POINT_PATCH = 11, + D3D_PRIMITIVE_5_CONTROL_POINT_PATCH = 12, + D3D_PRIMITIVE_6_CONTROL_POINT_PATCH = 13, + D3D_PRIMITIVE_7_CONTROL_POINT_PATCH = 14, + D3D_PRIMITIVE_8_CONTROL_POINT_PATCH = 15, + D3D_PRIMITIVE_9_CONTROL_POINT_PATCH = 16, + D3D_PRIMITIVE_10_CONTROL_POINT_PATCH = 17, + D3D_PRIMITIVE_11_CONTROL_POINT_PATCH = 18, + D3D_PRIMITIVE_12_CONTROL_POINT_PATCH = 19, + D3D_PRIMITIVE_13_CONTROL_POINT_PATCH = 20, + D3D_PRIMITIVE_14_CONTROL_POINT_PATCH = 21, + D3D_PRIMITIVE_15_CONTROL_POINT_PATCH = 22, + D3D_PRIMITIVE_16_CONTROL_POINT_PATCH = 23, + D3D_PRIMITIVE_17_CONTROL_POINT_PATCH = 24, + D3D_PRIMITIVE_18_CONTROL_POINT_PATCH = 25, + D3D_PRIMITIVE_19_CONTROL_POINT_PATCH = 26, + D3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 28, + D3D_PRIMITIVE_21_CONTROL_POINT_PATCH = 29, + D3D_PRIMITIVE_22_CONTROL_POINT_PATCH = 30, + D3D_PRIMITIVE_23_CONTROL_POINT_PATCH = 31, + D3D_PRIMITIVE_24_CONTROL_POINT_PATCH = 32, + D3D_PRIMITIVE_25_CONTROL_POINT_PATCH = 33, + D3D_PRIMITIVE_26_CONTROL_POINT_PATCH = 34, + D3D_PRIMITIVE_27_CONTROL_POINT_PATCH = 35, + D3D_PRIMITIVE_28_CONTROL_POINT_PATCH = 36, + D3D_PRIMITIVE_29_CONTROL_POINT_PATCH = 37, + D3D_PRIMITIVE_30_CONTROL_POINT_PATCH = 38, + D3D_PRIMITIVE_31_CONTROL_POINT_PATCH = 39, + D3D_PRIMITIVE_32_CONTROL_POINT_PATCH = 40, + D3D10_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED, + D3D10_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT, + D3D10_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE, + D3D10_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE, + D3D10_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ, + D3D10_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED, + D3D11_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT, + D3D11_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE, + D3D11_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE, + D3D11_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ, + D3D11_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_1_CONTROL_POINT_PATCH = D3D_PRIMITIVE_1_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_2_CONTROL_POINT_PATCH = D3D_PRIMITIVE_2_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_3_CONTROL_POINT_PATCH = D3D_PRIMITIVE_3_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_4_CONTROL_POINT_PATCH = D3D_PRIMITIVE_4_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_5_CONTROL_POINT_PATCH = D3D_PRIMITIVE_5_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_6_CONTROL_POINT_PATCH = D3D_PRIMITIVE_6_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_7_CONTROL_POINT_PATCH = D3D_PRIMITIVE_7_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_8_CONTROL_POINT_PATCH = D3D_PRIMITIVE_8_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_9_CONTROL_POINT_PATCH = D3D_PRIMITIVE_9_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_10_CONTROL_POINT_PATCH = D3D_PRIMITIVE_10_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_11_CONTROL_POINT_PATCH = D3D_PRIMITIVE_11_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_12_CONTROL_POINT_PATCH = D3D_PRIMITIVE_12_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_13_CONTROL_POINT_PATCH = D3D_PRIMITIVE_13_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_14_CONTROL_POINT_PATCH = D3D_PRIMITIVE_14_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_15_CONTROL_POINT_PATCH = D3D_PRIMITIVE_15_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_16_CONTROL_POINT_PATCH = D3D_PRIMITIVE_16_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_17_CONTROL_POINT_PATCH = D3D_PRIMITIVE_17_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_18_CONTROL_POINT_PATCH = D3D_PRIMITIVE_18_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_19_CONTROL_POINT_PATCH = D3D_PRIMITIVE_19_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_20_CONTROL_POINT_PATCH = D3D_PRIMITIVE_20_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_21_CONTROL_POINT_PATCH = D3D_PRIMITIVE_21_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_22_CONTROL_POINT_PATCH = D3D_PRIMITIVE_22_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_23_CONTROL_POINT_PATCH = D3D_PRIMITIVE_23_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_24_CONTROL_POINT_PATCH = D3D_PRIMITIVE_24_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_25_CONTROL_POINT_PATCH = D3D_PRIMITIVE_25_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_26_CONTROL_POINT_PATCH = D3D_PRIMITIVE_26_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_27_CONTROL_POINT_PATCH = D3D_PRIMITIVE_27_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_28_CONTROL_POINT_PATCH = D3D_PRIMITIVE_28_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_29_CONTROL_POINT_PATCH = D3D_PRIMITIVE_29_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_30_CONTROL_POINT_PATCH = D3D_PRIMITIVE_30_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_31_CONTROL_POINT_PATCH = D3D_PRIMITIVE_31_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_32_CONTROL_POINT_PATCH = D3D_PRIMITIVE_32_CONTROL_POINT_PATCH + } D3D_PRIMITIVE; + +typedef +enum D3D_SRV_DIMENSION + { D3D_SRV_DIMENSION_UNKNOWN = 0, + D3D_SRV_DIMENSION_BUFFER = 1, + D3D_SRV_DIMENSION_TEXTURE1D = 2, + D3D_SRV_DIMENSION_TEXTURE1DARRAY = 3, + D3D_SRV_DIMENSION_TEXTURE2D = 4, + D3D_SRV_DIMENSION_TEXTURE2DARRAY = 5, + D3D_SRV_DIMENSION_TEXTURE2DMS = 6, + D3D_SRV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D_SRV_DIMENSION_TEXTURE3D = 8, + D3D_SRV_DIMENSION_TEXTURECUBE = 9, + D3D_SRV_DIMENSION_TEXTURECUBEARRAY = 10, + D3D_SRV_DIMENSION_BUFFEREX = 11, + D3D10_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D10_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D10_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D10_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D10_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D10_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D10_1_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D10_1_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D10_1_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D11_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D11_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D11_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D11_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D11_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D11_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D11_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_BUFFEREX = D3D_SRV_DIMENSION_BUFFEREX + } D3D_SRV_DIMENSION; + +typedef struct _D3D_SHADER_MACRO + { + LPCSTR Name; + LPCSTR Definition; + } D3D_SHADER_MACRO; + +typedef struct _D3D_SHADER_MACRO *LPD3D_SHADER_MACRO; + +DEFINE_GUID(IID_ID3D10Blob, 0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); + + +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D10Blob_INTERFACE_DEFINED__ +#define __ID3D10Blob_INTERFACE_DEFINED__ + +/* interface ID3D10Blob */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Blob; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8BA5FB08-5195-40e2-AC58-0D989C3A0102") + ID3D10Blob : public IUnknown + { + public: + virtual LPVOID STDMETHODCALLTYPE GetBufferPointer( void) = 0; + + virtual SIZE_T STDMETHODCALLTYPE GetBufferSize( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10BlobVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Blob * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Blob * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Blob * This); + + LPVOID ( STDMETHODCALLTYPE *GetBufferPointer )( + ID3D10Blob * This); + + SIZE_T ( STDMETHODCALLTYPE *GetBufferSize )( + ID3D10Blob * This); + + END_INTERFACE + } ID3D10BlobVtbl; + + interface ID3D10Blob + { + CONST_VTBL struct ID3D10BlobVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Blob_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Blob_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Blob_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Blob_GetBufferPointer(This) \ + ( (This)->lpVtbl -> GetBufferPointer(This) ) + +#define ID3D10Blob_GetBufferSize(This) \ + ( (This)->lpVtbl -> GetBufferSize(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Blob_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3dcommon_0000_0001 */ +/* [local] */ + +typedef interface ID3D10Blob* LPD3D10BLOB; +typedef ID3D10Blob ID3DBlob; +typedef ID3DBlob* LPD3DBLOB; +#define IID_ID3DBlob IID_ID3D10Blob +typedef +enum _D3D_INCLUDE_TYPE + { D3D_INCLUDE_LOCAL = 0, + D3D_INCLUDE_SYSTEM = ( D3D_INCLUDE_LOCAL + 1 ) , + D3D10_INCLUDE_LOCAL = D3D_INCLUDE_LOCAL, + D3D10_INCLUDE_SYSTEM = D3D_INCLUDE_SYSTEM, + D3D_INCLUDE_FORCE_DWORD = 0x7fffffff + } D3D_INCLUDE_TYPE; + +typedef interface ID3DInclude ID3DInclude; +#undef INTERFACE +#define INTERFACE ID3DInclude +DECLARE_INTERFACE(ID3DInclude) +{ + STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE; + STDMETHOD(Close)(THIS_ LPCVOID pData) PURE; +}; +typedef ID3DInclude* LPD3DINCLUDE; +typedef +enum _D3D_SHADER_VARIABLE_CLASS + { D3D_SVC_SCALAR = 0, + D3D_SVC_VECTOR = ( D3D_SVC_SCALAR + 1 ) , + D3D_SVC_MATRIX_ROWS = ( D3D_SVC_VECTOR + 1 ) , + D3D_SVC_MATRIX_COLUMNS = ( D3D_SVC_MATRIX_ROWS + 1 ) , + D3D_SVC_OBJECT = ( D3D_SVC_MATRIX_COLUMNS + 1 ) , + D3D_SVC_STRUCT = ( D3D_SVC_OBJECT + 1 ) , + D3D_SVC_INTERFACE_CLASS = ( D3D_SVC_STRUCT + 1 ) , + D3D_SVC_INTERFACE_POINTER = ( D3D_SVC_INTERFACE_CLASS + 1 ) , + D3D10_SVC_SCALAR = D3D_SVC_SCALAR, + D3D10_SVC_VECTOR = D3D_SVC_VECTOR, + D3D10_SVC_MATRIX_ROWS = D3D_SVC_MATRIX_ROWS, + D3D10_SVC_MATRIX_COLUMNS = D3D_SVC_MATRIX_COLUMNS, + D3D10_SVC_OBJECT = D3D_SVC_OBJECT, + D3D10_SVC_STRUCT = D3D_SVC_STRUCT, + D3D11_SVC_INTERFACE_CLASS = D3D_SVC_INTERFACE_CLASS, + D3D11_SVC_INTERFACE_POINTER = D3D_SVC_INTERFACE_POINTER, + D3D_SVC_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_CLASS; + +typedef +enum _D3D_SHADER_VARIABLE_FLAGS + { D3D_SVF_USERPACKED = 1, + D3D_SVF_USED = 2, + D3D_SVF_INTERFACE_POINTER = 4, + D3D_SVF_INTERFACE_PARAMETER = 8, + D3D10_SVF_USERPACKED = D3D_SVF_USERPACKED, + D3D10_SVF_USED = D3D_SVF_USED, + D3D11_SVF_INTERFACE_POINTER = D3D_SVF_INTERFACE_POINTER, + D3D11_SVF_INTERFACE_PARAMETER = D3D_SVF_INTERFACE_PARAMETER, + D3D_SVF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_FLAGS; + +typedef +enum _D3D_SHADER_VARIABLE_TYPE + { D3D_SVT_VOID = 0, + D3D_SVT_BOOL = 1, + D3D_SVT_INT = 2, + D3D_SVT_FLOAT = 3, + D3D_SVT_STRING = 4, + D3D_SVT_TEXTURE = 5, + D3D_SVT_TEXTURE1D = 6, + D3D_SVT_TEXTURE2D = 7, + D3D_SVT_TEXTURE3D = 8, + D3D_SVT_TEXTURECUBE = 9, + D3D_SVT_SAMPLER = 10, + D3D_SVT_SAMPLER1D = 11, + D3D_SVT_SAMPLER2D = 12, + D3D_SVT_SAMPLER3D = 13, + D3D_SVT_SAMPLERCUBE = 14, + D3D_SVT_PIXELSHADER = 15, + D3D_SVT_VERTEXSHADER = 16, + D3D_SVT_PIXELFRAGMENT = 17, + D3D_SVT_VERTEXFRAGMENT = 18, + D3D_SVT_UINT = 19, + D3D_SVT_UINT8 = 20, + D3D_SVT_GEOMETRYSHADER = 21, + D3D_SVT_RASTERIZER = 22, + D3D_SVT_DEPTHSTENCIL = 23, + D3D_SVT_BLEND = 24, + D3D_SVT_BUFFER = 25, + D3D_SVT_CBUFFER = 26, + D3D_SVT_TBUFFER = 27, + D3D_SVT_TEXTURE1DARRAY = 28, + D3D_SVT_TEXTURE2DARRAY = 29, + D3D_SVT_RENDERTARGETVIEW = 30, + D3D_SVT_DEPTHSTENCILVIEW = 31, + D3D_SVT_TEXTURE2DMS = 32, + D3D_SVT_TEXTURE2DMSARRAY = 33, + D3D_SVT_TEXTURECUBEARRAY = 34, + D3D_SVT_HULLSHADER = 35, + D3D_SVT_DOMAINSHADER = 36, + D3D_SVT_INTERFACE_POINTER = 37, + D3D_SVT_COMPUTESHADER = 38, + D3D_SVT_DOUBLE = 39, + D3D_SVT_RWTEXTURE1D = 40, + D3D_SVT_RWTEXTURE1DARRAY = 41, + D3D_SVT_RWTEXTURE2D = 42, + D3D_SVT_RWTEXTURE2DARRAY = 43, + D3D_SVT_RWTEXTURE3D = 44, + D3D_SVT_RWBUFFER = 45, + D3D_SVT_BYTEADDRESS_BUFFER = 46, + D3D_SVT_RWBYTEADDRESS_BUFFER = 47, + D3D_SVT_STRUCTURED_BUFFER = 48, + D3D_SVT_RWSTRUCTURED_BUFFER = 49, + D3D_SVT_APPEND_STRUCTURED_BUFFER = 50, + D3D_SVT_CONSUME_STRUCTURED_BUFFER = 51, + D3D10_SVT_VOID = D3D_SVT_VOID, + D3D10_SVT_BOOL = D3D_SVT_BOOL, + D3D10_SVT_INT = D3D_SVT_INT, + D3D10_SVT_FLOAT = D3D_SVT_FLOAT, + D3D10_SVT_STRING = D3D_SVT_STRING, + D3D10_SVT_TEXTURE = D3D_SVT_TEXTURE, + D3D10_SVT_TEXTURE1D = D3D_SVT_TEXTURE1D, + D3D10_SVT_TEXTURE2D = D3D_SVT_TEXTURE2D, + D3D10_SVT_TEXTURE3D = D3D_SVT_TEXTURE3D, + D3D10_SVT_TEXTURECUBE = D3D_SVT_TEXTURECUBE, + D3D10_SVT_SAMPLER = D3D_SVT_SAMPLER, + D3D10_SVT_SAMPLER1D = D3D_SVT_SAMPLER1D, + D3D10_SVT_SAMPLER2D = D3D_SVT_SAMPLER2D, + D3D10_SVT_SAMPLER3D = D3D_SVT_SAMPLER3D, + D3D10_SVT_SAMPLERCUBE = D3D_SVT_SAMPLERCUBE, + D3D10_SVT_PIXELSHADER = D3D_SVT_PIXELSHADER, + D3D10_SVT_VERTEXSHADER = D3D_SVT_VERTEXSHADER, + D3D10_SVT_PIXELFRAGMENT = D3D_SVT_PIXELFRAGMENT, + D3D10_SVT_VERTEXFRAGMENT = D3D_SVT_VERTEXFRAGMENT, + D3D10_SVT_UINT = D3D_SVT_UINT, + D3D10_SVT_UINT8 = D3D_SVT_UINT8, + D3D10_SVT_GEOMETRYSHADER = D3D_SVT_GEOMETRYSHADER, + D3D10_SVT_RASTERIZER = D3D_SVT_RASTERIZER, + D3D10_SVT_DEPTHSTENCIL = D3D_SVT_DEPTHSTENCIL, + D3D10_SVT_BLEND = D3D_SVT_BLEND, + D3D10_SVT_BUFFER = D3D_SVT_BUFFER, + D3D10_SVT_CBUFFER = D3D_SVT_CBUFFER, + D3D10_SVT_TBUFFER = D3D_SVT_TBUFFER, + D3D10_SVT_TEXTURE1DARRAY = D3D_SVT_TEXTURE1DARRAY, + D3D10_SVT_TEXTURE2DARRAY = D3D_SVT_TEXTURE2DARRAY, + D3D10_SVT_RENDERTARGETVIEW = D3D_SVT_RENDERTARGETVIEW, + D3D10_SVT_DEPTHSTENCILVIEW = D3D_SVT_DEPTHSTENCILVIEW, + D3D10_SVT_TEXTURE2DMS = D3D_SVT_TEXTURE2DMS, + D3D10_SVT_TEXTURE2DMSARRAY = D3D_SVT_TEXTURE2DMSARRAY, + D3D10_SVT_TEXTURECUBEARRAY = D3D_SVT_TEXTURECUBEARRAY, + D3D11_SVT_HULLSHADER = D3D_SVT_HULLSHADER, + D3D11_SVT_DOMAINSHADER = D3D_SVT_DOMAINSHADER, + D3D11_SVT_INTERFACE_POINTER = D3D_SVT_INTERFACE_POINTER, + D3D11_SVT_COMPUTESHADER = D3D_SVT_COMPUTESHADER, + D3D11_SVT_DOUBLE = D3D_SVT_DOUBLE, + D3D11_SVT_RWTEXTURE1D = D3D_SVT_RWTEXTURE1D, + D3D11_SVT_RWTEXTURE1DARRAY = D3D_SVT_RWTEXTURE1DARRAY, + D3D11_SVT_RWTEXTURE2D = D3D_SVT_RWTEXTURE2D, + D3D11_SVT_RWTEXTURE2DARRAY = D3D_SVT_RWTEXTURE2DARRAY, + D3D11_SVT_RWTEXTURE3D = D3D_SVT_RWTEXTURE3D, + D3D11_SVT_RWBUFFER = D3D_SVT_RWBUFFER, + D3D11_SVT_BYTEADDRESS_BUFFER = D3D_SVT_BYTEADDRESS_BUFFER, + D3D11_SVT_RWBYTEADDRESS_BUFFER = D3D_SVT_RWBYTEADDRESS_BUFFER, + D3D11_SVT_STRUCTURED_BUFFER = D3D_SVT_STRUCTURED_BUFFER, + D3D11_SVT_RWSTRUCTURED_BUFFER = D3D_SVT_RWSTRUCTURED_BUFFER, + D3D11_SVT_APPEND_STRUCTURED_BUFFER = D3D_SVT_APPEND_STRUCTURED_BUFFER, + D3D11_SVT_CONSUME_STRUCTURED_BUFFER = D3D_SVT_CONSUME_STRUCTURED_BUFFER, + D3D_SVT_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_TYPE; + +typedef +enum _D3D_SHADER_INPUT_FLAGS + { D3D_SIF_USERPACKED = 1, + D3D_SIF_COMPARISON_SAMPLER = 2, + D3D_SIF_TEXTURE_COMPONENT_0 = 4, + D3D_SIF_TEXTURE_COMPONENT_1 = 8, + D3D_SIF_TEXTURE_COMPONENTS = 12, + D3D10_SIF_USERPACKED = D3D_SIF_USERPACKED, + D3D10_SIF_COMPARISON_SAMPLER = D3D_SIF_COMPARISON_SAMPLER, + D3D10_SIF_TEXTURE_COMPONENT_0 = D3D_SIF_TEXTURE_COMPONENT_0, + D3D10_SIF_TEXTURE_COMPONENT_1 = D3D_SIF_TEXTURE_COMPONENT_1, + D3D10_SIF_TEXTURE_COMPONENTS = D3D_SIF_TEXTURE_COMPONENTS, + D3D_SIF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_INPUT_FLAGS; + +typedef +enum _D3D_SHADER_INPUT_TYPE + { D3D_SIT_CBUFFER = 0, + D3D_SIT_TBUFFER = ( D3D_SIT_CBUFFER + 1 ) , + D3D_SIT_TEXTURE = ( D3D_SIT_TBUFFER + 1 ) , + D3D_SIT_SAMPLER = ( D3D_SIT_TEXTURE + 1 ) , + D3D_SIT_UAV_RWTYPED = ( D3D_SIT_SAMPLER + 1 ) , + D3D_SIT_STRUCTURED = ( D3D_SIT_UAV_RWTYPED + 1 ) , + D3D_SIT_UAV_RWSTRUCTURED = ( D3D_SIT_STRUCTURED + 1 ) , + D3D_SIT_BYTEADDRESS = ( D3D_SIT_UAV_RWSTRUCTURED + 1 ) , + D3D_SIT_UAV_RWBYTEADDRESS = ( D3D_SIT_BYTEADDRESS + 1 ) , + D3D_SIT_UAV_APPEND_STRUCTURED = ( D3D_SIT_UAV_RWBYTEADDRESS + 1 ) , + D3D_SIT_UAV_CONSUME_STRUCTURED = ( D3D_SIT_UAV_APPEND_STRUCTURED + 1 ) , + D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = ( D3D_SIT_UAV_CONSUME_STRUCTURED + 1 ) , + D3D10_SIT_CBUFFER = D3D_SIT_CBUFFER, + D3D10_SIT_TBUFFER = D3D_SIT_TBUFFER, + D3D10_SIT_TEXTURE = D3D_SIT_TEXTURE, + D3D10_SIT_SAMPLER = D3D_SIT_SAMPLER, + D3D11_SIT_UAV_RWTYPED = D3D_SIT_UAV_RWTYPED, + D3D11_SIT_STRUCTURED = D3D_SIT_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED = D3D_SIT_UAV_RWSTRUCTURED, + D3D11_SIT_BYTEADDRESS = D3D_SIT_BYTEADDRESS, + D3D11_SIT_UAV_RWBYTEADDRESS = D3D_SIT_UAV_RWBYTEADDRESS, + D3D11_SIT_UAV_APPEND_STRUCTURED = D3D_SIT_UAV_APPEND_STRUCTURED, + D3D11_SIT_UAV_CONSUME_STRUCTURED = D3D_SIT_UAV_CONSUME_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER + } D3D_SHADER_INPUT_TYPE; + +typedef +enum _D3D_SHADER_CBUFFER_FLAGS + { D3D_CBF_USERPACKED = 1, + D3D10_CBF_USERPACKED = D3D_CBF_USERPACKED, + D3D_CBF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_CBUFFER_FLAGS; + +typedef +enum _D3D_CBUFFER_TYPE + { D3D_CT_CBUFFER = 0, + D3D_CT_TBUFFER = ( D3D_CT_CBUFFER + 1 ) , + D3D_CT_INTERFACE_POINTERS = ( D3D_CT_TBUFFER + 1 ) , + D3D_CT_RESOURCE_BIND_INFO = ( D3D_CT_INTERFACE_POINTERS + 1 ) , + D3D10_CT_CBUFFER = D3D_CT_CBUFFER, + D3D10_CT_TBUFFER = D3D_CT_TBUFFER, + D3D11_CT_CBUFFER = D3D_CT_CBUFFER, + D3D11_CT_TBUFFER = D3D_CT_TBUFFER, + D3D11_CT_INTERFACE_POINTERS = D3D_CT_INTERFACE_POINTERS, + D3D11_CT_RESOURCE_BIND_INFO = D3D_CT_RESOURCE_BIND_INFO + } D3D_CBUFFER_TYPE; + +typedef +enum D3D_NAME + { D3D_NAME_UNDEFINED = 0, + D3D_NAME_POSITION = 1, + D3D_NAME_CLIP_DISTANCE = 2, + D3D_NAME_CULL_DISTANCE = 3, + D3D_NAME_RENDER_TARGET_ARRAY_INDEX = 4, + D3D_NAME_VIEWPORT_ARRAY_INDEX = 5, + D3D_NAME_VERTEX_ID = 6, + D3D_NAME_PRIMITIVE_ID = 7, + D3D_NAME_INSTANCE_ID = 8, + D3D_NAME_IS_FRONT_FACE = 9, + D3D_NAME_SAMPLE_INDEX = 10, + D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR = 11, + D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = 12, + D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR = 13, + D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR = 14, + D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR = 15, + D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR = 16, + D3D_NAME_TARGET = 64, + D3D_NAME_DEPTH = 65, + D3D_NAME_COVERAGE = 66, + D3D_NAME_DEPTH_GREATER_EQUAL = 67, + D3D_NAME_DEPTH_LESS_EQUAL = 68, + D3D10_NAME_UNDEFINED = D3D_NAME_UNDEFINED, + D3D10_NAME_POSITION = D3D_NAME_POSITION, + D3D10_NAME_CLIP_DISTANCE = D3D_NAME_CLIP_DISTANCE, + D3D10_NAME_CULL_DISTANCE = D3D_NAME_CULL_DISTANCE, + D3D10_NAME_RENDER_TARGET_ARRAY_INDEX = D3D_NAME_RENDER_TARGET_ARRAY_INDEX, + D3D10_NAME_VIEWPORT_ARRAY_INDEX = D3D_NAME_VIEWPORT_ARRAY_INDEX, + D3D10_NAME_VERTEX_ID = D3D_NAME_VERTEX_ID, + D3D10_NAME_PRIMITIVE_ID = D3D_NAME_PRIMITIVE_ID, + D3D10_NAME_INSTANCE_ID = D3D_NAME_INSTANCE_ID, + D3D10_NAME_IS_FRONT_FACE = D3D_NAME_IS_FRONT_FACE, + D3D10_NAME_SAMPLE_INDEX = D3D_NAME_SAMPLE_INDEX, + D3D10_NAME_TARGET = D3D_NAME_TARGET, + D3D10_NAME_DEPTH = D3D_NAME_DEPTH, + D3D10_NAME_COVERAGE = D3D_NAME_COVERAGE, + D3D11_NAME_FINAL_QUAD_EDGE_TESSFACTOR = D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_EDGE_TESSFACTOR = D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_INSIDE_TESSFACTOR = D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DETAIL_TESSFACTOR = D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DENSITY_TESSFACTOR = D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR, + D3D11_NAME_DEPTH_GREATER_EQUAL = D3D_NAME_DEPTH_GREATER_EQUAL, + D3D11_NAME_DEPTH_LESS_EQUAL = D3D_NAME_DEPTH_LESS_EQUAL + } D3D_NAME; + +typedef +enum D3D_RESOURCE_RETURN_TYPE + { D3D_RETURN_TYPE_UNORM = 1, + D3D_RETURN_TYPE_SNORM = 2, + D3D_RETURN_TYPE_SINT = 3, + D3D_RETURN_TYPE_UINT = 4, + D3D_RETURN_TYPE_FLOAT = 5, + D3D_RETURN_TYPE_MIXED = 6, + D3D_RETURN_TYPE_DOUBLE = 7, + D3D_RETURN_TYPE_CONTINUED = 8, + D3D10_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM, + D3D10_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM, + D3D10_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT, + D3D10_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT, + D3D10_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT, + D3D10_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM, + D3D11_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM, + D3D11_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT, + D3D11_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT, + D3D11_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT, + D3D11_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_DOUBLE = D3D_RETURN_TYPE_DOUBLE, + D3D11_RETURN_TYPE_CONTINUED = D3D_RETURN_TYPE_CONTINUED + } D3D_RESOURCE_RETURN_TYPE; + +typedef +enum D3D_REGISTER_COMPONENT_TYPE + { D3D_REGISTER_COMPONENT_UNKNOWN = 0, + D3D_REGISTER_COMPONENT_UINT32 = 1, + D3D_REGISTER_COMPONENT_SINT32 = 2, + D3D_REGISTER_COMPONENT_FLOAT32 = 3, + D3D10_REGISTER_COMPONENT_UNKNOWN = D3D_REGISTER_COMPONENT_UNKNOWN, + D3D10_REGISTER_COMPONENT_UINT32 = D3D_REGISTER_COMPONENT_UINT32, + D3D10_REGISTER_COMPONENT_SINT32 = D3D_REGISTER_COMPONENT_SINT32, + D3D10_REGISTER_COMPONENT_FLOAT32 = D3D_REGISTER_COMPONENT_FLOAT32 + } D3D_REGISTER_COMPONENT_TYPE; + +typedef +enum D3D_TESSELLATOR_DOMAIN + { D3D_TESSELLATOR_DOMAIN_UNDEFINED = 0, + D3D_TESSELLATOR_DOMAIN_ISOLINE = 1, + D3D_TESSELLATOR_DOMAIN_TRI = 2, + D3D_TESSELLATOR_DOMAIN_QUAD = 3, + D3D11_TESSELLATOR_DOMAIN_UNDEFINED = D3D_TESSELLATOR_DOMAIN_UNDEFINED, + D3D11_TESSELLATOR_DOMAIN_ISOLINE = D3D_TESSELLATOR_DOMAIN_ISOLINE, + D3D11_TESSELLATOR_DOMAIN_TRI = D3D_TESSELLATOR_DOMAIN_TRI, + D3D11_TESSELLATOR_DOMAIN_QUAD = D3D_TESSELLATOR_DOMAIN_QUAD + } D3D_TESSELLATOR_DOMAIN; + +typedef +enum D3D_TESSELLATOR_PARTITIONING + { D3D_TESSELLATOR_PARTITIONING_UNDEFINED = 0, + D3D_TESSELLATOR_PARTITIONING_INTEGER = 1, + D3D_TESSELLATOR_PARTITIONING_POW2 = 2, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4, + D3D11_TESSELLATOR_PARTITIONING_UNDEFINED = D3D_TESSELLATOR_PARTITIONING_UNDEFINED, + D3D11_TESSELLATOR_PARTITIONING_INTEGER = D3D_TESSELLATOR_PARTITIONING_INTEGER, + D3D11_TESSELLATOR_PARTITIONING_POW2 = D3D_TESSELLATOR_PARTITIONING_POW2, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN + } D3D_TESSELLATOR_PARTITIONING; + +typedef +enum D3D_TESSELLATOR_OUTPUT_PRIMITIVE + { D3D_TESSELLATOR_OUTPUT_UNDEFINED = 0, + D3D_TESSELLATOR_OUTPUT_POINT = 1, + D3D_TESSELLATOR_OUTPUT_LINE = 2, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW = 3, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4, + D3D11_TESSELLATOR_OUTPUT_UNDEFINED = D3D_TESSELLATOR_OUTPUT_UNDEFINED, + D3D11_TESSELLATOR_OUTPUT_POINT = D3D_TESSELLATOR_OUTPUT_POINT, + D3D11_TESSELLATOR_OUTPUT_LINE = D3D_TESSELLATOR_OUTPUT_LINE, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW + } D3D_TESSELLATOR_OUTPUT_PRIMITIVE; + +DEFINE_GUID(WKPDID_D3DDebugObjectName,0x429b8c22,0x9188,0x4b0c,0x87,0x42,0xac,0xb0,0xbf,0x85,0xc2,0x00); + + +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0001_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/dxsdk/Include/D3Dcompiler.h b/dxsdk/Include/D3Dcompiler.h new file mode 100644 index 0000000..fea519f --- /dev/null +++ b/dxsdk/Include/D3Dcompiler.h @@ -0,0 +1,397 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3DCompiler.h +// Content: D3D Compilation Types and APIs +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DCOMPILER_H__ +#define __D3DCOMPILER_H__ + +// Current name of the DLL shipped in the same SDK as this header. + + +#define D3DCOMPILER_DLL_W L"d3dcompiler_43.dll" +#define D3DCOMPILER_DLL_A "d3dcompiler_43.dll" + +#ifdef UNICODE + #define D3DCOMPILER_DLL D3DCOMPILER_DLL_W +#else + #define D3DCOMPILER_DLL D3DCOMPILER_DLL_A +#endif + +#include "d3d11shader.h" + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//---------------------------------------------------------------------------- +// D3DCOMPILE flags: +// ----------------- +// D3DCOMPILE_DEBUG +// Insert debug file/line/type/symbol information. +// +// D3DCOMPILE_SKIP_VALIDATION +// Do not validate the generated code against known capabilities and +// constraints. This option is only recommended when compiling shaders +// you KNOW will work. (ie. have compiled before without this option.) +// Shaders are always validated by D3D before they are set to the device. +// +// D3DCOMPILE_SKIP_OPTIMIZATION +// Instructs the compiler to skip optimization steps during code generation. +// Unless you are trying to isolate a problem in your code using this option +// is not recommended. +// +// D3DCOMPILE_PACK_MATRIX_ROW_MAJOR +// Unless explicitly specified, matrices will be packed in row-major order +// on input and output from the shader. +// +// D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR +// Unless explicitly specified, matrices will be packed in column-major +// order on input and output from the shader. This is generally more +// efficient, since it allows vector-matrix multiplication to be performed +// using a series of dot-products. +// +// D3DCOMPILE_PARTIAL_PRECISION +// Force all computations in resulting shader to occur at partial precision. +// This may result in faster evaluation of shaders on some hardware. +// +// D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT +// Force compiler to compile against the next highest available software +// target for vertex shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT +// Force compiler to compile against the next highest available software +// target for pixel shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DCOMPILE_NO_PRESHADER +// Disables Preshaders. Using this flag will cause the compiler to not +// pull out static expression for evaluation on the host cpu +// +// D3DCOMPILE_AVOID_FLOW_CONTROL +// Hint compiler to avoid flow-control constructs where possible. +// +// D3DCOMPILE_PREFER_FLOW_CONTROL +// Hint compiler to prefer flow-control constructs where possible. +// +// D3DCOMPILE_ENABLE_STRICTNESS +// By default, the HLSL/Effect compilers are not strict on deprecated syntax. +// Specifying this flag enables the strict mode. Deprecated syntax may be +// removed in a future release, and enabling syntax is a good way to make +// sure your shaders comply to the latest spec. +// +// D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY +// This enables older shaders to compile to 4_0 targets. +// +//---------------------------------------------------------------------------- + +#define D3DCOMPILE_DEBUG (1 << 0) +#define D3DCOMPILE_SKIP_VALIDATION (1 << 1) +#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2) +#define D3DCOMPILE_PACK_MATRIX_ROW_MAJOR (1 << 3) +#define D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR (1 << 4) +#define D3DCOMPILE_PARTIAL_PRECISION (1 << 5) +#define D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT (1 << 6) +#define D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT (1 << 7) +#define D3DCOMPILE_NO_PRESHADER (1 << 8) +#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9) +#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10) +#define D3DCOMPILE_ENABLE_STRICTNESS (1 << 11) +#define D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY (1 << 12) +#define D3DCOMPILE_IEEE_STRICTNESS (1 << 13) +#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14) +#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0 +#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15)) +#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) +#define D3DCOMPILE_RESERVED16 (1 << 16) +#define D3DCOMPILE_RESERVED17 (1 << 17) +#define D3DCOMPILE_WARNINGS_ARE_ERRORS (1 << 18) + +//---------------------------------------------------------------------------- +// D3DCOMPILE_EFFECT flags: +// ------------------------------------- +// These flags are passed in when creating an effect, and affect +// either compilation behavior or runtime effect behavior +// +// D3DCOMPILE_EFFECT_CHILD_EFFECT +// Compile this .fx file to a child effect. Child effects have no +// initializers for any shared values as these are initialied in the +// master effect (pool). +// +// D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS +// By default, performance mode is enabled. Performance mode +// disallows mutable state objects by preventing non-literal +// expressions from appearing in state object definitions. +// Specifying this flag will disable the mode and allow for mutable +// state objects. +// +//---------------------------------------------------------------------------- + +#define D3DCOMPILE_EFFECT_CHILD_EFFECT (1 << 0) +#define D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS (1 << 1) + +//---------------------------------------------------------------------------- +// D3DCompile: +// ---------- +// Compile source text into bytecode appropriate for the given target. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DCompile(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in_opt LPCSTR pSourceName, + __in_xcount_opt(pDefines->Name != NULL) CONST D3D_SHADER_MACRO* pDefines, + __in_opt ID3DInclude* pInclude, + __in LPCSTR pEntrypoint, + __in LPCSTR pTarget, + __in UINT Flags1, + __in UINT Flags2, + __out ID3DBlob** ppCode, + __out_opt ID3DBlob** ppErrorMsgs); + +typedef HRESULT (WINAPI *pD3DCompile) + (LPCVOID pSrcData, + SIZE_T SrcDataSize, + LPCSTR pFileName, + CONST D3D_SHADER_MACRO* pDefines, + ID3DInclude* pInclude, + LPCSTR pEntrypoint, + LPCSTR pTarget, + UINT Flags1, + UINT Flags2, + ID3DBlob** ppCode, + ID3DBlob** ppErrorMsgs); + +//---------------------------------------------------------------------------- +// D3DPreprocess: +// ---------- +// Process source text with the compiler's preprocessor and return +// the resulting text. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DPreprocess(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in_opt LPCSTR pSourceName, + __in_opt CONST D3D_SHADER_MACRO* pDefines, + __in_opt ID3DInclude* pInclude, + __out ID3DBlob** ppCodeText, + __out_opt ID3DBlob** ppErrorMsgs); + +typedef HRESULT (WINAPI *pD3DPreprocess) + (LPCVOID pSrcData, + SIZE_T SrcDataSize, + LPCSTR pFileName, + CONST D3D_SHADER_MACRO* pDefines, + ID3DInclude* pInclude, + ID3DBlob** ppCodeText, + ID3DBlob** ppErrorMsgs); + +//---------------------------------------------------------------------------- +// D3DGetDebugInfo: +// ----------------------- +// Gets shader debug info. Debug info is generated by D3DCompile and is +// embedded in the body of the shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetDebugInfo(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppDebugInfo); + +//---------------------------------------------------------------------------- +// D3DReflect: +// ---------- +// Shader code contains metadata that can be inspected via the +// reflection APIs. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DReflect(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in REFIID pInterface, + __out void** ppReflector); + +//---------------------------------------------------------------------------- +// D3DDisassemble: +// ---------------------- +// Takes a binary shader and returns a buffer containing text assembly. +//---------------------------------------------------------------------------- + +#define D3D_DISASM_ENABLE_COLOR_CODE 0x00000001 +#define D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS 0x00000002 +#define D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING 0x00000004 +#define D3D_DISASM_ENABLE_INSTRUCTION_CYCLE 0x00000008 +#define D3D_DISASM_DISABLE_DEBUG_INFO 0x00000010 + +HRESULT WINAPI +D3DDisassemble(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in UINT Flags, + __in_opt LPCSTR szComments, + __out ID3DBlob** ppDisassembly); + +typedef HRESULT (WINAPI *pD3DDisassemble) + (__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in UINT Flags, + __in_opt LPCSTR szComments, + __out ID3DBlob** ppDisassembly); + +//---------------------------------------------------------------------------- +// D3DDisassemble10Effect: +// ----------------------- +// Takes a D3D10 effect interface and returns a +// buffer containing text assembly. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DDisassemble10Effect(__in interface ID3D10Effect *pEffect, + __in UINT Flags, + __out ID3DBlob** ppDisassembly); + +//---------------------------------------------------------------------------- +// D3DGetInputSignatureBlob: +// ----------------------- +// Retrieve the input signature from a compilation result. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetInputSignatureBlob(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppSignatureBlob); + +//---------------------------------------------------------------------------- +// D3DGetOutputSignatureBlob: +// ----------------------- +// Retrieve the output signature from a compilation result. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetOutputSignatureBlob(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppSignatureBlob); + +//---------------------------------------------------------------------------- +// D3DGetInputAndOutputSignatureBlob: +// ----------------------- +// Retrieve the input and output signatures from a compilation result. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetInputAndOutputSignatureBlob(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppSignatureBlob); + +//---------------------------------------------------------------------------- +// D3DStripShader: +// ----------------------- +// Removes unwanted blobs from a compilation result +//---------------------------------------------------------------------------- + +typedef enum D3DCOMPILER_STRIP_FLAGS +{ + D3DCOMPILER_STRIP_REFLECTION_DATA = 1, + D3DCOMPILER_STRIP_DEBUG_INFO = 2, + D3DCOMPILER_STRIP_TEST_BLOBS = 4, + D3DCOMPILER_STRIP_FORCE_DWORD = 0x7fffffff, +} D3DCOMPILER_STRIP_FLAGS; + +HRESULT WINAPI +D3DStripShader(__in_bcount(BytecodeLength) LPCVOID pShaderBytecode, + __in SIZE_T BytecodeLength, + __in UINT uStripFlags, + __out ID3DBlob** ppStrippedBlob); + +//---------------------------------------------------------------------------- +// D3DGetBlobPart: +// ----------------------- +// Extracts information from a compilation result. +//---------------------------------------------------------------------------- + +typedef enum D3D_BLOB_PART +{ + D3D_BLOB_INPUT_SIGNATURE_BLOB, + D3D_BLOB_OUTPUT_SIGNATURE_BLOB, + D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, + D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, + D3D_BLOB_ALL_SIGNATURE_BLOB, + D3D_BLOB_DEBUG_INFO, + D3D_BLOB_LEGACY_SHADER, + D3D_BLOB_XNA_PREPASS_SHADER, + D3D_BLOB_XNA_SHADER, + + // Test parts are only produced by special compiler versions and so + // are usually not present in shaders. + D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000, + D3D_BLOB_TEST_COMPILE_DETAILS, + D3D_BLOB_TEST_COMPILE_PERF, +} D3D_BLOB_PART; + +HRESULT WINAPI +D3DGetBlobPart(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in D3D_BLOB_PART Part, + __in UINT Flags, + __out ID3DBlob** ppPart); + +//---------------------------------------------------------------------------- +// D3DCompressShaders: +// ----------------------- +// Compresses a set of shaders into a more compact form. +//---------------------------------------------------------------------------- + +typedef struct _D3D_SHADER_DATA +{ + LPCVOID pBytecode; + SIZE_T BytecodeLength; +} D3D_SHADER_DATA; + +#define D3D_COMPRESS_SHADER_KEEP_ALL_PARTS 0x00000001 + +HRESULT WINAPI +D3DCompressShaders(__in UINT uNumShaders, + __in_ecount(uNumShaders) D3D_SHADER_DATA* pShaderData, + __in UINT uFlags, + __out ID3DBlob** ppCompressedData); + +//---------------------------------------------------------------------------- +// D3DDecompressShaders: +// ----------------------- +// Decompresses one or more shaders from a compressed set. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DDecompressShaders(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in UINT uNumShaders, + __in UINT uStartIndex, + __in_ecount_opt(uNumShaders) UINT* pIndices, + __in UINT uFlags, + __out_ecount(uNumShaders) ID3DBlob** ppShaders, + __out_opt UINT* pTotalShaders); + +//---------------------------------------------------------------------------- +// D3DCreateBlob: +// ----------------------- +// Create an ID3DBlob instance. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DCreateBlob(__in SIZE_T Size, + __out ID3DBlob** ppBlob); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif // #ifndef __D3DCOMPILER_H__ diff --git a/dxsdk/Include/DWrite.h b/dxsdk/Include/DWrite.h new file mode 100644 index 0000000..fc3b637 --- /dev/null +++ b/dxsdk/Include/DWrite.h @@ -0,0 +1,4995 @@ +//+-------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Abstract: +// DirectX Typography Services public API definitions. +// +//---------------------------------------------------------------------------- + +#ifndef DWRITE_H_INCLUDED +#define DWRITE_H_INCLUDED + +#if _MSC_VER > 1000 +#pragma once +#endif + +#ifndef DWRITE_NO_WINDOWS_H + +#include +#include + +#endif // DWRITE_NO_WINDOWS_H + +#include + +#ifndef DWRITE_DECLARE_INTERFACE +#define DWRITE_DECLARE_INTERFACE(iid) DECLSPEC_UUID(iid) DECLSPEC_NOVTABLE +#endif + +#ifndef DWRITE_EXPORT +#define DWRITE_EXPORT __declspec(dllimport) WINAPI +#endif + +/// +/// The type of a font represented by a single font file. +/// Font formats that consist of multiple files, e.g. Type 1 .PFM and .PFB, have +/// separate enum values for each of the file type. +/// +enum DWRITE_FONT_FILE_TYPE +{ + /// + /// Font type is not recognized by the DirectWrite font system. + /// + DWRITE_FONT_FILE_TYPE_UNKNOWN, + + /// + /// OpenType font with CFF outlines. + /// + DWRITE_FONT_FILE_TYPE_CFF, + + /// + /// OpenType font with TrueType outlines. + /// + DWRITE_FONT_FILE_TYPE_TRUETYPE, + + /// + /// OpenType font that contains a TrueType collection. + /// + DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION, + + /// + /// Type 1 PFM font. + /// + DWRITE_FONT_FILE_TYPE_TYPE1_PFM, + + /// + /// Type 1 PFB font. + /// + DWRITE_FONT_FILE_TYPE_TYPE1_PFB, + + /// + /// Vector .FON font. + /// + DWRITE_FONT_FILE_TYPE_VECTOR, + + /// + /// Bitmap .FON font. + /// + DWRITE_FONT_FILE_TYPE_BITMAP +}; + +/// +/// The file format of a complete font face. +/// Font formats that consist of multiple files, e.g. Type 1 .PFM and .PFB, have +/// a single enum entry. +/// +enum DWRITE_FONT_FACE_TYPE +{ + /// + /// OpenType font face with CFF outlines. + /// + DWRITE_FONT_FACE_TYPE_CFF, + + /// + /// OpenType font face with TrueType outlines. + /// + DWRITE_FONT_FACE_TYPE_TRUETYPE, + + /// + /// OpenType font face that is a part of a TrueType collection. + /// + DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION, + + /// + /// A Type 1 font face. + /// + DWRITE_FONT_FACE_TYPE_TYPE1, + + /// + /// A vector .FON format font face. + /// + DWRITE_FONT_FACE_TYPE_VECTOR, + + /// + /// A bitmap .FON format font face. + /// + DWRITE_FONT_FACE_TYPE_BITMAP, + + /// + /// Font face type is not recognized by the DirectWrite font system. + /// + DWRITE_FONT_FACE_TYPE_UNKNOWN +}; + +/// +/// Specifies algorithmic style simulations to be applied to the font face. +/// Bold and oblique simulations can be combined via bitwise OR operation. +/// +enum DWRITE_FONT_SIMULATIONS +{ + /// + /// No simulations are performed. + /// + DWRITE_FONT_SIMULATIONS_NONE = 0x0000, + + /// + /// Algorithmic emboldening is performed. + /// + DWRITE_FONT_SIMULATIONS_BOLD = 0x0001, + + /// + /// Algorithmic italicization is performed. + /// + DWRITE_FONT_SIMULATIONS_OBLIQUE = 0x0002 +}; + +#ifdef DEFINE_ENUM_FLAG_OPERATORS +DEFINE_ENUM_FLAG_OPERATORS(DWRITE_FONT_SIMULATIONS); +#endif + +/// +/// The font weight enumeration describes common values for degree of blackness or thickness of strokes of characters in a font. +/// Font weight values less than 1 or greater than 999 are considered to be invalid, and they are rejected by font API functions. +/// +enum DWRITE_FONT_WEIGHT +{ + /// + /// Predefined font weight : Thin (100). + /// + DWRITE_FONT_WEIGHT_THIN = 100, + + /// + /// Predefined font weight : Extra-light (200). + /// + DWRITE_FONT_WEIGHT_EXTRA_LIGHT = 200, + + /// + /// Predefined font weight : Ultra-light (200). + /// + DWRITE_FONT_WEIGHT_ULTRA_LIGHT = 200, + + /// + /// Predefined font weight : Light (300). + /// + DWRITE_FONT_WEIGHT_LIGHT = 300, + + /// + /// Predefined font weight : Normal (400). + /// + DWRITE_FONT_WEIGHT_NORMAL = 400, + + /// + /// Predefined font weight : Regular (400). + /// + DWRITE_FONT_WEIGHT_REGULAR = 400, + + /// + /// Predefined font weight : Medium (500). + /// + DWRITE_FONT_WEIGHT_MEDIUM = 500, + + /// + /// Predefined font weight : Demi-bold (600). + /// + DWRITE_FONT_WEIGHT_DEMI_BOLD = 600, + + /// + /// Predefined font weight : Semi-bold (600). + /// + DWRITE_FONT_WEIGHT_SEMI_BOLD = 600, + + /// + /// Predefined font weight : Bold (700). + /// + DWRITE_FONT_WEIGHT_BOLD = 700, + + /// + /// Predefined font weight : Extra-bold (800). + /// + DWRITE_FONT_WEIGHT_EXTRA_BOLD = 800, + + /// + /// Predefined font weight : Ultra-bold (800). + /// + DWRITE_FONT_WEIGHT_ULTRA_BOLD = 800, + + /// + /// Predefined font weight : Black (900). + /// + DWRITE_FONT_WEIGHT_BLACK = 900, + + /// + /// Predefined font weight : Heavy (900). + /// + DWRITE_FONT_WEIGHT_HEAVY = 900, + + /// + /// Predefined font weight : Extra-black (950). + /// + DWRITE_FONT_WEIGHT_EXTRA_BLACK = 950, + + /// + /// Predefined font weight : Ultra-black (950). + /// + DWRITE_FONT_WEIGHT_ULTRA_BLACK = 950 +}; + +/// +/// The font stretch enumeration describes relative change from the normal aspect ratio +/// as specified by a font designer for the glyphs in a font. +/// Values less than 1 or greater than 9 are considered to be invalid, and they are rejected by font API functions. +/// +enum DWRITE_FONT_STRETCH +{ + /// + /// Predefined font stretch : Not known (0). + /// + DWRITE_FONT_STRETCH_UNDEFINED = 0, + + /// + /// Predefined font stretch : Ultra-condensed (1). + /// + DWRITE_FONT_STRETCH_ULTRA_CONDENSED = 1, + + /// + /// Predefined font stretch : Extra-condensed (2). + /// + DWRITE_FONT_STRETCH_EXTRA_CONDENSED = 2, + + /// + /// Predefined font stretch : Condensed (3). + /// + DWRITE_FONT_STRETCH_CONDENSED = 3, + + /// + /// Predefined font stretch : Semi-condensed (4). + /// + DWRITE_FONT_STRETCH_SEMI_CONDENSED = 4, + + /// + /// Predefined font stretch : Normal (5). + /// + DWRITE_FONT_STRETCH_NORMAL = 5, + + /// + /// Predefined font stretch : Medium (5). + /// + DWRITE_FONT_STRETCH_MEDIUM = 5, + + /// + /// Predefined font stretch : Semi-expanded (6). + /// + DWRITE_FONT_STRETCH_SEMI_EXPANDED = 6, + + /// + /// Predefined font stretch : Expanded (7). + /// + DWRITE_FONT_STRETCH_EXPANDED = 7, + + /// + /// Predefined font stretch : Extra-expanded (8). + /// + DWRITE_FONT_STRETCH_EXTRA_EXPANDED = 8, + + /// + /// Predefined font stretch : Ultra-expanded (9). + /// + DWRITE_FONT_STRETCH_ULTRA_EXPANDED = 9 +}; + +/// +/// The font style enumeration describes the slope style of a font face, such as Normal, Italic or Oblique. +/// Values other than the ones defined in the enumeration are considered to be invalid, and they are rejected by font API functions. +/// +enum DWRITE_FONT_STYLE +{ + /// + /// Font slope style : Normal. + /// + DWRITE_FONT_STYLE_NORMAL, + + /// + /// Font slope style : Oblique. + /// + DWRITE_FONT_STYLE_OBLIQUE, + + /// + /// Font slope style : Italic. + /// + DWRITE_FONT_STYLE_ITALIC + +}; + +/// +/// The informational string enumeration identifies a string in a font. +/// +enum DWRITE_INFORMATIONAL_STRING_ID +{ + /// + /// Unspecified name ID. + /// + DWRITE_INFORMATIONAL_STRING_NONE, + + /// + /// Copyright notice provided by the font. + /// + DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE, + + /// + /// String containing a version number. + /// + DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS, + + /// + /// Trademark information provided by the font. + /// + DWRITE_INFORMATIONAL_STRING_TRADEMARK, + + /// + /// Name of the font manufacturer. + /// + DWRITE_INFORMATIONAL_STRING_MANUFACTURER, + + /// + /// Name of the font designer. + /// + DWRITE_INFORMATIONAL_STRING_DESIGNER, + + /// + /// URL of font designer (with protocol, e.g., http://, ftp://). + /// + DWRITE_INFORMATIONAL_STRING_DESIGNER_URL, + + /// + /// Description of the font. Can contain revision information, usage recommendations, history, features, etc. + /// + DWRITE_INFORMATIONAL_STRING_DESCRIPTION, + + /// + /// URL of font vendor (with protocol, e.g., http://, ftp://). If a unique serial number is embedded in the URL, it can be used to register the font. + /// + DWRITE_INFORMATIONAL_STRING_FONT_VENDOR_URL, + + /// + /// Description of how the font may be legally used, or different example scenarios for licensed use. This field should be written in plain language, not legalese. + /// + DWRITE_INFORMATIONAL_STRING_LICENSE_DESCRIPTION, + + /// + /// URL where additional licensing information can be found. + /// + DWRITE_INFORMATIONAL_STRING_LICENSE_INFO_URL, + + /// + /// GDI-compatible family name. Because GDI allows a maximum of four fonts per family, fonts in the same family may have different GDI-compatible family names + /// (e.g., "Arial", "Arial Narrow", "Arial Black"). + /// + DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, + + /// + /// GDI-compatible subfamily name. + /// + DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES, + + /// + /// Family name preferred by the designer. This enables font designers to group more than four fonts in a single family without losing compatibility with + /// GDI. This name is typically only present if it differs from the GDI-compatible family name. + /// + DWRITE_INFORMATIONAL_STRING_PREFERRED_FAMILY_NAMES, + + /// + /// Subfamily name preferred by the designer. This name is typically only present if it differs from the GDI-compatible subfamily name. + /// + DWRITE_INFORMATIONAL_STRING_PREFERRED_SUBFAMILY_NAMES, + + /// + /// Sample text. This can be the font name or any other text that the designer thinks is the best example to display the font in. + /// + DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT +}; + + +/// +/// The DWRITE_FONT_METRICS structure specifies the metrics of a font face that +/// are applicable to all glyphs within the font face. +/// +struct DWRITE_FONT_METRICS +{ + /// + /// The number of font design units per em unit. + /// Font files use their own coordinate system of font design units. + /// A font design unit is the smallest measurable unit in the em square, + /// an imaginary square that is used to size and align glyphs. + /// The concept of em square is used as a reference scale factor when defining font size and device transformation semantics. + /// The size of one em square is also commonly used to compute the paragraph identation value. + /// + UINT16 designUnitsPerEm; + + /// + /// Ascent value of the font face in font design units. + /// Ascent is the distance from the top of font character alignment box to English baseline. + /// + UINT16 ascent; + + /// + /// Descent value of the font face in font design units. + /// Descent is the distance from the bottom of font character alignment box to English baseline. + /// + UINT16 descent; + + /// + /// Line gap in font design units. + /// Recommended additional white space to add between lines to improve legibility. The recommended line spacing + /// (baseline-to-baseline distance) is thus the sum of ascent, descent, and lineGap. The line gap is usually + /// positive or zero but can be negative, in which case the recommended line spacing is less than the height + /// of the character alignment box. + /// + INT16 lineGap; + + /// + /// Cap height value of the font face in font design units. + /// Cap height is the distance from English baseline to the top of a typical English capital. + /// Capital "H" is often used as a reference character for the purpose of calculating the cap height value. + /// + UINT16 capHeight; + + /// + /// x-height value of the font face in font design units. + /// x-height is the distance from English baseline to the top of lowercase letter "x", or a similar lowercase character. + /// + UINT16 xHeight; + + /// + /// The underline position value of the font face in font design units. + /// Underline position is the position of underline relative to the English baseline. + /// The value is usually made negative in order to place the underline below the baseline. + /// + INT16 underlinePosition; + + /// + /// The suggested underline thickness value of the font face in font design units. + /// + UINT16 underlineThickness; + + /// + /// The strikethrough position value of the font face in font design units. + /// Strikethrough position is the position of strikethrough relative to the English baseline. + /// The value is usually made positive in order to place the strikethrough above the baseline. + /// + INT16 strikethroughPosition; + + /// + /// The suggested strikethrough thickness value of the font face in font design units. + /// + UINT16 strikethroughThickness; +}; + +/// +/// The DWRITE_GLYPH_METRICS structure specifies the metrics of an individual glyph. +/// The units depend on how the metrics are obtained. +/// +struct DWRITE_GLYPH_METRICS +{ + /// + /// Specifies the X offset from the glyph origin to the left edge of the black box. + /// The glyph origin is the current horizontal writing position. + /// A negative value means the black box extends to the left of the origin (often true for lowercase italic 'f'). + /// + INT32 leftSideBearing; + + /// + /// Specifies the X offset from the origin of the current glyph to the origin of the next glyph when writing horizontally. + /// + UINT32 advanceWidth; + + /// + /// Specifies the X offset from the right edge of the black box to the origin of the next glyph when writing horizontally. + /// The value is negative when the right edge of the black box overhangs the layout box. + /// + INT32 rightSideBearing; + + /// + /// Specifies the vertical offset from the vertical origin to the top of the black box. + /// Thus, a positive value adds whitespace whereas a negative value means the glyph overhangs the top of the layout box. + /// + INT32 topSideBearing; + + /// + /// Specifies the Y offset from the vertical origin of the current glyph to the vertical origin of the next glyph when writing vertically. + /// (Note that the term "origin" by itself denotes the horizontal origin. The vertical origin is different. + /// Its Y coordinate is specified by verticalOriginY value, + /// and its X coordinate is half the advanceWidth to the right of the horizontal origin). + /// + UINT32 advanceHeight; + + /// + /// Specifies the vertical distance from the black box's bottom edge to the advance height. + /// Positive when the bottom edge of the black box is within the layout box. + /// Negative when the bottom edge of black box overhangs the layout box. + /// + INT32 bottomSideBearing; + + /// + /// Specifies the Y coordinate of a glyph's vertical origin, in the font's design coordinate system. + /// The y coordinate of a glyph's vertical origin is the sum of the glyph's top side bearing + /// and the top (i.e. yMax) of the glyph's bounding box. + /// + INT32 verticalOriginY; +}; + +/// +/// Optional adjustment to a glyph's position. An glyph offset changes the position of a glyph without affecting +/// the pen position. Offsets are in logical, pre-transform units. +/// +struct DWRITE_GLYPH_OFFSET +{ + /// + /// Offset in the advance direction of the run. A positive advance offset moves the glyph to the right + /// (in pre-transform coordinates) if the run is left-to-right or to the left if the run is right-to-left. + /// + FLOAT advanceOffset; + + /// + /// Offset in the ascent direction, i.e., the direction ascenders point. A positive ascender offset moves + /// the glyph up (in pre-transform coordinates). + /// + FLOAT ascenderOffset; +}; + +/// +/// Specifies the type of DirectWrite factory object. +/// DirectWrite factory contains internal state such as font loader registration and cached font data. +/// In most cases it is recommended to use the shared factory object, because it allows multiple components +/// that use DirectWrite to share internal DirectWrite state and reduce memory usage. +/// However, there are cases when it is desirable to reduce the impact of a component, +/// such as a plug-in from an untrusted source, on the rest of the process by sandboxing and isolating it +/// from the rest of the process components. In such cases, it is recommended to use an isolated factory for the sandboxed +/// component. +/// +enum DWRITE_FACTORY_TYPE +{ + /// + /// Shared factory allow for re-use of cached font data across multiple in process components. + /// Such factories also take advantage of cross process font caching components for better performance. + /// + DWRITE_FACTORY_TYPE_SHARED, + + /// + /// Objects created from the isolated factory do not interact with internal DirectWrite state from other components. + /// + DWRITE_FACTORY_TYPE_ISOLATED +}; + +// Creates an OpenType tag as a 32bit integer such that +// the first character in the tag is the lowest byte, +// (least significant on little endian architectures) +// which can be used to compare with tags in the font file. +// This macro is compatible with DWRITE_FONT_FEATURE_TAG. +// +// Example: DWRITE_MAKE_OPENTYPE_TAG('c','c','m','p') +// Dword: 0x706D6363 +// +#define DWRITE_MAKE_OPENTYPE_TAG(a,b,c,d) ( \ + (static_cast(static_cast(d)) << 24) | \ + (static_cast(static_cast(c)) << 16) | \ + (static_cast(static_cast(b)) << 8) | \ + static_cast(static_cast(a))) + +interface IDWriteFontFileStream; + +/// +/// Font file loader interface handles loading font file resources of a particular type from a key. +/// The font file loader interface is recommended to be implemented by a singleton object. +/// IMPORTANT: font file loader implementations must not register themselves with DirectWrite factory +/// inside their constructors and must not unregister themselves in their destructors, because +/// registration and unregistraton operations increment and decrement the object reference count respectively. +/// Instead, registration and unregistration of font file loaders with DirectWrite factory should be performed +/// outside of the font file loader implementation as a separate step. +/// +interface DWRITE_DECLARE_INTERFACE("727cad4e-d6af-4c9e-8a08-d695b11caa49") IDWriteFontFileLoader : public IUnknown +{ + /// + /// Creates a font file stream object that encapsulates an open file resource. + /// The resource is closed when the last reference to fontFileStream is released. + /// + /// Font file reference key that uniquely identifies the font file resource + /// within the scope of the font loader being used. + /// Size of font file reference key in bytes. + /// Pointer to the newly created font file stream. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateStreamFromKey)( + __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + __out IDWriteFontFileStream** fontFileStream + ) PURE; +}; + +/// +/// A built-in implementation of IDWriteFontFileLoader interface that operates on local font files +/// and exposes local font file information from the font file reference key. +/// Font file references created using CreateFontFileReference use this font file loader. +/// +interface DWRITE_DECLARE_INTERFACE("b2d9f3ec-c9fe-4a11-a2ec-d86208f7c0a2") IDWriteLocalFontFileLoader : public IDWriteFontFileLoader +{ + /// + /// Obtains the length of the absolute file path from the font file reference key. + /// + /// Font file reference key that uniquely identifies the local font file + /// within the scope of the font loader being used. + /// Size of font file reference key in bytes. + /// Length of the file path string not including the terminated NULL character. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFilePathLengthFromKey)( + __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + __out UINT32* filePathLength + ) PURE; + + /// + /// Obtains the absolute font file path from the font file reference key. + /// + /// Font file reference key that uniquely identifies the local font file + /// within the scope of the font loader being used. + /// Size of font file reference key in bytes. + /// Character array that receives the local file path. + /// Size of the filePath array in character count including the terminated NULL character. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFilePathFromKey)( + __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + __out_ecount_z(filePathSize) WCHAR* filePath, + UINT32 filePathSize + ) PURE; + + /// + /// Obtains the last write time of the file from the font file reference key. + /// + /// Font file reference key that uniquely identifies the local font file + /// within the scope of the font loader being used. + /// Size of font file reference key in bytes. + /// Last modified time of the font file. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLastWriteTimeFromKey)( + __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + __out FILETIME* lastWriteTime + ) PURE; +}; + +/// +/// The interface for loading font file data. +/// +interface DWRITE_DECLARE_INTERFACE("6d4865fe-0ab8-4d91-8f62-5dd6be34a3e0") IDWriteFontFileStream : public IUnknown +{ + /// + /// Reads a fragment from a file. + /// + /// Receives the pointer to the start of the font file fragment. + /// Offset of the fragment from the beginning of the font file. + /// Size of the fragment in bytes. + /// The client defined context to be passed to the ReleaseFileFragment. + /// + /// Standard HRESULT error code. + /// + /// + /// IMPORTANT: ReadFileFragment() implementations must check whether the requested file fragment + /// is within the file bounds. Otherwise, an error should be returned from ReadFileFragment. + /// + STDMETHOD(ReadFileFragment)( + __deref_out_bcount(fragmentSize) void const** fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + __out void** fragmentContext + ) PURE; + + /// + /// Releases a fragment from a file. + /// + /// The client defined context of a font fragment returned from ReadFileFragment. + STDMETHOD_(void, ReleaseFileFragment)( + void* fragmentContext + ) PURE; + + /// + /// Obtains the total size of a file. + /// + /// Receives the total size of the file. + /// + /// Standard HRESULT error code. + /// + /// + /// Implementing GetFileSize() for asynchronously loaded font files may require + /// downloading the complete file contents, therefore this method should only be used for operations that + /// either require complete font file to be loaded (e.g., copying a font file) or need to make + /// decisions based on the value of the file size (e.g., validation against a persisted file size). + /// + STDMETHOD(GetFileSize)( + __out UINT64* fileSize + ) PURE; + + /// + /// Obtains the last modified time of the file. The last modified time is used by DirectWrite font selection algorithms + /// to determine whether one font resource is more up to date than another one. + /// + /// Receives the last modifed time of the file in the format that represents + /// the number of 100-nanosecond intervals since January 1, 1601 (UTC). + /// + /// Standard HRESULT error code. For resources that don't have a concept of the last modified time, the implementation of + /// GetLastWriteTime should return E_NOTIMPL. + /// + STDMETHOD(GetLastWriteTime)( + __out UINT64* lastWriteTime + ) PURE; +}; + +/// +/// The interface that represents a reference to a font file. +/// +interface DWRITE_DECLARE_INTERFACE("739d886a-cef5-47dc-8769-1a8b41bebbb0") IDWriteFontFile : public IUnknown +{ + /// + /// This method obtains the pointer to the reference key of a font file. The pointer is only valid until the object that refers to it is released. + /// + /// Pointer to the font file reference key. + /// IMPORTANT: The pointer value is valid until the font file reference object it is obtained from is released. + /// Size of font file reference key in bytes. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetReferenceKey)( + __deref_out_bcount(*fontFileReferenceKeySize) void const** fontFileReferenceKey, + __out UINT32* fontFileReferenceKeySize + ) PURE; + + /// + /// Obtains the file loader associated with a font file object. + /// + /// The font file loader associated with the font file object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLoader)( + __out IDWriteFontFileLoader** fontFileLoader + ) PURE; + + /// + /// Analyzes a file and returns whether it represents a font, and whether the font type is supported by the font system. + /// + /// TRUE if the font type is supported by the font system, FALSE otherwise. + /// The type of the font file. Note that even if isSupportedFontType is FALSE, + /// the fontFileType value may be different from DWRITE_FONT_FILE_TYPE_UNKNOWN. + /// The type of the font face that can be constructed from the font file. + /// Note that even if isSupportedFontType is FALSE, the fontFaceType value may be different from + /// DWRITE_FONT_FACE_TYPE_UNKNOWN. + /// Number of font faces contained in the font file. + /// + /// Standard HRESULT error code if there was a processing error during analysis. + /// + /// + /// IMPORTANT: certain font file types are recognized, but not supported by the font system. + /// For example, the font system will recognize a file as a Type 1 font file, + /// but will not be able to construct a font face object from it. In such situations, Analyze will set + /// isSupportedFontType output parameter to FALSE. + /// + STDMETHOD(Analyze)( + __out BOOL* isSupportedFontType, + __out DWRITE_FONT_FILE_TYPE* fontFileType, + __out_opt DWRITE_FONT_FACE_TYPE* fontFaceType, + __out UINT32* numberOfFaces + ) PURE; +}; + +/// +/// Represents the internal structure of a device pixel (i.e., the physical arrangement of red, +/// green, and blue color components) that is assumed for purposes of rendering text. +/// +#ifndef DWRITE_PIXEL_GEOMETRY_DEFINED +enum DWRITE_PIXEL_GEOMETRY +{ + /// + /// The red, green, and blue color components of each pixel are assumed to occupy the same point. + /// + DWRITE_PIXEL_GEOMETRY_FLAT, + + /// + /// Each pixel comprises three vertical stripes, with red on the left, green in the center, and + /// blue on the right. This is the most common pixel geometry for LCD monitors. + /// + DWRITE_PIXEL_GEOMETRY_RGB, + + /// + /// Each pixel comprises three vertical stripes, with blue on the left, green in the center, and + /// red on the right. + /// + DWRITE_PIXEL_GEOMETRY_BGR +}; +#define DWRITE_PIXEL_GEOMETRY_DEFINED +#endif + +/// +/// Represents a method of rendering glyphs. +/// +enum DWRITE_RENDERING_MODE +{ + /// + /// Specifies that the rendering mode is determined automatically based on the font and size. + /// + DWRITE_RENDERING_MODE_DEFAULT, + + /// + /// Specifies that no anti-aliasing is performed. Each pixel is either set to the foreground + /// color of the text or retains the color of the background. + /// + DWRITE_RENDERING_MODE_ALIASED, + + /// + /// Specifies ClearType rendering with the same metrics as aliased text. Glyphs can only + /// be positioned on whole-pixel boundaries. + /// + DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, + + /// + /// Specifies ClearType rendering with the same metrics as text rendering using GDI using a font + /// created with CLEARTYPE_NATURAL_QUALITY. Glyph metrics are closer to their ideal values than + /// with aliased text, but glyphs are still positioned on whole-pixel boundaries. + /// + DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL, + + /// + /// Specifies ClearType rendering with anti-aliasing in the horizontal dimension only. This is + /// typically used with small to medium font sizes (up to 16 ppem). + /// + DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL, + + /// + /// Specifies ClearType rendering with anti-aliasing in both horizontal and vertical dimensions. + /// This is typically used at larger sizes to makes curves and diagonal lines look smoother, at + /// the expense of some softness. + /// + DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, + + /// + /// Specifies that rendering should bypass the rasterizer and use the outlines directly. This is + /// typically used at very large sizes. + /// + DWRITE_RENDERING_MODE_OUTLINE +}; + +/// +/// The DWRITE_MATRIX structure specifies the graphics transform to be applied +/// to rendered glyphs. +/// +struct DWRITE_MATRIX +{ + /// + /// Horizontal scaling / cosine of rotation + /// + FLOAT m11; + + /// + /// Vertical shear / sine of rotation + /// + FLOAT m12; + + /// + /// Horizontal shear / negative sine of rotation + /// + FLOAT m21; + + /// + /// Vertical scaling / cosine of rotation + /// + FLOAT m22; + + /// + /// Horizontal shift (always orthogonal regardless of rotation) + /// + FLOAT dx; + + /// + /// Vertical shift (always orthogonal regardless of rotation) + /// + FLOAT dy; +}; + +/// +/// The interface that represents text rendering settings for glyph rasterization and filtering. +/// +interface DWRITE_DECLARE_INTERFACE("2f0da53a-2add-47cd-82ee-d9ec34688e75") IDWriteRenderingParams : public IUnknown +{ + /// + /// Gets the gamma value used for gamma correction. Valid values must be + /// greater than zero and cannot exceed 256. + /// + STDMETHOD_(FLOAT, GetGamma)() PURE; + + /// + /// Gets the amount of contrast enhancement. Valid values are greater than + /// or equal to zero. + /// + STDMETHOD_(FLOAT, GetEnhancedContrast)() PURE; + + /// + /// Gets the ClearType level. Valid values range from 0.0f (no ClearType) + /// to 1.0f (full ClearType). + /// + STDMETHOD_(FLOAT, GetClearTypeLevel)() PURE; + + /// + /// Gets the pixel geometry. + /// + STDMETHOD_(DWRITE_PIXEL_GEOMETRY, GetPixelGeometry)() PURE; + + /// + /// Gets the rendering mode. + /// + STDMETHOD_(DWRITE_RENDERING_MODE, GetRenderingMode)() PURE; +}; + +// Forward declarations of D2D types +interface ID2D1SimplifiedGeometrySink; + +typedef ID2D1SimplifiedGeometrySink IDWriteGeometrySink; + +/// +/// The interface that represents an absolute reference to a font face. +/// It contains font face type, appropriate file references and face identification data. +/// Various font data such as metrics, names and glyph outlines is obtained from IDWriteFontFace. +/// +interface DWRITE_DECLARE_INTERFACE("5f49804d-7024-4d43-bfa9-d25984f53849") IDWriteFontFace : public IUnknown +{ + /// + /// Obtains the file format type of a font face. + /// + STDMETHOD_(DWRITE_FONT_FACE_TYPE, GetType)() PURE; + + /// + /// Obtains the font files representing a font face. + /// + /// The number of files representing the font face. + /// User provided array that stores pointers to font files representing the font face. + /// This parameter can be NULL if the user is only interested in the number of files representing the font face. + /// This API increments reference count of the font file pointers returned according to COM conventions, and the client + /// should release them when finished. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFiles)( + __inout UINT32* numberOfFiles, + __out_ecount_opt(*numberOfFiles) IDWriteFontFile** fontFiles + ) PURE; + + /// + /// Obtains the zero-based index of the font face in its font file or files. If the font files contain a single face, + /// the return value is zero. + /// + STDMETHOD_(UINT32, GetIndex)() PURE; + + /// + /// Obtains the algorithmic style simulation flags of a font face. + /// + STDMETHOD_(DWRITE_FONT_SIMULATIONS, GetSimulations)() PURE; + + /// + /// Determines whether the font is a symbol font. + /// + STDMETHOD_(BOOL, IsSymbolFont)() PURE; + + /// + /// Obtains design units and common metrics for the font face. + /// These metrics are applicable to all the glyphs within a fontface and are used by applications for layout calculations. + /// + /// Points to a DWRITE_FONT_METRICS structure to fill in. + /// The metrics returned by this function are in font design units. + STDMETHOD_(void, GetMetrics)( + __out DWRITE_FONT_METRICS* fontFaceMetrics + ) PURE; + + /// + /// Obtains the number of glyphs in the font face. + /// + STDMETHOD_(UINT16, GetGlyphCount)() PURE; + + /// + /// Obtains ideal glyph metrics in font design units. Design glyphs metrics are used for glyph positioning. + /// + /// An array of glyph indices to compute the metrics for. + /// The number of elements in the glyphIndices array. + /// Array of DWRITE_GLYPH_METRICS structures filled by this function. + /// The metrics returned by this function are in font design units. + /// Indicates whether the font is being used in a sideways run. + /// This can affect the glyph metrics if the font has oblique simulation + /// because sideways oblique simulation differs from non-sideways oblique simulation. + /// + /// Standard HRESULT error code. If any of the input glyph indices are outside of the valid glyph index range + /// for the current font face, E_INVALIDARG will be returned. + /// + STDMETHOD(GetDesignGlyphMetrics)( + __in_ecount(glyphCount) UINT16 const* glyphIndices, + UINT32 glyphCount, + __out_ecount(glyphCount) DWRITE_GLYPH_METRICS* glyphMetrics, + BOOL isSideways = FALSE + ) PURE; + + /// + /// Returns the nominal mapping of UCS4 Unicode code points to glyph indices as defined by the font 'CMAP' table. + /// Note that this mapping is primarily provided for line layout engines built on top of the physical font API. + /// Because of OpenType glyph substitution and line layout character substitution, the nominal conversion does not always correspond + /// to how a Unicode string will map to glyph indices when rendering using a particular font face. + /// Also, note that Unicode Variant Selectors provide for alternate mappings for character to glyph. + /// This call will always return the default variant. + /// + /// An array of USC4 code points to obtain nominal glyph indices from. + /// The number of elements in the codePoints array. + /// Array of nominal glyph indices filled by this function. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetGlyphIndices)( + __in_ecount(codePointCount) UINT32 const* codePoints, + UINT32 codePointCount, + __out_ecount(codePointCount) UINT16* glyphIndices + ) PURE; + + /// + /// Finds the specified OpenType font table if it exists and returns a pointer to it. + /// The function accesses the underling font data via the IDWriteFontStream interface + /// implemented by the font file loader. + /// + /// Four character tag of table to find. + /// Use the DWRITE_MAKE_OPENTYPE_TAG() macro to create it. + /// Unlike GDI, it does not support the special TTCF and null tags to access the whole font. + /// + /// Pointer to base of table in memory. + /// The pointer is only valid so long as the FontFace used to get the font table still exists + /// (not any other FontFace, even if it actually refers to the same physical font). + /// + /// Byte size of table. + /// + /// Opaque context which must be freed by calling ReleaseFontTable. + /// The context actually comes from the lower level IDWriteFontFileStream, + /// which may be implemented by the application or DWrite itself. + /// It is possible for a NULL tableContext to be returned, especially if + /// the implementation directly memory maps the whole file. + /// Nevertheless, always release it later, and do not use it as a test for function success. + /// The same table can be queried multiple times, + /// but each returned context can be different, so release each separately. + /// + /// True if table exists. + /// + /// Standard HRESULT error code. + /// If a table can not be found, the function will not return an error, but the size will be 0, table NULL, and exists = FALSE. + /// The context does not need to be freed if the table was not found. + /// + /// + /// The context for the same tag may be different for each call, + /// so each one must be held and released separately. + /// + STDMETHOD(TryGetFontTable)( + __in UINT32 openTypeTableTag, + __deref_out_bcount(*tableSize) const void** tableData, + __out UINT32* tableSize, + __out void** tableContext, + __out BOOL* exists + ) PURE; + + /// + /// Releases the table obtained earlier from TryGetFontTable. + /// + /// Opaque context from TryGetFontTable. + /// + /// Standard HRESULT error code. + /// + STDMETHOD_(void, ReleaseFontTable)( + __in void* tableContext + ) PURE; + + /// + /// Computes the outline of a run of glyphs by calling back to the outline sink interface. + /// + /// Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch. + /// Array of glyph indices. + /// Optional array of glyph advances in DIPs. + /// Optional array of glyph offsets. + /// Number of glyphs. + /// If true, specifies that glyphs are rotated 90 degrees to the left and vertical metrics are used. + /// A client can render a vertical run by specifying isSideways = true and rotating the resulting geometry 90 degrees to the + /// right using a transform. The isSideways and isRightToLeft parameters cannot both be true. + /// If true, specifies that the advance direction is right to left. By default, the advance direction + /// is left to right. + /// Interface the function calls back to draw each element of the geometry. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetGlyphRunOutline)( + FLOAT emSize, + __in_ecount(glyphCount) UINT16 const* glyphIndices, + __in_ecount_opt(glyphCount) FLOAT const* glyphAdvances, + __in_ecount_opt(glyphCount) DWRITE_GLYPH_OFFSET const* glyphOffsets, + UINT32 glyphCount, + BOOL isSideways, + BOOL isRightToLeft, + IDWriteGeometrySink* geometrySink + ) PURE; + + /// + /// Determines the recommended rendering mode for the font given the specified size and rendering parameters. + /// + /// Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch. + /// Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this + /// value is 1.0f. If the DPI is 120, this value is 120.0f/96. + /// Specifies measuring method that will be used for glyphs in the font. + /// Renderer implementations may choose different rendering modes for given measuring methods, but + /// best results are seen when the corresponding modes match: + /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL + /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC + /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL + /// + /// Rendering parameters object. This parameter is necessary in case the rendering parameters + /// object overrides the rendering mode. + /// Receives the recommended rendering mode to use. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetRecommendedRenderingMode)( + FLOAT emSize, + FLOAT pixelsPerDip, + DWRITE_MEASURING_MODE measuringMode, + IDWriteRenderingParams* renderingParams, + __out DWRITE_RENDERING_MODE* renderingMode + ) PURE; + + /// + /// Obtains design units and common metrics for the font face. + /// These metrics are applicable to all the glyphs within a fontface and are used by applications for layout calculations. + /// + /// Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch. + /// Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this + /// value is 1.0f. If the DPI is 120, this value is 120.0f/96. + /// Optional transform applied to the glyphs and their positions. This transform is applied after the + /// scaling specified by the font size and pixelsPerDip. + /// Points to a DWRITE_FONT_METRICS structure to fill in. + /// The metrics returned by this function are in font design units. + STDMETHOD(GetGdiCompatibleMetrics)( + FLOAT emSize, + FLOAT pixelsPerDip, + __in_opt DWRITE_MATRIX const* transform, + __out DWRITE_FONT_METRICS* fontFaceMetrics + ) PURE; + + + /// + /// Obtains glyph metrics in font design units with the return values compatible with what GDI would produce. + /// Glyphs metrics are used for positioning of individual glyphs. + /// + /// Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch. + /// Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this + /// value is 1.0f. If the DPI is 120, this value is 120.0f/96. + /// Optional transform applied to the glyphs and their positions. This transform is applied after the + /// scaling specified by the font size and pixelsPerDip. + /// + /// When set to FALSE, the metrics are the same as the metrics of GDI aliased text. + /// When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font + /// created with CLEARTYPE_NATURAL_QUALITY. + /// + /// An array of glyph indices to compute the metrics for. + /// The number of elements in the glyphIndices array. + /// Array of DWRITE_GLYPH_METRICS structures filled by this function. + /// The metrics returned by this function are in font design units. + /// Indicates whether the font is being used in a sideways run. + /// This can affect the glyph metrics if the font has oblique simulation + /// because sideways oblique simulation differs from non-sideways oblique simulation. + /// + /// Standard HRESULT error code. If any of the input glyph indices are outside of the valid glyph index range + /// for the current font face, E_INVALIDARG will be returned. + /// + STDMETHOD(GetGdiCompatibleGlyphMetrics)( + FLOAT emSize, + FLOAT pixelsPerDip, + __in_opt DWRITE_MATRIX const* transform, + BOOL useGdiNatural, + __in_ecount(glyphCount) UINT16 const* glyphIndices, + UINT32 glyphCount, + __out_ecount(glyphCount) DWRITE_GLYPH_METRICS* glyphMetrics, + BOOL isSideways = FALSE + ) PURE; +}; + +interface IDWriteFactory; +interface IDWriteFontFileEnumerator; + +/// +/// The font collection loader interface is used to construct a collection of fonts given a particular type of key. +/// The font collection loader interface is recommended to be implemented by a singleton object. +/// IMPORTANT: font collection loader implementations must not register themselves with a DirectWrite factory +/// inside their constructors and must not unregister themselves in their destructors, because +/// registration and unregistraton operations increment and decrement the object reference count respectively. +/// Instead, registration and unregistration of font file loaders with DirectWrite factory should be performed +/// outside of the font file loader implementation as a separate step. +/// +interface DWRITE_DECLARE_INTERFACE("cca920e4-52f0-492b-bfa8-29c72ee0a468") IDWriteFontCollectionLoader : public IUnknown +{ + /// + /// Creates a font file enumerator object that encapsulates a collection of font files. + /// The font system calls back to this interface to create a font collection. + /// + /// Factory associated with the loader. + /// Font collection key that uniquely identifies the collection of font files within + /// the scope of the font collection loader being used. + /// Size of the font collection key in bytes. + /// Pointer to the newly created font file enumerator. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateEnumeratorFromKey)( + IDWriteFactory* factory, + __in_bcount(collectionKeySize) void const* collectionKey, + UINT32 collectionKeySize, + __out IDWriteFontFileEnumerator** fontFileEnumerator + ) PURE; +}; + +/// +/// The font file enumerator interface encapsulates a collection of font files. The font system uses this interface +/// to enumerate font files when building a font collection. +/// +interface DWRITE_DECLARE_INTERFACE("72755049-5ff7-435d-8348-4be97cfa6c7c") IDWriteFontFileEnumerator : public IUnknown +{ + /// + /// Advances to the next font file in the collection. When it is first created, the enumerator is positioned + /// before the first element of the collection and the first call to MoveNext advances to the first file. + /// + /// Receives the value TRUE if the enumerator advances to a file, or FALSE if + /// the enumerator advanced past the last file in the collection. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(MoveNext)( + __out BOOL* hasCurrentFile + ) PURE; + + /// + /// Gets a reference to the current font file. + /// + /// Pointer to the newly created font file object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetCurrentFontFile)( + __out IDWriteFontFile** fontFile + ) PURE; +}; + +/// +/// Represents a collection of strings indexed by locale name. +/// +interface DWRITE_DECLARE_INTERFACE("08256209-099a-4b34-b86d-c22b110e7771") IDWriteLocalizedStrings : public IUnknown +{ + /// + /// Gets the number of language/string pairs. + /// + STDMETHOD_(UINT32, GetCount)() PURE; + + /// + /// Gets the index of the item with the specified locale name. + /// + /// Locale name to look for. + /// Receives the zero-based index of the locale name/string pair. + /// Receives TRUE if the locale name exists or FALSE if not. + /// + /// Standard HRESULT error code. If the specified locale name does not exist, the return value is S_OK, + /// but *index is UINT_MAX and *exists is FALSE. + /// + STDMETHOD(FindLocaleName)( + __in_z WCHAR const* localeName, + __out UINT32* index, + __out BOOL* exists + ) PURE; + + /// + /// Gets the length in characters (not including the null terminator) of the locale name with the specified index. + /// + /// Zero-based index of the locale name. + /// Receives the length in characters, not including the null terminator. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLocaleNameLength)( + UINT32 index, + __out UINT32* length + ) PURE; + + /// + /// Copies the locale name with the specified index to the specified array. + /// + /// Zero-based index of the locale name. + /// Character array that receives the locale name. + /// Size of the array in characters. The size must include space for the terminating + /// null character. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLocaleName)( + UINT32 index, + __out_ecount_z(size) WCHAR* localeName, + UINT32 size + ) PURE; + + /// + /// Gets the length in characters (not including the null terminator) of the string with the specified index. + /// + /// Zero-based index of the string. + /// Receives the length in characters, not including the null terminator. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetStringLength)( + UINT32 index, + __out UINT32* length + ) PURE; + + /// + /// Copies the string with the specified index to the specified array. + /// + /// Zero-based index of the string. + /// Character array that receives the string. + /// Size of the array in characters. The size must include space for the terminating + /// null character. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetString)( + UINT32 index, + __out_ecount_z(size) WCHAR* stringBuffer, + UINT32 size + ) PURE; +}; + +interface IDWriteFontFamily; +interface IDWriteFont; + +/// +/// The IDWriteFontCollection encapsulates a collection of fonts. +/// +interface DWRITE_DECLARE_INTERFACE("a84cee02-3eea-4eee-a827-87c1a02a0fcc") IDWriteFontCollection : public IUnknown +{ + /// + /// Gets the number of font families in the collection. + /// + STDMETHOD_(UINT32, GetFontFamilyCount)() PURE; + + /// + /// Creates a font family object given a zero-based font family index. + /// + /// Zero-based index of the font family. + /// Receives a pointer the newly created font family object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontFamily)( + UINT32 index, + __out IDWriteFontFamily** fontFamily + ) PURE; + + /// + /// Finds the font family with the specified family name. + /// + /// Name of the font family. The name is not case-sensitive but must otherwise exactly match a family name in the collection. + /// Receives the zero-based index of the matching font family if the family name was found or UINT_MAX otherwise. + /// Receives TRUE if the family name exists or FALSE otherwise. + /// + /// Standard HRESULT error code. If the specified family name does not exist, the return value is S_OK, but *index is UINT_MAX and *exists is FALSE. + /// + STDMETHOD(FindFamilyName)( + __in_z WCHAR const* familyName, + __out UINT32* index, + __out BOOL* exists + ) PURE; + + /// + /// Gets the font object that corresponds to the same physical font as the specified font face object. The specified physical font must belong + /// to the font collection. + /// + /// Font face object that specifies the physical font. + /// Receives a pointer to the newly created font object if successful or NULL otherwise. + /// + /// Standard HRESULT error code. If the specified physical font is not part of the font collection the return value is DWRITE_E_NOFONT. + /// + STDMETHOD(GetFontFromFontFace)( + IDWriteFontFace* fontFace, + __out IDWriteFont** font + ) PURE; +}; + +/// +/// The IDWriteFontList interface represents a list of fonts. +/// +interface DWRITE_DECLARE_INTERFACE("1a0d8438-1d97-4ec1-aef9-a2fb86ed6acb") IDWriteFontList : public IUnknown +{ + /// + /// Gets the font collection that contains the fonts. + /// + /// Receives a pointer to the font collection object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontCollection)( + __out IDWriteFontCollection** fontCollection + ) PURE; + + /// + /// Gets the number of fonts in the font list. + /// + STDMETHOD_(UINT32, GetFontCount)() PURE; + + /// + /// Gets a font given its zero-based index. + /// + /// Zero-based index of the font in the font list. + /// Receives a pointer to the newly created font object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFont)( + UINT32 index, + __out IDWriteFont** font + ) PURE; +}; + +/// +/// The IDWriteFontFamily interface represents a set of fonts that share the same design but are differentiated +/// by weight, stretch, and style. +/// +interface DWRITE_DECLARE_INTERFACE("da20d8ef-812a-4c43-9802-62ec4abd7add") IDWriteFontFamily : public IDWriteFontList +{ + /// + /// Creates an localized strings object that contains the family names for the font family, indexed by locale name. + /// + /// Receives a pointer to the newly created localized strings object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFamilyNames)( + __out IDWriteLocalizedStrings** names + ) PURE; + + /// + /// Gets the font that best matches the specified properties. + /// + /// Requested font weight. + /// Requested font stretch. + /// Requested font style. + /// Receives a pointer to the newly created font object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFirstMatchingFont)( + DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STRETCH stretch, + DWRITE_FONT_STYLE style, + __out IDWriteFont** matchingFont + ) PURE; + + /// + /// Gets a list of fonts in the font family ranked in order of how well they match the specified properties. + /// + /// Requested font weight. + /// Requested font stretch. + /// Requested font style. + /// Receives a pointer to the newly created font list object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetMatchingFonts)( + DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STRETCH stretch, + DWRITE_FONT_STYLE style, + __out IDWriteFontList** matchingFonts + ) PURE; +}; + +/// +/// The IDWriteFont interface represents a physical font in a font collection. +/// +interface DWRITE_DECLARE_INTERFACE("acd16696-8c14-4f5d-877e-fe3fc1d32737") IDWriteFont : public IUnknown +{ + /// + /// Gets the font family to which the specified font belongs. + /// + /// Receives a pointer to the font family object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontFamily)( + __out IDWriteFontFamily** fontFamily + ) PURE; + + /// + /// Gets the weight of the specified font. + /// + STDMETHOD_(DWRITE_FONT_WEIGHT, GetWeight)() PURE; + + /// + /// Gets the stretch (aka. width) of the specified font. + /// + STDMETHOD_(DWRITE_FONT_STRETCH, GetStretch)() PURE; + + /// + /// Gets the style (aka. slope) of the specified font. + /// + STDMETHOD_(DWRITE_FONT_STYLE, GetStyle)() PURE; + + /// + /// Returns TRUE if the font is a symbol font or FALSE if not. + /// + STDMETHOD_(BOOL, IsSymbolFont)() PURE; + + /// + /// Gets a localized strings collection containing the face names for the font (e.g., Regular or Bold), indexed by locale name. + /// + /// Receives a pointer to the newly created localized strings object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFaceNames)( + __out IDWriteLocalizedStrings** names + ) PURE; + + /// + /// Gets a localized strings collection containing the specified informational strings, indexed by locale name. + /// + /// Identifies the string to get. + /// Receives a pointer to the newly created localized strings object. + /// Receives the value TRUE if the font contains the specified string ID or FALSE if not. + /// + /// Standard HRESULT error code. If the font does not contain the specified string, the return value is S_OK but + /// informationalStrings receives a NULL pointer and exists receives the value FALSE. + /// + STDMETHOD(GetInformationalStrings)( + DWRITE_INFORMATIONAL_STRING_ID informationalStringID, + __out IDWriteLocalizedStrings** informationalStrings, + __out BOOL* exists + ) PURE; + + /// + /// Gets a value that indicates what simulation are applied to the specified font. + /// + STDMETHOD_(DWRITE_FONT_SIMULATIONS, GetSimulations)() PURE; + + /// + /// Gets the metrics for the font. + /// + /// Receives the font metrics. + STDMETHOD_(void, GetMetrics)( + __out DWRITE_FONT_METRICS* fontMetrics + ) PURE; + + /// + /// Determines whether the font supports the specified character. + /// + /// Unicode (UCS-4) character value. + /// Receives the value TRUE if the font supports the specified character or FALSE if not. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(HasCharacter)( + UINT32 unicodeValue, + __out BOOL* exists + ) PURE; + + /// + /// Creates a font face object for the font. + /// + /// Receives a pointer to the newly created font face object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateFontFace)( + __out IDWriteFontFace** fontFace + ) PURE; +}; + +/// +/// Direction for how reading progresses. +/// +enum DWRITE_READING_DIRECTION +{ + /// + /// Reading progresses from left to right. + /// + DWRITE_READING_DIRECTION_LEFT_TO_RIGHT, + + /// + /// Reading progresses from right to left. + /// + DWRITE_READING_DIRECTION_RIGHT_TO_LEFT +}; + +/// +/// Direction for how lines of text are placed relative to one another. +/// +enum DWRITE_FLOW_DIRECTION +{ + /// + /// Text lines are placed from top to bottom. + /// + DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM +}; + +/// +/// Alignment of paragraph text along the reading direction axis relative to +/// the leading and trailing edge of the layout box. +/// +enum DWRITE_TEXT_ALIGNMENT +{ + /// + /// The leading edge of the paragraph text is aligned to the layout box's leading edge. + /// + DWRITE_TEXT_ALIGNMENT_LEADING, + + /// + /// The trailing edge of the paragraph text is aligned to the layout box's trailing edge. + /// + DWRITE_TEXT_ALIGNMENT_TRAILING, + + /// + /// The center of the paragraph text is aligned to the center of the layout box. + /// + DWRITE_TEXT_ALIGNMENT_CENTER +}; + +/// +/// Alignment of paragraph text along the flow direction axis relative to the +/// flow's beginning and ending edge of the layout box. +/// +enum DWRITE_PARAGRAPH_ALIGNMENT +{ + /// + /// The first line of paragraph is aligned to the flow's beginning edge of the layout box. + /// + DWRITE_PARAGRAPH_ALIGNMENT_NEAR, + + /// + /// The last line of paragraph is aligned to the flow's ending edge of the layout box. + /// + DWRITE_PARAGRAPH_ALIGNMENT_FAR, + + /// + /// The center of the paragraph is aligned to the center of the flow of the layout box. + /// + DWRITE_PARAGRAPH_ALIGNMENT_CENTER +}; + +/// +/// Word wrapping in multiline paragraph. +/// +enum DWRITE_WORD_WRAPPING +{ + /// + /// Words are broken across lines to avoid text overflowing the layout box. + /// + DWRITE_WORD_WRAPPING_WRAP, + + /// + /// Words are kept within the same line even when it overflows the layout box. + /// This option is often used with scrolling to reveal overflow text. + /// + DWRITE_WORD_WRAPPING_NO_WRAP +}; + +/// +/// The method used for line spacing in layout. +/// +enum DWRITE_LINE_SPACING_METHOD +{ + /// + /// Line spacing depends solely on the content, growing to accomodate the size of fonts and inline objects. + /// + DWRITE_LINE_SPACING_METHOD_DEFAULT, + + /// + /// Lines are explicitly set to uniform spacing, regardless of contained font sizes. + /// This can be useful to avoid the uneven appearance that can occur from font fallback. + /// + DWRITE_LINE_SPACING_METHOD_UNIFORM +}; + +/// +/// Text granularity used to trim text overflowing the layout box. +/// +enum DWRITE_TRIMMING_GRANULARITY +{ + /// + /// No trimming occurs. Text flows beyond the layout width. + /// + DWRITE_TRIMMING_GRANULARITY_NONE, + + /// + /// Trimming occurs at character cluster boundary. + /// + DWRITE_TRIMMING_GRANULARITY_CHARACTER, + + /// + /// Trimming occurs at word boundary. + /// + DWRITE_TRIMMING_GRANULARITY_WORD +}; + +/// +/// Typographic feature of text supplied by the font. +/// +enum DWRITE_FONT_FEATURE_TAG +{ + DWRITE_FONT_FEATURE_TAG_ALTERNATIVE_FRACTIONS = 0x63726661, // 'afrc' + DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS_FROM_CAPITALS = 0x63703263, // 'c2pc' + DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS_FROM_CAPITALS = 0x63733263, // 'c2sc' + DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_ALTERNATES = 0x746c6163, // 'calt' + DWRITE_FONT_FEATURE_TAG_CASE_SENSITIVE_FORMS = 0x65736163, // 'case' + DWRITE_FONT_FEATURE_TAG_GLYPH_COMPOSITION_DECOMPOSITION = 0x706d6363, // 'ccmp' + DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_LIGATURES = 0x67696c63, // 'clig' + DWRITE_FONT_FEATURE_TAG_CAPITAL_SPACING = 0x70737063, // 'cpsp' + DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_SWASH = 0x68777363, // 'cswh' + DWRITE_FONT_FEATURE_TAG_CURSIVE_POSITIONING = 0x73727563, // 'curs' + DWRITE_FONT_FEATURE_TAG_DEFAULT = 0x746c6664, // 'dflt' + DWRITE_FONT_FEATURE_TAG_DISCRETIONARY_LIGATURES = 0x67696c64, // 'dlig' + DWRITE_FONT_FEATURE_TAG_EXPERT_FORMS = 0x74707865, // 'expt' + DWRITE_FONT_FEATURE_TAG_FRACTIONS = 0x63617266, // 'frac' + DWRITE_FONT_FEATURE_TAG_FULL_WIDTH = 0x64697766, // 'fwid' + DWRITE_FONT_FEATURE_TAG_HALF_FORMS = 0x666c6168, // 'half' + DWRITE_FONT_FEATURE_TAG_HALANT_FORMS = 0x6e6c6168, // 'haln' + DWRITE_FONT_FEATURE_TAG_ALTERNATE_HALF_WIDTH = 0x746c6168, // 'halt' + DWRITE_FONT_FEATURE_TAG_HISTORICAL_FORMS = 0x74736968, // 'hist' + DWRITE_FONT_FEATURE_TAG_HORIZONTAL_KANA_ALTERNATES = 0x616e6b68, // 'hkna' + DWRITE_FONT_FEATURE_TAG_HISTORICAL_LIGATURES = 0x67696c68, // 'hlig' + DWRITE_FONT_FEATURE_TAG_HALF_WIDTH = 0x64697768, // 'hwid' + DWRITE_FONT_FEATURE_TAG_HOJO_KANJI_FORMS = 0x6f6a6f68, // 'hojo' + DWRITE_FONT_FEATURE_TAG_JIS04_FORMS = 0x3430706a, // 'jp04' + DWRITE_FONT_FEATURE_TAG_JIS78_FORMS = 0x3837706a, // 'jp78' + DWRITE_FONT_FEATURE_TAG_JIS83_FORMS = 0x3338706a, // 'jp83' + DWRITE_FONT_FEATURE_TAG_JIS90_FORMS = 0x3039706a, // 'jp90' + DWRITE_FONT_FEATURE_TAG_KERNING = 0x6e72656b, // 'kern' + DWRITE_FONT_FEATURE_TAG_STANDARD_LIGATURES = 0x6167696c, // 'liga' + DWRITE_FONT_FEATURE_TAG_LINING_FIGURES = 0x6d756e6c, // 'lnum' + DWRITE_FONT_FEATURE_TAG_LOCALIZED_FORMS = 0x6c636f6c, // 'locl' + DWRITE_FONT_FEATURE_TAG_MARK_POSITIONING = 0x6b72616d, // 'mark' + DWRITE_FONT_FEATURE_TAG_MATHEMATICAL_GREEK = 0x6b72676d, // 'mgrk' + DWRITE_FONT_FEATURE_TAG_MARK_TO_MARK_POSITIONING = 0x6b6d6b6d, // 'mkmk' + DWRITE_FONT_FEATURE_TAG_ALTERNATE_ANNOTATION_FORMS = 0x746c616e, // 'nalt' + DWRITE_FONT_FEATURE_TAG_NLC_KANJI_FORMS = 0x6b636c6e, // 'nlck' + DWRITE_FONT_FEATURE_TAG_OLD_STYLE_FIGURES = 0x6d756e6f, // 'onum' + DWRITE_FONT_FEATURE_TAG_ORDINALS = 0x6e64726f, // 'ordn' + DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_ALTERNATE_WIDTH = 0x746c6170, // 'palt' + DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS = 0x70616370, // 'pcap' + DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_FIGURES = 0x6d756e70, // 'pnum' + DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_WIDTHS = 0x64697770, // 'pwid' + DWRITE_FONT_FEATURE_TAG_QUARTER_WIDTHS = 0x64697771, // 'qwid' + DWRITE_FONT_FEATURE_TAG_REQUIRED_LIGATURES = 0x67696c72, // 'rlig' + DWRITE_FONT_FEATURE_TAG_RUBY_NOTATION_FORMS = 0x79627572, // 'ruby' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_ALTERNATES = 0x746c6173, // 'salt' + DWRITE_FONT_FEATURE_TAG_SCIENTIFIC_INFERIORS = 0x666e6973, // 'sinf' + DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS = 0x70636d73, // 'smcp' + DWRITE_FONT_FEATURE_TAG_SIMPLIFIED_FORMS = 0x6c706d73, // 'smpl' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_1 = 0x31307373, // 'ss01' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_2 = 0x32307373, // 'ss02' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_3 = 0x33307373, // 'ss03' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_4 = 0x34307373, // 'ss04' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_5 = 0x35307373, // 'ss05' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_6 = 0x36307373, // 'ss06' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7 = 0x37307373, // 'ss07' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_8 = 0x38307373, // 'ss08' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_9 = 0x39307373, // 'ss09' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_10 = 0x30317373, // 'ss10' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_11 = 0x31317373, // 'ss11' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_12 = 0x32317373, // 'ss12' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_13 = 0x33317373, // 'ss13' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_14 = 0x34317373, // 'ss14' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_15 = 0x35317373, // 'ss15' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_16 = 0x36317373, // 'ss16' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_17 = 0x37317373, // 'ss17' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_18 = 0x38317373, // 'ss18' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_19 = 0x39317373, // 'ss19' + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_20 = 0x30327373, // 'ss20' + DWRITE_FONT_FEATURE_TAG_SUBSCRIPT = 0x73627573, // 'subs' + DWRITE_FONT_FEATURE_TAG_SUPERSCRIPT = 0x73707573, // 'sups' + DWRITE_FONT_FEATURE_TAG_SWASH = 0x68737773, // 'swsh' + DWRITE_FONT_FEATURE_TAG_TITLING = 0x6c746974, // 'titl' + DWRITE_FONT_FEATURE_TAG_TRADITIONAL_NAME_FORMS = 0x6d616e74, // 'tnam' + DWRITE_FONT_FEATURE_TAG_TABULAR_FIGURES = 0x6d756e74, // 'tnum' + DWRITE_FONT_FEATURE_TAG_TRADITIONAL_FORMS = 0x64617274, // 'trad' + DWRITE_FONT_FEATURE_TAG_THIRD_WIDTHS = 0x64697774, // 'twid' + DWRITE_FONT_FEATURE_TAG_UNICASE = 0x63696e75, // 'unic' + DWRITE_FONT_FEATURE_TAG_SLASHED_ZERO = 0x6f72657a, // 'zero' +}; + +/// +/// The DWRITE_TEXT_RANGE structure specifies a range of text positions where format is applied. +/// +struct DWRITE_TEXT_RANGE +{ + /// + /// The start text position of the range. + /// + UINT32 startPosition; + + /// + /// The number of text positions in the range. + /// + UINT32 length; +}; + +/// +/// The DWRITE_FONT_FEATURE structure specifies properties used to identify and execute typographic feature in the font. +/// +struct DWRITE_FONT_FEATURE +{ + /// + /// The feature OpenType name identifier. + /// + DWRITE_FONT_FEATURE_TAG nameTag; + + /// + /// Execution parameter of the feature. + /// + /// + /// The parameter should be non-zero to enable the feature. Once enabled, a feature can't be disabled again within + /// the same range. Features requiring a selector use this value to indicate the selector index. + /// + UINT32 parameter; +}; + +/// +/// Defines a set of typographic features to be applied during shaping. +/// Notice the character range which this feature list spans is specified +/// as a separate parameter to GetGlyphs. +/// +struct DWRITE_TYPOGRAPHIC_FEATURES +{ + /// + /// Array of font features. + /// + __field_ecount(featureCount) DWRITE_FONT_FEATURE* features; + + /// + /// The number of features. + /// + UINT32 featureCount; +}; + +/// +/// The DWRITE_TRIMMING structure specifies the trimming option for text overflowing the layout box. +/// +struct DWRITE_TRIMMING +{ + /// + /// Text granularity of which trimming applies. + /// + DWRITE_TRIMMING_GRANULARITY granularity; + + /// + /// Character code used as the delimiter signaling the beginning of the portion of text to be preserved, + /// most useful for path ellipsis, where the delimeter would be a slash. + /// + UINT32 delimiter; + + /// + /// How many occurences of the delimiter to step back. + /// + UINT32 delimiterCount; +}; + + +interface IDWriteTypography; +interface IDWriteInlineObject; + +/// +/// The format of text used for text layout purpose. +/// +/// +/// This object may not be thread-safe and it may carry the state of text format change. +/// +interface DWRITE_DECLARE_INTERFACE("9c906818-31d7-4fd3-a151-7c5e225db55a") IDWriteTextFormat : public IUnknown +{ + /// + /// Set alignment option of text relative to layout box's leading and trailing edge. + /// + /// Text alignment option + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetTextAlignment)( + DWRITE_TEXT_ALIGNMENT textAlignment + ) PURE; + + /// + /// Set alignment option of paragraph relative to layout box's top and bottom edge. + /// + /// Paragraph alignment option + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetParagraphAlignment)( + DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment + ) PURE; + + /// + /// Set word wrapping option. + /// + /// Word wrapping option + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetWordWrapping)( + DWRITE_WORD_WRAPPING wordWrapping + ) PURE; + + /// + /// Set paragraph reading direction. + /// + /// Text reading direction + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetReadingDirection)( + DWRITE_READING_DIRECTION readingDirection + ) PURE; + + /// + /// Set paragraph flow direction. + /// + /// Paragraph flow direction + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetFlowDirection)( + DWRITE_FLOW_DIRECTION flowDirection + ) PURE; + + /// + /// Set incremental tab stop position. + /// + /// The incremental tab stop value + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetIncrementalTabStop)( + FLOAT incrementalTabStop + ) PURE; + + /// + /// Set trimming options for any trailing text exceeding the layout width + /// or for any far text exceeding the layout height. + /// + /// Text trimming options. + /// Application-defined omission sign. This parameter may be NULL if no trimming sign is desired. + /// + /// Any inline object can be used for the trimming sign, but CreateEllipsisTrimmingSign + /// provides a typical ellipsis symbol. Trimming is also useful vertically for hiding + /// partial lines. + /// + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetTrimming)( + __in DWRITE_TRIMMING const* trimmingOptions, + IDWriteInlineObject* trimmingSign + ) PURE; + + /// + /// Set line spacing. + /// + /// How to determine line height. + /// The line height, or rather distance between one baseline to another. + /// Distance from top of line to baseline. A reasonable ratio to lineSpacing is 80%. + /// + /// For the default method, spacing depends solely on the content. + /// For uniform spacing, the given line height will override the content. + /// + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetLineSpacing)( + DWRITE_LINE_SPACING_METHOD lineSpacingMethod, + FLOAT lineSpacing, + FLOAT baseline + ) PURE; + + /// + /// Get alignment option of text relative to layout box's leading and trailing edge. + /// + STDMETHOD_(DWRITE_TEXT_ALIGNMENT, GetTextAlignment)() PURE; + + /// + /// Get alignment option of paragraph relative to layout box's top and bottom edge. + /// + STDMETHOD_(DWRITE_PARAGRAPH_ALIGNMENT, GetParagraphAlignment)() PURE; + + /// + /// Get word wrapping option. + /// + STDMETHOD_(DWRITE_WORD_WRAPPING, GetWordWrapping)() PURE; + + /// + /// Get paragraph reading direction. + /// + STDMETHOD_(DWRITE_READING_DIRECTION, GetReadingDirection)() PURE; + + /// + /// Get paragraph flow direction. + /// + STDMETHOD_(DWRITE_FLOW_DIRECTION, GetFlowDirection)() PURE; + + /// + /// Get incremental tab stop position. + /// + STDMETHOD_(FLOAT, GetIncrementalTabStop)() PURE; + + /// + /// Get trimming options for text overflowing the layout width. + /// + /// Text trimming options. + /// Trimming omission sign. This parameter may be NULL. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetTrimming)( + __out DWRITE_TRIMMING* trimmingOptions, + __out IDWriteInlineObject** trimmingSign + ) PURE; + + /// + /// Get line spacing. + /// + /// How line height is determined. + /// The line height, or rather distance between one baseline to another. + /// Distance from top of line to baseline. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLineSpacing)( + __out DWRITE_LINE_SPACING_METHOD* lineSpacingMethod, + __out FLOAT* lineSpacing, + __out FLOAT* baseline + ) PURE; + + /// + /// Get the font collection. + /// + /// The current font collection. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontCollection)( + __out IDWriteFontCollection** fontCollection + ) PURE; + + /// + /// Get the length of the font family name, in characters, not including the terminating NULL character. + /// + STDMETHOD_(UINT32, GetFontFamilyNameLength)() PURE; + + /// + /// Get a copy of the font family name. + /// + /// Character array that receives the current font family name + /// Size of the character array in character count including the terminated NULL character. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontFamilyName)( + __out_ecount_z(nameSize) WCHAR* fontFamilyName, + UINT32 nameSize + ) PURE; + + /// + /// Get the font weight. + /// + STDMETHOD_(DWRITE_FONT_WEIGHT, GetFontWeight)() PURE; + + /// + /// Get the font style. + /// + STDMETHOD_(DWRITE_FONT_STYLE, GetFontStyle)() PURE; + + /// + /// Get the font stretch. + /// + STDMETHOD_(DWRITE_FONT_STRETCH, GetFontStretch)() PURE; + + /// + /// Get the font em height. + /// + STDMETHOD_(FLOAT, GetFontSize)() PURE; + + /// + /// Get the length of the locale name, in characters, not including the terminating NULL character. + /// + STDMETHOD_(UINT32, GetLocaleNameLength)() PURE; + + /// + /// Get a copy of the locale name. + /// + /// Character array that receives the current locale name + /// Size of the character array in character count including the terminated NULL character. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLocaleName)( + __out_ecount_z(nameSize) WCHAR* localeName, + UINT32 nameSize + ) PURE; +}; + + +/// +/// Font typography setting. +/// +interface DWRITE_DECLARE_INTERFACE("55f1112b-1dc2-4b3c-9541-f46894ed85b6") IDWriteTypography : public IUnknown +{ + /// + /// Add font feature. + /// + /// The font feature to add. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(AddFontFeature)( + DWRITE_FONT_FEATURE fontFeature + ) PURE; + + /// + /// Get the number of font features. + /// + STDMETHOD_(UINT32, GetFontFeatureCount)() PURE; + + /// + /// Get the font feature at the specified index. + /// + /// The zero-based index of the font feature to get. + /// The font feature. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontFeature)( + UINT32 fontFeatureIndex, + __out DWRITE_FONT_FEATURE* fontFeature + ) PURE; +}; + +enum DWRITE_SCRIPT_SHAPES +{ + /// + /// No additional shaping requirement. Text is shaped with the writing system default behavior. + /// + DWRITE_SCRIPT_SHAPES_DEFAULT = 0, + + /// + /// Text should leave no visual on display i.e. control or format control characters. + /// + DWRITE_SCRIPT_SHAPES_NO_VISUAL = 1 +}; + +#ifdef DEFINE_ENUM_FLAG_OPERATORS +DEFINE_ENUM_FLAG_OPERATORS(DWRITE_SCRIPT_SHAPES); +#endif + +/// +/// Association of text and its writing system script as well as some display attributes. +/// +struct DWRITE_SCRIPT_ANALYSIS +{ + /// + /// Zero-based index representation of writing system script. + /// + UINT16 script; + + /// + /// Additional shaping requirement of text. + /// + DWRITE_SCRIPT_SHAPES shapes; +}; + +/// +/// Condition at the edges of inline object or text used to determine +/// line-breaking behavior. +/// +enum DWRITE_BREAK_CONDITION +{ + /// + /// Whether a break is allowed is determined by the condition of the + /// neighboring text span or inline object. + /// + DWRITE_BREAK_CONDITION_NEUTRAL, + + /// + /// A break is allowed, unless overruled by the condition of the + /// neighboring text span or inline object, either prohibited by a + /// May Not or forced by a Must. + /// + DWRITE_BREAK_CONDITION_CAN_BREAK, + + /// + /// There should be no break, unless overruled by a Must condition from + /// the neighboring text span or inline object. + /// + DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, + + /// + /// The break must happen, regardless of the condition of the adjacent + /// text span or inline object. + /// + DWRITE_BREAK_CONDITION_MUST_BREAK +}; + +/// +/// Line breakpoint characteristics of a character. +/// +struct DWRITE_LINE_BREAKPOINT +{ + /// + /// Breaking condition before the character. + /// + UINT8 breakConditionBefore : 2; + + /// + /// Breaking condition after the character. + /// + UINT8 breakConditionAfter : 2; + + /// + /// The character is some form of whitespace, which may be meaningful + /// for justification. + /// + UINT8 isWhitespace : 1; + + /// + /// The character is a soft hyphen, often used to indicate hyphenation + /// points inside words. + /// + UINT8 isSoftHyphen : 1; + + UINT8 padding : 2; +}; + +/// +/// How to apply number substitution on digits and related punctuation. +/// +enum DWRITE_NUMBER_SUBSTITUTION_METHOD +{ + /// + /// Specifies that the substitution method should be determined based + /// on LOCALE_IDIGITSUBSTITUTION value of the specified text culture. + /// + DWRITE_NUMBER_SUBSTITUTION_METHOD_FROM_CULTURE, + + /// + /// If the culture is Arabic or Farsi, specifies that the number shape + /// depend on the context. Either traditional or nominal number shape + /// are used depending on the nearest preceding strong character or (if + /// there is none) the reading direction of the paragraph. + /// + DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL, + + /// + /// Specifies that code points 0x30-0x39 are always rendered as nominal numeral + /// shapes (ones of the European number), i.e., no substitution is performed. + /// + DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, + + /// + /// Specifies that number are rendered using the national number shape + /// as specified by the LOCALE_SNATIVEDIGITS value of the specified text culture. + /// + DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL, + + /// + /// Specifies that number are rendered using the traditional shape + /// for the specified culture. For most cultures, this is the same as + /// NativeNational. However, NativeNational results in Latin number + /// for some Arabic cultures, whereas this value results in Arabic + /// number for all Arabic cultures. + /// + DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL +}; + +/// +/// Holds the appropriate digits and numeric punctuation for a given locale. +/// +interface DECLSPEC_UUID("14885CC9-BAB0-4f90-B6ED-5C366A2CD03D") DECLSPEC_NOVTABLE IDWriteNumberSubstitution : public IUnknown +{ +}; + +/// +/// Shaping output properties per input character. +/// +struct DWRITE_SHAPING_TEXT_PROPERTIES +{ + /// + /// This character can be shaped independently from the others + /// (usually set for the space character). + /// + UINT16 isShapedAlone : 1; + + /// + /// Reserved for use by shaping engine. + /// + UINT16 reserved : 15; +}; + +/// +/// Shaping output properties per output glyph. +/// +struct DWRITE_SHAPING_GLYPH_PROPERTIES +{ + /// + /// Justification class, whether to use spacing, kashidas, or + /// another method. This exists for backwards compatibility + /// with Uniscribe's SCRIPT_JUSTIFY enum. + /// + UINT16 justification : 4; + + /// + /// Indicates glyph is the first of a cluster. + /// + UINT16 isClusterStart : 1; + + /// + /// Glyph is a diacritic. + /// + UINT16 isDiacritic : 1; + + /// + /// Glyph has no width, blank, ZWJ, ZWNJ etc. + /// + UINT16 isZeroWidthSpace : 1; + + /// + /// Reserved for use by shaping engine. + /// + UINT16 reserved : 9; +}; + +/// +/// The interface implemented by the text analyzer's client to provide text to +/// the analyzer. It allows the separation between the logical view of text as +/// a continuous stream of characters identifiable by unique text positions, +/// and the actual memory layout of potentially discrete blocks of text in the +/// client's backing store. +/// +/// If any of these callbacks returns an error, the analysis functions will +/// stop prematurely and return a callback error. Rather than return E_NOTIMPL, +/// an application should stub the method and return a constant/null and S_OK. +/// +interface DECLSPEC_UUID("688e1a58-5094-47c8-adc8-fbcea60ae92b") DECLSPEC_NOVTABLE IDWriteTextAnalysisSource : public IUnknown +{ + /// + /// Get a block of text starting at the specified text position. + /// Returning NULL indicates the end of text - the position is after + /// the last character. This function is called iteratively for + /// each consecutive block, tying together several fragmented blocks + /// in the backing store into a virtual contiguous string. + /// + /// First position of the piece to obtain. All + /// positions are in UTF16 code-units, not whole characters, which + /// matters when supplementary characters are used. + /// Address that receives a pointer to the text block + /// at the specified position. + /// Number of UTF16 units of the retrieved chunk. + /// The returned length is not the length of the block, but the length + /// remaining in the block, from the given position until its end. + /// So querying for a position that is 75 positions into a 100 + /// postition block would return 25. + /// Pointer to the first character at the given text position. + /// NULL indicates no chunk available at the specified position, either + /// because textPosition >= the entire text content length or because the + /// queried position is not mapped into the app's backing store. + /// + /// Although apps can implement sparse textual content that only maps part of + /// the backing store, the app must map any text that is in the range passed + /// to any analysis functions. + /// + STDMETHOD(GetTextAtPosition)( + UINT32 textPosition, + __out WCHAR const** textString, + __out UINT32* textLength + ) PURE; + + /// + /// Get a block of text immediately preceding the specified position. + /// + /// Position immediately after the last position of the chunk to obtain. + /// Address that receives a pointer to the text block + /// at the specified position. + /// Number of UTF16 units of the retrieved block. + /// The length returned is from the given position to the front of + /// the block. + /// Pointer to the first character at (textPosition - textLength). + /// NULL indicates no chunk available at the specified position, either + /// because textPosition == 0,the textPosition > the entire text content + /// length, or the queried position is not mapped into the app's backing + /// store. + /// + /// Although apps can implement sparse textual content that only maps part of + /// the backing store, the app must map any text that is in the range passed + /// to any analysis functions. + /// + STDMETHOD(GetTextBeforePosition)( + UINT32 textPosition, + __out WCHAR const** textString, + __out UINT32* textLength + ) PURE; + + /// + /// Get paragraph reading direction. + /// + STDMETHOD_(DWRITE_READING_DIRECTION, GetParagraphReadingDirection)() PURE; + + /// + /// Get locale name on the range affected by it. + /// + /// Position to get the locale name of. + /// Receives the length from the given position up to the + /// next differing locale. + /// Address that receives a pointer to the locale + /// at the specified position. + /// + /// The localeName pointer must remain valid until the next call or until + /// the analysis returns. + /// + STDMETHOD(GetLocaleName)( + UINT32 textPosition, + __out UINT32* textLength, + __out_z WCHAR const** localeName + ) PURE; + + /// + /// Get number substitution on the range affected by it. + /// + /// Position to get the number substitution of. + /// Receives the length from the given position up to the + /// next differing number substitution. + /// Address that receives a pointer to the number substitution + /// at the specified position. + /// + /// Any implementation should return the number substitution with an + /// incremented ref count, and the analysis will release when finished + /// with it (either before the next call or before it returns). However, + /// the sink callback may hold onto it after that. + /// + STDMETHOD(GetNumberSubstitution)( + UINT32 textPosition, + __out UINT32* textLength, + __out IDWriteNumberSubstitution** numberSubstitution + ) PURE; +}; + +/// +/// The interface implemented by the text analyzer's client to receive the +/// output of a given text analysis. The Text analyzer disregards any current +/// state of the analysis sink, therefore a Set method call on a range +/// overwrites the previously set analysis result of the same range. +/// +interface DECLSPEC_UUID("5810cd44-0ca0-4701-b3fa-bec5182ae4f6") DECLSPEC_NOVTABLE IDWriteTextAnalysisSink : public IUnknown +{ + /// + /// Report script analysis for the text range. + /// + /// Starting position to report from. + /// Number of UTF16 units of the reported range. + /// Script analysis of characters in range. + /// + /// A successful code or error code to abort analysis. + /// + STDMETHOD(SetScriptAnalysis)( + UINT32 textPosition, + UINT32 textLength, + __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis + ) PURE; + + /// + /// Repport line-break opportunities for each character, starting from + /// the specified position. + /// + /// Starting position to report from. + /// Number of UTF16 units of the reported range. + /// Breaking conditions for each character. + /// + /// A successful code or error code to abort analysis. + /// + STDMETHOD(SetLineBreakpoints)( + UINT32 textPosition, + UINT32 textLength, + __in_ecount(textLength) DWRITE_LINE_BREAKPOINT const* lineBreakpoints + ) PURE; + + /// + /// Set bidirectional level on the range, called once per each + /// level run change (either explicit or resolved implicit). + /// + /// Starting position to report from. + /// Number of UTF16 units of the reported range. + /// Explicit level from embedded control codes + /// RLE/RLO/LRE/LRO/PDF, determined before any additional rules. + /// Final implicit level considering the + /// explicit level and characters' natural directionality, after all + /// Bidi rules have been applied. + /// + /// A successful code or error code to abort analysis. + /// + STDMETHOD(SetBidiLevel)( + UINT32 textPosition, + UINT32 textLength, + UINT8 explicitLevel, + UINT8 resolvedLevel + ) PURE; + + /// + /// Set number substitution on the range. + /// + /// Starting position to report from. + /// Number of UTF16 units of the reported range. + /// The number substitution applicable to + /// the returned range of text. The sink callback may hold onto it by + /// incrementing its ref count. + /// + /// A successful code or error code to abort analysis. + /// + /// + /// Unlike script and bidi analysis, where every character passed to the + /// analyzer has a result, this will only be called for those ranges where + /// substitution is applicable. For any other range, you will simply not + /// be called. + /// + STDMETHOD(SetNumberSubstitution)( + UINT32 textPosition, + UINT32 textLength, + __notnull IDWriteNumberSubstitution* numberSubstitution + ) PURE; +}; + +/// +/// Analyzes various text properties for complex script processing. +/// +interface DWRITE_DECLARE_INTERFACE("b7e6163e-7f46-43b4-84b3-e4e6249c365d") IDWriteTextAnalyzer : public IUnknown +{ + /// + /// Analyzes a text range for script boundaries, reading text attributes + /// from the source and reporting the Unicode script ID to the sink + /// callback SetScript. + /// + /// Source object to analyze. + /// Starting position within the source object. + /// Length to analyze. + /// Callback object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(AnalyzeScript)( + IDWriteTextAnalysisSource* analysisSource, + UINT32 textPosition, + UINT32 textLength, + IDWriteTextAnalysisSink* analysisSink + ) PURE; + + /// + /// Analyzes a text range for script directionality, reading attributes + /// from the source and reporting levels to the sink callback SetBidiLevel. + /// + /// Source object to analyze. + /// Starting position within the source object. + /// Length to analyze. + /// Callback object. + /// + /// Standard HRESULT error code. + /// + /// + /// While the function can handle multiple paragraphs, the text range + /// should not arbitrarily split the middle of paragraphs. Otherwise the + /// returned levels may be wrong, since the Bidi algorithm is meant to + /// apply to the paragraph as a whole. + /// + /// + /// Embedded control codes (LRE/LRO/RLE/RLO/PDF) are taken into account. + /// + STDMETHOD(AnalyzeBidi)( + IDWriteTextAnalysisSource* analysisSource, + UINT32 textPosition, + UINT32 textLength, + IDWriteTextAnalysisSink* analysisSink + ) PURE; + + /// + /// Analyzes a text range for spans where number substitution is applicable, + /// reading attributes from the source and reporting substitutable ranges + /// to the sink callback SetNumberSubstitution. + /// + /// Source object to analyze. + /// Starting position within the source object. + /// Length to analyze. + /// Callback object. + /// + /// Standard HRESULT error code. + /// + /// + /// While the function can handle multiple ranges of differing number + /// substitutions, the text ranges should not arbitrarily split the + /// middle of numbers. Otherwise it will treat the numbers separately + /// and will not translate any intervening punctuation. + /// + /// + /// Embedded control codes (LRE/LRO/RLE/RLO/PDF) are taken into account. + /// + STDMETHOD(AnalyzeNumberSubstitution)( + IDWriteTextAnalysisSource* analysisSource, + UINT32 textPosition, + UINT32 textLength, + IDWriteTextAnalysisSink* analysisSink + ) PURE; + + /// + /// Analyzes a text range for potential breakpoint opportunities, reading + /// attributes from the source and reporting breakpoint opportunities to + /// the sink callback SetLineBreakpoints. + /// + /// Source object to analyze. + /// Starting position within the source object. + /// Length to analyze. + /// Callback object. + /// + /// Standard HRESULT error code. + /// + /// + /// While the function can handle multiple paragraphs, the text range + /// should not arbitrarily split the middle of paragraphs, unless the + /// given text span is considered a whole unit. Otherwise the + /// returned properties for the first and last characters will + /// inappropriately allow breaks. + /// + /// + /// Special cases include the first, last, and surrogate characters. Any + /// text span is treated as if adjacent to inline objects on either side. + /// So the rules with contingent-break opportunities are used, where the + /// edge between text and inline objects is always treated as a potential + /// break opportunity, dependent on any overriding rules of the adjacent + /// objects to prohibit or force the break (see Unicode TR #14). + /// Surrogate pairs never break between. + /// + STDMETHOD(AnalyzeLineBreakpoints)( + IDWriteTextAnalysisSource* analysisSource, + UINT32 textPosition, + UINT32 textLength, + IDWriteTextAnalysisSink* analysisSink + ) PURE; + + /// + /// Parses the input text string and maps it to the set of glyphs and associated glyph data + /// according to the font and the writing system's rendering rules. + /// + /// The string to convert to glyphs. + /// The length of textString. + /// The font face to get glyphs from. + /// Set to true if the text is intended to be + /// drawn vertically. + /// Set to TRUE for right-to-left text. + /// Script analysis result from AnalyzeScript. + /// The locale to use when selecting glyphs. + /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs. + /// If this is NULL then the default mapping based on the script is used. + /// Optional number substitution which + /// selects the appropriate glyphs for digits and related numeric characters, + /// depending on the results obtained from AnalyzeNumberSubstitution. Passing + /// null indicates that no substitution is needed and that the digits should + /// receive nominal glyphs. + /// An array of pointers to the sets of typographic + /// features to use in each feature range. + /// The length of each feature range, in characters. + /// The sum of all lengths should be equal to textLength. + /// The number of feature ranges. + /// The maximum number of glyphs that can be + /// returned. + /// The mapping from character ranges to glyph + /// ranges. + /// Per-character output properties. + /// Output glyph indices. + /// Per-glyph output properties. + /// The actual number of glyphs returned if + /// the call succeeds. + /// + /// Standard HRESULT error code. + /// + /// + /// Note that the mapping from characters to glyphs is, in general, many- + /// to-many. The recommended estimate for the per-glyph output buffers is + /// (3 * textLength / 2 + 16). This is not guaranteed to be sufficient. + /// + /// The value of the actualGlyphCount parameter is only valid if the call + /// succeeds. In the event that maxGlyphCount is not big enough + /// E_NOT_SUFFICIENT_BUFFER, which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), + /// will be returned. The application should allocate a larger buffer and try again. + /// + STDMETHOD(GetGlyphs)( + __in_ecount(textLength) WCHAR const* textString, + UINT32 textLength, + IDWriteFontFace* fontFace, + BOOL isSideways, + BOOL isRightToLeft, + __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis, + __in_z_opt WCHAR const* localeName, + __maybenull IDWriteNumberSubstitution* numberSubstitution, + __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features, + __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths, + UINT32 featureRanges, + UINT32 maxGlyphCount, + __out_ecount(textLength) UINT16* clusterMap, + __out_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps, + __out_ecount(maxGlyphCount) UINT16* glyphIndices, + __out_ecount(maxGlyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProps, + __out UINT32* actualGlyphCount + ) PURE; + + /// + /// Place glyphs output from the GetGlyphs method according to the font + /// and the writing system's rendering rules. + /// + /// The original string the glyphs came from. + /// The mapping from character ranges to glyph + /// ranges. Returned by GetGlyphs. + /// Per-character properties. Returned by + /// GetGlyphs. + /// The length of textString. + /// Glyph indices. See GetGlyphs + /// Per-glyph properties. See GetGlyphs + /// The number of glyphs. + /// The font face the glyphs came from. + /// Logical font size in DIP's. + /// Set to true if the text is intended to be + /// drawn vertically. + /// Set to TRUE for right-to-left text. + /// Script analysis result from AnalyzeScript. + /// The locale to use when selecting glyphs. + /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs. + /// If this is NULL then the default mapping based on the script is used. + /// An array of pointers to the sets of typographic + /// features to use in each feature range. + /// The length of each feature range, in characters. + /// The sum of all lengths should be equal to textLength. + /// The number of feature ranges. + /// The advance width of each glyph. + /// The offset of the origin of each glyph. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetGlyphPlacements)( + __in_ecount(textLength) WCHAR const* textString, + __in_ecount(textLength) UINT16 const* clusterMap, + __in_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps, + UINT32 textLength, + __in_ecount(glyphCount) UINT16 const* glyphIndices, + __in_ecount(glyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps, + UINT32 glyphCount, + IDWriteFontFace * fontFace, + FLOAT fontEmSize, + BOOL isSideways, + BOOL isRightToLeft, + __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis, + __in_z_opt WCHAR const* localeName, + __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features, + __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths, + UINT32 featureRanges, + __out_ecount(glyphCount) FLOAT* glyphAdvances, + __out_ecount(glyphCount) DWRITE_GLYPH_OFFSET* glyphOffsets + ) PURE; + + /// + /// Place glyphs output from the GetGlyphs method according to the font + /// and the writing system's rendering rules. + /// + /// The original string the glyphs came from. + /// The mapping from character ranges to glyph + /// ranges. Returned by GetGlyphs. + /// Per-character properties. Returned by + /// GetGlyphs. + /// The length of textString. + /// Glyph indices. See GetGlyphs + /// Per-glyph properties. See GetGlyphs + /// The number of glyphs. + /// The font face the glyphs came from. + /// Logical font size in DIP's. + /// Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this + /// value is 1.0f. If the DPI is 120, this value is 120.0f/96. + /// Optional transform applied to the glyphs and their positions. This transform is applied after the + /// scaling specified by the font size and pixelsPerDip. + /// + /// When set to FALSE, the metrics are the same as the metrics of GDI aliased text. + /// When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font + /// created with CLEARTYPE_NATURAL_QUALITY. + /// + /// Set to true if the text is intended to be + /// drawn vertically. + /// Set to TRUE for right-to-left text. + /// Script analysis result from AnalyzeScript. + /// The locale to use when selecting glyphs. + /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs. + /// If this is NULL then the default mapping based on the script is used. + /// An array of pointers to the sets of typographic + /// features to use in each feature range. + /// The length of each feature range, in characters. + /// The sum of all lengths should be equal to textLength. + /// The number of feature ranges. + /// The advance width of each glyph. + /// The offset of the origin of each glyph. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetGdiCompatibleGlyphPlacements)( + __in_ecount(textLength) WCHAR const* textString, + __in_ecount(textLength) UINT16 const* clusterMap, + __in_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps, + UINT32 textLength, + __in_ecount(glyphCount) UINT16 const* glyphIndices, + __in_ecount(glyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps, + UINT32 glyphCount, + IDWriteFontFace * fontFace, + FLOAT fontEmSize, + FLOAT pixelsPerDip, + __in_opt DWRITE_MATRIX const* transform, + BOOL useGdiNatural, + BOOL isSideways, + BOOL isRightToLeft, + __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis, + __in_z_opt WCHAR const* localeName, + __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features, + __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths, + UINT32 featureRanges, + __out_ecount(glyphCount) FLOAT* glyphAdvances, + __out_ecount(glyphCount) DWRITE_GLYPH_OFFSET* glyphOffsets + ) PURE; +}; + +/// +/// The DWRITE_GLYPH_RUN structure contains the information needed by renderers +/// to draw glyph runs. All coordinates are in device independent pixels (DIPs). +/// +struct DWRITE_GLYPH_RUN +{ + /// + /// The physical font face to draw with. + /// + __notnull IDWriteFontFace* fontFace; + + /// + /// Logical size of the font in DIPs, not points (equals 1/96 inch). + /// + FLOAT fontEmSize; + + /// + /// The number of glyphs. + /// + UINT32 glyphCount; + + /// + /// The indices to render. + /// + __field_ecount(glyphCount) UINT16 const* glyphIndices; + + /// + /// Glyph advance widths. + /// + __field_ecount_opt(glyphCount) FLOAT const* glyphAdvances; + + /// + /// Glyph offsets. + /// + __field_ecount_opt(glyphCount) DWRITE_GLYPH_OFFSET const* glyphOffsets; + + /// + /// If true, specifies that glyphs are rotated 90 degrees to the left and + /// vertical metrics are used. Vertical writing is achieved by specifying + /// isSideways = true and rotating the entire run 90 degrees to the right + /// via a rotate transform. + /// + BOOL isSideways; + + /// + /// The implicit resolved bidi level of the run. Odd levels indicate + /// right-to-left languages like Hebrew and Arabic, while even levels + /// indicate left-to-right languages like English and Japanese (when + /// written horizontally). For right-to-left languages, the text origin + /// is on the right, and text should be drawn to the left. + /// + UINT32 bidiLevel; +}; + +/// +/// The DWRITE_GLYPH_RUN_DESCRIPTION structure contains additional properties +/// related to those in DWRITE_GLYPH_RUN. +/// +struct DWRITE_GLYPH_RUN_DESCRIPTION +{ + /// + /// The locale name associated with this run. + /// + __nullterminated WCHAR const* localeName; + + /// + /// The text associated with the glyphs. + /// + __field_ecount(stringLength) WCHAR const* string; + + /// + /// The number of characters (UTF16 code-units). + /// Note that this may be different than the number of glyphs. + /// + UINT32 stringLength; + + /// + /// An array of indices to the glyph indices array, of the first glyphs of + /// all the glyph clusters of the glyphs to render. + /// + __field_ecount(stringLength) UINT16 const* clusterMap; + + /// + /// Corresponding text position in the original string + /// this glyph run came from. + /// + UINT32 textPosition; +}; + +/// +/// The DWRITE_UNDERLINE structure contains about the size and placement of +/// underlines. All coordinates are in device independent pixels (DIPs). +/// +struct DWRITE_UNDERLINE +{ + /// + /// Width of the underline, measured parallel to the baseline. + /// + FLOAT width; + + /// + /// Thickness of the underline, measured perpendicular to the + /// baseline. + /// + FLOAT thickness; + + /// + /// Offset of the underline from the baseline. + /// A positive offset represents a position below the baseline and + /// a negative offset is above. + /// + FLOAT offset; + + /// + /// Height of the tallest run where the underline applies. + /// + FLOAT runHeight; + + /// + /// Reading direction of the text associated with the underline. This + /// value is used to interpret whether the width value runs horizontally + /// or vertically. + /// + DWRITE_READING_DIRECTION readingDirection; + + /// + /// Flow direction of the text associated with the underline. This value + /// is used to interpret whether the thickness value advances top to + /// bottom, left to right, or right to left. + /// + DWRITE_FLOW_DIRECTION flowDirection; + + /// + /// Locale of the text the underline is being drawn under. Can be + /// pertinent where the locale affects how the underline is drawn. + /// For example, in vertical text, the underline belongs on the + /// left for Chinese but on the right for Japanese. + /// This choice is completely left up to higher levels. + /// + __nullterminated WCHAR const* localeName; + + /// + /// The measuring mode can be useful to the renderer to determine how + /// underlines are rendered, e.g. rounding the thickness to a whole pixel + /// in GDI-compatible modes. + /// + DWRITE_MEASURING_MODE measuringMode; +}; + +/// +/// The DWRITE_STRIKETHROUGH structure contains about the size and placement of +/// strickthroughs. All coordinates are in device independent pixels (DIPs). +/// +struct DWRITE_STRIKETHROUGH +{ + /// + /// Width of the strikethrough, measured parallel to the baseline. + /// + FLOAT width; + + /// + /// Thickness of the strikethrough, measured perpendicular to the + /// baseline. + /// + FLOAT thickness; + + /// + /// Offset of the stikethrough from the baseline. + /// A positive offset represents a position below the baseline and + /// a negative offset is above. + /// + FLOAT offset; + + /// + /// Reading direction of the text associated with the strikethrough. This + /// value is used to interpret whether the width value runs horizontally + /// or vertically. + /// + DWRITE_READING_DIRECTION readingDirection; + + /// + /// Flow direction of the text associated with the strikethrough. This + /// value is used to interpret whether the thickness value advances top to + /// bottom, left to right, or right to left. + /// + DWRITE_FLOW_DIRECTION flowDirection; + + /// + /// Locale of the range. Can be pertinent where the locale affects the style. + /// + __nullterminated WCHAR const* localeName; + + /// + /// The measuring mode can be useful to the renderer to determine how + /// underlines are rendered, e.g. rounding the thickness to a whole pixel + /// in GDI-compatible modes. + /// + DWRITE_MEASURING_MODE measuringMode; +}; + +/// +/// The DWRITE_LINE_METRICS structure contains information about a formatted +/// line of text. +/// +struct DWRITE_LINE_METRICS +{ + /// + /// The number of total text positions in the line. + /// This includes any trailing whitespace and newline characters. + /// + UINT32 length; + + /// + /// The number of whitespace positions at the end of the line. Newline + /// sequences are considered whitespace. + /// + UINT32 trailingWhitespaceLength; + + /// + /// The number of characters in the newline sequence at the end of the line. + /// If the count is zero, then the line was either wrapped or it is the + /// end of the text. + /// + UINT32 newlineLength; + + /// + /// Height of the line as measured from top to bottom. + /// + FLOAT height; + + /// + /// Distance from the top of the line to its baseline. + /// + FLOAT baseline; + + /// + /// The line is trimmed. + /// + BOOL isTrimmed; +}; + + +/// +/// The DWRITE_CLUSTER_METRICS structure contains information about a glyph cluster. +/// +struct DWRITE_CLUSTER_METRICS +{ + /// + /// The total advance width of all glyphs in the cluster. + /// + FLOAT width; + + /// + /// The number of text positions in the cluster. + /// + UINT16 length; + + /// + /// Indicate whether line can be broken right after the cluster. + /// + UINT16 canWrapLineAfter : 1; + + /// + /// Indicate whether the cluster corresponds to whitespace character. + /// + UINT16 isWhitespace : 1; + + /// + /// Indicate whether the cluster corresponds to a newline character. + /// + UINT16 isNewline : 1; + + /// + /// Indicate whether the cluster corresponds to soft hyphen character. + /// + UINT16 isSoftHyphen : 1; + + /// + /// Indicate whether the cluster is read from right to left. + /// + UINT16 isRightToLeft : 1; + + UINT16 padding : 11; +}; + + +/// +/// Overall metrics associated with text after layout. +/// All coordinates are in device independent pixels (DIPs). +/// +struct DWRITE_TEXT_METRICS +{ + /// + /// Left-most point of formatted text relative to layout box + /// (excluding any glyph overhang). + /// + FLOAT left; + + /// + /// Top-most point of formatted text relative to layout box + /// (excluding any glyph overhang). + /// + FLOAT top; + + /// + /// The width of the formatted text ignoring trailing whitespace + /// at the end of each line. + /// + FLOAT width; + + /// + /// The width of the formatted text taking into account the + /// trailing whitespace at the end of each line. + /// + FLOAT widthIncludingTrailingWhitespace; + + /// + /// The height of the formatted text. The height of an empty string + /// is determined by the size of the default font's line height. + /// + FLOAT height; + + /// + /// Initial width given to the layout. Depending on whether the text + /// was wrapped or not, it can be either larger or smaller than the + /// text content width. + /// + FLOAT layoutWidth; + + /// + /// Initial height given to the layout. Depending on the length of the + /// text, it may be larger or smaller than the text content height. + /// + FLOAT layoutHeight; + + /// + /// The maximum reordering count of any line of text, used + /// to calculate the most number of hit-testing boxes needed. + /// If the layout has no bidirectional text or no text at all, + /// the minimum level is 1. + /// + UINT32 maxBidiReorderingDepth; + + /// + /// Total number of lines. + /// + UINT32 lineCount; +}; + + +/// +/// Properties describing the geometric measurement of an +/// application-defined inline object. +/// +struct DWRITE_INLINE_OBJECT_METRICS +{ + /// + /// Width of the inline object. + /// + FLOAT width; + + /// + /// Height of the inline object as measured from top to bottom. + /// + FLOAT height; + + /// + /// Distance from the top of the object to the baseline where it is lined up with the adjacent text. + /// If the baseline is at the bottom, baseline simply equals height. + /// + FLOAT baseline; + + /// + /// Flag indicating whether the object is to be placed upright or alongside the text baseline + /// for vertical text. + /// + BOOL supportsSideways; +}; + + +/// +/// The DWRITE_OVERHANG_METRICS structure holds how much any visible pixels +/// (in DIPs) overshoot each side of the layout or inline objects. +/// +/// +/// Positive overhangs indicate that the visible area extends outside the layout +/// box or inline object, while negative values mean there is whitespace inside. +/// The returned values are unaffected by rendering transforms or pixel snapping. +/// Additionally, they may not exactly match final target's pixel bounds after +/// applying grid fitting and hinting. +/// +struct DWRITE_OVERHANG_METRICS +{ + /// + /// The distance from the left-most visible DIP to its left alignment edge. + /// + FLOAT left; + + /// + /// The distance from the top-most visible DIP to its top alignment edge. + /// + FLOAT top; + + /// + /// The distance from the right-most visible DIP to its right alignment edge. + /// + FLOAT right; + + /// + /// The distance from the bottom-most visible DIP to its bottom alignment edge. + /// + FLOAT bottom; +}; + + +/// +/// Geometry enclosing of text positions. +/// +struct DWRITE_HIT_TEST_METRICS +{ + /// + /// First text position within the geometry. + /// + UINT32 textPosition; + + /// + /// Number of text positions within the geometry. + /// + UINT32 length; + + /// + /// Left position of the top-left coordinate of the geometry. + /// + FLOAT left; + + /// + /// Top position of the top-left coordinate of the geometry. + /// + FLOAT top; + + /// + /// Geometry's width. + /// + FLOAT width; + + /// + /// Geometry's height. + /// + FLOAT height; + + /// + /// Bidi level of text positions enclosed within the geometry. + /// + UINT32 bidiLevel; + + /// + /// Geometry encloses text? + /// + BOOL isText; + + /// + /// Range is trimmed. + /// + BOOL isTrimmed; +}; + + +interface IDWriteTextRenderer; + + +/// +/// The IDWriteInlineObject interface wraps an application defined inline graphic, +/// allowing DWrite to query metrics as if it was a glyph inline with the text. +/// +interface DWRITE_DECLARE_INTERFACE("8339FDE3-106F-47ab-8373-1C6295EB10B3") IDWriteInlineObject : public IUnknown +{ + /// + /// The application implemented rendering callback (IDWriteTextRenderer::DrawInlineObject) + /// can use this to draw the inline object without needing to cast or query the object + /// type. The text layout does not call this method directly. + /// + /// The context passed to IDWriteTextLayout::Draw. + /// The renderer passed to IDWriteTextLayout::Draw as the object's containing parent. + /// X-coordinate at the top-left corner of the inline object. + /// Y-coordinate at the top-left corner of the inline object. + /// The object should be drawn on its side. + /// The object is in an right-to-left context and should be drawn flipped. + /// The drawing effect set in IDWriteTextLayout::SetDrawingEffect. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(Draw)( + __maybenull void* clientDrawingContext, + IDWriteTextRenderer* renderer, + FLOAT originX, + FLOAT originY, + BOOL isSideways, + BOOL isRightToLeft, + __maybenull IUnknown* clientDrawingEffect + ) PURE; + + /// + /// TextLayout calls this callback function to get the measurement of the inline object. + /// + /// Returned metrics + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetMetrics)( + __out DWRITE_INLINE_OBJECT_METRICS* metrics + ) PURE; + + /// + /// TextLayout calls this callback function to get the visible extents (in DIPs) of the inline object. + /// In the case of a simple bitmap, with no padding and no overhang, all the overhangs will + /// simply be zeroes. + /// + /// Overshoot of visible extents (in DIPs) outside the object. + /// + /// Standard HRESULT error code. + /// + /// + /// The overhangs should be returned relative to the reported size of the object + /// (DWRITE_INLINE_OBJECT_METRICS::width/height), and should not be baseline + /// adjusted. If you have an image that is actually 100x100 DIPs, but you want it + /// slightly inset (perhaps it has a glow) by 20 DIPs on each side, you would + /// return a width/height of 60x60 and four overhangs of 20 DIPs. + /// + STDMETHOD(GetOverhangMetrics)( + __out DWRITE_OVERHANG_METRICS* overhangs + ) PURE; + + /// + /// Layout uses this to determine the line breaking behavior of the inline object + /// amidst the text. + /// + /// Line-breaking condition between the object and the content immediately preceding it. + /// Line-breaking condition between the object and the content immediately following it. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetBreakConditions)( + __out DWRITE_BREAK_CONDITION* breakConditionBefore, + __out DWRITE_BREAK_CONDITION* breakConditionAfter + ) PURE; +}; + +/// +/// The IDWritePixelSnapping interface defines the pixel snapping properties of a text renderer. +/// +interface DWRITE_DECLARE_INTERFACE("eaf3a2da-ecf4-4d24-b644-b34f6842024b") IDWritePixelSnapping : public IUnknown +{ + /// + /// Determines whether pixel snapping is disabled. The recommended default is FALSE, + /// unless doing animation that requires subpixel vertical placement. + /// + /// The context passed to IDWriteTextLayout::Draw. + /// Receives TRUE if pixel snapping is disabled or FALSE if it not. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(IsPixelSnappingDisabled)( + __maybenull void* clientDrawingContext, + __out BOOL* isDisabled + ) PURE; + + /// + /// Gets the current transform that maps abstract coordinates to DIPs, + /// which may disable pixel snapping upon any rotation or shear. + /// + /// The context passed to IDWriteTextLayout::Draw. + /// Receives the transform. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetCurrentTransform)( + __maybenull void* clientDrawingContext, + __out DWRITE_MATRIX* transform + ) PURE; + + /// + /// Gets the number of physical pixels per DIP. A DIP (device-independent pixel) is 1/96 inch, + /// so the pixelsPerDip value is the number of logical pixels per inch divided by 96 (yielding + /// a value of 1 for 96 DPI and 1.25 for 120). + /// + /// The context passed to IDWriteTextLayout::Draw. + /// Receives the number of physical pixels per DIP. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetPixelsPerDip)( + __maybenull void* clientDrawingContext, + __out FLOAT* pixelsPerDip + ) PURE; +}; + +/// +/// The IDWriteTextLayout interface represents a set of application-defined +/// callbacks that perform rendering of text, inline objects, and decorations +/// such as underlines. +/// +interface DWRITE_DECLARE_INTERFACE("ef8a8135-5cc6-45fe-8825-c5a0724eb819") IDWriteTextRenderer : public IDWritePixelSnapping +{ + /// + /// IDWriteTextLayout::Draw calls this function to instruct the client to + /// render a run of glyphs. + /// + /// The context passed to + /// IDWriteTextLayout::Draw. + /// X-coordinate of the baseline. + /// Y-coordinate of the baseline. + /// Specifies measuring method for glyphs in the run. + /// Renderer implementations may choose different rendering modes for given measuring methods, + /// but best results are seen when the rendering mode matches the corresponding measuring mode: + /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL + /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC + /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL + /// + /// The glyph run to draw. + /// Properties of the characters + /// associated with this run. + /// The drawing effect set in + /// IDWriteTextLayout::SetDrawingEffect. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(DrawGlyphRun)( + __maybenull void* clientDrawingContext, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + DWRITE_MEASURING_MODE measuringMode, + __in DWRITE_GLYPH_RUN const* glyphRun, + __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, + __maybenull IUnknown* clientDrawingEffect + ) PURE; + + /// + /// IDWriteTextLayout::Draw calls this function to instruct the client to draw + /// an underline. + /// + /// The context passed to + /// IDWriteTextLayout::Draw. + /// X-coordinate of the baseline. + /// Y-coordinate of the baseline. + /// Underline logical information. + /// The drawing effect set in + /// IDWriteTextLayout::SetDrawingEffect. + /// + /// Standard HRESULT error code. + /// + /// + /// A single underline can be broken into multiple calls, depending on + /// how the formatting changes attributes. If font sizes/styles change + /// within an underline, the thickness and offset will be averaged + /// weighted according to characters. + /// To get the correct top coordinate of the underline rect, add underline::offset + /// to the baseline's Y. Otherwise the underline will be immediately under the text. + /// The x coordinate will always be passed as the left side, regardless + /// of text directionality. This simplifies drawing and reduces the + /// problem of round-off that could potentially cause gaps or a double + /// stamped alpha blend. To avoid alpha overlap, round the end points + /// to the nearest device pixel. + /// + STDMETHOD(DrawUnderline)( + __maybenull void* clientDrawingContext, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + __in DWRITE_UNDERLINE const* underline, + __maybenull IUnknown* clientDrawingEffect + ) PURE; + + /// + /// IDWriteTextLayout::Draw calls this function to instruct the client to draw + /// a strikethrough. + /// + /// The context passed to + /// IDWriteTextLayout::Draw. + /// X-coordinate of the baseline. + /// Y-coordinate of the baseline. + /// Strikethrough logical information. + /// The drawing effect set in + /// IDWriteTextLayout::SetDrawingEffect. + /// + /// Standard HRESULT error code. + /// + /// + /// A single strikethrough can be broken into multiple calls, depending on + /// how the formatting changes attributes. Strikethrough is not averaged + /// across font sizes/styles changes. + /// To get the correct top coordinate of the strikethrough rect, + /// add strikethrough::offset to the baseline's Y. + /// Like underlines, the x coordinate will always be passed as the left side, + /// regardless of text directionality. + /// + STDMETHOD(DrawStrikethrough)( + __maybenull void* clientDrawingContext, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + __in DWRITE_STRIKETHROUGH const* strikethrough, + __maybenull IUnknown* clientDrawingEffect + ) PURE; + + /// + /// IDWriteTextLayout::Draw calls this application callback when it needs to + /// draw an inline object. + /// + /// The context passed to IDWriteTextLayout::Draw. + /// X-coordinate at the top-left corner of the inline object. + /// Y-coordinate at the top-left corner of the inline object. + /// The object set using IDWriteTextLayout::SetInlineObject. + /// The object should be drawn on its side. + /// The object is in an right-to-left context and should be drawn flipped. + /// The drawing effect set in + /// IDWriteTextLayout::SetDrawingEffect. + /// + /// Standard HRESULT error code. + /// + /// + /// The right-to-left flag is a hint for those cases where it would look + /// strange for the image to be shown normally (like an arrow pointing to + /// right to indicate a submenu). + /// + STDMETHOD(DrawInlineObject)( + __maybenull void* clientDrawingContext, + FLOAT originX, + FLOAT originY, + IDWriteInlineObject* inlineObject, + BOOL isSideways, + BOOL isRightToLeft, + __maybenull IUnknown* clientDrawingEffect + ) PURE; +}; + +/// +/// The IDWriteTextLayout interface represents a block of text after it has +/// been fully analyzed and formatted. +/// +/// All coordinates are in device independent pixels (DIPs). +/// +interface DWRITE_DECLARE_INTERFACE("53737037-6d14-410b-9bfe-0b182bb70961") IDWriteTextLayout : public IDWriteTextFormat +{ + /// + /// Set layout maximum width + /// + /// Layout maximum width + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetMaxWidth)( + FLOAT maxWidth + ) PURE; + + /// + /// Set layout maximum height + /// + /// Layout maximum height + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetMaxHeight)( + FLOAT maxHeight + ) PURE; + + /// + /// Set the font collection. + /// + /// The font collection to set + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetFontCollection)( + IDWriteFontCollection* fontCollection, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set null-terminated font family name. + /// + /// Font family name + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetFontFamilyName)( + __in_z WCHAR const* fontFamilyName, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set font weight. + /// + /// Font weight + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetFontWeight)( + DWRITE_FONT_WEIGHT fontWeight, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set font style. + /// + /// Font style + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetFontStyle)( + DWRITE_FONT_STYLE fontStyle, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set font stretch. + /// + /// font stretch + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetFontStretch)( + DWRITE_FONT_STRETCH fontStretch, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set font em height. + /// + /// Font em height + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetFontSize)( + FLOAT fontSize, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set underline. + /// + /// The Boolean flag indicates whether underline takes place + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetUnderline)( + BOOL hasUnderline, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set strikethrough. + /// + /// The Boolean flag indicates whether strikethrough takes place + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetStrikethrough)( + BOOL hasStrikethrough, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set application-defined drawing effect. + /// + /// Pointer to an application-defined drawing effect. + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + /// + /// This drawing effect is associated with the specified range and will be passed back + /// to the application via the callback when the range is drawn at drawing time. + /// + STDMETHOD(SetDrawingEffect)( + IUnknown* drawingEffect, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set inline object. + /// + /// Pointer to an application-implemented inline object. + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + /// + /// This inline object applies to the specified range and will be passed back + /// to the application via the DrawInlineObject callback when the range is drawn. + /// Any text in that range will be suppressed. + /// + STDMETHOD(SetInlineObject)( + IDWriteInlineObject* inlineObject, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set font typography features. + /// + /// Pointer to font typography setting. + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetTypography)( + IDWriteTypography* typography, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Set locale name. + /// + /// Locale name + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetLocaleName)( + __in_z WCHAR const* localeName, + DWRITE_TEXT_RANGE textRange + ) PURE; + + /// + /// Get layout maximum width + /// + STDMETHOD_(FLOAT, GetMaxWidth)() PURE; + + /// + /// Get layout maximum height + /// + STDMETHOD_(FLOAT, GetMaxHeight)() PURE; + + /// + /// Get the font collection where the current position is at. + /// + /// The current text position. + /// The current font collection + /// Text range to which this change applies. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontCollection)( + UINT32 currentPosition, + __out IDWriteFontCollection** fontCollection, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the length of the font family name where the current position is at. + /// + /// The current text position. + /// Size of the character array in character count not including the terminated NULL character. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontFamilyNameLength)( + UINT32 currentPosition, + __out UINT32* nameLength, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Copy the font family name where the current position is at. + /// + /// The current text position. + /// Character array that receives the current font family name + /// Size of the character array in character count including the terminated NULL character. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontFamilyName)( + UINT32 currentPosition, + __out_ecount_z(nameSize) WCHAR* fontFamilyName, + UINT32 nameSize, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the font weight where the current position is at. + /// + /// The current text position. + /// The current font weight + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontWeight)( + UINT32 currentPosition, + __out DWRITE_FONT_WEIGHT* fontWeight, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the font style where the current position is at. + /// + /// The current text position. + /// The current font style + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontStyle)( + UINT32 currentPosition, + __out DWRITE_FONT_STYLE* fontStyle, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the font stretch where the current position is at. + /// + /// The current text position. + /// The current font stretch + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontStretch)( + UINT32 currentPosition, + __out DWRITE_FONT_STRETCH* fontStretch, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the font em height where the current position is at. + /// + /// The current text position. + /// The current font em height + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetFontSize)( + UINT32 currentPosition, + __out FLOAT* fontSize, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the underline presence where the current position is at. + /// + /// The current text position. + /// The Boolean flag indicates whether text is underlined. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetUnderline)( + UINT32 currentPosition, + __out BOOL* hasUnderline, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the strikethrough presence where the current position is at. + /// + /// The current text position. + /// The Boolean flag indicates whether text has strikethrough. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetStrikethrough)( + UINT32 currentPosition, + __out BOOL* hasStrikethrough, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the application-defined drawing effect where the current position is at. + /// + /// The current text position. + /// The current application-defined drawing effect. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetDrawingEffect)( + UINT32 currentPosition, + __out IUnknown** drawingEffect, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the inline object at the given position. + /// + /// The given text position. + /// The inline object. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetInlineObject)( + UINT32 currentPosition, + __out IDWriteInlineObject** inlineObject, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the typography setting where the current position is at. + /// + /// The current text position. + /// The current typography setting. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetTypography)( + UINT32 currentPosition, + __out IDWriteTypography** typography, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the length of the locale name where the current position is at. + /// + /// The current text position. + /// Size of the character array in character count not including the terminated NULL character. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLocaleNameLength)( + UINT32 currentPosition, + __out UINT32* nameLength, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Get the locale name where the current position is at. + /// + /// The current text position. + /// Character array that receives the current locale name + /// Size of the character array in character count including the terminated NULL character. + /// The position range of the current format. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetLocaleName)( + UINT32 currentPosition, + __out_ecount_z(nameSize) WCHAR* localeName, + UINT32 nameSize, + __out_opt DWRITE_TEXT_RANGE* textRange = NULL + ) PURE; + + /// + /// Initiate drawing of the text. + /// + /// An application defined value + /// included in rendering callbacks. + /// The set of application-defined callbacks that do + /// the actual rendering. + /// X-coordinate of the layout's left side. + /// Y-coordinate of the layout's top side. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(Draw)( + __maybenull void* clientDrawingContext, + IDWriteTextRenderer* renderer, + FLOAT originX, + FLOAT originY + ) PURE; + + /// + /// GetLineMetrics returns properties of each line. + /// + /// The array to fill with line information. + /// The maximum size of the lineMetrics array. + /// The actual size of the lineMetrics + /// array that is needed. + /// + /// Standard HRESULT error code. + /// + /// + /// If maxLineCount is not large enough E_NOT_SUFFICIENT_BUFFER, + /// which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), + /// is returned and *actualLineCount is set to the number of lines + /// needed. + /// + STDMETHOD(GetLineMetrics)( + __out_ecount_opt(maxLineCount) DWRITE_LINE_METRICS* lineMetrics, + UINT32 maxLineCount, + __out UINT32* actualLineCount + ) PURE; + + /// + /// GetMetrics retrieves overall metrics for the formatted string. + /// + /// The returned metrics. + /// + /// Standard HRESULT error code. + /// + /// + /// Drawing effects like underline and strikethrough do not contribute + /// to the text size, which is essentially the sum of advance widths and + /// line heights. Additionally, visible swashes and other graphic + /// adornments may extend outside the returned width and height. + /// + STDMETHOD(GetMetrics)( + __out DWRITE_TEXT_METRICS* textMetrics + ) PURE; + + /// + /// GetOverhangMetrics returns the overhangs (in DIPs) of the layout and all + /// objects contained in it, including text glyphs and inline objects. + /// + /// Overshoots of visible extents (in DIPs) outside the layout. + /// + /// Standard HRESULT error code. + /// + /// + /// Any underline and strikethrough do not contribute to the black box + /// determination, since these are actually drawn by the renderer, which + /// is allowed to draw them in any variety of styles. + /// + STDMETHOD(GetOverhangMetrics)( + __out DWRITE_OVERHANG_METRICS* overhangs + ) PURE; + + /// + /// Retrieve logical properties and measurement of each cluster. + /// + /// The array to fill with cluster information. + /// The maximum size of the clusterMetrics array. + /// The actual size of the clusterMetrics array that is needed. + /// + /// Standard HRESULT error code. + /// + /// + /// If maxClusterCount is not large enough E_NOT_SUFFICIENT_BUFFER, + /// which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), + /// is returned and *actualClusterCount is set to the number of clusters + /// needed. + /// + STDMETHOD(GetClusterMetrics)( + __out_ecount_opt(maxClusterCount) DWRITE_CLUSTER_METRICS* clusterMetrics, + UINT32 maxClusterCount, + __out UINT32* actualClusterCount + ) PURE; + + /// + /// Determines the minimum possible width the layout can be set to without + /// emergency breaking between the characters of whole words. + /// + /// Minimum width. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(DetermineMinWidth)( + __out FLOAT* minWidth + ) PURE; + + /// + /// Given a coordinate (in DIPs) relative to the top-left of the layout box, + /// this returns the corresponding hit-test metrics of the text string where + /// the hit-test has occurred. This is useful for mapping mouse clicks to caret + /// positions. When the given coordinate is outside the text string, the function + /// sets the output value *isInside to false but returns the nearest character + /// position. + /// + /// X coordinate to hit-test, relative to the top-left location of the layout box. + /// Y coordinate to hit-test, relative to the top-left location of the layout box. + /// Output flag indicating whether the hit-test location is at the leading or the trailing + /// side of the character. When the output *isInside value is set to false, this value is set according to the output + /// *position value to represent the edge closest to the hit-test location. + /// Output flag indicating whether the hit-test location is inside the text string. + /// When false, the position nearest the text's edge is returned. + /// Output geometry fully enclosing the hit-test location. When the output *isInside value + /// is set to false, this structure represents the geometry enclosing the edge closest to the hit-test location. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(HitTestPoint)( + FLOAT pointX, + FLOAT pointY, + __out BOOL* isTrailingHit, + __out BOOL* isInside, + __out DWRITE_HIT_TEST_METRICS* hitTestMetrics + ) PURE; + + /// + /// Given a text position and whether the caret is on the leading or trailing + /// edge of that position, this returns the corresponding coordinate (in DIPs) + /// relative to the top-left of the layout box. This is most useful for drawing + /// the caret's current position, but it could also be used to anchor an IME to the + /// typed text or attach a floating menu near the point of interest. It may also be + /// used to programmatically obtain the geometry of a particular text position + /// for UI automation. + /// + /// Text position to get the coordinate of. + /// Flag indicating whether the location is of the leading or the trailing side of the specified text position. + /// Output caret X, relative to the top-left of the layout box. + /// Output caret Y, relative to the top-left of the layout box. + /// Output geometry fully enclosing the specified text position. + /// + /// Standard HRESULT error code. + /// + /// + /// When drawing a caret at the returned X,Y, it should should be centered on X + /// and drawn from the Y coordinate down. The height will be the size of the + /// hit-tested text (which can vary in size within a line). + /// Reading direction also affects which side of the character the caret is drawn. + /// However, the returned X coordinate will be correct for either case. + /// You can get a text length back that is larger than a single character. + /// This happens for complex scripts when multiple characters form a single cluster, + /// when diacritics join their base character, or when you test a surrogate pair. + /// + STDMETHOD(HitTestTextPosition)( + UINT32 textPosition, + BOOL isTrailingHit, + __out FLOAT* pointX, + __out FLOAT* pointY, + __out DWRITE_HIT_TEST_METRICS* hitTestMetrics + ) PURE; + + /// + /// The application calls this function to get a set of hit-test metrics + /// corresponding to a range of text positions. The main usage for this + /// is to draw highlighted selection of the text string. + /// + /// The function returns E_NOT_SUFFICIENT_BUFFER, which is equivalent to + /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), when the buffer size of + /// hitTestMetrics is too small to hold all the regions calculated by the + /// function. In such situation, the function sets the output value + /// *actualHitTestMetricsCount to the number of geometries calculated. + /// The application is responsible to allocate a new buffer of greater + /// size and call the function again. + /// + /// A good value to use as an initial value for maxHitTestMetricsCount may + /// be calculated from the following equation: + /// maxHitTestMetricsCount = lineCount * maxBidiReorderingDepth + /// + /// where lineCount is obtained from the value of the output argument + /// *actualLineCount from the function IDWriteTextLayout::GetLineMetrics, + /// and the maxBidiReorderingDepth value from the DWRITE_TEXT_METRICS + /// structure of the output argument *textMetrics from the function + /// IDWriteFactory::CreateTextLayout. + /// + /// First text position of the specified range. + /// Number of positions of the specified range. + /// Offset of the X origin (left of the layout box) which is added to each of the hit-test metrics returned. + /// Offset of the Y origin (top of the layout box) which is added to each of the hit-test metrics returned. + /// Pointer to a buffer of the output geometry fully enclosing the specified position range. + /// Maximum number of distinct metrics it could hold in its buffer memory. + /// Actual number of metrics returned or needed. + /// + /// Standard HRESULT error code. + /// + /// + /// There are no gaps in the returned metrics. While there could be visual gaps, + /// depending on bidi ordering, each range is contiguous and reports all the text, + /// including any hidden characters and trimmed text. + /// The height of each returned range will be the same within each line, regardless + /// of how the font sizes vary. + /// + STDMETHOD(HitTestTextRange)( + UINT32 textPosition, + UINT32 textLength, + FLOAT originX, + FLOAT originY, + __out_ecount_opt(maxHitTestMetricsCount) DWRITE_HIT_TEST_METRICS* hitTestMetrics, + UINT32 maxHitTestMetricsCount, + __out UINT32* actualHitTestMetricsCount + ) PURE; +}; + +/// +/// Encapsulates a 32-bit device independent bitmap and device context, which can be used for rendering glyphs. +/// +interface DWRITE_DECLARE_INTERFACE("5e5a32a3-8dff-4773-9ff6-0696eab77267") IDWriteBitmapRenderTarget : public IUnknown +{ + /// + /// Draws a run of glyphs to the bitmap. + /// + /// Horizontal position of the baseline origin, in DIPs, relative to the upper-left corner of the DIB. + /// Vertical position of the baseline origin, in DIPs, relative to the upper-left corner of the DIB. + /// Specifies measuring method for glyphs in the run. + /// Renderer implementations may choose different rendering modes for different measuring methods, for example + /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL, + /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC, and + /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL. + /// + /// Structure containing the properties of the glyph run. + /// Object that controls rendering behavior. + /// Specifies the foreground color of the text. + /// Optional rectangle that receives the bounding box (in pixels not DIPs) of all the pixels affected by + /// drawing the glyph run. The black box rectangle may extend beyond the dimensions of the bitmap. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(DrawGlyphRun)( + FLOAT baselineOriginX, + FLOAT baselineOriginY, + DWRITE_MEASURING_MODE measuringMode, + __in DWRITE_GLYPH_RUN const* glyphRun, + IDWriteRenderingParams* renderingParams, + COLORREF textColor, + __out_opt RECT* blackBoxRect = NULL + ) PURE; + + /// + /// Gets a handle to the memory device context. + /// + /// + /// Returns the device context handle. + /// + /// + /// An application can use the device context to draw using GDI functions. An application can obtain the bitmap handle + /// (HBITMAP) by calling GetCurrentObject. An application that wants information about the underlying bitmap, including + /// a pointer to the pixel data, can call GetObject to fill in a DIBSECTION structure. The bitmap is always a 32-bit + /// top-down DIB. + /// + STDMETHOD_(HDC, GetMemoryDC)() PURE; + + /// + /// Gets the number of bitmap pixels per DIP. A DIP (device-independent pixel) is 1/96 inch so this value is the number + /// if pixels per inch divided by 96. + /// + /// + /// Returns the number of bitmap pixels per DIP. + /// + STDMETHOD_(FLOAT, GetPixelsPerDip)() PURE; + + /// + /// Sets the number of bitmap pixels per DIP. A DIP (device-independent pixel) is 1/96 inch so this value is the number + /// if pixels per inch divided by 96. + /// + /// Specifies the number of pixels per DIP. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetPixelsPerDip)( + FLOAT pixelsPerDip + ) PURE; + + /// + /// Gets the transform that maps abstract coordinate to DIPs. By default this is the identity + /// transform. Note that this is unrelated to the world transform of the underlying device + /// context. + /// + /// Receives the transform. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetCurrentTransform)( + __out DWRITE_MATRIX* transform + ) PURE; + + /// + /// Sets the transform that maps abstract coordinate to DIPs. This does not affect the world + /// transform of the underlying device context. + /// + /// Specifies the new transform. This parameter can be NULL, in which + /// case the identity transform is implied. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(SetCurrentTransform)( + __in_opt DWRITE_MATRIX const* transform + ) PURE; + + /// + /// Gets the dimensions of the bitmap. + /// + /// Receives the size of the bitmap in pixels. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetSize)( + __out SIZE* size + ) PURE; + + /// + /// Resizes the bitmap. + /// + /// New bitmap width, in pixels. + /// New bitmap height, in pixels. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(Resize)( + UINT32 width, + UINT32 height + ) PURE; +}; + +/// +/// The GDI interop interface provides interoperability with GDI. +/// +interface DWRITE_DECLARE_INTERFACE("1edd9491-9853-4299-898f-6432983b6f3a") IDWriteGdiInterop : public IUnknown +{ + /// + /// Creates a font object that matches the properties specified by the LOGFONT structure. + /// + /// Structure containing a GDI-compatible font description. + /// Receives a newly created font object if successful, or NULL in case of error. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateFontFromLOGFONT)( + __in LOGFONTW const* logFont, + __out IDWriteFont** font + ) PURE; + + /// + /// Initializes a LOGFONT structure based on the GDI-compatible properties of the specified font. + /// + /// Specifies a font in the system font collection. + /// Structure that receives a GDI-compatible font description. + /// Contains TRUE if the specified font object is part of the system font collection + /// or FALSE otherwise. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(ConvertFontToLOGFONT)( + IDWriteFont* font, + __out LOGFONTW* logFont, + __out BOOL* isSystemFont + ) PURE; + + /// + /// Initializes a LOGFONT structure based on the GDI-compatible properties of the specified font. + /// + /// Specifies a font face. + /// Structure that receives a GDI-compatible font description. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(ConvertFontFaceToLOGFONT)( + IDWriteFontFace* font, + __out LOGFONTW* logFont + ) PURE; + + /// + /// Creates a font face object that corresponds to the currently selected HFONT. + /// + /// Handle to a device context into which a font has been selected. It is assumed that the client + /// has already performed font mapping and that the font selected into the DC is the actual font that would be used + /// for rendering glyphs. + /// Contains the newly created font face object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateFontFaceFromHdc)( + HDC hdc, + __out IDWriteFontFace** fontFace + ) PURE; + + /// + /// Creates an object that encapsulates a bitmap and memory DC which can be used for rendering glyphs. + /// + /// Optional device context used to create a compatible memory DC. + /// Width of the bitmap. + /// Height of the bitmap. + /// Receives a pointer to the newly created render target. + STDMETHOD(CreateBitmapRenderTarget)( + __in_opt HDC hdc, + UINT32 width, + UINT32 height, + __out IDWriteBitmapRenderTarget** renderTarget + ) PURE; +}; + +/// +/// The DWRITE_TEXTURE_TYPE enumeration identifies a type of alpha texture. An alpha texture is a bitmap of alpha values, each +/// representing the darkness (i.e., opacity) of a pixel or subpixel. +/// +enum DWRITE_TEXTURE_TYPE +{ + /// + /// Specifies an alpha texture for aliased text rendering (i.e., bi-level, where each pixel is either fully opaque or fully transparent), + /// with one byte per pixel. + /// + DWRITE_TEXTURE_ALIASED_1x1, + + /// + /// Specifies an alpha texture for ClearType text rendering, with three bytes per pixel in the horizontal dimension and + /// one byte per pixel in the vertical dimension. + /// + DWRITE_TEXTURE_CLEARTYPE_3x1 +}; + +/// +/// Maximum alpha value in a texture returned by IDWriteGlyphRunAnalysis::CreateAlphaTexture. +/// +#define DWRITE_ALPHA_MAX 255 + +/// +/// Interface that encapsulates information used to render a glyph run. +/// +interface DWRITE_DECLARE_INTERFACE("7d97dbf7-e085-42d4-81e3-6a883bded118") IDWriteGlyphRunAnalysis : public IUnknown +{ + /// + /// Gets the bounding rectangle of the physical pixels affected by the glyph run. + /// + /// Specifies the type of texture requested. If a bi-level texture is requested, the + /// bounding rectangle includes only bi-level glyphs. Otherwise, the bounding rectangle includes only anti-aliased + /// glyphs. + /// Receives the bounding rectangle, or an empty rectangle if there are no glyphs + /// if the specified type. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetAlphaTextureBounds)( + DWRITE_TEXTURE_TYPE textureType, + __out RECT* textureBounds + ) PURE; + + /// + /// Creates an alpha texture of the specified type. + /// + /// Specifies the type of texture requested. If a bi-level texture is requested, the + /// texture contains only bi-level glyphs. Otherwise, the texture contains only anti-aliased glyphs. + /// Specifies the bounding rectangle of the texture, which can be different than + /// the bounding rectangle returned by GetAlphaTextureBounds. + /// Receives the array of alpha values. + /// Size of the alphaValues array. The minimum size depends on the dimensions of the + /// rectangle and the type of texture requested. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateAlphaTexture)( + DWRITE_TEXTURE_TYPE textureType, + __in RECT const* textureBounds, + __out_bcount(bufferSize) BYTE* alphaValues, + UINT32 bufferSize + ) PURE; + + /// + /// Gets properties required for ClearType blending. + /// + /// Rendering parameters object. In most cases, the values returned in the output + /// parameters are based on the properties of this object. The exception is if a GDI-compatible rendering mode + /// is specified. + /// Receives the gamma value to use for gamma correction. + /// Receives the enhanced contrast value. + /// Receives the ClearType level. + STDMETHOD(GetAlphaBlendParams)( + IDWriteRenderingParams* renderingParams, + __out FLOAT* blendGamma, + __out FLOAT* blendEnhancedContrast, + __out FLOAT* blendClearTypeLevel + ) PURE; +}; + +/// +/// The root factory interface for all DWrite objects. +/// +interface DWRITE_DECLARE_INTERFACE("b859ee5a-d838-4b5b-a2e8-1adc7d93db48") IDWriteFactory : public IUnknown +{ + /// + /// Gets a font collection representing the set of installed fonts. + /// + /// Receives a pointer to the system font collection object, or NULL in case of failure. + /// If this parameter is nonzero, the function performs an immediate check for changes to the set of + /// installed fonts. If this parameter is FALSE, the function will still detect changes if the font cache service is running, but + /// there may be some latency. For example, an application might specify TRUE if it has itself just installed a font and wants to + /// be sure the font collection contains that font. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetSystemFontCollection)( + __out IDWriteFontCollection** fontCollection, + BOOL checkForUpdates = FALSE + ) PURE; + + /// + /// Creates a font collection using a custom font collection loader. + /// + /// Application-defined font collection loader, which must have been previously + /// registered using RegisterFontCollectionLoader. + /// Key used by the loader to identify a collection of font files. + /// Size in bytes of the collection key. + /// Receives a pointer to the system font collection object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateCustomFontCollection)( + IDWriteFontCollectionLoader* collectionLoader, + __in_bcount(collectionKeySize) void const* collectionKey, + UINT32 collectionKeySize, + __out IDWriteFontCollection** fontCollection + ) PURE; + + /// + /// Registers a custom font collection loader with the factory object. + /// + /// Application-defined font collection loader. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(RegisterFontCollectionLoader)( + IDWriteFontCollectionLoader* fontCollectionLoader + ) PURE; + + /// + /// Unregisters a custom font collection loader that was previously registered using RegisterFontCollectionLoader. + /// + /// Application-defined font collection loader. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(UnregisterFontCollectionLoader)( + IDWriteFontCollectionLoader* fontCollectionLoader + ) PURE; + + /// + /// CreateFontFileReference creates a font file reference object from a local font file. + /// + /// Absolute file path. Subsequent operations on the constructed object may fail + /// if the user provided filePath doesn't correspond to a valid file on the disk. + /// Last modified time of the input file path. If the parameter is omitted, + /// the function will access the font file to obtain its last write time, so the clients are encouraged to specify this value + /// to avoid extra disk access. Subsequent operations on the constructed object may fail + /// if the user provided lastWriteTime doesn't match the file on the disk. + /// Contains newly created font file reference object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateFontFileReference)( + __in_z WCHAR const* filePath, + __in_opt FILETIME const* lastWriteTime, + __out IDWriteFontFile** fontFile + ) PURE; + + /// + /// CreateCustomFontFileReference creates a reference to an application specific font file resource. + /// This function enables an application or a document to use a font without having to install it on the system. + /// The fontFileReferenceKey has to be unique only in the scope of the fontFileLoader used in this call. + /// + /// Font file reference key that uniquely identifies the font file resource + /// during the lifetime of fontFileLoader. + /// Size of font file reference key in bytes. + /// Font file loader that will be used by the font system to load data from the file identified by + /// fontFileReferenceKey. + /// Contains the newly created font file object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + /// + /// This function is provided for cases when an application or a document needs to use a font + /// without having to install it on the system. fontFileReferenceKey has to be unique only in the scope + /// of the fontFileLoader used in this call. + /// + STDMETHOD(CreateCustomFontFileReference)( + __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + IDWriteFontFileLoader* fontFileLoader, + __out IDWriteFontFile** fontFile + ) PURE; + + /// + /// Creates a font face object. + /// + /// The file format of the font face. + /// The number of font files require to represent the font face. + /// Font files representing the font face. Since IDWriteFontFace maintains its own references + /// to the input font file objects, it's OK to release them after this call. + /// The zero based index of a font face in cases when the font files contain a collection of font faces. + /// If the font files contain a single face, this value should be zero. + /// Font face simulation flags for algorithmic emboldening and italicization. + /// Contains the newly created font face object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateFontFace)( + DWRITE_FONT_FACE_TYPE fontFaceType, + UINT32 numberOfFiles, + __in_ecount(numberOfFiles) IDWriteFontFile* const* fontFiles, + UINT32 faceIndex, + DWRITE_FONT_SIMULATIONS fontFaceSimulationFlags, + __out IDWriteFontFace** fontFace + ) PURE; + + /// + /// Creates a rendering parameters object with default settings for the primary monitor. + /// + /// Holds the newly created rendering parameters object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateRenderingParams)( + __out IDWriteRenderingParams** renderingParams + ) PURE; + + /// + /// Creates a rendering parameters object with default settings for the specified monitor. + /// + /// The monitor to read the default values from. + /// Holds the newly created rendering parameters object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateMonitorRenderingParams)( + HMONITOR monitor, + __out IDWriteRenderingParams** renderingParams + ) PURE; + + /// + /// Creates a rendering parameters object with the specified properties. + /// + /// The gamma value used for gamma correction, which must be greater than zero and cannot exceed 256. + /// The amount of contrast enhancement, zero or greater. + /// The degree of ClearType level, from 0.0f (no ClearType) to 1.0f (full ClearType). + /// The geometry of a device pixel. + /// Method of rendering glyphs. In most cases, this should be DWRITE_RENDERING_MODE_DEFAULT to automatically use an appropriate mode. + /// Holds the newly created rendering parameters object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateCustomRenderingParams)( + FLOAT gamma, + FLOAT enhancedContrast, + FLOAT clearTypeLevel, + DWRITE_PIXEL_GEOMETRY pixelGeometry, + DWRITE_RENDERING_MODE renderingMode, + __out IDWriteRenderingParams** renderingParams + ) PURE; + + /// + /// Registers a font file loader with DirectWrite. + /// + /// Pointer to the implementation of the IDWriteFontFileLoader for a particular file resource type. + /// + /// Standard HRESULT error code. + /// + /// + /// This function registers a font file loader with DirectWrite. + /// Font file loader interface handles loading font file resources of a particular type from a key. + /// The font file loader interface is recommended to be implemented by a singleton object. + /// A given instance can only be registered once. + /// Succeeding attempts will return an error that it has already been registered. + /// IMPORTANT: font file loader implementations must not register themselves with DirectWrite + /// inside their constructors and must not unregister themselves in their destructors, because + /// registration and unregistraton operations increment and decrement the object reference count respectively. + /// Instead, registration and unregistration of font file loaders with DirectWrite should be performed + /// outside of the font file loader implementation as a separate step. + /// + STDMETHOD(RegisterFontFileLoader)( + IDWriteFontFileLoader* fontFileLoader + ) PURE; + + /// + /// Unregisters a font file loader that was previously registered with the DirectWrite font system using RegisterFontFileLoader. + /// + /// Pointer to the file loader that was previously registered with the DirectWrite font system using RegisterFontFileLoader. + /// + /// This function will succeed if the user loader is requested to be removed. + /// It will fail if the pointer to the file loader identifies a standard DirectWrite loader, + /// or a loader that is never registered or has already been unregistered. + /// + /// + /// This function unregisters font file loader callbacks with the DirectWrite font system. + /// The font file loader interface is recommended to be implemented by a singleton object. + /// IMPORTANT: font file loader implementations must not register themselves with DirectWrite + /// inside their constructors and must not unregister themselves in their destructors, because + /// registration and unregistraton operations increment and decrement the object reference count respectively. + /// Instead, registration and unregistration of font file loaders with DirectWrite should be performed + /// outside of the font file loader implementation as a separate step. + /// + STDMETHOD(UnregisterFontFileLoader)( + IDWriteFontFileLoader* fontFileLoader + ) PURE; + + /// + /// Create a text format object used for text layout. + /// + /// Name of the font family + /// Font collection. NULL indicates the system font collection. + /// Font weight + /// Font style + /// Font stretch + /// Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch. + /// Locale name + /// Contains newly created text format object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateTextFormat)( + __in_z WCHAR const* fontFamilyName, + __maybenull IDWriteFontCollection* fontCollection, + DWRITE_FONT_WEIGHT fontWeight, + DWRITE_FONT_STYLE fontStyle, + DWRITE_FONT_STRETCH fontStretch, + FLOAT fontSize, + __in_z WCHAR const* localeName, + __out IDWriteTextFormat** textFormat + ) PURE; + + /// + /// Create a typography object used in conjunction with text format for text layout. + /// + /// Contains newly created typography object, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateTypography)( + __out IDWriteTypography** typography + ) PURE; + + /// + /// Create an object used for interoperability with GDI. + /// + /// Receives the GDI interop object if successful, or NULL in case of failure. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(GetGdiInterop)( + __out IDWriteGdiInterop** gdiInterop + ) PURE; + + /// + /// CreateTextLayout takes a string, format, and associated constraints + /// and produces and object representing the fully analyzed + /// and formatted result. + /// + /// The string to layout. + /// The length of the string. + /// The format to apply to the string. + /// Width of the layout box. + /// Height of the layout box. + /// The resultant object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateTextLayout)( + __in_ecount(stringLength) WCHAR const* string, + UINT32 stringLength, + IDWriteTextFormat* textFormat, + FLOAT maxWidth, + FLOAT maxHeight, + __out IDWriteTextLayout** textLayout + ) PURE; + + /// + /// CreateGdiCompatibleTextLayout takes a string, format, and associated constraints + /// and produces and object representing the result formatted for a particular display resolution + /// and measuring method. The resulting text layout should only be used for the intended resolution, + /// and for cases where text scalability is desired, CreateTextLayout should be used instead. + /// + /// The string to layout. + /// The length of the string. + /// The format to apply to the string. + /// Width of the layout box. + /// Height of the layout box. + /// Number of physical pixels per DIP. For example, if rendering onto a 96 DPI device then pixelsPerDip + /// is 1. If rendering onto a 120 DPI device then pixelsPerDip is 120/96. + /// Optional transform applied to the glyphs and their positions. This transform is applied after the + /// scaling specified the font size and pixelsPerDip. + /// + /// When set to FALSE, instructs the text layout to use the same metrics as GDI aliased text. + /// When set to TRUE, instructs the text layout to use the same metrics as text measured by GDI using a font + /// created with CLEARTYPE_NATURAL_QUALITY. + /// + /// The resultant object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateGdiCompatibleTextLayout)( + __in_ecount(stringLength) WCHAR const* string, + UINT32 stringLength, + IDWriteTextFormat* textFormat, + FLOAT layoutWidth, + FLOAT layoutHeight, + FLOAT pixelsPerDip, + __in_opt DWRITE_MATRIX const* transform, + BOOL useGdiNatural, + __out IDWriteTextLayout** textLayout + ) PURE; + + /// + /// The application may call this function to create an inline object for trimming, using an ellipsis as the omission sign. + /// The ellipsis will be created using the current settings of the format, including base font, style, and any effects. + /// Alternate omission signs can be created by the application by implementing IDWriteInlineObject. + /// + /// Text format used as a template for the omission sign. + /// Created omission sign. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateEllipsisTrimmingSign)( + IDWriteTextFormat* textFormat, + __out IDWriteInlineObject** trimmingSign + ) PURE; + + /// + /// Return an interface to perform text analysis with. + /// + /// The resultant object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateTextAnalyzer)( + __out IDWriteTextAnalyzer** textAnalyzer + ) PURE; + + /// + /// Creates a number substitution object using a locale name, + /// substitution method, and whether to ignore user overrides (uses NLS + /// defaults for the given culture instead). + /// + /// Method of number substitution to use. + /// Which locale to obtain the digits from. + /// Ignore the user's settings and use the locale defaults + /// Receives a pointer to the newly created object. + STDMETHOD(CreateNumberSubstitution)( + __in DWRITE_NUMBER_SUBSTITUTION_METHOD substitutionMethod, + __in_z WCHAR const* localeName, + __in BOOL ignoreUserOverride, + __out IDWriteNumberSubstitution** numberSubstitution + ) PURE; + + /// + /// Creates a glyph run analysis object, which encapsulates information + /// used to render a glyph run. + /// + /// Structure specifying the properties of the glyph run. + /// Number of physical pixels per DIP. For example, if rendering onto a 96 DPI bitmap then pixelsPerDip + /// is 1. If rendering onto a 120 DPI bitmap then pixelsPerDip is 120/96. + /// Optional transform applied to the glyphs and their positions. This transform is applied after the + /// scaling specified the emSize and pixelsPerDip. + /// Specifies the rendering mode, which must be one of the raster rendering modes (i.e., not default + /// and not outline). + /// Specifies the method to measure glyphs. + /// Horizontal position of the baseline origin, in DIPs. + /// Vertical position of the baseline origin, in DIPs. + /// Receives a pointer to the newly created object. + /// + /// Standard HRESULT error code. + /// + STDMETHOD(CreateGlyphRunAnalysis)( + __in DWRITE_GLYPH_RUN const* glyphRun, + FLOAT pixelsPerDip, + __in_opt DWRITE_MATRIX const* transform, + DWRITE_RENDERING_MODE renderingMode, + DWRITE_MEASURING_MODE measuringMode, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + __out IDWriteGlyphRunAnalysis** glyphRunAnalysis + ) PURE; + +}; // interface IDWriteFactory + +/// +/// Creates a DirectWrite factory object that is used for subsequent creation of individual DirectWrite objects. +/// +/// Identifies whether the factory object will be shared or isolated. +/// Identifies the DirectWrite factory interface, such as __uuidof(IDWriteFactory). +/// Receives the DirectWrite factory object. +/// +/// Standard HRESULT error code. +/// +/// +/// Obtains DirectWrite factory object that is used for subsequent creation of individual DirectWrite classes. +/// DirectWrite factory contains internal state such as font loader registration and cached font data. +/// In most cases it is recommended to use the shared factory object, because it allows multiple components +/// that use DirectWrite to share internal DirectWrite state and reduce memory usage. +/// However, there are cases when it is desirable to reduce the impact of a component, +/// such as a plug-in from an untrusted source, on the rest of the process by sandboxing and isolating it +/// from the rest of the process components. In such cases, it is recommended to use an isolated factory for the sandboxed +/// component. +/// +EXTERN_C HRESULT DWRITE_EXPORT DWriteCreateFactory( + __in DWRITE_FACTORY_TYPE factoryType, + __in REFIID iid, + __out IUnknown **factory + ); + +// Macros used to define DirectWrite error codes. +#define FACILITY_DWRITE 0x898 +#define DWRITE_ERR_BASE 0x5000 +#define MAKE_DWRITE_HR(severity, code) MAKE_HRESULT(severity, FACILITY_DWRITE, (DWRITE_ERR_BASE + code)) +#define MAKE_DWRITE_HR_ERR(code) MAKE_DWRITE_HR(SEVERITY_ERROR, code) + +/// +/// Indicates an error in an input file such as a font file. +/// +#define DWRITE_E_FILEFORMAT MAKE_DWRITE_HR_ERR(0x000) + +/// +/// Indicates an error originating in DirectWrite code, which is not expected to occur but is safe to recover from. +/// +#define DWRITE_E_UNEXPECTED MAKE_DWRITE_HR_ERR(0x001) + +/// +/// Indicates the specified font does not exist. +/// +#define DWRITE_E_NOFONT MAKE_DWRITE_HR_ERR(0x002) + +/// +/// A font file could not be opened because the file, directory, network location, drive, or other storage +/// location does not exist or is unavailable. +/// +#define DWRITE_E_FILENOTFOUND MAKE_DWRITE_HR_ERR(0x003) + +/// +/// A font file exists but could not be opened due to access denied, sharing violation, or similar error. +/// +#define DWRITE_E_FILEACCESS MAKE_DWRITE_HR_ERR(0x004) + +/// +/// A font collection is obsolete due to changes in the system. +/// +#define DWRITE_E_FONTCOLLECTIONOBSOLETE MAKE_DWRITE_HR_ERR(0x005) + +/// +/// The given interface is already registered. +/// +#define DWRITE_E_ALREADYREGISTERED MAKE_DWRITE_HR_ERR(0x006) + +#endif /* DWRITE_H_INCLUDED */ diff --git a/dxsdk/Include/DXGI.h b/dxsdk/Include/DXGI.h new file mode 100644 index 0000000..1bfb39e --- /dev/null +++ b/dxsdk/Include/DXGI.h @@ -0,0 +1,2901 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __dxgi_h__ +#define __dxgi_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IDXGIObject_FWD_DEFINED__ +#define __IDXGIObject_FWD_DEFINED__ +typedef interface IDXGIObject IDXGIObject; +#endif /* __IDXGIObject_FWD_DEFINED__ */ + + +#ifndef __IDXGIDeviceSubObject_FWD_DEFINED__ +#define __IDXGIDeviceSubObject_FWD_DEFINED__ +typedef interface IDXGIDeviceSubObject IDXGIDeviceSubObject; +#endif /* __IDXGIDeviceSubObject_FWD_DEFINED__ */ + + +#ifndef __IDXGIResource_FWD_DEFINED__ +#define __IDXGIResource_FWD_DEFINED__ +typedef interface IDXGIResource IDXGIResource; +#endif /* __IDXGIResource_FWD_DEFINED__ */ + + +#ifndef __IDXGIKeyedMutex_FWD_DEFINED__ +#define __IDXGIKeyedMutex_FWD_DEFINED__ +typedef interface IDXGIKeyedMutex IDXGIKeyedMutex; +#endif /* __IDXGIKeyedMutex_FWD_DEFINED__ */ + + +#ifndef __IDXGISurface_FWD_DEFINED__ +#define __IDXGISurface_FWD_DEFINED__ +typedef interface IDXGISurface IDXGISurface; +#endif /* __IDXGISurface_FWD_DEFINED__ */ + + +#ifndef __IDXGISurface1_FWD_DEFINED__ +#define __IDXGISurface1_FWD_DEFINED__ +typedef interface IDXGISurface1 IDXGISurface1; +#endif /* __IDXGISurface1_FWD_DEFINED__ */ + + +#ifndef __IDXGIAdapter_FWD_DEFINED__ +#define __IDXGIAdapter_FWD_DEFINED__ +typedef interface IDXGIAdapter IDXGIAdapter; +#endif /* __IDXGIAdapter_FWD_DEFINED__ */ + + +#ifndef __IDXGIOutput_FWD_DEFINED__ +#define __IDXGIOutput_FWD_DEFINED__ +typedef interface IDXGIOutput IDXGIOutput; +#endif /* __IDXGIOutput_FWD_DEFINED__ */ + + +#ifndef __IDXGISwapChain_FWD_DEFINED__ +#define __IDXGISwapChain_FWD_DEFINED__ +typedef interface IDXGISwapChain IDXGISwapChain; +#endif /* __IDXGISwapChain_FWD_DEFINED__ */ + + +#ifndef __IDXGIFactory_FWD_DEFINED__ +#define __IDXGIFactory_FWD_DEFINED__ +typedef interface IDXGIFactory IDXGIFactory; +#endif /* __IDXGIFactory_FWD_DEFINED__ */ + + +#ifndef __IDXGIDevice_FWD_DEFINED__ +#define __IDXGIDevice_FWD_DEFINED__ +typedef interface IDXGIDevice IDXGIDevice; +#endif /* __IDXGIDevice_FWD_DEFINED__ */ + + +#ifndef __IDXGIFactory1_FWD_DEFINED__ +#define __IDXGIFactory1_FWD_DEFINED__ +typedef interface IDXGIFactory1 IDXGIFactory1; +#endif /* __IDXGIFactory1_FWD_DEFINED__ */ + + +#ifndef __IDXGIAdapter1_FWD_DEFINED__ +#define __IDXGIAdapter1_FWD_DEFINED__ +typedef interface IDXGIAdapter1 IDXGIAdapter1; +#endif /* __IDXGIAdapter1_FWD_DEFINED__ */ + + +#ifndef __IDXGIDevice1_FWD_DEFINED__ +#define __IDXGIDevice1_FWD_DEFINED__ +typedef interface IDXGIDevice1 IDXGIDevice1; +#endif /* __IDXGIDevice1_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "dxgitype.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_dxgi_0000_0000 */ +/* [local] */ + +#define DXGI_CPU_ACCESS_NONE ( 0 ) +#define DXGI_CPU_ACCESS_DYNAMIC ( 1 ) +#define DXGI_CPU_ACCESS_READ_WRITE ( 2 ) +#define DXGI_CPU_ACCESS_SCRATCH ( 3 ) +#define DXGI_CPU_ACCESS_FIELD 15 +#define DXGI_USAGE_SHADER_INPUT ( 1L << (0 + 4) ) +#define DXGI_USAGE_RENDER_TARGET_OUTPUT ( 1L << (1 + 4) ) +#define DXGI_USAGE_BACK_BUFFER ( 1L << (2 + 4) ) +#define DXGI_USAGE_SHARED ( 1L << (3 + 4) ) +#define DXGI_USAGE_READ_ONLY ( 1L << (4 + 4) ) +#define DXGI_USAGE_DISCARD_ON_PRESENT ( 1L << (5 + 4) ) +#define DXGI_USAGE_UNORDERED_ACCESS ( 1L << (6 + 4) ) +typedef UINT DXGI_USAGE; + +typedef struct DXGI_FRAME_STATISTICS + { + UINT PresentCount; + UINT PresentRefreshCount; + UINT SyncRefreshCount; + LARGE_INTEGER SyncQPCTime; + LARGE_INTEGER SyncGPUTime; + } DXGI_FRAME_STATISTICS; + +typedef struct DXGI_MAPPED_RECT + { + INT Pitch; + BYTE *pBits; + } DXGI_MAPPED_RECT; + +#ifdef __midl +typedef struct _LUID + { + DWORD LowPart; + LONG HighPart; + } LUID; + +typedef struct _LUID *PLUID; + +#endif +typedef struct DXGI_ADAPTER_DESC + { + WCHAR Description[ 128 ]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; + } DXGI_ADAPTER_DESC; + +#if !defined(HMONITOR_DECLARED) && !defined(HMONITOR) && (WINVER < 0x0500) +#define HMONITOR_DECLARED +#if 0 +typedef HANDLE HMONITOR; + +#endif +DECLARE_HANDLE(HMONITOR); +#endif +typedef struct DXGI_OUTPUT_DESC + { + WCHAR DeviceName[ 32 ]; + RECT DesktopCoordinates; + BOOL AttachedToDesktop; + DXGI_MODE_ROTATION Rotation; + HMONITOR Monitor; + } DXGI_OUTPUT_DESC; + +typedef struct DXGI_SHARED_RESOURCE + { + HANDLE Handle; + } DXGI_SHARED_RESOURCE; + +#define DXGI_RESOURCE_PRIORITY_MINIMUM ( 0x28000000 ) + +#define DXGI_RESOURCE_PRIORITY_LOW ( 0x50000000 ) + +#define DXGI_RESOURCE_PRIORITY_NORMAL ( 0x78000000 ) + +#define DXGI_RESOURCE_PRIORITY_HIGH ( 0xa0000000 ) + +#define DXGI_RESOURCE_PRIORITY_MAXIMUM ( 0xc8000000 ) + +typedef +enum DXGI_RESIDENCY + { DXGI_RESIDENCY_FULLY_RESIDENT = 1, + DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2, + DXGI_RESIDENCY_EVICTED_TO_DISK = 3 + } DXGI_RESIDENCY; + +typedef struct DXGI_SURFACE_DESC + { + UINT Width; + UINT Height; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + } DXGI_SURFACE_DESC; + +typedef +enum DXGI_SWAP_EFFECT + { DXGI_SWAP_EFFECT_DISCARD = 0, + DXGI_SWAP_EFFECT_SEQUENTIAL = 1 + } DXGI_SWAP_EFFECT; + +typedef +enum DXGI_SWAP_CHAIN_FLAG + { DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1, + DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2, + DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4 + } DXGI_SWAP_CHAIN_FLAG; + +typedef struct DXGI_SWAP_CHAIN_DESC + { + DXGI_MODE_DESC BufferDesc; + DXGI_SAMPLE_DESC SampleDesc; + DXGI_USAGE BufferUsage; + UINT BufferCount; + HWND OutputWindow; + BOOL Windowed; + DXGI_SWAP_EFFECT SwapEffect; + UINT Flags; + } DXGI_SWAP_CHAIN_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0000_v0_0_s_ifspec; + +#ifndef __IDXGIObject_INTERFACE_DEFINED__ +#define __IDXGIObject_INTERFACE_DEFINED__ + +/* interface IDXGIObject */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIObject; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aec22fb8-76f3-4639-9be0-28eb43a67a2e") + IDXGIObject : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetParent( + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIObjectVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIObject * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIObject * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIObject * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIObject * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIObject * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIObject * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIObject * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + END_INTERFACE + } IDXGIObjectVtbl; + + interface IDXGIObject + { + CONST_VTBL struct IDXGIObjectVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIObject_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIObject_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIObject_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIObject_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIObject_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIObject_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIObject_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIObject_INTERFACE_DEFINED__ */ + + +#ifndef __IDXGIDeviceSubObject_INTERFACE_DEFINED__ +#define __IDXGIDeviceSubObject_INTERFACE_DEFINED__ + +/* interface IDXGIDeviceSubObject */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIDeviceSubObject; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3d3e0379-f9de-4d58-bb6c-18d62992f1a6") + IDXGIDeviceSubObject : public IDXGIObject + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDevice( + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppDevice) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIDeviceSubObjectVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIDeviceSubObject * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIDeviceSubObject * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIDeviceSubObject * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIDeviceSubObject * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIDeviceSubObject * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIDeviceSubObject * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIDeviceSubObject * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + IDXGIDeviceSubObject * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppDevice); + + END_INTERFACE + } IDXGIDeviceSubObjectVtbl; + + interface IDXGIDeviceSubObject + { + CONST_VTBL struct IDXGIDeviceSubObjectVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIDeviceSubObject_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIDeviceSubObject_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIDeviceSubObject_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIDeviceSubObject_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIDeviceSubObject_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIDeviceSubObject_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIDeviceSubObject_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIDeviceSubObject_GetDevice(This,riid,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppDevice) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIDeviceSubObject_INTERFACE_DEFINED__ */ + + +#ifndef __IDXGIResource_INTERFACE_DEFINED__ +#define __IDXGIResource_INTERFACE_DEFINED__ + +/* interface IDXGIResource */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIResource; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("035f3ab4-482e-4e50-b41f-8a7f8bd8960b") + IDXGIResource : public IDXGIDeviceSubObject + { + public: + virtual HRESULT STDMETHODCALLTYPE GetSharedHandle( + /* [annotation][out] */ + __out HANDLE *pSharedHandle) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetUsage( + /* [annotation][out] */ + __out DXGI_USAGE *pUsage) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetEvictionPriority( + /* [in] */ UINT EvictionPriority) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetEvictionPriority( + /* [annotation][retval][out] */ + __out UINT *pEvictionPriority) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIResourceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIResource * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIResource * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIResource * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIResource * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIResource * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIResource * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIResource * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + IDXGIResource * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetSharedHandle )( + IDXGIResource * This, + /* [annotation][out] */ + __out HANDLE *pSharedHandle); + + HRESULT ( STDMETHODCALLTYPE *GetUsage )( + IDXGIResource * This, + /* [annotation][out] */ + __out DXGI_USAGE *pUsage); + + HRESULT ( STDMETHODCALLTYPE *SetEvictionPriority )( + IDXGIResource * This, + /* [in] */ UINT EvictionPriority); + + HRESULT ( STDMETHODCALLTYPE *GetEvictionPriority )( + IDXGIResource * This, + /* [annotation][retval][out] */ + __out UINT *pEvictionPriority); + + END_INTERFACE + } IDXGIResourceVtbl; + + interface IDXGIResource + { + CONST_VTBL struct IDXGIResourceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIResource_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIResource_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIResource_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIResource_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIResource_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIResource_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIResource_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIResource_GetDevice(This,riid,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppDevice) ) + + +#define IDXGIResource_GetSharedHandle(This,pSharedHandle) \ + ( (This)->lpVtbl -> GetSharedHandle(This,pSharedHandle) ) + +#define IDXGIResource_GetUsage(This,pUsage) \ + ( (This)->lpVtbl -> GetUsage(This,pUsage) ) + +#define IDXGIResource_SetEvictionPriority(This,EvictionPriority) \ + ( (This)->lpVtbl -> SetEvictionPriority(This,EvictionPriority) ) + +#define IDXGIResource_GetEvictionPriority(This,pEvictionPriority) \ + ( (This)->lpVtbl -> GetEvictionPriority(This,pEvictionPriority) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIResource_INTERFACE_DEFINED__ */ + + +#ifndef __IDXGIKeyedMutex_INTERFACE_DEFINED__ +#define __IDXGIKeyedMutex_INTERFACE_DEFINED__ + +/* interface IDXGIKeyedMutex */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIKeyedMutex; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9d8e1289-d7b3-465f-8126-250e349af85d") + IDXGIKeyedMutex : public IDXGIDeviceSubObject + { + public: + virtual HRESULT STDMETHODCALLTYPE AcquireSync( + /* [in] */ UINT64 Key, + /* [in] */ DWORD dwMilliseconds) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReleaseSync( + /* [in] */ UINT64 Key) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIKeyedMutexVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIKeyedMutex * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIKeyedMutex * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIKeyedMutex * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIKeyedMutex * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIKeyedMutex * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIKeyedMutex * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIKeyedMutex * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + IDXGIKeyedMutex * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *AcquireSync )( + IDXGIKeyedMutex * This, + /* [in] */ UINT64 Key, + /* [in] */ DWORD dwMilliseconds); + + HRESULT ( STDMETHODCALLTYPE *ReleaseSync )( + IDXGIKeyedMutex * This, + /* [in] */ UINT64 Key); + + END_INTERFACE + } IDXGIKeyedMutexVtbl; + + interface IDXGIKeyedMutex + { + CONST_VTBL struct IDXGIKeyedMutexVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIKeyedMutex_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIKeyedMutex_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIKeyedMutex_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIKeyedMutex_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIKeyedMutex_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIKeyedMutex_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIKeyedMutex_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIKeyedMutex_GetDevice(This,riid,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppDevice) ) + + +#define IDXGIKeyedMutex_AcquireSync(This,Key,dwMilliseconds) \ + ( (This)->lpVtbl -> AcquireSync(This,Key,dwMilliseconds) ) + +#define IDXGIKeyedMutex_ReleaseSync(This,Key) \ + ( (This)->lpVtbl -> ReleaseSync(This,Key) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIKeyedMutex_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0004 */ +/* [local] */ + +#define DXGI_MAP_READ ( 1UL ) + +#define DXGI_MAP_WRITE ( 2UL ) + +#define DXGI_MAP_DISCARD ( 4UL ) + + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0004_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0004_v0_0_s_ifspec; + +#ifndef __IDXGISurface_INTERFACE_DEFINED__ +#define __IDXGISurface_INTERFACE_DEFINED__ + +/* interface IDXGISurface */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGISurface; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("cafcb56c-6ac3-4889-bf47-9e23bbd260ec") + IDXGISurface : public IDXGIDeviceSubObject + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [annotation][out] */ + __out DXGI_SURFACE_DESC *pDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE Map( + /* [annotation][out] */ + __out DXGI_MAPPED_RECT *pLockedRect, + /* [in] */ UINT MapFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE Unmap( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGISurfaceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGISurface * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGISurface * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGISurface * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGISurface * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGISurface * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGISurface * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGISurface * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + IDXGISurface * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetDesc )( + IDXGISurface * This, + /* [annotation][out] */ + __out DXGI_SURFACE_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *Map )( + IDXGISurface * This, + /* [annotation][out] */ + __out DXGI_MAPPED_RECT *pLockedRect, + /* [in] */ UINT MapFlags); + + HRESULT ( STDMETHODCALLTYPE *Unmap )( + IDXGISurface * This); + + END_INTERFACE + } IDXGISurfaceVtbl; + + interface IDXGISurface + { + CONST_VTBL struct IDXGISurfaceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGISurface_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGISurface_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGISurface_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGISurface_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGISurface_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGISurface_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGISurface_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGISurface_GetDevice(This,riid,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppDevice) ) + + +#define IDXGISurface_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#define IDXGISurface_Map(This,pLockedRect,MapFlags) \ + ( (This)->lpVtbl -> Map(This,pLockedRect,MapFlags) ) + +#define IDXGISurface_Unmap(This) \ + ( (This)->lpVtbl -> Unmap(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGISurface_INTERFACE_DEFINED__ */ + + +#ifndef __IDXGISurface1_INTERFACE_DEFINED__ +#define __IDXGISurface1_INTERFACE_DEFINED__ + +/* interface IDXGISurface1 */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGISurface1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4AE63092-6327-4c1b-80AE-BFE12EA32B86") + IDXGISurface1 : public IDXGISurface + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDC( + /* [in] */ BOOL Discard, + /* [annotation][out] */ + __out HDC *phdc) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReleaseDC( + /* [annotation][in] */ + __in_opt RECT *pDirtyRect) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGISurface1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGISurface1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGISurface1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGISurface1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGISurface1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGISurface1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGISurface1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGISurface1 * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + IDXGISurface1 * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *GetDesc )( + IDXGISurface1 * This, + /* [annotation][out] */ + __out DXGI_SURFACE_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *Map )( + IDXGISurface1 * This, + /* [annotation][out] */ + __out DXGI_MAPPED_RECT *pLockedRect, + /* [in] */ UINT MapFlags); + + HRESULT ( STDMETHODCALLTYPE *Unmap )( + IDXGISurface1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetDC )( + IDXGISurface1 * This, + /* [in] */ BOOL Discard, + /* [annotation][out] */ + __out HDC *phdc); + + HRESULT ( STDMETHODCALLTYPE *ReleaseDC )( + IDXGISurface1 * This, + /* [annotation][in] */ + __in_opt RECT *pDirtyRect); + + END_INTERFACE + } IDXGISurface1Vtbl; + + interface IDXGISurface1 + { + CONST_VTBL struct IDXGISurface1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGISurface1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGISurface1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGISurface1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGISurface1_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGISurface1_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGISurface1_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGISurface1_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGISurface1_GetDevice(This,riid,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppDevice) ) + + +#define IDXGISurface1_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#define IDXGISurface1_Map(This,pLockedRect,MapFlags) \ + ( (This)->lpVtbl -> Map(This,pLockedRect,MapFlags) ) + +#define IDXGISurface1_Unmap(This) \ + ( (This)->lpVtbl -> Unmap(This) ) + + +#define IDXGISurface1_GetDC(This,Discard,phdc) \ + ( (This)->lpVtbl -> GetDC(This,Discard,phdc) ) + +#define IDXGISurface1_ReleaseDC(This,pDirtyRect) \ + ( (This)->lpVtbl -> ReleaseDC(This,pDirtyRect) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGISurface1_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0006 */ +/* [local] */ + + + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0006_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0006_v0_0_s_ifspec; + +#ifndef __IDXGIAdapter_INTERFACE_DEFINED__ +#define __IDXGIAdapter_INTERFACE_DEFINED__ + +/* interface IDXGIAdapter */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIAdapter; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2411e7e1-12ac-4ccf-bd14-9798e8534dc0") + IDXGIAdapter : public IDXGIObject + { + public: + virtual HRESULT STDMETHODCALLTYPE EnumOutputs( + /* [in] */ UINT Output, + /* [annotation][out][in] */ + __out IDXGIOutput **ppOutput) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC *pDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( + /* [annotation][in] */ + __in REFGUID InterfaceName, + /* [annotation][out] */ + __out LARGE_INTEGER *pUMDVersion) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIAdapterVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIAdapter * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIAdapter * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIAdapter * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIAdapter * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIAdapter * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIAdapter * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIAdapter * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *EnumOutputs )( + IDXGIAdapter * This, + /* [in] */ UINT Output, + /* [annotation][out][in] */ + __out IDXGIOutput **ppOutput); + + HRESULT ( STDMETHODCALLTYPE *GetDesc )( + IDXGIAdapter * This, + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *CheckInterfaceSupport )( + IDXGIAdapter * This, + /* [annotation][in] */ + __in REFGUID InterfaceName, + /* [annotation][out] */ + __out LARGE_INTEGER *pUMDVersion); + + END_INTERFACE + } IDXGIAdapterVtbl; + + interface IDXGIAdapter + { + CONST_VTBL struct IDXGIAdapterVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIAdapter_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIAdapter_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIAdapter_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIAdapter_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIAdapter_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIAdapter_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIAdapter_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIAdapter_EnumOutputs(This,Output,ppOutput) \ + ( (This)->lpVtbl -> EnumOutputs(This,Output,ppOutput) ) + +#define IDXGIAdapter_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#define IDXGIAdapter_CheckInterfaceSupport(This,InterfaceName,pUMDVersion) \ + ( (This)->lpVtbl -> CheckInterfaceSupport(This,InterfaceName,pUMDVersion) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIAdapter_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0007 */ +/* [local] */ + +#define DXGI_ENUM_MODES_INTERLACED ( 1UL ) + +#define DXGI_ENUM_MODES_SCALING ( 2UL ) + + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0007_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0007_v0_0_s_ifspec; + +#ifndef __IDXGIOutput_INTERFACE_DEFINED__ +#define __IDXGIOutput_INTERFACE_DEFINED__ + +/* interface IDXGIOutput */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIOutput; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ae02eedb-c735-4690-8d52-5a8dc20213aa") + IDXGIOutput : public IDXGIObject + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [annotation][out] */ + __out DXGI_OUTPUT_DESC *pDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList( + /* [in] */ DXGI_FORMAT EnumFormat, + /* [in] */ UINT Flags, + /* [annotation][out][in] */ + __inout UINT *pNumModes, + /* [annotation][out] */ + __out_ecount_part_opt(*pNumModes,*pNumModes) DXGI_MODE_DESC *pDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode( + /* [annotation][in] */ + __in const DXGI_MODE_DESC *pModeToMatch, + /* [annotation][out] */ + __out DXGI_MODE_DESC *pClosestMatch, + /* [annotation][in] */ + __in_opt IUnknown *pConcernedDevice) = 0; + + virtual HRESULT STDMETHODCALLTYPE WaitForVBlank( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE TakeOwnership( + /* [annotation][in] */ + __in IUnknown *pDevice, + BOOL Exclusive) = 0; + + virtual void STDMETHODCALLTYPE ReleaseOwnership( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities( + /* [annotation][out] */ + __out DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetGammaControl( + /* [annotation][in] */ + __in const DXGI_GAMMA_CONTROL *pArray) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGammaControl( + /* [annotation][out] */ + __out DXGI_GAMMA_CONTROL *pArray) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetDisplaySurface( + /* [annotation][in] */ + __in IDXGISurface *pScanoutSurface) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData( + /* [annotation][in] */ + __in IDXGISurface *pDestination) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( + /* [annotation][out] */ + __out DXGI_FRAME_STATISTICS *pStats) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIOutputVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIOutput * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIOutput * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIOutput * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIOutput * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIOutput * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIOutput * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIOutput * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDesc )( + IDXGIOutput * This, + /* [annotation][out] */ + __out DXGI_OUTPUT_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayModeList )( + IDXGIOutput * This, + /* [in] */ DXGI_FORMAT EnumFormat, + /* [in] */ UINT Flags, + /* [annotation][out][in] */ + __inout UINT *pNumModes, + /* [annotation][out] */ + __out_ecount_part_opt(*pNumModes,*pNumModes) DXGI_MODE_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *FindClosestMatchingMode )( + IDXGIOutput * This, + /* [annotation][in] */ + __in const DXGI_MODE_DESC *pModeToMatch, + /* [annotation][out] */ + __out DXGI_MODE_DESC *pClosestMatch, + /* [annotation][in] */ + __in_opt IUnknown *pConcernedDevice); + + HRESULT ( STDMETHODCALLTYPE *WaitForVBlank )( + IDXGIOutput * This); + + HRESULT ( STDMETHODCALLTYPE *TakeOwnership )( + IDXGIOutput * This, + /* [annotation][in] */ + __in IUnknown *pDevice, + BOOL Exclusive); + + void ( STDMETHODCALLTYPE *ReleaseOwnership )( + IDXGIOutput * This); + + HRESULT ( STDMETHODCALLTYPE *GetGammaControlCapabilities )( + IDXGIOutput * This, + /* [annotation][out] */ + __out DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps); + + HRESULT ( STDMETHODCALLTYPE *SetGammaControl )( + IDXGIOutput * This, + /* [annotation][in] */ + __in const DXGI_GAMMA_CONTROL *pArray); + + HRESULT ( STDMETHODCALLTYPE *GetGammaControl )( + IDXGIOutput * This, + /* [annotation][out] */ + __out DXGI_GAMMA_CONTROL *pArray); + + HRESULT ( STDMETHODCALLTYPE *SetDisplaySurface )( + IDXGIOutput * This, + /* [annotation][in] */ + __in IDXGISurface *pScanoutSurface); + + HRESULT ( STDMETHODCALLTYPE *GetDisplaySurfaceData )( + IDXGIOutput * This, + /* [annotation][in] */ + __in IDXGISurface *pDestination); + + HRESULT ( STDMETHODCALLTYPE *GetFrameStatistics )( + IDXGIOutput * This, + /* [annotation][out] */ + __out DXGI_FRAME_STATISTICS *pStats); + + END_INTERFACE + } IDXGIOutputVtbl; + + interface IDXGIOutput + { + CONST_VTBL struct IDXGIOutputVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIOutput_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIOutput_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIOutput_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIOutput_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIOutput_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIOutput_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIOutput_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIOutput_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#define IDXGIOutput_GetDisplayModeList(This,EnumFormat,Flags,pNumModes,pDesc) \ + ( (This)->lpVtbl -> GetDisplayModeList(This,EnumFormat,Flags,pNumModes,pDesc) ) + +#define IDXGIOutput_FindClosestMatchingMode(This,pModeToMatch,pClosestMatch,pConcernedDevice) \ + ( (This)->lpVtbl -> FindClosestMatchingMode(This,pModeToMatch,pClosestMatch,pConcernedDevice) ) + +#define IDXGIOutput_WaitForVBlank(This) \ + ( (This)->lpVtbl -> WaitForVBlank(This) ) + +#define IDXGIOutput_TakeOwnership(This,pDevice,Exclusive) \ + ( (This)->lpVtbl -> TakeOwnership(This,pDevice,Exclusive) ) + +#define IDXGIOutput_ReleaseOwnership(This) \ + ( (This)->lpVtbl -> ReleaseOwnership(This) ) + +#define IDXGIOutput_GetGammaControlCapabilities(This,pGammaCaps) \ + ( (This)->lpVtbl -> GetGammaControlCapabilities(This,pGammaCaps) ) + +#define IDXGIOutput_SetGammaControl(This,pArray) \ + ( (This)->lpVtbl -> SetGammaControl(This,pArray) ) + +#define IDXGIOutput_GetGammaControl(This,pArray) \ + ( (This)->lpVtbl -> GetGammaControl(This,pArray) ) + +#define IDXGIOutput_SetDisplaySurface(This,pScanoutSurface) \ + ( (This)->lpVtbl -> SetDisplaySurface(This,pScanoutSurface) ) + +#define IDXGIOutput_GetDisplaySurfaceData(This,pDestination) \ + ( (This)->lpVtbl -> GetDisplaySurfaceData(This,pDestination) ) + +#define IDXGIOutput_GetFrameStatistics(This,pStats) \ + ( (This)->lpVtbl -> GetFrameStatistics(This,pStats) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIOutput_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0008 */ +/* [local] */ + +#define DXGI_MAX_SWAP_CHAIN_BUFFERS ( 16 ) +#define DXGI_PRESENT_TEST 0x00000001UL +#define DXGI_PRESENT_DO_NOT_SEQUENCE 0x00000002UL +#define DXGI_PRESENT_RESTART 0x00000004UL + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0008_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0008_v0_0_s_ifspec; + +#ifndef __IDXGISwapChain_INTERFACE_DEFINED__ +#define __IDXGISwapChain_INTERFACE_DEFINED__ + +/* interface IDXGISwapChain */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGISwapChain; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("310d36a0-d2e7-4c0a-aa04-6a9d23b8886a") + IDXGISwapChain : public IDXGIDeviceSubObject + { + public: + virtual HRESULT STDMETHODCALLTYPE Present( + /* [in] */ UINT SyncInterval, + /* [in] */ UINT Flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBuffer( + /* [in] */ UINT Buffer, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][out][in] */ + __out void **ppSurface) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFullscreenState( + /* [in] */ BOOL Fullscreen, + /* [annotation][in] */ + __in_opt IDXGIOutput *pTarget) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFullscreenState( + /* [annotation][out] */ + __out BOOL *pFullscreen, + /* [annotation][out] */ + __out IDXGIOutput **ppTarget) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [annotation][out] */ + __out DXGI_SWAP_CHAIN_DESC *pDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE ResizeBuffers( + /* [in] */ UINT BufferCount, + /* [in] */ UINT Width, + /* [in] */ UINT Height, + /* [in] */ DXGI_FORMAT NewFormat, + /* [in] */ UINT SwapChainFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE ResizeTarget( + /* [annotation][in] */ + __in const DXGI_MODE_DESC *pNewTargetParameters) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetContainingOutput( + /* [annotation][out] */ + __out IDXGIOutput **ppOutput) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( + /* [annotation][out] */ + __out DXGI_FRAME_STATISTICS *pStats) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount( + /* [annotation][out] */ + __out UINT *pLastPresentCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGISwapChainVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGISwapChain * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGISwapChain * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGISwapChain * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGISwapChain * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGISwapChain * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGISwapChain * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGISwapChain * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + IDXGISwapChain * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *Present )( + IDXGISwapChain * This, + /* [in] */ UINT SyncInterval, + /* [in] */ UINT Flags); + + HRESULT ( STDMETHODCALLTYPE *GetBuffer )( + IDXGISwapChain * This, + /* [in] */ UINT Buffer, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][out][in] */ + __out void **ppSurface); + + HRESULT ( STDMETHODCALLTYPE *SetFullscreenState )( + IDXGISwapChain * This, + /* [in] */ BOOL Fullscreen, + /* [annotation][in] */ + __in_opt IDXGIOutput *pTarget); + + HRESULT ( STDMETHODCALLTYPE *GetFullscreenState )( + IDXGISwapChain * This, + /* [annotation][out] */ + __out BOOL *pFullscreen, + /* [annotation][out] */ + __out IDXGIOutput **ppTarget); + + HRESULT ( STDMETHODCALLTYPE *GetDesc )( + IDXGISwapChain * This, + /* [annotation][out] */ + __out DXGI_SWAP_CHAIN_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *ResizeBuffers )( + IDXGISwapChain * This, + /* [in] */ UINT BufferCount, + /* [in] */ UINT Width, + /* [in] */ UINT Height, + /* [in] */ DXGI_FORMAT NewFormat, + /* [in] */ UINT SwapChainFlags); + + HRESULT ( STDMETHODCALLTYPE *ResizeTarget )( + IDXGISwapChain * This, + /* [annotation][in] */ + __in const DXGI_MODE_DESC *pNewTargetParameters); + + HRESULT ( STDMETHODCALLTYPE *GetContainingOutput )( + IDXGISwapChain * This, + /* [annotation][out] */ + __out IDXGIOutput **ppOutput); + + HRESULT ( STDMETHODCALLTYPE *GetFrameStatistics )( + IDXGISwapChain * This, + /* [annotation][out] */ + __out DXGI_FRAME_STATISTICS *pStats); + + HRESULT ( STDMETHODCALLTYPE *GetLastPresentCount )( + IDXGISwapChain * This, + /* [annotation][out] */ + __out UINT *pLastPresentCount); + + END_INTERFACE + } IDXGISwapChainVtbl; + + interface IDXGISwapChain + { + CONST_VTBL struct IDXGISwapChainVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGISwapChain_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGISwapChain_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGISwapChain_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGISwapChain_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGISwapChain_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGISwapChain_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGISwapChain_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGISwapChain_GetDevice(This,riid,ppDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppDevice) ) + + +#define IDXGISwapChain_Present(This,SyncInterval,Flags) \ + ( (This)->lpVtbl -> Present(This,SyncInterval,Flags) ) + +#define IDXGISwapChain_GetBuffer(This,Buffer,riid,ppSurface) \ + ( (This)->lpVtbl -> GetBuffer(This,Buffer,riid,ppSurface) ) + +#define IDXGISwapChain_SetFullscreenState(This,Fullscreen,pTarget) \ + ( (This)->lpVtbl -> SetFullscreenState(This,Fullscreen,pTarget) ) + +#define IDXGISwapChain_GetFullscreenState(This,pFullscreen,ppTarget) \ + ( (This)->lpVtbl -> GetFullscreenState(This,pFullscreen,ppTarget) ) + +#define IDXGISwapChain_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#define IDXGISwapChain_ResizeBuffers(This,BufferCount,Width,Height,NewFormat,SwapChainFlags) \ + ( (This)->lpVtbl -> ResizeBuffers(This,BufferCount,Width,Height,NewFormat,SwapChainFlags) ) + +#define IDXGISwapChain_ResizeTarget(This,pNewTargetParameters) \ + ( (This)->lpVtbl -> ResizeTarget(This,pNewTargetParameters) ) + +#define IDXGISwapChain_GetContainingOutput(This,ppOutput) \ + ( (This)->lpVtbl -> GetContainingOutput(This,ppOutput) ) + +#define IDXGISwapChain_GetFrameStatistics(This,pStats) \ + ( (This)->lpVtbl -> GetFrameStatistics(This,pStats) ) + +#define IDXGISwapChain_GetLastPresentCount(This,pLastPresentCount) \ + ( (This)->lpVtbl -> GetLastPresentCount(This,pLastPresentCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGISwapChain_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0009 */ +/* [local] */ + +#define DXGI_MWA_NO_WINDOW_CHANGES ( 1 << 0 ) +#define DXGI_MWA_NO_ALT_ENTER ( 1 << 1 ) +#define DXGI_MWA_NO_PRINT_SCREEN ( 1 << 2 ) +#define DXGI_MWA_VALID ( 0x7 ) + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0009_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0009_v0_0_s_ifspec; + +#ifndef __IDXGIFactory_INTERFACE_DEFINED__ +#define __IDXGIFactory_INTERFACE_DEFINED__ + +/* interface IDXGIFactory */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIFactory; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7b7166ec-21c7-44ae-b21a-c9ae321ae369") + IDXGIFactory : public IDXGIObject + { + public: + virtual HRESULT STDMETHODCALLTYPE EnumAdapters( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) = 0; + + virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation( + HWND WindowHandle, + UINT Flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( + /* [annotation][out] */ + __out HWND *pWindowHandle) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( + /* [annotation][in] */ + __in IUnknown *pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + __out IDXGISwapChain **ppSwapChain) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIFactoryVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIFactory * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIFactory * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIFactory * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIFactory * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIFactory * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIFactory * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIFactory * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *EnumAdapters )( + IDXGIFactory * This, + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter); + + HRESULT ( STDMETHODCALLTYPE *MakeWindowAssociation )( + IDXGIFactory * This, + HWND WindowHandle, + UINT Flags); + + HRESULT ( STDMETHODCALLTYPE *GetWindowAssociation )( + IDXGIFactory * This, + /* [annotation][out] */ + __out HWND *pWindowHandle); + + HRESULT ( STDMETHODCALLTYPE *CreateSwapChain )( + IDXGIFactory * This, + /* [annotation][in] */ + __in IUnknown *pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + __out IDXGISwapChain **ppSwapChain); + + HRESULT ( STDMETHODCALLTYPE *CreateSoftwareAdapter )( + IDXGIFactory * This, + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter); + + END_INTERFACE + } IDXGIFactoryVtbl; + + interface IDXGIFactory + { + CONST_VTBL struct IDXGIFactoryVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIFactory_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIFactory_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIFactory_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIFactory_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIFactory_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIFactory_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIFactory_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIFactory_EnumAdapters(This,Adapter,ppAdapter) \ + ( (This)->lpVtbl -> EnumAdapters(This,Adapter,ppAdapter) ) + +#define IDXGIFactory_MakeWindowAssociation(This,WindowHandle,Flags) \ + ( (This)->lpVtbl -> MakeWindowAssociation(This,WindowHandle,Flags) ) + +#define IDXGIFactory_GetWindowAssociation(This,pWindowHandle) \ + ( (This)->lpVtbl -> GetWindowAssociation(This,pWindowHandle) ) + +#define IDXGIFactory_CreateSwapChain(This,pDevice,pDesc,ppSwapChain) \ + ( (This)->lpVtbl -> CreateSwapChain(This,pDevice,pDesc,ppSwapChain) ) + +#define IDXGIFactory_CreateSoftwareAdapter(This,Module,ppAdapter) \ + ( (This)->lpVtbl -> CreateSoftwareAdapter(This,Module,ppAdapter) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIFactory_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0010 */ +/* [local] */ + +HRESULT WINAPI CreateDXGIFactory(REFIID riid, void **ppFactory); +HRESULT WINAPI CreateDXGIFactory1(REFIID riid, void **ppFactory); + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0010_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0010_v0_0_s_ifspec; + +#ifndef __IDXGIDevice_INTERFACE_DEFINED__ +#define __IDXGIDevice_INTERFACE_DEFINED__ + +/* interface IDXGIDevice */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIDevice; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("54ec77fa-1377-44e6-8c32-88fd5f44c84c") + IDXGIDevice : public IDXGIObject + { + public: + virtual HRESULT STDMETHODCALLTYPE GetAdapter( + /* [annotation][out] */ + __out IDXGIAdapter **pAdapter) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateSurface( + /* [annotation][in] */ + __in const DXGI_SURFACE_DESC *pDesc, + /* [in] */ UINT NumSurfaces, + /* [in] */ DXGI_USAGE Usage, + /* [annotation][in] */ + __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, + /* [annotation][out] */ + __out IDXGISurface **ppSurface) = 0; + + virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( + /* [annotation][size_is][in] */ + __in_ecount(NumResources) IUnknown *const *ppResources, + /* [annotation][size_is][out] */ + __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, + /* [in] */ UINT NumResources) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( + /* [in] */ INT Priority) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( + /* [annotation][retval][out] */ + __out INT *pPriority) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIDeviceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIDevice * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIDevice * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIDevice * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIDevice * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIDevice * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIDevice * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIDevice * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetAdapter )( + IDXGIDevice * This, + /* [annotation][out] */ + __out IDXGIAdapter **pAdapter); + + HRESULT ( STDMETHODCALLTYPE *CreateSurface )( + IDXGIDevice * This, + /* [annotation][in] */ + __in const DXGI_SURFACE_DESC *pDesc, + /* [in] */ UINT NumSurfaces, + /* [in] */ DXGI_USAGE Usage, + /* [annotation][in] */ + __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, + /* [annotation][out] */ + __out IDXGISurface **ppSurface); + + HRESULT ( STDMETHODCALLTYPE *QueryResourceResidency )( + IDXGIDevice * This, + /* [annotation][size_is][in] */ + __in_ecount(NumResources) IUnknown *const *ppResources, + /* [annotation][size_is][out] */ + __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, + /* [in] */ UINT NumResources); + + HRESULT ( STDMETHODCALLTYPE *SetGPUThreadPriority )( + IDXGIDevice * This, + /* [in] */ INT Priority); + + HRESULT ( STDMETHODCALLTYPE *GetGPUThreadPriority )( + IDXGIDevice * This, + /* [annotation][retval][out] */ + __out INT *pPriority); + + END_INTERFACE + } IDXGIDeviceVtbl; + + interface IDXGIDevice + { + CONST_VTBL struct IDXGIDeviceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIDevice_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIDevice_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIDevice_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIDevice_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIDevice_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIDevice_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIDevice_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIDevice_GetAdapter(This,pAdapter) \ + ( (This)->lpVtbl -> GetAdapter(This,pAdapter) ) + +#define IDXGIDevice_CreateSurface(This,pDesc,NumSurfaces,Usage,pSharedResource,ppSurface) \ + ( (This)->lpVtbl -> CreateSurface(This,pDesc,NumSurfaces,Usage,pSharedResource,ppSurface) ) + +#define IDXGIDevice_QueryResourceResidency(This,ppResources,pResidencyStatus,NumResources) \ + ( (This)->lpVtbl -> QueryResourceResidency(This,ppResources,pResidencyStatus,NumResources) ) + +#define IDXGIDevice_SetGPUThreadPriority(This,Priority) \ + ( (This)->lpVtbl -> SetGPUThreadPriority(This,Priority) ) + +#define IDXGIDevice_GetGPUThreadPriority(This,pPriority) \ + ( (This)->lpVtbl -> GetGPUThreadPriority(This,pPriority) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIDevice_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0011 */ +/* [local] */ + +typedef +enum DXGI_ADAPTER_FLAG + { DXGI_ADAPTER_FLAG_NONE = 0, + DXGI_ADAPTER_FLAG_REMOTE = 1, + DXGI_ADAPTER_FLAG_FORCE_DWORD = 0xffffffff + } DXGI_ADAPTER_FLAG; + +typedef struct DXGI_ADAPTER_DESC1 + { + WCHAR Description[ 128 ]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; + UINT Flags; + } DXGI_ADAPTER_DESC1; + +typedef struct DXGI_DISPLAY_COLOR_SPACE + { + FLOAT PrimaryCoordinates[ 8 ][ 2 ]; + FLOAT WhitePoints[ 16 ][ 2 ]; + } DXGI_DISPLAY_COLOR_SPACE; + + + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0011_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0011_v0_0_s_ifspec; + +#ifndef __IDXGIFactory1_INTERFACE_DEFINED__ +#define __IDXGIFactory1_INTERFACE_DEFINED__ + +/* interface IDXGIFactory1 */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIFactory1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("770aae78-f26f-4dba-a829-253c83d1b387") + IDXGIFactory1 : public IDXGIFactory + { + public: + virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter1 **ppAdapter) = 0; + + virtual BOOL STDMETHODCALLTYPE IsCurrent( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIFactory1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIFactory1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIFactory1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIFactory1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIFactory1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIFactory1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIFactory1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIFactory1 * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *EnumAdapters )( + IDXGIFactory1 * This, + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter); + + HRESULT ( STDMETHODCALLTYPE *MakeWindowAssociation )( + IDXGIFactory1 * This, + HWND WindowHandle, + UINT Flags); + + HRESULT ( STDMETHODCALLTYPE *GetWindowAssociation )( + IDXGIFactory1 * This, + /* [annotation][out] */ + __out HWND *pWindowHandle); + + HRESULT ( STDMETHODCALLTYPE *CreateSwapChain )( + IDXGIFactory1 * This, + /* [annotation][in] */ + __in IUnknown *pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + __out IDXGISwapChain **ppSwapChain); + + HRESULT ( STDMETHODCALLTYPE *CreateSoftwareAdapter )( + IDXGIFactory1 * This, + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter); + + HRESULT ( STDMETHODCALLTYPE *EnumAdapters1 )( + IDXGIFactory1 * This, + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter1 **ppAdapter); + + BOOL ( STDMETHODCALLTYPE *IsCurrent )( + IDXGIFactory1 * This); + + END_INTERFACE + } IDXGIFactory1Vtbl; + + interface IDXGIFactory1 + { + CONST_VTBL struct IDXGIFactory1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIFactory1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIFactory1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIFactory1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIFactory1_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIFactory1_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIFactory1_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIFactory1_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIFactory1_EnumAdapters(This,Adapter,ppAdapter) \ + ( (This)->lpVtbl -> EnumAdapters(This,Adapter,ppAdapter) ) + +#define IDXGIFactory1_MakeWindowAssociation(This,WindowHandle,Flags) \ + ( (This)->lpVtbl -> MakeWindowAssociation(This,WindowHandle,Flags) ) + +#define IDXGIFactory1_GetWindowAssociation(This,pWindowHandle) \ + ( (This)->lpVtbl -> GetWindowAssociation(This,pWindowHandle) ) + +#define IDXGIFactory1_CreateSwapChain(This,pDevice,pDesc,ppSwapChain) \ + ( (This)->lpVtbl -> CreateSwapChain(This,pDevice,pDesc,ppSwapChain) ) + +#define IDXGIFactory1_CreateSoftwareAdapter(This,Module,ppAdapter) \ + ( (This)->lpVtbl -> CreateSoftwareAdapter(This,Module,ppAdapter) ) + + +#define IDXGIFactory1_EnumAdapters1(This,Adapter,ppAdapter) \ + ( (This)->lpVtbl -> EnumAdapters1(This,Adapter,ppAdapter) ) + +#define IDXGIFactory1_IsCurrent(This) \ + ( (This)->lpVtbl -> IsCurrent(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIFactory1_INTERFACE_DEFINED__ */ + + +#ifndef __IDXGIAdapter1_INTERFACE_DEFINED__ +#define __IDXGIAdapter1_INTERFACE_DEFINED__ + +/* interface IDXGIAdapter1 */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIAdapter1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("29038f61-3839-4626-91fd-086879011a05") + IDXGIAdapter1 : public IDXGIAdapter + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDesc1( + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC1 *pDesc) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIAdapter1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIAdapter1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIAdapter1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIAdapter1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIAdapter1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIAdapter1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIAdapter1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIAdapter1 * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *EnumOutputs )( + IDXGIAdapter1 * This, + /* [in] */ UINT Output, + /* [annotation][out][in] */ + __out IDXGIOutput **ppOutput); + + HRESULT ( STDMETHODCALLTYPE *GetDesc )( + IDXGIAdapter1 * This, + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *CheckInterfaceSupport )( + IDXGIAdapter1 * This, + /* [annotation][in] */ + __in REFGUID InterfaceName, + /* [annotation][out] */ + __out LARGE_INTEGER *pUMDVersion); + + HRESULT ( STDMETHODCALLTYPE *GetDesc1 )( + IDXGIAdapter1 * This, + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC1 *pDesc); + + END_INTERFACE + } IDXGIAdapter1Vtbl; + + interface IDXGIAdapter1 + { + CONST_VTBL struct IDXGIAdapter1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIAdapter1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIAdapter1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIAdapter1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIAdapter1_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIAdapter1_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIAdapter1_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIAdapter1_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIAdapter1_EnumOutputs(This,Output,ppOutput) \ + ( (This)->lpVtbl -> EnumOutputs(This,Output,ppOutput) ) + +#define IDXGIAdapter1_GetDesc(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc(This,pDesc) ) + +#define IDXGIAdapter1_CheckInterfaceSupport(This,InterfaceName,pUMDVersion) \ + ( (This)->lpVtbl -> CheckInterfaceSupport(This,InterfaceName,pUMDVersion) ) + + +#define IDXGIAdapter1_GetDesc1(This,pDesc) \ + ( (This)->lpVtbl -> GetDesc1(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIAdapter1_INTERFACE_DEFINED__ */ + + +#ifndef __IDXGIDevice1_INTERFACE_DEFINED__ +#define __IDXGIDevice1_INTERFACE_DEFINED__ + +/* interface IDXGIDevice1 */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_IDXGIDevice1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("77db970f-6276-48ba-ba28-070143b4392c") + IDXGIDevice1 : public IDXGIDevice + { + public: + virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( + /* [in] */ UINT MaxLatency) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( + /* [annotation][out] */ + __out UINT *pMaxLatency) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDXGIDevice1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIDevice1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIDevice1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIDevice1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIDevice1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + __in_bcount(DataSize) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIDevice1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][in] */ + __in const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIDevice1 * This, + /* [annotation][in] */ + __in REFGUID Name, + /* [annotation][out][in] */ + __inout UINT *pDataSize, + /* [annotation][out] */ + __out_bcount(*pDataSize) void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIDevice1 * This, + /* [annotation][in] */ + __in REFIID riid, + /* [annotation][retval][out] */ + __out void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetAdapter )( + IDXGIDevice1 * This, + /* [annotation][out] */ + __out IDXGIAdapter **pAdapter); + + HRESULT ( STDMETHODCALLTYPE *CreateSurface )( + IDXGIDevice1 * This, + /* [annotation][in] */ + __in const DXGI_SURFACE_DESC *pDesc, + /* [in] */ UINT NumSurfaces, + /* [in] */ DXGI_USAGE Usage, + /* [annotation][in] */ + __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, + /* [annotation][out] */ + __out IDXGISurface **ppSurface); + + HRESULT ( STDMETHODCALLTYPE *QueryResourceResidency )( + IDXGIDevice1 * This, + /* [annotation][size_is][in] */ + __in_ecount(NumResources) IUnknown *const *ppResources, + /* [annotation][size_is][out] */ + __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, + /* [in] */ UINT NumResources); + + HRESULT ( STDMETHODCALLTYPE *SetGPUThreadPriority )( + IDXGIDevice1 * This, + /* [in] */ INT Priority); + + HRESULT ( STDMETHODCALLTYPE *GetGPUThreadPriority )( + IDXGIDevice1 * This, + /* [annotation][retval][out] */ + __out INT *pPriority); + + HRESULT ( STDMETHODCALLTYPE *SetMaximumFrameLatency )( + IDXGIDevice1 * This, + /* [in] */ UINT MaxLatency); + + HRESULT ( STDMETHODCALLTYPE *GetMaximumFrameLatency )( + IDXGIDevice1 * This, + /* [annotation][out] */ + __out UINT *pMaxLatency); + + END_INTERFACE + } IDXGIDevice1Vtbl; + + interface IDXGIDevice1 + { + CONST_VTBL struct IDXGIDevice1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDXGIDevice1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIDevice1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIDevice1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIDevice1_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIDevice1_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIDevice1_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIDevice1_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIDevice1_GetAdapter(This,pAdapter) \ + ( (This)->lpVtbl -> GetAdapter(This,pAdapter) ) + +#define IDXGIDevice1_CreateSurface(This,pDesc,NumSurfaces,Usage,pSharedResource,ppSurface) \ + ( (This)->lpVtbl -> CreateSurface(This,pDesc,NumSurfaces,Usage,pSharedResource,ppSurface) ) + +#define IDXGIDevice1_QueryResourceResidency(This,ppResources,pResidencyStatus,NumResources) \ + ( (This)->lpVtbl -> QueryResourceResidency(This,ppResources,pResidencyStatus,NumResources) ) + +#define IDXGIDevice1_SetGPUThreadPriority(This,Priority) \ + ( (This)->lpVtbl -> SetGPUThreadPriority(This,Priority) ) + +#define IDXGIDevice1_GetGPUThreadPriority(This,pPriority) \ + ( (This)->lpVtbl -> GetGPUThreadPriority(This,pPriority) ) + + +#define IDXGIDevice1_SetMaximumFrameLatency(This,MaxLatency) \ + ( (This)->lpVtbl -> SetMaximumFrameLatency(This,MaxLatency) ) + +#define IDXGIDevice1_GetMaximumFrameLatency(This,pMaxLatency) \ + ( (This)->lpVtbl -> GetMaximumFrameLatency(This,pMaxLatency) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDXGIDevice1_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dxgi_0000_0014 */ +/* [local] */ + +#ifdef __cplusplus +#endif /*__cplusplus*/ +DEFINE_GUID(IID_IDXGIObject,0xaec22fb8,0x76f3,0x4639,0x9b,0xe0,0x28,0xeb,0x43,0xa6,0x7a,0x2e); +DEFINE_GUID(IID_IDXGIDeviceSubObject,0x3d3e0379,0xf9de,0x4d58,0xbb,0x6c,0x18,0xd6,0x29,0x92,0xf1,0xa6); +DEFINE_GUID(IID_IDXGIResource,0x035f3ab4,0x482e,0x4e50,0xb4,0x1f,0x8a,0x7f,0x8b,0xd8,0x96,0x0b); +DEFINE_GUID(IID_IDXGIKeyedMutex,0x9d8e1289,0xd7b3,0x465f,0x81,0x26,0x25,0x0e,0x34,0x9a,0xf8,0x5d); +DEFINE_GUID(IID_IDXGISurface,0xcafcb56c,0x6ac3,0x4889,0xbf,0x47,0x9e,0x23,0xbb,0xd2,0x60,0xec); +DEFINE_GUID(IID_IDXGISurface1,0x4AE63092,0x6327,0x4c1b,0x80,0xAE,0xBF,0xE1,0x2E,0xA3,0x2B,0x86); +DEFINE_GUID(IID_IDXGIAdapter,0x2411e7e1,0x12ac,0x4ccf,0xbd,0x14,0x97,0x98,0xe8,0x53,0x4d,0xc0); +DEFINE_GUID(IID_IDXGIOutput,0xae02eedb,0xc735,0x4690,0x8d,0x52,0x5a,0x8d,0xc2,0x02,0x13,0xaa); +DEFINE_GUID(IID_IDXGISwapChain,0x310d36a0,0xd2e7,0x4c0a,0xaa,0x04,0x6a,0x9d,0x23,0xb8,0x88,0x6a); +DEFINE_GUID(IID_IDXGIFactory,0x7b7166ec,0x21c7,0x44ae,0xb2,0x1a,0xc9,0xae,0x32,0x1a,0xe3,0x69); +DEFINE_GUID(IID_IDXGIDevice,0x54ec77fa,0x1377,0x44e6,0x8c,0x32,0x88,0xfd,0x5f,0x44,0xc8,0x4c); +DEFINE_GUID(IID_IDXGIFactory1,0x770aae78,0xf26f,0x4dba,0xa8,0x29,0x25,0x3c,0x83,0xd1,0xb3,0x87); +DEFINE_GUID(IID_IDXGIAdapter1,0x29038f61,0x3839,0x4626,0x91,0xfd,0x08,0x68,0x79,0x01,0x1a,0x05); +DEFINE_GUID(IID_IDXGIDevice1,0x77db970f,0x6276,0x48ba,0xba,0x28,0x07,0x01,0x43,0xb4,0x39,0x2c); + + +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0014_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dxgi_0000_0014_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/dxsdk/Include/DXGIFormat.h b/dxsdk/Include/DXGIFormat.h new file mode 100644 index 0000000..e84f7f5 --- /dev/null +++ b/dxsdk/Include/DXGIFormat.h @@ -0,0 +1,112 @@ + +#ifndef __dxgiformat_h__ +#define __dxgiformat_h__ + +#define DXGI_FORMAT_DEFINED 1 + +typedef enum DXGI_FORMAT +{ + DXGI_FORMAT_UNKNOWN = 0, + DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, + DXGI_FORMAT_R32G32B32A32_FLOAT = 2, + DXGI_FORMAT_R32G32B32A32_UINT = 3, + DXGI_FORMAT_R32G32B32A32_SINT = 4, + DXGI_FORMAT_R32G32B32_TYPELESS = 5, + DXGI_FORMAT_R32G32B32_FLOAT = 6, + DXGI_FORMAT_R32G32B32_UINT = 7, + DXGI_FORMAT_R32G32B32_SINT = 8, + DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, + DXGI_FORMAT_R16G16B16A16_FLOAT = 10, + DXGI_FORMAT_R16G16B16A16_UNORM = 11, + DXGI_FORMAT_R16G16B16A16_UINT = 12, + DXGI_FORMAT_R16G16B16A16_SNORM = 13, + DXGI_FORMAT_R16G16B16A16_SINT = 14, + DXGI_FORMAT_R32G32_TYPELESS = 15, + DXGI_FORMAT_R32G32_FLOAT = 16, + DXGI_FORMAT_R32G32_UINT = 17, + DXGI_FORMAT_R32G32_SINT = 18, + DXGI_FORMAT_R32G8X24_TYPELESS = 19, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, + DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, + DXGI_FORMAT_R10G10B10A2_UNORM = 24, + DXGI_FORMAT_R10G10B10A2_UINT = 25, + DXGI_FORMAT_R11G11B10_FLOAT = 26, + DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, + DXGI_FORMAT_R8G8B8A8_UNORM = 28, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, + DXGI_FORMAT_R8G8B8A8_UINT = 30, + DXGI_FORMAT_R8G8B8A8_SNORM = 31, + DXGI_FORMAT_R8G8B8A8_SINT = 32, + DXGI_FORMAT_R16G16_TYPELESS = 33, + DXGI_FORMAT_R16G16_FLOAT = 34, + DXGI_FORMAT_R16G16_UNORM = 35, + DXGI_FORMAT_R16G16_UINT = 36, + DXGI_FORMAT_R16G16_SNORM = 37, + DXGI_FORMAT_R16G16_SINT = 38, + DXGI_FORMAT_R32_TYPELESS = 39, + DXGI_FORMAT_D32_FLOAT = 40, + DXGI_FORMAT_R32_FLOAT = 41, + DXGI_FORMAT_R32_UINT = 42, + DXGI_FORMAT_R32_SINT = 43, + DXGI_FORMAT_R24G8_TYPELESS = 44, + DXGI_FORMAT_D24_UNORM_S8_UINT = 45, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, + DXGI_FORMAT_R8G8_TYPELESS = 48, + DXGI_FORMAT_R8G8_UNORM = 49, + DXGI_FORMAT_R8G8_UINT = 50, + DXGI_FORMAT_R8G8_SNORM = 51, + DXGI_FORMAT_R8G8_SINT = 52, + DXGI_FORMAT_R16_TYPELESS = 53, + DXGI_FORMAT_R16_FLOAT = 54, + DXGI_FORMAT_D16_UNORM = 55, + DXGI_FORMAT_R16_UNORM = 56, + DXGI_FORMAT_R16_UINT = 57, + DXGI_FORMAT_R16_SNORM = 58, + DXGI_FORMAT_R16_SINT = 59, + DXGI_FORMAT_R8_TYPELESS = 60, + DXGI_FORMAT_R8_UNORM = 61, + DXGI_FORMAT_R8_UINT = 62, + DXGI_FORMAT_R8_SNORM = 63, + DXGI_FORMAT_R8_SINT = 64, + DXGI_FORMAT_A8_UNORM = 65, + DXGI_FORMAT_R1_UNORM = 66, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, + DXGI_FORMAT_R8G8_B8G8_UNORM = 68, + DXGI_FORMAT_G8R8_G8B8_UNORM = 69, + DXGI_FORMAT_BC1_TYPELESS = 70, + DXGI_FORMAT_BC1_UNORM = 71, + DXGI_FORMAT_BC1_UNORM_SRGB = 72, + DXGI_FORMAT_BC2_TYPELESS = 73, + DXGI_FORMAT_BC2_UNORM = 74, + DXGI_FORMAT_BC2_UNORM_SRGB = 75, + DXGI_FORMAT_BC3_TYPELESS = 76, + DXGI_FORMAT_BC3_UNORM = 77, + DXGI_FORMAT_BC3_UNORM_SRGB = 78, + DXGI_FORMAT_BC4_TYPELESS = 79, + DXGI_FORMAT_BC4_UNORM = 80, + DXGI_FORMAT_BC4_SNORM = 81, + DXGI_FORMAT_BC5_TYPELESS = 82, + DXGI_FORMAT_BC5_UNORM = 83, + DXGI_FORMAT_BC5_SNORM = 84, + DXGI_FORMAT_B5G6R5_UNORM = 85, + DXGI_FORMAT_B5G5R5A1_UNORM = 86, + DXGI_FORMAT_B8G8R8A8_UNORM = 87, + DXGI_FORMAT_B8G8R8X8_UNORM = 88, + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, + DXGI_FORMAT_BC6H_TYPELESS = 94, + DXGI_FORMAT_BC6H_UF16 = 95, + DXGI_FORMAT_BC6H_SF16 = 96, + DXGI_FORMAT_BC7_TYPELESS = 97, + DXGI_FORMAT_BC7_UNORM = 98, + DXGI_FORMAT_BC7_UNORM_SRGB = 99, + DXGI_FORMAT_FORCE_UINT = 0xffffffff +} DXGI_FORMAT; + +#endif // __dxgiformat_h__ diff --git a/dxsdk/Include/DXGIType.h b/dxsdk/Include/DXGIType.h new file mode 100644 index 0000000..89dd86a --- /dev/null +++ b/dxsdk/Include/DXGIType.h @@ -0,0 +1,123 @@ + +#ifndef __dxgitype_h__ +#define __dxgitype_h__ + + +#include "dxgiformat.h" + +#define _FACDXGI 0x87a +#define MAKE_DXGI_HRESULT(code) MAKE_HRESULT(1, _FACDXGI, code) +#define MAKE_DXGI_STATUS(code) MAKE_HRESULT(0, _FACDXGI, code) + +#define DXGI_STATUS_OCCLUDED MAKE_DXGI_STATUS(1) +#define DXGI_STATUS_CLIPPED MAKE_DXGI_STATUS(2) +#define DXGI_STATUS_NO_REDIRECTION MAKE_DXGI_STATUS(4) +#define DXGI_STATUS_NO_DESKTOP_ACCESS MAKE_DXGI_STATUS(5) +#define DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE MAKE_DXGI_STATUS(6) +#define DXGI_STATUS_MODE_CHANGED MAKE_DXGI_STATUS(7) +#define DXGI_STATUS_MODE_CHANGE_IN_PROGRESS MAKE_DXGI_STATUS(8) + + +#define DXGI_ERROR_INVALID_CALL MAKE_DXGI_HRESULT(1) +#define DXGI_ERROR_NOT_FOUND MAKE_DXGI_HRESULT(2) +#define DXGI_ERROR_MORE_DATA MAKE_DXGI_HRESULT(3) +#define DXGI_ERROR_UNSUPPORTED MAKE_DXGI_HRESULT(4) +#define DXGI_ERROR_DEVICE_REMOVED MAKE_DXGI_HRESULT(5) +#define DXGI_ERROR_DEVICE_HUNG MAKE_DXGI_HRESULT(6) +#define DXGI_ERROR_DEVICE_RESET MAKE_DXGI_HRESULT(7) +#define DXGI_ERROR_WAS_STILL_DRAWING MAKE_DXGI_HRESULT(10) +#define DXGI_ERROR_FRAME_STATISTICS_DISJOINT MAKE_DXGI_HRESULT(11) +#define DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE MAKE_DXGI_HRESULT(12) +#define DXGI_ERROR_DRIVER_INTERNAL_ERROR MAKE_DXGI_HRESULT(32) +#define DXGI_ERROR_NONEXCLUSIVE MAKE_DXGI_HRESULT(33) +#define DXGI_ERROR_NOT_CURRENTLY_AVAILABLE MAKE_DXGI_HRESULT(34) +#define DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED MAKE_DXGI_HRESULT(35) +#define DXGI_ERROR_REMOTE_OUTOFMEMORY MAKE_DXGI_HRESULT(36) + + + +#define DXGI_CPU_ACCESS_NONE ( 0 ) +#define DXGI_CPU_ACCESS_DYNAMIC ( 1 ) +#define DXGI_CPU_ACCESS_READ_WRITE ( 2 ) +#define DXGI_CPU_ACCESS_SCRATCH ( 3 ) +#define DXGI_CPU_ACCESS_FIELD 15 + +#define DXGI_USAGE_SHADER_INPUT ( 1L << (0 + 4) ) +#define DXGI_USAGE_RENDER_TARGET_OUTPUT ( 1L << (1 + 4) ) +#define DXGI_USAGE_BACK_BUFFER ( 1L << (2 + 4) ) +#define DXGI_USAGE_SHARED ( 1L << (3 + 4) ) +#define DXGI_USAGE_READ_ONLY ( 1L << (4 + 4) ) +#define DXGI_USAGE_DISCARD_ON_PRESENT ( 1L << (5 + 4) ) +#define DXGI_USAGE_UNORDERED_ACCESS ( 1L << (6 + 4) ) + +typedef struct DXGI_RGB +{ + float Red; + float Green; + float Blue; +} DXGI_RGB; + +typedef struct DXGI_GAMMA_CONTROL +{ + DXGI_RGB Scale; + DXGI_RGB Offset; + DXGI_RGB GammaCurve[ 1025 ]; +} DXGI_GAMMA_CONTROL; + +typedef struct DXGI_GAMMA_CONTROL_CAPABILITIES +{ + BOOL ScaleAndOffsetSupported; + float MaxConvertedValue; + float MinConvertedValue; + UINT NumGammaControlPoints; + float ControlPointPositions[1025]; +} DXGI_GAMMA_CONTROL_CAPABILITIES; + +typedef struct DXGI_RATIONAL +{ + UINT Numerator; + UINT Denominator; +} DXGI_RATIONAL; + +typedef enum DXGI_MODE_SCANLINE_ORDER +{ + DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED = 0, + DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE = 1, + DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST = 2, + DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST = 3 +} DXGI_MODE_SCANLINE_ORDER; + +typedef enum DXGI_MODE_SCALING +{ + DXGI_MODE_SCALING_UNSPECIFIED = 0, + DXGI_MODE_SCALING_CENTERED = 1, + DXGI_MODE_SCALING_STRETCHED = 2 +} DXGI_MODE_SCALING; + +typedef enum DXGI_MODE_ROTATION +{ + DXGI_MODE_ROTATION_UNSPECIFIED = 0, + DXGI_MODE_ROTATION_IDENTITY = 1, + DXGI_MODE_ROTATION_ROTATE90 = 2, + DXGI_MODE_ROTATION_ROTATE180 = 3, + DXGI_MODE_ROTATION_ROTATE270 = 4 +} DXGI_MODE_ROTATION; + +typedef struct DXGI_MODE_DESC +{ + UINT Width; + UINT Height; + DXGI_RATIONAL RefreshRate; + DXGI_FORMAT Format; + DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; + DXGI_MODE_SCALING Scaling; +} DXGI_MODE_DESC; + +typedef struct DXGI_SAMPLE_DESC +{ + UINT Count; + UINT Quality; +} DXGI_SAMPLE_DESC; + +#endif // __dxgitype_h__ + diff --git a/dxsdk/Include/Dcommon.h b/dxsdk/Include/Dcommon.h new file mode 100644 index 0000000..4ecc5c1 --- /dev/null +++ b/dxsdk/Include/Dcommon.h @@ -0,0 +1,65 @@ +//+-------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Abstract: +// Public API definitions for DWrite and D2D +// +//---------------------------------------------------------------------------- + +#ifndef DCOMMON_H_INCLUDED +#define DCOMMON_H_INCLUDED + +// +//These macros are defined in the Windows 7 SDK, however to enable development using the technical preview, +//they are included here temporarily. +// +#ifndef DEFINE_ENUM_FLAG_OPERATORS +#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \ +extern "C++" { \ +inline ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) | ((int)b)); } \ +inline ENUMTYPE &operator |= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) |= ((int)b)); } \ +inline ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) & ((int)b)); } \ +inline ENUMTYPE &operator &= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) &= ((int)b)); } \ +inline ENUMTYPE operator ~ (ENUMTYPE a) { return ENUMTYPE(~((int)a)); } \ +inline ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) ^ ((int)b)); } \ +inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) ^= ((int)b)); } \ +} +#endif + +#ifndef __field_ecount_opt +#define __field_ecount_opt(x) +#endif + +#ifndef __range +#define __range(x,y) +#endif + +#ifndef __field_ecount +#define __field_ecount(x) +#endif + +/// +/// The measuring method used for text layout. +/// +typedef enum DWRITE_MEASURING_MODE +{ + /// + /// Text is measured using glyph ideal metrics whose values are independent to the current display resolution. + /// + DWRITE_MEASURING_MODE_NATURAL, + + /// + /// Text is measured using glyph display compatible metrics whose values tuned for the current display resolution. + /// + DWRITE_MEASURING_MODE_GDI_CLASSIC, + + /// + /// Text is measured using the same glyph display metrics as text measured by GDI using a font + /// created with CLEARTYPE_NATURAL_QUALITY. + /// + DWRITE_MEASURING_MODE_GDI_NATURAL + +} DWRITE_MEASURING_MODE; + +#endif /* DCOMMON_H_INCLUDED */ diff --git a/dxsdk/Include/DxErr.h b/dxsdk/Include/DxErr.h new file mode 100644 index 0000000..2bd7591 --- /dev/null +++ b/dxsdk/Include/DxErr.h @@ -0,0 +1,99 @@ +/*==========================================================================; + * + * + * File: dxerr.h + * Content: DirectX Error Library Include File + * + ****************************************************************************/ + +#ifndef _DXERR_H_ +#define _DXERR_H_ + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +// +// DXGetErrorString +// +// Desc: Converts a DirectX HRESULT to a string +// +// Args: HRESULT hr Can be any error code from +// XACT XAUDIO2 XAPO XINPUT DXGI D3D10 D3DX10 D3D9 D3DX9 DDRAW DSOUND DINPUT DSHOW +// +// Return: Converted string +// +const char* WINAPI DXGetErrorStringA(__in HRESULT hr); +const WCHAR* WINAPI DXGetErrorStringW(__in HRESULT hr); + +#ifdef UNICODE +#define DXGetErrorString DXGetErrorStringW +#else +#define DXGetErrorString DXGetErrorStringA +#endif + + +// +// DXGetErrorDescription +// +// Desc: Returns a string description of a DirectX HRESULT +// +// Args: HRESULT hr Can be any error code from +// XACT XAUDIO2 XAPO XINPUT DXGI D3D10 D3DX10 D3D9 D3DX9 DDRAW DSOUND DINPUT DSHOW +// +// Return: String description +// +const char* WINAPI DXGetErrorDescriptionA(__in HRESULT hr); +const WCHAR* WINAPI DXGetErrorDescriptionW(__in HRESULT hr); + +#ifdef UNICODE + #define DXGetErrorDescription DXGetErrorDescriptionW +#else + #define DXGetErrorDescription DXGetErrorDescriptionA +#endif + + +// +// DXTrace +// +// Desc: Outputs a formatted error message to the debug stream +// +// Args: CHAR* strFile The current file, typically passed in using the +// __FILE__ macro. +// DWORD dwLine The current line number, typically passed in using the +// __LINE__ macro. +// HRESULT hr An HRESULT that will be traced to the debug stream. +// CHAR* strMsg A string that will be traced to the debug stream (may be NULL) +// BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info. +// +// Return: The hr that was passed in. +// +HRESULT WINAPI DXTraceA( __in_z const char* strFile, __in DWORD dwLine, __in HRESULT hr, __in_z_opt const char* strMsg, __in BOOL bPopMsgBox ); +HRESULT WINAPI DXTraceW( __in_z const char* strFile, __in DWORD dwLine, __in HRESULT hr, __in_z_opt const WCHAR* strMsg, __in BOOL bPopMsgBox ); + +#ifdef UNICODE +#define DXTrace DXTraceW +#else +#define DXTrace DXTraceA +#endif + + +// +// Helper macros +// +#if defined(DEBUG) | defined(_DEBUG) +#define DXTRACE_MSG(str) DXTrace( __FILE__, (DWORD)__LINE__, 0, str, FALSE ) +#define DXTRACE_ERR(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, FALSE ) +#define DXTRACE_ERR_MSGBOX(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, TRUE ) +#else +#define DXTRACE_MSG(str) (0L) +#define DXTRACE_ERR(str,hr) (hr) +#define DXTRACE_ERR_MSGBOX(str,hr) (hr) +#endif + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif // _DXERR_H_ diff --git a/dxsdk/Include/PIXPlugin.h b/dxsdk/Include/PIXPlugin.h new file mode 100644 index 0000000..9c249af --- /dev/null +++ b/dxsdk/Include/PIXPlugin.h @@ -0,0 +1,120 @@ +//================================================================================================== +// PIXPlugin.h +// +// Microsoft PIX Plugin Header +// +// Copyright (c) Microsoft Corporation, All rights reserved +//================================================================================================== + +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + + +//================================================================================================== +// PIX_PLUGIN_SYSTEM_VERSION - Indicates version of the plugin interface the plugin is built with. +//================================================================================================== +#define PIX_PLUGIN_SYSTEM_VERSION 0x101 + + +//================================================================================================== +// PIXCOUNTERID - A unique identifier for each PIX plugin counter. +//================================================================================================== +typedef int PIXCOUNTERID; + + +//================================================================================================== +// PIXCOUNTERDATATYPE - Indicates what type of data the counter produces. +//================================================================================================== +enum PIXCOUNTERDATATYPE +{ + PCDT_RESERVED, + PCDT_FLOAT, + PCDT_INT, + PCDT_INT64, + PCDT_STRING, +}; + + +//================================================================================================== +// PIXPLUGININFO - This structure is filled out by PIXGetPluginInfo and passed back to PIX. +//================================================================================================== +struct PIXPLUGININFO +{ + // Filled in by caller: + HINSTANCE hinst; + + // Filled in by PIXGetPluginInfo: + WCHAR* pstrPluginName; // Name of plugin + int iPluginVersion; // Version of this particular plugin + int iPluginSystemVersion; // Version of PIX's plugin system this plugin was designed for +}; + + +//================================================================================================== +// PIXCOUNTERINFO - This structure is filled out by PIXGetCounterInfo and passed back to PIX +// to allow PIX to determine information about the counters in the plugin. +//================================================================================================== +struct PIXCOUNTERINFO +{ + PIXCOUNTERID counterID; // Used to uniquely ID this counter + WCHAR* pstrName; // String name of the counter + PIXCOUNTERDATATYPE pcdtDataType; // Data type returned by this counter +}; + + +//================================================================================================== +// PIXGetPluginInfo - This returns basic information about this plugin to PIX. +//================================================================================================== +BOOL WINAPI PIXGetPluginInfo( PIXPLUGININFO* pPIXPluginInfo ); + + +//================================================================================================== +// PIXGetCounterInfo - This returns an array of PIXCOUNTERINFO structs to PIX. +// These PIXCOUNTERINFOs allow PIX to enumerate the counters contained +// in this plugin. +//================================================================================================== +BOOL WINAPI PIXGetCounterInfo( DWORD* pdwReturnCounters, PIXCOUNTERINFO** ppCounterInfoList ); + + +//================================================================================================== +// PIXGetCounterDesc - This is called by PIX to request a description of the indicated counter. +//================================================================================================== +BOOL WINAPI PIXGetCounterDesc( PIXCOUNTERID id, WCHAR** ppstrCounterDesc ); + + +//================================================================================================== +// PIXBeginExperiment - This called by PIX once per counter when instrumentation starts. +//================================================================================================== +BOOL WINAPI PIXBeginExperiment( PIXCOUNTERID id, const WCHAR* pstrApplication ); + + +//================================================================================================== +// PIXEndFrame - This is called by PIX once per counter at the end of each frame to gather the +// counter value for that frame. Note that the pointer to the return data must +// continue to point to valid counter data until the next call to PIXEndFrame (or +// PIXEndExperiment) for the same counter. So do not set *ppReturnData to the same +// pointer for multiple counters, or point to a local variable that will go out of +// scope. See the sample PIX plugin for an example of how to structure a plugin +// properly. +//================================================================================================== +BOOL WINAPI PIXEndFrame( PIXCOUNTERID id, UINT iFrame, DWORD* pdwReturnBytes, BYTE** ppReturnData ); + + +//================================================================================================== +// PIXEndExperiment - This is called by PIX once per counter when instrumentation ends. +//================================================================================================== +BOOL WINAPI PIXEndExperiment( PIXCOUNTERID id ); + + +#ifdef __cplusplus +}; +#endif + +//================================================================================================== +// eof: PIXPlugin.h +//================================================================================================== + diff --git a/dxsdk/Include/X3DAudio.h b/dxsdk/Include/X3DAudio.h new file mode 100644 index 0000000..c25d98f --- /dev/null +++ b/dxsdk/Include/X3DAudio.h @@ -0,0 +1,316 @@ +/*-========================================================================-_ + | - X3DAUDIO - | + | Copyright (c) Microsoft Corporation. All rights reserved. | + |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| + |PROJECT: X3DAudio MODEL: Unmanaged User-mode | + |VERSION: 1.7 EXCEPT: No Exceptions | + |CLASS: N / A MINREQ: WinXP, Xbox360 | + |BASE: N / A DIALECT: MSC++ 14.00 | + |>------------------------------------------------------------------------<| + | DUTY: Cross-platform stand-alone 3D audio math library | + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + NOTES: + 1. USE THE DEBUG DLL TO ENABLE PARAMETER VALIDATION VIA ASSERTS! + Here's how: + Copy X3DAudioDX_X.dll to where your application exists. + The debug DLL can be found under %WINDIR%\system32. + Rename X3DAudioDX_X.dll to X3DAudioX_X.dll to use the debug version. + + Only parameters required by DSP settings being calculated as + stipulated by the calculation control flags are validated. + + 2. Definition of terms: + LFE: Low Frequency Effect -- always omnidirectional. + LPF: Low Pass Filter, divided into two classifications: + Direct -- Applied to the direct signal path, + used for obstruction/occlusion effects. + Reverb -- Applied to the reverb signal path, + used for occlusion effects only. + + 3. Volume level is expressed as a linear amplitude scaler: + 1.0f represents no attenuation applied to the original signal, + 0.5f denotes an attenuation of 6dB, and 0.0f results in silence. + Amplification (volume > 1.0f) is also allowed, and is not clamped. + + LPF values range from 1.0f representing all frequencies pass through, + to 0.0f which results in silence as all frequencies are filtered out. + + 4. X3DAudio uses a left-handed Cartesian coordinate system with values + on the x-axis increasing from left to right, on the y-axis from + bottom to top, and on the z-axis from near to far. + Azimuths are measured clockwise from a given reference direction. + + Distance measurement is with respect to user-defined world units. + Applications may provide coordinates using any system of measure + as all non-normalized calculations are scale invariant, with such + operations natively occurring in user-defined world unit space. + Metric constants are supplied only as a convenience. + Distance is calculated using the Euclidean norm formula. + + 5. Only real values are permissible with functions using 32-bit + float parameters -- NAN and infinite values are not accepted. + All computation occurs in 32-bit precision mode. */ + +#pragma once +//---------------------------------------------------// +#include // general windows types +#if defined(_XBOX) + #include +#endif +#include // for D3DVECTOR + +// speaker geometry configuration flags, specifies assignment of channels to speaker positions, defined as per WAVEFORMATEXTENSIBLE.dwChannelMask +#if !defined(_SPEAKER_POSITIONS_) + #define _SPEAKER_POSITIONS_ + #define SPEAKER_FRONT_LEFT 0x00000001 + #define SPEAKER_FRONT_RIGHT 0x00000002 + #define SPEAKER_FRONT_CENTER 0x00000004 + #define SPEAKER_LOW_FREQUENCY 0x00000008 + #define SPEAKER_BACK_LEFT 0x00000010 + #define SPEAKER_BACK_RIGHT 0x00000020 + #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040 + #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080 + #define SPEAKER_BACK_CENTER 0x00000100 + #define SPEAKER_SIDE_LEFT 0x00000200 + #define SPEAKER_SIDE_RIGHT 0x00000400 + #define SPEAKER_TOP_CENTER 0x00000800 + #define SPEAKER_TOP_FRONT_LEFT 0x00001000 + #define SPEAKER_TOP_FRONT_CENTER 0x00002000 + #define SPEAKER_TOP_FRONT_RIGHT 0x00004000 + #define SPEAKER_TOP_BACK_LEFT 0x00008000 + #define SPEAKER_TOP_BACK_CENTER 0x00010000 + #define SPEAKER_TOP_BACK_RIGHT 0x00020000 + #define SPEAKER_RESERVED 0x7FFC0000 // bit mask locations reserved for future use + #define SPEAKER_ALL 0x80000000 // used to specify that any possible permutation of speaker configurations +#endif + +// standard speaker geometry configurations, used with X3DAudioInitialize +#if !defined(SPEAKER_MONO) + #define SPEAKER_MONO SPEAKER_FRONT_CENTER + #define SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) + #define SPEAKER_2POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY) + #define SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER) + #define SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + #define SPEAKER_4POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + #define SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + #define SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER) + #define SPEAKER_5POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) + #define SPEAKER_7POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) +#endif + +// Xbox360 speaker geometry configuration, used with X3DAudioInitialize +#if defined(_XBOX) + #define SPEAKER_XBOX SPEAKER_5POINT1 +#endif + + +// size of instance handle in bytes +#define X3DAUDIO_HANDLE_BYTESIZE 20 + +// float math constants +#define X3DAUDIO_PI 3.141592654f +#define X3DAUDIO_2PI 6.283185307f + +// speed of sound in meters per second for dry air at approximately 20C, used with X3DAudioInitialize +#define X3DAUDIO_SPEED_OF_SOUND 343.5f + +// calculation control flags, used with X3DAudioCalculate +#define X3DAUDIO_CALCULATE_MATRIX 0x00000001 // enable matrix coefficient table calculation +#define X3DAUDIO_CALCULATE_DELAY 0x00000002 // enable delay time array calculation (stereo final mix only) +#define X3DAUDIO_CALCULATE_LPF_DIRECT 0x00000004 // enable LPF direct-path coefficient calculation +#define X3DAUDIO_CALCULATE_LPF_REVERB 0x00000008 // enable LPF reverb-path coefficient calculation +#define X3DAUDIO_CALCULATE_REVERB 0x00000010 // enable reverb send level calculation +#define X3DAUDIO_CALCULATE_DOPPLER 0x00000020 // enable doppler shift factor calculation +#define X3DAUDIO_CALCULATE_EMITTER_ANGLE 0x00000040 // enable emitter-to-listener interior angle calculation + +#define X3DAUDIO_CALCULATE_ZEROCENTER 0x00010000 // do not position to front center speaker, signal positioned to remaining speakers instead, front center destination channel will be zero in returned matrix coefficient table, valid only for matrix calculations with final mix formats that have a front center channel +#define X3DAUDIO_CALCULATE_REDIRECT_TO_LFE 0x00020000 // apply equal mix of all source channels to LFE destination channel, valid only for matrix calculations with sources that have no LFE channel and final mix formats that have an LFE channel + + +//-----------------------------------------------------// +#pragma pack(push, 1) // set packing alignment to ensure consistency across arbitrary build environments + + +// primitive types +typedef float FLOAT32; // 32-bit IEEE float +typedef D3DVECTOR X3DAUDIO_VECTOR; // float 3D vector + +// instance handle of precalculated constants +typedef BYTE X3DAUDIO_HANDLE[X3DAUDIO_HANDLE_BYTESIZE]; + + +// Distance curve point: +// Defines a DSP setting at a given normalized distance. +typedef struct X3DAUDIO_DISTANCE_CURVE_POINT +{ + FLOAT32 Distance; // normalized distance, must be within [0.0f, 1.0f] + FLOAT32 DSPSetting; // DSP setting +} X3DAUDIO_DISTANCE_CURVE_POINT, *LPX3DAUDIO_DISTANCE_CURVE_POINT; + +// Distance curve: +// A piecewise curve made up of linear segments used to +// define DSP behaviour with respect to normalized distance. +// +// Note that curve point distances are normalized within [0.0f, 1.0f]. +// X3DAUDIO_EMITTER.CurveDistanceScaler must be used to scale the +// normalized distances to user-defined world units. +// For distances beyond CurveDistanceScaler * 1.0f, +// pPoints[PointCount-1].DSPSetting is used as the DSP setting. +// +// All distance curve spans must be such that: +// pPoints[k-1].DSPSetting + ((pPoints[k].DSPSetting-pPoints[k-1].DSPSetting) / (pPoints[k].Distance-pPoints[k-1].Distance)) * (pPoints[k].Distance-pPoints[k-1].Distance) != NAN or infinite values +// For all points in the distance curve where 1 <= k < PointCount. +typedef struct X3DAUDIO_DISTANCE_CURVE +{ + X3DAUDIO_DISTANCE_CURVE_POINT* pPoints; // distance curve point array, must have at least PointCount elements with no duplicates and be sorted in ascending order with respect to Distance + UINT32 PointCount; // number of distance curve points, must be >= 2 as all distance curves must have at least two endpoints, defining DSP settings at 0.0f and 1.0f normalized distance +} X3DAUDIO_DISTANCE_CURVE, *LPX3DAUDIO_DISTANCE_CURVE; +static const X3DAUDIO_DISTANCE_CURVE_POINT X3DAudioDefault_LinearCurvePoints[2] = { 0.0f, 1.0f, 1.0f, 0.0f }; +static const X3DAUDIO_DISTANCE_CURVE X3DAudioDefault_LinearCurve = { (X3DAUDIO_DISTANCE_CURVE_POINT*)&X3DAudioDefault_LinearCurvePoints[0], 2 }; + +// Cone: +// Specifies directionality for a listener or single-channel emitter by +// modifying DSP behaviour with respect to its front orientation. +// This is modeled using two sound cones: an inner cone and an outer cone. +// On/within the inner cone, DSP settings are scaled by the inner values. +// On/beyond the outer cone, DSP settings are scaled by the outer values. +// If on both the cones, DSP settings are scaled by the inner values only. +// Between the two cones, the scaler is linearly interpolated between the +// inner and outer values. Set both cone angles to 0 or X3DAUDIO_2PI for +// omnidirectionality using only the outer or inner values respectively. +typedef struct X3DAUDIO_CONE +{ + FLOAT32 InnerAngle; // inner cone angle in radians, must be within [0.0f, X3DAUDIO_2PI] + FLOAT32 OuterAngle; // outer cone angle in radians, must be within [InnerAngle, X3DAUDIO_2PI] + + FLOAT32 InnerVolume; // volume level scaler on/within inner cone, used only for matrix calculations, must be within [0.0f, 2.0f] when used + FLOAT32 OuterVolume; // volume level scaler on/beyond outer cone, used only for matrix calculations, must be within [0.0f, 2.0f] when used + FLOAT32 InnerLPF; // LPF (both direct and reverb paths) coefficient subtrahend on/within inner cone, used only for LPF (both direct and reverb paths) calculations, must be within [0.0f, 1.0f] when used + FLOAT32 OuterLPF; // LPF (both direct and reverb paths) coefficient subtrahend on/beyond outer cone, used only for LPF (both direct and reverb paths) calculations, must be within [0.0f, 1.0f] when used + FLOAT32 InnerReverb; // reverb send level scaler on/within inner cone, used only for reverb calculations, must be within [0.0f, 2.0f] when used + FLOAT32 OuterReverb; // reverb send level scaler on/beyond outer cone, used only for reverb calculations, must be within [0.0f, 2.0f] when used +} X3DAUDIO_CONE, *LPX3DAUDIO_CONE; +static const X3DAUDIO_CONE X3DAudioDefault_DirectionalCone = { X3DAUDIO_PI/2, X3DAUDIO_PI, 1.0f, 0.708f, 0.0f, 0.25f, 0.708f, 1.0f }; + + +// Listener: +// Defines a point of 3D audio reception. +// +// The cone is directed by the listener's front orientation. +typedef struct X3DAUDIO_LISTENER +{ + X3DAUDIO_VECTOR OrientFront; // orientation of front direction, used only for matrix and delay calculations or listeners with cones for matrix, LPF (both direct and reverb paths), and reverb calculations, must be normalized when used + X3DAUDIO_VECTOR OrientTop; // orientation of top direction, used only for matrix and delay calculations, must be orthonormal with OrientFront when used + + X3DAUDIO_VECTOR Position; // position in user-defined world units, does not affect Velocity + X3DAUDIO_VECTOR Velocity; // velocity vector in user-defined world units/second, used only for doppler calculations, does not affect Position + + X3DAUDIO_CONE* pCone; // sound cone, used only for matrix, LPF (both direct and reverb paths), and reverb calculations, NULL specifies omnidirectionality +} X3DAUDIO_LISTENER, *LPX3DAUDIO_LISTENER; + +// Emitter: +// Defines a 3D audio source, divided into two classifications: +// +// Single-point -- For use with single-channel sounds. +// Positioned at the emitter base, i.e. the channel radius +// and azimuth are ignored if the number of channels == 1. +// +// May be omnidirectional or directional using a cone. +// The cone originates from the emitter base position, +// and is directed by the emitter's front orientation. +// +// Multi-point -- For use with multi-channel sounds. +// Each non-LFE channel is positioned using an +// azimuth along the channel radius with respect to the +// front orientation vector in the plane orthogonal to the +// top orientation vector. An azimuth of X3DAUDIO_2PI +// specifies a channel is an LFE. Such channels are +// positioned at the emitter base and are calculated +// with respect to pLFECurve only, never pVolumeCurve. +// +// Multi-point emitters are always omnidirectional, +// i.e. the cone is ignored if the number of channels > 1. +// +// Note that many properties are shared among all channel points, +// locking certain behaviour with respect to the emitter base position. +// For example, doppler shift is always calculated with respect to the +// emitter base position and so is constant for all its channel points. +// Distance curve calculations are also with respect to the emitter base +// position, with the curves being calculated independently of each other. +// For instance, volume and LFE calculations do not affect one another. +typedef struct X3DAUDIO_EMITTER +{ + X3DAUDIO_CONE* pCone; // sound cone, used only with single-channel emitters for matrix, LPF (both direct and reverb paths), and reverb calculations, NULL specifies omnidirectionality + X3DAUDIO_VECTOR OrientFront; // orientation of front direction, used only for emitter angle calculations or with multi-channel emitters for matrix calculations or single-channel emitters with cones for matrix, LPF (both direct and reverb paths), and reverb calculations, must be normalized when used + X3DAUDIO_VECTOR OrientTop; // orientation of top direction, used only with multi-channel emitters for matrix calculations, must be orthonormal with OrientFront when used + + X3DAUDIO_VECTOR Position; // position in user-defined world units, does not affect Velocity + X3DAUDIO_VECTOR Velocity; // velocity vector in user-defined world units/second, used only for doppler calculations, does not affect Position + + FLOAT32 InnerRadius; // inner radius, must be within [0.0f, FLT_MAX] + FLOAT32 InnerRadiusAngle; // inner radius angle, must be within [0.0f, X3DAUDIO_PI/4.0) + + UINT32 ChannelCount; // number of sound channels, must be > 0 + FLOAT32 ChannelRadius; // channel radius, used only with multi-channel emitters for matrix calculations, must be >= 0.0f when used + FLOAT32* pChannelAzimuths; // channel azimuth array, used only with multi-channel emitters for matrix calculations, contains positions of each channel expressed in radians along the channel radius with respect to the front orientation vector in the plane orthogonal to the top orientation vector, or X3DAUDIO_2PI to specify an LFE channel, must have at least ChannelCount elements, all within [0.0f, X3DAUDIO_2PI] when used + + X3DAUDIO_DISTANCE_CURVE* pVolumeCurve; // volume level distance curve, used only for matrix calculations, NULL specifies a default curve that conforms to the inverse square law, calculated in user-defined world units with distances <= CurveDistanceScaler clamped to no attenuation + X3DAUDIO_DISTANCE_CURVE* pLFECurve; // LFE level distance curve, used only for matrix calculations, NULL specifies a default curve that conforms to the inverse square law, calculated in user-defined world units with distances <= CurveDistanceScaler clamped to no attenuation + X3DAUDIO_DISTANCE_CURVE* pLPFDirectCurve; // LPF direct-path coefficient distance curve, used only for LPF direct-path calculations, NULL specifies the default curve: [0.0f,1.0f], [1.0f,0.75f] + X3DAUDIO_DISTANCE_CURVE* pLPFReverbCurve; // LPF reverb-path coefficient distance curve, used only for LPF reverb-path calculations, NULL specifies the default curve: [0.0f,0.75f], [1.0f,0.75f] + X3DAUDIO_DISTANCE_CURVE* pReverbCurve; // reverb send level distance curve, used only for reverb calculations, NULL specifies the default curve: [0.0f,1.0f], [1.0f,0.0f] + + FLOAT32 CurveDistanceScaler; // curve distance scaler, used to scale normalized distance curves to user-defined world units and/or exaggerate their effect, used only for matrix, LPF (both direct and reverb paths), and reverb calculations, must be within [FLT_MIN, FLT_MAX] when used + FLOAT32 DopplerScaler; // doppler shift scaler, used to exaggerate doppler shift effect, used only for doppler calculations, must be within [0.0f, FLT_MAX] when used +} X3DAUDIO_EMITTER, *LPX3DAUDIO_EMITTER; + + +// DSP settings: +// Receives results from a call to X3DAudioCalculate to be sent +// to the low-level audio rendering API for 3D signal processing. +// +// The user is responsible for allocating the matrix coefficient table, +// delay time array, and initializing the channel counts when used. +typedef struct X3DAUDIO_DSP_SETTINGS +{ + FLOAT32* pMatrixCoefficients; // [inout] matrix coefficient table, receives an array representing the volume level used to send from source channel S to destination channel D, stored as pMatrixCoefficients[SrcChannelCount * D + S], must have at least SrcChannelCount*DstChannelCount elements + FLOAT32* pDelayTimes; // [inout] delay time array, receives delays for each destination channel in milliseconds, must have at least DstChannelCount elements (stereo final mix only) + UINT32 SrcChannelCount; // [in] number of source channels, must equal number of channels in respective emitter + UINT32 DstChannelCount; // [in] number of destination channels, must equal number of channels of the final mix + + FLOAT32 LPFDirectCoefficient; // [out] LPF direct-path coefficient + FLOAT32 LPFReverbCoefficient; // [out] LPF reverb-path coefficient + FLOAT32 ReverbLevel; // [out] reverb send level + FLOAT32 DopplerFactor; // [out] doppler shift factor, scales resampler ratio for doppler shift effect, where the effective frequency = DopplerFactor * original frequency + FLOAT32 EmitterToListenerAngle; // [out] emitter-to-listener interior angle, expressed in radians with respect to the emitter's front orientation + + FLOAT32 EmitterToListenerDistance; // [out] distance in user-defined world units from the emitter base to listener position, always calculated + FLOAT32 EmitterVelocityComponent; // [out] component of emitter velocity vector projected onto emitter->listener vector in user-defined world units/second, calculated only for doppler + FLOAT32 ListenerVelocityComponent; // [out] component of listener velocity vector projected onto emitter->listener vector in user-defined world units/second, calculated only for doppler +} X3DAUDIO_DSP_SETTINGS, *LPX3DAUDIO_DSP_SETTINGS; + + +//-------------------------------------------------------------// +// function storage-class attribute and calltype +#if defined(_XBOX) || defined(X3DAUDIOSTATIC) + #define X3DAUDIO_API_(type) EXTERN_C type STDAPIVCALLTYPE +#else + #if defined(X3DEXPORT) + #define X3DAUDIO_API_(type) EXTERN_C __declspec(dllexport) type STDAPIVCALLTYPE + #else + #define X3DAUDIO_API_(type) EXTERN_C __declspec(dllimport) type STDAPIVCALLTYPE + #endif +#endif +#define X3DAUDIO_IMP_(type) type STDMETHODVCALLTYPE + + +//-------------------------------------------------------// +// initializes instance handle +X3DAUDIO_API_(void) X3DAudioInitialize (UINT32 SpeakerChannelMask, FLOAT32 SpeedOfSound, __out X3DAUDIO_HANDLE Instance); + +// calculates DSP settings with respect to 3D parameters +X3DAUDIO_API_(void) X3DAudioCalculate (__in const X3DAUDIO_HANDLE Instance, __in const X3DAUDIO_LISTENER* pListener, __in const X3DAUDIO_EMITTER* pEmitter, UINT32 Flags, __inout X3DAUDIO_DSP_SETTINGS* pDSPSettings); + + +#pragma pack(pop) // revert packing alignment +//---------------------------------<-EOF->----------------------------------// diff --git a/dxsdk/Include/XAPO.h b/dxsdk/Include/XAPO.h new file mode 100644 index 0000000..17947d6 --- /dev/null +++ b/dxsdk/Include/XAPO.h @@ -0,0 +1,645 @@ +/*-========================================================================-_ + | - XAPO - | + | Copyright (c) Microsoft Corporation. All rights reserved. | + |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| + |PROJECT: XAPO MODEL: Unmanaged User-mode | + |VERSION: 1.0 EXCEPT: No Exceptions | + |CLASS: N / A MINREQ: WinXP, Xbox360 | + |BASE: N / A DIALECT: MSC++ 14.00 | + |>------------------------------------------------------------------------<| + | DUTY: Cross-platform Audio Processing Object interfaces | + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + NOTES: + 1. Definition of terms: + DSP: Digital Signal Processing. + + CBR: Constant BitRate -- DSP that consumes a constant number of + input samples to produce an output sample. + For example, a 22kHz to 44kHz resampler is CBR DSP. + Even though the number of input to output samples differ, + the ratio between input to output rate remains constant. + All user-defined XAPOs are assumed to be CBR as + XAudio2 only allows CBR DSP to be added to an effect chain. + + XAPO: Cross-platform Audio Processing Object -- + a thin wrapper that manages DSP code, allowing it + to be easily plugged into an XAudio2 effect chain. + + Frame: A block of samples, one per channel, + to be played simultaneously. + + In-Place: Processing such that the input buffer equals the + output buffer (i.e. input data modified directly). + This form of processing is generally more efficient + than using separate memory for input and output. + However, an XAPO may not perform format conversion + when processing in-place. + + 2. XAPO member variables are divided into three classifications: + Immutable: Set once via IXAPO::Initialize and remain + constant during the lifespan of the XAPO. + + Locked: May change before the XAPO is locked via + IXAPO::LockForProcess but remain constant + until IXAPO::UnlockForProcess is called. + + Dynamic: May change from one processing pass to the next, + usually via IXAPOParameters::SetParameters. + XAPOs should assign reasonable defaults to their dynamic + variables during IXAPO::Initialize/LockForProcess so + that calling IXAPOParameters::SetParameters is not + required before processing begins. + + When implementing an XAPO, determine the type of each variable and + initialize them in the appropriate method. Immutable variables are + generally preferable over locked which are preferable over dynamic. + That is, one should strive to minimize XAPO state changes for + best performance, maintainability, and ease of use. + + 3. To minimize glitches, the realtime audio processing thread must + not block. XAPO methods called by the realtime thread are commented + as non-blocking and therefore should not use blocking synchronization, + allocate memory, access the disk, etc. The XAPO interfaces were + designed to allow an effect implementer to move such operations + into other methods called on an application controlled thread. + + 4. Extending functionality is accomplished through the addition of new + COM interfaces. For example, if a new member is added to a parameter + structure, a new interface using the new structure should be added, + leaving the original interface unchanged. + This ensures consistent communication between future versions of + XAudio2 and various versions of XAPOs that may exist in an application. + + 5. All audio data is interleaved in XAudio2. + The default audio format for an effect chain is WAVE_FORMAT_IEEE_FLOAT. + + 6. User-defined XAPOs should assume all input and output buffers are + 16-byte aligned. + + 7. See XAPOBase.h for an XAPO base class which provides a default + implementation for most of the interface methods defined below. */ + +#pragma once +//---------------------------------------------------// +#include "comdecl.h" // for DEFINE_IID + +// XAPO interface IDs +DEFINE_IID(IXAPO, A90BC001, E897, E897, 55, E4, 9E, 47, 00, 00, 00, 00); +DEFINE_IID(IXAPOParameters, A90BC001, E897, E897, 55, E4, 9E, 47, 00, 00, 00, 01); + + +#if !defined(GUID_DEFS_ONLY) // ignore rest if only GUID definitions requested + #if defined(_XBOX) // general windows and COM declarations + #include + #include + #else + #include + #include + #endif + #include "audiodefs.h" // for WAVEFORMATEX etc. + + // XAPO error codes + #define FACILITY_XAPO 0x897 + #define XAPO_E_FORMAT_UNSUPPORTED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_XAPO, 0x01) // requested audio format unsupported + + // supported number of channels (samples per frame) range + #define XAPO_MIN_CHANNELS 1 + #define XAPO_MAX_CHANNELS 64 + + // supported framerate range + #define XAPO_MIN_FRAMERATE 1000 + #define XAPO_MAX_FRAMERATE 200000 + + // unicode string length, including terminator, used with XAPO_REGISTRATION_PROPERTIES + #define XAPO_REGISTRATION_STRING_LENGTH 256 + + + // XAPO property flags, used with XAPO_REGISTRATION_PROPERTIES.Flags: + // Number of channels of input and output buffers must match, + // applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat. + #define XAPO_FLAG_CHANNELS_MUST_MATCH 0x00000001 + + // Framerate of input and output buffers must match, + // applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat. + #define XAPO_FLAG_FRAMERATE_MUST_MATCH 0x00000002 + + // Bit depth of input and output buffers must match, + // applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat. + // Container size of input and output buffers must also match if + // XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat is WAVEFORMATEXTENSIBLE. + #define XAPO_FLAG_BITSPERSAMPLE_MUST_MATCH 0x00000004 + + // Number of input and output buffers must match, + // applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS. + // + // Also, XAPO_REGISTRATION_PROPERTIES.MinInputBufferCount must + // equal XAPO_REGISTRATION_PROPERTIES.MinOutputBufferCount and + // XAPO_REGISTRATION_PROPERTIES.MaxInputBufferCount must equal + // XAPO_REGISTRATION_PROPERTIES.MaxOutputBufferCount when used. + #define XAPO_FLAG_BUFFERCOUNT_MUST_MATCH 0x00000008 + + // XAPO must be run in-place. Use this flag only if your DSP + // implementation cannot process separate input and output buffers. + // If set, the following flags must also be set: + // XAPO_FLAG_CHANNELS_MUST_MATCH + // XAPO_FLAG_FRAMERATE_MUST_MATCH + // XAPO_FLAG_BITSPERSAMPLE_MUST_MATCH + // XAPO_FLAG_BUFFERCOUNT_MUST_MATCH + // XAPO_FLAG_INPLACE_SUPPORTED + // + // Multiple input and output buffers may be used with in-place XAPOs, + // though the input buffer count must equal the output buffer count. + // When multiple input/output buffers are used, the XAPO may assume + // input buffer [N] equals output buffer [N] for in-place processing. + #define XAPO_FLAG_INPLACE_REQUIRED 0x00000020 + + // XAPO may be run in-place. If the XAPO is used in a chain + // such that the requirements for XAPO_FLAG_INPLACE_REQUIRED are met, + // XAudio2 will ensure the XAPO is run in-place. If not met, XAudio2 + // will still run the XAPO albeit with separate input and output buffers. + // + // For example, consider an effect which may be ran in stereo->5.1 mode or + // mono->mono mode. When set to stereo->5.1, it will be run with separate + // input and output buffers as format conversion is not permitted in-place. + // However, if configured to run mono->mono, the same XAPO can be run + // in-place. Thus the same implementation may be conveniently reused + // for various input/output configurations, while taking advantage of + // in-place processing when possible. + #define XAPO_FLAG_INPLACE_SUPPORTED 0x00000010 + + +//-----------------------------------------------------// + #pragma pack(push, 1) // set packing alignment to ensure consistency across arbitrary build environments + + + // XAPO registration properties, describes general XAPO characteristics, used with IXAPO::GetRegistrationProperties + typedef struct XAPO_REGISTRATION_PROPERTIES { + CLSID clsid; // COM class ID, used with CoCreate + WCHAR FriendlyName[XAPO_REGISTRATION_STRING_LENGTH]; // friendly name unicode string + WCHAR CopyrightInfo[XAPO_REGISTRATION_STRING_LENGTH]; // copyright information unicode string + UINT32 MajorVersion; // major version + UINT32 MinorVersion; // minor version + UINT32 Flags; // XAPO property flags, describes supported input/output configuration + UINT32 MinInputBufferCount; // minimum number of input buffers required for processing, can be 0 + UINT32 MaxInputBufferCount; // maximum number of input buffers supported for processing, must be >= MinInputBufferCount + UINT32 MinOutputBufferCount; // minimum number of output buffers required for processing, can be 0, must match MinInputBufferCount when XAPO_FLAG_BUFFERCOUNT_MUST_MATCH used + UINT32 MaxOutputBufferCount; // maximum number of output buffers supported for processing, must be >= MinOutputBufferCount, must match MaxInputBufferCount when XAPO_FLAG_BUFFERCOUNT_MUST_MATCH used + } XAPO_REGISTRATION_PROPERTIES; + + + // LockForProcess buffer parameters: + // Defines buffer parameters that remain constant while an XAPO is locked. + // Used with IXAPO::LockForProcess. + // + // For CBR XAPOs, MaxFrameCount is the only number of frames + // IXAPO::Process would have to handle for the respective buffer. + typedef struct XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS { + const WAVEFORMATEX* pFormat; // buffer audio format + UINT32 MaxFrameCount; // maximum number of frames in respective buffer that IXAPO::Process would have to handle, irrespective of dynamic variable settings, can be 0 + } XAPO_LOCKFORPROCESS_PARAMETERS; + + // Buffer flags: + // Describes assumed content of the respective buffer. + // Used with XAPO_PROCESS_BUFFER_PARAMETERS.BufferFlags. + // + // This meta-data can be used by an XAPO to implement + // optimizations that require knowledge of a buffer's content. + // + // For example, XAPOs that always produce silent output from silent input + // can check the flag on the input buffer to determine if any signal + // processing is necessary. If silent, the XAPO may simply set the flag + // on the output buffer to silent and return, optimizing out the work of + // processing silent data: XAPOs that generate silence for any reason may + // set the buffer's flag accordingly rather than writing out silent + // frames to the buffer itself. + // + // The flags represent what should be assumed is in the respective buffer. + // The flags may not reflect what is actually stored in memory. + typedef enum XAPO_BUFFER_FLAGS { + XAPO_BUFFER_SILENT, // silent data should be assumed, respective memory may be uninitialized + XAPO_BUFFER_VALID, // arbitrary data should be assumed (may or may not be silent frames), respective memory initialized + } XAPO_BUFFER_FLAGS; + + // Process buffer parameters: + // Defines buffer parameters that may change from one + // processing pass to the next. Used with IXAPO::Process. + // + // Note the byte size of the respective buffer must be at least: + // XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount * XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat->nBlockAlign + // + // Although the audio format and maximum size of the respective + // buffer is locked (defined by XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS), + // the actual memory address of the buffer given is permitted to change + // from one processing pass to the next. + // + // For CBR XAPOs, ValidFrameCount is constant while locked and equals + // the respective XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount. + typedef struct XAPO_PROCESS_BUFFER_PARAMETERS { + void* pBuffer; // audio data buffer, must be non-NULL + XAPO_BUFFER_FLAGS BufferFlags; // describes assumed content of pBuffer, does not affect ValidFrameCount + UINT32 ValidFrameCount; // number of frames of valid data, must be within respective [0, XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount], always XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount for CBR/user-defined XAPOs, does not affect BufferFlags + } XAPO_PROCESS_BUFFER_PARAMETERS; + + +//-------------------------------------------------------------// + // Memory allocation macros that allow one module to allocate memory and + // another to free it, by guaranteeing that the same heap manager is used + // regardless of differences between build environments of the two modules. + // + // Used by IXAPO methods that must allocate arbitrary sized structures + // such as WAVEFORMATEX that are subsequently returned to the application. + #if defined(_XBOX) + #define XAPO_ALLOC_ATTRIBUTES MAKE_XALLOC_ATTRIBUTES ( \ + 0, /* ObjectType */ \ + FALSE, /* HeapTracksAttributes */ \ + FALSE, /* MustSucceed */ \ + FALSE, /* FixedSize */ \ + eXALLOCAllocatorId_XAUDIO2, /* AllocatorId */ \ + XALLOC_ALIGNMENT_DEFAULT, /* Alignment */ \ + XALLOC_MEMPROTECT_READWRITE, /* MemoryProtect */ \ + FALSE, /* ZeroInitialize */ \ + XALLOC_MEMTYPE_HEAP /* MemoryType */ \ + ) + #define XAPOAlloc(size) XMemAlloc(size, XAPO_ALLOC_ATTRIBUTES) + #define XAPOFree(p) XMemFree(p, XAPO_ALLOC_ATTRIBUTES) + #else + #define XAPOAlloc(size) CoTaskMemAlloc(size) + #define XAPOFree(p) CoTaskMemFree(p) + #endif + + +//-----------------------------------------------------// + // IXAPO: + // The only mandatory XAPO COM interface -- a thin wrapper that manages + // DSP code, allowing it to be easily plugged into an XAudio2 effect chain. + #undef INTERFACE + #define INTERFACE IXAPO + DECLARE_INTERFACE_(IXAPO, IUnknown) { + //// + // DESCRIPTION: + // Allocates a copy of the registration properties of the XAPO. + // + // PARAMETERS: + // ppRegistrationProperties - [out] receives pointer to copy of registration properties, use XAPOFree to free structure, left untouched on failure + // + // RETURN VALUE: + // COM error code + //// + STDMETHOD(GetRegistrationProperties) (THIS_ __deref_out XAPO_REGISTRATION_PROPERTIES** ppRegistrationProperties) PURE; + + //// + // DESCRIPTION: + // Queries if an input/output configuration is supported. + // + // REMARKS: + // This method allows XAPOs to express dependency of input format + // with respect to output format. + // + // If the input/output format pair configuration is unsupported, + // this method also determines the nearest input format supported. + // Nearest meaning closest bit depth, framerate, and channel count, + // in that order of importance. + // + // The behaviour of this method should remain constant after the + // XAPO has been initialized. + // + // PARAMETERS: + // pOutputFormat - [in] output format known to be supported + // pRequestedInputFormat - [in] input format to examine + // ppSupportedInputFormat - [out] receives pointer to nearest input format supported if not NULL and input/output configuration unsupported, use XAPOFree to free structure, left untouched on any failure except XAPO_E_FORMAT_UNSUPPORTED + // + // RETURN VALUE: + // COM error code, including: + // S_OK - input/output configuration supported, ppSupportedInputFormat left untouched + // XAPO_E_FORMAT_UNSUPPORTED - input/output configuration unsupported, ppSupportedInputFormat receives pointer to nearest input format supported if not NULL + // E_INVALIDARG - either audio format invalid, ppSupportedInputFormat left untouched + //// + STDMETHOD(IsInputFormatSupported) (THIS_ const WAVEFORMATEX* pOutputFormat, const WAVEFORMATEX* pRequestedInputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedInputFormat) PURE; + + //// + // DESCRIPTION: + // Queries if an input/output configuration is supported. + // + // REMARKS: + // This method allows XAPOs to express dependency of output format + // with respect to input format. + // + // If the input/output format pair configuration is unsupported, + // this method also determines the nearest output format supported. + // Nearest meaning closest bit depth, framerate, and channel count, + // in that order of importance. + // + // The behaviour of this method should remain constant after the + // XAPO has been initialized. + // + // PARAMETERS: + // pInputFormat - [in] input format known to be supported + // pRequestedOutputFormat - [in] output format to examine + // ppSupportedOutputFormat - [out] receives pointer to nearest output format supported if not NULL and input/output configuration unsupported, use XAPOFree to free structure, left untouched on any failure except XAPO_E_FORMAT_UNSUPPORTED + // + // RETURN VALUE: + // COM error code, including: + // S_OK - input/output configuration supported, ppSupportedOutputFormat left untouched + // XAPO_E_FORMAT_UNSUPPORTED - input/output configuration unsupported, ppSupportedOutputFormat receives pointer to nearest output format supported if not NULL + // E_INVALIDARG - either audio format invalid, ppSupportedOutputFormat left untouched + //// + STDMETHOD(IsOutputFormatSupported) (THIS_ const WAVEFORMATEX* pInputFormat, const WAVEFORMATEX* pRequestedOutputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedOutputFormat) PURE; + + //// + // DESCRIPTION: + // Performs any effect-specific initialization if required. + // + // REMARKS: + // The contents of pData are defined by the XAPO. + // Immutable variables (constant during the lifespan of the XAPO) + // should be set once via this method. + // Once initialized, an XAPO cannot be initialized again. + // + // An XAPO should be initialized before passing it to XAudio2 + // as part of an effect chain. XAudio2 will not call this method; + // it exists for future content-driven initialization by XACT. + // + // PARAMETERS: + // pData - [in] effect-specific initialization parameters, may be NULL if DataByteSize == 0 + // DataByteSize - [in] size of pData in bytes, may be 0 if DataByteSize is NULL + // + // RETURN VALUE: + // COM error code + //// + STDMETHOD(Initialize) (THIS_ __in_bcount_opt(DataByteSize) const void* pData, UINT32 DataByteSize) PURE; + + //// + // DESCRIPTION: + // Resets variables dependent on frame history. + // + // REMARKS: + // All other variables remain unchanged, including variables set by + // IXAPOParameters::SetParameters. + // + // For example, an effect with delay should zero out its delay line + // during this method, but should not reallocate anything as the + // XAPO remains locked with a constant input/output configuration. + // + // XAudio2 calls this method only if the XAPO is locked. + // This method should not block as it is called from the + // realtime thread. + // + // PARAMETERS: + // void + // + // RETURN VALUE: + // void + //// + STDMETHOD_(void, Reset) (THIS) PURE; + + //// + // DESCRIPTION: + // Locks the XAPO to a specific input/output configuration, + // allowing it to do any final initialization before Process + // is called on the realtime thread. + // + // REMARKS: + // Once locked, the input/output configuration and any other locked + // variables remain constant until UnlockForProcess is called. + // + // XAPOs should assert the input/output configuration is supported + // and that any required effect-specific initialization is complete. + // IsInputFormatSupported, IsOutputFormatSupported, and Initialize + // should be called as necessary before this method is called. + // + // All internal memory buffers required for Process should be + // allocated by the time this method returns successfully + // as Process is non-blocking and should not allocate memory. + // + // Once locked, an XAPO cannot be locked again until + // UnLockForProcess is called. + // + // PARAMETERS: + // InputLockedParameterCount - [in] number of input buffers, must be within [XAPO_REGISTRATION_PROPERTIES.MinInputBufferCount, XAPO_REGISTRATION_PROPERTIES.MaxInputBufferCount] + // pInputLockedParameters - [in] array of input locked buffer parameter structures, may be NULL if InputLockedParameterCount == 0, otherwise must have InputLockedParameterCount elements + // OutputLockedParameterCount - [in] number of output buffers, must be within [XAPO_REGISTRATION_PROPERTIES.MinOutputBufferCount, XAPO_REGISTRATION_PROPERTIES.MaxOutputBufferCount], must match InputLockedParameterCount when XAPO_FLAG_BUFFERCOUNT_MUST_MATCH used + // pOutputLockedParameters - [in] array of output locked buffer parameter structures, may be NULL if OutputLockedParameterCount == 0, otherwise must have OutputLockedParameterCount elements + // + // RETURN VALUE: + // COM error code + //// + STDMETHOD(LockForProcess) (THIS_ UINT32 InputLockedParameterCount, __in_ecount_opt(InputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pInputLockedParameters, UINT32 OutputLockedParameterCount, __in_ecount_opt(OutputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pOutputLockedParameters) PURE; + + //// + // DESCRIPTION: + // Opposite of LockForProcess. Variables allocated during + // LockForProcess should be deallocated by this method. + // + // REMARKS: + // Unlocking an XAPO allows an XAPO instance to be reused with + // different input/output configurations. + // + // PARAMETERS: + // void + // + // RETURN VALUE: + // void + //// + STDMETHOD_(void, UnlockForProcess) (THIS) PURE; + + //// + // DESCRIPTION: + // Runs the XAPO's DSP code on the given input/output buffers. + // + // REMARKS: + // In addition to writing to the output buffers as appropriate, + // an XAPO must set the BufferFlags and ValidFrameCount members + // of all elements in pOutputProcessParameters accordingly. + // + // ppInputProcessParameters will not necessarily be the same as + // ppOutputProcessParameters for in-place processing, rather + // the pBuffer members of each will point to the same memory. + // + // Multiple input/output buffers may be used with in-place XAPOs, + // though the input buffer count must equal the output buffer count. + // When multiple input/output buffers are used with in-place XAPOs, + // the XAPO may assume input buffer [N] equals output buffer [N]. + // + // When IsEnabled is FALSE, the XAPO should process thru. + // Thru processing means an XAPO should not apply its normal + // processing to the given input/output buffers during Process. + // It should instead pass data from input to output with as little + // modification possible. Effects that perform format conversion + // should continue to do so. The effect must ensure transitions + // between normal and thru processing do not introduce + // discontinuities into the signal. + // + // XAudio2 calls this method only if the XAPO is locked. + // This method should not block as it is called from the + // realtime thread. + // + // PARAMETERS: + // InputProcessParameterCount - [in] number of input buffers, matches respective InputLockedParameterCount parameter given to LockForProcess + // pInputProcessParameters - [in] array of input process buffer parameter structures, may be NULL if InputProcessParameterCount == 0, otherwise must have InputProcessParameterCount elements + // OutputProcessParameterCount - [in] number of output buffers, matches respective OutputLockedParameterCount parameter given to LockForProcess + // pOutputProcessParameters - [in/out] array of output process buffer parameter structures, may be NULL if OutputProcessParameterCount == 0, otherwise must have OutputProcessParameterCount elements + // IsEnabled - [in] TRUE to process normally, FALSE to process thru + // + // RETURN VALUE: + // void + //// + STDMETHOD_(void, Process) (THIS_ UINT32 InputProcessParameterCount, __in_ecount_opt(InputProcessParameterCount) const XAPO_PROCESS_BUFFER_PARAMETERS* pInputProcessParameters, UINT32 OutputProcessParameterCount, __inout_ecount_opt(OutputProcessParameterCount) XAPO_PROCESS_BUFFER_PARAMETERS* pOutputProcessParameters, BOOL IsEnabled) PURE; + + //// + // DESCRIPTION: + // Returns the number of input frames required to generate the + // requested number of output frames. + // + // REMARKS: + // XAudio2 may call this method to determine how many input frames + // an XAPO requires. This is constant for locked CBR XAPOs; + // this method need only be called once while an XAPO is locked. + // + // XAudio2 calls this method only if the XAPO is locked. + // This method should not block as it is called from the + // realtime thread. + // + // PARAMETERS: + // OutputFrameCount - [in] requested number of output frames, must be within respective [0, XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount], always XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount for CBR/user-defined XAPOs + // + // RETURN VALUE: + // number of input frames required + //// + STDMETHOD_(UINT32, CalcInputFrames) (THIS_ UINT32 OutputFrameCount) PURE; + + //// + // DESCRIPTION: + // Returns the number of output frames generated for the + // requested number of input frames. + // + // REMARKS: + // XAudio2 may call this method to determine how many output frames + // an XAPO will generate. This is constant for locked CBR XAPOs; + // this method need only be called once while an XAPO is locked. + // + // XAudio2 calls this method only if the XAPO is locked. + // This method should not block as it is called from the + // realtime thread. + // + // PARAMETERS: + // InputFrameCount - [in] requested number of input frames, must be within respective [0, XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount], always XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.MaxFrameCount for CBR/user-defined XAPOs + // + // RETURN VALUE: + // number of output frames generated + //// + STDMETHOD_(UINT32, CalcOutputFrames) (THIS_ UINT32 InputFrameCount) PURE; + }; + + + + // IXAPOParameters: + // Optional XAPO COM interface that allows an XAPO to use + // effect-specific parameters. + #undef INTERFACE + #define INTERFACE IXAPOParameters + DECLARE_INTERFACE_(IXAPOParameters, IUnknown) { + //// + // DESCRIPTION: + // Sets effect-specific parameters. + // + // REMARKS: + // This method may only be called on the realtime thread; + // no synchronization between it and IXAPO::Process is necessary. + // + // This method should not block as it is called from the + // realtime thread. + // + // PARAMETERS: + // pParameters - [in] effect-specific parameter block, must be != NULL + // ParameterByteSize - [in] size of pParameters in bytes, must be > 0 + // + // RETURN VALUE: + // void + //// + STDMETHOD_(void, SetParameters) (THIS_ __in_bcount(ParameterByteSize) const void* pParameters, UINT32 ParameterByteSize) PURE; + + //// + // DESCRIPTION: + // Gets effect-specific parameters. + // + // REMARKS: + // Unlike SetParameters, XAudio2 does not call this method on the + // realtime thread. Thus, the XAPO must protect variables shared + // with SetParameters/Process using appropriate synchronization. + // + // PARAMETERS: + // pParameters - [out] receives effect-specific parameter block, must be != NULL + // ParameterByteSize - [in] size of pParameters in bytes, must be > 0 + // + // RETURN VALUE: + // void + //// + STDMETHOD_(void, GetParameters) (THIS_ __out_bcount(ParameterByteSize) void* pParameters, UINT32 ParameterByteSize) PURE; + }; + + +//-------------------------------------------------------------// + // macros to allow XAPO interfaces to be used in C code + #if !defined(__cplusplus) + // IXAPO + #define IXAPO_QueryInterface(This, riid, ppInterface) \ + ( (This)->lpVtbl->QueryInterface(This, riid, ppInterface) ) + + #define IXAPO_AddRef(This) \ + ( (This)->lpVtbl->AddRef(This) ) + + #define IXAPO_Release(This) \ + ( (This)->lpVtbl->Release(This) ) + + #define IXAPO_GetRegistrationProperties(This, ppRegistrationProperties) \ + ( (This)->lpVtbl->GetRegistrationProperties(This, ppRegistrationProperties) ) + + #define IXAPO_IsInputFormatSupported(This, pOutputFormat, pRequestedInputFormat, ppSupportedInputFormat) \ + ( (This)->lpVtbl->IsInputFormatSupported(This, pOutputFormat, pRequestedInputFormat, ppSupportedInputFormat) ) + + #define IXAPO_IsOutputFormatSupported(This, pInputFormat, pRequestedOutputFormat, ppSupportedOutputFormat) \ + ( (This)->lpVtbl->IsOutputFormatSupported(This, pInputFormat, pRequestedOutputFormat, ppSupportedOutputFormat) ) + + #define IXAPO_Initialize(This, pData, DataByteSize) \ + ( (This)->lpVtbl->Initialize(This, pData, DataByteSize) ) + + #define IXAPO_Reset(This) \ + ( (This)->lpVtbl->Reset(This) ) + + #define IXAPO_LockForProcess(This, InputLockedParameterCount, pInputLockedParameters, OutputLockedParameterCount, pOutputLockedParameters) \ + ( (This)->lpVtbl->LockForProcess(This, InputLockedParameterCount, pInputLockedParameters, OutputLockedParameterCount, pOutputLockedParameters) ) + + #define IXAPO_UnlockForProcess(This) \ + ( (This)->lpVtbl->UnlockForProcess(This) ) + + #define IXAPO_Process(This, InputProcessParameterCount, pInputProcessParameters, OutputProcessParameterCount, pOutputProcessParameters, IsEnabled) \ + ( (This)->lpVtbl->Process(This, InputProcessParameterCount, pInputProcessParameters, OutputProcessParameterCount, pOutputProcessParameters, IsEnabled) ) + + #define IXAPO_CalcInputFrames(This, OutputFrameCount) \ + ( (This)->lpVtbl->CalcInputFrames(This, OutputFrameCount) ) + + #define IXAPO_CalcOutputFrames(This, InputFrameCount) \ + ( (This)->lpVtbl->CalcOutputFrames(This, InputFrameCount) ) + + + // IXAPOParameters + #define IXAPOParameters_QueryInterface(This, riid, ppInterface) \ + ( (This)->lpVtbl->QueryInterface(This, riid, ppInterface) ) + + #define IXAPOParameters_AddRef(This) \ + ( (This)->lpVtbl->AddRef(This) ) + + #define IXAPOParameters_Release(This) \ + ( (This)->lpVtbl->Release(This) ) + + #define IXAPOParameters_SetParameters(This, pParameters, ParameterByteSize) \ + ( (This)->lpVtbl->SetParameters(This, pParameters, ParameterByteSize) ) + + #define IXAPOParameters_GetParameters(This, pParameters, ParameterByteSize) \ + ( (This)->lpVtbl->GetParameters(This, pParameters, ParameterByteSize) ) + #endif // !defined(__cplusplus) + + + #pragma pack(pop) // revert packing alignment +#endif // !defined(GUID_DEFS_ONLY) +//---------------------------------<-EOF->----------------------------------// diff --git a/dxsdk/Include/XAPOBase.h b/dxsdk/Include/XAPOBase.h new file mode 100644 index 0000000..24c5c6f --- /dev/null +++ b/dxsdk/Include/XAPOBase.h @@ -0,0 +1,337 @@ +/*-========================================================================-_ + | - XAPO - | + | Copyright (c) Microsoft Corporation. All rights reserved. | + |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| + |PROJECT: XAPO MODEL: Unmanaged User-mode | + |VERSION: 1.0 EXCEPT: No Exceptions | + |CLASS: N / A MINREQ: WinXP, Xbox360 | + |BASE: N / A DIALECT: MSC++ 14.00 | + |>------------------------------------------------------------------------<| + | DUTY: XAPO base classes | + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + NOTES: + 1. See XAPO.h for the rules governing XAPO interface behaviour. */ + +#pragma once +//---------------------------------------------------// +#include "XAPO.h" + +// default audio format ranges supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat +#define XAPOBASE_DEFAULT_FORMAT_TAG WAVE_FORMAT_IEEE_FLOAT // 32-bit float only, applies to WAVEFORMATEX.wFormatTag or WAVEFORMATEXTENSIBLE.SubFormat when used +#define XAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS XAPO_MIN_CHANNELS // minimum channel count, applies to WAVEFORMATEX.nChannels +#define XAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS XAPO_MAX_CHANNELS // maximum channel count, applies to WAVEFORMATEX.nChannels +#define XAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE XAPO_MIN_FRAMERATE // minimum framerate, applies to WAVEFORMATEX.nSamplesPerSec +#define XAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE XAPO_MAX_FRAMERATE // maximum framerate, applies to WAVEFORMATEX.nSamplesPerSec +#define XAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE 32 // 32-bit float only, applies to WAVEFORMATEX.wBitsPerSample and WAVEFORMATEXTENSIBLE.wValidBitsPerSample when used + +// default XAPO property flags supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS +#define XAPOBASE_DEFAULT_FLAG (XAPO_FLAG_CHANNELS_MUST_MATCH | XAPO_FLAG_FRAMERATE_MUST_MATCH | XAPO_FLAG_BITSPERSAMPLE_MUST_MATCH | XAPO_FLAG_BUFFERCOUNT_MUST_MATCH | XAPO_FLAG_INPLACE_SUPPORTED) + +// default number of input and output buffers supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS +#define XAPOBASE_DEFAULT_BUFFER_COUNT 1 + + +//-------------------------------------------------------------// +// assertion +#if !defined(XAPOASSERT) + #if XAPODEBUG + #define XAPOASSERT(exp) if (!(exp)) { OutputDebugStringA("XAPO ASSERT: " #exp ", {" __FUNCTION__ "}\n"); __debugbreak(); } + #else + #define XAPOASSERT(exp) __assume(exp) + #endif +#endif + + +//-----------------------------------------------------// +#pragma pack(push, 8) // set packing alignment to ensure consistency across arbitrary build environments, and ensure synchronization variables used by Interlocked functionality are correctly aligned + + +// primitive types +typedef float FLOAT32; // 32-bit IEEE float + + + //// + // DESCRIPTION: + // Default implementation of the IXAPO and IUnknown interfaces. + // Provides overridable implementations for all methods save IXAPO::Process. + //// +class __declspec(novtable) CXAPOBase: public IXAPO { +private: + const XAPO_REGISTRATION_PROPERTIES* m_pRegistrationProperties; // pointer to registration properties of the XAPO, set via constructor + + void* m_pfnMatrixMixFunction; // optimal matrix function pointer, used for thru processing + FLOAT32* m_pfl32MatrixCoefficients; // matrix coefficient table, used for thru processing + UINT32 m_nSrcFormatType; // input format type, used for thru processing + BOOL m_fIsScalarMatrix; // TRUE if m_pfl32MatrixCoefficients is diagonal matrix with all main diagonal entries equal, i.e. m_pfnMatrixMixFunction only used for type conversion (no channel conversion), used for thru processing + BOOL m_fIsLocked; // TRUE if XAPO locked via CXAPOBase.LockForProcess + + +protected: + LONG m_lReferenceCount; // COM reference count, must be aligned for atomic operations + + //// + // DESCRIPTION: + // Verifies an audio format falls within the default ranges supported. + // + // REMARKS: + // If pFormat is unsupported, and fOverwrite is TRUE, + // pFormat is overwritten with the nearest format supported. + // Nearest meaning closest bit depth, framerate, and channel count, + // in that order of importance. + // + // PARAMETERS: + // pFormat - [in/out] audio format to examine + // fOverwrite - [in] TRUE to overwrite pFormat if audio format unsupported + // + // RETURN VALUE: + // COM error code, including: + // S_OK - audio format supported, pFormat left untouched + // XAPO_E_FORMAT_UNSUPPORTED - audio format unsupported, pFormat overwritten with nearest audio format supported if fOverwrite TRUE + // E_INVALIDARG - audio format invalid, pFormat left untouched + //// + virtual HRESULT ValidateFormatDefault (__inout WAVEFORMATEX* pFormat, BOOL fOverwrite); + + //// + // DESCRIPTION: + // Verifies that an input/output format pair configuration is supported + // with respect to the XAPO property flags. + // + // REMARKS: + // If pRequestedFormat is unsupported, and fOverwrite is TRUE, + // pRequestedFormat is overwritten with the nearest format supported. + // Nearest meaning closest bit depth, framerate, and channel count, + // in that order of importance. + // + // PARAMETERS: + // pSupportedFormat - [in] audio format known to be supported + // pRequestedFormat - [in/out] audio format to examine, must be WAVEFORMATEXTENSIBLE if fOverwrite TRUE + // fOverwrite - [in] TRUE to overwrite pRequestedFormat if input/output configuration unsupported + // + // RETURN VALUE: + // COM error code, including: + // S_OK - input/output configuration supported, pRequestedFormat left untouched + // XAPO_E_FORMAT_UNSUPPORTED - input/output configuration unsupported, pRequestedFormat overwritten with nearest audio format supported if fOverwrite TRUE + // E_INVALIDARG - either audio format invalid, pRequestedFormat left untouched + //// + HRESULT ValidateFormatPair (const WAVEFORMATEX* pSupportedFormat, __inout WAVEFORMATEX* pRequestedFormat, BOOL fOverwrite); + + //// + // DESCRIPTION: + // This method may be called by an IXAPO::Process implementation + // for thru processing. It copies/mixes data from source to + // destination, making as few changes as possible to the audio data. + // + // REMARKS: + // However, this method is capable of channel upmix/downmix and uses + // the same matrix coefficient table used by windows Vista to do so. + // + // For in-place processing (input buffer == output buffer) + // this method does nothing. + // + // This method should be called only if the XAPO is locked and + // XAPO_FLAG_FRAMERATE_MUST_MATCH is used. + // + // PARAMETERS: + // pInputBuffer - [in] input buffer, format may be INT8, INT16, INT20 (contained in 24 or 32 bits), INT24 (contained in 24 or 32 bits), INT32, or FLOAT32 + // pOutputBuffer - [out] output buffer, format must be FLOAT32 + // FrameCount - [in] number of frames to process + // InputChannelCount - [in] number of input channels + // OutputChannelCount - [in] number of output channels + // MixWithOutput - [in] TRUE to mix with output, FALSE to overwrite output + // + // RETURN VALUE: + // void + //// + void ProcessThru (__in void* pInputBuffer, __inout FLOAT32* pOutputBuffer, UINT32 FrameCount, WORD InputChannelCount, WORD OutputChannelCount, BOOL MixWithOutput); + + // accessors + const XAPO_REGISTRATION_PROPERTIES* GetRegistrationPropertiesInternal () { return m_pRegistrationProperties; } + BOOL IsLocked () { return m_fIsLocked; } + + +public: + CXAPOBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties); + virtual ~CXAPOBase (); + + // IUnknown methods: + // retrieves the requested interface pointer if supported + STDMETHOD(QueryInterface) (REFIID riid, __deref_out_opt void** ppInterface) + { + XAPOASSERT(ppInterface != NULL); + HRESULT hr = S_OK; + + if (riid == __uuidof(IXAPO)) { + *ppInterface = static_cast(this); + AddRef(); + } else if (riid == __uuidof(IUnknown)) { + *ppInterface = static_cast(this); + AddRef(); + } else { + *ppInterface = NULL; + hr = E_NOINTERFACE; + } + + return hr; + } + + // increments reference count + STDMETHOD_(ULONG, AddRef) () + { + return (ULONG)InterlockedIncrement(&m_lReferenceCount); + } + + // decrements reference count and deletes the object if the reference count falls to zero + STDMETHOD_(ULONG, Release) () + { + ULONG uTmpReferenceCount = (ULONG)InterlockedDecrement(&m_lReferenceCount); + if (uTmpReferenceCount == 0) { + delete this; + } + return uTmpReferenceCount; + } + + // IXAPO methods: + // Allocates a copy of the registration properties of the XAPO. + // This default implementation returns a copy of the registration + // properties given to the constructor, allocated via XAPOAlloc. + STDMETHOD(GetRegistrationProperties) (__deref_out XAPO_REGISTRATION_PROPERTIES** ppRegistrationProperties); + + // Queries if a specific input format is supported for a given output format. + // This default implementation assumes only the format described by the + // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output. + STDMETHOD(IsInputFormatSupported) (const WAVEFORMATEX* pOutputFormat, const WAVEFORMATEX* pRequestedInputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedInputFormat); + + // Queries if a specific output format is supported for a given input format. + // This default implementation assumes only the format described by the + // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output. + STDMETHOD(IsOutputFormatSupported) (const WAVEFORMATEX* pInputFormat, const WAVEFORMATEX* pRequestedOutputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedOutputFormat); + + // Performs any effect-specific initialization. + // This default implementation is a no-op and only returns S_OK. + STDMETHOD(Initialize) (__in_bcount_opt(DataByteSize) const void*, UINT32 DataByteSize) + { + UNREFERENCED_PARAMETER(DataByteSize); + return S_OK; + } + + // Resets variables dependent on frame history. + // This default implementation is a no-op: this base class contains no + // relevant state to reset. + STDMETHOD_(void, Reset) () { return; } + + // Notifies XAPO of buffer formats Process() will be given. + // This default implementation performs basic input/output format + // validation against the XAPO's registration properties. + // Derived XAPOs should call the base implementation first. + STDMETHOD(LockForProcess) (UINT32 InputLockedParameterCount, __in_ecount_opt(InputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pInputLockedParameters, UINT32 OutputLockedParameterCount, __in_ecount_opt(OutputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pOutputLockedParameters); + + // Opposite of LockForProcess. + // Derived XAPOs should call the base implementation first. + STDMETHOD_(void, UnlockForProcess) (); + + // Returns the number of input frames required to generate the requested number of output frames. + // By default, this method returns the same number of frames it was passed. + STDMETHOD_(UINT32, CalcInputFrames) (UINT32 OutputFrameCount) { return OutputFrameCount; } + + // Returns the number of output frames generated for the requested number of input frames. + // By default, this method returns the same number of frames it was passed. + STDMETHOD_(UINT32, CalcOutputFrames) (UINT32 InputFrameCount) { return InputFrameCount; } +}; + + + + + +//--------------------------------------------------------------------------// + //// + // DESCRIPTION: + // Extends CXAPOBase, providing a default implementation of the + // IXAPOParameters interface with appropriate synchronization to + // protect variables shared between IXAPOParameters::GetParameters + // and IXAPOParameters::SetParameters/IXAPO::Process. + // + // This class is for parameter blocks whose size is larger than 4 bytes. + // For smaller parameter blocks, use atomic operations directly + // on the parameters for synchronization. + //// +class __declspec(novtable) CXAPOParametersBase: public CXAPOBase, public IXAPOParameters { +private: + BYTE* m_pParameterBlocks; // three contiguous process parameter blocks used for synchronization, user responsible for initialization of parameter blocks before IXAPO::Process/SetParameters/GetParameters called + BYTE* m_pCurrentParameters; // pointer to current process parameters, must be aligned for atomic operations + BYTE* m_pCurrentParametersInternal; // pointer to current process parameters (temp pointer read by SetParameters/BeginProcess/EndProcess) + UINT32 m_uCurrentParametersIndex; // index of current process parameters + UINT32 m_uParameterBlockByteSize; // size of a single parameter block in bytes, must be > 0 + BOOL m_fNewerResultsReady; // TRUE if there exists new processing results not yet picked up by GetParameters(), must be aligned for atomic operations + BOOL m_fProducer; // IXAPO::Process produces data to be returned by GetParameters(); SetParameters() disallowed + + +public: + //// + // PARAMETERS: + // pRegistrationProperties - [in] registration properties of the XAPO + // pParameterBlocks - [in] three contiguous process parameter blocks used for synchronization + // uParameterBlockByteSize - [in] size of one of the parameter blocks, must be > 0 + // fProducer - [in] TRUE if IXAPO::Process produces data to be returned by GetParameters() (SetParameters() and ParametersChanged() disallowed) + //// + CXAPOParametersBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties, BYTE* pParameterBlocks, UINT32 uParameterBlockByteSize, BOOL fProducer); + virtual ~CXAPOParametersBase (); + + // IUnknown methods: + // retrieves the requested interface pointer if supported + STDMETHOD(QueryInterface) (REFIID riid, __deref_out_opt void** ppInterface) + { + XAPOASSERT(ppInterface != NULL); + HRESULT hr = S_OK; + + if (riid == __uuidof(IXAPOParameters)) { + *ppInterface = static_cast(this); + CXAPOBase::AddRef(); + } else { + hr = CXAPOBase::QueryInterface(riid, ppInterface); + } + + return hr; + } + + // increments reference count + STDMETHOD_(ULONG, AddRef)() { return CXAPOBase::AddRef(); } + + // decrements reference count and deletes the object if the reference count falls to zero + STDMETHOD_(ULONG, Release)() { return CXAPOBase::Release(); } + + // IXAPOParameters methods: + // Sets effect-specific parameters. + // This method may only be called on the realtime audio processing thread. + STDMETHOD_(void, SetParameters) (__in_bcount(ParameterByteSize) const void* pParameters, UINT32 ParameterByteSize); + + // Gets effect-specific parameters. + // This method may block and should not be called from the realtime thread. + // Get the current parameters via BeginProcess. + STDMETHOD_(void, GetParameters) (__out_bcount(ParameterByteSize) void* pParameters, UINT32 ParameterByteSize); + + // Called by SetParameters() to allow for user-defined parameter validation. + // SetParameters validates that ParameterByteSize == m_uParameterBlockByteSize + // so the user may assume/assert ParameterByteSize == m_uParameterBlockByteSize. + // This method should not block as it is called from the realtime thread. + virtual void OnSetParameters (const void*, UINT32) { } + + // Returns TRUE if SetParameters() has been called since the last processing pass. + // May only be used within the XAPO's IXAPO::Process implementation, + // before BeginProcess is called. + BOOL ParametersChanged (); + + // Returns latest process parameters. + // XAPOs must call this method within their IXAPO::Process + // implementation to access latest process parameters in threadsafe manner. + BYTE* BeginProcess (); + + // Notifies CXAPOParametersBase that the XAPO has finished accessing + // the latest process parameters. + // XAPOs must call this method within their IXAPO::Process + // implementation to access latest process parameters in threadsafe manner. + void EndProcess (); +}; + + +#pragma pack(pop) // revert packing alignment +//---------------------------------<-EOF->----------------------------------// diff --git a/dxsdk/Include/XAPOFX.h b/dxsdk/Include/XAPOFX.h new file mode 100644 index 0000000..a5dbeef --- /dev/null +++ b/dxsdk/Include/XAPOFX.h @@ -0,0 +1,167 @@ +/*-========================================================================-_ + | - XAPOFX - | + | Copyright (c) Microsoft Corporation. All rights reserved. | + |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| + |PROJECT: XAPOFX MODEL: Unmanaged User-mode | + |VERSION: 1.3 EXCEPT: No Exceptions | + |CLASS: N / A MINREQ: WinXP, Xbox360 | + |BASE: N / A DIALECT: MSC++ 14.00 | + |>------------------------------------------------------------------------<| + | DUTY: Cross-platform Audio Processing Objects | + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + NOTES: + 1. USE THE DEBUG DLL TO ENABLE PARAMETER VALIDATION VIA ASSERTS! + Here's how: + Copy XAPOFXDX_X.dll to where your application exists. + The debug DLL can be found under %WINDIR%\system32. + Rename XAPOFXDX_X.dll to XAPOFXX_X.dll to use the debug version. */ + +#pragma once +//---------------------------------------------------// +#include "comdecl.h" // for DEFINE_CLSID + +// FX class IDs +DEFINE_CLSID(FXEQ, A90BC001, E897, E897, 74, 39, 43, 55, 00, 00, 00, 00); +DEFINE_CLSID(FXMasteringLimiter, A90BC001, E897, E897, 74, 39, 43, 55, 00, 00, 00, 01); +DEFINE_CLSID(FXReverb, A90BC001, E897, E897, 74, 39, 43, 55, 00, 00, 00, 02); +DEFINE_CLSID(FXEcho, A90BC001, E897, E897, 74, 39, 43, 55, 00, 00, 00, 03); + + +#if !defined(GUID_DEFS_ONLY) // ignore rest if only GUID definitions requested + #if defined(_XBOX) // general windows and COM declarations + #include + #include + #else + #include + #include + #endif + #include // float bounds + + + // EQ parameter bounds (inclusive), used with XEQ: + #define FXEQ_MIN_FRAMERATE 22000 + #define FXEQ_MAX_FRAMERATE 48000 + + #define FXEQ_MIN_FREQUENCY_CENTER 20.0f + #define FXEQ_MAX_FREQUENCY_CENTER 20000.0f + #define FXEQ_DEFAULT_FREQUENCY_CENTER_0 100.0f // band 0 + #define FXEQ_DEFAULT_FREQUENCY_CENTER_1 800.0f // band 1 + #define FXEQ_DEFAULT_FREQUENCY_CENTER_2 2000.0f // band 2 + #define FXEQ_DEFAULT_FREQUENCY_CENTER_3 10000.0f // band 3 + + #define FXEQ_MIN_GAIN 0.126f // -18dB + #define FXEQ_MAX_GAIN 7.94f // +18dB + #define FXEQ_DEFAULT_GAIN 1.0f // 0dB change, all bands + + #define FXEQ_MIN_BANDWIDTH 0.1f + #define FXEQ_MAX_BANDWIDTH 2.0f + #define FXEQ_DEFAULT_BANDWIDTH 1.0f // all bands + + + // Mastering limiter parameter bounds (inclusive), used with XMasteringLimiter: + #define FXMASTERINGLIMITER_MIN_RELEASE 1 + #define FXMASTERINGLIMITER_MAX_RELEASE 20 + #define FXMASTERINGLIMITER_DEFAULT_RELEASE 6 + + #define FXMASTERINGLIMITER_MIN_LOUDNESS 1 + #define FXMASTERINGLIMITER_MAX_LOUDNESS 1800 + #define FXMASTERINGLIMITER_DEFAULT_LOUDNESS 1000 + + + // Reverb parameter bounds (inclusive), used with XReverb: + #define FXREVERB_MIN_DIFFUSION 0.0f + #define FXREVERB_MAX_DIFFUSION 1.0f + #define FXREVERB_DEFAULT_DIFFUSION 0.9f + + #define FXREVERB_MIN_ROOMSIZE 0.0001f + #define FXREVERB_MAX_ROOMSIZE 1.0f + #define FXREVERB_DEFAULT_ROOMSIZE 0.6f + + + // Echo parameter bounds (inclusive), used with XEcho: + #define FXECHO_MIN_WETDRYMIX 0.0f + #define FXECHO_MAX_WETDRYMIX 1.0f + #define FXECHO_DEFAULT_WETDRYMIX 0.5f + + #define FXECHO_MIN_FEEDBACK 0.0f + #define FXECHO_MAX_FEEDBACK 1.0f + #define FXECHO_DEFAULT_FEEDBACK 0.5f + + #define FXECHO_MIN_DELAY 1.0f + #define FXECHO_MAX_DELAY 2000.0f + #define FXECHO_DEFAULT_DELAY 500.0f + + +//-----------------------------------------------------// + #pragma pack(push, 1) // set packing alignment to ensure consistency across arbitrary build environments + + + // EQ parameters (4 bands), used with IXAPOParameters::SetParameters: + // The EQ supports only FLOAT32 audio foramts. + // The framerate must be within [22000, 48000] Hz. + typedef struct FXEQ_PARAMETERS { + float FrequencyCenter0; // center frequency in Hz, band 0 + float Gain0; // boost/cut + float Bandwidth0; // bandwidth, region of EQ is center frequency +/- bandwidth/2 + float FrequencyCenter1; // band 1 + float Gain1; + float Bandwidth1; + float FrequencyCenter2; // band 2 + float Gain2; + float Bandwidth2; + float FrequencyCenter3; // band 3 + float Gain3; + float Bandwidth3; + } FXEQ_PARAMETERS; + + + // Mastering limiter parameters, used with IXAPOParameters::SetParameters: + // The mastering limiter supports only FLOAT32 audio formats. + typedef struct FXMASTERINGLIMITER_PARAMETERS { + UINT32 Release; // release time (tuning factor with no specific units) + UINT32 Loudness; // loudness target (threshold) + } FXMASTERINGLIMITER_PARAMETERS; + + + // Reverb parameters, used with IXAPOParameters::SetParameters: + // The reverb supports only FLOAT32 audio formats with the following + // channel configurations: + // Input: Mono Output: Mono + // Input: Stereo Output: Stereo + typedef struct FXREVERB_PARAMETERS { + float Diffusion; // diffusion + float RoomSize; // room size + } FXREVERB_PARAMETERS; + + + // Echo parameters, used with IXAPOParameters::SetParameters: + // The echo supports only FLOAT32 audio formats. + typedef struct FXECHO_PARAMETERS { + float WetDryMix; // ratio of wet (processed) signal to dry (original) signal + float Feedback; // amount of output fed back into input + float Delay; // delay (all channels) in milliseconds + } FXECHO_PARAMETERS; + + +//-------------------------------------------------------------// + // function storage-class attribute and calltype + #if defined(_XBOX) || !defined(FXDLL) + #define FX_API_(type) EXTERN_C type STDAPIVCALLTYPE + #else + #if defined(FXEXPORT) + #define FX_API_(type) EXTERN_C __declspec(dllexport) type STDAPIVCALLTYPE + #else + #define FX_API_(type) EXTERN_C __declspec(dllimport) type STDAPIVCALLTYPE + #endif + #endif + #define FX_IMP_(type) type STDMETHODVCALLTYPE + + +//-------------------------------------------------------// + // creates instance of requested XAPO, use Release to free instance + FX_API_(HRESULT) CreateFX (REFCLSID clsid, __deref_out IUnknown** pEffect); + + + #pragma pack(pop) // revert packing alignment +#endif // !defined(GUID_DEFS_ONLY) +//---------------------------------<-EOF->----------------------------------// diff --git a/dxsdk/Include/XAudio2.h b/dxsdk/Include/XAudio2.h new file mode 100644 index 0000000..885b92f --- /dev/null +++ b/dxsdk/Include/XAudio2.h @@ -0,0 +1,1282 @@ +/************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: xaudio2.h + * Content: Declarations for the XAudio2 game audio API. + * + **************************************************************************/ + +#ifndef __XAUDIO2_INCLUDED__ +#define __XAUDIO2_INCLUDED__ + + +/************************************************************************** + * + * XAudio2 COM object class and interface IDs. + * + **************************************************************************/ + +#include // For DEFINE_CLSID and DEFINE_IID + +// XAudio 2.0 (March 2008 SDK) +//DEFINE_CLSID(XAudio2, fac23f48, 31f5, 45a8, b4, 9b, 52, 25, d6, 14, 01, aa); +//DEFINE_CLSID(XAudio2_Debug, fac23f48, 31f5, 45a8, b4, 9b, 52, 25, d6, 14, 01, db); + +// XAudio 2.1 (June 2008 SDK) +//DEFINE_CLSID(XAudio2, e21a7345, eb21, 468e, be, 50, 80, 4d, b9, 7c, f7, 08); +//DEFINE_CLSID(XAudio2_Debug, f7a76c21, 53d4, 46bb, ac, 53, 8b, 45, 9c, ae, 46, bd); + +// XAudio 2.2 (August 2008 SDK) +//DEFINE_CLSID(XAudio2, b802058a, 464a, 42db, bc, 10, b6, 50, d6, f2, 58, 6a); +//DEFINE_CLSID(XAudio2_Debug, 97dfb7e7, 5161, 4015, 87, a9, c7, 9e, 6a, 19, 52, cc); + +// XAudio 2.3 (November 2008 SDK) +//DEFINE_CLSID(XAudio2, 4c5e637a, 16c7, 4de3, 9c, 46, 5e, d2, 21, 81, 96, 2d); +//DEFINE_CLSID(XAudio2_Debug, ef0aa05d, 8075, 4e5d, be, ad, 45, be, 0c, 3c, cb, b3); + +// XAudio 2.4 (March 2009 SDK) +//DEFINE_CLSID(XAudio2, 03219e78, 5bc3, 44d1, b9, 2e, f6, 3d, 89, cc, 65, 26); +//DEFINE_CLSID(XAudio2_Debug, 4256535c, 1ea4, 4d4b, 8a, d5, f9, db, 76, 2e, ca, 9e); + +// XAudio 2.5 (August 2009 SDK) +//DEFINE_CLSID(XAudio2, 4c9b6dde, 6809, 46e6, a2, 78, 9b, 6a, 97, 58, 86, 70); +//DEFINE_CLSID(XAudio2_Debug, 715bdd1a, aa82, 436b, b0, fa, 6a, ce, a3, 9b, d0, a1); + +// XAudio 2.6 (February 2010 SDK) +//DEFINE_CLSID(XAudio2, 3eda9b49, 2085, 498b, 9b, b2, 39, a6, 77, 84, 93, de); +//DEFINE_CLSID(XAudio2_Debug, 47199894, 7cc2, 444d, 98, 73, ce, d2, 56, 2c, c6, 0e); + +// XAudio 2.7 (June 2010 SDK) +DEFINE_CLSID(XAudio2, 5a508685, a254, 4fba, 9b, 82, 9a, 24, b0, 03, 06, af); +DEFINE_CLSID(XAudio2_Debug, db05ea35, 0329, 4d4b, a5, 3a, 6d, ea, d0, 3d, 38, 52); +DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb); + + +// Ignore the rest of this header if only the GUID definitions were requested +#ifndef GUID_DEFS_ONLY + +#ifdef _XBOX + #include // Xbox COM declarations (IUnknown, etc) +#else + #include // Windows COM declarations +#endif + +#include // Markers for documenting API semantics +#include // Basic audio data types and constants +#include // Data types and constants for XMA2 audio + +// All structures defined in this file use tight field packing +#pragma pack(push, 1) + + +/************************************************************************** + * + * XAudio2 constants, flags and error codes. + * + **************************************************************************/ + +// Numeric boundary values +#define XAUDIO2_MAX_BUFFER_BYTES 0x80000000 // Maximum bytes allowed in a source buffer +#define XAUDIO2_MAX_QUEUED_BUFFERS 64 // Maximum buffers allowed in a voice queue +#define XAUDIO2_MAX_BUFFERS_SYSTEM 2 // Maximum buffers allowed for system threads (Xbox 360 only) +#define XAUDIO2_MAX_AUDIO_CHANNELS 64 // Maximum channels in an audio stream +#define XAUDIO2_MIN_SAMPLE_RATE 1000 // Minimum audio sample rate supported +#define XAUDIO2_MAX_SAMPLE_RATE 200000 // Maximum audio sample rate supported +#define XAUDIO2_MAX_VOLUME_LEVEL 16777216.0f // Maximum acceptable volume level (2^24) +#define XAUDIO2_MIN_FREQ_RATIO (1/1024.0f) // Minimum SetFrequencyRatio argument +#define XAUDIO2_MAX_FREQ_RATIO 1024.0f // Maximum MaxFrequencyRatio argument +#define XAUDIO2_DEFAULT_FREQ_RATIO 2.0f // Default MaxFrequencyRatio argument +#define XAUDIO2_MAX_FILTER_ONEOVERQ 1.5f // Maximum XAUDIO2_FILTER_PARAMETERS.OneOverQ +#define XAUDIO2_MAX_FILTER_FREQUENCY 1.0f // Maximum XAUDIO2_FILTER_PARAMETERS.Frequency +#define XAUDIO2_MAX_LOOP_COUNT 254 // Maximum non-infinite XAUDIO2_BUFFER.LoopCount +#define XAUDIO2_MAX_INSTANCES 8 // Maximum simultaneous XAudio2 objects on Xbox 360 + +// For XMA voices on Xbox 360 there is an additional restriction on the MaxFrequencyRatio +// argument and the voice's sample rate: the product of these numbers cannot exceed 600000 +// for one-channel voices or 300000 for voices with more than one channel. +#define XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MONO 600000 +#define XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MULTICHANNEL 300000 + +// Numeric values with special meanings +#define XAUDIO2_COMMIT_NOW 0 // Used as an OperationSet argument +#define XAUDIO2_COMMIT_ALL 0 // Used in IXAudio2::CommitChanges +#define XAUDIO2_INVALID_OPSET (UINT32)(-1) // Not allowed for OperationSet arguments +#define XAUDIO2_NO_LOOP_REGION 0 // Used in XAUDIO2_BUFFER.LoopCount +#define XAUDIO2_LOOP_INFINITE 255 // Used in XAUDIO2_BUFFER.LoopCount +#define XAUDIO2_DEFAULT_CHANNELS 0 // Used in CreateMasteringVoice +#define XAUDIO2_DEFAULT_SAMPLERATE 0 // Used in CreateMasteringVoice + +// Flags +#define XAUDIO2_DEBUG_ENGINE 0x0001 // Used in XAudio2Create on Windows only +#define XAUDIO2_VOICE_NOPITCH 0x0002 // Used in IXAudio2::CreateSourceVoice +#define XAUDIO2_VOICE_NOSRC 0x0004 // Used in IXAudio2::CreateSourceVoice +#define XAUDIO2_VOICE_USEFILTER 0x0008 // Used in IXAudio2::CreateSource/SubmixVoice +#define XAUDIO2_VOICE_MUSIC 0x0010 // Used in IXAudio2::CreateSourceVoice +#define XAUDIO2_PLAY_TAILS 0x0020 // Used in IXAudio2SourceVoice::Stop +#define XAUDIO2_END_OF_STREAM 0x0040 // Used in XAUDIO2_BUFFER.Flags +#define XAUDIO2_SEND_USEFILTER 0x0080 // Used in XAUDIO2_SEND_DESCRIPTOR.Flags + +// Default parameters for the built-in filter +#define XAUDIO2_DEFAULT_FILTER_TYPE LowPassFilter +#define XAUDIO2_DEFAULT_FILTER_FREQUENCY XAUDIO2_MAX_FILTER_FREQUENCY +#define XAUDIO2_DEFAULT_FILTER_ONEOVERQ 1.0f + +// Internal XAudio2 constants +#ifdef _XBOX + #define XAUDIO2_QUANTUM_NUMERATOR 2 // On Xbox 360, XAudio2 processes audio + #define XAUDIO2_QUANTUM_DENOMINATOR 375 // in 5.333ms chunks (= 2/375 seconds) +#else + #define XAUDIO2_QUANTUM_NUMERATOR 1 // On Windows, XAudio2 processes audio + #define XAUDIO2_QUANTUM_DENOMINATOR 100 // in 10ms chunks (= 1/100 seconds) +#endif +#define XAUDIO2_QUANTUM_MS (1000.0f * XAUDIO2_QUANTUM_NUMERATOR / XAUDIO2_QUANTUM_DENOMINATOR) + +// XAudio2 error codes +#define FACILITY_XAUDIO2 0x896 +#define XAUDIO2_E_INVALID_CALL 0x88960001 // An API call or one of its arguments was illegal +#define XAUDIO2_E_XMA_DECODER_ERROR 0x88960002 // The XMA hardware suffered an unrecoverable error +#define XAUDIO2_E_XAPO_CREATION_FAILED 0x88960003 // XAudio2 failed to initialize an XAPO effect +#define XAUDIO2_E_DEVICE_INVALIDATED 0x88960004 // An audio device became unusable (unplugged, etc) + + +/************************************************************************** + * + * Forward declarations for the XAudio2 interfaces. + * + **************************************************************************/ + +#ifdef __cplusplus + #define FWD_DECLARE(x) interface x +#else + #define FWD_DECLARE(x) typedef interface x x +#endif + +FWD_DECLARE(IXAudio2); +FWD_DECLARE(IXAudio2Voice); +FWD_DECLARE(IXAudio2SourceVoice); +FWD_DECLARE(IXAudio2SubmixVoice); +FWD_DECLARE(IXAudio2MasteringVoice); +FWD_DECLARE(IXAudio2EngineCallback); +FWD_DECLARE(IXAudio2VoiceCallback); + + +/************************************************************************** + * + * XAudio2 structures and enumerations. + * + **************************************************************************/ + +// Used in IXAudio2::Initialize +#ifdef _XBOX + typedef enum XAUDIO2_XBOX_HWTHREAD_SPECIFIER + { + XboxThread0 = 0x01, + XboxThread1 = 0x02, + XboxThread2 = 0x04, + XboxThread3 = 0x08, + XboxThread4 = 0x10, + XboxThread5 = 0x20, + XAUDIO2_ANY_PROCESSOR = XboxThread4, + XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR + } XAUDIO2_XBOX_HWTHREAD_SPECIFIER, XAUDIO2_PROCESSOR; +#else + typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER + { + Processor1 = 0x00000001, + Processor2 = 0x00000002, + Processor3 = 0x00000004, + Processor4 = 0x00000008, + Processor5 = 0x00000010, + Processor6 = 0x00000020, + Processor7 = 0x00000040, + Processor8 = 0x00000080, + Processor9 = 0x00000100, + Processor10 = 0x00000200, + Processor11 = 0x00000400, + Processor12 = 0x00000800, + Processor13 = 0x00001000, + Processor14 = 0x00002000, + Processor15 = 0x00004000, + Processor16 = 0x00008000, + Processor17 = 0x00010000, + Processor18 = 0x00020000, + Processor19 = 0x00040000, + Processor20 = 0x00080000, + Processor21 = 0x00100000, + Processor22 = 0x00200000, + Processor23 = 0x00400000, + Processor24 = 0x00800000, + Processor25 = 0x01000000, + Processor26 = 0x02000000, + Processor27 = 0x04000000, + Processor28 = 0x08000000, + Processor29 = 0x10000000, + Processor30 = 0x20000000, + Processor31 = 0x40000000, + Processor32 = 0x80000000, + XAUDIO2_ANY_PROCESSOR = 0xffffffff, + XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR + } XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR; +#endif + +// Used in XAUDIO2_DEVICE_DETAILS below to describe the types of applications +// that the user has specified each device as a default for. 0 means that the +// device isn't the default for any role. +typedef enum XAUDIO2_DEVICE_ROLE +{ + NotDefaultDevice = 0x0, + DefaultConsoleDevice = 0x1, + DefaultMultimediaDevice = 0x2, + DefaultCommunicationsDevice = 0x4, + DefaultGameDevice = 0x8, + GlobalDefaultDevice = 0xf, + InvalidDeviceRole = ~GlobalDefaultDevice +} XAUDIO2_DEVICE_ROLE; + +// Returned by IXAudio2::GetDeviceDetails +typedef struct XAUDIO2_DEVICE_DETAILS +{ + WCHAR DeviceID[256]; // String identifier for the audio device. + WCHAR DisplayName[256]; // Friendly name suitable for display to a human. + XAUDIO2_DEVICE_ROLE Role; // Roles that the device should be used for. + WAVEFORMATEXTENSIBLE OutputFormat; // The device's native PCM audio output format. +} XAUDIO2_DEVICE_DETAILS; + +// Returned by IXAudio2Voice::GetVoiceDetails +typedef struct XAUDIO2_VOICE_DETAILS +{ + UINT32 CreationFlags; // Flags the voice was created with. + UINT32 InputChannels; // Channels in the voice's input audio. + UINT32 InputSampleRate; // Sample rate of the voice's input audio. +} XAUDIO2_VOICE_DETAILS; + +// Used in XAUDIO2_VOICE_SENDS below +typedef struct XAUDIO2_SEND_DESCRIPTOR +{ + UINT32 Flags; // Either 0 or XAUDIO2_SEND_USEFILTER. + IXAudio2Voice* pOutputVoice; // This send's destination voice. +} XAUDIO2_SEND_DESCRIPTOR; + +// Used in the voice creation functions and in IXAudio2Voice::SetOutputVoices +typedef struct XAUDIO2_VOICE_SENDS +{ + UINT32 SendCount; // Number of sends from this voice. + XAUDIO2_SEND_DESCRIPTOR* pSends; // Array of SendCount send descriptors. +} XAUDIO2_VOICE_SENDS; + +// Used in XAUDIO2_EFFECT_CHAIN below +typedef struct XAUDIO2_EFFECT_DESCRIPTOR +{ + IUnknown* pEffect; // Pointer to the effect object's IUnknown interface. + BOOL InitialState; // TRUE if the effect should begin in the enabled state. + UINT32 OutputChannels; // How many output channels the effect should produce. +} XAUDIO2_EFFECT_DESCRIPTOR; + +// Used in the voice creation functions and in IXAudio2Voice::SetEffectChain +typedef struct XAUDIO2_EFFECT_CHAIN +{ + UINT32 EffectCount; // Number of effects in this voice's effect chain. + XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors; // Array of effect descriptors. +} XAUDIO2_EFFECT_CHAIN; + +// Used in XAUDIO2_FILTER_PARAMETERS below +typedef enum XAUDIO2_FILTER_TYPE +{ + LowPassFilter, // Attenuates frequencies above the cutoff frequency. + BandPassFilter, // Attenuates frequencies outside a given range. + HighPassFilter, // Attenuates frequencies below the cutoff frequency. + NotchFilter // Attenuates frequencies inside a given range. +} XAUDIO2_FILTER_TYPE; + +// Used in IXAudio2Voice::Set/GetFilterParameters and Set/GetOutputFilterParameters +typedef struct XAUDIO2_FILTER_PARAMETERS +{ + XAUDIO2_FILTER_TYPE Type; // Low-pass, band-pass or high-pass. + float Frequency; // Radian frequency (2 * sin(pi*CutoffFrequency/SampleRate)); + // must be >= 0 and <= XAUDIO2_MAX_FILTER_FREQUENCY + // (giving a maximum CutoffFrequency of SampleRate/6). + float OneOverQ; // Reciprocal of the filter's quality factor Q; + // must be > 0 and <= XAUDIO2_MAX_FILTER_ONEOVERQ. +} XAUDIO2_FILTER_PARAMETERS; + +// Used in IXAudio2SourceVoice::SubmitSourceBuffer +typedef struct XAUDIO2_BUFFER +{ + UINT32 Flags; // Either 0 or XAUDIO2_END_OF_STREAM. + UINT32 AudioBytes; // Size of the audio data buffer in bytes. + const BYTE* pAudioData; // Pointer to the audio data buffer. + UINT32 PlayBegin; // First sample in this buffer to be played. + UINT32 PlayLength; // Length of the region to be played in samples, + // or 0 to play the whole buffer. + UINT32 LoopBegin; // First sample of the region to be looped. + UINT32 LoopLength; // Length of the desired loop region in samples, + // or 0 to loop the entire buffer. + UINT32 LoopCount; // Number of times to repeat the loop region, + // or XAUDIO2_LOOP_INFINITE to loop forever. + void* pContext; // Context value to be passed back in callbacks. +} XAUDIO2_BUFFER; + +// Used in IXAudio2SourceVoice::SubmitSourceBuffer when submitting XWMA data. +// NOTE: If an XWMA sound is submitted in more than one buffer, each buffer's +// pDecodedPacketCumulativeBytes[PacketCount-1] value must be subtracted from +// all the entries in the next buffer's pDecodedPacketCumulativeBytes array. +// And whether a sound is submitted in more than one buffer or not, the final +// buffer of the sound should use the XAUDIO2_END_OF_STREAM flag, or else the +// client must call IXAudio2SourceVoice::Discontinuity after submitting it. +typedef struct XAUDIO2_BUFFER_WMA +{ + const UINT32* pDecodedPacketCumulativeBytes; // Decoded packet's cumulative size array. + // Each element is the number of bytes accumulated + // when the corresponding XWMA packet is decoded in + // order. The array must have PacketCount elements. + UINT32 PacketCount; // Number of XWMA packets submitted. Must be >= 1 and + // divide evenly into XAUDIO2_BUFFER.AudioBytes. +} XAUDIO2_BUFFER_WMA; + +// Returned by IXAudio2SourceVoice::GetState +typedef struct XAUDIO2_VOICE_STATE +{ + void* pCurrentBufferContext; // The pContext value provided in the XAUDIO2_BUFFER + // that is currently being processed, or NULL if + // there are no buffers in the queue. + UINT32 BuffersQueued; // Number of buffers currently queued on the voice + // (including the one that is being processed). + UINT64 SamplesPlayed; // Total number of samples produced by the voice since + // it began processing the current audio stream. +} XAUDIO2_VOICE_STATE; + +// Returned by IXAudio2::GetPerformanceData +typedef struct XAUDIO2_PERFORMANCE_DATA +{ + // CPU usage information + UINT64 AudioCyclesSinceLastQuery; // CPU cycles spent on audio processing since the + // last call to StartEngine or GetPerformanceData. + UINT64 TotalCyclesSinceLastQuery; // Total CPU cycles elapsed since the last call + // (only counts the CPU XAudio2 is running on). + UINT32 MinimumCyclesPerQuantum; // Fewest CPU cycles spent processing any one + // audio quantum since the last call. + UINT32 MaximumCyclesPerQuantum; // Most CPU cycles spent processing any one + // audio quantum since the last call. + + // Memory usage information + UINT32 MemoryUsageInBytes; // Total heap space currently in use. + + // Audio latency and glitching information + UINT32 CurrentLatencyInSamples; // Minimum delay from when a sample is read from a + // source buffer to when it reaches the speakers. + UINT32 GlitchesSinceEngineStarted; // Audio dropouts since the engine was started. + + // Data about XAudio2's current workload + UINT32 ActiveSourceVoiceCount; // Source voices currently playing. + UINT32 TotalSourceVoiceCount; // Source voices currently existing. + UINT32 ActiveSubmixVoiceCount; // Submix voices currently playing/existing. + + UINT32 ActiveResamplerCount; // Resample xAPOs currently active. + UINT32 ActiveMatrixMixCount; // MatrixMix xAPOs currently active. + + // Usage of the hardware XMA decoder (Xbox 360 only) + UINT32 ActiveXmaSourceVoices; // Number of source voices decoding XMA data. + UINT32 ActiveXmaStreams; // A voice can use more than one XMA stream. +} XAUDIO2_PERFORMANCE_DATA; + +// Used in IXAudio2::SetDebugConfiguration +typedef struct XAUDIO2_DEBUG_CONFIGURATION +{ + UINT32 TraceMask; // Bitmap of enabled debug message types. + UINT32 BreakMask; // Message types that will break into the debugger. + BOOL LogThreadID; // Whether to log the thread ID with each message. + BOOL LogFileline; // Whether to log the source file and line number. + BOOL LogFunctionName; // Whether to log the function name. + BOOL LogTiming; // Whether to log message timestamps. +} XAUDIO2_DEBUG_CONFIGURATION; + +// Values for the TraceMask and BreakMask bitmaps. Only ERRORS and WARNINGS +// are valid in BreakMask. WARNINGS implies ERRORS, DETAIL implies INFO, and +// FUNC_CALLS implies API_CALLS. By default, TraceMask is ERRORS and WARNINGS +// and all the other settings are zero. +#define XAUDIO2_LOG_ERRORS 0x0001 // For handled errors with serious effects. +#define XAUDIO2_LOG_WARNINGS 0x0002 // For handled errors that may be recoverable. +#define XAUDIO2_LOG_INFO 0x0004 // Informational chit-chat (e.g. state changes). +#define XAUDIO2_LOG_DETAIL 0x0008 // More detailed chit-chat. +#define XAUDIO2_LOG_API_CALLS 0x0010 // Public API function entries and exits. +#define XAUDIO2_LOG_FUNC_CALLS 0x0020 // Internal function entries and exits. +#define XAUDIO2_LOG_TIMING 0x0040 // Delays detected and other timing data. +#define XAUDIO2_LOG_LOCKS 0x0080 // Usage of critical sections and mutexes. +#define XAUDIO2_LOG_MEMORY 0x0100 // Memory heap usage information. +#define XAUDIO2_LOG_STREAMING 0x1000 // Audio streaming information. + + +/************************************************************************** + * + * IXAudio2: Top-level XAudio2 COM interface. + * + **************************************************************************/ + +// Use default arguments if compiling as C++ +#ifdef __cplusplus + #define X2DEFAULT(x) =x +#else + #define X2DEFAULT(x) +#endif + +#undef INTERFACE +#define INTERFACE IXAudio2 +DECLARE_INTERFACE_(IXAudio2, IUnknown) +{ + // NAME: IXAudio2::QueryInterface + // DESCRIPTION: Queries for a given COM interface on the XAudio2 object. + // Only IID_IUnknown and IID_IXAudio2 are supported. + // + // ARGUMENTS: + // riid - IID of the interface to be obtained. + // ppvInterface - Returns a pointer to the requested interface. + // + STDMETHOD(QueryInterface) (THIS_ REFIID riid, __deref_out void** ppvInterface) PURE; + + // NAME: IXAudio2::AddRef + // DESCRIPTION: Adds a reference to the XAudio2 object. + // + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + + // NAME: IXAudio2::Release + // DESCRIPTION: Releases a reference to the XAudio2 object. + // + STDMETHOD_(ULONG, Release) (THIS) PURE; + + // NAME: IXAudio2::GetDeviceCount + // DESCRIPTION: Returns the number of audio output devices available. + // + // ARGUMENTS: + // pCount - Returns the device count. + // + STDMETHOD(GetDeviceCount) (THIS_ __out UINT32* pCount) PURE; + + // NAME: IXAudio2::GetDeviceDetails + // DESCRIPTION: Returns information about the device with the given index. + // + // ARGUMENTS: + // Index - Index of the device to be queried. + // pDeviceDetails - Returns the device details. + // + STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, __out XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE; + + // NAME: IXAudio2::Initialize + // DESCRIPTION: Sets global XAudio2 parameters and prepares it for use. + // + // ARGUMENTS: + // Flags - Flags specifying the XAudio2 object's behavior. Currently unused. + // XAudio2Processor - An XAUDIO2_PROCESSOR enumeration value that specifies + // the hardware thread (Xbox) or processor (Windows) that XAudio2 will use. + // The enumeration values are platform-specific; platform-independent code + // can use XAUDIO2_DEFAULT_PROCESSOR to use the default on each platform. + // + STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE; + + // NAME: IXAudio2::RegisterForCallbacks + // DESCRIPTION: Adds a new client to receive XAudio2's engine callbacks. + // + // ARGUMENTS: + // pCallback - Callback interface to be called during each processing pass. + // + STDMETHOD(RegisterForCallbacks) (__in IXAudio2EngineCallback* pCallback) PURE; + + // NAME: IXAudio2::UnregisterForCallbacks + // DESCRIPTION: Removes an existing receiver of XAudio2 engine callbacks. + // + // ARGUMENTS: + // pCallback - Previously registered callback interface to be removed. + // + STDMETHOD_(void, UnregisterForCallbacks) (__in IXAudio2EngineCallback* pCallback) PURE; + + // NAME: IXAudio2::CreateSourceVoice + // DESCRIPTION: Creates and configures a source voice. + // + // ARGUMENTS: + // ppSourceVoice - Returns the new object's IXAudio2SourceVoice interface. + // pSourceFormat - Format of the audio that will be fed to the voice. + // Flags - XAUDIO2_VOICE flags specifying the source voice's behavior. + // MaxFrequencyRatio - Maximum SetFrequencyRatio argument to be allowed. + // pCallback - Optional pointer to a client-provided callback interface. + // pSendList - Optional list of voices this voice should send audio to. + // pEffectChain - Optional list of effects to apply to the audio data. + // + STDMETHOD(CreateSourceVoice) (THIS_ __deref_out IXAudio2SourceVoice** ppSourceVoice, + __in const WAVEFORMATEX* pSourceFormat, + UINT32 Flags X2DEFAULT(0), + float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO), + __in_opt IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL), + __in_opt const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), + __in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + + // NAME: IXAudio2::CreateSubmixVoice + // DESCRIPTION: Creates and configures a submix voice. + // + // ARGUMENTS: + // ppSubmixVoice - Returns the new object's IXAudio2SubmixVoice interface. + // InputChannels - Number of channels in this voice's input audio data. + // InputSampleRate - Sample rate of this voice's input audio data. + // Flags - XAUDIO2_VOICE flags specifying the submix voice's behavior. + // ProcessingStage - Arbitrary number that determines the processing order. + // pSendList - Optional list of voices this voice should send audio to. + // pEffectChain - Optional list of effects to apply to the audio data. + // + STDMETHOD(CreateSubmixVoice) (THIS_ __deref_out IXAudio2SubmixVoice** ppSubmixVoice, + UINT32 InputChannels, UINT32 InputSampleRate, + UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0), + __in_opt const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), + __in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + + + // NAME: IXAudio2::CreateMasteringVoice + // DESCRIPTION: Creates and configures a mastering voice. + // + // ARGUMENTS: + // ppMasteringVoice - Returns the new object's IXAudio2MasteringVoice interface. + // InputChannels - Number of channels in this voice's input audio data. + // InputSampleRate - Sample rate of this voice's input audio data. + // Flags - XAUDIO2_VOICE flags specifying the mastering voice's behavior. + // DeviceIndex - Identifier of the device to receive the output audio. + // pEffectChain - Optional list of effects to apply to the audio data. + // + STDMETHOD(CreateMasteringVoice) (THIS_ __deref_out IXAudio2MasteringVoice** ppMasteringVoice, + UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS), + UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE), + UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0), + __in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + + // NAME: IXAudio2::StartEngine + // DESCRIPTION: Creates and starts the audio processing thread. + // + STDMETHOD(StartEngine) (THIS) PURE; + + // NAME: IXAudio2::StopEngine + // DESCRIPTION: Stops and destroys the audio processing thread. + // + STDMETHOD_(void, StopEngine) (THIS) PURE; + + // NAME: IXAudio2::CommitChanges + // DESCRIPTION: Atomically applies a set of operations previously tagged + // with a given identifier. + // + // ARGUMENTS: + // OperationSet - Identifier of the set of operations to be applied. + // + STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE; + + // NAME: IXAudio2::GetPerformanceData + // DESCRIPTION: Returns current resource usage details: memory, CPU, etc. + // + // ARGUMENTS: + // pPerfData - Returns the performance data structure. + // + STDMETHOD_(void, GetPerformanceData) (THIS_ __out XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE; + + // NAME: IXAudio2::SetDebugConfiguration + // DESCRIPTION: Configures XAudio2's debug output (in debug builds only). + // + // ARGUMENTS: + // pDebugConfiguration - Structure describing the debug output behavior. + // pReserved - Optional parameter; must be NULL. + // + STDMETHOD_(void, SetDebugConfiguration) (THIS_ __in_opt const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration, + __in_opt __reserved void* pReserved X2DEFAULT(NULL)) PURE; +}; + + +/************************************************************************** + * + * IXAudio2Voice: Base voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2Voice +DECLARE_INTERFACE(IXAudio2Voice) +{ + // These methods are declared in a macro so that the same declarations + // can be used in the derived voice types (IXAudio2SourceVoice, etc). + + #define Declare_IXAudio2Voice_Methods() \ + \ + /* NAME: IXAudio2Voice::GetVoiceDetails + // DESCRIPTION: Returns the basic characteristics of this voice. + // + // ARGUMENTS: + // pVoiceDetails - Returns the voice's details. + */\ + STDMETHOD_(void, GetVoiceDetails) (THIS_ __out XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \ + \ + /* NAME: IXAudio2Voice::SetOutputVoices + // DESCRIPTION: Replaces the set of submix/mastering voices that receive + // this voice's output. + // + // ARGUMENTS: + // pSendList - Optional list of voices this voice should send audio to. + */\ + STDMETHOD(SetOutputVoices) (THIS_ __in_opt const XAUDIO2_VOICE_SENDS* pSendList) PURE; \ + \ + /* NAME: IXAudio2Voice::SetEffectChain + // DESCRIPTION: Replaces this voice's current effect chain with a new one. + // + // ARGUMENTS: + // pEffectChain - Structure describing the new effect chain to be used. + */\ + STDMETHOD(SetEffectChain) (THIS_ __in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \ + \ + /* NAME: IXAudio2Voice::EnableEffect + // DESCRIPTION: Enables an effect in this voice's effect chain. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::DisableEffect + // DESCRIPTION: Disables an effect in this voice's effect chain. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetEffectState + // DESCRIPTION: Returns the running state of an effect. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // pEnabled - Returns the enabled/disabled state of the given effect. + */\ + STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, __out BOOL* pEnabled) PURE; \ + \ + /* NAME: IXAudio2Voice::SetEffectParameters + // DESCRIPTION: Sets effect-specific parameters. + // + // REMARKS: Unlike IXAPOParameters::SetParameters, this method may + // be called from any thread. XAudio2 implements + // appropriate synchronization to copy the parameters to the + // realtime audio processing thread. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // pParameters - Pointer to an effect-specific parameters block. + // ParametersByteSize - Size of the pParameters array in bytes. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \ + __in_bcount(ParametersByteSize) const void* pParameters, \ + UINT32 ParametersByteSize, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetEffectParameters + // DESCRIPTION: Obtains the current effect-specific parameters. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // pParameters - Returns the current values of the effect-specific parameters. + // ParametersByteSize - Size of the pParameters array in bytes. + */\ + STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, \ + __out_bcount(ParametersByteSize) void* pParameters, \ + UINT32 ParametersByteSize) PURE; \ + \ + /* NAME: IXAudio2Voice::SetFilterParameters + // DESCRIPTION: Sets this voice's filter parameters. + // + // ARGUMENTS: + // pParameters - Pointer to the filter's parameter structure. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetFilterParameters) (THIS_ __in const XAUDIO2_FILTER_PARAMETERS* pParameters, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetFilterParameters + // DESCRIPTION: Returns this voice's current filter parameters. + // + // ARGUMENTS: + // pParameters - Returns the filter parameters. + */\ + STDMETHOD_(void, GetFilterParameters) (THIS_ __out XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \ + \ + /* NAME: IXAudio2Voice::SetOutputFilterParameters + // DESCRIPTION: Sets the filter parameters on one of this voice's sends. + // + // ARGUMENTS: + // pDestinationVoice - Destination voice of the send whose filter parameters will be set. + // pParameters - Pointer to the filter's parameter structure. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetOutputFilterParameters) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \ + __in const XAUDIO2_FILTER_PARAMETERS* pParameters, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetOutputFilterParameters + // DESCRIPTION: Returns the filter parameters from one of this voice's sends. + // + // ARGUMENTS: + // pDestinationVoice - Destination voice of the send whose filter parameters will be read. + // pParameters - Returns the filter parameters. + */\ + STDMETHOD_(void, GetOutputFilterParameters) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \ + __out XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \ + \ + /* NAME: IXAudio2Voice::SetVolume + // DESCRIPTION: Sets this voice's overall volume level. + // + // ARGUMENTS: + // Volume - New overall volume level to be used, as an amplitude factor. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetVolume) (THIS_ float Volume, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetVolume + // DESCRIPTION: Obtains this voice's current overall volume level. + // + // ARGUMENTS: + // pVolume: Returns the voice's current overall volume level. + */\ + STDMETHOD_(void, GetVolume) (THIS_ __out float* pVolume) PURE; \ + \ + /* NAME: IXAudio2Voice::SetChannelVolumes + // DESCRIPTION: Sets this voice's per-channel volume levels. + // + // ARGUMENTS: + // Channels - Used to confirm the voice's channel count. + // pVolumes - Array of per-channel volume levels to be used. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, __in_ecount(Channels) const float* pVolumes, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetChannelVolumes + // DESCRIPTION: Returns this voice's current per-channel volume levels. + // + // ARGUMENTS: + // Channels - Used to confirm the voice's channel count. + // pVolumes - Returns an array of the current per-channel volume levels. + */\ + STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, __out_ecount(Channels) float* pVolumes) PURE; \ + \ + /* NAME: IXAudio2Voice::SetOutputMatrix + // DESCRIPTION: Sets the volume levels used to mix from each channel of this + // voice's output audio to each channel of a given destination + // voice's input audio. + // + // ARGUMENTS: + // pDestinationVoice - The destination voice whose mix matrix to change. + // SourceChannels - Used to confirm this voice's output channel count + // (the number of channels produced by the last effect in the chain). + // DestinationChannels - Confirms the destination voice's input channels. + // pLevelMatrix - Array of [SourceChannels * DestinationChannels] send + // levels. The level used to send from source channel S to destination + // channel D should be in pLevelMatrix[S + SourceChannels * D]. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetOutputMatrix) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \ + UINT32 SourceChannels, UINT32 DestinationChannels, \ + __in_ecount(SourceChannels * DestinationChannels) const float* pLevelMatrix, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetOutputMatrix + // DESCRIPTION: Obtains the volume levels used to send each channel of this + // voice's output audio to each channel of a given destination + // voice's input audio. + // + // ARGUMENTS: + // pDestinationVoice - The destination voice whose mix matrix to obtain. + // SourceChannels - Used to confirm this voice's output channel count + // (the number of channels produced by the last effect in the chain). + // DestinationChannels - Confirms the destination voice's input channels. + // pLevelMatrix - Array of send levels, as above. + */\ + STDMETHOD_(void, GetOutputMatrix) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \ + UINT32 SourceChannels, UINT32 DestinationChannels, \ + __out_ecount(SourceChannels * DestinationChannels) float* pLevelMatrix) PURE; \ + \ + /* NAME: IXAudio2Voice::DestroyVoice + // DESCRIPTION: Destroys this voice, stopping it if necessary and removing + // it from the XAudio2 graph. + */\ + STDMETHOD_(void, DestroyVoice) (THIS) PURE + + Declare_IXAudio2Voice_Methods(); +}; + + +/************************************************************************** + * + * IXAudio2SourceVoice: Source voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2SourceVoice +DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice) +{ + // Methods from IXAudio2Voice base interface + Declare_IXAudio2Voice_Methods(); + + // NAME: IXAudio2SourceVoice::Start + // DESCRIPTION: Makes this voice start consuming and processing audio. + // + // ARGUMENTS: + // Flags - Flags controlling how the voice should be started. + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(Start) (THIS_ UINT32 Flags X2DEFAULT(0), UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::Stop + // DESCRIPTION: Makes this voice stop consuming audio. + // + // ARGUMENTS: + // Flags - Flags controlling how the voice should be stopped. + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(Stop) (THIS_ UINT32 Flags X2DEFAULT(0), UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::SubmitSourceBuffer + // DESCRIPTION: Adds a new audio buffer to this voice's input queue. + // + // ARGUMENTS: + // pBuffer - Pointer to the buffer structure to be queued. + // pBufferWMA - Additional structure used only when submitting XWMA data. + // + STDMETHOD(SubmitSourceBuffer) (THIS_ __in const XAUDIO2_BUFFER* pBuffer, __in_opt const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE; + + // NAME: IXAudio2SourceVoice::FlushSourceBuffers + // DESCRIPTION: Removes all pending audio buffers from this voice's queue. + // + STDMETHOD(FlushSourceBuffers) (THIS) PURE; + + // NAME: IXAudio2SourceVoice::Discontinuity + // DESCRIPTION: Notifies the voice of an intentional break in the stream of + // audio buffers (e.g. the end of a sound), to prevent XAudio2 + // from interpreting an empty buffer queue as a glitch. + // + STDMETHOD(Discontinuity) (THIS) PURE; + + // NAME: IXAudio2SourceVoice::ExitLoop + // DESCRIPTION: Breaks out of the current loop when its end is reached. + // + // ARGUMENTS: + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::GetState + // DESCRIPTION: Returns the number of buffers currently queued on this voice, + // the pContext value associated with the currently processing + // buffer (if any), and other voice state information. + // + // ARGUMENTS: + // pVoiceState - Returns the state information. + // + STDMETHOD_(void, GetState) (THIS_ __out XAUDIO2_VOICE_STATE* pVoiceState) PURE; + + // NAME: IXAudio2SourceVoice::SetFrequencyRatio + // DESCRIPTION: Sets this voice's frequency adjustment, i.e. its pitch. + // + // ARGUMENTS: + // Ratio - Frequency change, expressed as source frequency / target frequency. + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio, + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::GetFrequencyRatio + // DESCRIPTION: Returns this voice's current frequency adjustment ratio. + // + // ARGUMENTS: + // pRatio - Returns the frequency adjustment. + // + STDMETHOD_(void, GetFrequencyRatio) (THIS_ __out float* pRatio) PURE; + + // NAME: IXAudio2SourceVoice::SetSourceSampleRate + // DESCRIPTION: Reconfigures this voice to treat its source data as being + // at a different sample rate than the original one specified + // in CreateSourceVoice's pSourceFormat argument. + // + // ARGUMENTS: + // UINT32 - The intended sample rate of further submitted source data. + // + STDMETHOD(SetSourceSampleRate) (THIS_ UINT32 NewSourceSampleRate) PURE; +}; + + +/************************************************************************** + * + * IXAudio2SubmixVoice: Submixing voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2SubmixVoice +DECLARE_INTERFACE_(IXAudio2SubmixVoice, IXAudio2Voice) +{ + // Methods from IXAudio2Voice base interface + Declare_IXAudio2Voice_Methods(); + + // There are currently no methods specific to submix voices. +}; + + +/************************************************************************** + * + * IXAudio2MasteringVoice: Mastering voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2MasteringVoice +DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice) +{ + // Methods from IXAudio2Voice base interface + Declare_IXAudio2Voice_Methods(); + + // There are currently no methods specific to mastering voices. +}; + + +/************************************************************************** + * + * IXAudio2EngineCallback: Client notification interface for engine events. + * + * REMARKS: Contains methods to notify the client when certain events happen + * in the XAudio2 engine. This interface should be implemented by + * the client. XAudio2 will call these methods via the interface + * pointer provided by the client when it calls XAudio2Create or + * IXAudio2::Initialize. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2EngineCallback +DECLARE_INTERFACE(IXAudio2EngineCallback) +{ + // Called by XAudio2 just before an audio processing pass begins. + STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE; + + // Called just after an audio processing pass ends. + STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE; + + // Called in the event of a critical system error which requires XAudio2 + // to be closed down and restarted. The error code is given in Error. + STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE; +}; + + +/************************************************************************** + * + * IXAudio2VoiceCallback: Client notification interface for voice events. + * + * REMARKS: Contains methods to notify the client when certain events happen + * in an XAudio2 voice. This interface should be implemented by the + * client. XAudio2 will call these methods via an interface pointer + * provided by the client in the IXAudio2::CreateSourceVoice call. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2VoiceCallback +DECLARE_INTERFACE(IXAudio2VoiceCallback) +{ + // Called just before this voice's processing pass begins. + STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE; + + // Called just after this voice's processing pass ends. + STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE; + + // Called when this voice has just finished playing a buffer stream + // (as marked with the XAUDIO2_END_OF_STREAM flag on the last buffer). + STDMETHOD_(void, OnStreamEnd) (THIS) PURE; + + // Called when this voice is about to start processing a new buffer. + STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext) PURE; + + // Called when this voice has just finished processing a buffer. + // The buffer can now be reused or destroyed. + STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext) PURE; + + // Called when this voice has just reached the end position of a loop. + STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext) PURE; + + // Called in the event of a critical error during voice processing, + // such as a failing xAPO or an error from the hardware XMA decoder. + // The voice may have to be destroyed and re-created to recover from + // the error. The callback arguments report which buffer was being + // processed when the error occurred, and its HRESULT code. + STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) PURE; +}; + + +/************************************************************************** + * + * Macros to make it easier to use the XAudio2 COM interfaces in C code. + * + **************************************************************************/ + +#ifndef __cplusplus + +// IXAudio2 +#define IXAudio2_QueryInterface(This,riid,ppvInterface) ((This)->lpVtbl->QueryInterface(This,riid,ppvInterface)) +#define IXAudio2_AddRef(This) ((This)->lpVtbl->AddRef(This)) +#define IXAudio2_Release(This) ((This)->lpVtbl->Release(This)) +#define IXAudio2_GetDeviceCount(This,puCount) ((This)->lpVtbl->GetDeviceCount(This,puCount)) +#define IXAudio2_GetDeviceDetails(This,Index,pDeviceDetails) ((This)->lpVtbl->GetDeviceDetails(This,Index,pDeviceDetails)) +#define IXAudio2_Initialize(This,Flags,XAudio2Processor) ((This)->lpVtbl->Initialize(This,Flags,XAudio2Processor)) +#define IXAudio2_CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) ((This)->lpVtbl->CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain)) +#define IXAudio2_CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain) ((This)->lpVtbl->CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain)) +#define IXAudio2_CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) ((This)->lpVtbl->CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain)) +#define IXAudio2_StartEngine(This) ((This)->lpVtbl->StartEngine(This)) +#define IXAudio2_StopEngine(This) ((This)->lpVtbl->StopEngine(This)) +#define IXAudio2_CommitChanges(This,OperationSet) ((This)->lpVtbl->CommitChanges(This,OperationSet)) +#define IXAudio2_GetPerformanceData(This,pPerfData) ((This)->lpVtbl->GetPerformanceData(This,pPerfData)) +#define IXAudio2_SetDebugConfiguration(This,pDebugConfiguration,pReserved) ((This)->lpVtbl->SetDebugConfiguration(This,pDebugConfiguration,pReserved)) + +// IXAudio2Voice +#define IXAudio2Voice_GetVoiceDetails(This,pVoiceDetails) ((This)->lpVtbl->GetVoiceDetails(This,pVoiceDetails)) +#define IXAudio2Voice_SetOutputVoices(This,pSendList) ((This)->lpVtbl->SetOutputVoices(This,pSendList)) +#define IXAudio2Voice_SetEffectChain(This,pEffectChain) ((This)->lpVtbl->SetEffectChain(This,pEffectChain)) +#define IXAudio2Voice_EnableEffect(This,EffectIndex,OperationSet) ((This)->lpVtbl->EnableEffect(This,EffectIndex,OperationSet)) +#define IXAudio2Voice_DisableEffect(This,EffectIndex,OperationSet) ((This)->lpVtbl->DisableEffect(This,EffectIndex,OperationSet)) +#define IXAudio2Voice_GetEffectState(This,EffectIndex,pEnabled) ((This)->lpVtbl->GetEffectState(This,EffectIndex,pEnabled)) +#define IXAudio2Voice_SetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize, OperationSet) ((This)->lpVtbl->SetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize,OperationSet)) +#define IXAudio2Voice_GetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize) ((This)->lpVtbl->GetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize)) +#define IXAudio2Voice_SetFilterParameters(This,pParameters,OperationSet) ((This)->lpVtbl->SetFilterParameters(This,pParameters,OperationSet)) +#define IXAudio2Voice_GetFilterParameters(This,pParameters) ((This)->lpVtbl->GetFilterParameters(This,pParameters)) +#define IXAudio2Voice_SetOutputFilterParameters(This,pDestinationVoice,pParameters,OperationSet) ((This)->lpVtbl->SetOutputFilterParameters(This,pDestinationVoice,pParameters,OperationSet)) +#define IXAudio2Voice_GetOutputFilterParameters(This,pDestinationVoice,pParameters) ((This)->lpVtbl->GetOutputFilterParameters(This,pDestinationVoice,pParameters)) +#define IXAudio2Voice_SetVolume(This,Volume,OperationSet) ((This)->lpVtbl->SetVolume(This,Volume,OperationSet)) +#define IXAudio2Voice_GetVolume(This,pVolume) ((This)->lpVtbl->GetVolume(This,pVolume)) +#define IXAudio2Voice_SetChannelVolumes(This,Channels,pVolumes,OperationSet) ((This)->lpVtbl->SetChannelVolumes(This,Channels,pVolumes,OperationSet)) +#define IXAudio2Voice_GetChannelVolumes(This,Channels,pVolumes) ((This)->lpVtbl->GetChannelVolumes(This,Channels,pVolumes)) +#define IXAudio2Voice_SetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix,OperationSet) ((This)->lpVtbl->SetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix,OperationSet)) +#define IXAudio2Voice_GetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix) ((This)->lpVtbl->GetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix)) +#define IXAudio2Voice_DestroyVoice(This) ((This)->lpVtbl->DestroyVoice(This)) + +// IXAudio2SourceVoice +#define IXAudio2SourceVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails +#define IXAudio2SourceVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices +#define IXAudio2SourceVoice_SetEffectChain IXAudio2Voice_SetEffectChain +#define IXAudio2SourceVoice_EnableEffect IXAudio2Voice_EnableEffect +#define IXAudio2SourceVoice_DisableEffect IXAudio2Voice_DisableEffect +#define IXAudio2SourceVoice_GetEffectState IXAudio2Voice_GetEffectState +#define IXAudio2SourceVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters +#define IXAudio2SourceVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters +#define IXAudio2SourceVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters +#define IXAudio2SourceVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters +#define IXAudio2SourceVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters +#define IXAudio2SourceVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters +#define IXAudio2SourceVoice_SetVolume IXAudio2Voice_SetVolume +#define IXAudio2SourceVoice_GetVolume IXAudio2Voice_GetVolume +#define IXAudio2SourceVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes +#define IXAudio2SourceVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes +#define IXAudio2SourceVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix +#define IXAudio2SourceVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix +#define IXAudio2SourceVoice_DestroyVoice IXAudio2Voice_DestroyVoice +#define IXAudio2SourceVoice_Start(This,Flags,OperationSet) ((This)->lpVtbl->Start(This,Flags,OperationSet)) +#define IXAudio2SourceVoice_Stop(This,Flags,OperationSet) ((This)->lpVtbl->Stop(This,Flags,OperationSet)) +#define IXAudio2SourceVoice_SubmitSourceBuffer(This,pBuffer,pBufferWMA) ((This)->lpVtbl->SubmitSourceBuffer(This,pBuffer,pBufferWMA)) +#define IXAudio2SourceVoice_FlushSourceBuffers(This) ((This)->lpVtbl->FlushSourceBuffers(This)) +#define IXAudio2SourceVoice_Discontinuity(This) ((This)->lpVtbl->Discontinuity(This)) +#define IXAudio2SourceVoice_ExitLoop(This,OperationSet) ((This)->lpVtbl->ExitLoop(This,OperationSet)) +#define IXAudio2SourceVoice_GetState(This,pVoiceState) ((This)->lpVtbl->GetState(This,pVoiceState)) +#define IXAudio2SourceVoice_SetFrequencyRatio(This,Ratio,OperationSet) ((This)->lpVtbl->SetFrequencyRatio(This,Ratio,OperationSet)) +#define IXAudio2SourceVoice_GetFrequencyRatio(This,pRatio) ((This)->lpVtbl->GetFrequencyRatio(This,pRatio)) +#define IXAudio2SourceVoice_SetSourceSampleRate(This,NewSourceSampleRate) ((This)->lpVtbl->SetSourceSampleRate(This,NewSourceSampleRate)) + +// IXAudio2SubmixVoice +#define IXAudio2SubmixVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails +#define IXAudio2SubmixVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices +#define IXAudio2SubmixVoice_SetEffectChain IXAudio2Voice_SetEffectChain +#define IXAudio2SubmixVoice_EnableEffect IXAudio2Voice_EnableEffect +#define IXAudio2SubmixVoice_DisableEffect IXAudio2Voice_DisableEffect +#define IXAudio2SubmixVoice_GetEffectState IXAudio2Voice_GetEffectState +#define IXAudio2SubmixVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters +#define IXAudio2SubmixVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters +#define IXAudio2SubmixVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters +#define IXAudio2SubmixVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters +#define IXAudio2SubmixVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters +#define IXAudio2SubmixVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters +#define IXAudio2SubmixVoice_SetVolume IXAudio2Voice_SetVolume +#define IXAudio2SubmixVoice_GetVolume IXAudio2Voice_GetVolume +#define IXAudio2SubmixVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes +#define IXAudio2SubmixVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes +#define IXAudio2SubmixVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix +#define IXAudio2SubmixVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix +#define IXAudio2SubmixVoice_DestroyVoice IXAudio2Voice_DestroyVoice + +// IXAudio2MasteringVoice +#define IXAudio2MasteringVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails +#define IXAudio2MasteringVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices +#define IXAudio2MasteringVoice_SetEffectChain IXAudio2Voice_SetEffectChain +#define IXAudio2MasteringVoice_EnableEffect IXAudio2Voice_EnableEffect +#define IXAudio2MasteringVoice_DisableEffect IXAudio2Voice_DisableEffect +#define IXAudio2MasteringVoice_GetEffectState IXAudio2Voice_GetEffectState +#define IXAudio2MasteringVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters +#define IXAudio2MasteringVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters +#define IXAudio2MasteringVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters +#define IXAudio2MasteringVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters +#define IXAudio2MasteringVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters +#define IXAudio2MasteringVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters +#define IXAudio2MasteringVoice_SetVolume IXAudio2Voice_SetVolume +#define IXAudio2MasteringVoice_GetVolume IXAudio2Voice_GetVolume +#define IXAudio2MasteringVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes +#define IXAudio2MasteringVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes +#define IXAudio2MasteringVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix +#define IXAudio2MasteringVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix +#define IXAudio2MasteringVoice_DestroyVoice IXAudio2Voice_DestroyVoice + +#endif // #ifndef __cplusplus + + +/************************************************************************** + * + * Utility functions used to convert from pitch in semitones and volume + * in decibels to the frequency and amplitude ratio units used by XAudio2. + * These are only defined if the client #defines XAUDIO2_HELPER_FUNCTIONS + * prior to #including xaudio2.h. + * + **************************************************************************/ + +#ifdef XAUDIO2_HELPER_FUNCTIONS + +#define _USE_MATH_DEFINES // Make math.h define M_PI +#include // For powf, log10f, sinf and asinf + +// Calculate the argument to SetVolume from a decibel value +__inline float XAudio2DecibelsToAmplitudeRatio(float Decibels) +{ + return powf(10.0f, Decibels / 20.0f); +} + +// Recover a volume in decibels from an amplitude factor +__inline float XAudio2AmplitudeRatioToDecibels(float Volume) +{ + if (Volume == 0) + { + return -3.402823466e+38f; // Smallest float value (-FLT_MAX) + } + return 20.0f * log10f(Volume); +} + +// Calculate the argument to SetFrequencyRatio from a semitone value +__inline float XAudio2SemitonesToFrequencyRatio(float Semitones) +{ + // FrequencyRatio = 2 ^ Octaves + // = 2 ^ (Semitones / 12) + return powf(2.0f, Semitones / 12.0f); +} + +// Recover a pitch in semitones from a frequency ratio +__inline float XAudio2FrequencyRatioToSemitones(float FrequencyRatio) +{ + // Semitones = 12 * log2(FrequencyRatio) + // = 12 * log2(10) * log10(FrequencyRatio) + return 39.86313713864835f * log10f(FrequencyRatio); +} + +// Convert from filter cutoff frequencies expressed in Hertz to the radian +// frequency values used in XAUDIO2_FILTER_PARAMETERS.Frequency. Note that +// the highest CutoffFrequency supported is SampleRate/6. Higher values of +// CutoffFrequency will return XAUDIO2_MAX_FILTER_FREQUENCY. +__inline float XAudio2CutoffFrequencyToRadians(float CutoffFrequency, UINT32 SampleRate) +{ + if ((UINT32)(CutoffFrequency * 6.0f) >= SampleRate) + { + return XAUDIO2_MAX_FILTER_FREQUENCY; + } + return 2.0f * sinf((float)M_PI * CutoffFrequency / SampleRate); +} + +// Convert from radian frequencies back to absolute frequencies in Hertz +__inline float XAudio2RadiansToCutoffFrequency(float Radians, float SampleRate) +{ + return SampleRate * asinf(Radians / 2.0f) / (float)M_PI; +} +#endif // #ifdef XAUDIO2_HELPER_FUNCTIONS + + +/************************************************************************** + * + * XAudio2Create: Top-level function that creates an XAudio2 instance. + * + * On Windows this is just an inline function that calls CoCreateInstance + * and Initialize. The arguments are described above, under Initialize, + * except that the XAUDIO2_DEBUG_ENGINE flag can be used here to select + * the debug version of XAudio2. + * + * On Xbox, this function is implemented in the XAudio2 library, and the + * XAUDIO2_DEBUG_ENGINE flag has no effect; the client must explicitly + * link with the debug version of the library to obtain debug behavior. + * + **************************************************************************/ + +#ifdef _XBOX + +STDAPI XAudio2Create(__deref_out IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)); + +#else // Windows + +__inline HRESULT XAudio2Create(__deref_out IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) +{ + // Instantiate the appropriate XAudio2 engine + IXAudio2* pXAudio2; + + #ifdef __cplusplus + + HRESULT hr = CoCreateInstance((Flags & XAUDIO2_DEBUG_ENGINE) ? __uuidof(XAudio2_Debug) : __uuidof(XAudio2), + NULL, CLSCTX_INPROC_SERVER, __uuidof(IXAudio2), (void**)&pXAudio2); + if (SUCCEEDED(hr)) + { + hr = pXAudio2->Initialize(Flags, XAudio2Processor); + + if (SUCCEEDED(hr)) + { + *ppXAudio2 = pXAudio2; + } + else + { + pXAudio2->Release(); + } + } + + #else + + HRESULT hr = CoCreateInstance((Flags & XAUDIO2_DEBUG_ENGINE) ? &CLSID_XAudio2_Debug : &CLSID_XAudio2, + NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2); + if (SUCCEEDED(hr)) + { + hr = pXAudio2->lpVtbl->Initialize(pXAudio2, Flags, XAudio2Processor); + + if (SUCCEEDED(hr)) + { + *ppXAudio2 = pXAudio2; + } + else + { + pXAudio2->lpVtbl->Release(pXAudio2); + } + } + + #endif // #ifdef __cplusplus + + return hr; +} + +#endif // #ifdef _XBOX + + +// Undo the #pragma pack(push, 1) directive at the top of this file +#pragma pack(pop) + +#endif // #ifndef GUID_DEFS_ONLY +#endif // #ifndef __XAUDIO2_INCLUDED__ diff --git a/dxsdk/Include/XAudio2fx.h b/dxsdk/Include/XAudio2fx.h new file mode 100644 index 0000000..4284bd2 --- /dev/null +++ b/dxsdk/Include/XAudio2fx.h @@ -0,0 +1,431 @@ +/************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: xaudio2fx.h + * Content: Declarations for the audio effects included with XAudio2. + * + **************************************************************************/ + +#ifndef __XAUDIO2FX_INCLUDED__ +#define __XAUDIO2FX_INCLUDED__ + + +/************************************************************************** + * + * XAudio2 effect class IDs. + * + **************************************************************************/ + +#include "comdecl.h" // For DEFINE_CLSID and DEFINE_IID + +// XAudio 2.0 (March 2008 SDK) +//DEFINE_CLSID(AudioVolumeMeter, C0C56F46, 29B1, 44E9, 99, 39, A3, 2C, E8, 68, 67, E2); +//DEFINE_CLSID(AudioVolumeMeter_Debug, C0C56F46, 29B1, 44E9, 99, 39, A3, 2C, E8, 68, 67, DB); +//DEFINE_CLSID(AudioReverb, 6F6EA3A9, 2CF5, 41CF, 91, C1, 21, 70, B1, 54, 00, 63); +//DEFINE_CLSID(AudioReverb_Debug, 6F6EA3A9, 2CF5, 41CF, 91, C1, 21, 70, B1, 54, 00, DB); + +// XAudio 2.1 (June 2008 SDK) +//DEFINE_CLSID(AudioVolumeMeter, c1e3f122, a2ea, 442c, 85, 4f, 20, d9, 8f, 83, 57, a1); +//DEFINE_CLSID(AudioVolumeMeter_Debug, 6d97a461, b02d, 48ae, b5, 43, 82, bc, 35, fd, fa, e2); +//DEFINE_CLSID(AudioReverb, f4769300, b949, 4df9, b3, 33, 00, d3, 39, 32, e9, a6); +//DEFINE_CLSID(AudioReverb_Debug, aea2cabc, 8c7c, 46aa, ba, 44, 0e, 6d, 75, 88, a1, f2); + +// XAudio 2.2 (August 2008 SDK) +//DEFINE_CLSID(AudioVolumeMeter, f5ca7b34, 8055, 42c0, b8, 36, 21, 61, 29, eb, 7e, 30); +//DEFINE_CLSID(AudioVolumeMeter_Debug, f796f5f7, 6059, 4a9f, 98, 2d, 61, ee, c2, ed, 67, ca); +//DEFINE_CLSID(AudioReverb, 629cf0de, 3ecc, 41e7, 99, 26, f7, e4, 3e, eb, ec, 51); +//DEFINE_CLSID(AudioReverb_Debug, 4aae4299, 3260, 46d4, 97, cc, 6c, c7, 60, c8, 53, 29); + +// XAudio 2.3 (November 2008 SDK) +//DEFINE_CLSID(AudioVolumeMeter, e180344b, ac83, 4483, 95, 9e, 18, a5, c5, 6a, 5e, 19); +//DEFINE_CLSID(AudioVolumeMeter_Debug, 922a0a56, 7d13, 40ae, a4, 81, 3c, 6c, 60, f1, 14, 01); +//DEFINE_CLSID(AudioReverb, 9cab402c, 1d37, 44b4, 88, 6d, fa, 4f, 36, 17, 0a, 4c); +//DEFINE_CLSID(AudioReverb_Debug, eadda998, 3be6, 4505, 84, be, ea, 06, 36, 5d, b9, 6b); + +// XAudio 2.4 (March 2009 SDK) +//DEFINE_CLSID(AudioVolumeMeter, c7338b95, 52b8, 4542, aa, 79, 42, eb, 01, 6c, 8c, 1c); +//DEFINE_CLSID(AudioVolumeMeter_Debug, 524bd872, 5c0b, 4217, bd, b8, 0a, 86, 81, 83, 0b, a5); +//DEFINE_CLSID(AudioReverb, 8bb7778b, 645b, 4475, 9a, 73, 1d, e3, 17, 0b, d3, af); +//DEFINE_CLSID(AudioReverb_Debug, da7738a2, cd0c, 4367, 9a, ac, d7, ea, d7, c6, 4f, 98); + +// XAudio 2.5 (March 2009 SDK) +//DEFINE_CLSID(AudioVolumeMeter, 2139e6da, c341, 4774, 9a, c3, b4, e0, 26, 34, 7f, 64); +//DEFINE_CLSID(AudioVolumeMeter_Debug, a5cc4e13, ca00, 416b, a6, ee, 49, fe, e7, b5, 43, d0); +//DEFINE_CLSID(AudioReverb, d06df0d0, 8518, 441e, 82, 2f, 54, 51, d5, c5, 95, b8); +//DEFINE_CLSID(AudioReverb_Debug, 613604ec, 304c, 45ec, a4, ed, 7a, 1c, 61, 2e, 9e, 72); + +// XAudio 2.6 (February 2010 SDK) +//DEFINE_CLSID(AudioVolumeMeter, e48c5a3f, 93ef, 43bb, a0, 92, 2c, 7c, eb, 94, 6f, 27); +//DEFINE_CLSID(AudioVolumeMeter_Debug, 9a9eaef7, a9e0, 4088, 9b, 1b, 9c, a0, 3a, 1a, ec, d4); +//DEFINE_CLSID(AudioReverb, cecec95a, d894, 491a, be, e3, 5e, 10, 6f, b5, 9f, 2d); +//DEFINE_CLSID(AudioReverb_Debug, 99a1c72e, 364c, 4c1b, 96, 23, fd, 5c, 8a, bd, 90, c7); + +// XAudio 2.7 (June 2010 SDK) +DEFINE_CLSID(AudioVolumeMeter, cac1105f, 619b, 4d04, 83, 1a, 44, e1, cb, f1, 2d, 57); +DEFINE_CLSID(AudioVolumeMeter_Debug, 2d9a0f9c, e67b, 4b24, ab, 44, 92, b3, e7, 70, c0, 20); +DEFINE_CLSID(AudioReverb, 6a93130e, 1d53, 41d1, a9, cf, e7, 58, 80, 0b, b1, 79); +DEFINE_CLSID(AudioReverb_Debug, c4f82dd4, cb4e, 4ce1, 8b, db, ee, 32, d4, 19, 82, 69); + +// Ignore the rest of this header if only the GUID definitions were requested +#ifndef GUID_DEFS_ONLY + +#ifdef _XBOX + #include // Xbox COM declarations (IUnknown, etc) +#else + #include // Windows COM declarations +#endif +#include // For log10() + + +// All structures defined in this file should use tight packing +#pragma pack(push, 1) + + +/************************************************************************** + * + * Effect creation functions. On Windows, these are just inline functions + * that call CoCreateInstance and Initialize; the XAUDIO2FX_DEBUG flag can + * be used to select the debug version of the effects. On Xbox, these map + * to real functions included in xaudio2.lib, and the XAUDIO2FX_DEBUG flag + * is ignored; the application must link with the debug library to use the + * debug functionality. + * + **************************************************************************/ + +// Use default values for some parameters if building C++ code +#ifdef __cplusplus + #define DEFAULT(x) =x +#else + #define DEFAULT(x) +#endif + +#define XAUDIO2FX_DEBUG 1 // To select the debug version of an effect + +#ifdef _XBOX + + STDAPI CreateAudioVolumeMeter(__deref_out IUnknown** ppApo); + STDAPI CreateAudioReverb(__deref_out IUnknown** ppApo); + + __inline HRESULT XAudio2CreateVolumeMeter(__deref_out IUnknown** ppApo, UINT32 /*Flags*/ DEFAULT(0)) + { + return CreateAudioVolumeMeter(ppApo); + } + + __inline HRESULT XAudio2CreateReverb(__deref_out IUnknown** ppApo, UINT32 /*Flags*/ DEFAULT(0)) + { + return CreateAudioReverb(ppApo); + } + +#else // Windows + + __inline HRESULT XAudio2CreateVolumeMeter(__deref_out IUnknown** ppApo, UINT32 Flags DEFAULT(0)) + { + #ifdef __cplusplus + return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? __uuidof(AudioVolumeMeter_Debug) + : __uuidof(AudioVolumeMeter), + NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)ppApo); + #else + return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? &CLSID_AudioVolumeMeter_Debug + : &CLSID_AudioVolumeMeter, + NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppApo); + #endif + } + + __inline HRESULT XAudio2CreateReverb(__deref_out IUnknown** ppApo, UINT32 Flags DEFAULT(0)) + { + #ifdef __cplusplus + return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? __uuidof(AudioReverb_Debug) + : __uuidof(AudioReverb), + NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)ppApo); + #else + return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? &CLSID_AudioReverb_Debug + : &CLSID_AudioReverb, + NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppApo); + #endif + } + +#endif // #ifdef _XBOX + + + +/************************************************************************** + * + * Volume meter parameters. + * The volume meter supports FLOAT32 audio formats and must be used in-place. + * + **************************************************************************/ + +// XAUDIO2FX_VOLUMEMETER_LEVELS: Receives results from GetEffectParameters(). +// The user is responsible for allocating pPeakLevels, pRMSLevels, and +// initializing ChannelCount accordingly. +// The volume meter does not support SetEffectParameters(). +typedef struct XAUDIO2FX_VOLUMEMETER_LEVELS +{ + float* pPeakLevels; // Peak levels table: receives maximum absolute level for each channel + // over a processing pass; may be NULL if pRMSLevls != NULL, + // otherwise must have at least ChannelCount elements. + float* pRMSLevels; // Root mean square levels table: receives RMS level for each channel + // over a processing pass; may be NULL if pPeakLevels != NULL, + // otherwise must have at least ChannelCount elements. + UINT32 ChannelCount; // Number of channels being processed by the volume meter APO +} XAUDIO2FX_VOLUMEMETER_LEVELS; + + + +/************************************************************************** + * + * Reverb parameters. + * The reverb supports only FLOAT32 audio with the following channel + * configurations: + * Input: Mono Output: Mono + * Input: Mono Output: 5.1 + * Input: Stereo Output: Stereo + * Input: Stereo Output: 5.1 + * The framerate must be within [20000, 48000] Hz. + * + * When using mono input, delay filters associated with the right channel + * are not executed. In this case, parameters such as PositionRight and + * PositionMatrixRight have no effect. This also means the reverb uses + * less CPU when hosted in a mono submix. + * + **************************************************************************/ + +#define XAUDIO2FX_REVERB_MIN_FRAMERATE 20000 +#define XAUDIO2FX_REVERB_MAX_FRAMERATE 48000 + +// XAUDIO2FX_REVERB_PARAMETERS: Native parameter set for the reverb effect + +typedef struct XAUDIO2FX_REVERB_PARAMETERS +{ + // ratio of wet (processed) signal to dry (original) signal + float WetDryMix; // [0, 100] (percentage) + + // Delay times + UINT32 ReflectionsDelay; // [0, 300] in ms + BYTE ReverbDelay; // [0, 85] in ms + BYTE RearDelay; // [0, 5] in ms + + // Indexed parameters + BYTE PositionLeft; // [0, 30] no units + BYTE PositionRight; // [0, 30] no units, ignored when configured to mono + BYTE PositionMatrixLeft; // [0, 30] no units + BYTE PositionMatrixRight; // [0, 30] no units, ignored when configured to mono + BYTE EarlyDiffusion; // [0, 15] no units + BYTE LateDiffusion; // [0, 15] no units + BYTE LowEQGain; // [0, 12] no units + BYTE LowEQCutoff; // [0, 9] no units + BYTE HighEQGain; // [0, 8] no units + BYTE HighEQCutoff; // [0, 14] no units + + // Direct parameters + float RoomFilterFreq; // [20, 20000] in Hz + float RoomFilterMain; // [-100, 0] in dB + float RoomFilterHF; // [-100, 0] in dB + float ReflectionsGain; // [-100, 20] in dB + float ReverbGain; // [-100, 20] in dB + float DecayTime; // [0.1, inf] in seconds + float Density; // [0, 100] (percentage) + float RoomSize; // [1, 100] in feet +} XAUDIO2FX_REVERB_PARAMETERS; + + +// Maximum, minimum and default values for the parameters above +#define XAUDIO2FX_REVERB_MIN_WET_DRY_MIX 0.0f +#define XAUDIO2FX_REVERB_MIN_REFLECTIONS_DELAY 0 +#define XAUDIO2FX_REVERB_MIN_REVERB_DELAY 0 +#define XAUDIO2FX_REVERB_MIN_REAR_DELAY 0 +#define XAUDIO2FX_REVERB_MIN_POSITION 0 +#define XAUDIO2FX_REVERB_MIN_DIFFUSION 0 +#define XAUDIO2FX_REVERB_MIN_LOW_EQ_GAIN 0 +#define XAUDIO2FX_REVERB_MIN_LOW_EQ_CUTOFF 0 +#define XAUDIO2FX_REVERB_MIN_HIGH_EQ_GAIN 0 +#define XAUDIO2FX_REVERB_MIN_HIGH_EQ_CUTOFF 0 +#define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_FREQ 20.0f +#define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_MAIN -100.0f +#define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_HF -100.0f +#define XAUDIO2FX_REVERB_MIN_REFLECTIONS_GAIN -100.0f +#define XAUDIO2FX_REVERB_MIN_REVERB_GAIN -100.0f +#define XAUDIO2FX_REVERB_MIN_DECAY_TIME 0.1f +#define XAUDIO2FX_REVERB_MIN_DENSITY 0.0f +#define XAUDIO2FX_REVERB_MIN_ROOM_SIZE 0.0f + +#define XAUDIO2FX_REVERB_MAX_WET_DRY_MIX 100.0f +#define XAUDIO2FX_REVERB_MAX_REFLECTIONS_DELAY 300 +#define XAUDIO2FX_REVERB_MAX_REVERB_DELAY 85 +#define XAUDIO2FX_REVERB_MAX_REAR_DELAY 5 +#define XAUDIO2FX_REVERB_MAX_POSITION 30 +#define XAUDIO2FX_REVERB_MAX_DIFFUSION 15 +#define XAUDIO2FX_REVERB_MAX_LOW_EQ_GAIN 12 +#define XAUDIO2FX_REVERB_MAX_LOW_EQ_CUTOFF 9 +#define XAUDIO2FX_REVERB_MAX_HIGH_EQ_GAIN 8 +#define XAUDIO2FX_REVERB_MAX_HIGH_EQ_CUTOFF 14 +#define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_FREQ 20000.0f +#define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_MAIN 0.0f +#define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_HF 0.0f +#define XAUDIO2FX_REVERB_MAX_REFLECTIONS_GAIN 20.0f +#define XAUDIO2FX_REVERB_MAX_REVERB_GAIN 20.0f +#define XAUDIO2FX_REVERB_MAX_DENSITY 100.0f +#define XAUDIO2FX_REVERB_MAX_ROOM_SIZE 100.0f + +#define XAUDIO2FX_REVERB_DEFAULT_WET_DRY_MIX 100.0f +#define XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_DELAY 5 +#define XAUDIO2FX_REVERB_DEFAULT_REVERB_DELAY 5 +#define XAUDIO2FX_REVERB_DEFAULT_REAR_DELAY 5 +#define XAUDIO2FX_REVERB_DEFAULT_POSITION 6 +#define XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX 27 +#define XAUDIO2FX_REVERB_DEFAULT_EARLY_DIFFUSION 8 +#define XAUDIO2FX_REVERB_DEFAULT_LATE_DIFFUSION 8 +#define XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_GAIN 8 +#define XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_CUTOFF 4 +#define XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_GAIN 8 +#define XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_CUTOFF 4 +#define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_FREQ 5000.0f +#define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_MAIN 0.0f +#define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_HF 0.0f +#define XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_GAIN 0.0f +#define XAUDIO2FX_REVERB_DEFAULT_REVERB_GAIN 0.0f +#define XAUDIO2FX_REVERB_DEFAULT_DECAY_TIME 1.0f +#define XAUDIO2FX_REVERB_DEFAULT_DENSITY 100.0f +#define XAUDIO2FX_REVERB_DEFAULT_ROOM_SIZE 100.0f + + +// XAUDIO2FX_REVERB_I3DL2_PARAMETERS: Parameter set compliant with the I3DL2 standard + +typedef struct XAUDIO2FX_REVERB_I3DL2_PARAMETERS +{ + // ratio of wet (processed) signal to dry (original) signal + float WetDryMix; // [0, 100] (percentage) + + // Standard I3DL2 parameters + INT32 Room; // [-10000, 0] in mB (hundredths of decibels) + INT32 RoomHF; // [-10000, 0] in mB (hundredths of decibels) + float RoomRolloffFactor; // [0.0, 10.0] + float DecayTime; // [0.1, 20.0] in seconds + float DecayHFRatio; // [0.1, 2.0] + INT32 Reflections; // [-10000, 1000] in mB (hundredths of decibels) + float ReflectionsDelay; // [0.0, 0.3] in seconds + INT32 Reverb; // [-10000, 2000] in mB (hundredths of decibels) + float ReverbDelay; // [0.0, 0.1] in seconds + float Diffusion; // [0.0, 100.0] (percentage) + float Density; // [0.0, 100.0] (percentage) + float HFReference; // [20.0, 20000.0] in Hz +} XAUDIO2FX_REVERB_I3DL2_PARAMETERS; + + +// ReverbConvertI3DL2ToNative: Utility function to map from I3DL2 to native parameters + +__inline void ReverbConvertI3DL2ToNative +( + __in const XAUDIO2FX_REVERB_I3DL2_PARAMETERS* pI3DL2, + __out XAUDIO2FX_REVERB_PARAMETERS* pNative +) +{ + float reflectionsDelay; + float reverbDelay; + + // RoomRolloffFactor is ignored + + // These parameters have no equivalent in I3DL2 + pNative->RearDelay = XAUDIO2FX_REVERB_DEFAULT_REAR_DELAY; // 5 + pNative->PositionLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION; // 6 + pNative->PositionRight = XAUDIO2FX_REVERB_DEFAULT_POSITION; // 6 + pNative->PositionMatrixLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX; // 27 + pNative->PositionMatrixRight = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX; // 27 + pNative->RoomSize = XAUDIO2FX_REVERB_DEFAULT_ROOM_SIZE; // 100 + pNative->LowEQCutoff = 4; + pNative->HighEQCutoff = 6; + + // The rest of the I3DL2 parameters map to the native property set + pNative->RoomFilterMain = (float)pI3DL2->Room / 100.0f; + pNative->RoomFilterHF = (float)pI3DL2->RoomHF / 100.0f; + + if (pI3DL2->DecayHFRatio >= 1.0f) + { + INT32 index = (INT32)(-4.0 * log10(pI3DL2->DecayHFRatio)); + if (index < -8) index = -8; + pNative->LowEQGain = (BYTE)((index < 0) ? index + 8 : 8); + pNative->HighEQGain = 8; + pNative->DecayTime = pI3DL2->DecayTime * pI3DL2->DecayHFRatio; + } + else + { + INT32 index = (INT32)(4.0 * log10(pI3DL2->DecayHFRatio)); + if (index < -8) index = -8; + pNative->LowEQGain = 8; + pNative->HighEQGain = (BYTE)((index < 0) ? index + 8 : 8); + pNative->DecayTime = pI3DL2->DecayTime; + } + + reflectionsDelay = pI3DL2->ReflectionsDelay * 1000.0f; + if (reflectionsDelay >= XAUDIO2FX_REVERB_MAX_REFLECTIONS_DELAY) // 300 + { + reflectionsDelay = (float)(XAUDIO2FX_REVERB_MAX_REFLECTIONS_DELAY - 1); + } + else if (reflectionsDelay <= 1) + { + reflectionsDelay = 1; + } + pNative->ReflectionsDelay = (UINT32)reflectionsDelay; + + reverbDelay = pI3DL2->ReverbDelay * 1000.0f; + if (reverbDelay >= XAUDIO2FX_REVERB_MAX_REVERB_DELAY) // 85 + { + reverbDelay = (float)(XAUDIO2FX_REVERB_MAX_REVERB_DELAY - 1); + } + pNative->ReverbDelay = (BYTE)reverbDelay; + + pNative->ReflectionsGain = pI3DL2->Reflections / 100.0f; + pNative->ReverbGain = pI3DL2->Reverb / 100.0f; + pNative->EarlyDiffusion = (BYTE)(15.0f * pI3DL2->Diffusion / 100.0f); + pNative->LateDiffusion = pNative->EarlyDiffusion; + pNative->Density = pI3DL2->Density; + pNative->RoomFilterFreq = pI3DL2->HFReference; + + pNative->WetDryMix = pI3DL2->WetDryMix; +} + + +/************************************************************************** + * + * Standard I3DL2 reverb presets (100% wet). + * + **************************************************************************/ + +#define XAUDIO2FX_I3DL2_PRESET_DEFAULT {100,-10000, 0,0.0f, 1.00f,0.50f,-10000,0.020f,-10000,0.040f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_GENERIC {100, -1000, -100,0.0f, 1.49f,0.83f, -2602,0.007f, 200,0.011f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_PADDEDCELL {100, -1000,-6000,0.0f, 0.17f,0.10f, -1204,0.001f, 207,0.002f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_ROOM {100, -1000, -454,0.0f, 0.40f,0.83f, -1646,0.002f, 53,0.003f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_BATHROOM {100, -1000,-1200,0.0f, 1.49f,0.54f, -370,0.007f, 1030,0.011f,100.0f, 60.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_LIVINGROOM {100, -1000,-6000,0.0f, 0.50f,0.10f, -1376,0.003f, -1104,0.004f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_STONEROOM {100, -1000, -300,0.0f, 2.31f,0.64f, -711,0.012f, 83,0.017f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_AUDITORIUM {100, -1000, -476,0.0f, 4.32f,0.59f, -789,0.020f, -289,0.030f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_CONCERTHALL {100, -1000, -500,0.0f, 3.92f,0.70f, -1230,0.020f, -2,0.029f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_CAVE {100, -1000, 0,0.0f, 2.91f,1.30f, -602,0.015f, -302,0.022f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_ARENA {100, -1000, -698,0.0f, 7.24f,0.33f, -1166,0.020f, 16,0.030f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_HANGAR {100, -1000,-1000,0.0f,10.05f,0.23f, -602,0.020f, 198,0.030f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_CARPETEDHALLWAY {100, -1000,-4000,0.0f, 0.30f,0.10f, -1831,0.002f, -1630,0.030f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_HALLWAY {100, -1000, -300,0.0f, 1.49f,0.59f, -1219,0.007f, 441,0.011f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_STONECORRIDOR {100, -1000, -237,0.0f, 2.70f,0.79f, -1214,0.013f, 395,0.020f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_ALLEY {100, -1000, -270,0.0f, 1.49f,0.86f, -1204,0.007f, -4,0.011f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_FOREST {100, -1000,-3300,0.0f, 1.49f,0.54f, -2560,0.162f, -613,0.088f, 79.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_CITY {100, -1000, -800,0.0f, 1.49f,0.67f, -2273,0.007f, -2217,0.011f, 50.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_MOUNTAINS {100, -1000,-2500,0.0f, 1.49f,0.21f, -2780,0.300f, -2014,0.100f, 27.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_QUARRY {100, -1000,-1000,0.0f, 1.49f,0.83f,-10000,0.061f, 500,0.025f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_PLAIN {100, -1000,-2000,0.0f, 1.49f,0.50f, -2466,0.179f, -2514,0.100f, 21.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_PARKINGLOT {100, -1000, 0,0.0f, 1.65f,1.50f, -1363,0.008f, -1153,0.012f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_SEWERPIPE {100, -1000,-1000,0.0f, 2.81f,0.14f, 429,0.014f, 648,0.021f, 80.0f, 60.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_UNDERWATER {100, -1000,-4000,0.0f, 1.49f,0.10f, -449,0.007f, 1700,0.011f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_SMALLROOM {100, -1000, -600,0.0f, 1.10f,0.83f, -400,0.005f, 500,0.010f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_MEDIUMROOM {100, -1000, -600,0.0f, 1.30f,0.83f, -1000,0.010f, -200,0.020f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_LARGEROOM {100, -1000, -600,0.0f, 1.50f,0.83f, -1600,0.020f, -1000,0.040f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_MEDIUMHALL {100, -1000, -600,0.0f, 1.80f,0.70f, -1300,0.015f, -800,0.030f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_LARGEHALL {100, -1000, -600,0.0f, 1.80f,0.70f, -2000,0.030f, -1400,0.060f,100.0f,100.0f,5000.0f} +#define XAUDIO2FX_I3DL2_PRESET_PLATE {100, -1000, -200,0.0f, 1.30f,0.90f, 0,0.002f, 0,0.010f,100.0f, 75.0f,5000.0f} + + +// Undo the #pragma pack(push, 1) at the top of this file +#pragma pack(pop) + +#endif // #ifndef GUID_DEFS_ONLY +#endif // #ifndef __XAUDIO2FX_INCLUDED__ diff --git a/dxsdk/Include/XDSP.h b/dxsdk/Include/XDSP.h new file mode 100644 index 0000000..6ed0dc5 --- /dev/null +++ b/dxsdk/Include/XDSP.h @@ -0,0 +1,754 @@ +/*-========================================================================-_ + | - XDSP - | + | Copyright (c) Microsoft Corporation. All rights reserved. | + |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| + |PROJECT: XDSP MODEL: Unmanaged User-mode | + |VERSION: 1.2 EXCEPT: No Exceptions | + |CLASS: N / A MINREQ: WinXP, Xbox360 | + |BASE: N / A DIALECT: MSC++ 14.00 | + |>------------------------------------------------------------------------<| + | DUTY: DSP functions with CPU extension specific optimizations | + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + NOTES: + 1. Definition of terms: + DSP: Digital Signal Processing. + FFT: Fast Fourier Transform. + Frame: A block of samples, one per channel, + to be played simultaneously. + + 2. All buffer parameters must be 16-byte aligned. + + 3. All FFT functions support only FLOAT32 audio. */ + +#pragma once +//---------------------------------------------------// +#include // general windows types +#include // trigonometric functions +#if defined(_XBOX) // SIMD intrinsics + #include +#else + #include +#endif + + +//-------------------------------------------------------------// +// assertion +#if !defined(DSPASSERT) + #if DBG + #define DSPASSERT(exp) if (!(exp)) { OutputDebugStringA("XDSP ASSERT: " #exp ", {" __FUNCTION__ "}\n"); __debugbreak(); } + #else + #define DSPASSERT(exp) __assume(exp) + #endif +#endif + +// true if n is a power of 2 +#if !defined(ISPOWEROF2) + #define ISPOWEROF2(n) ( ((n)&((n)-1)) == 0 && (n) != 0 ) +#endif + + +//-----------------------------------------------------------// +namespace XDSP { +#pragma warning(push) +#pragma warning(disable: 4328 4640) // disable "indirection alignment of formal parameter", "construction of local static object is not thread-safe" compile warnings + + +// Helper functions, used by the FFT functions. +// The application need not call them directly. + + // primitive types + typedef __m128 XVECTOR; + typedef XVECTOR& XVECTORREF; + typedef const XVECTOR& XVECTORREFC; + + + // Parallel multiplication of four complex numbers, assuming + // real and imaginary values are stored in separate vectors. + __forceinline void vmulComplex (__out XVECTORREF rResult, __out XVECTORREF iResult, __in XVECTORREFC r1, __in XVECTORREFC i1, __in XVECTORREFC r2, __in XVECTORREFC i2) + { + // (r1, i1) * (r2, i2) = (r1r2 - i1i2, r1i2 + r2i1) + XVECTOR vi1i2 = _mm_mul_ps(i1, i2); + XVECTOR vr1r2 = _mm_mul_ps(r1, r2); + XVECTOR vr1i2 = _mm_mul_ps(r1, i2); + XVECTOR vr2i1 = _mm_mul_ps(r2, i1); + rResult = _mm_sub_ps(vr1r2, vi1i2); // real: (r1*r2 - i1*i2) + iResult = _mm_add_ps(vr1i2, vr2i1); // imaginary: (r1*i2 + r2*i1) + } + __forceinline void vmulComplex (__inout XVECTORREF r1, __inout XVECTORREF i1, __in XVECTORREFC r2, __in XVECTORREFC i2) + { + // (r1, i1) * (r2, i2) = (r1r2 - i1i2, r1i2 + r2i1) + XVECTOR vi1i2 = _mm_mul_ps(i1, i2); + XVECTOR vr1r2 = _mm_mul_ps(r1, r2); + XVECTOR vr1i2 = _mm_mul_ps(r1, i2); + XVECTOR vr2i1 = _mm_mul_ps(r2, i1); + r1 = _mm_sub_ps(vr1r2, vi1i2); // real: (r1*r2 - i1*i2) + i1 = _mm_add_ps(vr1i2, vr2i1); // imaginary: (r1*i2 + r2*i1) + } + + + // Radix-4 decimation-in-time FFT butterfly. + // This version assumes that all four elements of the butterfly are + // adjacent in a single vector. + // + // Compute the product of the complex input vector and the + // 4-element DFT matrix: + // | 1 1 1 1 | | (r1X,i1X) | + // | 1 -j -1 j | | (r1Y,i1Y) | + // | 1 -1 1 -1 | | (r1Z,i1Z) | + // | 1 j -1 -j | | (r1W,i1W) | + // + // This matrix can be decomposed into two simpler ones to reduce the + // number of additions needed. The decomposed matrices look like this: + // | 1 0 1 0 | | 1 0 1 0 | + // | 0 1 0 -j | | 1 0 -1 0 | + // | 1 0 -1 0 | | 0 1 0 1 | + // | 0 1 0 j | | 0 1 0 -1 | + // + // Combine as follows: + // | 1 0 1 0 | | (r1X,i1X) | | (r1X + r1Z, i1X + i1Z) | + // Temp = | 1 0 -1 0 | * | (r1Y,i1Y) | = | (r1X - r1Z, i1X - i1Z) | + // | 0 1 0 1 | | (r1Z,i1Z) | | (r1Y + r1W, i1Y + i1W) | + // | 0 1 0 -1 | | (r1W,i1W) | | (r1Y - r1W, i1Y - i1W) | + // + // | 1 0 1 0 | | (rTempX,iTempX) | | (rTempX + rTempZ, iTempX + iTempZ) | + // Result = | 0 1 0 -j | * | (rTempY,iTempY) | = | (rTempY + iTempW, iTempY - rTempW) | + // | 1 0 -1 0 | | (rTempZ,iTempZ) | | (rTempX - rTempZ, iTempX - iTempZ) | + // | 0 1 0 j | | (rTempW,iTempW) | | (rTempY - iTempW, iTempY + rTempW) | + __forceinline void ButterflyDIT4_1 (__inout XVECTORREF r1, __inout XVECTORREF i1) + { + // sign constants for radix-4 butterflies + const static XVECTOR vDFT4SignBits1 = { 0.0f, -0.0f, 0.0f, -0.0f }; + const static XVECTOR vDFT4SignBits2 = { 0.0f, 0.0f, -0.0f, -0.0f }; + const static XVECTOR vDFT4SignBits3 = { 0.0f, -0.0f, -0.0f, 0.0f }; + + + // calculating Temp + XVECTOR rTemp = _mm_add_ps( _mm_shuffle_ps(r1, r1, _MM_SHUFFLE(1, 1, 0, 0)), // [r1X| r1X|r1Y| r1Y] + + _mm_xor_ps(_mm_shuffle_ps(r1, r1, _MM_SHUFFLE(3, 3, 2, 2)), vDFT4SignBits1) ); // [r1Z|-r1Z|r1W|-r1W] + XVECTOR iTemp = _mm_add_ps( _mm_shuffle_ps(i1, i1, _MM_SHUFFLE(1, 1, 0, 0)), // [i1X| i1X|i1Y| i1Y] + + _mm_xor_ps(_mm_shuffle_ps(i1, i1, _MM_SHUFFLE(3, 3, 2, 2)), vDFT4SignBits1) ); // [i1Z|-i1Z|i1W|-i1W] + + // calculating Result + XVECTOR rZrWiZiW = _mm_shuffle_ps(rTemp, iTemp, _MM_SHUFFLE(3, 2, 3, 2)); // [rTempZ|rTempW|iTempZ|iTempW] + XVECTOR rZiWrZiW = _mm_shuffle_ps(rZrWiZiW, rZrWiZiW, _MM_SHUFFLE(3, 0, 3, 0)); // [rTempZ|iTempW|rTempZ|iTempW] + XVECTOR iZrWiZrW = _mm_shuffle_ps(rZrWiZiW, rZrWiZiW, _MM_SHUFFLE(1, 2, 1, 2)); // [rTempZ|iTempW|rTempZ|iTempW] + r1 = _mm_add_ps( _mm_shuffle_ps(rTemp, rTemp, _MM_SHUFFLE(1, 0, 1, 0)), // [rTempX| rTempY| rTempX| rTempY] + + _mm_xor_ps(rZiWrZiW, vDFT4SignBits2) ); // [rTempZ| iTempW|-rTempZ|-iTempW] + i1 = _mm_add_ps( _mm_shuffle_ps(iTemp, iTemp, _MM_SHUFFLE(1, 0, 1, 0)), // [iTempX| iTempY| iTempX| iTempY] + + _mm_xor_ps(iZrWiZrW, vDFT4SignBits3) ); // [iTempZ|-rTempW|-iTempZ| rTempW] + } + + // Radix-4 decimation-in-time FFT butterfly. + // This version assumes that elements of the butterfly are + // in different vectors, so that each vector in the input + // contains elements from four different butterflies. + // The four separate butterflies are processed in parallel. + // + // The calculations here are the same as the ones in the single-vector + // radix-4 DFT, but instead of being done on a single vector (X,Y,Z,W) + // they are done in parallel on sixteen independent complex values. + // There is no interdependence between the vector elements: + // | 1 0 1 0 | | (rIn0,iIn0) | | (rIn0 + rIn2, iIn0 + iIn2) | + // | 1 0 -1 0 | * | (rIn1,iIn1) | = Temp = | (rIn0 - rIn2, iIn0 - iIn2) | + // | 0 1 0 1 | | (rIn2,iIn2) | | (rIn1 + rIn3, iIn1 + iIn3) | + // | 0 1 0 -1 | | (rIn3,iIn3) | | (rIn1 - rIn3, iIn1 - iIn3) | + // + // | 1 0 1 0 | | (rTemp0,iTemp0) | | (rTemp0 + rTemp2, iTemp0 + iTemp2) | + // Result = | 0 1 0 -j | * | (rTemp1,iTemp1) | = | (rTemp1 + iTemp3, iTemp1 - rTemp3) | + // | 1 0 -1 0 | | (rTemp2,iTemp2) | | (rTemp0 - rTemp2, iTemp0 - iTemp2) | + // | 0 1 0 j | | (rTemp3,iTemp3) | | (rTemp1 - iTemp3, iTemp1 + rTemp3) | + __forceinline void ButterflyDIT4_4 (__inout XVECTORREF r0, + __inout XVECTORREF r1, + __inout XVECTORREF r2, + __inout XVECTORREF r3, + __inout XVECTORREF i0, + __inout XVECTORREF i1, + __inout XVECTORREF i2, + __inout XVECTORREF i3, + __in_ecount(uStride*4) const XVECTOR* __restrict pUnityTableReal, + __in_ecount(uStride*4) const XVECTOR* __restrict pUnityTableImaginary, + const UINT32 uStride, const BOOL fLast) + { + DSPASSERT(pUnityTableReal != NULL); + DSPASSERT(pUnityTableImaginary != NULL); + DSPASSERT((UINT_PTR)pUnityTableReal % 16 == 0); + DSPASSERT((UINT_PTR)pUnityTableImaginary % 16 == 0); + DSPASSERT(ISPOWEROF2(uStride)); + + XVECTOR rTemp0, rTemp1, rTemp2, rTemp3, rTemp4, rTemp5, rTemp6, rTemp7; + XVECTOR iTemp0, iTemp1, iTemp2, iTemp3, iTemp4, iTemp5, iTemp6, iTemp7; + + + // calculating Temp + rTemp0 = _mm_add_ps(r0, r2); iTemp0 = _mm_add_ps(i0, i2); + rTemp2 = _mm_add_ps(r1, r3); iTemp2 = _mm_add_ps(i1, i3); + rTemp1 = _mm_sub_ps(r0, r2); iTemp1 = _mm_sub_ps(i0, i2); + rTemp3 = _mm_sub_ps(r1, r3); iTemp3 = _mm_sub_ps(i1, i3); + rTemp4 = _mm_add_ps(rTemp0, rTemp2); iTemp4 = _mm_add_ps(iTemp0, iTemp2); + rTemp5 = _mm_add_ps(rTemp1, iTemp3); iTemp5 = _mm_sub_ps(iTemp1, rTemp3); + rTemp6 = _mm_sub_ps(rTemp0, rTemp2); iTemp6 = _mm_sub_ps(iTemp0, iTemp2); + rTemp7 = _mm_sub_ps(rTemp1, iTemp3); iTemp7 = _mm_add_ps(iTemp1, rTemp3); + + // calculating Result + // vmulComplex(rTemp0, iTemp0, rTemp0, iTemp0, pUnityTableReal[0], pUnityTableImaginary[0]); // first one is always trivial + vmulComplex(rTemp5, iTemp5, pUnityTableReal[uStride], pUnityTableImaginary[uStride]); + vmulComplex(rTemp6, iTemp6, pUnityTableReal[uStride*2], pUnityTableImaginary[uStride*2]); + vmulComplex(rTemp7, iTemp7, pUnityTableReal[uStride*3], pUnityTableImaginary[uStride*3]); + if (fLast) { + ButterflyDIT4_1(rTemp4, iTemp4); + ButterflyDIT4_1(rTemp5, iTemp5); + ButterflyDIT4_1(rTemp6, iTemp6); + ButterflyDIT4_1(rTemp7, iTemp7); + } + + + r0 = rTemp4; i0 = iTemp4; + r1 = rTemp5; i1 = iTemp5; + r2 = rTemp6; i2 = iTemp6; + r3 = rTemp7; i3 = iTemp7; + } + +//-------------------------------------------------------// + + //// + // DESCRIPTION: + // 4-sample FFT. + // + // PARAMETERS: + // pReal - [inout] real components, must have at least uCount elements + // pImaginary - [inout] imaginary components, must have at least uCount elements + // uCount - [in] number of FFT iterations + // + // RETURN VALUE: + // void + //// + __forceinline void FFT4 (__inout_ecount(uCount) XVECTOR* __restrict pReal, __inout_ecount(uCount) XVECTOR* __restrict pImaginary, const UINT32 uCount=1) + { + DSPASSERT(pReal != NULL); + DSPASSERT(pImaginary != NULL); + DSPASSERT((UINT_PTR)pReal % 16 == 0); + DSPASSERT((UINT_PTR)pImaginary % 16 == 0); + DSPASSERT(ISPOWEROF2(uCount)); + + for (UINT32 uIndex=0; uIndex 16 + // uCount - [in] number of FFT iterations + // + // RETURN VALUE: + // void + //// + inline void FFT (__inout_ecount((uLength*uCount)/4) XVECTOR* __restrict pReal, __inout_ecount((uLength*uCount)/4) XVECTOR* __restrict pImaginary, __in_ecount(uLength*uCount) const XVECTOR* __restrict pUnityTable, const UINT32 uLength, const UINT32 uCount=1) + { + DSPASSERT(pReal != NULL); + DSPASSERT(pImaginary != NULL); + DSPASSERT(pUnityTable != NULL); + DSPASSERT((UINT_PTR)pReal % 16 == 0); + DSPASSERT((UINT_PTR)pImaginary % 16 == 0); + DSPASSERT((UINT_PTR)pUnityTable % 16 == 0); + DSPASSERT(uLength > 16); + DSPASSERT(ISPOWEROF2(uLength)); + DSPASSERT(ISPOWEROF2(uCount)); + + const XVECTOR* __restrict pUnityTableReal = pUnityTable; + const XVECTOR* __restrict pUnityTableImaginary = pUnityTable + (uLength>>2); + const UINT32 uTotal = uCount * uLength; + const UINT32 uTotal_vectors = uTotal >> 2; + const UINT32 uStage_vectors = uLength >> 2; + const UINT32 uStage_vectors_mask = uStage_vectors - 1; + const UINT32 uStride = uLength >> 4; // stride between butterfly elements + const UINT32 uStrideMask = uStride - 1; + const UINT32 uStride2 = uStride * 2; + const UINT32 uStride3 = uStride * 3; + const UINT32 uStrideInvMask = ~uStrideMask; + + + for (UINT32 uIndex=0; uIndex<(uTotal_vectors>>2); ++uIndex) { + const UINT32 n = ((uIndex & uStrideInvMask) << 2) + (uIndex & uStrideMask); + ButterflyDIT4_4(pReal[n], + pReal[n + uStride], + pReal[n + uStride2], + pReal[n + uStride3], + pImaginary[n ], + pImaginary[n + uStride], + pImaginary[n + uStride2], + pImaginary[n + uStride3], + pUnityTableReal + (n & uStage_vectors_mask), + pUnityTableImaginary + (n & uStage_vectors_mask), + uStride, FALSE); + } + + + if (uLength > 16*4) { + FFT(pReal, pImaginary, pUnityTable+(uLength>>1), uLength>>2, uCount*4); + } else if (uLength == 16*4) { + FFT16(pReal, pImaginary, uCount*4); + } else if (uLength == 8*4) { + FFT8(pReal, pImaginary, uCount*4); + } else if (uLength == 4*4) { + FFT4(pReal, pImaginary, uCount*4); + } + } + +//--------------------------------------------------------------------------// + //// + // DESCRIPTION: + // Initializes unity roots lookup table used by FFT functions. + // Once initialized, the table need not be initialized again unless a + // different FFT length is desired. + // + // REMARKS: + // The unity tables of FFT length 16 and below are hard coded into the + // respective FFT functions and so need not be initialized. + // + // PARAMETERS: + // pUnityTable - [out] unity table, receives unity roots lookup table, must have at least uLength elements + // uLength - [in] FFT length in frames, must be a power of 2 > 16 + // + // RETURN VALUE: + // void + //// +inline void FFTInitializeUnityTable (__out_ecount(uLength) XVECTOR* __restrict pUnityTable, UINT32 uLength) +{ + DSPASSERT(pUnityTable != NULL); + DSPASSERT(uLength > 16); + DSPASSERT(ISPOWEROF2(uLength)); + + FLOAT32* __restrict pfUnityTable = (FLOAT32* __restrict)pUnityTable; + + + // initialize unity table for recursive FFT lengths: uLength, uLength/4, uLength/16... > 16 + do { + FLOAT32 flStep = 6.283185307f / uLength; // 2PI / FFT length + uLength >>= 2; + + // pUnityTable[0 to uLength*4-1] contains real components for current FFT length + // pUnityTable[uLength*4 to uLength*8-1] contains imaginary components for current FFT length + for (UINT32 i=0; i<4; ++i) { + for (UINT32 j=0; j 16); +} + + + //// + // DESCRIPTION: + // The FFT functions generate output in bit reversed order. + // Use this function to re-arrange them into order of increasing frequency. + // + // REMARKS: + // + // PARAMETERS: + // pOutput - [out] output buffer, receives samples in order of increasing frequency, cannot overlap pInput, must have at least (1<= 2 + // + // RETURN VALUE: + // void + //// +inline void FFTUnswizzle (__out_ecount((1<= 2); + + FLOAT32* __restrict pfOutput = (FLOAT32* __restrict)pOutput; + const FLOAT32* __restrict pfInput = (const FLOAT32* __restrict)pInput; + const UINT32 uLength = UINT32(1 << uLog2Length); + + + if ((uLog2Length & 0x1) == 0) { + // even powers of two + for (UINT32 uIndex=0; uIndex> 2 ) | ( (n & 0x33333333) << 2 ); + n = ( (n & 0xf0f0f0f0) >> 4 ) | ( (n & 0x0f0f0f0f) << 4 ); + n = ( (n & 0xff00ff00) >> 8 ) | ( (n & 0x00ff00ff) << 8 ); + n = ( (n & 0xffff0000) >> 16 ) | ( (n & 0x0000ffff) << 16 ); + n >>= (32 - uLog2Length); + pfOutput[n] = pfInput[uIndex]; + } + } else { + // odd powers of two + for (UINT32 uIndex=0; uIndex>3); + n = ( (n & 0xcccccccc) >> 2 ) | ( (n & 0x33333333) << 2 ); + n = ( (n & 0xf0f0f0f0) >> 4 ) | ( (n & 0x0f0f0f0f) << 4 ); + n = ( (n & 0xff00ff00) >> 8 ) | ( (n & 0x00ff00ff) << 8 ); + n = ( (n & 0xffff0000) >> 16 ) | ( (n & 0x0000ffff) << 16 ); + n >>= (32 - (uLog2Length-3)); + n |= ((uIndex & 0x7) << (uLog2Length - 3)); + pfOutput[n] = pfInput[uIndex]; + } + } +} + + + //// + // DESCRIPTION: + // Convert complex components to polar form. + // + // PARAMETERS: + // pOutput - [out] output buffer, receives samples in polar form, must have at least uLength/4 elements + // pInputReal - [in] input buffer (real components), must have at least uLength/4 elements + // pInputImaginary - [in] input buffer (imaginary components), must have at least uLength/4 elements + // uLength - [in] FFT length in samples, must be a power of 2 >= 4 + // + // RETURN VALUE: + // void + //// +inline void FFTPolar (__out_ecount(uLength/4) XVECTOR* __restrict pOutput, __in_ecount(uLength/4) const XVECTOR* __restrict pInputReal, __in_ecount(uLength/4) const XVECTOR* __restrict pInputImaginary, const UINT32 uLength) +{ + DSPASSERT(pOutput != NULL); + DSPASSERT(pInputReal != NULL); + DSPASSERT(pInputImaginary != NULL); + DSPASSERT(uLength >= 4); + DSPASSERT(ISPOWEROF2(uLength)); + + FLOAT32 flOneOverLength = 1.0f / uLength; + + + // result = sqrtf((real/uLength)^2 + (imaginary/uLength)^2) * 2 + XVECTOR vOneOverLength = _mm_set_ps1(flOneOverLength); + + for (UINT32 uIndex=0; uIndex<(uLength>>2); ++uIndex) { + XVECTOR vReal = _mm_mul_ps(pInputReal[uIndex], vOneOverLength); + XVECTOR vImaginary = _mm_mul_ps(pInputImaginary[uIndex], vOneOverLength); + XVECTOR vRR = _mm_mul_ps(vReal, vReal); + XVECTOR vII = _mm_mul_ps(vImaginary, vImaginary); + XVECTOR vRRplusII = _mm_add_ps(vRR, vII); + XVECTOR vTotal = _mm_sqrt_ps(vRRplusII); + pOutput[uIndex] = _mm_add_ps(vTotal, vTotal); + } +} + + + + + +//--------------------------------------------------------------------------// + //// + // DESCRIPTION: + // Deinterleaves audio samples such that all samples corresponding to + + // + // REMARKS: + // For example, audio of the form [LRLRLR] becomes [LLLRRR]. + // + // PARAMETERS: + // pOutput - [out] output buffer, receives samples in deinterleaved form, cannot overlap pInput, must have at least (uChannelCount*uFrameCount)/4 elements + // pInput - [in] input buffer, cannot overlap pOutput, must have at least (uChannelCount*uFrameCount)/4 elements + // uChannelCount - [in] number of channels, must be > 1 + // uFrameCount - [in] number of frames of valid data, must be > 0 + // + // RETURN VALUE: + // void + //// +inline void Deinterleave (__out_ecount((uChannelCount*uFrameCount)/4) XVECTOR* __restrict pOutput, __in_ecount((uChannelCount*uFrameCount)/4) const XVECTOR* __restrict pInput, const UINT32 uChannelCount, const UINT32 uFrameCount) +{ + DSPASSERT(pOutput != NULL); + DSPASSERT(pInput != NULL); + DSPASSERT(uChannelCount > 1); + DSPASSERT(uFrameCount > 0); + + FLOAT32* __restrict pfOutput = (FLOAT32* __restrict)pOutput; + const FLOAT32* __restrict pfInput = (const FLOAT32* __restrict)pInput; + + + for (UINT32 uChannel=0; uChannel 1 + // uFrameCount - [in] number of frames of valid data, must be > 0 + // + // RETURN VALUE: + // void + //// +inline void Interleave (__out_ecount((uChannelCount*uFrameCount)/4) XVECTOR* __restrict pOutput, __in_ecount((uChannelCount*uFrameCount)/4) const XVECTOR* __restrict pInput, const UINT32 uChannelCount, const UINT32 uFrameCount) +{ + DSPASSERT(pOutput != NULL); + DSPASSERT(pInput != NULL); + DSPASSERT(uChannelCount > 1); + DSPASSERT(uFrameCount > 0); + + FLOAT32* __restrict pfOutput = (FLOAT32* __restrict)pOutput; + const FLOAT32* __restrict pfInput = (const FLOAT32* __restrict)pInput; + + + for (UINT32 uChannel=0; uChannel 0 && uChannelCount <= 6); + DSPASSERT(uLog2Length >= 2 && uLog2Length <= 9); + + XVECTOR vRealTemp[768]; + XVECTOR vImaginaryTemp[768]; + const UINT32 uLength = UINT32(1 << uLog2Length); + + + if (uChannelCount > 1) { + Deinterleave(vRealTemp, pReal, uChannelCount, uLength); + } else { + CopyMemory(vRealTemp, pReal, (uLength>>2)*sizeof(XVECTOR)); + } + for (UINT32 u=0; u>2); u++) { + vImaginaryTemp[u] = _mm_setzero_ps(); + } + + if (uLength > 16) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)], pUnityTable, uLength); + } + } else if (uLength == 16) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)]); + } + } else if (uLength == 8) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)]); + } + } else if (uLength == 4) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)]); + } + } + + for (UINT32 uChannel=0; uChannel>2)], &vRealTemp[uChannel*(uLength>>2)], uLog2Length); + FFTUnswizzle(&pImaginary[uChannel*(uLength>>2)], &vImaginaryTemp[uChannel*(uLength>>2)], uLog2Length); + } +} + + + //// + // DESCRIPTION: + // This function applies a 2^N-sample inverse FFT. + // Audio is interleaved if multichannel. + // + // PARAMETERS: + // pReal - [inout] real components, must have at least (1< 0 + // uLog2Length - [in] LOG (base 2) of FFT length in frames, must within [2, 10] + // + // RETURN VALUE: + // void + //// +inline void IFFTDeinterleaved (__inout_ecount((1< 0 && uChannelCount <= 6); + DSPASSERT(uLog2Length >= 2 && uLog2Length <= 9); + + XVECTOR vRealTemp[768]; + XVECTOR vImaginaryTemp[768]; + const UINT32 uLength = UINT32(1 << uLog2Length); + + + const XVECTOR vRnp = _mm_set_ps1(1.0f/uLength); + const XVECTOR vRnm = _mm_set_ps1(-1.0f/uLength); + for (UINT32 u=0; u>2); u++) { + vRealTemp[u] = _mm_mul_ps(pReal[u], vRnp); + vImaginaryTemp[u] = _mm_mul_ps(pImaginary[u], vRnm); + } + + if (uLength > 16) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)], pUnityTable, uLength); + } + } else if (uLength == 16) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)]); + } + } else if (uLength == 8) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)]); + } + } else if (uLength == 4) { + for (UINT32 uChannel=0; uChannel>2)], &vImaginaryTemp[uChannel*(uLength>>2)]); + } + } + + for (UINT32 uChannel=0; uChannel>2)], &vRealTemp[uChannel*(uLength>>2)], uLog2Length); + } + if (uChannelCount > 1) { + Interleave(pReal, vImaginaryTemp, uChannelCount, uLength); + } else { + CopyMemory(pReal, vImaginaryTemp, (uLength>>2)*sizeof(XVECTOR)); + } +} + + +#pragma warning(pop) +}; // namespace XDSP +//---------------------------------<-EOF->----------------------------------// + diff --git a/dxsdk/Include/XInput.h b/dxsdk/Include/XInput.h new file mode 100644 index 0000000..c50a5cb --- /dev/null +++ b/dxsdk/Include/XInput.h @@ -0,0 +1,283 @@ +/*************************************************************************** +* * +* XInput.h -- This module defines XBOX controller APIs * +* and constansts for the Windows platform. * +* * +* Copyright (c) Microsoft Corp. All rights reserved. * +* * +***************************************************************************/ +#ifndef _XINPUT_H_ +#define _XINPUT_H_ + +#include + +// Current name of the DLL shipped in the same SDK as this header. +// The name reflects the current version +#ifndef XINPUT_USE_9_1_0 +#define XINPUT_DLL_A "xinput1_3.dll" +#define XINPUT_DLL_W L"xinput1_3.dll" +#else +#define XINPUT_DLL_A "xinput9_1_0.dll" +#define XINPUT_DLL_W L"xinput9_1_0.dll" +#endif +#ifdef UNICODE + #define XINPUT_DLL XINPUT_DLL_W +#else + #define XINPUT_DLL XINPUT_DLL_A +#endif + +// +// Device types available in XINPUT_CAPABILITIES +// +#define XINPUT_DEVTYPE_GAMEPAD 0x01 + +// +// Device subtypes available in XINPUT_CAPABILITIES +// +#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01 + +#ifndef XINPUT_USE_9_1_0 + +#define XINPUT_DEVSUBTYPE_WHEEL 0x02 +#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03 +#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04 +#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05 +#define XINPUT_DEVSUBTYPE_GUITAR 0x06 +#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08 + +#endif // !XINPUT_USE_9_1_0 + + + +// +// Flags for XINPUT_CAPABILITIES +// +#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004 + +// +// Constants for gamepad buttons +// +#define XINPUT_GAMEPAD_DPAD_UP 0x0001 +#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 +#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 +#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 +#define XINPUT_GAMEPAD_START 0x0010 +#define XINPUT_GAMEPAD_BACK 0x0020 +#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 +#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 +#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 +#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 +#define XINPUT_GAMEPAD_A 0x1000 +#define XINPUT_GAMEPAD_B 0x2000 +#define XINPUT_GAMEPAD_X 0x4000 +#define XINPUT_GAMEPAD_Y 0x8000 + + +// +// Gamepad thresholds +// +#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 +#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 +#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30 + +// +// Flags to pass to XInputGetCapabilities +// +#define XINPUT_FLAG_GAMEPAD 0x00000001 + + +#ifndef XINPUT_USE_9_1_0 + +// +// Devices that support batteries +// +#define BATTERY_DEVTYPE_GAMEPAD 0x00 +#define BATTERY_DEVTYPE_HEADSET 0x01 + +// +// Flags for battery status level +// +#define BATTERY_TYPE_DISCONNECTED 0x00 // This device is not connected +#define BATTERY_TYPE_WIRED 0x01 // Wired device, no battery +#define BATTERY_TYPE_ALKALINE 0x02 // Alkaline battery source +#define BATTERY_TYPE_NIMH 0x03 // Nickel Metal Hydride battery source +#define BATTERY_TYPE_UNKNOWN 0xFF // Cannot determine the battery type + +// These are only valid for wireless, connected devices, with known battery types +// The amount of use time remaining depends on the type of device. +#define BATTERY_LEVEL_EMPTY 0x00 +#define BATTERY_LEVEL_LOW 0x01 +#define BATTERY_LEVEL_MEDIUM 0x02 +#define BATTERY_LEVEL_FULL 0x03 + +// User index definitions +#define XUSER_MAX_COUNT 4 + +#define XUSER_INDEX_ANY 0x000000FF + + +// +// Codes returned for the gamepad keystroke +// + +#define VK_PAD_A 0x5800 +#define VK_PAD_B 0x5801 +#define VK_PAD_X 0x5802 +#define VK_PAD_Y 0x5803 +#define VK_PAD_RSHOULDER 0x5804 +#define VK_PAD_LSHOULDER 0x5805 +#define VK_PAD_LTRIGGER 0x5806 +#define VK_PAD_RTRIGGER 0x5807 + +#define VK_PAD_DPAD_UP 0x5810 +#define VK_PAD_DPAD_DOWN 0x5811 +#define VK_PAD_DPAD_LEFT 0x5812 +#define VK_PAD_DPAD_RIGHT 0x5813 +#define VK_PAD_START 0x5814 +#define VK_PAD_BACK 0x5815 +#define VK_PAD_LTHUMB_PRESS 0x5816 +#define VK_PAD_RTHUMB_PRESS 0x5817 + +#define VK_PAD_LTHUMB_UP 0x5820 +#define VK_PAD_LTHUMB_DOWN 0x5821 +#define VK_PAD_LTHUMB_RIGHT 0x5822 +#define VK_PAD_LTHUMB_LEFT 0x5823 +#define VK_PAD_LTHUMB_UPLEFT 0x5824 +#define VK_PAD_LTHUMB_UPRIGHT 0x5825 +#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826 +#define VK_PAD_LTHUMB_DOWNLEFT 0x5827 + +#define VK_PAD_RTHUMB_UP 0x5830 +#define VK_PAD_RTHUMB_DOWN 0x5831 +#define VK_PAD_RTHUMB_RIGHT 0x5832 +#define VK_PAD_RTHUMB_LEFT 0x5833 +#define VK_PAD_RTHUMB_UPLEFT 0x5834 +#define VK_PAD_RTHUMB_UPRIGHT 0x5835 +#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836 +#define VK_PAD_RTHUMB_DOWNLEFT 0x5837 + +// +// Flags used in XINPUT_KEYSTROKE +// +#define XINPUT_KEYSTROKE_KEYDOWN 0x0001 +#define XINPUT_KEYSTROKE_KEYUP 0x0002 +#define XINPUT_KEYSTROKE_REPEAT 0x0004 + +#endif //!XINPUT_USE_9_1_0 + +// +// Structures used by XInput APIs +// +typedef struct _XINPUT_GAMEPAD +{ + WORD wButtons; + BYTE bLeftTrigger; + BYTE bRightTrigger; + SHORT sThumbLX; + SHORT sThumbLY; + SHORT sThumbRX; + SHORT sThumbRY; +} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD; + +typedef struct _XINPUT_STATE +{ + DWORD dwPacketNumber; + XINPUT_GAMEPAD Gamepad; +} XINPUT_STATE, *PXINPUT_STATE; + +typedef struct _XINPUT_VIBRATION +{ + WORD wLeftMotorSpeed; + WORD wRightMotorSpeed; +} XINPUT_VIBRATION, *PXINPUT_VIBRATION; + +typedef struct _XINPUT_CAPABILITIES +{ + BYTE Type; + BYTE SubType; + WORD Flags; + XINPUT_GAMEPAD Gamepad; + XINPUT_VIBRATION Vibration; +} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES; + +#ifndef XINPUT_USE_9_1_0 + +typedef struct _XINPUT_BATTERY_INFORMATION +{ + BYTE BatteryType; + BYTE BatteryLevel; +} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION; + +typedef struct _XINPUT_KEYSTROKE +{ + WORD VirtualKey; + WCHAR Unicode; + WORD Flags; + BYTE UserIndex; + BYTE HidCode; +} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE; + +#endif // !XINPUT_USE_9_1_0 + +// +// XInput APIs +// +#ifdef __cplusplus +extern "C" { +#endif + +DWORD WINAPI XInputGetState +( + __in DWORD dwUserIndex, // Index of the gamer associated with the device + __out XINPUT_STATE* pState // Receives the current state +); + +DWORD WINAPI XInputSetState +( + __in DWORD dwUserIndex, // Index of the gamer associated with the device + __in XINPUT_VIBRATION* pVibration // The vibration information to send to the controller +); + +DWORD WINAPI XInputGetCapabilities +( + __in DWORD dwUserIndex, // Index of the gamer associated with the device + __in DWORD dwFlags, // Input flags that identify the device type + __out XINPUT_CAPABILITIES* pCapabilities // Receives the capabilities +); + +void WINAPI XInputEnable +( + __in BOOL enable // [in] Indicates whether xinput is enabled or disabled. +); + +DWORD WINAPI XInputGetDSoundAudioDeviceGuids +( + __in DWORD dwUserIndex, // Index of the gamer associated with the device + __out GUID* pDSoundRenderGuid, // DSound device ID for render + __out GUID* pDSoundCaptureGuid // DSound device ID for capture +); + +#ifndef XINPUT_USE_9_1_0 + +DWORD WINAPI XInputGetBatteryInformation +( + __in DWORD dwUserIndex, // Index of the gamer associated with the device + __in BYTE devType, // Which device on this user index + __out XINPUT_BATTERY_INFORMATION* pBatteryInformation // Contains the level and types of batteries +); + +DWORD WINAPI XInputGetKeystroke +( + __in DWORD dwUserIndex, // Index of the gamer associated with the device + __reserved DWORD dwReserved, // Reserved for future use + __out PXINPUT_KEYSTROKE pKeystroke // Pointer to an XINPUT_KEYSTROKE structure that receives an input event. +); + +#endif //!XINPUT_USE_9_1_0 + +#ifdef __cplusplus +} +#endif + +#endif //_XINPUT_H_ + diff --git a/dxsdk/Include/audiodefs.h b/dxsdk/Include/audiodefs.h new file mode 100644 index 0000000..ff995ec --- /dev/null +++ b/dxsdk/Include/audiodefs.h @@ -0,0 +1,263 @@ +/*************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: audiodefs.h + * Content: Basic constants and data types for audio work. + * + * Remarks: This header file defines all of the audio format constants and + * structures required for XAudio2 and XACT work. Providing these + * in a single location avoids certain dependency problems in the + * legacy audio headers (mmreg.h, mmsystem.h, ksmedia.h). + * + * NOTE: Including the legacy headers after this one may cause a + * compilation error, because they define some of the same types + * defined here without preprocessor guards to avoid multiple + * definitions. If a source file needs one of the old headers, + * it must include it before including audiodefs.h. + * + ***************************************************************************/ + +#ifndef __AUDIODEFS_INCLUDED__ +#define __AUDIODEFS_INCLUDED__ + +#include // For WORD, DWORD, etc. + +#pragma pack(push, 1) // Pack structures to 1-byte boundaries + + +/************************************************************************** + * + * WAVEFORMATEX: Base structure for many audio formats. Format-specific + * extensions can be defined for particular formats by using a non-zero + * cbSize value and adding extra fields to the end of this structure. + * + ***************************************************************************/ + +#ifndef _WAVEFORMATEX_ + + #define _WAVEFORMATEX_ + typedef struct tWAVEFORMATEX + { + WORD wFormatTag; // Integer identifier of the format + WORD nChannels; // Number of audio channels + DWORD nSamplesPerSec; // Audio sample rate + DWORD nAvgBytesPerSec; // Bytes per second (possibly approximate) + WORD nBlockAlign; // Size in bytes of a sample block (all channels) + WORD wBitsPerSample; // Size in bits of a single per-channel sample + WORD cbSize; // Bytes of extra data appended to this struct + } WAVEFORMATEX; + +#endif + +// Defining pointer types outside of the #if block to make sure they are +// defined even if mmreg.h or mmsystem.h is #included before this file + +typedef WAVEFORMATEX *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX; +typedef const WAVEFORMATEX *PCWAVEFORMATEX, *LPCWAVEFORMATEX; + + +/************************************************************************** + * + * WAVEFORMATEXTENSIBLE: Extended version of WAVEFORMATEX that should be + * used as a basis for all new audio formats. The format tag is replaced + * with a GUID, allowing new formats to be defined without registering a + * format tag with Microsoft. There are also new fields that can be used + * to specify the spatial positions for each channel and the bit packing + * used for wide samples (e.g. 24-bit PCM samples in 32-bit containers). + * + ***************************************************************************/ + +#ifndef _WAVEFORMATEXTENSIBLE_ + + #define _WAVEFORMATEXTENSIBLE_ + typedef struct + { + WAVEFORMATEX Format; // Base WAVEFORMATEX data + union + { + WORD wValidBitsPerSample; // Valid bits in each sample container + WORD wSamplesPerBlock; // Samples per block of audio data; valid + // if wBitsPerSample=0 (but rarely used). + WORD wReserved; // Zero if neither case above applies. + } Samples; + DWORD dwChannelMask; // Positions of the audio channels + GUID SubFormat; // Format identifier GUID + } WAVEFORMATEXTENSIBLE; + +#endif + +typedef WAVEFORMATEXTENSIBLE *PWAVEFORMATEXTENSIBLE, *LPWAVEFORMATEXTENSIBLE; +typedef const WAVEFORMATEXTENSIBLE *PCWAVEFORMATEXTENSIBLE, *LPCWAVEFORMATEXTENSIBLE; + + + +/************************************************************************** + * + * Define the most common wave format tags used in WAVEFORMATEX formats. + * + ***************************************************************************/ + +#ifndef WAVE_FORMAT_PCM // Pulse Code Modulation + + // If WAVE_FORMAT_PCM is not defined, we need to define some legacy types + // for compatibility with the Windows mmreg.h / mmsystem.h header files. + + // Old general format structure (information common to all formats) + typedef struct waveformat_tag + { + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + } WAVEFORMAT, *PWAVEFORMAT, NEAR *NPWAVEFORMAT, FAR *LPWAVEFORMAT; + + // Specific format structure for PCM data + typedef struct pcmwaveformat_tag + { + WAVEFORMAT wf; + WORD wBitsPerSample; + } PCMWAVEFORMAT, *PPCMWAVEFORMAT, NEAR *NPPCMWAVEFORMAT, FAR *LPPCMWAVEFORMAT; + + #define WAVE_FORMAT_PCM 0x0001 + +#endif + +#ifndef WAVE_FORMAT_ADPCM // Microsoft Adaptive Differental PCM + + // Replicate the Microsoft ADPCM type definitions from mmreg.h. + + typedef struct adpcmcoef_tag + { + short iCoef1; + short iCoef2; + } ADPCMCOEFSET; + + #pragma warning(push) + #pragma warning(disable:4200) // Disable zero-sized array warnings + + typedef struct adpcmwaveformat_tag { + WAVEFORMATEX wfx; + WORD wSamplesPerBlock; + WORD wNumCoef; + ADPCMCOEFSET aCoef[]; // Always 7 coefficient pairs for MS ADPCM + } ADPCMWAVEFORMAT; + + #pragma warning(pop) + + #define WAVE_FORMAT_ADPCM 0x0002 + +#endif + +// Other frequently used format tags + +#ifndef WAVE_FORMAT_UNKNOWN + #define WAVE_FORMAT_UNKNOWN 0x0000 // Unknown or invalid format tag +#endif + +#ifndef WAVE_FORMAT_IEEE_FLOAT + #define WAVE_FORMAT_IEEE_FLOAT 0x0003 // 32-bit floating-point +#endif + +#ifndef WAVE_FORMAT_MPEGLAYER3 + #define WAVE_FORMAT_MPEGLAYER3 0x0055 // ISO/MPEG Layer3 +#endif + +#ifndef WAVE_FORMAT_DOLBY_AC3_SPDIF + #define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 // Dolby Audio Codec 3 over S/PDIF +#endif + +#ifndef WAVE_FORMAT_WMAUDIO2 + #define WAVE_FORMAT_WMAUDIO2 0x0161 // Windows Media Audio +#endif + +#ifndef WAVE_FORMAT_WMAUDIO3 + #define WAVE_FORMAT_WMAUDIO3 0x0162 // Windows Media Audio Pro +#endif + +#ifndef WAVE_FORMAT_WMASPDIF + #define WAVE_FORMAT_WMASPDIF 0x0164 // Windows Media Audio over S/PDIF +#endif + +#ifndef WAVE_FORMAT_EXTENSIBLE + #define WAVE_FORMAT_EXTENSIBLE 0xFFFE // All WAVEFORMATEXTENSIBLE formats +#endif + + +/************************************************************************** + * + * Define the most common wave format GUIDs used in WAVEFORMATEXTENSIBLE + * formats. Note that including the Windows ksmedia.h header after this + * one will cause build problems; this cannot be avoided, since ksmedia.h + * defines these macros without preprocessor guards. + * + ***************************************************************************/ + +#ifdef __cplusplus // uuid() and __uuidof() are only available in C++ + + #ifndef KSDATAFORMAT_SUBTYPE_PCM + struct __declspec(uuid("00000001-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_PCM_STRUCT; + #define KSDATAFORMAT_SUBTYPE_PCM __uuidof(KSDATAFORMAT_SUBTYPE_PCM_STRUCT) + #endif + + #ifndef KSDATAFORMAT_SUBTYPE_ADPCM + struct __declspec(uuid("00000002-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_ADPCM_STRUCT; + #define KSDATAFORMAT_SUBTYPE_ADPCM __uuidof(KSDATAFORMAT_SUBTYPE_ADPCM_STRUCT) + #endif + + #ifndef KSDATAFORMAT_SUBTYPE_IEEE_FLOAT + struct __declspec(uuid("00000003-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_STRUCT; + #define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT __uuidof(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_STRUCT) + #endif + +#endif + + +/************************************************************************** + * + * Speaker positions used in the WAVEFORMATEXTENSIBLE dwChannelMask field. + * + ***************************************************************************/ + +#ifndef SPEAKER_FRONT_LEFT + #define SPEAKER_FRONT_LEFT 0x00000001 + #define SPEAKER_FRONT_RIGHT 0x00000002 + #define SPEAKER_FRONT_CENTER 0x00000004 + #define SPEAKER_LOW_FREQUENCY 0x00000008 + #define SPEAKER_BACK_LEFT 0x00000010 + #define SPEAKER_BACK_RIGHT 0x00000020 + #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040 + #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080 + #define SPEAKER_BACK_CENTER 0x00000100 + #define SPEAKER_SIDE_LEFT 0x00000200 + #define SPEAKER_SIDE_RIGHT 0x00000400 + #define SPEAKER_TOP_CENTER 0x00000800 + #define SPEAKER_TOP_FRONT_LEFT 0x00001000 + #define SPEAKER_TOP_FRONT_CENTER 0x00002000 + #define SPEAKER_TOP_FRONT_RIGHT 0x00004000 + #define SPEAKER_TOP_BACK_LEFT 0x00008000 + #define SPEAKER_TOP_BACK_CENTER 0x00010000 + #define SPEAKER_TOP_BACK_RIGHT 0x00020000 + #define SPEAKER_RESERVED 0x7FFC0000 + #define SPEAKER_ALL 0x80000000 + #define _SPEAKER_POSITIONS_ +#endif + +#ifndef SPEAKER_STEREO + #define SPEAKER_MONO (SPEAKER_FRONT_CENTER) + #define SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) + #define SPEAKER_2POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY) + #define SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER) + #define SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + #define SPEAKER_4POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + #define SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + #define SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER) + #define SPEAKER_5POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) + #define SPEAKER_7POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) +#endif + + +#pragma pack(pop) + +#endif // #ifndef __AUDIODEFS_INCLUDED__ diff --git a/dxsdk/Include/comdecl.h b/dxsdk/Include/comdecl.h new file mode 100644 index 0000000..2ae9a96 --- /dev/null +++ b/dxsdk/Include/comdecl.h @@ -0,0 +1,59 @@ +// comdecl.h: Macros to facilitate COM interface and GUID declarations. +// Copyright (c) Microsoft Corporation. All rights reserved. + +#ifndef _COMDECL_H_ +#define _COMDECL_H_ + +#ifndef _XBOX + #include // For standard COM interface macros +#else + #pragma warning(push) + #pragma warning(disable:4061) + #include // Required by xobjbase.h + #include // Special definitions for Xbox build + #pragma warning(pop) +#endif + +// The DEFINE_CLSID() and DEFINE_IID() macros defined below allow COM GUIDs to +// be declared and defined in such a way that clients can obtain the GUIDs using +// either the __uuidof() extension or the old-style CLSID_Foo / IID_IFoo names. +// If using the latter approach, the client can also choose whether to get the +// GUID definitions by defining the INITGUID preprocessor constant or by linking +// to a GUID library. This works in either C or C++. + +#ifdef __cplusplus + + #define DECLSPEC_UUID_WRAPPER(x) __declspec(uuid(#x)) + #ifdef INITGUID + + #define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + class DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) className; \ + EXTERN_C const GUID DECLSPEC_SELECTANY CLSID_##className = __uuidof(className) + + #define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + interface DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) interfaceName; \ + EXTERN_C const GUID DECLSPEC_SELECTANY IID_##interfaceName = __uuidof(interfaceName) + + #else // INITGUID + + #define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + class DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) className; \ + EXTERN_C const GUID CLSID_##className + + #define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + interface DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) interfaceName; \ + EXTERN_C const GUID IID_##interfaceName + + #endif // INITGUID + +#else // __cplusplus + + #define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) + + #define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) + +#endif // __cplusplus + +#endif // #ifndef _COMDECL_H_ diff --git a/dxsdk/Include/d3d10misc.h b/dxsdk/Include/d3d10misc.h new file mode 100644 index 0000000..a20644d --- /dev/null +++ b/dxsdk/Include/d3d10misc.h @@ -0,0 +1,143 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3D10Misc.h +// Content: D3D10 Device Creation APIs +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3D10MISC_H__ +#define __D3D10MISC_H__ + +#include "d3d10.h" + +// ID3D10Blob has been made version-neutral and moved to d3dcommon.h. + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +/////////////////////////////////////////////////////////////////////////// +// D3D10_DRIVER_TYPE +// ---------------- +// +// This identifier is used to determine the implementation of Direct3D10 +// to be used. +// +// Pass one of these values to D3D10CreateDevice +// +/////////////////////////////////////////////////////////////////////////// +typedef enum D3D10_DRIVER_TYPE +{ + D3D10_DRIVER_TYPE_HARDWARE = 0, + D3D10_DRIVER_TYPE_REFERENCE = 1, + D3D10_DRIVER_TYPE_NULL = 2, + D3D10_DRIVER_TYPE_SOFTWARE = 3, + D3D10_DRIVER_TYPE_WARP = 5, +} D3D10_DRIVER_TYPE; + +DEFINE_GUID(GUID_DeviceType, +0xd722fb4d, 0x7a68, 0x437a, 0xb2, 0x0c, 0x58, 0x04, 0xee, 0x24, 0x94, 0xa6); + +/////////////////////////////////////////////////////////////////////////// +// D3D10CreateDevice +// ------------------ +// +// pAdapter +// If NULL, D3D10CreateDevice will choose the primary adapter and +// create a new instance from a temporarily created IDXGIFactory. +// If non-NULL, D3D10CreateDevice will register the appropriate +// device, if necessary (via IDXGIAdapter::RegisterDrver), before +// creating the device. +// DriverType +// Specifies the driver type to be created: hardware, reference or +// null. +// Software +// HMODULE of a DLL implementing a software rasterizer. Must be NULL for +// non-Software driver types. +// Flags +// Any of those documented for D3D10CreateDevice. +// SDKVersion +// SDK version. Use the D3D10_SDK_VERSION macro. +// ppDevice +// Pointer to returned interface. +// +// Return Values +// Any of those documented for +// CreateDXGIFactory +// IDXGIFactory::EnumAdapters +// IDXGIAdapter::RegisterDriver +// D3D10CreateDevice +// +/////////////////////////////////////////////////////////////////////////// +HRESULT WINAPI D3D10CreateDevice( + IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + UINT SDKVersion, + ID3D10Device **ppDevice); + +/////////////////////////////////////////////////////////////////////////// +// D3D10CreateDeviceAndSwapChain +// ------------------------------ +// +// ppAdapter +// If NULL, D3D10CreateDevice will choose the primary adapter and +// create a new instance from a temporarily created IDXGIFactory. +// If non-NULL, D3D10CreateDevice will register the appropriate +// device, if necessary (via IDXGIAdapter::RegisterDrver), before +// creating the device. +// DriverType +// Specifies the driver type to be created: hardware, reference or +// null. +// Software +// HMODULE of a DLL implementing a software rasterizer. Must be NULL for +// non-Software driver types. +// Flags +// Any of those documented for D3D10CreateDevice. +// SDKVersion +// SDK version. Use the D3D10_SDK_VERSION macro. +// pSwapChainDesc +// Swap chain description, may be NULL. +// ppSwapChain +// Pointer to returned interface. May be NULL. +// ppDevice +// Pointer to returned interface. +// +// Return Values +// Any of those documented for +// CreateDXGIFactory +// IDXGIFactory::EnumAdapters +// IDXGIAdapter::RegisterDriver +// D3D10CreateDevice +// IDXGIFactory::CreateSwapChain +// +/////////////////////////////////////////////////////////////////////////// +HRESULT WINAPI D3D10CreateDeviceAndSwapChain( + IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + UINT SDKVersion, + DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + IDXGISwapChain **ppSwapChain, + ID3D10Device **ppDevice); + + +/////////////////////////////////////////////////////////////////////////// +// D3D10CreateBlob: +// ----------------- +// Creates a Buffer of n Bytes +////////////////////////////////////////////////////////////////////////// + +HRESULT WINAPI D3D10CreateBlob(SIZE_T NumBytes, LPD3D10BLOB *ppBuffer); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3D10EFFECT_H__ + + diff --git a/dxsdk/Include/d3d10sdklayers.h b/dxsdk/Include/d3d10sdklayers.h new file mode 100644 index 0000000..ef432eb --- /dev/null +++ b/dxsdk/Include/d3d10sdklayers.h @@ -0,0 +1,1361 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* Compiler settings for d3d10sdklayers.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 7.00.0555 + protocol : all , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3d10sdklayers_h__ +#define __d3d10sdklayers_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D10Debug_FWD_DEFINED__ +#define __ID3D10Debug_FWD_DEFINED__ +typedef interface ID3D10Debug ID3D10Debug; +#endif /* __ID3D10Debug_FWD_DEFINED__ */ + + +#ifndef __ID3D10SwitchToRef_FWD_DEFINED__ +#define __ID3D10SwitchToRef_FWD_DEFINED__ +typedef interface ID3D10SwitchToRef ID3D10SwitchToRef; +#endif /* __ID3D10SwitchToRef_FWD_DEFINED__ */ + + +#ifndef __ID3D10InfoQueue_FWD_DEFINED__ +#define __ID3D10InfoQueue_FWD_DEFINED__ +typedef interface ID3D10InfoQueue ID3D10InfoQueue; +#endif /* __ID3D10InfoQueue_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "dxgi.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3d10sdklayers_0000_0000 */ +/* [local] */ + +#define D3D10_SDK_LAYERS_VERSION ( 11 ) + +#define D3D10_DEBUG_FEATURE_FLUSH_PER_RENDER_OP ( 0x1 ) + +#define D3D10_DEBUG_FEATURE_FINISH_PER_RENDER_OP ( 0x2 ) + +#define D3D10_DEBUG_FEATURE_PRESENT_PER_RENDER_OP ( 0x4 ) + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10sdklayers_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10sdklayers_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D10Debug_INTERFACE_DEFINED__ +#define __ID3D10Debug_INTERFACE_DEFINED__ + +/* interface ID3D10Debug */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Debug; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4E01-342C-4106-A19F-4F2704F689F0") + ID3D10Debug : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetFeatureMask( + UINT Mask) = 0; + + virtual UINT STDMETHODCALLTYPE GetFeatureMask( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPresentPerRenderOpDelay( + UINT Milliseconds) = 0; + + virtual UINT STDMETHODCALLTYPE GetPresentPerRenderOpDelay( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetSwapChain( + /* [annotation] */ + __in_opt IDXGISwapChain *pSwapChain) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSwapChain( + /* [annotation] */ + __out IDXGISwapChain **ppSwapChain) = 0; + + virtual HRESULT STDMETHODCALLTYPE Validate( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10DebugVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Debug * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Debug * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Debug * This); + + HRESULT ( STDMETHODCALLTYPE *SetFeatureMask )( + ID3D10Debug * This, + UINT Mask); + + UINT ( STDMETHODCALLTYPE *GetFeatureMask )( + ID3D10Debug * This); + + HRESULT ( STDMETHODCALLTYPE *SetPresentPerRenderOpDelay )( + ID3D10Debug * This, + UINT Milliseconds); + + UINT ( STDMETHODCALLTYPE *GetPresentPerRenderOpDelay )( + ID3D10Debug * This); + + HRESULT ( STDMETHODCALLTYPE *SetSwapChain )( + ID3D10Debug * This, + /* [annotation] */ + __in_opt IDXGISwapChain *pSwapChain); + + HRESULT ( STDMETHODCALLTYPE *GetSwapChain )( + ID3D10Debug * This, + /* [annotation] */ + __out IDXGISwapChain **ppSwapChain); + + HRESULT ( STDMETHODCALLTYPE *Validate )( + ID3D10Debug * This); + + END_INTERFACE + } ID3D10DebugVtbl; + + interface ID3D10Debug + { + CONST_VTBL struct ID3D10DebugVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Debug_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Debug_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Debug_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Debug_SetFeatureMask(This,Mask) \ + ( (This)->lpVtbl -> SetFeatureMask(This,Mask) ) + +#define ID3D10Debug_GetFeatureMask(This) \ + ( (This)->lpVtbl -> GetFeatureMask(This) ) + +#define ID3D10Debug_SetPresentPerRenderOpDelay(This,Milliseconds) \ + ( (This)->lpVtbl -> SetPresentPerRenderOpDelay(This,Milliseconds) ) + +#define ID3D10Debug_GetPresentPerRenderOpDelay(This) \ + ( (This)->lpVtbl -> GetPresentPerRenderOpDelay(This) ) + +#define ID3D10Debug_SetSwapChain(This,pSwapChain) \ + ( (This)->lpVtbl -> SetSwapChain(This,pSwapChain) ) + +#define ID3D10Debug_GetSwapChain(This,ppSwapChain) \ + ( (This)->lpVtbl -> GetSwapChain(This,ppSwapChain) ) + +#define ID3D10Debug_Validate(This) \ + ( (This)->lpVtbl -> Validate(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Debug_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D10SwitchToRef_INTERFACE_DEFINED__ +#define __ID3D10SwitchToRef_INTERFACE_DEFINED__ + +/* interface ID3D10SwitchToRef */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10SwitchToRef; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9B7E4E02-342C-4106-A19F-4F2704F689F0") + ID3D10SwitchToRef : public IUnknown + { + public: + virtual BOOL STDMETHODCALLTYPE SetUseRef( + BOOL UseRef) = 0; + + virtual BOOL STDMETHODCALLTYPE GetUseRef( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10SwitchToRefVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10SwitchToRef * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10SwitchToRef * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10SwitchToRef * This); + + BOOL ( STDMETHODCALLTYPE *SetUseRef )( + ID3D10SwitchToRef * This, + BOOL UseRef); + + BOOL ( STDMETHODCALLTYPE *GetUseRef )( + ID3D10SwitchToRef * This); + + END_INTERFACE + } ID3D10SwitchToRefVtbl; + + interface ID3D10SwitchToRef + { + CONST_VTBL struct ID3D10SwitchToRefVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10SwitchToRef_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10SwitchToRef_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10SwitchToRef_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10SwitchToRef_SetUseRef(This,UseRef) \ + ( (This)->lpVtbl -> SetUseRef(This,UseRef) ) + +#define ID3D10SwitchToRef_GetUseRef(This) \ + ( (This)->lpVtbl -> GetUseRef(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10SwitchToRef_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10sdklayers_0000_0002 */ +/* [local] */ + +typedef +enum D3D10_MESSAGE_CATEGORY + { D3D10_MESSAGE_CATEGORY_APPLICATION_DEFINED = 0, + D3D10_MESSAGE_CATEGORY_MISCELLANEOUS = ( D3D10_MESSAGE_CATEGORY_APPLICATION_DEFINED + 1 ) , + D3D10_MESSAGE_CATEGORY_INITIALIZATION = ( D3D10_MESSAGE_CATEGORY_MISCELLANEOUS + 1 ) , + D3D10_MESSAGE_CATEGORY_CLEANUP = ( D3D10_MESSAGE_CATEGORY_INITIALIZATION + 1 ) , + D3D10_MESSAGE_CATEGORY_COMPILATION = ( D3D10_MESSAGE_CATEGORY_CLEANUP + 1 ) , + D3D10_MESSAGE_CATEGORY_STATE_CREATION = ( D3D10_MESSAGE_CATEGORY_COMPILATION + 1 ) , + D3D10_MESSAGE_CATEGORY_STATE_SETTING = ( D3D10_MESSAGE_CATEGORY_STATE_CREATION + 1 ) , + D3D10_MESSAGE_CATEGORY_STATE_GETTING = ( D3D10_MESSAGE_CATEGORY_STATE_SETTING + 1 ) , + D3D10_MESSAGE_CATEGORY_RESOURCE_MANIPULATION = ( D3D10_MESSAGE_CATEGORY_STATE_GETTING + 1 ) , + D3D10_MESSAGE_CATEGORY_EXECUTION = ( D3D10_MESSAGE_CATEGORY_RESOURCE_MANIPULATION + 1 ) + } D3D10_MESSAGE_CATEGORY; + +typedef +enum D3D10_MESSAGE_SEVERITY + { D3D10_MESSAGE_SEVERITY_CORRUPTION = 0, + D3D10_MESSAGE_SEVERITY_ERROR = ( D3D10_MESSAGE_SEVERITY_CORRUPTION + 1 ) , + D3D10_MESSAGE_SEVERITY_WARNING = ( D3D10_MESSAGE_SEVERITY_ERROR + 1 ) , + D3D10_MESSAGE_SEVERITY_INFO = ( D3D10_MESSAGE_SEVERITY_WARNING + 1 ) + } D3D10_MESSAGE_SEVERITY; + +typedef +enum D3D10_MESSAGE_ID + { D3D10_MESSAGE_ID_UNKNOWN = 0, + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_HAZARD = ( D3D10_MESSAGE_ID_UNKNOWN + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_HAZARD + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SOSETTARGETS_HAZARD = ( D3D10_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD + 1 ) , + D3D10_MESSAGE_ID_STRING_FROM_APPLICATION = ( D3D10_MESSAGE_ID_DEVICE_SOSETTARGETS_HAZARD + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_THIS = ( D3D10_MESSAGE_ID_STRING_FROM_APPLICATION + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER1 = ( D3D10_MESSAGE_ID_CORRUPTED_THIS + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER2 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER1 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER3 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER2 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER4 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER3 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER5 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER4 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER6 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER5 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER7 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER6 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER8 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER7 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER9 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER8 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER10 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER9 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER11 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER10 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER12 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER11 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER13 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER12 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER14 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER13 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER15 = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER14 + 1 ) , + D3D10_MESSAGE_ID_CORRUPTED_MULTITHREADING = ( D3D10_MESSAGE_ID_CORRUPTED_PARAMETER15 + 1 ) , + D3D10_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY = ( D3D10_MESSAGE_ID_CORRUPTED_MULTITHREADING + 1 ) , + D3D10_MESSAGE_ID_IASETINPUTLAYOUT_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY + 1 ) , + D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_IASETINPUTLAYOUT_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_IASETINDEXBUFFER_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_VSSETSHADER_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_IASETINDEXBUFFER_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_VSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_VSSETSHADER_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_VSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_VSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_VSSETSAMPLERS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_VSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_GSSETSHADER_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_VSSETSAMPLERS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_GSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_GSSETSHADER_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_GSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_GSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_GSSETSAMPLERS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_GSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_SOSETTARGETS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_GSSETSAMPLERS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_PSSETSHADER_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_SOSETTARGETS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_PSSETSHADERRESOURCES_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_PSSETSHADER_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_PSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_PSSETSHADERRESOURCES_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_PSSETSAMPLERS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_PSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_RSSETSTATE_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_PSSETSAMPLERS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_OMSETBLENDSTATE_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_RSSETSTATE_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_OMSETDEPTHSTENCILSTATE_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_OMSETBLENDSTATE_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_OMSETDEPTHSTENCILSTATE_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_SETPREDICATION_UNBINDDELETINGOBJECT = ( D3D10_MESSAGE_ID_OMSETRENDERTARGETS_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_GETPRIVATEDATA_MOREDATA = ( D3D10_MESSAGE_ID_SETPREDICATION_UNBINDDELETINGOBJECT + 1 ) , + D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA = ( D3D10_MESSAGE_ID_GETPRIVATEDATA_MOREDATA + 1 ) , + D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN = ( D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA + 1 ) , + D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS = ( D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN + 1 ) , + D3D10_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS = ( D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS + 1 ) , + D3D10_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY = ( D3D10_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDFORMAT = ( D3D10_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDSAMPLES = ( D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDUSAGE = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDSAMPLES + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDUSAGE + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDINITIALDATA = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDINITIALDATA + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDMIPLEVELS = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDMIPLEVELS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_NULLDESC = ( D3D10_MESSAGE_ID_CREATEBUFFER_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDCONSTANTBUFFERBINDINGS = ( D3D10_MESSAGE_ID_CREATEBUFFER_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATEBUFFER_LARGEALLOCATION = ( D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDCONSTANTBUFFERBINDINGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDFORMAT = ( D3D10_MESSAGE_ID_CREATEBUFFER_LARGEALLOCATION + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNSUPPORTEDFORMAT = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDSAMPLES = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_UNSUPPORTEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDUSAGE = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDSAMPLES + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDUSAGE + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDINITIALDATA = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDINITIALDATA + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDMIPLEVELS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDMIPLEVELS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_NULLDESC = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE1D_LARGEALLOCATION = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDFORMAT = ( D3D10_MESSAGE_ID_CREATETEXTURE1D_LARGEALLOCATION + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNSUPPORTEDFORMAT = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDSAMPLES = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_UNSUPPORTEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDUSAGE = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDSAMPLES + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDUSAGE + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDINITIALDATA = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDINITIALDATA + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDMIPLEVELS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDMIPLEVELS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_NULLDESC = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE2D_LARGEALLOCATION = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDFORMAT = ( D3D10_MESSAGE_ID_CREATETEXTURE2D_LARGEALLOCATION + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNSUPPORTEDFORMAT = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDSAMPLES = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_UNSUPPORTEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDUSAGE = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDSAMPLES + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDUSAGE + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDCPUACCESSFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDBINDFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDCPUACCESSFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDINITIALDATA = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDBINDFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDINITIALDATA + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDMIPLEVELS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDMIPLEVELS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_NULLDESC = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATETEXTURE3D_LARGEALLOCATION = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT = ( D3D10_MESSAGE_ID_CREATETEXTURE3D_LARGEALLOCATION + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_TOOMANYOBJECTS = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_TOOMANYOBJECTS + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_TOOMANYOBJECTS = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_TOOMANYOBJECTS + 1 ) , + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT = ( D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_TOOMANYOBJECTS = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_TOOMANYOBJECTS + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_NULLDESC = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT + 1 ) , + D3D10_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE = ( D3D10_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY + 1 ) , + D3D10_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE = ( D3D10_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY = ( D3D10_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX + 1 ) , + D3D10_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE + 1 ) , + D3D10_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE = ( D3D10_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY + 1 ) , + D3D10_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE = ( D3D10_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE = ( D3D10_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_TOOMANYOBJECTS = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_TOOMANYOBJECTS + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_TOOMANYOBJECTS = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC + 1 ) , + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_TOOMANYOBJECTS + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_TOOMANYOBJECTS = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_TOOMANYOBJECTS + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_TOOMANYOBJECTS = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_TOOMANYOBJECTS + 1 ) , + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDQUERY = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDMISCFLAGS = ( D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDQUERY + 1 ) , + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_UNEXPECTEDMISCFLAG = ( D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDMISCFLAGS + 1 ) , + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_NULLDESC = ( D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_UNEXPECTEDMISCFLAG + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED = ( D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED = ( D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED + 1 ) , + D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_INVALIDBUFFER = ( D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_OFFSET_TOO_LARGE = ( D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_INVALIDBUFFER + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_OFFSET_TOO_LARGE + 1 ) , + D3D10_MESSAGE_ID_IASETINDEXBUFFER_INVALIDBUFFER = ( D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_FORMAT_INVALID = ( D3D10_MESSAGE_ID_IASETINDEXBUFFER_INVALIDBUFFER + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_TOO_LARGE = ( D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_FORMAT_INVALID + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_UNALIGNED = ( D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_TOO_LARGE + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_UNALIGNED + 1 ) , + D3D10_MESSAGE_ID_VSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D10_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_VSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_VSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_GSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D10_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_GSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_SOSETTARGETS_INVALIDBUFFER = ( D3D10_MESSAGE_ID_DEVICE_GSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SOSETTARGETS_OFFSET_UNALIGNED = ( D3D10_MESSAGE_ID_SOSETTARGETS_INVALIDBUFFER + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_SOSETTARGETS_OFFSET_UNALIGNED + 1 ) , + D3D10_MESSAGE_ID_PSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D10_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_PSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT = ( D3D10_MESSAGE_ID_DEVICE_PSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR = ( D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT + 1 ) , + D3D10_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH = ( D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR + 1 ) , + D3D10_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH = ( D3D10_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH + 1 ) , + D3D10_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID = ( D3D10_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IAGETVERTEXBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_IAGETVERTEXBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_VSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_VSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_VSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_VSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_GSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_GSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SOGETTARGETS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_GSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_SOGETTARGETS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_PSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_PSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_PSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSGETVIEWPORTS_VIEWPORTS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_PSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSGETSCISSORRECTS_RECTS_EMPTY = ( D3D10_MESSAGE_ID_DEVICE_RSGETVIEWPORTS_VIEWPORTS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_GENERATEMIPS_RESOURCE_INVALID = ( D3D10_MESSAGE_ID_DEVICE_RSGETSCISSORRECTS_RECTS_EMPTY + 1 ) , + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSUBRESOURCE = ( D3D10_MESSAGE_ID_DEVICE_GENERATEMIPS_RESOURCE_INVALID + 1 ) , + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESUBRESOURCE = ( D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCEBOX = ( D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCE = ( D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCEBOX + 1 ) , + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSTATE = ( D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCE + 1 ) , + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESTATE = ( D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSTATE + 1 ) , + D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE = ( D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESTATE + 1 ) , + D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE = ( D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE + 1 ) , + D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE = ( D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE + 1 ) , + D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE = ( D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE + 1 ) , + D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX = ( D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE = ( D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID = ( D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID = ( D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID = ( D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID = ( D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID = ( D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID + 1 ) , + D3D10_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE = ( D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID + 1 ) , + D3D10_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS = ( D3D10_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE + 1 ) , + D3D10_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED = ( D3D10_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS + 1 ) , + D3D10_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN = ( D3D10_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED + 1 ) , + D3D10_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED = ( D3D10_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE = ( D3D10_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED + 1 ) , + D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE = ( D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS = ( D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED = ( D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS + 1 ) , + D3D10_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN = ( D3D10_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED + 1 ) , + D3D10_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE = ( D3D10_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D10_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED = ( D3D10_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE = ( D3D10_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED + 1 ) , + D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE = ( D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS = ( D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED = ( D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS + 1 ) , + D3D10_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN = ( D3D10_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED + 1 ) , + D3D10_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE = ( D3D10_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D10_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED = ( D3D10_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE = ( D3D10_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED + 1 ) , + D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE = ( D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS = ( D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED = ( D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS + 1 ) , + D3D10_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN = ( D3D10_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED + 1 ) , + D3D10_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE = ( D3D10_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D10_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED = ( D3D10_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D10_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED = ( D3D10_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED + 1 ) , + D3D10_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED = ( D3D10_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED + 1 ) , + D3D10_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS = ( D3D10_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED + 1 ) , + D3D10_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS + 1 ) , + D3D10_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN = ( D3D10_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE = ( D3D10_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN + 1 ) , + D3D10_MESSAGE_ID_REF_THREADING_MODE = ( D3D10_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE + 1 ) , + D3D10_MESSAGE_ID_REF_UMDRIVER_EXCEPTION = ( D3D10_MESSAGE_ID_REF_THREADING_MODE + 1 ) , + D3D10_MESSAGE_ID_REF_KMDRIVER_EXCEPTION = ( D3D10_MESSAGE_ID_REF_UMDRIVER_EXCEPTION + 1 ) , + D3D10_MESSAGE_ID_REF_HARDWARE_EXCEPTION = ( D3D10_MESSAGE_ID_REF_KMDRIVER_EXCEPTION + 1 ) , + D3D10_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE = ( D3D10_MESSAGE_ID_REF_HARDWARE_EXCEPTION + 1 ) , + D3D10_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER = ( D3D10_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE + 1 ) , + D3D10_MESSAGE_ID_REF_OUT_OF_MEMORY = ( D3D10_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER + 1 ) , + D3D10_MESSAGE_ID_REF_INFO = ( D3D10_MESSAGE_ID_REF_OUT_OF_MEMORY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW = ( D3D10_MESSAGE_ID_REF_INFO + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW = ( D3D10_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW = ( D3D10_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW = ( D3D10_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW = ( D3D10_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX = ( D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE = ( D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK = ( D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE = ( D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS = ( D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_INPUTLAYOUT_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_DRAW_INPUTLAYOUT_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL = ( D3D10_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_SHADERRESOURCEVIEW_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VIEW_DIMENSION_MISMATCH = ( D3D10_MESSAGE_ID_DEVICE_DRAW_SHADERRESOURCEVIEW_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VIEW_DIMENSION_MISMATCH + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_FORMAT_INVALID = ( D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL = ( D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_FORMAT_INVALID + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_GS_INPUT_PRIMITIVE_MISMATCH = ( D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH = ( D3D10_MESSAGE_ID_DEVICE_DRAW_GS_INPUT_PRIMITIVE_MISMATCH + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_POSITION_NOT_PRESENT = ( D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_DRAW_POSITION_NOT_PRESENT + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_BOUND_RESOURCE_MAPPED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_INVALID_PRIMITIVETOPOLOGY = ( D3D10_MESSAGE_ID_DEVICE_DRAW_BOUND_RESOURCE_MAPPED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_OFFSET_UNALIGNED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_INVALID_PRIMITIVETOPOLOGY + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_STRIDE_UNALIGNED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_OFFSET_UNALIGNED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_OFFSET_UNALIGNED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_STRIDE_UNALIGNED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_OFFSET_UNALIGNED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE = ( D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_SO_STRIDE_LARGER_THAN_BUFFER = ( D3D10_MESSAGE_ID_DEVICE_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING = ( D3D10_MESSAGE_ID_DEVICE_DRAW_SO_STRIDE_LARGER_THAN_BUFFER + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 = ( D3D10_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING + 1 ) , + D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT = ( D3D10_MESSAGE_ID_DEVICE_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 + 1 ) , + D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT = ( D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT + 1 ) , + D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT = ( D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT + 1 ) , + D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN = ( D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT + 1 ) , + D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN + 1 ) , + D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN = ( D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET = ( D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC = ( D3D10_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET + 1 ) , + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH = ( D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC + 1 ) , + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW = ( D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH + 1 ) , + D3D10_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS = ( D3D10_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH = ( D3D10_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH = ( D3D10_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH + 1 ) , + D3D10_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH + 1 ) , + D3D10_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY = ( D3D10_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY + 1 ) , + D3D10_MESSAGE_ID_CREATEQUERY_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY + 1 ) , + D3D10_MESSAGE_ID_CREATEPREDICATE_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATEQUERY_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATECOUNTER_OUTOFRANGE_COUNTER = ( D3D10_MESSAGE_ID_CREATEPREDICATE_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATECOUNTER_SIMULTANEOUS_ACTIVE_COUNTERS_EXHAUSTED = ( D3D10_MESSAGE_ID_CREATECOUNTER_OUTOFRANGE_COUNTER + 1 ) , + D3D10_MESSAGE_ID_CREATECOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER = ( D3D10_MESSAGE_ID_CREATECOUNTER_SIMULTANEOUS_ACTIVE_COUNTERS_EXHAUSTED + 1 ) , + D3D10_MESSAGE_ID_CREATECOUNTER_OUTOFMEMORY_RETURN = ( D3D10_MESSAGE_ID_CREATECOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER + 1 ) , + D3D10_MESSAGE_ID_CREATECOUNTER_NONEXCLUSIVE_RETURN = ( D3D10_MESSAGE_ID_CREATECOUNTER_OUTOFMEMORY_RETURN + 1 ) , + D3D10_MESSAGE_ID_CREATECOUNTER_NULLDESC = ( D3D10_MESSAGE_ID_CREATECOUNTER_NONEXCLUSIVE_RETURN + 1 ) , + D3D10_MESSAGE_ID_CHECKCOUNTER_OUTOFRANGE_COUNTER = ( D3D10_MESSAGE_ID_CREATECOUNTER_NULLDESC + 1 ) , + D3D10_MESSAGE_ID_CHECKCOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER = ( D3D10_MESSAGE_ID_CHECKCOUNTER_OUTOFRANGE_COUNTER + 1 ) , + D3D10_MESSAGE_ID_SETPREDICATION_INVALID_PREDICATE_STATE = ( D3D10_MESSAGE_ID_CHECKCOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER + 1 ) , + D3D10_MESSAGE_ID_QUERY_BEGIN_UNSUPPORTED = ( D3D10_MESSAGE_ID_SETPREDICATION_INVALID_PREDICATE_STATE + 1 ) , + D3D10_MESSAGE_ID_PREDICATE_BEGIN_DURING_PREDICATION = ( D3D10_MESSAGE_ID_QUERY_BEGIN_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_QUERY_BEGIN_DUPLICATE = ( D3D10_MESSAGE_ID_PREDICATE_BEGIN_DURING_PREDICATION + 1 ) , + D3D10_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS = ( D3D10_MESSAGE_ID_QUERY_BEGIN_DUPLICATE + 1 ) , + D3D10_MESSAGE_ID_PREDICATE_END_DURING_PREDICATION = ( D3D10_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS + 1 ) , + D3D10_MESSAGE_ID_QUERY_END_ABANDONING_PREVIOUS_RESULTS = ( D3D10_MESSAGE_ID_PREDICATE_END_DURING_PREDICATION + 1 ) , + D3D10_MESSAGE_ID_QUERY_END_WITHOUT_BEGIN = ( D3D10_MESSAGE_ID_QUERY_END_ABANDONING_PREVIOUS_RESULTS + 1 ) , + D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_DATASIZE = ( D3D10_MESSAGE_ID_QUERY_END_WITHOUT_BEGIN + 1 ) , + D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_FLAGS = ( D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_DATASIZE + 1 ) , + D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_CALL = ( D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_FLAGS + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH = ( D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_CALL + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED = ( D3D10_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN = ( D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE = ( D3D10_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE = ( D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT = ( D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE + 1 ) , + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT + 1 ) , + D3D10_MESSAGE_ID_D3D10_MESSAGES_END = ( D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH + 1 ) , + D3D10_MESSAGE_ID_D3D10L9_MESSAGES_START = 0x100000, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_STENCIL_NO_TWO_SIDED = ( D3D10_MESSAGE_ID_D3D10L9_MESSAGES_START + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_DepthBiasClamp_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_STENCIL_NO_TWO_SIDED + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NO_COMPARISON_SUPPORT = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_DepthBiasClamp_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_EXCESSIVE_ANISOTROPY = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NO_COMPARISON_SUPPORT + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_OUT_OF_RANGE = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_EXCESSIVE_ANISOTROPY + 1 ) , + D3D10_MESSAGE_ID_VSSETSAMPLERS_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_OUT_OF_RANGE + 1 ) , + D3D10_MESSAGE_ID_VSSETSAMPLERS_TOO_MANY_SAMPLERS = ( D3D10_MESSAGE_ID_VSSETSAMPLERS_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_PSSETSAMPLERS_TOO_MANY_SAMPLERS = ( D3D10_MESSAGE_ID_VSSETSAMPLERS_TOO_MANY_SAMPLERS + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NO_ARRAYS = ( D3D10_MESSAGE_ID_PSSETSAMPLERS_TOO_MANY_SAMPLERS + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NO_VB_AND_IB_BIND = ( D3D10_MESSAGE_ID_CREATERESOURCE_NO_ARRAYS + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NO_TEXTURE_1D = ( D3D10_MESSAGE_ID_CREATERESOURCE_NO_VB_AND_IB_BIND + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_DIMENSION_OUT_OF_RANGE = ( D3D10_MESSAGE_ID_CREATERESOURCE_NO_TEXTURE_1D + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_SHADER_RESOURCE = ( D3D10_MESSAGE_ID_CREATERESOURCE_DIMENSION_OUT_OF_RANGE + 1 ) , + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_TOO_MANY_RENDER_TARGETS = ( D3D10_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_SHADER_RESOURCE + 1 ) , + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_NO_DIFFERING_BIT_DEPTHS = ( D3D10_MESSAGE_ID_OMSETRENDERTARGETS_TOO_MANY_RENDER_TARGETS + 1 ) , + D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_BAD_BUFFER_INDEX = ( D3D10_MESSAGE_ID_OMSETRENDERTARGETS_NO_DIFFERING_BIT_DEPTHS + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_TOO_MANY_VIEWPORTS = ( D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_BAD_BUFFER_INDEX + 1 ) , + D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_ADJACENCY_UNSUPPORTED = ( D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_TOO_MANY_VIEWPORTS + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_TOO_MANY_SCISSORS = ( D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_ADJACENCY_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_COPYRESOURCE_ONLY_TEXTURE_2D_WITHIN_GPU_MEMORY = ( D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_TOO_MANY_SCISSORS + 1 ) , + D3D10_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_3D_READBACK = ( D3D10_MESSAGE_ID_COPYRESOURCE_ONLY_TEXTURE_2D_WITHIN_GPU_MEMORY + 1 ) , + D3D10_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_ONLY_READBACK = ( D3D10_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_3D_READBACK + 1 ) , + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_UNSUPPORTED_FORMAT = ( D3D10_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_ONLY_READBACK + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_ALPHA_TO_COVERAGE = ( D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_UNSUPPORTED_FORMAT + 1 ) , + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_DepthClipEnable_MUST_BE_TRUE = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_ALPHA_TO_COVERAGE + 1 ) , + D3D10_MESSAGE_ID_DRAWINDEXED_STARTINDEXLOCATION_MUST_BE_POSITIVE = ( D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_DepthClipEnable_MUST_BE_TRUE + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_MUST_USE_LOWEST_LOD = ( D3D10_MESSAGE_ID_DRAWINDEXED_STARTINDEXLOCATION_MUST_BE_POSITIVE + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_MINLOD_MUST_NOT_BE_FRACTIONAL = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_MUST_USE_LOWEST_LOD + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_MAXLOD_MUST_BE_FLT_MAX = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_MINLOD_MUST_NOT_BE_FRACTIONAL + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_FIRSTARRAYSLICE_MUST_BE_ZERO = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_MAXLOD_MUST_BE_FLT_MAX + 1 ) , + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_CUBES_MUST_HAVE_6_SIDES = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_FIRSTARRAYSLICE_MUST_BE_ZERO + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_RENDER_TARGET = ( D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_CUBES_MUST_HAVE_6_SIDES + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NO_DWORD_INDEX_BUFFER = ( D3D10_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_RENDER_TARGET + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_MSAA_PRECLUDES_SHADER_RESOURCE = ( D3D10_MESSAGE_ID_CREATERESOURCE_NO_DWORD_INDEX_BUFFER + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_PRESENTATION_PRECLUDES_SHADER_RESOURCE = ( D3D10_MESSAGE_ID_CREATERESOURCE_MSAA_PRECLUDES_SHADER_RESOURCE + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_BLEND_ENABLE = ( D3D10_MESSAGE_ID_CREATERESOURCE_PRESENTATION_PRECLUDES_SHADER_RESOURCE + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_WRITE_MASKS = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_BLEND_ENABLE + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NO_STREAM_OUT = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_WRITE_MASKS + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_ONLY_VB_IB_FOR_BUFFERS = ( D3D10_MESSAGE_ID_CREATERESOURCE_NO_STREAM_OUT + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NO_AUTOGEN_FOR_VOLUMES = ( D3D10_MESSAGE_ID_CREATERESOURCE_ONLY_VB_IB_FOR_BUFFERS + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_DXGI_FORMAT_R8G8B8A8_CANNOT_BE_SHARED = ( D3D10_MESSAGE_ID_CREATERESOURCE_NO_AUTOGEN_FOR_VOLUMES + 1 ) , + D3D10_MESSAGE_ID_VSSHADERRESOURCES_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_CREATERESOURCE_DXGI_FORMAT_R8G8B8A8_CANNOT_BE_SHARED + 1 ) , + D3D10_MESSAGE_ID_GEOMETRY_SHADER_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_VSSHADERRESOURCES_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_STREAM_OUT_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_GEOMETRY_SHADER_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_TEXT_FILTER_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_STREAM_OUT_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_SEPARATE_ALPHA_BLEND = ( D3D10_MESSAGE_ID_TEXT_FILTER_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_MRT_BLEND = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_SEPARATE_ALPHA_BLEND + 1 ) , + D3D10_MESSAGE_ID_CREATEBLENDSTATE_OPERATION_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_MRT_BLEND + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NO_MIRRORONCE = ( D3D10_MESSAGE_ID_CREATEBLENDSTATE_OPERATION_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_DRAWINSTANCED_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NO_MIRRORONCE + 1 ) , + D3D10_MESSAGE_ID_DRAWINDEXEDINSTANCED_NOT_SUPPORTED_BELOW_9_3 = ( D3D10_MESSAGE_ID_DRAWINSTANCED_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_DRAWINDEXED_POINTLIST_UNSUPPORTED = ( D3D10_MESSAGE_ID_DRAWINDEXEDINSTANCED_NOT_SUPPORTED_BELOW_9_3 + 1 ) , + D3D10_MESSAGE_ID_SETBLENDSTATE_SAMPLE_MASK_CANNOT_BE_ZERO = ( D3D10_MESSAGE_ID_DRAWINDEXED_POINTLIST_UNSUPPORTED + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_DIMENSION_EXCEEDS_FEATURE_LEVEL_DEFINITION = ( D3D10_MESSAGE_ID_SETBLENDSTATE_SAMPLE_MASK_CANNOT_BE_ZERO + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_ONLY_SINGLE_MIP_LEVEL_DEPTH_STENCIL_SUPPORTED = ( D3D10_MESSAGE_ID_CREATERESOURCE_DIMENSION_EXCEEDS_FEATURE_LEVEL_DEFINITION + 1 ) , + D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_NEGATIVESCISSOR = ( D3D10_MESSAGE_ID_CREATERESOURCE_ONLY_SINGLE_MIP_LEVEL_DEPTH_STENCIL_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_SLOT_ZERO_MUST_BE_D3D10_INPUT_PER_VERTEX_DATA = ( D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_NEGATIVESCISSOR + 1 ) , + D3D10_MESSAGE_ID_CREATERESOURCE_NON_POW_2_MIPMAP = ( D3D10_MESSAGE_ID_SLOT_ZERO_MUST_BE_D3D10_INPUT_PER_VERTEX_DATA + 1 ) , + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_NOT_SUPPORTED = ( D3D10_MESSAGE_ID_CREATERESOURCE_NON_POW_2_MIPMAP + 1 ) , + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_NO_SRGB_MRT = ( D3D10_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_NOT_SUPPORTED + 1 ) , + D3D10_MESSAGE_ID_D3D10L9_MESSAGES_END = ( D3D10_MESSAGE_ID_OMSETRENDERTARGETS_NO_SRGB_MRT + 1 ) + } D3D10_MESSAGE_ID; + +typedef struct D3D10_MESSAGE + { + D3D10_MESSAGE_CATEGORY Category; + D3D10_MESSAGE_SEVERITY Severity; + D3D10_MESSAGE_ID ID; + const char *pDescription; + SIZE_T DescriptionByteLength; + } D3D10_MESSAGE; + +typedef struct D3D10_INFO_QUEUE_FILTER_DESC + { + UINT NumCategories; + D3D10_MESSAGE_CATEGORY *pCategoryList; + UINT NumSeverities; + D3D10_MESSAGE_SEVERITY *pSeverityList; + UINT NumIDs; + D3D10_MESSAGE_ID *pIDList; + } D3D10_INFO_QUEUE_FILTER_DESC; + +typedef struct D3D10_INFO_QUEUE_FILTER + { + D3D10_INFO_QUEUE_FILTER_DESC AllowList; + D3D10_INFO_QUEUE_FILTER_DESC DenyList; + } D3D10_INFO_QUEUE_FILTER; + +#define D3D10_INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT 1024 + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10sdklayers_0000_0002_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10sdklayers_0000_0002_v0_0_s_ifspec; + +#ifndef __ID3D10InfoQueue_INTERFACE_DEFINED__ +#define __ID3D10InfoQueue_INTERFACE_DEFINED__ + +/* interface ID3D10InfoQueue */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10InfoQueue; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1b940b17-2642-4d1f-ab1f-b99bad0c395f") + ID3D10InfoQueue : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetMessageCountLimit( + /* [annotation] */ + __in UINT64 MessageCountLimit) = 0; + + virtual void STDMETHODCALLTYPE ClearStoredMessages( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetMessage( + /* [annotation] */ + __in UINT64 MessageIndex, + /* [annotation] */ + __out_bcount_opt(*pMessageByteLength) D3D10_MESSAGE *pMessage, + /* [annotation] */ + __inout SIZE_T *pMessageByteLength) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesAllowedByStorageFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDeniedByStorageFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessages( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessagesAllowedByRetrievalFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDiscardedByMessageCountLimit( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetMessageCountLimit( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddStorageFilterEntries( + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStorageFilter( + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D10_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength) = 0; + + virtual void STDMETHODCALLTYPE ClearStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushEmptyStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushCopyOfStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushStorageFilter( + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual void STDMETHODCALLTYPE PopStorageFilter( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetStorageFilterStackSize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddRetrievalFilterEntries( + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRetrievalFilter( + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D10_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength) = 0; + + virtual void STDMETHODCALLTYPE ClearRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushEmptyRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushCopyOfRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushRetrievalFilter( + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual void STDMETHODCALLTYPE PopRetrievalFilter( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetRetrievalFilterStackSize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddMessage( + /* [annotation] */ + __in D3D10_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in D3D10_MESSAGE_ID ID, + /* [annotation] */ + __in LPCSTR pDescription) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddApplicationMessage( + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in LPCSTR pDescription) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnCategory( + /* [annotation] */ + __in D3D10_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in BOOL bEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnSeverity( + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in BOOL bEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnID( + /* [annotation] */ + __in D3D10_MESSAGE_ID ID, + /* [annotation] */ + __in BOOL bEnable) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnCategory( + /* [annotation] */ + __in D3D10_MESSAGE_CATEGORY Category) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnSeverity( + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnID( + /* [annotation] */ + __in D3D10_MESSAGE_ID ID) = 0; + + virtual void STDMETHODCALLTYPE SetMuteDebugOutput( + /* [annotation] */ + __in BOOL bMute) = 0; + + virtual BOOL STDMETHODCALLTYPE GetMuteDebugOutput( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10InfoQueueVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10InfoQueue * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10InfoQueue * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *SetMessageCountLimit )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in UINT64 MessageCountLimit); + + void ( STDMETHODCALLTYPE *ClearStoredMessages )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *GetMessage )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in UINT64 MessageIndex, + /* [annotation] */ + __out_bcount_opt(*pMessageByteLength) D3D10_MESSAGE *pMessage, + /* [annotation] */ + __inout SIZE_T *pMessageByteLength); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesAllowedByStorageFilter )( + ID3D10InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesDeniedByStorageFilter )( + ID3D10InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumStoredMessages )( + ID3D10InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumStoredMessagesAllowedByRetrievalFilter )( + ID3D10InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesDiscardedByMessageCountLimit )( + ID3D10InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetMessageCountLimit )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddStorageFilterEntries )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter); + + HRESULT ( STDMETHODCALLTYPE *GetStorageFilter )( + ID3D10InfoQueue * This, + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D10_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength); + + void ( STDMETHODCALLTYPE *ClearStorageFilter )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushEmptyStorageFilter )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushCopyOfStorageFilter )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushStorageFilter )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter); + + void ( STDMETHODCALLTYPE *PopStorageFilter )( + ID3D10InfoQueue * This); + + UINT ( STDMETHODCALLTYPE *GetStorageFilterStackSize )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddRetrievalFilterEntries )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter); + + HRESULT ( STDMETHODCALLTYPE *GetRetrievalFilter )( + ID3D10InfoQueue * This, + /* [annotation] */ + __out_bcount_opt(*pFilterByteLength) D3D10_INFO_QUEUE_FILTER *pFilter, + /* [annotation] */ + __inout SIZE_T *pFilterByteLength); + + void ( STDMETHODCALLTYPE *ClearRetrievalFilter )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushEmptyRetrievalFilter )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushCopyOfRetrievalFilter )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushRetrievalFilter )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_INFO_QUEUE_FILTER *pFilter); + + void ( STDMETHODCALLTYPE *PopRetrievalFilter )( + ID3D10InfoQueue * This); + + UINT ( STDMETHODCALLTYPE *GetRetrievalFilterStackSize )( + ID3D10InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddMessage )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in D3D10_MESSAGE_ID ID, + /* [annotation] */ + __in LPCSTR pDescription); + + HRESULT ( STDMETHODCALLTYPE *AddApplicationMessage )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in LPCSTR pDescription); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnCategory )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_CATEGORY Category, + /* [annotation] */ + __in BOOL bEnable); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnSeverity )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity, + /* [annotation] */ + __in BOOL bEnable); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnID )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_ID ID, + /* [annotation] */ + __in BOOL bEnable); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnCategory )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_CATEGORY Category); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnSeverity )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_SEVERITY Severity); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnID )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in D3D10_MESSAGE_ID ID); + + void ( STDMETHODCALLTYPE *SetMuteDebugOutput )( + ID3D10InfoQueue * This, + /* [annotation] */ + __in BOOL bMute); + + BOOL ( STDMETHODCALLTYPE *GetMuteDebugOutput )( + ID3D10InfoQueue * This); + + END_INTERFACE + } ID3D10InfoQueueVtbl; + + interface ID3D10InfoQueue + { + CONST_VTBL struct ID3D10InfoQueueVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10InfoQueue_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10InfoQueue_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10InfoQueue_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10InfoQueue_SetMessageCountLimit(This,MessageCountLimit) \ + ( (This)->lpVtbl -> SetMessageCountLimit(This,MessageCountLimit) ) + +#define ID3D10InfoQueue_ClearStoredMessages(This) \ + ( (This)->lpVtbl -> ClearStoredMessages(This) ) + +#define ID3D10InfoQueue_GetMessage(This,MessageIndex,pMessage,pMessageByteLength) \ + ( (This)->lpVtbl -> GetMessage(This,MessageIndex,pMessage,pMessageByteLength) ) + +#define ID3D10InfoQueue_GetNumMessagesAllowedByStorageFilter(This) \ + ( (This)->lpVtbl -> GetNumMessagesAllowedByStorageFilter(This) ) + +#define ID3D10InfoQueue_GetNumMessagesDeniedByStorageFilter(This) \ + ( (This)->lpVtbl -> GetNumMessagesDeniedByStorageFilter(This) ) + +#define ID3D10InfoQueue_GetNumStoredMessages(This) \ + ( (This)->lpVtbl -> GetNumStoredMessages(This) ) + +#define ID3D10InfoQueue_GetNumStoredMessagesAllowedByRetrievalFilter(This) \ + ( (This)->lpVtbl -> GetNumStoredMessagesAllowedByRetrievalFilter(This) ) + +#define ID3D10InfoQueue_GetNumMessagesDiscardedByMessageCountLimit(This) \ + ( (This)->lpVtbl -> GetNumMessagesDiscardedByMessageCountLimit(This) ) + +#define ID3D10InfoQueue_GetMessageCountLimit(This) \ + ( (This)->lpVtbl -> GetMessageCountLimit(This) ) + +#define ID3D10InfoQueue_AddStorageFilterEntries(This,pFilter) \ + ( (This)->lpVtbl -> AddStorageFilterEntries(This,pFilter) ) + +#define ID3D10InfoQueue_GetStorageFilter(This,pFilter,pFilterByteLength) \ + ( (This)->lpVtbl -> GetStorageFilter(This,pFilter,pFilterByteLength) ) + +#define ID3D10InfoQueue_ClearStorageFilter(This) \ + ( (This)->lpVtbl -> ClearStorageFilter(This) ) + +#define ID3D10InfoQueue_PushEmptyStorageFilter(This) \ + ( (This)->lpVtbl -> PushEmptyStorageFilter(This) ) + +#define ID3D10InfoQueue_PushCopyOfStorageFilter(This) \ + ( (This)->lpVtbl -> PushCopyOfStorageFilter(This) ) + +#define ID3D10InfoQueue_PushStorageFilter(This,pFilter) \ + ( (This)->lpVtbl -> PushStorageFilter(This,pFilter) ) + +#define ID3D10InfoQueue_PopStorageFilter(This) \ + ( (This)->lpVtbl -> PopStorageFilter(This) ) + +#define ID3D10InfoQueue_GetStorageFilterStackSize(This) \ + ( (This)->lpVtbl -> GetStorageFilterStackSize(This) ) + +#define ID3D10InfoQueue_AddRetrievalFilterEntries(This,pFilter) \ + ( (This)->lpVtbl -> AddRetrievalFilterEntries(This,pFilter) ) + +#define ID3D10InfoQueue_GetRetrievalFilter(This,pFilter,pFilterByteLength) \ + ( (This)->lpVtbl -> GetRetrievalFilter(This,pFilter,pFilterByteLength) ) + +#define ID3D10InfoQueue_ClearRetrievalFilter(This) \ + ( (This)->lpVtbl -> ClearRetrievalFilter(This) ) + +#define ID3D10InfoQueue_PushEmptyRetrievalFilter(This) \ + ( (This)->lpVtbl -> PushEmptyRetrievalFilter(This) ) + +#define ID3D10InfoQueue_PushCopyOfRetrievalFilter(This) \ + ( (This)->lpVtbl -> PushCopyOfRetrievalFilter(This) ) + +#define ID3D10InfoQueue_PushRetrievalFilter(This,pFilter) \ + ( (This)->lpVtbl -> PushRetrievalFilter(This,pFilter) ) + +#define ID3D10InfoQueue_PopRetrievalFilter(This) \ + ( (This)->lpVtbl -> PopRetrievalFilter(This) ) + +#define ID3D10InfoQueue_GetRetrievalFilterStackSize(This) \ + ( (This)->lpVtbl -> GetRetrievalFilterStackSize(This) ) + +#define ID3D10InfoQueue_AddMessage(This,Category,Severity,ID,pDescription) \ + ( (This)->lpVtbl -> AddMessage(This,Category,Severity,ID,pDescription) ) + +#define ID3D10InfoQueue_AddApplicationMessage(This,Severity,pDescription) \ + ( (This)->lpVtbl -> AddApplicationMessage(This,Severity,pDescription) ) + +#define ID3D10InfoQueue_SetBreakOnCategory(This,Category,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnCategory(This,Category,bEnable) ) + +#define ID3D10InfoQueue_SetBreakOnSeverity(This,Severity,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnSeverity(This,Severity,bEnable) ) + +#define ID3D10InfoQueue_SetBreakOnID(This,ID,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnID(This,ID,bEnable) ) + +#define ID3D10InfoQueue_GetBreakOnCategory(This,Category) \ + ( (This)->lpVtbl -> GetBreakOnCategory(This,Category) ) + +#define ID3D10InfoQueue_GetBreakOnSeverity(This,Severity) \ + ( (This)->lpVtbl -> GetBreakOnSeverity(This,Severity) ) + +#define ID3D10InfoQueue_GetBreakOnID(This,ID) \ + ( (This)->lpVtbl -> GetBreakOnID(This,ID) ) + +#define ID3D10InfoQueue_SetMuteDebugOutput(This,bMute) \ + ( (This)->lpVtbl -> SetMuteDebugOutput(This,bMute) ) + +#define ID3D10InfoQueue_GetMuteDebugOutput(This) \ + ( (This)->lpVtbl -> GetMuteDebugOutput(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10InfoQueue_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d10sdklayers_0000_0003 */ +/* [local] */ + +#define D3D10_REGKEY_PATH __TEXT("Software\\Microsoft\\Direct3D") +#define D3D10_MUTE_DEBUG_OUTPUT __TEXT("MuteDebugOutput") +#define D3D10_ENABLE_BREAK_ON_MESSAGE __TEXT("EnableBreakOnMessage") +#define D3D10_INFOQUEUE_STORAGE_FILTER_OVERRIDE __TEXT("InfoQueueStorageFilterOverride") +#define D3D10_MUTE_CATEGORY __TEXT("Mute_CATEGORY_%s") +#define D3D10_MUTE_SEVERITY __TEXT("Mute_SEVERITY_%s") +#define D3D10_MUTE_ID_STRING __TEXT("Mute_ID_%s") +#define D3D10_MUTE_ID_DECIMAL __TEXT("Mute_ID_%d") +#define D3D10_UNMUTE_SEVERITY_INFO __TEXT("Unmute_SEVERITY_INFO") +#define D3D10_BREAKON_CATEGORY __TEXT("BreakOn_CATEGORY_%s") +#define D3D10_BREAKON_SEVERITY __TEXT("BreakOn_SEVERITY_%s") +#define D3D10_BREAKON_ID_STRING __TEXT("BreakOn_ID_%s") +#define D3D10_BREAKON_ID_DECIMAL __TEXT("BreakOn_ID_%d") +#define D3D10_APPSIZE_STRING __TEXT("Size") +#define D3D10_APPNAME_STRING __TEXT("Name") +DEFINE_GUID(IID_ID3D10Debug,0x9B7E4E01,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10SwitchToRef,0x9B7E4E02,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10InfoQueue,0x1b940b17,0x2642,0x4d1f,0xab,0x1f,0xb9,0x9b,0xad,0x0c,0x39,0x5f); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d10sdklayers_0000_0003_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d10sdklayers_0000_0003_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/dxsdk/Include/d3d9.h b/dxsdk/Include/d3d9.h new file mode 100644 index 0000000..e5c7847 --- /dev/null +++ b/dxsdk/Include/d3d9.h @@ -0,0 +1,2791 @@ +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: d3d9.h + * Content: Direct3D include file + * + ****************************************************************************/ + +#ifndef _D3D9_H_ +#define _D3D9_H_ + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0900 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX9 interfaces +#if(DIRECT3D_VERSION >= 0x0900) + + +/* This identifier is passed to Direct3DCreate9 in order to ensure that an + * application was built against the correct header files. This number is + * incremented whenever a header (or other) change would require applications + * to be rebuilt. If the version doesn't match, Direct3DCreate9 will fail. + * (The number itself has no meaning.)*/ + +#ifdef D3D_DEBUG_INFO +#define D3D_SDK_VERSION (32 | 0x80000000) +#define D3D9b_SDK_VERSION (31 | 0x80000000) + +#else +#define D3D_SDK_VERSION 32 +#define D3D9b_SDK_VERSION 31 +#endif + + +#include + +#define COM_NO_WINDOWS_H +#include + +#include + +#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500) + #define HMONITOR_DECLARED + DECLARE_HANDLE(HMONITOR); +#endif + +#define D3DAPI WINAPI + +/* + * Interface IID's + */ +#if defined( _WIN32 ) && !defined( _NO_COM) + +/* IID_IDirect3D9 */ +/* {81BDCBCA-64D4-426d-AE8D-AD0147F4275C} */ +DEFINE_GUID(IID_IDirect3D9, 0x81bdcbca, 0x64d4, 0x426d, 0xae, 0x8d, 0xad, 0x1, 0x47, 0xf4, 0x27, 0x5c); + +/* IID_IDirect3DDevice9 */ +// {D0223B96-BF7A-43fd-92BD-A43B0D82B9EB} */ +DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb); + +/* IID_IDirect3DResource9 */ +// {05EEC05D-8F7D-4362-B999-D1BAF357C704} +DEFINE_GUID(IID_IDirect3DResource9, 0x5eec05d, 0x8f7d, 0x4362, 0xb9, 0x99, 0xd1, 0xba, 0xf3, 0x57, 0xc7, 0x4); + +/* IID_IDirect3DBaseTexture9 */ +/* {580CA87E-1D3C-4d54-991D-B7D3E3C298CE} */ +DEFINE_GUID(IID_IDirect3DBaseTexture9, 0x580ca87e, 0x1d3c, 0x4d54, 0x99, 0x1d, 0xb7, 0xd3, 0xe3, 0xc2, 0x98, 0xce); + +/* IID_IDirect3DTexture9 */ +/* {85C31227-3DE5-4f00-9B3A-F11AC38C18B5} */ +DEFINE_GUID(IID_IDirect3DTexture9, 0x85c31227, 0x3de5, 0x4f00, 0x9b, 0x3a, 0xf1, 0x1a, 0xc3, 0x8c, 0x18, 0xb5); + +/* IID_IDirect3DCubeTexture9 */ +/* {FFF32F81-D953-473a-9223-93D652ABA93F} */ +DEFINE_GUID(IID_IDirect3DCubeTexture9, 0xfff32f81, 0xd953, 0x473a, 0x92, 0x23, 0x93, 0xd6, 0x52, 0xab, 0xa9, 0x3f); + +/* IID_IDirect3DVolumeTexture9 */ +/* {2518526C-E789-4111-A7B9-47EF328D13E6} */ +DEFINE_GUID(IID_IDirect3DVolumeTexture9, 0x2518526c, 0xe789, 0x4111, 0xa7, 0xb9, 0x47, 0xef, 0x32, 0x8d, 0x13, 0xe6); + +/* IID_IDirect3DVertexBuffer9 */ +/* {B64BB1B5-FD70-4df6-BF91-19D0A12455E3} */ +DEFINE_GUID(IID_IDirect3DVertexBuffer9, 0xb64bb1b5, 0xfd70, 0x4df6, 0xbf, 0x91, 0x19, 0xd0, 0xa1, 0x24, 0x55, 0xe3); + +/* IID_IDirect3DIndexBuffer9 */ +/* {7C9DD65E-D3F7-4529-ACEE-785830ACDE35} */ +DEFINE_GUID(IID_IDirect3DIndexBuffer9, 0x7c9dd65e, 0xd3f7, 0x4529, 0xac, 0xee, 0x78, 0x58, 0x30, 0xac, 0xde, 0x35); + +/* IID_IDirect3DSurface9 */ +/* {0CFBAF3A-9FF6-429a-99B3-A2796AF8B89B} */ +DEFINE_GUID(IID_IDirect3DSurface9, 0xcfbaf3a, 0x9ff6, 0x429a, 0x99, 0xb3, 0xa2, 0x79, 0x6a, 0xf8, 0xb8, 0x9b); + +/* IID_IDirect3DVolume9 */ +/* {24F416E6-1F67-4aa7-B88E-D33F6F3128A1} */ +DEFINE_GUID(IID_IDirect3DVolume9, 0x24f416e6, 0x1f67, 0x4aa7, 0xb8, 0x8e, 0xd3, 0x3f, 0x6f, 0x31, 0x28, 0xa1); + +/* IID_IDirect3DSwapChain9 */ +/* {794950F2-ADFC-458a-905E-10A10B0B503B} */ +DEFINE_GUID(IID_IDirect3DSwapChain9, 0x794950f2, 0xadfc, 0x458a, 0x90, 0x5e, 0x10, 0xa1, 0xb, 0xb, 0x50, 0x3b); + +/* IID_IDirect3DVertexDeclaration9 */ +/* {DD13C59C-36FA-4098-A8FB-C7ED39DC8546} */ +DEFINE_GUID(IID_IDirect3DVertexDeclaration9, 0xdd13c59c, 0x36fa, 0x4098, 0xa8, 0xfb, 0xc7, 0xed, 0x39, 0xdc, 0x85, 0x46); + +/* IID_IDirect3DVertexShader9 */ +/* {EFC5557E-6265-4613-8A94-43857889EB36} */ +DEFINE_GUID(IID_IDirect3DVertexShader9, 0xefc5557e, 0x6265, 0x4613, 0x8a, 0x94, 0x43, 0x85, 0x78, 0x89, 0xeb, 0x36); + +/* IID_IDirect3DPixelShader9 */ +/* {6D3BDBDC-5B02-4415-B852-CE5E8BCCB289} */ +DEFINE_GUID(IID_IDirect3DPixelShader9, 0x6d3bdbdc, 0x5b02, 0x4415, 0xb8, 0x52, 0xce, 0x5e, 0x8b, 0xcc, 0xb2, 0x89); + +/* IID_IDirect3DStateBlock9 */ +/* {B07C4FE5-310D-4ba8-A23C-4F0F206F218B} */ +DEFINE_GUID(IID_IDirect3DStateBlock9, 0xb07c4fe5, 0x310d, 0x4ba8, 0xa2, 0x3c, 0x4f, 0xf, 0x20, 0x6f, 0x21, 0x8b); + +/* IID_IDirect3DQuery9 */ +/* {d9771460-a695-4f26-bbd3-27b840b541cc} */ +DEFINE_GUID(IID_IDirect3DQuery9, 0xd9771460, 0xa695, 0x4f26, 0xbb, 0xd3, 0x27, 0xb8, 0x40, 0xb5, 0x41, 0xcc); + + +/* IID_HelperName */ +/* {E4A36723-FDFE-4b22-B146-3C04C07F4CC8} */ +DEFINE_GUID(IID_HelperName, 0xe4a36723, 0xfdfe, 0x4b22, 0xb1, 0x46, 0x3c, 0x4, 0xc0, 0x7f, 0x4c, 0xc8); + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +/* IID_IDirect3D9Ex */ +/* {02177241-69FC-400C-8FF1-93A44DF6861D} */ +DEFINE_GUID(IID_IDirect3D9Ex, 0x02177241, 0x69FC, 0x400C, 0x8F, 0xF1, 0x93, 0xA4, 0x4D, 0xF6, 0x86, 0x1D); + +/* IID_IDirect3DDevice9Ex */ +// {B18B10CE-2649-405a-870F-95F777D4313A} +DEFINE_GUID(IID_IDirect3DDevice9Ex, 0xb18b10ce, 0x2649, 0x405a, 0x87, 0xf, 0x95, 0xf7, 0x77, 0xd4, 0x31, 0x3a); + +/* IID_IDirect3DSwapChain9Ex */ +/* {91886CAF-1C3D-4d2e-A0AB-3E4C7D8D3303} */ +DEFINE_GUID(IID_IDirect3DSwapChain9Ex, 0x91886caf, 0x1c3d, 0x4d2e, 0xa0, 0xab, 0x3e, 0x4c, 0x7d, 0x8d, 0x33, 0x3); + +/* IID_IDirect3D9ExOverlayExtension */ +/* {187aeb13-aaf5-4c59-876d-e059088c0df8} */ +DEFINE_GUID(IID_IDirect3D9ExOverlayExtension, 0x187aeb13, 0xaaf5, 0x4c59, 0x87, 0x6d, 0xe0, 0x59, 0x8, 0x8c, 0xd, 0xf8); + +/* IID_IDirect3DDevice9Video */ +// {26DC4561-A1EE-4ae7-96DA-118A36C0EC95} +DEFINE_GUID(IID_IDirect3DDevice9Video, 0x26dc4561, 0xa1ee, 0x4ae7, 0x96, 0xda, 0x11, 0x8a, 0x36, 0xc0, 0xec, 0x95); + +/* IID_IDirect3D9AuthenticatedChannel */ +// {FF24BEEE-DA21-4beb-98B5-D2F899F98AF9} +DEFINE_GUID(IID_IDirect3DAuthenticatedChannel9, 0xff24beee, 0xda21, 0x4beb, 0x98, 0xb5, 0xd2, 0xf8, 0x99, 0xf9, 0x8a, 0xf9); + +/* IID_IDirect3DCryptoSession9 */ +// {FA0AB799-7A9C-48ca-8C5B-237E71A54434} +DEFINE_GUID(IID_IDirect3DCryptoSession9, 0xfa0ab799, 0x7a9c, 0x48ca, 0x8c, 0x5b, 0x23, 0x7e, 0x71, 0xa5, 0x44, 0x34); + + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +#endif + +#ifdef __cplusplus + +#ifndef DECLSPEC_UUID +#if _MSC_VER >= 1100 +#define DECLSPEC_UUID(x) __declspec(uuid(x)) +#else +#define DECLSPEC_UUID(x) +#endif +#endif + +interface DECLSPEC_UUID("81BDCBCA-64D4-426d-AE8D-AD0147F4275C") IDirect3D9; +interface DECLSPEC_UUID("D0223B96-BF7A-43fd-92BD-A43B0D82B9EB") IDirect3DDevice9; + +interface DECLSPEC_UUID("B07C4FE5-310D-4ba8-A23C-4F0F206F218B") IDirect3DStateBlock9; +interface DECLSPEC_UUID("05EEC05D-8F7D-4362-B999-D1BAF357C704") IDirect3DResource9; +interface DECLSPEC_UUID("DD13C59C-36FA-4098-A8FB-C7ED39DC8546") IDirect3DVertexDeclaration9; +interface DECLSPEC_UUID("EFC5557E-6265-4613-8A94-43857889EB36") IDirect3DVertexShader9; +interface DECLSPEC_UUID("6D3BDBDC-5B02-4415-B852-CE5E8BCCB289") IDirect3DPixelShader9; +interface DECLSPEC_UUID("580CA87E-1D3C-4d54-991D-B7D3E3C298CE") IDirect3DBaseTexture9; +interface DECLSPEC_UUID("85C31227-3DE5-4f00-9B3A-F11AC38C18B5") IDirect3DTexture9; +interface DECLSPEC_UUID("2518526C-E789-4111-A7B9-47EF328D13E6") IDirect3DVolumeTexture9; +interface DECLSPEC_UUID("FFF32F81-D953-473a-9223-93D652ABA93F") IDirect3DCubeTexture9; + +interface DECLSPEC_UUID("B64BB1B5-FD70-4df6-BF91-19D0A12455E3") IDirect3DVertexBuffer9; +interface DECLSPEC_UUID("7C9DD65E-D3F7-4529-ACEE-785830ACDE35") IDirect3DIndexBuffer9; + +interface DECLSPEC_UUID("0CFBAF3A-9FF6-429a-99B3-A2796AF8B89B") IDirect3DSurface9; +interface DECLSPEC_UUID("24F416E6-1F67-4aa7-B88E-D33F6F3128A1") IDirect3DVolume9; + +interface DECLSPEC_UUID("794950F2-ADFC-458a-905E-10A10B0B503B") IDirect3DSwapChain9; +interface DECLSPEC_UUID("d9771460-a695-4f26-bbd3-27b840b541cc") IDirect3DQuery9; + + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +interface DECLSPEC_UUID("02177241-69FC-400C-8FF1-93A44DF6861D") IDirect3D9Ex; +interface DECLSPEC_UUID("B18B10CE-2649-405a-870F-95F777D4313A") IDirect3DDevice9Ex; +interface DECLSPEC_UUID("91886CAF-1C3D-4d2e-A0AB-3E4C7D8D3303") IDirect3DSwapChain9Ex; +interface DECLSPEC_UUID("187AEB13-AAF5-4C59-876D-E059088C0DF8") IDirect3D9ExOverlayExtension; +interface DECLSPEC_UUID("26DC4561-A1EE-4ae7-96DA-118A36C0EC95") IDirect3DDevice9Video; +interface DECLSPEC_UUID("FF24BEEE-DA21-4beb-98B5-D2F899F98AF9") IDirect3DAuthenticatedChannel9; +interface DECLSPEC_UUID("FA0AB799-7A9C-48CA-8C5B-237E71A54434") IDirect3DCryptoSession9; + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +#if defined(_COM_SMARTPTR_TYPEDEF) +_COM_SMARTPTR_TYPEDEF(IDirect3D9, __uuidof(IDirect3D9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DDevice9, __uuidof(IDirect3DDevice9)); + +_COM_SMARTPTR_TYPEDEF(IDirect3DStateBlock9, __uuidof(IDirect3DStateBlock9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DResource9, __uuidof(IDirect3DResource9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DVertexDeclaration9, __uuidof(IDirect3DVertexDeclaration9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DVertexShader9, __uuidof(IDirect3DVertexShader9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DPixelShader9, __uuidof(IDirect3DPixelShader9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DBaseTexture9, __uuidof(IDirect3DBaseTexture9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DTexture9, __uuidof(IDirect3DTexture9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DVolumeTexture9, __uuidof(IDirect3DVolumeTexture9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DCubeTexture9, __uuidof(IDirect3DCubeTexture9)); + +_COM_SMARTPTR_TYPEDEF(IDirect3DVertexBuffer9, __uuidof(IDirect3DVertexBuffer9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DIndexBuffer9, __uuidof(IDirect3DIndexBuffer9)); + +_COM_SMARTPTR_TYPEDEF(IDirect3DSurface9, __uuidof(IDirect3DSurface9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DVolume9, __uuidof(IDirect3DVolume9)); + +_COM_SMARTPTR_TYPEDEF(IDirect3DSwapChain9, __uuidof(IDirect3DSwapChain9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DQuery9, __uuidof(IDirect3DQuery9)); + + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +_COM_SMARTPTR_TYPEDEF(IDirect3D9Ex, __uuidof(IDirect3D9Ex)); +_COM_SMARTPTR_TYPEDEF(IDirect3DDevice9Ex, __uuidof(IDirect3DDevice9Ex)); +_COM_SMARTPTR_TYPEDEF(IDirect3DSwapChain9Ex, __uuidof(IDirect3DSwapChain9Ex)); +_COM_SMARTPTR_TYPEDEF(IDirect3D9ExOverlayExtension, __uuidof(IDirect3D9ExOverlayExtension)); +_COM_SMARTPTR_TYPEDEF(IDirect3DDevice9Video, __uuidof(IDirect3DDevice9Video)); +_COM_SMARTPTR_TYPEDEF(IDirect3DAuthenticatedChannel9, __uuidof(IDirect3DAuthenticatedChannel9)); +_COM_SMARTPTR_TYPEDEF(IDirect3DCryptoSession9, __uuidof(IDirect3DCryptoSession9)); + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +#endif + +#endif + + +typedef interface IDirect3D9 IDirect3D9; +typedef interface IDirect3DDevice9 IDirect3DDevice9; +typedef interface IDirect3DStateBlock9 IDirect3DStateBlock9; +typedef interface IDirect3DVertexDeclaration9 IDirect3DVertexDeclaration9; +typedef interface IDirect3DVertexShader9 IDirect3DVertexShader9; +typedef interface IDirect3DPixelShader9 IDirect3DPixelShader9; +typedef interface IDirect3DResource9 IDirect3DResource9; +typedef interface IDirect3DBaseTexture9 IDirect3DBaseTexture9; +typedef interface IDirect3DTexture9 IDirect3DTexture9; +typedef interface IDirect3DVolumeTexture9 IDirect3DVolumeTexture9; +typedef interface IDirect3DCubeTexture9 IDirect3DCubeTexture9; +typedef interface IDirect3DVertexBuffer9 IDirect3DVertexBuffer9; +typedef interface IDirect3DIndexBuffer9 IDirect3DIndexBuffer9; +typedef interface IDirect3DSurface9 IDirect3DSurface9; +typedef interface IDirect3DVolume9 IDirect3DVolume9; +typedef interface IDirect3DSwapChain9 IDirect3DSwapChain9; +typedef interface IDirect3DQuery9 IDirect3DQuery9; + + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + + +typedef interface IDirect3D9Ex IDirect3D9Ex; +typedef interface IDirect3DDevice9Ex IDirect3DDevice9Ex; +typedef interface IDirect3DSwapChain9Ex IDirect3DSwapChain9Ex; +typedef interface IDirect3D9ExOverlayExtension IDirect3D9ExOverlayExtension; +typedef interface IDirect3DDevice9Video IDirect3DDevice9Video; +typedef interface IDirect3DAuthenticatedChannel9 IDirect3DAuthenticatedChannel9; +typedef interface IDirect3DCryptoSession9 IDirect3DCryptoSession9; + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +#include "d3d9types.h" +#include "d3d9caps.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * DLL Function for creating a Direct3D9 object. This object supports + * enumeration and allows the creation of Direct3DDevice9 objects. + * Pass the value of the constant D3D_SDK_VERSION to this function, so + * that the run-time can validate that your application was compiled + * against the right headers. + */ + +IDirect3D9 * WINAPI Direct3DCreate9(UINT SDKVersion); + +/* + * Stubs for graphics profiling. + */ + +int WINAPI D3DPERF_BeginEvent( D3DCOLOR col, LPCWSTR wszName ); +int WINAPI D3DPERF_EndEvent( void ); +void WINAPI D3DPERF_SetMarker( D3DCOLOR col, LPCWSTR wszName ); +void WINAPI D3DPERF_SetRegion( D3DCOLOR col, LPCWSTR wszName ); +BOOL WINAPI D3DPERF_QueryRepeatFrame( void ); + +void WINAPI D3DPERF_SetOptions( DWORD dwOptions ); +DWORD WINAPI D3DPERF_GetStatus( void ); + +/* + * Direct3D interfaces + */ + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3D9 + +DECLARE_INTERFACE_(IDirect3D9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3D9 methods ***/ + STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE; + STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; + STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE; + STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE; + STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE; + STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE; + STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE; + STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE; + STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE; + STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE; + STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Version; + #endif +}; + +typedef struct IDirect3D9 *LPDIRECT3D9, *PDIRECT3D9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3D9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3D9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3D9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3D9_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a) +#define IDirect3D9_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p) +#define IDirect3D9_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c) +#define IDirect3D9_GetAdapterModeCount(p,a,b) (p)->lpVtbl->GetAdapterModeCount(p,a,b) +#define IDirect3D9_EnumAdapterModes(p,a,b,c,d) (p)->lpVtbl->EnumAdapterModes(p,a,b,c,d) +#define IDirect3D9_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b) +#define IDirect3D9_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e) +#define IDirect3D9_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f) +#define IDirect3D9_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e,f) +#define IDirect3D9_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e) +#define IDirect3D9_CheckDeviceFormatConversion(p,a,b,c,d) (p)->lpVtbl->CheckDeviceFormatConversion(p,a,b,c,d) +#define IDirect3D9_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c) +#define IDirect3D9_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a) +#define IDirect3D9_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f) +#else +#define IDirect3D9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3D9_AddRef(p) (p)->AddRef() +#define IDirect3D9_Release(p) (p)->Release() +#define IDirect3D9_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a) +#define IDirect3D9_GetAdapterCount(p) (p)->GetAdapterCount() +#define IDirect3D9_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c) +#define IDirect3D9_GetAdapterModeCount(p,a,b) (p)->GetAdapterModeCount(a,b) +#define IDirect3D9_EnumAdapterModes(p,a,b,c,d) (p)->EnumAdapterModes(a,b,c,d) +#define IDirect3D9_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b) +#define IDirect3D9_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e) +#define IDirect3D9_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f) +#define IDirect3D9_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->CheckDeviceMultiSampleType(a,b,c,d,e,f) +#define IDirect3D9_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e) +#define IDirect3D9_CheckDeviceFormatConversion(p,a,b,c,d) (p)->CheckDeviceFormatConversion(a,b,c,d) +#define IDirect3D9_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c) +#define IDirect3D9_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a) +#define IDirect3D9_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f) +#endif + + + + + + + +/* SwapChain */ + + + + + + + + + + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DDevice9 + +DECLARE_INTERFACE_(IDirect3DDevice9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DDevice9 methods ***/ + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE; + STDMETHOD(EvictManagedResources)(THIS) PURE; + STDMETHOD(GetDirect3D)(THIS_ IDirect3D9** ppD3D9) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS9* pCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ UINT iSwapChain,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE; + STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface9* pCursorBitmap) PURE; + STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y,DWORD Flags) PURE; + STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE; + STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain) PURE; + STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain,IDirect3DSwapChain9** pSwapChain) PURE; + STDMETHOD_(UINT, GetNumberOfSwapChains)(THIS) PURE; + STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT iSwapChain,UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ UINT iSwapChain,D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD(SetDialogBoxMode)(THIS_ BOOL bEnableDialogs) PURE; + STDMETHOD_(void, SetGammaRamp)(THIS_ UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp) PURE; + STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain,D3DGAMMARAMP* pRamp) PURE; + STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(UpdateSurface)(THIS_ IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestinationSurface,CONST POINT* pDestPoint) PURE; + STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture) PURE; + STDMETHOD(GetRenderTargetData)(THIS_ IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(StretchRect)(THIS_ IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter) PURE; + STDMETHOD(ColorFill)(THIS_ IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color) PURE; + STDMETHOD(CreateOffscreenPlainSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(SetRenderTarget)(THIS_ DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) PURE; + STDMETHOD(GetRenderTarget)(THIS_ DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget) PURE; + STDMETHOD(SetDepthStencilSurface)(THIS_ IDirect3DSurface9* pNewZStencil) PURE; + STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface9** ppZStencilSurface) PURE; + STDMETHOD(BeginScene)(THIS) PURE; + STDMETHOD(EndScene)(THIS) PURE; + STDMETHOD(Clear)(THIS_ DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) PURE; + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) PURE; + STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) PURE; + STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) PURE; + STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL9* pMaterial) PURE; + STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL9* pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index,CONST D3DLIGHT9*) PURE; + STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT9*) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; + STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL* pEnable) PURE; + STDMETHOD(SetClipPlane)(THIS_ DWORD Index,CONST float* pPlane) PURE; + STDMETHOD(GetClipPlane)(THIS_ DWORD Index,float* pPlane) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE; + STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD* pValue) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,IDirect3DStateBlock9** ppSB) PURE; + STDMETHOD(BeginStateBlock)(THIS) PURE; + STDMETHOD(EndStateBlock)(THIS_ IDirect3DStateBlock9** ppSB) PURE; + STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS9* pClipStatus) PURE; + STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS9* pClipStatus) PURE; + STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture9** ppTexture) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture9* pTexture) PURE; + STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE; + STDMETHOD(GetSamplerState)(THIS_ DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value) PURE; + STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE; + STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,CONST PALETTEENTRY* pEntries) PURE; + STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE; + STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE; + STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE; + STDMETHOD(SetScissorRect)(THIS_ CONST RECT* pRect) PURE; + STDMETHOD(GetScissorRect)(THIS_ RECT* pRect) PURE; + STDMETHOD(SetSoftwareVertexProcessing)(THIS_ BOOL bSoftware) PURE; + STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(THIS) PURE; + STDMETHOD(SetNPatchMode)(THIS_ float nSegments) PURE; + STDMETHOD_(float, GetNPatchMode)(THIS) PURE; + STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE; + STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE; + STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer9* pDestBuffer,IDirect3DVertexDeclaration9* pVertexDecl,DWORD Flags) PURE; + STDMETHOD(CreateVertexDeclaration)(THIS_ CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl) PURE; + STDMETHOD(SetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9* pDecl) PURE; + STDMETHOD(GetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9** ppDecl) PURE; + STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE; + STDMETHOD(GetFVF)(THIS_ DWORD* pFVF) PURE; + STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader) PURE; + STDMETHOD(SetVertexShader)(THIS_ IDirect3DVertexShader9* pShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ IDirect3DVertexShader9** ppShader) PURE; + STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(GetVertexShaderConstantF)(THIS_ UINT StartRegister,float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(GetVertexShaderConstantI)(THIS_ UINT StartRegister,int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(GetVertexShaderConstantB)(THIS_ UINT StartRegister,BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) PURE; + STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer9** ppStreamData,UINT* pOffsetInBytes,UINT* pStride) PURE; + STDMETHOD(SetStreamSourceFreq)(THIS_ UINT StreamNumber,UINT Setting) PURE; + STDMETHOD(GetStreamSourceFreq)(THIS_ UINT StreamNumber,UINT* pSetting) PURE; + STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer9* pIndexData) PURE; + STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer9** ppIndexData) PURE; + STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader) PURE; + STDMETHOD(SetPixelShader)(THIS_ IDirect3DPixelShader9* pShader) PURE; + STDMETHOD(GetPixelShader)(THIS_ IDirect3DPixelShader9** ppShader) PURE; + STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(GetPixelShaderConstantF)(THIS_ UINT StartRegister,float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(GetPixelShaderConstantI)(THIS_ UINT StartRegister,int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(GetPixelShaderConstantB)(THIS_ UINT StartRegister,BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE; + STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE; + STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; + STDMETHOD(CreateQuery)(THIS_ D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery) PURE; + + #ifdef D3D_DEBUG_INFO + D3DDEVICE_CREATION_PARAMETERS CreationParameters; + D3DPRESENT_PARAMETERS PresentParameters; + D3DDISPLAYMODE DisplayMode; + D3DCAPS9 Caps; + + UINT AvailableTextureMem; + UINT SwapChains; + UINT Textures; + UINT VertexBuffers; + UINT IndexBuffers; + UINT VertexShaders; + UINT PixelShaders; + + D3DVIEWPORT9 Viewport; + D3DMATRIX ProjectionMatrix; + D3DMATRIX ViewMatrix; + D3DMATRIX WorldMatrix; + D3DMATRIX TextureMatrices[8]; + + DWORD FVF; + UINT VertexSize; + DWORD VertexShaderVersion; + DWORD PixelShaderVersion; + BOOL SoftwareVertexProcessing; + + D3DMATERIAL9 Material; + D3DLIGHT9 Lights[16]; + BOOL LightsEnabled[16]; + + D3DGAMMARAMP GammaRamp; + RECT ScissorRect; + BOOL DialogBoxMode; + #endif +}; + +typedef struct IDirect3DDevice9 *LPDIRECT3DDEVICE9, *PDIRECT3DDEVICE9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DDevice9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DDevice9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DDevice9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DDevice9_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p) +#define IDirect3DDevice9_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p) +#define IDirect3DDevice9_EvictManagedResources(p) (p)->lpVtbl->EvictManagedResources(p) +#define IDirect3DDevice9_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a) +#define IDirect3DDevice9_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a) +#define IDirect3DDevice9_GetDisplayMode(p,a,b) (p)->lpVtbl->GetDisplayMode(p,a,b) +#define IDirect3DDevice9_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a) +#define IDirect3DDevice9_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c) +#define IDirect3DDevice9_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c) +#define IDirect3DDevice9_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a) +#define IDirect3DDevice9_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b) +#define IDirect3DDevice9_GetSwapChain(p,a,b) (p)->lpVtbl->GetSwapChain(p,a,b) +#define IDirect3DDevice9_GetNumberOfSwapChains(p) (p)->lpVtbl->GetNumberOfSwapChains(p) +#define IDirect3DDevice9_Reset(p,a) (p)->lpVtbl->Reset(p,a) +#define IDirect3DDevice9_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DDevice9_GetBackBuffer(p,a,b,c,d) (p)->lpVtbl->GetBackBuffer(p,a,b,c,d) +#define IDirect3DDevice9_GetRasterStatus(p,a,b) (p)->lpVtbl->GetRasterStatus(p,a,b) +#define IDirect3DDevice9_SetDialogBoxMode(p,a) (p)->lpVtbl->SetDialogBoxMode(p,a) +#define IDirect3DDevice9_SetGammaRamp(p,a,b,c) (p)->lpVtbl->SetGammaRamp(p,a,b,c) +#define IDirect3DDevice9_GetGammaRamp(p,a,b) (p)->lpVtbl->GetGammaRamp(p,a,b) +#define IDirect3DDevice9_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g) +#define IDirect3DDevice9_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e,f) +#define IDirect3DDevice9_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e,f) +#define IDirect3DDevice9_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_UpdateSurface(p,a,b,c,d) (p)->lpVtbl->UpdateSurface(p,a,b,c,d) +#define IDirect3DDevice9_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b) +#define IDirect3DDevice9_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b) +#define IDirect3DDevice9_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b) +#define IDirect3DDevice9_StretchRect(p,a,b,c,d,e) (p)->lpVtbl->StretchRect(p,a,b,c,d,e) +#define IDirect3DDevice9_ColorFill(p,a,b,c) (p)->lpVtbl->ColorFill(p,a,b,c) +#define IDirect3DDevice9_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->lpVtbl->CreateOffscreenPlainSurface(p,a,b,c,d,e,f) +#define IDirect3DDevice9_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b) +#define IDirect3DDevice9_GetRenderTarget(p,a,b) (p)->lpVtbl->GetRenderTarget(p,a,b) +#define IDirect3DDevice9_SetDepthStencilSurface(p,a) (p)->lpVtbl->SetDepthStencilSurface(p,a) +#define IDirect3DDevice9_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a) +#define IDirect3DDevice9_BeginScene(p) (p)->lpVtbl->BeginScene(p) +#define IDirect3DDevice9_EndScene(p) (p)->lpVtbl->EndScene(p) +#define IDirect3DDevice9_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f) +#define IDirect3DDevice9_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b) +#define IDirect3DDevice9_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b) +#define IDirect3DDevice9_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b) +#define IDirect3DDevice9_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a) +#define IDirect3DDevice9_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a) +#define IDirect3DDevice9_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a) +#define IDirect3DDevice9_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a) +#define IDirect3DDevice9_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b) +#define IDirect3DDevice9_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b) +#define IDirect3DDevice9_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b) +#define IDirect3DDevice9_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b) +#define IDirect3DDevice9_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b) +#define IDirect3DDevice9_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b) +#define IDirect3DDevice9_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b) +#define IDirect3DDevice9_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b) +#define IDirect3DDevice9_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b) +#define IDirect3DDevice9_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p) +#define IDirect3DDevice9_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a) +#define IDirect3DDevice9_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a) +#define IDirect3DDevice9_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a) +#define IDirect3DDevice9_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b) +#define IDirect3DDevice9_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b) +#define IDirect3DDevice9_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c) +#define IDirect3DDevice9_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c) +#define IDirect3DDevice9_GetSamplerState(p,a,b,c) (p)->lpVtbl->GetSamplerState(p,a,b,c) +#define IDirect3DDevice9_SetSamplerState(p,a,b,c) (p)->lpVtbl->SetSamplerState(p,a,b,c) +#define IDirect3DDevice9_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a) +#define IDirect3DDevice9_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b) +#define IDirect3DDevice9_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b) +#define IDirect3DDevice9_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a) +#define IDirect3DDevice9_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a) +#define IDirect3DDevice9_SetScissorRect(p,a) (p)->lpVtbl->SetScissorRect(p,a) +#define IDirect3DDevice9_GetScissorRect(p,a) (p)->lpVtbl->GetScissorRect(p,a) +#define IDirect3DDevice9_SetSoftwareVertexProcessing(p,a) (p)->lpVtbl->SetSoftwareVertexProcessing(p,a) +#define IDirect3DDevice9_GetSoftwareVertexProcessing(p) (p)->lpVtbl->GetSoftwareVertexProcessing(p) +#define IDirect3DDevice9_SetNPatchMode(p,a) (p)->lpVtbl->SetNPatchMode(p,a) +#define IDirect3DDevice9_GetNPatchMode(p) (p)->lpVtbl->GetNPatchMode(p) +#define IDirect3DDevice9_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c) +#define IDirect3DDevice9_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f) +#define IDirect3DDevice9_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) +#define IDirect3DDevice9_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_ProcessVertices(p,a,b,c,d,e,f) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e,f) +#define IDirect3DDevice9_CreateVertexDeclaration(p,a,b) (p)->lpVtbl->CreateVertexDeclaration(p,a,b) +#define IDirect3DDevice9_SetVertexDeclaration(p,a) (p)->lpVtbl->SetVertexDeclaration(p,a) +#define IDirect3DDevice9_GetVertexDeclaration(p,a) (p)->lpVtbl->GetVertexDeclaration(p,a) +#define IDirect3DDevice9_SetFVF(p,a) (p)->lpVtbl->SetFVF(p,a) +#define IDirect3DDevice9_GetFVF(p,a) (p)->lpVtbl->GetFVF(p,a) +#define IDirect3DDevice9_CreateVertexShader(p,a,b) (p)->lpVtbl->CreateVertexShader(p,a,b) +#define IDirect3DDevice9_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a) +#define IDirect3DDevice9_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a) +#define IDirect3DDevice9_SetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantF(p,a,b,c) +#define IDirect3DDevice9_GetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantF(p,a,b,c) +#define IDirect3DDevice9_SetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantI(p,a,b,c) +#define IDirect3DDevice9_GetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantI(p,a,b,c) +#define IDirect3DDevice9_SetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantB(p,a,b,c) +#define IDirect3DDevice9_GetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantB(p,a,b,c) +#define IDirect3DDevice9_SetStreamSource(p,a,b,c,d) (p)->lpVtbl->SetStreamSource(p,a,b,c,d) +#define IDirect3DDevice9_GetStreamSource(p,a,b,c,d) (p)->lpVtbl->GetStreamSource(p,a,b,c,d) +#define IDirect3DDevice9_SetStreamSourceFreq(p,a,b) (p)->lpVtbl->SetStreamSourceFreq(p,a,b) +#define IDirect3DDevice9_GetStreamSourceFreq(p,a,b) (p)->lpVtbl->GetStreamSourceFreq(p,a,b) +#define IDirect3DDevice9_SetIndices(p,a) (p)->lpVtbl->SetIndices(p,a) +#define IDirect3DDevice9_GetIndices(p,a) (p)->lpVtbl->GetIndices(p,a) +#define IDirect3DDevice9_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b) +#define IDirect3DDevice9_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a) +#define IDirect3DDevice9_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a) +#define IDirect3DDevice9_SetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantF(p,a,b,c) +#define IDirect3DDevice9_GetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantF(p,a,b,c) +#define IDirect3DDevice9_SetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantI(p,a,b,c) +#define IDirect3DDevice9_GetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantI(p,a,b,c) +#define IDirect3DDevice9_SetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantB(p,a,b,c) +#define IDirect3DDevice9_GetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantB(p,a,b,c) +#define IDirect3DDevice9_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c) +#define IDirect3DDevice9_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c) +#define IDirect3DDevice9_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a) +#define IDirect3DDevice9_CreateQuery(p,a,b) (p)->lpVtbl->CreateQuery(p,a,b) +#else +#define IDirect3DDevice9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DDevice9_AddRef(p) (p)->AddRef() +#define IDirect3DDevice9_Release(p) (p)->Release() +#define IDirect3DDevice9_TestCooperativeLevel(p) (p)->TestCooperativeLevel() +#define IDirect3DDevice9_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem() +#define IDirect3DDevice9_EvictManagedResources(p) (p)->EvictManagedResources() +#define IDirect3DDevice9_GetDirect3D(p,a) (p)->GetDirect3D(a) +#define IDirect3DDevice9_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a) +#define IDirect3DDevice9_GetDisplayMode(p,a,b) (p)->GetDisplayMode(a,b) +#define IDirect3DDevice9_GetCreationParameters(p,a) (p)->GetCreationParameters(a) +#define IDirect3DDevice9_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c) +#define IDirect3DDevice9_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c) +#define IDirect3DDevice9_ShowCursor(p,a) (p)->ShowCursor(a) +#define IDirect3DDevice9_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b) +#define IDirect3DDevice9_GetSwapChain(p,a,b) (p)->GetSwapChain(a,b) +#define IDirect3DDevice9_GetNumberOfSwapChains(p) (p)->GetNumberOfSwapChains() +#define IDirect3DDevice9_Reset(p,a) (p)->Reset(a) +#define IDirect3DDevice9_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DDevice9_GetBackBuffer(p,a,b,c,d) (p)->GetBackBuffer(a,b,c,d) +#define IDirect3DDevice9_GetRasterStatus(p,a,b) (p)->GetRasterStatus(a,b) +#define IDirect3DDevice9_SetDialogBoxMode(p,a) (p)->SetDialogBoxMode(a) +#define IDirect3DDevice9_SetGammaRamp(p,a,b,c) (p)->SetGammaRamp(a,b,c) +#define IDirect3DDevice9_GetGammaRamp(p,a,b) (p)->GetGammaRamp(a,b) +#define IDirect3DDevice9_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->CreateTexture(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->CreateCubeTexture(a,b,c,d,e,f,g) +#define IDirect3DDevice9_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->CreateVertexBuffer(a,b,c,d,e,f) +#define IDirect3DDevice9_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->CreateIndexBuffer(a,b,c,d,e,f) +#define IDirect3DDevice9_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->CreateRenderTarget(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->CreateDepthStencilSurface(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_UpdateSurface(p,a,b,c,d) (p)->UpdateSurface(a,b,c,d) +#define IDirect3DDevice9_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b) +#define IDirect3DDevice9_GetRenderTargetData(p,a,b) (p)->GetRenderTargetData(a,b) +#define IDirect3DDevice9_GetFrontBufferData(p,a,b) (p)->GetFrontBufferData(a,b) +#define IDirect3DDevice9_StretchRect(p,a,b,c,d,e) (p)->StretchRect(a,b,c,d,e) +#define IDirect3DDevice9_ColorFill(p,a,b,c) (p)->ColorFill(a,b,c) +#define IDirect3DDevice9_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->CreateOffscreenPlainSurface(a,b,c,d,e,f) +#define IDirect3DDevice9_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b) +#define IDirect3DDevice9_GetRenderTarget(p,a,b) (p)->GetRenderTarget(a,b) +#define IDirect3DDevice9_SetDepthStencilSurface(p,a) (p)->SetDepthStencilSurface(a) +#define IDirect3DDevice9_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a) +#define IDirect3DDevice9_BeginScene(p) (p)->BeginScene() +#define IDirect3DDevice9_EndScene(p) (p)->EndScene() +#define IDirect3DDevice9_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f) +#define IDirect3DDevice9_SetTransform(p,a,b) (p)->SetTransform(a,b) +#define IDirect3DDevice9_GetTransform(p,a,b) (p)->GetTransform(a,b) +#define IDirect3DDevice9_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b) +#define IDirect3DDevice9_SetViewport(p,a) (p)->SetViewport(a) +#define IDirect3DDevice9_GetViewport(p,a) (p)->GetViewport(a) +#define IDirect3DDevice9_SetMaterial(p,a) (p)->SetMaterial(a) +#define IDirect3DDevice9_GetMaterial(p,a) (p)->GetMaterial(a) +#define IDirect3DDevice9_SetLight(p,a,b) (p)->SetLight(a,b) +#define IDirect3DDevice9_GetLight(p,a,b) (p)->GetLight(a,b) +#define IDirect3DDevice9_LightEnable(p,a,b) (p)->LightEnable(a,b) +#define IDirect3DDevice9_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b) +#define IDirect3DDevice9_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b) +#define IDirect3DDevice9_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b) +#define IDirect3DDevice9_SetRenderState(p,a,b) (p)->SetRenderState(a,b) +#define IDirect3DDevice9_GetRenderState(p,a,b) (p)->GetRenderState(a,b) +#define IDirect3DDevice9_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b) +#define IDirect3DDevice9_BeginStateBlock(p) (p)->BeginStateBlock() +#define IDirect3DDevice9_EndStateBlock(p,a) (p)->EndStateBlock(a) +#define IDirect3DDevice9_SetClipStatus(p,a) (p)->SetClipStatus(a) +#define IDirect3DDevice9_GetClipStatus(p,a) (p)->GetClipStatus(a) +#define IDirect3DDevice9_GetTexture(p,a,b) (p)->GetTexture(a,b) +#define IDirect3DDevice9_SetTexture(p,a,b) (p)->SetTexture(a,b) +#define IDirect3DDevice9_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c) +#define IDirect3DDevice9_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c) +#define IDirect3DDevice9_GetSamplerState(p,a,b,c) (p)->GetSamplerState(a,b,c) +#define IDirect3DDevice9_SetSamplerState(p,a,b,c) (p)->SetSamplerState(a,b,c) +#define IDirect3DDevice9_ValidateDevice(p,a) (p)->ValidateDevice(a) +#define IDirect3DDevice9_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b) +#define IDirect3DDevice9_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b) +#define IDirect3DDevice9_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a) +#define IDirect3DDevice9_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a) +#define IDirect3DDevice9_SetScissorRect(p,a) (p)->SetScissorRect(a) +#define IDirect3DDevice9_GetScissorRect(p,a) (p)->GetScissorRect(a) +#define IDirect3DDevice9_SetSoftwareVertexProcessing(p,a) (p)->SetSoftwareVertexProcessing(a) +#define IDirect3DDevice9_GetSoftwareVertexProcessing(p) (p)->GetSoftwareVertexProcessing() +#define IDirect3DDevice9_SetNPatchMode(p,a) (p)->SetNPatchMode(a) +#define IDirect3DDevice9_GetNPatchMode(p) (p)->GetNPatchMode() +#define IDirect3DDevice9_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c) +#define IDirect3DDevice9_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->DrawIndexedPrimitive(a,b,c,d,e,f) +#define IDirect3DDevice9_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d) +#define IDirect3DDevice9_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9_ProcessVertices(p,a,b,c,d,e,f) (p)->ProcessVertices(a,b,c,d,e,f) +#define IDirect3DDevice9_CreateVertexDeclaration(p,a,b) (p)->CreateVertexDeclaration(a,b) +#define IDirect3DDevice9_SetVertexDeclaration(p,a) (p)->SetVertexDeclaration(a) +#define IDirect3DDevice9_GetVertexDeclaration(p,a) (p)->GetVertexDeclaration(a) +#define IDirect3DDevice9_SetFVF(p,a) (p)->SetFVF(a) +#define IDirect3DDevice9_GetFVF(p,a) (p)->GetFVF(a) +#define IDirect3DDevice9_CreateVertexShader(p,a,b) (p)->CreateVertexShader(a,b) +#define IDirect3DDevice9_SetVertexShader(p,a) (p)->SetVertexShader(a) +#define IDirect3DDevice9_GetVertexShader(p,a) (p)->GetVertexShader(a) +#define IDirect3DDevice9_SetVertexShaderConstantF(p,a,b,c) (p)->SetVertexShaderConstantF(a,b,c) +#define IDirect3DDevice9_GetVertexShaderConstantF(p,a,b,c) (p)->GetVertexShaderConstantF(a,b,c) +#define IDirect3DDevice9_SetVertexShaderConstantI(p,a,b,c) (p)->SetVertexShaderConstantI(a,b,c) +#define IDirect3DDevice9_GetVertexShaderConstantI(p,a,b,c) (p)->GetVertexShaderConstantI(a,b,c) +#define IDirect3DDevice9_SetVertexShaderConstantB(p,a,b,c) (p)->SetVertexShaderConstantB(a,b,c) +#define IDirect3DDevice9_GetVertexShaderConstantB(p,a,b,c) (p)->GetVertexShaderConstantB(a,b,c) +#define IDirect3DDevice9_SetStreamSource(p,a,b,c,d) (p)->SetStreamSource(a,b,c,d) +#define IDirect3DDevice9_GetStreamSource(p,a,b,c,d) (p)->GetStreamSource(a,b,c,d) +#define IDirect3DDevice9_SetStreamSourceFreq(p,a,b) (p)->SetStreamSourceFreq(a,b) +#define IDirect3DDevice9_GetStreamSourceFreq(p,a,b) (p)->GetStreamSourceFreq(a,b) +#define IDirect3DDevice9_SetIndices(p,a) (p)->SetIndices(a) +#define IDirect3DDevice9_GetIndices(p,a) (p)->GetIndices(a) +#define IDirect3DDevice9_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b) +#define IDirect3DDevice9_SetPixelShader(p,a) (p)->SetPixelShader(a) +#define IDirect3DDevice9_GetPixelShader(p,a) (p)->GetPixelShader(a) +#define IDirect3DDevice9_SetPixelShaderConstantF(p,a,b,c) (p)->SetPixelShaderConstantF(a,b,c) +#define IDirect3DDevice9_GetPixelShaderConstantF(p,a,b,c) (p)->GetPixelShaderConstantF(a,b,c) +#define IDirect3DDevice9_SetPixelShaderConstantI(p,a,b,c) (p)->SetPixelShaderConstantI(a,b,c) +#define IDirect3DDevice9_GetPixelShaderConstantI(p,a,b,c) (p)->GetPixelShaderConstantI(a,b,c) +#define IDirect3DDevice9_SetPixelShaderConstantB(p,a,b,c) (p)->SetPixelShaderConstantB(a,b,c) +#define IDirect3DDevice9_GetPixelShaderConstantB(p,a,b,c) (p)->GetPixelShaderConstantB(a,b,c) +#define IDirect3DDevice9_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c) +#define IDirect3DDevice9_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c) +#define IDirect3DDevice9_DeletePatch(p,a) (p)->DeletePatch(a) +#define IDirect3DDevice9_CreateQuery(p,a,b) (p)->CreateQuery(a,b) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DStateBlock9 + +DECLARE_INTERFACE_(IDirect3DStateBlock9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DStateBlock9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(Capture)(THIS) PURE; + STDMETHOD(Apply)(THIS) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DStateBlock9 *LPDIRECT3DSTATEBLOCK9, *PDIRECT3DSTATEBLOCK9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DStateBlock9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DStateBlock9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DStateBlock9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DStateBlock9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DStateBlock9_Capture(p) (p)->lpVtbl->Capture(p) +#define IDirect3DStateBlock9_Apply(p) (p)->lpVtbl->Apply(p) +#else +#define IDirect3DStateBlock9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DStateBlock9_AddRef(p) (p)->AddRef() +#define IDirect3DStateBlock9_Release(p) (p)->Release() +#define IDirect3DStateBlock9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DStateBlock9_Capture(p) (p)->Capture() +#define IDirect3DStateBlock9_Apply(p) (p)->Apply() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DSwapChain9 + +DECLARE_INTERFACE_(IDirect3DSwapChain9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSwapChain9 methods ***/ + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion,DWORD dwFlags) PURE; + STDMETHOD(GetFrontBufferData)(THIS_ IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetPresentParameters)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + + #ifdef D3D_DEBUG_INFO + D3DPRESENT_PARAMETERS PresentParameters; + D3DDISPLAYMODE DisplayMode; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DSwapChain9 *LPDIRECT3DSWAPCHAIN9, *PDIRECT3DSWAPCHAIN9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSwapChain9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSwapChain9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSwapChain9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSwapChain9_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e) +#define IDirect3DSwapChain9_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a) +#define IDirect3DSwapChain9_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#define IDirect3DSwapChain9_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) +#define IDirect3DSwapChain9_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a) +#define IDirect3DSwapChain9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DSwapChain9_GetPresentParameters(p,a) (p)->lpVtbl->GetPresentParameters(p,a) +#else +#define IDirect3DSwapChain9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSwapChain9_AddRef(p) (p)->AddRef() +#define IDirect3DSwapChain9_Release(p) (p)->Release() +#define IDirect3DSwapChain9_Present(p,a,b,c,d,e) (p)->Present(a,b,c,d,e) +#define IDirect3DSwapChain9_GetFrontBufferData(p,a) (p)->GetFrontBufferData(a) +#define IDirect3DSwapChain9_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#define IDirect3DSwapChain9_GetRasterStatus(p,a) (p)->GetRasterStatus(a) +#define IDirect3DSwapChain9_GetDisplayMode(p,a) (p)->GetDisplayMode(a) +#define IDirect3DSwapChain9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DSwapChain9_GetPresentParameters(p,a) (p)->GetPresentParameters(a) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DResource9 + +DECLARE_INTERFACE_(IDirect3DResource9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; +}; + +typedef struct IDirect3DResource9 *LPDIRECT3DRESOURCE9, *PDIRECT3DRESOURCE9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DResource9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DResource9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DResource9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DResource9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DResource9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DResource9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DResource9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DResource9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DResource9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DResource9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DResource9_GetType(p) (p)->lpVtbl->GetType(p) +#else +#define IDirect3DResource9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DResource9_AddRef(p) (p)->AddRef() +#define IDirect3DResource9_Release(p) (p)->Release() +#define IDirect3DResource9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DResource9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DResource9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DResource9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DResource9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DResource9_GetPriority(p) (p)->GetPriority() +#define IDirect3DResource9_PreLoad(p) (p)->PreLoad() +#define IDirect3DResource9_GetType(p) (p)->GetType() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVertexDeclaration9 + +DECLARE_INTERFACE_(IDirect3DVertexDeclaration9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DVertexDeclaration9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9* pElement,UINT* pNumElements) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DVertexDeclaration9 *LPDIRECT3DVERTEXDECLARATION9, *PDIRECT3DVERTEXDECLARATION9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVertexDeclaration9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVertexDeclaration9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVertexDeclaration9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVertexDeclaration9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVertexDeclaration9_GetDeclaration(p,a,b) (p)->lpVtbl->GetDeclaration(p,a,b) +#else +#define IDirect3DVertexDeclaration9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVertexDeclaration9_AddRef(p) (p)->AddRef() +#define IDirect3DVertexDeclaration9_Release(p) (p)->Release() +#define IDirect3DVertexDeclaration9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVertexDeclaration9_GetDeclaration(p,a,b) (p)->GetDeclaration(a,b) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVertexShader9 + +DECLARE_INTERFACE_(IDirect3DVertexShader9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DVertexShader9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetFunction)(THIS_ void*,UINT* pSizeOfData) PURE; + + #ifdef D3D_DEBUG_INFO + DWORD Version; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DVertexShader9 *LPDIRECT3DVERTEXSHADER9, *PDIRECT3DVERTEXSHADER9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVertexShader9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVertexShader9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVertexShader9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVertexShader9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVertexShader9_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b) +#else +#define IDirect3DVertexShader9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVertexShader9_AddRef(p) (p)->AddRef() +#define IDirect3DVertexShader9_Release(p) (p)->Release() +#define IDirect3DVertexShader9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVertexShader9_GetFunction(p,a,b) (p)->GetFunction(a,b) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DPixelShader9 + +DECLARE_INTERFACE_(IDirect3DPixelShader9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DPixelShader9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetFunction)(THIS_ void*,UINT* pSizeOfData) PURE; + + #ifdef D3D_DEBUG_INFO + DWORD Version; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DPixelShader9 *LPDIRECT3DPIXELSHADER9, *PDIRECT3DPIXELSHADER9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DPixelShader9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DPixelShader9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DPixelShader9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DPixelShader9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DPixelShader9_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b) +#else +#define IDirect3DPixelShader9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DPixelShader9_AddRef(p) (p)->AddRef() +#define IDirect3DPixelShader9_Release(p) (p)->Release() +#define IDirect3DPixelShader9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DPixelShader9_GetFunction(p,a,b) (p)->GetFunction(a,b) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DBaseTexture9 + +DECLARE_INTERFACE_(IDirect3DBaseTexture9, IDirect3DResource9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE; + STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE; + STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; +}; + +typedef struct IDirect3DBaseTexture9 *LPDIRECT3DBASETEXTURE9, *PDIRECT3DBASETEXTURE9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DBaseTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DBaseTexture9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DBaseTexture9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DBaseTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DBaseTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DBaseTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DBaseTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DBaseTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DBaseTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DBaseTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DBaseTexture9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DBaseTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DBaseTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DBaseTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DBaseTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a) +#define IDirect3DBaseTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p) +#define IDirect3DBaseTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) +#else +#define IDirect3DBaseTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DBaseTexture9_AddRef(p) (p)->AddRef() +#define IDirect3DBaseTexture9_Release(p) (p)->Release() +#define IDirect3DBaseTexture9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DBaseTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DBaseTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DBaseTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DBaseTexture9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DBaseTexture9_GetPriority(p) (p)->GetPriority() +#define IDirect3DBaseTexture9_PreLoad(p) (p)->PreLoad() +#define IDirect3DBaseTexture9_GetType(p) (p)->GetType() +#define IDirect3DBaseTexture9_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DBaseTexture9_GetLOD(p) (p)->GetLOD() +#define IDirect3DBaseTexture9_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DBaseTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a) +#define IDirect3DBaseTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType() +#define IDirect3DBaseTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels() +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DTexture9 + +DECLARE_INTERFACE_(IDirect3DTexture9, IDirect3DBaseTexture9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE; + STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE; + STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level,IDirect3DSurface9** ppSurfaceLevel) PURE; + STDMETHOD(LockRect)(THIS_ UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pDirtyRect) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Name; + UINT Width; + UINT Height; + UINT Levels; + DWORD Usage; + D3DFORMAT Format; + D3DPOOL Pool; + DWORD Priority; + DWORD LOD; + D3DTEXTUREFILTERTYPE FilterType; + UINT LockCount; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DTexture9 *LPDIRECT3DTEXTURE9, *PDIRECT3DTEXTURE9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DTexture9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DTexture9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DTexture9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a) +#define IDirect3DTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p) +#define IDirect3DTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) +#define IDirect3DTexture9_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DTexture9_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b) +#define IDirect3DTexture9_LockRect(p,a,b,c,d) (p)->lpVtbl->LockRect(p,a,b,c,d) +#define IDirect3DTexture9_UnlockRect(p,a) (p)->lpVtbl->UnlockRect(p,a) +#define IDirect3DTexture9_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a) +#else +#define IDirect3DTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DTexture9_AddRef(p) (p)->AddRef() +#define IDirect3DTexture9_Release(p) (p)->Release() +#define IDirect3DTexture9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DTexture9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DTexture9_GetPriority(p) (p)->GetPriority() +#define IDirect3DTexture9_PreLoad(p) (p)->PreLoad() +#define IDirect3DTexture9_GetType(p) (p)->GetType() +#define IDirect3DTexture9_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DTexture9_GetLOD(p) (p)->GetLOD() +#define IDirect3DTexture9_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a) +#define IDirect3DTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType() +#define IDirect3DTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels() +#define IDirect3DTexture9_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DTexture9_GetSurfaceLevel(p,a,b) (p)->GetSurfaceLevel(a,b) +#define IDirect3DTexture9_LockRect(p,a,b,c,d) (p)->LockRect(a,b,c,d) +#define IDirect3DTexture9_UnlockRect(p,a) (p)->UnlockRect(a) +#define IDirect3DTexture9_AddDirtyRect(p,a) (p)->AddDirtyRect(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolumeTexture9 + +DECLARE_INTERFACE_(IDirect3DVolumeTexture9, IDirect3DBaseTexture9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE; + STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE; + STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(GetVolumeLevel)(THIS_ UINT Level,IDirect3DVolume9** ppVolumeLevel) PURE; + STDMETHOD(LockBox)(THIS_ UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Name; + UINT Width; + UINT Height; + UINT Depth; + UINT Levels; + DWORD Usage; + D3DFORMAT Format; + D3DPOOL Pool; + DWORD Priority; + DWORD LOD; + D3DTEXTUREFILTERTYPE FilterType; + UINT LockCount; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DVolumeTexture9 *LPDIRECT3DVOLUMETEXTURE9, *PDIRECT3DVOLUMETEXTURE9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolumeTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolumeTexture9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolumeTexture9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolumeTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolumeTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolumeTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolumeTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolumeTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVolumeTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVolumeTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVolumeTexture9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVolumeTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DVolumeTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DVolumeTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DVolumeTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a) +#define IDirect3DVolumeTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p) +#define IDirect3DVolumeTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) +#define IDirect3DVolumeTexture9_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DVolumeTexture9_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b) +#define IDirect3DVolumeTexture9_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d) +#define IDirect3DVolumeTexture9_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a) +#define IDirect3DVolumeTexture9_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a) +#else +#define IDirect3DVolumeTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolumeTexture9_AddRef(p) (p)->AddRef() +#define IDirect3DVolumeTexture9_Release(p) (p)->Release() +#define IDirect3DVolumeTexture9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolumeTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolumeTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolumeTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolumeTexture9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVolumeTexture9_GetPriority(p) (p)->GetPriority() +#define IDirect3DVolumeTexture9_PreLoad(p) (p)->PreLoad() +#define IDirect3DVolumeTexture9_GetType(p) (p)->GetType() +#define IDirect3DVolumeTexture9_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DVolumeTexture9_GetLOD(p) (p)->GetLOD() +#define IDirect3DVolumeTexture9_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DVolumeTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a) +#define IDirect3DVolumeTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType() +#define IDirect3DVolumeTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels() +#define IDirect3DVolumeTexture9_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DVolumeTexture9_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b) +#define IDirect3DVolumeTexture9_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d) +#define IDirect3DVolumeTexture9_UnlockBox(p,a) (p)->UnlockBox(a) +#define IDirect3DVolumeTexture9_AddDirtyBox(p,a) (p)->AddDirtyBox(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DCubeTexture9 + +DECLARE_INTERFACE_(IDirect3DCubeTexture9, IDirect3DBaseTexture9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE; + STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE; + STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface) PURE; + STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType,CONST RECT* pDirtyRect) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Name; + UINT Width; + UINT Height; + UINT Levels; + DWORD Usage; + D3DFORMAT Format; + D3DPOOL Pool; + DWORD Priority; + DWORD LOD; + D3DTEXTUREFILTERTYPE FilterType; + UINT LockCount; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DCubeTexture9 *LPDIRECT3DCUBETEXTURE9, *PDIRECT3DCUBETEXTURE9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DCubeTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DCubeTexture9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DCubeTexture9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DCubeTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DCubeTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DCubeTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DCubeTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DCubeTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DCubeTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DCubeTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DCubeTexture9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DCubeTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DCubeTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DCubeTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DCubeTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a) +#define IDirect3DCubeTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p) +#define IDirect3DCubeTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) +#define IDirect3DCubeTexture9_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DCubeTexture9_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c) +#define IDirect3DCubeTexture9_LockRect(p,a,b,c,d,e) (p)->lpVtbl->LockRect(p,a,b,c,d,e) +#define IDirect3DCubeTexture9_UnlockRect(p,a,b) (p)->lpVtbl->UnlockRect(p,a,b) +#define IDirect3DCubeTexture9_AddDirtyRect(p,a,b) (p)->lpVtbl->AddDirtyRect(p,a,b) +#else +#define IDirect3DCubeTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DCubeTexture9_AddRef(p) (p)->AddRef() +#define IDirect3DCubeTexture9_Release(p) (p)->Release() +#define IDirect3DCubeTexture9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DCubeTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DCubeTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DCubeTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DCubeTexture9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DCubeTexture9_GetPriority(p) (p)->GetPriority() +#define IDirect3DCubeTexture9_PreLoad(p) (p)->PreLoad() +#define IDirect3DCubeTexture9_GetType(p) (p)->GetType() +#define IDirect3DCubeTexture9_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DCubeTexture9_GetLOD(p) (p)->GetLOD() +#define IDirect3DCubeTexture9_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DCubeTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a) +#define IDirect3DCubeTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType() +#define IDirect3DCubeTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels() +#define IDirect3DCubeTexture9_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DCubeTexture9_GetCubeMapSurface(p,a,b,c) (p)->GetCubeMapSurface(a,b,c) +#define IDirect3DCubeTexture9_LockRect(p,a,b,c,d,e) (p)->LockRect(a,b,c,d,e) +#define IDirect3DCubeTexture9_UnlockRect(p,a,b) (p)->UnlockRect(a,b) +#define IDirect3DCubeTexture9_AddDirtyRect(p,a,b) (p)->AddDirtyRect(a,b) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVertexBuffer9 + +DECLARE_INTERFACE_(IDirect3DVertexBuffer9, IDirect3DResource9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC *pDesc) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Name; + UINT Length; + DWORD Usage; + DWORD FVF; + D3DPOOL Pool; + DWORD Priority; + UINT LockCount; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DVertexBuffer9 *LPDIRECT3DVERTEXBUFFER9, *PDIRECT3DVERTEXBUFFER9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVertexBuffer9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVertexBuffer9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVertexBuffer9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVertexBuffer9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVertexBuffer9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVertexBuffer9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVertexBuffer9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVertexBuffer9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVertexBuffer9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVertexBuffer9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVertexBuffer9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVertexBuffer9_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DVertexBuffer9_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DVertexBuffer9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DVertexBuffer9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVertexBuffer9_AddRef(p) (p)->AddRef() +#define IDirect3DVertexBuffer9_Release(p) (p)->Release() +#define IDirect3DVertexBuffer9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVertexBuffer9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVertexBuffer9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVertexBuffer9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVertexBuffer9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVertexBuffer9_GetPriority(p) (p)->GetPriority() +#define IDirect3DVertexBuffer9_PreLoad(p) (p)->PreLoad() +#define IDirect3DVertexBuffer9_GetType(p) (p)->GetType() +#define IDirect3DVertexBuffer9_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DVertexBuffer9_Unlock(p) (p)->Unlock() +#define IDirect3DVertexBuffer9_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DIndexBuffer9 + +DECLARE_INTERFACE_(IDirect3DIndexBuffer9, IDirect3DResource9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC *pDesc) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Name; + UINT Length; + DWORD Usage; + D3DFORMAT Format; + D3DPOOL Pool; + DWORD Priority; + UINT LockCount; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DIndexBuffer9 *LPDIRECT3DINDEXBUFFER9, *PDIRECT3DINDEXBUFFER9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DIndexBuffer9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DIndexBuffer9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DIndexBuffer9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DIndexBuffer9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DIndexBuffer9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DIndexBuffer9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DIndexBuffer9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DIndexBuffer9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DIndexBuffer9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DIndexBuffer9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DIndexBuffer9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DIndexBuffer9_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DIndexBuffer9_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DIndexBuffer9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DIndexBuffer9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DIndexBuffer9_AddRef(p) (p)->AddRef() +#define IDirect3DIndexBuffer9_Release(p) (p)->Release() +#define IDirect3DIndexBuffer9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DIndexBuffer9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DIndexBuffer9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DIndexBuffer9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DIndexBuffer9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DIndexBuffer9_GetPriority(p) (p)->GetPriority() +#define IDirect3DIndexBuffer9_PreLoad(p) (p)->PreLoad() +#define IDirect3DIndexBuffer9_GetType(p) (p)->GetType() +#define IDirect3DIndexBuffer9_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DIndexBuffer9_Unlock(p) (p)->Unlock() +#define IDirect3DIndexBuffer9_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DSurface9 + +DECLARE_INTERFACE_(IDirect3DSurface9, IDirect3DResource9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS) PURE; + STDMETHOD(GetDC)(THIS_ HDC *phdc) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC hdc) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Name; + UINT Width; + UINT Height; + DWORD Usage; + D3DFORMAT Format; + D3DPOOL Pool; + D3DMULTISAMPLE_TYPE MultiSampleType; + DWORD MultiSampleQuality; + DWORD Priority; + UINT LockCount; + UINT DCCount; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DSurface9 *LPDIRECT3DSURFACE9, *PDIRECT3DSURFACE9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSurface9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSurface9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSurface9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSurface9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DSurface9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DSurface9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DSurface9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DSurface9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DSurface9_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DSurface9_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DSurface9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DSurface9_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DSurface9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DSurface9_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c) +#define IDirect3DSurface9_UnlockRect(p) (p)->lpVtbl->UnlockRect(p) +#define IDirect3DSurface9_GetDC(p,a) (p)->lpVtbl->GetDC(p,a) +#define IDirect3DSurface9_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a) +#else +#define IDirect3DSurface9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSurface9_AddRef(p) (p)->AddRef() +#define IDirect3DSurface9_Release(p) (p)->Release() +#define IDirect3DSurface9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DSurface9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DSurface9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DSurface9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DSurface9_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DSurface9_GetPriority(p) (p)->GetPriority() +#define IDirect3DSurface9_PreLoad(p) (p)->PreLoad() +#define IDirect3DSurface9_GetType(p) (p)->GetType() +#define IDirect3DSurface9_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DSurface9_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DSurface9_LockRect(p,a,b,c) (p)->LockRect(a,b,c) +#define IDirect3DSurface9_UnlockRect(p) (p)->UnlockRect() +#define IDirect3DSurface9_GetDC(p,a) (p)->GetDC(a) +#define IDirect3DSurface9_ReleaseDC(p,a) (p)->ReleaseDC(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolume9 + +DECLARE_INTERFACE_(IDirect3DVolume9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DVolume9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS) PURE; + + #ifdef D3D_DEBUG_INFO + LPCWSTR Name; + UINT Width; + UINT Height; + UINT Depth; + DWORD Usage; + D3DFORMAT Format; + D3DPOOL Pool; + UINT LockCount; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DVolume9 *LPDIRECT3DVOLUME9, *PDIRECT3DVOLUME9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolume9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolume9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolume9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolume9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolume9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolume9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolume9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolume9_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DVolume9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DVolume9_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c) +#define IDirect3DVolume9_UnlockBox(p) (p)->lpVtbl->UnlockBox(p) +#else +#define IDirect3DVolume9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolume9_AddRef(p) (p)->AddRef() +#define IDirect3DVolume9_Release(p) (p)->Release() +#define IDirect3DVolume9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolume9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolume9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolume9_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolume9_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DVolume9_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DVolume9_LockBox(p,a,b,c) (p)->LockBox(a,b,c) +#define IDirect3DVolume9_UnlockBox(p) (p)->UnlockBox() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DQuery9 + +DECLARE_INTERFACE_(IDirect3DQuery9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DQuery9 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD_(D3DQUERYTYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, GetDataSize)(THIS) PURE; + STDMETHOD(Issue)(THIS_ DWORD dwIssueFlags) PURE; + STDMETHOD(GetData)(THIS_ void* pData,DWORD dwSize,DWORD dwGetDataFlags) PURE; + + #ifdef D3D_DEBUG_INFO + D3DQUERYTYPE Type; + DWORD DataSize; + LPCWSTR CreationCallStack; + #endif +}; + +typedef struct IDirect3DQuery9 *LPDIRECT3DQUERY9, *PDIRECT3DQUERY9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DQuery9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DQuery9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DQuery9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DQuery9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DQuery9_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DQuery9_GetDataSize(p) (p)->lpVtbl->GetDataSize(p) +#define IDirect3DQuery9_Issue(p,a) (p)->lpVtbl->Issue(p,a) +#define IDirect3DQuery9_GetData(p,a,b,c) (p)->lpVtbl->GetData(p,a,b,c) +#else +#define IDirect3DQuery9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DQuery9_AddRef(p) (p)->AddRef() +#define IDirect3DQuery9_Release(p) (p)->Release() +#define IDirect3DQuery9_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DQuery9_GetType(p) (p)->GetType() +#define IDirect3DQuery9_GetDataSize(p) (p)->GetDataSize() +#define IDirect3DQuery9_Issue(p,a) (p)->Issue(a) +#define IDirect3DQuery9_GetData(p,a,b,c) (p)->GetData(a,b,c) +#endif + + +/**************************************************************************** + * Flags for SetPrivateData method on all D3D9 interfaces + * + * The passed pointer is an IUnknown ptr. The SizeOfData argument to SetPrivateData + * must be set to sizeof(IUnknown*). Direct3D will call AddRef through this + * pointer and Release when the private data is destroyed. The data will be + * destroyed when another SetPrivateData with the same GUID is set, when + * FreePrivateData is called, or when the D3D9 object is freed. + ****************************************************************************/ +#define D3DSPD_IUNKNOWN 0x00000001L + +/**************************************************************************** + * + * Flags for IDirect3D9::CreateDevice's BehaviorFlags + * + ****************************************************************************/ + +#define D3DCREATE_FPU_PRESERVE 0x00000002L +#define D3DCREATE_MULTITHREADED 0x00000004L + +#define D3DCREATE_PUREDEVICE 0x00000010L +#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L +#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L +#define D3DCREATE_MIXED_VERTEXPROCESSING 0x00000080L + +#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT 0x00000100L +#define D3DCREATE_ADAPTERGROUP_DEVICE 0x00000200L +#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX 0x00000400L + +// This flag causes the D3D runtime not to alter the focus +// window in any way. Use with caution- the burden of supporting +// focus management events (alt-tab, etc.) falls on the +// application, and appropriate responses (switching display +// mode, etc.) should be coded. +#define D3DCREATE_NOWINDOWCHANGES 0x00000800L + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +// Disable multithreading for software vertex processing +#define D3DCREATE_DISABLE_PSGP_THREADING 0x00002000L +// This flag enables present statistics on device. +#define D3DCREATE_ENABLE_PRESENTSTATS 0x00004000L +// This flag disables printscreen support in the runtime for this device +#define D3DCREATE_DISABLE_PRINTSCREEN 0x00008000L + +#define D3DCREATE_SCREENSAVER 0x10000000L + + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + + + +/**************************************************************************** + * + * Parameter for IDirect3D9::CreateDevice's Adapter argument + * + ****************************************************************************/ + +#define D3DADAPTER_DEFAULT 0 + +/**************************************************************************** + * + * Flags for IDirect3D9::EnumAdapters + * + ****************************************************************************/ + +/* + * The D3DENUM_WHQL_LEVEL value has been retired for 9Ex and future versions, + * but it needs to be defined here for compatibility with DX9 and earlier versions. + * See the DirectX SDK for sample code on discovering driver signatures. + */ +#define D3DENUM_WHQL_LEVEL 0x00000002L + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +/* NO_DRIVERVERSION will not fill out the DriverVersion field, nor will the + DriverVersion be incorporated into the DeviceIdentifier GUID. WINNT only */ +#define D3DENUM_NO_DRIVERVERSION 0x00000004L + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + + +/**************************************************************************** + * + * Maximum number of back-buffers supported in DX9 + * + ****************************************************************************/ + +#define D3DPRESENT_BACK_BUFFERS_MAX 3L + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +/**************************************************************************** + * + * Maximum number of back-buffers supported when apps use CreateDeviceEx + * + ****************************************************************************/ + +#define D3DPRESENT_BACK_BUFFERS_MAX_EX 30L + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +/**************************************************************************** + * + * Flags for IDirect3DDevice9::SetGammaRamp + * + ****************************************************************************/ + +#define D3DSGR_NO_CALIBRATION 0x00000000L +#define D3DSGR_CALIBRATE 0x00000001L + +/**************************************************************************** + * + * Flags for IDirect3DDevice9::SetCursorPosition + * + ****************************************************************************/ + +#define D3DCURSOR_IMMEDIATE_UPDATE 0x00000001L + +/**************************************************************************** + * + * Flags for IDirect3DSwapChain9::Present + * + ****************************************************************************/ + +#define D3DPRESENT_DONOTWAIT 0x00000001L +#define D3DPRESENT_LINEAR_CONTENT 0x00000002L + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +#define D3DPRESENT_DONOTFLIP 0x00000004L +#define D3DPRESENT_FLIPRESTART 0x00000008L +#define D3DPRESENT_VIDEO_RESTRICT_TO_MONITOR 0x00000010L +#define D3DPRESENT_UPDATEOVERLAYONLY 0x00000020L +#define D3DPRESENT_HIDEOVERLAY 0x00000040L +#define D3DPRESENT_UPDATECOLORKEY 0x00000080L +#define D3DPRESENT_FORCEIMMEDIATE 0x00000100L + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + + +/**************************************************************************** + * + * Flags for DrawPrimitive/DrawIndexedPrimitive + * Also valid for Begin/BeginIndexed + * Also valid for VertexBuffer::CreateVertexBuffer + ****************************************************************************/ + + +/* + * DirectDraw error codes + */ +#define _FACD3D 0x876 +#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) +#define MAKE_D3DSTATUS( code ) MAKE_HRESULT( 0, _FACD3D, code ) + +/* + * Direct3D Errors + */ +#define D3D_OK S_OK + +#define D3DERR_WRONGTEXTUREFORMAT MAKE_D3DHRESULT(2072) +#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT(2073) +#define D3DERR_UNSUPPORTEDCOLORARG MAKE_D3DHRESULT(2074) +#define D3DERR_UNSUPPORTEDALPHAOPERATION MAKE_D3DHRESULT(2075) +#define D3DERR_UNSUPPORTEDALPHAARG MAKE_D3DHRESULT(2076) +#define D3DERR_TOOMANYOPERATIONS MAKE_D3DHRESULT(2077) +#define D3DERR_CONFLICTINGTEXTUREFILTER MAKE_D3DHRESULT(2078) +#define D3DERR_UNSUPPORTEDFACTORVALUE MAKE_D3DHRESULT(2079) +#define D3DERR_CONFLICTINGRENDERSTATE MAKE_D3DHRESULT(2081) +#define D3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_D3DHRESULT(2082) +#define D3DERR_CONFLICTINGTEXTUREPALETTE MAKE_D3DHRESULT(2086) +#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087) + +#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150) +#define D3DERR_MOREDATA MAKE_D3DHRESULT(2151) +#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152) +#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153) +#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154) +#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380) +#define D3DERR_INVALIDDEVICE MAKE_D3DHRESULT(2155) +#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) +#define D3DERR_DRIVERINVALIDCALL MAKE_D3DHRESULT(2157) +#define D3DERR_WASSTILLDRAWING MAKE_D3DHRESULT(540) +#define D3DOK_NOAUTOGEN MAKE_D3DSTATUS(2159) + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + + +#define D3DERR_DEVICEREMOVED MAKE_D3DHRESULT(2160) +#define S_NOT_RESIDENT MAKE_D3DSTATUS(2165) +#define S_RESIDENT_IN_SHARED_MEMORY MAKE_D3DSTATUS(2166) +#define S_PRESENT_MODE_CHANGED MAKE_D3DSTATUS(2167) +#define S_PRESENT_OCCLUDED MAKE_D3DSTATUS(2168) +#define D3DERR_DEVICEHUNG MAKE_D3DHRESULT(2164) +#define D3DERR_UNSUPPORTEDOVERLAY MAKE_D3DHRESULT(2171) +#define D3DERR_UNSUPPORTEDOVERLAYFORMAT MAKE_D3DHRESULT(2172) +#define D3DERR_CANNOTPROTECTCONTENT MAKE_D3DHRESULT(2173) +#define D3DERR_UNSUPPORTEDCRYPTO MAKE_D3DHRESULT(2174) +#define D3DERR_PRESENT_STATISTICS_DISJOINT MAKE_D3DHRESULT(2180) + + +/********************* +/* D3D9Ex interfaces +/*********************/ + +HRESULT WINAPI Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex**); + + + + +#undef INTERFACE +#define INTERFACE IDirect3D9Ex + +DECLARE_INTERFACE_(IDirect3D9Ex, IDirect3D9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3D9 methods ***/ + STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; + STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE; + STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE; + STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE; + STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE; + STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE; + STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE; + STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE; + STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE; + STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE; + STDMETHOD_(UINT, GetAdapterModeCountEx)(THIS_ UINT Adapter,CONST D3DDISPLAYMODEFILTER* pFilter ) PURE; + STDMETHOD(EnumAdapterModesEx)(THIS_ UINT Adapter,CONST D3DDISPLAYMODEFILTER* pFilter,UINT Mode,D3DDISPLAYMODEEX* pMode) PURE; + STDMETHOD(GetAdapterDisplayModeEx)(THIS_ UINT Adapter,D3DDISPLAYMODEEX* pMode,D3DDISPLAYROTATION* pRotation) PURE; + STDMETHOD(CreateDeviceEx)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,D3DDISPLAYMODEEX* pFullscreenDisplayMode,IDirect3DDevice9Ex** ppReturnedDeviceInterface) PURE; + STDMETHOD(GetAdapterLUID)(THIS_ UINT Adapter,LUID * pLUID) PURE; +}; + +typedef struct IDirect3D9Ex *LPDIRECT3D9EX, *PDIRECT3D9EX; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3D9Ex_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3D9Ex_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3D9Ex_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3D9Ex_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p) +#define IDirect3D9Ex_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c) +#define IDirect3D9Ex_GetAdapterModeCount(p,a,b) (p)->lpVtbl->GetAdapterModeCount(p,a,b) +#define IDirect3D9Ex_EnumAdapterModes(p,a,b,c,d) (p)->lpVtbl->EnumAdapterModes(p,a,b,c,d) +#define IDirect3D9Ex_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b) +#define IDirect3D9Ex_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e) +#define IDirect3D9Ex_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f) +#define IDirect3D9Ex_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e,f) +#define IDirect3D9Ex_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e) +#define IDirect3D9Ex_CheckDeviceFormatConversion(p,a,b,c,d) (p)->lpVtbl->CheckDeviceFormatConversion(p,a,b,c,d) +#define IDirect3D9Ex_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c) +#define IDirect3D9Ex_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a) +#define IDirect3D9Ex_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f) +#define IDirect3D9Ex_GetAdapterModeCountEx(p,a,b) (p)->lpVtbl->GetAdapterModeCountEx(p,a,b) +#define IDirect3D9Ex_EnumAdapterModesEx(p,a,b,c,d) (p)->lpVtbl->EnumAdapterModesEx(p,a,b,c,d) +#define IDirect3D9Ex_GetAdapterDisplayModeEx(p,a,b,c) (p)->lpVtbl->GetAdapterDisplayModeEx(p,a,b,c) +#define IDirect3D9Ex_CreateDeviceEx(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d,e,f,g) +#define IDirect3D9Ex_GetAdapterLUID(p,a,b) (p)->lpVtbl->GetAdapterLUID(p,a,b) +#else +#define IDirect3D9Ex_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3D9Ex_AddRef(p) (p)->AddRef() +#define IDirect3D9Ex_Release(p) (p)->Release() +#define IDirect3D9Ex_GetAdapterCount(p) (p)->GetAdapterCount() +#define IDirect3D9Ex_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c) +#define IDirect3D9Ex_GetAdapterModeCount(p,a,b) (p)->GetAdapterModeCount(a,b) +#define IDirect3D9Ex_EnumAdapterModes(p,a,b,c,d) (p)->EnumAdapterModes(a,b,c,d) +#define IDirect3D9Ex_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b) +#define IDirect3D9Ex_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e) +#define IDirect3D9Ex_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f) +#define IDirect3D9Ex_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->CheckDeviceMultiSampleType(a,b,c,d,e,f) +#define IDirect3D9Ex_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e) +#define IDirect3D9Ex_CheckDeviceFormatConversion(p,a,b,c,d) (p)->CheckDeviceFormatConversion(a,b,c,d) +#define IDirect3D9Ex_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c) +#define IDirect3D9Ex_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a) +#define IDirect3D9Ex_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f) +#define IDirect3D9Ex_GetAdapterModeCountEx(p,a,b) (p)->GetAdapterModeCountEx(a,b) +#define IDirect3D9Ex_EnumAdapterModesEx(p,a,b,c,d) (p)->EnumAdapterModesEx(a,b,c,d) +#define IDirect3D9Ex_GetAdapterDisplayModeEx(p,a,b,c) (p)->GetAdapterDisplayModeEx(a,b,c) +#define IDirect3D9Ex_CreateDeviceEx(p,a,b,c,d,e,f,g) (p)->CreateDeviceEx(a,b,c,d,e,f,g) +#define IDirect3D9Ex_GetAdapterLUID(p,a,b) (p)->GetAdapterLUID(a,b) +#endif + + + + + + + + + + + + + + + + + + + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DDevice9Ex + +DECLARE_INTERFACE_(IDirect3DDevice9Ex, IDirect3DDevice9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DDevice9 methods ***/ + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE; + STDMETHOD(EvictManagedResources)(THIS) PURE; + STDMETHOD(GetDirect3D)(THIS_ IDirect3D9** ppD3D9) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS9* pCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ UINT iSwapChain,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE; + STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface9* pCursorBitmap) PURE; + STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y,DWORD Flags) PURE; + STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE; + STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain) PURE; + STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain,IDirect3DSwapChain9** pSwapChain) PURE; + STDMETHOD_(UINT, GetNumberOfSwapChains)(THIS) PURE; + STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT iSwapChain,UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ UINT iSwapChain,D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD(SetDialogBoxMode)(THIS_ BOOL bEnableDialogs) PURE; + STDMETHOD_(void, SetGammaRamp)(THIS_ UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp) PURE; + STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain,D3DGAMMARAMP* pRamp) PURE; + STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(UpdateSurface)(THIS_ IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestinationSurface,CONST POINT* pDestPoint) PURE; + STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture) PURE; + STDMETHOD(GetRenderTargetData)(THIS_ IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(StretchRect)(THIS_ IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter) PURE; + STDMETHOD(ColorFill)(THIS_ IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color) PURE; + STDMETHOD(CreateOffscreenPlainSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(SetRenderTarget)(THIS_ DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) PURE; + STDMETHOD(GetRenderTarget)(THIS_ DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget) PURE; + STDMETHOD(SetDepthStencilSurface)(THIS_ IDirect3DSurface9* pNewZStencil) PURE; + STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface9** ppZStencilSurface) PURE; + STDMETHOD(BeginScene)(THIS) PURE; + STDMETHOD(EndScene)(THIS) PURE; + STDMETHOD(Clear)(THIS_ DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) PURE; + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) PURE; + STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) PURE; + STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) PURE; + STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL9* pMaterial) PURE; + STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL9* pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index,CONST D3DLIGHT9*) PURE; + STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT9*) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; + STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL* pEnable) PURE; + STDMETHOD(SetClipPlane)(THIS_ DWORD Index,CONST float* pPlane) PURE; + STDMETHOD(GetClipPlane)(THIS_ DWORD Index,float* pPlane) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE; + STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD* pValue) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,IDirect3DStateBlock9** ppSB) PURE; + STDMETHOD(BeginStateBlock)(THIS) PURE; + STDMETHOD(EndStateBlock)(THIS_ IDirect3DStateBlock9** ppSB) PURE; + STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS9* pClipStatus) PURE; + STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS9* pClipStatus) PURE; + STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture9** ppTexture) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture9* pTexture) PURE; + STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE; + STDMETHOD(GetSamplerState)(THIS_ DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value) PURE; + STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE; + STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,CONST PALETTEENTRY* pEntries) PURE; + STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE; + STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE; + STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE; + STDMETHOD(SetScissorRect)(THIS_ CONST RECT* pRect) PURE; + STDMETHOD(GetScissorRect)(THIS_ RECT* pRect) PURE; + STDMETHOD(SetSoftwareVertexProcessing)(THIS_ BOOL bSoftware) PURE; + STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(THIS) PURE; + STDMETHOD(SetNPatchMode)(THIS_ float nSegments) PURE; + STDMETHOD_(float, GetNPatchMode)(THIS) PURE; + STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE; + STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE; + STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer9* pDestBuffer,IDirect3DVertexDeclaration9* pVertexDecl,DWORD Flags) PURE; + STDMETHOD(CreateVertexDeclaration)(THIS_ CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl) PURE; + STDMETHOD(SetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9* pDecl) PURE; + STDMETHOD(GetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9** ppDecl) PURE; + STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE; + STDMETHOD(GetFVF)(THIS_ DWORD* pFVF) PURE; + STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader) PURE; + STDMETHOD(SetVertexShader)(THIS_ IDirect3DVertexShader9* pShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ IDirect3DVertexShader9** ppShader) PURE; + STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(GetVertexShaderConstantF)(THIS_ UINT StartRegister,float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(GetVertexShaderConstantI)(THIS_ UINT StartRegister,int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(GetVertexShaderConstantB)(THIS_ UINT StartRegister,BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) PURE; + STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer9** ppStreamData,UINT* pOffsetInBytes,UINT* pStride) PURE; + STDMETHOD(SetStreamSourceFreq)(THIS_ UINT StreamNumber,UINT Setting) PURE; + STDMETHOD(GetStreamSourceFreq)(THIS_ UINT StreamNumber,UINT* pSetting) PURE; + STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer9* pIndexData) PURE; + STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer9** ppIndexData) PURE; + STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader) PURE; + STDMETHOD(SetPixelShader)(THIS_ IDirect3DPixelShader9* pShader) PURE; + STDMETHOD(GetPixelShader)(THIS_ IDirect3DPixelShader9** ppShader) PURE; + STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(GetPixelShaderConstantF)(THIS_ UINT StartRegister,float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(GetPixelShaderConstantI)(THIS_ UINT StartRegister,int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(GetPixelShaderConstantB)(THIS_ UINT StartRegister,BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE; + STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE; + STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; + STDMETHOD(CreateQuery)(THIS_ D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery) PURE; + STDMETHOD(SetConvolutionMonoKernel)(THIS_ UINT width,UINT height,float* rows,float* columns) PURE; + STDMETHOD(ComposeRects)(THIS_ IDirect3DSurface9* pSrc,IDirect3DSurface9* pDst,IDirect3DVertexBuffer9* pSrcRectDescs,UINT NumRects,IDirect3DVertexBuffer9* pDstRectDescs,D3DCOMPOSERECTSOP Operation,int Xoffset,int Yoffset) PURE; + STDMETHOD(PresentEx)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion,DWORD dwFlags) PURE; + STDMETHOD(GetGPUThreadPriority)(THIS_ INT* pPriority) PURE; + STDMETHOD(SetGPUThreadPriority)(THIS_ INT Priority) PURE; + STDMETHOD(WaitForVBlank)(THIS_ UINT iSwapChain) PURE; + STDMETHOD(CheckResourceResidency)(THIS_ IDirect3DResource9** pResourceArray,UINT32 NumResources) PURE; + STDMETHOD(SetMaximumFrameLatency)(THIS_ UINT MaxLatency) PURE; + STDMETHOD(GetMaximumFrameLatency)(THIS_ UINT* pMaxLatency) PURE; + STDMETHOD(CheckDeviceState)(THIS_ HWND hDestinationWindow) PURE; + STDMETHOD(CreateRenderTargetEx)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle,DWORD Usage) PURE; + STDMETHOD(CreateOffscreenPlainSurfaceEx)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle,DWORD Usage) PURE; + STDMETHOD(CreateDepthStencilSurfaceEx)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle,DWORD Usage) PURE; + STDMETHOD(ResetEx)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,D3DDISPLAYMODEEX *pFullscreenDisplayMode) PURE; + STDMETHOD(GetDisplayModeEx)(THIS_ UINT iSwapChain,D3DDISPLAYMODEEX* pMode,D3DDISPLAYROTATION* pRotation) PURE; +}; + +typedef struct IDirect3DDevice9Ex *LPDIRECT3DDEVICE9EX, *PDIRECT3DDEVICE9EX; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DDevice9Ex_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DDevice9Ex_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DDevice9Ex_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DDevice9Ex_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p) +#define IDirect3DDevice9Ex_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p) +#define IDirect3DDevice9Ex_EvictManagedResources(p) (p)->lpVtbl->EvictManagedResources(p) +#define IDirect3DDevice9Ex_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a) +#define IDirect3DDevice9Ex_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a) +#define IDirect3DDevice9Ex_GetDisplayMode(p,a,b) (p)->lpVtbl->GetDisplayMode(p,a,b) +#define IDirect3DDevice9Ex_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a) +#define IDirect3DDevice9Ex_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c) +#define IDirect3DDevice9Ex_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c) +#define IDirect3DDevice9Ex_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a) +#define IDirect3DDevice9Ex_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b) +#define IDirect3DDevice9Ex_GetSwapChain(p,a,b) (p)->lpVtbl->GetSwapChain(p,a,b) +#define IDirect3DDevice9Ex_GetNumberOfSwapChains(p) (p)->lpVtbl->GetNumberOfSwapChains(p) +#define IDirect3DDevice9Ex_Reset(p,a) (p)->lpVtbl->Reset(p,a) +#define IDirect3DDevice9Ex_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DDevice9Ex_GetBackBuffer(p,a,b,c,d) (p)->lpVtbl->GetBackBuffer(p,a,b,c,d) +#define IDirect3DDevice9Ex_GetRasterStatus(p,a,b) (p)->lpVtbl->GetRasterStatus(p,a,b) +#define IDirect3DDevice9Ex_SetDialogBoxMode(p,a) (p)->lpVtbl->SetDialogBoxMode(p,a) +#define IDirect3DDevice9Ex_SetGammaRamp(p,a,b,c) (p)->lpVtbl->SetGammaRamp(p,a,b,c) +#define IDirect3DDevice9Ex_GetGammaRamp(p,a,b) (p)->lpVtbl->GetGammaRamp(p,a,b) +#define IDirect3DDevice9Ex_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9Ex_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g) +#define IDirect3DDevice9Ex_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e,f) +#define IDirect3DDevice9Ex_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e,f) +#define IDirect3DDevice9Ex_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_UpdateSurface(p,a,b,c,d) (p)->lpVtbl->UpdateSurface(p,a,b,c,d) +#define IDirect3DDevice9Ex_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b) +#define IDirect3DDevice9Ex_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b) +#define IDirect3DDevice9Ex_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b) +#define IDirect3DDevice9Ex_StretchRect(p,a,b,c,d,e) (p)->lpVtbl->StretchRect(p,a,b,c,d,e) +#define IDirect3DDevice9Ex_ColorFill(p,a,b,c) (p)->lpVtbl->ColorFill(p,a,b,c) +#define IDirect3DDevice9Ex_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->lpVtbl->CreateOffscreenPlainSurface(p,a,b,c,d,e,f) +#define IDirect3DDevice9Ex_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b) +#define IDirect3DDevice9Ex_GetRenderTarget(p,a,b) (p)->lpVtbl->GetRenderTarget(p,a,b) +#define IDirect3DDevice9Ex_SetDepthStencilSurface(p,a) (p)->lpVtbl->SetDepthStencilSurface(p,a) +#define IDirect3DDevice9Ex_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a) +#define IDirect3DDevice9Ex_BeginScene(p) (p)->lpVtbl->BeginScene(p) +#define IDirect3DDevice9Ex_EndScene(p) (p)->lpVtbl->EndScene(p) +#define IDirect3DDevice9Ex_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f) +#define IDirect3DDevice9Ex_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b) +#define IDirect3DDevice9Ex_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b) +#define IDirect3DDevice9Ex_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b) +#define IDirect3DDevice9Ex_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a) +#define IDirect3DDevice9Ex_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a) +#define IDirect3DDevice9Ex_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a) +#define IDirect3DDevice9Ex_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a) +#define IDirect3DDevice9Ex_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b) +#define IDirect3DDevice9Ex_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b) +#define IDirect3DDevice9Ex_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b) +#define IDirect3DDevice9Ex_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b) +#define IDirect3DDevice9Ex_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b) +#define IDirect3DDevice9Ex_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b) +#define IDirect3DDevice9Ex_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b) +#define IDirect3DDevice9Ex_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b) +#define IDirect3DDevice9Ex_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b) +#define IDirect3DDevice9Ex_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p) +#define IDirect3DDevice9Ex_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a) +#define IDirect3DDevice9Ex_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a) +#define IDirect3DDevice9Ex_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a) +#define IDirect3DDevice9Ex_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b) +#define IDirect3DDevice9Ex_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b) +#define IDirect3DDevice9Ex_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c) +#define IDirect3DDevice9Ex_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c) +#define IDirect3DDevice9Ex_GetSamplerState(p,a,b,c) (p)->lpVtbl->GetSamplerState(p,a,b,c) +#define IDirect3DDevice9Ex_SetSamplerState(p,a,b,c) (p)->lpVtbl->SetSamplerState(p,a,b,c) +#define IDirect3DDevice9Ex_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a) +#define IDirect3DDevice9Ex_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b) +#define IDirect3DDevice9Ex_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b) +#define IDirect3DDevice9Ex_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a) +#define IDirect3DDevice9Ex_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a) +#define IDirect3DDevice9Ex_SetScissorRect(p,a) (p)->lpVtbl->SetScissorRect(p,a) +#define IDirect3DDevice9Ex_GetScissorRect(p,a) (p)->lpVtbl->GetScissorRect(p,a) +#define IDirect3DDevice9Ex_SetSoftwareVertexProcessing(p,a) (p)->lpVtbl->SetSoftwareVertexProcessing(p,a) +#define IDirect3DDevice9Ex_GetSoftwareVertexProcessing(p) (p)->lpVtbl->GetSoftwareVertexProcessing(p) +#define IDirect3DDevice9Ex_SetNPatchMode(p,a) (p)->lpVtbl->SetNPatchMode(p,a) +#define IDirect3DDevice9Ex_GetNPatchMode(p) (p)->lpVtbl->GetNPatchMode(p) +#define IDirect3DDevice9Ex_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c) +#define IDirect3DDevice9Ex_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f) +#define IDirect3DDevice9Ex_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) +#define IDirect3DDevice9Ex_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_ProcessVertices(p,a,b,c,d,e,f) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e,f) +#define IDirect3DDevice9Ex_CreateVertexDeclaration(p,a,b) (p)->lpVtbl->CreateVertexDeclaration(p,a,b) +#define IDirect3DDevice9Ex_SetVertexDeclaration(p,a) (p)->lpVtbl->SetVertexDeclaration(p,a) +#define IDirect3DDevice9Ex_GetVertexDeclaration(p,a) (p)->lpVtbl->GetVertexDeclaration(p,a) +#define IDirect3DDevice9Ex_SetFVF(p,a) (p)->lpVtbl->SetFVF(p,a) +#define IDirect3DDevice9Ex_GetFVF(p,a) (p)->lpVtbl->GetFVF(p,a) +#define IDirect3DDevice9Ex_CreateVertexShader(p,a,b) (p)->lpVtbl->CreateVertexShader(p,a,b) +#define IDirect3DDevice9Ex_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a) +#define IDirect3DDevice9Ex_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a) +#define IDirect3DDevice9Ex_SetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantF(p,a,b,c) +#define IDirect3DDevice9Ex_GetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantF(p,a,b,c) +#define IDirect3DDevice9Ex_SetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantI(p,a,b,c) +#define IDirect3DDevice9Ex_GetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantI(p,a,b,c) +#define IDirect3DDevice9Ex_SetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantB(p,a,b,c) +#define IDirect3DDevice9Ex_GetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantB(p,a,b,c) +#define IDirect3DDevice9Ex_SetStreamSource(p,a,b,c,d) (p)->lpVtbl->SetStreamSource(p,a,b,c,d) +#define IDirect3DDevice9Ex_GetStreamSource(p,a,b,c,d) (p)->lpVtbl->GetStreamSource(p,a,b,c,d) +#define IDirect3DDevice9Ex_SetStreamSourceFreq(p,a,b) (p)->lpVtbl->SetStreamSourceFreq(p,a,b) +#define IDirect3DDevice9Ex_GetStreamSourceFreq(p,a,b) (p)->lpVtbl->GetStreamSourceFreq(p,a,b) +#define IDirect3DDevice9Ex_SetIndices(p,a) (p)->lpVtbl->SetIndices(p,a) +#define IDirect3DDevice9Ex_GetIndices(p,a) (p)->lpVtbl->GetIndices(p,a) +#define IDirect3DDevice9Ex_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b) +#define IDirect3DDevice9Ex_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a) +#define IDirect3DDevice9Ex_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a) +#define IDirect3DDevice9Ex_SetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantF(p,a,b,c) +#define IDirect3DDevice9Ex_GetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantF(p,a,b,c) +#define IDirect3DDevice9Ex_SetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantI(p,a,b,c) +#define IDirect3DDevice9Ex_GetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantI(p,a,b,c) +#define IDirect3DDevice9Ex_SetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantB(p,a,b,c) +#define IDirect3DDevice9Ex_GetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantB(p,a,b,c) +#define IDirect3DDevice9Ex_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c) +#define IDirect3DDevice9Ex_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c) +#define IDirect3DDevice9Ex_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a) +#define IDirect3DDevice9Ex_CreateQuery(p,a,b) (p)->lpVtbl->CreateQuery(p,a,b) +#define IDirect3DDevice9Ex_SetConvolutionMonoKernel(p,a,b,c,d) (p)->lpVtbl->SetConvolutionMonoKernel(p,a,b,c,d) +#define IDirect3DDevice9Ex_ComposeRects(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->ComposeRects(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_PresentEx(p,a,b,c,d,e) (p)->lpVtbl->PresentEx(p,a,b,c,d,e) +#define IDirect3DDevice9Ex_GetGPUThreadPriority(p,a) (p)->lpVtbl->GetGPUThreadPriority(p,a) +#define IDirect3DDevice9Ex_SetGPUThreadPriority(p,a) (p)->lpVtbl->SetGPUThreadPriority(p,a) +#define IDirect3DDevice9Ex_WaitForVBlank(p,a) (p)->lpVtbl->WaitForVBlank(p,a) +#define IDirect3DDevice9Ex_CheckResourceResidency(p,a,b) (p)->lpVtbl->CheckResourceResidency(p,a,b) +#define IDirect3DDevice9Ex_SetMaximumFrameLatency(p,a) (p)->lpVtbl->SetMaximumFrameLatency(p,a) +#define IDirect3DDevice9Ex_GetMaximumFrameLatency(p,a) (p)->lpVtbl->GetMaximumFrameLatency(p,a) +#define IDirect3DDevice9Ex_CheckDeviceState(p,a) (p)->lpVtbl->CheckDeviceState(p,a) +#define IDirect3DDevice9Ex_CreateRenderTargetEx(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateRenderTargetEx(p,a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateOffscreenPlainSurfaceEx(p,a,b,c,d,e,f,g) +#define IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateDepthStencilSurfaceEx(p,a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9Ex_ResetEx(p,a,b) (p)->lpVtbl->ResetEx(p,a,b) +#define IDirect3DDevice9Ex_GetDisplayModeEx(p,a,b,c) (p)->lpVtbl->GetDisplayModeEx(p,a,b,c) +#else +#define IDirect3DDevice9Ex_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DDevice9Ex_AddRef(p) (p)->AddRef() +#define IDirect3DDevice9Ex_Release(p) (p)->Release() +#define IDirect3DDevice9Ex_TestCooperativeLevel(p) (p)->TestCooperativeLevel() +#define IDirect3DDevice9Ex_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem() +#define IDirect3DDevice9Ex_EvictManagedResources(p) (p)->EvictManagedResources() +#define IDirect3DDevice9Ex_GetDirect3D(p,a) (p)->GetDirect3D(a) +#define IDirect3DDevice9Ex_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a) +#define IDirect3DDevice9Ex_GetDisplayMode(p,a,b) (p)->GetDisplayMode(a,b) +#define IDirect3DDevice9Ex_GetCreationParameters(p,a) (p)->GetCreationParameters(a) +#define IDirect3DDevice9Ex_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c) +#define IDirect3DDevice9Ex_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c) +#define IDirect3DDevice9Ex_ShowCursor(p,a) (p)->ShowCursor(a) +#define IDirect3DDevice9Ex_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b) +#define IDirect3DDevice9Ex_GetSwapChain(p,a,b) (p)->GetSwapChain(a,b) +#define IDirect3DDevice9Ex_GetNumberOfSwapChains(p) (p)->GetNumberOfSwapChains() +#define IDirect3DDevice9Ex_Reset(p,a) (p)->Reset(a) +#define IDirect3DDevice9Ex_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DDevice9Ex_GetBackBuffer(p,a,b,c,d) (p)->GetBackBuffer(a,b,c,d) +#define IDirect3DDevice9Ex_GetRasterStatus(p,a,b) (p)->GetRasterStatus(a,b) +#define IDirect3DDevice9Ex_SetDialogBoxMode(p,a) (p)->SetDialogBoxMode(a) +#define IDirect3DDevice9Ex_SetGammaRamp(p,a,b,c) (p)->SetGammaRamp(a,b,c) +#define IDirect3DDevice9Ex_GetGammaRamp(p,a,b) (p)->GetGammaRamp(a,b) +#define IDirect3DDevice9Ex_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->CreateTexture(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9Ex_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->CreateCubeTexture(a,b,c,d,e,f,g) +#define IDirect3DDevice9Ex_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->CreateVertexBuffer(a,b,c,d,e,f) +#define IDirect3DDevice9Ex_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->CreateIndexBuffer(a,b,c,d,e,f) +#define IDirect3DDevice9Ex_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->CreateRenderTarget(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->CreateDepthStencilSurface(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_UpdateSurface(p,a,b,c,d) (p)->UpdateSurface(a,b,c,d) +#define IDirect3DDevice9Ex_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b) +#define IDirect3DDevice9Ex_GetRenderTargetData(p,a,b) (p)->GetRenderTargetData(a,b) +#define IDirect3DDevice9Ex_GetFrontBufferData(p,a,b) (p)->GetFrontBufferData(a,b) +#define IDirect3DDevice9Ex_StretchRect(p,a,b,c,d,e) (p)->StretchRect(a,b,c,d,e) +#define IDirect3DDevice9Ex_ColorFill(p,a,b,c) (p)->ColorFill(a,b,c) +#define IDirect3DDevice9Ex_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->CreateOffscreenPlainSurface(a,b,c,d,e,f) +#define IDirect3DDevice9Ex_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b) +#define IDirect3DDevice9Ex_GetRenderTarget(p,a,b) (p)->GetRenderTarget(a,b) +#define IDirect3DDevice9Ex_SetDepthStencilSurface(p,a) (p)->SetDepthStencilSurface(a) +#define IDirect3DDevice9Ex_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a) +#define IDirect3DDevice9Ex_BeginScene(p) (p)->BeginScene() +#define IDirect3DDevice9Ex_EndScene(p) (p)->EndScene() +#define IDirect3DDevice9Ex_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f) +#define IDirect3DDevice9Ex_SetTransform(p,a,b) (p)->SetTransform(a,b) +#define IDirect3DDevice9Ex_GetTransform(p,a,b) (p)->GetTransform(a,b) +#define IDirect3DDevice9Ex_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b) +#define IDirect3DDevice9Ex_SetViewport(p,a) (p)->SetViewport(a) +#define IDirect3DDevice9Ex_GetViewport(p,a) (p)->GetViewport(a) +#define IDirect3DDevice9Ex_SetMaterial(p,a) (p)->SetMaterial(a) +#define IDirect3DDevice9Ex_GetMaterial(p,a) (p)->GetMaterial(a) +#define IDirect3DDevice9Ex_SetLight(p,a,b) (p)->SetLight(a,b) +#define IDirect3DDevice9Ex_GetLight(p,a,b) (p)->GetLight(a,b) +#define IDirect3DDevice9Ex_LightEnable(p,a,b) (p)->LightEnable(a,b) +#define IDirect3DDevice9Ex_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b) +#define IDirect3DDevice9Ex_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b) +#define IDirect3DDevice9Ex_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b) +#define IDirect3DDevice9Ex_SetRenderState(p,a,b) (p)->SetRenderState(a,b) +#define IDirect3DDevice9Ex_GetRenderState(p,a,b) (p)->GetRenderState(a,b) +#define IDirect3DDevice9Ex_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b) +#define IDirect3DDevice9Ex_BeginStateBlock(p) (p)->BeginStateBlock() +#define IDirect3DDevice9Ex_EndStateBlock(p,a) (p)->EndStateBlock(a) +#define IDirect3DDevice9Ex_SetClipStatus(p,a) (p)->SetClipStatus(a) +#define IDirect3DDevice9Ex_GetClipStatus(p,a) (p)->GetClipStatus(a) +#define IDirect3DDevice9Ex_GetTexture(p,a,b) (p)->GetTexture(a,b) +#define IDirect3DDevice9Ex_SetTexture(p,a,b) (p)->SetTexture(a,b) +#define IDirect3DDevice9Ex_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c) +#define IDirect3DDevice9Ex_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c) +#define IDirect3DDevice9Ex_GetSamplerState(p,a,b,c) (p)->GetSamplerState(a,b,c) +#define IDirect3DDevice9Ex_SetSamplerState(p,a,b,c) (p)->SetSamplerState(a,b,c) +#define IDirect3DDevice9Ex_ValidateDevice(p,a) (p)->ValidateDevice(a) +#define IDirect3DDevice9Ex_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b) +#define IDirect3DDevice9Ex_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b) +#define IDirect3DDevice9Ex_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a) +#define IDirect3DDevice9Ex_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a) +#define IDirect3DDevice9Ex_SetScissorRect(p,a) (p)->SetScissorRect(a) +#define IDirect3DDevice9Ex_GetScissorRect(p,a) (p)->GetScissorRect(a) +#define IDirect3DDevice9Ex_SetSoftwareVertexProcessing(p,a) (p)->SetSoftwareVertexProcessing(a) +#define IDirect3DDevice9Ex_GetSoftwareVertexProcessing(p) (p)->GetSoftwareVertexProcessing() +#define IDirect3DDevice9Ex_SetNPatchMode(p,a) (p)->SetNPatchMode(a) +#define IDirect3DDevice9Ex_GetNPatchMode(p) (p)->GetNPatchMode() +#define IDirect3DDevice9Ex_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c) +#define IDirect3DDevice9Ex_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->DrawIndexedPrimitive(a,b,c,d,e,f) +#define IDirect3DDevice9Ex_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d) +#define IDirect3DDevice9Ex_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_ProcessVertices(p,a,b,c,d,e,f) (p)->ProcessVertices(a,b,c,d,e,f) +#define IDirect3DDevice9Ex_CreateVertexDeclaration(p,a,b) (p)->CreateVertexDeclaration(a,b) +#define IDirect3DDevice9Ex_SetVertexDeclaration(p,a) (p)->SetVertexDeclaration(a) +#define IDirect3DDevice9Ex_GetVertexDeclaration(p,a) (p)->GetVertexDeclaration(a) +#define IDirect3DDevice9Ex_SetFVF(p,a) (p)->SetFVF(a) +#define IDirect3DDevice9Ex_GetFVF(p,a) (p)->GetFVF(a) +#define IDirect3DDevice9Ex_CreateVertexShader(p,a,b) (p)->CreateVertexShader(a,b) +#define IDirect3DDevice9Ex_SetVertexShader(p,a) (p)->SetVertexShader(a) +#define IDirect3DDevice9Ex_GetVertexShader(p,a) (p)->GetVertexShader(a) +#define IDirect3DDevice9Ex_SetVertexShaderConstantF(p,a,b,c) (p)->SetVertexShaderConstantF(a,b,c) +#define IDirect3DDevice9Ex_GetVertexShaderConstantF(p,a,b,c) (p)->GetVertexShaderConstantF(a,b,c) +#define IDirect3DDevice9Ex_SetVertexShaderConstantI(p,a,b,c) (p)->SetVertexShaderConstantI(a,b,c) +#define IDirect3DDevice9Ex_GetVertexShaderConstantI(p,a,b,c) (p)->GetVertexShaderConstantI(a,b,c) +#define IDirect3DDevice9Ex_SetVertexShaderConstantB(p,a,b,c) (p)->SetVertexShaderConstantB(a,b,c) +#define IDirect3DDevice9Ex_GetVertexShaderConstantB(p,a,b,c) (p)->GetVertexShaderConstantB(a,b,c) +#define IDirect3DDevice9Ex_SetStreamSource(p,a,b,c,d) (p)->SetStreamSource(a,b,c,d) +#define IDirect3DDevice9Ex_GetStreamSource(p,a,b,c,d) (p)->GetStreamSource(a,b,c,d) +#define IDirect3DDevice9Ex_SetStreamSourceFreq(p,a,b) (p)->SetStreamSourceFreq(a,b) +#define IDirect3DDevice9Ex_GetStreamSourceFreq(p,a,b) (p)->GetStreamSourceFreq(a,b) +#define IDirect3DDevice9Ex_SetIndices(p,a) (p)->SetIndices(a) +#define IDirect3DDevice9Ex_GetIndices(p,a) (p)->GetIndices(a) +#define IDirect3DDevice9Ex_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b) +#define IDirect3DDevice9Ex_SetPixelShader(p,a) (p)->SetPixelShader(a) +#define IDirect3DDevice9Ex_GetPixelShader(p,a) (p)->GetPixelShader(a) +#define IDirect3DDevice9Ex_SetPixelShaderConstantF(p,a,b,c) (p)->SetPixelShaderConstantF(a,b,c) +#define IDirect3DDevice9Ex_GetPixelShaderConstantF(p,a,b,c) (p)->GetPixelShaderConstantF(a,b,c) +#define IDirect3DDevice9Ex_SetPixelShaderConstantI(p,a,b,c) (p)->SetPixelShaderConstantI(a,b,c) +#define IDirect3DDevice9Ex_GetPixelShaderConstantI(p,a,b,c) (p)->GetPixelShaderConstantI(a,b,c) +#define IDirect3DDevice9Ex_SetPixelShaderConstantB(p,a,b,c) (p)->SetPixelShaderConstantB(a,b,c) +#define IDirect3DDevice9Ex_GetPixelShaderConstantB(p,a,b,c) (p)->GetPixelShaderConstantB(a,b,c) +#define IDirect3DDevice9Ex_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c) +#define IDirect3DDevice9Ex_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c) +#define IDirect3DDevice9Ex_DeletePatch(p,a) (p)->DeletePatch(a) +#define IDirect3DDevice9Ex_CreateQuery(p,a,b) (p)->CreateQuery(a,b) +#define IDirect3DDevice9Ex_SetConvolutionMonoKernel(p,a,b,c,d) (p)->SetConvolutionMonoKernel(a,b,c,d) +#define IDirect3DDevice9Ex_ComposeRects(p,a,b,c,d,e,f,g,h) (p)->ComposeRects(a,b,c,d,e,f,g,h) +#define IDirect3DDevice9Ex_PresentEx(p,a,b,c,d,e) (p)->PresentEx(a,b,c,d,e) +#define IDirect3DDevice9Ex_GetGPUThreadPriority(p,a) (p)->GetGPUThreadPriority(a) +#define IDirect3DDevice9Ex_SetGPUThreadPriority(p,a) (p)->SetGPUThreadPriority(a) +#define IDirect3DDevice9Ex_WaitForVBlank(p,a) (p)->WaitForVBlank(a) +#define IDirect3DDevice9Ex_CheckResourceResidency(p,a,b) (p)->CheckResourceResidency(a,b) +#define IDirect3DDevice9Ex_SetMaximumFrameLatency(p,a) (p)->SetMaximumFrameLatency(a) +#define IDirect3DDevice9Ex_GetMaximumFrameLatency(p,a) (p)->GetMaximumFrameLatency(a) +#define IDirect3DDevice9Ex_CheckDeviceState(p,a) (p)->CheckDeviceState(a) +#define IDirect3DDevice9Ex_CreateRenderTargetEx(p,a,b,c,d,e,f,g,h,i) (p)->CreateRenderTargetEx(a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(p,a,b,c,d,e,f,g) (p)->CreateOffscreenPlainSurfaceEx(a,b,c,d,e,f,g) +#define IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(p,a,b,c,d,e,f,g,h,i) (p)->CreateDepthStencilSurfaceEx(a,b,c,d,e,f,g,h,i) +#define IDirect3DDevice9Ex_ResetEx(p,a,b) (p)->ResetEx(a,b) +#define IDirect3DDevice9Ex_GetDisplayModeEx(p,a,b,c) (p)->GetDisplayModeEx(a,b,c) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DSwapChain9Ex + +DECLARE_INTERFACE_(IDirect3DSwapChain9Ex, IDirect3DSwapChain9) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSwapChain9 methods ***/ + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion,DWORD dwFlags) PURE; + STDMETHOD(GetFrontBufferData)(THIS_ IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetPresentParameters)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + STDMETHOD(GetLastPresentCount)(THIS_ UINT* pLastPresentCount) PURE; + STDMETHOD(GetPresentStats)(THIS_ D3DPRESENTSTATS* pPresentationStatistics) PURE; + STDMETHOD(GetDisplayModeEx)(THIS_ D3DDISPLAYMODEEX* pMode,D3DDISPLAYROTATION* pRotation) PURE; +}; + +typedef struct IDirect3DSwapChain9Ex *LPDIRECT3DSWAPCHAIN9EX, *PDIRECT3DSWAPCHAIN9EX; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSwapChain9Ex_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSwapChain9Ex_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSwapChain9Ex_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSwapChain9Ex_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e) +#define IDirect3DSwapChain9Ex_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a) +#define IDirect3DSwapChain9Ex_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#define IDirect3DSwapChain9Ex_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) +#define IDirect3DSwapChain9Ex_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a) +#define IDirect3DSwapChain9Ex_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DSwapChain9Ex_GetPresentParameters(p,a) (p)->lpVtbl->GetPresentParameters(p,a) +#define IDirect3DSwapChain9Ex_GetLastPresentCount(p,a) (p)->lpVtbl->GetLastPresentCount(p,a) +#define IDirect3DSwapChain9Ex_GetPresentStats(p,a) (p)->lpVtbl->GetPresentStats(p,a) +#define IDirect3DSwapChain9Ex_GetDisplayModeEx(p,a,b) (p)->lpVtbl->GetDisplayModeEx(p,a,b) +#else +#define IDirect3DSwapChain9Ex_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSwapChain9Ex_AddRef(p) (p)->AddRef() +#define IDirect3DSwapChain9Ex_Release(p) (p)->Release() +#define IDirect3DSwapChain9Ex_Present(p,a,b,c,d,e) (p)->Present(a,b,c,d,e) +#define IDirect3DSwapChain9Ex_GetFrontBufferData(p,a) (p)->GetFrontBufferData(a) +#define IDirect3DSwapChain9Ex_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#define IDirect3DSwapChain9Ex_GetRasterStatus(p,a) (p)->GetRasterStatus(a) +#define IDirect3DSwapChain9Ex_GetDisplayMode(p,a) (p)->GetDisplayMode(a) +#define IDirect3DSwapChain9Ex_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DSwapChain9Ex_GetPresentParameters(p,a) (p)->GetPresentParameters(a) +#define IDirect3DSwapChain9Ex_GetLastPresentCount(p,a) (p)->GetLastPresentCount(a) +#define IDirect3DSwapChain9Ex_GetPresentStats(p,a) (p)->GetPresentStats(a) +#define IDirect3DSwapChain9Ex_GetDisplayModeEx(p,a,b) (p)->GetDisplayModeEx(a,b) +#endif + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + + + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + + + +#undef INTERFACE +#define INTERFACE IDirect3D9ExOverlayExtension + +DECLARE_INTERFACE_(IDirect3D9ExOverlayExtension, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3D9ExOverlayExtension methods ***/ + STDMETHOD(CheckDeviceOverlayType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,UINT OverlayWidth,UINT OverlayHeight,D3DFORMAT OverlayFormat,D3DDISPLAYMODEEX* pDisplayMode,D3DDISPLAYROTATION DisplayRotation,D3DOVERLAYCAPS* pOverlayCaps) PURE; +}; + +typedef struct IDirect3D9ExOverlayExtension *LPDIRECT3D9EXOVERLAYEXTENSION, *PDIRECT3D9EXOVERLAYEXTENSION; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3D9ExOverlayExtension_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3D9ExOverlayExtension_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3D9ExOverlayExtension_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3D9ExOverlayExtension_CheckDeviceOverlayType(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CheckDeviceOverlayType(p,a,b,c,d,e,f,g,h) +#else +#define IDirect3D9ExOverlayExtension_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3D9ExOverlayExtension_AddRef(p) (p)->AddRef() +#define IDirect3D9ExOverlayExtension_Release(p) (p)->Release() +#define IDirect3D9ExOverlayExtension_CheckDeviceOverlayType(p,a,b,c,d,e,f,g,h) (p)->CheckDeviceOverlayType(a,b,c,d,e,f,g,h) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DDevice9Video + +DECLARE_INTERFACE_(IDirect3DDevice9Video, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DDevice9Video methods ***/ + STDMETHOD(GetContentProtectionCaps)(THIS_ CONST GUID* pCryptoType,CONST GUID* pDecodeProfile,D3DCONTENTPROTECTIONCAPS* pCaps) PURE; + STDMETHOD(CreateAuthenticatedChannel)(THIS_ D3DAUTHENTICATEDCHANNELTYPE ChannelType,IDirect3DAuthenticatedChannel9** ppAuthenticatedChannel,HANDLE* pChannelHandle) PURE; + STDMETHOD(CreateCryptoSession)(THIS_ CONST GUID* pCryptoType,CONST GUID* pDecodeProfile,IDirect3DCryptoSession9** ppCryptoSession,HANDLE* pCryptoHandle) PURE; +}; + +typedef struct IDirect3DDevice9Video *LPDIRECT3DDEVICE9VIDEO, *PDIRECT3DDEVICE9VIDEO; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DDevice9Video_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DDevice9Video_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DDevice9Video_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DDevice9Video_GetContentProtectionCaps(p,a,b,c) (p)->lpVtbl->GetContentProtectionCaps(p,a,b,c) +#define IDirect3DDevice9Video_CreateAuthenticatedChannel(p,a,b,c) (p)->lpVtbl->CreateAuthenticatedChannel(p,a,b,c) +#define IDirect3DDevice9Video_CreateCryptoSession(p,a,b,c,d) (p)->lpVtbl->CreateCryptoSession(p,a,b,c,d) +#else +#define IDirect3DDevice9Video_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DDevice9Video_AddRef(p) (p)->AddRef() +#define IDirect3DDevice9Video_Release(p) (p)->Release() +#define IDirect3DDevice9Video_GetContentProtectionCaps(p,a,b,c) (p)->GetContentProtectionCaps(a,b,c) +#define IDirect3DDevice9Video_CreateAuthenticatedChannel(p,a,b,c) (p)->CreateAuthenticatedChannel(a,b,c) +#define IDirect3DDevice9Video_CreateCryptoSession(p,a,b,c,d) (p)->CreateCryptoSession(a,b,c,d) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DAuthenticatedChannel9 + +DECLARE_INTERFACE_(IDirect3DAuthenticatedChannel9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DAuthenticatedChannel9 methods ***/ + STDMETHOD(GetCertificateSize)(THIS_ UINT* pCertificateSize) PURE; + STDMETHOD(GetCertificate)(THIS_ UINT CertifacteSize,BYTE* ppCertificate) PURE; + STDMETHOD(NegotiateKeyExchange)(THIS_ UINT DataSize,VOID* pData) PURE; + STDMETHOD(Query)(THIS_ UINT InputSize,CONST VOID* pInput,UINT OutputSize,VOID* pOutput) PURE; + STDMETHOD(Configure)(THIS_ UINT InputSize,CONST VOID* pInput,D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT* pOutput) PURE; +}; + +typedef struct IDirect3DAuthenticatedChannel9 *LPDIRECT3DAUTHENTICATEDCHANNEL9, *PDIRECT3DAUTHENTICATEDCHANNEL9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DAuthenticatedChannel9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DAuthenticatedChannel9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DAuthenticatedChannel9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DAuthenticatedChannel9_GetCertificateSize(p,a) (p)->lpVtbl->GetCertificateSize(p,a) +#define IDirect3DAuthenticatedChannel9_GetCertificate(p,a,b) (p)->lpVtbl->GetCertificate(p,a,b) +#define IDirect3DAuthenticatedChannel9_NegotiateKeyExchange(p,a,b) (p)->lpVtbl->NegotiateKeyExchange(p,a,b) +#define IDirect3DAuthenticatedChannel9_Query(p,a,b,c,d) (p)->lpVtbl->Query(p,a,b,c,d) +#define IDirect3DAuthenticatedChannel9_Configure(p,a,b,c) (p)->lpVtbl->Configure(p,a,b,c) +#else +#define IDirect3DAuthenticatedChannel9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DAuthenticatedChannel9_AddRef(p) (p)->AddRef() +#define IDirect3DAuthenticatedChannel9_Release(p) (p)->Release() +#define IDirect3DAuthenticatedChannel9_GetCertificateSize(p,a) (p)->GetCertificateSize(a) +#define IDirect3DAuthenticatedChannel9_GetCertificate(p,a,b) (p)->GetCertificate(a,b) +#define IDirect3DAuthenticatedChannel9_NegotiateKeyExchange(p,a,b) (p)->NegotiateKeyExchange(a,b) +#define IDirect3DAuthenticatedChannel9_Query(p,a,b,c,d) (p)->Query(a,b,c,d) +#define IDirect3DAuthenticatedChannel9_Configure(p,a,b,c) (p)->Configure(a,b,c) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DCryptoSession9 + +DECLARE_INTERFACE_(IDirect3DCryptoSession9, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DCryptoSession9 methods ***/ + STDMETHOD(GetCertificateSize)(THIS_ UINT* pCertificateSize) PURE; + STDMETHOD(GetCertificate)(THIS_ UINT CertifacteSize,BYTE* ppCertificate) PURE; + STDMETHOD(NegotiateKeyExchange)(THIS_ UINT DataSize,VOID* pData) PURE; + STDMETHOD(EncryptionBlt)(THIS_ IDirect3DSurface9* pSrcSurface,IDirect3DSurface9* pDstSurface,UINT DstSurfaceSize,VOID* pIV) PURE; + STDMETHOD(DecryptionBlt)(THIS_ IDirect3DSurface9* pSrcSurface,IDirect3DSurface9* pDstSurface,UINT SrcSurfaceSize,D3DENCRYPTED_BLOCK_INFO* pEncryptedBlockInfo,VOID* pContentKey,VOID* pIV) PURE; + STDMETHOD(GetSurfacePitch)(THIS_ IDirect3DSurface9* pSrcSurface,UINT* pSurfacePitch) PURE; + STDMETHOD(StartSessionKeyRefresh)(THIS_ VOID* pRandomNumber,UINT RandomNumberSize) PURE; + STDMETHOD(FinishSessionKeyRefresh)(THIS) PURE; + STDMETHOD(GetEncryptionBltKey)(THIS_ VOID* pReadbackKey,UINT KeySize) PURE; +}; + +typedef struct IDirect3DCryptoSession9 *LPDIRECT3DCRYPTOSESSION9, *PDIRECT3DCRYPTOSESSION9; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DCryptoSession9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DCryptoSession9_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DCryptoSession9_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DCryptoSession9_GetCertificateSize(p,a) (p)->lpVtbl->GetCertificateSize(p,a) +#define IDirect3DCryptoSession9_GetCertificate(p,a,b) (p)->lpVtbl->GetCertificate(p,a,b) +#define IDirect3DCryptoSession9_NegotiateKeyExchange(p,a,b) (p)->lpVtbl->NegotiateKeyExchange(p,a,b) +#define IDirect3DCryptoSession9_EncryptionBlt(p,a,b,c,d) (p)->lpVtbl->EncryptionBlt(p,a,b,c,d) +#define IDirect3DCryptoSession9_DecryptionBlt(p,a,b,c,d,e,f) (p)->lpVtbl->DecryptionBlt(p,a,b,c,d,e,f) +#define IDirect3DCryptoSession9_GetSurfacePitch(p,a,b) (p)->lpVtbl->GetSurfacePitch(p,a,b) +#define IDirect3DCryptoSession9_StartSessionKeyRefresh(p,a,b) (p)->lpVtbl->StartSessionKeyRefresh(p,a,b) +#define IDirect3DCryptoSession9_FinishSessionKeyRefresh(p) (p)->lpVtbl->FinishSessionKeyRefresh(p) +#define IDirect3DCryptoSession9_GetEncryptionBltKey(p,a,b) (p)->lpVtbl->GetEncryptionBltKey(p,a,b) +#else +#define IDirect3DCryptoSession9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DCryptoSession9_AddRef(p) (p)->AddRef() +#define IDirect3DCryptoSession9_Release(p) (p)->Release() +#define IDirect3DCryptoSession9_GetCertificateSize(p,a) (p)->GetCertificateSize(a) +#define IDirect3DCryptoSession9_GetCertificate(p,a,b) (p)->GetCertificate(a,b) +#define IDirect3DCryptoSession9_NegotiateKeyExchange(p,a,b) (p)->NegotiateKeyExchange(a,b) +#define IDirect3DCryptoSession9_EncryptionBlt(p,a,b,c,d) (p)->EncryptionBlt(a,b,c,d) +#define IDirect3DCryptoSession9_DecryptionBlt(p,a,b,c,d,e,f) (p)->DecryptionBlt(a,b,c,d,e,f) +#define IDirect3DCryptoSession9_GetSurfacePitch(p,a,b) (p)->GetSurfacePitch(a,b) +#define IDirect3DCryptoSession9_StartSessionKeyRefresh(p,a,b) (p)->StartSessionKeyRefresh(a,b) +#define IDirect3DCryptoSession9_FinishSessionKeyRefresh(p) (p)->FinishSessionKeyRefresh() +#define IDirect3DCryptoSession9_GetEncryptionBltKey(p,a,b) (p)->GetEncryptionBltKey(a,b) +#endif + +/* -- D3D9Ex only */ +#endif // !D3D_DISABLE_9EX + + +#ifdef __cplusplus +}; +#endif + +#endif /* (DIRECT3D_VERSION >= 0x0900) */ +#endif /* _D3D_H_ */ + diff --git a/dxsdk/Include/d3d9caps.h b/dxsdk/Include/d3d9caps.h new file mode 100644 index 0000000..c10c4cd --- /dev/null +++ b/dxsdk/Include/d3d9caps.h @@ -0,0 +1,567 @@ +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: d3d9caps.h + * Content: Direct3D capabilities include file + * + ***************************************************************************/ + +#ifndef _d3d9CAPS_H +#define _d3d9CAPS_H + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0900 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX9 interfaces +#if(DIRECT3D_VERSION >= 0x0900) + +#if defined(_X86_) || defined(_IA64_) +#pragma pack(4) +#endif + +typedef struct _D3DVSHADERCAPS2_0 +{ + DWORD Caps; + INT DynamicFlowControlDepth; + INT NumTemps; + INT StaticFlowControlDepth; +} D3DVSHADERCAPS2_0; + +#define D3DVS20CAPS_PREDICATION (1<<0) + +#define D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH 24 +#define D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH 0 +#define D3DVS20_MAX_NUMTEMPS 32 +#define D3DVS20_MIN_NUMTEMPS 12 +#define D3DVS20_MAX_STATICFLOWCONTROLDEPTH 4 +#define D3DVS20_MIN_STATICFLOWCONTROLDEPTH 1 + +typedef struct _D3DPSHADERCAPS2_0 +{ + DWORD Caps; + INT DynamicFlowControlDepth; + INT NumTemps; + INT StaticFlowControlDepth; + INT NumInstructionSlots; +} D3DPSHADERCAPS2_0; + +#define D3DPS20CAPS_ARBITRARYSWIZZLE (1<<0) +#define D3DPS20CAPS_GRADIENTINSTRUCTIONS (1<<1) +#define D3DPS20CAPS_PREDICATION (1<<2) +#define D3DPS20CAPS_NODEPENDENTREADLIMIT (1<<3) +#define D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT (1<<4) + +#define D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH 24 +#define D3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH 0 +#define D3DPS20_MAX_NUMTEMPS 32 +#define D3DPS20_MIN_NUMTEMPS 12 +#define D3DPS20_MAX_STATICFLOWCONTROLDEPTH 4 +#define D3DPS20_MIN_STATICFLOWCONTROLDEPTH 0 +#define D3DPS20_MAX_NUMINSTRUCTIONSLOTS 512 +#define D3DPS20_MIN_NUMINSTRUCTIONSLOTS 96 + +#define D3DMIN30SHADERINSTRUCTIONS 512 +#define D3DMAX30SHADERINSTRUCTIONS 32768 + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +typedef struct _D3DOVERLAYCAPS +{ + UINT Caps; + UINT MaxOverlayDisplayWidth; + UINT MaxOverlayDisplayHeight; +} D3DOVERLAYCAPS; + +#define D3DOVERLAYCAPS_FULLRANGERGB 0x00000001 +#define D3DOVERLAYCAPS_LIMITEDRANGERGB 0x00000002 +#define D3DOVERLAYCAPS_YCbCr_BT601 0x00000004 +#define D3DOVERLAYCAPS_YCbCr_BT709 0x00000008 +#define D3DOVERLAYCAPS_YCbCr_BT601_xvYCC 0x00000010 +#define D3DOVERLAYCAPS_YCbCr_BT709_xvYCC 0x00000020 +#define D3DOVERLAYCAPS_STRETCHX 0x00000040 +#define D3DOVERLAYCAPS_STRETCHY 0x00000080 + + +typedef struct _D3DCONTENTPROTECTIONCAPS +{ + DWORD Caps; + GUID KeyExchangeType; + UINT BufferAlignmentStart; + UINT BlockAlignmentSize; + ULONGLONG ProtectedMemorySize; +} D3DCONTENTPROTECTIONCAPS; + +#define D3DCPCAPS_SOFTWARE 0x00000001 +#define D3DCPCAPS_HARDWARE 0x00000002 +#define D3DCPCAPS_PROTECTIONALWAYSON 0x00000004 +#define D3DCPCAPS_PARTIALDECRYPTION 0x00000008 +#define D3DCPCAPS_CONTENTKEY 0x00000010 +#define D3DCPCAPS_FRESHENSESSIONKEY 0x00000020 +#define D3DCPCAPS_ENCRYPTEDREADBACK 0x00000040 +#define D3DCPCAPS_ENCRYPTEDREADBACKKEY 0x00000080 +#define D3DCPCAPS_SEQUENTIAL_CTR_IV 0x00000100 +#define D3DCPCAPS_ENCRYPTSLICEDATAONLY 0x00000200 + +DEFINE_GUID(D3DCRYPTOTYPE_AES128_CTR, +0x9b6bd711, 0x4f74, 0x41c9, 0x9e, 0x7b, 0xb, 0xe2, 0xd7, 0xd9, 0x3b, 0x4f); +DEFINE_GUID(D3DCRYPTOTYPE_PROPRIETARY, +0xab4e9afd, 0x1d1c, 0x46e6, 0xa7, 0x2f, 0x8, 0x69, 0x91, 0x7b, 0xd, 0xe8); + +DEFINE_GUID(D3DKEYEXCHANGE_RSAES_OAEP, +0xc1949895, 0xd72a, 0x4a1d, 0x8e, 0x5d, 0xed, 0x85, 0x7d, 0x17, 0x15, 0x20); +DEFINE_GUID(D3DKEYEXCHANGE_DXVA, +0x43d3775c, 0x38e5, 0x4924, 0x8d, 0x86, 0xd3, 0xfc, 0xcf, 0x15, 0x3e, 0x9b); + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +typedef struct _D3DCAPS9 +{ + /* Device Info */ + D3DDEVTYPE DeviceType; + UINT AdapterOrdinal; + + /* Caps from DX7 Draw */ + DWORD Caps; + DWORD Caps2; + DWORD Caps3; + DWORD PresentationIntervals; + + /* Cursor Caps */ + DWORD CursorCaps; + + /* 3D Device Caps */ + DWORD DevCaps; + + DWORD PrimitiveMiscCaps; + DWORD RasterCaps; + DWORD ZCmpCaps; + DWORD SrcBlendCaps; + DWORD DestBlendCaps; + DWORD AlphaCmpCaps; + DWORD ShadeCaps; + DWORD TextureCaps; + DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's + DWORD CubeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DCubeTexture9's + DWORD VolumeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DVolumeTexture9's + DWORD TextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DTexture9's + DWORD VolumeTextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DVolumeTexture9's + + DWORD LineCaps; // D3DLINECAPS + + DWORD MaxTextureWidth, MaxTextureHeight; + DWORD MaxVolumeExtent; + + DWORD MaxTextureRepeat; + DWORD MaxTextureAspectRatio; + DWORD MaxAnisotropy; + float MaxVertexW; + + float GuardBandLeft; + float GuardBandTop; + float GuardBandRight; + float GuardBandBottom; + + float ExtentsAdjust; + DWORD StencilCaps; + + DWORD FVFCaps; + DWORD TextureOpCaps; + DWORD MaxTextureBlendStages; + DWORD MaxSimultaneousTextures; + + DWORD VertexProcessingCaps; + DWORD MaxActiveLights; + DWORD MaxUserClipPlanes; + DWORD MaxVertexBlendMatrices; + DWORD MaxVertexBlendMatrixIndex; + + float MaxPointSize; + + DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call + DWORD MaxVertexIndex; + DWORD MaxStreams; + DWORD MaxStreamStride; // max stride for SetStreamSource + + DWORD VertexShaderVersion; + DWORD MaxVertexShaderConst; // number of vertex shader constant registers + + DWORD PixelShaderVersion; + float PixelShader1xMaxValue; // max value storable in registers of ps.1.x shaders + + // Here are the DX9 specific ones + DWORD DevCaps2; + + float MaxNpatchTessellationLevel; + DWORD Reserved5; + + UINT MasterAdapterOrdinal; // ordinal of master adaptor for adapter group + UINT AdapterOrdinalInGroup; // ordinal inside the adapter group + UINT NumberOfAdaptersInGroup; // number of adapters in this adapter group (only if master) + DWORD DeclTypes; // Data types, supported in vertex declarations + DWORD NumSimultaneousRTs; // Will be at least 1 + DWORD StretchRectFilterCaps; // Filter caps supported by StretchRect + D3DVSHADERCAPS2_0 VS20Caps; + D3DPSHADERCAPS2_0 PS20Caps; + DWORD VertexTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders + DWORD MaxVShaderInstructionsExecuted; // maximum number of vertex shader instructions that can be executed + DWORD MaxPShaderInstructionsExecuted; // maximum number of pixel shader instructions that can be executed + DWORD MaxVertexShader30InstructionSlots; + DWORD MaxPixelShader30InstructionSlots; +} D3DCAPS9; + +// +// BIT DEFINES FOR D3DCAPS9 DWORD MEMBERS +// + +// +// Caps +// +#define D3DCAPS_OVERLAY 0x00000800L +#define D3DCAPS_READ_SCANLINE 0x00020000L + +// +// Caps2 +// +#define D3DCAPS2_FULLSCREENGAMMA 0x00020000L +#define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000L +#define D3DCAPS2_RESERVED 0x02000000L +#define D3DCAPS2_CANMANAGERESOURCE 0x10000000L +#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L +#define D3DCAPS2_CANAUTOGENMIPMAP 0x40000000L + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +#define D3DCAPS2_CANSHARERESOURCE 0x80000000L + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +// +// Caps3 +// +#define D3DCAPS3_RESERVED 0x8000001fL + +// Indicates that the device can respect the ALPHABLENDENABLE render state +// when fullscreen while using the FLIP or DISCARD swap effect. +// COPY and COPYVSYNC swap effects work whether or not this flag is set. +#define D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD 0x00000020L + +// Indicates that the device can perform a gamma correction from +// a windowed back buffer containing linear content to the sRGB desktop. +#define D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION 0x00000080L + +#define D3DCAPS3_COPY_TO_VIDMEM 0x00000100L /* Device can acclerate copies from sysmem to local vidmem */ +#define D3DCAPS3_COPY_TO_SYSTEMMEM 0x00000200L /* Device can acclerate copies from local vidmem to sysmem */ +#define D3DCAPS3_DXVAHD 0x00000400L + + +// +// PresentationIntervals +// +#define D3DPRESENT_INTERVAL_DEFAULT 0x00000000L +#define D3DPRESENT_INTERVAL_ONE 0x00000001L +#define D3DPRESENT_INTERVAL_TWO 0x00000002L +#define D3DPRESENT_INTERVAL_THREE 0x00000004L +#define D3DPRESENT_INTERVAL_FOUR 0x00000008L +#define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000L + +// +// CursorCaps +// +// Driver supports HW color cursor in at least hi-res modes(height >=400) +#define D3DCURSORCAPS_COLOR 0x00000001L +// Driver supports HW cursor also in low-res modes(height < 400) +#define D3DCURSORCAPS_LOWRES 0x00000002L + +// +// DevCaps +// +#define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010L /* Device can use execute buffers from system memory */ +#define D3DDEVCAPS_EXECUTEVIDEOMEMORY 0x00000020L /* Device can use execute buffers from video memory */ +#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040L /* Device can use TL buffers from system memory */ +#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080L /* Device can use TL buffers from video memory */ +#define D3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100L /* Device can texture from system memory */ +#define D3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200L /* Device can texture from device memory */ +#define D3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400L /* Device can draw TLVERTEX primitives */ +#define D3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800L /* Device can render without waiting for flip to complete */ +#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000L /* Device can texture from nonlocal video memory */ +#define D3DDEVCAPS_DRAWPRIMITIVES2 0x00002000L /* Device can support DrawPrimitives2 */ +#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000L /* Device is texturing from separate memory pools */ +#define D3DDEVCAPS_DRAWPRIMITIVES2EX 0x00008000L /* Device can support Extended DrawPrimitives2 i.e. DX7 compliant driver*/ +#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */ +#define D3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000L /* Device supports a Tex Blt from system memory to non-local vidmem */ +#define D3DDEVCAPS_HWRASTERIZATION 0x00080000L /* Device has HW acceleration for rasterization */ +#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */ +#define D3DDEVCAPS_QUINTICRTPATCHES 0x00200000L /* Device supports quintic Beziers and BSplines */ +#define D3DDEVCAPS_RTPATCHES 0x00400000L /* Device supports Rect and Tri patches */ +#define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000L /* Indicates that RT Patches may be drawn efficiently using handle 0 */ +#define D3DDEVCAPS_NPATCHES 0x01000000L /* Device supports N-Patches */ + +// +// PrimitiveMiscCaps +// +#define D3DPMISCCAPS_MASKZ 0x00000002L +#define D3DPMISCCAPS_CULLNONE 0x00000010L +#define D3DPMISCCAPS_CULLCW 0x00000020L +#define D3DPMISCCAPS_CULLCCW 0x00000040L +#define D3DPMISCCAPS_COLORWRITEENABLE 0x00000080L +#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100L /* Device correctly clips scaled points to clip planes */ +#define D3DPMISCCAPS_CLIPTLVERTS 0x00000200L /* device will clip post-transformed vertex primitives */ +#define D3DPMISCCAPS_TSSARGTEMP 0x00000400L /* device supports D3DTA_TEMP for temporary register */ +#define D3DPMISCCAPS_BLENDOP 0x00000800L /* device supports D3DRS_BLENDOP */ +#define D3DPMISCCAPS_NULLREFERENCE 0x00001000L /* Reference Device that doesnt render */ +#define D3DPMISCCAPS_INDEPENDENTWRITEMASKS 0x00004000L /* Device supports independent write masks for MET or MRT */ +#define D3DPMISCCAPS_PERSTAGECONSTANT 0x00008000L /* Device supports per-stage constants */ +#define D3DPMISCCAPS_FOGANDSPECULARALPHA 0x00010000L /* Device supports separate fog and specular alpha (many devices + use the specular alpha channel to store fog factor) */ +#define D3DPMISCCAPS_SEPARATEALPHABLEND 0x00020000L /* Device supports separate blend settings for the alpha channel */ +#define D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS 0x00040000L /* Device supports different bit depths for MRT */ +#define D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING 0x00080000L /* Device supports post-pixel shader operations for MRT */ +#define D3DPMISCCAPS_FOGVERTEXCLAMPED 0x00100000L /* Device clamps fog blend factor per vertex */ + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +#define D3DPMISCCAPS_POSTBLENDSRGBCONVERT 0x00200000L /* Indicates device can perform conversion to sRGB after blending. */ + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + + +// +// LineCaps +// +#define D3DLINECAPS_TEXTURE 0x00000001L +#define D3DLINECAPS_ZTEST 0x00000002L +#define D3DLINECAPS_BLEND 0x00000004L +#define D3DLINECAPS_ALPHACMP 0x00000008L +#define D3DLINECAPS_FOG 0x00000010L +#define D3DLINECAPS_ANTIALIAS 0x00000020L + +// +// RasterCaps +// +#define D3DPRASTERCAPS_DITHER 0x00000001L +#define D3DPRASTERCAPS_ZTEST 0x00000010L +#define D3DPRASTERCAPS_FOGVERTEX 0x00000080L +#define D3DPRASTERCAPS_FOGTABLE 0x00000100L +#define D3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000L +#define D3DPRASTERCAPS_ZBUFFERLESSHSR 0x00008000L +#define D3DPRASTERCAPS_FOGRANGE 0x00010000L +#define D3DPRASTERCAPS_ANISOTROPY 0x00020000L +#define D3DPRASTERCAPS_WBUFFER 0x00040000L +#define D3DPRASTERCAPS_WFOG 0x00100000L +#define D3DPRASTERCAPS_ZFOG 0x00200000L +#define D3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000L /* Device iterates colors perspective correct */ +#define D3DPRASTERCAPS_SCISSORTEST 0x01000000L +#define D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000L +#define D3DPRASTERCAPS_DEPTHBIAS 0x04000000L +#define D3DPRASTERCAPS_MULTISAMPLE_TOGGLE 0x08000000L + +// +// ZCmpCaps, AlphaCmpCaps +// +#define D3DPCMPCAPS_NEVER 0x00000001L +#define D3DPCMPCAPS_LESS 0x00000002L +#define D3DPCMPCAPS_EQUAL 0x00000004L +#define D3DPCMPCAPS_LESSEQUAL 0x00000008L +#define D3DPCMPCAPS_GREATER 0x00000010L +#define D3DPCMPCAPS_NOTEQUAL 0x00000020L +#define D3DPCMPCAPS_GREATEREQUAL 0x00000040L +#define D3DPCMPCAPS_ALWAYS 0x00000080L + +// +// SourceBlendCaps, DestBlendCaps +// +#define D3DPBLENDCAPS_ZERO 0x00000001L +#define D3DPBLENDCAPS_ONE 0x00000002L +#define D3DPBLENDCAPS_SRCCOLOR 0x00000004L +#define D3DPBLENDCAPS_INVSRCCOLOR 0x00000008L +#define D3DPBLENDCAPS_SRCALPHA 0x00000010L +#define D3DPBLENDCAPS_INVSRCALPHA 0x00000020L +#define D3DPBLENDCAPS_DESTALPHA 0x00000040L +#define D3DPBLENDCAPS_INVDESTALPHA 0x00000080L +#define D3DPBLENDCAPS_DESTCOLOR 0x00000100L +#define D3DPBLENDCAPS_INVDESTCOLOR 0x00000200L +#define D3DPBLENDCAPS_SRCALPHASAT 0x00000400L +#define D3DPBLENDCAPS_BOTHSRCALPHA 0x00000800L +#define D3DPBLENDCAPS_BOTHINVSRCALPHA 0x00001000L +#define D3DPBLENDCAPS_BLENDFACTOR 0x00002000L /* Supports both D3DBLEND_BLENDFACTOR and D3DBLEND_INVBLENDFACTOR */ + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +#define D3DPBLENDCAPS_SRCCOLOR2 0x00004000L +#define D3DPBLENDCAPS_INVSRCCOLOR2 0x00008000L + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + + +// +// ShadeCaps +// +#define D3DPSHADECAPS_COLORGOURAUDRGB 0x00000008L +#define D3DPSHADECAPS_SPECULARGOURAUDRGB 0x00000200L +#define D3DPSHADECAPS_ALPHAGOURAUDBLEND 0x00004000L +#define D3DPSHADECAPS_FOGGOURAUD 0x00080000L + +// +// TextureCaps +// +#define D3DPTEXTURECAPS_PERSPECTIVE 0x00000001L /* Perspective-correct texturing is supported */ +#define D3DPTEXTURECAPS_POW2 0x00000002L /* Power-of-2 texture dimensions are required - applies to non-Cube/Volume textures only. */ +#define D3DPTEXTURECAPS_ALPHA 0x00000004L /* Alpha in texture pixels is supported */ +#define D3DPTEXTURECAPS_SQUAREONLY 0x00000020L /* Only square textures are supported */ +#define D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00000040L /* Texture indices are not scaled by the texture size prior to interpolation */ +#define D3DPTEXTURECAPS_ALPHAPALETTE 0x00000080L /* Device can draw alpha from texture palettes */ +// Device can use non-POW2 textures if: +// 1) D3DTEXTURE_ADDRESS is set to CLAMP for this texture's stage +// 2) D3DRS_WRAP(N) is zero for this texture's coordinates +// 3) mip mapping is not enabled (use magnification filter only) +#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100L +#define D3DPTEXTURECAPS_PROJECTED 0x00000400L /* Device can do D3DTTFF_PROJECTED */ +#define D3DPTEXTURECAPS_CUBEMAP 0x00000800L /* Device can do cubemap textures */ +#define D3DPTEXTURECAPS_VOLUMEMAP 0x00002000L /* Device can do volume textures */ +#define D3DPTEXTURECAPS_MIPMAP 0x00004000L /* Device can do mipmapped textures */ +#define D3DPTEXTURECAPS_MIPVOLUMEMAP 0x00008000L /* Device can do mipmapped volume textures */ +#define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000L /* Device can do mipmapped cube maps */ +#define D3DPTEXTURECAPS_CUBEMAP_POW2 0x00020000L /* Device requires that cubemaps be power-of-2 dimension */ +#define D3DPTEXTURECAPS_VOLUMEMAP_POW2 0x00040000L /* Device requires that volume maps be power-of-2 dimension */ +#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000L /* Device does not support projected bump env lookup operation + in programmable and fixed function pixel shaders */ + +// +// TextureFilterCaps, StretchRectFilterCaps +// +#define D3DPTFILTERCAPS_MINFPOINT 0x00000100L /* Min Filter */ +#define D3DPTFILTERCAPS_MINFLINEAR 0x00000200L +#define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400L +#define D3DPTFILTERCAPS_MINFPYRAMIDALQUAD 0x00000800L +#define D3DPTFILTERCAPS_MINFGAUSSIANQUAD 0x00001000L +#define D3DPTFILTERCAPS_MIPFPOINT 0x00010000L /* Mip Filter */ +#define D3DPTFILTERCAPS_MIPFLINEAR 0x00020000L + +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + +#define D3DPTFILTERCAPS_CONVOLUTIONMONO 0x00040000L /* Min and Mag for the convolution mono filter */ + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + +#define D3DPTFILTERCAPS_MAGFPOINT 0x01000000L /* Mag Filter */ +#define D3DPTFILTERCAPS_MAGFLINEAR 0x02000000L +#define D3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000L +#define D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD 0x08000000L +#define D3DPTFILTERCAPS_MAGFGAUSSIANQUAD 0x10000000L + +// +// TextureAddressCaps +// +#define D3DPTADDRESSCAPS_WRAP 0x00000001L +#define D3DPTADDRESSCAPS_MIRROR 0x00000002L +#define D3DPTADDRESSCAPS_CLAMP 0x00000004L +#define D3DPTADDRESSCAPS_BORDER 0x00000008L +#define D3DPTADDRESSCAPS_INDEPENDENTUV 0x00000010L +#define D3DPTADDRESSCAPS_MIRRORONCE 0x00000020L + +// +// StencilCaps +// +#define D3DSTENCILCAPS_KEEP 0x00000001L +#define D3DSTENCILCAPS_ZERO 0x00000002L +#define D3DSTENCILCAPS_REPLACE 0x00000004L +#define D3DSTENCILCAPS_INCRSAT 0x00000008L +#define D3DSTENCILCAPS_DECRSAT 0x00000010L +#define D3DSTENCILCAPS_INVERT 0x00000020L +#define D3DSTENCILCAPS_INCR 0x00000040L +#define D3DSTENCILCAPS_DECR 0x00000080L +#define D3DSTENCILCAPS_TWOSIDED 0x00000100L + +// +// TextureOpCaps +// +#define D3DTEXOPCAPS_DISABLE 0x00000001L +#define D3DTEXOPCAPS_SELECTARG1 0x00000002L +#define D3DTEXOPCAPS_SELECTARG2 0x00000004L +#define D3DTEXOPCAPS_MODULATE 0x00000008L +#define D3DTEXOPCAPS_MODULATE2X 0x00000010L +#define D3DTEXOPCAPS_MODULATE4X 0x00000020L +#define D3DTEXOPCAPS_ADD 0x00000040L +#define D3DTEXOPCAPS_ADDSIGNED 0x00000080L +#define D3DTEXOPCAPS_ADDSIGNED2X 0x00000100L +#define D3DTEXOPCAPS_SUBTRACT 0x00000200L +#define D3DTEXOPCAPS_ADDSMOOTH 0x00000400L +#define D3DTEXOPCAPS_BLENDDIFFUSEALPHA 0x00000800L +#define D3DTEXOPCAPS_BLENDTEXTUREALPHA 0x00001000L +#define D3DTEXOPCAPS_BLENDFACTORALPHA 0x00002000L +#define D3DTEXOPCAPS_BLENDTEXTUREALPHAPM 0x00004000L +#define D3DTEXOPCAPS_BLENDCURRENTALPHA 0x00008000L +#define D3DTEXOPCAPS_PREMODULATE 0x00010000L +#define D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR 0x00020000L +#define D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA 0x00040000L +#define D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR 0x00080000L +#define D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA 0x00100000L +#define D3DTEXOPCAPS_BUMPENVMAP 0x00200000L +#define D3DTEXOPCAPS_BUMPENVMAPLUMINANCE 0x00400000L +#define D3DTEXOPCAPS_DOTPRODUCT3 0x00800000L +#define D3DTEXOPCAPS_MULTIPLYADD 0x01000000L +#define D3DTEXOPCAPS_LERP 0x02000000L + +// +// FVFCaps +// +#define D3DFVFCAPS_TEXCOORDCOUNTMASK 0x0000ffffL /* mask for texture coordinate count field */ +#define D3DFVFCAPS_DONOTSTRIPELEMENTS 0x00080000L /* Device prefers that vertex elements not be stripped */ +#define D3DFVFCAPS_PSIZE 0x00100000L /* Device can receive point size */ + +// +// VertexProcessingCaps +// +#define D3DVTXPCAPS_TEXGEN 0x00000001L /* device can do texgen */ +#define D3DVTXPCAPS_MATERIALSOURCE7 0x00000002L /* device can do DX7-level colormaterialsource ops */ +#define D3DVTXPCAPS_DIRECTIONALLIGHTS 0x00000008L /* device can do directional lights */ +#define D3DVTXPCAPS_POSITIONALLIGHTS 0x00000010L /* device can do positional lights (includes point and spot) */ +#define D3DVTXPCAPS_LOCALVIEWER 0x00000020L /* device can do local viewer */ +#define D3DVTXPCAPS_TWEENING 0x00000040L /* device can do vertex tweening */ +#define D3DVTXPCAPS_TEXGEN_SPHEREMAP 0x00000100L /* device supports D3DTSS_TCI_SPHEREMAP */ +#define D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER 0x00000200L /* device does not support TexGen in non-local + viewer mode */ + +// +// DevCaps2 +// +#define D3DDEVCAPS2_STREAMOFFSET 0x00000001L /* Device supports offsets in streams. Must be set by DX9 drivers */ +#define D3DDEVCAPS2_DMAPNPATCH 0x00000002L /* Device supports displacement maps for N-Patches*/ +#define D3DDEVCAPS2_ADAPTIVETESSRTPATCH 0x00000004L /* Device supports adaptive tesselation of RT-patches*/ +#define D3DDEVCAPS2_ADAPTIVETESSNPATCH 0x00000008L /* Device supports adaptive tesselation of N-patches*/ +#define D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES 0x00000010L /* Device supports StretchRect calls with a texture as the source*/ +#define D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH 0x00000020L /* Device supports presampled displacement maps for N-Patches */ +#define D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET 0x00000040L /* Vertex elements in a vertex declaration can share the same stream offset */ + +// +// DeclTypes +// +#define D3DDTCAPS_UBYTE4 0x00000001L +#define D3DDTCAPS_UBYTE4N 0x00000002L +#define D3DDTCAPS_SHORT2N 0x00000004L +#define D3DDTCAPS_SHORT4N 0x00000008L +#define D3DDTCAPS_USHORT2N 0x00000010L +#define D3DDTCAPS_USHORT4N 0x00000020L +#define D3DDTCAPS_UDEC3 0x00000040L +#define D3DDTCAPS_DEC3N 0x00000080L +#define D3DDTCAPS_FLOAT16_2 0x00000100L +#define D3DDTCAPS_FLOAT16_4 0x00000200L + + +#pragma pack() + +#endif /* (DIRECT3D_VERSION >= 0x0900) */ +#endif /* _d3d9CAPS_H_ */ + diff --git a/dxsdk/Include/d3d9types.h b/dxsdk/Include/d3d9types.h new file mode 100644 index 0000000..4dd3cfa --- /dev/null +++ b/dxsdk/Include/d3d9types.h @@ -0,0 +1,2416 @@ +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: d3d9types.h + * Content: Direct3D capabilities include file + * + ***************************************************************************/ + +#ifndef _d3d9TYPES_H_ +#define _d3d9TYPES_H_ + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0900 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX9 interfaces +#if(DIRECT3D_VERSION >= 0x0900) + +#include + +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4201) // anonymous unions warning +#if defined(_X86_) || defined(_IA64_) +#pragma pack(4) +#endif + +// D3DCOLOR is equivalent to D3DFMT_A8R8G8B8 +#ifndef D3DCOLOR_DEFINED +typedef DWORD D3DCOLOR; +#define D3DCOLOR_DEFINED +#endif + +// maps unsigned 8 bits/channel to D3DCOLOR +#define D3DCOLOR_ARGB(a,r,g,b) \ + ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) +#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) +#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b) + +#define D3DCOLOR_XYUV(y,u,v) D3DCOLOR_ARGB(0xff,y,u,v) +#define D3DCOLOR_AYUV(a,y,u,v) D3DCOLOR_ARGB(a,y,u,v) + +// maps floating point channels (0.f to 1.f range) to D3DCOLOR +#define D3DCOLOR_COLORVALUE(r,g,b,a) \ + D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) + + +#ifndef D3DVECTOR_DEFINED +typedef struct _D3DVECTOR { + float x; + float y; + float z; +} D3DVECTOR; +#define D3DVECTOR_DEFINED +#endif + +#ifndef D3DCOLORVALUE_DEFINED +typedef struct _D3DCOLORVALUE { + float r; + float g; + float b; + float a; +} D3DCOLORVALUE; +#define D3DCOLORVALUE_DEFINED +#endif + +#ifndef D3DRECT_DEFINED +typedef struct _D3DRECT { + LONG x1; + LONG y1; + LONG x2; + LONG y2; +} D3DRECT; +#define D3DRECT_DEFINED +#endif + +#ifndef D3DMATRIX_DEFINED +typedef struct _D3DMATRIX { + union { + struct { + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; + + }; + float m[4][4]; + }; +} D3DMATRIX; +#define D3DMATRIX_DEFINED +#endif + +typedef struct _D3DVIEWPORT9 { + DWORD X; + DWORD Y; /* Viewport Top left */ + DWORD Width; + DWORD Height; /* Viewport Dimensions */ + float MinZ; /* Min/max of clip Volume */ + float MaxZ; +} D3DVIEWPORT9; + +/* + * Values for clip fields. + */ + +// Max number of user clipping planes, supported in D3D. +#define D3DMAXUSERCLIPPLANES 32 + +// These bits could be ORed together to use with D3DRS_CLIPPLANEENABLE +// +#define D3DCLIPPLANE0 (1 << 0) +#define D3DCLIPPLANE1 (1 << 1) +#define D3DCLIPPLANE2 (1 << 2) +#define D3DCLIPPLANE3 (1 << 3) +#define D3DCLIPPLANE4 (1 << 4) +#define D3DCLIPPLANE5 (1 << 5) + +// The following bits are used in the ClipUnion and ClipIntersection +// members of the D3DCLIPSTATUS9 +// + +#define D3DCS_LEFT 0x00000001L +#define D3DCS_RIGHT 0x00000002L +#define D3DCS_TOP 0x00000004L +#define D3DCS_BOTTOM 0x00000008L +#define D3DCS_FRONT 0x00000010L +#define D3DCS_BACK 0x00000020L +#define D3DCS_PLANE0 0x00000040L +#define D3DCS_PLANE1 0x00000080L +#define D3DCS_PLANE2 0x00000100L +#define D3DCS_PLANE3 0x00000200L +#define D3DCS_PLANE4 0x00000400L +#define D3DCS_PLANE5 0x00000800L + +#define D3DCS_ALL (D3DCS_LEFT | \ + D3DCS_RIGHT | \ + D3DCS_TOP | \ + D3DCS_BOTTOM | \ + D3DCS_FRONT | \ + D3DCS_BACK | \ + D3DCS_PLANE0 | \ + D3DCS_PLANE1 | \ + D3DCS_PLANE2 | \ + D3DCS_PLANE3 | \ + D3DCS_PLANE4 | \ + D3DCS_PLANE5) + +typedef struct _D3DCLIPSTATUS9 { + DWORD ClipUnion; + DWORD ClipIntersection; +} D3DCLIPSTATUS9; + +typedef struct _D3DMATERIAL9 { + D3DCOLORVALUE Diffuse; /* Diffuse color RGBA */ + D3DCOLORVALUE Ambient; /* Ambient color RGB */ + D3DCOLORVALUE Specular; /* Specular 'shininess' */ + D3DCOLORVALUE Emissive; /* Emissive color RGB */ + float Power; /* Sharpness if specular highlight */ +} D3DMATERIAL9; + +typedef enum _D3DLIGHTTYPE { + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DLIGHTTYPE; + +typedef struct _D3DLIGHT9 { + D3DLIGHTTYPE Type; /* Type of light source */ + D3DCOLORVALUE Diffuse; /* Diffuse color of light */ + D3DCOLORVALUE Specular; /* Specular color of light */ + D3DCOLORVALUE Ambient; /* Ambient color of light */ + D3DVECTOR Position; /* Position in world space */ + D3DVECTOR Direction; /* Direction in world space */ + float Range; /* Cutoff range */ + float Falloff; /* Falloff */ + float Attenuation0; /* Constant attenuation */ + float Attenuation1; /* Linear attenuation */ + float Attenuation2; /* Quadratic attenuation */ + float Theta; /* Inner angle of spotlight cone */ + float Phi; /* Outer angle of spotlight cone */ +} D3DLIGHT9; + +/* + * Options for clearing + */ +#define D3DCLEAR_TARGET 0x00000001l /* Clear target surface */ +#define D3DCLEAR_ZBUFFER 0x00000002l /* Clear target z buffer */ +#define D3DCLEAR_STENCIL 0x00000004l /* Clear stencil planes */ + +/* + * The following defines the rendering states + */ + +typedef enum _D3DSHADEMODE { + D3DSHADE_FLAT = 1, + D3DSHADE_GOURAUD = 2, + D3DSHADE_PHONG = 3, + D3DSHADE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DSHADEMODE; + +typedef enum _D3DFILLMODE { + D3DFILL_POINT = 1, + D3DFILL_WIREFRAME = 2, + D3DFILL_SOLID = 3, + D3DFILL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DFILLMODE; + +typedef enum _D3DBLEND { + D3DBLEND_ZERO = 1, + D3DBLEND_ONE = 2, + D3DBLEND_SRCCOLOR = 3, + D3DBLEND_INVSRCCOLOR = 4, + D3DBLEND_SRCALPHA = 5, + D3DBLEND_INVSRCALPHA = 6, + D3DBLEND_DESTALPHA = 7, + D3DBLEND_INVDESTALPHA = 8, + D3DBLEND_DESTCOLOR = 9, + D3DBLEND_INVDESTCOLOR = 10, + D3DBLEND_SRCALPHASAT = 11, + D3DBLEND_BOTHSRCALPHA = 12, + D3DBLEND_BOTHINVSRCALPHA = 13, + D3DBLEND_BLENDFACTOR = 14, /* Only supported if D3DPBLENDCAPS_BLENDFACTOR is on */ + D3DBLEND_INVBLENDFACTOR = 15, /* Only supported if D3DPBLENDCAPS_BLENDFACTOR is on */ +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + + D3DBLEND_SRCCOLOR2 = 16, + D3DBLEND_INVSRCCOLOR2 = 17, + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + D3DBLEND_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DBLEND; + +typedef enum _D3DBLENDOP { + D3DBLENDOP_ADD = 1, + D3DBLENDOP_SUBTRACT = 2, + D3DBLENDOP_REVSUBTRACT = 3, + D3DBLENDOP_MIN = 4, + D3DBLENDOP_MAX = 5, + D3DBLENDOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DBLENDOP; + +typedef enum _D3DTEXTUREADDRESS { + D3DTADDRESS_WRAP = 1, + D3DTADDRESS_MIRROR = 2, + D3DTADDRESS_CLAMP = 3, + D3DTADDRESS_BORDER = 4, + D3DTADDRESS_MIRRORONCE = 5, + D3DTADDRESS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTUREADDRESS; + +typedef enum _D3DCULL { + D3DCULL_NONE = 1, + D3DCULL_CW = 2, + D3DCULL_CCW = 3, + D3DCULL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DCULL; + +typedef enum _D3DCMPFUNC { + D3DCMP_NEVER = 1, + D3DCMP_LESS = 2, + D3DCMP_EQUAL = 3, + D3DCMP_LESSEQUAL = 4, + D3DCMP_GREATER = 5, + D3DCMP_NOTEQUAL = 6, + D3DCMP_GREATEREQUAL = 7, + D3DCMP_ALWAYS = 8, + D3DCMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DCMPFUNC; + +typedef enum _D3DSTENCILOP { + D3DSTENCILOP_KEEP = 1, + D3DSTENCILOP_ZERO = 2, + D3DSTENCILOP_REPLACE = 3, + D3DSTENCILOP_INCRSAT = 4, + D3DSTENCILOP_DECRSAT = 5, + D3DSTENCILOP_INVERT = 6, + D3DSTENCILOP_INCR = 7, + D3DSTENCILOP_DECR = 8, + D3DSTENCILOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DSTENCILOP; + +typedef enum _D3DFOGMODE { + D3DFOG_NONE = 0, + D3DFOG_EXP = 1, + D3DFOG_EXP2 = 2, + D3DFOG_LINEAR = 3, + D3DFOG_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DFOGMODE; + +typedef enum _D3DZBUFFERTYPE { + D3DZB_FALSE = 0, + D3DZB_TRUE = 1, // Z buffering + D3DZB_USEW = 2, // W buffering + D3DZB_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DZBUFFERTYPE; + +// Primitives supported by draw-primitive API +typedef enum _D3DPRIMITIVETYPE { + D3DPT_POINTLIST = 1, + D3DPT_LINELIST = 2, + D3DPT_LINESTRIP = 3, + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + D3DPT_TRIANGLEFAN = 6, + D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DPRIMITIVETYPE; + +typedef enum _D3DTRANSFORMSTATETYPE { + D3DTS_VIEW = 2, + D3DTS_PROJECTION = 3, + D3DTS_TEXTURE0 = 16, + D3DTS_TEXTURE1 = 17, + D3DTS_TEXTURE2 = 18, + D3DTS_TEXTURE3 = 19, + D3DTS_TEXTURE4 = 20, + D3DTS_TEXTURE5 = 21, + D3DTS_TEXTURE6 = 22, + D3DTS_TEXTURE7 = 23, + D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTRANSFORMSTATETYPE; + +#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256) +#define D3DTS_WORLD D3DTS_WORLDMATRIX(0) +#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1) +#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2) +#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3) + +typedef enum _D3DRENDERSTATETYPE { + D3DRS_ZENABLE = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */ + D3DRS_FILLMODE = 8, /* D3DFILLMODE */ + D3DRS_SHADEMODE = 9, /* D3DSHADEMODE */ + D3DRS_ZWRITEENABLE = 14, /* TRUE to enable z writes */ + D3DRS_ALPHATESTENABLE = 15, /* TRUE to enable alpha tests */ + D3DRS_LASTPIXEL = 16, /* TRUE for last-pixel on lines */ + D3DRS_SRCBLEND = 19, /* D3DBLEND */ + D3DRS_DESTBLEND = 20, /* D3DBLEND */ + D3DRS_CULLMODE = 22, /* D3DCULL */ + D3DRS_ZFUNC = 23, /* D3DCMPFUNC */ + D3DRS_ALPHAREF = 24, /* D3DFIXED */ + D3DRS_ALPHAFUNC = 25, /* D3DCMPFUNC */ + D3DRS_DITHERENABLE = 26, /* TRUE to enable dithering */ + D3DRS_ALPHABLENDENABLE = 27, /* TRUE to enable alpha blending */ + D3DRS_FOGENABLE = 28, /* TRUE to enable fog blending */ + D3DRS_SPECULARENABLE = 29, /* TRUE to enable specular */ + D3DRS_FOGCOLOR = 34, /* D3DCOLOR */ + D3DRS_FOGTABLEMODE = 35, /* D3DFOGMODE */ + D3DRS_FOGSTART = 36, /* Fog start (for both vertex and pixel fog) */ + D3DRS_FOGEND = 37, /* Fog end */ + D3DRS_FOGDENSITY = 38, /* Fog density */ + D3DRS_RANGEFOGENABLE = 48, /* Enables range-based fog */ + D3DRS_STENCILENABLE = 52, /* BOOL enable/disable stenciling */ + D3DRS_STENCILFAIL = 53, /* D3DSTENCILOP to do if stencil test fails */ + D3DRS_STENCILZFAIL = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */ + D3DRS_STENCILPASS = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */ + D3DRS_STENCILFUNC = 56, /* D3DCMPFUNC fn. Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ + D3DRS_STENCILREF = 57, /* Reference value used in stencil test */ + D3DRS_STENCILMASK = 58, /* Mask value used in stencil test */ + D3DRS_STENCILWRITEMASK = 59, /* Write mask applied to values written to stencil buffer */ + D3DRS_TEXTUREFACTOR = 60, /* D3DCOLOR used for multi-texture blend */ + D3DRS_WRAP0 = 128, /* wrap for 1st texture coord. set */ + D3DRS_WRAP1 = 129, /* wrap for 2nd texture coord. set */ + D3DRS_WRAP2 = 130, /* wrap for 3rd texture coord. set */ + D3DRS_WRAP3 = 131, /* wrap for 4th texture coord. set */ + D3DRS_WRAP4 = 132, /* wrap for 5th texture coord. set */ + D3DRS_WRAP5 = 133, /* wrap for 6th texture coord. set */ + D3DRS_WRAP6 = 134, /* wrap for 7th texture coord. set */ + D3DRS_WRAP7 = 135, /* wrap for 8th texture coord. set */ + D3DRS_CLIPPING = 136, + D3DRS_LIGHTING = 137, + D3DRS_AMBIENT = 139, + D3DRS_FOGVERTEXMODE = 140, + D3DRS_COLORVERTEX = 141, + D3DRS_LOCALVIEWER = 142, + D3DRS_NORMALIZENORMALS = 143, + D3DRS_DIFFUSEMATERIALSOURCE = 145, + D3DRS_SPECULARMATERIALSOURCE = 146, + D3DRS_AMBIENTMATERIALSOURCE = 147, + D3DRS_EMISSIVEMATERIALSOURCE = 148, + D3DRS_VERTEXBLEND = 151, + D3DRS_CLIPPLANEENABLE = 152, + D3DRS_POINTSIZE = 154, /* float point size */ + D3DRS_POINTSIZE_MIN = 155, /* float point size min threshold */ + D3DRS_POINTSPRITEENABLE = 156, /* BOOL point texture coord control */ + D3DRS_POINTSCALEENABLE = 157, /* BOOL point size scale enable */ + D3DRS_POINTSCALE_A = 158, /* float point attenuation A value */ + D3DRS_POINTSCALE_B = 159, /* float point attenuation B value */ + D3DRS_POINTSCALE_C = 160, /* float point attenuation C value */ + D3DRS_MULTISAMPLEANTIALIAS = 161, // BOOL - set to do FSAA with multisample buffer + D3DRS_MULTISAMPLEMASK = 162, // DWORD - per-sample enable/disable + D3DRS_PATCHEDGESTYLE = 163, // Sets whether patch edges will use float style tessellation + D3DRS_DEBUGMONITORTOKEN = 165, // DEBUG ONLY - token to debug monitor + D3DRS_POINTSIZE_MAX = 166, /* float point size max threshold */ + D3DRS_INDEXEDVERTEXBLENDENABLE = 167, + D3DRS_COLORWRITEENABLE = 168, // per-channel write enable + D3DRS_TWEENFACTOR = 170, // float tween factor + D3DRS_BLENDOP = 171, // D3DBLENDOP setting + D3DRS_POSITIONDEGREE = 172, // NPatch position interpolation degree. D3DDEGREE_LINEAR or D3DDEGREE_CUBIC (default) + D3DRS_NORMALDEGREE = 173, // NPatch normal interpolation degree. D3DDEGREE_LINEAR (default) or D3DDEGREE_QUADRATIC + D3DRS_SCISSORTESTENABLE = 174, + D3DRS_SLOPESCALEDEPTHBIAS = 175, + D3DRS_ANTIALIASEDLINEENABLE = 176, + D3DRS_MINTESSELLATIONLEVEL = 178, + D3DRS_MAXTESSELLATIONLEVEL = 179, + D3DRS_ADAPTIVETESS_X = 180, + D3DRS_ADAPTIVETESS_Y = 181, + D3DRS_ADAPTIVETESS_Z = 182, + D3DRS_ADAPTIVETESS_W = 183, + D3DRS_ENABLEADAPTIVETESSELLATION = 184, + D3DRS_TWOSIDEDSTENCILMODE = 185, /* BOOL enable/disable 2 sided stenciling */ + D3DRS_CCW_STENCILFAIL = 186, /* D3DSTENCILOP to do if ccw stencil test fails */ + D3DRS_CCW_STENCILZFAIL = 187, /* D3DSTENCILOP to do if ccw stencil test passes and Z test fails */ + D3DRS_CCW_STENCILPASS = 188, /* D3DSTENCILOP to do if both ccw stencil and Z tests pass */ + D3DRS_CCW_STENCILFUNC = 189, /* D3DCMPFUNC fn. ccw Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ + D3DRS_COLORWRITEENABLE1 = 190, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */ + D3DRS_COLORWRITEENABLE2 = 191, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */ + D3DRS_COLORWRITEENABLE3 = 192, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */ + D3DRS_BLENDFACTOR = 193, /* D3DCOLOR used for a constant blend factor during alpha blending for devices that support D3DPBLENDCAPS_BLENDFACTOR */ + D3DRS_SRGBWRITEENABLE = 194, /* Enable rendertarget writes to be DE-linearized to SRGB (for formats that expose D3DUSAGE_QUERY_SRGBWRITE) */ + D3DRS_DEPTHBIAS = 195, + D3DRS_WRAP8 = 198, /* Additional wrap states for vs_3_0+ attributes with D3DDECLUSAGE_TEXCOORD */ + D3DRS_WRAP9 = 199, + D3DRS_WRAP10 = 200, + D3DRS_WRAP11 = 201, + D3DRS_WRAP12 = 202, + D3DRS_WRAP13 = 203, + D3DRS_WRAP14 = 204, + D3DRS_WRAP15 = 205, + D3DRS_SEPARATEALPHABLENDENABLE = 206, /* TRUE to enable a separate blending function for the alpha channel */ + D3DRS_SRCBLENDALPHA = 207, /* SRC blend factor for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */ + D3DRS_DESTBLENDALPHA = 208, /* DST blend factor for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */ + D3DRS_BLENDOPALPHA = 209, /* Blending operation for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */ + + + D3DRS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DRENDERSTATETYPE; + +// Maximum number of simultaneous render targets D3D supports +#define D3D_MAX_SIMULTANEOUS_RENDERTARGETS 4 + +// Values for material source +typedef enum _D3DMATERIALCOLORSOURCE +{ + D3DMCS_MATERIAL = 0, // Color from material is used + D3DMCS_COLOR1 = 1, // Diffuse vertex color is used + D3DMCS_COLOR2 = 2, // Specular vertex color is used + D3DMCS_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DMATERIALCOLORSOURCE; + +// Bias to apply to the texture coordinate set to apply a wrap to. +#define D3DRENDERSTATE_WRAPBIAS 128UL + +/* Flags to construct the WRAP render states */ +#define D3DWRAP_U 0x00000001L +#define D3DWRAP_V 0x00000002L +#define D3DWRAP_W 0x00000004L + +/* Flags to construct the WRAP render states for 1D thru 4D texture coordinates */ +#define D3DWRAPCOORD_0 0x00000001L // same as D3DWRAP_U +#define D3DWRAPCOORD_1 0x00000002L // same as D3DWRAP_V +#define D3DWRAPCOORD_2 0x00000004L // same as D3DWRAP_W +#define D3DWRAPCOORD_3 0x00000008L + +/* Flags to construct D3DRS_COLORWRITEENABLE */ +#define D3DCOLORWRITEENABLE_RED (1L<<0) +#define D3DCOLORWRITEENABLE_GREEN (1L<<1) +#define D3DCOLORWRITEENABLE_BLUE (1L<<2) +#define D3DCOLORWRITEENABLE_ALPHA (1L<<3) + +/* + * State enumerants for per-stage processing of fixed function pixel processing + * Two of these affect fixed function vertex processing as well: TEXTURETRANSFORMFLAGS and TEXCOORDINDEX. + */ +typedef enum _D3DTEXTURESTAGESTATETYPE +{ + D3DTSS_COLOROP = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ + D3DTSS_COLORARG1 = 2, /* D3DTA_* (texture arg) */ + D3DTSS_COLORARG2 = 3, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAOP = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ + D3DTSS_ALPHAARG1 = 5, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAARG2 = 6, /* D3DTA_* (texture arg) */ + D3DTSS_BUMPENVMAT00 = 7, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT01 = 8, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT10 = 9, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT11 = 10, /* float (bump mapping matrix) */ + D3DTSS_TEXCOORDINDEX = 11, /* identifies which set of texture coordinates index this texture */ + D3DTSS_BUMPENVLSCALE = 22, /* float scale for bump map luminance */ + D3DTSS_BUMPENVLOFFSET = 23, /* float offset for bump map luminance */ + D3DTSS_TEXTURETRANSFORMFLAGS = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ + D3DTSS_COLORARG0 = 26, /* D3DTA_* third arg for triadic ops */ + D3DTSS_ALPHAARG0 = 27, /* D3DTA_* third arg for triadic ops */ + D3DTSS_RESULTARG = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ + D3DTSS_CONSTANT = 32, /* Per-stage constant D3DTA_CONSTANT */ + + + D3DTSS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTURESTAGESTATETYPE; + +/* + * State enumerants for per-sampler texture processing. + */ +typedef enum _D3DSAMPLERSTATETYPE +{ + D3DSAMP_ADDRESSU = 1, /* D3DTEXTUREADDRESS for U coordinate */ + D3DSAMP_ADDRESSV = 2, /* D3DTEXTUREADDRESS for V coordinate */ + D3DSAMP_ADDRESSW = 3, /* D3DTEXTUREADDRESS for W coordinate */ + D3DSAMP_BORDERCOLOR = 4, /* D3DCOLOR */ + D3DSAMP_MAGFILTER = 5, /* D3DTEXTUREFILTER filter to use for magnification */ + D3DSAMP_MINFILTER = 6, /* D3DTEXTUREFILTER filter to use for minification */ + D3DSAMP_MIPFILTER = 7, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */ + D3DSAMP_MIPMAPLODBIAS = 8, /* float Mipmap LOD bias */ + D3DSAMP_MAXMIPLEVEL = 9, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */ + D3DSAMP_MAXANISOTROPY = 10, /* DWORD maximum anisotropy */ + D3DSAMP_SRGBTEXTURE = 11, /* Default = 0 (which means Gamma 1.0, + no correction required.) else correct for + Gamma = 2.2 */ + D3DSAMP_ELEMENTINDEX = 12, /* When multi-element texture is assigned to sampler, this + indicates which element index to use. Default = 0. */ + D3DSAMP_DMAPOFFSET = 13, /* Offset in vertices in the pre-sampled displacement map. + Only valid for D3DDMAPSAMPLER sampler */ + D3DSAMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DSAMPLERSTATETYPE; + +/* Special sampler which is used in the tesselator */ +#define D3DDMAPSAMPLER 256 + +// Samplers used in vertex shaders +#define D3DVERTEXTEXTURESAMPLER0 (D3DDMAPSAMPLER+1) +#define D3DVERTEXTEXTURESAMPLER1 (D3DDMAPSAMPLER+2) +#define D3DVERTEXTEXTURESAMPLER2 (D3DDMAPSAMPLER+3) +#define D3DVERTEXTEXTURESAMPLER3 (D3DDMAPSAMPLER+4) + +// Values, used with D3DTSS_TEXCOORDINDEX, to specify that the vertex data(position +// and normal in the camera space) should be taken as texture coordinates +// Low 16 bits are used to specify texture coordinate index, to take the WRAP mode from +// +#define D3DTSS_TCI_PASSTHRU 0x00000000 +#define D3DTSS_TCI_CAMERASPACENORMAL 0x00010000 +#define D3DTSS_TCI_CAMERASPACEPOSITION 0x00020000 +#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x00030000 +#define D3DTSS_TCI_SPHEREMAP 0x00040000 + +/* + * Enumerations for COLOROP and ALPHAOP texture blending operations set in + * texture processing stage controls in D3DTSS. + */ +typedef enum _D3DTEXTUREOP +{ + // Control + D3DTOP_DISABLE = 1, // disables stage + D3DTOP_SELECTARG1 = 2, // the default + D3DTOP_SELECTARG2 = 3, + + // Modulate + D3DTOP_MODULATE = 4, // multiply args together + D3DTOP_MODULATE2X = 5, // multiply and 1 bit + D3DTOP_MODULATE4X = 6, // multiply and 2 bits + + // Add + D3DTOP_ADD = 7, // add arguments together + D3DTOP_ADDSIGNED = 8, // add with -0.5 bias + D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit + D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation + D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product + // Arg1 + Arg2 - Arg1*Arg2 + // = Arg1 + (1-Arg1)*Arg2 + + // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha) + D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha + D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha + D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRS_TEXTUREFACTOR + + // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha) + D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha + D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color + + // Specular mapping + D3DTOP_PREMODULATE = 17, // modulate with next texture before use + D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB + // COLOROP only + D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A + // COLOROP only + D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, // (1-Arg1.A)*Arg2.RGB + Arg1.RGB + // COLOROP only + D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, // (1-Arg1.RGB)*Arg2.RGB + Arg1.A + // COLOROP only + + // Bump mapping + D3DTOP_BUMPENVMAP = 22, // per pixel env map perturbation + D3DTOP_BUMPENVMAPLUMINANCE = 23, // with luminance channel + + // This can do either diffuse or specular bump mapping with correct input. + // Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B) + // where each component has been scaled and offset to make it signed. + // The result is replicated into all four (including alpha) channels. + // This is a valid COLOROP only. + D3DTOP_DOTPRODUCT3 = 24, + + // Triadic ops + D3DTOP_MULTIPLYADD = 25, // Arg0 + Arg1*Arg2 + D3DTOP_LERP = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2 + + D3DTOP_FORCE_DWORD = 0x7fffffff, +} D3DTEXTUREOP; + +/* + * Values for COLORARG0,1,2, ALPHAARG0,1,2, and RESULTARG texture blending + * operations set in texture processing stage controls in D3DRENDERSTATE. + */ +#define D3DTA_SELECTMASK 0x0000000f // mask for arg selector +#define D3DTA_DIFFUSE 0x00000000 // select diffuse color (read only) +#define D3DTA_CURRENT 0x00000001 // select stage destination register (read/write) +#define D3DTA_TEXTURE 0x00000002 // select texture color (read only) +#define D3DTA_TFACTOR 0x00000003 // select D3DRS_TEXTUREFACTOR (read only) +#define D3DTA_SPECULAR 0x00000004 // select specular color (read only) +#define D3DTA_TEMP 0x00000005 // select temporary register color (read/write) +#define D3DTA_CONSTANT 0x00000006 // select texture stage constant +#define D3DTA_COMPLEMENT 0x00000010 // take 1.0 - x (read modifier) +#define D3DTA_ALPHAREPLICATE 0x00000020 // replicate alpha to color components (read modifier) + +// +// Values for D3DSAMP_***FILTER texture stage states +// +typedef enum _D3DTEXTUREFILTERTYPE +{ + D3DTEXF_NONE = 0, // filtering disabled (valid for mip filter only) + D3DTEXF_POINT = 1, // nearest + D3DTEXF_LINEAR = 2, // linear interpolation + D3DTEXF_ANISOTROPIC = 3, // anisotropic + D3DTEXF_PYRAMIDALQUAD = 6, // 4-sample tent + D3DTEXF_GAUSSIANQUAD = 7, // 4-sample gaussian +/* D3D9Ex only -- */ +#if !defined(D3D_DISABLE_9EX) + + D3DTEXF_CONVOLUTIONMONO = 8, // Convolution filter for monochrome textures + +#endif // !D3D_DISABLE_9EX +/* -- D3D9Ex only */ + D3DTEXF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DTEXTUREFILTERTYPE; + +/* Bits for Flags in ProcessVertices call */ + +#define D3DPV_DONOTCOPYDATA (1 << 0) + +//------------------------------------------------------------------- + +// Flexible vertex format bits +// +#define D3DFVF_RESERVED0 0x001 +#define D3DFVF_POSITION_MASK 0x400E +#define D3DFVF_XYZ 0x002 +#define D3DFVF_XYZRHW 0x004 +#define D3DFVF_XYZB1 0x006 +#define D3DFVF_XYZB2 0x008 +#define D3DFVF_XYZB3 0x00a +#define D3DFVF_XYZB4 0x00c +#define D3DFVF_XYZB5 0x00e +#define D3DFVF_XYZW 0x4002 + +#define D3DFVF_NORMAL 0x010 +#define D3DFVF_PSIZE 0x020 +#define D3DFVF_DIFFUSE 0x040 +#define D3DFVF_SPECULAR 0x080 + +#define D3DFVF_TEXCOUNT_MASK 0xf00 +#define D3DFVF_TEXCOUNT_SHIFT 8 +#define D3DFVF_TEX0 0x000 +#define D3DFVF_TEX1 0x100 +#define D3DFVF_TEX2 0x200 +#define D3DFVF_TEX3 0x300 +#define D3DFVF_TEX4 0x400 +#define D3DFVF_TEX5 0x500 +#define D3DFVF_TEX6 0x600 +#define D3DFVF_TEX7 0x700 +#define D3DFVF_TEX8 0x800 + +#define D3DFVF_LASTBETA_UBYTE4 0x1000 +#define D3DFVF_LASTBETA_D3DCOLOR 0x8000 + +#define D3DFVF_RESERVED2 0x6000 // 2 reserved bits + +//--------------------------------------------------------------------- +// Vertex Shaders +// + +// Vertex shader declaration + +// Vertex element semantics +// +typedef enum _D3DDECLUSAGE +{ + D3DDECLUSAGE_POSITION = 0, + D3DDECLUSAGE_BLENDWEIGHT, // 1 + D3DDECLUSAGE_BLENDINDICES, // 2 + D3DDECLUSAGE_NORMAL, // 3 + D3DDECLUSAGE_PSIZE, // 4 + D3DDECLUSAGE_TEXCOORD, // 5 + D3DDECLUSAGE_TANGENT, // 6 + D3DDECLUSAGE_BINORMAL, // 7 + D3DDECLUSAGE_TESSFACTOR, // 8 + D3DDECLUSAGE_POSITIONT, // 9 + D3DDECLUSAGE_COLOR, // 10 + D3DDECLUSAGE_FOG, // 11 + D3DDECLUSAGE_DEPTH, // 12 + D3DDECLUSAGE_SAMPLE, // 13 +} D3DDECLUSAGE; + +#define MAXD3DDECLUSAGE D3DDECLUSAGE_SAMPLE +#define MAXD3DDECLUSAGEINDEX 15 +#define MAXD3DDECLLENGTH 64 // does not include "end" marker vertex element + +typedef enum _D3DDECLMETHOD +{ + D3DDECLMETHOD_DEFAULT = 0, + D3DDECLMETHOD_PARTIALU, + D3DDECLMETHOD_PARTIALV, + D3DDECLMETHOD_CROSSUV, // Normal + D3DDECLMETHOD_UV, + D3DDECLMETHOD_LOOKUP, // Lookup a displacement map + D3DDECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map +} D3DDECLMETHOD; + +#define MAXD3DDECLMETHOD D3DDECLMETHOD_LOOKUPPRESAMPLED + +// Declarations for _Type fields +// +typedef enum _D3DDECLTYPE +{ + D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.) + D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.) + D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.) + D3DDECLTYPE_FLOAT4 = 3, // 4D float + D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range + // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A) + D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte + D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.) + D3DDECLTYPE_SHORT4 = 7, // 4D signed short + +// The following types are valid only with vertex shaders >= 2.0 + + + D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0 + D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1) + D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0) + D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1) + D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0) + D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1) + D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1) + D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1) + D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values + D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused. +} D3DDECLTYPE; + +#define MAXD3DDECLTYPE D3DDECLTYPE_UNUSED + +typedef struct _D3DVERTEXELEMENT9 +{ + WORD Stream; // Stream index + WORD Offset; // Offset in the stream in bytes + BYTE Type; // Data type + BYTE Method; // Processing method + BYTE Usage; // Semantics + BYTE UsageIndex; // Semantic index +} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; + +// This is used to initialize the last vertex element in a vertex declaration +// array +// +#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0} + +// Maximum supported number of texture coordinate sets +#define D3DDP_MAXTEXCOORD 8 + +//--------------------------------------------------------------------- +// Values for IDirect3DDevice9::SetStreamSourceFreq's Setting parameter +//--------------------------------------------------------------------- +#define D3DSTREAMSOURCE_INDEXEDDATA (1<<30) +#define D3DSTREAMSOURCE_INSTANCEDATA (2<<30) + + + +//--------------------------------------------------------------------- +// +// The internal format of Pixel Shader (PS) & Vertex Shader (VS) +// Instruction Tokens is defined in the Direct3D Device Driver Kit +// +//--------------------------------------------------------------------- + +// +// Instruction Token Bit Definitions +// +#define D3DSI_OPCODE_MASK 0x0000FFFF + +#define D3DSI_INSTLENGTH_MASK 0x0F000000 +#define D3DSI_INSTLENGTH_SHIFT 24 + +typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE +{ + D3DSIO_NOP = 0, + D3DSIO_MOV , + D3DSIO_ADD , + D3DSIO_SUB , + D3DSIO_MAD , + D3DSIO_MUL , + D3DSIO_RCP , + D3DSIO_RSQ , + D3DSIO_DP3 , + D3DSIO_DP4 , + D3DSIO_MIN , + D3DSIO_MAX , + D3DSIO_SLT , + D3DSIO_SGE , + D3DSIO_EXP , + D3DSIO_LOG , + D3DSIO_LIT , + D3DSIO_DST , + D3DSIO_LRP , + D3DSIO_FRC , + D3DSIO_M4x4 , + D3DSIO_M4x3 , + D3DSIO_M3x4 , + D3DSIO_M3x3 , + D3DSIO_M3x2 , + D3DSIO_CALL , + D3DSIO_CALLNZ , + D3DSIO_LOOP , + D3DSIO_RET , + D3DSIO_ENDLOOP , + D3DSIO_LABEL , + D3DSIO_DCL , + D3DSIO_POW , + D3DSIO_CRS , + D3DSIO_SGN , + D3DSIO_ABS , + D3DSIO_NRM , + D3DSIO_SINCOS , + D3DSIO_REP , + D3DSIO_ENDREP , + D3DSIO_IF , + D3DSIO_IFC , + D3DSIO_ELSE , + D3DSIO_ENDIF , + D3DSIO_BREAK , + D3DSIO_BREAKC , + D3DSIO_MOVA , + D3DSIO_DEFB , + D3DSIO_DEFI , + + D3DSIO_TEXCOORD = 64, + D3DSIO_TEXKILL , + D3DSIO_TEX , + D3DSIO_TEXBEM , + D3DSIO_TEXBEML , + D3DSIO_TEXREG2AR , + D3DSIO_TEXREG2GB , + D3DSIO_TEXM3x2PAD , + D3DSIO_TEXM3x2TEX , + D3DSIO_TEXM3x3PAD , + D3DSIO_TEXM3x3TEX , + D3DSIO_RESERVED0 , + D3DSIO_TEXM3x3SPEC , + D3DSIO_TEXM3x3VSPEC , + D3DSIO_EXPP , + D3DSIO_LOGP , + D3DSIO_CND , + D3DSIO_DEF , + D3DSIO_TEXREG2RGB , + D3DSIO_TEXDP3TEX , + D3DSIO_TEXM3x2DEPTH , + D3DSIO_TEXDP3 , + D3DSIO_TEXM3x3 , + D3DSIO_TEXDEPTH , + D3DSIO_CMP , + D3DSIO_BEM , + D3DSIO_DP2ADD , + D3DSIO_DSX , + D3DSIO_DSY , + D3DSIO_TEXLDD , + D3DSIO_SETP , + D3DSIO_TEXLDL , + D3DSIO_BREAKP , + + D3DSIO_PHASE = 0xFFFD, + D3DSIO_COMMENT = 0xFFFE, + D3DSIO_END = 0xFFFF, + + D3DSIO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DSHADER_INSTRUCTION_OPCODE_TYPE; + +//--------------------------------------------------------------------- +// Use these constants with D3DSIO_SINCOS macro as SRC2, SRC3 +// +#define D3DSINCOSCONST1 -1.5500992e-006f, -2.1701389e-005f, 0.0026041667f, 0.00026041668f +#define D3DSINCOSCONST2 -0.020833334f, -0.12500000f, 1.0f, 0.50000000f + +//--------------------------------------------------------------------- +// Co-Issue Instruction Modifier - if set then this instruction is to be +// issued in parallel with the previous instruction(s) for which this bit +// is not set. +// +#define D3DSI_COISSUE 0x40000000 + +//--------------------------------------------------------------------- +// Opcode specific controls + +#define D3DSP_OPCODESPECIFICCONTROL_MASK 0x00ff0000 +#define D3DSP_OPCODESPECIFICCONTROL_SHIFT 16 + +// ps_2_0 texld controls +#define D3DSI_TEXLD_PROJECT (0x01 << D3DSP_OPCODESPECIFICCONTROL_SHIFT) +#define D3DSI_TEXLD_BIAS (0x02 << D3DSP_OPCODESPECIFICCONTROL_SHIFT) + +// Comparison for dynamic conditional instruction opcodes (i.e. if, breakc) +typedef enum _D3DSHADER_COMPARISON +{ + // < = > + D3DSPC_RESERVED0= 0, // 0 0 0 + D3DSPC_GT = 1, // 0 0 1 + D3DSPC_EQ = 2, // 0 1 0 + D3DSPC_GE = 3, // 0 1 1 + D3DSPC_LT = 4, // 1 0 0 + D3DSPC_NE = 5, // 1 0 1 + D3DSPC_LE = 6, // 1 1 0 + D3DSPC_RESERVED1= 7 // 1 1 1 +} D3DSHADER_COMPARISON; + +// Comparison is part of instruction opcode token: +#define D3DSHADER_COMPARISON_SHIFT D3DSP_OPCODESPECIFICCONTROL_SHIFT +#define D3DSHADER_COMPARISON_MASK (0x7<>8)&0xFF) +#define D3DSHADER_VERSION_MINOR(_Version) (((_Version)>>0)&0xFF) + +// destination/source parameter register type +#define D3DSI_COMMENTSIZE_SHIFT 16 +#define D3DSI_COMMENTSIZE_MASK 0x7FFF0000 +#define D3DSHADER_COMMENT(_DWordSize) \ + ((((_DWordSize)<= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4201) +#endif + +#endif /* (DIRECT3D_VERSION >= 0x0900) */ +#endif /* _d3d9TYPES(P)_H_ */ + diff --git a/dxsdk/Include/d3dx10async.h b/dxsdk/Include/d3dx10async.h new file mode 100644 index 0000000..d1b1fc5 --- /dev/null +++ b/dxsdk/Include/d3dx10async.h @@ -0,0 +1,290 @@ + +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3DX10Async.h +// Content: D3DX10 Asynchronous Effect / Shader loaders / compilers +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX10ASYNC_H__ +#define __D3DX10ASYNC_H__ + +#include "d3dx10.h" + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3DX10Compile: +// ------------------ +// Compiles an effect or shader. +// +// Parameters: +// pSrcFile +// Source file name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module. +// pSrcData +// Pointer to source code. +// SrcDataLen +// Size of source code, in bytes. +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pFunctionName +// Name of the entrypoint function where execution should begin. +// pProfile +// Instruction set to be used when generating code. Currently supported +// profiles are "vs_1_1", "vs_2_0", "vs_2_a", "vs_2_sw", "vs_3_0", +// "vs_3_sw", "vs_4_0", "vs_4_1", +// "ps_2_0", "ps_2_a", "ps_2_b", "ps_2_sw", "ps_3_0", +// "ps_3_sw", "ps_4_0", "ps_4_1", +// "gs_4_0", "gs_4_1", +// "tx_1_0", +// "fx_4_0", "fx_4_1" +// Note that this entrypoint does not compile fx_2_0 targets, for that +// you need to use the D3DX9 function. +// Flags1 +// See D3D10_SHADER_xxx flags. +// Flags2 +// See D3D10_EFFECT_xxx flags. +// ppShader +// Returns a buffer containing the created shader. This buffer contains +// the compiled shader code, as well as any embedded debug and symbol +// table info. (See D3D10GetShaderConstantTable) +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during the compile. If you are running in a debugger, +// these are the same messages you will see in your debug output. +// pHResult +// Pointer to a memory location to receive the return value upon completion. +// Maybe NULL if not needed. +// If pPump != NULL, pHResult must be a valid memory location until the +// the asynchronous execution completes. +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3DX10CompileFromFileA(LPCSTR pSrcFile,CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX10ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CompileFromFileW(LPCWSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX10ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10CompileFromFile D3DX10CompileFromFileW +#else +#define D3DX10CompileFromFile D3DX10CompileFromFileA +#endif + +HRESULT WINAPI D3DX10CompileFromResourceA(HMODULE hSrcModule, LPCSTR pSrcResource, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX10ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CompileFromResourceW(HMODULE hSrcModule, LPCWSTR pSrcResource, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX10ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10CompileFromResource D3DX10CompileFromResourceW +#else +#define D3DX10CompileFromResource D3DX10CompileFromResourceA +#endif + +HRESULT WINAPI D3DX10CompileFromMemory(LPCSTR pSrcData, SIZE_T SrcDataLen, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX10ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +//---------------------------------------------------------------------------- +// D3DX10CreateEffectFromXXXX: +// -------------------------- +// Creates an effect from a binary effect or file +// +// Parameters: +// +// [in] +// +// +// pFileName +// Name of the ASCII (uncompiled) or binary (compiled) Effect file to load +// +// hModule +// Handle to the module containing the resource to compile from +// pResourceName +// Name of the resource within hModule to compile from +// +// pData +// Blob of effect data, either ASCII (uncompiled) or binary (compiled) +// DataLength +// Length of the data blob +// +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pProfile +// Profile to use when compiling the effect. +// HLSLFlags +// Compilation flags pertaining to shaders and data types, honored by +// the HLSL compiler +// FXFlags +// Compilation flags pertaining to Effect compilation, honored +// by the Effect compiler +// pDevice +// Pointer to the D3D10 device on which to create Effect resources +// pEffectPool +// Pointer to an Effect pool to share variables with or NULL +// +// [out] +// +// ppEffect +// Address of the newly created Effect interface +// ppEffectPool +// Address of the newly created Effect pool interface +// ppErrors +// If non-NULL, address of a buffer with error messages that occurred +// during parsing or compilation +// pHResult +// Pointer to a memory location to receive the return value upon completion. +// Maybe NULL if not needed. +// If pPump != NULL, pHResult must be a valid memory location until the +// the asynchronous execution completes. +//---------------------------------------------------------------------------- + + +HRESULT WINAPI D3DX10CreateEffectFromFileA(LPCSTR pFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, ID3DX10ThreadPump* pPump, ID3D10Effect **ppEffect, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectFromFileW(LPCWSTR pFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, ID3DX10ThreadPump* pPump, ID3D10Effect **ppEffect, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectFromMemory(LPCVOID pData, SIZE_T DataLength, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, ID3DX10ThreadPump* pPump, ID3D10Effect **ppEffect, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectFromResourceA(HMODULE hModule, LPCSTR pResourceName, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, ID3DX10ThreadPump* pPump, ID3D10Effect **ppEffect, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectFromResourceW(HMODULE hModule, LPCWSTR pResourceName, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, ID3DX10ThreadPump* pPump, ID3D10Effect **ppEffect, ID3D10Blob **ppErrors, HRESULT* pHResult); + + +#ifdef UNICODE +#define D3DX10CreateEffectFromFile D3DX10CreateEffectFromFileW +#define D3DX10CreateEffectFromResource D3DX10CreateEffectFromResourceW +#else +#define D3DX10CreateEffectFromFile D3DX10CreateEffectFromFileA +#define D3DX10CreateEffectFromResource D3DX10CreateEffectFromResourceA +#endif + +HRESULT WINAPI D3DX10CreateEffectPoolFromFileA(LPCSTR pFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, ID3DX10ThreadPump* pPump, + ID3D10EffectPool **ppEffectPool, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectPoolFromFileW(LPCWSTR pFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, ID3DX10ThreadPump* pPump, + ID3D10EffectPool **ppEffectPool, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectPoolFromMemory(LPCVOID pData, SIZE_T DataLength, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3DX10ThreadPump* pPump, ID3D10EffectPool **ppEffectPool, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectPoolFromResourceA(HMODULE hModule, LPCSTR pResourceName, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3DX10ThreadPump* pPump, ID3D10EffectPool **ppEffectPool, ID3D10Blob **ppErrors, HRESULT* pHResult); + +HRESULT WINAPI D3DX10CreateEffectPoolFromResourceW(HMODULE hModule, LPCWSTR pResourceName, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, LPCSTR pProfile, UINT HLSLFlags, UINT FXFlags, ID3D10Device *pDevice, + ID3DX10ThreadPump* pPump, ID3D10EffectPool **ppEffectPool, ID3D10Blob **ppErrors, HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10CreateEffectPoolFromFile D3DX10CreateEffectPoolFromFileW +#define D3DX10CreateEffectPoolFromResource D3DX10CreateEffectPoolFromResourceW +#else +#define D3DX10CreateEffectPoolFromFile D3DX10CreateEffectPoolFromFileA +#define D3DX10CreateEffectPoolFromResource D3DX10CreateEffectPoolFromResourceA +#endif + +HRESULT WINAPI D3DX10PreprocessShaderFromFileA(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX10ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX10PreprocessShaderFromFileW(LPCWSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX10ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX10PreprocessShaderFromMemory(LPCSTR pSrcData, SIZE_T SrcDataSize, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX10ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX10PreprocessShaderFromResourceA(HMODULE hModule, LPCSTR pResourceName, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX10ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +HRESULT WINAPI D3DX10PreprocessShaderFromResourceW(HMODULE hModule, LPCWSTR pResourceName, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, ID3DX10ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +#ifdef UNICODE +#define D3DX10PreprocessShaderFromFile D3DX10PreprocessShaderFromFileW +#define D3DX10PreprocessShaderFromResource D3DX10PreprocessShaderFromResourceW +#else +#define D3DX10PreprocessShaderFromFile D3DX10PreprocessShaderFromFileA +#define D3DX10PreprocessShaderFromResource D3DX10PreprocessShaderFromResourceA +#endif + +//---------------------------------------------------------------------------- +// Async processors +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3DX10CreateAsyncCompilerProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, + ID3D10Blob **ppCompiledShader, ID3D10Blob **ppErrorBuffer, ID3DX10DataProcessor **ppProcessor); + +HRESULT WINAPI D3DX10CreateAsyncEffectCreateProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pProfile, UINT Flags, UINT FXFlags, ID3D10Device *pDevice, + ID3D10EffectPool *pPool, ID3D10Blob **ppErrorBuffer, ID3DX10DataProcessor **ppProcessor); + +HRESULT WINAPI D3DX10CreateAsyncEffectPoolCreateProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pProfile, UINT Flags, UINT FXFlags, ID3D10Device *pDevice, + ID3D10Blob **ppErrorBuffer, ID3DX10DataProcessor **ppProcessor); + +HRESULT WINAPI D3DX10CreateAsyncShaderPreprocessProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + ID3D10Blob** ppShaderText, ID3D10Blob **ppErrorBuffer, ID3DX10DataProcessor **ppProcessor); + + + +//---------------------------------------------------------------------------- +// D3DX10 Asynchronous texture I/O (advanced mode) +//---------------------------------------------------------------------------- + +HRESULT WINAPI D3DX10CreateAsyncFileLoaderW(LPCWSTR pFileName, ID3DX10DataLoader **ppDataLoader); +HRESULT WINAPI D3DX10CreateAsyncFileLoaderA(LPCSTR pFileName, ID3DX10DataLoader **ppDataLoader); +HRESULT WINAPI D3DX10CreateAsyncMemoryLoader(LPCVOID pData, SIZE_T cbData, ID3DX10DataLoader **ppDataLoader); +HRESULT WINAPI D3DX10CreateAsyncResourceLoaderW(HMODULE hSrcModule, LPCWSTR pSrcResource, ID3DX10DataLoader **ppDataLoader); +HRESULT WINAPI D3DX10CreateAsyncResourceLoaderA(HMODULE hSrcModule, LPCSTR pSrcResource, ID3DX10DataLoader **ppDataLoader); + +#ifdef UNICODE +#define D3DX10CreateAsyncFileLoader D3DX10CreateAsyncFileLoaderW +#define D3DX10CreateAsyncResourceLoader D3DX10CreateAsyncResourceLoaderW +#else +#define D3DX10CreateAsyncFileLoader D3DX10CreateAsyncFileLoaderA +#define D3DX10CreateAsyncResourceLoader D3DX10CreateAsyncResourceLoaderA +#endif + +HRESULT WINAPI D3DX10CreateAsyncTextureProcessor(ID3D10Device *pDevice, D3DX10_IMAGE_LOAD_INFO *pLoadInfo, ID3DX10DataProcessor **ppDataProcessor); +HRESULT WINAPI D3DX10CreateAsyncTextureInfoProcessor(D3DX10_IMAGE_INFO *pImageInfo, ID3DX10DataProcessor **ppDataProcessor); +HRESULT WINAPI D3DX10CreateAsyncShaderResourceViewProcessor(ID3D10Device *pDevice, D3DX10_IMAGE_LOAD_INFO *pLoadInfo, ID3DX10DataProcessor **ppDataProcessor); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX10ASYNC_H__ + + diff --git a/dxsdk/Include/d3dx9.h b/dxsdk/Include/d3dx9.h new file mode 100644 index 0000000..43f9e62 --- /dev/null +++ b/dxsdk/Include/d3dx9.h @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9.h +// Content: D3DX utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __D3DX_INTERNAL__ +#error Incorrect D3DX header used +#endif + +#ifndef __D3DX9_H__ +#define __D3DX9_H__ + + +// Defines +#include + +#define D3DX_DEFAULT ((UINT) -1) +#define D3DX_DEFAULT_NONPOW2 ((UINT) -2) +#define D3DX_DEFAULT_FLOAT FLT_MAX +#define D3DX_FROM_FILE ((UINT) -3) +#define D3DFMT_FROM_FILE ((D3DFORMAT) -3) + +#ifndef D3DXINLINE +#ifdef _MSC_VER + #if (_MSC_VER >= 1200) + #define D3DXINLINE __forceinline + #else + #define D3DXINLINE __inline + #endif +#else + #ifdef __cplusplus + #define D3DXINLINE inline + #else + #define D3DXINLINE + #endif +#endif +#endif + + + +// Includes +#include "d3d9.h" +#include "d3dx9math.h" +#include "d3dx9core.h" +#include "d3dx9xof.h" +#include "d3dx9mesh.h" +#include "d3dx9shader.h" +#include "d3dx9effect.h" + +#include "d3dx9tex.h" +#include "d3dx9shape.h" +#include "d3dx9anim.h" + + + +// Errors +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +enum _D3DXERR { + D3DXERR_CANNOTMODIFYINDEXBUFFER = MAKE_DDHRESULT(2900), + D3DXERR_INVALIDMESH = MAKE_DDHRESULT(2901), + D3DXERR_CANNOTATTRSORT = MAKE_DDHRESULT(2902), + D3DXERR_SKINNINGNOTSUPPORTED = MAKE_DDHRESULT(2903), + D3DXERR_TOOMANYINFLUENCES = MAKE_DDHRESULT(2904), + D3DXERR_INVALIDDATA = MAKE_DDHRESULT(2905), + D3DXERR_LOADEDMESHASNODATA = MAKE_DDHRESULT(2906), + D3DXERR_DUPLICATENAMEDFRAGMENT = MAKE_DDHRESULT(2907), + D3DXERR_CANNOTREMOVELASTITEM = MAKE_DDHRESULT(2908), +}; + + +#endif //__D3DX9_H__ + diff --git a/dxsdk/Include/d3dx9anim.h b/dxsdk/Include/d3dx9anim.h new file mode 100644 index 0000000..fedb1db --- /dev/null +++ b/dxsdk/Include/d3dx9anim.h @@ -0,0 +1,1114 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9anim.h +// Content: D3DX mesh types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX9ANIM_H__ +#define __D3DX9ANIM_H__ + +// {698CFB3F-9289-4d95-9A57-33A94B5A65F9} +DEFINE_GUID(IID_ID3DXAnimationSet, +0x698cfb3f, 0x9289, 0x4d95, 0x9a, 0x57, 0x33, 0xa9, 0x4b, 0x5a, 0x65, 0xf9); + +// {FA4E8E3A-9786-407d-8B4C-5995893764AF} +DEFINE_GUID(IID_ID3DXKeyframedAnimationSet, +0xfa4e8e3a, 0x9786, 0x407d, 0x8b, 0x4c, 0x59, 0x95, 0x89, 0x37, 0x64, 0xaf); + +// {6CC2480D-3808-4739-9F88-DE49FACD8D4C} +DEFINE_GUID(IID_ID3DXCompressedAnimationSet, +0x6cc2480d, 0x3808, 0x4739, 0x9f, 0x88, 0xde, 0x49, 0xfa, 0xcd, 0x8d, 0x4c); + +// {AC8948EC-F86D-43e2-96DE-31FC35F96D9E} +DEFINE_GUID(IID_ID3DXAnimationController, +0xac8948ec, 0xf86d, 0x43e2, 0x96, 0xde, 0x31, 0xfc, 0x35, 0xf9, 0x6d, 0x9e); + + +//---------------------------------------------------------------------------- +// D3DXMESHDATATYPE: +// ----------------- +// This enum defines the type of mesh data present in a MeshData structure. +//---------------------------------------------------------------------------- +typedef enum _D3DXMESHDATATYPE { + D3DXMESHTYPE_MESH = 0x001, // Normal ID3DXMesh data + D3DXMESHTYPE_PMESH = 0x002, // Progressive Mesh - ID3DXPMesh + D3DXMESHTYPE_PATCHMESH = 0x003, // Patch Mesh - ID3DXPatchMesh + + D3DXMESHTYPE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXMESHDATATYPE; + +//---------------------------------------------------------------------------- +// D3DXMESHDATA: +// ------------- +// This struct encapsulates a the mesh data that can be present in a mesh +// container. The supported mesh types are pMesh, pPMesh, pPatchMesh. +// The valid way to access this is determined by the Type enum. +//---------------------------------------------------------------------------- +typedef struct _D3DXMESHDATA +{ + D3DXMESHDATATYPE Type; + + // current mesh data interface + union + { + LPD3DXMESH pMesh; + LPD3DXPMESH pPMesh; + LPD3DXPATCHMESH pPatchMesh; + }; +} D3DXMESHDATA, *LPD3DXMESHDATA; + +//---------------------------------------------------------------------------- +// D3DXMESHCONTAINER: +// ------------------ +// This struct encapsulates a mesh object in a transformation frame +// hierarchy. The app can derive from this structure to add other app specific +// data to this. +//---------------------------------------------------------------------------- +typedef struct _D3DXMESHCONTAINER +{ + LPSTR Name; + + D3DXMESHDATA MeshData; + + LPD3DXMATERIAL pMaterials; + LPD3DXEFFECTINSTANCE pEffects; + DWORD NumMaterials; + DWORD *pAdjacency; + + LPD3DXSKININFO pSkinInfo; + + struct _D3DXMESHCONTAINER *pNextMeshContainer; +} D3DXMESHCONTAINER, *LPD3DXMESHCONTAINER; + +//---------------------------------------------------------------------------- +// D3DXFRAME: +// ---------- +// This struct is the encapsulates a transform frame in a transformation frame +// hierarchy. The app can derive from this structure to add other app specific +// data to this +//---------------------------------------------------------------------------- +typedef struct _D3DXFRAME +{ + LPSTR Name; + D3DXMATRIX TransformationMatrix; + + LPD3DXMESHCONTAINER pMeshContainer; + + struct _D3DXFRAME *pFrameSibling; + struct _D3DXFRAME *pFrameFirstChild; +} D3DXFRAME, *LPD3DXFRAME; + + +//---------------------------------------------------------------------------- +// ID3DXAllocateHierarchy: +// ----------------------- +// This interface is implemented by the application to allocate/free frame and +// mesh container objects. Methods on this are called during loading and +// destroying frame hierarchies +//---------------------------------------------------------------------------- +typedef interface ID3DXAllocateHierarchy ID3DXAllocateHierarchy; +typedef interface ID3DXAllocateHierarchy *LPD3DXALLOCATEHIERARCHY; + +#undef INTERFACE +#define INTERFACE ID3DXAllocateHierarchy + +DECLARE_INTERFACE(ID3DXAllocateHierarchy) +{ + // ID3DXAllocateHierarchy + + //------------------------------------------------------------------------ + // CreateFrame: + // ------------ + // Requests allocation of a frame object. + // + // Parameters: + // Name + // Name of the frame to be created + // ppNewFrame + // Returns the created frame object + // + //------------------------------------------------------------------------ + STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, + LPD3DXFRAME *ppNewFrame) PURE; + + //------------------------------------------------------------------------ + // CreateMeshContainer: + // -------------------- + // Requests allocation of a mesh container object. + // + // Parameters: + // Name + // Name of the mesh + // pMesh + // Pointer to the mesh object if basic polygon data found + // pPMesh + // Pointer to the progressive mesh object if progressive mesh data found + // pPatchMesh + // Pointer to the patch mesh object if patch data found + // pMaterials + // Array of materials used in the mesh + // pEffectInstances + // Array of effect instances used in the mesh + // NumMaterials + // Num elements in the pMaterials array + // pAdjacency + // Adjacency array for the mesh + // pSkinInfo + // Pointer to the skininfo object if the mesh is skinned + // pBoneNames + // Array of names, one for each bone in the skinned mesh. + // The numberof bones can be found from the pSkinMesh object + // pBoneOffsetMatrices + // Array of matrices, one for each bone in the skinned mesh. + // + //------------------------------------------------------------------------ + STDMETHOD(CreateMeshContainer)(THIS_ + LPCSTR Name, + CONST D3DXMESHDATA *pMeshData, + CONST D3DXMATERIAL *pMaterials, + CONST D3DXEFFECTINSTANCE *pEffectInstances, + DWORD NumMaterials, + CONST DWORD *pAdjacency, + LPD3DXSKININFO pSkinInfo, + LPD3DXMESHCONTAINER *ppNewMeshContainer) PURE; + + //------------------------------------------------------------------------ + // DestroyFrame: + // ------------- + // Requests de-allocation of a frame object. + // + // Parameters: + // pFrameToFree + // Pointer to the frame to be de-allocated + // + //------------------------------------------------------------------------ + STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree) PURE; + + //------------------------------------------------------------------------ + // DestroyMeshContainer: + // --------------------- + // Requests de-allocation of a mesh container object. + // + // Parameters: + // pMeshContainerToFree + // Pointer to the mesh container object to be de-allocated + // + //------------------------------------------------------------------------ + STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree) PURE; +}; + +//---------------------------------------------------------------------------- +// ID3DXLoadUserData: +// ------------------ +// This interface is implemented by the application to load user data in a .X file +// When user data is found, these callbacks will be used to allow the application +// to load the data. +//---------------------------------------------------------------------------- +typedef interface ID3DXLoadUserData ID3DXLoadUserData; +typedef interface ID3DXLoadUserData *LPD3DXLOADUSERDATA; + +#undef INTERFACE +#define INTERFACE ID3DXLoadUserData + +DECLARE_INTERFACE(ID3DXLoadUserData) +{ + STDMETHOD(LoadTopLevelData)(LPD3DXFILEDATA pXofChildData) PURE; + + STDMETHOD(LoadFrameChildData)(LPD3DXFRAME pFrame, + LPD3DXFILEDATA pXofChildData) PURE; + + STDMETHOD(LoadMeshChildData)(LPD3DXMESHCONTAINER pMeshContainer, + LPD3DXFILEDATA pXofChildData) PURE; +}; + +//---------------------------------------------------------------------------- +// ID3DXSaveUserData: +// ------------------ +// This interface is implemented by the application to save user data in a .X file +// The callbacks are called for all data saved. The user can then add any +// child data objects to the object provided to the callback. +//---------------------------------------------------------------------------- +typedef interface ID3DXSaveUserData ID3DXSaveUserData; +typedef interface ID3DXSaveUserData *LPD3DXSAVEUSERDATA; + +#undef INTERFACE +#define INTERFACE ID3DXSaveUserData + +DECLARE_INTERFACE(ID3DXSaveUserData) +{ + STDMETHOD(AddFrameChildData)(CONST D3DXFRAME *pFrame, + LPD3DXFILESAVEOBJECT pXofSave, + LPD3DXFILESAVEDATA pXofFrameData) PURE; + + STDMETHOD(AddMeshChildData)(CONST D3DXMESHCONTAINER *pMeshContainer, + LPD3DXFILESAVEOBJECT pXofSave, + LPD3DXFILESAVEDATA pXofMeshData) PURE; + + // NOTE: this is called once per Save. All top level objects should be added using the + // provided interface. One call adds objects before the frame hierarchy, the other after + STDMETHOD(AddTopLevelDataObjectsPre)(LPD3DXFILESAVEOBJECT pXofSave) PURE; + STDMETHOD(AddTopLevelDataObjectsPost)(LPD3DXFILESAVEOBJECT pXofSave) PURE; + + // callbacks for the user to register and then save templates to the XFile + STDMETHOD(RegisterTemplates)(LPD3DXFILE pXFileApi) PURE; + STDMETHOD(SaveTemplates)(LPD3DXFILESAVEOBJECT pXofSave) PURE; +}; + + +//---------------------------------------------------------------------------- +// D3DXCALLBACK_SEARCH_FLAGS: +// -------------------------- +// Flags that can be passed into ID3DXAnimationSet::GetCallback. +//---------------------------------------------------------------------------- +typedef enum _D3DXCALLBACK_SEARCH_FLAGS +{ + D3DXCALLBACK_SEARCH_EXCLUDING_INITIAL_POSITION = 0x01, // exclude callbacks at the initial position from the search + D3DXCALLBACK_SEARCH_BEHIND_INITIAL_POSITION = 0x02, // reverse the callback search direction + + D3DXCALLBACK_SEARCH_FORCE_DWORD = 0x7fffffff, +} D3DXCALLBACK_SEARCH_FLAGS; + +//---------------------------------------------------------------------------- +// ID3DXAnimationSet: +// ------------------ +// This interface implements an animation set. +//---------------------------------------------------------------------------- +typedef interface ID3DXAnimationSet ID3DXAnimationSet; +typedef interface ID3DXAnimationSet *LPD3DXANIMATIONSET; + +#undef INTERFACE +#define INTERFACE ID3DXAnimationSet + +DECLARE_INTERFACE_(ID3DXAnimationSet, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Name + STDMETHOD_(LPCSTR, GetName)(THIS) PURE; + + // Period + STDMETHOD_(DOUBLE, GetPeriod)(THIS) PURE; + STDMETHOD_(DOUBLE, GetPeriodicPosition)(THIS_ DOUBLE Position) PURE; // Maps position into animation period + + // Animation names + STDMETHOD_(UINT, GetNumAnimations)(THIS) PURE; + STDMETHOD(GetAnimationNameByIndex)(THIS_ UINT Index, LPCSTR *ppName) PURE; + STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; + + // SRT + STDMETHOD(GetSRT)(THIS_ + DOUBLE PeriodicPosition, // Position mapped to period (use GetPeriodicPosition) + UINT Animation, // Animation index + D3DXVECTOR3 *pScale, // Returns the scale + D3DXQUATERNION *pRotation, // Returns the rotation as a quaternion + D3DXVECTOR3 *pTranslation) PURE; // Returns the translation + + // Callbacks + STDMETHOD(GetCallback)(THIS_ + DOUBLE Position, // Position from which to find callbacks + DWORD Flags, // Callback search flags + DOUBLE *pCallbackPosition, // Returns the position of the callback + LPVOID *ppCallbackData) PURE; // Returns the callback data pointer +}; + + +//---------------------------------------------------------------------------- +// D3DXPLAYBACK_TYPE: +// ------------------ +// This enum defines the type of animation set loop modes. +//---------------------------------------------------------------------------- +typedef enum _D3DXPLAYBACK_TYPE +{ + D3DXPLAY_LOOP = 0, + D3DXPLAY_ONCE = 1, + D3DXPLAY_PINGPONG = 2, + + D3DXPLAY_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXPLAYBACK_TYPE; + + +//---------------------------------------------------------------------------- +// D3DXKEY_VECTOR3: +// ---------------- +// This structure describes a vector key for use in keyframe animation. +// It specifies a vector Value at a given Time. This is used for scale and +// translation keys. +//---------------------------------------------------------------------------- +typedef struct _D3DXKEY_VECTOR3 +{ + FLOAT Time; + D3DXVECTOR3 Value; +} D3DXKEY_VECTOR3, *LPD3DXKEY_VECTOR3; + + +//---------------------------------------------------------------------------- +// D3DXKEY_QUATERNION: +// ------------------- +// This structure describes a quaternion key for use in keyframe animation. +// It specifies a quaternion Value at a given Time. This is used for rotation +// keys. +//---------------------------------------------------------------------------- +typedef struct _D3DXKEY_QUATERNION +{ + FLOAT Time; + D3DXQUATERNION Value; +} D3DXKEY_QUATERNION, *LPD3DXKEY_QUATERNION; + + +//---------------------------------------------------------------------------- +// D3DXKEY_CALLBACK: +// ----------------- +// This structure describes an callback key for use in keyframe animation. +// It specifies a pointer to user data at a given Time. +//---------------------------------------------------------------------------- +typedef struct _D3DXKEY_CALLBACK +{ + FLOAT Time; + LPVOID pCallbackData; +} D3DXKEY_CALLBACK, *LPD3DXKEY_CALLBACK; + + +//---------------------------------------------------------------------------- +// D3DXCOMPRESSION_FLAGS: +// ---------------------- +// Flags that can be passed into ID3DXKeyframedAnimationSet::Compress. +//---------------------------------------------------------------------------- +typedef enum _D3DXCOMPRESSION_FLAGS +{ + D3DXCOMPRESS_DEFAULT = 0x00, + + D3DXCOMPRESS_FORCE_DWORD = 0x7fffffff, +} D3DXCOMPRESSION_FLAGS; + + +//---------------------------------------------------------------------------- +// ID3DXKeyframedAnimationSet: +// --------------------------- +// This interface implements a compressable keyframed animation set. +//---------------------------------------------------------------------------- +typedef interface ID3DXKeyframedAnimationSet ID3DXKeyframedAnimationSet; +typedef interface ID3DXKeyframedAnimationSet *LPD3DXKEYFRAMEDANIMATIONSET; + +#undef INTERFACE +#define INTERFACE ID3DXKeyframedAnimationSet + +DECLARE_INTERFACE_(ID3DXKeyframedAnimationSet, ID3DXAnimationSet) +{ + // ID3DXAnimationSet + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Name + STDMETHOD_(LPCSTR, GetName)(THIS) PURE; + + // Period + STDMETHOD_(DOUBLE, GetPeriod)(THIS) PURE; + STDMETHOD_(DOUBLE, GetPeriodicPosition)(THIS_ DOUBLE Position) PURE; // Maps position into animation period + + // Animation names + STDMETHOD_(UINT, GetNumAnimations)(THIS) PURE; + STDMETHOD(GetAnimationNameByIndex)(THIS_ UINT Index, LPCSTR *ppName) PURE; + STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; + + // SRT + STDMETHOD(GetSRT)(THIS_ + DOUBLE PeriodicPosition, // Position mapped to period (use GetPeriodicPosition) + UINT Animation, // Animation index + D3DXVECTOR3 *pScale, // Returns the scale + D3DXQUATERNION *pRotation, // Returns the rotation as a quaternion + D3DXVECTOR3 *pTranslation) PURE; // Returns the translation + + // Callbacks + STDMETHOD(GetCallback)(THIS_ + DOUBLE Position, // Position from which to find callbacks + DWORD Flags, // Callback search flags + DOUBLE *pCallbackPosition, // Returns the position of the callback + LPVOID *ppCallbackData) PURE; // Returns the callback data pointer + + // Playback + STDMETHOD_(D3DXPLAYBACK_TYPE, GetPlaybackType)(THIS) PURE; + STDMETHOD_(DOUBLE, GetSourceTicksPerSecond)(THIS) PURE; + + // Scale keys + STDMETHOD_(UINT, GetNumScaleKeys)(THIS_ UINT Animation) PURE; + STDMETHOD(GetScaleKeys)(THIS_ UINT Animation, LPD3DXKEY_VECTOR3 pScaleKeys) PURE; + STDMETHOD(GetScaleKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pScaleKey) PURE; + STDMETHOD(SetScaleKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pScaleKey) PURE; + + // Rotation keys + STDMETHOD_(UINT, GetNumRotationKeys)(THIS_ UINT Animation) PURE; + STDMETHOD(GetRotationKeys)(THIS_ UINT Animation, LPD3DXKEY_QUATERNION pRotationKeys) PURE; + STDMETHOD(GetRotationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_QUATERNION pRotationKey) PURE; + STDMETHOD(SetRotationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_QUATERNION pRotationKey) PURE; + + // Translation keys + STDMETHOD_(UINT, GetNumTranslationKeys)(THIS_ UINT Animation) PURE; + STDMETHOD(GetTranslationKeys)(THIS_ UINT Animation, LPD3DXKEY_VECTOR3 pTranslationKeys) PURE; + STDMETHOD(GetTranslationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pTranslationKey) PURE; + STDMETHOD(SetTranslationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pTranslationKey) PURE; + + // Callback keys + STDMETHOD_(UINT, GetNumCallbackKeys)(THIS) PURE; + STDMETHOD(GetCallbackKeys)(THIS_ LPD3DXKEY_CALLBACK pCallbackKeys) PURE; + STDMETHOD(GetCallbackKey)(THIS_ UINT Key, LPD3DXKEY_CALLBACK pCallbackKey) PURE; + STDMETHOD(SetCallbackKey)(THIS_ UINT Key, LPD3DXKEY_CALLBACK pCallbackKey) PURE; + + // Key removal methods. These are slow, and should not be used once the animation starts playing + STDMETHOD(UnregisterScaleKey)(THIS_ UINT Animation, UINT Key) PURE; + STDMETHOD(UnregisterRotationKey)(THIS_ UINT Animation, UINT Key) PURE; + STDMETHOD(UnregisterTranslationKey)(THIS_ UINT Animation, UINT Key) PURE; + + // One-time animaton SRT keyframe registration + STDMETHOD(RegisterAnimationSRTKeys)(THIS_ + LPCSTR pName, // Animation name + UINT NumScaleKeys, // Number of scale keys + UINT NumRotationKeys, // Number of rotation keys + UINT NumTranslationKeys, // Number of translation keys + CONST D3DXKEY_VECTOR3 *pScaleKeys, // Array of scale keys + CONST D3DXKEY_QUATERNION *pRotationKeys, // Array of rotation keys + CONST D3DXKEY_VECTOR3 *pTranslationKeys, // Array of translation keys + DWORD *pAnimationIndex) PURE; // Returns the animation index + + // Compression + STDMETHOD(Compress)(THIS_ + DWORD Flags, // Compression flags (use D3DXCOMPRESS_STRONG for better results) + FLOAT Lossiness, // Compression loss ratio in the [0, 1] range + LPD3DXFRAME pHierarchy, // Frame hierarchy (optional) + LPD3DXBUFFER *ppCompressedData) PURE; // Returns the compressed animation set + + STDMETHOD(UnregisterAnimation)(THIS_ UINT Index) PURE; +}; + + +//---------------------------------------------------------------------------- +// ID3DXCompressedAnimationSet: +// ---------------------------- +// This interface implements a compressed keyframed animation set. +//---------------------------------------------------------------------------- +typedef interface ID3DXCompressedAnimationSet ID3DXCompressedAnimationSet; +typedef interface ID3DXCompressedAnimationSet *LPD3DXCOMPRESSEDANIMATIONSET; + +#undef INTERFACE +#define INTERFACE ID3DXCompressedAnimationSet + +DECLARE_INTERFACE_(ID3DXCompressedAnimationSet, ID3DXAnimationSet) +{ + // ID3DXAnimationSet + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Name + STDMETHOD_(LPCSTR, GetName)(THIS) PURE; + + // Period + STDMETHOD_(DOUBLE, GetPeriod)(THIS) PURE; + STDMETHOD_(DOUBLE, GetPeriodicPosition)(THIS_ DOUBLE Position) PURE; // Maps position into animation period + + // Animation names + STDMETHOD_(UINT, GetNumAnimations)(THIS) PURE; + STDMETHOD(GetAnimationNameByIndex)(THIS_ UINT Index, LPCSTR *ppName) PURE; + STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; + + // SRT + STDMETHOD(GetSRT)(THIS_ + DOUBLE PeriodicPosition, // Position mapped to period (use GetPeriodicPosition) + UINT Animation, // Animation index + D3DXVECTOR3 *pScale, // Returns the scale + D3DXQUATERNION *pRotation, // Returns the rotation as a quaternion + D3DXVECTOR3 *pTranslation) PURE; // Returns the translation + + // Callbacks + STDMETHOD(GetCallback)(THIS_ + DOUBLE Position, // Position from which to find callbacks + DWORD Flags, // Callback search flags + DOUBLE *pCallbackPosition, // Returns the position of the callback + LPVOID *ppCallbackData) PURE; // Returns the callback data pointer + + // Playback + STDMETHOD_(D3DXPLAYBACK_TYPE, GetPlaybackType)(THIS) PURE; + STDMETHOD_(DOUBLE, GetSourceTicksPerSecond)(THIS) PURE; + + // Scale keys + STDMETHOD(GetCompressedData)(THIS_ LPD3DXBUFFER *ppCompressedData) PURE; + + // Callback keys + STDMETHOD_(UINT, GetNumCallbackKeys)(THIS) PURE; + STDMETHOD(GetCallbackKeys)(THIS_ LPD3DXKEY_CALLBACK pCallbackKeys) PURE; +}; + + +//---------------------------------------------------------------------------- +// D3DXPRIORITY_TYPE: +// ------------------ +// This enum defines the type of priority group that a track can be assigned to. +//---------------------------------------------------------------------------- +typedef enum _D3DXPRIORITY_TYPE { + D3DXPRIORITY_LOW = 0, // This track should be blended with all low priority tracks before mixed with the high priority result + D3DXPRIORITY_HIGH = 1, // This track should be blended with all high priority tracks before mixed with the low priority result + + D3DXPRIORITY_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXPRIORITY_TYPE; + +//---------------------------------------------------------------------------- +// D3DXTRACK_DESC: +// --------------- +// This structure describes the mixing information of an animation track. +// The mixing information consists of the current position, speed, and blending +// weight for the track. The Flags field also specifies whether the track is +// low or high priority. Tracks with the same priority are blended together +// and then the two resulting values are blended using the priority blend factor. +// A track also has an animation set (stored separately) associated with it. +//---------------------------------------------------------------------------- +typedef struct _D3DXTRACK_DESC +{ + D3DXPRIORITY_TYPE Priority; + FLOAT Weight; + FLOAT Speed; + DOUBLE Position; + BOOL Enable; +} D3DXTRACK_DESC, *LPD3DXTRACK_DESC; + +//---------------------------------------------------------------------------- +// D3DXEVENT_TYPE: +// --------------- +// This enum defines the type of events keyable via the animation controller. +//---------------------------------------------------------------------------- +typedef enum _D3DXEVENT_TYPE +{ + D3DXEVENT_TRACKSPEED = 0, + D3DXEVENT_TRACKWEIGHT = 1, + D3DXEVENT_TRACKPOSITION = 2, + D3DXEVENT_TRACKENABLE = 3, + D3DXEVENT_PRIORITYBLEND = 4, + + D3DXEVENT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXEVENT_TYPE; + +//---------------------------------------------------------------------------- +// D3DXTRANSITION_TYPE: +// -------------------- +// This enum defines the type of transtion performed on a event that +// transitions from one value to another. +//---------------------------------------------------------------------------- +typedef enum _D3DXTRANSITION_TYPE { + D3DXTRANSITION_LINEAR = 0x000, // Linear transition from one value to the next + D3DXTRANSITION_EASEINEASEOUT = 0x001, // Ease-In Ease-Out spline transtion from one value to the next + + D3DXTRANSITION_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXTRANSITION_TYPE; + +//---------------------------------------------------------------------------- +// D3DXEVENT_DESC: +// --------------- +// This structure describes a animation controller event. +// It gives the event's type, track (if the event is a track event), global +// start time, duration, transition method, and target value. +//---------------------------------------------------------------------------- +typedef struct _D3DXEVENT_DESC +{ + D3DXEVENT_TYPE Type; + UINT Track; + DOUBLE StartTime; + DOUBLE Duration; + D3DXTRANSITION_TYPE Transition; + union + { + FLOAT Weight; + FLOAT Speed; + DOUBLE Position; + BOOL Enable; + }; +} D3DXEVENT_DESC, *LPD3DXEVENT_DESC; + +//---------------------------------------------------------------------------- +// D3DXEVENTHANDLE: +// ---------------- +// Handle values used to efficiently reference animation controller events. +//---------------------------------------------------------------------------- +typedef DWORD D3DXEVENTHANDLE; +typedef D3DXEVENTHANDLE *LPD3DXEVENTHANDLE; + + +//---------------------------------------------------------------------------- +// ID3DXAnimationCallbackHandler: +// ------------------------------ +// This interface is intended to be implemented by the application, and can +// be used to handle callbacks in animation sets generated when +// ID3DXAnimationController::AdvanceTime() is called. +//---------------------------------------------------------------------------- +typedef interface ID3DXAnimationCallbackHandler ID3DXAnimationCallbackHandler; +typedef interface ID3DXAnimationCallbackHandler *LPD3DXANIMATIONCALLBACKHANDLER; + +#undef INTERFACE +#define INTERFACE ID3DXAnimationCallbackHandler + +DECLARE_INTERFACE(ID3DXAnimationCallbackHandler) +{ + //---------------------------------------------------------------------------- + // ID3DXAnimationCallbackHandler::HandleCallback: + // ---------------------------------------------- + // This method gets called when a callback occurs for an animation set in one + // of the tracks during the ID3DXAnimationController::AdvanceTime() call. + // + // Parameters: + // Track + // Index of the track on which the callback occured. + // pCallbackData + // Pointer to user owned callback data. + // + //---------------------------------------------------------------------------- + STDMETHOD(HandleCallback)(THIS_ UINT Track, LPVOID pCallbackData) PURE; +}; + + +//---------------------------------------------------------------------------- +// ID3DXAnimationController: +// ------------------------- +// This interface implements the main animation functionality. It connects +// animation sets with the transform frames that are being animated. Allows +// mixing multiple animations for blended animations or for transistions +// It adds also has methods to modify blending parameters over time to +// enable smooth transistions and other effects. +//---------------------------------------------------------------------------- +typedef interface ID3DXAnimationController ID3DXAnimationController; +typedef interface ID3DXAnimationController *LPD3DXANIMATIONCONTROLLER; + +#undef INTERFACE +#define INTERFACE ID3DXAnimationController + +DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Max sizes + STDMETHOD_(UINT, GetMaxNumAnimationOutputs)(THIS) PURE; + STDMETHOD_(UINT, GetMaxNumAnimationSets)(THIS) PURE; + STDMETHOD_(UINT, GetMaxNumTracks)(THIS) PURE; + STDMETHOD_(UINT, GetMaxNumEvents)(THIS) PURE; + + // Animation output registration + STDMETHOD(RegisterAnimationOutput)(THIS_ + LPCSTR pName, + D3DXMATRIX *pMatrix, + D3DXVECTOR3 *pScale, + D3DXQUATERNION *pRotation, + D3DXVECTOR3 *pTranslation) PURE; + + // Animation set registration + STDMETHOD(RegisterAnimationSet)(THIS_ LPD3DXANIMATIONSET pAnimSet) PURE; + STDMETHOD(UnregisterAnimationSet)(THIS_ LPD3DXANIMATIONSET pAnimSet) PURE; + + STDMETHOD_(UINT, GetNumAnimationSets)(THIS) PURE; + STDMETHOD(GetAnimationSet)(THIS_ UINT Index, LPD3DXANIMATIONSET *ppAnimationSet) PURE; + STDMETHOD(GetAnimationSetByName)(THIS_ LPCSTR szName, LPD3DXANIMATIONSET *ppAnimationSet) PURE; + + // Global time + STDMETHOD(AdvanceTime)(THIS_ DOUBLE TimeDelta, LPD3DXANIMATIONCALLBACKHANDLER pCallbackHandler) PURE; + STDMETHOD(ResetTime)(THIS) PURE; + STDMETHOD_(DOUBLE, GetTime)(THIS) PURE; + + // Tracks + STDMETHOD(SetTrackAnimationSet)(THIS_ UINT Track, LPD3DXANIMATIONSET pAnimSet) PURE; + STDMETHOD(GetTrackAnimationSet)(THIS_ UINT Track, LPD3DXANIMATIONSET *ppAnimSet) PURE; + + STDMETHOD(SetTrackPriority)(THIS_ UINT Track, D3DXPRIORITY_TYPE Priority) PURE; + + STDMETHOD(SetTrackSpeed)(THIS_ UINT Track, FLOAT Speed) PURE; + STDMETHOD(SetTrackWeight)(THIS_ UINT Track, FLOAT Weight) PURE; + STDMETHOD(SetTrackPosition)(THIS_ UINT Track, DOUBLE Position) PURE; + STDMETHOD(SetTrackEnable)(THIS_ UINT Track, BOOL Enable) PURE; + + STDMETHOD(SetTrackDesc)(THIS_ UINT Track, LPD3DXTRACK_DESC pDesc) PURE; + STDMETHOD(GetTrackDesc)(THIS_ UINT Track, LPD3DXTRACK_DESC pDesc) PURE; + + // Priority blending + STDMETHOD(SetPriorityBlend)(THIS_ FLOAT BlendWeight) PURE; + STDMETHOD_(FLOAT, GetPriorityBlend)(THIS) PURE; + + // Event keying + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackSpeed)(THIS_ UINT Track, FLOAT NewSpeed, DOUBLE StartTime, DOUBLE Duration, D3DXTRANSITION_TYPE Transition) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackWeight)(THIS_ UINT Track, FLOAT NewWeight, DOUBLE StartTime, DOUBLE Duration, D3DXTRANSITION_TYPE Transition) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackPosition)(THIS_ UINT Track, DOUBLE NewPosition, DOUBLE StartTime) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackEnable)(THIS_ UINT Track, BOOL NewEnable, DOUBLE StartTime) PURE; + + STDMETHOD_(D3DXEVENTHANDLE, KeyPriorityBlend)(THIS_ FLOAT NewBlendWeight, DOUBLE StartTime, DOUBLE Duration, D3DXTRANSITION_TYPE Transition) PURE; + + // Event unkeying + STDMETHOD(UnkeyEvent)(THIS_ D3DXEVENTHANDLE hEvent) PURE; + + STDMETHOD(UnkeyAllTrackEvents)(THIS_ UINT Track) PURE; + STDMETHOD(UnkeyAllPriorityBlends)(THIS) PURE; + + // Event enumeration + STDMETHOD_(D3DXEVENTHANDLE, GetCurrentTrackEvent)(THIS_ UINT Track, D3DXEVENT_TYPE EventType) PURE; + STDMETHOD_(D3DXEVENTHANDLE, GetCurrentPriorityBlend)(THIS) PURE; + + STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingTrackEvent)(THIS_ UINT Track, D3DXEVENTHANDLE hEvent) PURE; + STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingPriorityBlend)(THIS_ D3DXEVENTHANDLE hEvent) PURE; + + STDMETHOD(ValidateEvent)(THIS_ D3DXEVENTHANDLE hEvent) PURE; + + STDMETHOD(GetEventDesc)(THIS_ D3DXEVENTHANDLE hEvent, LPD3DXEVENT_DESC pDesc) PURE; + + // Cloning + STDMETHOD(CloneAnimationController)(THIS_ + UINT MaxNumAnimationOutputs, + UINT MaxNumAnimationSets, + UINT MaxNumTracks, + UINT MaxNumEvents, + LPD3DXANIMATIONCONTROLLER *ppAnimController) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3DXLoadMeshHierarchyFromX: +// --------------------------- +// Loads the first frame hierarchy in a .X file. +// +// Parameters: +// Filename +// Name of the .X file +// MeshOptions +// Mesh creation options for meshes in the file (see d3dx9mesh.h) +// pD3DDevice +// D3D9 device on which meshes in the file are created in +// pAlloc +// Allocation interface used to allocate nodes of the frame hierarchy +// pUserDataLoader +// Application provided interface to allow loading of user data +// ppFrameHierarchy +// Returns root node pointer of the loaded frame hierarchy +// ppAnimController +// Returns pointer to an animation controller corresponding to animation +// in the .X file. This is created with default max tracks and events +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXLoadMeshHierarchyFromXA + ( + LPCSTR Filename, + DWORD MeshOptions, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXALLOCATEHIERARCHY pAlloc, + LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXFRAME *ppFrameHierarchy, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + +HRESULT WINAPI +D3DXLoadMeshHierarchyFromXW + ( + LPCWSTR Filename, + DWORD MeshOptions, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXALLOCATEHIERARCHY pAlloc, + LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXFRAME *ppFrameHierarchy, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + +#ifdef UNICODE +#define D3DXLoadMeshHierarchyFromX D3DXLoadMeshHierarchyFromXW +#else +#define D3DXLoadMeshHierarchyFromX D3DXLoadMeshHierarchyFromXA +#endif + +HRESULT WINAPI +D3DXLoadMeshHierarchyFromXInMemory + ( + LPCVOID Memory, + DWORD SizeOfMemory, + DWORD MeshOptions, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXALLOCATEHIERARCHY pAlloc, + LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXFRAME *ppFrameHierarchy, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + +//---------------------------------------------------------------------------- +// D3DXSaveMeshHierarchyToFile: +// ---------------------------- +// Creates a .X file and saves the mesh hierarchy and corresponding animations +// in it +// +// Parameters: +// Filename +// Name of the .X file +// XFormat +// Format of the .X file (text or binary, compressed or not, etc) +// pFrameRoot +// Root node of the hierarchy to be saved +// pAnimController +// The animation controller whose animation sets are to be stored +// pUserDataSaver +// Application provided interface to allow adding of user data to +// data objects saved to .X file +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXSaveMeshHierarchyToFileA + ( + LPCSTR Filename, + DWORD XFormat, + CONST D3DXFRAME *pFrameRoot, + LPD3DXANIMATIONCONTROLLER pAnimcontroller, + LPD3DXSAVEUSERDATA pUserDataSaver + ); + +HRESULT WINAPI +D3DXSaveMeshHierarchyToFileW + ( + LPCWSTR Filename, + DWORD XFormat, + CONST D3DXFRAME *pFrameRoot, + LPD3DXANIMATIONCONTROLLER pAnimController, + LPD3DXSAVEUSERDATA pUserDataSaver + ); + +#ifdef UNICODE +#define D3DXSaveMeshHierarchyToFile D3DXSaveMeshHierarchyToFileW +#else +#define D3DXSaveMeshHierarchyToFile D3DXSaveMeshHierarchyToFileA +#endif + +//---------------------------------------------------------------------------- +// D3DXFrameDestroy: +// ----------------- +// Destroys the subtree of frames under the root, including the root +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// pAlloc +// Allocation interface used to de-allocate nodes of the frame hierarchy +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameDestroy + ( + LPD3DXFRAME pFrameRoot, + LPD3DXALLOCATEHIERARCHY pAlloc + ); + +//---------------------------------------------------------------------------- +// D3DXFrameAppendChild: +// --------------------- +// Add a child frame to a frame +// +// Parameters: +// pFrameParent +// Pointer to the parent node +// pFrameChild +// Pointer to the child node +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameAppendChild + ( + LPD3DXFRAME pFrameParent, + CONST D3DXFRAME *pFrameChild + ); + +//---------------------------------------------------------------------------- +// D3DXFrameFind: +// -------------- +// Finds a frame with the given name. Returns NULL if no frame found. +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// Name +// Name of frame to find +// +//---------------------------------------------------------------------------- +LPD3DXFRAME WINAPI +D3DXFrameFind + ( + CONST D3DXFRAME *pFrameRoot, + LPCSTR Name + ); + +//---------------------------------------------------------------------------- +// D3DXFrameRegisterNamedMatrices: +// ------------------------------- +// Finds all frames that have non-null names and registers each of those frame +// matrices to the given animation controller +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// pAnimController +// Pointer to the animation controller where the matrices are registered +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameRegisterNamedMatrices + ( + LPD3DXFRAME pFrameRoot, + LPD3DXANIMATIONCONTROLLER pAnimController + ); + +//---------------------------------------------------------------------------- +// D3DXFrameNumNamedMatrices: +// -------------------------- +// Counts number of frames in a subtree that have non-null names +// +// Parameters: +// pFrameRoot +// Pointer to the root node of the subtree +// Return Value: +// Count of frames +// +//---------------------------------------------------------------------------- +UINT WINAPI +D3DXFrameNumNamedMatrices + ( + CONST D3DXFRAME *pFrameRoot + ); + +//---------------------------------------------------------------------------- +// D3DXFrameCalculateBoundingSphere: +// --------------------------------- +// Computes the bounding sphere of all the meshes in the frame hierarchy. +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// pObjectCenter +// Returns the center of the bounding sphere +// pObjectRadius +// Returns the radius of the bounding sphere +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameCalculateBoundingSphere + ( + CONST D3DXFRAME *pFrameRoot, + LPD3DXVECTOR3 pObjectCenter, + FLOAT *pObjectRadius + ); + + +//---------------------------------------------------------------------------- +// D3DXCreateKeyframedAnimationSet: +// -------------------------------- +// This function creates a compressable keyframed animations set interface. +// +// Parameters: +// pName +// Name of the animation set +// TicksPerSecond +// Number of keyframe ticks that elapse per second +// Playback +// Playback mode of keyframe looping +// NumAnimations +// Number of SRT animations +// NumCallbackKeys +// Number of callback keys +// pCallbackKeys +// Array of callback keys +// ppAnimationSet +// Returns the animation set interface +// +//----------------------------------------------------------------------------- +HRESULT WINAPI +D3DXCreateKeyframedAnimationSet + ( + LPCSTR pName, + DOUBLE TicksPerSecond, + D3DXPLAYBACK_TYPE Playback, + UINT NumAnimations, + UINT NumCallbackKeys, + CONST D3DXKEY_CALLBACK *pCallbackKeys, + LPD3DXKEYFRAMEDANIMATIONSET *ppAnimationSet + ); + + +//---------------------------------------------------------------------------- +// D3DXCreateCompressedAnimationSet: +// -------------------------------- +// This function creates a compressed animations set interface from +// compressed data. +// +// Parameters: +// pName +// Name of the animation set +// TicksPerSecond +// Number of keyframe ticks that elapse per second +// Playback +// Playback mode of keyframe looping +// pCompressedData +// Compressed animation SRT data +// NumCallbackKeys +// Number of callback keys +// pCallbackKeys +// Array of callback keys +// ppAnimationSet +// Returns the animation set interface +// +//----------------------------------------------------------------------------- +HRESULT WINAPI +D3DXCreateCompressedAnimationSet + ( + LPCSTR pName, + DOUBLE TicksPerSecond, + D3DXPLAYBACK_TYPE Playback, + LPD3DXBUFFER pCompressedData, + UINT NumCallbackKeys, + CONST D3DXKEY_CALLBACK *pCallbackKeys, + LPD3DXCOMPRESSEDANIMATIONSET *ppAnimationSet + ); + + +//---------------------------------------------------------------------------- +// D3DXCreateAnimationController: +// ------------------------------ +// This function creates an animation controller object. +// +// Parameters: +// MaxNumMatrices +// Maximum number of matrices that can be animated +// MaxNumAnimationSets +// Maximum number of animation sets that can be played +// MaxNumTracks +// Maximum number of animation sets that can be blended +// MaxNumEvents +// Maximum number of outstanding events that can be scheduled at any given time +// ppAnimController +// Returns the animation controller interface +// +//----------------------------------------------------------------------------- +HRESULT WINAPI +D3DXCreateAnimationController + ( + UINT MaxNumMatrices, + UINT MaxNumAnimationSets, + UINT MaxNumTracks, + UINT MaxNumEvents, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9ANIM_H__ + + diff --git a/dxsdk/Include/d3dx9core.h b/dxsdk/Include/d3dx9core.h new file mode 100644 index 0000000..45243f4 --- /dev/null +++ b/dxsdk/Include/d3dx9core.h @@ -0,0 +1,753 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9core.h +// Content: D3DX core types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9CORE_H__ +#define __D3DX9CORE_H__ + + +/////////////////////////////////////////////////////////////////////////// +// D3DX_SDK_VERSION: +// ----------------- +// This identifier is passed to D3DXCheckVersion in order to ensure that an +// application was built against the correct header files and lib files. +// This number is incremented whenever a header (or other) change would +// require applications to be rebuilt. If the version doesn't match, +// D3DXCheckVersion will return FALSE. (The number itself has no meaning.) +/////////////////////////////////////////////////////////////////////////// + +#define D3DX_VERSION 0x0902 + +#define D3DX_SDK_VERSION 43 + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +BOOL WINAPI + D3DXCheckVersion(UINT D3DSdkVersion, UINT D3DXSdkVersion); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// D3DXDebugMute +// Mutes D3DX and D3D debug spew (TRUE - mute, FALSE - not mute) +// +// returns previous mute value +// +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +BOOL WINAPI + D3DXDebugMute(BOOL Mute); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +/////////////////////////////////////////////////////////////////////////// +// D3DXGetDriverLevel: +// Returns driver version information: +// +// 700 - DX7 level driver +// 800 - DX8 level driver +// 900 - DX9 level driver +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +UINT WINAPI + D3DXGetDriverLevel(LPDIRECT3DDEVICE9 pDevice); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXBuffer: +// ------------ +// The buffer object is used by D3DX to return arbitrary size data. +// +// GetBufferPointer - +// Returns a pointer to the beginning of the buffer. +// +// GetBufferSize - +// Returns the size of the buffer, in bytes. +/////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXBuffer ID3DXBuffer; +typedef interface ID3DXBuffer *LPD3DXBUFFER; + +// {8BA5FB08-5195-40e2-AC58-0D989C3A0102} +DEFINE_GUID(IID_ID3DXBuffer, +0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); + +#undef INTERFACE +#define INTERFACE ID3DXBuffer + +DECLARE_INTERFACE_(ID3DXBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBuffer + STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; + STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; +}; + + + +////////////////////////////////////////////////////////////////////////////// +// D3DXSPRITE flags: +// ----------------- +// D3DXSPRITE_DONOTSAVESTATE +// Specifies device state is not to be saved and restored in Begin/End. +// D3DXSPRITE_DONOTMODIFY_RENDERSTATE +// Specifies device render state is not to be changed in Begin. The device +// is assumed to be in a valid state to draw vertices containing POSITION0, +// TEXCOORD0, and COLOR0 data. +// D3DXSPRITE_OBJECTSPACE +// The WORLD, VIEW, and PROJECTION transforms are NOT modified. The +// transforms currently set to the device are used to transform the sprites +// when the batch is drawn (at Flush or End). If this is not specified, +// WORLD, VIEW, and PROJECTION transforms are modified so that sprites are +// drawn in screenspace coordinates. +// D3DXSPRITE_BILLBOARD +// Rotates each sprite about its center so that it is facing the viewer. +// D3DXSPRITE_ALPHABLEND +// Enables ALPHABLEND(SRCALPHA, INVSRCALPHA) and ALPHATEST(alpha > 0). +// ID3DXFont expects this to be set when drawing text. +// D3DXSPRITE_SORT_TEXTURE +// Sprites are sorted by texture prior to drawing. This is recommended when +// drawing non-overlapping sprites of uniform depth. For example, drawing +// screen-aligned text with ID3DXFont. +// D3DXSPRITE_SORT_DEPTH_FRONTTOBACK +// Sprites are sorted by depth front-to-back prior to drawing. This is +// recommended when drawing opaque sprites of varying depths. +// D3DXSPRITE_SORT_DEPTH_BACKTOFRONT +// Sprites are sorted by depth back-to-front prior to drawing. This is +// recommended when drawing transparent sprites of varying depths. +// D3DXSPRITE_DO_NOT_ADDREF_TEXTURE +// Disables calling AddRef() on every draw, and Release() on Flush() for +// better performance. +////////////////////////////////////////////////////////////////////////////// + +#define D3DXSPRITE_DONOTSAVESTATE (1 << 0) +#define D3DXSPRITE_DONOTMODIFY_RENDERSTATE (1 << 1) +#define D3DXSPRITE_OBJECTSPACE (1 << 2) +#define D3DXSPRITE_BILLBOARD (1 << 3) +#define D3DXSPRITE_ALPHABLEND (1 << 4) +#define D3DXSPRITE_SORT_TEXTURE (1 << 5) +#define D3DXSPRITE_SORT_DEPTH_FRONTTOBACK (1 << 6) +#define D3DXSPRITE_SORT_DEPTH_BACKTOFRONT (1 << 7) +#define D3DXSPRITE_DO_NOT_ADDREF_TEXTURE (1 << 8) + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXSprite: +// ------------ +// This object intends to provide an easy way to drawing sprites using D3D. +// +// Begin - +// Prepares device for drawing sprites. +// +// Draw - +// Draws a sprite. Before transformation, the sprite is the size of +// SrcRect, with its top-left corner specified by Position. The color +// and alpha channels are modulated by Color. +// +// Flush - +// Forces all batched sprites to submitted to the device. +// +// End - +// Restores device state to how it was when Begin was called. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXSprite ID3DXSprite; +typedef interface ID3DXSprite *LPD3DXSPRITE; + + +// {BA0B762D-7D28-43ec-B9DC-2F84443B0614} +DEFINE_GUID(IID_ID3DXSprite, +0xba0b762d, 0x7d28, 0x43ec, 0xb9, 0xdc, 0x2f, 0x84, 0x44, 0x3b, 0x6, 0x14); + + +#undef INTERFACE +#define INTERFACE ID3DXSprite + +DECLARE_INTERFACE_(ID3DXSprite, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXSprite + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + + STDMETHOD(GetTransform)(THIS_ D3DXMATRIX *pTransform) PURE; + STDMETHOD(SetTransform)(THIS_ CONST D3DXMATRIX *pTransform) PURE; + + STDMETHOD(SetWorldViewRH)(THIS_ CONST D3DXMATRIX *pWorld, CONST D3DXMATRIX *pView) PURE; + STDMETHOD(SetWorldViewLH)(THIS_ CONST D3DXMATRIX *pWorld, CONST D3DXMATRIX *pView) PURE; + + STDMETHOD(Begin)(THIS_ DWORD Flags) PURE; + STDMETHOD(Draw)(THIS_ LPDIRECT3DTEXTURE9 pTexture, CONST RECT *pSrcRect, CONST D3DXVECTOR3 *pCenter, CONST D3DXVECTOR3 *pPosition, D3DCOLOR Color) PURE; + STDMETHOD(Flush)(THIS) PURE; + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateSprite( + LPDIRECT3DDEVICE9 pDevice, + LPD3DXSPRITE* ppSprite); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFont: +// ---------- +// Font objects contain the textures and resources needed to render a specific +// font on a specific device. +// +// GetGlyphData - +// Returns glyph cache data, for a given glyph. +// +// PreloadCharacters/PreloadGlyphs/PreloadText - +// Preloads glyphs into the glyph cache textures. +// +// DrawText - +// Draws formatted text on a D3D device. Some parameters are +// surprisingly similar to those of GDI's DrawText function. See GDI +// documentation for a detailed description of these parameters. +// If pSprite is NULL, an internal sprite object will be used. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +////////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXFONT_DESCA +{ + INT Height; + UINT Width; + UINT Weight; + UINT MipLevels; + BOOL Italic; + BYTE CharSet; + BYTE OutputPrecision; + BYTE Quality; + BYTE PitchAndFamily; + CHAR FaceName[LF_FACESIZE]; + +} D3DXFONT_DESCA, *LPD3DXFONT_DESCA; + +typedef struct _D3DXFONT_DESCW +{ + INT Height; + UINT Width; + UINT Weight; + UINT MipLevels; + BOOL Italic; + BYTE CharSet; + BYTE OutputPrecision; + BYTE Quality; + BYTE PitchAndFamily; + WCHAR FaceName[LF_FACESIZE]; + +} D3DXFONT_DESCW, *LPD3DXFONT_DESCW; + +#ifdef UNICODE +typedef D3DXFONT_DESCW D3DXFONT_DESC; +typedef LPD3DXFONT_DESCW LPD3DXFONT_DESC; +#else +typedef D3DXFONT_DESCA D3DXFONT_DESC; +typedef LPD3DXFONT_DESCA LPD3DXFONT_DESC; +#endif + + +typedef interface ID3DXFont ID3DXFont; +typedef interface ID3DXFont *LPD3DXFONT; + + +// {D79DBB70-5F21-4d36-BBC2-FF525C213CDC} +DEFINE_GUID(IID_ID3DXFont, +0xd79dbb70, 0x5f21, 0x4d36, 0xbb, 0xc2, 0xff, 0x52, 0x5c, 0x21, 0x3c, 0xdc); + + +#undef INTERFACE +#define INTERFACE ID3DXFont + +DECLARE_INTERFACE_(ID3DXFont, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXFont + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9 *ppDevice) PURE; + STDMETHOD(GetDescA)(THIS_ D3DXFONT_DESCA *pDesc) PURE; + STDMETHOD(GetDescW)(THIS_ D3DXFONT_DESCW *pDesc) PURE; + STDMETHOD_(BOOL, GetTextMetricsA)(THIS_ TEXTMETRICA *pTextMetrics) PURE; + STDMETHOD_(BOOL, GetTextMetricsW)(THIS_ TEXTMETRICW *pTextMetrics) PURE; + + STDMETHOD_(HDC, GetDC)(THIS) PURE; + STDMETHOD(GetGlyphData)(THIS_ UINT Glyph, LPDIRECT3DTEXTURE9 *ppTexture, RECT *pBlackBox, POINT *pCellInc) PURE; + + STDMETHOD(PreloadCharacters)(THIS_ UINT First, UINT Last) PURE; + STDMETHOD(PreloadGlyphs)(THIS_ UINT First, UINT Last) PURE; + STDMETHOD(PreloadTextA)(THIS_ LPCSTR pString, INT Count) PURE; + STDMETHOD(PreloadTextW)(THIS_ LPCWSTR pString, INT Count) PURE; + + STDMETHOD_(INT, DrawTextA)(THIS_ LPD3DXSPRITE pSprite, LPCSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; + STDMETHOD_(INT, DrawTextW)(THIS_ LPD3DXSPRITE pSprite, LPCWSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; + +#ifdef __cplusplus +#ifdef UNICODE + HRESULT GetDesc(D3DXFONT_DESCW *pDesc) { return GetDescW(pDesc); } + HRESULT PreloadText(LPCWSTR pString, INT Count) { return PreloadTextW(pString, Count); } +#else + HRESULT GetDesc(D3DXFONT_DESCA *pDesc) { return GetDescA(pDesc); } + HRESULT PreloadText(LPCSTR pString, INT Count) { return PreloadTextA(pString, Count); } +#endif +#endif //__cplusplus +}; + +#ifndef GetTextMetrics +#ifdef UNICODE +#define GetTextMetrics GetTextMetricsW +#else +#define GetTextMetrics GetTextMetricsA +#endif +#endif + +#ifndef DrawText +#ifdef UNICODE +#define DrawText DrawTextW +#else +#define DrawText DrawTextA +#endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DXCreateFontA( + LPDIRECT3DDEVICE9 pDevice, + INT Height, + UINT Width, + UINT Weight, + UINT MipLevels, + BOOL Italic, + DWORD CharSet, + DWORD OutputPrecision, + DWORD Quality, + DWORD PitchAndFamily, + LPCSTR pFaceName, + LPD3DXFONT* ppFont); + +HRESULT WINAPI + D3DXCreateFontW( + LPDIRECT3DDEVICE9 pDevice, + INT Height, + UINT Width, + UINT Weight, + UINT MipLevels, + BOOL Italic, + DWORD CharSet, + DWORD OutputPrecision, + DWORD Quality, + DWORD PitchAndFamily, + LPCWSTR pFaceName, + LPD3DXFONT* ppFont); + +#ifdef UNICODE +#define D3DXCreateFont D3DXCreateFontW +#else +#define D3DXCreateFont D3DXCreateFontA +#endif + + +HRESULT WINAPI + D3DXCreateFontIndirectA( + LPDIRECT3DDEVICE9 pDevice, + CONST D3DXFONT_DESCA* pDesc, + LPD3DXFONT* ppFont); + +HRESULT WINAPI + D3DXCreateFontIndirectW( + LPDIRECT3DDEVICE9 pDevice, + CONST D3DXFONT_DESCW* pDesc, + LPD3DXFONT* ppFont); + +#ifdef UNICODE +#define D3DXCreateFontIndirect D3DXCreateFontIndirectW +#else +#define D3DXCreateFontIndirect D3DXCreateFontIndirectA +#endif + + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXRenderToSurface: +// --------------------- +// This object abstracts rendering to surfaces. These surfaces do not +// necessarily need to be render targets. If they are not, a compatible +// render target is used, and the result copied into surface at end scene. +// +// BeginScene, EndScene - +// Call BeginScene() and EndScene() at the beginning and ending of your +// scene. These calls will setup and restore render targets, viewports, +// etc.. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXRTS_DESC +{ + UINT Width; + UINT Height; + D3DFORMAT Format; + BOOL DepthStencil; + D3DFORMAT DepthStencilFormat; + +} D3DXRTS_DESC, *LPD3DXRTS_DESC; + + +typedef interface ID3DXRenderToSurface ID3DXRenderToSurface; +typedef interface ID3DXRenderToSurface *LPD3DXRENDERTOSURFACE; + + +// {6985F346-2C3D-43b3-BE8B-DAAE8A03D894} +DEFINE_GUID(IID_ID3DXRenderToSurface, +0x6985f346, 0x2c3d, 0x43b3, 0xbe, 0x8b, 0xda, 0xae, 0x8a, 0x3, 0xd8, 0x94); + + +#undef INTERFACE +#define INTERFACE ID3DXRenderToSurface + +DECLARE_INTERFACE_(ID3DXRenderToSurface, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXRenderToSurface + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(GetDesc)(THIS_ D3DXRTS_DESC* pDesc) PURE; + + STDMETHOD(BeginScene)(THIS_ LPDIRECT3DSURFACE9 pSurface, CONST D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(EndScene)(THIS_ DWORD MipFilter) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateRenderToSurface( + LPDIRECT3DDEVICE9 pDevice, + UINT Width, + UINT Height, + D3DFORMAT Format, + BOOL DepthStencil, + D3DFORMAT DepthStencilFormat, + LPD3DXRENDERTOSURFACE* ppRenderToSurface); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXRenderToEnvMap: +// -------------------- +// This object abstracts rendering to environment maps. These surfaces +// do not necessarily need to be render targets. If they are not, a +// compatible render target is used, and the result copied into the +// environment map at end scene. +// +// BeginCube, BeginSphere, BeginHemisphere, BeginParabolic - +// This function initiates the rendering of the environment map. As +// parameters, you pass the textures in which will get filled in with +// the resulting environment map. +// +// Face - +// Call this function to initiate the drawing of each face. For each +// environment map, you will call this six times.. once for each face +// in D3DCUBEMAP_FACES. +// +// End - +// This will restore all render targets, and if needed compose all the +// rendered faces into the environment map surfaces. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXRTE_DESC +{ + UINT Size; + UINT MipLevels; + D3DFORMAT Format; + BOOL DepthStencil; + D3DFORMAT DepthStencilFormat; + +} D3DXRTE_DESC, *LPD3DXRTE_DESC; + + +typedef interface ID3DXRenderToEnvMap ID3DXRenderToEnvMap; +typedef interface ID3DXRenderToEnvMap *LPD3DXRenderToEnvMap; + + +// {313F1B4B-C7B0-4fa2-9D9D-8D380B64385E} +DEFINE_GUID(IID_ID3DXRenderToEnvMap, +0x313f1b4b, 0xc7b0, 0x4fa2, 0x9d, 0x9d, 0x8d, 0x38, 0xb, 0x64, 0x38, 0x5e); + + +#undef INTERFACE +#define INTERFACE ID3DXRenderToEnvMap + +DECLARE_INTERFACE_(ID3DXRenderToEnvMap, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXRenderToEnvMap + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(GetDesc)(THIS_ D3DXRTE_DESC* pDesc) PURE; + + STDMETHOD(BeginCube)(THIS_ + LPDIRECT3DCUBETEXTURE9 pCubeTex) PURE; + + STDMETHOD(BeginSphere)(THIS_ + LPDIRECT3DTEXTURE9 pTex) PURE; + + STDMETHOD(BeginHemisphere)(THIS_ + LPDIRECT3DTEXTURE9 pTexZPos, + LPDIRECT3DTEXTURE9 pTexZNeg) PURE; + + STDMETHOD(BeginParabolic)(THIS_ + LPDIRECT3DTEXTURE9 pTexZPos, + LPDIRECT3DTEXTURE9 pTexZNeg) PURE; + + STDMETHOD(Face)(THIS_ D3DCUBEMAP_FACES Face, DWORD MipFilter) PURE; + STDMETHOD(End)(THIS_ DWORD MipFilter) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateRenderToEnvMap( + LPDIRECT3DDEVICE9 pDevice, + UINT Size, + UINT MipLevels, + D3DFORMAT Format, + BOOL DepthStencil, + D3DFORMAT DepthStencilFormat, + LPD3DXRenderToEnvMap* ppRenderToEnvMap); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXLine: +// ------------ +// This object intends to provide an easy way to draw lines using D3D. +// +// Begin - +// Prepares device for drawing lines +// +// Draw - +// Draws a line strip in screen-space. +// Input is in the form of a array defining points on the line strip. of D3DXVECTOR2 +// +// DrawTransform - +// Draws a line in screen-space with a specified input transformation matrix. +// +// End - +// Restores device state to how it was when Begin was called. +// +// SetPattern - +// Applies a stipple pattern to the line. Input is one 32-bit +// DWORD which describes the stipple pattern. 1 is opaque, 0 is +// transparent. +// +// SetPatternScale - +// Stretches the stipple pattern in the u direction. Input is one +// floating-point value. 0.0f is no scaling, whereas 1.0f doubles +// the length of the stipple pattern. +// +// SetWidth - +// Specifies the thickness of the line in the v direction. Input is +// one floating-point value. +// +// SetAntialias - +// Toggles line antialiasing. Input is a BOOL. +// TRUE = Antialiasing on. +// FALSE = Antialiasing off. +// +// SetGLLines - +// Toggles non-antialiased OpenGL line emulation. Input is a BOOL. +// TRUE = OpenGL line emulation on. +// FALSE = OpenGL line emulation off. +// +// OpenGL line: Regular line: +// *\ *\ +// | \ / \ +// | \ *\ \ +// *\ \ \ \ +// \ \ \ \ +// \ * \ * +// \ | \ / +// \| * +// * +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + + +typedef interface ID3DXLine ID3DXLine; +typedef interface ID3DXLine *LPD3DXLINE; + + +// {D379BA7F-9042-4ac4-9F5E-58192A4C6BD8} +DEFINE_GUID(IID_ID3DXLine, +0xd379ba7f, 0x9042, 0x4ac4, 0x9f, 0x5e, 0x58, 0x19, 0x2a, 0x4c, 0x6b, 0xd8); + +#undef INTERFACE +#define INTERFACE ID3DXLine + +DECLARE_INTERFACE_(ID3DXLine, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXLine + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + + STDMETHOD(Begin)(THIS) PURE; + + STDMETHOD(Draw)(THIS_ CONST D3DXVECTOR2 *pVertexList, + DWORD dwVertexListCount, D3DCOLOR Color) PURE; + + STDMETHOD(DrawTransform)(THIS_ CONST D3DXVECTOR3 *pVertexList, + DWORD dwVertexListCount, CONST D3DXMATRIX* pTransform, + D3DCOLOR Color) PURE; + + STDMETHOD(SetPattern)(THIS_ DWORD dwPattern) PURE; + STDMETHOD_(DWORD, GetPattern)(THIS) PURE; + + STDMETHOD(SetPatternScale)(THIS_ FLOAT fPatternScale) PURE; + STDMETHOD_(FLOAT, GetPatternScale)(THIS) PURE; + + STDMETHOD(SetWidth)(THIS_ FLOAT fWidth) PURE; + STDMETHOD_(FLOAT, GetWidth)(THIS) PURE; + + STDMETHOD(SetAntialias)(THIS_ BOOL bAntialias) PURE; + STDMETHOD_(BOOL, GetAntialias)(THIS) PURE; + + STDMETHOD(SetGLLines)(THIS_ BOOL bGLLines) PURE; + STDMETHOD_(BOOL, GetGLLines)(THIS) PURE; + + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DXCreateLine( + LPDIRECT3DDEVICE9 pDevice, + LPD3DXLINE* ppLine); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9CORE_H__ + diff --git a/dxsdk/Include/d3dx9effect.h b/dxsdk/Include/d3dx9effect.h new file mode 100644 index 0000000..a3bcd30 --- /dev/null +++ b/dxsdk/Include/d3dx9effect.h @@ -0,0 +1,873 @@ + +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: d3dx9effect.h +// Content: D3DX effect types and Shaders +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9EFFECT_H__ +#define __D3DX9EFFECT_H__ + + +//---------------------------------------------------------------------------- +// D3DXFX_DONOTSAVESTATE +// This flag is used as a parameter to ID3DXEffect::Begin(). When this flag +// is specified, device state is not saved or restored in Begin/End. +// D3DXFX_DONOTSAVESHADERSTATE +// This flag is used as a parameter to ID3DXEffect::Begin(). When this flag +// is specified, shader device state is not saved or restored in Begin/End. +// This includes pixel/vertex shaders and shader constants +// D3DXFX_DONOTSAVESAMPLERSTATE +// This flag is used as a parameter to ID3DXEffect::Begin(). When this flag +// is specified, sampler device state is not saved or restored in Begin/End. +// D3DXFX_NOT_CLONEABLE +// This flag is used as a parameter to the D3DXCreateEffect family of APIs. +// When this flag is specified, the effect will be non-cloneable and will not +// contain any shader binary data. +// Furthermore, GetPassDesc will not return shader function pointers. +// Setting this flag reduces effect memory usage by about 50%. +//---------------------------------------------------------------------------- + +#define D3DXFX_DONOTSAVESTATE (1 << 0) +#define D3DXFX_DONOTSAVESHADERSTATE (1 << 1) +#define D3DXFX_DONOTSAVESAMPLERSTATE (1 << 2) + +#define D3DXFX_NOT_CLONEABLE (1 << 11) +#define D3DXFX_LARGEADDRESSAWARE (1 << 17) + +//---------------------------------------------------------------------------- +// D3DX_PARAMETER_SHARED +// Indicates that the value of a parameter will be shared with all effects +// which share the same namespace. Changing the value in one effect will +// change it in all. +// +// D3DX_PARAMETER_LITERAL +// Indicates that the value of this parameter can be treated as literal. +// Literal parameters can be marked when the effect is compiled, and their +// cannot be changed after the effect is compiled. Shared parameters cannot +// be literal. +//---------------------------------------------------------------------------- + +#define D3DX_PARAMETER_SHARED (1 << 0) +#define D3DX_PARAMETER_LITERAL (1 << 1) +#define D3DX_PARAMETER_ANNOTATION (1 << 2) + +//---------------------------------------------------------------------------- +// D3DXEFFECT_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXEFFECT_DESC +{ + LPCSTR Creator; // Creator string + UINT Parameters; // Number of parameters + UINT Techniques; // Number of techniques + UINT Functions; // Number of function entrypoints + +} D3DXEFFECT_DESC; + + +//---------------------------------------------------------------------------- +// D3DXPARAMETER_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXPARAMETER_DESC +{ + LPCSTR Name; // Parameter name + LPCSTR Semantic; // Parameter semantic + D3DXPARAMETER_CLASS Class; // Class + D3DXPARAMETER_TYPE Type; // Component type + UINT Rows; // Number of rows + UINT Columns; // Number of columns + UINT Elements; // Number of array elements + UINT Annotations; // Number of annotations + UINT StructMembers; // Number of structure member sub-parameters + DWORD Flags; // D3DX_PARAMETER_* flags + UINT Bytes; // Parameter size, in bytes + +} D3DXPARAMETER_DESC; + + +//---------------------------------------------------------------------------- +// D3DXTECHNIQUE_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXTECHNIQUE_DESC +{ + LPCSTR Name; // Technique name + UINT Passes; // Number of passes + UINT Annotations; // Number of annotations + +} D3DXTECHNIQUE_DESC; + + +//---------------------------------------------------------------------------- +// D3DXPASS_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXPASS_DESC +{ + LPCSTR Name; // Pass name + UINT Annotations; // Number of annotations + + CONST DWORD *pVertexShaderFunction; // Vertex shader function + CONST DWORD *pPixelShaderFunction; // Pixel shader function + +} D3DXPASS_DESC; + + +//---------------------------------------------------------------------------- +// D3DXFUNCTION_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXFUNCTION_DESC +{ + LPCSTR Name; // Function name + UINT Annotations; // Number of annotations + +} D3DXFUNCTION_DESC; + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXEffectPool /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXEffectPool ID3DXEffectPool; +typedef interface ID3DXEffectPool *LPD3DXEFFECTPOOL; + +// {9537AB04-3250-412e-8213-FCD2F8677933} +DEFINE_GUID(IID_ID3DXEffectPool, +0x9537ab04, 0x3250, 0x412e, 0x82, 0x13, 0xfc, 0xd2, 0xf8, 0x67, 0x79, 0x33); + + +#undef INTERFACE +#define INTERFACE ID3DXEffectPool + +DECLARE_INTERFACE_(ID3DXEffectPool, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // No public methods +}; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXBaseEffect /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXBaseEffect ID3DXBaseEffect; +typedef interface ID3DXBaseEffect *LPD3DXBASEEFFECT; + +// {017C18AC-103F-4417-8C51-6BF6EF1E56BE} +DEFINE_GUID(IID_ID3DXBaseEffect, +0x17c18ac, 0x103f, 0x4417, 0x8c, 0x51, 0x6b, 0xf6, 0xef, 0x1e, 0x56, 0xbe); + + +#undef INTERFACE +#define INTERFACE ID3DXBaseEffect + +DECLARE_INTERFACE_(ID3DXBaseEffect, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; + STDMETHOD(GetParameterDesc)(THIS_ D3DXHANDLE hParameter, D3DXPARAMETER_DESC* pDesc) PURE; + STDMETHOD(GetTechniqueDesc)(THIS_ D3DXHANDLE hTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(GetPassDesc)(THIS_ D3DXHANDLE hPass, D3DXPASS_DESC* pDesc) PURE; + STDMETHOD(GetFunctionDesc)(THIS_ D3DXHANDLE hShader, D3DXFUNCTION_DESC* pDesc) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetParameter)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterByName)(THIS_ D3DXHANDLE hParameter, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterBySemantic)(THIS_ D3DXHANDLE hParameter, LPCSTR pSemantic) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterElement)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechnique)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechniqueByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetPass)(THIS_ D3DXHANDLE hTechnique, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetPassByName)(THIS_ D3DXHANDLE hTechnique, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetFunction)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetFunctionByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotation)(THIS_ D3DXHANDLE hObject, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotationByName)(THIS_ D3DXHANDLE hObject, LPCSTR pName) PURE; + + // Get/Set Parameters + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(GetValue)(THIS_ D3DXHANDLE hParameter, LPVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hParameter, BOOL b) PURE; + STDMETHOD(GetBool)(THIS_ D3DXHANDLE hParameter, BOOL* pb) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hParameter, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(GetBoolArray)(THIS_ D3DXHANDLE hParameter, BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hParameter, INT n) PURE; + STDMETHOD(GetInt)(THIS_ D3DXHANDLE hParameter, INT* pn) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hParameter, CONST INT* pn, UINT Count) PURE; + STDMETHOD(GetIntArray)(THIS_ D3DXHANDLE hParameter, INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT f) PURE; + STDMETHOD(GetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT* pf) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hParameter, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(GetFloatArray)(THIS_ D3DXHANDLE hParameter, FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(GetVector)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(GetVectorArray)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrix)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetString)(THIS_ D3DXHANDLE hParameter, LPCSTR pString) PURE; + STDMETHOD(GetString)(THIS_ D3DXHANDLE hParameter, LPCSTR* ppString) PURE; + STDMETHOD(SetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(GetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 *ppTexture) PURE; + STDMETHOD(GetPixelShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DPIXELSHADER9 *ppPShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9 *ppVShader) PURE; + + //Set Range of an Array to pass to device + //Useful for sending only a subrange of an array down to the device + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + +}; + + +//---------------------------------------------------------------------------- +// ID3DXEffectStateManager: +// ------------------------ +// This is a user implemented interface that can be used to manage device +// state changes made by an Effect. +//---------------------------------------------------------------------------- + +typedef interface ID3DXEffectStateManager ID3DXEffectStateManager; +typedef interface ID3DXEffectStateManager *LPD3DXEFFECTSTATEMANAGER; + +// {79AAB587-6DBC-4fa7-82DE-37FA1781C5CE} +DEFINE_GUID(IID_ID3DXEffectStateManager, +0x79aab587, 0x6dbc, 0x4fa7, 0x82, 0xde, 0x37, 0xfa, 0x17, 0x81, 0xc5, 0xce); + +#undef INTERFACE +#define INTERFACE ID3DXEffectStateManager + +DECLARE_INTERFACE_(ID3DXEffectStateManager, IUnknown) +{ + // The user must correctly implement QueryInterface, AddRef, and Release. + + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // The following methods are called by the Effect when it wants to make + // the corresponding device call. Note that: + // 1. Users manage the state and are therefore responsible for making the + // the corresponding device calls themselves inside their callbacks. + // 2. Effects pay attention to the return values of the callbacks, and so + // users must pay attention to what they return in their callbacks. + + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix) PURE; + STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL9 *pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index, CONST D3DLIGHT9 *pLight) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index, BOOL Enable) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD Value) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) PURE; + STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) PURE; + STDMETHOD(SetNPatchMode)(THIS_ FLOAT NumSegments) PURE; + STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE; + STDMETHOD(SetVertexShader)(THIS_ LPDIRECT3DVERTEXSHADER9 pShader) PURE; + STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetPixelShader)(THIS_ LPDIRECT3DPIXELSHADER9 pShader) PURE; + STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXEffect /////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXEffect ID3DXEffect; +typedef interface ID3DXEffect *LPD3DXEFFECT; + +// {F6CEB4B3-4E4C-40dd-B883-8D8DE5EA0CD5} +DEFINE_GUID(IID_ID3DXEffect, +0xf6ceb4b3, 0x4e4c, 0x40dd, 0xb8, 0x83, 0x8d, 0x8d, 0xe5, 0xea, 0xc, 0xd5); + +#undef INTERFACE +#define INTERFACE ID3DXEffect + +DECLARE_INTERFACE_(ID3DXEffect, ID3DXBaseEffect) +{ + // ID3DXBaseEffect + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; + STDMETHOD(GetParameterDesc)(THIS_ D3DXHANDLE hParameter, D3DXPARAMETER_DESC* pDesc) PURE; + STDMETHOD(GetTechniqueDesc)(THIS_ D3DXHANDLE hTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(GetPassDesc)(THIS_ D3DXHANDLE hPass, D3DXPASS_DESC* pDesc) PURE; + STDMETHOD(GetFunctionDesc)(THIS_ D3DXHANDLE hShader, D3DXFUNCTION_DESC* pDesc) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetParameter)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterByName)(THIS_ D3DXHANDLE hParameter, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterBySemantic)(THIS_ D3DXHANDLE hParameter, LPCSTR pSemantic) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterElement)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechnique)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechniqueByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetPass)(THIS_ D3DXHANDLE hTechnique, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetPassByName)(THIS_ D3DXHANDLE hTechnique, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetFunction)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetFunctionByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotation)(THIS_ D3DXHANDLE hObject, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotationByName)(THIS_ D3DXHANDLE hObject, LPCSTR pName) PURE; + + // Get/Set Parameters + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(GetValue)(THIS_ D3DXHANDLE hParameter, LPVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hParameter, BOOL b) PURE; + STDMETHOD(GetBool)(THIS_ D3DXHANDLE hParameter, BOOL* pb) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hParameter, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(GetBoolArray)(THIS_ D3DXHANDLE hParameter, BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hParameter, INT n) PURE; + STDMETHOD(GetInt)(THIS_ D3DXHANDLE hParameter, INT* pn) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hParameter, CONST INT* pn, UINT Count) PURE; + STDMETHOD(GetIntArray)(THIS_ D3DXHANDLE hParameter, INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT f) PURE; + STDMETHOD(GetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT* pf) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hParameter, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(GetFloatArray)(THIS_ D3DXHANDLE hParameter, FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(GetVector)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(GetVectorArray)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrix)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetString)(THIS_ D3DXHANDLE hParameter, LPCSTR pString) PURE; + STDMETHOD(GetString)(THIS_ D3DXHANDLE hParameter, LPCSTR* ppString) PURE; + STDMETHOD(SetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(GetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 *ppTexture) PURE; + STDMETHOD(GetPixelShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DPIXELSHADER9 *ppPShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9 *ppVShader) PURE; + + //Set Range of an Array to pass to device + //Usefull for sending only a subrange of an array down to the device + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + // ID3DXBaseEffect + + + // Pool + STDMETHOD(GetPool)(THIS_ LPD3DXEFFECTPOOL* ppPool) PURE; + + // Selecting and setting a technique + STDMETHOD(SetTechnique)(THIS_ D3DXHANDLE hTechnique) PURE; + STDMETHOD_(D3DXHANDLE, GetCurrentTechnique)(THIS) PURE; + STDMETHOD(ValidateTechnique)(THIS_ D3DXHANDLE hTechnique) PURE; + STDMETHOD(FindNextValidTechnique)(THIS_ D3DXHANDLE hTechnique, D3DXHANDLE *pTechnique) PURE; + STDMETHOD_(BOOL, IsParameterUsed)(THIS_ D3DXHANDLE hParameter, D3DXHANDLE hTechnique) PURE; + + // Using current technique + // Begin starts active technique + // BeginPass begins a pass + // CommitChanges updates changes to any set calls in the pass. This should be called before + // any DrawPrimitive call to d3d + // EndPass ends a pass + // End ends active technique + STDMETHOD(Begin)(THIS_ UINT *pPasses, DWORD Flags) PURE; + STDMETHOD(BeginPass)(THIS_ UINT Pass) PURE; + STDMETHOD(CommitChanges)(THIS) PURE; + STDMETHOD(EndPass)(THIS) PURE; + STDMETHOD(End)(THIS) PURE; + + // Managing D3D Device + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; + + // Logging device calls + STDMETHOD(SetStateManager)(THIS_ LPD3DXEFFECTSTATEMANAGER pManager) PURE; + STDMETHOD(GetStateManager)(THIS_ LPD3DXEFFECTSTATEMANAGER *ppManager) PURE; + + // Parameter blocks + STDMETHOD(BeginParameterBlock)(THIS) PURE; + STDMETHOD_(D3DXHANDLE, EndParameterBlock)(THIS) PURE; + STDMETHOD(ApplyParameterBlock)(THIS_ D3DXHANDLE hParameterBlock) PURE; + STDMETHOD(DeleteParameterBlock)(THIS_ D3DXHANDLE hParameterBlock) PURE; + + // Cloning + STDMETHOD(CloneEffect)(THIS_ LPDIRECT3DDEVICE9 pDevice, LPD3DXEFFECT* ppEffect) PURE; + + // Fast path for setting variables directly in ID3DXEffect + STDMETHOD(SetRawValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT ByteOffset, UINT Bytes) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXEffectCompiler /////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXEffectCompiler ID3DXEffectCompiler; +typedef interface ID3DXEffectCompiler *LPD3DXEFFECTCOMPILER; + +// {51B8A949-1A31-47e6-BEA0-4B30DB53F1E0} +DEFINE_GUID(IID_ID3DXEffectCompiler, +0x51b8a949, 0x1a31, 0x47e6, 0xbe, 0xa0, 0x4b, 0x30, 0xdb, 0x53, 0xf1, 0xe0); + + +#undef INTERFACE +#define INTERFACE ID3DXEffectCompiler + +DECLARE_INTERFACE_(ID3DXEffectCompiler, ID3DXBaseEffect) +{ + // ID3DXBaseEffect + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; + STDMETHOD(GetParameterDesc)(THIS_ D3DXHANDLE hParameter, D3DXPARAMETER_DESC* pDesc) PURE; + STDMETHOD(GetTechniqueDesc)(THIS_ D3DXHANDLE hTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(GetPassDesc)(THIS_ D3DXHANDLE hPass, D3DXPASS_DESC* pDesc) PURE; + STDMETHOD(GetFunctionDesc)(THIS_ D3DXHANDLE hShader, D3DXFUNCTION_DESC* pDesc) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetParameter)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterByName)(THIS_ D3DXHANDLE hParameter, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterBySemantic)(THIS_ D3DXHANDLE hParameter, LPCSTR pSemantic) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterElement)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechnique)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechniqueByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetPass)(THIS_ D3DXHANDLE hTechnique, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetPassByName)(THIS_ D3DXHANDLE hTechnique, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetFunction)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetFunctionByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotation)(THIS_ D3DXHANDLE hObject, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotationByName)(THIS_ D3DXHANDLE hObject, LPCSTR pName) PURE; + + // Get/Set Parameters + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(GetValue)(THIS_ D3DXHANDLE hParameter, LPVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hParameter, BOOL b) PURE; + STDMETHOD(GetBool)(THIS_ D3DXHANDLE hParameter, BOOL* pb) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hParameter, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(GetBoolArray)(THIS_ D3DXHANDLE hParameter, BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hParameter, INT n) PURE; + STDMETHOD(GetInt)(THIS_ D3DXHANDLE hParameter, INT* pn) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hParameter, CONST INT* pn, UINT Count) PURE; + STDMETHOD(GetIntArray)(THIS_ D3DXHANDLE hParameter, INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT f) PURE; + STDMETHOD(GetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT* pf) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hParameter, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(GetFloatArray)(THIS_ D3DXHANDLE hParameter, FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(GetVector)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(GetVectorArray)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrix)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetString)(THIS_ D3DXHANDLE hParameter, LPCSTR pString) PURE; + STDMETHOD(GetString)(THIS_ D3DXHANDLE hParameter, LPCSTR* ppString) PURE; + STDMETHOD(SetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(GetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 *ppTexture) PURE; + STDMETHOD(GetPixelShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DPIXELSHADER9 *ppPShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9 *ppVShader) PURE; + + //Set Range of an Array to pass to device + //Usefull for sending only a subrange of an array down to the device + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + // ID3DXBaseEffect + + // Parameter sharing, specialization, and information + STDMETHOD(SetLiteral)(THIS_ D3DXHANDLE hParameter, BOOL Literal) PURE; + STDMETHOD(GetLiteral)(THIS_ D3DXHANDLE hParameter, BOOL *pLiteral) PURE; + + // Compilation + STDMETHOD(CompileEffect)(THIS_ DWORD Flags, + LPD3DXBUFFER* ppEffect, LPD3DXBUFFER* ppErrorMsgs) PURE; + + STDMETHOD(CompileShader)(THIS_ D3DXHANDLE hFunction, LPCSTR pTarget, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//---------------------------------------------------------------------------- +// D3DXCreateEffectPool: +// --------------------- +// Creates an effect pool. Pools are used for sharing parameters between +// multiple effects. For all effects within a pool, shared parameters of the +// same name all share the same value. +// +// Parameters: +// ppPool +// Returns the created pool. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateEffectPool( + LPD3DXEFFECTPOOL* ppPool); + + +//---------------------------------------------------------------------------- +// D3DXCreateEffect: +// ----------------- +// Creates an effect from an ascii or binary effect description. +// +// Parameters: +// pDevice +// Pointer of the device on which to create the effect +// pSrcFile +// Name of the file containing the effect description +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to effect description +// SrcDataSize +// Size of the effect description in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// Flags +// See D3DXSHADER_xxx flags. +// pSkipConstants +// A list of semi-colon delimited variable names. The effect will +// not set these variables to the device when they are referenced +// by a shader. NOTE: the variables specified here must be +// register bound in the file and must not be used in expressions +// in passes or samplers or the file will not load. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pPool +// Pointer to ID3DXEffectPool object to use for shared parameters. +// If NULL, no parameters will be shared. +// ppEffect +// Returns a buffer containing created effect. +// ppCompilationErrors +// Returns a buffer containing any error messages which occurred during +// compile. Or NULL if you do not care about the error messages. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateEffectFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileW +#else +#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateEffectFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceW +#else +#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateEffect( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +// +// Ex functions that accept pSkipConstants in addition to other parameters +// + +HRESULT WINAPI + D3DXCreateEffectFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromFileEx D3DXCreateEffectFromFileExW +#else +#define D3DXCreateEffectFromFileEx D3DXCreateEffectFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateEffectFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromResourceEx D3DXCreateEffectFromResourceExW +#else +#define D3DXCreateEffectFromResourceEx D3DXCreateEffectFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateEffectEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +//---------------------------------------------------------------------------- +// D3DXCreateEffectCompiler: +// ------------------------- +// Creates an effect from an ascii or binary effect description. +// +// Parameters: +// pSrcFile +// Name of the file containing the effect description +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to effect description +// SrcDataSize +// Size of the effect description in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pPool +// Pointer to ID3DXEffectPool object to use for shared parameters. +// If NULL, no parameters will be shared. +// ppCompiler +// Returns a buffer containing created effect compiler. +// ppParseErrors +// Returns a buffer containing any error messages which occurred during +// parse. Or NULL if you do not care about the error messages. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateEffectCompilerFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +HRESULT WINAPI + D3DXCreateEffectCompilerFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +#ifdef UNICODE +#define D3DXCreateEffectCompilerFromFile D3DXCreateEffectCompilerFromFileW +#else +#define D3DXCreateEffectCompilerFromFile D3DXCreateEffectCompilerFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateEffectCompilerFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +HRESULT WINAPI + D3DXCreateEffectCompilerFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +#ifdef UNICODE +#define D3DXCreateEffectCompilerFromResource D3DXCreateEffectCompilerFromResourceW +#else +#define D3DXCreateEffectCompilerFromResource D3DXCreateEffectCompilerFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateEffectCompiler( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +//---------------------------------------------------------------------------- +// D3DXDisassembleEffect: +// ----------------------- +// +// Parameters: +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXDisassembleEffect( + LPD3DXEFFECT pEffect, + BOOL EnableColorCode, + LPD3DXBUFFER *ppDisassembly); + + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9EFFECT_H__ + + diff --git a/dxsdk/Include/d3dx9math.h b/dxsdk/Include/d3dx9math.h new file mode 100644 index 0000000..3fda053 --- /dev/null +++ b/dxsdk/Include/d3dx9math.h @@ -0,0 +1,1796 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9math.h +// Content: D3DX math types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9MATH_H__ +#define __D3DX9MATH_H__ + +#include +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4201) // anonymous unions warning + + + +//=========================================================================== +// +// General purpose utilities +// +//=========================================================================== +#define D3DX_PI ((FLOAT) 3.141592654f) +#define D3DX_1BYPI ((FLOAT) 0.318309886f) + +#define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f)) +#define D3DXToDegree( radian ) ((radian) * (180.0f / D3DX_PI)) + + + +//=========================================================================== +// +// 16 bit floating point numbers +// +//=========================================================================== + +#define D3DX_16F_DIG 3 // # of decimal digits of precision +#define D3DX_16F_EPSILON 4.8875809e-4f // smallest such that 1.0 + epsilon != 1.0 +#define D3DX_16F_MANT_DIG 11 // # of bits in mantissa +#define D3DX_16F_MAX 6.550400e+004 // max value +#define D3DX_16F_MAX_10_EXP 4 // max decimal exponent +#define D3DX_16F_MAX_EXP 15 // max binary exponent +#define D3DX_16F_MIN 6.1035156e-5f // min positive value +#define D3DX_16F_MIN_10_EXP (-4) // min decimal exponent +#define D3DX_16F_MIN_EXP (-14) // min binary exponent +#define D3DX_16F_RADIX 2 // exponent radix +#define D3DX_16F_ROUNDS 1 // addition rounding: near + + +typedef struct D3DXFLOAT16 +{ +#ifdef __cplusplus +public: + D3DXFLOAT16() {}; + D3DXFLOAT16( FLOAT ); + D3DXFLOAT16( CONST D3DXFLOAT16& ); + + // casting + operator FLOAT (); + + // binary operators + BOOL operator == ( CONST D3DXFLOAT16& ) const; + BOOL operator != ( CONST D3DXFLOAT16& ) const; + +protected: +#endif //__cplusplus + WORD value; +} D3DXFLOAT16, *LPD3DXFLOAT16; + + + +//=========================================================================== +// +// Vectors +// +//=========================================================================== + + +//-------------------------- +// 2D Vector +//-------------------------- +typedef struct D3DXVECTOR2 +{ +#ifdef __cplusplus +public: + D3DXVECTOR2() {}; + D3DXVECTOR2( CONST FLOAT * ); + D3DXVECTOR2( CONST D3DXFLOAT16 * ); + D3DXVECTOR2( FLOAT x, FLOAT y ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR2& operator += ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator -= ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator *= ( FLOAT ); + D3DXVECTOR2& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR2 operator + () const; + D3DXVECTOR2 operator - () const; + + // binary operators + D3DXVECTOR2 operator + ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator - ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator * ( FLOAT ) const; + D3DXVECTOR2 operator / ( FLOAT ) const; + + friend D3DXVECTOR2 operator * ( FLOAT, CONST D3DXVECTOR2& ); + + BOOL operator == ( CONST D3DXVECTOR2& ) const; + BOOL operator != ( CONST D3DXVECTOR2& ) const; + + +public: +#endif //__cplusplus + FLOAT x, y; +} D3DXVECTOR2, *LPD3DXVECTOR2; + + + +//-------------------------- +// 2D Vector (16 bit) +//-------------------------- + +typedef struct D3DXVECTOR2_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR2_16F() {}; + D3DXVECTOR2_16F( CONST FLOAT * ); + D3DXVECTOR2_16F( CONST D3DXFLOAT16 * ); + D3DXVECTOR2_16F( CONST D3DXFLOAT16 &x, CONST D3DXFLOAT16 &y ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR2_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR2_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y; + +} D3DXVECTOR2_16F, *LPD3DXVECTOR2_16F; + + + +//-------------------------- +// 3D Vector +//-------------------------- +#ifdef __cplusplus +typedef struct D3DXVECTOR3 : public D3DVECTOR +{ +public: + D3DXVECTOR3() {}; + D3DXVECTOR3( CONST FLOAT * ); + D3DXVECTOR3( CONST D3DVECTOR& ); + D3DXVECTOR3( CONST D3DXFLOAT16 * ); + D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator *= ( FLOAT ); + D3DXVECTOR3& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR3 operator + () const; + D3DXVECTOR3 operator - () const; + + // binary operators + D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator * ( FLOAT ) const; + D3DXVECTOR3 operator / ( FLOAT ) const; + + friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& ); + + BOOL operator == ( CONST D3DXVECTOR3& ) const; + BOOL operator != ( CONST D3DXVECTOR3& ) const; + +} D3DXVECTOR3, *LPD3DXVECTOR3; + +#else //!__cplusplus +typedef struct _D3DVECTOR D3DXVECTOR3, *LPD3DXVECTOR3; +#endif //!__cplusplus + + + +//-------------------------- +// 3D Vector (16 bit) +//-------------------------- +typedef struct D3DXVECTOR3_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR3_16F() {}; + D3DXVECTOR3_16F( CONST FLOAT * ); + D3DXVECTOR3_16F( CONST D3DVECTOR& ); + D3DXVECTOR3_16F( CONST D3DXFLOAT16 * ); + D3DXVECTOR3_16F( CONST D3DXFLOAT16 &x, CONST D3DXFLOAT16 &y, CONST D3DXFLOAT16 &z ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR3_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR3_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y, z; + +} D3DXVECTOR3_16F, *LPD3DXVECTOR3_16F; + + + +//-------------------------- +// 4D Vector +//-------------------------- +typedef struct D3DXVECTOR4 +{ +#ifdef __cplusplus +public: + D3DXVECTOR4() {}; + D3DXVECTOR4( CONST FLOAT* ); + D3DXVECTOR4( CONST D3DXFLOAT16* ); + D3DXVECTOR4( CONST D3DVECTOR& xyz, FLOAT w ); + D3DXVECTOR4( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR4& operator += ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator -= ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator *= ( FLOAT ); + D3DXVECTOR4& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR4 operator + () const; + D3DXVECTOR4 operator - () const; + + // binary operators + D3DXVECTOR4 operator + ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator - ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator * ( FLOAT ) const; + D3DXVECTOR4 operator / ( FLOAT ) const; + + friend D3DXVECTOR4 operator * ( FLOAT, CONST D3DXVECTOR4& ); + + BOOL operator == ( CONST D3DXVECTOR4& ) const; + BOOL operator != ( CONST D3DXVECTOR4& ) const; + +public: +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXVECTOR4, *LPD3DXVECTOR4; + + +//-------------------------- +// 4D Vector (16 bit) +//-------------------------- +typedef struct D3DXVECTOR4_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR4_16F() {}; + D3DXVECTOR4_16F( CONST FLOAT * ); + D3DXVECTOR4_16F( CONST D3DXFLOAT16* ); + D3DXVECTOR4_16F( CONST D3DXVECTOR3_16F& xyz, CONST D3DXFLOAT16& w ); + D3DXVECTOR4_16F( CONST D3DXFLOAT16& x, CONST D3DXFLOAT16& y, CONST D3DXFLOAT16& z, CONST D3DXFLOAT16& w ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR4_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR4_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y, z, w; + +} D3DXVECTOR4_16F, *LPD3DXVECTOR4_16F; + + + +//=========================================================================== +// +// Matrices +// +//=========================================================================== +#ifdef __cplusplus +typedef struct D3DXMATRIX : public D3DMATRIX +{ +public: + D3DXMATRIX() {}; + D3DXMATRIX( CONST FLOAT * ); + D3DXMATRIX( CONST D3DMATRIX& ); + D3DXMATRIX( CONST D3DXFLOAT16 * ); + D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); + + + // access grants + FLOAT& operator () ( UINT Row, UINT Col ); + FLOAT operator () ( UINT Row, UINT Col ) const; + + // casting operators + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXMATRIX& operator *= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator += ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator -= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator *= ( FLOAT ); + D3DXMATRIX& operator /= ( FLOAT ); + + // unary operators + D3DXMATRIX operator + () const; + D3DXMATRIX operator - () const; + + // binary operators + D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator * ( FLOAT ) const; + D3DXMATRIX operator / ( FLOAT ) const; + + friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& ); + + BOOL operator == ( CONST D3DXMATRIX& ) const; + BOOL operator != ( CONST D3DXMATRIX& ) const; + +} D3DXMATRIX, *LPD3DXMATRIX; + +#else //!__cplusplus +typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX; +#endif //!__cplusplus + + +//--------------------------------------------------------------------------- +// Aligned Matrices +// +// This class helps keep matrices 16-byte aligned as preferred by P4 cpus. +// It aligns matrices on the stack and on the heap or in global scope. +// It does this using __declspec(align(16)) which works on VC7 and on VC 6 +// with the processor pack. Unfortunately there is no way to detect the +// latter so this is turned on only on VC7. On other compilers this is the +// the same as D3DXMATRIX. +// +// Using this class on a compiler that does not actually do the alignment +// can be dangerous since it will not expose bugs that ignore alignment. +// E.g if an object of this class in inside a struct or class, and some code +// memcopys data in it assuming tight packing. This could break on a compiler +// that eventually start aligning the matrix. +//--------------------------------------------------------------------------- +#ifdef __cplusplus +typedef struct _D3DXMATRIXA16 : public D3DXMATRIX +{ + _D3DXMATRIXA16() {} + _D3DXMATRIXA16( CONST FLOAT * ); + _D3DXMATRIXA16( CONST D3DMATRIX& ); + _D3DXMATRIXA16( CONST D3DXFLOAT16 * ); + _D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); + + // new operators + void* operator new ( size_t ); + void* operator new[] ( size_t ); + + // delete operators + void operator delete ( void* ); // These are NOT virtual; Do not + void operator delete[] ( void* ); // cast to D3DXMATRIX and delete. + + // assignment operators + _D3DXMATRIXA16& operator = ( CONST D3DXMATRIX& ); + +} _D3DXMATRIXA16; + +#else //!__cplusplus +typedef D3DXMATRIX _D3DXMATRIXA16; +#endif //!__cplusplus + + + +#if _MSC_VER >= 1300 // VC7 +#define D3DX_ALIGN16 __declspec(align(16)) +#else +#define D3DX_ALIGN16 // Earlier compiler may not understand this, do nothing. +#endif + +typedef D3DX_ALIGN16 _D3DXMATRIXA16 D3DXMATRIXA16, *LPD3DXMATRIXA16; + + + +//=========================================================================== +// +// Quaternions +// +//=========================================================================== +typedef struct D3DXQUATERNION +{ +#ifdef __cplusplus +public: + D3DXQUATERNION() {} + D3DXQUATERNION( CONST FLOAT * ); + D3DXQUATERNION( CONST D3DXFLOAT16 * ); + D3DXQUATERNION( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXQUATERNION& operator += ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator -= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( FLOAT ); + D3DXQUATERNION& operator /= ( FLOAT ); + + // unary operators + D3DXQUATERNION operator + () const; + D3DXQUATERNION operator - () const; + + // binary operators + D3DXQUATERNION operator + ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator - ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( FLOAT ) const; + D3DXQUATERNION operator / ( FLOAT ) const; + + friend D3DXQUATERNION operator * (FLOAT, CONST D3DXQUATERNION& ); + + BOOL operator == ( CONST D3DXQUATERNION& ) const; + BOOL operator != ( CONST D3DXQUATERNION& ) const; + +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXQUATERNION, *LPD3DXQUATERNION; + + +//=========================================================================== +// +// Planes +// +//=========================================================================== +typedef struct D3DXPLANE +{ +#ifdef __cplusplus +public: + D3DXPLANE() {} + D3DXPLANE( CONST FLOAT* ); + D3DXPLANE( CONST D3DXFLOAT16* ); + D3DXPLANE( FLOAT a, FLOAT b, FLOAT c, FLOAT d ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXPLANE& operator *= ( FLOAT ); + D3DXPLANE& operator /= ( FLOAT ); + + // unary operators + D3DXPLANE operator + () const; + D3DXPLANE operator - () const; + + // binary operators + D3DXPLANE operator * ( FLOAT ) const; + D3DXPLANE operator / ( FLOAT ) const; + + friend D3DXPLANE operator * ( FLOAT, CONST D3DXPLANE& ); + + BOOL operator == ( CONST D3DXPLANE& ) const; + BOOL operator != ( CONST D3DXPLANE& ) const; + +#endif //__cplusplus + FLOAT a, b, c, d; +} D3DXPLANE, *LPD3DXPLANE; + + +//=========================================================================== +// +// Colors +// +//=========================================================================== + +typedef struct D3DXCOLOR +{ +#ifdef __cplusplus +public: + D3DXCOLOR() {} + D3DXCOLOR( DWORD argb ); + D3DXCOLOR( CONST FLOAT * ); + D3DXCOLOR( CONST D3DXFLOAT16 * ); + D3DXCOLOR( CONST D3DCOLORVALUE& ); + D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a ); + + // casting + operator DWORD () const; + + operator FLOAT* (); + operator CONST FLOAT* () const; + + operator D3DCOLORVALUE* (); + operator CONST D3DCOLORVALUE* () const; + + operator D3DCOLORVALUE& (); + operator CONST D3DCOLORVALUE& () const; + + // assignment operators + D3DXCOLOR& operator += ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator -= ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator *= ( FLOAT ); + D3DXCOLOR& operator /= ( FLOAT ); + + // unary operators + D3DXCOLOR operator + () const; + D3DXCOLOR operator - () const; + + // binary operators + D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator * ( FLOAT ) const; + D3DXCOLOR operator / ( FLOAT ) const; + + friend D3DXCOLOR operator * ( FLOAT, CONST D3DXCOLOR& ); + + BOOL operator == ( CONST D3DXCOLOR& ) const; + BOOL operator != ( CONST D3DXCOLOR& ) const; + +#endif //__cplusplus + FLOAT r, g, b, a; +} D3DXCOLOR, *LPD3DXCOLOR; + + + +//=========================================================================== +// +// D3DX math functions: +// +// NOTE: +// * All these functions can take the same object as in and out parameters. +// +// * Out parameters are typically also returned as return values, so that +// the output of one function may be used as a parameter to another. +// +//=========================================================================== + +//-------------------------- +// Float16 +//-------------------------- + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Converts an array 32-bit floats to 16-bit floats +D3DXFLOAT16* WINAPI D3DXFloat32To16Array + ( D3DXFLOAT16 *pOut, CONST FLOAT *pIn, UINT n ); + +// Converts an array 16-bit floats to 32-bit floats +FLOAT* WINAPI D3DXFloat16To32Array + ( FLOAT *pOut, CONST D3DXFLOAT16 *pIn, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 2D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec2Length + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2LengthSq + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2Dot + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Z component of ((x1,y1,0) cross (x2,y2,0)) +FLOAT D3DXVec2CCW + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Add + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Subtract + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2) +D3DXVECTOR2* D3DXVec2Minimize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2) +D3DXVECTOR2* D3DXVec2Maximize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Scale + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR2* D3DXVec2Lerp + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR2* WINAPI D3DXVec2Normalize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR2* WINAPI D3DXVec2Hermite + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pT1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR2* WINAPI D3DXVec2CatmullRom + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV0, CONST D3DXVECTOR2 *pV1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR2* WINAPI D3DXVec2BaryCentric + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + CONST D3DXVECTOR2 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, 0, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec2Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 1) by matrix, project result back into w=1. +D3DXVECTOR2* WINAPI D3DXVec2TransformCoord + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 0) by matrix. +D3DXVECTOR2* WINAPI D3DXVec2TransformNormal + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform Array (x, y, 0, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec2TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n); + +// Transform Array (x, y, 0, 1) by matrix, project result back into w=1. +D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray + ( D3DXVECTOR2 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform Array (x, y, 0, 0) by matrix. +D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray + ( D3DXVECTOR2 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + + + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 3D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec3Length + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3LengthSq + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3Dot + ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Cross + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Add + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Subtract + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR3* D3DXVec3Minimize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR3* D3DXVec3Maximize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Scale + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR3* D3DXVec3Lerp + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR3* WINAPI D3DXVec3Normalize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR3* WINAPI D3DXVec3Hermite + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pT1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR3* WINAPI D3DXVec3CatmullRom + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV0, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR3* WINAPI D3DXVec3BaryCentric + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, z, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec3Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 1) by matrix, project result back into w=1. +D3DXVECTOR3* WINAPI D3DXVec3TransformCoord + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the +// transpose of the inverse of the matrix you would use to transform a coord. +D3DXVECTOR3* WINAPI D3DXVec3TransformNormal + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + + +// Transform Array (x, y, z, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec3TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform Array (x, y, z, 1) by matrix, project result back into w=1. +D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the +// transpose of the inverse of the matrix you would use to transform a coord. +D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Project vector from object space into screen space +D3DXVECTOR3* WINAPI D3DXVec3Project + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +// Project vector from screen space into object space +D3DXVECTOR3* WINAPI D3DXVec3Unproject + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +// Project vector Array from object space into screen space +D3DXVECTOR3* WINAPI D3DXVec3ProjectArray + ( D3DXVECTOR3 *pOut, UINT OutStride,CONST D3DXVECTOR3 *pV, UINT VStride,CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld, UINT n); + +// Project vector Array from screen space into object space +D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld, UINT n); + + +#ifdef __cplusplus +} +#endif + + + +//-------------------------- +// 4D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec4Length + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4LengthSq + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4Dot + ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ); + +D3DXVECTOR4* D3DXVec4Add + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Subtract + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR4* D3DXVec4Minimize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR4* D3DXVec4Maximize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Scale + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR4* D3DXVec4Lerp + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Cross-product in 4 dimensions. +D3DXVECTOR4* WINAPI D3DXVec4Cross + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3); + +D3DXVECTOR4* WINAPI D3DXVec4Normalize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR4* WINAPI D3DXVec4Hermite + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pT1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR4* WINAPI D3DXVec4CatmullRom + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV0, CONST D3DXVECTOR4 *pV1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR4* WINAPI D3DXVec4BaryCentric + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3, FLOAT f, FLOAT g); + +// Transform vector by matrix. +D3DXVECTOR4* WINAPI D3DXVec4Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); + +// Transform vector array by matrix. +D3DXVECTOR4* WINAPI D3DXVec4TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR4 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 4D Matrix +//-------------------------- + +// inline + +D3DXMATRIX* D3DXMatrixIdentity + ( D3DXMATRIX *pOut ); + +BOOL D3DXMatrixIsIdentity + ( CONST D3DXMATRIX *pM ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +FLOAT WINAPI D3DXMatrixDeterminant + ( CONST D3DXMATRIX *pM ); + +HRESULT WINAPI D3DXMatrixDecompose + ( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation, + D3DXVECTOR3 *pOutTranslation, CONST D3DXMATRIX *pM ); + +D3DXMATRIX* WINAPI D3DXMatrixTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); + +// Matrix multiplication. The result represents the transformation M2 +// followed by the transformation M1. (Out = M1 * M2) +D3DXMATRIX* WINAPI D3DXMatrixMultiply + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Matrix multiplication, followed by a transpose. (Out = T(M1 * M2)) +D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Calculate inverse of matrix. Inversion my fail, in which case NULL will +// be returned. The determinant of pM is also returned it pfDeterminant +// is non-NULL. +D3DXMATRIX* WINAPI D3DXMatrixInverse + ( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); + +// Build a matrix which scales by (sx, sy, sz) +D3DXMATRIX* WINAPI D3DXMatrixScaling + ( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz ); + +// Build a matrix which translates by (x, y, z) +D3DXMATRIX* WINAPI D3DXMatrixTranslation + ( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); + +// Build a matrix which rotates around the X axis +D3DXMATRIX* WINAPI D3DXMatrixRotationX + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Y axis +D3DXMATRIX* WINAPI D3DXMatrixRotationY + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Z axis +D3DXMATRIX* WINAPI D3DXMatrixRotationZ + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around an arbitrary axis +D3DXMATRIX* WINAPI D3DXMatrixRotationAxis + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Build a matrix from a quaternion +D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion + ( D3DXMATRIX *pOut, CONST D3DXQUATERNION *pQ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXMATRIX* WINAPI D3DXMatrixRotationYawPitchRoll + ( D3DXMATRIX *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + +// Build transformation matrix. NULL arguments are treated as identity. +// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixTransformation + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pScalingCenter, + CONST D3DXQUATERNION *pScalingRotation, CONST D3DXVECTOR3 *pScaling, + CONST D3DXVECTOR3 *pRotationCenter, CONST D3DXQUATERNION *pRotation, + CONST D3DXVECTOR3 *pTranslation); + +// Build 2D transformation matrix in XY plane. NULL arguments are treated as identity. +// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixTransformation2D + ( D3DXMATRIX *pOut, CONST D3DXVECTOR2* pScalingCenter, + FLOAT ScalingRotation, CONST D3DXVECTOR2* pScaling, + CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, + CONST D3DXVECTOR2* pTranslation); + +// Build affine transformation matrix. NULL arguments are treated as identity. +// Mout = Ms * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR3 *pRotationCenter, + CONST D3DXQUATERNION *pRotation, CONST D3DXVECTOR3 *pTranslation); + +// Build 2D affine transformation matrix in XY plane. NULL arguments are treated as identity. +// Mout = Ms * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR2* pRotationCenter, + FLOAT Rotation, CONST D3DXVECTOR2* pTranslation); + +// Build a lookat matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtRH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a lookat matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtLH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a matrix which flattens geometry into a plane, as if casting +// a shadow from a light. +D3DXMATRIX* WINAPI D3DXMatrixShadow + ( D3DXMATRIX *pOut, CONST D3DXVECTOR4 *pLight, + CONST D3DXPLANE *pPlane ); + +// Build a matrix which reflects the coordinate system about a plane +D3DXMATRIX* WINAPI D3DXMatrixReflect + ( D3DXMATRIX *pOut, CONST D3DXPLANE *pPlane ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Quaternion +//-------------------------- + +// inline + +FLOAT D3DXQuaternionLength + ( CONST D3DXQUATERNION *pQ ); + +// Length squared, or "norm" +FLOAT D3DXQuaternionLengthSq + ( CONST D3DXQUATERNION *pQ ); + +FLOAT D3DXQuaternionDot + ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ); + +// (0, 0, 0, 1) +D3DXQUATERNION* D3DXQuaternionIdentity + ( D3DXQUATERNION *pOut ); + +BOOL D3DXQuaternionIsIdentity + ( CONST D3DXQUATERNION *pQ ); + +// (-x, -y, -z, w) +D3DXQUATERNION* D3DXQuaternionConjugate + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Compute a quaternin's axis and angle of rotation. Expects unit quaternions. +void WINAPI D3DXQuaternionToAxisAngle + ( CONST D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, FLOAT *pAngle ); + +// Build a quaternion from a rotation matrix. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix + ( D3DXQUATERNION *pOut, CONST D3DXMATRIX *pM); + +// Rotation about arbitrary axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis + ( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll + ( D3DXQUATERNION *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + +// Quaternion multiplication. The result represents the rotation Q2 +// followed by the rotation Q1. (Out = Q2 * Q1) +D3DXQUATERNION* WINAPI D3DXQuaternionMultiply + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2 ); + +D3DXQUATERNION* WINAPI D3DXQuaternionNormalize + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Conjugate and re-norm +D3DXQUATERNION* WINAPI D3DXQuaternionInverse + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects unit quaternions. +// if q = (cos(theta), sin(theta) * v); ln(q) = (0, theta * v) +D3DXQUATERNION* WINAPI D3DXQuaternionLn + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects pure quaternions. (w == 0) w is ignored in calculation. +// if q = (0, theta * v); exp(q) = (cos(theta), sin(theta) * v) +D3DXQUATERNION* WINAPI D3DXQuaternionExp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Spherical linear interpolation between Q1 (t == 0) and Q2 (t == 1). +// Expects unit quaternions. +D3DXQUATERNION* WINAPI D3DXQuaternionSlerp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, FLOAT t ); + +// Spherical quadrangle interpolation. +// Slerp(Slerp(Q1, C, t), Slerp(A, B, t), 2t(1-t)) +D3DXQUATERNION* WINAPI D3DXQuaternionSquad + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pA, CONST D3DXQUATERNION *pB, + CONST D3DXQUATERNION *pC, FLOAT t ); + +// Setup control points for spherical quadrangle interpolation +// from Q1 to Q2. The control points are chosen in such a way +// to ensure the continuity of tangents with adjacent segments. +void WINAPI D3DXQuaternionSquadSetup + ( D3DXQUATERNION *pAOut, D3DXQUATERNION *pBOut, D3DXQUATERNION *pCOut, + CONST D3DXQUATERNION *pQ0, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3 ); + +// Barycentric interpolation. +// Slerp(Slerp(Q1, Q2, f+g), Slerp(Q1, Q3, f+g), g/(f+g)) +D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3, + FLOAT f, FLOAT g ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Plane +//-------------------------- + +// inline + +// ax + by + cz + dw +FLOAT D3DXPlaneDot + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV); + +// ax + by + cz + d +FLOAT D3DXPlaneDotCoord + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +// ax + by + cz +FLOAT D3DXPlaneDotNormal + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +D3DXPLANE* D3DXPlaneScale + (D3DXPLANE *pOut, CONST D3DXPLANE *pP, FLOAT s); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Normalize plane (so that |a,b,c| == 1) +D3DXPLANE* WINAPI D3DXPlaneNormalize + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP); + +// Find the intersection between a plane and a line. If the line is +// parallel to the plane, NULL is returned. +D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine + ( D3DXVECTOR3 *pOut, CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2); + +// Construct a plane from a point and a normal +D3DXPLANE* WINAPI D3DXPlaneFromPointNormal + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pPoint, CONST D3DXVECTOR3 *pNormal); + +// Construct a plane from 3 points +D3DXPLANE* WINAPI D3DXPlaneFromPoints + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3); + +// Transform a plane by a matrix. The vector (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +D3DXPLANE* WINAPI D3DXPlaneTransform + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); + +// Transform an array of planes by a matrix. The vectors (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +D3DXPLANE* WINAPI D3DXPlaneTransformArray + ( D3DXPLANE *pOut, UINT OutStride, CONST D3DXPLANE *pP, UINT PStride, CONST D3DXMATRIX *pM, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Color +//-------------------------- + +// inline + +// (1-r, 1-g, 1-b, a) +D3DXCOLOR* D3DXColorNegative + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC); + +D3DXCOLOR* D3DXColorAdd + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorSubtract + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorScale + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// (r1*r2, g1*g2, b1*b2, a1*a2) +D3DXCOLOR* D3DXColorModulate + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +// Linear interpolation of r,g,b, and a. C1 + s(C2-C1) +D3DXCOLOR* D3DXColorLerp + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Interpolate r,g,b between desaturated color and color. +// DesaturatedColor + s(Color - DesaturatedColor) +D3DXCOLOR* WINAPI D3DXColorAdjustSaturation + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// Interpolate r,g,b between 50% grey and color. Grey + s(Color - Grey) +D3DXCOLOR* WINAPI D3DXColorAdjustContrast + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT c); + +#ifdef __cplusplus +} +#endif + + + + +//-------------------------- +// Misc +//-------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +// Calculate Fresnel term given the cosine of theta (likely obtained by +// taking the dot of two normals), and the refraction index of the material. +FLOAT WINAPI D3DXFresnelTerm + (FLOAT CosTheta, FLOAT RefractionIndex); + +#ifdef __cplusplus +} +#endif + + + +//=========================================================================== +// +// Matrix Stack +// +//=========================================================================== + +typedef interface ID3DXMatrixStack ID3DXMatrixStack; +typedef interface ID3DXMatrixStack *LPD3DXMATRIXSTACK; + +// {C7885BA7-F990-4fe7-922D-8515E477DD85} +DEFINE_GUID(IID_ID3DXMatrixStack, +0xc7885ba7, 0xf990, 0x4fe7, 0x92, 0x2d, 0x85, 0x15, 0xe4, 0x77, 0xdd, 0x85); + + +#undef INTERFACE +#define INTERFACE ID3DXMatrixStack + +DECLARE_INTERFACE_(ID3DXMatrixStack, IUnknown) +{ + // + // IUnknown methods + // + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + // + // ID3DXMatrixStack methods + // + + // Pops the top of the stack, returns the current top + // *after* popping the top. + STDMETHOD(Pop)(THIS) PURE; + + // Pushes the stack by one, duplicating the current matrix. + STDMETHOD(Push)(THIS) PURE; + + // Loads identity in the current matrix. + STDMETHOD(LoadIdentity)(THIS) PURE; + + // Loads the given matrix into the current matrix + STDMETHOD(LoadMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right-Multiplies the given matrix to the current matrix. + // (transformation is about the current world origin) + STDMETHOD(MultMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Left-Multiplies the given matrix to the current matrix + // (transformation is about the local origin of the object) + STDMETHOD(MultMatrixLocal)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the current world origin) + STDMETHOD(RotateAxis) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + STDMETHOD(RotateAxisLocal) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // current world origin) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRoll) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // local origin of the object) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRollLocal) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Right multiply the current matrix with the computed scale + // matrix. (transformation is about the current world origin) + STDMETHOD(Scale)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Left multiply the current matrix with the computed scale + // matrix. (transformation is about the local origin of the object) + STDMETHOD(ScaleLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Right multiply the current matrix with the computed translation + // matrix. (transformation is about the current world origin) + STDMETHOD(Translate)(THIS_ FLOAT x, FLOAT y, FLOAT z ) PURE; + + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + STDMETHOD(TranslateLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Obtain the current matrix at the top of the stack + STDMETHOD_(D3DXMATRIX*, GetTop)(THIS) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI + D3DXCreateMatrixStack( + DWORD Flags, + LPD3DXMATRIXSTACK* ppStack); + +#ifdef __cplusplus +} +#endif + +//=========================================================================== +// +// Spherical Harmonic Runtime Routines +// +// NOTE: +// * Most of these functions can take the same object as in and out parameters. +// The exceptions are the rotation functions. +// +// * Out parameters are typically also returned as return values, so that +// the output of one function may be used as a parameter to another. +// +//============================================================================ + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================ +// +// Basic Spherical Harmonic math routines +// +//============================================================================ + +#define D3DXSH_MINORDER 2 +#define D3DXSH_MAXORDER 6 + +//============================================================================ +// +// D3DXSHEvalDirection: +// -------------------- +// Evaluates the Spherical Harmonic basis functions +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction to evaluate in - assumed to be normalized +// +//============================================================================ + +FLOAT* WINAPI D3DXSHEvalDirection + ( FLOAT *pOut, UINT Order, CONST D3DXVECTOR3 *pDir ); + +//============================================================================ +// +// D3DXSHRotate: +// -------------------- +// Rotates SH vector by a rotation matrix +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned (should not alias with pIn.) +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pMatrix +// Matrix used for rotation - rotation sub matrix should be orthogonal +// and have a unit determinant. +// pIn +// Input SH coeffs (rotated), incorect results if this is also output. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHRotate + ( FLOAT *pOut, UINT Order, CONST D3DXMATRIX *pMatrix, CONST FLOAT *pIn ); + +//============================================================================ +// +// D3DXSHRotateZ: +// -------------------- +// Rotates the SH vector in the Z axis by an angle +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned (should not alias with pIn.) +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// Angle +// Angle in radians to rotate around the Z axis. +// pIn +// Input SH coeffs (rotated), incorect results if this is also output. +// +//============================================================================ + + +FLOAT* WINAPI D3DXSHRotateZ + ( FLOAT *pOut, UINT Order, FLOAT Angle, CONST FLOAT *pIn ); + +//============================================================================ +// +// D3DXSHAdd: +// -------------------- +// Adds two SH vectors, pOut[i] = pA[i] + pB[i]; +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pA +// Input SH coeffs. +// pB +// Input SH coeffs (second vector.) +// +//============================================================================ + +FLOAT* WINAPI D3DXSHAdd + ( FLOAT *pOut, UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); + +//============================================================================ +// +// D3DXSHScale: +// -------------------- +// Adds two SH vectors, pOut[i] = pA[i]*Scale; +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pIn +// Input SH coeffs. +// Scale +// Scale factor. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHScale + ( FLOAT *pOut, UINT Order, CONST FLOAT *pIn, CONST FLOAT Scale ); + +//============================================================================ +// +// D3DXSHDot: +// -------------------- +// Computes the dot product of two SH vectors +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pA +// Input SH coeffs. +// pB +// Second set of input SH coeffs. +// +//============================================================================ + +FLOAT WINAPI D3DXSHDot + ( UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); + +//============================================================================ +// +// D3DXSHMultiply[O]: +// -------------------- +// Computes the product of two functions represented using SH (f and g), where: +// pOut[i] = int(y_i(s) * f(s) * g(s)), where y_i(s) is the ith SH basis +// function, f(s) and g(s) are SH functions (sum_i(y_i(s)*c_i)). The order O +// determines the lengths of the arrays, where there should always be O^2 +// coefficients. In general the product of two SH functions of order O generates +// and SH function of order 2*O - 1, but we truncate the result. This means +// that the product commutes (f*g == g*f) but doesn't associate +// (f*(g*h) != (f*g)*h. +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// pF +// Input SH coeffs for first function. +// pG +// Second set of input SH coeffs. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHMultiply2( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply3( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply4( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply5( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply6( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); + + +//============================================================================ +// +// Basic Spherical Harmonic lighting routines +// +//============================================================================ + +//============================================================================ +// +// D3DXSHEvalDirectionalLight: +// -------------------- +// Evaluates a directional light and returns spectral SH data. The output +// vector is computed so that if the intensity of R/G/B is unit the resulting +// exit radiance of a point directly under the light on a diffuse object with +// an albedo of 1 would be 1.0. This will compute 3 spectral samples, pROut +// has to be specified, while pGout and pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction light is coming from (assumed to be normalized.) +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalDirectionalLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalSphericalLight: +// -------------------- +// Evaluates a spherical light and returns spectral SH data. There is no +// normalization of the intensity of the light like there is for directional +// lights, care has to be taken when specifiying the intensities. This will +// compute 3 spectral samples, pROut has to be specified, while pGout and +// pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pPos +// Position of light - reciever is assumed to be at the origin. +// Radius +// Radius of the spherical light source. +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalSphericalLight + ( UINT Order, CONST D3DXVECTOR3 *pPos, FLOAT Radius, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalConeLight: +// -------------------- +// Evaluates a light that is a cone of constant intensity and returns spectral +// SH data. The output vector is computed so that if the intensity of R/G/B is +// unit the resulting exit radiance of a point directly under the light oriented +// in the cone direction on a diffuse object with an albedo of 1 would be 1.0. +// This will compute 3 spectral samples, pROut has to be specified, while pGout +// and pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction light is coming from (assumed to be normalized.) +// Radius +// Radius of cone in radians. +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalConeLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, FLOAT Radius, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalHemisphereLight: +// -------------------- +// Evaluates a light that is a linear interpolant between two colors over the +// sphere. The interpolant is linear along the axis of the two points, not +// over the surface of the sphere (ie: if the axis was (0,0,1) it is linear in +// Z, not in the azimuthal angle.) The resulting spherical lighting function +// is normalized so that a point on a perfectly diffuse surface with no +// shadowing and a normal pointed in the direction pDir would result in exit +// radiance with a value of 1 if the top color was white and the bottom color +// was black. This is a very simple model where Top represents the intensity +// of the "sky" and Bottom represents the intensity of the "ground". +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Axis of the hemisphere. +// Top +// Color of the upper hemisphere. +// Bottom +// Color of the lower hemisphere. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green +// pBOut +// Output SH vector for Blue +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalHemisphereLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, D3DXCOLOR Top, D3DXCOLOR Bottom, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// Basic Spherical Harmonic projection routines +// +//============================================================================ + +//============================================================================ +// +// D3DXSHProjectCubeMap: +// -------------------- +// Projects a function represented on a cube map into spherical harmonics. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pCubeMap +// CubeMap that is going to be projected into spherical harmonics +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green +// pBOut +// Output SH vector for Blue +// +//============================================================================ + +HRESULT WINAPI D3DXSHProjectCubeMap + ( UINT uOrder, LPDIRECT3DCUBETEXTURE9 pCubeMap, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + + +#ifdef __cplusplus +} +#endif + + +#include "d3dx9math.inl" + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4201) +#endif + +#endif // __D3DX9MATH_H__ + diff --git a/dxsdk/Include/d3dx9math.inl b/dxsdk/Include/d3dx9math.inl new file mode 100644 index 0000000..a3652ed --- /dev/null +++ b/dxsdk/Include/d3dx9math.inl @@ -0,0 +1,2251 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9math.inl +// Content: D3DX math inline functions +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX9MATH_INL__ +#define __D3DX9MATH_INL__ + +//=========================================================================== +// +// Inline Class Methods +// +//=========================================================================== + +#ifdef __cplusplus + +//-------------------------- +// Float16 +//-------------------------- + +D3DXINLINE +D3DXFLOAT16::D3DXFLOAT16( FLOAT f ) +{ + D3DXFloat32To16Array(this, &f, 1); +} + +D3DXINLINE +D3DXFLOAT16::D3DXFLOAT16( CONST D3DXFLOAT16& f ) +{ + value = f.value; +} + +// casting +D3DXINLINE +D3DXFLOAT16::operator FLOAT () +{ + FLOAT f; + D3DXFloat16To32Array(&f, this, 1); + return f; +} + +// binary operators +D3DXINLINE BOOL +D3DXFLOAT16::operator == ( CONST D3DXFLOAT16& f ) const +{ + return value == f.value; +} + +D3DXINLINE BOOL +D3DXFLOAT16::operator != ( CONST D3DXFLOAT16& f ) const +{ + return value != f.value; +} + + +//-------------------------- +// 2D Vector +//-------------------------- + +D3DXINLINE +D3DXVECTOR2::D3DXVECTOR2( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; +} + +D3DXINLINE +D3DXVECTOR2::D3DXVECTOR2( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 2); +} + +D3DXINLINE +D3DXVECTOR2::D3DXVECTOR2( FLOAT fx, FLOAT fy ) +{ + x = fx; + y = fy; +} + + +// casting +D3DXINLINE +D3DXVECTOR2::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXVECTOR2::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator += ( CONST D3DXVECTOR2& v ) +{ + x += v.x; + y += v.y; + return *this; +} + +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator -= ( CONST D3DXVECTOR2& v ) +{ + x -= v.x; + y -= v.y; + return *this; +} + +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + return *this; +} + +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator - () const +{ + return D3DXVECTOR2(-x, -y); +} + + +// binary operators +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator + ( CONST D3DXVECTOR2& v ) const +{ + return D3DXVECTOR2(x + v.x, y + v.y); +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator - ( CONST D3DXVECTOR2& v ) const +{ + return D3DXVECTOR2(x - v.x, y - v.y); +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator * ( FLOAT f ) const +{ + return D3DXVECTOR2(x * f, y * f); +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR2(x * fInv, y * fInv); +} + +D3DXINLINE D3DXVECTOR2 +operator * ( FLOAT f, CONST D3DXVECTOR2& v ) +{ + return D3DXVECTOR2(f * v.x, f * v.y); +} + +D3DXINLINE BOOL +D3DXVECTOR2::operator == ( CONST D3DXVECTOR2& v ) const +{ + return x == v.x && y == v.y; +} + +D3DXINLINE BOOL +D3DXVECTOR2::operator != ( CONST D3DXVECTOR2& v ) const +{ + return x != v.x || y != v.y; +} + + + +//-------------------------- +// 2D Vector (16 bit) +//-------------------------- + +D3DXINLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 2); +} + +D3DXINLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + *((DWORD *) &x) = *((DWORD *) &pf[0]); +} + +D3DXINLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy ) +{ + x = fx; + y = fy; +} + + +// casting +D3DXINLINE +D3DXVECTOR2_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DXINLINE +D3DXVECTOR2_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DXINLINE BOOL +D3DXVECTOR2_16F::operator == ( CONST D3DXVECTOR2_16F &v ) const +{ + return *((DWORD *) &x) == *((DWORD *) &v.x); +} + +D3DXINLINE BOOL +D3DXVECTOR2_16F::operator != ( CONST D3DXVECTOR2_16F &v ) const +{ + return *((DWORD *) &x) != *((DWORD *) &v.x); +} + + +//-------------------------- +// 3D Vector +//-------------------------- +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; +} + +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( CONST D3DVECTOR& v ) +{ + x = v.x; + y = v.y; + z = v.z; +} + +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 3); +} + +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( FLOAT fx, FLOAT fy, FLOAT fz ) +{ + x = fx; + y = fy; + z = fz; +} + + +// casting +D3DXINLINE +D3DXVECTOR3::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXVECTOR3::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator += ( CONST D3DXVECTOR3& v ) +{ + x += v.x; + y += v.y; + z += v.z; + return *this; +} + +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator -= ( CONST D3DXVECTOR3& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + return *this; +} + +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + return *this; +} + +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator - () const +{ + return D3DXVECTOR3(-x, -y, -z); +} + + +// binary operators +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator + ( CONST D3DXVECTOR3& v ) const +{ + return D3DXVECTOR3(x + v.x, y + v.y, z + v.z); +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator - ( CONST D3DXVECTOR3& v ) const +{ + return D3DXVECTOR3(x - v.x, y - v.y, z - v.z); +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator * ( FLOAT f ) const +{ + return D3DXVECTOR3(x * f, y * f, z * f); +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR3(x * fInv, y * fInv, z * fInv); +} + + +D3DXINLINE D3DXVECTOR3 +operator * ( FLOAT f, CONST struct D3DXVECTOR3& v ) +{ + return D3DXVECTOR3(f * v.x, f * v.y, f * v.z); +} + + +D3DXINLINE BOOL +D3DXVECTOR3::operator == ( CONST D3DXVECTOR3& v ) const +{ + return x == v.x && y == v.y && z == v.z; +} + +D3DXINLINE BOOL +D3DXVECTOR3::operator != ( CONST D3DXVECTOR3& v ) const +{ + return x != v.x || y != v.y || z != v.z; +} + + + +//-------------------------- +// 3D Vector (16 bit) +//-------------------------- + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 3); +} + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DVECTOR& v ) +{ + D3DXFloat32To16Array(&x, &v.x, 1); + D3DXFloat32To16Array(&y, &v.y, 1); + D3DXFloat32To16Array(&z, &v.z, 1); +} + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + *((DWORD *) &x) = *((DWORD *) &pf[0]); + *((WORD *) &z) = *((WORD *) &pf[2]); +} + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy, CONST D3DXFLOAT16 &fz ) +{ + x = fx; + y = fy; + z = fz; +} + + +// casting +D3DXINLINE +D3DXVECTOR3_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DXINLINE +D3DXVECTOR3_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DXINLINE BOOL +D3DXVECTOR3_16F::operator == ( CONST D3DXVECTOR3_16F &v ) const +{ + return *((DWORD *) &x) == *((DWORD *) &v.x) && + *((WORD *) &z) == *((WORD *) &v.z); +} + +D3DXINLINE BOOL +D3DXVECTOR3_16F::operator != ( CONST D3DXVECTOR3_16F &v ) const +{ + return *((DWORD *) &x) != *((DWORD *) &v.x) || + *((WORD *) &z) != *((WORD *) &v.z); +} + + +//-------------------------- +// 4D Vector +//-------------------------- +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; + w = pf[3]; +} + +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 4); +} + +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( CONST D3DVECTOR& v, FLOAT f ) +{ + x = v.x; + y = v.y; + z = v.z; + w = f; +} + +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DXINLINE +D3DXVECTOR4::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXVECTOR4::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator += ( CONST D3DXVECTOR4& v ) +{ + x += v.x; + y += v.y; + z += v.z; + w += v.w; + return *this; +} + +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator -= ( CONST D3DXVECTOR4& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + return *this; +} + +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + w *= f; + return *this; +} + +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + w *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator - () const +{ + return D3DXVECTOR4(-x, -y, -z, -w); +} + + +// binary operators +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator + ( CONST D3DXVECTOR4& v ) const +{ + return D3DXVECTOR4(x + v.x, y + v.y, z + v.z, w + v.w); +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator - ( CONST D3DXVECTOR4& v ) const +{ + return D3DXVECTOR4(x - v.x, y - v.y, z - v.z, w - v.w); +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator * ( FLOAT f ) const +{ + return D3DXVECTOR4(x * f, y * f, z * f, w * f); +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR4(x * fInv, y * fInv, z * fInv, w * fInv); +} + +D3DXINLINE D3DXVECTOR4 +operator * ( FLOAT f, CONST D3DXVECTOR4& v ) +{ + return D3DXVECTOR4(f * v.x, f * v.y, f * v.z, f * v.w); +} + + +D3DXINLINE BOOL +D3DXVECTOR4::operator == ( CONST D3DXVECTOR4& v ) const +{ + return x == v.x && y == v.y && z == v.z && w == v.w; +} + +D3DXINLINE BOOL +D3DXVECTOR4::operator != ( CONST D3DXVECTOR4& v ) const +{ + return x != v.x || y != v.y || z != v.z || w != v.w; +} + + + +//-------------------------- +// 4D Vector (16 bit) +//-------------------------- + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 4); +} + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + *((DWORD *) &x) = *((DWORD *) &pf[0]); + *((DWORD *) &z) = *((DWORD *) &pf[2]); +} + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXVECTOR3_16F& v, CONST D3DXFLOAT16& f ) +{ + x = v.x; + y = v.y; + z = v.z; + w = f; +} + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy, CONST D3DXFLOAT16 &fz, CONST D3DXFLOAT16 &fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DXINLINE +D3DXVECTOR4_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DXINLINE +D3DXVECTOR4_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DXINLINE BOOL +D3DXVECTOR4_16F::operator == ( CONST D3DXVECTOR4_16F &v ) const +{ + return *((DWORD *) &x) == *((DWORD *) &v.x) && + *((DWORD *) &z) == *((DWORD *) &v.z); +} + +D3DXINLINE BOOL +D3DXVECTOR4_16F::operator != ( CONST D3DXVECTOR4_16F &v ) const +{ + return *((DWORD *) &x) != *((DWORD *) &v.x) || + *((DWORD *) &z) != *((DWORD *) &v.z); +} + + +//-------------------------- +// Matrix +//-------------------------- +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + memcpy(&_11, pf, sizeof(D3DXMATRIX)); +} + +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( CONST D3DMATRIX& mat ) +{ + memcpy(&_11, &mat, sizeof(D3DXMATRIX)); +} + +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&_11, pf, 16); +} + +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( FLOAT f11, FLOAT f12, FLOAT f13, FLOAT f14, + FLOAT f21, FLOAT f22, FLOAT f23, FLOAT f24, + FLOAT f31, FLOAT f32, FLOAT f33, FLOAT f34, + FLOAT f41, FLOAT f42, FLOAT f43, FLOAT f44 ) +{ + _11 = f11; _12 = f12; _13 = f13; _14 = f14; + _21 = f21; _22 = f22; _23 = f23; _24 = f24; + _31 = f31; _32 = f32; _33 = f33; _34 = f34; + _41 = f41; _42 = f42; _43 = f43; _44 = f44; +} + + + +// access grants +D3DXINLINE FLOAT& +D3DXMATRIX::operator () ( UINT iRow, UINT iCol ) +{ + return m[iRow][iCol]; +} + +D3DXINLINE FLOAT +D3DXMATRIX::operator () ( UINT iRow, UINT iCol ) const +{ + return m[iRow][iCol]; +} + + +// casting operators +D3DXINLINE +D3DXMATRIX::operator FLOAT* () +{ + return (FLOAT *) &_11; +} + +D3DXINLINE +D3DXMATRIX::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &_11; +} + + +// assignment operators +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator *= ( CONST D3DXMATRIX& mat ) +{ + D3DXMatrixMultiply(this, this, &mat); + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator += ( CONST D3DXMATRIX& mat ) +{ + _11 += mat._11; _12 += mat._12; _13 += mat._13; _14 += mat._14; + _21 += mat._21; _22 += mat._22; _23 += mat._23; _24 += mat._24; + _31 += mat._31; _32 += mat._32; _33 += mat._33; _34 += mat._34; + _41 += mat._41; _42 += mat._42; _43 += mat._43; _44 += mat._44; + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator -= ( CONST D3DXMATRIX& mat ) +{ + _11 -= mat._11; _12 -= mat._12; _13 -= mat._13; _14 -= mat._14; + _21 -= mat._21; _22 -= mat._22; _23 -= mat._23; _24 -= mat._24; + _31 -= mat._31; _32 -= mat._32; _33 -= mat._33; _34 -= mat._34; + _41 -= mat._41; _42 -= mat._42; _43 -= mat._43; _44 -= mat._44; + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator *= ( FLOAT f ) +{ + _11 *= f; _12 *= f; _13 *= f; _14 *= f; + _21 *= f; _22 *= f; _23 *= f; _24 *= f; + _31 *= f; _32 *= f; _33 *= f; _34 *= f; + _41 *= f; _42 *= f; _43 *= f; _44 *= f; + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + _11 *= fInv; _12 *= fInv; _13 *= fInv; _14 *= fInv; + _21 *= fInv; _22 *= fInv; _23 *= fInv; _24 *= fInv; + _31 *= fInv; _32 *= fInv; _33 *= fInv; _34 *= fInv; + _41 *= fInv; _42 *= fInv; _43 *= fInv; _44 *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator - () const +{ + return D3DXMATRIX(-_11, -_12, -_13, -_14, + -_21, -_22, -_23, -_24, + -_31, -_32, -_33, -_34, + -_41, -_42, -_43, -_44); +} + + +// binary operators +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator * ( CONST D3DXMATRIX& mat ) const +{ + D3DXMATRIX matT; + D3DXMatrixMultiply(&matT, this, &mat); + return matT; +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator + ( CONST D3DXMATRIX& mat ) const +{ + return D3DXMATRIX(_11 + mat._11, _12 + mat._12, _13 + mat._13, _14 + mat._14, + _21 + mat._21, _22 + mat._22, _23 + mat._23, _24 + mat._24, + _31 + mat._31, _32 + mat._32, _33 + mat._33, _34 + mat._34, + _41 + mat._41, _42 + mat._42, _43 + mat._43, _44 + mat._44); +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator - ( CONST D3DXMATRIX& mat ) const +{ + return D3DXMATRIX(_11 - mat._11, _12 - mat._12, _13 - mat._13, _14 - mat._14, + _21 - mat._21, _22 - mat._22, _23 - mat._23, _24 - mat._24, + _31 - mat._31, _32 - mat._32, _33 - mat._33, _34 - mat._34, + _41 - mat._41, _42 - mat._42, _43 - mat._43, _44 - mat._44); +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator * ( FLOAT f ) const +{ + return D3DXMATRIX(_11 * f, _12 * f, _13 * f, _14 * f, + _21 * f, _22 * f, _23 * f, _24 * f, + _31 * f, _32 * f, _33 * f, _34 * f, + _41 * f, _42 * f, _43 * f, _44 * f); +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXMATRIX(_11 * fInv, _12 * fInv, _13 * fInv, _14 * fInv, + _21 * fInv, _22 * fInv, _23 * fInv, _24 * fInv, + _31 * fInv, _32 * fInv, _33 * fInv, _34 * fInv, + _41 * fInv, _42 * fInv, _43 * fInv, _44 * fInv); +} + + +D3DXINLINE D3DXMATRIX +operator * ( FLOAT f, CONST D3DXMATRIX& mat ) +{ + return D3DXMATRIX(f * mat._11, f * mat._12, f * mat._13, f * mat._14, + f * mat._21, f * mat._22, f * mat._23, f * mat._24, + f * mat._31, f * mat._32, f * mat._33, f * mat._34, + f * mat._41, f * mat._42, f * mat._43, f * mat._44); +} + + +D3DXINLINE BOOL +D3DXMATRIX::operator == ( CONST D3DXMATRIX& mat ) const +{ + return 0 == memcmp(this, &mat, sizeof(D3DXMATRIX)); +} + +D3DXINLINE BOOL +D3DXMATRIX::operator != ( CONST D3DXMATRIX& mat ) const +{ + return 0 != memcmp(this, &mat, sizeof(D3DXMATRIX)); +} + + + +//-------------------------- +// Aligned Matrices +//-------------------------- + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST FLOAT* f ) : + D3DXMATRIX( f ) +{ +} + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST D3DMATRIX& m ) : + D3DXMATRIX( m ) +{ +} + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST D3DXFLOAT16* f ) : + D3DXMATRIX( f ) +{ +} + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ) : + D3DXMATRIX(_11, _12, _13, _14, + _21, _22, _23, _24, + _31, _32, _33, _34, + _41, _42, _43, _44) +{ +} + +#ifndef SIZE_MAX +#define SIZE_MAX ((SIZE_T)-1) +#endif + +D3DXINLINE void* +_D3DXMATRIXA16::operator new( size_t s ) +{ + if (s > (SIZE_MAX-16)) + return NULL; + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; +} + +D3DXINLINE void* +_D3DXMATRIXA16::operator new[]( size_t s ) +{ + if (s > (SIZE_MAX-16)) + return NULL; + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; +} + +D3DXINLINE void +_D3DXMATRIXA16::operator delete(void* p) +{ + if(p) + { + BYTE* pb = static_cast(p); + pb -= pb[-1]; + ::delete [] pb; + } +} + +D3DXINLINE void +_D3DXMATRIXA16::operator delete[](void* p) +{ + if(p) + { + BYTE* pb = static_cast(p); + pb -= pb[-1]; + ::delete [] pb; + } +} + +D3DXINLINE _D3DXMATRIXA16& +_D3DXMATRIXA16::operator=(CONST D3DXMATRIX& rhs) +{ + memcpy(&_11, &rhs, sizeof(D3DXMATRIX)); + return *this; +} + + +//-------------------------- +// Quaternion +//-------------------------- + +D3DXINLINE +D3DXQUATERNION::D3DXQUATERNION( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; + w = pf[3]; +} + +D3DXINLINE +D3DXQUATERNION::D3DXQUATERNION( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 4); +} + +D3DXINLINE +D3DXQUATERNION::D3DXQUATERNION( FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DXINLINE +D3DXQUATERNION::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXQUATERNION::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator += ( CONST D3DXQUATERNION& q ) +{ + x += q.x; + y += q.y; + z += q.z; + w += q.w; + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator -= ( CONST D3DXQUATERNION& q ) +{ + x -= q.x; + y -= q.y; + z -= q.z; + w -= q.w; + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator *= ( CONST D3DXQUATERNION& q ) +{ + D3DXQuaternionMultiply(this, this, &q); + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + w *= f; + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + w *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator - () const +{ + return D3DXQUATERNION(-x, -y, -z, -w); +} + + +// binary operators +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator + ( CONST D3DXQUATERNION& q ) const +{ + return D3DXQUATERNION(x + q.x, y + q.y, z + q.z, w + q.w); +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator - ( CONST D3DXQUATERNION& q ) const +{ + return D3DXQUATERNION(x - q.x, y - q.y, z - q.z, w - q.w); +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator * ( CONST D3DXQUATERNION& q ) const +{ + D3DXQUATERNION qT; + D3DXQuaternionMultiply(&qT, this, &q); + return qT; +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator * ( FLOAT f ) const +{ + return D3DXQUATERNION(x * f, y * f, z * f, w * f); +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXQUATERNION(x * fInv, y * fInv, z * fInv, w * fInv); +} + + +D3DXINLINE D3DXQUATERNION +operator * (FLOAT f, CONST D3DXQUATERNION& q ) +{ + return D3DXQUATERNION(f * q.x, f * q.y, f * q.z, f * q.w); +} + + +D3DXINLINE BOOL +D3DXQUATERNION::operator == ( CONST D3DXQUATERNION& q ) const +{ + return x == q.x && y == q.y && z == q.z && w == q.w; +} + +D3DXINLINE BOOL +D3DXQUATERNION::operator != ( CONST D3DXQUATERNION& q ) const +{ + return x != q.x || y != q.y || z != q.z || w != q.w; +} + + + +//-------------------------- +// Plane +//-------------------------- + +D3DXINLINE +D3DXPLANE::D3DXPLANE( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + a = pf[0]; + b = pf[1]; + c = pf[2]; + d = pf[3]; +} + +D3DXINLINE +D3DXPLANE::D3DXPLANE( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&a, pf, 4); +} + +D3DXINLINE +D3DXPLANE::D3DXPLANE( FLOAT fa, FLOAT fb, FLOAT fc, FLOAT fd ) +{ + a = fa; + b = fb; + c = fc; + d = fd; +} + + +// casting +D3DXINLINE +D3DXPLANE::operator FLOAT* () +{ + return (FLOAT *) &a; +} + +D3DXINLINE +D3DXPLANE::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &a; +} + + +// assignment operators +D3DXINLINE D3DXPLANE& +D3DXPLANE::operator *= ( FLOAT f ) +{ + a *= f; + b *= f; + c *= f; + d *= f; + return *this; +} + +D3DXINLINE D3DXPLANE& +D3DXPLANE::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + a *= fInv; + b *= fInv; + c *= fInv; + d *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXPLANE +D3DXPLANE::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXPLANE +D3DXPLANE::operator - () const +{ + return D3DXPLANE(-a, -b, -c, -d); +} + + +// binary operators +D3DXINLINE D3DXPLANE +D3DXPLANE::operator * ( FLOAT f ) const +{ + return D3DXPLANE(a * f, b * f, c * f, d * f); +} + +D3DXINLINE D3DXPLANE +D3DXPLANE::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXPLANE(a * fInv, b * fInv, c * fInv, d * fInv); +} + +D3DXINLINE D3DXPLANE +operator * (FLOAT f, CONST D3DXPLANE& p ) +{ + return D3DXPLANE(f * p.a, f * p.b, f * p.c, f * p.d); +} + +D3DXINLINE BOOL +D3DXPLANE::operator == ( CONST D3DXPLANE& p ) const +{ + return a == p.a && b == p.b && c == p.c && d == p.d; +} + +D3DXINLINE BOOL +D3DXPLANE::operator != ( CONST D3DXPLANE& p ) const +{ + return a != p.a || b != p.b || c != p.c || d != p.d; +} + + + + +//-------------------------- +// Color +//-------------------------- + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( DWORD dw ) +{ + CONST FLOAT f = 1.0f / 255.0f; + r = f * (FLOAT) (unsigned char) (dw >> 16); + g = f * (FLOAT) (unsigned char) (dw >> 8); + b = f * (FLOAT) (unsigned char) (dw >> 0); + a = f * (FLOAT) (unsigned char) (dw >> 24); +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + r = pf[0]; + g = pf[1]; + b = pf[2]; + a = pf[3]; +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&r, pf, 4); +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( CONST D3DCOLORVALUE& c ) +{ + r = c.r; + g = c.g; + b = c.b; + a = c.a; +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( FLOAT fr, FLOAT fg, FLOAT fb, FLOAT fa ) +{ + r = fr; + g = fg; + b = fb; + a = fa; +} + + +// casting +D3DXINLINE +D3DXCOLOR::operator DWORD () const +{ + DWORD dwR = r >= 1.0f ? 0xff : r <= 0.0f ? 0x00 : (DWORD) (r * 255.0f + 0.5f); + DWORD dwG = g >= 1.0f ? 0xff : g <= 0.0f ? 0x00 : (DWORD) (g * 255.0f + 0.5f); + DWORD dwB = b >= 1.0f ? 0xff : b <= 0.0f ? 0x00 : (DWORD) (b * 255.0f + 0.5f); + DWORD dwA = a >= 1.0f ? 0xff : a <= 0.0f ? 0x00 : (DWORD) (a * 255.0f + 0.5f); + + return (dwA << 24) | (dwR << 16) | (dwG << 8) | dwB; +} + + +D3DXINLINE +D3DXCOLOR::operator FLOAT * () +{ + return (FLOAT *) &r; +} + +D3DXINLINE +D3DXCOLOR::operator CONST FLOAT * () const +{ + return (CONST FLOAT *) &r; +} + + +D3DXINLINE +D3DXCOLOR::operator D3DCOLORVALUE * () +{ + return (D3DCOLORVALUE *) &r; +} + +D3DXINLINE +D3DXCOLOR::operator CONST D3DCOLORVALUE * () const +{ + return (CONST D3DCOLORVALUE *) &r; +} + + +D3DXINLINE +D3DXCOLOR::operator D3DCOLORVALUE& () +{ + return *((D3DCOLORVALUE *) &r); +} + +D3DXINLINE +D3DXCOLOR::operator CONST D3DCOLORVALUE& () const +{ + return *((CONST D3DCOLORVALUE *) &r); +} + + +// assignment operators +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator += ( CONST D3DXCOLOR& c ) +{ + r += c.r; + g += c.g; + b += c.b; + a += c.a; + return *this; +} + +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator -= ( CONST D3DXCOLOR& c ) +{ + r -= c.r; + g -= c.g; + b -= c.b; + a -= c.a; + return *this; +} + +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator *= ( FLOAT f ) +{ + r *= f; + g *= f; + b *= f; + a *= f; + return *this; +} + +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + r *= fInv; + g *= fInv; + b *= fInv; + a *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator - () const +{ + return D3DXCOLOR(-r, -g, -b, -a); +} + + +// binary operators +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator + ( CONST D3DXCOLOR& c ) const +{ + return D3DXCOLOR(r + c.r, g + c.g, b + c.b, a + c.a); +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator - ( CONST D3DXCOLOR& c ) const +{ + return D3DXCOLOR(r - c.r, g - c.g, b - c.b, a - c.a); +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator * ( FLOAT f ) const +{ + return D3DXCOLOR(r * f, g * f, b * f, a * f); +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXCOLOR(r * fInv, g * fInv, b * fInv, a * fInv); +} + + +D3DXINLINE D3DXCOLOR +operator * (FLOAT f, CONST D3DXCOLOR& c ) +{ + return D3DXCOLOR(f * c.r, f * c.g, f * c.b, f * c.a); +} + + +D3DXINLINE BOOL +D3DXCOLOR::operator == ( CONST D3DXCOLOR& c ) const +{ + return r == c.r && g == c.g && b == c.b && a == c.a; +} + +D3DXINLINE BOOL +D3DXCOLOR::operator != ( CONST D3DXCOLOR& c ) const +{ + return r != c.r || g != c.g || b != c.b || a != c.a; +} + + +#endif //__cplusplus + + + +//=========================================================================== +// +// Inline functions +// +//=========================================================================== + + +//-------------------------- +// 2D Vector +//-------------------------- + +D3DXINLINE FLOAT D3DXVec2Length + ( CONST D3DXVECTOR2 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y); +#endif +} + +D3DXINLINE FLOAT D3DXVec2LengthSq + ( CONST D3DXVECTOR2 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y; +} + +D3DXINLINE FLOAT D3DXVec2Dot + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y; +} + +D3DXINLINE FLOAT D3DXVec2CCW + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->y - pV1->y * pV2->x; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Add + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Subtract + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Minimize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Maximize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Scale + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Lerp + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + return pOut; +} + + +//-------------------------- +// 3D Vector +//-------------------------- + +D3DXINLINE FLOAT D3DXVec3Length + ( CONST D3DXVECTOR3 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z); +#endif +} + +D3DXINLINE FLOAT D3DXVec3LengthSq + ( CONST D3DXVECTOR3 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y + pV->z * pV->z; +} + +D3DXINLINE FLOAT D3DXVec3Dot + ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Cross + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + D3DXVECTOR3 v; + +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + v.x = pV1->y * pV2->z - pV1->z * pV2->y; + v.y = pV1->z * pV2->x - pV1->x * pV2->z; + v.z = pV1->x * pV2->y - pV1->y * pV2->x; + + *pOut = v; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Add + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + pOut->z = pV1->z + pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Minimize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z < pV2->z ? pV1->z : pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Maximize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z > pV2->z ? pV1->z : pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Scale + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + pOut->z = pV->z * s; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Lerp + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + pOut->z = pV1->z + s * (pV2->z - pV1->z); + return pOut; +} + + +//-------------------------- +// 4D Vector +//-------------------------- + +D3DXINLINE FLOAT D3DXVec4Length + ( CONST D3DXVECTOR4 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w); +#endif +} + +D3DXINLINE FLOAT D3DXVec4LengthSq + ( CONST D3DXVECTOR4 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w; +} + +D3DXINLINE FLOAT D3DXVec4Dot + ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z + pV1->w * pV2->w; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Add + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + pOut->z = pV1->z + pV2->z; + pOut->w = pV1->w + pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Subtract + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + pOut->w = pV1->w - pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Minimize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z < pV2->z ? pV1->z : pV2->z; + pOut->w = pV1->w < pV2->w ? pV1->w : pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Maximize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z > pV2->z ? pV1->z : pV2->z; + pOut->w = pV1->w > pV2->w ? pV1->w : pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Scale + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + pOut->z = pV->z * s; + pOut->w = pV->w * s; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Lerp + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + pOut->z = pV1->z + s * (pV2->z - pV1->z); + pOut->w = pV1->w + s * (pV2->w - pV1->w); + return pOut; +} + + +//-------------------------- +// 4D Matrix +//-------------------------- + +D3DXINLINE D3DXMATRIX* D3DXMatrixIdentity + ( D3DXMATRIX *pOut ) +{ +#ifdef D3DX_DEBUG + if(!pOut) + return NULL; +#endif + + pOut->m[0][1] = pOut->m[0][2] = pOut->m[0][3] = + pOut->m[1][0] = pOut->m[1][2] = pOut->m[1][3] = + pOut->m[2][0] = pOut->m[2][1] = pOut->m[2][3] = + pOut->m[3][0] = pOut->m[3][1] = pOut->m[3][2] = 0.0f; + + pOut->m[0][0] = pOut->m[1][1] = pOut->m[2][2] = pOut->m[3][3] = 1.0f; + return pOut; +} + + +D3DXINLINE BOOL D3DXMatrixIsIdentity + ( CONST D3DXMATRIX *pM ) +{ +#ifdef D3DX_DEBUG + if(!pM) + return FALSE; +#endif + + return pM->m[0][0] == 1.0f && pM->m[0][1] == 0.0f && pM->m[0][2] == 0.0f && pM->m[0][3] == 0.0f && + pM->m[1][0] == 0.0f && pM->m[1][1] == 1.0f && pM->m[1][2] == 0.0f && pM->m[1][3] == 0.0f && + pM->m[2][0] == 0.0f && pM->m[2][1] == 0.0f && pM->m[2][2] == 1.0f && pM->m[2][3] == 0.0f && + pM->m[3][0] == 0.0f && pM->m[3][1] == 0.0f && pM->m[3][2] == 0.0f && pM->m[3][3] == 1.0f; +} + + +//-------------------------- +// Quaternion +//-------------------------- + +D3DXINLINE FLOAT D3DXQuaternionLength + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pQ) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w); +#else + return (FLOAT) sqrt(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w); +#endif +} + +D3DXINLINE FLOAT D3DXQuaternionLengthSq + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pQ) + return 0.0f; +#endif + + return pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w; +} + +D3DXINLINE FLOAT D3DXQuaternionDot + ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ) +{ +#ifdef D3DX_DEBUG + if(!pQ1 || !pQ2) + return 0.0f; +#endif + + return pQ1->x * pQ2->x + pQ1->y * pQ2->y + pQ1->z * pQ2->z + pQ1->w * pQ2->w; +} + + +D3DXINLINE D3DXQUATERNION* D3DXQuaternionIdentity + ( D3DXQUATERNION *pOut ) +{ +#ifdef D3DX_DEBUG + if(!pOut) + return NULL; +#endif + + pOut->x = pOut->y = pOut->z = 0.0f; + pOut->w = 1.0f; + return pOut; +} + +D3DXINLINE BOOL D3DXQuaternionIsIdentity + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pQ) + return FALSE; +#endif + + return pQ->x == 0.0f && pQ->y == 0.0f && pQ->z == 0.0f && pQ->w == 1.0f; +} + + +D3DXINLINE D3DXQUATERNION* D3DXQuaternionConjugate + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pQ) + return NULL; +#endif + + pOut->x = -pQ->x; + pOut->y = -pQ->y; + pOut->z = -pQ->z; + pOut->w = pQ->w; + return pOut; +} + + +//-------------------------- +// Plane +//-------------------------- + +D3DXINLINE FLOAT D3DXPlaneDot + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV) +{ +#ifdef D3DX_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d * pV->w; +} + +D3DXINLINE FLOAT D3DXPlaneDotCoord + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV) +{ +#ifdef D3DX_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d; +} + +D3DXINLINE FLOAT D3DXPlaneDotNormal + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV) +{ +#ifdef D3DX_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z; +} + +D3DXINLINE D3DXPLANE* D3DXPlaneScale + (D3DXPLANE *pOut, CONST D3DXPLANE *pP, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pP) + return NULL; +#endif + + pOut->a = pP->a * s; + pOut->b = pP->b * s; + pOut->c = pP->c * s; + pOut->d = pP->d * s; + return pOut; +} + + +//-------------------------- +// Color +//-------------------------- + +D3DXINLINE D3DXCOLOR* D3DXColorNegative + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC) + return NULL; +#endif + + pOut->r = 1.0f - pC->r; + pOut->g = 1.0f - pC->g; + pOut->b = 1.0f - pC->b; + pOut->a = pC->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorAdd + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r + pC2->r; + pOut->g = pC1->g + pC2->g; + pOut->b = pC1->b + pC2->b; + pOut->a = pC1->a + pC2->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorSubtract + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r - pC2->r; + pOut->g = pC1->g - pC2->g; + pOut->b = pC1->b - pC2->b; + pOut->a = pC1->a - pC2->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorScale + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC) + return NULL; +#endif + + pOut->r = pC->r * s; + pOut->g = pC->g * s; + pOut->b = pC->b * s; + pOut->a = pC->a * s; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorModulate + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r * pC2->r; + pOut->g = pC1->g * pC2->g; + pOut->b = pC1->b * pC2->b; + pOut->a = pC1->a * pC2->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorLerp + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r + s * (pC2->r - pC1->r); + pOut->g = pC1->g + s * (pC2->g - pC1->g); + pOut->b = pC1->b + s * (pC2->b - pC1->b); + pOut->a = pC1->a + s * (pC2->a - pC1->a); + return pOut; +} + + +#endif // __D3DX9MATH_INL__ + diff --git a/dxsdk/Include/d3dx9mesh.h b/dxsdk/Include/d3dx9mesh.h new file mode 100644 index 0000000..a009d9a --- /dev/null +++ b/dxsdk/Include/d3dx9mesh.h @@ -0,0 +1,3007 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9mesh.h +// Content: D3DX mesh types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9MESH_H__ +#define __D3DX9MESH_H__ + +// {7ED943DD-52E8-40b5-A8D8-76685C406330} +DEFINE_GUID(IID_ID3DXBaseMesh, +0x7ed943dd, 0x52e8, 0x40b5, 0xa8, 0xd8, 0x76, 0x68, 0x5c, 0x40, 0x63, 0x30); + +// {4020E5C2-1403-4929-883F-E2E849FAC195} +DEFINE_GUID(IID_ID3DXMesh, +0x4020e5c2, 0x1403, 0x4929, 0x88, 0x3f, 0xe2, 0xe8, 0x49, 0xfa, 0xc1, 0x95); + +// {8875769A-D579-4088-AAEB-534D1AD84E96} +DEFINE_GUID(IID_ID3DXPMesh, +0x8875769a, 0xd579, 0x4088, 0xaa, 0xeb, 0x53, 0x4d, 0x1a, 0xd8, 0x4e, 0x96); + +// {667EA4C7-F1CD-4386-B523-7C0290B83CC5} +DEFINE_GUID(IID_ID3DXSPMesh, +0x667ea4c7, 0xf1cd, 0x4386, 0xb5, 0x23, 0x7c, 0x2, 0x90, 0xb8, 0x3c, 0xc5); + +// {11EAA540-F9A6-4d49-AE6A-E19221F70CC4} +DEFINE_GUID(IID_ID3DXSkinInfo, +0x11eaa540, 0xf9a6, 0x4d49, 0xae, 0x6a, 0xe1, 0x92, 0x21, 0xf7, 0xc, 0xc4); + +// {3CE6CC22-DBF2-44f4-894D-F9C34A337139} +DEFINE_GUID(IID_ID3DXPatchMesh, +0x3ce6cc22, 0xdbf2, 0x44f4, 0x89, 0x4d, 0xf9, 0xc3, 0x4a, 0x33, 0x71, 0x39); + +//patch mesh can be quads or tris +typedef enum _D3DXPATCHMESHTYPE { + D3DXPATCHMESH_RECT = 0x001, + D3DXPATCHMESH_TRI = 0x002, + D3DXPATCHMESH_NPATCH = 0x003, + + D3DXPATCHMESH_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXPATCHMESHTYPE; + +// Mesh options - lower 3 bytes only, upper byte used by _D3DXMESHOPT option flags +enum _D3DXMESH { + D3DXMESH_32BIT = 0x001, // If set, then use 32 bit indices, if not set use 16 bit indices. + D3DXMESH_DONOTCLIP = 0x002, // Use D3DUSAGE_DONOTCLIP for VB & IB. + D3DXMESH_POINTS = 0x004, // Use D3DUSAGE_POINTS for VB & IB. + D3DXMESH_RTPATCHES = 0x008, // Use D3DUSAGE_RTPATCHES for VB & IB. + D3DXMESH_NPATCHES = 0x4000,// Use D3DUSAGE_NPATCHES for VB & IB. + D3DXMESH_VB_SYSTEMMEM = 0x010, // Use D3DPOOL_SYSTEMMEM for VB. Overrides D3DXMESH_MANAGEDVERTEXBUFFER + D3DXMESH_VB_MANAGED = 0x020, // Use D3DPOOL_MANAGED for VB. + D3DXMESH_VB_WRITEONLY = 0x040, // Use D3DUSAGE_WRITEONLY for VB. + D3DXMESH_VB_DYNAMIC = 0x080, // Use D3DUSAGE_DYNAMIC for VB. + D3DXMESH_VB_SOFTWAREPROCESSING = 0x8000, // Use D3DUSAGE_SOFTWAREPROCESSING for VB. + D3DXMESH_IB_SYSTEMMEM = 0x100, // Use D3DPOOL_SYSTEMMEM for IB. Overrides D3DXMESH_MANAGEDINDEXBUFFER + D3DXMESH_IB_MANAGED = 0x200, // Use D3DPOOL_MANAGED for IB. + D3DXMESH_IB_WRITEONLY = 0x400, // Use D3DUSAGE_WRITEONLY for IB. + D3DXMESH_IB_DYNAMIC = 0x800, // Use D3DUSAGE_DYNAMIC for IB. + D3DXMESH_IB_SOFTWAREPROCESSING= 0x10000, // Use D3DUSAGE_SOFTWAREPROCESSING for IB. + + D3DXMESH_VB_SHARE = 0x1000, // Valid for Clone* calls only, forces cloned mesh/pmesh to share vertex buffer + + D3DXMESH_USEHWONLY = 0x2000, // Valid for ID3DXSkinInfo::ConvertToBlendedMesh + + // Helper options + D3DXMESH_SYSTEMMEM = 0x110, // D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM + D3DXMESH_MANAGED = 0x220, // D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED + D3DXMESH_WRITEONLY = 0x440, // D3DXMESH_VB_WRITEONLY | D3DXMESH_IB_WRITEONLY + D3DXMESH_DYNAMIC = 0x880, // D3DXMESH_VB_DYNAMIC | D3DXMESH_IB_DYNAMIC + D3DXMESH_SOFTWAREPROCESSING = 0x18000, // D3DXMESH_VB_SOFTWAREPROCESSING | D3DXMESH_IB_SOFTWAREPROCESSING + +}; + +//patch mesh options +enum _D3DXPATCHMESH { + D3DXPATCHMESH_DEFAULT = 000, +}; +// option field values for specifying min value in D3DXGeneratePMesh and D3DXSimplifyMesh +enum _D3DXMESHSIMP +{ + D3DXMESHSIMP_VERTEX = 0x1, + D3DXMESHSIMP_FACE = 0x2, + +}; + +typedef enum _D3DXCLEANTYPE { + D3DXCLEAN_BACKFACING = 0x00000001, + D3DXCLEAN_BOWTIES = 0x00000002, + + // Helper options + D3DXCLEAN_SKINNING = D3DXCLEAN_BACKFACING, // Bowtie cleaning modifies geometry and breaks skinning + D3DXCLEAN_OPTIMIZATION = D3DXCLEAN_BACKFACING, + D3DXCLEAN_SIMPLIFICATION= D3DXCLEAN_BACKFACING | D3DXCLEAN_BOWTIES, +} D3DXCLEANTYPE; + +enum _MAX_FVF_DECL_SIZE +{ + MAX_FVF_DECL_SIZE = MAXD3DDECLLENGTH + 1 // +1 for END +}; + +typedef enum _D3DXTANGENT +{ + D3DXTANGENT_WRAP_U = 0x01, + D3DXTANGENT_WRAP_V = 0x02, + D3DXTANGENT_WRAP_UV = 0x03, + D3DXTANGENT_DONT_NORMALIZE_PARTIALS = 0x04, + D3DXTANGENT_DONT_ORTHOGONALIZE = 0x08, + D3DXTANGENT_ORTHOGONALIZE_FROM_V = 0x010, + D3DXTANGENT_ORTHOGONALIZE_FROM_U = 0x020, + D3DXTANGENT_WEIGHT_BY_AREA = 0x040, + D3DXTANGENT_WEIGHT_EQUAL = 0x080, + D3DXTANGENT_WIND_CW = 0x0100, + D3DXTANGENT_CALCULATE_NORMALS = 0x0200, + D3DXTANGENT_GENERATE_IN_PLACE = 0x0400, +} D3DXTANGENT; + +// D3DXIMT_WRAP_U means the texture wraps in the U direction +// D3DXIMT_WRAP_V means the texture wraps in the V direction +// D3DXIMT_WRAP_UV means the texture wraps in both directions +typedef enum _D3DXIMT +{ + D3DXIMT_WRAP_U = 0x01, + D3DXIMT_WRAP_V = 0x02, + D3DXIMT_WRAP_UV = 0x03, +} D3DXIMT; + +// These options are only valid for UVAtlasCreate and UVAtlasPartition, we may add more for UVAtlasPack if necessary +// D3DXUVATLAS_DEFAULT - Meshes with more than 25k faces go through fast, meshes with fewer than 25k faces go through quality +// D3DXUVATLAS_GEODESIC_FAST - Uses approximations to improve charting speed at the cost of added stretch or more charts. +// D3DXUVATLAS_GEODESIC_QUALITY - Provides better quality charts, but requires more time and memory than fast. +typedef enum _D3DXUVATLAS +{ + D3DXUVATLAS_DEFAULT = 0x00, + D3DXUVATLAS_GEODESIC_FAST = 0x01, + D3DXUVATLAS_GEODESIC_QUALITY = 0x02, +} D3DXUVATLAS; + +typedef struct ID3DXBaseMesh *LPD3DXBASEMESH; +typedef struct ID3DXMesh *LPD3DXMESH; +typedef struct ID3DXPMesh *LPD3DXPMESH; +typedef struct ID3DXSPMesh *LPD3DXSPMESH; +typedef struct ID3DXSkinInfo *LPD3DXSKININFO; +typedef struct ID3DXPatchMesh *LPD3DXPATCHMESH; +typedef interface ID3DXTextureGutterHelper *LPD3DXTEXTUREGUTTERHELPER; +typedef interface ID3DXPRTBuffer *LPD3DXPRTBUFFER; + + +typedef struct _D3DXATTRIBUTERANGE +{ + DWORD AttribId; + DWORD FaceStart; + DWORD FaceCount; + DWORD VertexStart; + DWORD VertexCount; +} D3DXATTRIBUTERANGE; + +typedef D3DXATTRIBUTERANGE* LPD3DXATTRIBUTERANGE; + +typedef struct _D3DXMATERIAL +{ + D3DMATERIAL9 MatD3D; + LPSTR pTextureFilename; +} D3DXMATERIAL; +typedef D3DXMATERIAL *LPD3DXMATERIAL; + +typedef enum _D3DXEFFECTDEFAULTTYPE +{ + D3DXEDT_STRING = 0x1, // pValue points to a null terminated ASCII string + D3DXEDT_FLOATS = 0x2, // pValue points to an array of floats - number of floats is NumBytes / sizeof(float) + D3DXEDT_DWORD = 0x3, // pValue points to a DWORD + + D3DXEDT_FORCEDWORD = 0x7fffffff +} D3DXEFFECTDEFAULTTYPE; + +typedef struct _D3DXEFFECTDEFAULT +{ + LPSTR pParamName; + D3DXEFFECTDEFAULTTYPE Type; // type of the data pointed to by pValue + DWORD NumBytes; // size in bytes of the data pointed to by pValue + LPVOID pValue; // data for the default of the effect +} D3DXEFFECTDEFAULT, *LPD3DXEFFECTDEFAULT; + +typedef struct _D3DXEFFECTINSTANCE +{ + LPSTR pEffectFilename; + DWORD NumDefaults; + LPD3DXEFFECTDEFAULT pDefaults; +} D3DXEFFECTINSTANCE, *LPD3DXEFFECTINSTANCE; + +typedef struct _D3DXATTRIBUTEWEIGHTS +{ + FLOAT Position; + FLOAT Boundary; + FLOAT Normal; + FLOAT Diffuse; + FLOAT Specular; + FLOAT Texcoord[8]; + FLOAT Tangent; + FLOAT Binormal; +} D3DXATTRIBUTEWEIGHTS, *LPD3DXATTRIBUTEWEIGHTS; + +enum _D3DXWELDEPSILONSFLAGS +{ + D3DXWELDEPSILONS_WELDALL = 0x1, // weld all vertices marked by adjacency as being overlapping + + D3DXWELDEPSILONS_WELDPARTIALMATCHES = 0x2, // if a given vertex component is within epsilon, modify partial matched + // vertices so that both components identical AND if all components "equal" + // remove one of the vertices + D3DXWELDEPSILONS_DONOTREMOVEVERTICES = 0x4, // instructs weld to only allow modifications to vertices and not removal + // ONLY valid if D3DXWELDEPSILONS_WELDPARTIALMATCHES is set + // useful to modify vertices to be equal, but not allow vertices to be removed + + D3DXWELDEPSILONS_DONOTSPLIT = 0x8, // instructs weld to specify the D3DXMESHOPT_DONOTSPLIT flag when doing an Optimize(ATTR_SORT) + // if this flag is not set, all vertices that are in separate attribute groups + // will remain split and not welded. Setting this flag can slow down software vertex processing + +}; + +typedef struct _D3DXWELDEPSILONS +{ + FLOAT Position; // NOTE: This does NOT replace the epsilon in GenerateAdjacency + // in general, it should be the same value or greater than the one passed to GeneratedAdjacency + FLOAT BlendWeights; + FLOAT Normal; + FLOAT PSize; + FLOAT Specular; + FLOAT Diffuse; + FLOAT Texcoord[8]; + FLOAT Tangent; + FLOAT Binormal; + FLOAT TessFactor; +} D3DXWELDEPSILONS; + +typedef D3DXWELDEPSILONS* LPD3DXWELDEPSILONS; + + +#undef INTERFACE +#define INTERFACE ID3DXBaseMesh + +DECLARE_INTERFACE_(ID3DXBaseMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + STDMETHOD(UpdateSemantics)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXMesh + +DECLARE_INTERFACE_(ID3DXMesh, ID3DXBaseMesh) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + STDMETHOD(UpdateSemantics)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + + // ID3DXMesh + STDMETHOD(LockAttributeBuffer)(THIS_ DWORD Flags, DWORD** ppData) PURE; + STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; + STDMETHOD(Optimize)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppOptMesh) PURE; + STDMETHOD(OptimizeInplace)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap) PURE; + STDMETHOD(SetAttributeTable)(THIS_ CONST D3DXATTRIBUTERANGE *pAttribTable, DWORD cAttribTableSize) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXPMesh + +DECLARE_INTERFACE_(ID3DXPMesh, ID3DXBaseMesh) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + STDMETHOD(UpdateSemantics)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + + // ID3DXPMesh + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(SetNumFaces)(THIS_ DWORD Faces) PURE; + STDMETHOD(SetNumVertices)(THIS_ DWORD Vertices) PURE; + STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMinFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetMinVertices)(THIS) PURE; + STDMETHOD(Save)(THIS_ IStream *pStream, CONST D3DXMATERIAL* pMaterials, CONST D3DXEFFECTINSTANCE* pEffectInstances, DWORD NumMaterials) PURE; + + STDMETHOD(Optimize)(THIS_ DWORD Flags, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppOptMesh) PURE; + + STDMETHOD(OptimizeBaseLOD)(THIS_ DWORD Flags, DWORD* pFaceRemap) PURE; + STDMETHOD(TrimByFaces)(THIS_ DWORD NewFacesMin, DWORD NewFacesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; + STDMETHOD(TrimByVertices)(THIS_ DWORD NewVerticesMin, DWORD NewVerticesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; + + STDMETHOD(GetAdjacency)(THIS_ DWORD* pAdjacency) PURE; + + // Used to generate the immediate "ancestor" for each vertex when it is removed by a vsplit. Allows generation of geomorphs + // Vertex buffer must be equal to or greater than the maximum number of vertices in the pmesh + STDMETHOD(GenerateVertexHistory)(THIS_ DWORD* pVertexHistory) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXSPMesh + +DECLARE_INTERFACE_(ID3DXSPMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXSPMesh + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pVertexRemapOut, FLOAT *pErrorsByFace, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pVertexRemapOut, FLOAT *pErrorsbyFace, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ReduceFaces)(THIS_ DWORD Faces) PURE; + STDMETHOD(ReduceVertices)(THIS_ DWORD Vertices) PURE; + STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; + STDMETHOD(GetVertexAttributeWeights)(THIS_ LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights) PURE; + STDMETHOD(GetVertexWeights)(THIS_ FLOAT *pVertexWeights) PURE; +}; + +#define UNUSED16 (0xffff) +#define UNUSED32 (0xffffffff) + +// ID3DXMesh::Optimize options - upper byte only, lower 3 bytes used from _D3DXMESH option flags +enum _D3DXMESHOPT { + D3DXMESHOPT_COMPACT = 0x01000000, + D3DXMESHOPT_ATTRSORT = 0x02000000, + D3DXMESHOPT_VERTEXCACHE = 0x04000000, + D3DXMESHOPT_STRIPREORDER = 0x08000000, + D3DXMESHOPT_IGNOREVERTS = 0x10000000, // optimize faces only, don't touch vertices + D3DXMESHOPT_DONOTSPLIT = 0x20000000, // do not split vertices shared between attribute groups when attribute sorting + D3DXMESHOPT_DEVICEINDEPENDENT = 0x00400000, // Only affects VCache. uses a static known good cache size for all cards + + // D3DXMESHOPT_SHAREVB has been removed, please use D3DXMESH_VB_SHARE instead + +}; + +// Subset of the mesh that has the same attribute and bone combination. +// This subset can be rendered in a single draw call +typedef struct _D3DXBONECOMBINATION +{ + DWORD AttribId; + DWORD FaceStart; + DWORD FaceCount; + DWORD VertexStart; + DWORD VertexCount; + DWORD* BoneId; +} D3DXBONECOMBINATION, *LPD3DXBONECOMBINATION; + +// The following types of patch combinations are supported: +// Patch type Basis Degree +// Rect Bezier 2,3,5 +// Rect B-Spline 2,3,5 +// Rect Catmull-Rom 3 +// Tri Bezier 2,3,5 +// N-Patch N/A 3 + +typedef struct _D3DXPATCHINFO +{ + D3DXPATCHMESHTYPE PatchType; + D3DDEGREETYPE Degree; + D3DBASISTYPE Basis; +} D3DXPATCHINFO, *LPD3DXPATCHINFO; + +#undef INTERFACE +#define INTERFACE ID3DXPatchMesh + +DECLARE_INTERFACE_(ID3DXPatchMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXPatchMesh + + // Return creation parameters + STDMETHOD_(DWORD, GetNumPatches)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetControlVerticesPerPatch)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9 *ppDevice) PURE; + STDMETHOD(GetPatchInfo)(THIS_ LPD3DXPATCHINFO PatchInfo) PURE; + + // Control mesh access + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(LockAttributeBuffer)(THIS_ DWORD flags, DWORD** ppData) PURE; + STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; + + // This function returns the size of the tessellated mesh given a tessellation level. + // This assumes uniform tessellation. For adaptive tessellation the Adaptive parameter must + // be set to TRUE and TessellationLevel should be the max tessellation. + // This will result in the max mesh size necessary for adaptive tessellation. + STDMETHOD(GetTessSize)(THIS_ FLOAT fTessLevel,DWORD Adaptive, DWORD *NumTriangles,DWORD *NumVertices) PURE; + + //GenerateAdjacency determines which patches are adjacent with provided tolerance + //this information is used internally to optimize tessellation + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Tolerance) PURE; + + //CloneMesh Creates a new patchmesh with the specified decl, and converts the vertex buffer + //to the new decl. Entries in the new decl which are new are set to 0. If the current mesh + //has adjacency, the new mesh will also have adjacency + STDMETHOD(CloneMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDecl, LPD3DXPATCHMESH *pMesh) PURE; + + // Optimizes the patchmesh for efficient tessellation. This function is designed + // to perform one time optimization for patch meshes that need to be tessellated + // repeatedly by calling the Tessellate() method. The optimization performed is + // independent of the actual tessellation level used. + // Currently Flags is unused. + // If vertices are changed, Optimize must be called again + STDMETHOD(Optimize)(THIS_ DWORD flags) PURE; + + //gets and sets displacement parameters + //displacement maps can only be 2D textures MIP-MAPPING is ignored for non adapative tessellation + STDMETHOD(SetDisplaceParam)(THIS_ LPDIRECT3DBASETEXTURE9 Texture, + D3DTEXTUREFILTERTYPE MinFilter, + D3DTEXTUREFILTERTYPE MagFilter, + D3DTEXTUREFILTERTYPE MipFilter, + D3DTEXTUREADDRESS Wrap, + DWORD dwLODBias) PURE; + + STDMETHOD(GetDisplaceParam)(THIS_ LPDIRECT3DBASETEXTURE9 *Texture, + D3DTEXTUREFILTERTYPE *MinFilter, + D3DTEXTUREFILTERTYPE *MagFilter, + D3DTEXTUREFILTERTYPE *MipFilter, + D3DTEXTUREADDRESS *Wrap, + DWORD *dwLODBias) PURE; + + // Performs the uniform tessellation based on the tessellation level. + // This function will perform more efficiently if the patch mesh has been optimized using the Optimize() call. + STDMETHOD(Tessellate)(THIS_ FLOAT fTessLevel,LPD3DXMESH pMesh) PURE; + + // Performs adaptive tessellation based on the Z based adaptive tessellation criterion. + // pTrans specifies a 4D vector that is dotted with the vertices to get the per vertex + // adaptive tessellation amount. Each edge is tessellated to the average of the criterion + // at the 2 vertices it connects. + // MaxTessLevel specifies the upper limit for adaptive tesselation. + // This function will perform more efficiently if the patch mesh has been optimized using the Optimize() call. + STDMETHOD(TessellateAdaptive)(THIS_ + CONST D3DXVECTOR4 *pTrans, + DWORD dwMaxTessLevel, + DWORD dwMinTessLevel, + LPD3DXMESH pMesh) PURE; + +}; + +#undef INTERFACE +#define INTERFACE ID3DXSkinInfo + +DECLARE_INTERFACE_(ID3DXSkinInfo, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Specify the which vertices do each bones influence and by how much + STDMETHOD(SetBoneInfluence)(THIS_ DWORD bone, DWORD numInfluences, CONST DWORD* vertices, CONST FLOAT* weights) PURE; + STDMETHOD(SetBoneVertexInfluence)(THIS_ DWORD boneNum, DWORD influenceNum, float weight) PURE; + STDMETHOD_(DWORD, GetNumBoneInfluences)(THIS_ DWORD bone) PURE; + STDMETHOD(GetBoneInfluence)(THIS_ DWORD bone, DWORD* vertices, FLOAT* weights) PURE; + STDMETHOD(GetBoneVertexInfluence)(THIS_ DWORD boneNum, DWORD influenceNum, float *pWeight, DWORD *pVertexNum) PURE; + STDMETHOD(GetMaxVertexInfluences)(THIS_ DWORD* maxVertexInfluences) PURE; + STDMETHOD_(DWORD, GetNumBones)(THIS) PURE; + STDMETHOD(FindBoneVertexInfluenceIndex)(THIS_ DWORD boneNum, DWORD vertexNum, DWORD *pInfluenceIndex) PURE; + + // This gets the max face influences based on a triangle mesh with the specified index buffer + STDMETHOD(GetMaxFaceInfluences)(THIS_ LPDIRECT3DINDEXBUFFER9 pIB, DWORD NumFaces, DWORD* maxFaceInfluences) PURE; + + // Set min bone influence. Bone influences that are smaller than this are ignored + STDMETHOD(SetMinBoneInfluence)(THIS_ FLOAT MinInfl) PURE; + // Get min bone influence. + STDMETHOD_(FLOAT, GetMinBoneInfluence)(THIS) PURE; + + // Bone names are returned by D3DXLoadSkinMeshFromXof. They are not used by any other method of this object + STDMETHOD(SetBoneName)(THIS_ DWORD Bone, LPCSTR pName) PURE; // pName is copied to an internal string buffer + STDMETHOD_(LPCSTR, GetBoneName)(THIS_ DWORD Bone) PURE; // A pointer to an internal string buffer is returned. Do not free this. + + // Bone offset matrices are returned by D3DXLoadSkinMeshFromXof. They are not used by any other method of this object + STDMETHOD(SetBoneOffsetMatrix)(THIS_ DWORD Bone, CONST D3DXMATRIX *pBoneTransform) PURE; // pBoneTransform is copied to an internal buffer + STDMETHOD_(LPD3DXMATRIX, GetBoneOffsetMatrix)(THIS_ DWORD Bone) PURE; // A pointer to an internal matrix is returned. Do not free this. + + // Clone a skin info object + STDMETHOD(Clone)(THIS_ LPD3DXSKININFO* ppSkinInfo) PURE; + + // Update bone influence information to match vertices after they are reordered. This should be called + // if the target vertex buffer has been reordered externally. + STDMETHOD(Remap)(THIS_ DWORD NumVertices, DWORD* pVertexRemap) PURE; + + // These methods enable the modification of the vertex layout of the vertices that will be skinned + STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE; + STDMETHOD(SetDeclaration)(THIS_ CONST D3DVERTEXELEMENT9 *pDeclaration) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + + // Apply SW skinning based on current pose matrices to the target vertices. + STDMETHOD(UpdateSkinnedMesh)(THIS_ + CONST D3DXMATRIX* pBoneTransforms, + CONST D3DXMATRIX* pBoneInvTransposeTransforms, + LPCVOID pVerticesSrc, + PVOID pVerticesDst) PURE; + + // Takes a mesh and returns a new mesh with per vertex blend weights and a bone combination + // table that describes which bones affect which subsets of the mesh + STDMETHOD(ConvertToBlendedMesh)(THIS_ + LPD3DXMESH pMesh, + DWORD Options, + CONST DWORD *pAdjacencyIn, + LPDWORD pAdjacencyOut, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, + DWORD* pMaxFaceInfl, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, + LPD3DXMESH* ppMesh) PURE; + + // Takes a mesh and returns a new mesh with per vertex blend weights and indices + // and a bone combination table that describes which bones palettes affect which subsets of the mesh + STDMETHOD(ConvertToIndexedBlendedMesh)(THIS_ + LPD3DXMESH pMesh, + DWORD Options, + DWORD paletteSize, + CONST DWORD *pAdjacencyIn, + LPDWORD pAdjacencyOut, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, + DWORD* pMaxVertexInfl, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, + LPD3DXMESH* ppMesh) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DXCreateMesh( + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXCreateMeshFVF( + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + DWORD FVF, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXCreateSPMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + LPD3DXSPMESH* ppSMesh); + +// clean a mesh up for simplification, try to make manifold +HRESULT WINAPI + D3DXCleanMesh( + D3DXCLEANTYPE CleanType, + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacencyIn, + LPD3DXMESH* ppMeshOut, + DWORD* pAdjacencyOut, + LPD3DXBUFFER* ppErrorsAndWarnings); + +HRESULT WINAPI + D3DXValidMesh( + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacency, + LPD3DXBUFFER* ppErrorsAndWarnings); + +HRESULT WINAPI + D3DXGeneratePMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + DWORD MinValue, + DWORD Options, + LPD3DXPMESH* ppPMesh); + +HRESULT WINAPI + D3DXSimplifyMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + DWORD MinValue, + DWORD Options, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXComputeBoundingSphere( + CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position + DWORD NumVertices, + DWORD dwStride, // count in bytes to subsequent position vectors + D3DXVECTOR3 *pCenter, + FLOAT *pRadius); + +HRESULT WINAPI + D3DXComputeBoundingBox( + CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position + DWORD NumVertices, + DWORD dwStride, // count in bytes to subsequent position vectors + D3DXVECTOR3 *pMin, + D3DXVECTOR3 *pMax); + +HRESULT WINAPI + D3DXComputeNormals( + LPD3DXBASEMESH pMesh, + CONST DWORD *pAdjacency); + +HRESULT WINAPI + D3DXCreateBuffer( + DWORD NumBytes, + LPD3DXBUFFER *ppBuffer); + + +HRESULT WINAPI + D3DXLoadMeshFromXA( + LPCSTR pFilename, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXLoadMeshFromXW( + LPCWSTR pFilename, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +#ifdef UNICODE +#define D3DXLoadMeshFromX D3DXLoadMeshFromXW +#else +#define D3DXLoadMeshFromX D3DXLoadMeshFromXA +#endif + +HRESULT WINAPI + D3DXLoadMeshFromXInMemory( + LPCVOID Memory, + DWORD SizeOfMemory, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXLoadMeshFromXResource( + HMODULE Module, + LPCSTR Name, + LPCSTR Type, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXSaveMeshToXA( + LPCSTR pFilename, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXMATERIAL* pMaterials, + CONST D3DXEFFECTINSTANCE* pEffectInstances, + DWORD NumMaterials, + DWORD Format + ); + +HRESULT WINAPI + D3DXSaveMeshToXW( + LPCWSTR pFilename, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXMATERIAL* pMaterials, + CONST D3DXEFFECTINSTANCE* pEffectInstances, + DWORD NumMaterials, + DWORD Format + ); + +#ifdef UNICODE +#define D3DXSaveMeshToX D3DXSaveMeshToXW +#else +#define D3DXSaveMeshToX D3DXSaveMeshToXA +#endif + + +HRESULT WINAPI + D3DXCreatePMeshFromStream( + IStream *pStream, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD* pNumMaterials, + LPD3DXPMESH *ppPMesh); + +// Creates a skin info object based on the number of vertices, number of bones, and a declaration describing the vertex layout of the target vertices +// The bone names and initial bone transforms are not filled in the skin info object by this method. +HRESULT WINAPI + D3DXCreateSkinInfo( + DWORD NumVertices, + CONST D3DVERTEXELEMENT9 *pDeclaration, + DWORD NumBones, + LPD3DXSKININFO* ppSkinInfo); + +// Creates a skin info object based on the number of vertices, number of bones, and a FVF describing the vertex layout of the target vertices +// The bone names and initial bone transforms are not filled in the skin info object by this method. +HRESULT WINAPI + D3DXCreateSkinInfoFVF( + DWORD NumVertices, + DWORD FVF, + DWORD NumBones, + LPD3DXSKININFO* ppSkinInfo); + +#ifdef __cplusplus +} + +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXLoadMeshFromXof( + LPD3DXFILEDATA pxofMesh, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +// This similar to D3DXLoadMeshFromXof, except also returns skinning info if present in the file +// If skinning info is not present, ppSkinInfo will be NULL +HRESULT WINAPI + D3DXLoadSkinMeshFromXof( + LPD3DXFILEDATA pxofMesh, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER* ppAdjacency, + LPD3DXBUFFER* ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pMatOut, + LPD3DXSKININFO* ppSkinInfo, + LPD3DXMESH* ppMesh); + + +// The inverse of D3DXConvertTo{Indexed}BlendedMesh() functions. It figures out the skinning info from +// the mesh and the bone combination table and populates a skin info object with that data. The bone +// names and initial bone transforms are not filled in the skin info object by this method. This works +// with either a non-indexed or indexed blended mesh. It examines the FVF or declarator of the mesh to +// determine what type it is. +HRESULT WINAPI + D3DXCreateSkinInfoFromBlendedMesh( + LPD3DXBASEMESH pMesh, + DWORD NumBones, + CONST D3DXBONECOMBINATION *pBoneCombinationTable, + LPD3DXSKININFO* ppSkinInfo); + +HRESULT WINAPI + D3DXTessellateNPatches( + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacencyIn, + FLOAT NumSegs, + BOOL QuadraticInterpNormals, // if false use linear intrep for normals, if true use quadratic + LPD3DXMESH *ppMeshOut, + LPD3DXBUFFER *ppAdjacencyOut); + + +//generates implied outputdecl from input decl +//the decl generated from this should be used to generate the output decl for +//the tessellator subroutines. + +HRESULT WINAPI + D3DXGenerateOutputDecl( + D3DVERTEXELEMENT9 *pOutput, + CONST D3DVERTEXELEMENT9 *pInput); + +//loads patches from an XFileData +//since an X file can have up to 6 different patch meshes in it, +//returns them in an array - pNumPatches will contain the number of +//meshes in the actual file. +HRESULT WINAPI + D3DXLoadPatchMeshFromXof( + LPD3DXFILEDATA pXofObjMesh, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + PDWORD pNumMaterials, + LPD3DXPATCHMESH *ppMesh); + +//computes the size a single rect patch. +HRESULT WINAPI + D3DXRectPatchSize( + CONST FLOAT *pfNumSegs, //segments for each edge (4) + DWORD *pdwTriangles, //output number of triangles + DWORD *pdwVertices); //output number of vertices + +//computes the size of a single triangle patch +HRESULT WINAPI + D3DXTriPatchSize( + CONST FLOAT *pfNumSegs, //segments for each edge (3) + DWORD *pdwTriangles, //output number of triangles + DWORD *pdwVertices); //output number of vertices + + +//tessellates a patch into a created mesh +//similar to D3D RT patch +HRESULT WINAPI + D3DXTessellateRectPatch( + LPDIRECT3DVERTEXBUFFER9 pVB, + CONST FLOAT *pNumSegs, + CONST D3DVERTEXELEMENT9 *pdwInDecl, + CONST D3DRECTPATCH_INFO *pRectPatchInfo, + LPD3DXMESH pMesh); + + +HRESULT WINAPI + D3DXTessellateTriPatch( + LPDIRECT3DVERTEXBUFFER9 pVB, + CONST FLOAT *pNumSegs, + CONST D3DVERTEXELEMENT9 *pInDecl, + CONST D3DTRIPATCH_INFO *pTriPatchInfo, + LPD3DXMESH pMesh); + + + +//creates an NPatch PatchMesh from a D3DXMESH +HRESULT WINAPI + D3DXCreateNPatchMesh( + LPD3DXMESH pMeshSysMem, + LPD3DXPATCHMESH *pPatchMesh); + + +//creates a patch mesh +HRESULT WINAPI + D3DXCreatePatchMesh( + CONST D3DXPATCHINFO *pInfo, //patch type + DWORD dwNumPatches, //number of patches + DWORD dwNumVertices, //number of control vertices + DWORD dwOptions, //options + CONST D3DVERTEXELEMENT9 *pDecl, //format of control vertices + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXPATCHMESH *pPatchMesh); + + +//returns the number of degenerates in a patch mesh - +//text output put in string. +HRESULT WINAPI + D3DXValidPatchMesh(LPD3DXPATCHMESH pMesh, + DWORD *dwcDegenerateVertices, + DWORD *dwcDegeneratePatches, + LPD3DXBUFFER *ppErrorsAndWarnings); + +UINT WINAPI + D3DXGetFVFVertexSize(DWORD FVF); + +UINT WINAPI + D3DXGetDeclVertexSize(CONST D3DVERTEXELEMENT9 *pDecl,DWORD Stream); + +UINT WINAPI + D3DXGetDeclLength(CONST D3DVERTEXELEMENT9 *pDecl); + +HRESULT WINAPI + D3DXDeclaratorFromFVF( + DWORD FVF, + D3DVERTEXELEMENT9 pDeclarator[MAX_FVF_DECL_SIZE]); + +HRESULT WINAPI + D3DXFVFFromDeclarator( + CONST D3DVERTEXELEMENT9 *pDeclarator, + DWORD *pFVF); + +HRESULT WINAPI + D3DXWeldVertices( + LPD3DXMESH pMesh, + DWORD Flags, + CONST D3DXWELDEPSILONS *pEpsilons, + CONST DWORD *pAdjacencyIn, + DWORD *pAdjacencyOut, + DWORD *pFaceRemap, + LPD3DXBUFFER *ppVertexRemap); + +typedef struct _D3DXINTERSECTINFO +{ + DWORD FaceIndex; // index of face intersected + FLOAT U; // Barycentric Hit Coordinates + FLOAT V; // Barycentric Hit Coordinates + FLOAT Dist; // Ray-Intersection Parameter Distance +} D3DXINTERSECTINFO, *LPD3DXINTERSECTINFO; + + +HRESULT WINAPI + D3DXIntersect( + LPD3DXBASEMESH pMesh, + CONST D3DXVECTOR3 *pRayPos, + CONST D3DXVECTOR3 *pRayDir, + BOOL *pHit, // True if any faces were intersected + DWORD *pFaceIndex, // index of closest face intersected + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist, // Ray-Intersection Parameter Distance + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + DWORD *pCountOfHits); // Number of entries in AllHits array + +HRESULT WINAPI + D3DXIntersectSubset( + LPD3DXBASEMESH pMesh, + DWORD AttribId, + CONST D3DXVECTOR3 *pRayPos, + CONST D3DXVECTOR3 *pRayDir, + BOOL *pHit, // True if any faces were intersected + DWORD *pFaceIndex, // index of closest face intersected + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist, // Ray-Intersection Parameter Distance + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + DWORD *pCountOfHits); // Number of entries in AllHits array + + +HRESULT WINAPI D3DXSplitMesh + ( + LPD3DXMESH pMeshIn, + CONST DWORD *pAdjacencyIn, + CONST DWORD MaxSize, + CONST DWORD Options, + DWORD *pMeshesOut, + LPD3DXBUFFER *ppMeshArrayOut, + LPD3DXBUFFER *ppAdjacencyArrayOut, + LPD3DXBUFFER *ppFaceRemapArrayOut, + LPD3DXBUFFER *ppVertRemapArrayOut + ); + +BOOL WINAPI D3DXIntersectTri +( + CONST D3DXVECTOR3 *p0, // Triangle vertex 0 position + CONST D3DXVECTOR3 *p1, // Triangle vertex 1 position + CONST D3DXVECTOR3 *p2, // Triangle vertex 2 position + CONST D3DXVECTOR3 *pRayPos, // Ray origin + CONST D3DXVECTOR3 *pRayDir, // Ray direction + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist); // Ray-Intersection Parameter Distance + +BOOL WINAPI + D3DXSphereBoundProbe( + CONST D3DXVECTOR3 *pCenter, + FLOAT Radius, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + +BOOL WINAPI + D3DXBoxBoundProbe( + CONST D3DXVECTOR3 *pMin, + CONST D3DXVECTOR3 *pMax, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + + +HRESULT WINAPI D3DXComputeTangentFrame(ID3DXMesh *pMesh, + DWORD dwOptions); + +HRESULT WINAPI D3DXComputeTangentFrameEx(ID3DXMesh *pMesh, + DWORD dwTextureInSemantic, + DWORD dwTextureInIndex, + DWORD dwUPartialOutSemantic, + DWORD dwUPartialOutIndex, + DWORD dwVPartialOutSemantic, + DWORD dwVPartialOutIndex, + DWORD dwNormalOutSemantic, + DWORD dwNormalOutIndex, + DWORD dwOptions, + CONST DWORD *pdwAdjacency, + FLOAT fPartialEdgeThreshold, + FLOAT fSingularPointThreshold, + FLOAT fNormalEdgeThreshold, + ID3DXMesh **ppMeshOut, + ID3DXBuffer **ppVertexMapping); + + +//D3DXComputeTangent +// +//Computes the Tangent vectors for the TexStage texture coordinates +//and places the results in the TANGENT[TangentIndex] specified in the meshes' DECL +//puts the binorm in BINORM[BinormIndex] also specified in the decl. +// +//If neither the binorm or the tangnet are in the meshes declaration, +//the function will fail. +// +//If a tangent or Binorm field is in the Decl, but the user does not +//wish D3DXComputeTangent to replace them, then D3DX_DEFAULT specified +//in the TangentIndex or BinormIndex will cause it to ignore the specified +//semantic. +// +//Wrap should be specified if the texture coordinates wrap. + +HRESULT WINAPI D3DXComputeTangent(LPD3DXMESH Mesh, + DWORD TexStage, + DWORD TangentIndex, + DWORD BinormIndex, + DWORD Wrap, + CONST DWORD *pAdjacency); + +//============================================================================ +// +// UVAtlas apis +// +//============================================================================ +typedef HRESULT (WINAPI *LPD3DXUVATLASCB)(FLOAT fPercentDone, LPVOID lpUserContext); + +// This function creates atlases for meshes. There are two modes of operation, +// either based on the number of charts, or the maximum allowed stretch. If the +// maximum allowed stretch is 0, then each triangle will likely be in its own +// chart. + +// +// The parameters are as follows: +// pMesh - Input mesh to calculate an atlas for. This must have a position +// channel and at least a 2-d texture channel. +// uMaxChartNumber - The maximum number of charts required for the atlas. +// If this is 0, it will be parameterized based solely on +// stretch. +// fMaxStretch - The maximum amount of stretch, if 0, no stretching is allowed, +// if 1, then any amount of stretching is allowed. +// uWidth - The width of the texture the atlas will be used on. +// uHeight - The height of the texture the atlas will be used on. +// fGutter - The minimum distance, in texels between two charts on the atlas. +// this gets scaled by the width, so if fGutter is 2.5, and it is +// used on a 512x512 texture, then the minimum distance will be +// 2.5 / 512 in u-v space. +// dwTextureIndex - Specifies which texture coordinate to write to in the +// output mesh (which is cloned from the input mesh). Useful +// if your vertex has multiple texture coordinates. +// pdwAdjacency - a pointer to an array with 3 DWORDs per face, indicating +// which triangles are adjacent to each other. +// pdwFalseEdgeAdjacency - a pointer to an array with 3 DWORDS per face, indicating +// at each face, whether an edge is a false edge or not (using +// the same ordering as the adjacency data structure). If this +// is NULL, then it is assumed that there are no false edges. If +// not NULL, then a non-false edge is indicated by -1 and a false +// edge is indicated by any other value (it is not required, but +// it may be useful for the caller to use the original adjacency +// value). This allows you to parameterize a mesh of quads, and +// the edges down the middle of each quad will not be cut when +// parameterizing the mesh. +// pfIMTArray - a pointer to an array with 3 FLOATs per face, describing the +// integrated metric tensor for that face. This lets you control +// the way this triangle may be stretched in the atlas. The IMT +// passed in will be 3 floats (a,b,c) and specify a symmetric +// matrix (a b) that, given a vector (s,t), specifies the +// (b c) +// distance between a vector v1 and a vector v2 = v1 + (s,t) as +// sqrt((s, t) * M * (s, t)^T). +// In other words, this lets one specify the magnitude of the +// stretch in an arbitrary direction in u-v space. For example +// if a = b = c = 1, then this scales the vector (1,1) by 2, and +// the vector (1,-1) by 0. Note that this is multiplying the edge +// length by the square of the matrix, so if you want the face to +// stretch to twice its +// size with no shearing, the IMT value should be (2, 0, 2), which +// is just the identity matrix times 2. +// Note that this assumes you have an orientation for the triangle +// in some 2-D space. For D3DXUVAtlas, this space is created by +// letting S be the direction from the first to the second +// vertex, and T be the cross product between the normal and S. +// +// pStatusCallback - Since the atlas creation process can be very CPU intensive, +// this allows the programmer to specify a function to be called +// periodically, similarly to how it is done in the PRT simulation +// engine. +// fCallbackFrequency - This lets you specify how often the callback will be +// called. A decent default should be 0.0001f. +// pUserContext - a void pointer to be passed back to the callback function +// dwOptions - A combination of flags in the D3DXUVATLAS enum +// ppMeshOut - A pointer to a location to store a pointer for the newly created +// mesh. +// ppFacePartitioning - A pointer to a location to store a pointer for an array, +// one DWORD per face, giving the final partitioning +// created by the atlasing algorithm. +// ppVertexRemapArray - A pointer to a location to store a pointer for an array, +// one DWORD per vertex, giving the vertex it was copied +// from, if any vertices needed to be split. +// pfMaxStretchOut - A location to store the maximum stretch resulting from the +// atlasing algorithm. +// puNumChartsOut - A location to store the number of charts created, or if the +// maximum number of charts was too low, this gives the minimum +// number of charts needed to create an atlas. + +HRESULT WINAPI D3DXUVAtlasCreate(LPD3DXMESH pMesh, + UINT uMaxChartNumber, + FLOAT fMaxStretch, + UINT uWidth, + UINT uHeight, + FLOAT fGutter, + DWORD dwTextureIndex, + CONST DWORD *pdwAdjacency, + CONST DWORD *pdwFalseEdgeAdjacency, + CONST FLOAT *pfIMTArray, + LPD3DXUVATLASCB pStatusCallback, + FLOAT fCallbackFrequency, + LPVOID pUserContext, + DWORD dwOptions, + LPD3DXMESH *ppMeshOut, + LPD3DXBUFFER *ppFacePartitioning, + LPD3DXBUFFER *ppVertexRemapArray, + FLOAT *pfMaxStretchOut, + UINT *puNumChartsOut); + +// This has the same exact arguments as Create, except that it does not perform the +// final packing step. This method allows one to get a partitioning out, and possibly +// modify it before sending it to be repacked. Note that if you change the +// partitioning, you'll also need to calculate new texture coordinates for any faces +// that have switched charts. +// +// The partition result adjacency output parameter is meant to be passed to the +// UVAtlasPack function, this adjacency cuts edges that are between adjacent +// charts, and also can include cuts inside of a chart in order to make it +// equivalent to a disc. For example: +// +// _______ +// | ___ | +// | |_| | +// |_____| +// +// In order to make this equivalent to a disc, we would need to add a cut, and it +// Would end up looking like: +// _______ +// | ___ | +// | |_|_| +// |_____| +// +// The resulting partition adjacency parameter cannot be NULL, because it is +// required for the packing step. + + + +HRESULT WINAPI D3DXUVAtlasPartition(LPD3DXMESH pMesh, + UINT uMaxChartNumber, + FLOAT fMaxStretch, + DWORD dwTextureIndex, + CONST DWORD *pdwAdjacency, + CONST DWORD *pdwFalseEdgeAdjacency, + CONST FLOAT *pfIMTArray, + LPD3DXUVATLASCB pStatusCallback, + FLOAT fCallbackFrequency, + LPVOID pUserContext, + DWORD dwOptions, + LPD3DXMESH *ppMeshOut, + LPD3DXBUFFER *ppFacePartitioning, + LPD3DXBUFFER *ppVertexRemapArray, + LPD3DXBUFFER *ppPartitionResultAdjacency, + FLOAT *pfMaxStretchOut, + UINT *puNumChartsOut); + +// This takes the face partitioning result from Partition and packs it into an +// atlas of the given size. pdwPartitionResultAdjacency should be derived from +// the adjacency returned from the partition step. This value cannot be NULL +// because Pack needs to know where charts were cut in the partition step in +// order to find the edges of each chart. +// The options parameter is currently reserved. +HRESULT WINAPI D3DXUVAtlasPack(ID3DXMesh *pMesh, + UINT uWidth, + UINT uHeight, + FLOAT fGutter, + DWORD dwTextureIndex, + CONST DWORD *pdwPartitionResultAdjacency, + LPD3DXUVATLASCB pStatusCallback, + FLOAT fCallbackFrequency, + LPVOID pUserContext, + DWORD dwOptions, + LPD3DXBUFFER pFacePartitioning); + + +//============================================================================ +// +// IMT Calculation apis +// +// These functions all compute the Integrated Metric Tensor for use in the +// UVAtlas API. They all calculate the IMT with respect to the canonical +// triangle, where the coordinate system is set up so that the u axis goes +// from vertex 0 to 1 and the v axis is N x u. So, for example, the second +// vertex's canonical uv coordinates are (d,0) where d is the distance between +// vertices 0 and 1. This way the IMT does not depend on the parameterization +// of the mesh, and if the signal over the surface doesn't change, then +// the IMT doesn't need to be recalculated. +//============================================================================ + +// This callback is used by D3DXComputeIMTFromSignal. +// +// uv - The texture coordinate for the vertex. +// uPrimitiveID - Face ID of the triangle on which to compute the signal. +// uSignalDimension - The number of floats to store in pfSignalOut. +// pUserData - The pUserData pointer passed in to ComputeIMTFromSignal. +// pfSignalOut - A pointer to where to store the signal data. +typedef HRESULT (WINAPI* LPD3DXIMTSIGNALCALLBACK) + (CONST D3DXVECTOR2 *uv, + UINT uPrimitiveID, + UINT uSignalDimension, + VOID *pUserData, + FLOAT *pfSignalOut); + +// This function is used to calculate the IMT from per vertex data. It sets +// up a linear system over the triangle, solves for the jacobian J, then +// constructs the IMT from that (J^TJ). +// This function allows you to calculate the IMT based off of any value in a +// mesh (color, normal, etc) by specifying the correct stride of the array. +// The IMT computed will cause areas of the mesh that have similar values to +// take up less space in the texture. +// +// pMesh - The mesh to calculate the IMT for. +// pVertexSignal - A float array of size uSignalStride * v, where v is the +// number of vertices in the mesh. +// uSignalDimension - How many floats per vertex to use in calculating the IMT. +// uSignalStride - The number of bytes per vertex in the array. This must be +// a multiple of sizeof(float) +// ppIMTData - Where to store the buffer holding the IMT data + +HRESULT WINAPI D3DXComputeIMTFromPerVertexSignal ( + LPD3DXMESH pMesh, + CONST FLOAT *pfVertexSignal, // uSignalDimension floats per vertex + UINT uSignalDimension, + UINT uSignalStride, // stride of signal in bytes + DWORD dwOptions, // reserved for future use + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +// This function is used to calculate the IMT from data that varies over the +// surface of the mesh (generally at a higher frequency than vertex data). +// This function requires the mesh to already be parameterized (so it already +// has texture coordinates). It allows the user to define a signal arbitrarily +// over the surface of the mesh. +// +// pMesh - The mesh to calculate the IMT for. +// dwTextureIndex - This describes which set of texture coordinates in the +// mesh to use. +// uSignalDimension - How many components there are in the signal. +// fMaxUVDistance - The subdivision will continue until the distance between +// all vertices is at most fMaxUVDistance. +// dwOptions - reserved for future use +// pSignalCallback - The callback to use to get the signal. +// pUserData - A pointer that will be passed in to the callback. +// ppIMTData - Where to store the buffer holding the IMT data +HRESULT WINAPI D3DXComputeIMTFromSignal( + LPD3DXMESH pMesh, + DWORD dwTextureIndex, + UINT uSignalDimension, + FLOAT fMaxUVDistance, + DWORD dwOptions, // reserved for future use + LPD3DXIMTSIGNALCALLBACK pSignalCallback, + VOID *pUserData, + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +// This function is used to calculate the IMT from texture data. Given a texture +// that maps over the surface of the mesh, the algorithm computes the IMT for +// each face. This will cause large areas that are very similar to take up less +// room when parameterized with UVAtlas. The texture is assumed to be +// interpolated over the mesh bilinearly. +// +// pMesh - The mesh to calculate the IMT for. +// pTexture - The texture to load data from. +// dwTextureIndex - This describes which set of texture coordinates in the +// mesh to use. +// dwOptions - Combination of one or more D3DXIMT flags. +// ppIMTData - Where to store the buffer holding the IMT data +HRESULT WINAPI D3DXComputeIMTFromTexture ( + LPD3DXMESH pMesh, + LPDIRECT3DTEXTURE9 pTexture, + DWORD dwTextureIndex, + DWORD dwOptions, + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +// This function is very similar to ComputeIMTFromTexture, but it uses a +// float array to pass in the data, and it can calculate higher dimensional +// values than 4. +// +// pMesh - The mesh to calculate the IMT for. +// dwTextureIndex - This describes which set of texture coordinates in the +// mesh to use. +// pfFloatArray - a pointer to a float array of size +// uWidth*uHeight*uComponents +// uWidth - The width of the texture +// uHeight - The height of the texture +// uSignalDimension - The number of floats per texel in the signal +// uComponents - The number of floats in each texel +// dwOptions - Combination of one or more D3DXIMT flags +// ppIMTData - Where to store the buffer holding the IMT data +HRESULT WINAPI D3DXComputeIMTFromPerTexelSignal( + LPD3DXMESH pMesh, + DWORD dwTextureIndex, + FLOAT *pfTexelSignal, + UINT uWidth, + UINT uHeight, + UINT uSignalDimension, + UINT uComponents, + DWORD dwOptions, + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +HRESULT WINAPI + D3DXConvertMeshSubsetToSingleStrip( + LPD3DXBASEMESH MeshIn, + DWORD AttribId, + DWORD IBOptions, + LPDIRECT3DINDEXBUFFER9 *ppIndexBuffer, + DWORD *pNumIndices); + +HRESULT WINAPI + D3DXConvertMeshSubsetToStrips( + LPD3DXBASEMESH MeshIn, + DWORD AttribId, + DWORD IBOptions, + LPDIRECT3DINDEXBUFFER9 *ppIndexBuffer, + DWORD *pNumIndices, + LPD3DXBUFFER *ppStripLengths, + DWORD *pNumStrips); + + +//============================================================================ +// +// D3DXOptimizeFaces: +// -------------------- +// Generate a face remapping for a triangle list that more effectively utilizes +// vertex caches. This optimization is identical to the one provided +// by ID3DXMesh::Optimize with the hardware independent option enabled. +// +// Parameters: +// pbIndices +// Triangle list indices to use for generating a vertex ordering +// NumFaces +// Number of faces in the triangle list +// NumVertices +// Number of vertices referenced by the triangle list +// b32BitIndices +// TRUE if indices are 32 bit, FALSE if indices are 16 bit +// pFaceRemap +// Destination buffer to store face ordering +// The number stored for a given element is where in the new ordering +// the face will have come from. See ID3DXMesh::Optimize for more info. +// +//============================================================================ +HRESULT WINAPI + D3DXOptimizeFaces( + LPCVOID pbIndices, + UINT cFaces, + UINT cVertices, + BOOL b32BitIndices, + DWORD* pFaceRemap); + +//============================================================================ +// +// D3DXOptimizeVertices: +// -------------------- +// Generate a vertex remapping to optimize for in order use of vertices for +// a given set of indices. This is commonly used after applying the face +// remap generated by D3DXOptimizeFaces +// +// Parameters: +// pbIndices +// Triangle list indices to use for generating a vertex ordering +// NumFaces +// Number of faces in the triangle list +// NumVertices +// Number of vertices referenced by the triangle list +// b32BitIndices +// TRUE if indices are 32 bit, FALSE if indices are 16 bit +// pVertexRemap +// Destination buffer to store vertex ordering +// The number stored for a given element is where in the new ordering +// the vertex will have come from. See ID3DXMesh::Optimize for more info. +// +//============================================================================ +HRESULT WINAPI + D3DXOptimizeVertices( + LPCVOID pbIndices, + UINT cFaces, + UINT cVertices, + BOOL b32BitIndices, + DWORD* pVertexRemap); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +//=========================================================================== +// +// Data structures for Spherical Harmonic Precomputation +// +// +//============================================================================ + +typedef enum _D3DXSHCOMPRESSQUALITYTYPE { + D3DXSHCQUAL_FASTLOWQUALITY = 1, + D3DXSHCQUAL_SLOWHIGHQUALITY = 2, + D3DXSHCQUAL_FORCE_DWORD = 0x7fffffff +} D3DXSHCOMPRESSQUALITYTYPE; + +typedef enum _D3DXSHGPUSIMOPT { + D3DXSHGPUSIMOPT_SHADOWRES256 = 1, + D3DXSHGPUSIMOPT_SHADOWRES512 = 0, + D3DXSHGPUSIMOPT_SHADOWRES1024 = 2, + D3DXSHGPUSIMOPT_SHADOWRES2048 = 3, + + D3DXSHGPUSIMOPT_HIGHQUALITY = 4, + + D3DXSHGPUSIMOPT_FORCE_DWORD = 0x7fffffff +} D3DXSHGPUSIMOPT; + +// for all properties that are colors the luminance is computed +// if the simulator is run with a single channel using the following +// formula: R * 0.2125 + G * 0.7154 + B * 0.0721 + +typedef struct _D3DXSHMATERIAL { + D3DCOLORVALUE Diffuse; // Diffuse albedo of the surface. (Ignored if object is a Mirror) + BOOL bMirror; // Must be set to FALSE. bMirror == TRUE not currently supported + BOOL bSubSurf; // true if the object does subsurface scattering - can't do this and be a mirror + + // subsurface scattering parameters + FLOAT RelativeIndexOfRefraction; + D3DCOLORVALUE Absorption; + D3DCOLORVALUE ReducedScattering; + +} D3DXSHMATERIAL; + +// allocated in D3DXSHPRTCompSplitMeshSC +// vertices are duplicated into multiple super clusters but +// only have a valid status in one super cluster (fill in the rest) + +typedef struct _D3DXSHPRTSPLITMESHVERTDATA { + UINT uVertRemap; // vertex in original mesh this corresponds to + UINT uSubCluster; // cluster index relative to super cluster + UCHAR ucVertStatus; // 1 if vertex has valid data, 0 if it is "fill" +} D3DXSHPRTSPLITMESHVERTDATA; + +// used in D3DXSHPRTCompSplitMeshSC +// information for each super cluster that maps into face/vert arrays + +typedef struct _D3DXSHPRTSPLITMESHCLUSTERDATA { + UINT uVertStart; // initial index into remapped vertex array + UINT uVertLength; // number of vertices in this super cluster + + UINT uFaceStart; // initial index into face array + UINT uFaceLength; // number of faces in this super cluster + + UINT uClusterStart; // initial index into cluster array + UINT uClusterLength; // number of clusters in this super cluster +} D3DXSHPRTSPLITMESHCLUSTERDATA; + +// call back function for simulator +// return S_OK to keep running the simulator - anything else represents +// failure and the simulator will abort. + +typedef HRESULT (WINAPI *LPD3DXSHPRTSIMCB)(float fPercentDone, LPVOID lpUserContext); + +// interfaces for PRT buffers/simulator + +// GUIDs +// {F1827E47-00A8-49cd-908C-9D11955F8728} +DEFINE_GUID(IID_ID3DXPRTBuffer, +0xf1827e47, 0xa8, 0x49cd, 0x90, 0x8c, 0x9d, 0x11, 0x95, 0x5f, 0x87, 0x28); + +// {A758D465-FE8D-45ad-9CF0-D01E56266A07} +DEFINE_GUID(IID_ID3DXPRTCompBuffer, +0xa758d465, 0xfe8d, 0x45ad, 0x9c, 0xf0, 0xd0, 0x1e, 0x56, 0x26, 0x6a, 0x7); + +// {838F01EC-9729-4527-AADB-DF70ADE7FEA9} +DEFINE_GUID(IID_ID3DXTextureGutterHelper, +0x838f01ec, 0x9729, 0x4527, 0xaa, 0xdb, 0xdf, 0x70, 0xad, 0xe7, 0xfe, 0xa9); + +// {683A4278-CD5F-4d24-90AD-C4E1B6855D53} +DEFINE_GUID(IID_ID3DXPRTEngine, +0x683a4278, 0xcd5f, 0x4d24, 0x90, 0xad, 0xc4, 0xe1, 0xb6, 0x85, 0x5d, 0x53); + +// interface defenitions + +typedef interface ID3DXTextureGutterHelper ID3DXTextureGutterHelper; +typedef interface ID3DXPRTBuffer ID3DXPRTBuffer; + +#undef INTERFACE +#define INTERFACE ID3DXPRTBuffer + +// Buffer interface - contains "NumSamples" samples +// each sample in memory is stored as NumCoeffs scalars per channel (1 or 3) +// Same interface is used for both Vertex and Pixel PRT buffers + +DECLARE_INTERFACE_(ID3DXPRTBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXPRTBuffer + STDMETHOD_(UINT, GetNumSamples)(THIS) PURE; + STDMETHOD_(UINT, GetNumCoeffs)(THIS) PURE; + STDMETHOD_(UINT, GetNumChannels)(THIS) PURE; + + STDMETHOD_(BOOL, IsTexture)(THIS) PURE; + STDMETHOD_(UINT, GetWidth)(THIS) PURE; + STDMETHOD_(UINT, GetHeight)(THIS) PURE; + + // changes the number of samples allocated in the buffer + STDMETHOD(Resize)(THIS_ UINT NewSize) PURE; + + // ppData will point to the memory location where sample Start begins + // pointer is valid for at least NumSamples samples + STDMETHOD(LockBuffer)(THIS_ UINT Start, UINT NumSamples, FLOAT **ppData) PURE; + STDMETHOD(UnlockBuffer)(THIS) PURE; + + // every scalar in buffer is multiplied by Scale + STDMETHOD(ScaleBuffer)(THIS_ FLOAT Scale) PURE; + + // every scalar contains the sum of this and pBuffers values + // pBuffer must have the same storage class/dimensions + STDMETHOD(AddBuffer)(THIS_ LPD3DXPRTBUFFER pBuffer) PURE; + + // GutterHelper (described below) will fill in the gutter + // regions of a texture by interpolating "internal" values + STDMETHOD(AttachGH)(THIS_ LPD3DXTEXTUREGUTTERHELPER) PURE; + STDMETHOD(ReleaseGH)(THIS) PURE; + + // Evaluates attached gutter helper on the contents of this buffer + STDMETHOD(EvalGH)(THIS) PURE; + + // extracts a given channel into texture pTexture + // NumCoefficients starting from StartCoefficient are copied + STDMETHOD(ExtractTexture)(THIS_ UINT Channel, UINT StartCoefficient, + UINT NumCoefficients, LPDIRECT3DTEXTURE9 pTexture) PURE; + + // extracts NumCoefficients coefficients into mesh - only applicable on single channel + // buffers, otherwise just lockbuffer and copy data. With SHPRT data NumCoefficients + // should be Order^2 + STDMETHOD(ExtractToMesh)(THIS_ UINT NumCoefficients, D3DDECLUSAGE Usage, UINT UsageIndexStart, + LPD3DXMESH pScene) PURE; + +}; + +typedef interface ID3DXPRTCompBuffer ID3DXPRTCompBuffer; +typedef interface ID3DXPRTCompBuffer *LPD3DXPRTCOMPBUFFER; + +#undef INTERFACE +#define INTERFACE ID3DXPRTCompBuffer + +// compressed buffers stored a compressed version of a PRTBuffer + +DECLARE_INTERFACE_(ID3DXPRTCompBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DPRTCompBuffer + + // NumCoeffs and NumChannels are properties of input buffer + STDMETHOD_(UINT, GetNumSamples)(THIS) PURE; + STDMETHOD_(UINT, GetNumCoeffs)(THIS) PURE; + STDMETHOD_(UINT, GetNumChannels)(THIS) PURE; + + STDMETHOD_(BOOL, IsTexture)(THIS) PURE; + STDMETHOD_(UINT, GetWidth)(THIS) PURE; + STDMETHOD_(UINT, GetHeight)(THIS) PURE; + + // number of clusters, and PCA vectors per-cluster + STDMETHOD_(UINT, GetNumClusters)(THIS) PURE; + STDMETHOD_(UINT, GetNumPCA)(THIS) PURE; + + // normalizes PCA weights so that they are between [-1,1] + // basis vectors are modified to reflect this + STDMETHOD(NormalizeData)(THIS) PURE; + + // copies basis vectors for cluster "Cluster" into pClusterBasis + // (NumPCA+1)*NumCoeffs*NumChannels floats + STDMETHOD(ExtractBasis)(THIS_ UINT Cluster, FLOAT *pClusterBasis) PURE; + + // UINT per sample - which cluster it belongs to + STDMETHOD(ExtractClusterIDs)(THIS_ UINT *pClusterIDs) PURE; + + // copies NumExtract PCA projection coefficients starting at StartPCA + // into pPCACoefficients - NumSamples*NumExtract floats copied + STDMETHOD(ExtractPCA)(THIS_ UINT StartPCA, UINT NumExtract, FLOAT *pPCACoefficients) PURE; + + // copies NumPCA projection coefficients starting at StartPCA + // into pTexture - should be able to cope with signed formats + STDMETHOD(ExtractTexture)(THIS_ UINT StartPCA, UINT NumpPCA, + LPDIRECT3DTEXTURE9 pTexture) PURE; + + // copies NumPCA projection coefficients into mesh pScene + // Usage is D3DDECLUSAGE where coefficients are to be stored + // UsageIndexStart is starting index + STDMETHOD(ExtractToMesh)(THIS_ UINT NumPCA, D3DDECLUSAGE Usage, UINT UsageIndexStart, + LPD3DXMESH pScene) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXTextureGutterHelper + +// ID3DXTextureGutterHelper will build and manage +// "gutter" regions in a texture - this will allow for +// bi-linear interpolation to not have artifacts when rendering +// It generates a map (in texture space) where each texel +// is in one of 3 states: +// 0 Invalid - not used at all +// 1 Inside triangle +// 2 Gutter texel +// 4 represents a gutter texel that will be computed during PRT +// For each Inside/Gutter texel it stores the face it +// belongs to and barycentric coordinates for the 1st two +// vertices of that face. Gutter vertices are assigned to +// the closest edge in texture space. +// +// When used with PRT this requires a unique parameterization +// of the model - every texel must correspond to a single point +// on the surface of the model and vice versa + +DECLARE_INTERFACE_(ID3DXTextureGutterHelper, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXTextureGutterHelper + + // dimensions of texture this is bound too + STDMETHOD_(UINT, GetWidth)(THIS) PURE; + STDMETHOD_(UINT, GetHeight)(THIS) PURE; + + + // Applying gutters recomputes all of the gutter texels of class "2" + // based on texels of class "1" or "4" + + // Applies gutters to a raw float buffer - each texel is NumCoeffs floats + // Width and Height must match GutterHelper + STDMETHOD(ApplyGuttersFloat)(THIS_ FLOAT *pDataIn, UINT NumCoeffs, UINT Width, UINT Height); + + // Applies gutters to pTexture + // Dimensions must match GutterHelper + STDMETHOD(ApplyGuttersTex)(THIS_ LPDIRECT3DTEXTURE9 pTexture); + + // Applies gutters to a D3DXPRTBuffer + // Dimensions must match GutterHelper + STDMETHOD(ApplyGuttersPRT)(THIS_ LPD3DXPRTBUFFER pBuffer); + + // Resamples a texture from a mesh onto this gutterhelpers + // parameterization. It is assumed that the UV coordinates + // for this gutter helper are in TEXTURE 0 (usage/usage index) + // and the texture coordinates should all be within [0,1] for + // both sets. + // + // pTextureIn - texture represented using parameterization in pMeshIn + // pMeshIn - Mesh with texture coordinates that represent pTextureIn + // pTextureOut texture coordinates are assumed to be in + // TEXTURE 0 + // Usage - field in DECL for pMeshIn that stores texture coordinates + // for pTextureIn + // UsageIndex - which index for Usage above for pTextureIn + // pTextureOut- Resampled texture + // + // Usage would generally be D3DDECLUSAGE_TEXCOORD and UsageIndex other than zero + STDMETHOD(ResampleTex)(THIS_ LPDIRECT3DTEXTURE9 pTextureIn, + LPD3DXMESH pMeshIn, + D3DDECLUSAGE Usage, UINT UsageIndex, + LPDIRECT3DTEXTURE9 pTextureOut); + + // the routines below provide access to the data structures + // used by the Apply functions + + // face map is a UINT per texel that represents the + // face of the mesh that texel belongs too - + // only valid if same texel is valid in pGutterData + // pFaceData must be allocated by the user + STDMETHOD(GetFaceMap)(THIS_ UINT *pFaceData) PURE; + + // BaryMap is a D3DXVECTOR2 per texel + // the 1st two barycentric coordinates for the corresponding + // face (3rd weight is always 1-sum of first two) + // only valid if same texel is valid in pGutterData + // pBaryData must be allocated by the user + STDMETHOD(GetBaryMap)(THIS_ D3DXVECTOR2 *pBaryData) PURE; + + // TexelMap is a D3DXVECTOR2 per texel that + // stores the location in pixel coordinates where the + // corresponding texel is mapped + // pTexelData must be allocated by the user + STDMETHOD(GetTexelMap)(THIS_ D3DXVECTOR2 *pTexelData) PURE; + + // GutterMap is a BYTE per texel + // 0/1/2 for Invalid/Internal/Gutter texels + // 4 represents a gutter texel that will be computed + // during PRT + // pGutterData must be allocated by the user + STDMETHOD(GetGutterMap)(THIS_ BYTE *pGutterData) PURE; + + // face map is a UINT per texel that represents the + // face of the mesh that texel belongs too - + // only valid if same texel is valid in pGutterData + STDMETHOD(SetFaceMap)(THIS_ UINT *pFaceData) PURE; + + // BaryMap is a D3DXVECTOR2 per texel + // the 1st two barycentric coordinates for the corresponding + // face (3rd weight is always 1-sum of first two) + // only valid if same texel is valid in pGutterData + STDMETHOD(SetBaryMap)(THIS_ D3DXVECTOR2 *pBaryData) PURE; + + // TexelMap is a D3DXVECTOR2 per texel that + // stores the location in pixel coordinates where the + // corresponding texel is mapped + STDMETHOD(SetTexelMap)(THIS_ D3DXVECTOR2 *pTexelData) PURE; + + // GutterMap is a BYTE per texel + // 0/1/2 for Invalid/Internal/Gutter texels + // 4 represents a gutter texel that will be computed + // during PRT + STDMETHOD(SetGutterMap)(THIS_ BYTE *pGutterData) PURE; +}; + + +typedef interface ID3DXPRTEngine ID3DXPRTEngine; +typedef interface ID3DXPRTEngine *LPD3DXPRTENGINE; + +#undef INTERFACE +#define INTERFACE ID3DXPRTEngine + +// ID3DXPRTEngine is used to compute a PRT simulation +// Use the following steps to compute PRT for SH +// (1) create an interface (which includes a scene) +// (2) call SetSamplingInfo +// (3) [optional] Set MeshMaterials/albedo's (required if doing bounces) +// (4) call ComputeDirectLightingSH +// (5) [optional] call ComputeBounce +// repeat step 5 for as many bounces as wanted. +// if you want to model subsurface scattering you +// need to call ComputeSS after direct lighting and +// each bounce. +// If you want to bake the albedo into the PRT signal, you +// must call MutliplyAlbedo, otherwise the user has to multiply +// the albedo themselves. Not multiplying the albedo allows you +// to model albedo variation at a finer scale then illumination, and +// can result in better compression results. +// Luminance values are computed from RGB values using the following +// formula: R * 0.2125 + G * 0.7154 + B * 0.0721 + +DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXPRTEngine + + // This sets a material per attribute in the scene mesh and it is + // the only way to specify subsurface scattering parameters. if + // bSetAlbedo is FALSE, NumChannels must match the current + // configuration of the PRTEngine. If you intend to change + // NumChannels (through some other SetAlbedo function) it must + // happen before SetMeshMaterials is called. + // + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + // bSetAlbedo sets albedo from material if TRUE - which clobbers per texel/vertex + // albedo that might have been set before. FALSE won't clobber. + // fLengthScale is used for subsurface scattering - scene is mapped into a 1mm unit cube + // and scaled by this amount + STDMETHOD(SetMeshMaterials)(THIS_ CONST D3DXSHMATERIAL **ppMaterials, UINT NumMeshes, + UINT NumChannels, BOOL bSetAlbedo, FLOAT fLengthScale) PURE; + + // setting albedo per-vertex or per-texel over rides the albedos stored per mesh + // but it does not over ride any other settings + + // sets an albedo to be used per vertex - the albedo is represented as a float + // pDataIn input pointer (pointint to albedo of 1st sample) + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + // Stride - stride in bytes to get to next samples albedo + STDMETHOD(SetPerVertexAlbedo)(THIS_ CONST VOID *pDataIn, UINT NumChannels, UINT Stride) PURE; + + // represents the albedo per-texel instead of per-vertex (even if per-vertex PRT is used) + // pAlbedoTexture - texture that stores the albedo (dimension arbitrary) + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + // pGH - optional gutter helper, otherwise one is constructed in computation routines and + // destroyed (if not attached to buffers) + STDMETHOD(SetPerTexelAlbedo)(THIS_ LPDIRECT3DTEXTURE9 pAlbedoTexture, + UINT NumChannels, + LPD3DXTEXTUREGUTTERHELPER pGH) PURE; + + // gets the per-vertex albedo + STDMETHOD(GetVertexAlbedo)(THIS_ D3DXCOLOR *pVertColors, UINT NumVerts) PURE; + + // If pixel PRT is being computed normals default to ones that are interpolated + // from the vertex normals. This specifies a texture that stores an object + // space normal map instead (must use a texture format that can represent signed values) + // pNormalTexture - normal map, must be same dimensions as PRTBuffers, signed + STDMETHOD(SetPerTexelNormal)(THIS_ LPDIRECT3DTEXTURE9 pNormalTexture) PURE; + + // Copies per-vertex albedo from mesh + // pMesh - mesh that represents the scene. It must have the same + // properties as the mesh used to create the PRTEngine + // Usage - D3DDECLUSAGE to extract albedos from + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + STDMETHOD(ExtractPerVertexAlbedo)(THIS_ LPD3DXMESH pMesh, + D3DDECLUSAGE Usage, + UINT NumChannels) PURE; + + // Resamples the input buffer into the output buffer + // can be used to move between per-vertex and per-texel buffers. This can also be used + // to convert single channel buffers to 3-channel buffers and vice-versa. + STDMETHOD(ResampleBuffer)(THIS_ LPD3DXPRTBUFFER pBufferIn, LPD3DXPRTBUFFER pBufferOut) PURE; + + // Returns the scene mesh - including modifications from adaptive spatial sampling + // The returned mesh only has positions, normals and texture coordinates (if defined) + // pD3DDevice - d3d device that will be used to allocate the mesh + // pFaceRemap - each face has a pointer back to the face on the original mesh that it comes from + // if the face hasn't been subdivided this will be an identity mapping + // pVertRemap - each vertex contains 3 vertices that this is a linear combination of + // pVertWeights - weights for each of above indices (sum to 1.0f) + // ppMesh - mesh that will be allocated and filled + STDMETHOD(GetAdaptedMesh)(THIS_ LPDIRECT3DDEVICE9 pD3DDevice,UINT *pFaceRemap, UINT *pVertRemap, FLOAT *pfVertWeights, LPD3DXMESH *ppMesh) PURE; + + // Number of vertices currently allocated (includes new vertices from adaptive sampling) + STDMETHOD_(UINT, GetNumVerts)(THIS) PURE; + // Number of faces currently allocated (includes new faces) + STDMETHOD_(UINT, GetNumFaces)(THIS) PURE; + + // Sets the Minimum/Maximum intersection distances, this can be used to control + // maximum distance that objects can shadow/reflect light, and help with "bad" + // art that might have near features that you don't want to shadow. This does not + // apply for GPU simulations. + // fMin - minimum intersection distance, must be positive and less than fMax + // fMax - maximum intersection distance, if 0.0f use the previous value, otherwise + // must be strictly greater than fMin + STDMETHOD(SetMinMaxIntersection)(THIS_ FLOAT fMin, FLOAT fMax) PURE; + + // This will subdivide faces on a mesh so that adaptively simulations can + // use a more conservative threshold (it won't miss features.) + // MinEdgeLength - minimum edge length that will be generated, if 0.0f a + // reasonable default will be used + // MaxSubdiv - maximum level of subdivision, if 0 is specified a default + // value will be used (5) + STDMETHOD(RobustMeshRefine)(THIS_ FLOAT MinEdgeLength, UINT MaxSubdiv) PURE; + + // This sets to sampling information used by the simulator. Adaptive sampling + // parameters are currently ignored. + // NumRays - number of rays to shoot per sample + // UseSphere - if TRUE uses spherical samples, otherwise samples over + // the hemisphere. Should only be used with GPU and Vol computations + // UseCosine - if TRUE uses a cosine weighting - not used for Vol computations + // or if only the visiblity function is desired + // Adaptive - if TRUE adaptive sampling (angular) is used + // AdaptiveThresh - threshold used to terminate adaptive angular sampling + // ignored if adaptive sampling is not set + STDMETHOD(SetSamplingInfo)(THIS_ UINT NumRays, + BOOL UseSphere, + BOOL UseCosine, + BOOL Adaptive, + FLOAT AdaptiveThresh) PURE; + + // Methods that compute the direct lighting contribution for objects + // always represente light using spherical harmonics (SH) + // the albedo is not multiplied by the signal - it just integrates + // incoming light. If NumChannels is not 1 the vector is replicated + // + // SHOrder - order of SH to use + // pDataOut - PRT buffer that is generated. Can be single channel + STDMETHOD(ComputeDirectLightingSH)(THIS_ UINT SHOrder, + LPD3DXPRTBUFFER pDataOut) PURE; + + // Adaptive variant of above function. This will refine the mesh + // generating new vertices/faces to approximate the PRT signal + // more faithfully. + // SHOrder - order of SH to use + // AdaptiveThresh - threshold for adaptive subdivision (in PRT vector error) + // if value is less then 1e-6f, 1e-6f is specified + // MinEdgeLength - minimum edge length that will be generated + // if value is too small a fairly conservative model dependent value + // is used + // MaxSubdiv - maximum subdivision level, if 0 is specified it + // will default to 4 + // pDataOut - PRT buffer that is generated. Can be single channel. + STDMETHOD(ComputeDirectLightingSHAdaptive)(THIS_ UINT SHOrder, + FLOAT AdaptiveThresh, + FLOAT MinEdgeLength, + UINT MaxSubdiv, + LPD3DXPRTBUFFER pDataOut) PURE; + + // Function that computes the direct lighting contribution for objects + // light is always represented using spherical harmonics (SH) + // This is done on the GPU and is much faster then using the CPU. + // The albedo is not multiplied by the signal - it just integrates + // incoming light. If NumChannels is not 1 the vector is replicated. + // ZBias/ZAngleBias are akin to parameters used with shadow zbuffers. + // A reasonable default for both values is 0.005, but the user should + // experiment (ZAngleBias can be zero, ZBias should not be.) + // Callbacks should not use the Direct3D9Device the simulator is using. + // SetSamplingInfo must be called with TRUE for UseSphere and + // FALSE for UseCosine before this method is called. + // + // pD3DDevice - device used to run GPU simulator - must support PS2.0 + // and FP render targets + // Flags - parameters for the GPU simulator, combination of one or more + // D3DXSHGPUSIMOPT flags. Only one SHADOWRES setting should be set and + // the defaults is 512 + // SHOrder - order of SH to use + // ZBias - bias in normal direction (for depth test) + // ZAngleBias - scaled by one minus cosine of angle with light (offset in depth) + // pDataOut - PRT buffer that is filled in. Can be single channel + STDMETHOD(ComputeDirectLightingSHGPU)(THIS_ LPDIRECT3DDEVICE9 pD3DDevice, + UINT Flags, + UINT SHOrder, + FLOAT ZBias, + FLOAT ZAngleBias, + LPD3DXPRTBUFFER pDataOut) PURE; + + + // Functions that computes subsurface scattering (using material properties) + // Albedo is not multiplied by result. This only works for per-vertex data + // use ResampleBuffer to move per-vertex data into a texture and back. + // + // pDataIn - input data (previous bounce) + // pDataOut - result of subsurface scattering simulation + // pDataTotal - [optional] results can be summed into this buffer + STDMETHOD(ComputeSS)(THIS_ LPD3DXPRTBUFFER pDataIn, + LPD3DXPRTBUFFER pDataOut, LPD3DXPRTBUFFER pDataTotal) PURE; + + // Adaptive version of ComputeSS. + // + // pDataIn - input data (previous bounce) + // AdaptiveThresh - threshold for adaptive subdivision (in PRT vector error) + // if value is less then 1e-6f, 1e-6f is specified + // MinEdgeLength - minimum edge length that will be generated + // if value is too small a fairly conservative model dependent value + // is used + // MaxSubdiv - maximum subdivision level, if 0 is specified it + // will default to 4 + // pDataOut - result of subsurface scattering simulation + // pDataTotal - [optional] results can be summed into this buffer + STDMETHOD(ComputeSSAdaptive)(THIS_ LPD3DXPRTBUFFER pDataIn, + FLOAT AdaptiveThresh, + FLOAT MinEdgeLength, + UINT MaxSubdiv, + LPD3DXPRTBUFFER pDataOut, LPD3DXPRTBUFFER pDataTotal) PURE; + + // computes a single bounce of inter-reflected light + // works for SH based PRT or generic lighting + // Albedo is not multiplied by result + // + // pDataIn - previous bounces data + // pDataOut - PRT buffer that is generated + // pDataTotal - [optional] can be used to keep a running sum + STDMETHOD(ComputeBounce)(THIS_ LPD3DXPRTBUFFER pDataIn, + LPD3DXPRTBUFFER pDataOut, + LPD3DXPRTBUFFER pDataTotal) PURE; + + // Adaptive version of above function. + // + // pDataIn - previous bounces data, can be single channel + // AdaptiveThresh - threshold for adaptive subdivision (in PRT vector error) + // if value is less then 1e-6f, 1e-6f is specified + // MinEdgeLength - minimum edge length that will be generated + // if value is too small a fairly conservative model dependent value + // is used + // MaxSubdiv - maximum subdivision level, if 0 is specified it + // will default to 4 + // pDataOut - PRT buffer that is generated + // pDataTotal - [optional] can be used to keep a running sum + STDMETHOD(ComputeBounceAdaptive)(THIS_ LPD3DXPRTBUFFER pDataIn, + FLOAT AdaptiveThresh, + FLOAT MinEdgeLength, + UINT MaxSubdiv, + LPD3DXPRTBUFFER pDataOut, + LPD3DXPRTBUFFER pDataTotal) PURE; + + // Computes projection of distant SH radiance into a local SH radiance + // function. This models how direct lighting is attenuated by the + // scene and is a form of "neighborhood transfer." The result is + // a linear operator (matrix) at every sample point, if you multiply + // this matrix by the distant SH lighting coefficients you get an + // approximation of the local incident radiance function from + // direct lighting. These resulting lighting coefficients can + // than be projected into another basis or used with any rendering + // technique that uses spherical harmonics as input. + // SetSamplingInfo must be called with TRUE for UseSphere and + // FALSE for UseCosine before this method is called. + // Generates SHOrderIn*SHOrderIn*SHOrderOut*SHOrderOut scalars + // per channel at each sample location. + // + // SHOrderIn - Order of the SH representation of distant lighting + // SHOrderOut - Order of the SH representation of local lighting + // NumVolSamples - Number of sample locations + // pSampleLocs - position of sample locations + // pDataOut - PRT Buffer that will store output results + STDMETHOD(ComputeVolumeSamplesDirectSH)(THIS_ UINT SHOrderIn, + UINT SHOrderOut, + UINT NumVolSamples, + CONST D3DXVECTOR3 *pSampleLocs, + LPD3DXPRTBUFFER pDataOut) PURE; + + // At each sample location computes a linear operator (matrix) that maps + // the representation of source radiance (NumCoeffs in pSurfDataIn) + // into a local incident radiance function approximated with spherical + // harmonics. For example if a light map data is specified in pSurfDataIn + // the result is an SH representation of the flow of light at each sample + // point. If PRT data for an outdoor scene is used, each sample point + // contains a matrix that models how distant lighting bounces of the objects + // in the scene and arrives at the given sample point. Combined with + // ComputeVolumeSamplesDirectSH this gives the complete representation for + // how light arrives at each sample point parameterized by distant lighting. + // SetSamplingInfo must be called with TRUE for UseSphere and + // FALSE for UseCosine before this method is called. + // Generates pSurfDataIn->NumCoeffs()*SHOrder*SHOrder scalars + // per channel at each sample location. + // + // pSurfDataIn - previous bounce data + // SHOrder - order of SH to generate projection with + // NumVolSamples - Number of sample locations + // pSampleLocs - position of sample locations + // pDataOut - PRT Buffer that will store output results + STDMETHOD(ComputeVolumeSamples)(THIS_ LPD3DXPRTBUFFER pSurfDataIn, + UINT SHOrder, + UINT NumVolSamples, + CONST D3DXVECTOR3 *pSampleLocs, + LPD3DXPRTBUFFER pDataOut) PURE; + + // Computes direct lighting (SH) for a point not on the mesh + // with a given normal - cannot use texture buffers. + // + // SHOrder - order of SH to use + // NumSamples - number of sample locations + // pSampleLocs - position for each sample + // pSampleNorms - normal for each sample + // pDataOut - PRT Buffer that will store output results + STDMETHOD(ComputeSurfSamplesDirectSH)(THIS_ UINT SHOrder, + UINT NumSamples, + CONST D3DXVECTOR3 *pSampleLocs, + CONST D3DXVECTOR3 *pSampleNorms, + LPD3DXPRTBUFFER pDataOut) PURE; + + + // given the solution for PRT or light maps, computes transfer vector at arbitrary + // position/normal pairs in space + // + // pSurfDataIn - input data + // NumSamples - number of sample locations + // pSampleLocs - position for each sample + // pSampleNorms - normal for each sample + // pDataOut - PRT Buffer that will store output results + // pDataTotal - optional buffer to sum results into - can be NULL + STDMETHOD(ComputeSurfSamplesBounce)(THIS_ LPD3DXPRTBUFFER pSurfDataIn, + UINT NumSamples, + CONST D3DXVECTOR3 *pSampleLocs, + CONST D3DXVECTOR3 *pSampleNorms, + LPD3DXPRTBUFFER pDataOut, + LPD3DXPRTBUFFER pDataTotal) PURE; + + // Frees temporary data structures that can be created for subsurface scattering + // this data is freed when the PRTComputeEngine is freed and is lazily created + STDMETHOD(FreeSSData)(THIS) PURE; + + // Frees temporary data structures that can be created for bounce simulations + // this data is freed when the PRTComputeEngine is freed and is lazily created + STDMETHOD(FreeBounceData)(THIS) PURE; + + // This computes the Local Deformable PRT (LDPRT) coefficients relative to the + // per sample normals that minimize error in a least squares sense with respect + // to the input PRT data set. These coefficients can be used with skinned/transformed + // normals to model global effects with dynamic objects. Shading normals can + // optionally be solved for - these normals (along with the LDPRT coefficients) can + // more accurately represent the PRT signal. The coefficients are for zonal + // harmonics oriented in the normal/shading normal direction. + // + // pDataIn - SH PRT dataset that is input + // SHOrder - Order of SH to compute conv coefficients for + // pNormOut - Optional array of vectors (passed in) that will be filled with + // "shading normals", LDPRT coefficients are optimized for + // these normals. This array must be the same size as the number of + // samples in pDataIn + // pDataOut - Output buffer (SHOrder zonal harmonic coefficients per channel per sample) + STDMETHOD(ComputeLDPRTCoeffs)(THIS_ LPD3DXPRTBUFFER pDataIn, + UINT SHOrder, + D3DXVECTOR3 *pNormOut, + LPD3DXPRTBUFFER pDataOut) PURE; + + // scales all the samples associated with a given sub mesh + // can be useful when using subsurface scattering + // fScale - value to scale each vector in submesh by + STDMETHOD(ScaleMeshChunk)(THIS_ UINT uMeshChunk, FLOAT fScale, LPD3DXPRTBUFFER pDataOut) PURE; + + // mutliplies each PRT vector by the albedo - can be used if you want to have the albedo + // burned into the dataset, often better not to do this. If this is not done the user + // must mutliply the albedo themselves when rendering - just multiply the albedo times + // the result of the PRT dot product. + // If pDataOut is a texture simulation result and there is an albedo texture it + // must be represented at the same resolution as the simulation buffer. You can use + // LoadSurfaceFromSurface and set a new albedo texture if this is an issue - but must + // be careful about how the gutters are handled. + // + // pDataOut - dataset that will get albedo pushed into it + STDMETHOD(MultiplyAlbedo)(THIS_ LPD3DXPRTBUFFER pDataOut) PURE; + + // Sets a pointer to an optional call back function that reports back to the + // user percentage done and gives them the option of quitting + // pCB - pointer to call back function, return S_OK for the simulation + // to continue + // Frequency - 1/Frequency is roughly the number of times the call back + // will be invoked + // lpUserContext - will be passed back to the users call back + STDMETHOD(SetCallBack)(THIS_ LPD3DXSHPRTSIMCB pCB, FLOAT Frequency, LPVOID lpUserContext) PURE; + + // Returns TRUE if the ray intersects the mesh, FALSE if it does not. This function + // takes into account settings from SetMinMaxIntersection. If the closest intersection + // is not needed this function is more efficient compared to the ClosestRayIntersection + // method. + // pRayPos - origin of ray + // pRayDir - normalized ray direction (normalization required for SetMinMax to be meaningful) + + STDMETHOD_(BOOL, ShadowRayIntersects)(THIS_ CONST D3DXVECTOR3 *pRayPos, CONST D3DXVECTOR3 *pRayDir) PURE; + + // Returns TRUE if the ray intersects the mesh, FALSE if it does not. If there is an + // intersection the closest face that was intersected and its first two barycentric coordinates + // are returned. This function takes into account settings from SetMinMaxIntersection. + // This is a slower function compared to ShadowRayIntersects and should only be used where + // needed. The third vertices barycentric coordinates will be 1 - pU - pV. + // pRayPos - origin of ray + // pRayDir - normalized ray direction (normalization required for SetMinMax to be meaningful) + // pFaceIndex - Closest face that intersects. This index is based on stacking the pBlockerMesh + // faces before the faces from pMesh + // pU - Barycentric coordinate for vertex 0 + // pV - Barycentric coordinate for vertex 1 + // pDist - Distance along ray where the intersection occured + + STDMETHOD_(BOOL, ClosestRayIntersects)(THIS_ CONST D3DXVECTOR3 *pRayPos, CONST D3DXVECTOR3 *pRayDir, + DWORD *pFaceIndex, FLOAT *pU, FLOAT *pV, FLOAT *pDist) PURE; +}; + + +// API functions for creating interfaces + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//============================================================================ +// +// D3DXCreatePRTBuffer: +// -------------------- +// Generates a PRT Buffer that can be compressed or filled by a simulator +// This function should be used to create per-vertex or volume buffers. +// When buffers are created all values are initialized to zero. +// +// Parameters: +// NumSamples +// Number of sample locations represented +// NumCoeffs +// Number of coefficients per sample location (order^2 for SH) +// NumChannels +// Number of color channels to represent (1 or 3) +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXCreatePRTBuffer( + UINT NumSamples, + UINT NumCoeffs, + UINT NumChannels, + LPD3DXPRTBUFFER* ppBuffer); + +//============================================================================ +// +// D3DXCreatePRTBufferTex: +// -------------------- +// Generates a PRT Buffer that can be compressed or filled by a simulator +// This function should be used to create per-pixel buffers. +// When buffers are created all values are initialized to zero. +// +// Parameters: +// Width +// Width of texture +// Height +// Height of texture +// NumCoeffs +// Number of coefficients per sample location (order^2 for SH) +// NumChannels +// Number of color channels to represent (1 or 3) +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXCreatePRTBufferTex( + UINT Width, + UINT Height, + UINT NumCoeffs, + UINT NumChannels, + LPD3DXPRTBUFFER* ppBuffer); + +//============================================================================ +// +// D3DXLoadPRTBufferFromFile: +// -------------------- +// Loads a PRT buffer that has been saved to disk. +// +// Parameters: +// pFilename +// Name of the file to load +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXLoadPRTBufferFromFileA( + LPCSTR pFilename, + LPD3DXPRTBUFFER* ppBuffer); + +HRESULT WINAPI + D3DXLoadPRTBufferFromFileW( + LPCWSTR pFilename, + LPD3DXPRTBUFFER* ppBuffer); + +#ifdef UNICODE +#define D3DXLoadPRTBufferFromFile D3DXLoadPRTBufferFromFileW +#else +#define D3DXLoadPRTBufferFromFile D3DXLoadPRTBufferFromFileA +#endif + + +//============================================================================ +// +// D3DXSavePRTBufferToFile: +// -------------------- +// Saves a PRTBuffer to disk. +// +// Parameters: +// pFilename +// Name of the file to save +// pBuffer +// Buffer that will be saved +// +//============================================================================ + +HRESULT WINAPI + D3DXSavePRTBufferToFileA( + LPCSTR pFileName, + LPD3DXPRTBUFFER pBuffer); + +HRESULT WINAPI + D3DXSavePRTBufferToFileW( + LPCWSTR pFileName, + LPD3DXPRTBUFFER pBuffer); + +#ifdef UNICODE +#define D3DXSavePRTBufferToFile D3DXSavePRTBufferToFileW +#else +#define D3DXSavePRTBufferToFile D3DXSavePRTBufferToFileA +#endif + + +//============================================================================ +// +// D3DXLoadPRTCompBufferFromFile: +// -------------------- +// Loads a PRTComp buffer that has been saved to disk. +// +// Parameters: +// pFilename +// Name of the file to load +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXLoadPRTCompBufferFromFileA( + LPCSTR pFilename, + LPD3DXPRTCOMPBUFFER* ppBuffer); + +HRESULT WINAPI + D3DXLoadPRTCompBufferFromFileW( + LPCWSTR pFilename, + LPD3DXPRTCOMPBUFFER* ppBuffer); + +#ifdef UNICODE +#define D3DXLoadPRTCompBufferFromFile D3DXLoadPRTCompBufferFromFileW +#else +#define D3DXLoadPRTCompBufferFromFile D3DXLoadPRTCompBufferFromFileA +#endif + +//============================================================================ +// +// D3DXSavePRTCompBufferToFile: +// -------------------- +// Saves a PRTCompBuffer to disk. +// +// Parameters: +// pFilename +// Name of the file to save +// pBuffer +// Buffer that will be saved +// +//============================================================================ + +HRESULT WINAPI + D3DXSavePRTCompBufferToFileA( + LPCSTR pFileName, + LPD3DXPRTCOMPBUFFER pBuffer); + +HRESULT WINAPI + D3DXSavePRTCompBufferToFileW( + LPCWSTR pFileName, + LPD3DXPRTCOMPBUFFER pBuffer); + +#ifdef UNICODE +#define D3DXSavePRTCompBufferToFile D3DXSavePRTCompBufferToFileW +#else +#define D3DXSavePRTCompBufferToFile D3DXSavePRTCompBufferToFileA +#endif + +//============================================================================ +// +// D3DXCreatePRTCompBuffer: +// -------------------- +// Compresses a PRT buffer (vertex or texel) +// +// Parameters: +// D3DXSHCOMPRESSQUALITYTYPE +// Quality of compression - low is faster (computes PCA per voronoi cluster) +// high is slower but better quality (clusters based on distance to affine subspace) +// NumClusters +// Number of clusters to compute +// NumPCA +// Number of basis vectors to compute +// pCB +// Optional Callback function +// lpUserContext +// Optional user context +// pBufferIn +// Buffer that will be compressed +// ppBufferOut +// Compressed buffer that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXCreatePRTCompBuffer( + D3DXSHCOMPRESSQUALITYTYPE Quality, + UINT NumClusters, + UINT NumPCA, + LPD3DXSHPRTSIMCB pCB, + LPVOID lpUserContext, + LPD3DXPRTBUFFER pBufferIn, + LPD3DXPRTCOMPBUFFER *ppBufferOut + ); + +//============================================================================ +// +// D3DXCreateTextureGutterHelper: +// -------------------- +// Generates a "GutterHelper" for a given set of meshes and texture +// resolution +// +// Parameters: +// Width +// Width of texture +// Height +// Height of texture +// pMesh +// Mesh that represents the scene +// GutterSize +// Number of texels to over rasterize in texture space +// this should be at least 1.0 +// ppBuffer +// GutterHelper that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXCreateTextureGutterHelper( + UINT Width, + UINT Height, + LPD3DXMESH pMesh, + FLOAT GutterSize, + LPD3DXTEXTUREGUTTERHELPER* ppBuffer); + + +//============================================================================ +// +// D3DXCreatePRTEngine: +// -------------------- +// Computes a PRTEngine which can efficiently generate PRT simulations +// of a scene +// +// Parameters: +// pMesh +// Mesh that represents the scene - must have an AttributeTable +// where vertices are in a unique attribute. +// pAdjacency +// Optional adjacency information +// ExtractUVs +// Set this to true if textures are going to be used for albedos +// or to store PRT vectors +// pBlockerMesh +// Optional mesh that just blocks the scene +// ppEngine +// PRTEngine that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXCreatePRTEngine( + LPD3DXMESH pMesh, + DWORD *pAdjacency, + BOOL ExtractUVs, + LPD3DXMESH pBlockerMesh, + LPD3DXPRTENGINE* ppEngine); + +//============================================================================ +// +// D3DXConcatenateMeshes: +// -------------------- +// Concatenates a group of meshes into one common mesh. This can optionaly transform +// each sub mesh or its texture coordinates. If no DECL is given it will +// generate a union of all of the DECL's of the sub meshes, promoting channels +// and types if neccesary. It will create an AttributeTable if possible, one can +// call OptimizeMesh with attribute sort and compacting enabled to ensure this. +// +// Parameters: +// ppMeshes +// Array of pointers to meshes that can store PRT vectors +// NumMeshes +// Number of meshes +// Options +// Passed through to D3DXCreateMesh +// pGeomXForms +// [optional] Each sub mesh is transformed by the corresponding +// matrix if this array is supplied +// pTextureXForms +// [optional] UV coordinates for each sub mesh are transformed +// by corresponding matrix if supplied +// pDecl +// [optional] Only information in this DECL is used when merging +// data +// pD3DDevice +// D3D device that is used to create the new mesh +// ppMeshOut +// Mesh that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXConcatenateMeshes( + LPD3DXMESH *ppMeshes, + UINT NumMeshes, + DWORD Options, + CONST D3DXMATRIX *pGeomXForms, + CONST D3DXMATRIX *pTextureXForms, + CONST D3DVERTEXELEMENT9 *pDecl, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXMESH *ppMeshOut); + +//============================================================================ +// +// D3DXSHPRTCompSuperCluster: +// -------------------------- +// Used with compressed results of D3DXSHPRTSimulation. +// Generates "super clusters" - groups of clusters that can be drawn in +// the same draw call. A greedy algorithm that minimizes overdraw is used +// to group the clusters. +// +// Parameters: +// pClusterIDs +// NumVerts cluster ID's (extracted from a compressed buffer) +// pScene +// Mesh that represents composite scene passed to the simulator +// MaxNumClusters +// Maximum number of clusters allocated per super cluster +// NumClusters +// Number of clusters computed in the simulator +// pSuperClusterIDs +// Array of length NumClusters, contains index of super cluster +// that corresponding cluster was assigned to +// pNumSuperClusters +// Returns the number of super clusters allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXSHPRTCompSuperCluster( + UINT *pClusterIDs, + LPD3DXMESH pScene, + UINT MaxNumClusters, + UINT NumClusters, + UINT *pSuperClusterIDs, + UINT *pNumSuperClusters); + +//============================================================================ +// +// D3DXSHPRTCompSplitMeshSC: +// ------------------------- +// Used with compressed results of the vertex version of the PRT simulator. +// After D3DXSHRTCompSuperCluster has been called this function can be used +// to split the mesh into a group of faces/vertices per super cluster. +// Each super cluster contains all of the faces that contain any vertex +// classified in one of its clusters. All of the vertices connected to this +// set of faces are also included with the returned array ppVertStatus +// indicating whether or not the vertex belongs to the supercluster. +// +// Parameters: +// pClusterIDs +// NumVerts cluster ID's (extracted from a compressed buffer) +// NumVertices +// Number of vertices in original mesh +// NumClusters +// Number of clusters (input parameter to compression) +// pSuperClusterIDs +// Array of size NumClusters that will contain super cluster ID's (from +// D3DXSHCompSuerCluster) +// NumSuperClusters +// Number of superclusters allocated in D3DXSHCompSuerCluster +// pInputIB +// Raw index buffer for mesh - format depends on bInputIBIs32Bit +// InputIBIs32Bit +// Indicates whether the input index buffer is 32-bit (otherwise 16-bit +// is assumed) +// NumFaces +// Number of faces in the original mesh (pInputIB is 3 times this length) +// ppIBData +// LPD3DXBUFFER holds raw index buffer that will contain the resulting split faces. +// Format determined by bIBIs32Bit. Allocated by function +// pIBDataLength +// Length of ppIBData, assigned in function +// OutputIBIs32Bit +// Indicates whether the output index buffer is to be 32-bit (otherwise +// 16-bit is assumed) +// ppFaceRemap +// LPD3DXBUFFER mapping of each face in ppIBData to original faces. Length is +// *pIBDataLength/3. Optional paramter, allocated in function +// ppVertData +// LPD3DXBUFFER contains new vertex data structure. Size of pVertDataLength +// pVertDataLength +// Number of new vertices in split mesh. Assigned in function +// pSCClusterList +// Array of length NumClusters which pSCData indexes into (Cluster* fields) +// for each SC, contains clusters sorted by super cluster +// pSCData +// Structure per super cluster - contains indices into ppIBData, +// pSCClusterList and ppVertData +// +//============================================================================ + +HRESULT WINAPI + D3DXSHPRTCompSplitMeshSC( + UINT *pClusterIDs, + UINT NumVertices, + UINT NumClusters, + UINT *pSuperClusterIDs, + UINT NumSuperClusters, + LPVOID pInputIB, + BOOL InputIBIs32Bit, + UINT NumFaces, + LPD3DXBUFFER *ppIBData, + UINT *pIBDataLength, + BOOL OutputIBIs32Bit, + LPD3DXBUFFER *ppFaceRemap, + LPD3DXBUFFER *ppVertData, + UINT *pVertDataLength, + UINT *pSCClusterList, + D3DXSHPRTSPLITMESHCLUSTERDATA *pSCData); + + +#ifdef __cplusplus +} +#endif //__cplusplus + +////////////////////////////////////////////////////////////////////////////// +// +// Definitions of .X file templates used by mesh load/save functions +// that are not RM standard +// +////////////////////////////////////////////////////////////////////////////// + +// {3CF169CE-FF7C-44ab-93C0-F78F62D172E2} +DEFINE_GUID(DXFILEOBJ_XSkinMeshHeader, +0x3cf169ce, 0xff7c, 0x44ab, 0x93, 0xc0, 0xf7, 0x8f, 0x62, 0xd1, 0x72, 0xe2); + +// {B8D65549-D7C9-4995-89CF-53A9A8B031E3} +DEFINE_GUID(DXFILEOBJ_VertexDuplicationIndices, +0xb8d65549, 0xd7c9, 0x4995, 0x89, 0xcf, 0x53, 0xa9, 0xa8, 0xb0, 0x31, 0xe3); + +// {A64C844A-E282-4756-8B80-250CDE04398C} +DEFINE_GUID(DXFILEOBJ_FaceAdjacency, +0xa64c844a, 0xe282, 0x4756, 0x8b, 0x80, 0x25, 0xc, 0xde, 0x4, 0x39, 0x8c); + +// {6F0D123B-BAD2-4167-A0D0-80224F25FABB} +DEFINE_GUID(DXFILEOBJ_SkinWeights, +0x6f0d123b, 0xbad2, 0x4167, 0xa0, 0xd0, 0x80, 0x22, 0x4f, 0x25, 0xfa, 0xbb); + +// {A3EB5D44-FC22-429d-9AFB-3221CB9719A6} +DEFINE_GUID(DXFILEOBJ_Patch, +0xa3eb5d44, 0xfc22, 0x429d, 0x9a, 0xfb, 0x32, 0x21, 0xcb, 0x97, 0x19, 0xa6); + +// {D02C95CC-EDBA-4305-9B5D-1820D7704BBF} +DEFINE_GUID(DXFILEOBJ_PatchMesh, +0xd02c95cc, 0xedba, 0x4305, 0x9b, 0x5d, 0x18, 0x20, 0xd7, 0x70, 0x4b, 0xbf); + +// {B9EC94E1-B9A6-4251-BA18-94893F02C0EA} +DEFINE_GUID(DXFILEOBJ_PatchMesh9, +0xb9ec94e1, 0xb9a6, 0x4251, 0xba, 0x18, 0x94, 0x89, 0x3f, 0x2, 0xc0, 0xea); + +// {B6C3E656-EC8B-4b92-9B62-681659522947} +DEFINE_GUID(DXFILEOBJ_PMInfo, +0xb6c3e656, 0xec8b, 0x4b92, 0x9b, 0x62, 0x68, 0x16, 0x59, 0x52, 0x29, 0x47); + +// {917E0427-C61E-4a14-9C64-AFE65F9E9844} +DEFINE_GUID(DXFILEOBJ_PMAttributeRange, +0x917e0427, 0xc61e, 0x4a14, 0x9c, 0x64, 0xaf, 0xe6, 0x5f, 0x9e, 0x98, 0x44); + +// {574CCC14-F0B3-4333-822D-93E8A8A08E4C} +DEFINE_GUID(DXFILEOBJ_PMVSplitRecord, +0x574ccc14, 0xf0b3, 0x4333, 0x82, 0x2d, 0x93, 0xe8, 0xa8, 0xa0, 0x8e, 0x4c); + +// {B6E70A0E-8EF9-4e83-94AD-ECC8B0C04897} +DEFINE_GUID(DXFILEOBJ_FVFData, +0xb6e70a0e, 0x8ef9, 0x4e83, 0x94, 0xad, 0xec, 0xc8, 0xb0, 0xc0, 0x48, 0x97); + +// {F752461C-1E23-48f6-B9F8-8350850F336F} +DEFINE_GUID(DXFILEOBJ_VertexElement, +0xf752461c, 0x1e23, 0x48f6, 0xb9, 0xf8, 0x83, 0x50, 0x85, 0xf, 0x33, 0x6f); + +// {BF22E553-292C-4781-9FEA-62BD554BDD93} +DEFINE_GUID(DXFILEOBJ_DeclData, +0xbf22e553, 0x292c, 0x4781, 0x9f, 0xea, 0x62, 0xbd, 0x55, 0x4b, 0xdd, 0x93); + +// {F1CFE2B3-0DE3-4e28-AFA1-155A750A282D} +DEFINE_GUID(DXFILEOBJ_EffectFloats, +0xf1cfe2b3, 0xde3, 0x4e28, 0xaf, 0xa1, 0x15, 0x5a, 0x75, 0xa, 0x28, 0x2d); + +// {D55B097E-BDB6-4c52-B03D-6051C89D0E42} +DEFINE_GUID(DXFILEOBJ_EffectString, +0xd55b097e, 0xbdb6, 0x4c52, 0xb0, 0x3d, 0x60, 0x51, 0xc8, 0x9d, 0xe, 0x42); + +// {622C0ED0-956E-4da9-908A-2AF94F3CE716} +DEFINE_GUID(DXFILEOBJ_EffectDWord, +0x622c0ed0, 0x956e, 0x4da9, 0x90, 0x8a, 0x2a, 0xf9, 0x4f, 0x3c, 0xe7, 0x16); + +// {3014B9A0-62F5-478c-9B86-E4AC9F4E418B} +DEFINE_GUID(DXFILEOBJ_EffectParamFloats, +0x3014b9a0, 0x62f5, 0x478c, 0x9b, 0x86, 0xe4, 0xac, 0x9f, 0x4e, 0x41, 0x8b); + +// {1DBC4C88-94C1-46ee-9076-2C28818C9481} +DEFINE_GUID(DXFILEOBJ_EffectParamString, +0x1dbc4c88, 0x94c1, 0x46ee, 0x90, 0x76, 0x2c, 0x28, 0x81, 0x8c, 0x94, 0x81); + +// {E13963BC-AE51-4c5d-B00F-CFA3A9D97CE5} +DEFINE_GUID(DXFILEOBJ_EffectParamDWord, +0xe13963bc, 0xae51, 0x4c5d, 0xb0, 0xf, 0xcf, 0xa3, 0xa9, 0xd9, 0x7c, 0xe5); + +// {E331F7E4-0559-4cc2-8E99-1CEC1657928F} +DEFINE_GUID(DXFILEOBJ_EffectInstance, +0xe331f7e4, 0x559, 0x4cc2, 0x8e, 0x99, 0x1c, 0xec, 0x16, 0x57, 0x92, 0x8f); + +// {9E415A43-7BA6-4a73-8743-B73D47E88476} +DEFINE_GUID(DXFILEOBJ_AnimTicksPerSecond, +0x9e415a43, 0x7ba6, 0x4a73, 0x87, 0x43, 0xb7, 0x3d, 0x47, 0xe8, 0x84, 0x76); + +// {7F9B00B3-F125-4890-876E-1CFFBF697C4D} +DEFINE_GUID(DXFILEOBJ_CompressedAnimationSet, +0x7f9b00b3, 0xf125, 0x4890, 0x87, 0x6e, 0x1c, 0x42, 0xbf, 0x69, 0x7c, 0x4d); + +#pragma pack(push, 1) +typedef struct _XFILECOMPRESSEDANIMATIONSET +{ + DWORD CompressedBlockSize; + FLOAT TicksPerSec; + DWORD PlaybackType; + DWORD BufferLength; +} XFILECOMPRESSEDANIMATIONSET; +#pragma pack(pop) + +#define XSKINEXP_TEMPLATES \ + "xof 0303txt 0032\ + template XSkinMeshHeader \ + { \ + <3CF169CE-FF7C-44ab-93C0-F78F62D172E2> \ + WORD nMaxSkinWeightsPerVertex; \ + WORD nMaxSkinWeightsPerFace; \ + WORD nBones; \ + } \ + template VertexDuplicationIndices \ + { \ + \ + DWORD nIndices; \ + DWORD nOriginalVertices; \ + array DWORD indices[nIndices]; \ + } \ + template FaceAdjacency \ + { \ + \ + DWORD nIndices; \ + array DWORD indices[nIndices]; \ + } \ + template SkinWeights \ + { \ + <6F0D123B-BAD2-4167-A0D0-80224F25FABB> \ + STRING transformNodeName; \ + DWORD nWeights; \ + array DWORD vertexIndices[nWeights]; \ + array float weights[nWeights]; \ + Matrix4x4 matrixOffset; \ + } \ + template Patch \ + { \ + \ + DWORD nControlIndices; \ + array DWORD controlIndices[nControlIndices]; \ + } \ + template PatchMesh \ + { \ + \ + DWORD nVertices; \ + array Vector vertices[nVertices]; \ + DWORD nPatches; \ + array Patch patches[nPatches]; \ + [ ... ] \ + } \ + template PatchMesh9 \ + { \ + \ + DWORD Type; \ + DWORD Degree; \ + DWORD Basis; \ + DWORD nVertices; \ + array Vector vertices[nVertices]; \ + DWORD nPatches; \ + array Patch patches[nPatches]; \ + [ ... ] \ + } " \ + "template EffectFloats \ + { \ + \ + DWORD nFloats; \ + array float Floats[nFloats]; \ + } \ + template EffectString \ + { \ + \ + STRING Value; \ + } \ + template EffectDWord \ + { \ + <622C0ED0-956E-4da9-908A-2AF94F3CE716> \ + DWORD Value; \ + } " \ + "template EffectParamFloats \ + { \ + <3014B9A0-62F5-478c-9B86-E4AC9F4E418B> \ + STRING ParamName; \ + DWORD nFloats; \ + array float Floats[nFloats]; \ + } " \ + "template EffectParamString \ + { \ + <1DBC4C88-94C1-46ee-9076-2C28818C9481> \ + STRING ParamName; \ + STRING Value; \ + } \ + template EffectParamDWord \ + { \ + \ + STRING ParamName; \ + DWORD Value; \ + } \ + template EffectInstance \ + { \ + \ + STRING EffectFilename; \ + [ ... ] \ + } " \ + "template AnimTicksPerSecond \ + { \ + <9E415A43-7BA6-4a73-8743-B73D47E88476> \ + DWORD AnimTicksPerSecond; \ + } \ + template CompressedAnimationSet \ + { \ + <7F9B00B3-F125-4890-876E-1C42BF697C4D> \ + DWORD CompressedBlockSize; \ + FLOAT TicksPerSec; \ + DWORD PlaybackType; \ + DWORD BufferLength; \ + array DWORD CompressedData[BufferLength]; \ + } " + +#define XEXTENSIONS_TEMPLATES \ + "xof 0303txt 0032\ + template FVFData \ + { \ + \ + DWORD dwFVF; \ + DWORD nDWords; \ + array DWORD data[nDWords]; \ + } \ + template VertexElement \ + { \ + \ + DWORD Type; \ + DWORD Method; \ + DWORD Usage; \ + DWORD UsageIndex; \ + } \ + template DeclData \ + { \ + \ + DWORD nElements; \ + array VertexElement Elements[nElements]; \ + DWORD nDWords; \ + array DWORD data[nDWords]; \ + } \ + template PMAttributeRange \ + { \ + <917E0427-C61E-4a14-9C64-AFE65F9E9844> \ + DWORD iFaceOffset; \ + DWORD nFacesMin; \ + DWORD nFacesMax; \ + DWORD iVertexOffset; \ + DWORD nVerticesMin; \ + DWORD nVerticesMax; \ + } \ + template PMVSplitRecord \ + { \ + <574CCC14-F0B3-4333-822D-93E8A8A08E4C> \ + DWORD iFaceCLW; \ + DWORD iVlrOffset; \ + DWORD iCode; \ + } \ + template PMInfo \ + { \ + \ + DWORD nAttributes; \ + array PMAttributeRange attributeRanges[nAttributes]; \ + DWORD nMaxValence; \ + DWORD nMinLogicalVertices; \ + DWORD nMaxLogicalVertices; \ + DWORD nVSplits; \ + array PMVSplitRecord splitRecords[nVSplits]; \ + DWORD nAttributeMispredicts; \ + array DWORD attributeMispredicts[nAttributeMispredicts]; \ + } " + +#endif //__D3DX9MESH_H__ + + diff --git a/dxsdk/Include/d3dx9shader.h b/dxsdk/Include/d3dx9shader.h new file mode 100644 index 0000000..5ed3f01 --- /dev/null +++ b/dxsdk/Include/d3dx9shader.h @@ -0,0 +1,1010 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: d3dx9shader.h +// Content: D3DX Shader APIs +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9SHADER_H__ +#define __D3DX9SHADER_H__ + + +//--------------------------------------------------------------------------- +// D3DXTX_VERSION: +// -------------- +// Version token used to create a procedural texture filler in effects +// Used by D3DXFill[]TX functions +//--------------------------------------------------------------------------- +#define D3DXTX_VERSION(_Major,_Minor) (('T' << 24) | ('X' << 16) | ((_Major) << 8) | (_Minor)) + + + +//---------------------------------------------------------------------------- +// D3DXSHADER flags: +// ----------------- +// D3DXSHADER_DEBUG +// Insert debug file/line/type/symbol information. +// +// D3DXSHADER_SKIPVALIDATION +// Do not validate the generated code against known capabilities and +// constraints. This option is only recommended when compiling shaders +// you KNOW will work. (ie. have compiled before without this option.) +// Shaders are always validated by D3D before they are set to the device. +// +// D3DXSHADER_SKIPOPTIMIZATION +// Instructs the compiler to skip optimization steps during code generation. +// Unless you are trying to isolate a problem in your code using this option +// is not recommended. +// +// D3DXSHADER_PACKMATRIX_ROWMAJOR +// Unless explicitly specified, matrices will be packed in row-major order +// on input and output from the shader. +// +// D3DXSHADER_PACKMATRIX_COLUMNMAJOR +// Unless explicitly specified, matrices will be packed in column-major +// order on input and output from the shader. This is generally more +// efficient, since it allows vector-matrix multiplication to be performed +// using a series of dot-products. +// +// D3DXSHADER_PARTIALPRECISION +// Force all computations in resulting shader to occur at partial precision. +// This may result in faster evaluation of shaders on some hardware. +// +// D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT +// Force compiler to compile against the next highest available software +// target for vertex shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT +// Force compiler to compile against the next highest available software +// target for pixel shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DXSHADER_NO_PRESHADER +// Disables Preshaders. Using this flag will cause the compiler to not +// pull out static expression for evaluation on the host cpu +// +// D3DXSHADER_AVOID_FLOW_CONTROL +// Hint compiler to avoid flow-control constructs where possible. +// +// D3DXSHADER_PREFER_FLOW_CONTROL +// Hint compiler to prefer flow-control constructs where possible. +// +//---------------------------------------------------------------------------- + +#define D3DXSHADER_DEBUG (1 << 0) +#define D3DXSHADER_SKIPVALIDATION (1 << 1) +#define D3DXSHADER_SKIPOPTIMIZATION (1 << 2) +#define D3DXSHADER_PACKMATRIX_ROWMAJOR (1 << 3) +#define D3DXSHADER_PACKMATRIX_COLUMNMAJOR (1 << 4) +#define D3DXSHADER_PARTIALPRECISION (1 << 5) +#define D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT (1 << 6) +#define D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT (1 << 7) +#define D3DXSHADER_NO_PRESHADER (1 << 8) +#define D3DXSHADER_AVOID_FLOW_CONTROL (1 << 9) +#define D3DXSHADER_PREFER_FLOW_CONTROL (1 << 10) +#define D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY (1 << 12) +#define D3DXSHADER_IEEE_STRICTNESS (1 << 13) +#define D3DXSHADER_USE_LEGACY_D3DX9_31_DLL (1 << 16) + + +// optimization level flags +#define D3DXSHADER_OPTIMIZATION_LEVEL0 (1 << 14) +#define D3DXSHADER_OPTIMIZATION_LEVEL1 0 +#define D3DXSHADER_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15)) +#define D3DXSHADER_OPTIMIZATION_LEVEL3 (1 << 15) + + + +//---------------------------------------------------------------------------- +// D3DXCONSTTABLE flags: +// ------------------- + +#define D3DXCONSTTABLE_LARGEADDRESSAWARE (1 << 17) + + + +//---------------------------------------------------------------------------- +// D3DXHANDLE: +// ----------- +// Handle values used to efficiently reference shader and effect parameters. +// Strings can be used as handles. However, handles are not always strings. +//---------------------------------------------------------------------------- + +#ifndef D3DXFX_LARGEADDRESS_HANDLE +typedef LPCSTR D3DXHANDLE; +#else +typedef UINT_PTR D3DXHANDLE; +#endif +typedef D3DXHANDLE *LPD3DXHANDLE; + + +//---------------------------------------------------------------------------- +// D3DXMACRO: +// ---------- +// Preprocessor macro definition. The application pass in a NULL-terminated +// array of this structure to various D3DX APIs. This enables the application +// to #define tokens at runtime, before the file is parsed. +//---------------------------------------------------------------------------- + +typedef struct _D3DXMACRO +{ + LPCSTR Name; + LPCSTR Definition; + +} D3DXMACRO, *LPD3DXMACRO; + + +//---------------------------------------------------------------------------- +// D3DXSEMANTIC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXSEMANTIC +{ + UINT Usage; + UINT UsageIndex; + +} D3DXSEMANTIC, *LPD3DXSEMANTIC; + + + +//---------------------------------------------------------------------------- +// D3DXREGISTER_SET: +//---------------------------------------------------------------------------- + +typedef enum _D3DXREGISTER_SET +{ + D3DXRS_BOOL, + D3DXRS_INT4, + D3DXRS_FLOAT4, + D3DXRS_SAMPLER, + + // force 32-bit size enum + D3DXRS_FORCE_DWORD = 0x7fffffff + +} D3DXREGISTER_SET, *LPD3DXREGISTER_SET; + + +//---------------------------------------------------------------------------- +// D3DXPARAMETER_CLASS: +//---------------------------------------------------------------------------- + +typedef enum _D3DXPARAMETER_CLASS +{ + D3DXPC_SCALAR, + D3DXPC_VECTOR, + D3DXPC_MATRIX_ROWS, + D3DXPC_MATRIX_COLUMNS, + D3DXPC_OBJECT, + D3DXPC_STRUCT, + + // force 32-bit size enum + D3DXPC_FORCE_DWORD = 0x7fffffff + +} D3DXPARAMETER_CLASS, *LPD3DXPARAMETER_CLASS; + + +//---------------------------------------------------------------------------- +// D3DXPARAMETER_TYPE: +//---------------------------------------------------------------------------- + +typedef enum _D3DXPARAMETER_TYPE +{ + D3DXPT_VOID, + D3DXPT_BOOL, + D3DXPT_INT, + D3DXPT_FLOAT, + D3DXPT_STRING, + D3DXPT_TEXTURE, + D3DXPT_TEXTURE1D, + D3DXPT_TEXTURE2D, + D3DXPT_TEXTURE3D, + D3DXPT_TEXTURECUBE, + D3DXPT_SAMPLER, + D3DXPT_SAMPLER1D, + D3DXPT_SAMPLER2D, + D3DXPT_SAMPLER3D, + D3DXPT_SAMPLERCUBE, + D3DXPT_PIXELSHADER, + D3DXPT_VERTEXSHADER, + D3DXPT_PIXELFRAGMENT, + D3DXPT_VERTEXFRAGMENT, + D3DXPT_UNSUPPORTED, + + // force 32-bit size enum + D3DXPT_FORCE_DWORD = 0x7fffffff + +} D3DXPARAMETER_TYPE, *LPD3DXPARAMETER_TYPE; + + +//---------------------------------------------------------------------------- +// D3DXCONSTANTTABLE_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXCONSTANTTABLE_DESC +{ + LPCSTR Creator; // Creator string + DWORD Version; // Shader version + UINT Constants; // Number of constants + +} D3DXCONSTANTTABLE_DESC, *LPD3DXCONSTANTTABLE_DESC; + + +//---------------------------------------------------------------------------- +// D3DXCONSTANT_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXCONSTANT_DESC +{ + LPCSTR Name; // Constant name + + D3DXREGISTER_SET RegisterSet; // Register set + UINT RegisterIndex; // Register index + UINT RegisterCount; // Number of registers occupied + + D3DXPARAMETER_CLASS Class; // Class + D3DXPARAMETER_TYPE Type; // Component type + + UINT Rows; // Number of rows + UINT Columns; // Number of columns + UINT Elements; // Number of array elements + UINT StructMembers; // Number of structure member sub-parameters + + UINT Bytes; // Data size, in bytes + LPCVOID DefaultValue; // Pointer to default value + +} D3DXCONSTANT_DESC, *LPD3DXCONSTANT_DESC; + + + +//---------------------------------------------------------------------------- +// ID3DXConstantTable: +//---------------------------------------------------------------------------- + +typedef interface ID3DXConstantTable ID3DXConstantTable; +typedef interface ID3DXConstantTable *LPD3DXCONSTANTTABLE; + +// {AB3C758F-093E-4356-B762-4DB18F1B3A01} +DEFINE_GUID(IID_ID3DXConstantTable, +0xab3c758f, 0x93e, 0x4356, 0xb7, 0x62, 0x4d, 0xb1, 0x8f, 0x1b, 0x3a, 0x1); + + +#undef INTERFACE +#define INTERFACE ID3DXConstantTable + +DECLARE_INTERFACE_(ID3DXConstantTable, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Buffer + STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; + STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXCONSTANTTABLE_DESC *pDesc) PURE; + STDMETHOD(GetConstantDesc)(THIS_ D3DXHANDLE hConstant, D3DXCONSTANT_DESC *pConstantDesc, UINT *pCount) PURE; + STDMETHOD_(UINT, GetSamplerIndex)(THIS_ D3DXHANDLE hConstant) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetConstant)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantByName)(THIS_ D3DXHANDLE hConstant, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantElement)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + + // Set Constants + STDMETHOD(SetDefaults)(THIS_ LPDIRECT3DDEVICE9 pDevice) PURE; + STDMETHOD(SetValue)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, BOOL b) PURE; + STDMETHOD(SetBoolArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, INT n) PURE; + STDMETHOD(SetIntArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, FLOAT f) PURE; + STDMETHOD(SetFloatArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; +}; + + +//---------------------------------------------------------------------------- +// ID3DXTextureShader: +//---------------------------------------------------------------------------- + +typedef interface ID3DXTextureShader ID3DXTextureShader; +typedef interface ID3DXTextureShader *LPD3DXTEXTURESHADER; + +// {3E3D67F8-AA7A-405d-A857-BA01D4758426} +DEFINE_GUID(IID_ID3DXTextureShader, +0x3e3d67f8, 0xaa7a, 0x405d, 0xa8, 0x57, 0xba, 0x1, 0xd4, 0x75, 0x84, 0x26); + +#undef INTERFACE +#define INTERFACE ID3DXTextureShader + +DECLARE_INTERFACE_(ID3DXTextureShader, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Gets + STDMETHOD(GetFunction)(THIS_ LPD3DXBUFFER *ppFunction) PURE; + STDMETHOD(GetConstantBuffer)(THIS_ LPD3DXBUFFER *ppConstantBuffer) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXCONSTANTTABLE_DESC *pDesc) PURE; + STDMETHOD(GetConstantDesc)(THIS_ D3DXHANDLE hConstant, D3DXCONSTANT_DESC *pConstantDesc, UINT *pCount) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetConstant)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantByName)(THIS_ D3DXHANDLE hConstant, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantElement)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + + // Set Constants + STDMETHOD(SetDefaults)(THIS) PURE; + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hConstant, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hConstant, BOOL b) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hConstant, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hConstant, INT n) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hConstant, CONST INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hConstant, FLOAT f) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hConstant, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; +}; + + +//---------------------------------------------------------------------------- +// D3DXINCLUDE_TYPE: +//---------------------------------------------------------------------------- + +typedef enum _D3DXINCLUDE_TYPE +{ + D3DXINC_LOCAL, + D3DXINC_SYSTEM, + + // force 32-bit size enum + D3DXINC_FORCE_DWORD = 0x7fffffff + +} D3DXINCLUDE_TYPE, *LPD3DXINCLUDE_TYPE; + + +//---------------------------------------------------------------------------- +// ID3DXInclude: +// ------------- +// This interface is intended to be implemented by the application, and can +// be used by various D3DX APIs. This enables application-specific handling +// of #include directives in source files. +// +// Open() +// Opens an include file. If successful, it should fill in ppData and +// pBytes. The data pointer returned must remain valid until Close is +// subsequently called. The name of the file is encoded in UTF-8 format. +// Close() +// Closes an include file. If Open was successful, Close is guaranteed +// to be called before the API using this interface returns. +//---------------------------------------------------------------------------- + +typedef interface ID3DXInclude ID3DXInclude; +typedef interface ID3DXInclude *LPD3DXINCLUDE; + +#undef INTERFACE +#define INTERFACE ID3DXInclude + +DECLARE_INTERFACE(ID3DXInclude) +{ + STDMETHOD(Open)(THIS_ D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE; + STDMETHOD(Close)(THIS_ LPCVOID pData) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3DXAssembleShader: +// ------------------- +// Assembles a shader. +// +// Parameters: +// pSrcFile +// Source file name +// hSrcModule +// Module handle. if NULL, current module will be used +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to source code +// SrcDataLen +// Size of source code, in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when assembling +// from file, and will error when assembling from resource or memory. +// Flags +// See D3DXSHADER_xxx flags +// ppShader +// Returns a buffer containing the created shader. This buffer contains +// the assembled shader code, as well as any embedded debug info. +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during assembly. If you are running in a debugger, +// these are the same messages you will see in your debug output. +//---------------------------------------------------------------------------- + + +HRESULT WINAPI + D3DXAssembleShaderFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXAssembleShaderFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileW +#else +#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileA +#endif + + +HRESULT WINAPI + D3DXAssembleShaderFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXAssembleShaderFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceW +#else +#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceA +#endif + + +HRESULT WINAPI + D3DXAssembleShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + + + +//---------------------------------------------------------------------------- +// D3DXCompileShader: +// ------------------ +// Compiles a shader. +// +// Parameters: +// pSrcFile +// Source file name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module. +// pSrcData +// Pointer to source code. +// SrcDataLen +// Size of source code, in bytes. +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pFunctionName +// Name of the entrypoint function where execution should begin. +// pProfile +// Instruction set to be used when generating code. Currently supported +// profiles are "vs_1_1", "vs_2_0", "vs_2_a", "vs_2_sw", "ps_1_1", +// "ps_1_2", "ps_1_3", "ps_1_4", "ps_2_0", "ps_2_a", "ps_2_sw", "tx_1_0" +// Flags +// See D3DXSHADER_xxx flags. +// ppShader +// Returns a buffer containing the created shader. This buffer contains +// the compiled shader code, as well as any embedded debug and symbol +// table info. (See D3DXGetShaderConstantTable) +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during the compile. If you are running in a debugger, +// these are the same messages you will see in your debug output. +// ppConstantTable +// Returns a ID3DXConstantTable object which can be used to set +// shader constants to the device. Alternatively, an application can +// parse the D3DXSHADER_CONSTANTTABLE block embedded as a comment within +// the shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCompileShaderFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +HRESULT WINAPI + D3DXCompileShaderFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +#ifdef UNICODE +#define D3DXCompileShaderFromFile D3DXCompileShaderFromFileW +#else +#define D3DXCompileShaderFromFile D3DXCompileShaderFromFileA +#endif + + +HRESULT WINAPI + D3DXCompileShaderFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +HRESULT WINAPI + D3DXCompileShaderFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +#ifdef UNICODE +#define D3DXCompileShaderFromResource D3DXCompileShaderFromResourceW +#else +#define D3DXCompileShaderFromResource D3DXCompileShaderFromResourceA +#endif + + +HRESULT WINAPI + D3DXCompileShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + + +//---------------------------------------------------------------------------- +// D3DXDisassembleShader: +// ---------------------- +// Takes a binary shader, and returns a buffer containing text assembly. +// +// Parameters: +// pShader +// Pointer to the shader byte code. +// ShaderSizeInBytes +// Size of the shader byte code in bytes. +// EnableColorCode +// Emit HTML tags for color coding the output? +// pComments +// Pointer to a comment string to include at the top of the shader. +// ppDisassembly +// Returns a buffer containing the disassembled shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXDisassembleShader( + CONST DWORD* pShader, + BOOL EnableColorCode, + LPCSTR pComments, + LPD3DXBUFFER* ppDisassembly); + + +//---------------------------------------------------------------------------- +// D3DXGetPixelShaderProfile/D3DXGetVertexShaderProfile: +// ----------------------------------------------------- +// Returns the name of the HLSL profile best suited to a given device. +// +// Parameters: +// pDevice +// Pointer to the device in question +//---------------------------------------------------------------------------- + +LPCSTR WINAPI + D3DXGetPixelShaderProfile( + LPDIRECT3DDEVICE9 pDevice); + +LPCSTR WINAPI + D3DXGetVertexShaderProfile( + LPDIRECT3DDEVICE9 pDevice); + + +//---------------------------------------------------------------------------- +// D3DXFindShaderComment: +// ---------------------- +// Searches through a shader for a particular comment, denoted by a FourCC in +// the first DWORD of the comment. If the comment is not found, and no other +// error has occurred, S_FALSE is returned. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +// FourCC +// FourCC used to identify the desired comment block. +// ppData +// Returns a pointer to the comment data (not including comment token +// and FourCC). Can be NULL. +// pSizeInBytes +// Returns the size of the comment data in bytes. Can be NULL. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFindShaderComment( + CONST DWORD* pFunction, + DWORD FourCC, + LPCVOID* ppData, + UINT* pSizeInBytes); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderSize: +// ------------------ +// Returns the size of the shader byte-code, in bytes. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +//---------------------------------------------------------------------------- + +UINT WINAPI + D3DXGetShaderSize( + CONST DWORD* pFunction); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderVersion: +// ----------------------- +// Returns the shader version of a given shader. Returns zero if the shader +// function is NULL. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +//---------------------------------------------------------------------------- + +DWORD WINAPI + D3DXGetShaderVersion( + CONST DWORD* pFunction); + +//---------------------------------------------------------------------------- +// D3DXGetShaderSemantics: +// ----------------------- +// Gets semantics for all input elements referenced inside a given shader. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +// pSemantics +// Pointer to an array of D3DXSEMANTIC structures. The function will +// fill this array with the semantics for each input element referenced +// inside the shader. This array is assumed to contain at least +// MAXD3DDECLLENGTH elements. +// pCount +// Returns the number of elements referenced by the shader +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetShaderInputSemantics( + CONST DWORD* pFunction, + D3DXSEMANTIC* pSemantics, + UINT* pCount); + +HRESULT WINAPI + D3DXGetShaderOutputSemantics( + CONST DWORD* pFunction, + D3DXSEMANTIC* pSemantics, + UINT* pCount); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderSamplers: +// ---------------------- +// Gets semantics for all input elements referenced inside a given shader. +// +// pFunction +// Pointer to the function DWORD stream +// pSamplers +// Pointer to an array of LPCSTRs. The function will fill this array +// with pointers to the sampler names contained within pFunction, for +// each sampler referenced inside the shader. This array is assumed to +// contain at least 16 elements. +// pCount +// Returns the number of samplers referenced by the shader +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetShaderSamplers( + CONST DWORD* pFunction, + LPCSTR* pSamplers, + UINT* pCount); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderConstantTable: +// --------------------------- +// Gets shader constant table embedded inside shader. A constant table is +// generated by D3DXAssembleShader and D3DXCompileShader, and is embedded in +// the body of the shader. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +// Flags +// See D3DXCONSTTABLE_xxx +// ppConstantTable +// Returns a ID3DXConstantTable object which can be used to set +// shader constants to the device. Alternatively, an application can +// parse the D3DXSHADER_CONSTANTTABLE block embedded as a comment within +// the shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetShaderConstantTable( + CONST DWORD* pFunction, + LPD3DXCONSTANTTABLE* ppConstantTable); + +HRESULT WINAPI + D3DXGetShaderConstantTableEx( + CONST DWORD* pFunction, + DWORD Flags, + LPD3DXCONSTANTTABLE* ppConstantTable); + + + +//---------------------------------------------------------------------------- +// D3DXCreateTextureShader: +// ------------------------ +// Creates a texture shader object, given the compiled shader. +// +// Parameters +// pFunction +// Pointer to the function DWORD stream +// ppTextureShader +// Returns a ID3DXTextureShader object which can be used to procedurally +// fill the contents of a texture using the D3DXFillTextureTX functions. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateTextureShader( + CONST DWORD* pFunction, + LPD3DXTEXTURESHADER* ppTextureShader); + + +//---------------------------------------------------------------------------- +// D3DXPreprocessShader: +// --------------------- +// Runs the preprocessor on the specified shader or effect, but does +// not actually compile it. This is useful for evaluating the #includes +// and #defines in a shader and then emitting a reformatted token stream +// for debugging purposes or for generating a self-contained shader. +// +// Parameters: +// pSrcFile +// Source file name +// hSrcModule +// Module handle. if NULL, current module will be used +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to source code +// SrcDataLen +// Size of source code, in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when assembling +// from file, and will error when assembling from resource or memory. +// ppShaderText +// Returns a buffer containing a single large string that represents +// the resulting formatted token stream +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during assembly. If you are running in a debugger, +// these are the same messages you will see in your debug output. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXPreprocessShaderFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXPreprocessShaderFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXPreprocessShaderFromFile D3DXPreprocessShaderFromFileW +#else +#define D3DXPreprocessShaderFromFile D3DXPreprocessShaderFromFileA +#endif + +HRESULT WINAPI + D3DXPreprocessShaderFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXPreprocessShaderFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXPreprocessShaderFromResource D3DXPreprocessShaderFromResourceW +#else +#define D3DXPreprocessShaderFromResource D3DXPreprocessShaderFromResourceA +#endif + +HRESULT WINAPI + D3DXPreprocessShader( + LPCSTR pSrcData, + UINT SrcDataSize, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + + +#ifdef __cplusplus +} +#endif //__cplusplus + + +////////////////////////////////////////////////////////////////////////////// +// Shader comment block layouts ////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXSHADER_CONSTANTTABLE: +// ------------------------- +// Shader constant information; included as an CTAB comment block inside +// shaders. All offsets are BYTE offsets from start of CONSTANTTABLE struct. +// Entries in the table are sorted by Name in ascending order. +//---------------------------------------------------------------------------- + +typedef struct _D3DXSHADER_CONSTANTTABLE +{ + DWORD Size; // sizeof(D3DXSHADER_CONSTANTTABLE) + DWORD Creator; // LPCSTR offset + DWORD Version; // shader version + DWORD Constants; // number of constants + DWORD ConstantInfo; // D3DXSHADER_CONSTANTINFO[Constants] offset + DWORD Flags; // flags shader was compiled with + DWORD Target; // LPCSTR offset + +} D3DXSHADER_CONSTANTTABLE, *LPD3DXSHADER_CONSTANTTABLE; + + +typedef struct _D3DXSHADER_CONSTANTINFO +{ + DWORD Name; // LPCSTR offset + WORD RegisterSet; // D3DXREGISTER_SET + WORD RegisterIndex; // register number + WORD RegisterCount; // number of registers + WORD Reserved; // reserved + DWORD TypeInfo; // D3DXSHADER_TYPEINFO offset + DWORD DefaultValue; // offset of default value + +} D3DXSHADER_CONSTANTINFO, *LPD3DXSHADER_CONSTANTINFO; + + +typedef struct _D3DXSHADER_TYPEINFO +{ + WORD Class; // D3DXPARAMETER_CLASS + WORD Type; // D3DXPARAMETER_TYPE + WORD Rows; // number of rows (matrices) + WORD Columns; // number of columns (vectors and matrices) + WORD Elements; // array dimension + WORD StructMembers; // number of struct members + DWORD StructMemberInfo; // D3DXSHADER_STRUCTMEMBERINFO[Members] offset + +} D3DXSHADER_TYPEINFO, *LPD3DXSHADER_TYPEINFO; + + +typedef struct _D3DXSHADER_STRUCTMEMBERINFO +{ + DWORD Name; // LPCSTR offset + DWORD TypeInfo; // D3DXSHADER_TYPEINFO offset + +} D3DXSHADER_STRUCTMEMBERINFO, *LPD3DXSHADER_STRUCTMEMBERINFO; + + + +#endif //__D3DX9SHADER_H__ + diff --git a/dxsdk/Include/d3dx9shape.h b/dxsdk/Include/d3dx9shape.h new file mode 100644 index 0000000..4c23091 --- /dev/null +++ b/dxsdk/Include/d3dx9shape.h @@ -0,0 +1,221 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9shapes.h +// Content: D3DX simple shapes +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9SHAPES_H__ +#define __D3DX9SHAPES_H__ + +/////////////////////////////////////////////////////////////////////////// +// Functions: +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//------------------------------------------------------------------------- +// D3DXCreatePolygon: +// ------------------ +// Creates a mesh containing an n-sided polygon. The polygon is centered +// at the origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Length Length of each side. +// Sides Number of sides the polygon has. (Must be >= 3) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreatePolygon( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Length, + UINT Sides, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateBox: +// -------------- +// Creates a mesh containing an axis-aligned box. The box is centered at +// the origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Width Width of box (along X-axis) +// Height Height of box (along Y-axis) +// Depth Depth of box (along Z-axis) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateBox( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Width, + FLOAT Height, + FLOAT Depth, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateCylinder: +// ------------------- +// Creates a mesh containing a cylinder. The generated cylinder is +// centered at the origin, and its axis is aligned with the Z-axis. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Radius1 Radius at -Z end (should be >= 0.0f) +// Radius2 Radius at +Z end (should be >= 0.0f) +// Length Length of cylinder (along Z-axis) +// Slices Number of slices about the main axis +// Stacks Number of stacks along the main axis +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateCylinder( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Radius1, + FLOAT Radius2, + FLOAT Length, + UINT Slices, + UINT Stacks, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateSphere: +// ----------------- +// Creates a mesh containing a sphere. The sphere is centered at the +// origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Radius Radius of the sphere (should be >= 0.0f) +// Slices Number of slices about the main axis +// Stacks Number of stacks along the main axis +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateSphere( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Radius, + UINT Slices, + UINT Stacks, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateTorus: +// ---------------- +// Creates a mesh containing a torus. The generated torus is centered at +// the origin, and its axis is aligned with the Z-axis. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// InnerRadius Inner radius of the torus (should be >= 0.0f) +// OuterRadius Outer radius of the torue (should be >= 0.0f) +// Sides Number of sides in a cross-section (must be >= 3) +// Rings Number of rings making up the torus (must be >= 3) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTorus( + LPDIRECT3DDEVICE9 pDevice, + FLOAT InnerRadius, + FLOAT OuterRadius, + UINT Sides, + UINT Rings, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateTeapot: +// ----------------- +// Creates a mesh containing a teapot. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTeapot( + LPDIRECT3DDEVICE9 pDevice, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateText: +// --------------- +// Creates a mesh containing the specified text using the font associated +// with the device context. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// hDC Device context, with desired font selected +// pText Text to generate +// Deviation Maximum chordal deviation from true font outlines +// Extrusion Amount to extrude text in -Z direction +// ppMesh The mesh object which will be created +// pGlyphMetrics Address of buffer to receive glyph metric data (or NULL) +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTextA( + LPDIRECT3DDEVICE9 pDevice, + HDC hDC, + LPCSTR pText, + FLOAT Deviation, + FLOAT Extrusion, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency, + LPGLYPHMETRICSFLOAT pGlyphMetrics); + +HRESULT WINAPI + D3DXCreateTextW( + LPDIRECT3DDEVICE9 pDevice, + HDC hDC, + LPCWSTR pText, + FLOAT Deviation, + FLOAT Extrusion, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency, + LPGLYPHMETRICSFLOAT pGlyphMetrics); + +#ifdef UNICODE +#define D3DXCreateText D3DXCreateTextW +#else +#define D3DXCreateText D3DXCreateTextA +#endif + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9SHAPES_H__ + diff --git a/dxsdk/Include/d3dx9tex.h b/dxsdk/Include/d3dx9tex.h new file mode 100644 index 0000000..c4b6510 --- /dev/null +++ b/dxsdk/Include/d3dx9tex.h @@ -0,0 +1,1735 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9tex.h +// Content: D3DX texturing APIs +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9TEX_H__ +#define __D3DX9TEX_H__ + + +//---------------------------------------------------------------------------- +// D3DX_FILTER flags: +// ------------------ +// +// A valid filter must contain one of these values: +// +// D3DX_FILTER_NONE +// No scaling or filtering will take place. Pixels outside the bounds +// of the source image are assumed to be transparent black. +// D3DX_FILTER_POINT +// Each destination pixel is computed by sampling the nearest pixel +// from the source image. +// D3DX_FILTER_LINEAR +// Each destination pixel is computed by linearly interpolating between +// the nearest pixels in the source image. This filter works best +// when the scale on each axis is less than 2. +// D3DX_FILTER_TRIANGLE +// Every pixel in the source image contributes equally to the +// destination image. This is the slowest of all the filters. +// D3DX_FILTER_BOX +// Each pixel is computed by averaging a 2x2(x2) box pixels from +// the source image. Only works when the dimensions of the +// destination are half those of the source. (as with mip maps) +// +// And can be OR'd with any of these optional flags: +// +// D3DX_FILTER_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR_W +// Indicates that pixels off the edge of the texture on the W-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR +// Same as specifying D3DX_FILTER_MIRROR_U | D3DX_FILTER_MIRROR_V | +// D3DX_FILTER_MIRROR_V +// D3DX_FILTER_DITHER +// Dithers the resulting image using a 4x4 order dither pattern. +// D3DX_FILTER_SRGB_IN +// Denotes that the input data is in sRGB (gamma 2.2) colorspace. +// D3DX_FILTER_SRGB_OUT +// Denotes that the output data is in sRGB (gamma 2.2) colorspace. +// D3DX_FILTER_SRGB +// Same as specifying D3DX_FILTER_SRGB_IN | D3DX_FILTER_SRGB_OUT +// +//---------------------------------------------------------------------------- + +#define D3DX_FILTER_NONE (1 << 0) +#define D3DX_FILTER_POINT (2 << 0) +#define D3DX_FILTER_LINEAR (3 << 0) +#define D3DX_FILTER_TRIANGLE (4 << 0) +#define D3DX_FILTER_BOX (5 << 0) + +#define D3DX_FILTER_MIRROR_U (1 << 16) +#define D3DX_FILTER_MIRROR_V (2 << 16) +#define D3DX_FILTER_MIRROR_W (4 << 16) +#define D3DX_FILTER_MIRROR (7 << 16) + +#define D3DX_FILTER_DITHER (1 << 19) +#define D3DX_FILTER_DITHER_DIFFUSION (2 << 19) + +#define D3DX_FILTER_SRGB_IN (1 << 21) +#define D3DX_FILTER_SRGB_OUT (2 << 21) +#define D3DX_FILTER_SRGB (3 << 21) + + +//----------------------------------------------------------------------------- +// D3DX_SKIP_DDS_MIP_LEVELS is used to skip mip levels when loading a DDS file: +//----------------------------------------------------------------------------- + +#define D3DX_SKIP_DDS_MIP_LEVELS_MASK 0x1F +#define D3DX_SKIP_DDS_MIP_LEVELS_SHIFT 26 +#define D3DX_SKIP_DDS_MIP_LEVELS(levels, filter) ((((levels) & D3DX_SKIP_DDS_MIP_LEVELS_MASK) << D3DX_SKIP_DDS_MIP_LEVELS_SHIFT) | ((filter) == D3DX_DEFAULT ? D3DX_FILTER_BOX : (filter))) + + + + +//---------------------------------------------------------------------------- +// D3DX_NORMALMAP flags: +// --------------------- +// These flags are used to control how D3DXComputeNormalMap generates normal +// maps. Any number of these flags may be OR'd together in any combination. +// +// D3DX_NORMALMAP_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX_NORMALMAP_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX_NORMALMAP_MIRROR +// Same as specifying D3DX_NORMALMAP_MIRROR_U | D3DX_NORMALMAP_MIRROR_V +// D3DX_NORMALMAP_INVERTSIGN +// Inverts the direction of each normal +// D3DX_NORMALMAP_COMPUTE_OCCLUSION +// Compute the per pixel Occlusion term and encodes it into the alpha. +// An Alpha of 1 means that the pixel is not obscured in anyway, and +// an alpha of 0 would mean that the pixel is completly obscured. +// +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +#define D3DX_NORMALMAP_MIRROR_U (1 << 16) +#define D3DX_NORMALMAP_MIRROR_V (2 << 16) +#define D3DX_NORMALMAP_MIRROR (3 << 16) +#define D3DX_NORMALMAP_INVERTSIGN (8 << 16) +#define D3DX_NORMALMAP_COMPUTE_OCCLUSION (16 << 16) + + + + +//---------------------------------------------------------------------------- +// D3DX_CHANNEL flags: +// ------------------- +// These flags are used by functions which operate on or more channels +// in a texture. +// +// D3DX_CHANNEL_RED +// Indicates the red channel should be used +// D3DX_CHANNEL_BLUE +// Indicates the blue channel should be used +// D3DX_CHANNEL_GREEN +// Indicates the green channel should be used +// D3DX_CHANNEL_ALPHA +// Indicates the alpha channel should be used +// D3DX_CHANNEL_LUMINANCE +// Indicates the luminaces of the red green and blue channels should be +// used. +// +//---------------------------------------------------------------------------- + +#define D3DX_CHANNEL_RED (1 << 0) +#define D3DX_CHANNEL_BLUE (1 << 1) +#define D3DX_CHANNEL_GREEN (1 << 2) +#define D3DX_CHANNEL_ALPHA (1 << 3) +#define D3DX_CHANNEL_LUMINANCE (1 << 4) + + + + +//---------------------------------------------------------------------------- +// D3DXIMAGE_FILEFORMAT: +// --------------------- +// This enum is used to describe supported image file formats. +// +//---------------------------------------------------------------------------- + +typedef enum _D3DXIMAGE_FILEFORMAT +{ + D3DXIFF_BMP = 0, + D3DXIFF_JPG = 1, + D3DXIFF_TGA = 2, + D3DXIFF_PNG = 3, + D3DXIFF_DDS = 4, + D3DXIFF_PPM = 5, + D3DXIFF_DIB = 6, + D3DXIFF_HDR = 7, //high dynamic range formats + D3DXIFF_PFM = 8, // + D3DXIFF_FORCE_DWORD = 0x7fffffff + +} D3DXIMAGE_FILEFORMAT; + + +//---------------------------------------------------------------------------- +// LPD3DXFILL2D and LPD3DXFILL3D: +// ------------------------------ +// Function types used by the texture fill functions. +// +// Parameters: +// pOut +// Pointer to a vector which the function uses to return its result. +// X,Y,Z,W will be mapped to R,G,B,A respectivly. +// pTexCoord +// Pointer to a vector containing the coordinates of the texel currently +// being evaluated. Textures and VolumeTexture texcoord components +// range from 0 to 1. CubeTexture texcoord component range from -1 to 1. +// pTexelSize +// Pointer to a vector containing the dimensions of the current texel. +// pData +// Pointer to user data. +// +//---------------------------------------------------------------------------- + +typedef VOID (WINAPI *LPD3DXFILL2D)(D3DXVECTOR4 *pOut, + CONST D3DXVECTOR2 *pTexCoord, CONST D3DXVECTOR2 *pTexelSize, LPVOID pData); + +typedef VOID (WINAPI *LPD3DXFILL3D)(D3DXVECTOR4 *pOut, + CONST D3DXVECTOR3 *pTexCoord, CONST D3DXVECTOR3 *pTexelSize, LPVOID pData); + + + +//---------------------------------------------------------------------------- +// D3DXIMAGE_INFO: +// --------------- +// This structure is used to return a rough description of what the +// the original contents of an image file looked like. +// +// Width +// Width of original image in pixels +// Height +// Height of original image in pixels +// Depth +// Depth of original image in pixels +// MipLevels +// Number of mip levels in original image +// Format +// D3D format which most closely describes the data in original image +// ResourceType +// D3DRESOURCETYPE representing the type of texture stored in the file. +// D3DRTYPE_TEXTURE, D3DRTYPE_VOLUMETEXTURE, or D3DRTYPE_CUBETEXTURE. +// ImageFileFormat +// D3DXIMAGE_FILEFORMAT representing the format of the image file. +// +//---------------------------------------------------------------------------- + +typedef struct _D3DXIMAGE_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + D3DFORMAT Format; + D3DRESOURCETYPE ResourceType; + D3DXIMAGE_FILEFORMAT ImageFileFormat; + +} D3DXIMAGE_INFO; + + + + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// Image File APIs /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +; +//---------------------------------------------------------------------------- +// GetImageInfoFromFile/Resource: +// ------------------------------ +// Fills in a D3DXIMAGE_INFO struct with information about an image file. +// +// Parameters: +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetImageInfoFromFileA( + LPCSTR pSrcFile, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXGetImageInfoFromFileW( + LPCWSTR pSrcFile, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileW +#else +#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileA +#endif + + +HRESULT WINAPI + D3DXGetImageInfoFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXGetImageInfoFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceW +#else +#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceA +#endif + + +HRESULT WINAPI + D3DXGetImageInfoFromFileInMemory( + LPCVOID pSrcData, + UINT SrcDataSize, + D3DXIMAGE_INFO* pSrcInfo); + + + + +////////////////////////////////////////////////////////////////////////////// +// Load/Save Surface APIs //////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromFile/Resource: +// --------------------------------- +// Load surface from a file or resource +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcRect +// Source rectangle, or NULL for entire image +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromFileA( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCSTR pSrcFile, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadSurfaceFromFileW( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCWSTR pSrcFile, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileW +#else +#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileA +#endif + + + +HRESULT WINAPI + D3DXLoadSurfaceFromResourceA( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadSurfaceFromResourceW( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + +#ifdef UNICODE +#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceW +#else +#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceA +#endif + + + +HRESULT WINAPI + D3DXLoadSurfaceFromFileInMemory( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCVOID pSrcData, + UINT SrcDataSize, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromSurface: +// --------------------------- +// Load surface from another surface (with color conversion) +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcSurface +// Source surface +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for entire surface +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromSurface( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey); + + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromMemory: +// -------------------------- +// Load surface from memory. +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcMemory +// Pointer to the top-left corner of the source image in memory +// SrcFormat +// Pixel format of the source image. +// SrcPitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the width of one row of cells, in bytes. +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle. +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromMemory( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCVOID pSrcMemory, + D3DFORMAT SrcFormat, + UINT SrcPitch, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey); + + +//---------------------------------------------------------------------------- +// D3DXSaveSurfaceToFile: +// ---------------------- +// Save a surface to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcSurface +// Source surface, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for the entire image +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveSurfaceToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + +HRESULT WINAPI + D3DXSaveSurfaceToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + +#ifdef UNICODE +#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileW +#else +#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileA +#endif + +//---------------------------------------------------------------------------- +// D3DXSaveSurfaceToFileInMemory: +// ---------------------- +// Save a surface to a image file. +// +// Parameters: +// ppDestBuf +// address of pointer to d3dxbuffer for returning data bits +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcSurface +// Source surface, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for the entire image +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveSurfaceToFileInMemory( + LPD3DXBUFFER* ppDestBuf, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + + +////////////////////////////////////////////////////////////////////////////// +// Load/Save Volume APIs ///////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromFile/Resource: +// -------------------------------- +// Load volume from a file or resource +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcBox +// Source box, or NULL for entire image +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromFileA( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCSTR pSrcFile, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadVolumeFromFileW( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCWSTR pSrcFile, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileW +#else +#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileA +#endif + + +HRESULT WINAPI + D3DXLoadVolumeFromResourceA( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadVolumeFromResourceW( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceW +#else +#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceA +#endif + + + +HRESULT WINAPI + D3DXLoadVolumeFromFileInMemory( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCVOID pSrcData, + UINT SrcDataSize, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromVolume: +// ------------------------- +// Load volume from another volume (with color conversion) +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcVolume +// Source volume +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for entire volume +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromVolume( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey); + + + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromMemory: +// ------------------------- +// Load volume from memory. +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcMemory +// Pointer to the top-left corner of the source volume in memory +// SrcFormat +// Pixel format of the source volume. +// SrcRowPitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the size of one row of cells, in bytes. +// SrcSlicePitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the size of one slice of cells, in bytes. +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box. +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromMemory( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCVOID pSrcMemory, + D3DFORMAT SrcFormat, + UINT SrcRowPitch, + UINT SrcSlicePitch, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey); + + + +//---------------------------------------------------------------------------- +// D3DXSaveVolumeToFile: +// --------------------- +// Save a volume to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcVolume +// Source volume, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for the entire volume +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveVolumeToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +HRESULT WINAPI + D3DXSaveVolumeToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +#ifdef UNICODE +#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileW +#else +#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileA +#endif + + +//---------------------------------------------------------------------------- +// D3DXSaveVolumeToFileInMemory: +// --------------------- +// Save a volume to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcVolume +// Source volume, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for the entire volume +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveVolumeToFileInMemory( + LPD3DXBUFFER* ppDestBuf, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +////////////////////////////////////////////////////////////////////////////// +// Create/Save Texture APIs ////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXCheckTextureRequirements: +// ----------------------------- +// Checks texture creation parameters. If parameters are invalid, this +// function returns corrected parameters. +// +// Parameters: +// +// pDevice +// The D3D device to be used +// pWidth, pHeight, pDepth, pSize +// Desired size in pixels, or NULL. Returns corrected size. +// pNumMipLevels +// Number of desired mipmap levels, or NULL. Returns corrected number. +// Usage +// Texture usage flags +// pFormat +// Desired pixel format, or NULL. Returns corrected format. +// Pool +// Memory pool to be used to create texture +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCheckTextureRequirements( + LPDIRECT3DDEVICE9 pDevice, + UINT* pWidth, + UINT* pHeight, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + +HRESULT WINAPI + D3DXCheckCubeTextureRequirements( + LPDIRECT3DDEVICE9 pDevice, + UINT* pSize, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + +HRESULT WINAPI + D3DXCheckVolumeTextureRequirements( + LPDIRECT3DDEVICE9 pDevice, + UINT* pWidth, + UINT* pHeight, + UINT* pDepth, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + + +//---------------------------------------------------------------------------- +// D3DXCreateTexture: +// ------------------ +// Create an empty texture +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// Width, Height, Depth, Size +// size in pixels. these must be non-zero +// MipLevels +// number of mip levels desired. if zero or D3DX_DEFAULT, a complete +// mipmap chain will be created. +// Usage +// Texture usage flags +// Format +// Pixel format. +// Pool +// Memory pool to be used to create texture +// ppTexture, ppCubeTexture, ppVolumeTexture +// The texture object that will be created +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateTexture( + LPDIRECT3DDEVICE9 pDevice, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTexture( + LPDIRECT3DDEVICE9 pDevice, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTexture( + LPDIRECT3DDEVICE9 pDevice, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + + + +//---------------------------------------------------------------------------- +// D3DXCreateTextureFromFile/Resource: +// ----------------------------------- +// Create a texture object from a file or resource. +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// pSrcFile +// File name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pvSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// Width, Height, Depth, Size +// Size in pixels. If zero or D3DX_DEFAULT, the size will be taken from +// the file and rounded up to a power of two. If D3DX_DEFAULT_NONPOW2, +// and the device supports NONPOW2 textures, the size will not be rounded. +// If D3DX_FROM_FILE, the size will be taken exactly as it is in the file, +// and the call will fail if this violates device capabilities. +// MipLevels +// Number of mip levels. If zero or D3DX_DEFAULT, a complete mipmap +// chain will be created. If D3DX_FROM_FILE, the size will be taken +// exactly as it is in the file, and the call will fail if this violates +// device capabilities. +// Usage +// Texture usage flags +// Format +// Desired pixel format. If D3DFMT_UNKNOWN, the format will be +// taken from the file. If D3DFMT_FROM_FILE, the format will be taken +// exactly as it is in the file, and the call will fail if the device does +// not support the given format. +// Pool +// Memory pool to be used to create texture +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// MipFilter +// D3DX_FILTER flags controlling how each miplevel is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_BOX. +// Use the D3DX_SKIP_DDS_MIP_LEVELS macro to specify both a filter and the +// number of mip levels to skip when loading DDS files. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// pPalette +// 256 color palette to be filled in, or NULL +// ppTexture, ppCubeTexture, ppVolumeTexture +// The texture object that will be created +// +//---------------------------------------------------------------------------- + +// FromFile + +HRESULT WINAPI + D3DXCreateTextureFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileW +#else +#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileW +#else +#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileW +#else +#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileA +#endif + + +// FromResource + +HRESULT WINAPI + D3DXCreateTextureFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceW +#else +#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceW +#else +#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceW +#else +#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceA +#endif + + +// FromFileEx + +HRESULT WINAPI + D3DXCreateTextureFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExW +#else +#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExW +#else +#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExW +#else +#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExA +#endif + + +// FromResourceEx + +HRESULT WINAPI + D3DXCreateTextureFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExW +#else +#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExW +#else +#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExW +#else +#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExA +#endif + + +// FromFileInMemory + +HRESULT WINAPI + D3DXCreateTextureFromFileInMemory( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileInMemory( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileInMemory( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + + +// FromFileInMemoryEx + +HRESULT WINAPI + D3DXCreateTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + + + +//---------------------------------------------------------------------------- +// D3DXSaveTextureToFile: +// ---------------------- +// Save a texture to a file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcTexture +// Source texture, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// +//---------------------------------------------------------------------------- + + +HRESULT WINAPI + D3DXSaveTextureToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + +HRESULT WINAPI + D3DXSaveTextureToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + +#ifdef UNICODE +#define D3DXSaveTextureToFile D3DXSaveTextureToFileW +#else +#define D3DXSaveTextureToFile D3DXSaveTextureToFileA +#endif + + +//---------------------------------------------------------------------------- +// D3DXSaveTextureToFileInMemory: +// ---------------------- +// Save a texture to a file. +// +// Parameters: +// ppDestBuf +// address of a d3dxbuffer pointer to return the image data +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcTexture +// Source texture, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveTextureToFileInMemory( + LPD3DXBUFFER* ppDestBuf, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + + + + +////////////////////////////////////////////////////////////////////////////// +// Misc Texture APIs ///////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXFilterTexture: +// ------------------ +// Filters mipmaps levels of a texture. +// +// Parameters: +// pBaseTexture +// The texture object to be filtered +// pPalette +// 256 color palette to be used, or NULL for non-palettized formats +// SrcLevel +// The level whose image is used to generate the subsequent levels. +// Filter +// D3DX_FILTER flags controlling how each miplevel is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_BOX, +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFilterTexture( + LPDIRECT3DBASETEXTURE9 pBaseTexture, + CONST PALETTEENTRY* pPalette, + UINT SrcLevel, + DWORD Filter); + +#define D3DXFilterCubeTexture D3DXFilterTexture +#define D3DXFilterVolumeTexture D3DXFilterTexture + + + +//---------------------------------------------------------------------------- +// D3DXFillTexture: +// ---------------- +// Uses a user provided function to fill each texel of each mip level of a +// given texture. +// +// Paramters: +// pTexture, pCubeTexture, pVolumeTexture +// Pointer to the texture to be filled. +// pFunction +// Pointer to user provided evalutor function which will be used to +// compute the value of each texel. +// pData +// Pointer to an arbitrary block of user defined data. This pointer +// will be passed to the function provided in pFunction +//----------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFillTexture( + LPDIRECT3DTEXTURE9 pTexture, + LPD3DXFILL2D pFunction, + LPVOID pData); + +HRESULT WINAPI + D3DXFillCubeTexture( + LPDIRECT3DCUBETEXTURE9 pCubeTexture, + LPD3DXFILL3D pFunction, + LPVOID pData); + +HRESULT WINAPI + D3DXFillVolumeTexture( + LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture, + LPD3DXFILL3D pFunction, + LPVOID pData); + +//--------------------------------------------------------------------------- +// D3DXFillTextureTX: +// ------------------ +// Uses a TX Shader target to function to fill each texel of each mip level +// of a given texture. The TX Shader target should be a compiled function +// taking 2 paramters and returning a float4 color. +// +// Paramters: +// pTexture, pCubeTexture, pVolumeTexture +// Pointer to the texture to be filled. +// pTextureShader +// Pointer to the texture shader to be used to fill in the texture +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFillTextureTX( + LPDIRECT3DTEXTURE9 pTexture, + LPD3DXTEXTURESHADER pTextureShader); + + +HRESULT WINAPI + D3DXFillCubeTextureTX( + LPDIRECT3DCUBETEXTURE9 pCubeTexture, + LPD3DXTEXTURESHADER pTextureShader); + + +HRESULT WINAPI + D3DXFillVolumeTextureTX( + LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture, + LPD3DXTEXTURESHADER pTextureShader); + + + +//---------------------------------------------------------------------------- +// D3DXComputeNormalMap: +// --------------------- +// Converts a height map into a normal map. The (x,y,z) components of each +// normal are mapped to the (r,g,b) channels of the output texture. +// +// Parameters +// pTexture +// Pointer to the destination texture +// pSrcTexture +// Pointer to the source heightmap texture +// pSrcPalette +// Source palette of 256 colors, or NULL +// Flags +// D3DX_NORMALMAP flags +// Channel +// D3DX_CHANNEL specifying source of height information +// Amplitude +// The constant value which the height information is multiplied by. +//--------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXComputeNormalMap( + LPDIRECT3DTEXTURE9 pTexture, + LPDIRECT3DTEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette, + DWORD Flags, + DWORD Channel, + FLOAT Amplitude); + + + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9TEX_H__ + diff --git a/dxsdk/Include/d3dx9xof.h b/dxsdk/Include/d3dx9xof.h new file mode 100644 index 0000000..c513f0f --- /dev/null +++ b/dxsdk/Include/d3dx9xof.h @@ -0,0 +1,299 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9xof.h +// Content: D3DX .X File types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#if !defined( __D3DX9XOF_H__ ) +#define __D3DX9XOF_H__ + +#if defined( __cplusplus ) +extern "C" { +#endif // defined( __cplusplus ) + +//---------------------------------------------------------------------------- +// D3DXF_FILEFORMAT +// This flag is used to specify what file type to use when saving to disk. +// _BINARY, and _TEXT are mutually exclusive, while +// _COMPRESSED is an optional setting that works with all file types. +//---------------------------------------------------------------------------- +typedef DWORD D3DXF_FILEFORMAT; + +#define D3DXF_FILEFORMAT_BINARY 0 +#define D3DXF_FILEFORMAT_TEXT 1 +#define D3DXF_FILEFORMAT_COMPRESSED 2 + +//---------------------------------------------------------------------------- +// D3DXF_FILESAVEOPTIONS +// This flag is used to specify where to save the file to. Each flag is +// mutually exclusive, indicates the data location of the file, and also +// chooses which additional data will specify the location. +// _TOFILE is paired with a filename (LPCSTR) +// _TOWFILE is paired with a filename (LPWSTR) +//---------------------------------------------------------------------------- +typedef DWORD D3DXF_FILESAVEOPTIONS; + +#define D3DXF_FILESAVE_TOFILE 0x00L +#define D3DXF_FILESAVE_TOWFILE 0x01L + +//---------------------------------------------------------------------------- +// D3DXF_FILELOADOPTIONS +// This flag is used to specify where to load the file from. Each flag is +// mutually exclusive, indicates the data location of the file, and also +// chooses which additional data will specify the location. +// _FROMFILE is paired with a filename (LPCSTR) +// _FROMWFILE is paired with a filename (LPWSTR) +// _FROMRESOURCE is paired with a (D3DXF_FILELOADRESOUCE*) description. +// _FROMMEMORY is paired with a (D3DXF_FILELOADMEMORY*) description. +//---------------------------------------------------------------------------- +typedef DWORD D3DXF_FILELOADOPTIONS; + +#define D3DXF_FILELOAD_FROMFILE 0x00L +#define D3DXF_FILELOAD_FROMWFILE 0x01L +#define D3DXF_FILELOAD_FROMRESOURCE 0x02L +#define D3DXF_FILELOAD_FROMMEMORY 0x03L + +//---------------------------------------------------------------------------- +// D3DXF_FILELOADRESOURCE: +//---------------------------------------------------------------------------- + +typedef struct _D3DXF_FILELOADRESOURCE +{ + HMODULE hModule; // Desc + LPCSTR lpName; // Desc + LPCSTR lpType; // Desc +} D3DXF_FILELOADRESOURCE; + +//---------------------------------------------------------------------------- +// D3DXF_FILELOADMEMORY: +//---------------------------------------------------------------------------- + +typedef struct _D3DXF_FILELOADMEMORY +{ + LPCVOID lpMemory; // Desc + SIZE_T dSize; // Desc +} D3DXF_FILELOADMEMORY; + +#if defined( _WIN32 ) && !defined( _NO_COM ) + +// {cef08cf9-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFile, +0xcef08cf9, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfa-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileSaveObject, +0xcef08cfa, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfb-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileSaveData, +0xcef08cfb, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfc-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileEnumObject, +0xcef08cfc, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfd-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileData, +0xcef08cfd, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +#endif // defined( _WIN32 ) && !defined( _NO_COM ) + +#if defined( __cplusplus ) +#if !defined( DECLSPEC_UUID ) +#if _MSC_VER >= 1100 +#define DECLSPEC_UUID( x ) __declspec( uuid( x ) ) +#else // !( _MSC_VER >= 1100 ) +#define DECLSPEC_UUID( x ) +#endif // !( _MSC_VER >= 1100 ) +#endif // !defined( DECLSPEC_UUID ) + +interface DECLSPEC_UUID( "cef08cf9-7b4f-4429-9624-2a690a933201" ) + ID3DXFile; +interface DECLSPEC_UUID( "cef08cfa-7b4f-4429-9624-2a690a933201" ) + ID3DXFileSaveObject; +interface DECLSPEC_UUID( "cef08cfb-7b4f-4429-9624-2a690a933201" ) + ID3DXFileSaveData; +interface DECLSPEC_UUID( "cef08cfc-7b4f-4429-9624-2a690a933201" ) + ID3DXFileEnumObject; +interface DECLSPEC_UUID( "cef08cfd-7b4f-4429-9624-2a690a933201" ) + ID3DXFileData; + +#if defined( _COM_SMARTPTR_TYPEDEF ) +_COM_SMARTPTR_TYPEDEF( ID3DXFile, + __uuidof( ID3DXFile ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileSaveObject, + __uuidof( ID3DXFileSaveObject ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileSaveData, + __uuidof( ID3DXFileSaveData ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileEnumObject, + __uuidof( ID3DXFileEnumObject ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileData, + __uuidof( ID3DXFileData ) ); +#endif // defined( _COM_SMARTPTR_TYPEDEF ) +#endif // defined( __cplusplus ) + +typedef interface ID3DXFile ID3DXFile; +typedef interface ID3DXFileSaveObject ID3DXFileSaveObject; +typedef interface ID3DXFileSaveData ID3DXFileSaveData; +typedef interface ID3DXFileEnumObject ID3DXFileEnumObject; +typedef interface ID3DXFileData ID3DXFileData; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFile ///////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFile + +DECLARE_INTERFACE_( ID3DXFile, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( CreateEnumObject )( THIS_ LPCVOID, D3DXF_FILELOADOPTIONS, + ID3DXFileEnumObject** ) PURE; + STDMETHOD( CreateSaveObject )( THIS_ LPCVOID, D3DXF_FILESAVEOPTIONS, + D3DXF_FILEFORMAT, ID3DXFileSaveObject** ) PURE; + STDMETHOD( RegisterTemplates )( THIS_ LPCVOID, SIZE_T ) PURE; + STDMETHOD( RegisterEnumTemplates )( THIS_ ID3DXFileEnumObject* ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileSaveObject /////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileSaveObject + +DECLARE_INTERFACE_( ID3DXFileSaveObject, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetFile )( THIS_ ID3DXFile** ) PURE; + STDMETHOD( AddDataObject )( THIS_ REFGUID, LPCSTR, CONST GUID*, + SIZE_T, LPCVOID, ID3DXFileSaveData** ) PURE; + STDMETHOD( Save )( THIS ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileSaveData ///////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileSaveData + +DECLARE_INTERFACE_( ID3DXFileSaveData, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetSave )( THIS_ ID3DXFileSaveObject** ) PURE; + STDMETHOD( GetName )( THIS_ LPSTR, SIZE_T* ) PURE; + STDMETHOD( GetId )( THIS_ LPGUID ) PURE; + STDMETHOD( GetType )( THIS_ GUID* ) PURE; + STDMETHOD( AddDataObject )( THIS_ REFGUID, LPCSTR, CONST GUID*, + SIZE_T, LPCVOID, ID3DXFileSaveData** ) PURE; + STDMETHOD( AddDataReference )( THIS_ LPCSTR, CONST GUID* ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileEnumObject /////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileEnumObject + +DECLARE_INTERFACE_( ID3DXFileEnumObject, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetFile )( THIS_ ID3DXFile** ) PURE; + STDMETHOD( GetChildren )( THIS_ SIZE_T* ) PURE; + STDMETHOD( GetChild )( THIS_ SIZE_T, ID3DXFileData** ) PURE; + STDMETHOD( GetDataObjectById )( THIS_ REFGUID, ID3DXFileData** ) PURE; + STDMETHOD( GetDataObjectByName )( THIS_ LPCSTR, ID3DXFileData** ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileData ///////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileData + +DECLARE_INTERFACE_( ID3DXFileData, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetEnum )( THIS_ ID3DXFileEnumObject** ) PURE; + STDMETHOD( GetName )( THIS_ LPSTR, SIZE_T* ) PURE; + STDMETHOD( GetId )( THIS_ LPGUID ) PURE; + STDMETHOD( Lock )( THIS_ SIZE_T*, LPCVOID* ) PURE; + STDMETHOD( Unlock )( THIS ) PURE; + STDMETHOD( GetType )( THIS_ GUID* ) PURE; + STDMETHOD_( BOOL, IsReference )( THIS ) PURE; + STDMETHOD( GetChildren )( THIS_ SIZE_T* ) PURE; + STDMETHOD( GetChild )( THIS_ SIZE_T, ID3DXFileData** ) PURE; +}; + +STDAPI D3DXFileCreate( ID3DXFile** lplpDirectXFile ); + +/* + * DirectX File errors. + */ + +#define _FACD3DXF 0x876 + +#define D3DXFERR_BADOBJECT MAKE_HRESULT( 1, _FACD3DXF, 900 ) +#define D3DXFERR_BADVALUE MAKE_HRESULT( 1, _FACD3DXF, 901 ) +#define D3DXFERR_BADTYPE MAKE_HRESULT( 1, _FACD3DXF, 902 ) +#define D3DXFERR_NOTFOUND MAKE_HRESULT( 1, _FACD3DXF, 903 ) +#define D3DXFERR_NOTDONEYET MAKE_HRESULT( 1, _FACD3DXF, 904 ) +#define D3DXFERR_FILENOTFOUND MAKE_HRESULT( 1, _FACD3DXF, 905 ) +#define D3DXFERR_RESOURCENOTFOUND MAKE_HRESULT( 1, _FACD3DXF, 906 ) +#define D3DXFERR_BADRESOURCE MAKE_HRESULT( 1, _FACD3DXF, 907 ) +#define D3DXFERR_BADFILETYPE MAKE_HRESULT( 1, _FACD3DXF, 908 ) +#define D3DXFERR_BADFILEVERSION MAKE_HRESULT( 1, _FACD3DXF, 909 ) +#define D3DXFERR_BADFILEFLOATSIZE MAKE_HRESULT( 1, _FACD3DXF, 910 ) +#define D3DXFERR_BADFILE MAKE_HRESULT( 1, _FACD3DXF, 911 ) +#define D3DXFERR_PARSEERROR MAKE_HRESULT( 1, _FACD3DXF, 912 ) +#define D3DXFERR_BADARRAYSIZE MAKE_HRESULT( 1, _FACD3DXF, 913 ) +#define D3DXFERR_BADDATAREFERENCE MAKE_HRESULT( 1, _FACD3DXF, 914 ) +#define D3DXFERR_NOMOREOBJECTS MAKE_HRESULT( 1, _FACD3DXF, 915 ) +#define D3DXFERR_NOMOREDATA MAKE_HRESULT( 1, _FACD3DXF, 916 ) +#define D3DXFERR_BADCACHEFILE MAKE_HRESULT( 1, _FACD3DXF, 917 ) + +/* + * DirectX File object types. + */ + +#ifndef WIN_TYPES +#define WIN_TYPES(itype, ptype) typedef interface itype *LP##ptype, **LPLP##ptype +#endif + +WIN_TYPES(ID3DXFile, D3DXFILE); +WIN_TYPES(ID3DXFileEnumObject, D3DXFILEENUMOBJECT); +WIN_TYPES(ID3DXFileSaveObject, D3DXFILESAVEOBJECT); +WIN_TYPES(ID3DXFileData, D3DXFILEDATA); +WIN_TYPES(ID3DXFileSaveData, D3DXFILESAVEDATA); + +#if defined( __cplusplus ) +} // extern "C" +#endif // defined( __cplusplus ) + +#endif // !defined( __D3DX9XOF_H__ ) + + diff --git a/dxsdk/Include/dinput.h b/dxsdk/Include/dinput.h new file mode 100644 index 0000000..5aac256 --- /dev/null +++ b/dxsdk/Include/dinput.h @@ -0,0 +1,4417 @@ +/**************************************************************************** + * + * Copyright (C) 1996-2000 Microsoft Corporation. All Rights Reserved. + * + * File: dinput.h + * Content: DirectInput include file + * + ****************************************************************************/ + +#ifndef __DINPUT_INCLUDED__ +#define __DINPUT_INCLUDED__ + +#ifndef DIJ_RINGZERO + +#ifdef _WIN32 +#define COM_NO_WINDOWS_H +#include +#endif + +#endif /* DIJ_RINGZERO */ + +#ifdef __cplusplus +extern "C" { +#endif + + + + + +/* + * To build applications for older versions of DirectInput + * + * #define DIRECTINPUT_VERSION [ 0x0300 | 0x0500 | 0x0700 ] + * + * before #include . By default, #include + * will produce a DirectX 8-compatible header file. + * + */ + +#define DIRECTINPUT_HEADER_VERSION 0x0800 +#ifndef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION DIRECTINPUT_HEADER_VERSION +#pragma message(__FILE__ ": DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800") +#endif + +#ifndef DIJ_RINGZERO + +/**************************************************************************** + * + * Class IDs + * + ****************************************************************************/ + +DEFINE_GUID(CLSID_DirectInput, 0x25E609E0,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(CLSID_DirectInputDevice, 0x25E609E1,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +DEFINE_GUID(CLSID_DirectInput8, 0x25E609E4,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(CLSID_DirectInputDevice8,0x25E609E5,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +/**************************************************************************** + * + * Interfaces + * + ****************************************************************************/ + +DEFINE_GUID(IID_IDirectInputA, 0x89521360,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInputW, 0x89521361,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInput2A, 0x5944E662,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInput2W, 0x5944E663,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInput7A, 0x9A4CB684,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); +DEFINE_GUID(IID_IDirectInput7W, 0x9A4CB685,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); +DEFINE_GUID(IID_IDirectInput8A, 0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00); +DEFINE_GUID(IID_IDirectInput8W, 0xBF798031,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00); +DEFINE_GUID(IID_IDirectInputDeviceA, 0x5944E680,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInputDeviceW, 0x5944E681,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInputDevice2A,0x5944E682,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInputDevice2W,0x5944E683,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInputDevice7A,0x57D7C6BC,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); +DEFINE_GUID(IID_IDirectInputDevice7W,0x57D7C6BD,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE); +DEFINE_GUID(IID_IDirectInputDevice8A,0x54D41080,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79); +DEFINE_GUID(IID_IDirectInputDevice8W,0x54D41081,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79); +DEFINE_GUID(IID_IDirectInputEffect, 0xE7E1F7C0,0x88D2,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); + +/**************************************************************************** + * + * Predefined object types + * + ****************************************************************************/ + +DEFINE_GUID(GUID_XAxis, 0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_YAxis, 0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_ZAxis, 0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_RxAxis, 0xA36D02F4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_RyAxis, 0xA36D02F5,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_RzAxis, 0xA36D02E3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_Slider, 0xA36D02E4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +DEFINE_GUID(GUID_Button, 0xA36D02F0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_Key, 0x55728220,0xD33C,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +DEFINE_GUID(GUID_POV, 0xA36D02F2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +DEFINE_GUID(GUID_Unknown, 0xA36D02F3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +/**************************************************************************** + * + * Predefined product GUIDs + * + ****************************************************************************/ + +DEFINE_GUID(GUID_SysMouse, 0x6F1D2B60,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_SysKeyboard,0x6F1D2B61,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_Joystick ,0x6F1D2B70,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_SysMouseEm, 0x6F1D2B80,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_SysMouseEm2,0x6F1D2B81,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_SysKeyboardEm, 0x6F1D2B82,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_SysKeyboardEm2,0x6F1D2B83,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +/**************************************************************************** + * + * Predefined force feedback effects + * + ****************************************************************************/ + +DEFINE_GUID(GUID_ConstantForce, 0x13541C20,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_RampForce, 0x13541C21,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_Square, 0x13541C22,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_Sine, 0x13541C23,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_Triangle, 0x13541C24,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_SawtoothUp, 0x13541C25,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_SawtoothDown, 0x13541C26,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_Spring, 0x13541C27,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_Damper, 0x13541C28,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_Inertia, 0x13541C29,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_Friction, 0x13541C2A,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(GUID_CustomForce, 0x13541C2B,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); + +#endif /* DIJ_RINGZERO */ + +/**************************************************************************** + * + * Interfaces and Structures... + * + ****************************************************************************/ + +#if(DIRECTINPUT_VERSION >= 0x0500) + +/**************************************************************************** + * + * IDirectInputEffect + * + ****************************************************************************/ + +#define DIEFT_ALL 0x00000000 + +#define DIEFT_CONSTANTFORCE 0x00000001 +#define DIEFT_RAMPFORCE 0x00000002 +#define DIEFT_PERIODIC 0x00000003 +#define DIEFT_CONDITION 0x00000004 +#define DIEFT_CUSTOMFORCE 0x00000005 +#define DIEFT_HARDWARE 0x000000FF +#define DIEFT_FFATTACK 0x00000200 +#define DIEFT_FFFADE 0x00000400 +#define DIEFT_SATURATION 0x00000800 +#define DIEFT_POSNEGCOEFFICIENTS 0x00001000 +#define DIEFT_POSNEGSATURATION 0x00002000 +#define DIEFT_DEADBAND 0x00004000 +#define DIEFT_STARTDELAY 0x00008000 +#define DIEFT_GETTYPE(n) LOBYTE(n) + +#define DI_DEGREES 100 +#define DI_FFNOMINALMAX 10000 +#define DI_SECONDS 1000000 + +typedef struct DICONSTANTFORCE { + LONG lMagnitude; +} DICONSTANTFORCE, *LPDICONSTANTFORCE; +typedef const DICONSTANTFORCE *LPCDICONSTANTFORCE; + +typedef struct DIRAMPFORCE { + LONG lStart; + LONG lEnd; +} DIRAMPFORCE, *LPDIRAMPFORCE; +typedef const DIRAMPFORCE *LPCDIRAMPFORCE; + +typedef struct DIPERIODIC { + DWORD dwMagnitude; + LONG lOffset; + DWORD dwPhase; + DWORD dwPeriod; +} DIPERIODIC, *LPDIPERIODIC; +typedef const DIPERIODIC *LPCDIPERIODIC; + +typedef struct DICONDITION { + LONG lOffset; + LONG lPositiveCoefficient; + LONG lNegativeCoefficient; + DWORD dwPositiveSaturation; + DWORD dwNegativeSaturation; + LONG lDeadBand; +} DICONDITION, *LPDICONDITION; +typedef const DICONDITION *LPCDICONDITION; + +typedef struct DICUSTOMFORCE { + DWORD cChannels; + DWORD dwSamplePeriod; + DWORD cSamples; + LPLONG rglForceData; +} DICUSTOMFORCE, *LPDICUSTOMFORCE; +typedef const DICUSTOMFORCE *LPCDICUSTOMFORCE; + + +typedef struct DIENVELOPE { + DWORD dwSize; /* sizeof(DIENVELOPE) */ + DWORD dwAttackLevel; + DWORD dwAttackTime; /* Microseconds */ + DWORD dwFadeLevel; + DWORD dwFadeTime; /* Microseconds */ +} DIENVELOPE, *LPDIENVELOPE; +typedef const DIENVELOPE *LPCDIENVELOPE; + + +/* This structure is defined for DirectX 5.0 compatibility */ +typedef struct DIEFFECT_DX5 { + DWORD dwSize; /* sizeof(DIEFFECT_DX5) */ + DWORD dwFlags; /* DIEFF_* */ + DWORD dwDuration; /* Microseconds */ + DWORD dwSamplePeriod; /* Microseconds */ + DWORD dwGain; + DWORD dwTriggerButton; /* or DIEB_NOTRIGGER */ + DWORD dwTriggerRepeatInterval; /* Microseconds */ + DWORD cAxes; /* Number of axes */ + LPDWORD rgdwAxes; /* Array of axes */ + LPLONG rglDirection; /* Array of directions */ + LPDIENVELOPE lpEnvelope; /* Optional */ + DWORD cbTypeSpecificParams; /* Size of params */ + LPVOID lpvTypeSpecificParams; /* Pointer to params */ +} DIEFFECT_DX5, *LPDIEFFECT_DX5; +typedef const DIEFFECT_DX5 *LPCDIEFFECT_DX5; + +typedef struct DIEFFECT { + DWORD dwSize; /* sizeof(DIEFFECT) */ + DWORD dwFlags; /* DIEFF_* */ + DWORD dwDuration; /* Microseconds */ + DWORD dwSamplePeriod; /* Microseconds */ + DWORD dwGain; + DWORD dwTriggerButton; /* or DIEB_NOTRIGGER */ + DWORD dwTriggerRepeatInterval; /* Microseconds */ + DWORD cAxes; /* Number of axes */ + LPDWORD rgdwAxes; /* Array of axes */ + LPLONG rglDirection; /* Array of directions */ + LPDIENVELOPE lpEnvelope; /* Optional */ + DWORD cbTypeSpecificParams; /* Size of params */ + LPVOID lpvTypeSpecificParams; /* Pointer to params */ +#if(DIRECTINPUT_VERSION >= 0x0600) + DWORD dwStartDelay; /* Microseconds */ +#endif /* DIRECTINPUT_VERSION >= 0x0600 */ +} DIEFFECT, *LPDIEFFECT; +typedef DIEFFECT DIEFFECT_DX6; +typedef LPDIEFFECT LPDIEFFECT_DX6; +typedef const DIEFFECT *LPCDIEFFECT; + + +#if(DIRECTINPUT_VERSION >= 0x0700) +#ifndef DIJ_RINGZERO +typedef struct DIFILEEFFECT{ + DWORD dwSize; + GUID GuidEffect; + LPCDIEFFECT lpDiEffect; + CHAR szFriendlyName[MAX_PATH]; +}DIFILEEFFECT, *LPDIFILEEFFECT; +typedef const DIFILEEFFECT *LPCDIFILEEFFECT; +typedef BOOL (FAR PASCAL * LPDIENUMEFFECTSINFILECALLBACK)(LPCDIFILEEFFECT , LPVOID); +#endif /* DIJ_RINGZERO */ +#endif /* DIRECTINPUT_VERSION >= 0x0700 */ + +#define DIEFF_OBJECTIDS 0x00000001 +#define DIEFF_OBJECTOFFSETS 0x00000002 +#define DIEFF_CARTESIAN 0x00000010 +#define DIEFF_POLAR 0x00000020 +#define DIEFF_SPHERICAL 0x00000040 + +#define DIEP_DURATION 0x00000001 +#define DIEP_SAMPLEPERIOD 0x00000002 +#define DIEP_GAIN 0x00000004 +#define DIEP_TRIGGERBUTTON 0x00000008 +#define DIEP_TRIGGERREPEATINTERVAL 0x00000010 +#define DIEP_AXES 0x00000020 +#define DIEP_DIRECTION 0x00000040 +#define DIEP_ENVELOPE 0x00000080 +#define DIEP_TYPESPECIFICPARAMS 0x00000100 +#if(DIRECTINPUT_VERSION >= 0x0600) +#define DIEP_STARTDELAY 0x00000200 +#define DIEP_ALLPARAMS_DX5 0x000001FF +#define DIEP_ALLPARAMS 0x000003FF +#else /* DIRECTINPUT_VERSION < 0x0600 */ +#define DIEP_ALLPARAMS 0x000001FF +#endif /* DIRECTINPUT_VERSION < 0x0600 */ +#define DIEP_START 0x20000000 +#define DIEP_NORESTART 0x40000000 +#define DIEP_NODOWNLOAD 0x80000000 +#define DIEB_NOTRIGGER 0xFFFFFFFF + +#define DIES_SOLO 0x00000001 +#define DIES_NODOWNLOAD 0x80000000 + +#define DIEGES_PLAYING 0x00000001 +#define DIEGES_EMULATED 0x00000002 + +typedef struct DIEFFESCAPE { + DWORD dwSize; + DWORD dwCommand; + LPVOID lpvInBuffer; + DWORD cbInBuffer; + LPVOID lpvOutBuffer; + DWORD cbOutBuffer; +} DIEFFESCAPE, *LPDIEFFESCAPE; + +#ifndef DIJ_RINGZERO + +#undef INTERFACE +#define INTERFACE IDirectInputEffect + +DECLARE_INTERFACE_(IDirectInputEffect, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputEffect methods ***/ + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; + STDMETHOD(GetEffectGuid)(THIS_ LPGUID) PURE; + STDMETHOD(GetParameters)(THIS_ LPDIEFFECT,DWORD) PURE; + STDMETHOD(SetParameters)(THIS_ LPCDIEFFECT,DWORD) PURE; + STDMETHOD(Start)(THIS_ DWORD,DWORD) PURE; + STDMETHOD(Stop)(THIS) PURE; + STDMETHOD(GetEffectStatus)(THIS_ LPDWORD) PURE; + STDMETHOD(Download)(THIS) PURE; + STDMETHOD(Unload)(THIS) PURE; + STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; +}; + +typedef struct IDirectInputEffect *LPDIRECTINPUTEFFECT; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputEffect_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputEffect_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputEffect_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputEffect_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) +#define IDirectInputEffect_GetEffectGuid(p,a) (p)->lpVtbl->GetEffectGuid(p,a) +#define IDirectInputEffect_GetParameters(p,a,b) (p)->lpVtbl->GetParameters(p,a,b) +#define IDirectInputEffect_SetParameters(p,a,b) (p)->lpVtbl->SetParameters(p,a,b) +#define IDirectInputEffect_Start(p,a,b) (p)->lpVtbl->Start(p,a,b) +#define IDirectInputEffect_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectInputEffect_GetEffectStatus(p,a) (p)->lpVtbl->GetEffectStatus(p,a) +#define IDirectInputEffect_Download(p) (p)->lpVtbl->Download(p) +#define IDirectInputEffect_Unload(p) (p)->lpVtbl->Unload(p) +#define IDirectInputEffect_Escape(p,a) (p)->lpVtbl->Escape(p,a) +#else +#define IDirectInputEffect_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputEffect_AddRef(p) (p)->AddRef() +#define IDirectInputEffect_Release(p) (p)->Release() +#define IDirectInputEffect_Initialize(p,a,b,c) (p)->Initialize(a,b,c) +#define IDirectInputEffect_GetEffectGuid(p,a) (p)->GetEffectGuid(a) +#define IDirectInputEffect_GetParameters(p,a,b) (p)->GetParameters(a,b) +#define IDirectInputEffect_SetParameters(p,a,b) (p)->SetParameters(a,b) +#define IDirectInputEffect_Start(p,a,b) (p)->Start(a,b) +#define IDirectInputEffect_Stop(p) (p)->Stop() +#define IDirectInputEffect_GetEffectStatus(p,a) (p)->GetEffectStatus(a) +#define IDirectInputEffect_Download(p) (p)->Download() +#define IDirectInputEffect_Unload(p) (p)->Unload() +#define IDirectInputEffect_Escape(p,a) (p)->Escape(a) +#endif + +#endif /* DIJ_RINGZERO */ + +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ + +/**************************************************************************** + * + * IDirectInputDevice + * + ****************************************************************************/ + +#if DIRECTINPUT_VERSION <= 0x700 +#define DIDEVTYPE_DEVICE 1 +#define DIDEVTYPE_MOUSE 2 +#define DIDEVTYPE_KEYBOARD 3 +#define DIDEVTYPE_JOYSTICK 4 + +#else +#define DI8DEVCLASS_ALL 0 +#define DI8DEVCLASS_DEVICE 1 +#define DI8DEVCLASS_POINTER 2 +#define DI8DEVCLASS_KEYBOARD 3 +#define DI8DEVCLASS_GAMECTRL 4 + +#define DI8DEVTYPE_DEVICE 0x11 +#define DI8DEVTYPE_MOUSE 0x12 +#define DI8DEVTYPE_KEYBOARD 0x13 +#define DI8DEVTYPE_JOYSTICK 0x14 +#define DI8DEVTYPE_GAMEPAD 0x15 +#define DI8DEVTYPE_DRIVING 0x16 +#define DI8DEVTYPE_FLIGHT 0x17 +#define DI8DEVTYPE_1STPERSON 0x18 +#define DI8DEVTYPE_DEVICECTRL 0x19 +#define DI8DEVTYPE_SCREENPOINTER 0x1A +#define DI8DEVTYPE_REMOTE 0x1B +#define DI8DEVTYPE_SUPPLEMENTAL 0x1C +#endif /* DIRECTINPUT_VERSION <= 0x700 */ + +#define DIDEVTYPE_HID 0x00010000 + +#if DIRECTINPUT_VERSION <= 0x700 +#define DIDEVTYPEMOUSE_UNKNOWN 1 +#define DIDEVTYPEMOUSE_TRADITIONAL 2 +#define DIDEVTYPEMOUSE_FINGERSTICK 3 +#define DIDEVTYPEMOUSE_TOUCHPAD 4 +#define DIDEVTYPEMOUSE_TRACKBALL 5 + +#define DIDEVTYPEKEYBOARD_UNKNOWN 0 +#define DIDEVTYPEKEYBOARD_PCXT 1 +#define DIDEVTYPEKEYBOARD_OLIVETTI 2 +#define DIDEVTYPEKEYBOARD_PCAT 3 +#define DIDEVTYPEKEYBOARD_PCENH 4 +#define DIDEVTYPEKEYBOARD_NOKIA1050 5 +#define DIDEVTYPEKEYBOARD_NOKIA9140 6 +#define DIDEVTYPEKEYBOARD_NEC98 7 +#define DIDEVTYPEKEYBOARD_NEC98LAPTOP 8 +#define DIDEVTYPEKEYBOARD_NEC98106 9 +#define DIDEVTYPEKEYBOARD_JAPAN106 10 +#define DIDEVTYPEKEYBOARD_JAPANAX 11 +#define DIDEVTYPEKEYBOARD_J3100 12 + +#define DIDEVTYPEJOYSTICK_UNKNOWN 1 +#define DIDEVTYPEJOYSTICK_TRADITIONAL 2 +#define DIDEVTYPEJOYSTICK_FLIGHTSTICK 3 +#define DIDEVTYPEJOYSTICK_GAMEPAD 4 +#define DIDEVTYPEJOYSTICK_RUDDER 5 +#define DIDEVTYPEJOYSTICK_WHEEL 6 +#define DIDEVTYPEJOYSTICK_HEADTRACKER 7 + +#else +#define DI8DEVTYPEMOUSE_UNKNOWN 1 +#define DI8DEVTYPEMOUSE_TRADITIONAL 2 +#define DI8DEVTYPEMOUSE_FINGERSTICK 3 +#define DI8DEVTYPEMOUSE_TOUCHPAD 4 +#define DI8DEVTYPEMOUSE_TRACKBALL 5 +#define DI8DEVTYPEMOUSE_ABSOLUTE 6 + +#define DI8DEVTYPEKEYBOARD_UNKNOWN 0 +#define DI8DEVTYPEKEYBOARD_PCXT 1 +#define DI8DEVTYPEKEYBOARD_OLIVETTI 2 +#define DI8DEVTYPEKEYBOARD_PCAT 3 +#define DI8DEVTYPEKEYBOARD_PCENH 4 +#define DI8DEVTYPEKEYBOARD_NOKIA1050 5 +#define DI8DEVTYPEKEYBOARD_NOKIA9140 6 +#define DI8DEVTYPEKEYBOARD_NEC98 7 +#define DI8DEVTYPEKEYBOARD_NEC98LAPTOP 8 +#define DI8DEVTYPEKEYBOARD_NEC98106 9 +#define DI8DEVTYPEKEYBOARD_JAPAN106 10 +#define DI8DEVTYPEKEYBOARD_JAPANAX 11 +#define DI8DEVTYPEKEYBOARD_J3100 12 + +#define DI8DEVTYPE_LIMITEDGAMESUBTYPE 1 + +#define DI8DEVTYPEJOYSTICK_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEJOYSTICK_STANDARD 2 + +#define DI8DEVTYPEGAMEPAD_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEGAMEPAD_STANDARD 2 +#define DI8DEVTYPEGAMEPAD_TILT 3 + +#define DI8DEVTYPEDRIVING_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEDRIVING_COMBINEDPEDALS 2 +#define DI8DEVTYPEDRIVING_DUALPEDALS 3 +#define DI8DEVTYPEDRIVING_THREEPEDALS 4 +#define DI8DEVTYPEDRIVING_HANDHELD 5 + +#define DI8DEVTYPEFLIGHT_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEFLIGHT_STICK 2 +#define DI8DEVTYPEFLIGHT_YOKE 3 +#define DI8DEVTYPEFLIGHT_RC 4 + +#define DI8DEVTYPE1STPERSON_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPE1STPERSON_UNKNOWN 2 +#define DI8DEVTYPE1STPERSON_SIXDOF 3 +#define DI8DEVTYPE1STPERSON_SHOOTER 4 + +#define DI8DEVTYPESCREENPTR_UNKNOWN 2 +#define DI8DEVTYPESCREENPTR_LIGHTGUN 3 +#define DI8DEVTYPESCREENPTR_LIGHTPEN 4 +#define DI8DEVTYPESCREENPTR_TOUCH 5 + +#define DI8DEVTYPEREMOTE_UNKNOWN 2 + +#define DI8DEVTYPEDEVICECTRL_UNKNOWN 2 +#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION 3 +#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION_HARDWIRED 4 + +#define DI8DEVTYPESUPPLEMENTAL_UNKNOWN 2 +#define DI8DEVTYPESUPPLEMENTAL_2NDHANDCONTROLLER 3 +#define DI8DEVTYPESUPPLEMENTAL_HEADTRACKER 4 +#define DI8DEVTYPESUPPLEMENTAL_HANDTRACKER 5 +#define DI8DEVTYPESUPPLEMENTAL_SHIFTSTICKGATE 6 +#define DI8DEVTYPESUPPLEMENTAL_SHIFTER 7 +#define DI8DEVTYPESUPPLEMENTAL_THROTTLE 8 +#define DI8DEVTYPESUPPLEMENTAL_SPLITTHROTTLE 9 +#define DI8DEVTYPESUPPLEMENTAL_COMBINEDPEDALS 10 +#define DI8DEVTYPESUPPLEMENTAL_DUALPEDALS 11 +#define DI8DEVTYPESUPPLEMENTAL_THREEPEDALS 12 +#define DI8DEVTYPESUPPLEMENTAL_RUDDERPEDALS 13 +#endif /* DIRECTINPUT_VERSION <= 0x700 */ + +#define GET_DIDEVICE_TYPE(dwDevType) LOBYTE(dwDevType) +#define GET_DIDEVICE_SUBTYPE(dwDevType) HIBYTE(dwDevType) + +#if(DIRECTINPUT_VERSION >= 0x0500) +/* This structure is defined for DirectX 3.0 compatibility */ +typedef struct DIDEVCAPS_DX3 { + DWORD dwSize; + DWORD dwFlags; + DWORD dwDevType; + DWORD dwAxes; + DWORD dwButtons; + DWORD dwPOVs; +} DIDEVCAPS_DX3, *LPDIDEVCAPS_DX3; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ + +typedef struct DIDEVCAPS { + DWORD dwSize; + DWORD dwFlags; + DWORD dwDevType; + DWORD dwAxes; + DWORD dwButtons; + DWORD dwPOVs; +#if(DIRECTINPUT_VERSION >= 0x0500) + DWORD dwFFSamplePeriod; + DWORD dwFFMinTimeResolution; + DWORD dwFirmwareRevision; + DWORD dwHardwareRevision; + DWORD dwFFDriverVersion; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +} DIDEVCAPS, *LPDIDEVCAPS; + +#define DIDC_ATTACHED 0x00000001 +#define DIDC_POLLEDDEVICE 0x00000002 +#define DIDC_EMULATED 0x00000004 +#define DIDC_POLLEDDATAFORMAT 0x00000008 +#if(DIRECTINPUT_VERSION >= 0x0500) +#define DIDC_FORCEFEEDBACK 0x00000100 +#define DIDC_FFATTACK 0x00000200 +#define DIDC_FFFADE 0x00000400 +#define DIDC_SATURATION 0x00000800 +#define DIDC_POSNEGCOEFFICIENTS 0x00001000 +#define DIDC_POSNEGSATURATION 0x00002000 +#define DIDC_DEADBAND 0x00004000 +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +#define DIDC_STARTDELAY 0x00008000 +#if(DIRECTINPUT_VERSION >= 0x050a) +#define DIDC_ALIAS 0x00010000 +#define DIDC_PHANTOM 0x00020000 +#endif /* DIRECTINPUT_VERSION >= 0x050a */ +#if(DIRECTINPUT_VERSION >= 0x0800) +#define DIDC_HIDDEN 0x00040000 +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +#define DIDFT_ALL 0x00000000 + +#define DIDFT_RELAXIS 0x00000001 +#define DIDFT_ABSAXIS 0x00000002 +#define DIDFT_AXIS 0x00000003 + +#define DIDFT_PSHBUTTON 0x00000004 +#define DIDFT_TGLBUTTON 0x00000008 +#define DIDFT_BUTTON 0x0000000C + +#define DIDFT_POV 0x00000010 +#define DIDFT_COLLECTION 0x00000040 +#define DIDFT_NODATA 0x00000080 + +#define DIDFT_ANYINSTANCE 0x00FFFF00 +#define DIDFT_INSTANCEMASK DIDFT_ANYINSTANCE +#define DIDFT_MAKEINSTANCE(n) ((WORD)(n) << 8) +#define DIDFT_GETTYPE(n) LOBYTE(n) +#define DIDFT_GETINSTANCE(n) LOWORD((n) >> 8) +#define DIDFT_FFACTUATOR 0x01000000 +#define DIDFT_FFEFFECTTRIGGER 0x02000000 +#if(DIRECTINPUT_VERSION >= 0x050a) +#define DIDFT_OUTPUT 0x10000000 +#define DIDFT_VENDORDEFINED 0x04000000 +#define DIDFT_ALIAS 0x08000000 +#endif /* DIRECTINPUT_VERSION >= 0x050a */ +#ifndef DIDFT_OPTIONAL +#define DIDFT_OPTIONAL 0x80000000 +#endif + +#define DIDFT_ENUMCOLLECTION(n) ((WORD)(n) << 8) +#define DIDFT_NOCOLLECTION 0x00FFFF00 + +#ifndef DIJ_RINGZERO + +typedef struct _DIOBJECTDATAFORMAT { + const GUID *pguid; + DWORD dwOfs; + DWORD dwType; + DWORD dwFlags; +} DIOBJECTDATAFORMAT, *LPDIOBJECTDATAFORMAT; +typedef const DIOBJECTDATAFORMAT *LPCDIOBJECTDATAFORMAT; + +typedef struct _DIDATAFORMAT { + DWORD dwSize; + DWORD dwObjSize; + DWORD dwFlags; + DWORD dwDataSize; + DWORD dwNumObjs; + LPDIOBJECTDATAFORMAT rgodf; +} DIDATAFORMAT, *LPDIDATAFORMAT; +typedef const DIDATAFORMAT *LPCDIDATAFORMAT; + +#define DIDF_ABSAXIS 0x00000001 +#define DIDF_RELAXIS 0x00000002 + +#ifdef __cplusplus +extern "C" { +#endif +extern const DIDATAFORMAT c_dfDIMouse; + +#if(DIRECTINPUT_VERSION >= 0x0700) +extern const DIDATAFORMAT c_dfDIMouse2; +#endif /* DIRECTINPUT_VERSION >= 0x0700 */ + +extern const DIDATAFORMAT c_dfDIKeyboard; + +#if(DIRECTINPUT_VERSION >= 0x0500) +extern const DIDATAFORMAT c_dfDIJoystick; +extern const DIDATAFORMAT c_dfDIJoystick2; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ + +#ifdef __cplusplus +}; +#endif + + +#if DIRECTINPUT_VERSION > 0x0700 + +typedef struct _DIACTIONA { + UINT_PTR uAppData; + DWORD dwSemantic; + OPTIONAL DWORD dwFlags; + OPTIONAL union { + LPCSTR lptszActionName; + UINT uResIdString; + }; + OPTIONAL GUID guidInstance; + OPTIONAL DWORD dwObjID; + OPTIONAL DWORD dwHow; +} DIACTIONA, *LPDIACTIONA ; +typedef struct _DIACTIONW { + UINT_PTR uAppData; + DWORD dwSemantic; + OPTIONAL DWORD dwFlags; + OPTIONAL union { + LPCWSTR lptszActionName; + UINT uResIdString; + }; + OPTIONAL GUID guidInstance; + OPTIONAL DWORD dwObjID; + OPTIONAL DWORD dwHow; +} DIACTIONW, *LPDIACTIONW ; +#ifdef UNICODE +typedef DIACTIONW DIACTION; +typedef LPDIACTIONW LPDIACTION; +#else +typedef DIACTIONA DIACTION; +typedef LPDIACTIONA LPDIACTION; +#endif // UNICODE + +typedef const DIACTIONA *LPCDIACTIONA; +typedef const DIACTIONW *LPCDIACTIONW; +#ifdef UNICODE +typedef DIACTIONW DIACTION; +typedef LPCDIACTIONW LPCDIACTION; +#else +typedef DIACTIONA DIACTION; +typedef LPCDIACTIONA LPCDIACTION; +#endif // UNICODE +typedef const DIACTION *LPCDIACTION; + + +#define DIA_FORCEFEEDBACK 0x00000001 +#define DIA_APPMAPPED 0x00000002 +#define DIA_APPNOMAP 0x00000004 +#define DIA_NORANGE 0x00000008 +#define DIA_APPFIXED 0x00000010 + +#define DIAH_UNMAPPED 0x00000000 +#define DIAH_USERCONFIG 0x00000001 +#define DIAH_APPREQUESTED 0x00000002 +#define DIAH_HWAPP 0x00000004 +#define DIAH_HWDEFAULT 0x00000008 +#define DIAH_DEFAULT 0x00000020 +#define DIAH_ERROR 0x80000000 + +typedef struct _DIACTIONFORMATA { + DWORD dwSize; + DWORD dwActionSize; + DWORD dwDataSize; + DWORD dwNumActions; + LPDIACTIONA rgoAction; + GUID guidActionMap; + DWORD dwGenre; + DWORD dwBufferSize; + OPTIONAL LONG lAxisMin; + OPTIONAL LONG lAxisMax; + OPTIONAL HINSTANCE hInstString; + FILETIME ftTimeStamp; + DWORD dwCRC; + CHAR tszActionMap[MAX_PATH]; +} DIACTIONFORMATA, *LPDIACTIONFORMATA; +typedef struct _DIACTIONFORMATW { + DWORD dwSize; + DWORD dwActionSize; + DWORD dwDataSize; + DWORD dwNumActions; + LPDIACTIONW rgoAction; + GUID guidActionMap; + DWORD dwGenre; + DWORD dwBufferSize; + OPTIONAL LONG lAxisMin; + OPTIONAL LONG lAxisMax; + OPTIONAL HINSTANCE hInstString; + FILETIME ftTimeStamp; + DWORD dwCRC; + WCHAR tszActionMap[MAX_PATH]; +} DIACTIONFORMATW, *LPDIACTIONFORMATW; +#ifdef UNICODE +typedef DIACTIONFORMATW DIACTIONFORMAT; +typedef LPDIACTIONFORMATW LPDIACTIONFORMAT; +#else +typedef DIACTIONFORMATA DIACTIONFORMAT; +typedef LPDIACTIONFORMATA LPDIACTIONFORMAT; +#endif // UNICODE +typedef const DIACTIONFORMATA *LPCDIACTIONFORMATA; +typedef const DIACTIONFORMATW *LPCDIACTIONFORMATW; +#ifdef UNICODE +typedef DIACTIONFORMATW DIACTIONFORMAT; +typedef LPCDIACTIONFORMATW LPCDIACTIONFORMAT; +#else +typedef DIACTIONFORMATA DIACTIONFORMAT; +typedef LPCDIACTIONFORMATA LPCDIACTIONFORMAT; +#endif // UNICODE +typedef const DIACTIONFORMAT *LPCDIACTIONFORMAT; + +#define DIAFTS_NEWDEVICELOW 0xFFFFFFFF +#define DIAFTS_NEWDEVICEHIGH 0xFFFFFFFF +#define DIAFTS_UNUSEDDEVICELOW 0x00000000 +#define DIAFTS_UNUSEDDEVICEHIGH 0x00000000 + +#define DIDBAM_DEFAULT 0x00000000 +#define DIDBAM_PRESERVE 0x00000001 +#define DIDBAM_INITIALIZE 0x00000002 +#define DIDBAM_HWDEFAULTS 0x00000004 + +#define DIDSAM_DEFAULT 0x00000000 +#define DIDSAM_NOUSER 0x00000001 +#define DIDSAM_FORCESAVE 0x00000002 + +#define DICD_DEFAULT 0x00000000 +#define DICD_EDIT 0x00000001 + +/* + * The following definition is normally defined in d3dtypes.h + */ +#ifndef D3DCOLOR_DEFINED +typedef DWORD D3DCOLOR; +#define D3DCOLOR_DEFINED +#endif + +typedef struct _DICOLORSET{ + DWORD dwSize; + D3DCOLOR cTextFore; + D3DCOLOR cTextHighlight; + D3DCOLOR cCalloutLine; + D3DCOLOR cCalloutHighlight; + D3DCOLOR cBorder; + D3DCOLOR cControlFill; + D3DCOLOR cHighlightFill; + D3DCOLOR cAreaFill; +} DICOLORSET, *LPDICOLORSET; +typedef const DICOLORSET *LPCDICOLORSET; + + +typedef struct _DICONFIGUREDEVICESPARAMSA{ + DWORD dwSize; + DWORD dwcUsers; + LPSTR lptszUserNames; + DWORD dwcFormats; + LPDIACTIONFORMATA lprgFormats; + HWND hwnd; + DICOLORSET dics; + IUnknown FAR * lpUnkDDSTarget; +} DICONFIGUREDEVICESPARAMSA, *LPDICONFIGUREDEVICESPARAMSA; +typedef struct _DICONFIGUREDEVICESPARAMSW{ + DWORD dwSize; + DWORD dwcUsers; + LPWSTR lptszUserNames; + DWORD dwcFormats; + LPDIACTIONFORMATW lprgFormats; + HWND hwnd; + DICOLORSET dics; + IUnknown FAR * lpUnkDDSTarget; +} DICONFIGUREDEVICESPARAMSW, *LPDICONFIGUREDEVICESPARAMSW; +#ifdef UNICODE +typedef DICONFIGUREDEVICESPARAMSW DICONFIGUREDEVICESPARAMS; +typedef LPDICONFIGUREDEVICESPARAMSW LPDICONFIGUREDEVICESPARAMS; +#else +typedef DICONFIGUREDEVICESPARAMSA DICONFIGUREDEVICESPARAMS; +typedef LPDICONFIGUREDEVICESPARAMSA LPDICONFIGUREDEVICESPARAMS; +#endif // UNICODE +typedef const DICONFIGUREDEVICESPARAMSA *LPCDICONFIGUREDEVICESPARAMSA; +typedef const DICONFIGUREDEVICESPARAMSW *LPCDICONFIGUREDEVICESPARAMSW; +#ifdef UNICODE +typedef DICONFIGUREDEVICESPARAMSW DICONFIGUREDEVICESPARAMS; +typedef LPCDICONFIGUREDEVICESPARAMSW LPCDICONFIGUREDEVICESPARAMS; +#else +typedef DICONFIGUREDEVICESPARAMSA DICONFIGUREDEVICESPARAMS; +typedef LPCDICONFIGUREDEVICESPARAMSA LPCDICONFIGUREDEVICESPARAMS; +#endif // UNICODE +typedef const DICONFIGUREDEVICESPARAMS *LPCDICONFIGUREDEVICESPARAMS; + + +#define DIDIFT_CONFIGURATION 0x00000001 +#define DIDIFT_OVERLAY 0x00000002 + +#define DIDAL_CENTERED 0x00000000 +#define DIDAL_LEFTALIGNED 0x00000001 +#define DIDAL_RIGHTALIGNED 0x00000002 +#define DIDAL_MIDDLE 0x00000000 +#define DIDAL_TOPALIGNED 0x00000004 +#define DIDAL_BOTTOMALIGNED 0x00000008 + +typedef struct _DIDEVICEIMAGEINFOA { + CHAR tszImagePath[MAX_PATH]; + DWORD dwFlags; + // These are valid if DIDIFT_OVERLAY is present in dwFlags. + DWORD dwViewID; + RECT rcOverlay; + DWORD dwObjID; + DWORD dwcValidPts; + POINT rgptCalloutLine[5]; + RECT rcCalloutRect; + DWORD dwTextAlign; +} DIDEVICEIMAGEINFOA, *LPDIDEVICEIMAGEINFOA; +typedef struct _DIDEVICEIMAGEINFOW { + WCHAR tszImagePath[MAX_PATH]; + DWORD dwFlags; + // These are valid if DIDIFT_OVERLAY is present in dwFlags. + DWORD dwViewID; + RECT rcOverlay; + DWORD dwObjID; + DWORD dwcValidPts; + POINT rgptCalloutLine[5]; + RECT rcCalloutRect; + DWORD dwTextAlign; +} DIDEVICEIMAGEINFOW, *LPDIDEVICEIMAGEINFOW; +#ifdef UNICODE +typedef DIDEVICEIMAGEINFOW DIDEVICEIMAGEINFO; +typedef LPDIDEVICEIMAGEINFOW LPDIDEVICEIMAGEINFO; +#else +typedef DIDEVICEIMAGEINFOA DIDEVICEIMAGEINFO; +typedef LPDIDEVICEIMAGEINFOA LPDIDEVICEIMAGEINFO; +#endif // UNICODE +typedef const DIDEVICEIMAGEINFOA *LPCDIDEVICEIMAGEINFOA; +typedef const DIDEVICEIMAGEINFOW *LPCDIDEVICEIMAGEINFOW; +#ifdef UNICODE +typedef DIDEVICEIMAGEINFOW DIDEVICEIMAGEINFO; +typedef LPCDIDEVICEIMAGEINFOW LPCDIDEVICEIMAGEINFO; +#else +typedef DIDEVICEIMAGEINFOA DIDEVICEIMAGEINFO; +typedef LPCDIDEVICEIMAGEINFOA LPCDIDEVICEIMAGEINFO; +#endif // UNICODE +typedef const DIDEVICEIMAGEINFO *LPCDIDEVICEIMAGEINFO; + +typedef struct _DIDEVICEIMAGEINFOHEADERA { + DWORD dwSize; + DWORD dwSizeImageInfo; + DWORD dwcViews; + DWORD dwcButtons; + DWORD dwcAxes; + DWORD dwcPOVs; + DWORD dwBufferSize; + DWORD dwBufferUsed; + LPDIDEVICEIMAGEINFOA lprgImageInfoArray; +} DIDEVICEIMAGEINFOHEADERA, *LPDIDEVICEIMAGEINFOHEADERA; +typedef struct _DIDEVICEIMAGEINFOHEADERW { + DWORD dwSize; + DWORD dwSizeImageInfo; + DWORD dwcViews; + DWORD dwcButtons; + DWORD dwcAxes; + DWORD dwcPOVs; + DWORD dwBufferSize; + DWORD dwBufferUsed; + LPDIDEVICEIMAGEINFOW lprgImageInfoArray; +} DIDEVICEIMAGEINFOHEADERW, *LPDIDEVICEIMAGEINFOHEADERW; +#ifdef UNICODE +typedef DIDEVICEIMAGEINFOHEADERW DIDEVICEIMAGEINFOHEADER; +typedef LPDIDEVICEIMAGEINFOHEADERW LPDIDEVICEIMAGEINFOHEADER; +#else +typedef DIDEVICEIMAGEINFOHEADERA DIDEVICEIMAGEINFOHEADER; +typedef LPDIDEVICEIMAGEINFOHEADERA LPDIDEVICEIMAGEINFOHEADER; +#endif // UNICODE +typedef const DIDEVICEIMAGEINFOHEADERA *LPCDIDEVICEIMAGEINFOHEADERA; +typedef const DIDEVICEIMAGEINFOHEADERW *LPCDIDEVICEIMAGEINFOHEADERW; +#ifdef UNICODE +typedef DIDEVICEIMAGEINFOHEADERW DIDEVICEIMAGEINFOHEADER; +typedef LPCDIDEVICEIMAGEINFOHEADERW LPCDIDEVICEIMAGEINFOHEADER; +#else +typedef DIDEVICEIMAGEINFOHEADERA DIDEVICEIMAGEINFOHEADER; +typedef LPCDIDEVICEIMAGEINFOHEADERA LPCDIDEVICEIMAGEINFOHEADER; +#endif // UNICODE +typedef const DIDEVICEIMAGEINFOHEADER *LPCDIDEVICEIMAGEINFOHEADER; + +#endif /* DIRECTINPUT_VERSION > 0x0700 */ + +#if(DIRECTINPUT_VERSION >= 0x0500) +/* These structures are defined for DirectX 3.0 compatibility */ + +typedef struct DIDEVICEOBJECTINSTANCE_DX3A { + DWORD dwSize; + GUID guidType; + DWORD dwOfs; + DWORD dwType; + DWORD dwFlags; + CHAR tszName[MAX_PATH]; +} DIDEVICEOBJECTINSTANCE_DX3A, *LPDIDEVICEOBJECTINSTANCE_DX3A; +typedef struct DIDEVICEOBJECTINSTANCE_DX3W { + DWORD dwSize; + GUID guidType; + DWORD dwOfs; + DWORD dwType; + DWORD dwFlags; + WCHAR tszName[MAX_PATH]; +} DIDEVICEOBJECTINSTANCE_DX3W, *LPDIDEVICEOBJECTINSTANCE_DX3W; +#ifdef UNICODE +typedef DIDEVICEOBJECTINSTANCE_DX3W DIDEVICEOBJECTINSTANCE_DX3; +typedef LPDIDEVICEOBJECTINSTANCE_DX3W LPDIDEVICEOBJECTINSTANCE_DX3; +#else +typedef DIDEVICEOBJECTINSTANCE_DX3A DIDEVICEOBJECTINSTANCE_DX3; +typedef LPDIDEVICEOBJECTINSTANCE_DX3A LPDIDEVICEOBJECTINSTANCE_DX3; +#endif // UNICODE +typedef const DIDEVICEOBJECTINSTANCE_DX3A *LPCDIDEVICEOBJECTINSTANCE_DX3A; +typedef const DIDEVICEOBJECTINSTANCE_DX3W *LPCDIDEVICEOBJECTINSTANCE_DX3W; +typedef const DIDEVICEOBJECTINSTANCE_DX3 *LPCDIDEVICEOBJECTINSTANCE_DX3; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ + +typedef struct DIDEVICEOBJECTINSTANCEA { + DWORD dwSize; + GUID guidType; + DWORD dwOfs; + DWORD dwType; + DWORD dwFlags; + CHAR tszName[MAX_PATH]; +#if(DIRECTINPUT_VERSION >= 0x0500) + DWORD dwFFMaxForce; + DWORD dwFFForceResolution; + WORD wCollectionNumber; + WORD wDesignatorIndex; + WORD wUsagePage; + WORD wUsage; + DWORD dwDimension; + WORD wExponent; + WORD wReportId; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +} DIDEVICEOBJECTINSTANCEA, *LPDIDEVICEOBJECTINSTANCEA; +typedef struct DIDEVICEOBJECTINSTANCEW { + DWORD dwSize; + GUID guidType; + DWORD dwOfs; + DWORD dwType; + DWORD dwFlags; + WCHAR tszName[MAX_PATH]; +#if(DIRECTINPUT_VERSION >= 0x0500) + DWORD dwFFMaxForce; + DWORD dwFFForceResolution; + WORD wCollectionNumber; + WORD wDesignatorIndex; + WORD wUsagePage; + WORD wUsage; + DWORD dwDimension; + WORD wExponent; + WORD wReportId; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +} DIDEVICEOBJECTINSTANCEW, *LPDIDEVICEOBJECTINSTANCEW; +#ifdef UNICODE +typedef DIDEVICEOBJECTINSTANCEW DIDEVICEOBJECTINSTANCE; +typedef LPDIDEVICEOBJECTINSTANCEW LPDIDEVICEOBJECTINSTANCE; +#else +typedef DIDEVICEOBJECTINSTANCEA DIDEVICEOBJECTINSTANCE; +typedef LPDIDEVICEOBJECTINSTANCEA LPDIDEVICEOBJECTINSTANCE; +#endif // UNICODE +typedef const DIDEVICEOBJECTINSTANCEA *LPCDIDEVICEOBJECTINSTANCEA; +typedef const DIDEVICEOBJECTINSTANCEW *LPCDIDEVICEOBJECTINSTANCEW; +typedef const DIDEVICEOBJECTINSTANCE *LPCDIDEVICEOBJECTINSTANCE; + +typedef BOOL (FAR PASCAL * LPDIENUMDEVICEOBJECTSCALLBACKA)(LPCDIDEVICEOBJECTINSTANCEA, LPVOID); +typedef BOOL (FAR PASCAL * LPDIENUMDEVICEOBJECTSCALLBACKW)(LPCDIDEVICEOBJECTINSTANCEW, LPVOID); +#ifdef UNICODE +#define LPDIENUMDEVICEOBJECTSCALLBACK LPDIENUMDEVICEOBJECTSCALLBACKW +#else +#define LPDIENUMDEVICEOBJECTSCALLBACK LPDIENUMDEVICEOBJECTSCALLBACKA +#endif // !UNICODE + +#if(DIRECTINPUT_VERSION >= 0x0500) +#define DIDOI_FFACTUATOR 0x00000001 +#define DIDOI_FFEFFECTTRIGGER 0x00000002 +#define DIDOI_POLLED 0x00008000 +#define DIDOI_ASPECTPOSITION 0x00000100 +#define DIDOI_ASPECTVELOCITY 0x00000200 +#define DIDOI_ASPECTACCEL 0x00000300 +#define DIDOI_ASPECTFORCE 0x00000400 +#define DIDOI_ASPECTMASK 0x00000F00 +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +#if(DIRECTINPUT_VERSION >= 0x050a) +#define DIDOI_GUIDISUSAGE 0x00010000 +#endif /* DIRECTINPUT_VERSION >= 0x050a */ + +typedef struct DIPROPHEADER { + DWORD dwSize; + DWORD dwHeaderSize; + DWORD dwObj; + DWORD dwHow; +} DIPROPHEADER, *LPDIPROPHEADER; +typedef const DIPROPHEADER *LPCDIPROPHEADER; + +#define DIPH_DEVICE 0 +#define DIPH_BYOFFSET 1 +#define DIPH_BYID 2 +#if(DIRECTINPUT_VERSION >= 0x050a) +#define DIPH_BYUSAGE 3 +#endif /* DIRECTINPUT_VERSION >= 0x050a */ + +#if(DIRECTINPUT_VERSION >= 0x050a) +#define DIMAKEUSAGEDWORD(UsagePage, Usage) \ + (DWORD)MAKELONG(Usage, UsagePage) +#endif /* DIRECTINPUT_VERSION >= 0x050a */ + +typedef struct DIPROPDWORD { + DIPROPHEADER diph; + DWORD dwData; +} DIPROPDWORD, *LPDIPROPDWORD; +typedef const DIPROPDWORD *LPCDIPROPDWORD; + +#if(DIRECTINPUT_VERSION >= 0x0800) +typedef struct DIPROPPOINTER { + DIPROPHEADER diph; + UINT_PTR uData; +} DIPROPPOINTER, *LPDIPROPPOINTER; +typedef const DIPROPPOINTER *LPCDIPROPPOINTER; +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +typedef struct DIPROPRANGE { + DIPROPHEADER diph; + LONG lMin; + LONG lMax; +} DIPROPRANGE, *LPDIPROPRANGE; +typedef const DIPROPRANGE *LPCDIPROPRANGE; + +#define DIPROPRANGE_NOMIN ((LONG)0x80000000) +#define DIPROPRANGE_NOMAX ((LONG)0x7FFFFFFF) + +#if(DIRECTINPUT_VERSION >= 0x050a) +typedef struct DIPROPCAL { + DIPROPHEADER diph; + LONG lMin; + LONG lCenter; + LONG lMax; +} DIPROPCAL, *LPDIPROPCAL; +typedef const DIPROPCAL *LPCDIPROPCAL; + +typedef struct DIPROPCALPOV { + DIPROPHEADER diph; + LONG lMin[5]; + LONG lMax[5]; +} DIPROPCALPOV, *LPDIPROPCALPOV; +typedef const DIPROPCALPOV *LPCDIPROPCALPOV; + +typedef struct DIPROPGUIDANDPATH { + DIPROPHEADER diph; + GUID guidClass; + WCHAR wszPath[MAX_PATH]; +} DIPROPGUIDANDPATH, *LPDIPROPGUIDANDPATH; +typedef const DIPROPGUIDANDPATH *LPCDIPROPGUIDANDPATH; + +typedef struct DIPROPSTRING { + DIPROPHEADER diph; + WCHAR wsz[MAX_PATH]; +} DIPROPSTRING, *LPDIPROPSTRING; +typedef const DIPROPSTRING *LPCDIPROPSTRING; + +#endif /* DIRECTINPUT_VERSION >= 0x050a */ + +#if(DIRECTINPUT_VERSION >= 0x0800) +#define MAXCPOINTSNUM 8 + +typedef struct _CPOINT +{ + LONG lP; // raw value + DWORD dwLog; // logical_value / max_logical_value * 10000 +} CPOINT, *PCPOINT; + +typedef struct DIPROPCPOINTS { + DIPROPHEADER diph; + DWORD dwCPointsNum; + CPOINT cp[MAXCPOINTSNUM]; +} DIPROPCPOINTS, *LPDIPROPCPOINTS; +typedef const DIPROPCPOINTS *LPCDIPROPCPOINTS; +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + + +#ifdef __cplusplus +#define MAKEDIPROP(prop) (*(const GUID *)(prop)) +#else +#define MAKEDIPROP(prop) ((REFGUID)(prop)) +#endif + +#define DIPROP_BUFFERSIZE MAKEDIPROP(1) + +#define DIPROP_AXISMODE MAKEDIPROP(2) + +#define DIPROPAXISMODE_ABS 0 +#define DIPROPAXISMODE_REL 1 + +#define DIPROP_GRANULARITY MAKEDIPROP(3) + +#define DIPROP_RANGE MAKEDIPROP(4) + +#define DIPROP_DEADZONE MAKEDIPROP(5) + +#define DIPROP_SATURATION MAKEDIPROP(6) + +#define DIPROP_FFGAIN MAKEDIPROP(7) + +#define DIPROP_FFLOAD MAKEDIPROP(8) + +#define DIPROP_AUTOCENTER MAKEDIPROP(9) + +#define DIPROPAUTOCENTER_OFF 0 +#define DIPROPAUTOCENTER_ON 1 + +#define DIPROP_CALIBRATIONMODE MAKEDIPROP(10) + +#define DIPROPCALIBRATIONMODE_COOKED 0 +#define DIPROPCALIBRATIONMODE_RAW 1 + +#if(DIRECTINPUT_VERSION >= 0x050a) +#define DIPROP_CALIBRATION MAKEDIPROP(11) + +#define DIPROP_GUIDANDPATH MAKEDIPROP(12) + +#define DIPROP_INSTANCENAME MAKEDIPROP(13) + +#define DIPROP_PRODUCTNAME MAKEDIPROP(14) +#endif /* DIRECTINPUT_VERSION >= 0x050a */ + +#if(DIRECTINPUT_VERSION >= 0x05b2) +#define DIPROP_JOYSTICKID MAKEDIPROP(15) + +#define DIPROP_GETPORTDISPLAYNAME MAKEDIPROP(16) + +#endif /* DIRECTINPUT_VERSION >= 0x05b2 */ + +#if(DIRECTINPUT_VERSION >= 0x0700) +#define DIPROP_PHYSICALRANGE MAKEDIPROP(18) + +#define DIPROP_LOGICALRANGE MAKEDIPROP(19) +#endif /* DIRECTINPUT_VERSION >= 0x0700 */ + +#if(DIRECTINPUT_VERSION >= 0x0800) +#define DIPROP_KEYNAME MAKEDIPROP(20) + +#define DIPROP_CPOINTS MAKEDIPROP(21) + +#define DIPROP_APPDATA MAKEDIPROP(22) + +#define DIPROP_SCANCODE MAKEDIPROP(23) + +#define DIPROP_VIDPID MAKEDIPROP(24) + +#define DIPROP_USERNAME MAKEDIPROP(25) + +#define DIPROP_TYPENAME MAKEDIPROP(26) +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + + +typedef struct DIDEVICEOBJECTDATA_DX3 { + DWORD dwOfs; + DWORD dwData; + DWORD dwTimeStamp; + DWORD dwSequence; +} DIDEVICEOBJECTDATA_DX3, *LPDIDEVICEOBJECTDATA_DX3; +typedef const DIDEVICEOBJECTDATA_DX3 *LPCDIDEVICEOBJECTDATA_DX; + +typedef struct DIDEVICEOBJECTDATA { + DWORD dwOfs; + DWORD dwData; + DWORD dwTimeStamp; + DWORD dwSequence; +#if(DIRECTINPUT_VERSION >= 0x0800) + UINT_PTR uAppData; +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ +} DIDEVICEOBJECTDATA, *LPDIDEVICEOBJECTDATA; +typedef const DIDEVICEOBJECTDATA *LPCDIDEVICEOBJECTDATA; + +#define DIGDD_PEEK 0x00000001 + +#define DISEQUENCE_COMPARE(dwSequence1, cmp, dwSequence2) \ + ((int)((dwSequence1) - (dwSequence2)) cmp 0) +#define DISCL_EXCLUSIVE 0x00000001 +#define DISCL_NONEXCLUSIVE 0x00000002 +#define DISCL_FOREGROUND 0x00000004 +#define DISCL_BACKGROUND 0x00000008 +#define DISCL_NOWINKEY 0x00000010 + +#if(DIRECTINPUT_VERSION >= 0x0500) +/* These structures are defined for DirectX 3.0 compatibility */ + +typedef struct DIDEVICEINSTANCE_DX3A { + DWORD dwSize; + GUID guidInstance; + GUID guidProduct; + DWORD dwDevType; + CHAR tszInstanceName[MAX_PATH]; + CHAR tszProductName[MAX_PATH]; +} DIDEVICEINSTANCE_DX3A, *LPDIDEVICEINSTANCE_DX3A; +typedef struct DIDEVICEINSTANCE_DX3W { + DWORD dwSize; + GUID guidInstance; + GUID guidProduct; + DWORD dwDevType; + WCHAR tszInstanceName[MAX_PATH]; + WCHAR tszProductName[MAX_PATH]; +} DIDEVICEINSTANCE_DX3W, *LPDIDEVICEINSTANCE_DX3W; +#ifdef UNICODE +typedef DIDEVICEINSTANCE_DX3W DIDEVICEINSTANCE_DX3; +typedef LPDIDEVICEINSTANCE_DX3W LPDIDEVICEINSTANCE_DX3; +#else +typedef DIDEVICEINSTANCE_DX3A DIDEVICEINSTANCE_DX3; +typedef LPDIDEVICEINSTANCE_DX3A LPDIDEVICEINSTANCE_DX3; +#endif // UNICODE +typedef const DIDEVICEINSTANCE_DX3A *LPCDIDEVICEINSTANCE_DX3A; +typedef const DIDEVICEINSTANCE_DX3W *LPCDIDEVICEINSTANCE_DX3W; +typedef const DIDEVICEINSTANCE_DX3 *LPCDIDEVICEINSTANCE_DX3; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ + +typedef struct DIDEVICEINSTANCEA { + DWORD dwSize; + GUID guidInstance; + GUID guidProduct; + DWORD dwDevType; + CHAR tszInstanceName[MAX_PATH]; + CHAR tszProductName[MAX_PATH]; +#if(DIRECTINPUT_VERSION >= 0x0500) + GUID guidFFDriver; + WORD wUsagePage; + WORD wUsage; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +} DIDEVICEINSTANCEA, *LPDIDEVICEINSTANCEA; +typedef struct DIDEVICEINSTANCEW { + DWORD dwSize; + GUID guidInstance; + GUID guidProduct; + DWORD dwDevType; + WCHAR tszInstanceName[MAX_PATH]; + WCHAR tszProductName[MAX_PATH]; +#if(DIRECTINPUT_VERSION >= 0x0500) + GUID guidFFDriver; + WORD wUsagePage; + WORD wUsage; +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +} DIDEVICEINSTANCEW, *LPDIDEVICEINSTANCEW; +#ifdef UNICODE +typedef DIDEVICEINSTANCEW DIDEVICEINSTANCE; +typedef LPDIDEVICEINSTANCEW LPDIDEVICEINSTANCE; +#else +typedef DIDEVICEINSTANCEA DIDEVICEINSTANCE; +typedef LPDIDEVICEINSTANCEA LPDIDEVICEINSTANCE; +#endif // UNICODE + +typedef const DIDEVICEINSTANCEA *LPCDIDEVICEINSTANCEA; +typedef const DIDEVICEINSTANCEW *LPCDIDEVICEINSTANCEW; +#ifdef UNICODE +typedef DIDEVICEINSTANCEW DIDEVICEINSTANCE; +typedef LPCDIDEVICEINSTANCEW LPCDIDEVICEINSTANCE; +#else +typedef DIDEVICEINSTANCEA DIDEVICEINSTANCE; +typedef LPCDIDEVICEINSTANCEA LPCDIDEVICEINSTANCE; +#endif // UNICODE +typedef const DIDEVICEINSTANCE *LPCDIDEVICEINSTANCE; + +#undef INTERFACE +#define INTERFACE IDirectInputDeviceW + +DECLARE_INTERFACE_(IDirectInputDeviceW, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDeviceW methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; +}; + +typedef struct IDirectInputDeviceW *LPDIRECTINPUTDEVICEW; + +#undef INTERFACE +#define INTERFACE IDirectInputDeviceA + +DECLARE_INTERFACE_(IDirectInputDeviceA, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDeviceA methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; +}; + +typedef struct IDirectInputDeviceA *LPDIRECTINPUTDEVICEA; + +#ifdef UNICODE +#define IID_IDirectInputDevice IID_IDirectInputDeviceW +#define IDirectInputDevice IDirectInputDeviceW +#define IDirectInputDeviceVtbl IDirectInputDeviceWVtbl +#else +#define IID_IDirectInputDevice IID_IDirectInputDeviceA +#define IDirectInputDevice IDirectInputDeviceA +#define IDirectInputDeviceVtbl IDirectInputDeviceAVtbl +#endif +typedef struct IDirectInputDevice *LPDIRECTINPUTDEVICE; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputDevice_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputDevice_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputDevice_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputDevice_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) +#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) +#define IDirectInputDevice_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) +#define IDirectInputDevice_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) +#define IDirectInputDevice_Acquire(p) (p)->lpVtbl->Acquire(p) +#define IDirectInputDevice_Unacquire(p) (p)->lpVtbl->Unacquire(p) +#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) +#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) +#define IDirectInputDevice_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) +#define IDirectInputDevice_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) +#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) +#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) +#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInputDevice_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) +#else +#define IDirectInputDevice_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputDevice_AddRef(p) (p)->AddRef() +#define IDirectInputDevice_Release(p) (p)->Release() +#define IDirectInputDevice_GetCapabilities(p,a) (p)->GetCapabilities(a) +#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) +#define IDirectInputDevice_GetProperty(p,a,b) (p)->GetProperty(a,b) +#define IDirectInputDevice_SetProperty(p,a,b) (p)->SetProperty(a,b) +#define IDirectInputDevice_Acquire(p) (p)->Acquire() +#define IDirectInputDevice_Unacquire(p) (p)->Unacquire() +#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) +#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) +#define IDirectInputDevice_SetDataFormat(p,a) (p)->SetDataFormat(a) +#define IDirectInputDevice_SetEventNotification(p,a) (p)->SetEventNotification(a) +#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) +#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) +#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInputDevice_Initialize(p,a,b,c) (p)->Initialize(a,b,c) +#endif + +#endif /* DIJ_RINGZERO */ + + +#if(DIRECTINPUT_VERSION >= 0x0500) + +#define DISFFC_RESET 0x00000001 +#define DISFFC_STOPALL 0x00000002 +#define DISFFC_PAUSE 0x00000004 +#define DISFFC_CONTINUE 0x00000008 +#define DISFFC_SETACTUATORSON 0x00000010 +#define DISFFC_SETACTUATORSOFF 0x00000020 + +#define DIGFFS_EMPTY 0x00000001 +#define DIGFFS_STOPPED 0x00000002 +#define DIGFFS_PAUSED 0x00000004 +#define DIGFFS_ACTUATORSON 0x00000010 +#define DIGFFS_ACTUATORSOFF 0x00000020 +#define DIGFFS_POWERON 0x00000040 +#define DIGFFS_POWEROFF 0x00000080 +#define DIGFFS_SAFETYSWITCHON 0x00000100 +#define DIGFFS_SAFETYSWITCHOFF 0x00000200 +#define DIGFFS_USERFFSWITCHON 0x00000400 +#define DIGFFS_USERFFSWITCHOFF 0x00000800 +#define DIGFFS_DEVICELOST 0x80000000 + +#ifndef DIJ_RINGZERO + +typedef struct DIEFFECTINFOA { + DWORD dwSize; + GUID guid; + DWORD dwEffType; + DWORD dwStaticParams; + DWORD dwDynamicParams; + CHAR tszName[MAX_PATH]; +} DIEFFECTINFOA, *LPDIEFFECTINFOA; +typedef struct DIEFFECTINFOW { + DWORD dwSize; + GUID guid; + DWORD dwEffType; + DWORD dwStaticParams; + DWORD dwDynamicParams; + WCHAR tszName[MAX_PATH]; +} DIEFFECTINFOW, *LPDIEFFECTINFOW; +#ifdef UNICODE +typedef DIEFFECTINFOW DIEFFECTINFO; +typedef LPDIEFFECTINFOW LPDIEFFECTINFO; +#else +typedef DIEFFECTINFOA DIEFFECTINFO; +typedef LPDIEFFECTINFOA LPDIEFFECTINFO; +#endif // UNICODE +typedef const DIEFFECTINFOA *LPCDIEFFECTINFOA; +typedef const DIEFFECTINFOW *LPCDIEFFECTINFOW; +typedef const DIEFFECTINFO *LPCDIEFFECTINFO; + +#define DISDD_CONTINUE 0x00000001 + +typedef BOOL (FAR PASCAL * LPDIENUMEFFECTSCALLBACKA)(LPCDIEFFECTINFOA, LPVOID); +typedef BOOL (FAR PASCAL * LPDIENUMEFFECTSCALLBACKW)(LPCDIEFFECTINFOW, LPVOID); +#ifdef UNICODE +#define LPDIENUMEFFECTSCALLBACK LPDIENUMEFFECTSCALLBACKW +#else +#define LPDIENUMEFFECTSCALLBACK LPDIENUMEFFECTSCALLBACKA +#endif // !UNICODE +typedef BOOL (FAR PASCAL * LPDIENUMCREATEDEFFECTOBJECTSCALLBACK)(LPDIRECTINPUTEFFECT, LPVOID); + +#undef INTERFACE +#define INTERFACE IDirectInputDevice2W + +DECLARE_INTERFACE_(IDirectInputDevice2W, IDirectInputDeviceW) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDeviceW methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; + + /*** IDirectInputDevice2W methods ***/ + STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE; + STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW,REFGUID) PURE; + STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE; + STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE; + STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; + STDMETHOD(Poll)(THIS) PURE; + STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; +}; + +typedef struct IDirectInputDevice2W *LPDIRECTINPUTDEVICE2W; + +#undef INTERFACE +#define INTERFACE IDirectInputDevice2A + +DECLARE_INTERFACE_(IDirectInputDevice2A, IDirectInputDeviceA) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDeviceA methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; + + /*** IDirectInputDevice2A methods ***/ + STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE; + STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA,REFGUID) PURE; + STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE; + STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE; + STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; + STDMETHOD(Poll)(THIS) PURE; + STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; +}; + +typedef struct IDirectInputDevice2A *LPDIRECTINPUTDEVICE2A; + +#ifdef UNICODE +#define IID_IDirectInputDevice2 IID_IDirectInputDevice2W +#define IDirectInputDevice2 IDirectInputDevice2W +#define IDirectInputDevice2Vtbl IDirectInputDevice2WVtbl +#else +#define IID_IDirectInputDevice2 IID_IDirectInputDevice2A +#define IDirectInputDevice2 IDirectInputDevice2A +#define IDirectInputDevice2Vtbl IDirectInputDevice2AVtbl +#endif +typedef struct IDirectInputDevice2 *LPDIRECTINPUTDEVICE2; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputDevice2_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputDevice2_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputDevice2_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) +#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) +#define IDirectInputDevice2_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) +#define IDirectInputDevice2_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) +#define IDirectInputDevice2_Acquire(p) (p)->lpVtbl->Acquire(p) +#define IDirectInputDevice2_Unacquire(p) (p)->lpVtbl->Unacquire(p) +#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) +#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) +#define IDirectInputDevice2_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) +#define IDirectInputDevice2_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) +#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) +#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) +#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) +#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d) +#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c) +#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b) +#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a) +#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a) +#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c) +#define IDirectInputDevice2_Escape(p,a) (p)->lpVtbl->Escape(p,a) +#define IDirectInputDevice2_Poll(p) (p)->lpVtbl->Poll(p) +#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d) +#else +#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputDevice2_AddRef(p) (p)->AddRef() +#define IDirectInputDevice2_Release(p) (p)->Release() +#define IDirectInputDevice2_GetCapabilities(p,a) (p)->GetCapabilities(a) +#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) +#define IDirectInputDevice2_GetProperty(p,a,b) (p)->GetProperty(a,b) +#define IDirectInputDevice2_SetProperty(p,a,b) (p)->SetProperty(a,b) +#define IDirectInputDevice2_Acquire(p) (p)->Acquire() +#define IDirectInputDevice2_Unacquire(p) (p)->Unacquire() +#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) +#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) +#define IDirectInputDevice2_SetDataFormat(p,a) (p)->SetDataFormat(a) +#define IDirectInputDevice2_SetEventNotification(p,a) (p)->SetEventNotification(a) +#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) +#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) +#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->Initialize(a,b,c) +#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d) +#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c) +#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b) +#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a) +#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a) +#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c) +#define IDirectInputDevice2_Escape(p,a) (p)->Escape(a) +#define IDirectInputDevice2_Poll(p) (p)->Poll() +#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d) +#endif + +#endif /* DIJ_RINGZERO */ + +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ + +#if(DIRECTINPUT_VERSION >= 0x0700) +#define DIFEF_DEFAULT 0x00000000 +#define DIFEF_INCLUDENONSTANDARD 0x00000001 +#define DIFEF_MODIFYIFNEEDED 0x00000010 + +#ifndef DIJ_RINGZERO + +#undef INTERFACE +#define INTERFACE IDirectInputDevice7W + +DECLARE_INTERFACE_(IDirectInputDevice7W, IDirectInputDevice2W) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDevice2W methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; + STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE; + STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW,REFGUID) PURE; + STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE; + STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE; + STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; + STDMETHOD(Poll)(THIS) PURE; + STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + + /*** IDirectInputDevice7W methods ***/ + STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR,LPDIENUMEFFECTSINFILECALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR,DWORD,LPDIFILEEFFECT,DWORD) PURE; +}; + +typedef struct IDirectInputDevice7W *LPDIRECTINPUTDEVICE7W; + +#undef INTERFACE +#define INTERFACE IDirectInputDevice7A + +DECLARE_INTERFACE_(IDirectInputDevice7A, IDirectInputDevice2A) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDevice2A methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; + STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE; + STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA,REFGUID) PURE; + STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE; + STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE; + STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; + STDMETHOD(Poll)(THIS) PURE; + STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + + /*** IDirectInputDevice7A methods ***/ + STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR,LPDIENUMEFFECTSINFILECALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR,DWORD,LPDIFILEEFFECT,DWORD) PURE; +}; + +typedef struct IDirectInputDevice7A *LPDIRECTINPUTDEVICE7A; + +#ifdef UNICODE +#define IID_IDirectInputDevice7 IID_IDirectInputDevice7W +#define IDirectInputDevice7 IDirectInputDevice7W +#define IDirectInputDevice7Vtbl IDirectInputDevice7WVtbl +#else +#define IID_IDirectInputDevice7 IID_IDirectInputDevice7A +#define IDirectInputDevice7 IDirectInputDevice7A +#define IDirectInputDevice7Vtbl IDirectInputDevice7AVtbl +#endif +typedef struct IDirectInputDevice7 *LPDIRECTINPUTDEVICE7; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputDevice7_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputDevice7_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputDevice7_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) +#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) +#define IDirectInputDevice7_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) +#define IDirectInputDevice7_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) +#define IDirectInputDevice7_Acquire(p) (p)->lpVtbl->Acquire(p) +#define IDirectInputDevice7_Unacquire(p) (p)->lpVtbl->Unacquire(p) +#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) +#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) +#define IDirectInputDevice7_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) +#define IDirectInputDevice7_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) +#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) +#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) +#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) +#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d) +#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c) +#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b) +#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a) +#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a) +#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c) +#define IDirectInputDevice7_Escape(p,a) (p)->lpVtbl->Escape(p,a) +#define IDirectInputDevice7_Poll(p) (p)->lpVtbl->Poll(p) +#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d) +#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d) +#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d) +#else +#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputDevice7_AddRef(p) (p)->AddRef() +#define IDirectInputDevice7_Release(p) (p)->Release() +#define IDirectInputDevice7_GetCapabilities(p,a) (p)->GetCapabilities(a) +#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) +#define IDirectInputDevice7_GetProperty(p,a,b) (p)->GetProperty(a,b) +#define IDirectInputDevice7_SetProperty(p,a,b) (p)->SetProperty(a,b) +#define IDirectInputDevice7_Acquire(p) (p)->Acquire() +#define IDirectInputDevice7_Unacquire(p) (p)->Unacquire() +#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) +#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) +#define IDirectInputDevice7_SetDataFormat(p,a) (p)->SetDataFormat(a) +#define IDirectInputDevice7_SetEventNotification(p,a) (p)->SetEventNotification(a) +#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) +#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) +#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->Initialize(a,b,c) +#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d) +#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c) +#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b) +#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a) +#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a) +#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c) +#define IDirectInputDevice7_Escape(p,a) (p)->Escape(a) +#define IDirectInputDevice7_Poll(p) (p)->Poll() +#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d) +#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d) +#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d) +#endif + +#endif /* DIJ_RINGZERO */ + +#endif /* DIRECTINPUT_VERSION >= 0x0700 */ + +#if(DIRECTINPUT_VERSION >= 0x0800) + +#ifndef DIJ_RINGZERO + +#undef INTERFACE +#define INTERFACE IDirectInputDevice8W + +DECLARE_INTERFACE_(IDirectInputDevice8W, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDevice8W methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; + STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE; + STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW,REFGUID) PURE; + STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE; + STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE; + STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; + STDMETHOD(Poll)(THIS) PURE; + STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR,LPDIENUMEFFECTSINFILECALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR,DWORD,LPDIFILEEFFECT,DWORD) PURE; + STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATW,LPCWSTR,DWORD) PURE; + STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATW,LPCWSTR,DWORD) PURE; + STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERW) PURE; +}; + +typedef struct IDirectInputDevice8W *LPDIRECTINPUTDEVICE8W; + +#undef INTERFACE +#define INTERFACE IDirectInputDevice8A + +DECLARE_INTERFACE_(IDirectInputDevice8A, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputDevice8A methods ***/ + STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE; + STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE; + STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE; + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE; + STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE; + STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA,DWORD,DWORD) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE; + STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE; + STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA,REFGUID) PURE; + STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE; + STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE; + STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE; + STDMETHOD(Poll)(THIS) PURE; + STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE; + STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR,LPDIENUMEFFECTSINFILECALLBACK,LPVOID,DWORD) PURE; + STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR,DWORD,LPDIFILEEFFECT,DWORD) PURE; + STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATA,LPCSTR,DWORD) PURE; + STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATA,LPCSTR,DWORD) PURE; + STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERA) PURE; +}; + +typedef struct IDirectInputDevice8A *LPDIRECTINPUTDEVICE8A; + +#ifdef UNICODE +#define IID_IDirectInputDevice8 IID_IDirectInputDevice8W +#define IDirectInputDevice8 IDirectInputDevice8W +#define IDirectInputDevice8Vtbl IDirectInputDevice8WVtbl +#else +#define IID_IDirectInputDevice8 IID_IDirectInputDevice8A +#define IDirectInputDevice8 IDirectInputDevice8A +#define IDirectInputDevice8Vtbl IDirectInputDevice8AVtbl +#endif +typedef struct IDirectInputDevice8 *LPDIRECTINPUTDEVICE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputDevice8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputDevice8_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputDevice8_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a) +#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c) +#define IDirectInputDevice8_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b) +#define IDirectInputDevice8_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b) +#define IDirectInputDevice8_Acquire(p) (p)->lpVtbl->Acquire(p) +#define IDirectInputDevice8_Unacquire(p) (p)->lpVtbl->Unacquire(p) +#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b) +#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d) +#define IDirectInputDevice8_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a) +#define IDirectInputDevice8_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a) +#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c) +#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a) +#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) +#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d) +#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c) +#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b) +#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a) +#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a) +#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c) +#define IDirectInputDevice8_Escape(p,a) (p)->lpVtbl->Escape(p,a) +#define IDirectInputDevice8_Poll(p) (p)->lpVtbl->Poll(p) +#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d) +#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d) +#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d) +#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->lpVtbl->BuildActionMap(p,a,b,c) +#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->lpVtbl->SetActionMap(p,a,b,c) +#define IDirectInputDevice8_GetImageInfo(p,a) (p)->lpVtbl->GetImageInfo(p,a) +#else +#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputDevice8_AddRef(p) (p)->AddRef() +#define IDirectInputDevice8_Release(p) (p)->Release() +#define IDirectInputDevice8_GetCapabilities(p,a) (p)->GetCapabilities(a) +#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c) +#define IDirectInputDevice8_GetProperty(p,a,b) (p)->GetProperty(a,b) +#define IDirectInputDevice8_SetProperty(p,a,b) (p)->SetProperty(a,b) +#define IDirectInputDevice8_Acquire(p) (p)->Acquire() +#define IDirectInputDevice8_Unacquire(p) (p)->Unacquire() +#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b) +#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d) +#define IDirectInputDevice8_SetDataFormat(p,a) (p)->SetDataFormat(a) +#define IDirectInputDevice8_SetEventNotification(p,a) (p)->SetEventNotification(a) +#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c) +#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a) +#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->Initialize(a,b,c) +#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d) +#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c) +#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b) +#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a) +#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a) +#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c) +#define IDirectInputDevice8_Escape(p,a) (p)->Escape(a) +#define IDirectInputDevice8_Poll(p) (p)->Poll() +#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d) +#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d) +#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d) +#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->BuildActionMap(a,b,c) +#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->SetActionMap(a,b,c) +#define IDirectInputDevice8_GetImageInfo(p,a) (p)->GetImageInfo(a) +#endif + +#endif /* DIJ_RINGZERO */ + +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +/**************************************************************************** + * + * Mouse + * + ****************************************************************************/ + +#ifndef DIJ_RINGZERO + +typedef struct _DIMOUSESTATE { + LONG lX; + LONG lY; + LONG lZ; + BYTE rgbButtons[4]; +} DIMOUSESTATE, *LPDIMOUSESTATE; + +#if DIRECTINPUT_VERSION >= 0x0700 +typedef struct _DIMOUSESTATE2 { + LONG lX; + LONG lY; + LONG lZ; + BYTE rgbButtons[8]; +} DIMOUSESTATE2, *LPDIMOUSESTATE2; +#endif + + +#define DIMOFS_X FIELD_OFFSET(DIMOUSESTATE, lX) +#define DIMOFS_Y FIELD_OFFSET(DIMOUSESTATE, lY) +#define DIMOFS_Z FIELD_OFFSET(DIMOUSESTATE, lZ) +#define DIMOFS_BUTTON0 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 0) +#define DIMOFS_BUTTON1 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 1) +#define DIMOFS_BUTTON2 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 2) +#define DIMOFS_BUTTON3 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 3) +#if (DIRECTINPUT_VERSION >= 0x0700) +#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4) +#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5) +#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6) +#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7) +#endif +#endif /* DIJ_RINGZERO */ + +/**************************************************************************** + * + * Keyboard + * + ****************************************************************************/ + +#ifndef DIJ_RINGZERO + +/**************************************************************************** + * + * DirectInput keyboard scan codes + * + ****************************************************************************/ +#define DIK_ESCAPE 0x01 +#define DIK_1 0x02 +#define DIK_2 0x03 +#define DIK_3 0x04 +#define DIK_4 0x05 +#define DIK_5 0x06 +#define DIK_6 0x07 +#define DIK_7 0x08 +#define DIK_8 0x09 +#define DIK_9 0x0A +#define DIK_0 0x0B +#define DIK_MINUS 0x0C /* - on main keyboard */ +#define DIK_EQUALS 0x0D +#define DIK_BACK 0x0E /* backspace */ +#define DIK_TAB 0x0F +#define DIK_Q 0x10 +#define DIK_W 0x11 +#define DIK_E 0x12 +#define DIK_R 0x13 +#define DIK_T 0x14 +#define DIK_Y 0x15 +#define DIK_U 0x16 +#define DIK_I 0x17 +#define DIK_O 0x18 +#define DIK_P 0x19 +#define DIK_LBRACKET 0x1A +#define DIK_RBRACKET 0x1B +#define DIK_RETURN 0x1C /* Enter on main keyboard */ +#define DIK_LCONTROL 0x1D +#define DIK_A 0x1E +#define DIK_S 0x1F +#define DIK_D 0x20 +#define DIK_F 0x21 +#define DIK_G 0x22 +#define DIK_H 0x23 +#define DIK_J 0x24 +#define DIK_K 0x25 +#define DIK_L 0x26 +#define DIK_SEMICOLON 0x27 +#define DIK_APOSTROPHE 0x28 +#define DIK_GRAVE 0x29 /* accent grave */ +#define DIK_LSHIFT 0x2A +#define DIK_BACKSLASH 0x2B +#define DIK_Z 0x2C +#define DIK_X 0x2D +#define DIK_C 0x2E +#define DIK_V 0x2F +#define DIK_B 0x30 +#define DIK_N 0x31 +#define DIK_M 0x32 +#define DIK_COMMA 0x33 +#define DIK_PERIOD 0x34 /* . on main keyboard */ +#define DIK_SLASH 0x35 /* / on main keyboard */ +#define DIK_RSHIFT 0x36 +#define DIK_MULTIPLY 0x37 /* * on numeric keypad */ +#define DIK_LMENU 0x38 /* left Alt */ +#define DIK_SPACE 0x39 +#define DIK_CAPITAL 0x3A +#define DIK_F1 0x3B +#define DIK_F2 0x3C +#define DIK_F3 0x3D +#define DIK_F4 0x3E +#define DIK_F5 0x3F +#define DIK_F6 0x40 +#define DIK_F7 0x41 +#define DIK_F8 0x42 +#define DIK_F9 0x43 +#define DIK_F10 0x44 +#define DIK_NUMLOCK 0x45 +#define DIK_SCROLL 0x46 /* Scroll Lock */ +#define DIK_NUMPAD7 0x47 +#define DIK_NUMPAD8 0x48 +#define DIK_NUMPAD9 0x49 +#define DIK_SUBTRACT 0x4A /* - on numeric keypad */ +#define DIK_NUMPAD4 0x4B +#define DIK_NUMPAD5 0x4C +#define DIK_NUMPAD6 0x4D +#define DIK_ADD 0x4E /* + on numeric keypad */ +#define DIK_NUMPAD1 0x4F +#define DIK_NUMPAD2 0x50 +#define DIK_NUMPAD3 0x51 +#define DIK_NUMPAD0 0x52 +#define DIK_DECIMAL 0x53 /* . on numeric keypad */ +#define DIK_OEM_102 0x56 /* <> or \| on RT 102-key keyboard (Non-U.S.) */ +#define DIK_F11 0x57 +#define DIK_F12 0x58 +#define DIK_F13 0x64 /* (NEC PC98) */ +#define DIK_F14 0x65 /* (NEC PC98) */ +#define DIK_F15 0x66 /* (NEC PC98) */ +#define DIK_KANA 0x70 /* (Japanese keyboard) */ +#define DIK_ABNT_C1 0x73 /* /? on Brazilian keyboard */ +#define DIK_CONVERT 0x79 /* (Japanese keyboard) */ +#define DIK_NOCONVERT 0x7B /* (Japanese keyboard) */ +#define DIK_YEN 0x7D /* (Japanese keyboard) */ +#define DIK_ABNT_C2 0x7E /* Numpad . on Brazilian keyboard */ +#define DIK_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */ +#define DIK_PREVTRACK 0x90 /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ +#define DIK_AT 0x91 /* (NEC PC98) */ +#define DIK_COLON 0x92 /* (NEC PC98) */ +#define DIK_UNDERLINE 0x93 /* (NEC PC98) */ +#define DIK_KANJI 0x94 /* (Japanese keyboard) */ +#define DIK_STOP 0x95 /* (NEC PC98) */ +#define DIK_AX 0x96 /* (Japan AX) */ +#define DIK_UNLABELED 0x97 /* (J3100) */ +#define DIK_NEXTTRACK 0x99 /* Next Track */ +#define DIK_NUMPADENTER 0x9C /* Enter on numeric keypad */ +#define DIK_RCONTROL 0x9D +#define DIK_MUTE 0xA0 /* Mute */ +#define DIK_CALCULATOR 0xA1 /* Calculator */ +#define DIK_PLAYPAUSE 0xA2 /* Play / Pause */ +#define DIK_MEDIASTOP 0xA4 /* Media Stop */ +#define DIK_VOLUMEDOWN 0xAE /* Volume - */ +#define DIK_VOLUMEUP 0xB0 /* Volume + */ +#define DIK_WEBHOME 0xB2 /* Web home */ +#define DIK_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */ +#define DIK_DIVIDE 0xB5 /* / on numeric keypad */ +#define DIK_SYSRQ 0xB7 +#define DIK_RMENU 0xB8 /* right Alt */ +#define DIK_PAUSE 0xC5 /* Pause */ +#define DIK_HOME 0xC7 /* Home on arrow keypad */ +#define DIK_UP 0xC8 /* UpArrow on arrow keypad */ +#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */ +#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */ +#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */ +#define DIK_END 0xCF /* End on arrow keypad */ +#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */ +#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */ +#define DIK_INSERT 0xD2 /* Insert on arrow keypad */ +#define DIK_DELETE 0xD3 /* Delete on arrow keypad */ +#define DIK_LWIN 0xDB /* Left Windows key */ +#define DIK_RWIN 0xDC /* Right Windows key */ +#define DIK_APPS 0xDD /* AppMenu key */ +#define DIK_POWER 0xDE /* System Power */ +#define DIK_SLEEP 0xDF /* System Sleep */ +#define DIK_WAKE 0xE3 /* System Wake */ +#define DIK_WEBSEARCH 0xE5 /* Web Search */ +#define DIK_WEBFAVORITES 0xE6 /* Web Favorites */ +#define DIK_WEBREFRESH 0xE7 /* Web Refresh */ +#define DIK_WEBSTOP 0xE8 /* Web Stop */ +#define DIK_WEBFORWARD 0xE9 /* Web Forward */ +#define DIK_WEBBACK 0xEA /* Web Back */ +#define DIK_MYCOMPUTER 0xEB /* My Computer */ +#define DIK_MAIL 0xEC /* Mail */ +#define DIK_MEDIASELECT 0xED /* Media Select */ + +/* + * Alternate names for keys, to facilitate transition from DOS. + */ +#define DIK_BACKSPACE DIK_BACK /* backspace */ +#define DIK_NUMPADSTAR DIK_MULTIPLY /* * on numeric keypad */ +#define DIK_LALT DIK_LMENU /* left Alt */ +#define DIK_CAPSLOCK DIK_CAPITAL /* CapsLock */ +#define DIK_NUMPADMINUS DIK_SUBTRACT /* - on numeric keypad */ +#define DIK_NUMPADPLUS DIK_ADD /* + on numeric keypad */ +#define DIK_NUMPADPERIOD DIK_DECIMAL /* . on numeric keypad */ +#define DIK_NUMPADSLASH DIK_DIVIDE /* / on numeric keypad */ +#define DIK_RALT DIK_RMENU /* right Alt */ +#define DIK_UPARROW DIK_UP /* UpArrow on arrow keypad */ +#define DIK_PGUP DIK_PRIOR /* PgUp on arrow keypad */ +#define DIK_LEFTARROW DIK_LEFT /* LeftArrow on arrow keypad */ +#define DIK_RIGHTARROW DIK_RIGHT /* RightArrow on arrow keypad */ +#define DIK_DOWNARROW DIK_DOWN /* DownArrow on arrow keypad */ +#define DIK_PGDN DIK_NEXT /* PgDn on arrow keypad */ + +/* + * Alternate names for keys originally not used on US keyboards. + */ +#define DIK_CIRCUMFLEX DIK_PREVTRACK /* Japanese keyboard */ + +#endif /* DIJ_RINGZERO */ + +/**************************************************************************** + * + * Joystick + * + ****************************************************************************/ + +#ifndef DIJ_RINGZERO + +typedef struct DIJOYSTATE { + LONG lX; /* x-axis position */ + LONG lY; /* y-axis position */ + LONG lZ; /* z-axis position */ + LONG lRx; /* x-axis rotation */ + LONG lRy; /* y-axis rotation */ + LONG lRz; /* z-axis rotation */ + LONG rglSlider[2]; /* extra axes positions */ + DWORD rgdwPOV[4]; /* POV directions */ + BYTE rgbButtons[32]; /* 32 buttons */ +} DIJOYSTATE, *LPDIJOYSTATE; + +typedef struct DIJOYSTATE2 { + LONG lX; /* x-axis position */ + LONG lY; /* y-axis position */ + LONG lZ; /* z-axis position */ + LONG lRx; /* x-axis rotation */ + LONG lRy; /* y-axis rotation */ + LONG lRz; /* z-axis rotation */ + LONG rglSlider[2]; /* extra axes positions */ + DWORD rgdwPOV[4]; /* POV directions */ + BYTE rgbButtons[128]; /* 128 buttons */ + LONG lVX; /* x-axis velocity */ + LONG lVY; /* y-axis velocity */ + LONG lVZ; /* z-axis velocity */ + LONG lVRx; /* x-axis angular velocity */ + LONG lVRy; /* y-axis angular velocity */ + LONG lVRz; /* z-axis angular velocity */ + LONG rglVSlider[2]; /* extra axes velocities */ + LONG lAX; /* x-axis acceleration */ + LONG lAY; /* y-axis acceleration */ + LONG lAZ; /* z-axis acceleration */ + LONG lARx; /* x-axis angular acceleration */ + LONG lARy; /* y-axis angular acceleration */ + LONG lARz; /* z-axis angular acceleration */ + LONG rglASlider[2]; /* extra axes accelerations */ + LONG lFX; /* x-axis force */ + LONG lFY; /* y-axis force */ + LONG lFZ; /* z-axis force */ + LONG lFRx; /* x-axis torque */ + LONG lFRy; /* y-axis torque */ + LONG lFRz; /* z-axis torque */ + LONG rglFSlider[2]; /* extra axes forces */ +} DIJOYSTATE2, *LPDIJOYSTATE2; + +#define DIJOFS_X FIELD_OFFSET(DIJOYSTATE, lX) +#define DIJOFS_Y FIELD_OFFSET(DIJOYSTATE, lY) +#define DIJOFS_Z FIELD_OFFSET(DIJOYSTATE, lZ) +#define DIJOFS_RX FIELD_OFFSET(DIJOYSTATE, lRx) +#define DIJOFS_RY FIELD_OFFSET(DIJOYSTATE, lRy) +#define DIJOFS_RZ FIELD_OFFSET(DIJOYSTATE, lRz) +#define DIJOFS_SLIDER(n) (FIELD_OFFSET(DIJOYSTATE, rglSlider) + \ + (n) * sizeof(LONG)) +#define DIJOFS_POV(n) (FIELD_OFFSET(DIJOYSTATE, rgdwPOV) + \ + (n) * sizeof(DWORD)) +#define DIJOFS_BUTTON(n) (FIELD_OFFSET(DIJOYSTATE, rgbButtons) + (n)) +#define DIJOFS_BUTTON0 DIJOFS_BUTTON(0) +#define DIJOFS_BUTTON1 DIJOFS_BUTTON(1) +#define DIJOFS_BUTTON2 DIJOFS_BUTTON(2) +#define DIJOFS_BUTTON3 DIJOFS_BUTTON(3) +#define DIJOFS_BUTTON4 DIJOFS_BUTTON(4) +#define DIJOFS_BUTTON5 DIJOFS_BUTTON(5) +#define DIJOFS_BUTTON6 DIJOFS_BUTTON(6) +#define DIJOFS_BUTTON7 DIJOFS_BUTTON(7) +#define DIJOFS_BUTTON8 DIJOFS_BUTTON(8) +#define DIJOFS_BUTTON9 DIJOFS_BUTTON(9) +#define DIJOFS_BUTTON10 DIJOFS_BUTTON(10) +#define DIJOFS_BUTTON11 DIJOFS_BUTTON(11) +#define DIJOFS_BUTTON12 DIJOFS_BUTTON(12) +#define DIJOFS_BUTTON13 DIJOFS_BUTTON(13) +#define DIJOFS_BUTTON14 DIJOFS_BUTTON(14) +#define DIJOFS_BUTTON15 DIJOFS_BUTTON(15) +#define DIJOFS_BUTTON16 DIJOFS_BUTTON(16) +#define DIJOFS_BUTTON17 DIJOFS_BUTTON(17) +#define DIJOFS_BUTTON18 DIJOFS_BUTTON(18) +#define DIJOFS_BUTTON19 DIJOFS_BUTTON(19) +#define DIJOFS_BUTTON20 DIJOFS_BUTTON(20) +#define DIJOFS_BUTTON21 DIJOFS_BUTTON(21) +#define DIJOFS_BUTTON22 DIJOFS_BUTTON(22) +#define DIJOFS_BUTTON23 DIJOFS_BUTTON(23) +#define DIJOFS_BUTTON24 DIJOFS_BUTTON(24) +#define DIJOFS_BUTTON25 DIJOFS_BUTTON(25) +#define DIJOFS_BUTTON26 DIJOFS_BUTTON(26) +#define DIJOFS_BUTTON27 DIJOFS_BUTTON(27) +#define DIJOFS_BUTTON28 DIJOFS_BUTTON(28) +#define DIJOFS_BUTTON29 DIJOFS_BUTTON(29) +#define DIJOFS_BUTTON30 DIJOFS_BUTTON(30) +#define DIJOFS_BUTTON31 DIJOFS_BUTTON(31) + + +#endif /* DIJ_RINGZERO */ + +/**************************************************************************** + * + * IDirectInput + * + ****************************************************************************/ + +#ifndef DIJ_RINGZERO + +#define DIENUM_STOP 0 +#define DIENUM_CONTINUE 1 + +typedef BOOL (FAR PASCAL * LPDIENUMDEVICESCALLBACKA)(LPCDIDEVICEINSTANCEA, LPVOID); +typedef BOOL (FAR PASCAL * LPDIENUMDEVICESCALLBACKW)(LPCDIDEVICEINSTANCEW, LPVOID); +#ifdef UNICODE +#define LPDIENUMDEVICESCALLBACK LPDIENUMDEVICESCALLBACKW +#else +#define LPDIENUMDEVICESCALLBACK LPDIENUMDEVICESCALLBACKA +#endif // !UNICODE +typedef BOOL (FAR PASCAL * LPDICONFIGUREDEVICESCALLBACK)(IUnknown FAR *, LPVOID); + +#define DIEDFL_ALLDEVICES 0x00000000 +#define DIEDFL_ATTACHEDONLY 0x00000001 +#if(DIRECTINPUT_VERSION >= 0x0500) +#define DIEDFL_FORCEFEEDBACK 0x00000100 +#endif /* DIRECTINPUT_VERSION >= 0x0500 */ +#if(DIRECTINPUT_VERSION >= 0x050a) +#define DIEDFL_INCLUDEALIASES 0x00010000 +#define DIEDFL_INCLUDEPHANTOMS 0x00020000 +#endif /* DIRECTINPUT_VERSION >= 0x050a */ +#if(DIRECTINPUT_VERSION >= 0x0800) +#define DIEDFL_INCLUDEHIDDEN 0x00040000 +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + + +#if(DIRECTINPUT_VERSION >= 0x0800) +typedef BOOL (FAR PASCAL * LPDIENUMDEVICESBYSEMANTICSCBA)(LPCDIDEVICEINSTANCEA, LPDIRECTINPUTDEVICE8A, DWORD, DWORD, LPVOID); +typedef BOOL (FAR PASCAL * LPDIENUMDEVICESBYSEMANTICSCBW)(LPCDIDEVICEINSTANCEW, LPDIRECTINPUTDEVICE8W, DWORD, DWORD, LPVOID); +#ifdef UNICODE +#define LPDIENUMDEVICESBYSEMANTICSCB LPDIENUMDEVICESBYSEMANTICSCBW +#else +#define LPDIENUMDEVICESBYSEMANTICSCB LPDIENUMDEVICESBYSEMANTICSCBA +#endif // !UNICODE +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +#if(DIRECTINPUT_VERSION >= 0x0800) +#define DIEDBS_MAPPEDPRI1 0x00000001 +#define DIEDBS_MAPPEDPRI2 0x00000002 +#define DIEDBS_RECENTDEVICE 0x00000010 +#define DIEDBS_NEWDEVICE 0x00000020 +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +#if(DIRECTINPUT_VERSION >= 0x0800) +#define DIEDBSFL_ATTACHEDONLY 0x00000000 +#define DIEDBSFL_THISUSER 0x00000010 +#define DIEDBSFL_FORCEFEEDBACK DIEDFL_FORCEFEEDBACK +#define DIEDBSFL_AVAILABLEDEVICES 0x00001000 +#define DIEDBSFL_MULTIMICEKEYBOARDS 0x00002000 +#define DIEDBSFL_NONGAMINGDEVICES 0x00004000 +#define DIEDBSFL_VALID 0x00007110 +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +#undef INTERFACE +#define INTERFACE IDirectInputW + +DECLARE_INTERFACE_(IDirectInputW, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputW methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEW *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; +}; + +typedef struct IDirectInputW *LPDIRECTINPUTW; + +#undef INTERFACE +#define INTERFACE IDirectInputA + +DECLARE_INTERFACE_(IDirectInputA, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputA methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEA *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; +}; + +typedef struct IDirectInputA *LPDIRECTINPUTA; + +#ifdef UNICODE +#define IID_IDirectInput IID_IDirectInputW +#define IDirectInput IDirectInputW +#define IDirectInputVtbl IDirectInputWVtbl +#else +#define IID_IDirectInput IID_IDirectInputA +#define IDirectInput IDirectInputA +#define IDirectInputVtbl IDirectInputAVtbl +#endif +typedef struct IDirectInput *LPDIRECTINPUT; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInput_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInput_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInput_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInput_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) +#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) +#define IDirectInput_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) +#define IDirectInput_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInput_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#else +#define IDirectInput_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInput_AddRef(p) (p)->AddRef() +#define IDirectInput_Release(p) (p)->Release() +#define IDirectInput_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) +#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) +#define IDirectInput_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) +#define IDirectInput_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInput_Initialize(p,a,b) (p)->Initialize(a,b) +#endif + +#undef INTERFACE +#define INTERFACE IDirectInput2W + +DECLARE_INTERFACE_(IDirectInput2W, IDirectInputW) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputW methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEW *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; + + /*** IDirectInput2W methods ***/ + STDMETHOD(FindDevice)(THIS_ REFGUID,LPCWSTR,LPGUID) PURE; +}; + +typedef struct IDirectInput2W *LPDIRECTINPUT2W; + +#undef INTERFACE +#define INTERFACE IDirectInput2A + +DECLARE_INTERFACE_(IDirectInput2A, IDirectInputA) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputA methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEA *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; + + /*** IDirectInput2A methods ***/ + STDMETHOD(FindDevice)(THIS_ REFGUID,LPCSTR,LPGUID) PURE; +}; + +typedef struct IDirectInput2A *LPDIRECTINPUT2A; + +#ifdef UNICODE +#define IID_IDirectInput2 IID_IDirectInput2W +#define IDirectInput2 IDirectInput2W +#define IDirectInput2Vtbl IDirectInput2WVtbl +#else +#define IID_IDirectInput2 IID_IDirectInput2A +#define IDirectInput2 IDirectInput2A +#define IDirectInput2Vtbl IDirectInput2AVtbl +#endif +typedef struct IDirectInput2 *LPDIRECTINPUT2; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInput2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInput2_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInput2_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInput2_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) +#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) +#define IDirectInput2_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) +#define IDirectInput2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInput2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectInput2_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c) +#else +#define IDirectInput2_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInput2_AddRef(p) (p)->AddRef() +#define IDirectInput2_Release(p) (p)->Release() +#define IDirectInput2_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) +#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) +#define IDirectInput2_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) +#define IDirectInput2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInput2_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectInput2_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c) +#endif + + +#undef INTERFACE +#define INTERFACE IDirectInput7W + +DECLARE_INTERFACE_(IDirectInput7W, IDirectInput2W) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInput2W methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEW *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; + STDMETHOD(FindDevice)(THIS_ REFGUID,LPCWSTR,LPGUID) PURE; + + /*** IDirectInput7W methods ***/ + STDMETHOD(CreateDeviceEx)(THIS_ REFGUID,REFIID,LPVOID *,LPUNKNOWN) PURE; +}; + +typedef struct IDirectInput7W *LPDIRECTINPUT7W; + +#undef INTERFACE +#define INTERFACE IDirectInput7A + +DECLARE_INTERFACE_(IDirectInput7A, IDirectInput2A) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInput2A methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEA *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; + STDMETHOD(FindDevice)(THIS_ REFGUID,LPCSTR,LPGUID) PURE; + + /*** IDirectInput7A methods ***/ + STDMETHOD(CreateDeviceEx)(THIS_ REFGUID,REFIID,LPVOID *,LPUNKNOWN) PURE; +}; + +typedef struct IDirectInput7A *LPDIRECTINPUT7A; + +#ifdef UNICODE +#define IID_IDirectInput7 IID_IDirectInput7W +#define IDirectInput7 IDirectInput7W +#define IDirectInput7Vtbl IDirectInput7WVtbl +#else +#define IID_IDirectInput7 IID_IDirectInput7A +#define IDirectInput7 IDirectInput7A +#define IDirectInput7Vtbl IDirectInput7AVtbl +#endif +typedef struct IDirectInput7 *LPDIRECTINPUT7; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInput7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInput7_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInput7_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInput7_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) +#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) +#define IDirectInput7_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) +#define IDirectInput7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInput7_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectInput7_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c) +#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d) +#else +#define IDirectInput7_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInput7_AddRef(p) (p)->AddRef() +#define IDirectInput7_Release(p) (p)->Release() +#define IDirectInput7_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) +#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) +#define IDirectInput7_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) +#define IDirectInput7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInput7_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectInput7_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c) +#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->CreateDeviceEx(a,b,c,d) +#endif + +#if(DIRECTINPUT_VERSION >= 0x0800) +#undef INTERFACE +#define INTERFACE IDirectInput8W + +DECLARE_INTERFACE_(IDirectInput8W, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInput8W methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICE8W *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; + STDMETHOD(FindDevice)(THIS_ REFGUID,LPCWSTR,LPGUID) PURE; + STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCWSTR,LPDIACTIONFORMATW,LPDIENUMDEVICESBYSEMANTICSCBW,LPVOID,DWORD) PURE; + STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK,LPDICONFIGUREDEVICESPARAMSW,DWORD,LPVOID) PURE; +}; + +typedef struct IDirectInput8W *LPDIRECTINPUT8W; + +#undef INTERFACE +#define INTERFACE IDirectInput8A + +DECLARE_INTERFACE_(IDirectInput8A, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInput8A methods ***/ + STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICE8A *,LPUNKNOWN) PURE; + STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKA,LPVOID,DWORD) PURE; + STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE; + STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE; + STDMETHOD(FindDevice)(THIS_ REFGUID,LPCSTR,LPGUID) PURE; + STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCSTR,LPDIACTIONFORMATA,LPDIENUMDEVICESBYSEMANTICSCBA,LPVOID,DWORD) PURE; + STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK,LPDICONFIGUREDEVICESPARAMSA,DWORD,LPVOID) PURE; +}; + +typedef struct IDirectInput8A *LPDIRECTINPUT8A; + +#ifdef UNICODE +#define IID_IDirectInput8 IID_IDirectInput8W +#define IDirectInput8 IDirectInput8W +#define IDirectInput8Vtbl IDirectInput8WVtbl +#else +#define IID_IDirectInput8 IID_IDirectInput8A +#define IDirectInput8 IDirectInput8A +#define IDirectInput8Vtbl IDirectInput8AVtbl +#endif +typedef struct IDirectInput8 *LPDIRECTINPUT8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInput8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInput8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInput8_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInput8_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c) +#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d) +#define IDirectInput8_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a) +#define IDirectInput8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b) +#define IDirectInput8_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectInput8_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c) +#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->lpVtbl->EnumDevicesBySemantics(p,a,b,c,d,e) +#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->lpVtbl->ConfigureDevices(p,a,b,c,d) +#else +#define IDirectInput8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInput8_AddRef(p) (p)->AddRef() +#define IDirectInput8_Release(p) (p)->Release() +#define IDirectInput8_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c) +#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d) +#define IDirectInput8_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a) +#define IDirectInput8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b) +#define IDirectInput8_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectInput8_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c) +#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->EnumDevicesBySemantics(a,b,c,d,e) +#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->ConfigureDevices(a,b,c,d) +#endif +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +#if DIRECTINPUT_VERSION > 0x0700 + +extern HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); + +#else +extern HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter); +extern HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTW *ppDI, LPUNKNOWN punkOuter); +#ifdef UNICODE +#define DirectInputCreate DirectInputCreateW +#else +#define DirectInputCreate DirectInputCreateA +#endif // !UNICODE + +extern HRESULT WINAPI DirectInputCreateEx(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); + +#endif /* DIRECTINPUT_VERSION > 0x700 */ + +#endif /* DIJ_RINGZERO */ + + +/**************************************************************************** + * + * Return Codes + * + ****************************************************************************/ + +/* + * The operation completed successfully. + */ +#define DI_OK S_OK + +/* + * The device exists but is not currently attached. + */ +#define DI_NOTATTACHED S_FALSE + +/* + * The device buffer overflowed. Some input was lost. + */ +#define DI_BUFFEROVERFLOW S_FALSE + +/* + * The change in device properties had no effect. + */ +#define DI_PROPNOEFFECT S_FALSE + +/* + * The operation had no effect. + */ +#define DI_NOEFFECT S_FALSE + +/* + * The device is a polled device. As a result, device buffering + * will not collect any data and event notifications will not be + * signalled until GetDeviceState is called. + */ +#define DI_POLLEDDEVICE ((HRESULT)0x00000002L) + +/* + * The parameters of the effect were successfully updated by + * IDirectInputEffect::SetParameters, but the effect was not + * downloaded because the device is not exclusively acquired + * or because the DIEP_NODOWNLOAD flag was passed. + */ +#define DI_DOWNLOADSKIPPED ((HRESULT)0x00000003L) + +/* + * The parameters of the effect were successfully updated by + * IDirectInputEffect::SetParameters, but in order to change + * the parameters, the effect needed to be restarted. + */ +#define DI_EFFECTRESTARTED ((HRESULT)0x00000004L) + +/* + * The parameters of the effect were successfully updated by + * IDirectInputEffect::SetParameters, but some of them were + * beyond the capabilities of the device and were truncated. + */ +#define DI_TRUNCATED ((HRESULT)0x00000008L) + +/* + * The settings have been successfully applied but could not be + * persisted. + */ +#define DI_SETTINGSNOTSAVED ((HRESULT)0x0000000BL) + +/* + * Equal to DI_EFFECTRESTARTED | DI_TRUNCATED. + */ +#define DI_TRUNCATEDANDRESTARTED ((HRESULT)0x0000000CL) + +/* + * A SUCCESS code indicating that settings cannot be modified. + */ +#define DI_WRITEPROTECT ((HRESULT)0x00000013L) + +/* + * The application requires a newer version of DirectInput. + */ +#define DIERR_OLDDIRECTINPUTVERSION \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_OLD_WIN_VERSION) + +/* + * The application was written for an unsupported prerelease version + * of DirectInput. + */ +#define DIERR_BETADIRECTINPUTVERSION \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_RMODE_APP) + +/* + * The object could not be created due to an incompatible driver version + * or mismatched or incomplete driver components. + */ +#define DIERR_BADDRIVERVER \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BAD_DRIVER_LEVEL) + +/* + * The device or device instance or effect is not registered with DirectInput. + */ +#define DIERR_DEVICENOTREG REGDB_E_CLASSNOTREG + +/* + * The requested object does not exist. + */ +#define DIERR_NOTFOUND \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND) + +/* + * The requested object does not exist. + */ +#define DIERR_OBJECTNOTFOUND \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND) + +/* + * An invalid parameter was passed to the returning function, + * or the object was not in a state that admitted the function + * to be called. + */ +#define DIERR_INVALIDPARAM E_INVALIDARG + +/* + * The specified interface is not supported by the object + */ +#define DIERR_NOINTERFACE E_NOINTERFACE + +/* + * An undetermined error occured inside the DInput subsystem + */ +#define DIERR_GENERIC E_FAIL + +/* + * The DInput subsystem couldn't allocate sufficient memory to complete the + * caller's request. + */ +#define DIERR_OUTOFMEMORY E_OUTOFMEMORY + +/* + * The function called is not supported at this time + */ +#define DIERR_UNSUPPORTED E_NOTIMPL + +/* + * This object has not been initialized + */ +#define DIERR_NOTINITIALIZED \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_READY) + +/* + * This object is already initialized + */ +#define DIERR_ALREADYINITIALIZED \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_ALREADY_INITIALIZED) + +/* + * This object does not support aggregation + */ +#define DIERR_NOAGGREGATION CLASS_E_NOAGGREGATION + +/* + * Another app has a higher priority level, preventing this call from + * succeeding. + */ +#define DIERR_OTHERAPPHASPRIO E_ACCESSDENIED + +/* + * Access to the device has been lost. It must be re-acquired. + */ +#define DIERR_INPUTLOST \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_READ_FAULT) + +/* + * The operation cannot be performed while the device is acquired. + */ +#define DIERR_ACQUIRED \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BUSY) + +/* + * The operation cannot be performed unless the device is acquired. + */ +#define DIERR_NOTACQUIRED \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_INVALID_ACCESS) + +/* + * The specified property cannot be changed. + */ +#define DIERR_READONLY E_ACCESSDENIED + +/* + * The device already has an event notification associated with it. + */ +#define DIERR_HANDLEEXISTS E_ACCESSDENIED + +/* + * Data is not yet available. + */ +#ifndef E_PENDING +#define E_PENDING 0x8000000AL +#endif + +/* + * Unable to IDirectInputJoyConfig_Acquire because the user + * does not have sufficient privileges to change the joystick + * configuration. + */ +#define DIERR_INSUFFICIENTPRIVS 0x80040200L + +/* + * The device is full. + */ +#define DIERR_DEVICEFULL 0x80040201L + +/* + * Not all the requested information fit into the buffer. + */ +#define DIERR_MOREDATA 0x80040202L + +/* + * The effect is not downloaded. + */ +#define DIERR_NOTDOWNLOADED 0x80040203L + +/* + * The device cannot be reinitialized because there are still effects + * attached to it. + */ +#define DIERR_HASEFFECTS 0x80040204L + +/* + * The operation cannot be performed unless the device is acquired + * in DISCL_EXCLUSIVE mode. + */ +#define DIERR_NOTEXCLUSIVEACQUIRED 0x80040205L + +/* + * The effect could not be downloaded because essential information + * is missing. For example, no axes have been associated with the + * effect, or no type-specific information has been created. + */ +#define DIERR_INCOMPLETEEFFECT 0x80040206L + +/* + * Attempted to read buffered device data from a device that is + * not buffered. + */ +#define DIERR_NOTBUFFERED 0x80040207L + +/* + * An attempt was made to modify parameters of an effect while it is + * playing. Not all hardware devices support altering the parameters + * of an effect while it is playing. + */ +#define DIERR_EFFECTPLAYING 0x80040208L + +/* + * The operation could not be completed because the device is not + * plugged in. + */ +#define DIERR_UNPLUGGED 0x80040209L + +/* + * SendDeviceData failed because more information was requested + * to be sent than can be sent to the device. Some devices have + * restrictions on how much data can be sent to them. (For example, + * there might be a limit on the number of buttons that can be + * pressed at once.) + */ +#define DIERR_REPORTFULL 0x8004020AL + + +/* + * A mapper file function failed because reading or writing the user or IHV + * settings file failed. + */ +#define DIERR_MAPFILEFAIL 0x8004020BL + + +/*--- DINPUT Mapper Definitions: New for Dx8 ---*/ + + +/*--- Keyboard + Physical Keyboard Device ---*/ + +#define DIKEYBOARD_ESCAPE 0x81000401 +#define DIKEYBOARD_1 0x81000402 +#define DIKEYBOARD_2 0x81000403 +#define DIKEYBOARD_3 0x81000404 +#define DIKEYBOARD_4 0x81000405 +#define DIKEYBOARD_5 0x81000406 +#define DIKEYBOARD_6 0x81000407 +#define DIKEYBOARD_7 0x81000408 +#define DIKEYBOARD_8 0x81000409 +#define DIKEYBOARD_9 0x8100040A +#define DIKEYBOARD_0 0x8100040B +#define DIKEYBOARD_MINUS 0x8100040C /* - on main keyboard */ +#define DIKEYBOARD_EQUALS 0x8100040D +#define DIKEYBOARD_BACK 0x8100040E /* backspace */ +#define DIKEYBOARD_TAB 0x8100040F +#define DIKEYBOARD_Q 0x81000410 +#define DIKEYBOARD_W 0x81000411 +#define DIKEYBOARD_E 0x81000412 +#define DIKEYBOARD_R 0x81000413 +#define DIKEYBOARD_T 0x81000414 +#define DIKEYBOARD_Y 0x81000415 +#define DIKEYBOARD_U 0x81000416 +#define DIKEYBOARD_I 0x81000417 +#define DIKEYBOARD_O 0x81000418 +#define DIKEYBOARD_P 0x81000419 +#define DIKEYBOARD_LBRACKET 0x8100041A +#define DIKEYBOARD_RBRACKET 0x8100041B +#define DIKEYBOARD_RETURN 0x8100041C /* Enter on main keyboard */ +#define DIKEYBOARD_LCONTROL 0x8100041D +#define DIKEYBOARD_A 0x8100041E +#define DIKEYBOARD_S 0x8100041F +#define DIKEYBOARD_D 0x81000420 +#define DIKEYBOARD_F 0x81000421 +#define DIKEYBOARD_G 0x81000422 +#define DIKEYBOARD_H 0x81000423 +#define DIKEYBOARD_J 0x81000424 +#define DIKEYBOARD_K 0x81000425 +#define DIKEYBOARD_L 0x81000426 +#define DIKEYBOARD_SEMICOLON 0x81000427 +#define DIKEYBOARD_APOSTROPHE 0x81000428 +#define DIKEYBOARD_GRAVE 0x81000429 /* accent grave */ +#define DIKEYBOARD_LSHIFT 0x8100042A +#define DIKEYBOARD_BACKSLASH 0x8100042B +#define DIKEYBOARD_Z 0x8100042C +#define DIKEYBOARD_X 0x8100042D +#define DIKEYBOARD_C 0x8100042E +#define DIKEYBOARD_V 0x8100042F +#define DIKEYBOARD_B 0x81000430 +#define DIKEYBOARD_N 0x81000431 +#define DIKEYBOARD_M 0x81000432 +#define DIKEYBOARD_COMMA 0x81000433 +#define DIKEYBOARD_PERIOD 0x81000434 /* . on main keyboard */ +#define DIKEYBOARD_SLASH 0x81000435 /* / on main keyboard */ +#define DIKEYBOARD_RSHIFT 0x81000436 +#define DIKEYBOARD_MULTIPLY 0x81000437 /* * on numeric keypad */ +#define DIKEYBOARD_LMENU 0x81000438 /* left Alt */ +#define DIKEYBOARD_SPACE 0x81000439 +#define DIKEYBOARD_CAPITAL 0x8100043A +#define DIKEYBOARD_F1 0x8100043B +#define DIKEYBOARD_F2 0x8100043C +#define DIKEYBOARD_F3 0x8100043D +#define DIKEYBOARD_F4 0x8100043E +#define DIKEYBOARD_F5 0x8100043F +#define DIKEYBOARD_F6 0x81000440 +#define DIKEYBOARD_F7 0x81000441 +#define DIKEYBOARD_F8 0x81000442 +#define DIKEYBOARD_F9 0x81000443 +#define DIKEYBOARD_F10 0x81000444 +#define DIKEYBOARD_NUMLOCK 0x81000445 +#define DIKEYBOARD_SCROLL 0x81000446 /* Scroll Lock */ +#define DIKEYBOARD_NUMPAD7 0x81000447 +#define DIKEYBOARD_NUMPAD8 0x81000448 +#define DIKEYBOARD_NUMPAD9 0x81000449 +#define DIKEYBOARD_SUBTRACT 0x8100044A /* - on numeric keypad */ +#define DIKEYBOARD_NUMPAD4 0x8100044B +#define DIKEYBOARD_NUMPAD5 0x8100044C +#define DIKEYBOARD_NUMPAD6 0x8100044D +#define DIKEYBOARD_ADD 0x8100044E /* + on numeric keypad */ +#define DIKEYBOARD_NUMPAD1 0x8100044F +#define DIKEYBOARD_NUMPAD2 0x81000450 +#define DIKEYBOARD_NUMPAD3 0x81000451 +#define DIKEYBOARD_NUMPAD0 0x81000452 +#define DIKEYBOARD_DECIMAL 0x81000453 /* . on numeric keypad */ +#define DIKEYBOARD_OEM_102 0x81000456 /* <> or \| on RT 102-key keyboard (Non-U.S.) */ +#define DIKEYBOARD_F11 0x81000457 +#define DIKEYBOARD_F12 0x81000458 +#define DIKEYBOARD_F13 0x81000464 /* (NEC PC98) */ +#define DIKEYBOARD_F14 0x81000465 /* (NEC PC98) */ +#define DIKEYBOARD_F15 0x81000466 /* (NEC PC98) */ +#define DIKEYBOARD_KANA 0x81000470 /* (Japanese keyboard) */ +#define DIKEYBOARD_ABNT_C1 0x81000473 /* /? on Brazilian keyboard */ +#define DIKEYBOARD_CONVERT 0x81000479 /* (Japanese keyboard) */ +#define DIKEYBOARD_NOCONVERT 0x8100047B /* (Japanese keyboard) */ +#define DIKEYBOARD_YEN 0x8100047D /* (Japanese keyboard) */ +#define DIKEYBOARD_ABNT_C2 0x8100047E /* Numpad . on Brazilian keyboard */ +#define DIKEYBOARD_NUMPADEQUALS 0x8100048D /* = on numeric keypad (NEC PC98) */ +#define DIKEYBOARD_PREVTRACK 0x81000490 /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ +#define DIKEYBOARD_AT 0x81000491 /* (NEC PC98) */ +#define DIKEYBOARD_COLON 0x81000492 /* (NEC PC98) */ +#define DIKEYBOARD_UNDERLINE 0x81000493 /* (NEC PC98) */ +#define DIKEYBOARD_KANJI 0x81000494 /* (Japanese keyboard) */ +#define DIKEYBOARD_STOP 0x81000495 /* (NEC PC98) */ +#define DIKEYBOARD_AX 0x81000496 /* (Japan AX) */ +#define DIKEYBOARD_UNLABELED 0x81000497 /* (J3100) */ +#define DIKEYBOARD_NEXTTRACK 0x81000499 /* Next Track */ +#define DIKEYBOARD_NUMPADENTER 0x8100049C /* Enter on numeric keypad */ +#define DIKEYBOARD_RCONTROL 0x8100049D +#define DIKEYBOARD_MUTE 0x810004A0 /* Mute */ +#define DIKEYBOARD_CALCULATOR 0x810004A1 /* Calculator */ +#define DIKEYBOARD_PLAYPAUSE 0x810004A2 /* Play / Pause */ +#define DIKEYBOARD_MEDIASTOP 0x810004A4 /* Media Stop */ +#define DIKEYBOARD_VOLUMEDOWN 0x810004AE /* Volume - */ +#define DIKEYBOARD_VOLUMEUP 0x810004B0 /* Volume + */ +#define DIKEYBOARD_WEBHOME 0x810004B2 /* Web home */ +#define DIKEYBOARD_NUMPADCOMMA 0x810004B3 /* , on numeric keypad (NEC PC98) */ +#define DIKEYBOARD_DIVIDE 0x810004B5 /* / on numeric keypad */ +#define DIKEYBOARD_SYSRQ 0x810004B7 +#define DIKEYBOARD_RMENU 0x810004B8 /* right Alt */ +#define DIKEYBOARD_PAUSE 0x810004C5 /* Pause */ +#define DIKEYBOARD_HOME 0x810004C7 /* Home on arrow keypad */ +#define DIKEYBOARD_UP 0x810004C8 /* UpArrow on arrow keypad */ +#define DIKEYBOARD_PRIOR 0x810004C9 /* PgUp on arrow keypad */ +#define DIKEYBOARD_LEFT 0x810004CB /* LeftArrow on arrow keypad */ +#define DIKEYBOARD_RIGHT 0x810004CD /* RightArrow on arrow keypad */ +#define DIKEYBOARD_END 0x810004CF /* End on arrow keypad */ +#define DIKEYBOARD_DOWN 0x810004D0 /* DownArrow on arrow keypad */ +#define DIKEYBOARD_NEXT 0x810004D1 /* PgDn on arrow keypad */ +#define DIKEYBOARD_INSERT 0x810004D2 /* Insert on arrow keypad */ +#define DIKEYBOARD_DELETE 0x810004D3 /* Delete on arrow keypad */ +#define DIKEYBOARD_LWIN 0x810004DB /* Left Windows key */ +#define DIKEYBOARD_RWIN 0x810004DC /* Right Windows key */ +#define DIKEYBOARD_APPS 0x810004DD /* AppMenu key */ +#define DIKEYBOARD_POWER 0x810004DE /* System Power */ +#define DIKEYBOARD_SLEEP 0x810004DF /* System Sleep */ +#define DIKEYBOARD_WAKE 0x810004E3 /* System Wake */ +#define DIKEYBOARD_WEBSEARCH 0x810004E5 /* Web Search */ +#define DIKEYBOARD_WEBFAVORITES 0x810004E6 /* Web Favorites */ +#define DIKEYBOARD_WEBREFRESH 0x810004E7 /* Web Refresh */ +#define DIKEYBOARD_WEBSTOP 0x810004E8 /* Web Stop */ +#define DIKEYBOARD_WEBFORWARD 0x810004E9 /* Web Forward */ +#define DIKEYBOARD_WEBBACK 0x810004EA /* Web Back */ +#define DIKEYBOARD_MYCOMPUTER 0x810004EB /* My Computer */ +#define DIKEYBOARD_MAIL 0x810004EC /* Mail */ +#define DIKEYBOARD_MEDIASELECT 0x810004ED /* Media Select */ + + +/*--- MOUSE + Physical Mouse Device ---*/ + +#define DIMOUSE_XAXISAB (0x82000200 |DIMOFS_X ) /* X Axis-absolute: Some mice natively report absolute coordinates */ +#define DIMOUSE_YAXISAB (0x82000200 |DIMOFS_Y ) /* Y Axis-absolute: Some mice natively report absolute coordinates */ +#define DIMOUSE_XAXIS (0x82000300 |DIMOFS_X ) /* X Axis */ +#define DIMOUSE_YAXIS (0x82000300 |DIMOFS_Y ) /* Y Axis */ +#define DIMOUSE_WHEEL (0x82000300 |DIMOFS_Z ) /* Z Axis */ +#define DIMOUSE_BUTTON0 (0x82000400 |DIMOFS_BUTTON0) /* Button 0 */ +#define DIMOUSE_BUTTON1 (0x82000400 |DIMOFS_BUTTON1) /* Button 1 */ +#define DIMOUSE_BUTTON2 (0x82000400 |DIMOFS_BUTTON2) /* Button 2 */ +#define DIMOUSE_BUTTON3 (0x82000400 |DIMOFS_BUTTON3) /* Button 3 */ +#define DIMOUSE_BUTTON4 (0x82000400 |DIMOFS_BUTTON4) /* Button 4 */ +#define DIMOUSE_BUTTON5 (0x82000400 |DIMOFS_BUTTON5) /* Button 5 */ +#define DIMOUSE_BUTTON6 (0x82000400 |DIMOFS_BUTTON6) /* Button 6 */ +#define DIMOUSE_BUTTON7 (0x82000400 |DIMOFS_BUTTON7) /* Button 7 */ + + +/*--- VOICE + Physical Dplay Voice Device ---*/ + +#define DIVOICE_CHANNEL1 0x83000401 +#define DIVOICE_CHANNEL2 0x83000402 +#define DIVOICE_CHANNEL3 0x83000403 +#define DIVOICE_CHANNEL4 0x83000404 +#define DIVOICE_CHANNEL5 0x83000405 +#define DIVOICE_CHANNEL6 0x83000406 +#define DIVOICE_CHANNEL7 0x83000407 +#define DIVOICE_CHANNEL8 0x83000408 +#define DIVOICE_TEAM 0x83000409 +#define DIVOICE_ALL 0x8300040A +#define DIVOICE_RECORDMUTE 0x8300040B +#define DIVOICE_PLAYBACKMUTE 0x8300040C +#define DIVOICE_TRANSMIT 0x8300040D + +#define DIVOICE_VOICECOMMAND 0x83000410 + + +/*--- Driving Simulator - Racing + Vehicle control is primary objective ---*/ +#define DIVIRTUAL_DRIVING_RACE 0x01000000 +#define DIAXIS_DRIVINGR_STEER 0x01008A01 /* Steering */ +#define DIAXIS_DRIVINGR_ACCELERATE 0x01039202 /* Accelerate */ +#define DIAXIS_DRIVINGR_BRAKE 0x01041203 /* Brake-Axis */ +#define DIBUTTON_DRIVINGR_SHIFTUP 0x01000C01 /* Shift to next higher gear */ +#define DIBUTTON_DRIVINGR_SHIFTDOWN 0x01000C02 /* Shift to next lower gear */ +#define DIBUTTON_DRIVINGR_VIEW 0x01001C03 /* Cycle through view options */ +#define DIBUTTON_DRIVINGR_MENU 0x010004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIAXIS_DRIVINGR_ACCEL_AND_BRAKE 0x01014A04 /* Some devices combine accelerate and brake in a single axis */ +#define DIHATSWITCH_DRIVINGR_GLANCE 0x01004601 /* Look around */ +#define DIBUTTON_DRIVINGR_BRAKE 0x01004C04 /* Brake-button */ +#define DIBUTTON_DRIVINGR_DASHBOARD 0x01004405 /* Select next dashboard option */ +#define DIBUTTON_DRIVINGR_AIDS 0x01004406 /* Driver correction aids */ +#define DIBUTTON_DRIVINGR_MAP 0x01004407 /* Display Driving Map */ +#define DIBUTTON_DRIVINGR_BOOST 0x01004408 /* Turbo Boost */ +#define DIBUTTON_DRIVINGR_PIT 0x01004409 /* Pit stop notification */ +#define DIBUTTON_DRIVINGR_ACCELERATE_LINK 0x0103D4E0 /* Fallback Accelerate button */ +#define DIBUTTON_DRIVINGR_STEER_LEFT_LINK 0x0100CCE4 /* Fallback Steer Left button */ +#define DIBUTTON_DRIVINGR_STEER_RIGHT_LINK 0x0100CCEC /* Fallback Steer Right button */ +#define DIBUTTON_DRIVINGR_GLANCE_LEFT_LINK 0x0107C4E4 /* Fallback Glance Left button */ +#define DIBUTTON_DRIVINGR_GLANCE_RIGHT_LINK 0x0107C4EC /* Fallback Glance Right button */ +#define DIBUTTON_DRIVINGR_DEVICE 0x010044FE /* Show input device and controls */ +#define DIBUTTON_DRIVINGR_PAUSE 0x010044FC /* Start / Pause / Restart game */ + +/*--- Driving Simulator - Combat + Combat from within a vehicle is primary objective ---*/ +#define DIVIRTUAL_DRIVING_COMBAT 0x02000000 +#define DIAXIS_DRIVINGC_STEER 0x02008A01 /* Steering */ +#define DIAXIS_DRIVINGC_ACCELERATE 0x02039202 /* Accelerate */ +#define DIAXIS_DRIVINGC_BRAKE 0x02041203 /* Brake-axis */ +#define DIBUTTON_DRIVINGC_FIRE 0x02000C01 /* Fire */ +#define DIBUTTON_DRIVINGC_WEAPONS 0x02000C02 /* Select next weapon */ +#define DIBUTTON_DRIVINGC_TARGET 0x02000C03 /* Select next available target */ +#define DIBUTTON_DRIVINGC_MENU 0x020004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIAXIS_DRIVINGC_ACCEL_AND_BRAKE 0x02014A04 /* Some devices combine accelerate and brake in a single axis */ +#define DIHATSWITCH_DRIVINGC_GLANCE 0x02004601 /* Look around */ +#define DIBUTTON_DRIVINGC_SHIFTUP 0x02004C04 /* Shift to next higher gear */ +#define DIBUTTON_DRIVINGC_SHIFTDOWN 0x02004C05 /* Shift to next lower gear */ +#define DIBUTTON_DRIVINGC_DASHBOARD 0x02004406 /* Select next dashboard option */ +#define DIBUTTON_DRIVINGC_AIDS 0x02004407 /* Driver correction aids */ +#define DIBUTTON_DRIVINGC_BRAKE 0x02004C08 /* Brake-button */ +#define DIBUTTON_DRIVINGC_FIRESECONDARY 0x02004C09 /* Alternative fire button */ +#define DIBUTTON_DRIVINGC_ACCELERATE_LINK 0x0203D4E0 /* Fallback Accelerate button */ +#define DIBUTTON_DRIVINGC_STEER_LEFT_LINK 0x0200CCE4 /* Fallback Steer Left button */ +#define DIBUTTON_DRIVINGC_STEER_RIGHT_LINK 0x0200CCEC /* Fallback Steer Right button */ +#define DIBUTTON_DRIVINGC_GLANCE_LEFT_LINK 0x0207C4E4 /* Fallback Glance Left button */ +#define DIBUTTON_DRIVINGC_GLANCE_RIGHT_LINK 0x0207C4EC /* Fallback Glance Right button */ +#define DIBUTTON_DRIVINGC_DEVICE 0x020044FE /* Show input device and controls */ +#define DIBUTTON_DRIVINGC_PAUSE 0x020044FC /* Start / Pause / Restart game */ + +/*--- Driving Simulator - Tank + Combat from withing a tank is primary objective ---*/ +#define DIVIRTUAL_DRIVING_TANK 0x03000000 +#define DIAXIS_DRIVINGT_STEER 0x03008A01 /* Turn tank left / right */ +#define DIAXIS_DRIVINGT_BARREL 0x03010202 /* Raise / lower barrel */ +#define DIAXIS_DRIVINGT_ACCELERATE 0x03039203 /* Accelerate */ +#define DIAXIS_DRIVINGT_ROTATE 0x03020204 /* Turn barrel left / right */ +#define DIBUTTON_DRIVINGT_FIRE 0x03000C01 /* Fire */ +#define DIBUTTON_DRIVINGT_WEAPONS 0x03000C02 /* Select next weapon */ +#define DIBUTTON_DRIVINGT_TARGET 0x03000C03 /* Selects next available target */ +#define DIBUTTON_DRIVINGT_MENU 0x030004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_DRIVINGT_GLANCE 0x03004601 /* Look around */ +#define DIAXIS_DRIVINGT_BRAKE 0x03045205 /* Brake-axis */ +#define DIAXIS_DRIVINGT_ACCEL_AND_BRAKE 0x03014A06 /* Some devices combine accelerate and brake in a single axis */ +#define DIBUTTON_DRIVINGT_VIEW 0x03005C04 /* Cycle through view options */ +#define DIBUTTON_DRIVINGT_DASHBOARD 0x03005C05 /* Select next dashboard option */ +#define DIBUTTON_DRIVINGT_BRAKE 0x03004C06 /* Brake-button */ +#define DIBUTTON_DRIVINGT_FIRESECONDARY 0x03004C07 /* Alternative fire button */ +#define DIBUTTON_DRIVINGT_ACCELERATE_LINK 0x0303D4E0 /* Fallback Accelerate button */ +#define DIBUTTON_DRIVINGT_STEER_LEFT_LINK 0x0300CCE4 /* Fallback Steer Left button */ +#define DIBUTTON_DRIVINGT_STEER_RIGHT_LINK 0x0300CCEC /* Fallback Steer Right button */ +#define DIBUTTON_DRIVINGT_BARREL_UP_LINK 0x030144E0 /* Fallback Barrel up button */ +#define DIBUTTON_DRIVINGT_BARREL_DOWN_LINK 0x030144E8 /* Fallback Barrel down button */ +#define DIBUTTON_DRIVINGT_ROTATE_LEFT_LINK 0x030244E4 /* Fallback Rotate left button */ +#define DIBUTTON_DRIVINGT_ROTATE_RIGHT_LINK 0x030244EC /* Fallback Rotate right button */ +#define DIBUTTON_DRIVINGT_GLANCE_LEFT_LINK 0x0307C4E4 /* Fallback Glance Left button */ +#define DIBUTTON_DRIVINGT_GLANCE_RIGHT_LINK 0x0307C4EC /* Fallback Glance Right button */ +#define DIBUTTON_DRIVINGT_DEVICE 0x030044FE /* Show input device and controls */ +#define DIBUTTON_DRIVINGT_PAUSE 0x030044FC /* Start / Pause / Restart game */ + +/*--- Flight Simulator - Civilian + Plane control is the primary objective ---*/ +#define DIVIRTUAL_FLYING_CIVILIAN 0x04000000 +#define DIAXIS_FLYINGC_BANK 0x04008A01 /* Roll ship left / right */ +#define DIAXIS_FLYINGC_PITCH 0x04010A02 /* Nose up / down */ +#define DIAXIS_FLYINGC_THROTTLE 0x04039203 /* Throttle */ +#define DIBUTTON_FLYINGC_VIEW 0x04002401 /* Cycle through view options */ +#define DIBUTTON_FLYINGC_DISPLAY 0x04002402 /* Select next dashboard / heads up display option */ +#define DIBUTTON_FLYINGC_GEAR 0x04002C03 /* Gear up / down */ +#define DIBUTTON_FLYINGC_MENU 0x040004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_FLYINGC_GLANCE 0x04004601 /* Look around */ +#define DIAXIS_FLYINGC_BRAKE 0x04046A04 /* Apply Brake */ +#define DIAXIS_FLYINGC_RUDDER 0x04025205 /* Yaw ship left/right */ +#define DIAXIS_FLYINGC_FLAPS 0x04055A06 /* Flaps */ +#define DIBUTTON_FLYINGC_FLAPSUP 0x04006404 /* Increment stepping up until fully retracted */ +#define DIBUTTON_FLYINGC_FLAPSDOWN 0x04006405 /* Decrement stepping down until fully extended */ +#define DIBUTTON_FLYINGC_BRAKE_LINK 0x04046CE0 /* Fallback brake button */ +#define DIBUTTON_FLYINGC_FASTER_LINK 0x0403D4E0 /* Fallback throttle up button */ +#define DIBUTTON_FLYINGC_SLOWER_LINK 0x0403D4E8 /* Fallback throttle down button */ +#define DIBUTTON_FLYINGC_GLANCE_LEFT_LINK 0x0407C4E4 /* Fallback Glance Left button */ +#define DIBUTTON_FLYINGC_GLANCE_RIGHT_LINK 0x0407C4EC /* Fallback Glance Right button */ +#define DIBUTTON_FLYINGC_GLANCE_UP_LINK 0x0407C4E0 /* Fallback Glance Up button */ +#define DIBUTTON_FLYINGC_GLANCE_DOWN_LINK 0x0407C4E8 /* Fallback Glance Down button */ +#define DIBUTTON_FLYINGC_DEVICE 0x040044FE /* Show input device and controls */ +#define DIBUTTON_FLYINGC_PAUSE 0x040044FC /* Start / Pause / Restart game */ + +/*--- Flight Simulator - Military + Aerial combat is the primary objective ---*/ +#define DIVIRTUAL_FLYING_MILITARY 0x05000000 +#define DIAXIS_FLYINGM_BANK 0x05008A01 /* Bank - Roll ship left / right */ +#define DIAXIS_FLYINGM_PITCH 0x05010A02 /* Pitch - Nose up / down */ +#define DIAXIS_FLYINGM_THROTTLE 0x05039203 /* Throttle - faster / slower */ +#define DIBUTTON_FLYINGM_FIRE 0x05000C01 /* Fire */ +#define DIBUTTON_FLYINGM_WEAPONS 0x05000C02 /* Select next weapon */ +#define DIBUTTON_FLYINGM_TARGET 0x05000C03 /* Selects next available target */ +#define DIBUTTON_FLYINGM_MENU 0x050004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_FLYINGM_GLANCE 0x05004601 /* Look around */ +#define DIBUTTON_FLYINGM_COUNTER 0x05005C04 /* Activate counter measures */ +#define DIAXIS_FLYINGM_RUDDER 0x05024A04 /* Rudder - Yaw ship left/right */ +#define DIAXIS_FLYINGM_BRAKE 0x05046205 /* Brake-axis */ +#define DIBUTTON_FLYINGM_VIEW 0x05006405 /* Cycle through view options */ +#define DIBUTTON_FLYINGM_DISPLAY 0x05006406 /* Select next dashboard option */ +#define DIAXIS_FLYINGM_FLAPS 0x05055206 /* Flaps */ +#define DIBUTTON_FLYINGM_FLAPSUP 0x05005407 /* Increment stepping up until fully retracted */ +#define DIBUTTON_FLYINGM_FLAPSDOWN 0x05005408 /* Decrement stepping down until fully extended */ +#define DIBUTTON_FLYINGM_FIRESECONDARY 0x05004C09 /* Alternative fire button */ +#define DIBUTTON_FLYINGM_GEAR 0x0500640A /* Gear up / down */ +#define DIBUTTON_FLYINGM_BRAKE_LINK 0x050464E0 /* Fallback brake button */ +#define DIBUTTON_FLYINGM_FASTER_LINK 0x0503D4E0 /* Fallback throttle up button */ +#define DIBUTTON_FLYINGM_SLOWER_LINK 0x0503D4E8 /* Fallback throttle down button */ +#define DIBUTTON_FLYINGM_GLANCE_LEFT_LINK 0x0507C4E4 /* Fallback Glance Left button */ +#define DIBUTTON_FLYINGM_GLANCE_RIGHT_LINK 0x0507C4EC /* Fallback Glance Right button */ +#define DIBUTTON_FLYINGM_GLANCE_UP_LINK 0x0507C4E0 /* Fallback Glance Up button */ +#define DIBUTTON_FLYINGM_GLANCE_DOWN_LINK 0x0507C4E8 /* Fallback Glance Down button */ +#define DIBUTTON_FLYINGM_DEVICE 0x050044FE /* Show input device and controls */ +#define DIBUTTON_FLYINGM_PAUSE 0x050044FC /* Start / Pause / Restart game */ + +/*--- Flight Simulator - Combat Helicopter + Combat from helicopter is primary objective ---*/ +#define DIVIRTUAL_FLYING_HELICOPTER 0x06000000 +#define DIAXIS_FLYINGH_BANK 0x06008A01 /* Bank - Roll ship left / right */ +#define DIAXIS_FLYINGH_PITCH 0x06010A02 /* Pitch - Nose up / down */ +#define DIAXIS_FLYINGH_COLLECTIVE 0x06018A03 /* Collective - Blade pitch/power */ +#define DIBUTTON_FLYINGH_FIRE 0x06001401 /* Fire */ +#define DIBUTTON_FLYINGH_WEAPONS 0x06001402 /* Select next weapon */ +#define DIBUTTON_FLYINGH_TARGET 0x06001403 /* Selects next available target */ +#define DIBUTTON_FLYINGH_MENU 0x060004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_FLYINGH_GLANCE 0x06004601 /* Look around */ +#define DIAXIS_FLYINGH_TORQUE 0x06025A04 /* Torque - Rotate ship around left / right axis */ +#define DIAXIS_FLYINGH_THROTTLE 0x0603DA05 /* Throttle */ +#define DIBUTTON_FLYINGH_COUNTER 0x06005404 /* Activate counter measures */ +#define DIBUTTON_FLYINGH_VIEW 0x06006405 /* Cycle through view options */ +#define DIBUTTON_FLYINGH_GEAR 0x06006406 /* Gear up / down */ +#define DIBUTTON_FLYINGH_FIRESECONDARY 0x06004C07 /* Alternative fire button */ +#define DIBUTTON_FLYINGH_FASTER_LINK 0x0603DCE0 /* Fallback throttle up button */ +#define DIBUTTON_FLYINGH_SLOWER_LINK 0x0603DCE8 /* Fallback throttle down button */ +#define DIBUTTON_FLYINGH_GLANCE_LEFT_LINK 0x0607C4E4 /* Fallback Glance Left button */ +#define DIBUTTON_FLYINGH_GLANCE_RIGHT_LINK 0x0607C4EC /* Fallback Glance Right button */ +#define DIBUTTON_FLYINGH_GLANCE_UP_LINK 0x0607C4E0 /* Fallback Glance Up button */ +#define DIBUTTON_FLYINGH_GLANCE_DOWN_LINK 0x0607C4E8 /* Fallback Glance Down button */ +#define DIBUTTON_FLYINGH_DEVICE 0x060044FE /* Show input device and controls */ +#define DIBUTTON_FLYINGH_PAUSE 0x060044FC /* Start / Pause / Restart game */ + +/*--- Space Simulator - Combat + Space Simulator with weapons ---*/ +#define DIVIRTUAL_SPACESIM 0x07000000 +#define DIAXIS_SPACESIM_LATERAL 0x07008201 /* Move ship left / right */ +#define DIAXIS_SPACESIM_MOVE 0x07010202 /* Move ship forward/backward */ +#define DIAXIS_SPACESIM_THROTTLE 0x07038203 /* Throttle - Engine speed */ +#define DIBUTTON_SPACESIM_FIRE 0x07000401 /* Fire */ +#define DIBUTTON_SPACESIM_WEAPONS 0x07000402 /* Select next weapon */ +#define DIBUTTON_SPACESIM_TARGET 0x07000403 /* Selects next available target */ +#define DIBUTTON_SPACESIM_MENU 0x070004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_SPACESIM_GLANCE 0x07004601 /* Look around */ +#define DIAXIS_SPACESIM_CLIMB 0x0701C204 /* Climb - Pitch ship up/down */ +#define DIAXIS_SPACESIM_ROTATE 0x07024205 /* Rotate - Turn ship left/right */ +#define DIBUTTON_SPACESIM_VIEW 0x07004404 /* Cycle through view options */ +#define DIBUTTON_SPACESIM_DISPLAY 0x07004405 /* Select next dashboard / heads up display option */ +#define DIBUTTON_SPACESIM_RAISE 0x07004406 /* Raise ship while maintaining current pitch */ +#define DIBUTTON_SPACESIM_LOWER 0x07004407 /* Lower ship while maintaining current pitch */ +#define DIBUTTON_SPACESIM_GEAR 0x07004408 /* Gear up / down */ +#define DIBUTTON_SPACESIM_FIRESECONDARY 0x07004409 /* Alternative fire button */ +#define DIBUTTON_SPACESIM_LEFT_LINK 0x0700C4E4 /* Fallback move left button */ +#define DIBUTTON_SPACESIM_RIGHT_LINK 0x0700C4EC /* Fallback move right button */ +#define DIBUTTON_SPACESIM_FORWARD_LINK 0x070144E0 /* Fallback move forward button */ +#define DIBUTTON_SPACESIM_BACKWARD_LINK 0x070144E8 /* Fallback move backwards button */ +#define DIBUTTON_SPACESIM_FASTER_LINK 0x0703C4E0 /* Fallback throttle up button */ +#define DIBUTTON_SPACESIM_SLOWER_LINK 0x0703C4E8 /* Fallback throttle down button */ +#define DIBUTTON_SPACESIM_TURN_LEFT_LINK 0x070244E4 /* Fallback turn left button */ +#define DIBUTTON_SPACESIM_TURN_RIGHT_LINK 0x070244EC /* Fallback turn right button */ +#define DIBUTTON_SPACESIM_GLANCE_LEFT_LINK 0x0707C4E4 /* Fallback Glance Left button */ +#define DIBUTTON_SPACESIM_GLANCE_RIGHT_LINK 0x0707C4EC /* Fallback Glance Right button */ +#define DIBUTTON_SPACESIM_GLANCE_UP_LINK 0x0707C4E0 /* Fallback Glance Up button */ +#define DIBUTTON_SPACESIM_GLANCE_DOWN_LINK 0x0707C4E8 /* Fallback Glance Down button */ +#define DIBUTTON_SPACESIM_DEVICE 0x070044FE /* Show input device and controls */ +#define DIBUTTON_SPACESIM_PAUSE 0x070044FC /* Start / Pause / Restart game */ + +/*--- Fighting - First Person + Hand to Hand combat is primary objective ---*/ +#define DIVIRTUAL_FIGHTING_HAND2HAND 0x08000000 +#define DIAXIS_FIGHTINGH_LATERAL 0x08008201 /* Sidestep left/right */ +#define DIAXIS_FIGHTINGH_MOVE 0x08010202 /* Move forward/backward */ +#define DIBUTTON_FIGHTINGH_PUNCH 0x08000401 /* Punch */ +#define DIBUTTON_FIGHTINGH_KICK 0x08000402 /* Kick */ +#define DIBUTTON_FIGHTINGH_BLOCK 0x08000403 /* Block */ +#define DIBUTTON_FIGHTINGH_CROUCH 0x08000404 /* Crouch */ +#define DIBUTTON_FIGHTINGH_JUMP 0x08000405 /* Jump */ +#define DIBUTTON_FIGHTINGH_SPECIAL1 0x08000406 /* Apply first special move */ +#define DIBUTTON_FIGHTINGH_SPECIAL2 0x08000407 /* Apply second special move */ +#define DIBUTTON_FIGHTINGH_MENU 0x080004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_FIGHTINGH_SELECT 0x08004408 /* Select special move */ +#define DIHATSWITCH_FIGHTINGH_SLIDE 0x08004601 /* Look around */ +#define DIBUTTON_FIGHTINGH_DISPLAY 0x08004409 /* Shows next on-screen display option */ +#define DIAXIS_FIGHTINGH_ROTATE 0x08024203 /* Rotate - Turn body left/right */ +#define DIBUTTON_FIGHTINGH_DODGE 0x0800440A /* Dodge */ +#define DIBUTTON_FIGHTINGH_LEFT_LINK 0x0800C4E4 /* Fallback left sidestep button */ +#define DIBUTTON_FIGHTINGH_RIGHT_LINK 0x0800C4EC /* Fallback right sidestep button */ +#define DIBUTTON_FIGHTINGH_FORWARD_LINK 0x080144E0 /* Fallback forward button */ +#define DIBUTTON_FIGHTINGH_BACKWARD_LINK 0x080144E8 /* Fallback backward button */ +#define DIBUTTON_FIGHTINGH_DEVICE 0x080044FE /* Show input device and controls */ +#define DIBUTTON_FIGHTINGH_PAUSE 0x080044FC /* Start / Pause / Restart game */ + +/*--- Fighting - First Person Shooting + Navigation and combat are primary objectives ---*/ +#define DIVIRTUAL_FIGHTING_FPS 0x09000000 +#define DIAXIS_FPS_ROTATE 0x09008201 /* Rotate character left/right */ +#define DIAXIS_FPS_MOVE 0x09010202 /* Move forward/backward */ +#define DIBUTTON_FPS_FIRE 0x09000401 /* Fire */ +#define DIBUTTON_FPS_WEAPONS 0x09000402 /* Select next weapon */ +#define DIBUTTON_FPS_APPLY 0x09000403 /* Use item */ +#define DIBUTTON_FPS_SELECT 0x09000404 /* Select next inventory item */ +#define DIBUTTON_FPS_CROUCH 0x09000405 /* Crouch/ climb down/ swim down */ +#define DIBUTTON_FPS_JUMP 0x09000406 /* Jump/ climb up/ swim up */ +#define DIAXIS_FPS_LOOKUPDOWN 0x09018203 /* Look up / down */ +#define DIBUTTON_FPS_STRAFE 0x09000407 /* Enable strafing while active */ +#define DIBUTTON_FPS_MENU 0x090004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_FPS_GLANCE 0x09004601 /* Look around */ +#define DIBUTTON_FPS_DISPLAY 0x09004408 /* Shows next on-screen display option/ map */ +#define DIAXIS_FPS_SIDESTEP 0x09024204 /* Sidestep */ +#define DIBUTTON_FPS_DODGE 0x09004409 /* Dodge */ +#define DIBUTTON_FPS_GLANCEL 0x0900440A /* Glance Left */ +#define DIBUTTON_FPS_GLANCER 0x0900440B /* Glance Right */ +#define DIBUTTON_FPS_FIRESECONDARY 0x0900440C /* Alternative fire button */ +#define DIBUTTON_FPS_ROTATE_LEFT_LINK 0x0900C4E4 /* Fallback rotate left button */ +#define DIBUTTON_FPS_ROTATE_RIGHT_LINK 0x0900C4EC /* Fallback rotate right button */ +#define DIBUTTON_FPS_FORWARD_LINK 0x090144E0 /* Fallback forward button */ +#define DIBUTTON_FPS_BACKWARD_LINK 0x090144E8 /* Fallback backward button */ +#define DIBUTTON_FPS_GLANCE_UP_LINK 0x0901C4E0 /* Fallback look up button */ +#define DIBUTTON_FPS_GLANCE_DOWN_LINK 0x0901C4E8 /* Fallback look down button */ +#define DIBUTTON_FPS_STEP_LEFT_LINK 0x090244E4 /* Fallback step left button */ +#define DIBUTTON_FPS_STEP_RIGHT_LINK 0x090244EC /* Fallback step right button */ +#define DIBUTTON_FPS_DEVICE 0x090044FE /* Show input device and controls */ +#define DIBUTTON_FPS_PAUSE 0x090044FC /* Start / Pause / Restart game */ + +/*--- Fighting - Third Person action + Perspective of camera is behind the main character ---*/ +#define DIVIRTUAL_FIGHTING_THIRDPERSON 0x0A000000 +#define DIAXIS_TPS_TURN 0x0A020201 /* Turn left/right */ +#define DIAXIS_TPS_MOVE 0x0A010202 /* Move forward/backward */ +#define DIBUTTON_TPS_RUN 0x0A000401 /* Run or walk toggle switch */ +#define DIBUTTON_TPS_ACTION 0x0A000402 /* Action Button */ +#define DIBUTTON_TPS_SELECT 0x0A000403 /* Select next weapon */ +#define DIBUTTON_TPS_USE 0x0A000404 /* Use inventory item currently selected */ +#define DIBUTTON_TPS_JUMP 0x0A000405 /* Character Jumps */ +#define DIBUTTON_TPS_MENU 0x0A0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_TPS_GLANCE 0x0A004601 /* Look around */ +#define DIBUTTON_TPS_VIEW 0x0A004406 /* Select camera view */ +#define DIBUTTON_TPS_STEPLEFT 0x0A004407 /* Character takes a left step */ +#define DIBUTTON_TPS_STEPRIGHT 0x0A004408 /* Character takes a right step */ +#define DIAXIS_TPS_STEP 0x0A00C203 /* Character steps left/right */ +#define DIBUTTON_TPS_DODGE 0x0A004409 /* Character dodges or ducks */ +#define DIBUTTON_TPS_INVENTORY 0x0A00440A /* Cycle through inventory */ +#define DIBUTTON_TPS_TURN_LEFT_LINK 0x0A0244E4 /* Fallback turn left button */ +#define DIBUTTON_TPS_TURN_RIGHT_LINK 0x0A0244EC /* Fallback turn right button */ +#define DIBUTTON_TPS_FORWARD_LINK 0x0A0144E0 /* Fallback forward button */ +#define DIBUTTON_TPS_BACKWARD_LINK 0x0A0144E8 /* Fallback backward button */ +#define DIBUTTON_TPS_GLANCE_UP_LINK 0x0A07C4E0 /* Fallback look up button */ +#define DIBUTTON_TPS_GLANCE_DOWN_LINK 0x0A07C4E8 /* Fallback look down button */ +#define DIBUTTON_TPS_GLANCE_LEFT_LINK 0x0A07C4E4 /* Fallback glance up button */ +#define DIBUTTON_TPS_GLANCE_RIGHT_LINK 0x0A07C4EC /* Fallback glance right button */ +#define DIBUTTON_TPS_DEVICE 0x0A0044FE /* Show input device and controls */ +#define DIBUTTON_TPS_PAUSE 0x0A0044FC /* Start / Pause / Restart game */ + +/*--- Strategy - Role Playing + Navigation and problem solving are primary actions ---*/ +#define DIVIRTUAL_STRATEGY_ROLEPLAYING 0x0B000000 +#define DIAXIS_STRATEGYR_LATERAL 0x0B008201 /* sidestep - left/right */ +#define DIAXIS_STRATEGYR_MOVE 0x0B010202 /* move forward/backward */ +#define DIBUTTON_STRATEGYR_GET 0x0B000401 /* Acquire item */ +#define DIBUTTON_STRATEGYR_APPLY 0x0B000402 /* Use selected item */ +#define DIBUTTON_STRATEGYR_SELECT 0x0B000403 /* Select nextitem */ +#define DIBUTTON_STRATEGYR_ATTACK 0x0B000404 /* Attack */ +#define DIBUTTON_STRATEGYR_CAST 0x0B000405 /* Cast Spell */ +#define DIBUTTON_STRATEGYR_CROUCH 0x0B000406 /* Crouch */ +#define DIBUTTON_STRATEGYR_JUMP 0x0B000407 /* Jump */ +#define DIBUTTON_STRATEGYR_MENU 0x0B0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_STRATEGYR_GLANCE 0x0B004601 /* Look around */ +#define DIBUTTON_STRATEGYR_MAP 0x0B004408 /* Cycle through map options */ +#define DIBUTTON_STRATEGYR_DISPLAY 0x0B004409 /* Shows next on-screen display option */ +#define DIAXIS_STRATEGYR_ROTATE 0x0B024203 /* Turn body left/right */ +#define DIBUTTON_STRATEGYR_LEFT_LINK 0x0B00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_STRATEGYR_RIGHT_LINK 0x0B00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_STRATEGYR_FORWARD_LINK 0x0B0144E0 /* Fallback move forward button */ +#define DIBUTTON_STRATEGYR_BACK_LINK 0x0B0144E8 /* Fallback move backward button */ +#define DIBUTTON_STRATEGYR_ROTATE_LEFT_LINK 0x0B0244E4 /* Fallback turn body left button */ +#define DIBUTTON_STRATEGYR_ROTATE_RIGHT_LINK 0x0B0244EC /* Fallback turn body right button */ +#define DIBUTTON_STRATEGYR_DEVICE 0x0B0044FE /* Show input device and controls */ +#define DIBUTTON_STRATEGYR_PAUSE 0x0B0044FC /* Start / Pause / Restart game */ + +/*--- Strategy - Turn based + Navigation and problem solving are primary actions ---*/ +#define DIVIRTUAL_STRATEGY_TURN 0x0C000000 +#define DIAXIS_STRATEGYT_LATERAL 0x0C008201 /* Sidestep left/right */ +#define DIAXIS_STRATEGYT_MOVE 0x0C010202 /* Move forward/backwards */ +#define DIBUTTON_STRATEGYT_SELECT 0x0C000401 /* Select unit or object */ +#define DIBUTTON_STRATEGYT_INSTRUCT 0x0C000402 /* Cycle through instructions */ +#define DIBUTTON_STRATEGYT_APPLY 0x0C000403 /* Apply selected instruction */ +#define DIBUTTON_STRATEGYT_TEAM 0x0C000404 /* Select next team / cycle through all */ +#define DIBUTTON_STRATEGYT_TURN 0x0C000405 /* Indicate turn over */ +#define DIBUTTON_STRATEGYT_MENU 0x0C0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_STRATEGYT_ZOOM 0x0C004406 /* Zoom - in / out */ +#define DIBUTTON_STRATEGYT_MAP 0x0C004407 /* cycle through map options */ +#define DIBUTTON_STRATEGYT_DISPLAY 0x0C004408 /* shows next on-screen display options */ +#define DIBUTTON_STRATEGYT_LEFT_LINK 0x0C00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_STRATEGYT_RIGHT_LINK 0x0C00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_STRATEGYT_FORWARD_LINK 0x0C0144E0 /* Fallback move forward button */ +#define DIBUTTON_STRATEGYT_BACK_LINK 0x0C0144E8 /* Fallback move back button */ +#define DIBUTTON_STRATEGYT_DEVICE 0x0C0044FE /* Show input device and controls */ +#define DIBUTTON_STRATEGYT_PAUSE 0x0C0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Hunting + Hunting ---*/ +#define DIVIRTUAL_SPORTS_HUNTING 0x0D000000 +#define DIAXIS_HUNTING_LATERAL 0x0D008201 /* sidestep left/right */ +#define DIAXIS_HUNTING_MOVE 0x0D010202 /* move forward/backwards */ +#define DIBUTTON_HUNTING_FIRE 0x0D000401 /* Fire selected weapon */ +#define DIBUTTON_HUNTING_AIM 0x0D000402 /* Select aim/move */ +#define DIBUTTON_HUNTING_WEAPON 0x0D000403 /* Select next weapon */ +#define DIBUTTON_HUNTING_BINOCULAR 0x0D000404 /* Look through Binoculars */ +#define DIBUTTON_HUNTING_CALL 0x0D000405 /* Make animal call */ +#define DIBUTTON_HUNTING_MAP 0x0D000406 /* View Map */ +#define DIBUTTON_HUNTING_SPECIAL 0x0D000407 /* Special game operation */ +#define DIBUTTON_HUNTING_MENU 0x0D0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_HUNTING_GLANCE 0x0D004601 /* Look around */ +#define DIBUTTON_HUNTING_DISPLAY 0x0D004408 /* show next on-screen display option */ +#define DIAXIS_HUNTING_ROTATE 0x0D024203 /* Turn body left/right */ +#define DIBUTTON_HUNTING_CROUCH 0x0D004409 /* Crouch/ Climb / Swim down */ +#define DIBUTTON_HUNTING_JUMP 0x0D00440A /* Jump/ Climb up / Swim up */ +#define DIBUTTON_HUNTING_FIRESECONDARY 0x0D00440B /* Alternative fire button */ +#define DIBUTTON_HUNTING_LEFT_LINK 0x0D00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_HUNTING_RIGHT_LINK 0x0D00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_HUNTING_FORWARD_LINK 0x0D0144E0 /* Fallback move forward button */ +#define DIBUTTON_HUNTING_BACK_LINK 0x0D0144E8 /* Fallback move back button */ +#define DIBUTTON_HUNTING_ROTATE_LEFT_LINK 0x0D0244E4 /* Fallback turn body left button */ +#define DIBUTTON_HUNTING_ROTATE_RIGHT_LINK 0x0D0244EC /* Fallback turn body right button */ +#define DIBUTTON_HUNTING_DEVICE 0x0D0044FE /* Show input device and controls */ +#define DIBUTTON_HUNTING_PAUSE 0x0D0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Fishing + Catching Fish is primary objective ---*/ +#define DIVIRTUAL_SPORTS_FISHING 0x0E000000 +#define DIAXIS_FISHING_LATERAL 0x0E008201 /* sidestep left/right */ +#define DIAXIS_FISHING_MOVE 0x0E010202 /* move forward/backwards */ +#define DIBUTTON_FISHING_CAST 0x0E000401 /* Cast line */ +#define DIBUTTON_FISHING_TYPE 0x0E000402 /* Select cast type */ +#define DIBUTTON_FISHING_BINOCULAR 0x0E000403 /* Look through Binocular */ +#define DIBUTTON_FISHING_BAIT 0x0E000404 /* Select type of Bait */ +#define DIBUTTON_FISHING_MAP 0x0E000405 /* View Map */ +#define DIBUTTON_FISHING_MENU 0x0E0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_FISHING_GLANCE 0x0E004601 /* Look around */ +#define DIBUTTON_FISHING_DISPLAY 0x0E004406 /* Show next on-screen display option */ +#define DIAXIS_FISHING_ROTATE 0x0E024203 /* Turn character left / right */ +#define DIBUTTON_FISHING_CROUCH 0x0E004407 /* Crouch/ Climb / Swim down */ +#define DIBUTTON_FISHING_JUMP 0x0E004408 /* Jump/ Climb up / Swim up */ +#define DIBUTTON_FISHING_LEFT_LINK 0x0E00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_FISHING_RIGHT_LINK 0x0E00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_FISHING_FORWARD_LINK 0x0E0144E0 /* Fallback move forward button */ +#define DIBUTTON_FISHING_BACK_LINK 0x0E0144E8 /* Fallback move back button */ +#define DIBUTTON_FISHING_ROTATE_LEFT_LINK 0x0E0244E4 /* Fallback turn body left button */ +#define DIBUTTON_FISHING_ROTATE_RIGHT_LINK 0x0E0244EC /* Fallback turn body right button */ +#define DIBUTTON_FISHING_DEVICE 0x0E0044FE /* Show input device and controls */ +#define DIBUTTON_FISHING_PAUSE 0x0E0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Baseball - Batting + Batter control is primary objective ---*/ +#define DIVIRTUAL_SPORTS_BASEBALL_BAT 0x0F000000 +#define DIAXIS_BASEBALLB_LATERAL 0x0F008201 /* Aim left / right */ +#define DIAXIS_BASEBALLB_MOVE 0x0F010202 /* Aim up / down */ +#define DIBUTTON_BASEBALLB_SELECT 0x0F000401 /* cycle through swing options */ +#define DIBUTTON_BASEBALLB_NORMAL 0x0F000402 /* normal swing */ +#define DIBUTTON_BASEBALLB_POWER 0x0F000403 /* swing for the fence */ +#define DIBUTTON_BASEBALLB_BUNT 0x0F000404 /* bunt */ +#define DIBUTTON_BASEBALLB_STEAL 0x0F000405 /* Base runner attempts to steal a base */ +#define DIBUTTON_BASEBALLB_BURST 0x0F000406 /* Base runner invokes burst of speed */ +#define DIBUTTON_BASEBALLB_SLIDE 0x0F000407 /* Base runner slides into base */ +#define DIBUTTON_BASEBALLB_CONTACT 0x0F000408 /* Contact swing */ +#define DIBUTTON_BASEBALLB_MENU 0x0F0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_BASEBALLB_NOSTEAL 0x0F004409 /* Base runner goes back to a base */ +#define DIBUTTON_BASEBALLB_BOX 0x0F00440A /* Enter or exit batting box */ +#define DIBUTTON_BASEBALLB_LEFT_LINK 0x0F00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_BASEBALLB_RIGHT_LINK 0x0F00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_BASEBALLB_FORWARD_LINK 0x0F0144E0 /* Fallback move forward button */ +#define DIBUTTON_BASEBALLB_BACK_LINK 0x0F0144E8 /* Fallback move back button */ +#define DIBUTTON_BASEBALLB_DEVICE 0x0F0044FE /* Show input device and controls */ +#define DIBUTTON_BASEBALLB_PAUSE 0x0F0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Baseball - Pitching + Pitcher control is primary objective ---*/ +#define DIVIRTUAL_SPORTS_BASEBALL_PITCH 0x10000000 +#define DIAXIS_BASEBALLP_LATERAL 0x10008201 /* Aim left / right */ +#define DIAXIS_BASEBALLP_MOVE 0x10010202 /* Aim up / down */ +#define DIBUTTON_BASEBALLP_SELECT 0x10000401 /* cycle through pitch selections */ +#define DIBUTTON_BASEBALLP_PITCH 0x10000402 /* throw pitch */ +#define DIBUTTON_BASEBALLP_BASE 0x10000403 /* select base to throw to */ +#define DIBUTTON_BASEBALLP_THROW 0x10000404 /* throw to base */ +#define DIBUTTON_BASEBALLP_FAKE 0x10000405 /* Fake a throw to a base */ +#define DIBUTTON_BASEBALLP_MENU 0x100004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_BASEBALLP_WALK 0x10004406 /* Throw intentional walk / pitch out */ +#define DIBUTTON_BASEBALLP_LOOK 0x10004407 /* Look at runners on bases */ +#define DIBUTTON_BASEBALLP_LEFT_LINK 0x1000C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_BASEBALLP_RIGHT_LINK 0x1000C4EC /* Fallback sidestep right button */ +#define DIBUTTON_BASEBALLP_FORWARD_LINK 0x100144E0 /* Fallback move forward button */ +#define DIBUTTON_BASEBALLP_BACK_LINK 0x100144E8 /* Fallback move back button */ +#define DIBUTTON_BASEBALLP_DEVICE 0x100044FE /* Show input device and controls */ +#define DIBUTTON_BASEBALLP_PAUSE 0x100044FC /* Start / Pause / Restart game */ + +/*--- Sports - Baseball - Fielding + Fielder control is primary objective ---*/ +#define DIVIRTUAL_SPORTS_BASEBALL_FIELD 0x11000000 +#define DIAXIS_BASEBALLF_LATERAL 0x11008201 /* Aim left / right */ +#define DIAXIS_BASEBALLF_MOVE 0x11010202 /* Aim up / down */ +#define DIBUTTON_BASEBALLF_NEAREST 0x11000401 /* Switch to fielder nearest to the ball */ +#define DIBUTTON_BASEBALLF_THROW1 0x11000402 /* Make conservative throw */ +#define DIBUTTON_BASEBALLF_THROW2 0x11000403 /* Make aggressive throw */ +#define DIBUTTON_BASEBALLF_BURST 0x11000404 /* Invoke burst of speed */ +#define DIBUTTON_BASEBALLF_JUMP 0x11000405 /* Jump to catch ball */ +#define DIBUTTON_BASEBALLF_DIVE 0x11000406 /* Dive to catch ball */ +#define DIBUTTON_BASEBALLF_MENU 0x110004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_BASEBALLF_SHIFTIN 0x11004407 /* Shift the infield positioning */ +#define DIBUTTON_BASEBALLF_SHIFTOUT 0x11004408 /* Shift the outfield positioning */ +#define DIBUTTON_BASEBALLF_AIM_LEFT_LINK 0x1100C4E4 /* Fallback aim left button */ +#define DIBUTTON_BASEBALLF_AIM_RIGHT_LINK 0x1100C4EC /* Fallback aim right button */ +#define DIBUTTON_BASEBALLF_FORWARD_LINK 0x110144E0 /* Fallback move forward button */ +#define DIBUTTON_BASEBALLF_BACK_LINK 0x110144E8 /* Fallback move back button */ +#define DIBUTTON_BASEBALLF_DEVICE 0x110044FE /* Show input device and controls */ +#define DIBUTTON_BASEBALLF_PAUSE 0x110044FC /* Start / Pause / Restart game */ + +/*--- Sports - Basketball - Offense + Offense ---*/ +#define DIVIRTUAL_SPORTS_BASKETBALL_OFFENSE 0x12000000 +#define DIAXIS_BBALLO_LATERAL 0x12008201 /* left / right */ +#define DIAXIS_BBALLO_MOVE 0x12010202 /* up / down */ +#define DIBUTTON_BBALLO_SHOOT 0x12000401 /* shoot basket */ +#define DIBUTTON_BBALLO_DUNK 0x12000402 /* dunk basket */ +#define DIBUTTON_BBALLO_PASS 0x12000403 /* throw pass */ +#define DIBUTTON_BBALLO_FAKE 0x12000404 /* fake shot or pass */ +#define DIBUTTON_BBALLO_SPECIAL 0x12000405 /* apply special move */ +#define DIBUTTON_BBALLO_PLAYER 0x12000406 /* select next player */ +#define DIBUTTON_BBALLO_BURST 0x12000407 /* invoke burst */ +#define DIBUTTON_BBALLO_CALL 0x12000408 /* call for ball / pass to me */ +#define DIBUTTON_BBALLO_MENU 0x120004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_BBALLO_GLANCE 0x12004601 /* scroll view */ +#define DIBUTTON_BBALLO_SCREEN 0x12004409 /* Call for screen */ +#define DIBUTTON_BBALLO_PLAY 0x1200440A /* Call for specific offensive play */ +#define DIBUTTON_BBALLO_JAB 0x1200440B /* Initiate fake drive to basket */ +#define DIBUTTON_BBALLO_POST 0x1200440C /* Perform post move */ +#define DIBUTTON_BBALLO_TIMEOUT 0x1200440D /* Time Out */ +#define DIBUTTON_BBALLO_SUBSTITUTE 0x1200440E /* substitute one player for another */ +#define DIBUTTON_BBALLO_LEFT_LINK 0x1200C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_BBALLO_RIGHT_LINK 0x1200C4EC /* Fallback sidestep right button */ +#define DIBUTTON_BBALLO_FORWARD_LINK 0x120144E0 /* Fallback move forward button */ +#define DIBUTTON_BBALLO_BACK_LINK 0x120144E8 /* Fallback move back button */ +#define DIBUTTON_BBALLO_DEVICE 0x120044FE /* Show input device and controls */ +#define DIBUTTON_BBALLO_PAUSE 0x120044FC /* Start / Pause / Restart game */ + +/*--- Sports - Basketball - Defense + Defense ---*/ +#define DIVIRTUAL_SPORTS_BASKETBALL_DEFENSE 0x13000000 +#define DIAXIS_BBALLD_LATERAL 0x13008201 /* left / right */ +#define DIAXIS_BBALLD_MOVE 0x13010202 /* up / down */ +#define DIBUTTON_BBALLD_JUMP 0x13000401 /* jump to block shot */ +#define DIBUTTON_BBALLD_STEAL 0x13000402 /* attempt to steal ball */ +#define DIBUTTON_BBALLD_FAKE 0x13000403 /* fake block or steal */ +#define DIBUTTON_BBALLD_SPECIAL 0x13000404 /* apply special move */ +#define DIBUTTON_BBALLD_PLAYER 0x13000405 /* select next player */ +#define DIBUTTON_BBALLD_BURST 0x13000406 /* invoke burst */ +#define DIBUTTON_BBALLD_PLAY 0x13000407 /* call for specific defensive play */ +#define DIBUTTON_BBALLD_MENU 0x130004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_BBALLD_GLANCE 0x13004601 /* scroll view */ +#define DIBUTTON_BBALLD_TIMEOUT 0x13004408 /* Time Out */ +#define DIBUTTON_BBALLD_SUBSTITUTE 0x13004409 /* substitute one player for another */ +#define DIBUTTON_BBALLD_LEFT_LINK 0x1300C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_BBALLD_RIGHT_LINK 0x1300C4EC /* Fallback sidestep right button */ +#define DIBUTTON_BBALLD_FORWARD_LINK 0x130144E0 /* Fallback move forward button */ +#define DIBUTTON_BBALLD_BACK_LINK 0x130144E8 /* Fallback move back button */ +#define DIBUTTON_BBALLD_DEVICE 0x130044FE /* Show input device and controls */ +#define DIBUTTON_BBALLD_PAUSE 0x130044FC /* Start / Pause / Restart game */ + +/*--- Sports - Football - Play + Play selection ---*/ +#define DIVIRTUAL_SPORTS_FOOTBALL_FIELD 0x14000000 +#define DIBUTTON_FOOTBALLP_PLAY 0x14000401 /* cycle through available plays */ +#define DIBUTTON_FOOTBALLP_SELECT 0x14000402 /* select play */ +#define DIBUTTON_FOOTBALLP_HELP 0x14000403 /* Bring up pop-up help */ +#define DIBUTTON_FOOTBALLP_MENU 0x140004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_FOOTBALLP_DEVICE 0x140044FE /* Show input device and controls */ +#define DIBUTTON_FOOTBALLP_PAUSE 0x140044FC /* Start / Pause / Restart game */ + +/*--- Sports - Football - QB + Offense: Quarterback / Kicker ---*/ +#define DIVIRTUAL_SPORTS_FOOTBALL_QBCK 0x15000000 +#define DIAXIS_FOOTBALLQ_LATERAL 0x15008201 /* Move / Aim: left / right */ +#define DIAXIS_FOOTBALLQ_MOVE 0x15010202 /* Move / Aim: up / down */ +#define DIBUTTON_FOOTBALLQ_SELECT 0x15000401 /* Select */ +#define DIBUTTON_FOOTBALLQ_SNAP 0x15000402 /* snap ball - start play */ +#define DIBUTTON_FOOTBALLQ_JUMP 0x15000403 /* jump over defender */ +#define DIBUTTON_FOOTBALLQ_SLIDE 0x15000404 /* Dive/Slide */ +#define DIBUTTON_FOOTBALLQ_PASS 0x15000405 /* throws pass to receiver */ +#define DIBUTTON_FOOTBALLQ_FAKE 0x15000406 /* pump fake pass or fake kick */ +#define DIBUTTON_FOOTBALLQ_MENU 0x150004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_FOOTBALLQ_FAKESNAP 0x15004407 /* Fake snap */ +#define DIBUTTON_FOOTBALLQ_MOTION 0x15004408 /* Send receivers in motion */ +#define DIBUTTON_FOOTBALLQ_AUDIBLE 0x15004409 /* Change offensive play at line of scrimmage */ +#define DIBUTTON_FOOTBALLQ_LEFT_LINK 0x1500C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_FOOTBALLQ_RIGHT_LINK 0x1500C4EC /* Fallback sidestep right button */ +#define DIBUTTON_FOOTBALLQ_FORWARD_LINK 0x150144E0 /* Fallback move forward button */ +#define DIBUTTON_FOOTBALLQ_BACK_LINK 0x150144E8 /* Fallback move back button */ +#define DIBUTTON_FOOTBALLQ_DEVICE 0x150044FE /* Show input device and controls */ +#define DIBUTTON_FOOTBALLQ_PAUSE 0x150044FC /* Start / Pause / Restart game */ + +/*--- Sports - Football - Offense + Offense - Runner ---*/ +#define DIVIRTUAL_SPORTS_FOOTBALL_OFFENSE 0x16000000 +#define DIAXIS_FOOTBALLO_LATERAL 0x16008201 /* Move / Aim: left / right */ +#define DIAXIS_FOOTBALLO_MOVE 0x16010202 /* Move / Aim: up / down */ +#define DIBUTTON_FOOTBALLO_JUMP 0x16000401 /* jump or hurdle over defender */ +#define DIBUTTON_FOOTBALLO_LEFTARM 0x16000402 /* holds out left arm */ +#define DIBUTTON_FOOTBALLO_RIGHTARM 0x16000403 /* holds out right arm */ +#define DIBUTTON_FOOTBALLO_THROW 0x16000404 /* throw pass or lateral ball to another runner */ +#define DIBUTTON_FOOTBALLO_SPIN 0x16000405 /* Spin to avoid defenders */ +#define DIBUTTON_FOOTBALLO_MENU 0x160004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_FOOTBALLO_JUKE 0x16004406 /* Use special move to avoid defenders */ +#define DIBUTTON_FOOTBALLO_SHOULDER 0x16004407 /* Lower shoulder to run over defenders */ +#define DIBUTTON_FOOTBALLO_TURBO 0x16004408 /* Speed burst past defenders */ +#define DIBUTTON_FOOTBALLO_DIVE 0x16004409 /* Dive over defenders */ +#define DIBUTTON_FOOTBALLO_ZOOM 0x1600440A /* Zoom view in / out */ +#define DIBUTTON_FOOTBALLO_SUBSTITUTE 0x1600440B /* substitute one player for another */ +#define DIBUTTON_FOOTBALLO_LEFT_LINK 0x1600C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_FOOTBALLO_RIGHT_LINK 0x1600C4EC /* Fallback sidestep right button */ +#define DIBUTTON_FOOTBALLO_FORWARD_LINK 0x160144E0 /* Fallback move forward button */ +#define DIBUTTON_FOOTBALLO_BACK_LINK 0x160144E8 /* Fallback move back button */ +#define DIBUTTON_FOOTBALLO_DEVICE 0x160044FE /* Show input device and controls */ +#define DIBUTTON_FOOTBALLO_PAUSE 0x160044FC /* Start / Pause / Restart game */ + +/*--- Sports - Football - Defense + Defense ---*/ +#define DIVIRTUAL_SPORTS_FOOTBALL_DEFENSE 0x17000000 +#define DIAXIS_FOOTBALLD_LATERAL 0x17008201 /* Move / Aim: left / right */ +#define DIAXIS_FOOTBALLD_MOVE 0x17010202 /* Move / Aim: up / down */ +#define DIBUTTON_FOOTBALLD_PLAY 0x17000401 /* cycle through available plays */ +#define DIBUTTON_FOOTBALLD_SELECT 0x17000402 /* select player closest to the ball */ +#define DIBUTTON_FOOTBALLD_JUMP 0x17000403 /* jump to intercept or block */ +#define DIBUTTON_FOOTBALLD_TACKLE 0x17000404 /* tackler runner */ +#define DIBUTTON_FOOTBALLD_FAKE 0x17000405 /* hold down to fake tackle or intercept */ +#define DIBUTTON_FOOTBALLD_SUPERTACKLE 0x17000406 /* Initiate special tackle */ +#define DIBUTTON_FOOTBALLD_MENU 0x170004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_FOOTBALLD_SPIN 0x17004407 /* Spin to beat offensive line */ +#define DIBUTTON_FOOTBALLD_SWIM 0x17004408 /* Swim to beat the offensive line */ +#define DIBUTTON_FOOTBALLD_BULLRUSH 0x17004409 /* Bull rush the offensive line */ +#define DIBUTTON_FOOTBALLD_RIP 0x1700440A /* Rip the offensive line */ +#define DIBUTTON_FOOTBALLD_AUDIBLE 0x1700440B /* Change defensive play at the line of scrimmage */ +#define DIBUTTON_FOOTBALLD_ZOOM 0x1700440C /* Zoom view in / out */ +#define DIBUTTON_FOOTBALLD_SUBSTITUTE 0x1700440D /* substitute one player for another */ +#define DIBUTTON_FOOTBALLD_LEFT_LINK 0x1700C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_FOOTBALLD_RIGHT_LINK 0x1700C4EC /* Fallback sidestep right button */ +#define DIBUTTON_FOOTBALLD_FORWARD_LINK 0x170144E0 /* Fallback move forward button */ +#define DIBUTTON_FOOTBALLD_BACK_LINK 0x170144E8 /* Fallback move back button */ +#define DIBUTTON_FOOTBALLD_DEVICE 0x170044FE /* Show input device and controls */ +#define DIBUTTON_FOOTBALLD_PAUSE 0x170044FC /* Start / Pause / Restart game */ + +/*--- Sports - Golf + ---*/ +#define DIVIRTUAL_SPORTS_GOLF 0x18000000 +#define DIAXIS_GOLF_LATERAL 0x18008201 /* Move / Aim: left / right */ +#define DIAXIS_GOLF_MOVE 0x18010202 /* Move / Aim: up / down */ +#define DIBUTTON_GOLF_SWING 0x18000401 /* swing club */ +#define DIBUTTON_GOLF_SELECT 0x18000402 /* cycle between: club / swing strength / ball arc / ball spin */ +#define DIBUTTON_GOLF_UP 0x18000403 /* increase selection */ +#define DIBUTTON_GOLF_DOWN 0x18000404 /* decrease selection */ +#define DIBUTTON_GOLF_TERRAIN 0x18000405 /* shows terrain detail */ +#define DIBUTTON_GOLF_FLYBY 0x18000406 /* view the hole via a flyby */ +#define DIBUTTON_GOLF_MENU 0x180004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_GOLF_SCROLL 0x18004601 /* scroll view */ +#define DIBUTTON_GOLF_ZOOM 0x18004407 /* Zoom view in / out */ +#define DIBUTTON_GOLF_TIMEOUT 0x18004408 /* Call for time out */ +#define DIBUTTON_GOLF_SUBSTITUTE 0x18004409 /* substitute one player for another */ +#define DIBUTTON_GOLF_LEFT_LINK 0x1800C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_GOLF_RIGHT_LINK 0x1800C4EC /* Fallback sidestep right button */ +#define DIBUTTON_GOLF_FORWARD_LINK 0x180144E0 /* Fallback move forward button */ +#define DIBUTTON_GOLF_BACK_LINK 0x180144E8 /* Fallback move back button */ +#define DIBUTTON_GOLF_DEVICE 0x180044FE /* Show input device and controls */ +#define DIBUTTON_GOLF_PAUSE 0x180044FC /* Start / Pause / Restart game */ + +/*--- Sports - Hockey - Offense + Offense ---*/ +#define DIVIRTUAL_SPORTS_HOCKEY_OFFENSE 0x19000000 +#define DIAXIS_HOCKEYO_LATERAL 0x19008201 /* Move / Aim: left / right */ +#define DIAXIS_HOCKEYO_MOVE 0x19010202 /* Move / Aim: up / down */ +#define DIBUTTON_HOCKEYO_SHOOT 0x19000401 /* Shoot */ +#define DIBUTTON_HOCKEYO_PASS 0x19000402 /* pass the puck */ +#define DIBUTTON_HOCKEYO_BURST 0x19000403 /* invoke speed burst */ +#define DIBUTTON_HOCKEYO_SPECIAL 0x19000404 /* invoke special move */ +#define DIBUTTON_HOCKEYO_FAKE 0x19000405 /* hold down to fake pass or kick */ +#define DIBUTTON_HOCKEYO_MENU 0x190004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_HOCKEYO_SCROLL 0x19004601 /* scroll view */ +#define DIBUTTON_HOCKEYO_ZOOM 0x19004406 /* Zoom view in / out */ +#define DIBUTTON_HOCKEYO_STRATEGY 0x19004407 /* Invoke coaching menu for strategy help */ +#define DIBUTTON_HOCKEYO_TIMEOUT 0x19004408 /* Call for time out */ +#define DIBUTTON_HOCKEYO_SUBSTITUTE 0x19004409 /* substitute one player for another */ +#define DIBUTTON_HOCKEYO_LEFT_LINK 0x1900C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_HOCKEYO_RIGHT_LINK 0x1900C4EC /* Fallback sidestep right button */ +#define DIBUTTON_HOCKEYO_FORWARD_LINK 0x190144E0 /* Fallback move forward button */ +#define DIBUTTON_HOCKEYO_BACK_LINK 0x190144E8 /* Fallback move back button */ +#define DIBUTTON_HOCKEYO_DEVICE 0x190044FE /* Show input device and controls */ +#define DIBUTTON_HOCKEYO_PAUSE 0x190044FC /* Start / Pause / Restart game */ + +/*--- Sports - Hockey - Defense + Defense ---*/ +#define DIVIRTUAL_SPORTS_HOCKEY_DEFENSE 0x1A000000 +#define DIAXIS_HOCKEYD_LATERAL 0x1A008201 /* Move / Aim: left / right */ +#define DIAXIS_HOCKEYD_MOVE 0x1A010202 /* Move / Aim: up / down */ +#define DIBUTTON_HOCKEYD_PLAYER 0x1A000401 /* control player closest to the puck */ +#define DIBUTTON_HOCKEYD_STEAL 0x1A000402 /* attempt steal */ +#define DIBUTTON_HOCKEYD_BURST 0x1A000403 /* speed burst or body check */ +#define DIBUTTON_HOCKEYD_BLOCK 0x1A000404 /* block puck */ +#define DIBUTTON_HOCKEYD_FAKE 0x1A000405 /* hold down to fake tackle or intercept */ +#define DIBUTTON_HOCKEYD_MENU 0x1A0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_HOCKEYD_SCROLL 0x1A004601 /* scroll view */ +#define DIBUTTON_HOCKEYD_ZOOM 0x1A004406 /* Zoom view in / out */ +#define DIBUTTON_HOCKEYD_STRATEGY 0x1A004407 /* Invoke coaching menu for strategy help */ +#define DIBUTTON_HOCKEYD_TIMEOUT 0x1A004408 /* Call for time out */ +#define DIBUTTON_HOCKEYD_SUBSTITUTE 0x1A004409 /* substitute one player for another */ +#define DIBUTTON_HOCKEYD_LEFT_LINK 0x1A00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_HOCKEYD_RIGHT_LINK 0x1A00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_HOCKEYD_FORWARD_LINK 0x1A0144E0 /* Fallback move forward button */ +#define DIBUTTON_HOCKEYD_BACK_LINK 0x1A0144E8 /* Fallback move back button */ +#define DIBUTTON_HOCKEYD_DEVICE 0x1A0044FE /* Show input device and controls */ +#define DIBUTTON_HOCKEYD_PAUSE 0x1A0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Hockey - Goalie + Goal tending ---*/ +#define DIVIRTUAL_SPORTS_HOCKEY_GOALIE 0x1B000000 +#define DIAXIS_HOCKEYG_LATERAL 0x1B008201 /* Move / Aim: left / right */ +#define DIAXIS_HOCKEYG_MOVE 0x1B010202 /* Move / Aim: up / down */ +#define DIBUTTON_HOCKEYG_PASS 0x1B000401 /* pass puck */ +#define DIBUTTON_HOCKEYG_POKE 0x1B000402 /* poke / check / hack */ +#define DIBUTTON_HOCKEYG_STEAL 0x1B000403 /* attempt steal */ +#define DIBUTTON_HOCKEYG_BLOCK 0x1B000404 /* block puck */ +#define DIBUTTON_HOCKEYG_MENU 0x1B0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_HOCKEYG_SCROLL 0x1B004601 /* scroll view */ +#define DIBUTTON_HOCKEYG_ZOOM 0x1B004405 /* Zoom view in / out */ +#define DIBUTTON_HOCKEYG_STRATEGY 0x1B004406 /* Invoke coaching menu for strategy help */ +#define DIBUTTON_HOCKEYG_TIMEOUT 0x1B004407 /* Call for time out */ +#define DIBUTTON_HOCKEYG_SUBSTITUTE 0x1B004408 /* substitute one player for another */ +#define DIBUTTON_HOCKEYG_LEFT_LINK 0x1B00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_HOCKEYG_RIGHT_LINK 0x1B00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_HOCKEYG_FORWARD_LINK 0x1B0144E0 /* Fallback move forward button */ +#define DIBUTTON_HOCKEYG_BACK_LINK 0x1B0144E8 /* Fallback move back button */ +#define DIBUTTON_HOCKEYG_DEVICE 0x1B0044FE /* Show input device and controls */ +#define DIBUTTON_HOCKEYG_PAUSE 0x1B0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Mountain Biking + ---*/ +#define DIVIRTUAL_SPORTS_BIKING_MOUNTAIN 0x1C000000 +#define DIAXIS_BIKINGM_TURN 0x1C008201 /* left / right */ +#define DIAXIS_BIKINGM_PEDAL 0x1C010202 /* Pedal faster / slower / brake */ +#define DIBUTTON_BIKINGM_JUMP 0x1C000401 /* jump over obstacle */ +#define DIBUTTON_BIKINGM_CAMERA 0x1C000402 /* switch camera view */ +#define DIBUTTON_BIKINGM_SPECIAL1 0x1C000403 /* perform first special move */ +#define DIBUTTON_BIKINGM_SELECT 0x1C000404 /* Select */ +#define DIBUTTON_BIKINGM_SPECIAL2 0x1C000405 /* perform second special move */ +#define DIBUTTON_BIKINGM_MENU 0x1C0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_BIKINGM_SCROLL 0x1C004601 /* scroll view */ +#define DIBUTTON_BIKINGM_ZOOM 0x1C004406 /* Zoom view in / out */ +#define DIAXIS_BIKINGM_BRAKE 0x1C044203 /* Brake axis */ +#define DIBUTTON_BIKINGM_LEFT_LINK 0x1C00C4E4 /* Fallback turn left button */ +#define DIBUTTON_BIKINGM_RIGHT_LINK 0x1C00C4EC /* Fallback turn right button */ +#define DIBUTTON_BIKINGM_FASTER_LINK 0x1C0144E0 /* Fallback pedal faster button */ +#define DIBUTTON_BIKINGM_SLOWER_LINK 0x1C0144E8 /* Fallback pedal slower button */ +#define DIBUTTON_BIKINGM_BRAKE_BUTTON_LINK 0x1C0444E8 /* Fallback brake button */ +#define DIBUTTON_BIKINGM_DEVICE 0x1C0044FE /* Show input device and controls */ +#define DIBUTTON_BIKINGM_PAUSE 0x1C0044FC /* Start / Pause / Restart game */ + +/*--- Sports: Skiing / Snowboarding / Skateboarding + ---*/ +#define DIVIRTUAL_SPORTS_SKIING 0x1D000000 +#define DIAXIS_SKIING_TURN 0x1D008201 /* left / right */ +#define DIAXIS_SKIING_SPEED 0x1D010202 /* faster / slower */ +#define DIBUTTON_SKIING_JUMP 0x1D000401 /* Jump */ +#define DIBUTTON_SKIING_CROUCH 0x1D000402 /* crouch down */ +#define DIBUTTON_SKIING_CAMERA 0x1D000403 /* switch camera view */ +#define DIBUTTON_SKIING_SPECIAL1 0x1D000404 /* perform first special move */ +#define DIBUTTON_SKIING_SELECT 0x1D000405 /* Select */ +#define DIBUTTON_SKIING_SPECIAL2 0x1D000406 /* perform second special move */ +#define DIBUTTON_SKIING_MENU 0x1D0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_SKIING_GLANCE 0x1D004601 /* scroll view */ +#define DIBUTTON_SKIING_ZOOM 0x1D004407 /* Zoom view in / out */ +#define DIBUTTON_SKIING_LEFT_LINK 0x1D00C4E4 /* Fallback turn left button */ +#define DIBUTTON_SKIING_RIGHT_LINK 0x1D00C4EC /* Fallback turn right button */ +#define DIBUTTON_SKIING_FASTER_LINK 0x1D0144E0 /* Fallback increase speed button */ +#define DIBUTTON_SKIING_SLOWER_LINK 0x1D0144E8 /* Fallback decrease speed button */ +#define DIBUTTON_SKIING_DEVICE 0x1D0044FE /* Show input device and controls */ +#define DIBUTTON_SKIING_PAUSE 0x1D0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Soccer - Offense + Offense ---*/ +#define DIVIRTUAL_SPORTS_SOCCER_OFFENSE 0x1E000000 +#define DIAXIS_SOCCERO_LATERAL 0x1E008201 /* Move / Aim: left / right */ +#define DIAXIS_SOCCERO_MOVE 0x1E010202 /* Move / Aim: up / down */ +#define DIAXIS_SOCCERO_BEND 0x1E018203 /* Bend to soccer shot/pass */ +#define DIBUTTON_SOCCERO_SHOOT 0x1E000401 /* Shoot the ball */ +#define DIBUTTON_SOCCERO_PASS 0x1E000402 /* Pass */ +#define DIBUTTON_SOCCERO_FAKE 0x1E000403 /* Fake */ +#define DIBUTTON_SOCCERO_PLAYER 0x1E000404 /* Select next player */ +#define DIBUTTON_SOCCERO_SPECIAL1 0x1E000405 /* Apply special move */ +#define DIBUTTON_SOCCERO_SELECT 0x1E000406 /* Select special move */ +#define DIBUTTON_SOCCERO_MENU 0x1E0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_SOCCERO_GLANCE 0x1E004601 /* scroll view */ +#define DIBUTTON_SOCCERO_SUBSTITUTE 0x1E004407 /* Substitute one player for another */ +#define DIBUTTON_SOCCERO_SHOOTLOW 0x1E004408 /* Shoot the ball low */ +#define DIBUTTON_SOCCERO_SHOOTHIGH 0x1E004409 /* Shoot the ball high */ +#define DIBUTTON_SOCCERO_PASSTHRU 0x1E00440A /* Make a thru pass */ +#define DIBUTTON_SOCCERO_SPRINT 0x1E00440B /* Sprint / turbo boost */ +#define DIBUTTON_SOCCERO_CONTROL 0x1E00440C /* Obtain control of the ball */ +#define DIBUTTON_SOCCERO_HEAD 0x1E00440D /* Attempt to head the ball */ +#define DIBUTTON_SOCCERO_LEFT_LINK 0x1E00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_SOCCERO_RIGHT_LINK 0x1E00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_SOCCERO_FORWARD_LINK 0x1E0144E0 /* Fallback move forward button */ +#define DIBUTTON_SOCCERO_BACK_LINK 0x1E0144E8 /* Fallback move back button */ +#define DIBUTTON_SOCCERO_DEVICE 0x1E0044FE /* Show input device and controls */ +#define DIBUTTON_SOCCERO_PAUSE 0x1E0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Soccer - Defense + Defense ---*/ +#define DIVIRTUAL_SPORTS_SOCCER_DEFENSE 0x1F000000 +#define DIAXIS_SOCCERD_LATERAL 0x1F008201 /* Move / Aim: left / right */ +#define DIAXIS_SOCCERD_MOVE 0x1F010202 /* Move / Aim: up / down */ +#define DIBUTTON_SOCCERD_BLOCK 0x1F000401 /* Attempt to block shot */ +#define DIBUTTON_SOCCERD_STEAL 0x1F000402 /* Attempt to steal ball */ +#define DIBUTTON_SOCCERD_FAKE 0x1F000403 /* Fake a block or a steal */ +#define DIBUTTON_SOCCERD_PLAYER 0x1F000404 /* Select next player */ +#define DIBUTTON_SOCCERD_SPECIAL 0x1F000405 /* Apply special move */ +#define DIBUTTON_SOCCERD_SELECT 0x1F000406 /* Select special move */ +#define DIBUTTON_SOCCERD_SLIDE 0x1F000407 /* Attempt a slide tackle */ +#define DIBUTTON_SOCCERD_MENU 0x1F0004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_SOCCERD_GLANCE 0x1F004601 /* scroll view */ +#define DIBUTTON_SOCCERD_FOUL 0x1F004408 /* Initiate a foul / hard-foul */ +#define DIBUTTON_SOCCERD_HEAD 0x1F004409 /* Attempt a Header */ +#define DIBUTTON_SOCCERD_CLEAR 0x1F00440A /* Attempt to clear the ball down the field */ +#define DIBUTTON_SOCCERD_GOALIECHARGE 0x1F00440B /* Make the goalie charge out of the box */ +#define DIBUTTON_SOCCERD_SUBSTITUTE 0x1F00440C /* Substitute one player for another */ +#define DIBUTTON_SOCCERD_LEFT_LINK 0x1F00C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_SOCCERD_RIGHT_LINK 0x1F00C4EC /* Fallback sidestep right button */ +#define DIBUTTON_SOCCERD_FORWARD_LINK 0x1F0144E0 /* Fallback move forward button */ +#define DIBUTTON_SOCCERD_BACK_LINK 0x1F0144E8 /* Fallback move back button */ +#define DIBUTTON_SOCCERD_DEVICE 0x1F0044FE /* Show input device and controls */ +#define DIBUTTON_SOCCERD_PAUSE 0x1F0044FC /* Start / Pause / Restart game */ + +/*--- Sports - Racquet + Tennis - Table-Tennis - Squash ---*/ +#define DIVIRTUAL_SPORTS_RACQUET 0x20000000 +#define DIAXIS_RACQUET_LATERAL 0x20008201 /* Move / Aim: left / right */ +#define DIAXIS_RACQUET_MOVE 0x20010202 /* Move / Aim: up / down */ +#define DIBUTTON_RACQUET_SWING 0x20000401 /* Swing racquet */ +#define DIBUTTON_RACQUET_BACKSWING 0x20000402 /* Swing backhand */ +#define DIBUTTON_RACQUET_SMASH 0x20000403 /* Smash shot */ +#define DIBUTTON_RACQUET_SPECIAL 0x20000404 /* Special shot */ +#define DIBUTTON_RACQUET_SELECT 0x20000405 /* Select special shot */ +#define DIBUTTON_RACQUET_MENU 0x200004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_RACQUET_GLANCE 0x20004601 /* scroll view */ +#define DIBUTTON_RACQUET_TIMEOUT 0x20004406 /* Call for time out */ +#define DIBUTTON_RACQUET_SUBSTITUTE 0x20004407 /* Substitute one player for another */ +#define DIBUTTON_RACQUET_LEFT_LINK 0x2000C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_RACQUET_RIGHT_LINK 0x2000C4EC /* Fallback sidestep right button */ +#define DIBUTTON_RACQUET_FORWARD_LINK 0x200144E0 /* Fallback move forward button */ +#define DIBUTTON_RACQUET_BACK_LINK 0x200144E8 /* Fallback move back button */ +#define DIBUTTON_RACQUET_DEVICE 0x200044FE /* Show input device and controls */ +#define DIBUTTON_RACQUET_PAUSE 0x200044FC /* Start / Pause / Restart game */ + +/*--- Arcade- 2D + Side to Side movement ---*/ +#define DIVIRTUAL_ARCADE_SIDE2SIDE 0x21000000 +#define DIAXIS_ARCADES_LATERAL 0x21008201 /* left / right */ +#define DIAXIS_ARCADES_MOVE 0x21010202 /* up / down */ +#define DIBUTTON_ARCADES_THROW 0x21000401 /* throw object */ +#define DIBUTTON_ARCADES_CARRY 0x21000402 /* carry object */ +#define DIBUTTON_ARCADES_ATTACK 0x21000403 /* attack */ +#define DIBUTTON_ARCADES_SPECIAL 0x21000404 /* apply special move */ +#define DIBUTTON_ARCADES_SELECT 0x21000405 /* select special move */ +#define DIBUTTON_ARCADES_MENU 0x210004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_ARCADES_VIEW 0x21004601 /* scroll view left / right / up / down */ +#define DIBUTTON_ARCADES_LEFT_LINK 0x2100C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_ARCADES_RIGHT_LINK 0x2100C4EC /* Fallback sidestep right button */ +#define DIBUTTON_ARCADES_FORWARD_LINK 0x210144E0 /* Fallback move forward button */ +#define DIBUTTON_ARCADES_BACK_LINK 0x210144E8 /* Fallback move back button */ +#define DIBUTTON_ARCADES_VIEW_UP_LINK 0x2107C4E0 /* Fallback scroll view up button */ +#define DIBUTTON_ARCADES_VIEW_DOWN_LINK 0x2107C4E8 /* Fallback scroll view down button */ +#define DIBUTTON_ARCADES_VIEW_LEFT_LINK 0x2107C4E4 /* Fallback scroll view left button */ +#define DIBUTTON_ARCADES_VIEW_RIGHT_LINK 0x2107C4EC /* Fallback scroll view right button */ +#define DIBUTTON_ARCADES_DEVICE 0x210044FE /* Show input device and controls */ +#define DIBUTTON_ARCADES_PAUSE 0x210044FC /* Start / Pause / Restart game */ + +/*--- Arcade - Platform Game + Character moves around on screen ---*/ +#define DIVIRTUAL_ARCADE_PLATFORM 0x22000000 +#define DIAXIS_ARCADEP_LATERAL 0x22008201 /* Left / right */ +#define DIAXIS_ARCADEP_MOVE 0x22010202 /* Up / down */ +#define DIBUTTON_ARCADEP_JUMP 0x22000401 /* Jump */ +#define DIBUTTON_ARCADEP_FIRE 0x22000402 /* Fire */ +#define DIBUTTON_ARCADEP_CROUCH 0x22000403 /* Crouch */ +#define DIBUTTON_ARCADEP_SPECIAL 0x22000404 /* Apply special move */ +#define DIBUTTON_ARCADEP_SELECT 0x22000405 /* Select special move */ +#define DIBUTTON_ARCADEP_MENU 0x220004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_ARCADEP_VIEW 0x22004601 /* Scroll view */ +#define DIBUTTON_ARCADEP_FIRESECONDARY 0x22004406 /* Alternative fire button */ +#define DIBUTTON_ARCADEP_LEFT_LINK 0x2200C4E4 /* Fallback sidestep left button */ +#define DIBUTTON_ARCADEP_RIGHT_LINK 0x2200C4EC /* Fallback sidestep right button */ +#define DIBUTTON_ARCADEP_FORWARD_LINK 0x220144E0 /* Fallback move forward button */ +#define DIBUTTON_ARCADEP_BACK_LINK 0x220144E8 /* Fallback move back button */ +#define DIBUTTON_ARCADEP_VIEW_UP_LINK 0x2207C4E0 /* Fallback scroll view up button */ +#define DIBUTTON_ARCADEP_VIEW_DOWN_LINK 0x2207C4E8 /* Fallback scroll view down button */ +#define DIBUTTON_ARCADEP_VIEW_LEFT_LINK 0x2207C4E4 /* Fallback scroll view left button */ +#define DIBUTTON_ARCADEP_VIEW_RIGHT_LINK 0x2207C4EC /* Fallback scroll view right button */ +#define DIBUTTON_ARCADEP_DEVICE 0x220044FE /* Show input device and controls */ +#define DIBUTTON_ARCADEP_PAUSE 0x220044FC /* Start / Pause / Restart game */ + +/*--- CAD - 2D Object Control + Controls to select and move objects in 2D ---*/ +#define DIVIRTUAL_CAD_2DCONTROL 0x23000000 +#define DIAXIS_2DCONTROL_LATERAL 0x23008201 /* Move view left / right */ +#define DIAXIS_2DCONTROL_MOVE 0x23010202 /* Move view up / down */ +#define DIAXIS_2DCONTROL_INOUT 0x23018203 /* Zoom - in / out */ +#define DIBUTTON_2DCONTROL_SELECT 0x23000401 /* Select Object */ +#define DIBUTTON_2DCONTROL_SPECIAL1 0x23000402 /* Do first special operation */ +#define DIBUTTON_2DCONTROL_SPECIAL 0x23000403 /* Select special operation */ +#define DIBUTTON_2DCONTROL_SPECIAL2 0x23000404 /* Do second special operation */ +#define DIBUTTON_2DCONTROL_MENU 0x230004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_2DCONTROL_HATSWITCH 0x23004601 /* Hat switch */ +#define DIAXIS_2DCONTROL_ROTATEZ 0x23024204 /* Rotate view clockwise / counterclockwise */ +#define DIBUTTON_2DCONTROL_DISPLAY 0x23004405 /* Shows next on-screen display options */ +#define DIBUTTON_2DCONTROL_DEVICE 0x230044FE /* Show input device and controls */ +#define DIBUTTON_2DCONTROL_PAUSE 0x230044FC /* Start / Pause / Restart game */ + +/*--- CAD - 3D object control + Controls to select and move objects within a 3D environment ---*/ +#define DIVIRTUAL_CAD_3DCONTROL 0x24000000 +#define DIAXIS_3DCONTROL_LATERAL 0x24008201 /* Move view left / right */ +#define DIAXIS_3DCONTROL_MOVE 0x24010202 /* Move view up / down */ +#define DIAXIS_3DCONTROL_INOUT 0x24018203 /* Zoom - in / out */ +#define DIBUTTON_3DCONTROL_SELECT 0x24000401 /* Select Object */ +#define DIBUTTON_3DCONTROL_SPECIAL1 0x24000402 /* Do first special operation */ +#define DIBUTTON_3DCONTROL_SPECIAL 0x24000403 /* Select special operation */ +#define DIBUTTON_3DCONTROL_SPECIAL2 0x24000404 /* Do second special operation */ +#define DIBUTTON_3DCONTROL_MENU 0x240004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_3DCONTROL_HATSWITCH 0x24004601 /* Hat switch */ +#define DIAXIS_3DCONTROL_ROTATEX 0x24034204 /* Rotate view forward or up / backward or down */ +#define DIAXIS_3DCONTROL_ROTATEY 0x2402C205 /* Rotate view clockwise / counterclockwise */ +#define DIAXIS_3DCONTROL_ROTATEZ 0x24024206 /* Rotate view left / right */ +#define DIBUTTON_3DCONTROL_DISPLAY 0x24004405 /* Show next on-screen display options */ +#define DIBUTTON_3DCONTROL_DEVICE 0x240044FE /* Show input device and controls */ +#define DIBUTTON_3DCONTROL_PAUSE 0x240044FC /* Start / Pause / Restart game */ + +/*--- CAD - 3D Navigation - Fly through + Controls for 3D modeling ---*/ +#define DIVIRTUAL_CAD_FLYBY 0x25000000 +#define DIAXIS_CADF_LATERAL 0x25008201 /* move view left / right */ +#define DIAXIS_CADF_MOVE 0x25010202 /* move view up / down */ +#define DIAXIS_CADF_INOUT 0x25018203 /* in / out */ +#define DIBUTTON_CADF_SELECT 0x25000401 /* Select Object */ +#define DIBUTTON_CADF_SPECIAL1 0x25000402 /* do first special operation */ +#define DIBUTTON_CADF_SPECIAL 0x25000403 /* Select special operation */ +#define DIBUTTON_CADF_SPECIAL2 0x25000404 /* do second special operation */ +#define DIBUTTON_CADF_MENU 0x250004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_CADF_HATSWITCH 0x25004601 /* Hat switch */ +#define DIAXIS_CADF_ROTATEX 0x25034204 /* Rotate view forward or up / backward or down */ +#define DIAXIS_CADF_ROTATEY 0x2502C205 /* Rotate view clockwise / counterclockwise */ +#define DIAXIS_CADF_ROTATEZ 0x25024206 /* Rotate view left / right */ +#define DIBUTTON_CADF_DISPLAY 0x25004405 /* shows next on-screen display options */ +#define DIBUTTON_CADF_DEVICE 0x250044FE /* Show input device and controls */ +#define DIBUTTON_CADF_PAUSE 0x250044FC /* Start / Pause / Restart game */ + +/*--- CAD - 3D Model Control + Controls for 3D modeling ---*/ +#define DIVIRTUAL_CAD_MODEL 0x26000000 +#define DIAXIS_CADM_LATERAL 0x26008201 /* move view left / right */ +#define DIAXIS_CADM_MOVE 0x26010202 /* move view up / down */ +#define DIAXIS_CADM_INOUT 0x26018203 /* in / out */ +#define DIBUTTON_CADM_SELECT 0x26000401 /* Select Object */ +#define DIBUTTON_CADM_SPECIAL1 0x26000402 /* do first special operation */ +#define DIBUTTON_CADM_SPECIAL 0x26000403 /* Select special operation */ +#define DIBUTTON_CADM_SPECIAL2 0x26000404 /* do second special operation */ +#define DIBUTTON_CADM_MENU 0x260004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIHATSWITCH_CADM_HATSWITCH 0x26004601 /* Hat switch */ +#define DIAXIS_CADM_ROTATEX 0x26034204 /* Rotate view forward or up / backward or down */ +#define DIAXIS_CADM_ROTATEY 0x2602C205 /* Rotate view clockwise / counterclockwise */ +#define DIAXIS_CADM_ROTATEZ 0x26024206 /* Rotate view left / right */ +#define DIBUTTON_CADM_DISPLAY 0x26004405 /* shows next on-screen display options */ +#define DIBUTTON_CADM_DEVICE 0x260044FE /* Show input device and controls */ +#define DIBUTTON_CADM_PAUSE 0x260044FC /* Start / Pause / Restart game */ + +/*--- Control - Media Equipment + Remote ---*/ +#define DIVIRTUAL_REMOTE_CONTROL 0x27000000 +#define DIAXIS_REMOTE_SLIDER 0x27050201 /* Slider for adjustment: volume / color / bass / etc */ +#define DIBUTTON_REMOTE_MUTE 0x27000401 /* Set volume on current device to zero */ +#define DIBUTTON_REMOTE_SELECT 0x27000402 /* Next/previous: channel/ track / chapter / picture / station */ +#define DIBUTTON_REMOTE_PLAY 0x27002403 /* Start or pause entertainment on current device */ +#define DIBUTTON_REMOTE_CUE 0x27002404 /* Move through current media */ +#define DIBUTTON_REMOTE_REVIEW 0x27002405 /* Move through current media */ +#define DIBUTTON_REMOTE_CHANGE 0x27002406 /* Select next device */ +#define DIBUTTON_REMOTE_RECORD 0x27002407 /* Start recording the current media */ +#define DIBUTTON_REMOTE_MENU 0x270004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIAXIS_REMOTE_SLIDER2 0x27054202 /* Slider for adjustment: volume */ +#define DIBUTTON_REMOTE_TV 0x27005C08 /* Select TV */ +#define DIBUTTON_REMOTE_CABLE 0x27005C09 /* Select cable box */ +#define DIBUTTON_REMOTE_CD 0x27005C0A /* Select CD player */ +#define DIBUTTON_REMOTE_VCR 0x27005C0B /* Select VCR */ +#define DIBUTTON_REMOTE_TUNER 0x27005C0C /* Select tuner */ +#define DIBUTTON_REMOTE_DVD 0x27005C0D /* Select DVD player */ +#define DIBUTTON_REMOTE_ADJUST 0x27005C0E /* Enter device adjustment menu */ +#define DIBUTTON_REMOTE_DIGIT0 0x2700540F /* Digit 0 */ +#define DIBUTTON_REMOTE_DIGIT1 0x27005410 /* Digit 1 */ +#define DIBUTTON_REMOTE_DIGIT2 0x27005411 /* Digit 2 */ +#define DIBUTTON_REMOTE_DIGIT3 0x27005412 /* Digit 3 */ +#define DIBUTTON_REMOTE_DIGIT4 0x27005413 /* Digit 4 */ +#define DIBUTTON_REMOTE_DIGIT5 0x27005414 /* Digit 5 */ +#define DIBUTTON_REMOTE_DIGIT6 0x27005415 /* Digit 6 */ +#define DIBUTTON_REMOTE_DIGIT7 0x27005416 /* Digit 7 */ +#define DIBUTTON_REMOTE_DIGIT8 0x27005417 /* Digit 8 */ +#define DIBUTTON_REMOTE_DIGIT9 0x27005418 /* Digit 9 */ +#define DIBUTTON_REMOTE_DEVICE 0x270044FE /* Show input device and controls */ +#define DIBUTTON_REMOTE_PAUSE 0x270044FC /* Start / Pause / Restart game */ + +/*--- Control- Web + Help or Browser ---*/ +#define DIVIRTUAL_BROWSER_CONTROL 0x28000000 +#define DIAXIS_BROWSER_LATERAL 0x28008201 /* Move on screen pointer */ +#define DIAXIS_BROWSER_MOVE 0x28010202 /* Move on screen pointer */ +#define DIBUTTON_BROWSER_SELECT 0x28000401 /* Select current item */ +#define DIAXIS_BROWSER_VIEW 0x28018203 /* Move view up/down */ +#define DIBUTTON_BROWSER_REFRESH 0x28000402 /* Refresh */ +#define DIBUTTON_BROWSER_MENU 0x280004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_BROWSER_SEARCH 0x28004403 /* Use search tool */ +#define DIBUTTON_BROWSER_STOP 0x28004404 /* Cease current update */ +#define DIBUTTON_BROWSER_HOME 0x28004405 /* Go directly to "home" location */ +#define DIBUTTON_BROWSER_FAVORITES 0x28004406 /* Mark current site as favorite */ +#define DIBUTTON_BROWSER_NEXT 0x28004407 /* Select Next page */ +#define DIBUTTON_BROWSER_PREVIOUS 0x28004408 /* Select Previous page */ +#define DIBUTTON_BROWSER_HISTORY 0x28004409 /* Show/Hide History */ +#define DIBUTTON_BROWSER_PRINT 0x2800440A /* Print current page */ +#define DIBUTTON_BROWSER_DEVICE 0x280044FE /* Show input device and controls */ +#define DIBUTTON_BROWSER_PAUSE 0x280044FC /* Start / Pause / Restart game */ + +/*--- Driving Simulator - Giant Walking Robot + Walking tank with weapons ---*/ +#define DIVIRTUAL_DRIVING_MECHA 0x29000000 +#define DIAXIS_MECHA_STEER 0x29008201 /* Turns mecha left/right */ +#define DIAXIS_MECHA_TORSO 0x29010202 /* Tilts torso forward/backward */ +#define DIAXIS_MECHA_ROTATE 0x29020203 /* Turns torso left/right */ +#define DIAXIS_MECHA_THROTTLE 0x29038204 /* Engine Speed */ +#define DIBUTTON_MECHA_FIRE 0x29000401 /* Fire */ +#define DIBUTTON_MECHA_WEAPONS 0x29000402 /* Select next weapon group */ +#define DIBUTTON_MECHA_TARGET 0x29000403 /* Select closest enemy available target */ +#define DIBUTTON_MECHA_REVERSE 0x29000404 /* Toggles throttle in/out of reverse */ +#define DIBUTTON_MECHA_ZOOM 0x29000405 /* Zoom in/out targeting reticule */ +#define DIBUTTON_MECHA_JUMP 0x29000406 /* Fires jump jets */ +#define DIBUTTON_MECHA_MENU 0x290004FD /* Show menu options */ +/*--- Priority 2 controls ---*/ + +#define DIBUTTON_MECHA_CENTER 0x29004407 /* Center torso to legs */ +#define DIHATSWITCH_MECHA_GLANCE 0x29004601 /* Look around */ +#define DIBUTTON_MECHA_VIEW 0x29004408 /* Cycle through view options */ +#define DIBUTTON_MECHA_FIRESECONDARY 0x29004409 /* Alternative fire button */ +#define DIBUTTON_MECHA_LEFT_LINK 0x2900C4E4 /* Fallback steer left button */ +#define DIBUTTON_MECHA_RIGHT_LINK 0x2900C4EC /* Fallback steer right button */ +#define DIBUTTON_MECHA_FORWARD_LINK 0x290144E0 /* Fallback tilt torso forward button */ +#define DIBUTTON_MECHA_BACK_LINK 0x290144E8 /* Fallback tilt toroso backward button */ +#define DIBUTTON_MECHA_ROTATE_LEFT_LINK 0x290244E4 /* Fallback rotate toroso right button */ +#define DIBUTTON_MECHA_ROTATE_RIGHT_LINK 0x290244EC /* Fallback rotate torso left button */ +#define DIBUTTON_MECHA_FASTER_LINK 0x2903C4E0 /* Fallback increase engine speed */ +#define DIBUTTON_MECHA_SLOWER_LINK 0x2903C4E8 /* Fallback decrease engine speed */ +#define DIBUTTON_MECHA_DEVICE 0x290044FE /* Show input device and controls */ +#define DIBUTTON_MECHA_PAUSE 0x290044FC /* Start / Pause / Restart game */ + +/* + * "ANY" semantics can be used as a last resort to get mappings for actions + * that match nothing in the chosen virtual genre. These semantics will be + * mapped at a lower priority that virtual genre semantics. Also, hardware + * vendors will not be able to provide sensible mappings for these unless + * they provide application specific mappings. + */ +#define DIAXIS_ANY_X_1 0xFF00C201 +#define DIAXIS_ANY_X_2 0xFF00C202 +#define DIAXIS_ANY_Y_1 0xFF014201 +#define DIAXIS_ANY_Y_2 0xFF014202 +#define DIAXIS_ANY_Z_1 0xFF01C201 +#define DIAXIS_ANY_Z_2 0xFF01C202 +#define DIAXIS_ANY_R_1 0xFF024201 +#define DIAXIS_ANY_R_2 0xFF024202 +#define DIAXIS_ANY_U_1 0xFF02C201 +#define DIAXIS_ANY_U_2 0xFF02C202 +#define DIAXIS_ANY_V_1 0xFF034201 +#define DIAXIS_ANY_V_2 0xFF034202 +#define DIAXIS_ANY_A_1 0xFF03C201 +#define DIAXIS_ANY_A_2 0xFF03C202 +#define DIAXIS_ANY_B_1 0xFF044201 +#define DIAXIS_ANY_B_2 0xFF044202 +#define DIAXIS_ANY_C_1 0xFF04C201 +#define DIAXIS_ANY_C_2 0xFF04C202 +#define DIAXIS_ANY_S_1 0xFF054201 +#define DIAXIS_ANY_S_2 0xFF054202 + +#define DIAXIS_ANY_1 0xFF004201 +#define DIAXIS_ANY_2 0xFF004202 +#define DIAXIS_ANY_3 0xFF004203 +#define DIAXIS_ANY_4 0xFF004204 + +#define DIPOV_ANY_1 0xFF004601 +#define DIPOV_ANY_2 0xFF004602 +#define DIPOV_ANY_3 0xFF004603 +#define DIPOV_ANY_4 0xFF004604 + +#define DIBUTTON_ANY(instance) ( 0xFF004400 | instance ) + + +#ifdef __cplusplus +}; +#endif + +#endif /* __DINPUT_INCLUDED__ */ + +/**************************************************************************** + * + * Definitions for non-IDirectInput (VJoyD) features defined more recently + * than the current sdk files + * + ****************************************************************************/ + +#ifdef _INC_MMSYSTEM +#ifndef MMNOJOY + +#ifndef __VJOYDX_INCLUDED__ +#define __VJOYDX_INCLUDED__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Flag to indicate that the dwReserved2 field of the JOYINFOEX structure + * contains mini-driver specific data to be passed by VJoyD to the mini- + * driver instead of doing a poll. + */ +#define JOY_PASSDRIVERDATA 0x10000000l + +/* + * Informs the joystick driver that the configuration has been changed + * and should be reloaded from the registery. + * dwFlags is reserved and should be set to zero + */ +WINMMAPI MMRESULT WINAPI joyConfigChanged( DWORD dwFlags ); + +#ifndef DIJ_RINGZERO +/* + * Invoke the joystick control panel directly, using the passed window handle + * as the parent of the dialog. This API is only supported for compatibility + * purposes; new applications should use the RunControlPanel method of a + * device interface for a game controller. + * The API is called by using the function pointer returned by + * GetProcAddress( hCPL, TEXT("ShowJoyCPL") ) where hCPL is a HMODULE returned + * by LoadLibrary( TEXT("joy.cpl") ). The typedef is provided to allow + * declaration and casting of an appropriately typed variable. + */ +void WINAPI ShowJoyCPL( HWND hWnd ); +typedef void (WINAPI* LPFNSHOWJOYCPL)( HWND hWnd ); +#endif /* DIJ_RINGZERO */ + + +/* + * Hardware Setting indicating that the device is a headtracker + */ +#define JOY_HWS_ISHEADTRACKER 0x02000000l + +/* + * Hardware Setting indicating that the VxD is used to replace + * the standard analog polling + */ +#define JOY_HWS_ISGAMEPORTDRIVER 0x04000000l + +/* + * Hardware Setting indicating that the driver needs a standard + * gameport in order to communicate with the device. + */ +#define JOY_HWS_ISANALOGPORTDRIVER 0x08000000l + +/* + * Hardware Setting indicating that VJoyD should not load this + * driver, it will be loaded externally and will register with + * VJoyD of it's own accord. + */ +#define JOY_HWS_AUTOLOAD 0x10000000l + +/* + * Hardware Setting indicating that the driver acquires any + * resources needed without needing a devnode through VJoyD. + */ +#define JOY_HWS_NODEVNODE 0x20000000l + + +/* + * Hardware Setting indicating that the device is a gameport bus + */ +#define JOY_HWS_ISGAMEPORTBUS 0x80000000l +#define JOY_HWS_GAMEPORTBUSBUSY 0x00000001l + +/* + * Usage Setting indicating that the settings are volatile and + * should be removed if still present on a reboot. + */ +#define JOY_US_VOLATILE 0x00000008L + +#ifdef __cplusplus +}; +#endif + +#endif /* __VJOYDX_INCLUDED__ */ + +#endif /* not MMNOJOY */ +#endif /* _INC_MMSYSTEM */ + +/**************************************************************************** + * + * Definitions for non-IDirectInput (VJoyD) features defined more recently + * than the current ddk files + * + ****************************************************************************/ + +#ifndef DIJ_RINGZERO + +#ifdef _INC_MMDDK +#ifndef MMNOJOYDEV + +#ifndef __VJOYDXD_INCLUDED__ +#define __VJOYDXD_INCLUDED__ +/* + * Poll type in which the do_other field of the JOYOEMPOLLDATA + * structure contains mini-driver specific data passed from an app. + */ +#define JOY_OEMPOLL_PASSDRIVERDATA 7 + +#endif /* __VJOYDXD_INCLUDED__ */ + +#endif /* not MMNOJOYDEV */ +#endif /* _INC_MMDDK */ + +#endif /* DIJ_RINGZERO */ + diff --git a/dxsdk/Include/dinputd.h b/dxsdk/Include/dinputd.h new file mode 100644 index 0000000..f534353 --- /dev/null +++ b/dxsdk/Include/dinputd.h @@ -0,0 +1,755 @@ +/**************************************************************************** + * + * Copyright (C) 1995-2000 Microsoft Corporation. All Rights Reserved. + * + * File: dinputd.h + * Content: DirectInput include file for device driver implementors + * + ****************************************************************************/ +#ifndef __DINPUTD_INCLUDED__ +#define __DINPUTD_INCLUDED__ + +#ifndef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0800 +#pragma message(__FILE__ ": DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800") +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * + * Interfaces + * + ****************************************************************************/ + +#ifndef DIJ_RINGZERO + +DEFINE_GUID(IID_IDirectInputEffectDriver, 0x02538130,0x898F,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35); +DEFINE_GUID(IID_IDirectInputJoyConfig, 0x1DE12AB1,0xC9F5,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(IID_IDirectInputPIDDriver, 0xEEC6993A,0xB3FD,0x11D2,0xA9,0x16,0x00,0xC0,0x4F,0xB9,0x86,0x38); + +DEFINE_GUID(IID_IDirectInputJoyConfig8, 0xeb0d7dfa,0x1990,0x4f27,0xb4,0xd6,0xed,0xf2,0xee,0xc4,0xa4,0x4c); + +#endif /* DIJ_RINGZERO */ + + +/**************************************************************************** + * + * IDirectInputEffectDriver + * + ****************************************************************************/ + +typedef struct DIOBJECTATTRIBUTES { + DWORD dwFlags; + WORD wUsagePage; + WORD wUsage; +} DIOBJECTATTRIBUTES, *LPDIOBJECTATTRIBUTES; +typedef const DIOBJECTATTRIBUTES *LPCDIOBJECTATTRIBUTES; + +typedef struct DIFFOBJECTATTRIBUTES { + DWORD dwFFMaxForce; + DWORD dwFFForceResolution; +} DIFFOBJECTATTRIBUTES, *LPDIFFOBJECTATTRIBUTES; +typedef const DIFFOBJECTATTRIBUTES *LPCDIFFOBJECTATTRIBUTES; + +typedef struct DIOBJECTCALIBRATION { + LONG lMin; + LONG lCenter; + LONG lMax; +} DIOBJECTCALIBRATION, *LPDIOBJECTCALIBRATION; +typedef const DIOBJECTCALIBRATION *LPCDIOBJECTCALIBRATION; + +typedef struct DIPOVCALIBRATION { + LONG lMin[5]; + LONG lMax[5]; +} DIPOVCALIBRATION, *LPDIPOVCALIBRATION; +typedef const DIPOVCALIBRATION *LPCDIPOVCALIBRATION; + +typedef struct DIEFFECTATTRIBUTES { + DWORD dwEffectId; + DWORD dwEffType; + DWORD dwStaticParams; + DWORD dwDynamicParams; + DWORD dwCoords; +} DIEFFECTATTRIBUTES, *LPDIEFFECTATTRIBUTES; +typedef const DIEFFECTATTRIBUTES *LPCDIEFFECTATTRIBUTES; + +typedef struct DIFFDEVICEATTRIBUTES { + DWORD dwFlags; + DWORD dwFFSamplePeriod; + DWORD dwFFMinTimeResolution; +} DIFFDEVICEATTRIBUTES, *LPDIFFDEVICEATTRIBUTES; +typedef const DIFFDEVICEATTRIBUTES *LPCDIFFDEVICEATTRIBUTES; + +typedef struct DIDRIVERVERSIONS { + DWORD dwSize; + DWORD dwFirmwareRevision; + DWORD dwHardwareRevision; + DWORD dwFFDriverVersion; +} DIDRIVERVERSIONS, *LPDIDRIVERVERSIONS; +typedef const DIDRIVERVERSIONS *LPCDIDRIVERVERSIONS; + +typedef struct DIDEVICESTATE { + DWORD dwSize; + DWORD dwState; + DWORD dwLoad; +} DIDEVICESTATE, *LPDIDEVICESTATE; + +#define DEV_STS_EFFECT_RUNNING DIEGES_PLAYING + +#ifndef DIJ_RINGZERO + +typedef struct DIHIDFFINITINFO { + DWORD dwSize; + LPWSTR pwszDeviceInterface; + GUID GuidInstance; +} DIHIDFFINITINFO, *LPDIHIDFFINITINFO; + +#undef INTERFACE +#define INTERFACE IDirectInputEffectDriver + +DECLARE_INTERFACE_(IDirectInputEffectDriver, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputEffectDriver methods ***/ + STDMETHOD(DeviceID)(THIS_ DWORD,DWORD,DWORD,DWORD,LPVOID) PURE; + STDMETHOD(GetVersions)(THIS_ LPDIDRIVERVERSIONS) PURE; + STDMETHOD(Escape)(THIS_ DWORD,DWORD,LPDIEFFESCAPE) PURE; + STDMETHOD(SetGain)(THIS_ DWORD,DWORD) PURE; + STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD,DWORD) PURE; + STDMETHOD(GetForceFeedbackState)(THIS_ DWORD,LPDIDEVICESTATE) PURE; + STDMETHOD(DownloadEffect)(THIS_ DWORD,DWORD,LPDWORD,LPCDIEFFECT,DWORD) PURE; + STDMETHOD(DestroyEffect)(THIS_ DWORD,DWORD) PURE; + STDMETHOD(StartEffect)(THIS_ DWORD,DWORD,DWORD,DWORD) PURE; + STDMETHOD(StopEffect)(THIS_ DWORD,DWORD) PURE; + STDMETHOD(GetEffectStatus)(THIS_ DWORD,DWORD,LPDWORD) PURE; +}; + +typedef struct IDirectInputEffectDriver *LPDIRECTINPUTEFFECTDRIVER; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputEffectDriver_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputEffectDriver_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputEffectDriver_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputEffectDriver_DeviceID(p,a,b,c,d,e) (p)->lpVtbl->DeviceID(p,a,b,c,d,e) +#define IDirectInputEffectDriver_GetVersions(p,a) (p)->lpVtbl->GetVersions(p,a) +#define IDirectInputEffectDriver_Escape(p,a,b,c) (p)->lpVtbl->Escape(p,a,b,c) +#define IDirectInputEffectDriver_SetGain(p,a,b) (p)->lpVtbl->SetGain(p,a,b) +#define IDirectInputEffectDriver_SendForceFeedbackCommand(p,a,b) (p)->lpVtbl->SendForceFeedbackCommand(p,a,b) +#define IDirectInputEffectDriver_GetForceFeedbackState(p,a,b) (p)->lpVtbl->GetForceFeedbackState(p,a,b) +#define IDirectInputEffectDriver_DownloadEffect(p,a,b,c,d,e) (p)->lpVtbl->DownloadEffect(p,a,b,c,d,e) +#define IDirectInputEffectDriver_DestroyEffect(p,a,b) (p)->lpVtbl->DestroyEffect(p,a,b) +#define IDirectInputEffectDriver_StartEffect(p,a,b,c,d) (p)->lpVtbl->StartEffect(p,a,b,c,d) +#define IDirectInputEffectDriver_StopEffect(p,a,b) (p)->lpVtbl->StopEffect(p,a,b) +#define IDirectInputEffectDriver_GetEffectStatus(p,a,b,c) (p)->lpVtbl->GetEffectStatus(p,a,b,c) +#else +#define IDirectInputEffectDriver_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputEffectDriver_AddRef(p) (p)->AddRef() +#define IDirectInputEffectDriver_Release(p) (p)->Release() +#define IDirectInputEffectDriver_DeviceID(p,a,b,c,d,e) (p)->DeviceID(a,b,c,d,e) +#define IDirectInputEffectDriver_GetVersions(p,a) (p)->GetVersions(a) +#define IDirectInputEffectDriver_Escape(p,a,b,c) (p)->Escape(a,b,c) +#define IDirectInputEffectDriver_SetGain(p,a,b) (p)->SetGain(a,b) +#define IDirectInputEffectDriver_SendForceFeedbackCommand(p,a,b) (p)->SendForceFeedbackCommand(a,b) +#define IDirectInputEffectDriver_GetForceFeedbackState(p,a,b) (p)->GetForceFeedbackState(a,b) +#define IDirectInputEffectDriver_DownloadEffect(p,a,b,c,d,e) (p)->DownloadEffect(a,b,c,d,e) +#define IDirectInputEffectDriver_DestroyEffect(p,a,b) (p)->DestroyEffect(a,b) +#define IDirectInputEffectDriver_StartEffect(p,a,b,c,d) (p)->StartEffect(a,b,c,d) +#define IDirectInputEffectDriver_StopEffect(p,a,b) (p)->StopEffect(a,b) +#define IDirectInputEffectDriver_GetEffectStatus(p,a,b,c) (p)->GetEffectStatus(a,b,c) +#endif + + +#endif /* DIJ_RINGZERO */ + + +/**************************************************************************** + * + * IDirectInputJoyConfig + * + ****************************************************************************/ + +/**************************************************************************** + * + * Definitions copied from the DDK + * + ****************************************************************************/ + +#ifndef JOY_HW_NONE + +/* pre-defined joystick types */ +#define JOY_HW_NONE 0 +#define JOY_HW_CUSTOM 1 +#define JOY_HW_2A_2B_GENERIC 2 +#define JOY_HW_2A_4B_GENERIC 3 +#define JOY_HW_2B_GAMEPAD 4 +#define JOY_HW_2B_FLIGHTYOKE 5 +#define JOY_HW_2B_FLIGHTYOKETHROTTLE 6 +#define JOY_HW_3A_2B_GENERIC 7 +#define JOY_HW_3A_4B_GENERIC 8 +#define JOY_HW_4B_GAMEPAD 9 +#define JOY_HW_4B_FLIGHTYOKE 10 +#define JOY_HW_4B_FLIGHTYOKETHROTTLE 11 +#define JOY_HW_TWO_2A_2B_WITH_Y 12 +#define JOY_HW_LASTENTRY 13 + + +/* calibration flags */ +#define JOY_ISCAL_XY 0x00000001l /* XY are calibrated */ +#define JOY_ISCAL_Z 0x00000002l /* Z is calibrated */ +#define JOY_ISCAL_R 0x00000004l /* R is calibrated */ +#define JOY_ISCAL_U 0x00000008l /* U is calibrated */ +#define JOY_ISCAL_V 0x00000010l /* V is calibrated */ +#define JOY_ISCAL_POV 0x00000020l /* POV is calibrated */ + +/* point of view constants */ +#define JOY_POV_NUMDIRS 4 +#define JOY_POVVAL_FORWARD 0 +#define JOY_POVVAL_BACKWARD 1 +#define JOY_POVVAL_LEFT 2 +#define JOY_POVVAL_RIGHT 3 + +/* Specific settings for joystick hardware */ +#define JOY_HWS_HASZ 0x00000001l /* has Z info? */ +#define JOY_HWS_HASPOV 0x00000002l /* point of view hat present */ +#define JOY_HWS_POVISBUTTONCOMBOS 0x00000004l /* pov done through combo of buttons */ +#define JOY_HWS_POVISPOLL 0x00000008l /* pov done through polling */ +#define JOY_HWS_ISYOKE 0x00000010l /* joystick is a flight yoke */ +#define JOY_HWS_ISGAMEPAD 0x00000020l /* joystick is a game pad */ +#define JOY_HWS_ISCARCTRL 0x00000040l /* joystick is a car controller */ +/* X defaults to J1 X axis */ +#define JOY_HWS_XISJ1Y 0x00000080l /* X is on J1 Y axis */ +#define JOY_HWS_XISJ2X 0x00000100l /* X is on J2 X axis */ +#define JOY_HWS_XISJ2Y 0x00000200l /* X is on J2 Y axis */ +/* Y defaults to J1 Y axis */ +#define JOY_HWS_YISJ1X 0x00000400l /* Y is on J1 X axis */ +#define JOY_HWS_YISJ2X 0x00000800l /* Y is on J2 X axis */ +#define JOY_HWS_YISJ2Y 0x00001000l /* Y is on J2 Y axis */ +/* Z defaults to J2 Y axis */ +#define JOY_HWS_ZISJ1X 0x00002000l /* Z is on J1 X axis */ +#define JOY_HWS_ZISJ1Y 0x00004000l /* Z is on J1 Y axis */ +#define JOY_HWS_ZISJ2X 0x00008000l /* Z is on J2 X axis */ +/* POV defaults to J2 Y axis, if it is not button based */ +#define JOY_HWS_POVISJ1X 0x00010000l /* pov done through J1 X axis */ +#define JOY_HWS_POVISJ1Y 0x00020000l /* pov done through J1 Y axis */ +#define JOY_HWS_POVISJ2X 0x00040000l /* pov done through J2 X axis */ +/* R defaults to J2 X axis */ +#define JOY_HWS_HASR 0x00080000l /* has R (4th axis) info */ +#define JOY_HWS_RISJ1X 0x00100000l /* R done through J1 X axis */ +#define JOY_HWS_RISJ1Y 0x00200000l /* R done through J1 Y axis */ +#define JOY_HWS_RISJ2Y 0x00400000l /* R done through J2 X axis */ +/* U & V for future hardware */ +#define JOY_HWS_HASU 0x00800000l /* has U (5th axis) info */ +#define JOY_HWS_HASV 0x01000000l /* has V (6th axis) info */ + +/* Usage settings */ +#define JOY_US_HASRUDDER 0x00000001l /* joystick configured with rudder */ +#define JOY_US_PRESENT 0x00000002l /* is joystick actually present? */ +#define JOY_US_ISOEM 0x00000004l /* joystick is an OEM defined type */ + +/* reserved for future use -> as link to next possible dword */ +#define JOY_US_RESERVED 0x80000000l /* reserved */ + + +/* Settings for TypeInfo Flags1 */ +#define JOYTYPE_ZEROGAMEENUMOEMDATA 0x00000001l /* Zero GameEnum's OEM data field */ +#define JOYTYPE_NOAUTODETECTGAMEPORT 0x00000002l /* Device does not support Autodetect gameport*/ +#define JOYTYPE_NOHIDDIRECT 0x00000004l /* Do not use HID directly for this device */ +#define JOYTYPE_ANALOGCOMPAT 0x00000008l /* Expose the analog compatible ID */ +#define JOYTYPE_DEFAULTPROPSHEET 0x80000000l /* CPL overrides custom property sheet */ + +/* Settings for TypeInfo Flags2 */ +#define JOYTYPE_DEVICEHIDE 0x00010000l /* Hide unclassified devices */ +#define JOYTYPE_MOUSEHIDE 0x00020000l /* Hide mice */ +#define JOYTYPE_KEYBHIDE 0x00040000l /* Hide keyboards */ +#define JOYTYPE_GAMEHIDE 0x00080000l /* Hide game controllers */ +#define JOYTYPE_HIDEACTIVE 0x00100000l /* Hide flags are active */ +#define JOYTYPE_INFOMASK 0x00E00000l /* Mask for type specific info */ +#define JOYTYPE_INFODEFAULT 0x00000000l /* Use default axis mappings */ +#define JOYTYPE_INFOYYPEDALS 0x00200000l /* Use Y as a combined pedals axis */ +#define JOYTYPE_INFOZYPEDALS 0x00400000l /* Use Z for accelerate, Y for brake */ +#define JOYTYPE_INFOYRPEDALS 0x00600000l /* Use Y for accelerate, R for brake */ +#define JOYTYPE_INFOZRPEDALS 0x00800000l /* Use Z for accelerate, R for brake */ +#define JOYTYPE_INFOZISSLIDER 0x00200000l /* Use Z as a slider */ +#define JOYTYPE_INFOZISZ 0x00400000l /* Use Z as Z axis */ +#define JOYTYPE_ENABLEINPUTREPORT 0x01000000l /* Enable initial input reports */ + +/* struct for storing x,y, z, and rudder values */ +typedef struct joypos_tag { + DWORD dwX; + DWORD dwY; + DWORD dwZ; + DWORD dwR; + DWORD dwU; + DWORD dwV; +} JOYPOS, FAR *LPJOYPOS; + +/* struct for storing ranges */ +typedef struct joyrange_tag { + JOYPOS jpMin; + JOYPOS jpMax; + JOYPOS jpCenter; +} JOYRANGE,FAR *LPJOYRANGE; + +/* + * dwTimeout - value at which to timeout joystick polling + * jrvRanges - range of values app wants returned for axes + * jpDeadZone - area around center to be considered + * as "dead". specified as a percentage + * (0-100). Only X & Y handled by system driver + */ +typedef struct joyreguservalues_tag { + DWORD dwTimeOut; + JOYRANGE jrvRanges; + JOYPOS jpDeadZone; +} JOYREGUSERVALUES, FAR *LPJOYREGUSERVALUES; + +typedef struct joyreghwsettings_tag { + DWORD dwFlags; + DWORD dwNumButtons; +} JOYREGHWSETTINGS, FAR *LPJOYHWSETTINGS; + +/* range of values returned by the hardware (filled in by calibration) */ +/* + * jrvHardware - values returned by hardware + * dwPOVValues - POV values returned by hardware + * dwCalFlags - what has been calibrated + */ +typedef struct joyreghwvalues_tag { + JOYRANGE jrvHardware; + DWORD dwPOVValues[JOY_POV_NUMDIRS]; + DWORD dwCalFlags; +} JOYREGHWVALUES, FAR *LPJOYREGHWVALUES; + +/* hardware configuration */ +/* + * hws - hardware settings + * dwUsageSettings - usage settings + * hwv - values returned by hardware + * dwType - type of joystick + * dwReserved - reserved for OEM drivers + */ +typedef struct joyreghwconfig_tag { + JOYREGHWSETTINGS hws; + DWORD dwUsageSettings; + JOYREGHWVALUES hwv; + DWORD dwType; + DWORD dwReserved; +} JOYREGHWCONFIG, FAR *LPJOYREGHWCONFIG; + +/* joystick calibration info structure */ +typedef struct joycalibrate_tag { + UINT wXbase; + UINT wXdelta; + UINT wYbase; + UINT wYdelta; + UINT wZbase; + UINT wZdelta; +} JOYCALIBRATE; +typedef JOYCALIBRATE FAR *LPJOYCALIBRATE; + +#endif + +#ifndef DIJ_RINGZERO + +#define MAX_JOYSTRING 256 +typedef BOOL (FAR PASCAL * LPDIJOYTYPECALLBACK)(LPCWSTR, LPVOID); + +#ifndef MAX_JOYSTICKOEMVXDNAME +#define MAX_JOYSTICKOEMVXDNAME 260 +#endif + +#define DITC_REGHWSETTINGS 0x00000001 +#define DITC_CLSIDCONFIG 0x00000002 +#define DITC_DISPLAYNAME 0x00000004 +#define DITC_CALLOUT 0x00000008 +#define DITC_HARDWAREID 0x00000010 +#define DITC_FLAGS1 0x00000020 +#define DITC_FLAGS2 0x00000040 +#define DITC_MAPFILE 0x00000080 + + + +/* This structure is defined for DirectX 5.0 compatibility */ + +typedef struct DIJOYTYPEINFO_DX5 { + DWORD dwSize; + JOYREGHWSETTINGS hws; + CLSID clsidConfig; + WCHAR wszDisplayName[MAX_JOYSTRING]; + WCHAR wszCallout[MAX_JOYSTICKOEMVXDNAME]; +} DIJOYTYPEINFO_DX5, *LPDIJOYTYPEINFO_DX5; +typedef const DIJOYTYPEINFO_DX5 *LPCDIJOYTYPEINFO_DX5; + +/* This structure is defined for DirectX 6.1 compatibility */ +typedef struct DIJOYTYPEINFO_DX6 { + DWORD dwSize; + JOYREGHWSETTINGS hws; + CLSID clsidConfig; + WCHAR wszDisplayName[MAX_JOYSTRING]; + WCHAR wszCallout[MAX_JOYSTICKOEMVXDNAME]; + WCHAR wszHardwareId[MAX_JOYSTRING]; + DWORD dwFlags1; +} DIJOYTYPEINFO_DX6, *LPDIJOYTYPEINFO_DX6; +typedef const DIJOYTYPEINFO_DX6 *LPCDIJOYTYPEINFO_DX6; + +typedef struct DIJOYTYPEINFO { + DWORD dwSize; + JOYREGHWSETTINGS hws; + CLSID clsidConfig; + WCHAR wszDisplayName[MAX_JOYSTRING]; + WCHAR wszCallout[MAX_JOYSTICKOEMVXDNAME]; +#if(DIRECTINPUT_VERSION >= 0x05b2) + WCHAR wszHardwareId[MAX_JOYSTRING]; + DWORD dwFlags1; +#if(DIRECTINPUT_VERSION >= 0x0800) + DWORD dwFlags2; + WCHAR wszMapFile[MAX_JOYSTRING]; +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ +#endif /* DIRECTINPUT_VERSION >= 0x05b2 */ +} DIJOYTYPEINFO, *LPDIJOYTYPEINFO; +typedef const DIJOYTYPEINFO *LPCDIJOYTYPEINFO; +#define DIJC_GUIDINSTANCE 0x00000001 +#define DIJC_REGHWCONFIGTYPE 0x00000002 +#define DIJC_GAIN 0x00000004 +#define DIJC_CALLOUT 0x00000008 +#define DIJC_WDMGAMEPORT 0x00000010 + +/* This structure is defined for DirectX 5.0 compatibility */ + +typedef struct DIJOYCONFIG_DX5 { + DWORD dwSize; + GUID guidInstance; + JOYREGHWCONFIG hwc; + DWORD dwGain; + WCHAR wszType[MAX_JOYSTRING]; + WCHAR wszCallout[MAX_JOYSTRING]; +} DIJOYCONFIG_DX5, *LPDIJOYCONFIG_DX5; +typedef const DIJOYCONFIG_DX5 *LPCDIJOYCONFIG_DX5; + +typedef struct DIJOYCONFIG { + DWORD dwSize; + GUID guidInstance; + JOYREGHWCONFIG hwc; + DWORD dwGain; + WCHAR wszType[MAX_JOYSTRING]; + WCHAR wszCallout[MAX_JOYSTRING]; +#if(DIRECTINPUT_VERSION >= 0x05b2) + GUID guidGameport; +#endif /* DIRECTINPUT_VERSION >= 0x05b2 */ + } DIJOYCONFIG, *LPDIJOYCONFIG; +typedef const DIJOYCONFIG *LPCDIJOYCONFIG; + + +#define DIJU_USERVALUES 0x00000001 +#define DIJU_GLOBALDRIVER 0x00000002 +#define DIJU_GAMEPORTEMULATOR 0x00000004 + +typedef struct DIJOYUSERVALUES { + DWORD dwSize; + JOYREGUSERVALUES ruv; + WCHAR wszGlobalDriver[MAX_JOYSTRING]; + WCHAR wszGameportEmulator[MAX_JOYSTRING]; +} DIJOYUSERVALUES, *LPDIJOYUSERVALUES; +typedef const DIJOYUSERVALUES *LPCDIJOYUSERVALUES; + +DEFINE_GUID(GUID_KeyboardClass, 0x4D36E96B,0xE325,0x11CE,0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18); +DEFINE_GUID(GUID_MediaClass, 0x4D36E96C,0xE325,0x11CE,0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18); +DEFINE_GUID(GUID_MouseClass, 0x4D36E96F,0xE325,0x11CE,0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18); +DEFINE_GUID(GUID_HIDClass, 0x745A17A0,0x74D3,0x11D0,0xB6,0xFE,0x00,0xA0,0xC9,0x0F,0x57,0xDA); + +#undef INTERFACE +#define INTERFACE IDirectInputJoyConfig + +DECLARE_INTERFACE_(IDirectInputJoyConfig, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputJoyConfig methods ***/ + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(SendNotify)(THIS) PURE; + STDMETHOD(EnumTypes)(THIS_ LPDIJOYTYPECALLBACK,LPVOID) PURE; + STDMETHOD(GetTypeInfo)(THIS_ LPCWSTR,LPDIJOYTYPEINFO,DWORD) PURE; + STDMETHOD(SetTypeInfo)(THIS_ LPCWSTR,LPCDIJOYTYPEINFO,DWORD) PURE; + STDMETHOD(DeleteType)(THIS_ LPCWSTR) PURE; + STDMETHOD(GetConfig)(THIS_ UINT,LPDIJOYCONFIG,DWORD) PURE; + STDMETHOD(SetConfig)(THIS_ UINT,LPCDIJOYCONFIG,DWORD) PURE; + STDMETHOD(DeleteConfig)(THIS_ UINT) PURE; + STDMETHOD(GetUserValues)(THIS_ LPDIJOYUSERVALUES,DWORD) PURE; + STDMETHOD(SetUserValues)(THIS_ LPCDIJOYUSERVALUES,DWORD) PURE; + STDMETHOD(AddNewHardware)(THIS_ HWND,REFGUID) PURE; + STDMETHOD(OpenTypeKey)(THIS_ LPCWSTR,DWORD,PHKEY) PURE; + STDMETHOD(OpenConfigKey)(THIS_ UINT,DWORD,PHKEY) PURE; +}; + +typedef struct IDirectInputJoyConfig *LPDIRECTINPUTJOYCONFIG; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputJoyConfig_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputJoyConfig_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputJoyConfig_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputJoyConfig_Acquire(p) (p)->lpVtbl->Acquire(p) +#define IDirectInputJoyConfig_Unacquire(p) (p)->lpVtbl->Unacquire(p) +#define IDirectInputJoyConfig_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectInputJoyConfig_SendNotify(p) (p)->lpVtbl->SendNotify(p) +#define IDirectInputJoyConfig_EnumTypes(p,a,b) (p)->lpVtbl->EnumTypes(p,a,b) +#define IDirectInputJoyConfig_GetTypeInfo(p,a,b,c) (p)->lpVtbl->GetTypeInfo(p,a,b,c) +#define IDirectInputJoyConfig_SetTypeInfo(p,a,b,c) (p)->lpVtbl->SetTypeInfo(p,a,b,c) +#define IDirectInputJoyConfig_DeleteType(p,a) (p)->lpVtbl->DeleteType(p,a) +#define IDirectInputJoyConfig_GetConfig(p,a,b,c) (p)->lpVtbl->GetConfig(p,a,b,c) +#define IDirectInputJoyConfig_SetConfig(p,a,b,c) (p)->lpVtbl->SetConfig(p,a,b,c) +#define IDirectInputJoyConfig_DeleteConfig(p,a) (p)->lpVtbl->DeleteConfig(p,a) +#define IDirectInputJoyConfig_GetUserValues(p,a,b) (p)->lpVtbl->GetUserValues(p,a,b) +#define IDirectInputJoyConfig_SetUserValues(p,a,b) (p)->lpVtbl->SetUserValues(p,a,b) +#define IDirectInputJoyConfig_AddNewHardware(p,a,b) (p)->lpVtbl->AddNewHardware(p,a,b) +#define IDirectInputJoyConfig_OpenTypeKey(p,a,b,c) (p)->lpVtbl->OpenTypeKey(p,a,b,c) +#define IDirectInputJoyConfig_OpenConfigKey(p,a,b,c) (p)->lpVtbl->OpenConfigKey(p,a,b,c) +#else +#define IDirectInputJoyConfig_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputJoyConfig_AddRef(p) (p)->AddRef() +#define IDirectInputJoyConfig_Release(p) (p)->Release() +#define IDirectInputJoyConfig_Acquire(p) (p)->Acquire() +#define IDirectInputJoyConfig_Unacquire(p) (p)->Unacquire() +#define IDirectInputJoyConfig_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectInputJoyConfig_SendNotify(p) (p)->SendNotify() +#define IDirectInputJoyConfig_EnumTypes(p,a,b) (p)->EnumTypes(a,b) +#define IDirectInputJoyConfig_GetTypeInfo(p,a,b,c) (p)->GetTypeInfo(a,b,c) +#define IDirectInputJoyConfig_SetTypeInfo(p,a,b,c) (p)->SetTypeInfo(a,b,c) +#define IDirectInputJoyConfig_DeleteType(p,a) (p)->DeleteType(a) +#define IDirectInputJoyConfig_GetConfig(p,a,b,c) (p)->GetConfig(a,b,c) +#define IDirectInputJoyConfig_SetConfig(p,a,b,c) (p)->SetConfig(a,b,c) +#define IDirectInputJoyConfig_DeleteConfig(p,a) (p)->DeleteConfig(a) +#define IDirectInputJoyConfig_GetUserValues(p,a,b) (p)->GetUserValues(a,b) +#define IDirectInputJoyConfig_SetUserValues(p,a,b) (p)->SetUserValues(a,b) +#define IDirectInputJoyConfig_AddNewHardware(p,a,b) (p)->AddNewHardware(a,b) +#define IDirectInputJoyConfig_OpenTypeKey(p,a,b,c) (p)->OpenTypeKey(a,b,c) +#define IDirectInputJoyConfig_OpenConfigKey(p,a,b,c) (p)->OpenConfigKey(a,b,c) +#endif + +#endif /* DIJ_RINGZERO */ + +#if(DIRECTINPUT_VERSION >= 0x0800) + +#ifndef DIJ_RINGZERO + +#undef INTERFACE +#define INTERFACE IDirectInputJoyConfig8 + +DECLARE_INTERFACE_(IDirectInputJoyConfig8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirectInputJoyConfig8 methods ***/ + STDMETHOD(Acquire)(THIS) PURE; + STDMETHOD(Unacquire)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE; + STDMETHOD(SendNotify)(THIS) PURE; + STDMETHOD(EnumTypes)(THIS_ LPDIJOYTYPECALLBACK,LPVOID) PURE; + STDMETHOD(GetTypeInfo)(THIS_ LPCWSTR,LPDIJOYTYPEINFO,DWORD) PURE; + STDMETHOD(SetTypeInfo)(THIS_ LPCWSTR,LPCDIJOYTYPEINFO,DWORD,LPWSTR) PURE; + STDMETHOD(DeleteType)(THIS_ LPCWSTR) PURE; + STDMETHOD(GetConfig)(THIS_ UINT,LPDIJOYCONFIG,DWORD) PURE; + STDMETHOD(SetConfig)(THIS_ UINT,LPCDIJOYCONFIG,DWORD) PURE; + STDMETHOD(DeleteConfig)(THIS_ UINT) PURE; + STDMETHOD(GetUserValues)(THIS_ LPDIJOYUSERVALUES,DWORD) PURE; + STDMETHOD(SetUserValues)(THIS_ LPCDIJOYUSERVALUES,DWORD) PURE; + STDMETHOD(AddNewHardware)(THIS_ HWND,REFGUID) PURE; + STDMETHOD(OpenTypeKey)(THIS_ LPCWSTR,DWORD,PHKEY) PURE; + STDMETHOD(OpenAppStatusKey)(THIS_ PHKEY) PURE; +}; + +typedef struct IDirectInputJoyConfig8 *LPDIRECTINPUTJOYCONFIG8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectInputJoyConfig8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectInputJoyConfig8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectInputJoyConfig8_Release(p) (p)->lpVtbl->Release(p) +#define IDirectInputJoyConfig8_Acquire(p) (p)->lpVtbl->Acquire(p) +#define IDirectInputJoyConfig8_Unacquire(p) (p)->lpVtbl->Unacquire(p) +#define IDirectInputJoyConfig8_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectInputJoyConfig8_SendNotify(p) (p)->lpVtbl->SendNotify(p) +#define IDirectInputJoyConfig8_EnumTypes(p,a,b) (p)->lpVtbl->EnumTypes(p,a,b) +#define IDirectInputJoyConfig8_GetTypeInfo(p,a,b,c) (p)->lpVtbl->GetTypeInfo(p,a,b,c) +#define IDirectInputJoyConfig8_SetTypeInfo(p,a,b,c,d) (p)->lpVtbl->SetTypeInfo(p,a,b,c,d) +#define IDirectInputJoyConfig8_DeleteType(p,a) (p)->lpVtbl->DeleteType(p,a) +#define IDirectInputJoyConfig8_GetConfig(p,a,b,c) (p)->lpVtbl->GetConfig(p,a,b,c) +#define IDirectInputJoyConfig8_SetConfig(p,a,b,c) (p)->lpVtbl->SetConfig(p,a,b,c) +#define IDirectInputJoyConfig8_DeleteConfig(p,a) (p)->lpVtbl->DeleteConfig(p,a) +#define IDirectInputJoyConfig8_GetUserValues(p,a,b) (p)->lpVtbl->GetUserValues(p,a,b) +#define IDirectInputJoyConfig8_SetUserValues(p,a,b) (p)->lpVtbl->SetUserValues(p,a,b) +#define IDirectInputJoyConfig8_AddNewHardware(p,a,b) (p)->lpVtbl->AddNewHardware(p,a,b) +#define IDirectInputJoyConfig8_OpenTypeKey(p,a,b,c) (p)->lpVtbl->OpenTypeKey(p,a,b,c) +#define IDirectInputJoyConfig8_OpenAppStatusKey(p,a) (p)->lpVtbl->OpenAppStatusKey(p,a) +#else +#define IDirectInputJoyConfig8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectInputJoyConfig8_AddRef(p) (p)->AddRef() +#define IDirectInputJoyConfig8_Release(p) (p)->Release() +#define IDirectInputJoyConfig8_Acquire(p) (p)->Acquire() +#define IDirectInputJoyConfig8_Unacquire(p) (p)->Unacquire() +#define IDirectInputJoyConfig8_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectInputJoyConfig8_SendNotify(p) (p)->SendNotify() +#define IDirectInputJoyConfig8_EnumTypes(p,a,b) (p)->EnumTypes(a,b) +#define IDirectInputJoyConfig8_GetTypeInfo(p,a,b,c) (p)->GetTypeInfo(a,b,c) +#define IDirectInputJoyConfig8_SetTypeInfo(p,a,b,c,d) (p)->SetTypeInfo(a,b,c,d) +#define IDirectInputJoyConfig8_DeleteType(p,a) (p)->DeleteType(a) +#define IDirectInputJoyConfig8_GetConfig(p,a,b,c) (p)->GetConfig(a,b,c) +#define IDirectInputJoyConfig8_SetConfig(p,a,b,c) (p)->SetConfig(a,b,c) +#define IDirectInputJoyConfig8_DeleteConfig(p,a) (p)->DeleteConfig(a) +#define IDirectInputJoyConfig8_GetUserValues(p,a,b) (p)->GetUserValues(a,b) +#define IDirectInputJoyConfig8_SetUserValues(p,a,b) (p)->SetUserValues(a,b) +#define IDirectInputJoyConfig8_AddNewHardware(p,a,b) (p)->AddNewHardware(a,b) +#define IDirectInputJoyConfig8_OpenTypeKey(p,a,b,c) (p)->OpenTypeKey(a,b,c) +#define IDirectInputJoyConfig8_OpenAppStatusKey(p,a) (p)->OpenAppStatusKey(a) +#endif + +#endif /* DIJ_RINGZERO */ + +/**************************************************************************** + * + * Notification Messages + * + ****************************************************************************/ + +/* RegisterWindowMessage with this to get DirectInput notification messages */ +#define DIRECTINPUT_NOTIFICATION_MSGSTRINGA "DIRECTINPUT_NOTIFICATION_MSGSTRING" +#define DIRECTINPUT_NOTIFICATION_MSGSTRINGW L"DIRECTINPUT_NOTIFICATION_MSGSTRING" + +#ifdef UNICODE +#define DIRECTINPUT_NOTIFICATION_MSGSTRING DIRECTINPUT_NOTIFICATION_MSGSTRINGW +#else +#define DIRECTINPUT_NOTIFICATION_MSGSTRING DIRECTINPUT_NOTIFICATION_MSGSTRINGA +#endif + +#define DIMSGWP_NEWAPPSTART 0x00000001 +#define DIMSGWP_DX8APPSTART 0x00000002 +#define DIMSGWP_DX8MAPPERAPPSTART 0x00000003 + +#endif /* DIRECTINPUT_VERSION >= 0x0800 */ + +#define DIAPPIDFLAG_NOTIME 0x00000001 +#define DIAPPIDFLAG_NOSIZE 0x00000002 + +#define DIRECTINPUT_REGSTR_VAL_APPIDFLAGA "AppIdFlag" +#define DIRECTINPUT_REGSTR_KEY_LASTAPPA "MostRecentApplication" +#define DIRECTINPUT_REGSTR_KEY_LASTMAPAPPA "MostRecentMapperApplication" +#define DIRECTINPUT_REGSTR_VAL_VERSIONA "Version" +#define DIRECTINPUT_REGSTR_VAL_NAMEA "Name" +#define DIRECTINPUT_REGSTR_VAL_IDA "Id" +#define DIRECTINPUT_REGSTR_VAL_MAPPERA "UsesMapper" +#define DIRECTINPUT_REGSTR_VAL_LASTSTARTA "MostRecentStart" + +#define DIRECTINPUT_REGSTR_VAL_APPIDFLAGW L"AppIdFlag" +#define DIRECTINPUT_REGSTR_KEY_LASTAPPW L"MostRecentApplication" +#define DIRECTINPUT_REGSTR_KEY_LASTMAPAPPW L"MostRecentMapperApplication" +#define DIRECTINPUT_REGSTR_VAL_VERSIONW L"Version" +#define DIRECTINPUT_REGSTR_VAL_NAMEW L"Name" +#define DIRECTINPUT_REGSTR_VAL_IDW L"Id" +#define DIRECTINPUT_REGSTR_VAL_MAPPERW L"UsesMapper" +#define DIRECTINPUT_REGSTR_VAL_LASTSTARTW L"MostRecentStart" + +#ifdef UNICODE +#define DIRECTINPUT_REGSTR_VAL_APPIDFLAG DIRECTINPUT_REGSTR_VAL_APPIDFLAGW +#define DIRECTINPUT_REGSTR_KEY_LASTAPP DIRECTINPUT_REGSTR_KEY_LASTAPPW +#define DIRECTINPUT_REGSTR_KEY_LASTMAPAPP DIRECTINPUT_REGSTR_KEY_LASTMAPAPPW +#define DIRECTINPUT_REGSTR_VAL_VERSION DIRECTINPUT_REGSTR_VAL_VERSIONW +#define DIRECTINPUT_REGSTR_VAL_NAME DIRECTINPUT_REGSTR_VAL_NAMEW +#define DIRECTINPUT_REGSTR_VAL_ID DIRECTINPUT_REGSTR_VAL_IDW +#define DIRECTINPUT_REGSTR_VAL_MAPPER DIRECTINPUT_REGSTR_VAL_MAPPERW +#define DIRECTINPUT_REGSTR_VAL_LASTSTART DIRECTINPUT_REGSTR_VAL_LASTSTARTW +#else +#define DIRECTINPUT_REGSTR_VAL_APPIDFLAG DIRECTINPUT_REGSTR_VAL_APPIDFLAGA +#define DIRECTINPUT_REGSTR_KEY_LASTAPP DIRECTINPUT_REGSTR_KEY_LASTAPPA +#define DIRECTINPUT_REGSTR_KEY_LASTMAPAPP DIRECTINPUT_REGSTR_KEY_LASTMAPAPPA +#define DIRECTINPUT_REGSTR_VAL_VERSION DIRECTINPUT_REGSTR_VAL_VERSIONA +#define DIRECTINPUT_REGSTR_VAL_NAME DIRECTINPUT_REGSTR_VAL_NAMEA +#define DIRECTINPUT_REGSTR_VAL_ID DIRECTINPUT_REGSTR_VAL_IDA +#define DIRECTINPUT_REGSTR_VAL_MAPPER DIRECTINPUT_REGSTR_VAL_MAPPERA +#define DIRECTINPUT_REGSTR_VAL_LASTSTART DIRECTINPUT_REGSTR_VAL_LASTSTARTA +#endif + + +/**************************************************************************** + * + * Return Codes + * + ****************************************************************************/ + +#define DIERR_NOMOREITEMS \ + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NO_MORE_ITEMS) + +/* + * Device driver-specific codes. + */ + +#define DIERR_DRIVERFIRST 0x80040300L +#define DIERR_DRIVERLAST 0x800403FFL + +/* + * Unless the specific driver has been precisely identified, no meaning + * should be attributed to these values other than that the driver + * originated the error. However, to illustrate the types of error that + * may be causing the failure, the PID force feedback driver distributed + * with DirectX 7 could return the following errors: + * + * DIERR_DRIVERFIRST + 1 + * The requested usage was not found. + * DIERR_DRIVERFIRST + 2 + * The parameter block couldn't be downloaded to the device. + * DIERR_DRIVERFIRST + 3 + * PID initialization failed. + * DIERR_DRIVERFIRST + 4 + * The provided values couldn't be scaled. + */ + + +/* + * Device installer errors. + */ + +/* + * Registry entry or DLL for class installer invalid + * or class installer not found. + */ +#define DIERR_INVALIDCLASSINSTALLER 0x80040400L + +/* + * The user cancelled the install operation. + */ +#define DIERR_CANCELLED 0x80040401L + +/* + * The INF file for the selected device could not be + * found or is invalid or is damaged. + */ +#define DIERR_BADINF 0x80040402L + +/**************************************************************************** + * + * Map files + * + ****************************************************************************/ + +/* + * Delete particular data from default map file. + */ +#define DIDIFT_DELETE 0x01000000 + +#ifdef __cplusplus +}; +#endif + +#endif /* __DINPUTD_INCLUDED__ */ diff --git a/dxsdk/Include/dsconf.h b/dxsdk/Include/dsconf.h new file mode 100644 index 0000000..018f65a --- /dev/null +++ b/dxsdk/Include/dsconf.h @@ -0,0 +1,195 @@ +/*==========================================================================; + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: dsconf.h + * Content: DirectSound configuration interface include file + * + **************************************************************************/ + +#ifndef __DSCONF_INCLUDED__ +#define __DSCONF_INCLUDED__ + +#ifndef __DSOUND_INCLUDED__ +#error dsound.h not included +#endif // __DSOUND_INCLUDED__ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + +// DirectSound Private Component GUID {11AB3EC0-25EC-11d1-A4D8-00C04FC28ACA} +DEFINE_GUID(CLSID_DirectSoundPrivate, 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + + +// +// DirectSound Device Properties {84624F82-25EC-11d1-A4D8-00C04FC28ACA} +// + +DEFINE_GUID(DSPROPSETID_DirectSoundDevice, 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + +typedef enum +{ + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A = 1, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1 = 2, + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 = 3, + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W = 4, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A = 5, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W = 6, + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A = 7, + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W = 8, +} DSPROPERTY_DIRECTSOUNDDEVICE; + +#if DIRECTSOUND_VERSION >= 0x0700 +#ifdef UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W +#define DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W +#else // UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A +#define DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A +#endif // UNICODE +#else // DIRECTSOUND_VERSION >= 0x0700 +#define DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1 +#define DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 +#endif // DIRECTSOUND_VERSION >= 0x0700 + +typedef enum +{ + DIRECTSOUNDDEVICE_TYPE_EMULATED, + DIRECTSOUNDDEVICE_TYPE_VXD, + DIRECTSOUNDDEVICE_TYPE_WDM +} DIRECTSOUNDDEVICE_TYPE; + +typedef enum +{ + DIRECTSOUNDDEVICE_DATAFLOW_RENDER, + DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE +} DIRECTSOUNDDEVICE_DATAFLOW; + + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA +{ + LPSTR DeviceName; // waveIn/waveOut device name + DIRECTSOUNDDEVICE_DATAFLOW DataFlow; // Data flow (i.e. waveIn or waveOut) + GUID DeviceId; // DirectSound device id +} DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA; + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA +{ + LPWSTR DeviceName; // waveIn/waveOut device name + DIRECTSOUNDDEVICE_DATAFLOW DataFlow; // Data flow (i.e. waveIn or waveOut) + GUID DeviceId; // DirectSound device id +} DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA; + +#ifdef UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_DATA DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA +#else // UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_DATA DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA +#endif // UNICODE + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA +{ + GUID DeviceId; // DirectSound device id + CHAR DescriptionA[0x100]; // Device description (ANSI) + WCHAR DescriptionW[0x100]; // Device description (Unicode) + CHAR ModuleA[MAX_PATH]; // Device driver module (ANSI) + WCHAR ModuleW[MAX_PATH]; // Device driver module (Unicode) + DIRECTSOUNDDEVICE_TYPE Type; // Device type + DIRECTSOUNDDEVICE_DATAFLOW DataFlow; // Device dataflow + ULONG WaveDeviceId; // Wave device id + ULONG Devnode; // Devnode (or DevInst) +} DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA; + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA +{ + DIRECTSOUNDDEVICE_TYPE Type; // Device type + DIRECTSOUNDDEVICE_DATAFLOW DataFlow; // Device dataflow + GUID DeviceId; // DirectSound device id + LPSTR Description; // Device description + LPSTR Module; // Device driver module + LPSTR Interface; // Device interface + ULONG WaveDeviceId; // Wave device id +} DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA; + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA +{ + DIRECTSOUNDDEVICE_TYPE Type; // Device type + DIRECTSOUNDDEVICE_DATAFLOW DataFlow; // Device dataflow + GUID DeviceId; // DirectSound device id + LPWSTR Description; // Device description + LPWSTR Module; // Device driver module + LPWSTR Interface; // Device interface + ULONG WaveDeviceId; // Wave device id +} DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA; + +#if DIRECTSOUND_VERSION >= 0x0700 +#ifdef UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA +#else // UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA +#endif // UNICODE +#else // DIRECTSOUND_VERSION >= 0x0700 +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA +#endif // DIRECTSOUND_VERSION >= 0x0700 + +typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK1)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA, LPVOID); +typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKA)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA, LPVOID); +typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKW)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA, LPVOID); + +#if DIRECTSOUND_VERSION >= 0x0700 +#ifdef UNICODE +#define LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKW +#else // UNICODE +#define LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKA +#endif // UNICODE +#else // DIRECTSOUND_VERSION >= 0x0700 +#define LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK1 +#endif // DIRECTSOUND_VERSION >= 0x0700 + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA +{ + LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK1 Callback; // Callback function pointer + LPVOID Context; // Callback function context argument +} DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA; + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA +{ + LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKA Callback; // Callback function pointer + LPVOID Context; // Callback function context argument +} DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA; + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA +{ + LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKW Callback; // Callback function pointer + LPVOID Context; // Callback function context argument +} DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA; + +#if DIRECTSOUND_VERSION >= 0x0700 +#ifdef UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA +#else // UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA +#endif // UNICODE +#else // DIRECTSOUND_VERSION >= 0x0700 +#define DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA +#define PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA +#endif // DIRECTSOUND_VERSION >= 0x0700 + + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // __DSCONF_INCLUDED__ + diff --git a/dxsdk/Include/dsetup.h b/dxsdk/Include/dsetup.h new file mode 100644 index 0000000..ebada13 --- /dev/null +++ b/dxsdk/Include/dsetup.h @@ -0,0 +1,283 @@ +/*========================================================================== + * + * Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved. + * + * File: dsetup.h + * Content: DirectXSetup, error codes and flags + ***************************************************************************/ + +#ifndef __DSETUP_H__ +#define __DSETUP_H__ + +#include // windows stuff + +#ifdef __cplusplus +extern "C" { +#endif + +#define FOURCC_VERS mmioFOURCC('v','e','r','s') + +// DSETUP Error Codes, must remain compatible with previous setup. +#define DSETUPERR_SUCCESS_RESTART 1 +#define DSETUPERR_SUCCESS 0 +#define DSETUPERR_BADWINDOWSVERSION -1 +#define DSETUPERR_SOURCEFILENOTFOUND -2 +#define DSETUPERR_NOCOPY -5 +#define DSETUPERR_OUTOFDISKSPACE -6 +#define DSETUPERR_CANTFINDINF -7 +#define DSETUPERR_CANTFINDDIR -8 +#define DSETUPERR_INTERNAL -9 +#define DSETUPERR_UNKNOWNOS -11 +#define DSETUPERR_NEWERVERSION -14 +#define DSETUPERR_NOTADMIN -15 +#define DSETUPERR_UNSUPPORTEDPROCESSOR -16 +#define DSETUPERR_MISSINGCAB_MANAGEDDX -17 +#define DSETUPERR_NODOTNETFRAMEWORKINSTALLED -18 +#define DSETUPERR_CABDOWNLOADFAIL -19 +#define DSETUPERR_DXCOMPONENTFILEINUSE -20 +#define DSETUPERR_UNTRUSTEDCABINETFILE -21 + +// DSETUP flags. DirectX 5.0 apps should use these flags only. +#define DSETUP_DDRAWDRV 0x00000008 /* install DirectDraw Drivers */ +#define DSETUP_DSOUNDDRV 0x00000010 /* install DirectSound Drivers */ +#define DSETUP_DXCORE 0x00010000 /* install DirectX runtime */ +#define DSETUP_DIRECTX (DSETUP_DXCORE|DSETUP_DDRAWDRV|DSETUP_DSOUNDDRV) +#define DSETUP_MANAGEDDX 0x00004000 /* OBSOLETE. install managed DirectX */ +#define DSETUP_TESTINSTALL 0x00020000 /* just test install, don't do anything */ + +// These OBSOLETE flags are here for compatibility with pre-DX5 apps only. +// They are present to allow DX3 apps to be recompiled with DX5 and still work. +// DO NOT USE THEM for DX5. They will go away in future DX releases. +#define DSETUP_DDRAW 0x00000001 /* OBSOLETE. install DirectDraw */ +#define DSETUP_DSOUND 0x00000002 /* OBSOLETE. install DirectSound */ +#define DSETUP_DPLAY 0x00000004 /* OBSOLETE. install DirectPlay */ +#define DSETUP_DPLAYSP 0x00000020 /* OBSOLETE. install DirectPlay Providers */ +#define DSETUP_DVIDEO 0x00000040 /* OBSOLETE. install DirectVideo */ +#define DSETUP_D3D 0x00000200 /* OBSOLETE. install Direct3D */ +#define DSETUP_DINPUT 0x00000800 /* OBSOLETE. install DirectInput */ +#define DSETUP_DIRECTXSETUP 0x00001000 /* OBSOLETE. install DirectXSetup DLL's */ +#define DSETUP_NOUI 0x00002000 /* OBSOLETE. install DirectX with NO UI */ +#define DSETUP_PROMPTFORDRIVERS 0x10000000 /* OBSOLETE. prompt when replacing display/audio drivers */ +#define DSETUP_RESTOREDRIVERS 0x20000000 /* OBSOLETE. restore display/audio drivers */ + + + +//****************************************************************** +// DirectX Setup Callback mechanism +//****************************************************************** + +// DSETUP Message Info Codes, passed to callback as Reason parameter. +#define DSETUP_CB_MSG_NOMESSAGE 0 +#define DSETUP_CB_MSG_INTERNAL_ERROR 10 +#define DSETUP_CB_MSG_BEGIN_INSTALL 13 +#define DSETUP_CB_MSG_BEGIN_INSTALL_RUNTIME 14 +#define DSETUP_CB_MSG_PROGRESS 18 +#define DSETUP_CB_MSG_WARNING_DISABLED_COMPONENT 19 + + + + + + +typedef struct _DSETUP_CB_PROGRESS +{ + DWORD dwPhase; + DWORD dwInPhaseMaximum; + DWORD dwInPhaseProgress; + DWORD dwOverallMaximum; + DWORD dwOverallProgress; +} DSETUP_CB_PROGRESS; + + +enum _DSETUP_CB_PROGRESS_PHASE +{ + DSETUP_INITIALIZING, + DSETUP_EXTRACTING, + DSETUP_COPYING, + DSETUP_FINALIZING +}; + + +#ifdef _WIN32 +// +// Data Structures +// +#ifndef UNICODE_ONLY + +typedef struct _DIRECTXREGISTERAPPA { + DWORD dwSize; + DWORD dwFlags; + LPSTR lpszApplicationName; + LPGUID lpGUID; + LPSTR lpszFilename; + LPSTR lpszCommandLine; + LPSTR lpszPath; + LPSTR lpszCurrentDirectory; +} DIRECTXREGISTERAPPA, *PDIRECTXREGISTERAPPA, *LPDIRECTXREGISTERAPPA; + +typedef struct _DIRECTXREGISTERAPP2A { + DWORD dwSize; + DWORD dwFlags; + LPSTR lpszApplicationName; + LPGUID lpGUID; + LPSTR lpszFilename; + LPSTR lpszCommandLine; + LPSTR lpszPath; + LPSTR lpszCurrentDirectory; + LPSTR lpszLauncherName; +} DIRECTXREGISTERAPP2A, *PDIRECTXREGISTERAPP2A, *LPDIRECTXREGISTERAPP2A; + +#endif //!UNICODE_ONLY +#ifndef ANSI_ONLY + +typedef struct _DIRECTXREGISTERAPPW { + DWORD dwSize; + DWORD dwFlags; + LPWSTR lpszApplicationName; + LPGUID lpGUID; + LPWSTR lpszFilename; + LPWSTR lpszCommandLine; + LPWSTR lpszPath; + LPWSTR lpszCurrentDirectory; +} DIRECTXREGISTERAPPW, *PDIRECTXREGISTERAPPW, *LPDIRECTXREGISTERAPPW; + +typedef struct _DIRECTXREGISTERAPP2W { + DWORD dwSize; + DWORD dwFlags; + LPWSTR lpszApplicationName; + LPGUID lpGUID; + LPWSTR lpszFilename; + LPWSTR lpszCommandLine; + LPWSTR lpszPath; + LPWSTR lpszCurrentDirectory; + LPWSTR lpszLauncherName; +} DIRECTXREGISTERAPP2W, *PDIRECTXREGISTERAPP2W, *LPDIRECTXREGISTERAPP2W; +#endif //!ANSI_ONLY +#ifdef UNICODE +typedef DIRECTXREGISTERAPPW DIRECTXREGISTERAPP; +typedef PDIRECTXREGISTERAPPW PDIRECTXREGISTERAPP; +typedef LPDIRECTXREGISTERAPPW LPDIRECTXREGISTERAPP; +typedef DIRECTXREGISTERAPP2W DIRECTXREGISTERAPP2; +typedef PDIRECTXREGISTERAPP2W PDIRECTXREGISTERAPP2; +typedef LPDIRECTXREGISTERAPP2W LPDIRECTXREGISTERAPP2; +#else +typedef DIRECTXREGISTERAPPA DIRECTXREGISTERAPP; +typedef PDIRECTXREGISTERAPPA PDIRECTXREGISTERAPP; +typedef LPDIRECTXREGISTERAPPA LPDIRECTXREGISTERAPP; +typedef DIRECTXREGISTERAPP2A DIRECTXREGISTERAPP2; +typedef PDIRECTXREGISTERAPP2A PDIRECTXREGISTERAPP2; +typedef LPDIRECTXREGISTERAPP2A LPDIRECTXREGISTERAPP2; +#endif // UNICODE + + +// +// API +// + +#ifndef UNICODE_ONLY +INT +WINAPI +DirectXSetupA( + HWND hWnd, + __in_opt LPSTR lpszRootPath, + DWORD dwFlags + ); +#endif //!UNICODE_ONLY +#ifndef ANSI_ONLY +INT +WINAPI +DirectXSetupW( + HWND hWnd, + __in_opt LPWSTR lpszRootPath, + DWORD dwFlags + ); +#endif //!ANSI_ONLY +#ifdef UNICODE +#define DirectXSetup DirectXSetupW +#else +#define DirectXSetup DirectXSetupA +#endif // !UNICODE + +#ifndef UNICODE_ONLY +INT +WINAPI +DirectXRegisterApplicationA( + HWND hWnd, + LPVOID lpDXRegApp + ); +#endif //!UNICODE_ONLY +#ifndef ANSI_ONLY +INT +WINAPI +DirectXRegisterApplicationW( + HWND hWnd, + LPVOID lpDXRegApp + ); +#endif //!ANSI_ONLY +#ifdef UNICODE +#define DirectXRegisterApplication DirectXRegisterApplicationW +#else +#define DirectXRegisterApplication DirectXRegisterApplicationA +#endif // !UNICODE + +INT +WINAPI +DirectXUnRegisterApplication( + HWND hWnd, + LPGUID lpGUID + ); + +// +// Function Pointers +// +#ifdef UNICODE +typedef INT (WINAPI * LPDIRECTXSETUP)(HWND, LPWSTR, DWORD); +typedef INT (WINAPI * LPDIRECTXREGISTERAPPLICATION)(HWND, LPVOID); +#else +typedef INT (WINAPI * LPDIRECTXSETUP)(HWND, LPSTR, DWORD); +typedef INT (WINAPI * LPDIRECTXREGISTERAPPLICATION)(HWND, LPVOID); +#endif // UNICODE + +typedef DWORD (FAR PASCAL * DSETUP_CALLBACK)(DWORD Reason, + DWORD MsgType, /* Same as flags to MessageBox */ + LPSTR szMessage, + LPSTR szName, + void *pInfo); + +INT WINAPI DirectXSetupSetCallback(DSETUP_CALLBACK Callback); +INT WINAPI DirectXSetupGetVersion(DWORD *lpdwVersion, DWORD *lpdwMinorVersion); +INT WINAPI DirectXSetupShowEULA(HWND hWndParent); +#ifndef UNICODE_ONLY +UINT +WINAPI +DirectXSetupGetEULAA( + __out_ecount(cchEULA) LPSTR lpszEULA, + UINT cchEULA, + WORD LangID + ); +#endif //!UNICODE_ONLY +#ifndef ANSI_ONLY +UINT +WINAPI +DirectXSetupGetEULAW( + __out_ecount(cchEULA) LPWSTR lpszEULA, + UINT cchEULA, + WORD LangID + ); +#endif //!ANSI_ONLY +#ifdef UNICODE +#define DirectXSetupGetEULA DirectXSetupGetEULAW +typedef UINT (WINAPI * LPDIRECTXSETUPGETEULA)(LPWSTR, UINT, WORD); +#else +#define DirectXSetupGetEULA DirectXSetupGetEULAA +typedef UINT (WINAPI * LPDIRECTXSETUPGETEULA)(LPSTR, UINT, WORD); +#endif // !UNICODE + +#endif // WIN32 + + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/dxsdk/Include/dsound.h b/dxsdk/Include/dsound.h new file mode 100644 index 0000000..34e4c30 --- /dev/null +++ b/dxsdk/Include/dsound.h @@ -0,0 +1,2385 @@ +/*==========================================================================; + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: dsound.h + * Content: DirectSound include file + * + **************************************************************************/ + +#define COM_NO_WINDOWS_H +#include +#include +#include + +#ifndef DIRECTSOUND_VERSION + +#if (NTDDI_VERSION < NTDDI_WINXP) /* Windows 2000 */ +#define DIRECTSOUND_VERSION 0x0700 /* Version 7.0 */ +#elif (NTDDI_VERSION < NTDDI_WINXPSP2 || NTDDI_VERSION == NTDDI_WS03) /* Windows XP and SP1, or Windows Server 2003 */ +#define DIRECTSOUND_VERSION 0x0800 /* Version 8.0 */ +#else /* Windows XP SP2 and higher, Windows Server 2003 SP1 and higher, Longhorn, or higher */ +#define DIRECTSOUND_VERSION 0x0900 /* Version 9.0 */ +#endif + +#endif // DIRECTSOUND_VERSION + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#ifndef __DSOUND_INCLUDED__ +#define __DSOUND_INCLUDED__ + +/* Type definitions shared with Direct3D */ + +#ifndef DX_SHARED_DEFINES + +typedef float D3DVALUE, *LPD3DVALUE; + +#ifndef D3DCOLOR_DEFINED +typedef DWORD D3DCOLOR; +#define D3DCOLOR_DEFINED +#endif + +#ifndef LPD3DCOLOR_DEFINED +typedef DWORD *LPD3DCOLOR; +#define LPD3DCOLOR_DEFINED +#endif + +#ifndef D3DVECTOR_DEFINED +typedef struct _D3DVECTOR { + float x; + float y; + float z; +} D3DVECTOR; +#define D3DVECTOR_DEFINED +#endif + +#ifndef LPD3DVECTOR_DEFINED +typedef D3DVECTOR *LPD3DVECTOR; +#define LPD3DVECTOR_DEFINED +#endif + +#define DX_SHARED_DEFINES +#endif // DX_SHARED_DEFINES + +#define _FACDS 0x878 /* DirectSound's facility code */ +#define MAKE_DSHRESULT(code) MAKE_HRESULT(1, _FACDS, code) + +// DirectSound Component GUID {47D4D946-62E8-11CF-93BC-444553540000} +DEFINE_GUID(CLSID_DirectSound, 0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0); + +// DirectSound 8.0 Component GUID {3901CC3F-84B5-4FA4-BA35-AA8172B8A09B} +DEFINE_GUID(CLSID_DirectSound8, 0x3901cc3f, 0x84b5, 0x4fa4, 0xba, 0x35, 0xaa, 0x81, 0x72, 0xb8, 0xa0, 0x9b); + +// DirectSound Capture Component GUID {B0210780-89CD-11D0-AF08-00A0C925CD16} +DEFINE_GUID(CLSID_DirectSoundCapture, 0xb0210780, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +// DirectSound 8.0 Capture Component GUID {E4BCAC13-7F99-4908-9A8E-74E3BF24B6E1} +DEFINE_GUID(CLSID_DirectSoundCapture8, 0xe4bcac13, 0x7f99, 0x4908, 0x9a, 0x8e, 0x74, 0xe3, 0xbf, 0x24, 0xb6, 0xe1); + +// DirectSound Full Duplex Component GUID {FEA4300C-7959-4147-B26A-2377B9E7A91D} +DEFINE_GUID(CLSID_DirectSoundFullDuplex, 0xfea4300c, 0x7959, 0x4147, 0xb2, 0x6a, 0x23, 0x77, 0xb9, 0xe7, 0xa9, 0x1d); + + +// DirectSound default playback device GUID {DEF00000-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultPlayback, 0xdef00000, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + +// DirectSound default capture device GUID {DEF00001-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultCapture, 0xdef00001, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + +// DirectSound default device for voice playback {DEF00002-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultVoicePlayback, 0xdef00002, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + +// DirectSound default device for voice capture {DEF00003-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultVoiceCapture, 0xdef00003, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + + +// +// Forward declarations for interfaces. +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +// + +#ifdef __cplusplus +struct IDirectSound; +struct IDirectSoundBuffer; +struct IDirectSound3DListener; +struct IDirectSound3DBuffer; +struct IDirectSoundCapture; +struct IDirectSoundCaptureBuffer; +struct IDirectSoundNotify; +#endif // __cplusplus + +// +// DirectSound 8.0 interfaces. +// + +#if DIRECTSOUND_VERSION >= 0x0800 + +#ifdef __cplusplus +struct IDirectSound8; +struct IDirectSoundBuffer8; +struct IDirectSoundCaptureBuffer8; +struct IDirectSoundFXGargle; +struct IDirectSoundFXChorus; +struct IDirectSoundFXFlanger; +struct IDirectSoundFXEcho; +struct IDirectSoundFXDistortion; +struct IDirectSoundFXCompressor; +struct IDirectSoundFXParamEq; +struct IDirectSoundFXWavesReverb; +struct IDirectSoundFXI3DL2Reverb; +struct IDirectSoundCaptureFXAec; +struct IDirectSoundCaptureFXNoiseSuppress; +struct IDirectSoundFullDuplex; +#endif // __cplusplus + +// IDirectSound8, IDirectSoundBuffer8 and IDirectSoundCaptureBuffer8 are the +// only DirectSound 7.0 interfaces with changed functionality in version 8.0. +// The other level 8 interfaces as equivalent to their level 7 counterparts: + +#define IDirectSoundCapture8 IDirectSoundCapture +#define IDirectSound3DListener8 IDirectSound3DListener +#define IDirectSound3DBuffer8 IDirectSound3DBuffer +#define IDirectSoundNotify8 IDirectSoundNotify +#define IDirectSoundFXGargle8 IDirectSoundFXGargle +#define IDirectSoundFXChorus8 IDirectSoundFXChorus +#define IDirectSoundFXFlanger8 IDirectSoundFXFlanger +#define IDirectSoundFXEcho8 IDirectSoundFXEcho +#define IDirectSoundFXDistortion8 IDirectSoundFXDistortion +#define IDirectSoundFXCompressor8 IDirectSoundFXCompressor +#define IDirectSoundFXParamEq8 IDirectSoundFXParamEq +#define IDirectSoundFXWavesReverb8 IDirectSoundFXWavesReverb +#define IDirectSoundFXI3DL2Reverb8 IDirectSoundFXI3DL2Reverb +#define IDirectSoundCaptureFXAec8 IDirectSoundCaptureFXAec +#define IDirectSoundCaptureFXNoiseSuppress8 IDirectSoundCaptureFXNoiseSuppress +#define IDirectSoundFullDuplex8 IDirectSoundFullDuplex + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +typedef struct IDirectSound *LPDIRECTSOUND; +typedef struct IDirectSoundBuffer *LPDIRECTSOUNDBUFFER; +typedef struct IDirectSound3DListener *LPDIRECTSOUND3DLISTENER; +typedef struct IDirectSound3DBuffer *LPDIRECTSOUND3DBUFFER; +typedef struct IDirectSoundCapture *LPDIRECTSOUNDCAPTURE; +typedef struct IDirectSoundCaptureBuffer *LPDIRECTSOUNDCAPTUREBUFFER; +typedef struct IDirectSoundNotify *LPDIRECTSOUNDNOTIFY; + +#if DIRECTSOUND_VERSION >= 0x0800 + +typedef struct IDirectSoundFXGargle *LPDIRECTSOUNDFXGARGLE; +typedef struct IDirectSoundFXChorus *LPDIRECTSOUNDFXCHORUS; +typedef struct IDirectSoundFXFlanger *LPDIRECTSOUNDFXFLANGER; +typedef struct IDirectSoundFXEcho *LPDIRECTSOUNDFXECHO; +typedef struct IDirectSoundFXDistortion *LPDIRECTSOUNDFXDISTORTION; +typedef struct IDirectSoundFXCompressor *LPDIRECTSOUNDFXCOMPRESSOR; +typedef struct IDirectSoundFXParamEq *LPDIRECTSOUNDFXPARAMEQ; +typedef struct IDirectSoundFXWavesReverb *LPDIRECTSOUNDFXWAVESREVERB; +typedef struct IDirectSoundFXI3DL2Reverb *LPDIRECTSOUNDFXI3DL2REVERB; +typedef struct IDirectSoundCaptureFXAec *LPDIRECTSOUNDCAPTUREFXAEC; +typedef struct IDirectSoundCaptureFXNoiseSuppress *LPDIRECTSOUNDCAPTUREFXNOISESUPPRESS; +typedef struct IDirectSoundFullDuplex *LPDIRECTSOUNDFULLDUPLEX; + +typedef struct IDirectSound8 *LPDIRECTSOUND8; +typedef struct IDirectSoundBuffer8 *LPDIRECTSOUNDBUFFER8; +typedef struct IDirectSound3DListener8 *LPDIRECTSOUND3DLISTENER8; +typedef struct IDirectSound3DBuffer8 *LPDIRECTSOUND3DBUFFER8; +typedef struct IDirectSoundCapture8 *LPDIRECTSOUNDCAPTURE8; +typedef struct IDirectSoundCaptureBuffer8 *LPDIRECTSOUNDCAPTUREBUFFER8; +typedef struct IDirectSoundNotify8 *LPDIRECTSOUNDNOTIFY8; +typedef struct IDirectSoundFXGargle8 *LPDIRECTSOUNDFXGARGLE8; +typedef struct IDirectSoundFXChorus8 *LPDIRECTSOUNDFXCHORUS8; +typedef struct IDirectSoundFXFlanger8 *LPDIRECTSOUNDFXFLANGER8; +typedef struct IDirectSoundFXEcho8 *LPDIRECTSOUNDFXECHO8; +typedef struct IDirectSoundFXDistortion8 *LPDIRECTSOUNDFXDISTORTION8; +typedef struct IDirectSoundFXCompressor8 *LPDIRECTSOUNDFXCOMPRESSOR8; +typedef struct IDirectSoundFXParamEq8 *LPDIRECTSOUNDFXPARAMEQ8; +typedef struct IDirectSoundFXWavesReverb8 *LPDIRECTSOUNDFXWAVESREVERB8; +typedef struct IDirectSoundFXI3DL2Reverb8 *LPDIRECTSOUNDFXI3DL2REVERB8; +typedef struct IDirectSoundCaptureFXAec8 *LPDIRECTSOUNDCAPTUREFXAEC8; +typedef struct IDirectSoundCaptureFXNoiseSuppress8 *LPDIRECTSOUNDCAPTUREFXNOISESUPPRESS8; +typedef struct IDirectSoundFullDuplex8 *LPDIRECTSOUNDFULLDUPLEX8; + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IID definitions for the unchanged DirectSound 8.0 interfaces +// + +#if DIRECTSOUND_VERSION >= 0x0800 + +#define IID_IDirectSoundCapture8 IID_IDirectSoundCapture +#define IID_IDirectSound3DListener8 IID_IDirectSound3DListener +#define IID_IDirectSound3DBuffer8 IID_IDirectSound3DBuffer +#define IID_IDirectSoundNotify8 IID_IDirectSoundNotify +#define IID_IDirectSoundFXGargle8 IID_IDirectSoundFXGargle +#define IID_IDirectSoundFXChorus8 IID_IDirectSoundFXChorus +#define IID_IDirectSoundFXFlanger8 IID_IDirectSoundFXFlanger +#define IID_IDirectSoundFXEcho8 IID_IDirectSoundFXEcho +#define IID_IDirectSoundFXDistortion8 IID_IDirectSoundFXDistortion +#define IID_IDirectSoundFXCompressor8 IID_IDirectSoundFXCompressor +#define IID_IDirectSoundFXParamEq8 IID_IDirectSoundFXParamEq +#define IID_IDirectSoundFXWavesReverb8 IID_IDirectSoundFXWavesReverb +#define IID_IDirectSoundFXI3DL2Reverb8 IID_IDirectSoundFXI3DL2Reverb +#define IID_IDirectSoundCaptureFXAec8 IID_IDirectSoundCaptureFXAec +#define IID_IDirectSoundCaptureFXNoiseSuppress8 IID_IDirectSoundCaptureFXNoiseSuppress +#define IID_IDirectSoundFullDuplex8 IID_IDirectSoundFullDuplex + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// Compatibility typedefs +// + +#ifndef _LPCWAVEFORMATEX_DEFINED +#define _LPCWAVEFORMATEX_DEFINED +typedef const WAVEFORMATEX *LPCWAVEFORMATEX; +#endif // _LPCWAVEFORMATEX_DEFINED + +#ifndef __LPCGUID_DEFINED__ +#define __LPCGUID_DEFINED__ +typedef const GUID *LPCGUID; +#endif // __LPCGUID_DEFINED__ + +typedef LPDIRECTSOUND *LPLPDIRECTSOUND; +typedef LPDIRECTSOUNDBUFFER *LPLPDIRECTSOUNDBUFFER; +typedef LPDIRECTSOUND3DLISTENER *LPLPDIRECTSOUND3DLISTENER; +typedef LPDIRECTSOUND3DBUFFER *LPLPDIRECTSOUND3DBUFFER; +typedef LPDIRECTSOUNDCAPTURE *LPLPDIRECTSOUNDCAPTURE; +typedef LPDIRECTSOUNDCAPTUREBUFFER *LPLPDIRECTSOUNDCAPTUREBUFFER; +typedef LPDIRECTSOUNDNOTIFY *LPLPDIRECTSOUNDNOTIFY; + +#if DIRECTSOUND_VERSION >= 0x0800 +typedef LPDIRECTSOUND8 *LPLPDIRECTSOUND8; +typedef LPDIRECTSOUNDBUFFER8 *LPLPDIRECTSOUNDBUFFER8; +typedef LPDIRECTSOUNDCAPTURE8 *LPLPDIRECTSOUNDCAPTURE8; +typedef LPDIRECTSOUNDCAPTUREBUFFER8 *LPLPDIRECTSOUNDCAPTUREBUFFER8; +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// Structures +// + +typedef struct _DSCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwMinSecondarySampleRate; + DWORD dwMaxSecondarySampleRate; + DWORD dwPrimaryBuffers; + DWORD dwMaxHwMixingAllBuffers; + DWORD dwMaxHwMixingStaticBuffers; + DWORD dwMaxHwMixingStreamingBuffers; + DWORD dwFreeHwMixingAllBuffers; + DWORD dwFreeHwMixingStaticBuffers; + DWORD dwFreeHwMixingStreamingBuffers; + DWORD dwMaxHw3DAllBuffers; + DWORD dwMaxHw3DStaticBuffers; + DWORD dwMaxHw3DStreamingBuffers; + DWORD dwFreeHw3DAllBuffers; + DWORD dwFreeHw3DStaticBuffers; + DWORD dwFreeHw3DStreamingBuffers; + DWORD dwTotalHwMemBytes; + DWORD dwFreeHwMemBytes; + DWORD dwMaxContigFreeHwMemBytes; + DWORD dwUnlockTransferRateHwBuffers; + DWORD dwPlayCpuOverheadSwBuffers; + DWORD dwReserved1; + DWORD dwReserved2; +} DSCAPS, *LPDSCAPS; + +typedef const DSCAPS *LPCDSCAPS; + +typedef struct _DSBCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwUnlockTransferRate; + DWORD dwPlayCpuOverhead; +} DSBCAPS, *LPDSBCAPS; + +typedef const DSBCAPS *LPCDSBCAPS; + +#if DIRECTSOUND_VERSION >= 0x0800 + + typedef struct _DSEFFECTDESC + { + DWORD dwSize; + DWORD dwFlags; + GUID guidDSFXClass; + DWORD_PTR dwReserved1; + DWORD_PTR dwReserved2; + } DSEFFECTDESC, *LPDSEFFECTDESC; + typedef const DSEFFECTDESC *LPCDSEFFECTDESC; + + #define DSFX_LOCHARDWARE 0x00000001 + #define DSFX_LOCSOFTWARE 0x00000002 + + enum + { + DSFXR_PRESENT, // 0 + DSFXR_LOCHARDWARE, // 1 + DSFXR_LOCSOFTWARE, // 2 + DSFXR_UNALLOCATED, // 3 + DSFXR_FAILED, // 4 + DSFXR_UNKNOWN, // 5 + DSFXR_SENDLOOP // 6 + }; + + typedef struct _DSCEFFECTDESC + { + DWORD dwSize; + DWORD dwFlags; + GUID guidDSCFXClass; + GUID guidDSCFXInstance; + DWORD dwReserved1; + DWORD dwReserved2; + } DSCEFFECTDESC, *LPDSCEFFECTDESC; + typedef const DSCEFFECTDESC *LPCDSCEFFECTDESC; + + #define DSCFX_LOCHARDWARE 0x00000001 + #define DSCFX_LOCSOFTWARE 0x00000002 + + #define DSCFXR_LOCHARDWARE 0x00000010 + #define DSCFXR_LOCSOFTWARE 0x00000020 + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +typedef struct _DSBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +#if DIRECTSOUND_VERSION >= 0x0700 + GUID guid3DAlgorithm; +#endif +} DSBUFFERDESC, *LPDSBUFFERDESC; + +typedef const DSBUFFERDESC *LPCDSBUFFERDESC; + +// Older version of this structure: + +typedef struct _DSBUFFERDESC1 +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSBUFFERDESC1, *LPDSBUFFERDESC1; + +typedef const DSBUFFERDESC1 *LPCDSBUFFERDESC1; + +typedef struct _DS3DBUFFER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + DWORD dwInsideConeAngle; + DWORD dwOutsideConeAngle; + D3DVECTOR vConeOrientation; + LONG lConeOutsideVolume; + D3DVALUE flMinDistance; + D3DVALUE flMaxDistance; + DWORD dwMode; +} DS3DBUFFER, *LPDS3DBUFFER; + +typedef const DS3DBUFFER *LPCDS3DBUFFER; + +typedef struct _DS3DLISTENER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + D3DVECTOR vOrientFront; + D3DVECTOR vOrientTop; + D3DVALUE flDistanceFactor; + D3DVALUE flRolloffFactor; + D3DVALUE flDopplerFactor; +} DS3DLISTENER, *LPDS3DLISTENER; + +typedef const DS3DLISTENER *LPCDS3DLISTENER; + +typedef struct _DSCCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwFormats; + DWORD dwChannels; +} DSCCAPS, *LPDSCCAPS; + +typedef const DSCCAPS *LPCDSCCAPS; + +typedef struct _DSCBUFFERDESC1 +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSCBUFFERDESC1, *LPDSCBUFFERDESC1; + +typedef struct _DSCBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +#if DIRECTSOUND_VERSION >= 0x0800 + DWORD dwFXCount; + LPDSCEFFECTDESC lpDSCFXDesc; +#endif +} DSCBUFFERDESC, *LPDSCBUFFERDESC; + +typedef const DSCBUFFERDESC *LPCDSCBUFFERDESC; + +typedef struct _DSCBCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; +} DSCBCAPS, *LPDSCBCAPS; + +typedef const DSCBCAPS *LPCDSCBCAPS; + +typedef struct _DSBPOSITIONNOTIFY +{ + DWORD dwOffset; + HANDLE hEventNotify; +} DSBPOSITIONNOTIFY, *LPDSBPOSITIONNOTIFY; + +typedef const DSBPOSITIONNOTIFY *LPCDSBPOSITIONNOTIFY; + +// +// DirectSound API +// + +typedef BOOL (CALLBACK *LPDSENUMCALLBACKA)(LPGUID, LPCSTR, LPCSTR, LPVOID); +typedef BOOL (CALLBACK *LPDSENUMCALLBACKW)(LPGUID, LPCWSTR, LPCWSTR, LPVOID); + +extern HRESULT WINAPI DirectSoundCreate(__in_opt LPCGUID pcGuidDevice, __deref_out LPDIRECTSOUND *ppDS, __null LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundEnumerateA(__in LPDSENUMCALLBACKA pDSEnumCallback, __in_opt LPVOID pContext); +extern HRESULT WINAPI DirectSoundEnumerateW(__in LPDSENUMCALLBACKW pDSEnumCallback, __in_opt LPVOID pContext); + +extern HRESULT WINAPI DirectSoundCaptureCreate(__in_opt LPCGUID pcGuidDevice, __deref_out LPDIRECTSOUNDCAPTURE *ppDSC, __null LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundCaptureEnumerateA(__in LPDSENUMCALLBACKA pDSEnumCallback, __in_opt LPVOID pContext); +extern HRESULT WINAPI DirectSoundCaptureEnumerateW(__in LPDSENUMCALLBACKW pDSEnumCallback, __in_opt LPVOID pContext); + +#if DIRECTSOUND_VERSION >= 0x0800 +extern HRESULT WINAPI DirectSoundCreate8(__in_opt LPCGUID pcGuidDevice, __deref_out LPDIRECTSOUND8 *ppDS8, __null LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundCaptureCreate8(__in_opt LPCGUID pcGuidDevice, __deref_out LPDIRECTSOUNDCAPTURE8 *ppDSC8, __null LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundFullDuplexCreate +( + __in_opt LPCGUID pcGuidCaptureDevice, + __in_opt LPCGUID pcGuidRenderDevice, + __in LPCDSCBUFFERDESC pcDSCBufferDesc, + __in LPCDSBUFFERDESC pcDSBufferDesc, + HWND hWnd, + DWORD dwLevel, + __deref_out LPDIRECTSOUNDFULLDUPLEX* ppDSFD, + __deref_out LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8, + __deref_out LPDIRECTSOUNDBUFFER8 *ppDSBuffer8, + __null LPUNKNOWN pUnkOuter +); +#define DirectSoundFullDuplexCreate8 DirectSoundFullDuplexCreate + +extern HRESULT WINAPI GetDeviceID(__in_opt LPCGUID pGuidSrc, __out LPGUID pGuidDest); +#endif // DIRECTSOUND_VERSION >= 0x0800 + +#ifdef UNICODE +#define LPDSENUMCALLBACK LPDSENUMCALLBACKW +#define DirectSoundEnumerate DirectSoundEnumerateW +#define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateW +#else // UNICODE +#define LPDSENUMCALLBACK LPDSENUMCALLBACKA +#define DirectSoundEnumerate DirectSoundEnumerateA +#define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateA +#endif // UNICODE + +// +// IUnknown +// + +#if !defined(__cplusplus) || defined(CINTERFACE) +#ifndef IUnknown_QueryInterface +#define IUnknown_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#endif // IUnknown_QueryInterface +#ifndef IUnknown_AddRef +#define IUnknown_AddRef(p) (p)->lpVtbl->AddRef(p) +#endif // IUnknown_AddRef +#ifndef IUnknown_Release +#define IUnknown_Release(p) (p)->lpVtbl->Release(p) +#endif // IUnknown_Release +#else // !defined(__cplusplus) || defined(CINTERFACE) +#ifndef IUnknown_QueryInterface +#define IUnknown_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#endif // IUnknown_QueryInterface +#ifndef IUnknown_AddRef +#define IUnknown_AddRef(p) (p)->AddRef() +#endif // IUnknown_AddRef +#ifndef IUnknown_Release +#define IUnknown_Release(p) (p)->Release() +#endif // IUnknown_Release +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#ifndef __IReferenceClock_INTERFACE_DEFINED__ +#define __IReferenceClock_INTERFACE_DEFINED__ + +typedef LONGLONG REFERENCE_TIME; +typedef REFERENCE_TIME *LPREFERENCE_TIME; + +DEFINE_GUID(IID_IReferenceClock, 0x56a86897, 0x0ad4, 0x11ce, 0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); + +#undef INTERFACE +#define INTERFACE IReferenceClock + +DECLARE_INTERFACE_(IReferenceClock, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IReferenceClock methods + STDMETHOD(GetTime) (THIS_ __out REFERENCE_TIME *pTime) PURE; + STDMETHOD(AdviseTime) (THIS_ REFERENCE_TIME rtBaseTime, REFERENCE_TIME rtStreamTime, + HANDLE hEvent, __out LPDWORD pdwAdviseCookie) PURE; + STDMETHOD(AdvisePeriodic) (THIS_ REFERENCE_TIME rtStartTime, REFERENCE_TIME rtPeriodTime, + HANDLE hSemaphore, __out LPDWORD pdwAdviseCookie) PURE; + STDMETHOD(Unadvise) (THIS_ DWORD dwAdviseCookie) PURE; +}; + +#endif // __IReferenceClock_INTERFACE_DEFINED__ + +#ifndef IReferenceClock_QueryInterface + +#define IReferenceClock_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IReferenceClock_AddRef(p) IUnknown_AddRef(p) +#define IReferenceClock_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IReferenceClock_GetTime(p,a) (p)->lpVtbl->GetTime(p,a) +#define IReferenceClock_AdviseTime(p,a,b,c,d) (p)->lpVtbl->AdviseTime(p,a,b,c,d) +#define IReferenceClock_AdvisePeriodic(p,a,b,c,d) (p)->lpVtbl->AdvisePeriodic(p,a,b,c,d) +#define IReferenceClock_Unadvise(p,a) (p)->lpVtbl->Unadvise(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IReferenceClock_GetTime(p,a) (p)->GetTime(a) +#define IReferenceClock_AdviseTime(p,a,b,c,d) (p)->AdviseTime(a,b,c,d) +#define IReferenceClock_AdvisePeriodic(p,a,b,c,d) (p)->AdvisePeriodic(a,b,c,d) +#define IReferenceClock_Unadvise(p,a) (p)->Unadvise(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // IReferenceClock_QueryInterface + +// +// IDirectSound +// + +DEFINE_GUID(IID_IDirectSound, 0x279AFA83, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound + +DECLARE_INTERFACE_(IDirectSound, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound methods + STDMETHOD(CreateSoundBuffer) (THIS_ __in LPCDSBUFFERDESC pcDSBufferDesc, __deref_out LPDIRECTSOUNDBUFFER *ppDSBuffer, __null LPUNKNOWN pUnkOuter) PURE; + STDMETHOD(GetCaps) (THIS_ __out LPDSCAPS pDSCaps) PURE; + STDMETHOD(DuplicateSoundBuffer) (THIS_ __in LPDIRECTSOUNDBUFFER pDSBufferOriginal, __deref_out LPDIRECTSOUNDBUFFER *ppDSBufferDuplicate) PURE; + STDMETHOD(SetCooperativeLevel) (THIS_ HWND hwnd, DWORD dwLevel) PURE; + STDMETHOD(Compact) (THIS) PURE; + STDMETHOD(GetSpeakerConfig) (THIS_ __out LPDWORD pdwSpeakerConfig) PURE; + STDMETHOD(SetSpeakerConfig) (THIS_ DWORD dwSpeakerConfig) PURE; + STDMETHOD(Initialize) (THIS_ __in_opt LPCGUID pcGuidDevice) PURE; +}; + +#define IDirectSound_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSound_AddRef(p) IUnknown_AddRef(p) +#define IDirectSound_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->lpVtbl->CreateSoundBuffer(p,a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->lpVtbl->DuplicateSoundBuffer(p,a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectSound_Compact(p) (p)->lpVtbl->Compact(p) +#define IDirectSound_GetSpeakerConfig(p,a) (p)->lpVtbl->GetSpeakerConfig(p,a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->lpVtbl->SetSpeakerConfig(p,b) +#define IDirectSound_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->CreateSoundBuffer(a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->DuplicateSoundBuffer(a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectSound_Compact(p) (p)->Compact() +#define IDirectSound_GetSpeakerConfig(p,a) (p)->GetSpeakerConfig(a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->SetSpeakerConfig(b) +#define IDirectSound_Initialize(p,a) (p)->Initialize(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSound8 +// + +DEFINE_GUID(IID_IDirectSound8, 0xC50A7E93, 0xF395, 0x4834, 0x9E, 0xF6, 0x7F, 0xA9, 0x9D, 0xE5, 0x09, 0x66); + +#undef INTERFACE +#define INTERFACE IDirectSound8 + +DECLARE_INTERFACE_(IDirectSound8, IDirectSound) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound methods + STDMETHOD(CreateSoundBuffer) (THIS_ __in LPCDSBUFFERDESC pcDSBufferDesc, __out LPDIRECTSOUNDBUFFER *ppDSBuffer, __null LPUNKNOWN pUnkOuter) PURE; + STDMETHOD(GetCaps) (THIS_ __out LPDSCAPS pDSCaps) PURE; + STDMETHOD(DuplicateSoundBuffer) (THIS_ __in LPDIRECTSOUNDBUFFER pDSBufferOriginal, __out LPDIRECTSOUNDBUFFER *ppDSBufferDuplicate) PURE; + STDMETHOD(SetCooperativeLevel) (THIS_ HWND hwnd, DWORD dwLevel) PURE; + STDMETHOD(Compact) (THIS) PURE; + STDMETHOD(GetSpeakerConfig) (THIS_ __out LPDWORD pdwSpeakerConfig) PURE; + STDMETHOD(SetSpeakerConfig) (THIS_ DWORD dwSpeakerConfig) PURE; + STDMETHOD(Initialize) (THIS_ __in_opt LPCGUID pcGuidDevice) PURE; + + // IDirectSound8 methods + STDMETHOD(VerifyCertification) (THIS_ __out LPDWORD pdwCertified) PURE; +}; + +#define IDirectSound8_QueryInterface(p,a,b) IDirectSound_QueryInterface(p,a,b) +#define IDirectSound8_AddRef(p) IDirectSound_AddRef(p) +#define IDirectSound8_Release(p) IDirectSound_Release(p) +#define IDirectSound8_CreateSoundBuffer(p,a,b,c) IDirectSound_CreateSoundBuffer(p,a,b,c) +#define IDirectSound8_GetCaps(p,a) IDirectSound_GetCaps(p,a) +#define IDirectSound8_DuplicateSoundBuffer(p,a,b) IDirectSound_DuplicateSoundBuffer(p,a,b) +#define IDirectSound8_SetCooperativeLevel(p,a,b) IDirectSound_SetCooperativeLevel(p,a,b) +#define IDirectSound8_Compact(p) IDirectSound_Compact(p) +#define IDirectSound8_GetSpeakerConfig(p,a) IDirectSound_GetSpeakerConfig(p,a) +#define IDirectSound8_SetSpeakerConfig(p,a) IDirectSound_SetSpeakerConfig(p,a) +#define IDirectSound8_Initialize(p,a) IDirectSound_Initialize(p,a) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound8_VerifyCertification(p,a) (p)->lpVtbl->VerifyCertification(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound8_VerifyCertification(p,a) (p)->VerifyCertification(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundBuffer +// + +DEFINE_GUID(IID_IDirectSoundBuffer, 0x279AFA85, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSoundBuffer + +DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundBuffer methods + STDMETHOD(GetCaps) (THIS_ __out LPDSBCAPS pDSBufferCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ __out_opt LPDWORD pdwCurrentPlayCursor, __out_opt LPDWORD pdwCurrentWriteCursor) PURE; + STDMETHOD(GetFormat) (THIS_ __out_bcount_opt(dwSizeAllocated) LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, __out_opt LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetVolume) (THIS_ __out LPLONG plVolume) PURE; + STDMETHOD(GetPan) (THIS_ __out LPLONG plPan) PURE; + STDMETHOD(GetFrequency) (THIS_ __out LPDWORD pdwFrequency) PURE; + STDMETHOD(GetStatus) (THIS_ __out LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ __in LPDIRECTSOUND pDirectSound, __in LPCDSBUFFERDESC pcDSBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, + __deref_out_bcount(*pdwAudioBytes1) LPVOID *ppvAudioPtr1, __out LPDWORD pdwAudioBytes1, + __deref_opt_out_bcount(*pdwAudioBytes2) LPVOID *ppvAudioPtr2, __out_opt LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Play) (THIS_ DWORD dwReserved1, DWORD dwPriority, DWORD dwFlags) PURE; + STDMETHOD(SetCurrentPosition) (THIS_ DWORD dwNewPosition) PURE; + STDMETHOD(SetFormat) (THIS_ __in LPCWAVEFORMATEX pcfxFormat) PURE; + STDMETHOD(SetVolume) (THIS_ LONG lVolume) PURE; + STDMETHOD(SetPan) (THIS_ LONG lPan) PURE; + STDMETHOD(SetFrequency) (THIS_ DWORD dwFrequency) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ __in_bcount(dwAudioBytes1) LPVOID pvAudioPtr1, DWORD dwAudioBytes1, + __in_bcount_opt(dwAudioBytes2) LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; + STDMETHOD(Restore) (THIS) PURE; +}; + +#define IDirectSoundBuffer_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundBuffer_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundBuffer_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->lpVtbl->GetVolume(p,a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->lpVtbl->GetPan(p,a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->lpVtbl->GetFrequency(p,a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->lpVtbl->Play(p,a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->lpVtbl->SetCurrentPosition(p,a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->lpVtbl->SetVolume(p,a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->lpVtbl->SetPan(p,a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->lpVtbl->SetFrequency(p,a) +#define IDirectSoundBuffer_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->lpVtbl->Restore(p) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->GetCurrentPosition(a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->GetFormat(a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->GetVolume(a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->GetPan(a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->GetFrequency(a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->GetStatus(a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->Lock(a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->Play(a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->SetCurrentPosition(a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->SetFormat(a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->SetVolume(a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->SetPan(a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->SetFrequency(a) +#define IDirectSoundBuffer_Stop(p) (p)->Stop() +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->Unlock(a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->Restore() +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundBuffer8 +// + +DEFINE_GUID(IID_IDirectSoundBuffer8, 0x6825a449, 0x7524, 0x4d82, 0x92, 0x0f, 0x50, 0xe3, 0x6a, 0xb3, 0xab, 0x1e); + +#undef INTERFACE +#define INTERFACE IDirectSoundBuffer8 + +DECLARE_INTERFACE_(IDirectSoundBuffer8, IDirectSoundBuffer) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundBuffer methods + STDMETHOD(GetCaps) (THIS_ __out LPDSBCAPS pDSBufferCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ __out_opt LPDWORD pdwCurrentPlayCursor, __out_opt LPDWORD pdwCurrentWriteCursor) PURE; + STDMETHOD(GetFormat) (THIS_ __out_bcount_opt(dwSizeAllocated) LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, __out_opt LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetVolume) (THIS_ __out LPLONG plVolume) PURE; + STDMETHOD(GetPan) (THIS_ __out LPLONG plPan) PURE; + STDMETHOD(GetFrequency) (THIS_ __out LPDWORD pdwFrequency) PURE; + STDMETHOD(GetStatus) (THIS_ __out LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ __in LPDIRECTSOUND pDirectSound, __in LPCDSBUFFERDESC pcDSBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, + __deref_out_bcount(*pdwAudioBytes1) LPVOID *ppvAudioPtr1, __out LPDWORD pdwAudioBytes1, + __deref_opt_out_bcount(*pdwAudioBytes2) LPVOID *ppvAudioPtr2, __out_opt LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Play) (THIS_ DWORD dwReserved1, DWORD dwPriority, DWORD dwFlags) PURE; + STDMETHOD(SetCurrentPosition) (THIS_ DWORD dwNewPosition) PURE; + STDMETHOD(SetFormat) (THIS_ __in LPCWAVEFORMATEX pcfxFormat) PURE; + STDMETHOD(SetVolume) (THIS_ LONG lVolume) PURE; + STDMETHOD(SetPan) (THIS_ LONG lPan) PURE; + STDMETHOD(SetFrequency) (THIS_ DWORD dwFrequency) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ __in_bcount(dwAudioBytes1) LPVOID pvAudioPtr1, DWORD dwAudioBytes1, + __in_bcount_opt(dwAudioBytes2) LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; + STDMETHOD(Restore) (THIS) PURE; + + // IDirectSoundBuffer8 methods + STDMETHOD(SetFX) (THIS_ DWORD dwEffectsCount, __in_ecount_opt(dwEffectsCount) LPDSEFFECTDESC pDSFXDesc, __out_ecount_opt(dwEffectsCount) LPDWORD pdwResultCodes) PURE; + STDMETHOD(AcquireResources) (THIS_ DWORD dwFlags, DWORD dwEffectsCount, __out_ecount(dwEffectsCount) LPDWORD pdwResultCodes) PURE; + STDMETHOD(GetObjectInPath) (THIS_ __in REFGUID rguidObject, DWORD dwIndex, __in REFGUID rguidInterface, __deref_out LPVOID *ppObject) PURE; +}; + +// Special GUID meaning "select all objects" for use in GetObjectInPath() +DEFINE_GUID(GUID_All_Objects, 0xaa114de5, 0xc262, 0x4169, 0xa1, 0xc8, 0x23, 0xd6, 0x98, 0xcc, 0x73, 0xb5); + +#define IDirectSoundBuffer8_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundBuffer8_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundBuffer8_Release(p) IUnknown_Release(p) + +#define IDirectSoundBuffer8_GetCaps(p,a) IDirectSoundBuffer_GetCaps(p,a) +#define IDirectSoundBuffer8_GetCurrentPosition(p,a,b) IDirectSoundBuffer_GetCurrentPosition(p,a,b) +#define IDirectSoundBuffer8_GetFormat(p,a,b,c) IDirectSoundBuffer_GetFormat(p,a,b,c) +#define IDirectSoundBuffer8_GetVolume(p,a) IDirectSoundBuffer_GetVolume(p,a) +#define IDirectSoundBuffer8_GetPan(p,a) IDirectSoundBuffer_GetPan(p,a) +#define IDirectSoundBuffer8_GetFrequency(p,a) IDirectSoundBuffer_GetFrequency(p,a) +#define IDirectSoundBuffer8_GetStatus(p,a) IDirectSoundBuffer_GetStatus(p,a) +#define IDirectSoundBuffer8_Initialize(p,a,b) IDirectSoundBuffer_Initialize(p,a,b) +#define IDirectSoundBuffer8_Lock(p,a,b,c,d,e,f,g) IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundBuffer8_Play(p,a,b,c) IDirectSoundBuffer_Play(p,a,b,c) +#define IDirectSoundBuffer8_SetCurrentPosition(p,a) IDirectSoundBuffer_SetCurrentPosition(p,a) +#define IDirectSoundBuffer8_SetFormat(p,a) IDirectSoundBuffer_SetFormat(p,a) +#define IDirectSoundBuffer8_SetVolume(p,a) IDirectSoundBuffer_SetVolume(p,a) +#define IDirectSoundBuffer8_SetPan(p,a) IDirectSoundBuffer_SetPan(p,a) +#define IDirectSoundBuffer8_SetFrequency(p,a) IDirectSoundBuffer_SetFrequency(p,a) +#define IDirectSoundBuffer8_Stop(p) IDirectSoundBuffer_Stop(p) +#define IDirectSoundBuffer8_Unlock(p,a,b,c,d) IDirectSoundBuffer_Unlock(p,a,b,c,d) +#define IDirectSoundBuffer8_Restore(p) IDirectSoundBuffer_Restore(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer8_SetFX(p,a,b,c) (p)->lpVtbl->SetFX(p,a,b,c) +#define IDirectSoundBuffer8_AcquireResources(p,a,b,c) (p)->lpVtbl->AcquireResources(p,a,b,c) +#define IDirectSoundBuffer8_GetObjectInPath(p,a,b,c,d) (p)->lpVtbl->GetObjectInPath(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer8_SetFX(p,a,b,c) (p)->SetFX(a,b,c) +#define IDirectSoundBuffer8_AcquireResources(p,a,b,c) (p)->AcquireResources(a,b,c) +#define IDirectSoundBuffer8_GetObjectInPath(p,a,b,c,d) (p)->GetObjectInPath(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSound3DListener +// + +DEFINE_GUID(IID_IDirectSound3DListener, 0x279AFA84, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound3DListener + +DECLARE_INTERFACE_(IDirectSound3DListener, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound3DListener methods + STDMETHOD(GetAllParameters) (THIS_ __out LPDS3DLISTENER pListener) PURE; + STDMETHOD(GetDistanceFactor) (THIS_ __out D3DVALUE* pflDistanceFactor) PURE; + STDMETHOD(GetDopplerFactor) (THIS_ __out D3DVALUE* pflDopplerFactor) PURE; + STDMETHOD(GetOrientation) (THIS_ __out D3DVECTOR* pvOrientFront, __out D3DVECTOR* pvOrientTop) PURE; + STDMETHOD(GetPosition) (THIS_ __out D3DVECTOR* pvPosition) PURE; + STDMETHOD(GetRolloffFactor) (THIS_ __out D3DVALUE* pflRolloffFactor) PURE; + STDMETHOD(GetVelocity) (THIS_ __out D3DVECTOR* pvVelocity) PURE; + STDMETHOD(SetAllParameters) (THIS_ __in LPCDS3DLISTENER pcListener, DWORD dwApply) PURE; + STDMETHOD(SetDistanceFactor) (THIS_ D3DVALUE flDistanceFactor, DWORD dwApply) PURE; + STDMETHOD(SetDopplerFactor) (THIS_ D3DVALUE flDopplerFactor, DWORD dwApply) PURE; + STDMETHOD(SetOrientation) (THIS_ D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront, + D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop, DWORD dwApply) PURE; + STDMETHOD(SetPosition) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(SetRolloffFactor) (THIS_ D3DVALUE flRolloffFactor, DWORD dwApply) PURE; + STDMETHOD(SetVelocity) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(CommitDeferredSettings) (THIS) PURE; +}; + +#define IDirectSound3DListener_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSound3DListener_AddRef(p) IUnknown_AddRef(p) +#define IDirectSound3DListener_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->lpVtbl->GetDistanceFactor(p,a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->lpVtbl->GetDopplerFactor(p,a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->lpVtbl->GetOrientation(p,a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->lpVtbl->GetRolloffFactor(p,a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->lpVtbl->SetDistanceFactor(p,a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->lpVtbl->SetDopplerFactor(p,a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->lpVtbl->SetOrientation(p,a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->lpVtbl->SetRolloffFactor(p,a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->lpVtbl->CommitDeferredSettings(p) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->GetDistanceFactor(a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->GetDopplerFactor(a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->GetOrientation(a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->GetRolloffFactor(a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->SetDistanceFactor(a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->SetDopplerFactor(a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->SetOrientation(a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->SetRolloffFactor(a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->CommitDeferredSettings() +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSound3DBuffer +// + +DEFINE_GUID(IID_IDirectSound3DBuffer, 0x279AFA86, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound3DBuffer + +DECLARE_INTERFACE_(IDirectSound3DBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound3DBuffer methods + STDMETHOD(GetAllParameters) (THIS_ __out LPDS3DBUFFER pDs3dBuffer) PURE; + STDMETHOD(GetConeAngles) (THIS_ __out LPDWORD pdwInsideConeAngle, __out LPDWORD pdwOutsideConeAngle) PURE; + STDMETHOD(GetConeOrientation) (THIS_ __out D3DVECTOR* pvOrientation) PURE; + STDMETHOD(GetConeOutsideVolume) (THIS_ __out LPLONG plConeOutsideVolume) PURE; + STDMETHOD(GetMaxDistance) (THIS_ __out D3DVALUE* pflMaxDistance) PURE; + STDMETHOD(GetMinDistance) (THIS_ __out D3DVALUE* pflMinDistance) PURE; + STDMETHOD(GetMode) (THIS_ __out LPDWORD pdwMode) PURE; + STDMETHOD(GetPosition) (THIS_ __out D3DVECTOR* pvPosition) PURE; + STDMETHOD(GetVelocity) (THIS_ __out D3DVECTOR* pvVelocity) PURE; + STDMETHOD(SetAllParameters) (THIS_ __in LPCDS3DBUFFER pcDs3dBuffer, DWORD dwApply) PURE; + STDMETHOD(SetConeAngles) (THIS_ DWORD dwInsideConeAngle, DWORD dwOutsideConeAngle, DWORD dwApply) PURE; + STDMETHOD(SetConeOrientation) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(SetConeOutsideVolume) (THIS_ LONG lConeOutsideVolume, DWORD dwApply) PURE; + STDMETHOD(SetMaxDistance) (THIS_ D3DVALUE flMaxDistance, DWORD dwApply) PURE; + STDMETHOD(SetMinDistance) (THIS_ D3DVALUE flMinDistance, DWORD dwApply) PURE; + STDMETHOD(SetMode) (THIS_ DWORD dwMode, DWORD dwApply) PURE; + STDMETHOD(SetPosition) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(SetVelocity) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; +}; + +#define IDirectSound3DBuffer_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSound3DBuffer_AddRef(p) IUnknown_AddRef(p) +#define IDirectSound3DBuffer_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->lpVtbl->GetConeAngles(p,a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->lpVtbl->GetConeOrientation(p,a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->lpVtbl->GetConeOutsideVolume(p,a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->lpVtbl->GetMinDistance(p,a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->lpVtbl->GetMaxDistance(p,a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->lpVtbl->GetMode(p,a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->lpVtbl->SetConeAngles(p,a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->lpVtbl->SetConeOrientation(p,a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b) (p)->lpVtbl->SetConeOutsideVolume(p,a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->lpVtbl->SetMinDistance(p,a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->lpVtbl->SetMaxDistance(p,a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->lpVtbl->SetMode(p,a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->GetConeAngles(a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->GetConeOrientation(a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->GetConeOutsideVolume(a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->GetMinDistance(a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->GetMaxDistance(a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->GetMode(a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->SetConeAngles(a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->SetConeOrientation(a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b) (p)->SetConeOutsideVolume(a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->SetMinDistance(a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->SetMaxDistance(a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->SetMode(a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCapture +// + +DEFINE_GUID(IID_IDirectSoundCapture, 0xb0210781, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundCapture + +DECLARE_INTERFACE_(IDirectSoundCapture, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCapture methods + STDMETHOD(CreateCaptureBuffer) (THIS_ __in LPCDSCBUFFERDESC pcDSCBufferDesc, __deref_out LPDIRECTSOUNDCAPTUREBUFFER *ppDSCBuffer, __null LPUNKNOWN pUnkOuter) PURE; + STDMETHOD(GetCaps) (THIS_ __out LPDSCCAPS pDSCCaps) PURE; + STDMETHOD(Initialize) (THIS_ __in_opt LPCGUID pcGuidDevice) PURE; +}; + +#define IDirectSoundCapture_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCapture_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCapture_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCapture_CreateCaptureBuffer(p,a,b,c) (p)->lpVtbl->CreateCaptureBuffer(p,a,b,c) +#define IDirectSoundCapture_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundCapture_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCapture_CreateCaptureBuffer(p,a,b,c) (p)->CreateCaptureBuffer(a,b,c) +#define IDirectSoundCapture_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundCapture_Initialize(p,a) (p)->Initialize(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCaptureBuffer +// + +DEFINE_GUID(IID_IDirectSoundCaptureBuffer, 0xb0210782, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureBuffer + +DECLARE_INTERFACE_(IDirectSoundCaptureBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureBuffer methods + STDMETHOD(GetCaps) (THIS_ __out LPDSCBCAPS pDSCBCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ __out_opt LPDWORD pdwCapturePosition, __out_opt LPDWORD pdwReadPosition) PURE; + STDMETHOD(GetFormat) (THIS_ __out_bcount_opt(dwSizeAllocated) LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, __out_opt LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetStatus) (THIS_ __out LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ __in LPDIRECTSOUNDCAPTURE pDirectSoundCapture, __in LPCDSCBUFFERDESC pcDSCBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, + __deref_out_bcount(*pdwAudioBytes1) LPVOID *ppvAudioPtr1, __out LPDWORD pdwAudioBytes1, + __deref_opt_out_bcount(*pdwAudioBytes2) LPVOID *ppvAudioPtr2, __out_opt LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Start) (THIS_ DWORD dwFlags) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ __in_bcount(dwAudioBytes1) LPVOID pvAudioPtr1, DWORD dwAudioBytes1, + __in_bcount_opt(dwAudioBytes2) LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; +}; + +#define IDirectSoundCaptureBuffer_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureBuffer_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureBuffer_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) +#define IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) +#define IDirectSoundCaptureBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) +#define IDirectSoundCaptureBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer_Start(p,a) (p)->lpVtbl->Start(p,a) +#define IDirectSoundCaptureBuffer_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) (p)->GetCurrentPosition(a,b) +#define IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) (p)->GetFormat(a,b,c) +#define IDirectSoundCaptureBuffer_GetStatus(p,a) (p)->GetStatus(a) +#define IDirectSoundCaptureBuffer_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) (p)->Lock(a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer_Start(p,a) (p)->Start(a) +#define IDirectSoundCaptureBuffer_Stop(p) (p)->Stop() +#define IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) (p)->Unlock(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundCaptureBuffer8 +// + +DEFINE_GUID(IID_IDirectSoundCaptureBuffer8, 0x990df4, 0xdbb, 0x4872, 0x83, 0x3e, 0x6d, 0x30, 0x3e, 0x80, 0xae, 0xb6); + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureBuffer8 + +DECLARE_INTERFACE_(IDirectSoundCaptureBuffer8, IDirectSoundCaptureBuffer) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureBuffer methods + STDMETHOD(GetCaps) (THIS_ __out LPDSCBCAPS pDSCBCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ __out_opt LPDWORD pdwCapturePosition, __out_opt LPDWORD pdwReadPosition) PURE; + STDMETHOD(GetFormat) (THIS_ __out_bcount_opt(dwSizeAllocated) LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, __out_opt LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetStatus) (THIS_ __out LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ __in LPDIRECTSOUNDCAPTURE pDirectSoundCapture, __in LPCDSCBUFFERDESC pcDSCBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, + __deref_out_bcount(*pdwAudioBytes1) LPVOID *ppvAudioPtr1, __out LPDWORD pdwAudioBytes1, + __deref_opt_out_bcount(*pdwAudioBytes2) LPVOID *ppvAudioPtr2, __out_opt LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Start) (THIS_ DWORD dwFlags) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ __in_bcount(dwAudioBytes1) LPVOID pvAudioPtr1, DWORD dwAudioBytes1, + __in_bcount_opt(dwAudioBytes2) LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; + + // IDirectSoundCaptureBuffer8 methods + STDMETHOD(GetObjectInPath) (THIS_ __in REFGUID rguidObject, DWORD dwIndex, __in REFGUID rguidInterface, __deref_out LPVOID *ppObject) PURE; + STDMETHOD(GetFXStatus) (DWORD dwEffectsCount, __out_ecount(dwEffectsCount) LPDWORD pdwFXStatus) PURE; +}; + +#define IDirectSoundCaptureBuffer8_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureBuffer8_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureBuffer8_Release(p) IUnknown_Release(p) + +#define IDirectSoundCaptureBuffer8_GetCaps(p,a) IDirectSoundCaptureBuffer_GetCaps(p,a) +#define IDirectSoundCaptureBuffer8_GetCurrentPosition(p,a,b) IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) +#define IDirectSoundCaptureBuffer8_GetFormat(p,a,b,c) IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) +#define IDirectSoundCaptureBuffer8_GetStatus(p,a) IDirectSoundCaptureBuffer_GetStatus(p,a) +#define IDirectSoundCaptureBuffer8_Initialize(p,a,b) IDirectSoundCaptureBuffer_Initialize(p,a,b) +#define IDirectSoundCaptureBuffer8_Lock(p,a,b,c,d,e,f,g) IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer8_Start(p,a) IDirectSoundCaptureBuffer_Start(p,a) +#define IDirectSoundCaptureBuffer8_Stop(p) IDirectSoundCaptureBuffer_Stop(p)) +#define IDirectSoundCaptureBuffer8_Unlock(p,a,b,c,d) IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer8_GetObjectInPath(p,a,b,c,d) (p)->lpVtbl->GetObjectInPath(p,a,b,c,d) +#define IDirectSoundCaptureBuffer8_GetFXStatus(p,a,b) (p)->lpVtbl->GetFXStatus(p,a,b) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer8_GetObjectInPath(p,a,b,c,d) (p)->GetObjectInPath(a,b,c,d) +#define IDirectSoundCaptureBuffer8_GetFXStatus(p,a,b) (p)->GetFXStatus(a,b) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundNotify +// + +DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundNotify + +DECLARE_INTERFACE_(IDirectSoundNotify, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundNotify methods + STDMETHOD(SetNotificationPositions) (THIS_ DWORD dwPositionNotifies, __in_ecount(dwPositionNotifies) LPCDSBPOSITIONNOTIFY pcPositionNotifies) PURE; +}; + +#define IDirectSoundNotify_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundNotify_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundNotify_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundNotify_SetNotificationPositions(p,a,b) (p)->lpVtbl->SetNotificationPositions(p,a,b) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundNotify_SetNotificationPositions(p,a,b) (p)->SetNotificationPositions(a,b) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IKsPropertySet +// + +#ifndef _IKsPropertySet_ +#define _IKsPropertySet_ + +#ifdef __cplusplus +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +struct IKsPropertySet; +#endif // __cplusplus + +typedef struct IKsPropertySet *LPKSPROPERTYSET; + +#define KSPROPERTY_SUPPORT_GET 0x00000001 +#define KSPROPERTY_SUPPORT_SET 0x00000002 + +DEFINE_GUID(IID_IKsPropertySet, 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93); + +#undef INTERFACE +#define INTERFACE IKsPropertySet + +DECLARE_INTERFACE_(IKsPropertySet, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IKsPropertySet methods + STDMETHOD(Get) (THIS_ __in REFGUID rguidPropSet, ULONG ulId, __in_bcount(ulInstanceLength) LPVOID pInstanceData, ULONG ulInstanceLength, + __out_bcount(ulDataLength) LPVOID pPropertyData, ULONG ulDataLength, __out PULONG pulBytesReturned) PURE; + STDMETHOD(Set) (THIS_ __in REFGUID rguidPropSet, ULONG ulId, __in_bcount(ulInstanceLength) LPVOID pInstanceData, ULONG ulInstanceLength, + __in_bcount(ulDataLength) LPVOID pPropertyData, ULONG ulDataLength) PURE; + STDMETHOD(QuerySupport) (THIS_ __in REFGUID rguidPropSet, ULONG ulId, __out PULONG pulTypeSupport) PURE; +}; + +#define IKsPropertySet_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IKsPropertySet_AddRef(p) IUnknown_AddRef(p) +#define IKsPropertySet_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IKsPropertySet_Get(p,a,b,c,d,e,f,g) (p)->lpVtbl->Get(p,a,b,c,d,e,f,g) +#define IKsPropertySet_Set(p,a,b,c,d,e,f) (p)->lpVtbl->Set(p,a,b,c,d,e,f) +#define IKsPropertySet_QuerySupport(p,a,b,c) (p)->lpVtbl->QuerySupport(p,a,b,c) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IKsPropertySet_Get(p,a,b,c,d,e,f,g) (p)->Get(a,b,c,d,e,f,g) +#define IKsPropertySet_Set(p,a,b,c,d,e,f) (p)->Set(a,b,c,d,e,f) +#define IKsPropertySet_QuerySupport(p,a,b,c) (p)->QuerySupport(a,b,c) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // _IKsPropertySet_ + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundFXGargle +// + +DEFINE_GUID(IID_IDirectSoundFXGargle, 0xd616f352, 0xd622, 0x11ce, 0xaa, 0xc5, 0x00, 0x20, 0xaf, 0x0b, 0x99, 0xa3); + +typedef struct _DSFXGargle +{ + DWORD dwRateHz; // Rate of modulation in hz + DWORD dwWaveShape; // DSFXGARGLE_WAVE_xxx +} DSFXGargle, *LPDSFXGargle; + +#define DSFXGARGLE_WAVE_TRIANGLE 0 +#define DSFXGARGLE_WAVE_SQUARE 1 + +typedef const DSFXGargle *LPCDSFXGargle; + +#define DSFXGARGLE_RATEHZ_MIN 1 +#define DSFXGARGLE_RATEHZ_MAX 1000 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXGargle + +DECLARE_INTERFACE_(IDirectSoundFXGargle, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXGargle methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXGargle pcDsFxGargle) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXGargle pDsFxGargle) PURE; +}; + +#define IDirectSoundFXGargle_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXGargle_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXGargle_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXGargle_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXGargle_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXGargle_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXGargle_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXChorus +// + +DEFINE_GUID(IID_IDirectSoundFXChorus, 0x880842e3, 0x145f, 0x43e6, 0xa9, 0x34, 0xa7, 0x18, 0x06, 0xe5, 0x05, 0x47); + +typedef struct _DSFXChorus +{ + FLOAT fWetDryMix; + FLOAT fDepth; + FLOAT fFeedback; + FLOAT fFrequency; + LONG lWaveform; // LFO shape; DSFXCHORUS_WAVE_xxx + FLOAT fDelay; + LONG lPhase; +} DSFXChorus, *LPDSFXChorus; + +typedef const DSFXChorus *LPCDSFXChorus; + +#define DSFXCHORUS_WAVE_TRIANGLE 0 +#define DSFXCHORUS_WAVE_SIN 1 + +#define DSFXCHORUS_WETDRYMIX_MIN 0.0f +#define DSFXCHORUS_WETDRYMIX_MAX 100.0f +#define DSFXCHORUS_DEPTH_MIN 0.0f +#define DSFXCHORUS_DEPTH_MAX 100.0f +#define DSFXCHORUS_FEEDBACK_MIN -99.0f +#define DSFXCHORUS_FEEDBACK_MAX 99.0f +#define DSFXCHORUS_FREQUENCY_MIN 0.0f +#define DSFXCHORUS_FREQUENCY_MAX 10.0f +#define DSFXCHORUS_DELAY_MIN 0.0f +#define DSFXCHORUS_DELAY_MAX 20.0f +#define DSFXCHORUS_PHASE_MIN 0 +#define DSFXCHORUS_PHASE_MAX 4 + +#define DSFXCHORUS_PHASE_NEG_180 0 +#define DSFXCHORUS_PHASE_NEG_90 1 +#define DSFXCHORUS_PHASE_ZERO 2 +#define DSFXCHORUS_PHASE_90 3 +#define DSFXCHORUS_PHASE_180 4 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXChorus + +DECLARE_INTERFACE_(IDirectSoundFXChorus, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXChorus methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXChorus pcDsFxChorus) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXChorus pDsFxChorus) PURE; +}; + +#define IDirectSoundFXChorus_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXChorus_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXChorus_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXChorus_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXChorus_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXChorus_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXChorus_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXFlanger +// + +DEFINE_GUID(IID_IDirectSoundFXFlanger, 0x903e9878, 0x2c92, 0x4072, 0x9b, 0x2c, 0xea, 0x68, 0xf5, 0x39, 0x67, 0x83); + +typedef struct _DSFXFlanger +{ + FLOAT fWetDryMix; + FLOAT fDepth; + FLOAT fFeedback; + FLOAT fFrequency; + LONG lWaveform; + FLOAT fDelay; + LONG lPhase; +} DSFXFlanger, *LPDSFXFlanger; + +typedef const DSFXFlanger *LPCDSFXFlanger; + +#define DSFXFLANGER_WAVE_TRIANGLE 0 +#define DSFXFLANGER_WAVE_SIN 1 + +#define DSFXFLANGER_WETDRYMIX_MIN 0.0f +#define DSFXFLANGER_WETDRYMIX_MAX 100.0f +#define DSFXFLANGER_FREQUENCY_MIN 0.0f +#define DSFXFLANGER_FREQUENCY_MAX 10.0f +#define DSFXFLANGER_DEPTH_MIN 0.0f +#define DSFXFLANGER_DEPTH_MAX 100.0f +#define DSFXFLANGER_PHASE_MIN 0 +#define DSFXFLANGER_PHASE_MAX 4 +#define DSFXFLANGER_FEEDBACK_MIN -99.0f +#define DSFXFLANGER_FEEDBACK_MAX 99.0f +#define DSFXFLANGER_DELAY_MIN 0.0f +#define DSFXFLANGER_DELAY_MAX 4.0f + +#define DSFXFLANGER_PHASE_NEG_180 0 +#define DSFXFLANGER_PHASE_NEG_90 1 +#define DSFXFLANGER_PHASE_ZERO 2 +#define DSFXFLANGER_PHASE_90 3 +#define DSFXFLANGER_PHASE_180 4 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXFlanger + +DECLARE_INTERFACE_(IDirectSoundFXFlanger, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXFlanger methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXFlanger pcDsFxFlanger) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXFlanger pDsFxFlanger) PURE; +}; + +#define IDirectSoundFXFlanger_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXFlanger_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXFlanger_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXFlanger_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXFlanger_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXFlanger_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXFlanger_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXEcho +// + +DEFINE_GUID(IID_IDirectSoundFXEcho, 0x8bd28edf, 0x50db, 0x4e92, 0xa2, 0xbd, 0x44, 0x54, 0x88, 0xd1, 0xed, 0x42); + +typedef struct _DSFXEcho +{ + FLOAT fWetDryMix; + FLOAT fFeedback; + FLOAT fLeftDelay; + FLOAT fRightDelay; + LONG lPanDelay; +} DSFXEcho, *LPDSFXEcho; + +typedef const DSFXEcho *LPCDSFXEcho; + +#define DSFXECHO_WETDRYMIX_MIN 0.0f +#define DSFXECHO_WETDRYMIX_MAX 100.0f +#define DSFXECHO_FEEDBACK_MIN 0.0f +#define DSFXECHO_FEEDBACK_MAX 100.0f +#define DSFXECHO_LEFTDELAY_MIN 1.0f +#define DSFXECHO_LEFTDELAY_MAX 2000.0f +#define DSFXECHO_RIGHTDELAY_MIN 1.0f +#define DSFXECHO_RIGHTDELAY_MAX 2000.0f +#define DSFXECHO_PANDELAY_MIN 0 +#define DSFXECHO_PANDELAY_MAX 1 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXEcho + +DECLARE_INTERFACE_(IDirectSoundFXEcho, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXEcho methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXEcho pcDsFxEcho) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXEcho pDsFxEcho) PURE; +}; + +#define IDirectSoundFXEcho_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXEcho_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXEcho_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXEcho_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXEcho_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXEcho_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXEcho_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXDistortion +// + +DEFINE_GUID(IID_IDirectSoundFXDistortion, 0x8ecf4326, 0x455f, 0x4d8b, 0xbd, 0xa9, 0x8d, 0x5d, 0x3e, 0x9e, 0x3e, 0x0b); + +typedef struct _DSFXDistortion +{ + FLOAT fGain; + FLOAT fEdge; + FLOAT fPostEQCenterFrequency; + FLOAT fPostEQBandwidth; + FLOAT fPreLowpassCutoff; +} DSFXDistortion, *LPDSFXDistortion; + +typedef const DSFXDistortion *LPCDSFXDistortion; + +#define DSFXDISTORTION_GAIN_MIN -60.0f +#define DSFXDISTORTION_GAIN_MAX 0.0f +#define DSFXDISTORTION_EDGE_MIN 0.0f +#define DSFXDISTORTION_EDGE_MAX 100.0f +#define DSFXDISTORTION_POSTEQCENTERFREQUENCY_MIN 100.0f +#define DSFXDISTORTION_POSTEQCENTERFREQUENCY_MAX 8000.0f +#define DSFXDISTORTION_POSTEQBANDWIDTH_MIN 100.0f +#define DSFXDISTORTION_POSTEQBANDWIDTH_MAX 8000.0f +#define DSFXDISTORTION_PRELOWPASSCUTOFF_MIN 100.0f +#define DSFXDISTORTION_PRELOWPASSCUTOFF_MAX 8000.0f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXDistortion + +DECLARE_INTERFACE_(IDirectSoundFXDistortion, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXDistortion methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXDistortion pcDsFxDistortion) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXDistortion pDsFxDistortion) PURE; +}; + +#define IDirectSoundFXDistortion_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXDistortion_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXDistortion_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXDistortion_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXDistortion_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXDistortion_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXDistortion_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXCompressor +// + +DEFINE_GUID(IID_IDirectSoundFXCompressor, 0x4bbd1154, 0x62f6, 0x4e2c, 0xa1, 0x5c, 0xd3, 0xb6, 0xc4, 0x17, 0xf7, 0xa0); + +typedef struct _DSFXCompressor +{ + FLOAT fGain; + FLOAT fAttack; + FLOAT fRelease; + FLOAT fThreshold; + FLOAT fRatio; + FLOAT fPredelay; +} DSFXCompressor, *LPDSFXCompressor; + +typedef const DSFXCompressor *LPCDSFXCompressor; + +#define DSFXCOMPRESSOR_GAIN_MIN -60.0f +#define DSFXCOMPRESSOR_GAIN_MAX 60.0f +#define DSFXCOMPRESSOR_ATTACK_MIN 0.01f +#define DSFXCOMPRESSOR_ATTACK_MAX 500.0f +#define DSFXCOMPRESSOR_RELEASE_MIN 50.0f +#define DSFXCOMPRESSOR_RELEASE_MAX 3000.0f +#define DSFXCOMPRESSOR_THRESHOLD_MIN -60.0f +#define DSFXCOMPRESSOR_THRESHOLD_MAX 0.0f +#define DSFXCOMPRESSOR_RATIO_MIN 1.0f +#define DSFXCOMPRESSOR_RATIO_MAX 100.0f +#define DSFXCOMPRESSOR_PREDELAY_MIN 0.0f +#define DSFXCOMPRESSOR_PREDELAY_MAX 4.0f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXCompressor + +DECLARE_INTERFACE_(IDirectSoundFXCompressor, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXCompressor methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXCompressor pcDsFxCompressor) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXCompressor pDsFxCompressor) PURE; +}; + +#define IDirectSoundFXCompressor_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXCompressor_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXCompressor_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXCompressor_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXCompressor_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXCompressor_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXCompressor_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXParamEq +// + +DEFINE_GUID(IID_IDirectSoundFXParamEq, 0xc03ca9fe, 0xfe90, 0x4204, 0x80, 0x78, 0x82, 0x33, 0x4c, 0xd1, 0x77, 0xda); + +typedef struct _DSFXParamEq +{ + FLOAT fCenter; + FLOAT fBandwidth; + FLOAT fGain; +} DSFXParamEq, *LPDSFXParamEq; + +typedef const DSFXParamEq *LPCDSFXParamEq; + +#define DSFXPARAMEQ_CENTER_MIN 80.0f +#define DSFXPARAMEQ_CENTER_MAX 16000.0f +#define DSFXPARAMEQ_BANDWIDTH_MIN 1.0f +#define DSFXPARAMEQ_BANDWIDTH_MAX 36.0f +#define DSFXPARAMEQ_GAIN_MIN -15.0f +#define DSFXPARAMEQ_GAIN_MAX 15.0f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXParamEq + +DECLARE_INTERFACE_(IDirectSoundFXParamEq, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXParamEq methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXParamEq pcDsFxParamEq) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXParamEq pDsFxParamEq) PURE; +}; + +#define IDirectSoundFXParamEq_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXParamEq_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXParamEq_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXParamEq_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXParamEq_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXParamEq_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXParamEq_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXI3DL2Reverb +// + +DEFINE_GUID(IID_IDirectSoundFXI3DL2Reverb, 0x4b166a6a, 0x0d66, 0x43f3, 0x80, 0xe3, 0xee, 0x62, 0x80, 0xde, 0xe1, 0xa4); + +typedef struct _DSFXI3DL2Reverb +{ + LONG lRoom; // [-10000, 0] default: -1000 mB + LONG lRoomHF; // [-10000, 0] default: 0 mB + FLOAT flRoomRolloffFactor; // [0.0, 10.0] default: 0.0 + FLOAT flDecayTime; // [0.1, 20.0] default: 1.49s + FLOAT flDecayHFRatio; // [0.1, 2.0] default: 0.83 + LONG lReflections; // [-10000, 1000] default: -2602 mB + FLOAT flReflectionsDelay; // [0.0, 0.3] default: 0.007 s + LONG lReverb; // [-10000, 2000] default: 200 mB + FLOAT flReverbDelay; // [0.0, 0.1] default: 0.011 s + FLOAT flDiffusion; // [0.0, 100.0] default: 100.0 % + FLOAT flDensity; // [0.0, 100.0] default: 100.0 % + FLOAT flHFReference; // [20.0, 20000.0] default: 5000.0 Hz +} DSFXI3DL2Reverb, *LPDSFXI3DL2Reverb; + +typedef const DSFXI3DL2Reverb *LPCDSFXI3DL2Reverb; + +#define DSFX_I3DL2REVERB_ROOM_MIN (-10000) +#define DSFX_I3DL2REVERB_ROOM_MAX 0 +#define DSFX_I3DL2REVERB_ROOM_DEFAULT (-1000) + +#define DSFX_I3DL2REVERB_ROOMHF_MIN (-10000) +#define DSFX_I3DL2REVERB_ROOMHF_MAX 0 +#define DSFX_I3DL2REVERB_ROOMHF_DEFAULT (-100) + +#define DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_MIN 0.0f +#define DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_MAX 10.0f +#define DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_DEFAULT 0.0f + +#define DSFX_I3DL2REVERB_DECAYTIME_MIN 0.1f +#define DSFX_I3DL2REVERB_DECAYTIME_MAX 20.0f +#define DSFX_I3DL2REVERB_DECAYTIME_DEFAULT 1.49f + +#define DSFX_I3DL2REVERB_DECAYHFRATIO_MIN 0.1f +#define DSFX_I3DL2REVERB_DECAYHFRATIO_MAX 2.0f +#define DSFX_I3DL2REVERB_DECAYHFRATIO_DEFAULT 0.83f + +#define DSFX_I3DL2REVERB_REFLECTIONS_MIN (-10000) +#define DSFX_I3DL2REVERB_REFLECTIONS_MAX 1000 +#define DSFX_I3DL2REVERB_REFLECTIONS_DEFAULT (-2602) + +#define DSFX_I3DL2REVERB_REFLECTIONSDELAY_MIN 0.0f +#define DSFX_I3DL2REVERB_REFLECTIONSDELAY_MAX 0.3f +#define DSFX_I3DL2REVERB_REFLECTIONSDELAY_DEFAULT 0.007f + +#define DSFX_I3DL2REVERB_REVERB_MIN (-10000) +#define DSFX_I3DL2REVERB_REVERB_MAX 2000 +#define DSFX_I3DL2REVERB_REVERB_DEFAULT (200) + +#define DSFX_I3DL2REVERB_REVERBDELAY_MIN 0.0f +#define DSFX_I3DL2REVERB_REVERBDELAY_MAX 0.1f +#define DSFX_I3DL2REVERB_REVERBDELAY_DEFAULT 0.011f + +#define DSFX_I3DL2REVERB_DIFFUSION_MIN 0.0f +#define DSFX_I3DL2REVERB_DIFFUSION_MAX 100.0f +#define DSFX_I3DL2REVERB_DIFFUSION_DEFAULT 100.0f + +#define DSFX_I3DL2REVERB_DENSITY_MIN 0.0f +#define DSFX_I3DL2REVERB_DENSITY_MAX 100.0f +#define DSFX_I3DL2REVERB_DENSITY_DEFAULT 100.0f + +#define DSFX_I3DL2REVERB_HFREFERENCE_MIN 20.0f +#define DSFX_I3DL2REVERB_HFREFERENCE_MAX 20000.0f +#define DSFX_I3DL2REVERB_HFREFERENCE_DEFAULT 5000.0f + +#define DSFX_I3DL2REVERB_QUALITY_MIN 0 +#define DSFX_I3DL2REVERB_QUALITY_MAX 3 +#define DSFX_I3DL2REVERB_QUALITY_DEFAULT 2 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXI3DL2Reverb + +DECLARE_INTERFACE_(IDirectSoundFXI3DL2Reverb, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXI3DL2Reverb methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXI3DL2Reverb pcDsFxI3DL2Reverb) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXI3DL2Reverb pDsFxI3DL2Reverb) PURE; + STDMETHOD(SetPreset) (THIS_ DWORD dwPreset) PURE; + STDMETHOD(GetPreset) (THIS_ __out LPDWORD pdwPreset) PURE; + STDMETHOD(SetQuality) (THIS_ LONG lQuality) PURE; + STDMETHOD(GetQuality) (THIS_ __out LONG *plQuality) PURE; +}; + +#define IDirectSoundFXI3DL2Reverb_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXI3DL2Reverb_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXI3DL2Reverb_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXI3DL2Reverb_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXI3DL2Reverb_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSoundFXI3DL2Reverb_SetPreset(p,a) (p)->lpVtbl->SetPreset(p,a) +#define IDirectSoundFXI3DL2Reverb_GetPreset(p,a) (p)->lpVtbl->GetPreset(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXI3DL2Reverb_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXI3DL2Reverb_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSoundFXI3DL2Reverb_SetPreset(p,a) (p)->SetPreset(a) +#define IDirectSoundFXI3DL2Reverb_GetPreset(p,a) (p)->GetPreset(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXWavesReverb +// + +DEFINE_GUID(IID_IDirectSoundFXWavesReverb,0x46858c3a,0x0dc6,0x45e3,0xb7,0x60,0xd4,0xee,0xf1,0x6c,0xb3,0x25); + +typedef struct _DSFXWavesReverb +{ + FLOAT fInGain; // [-96.0,0.0] default: 0.0 dB + FLOAT fReverbMix; // [-96.0,0.0] default: 0.0 db + FLOAT fReverbTime; // [0.001,3000.0] default: 1000.0 ms + FLOAT fHighFreqRTRatio; // [0.001,0.999] default: 0.001 +} DSFXWavesReverb, *LPDSFXWavesReverb; + +typedef const DSFXWavesReverb *LPCDSFXWavesReverb; + +#define DSFX_WAVESREVERB_INGAIN_MIN -96.0f +#define DSFX_WAVESREVERB_INGAIN_MAX 0.0f +#define DSFX_WAVESREVERB_INGAIN_DEFAULT 0.0f +#define DSFX_WAVESREVERB_REVERBMIX_MIN -96.0f +#define DSFX_WAVESREVERB_REVERBMIX_MAX 0.0f +#define DSFX_WAVESREVERB_REVERBMIX_DEFAULT 0.0f +#define DSFX_WAVESREVERB_REVERBTIME_MIN 0.001f +#define DSFX_WAVESREVERB_REVERBTIME_MAX 3000.0f +#define DSFX_WAVESREVERB_REVERBTIME_DEFAULT 1000.0f +#define DSFX_WAVESREVERB_HIGHFREQRTRATIO_MIN 0.001f +#define DSFX_WAVESREVERB_HIGHFREQRTRATIO_MAX 0.999f +#define DSFX_WAVESREVERB_HIGHFREQRTRATIO_DEFAULT 0.001f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXWavesReverb + +DECLARE_INTERFACE_(IDirectSoundFXWavesReverb, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXWavesReverb methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSFXWavesReverb pcDsFxWavesReverb) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSFXWavesReverb pDsFxWavesReverb) PURE; +}; + +#define IDirectSoundFXWavesReverb_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXWavesReverb_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXWavesReverb_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXWavesReverb_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXWavesReverb_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXWavesReverb_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXWavesReverb_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCaptureFXAec +// + +DEFINE_GUID(IID_IDirectSoundCaptureFXAec, 0xad74143d, 0x903d, 0x4ab7, 0x80, 0x66, 0x28, 0xd3, 0x63, 0x03, 0x6d, 0x65); + +typedef struct _DSCFXAec +{ + BOOL fEnable; + BOOL fNoiseFill; + DWORD dwMode; +} DSCFXAec, *LPDSCFXAec; + +typedef const DSCFXAec *LPCDSCFXAec; + +// These match the AEC_MODE_* constants in the DDK's ksmedia.h file +#define DSCFX_AEC_MODE_PASS_THROUGH 0x0 +#define DSCFX_AEC_MODE_HALF_DUPLEX 0x1 +#define DSCFX_AEC_MODE_FULL_DUPLEX 0x2 + +// These match the AEC_STATUS_* constants in ksmedia.h +#define DSCFX_AEC_STATUS_HISTORY_UNINITIALIZED 0x0 +#define DSCFX_AEC_STATUS_HISTORY_CONTINUOUSLY_CONVERGED 0x1 +#define DSCFX_AEC_STATUS_HISTORY_PREVIOUSLY_DIVERGED 0x2 +#define DSCFX_AEC_STATUS_CURRENTLY_CONVERGED 0x8 + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureFXAec + +DECLARE_INTERFACE_(IDirectSoundCaptureFXAec, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureFXAec methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSCFXAec pDscFxAec) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSCFXAec pDscFxAec) PURE; + STDMETHOD(GetStatus) (THIS_ __out LPDWORD pdwStatus) PURE; + STDMETHOD(Reset) (THIS) PURE; +}; + +#define IDirectSoundCaptureFXAec_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureFXAec_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureFXAec_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXAec_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundCaptureFXAec_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXAec_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundCaptureFXAec_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + + +// +// IDirectSoundCaptureFXNoiseSuppress +// + +DEFINE_GUID(IID_IDirectSoundCaptureFXNoiseSuppress, 0xed311e41, 0xfbae, 0x4175, 0x96, 0x25, 0xcd, 0x8, 0x54, 0xf6, 0x93, 0xca); + +typedef struct _DSCFXNoiseSuppress +{ + BOOL fEnable; +} DSCFXNoiseSuppress, *LPDSCFXNoiseSuppress; + +typedef const DSCFXNoiseSuppress *LPCDSCFXNoiseSuppress; + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureFXNoiseSuppress + +DECLARE_INTERFACE_(IDirectSoundCaptureFXNoiseSuppress, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureFXNoiseSuppress methods + STDMETHOD(SetAllParameters) (THIS_ __in LPCDSCFXNoiseSuppress pcDscFxNoiseSuppress) PURE; + STDMETHOD(GetAllParameters) (THIS_ __out LPDSCFXNoiseSuppress pDscFxNoiseSuppress) PURE; + STDMETHOD(Reset) (THIS) PURE; +}; + +#define IDirectSoundCaptureFXNoiseSuppress_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureFXNoiseSuppress_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureFXNoiseSuppress_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXNoiseSuppress_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundCaptureFXNoiseSuppress_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXNoiseSuppress_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundCaptureFXNoiseSuppress_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + + +// +// IDirectSoundFullDuplex +// + +#ifndef _IDirectSoundFullDuplex_ +#define _IDirectSoundFullDuplex_ + +#ifdef __cplusplus +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +struct IDirectSoundFullDuplex; +#endif // __cplusplus + +typedef struct IDirectSoundFullDuplex *LPDIRECTSOUNDFULLDUPLEX; + +DEFINE_GUID(IID_IDirectSoundFullDuplex, 0xedcb4c7a, 0xdaab, 0x4216, 0xa4, 0x2e, 0x6c, 0x50, 0x59, 0x6d, 0xdc, 0x1d); + +#undef INTERFACE +#define INTERFACE IDirectSoundFullDuplex + +DECLARE_INTERFACE_(IDirectSoundFullDuplex, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFullDuplex methods + STDMETHOD(Initialize) (THIS_ __in LPCGUID pCaptureGuid, __in LPCGUID pRenderGuid, __in LPCDSCBUFFERDESC lpDscBufferDesc, __in LPCDSBUFFERDESC lpDsBufferDesc, HWND hWnd, DWORD dwLevel, + __deref_out LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8, __deref_out LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8) PURE; +}; + +#define IDirectSoundFullDuplex_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFullDuplex_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFullDuplex_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFullDuplex_Initialize(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->Initialize(p,a,b,c,d,e,f,g,h) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFullDuplex_Initialize(p,a,b,c,d,e,f,g,h) (p)->Initialize(a,b,c,d,e,f,g,h) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // _IDirectSoundFullDuplex_ + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// Return Codes +// + +// The function completed successfully +#define DS_OK S_OK + +// The call succeeded, but we had to substitute the 3D algorithm +#define DS_NO_VIRTUALIZATION MAKE_HRESULT(0, _FACDS, 10) + +// The call failed because resources (such as a priority level) +// were already being used by another caller +#define DSERR_ALLOCATED MAKE_DSHRESULT(10) + +// The control (vol, pan, etc.) requested by the caller is not available +#define DSERR_CONTROLUNAVAIL MAKE_DSHRESULT(30) + +// An invalid parameter was passed to the returning function +#define DSERR_INVALIDPARAM E_INVALIDARG + +// This call is not valid for the current state of this object +#define DSERR_INVALIDCALL MAKE_DSHRESULT(50) + +// An undetermined error occurred inside the DirectSound subsystem +#define DSERR_GENERIC E_FAIL + +// The caller does not have the priority level required for the function to +// succeed +#define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT(70) + +// Not enough free memory is available to complete the operation +#define DSERR_OUTOFMEMORY E_OUTOFMEMORY + +// The specified WAVE format is not supported +#define DSERR_BADFORMAT MAKE_DSHRESULT(100) + +// The function called is not supported at this time +#define DSERR_UNSUPPORTED E_NOTIMPL + +// No sound driver is available for use +#define DSERR_NODRIVER MAKE_DSHRESULT(120) + +// This object is already initialized +#define DSERR_ALREADYINITIALIZED MAKE_DSHRESULT(130) + +// This object does not support aggregation +#define DSERR_NOAGGREGATION CLASS_E_NOAGGREGATION + +// The buffer memory has been lost, and must be restored +#define DSERR_BUFFERLOST MAKE_DSHRESULT(150) + +// Another app has a higher priority level, preventing this call from +// succeeding +#define DSERR_OTHERAPPHASPRIO MAKE_DSHRESULT(160) + +// This object has not been initialized +#define DSERR_UNINITIALIZED MAKE_DSHRESULT(170) + +// The requested COM interface is not available +#define DSERR_NOINTERFACE E_NOINTERFACE + +// Access is denied +#define DSERR_ACCESSDENIED E_ACCESSDENIED + +// Tried to create a DSBCAPS_CTRLFX buffer shorter than DSBSIZE_FX_MIN milliseconds +#define DSERR_BUFFERTOOSMALL MAKE_DSHRESULT(180) + +// Attempt to use DirectSound 8 functionality on an older DirectSound object +#define DSERR_DS8_REQUIRED MAKE_DSHRESULT(190) + +// A circular loop of send effects was detected +#define DSERR_SENDLOOP MAKE_DSHRESULT(200) + +// The GUID specified in an audiopath file does not match a valid MIXIN buffer +#define DSERR_BADSENDBUFFERGUID MAKE_DSHRESULT(210) + +// The object requested was not found (numerically equal to DMUS_E_NOT_FOUND) +#define DSERR_OBJECTNOTFOUND MAKE_DSHRESULT(4449) + +// The effects requested could not be found on the system, or they were found +// but in the wrong order, or in the wrong hardware/software locations. +#define DSERR_FXUNAVAILABLE MAKE_DSHRESULT(220) + +// +// Flags +// + +#define DSCAPS_PRIMARYMONO 0x00000001 +#define DSCAPS_PRIMARYSTEREO 0x00000002 +#define DSCAPS_PRIMARY8BIT 0x00000004 +#define DSCAPS_PRIMARY16BIT 0x00000008 +#define DSCAPS_CONTINUOUSRATE 0x00000010 +#define DSCAPS_EMULDRIVER 0x00000020 +#define DSCAPS_CERTIFIED 0x00000040 +#define DSCAPS_SECONDARYMONO 0x00000100 +#define DSCAPS_SECONDARYSTEREO 0x00000200 +#define DSCAPS_SECONDARY8BIT 0x00000400 +#define DSCAPS_SECONDARY16BIT 0x00000800 + +#define DSSCL_NORMAL 0x00000001 +#define DSSCL_PRIORITY 0x00000002 +#define DSSCL_EXCLUSIVE 0x00000003 +#define DSSCL_WRITEPRIMARY 0x00000004 + +#define DSSPEAKER_DIRECTOUT 0x00000000 +#define DSSPEAKER_HEADPHONE 0x00000001 +#define DSSPEAKER_MONO 0x00000002 +#define DSSPEAKER_QUAD 0x00000003 +#define DSSPEAKER_STEREO 0x00000004 +#define DSSPEAKER_SURROUND 0x00000005 +#define DSSPEAKER_5POINT1 0x00000006 // obsolete 5.1 setting +#define DSSPEAKER_7POINT1 0x00000007 // obsolete 7.1 setting +#define DSSPEAKER_7POINT1_SURROUND 0x00000008 // correct 7.1 Home Theater setting +#define DSSPEAKER_5POINT1_SURROUND 0x00000009 // correct 5.1 setting +#define DSSPEAKER_7POINT1_WIDE DSSPEAKER_7POINT1 +#define DSSPEAKER_5POINT1_BACK DSSPEAKER_5POINT1 + +#define DSSPEAKER_GEOMETRY_MIN 0x00000005 // 5 degrees +#define DSSPEAKER_GEOMETRY_NARROW 0x0000000A // 10 degrees +#define DSSPEAKER_GEOMETRY_WIDE 0x00000014 // 20 degrees +#define DSSPEAKER_GEOMETRY_MAX 0x000000B4 // 180 degrees + +#define DSSPEAKER_COMBINED(c, g) ((DWORD)(((BYTE)(c)) | ((DWORD)((BYTE)(g))) << 16)) +#define DSSPEAKER_CONFIG(a) ((BYTE)(a)) +#define DSSPEAKER_GEOMETRY(a) ((BYTE)(((DWORD)(a) >> 16) & 0x00FF)) + +#define DSBCAPS_PRIMARYBUFFER 0x00000001 +#define DSBCAPS_STATIC 0x00000002 +#define DSBCAPS_LOCHARDWARE 0x00000004 +#define DSBCAPS_LOCSOFTWARE 0x00000008 +#define DSBCAPS_CTRL3D 0x00000010 +#define DSBCAPS_CTRLFREQUENCY 0x00000020 +#define DSBCAPS_CTRLPAN 0x00000040 +#define DSBCAPS_CTRLVOLUME 0x00000080 +#define DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100 +#define DSBCAPS_CTRLFX 0x00000200 +#define DSBCAPS_STICKYFOCUS 0x00004000 +#define DSBCAPS_GLOBALFOCUS 0x00008000 +#define DSBCAPS_GETCURRENTPOSITION2 0x00010000 +#define DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000 +#define DSBCAPS_LOCDEFER 0x00040000 +#define DSBCAPS_TRUEPLAYPOSITION 0x00080000 + +#define DSBPLAY_LOOPING 0x00000001 +#define DSBPLAY_LOCHARDWARE 0x00000002 +#define DSBPLAY_LOCSOFTWARE 0x00000004 +#define DSBPLAY_TERMINATEBY_TIME 0x00000008 +#define DSBPLAY_TERMINATEBY_DISTANCE 0x000000010 +#define DSBPLAY_TERMINATEBY_PRIORITY 0x000000020 + +#define DSBSTATUS_PLAYING 0x00000001 +#define DSBSTATUS_BUFFERLOST 0x00000002 +#define DSBSTATUS_LOOPING 0x00000004 +#define DSBSTATUS_LOCHARDWARE 0x00000008 +#define DSBSTATUS_LOCSOFTWARE 0x00000010 +#define DSBSTATUS_TERMINATED 0x00000020 + +#define DSBLOCK_FROMWRITECURSOR 0x00000001 +#define DSBLOCK_ENTIREBUFFER 0x00000002 + +#define DSBFREQUENCY_ORIGINAL 0 +#define DSBFREQUENCY_MIN 100 +#if DIRECTSOUND_VERSION >= 0x0900 +#define DSBFREQUENCY_MAX 200000 +#else +#define DSBFREQUENCY_MAX 100000 +#endif + +#define DSBPAN_LEFT -10000 +#define DSBPAN_CENTER 0 +#define DSBPAN_RIGHT 10000 + +#define DSBVOLUME_MIN -10000 +#define DSBVOLUME_MAX 0 + +#define DSBSIZE_MIN 4 +#define DSBSIZE_MAX 0x0FFFFFFF +#define DSBSIZE_FX_MIN 150 // NOTE: Milliseconds, not bytes + +#define DSBNOTIFICATIONS_MAX 100000UL + +#define DS3DMODE_NORMAL 0x00000000 +#define DS3DMODE_HEADRELATIVE 0x00000001 +#define DS3DMODE_DISABLE 0x00000002 + +#define DS3D_IMMEDIATE 0x00000000 +#define DS3D_DEFERRED 0x00000001 + +#define DS3D_MINDISTANCEFACTOR FLT_MIN +#define DS3D_MAXDISTANCEFACTOR FLT_MAX +#define DS3D_DEFAULTDISTANCEFACTOR 1.0f + +#define DS3D_MINROLLOFFFACTOR 0.0f +#define DS3D_MAXROLLOFFFACTOR 10.0f +#define DS3D_DEFAULTROLLOFFFACTOR 1.0f + +#define DS3D_MINDOPPLERFACTOR 0.0f +#define DS3D_MAXDOPPLERFACTOR 10.0f +#define DS3D_DEFAULTDOPPLERFACTOR 1.0f + +#define DS3D_DEFAULTMINDISTANCE 1.0f +#define DS3D_DEFAULTMAXDISTANCE 1000000000.0f + +#define DS3D_MINCONEANGLE 0 +#define DS3D_MAXCONEANGLE 360 +#define DS3D_DEFAULTCONEANGLE 360 + +#define DS3D_DEFAULTCONEOUTSIDEVOLUME DSBVOLUME_MAX + +// IDirectSoundCapture attributes + +#define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER +#define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED +#define DSCCAPS_MULTIPLECAPTURE 0x00000001 + +// IDirectSoundCaptureBuffer attributes + +#define DSCBCAPS_WAVEMAPPED 0x80000000 +#if DIRECTSOUND_VERSION >= 0x0800 +#define DSCBCAPS_CTRLFX 0x00000200 +#endif + +#define DSCBLOCK_ENTIREBUFFER 0x00000001 + +#define DSCBSTATUS_CAPTURING 0x00000001 +#define DSCBSTATUS_LOOPING 0x00000002 + +#define DSCBSTART_LOOPING 0x00000001 + +#define DSBPN_OFFSETSTOP 0xFFFFFFFF + +#define DS_CERTIFIED 0x00000000 +#define DS_UNCERTIFIED 0x00000001 + +// +// Flags for the I3DL2 effects +// + +// +// I3DL2 Material Presets +// + +enum +{ + DSFX_I3DL2_MATERIAL_PRESET_SINGLEWINDOW, + DSFX_I3DL2_MATERIAL_PRESET_DOUBLEWINDOW, + DSFX_I3DL2_MATERIAL_PRESET_THINDOOR, + DSFX_I3DL2_MATERIAL_PRESET_THICKDOOR, + DSFX_I3DL2_MATERIAL_PRESET_WOODWALL, + DSFX_I3DL2_MATERIAL_PRESET_BRICKWALL, + DSFX_I3DL2_MATERIAL_PRESET_STONEWALL, + DSFX_I3DL2_MATERIAL_PRESET_CURTAIN +}; + +#define I3DL2_MATERIAL_PRESET_SINGLEWINDOW -2800,0.71f +#define I3DL2_MATERIAL_PRESET_DOUBLEWINDOW -5000,0.40f +#define I3DL2_MATERIAL_PRESET_THINDOOR -1800,0.66f +#define I3DL2_MATERIAL_PRESET_THICKDOOR -4400,0.64f +#define I3DL2_MATERIAL_PRESET_WOODWALL -4000,0.50f +#define I3DL2_MATERIAL_PRESET_BRICKWALL -5000,0.60f +#define I3DL2_MATERIAL_PRESET_STONEWALL -6000,0.68f +#define I3DL2_MATERIAL_PRESET_CURTAIN -1200,0.15f + +enum +{ + DSFX_I3DL2_ENVIRONMENT_PRESET_DEFAULT, + DSFX_I3DL2_ENVIRONMENT_PRESET_GENERIC, + DSFX_I3DL2_ENVIRONMENT_PRESET_PADDEDCELL, + DSFX_I3DL2_ENVIRONMENT_PRESET_ROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_BATHROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_LIVINGROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_STONEROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_AUDITORIUM, + DSFX_I3DL2_ENVIRONMENT_PRESET_CONCERTHALL, + DSFX_I3DL2_ENVIRONMENT_PRESET_CAVE, + DSFX_I3DL2_ENVIRONMENT_PRESET_ARENA, + DSFX_I3DL2_ENVIRONMENT_PRESET_HANGAR, + DSFX_I3DL2_ENVIRONMENT_PRESET_CARPETEDHALLWAY, + DSFX_I3DL2_ENVIRONMENT_PRESET_HALLWAY, + DSFX_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR, + DSFX_I3DL2_ENVIRONMENT_PRESET_ALLEY, + DSFX_I3DL2_ENVIRONMENT_PRESET_FOREST, + DSFX_I3DL2_ENVIRONMENT_PRESET_CITY, + DSFX_I3DL2_ENVIRONMENT_PRESET_MOUNTAINS, + DSFX_I3DL2_ENVIRONMENT_PRESET_QUARRY, + DSFX_I3DL2_ENVIRONMENT_PRESET_PLAIN, + DSFX_I3DL2_ENVIRONMENT_PRESET_PARKINGLOT, + DSFX_I3DL2_ENVIRONMENT_PRESET_SEWERPIPE, + DSFX_I3DL2_ENVIRONMENT_PRESET_UNDERWATER, + DSFX_I3DL2_ENVIRONMENT_PRESET_SMALLROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMHALL, + DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEHALL, + DSFX_I3DL2_ENVIRONMENT_PRESET_PLATE +}; + +// +// I3DL2 Reverberation Presets Values +// + +#define I3DL2_ENVIRONMENT_PRESET_DEFAULT -1000, -100, 0.0f, 1.49f, 0.83f, -2602, 0.007f, 200, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_GENERIC -1000, -100, 0.0f, 1.49f, 0.83f, -2602, 0.007f, 200, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PADDEDCELL -1000,-6000, 0.0f, 0.17f, 0.10f, -1204, 0.001f, 207, 0.002f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_ROOM -1000, -454, 0.0f, 0.40f, 0.83f, -1646, 0.002f, 53, 0.003f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_BATHROOM -1000,-1200, 0.0f, 1.49f, 0.54f, -370, 0.007f, 1030, 0.011f, 100.0f, 60.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_LIVINGROOM -1000,-6000, 0.0f, 0.50f, 0.10f, -1376, 0.003f, -1104, 0.004f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_STONEROOM -1000, -300, 0.0f, 2.31f, 0.64f, -711, 0.012f, 83, 0.017f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_AUDITORIUM -1000, -476, 0.0f, 4.32f, 0.59f, -789, 0.020f, -289, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CONCERTHALL -1000, -500, 0.0f, 3.92f, 0.70f, -1230, 0.020f, -2, 0.029f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CAVE -1000, 0, 0.0f, 2.91f, 1.30f, -602, 0.015f, -302, 0.022f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_ARENA -1000, -698, 0.0f, 7.24f, 0.33f, -1166, 0.020f, 16, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_HANGAR -1000,-1000, 0.0f,10.05f, 0.23f, -602, 0.020f, 198, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CARPETEDHALLWAY -1000,-4000, 0.0f, 0.30f, 0.10f, -1831, 0.002f, -1630, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_HALLWAY -1000, -300, 0.0f, 1.49f, 0.59f, -1219, 0.007f, 441, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR -1000, -237, 0.0f, 2.70f, 0.79f, -1214, 0.013f, 395, 0.020f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_ALLEY -1000, -270, 0.0f, 1.49f, 0.86f, -1204, 0.007f, -4, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_FOREST -1000,-3300, 0.0f, 1.49f, 0.54f, -2560, 0.162f, -613, 0.088f, 79.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CITY -1000, -800, 0.0f, 1.49f, 0.67f, -2273, 0.007f, -2217, 0.011f, 50.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_MOUNTAINS -1000,-2500, 0.0f, 1.49f, 0.21f, -2780, 0.300f, -2014, 0.100f, 27.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_QUARRY -1000,-1000, 0.0f, 1.49f, 0.83f,-10000, 0.061f, 500, 0.025f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PLAIN -1000,-2000, 0.0f, 1.49f, 0.50f, -2466, 0.179f, -2514, 0.100f, 21.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PARKINGLOT -1000, 0, 0.0f, 1.65f, 1.50f, -1363, 0.008f, -1153, 0.012f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_SEWERPIPE -1000,-1000, 0.0f, 2.81f, 0.14f, 429, 0.014f, 648, 0.021f, 80.0f, 60.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_UNDERWATER -1000,-4000, 0.0f, 1.49f, 0.10f, -449, 0.007f, 1700, 0.011f, 100.0f, 100.0f, 5000.0f + +// +// Examples simulating 'musical' reverb presets +// +// Name Decay time Description +// Small Room 1.1s A small size room with a length of 5m or so. +// Medium Room 1.3s A medium size room with a length of 10m or so. +// Large Room 1.5s A large size room suitable for live performances. +// Medium Hall 1.8s A medium size concert hall. +// Large Hall 1.8s A large size concert hall suitable for a full orchestra. +// Plate 1.3s A plate reverb simulation. +// + +#define I3DL2_ENVIRONMENT_PRESET_SMALLROOM -1000, -600, 0.0f, 1.10f, 0.83f, -400, 0.005f, 500, 0.010f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_MEDIUMROOM -1000, -600, 0.0f, 1.30f, 0.83f, -1000, 0.010f, -200, 0.020f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_LARGEROOM -1000, -600, 0.0f, 1.50f, 0.83f, -1600, 0.020f, -1000, 0.040f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_MEDIUMHALL -1000, -600, 0.0f, 1.80f, 0.70f, -1300, 0.015f, -800, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_LARGEHALL -1000, -600, 0.0f, 1.80f, 0.70f, -2000, 0.030f, -1400, 0.060f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PLATE -1000, -200, 0.0f, 1.30f, 0.90f, 0, 0.002f, 0, 0.010f, 100.0f, 75.0f, 5000.0f + +// +// DirectSound3D Algorithms +// + +// Default DirectSound3D algorithm {00000000-0000-0000-0000-000000000000} +#define DS3DALG_DEFAULT GUID_NULL + +// No virtualization (Pan3D) {C241333F-1C1B-11d2-94F5-00C04FC28ACA} +DEFINE_GUID(DS3DALG_NO_VIRTUALIZATION, 0xc241333f, 0x1c1b, 0x11d2, 0x94, 0xf5, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + +// High-quality HRTF algorithm {C2413340-1C1B-11d2-94F5-00C04FC28ACA} +DEFINE_GUID(DS3DALG_HRTF_FULL, 0xc2413340, 0x1c1b, 0x11d2, 0x94, 0xf5, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + +// Lower-quality HRTF algorithm {C2413342-1C1B-11d2-94F5-00C04FC28ACA} +DEFINE_GUID(DS3DALG_HRTF_LIGHT, 0xc2413342, 0x1c1b, 0x11d2, 0x94, 0xf5, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// DirectSound Internal Effect Algorithms +// + + +// Gargle {DAFD8210-5711-4B91-9FE3-F75B7AE279BF} +DEFINE_GUID(GUID_DSFX_STANDARD_GARGLE, 0xdafd8210, 0x5711, 0x4b91, 0x9f, 0xe3, 0xf7, 0x5b, 0x7a, 0xe2, 0x79, 0xbf); + +// Chorus {EFE6629C-81F7-4281-BD91-C9D604A95AF6} +DEFINE_GUID(GUID_DSFX_STANDARD_CHORUS, 0xefe6629c, 0x81f7, 0x4281, 0xbd, 0x91, 0xc9, 0xd6, 0x04, 0xa9, 0x5a, 0xf6); + +// Flanger {EFCA3D92-DFD8-4672-A603-7420894BAD98} +DEFINE_GUID(GUID_DSFX_STANDARD_FLANGER, 0xefca3d92, 0xdfd8, 0x4672, 0xa6, 0x03, 0x74, 0x20, 0x89, 0x4b, 0xad, 0x98); + +// Echo/Delay {EF3E932C-D40B-4F51-8CCF-3F98F1B29D5D} +DEFINE_GUID(GUID_DSFX_STANDARD_ECHO, 0xef3e932c, 0xd40b, 0x4f51, 0x8c, 0xcf, 0x3f, 0x98, 0xf1, 0xb2, 0x9d, 0x5d); + +// Distortion {EF114C90-CD1D-484E-96E5-09CFAF912A21} +DEFINE_GUID(GUID_DSFX_STANDARD_DISTORTION, 0xef114c90, 0xcd1d, 0x484e, 0x96, 0xe5, 0x09, 0xcf, 0xaf, 0x91, 0x2a, 0x21); + +// Compressor/Limiter {EF011F79-4000-406D-87AF-BFFB3FC39D57} +DEFINE_GUID(GUID_DSFX_STANDARD_COMPRESSOR, 0xef011f79, 0x4000, 0x406d, 0x87, 0xaf, 0xbf, 0xfb, 0x3f, 0xc3, 0x9d, 0x57); + +// Parametric Equalization {120CED89-3BF4-4173-A132-3CB406CF3231} +DEFINE_GUID(GUID_DSFX_STANDARD_PARAMEQ, 0x120ced89, 0x3bf4, 0x4173, 0xa1, 0x32, 0x3c, 0xb4, 0x06, 0xcf, 0x32, 0x31); + +// I3DL2 Environmental Reverberation: Reverb (Listener) Effect {EF985E71-D5C7-42D4-BA4D-2D073E2E96F4} +DEFINE_GUID(GUID_DSFX_STANDARD_I3DL2REVERB, 0xef985e71, 0xd5c7, 0x42d4, 0xba, 0x4d, 0x2d, 0x07, 0x3e, 0x2e, 0x96, 0xf4); + +// Waves Reverberation {87FC0268-9A55-4360-95AA-004A1D9DE26C} +DEFINE_GUID(GUID_DSFX_WAVES_REVERB, 0x87fc0268, 0x9a55, 0x4360, 0x95, 0xaa, 0x00, 0x4a, 0x1d, 0x9d, 0xe2, 0x6c); + +// +// DirectSound Capture Effect Algorithms +// + + +// Acoustic Echo Canceller {BF963D80-C559-11D0-8A2B-00A0C9255AC1} +// Matches KSNODETYPE_ACOUSTIC_ECHO_CANCEL in ksmedia.h +DEFINE_GUID(GUID_DSCFX_CLASS_AEC, 0xBF963D80L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); + +// Microsoft AEC {CDEBB919-379A-488a-8765-F53CFD36DE40} +DEFINE_GUID(GUID_DSCFX_MS_AEC, 0xcdebb919, 0x379a, 0x488a, 0x87, 0x65, 0xf5, 0x3c, 0xfd, 0x36, 0xde, 0x40); + +// System AEC {1C22C56D-9879-4f5b-A389-27996DDC2810} +DEFINE_GUID(GUID_DSCFX_SYSTEM_AEC, 0x1c22c56d, 0x9879, 0x4f5b, 0xa3, 0x89, 0x27, 0x99, 0x6d, 0xdc, 0x28, 0x10); + +// Noise Supression {E07F903F-62FD-4e60-8CDD-DEA7236665B5} +// Matches KSNODETYPE_NOISE_SUPPRESS in post Windows ME DDK's ksmedia.h +DEFINE_GUID(GUID_DSCFX_CLASS_NS, 0xe07f903f, 0x62fd, 0x4e60, 0x8c, 0xdd, 0xde, 0xa7, 0x23, 0x66, 0x65, 0xb5); + +// Microsoft Noise Suppresion {11C5C73B-66E9-4ba1-A0BA-E814C6EED92D} +DEFINE_GUID(GUID_DSCFX_MS_NS, 0x11c5c73b, 0x66e9, 0x4ba1, 0xa0, 0xba, 0xe8, 0x14, 0xc6, 0xee, 0xd9, 0x2d); + +// System Noise Suppresion {5AB0882E-7274-4516-877D-4EEE99BA4FD0} +DEFINE_GUID(GUID_DSCFX_SYSTEM_NS, 0x5ab0882e, 0x7274, 0x4516, 0x87, 0x7d, 0x4e, 0xee, 0x99, 0xba, 0x4f, 0xd0); + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +#endif // __DSOUND_INCLUDED__ + + + +#ifdef __cplusplus +}; +#endif // __cplusplus + diff --git a/dxsdk/Include/dxdiag.h b/dxsdk/Include/dxdiag.h new file mode 100644 index 0000000..602c88f --- /dev/null +++ b/dxsdk/Include/dxdiag.h @@ -0,0 +1,187 @@ +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: dxdiag.h + * Content: DirectX Diagnostic Tool include file + * + ****************************************************************************/ + +#ifndef _DXDIAG_H_ +#define _DXDIAG_H_ + +#include // for DECLARE_INTERFACE_ and HRESULT + +// This identifier is passed to IDxDiagProvider::Initialize in order to ensure that an +// application was built against the correct header files. This number is +// incremented whenever a header (or other) change would require applications +// to be rebuilt. If the version doesn't match, IDxDiagProvider::Initialize will fail. +// (The number itself has no meaning.) +#define DXDIAG_DX9_SDK_VERSION 111 + +#ifdef __cplusplus +extern "C" { +#endif + + +/**************************************************************************** + * + * DxDiag Errors + * + ****************************************************************************/ +#define DXDIAG_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) + + +/**************************************************************************** + * + * DxDiag CLSIDs + * + ****************************************************************************/ + +// {A65B8071-3BFE-4213-9A5B-491DA4461CA7} +DEFINE_GUID(CLSID_DxDiagProvider, +0xA65B8071, 0x3BFE, 0x4213, 0x9A, 0x5B, 0x49, 0x1D, 0xA4, 0x46, 0x1C, 0xA7); + + +/**************************************************************************** + * + * DxDiag Interface IIDs + * + ****************************************************************************/ + +// {9C6B4CB0-23F8-49CC-A3ED-45A55000A6D2} +DEFINE_GUID(IID_IDxDiagProvider, +0x9C6B4CB0, 0x23F8, 0x49CC, 0xA3, 0xED, 0x45, 0xA5, 0x50, 0x00, 0xA6, 0xD2); + +// {0x7D0F462F-0x4064-0x4862-BC7F-933E5058C10F} +DEFINE_GUID(IID_IDxDiagContainer, +0x7D0F462F, 0x4064, 0x4862, 0xBC, 0x7F, 0x93, 0x3E, 0x50, 0x58, 0xC1, 0x0F); + + +/**************************************************************************** + * + * DxDiag Interface Pointer definitions + * + ****************************************************************************/ + +typedef struct IDxDiagProvider *LPDXDIAGPROVIDER, *PDXDIAGPROVIDER; + +typedef struct IDxDiagContainer *LPDXDIAGCONTAINER, *PDXDIAGCONTAINER; + + +/**************************************************************************** + * + * DxDiag Structures + * + ****************************************************************************/ + +typedef struct _DXDIAG_INIT_PARAMS +{ + DWORD dwSize; // Size of this structure. + DWORD dwDxDiagHeaderVersion; // Pass in DXDIAG_DX9_SDK_VERSION. This verifies + // the header and dll are correctly matched. + BOOL bAllowWHQLChecks; // If true, allow dxdiag to check if drivers are + // digital signed as logo'd by WHQL which may + // connect via internet to update WHQL certificates. + VOID* pReserved; // Reserved. Must be NULL. +} DXDIAG_INIT_PARAMS; + + +/**************************************************************************** + * + * DxDiag Application Interfaces + * + ****************************************************************************/ + +// +// COM definition for IDxDiagProvider +// +#undef INTERFACE // External COM Implementation +#define INTERFACE IDxDiagProvider +DECLARE_INTERFACE_(IDxDiagProvider,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IDxDiagProvider methods ***/ + STDMETHOD(Initialize) (THIS_ DXDIAG_INIT_PARAMS* pParams) PURE; + STDMETHOD(GetRootContainer) (THIS_ IDxDiagContainer **ppInstance) PURE; +}; + + +// +// COM definition for IDxDiagContainer +// +#undef INTERFACE // External COM Implementation +#define INTERFACE IDxDiagContainer +DECLARE_INTERFACE_(IDxDiagContainer,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IDxDiagContainer methods ***/ + STDMETHOD(GetNumberOfChildContainers) (THIS_ DWORD *pdwCount) PURE; + STDMETHOD(EnumChildContainerNames) (THIS_ DWORD dwIndex, LPWSTR pwszContainer, DWORD cchContainer) PURE; + STDMETHOD(GetChildContainer) (THIS_ LPCWSTR pwszContainer, IDxDiagContainer **ppInstance) PURE; + STDMETHOD(GetNumberOfProps) (THIS_ DWORD *pdwCount) PURE; + STDMETHOD(EnumPropNames) (THIS_ DWORD dwIndex, LPWSTR pwszPropName, DWORD cchPropName) PURE; + STDMETHOD(GetProp) (THIS_ LPCWSTR pwszPropName, VARIANT *pvarProp) PURE; +}; + + +/**************************************************************************** + * + * DxDiag application interface macros + * + ****************************************************************************/ + +#if !defined(__cplusplus) || defined(CINTERFACE) + +#define IDxDiagProvider_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDxDiagProvider_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDxDiagProvider_Release(p) (p)->lpVtbl->Release(p) +#define IDxDiagProvider_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDxDiagProvider_GetRootContainer(p,a) (p)->lpVtbl->GetRootContainer(p,a) + +#define IDxDiagContainer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDxDiagContainer_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDxDiagContainer_Release(p) (p)->lpVtbl->Release(p) +#define IDxDiagContainer_GetNumberOfChildContainers(p,a) (p)->lpVtbl->GetNumberOfChildContainers(p,a) +#define IDxDiagContainer_EnumChildContainerNames(p,a,b,c) (p)->lpVtbl->EnumChildContainerNames(p,a,b,c) +#define IDxDiagContainer_GetChildContainer(p,a,b) (p)->lpVtbl->GetChildContainer(p,a,b) +#define IDxDiagContainer_GetNumberOfProps(p,a) (p)->lpVtbl->GetNumberOfProps(p,a) +#define IDxDiagContainer_EnumProps(p,a,b) (p)->lpVtbl->EnumProps(p,a,b,c) +#define IDxDiagContainer_GetProp(p,a,b) (p)->lpVtbl->GetProp(p,a,b) + +#else /* C++ */ + +#define IDxDiagProvider_QueryInterface(p,a,b) (p)->QueryInterface(p,a,b) +#define IDxDiagProvider_AddRef(p) (p)->AddRef(p) +#define IDxDiagProvider_Release(p) (p)->Release(p) +#define IDxDiagProvider_Initialize(p,a,b) (p)->Initialize(p,a,b) +#define IDxDiagProvider_GetRootContainer(p,a) (p)->GetRootContainer(p,a) + +#define IDxDiagContainer_QueryInterface(p,a,b) (p)->QueryInterface(p,a,b) +#define IDxDiagContainer_AddRef(p) (p)->AddRef(p) +#define IDxDiagContainer_Release(p) (p)->Release(p) +#define IDxDiagContainer_GetNumberOfChildContainers(p,a) (p)->GetNumberOfChildContainers(p,a) +#define IDxDiagContainer_EnumChildContainerNames(p,a,b,c) (p)->EnumChildContainerNames(p,a,b,c) +#define IDxDiagContainer_GetChildContainer(p,a,b) (p)->GetChildContainer(p,a,b) +#define IDxDiagContainer_GetNumberOfProps(p,a) (p)->GetNumberOfProps(p,a) +#define IDxDiagContainer_EnumProps(p,a,b) (p)->EnumProps(p,a,b,c) +#define IDxDiagContainer_GetProp(p,a,b) (p)->GetProp(p,a,b) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _DXDIAG_H_ */ + + diff --git a/dxsdk/Include/dxfile.h b/dxsdk/Include/dxfile.h new file mode 100644 index 0000000..74e80e5 --- /dev/null +++ b/dxsdk/Include/dxfile.h @@ -0,0 +1,239 @@ +/*************************************************************************** + * + * Copyright (C) 1998-1999 Microsoft Corporation. All Rights Reserved. + * + * File: dxfile.h + * + * Content: DirectX File public header file + * + ***************************************************************************/ + +#ifndef __DXFILE_H__ +#define __DXFILE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef DWORD DXFILEFORMAT; + +#define DXFILEFORMAT_BINARY 0 +#define DXFILEFORMAT_TEXT 1 +#define DXFILEFORMAT_COMPRESSED 2 + +typedef DWORD DXFILELOADOPTIONS; + +#define DXFILELOAD_FROMFILE 0x00L +#define DXFILELOAD_FROMRESOURCE 0x01L +#define DXFILELOAD_FROMMEMORY 0x02L +#define DXFILELOAD_FROMSTREAM 0x04L +#define DXFILELOAD_FROMURL 0x08L + +typedef struct _DXFILELOADRESOURCE { + HMODULE hModule; + LPCTSTR lpName; + LPCTSTR lpType; +}DXFILELOADRESOURCE, *LPDXFILELOADRESOURCE; + +typedef struct _DXFILELOADMEMORY { + LPVOID lpMemory; + DWORD dSize; +}DXFILELOADMEMORY, *LPDXFILELOADMEMORY; + +/* + * DirectX File object types. + */ + +#ifndef WIN_TYPES +#define WIN_TYPES(itype, ptype) typedef interface itype *LP##ptype, **LPLP##ptype +#endif + +WIN_TYPES(IDirectXFile, DIRECTXFILE); +WIN_TYPES(IDirectXFileEnumObject, DIRECTXFILEENUMOBJECT); +WIN_TYPES(IDirectXFileSaveObject, DIRECTXFILESAVEOBJECT); +WIN_TYPES(IDirectXFileObject, DIRECTXFILEOBJECT); +WIN_TYPES(IDirectXFileData, DIRECTXFILEDATA); +WIN_TYPES(IDirectXFileDataReference, DIRECTXFILEDATAREFERENCE); +WIN_TYPES(IDirectXFileBinary, DIRECTXFILEBINARY); + +/* + * API for creating IDirectXFile interface. + */ + +STDAPI DirectXFileCreate(LPDIRECTXFILE *lplpDirectXFile); + +/* + * The methods for IUnknown + */ + +#define IUNKNOWN_METHODS(kind) \ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) kind; \ + STDMETHOD_(ULONG, AddRef) (THIS) kind; \ + STDMETHOD_(ULONG, Release) (THIS) kind + +/* + * The methods for IDirectXFileObject + */ + +#define IDIRECTXFILEOBJECT_METHODS(kind) \ + STDMETHOD(GetName) (THIS_ LPSTR, LPDWORD) kind; \ + STDMETHOD(GetId) (THIS_ LPGUID) kind + +/* + * DirectX File interfaces. + */ + +#undef INTERFACE +#define INTERFACE IDirectXFile + +DECLARE_INTERFACE_(IDirectXFile, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + STDMETHOD(CreateEnumObject) (THIS_ LPVOID, DXFILELOADOPTIONS, + LPDIRECTXFILEENUMOBJECT *) PURE; + STDMETHOD(CreateSaveObject) (THIS_ LPCSTR, DXFILEFORMAT, + LPDIRECTXFILESAVEOBJECT *) PURE; + STDMETHOD(RegisterTemplates) (THIS_ LPVOID, DWORD) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileEnumObject + +DECLARE_INTERFACE_(IDirectXFileEnumObject, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + STDMETHOD(GetNextDataObject) (THIS_ LPDIRECTXFILEDATA *) PURE; + STDMETHOD(GetDataObjectById) (THIS_ REFGUID, LPDIRECTXFILEDATA *) PURE; + STDMETHOD(GetDataObjectByName) (THIS_ LPCSTR, LPDIRECTXFILEDATA *) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileSaveObject + +DECLARE_INTERFACE_(IDirectXFileSaveObject, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + STDMETHOD(SaveTemplates) (THIS_ DWORD, const GUID **) PURE; + STDMETHOD(CreateDataObject) (THIS_ REFGUID, LPCSTR, const GUID *, + DWORD, LPVOID, LPDIRECTXFILEDATA *) PURE; + STDMETHOD(SaveData) (THIS_ LPDIRECTXFILEDATA) PURE; +}; + + +#undef INTERFACE +#define INTERFACE IDirectXFileObject + +DECLARE_INTERFACE_(IDirectXFileObject, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileData + +DECLARE_INTERFACE_(IDirectXFileData, IDirectXFileObject) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + + STDMETHOD(GetData) (THIS_ LPCSTR, DWORD *, void **) PURE; + STDMETHOD(GetType) (THIS_ const GUID **) PURE; + STDMETHOD(GetNextObject) (THIS_ LPDIRECTXFILEOBJECT *) PURE; + STDMETHOD(AddDataObject) (THIS_ LPDIRECTXFILEDATA) PURE; + STDMETHOD(AddDataReference) (THIS_ LPCSTR, const GUID *) PURE; + STDMETHOD(AddBinaryObject) (THIS_ LPCSTR, const GUID *, LPCSTR, LPVOID, DWORD) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileDataReference + +DECLARE_INTERFACE_(IDirectXFileDataReference, IDirectXFileObject) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + + STDMETHOD(Resolve) (THIS_ LPDIRECTXFILEDATA *) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileBinary + +DECLARE_INTERFACE_(IDirectXFileBinary, IDirectXFileObject) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + + STDMETHOD(GetSize) (THIS_ DWORD *) PURE; + STDMETHOD(GetMimeType) (THIS_ LPCSTR *) PURE; + STDMETHOD(Read) (THIS_ LPVOID, DWORD, LPDWORD) PURE; +}; + +/* + * DirectXFile Object Class Id (for CoCreateInstance()) + */ + +DEFINE_GUID(CLSID_CDirectXFile, 0x4516ec43, 0x8f20, 0x11d0, 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3); + +/* + * DirectX File Interface GUIDs. + */ + +DEFINE_GUID(IID_IDirectXFile, 0x3d82ab40, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileEnumObject, 0x3d82ab41, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileSaveObject, 0x3d82ab42, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileObject, 0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileData, 0x3d82ab44, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileDataReference, 0x3d82ab45, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileBinary, 0x3d82ab46, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* + * DirectX File Header template's GUID. + */ + +DEFINE_GUID(TID_DXFILEHeader, 0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + + +/* + * DirectX File errors. + */ + +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +#define DXFILE_OK 0 + +#define DXFILEERR_BADOBJECT MAKE_DDHRESULT(850) +#define DXFILEERR_BADVALUE MAKE_DDHRESULT(851) +#define DXFILEERR_BADTYPE MAKE_DDHRESULT(852) +#define DXFILEERR_BADSTREAMHANDLE MAKE_DDHRESULT(853) +#define DXFILEERR_BADALLOC MAKE_DDHRESULT(854) +#define DXFILEERR_NOTFOUND MAKE_DDHRESULT(855) +#define DXFILEERR_NOTDONEYET MAKE_DDHRESULT(856) +#define DXFILEERR_FILENOTFOUND MAKE_DDHRESULT(857) +#define DXFILEERR_RESOURCENOTFOUND MAKE_DDHRESULT(858) +#define DXFILEERR_URLNOTFOUND MAKE_DDHRESULT(859) +#define DXFILEERR_BADRESOURCE MAKE_DDHRESULT(860) +#define DXFILEERR_BADFILETYPE MAKE_DDHRESULT(861) +#define DXFILEERR_BADFILEVERSION MAKE_DDHRESULT(862) +#define DXFILEERR_BADFILEFLOATSIZE MAKE_DDHRESULT(863) +#define DXFILEERR_BADFILECOMPRESSIONTYPE MAKE_DDHRESULT(864) +#define DXFILEERR_BADFILE MAKE_DDHRESULT(865) +#define DXFILEERR_PARSEERROR MAKE_DDHRESULT(866) +#define DXFILEERR_NOTEMPLATE MAKE_DDHRESULT(867) +#define DXFILEERR_BADARRAYSIZE MAKE_DDHRESULT(868) +#define DXFILEERR_BADDATAREFERENCE MAKE_DDHRESULT(869) +#define DXFILEERR_INTERNALERROR MAKE_DDHRESULT(870) +#define DXFILEERR_NOMOREOBJECTS MAKE_DDHRESULT(871) +#define DXFILEERR_BADINTRINSICS MAKE_DDHRESULT(872) +#define DXFILEERR_NOMORESTREAMHANDLES MAKE_DDHRESULT(873) +#define DXFILEERR_NOMOREDATA MAKE_DDHRESULT(874) +#define DXFILEERR_BADCACHEFILE MAKE_DDHRESULT(875) +#define DXFILEERR_NOINTERNET MAKE_DDHRESULT(876) + + +#ifdef __cplusplus +}; +#endif + +#endif /* _DXFILE_H_ */ diff --git a/dxsdk/Include/dxsdkver.h b/dxsdk/Include/dxsdkver.h new file mode 100644 index 0000000..7d88bbb --- /dev/null +++ b/dxsdk/Include/dxsdkver.h @@ -0,0 +1,18 @@ +/*==========================================================================; + * + * + * File: dxsdkver.h + * Content: DirectX SDK Version Include File + * + ****************************************************************************/ + +#ifndef _DXSDKVER_H_ +#define _DXSDKVER_H_ + +#define _DXSDK_PRODUCT_MAJOR 9 +#define _DXSDK_PRODUCT_MINOR 29 +#define _DXSDK_BUILD_MAJOR 1962 +#define _DXSDK_BUILD_MINOR 0 + +#endif // _DXSDKVER_H_ + diff --git a/dxsdk/Include/gameux.h b/dxsdk/Include/gameux.h new file mode 100644 index 0000000..19e2f95 --- /dev/null +++ b/dxsdk/Include/gameux.h @@ -0,0 +1,719 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0550 */ +/* Compiler settings for gameux.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0550 + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __gameux_h__ +#define __gameux_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IGameExplorer_FWD_DEFINED__ +#define __IGameExplorer_FWD_DEFINED__ +typedef interface IGameExplorer IGameExplorer; +#endif /* __IGameExplorer_FWD_DEFINED__ */ + + +#ifndef __IGameStatistics_FWD_DEFINED__ +#define __IGameStatistics_FWD_DEFINED__ +typedef interface IGameStatistics IGameStatistics; +#endif /* __IGameStatistics_FWD_DEFINED__ */ + + +#ifndef __IGameStatisticsMgr_FWD_DEFINED__ +#define __IGameStatisticsMgr_FWD_DEFINED__ +typedef interface IGameStatisticsMgr IGameStatisticsMgr; +#endif /* __IGameStatisticsMgr_FWD_DEFINED__ */ + + +#ifndef __IGameExplorer2_FWD_DEFINED__ +#define __IGameExplorer2_FWD_DEFINED__ +typedef interface IGameExplorer2 IGameExplorer2; +#endif /* __IGameExplorer2_FWD_DEFINED__ */ + + +#ifndef __GameExplorer_FWD_DEFINED__ +#define __GameExplorer_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class GameExplorer GameExplorer; +#else +typedef struct GameExplorer GameExplorer; +#endif /* __cplusplus */ + +#endif /* __GameExplorer_FWD_DEFINED__ */ + + +#ifndef __GameStatistics_FWD_DEFINED__ +#define __GameStatistics_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class GameStatistics GameStatistics; +#else +typedef struct GameStatistics GameStatistics; +#endif /* __cplusplus */ + +#endif /* __GameStatistics_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "shobjidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_gameux_0000_0000 */ +/* [local] */ + +#define ID_GDF_XML __GDF_XML +#define ID_GDF_THUMBNAIL __GDF_THUMBNAIL +#define ID_ICON_ICO __ICON_ICO +#define ID_GDF_XML_STR L"__GDF_XML" +#define ID_GDF_THUMBNAIL_STR L"__GDF_THUMBNAIL" +typedef /* [v1_enum] */ +enum GAME_INSTALL_SCOPE + { GIS_NOT_INSTALLED = 1, + GIS_CURRENT_USER = 2, + GIS_ALL_USERS = 3 + } GAME_INSTALL_SCOPE; + + + +extern RPC_IF_HANDLE __MIDL_itf_gameux_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_gameux_0000_0000_v0_0_s_ifspec; + +#ifndef __IGameExplorer_INTERFACE_DEFINED__ +#define __IGameExplorer_INTERFACE_DEFINED__ + +/* interface IGameExplorer */ +/* [unique][helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IGameExplorer; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E7B2FB72-D728-49B3-A5F2-18EBF5F1349E") + IGameExplorer : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddGame( + /* [in] */ __RPC__in BSTR bstrGDFBinaryPath, + /* [in] */ __RPC__in BSTR bstrGameInstallDirectory, + /* [in] */ GAME_INSTALL_SCOPE installScope, + /* [out][in] */ __RPC__inout GUID *pguidInstanceID) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE RemoveGame( + /* [in] */ GUID guidInstanceID) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UpdateGame( + /* [in] */ GUID guidInstanceID) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VerifyAccess( + /* [in] */ __RPC__in BSTR bstrGDFBinaryPath, + /* [out] */ __RPC__out BOOL *pfHasAccess) = 0; + + }; + +#else /* C style interface */ + + typedef struct IGameExplorerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in IGameExplorer * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in IGameExplorer * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in IGameExplorer * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *AddGame )( + __RPC__in IGameExplorer * This, + /* [in] */ __RPC__in BSTR bstrGDFBinaryPath, + /* [in] */ __RPC__in BSTR bstrGameInstallDirectory, + /* [in] */ GAME_INSTALL_SCOPE installScope, + /* [out][in] */ __RPC__inout GUID *pguidInstanceID); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *RemoveGame )( + __RPC__in IGameExplorer * This, + /* [in] */ GUID guidInstanceID); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *UpdateGame )( + __RPC__in IGameExplorer * This, + /* [in] */ GUID guidInstanceID); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *VerifyAccess )( + __RPC__in IGameExplorer * This, + /* [in] */ __RPC__in BSTR bstrGDFBinaryPath, + /* [out] */ __RPC__out BOOL *pfHasAccess); + + END_INTERFACE + } IGameExplorerVtbl; + + interface IGameExplorer + { + CONST_VTBL struct IGameExplorerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IGameExplorer_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IGameExplorer_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IGameExplorer_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IGameExplorer_AddGame(This,bstrGDFBinaryPath,bstrGameInstallDirectory,installScope,pguidInstanceID) \ + ( (This)->lpVtbl -> AddGame(This,bstrGDFBinaryPath,bstrGameInstallDirectory,installScope,pguidInstanceID) ) + +#define IGameExplorer_RemoveGame(This,guidInstanceID) \ + ( (This)->lpVtbl -> RemoveGame(This,guidInstanceID) ) + +#define IGameExplorer_UpdateGame(This,guidInstanceID) \ + ( (This)->lpVtbl -> UpdateGame(This,guidInstanceID) ) + +#define IGameExplorer_VerifyAccess(This,bstrGDFBinaryPath,pfHasAccess) \ + ( (This)->lpVtbl -> VerifyAccess(This,bstrGDFBinaryPath,pfHasAccess) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IGameExplorer_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_gameux_0000_0001 */ +/* [local] */ + +typedef /* [v1_enum] */ +enum GAMESTATS_OPEN_TYPE + { GAMESTATS_OPEN_OPENORCREATE = 0, + GAMESTATS_OPEN_OPENONLY = 1 + } GAMESTATS_OPEN_TYPE; + +typedef /* [v1_enum] */ +enum GAMESTATS_OPEN_RESULT + { GAMESTATS_OPEN_CREATED = 0, + GAMESTATS_OPEN_OPENED = 1 + } GAMESTATS_OPEN_RESULT; + + + +extern RPC_IF_HANDLE __MIDL_itf_gameux_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_gameux_0000_0001_v0_0_s_ifspec; + +#ifndef __IGameStatistics_INTERFACE_DEFINED__ +#define __IGameStatistics_INTERFACE_DEFINED__ + +/* interface IGameStatistics */ +/* [unique][helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IGameStatistics; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3887C9CA-04A0-42ae-BC4C-5FA6C7721145") + IGameStatistics : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMaxCategoryLength( + /* [retval][out] */ __RPC__out UINT *cch) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMaxNameLength( + /* [retval][out] */ __RPC__out UINT *cch) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMaxValueLength( + /* [retval][out] */ __RPC__out UINT *cch) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMaxCategories( + /* [retval][out] */ __RPC__out WORD *pMax) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMaxStatsPerCategory( + /* [retval][out] */ __RPC__out WORD *pMax) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetCategoryTitle( + /* [in] */ WORD categoryIndex, + /* [string][in] */ __RPC__in_string LPCWSTR title) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCategoryTitle( + /* [in] */ WORD categoryIndex, + /* [retval][string][out] */ __RPC__deref_out_opt_string LPWSTR *pTitle) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStatistic( + /* [in] */ WORD categoryIndex, + /* [in] */ WORD statIndex, + /* [string][unique][out][in] */ __RPC__deref_opt_inout_opt_string LPWSTR *pName, + /* [string][unique][out][in] */ __RPC__deref_opt_inout_opt_string LPWSTR *pValue) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStatistic( + /* [in] */ WORD categoryIndex, + /* [in] */ WORD statIndex, + /* [string][in] */ __RPC__in_string LPCWSTR name, + /* [string][in] */ __RPC__in_string LPCWSTR value) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Save( + /* [in] */ BOOL trackChanges) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetLastPlayedCategory( + /* [in] */ UINT categoryIndex) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetLastPlayedCategory( + /* [retval][out] */ __RPC__out UINT *pCategoryIndex) = 0; + + }; + +#else /* C style interface */ + + typedef struct IGameStatisticsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in IGameStatistics * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in IGameStatistics * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in IGameStatistics * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMaxCategoryLength )( + __RPC__in IGameStatistics * This, + /* [retval][out] */ __RPC__out UINT *cch); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMaxNameLength )( + __RPC__in IGameStatistics * This, + /* [retval][out] */ __RPC__out UINT *cch); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMaxValueLength )( + __RPC__in IGameStatistics * This, + /* [retval][out] */ __RPC__out UINT *cch); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMaxCategories )( + __RPC__in IGameStatistics * This, + /* [retval][out] */ __RPC__out WORD *pMax); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMaxStatsPerCategory )( + __RPC__in IGameStatistics * This, + /* [retval][out] */ __RPC__out WORD *pMax); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCategoryTitle )( + __RPC__in IGameStatistics * This, + /* [in] */ WORD categoryIndex, + /* [string][in] */ __RPC__in_string LPCWSTR title); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCategoryTitle )( + __RPC__in IGameStatistics * This, + /* [in] */ WORD categoryIndex, + /* [retval][string][out] */ __RPC__deref_out_opt_string LPWSTR *pTitle); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetStatistic )( + __RPC__in IGameStatistics * This, + /* [in] */ WORD categoryIndex, + /* [in] */ WORD statIndex, + /* [string][unique][out][in] */ __RPC__deref_opt_inout_opt_string LPWSTR *pName, + /* [string][unique][out][in] */ __RPC__deref_opt_inout_opt_string LPWSTR *pValue); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetStatistic )( + __RPC__in IGameStatistics * This, + /* [in] */ WORD categoryIndex, + /* [in] */ WORD statIndex, + /* [string][in] */ __RPC__in_string LPCWSTR name, + /* [string][in] */ __RPC__in_string LPCWSTR value); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Save )( + __RPC__in IGameStatistics * This, + /* [in] */ BOOL trackChanges); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetLastPlayedCategory )( + __RPC__in IGameStatistics * This, + /* [in] */ UINT categoryIndex); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetLastPlayedCategory )( + __RPC__in IGameStatistics * This, + /* [retval][out] */ __RPC__out UINT *pCategoryIndex); + + END_INTERFACE + } IGameStatisticsVtbl; + + interface IGameStatistics + { + CONST_VTBL struct IGameStatisticsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IGameStatistics_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IGameStatistics_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IGameStatistics_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IGameStatistics_GetMaxCategoryLength(This,cch) \ + ( (This)->lpVtbl -> GetMaxCategoryLength(This,cch) ) + +#define IGameStatistics_GetMaxNameLength(This,cch) \ + ( (This)->lpVtbl -> GetMaxNameLength(This,cch) ) + +#define IGameStatistics_GetMaxValueLength(This,cch) \ + ( (This)->lpVtbl -> GetMaxValueLength(This,cch) ) + +#define IGameStatistics_GetMaxCategories(This,pMax) \ + ( (This)->lpVtbl -> GetMaxCategories(This,pMax) ) + +#define IGameStatistics_GetMaxStatsPerCategory(This,pMax) \ + ( (This)->lpVtbl -> GetMaxStatsPerCategory(This,pMax) ) + +#define IGameStatistics_SetCategoryTitle(This,categoryIndex,title) \ + ( (This)->lpVtbl -> SetCategoryTitle(This,categoryIndex,title) ) + +#define IGameStatistics_GetCategoryTitle(This,categoryIndex,pTitle) \ + ( (This)->lpVtbl -> GetCategoryTitle(This,categoryIndex,pTitle) ) + +#define IGameStatistics_GetStatistic(This,categoryIndex,statIndex,pName,pValue) \ + ( (This)->lpVtbl -> GetStatistic(This,categoryIndex,statIndex,pName,pValue) ) + +#define IGameStatistics_SetStatistic(This,categoryIndex,statIndex,name,value) \ + ( (This)->lpVtbl -> SetStatistic(This,categoryIndex,statIndex,name,value) ) + +#define IGameStatistics_Save(This,trackChanges) \ + ( (This)->lpVtbl -> Save(This,trackChanges) ) + +#define IGameStatistics_SetLastPlayedCategory(This,categoryIndex) \ + ( (This)->lpVtbl -> SetLastPlayedCategory(This,categoryIndex) ) + +#define IGameStatistics_GetLastPlayedCategory(This,pCategoryIndex) \ + ( (This)->lpVtbl -> GetLastPlayedCategory(This,pCategoryIndex) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IGameStatistics_INTERFACE_DEFINED__ */ + + +#ifndef __IGameStatisticsMgr_INTERFACE_DEFINED__ +#define __IGameStatisticsMgr_INTERFACE_DEFINED__ + +/* interface IGameStatisticsMgr */ +/* [unique][helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IGameStatisticsMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("AFF3EA11-E70E-407d-95DD-35E612C41CE2") + IGameStatisticsMgr : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetGameStatistics( + /* [string][in] */ __RPC__in_string LPCWSTR GDFBinaryPath, + /* [in] */ GAMESTATS_OPEN_TYPE openType, + /* [out] */ __RPC__out GAMESTATS_OPEN_RESULT *pOpenResult, + /* [retval][out] */ __RPC__deref_out_opt IGameStatistics **ppiStats) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE RemoveGameStatistics( + /* [string][in] */ __RPC__in_string LPCWSTR GDFBinaryPath) = 0; + + }; + +#else /* C style interface */ + + typedef struct IGameStatisticsMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in IGameStatisticsMgr * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in IGameStatisticsMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in IGameStatisticsMgr * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetGameStatistics )( + __RPC__in IGameStatisticsMgr * This, + /* [string][in] */ __RPC__in_string LPCWSTR GDFBinaryPath, + /* [in] */ GAMESTATS_OPEN_TYPE openType, + /* [out] */ __RPC__out GAMESTATS_OPEN_RESULT *pOpenResult, + /* [retval][out] */ __RPC__deref_out_opt IGameStatistics **ppiStats); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *RemoveGameStatistics )( + __RPC__in IGameStatisticsMgr * This, + /* [string][in] */ __RPC__in_string LPCWSTR GDFBinaryPath); + + END_INTERFACE + } IGameStatisticsMgrVtbl; + + interface IGameStatisticsMgr + { + CONST_VTBL struct IGameStatisticsMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IGameStatisticsMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IGameStatisticsMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IGameStatisticsMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IGameStatisticsMgr_GetGameStatistics(This,GDFBinaryPath,openType,pOpenResult,ppiStats) \ + ( (This)->lpVtbl -> GetGameStatistics(This,GDFBinaryPath,openType,pOpenResult,ppiStats) ) + +#define IGameStatisticsMgr_RemoveGameStatistics(This,GDFBinaryPath) \ + ( (This)->lpVtbl -> RemoveGameStatistics(This,GDFBinaryPath) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IGameStatisticsMgr_INTERFACE_DEFINED__ */ + + +#ifndef __IGameExplorer2_INTERFACE_DEFINED__ +#define __IGameExplorer2_INTERFACE_DEFINED__ + +/* interface IGameExplorer2 */ +/* [unique][helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IGameExplorer2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("86874AA7-A1ED-450d-A7EB-B89E20B2FFF3") + IGameExplorer2 : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE InstallGame( + /* [string][in] */ __RPC__in_string LPCWSTR binaryGDFPath, + /* [unique][in] */ __RPC__in_opt LPCWSTR installDirectory, + /* [in] */ GAME_INSTALL_SCOPE installScope) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UninstallGame( + /* [string][in] */ __RPC__in_string LPCWSTR binaryGDFPath) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CheckAccess( + /* [string][in] */ __RPC__in_string LPCWSTR binaryGDFPath, + /* [retval][out] */ __RPC__out BOOL *pHasAccess) = 0; + + }; + +#else /* C style interface */ + + typedef struct IGameExplorer2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in IGameExplorer2 * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in IGameExplorer2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in IGameExplorer2 * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *InstallGame )( + __RPC__in IGameExplorer2 * This, + /* [string][in] */ __RPC__in_string LPCWSTR binaryGDFPath, + /* [unique][in] */ __RPC__in_opt LPCWSTR installDirectory, + /* [in] */ GAME_INSTALL_SCOPE installScope); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *UninstallGame )( + __RPC__in IGameExplorer2 * This, + /* [string][in] */ __RPC__in_string LPCWSTR binaryGDFPath); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CheckAccess )( + __RPC__in IGameExplorer2 * This, + /* [string][in] */ __RPC__in_string LPCWSTR binaryGDFPath, + /* [retval][out] */ __RPC__out BOOL *pHasAccess); + + END_INTERFACE + } IGameExplorer2Vtbl; + + interface IGameExplorer2 + { + CONST_VTBL struct IGameExplorer2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IGameExplorer2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IGameExplorer2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IGameExplorer2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IGameExplorer2_InstallGame(This,binaryGDFPath,installDirectory,installScope) \ + ( (This)->lpVtbl -> InstallGame(This,binaryGDFPath,installDirectory,installScope) ) + +#define IGameExplorer2_UninstallGame(This,binaryGDFPath) \ + ( (This)->lpVtbl -> UninstallGame(This,binaryGDFPath) ) + +#define IGameExplorer2_CheckAccess(This,binaryGDFPath,pHasAccess) \ + ( (This)->lpVtbl -> CheckAccess(This,binaryGDFPath,pHasAccess) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IGameExplorer2_INTERFACE_DEFINED__ */ + + + +#ifndef __gameuxLib_LIBRARY_DEFINED__ +#define __gameuxLib_LIBRARY_DEFINED__ + +/* library gameuxLib */ +/* [helpstring][version][uuid] */ + + +EXTERN_C const IID LIBID_gameuxLib; + +EXTERN_C const CLSID CLSID_GameExplorer; + +#ifdef __cplusplus + +class DECLSPEC_UUID("9A5EA990-3034-4D6F-9128-01F3C61022BC") +GameExplorer; +#endif + +EXTERN_C const CLSID CLSID_GameStatistics; + +#ifdef __cplusplus + +class DECLSPEC_UUID("DBC85A2C-C0DC-4961-B6E2-D28B62C11AD4") +GameStatistics; +#endif +#endif /* __gameuxLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +unsigned long __RPC_USER BSTR_UserSize( __RPC__in unsigned long *, unsigned long , __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out BSTR * ); +void __RPC_USER BSTR_UserFree( __RPC__in unsigned long *, __RPC__in BSTR * ); + +unsigned long __RPC_USER BSTR_UserSize64( __RPC__in unsigned long *, unsigned long , __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal64( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal64(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out BSTR * ); +void __RPC_USER BSTR_UserFree64( __RPC__in unsigned long *, __RPC__in BSTR * ); + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/dxsdk/Include/rmxfguid.h b/dxsdk/Include/rmxfguid.h new file mode 100644 index 0000000..d3326cc --- /dev/null +++ b/dxsdk/Include/rmxfguid.h @@ -0,0 +1,223 @@ +/*************************************************************************** + * + * Copyright (C) 1998-1999 Microsoft Corporation. All Rights Reserved. + * + * File: rmxfguid.h + * + * Content: Defines GUIDs of D3DRM's templates. + * + ***************************************************************************/ + +#ifndef __RMXFGUID_H_ +#define __RMXFGUID_H_ + +/* {2B957100-9E9A-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMInfo, +0x2b957100, 0x9e9a, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {3D82AB44-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMMesh, +0x3d82ab44, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {3D82AB5E-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMVector, +0x3d82ab5e, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {3D82AB5F-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMMeshFace, +0x3d82ab5f, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {3D82AB4D-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMMaterial, +0x3d82ab4d, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {35FF44E1-6C7C-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMaterialArray, +0x35ff44e1, 0x6c7c, 0x11cf, 0x8F, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {3D82AB46-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMFrame, +0x3d82ab46, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {F6F23F41-7686-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMFrameTransformMatrix, +0xf6f23f41, 0x7686, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {F6F23F42-7686-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMeshMaterialList, +0xf6f23f42, 0x7686, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {F6F23F40-7686-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMeshTextureCoords, +0xf6f23f40, 0x7686, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {F6F23F43-7686-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMeshNormals, +0xf6f23f43, 0x7686, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {F6F23F44-7686-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMCoords2d, +0xf6f23f44, 0x7686, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {F6F23F45-7686-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMatrix4x4, +0xf6f23f45, 0x7686, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {3D82AB4F-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMAnimation, +0x3d82ab4f, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {3D82AB50-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMAnimationSet, +0x3d82ab50, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {10DD46A8-775B-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMAnimationKey, +0x10dd46a8, 0x775b, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xA3); + +/* {10DD46A9-775B-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMFloatKeys, +0x10dd46a9, 0x775b, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xA3); + +/* {01411840-7786-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMaterialAmbientColor, +0x01411840, 0x7786, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xA3); + +/* {01411841-7786-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMaterialDiffuseColor, +0x01411841, 0x7786, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xA3); + +/* {01411842-7786-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMaterialSpecularColor, +0x01411842, 0x7786, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xA3); + +/* {D3E16E80-7835-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMaterialEmissiveColor, +0xd3e16e80, 0x7835, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {01411843-7786-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMaterialPower, +0x01411843, 0x7786, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xA3); + +/* {35FF44E0-6C7C-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMColorRGBA, +0x35ff44e0, 0x6c7c, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xA3); + +/* {D3E16E81-7835-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMColorRGB, +0xd3e16e81, 0x7835, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {A42790E0-7810-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMGuid, +0xa42790e0, 0x7810, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {A42790E1-7810-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMTextureFilename, +0xa42790e1, 0x7810, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {A42790E2-7810-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMTextureReference, +0xa42790e2, 0x7810, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {1630B820-7842-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMIndexedColor, +0x1630b820, 0x7842, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {1630B821-7842-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMeshVertexColors, +0x1630b821, 0x7842, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {4885AE60-78E8-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMMaterialWrap, +0x4885ae60, 0x78e8, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {537DA6A0-CA37-11d0-941C-0080C80CFA7B} */ +DEFINE_GUID(TID_D3DRMBoolean, +0x537da6a0, 0xca37, 0x11d0, 0x94, 0x1c, 0x0, 0x80, 0xc8, 0xc, 0xfa, 0x7b); + +/* {ED1EC5C0-C0A8-11d0-941C-0080C80CFA7B} */ +DEFINE_GUID(TID_D3DRMMeshFaceWraps, +0xed1ec5c0, 0xc0a8, 0x11d0, 0x94, 0x1c, 0x0, 0x80, 0xc8, 0xc, 0xfa, 0x7b); + +/* {4885AE63-78E8-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMBoolean2d, +0x4885ae63, 0x78e8, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {F406B180-7B3B-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMTimedFloatKeys, +0xf406b180, 0x7b3b, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {E2BF56C0-840F-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMAnimationOptions, +0xe2bf56c0, 0x840f, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {E2BF56C1-840F-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMFramePosition, +0xe2bf56c1, 0x840f, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {E2BF56C2-840F-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMFrameVelocity, +0xe2bf56c2, 0x840f, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {E2BF56C3-840F-11cf-8F52-0040333594A3} */ +DEFINE_GUID(TID_D3DRMFrameRotation, +0xe2bf56c3, 0x840f, 0x11cf, 0x8f, 0x52, 0x0, 0x40, 0x33, 0x35, 0x94, 0xa3); + +/* {3D82AB4A-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMLight, +0x3d82ab4a, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {3D82AB51-62DA-11cf-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMCamera, +0x3d82ab51, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {E5745280-B24F-11cf-9DD5-00AA00A71A2F} */ +DEFINE_GUID(TID_D3DRMAppData, +0xe5745280, 0xb24f, 0x11cf, 0x9d, 0xd5, 0x0, 0xaa, 0x0, 0xa7, 0x1a, 0x2f); + +/* {AED22740-B31F-11cf-9DD5-00AA00A71A2F} */ +DEFINE_GUID(TID_D3DRMLightUmbra, +0xaed22740, 0xb31f, 0x11cf, 0x9d, 0xd5, 0x0, 0xaa, 0x0, 0xa7, 0x1a, 0x2f); + +/* {AED22742-B31F-11cf-9DD5-00AA00A71A2F} */ +DEFINE_GUID(TID_D3DRMLightRange, +0xaed22742, 0xb31f, 0x11cf, 0x9d, 0xd5, 0x0, 0xaa, 0x0, 0xa7, 0x1a, 0x2f); + +/* {AED22741-B31F-11cf-9DD5-00AA00A71A2F} */ +DEFINE_GUID(TID_D3DRMLightPenumbra, +0xaed22741, 0xb31f, 0x11cf, 0x9d, 0xd5, 0x0, 0xaa, 0x0, 0xa7, 0x1a, 0x2f); + +/* {A8A98BA0-C5E5-11cf-B941-0080C80CFA7B} */ +DEFINE_GUID(TID_D3DRMLightAttenuation, +0xa8a98ba0, 0xc5e5, 0x11cf, 0xb9, 0x41, 0x0, 0x80, 0xc8, 0xc, 0xfa, 0x7b); + +/* {3A23EEA0-94B1-11d0-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMInlineData, +0x3a23eea0, 0x94b1, 0x11d0, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {3A23EEA1-94B1-11d0-AB39-0020AF71E433} */ +DEFINE_GUID(TID_D3DRMUrl, +0x3a23eea1, 0x94b1, 0x11d0, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* {8A63C360-997D-11d0-941C-0080C80CFA7B} */ +DEFINE_GUID(TID_D3DRMProgressiveMesh, +0x8A63C360, 0x997D, 0x11d0, 0x94, 0x1C, 0x0, 0x80, 0xC8, 0x0C, 0xFA, 0x7B); + +/* {98116AA0-BDBA-11d1-82C0-00A0C9697271} */ +DEFINE_GUID(TID_D3DRMExternalVisual, +0x98116AA0, 0xBDBA, 0x11d1, 0x82, 0xC0, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x71); + +/* {7F0F21E0-BFE1-11d1-82C0-00A0C9697271} */ +DEFINE_GUID(TID_D3DRMStringProperty, +0x7f0f21e0, 0xbfe1, 0x11d1, 0x82, 0xc0, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x71); + +/* {7F0F21E1-BFE1-11d1-82C0-00A0C9697271} */ +DEFINE_GUID(TID_D3DRMPropertyBag, +0x7f0f21e1, 0xbfe1, 0x11d1, 0x82, 0xc0, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x71); + +// {7F5D5EA0-D53A-11d1-82C0-00A0C9697271} +DEFINE_GUID(TID_D3DRMRightHanded, +0x7f5d5ea0, 0xd53a, 0x11d1, 0x82, 0xc0, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x71); + +#endif /* __RMXFGUID_H_ */ + diff --git a/dxsdk/Include/rmxftmpl.h b/dxsdk/Include/rmxftmpl.h new file mode 100644 index 0000000..e0018d0 --- /dev/null +++ b/dxsdk/Include/rmxftmpl.h @@ -0,0 +1,339 @@ +/* D3DRM XFile templates in binary form */ + +#ifndef _RMXFTMPL_H_ +#define _RMXFTMPL_H_ + +unsigned char D3DRM_XTEMPLATES[] = { + 0x78, 0x6f, 0x66, 0x20, 0x30, 0x33, 0x30, 0x32, 0x62, + 0x69, 0x6e, 0x20, 0x30, 0x30, 0x36, 0x34, 0x1f, 0, 0x1, + 0, 0x6, 0, 0, 0, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0xa, 0, 0x5, 0, 0x43, 0xab, 0x82, 0x3d, 0xda, + 0x62, 0xcf, 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, + 0x33, 0x28, 0, 0x1, 0, 0x5, 0, 0, 0, 0x6d, + 0x61, 0x6a, 0x6f, 0x72, 0x14, 0, 0x28, 0, 0x1, 0, + 0x5, 0, 0, 0, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x14, + 0, 0x29, 0, 0x1, 0, 0x5, 0, 0, 0, 0x66, + 0x6c, 0x61, 0x67, 0x73, 0x14, 0, 0xb, 0, 0x1f, 0, + 0x1, 0, 0x6, 0, 0, 0, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0xa, 0, 0x5, 0, 0x5e, 0xab, 0x82, 0x3d, + 0xda, 0x62, 0xcf, 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, + 0xe4, 0x33, 0x2a, 0, 0x1, 0, 0x1, 0, 0, 0, + 0x78, 0x14, 0, 0x2a, 0, 0x1, 0, 0x1, 0, 0, + 0, 0x79, 0x14, 0, 0x2a, 0, 0x1, 0, 0x1, 0, + 0, 0, 0x7a, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, + 0, 0x8, 0, 0, 0, 0x43, 0x6f, 0x6f, 0x72, 0x64, + 0x73, 0x32, 0x64, 0xa, 0, 0x5, 0, 0x44, 0x3f, 0xf2, + 0xf6, 0x86, 0x76, 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, + 0x35, 0x94, 0xa3, 0x2a, 0, 0x1, 0, 0x1, 0, 0, + 0, 0x75, 0x14, 0, 0x2a, 0, 0x1, 0, 0x1, 0, + 0, 0, 0x76, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, + 0, 0x9, 0, 0, 0, 0x4d, 0x61, 0x74, 0x72, 0x69, + 0x78, 0x34, 0x78, 0x34, 0xa, 0, 0x5, 0, 0x45, 0x3f, + 0xf2, 0xf6, 0x86, 0x76, 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, + 0x33, 0x35, 0x94, 0xa3, 0x34, 0, 0x2a, 0, 0x1, 0, + 0x6, 0, 0, 0, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0xe, 0, 0x3, 0, 0x10, 0, 0, 0, 0xf, 0, + 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, 0, 0x9, 0, + 0, 0, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x52, 0x47, 0x42, + 0x41, 0xa, 0, 0x5, 0, 0xe0, 0x44, 0xff, 0x35, 0x7c, + 0x6c, 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, + 0xa3, 0x2a, 0, 0x1, 0, 0x3, 0, 0, 0, 0x72, + 0x65, 0x64, 0x14, 0, 0x2a, 0, 0x1, 0, 0x5, 0, + 0, 0, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x14, 0, 0x2a, + 0, 0x1, 0, 0x4, 0, 0, 0, 0x62, 0x6c, 0x75, + 0x65, 0x14, 0, 0x2a, 0, 0x1, 0, 0x5, 0, 0, + 0, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x14, 0, 0xb, 0, + 0x1f, 0, 0x1, 0, 0x8, 0, 0, 0, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x52, 0x47, 0x42, 0xa, 0, 0x5, 0, + 0x81, 0x6e, 0xe1, 0xd3, 0x35, 0x78, 0xcf, 0x11, 0x8f, 0x52, + 0, 0x40, 0x33, 0x35, 0x94, 0xa3, 0x2a, 0, 0x1, 0, + 0x3, 0, 0, 0, 0x72, 0x65, 0x64, 0x14, 0, 0x2a, + 0, 0x1, 0, 0x5, 0, 0, 0, 0x67, 0x72, 0x65, + 0x65, 0x6e, 0x14, 0, 0x2a, 0, 0x1, 0, 0x4, 0, + 0, 0, 0x62, 0x6c, 0x75, 0x65, 0x14, 0, 0xb, 0, + 0x1f, 0, 0x1, 0, 0xc, 0, 0, 0, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0xa, 0, 0x5, 0, 0x20, 0xb8, 0x30, 0x16, 0x42, 0x78, + 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, + 0x29, 0, 0x1, 0, 0x5, 0, 0, 0, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x14, 0, 0x1, 0, 0x9, 0, 0, + 0, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x52, 0x47, 0x42, 0x41, + 0x1, 0, 0xa, 0, 0, 0, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x14, 0, 0xb, 0, + 0x1f, 0, 0x1, 0, 0x7, 0, 0, 0, 0x42, 0x6f, + 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0xa, 0, 0x5, 0, 0xa0, + 0xa6, 0x7d, 0x53, 0x37, 0xca, 0xd0, 0x11, 0x94, 0x1c, 0, + 0x80, 0xc8, 0xc, 0xfa, 0x7b, 0x29, 0, 0x1, 0, 0x9, + 0, 0, 0, 0x74, 0x72, 0x75, 0x65, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, 0, + 0x9, 0, 0, 0, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, + 0x6e, 0x32, 0x64, 0xa, 0, 0x5, 0, 0x63, 0xae, 0x85, + 0x48, 0xe8, 0x78, 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, + 0x35, 0x94, 0xa3, 0x1, 0, 0x7, 0, 0, 0, 0x42, + 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x1, 0, 0x1, 0, + 0, 0, 0x75, 0x14, 0, 0x1, 0, 0x7, 0, 0, + 0, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x1, 0, + 0x1, 0, 0, 0, 0x76, 0x14, 0, 0xb, 0, 0x1f, + 0, 0x1, 0, 0xc, 0, 0, 0, 0x4d, 0x61, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x57, 0x72, 0x61, 0x70, 0xa, + 0, 0x5, 0, 0x60, 0xae, 0x85, 0x48, 0xe8, 0x78, 0xcf, + 0x11, 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, 0x1, + 0, 0x7, 0, 0, 0, 0x42, 0x6f, 0x6f, 0x6c, 0x65, + 0x61, 0x6e, 0x1, 0, 0x1, 0, 0, 0, 0x75, 0x14, + 0, 0x1, 0, 0x7, 0, 0, 0, 0x42, 0x6f, 0x6f, + 0x6c, 0x65, 0x61, 0x6e, 0x1, 0, 0x1, 0, 0, 0, + 0x76, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, 0, 0xf, + 0, 0, 0, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0xa, 0, + 0x5, 0, 0xe1, 0x90, 0x27, 0xa4, 0x10, 0x78, 0xcf, 0x11, + 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, 0x31, 0, + 0x1, 0, 0x8, 0, 0, 0, 0x66, 0x69, 0x6c, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x14, 0, 0xb, 0, 0x1f, 0, + 0x1, 0, 0x8, 0, 0, 0, 0x4d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0xa, 0, 0x5, 0, 0x4d, 0xab, + 0x82, 0x3d, 0xda, 0x62, 0xcf, 0x11, 0xab, 0x39, 0, 0x20, + 0xaf, 0x71, 0xe4, 0x33, 0x1, 0, 0x9, 0, 0, 0, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x52, 0x47, 0x42, 0x41, 0x1, + 0, 0x9, 0, 0, 0, 0x66, 0x61, 0x63, 0x65, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x14, 0, 0x2a, 0, 0x1, 0, + 0x5, 0, 0, 0, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x14, + 0, 0x1, 0, 0x8, 0, 0, 0, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x52, 0x47, 0x42, 0x1, 0, 0xd, 0, 0, + 0, 0x73, 0x70, 0x65, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x14, 0, 0x1, 0, 0x8, 0, + 0, 0, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x52, 0x47, 0x42, + 0x1, 0, 0xd, 0, 0, 0, 0x65, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x14, + 0, 0xe, 0, 0x12, 0, 0x12, 0, 0x12, 0, 0xf, + 0, 0xb, 0, 0x1f, 0, 0x1, 0, 0x8, 0, 0, + 0, 0x4d, 0x65, 0x73, 0x68, 0x46, 0x61, 0x63, 0x65, 0xa, + 0, 0x5, 0, 0x5f, 0xab, 0x82, 0x3d, 0xda, 0x62, 0xcf, + 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, 0x33, 0x29, + 0, 0x1, 0, 0x12, 0, 0, 0, 0x6e, 0x46, 0x61, + 0x63, 0x65, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, + 0x64, 0x69, 0x63, 0x65, 0x73, 0x14, 0, 0x34, 0, 0x29, + 0, 0x1, 0, 0x11, 0, 0, 0, 0x66, 0x61, 0x63, + 0x65, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x64, + 0x69, 0x63, 0x65, 0x73, 0xe, 0, 0x1, 0, 0x12, 0, + 0, 0, 0x6e, 0x46, 0x61, 0x63, 0x65, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, + 0xf, 0, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, 0, + 0xd, 0, 0, 0, 0x4d, 0x65, 0x73, 0x68, 0x46, 0x61, + 0x63, 0x65, 0x57, 0x72, 0x61, 0x70, 0x73, 0xa, 0, 0x5, + 0, 0xc0, 0xc5, 0x1e, 0xed, 0xa8, 0xc0, 0xd0, 0x11, 0x94, + 0x1c, 0, 0x80, 0xc8, 0xc, 0xfa, 0x7b, 0x29, 0, 0x1, + 0, 0xf, 0, 0, 0, 0x6e, 0x46, 0x61, 0x63, 0x65, + 0x57, 0x72, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x14, 0, 0x34, 0, 0x1, 0, 0x9, 0, 0, 0, + 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x32, 0x64, 0x1, + 0, 0xe, 0, 0, 0, 0x66, 0x61, 0x63, 0x65, 0x57, + 0x72, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0xe, + 0, 0x1, 0, 0xf, 0, 0, 0, 0x6e, 0x46, 0x61, + 0x63, 0x65, 0x57, 0x72, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0xf, 0, 0x14, 0, 0xb, 0, 0x1f, 0, + 0x1, 0, 0x11, 0, 0, 0, 0x4d, 0x65, 0x73, 0x68, + 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6f, + 0x72, 0x64, 0x73, 0xa, 0, 0x5, 0, 0x40, 0x3f, 0xf2, + 0xf6, 0x86, 0x76, 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, + 0x35, 0x94, 0xa3, 0x29, 0, 0x1, 0, 0xe, 0, 0, + 0, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, + 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x14, 0, 0x34, 0, 0x1, + 0, 0x8, 0, 0, 0, 0x43, 0x6f, 0x6f, 0x72, 0x64, + 0x73, 0x32, 0x64, 0x1, 0, 0xd, 0, 0, 0, 0x74, + 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6f, 0x72, + 0x64, 0x73, 0xe, 0, 0x1, 0, 0xe, 0, 0, 0, + 0x6e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, + 0x6f, 0x72, 0x64, 0x73, 0xf, 0, 0x14, 0, 0xb, 0, + 0x1f, 0, 0x1, 0, 0x10, 0, 0, 0, 0x4d, 0x65, + 0x73, 0x68, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, + 0x4c, 0x69, 0x73, 0x74, 0xa, 0, 0x5, 0, 0x42, 0x3f, + 0xf2, 0xf6, 0x86, 0x76, 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, + 0x33, 0x35, 0x94, 0xa3, 0x29, 0, 0x1, 0, 0xa, 0, + 0, 0, 0x6e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x73, 0x14, 0, 0x29, 0, 0x1, 0, 0xc, 0, + 0, 0, 0x6e, 0x46, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x65, 0x73, 0x14, 0, 0x34, 0, 0x29, 0, + 0x1, 0, 0xb, 0, 0, 0, 0x66, 0x61, 0x63, 0x65, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0xe, 0, 0x1, + 0, 0xc, 0, 0, 0, 0x6e, 0x46, 0x61, 0x63, 0x65, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0xf, 0, 0x14, + 0, 0xe, 0, 0x1, 0, 0x8, 0, 0, 0, 0x4d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0xf, 0, 0xb, + 0, 0x1f, 0, 0x1, 0, 0xb, 0, 0, 0, 0x4d, + 0x65, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, + 0xa, 0, 0x5, 0, 0x43, 0x3f, 0xf2, 0xf6, 0x86, 0x76, + 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, + 0x29, 0, 0x1, 0, 0x8, 0, 0, 0, 0x6e, 0x4e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, 0x14, 0, 0x34, 0, + 0x1, 0, 0x6, 0, 0, 0, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x1, 0, 0x7, 0, 0, 0, 0x6e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x73, 0xe, 0, 0x1, 0, 0x8, + 0, 0, 0, 0x6e, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x73, 0xf, 0, 0x14, 0, 0x29, 0, 0x1, 0, 0xc, + 0, 0, 0, 0x6e, 0x46, 0x61, 0x63, 0x65, 0x4e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x73, 0x14, 0, 0x34, 0, 0x1, + 0, 0x8, 0, 0, 0, 0x4d, 0x65, 0x73, 0x68, 0x46, + 0x61, 0x63, 0x65, 0x1, 0, 0xb, 0, 0, 0, 0x66, + 0x61, 0x63, 0x65, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, + 0xe, 0, 0x1, 0, 0xc, 0, 0, 0, 0x6e, 0x46, + 0x61, 0x63, 0x65, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, + 0xf, 0, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, 0, + 0x10, 0, 0, 0, 0x4d, 0x65, 0x73, 0x68, 0x56, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x73, + 0xa, 0, 0x5, 0, 0x21, 0xb8, 0x30, 0x16, 0x42, 0x78, + 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, + 0x29, 0, 0x1, 0, 0xd, 0, 0, 0, 0x6e, 0x56, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x73, 0x14, 0, 0x34, 0, 0x1, 0, 0xc, 0, 0, + 0, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x1, 0, 0xc, 0, 0, 0, 0x76, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x73, 0xe, 0, 0x1, 0, 0xd, 0, 0, 0, 0x6e, + 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x73, 0xf, 0, 0x14, 0, 0xb, 0, 0x1f, 0, + 0x1, 0, 0x4, 0, 0, 0, 0x4d, 0x65, 0x73, 0x68, + 0xa, 0, 0x5, 0, 0x44, 0xab, 0x82, 0x3d, 0xda, 0x62, + 0xcf, 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, 0x33, + 0x29, 0, 0x1, 0, 0x9, 0, 0, 0, 0x6e, 0x56, + 0x65, 0x72, 0x74, 0x69, 0x63, 0x65, 0x73, 0x14, 0, 0x34, + 0, 0x1, 0, 0x6, 0, 0, 0, 0x56, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x1, 0, 0x8, 0, 0, 0, 0x76, + 0x65, 0x72, 0x74, 0x69, 0x63, 0x65, 0x73, 0xe, 0, 0x1, + 0, 0x9, 0, 0, 0, 0x6e, 0x56, 0x65, 0x72, 0x74, + 0x69, 0x63, 0x65, 0x73, 0xf, 0, 0x14, 0, 0x29, 0, + 0x1, 0, 0x6, 0, 0, 0, 0x6e, 0x46, 0x61, 0x63, + 0x65, 0x73, 0x14, 0, 0x34, 0, 0x1, 0, 0x8, 0, + 0, 0, 0x4d, 0x65, 0x73, 0x68, 0x46, 0x61, 0x63, 0x65, + 0x1, 0, 0x5, 0, 0, 0, 0x66, 0x61, 0x63, 0x65, + 0x73, 0xe, 0, 0x1, 0, 0x6, 0, 0, 0, 0x6e, + 0x46, 0x61, 0x63, 0x65, 0x73, 0xf, 0, 0x14, 0, 0xe, + 0, 0x12, 0, 0x12, 0, 0x12, 0, 0xf, 0, 0xb, + 0, 0x1f, 0, 0x1, 0, 0x14, 0, 0, 0, 0x46, + 0x72, 0x61, 0x6d, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0xa, + 0, 0x5, 0, 0x41, 0x3f, 0xf2, 0xf6, 0x86, 0x76, 0xcf, + 0x11, 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, 0x1, + 0, 0x9, 0, 0, 0, 0x4d, 0x61, 0x74, 0x72, 0x69, + 0x78, 0x34, 0x78, 0x34, 0x1, 0, 0xb, 0, 0, 0, + 0x66, 0x72, 0x61, 0x6d, 0x65, 0x4d, 0x61, 0x74, 0x72, 0x69, + 0x78, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, 0, 0x5, + 0, 0, 0, 0x46, 0x72, 0x61, 0x6d, 0x65, 0xa, 0, + 0x5, 0, 0x46, 0xab, 0x82, 0x3d, 0xda, 0x62, 0xcf, 0x11, + 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, 0x33, 0xe, 0, + 0x12, 0, 0x12, 0, 0x12, 0, 0xf, 0, 0xb, 0, + 0x1f, 0, 0x1, 0, 0x9, 0, 0, 0, 0x46, 0x6c, + 0x6f, 0x61, 0x74, 0x4b, 0x65, 0x79, 0x73, 0xa, 0, 0x5, + 0, 0xa9, 0x46, 0xdd, 0x10, 0x5b, 0x77, 0xcf, 0x11, 0x8f, + 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, 0x29, 0, 0x1, + 0, 0x7, 0, 0, 0, 0x6e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x14, 0, 0x34, 0, 0x2a, 0, 0x1, 0, + 0x6, 0, 0, 0, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0xe, 0, 0x1, 0, 0x7, 0, 0, 0, 0x6e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0xf, 0, 0x14, 0, 0xb, + 0, 0x1f, 0, 0x1, 0, 0xe, 0, 0, 0, 0x54, + 0x69, 0x6d, 0x65, 0x64, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0xa, 0, 0x5, 0, 0x80, 0xb1, 0x6, + 0xf4, 0x3b, 0x7b, 0xcf, 0x11, 0x8f, 0x52, 0, 0x40, 0x33, + 0x35, 0x94, 0xa3, 0x29, 0, 0x1, 0, 0x4, 0, 0, + 0, 0x74, 0x69, 0x6d, 0x65, 0x14, 0, 0x1, 0, 0x9, + 0, 0, 0, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x4b, 0x65, + 0x79, 0x73, 0x1, 0, 0x6, 0, 0, 0, 0x74, 0x66, + 0x6b, 0x65, 0x79, 0x73, 0x14, 0, 0xb, 0, 0x1f, 0, + 0x1, 0, 0xc, 0, 0, 0, 0x41, 0x6e, 0x69, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0xa, 0, + 0x5, 0, 0xa8, 0x46, 0xdd, 0x10, 0x5b, 0x77, 0xcf, 0x11, + 0x8f, 0x52, 0, 0x40, 0x33, 0x35, 0x94, 0xa3, 0x29, 0, + 0x1, 0, 0x7, 0, 0, 0, 0x6b, 0x65, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x14, 0, 0x29, 0, 0x1, 0, 0x5, + 0, 0, 0, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x14, 0, + 0x34, 0, 0x1, 0, 0xe, 0, 0, 0, 0x54, 0x69, + 0x6d, 0x65, 0x64, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x4b, 0x65, + 0x79, 0x73, 0x1, 0, 0x4, 0, 0, 0, 0x6b, 0x65, + 0x79, 0x73, 0xe, 0, 0x1, 0, 0x5, 0, 0, 0, + 0x6e, 0x4b, 0x65, 0x79, 0x73, 0xf, 0, 0x14, 0, 0xb, + 0, 0x1f, 0, 0x1, 0, 0x10, 0, 0, 0, 0x41, + 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa, 0, 0x5, 0, 0xc0, + 0x56, 0xbf, 0xe2, 0xf, 0x84, 0xcf, 0x11, 0x8f, 0x52, 0, + 0x40, 0x33, 0x35, 0x94, 0xa3, 0x29, 0, 0x1, 0, 0xa, + 0, 0, 0, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x64, 0x14, 0, 0x29, 0, 0x1, 0, 0xf, + 0, 0, 0, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x14, 0, + 0xb, 0, 0x1f, 0, 0x1, 0, 0x9, 0, 0, 0, + 0x41, 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xa, + 0, 0x5, 0, 0x4f, 0xab, 0x82, 0x3d, 0xda, 0x62, 0xcf, + 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, 0x33, 0xe, + 0, 0x12, 0, 0x12, 0, 0x12, 0, 0xf, 0, 0xb, + 0, 0x1f, 0, 0x1, 0, 0xc, 0, 0, 0, 0x41, + 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x74, 0xa, 0, 0x5, 0, 0x50, 0xab, 0x82, 0x3d, 0xda, + 0x62, 0xcf, 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, + 0x33, 0xe, 0, 0x1, 0, 0x9, 0, 0, 0, 0x41, + 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xf, 0, + 0xb, 0, 0x1f, 0, 0x1, 0, 0xa, 0, 0, 0, + 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x44, 0x61, 0x74, 0x61, + 0xa, 0, 0x5, 0, 0xa0, 0xee, 0x23, 0x3a, 0xb1, 0x94, + 0xd0, 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, 0x33, + 0xe, 0, 0x1, 0, 0x6, 0, 0, 0, 0x42, 0x49, + 0x4e, 0x41, 0x52, 0x59, 0xf, 0, 0xb, 0, 0x1f, 0, + 0x1, 0, 0x3, 0, 0, 0, 0x55, 0x72, 0x6c, 0xa, + 0, 0x5, 0, 0xa1, 0xee, 0x23, 0x3a, 0xb1, 0x94, 0xd0, + 0x11, 0xab, 0x39, 0, 0x20, 0xaf, 0x71, 0xe4, 0x33, 0x29, + 0, 0x1, 0, 0x5, 0, 0, 0, 0x6e, 0x55, 0x72, + 0x6c, 0x73, 0x14, 0, 0x34, 0, 0x31, 0, 0x1, 0, + 0x4, 0, 0, 0, 0x75, 0x72, 0x6c, 0x73, 0xe, 0, + 0x1, 0, 0x5, 0, 0, 0, 0x6e, 0x55, 0x72, 0x6c, + 0x73, 0xf, 0, 0x14, 0, 0xb, 0, 0x1f, 0, 0x1, + 0, 0xf, 0, 0, 0, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x65, 0x73, 0x68, + 0xa, 0, 0x5, 0, 0x60, 0xc3, 0x63, 0x8a, 0x7d, 0x99, + 0xd0, 0x11, 0x94, 0x1c, 0, 0x80, 0xc8, 0xc, 0xfa, 0x7b, + 0xe, 0, 0x1, 0, 0x3, 0, 0, 0, 0x55, 0x72, + 0x6c, 0x13, 0, 0x1, 0, 0xa, 0, 0, 0, 0x49, + 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x44, 0x61, 0x74, 0x61, 0xf, + 0, 0xb, 0, 0x1f, 0, 0x1, 0, 0x4, 0, 0, + 0, 0x47, 0x75, 0x69, 0x64, 0xa, 0, 0x5, 0, 0xe0, + 0x90, 0x27, 0xa4, 0x10, 0x78, 0xcf, 0x11, 0x8f, 0x52, 0, + 0x40, 0x33, 0x35, 0x94, 0xa3, 0x29, 0, 0x1, 0, 0x5, + 0, 0, 0, 0x64, 0x61, 0x74, 0x61, 0x31, 0x14, 0, + 0x28, 0, 0x1, 0, 0x5, 0, 0, 0, 0x64, 0x61, + 0x74, 0x61, 0x32, 0x14, 0, 0x28, 0, 0x1, 0, 0x5, + 0, 0, 0, 0x64, 0x61, 0x74, 0x61, 0x33, 0x14, 0, + 0x34, 0, 0x2d, 0, 0x1, 0, 0x5, 0, 0, 0, + 0x64, 0x61, 0x74, 0x61, 0x34, 0xe, 0, 0x3, 0, 0x8, + 0, 0, 0, 0xf, 0, 0x14, 0, 0xb, 0, 0x1f, + 0, 0x1, 0, 0xe, 0, 0, 0, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0xa, 0, 0x5, 0, 0xe0, 0x21, 0xf, 0x7f, 0xe1, + 0xbf, 0xd1, 0x11, 0x82, 0xc0, 0, 0xa0, 0xc9, 0x69, 0x72, + 0x71, 0x31, 0, 0x1, 0, 0x3, 0, 0, 0, 0x6b, + 0x65, 0x79, 0x14, 0, 0x31, 0, 0x1, 0, 0x5, 0, + 0, 0, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x14, 0, 0xb, + 0, 0x1f, 0, 0x1, 0, 0xb, 0, 0, 0, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x42, 0x61, 0x67, + 0xa, 0, 0x5, 0, 0xe1, 0x21, 0xf, 0x7f, 0xe1, 0xbf, + 0xd1, 0x11, 0x82, 0xc0, 0, 0xa0, 0xc9, 0x69, 0x72, 0x71, + 0xe, 0, 0x1, 0, 0xe, 0, 0, 0, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0xf, 0, 0xb, 0, 0x1f, 0, 0x1, 0, + 0xe, 0, 0, 0, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6c, 0xa, 0, + 0x5, 0, 0xa0, 0x6a, 0x11, 0x98, 0xba, 0xbd, 0xd1, 0x11, + 0x82, 0xc0, 0, 0xa0, 0xc9, 0x69, 0x72, 0x71, 0x1, 0, + 0x4, 0, 0, 0, 0x47, 0x75, 0x69, 0x64, 0x1, 0, + 0x12, 0, 0, 0, 0x67, 0x75, 0x69, 0x64, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x69, 0x73, 0x75, + 0x61, 0x6c, 0x14, 0, 0xe, 0, 0x12, 0, 0x12, 0, + 0x12, 0, 0xf, 0, 0xb, 0, 0x1f, 0, 0x1, 0, + 0xb, 0, 0, 0, 0x52, 0x69, 0x67, 0x68, 0x74, 0x48, + 0x61, 0x6e, 0x64, 0x65, 0x64, 0xa, 0, 0x5, 0, 0xa0, + 0x5e, 0x5d, 0x7f, 0x3a, 0xd5, 0xd1, 0x11, 0x82, 0xc0, 0, + 0xa0, 0xc9, 0x69, 0x72, 0x71, 0x29, 0, 0x1, 0, 0xc, + 0, 0, 0, 0x62, 0x52, 0x69, 0x67, 0x68, 0x74, 0x48, + 0x61, 0x6e, 0x64, 0x65, 0x64, 0x14, 0, 0xb, 0 +}; + +#define D3DRM_XTEMPLATE_BYTES 3278 + +#endif /* _RMXFTMPL_H_ */ diff --git a/dxsdk/Include/rpcsal.h b/dxsdk/Include/rpcsal.h new file mode 100644 index 0000000..484ddc9 --- /dev/null +++ b/dxsdk/Include/rpcsal.h @@ -0,0 +1,499 @@ +/****************************************************************\ +* * +* rpcsal.h - markers for documenting the semantics of RPC APIs * +* * +* Version 1.0 * +* * +* Copyright (c) 2004 Microsoft Corporation. All rights reserved. * +* * +\****************************************************************/ + +// ------------------------------------------------------------------------------- +// Introduction +// +// rpcsal.h provides a set of annotations to describe how RPC functions use their +// parameters - the assumptions it makes about them, adn the guarantees it makes +// upon finishing. These annotations are similar to those found in specstrings.h, +// but are designed to be used by the MIDL compiler when it generates annotations +// enabled header files. +// +// IDL authors do not need to annotate their functions declarations. The MIDL compiler +// will interpret the IDL directives and use one of the annotations contained +// in this header. This documentation is intended to help those trying to understand +// the MIDL-generated header files or those who maintain their own copies of these files. +// +// ------------------------------------------------------------------------------- +// Differences between rpcsal.h and specstrings.h +// +// There are a few important differences between the annotations found in rpcsal.h and +// those in specstrings.h: +// +// 1. [in] parameters are not marked as read-only. They may be used for scratch space +// at the server and changes will not affect the client. +// 2. String versions of each macro alleviates the need for a special type definition +// +// ------------------------------------------------------------------------------- +// Interpreting RPC Annotations +// +// These annotations are interpreted precisely in the same way as those in specstrings.h. +// Please refer to that header for information related to general usage in annotations. +// +// To construct an RPC annotation, concatenate the appropriate value from each category +// along with a leading __RPC_. A typical annotation looks like "__RPC__in_string". +// +// |----------------------------------------------------------------------------------| +// | RPC Annotations | +// |------------|------------|---------|--------|----------|----------|---------------| +// | Level | Usage | Size | Output | Optional | String | Parameters | +// |------------|------------|---------|--------|----------|----------|---------------| +// | <> | <> | <> | <> | <> | <> | <> | +// | _deref | _in | _ecount | _full | _opt | _string | (size) | +// | _deref_opt | _out | _bcount | _part | | | (size,length) | +// | | _inout | | | | | | +// | | | | | | | | +// |------------|------------|---------|--------|----------|----------|---------------| +// +// Level: Describes the buffer pointer's level of indirection from the parameter or +// return value 'p'. +// +// <> : p is the buffer pointer. +// _deref : *p is the buffer pointer. p must not be NULL. +// _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the rest of +// the annotation is ignored. +// +// Usage: Describes how the function uses the buffer. +// +// <> : The buffer is not accessed. If used on the return value or with _deref, the +// function will provide the buffer, and it will be uninitialized at exit. +// Otherwise, the caller must provide the buffer. This should only be used +// for alloc and free functions. +// _in : The function will only read from the buffer. The caller must provide the +// buffer and initialize it. Cannot be used with _deref. +// _out : The function will only write to the buffer. If used on the return value or +// with _deref, the function will provide the buffer and initialize it. +// Otherwise, the caller must provide the buffer, and the function will +// initialize it. +// _inout : The function may freely read from and write to the buffer. The caller must +// provide the buffer and initialize it. If used with _deref, the buffer may +// be reallocated by the function. +// +// Size: Describes the total size of the buffer. This may be less than the space actually +// allocated for the buffer, in which case it describes the accessible amount. +// +// <> : No buffer size is given. If the type specifies the buffer size (such as +// with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is one +// element long. Must be used with _in, _out, or _inout. +// _ecount : The buffer size is an explicit element count. +// _bcount : The buffer size is an explicit byte count. +// +// Output: Describes how much of the buffer will be initialized by the function. For +// _inout buffers, this also describes how much is initialized at entry. Omit this +// category for _in buffers; they must be fully initialized by the caller. +// +// <> : The type specifies how much is initialized. For instance, a function initializing +// an LPWSTR must NULL-terminate the string. +// _full : The function initializes the entire buffer. +// _part : The function initializes part of the buffer, and explicitly indicates how much. +// +// Optional: Describes if the buffer itself is optional. +// +// <> : The pointer to the buffer must not be NULL. +// _opt : The pointer to the buffer might be NULL. It will be checked before being dereferenced. +// +// String: Describes if the buffer is NULL terminated +// +// <> : The buffer is not assumed to be NULL terminated +// _string : The buffer is assumed to be NULL terminated once it has been initialized +// +// Parameters: Gives explicit counts for the size and length of the buffer. +// +// <> : There is no explicit count. Use when neither _ecount nor _bcount is used. +// (size) : Only the buffer's total size is given. Use with _ecount or _bcount but not _part. +// (size,length) : The buffer's total size and initialized length are given. Use with _ecount_part +// and _bcount_part. +// +// Notes: +// +// 1. Specifying two buffer annotations on a single parameter results in unspecified behavior +// (e.g. __RPC__in_bcount(5) __RPC__out_bcount(6) +// +// 2. The size of the buffer and the amount that has been initialized are separate concepts. +// Specify the size using _ecount or _bcount. Specify the amount that is initialized using +// _full, _part, or _string. As a special case, a single element buffer does not need +// _ecount, _bcount, _full, or _part +// +// 3. The count may be less than the total size of the buffer in which case it describes the +// accessible portion. +// +// 4. "__RPC__opt" and "__RPC_deref" are not valid annotations. +// +// 5. The placement of _opt when using _deref is important: +// __RPC__deref_opt_... : Input may be NULL +// __RPC__deref_..._opt : Output may be NULL +// __RPC__deref_opt_..._opt : Both input and output may be NULL +// + +#pragma once + +#include + +#ifndef __RPCSAL_H_VERSION__ +#define __RPCSAL_H_VERSION__ ( 100 ) +#endif // __RPCSAL_H_VERSION__ + +#ifdef __REQUIRED_RPCSAL_H_VERSION__ + #if ( __RPCSAL_H_VERSION__ < __REQUIRED_RPCSAL_H_VERSION__ ) + #error incorrect version. Use the header that matches with the MIDL compiler. + #endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif // #ifdef __cplusplus + +#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_) + + +// [in] +#define __RPC__in __pre __valid +#define __RPC__in_string __RPC__in __pre __nullterminated +#define __RPC__in_ecount(size) __RPC__in __pre __elem_readableTo(size) +#define __RPC__in_ecount_full(size) __RPC__in_ecount(size) +#define __RPC__in_ecount_full_string(size) __RPC__in_ecount_full(size) __pre __nullterminated +#define __RPC__in_ecount_part(size, length) __RPC__in_ecount(length) __pre __elem_writableTo(size) +#define __RPC__in_ecount_full_opt(size) __RPC__in_ecount_full(size) __pre __exceptthat __maybenull +#define __RPC__in_ecount_full_opt_string(size) __RPC__in_ecount_full_opt(size) __pre __nullterminated +#define __RPC__in_ecount_part_opt(size, length) __RPC__in_ecount_part(size, length) __pre __exceptthat __maybenull +#define __RPC__in_xcount(size) __RPC__in __pre __elem_readableTo(size) +#define __RPC__in_xcount_full(size) __RPC__in_ecount(size) +#define __RPC__in_xcount_full_string(size) __RPC__in_ecount_full(size) __pre __nullterminated +#define __RPC__in_xcount_part(size, length) __RPC__in_ecount(length) __pre __elem_writableTo(size) +#define __RPC__in_xcount_full_opt(size) __RPC__in_ecount_full(size) __pre __exceptthat __maybenull +#define __RPC__in_xcount_full_opt_string(size) __RPC__in_ecount_full_opt(size) __pre __nullterminated +#define __RPC__in_xcount_part_opt(size, length) __RPC__in_ecount_part(size, length) __pre __exceptthat __maybenull + + +#define __RPC__deref_in __RPC__in __deref __notnull +#define __RPC__deref_in_string __RPC__in __pre __deref __nullterminated +#define __RPC__deref_in_opt __RPC__deref_in __deref __exceptthat __maybenull +#define __RPC__deref_in_opt_string __RPC__deref_in_opt __pre __deref __nullterminated +#define __RPC__deref_opt_in __RPC__in __exceptthat __maybenull +#define __RPC__deref_opt_in_string __RPC__deref_opt_in __pre __deref __nullterminated +#define __RPC__deref_opt_in_opt __RPC__deref_opt_in __pre __deref __exceptthat __maybenull +#define __RPC__deref_opt_in_opt_string __RPC__deref_opt_in_opt __pre __deref __nullterminated +#define __RPC__deref_in_ecount(size) __RPC__in __pre __deref __elem_readableTo(size) +#define __RPC__deref_in_ecount_part(size, length) __RPC__deref_in_ecount(size) __pre __deref __elem_readableTo(length) +#define __RPC__deref_in_ecount_full(size) __RPC__deref_in_ecount_part(size, size) +#define __RPC__deref_in_ecount_full_opt(size) __RPC__deref_in_ecount_full(size) __pre __deref __exceptthat __maybenull +#define __RPC__deref_in_ecount_full_opt_string(size) __RPC__deref_in_ecount_full_opt(size) __pre __deref __nullterminated +#define __RPC__deref_in_ecount_full_string(size) __RPC__deref_in_ecount_full(size) __pre __deref __nullterminated +#define __RPC__deref_in_ecount_opt(size) __RPC__deref_in_ecount(size) __pre __deref __exceptthat __maybenull +#define __RPC__deref_in_ecount_opt_string(size) __RPC__deref_in_ecount_opt(size) __pre __deref __nullterminated +#define __RPC__deref_in_ecount_part_opt(size, length) __RPC__deref_in_ecount_opt(size) __pre __deref __elem_readableTo(length) +#define __RPC__deref_in_xcount(size) __RPC__in __pre __deref __elem_readableTo(size) +#define __RPC__deref_in_xcount_part(size, length) __RPC__deref_in_ecount(size) __pre __deref __elem_readableTo(length) +#define __RPC__deref_in_xcount_full(size) __RPC__deref_in_ecount_part(size, size) +#define __RPC__deref_in_xcount_full_opt(size) __RPC__deref_in_ecount_full(size) __pre __deref __exceptthat __maybenull +#define __RPC__deref_in_xcount_full_opt_string(size) __RPC__deref_in_ecount_full_opt(size) __pre __deref __nullterminated +#define __RPC__deref_in_xcount_full_string(size) __RPC__deref_in_ecount_full(size) __pre __deref __nullterminated +#define __RPC__deref_in_xcount_opt(size) __RPC__deref_in_ecount(size) __pre __deref __exceptthat __maybenull +#define __RPC__deref_in_xcount_opt_string(size) __RPC__deref_in_ecount_opt(size) __pre __deref __nullterminated +#define __RPC__deref_in_xcount_part_opt(size, length) __RPC__deref_in_ecount_opt(size) __pre __deref __elem_readableTo(length) + +// [out] +#define __RPC__out __out +#define __RPC__out_ecount(size) __out_ecount(size) __post __elem_writableTo(size) +#define __RPC__out_ecount_string(size) __RPC__out_ecount(size) __post __nullterminated +#define __RPC__out_ecount_part(size, length) __RPC__out_ecount(size) __post __elem_readableTo(length) +#define __RPC__out_ecount_full(size) __RPC__out_ecount_part(size, size) +#define __RPC__out_ecount_full_string(size) __RPC__out_ecount_full(size) __post __nullterminated +#define __RPC__out_xcount(size) __out +#define __RPC__out_xcount_string(size) __RPC__out __post __nullterminated +#define __RPC__out_xcount_part(size, length) __RPC__out +#define __RPC__out_xcount_full(size) __RPC__out +#define __RPC__out_xcount_full_string(size) __RPC__out __post __nullterminated + +// [in,out] +#define __RPC__inout __inout +#define __RPC__inout_string __RPC__inout __pre __nullterminated __post __nullterminated +#define __RPC__inout_ecount(size) __inout_ecount(size) +#define __RPC__inout_ecount_part(size, length) __inout_ecount_part(size, length) +#define __RPC__inout_ecount_full(size) __RPC__inout_ecount_part(size, size) +#define __RPC__inout_ecount_full_string(size) __RPC__inout_ecount_full(size) __pre __nullterminated __post __nullterminated +#define __RPC__inout_xcount(size) __inout +#define __RPC__inout_xcount_part(size, length) __inout +#define __RPC__inout_xcount_full(size) __RPC__inout +#define __RPC__inout_xcount_full_string(size) __RPC__inout __pre __nullterminated __post __nullterminated + +// [in,unique] +#define __RPC__in_opt __RPC__in __pre __exceptthat __maybenull +#define __RPC__in_opt_string __RPC__in_opt __pre __nullterminated +#define __RPC__in_ecount_opt(size) __RPC__in_ecount(size) __pre __exceptthat __maybenull +#define __RPC__in_ecount_opt_string(size) __RPC__in_ecount_opt(size) __pre __nullterminated +#define __RPC__in_xcount_opt(size) __RPC__in_ecount(size) __pre __exceptthat __maybenull +#define __RPC__in_xcount_opt_string(size) __RPC__in_ecount_opt(size) __pre __nullterminated + +// [in,out,unique] +#define __RPC__inout_opt __inout_opt +#define __RPC__inout_opt_string __RPC__inout_opt __pre __nullterminated +#define __RPC__inout_ecount_opt(size) __inout_ecount_opt(size) +#define __RPC__inout_ecount_part_opt(size, length) __inout_ecount_part_opt(size, length) +#define __RPC__inout_ecount_full_opt(size) __RPC__inout_ecount_part_opt(size, size) +#define __RPC__inout_ecount_full_opt_string(size) __RPC__inout_ecount_full_opt(size) __pre __nullterminated __post __nullterminated +#define __RPC__inout_xcount_opt(size) __inout_opt +#define __RPC__inout_xcount_part_opt(size, length) __inout_opt +#define __RPC__inout_xcount_full_opt(size) __RPC__inout_opt +#define __RPC__inout_xcount_full_opt_string(size) __RPC__inout_opt __pre __nullterminated __post __nullterminated + +// [out] ** +#define __RPC__deref_out __deref_out +#define __RPC__deref_out_string __RPC__deref_out __post __deref __nullterminated +// Removed "__post __deref __exceptthat __maybenull" so return values from QueryInterface and the like can be trusted without an explicit NULL check. +// This is a temporary fix until midl.exe can be rev'd to produce more accurate annotations. +#define __RPC__deref_out_opt __RPC__deref_out +#define __RPC__deref_out_opt_string __RPC__deref_out_opt __post __deref __nullterminated __pre __deref __null +#define __RPC__deref_out_ecount(size) __deref_out_ecount(size) __post __deref __elem_writableTo(size) +#define __RPC__deref_out_ecount_part(size, length) __RPC__deref_out_ecount(size) __post __deref __elem_readableTo(length) +#define __RPC__deref_out_ecount_full(size) __RPC__deref_out_ecount_part(size,size) +#define __RPC__deref_out_ecount_full_string(size) __RPC__deref_out_ecount_full(size) __post __deref __nullterminated +#define __RPC__deref_out_xcount(size) __deref_out __post __deref +#define __RPC__deref_out_xcount_part(size, length) __RPC__deref_out __post __deref +#define __RPC__deref_out_xcount_full(size) __RPC__deref_out +#define __RPC__deref_out_xcount_full_string(size) __RPC__deref_out __post __deref __nullterminated + +// [in,out] **, second pointer decoration. +#define __RPC__deref_inout __deref_inout +#define __RPC__deref_inout_string __RPC__deref_inout __pre __deref __nullterminated __post __deref __nullterminated +#define __RPC__deref_inout_opt __deref_inout_opt +#define __RPC__deref_inout_opt_string __RPC__deref_inout_opt __deref __nullterminated +#define __RPC__deref_inout_ecount_opt(size) __deref_inout_ecount_opt(size) +#define __RPC__deref_inout_ecount_part_opt(size, length) __deref_inout_ecount_part_opt(size , length) +#define __RPC__deref_inout_ecount_full_opt(size) __RPC__deref_inout_ecount_part_opt(size, size) +#define __RPC__deref_inout_ecount_full(size) __deref_inout_ecount_full(size) +#define __RPC__deref_inout_ecount_full_string(size) __RPC__deref_inout_ecount_full(size) __post __deref __nullterminated +#define __RPC__deref_inout_ecount_full_opt_string(size) __RPC__deref_inout_ecount_full_opt(size) __pre __deref __nullterminated __post __deref __nullterminated +#define __RPC__deref_inout_xcount_opt(size) __deref_inout_opt +#define __RPC__deref_inout_xcount_part_opt(size, length) __deref_inout_opt +#define __RPC__deref_inout_xcount_full_opt(size) __RPC__deref_inout_opt +#define __RPC__deref_inout_xcount_full(size) __deref_inout +#define __RPC__deref_inout_xcount_full_string(size) __RPC__deref_inout __post __deref __nullterminated +#define __RPC__deref_inout_xcount_full_opt_string(size) __RPC__deref_inout_opt __pre __deref __nullterminated __post __deref __nullterminated + + +// #define __RPC_out_opt out_opt is not allowed in rpc + +// [in,out,unique] +#define __RPC__deref_opt_inout __deref_opt_inout +#define __RPC__deref_opt_inout_ecount(size) __deref_opt_inout_ecount(size) +#define __RPC__deref_opt_inout_string __RPC__deref_opt_inout __pre __deref __nullterminated __post __deref __nullterminated +#define __RPC__deref_opt_inout_ecount_part(size, length) __deref_opt_inout_ecount_part(size, length) +#define __RPC__deref_opt_inout_ecount_full(size) __deref_opt_inout_ecount_full(size) +#define __RPC__deref_opt_inout_ecount_full_string(size) __RPC__deref_opt_inout_ecount_full(size) __pre __deref __nullterminated __post __deref __nullterminated +#define __RPC__deref_opt_inout_xcount_part(size, length) __deref_opt_inout +#define __RPC__deref_opt_inout_xcount_full(size) __deref_opt_inout +#define __RPC__deref_opt_inout_xcount_full_string(size) __RPC__deref_opt_inout __pre __deref __nullterminated __post __deref __nullterminated + + +// We don't need to specify __pre __deref __exceptthat __maybenull : this is default behavior. While this might not hold in SAL 1.1 syntax, SAL team +// believes it's OK. We can revisit if SAL 1.1 can survive. +#define __RPC__deref_out_ecount_opt(size) __RPC__out_ecount(size) __post __deref __exceptthat __maybenull __pre __deref __null +#define __RPC__deref_out_ecount_part_opt(size, length) __RPC__deref_out_ecount_part(size, length) __post __deref __exceptthat __maybenull __pre __deref __null +#define __RPC__deref_out_ecount_full_opt(size) __RPC__deref_out_ecount_part_opt(size, size) __pre __deref __null +#define __RPC__deref_out_ecount_full_opt_string(size) __RPC__deref_out_ecount_part_opt(size, size) __post __deref __nullterminated __pre __deref __null +#define __RPC__deref_out_xcount_opt(size) __RPC__out __post __deref __exceptthat __maybenull __pre __deref __null +#define __RPC__deref_out_xcount_part_opt(size, length) __RPC__deref_out __post __deref __exceptthat __maybenull __pre __deref __null +#define __RPC__deref_out_xcount_full_opt(size) __RPC__deref_out_opt __pre __deref __null +#define __RPC__deref_out_xcount_full_opt_string(size) __RPC__deref_out_opt __post __deref __nullterminated __pre __deref __null + +#define __RPC__deref_opt_inout_opt __deref_opt_inout_opt +#define __RPC__deref_opt_inout_opt_string __RPC__deref_opt_inout_opt __pre __deref __nullterminated __post __deref __nullterminated +#define __RPC__deref_opt_inout_ecount_opt(size) __deref_opt_inout_ecount_opt(size) +#define __RPC__deref_opt_inout_ecount_part_opt(size, length) __deref_opt_inout_ecount_part_opt(size, length) +#define __RPC__deref_opt_inout_ecount_full_opt(size) __RPC__deref_opt_inout_ecount_part_opt(size, size) +#define __RPC__deref_opt_inout_ecount_full_opt_string(size) __RPC__deref_opt_inout_ecount_full_opt(size) __pre __deref __nullterminated __post __deref __nullterminated +#define __RPC__deref_opt_inout_xcount_opt(size) __deref_opt_inout_opt +#define __RPC__deref_opt_inout_xcount_part_opt(size, length) __deref_opt_inout_opt +#define __RPC__deref_opt_inout_xcount_full_opt(size) __RPC__deref_opt_inout_opt +#define __RPC__deref_opt_inout_xcount_full_opt_string(size) __RPC__deref_opt_inout_opt __pre __deref __nullterminated __post __deref __nullterminated + +#define __RPC_full_pointer __maybenull +#define __RPC_unique_pointer __maybenull +#define __RPC_ref_pointer __notnull +#define __RPC_string __nullterminated + +#define __RPC__range(min,max) __range(min,max) +#define __RPC__in_range(min,max) __in_range(min,max) + +#else // not prefast + +#define __RPC__range(min,max) +#define __RPC__in_range(min,max) + +#define __RPC__in +#define __RPC__in_string +#define __RPC__in_opt_string +#define __RPC__in_ecount(size) +#define __RPC__in_ecount_full(size) +#define __RPC__in_ecount_full_string(size) +#define __RPC__in_ecount_part(size, length) +#define __RPC__in_ecount_full_opt(size) +#define __RPC__in_ecount_full_opt_string(size) +#define __RPC__inout_ecount_full_opt_string(size) +#define __RPC__in_ecount_part_opt(size, length) +#define __RPC__in_xcount(size) +#define __RPC__in_xcount_full(size) +#define __RPC__in_xcount_full_string(size) +#define __RPC__in_xcount_part(size, length) +#define __RPC__in_xcount_full_opt(size) +#define __RPC__in_xcount_full_opt_string(size) +#define __RPC__inout_xcount_full_opt_string(size) +#define __RPC__in_xcount_part_opt(size, length) + +#define __RPC__deref_in +#define __RPC__deref_in_string +#define __RPC__deref_in_opt +#define __RPC__deref_in_opt_string +#define __RPC__deref_opt_in +#define __RPC__deref_opt_in_string +#define __RPC__deref_opt_in_opt +#define __RPC__deref_opt_in_opt_string +#define __RPC__deref_in_ecount(size) +#define __RPC__deref_in_ecount_part(size, length) +#define __RPC__deref_in_ecount_full(size) +#define __RPC__deref_in_ecount_full_opt(size) +#define __RPC__deref_in_ecount_full_string(size) +#define __RPC__deref_in_ecount_full_opt_string(size) +#define __RPC__deref_in_ecount_opt(size) +#define __RPC__deref_in_ecount_opt_string(size) +#define __RPC__deref_in_ecount_part_opt(size, length) +#define __RPC__deref_in_xcount(size) +#define __RPC__deref_in_xcount_part(size, length) +#define __RPC__deref_in_xcount_full(size) +#define __RPC__deref_in_xcount_full_opt(size) +#define __RPC__deref_in_xcount_full_string(size) +#define __RPC__deref_in_xcount_full_opt_string(size) +#define __RPC__deref_in_xcount_opt(size) +#define __RPC__deref_in_xcount_opt_string(size) +#define __RPC__deref_in_xcount_part_opt(size, length) + +// [out] +#define __RPC__out +#define __RPC__out_ecount(size) +#define __RPC__out_ecount_part(size, length) +#define __RPC__out_ecount_full(size) +#define __RPC__out_ecount_full_string(size) +#define __RPC__out_xcount(size) +#define __RPC__out_xcount_part(size, length) +#define __RPC__out_xcount_full(size) +#define __RPC__out_xcount_full_string(size) + +// [in,out] +#define __RPC__inout +#define __RPC__inout_string +#define __RPC__opt_inout +#define __RPC__inout_ecount(size) +#define __RPC__inout_ecount_part(size, length) +#define __RPC__inout_ecount_full(size) +#define __RPC__inout_ecount_full_string(size) +#define __RPC__inout_xcount(size) +#define __RPC__inout_xcount_part(size, length) +#define __RPC__inout_xcount_full(size) +#define __RPC__inout_xcount_full_string(size) + +// [in,unique] +#define __RPC__in_opt +#define __RPC__in_ecount_opt(size) +#define __RPC__in_xcount_opt(size) + + +// [in,out,unique] +#define __RPC__inout_opt +#define __RPC__inout_opt_string +#define __RPC__inout_ecount_opt(size) +#define __RPC__inout_ecount_part_opt(size, length) +#define __RPC__inout_ecount_full_opt(size) +#define __RPC__inout_ecount_full_string(size) +#define __RPC__inout_xcount_opt(size) +#define __RPC__inout_xcount_part_opt(size, length) +#define __RPC__inout_xcount_full_opt(size) +#define __RPC__inout_xcount_full_string(size) + +// [out] ** +#define __RPC__deref_out +#define __RPC__deref_out_string +#define __RPC__deref_out_opt +#define __RPC__deref_out_opt_string +#define __RPC__deref_out_ecount(size) +#define __RPC__deref_out_ecount_part(size, length) +#define __RPC__deref_out_ecount_full(size) +#define __RPC__deref_out_ecount_full_string(size) +#define __RPC__deref_out_xcount(size) +#define __RPC__deref_out_xcount_part(size, length) +#define __RPC__deref_out_xcount_full(size) +#define __RPC__deref_out_xcount_full_string(size) + + +// [in,out] **, second pointer decoration. +#define __RPC__deref_inout +#define __RPC__deref_inout_string +#define __RPC__deref_inout_opt +#define __RPC__deref_inout_opt_string +#define __RPC__deref_inout_ecount_full(size) +#define __RPC__deref_inout_ecount_full_string(size) +#define __RPC__deref_inout_ecount_opt(size) +#define __RPC__deref_inout_ecount_part_opt(size, length) +#define __RPC__deref_inout_ecount_full_opt(size) +#define __RPC__deref_inout_ecount_full_opt_string(size) +#define __RPC__deref_inout_xcount_full(size) +#define __RPC__deref_inout_xcount_full_string(size) +#define __RPC__deref_inout_xcount_opt(size) +#define __RPC__deref_inout_xcount_part_opt(size, length) +#define __RPC__deref_inout_xcount_full_opt(size) +#define __RPC__deref_inout_xcount_full_opt_string(size) + +// #define __RPC_out_opt out_opt is not allowed in rpc + +// [in,out,unique] +#define __RPC__deref_opt_inout +#define __RPC__deref_opt_inout_string +#define __RPC__deref_opt_inout_ecount(size) +#define __RPC__deref_opt_inout_ecount_part(size, length) +#define __RPC__deref_opt_inout_ecount_full(size) +#define __RPC__deref_opt_inout_ecount_full_string(size) +#define __RPC__deref_opt_inout_xcount(size) +#define __RPC__deref_opt_inout_xcount_part(size, length) +#define __RPC__deref_opt_inout_xcount_full(size) +#define __RPC__deref_opt_inout_xcount_full_string(size) + +#define __RPC__deref_out_ecount_opt(size) +#define __RPC__deref_out_ecount_part_opt(size, length) +#define __RPC__deref_out_ecount_full_opt(size) +#define __RPC__deref_out_ecount_full_opt_string(size) +#define __RPC__deref_out_xcount_opt(size) +#define __RPC__deref_out_xcount_part_opt(size, length) +#define __RPC__deref_out_xcount_full_opt(size) +#define __RPC__deref_out_xcount_full_opt_string(size) + +#define __RPC__deref_opt_inout_opt +#define __RPC__deref_opt_inout_opt_string +#define __RPC__deref_opt_inout_ecount_opt(size) +#define __RPC__deref_opt_inout_ecount_part_opt(size, length) +#define __RPC__deref_opt_inout_ecount_full_opt(size) +#define __RPC__deref_opt_inout_ecount_full_opt_string(size) +#define __RPC__deref_opt_inout_xcount_opt(size) +#define __RPC__deref_opt_inout_xcount_part_opt(size, length) +#define __RPC__deref_opt_inout_xcount_full_opt(size) +#define __RPC__deref_opt_inout_xcount_full_opt_string(size) + +#define __RPC_full_pointer +#define __RPC_unique_pointer +#define __RPC_ref_pointer +#define __RPC_string + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/dxsdk/Include/xact3.h b/dxsdk/Include/xact3.h new file mode 100644 index 0000000..c27d563 --- /dev/null +++ b/dxsdk/Include/xact3.h @@ -0,0 +1,1551 @@ +/************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * Module Name: + * + * xact3.h + * + * Abstract: + * + * XACT public interfaces, functions and data types + * + **************************************************************************/ + +#pragma once + +#ifndef _XACT3_H_ +#define _XACT3_H_ + +//------------------------------------------------------------------------------ +// XACT class and interface IDs (Version 3.7) +//------------------------------------------------------------------------------ +#ifndef _XBOX // XACT COM support only exists on Windows + #include // For DEFINE_CLSID, DEFINE_IID and DECLARE_INTERFACE + DEFINE_CLSID(XACTEngine, bcc782bc, 6492, 4c22, 8c, 35, f5, d7, 2f, e7, 3c, 6e); + DEFINE_CLSID(XACTAuditionEngine, 9ecdd80d, 0e81, 40d8, 89, 03, 2b, f7, b1, 31, ac, 43); + DEFINE_CLSID(XACTDebugEngine, 02860630, bf3b, 42a8, b1, 4e, 91, ed, a2, f5, 1e, a5); + DEFINE_IID(IXACT3Engine, b1ee676a, d9cd, 4d2a, 89, a8, fa, 53, eb, 9e, 48, 0b); +#endif + +// Ignore the rest of this header if only the GUID definitions were requested: +#ifndef GUID_DEFS_ONLY + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ + +#ifndef _XBOX + #include + #include + #include +#endif +#include +#include +#include + +//------------------------------------------------------------------------------ +// Forward Declarations +//------------------------------------------------------------------------------ + +typedef struct IXACT3SoundBank IXACT3SoundBank; +typedef struct IXACT3WaveBank IXACT3WaveBank; +typedef struct IXACT3Cue IXACT3Cue; +typedef struct IXACT3Wave IXACT3Wave; +typedef struct IXACT3Engine IXACT3Engine; +typedef struct XACT_NOTIFICATION XACT_NOTIFICATION; + + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +typedef WORD XACTINDEX; // All normal indices +typedef BYTE XACTNOTIFICATIONTYPE; // Notification type +typedef FLOAT XACTVARIABLEVALUE; // Variable value +typedef WORD XACTVARIABLEINDEX; // Variable index +typedef WORD XACTCATEGORY; // Sound category +typedef BYTE XACTCHANNEL; // Audio channel +typedef FLOAT XACTVOLUME; // Volume value +typedef LONG XACTTIME; // Time (in ms) +typedef SHORT XACTPITCH; // Pitch value +typedef BYTE XACTLOOPCOUNT; // For all loops / recurrences +typedef BYTE XACTVARIATIONWEIGHT; // Variation weight +typedef BYTE XACTPRIORITY; // Sound priority +typedef BYTE XACTINSTANCELIMIT; // Instance limitations + +//------------------------------------------------------------------------------ +// Standard win32 multimedia definitions +//------------------------------------------------------------------------------ +#ifndef WAVE_FORMAT_IEEE_FLOAT + #define WAVE_FORMAT_IEEE_FLOAT 0x0003 +#endif + +#ifndef WAVE_FORMAT_EXTENSIBLE + #define WAVE_FORMAT_EXTENSIBLE 0xFFFE +#endif + +#ifndef _WAVEFORMATEX_ +#define _WAVEFORMATEX_ + #pragma pack(push, 1) + typedef struct tWAVEFORMATEX + { + WORD wFormatTag; // format type + WORD nChannels; // number of channels (i.e. mono, stereo...) + DWORD nSamplesPerSec; // sample rate + DWORD nAvgBytesPerSec; // for buffer estimation + WORD nBlockAlign; // block size of data + WORD wBitsPerSample; // Number of bits per sample of mono data + WORD cbSize; // The count in bytes of the size of extra information (after cbSize) + + } WAVEFORMATEX, *PWAVEFORMATEX; + typedef WAVEFORMATEX NEAR *NPWAVEFORMATEX; + typedef WAVEFORMATEX FAR *LPWAVEFORMATEX; + #pragma pack(pop) +#endif + +#ifndef _WAVEFORMATEXTENSIBLE_ +#define _WAVEFORMATEXTENSIBLE_ + #pragma pack(push, 1) + typedef struct + { + WAVEFORMATEX Format; // WAVEFORMATEX data + + union + { + WORD wValidBitsPerSample; // Bits of precision + WORD wSamplesPerBlock; // Samples per block of audio data, valid if wBitsPerSample==0 + WORD wReserved; // Unused -- If neither applies, set to zero. + } Samples; + + DWORD dwChannelMask; // Speaker usage bitmask + GUID SubFormat; // Sub-format identifier + } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; + #pragma pack(pop) +#endif + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ +static const XACTTIME XACTTIME_MIN = LONG_MIN; +static const XACTTIME XACTTIME_MAX = LONG_MAX; // 24 days 20:31:23.647 +static const XACTTIME XACTTIME_INFINITE = LONG_MAX; +static const XACTINSTANCELIMIT XACTINSTANCELIMIT_INFINITE = 0xff; +static const XACTINSTANCELIMIT XACTINSTANCELIMIT_MIN = 0x00; // == 1 instance total (0 additional instances) +static const XACTINSTANCELIMIT XACTINSTANCELIMIT_MAX = 0xfe; // == 255 instances total (254 additional instances) +static const XACTINDEX XACTINDEX_MIN = 0x0; +static const XACTINDEX XACTINDEX_MAX = 0xfffe; +static const XACTINDEX XACTINDEX_INVALID = 0xffff; +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_MIN = 0x00; +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_MAX = 0xff; +static const XACTVARIABLEVALUE XACTVARIABLEVALUE_MIN = -FLT_MAX; +static const XACTVARIABLEVALUE XACTVARIABLEVALUE_MAX = FLT_MAX; +static const XACTVARIABLEINDEX XACTVARIABLEINDEX_MIN = 0x0000; +static const XACTVARIABLEINDEX XACTVARIABLEINDEX_MAX = 0xfffe; +static const XACTVARIABLEINDEX XACTVARIABLEINDEX_INVALID = 0xffff; +static const XACTCATEGORY XACTCATEGORY_MIN = 0x0; +static const XACTCATEGORY XACTCATEGORY_MAX = 0xfffe; +static const XACTCATEGORY XACTCATEGORY_INVALID = 0xffff; +static const XACTCHANNEL XACTCHANNEL_MIN = 0; +static const XACTCHANNEL XACTCHANNEL_MAX = 0xFF; +static const XACTPITCH XACTPITCH_MIN = -1200; // pitch change allowable per individual content field +static const XACTPITCH XACTPITCH_MAX = 1200; +static const XACTPITCH XACTPITCH_MIN_TOTAL = -2400; // total allowable pitch change, use with IXACTWave.SetPitch() +static const XACTPITCH XACTPITCH_MAX_TOTAL = 2400; +static const XACTVOLUME XACTVOLUME_MIN = 0.0f; +static const XACTVOLUME XACTVOLUME_MAX = 16777216.0f; // Maximum acceptable volume level (2^24) - matches XAudio2 max volume +static const XACTVARIABLEVALUE XACTPARAMETERVALUE_MIN = -FLT_MAX; +static const XACTVARIABLEVALUE XACTPARAMETERVALUE_MAX = FLT_MAX; +static const XACTLOOPCOUNT XACTLOOPCOUNT_MIN = 0x0; +static const XACTLOOPCOUNT XACTLOOPCOUNT_MAX = 0xfe; +static const XACTLOOPCOUNT XACTLOOPCOUNT_INFINITE = 0xff; +static const DWORD XACTWAVEALIGNMENT_MIN = 2048; +#ifdef _XBOX +static const BYTE XACTMAXOUTPUTVOICECOUNT = 3; +#endif // _XBOX + + +// ----------------------------------------------------------------------------- +// Cue friendly name length +// ----------------------------------------------------------------------------- +#define XACT_CUE_NAME_LENGTH 0xFF + +// ----------------------------------------------------------------------------- +// Current Content Tool Version +// ----------------------------------------------------------------------------- +#define XACT_CONTENT_VERSION 46 + +// ----------------------------------------------------------------------------- +// XACT Stop Flags +// ----------------------------------------------------------------------------- +static const DWORD XACT_FLAG_STOP_RELEASE = 0x00000000; // Stop with release envelope (or as authored), for looping waves this acts as break loop. +static const DWORD XACT_FLAG_STOP_IMMEDIATE = 0x00000001; // Stop immediately + +// ----------------------------------------------------------------------------- +// XACT Manage Data Flag - XACT will manage the lifetime of this data +// ----------------------------------------------------------------------------- +static const DWORD XACT_FLAG_MANAGEDATA = 0x00000001; + +// ----------------------------------------------------------------------------- +// XACT Content Preparation Flags +// ----------------------------------------------------------------------------- +static const DWORD XACT_FLAG_BACKGROUND_MUSIC = 0x00000002; // Marks the waves as background music. +static const DWORD XACT_FLAG_UNITS_MS = 0x00000004; // Indicates that the units passed in are in milliseconds. +static const DWORD XACT_FLAG_UNITS_SAMPLES = 0x00000008; // Indicates that the units passed in are in samples. + +// ----------------------------------------------------------------------------- +// XACT State flags +// ----------------------------------------------------------------------------- +static const DWORD XACT_STATE_CREATED = 0x00000001; // Created, but nothing else +static const DWORD XACT_STATE_PREPARING = 0x00000002; // In the middle of preparing +static const DWORD XACT_STATE_PREPARED = 0x00000004; // Prepared, but not yet played +static const DWORD XACT_STATE_PLAYING = 0x00000008; // Playing (though could be paused) +static const DWORD XACT_STATE_STOPPING = 0x00000010; // Stopping +static const DWORD XACT_STATE_STOPPED = 0x00000020; // Stopped +static const DWORD XACT_STATE_PAUSED = 0x00000040; // Paused (Can be combined with some of the other state flags above) +static const DWORD XACT_STATE_INUSE = 0x00000080; // Object is in use (used by wavebanks and soundbanks). +static const DWORD XACT_STATE_PREPAREFAILED = 0x80000000; // Object preparation failed. + +//------------------------------------------------------------------------------ +// XACT Parameters +//------------------------------------------------------------------------------ + +#define XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA XACT_FLAG_MANAGEDATA + +// ----------------------------------------------------------------------------- +// File IO Callbacks +// ----------------------------------------------------------------------------- +typedef BOOL (__stdcall * XACT_READFILE_CALLBACK)(__in HANDLE hFile, __out_bcount(nNumberOfBytesToRead) LPVOID lpBuffer, DWORD nNumberOfBytesToRead, __out LPDWORD lpNumberOfBytesRead, __inout LPOVERLAPPED lpOverlapped); +typedef BOOL (__stdcall * XACT_GETOVERLAPPEDRESULT_CALLBACK)(__in HANDLE hFile, __inout LPOVERLAPPED lpOverlapped, __out LPDWORD lpNumberOfBytesTransferred, BOOL bWait); + +typedef struct XACT_FILEIO_CALLBACKS +{ + XACT_READFILE_CALLBACK readFileCallback; + XACT_GETOVERLAPPEDRESULT_CALLBACK getOverlappedResultCallback; + +} XACT_FILEIO_CALLBACKS, *PXACT_FILEIO_CALLBACKS; +typedef const XACT_FILEIO_CALLBACKS *PCXACT_FILEIO_CALLBACKS; + +// ----------------------------------------------------------------------------- +// Notification Callback +// ----------------------------------------------------------------------------- +typedef void (__stdcall * XACT_NOTIFICATION_CALLBACK)(__in const XACT_NOTIFICATION* pNotification); + +#define XACT_RENDERER_ID_LENGTH 0xff // Maximum number of characters allowed in the renderer ID +#define XACT_RENDERER_NAME_LENGTH 0xff // Maximum number of characters allowed in the renderer display name. + +// ----------------------------------------------------------------------------- +// Renderer Details +// ----------------------------------------------------------------------------- +typedef struct XACT_RENDERER_DETAILS +{ + WCHAR rendererID[XACT_RENDERER_ID_LENGTH]; // The string ID for the rendering device. + WCHAR displayName[XACT_RENDERER_NAME_LENGTH]; // A friendly name suitable for display to a human. + BOOL defaultDevice; // Set to TRUE if this device is the primary audio device on the system. + +} XACT_RENDERER_DETAILS, *LPXACT_RENDERER_DETAILS; + +// ----------------------------------------------------------------------------- +// Engine Look-Ahead Time +// ----------------------------------------------------------------------------- +#define XACT_ENGINE_LOOKAHEAD_DEFAULT 250 // Default look-ahead time of 250ms can be used during XACT engine initialization. + +// ----------------------------------------------------------------------------- +// Runtime (engine) parameters +// ----------------------------------------------------------------------------- +typedef struct XACT_RUNTIME_PARAMETERS +{ + DWORD lookAheadTime; // Time in ms + void* pGlobalSettingsBuffer; // Buffer containing the global settings file + DWORD globalSettingsBufferSize; // Size of global settings buffer + DWORD globalSettingsFlags; // Flags for global settings + DWORD globalSettingsAllocAttributes; // Global settings buffer allocation attributes (see XMemAlloc) + XACT_FILEIO_CALLBACKS fileIOCallbacks; // File I/O callbacks + XACT_NOTIFICATION_CALLBACK fnNotificationCallback; // Callback that receives notifications. + PWSTR pRendererID; // Ptr to the ID for the audio renderer the engine should connect to. + IXAudio2* pXAudio2; // XAudio2 object to be used by the engine (NULL if one needs to be created) + IXAudio2MasteringVoice* pMasteringVoice; // Mastering voice to be used by the engine, if pXAudio2 is not NULL. + +} XACT_RUNTIME_PARAMETERS, *LPXACT_RUNTIME_PARAMETERS; +typedef const XACT_RUNTIME_PARAMETERS *LPCXACT_RUNTIME_PARAMETERS; + +//------------------------------------------------------------------------------ +// Streaming Parameters +//------------------------------------------------------------------------------ + +typedef struct XACT_STREAMING_PARAMETERS +{ + HANDLE file; // File handle associated with wavebank data + DWORD offset; // Offset within file of wavebank header (must be sector aligned) + DWORD flags; // Flags (none currently) + WORD packetSize; // Stream packet size (in sectors) to use for each stream (min = 2) + // number of sectors (DVD = 2048 bytes: 2 = 4096, 3 = 6144, 4 = 8192 etc.) + // optimal DVD size is a multiple of 16 (DVD block = 16 DVD sectors) + +} XACT_WAVEBANK_STREAMING_PARAMETERS, *LPXACT_WAVEBANK_STREAMING_PARAMETERS, XACT_STREAMING_PARAMETERS, *LPXACT_STREAMING_PARAMETERS; +typedef const XACT_STREAMING_PARAMETERS *LPCXACT_STREAMING_PARAMETERS; +typedef const XACT_WAVEBANK_STREAMING_PARAMETERS *LPCXACT_WAVEBANK_STREAMING_PARAMETERS; + +// Structure used to report cue properties back to the client. +typedef struct XACT_CUE_PROPERTIES +{ + CHAR friendlyName[XACT_CUE_NAME_LENGTH]; // Empty if the soundbank doesn't contain any friendly names + BOOL interactive; // TRUE if an IA cue; FALSE otherwise + XACTINDEX iaVariableIndex; // Only valid for IA cues; XACTINDEX_INVALID otherwise + XACTINDEX numVariations; // Number of variations in the cue + XACTINSTANCELIMIT maxInstances; // Number of maximum instances for this cue + XACTINSTANCELIMIT currentInstances; // Current active instances of this cue + +} XACT_CUE_PROPERTIES, *LPXACT_CUE_PROPERTIES; + +// Strucutre used to return the track properties. +typedef struct XACT_TRACK_PROPERTIES +{ + XACTTIME duration; // Duration of the track in ms + XACTINDEX numVariations; // Number of wave variations in the track + XACTCHANNEL numChannels; // Number of channels for the active wave variation on this track + XACTINDEX waveVariation; // Index of the active wave variation + XACTLOOPCOUNT loopCount; // Current loop count on this track + +} XACT_TRACK_PROPERTIES, *LPXACT_TRACK_PROPERTIES; + +// Structure used to return the properties of a variation. +typedef struct XACT_VARIATION_PROPERTIES +{ + XACTINDEX index; // Index of the variation in the cue's variation list + XACTVARIATIONWEIGHT weight; // Weight for the active variation. Valid only for complex cues + XACTVARIABLEVALUE iaVariableMin; // Valid only for IA cues + XACTVARIABLEVALUE iaVariableMax; // Valid only for IA cues + BOOL linger; // Valid only for IA cues + +} XACT_VARIATION_PROPERTIES, *LPXACT_VARIATION_PROPERTIES; + +// Structure used to return the properties of the sound referenced by a variation. +typedef struct XACT_SOUND_PROPERTIES +{ + XACTCATEGORY category; // Category this sound belongs to + BYTE priority; // Priority of this variation + XACTPITCH pitch; // Current pitch set on the active variation + XACTVOLUME volume; // Current volume set on the active variation + XACTINDEX numTracks; // Number of tracks in the active variation + XACT_TRACK_PROPERTIES arrTrackProperties[1]; // Array of active track properties (has numTracks number of elements) + +} XACT_SOUND_PROPERTIES, *LPXACT_SOUND_PROPERTIES; + +// Structure used to return the properties of the active variation and the sound referenced. +typedef struct XACT_SOUND_VARIATION_PROPERTIES +{ + XACT_VARIATION_PROPERTIES variationProperties;// Properties for this variation + XACT_SOUND_PROPERTIES soundProperties; // Proeprties for the sound referenced by this variation + +} XACT_SOUND_VARIATION_PROPERTIES, *LPXACT_SOUND_VARIATION_PROPERTIES; + +// Structure used to return the properties of an active cue instance. +typedef struct XACT_CUE_INSTANCE_PROPERTIES +{ + DWORD allocAttributes; // Buffer allocation attributes (see XMemAlloc) + XACT_CUE_PROPERTIES cueProperties; // Properties of the cue that are shared by all instances. + XACT_SOUND_VARIATION_PROPERTIES activeVariationProperties; // Properties if the currently active variation. + +} XACT_CUE_INSTANCE_PROPERTIES, *LPXACT_CUE_INSTANCE_PROPERTIES; + +// Structure used to return the common wave properties. +typedef struct XACT_WAVE_PROPERTIES +{ + char friendlyName[WAVEBANK_ENTRYNAME_LENGTH]; // Friendly name for the wave; empty if the wavebank doesn't contain friendly names. + WAVEBANKMINIWAVEFORMAT format; // Format for the wave. + DWORD durationInSamples; // Duration of the wave in units of one sample + WAVEBANKSAMPLEREGION loopRegion; // Loop region defined in samples. + BOOL streaming; // Set to TRUE if the wave is streaming; FALSE otherwise. + +} XACT_WAVE_PROPERTIES, *LPXACT_WAVE_PROPERTIES; +typedef const XACT_WAVE_PROPERTIES* LPCXACT_WAVE_PROPERTIES; + +// Structure used to return the properties specific to a wave instance. +typedef struct XACT_WAVE_INSTANCE_PROPERTIES +{ + XACT_WAVE_PROPERTIES properties; // Static properties common to all the wave instances. + BOOL backgroundMusic; // Set to TRUE if the wave is tagged as background music; FALSE otherwise. + +} XACT_WAVE_INSTANCE_PROPERTIES, *LPXACT_WAVE_INSTANCE_PROPERTIES; +typedef const XACT_WAVE_INSTANCE_PROPERTIES* LPCXACT_WAVE_INSTANCE_PROPERTIES; + +//------------------------------------------------------------------------------ +// Channel Mapping / Speaker Panning +//------------------------------------------------------------------------------ + +typedef struct XACTCHANNELMAPENTRY +{ + XACTCHANNEL InputChannel; + XACTCHANNEL OutputChannel; + XACTVOLUME Volume; + +} XACTCHANNELMAPENTRY, *LPXACTCHANNELMAPENTRY; +typedef const XACTCHANNELMAPENTRY *LPCXACTCHANNELMAPENTRY; + +typedef struct XACTCHANNELMAP +{ + XACTCHANNEL EntryCount; + XACTCHANNELMAPENTRY* paEntries; + +} XACTCHANNELMAP, *LPXACTCHANNELMAP; +typedef const XACTCHANNELMAP *LPCXACTCHANNELMAP; + +typedef struct XACTCHANNELVOLUMEENTRY +{ + XACTCHANNEL EntryIndex; + XACTVOLUME Volume; + +} XACTCHANNELVOLUMEENTRY, *LPXACTCHANNELVOLUMEENTRY; +typedef const XACTCHANNELVOLUMEENTRY *LPCXACTCHANNELVOLUMEENTRY; + +typedef struct XACTCHANNELVOLUME +{ + XACTCHANNEL EntryCount; + XACTCHANNELVOLUMEENTRY* paEntries; + +} XACTCHANNELVOLUME, *LPXACTCHANNELVOLUME; +typedef const XACTCHANNELVOLUME *LPCXACTCHANNELVOLUME; + +//------------------------------------------------------------------------------ +// Notifications +//------------------------------------------------------------------------------ + +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_CUEPREPARED = 1; // None, SoundBank, SoundBank & cue index, cue instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_CUEPLAY = 2; // None, SoundBank, SoundBank & cue index, cue instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_CUESTOP = 3; // None, SoundBank, SoundBank & cue index, cue instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_CUEDESTROYED = 4; // None, SoundBank, SoundBank & cue index, cue instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_MARKER = 5; // None, SoundBank, SoundBank & cue index, cue instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED = 6; // None, SoundBank +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED = 7; // None, WaveBank +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED = 8; // None, SoundBank, SoundBank & cue index, cue instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_GLOBALVARIABLECHANGED = 9; // None +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_GUICONNECTED = 10; // None +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_GUIDISCONNECTED = 11; // None +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVEPREPARED = 12; // None, WaveBank & wave index, wave instance. +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVEPLAY = 13; // None, SoundBank, SoundBank & cue index, cue instance, WaveBank, wave instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVESTOP = 14; // None, SoundBank, SoundBank & cue index, cue instance, WaveBank, wave instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVELOOPED = 15; // None, SoundBank, SoundBank & cue index, cue instance, WaveBank, wave instance +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVEDESTROYED = 16; // None, WaveBank & wave index, wave instance. +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVEBANKPREPARED = 17; // None, WaveBank +static const XACTNOTIFICATIONTYPE XACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT = 18; // None, WaveBank + +static const BYTE XACT_FLAG_NOTIFICATION_PERSIST = 0x01; + +// Pack the notification structures +#pragma pack(push, 1) + +// Notification description used for registering, un-registering and flushing notifications +typedef struct XACT_NOTIFICATION_DESCRIPTION +{ + XACTNOTIFICATIONTYPE type; // Notification type + BYTE flags; // Flags + IXACT3SoundBank* pSoundBank; // SoundBank instance + IXACT3WaveBank* pWaveBank; // WaveBank instance + IXACT3Cue* pCue; // Cue instance + IXACT3Wave* pWave; // Wave instance + XACTINDEX cueIndex; // Cue index + XACTINDEX waveIndex; // Wave index + PVOID pvContext; // User context (optional) + +} XACT_NOTIFICATION_DESCRIPTION, *LPXACT_NOTIFICATION_DESCRIPTION; +typedef const XACT_NOTIFICATION_DESCRIPTION *LPCXACT_NOTIFICATION_DESCRIPTION; + +// Notification structure for all XACTNOTIFICATIONTYPE_CUE* notifications +typedef struct XACT_NOTIFICATION_CUE +{ + XACTINDEX cueIndex; // Cue index + IXACT3SoundBank* pSoundBank; // SoundBank instance + IXACT3Cue* pCue; // Cue instance + +} XACT_NOTIFICATION_CUE, *LPXACT_NOTIFICATION_CUE; +typedef const XACT_NOTIFICATION_CUE *LPCXACT_NOTIFICATION_CUE; + +// Notification structure for all XACTNOTIFICATIONTYPE_MARKER* notifications +typedef struct XACT_NOTIFICATION_MARKER +{ + XACTINDEX cueIndex; // Cue index + IXACT3SoundBank* pSoundBank; // SoundBank instance + IXACT3Cue* pCue; // Cue instance + DWORD marker; // Marker value + +} XACT_NOTIFICATION_MARKER, *LPXACT_NOTIFICATION_MARKER; +typedef const XACT_NOTIFICATION_MARKER *LPCXACT_NOTIFICATION_MARKER; + +// Notification structure for all XACTNOTIFICATIONTYPE_SOUNDBANK* notifications +typedef struct XACT_NOTIFICATION_SOUNDBANK +{ + IXACT3SoundBank* pSoundBank; // SoundBank instance + +} XACT_NOTIFICATION_SOUNDBANK, *LPXACT_NOTIFICATION_SOUNDBANK; +typedef const XACT_NOTIFICATION_SOUNDBANK *LPCXACT_NOTIFICATION_SOUNDBANK; + +// Notification structure for all XACTNOTIFICATIONTYPE_WAVEBANK* notifications +typedef struct XACT_NOTIFICATION_WAVEBANK +{ + IXACT3WaveBank* pWaveBank; // WaveBank instance + +} XACT_NOTIFICATION_WAVEBANK, *LPXACT_NOTIFICATION_WAVEBANK; +typedef const XACT_NOTIFICATION_WAVEBANK *LPCXACT_NOTIFICATION_WAVEBANK; + +// Notification structure for all XACTNOTIFICATIONTYPE_*VARIABLE* notifications +typedef struct XACT_NOTIFICATION_VARIABLE +{ + XACTINDEX cueIndex; // Cue index + IXACT3SoundBank* pSoundBank; // SoundBank instance + IXACT3Cue* pCue; // Cue instance + XACTVARIABLEINDEX variableIndex; // Variable index + XACTVARIABLEVALUE variableValue; // Variable value + BOOL local; // TRUE if a local variable + +} XACT_NOTIFICATION_VARIABLE, *LPXACT_NOTIFICATION_VARIABLE; +typedef const XACT_NOTIFICATION_VARIABLE *LPCXACT_NOTIFICATION_VARIABLE; + +// Notification structure for all XACTNOTIFICATIONTYPE_GUI* notifications +typedef struct XACT_NOTIFICATION_GUI +{ + DWORD reserved; // Reserved +} XACT_NOTIFICATION_GUI, *LPXACT_NOTIFICATION_GUI; +typedef const XACT_NOTIFICATION_GUI *LPCXACT_NOTIFICATION_GUI; + +// Notification structure for all XACTNOTIFICATIONTYPE_WAVE* notifications +typedef struct XACT_NOTIFICATION_WAVE +{ + IXACT3WaveBank* pWaveBank; // WaveBank + XACTINDEX waveIndex; // Wave index + XACTINDEX cueIndex; // Cue index + IXACT3SoundBank* pSoundBank; // SoundBank instance + IXACT3Cue* pCue; // Cue instance + IXACT3Wave* pWave; // Wave instance + +} XACT_NOTIFICATION_WAVE, *LPXACT_NOTIFICATION_WAVE; +typedef const XACT_NOTIFICATION_WAVE *LPCXACT_NOTIFICATION_WAVE; + +// General notification structure +typedef struct XACT_NOTIFICATION +{ + XACTNOTIFICATIONTYPE type; // Notification type + LONG timeStamp; // Timestamp of notification (milliseconds) + PVOID pvContext; // User context (optional) + union + { + XACT_NOTIFICATION_CUE cue; // XACTNOTIFICATIONTYPE_CUE* + XACT_NOTIFICATION_MARKER marker; // XACTNOTIFICATIONTYPE_MARKER* + XACT_NOTIFICATION_SOUNDBANK soundBank; // XACTNOTIFICATIONTYPE_SOUNDBANK* + XACT_NOTIFICATION_WAVEBANK waveBank; // XACTNOTIFICATIONTYPE_WAVEBANK* + XACT_NOTIFICATION_VARIABLE variable; // XACTNOTIFICATIONTYPE_VARIABLE* + XACT_NOTIFICATION_GUI gui; // XACTNOTIFICATIONTYPE_GUI* + XACT_NOTIFICATION_WAVE wave; // XACTNOTIFICATIONTYPE_WAVE* + }; + +} XACT_NOTIFICATION, *LPXACT_NOTIFICATION; +typedef const XACT_NOTIFICATION *LPCXACT_NOTIFICATION; + +#pragma pack(pop) + +//------------------------------------------------------------------------------ +// IXACT3SoundBank +//------------------------------------------------------------------------------ + +#define XACT_FLAG_SOUNDBANK_STOP_IMMEDIATE XACT_FLAG_STOP_IMMEDIATE +#define XACT_SOUNDBANKSTATE_INUSE XACT_STATE_INUSE + +STDAPI_(XACTINDEX) IXACT3SoundBank_GetCueIndex(__in IXACT3SoundBank* pSoundBank, __in PCSTR szFriendlyName); +STDAPI IXACT3SoundBank_GetNumCues(__in IXACT3SoundBank* pSoundBank, __out XACTINDEX* pnNumCues); +STDAPI IXACT3SoundBank_GetCueProperties(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, __out LPXACT_CUE_PROPERTIES pProperties); +STDAPI IXACT3SoundBank_Prepare(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_out IXACT3Cue** ppCue); +STDAPI IXACT3SoundBank_Play(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_opt_out IXACT3Cue** ppCue); +STDAPI IXACT3SoundBank_Stop(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags); +STDAPI IXACT3SoundBank_Destroy(__in IXACT3SoundBank* pSoundBank); +STDAPI IXACT3SoundBank_GetState(__in IXACT3SoundBank* pSoundBank, __out DWORD* pdwState); + +#undef INTERFACE +#define INTERFACE IXACT3SoundBank + +DECLARE_INTERFACE(IXACT3SoundBank) +{ + STDMETHOD_(XACTINDEX, GetCueIndex)(THIS_ __in PCSTR szFriendlyName) PURE; + STDMETHOD(GetNumCues)(THIS_ __out XACTINDEX* pnNumCues) PURE; + STDMETHOD(GetCueProperties)(THIS_ XACTINDEX nCueIndex, __out LPXACT_CUE_PROPERTIES pProperties) PURE; + STDMETHOD(Prepare)(THIS_ XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_out IXACT3Cue** ppCue) PURE; + STDMETHOD(Play)(THIS_ XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_opt_out IXACT3Cue** ppCue) PURE; + STDMETHOD(Stop)(THIS_ XACTINDEX nCueIndex, DWORD dwFlags) PURE; + STDMETHOD(Destroy)(THIS) PURE; + STDMETHOD(GetState)(THIS_ __out DWORD* pdwState) PURE; +}; + +#ifdef __cplusplus + +__inline HRESULT __stdcall IXACT3SoundBank_Destroy(__in IXACT3SoundBank* pSoundBank) +{ + return pSoundBank->Destroy(); +} + +__inline XACTINDEX __stdcall IXACT3SoundBank_GetCueIndex(__in IXACT3SoundBank* pSoundBank, __in PCSTR szFriendlyName) +{ + return pSoundBank->GetCueIndex(szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3SoundBank_GetNumCues(__in IXACT3SoundBank* pSoundBank, __out XACTINDEX* pnNumCues) +{ + return pSoundBank->GetNumCues(pnNumCues); +} + +__inline HRESULT __stdcall IXACT3SoundBank_GetCueProperties(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, __out LPXACT_CUE_PROPERTIES pProperties) +{ + return pSoundBank->GetCueProperties(nCueIndex, pProperties); +} + +__inline HRESULT __stdcall IXACT3SoundBank_Prepare(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_out IXACT3Cue** ppCue) +{ + return pSoundBank->Prepare(nCueIndex, dwFlags, timeOffset, ppCue); +} + +__inline HRESULT __stdcall IXACT3SoundBank_Play(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_opt_out IXACT3Cue** ppCue) +{ + return pSoundBank->Play(nCueIndex, dwFlags, timeOffset, ppCue); +} + +__inline HRESULT __stdcall IXACT3SoundBank_Stop(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags) +{ + return pSoundBank->Stop(nCueIndex, dwFlags); +} + +__inline HRESULT __stdcall IXACT3SoundBank_GetState(__in IXACT3SoundBank* pSoundBank, __out DWORD* pdwState) +{ + return pSoundBank->GetState(pdwState); +} + +#else // __cplusplus + +__inline HRESULT __stdcall IXACT3SoundBank_Destroy(__in IXACT3SoundBank* pSoundBank) +{ + return pSoundBank->lpVtbl->Destroy(pSoundBank); +} + +__inline XACTINDEX __stdcall IXACT3SoundBank_GetCueIndex(__in IXACT3SoundBank* pSoundBank, __in PCSTR szFriendlyName) +{ + return pSoundBank->lpVtbl->GetCueIndex(pSoundBank, szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3SoundBank_GetNumCues(__in IXACT3SoundBank* pSoundBank, __out XACTINDEX* pnNumCues) +{ + return pSoundBank->lpVtbl->GetNumCues(pSoundBank, pnNumCues); +} + +__inline HRESULT __stdcall IXACT3SoundBank_GetCueProperties(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, __out LPXACT_CUE_PROPERTIES pProperties) +{ + return pSoundBank->lpVtbl->GetCueProperties(pSoundBank, nCueIndex, pProperties); +} + +__inline HRESULT __stdcall IXACT3SoundBank_Prepare(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_out IXACT3Cue** ppCue) +{ + return pSoundBank->lpVtbl->Prepare(pSoundBank, nCueIndex, dwFlags, timeOffset, ppCue); +} + +__inline HRESULT __stdcall IXACT3SoundBank_Play(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset, __deref_opt_out IXACT3Cue** ppCue) +{ + return pSoundBank->lpVtbl->Play(pSoundBank, nCueIndex, dwFlags, timeOffset, ppCue); +} + +__inline HRESULT __stdcall IXACT3SoundBank_Stop(__in IXACT3SoundBank* pSoundBank, XACTINDEX nCueIndex, DWORD dwFlags) +{ + return pSoundBank->lpVtbl->Stop(pSoundBank, nCueIndex, dwFlags); +} + +__inline HRESULT __stdcall IXACT3SoundBank_GetState(__in IXACT3SoundBank* pSoundBank, __out DWORD* pdwState) +{ + return pSoundBank->lpVtbl->GetState(pSoundBank, pdwState); +} + +#endif // __cplusplus + +//------------------------------------------------------------------------------ +// IXACT3WaveBank +//------------------------------------------------------------------------------ +#define XACT_WAVEBANKSTATE_INUSE XACT_STATE_INUSE // Currently in-use +#define XACT_WAVEBANKSTATE_PREPARED XACT_STATE_PREPARED // Prepared +#define XACT_WAVEBANKSTATE_PREPAREFAILED XACT_STATE_PREPAREFAILED // Prepare failed. + + +STDAPI IXACT3WaveBank_Destroy(__in IXACT3WaveBank* pWaveBank); +STDAPI IXACT3WaveBank_GetState(__in IXACT3WaveBank* pWaveBank, __out DWORD* pdwState); +STDAPI IXACT3WaveBank_GetNumWaves(__in IXACT3WaveBank* pWaveBank, __out XACTINDEX* pnNumWaves); +STDAPI_(XACTINDEX) IXACT3WaveBank_GetWaveIndex(__in IXACT3WaveBank* pWaveBank, __in PCSTR szFriendlyName); +STDAPI IXACT3WaveBank_GetWaveProperties(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, __out LPXACT_WAVE_PROPERTIES pWaveProperties); +STDAPI IXACT3WaveBank_Prepare(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave); +STDAPI IXACT3WaveBank_Play(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave); +STDAPI IXACT3WaveBank_Stop(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags); + +#undef INTERFACE +#define INTERFACE IXACT3WaveBank + +DECLARE_INTERFACE(IXACT3WaveBank) +{ + STDMETHOD(Destroy)(THIS) PURE; + STDMETHOD(GetNumWaves)(THIS_ __out XACTINDEX* pnNumWaves) PURE; + STDMETHOD_(XACTINDEX, GetWaveIndex)(THIS_ __in PCSTR szFriendlyName) PURE; + STDMETHOD(GetWaveProperties)(THIS_ XACTINDEX nWaveIndex, __out LPXACT_WAVE_PROPERTIES pWaveProperties) PURE; + STDMETHOD(Prepare)(THIS_ XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) PURE; + STDMETHOD(Play)(THIS_ XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) PURE; + STDMETHOD(Stop)(THIS_ XACTINDEX nWaveIndex, DWORD dwFlags) PURE; + STDMETHOD(GetState)(THIS_ __out DWORD* pdwState) PURE; +}; + +#ifdef __cplusplus + +__inline HRESULT __stdcall IXACT3WaveBank_Destroy(__in IXACT3WaveBank* pWaveBank) +{ + return pWaveBank->Destroy(); +} + +__inline HRESULT __stdcall IXACT3WaveBank_GetNumWaves(__in IXACT3WaveBank* pWaveBank, __out XACTINDEX* pnNumWaves) +{ + return pWaveBank->GetNumWaves(pnNumWaves); +} + +__inline XACTINDEX __stdcall IXACT3WaveBank_GetWaveIndex(__in IXACT3WaveBank* pWaveBank, __in PCSTR szFriendlyName) +{ + return pWaveBank->GetWaveIndex(szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3WaveBank_GetWaveProperties(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, __out LPXACT_WAVE_PROPERTIES pWaveProperties) +{ + return pWaveBank->GetWaveProperties(nWaveIndex, pWaveProperties); +} + +__inline HRESULT __stdcall IXACT3WaveBank_Prepare(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pWaveBank->Prepare(nWaveIndex, dwFlags, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3WaveBank_Play(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pWaveBank->Play(nWaveIndex, dwFlags, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3WaveBank_Stop(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags) +{ + return pWaveBank->Stop(nWaveIndex, dwFlags); +} + +__inline HRESULT __stdcall IXACT3WaveBank_GetState(__in IXACT3WaveBank* pWaveBank, __out DWORD* pdwState) +{ + return pWaveBank->GetState(pdwState); +} + +#else // __cplusplus + +__inline HRESULT __stdcall IXACT3WaveBank_Destroy(__in IXACT3WaveBank* pWaveBank) +{ + return pWaveBank->lpVtbl->Destroy(pWaveBank); +} + +__inline HRESULT __stdcall IXACT3WaveBank_GetNumWaves(__in IXACT3WaveBank* pWaveBank, __out XACTINDEX* pnNumWaves) +{ + return pWaveBank->lpVtbl->GetNumWaves(pWaveBank, pnNumWaves); +} + +__inline XACTINDEX __stdcall IXACT3WaveBank_GetWaveIndex(__in IXACT3WaveBank* pWaveBank, __in PCSTR szFriendlyName) +{ + return pWaveBank->lpVtbl->GetWaveIndex(pWaveBank, szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3WaveBank_GetWaveProperties(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, __out LPXACT_WAVE_PROPERTIES pWaveProperties) +{ + return pWaveBank->lpVtbl->GetWaveProperties(pWaveBank, nWaveIndex, pWaveProperties); +} + +__inline HRESULT __stdcall IXACT3WaveBank_Prepare(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pWaveBank->lpVtbl->Prepare(pWaveBank, nWaveIndex, dwFlags, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3WaveBank_Play(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pWaveBank->lpVtbl->Play(pWaveBank, nWaveIndex, dwFlags, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3WaveBank_Stop(__in IXACT3WaveBank* pWaveBank, XACTINDEX nWaveIndex, DWORD dwFlags) +{ + return pWaveBank->lpVtbl->Stop(pWaveBank, nWaveIndex, dwFlags); +} + +__inline HRESULT __stdcall IXACT3WaveBank_GetState(__in IXACT3WaveBank* pWaveBank, __out DWORD* pdwState) +{ + return pWaveBank->lpVtbl->GetState(pWaveBank, pdwState); +} +#endif // __cplusplus + + +//------------------------------------------------------------------------------ +// IXACT3Wave +//------------------------------------------------------------------------------ + +STDAPI IXACT3Wave_Destroy(__in IXACT3Wave* pWave); +STDAPI IXACT3Wave_Play(__in IXACT3Wave* pWave); +STDAPI IXACT3Wave_Stop(__in IXACT3Wave* pWave, DWORD dwFlags); +STDAPI IXACT3Wave_Pause(__in IXACT3Wave* pWave, BOOL fPause); +STDAPI IXACT3Wave_GetState(__in IXACT3Wave* pWave, __out DWORD* pdwState); +STDAPI IXACT3Wave_SetPitch(__in IXACT3Wave* pWave, XACTPITCH pitch); +STDAPI IXACT3Wave_SetVolume(__in IXACT3Wave* pWave, XACTVOLUME volume); +STDAPI IXACT3Wave_SetMatrixCoefficients(__in IXACT3Wave* pWave, UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients); +STDAPI IXACT3Wave_GetProperties(__in IXACT3Wave* pWave, __out LPXACT_WAVE_INSTANCE_PROPERTIES pProperties); + +#undef INTERFACE +#define INTERFACE IXACT3Wave + +DECLARE_INTERFACE(IXACT3Wave) +{ + STDMETHOD(Destroy)(THIS) PURE; + STDMETHOD(Play)(THIS) PURE; + STDMETHOD(Stop)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(Pause)(THIS_ BOOL fPause) PURE; + STDMETHOD(GetState)(THIS_ __out DWORD* pdwState) PURE; + STDMETHOD(SetPitch)(THIS_ XACTPITCH pitch) PURE; + STDMETHOD(SetVolume)(THIS_ XACTVOLUME volume) PURE; + STDMETHOD(SetMatrixCoefficients)(THIS_ UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients) PURE; + STDMETHOD(GetProperties)(THIS_ __out LPXACT_WAVE_INSTANCE_PROPERTIES pProperties) PURE; +}; + +#ifdef __cplusplus + +__inline HRESULT __stdcall IXACT3Wave_Destroy(__in IXACT3Wave* pWave) +{ + return pWave->Destroy(); +} + +__inline HRESULT __stdcall IXACT3Wave_Play(__in IXACT3Wave* pWave) +{ + return pWave->Play(); +} + +__inline HRESULT __stdcall IXACT3Wave_Stop(__in IXACT3Wave* pWave, DWORD dwFlags) +{ + return pWave->Stop(dwFlags); +} + +__inline HRESULT __stdcall IXACT3Wave_Pause(__in IXACT3Wave* pWave, BOOL fPause) +{ + return pWave->Pause(fPause); +} + +__inline HRESULT __stdcall IXACT3Wave_GetState(__in IXACT3Wave* pWave, __out DWORD* pdwState) +{ + return pWave->GetState(pdwState); +} + +__inline HRESULT __stdcall IXACT3Wave_SetPitch(__in IXACT3Wave* pWave, XACTPITCH pitch) +{ + return pWave->SetPitch(pitch); +} + +__inline HRESULT __stdcall IXACT3Wave_SetVolume(__in IXACT3Wave* pWave, XACTVOLUME volume) +{ + return pWave->SetVolume(volume); +} + +__inline HRESULT __stdcall IXACT3Wave_SetMatrixCoefficients(__in IXACT3Wave* pWave, UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients) +{ + return pWave->SetMatrixCoefficients(uSrcChannelCount, uDstChannelCount, pMatrixCoefficients); +} + +__inline HRESULT __stdcall IXACT3Wave_GetProperties(__in IXACT3Wave* pWave, __out LPXACT_WAVE_INSTANCE_PROPERTIES pProperties) +{ + return pWave->GetProperties(pProperties); +} + +#else // __cplusplus + +__inline HRESULT __stdcall IXACT3Wave_Destroy(__in IXACT3Wave* pWave) +{ + return pWave->lpVtbl->Destroy(pWave); +} + +__inline HRESULT __stdcall IXACT3Wave_Play(__in IXACT3Wave* pWave) +{ + return pWave->lpVtbl->Play(pWave); +} + +__inline HRESULT __stdcall IXACT3Wave_Stop(__in IXACT3Wave* pWave, DWORD dwFlags) +{ + return pWave->lpVtbl->Stop(pWave, dwFlags); +} + +__inline HRESULT __stdcall IXACT3Wave_Pause(__in IXACT3Wave* pWave, BOOL fPause) +{ + return pWave->lpVtbl->Pause(pWave, fPause); +} + +__inline HRESULT __stdcall IXACT3Wave_GetState(__in IXACT3Wave* pWave, __out DWORD* pdwState) +{ + return pWave->lpVtbl->GetState(pWave, pdwState); +} + +__inline HRESULT __stdcall IXACT3Wave_SetPitch(__in IXACT3Wave* pWave, XACTPITCH pitch) +{ + return pWave->lpVtbl->SetPitch(pWave, pitch); +} + +__inline HRESULT __stdcall IXACT3Wave_SetVolume(__in IXACT3Wave* pWave, XACTVOLUME volume) +{ + return pWave->lpVtbl->SetVolume(pWave, volume); +} + +__inline HRESULT __stdcall IXACT3Wave_SetMatrixCoefficients(__in IXACT3Wave* pWave, UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients) +{ + return pWave->lpVtbl->SetMatrixCoefficients(pWave, uSrcChannelCount, uDstChannelCount, pMatrixCoefficients); +} + +__inline HRESULT __stdcall IXACT3Wave_GetProperties(__in IXACT3Wave* pWave, __out LPXACT_WAVE_INSTANCE_PROPERTIES pProperties) +{ + return pWave->lpVtbl->GetProperties(pWave, pProperties); +} +#endif // __cplusplus + +//------------------------------------------------------------------------------ +// IXACT3Cue +//------------------------------------------------------------------------------ + +// Cue Flags +#define XACT_FLAG_CUE_STOP_RELEASE XACT_FLAG_STOP_RELEASE +#define XACT_FLAG_CUE_STOP_IMMEDIATE XACT_FLAG_STOP_IMMEDIATE + +// Mutually exclusive states +#define XACT_CUESTATE_CREATED XACT_STATE_CREATED // Created, but nothing else +#define XACT_CUESTATE_PREPARING XACT_STATE_PREPARING // In the middle of preparing +#define XACT_CUESTATE_PREPARED XACT_STATE_PREPARED // Prepared, but not yet played +#define XACT_CUESTATE_PLAYING XACT_STATE_PLAYING // Playing (though could be paused) +#define XACT_CUESTATE_STOPPING XACT_STATE_STOPPING // Stopping +#define XACT_CUESTATE_STOPPED XACT_STATE_STOPPED // Stopped +#define XACT_CUESTATE_PAUSED XACT_STATE_PAUSED // Paused (can be combined with other states) + +STDAPI IXACT3Cue_Destroy(__in IXACT3Cue* pCue); +STDAPI IXACT3Cue_Play(__in IXACT3Cue* pCue); +STDAPI IXACT3Cue_Stop(__in IXACT3Cue* pCue, DWORD dwFlags); +STDAPI IXACT3Cue_GetState(__in IXACT3Cue* pCue, __out DWORD* pdwState); +STDAPI IXACT3Cue_SetMatrixCoefficients(__in IXACT3Cue*, UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients); +STDAPI_(XACTVARIABLEINDEX) IXACT3Cue_GetVariableIndex(__in IXACT3Cue* pCue, __in PCSTR szFriendlyName); +STDAPI IXACT3Cue_SetVariable(__in IXACT3Cue* pCue, XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue); +STDAPI IXACT3Cue_GetVariable(__in IXACT3Cue* pCue, XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* nValue); +STDAPI IXACT3Cue_Pause(__in IXACT3Cue* pCue, BOOL fPause); +STDAPI IXACT3Cue_GetProperties(__in IXACT3Cue* pCue, __out LPXACT_CUE_INSTANCE_PROPERTIES* ppProperties); +STDAPI IXACT3Cue_SetOutputVoices(__in IXACT3Cue* pCue, __in_opt const XAUDIO2_VOICE_SENDS* pSendList); +STDAPI IXACT3Cue_SetOutputVoiceMatrix(__in IXACT3Cue* pCue, __in_opt IXAudio2Voice* pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, __in_ecount(SourceChannels * DestinationChannels) const float* pLevelMatrix); + +#undef INTERFACE +#define INTERFACE IXACT3Cue + +DECLARE_INTERFACE(IXACT3Cue) +{ + STDMETHOD(Play)(THIS) PURE; + STDMETHOD(Stop)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetState)(THIS_ __out DWORD* pdwState) PURE; + STDMETHOD(Destroy)(THIS) PURE; + STDMETHOD(SetMatrixCoefficients)(THIS_ UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients) PURE; + STDMETHOD_(XACTVARIABLEINDEX, GetVariableIndex)(THIS_ __in PCSTR szFriendlyName) PURE; + STDMETHOD(SetVariable)(THIS_ XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue) PURE; + STDMETHOD(GetVariable)(THIS_ XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* nValue) PURE; + STDMETHOD(Pause)(THIS_ BOOL fPause) PURE; + STDMETHOD(GetProperties)(THIS_ __out LPXACT_CUE_INSTANCE_PROPERTIES* ppProperties) PURE; + STDMETHOD(SetOutputVoices)(THIS_ __in_opt const XAUDIO2_VOICE_SENDS* pSendList) PURE; + STDMETHOD(SetOutputVoiceMatrix)(THIS_ __in_opt IXAudio2Voice* pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, __in_ecount(SourceChannels * DestinationChannels) const float* pLevelMatrix) PURE; +}; + +#ifdef __cplusplus + +__inline HRESULT __stdcall IXACT3Cue_Play(__in IXACT3Cue* pCue) +{ + return pCue->Play(); +} + +__inline HRESULT __stdcall IXACT3Cue_Stop(__in IXACT3Cue* pCue, DWORD dwFlags) +{ + return pCue->Stop(dwFlags); +} + +__inline HRESULT __stdcall IXACT3Cue_GetState(__in IXACT3Cue* pCue, __out DWORD* pdwState) +{ + return pCue->GetState(pdwState); +} + +__inline HRESULT __stdcall IXACT3Cue_Destroy(__in IXACT3Cue* pCue) +{ + return pCue->Destroy(); +} + +__inline HRESULT __stdcall IXACT3Cue_SetMatrixCoefficients(__in IXACT3Cue* pCue, UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients) +{ + return pCue->SetMatrixCoefficients(uSrcChannelCount, uDstChannelCount, pMatrixCoefficients); +} + +__inline XACTVARIABLEINDEX __stdcall IXACT3Cue_GetVariableIndex(__in IXACT3Cue* pCue, __in PCSTR szFriendlyName) +{ + return pCue->GetVariableIndex(szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3Cue_SetVariable(__in IXACT3Cue* pCue, XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue) +{ + return pCue->SetVariable(nIndex, nValue); +} + +__inline HRESULT __stdcall IXACT3Cue_GetVariable(__in IXACT3Cue* pCue, XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* pnValue) +{ + return pCue->GetVariable(nIndex, pnValue); +} + +__inline HRESULT __stdcall IXACT3Cue_Pause(__in IXACT3Cue* pCue, BOOL fPause) +{ + return pCue->Pause(fPause); +} + +__inline HRESULT __stdcall IXACT3Cue_GetProperties(__in IXACT3Cue* pCue, __out LPXACT_CUE_INSTANCE_PROPERTIES* ppProperties) +{ + return pCue->GetProperties(ppProperties); +} + +__inline HRESULT __stdcall IXACT3Cue_SetOutputVoices(__in IXACT3Cue* pCue, __in_opt const XAUDIO2_VOICE_SENDS* pSendList) +{ + return pCue->SetOutputVoices(pSendList); +} + +__inline HRESULT __stdcall IXACT3Cue_SetOutputVoiceMatrix(__in IXACT3Cue* pCue, __in_opt IXAudio2Voice* pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, __in_ecount(SourceChannels * DestinationChannels) const float* pLevelMatrix) +{ + return pCue->SetOutputVoiceMatrix(pDestinationVoice, SourceChannels, DestinationChannels, pLevelMatrix); +} + +#else // __cplusplus + +__inline HRESULT __stdcall IXACT3Cue_Play(__in IXACT3Cue* pCue) +{ + return pCue->lpVtbl->Play(pCue); +} + +__inline HRESULT __stdcall IXACT3Cue_Stop(__in IXACT3Cue* pCue, DWORD dwFlags) +{ + return pCue->lpVtbl->Stop(pCue, dwFlags); +} + +__inline HRESULT __stdcall IXACT3Cue_GetState(__in IXACT3Cue* pCue, __out DWORD* pdwState) +{ + return pCue->lpVtbl->GetState(pCue, pdwState); +} + +__inline HRESULT __stdcall IXACT3Cue_Destroy(__in IXACT3Cue* pCue) +{ + return pCue->lpVtbl->Destroy(pCue); +} + +__inline HRESULT __stdcall IXACT3Cue_SetMatrixCoefficients(__in IXACT3Cue* pCue, UINT32 uSrcChannelCount, UINT32 uDstChannelCount, __in float* pMatrixCoefficients) +{ + return pCue->lpVtbl->SetMatrixCoefficients(pCue, uSrcChannelCount, uDstChannelCount, pMatrixCoefficients); +} + +__inline XACTVARIABLEINDEX __stdcall IXACT3Cue_GetVariableIndex(__in IXACT3Cue* pCue, __in PCSTR szFriendlyName) +{ + return pCue->lpVtbl->GetVariableIndex(pCue, szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3Cue_SetVariable(__in IXACT3Cue* pCue, XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue) +{ + return pCue->lpVtbl->SetVariable(pCue, nIndex, nValue); +} + +__inline HRESULT __stdcall IXACT3Cue_GetVariable(__in IXACT3Cue* pCue, XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* pnValue) +{ + return pCue->lpVtbl->GetVariable(pCue, nIndex, pnValue); +} + +__inline HRESULT __stdcall IXACT3Cue_Pause(__in IXACT3Cue* pCue, BOOL fPause) +{ + return pCue->lpVtbl->Pause(pCue, fPause); +} + +__inline HRESULT __stdcall IXACT3Cue_GetProperties(__in IXACT3Cue* pCue, __out LPXACT_CUE_INSTANCE_PROPERTIES* ppProperties) +{ + return pCue->lpVtbl->GetProperties(pCue, ppProperties); +} + +__inline HRESULT __stdcall IXACT3Cue_SetOutputVoices(__in IXACT3Cue* pCue, __in_opt const XAUDIO2_VOICE_SENDS* pSendList) +{ + return pCue->lpVtbl->SetOutputVoices(pSendList); +} + +__inline HRESULT __stdcall IXACT3Cue_SetOutputVoiceMatrix(__in IXACT3Cue* pCue, __in_opt IXAudio2Voice* pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, __in_ecount(SourceChannels * DestinationChannels) const float* pLevelMatrix) +{ + return pCue->lpVtbl->SetOutputVoiceMatrix(pDestinationVoice, SourceChannels, DestinationChannels, pLevelMatrix); +} + +#endif // __cplusplus + +//------------------------------------------------------------------------------ +// IXACT3Engine +//------------------------------------------------------------------------------ + +// Engine flags +#define XACT_FLAG_ENGINE_CREATE_MANAGEDATA XACT_FLAG_MANAGEDATA +#define XACT_FLAG_ENGINE_STOP_IMMEDIATE XACT_FLAG_STOP_IMMEDIATE + +STDAPI_(ULONG) IXACT3Engine_AddRef(__in IXACT3Engine* pEngine); +STDAPI_(ULONG) IXACT3Engine_Release(__in IXACT3Engine* pEngine); +STDAPI IXACT3Engine_GetRendererCount(__in IXACT3Engine* pEngine, __out XACTINDEX* pnRendererCount); +STDAPI IXACT3Engine_GetRendererDetails(__in IXACT3Engine* pEngine, XACTINDEX nRendererIndex, __out LPXACT_RENDERER_DETAILS pRendererDetails); +STDAPI IXACT3Engine_GetFinalMixFormat(__in IXACT3Engine* pEngine, __out WAVEFORMATEXTENSIBLE* pFinalMixFormat); +STDAPI IXACT3Engine_Initialize(__in IXACT3Engine* pEngine, __in const XACT_RUNTIME_PARAMETERS* pParams); +STDAPI IXACT3Engine_ShutDown(__in IXACT3Engine* pEngine); +STDAPI IXACT3Engine_DoWork(__in IXACT3Engine* pEngine); +STDAPI IXACT3Engine_CreateSoundBank(__in IXACT3Engine* pEngine, __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3SoundBank** ppSoundBank); +STDAPI IXACT3Engine_CreateInMemoryWaveBank(__in IXACT3Engine* pEngine, __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3WaveBank** ppWaveBank); +STDAPI IXACT3Engine_CreateStreamingWaveBank(__in IXACT3Engine* pEngine, __in const XACT_WAVEBANK_STREAMING_PARAMETERS* pParms, __deref_out IXACT3WaveBank** ppWaveBank); +STDAPI IXACT3Engine_PrepareWave(__in IXACT3Engine* pEngine, DWORD dwFlags, __in PCSTR szWavePath, WORD wStreamingPacketSize, DWORD dwAlignment, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave); +STDAPI IXACT3Engine_PrepareInMemoryWave(__in IXACT3Engine* pEngine, DWORD dwFlags, WAVEBANKENTRY entry, __in_opt DWORD* pdwSeekTable, __in_opt BYTE* pbWaveData, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave); +STDAPI IXACT3Engine_PrepareStreamingWave(__in IXACT3Engine* pEngine, DWORD dwFlags, WAVEBANKENTRY entry, XACT_STREAMING_PARAMETERS streamingParams, DWORD dwAlignment, __in_opt DWORD* pdwSeekTable, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave); +STDAPI IXACT3Engine_RegisterNotification(__in IXACT3Engine* pEngine, __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc); +STDAPI IXACT3Engine_UnRegisterNotification(__in IXACT3Engine* pEngine, __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc); +STDAPI_(XACTCATEGORY) IXACT3Engine_GetCategory(__in IXACT3Engine* pEngine, __in PCSTR szFriendlyName); +STDAPI IXACT3Engine_Stop(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, DWORD dwFlags); +STDAPI IXACT3Engine_SetVolume(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, XACTVOLUME nVolume); +STDAPI IXACT3Engine_Pause(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, BOOL fPause); +STDAPI_(XACTVARIABLEINDEX) IXACT3Engine_GetGlobalVariableIndex(__in IXACT3Engine* pEngine, __in PCSTR szFriendlyName); +STDAPI IXACT3Engine_SetGlobalVariable(__in IXACT3Engine* pEngine, XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue); +STDAPI IXACT3Engine_GetGlobalVariable(__in IXACT3Engine* pEngine, XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* pnValue); + +#undef INTERFACE +#define INTERFACE IXACT3Engine + +#ifdef _XBOX +DECLARE_INTERFACE(IXACT3Engine) +{ +#else +DECLARE_INTERFACE_(IXACT3Engine, IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ __in REFIID riid, __deref_out void** ppvObj) PURE; +#endif + + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD(GetRendererCount)(THIS_ __out XACTINDEX* pnRendererCount) PURE; + STDMETHOD(GetRendererDetails)(THIS_ XACTINDEX nRendererIndex, __out LPXACT_RENDERER_DETAILS pRendererDetails) PURE; + + STDMETHOD(GetFinalMixFormat)(THIS_ __out WAVEFORMATEXTENSIBLE* pFinalMixFormat) PURE; + STDMETHOD(Initialize)(THIS_ __in const XACT_RUNTIME_PARAMETERS* pParams) PURE; + STDMETHOD(ShutDown)(THIS) PURE; + + STDMETHOD(DoWork)(THIS) PURE; + + STDMETHOD(CreateSoundBank)(THIS_ __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3SoundBank** ppSoundBank) PURE; + STDMETHOD(CreateInMemoryWaveBank)(THIS_ __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3WaveBank** ppWaveBank) PURE; + STDMETHOD(CreateStreamingWaveBank)(THIS_ __in const XACT_WAVEBANK_STREAMING_PARAMETERS* pParms, __deref_out IXACT3WaveBank** ppWaveBank) PURE; + + STDMETHOD(PrepareWave)(THIS_ DWORD dwFlags, __in PCSTR szWavePath, WORD wStreamingPacketSize, DWORD dwAlignment, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) PURE; + STDMETHOD(PrepareInMemoryWave)(THIS_ DWORD dwFlags, WAVEBANKENTRY entry, __in_opt DWORD* pdwSeekTable, __in_opt BYTE* pbWaveData, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) PURE; + STDMETHOD(PrepareStreamingWave)(THIS_ DWORD dwFlags, WAVEBANKENTRY entry, XACT_STREAMING_PARAMETERS streamingParams, DWORD dwAlignment, __in_opt DWORD* pdwSeekTable, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) PURE; + + STDMETHOD(RegisterNotification)(THIS_ __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc) PURE; + STDMETHOD(UnRegisterNotification)(THIS_ __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc) PURE; + + STDMETHOD_(XACTCATEGORY, GetCategory)(THIS_ __in PCSTR szFriendlyName) PURE; + STDMETHOD(Stop)(THIS_ XACTCATEGORY nCategory, DWORD dwFlags) PURE; + STDMETHOD(SetVolume)(THIS_ XACTCATEGORY nCategory, XACTVOLUME nVolume) PURE; + STDMETHOD(Pause)(THIS_ XACTCATEGORY nCategory, BOOL fPause) PURE; + + STDMETHOD_(XACTVARIABLEINDEX, GetGlobalVariableIndex)(THIS_ __in PCSTR szFriendlyName) PURE; + STDMETHOD(SetGlobalVariable)(THIS_ XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue) PURE; + STDMETHOD(GetGlobalVariable)(THIS_ XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* nValue) PURE; +}; + +#ifdef __cplusplus + +__inline ULONG __stdcall IXACT3Engine_AddRef(__in IXACT3Engine* pEngine) +{ + return pEngine->AddRef(); +} + +__inline ULONG __stdcall IXACT3Engine_Release(__in IXACT3Engine* pEngine) +{ + return pEngine->Release(); +} + +__inline HRESULT __stdcall IXACT3Engine_GetRendererCount(__in IXACT3Engine* pEngine, __out XACTINDEX* pnRendererCount) +{ + return pEngine->GetRendererCount(pnRendererCount); +} + +__inline HRESULT __stdcall IXACT3Engine_GetRendererDetails(__in IXACT3Engine* pEngine, XACTINDEX nRendererIndex, __out LPXACT_RENDERER_DETAILS pRendererDetails) +{ + return pEngine->GetRendererDetails(nRendererIndex, pRendererDetails); +} + +__inline HRESULT __stdcall IXACT3Engine_GetFinalMixFormat(__in IXACT3Engine* pEngine, __out WAVEFORMATEXTENSIBLE* pFinalMixFormat) +{ + return pEngine->GetFinalMixFormat(pFinalMixFormat); +} + +__inline HRESULT __stdcall IXACT3Engine_Initialize(__in IXACT3Engine* pEngine, __in const XACT_RUNTIME_PARAMETERS* pParams) +{ + return pEngine->Initialize(pParams); +} + +__inline HRESULT __stdcall IXACT3Engine_ShutDown(__in IXACT3Engine* pEngine) +{ + return pEngine->ShutDown(); +} + +__inline HRESULT __stdcall IXACT3Engine_DoWork(__in IXACT3Engine* pEngine) +{ + return pEngine->DoWork(); +} + +__inline HRESULT __stdcall IXACT3Engine_CreateSoundBank(__in IXACT3Engine* pEngine, __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3SoundBank** ppSoundBank) +{ + return pEngine->CreateSoundBank(pvBuffer, dwSize, dwFlags, dwAllocAttributes, ppSoundBank); +} + +__inline HRESULT __stdcall IXACT3Engine_CreateInMemoryWaveBank(__in IXACT3Engine* pEngine, __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3WaveBank** ppWaveBank) +{ + return pEngine->CreateInMemoryWaveBank(pvBuffer, dwSize, dwFlags, dwAllocAttributes, ppWaveBank); +} + +__inline HRESULT __stdcall IXACT3Engine_CreateStreamingWaveBank(__in IXACT3Engine* pEngine, __in const XACT_WAVEBANK_STREAMING_PARAMETERS* pParms, __deref_out IXACT3WaveBank** ppWaveBank) +{ + return pEngine->CreateStreamingWaveBank(pParms, ppWaveBank); +} + +__inline HRESULT __stdcall IXACT3Engine_PrepareWave(__in IXACT3Engine* pEngine, DWORD dwFlags, __in PCSTR szWavePath, WORD wStreamingPacketSize, DWORD dwAlignment, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pEngine->PrepareWave(dwFlags, szWavePath, wStreamingPacketSize, dwAlignment, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3Engine_PrepareInMemoryWave(__in IXACT3Engine* pEngine, DWORD dwFlags, WAVEBANKENTRY entry, __in_opt DWORD* pdwSeekTable, __in_opt BYTE* pbWaveData, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pEngine->PrepareInMemoryWave(dwFlags, entry, pdwSeekTable, pbWaveData, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3Engine_PrepareStreamingWave(__in IXACT3Engine* pEngine, DWORD dwFlags, WAVEBANKENTRY entry, XACT_STREAMING_PARAMETERS streamingParams, DWORD dwAlignment, __in_opt DWORD* pdwSeekTable, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pEngine->PrepareStreamingWave(dwFlags, entry, streamingParams, dwAlignment, pdwSeekTable, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3Engine_RegisterNotification(__in IXACT3Engine* pEngine, __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc) +{ + return pEngine->RegisterNotification(pNotificationDesc); +} + +__inline HRESULT __stdcall IXACT3Engine_UnRegisterNotification(__in IXACT3Engine* pEngine, __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc) +{ + return pEngine->UnRegisterNotification(pNotificationDesc); +} + +__inline XACTCATEGORY __stdcall IXACT3Engine_GetCategory(__in IXACT3Engine* pEngine, __in PCSTR szFriendlyName) +{ + return pEngine->GetCategory(szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3Engine_Stop(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, DWORD dwFlags) +{ + return pEngine->Stop(nCategory, dwFlags); +} + +__inline HRESULT __stdcall IXACT3Engine_SetVolume(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, XACTVOLUME nVolume) +{ + return pEngine->SetVolume(nCategory, nVolume); +} + +__inline HRESULT __stdcall IXACT3Engine_Pause(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, BOOL fPause) +{ + return pEngine->Pause(nCategory, fPause); +} + +__inline XACTVARIABLEINDEX __stdcall IXACT3Engine_GetGlobalVariableIndex(__in IXACT3Engine* pEngine, __in PCSTR szFriendlyName) +{ + return pEngine->GetGlobalVariableIndex(szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3Engine_SetGlobalVariable(__in IXACT3Engine* pEngine, XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue) +{ + return pEngine->SetGlobalVariable(nIndex, nValue); +} + +__inline HRESULT __stdcall IXACT3Engine_GetGlobalVariable(__in IXACT3Engine* pEngine, XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* nValue) +{ + return pEngine->GetGlobalVariable(nIndex, nValue); +} + +#else // __cplusplus + +__inline ULONG __stdcall IXACT3Engine_AddRef(__in IXACT3Engine* pEngine) +{ + return pEngine->lpVtbl->AddRef(pEngine); +} + +__inline ULONG __stdcall IXACT3Engine_Release(__in IXACT3Engine* pEngine) +{ + return pEngine->lpVtbl->Release(pEngine); +} + +__inline HRESULT __stdcall IXACT3Engine_GetRendererCount(__in IXACT3Engine* pEngine, __out XACTINDEX* pnRendererCount) +{ + return pEngine->lpVtbl->GetRendererCount(pEngine, pnRendererCount); +} + +__inline HRESULT __stdcall IXACT3Engine_GetRendererDetails(__in IXACT3Engine* pEngine, XACTINDEX nRendererIndex, __out LPXACT_RENDERER_DETAILS pRendererDetails) +{ + return pEngine->lpVtbl->GetRendererDetails(pEngine, nRendererIndex, pRendererDetails); +} + +__inline HRESULT __stdcall IXACT3Engine_GetFinalMixFormat(__in IXACT3Engine* pEngine, __out WAVEFORMATEXTENSIBLE* pFinalMixFormat) +{ + return pEngine->lpVtbl->GetFinalMixFormat(pEngine, pFinalMixFormat); +} + +__inline HRESULT __stdcall IXACT3Engine_Initialize(__in IXACT3Engine* pEngine, __in const XACT_RUNTIME_PARAMETERS* pParams) +{ + return pEngine->lpVtbl->Initialize(pEngine, pParams); +} + +__inline HRESULT __stdcall IXACT3Engine_ShutDown(__in IXACT3Engine* pEngine) +{ + return pEngine->lpVtbl->ShutDown(pEngine); +} + +__inline HRESULT __stdcall IXACT3Engine_DoWork(__in IXACT3Engine* pEngine) +{ + return pEngine->lpVtbl->DoWork(pEngine); +} + +__inline HRESULT __stdcall IXACT3Engine_CreateSoundBank(__in IXACT3Engine* pEngine, __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3SoundBank** ppSoundBank) +{ + return pEngine->lpVtbl->CreateSoundBank(pEngine, pvBuffer, dwSize, dwFlags, dwAllocAttributes, ppSoundBank); +} + +__inline HRESULT __stdcall IXACT3Engine_CreateInMemoryWaveBank(__in IXACT3Engine* pEngine, __in const void* pvBuffer, DWORD dwSize, DWORD dwFlags, DWORD dwAllocAttributes, __deref_out IXACT3WaveBank** ppWaveBank) +{ + return pEngine->lpVtbl->CreateInMemoryWaveBank(pEngine, pvBuffer, dwSize, dwFlags, dwAllocAttributes, ppWaveBank); +} + +__inline HRESULT __stdcall IXACT3Engine_CreateStreamingWaveBank(__in IXACT3Engine* pEngine, __in const XACT_WAVEBANK_STREAMING_PARAMETERS* pParms, __deref_out IXACT3WaveBank** ppWaveBank) +{ + return pEngine->lpVtbl->CreateStreamingWaveBank(pEngine, pParms, ppWaveBank); +} + +__inline HRESULT __stdcall IXACT3Engine_PrepareWave(__in IXACT3Engine* pEngine, DWORD dwFlags, __in PCSTR szWavePath, WORD wStreamingPacketSize, DWORD dwAlignment, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pEngine->lpVtbl->PrepareWave(pEngine, dwFlags, szWavePath, wStreamingPacketSize, dwAlignment, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3Engine_PrepareInMemoryWave(__in IXACT3Engine* pEngine, DWORD dwFlags, WAVEBANKENTRY entry, __in_opt DWORD* pdwSeekTable, __in_opt BYTE* pbWaveData, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pEngine->lpVtbl->PrepareInMemoryWave(pEngine, dwFlags, entry, pdwSeekTable, pbWaveData, dwPlayOffset, nLoopCount, ppWave); +} + +__inline HRESULT __stdcall IXACT3Engine_PrepareStreamingWave(__in IXACT3Engine* pEngine, DWORD dwFlags, WAVEBANKENTRY entry, XACT_STREAMING_PARAMETERS streamingParams, DWORD dwAlignment, __in_opt DWORD* pdwSeekTable, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, __deref_out IXACT3Wave** ppWave) +{ + return pEngine->lpVtbl->PrepareStreamingWave(pEngine, dwFlags, entry, streamingParams, dwAlignment, pdwSeekTable, dwPlayOffset, nLoopCount, ppWave); +} + + +__inline HRESULT __stdcall IXACT3Engine_RegisterNotification(__in IXACT3Engine* pEngine, __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc) +{ + return pEngine->lpVtbl->RegisterNotification(pEngine, pNotificationDesc); +} + +__inline HRESULT __stdcall IXACT3Engine_UnRegisterNotification(__in IXACT3Engine* pEngine, __in const XACT_NOTIFICATION_DESCRIPTION* pNotificationDesc) +{ + return pEngine->lpVtbl->UnRegisterNotification(pEngine, pNotificationDesc); +} + +__inline XACTCATEGORY __stdcall IXACT3Engine_GetCategory(__in IXACT3Engine* pEngine, __in PCSTR szFriendlyName) +{ + return pEngine->lpVtbl->GetCategory(pEngine, szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3Engine_Stop(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, DWORD dwFlags) +{ + return pEngine->lpVtbl->Stop(pEngine, nCategory, dwFlags); +} + +__inline HRESULT __stdcall IXACT3Engine_SetVolume(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, XACTVOLUME nVolume) +{ + return pEngine->lpVtbl->SetVolume(pEngine, nCategory, nVolume); +} + +__inline HRESULT __stdcall IXACT3Engine_Pause(__in IXACT3Engine* pEngine, XACTCATEGORY nCategory, BOOL fPause) +{ + return pEngine->lpVtbl->Pause(pEngine, nCategory, fPause); +} + +__inline XACTVARIABLEINDEX __stdcall IXACT3Engine_GetGlobalVariableIndex(__in IXACT3Engine* pEngine, __in PCSTR szFriendlyName) +{ + return pEngine->lpVtbl->GetGlobalVariableIndex(pEngine, szFriendlyName); +} + +__inline HRESULT __stdcall IXACT3Engine_SetGlobalVariable(__in IXACT3Engine* pEngine, XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue) +{ + return pEngine->lpVtbl->SetGlobalVariable(pEngine, nIndex, nValue); +} + +__inline HRESULT __stdcall IXACT3Engine_GetGlobalVariable(__in IXACT3Engine* pEngine, XACTVARIABLEINDEX nIndex, __out XACTVARIABLEVALUE* nValue) +{ + return pEngine->lpVtbl->GetGlobalVariable(pEngine, nIndex, nValue); +} + +#endif // __cplusplus + +//------------------------------------------------------------------------------ +// Create Engine +//------------------------------------------------------------------------------ + +// Flags used only in XACT3CreateEngine below. These flags are valid but ignored +// when building for Xbox 360; to enable auditioning on that platform you must +// link explicitly to an auditioning version of the XACT static library. +static const DWORD XACT_FLAG_API_AUDITION_MODE = 0x00000001; +static const DWORD XACT_FLAG_API_DEBUG_MODE = 0x00000002; + +#ifdef _XBOX + +STDAPI XACT3CreateEngine(DWORD dwCreationFlags, __deref_out IXACT3Engine** ppEngine); + +#else // #ifdef _XBOX + +#define XACT_DEBUGENGINE_REGISTRY_KEY TEXT("Software\\Microsoft\\XACT") +#define XACT_DEBUGENGINE_REGISTRY_VALUE TEXT("DebugEngine") + + +#ifdef __cplusplus + +__inline HRESULT __stdcall XACT3CreateEngine(DWORD dwCreationFlags, __deref_out IXACT3Engine** ppEngine) +{ + HRESULT hr; + HKEY key; + DWORD data; + DWORD type = REG_DWORD; + DWORD dataSize = sizeof(DWORD); + BOOL debug = (dwCreationFlags & XACT_FLAG_API_DEBUG_MODE) ? TRUE : FALSE; + BOOL audition = (dwCreationFlags & XACT_FLAG_API_AUDITION_MODE) ? TRUE : FALSE; + + // If neither the debug nor audition flags are set, see if the debug registry key is set + if(!debug && !audition && + (RegOpenKeyEx(HKEY_LOCAL_MACHINE, XACT_DEBUGENGINE_REGISTRY_KEY, 0, KEY_READ, &key) == ERROR_SUCCESS)) + { + if(RegQueryValueEx(key, XACT_DEBUGENGINE_REGISTRY_VALUE, NULL, &type, (LPBYTE)&data, &dataSize) == ERROR_SUCCESS) + { + if(data) + { + debug = TRUE; + } + } + RegCloseKey(key); + } + + // Priority order: Audition, Debug, Retail + hr = CoCreateInstance(audition ? __uuidof(XACTAuditionEngine) + : (debug ? __uuidof(XACTDebugEngine) : __uuidof(XACTEngine)), + NULL, CLSCTX_INPROC_SERVER, __uuidof(IXACT3Engine), (void**)ppEngine); + + // If debug engine does not exist fallback to retail version + if(FAILED(hr) && debug && !audition) + { + hr = CoCreateInstance(__uuidof(XACTEngine), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXACT3Engine), (void**)ppEngine); + } + + return hr; +} + +#else // #ifdef __cplusplus + +__inline HRESULT __stdcall XACT3CreateEngine(DWORD dwCreationFlags, __deref_out IXACT3Engine** ppEngine) +{ + HRESULT hr; + HKEY key; + DWORD data; + DWORD type = REG_DWORD; + DWORD dataSize = sizeof(DWORD); + BOOL debug = (dwCreationFlags & XACT_FLAG_API_DEBUG_MODE) ? TRUE : FALSE; + BOOL audition = (dwCreationFlags & XACT_FLAG_API_AUDITION_MODE) ? TRUE : FALSE; + + // If neither the debug nor audition flags are set, see if the debug registry key is set + if(!debug && !audition && + (RegOpenKeyEx(HKEY_LOCAL_MACHINE, XACT_DEBUGENGINE_REGISTRY_KEY, 0, KEY_READ, &key) == ERROR_SUCCESS)) + { + if(RegQueryValueEx(key, XACT_DEBUGENGINE_REGISTRY_VALUE, NULL, &type, (LPBYTE)&data, &dataSize) == ERROR_SUCCESS) + { + if(data) + { + debug = TRUE; + } + } + RegCloseKey(key); + } + + // Priority order: Audition, Debug, Retail + hr = CoCreateInstance(audition ? &CLSID_XACTAuditionEngine + : (debug ? &CLSID_XACTDebugEngine : &CLSID_XACTEngine), + NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void**)ppEngine); + + // If debug engine does not exist fallback to retail version + if(FAILED(hr) && debug && !audition) + { + hr = CoCreateInstance(&CLSID_XACTEngine, NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void**)ppEngine); + } + + return hr; +} + +#endif // #ifdef __cplusplus + +#endif // #ifdef _XBOX + +//------------------------------------------------------------------------------ +// XACT specific error codes +//------------------------------------------------------------------------------ + +#define FACILITY_XACTENGINE 0xAC7 +#define XACTENGINEERROR(n) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_XACTENGINE, n) + +#define XACTENGINE_E_OUTOFMEMORY E_OUTOFMEMORY // Out of memory +#define XACTENGINE_E_INVALIDARG E_INVALIDARG // Invalid arg +#define XACTENGINE_E_NOTIMPL E_NOTIMPL // Not implemented +#define XACTENGINE_E_FAIL E_FAIL // Unknown error + +#define XACTENGINE_E_ALREADYINITIALIZED XACTENGINEERROR(0x001) // The engine is already initialized +#define XACTENGINE_E_NOTINITIALIZED XACTENGINEERROR(0x002) // The engine has not been initialized +#define XACTENGINE_E_EXPIRED XACTENGINEERROR(0x003) // The engine has expired (demo or pre-release version) +#define XACTENGINE_E_NONOTIFICATIONCALLBACK XACTENGINEERROR(0x004) // No notification callback +#define XACTENGINE_E_NOTIFICATIONREGISTERED XACTENGINEERROR(0x005) // Notification already registered +#define XACTENGINE_E_INVALIDUSAGE XACTENGINEERROR(0x006) // Invalid usage +#define XACTENGINE_E_INVALIDDATA XACTENGINEERROR(0x007) // Invalid data +#define XACTENGINE_E_INSTANCELIMITFAILTOPLAY XACTENGINEERROR(0x008) // Fail to play due to instance limit +#define XACTENGINE_E_NOGLOBALSETTINGS XACTENGINEERROR(0x009) // Global Settings not loaded +#define XACTENGINE_E_INVALIDVARIABLEINDEX XACTENGINEERROR(0x00a) // Invalid variable index +#define XACTENGINE_E_INVALIDCATEGORY XACTENGINEERROR(0x00b) // Invalid category +#define XACTENGINE_E_INVALIDCUEINDEX XACTENGINEERROR(0x00c) // Invalid cue index +#define XACTENGINE_E_INVALIDWAVEINDEX XACTENGINEERROR(0x00d) // Invalid wave index +#define XACTENGINE_E_INVALIDTRACKINDEX XACTENGINEERROR(0x00e) // Invalid track index +#define XACTENGINE_E_INVALIDSOUNDOFFSETORINDEX XACTENGINEERROR(0x00f) // Invalid sound offset or index +#define XACTENGINE_E_READFILE XACTENGINEERROR(0x010) // Error reading a file +#define XACTENGINE_E_UNKNOWNEVENT XACTENGINEERROR(0x011) // Unknown event type +#define XACTENGINE_E_INCALLBACK XACTENGINEERROR(0x012) // Invalid call of method of function from callback +#define XACTENGINE_E_NOWAVEBANK XACTENGINEERROR(0x013) // No wavebank exists for desired operation +#define XACTENGINE_E_SELECTVARIATION XACTENGINEERROR(0x014) // Unable to select a variation +#define XACTENGINE_E_MULTIPLEAUDITIONENGINES XACTENGINEERROR(0x015) // There can be only one audition engine +#define XACTENGINE_E_WAVEBANKNOTPREPARED XACTENGINEERROR(0x016) // The wavebank is not prepared +#define XACTENGINE_E_NORENDERER XACTENGINEERROR(0x017) // No audio device found on. +#define XACTENGINE_E_INVALIDENTRYCOUNT XACTENGINEERROR(0x018) // Invalid entry count for channel maps +#define XACTENGINE_E_SEEKTIMEBEYONDCUEEND XACTENGINEERROR(0x019) // Time offset for seeking is beyond the cue end. +#define XACTENGINE_E_SEEKTIMEBEYONDWAVEEND XACTENGINEERROR(0x01a) // Time offset for seeking is beyond the wave end. +#define XACTENGINE_E_NOFRIENDLYNAMES XACTENGINEERROR(0x01b) // Friendly names are not included in the bank. + +#define XACTENGINE_E_AUDITION_WRITEFILE XACTENGINEERROR(0x101) // Error writing a file during auditioning +#define XACTENGINE_E_AUDITION_NOSOUNDBANK XACTENGINEERROR(0x102) // Missing a soundbank +#define XACTENGINE_E_AUDITION_INVALIDRPCINDEX XACTENGINEERROR(0x103) // Missing an RPC curve +#define XACTENGINE_E_AUDITION_MISSINGDATA XACTENGINEERROR(0x104) // Missing data for an audition command +#define XACTENGINE_E_AUDITION_UNKNOWNCOMMAND XACTENGINEERROR(0x105) // Unknown command +#define XACTENGINE_E_AUDITION_INVALIDDSPINDEX XACTENGINEERROR(0x106) // Missing a DSP parameter +#define XACTENGINE_E_AUDITION_MISSINGWAVE XACTENGINEERROR(0x107) // Wave does not exist in auditioned wavebank +#define XACTENGINE_E_AUDITION_CREATEDIRECTORYFAILED XACTENGINEERROR(0x108) // Failed to create a directory for streaming wavebank data +#define XACTENGINE_E_AUDITION_INVALIDSESSION XACTENGINEERROR(0x109) // Invalid audition session + +#endif // #ifndef GUID_DEFS_ONLY + +#endif // #ifndef _XACT3_H_ diff --git a/dxsdk/Include/xact3d3.h b/dxsdk/Include/xact3d3.h new file mode 100644 index 0000000..f17e1e5 --- /dev/null +++ b/dxsdk/Include/xact3d3.h @@ -0,0 +1,275 @@ +/*-========================================================================-_ + | - XACT3D3 - | + | Copyright (c) Microsoft Corporation. All rights reserved. | + |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| + |VERSION: 0.1 MODEL: Unmanaged User-mode | + |CONTRACT: N / A EXCEPT: No Exceptions | + |PARENT: N / A MINREQ: Win2000, Xbox360 | + |PROJECT: XACT3D DIALECT: MS Visual C++ 7.0 | + |>------------------------------------------------------------------------<| + | DUTY: XACT 3D support | + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + NOTES: + 1. See X3DAudio.h for information regarding X3DAudio types. */ + + +#ifndef __XACT3D3_H__ +#define __XACT3D3_H__ + +//---------------------------------------------------// + #include + #include + + #pragma warning(push) + #pragma warning(disable: 4701) // disable "local variable may be used without having been initialized" compile warning + + // Supported speaker positions, represented as azimuth angles. + // + // Here's a picture of the azimuth angles for the 8 cardinal points, + // seen from above. The emitter's base position is at the origin 0. + // + // FRONT + // | 0 <-- azimuth + // | + // 7pi/4 \ | / pi/4 + // \ | / + // LEFT \|/ RIGHT + // 3pi/2-------0-------pi/2 + // /|\ + // / | \ + // 5pi/4 / | \ 3pi/4 + // | + // | pi + // BACK + // + #define LEFT_AZIMUTH (3*X3DAUDIO_PI/2) + #define RIGHT_AZIMUTH (X3DAUDIO_PI/2) + #define FRONT_LEFT_AZIMUTH (7*X3DAUDIO_PI/4) + #define FRONT_RIGHT_AZIMUTH (X3DAUDIO_PI/4) + #define FRONT_CENTER_AZIMUTH 0.0f + #define LOW_FREQUENCY_AZIMUTH X3DAUDIO_2PI + #define BACK_LEFT_AZIMUTH (5*X3DAUDIO_PI/4) + #define BACK_RIGHT_AZIMUTH (3*X3DAUDIO_PI/4) + #define BACK_CENTER_AZIMUTH X3DAUDIO_PI + #define FRONT_LEFT_OF_CENTER_AZIMUTH (15*X3DAUDIO_PI/8) + #define FRONT_RIGHT_OF_CENTER_AZIMUTH (X3DAUDIO_PI/8) + + +//-----------------------------------------------------// + // Supported emitter channel layouts: + static const float aStereoLayout[] = + { + LEFT_AZIMUTH, + RIGHT_AZIMUTH + }; + static const float a2Point1Layout[] = + { + LEFT_AZIMUTH, + RIGHT_AZIMUTH, + LOW_FREQUENCY_AZIMUTH + }; + static const float aQuadLayout[] = + { + FRONT_LEFT_AZIMUTH, + FRONT_RIGHT_AZIMUTH, + BACK_LEFT_AZIMUTH, + BACK_RIGHT_AZIMUTH + }; + static const float a4Point1Layout[] = + { + FRONT_LEFT_AZIMUTH, + FRONT_RIGHT_AZIMUTH, + LOW_FREQUENCY_AZIMUTH, + BACK_LEFT_AZIMUTH, + BACK_RIGHT_AZIMUTH + }; + static const float a5Point1Layout[] = + { + FRONT_LEFT_AZIMUTH, + FRONT_RIGHT_AZIMUTH, + FRONT_CENTER_AZIMUTH, + LOW_FREQUENCY_AZIMUTH, + BACK_LEFT_AZIMUTH, + BACK_RIGHT_AZIMUTH + }; + static const float a7Point1Layout[] = + { + FRONT_LEFT_AZIMUTH, + FRONT_RIGHT_AZIMUTH, + FRONT_CENTER_AZIMUTH, + LOW_FREQUENCY_AZIMUTH, + BACK_LEFT_AZIMUTH, + BACK_RIGHT_AZIMUTH, + LEFT_AZIMUTH, + RIGHT_AZIMUTH + }; + + +//-------------------------------------------------------// + //// + // DESCRIPTION: + // Initializes the 3D API's: + // + // REMARKS: + // This method only needs to be called once. + // X3DAudio will be initialized such that its speaker channel mask + // matches the format of the given XACT engine's final mix. + // + // PARAMETERS: + // pEngine - [in] XACT engine + // X3DInstance - [out] X3DAudio instance handle + // + // RETURN VALUE: + // HResult error code + //// + EXTERN_C HRESULT inline XACT3DInitialize (__in IXACT3Engine* pEngine, __in X3DAUDIO_HANDLE X3DInstance) + { + HRESULT hr = S_OK; + if (pEngine == NULL) { + hr = E_POINTER; + } + + XACTVARIABLEVALUE nSpeedOfSound; + if (SUCCEEDED(hr)) { + XACTVARIABLEINDEX xactSpeedOfSoundID = pEngine->GetGlobalVariableIndex("SpeedOfSound"); + hr = pEngine->GetGlobalVariable(xactSpeedOfSoundID, &nSpeedOfSound); + } + + if (SUCCEEDED(hr)) { + WAVEFORMATEXTENSIBLE wfxFinalMixFormat; + hr = pEngine->GetFinalMixFormat(&wfxFinalMixFormat); + if (SUCCEEDED(hr)) { + X3DAudioInitialize(wfxFinalMixFormat.dwChannelMask, nSpeedOfSound, X3DInstance); + } + } + return hr; + } + + + //// + // DESCRIPTION: + // Calculates DSP settings with respect to 3D parameters: + // + // REMARKS: + // Note the following flags are always specified for XACT3D calculation: + // X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_EMITTER_ANGLE + // + // This means the caller must set at least the following fields: + // X3DAUDIO_LISTENER.OrientFront + // X3DAUDIO_LISTENER.OrientTop + // X3DAUDIO_LISTENER.Position + // X3DAUDIO_LISTENER.Velocity + // + // X3DAUDIO_EMITTER.OrientFront + // X3DAUDIO_EMITTER.OrientTop, if emitter is multi-channel + // X3DAUDIO_EMITTER.Position + // X3DAUDIO_EMITTER.Velocity + // X3DAUDIO_EMITTER.InnerRadius + // X3DAUDIO_EMITTER.InnerRadiusAngle + // X3DAUDIO_EMITTER.ChannelCount + // X3DAUDIO_EMITTER.CurveDistanceScaler + // X3DAUDIO_EMITTER.DopplerScaler + // + // X3DAUDIO_DSP_SETTINGS.pMatrixCoefficients, the caller need only allocate space for SrcChannelCount*DstChannelCount elements + // X3DAUDIO_DSP_SETTINGS.SrcChannelCount + // X3DAUDIO_DSP_SETTINGS.DstChannelCount + // + // If X3DAUDIO_EMITTER.pChannelAzimuths is left NULL for multi-channel emitters, + // a default channel radius and channel azimuth array will be applied below. + // Distance curves such as X3DAUDIO_EMITTER.pVolumeCurve should be + // left NULL as XACT's native RPCs will be used to define DSP behaviour + // with respect to normalized distance. + // + // See X3DAudio.h for information regarding X3DAudio types. + // + // PARAMETERS: + // X3DInstance - [in] X3DAudio instance handle, returned from XACT3DInitialize() + // pListener - [in] point of 3D audio reception + // pEmitter - [in] 3D audio source + // pDSPSettings - [out] receives calculation results, applied to an XACT cue via XACT3DApply() + // + // RETURN VALUE: + // HResult error code + //// + EXTERN_C HRESULT inline XACT3DCalculate (__in X3DAUDIO_HANDLE X3DInstance, __in const X3DAUDIO_LISTENER* pListener, __inout X3DAUDIO_EMITTER* pEmitter, __inout X3DAUDIO_DSP_SETTINGS* pDSPSettings) + { + HRESULT hr = S_OK; + if (pListener == NULL || pEmitter == NULL || pDSPSettings == NULL) { + hr = E_POINTER; + } + + if (SUCCEEDED(hr)) { + if (pEmitter->ChannelCount > 1 && pEmitter->pChannelAzimuths == NULL) { + pEmitter->ChannelRadius = 1.0f; + + switch (pEmitter->ChannelCount) { + case 2: pEmitter->pChannelAzimuths = (float*)&aStereoLayout[0]; break; + case 3: pEmitter->pChannelAzimuths = (float*)&a2Point1Layout[0]; break; + case 4: pEmitter->pChannelAzimuths = (float*)&aQuadLayout[0]; break; + case 5: pEmitter->pChannelAzimuths = (float*)&a4Point1Layout[0]; break; + case 6: pEmitter->pChannelAzimuths = (float*)&a5Point1Layout[0]; break; + case 8: pEmitter->pChannelAzimuths = (float*)&a7Point1Layout[0]; break; + default: hr = E_FAIL; break; + } + } + } + + if (SUCCEEDED(hr)) { + static X3DAUDIO_DISTANCE_CURVE_POINT DefaultCurvePoints[2] = { 0.0f, 1.0f, 1.0f, 1.0f }; + static X3DAUDIO_DISTANCE_CURVE DefaultCurve = { (X3DAUDIO_DISTANCE_CURVE_POINT*)&DefaultCurvePoints[0], 2 }; + if (pEmitter->pVolumeCurve == NULL) { + pEmitter->pVolumeCurve = &DefaultCurve; + } + if (pEmitter->pLFECurve == NULL) { + pEmitter->pLFECurve = &DefaultCurve; + } + + X3DAudioCalculate(X3DInstance, pListener, pEmitter, (X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_EMITTER_ANGLE), pDSPSettings); + } + + return hr; + } + + + //// + // DESCRIPTION: + // Applies results from a call to XACT3DCalculate() to a cue. + // + // PARAMETERS: + // pDSPSettings - [in] calculation results generated by XACT3DCalculate() + // pCue - [in] cue to which to apply pDSPSettings + // + // RETURN VALUE: + // HResult error code + //// + EXTERN_C HRESULT inline XACT3DApply (__in const X3DAUDIO_DSP_SETTINGS* pDSPSettings, __in IXACT3Cue* pCue) + { + HRESULT hr = S_OK; + if (pDSPSettings == NULL || pCue == NULL) { + hr = E_POINTER; + } + + if (SUCCEEDED(hr)) { + hr = pCue->SetMatrixCoefficients(pDSPSettings->SrcChannelCount, pDSPSettings->DstChannelCount, pDSPSettings->pMatrixCoefficients); + } + if (SUCCEEDED(hr)) { + XACTVARIABLEINDEX xactDistanceID = pCue->GetVariableIndex("Distance"); + hr = pCue->SetVariable(xactDistanceID, pDSPSettings->EmitterToListenerDistance); + } + if (SUCCEEDED(hr)) { + XACTVARIABLEINDEX xactDopplerID = pCue->GetVariableIndex("DopplerPitchScalar"); + hr = pCue->SetVariable(xactDopplerID, pDSPSettings->DopplerFactor); + } + if (SUCCEEDED(hr)) { + XACTVARIABLEINDEX xactOrientationID = pCue->GetVariableIndex("OrientationAngle"); + hr = pCue->SetVariable(xactOrientationID, pDSPSettings->EmitterToListenerAngle * (180.0f / X3DAUDIO_PI)); + } + + return hr; + } + + + #pragma warning(pop) + +#endif // __XACT3D3_H__ +//---------------------------------<-EOF->----------------------------------// diff --git a/dxsdk/Include/xact3wb.h b/dxsdk/Include/xact3wb.h new file mode 100644 index 0000000..521667b --- /dev/null +++ b/dxsdk/Include/xact3wb.h @@ -0,0 +1,598 @@ +/*************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: xact3wb.h + * Content: XACT 3 wave bank definitions. + * + ****************************************************************************/ + +#ifndef __XACT3WB_H__ +#define __XACT3WB_H__ + +#ifdef _XBOX +# include +#else +# include +#endif + +#include +#include + +#pragma warning(push) +#pragma warning(disable:4201) +#pragma warning(disable:4214) // nonstandard extension used : bit field types other than int + +#pragma pack(push, 1) +#if !defined(_X86_) + #define XACTUNALIGNED __unaligned +#else + #define XACTUNALIGNED +#endif + +#ifdef _M_PPCBE +#pragma bitfield_order(push, lsb_to_msb) +#endif + +#define WAVEBANK_HEADER_SIGNATURE 'DNBW' // WaveBank RIFF chunk signature +#define WAVEBANK_HEADER_VERSION 44 // Current wavebank file version + +#define WAVEBANK_BANKNAME_LENGTH 64 // Wave bank friendly name length, in characters +#define WAVEBANK_ENTRYNAME_LENGTH 64 // Wave bank entry friendly name length, in characters + +#define WAVEBANK_MAX_DATA_SEGMENT_SIZE 0xFFFFFFFF // Maximum wave bank data segment size, in bytes +#define WAVEBANK_MAX_COMPACT_DATA_SEGMENT_SIZE 0x001FFFFF // Maximum compact wave bank data segment size, in bytes + +typedef DWORD WAVEBANKOFFSET; + +// +// Bank flags +// + +#define WAVEBANK_TYPE_BUFFER 0x00000000 // In-memory buffer +#define WAVEBANK_TYPE_STREAMING 0x00000001 // Streaming +#define WAVEBANK_TYPE_MASK 0x00000001 + +#define WAVEBANK_FLAGS_ENTRYNAMES 0x00010000 // Bank includes entry names +#define WAVEBANK_FLAGS_COMPACT 0x00020000 // Bank uses compact format +#define WAVEBANK_FLAGS_SYNC_DISABLED 0x00040000 // Bank is disabled for audition sync +#define WAVEBANK_FLAGS_SEEKTABLES 0x00080000 // Bank includes seek tables. +#define WAVEBANK_FLAGS_MASK 0x000F0000 + +// +// Entry flags +// + +#define WAVEBANKENTRY_FLAGS_READAHEAD 0x00000001 // Enable stream read-ahead +#define WAVEBANKENTRY_FLAGS_LOOPCACHE 0x00000002 // One or more looping sounds use this wave +#define WAVEBANKENTRY_FLAGS_REMOVELOOPTAIL 0x00000004 // Remove data after the end of the loop region +#define WAVEBANKENTRY_FLAGS_IGNORELOOP 0x00000008 // Used internally when the loop region can't be used +#define WAVEBANKENTRY_FLAGS_MASK 0x00000008 + +// +// Entry wave format identifiers +// + +#define WAVEBANKMINIFORMAT_TAG_PCM 0x0 // PCM data +#define WAVEBANKMINIFORMAT_TAG_XMA 0x1 // XMA data +#define WAVEBANKMINIFORMAT_TAG_ADPCM 0x2 // ADPCM data +#define WAVEBANKMINIFORMAT_TAG_WMA 0x3 // WMA data + +#define WAVEBANKMINIFORMAT_BITDEPTH_8 0x0 // 8-bit data (PCM only) +#define WAVEBANKMINIFORMAT_BITDEPTH_16 0x1 // 16-bit data (PCM only) + +// +// Arbitrary fixed sizes +// +#define WAVEBANKENTRY_XMASTREAMS_MAX 3 // enough for 5.1 channel audio +#define WAVEBANKENTRY_XMACHANNELS_MAX 6 // enough for 5.1 channel audio (cf. XAUDIOCHANNEL_SOURCEMAX) + +// +// DVD data sizes +// + +#define WAVEBANK_DVD_SECTOR_SIZE 2048 +#define WAVEBANK_DVD_BLOCK_SIZE (WAVEBANK_DVD_SECTOR_SIZE * 16) + +// +// Bank alignment presets +// + +#define WAVEBANK_ALIGNMENT_MIN 4 // Minimum alignment +#define WAVEBANK_ALIGNMENT_DVD WAVEBANK_DVD_SECTOR_SIZE // DVD-optimized alignment + +// +// Wave bank segment identifiers +// + +typedef enum WAVEBANKSEGIDX +{ + WAVEBANK_SEGIDX_BANKDATA = 0, // Bank data + WAVEBANK_SEGIDX_ENTRYMETADATA, // Entry meta-data + WAVEBANK_SEGIDX_SEEKTABLES, // Storage for seek tables for the encoded waves. + WAVEBANK_SEGIDX_ENTRYNAMES, // Entry friendly names + WAVEBANK_SEGIDX_ENTRYWAVEDATA, // Entry wave data + WAVEBANK_SEGIDX_COUNT +} WAVEBANKSEGIDX, *LPWAVEBANKSEGIDX; + +typedef const WAVEBANKSEGIDX *LPCWAVEBANKSEGIDX; + +// +// Endianness +// + +#ifdef __cplusplus + +namespace XACTWaveBank +{ + __inline void SwapBytes(XACTUNALIGNED DWORD &dw) + { + +#ifdef _X86_ + + __asm + { + mov edi, dw + mov eax, [edi] + bswap eax + mov [edi], eax + } + +#else // _X86_ + + dw = _byteswap_ulong(dw); + +#endif // _X86_ + + } + + __inline void SwapBytes(XACTUNALIGNED WORD &w) + { + +#ifdef _X86_ + + __asm + { + mov edi, w + mov ax, [edi] + xchg ah, al + mov [edi], ax + } + +#else // _X86_ + + w = _byteswap_ushort(w); + +#endif // _X86_ + + } + +} + +#endif // __cplusplus + +// +// Wave bank region in bytes. +// + +typedef struct WAVEBANKREGION +{ + DWORD dwOffset; // Region offset, in bytes. + DWORD dwLength; // Region length, in bytes. + +#ifdef __cplusplus + + void SwapBytes(void) + { + XACTWaveBank::SwapBytes(dwOffset); + XACTWaveBank::SwapBytes(dwLength); + } + +#endif // __cplusplus + +} WAVEBANKREGION, *LPWAVEBANKREGION; + +typedef const WAVEBANKREGION *LPCWAVEBANKREGION; + + +// +// Wave bank region in samples. +// + +typedef struct WAVEBANKSAMPLEREGION +{ + DWORD dwStartSample; // Start sample for the region. + DWORD dwTotalSamples; // Region length in samples. + +#ifdef __cplusplus + + void SwapBytes(void) + { + XACTWaveBank::SwapBytes(dwStartSample); + XACTWaveBank::SwapBytes(dwTotalSamples); + } + +#endif // __cplusplus + +} WAVEBANKSAMPLEREGION, *LPWAVEBANKSAMPLEREGION; + +typedef const WAVEBANKSAMPLEREGION *LPCWAVEBANKSAMPLEREGION; + + +// +// Wave bank file header +// + +typedef struct WAVEBANKHEADER +{ + DWORD dwSignature; // File signature + DWORD dwVersion; // Version of the tool that created the file + DWORD dwHeaderVersion; // Version of the file format + WAVEBANKREGION Segments[WAVEBANK_SEGIDX_COUNT]; // Segment lookup table + +#ifdef __cplusplus + + void SwapBytes(void) + { + XACTWaveBank::SwapBytes(dwSignature); + XACTWaveBank::SwapBytes(dwVersion); + XACTWaveBank::SwapBytes(dwHeaderVersion); + + for(int i = 0; i < WAVEBANK_SEGIDX_COUNT; i++) + { + Segments[i].SwapBytes(); + } + } + +#endif // __cplusplus + +} WAVEBANKHEADER, *LPWAVEBANKHEADER; + +typedef const WAVEBANKHEADER *LPCWAVEBANKHEADER; + +// +// Table for converting WMA Average Bytes per Second values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field +// NOTE: There can be a max of 8 values in the table. +// + +#define MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES 7 + +static const DWORD aWMAAvgBytesPerSec[] = +{ + 12000, + 24000, + 4000, + 6000, + 8000, + 20000, + 2500 +}; +// bitrate = entry * 8 + +// +// Table for converting WMA Block Align values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field +// NOTE: There can be a max of 32 values in the table. +// + +#define MAX_WMA_BLOCK_ALIGN_ENTRIES 17 + +static const DWORD aWMABlockAlign[] = +{ + 929, + 1487, + 1280, + 2230, + 8917, + 8192, + 4459, + 5945, + 2304, + 1536, + 1485, + 1008, + 2731, + 4096, + 6827, + 5462, + 1280 +}; + +struct WAVEBANKENTRY; + +// +// Entry compressed data format +// + +typedef union WAVEBANKMINIWAVEFORMAT +{ + struct + { + DWORD wFormatTag : 2; // Format tag + DWORD nChannels : 3; // Channel count (1 - 6) + DWORD nSamplesPerSec : 18; // Sampling rate + DWORD wBlockAlign : 8; // Block alignment. For WMA, lower 6 bits block alignment index, upper 2 bits bytes-per-second index. + DWORD wBitsPerSample : 1; // Bits per sample (8 vs. 16, PCM only); WMAudio2/WMAudio3 (for WMA) + }; + + DWORD dwValue; + +#ifdef __cplusplus + + void SwapBytes(void) + { + XACTWaveBank::SwapBytes(dwValue); + } + + WORD BitsPerSample() const + { + if (wFormatTag == WAVEBANKMINIFORMAT_TAG_XMA) + return XMA_OUTPUT_SAMPLE_BITS; // First, because most common on Xbox 360 + if (wFormatTag == WAVEBANKMINIFORMAT_TAG_WMA) + return 16; + if (wFormatTag == WAVEBANKMINIFORMAT_TAG_ADPCM) + return 4; // MSADPCM_BITS_PER_SAMPLE == 4 + + // wFormatTag must be WAVEBANKMINIFORMAT_TAG_PCM (2 bits can only represent 4 different values) + return (wBitsPerSample == WAVEBANKMINIFORMAT_BITDEPTH_16) ? 16 : 8; + } + + #define ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET 22 + DWORD BlockAlign() const + { + DWORD dwReturn = 0; + + switch (wFormatTag) + { + case WAVEBANKMINIFORMAT_TAG_PCM: + dwReturn = wBlockAlign; + break; + + case WAVEBANKMINIFORMAT_TAG_XMA: + dwReturn = nChannels * XMA_OUTPUT_SAMPLE_BITS / 8; + break; + + case WAVEBANKMINIFORMAT_TAG_ADPCM: + dwReturn = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels; + break; + + case WAVEBANKMINIFORMAT_TAG_WMA: + { + DWORD dwBlockAlignIndex = wBlockAlign & 0x1F; + if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES) + dwReturn = aWMABlockAlign[dwBlockAlignIndex]; + } + break; + } + + return dwReturn; + } + + DWORD AvgBytesPerSec() const + { + DWORD dwReturn = 0; + + switch (wFormatTag) + { + case WAVEBANKMINIFORMAT_TAG_PCM: + case WAVEBANKMINIFORMAT_TAG_XMA: + dwReturn = nSamplesPerSec * wBlockAlign; + break; + + case WAVEBANKMINIFORMAT_TAG_ADPCM: + { + DWORD blockAlign = BlockAlign(); + DWORD samplesPerAdpcmBlock = AdpcmSamplesPerBlock(); + dwReturn = blockAlign * nSamplesPerSec / samplesPerAdpcmBlock; + } + break; + + case WAVEBANKMINIFORMAT_TAG_WMA: + { + DWORD dwBytesPerSecIndex = wBlockAlign >> 5; + if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES) + dwReturn = aWMAAvgBytesPerSec[dwBytesPerSecIndex]; + } + break; + } + + return dwReturn; + } + + DWORD EncodeWMABlockAlign(DWORD dwBlockAlign, DWORD dwAvgBytesPerSec) const + { + DWORD dwReturn = 0; + DWORD dwBlockAlignIndex = 0; + DWORD dwBytesPerSecIndex = 0; + + for (; dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES && dwBlockAlign != aWMABlockAlign[dwBlockAlignIndex]; dwBlockAlignIndex++); + + if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES) + { + for (; dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES && dwAvgBytesPerSec != aWMAAvgBytesPerSec[dwBytesPerSecIndex]; dwBytesPerSecIndex++); + + if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES) + { + dwReturn = dwBlockAlignIndex | (dwBytesPerSecIndex << 5); + } + } + + return dwReturn; + } + + + void XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const struct WAVEBANKENTRY* entry) const; + + DWORD AdpcmSamplesPerBlock() const + { + DWORD nBlockAlign = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels; + return nBlockAlign * 2 / (DWORD)nChannels - 12; + } + + void AdpcmFillCoefficientTable(ADPCMWAVEFORMAT *fmt) const + { + // These are fixed since we are always using MS ADPCM + fmt->wNumCoef = 7; /* MSADPCM_NUM_COEFFICIENTS */ + + static ADPCMCOEFSET aCoef[7] = { { 256, 0}, {512, -256}, {0,0}, {192,64}, {240,0}, {460, -208}, {392,-232} }; + memcpy( &fmt->aCoef, aCoef, sizeof(aCoef) ); + } + +#endif // __cplusplus + +} WAVEBANKMINIWAVEFORMAT, *LPWAVEBANKMINIWAVEFORMAT; + +typedef const WAVEBANKMINIWAVEFORMAT *LPCWAVEBANKMINIWAVEFORMAT; + +// +// Entry meta-data +// + +typedef struct WAVEBANKENTRY +{ + union + { + struct + { + // Entry flags + DWORD dwFlags : 4; + + // Duration of the wave, in units of one sample. + // For instance, a ten second long wave sampled + // at 48KHz would have a duration of 480,000. + // This value is not affected by the number of + // channels, the number of bits per sample, or the + // compression format of the wave. + DWORD Duration : 28; + }; + DWORD dwFlagsAndDuration; + }; + + WAVEBANKMINIWAVEFORMAT Format; // Entry format. + WAVEBANKREGION PlayRegion; // Region within the wave data segment that contains this entry. + WAVEBANKSAMPLEREGION LoopRegion; // Region within the wave data (in samples) that should loop. + +#ifdef __cplusplus + + void SwapBytes(void) + { + XACTWaveBank::SwapBytes(dwFlagsAndDuration); + Format.SwapBytes(); + PlayRegion.SwapBytes(); + LoopRegion.SwapBytes(); + } + +#endif // __cplusplus + +} WAVEBANKENTRY, *LPWAVEBANKENTRY; + +typedef const WAVEBANKENTRY *LPCWAVEBANKENTRY; + +// +// Compact entry meta-data +// + +typedef struct WAVEBANKENTRYCOMPACT +{ + DWORD dwOffset : 21; // Data offset, in sectors + DWORD dwLengthDeviation : 11; // Data length deviation, in bytes + +#ifdef __cplusplus + + void SwapBytes(void) + { + XACTWaveBank::SwapBytes(*(LPDWORD)this); + } + +#endif // __cplusplus + +} WAVEBANKENTRYCOMPACT, *LPWAVEBANKENTRYCOMPACT; + +typedef const WAVEBANKENTRYCOMPACT *LPCWAVEBANKENTRYCOMPACT; + +// +// Bank data segment +// + +typedef struct WAVEBANKDATA +{ + DWORD dwFlags; // Bank flags + DWORD dwEntryCount; // Number of entries in the bank + CHAR szBankName[WAVEBANK_BANKNAME_LENGTH]; // Bank friendly name + DWORD dwEntryMetaDataElementSize; // Size of each entry meta-data element, in bytes + DWORD dwEntryNameElementSize; // Size of each entry name element, in bytes + DWORD dwAlignment; // Entry alignment, in bytes + WAVEBANKMINIWAVEFORMAT CompactFormat; // Format data for compact bank + FILETIME BuildTime; // Build timestamp + +#ifdef __cplusplus + + void SwapBytes(void) + { + XACTWaveBank::SwapBytes(dwFlags); + XACTWaveBank::SwapBytes(dwEntryCount); + XACTWaveBank::SwapBytes(dwEntryMetaDataElementSize); + XACTWaveBank::SwapBytes(dwEntryNameElementSize); + XACTWaveBank::SwapBytes(dwAlignment); + CompactFormat.SwapBytes(); + XACTWaveBank::SwapBytes(BuildTime.dwLowDateTime); + XACTWaveBank::SwapBytes(BuildTime.dwHighDateTime); + } + +#endif // __cplusplus + +} WAVEBANKDATA, *LPWAVEBANKDATA; + +typedef const WAVEBANKDATA *LPCWAVEBANKDATA; + +inline void WAVEBANKMINIWAVEFORMAT::XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const WAVEBANKENTRY* entry) const +{ + // Note caller is responsbile for filling out fmt->wfx with other helper functions. + + fmt->NumStreams = (WORD)( (nChannels + 1) / 2 ); + + switch (nChannels) + { + case 1: fmt->ChannelMask = SPEAKER_MONO; break; + case 2: fmt->ChannelMask = SPEAKER_STEREO; break; + case 3: fmt->ChannelMask = SPEAKER_2POINT1; break; + case 4: fmt->ChannelMask = SPEAKER_QUAD; break; + case 5: fmt->ChannelMask = SPEAKER_4POINT1; break; + case 6: fmt->ChannelMask = SPEAKER_5POINT1; break; + case 7: fmt->ChannelMask = SPEAKER_5POINT1 | SPEAKER_BACK_CENTER; break; + case 8: fmt->ChannelMask = SPEAKER_7POINT1; break; + default: fmt->ChannelMask = 0; break; + } + + fmt->SamplesEncoded = entry->Duration; + fmt->BytesPerBlock = 65536; /* XACT_FIXED_XMA_BLOCK_SIZE */ + + fmt->PlayBegin = entry->PlayRegion.dwOffset; + fmt->PlayLength = entry->PlayRegion.dwLength; + + if (entry->LoopRegion.dwTotalSamples > 0) + { + fmt->LoopBegin = entry->LoopRegion.dwStartSample; + fmt->LoopLength = entry->LoopRegion.dwTotalSamples; + fmt->LoopCount = 0xff; /* XACTLOOPCOUNT_INFINITE */ + } + else + { + fmt->LoopBegin = 0; + fmt->LoopLength = 0; + fmt->LoopCount = 0; + } + + fmt->EncoderVersion = 4; // XMAENCODER_VERSION_XMA2 + + fmt->BlockCount = blockCount; +} + +#ifdef _M_PPCBE +#pragma bitfield_order(pop) +#endif + +#pragma warning(pop) +#pragma pack(pop) + +#endif // __XACTWB_H__ + diff --git a/dxsdk/Include/xma2defs.h b/dxsdk/Include/xma2defs.h new file mode 100644 index 0000000..13a4306 --- /dev/null +++ b/dxsdk/Include/xma2defs.h @@ -0,0 +1,718 @@ +/*************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: xma2defs.h + * Content: Constants, data types and functions for XMA2 compressed audio. + * + ***************************************************************************/ + +#ifndef __XMA2DEFS_INCLUDED__ +#define __XMA2DEFS_INCLUDED__ + +#include // Markers for documenting API semantics +#include // For S_OK, E_FAIL +#include // Basic data types and constants for audio work + + +/*************************************************************************** + * Overview + ***************************************************************************/ + +// A typical XMA2 file contains these RIFF chunks: +// +// 'fmt' or 'XMA2' chunk (or both): A description of the XMA data's structure +// and characteristics (length, channels, sample rate, loops, block size, etc). +// +// 'seek' chunk: A seek table to help navigate the XMA data. +// +// 'data' chunk: The encoded XMA2 data. +// +// The encoded XMA2 data is structured as a set of BLOCKS, which contain PACKETS, +// which contain FRAMES, which contain SUBFRAMES (roughly speaking). The frames +// in a file may also be divided into several subsets, called STREAMS. +// +// FRAME: A variable-sized segment of XMA data that decodes to exactly 512 mono +// or stereo PCM samples. This is the smallest unit of XMA data that can +// be decoded in isolation. Frames are an arbitrary number of bits in +// length, and need not be byte-aligned. See "XMA frame structure" below. +// +// SUBFRAME: A region of bits in an XMA frame that decodes to 128 mono or stereo +// samples. The XMA decoder cannot decode a subframe in isolation; it needs +// a whole frame to work with. However, it can begin emitting the frame's +// decoded samples at any one of the four subframe boundaries. Subframes +// can be addressed for seeking and looping purposes. +// +// PACKET: A 2Kb region containing a 32-bit header and some XMA frames. Frames +// can (and usually do) span packets. A packet's header includes the offset +// in bits of the first frame that begins within that packet. All of the +// frames that begin in a given packet belong to the same "stream" (see the +// Multichannel Audio section below). +// +// STREAM: A set of packets within an XMA file that all contain data for the +// same mono or stereo component of a PCM file with more than two channels. +// The packets comprising a given stream may be interleaved with each other +// more or less arbitrarily; see Multichannel Audio. +// +// BLOCK: An array of XMA packets; or, to break it down differently, a series of +// consecutive XMA frames, padded at the end with reserved data. A block +// must contain at least one 2Kb packet per stream, and it can hold up to +// 4095 packets (8190Kb), but its size is typically in the 32Kb-128Kb range. +// (The size chosen involves a trade-off between memory use and efficiency +// of reading from permanent storage.) +// +// XMA frames do not span blocks, so a block is guaranteed to begin with a +// set of complete frames, one per stream. Also, a block in a multi-stream +// XMA2 file always contains the same number of samples for each stream; +// see Multichannel Audio. +// +// The 'data' chunk in an XMA2 file is an array of XMA2WAVEFORMAT.BlockCount XMA +// blocks, all the same size (as specified in XMA2WAVEFORMAT.BlockSizeInBytes) +// except for the last one, which may be shorter. + + +// MULTICHANNEL AUDIO: the XMA decoder can only decode raw XMA data into either +// mono or stereo PCM data. In order to encode a 6-channel file (say), the file +// must be deinterleaved into 3 stereo streams that are encoded independently, +// producing 3 encoded XMA data streams. Then the packets in these 3 streams +// are interleaved to produce a single XMA2 file, and some information is added +// to the file so that the original 6-channel audio can be reconstructed at +// decode time. This works using the concept of an XMA stream (see above). +// +// The frames for all the streams in an XMA file are interleaved in an arbitrary +// order. To locate a frame that belongs to a given stream in a given XMA block, +// you must examine the first few packets in the block. Here (and only here) the +// packets are guaranteed to be presented in stream order, so that all frames +// beginning in packet 0 belong to stream 0 (the first stereo pair), etc. +// +// (This means that when decoding multi-stream XMA files, only entire XMA blocks +// should be submitted to the decoder; otherwise it cannot know which frames +// belong to which stream.) +// +// Once you have one frame that belongs to a given stream, you can find the next +// one by looking at the frame's 'NextFrameOffsetBits' value (which is stored in +// its first 15 bits; see XMAFRAME below). The GetXmaFrameBitPosition function +// uses this technique. + + +// SEEKING IN XMA2 FILES: Here is some pseudocode to find the byte position and +// subframe in an XMA2 file which will contain sample S when decoded. +// +// 1. Traverse the seek table to find the XMA2 block containing sample S. The +// seek table is an array of big-endian DWORDs, one per block in the file. +// The Nth DWORD is the total number of PCM samples that would be obtained +// by decoding the entire XMA file up to the end of block N. Hence, the +// block we want is the first one whose seek table entry is greater than S. +// (See the GetXmaBlockContainingSample helper function.) +// +// 2. Calculate which frame F within the block found above contains sample S. +// Since each frame decodes to 512 samples, this is straightforward. The +// first frame in the block produces samples X to X + 512, where X is the +// seek table entry for the prior block. So F is (S - X) / 512. +// +// 3. Find the bit offset within the block where frame F starts. Since frames +// are variable-sized, this can only be done by traversing all the frames in +// the block until we reach frame F. (See GetXmaFrameBitPosition.) +// +// 4. Frame F has four 128-sample subframes. To find the subframe containing S, +// we can use the formula (S % 512) / 128. +// +// In the case of multi-stream XMA files, sample S is a multichannel sample with +// parts coming from several frames, one per stream. To find all these frames, +// steps 2-4 need to be repeated for each stream N, using the knowledge that the +// first packets in a block are presented in stream order. The frame traversal +// in step 3 must be started at the first frame in the Nth packet of the block, +// which will be the first frame for stream N. (And the packet header will tell +// you the first frame's start position within the packet.) +// +// Step 1 can be performed using the GetXmaBlockContainingSample function below, +// and steps 2-4 by calling GetXmaDecodePositionForSample once for each stream. + + + +/*************************************************************************** + * XMA constants + ***************************************************************************/ + +// Size of the PCM samples produced by the XMA decoder +#define XMA_OUTPUT_SAMPLE_BYTES 2u +#define XMA_OUTPUT_SAMPLE_BITS (XMA_OUTPUT_SAMPLE_BYTES * 8u) + +// Size of an XMA packet +#define XMA_BYTES_PER_PACKET 2048u +#define XMA_BITS_PER_PACKET (XMA_BYTES_PER_PACKET * 8u) + +// Size of an XMA packet header +#define XMA_PACKET_HEADER_BYTES 4u +#define XMA_PACKET_HEADER_BITS (XMA_PACKET_HEADER_BYTES * 8u) + +// Sample blocks in a decoded XMA frame +#define XMA_SAMPLES_PER_FRAME 512u + +// Sample blocks in a decoded XMA subframe +#define XMA_SAMPLES_PER_SUBFRAME 128u + +// Maximum encoded data that can be submitted to the XMA decoder at a time +#define XMA_READBUFFER_MAX_PACKETS 4095u +#define XMA_READBUFFER_MAX_BYTES (XMA_READBUFFER_MAX_PACKETS * XMA_BYTES_PER_PACKET) + +// Maximum size allowed for the XMA decoder's output buffers +#define XMA_WRITEBUFFER_MAX_BYTES (31u * 256u) + +// Required byte alignment of the XMA decoder's output buffers +#define XMA_WRITEBUFFER_BYTE_ALIGNMENT 256u + +// Decode chunk sizes for the XMA_PLAYBACK_INIT.subframesToDecode field +#define XMA_MIN_SUBFRAMES_TO_DECODE 1u +#define XMA_MAX_SUBFRAMES_TO_DECODE 8u +#define XMA_OPTIMAL_SUBFRAMES_TO_DECODE 4u + +// LoopCount<255 means finite repetitions; LoopCount=255 means infinite looping +#define XMA_MAX_LOOPCOUNT 254u +#define XMA_INFINITE_LOOP 255u + + + +/*************************************************************************** + * XMA format structures + ***************************************************************************/ + +// The currently recommended way to express format information for XMA2 files +// is the XMA2WAVEFORMATEX structure. This structure is fully compliant with +// the WAVEFORMATEX standard and contains all the information needed to parse +// and manage XMA2 files in a compact way. + +#define WAVE_FORMAT_XMA2 0x166 + +typedef struct XMA2WAVEFORMATEX +{ + WAVEFORMATEX wfx; + // Meaning of the WAVEFORMATEX fields here: + // wFormatTag; // Audio format type; always WAVE_FORMAT_XMA2 + // nChannels; // Channel count of the decoded audio + // nSamplesPerSec; // Sample rate of the decoded audio + // nAvgBytesPerSec; // Used internally by the XMA encoder + // nBlockAlign; // Decoded sample size; channels * wBitsPerSample / 8 + // wBitsPerSample; // Bits per decoded mono sample; always 16 for XMA + // cbSize; // Size in bytes of the rest of this structure (34) + + WORD NumStreams; // Number of audio streams (1 or 2 channels each) + DWORD ChannelMask; // Spatial positions of the channels in this file, + // stored as SPEAKER_xxx values (see audiodefs.h) + DWORD SamplesEncoded; // Total number of PCM samples the file decodes to + DWORD BytesPerBlock; // XMA block size (but the last one may be shorter) + DWORD PlayBegin; // First valid sample in the decoded audio + DWORD PlayLength; // Length of the valid part of the decoded audio + DWORD LoopBegin; // Beginning of the loop region in decoded sample terms + DWORD LoopLength; // Length of the loop region in decoded sample terms + BYTE LoopCount; // Number of loop repetitions; 255 = infinite + BYTE EncoderVersion; // Version of XMA encoder that generated the file + WORD BlockCount; // XMA blocks in file (and entries in its seek table) +} XMA2WAVEFORMATEX, *PXMA2WAVEFORMATEX; + + +// The legacy XMA format structures are described here for reference, but they +// should not be used in new content. XMAWAVEFORMAT was the structure used in +// XMA version 1 files. XMA2WAVEFORMAT was used in early XMA2 files; it is not +// placed in the usual 'fmt' RIFF chunk but in its own 'XMA2' chunk. + +#ifndef WAVE_FORMAT_XMA +#define WAVE_FORMAT_XMA 0x0165 + +// Values used in the ChannelMask fields below. Similar to the SPEAKER_xxx +// values defined in audiodefs.h, but modified to fit in a single byte. +#ifndef XMA_SPEAKER_LEFT + #define XMA_SPEAKER_LEFT 0x01 + #define XMA_SPEAKER_RIGHT 0x02 + #define XMA_SPEAKER_CENTER 0x04 + #define XMA_SPEAKER_LFE 0x08 + #define XMA_SPEAKER_LEFT_SURROUND 0x10 + #define XMA_SPEAKER_RIGHT_SURROUND 0x20 + #define XMA_SPEAKER_LEFT_BACK 0x40 + #define XMA_SPEAKER_RIGHT_BACK 0x80 +#endif + + +// Used in XMAWAVEFORMAT for per-stream data +typedef struct XMASTREAMFORMAT +{ + DWORD PsuedoBytesPerSec; // Used by the XMA encoder (typo preserved for legacy reasons) + DWORD SampleRate; // The stream's decoded sample rate (in XMA2 files, + // this is the same for all streams in the file). + DWORD LoopStart; // Bit offset of the frame containing the loop start + // point, relative to the beginning of the stream. + DWORD LoopEnd; // Bit offset of the frame containing the loop end. + BYTE SubframeData; // Two 4-bit numbers specifying the exact location of + // the loop points within the frames that contain them. + // SubframeEnd: Subframe of the loop end frame where + // the loop ends. Ranges from 0 to 3. + // SubframeSkip: Subframes to skip in the start frame to + // reach the loop. Ranges from 0 to 4. + BYTE Channels; // Number of channels in the stream (1 or 2) + WORD ChannelMask; // Spatial positions of the channels in the stream +} XMASTREAMFORMAT; + +// Legacy XMA1 format structure +typedef struct XMAWAVEFORMAT +{ + WORD FormatTag; // Audio format type (always WAVE_FORMAT_XMA) + WORD BitsPerSample; // Bit depth (currently required to be 16) + WORD EncodeOptions; // Options for XMA encoder/decoder + WORD LargestSkip; // Largest skip used in interleaving streams + WORD NumStreams; // Number of interleaved audio streams + BYTE LoopCount; // Number of loop repetitions; 255 = infinite + BYTE Version; // XMA encoder version that generated the file. + // Always 3 or higher for XMA2 files. + XMASTREAMFORMAT XmaStreams[1]; // Per-stream format information; the actual + // array length is in the NumStreams field. +} XMAWAVEFORMAT; + + +// Used in XMA2WAVEFORMAT for per-stream data +typedef struct XMA2STREAMFORMAT +{ + BYTE Channels; // Number of channels in the stream (1 or 2) + BYTE RESERVED; // Reserved for future use + WORD ChannelMask; // Spatial positions of the channels in the stream +} XMA2STREAMFORMAT; + +// Legacy XMA2 format structure (big-endian byte ordering) +typedef struct XMA2WAVEFORMAT +{ + BYTE Version; // XMA encoder version that generated the file. + // Always 3 or higher for XMA2 files. + BYTE NumStreams; // Number of interleaved audio streams + BYTE RESERVED; // Reserved for future use + BYTE LoopCount; // Number of loop repetitions; 255 = infinite + DWORD LoopBegin; // Loop begin point, in samples + DWORD LoopEnd; // Loop end point, in samples + DWORD SampleRate; // The file's decoded sample rate + DWORD EncodeOptions; // Options for the XMA encoder/decoder + DWORD PsuedoBytesPerSec; // Used internally by the XMA encoder + DWORD BlockSizeInBytes; // Size in bytes of this file's XMA blocks (except + // possibly the last one). Always a multiple of + // 2Kb, since XMA blocks are arrays of 2Kb packets. + DWORD SamplesEncoded; // Total number of PCM samples encoded in this file + DWORD SamplesInSource; // Actual number of PCM samples in the source + // material used to generate this file + DWORD BlockCount; // Number of XMA blocks in this file (and hence + // also the number of entries in its seek table) + XMA2STREAMFORMAT Streams[1]; // Per-stream format information; the actual + // array length is in the NumStreams field. +} XMA2WAVEFORMAT; + +#endif // #ifndef WAVE_FORMAT_XMA + + + +/*************************************************************************** + * XMA packet structure (in big-endian form) + ***************************************************************************/ + +typedef struct XMA2PACKET +{ + int FrameCount : 6; // Number of XMA frames that begin in this packet + int FrameOffsetInBits : 15; // Bit of XmaData where the first complete frame begins + int PacketMetaData : 3; // Metadata stored in the packet (always 1 for XMA2) + int PacketSkipCount : 8; // How many packets belonging to other streams must be + // skipped to find the next packet belonging to this one + BYTE XmaData[XMA_BYTES_PER_PACKET - sizeof(DWORD)]; // XMA encoded data +} XMA2PACKET; + +// E.g. if the first DWORD of a packet is 0x30107902: +// +// 001100 000001000001111 001 00000010 +// | | | |____ Skip 2 packets to find the next one for this stream +// | | |___________ XMA2 signature (always 001) +// | |_____________________ First frame starts 527 bits into packet +// |________________________________ Packet contains 12 frames + + +// Helper functions to extract the fields above from an XMA packet. (Note that +// the bitfields cannot be read directly on little-endian architectures such as +// the Intel x86, as they are laid out in big-endian form.) + +__inline DWORD GetXmaPacketFrameCount(__in_bcount(1) const BYTE* pPacket) +{ + return (DWORD)(pPacket[0] >> 2); +} + +__inline DWORD GetXmaPacketFirstFrameOffsetInBits(__in_bcount(3) const BYTE* pPacket) +{ + return ((DWORD)(pPacket[0] & 0x3) << 13) | + ((DWORD)(pPacket[1]) << 5) | + ((DWORD)(pPacket[2]) >> 3); +} + +__inline DWORD GetXmaPacketMetadata(__in_bcount(3) const BYTE* pPacket) +{ + return (DWORD)(pPacket[2] & 0x7); +} + +__inline DWORD GetXmaPacketSkipCount(__in_bcount(4) const BYTE* pPacket) +{ + return (DWORD)(pPacket[3]); +} + + + +/*************************************************************************** + * XMA frame structure + ***************************************************************************/ + +// There is no way to represent the XMA frame as a C struct, since it is a +// variable-sized string of bits that need not be stored at a byte-aligned +// position in memory. This is the layout: +// +// XMAFRAME +// { +// LengthInBits: A 15-bit number representing the length of this frame. +// XmaData: Encoded XMA data; its size in bits is (LengthInBits - 15). +// } + +// Size in bits of the frame's initial LengthInBits field +#define XMA_BITS_IN_FRAME_LENGTH_FIELD 15 + +// Special LengthInBits value that marks an invalid final frame +#define XMA_FINAL_FRAME_MARKER 0x7FFF + + + +/*************************************************************************** + * XMA helper functions + ***************************************************************************/ + +// We define a local ASSERT macro to equal the global one if it exists. +// You can define XMA2DEFS_ASSERT in advance to override this default. +#ifndef XMA2DEFS_ASSERT + #ifdef ASSERT + #define XMA2DEFS_ASSERT ASSERT + #else + #define XMA2DEFS_ASSERT(a) /* No-op by default */ + #endif +#endif + + +// GetXmaBlockContainingSample: Use a given seek table to find the XMA block +// containing a given decoded sample. Note that the seek table entries in an +// XMA file are stored in big-endian form and may need to be converted prior +// to calling this function. + +__inline HRESULT GetXmaBlockContainingSample +( + DWORD nBlockCount, // Blocks in the file (= seek table entries) + __in_ecount(nBlockCount) const DWORD* pSeekTable, // Pointer to the seek table data + DWORD nDesiredSample, // Decoded sample to locate + __out DWORD* pnBlockContainingSample, // Index of the block containing the sample + __out DWORD* pnSampleOffsetWithinBlock // Position of the sample in this block +) +{ + DWORD nPreviousTotalSamples = 0; + DWORD nBlock; + DWORD nTotalSamplesSoFar; + + XMA2DEFS_ASSERT(pSeekTable); + XMA2DEFS_ASSERT(pnBlockContainingSample); + XMA2DEFS_ASSERT(pnSampleOffsetWithinBlock); + + for (nBlock = 0; nBlock < nBlockCount; ++nBlock) + { + nTotalSamplesSoFar = pSeekTable[nBlock]; + if (nTotalSamplesSoFar > nDesiredSample) + { + *pnBlockContainingSample = nBlock; + *pnSampleOffsetWithinBlock = nDesiredSample - nPreviousTotalSamples; + return S_OK; + } + nPreviousTotalSamples = nTotalSamplesSoFar; + } + + return E_FAIL; +} + + +// GetXmaFrameLengthInBits: Reads a given frame's LengthInBits field. + +__inline DWORD GetXmaFrameLengthInBits +( + __in_bcount(nBitPosition / 8 + 3) + __in const BYTE* pPacket, // Pointer to XMA packet[s] containing the frame + DWORD nBitPosition // Bit offset of the frame within this packet +) +{ + DWORD nRegion; + DWORD nBytePosition = nBitPosition / 8; + DWORD nBitOffset = nBitPosition % 8; + + if (nBitOffset < 2) // Only need to read 2 bytes (and might not be safe to read more) + { + nRegion = (DWORD)(pPacket[nBytePosition+0]) << 8 | + (DWORD)(pPacket[nBytePosition+1]); + return (nRegion >> (1 - nBitOffset)) & 0x7FFF; // Last 15 bits + } + else // Need to read 3 bytes + { + nRegion = (DWORD)(pPacket[nBytePosition+0]) << 16 | + (DWORD)(pPacket[nBytePosition+1]) << 8 | + (DWORD)(pPacket[nBytePosition+2]); + return (nRegion >> (9 - nBitOffset)) & 0x7FFF; // Last 15 bits + } +} + + +// GetXmaFrameBitPosition: Calculates the bit offset of a given frame within +// an XMA block or set of blocks. Returns 0 on failure. + +__inline DWORD GetXmaFrameBitPosition +( + __in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s] + DWORD nXmaDataBytes, // Size of pXmaData in bytes + DWORD nStreamIndex, // Stream within which to seek + DWORD nDesiredFrame // Frame sought +) +{ + const BYTE* pCurrentPacket; + DWORD nPacketsExamined = 0; + DWORD nFrameCountSoFar = 0; + DWORD nFramesToSkip; + DWORD nFrameBitOffset; + + XMA2DEFS_ASSERT(pXmaData); + XMA2DEFS_ASSERT(nXmaDataBytes % XMA_BYTES_PER_PACKET == 0); + + // Get the first XMA packet belonging to the desired stream, relying on the + // fact that the first packets for each stream are in consecutive order at + // the beginning of an XMA block. + + pCurrentPacket = pXmaData + nStreamIndex * XMA_BYTES_PER_PACKET; + for (;;) + { + // If we have exceeded the size of the XMA data, return failure + if (pCurrentPacket + XMA_BYTES_PER_PACKET > pXmaData + nXmaDataBytes) + { + return 0; + } + + // If the current packet contains the frame we are looking for... + if (nFrameCountSoFar + GetXmaPacketFrameCount(pCurrentPacket) > nDesiredFrame) + { + // See how many frames in this packet we need to skip to get to it + XMA2DEFS_ASSERT(nDesiredFrame >= nFrameCountSoFar); + nFramesToSkip = nDesiredFrame - nFrameCountSoFar; + + // Get the bit offset of the first frame in this packet + nFrameBitOffset = XMA_PACKET_HEADER_BITS + GetXmaPacketFirstFrameOffsetInBits(pCurrentPacket); + + // Advance nFrameBitOffset to the frame of interest + while (nFramesToSkip--) + { + nFrameBitOffset += GetXmaFrameLengthInBits(pCurrentPacket, nFrameBitOffset); + } + + // The bit offset to return is the number of bits from pXmaData to + // pCurrentPacket plus the bit offset of the frame of interest + return (DWORD)(pCurrentPacket - pXmaData) * 8 + nFrameBitOffset; + } + + // If we haven't found the right packet yet, advance our counters + ++nPacketsExamined; + nFrameCountSoFar += GetXmaPacketFrameCount(pCurrentPacket); + + // And skip to the next packet belonging to the same stream + pCurrentPacket += XMA_BYTES_PER_PACKET * (GetXmaPacketSkipCount(pCurrentPacket) + 1); + } +} + + +// GetLastXmaFrameBitPosition: Calculates the bit offset of the last complete +// frame in an XMA block or set of blocks. + +__inline DWORD GetLastXmaFrameBitPosition +( + __in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s] + DWORD nXmaDataBytes, // Size of pXmaData in bytes + DWORD nStreamIndex // Stream within which to seek +) +{ + const BYTE* pLastPacket; + DWORD nBytesToNextPacket; + DWORD nFrameBitOffset; + DWORD nFramesInLastPacket; + + XMA2DEFS_ASSERT(pXmaData); + XMA2DEFS_ASSERT(nXmaDataBytes % XMA_BYTES_PER_PACKET == 0); + XMA2DEFS_ASSERT(nXmaDataBytes >= XMA_BYTES_PER_PACKET * (nStreamIndex + 1)); + + // Get the first XMA packet belonging to the desired stream, relying on the + // fact that the first packets for each stream are in consecutive order at + // the beginning of an XMA block. + pLastPacket = pXmaData + nStreamIndex * XMA_BYTES_PER_PACKET; + + // Search for the last packet belonging to the desired stream + for (;;) + { + nBytesToNextPacket = XMA_BYTES_PER_PACKET * (GetXmaPacketSkipCount(pLastPacket) + 1); + XMA2DEFS_ASSERT(nBytesToNextPacket); + if (pLastPacket + nBytesToNextPacket + XMA_BYTES_PER_PACKET > pXmaData + nXmaDataBytes) + { + break; // The next packet would extend beyond the end of pXmaData + } + pLastPacket += nBytesToNextPacket; + } + + // The last packet can sometimes have no seekable frames, in which case we + // have to use the previous one + if (GetXmaPacketFrameCount(pLastPacket) == 0) + { + pLastPacket -= nBytesToNextPacket; + } + + // Found the last packet. Get the bit offset of its first frame. + nFrameBitOffset = XMA_PACKET_HEADER_BITS + GetXmaPacketFirstFrameOffsetInBits(pLastPacket); + + // Traverse frames until we reach the last one + nFramesInLastPacket = GetXmaPacketFrameCount(pLastPacket); + while (--nFramesInLastPacket) + { + nFrameBitOffset += GetXmaFrameLengthInBits(pLastPacket, nFrameBitOffset); + } + + // The bit offset to return is the number of bits from pXmaData to + // pLastPacket plus the offset of the last frame in this packet. + return (DWORD)(pLastPacket - pXmaData) * 8 + nFrameBitOffset; +} + + +// GetXmaDecodePositionForSample: Obtains the information needed to make the +// decoder generate audio starting at a given sample position relative to the +// beginning of the given XMA block: the bit offset of the appropriate frame, +// and the right subframe within that frame. This data can be passed directly +// to the XMAPlaybackSetDecodePosition function. + +__inline HRESULT GetXmaDecodePositionForSample +( + __in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s] + DWORD nXmaDataBytes, // Size of pXmaData in bytes + DWORD nStreamIndex, // Stream within which to seek + DWORD nDesiredSample, // Sample sought + __out DWORD* pnBitOffset, // Returns the bit offset within pXmaData of + // the frame containing the sample sought + __out DWORD* pnSubFrame // Returns the subframe containing the sample +) +{ + DWORD nDesiredFrame = nDesiredSample / XMA_SAMPLES_PER_FRAME; + DWORD nSubFrame = (nDesiredSample % XMA_SAMPLES_PER_FRAME) / XMA_SAMPLES_PER_SUBFRAME; + DWORD nBitOffset = GetXmaFrameBitPosition(pXmaData, nXmaDataBytes, nStreamIndex, nDesiredFrame); + + XMA2DEFS_ASSERT(pnBitOffset); + XMA2DEFS_ASSERT(pnSubFrame); + + if (nBitOffset) + { + *pnBitOffset = nBitOffset; + *pnSubFrame = nSubFrame; + return S_OK; + } + else + { + return E_FAIL; + } +} + + +// GetXmaSampleRate: Obtains the legal XMA sample rate (24, 32, 44.1 or 48Khz) +// corresponding to a generic sample rate. + +__inline DWORD GetXmaSampleRate(DWORD dwGeneralRate) +{ + DWORD dwXmaRate = 48000; // Default XMA rate for all rates above 44100Hz + + if (dwGeneralRate <= 24000) dwXmaRate = 24000; + else if (dwGeneralRate <= 32000) dwXmaRate = 32000; + else if (dwGeneralRate <= 44100) dwXmaRate = 44100; + + return dwXmaRate; +} + + +// Functions to convert between WAVEFORMATEXTENSIBLE channel masks (combinations +// of the SPEAKER_xxx flags defined in audiodefs.h) and XMA channel masks (which +// are limited to eight possible speaker positions: left, right, center, low +// frequency, side left, side right, back left and back right). + +__inline DWORD GetStandardChannelMaskFromXmaMask(BYTE bXmaMask) +{ + DWORD dwStandardMask = 0; + + if (bXmaMask & XMA_SPEAKER_LEFT) dwStandardMask |= SPEAKER_FRONT_LEFT; + if (bXmaMask & XMA_SPEAKER_RIGHT) dwStandardMask |= SPEAKER_FRONT_RIGHT; + if (bXmaMask & XMA_SPEAKER_CENTER) dwStandardMask |= SPEAKER_FRONT_CENTER; + if (bXmaMask & XMA_SPEAKER_LFE) dwStandardMask |= SPEAKER_LOW_FREQUENCY; + if (bXmaMask & XMA_SPEAKER_LEFT_SURROUND) dwStandardMask |= SPEAKER_SIDE_LEFT; + if (bXmaMask & XMA_SPEAKER_RIGHT_SURROUND) dwStandardMask |= SPEAKER_SIDE_RIGHT; + if (bXmaMask & XMA_SPEAKER_LEFT_BACK) dwStandardMask |= SPEAKER_BACK_LEFT; + if (bXmaMask & XMA_SPEAKER_RIGHT_BACK) dwStandardMask |= SPEAKER_BACK_RIGHT; + + return dwStandardMask; +} + +__inline BYTE GetXmaChannelMaskFromStandardMask(DWORD dwStandardMask) +{ + BYTE bXmaMask = 0; + + if (dwStandardMask & SPEAKER_FRONT_LEFT) bXmaMask |= XMA_SPEAKER_LEFT; + if (dwStandardMask & SPEAKER_FRONT_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT; + if (dwStandardMask & SPEAKER_FRONT_CENTER) bXmaMask |= XMA_SPEAKER_CENTER; + if (dwStandardMask & SPEAKER_LOW_FREQUENCY) bXmaMask |= XMA_SPEAKER_LFE; + if (dwStandardMask & SPEAKER_SIDE_LEFT) bXmaMask |= XMA_SPEAKER_LEFT_SURROUND; + if (dwStandardMask & SPEAKER_SIDE_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT_SURROUND; + if (dwStandardMask & SPEAKER_BACK_LEFT) bXmaMask |= XMA_SPEAKER_LEFT_BACK; + if (dwStandardMask & SPEAKER_BACK_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT_BACK; + + return bXmaMask; +} + + +// LocalizeXma2Format: Modifies a XMA2WAVEFORMATEX structure in place to comply +// with the current platform's byte-ordering rules (little- or big-endian). + +__inline HRESULT LocalizeXma2Format(__inout XMA2WAVEFORMATEX* pXma2Format) +{ + #define XMASWAP2BYTES(n) ((WORD)(((n) >> 8) | (((n) & 0xff) << 8))) + #define XMASWAP4BYTES(n) ((DWORD)((n) >> 24 | (n) << 24 | ((n) & 0xff00) << 8 | ((n) & 0xff0000) >> 8)) + + if (pXma2Format->wfx.wFormatTag == WAVE_FORMAT_XMA2) + { + return S_OK; + } + else if (XMASWAP2BYTES(pXma2Format->wfx.wFormatTag) == WAVE_FORMAT_XMA2) + { + pXma2Format->wfx.wFormatTag = XMASWAP2BYTES(pXma2Format->wfx.wFormatTag); + pXma2Format->wfx.nChannels = XMASWAP2BYTES(pXma2Format->wfx.nChannels); + pXma2Format->wfx.nSamplesPerSec = XMASWAP4BYTES(pXma2Format->wfx.nSamplesPerSec); + pXma2Format->wfx.nAvgBytesPerSec = XMASWAP4BYTES(pXma2Format->wfx.nAvgBytesPerSec); + pXma2Format->wfx.nBlockAlign = XMASWAP2BYTES(pXma2Format->wfx.nBlockAlign); + pXma2Format->wfx.wBitsPerSample = XMASWAP2BYTES(pXma2Format->wfx.wBitsPerSample); + pXma2Format->wfx.cbSize = XMASWAP2BYTES(pXma2Format->wfx.cbSize); + pXma2Format->NumStreams = XMASWAP2BYTES(pXma2Format->NumStreams); + pXma2Format->ChannelMask = XMASWAP4BYTES(pXma2Format->ChannelMask); + pXma2Format->SamplesEncoded = XMASWAP4BYTES(pXma2Format->SamplesEncoded); + pXma2Format->BytesPerBlock = XMASWAP4BYTES(pXma2Format->BytesPerBlock); + pXma2Format->PlayBegin = XMASWAP4BYTES(pXma2Format->PlayBegin); + pXma2Format->PlayLength = XMASWAP4BYTES(pXma2Format->PlayLength); + pXma2Format->LoopBegin = XMASWAP4BYTES(pXma2Format->LoopBegin); + pXma2Format->LoopLength = XMASWAP4BYTES(pXma2Format->LoopLength); + pXma2Format->BlockCount = XMASWAP2BYTES(pXma2Format->BlockCount); + return S_OK; + } + else + { + return E_FAIL; // Not a recognizable XMA2 format + } + + #undef XMASWAP2BYTES + #undef XMASWAP4BYTES +} + + +#endif // #ifndef __XMA2DEFS_INCLUDED__ diff --git a/dxsdk/Include/xnamath.h b/dxsdk/Include/xnamath.h new file mode 100644 index 0000000..daaba0b --- /dev/null +++ b/dxsdk/Include/xnamath.h @@ -0,0 +1,2938 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + xnamath.h + +Abstract: + + XNA math library for Windows and Xbox 360 +--*/ + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __XNAMATH_H__ +#define __XNAMATH_H__ + +#ifdef __XBOXMATH_H__ +#error XNAMATH and XBOXMATH are incompatible in the same compilation module. Use one or the other. +#endif + +#define XNAMATH_VERSION 203 + +#if !defined(_XM_X64_) && !defined(_XM_X86_) +#if defined(_M_AMD64) || defined(_AMD64_) +#define _XM_X64_ +#elif defined(_M_IX86) || defined(_X86_) +#define _XM_X86_ +#endif +#endif + +#if !defined(_XM_BIGENDIAN_) && !defined(_XM_LITTLEENDIAN_) +#if defined(_XM_X64_) || defined(_XM_X86_) +#define _XM_LITTLEENDIAN_ +#elif defined(_XBOX_VER) +#define _XM_BIGENDIAN_ +#else +#error xnamath.h only supports x86, x64, or XBox 360 targets +#endif +#endif + +#if defined(_XM_X86_) || defined(_XM_X64_) +#define _XM_SSE_INTRINSICS_ +#if !defined(__cplusplus) && !defined(_XM_NO_INTRINSICS_) +#error xnamath.h only supports C compliation for Xbox 360 targets and no intrinsics cases for x86/x64 +#endif +#elif defined(_XBOX_VER) +#if !defined(__VMX128_SUPPORTED) && !defined(_XM_NO_INTRINSICS_) +#error xnamath.h requires VMX128 compiler support for XBOX 360 +#endif // !__VMX128_SUPPORTED && !_XM_NO_INTRINSICS_ +#define _XM_VMX128_INTRINSICS_ +#else +#error xnamath.h only supports x86, x64, or XBox 360 targets +#endif + + +#if defined(_XM_SSE_INTRINSICS_) +#ifndef _XM_NO_INTRINSICS_ +#include +#include +#endif +#elif defined(_XM_VMX128_INTRINSICS_) +#error This version of xnamath.h is for Windows use only +#endif + +#if defined(_XM_SSE_INTRINSICS_) +#pragma warning(push) +#pragma warning(disable:4985) +#endif +#include +#if defined(_XM_SSE_INTRINSICS_) +#pragma warning(pop) +#endif + +#include + +#if !defined(XMINLINE) +#if !defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#define XMINLINE __inline +#else +#define XMINLINE __forceinline +#endif +#endif + +#if !defined(XMFINLINE) +#define XMFINLINE __forceinline +#endif + +#if !defined(XMDEBUG) +#if defined(_DEBUG) +#define XMDEBUG +#endif +#endif // !XMDEBUG + +#if !defined(XMASSERT) +#if defined(_PREFAST_) +#define XMASSERT(Expression) __analysis_assume((Expression)) +#elif defined(XMDEBUG) // !_PREFAST_ +#define XMASSERT(Expression) ((VOID)((Expression) || (XMAssert(#Expression, __FILE__, __LINE__), 0))) +#else // !XMDEBUG +#define XMASSERT(Expression) ((VOID)0) +#endif // !XMDEBUG +#endif // !XMASSERT + +#if !defined(XM_NO_ALIGNMENT) +#define _DECLSPEC_ALIGN_16_ __declspec(align(16)) +#else +#define _DECLSPEC_ALIGN_16_ +#endif + + +#if defined(_MSC_VER) && (_MSC_VER<1500) && (_MSC_VER>=1400) +#define _XM_ISVS2005_ +#endif + +/**************************************************************************** + * + * Constant definitions + * + ****************************************************************************/ + +#define XM_PI 3.141592654f +#define XM_2PI 6.283185307f +#define XM_1DIVPI 0.318309886f +#define XM_1DIV2PI 0.159154943f +#define XM_PIDIV2 1.570796327f +#define XM_PIDIV4 0.785398163f + +#define XM_SELECT_0 0x00000000 +#define XM_SELECT_1 0xFFFFFFFF + +#define XM_PERMUTE_0X 0x00010203 +#define XM_PERMUTE_0Y 0x04050607 +#define XM_PERMUTE_0Z 0x08090A0B +#define XM_PERMUTE_0W 0x0C0D0E0F +#define XM_PERMUTE_1X 0x10111213 +#define XM_PERMUTE_1Y 0x14151617 +#define XM_PERMUTE_1Z 0x18191A1B +#define XM_PERMUTE_1W 0x1C1D1E1F + +#define XM_CRMASK_CR6 0x000000F0 +#define XM_CRMASK_CR6TRUE 0x00000080 +#define XM_CRMASK_CR6FALSE 0x00000020 +#define XM_CRMASK_CR6BOUNDS XM_CRMASK_CR6FALSE + +#define XM_CACHE_LINE_SIZE 64 + +/**************************************************************************** + * + * Macros + * + ****************************************************************************/ + +// Unit conversion + +XMFINLINE FLOAT XMConvertToRadians(FLOAT fDegrees) { return fDegrees * (XM_PI / 180.0f); } +XMFINLINE FLOAT XMConvertToDegrees(FLOAT fRadians) { return fRadians * (180.0f / XM_PI); } + +// Condition register evaluation proceeding a recording (Rc) comparison + +#define XMComparisonAllTrue(CR) (((CR) & XM_CRMASK_CR6TRUE) == XM_CRMASK_CR6TRUE) +#define XMComparisonAnyTrue(CR) (((CR) & XM_CRMASK_CR6FALSE) != XM_CRMASK_CR6FALSE) +#define XMComparisonAllFalse(CR) (((CR) & XM_CRMASK_CR6FALSE) == XM_CRMASK_CR6FALSE) +#define XMComparisonAnyFalse(CR) (((CR) & XM_CRMASK_CR6TRUE) != XM_CRMASK_CR6TRUE) +#define XMComparisonMixed(CR) (((CR) & XM_CRMASK_CR6) == 0) +#define XMComparisonAllInBounds(CR) (((CR) & XM_CRMASK_CR6BOUNDS) == XM_CRMASK_CR6BOUNDS) +#define XMComparisonAnyOutOfBounds(CR) (((CR) & XM_CRMASK_CR6BOUNDS) != XM_CRMASK_CR6BOUNDS) + + +#define XMMin(a, b) (((a) < (b)) ? (a) : (b)) +#define XMMax(a, b) (((a) > (b)) ? (a) : (b)) + +/**************************************************************************** + * + * Data types + * + ****************************************************************************/ + +#pragma warning(push) +#pragma warning(disable:4201 4365 4324) + +#if !defined (_XM_X86_) && !defined(_XM_X64_) +#pragma bitfield_order(push) +#pragma bitfield_order(lsb_to_msb) +#endif // !_XM_X86_ && !_XM_X64_ + +#if defined(_XM_NO_INTRINSICS_) && !defined(_XBOX_VER) +// The __vector4 structure is an intrinsic on Xbox but must be separately defined +// for x86/x64 +typedef struct __vector4 +{ + union + { + float vector4_f32[4]; + unsigned int vector4_u32[4]; +#ifndef XM_STRICT_VECTOR4 + struct + { + FLOAT x; + FLOAT y; + FLOAT z; + FLOAT w; + }; + FLOAT v[4]; + UINT u[4]; +#endif // !XM_STRICT_VECTOR4 + }; +} __vector4; +#endif // _XM_NO_INTRINSICS_ + +#if (defined (_XM_X86_) || defined(_XM_X64_)) && defined(_XM_NO_INTRINSICS_) +typedef UINT __vector4i[4]; +#else +typedef __declspec(align(16)) UINT __vector4i[4]; +#endif + +// Vector intrinsic: Four 32 bit floating point components aligned on a 16 byte +// boundary and mapped to hardware vector registers +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) +typedef __m128 XMVECTOR; +#else +typedef __vector4 XMVECTOR; +#endif + +// Conversion types for constants +typedef _DECLSPEC_ALIGN_16_ struct XMVECTORF32 { + union { + float f[4]; + XMVECTOR v; + }; + +#if defined(__cplusplus) + inline operator XMVECTOR() const { return v; } +#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_) + inline operator __m128i() const { return reinterpret_cast(&v)[0]; } + inline operator __m128d() const { return reinterpret_cast(&v)[0]; } +#endif +#endif // __cplusplus +} XMVECTORF32; + +typedef _DECLSPEC_ALIGN_16_ struct XMVECTORI32 { + union { + INT i[4]; + XMVECTOR v; + }; +#if defined(__cplusplus) + inline operator XMVECTOR() const { return v; } +#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_) + inline operator __m128i() const { return reinterpret_cast(&v)[0]; } + inline operator __m128d() const { return reinterpret_cast(&v)[0]; } +#endif +#endif // __cplusplus +} XMVECTORI32; + +typedef _DECLSPEC_ALIGN_16_ struct XMVECTORU8 { + union { + BYTE u[16]; + XMVECTOR v; + }; +#if defined(__cplusplus) + inline operator XMVECTOR() const { return v; } +#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_) + inline operator __m128i() const { return reinterpret_cast(&v)[0]; } + inline operator __m128d() const { return reinterpret_cast(&v)[0]; } +#endif +#endif // __cplusplus +} XMVECTORU8; + +typedef _DECLSPEC_ALIGN_16_ struct XMVECTORU32 { + union { + UINT u[4]; + XMVECTOR v; + }; +#if defined(__cplusplus) + inline operator XMVECTOR() const { return v; } +#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_) + inline operator __m128i() const { return reinterpret_cast(&v)[0]; } + inline operator __m128d() const { return reinterpret_cast(&v)[0]; } +#endif +#endif // __cplusplus +} XMVECTORU32; + +// Fix-up for (1st-3rd) XMVECTOR parameters that are pass-in-register for x86 and Xbox 360, but not for other targets +#if defined(_XM_VMX128_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) +typedef const XMVECTOR FXMVECTOR; +#elif defined(_XM_X86_) && !defined(_XM_NO_INTRINSICS_) +typedef const XMVECTOR FXMVECTOR; +#elif defined(__cplusplus) +typedef const XMVECTOR& FXMVECTOR; +#else +typedef const XMVECTOR FXMVECTOR; +#endif + +// Fix-up for (4th+) XMVECTOR parameters to pass in-register for Xbox 360 and by reference otherwise +#if defined(_XM_VMX128_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) +typedef const XMVECTOR CXMVECTOR; +#elif defined(__cplusplus) +typedef const XMVECTOR& CXMVECTOR; +#else +typedef const XMVECTOR CXMVECTOR; +#endif + +// Vector operators +#if defined(__cplusplus) && !defined(XM_NO_OPERATOR_OVERLOADS) + +XMVECTOR operator+ (FXMVECTOR V); +XMVECTOR operator- (FXMVECTOR V); + +XMVECTOR& operator+= (XMVECTOR& V1, FXMVECTOR V2); +XMVECTOR& operator-= (XMVECTOR& V1, FXMVECTOR V2); +XMVECTOR& operator*= (XMVECTOR& V1, FXMVECTOR V2); +XMVECTOR& operator/= (XMVECTOR& V1, FXMVECTOR V2); +XMVECTOR& operator*= (XMVECTOR& V, FLOAT S); +XMVECTOR& operator/= (XMVECTOR& V, FLOAT S); + +XMVECTOR operator+ (FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR operator- (FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR operator* (FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR operator/ (FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR operator* (FXMVECTOR V, FLOAT S); +XMVECTOR operator* (FLOAT S, FXMVECTOR V); +XMVECTOR operator/ (FXMVECTOR V, FLOAT S); + +#endif // __cplusplus && !XM_NO_OPERATOR_OVERLOADS + +// Matrix type: Sixteen 32 bit floating point components aligned on a +// 16 byte boundary and mapped to four hardware vector registers +#if (defined(_XM_X86_) || defined(_XM_X64_)) && defined(_XM_NO_INTRINSICS_) +typedef struct _XMMATRIX +#else +typedef _DECLSPEC_ALIGN_16_ struct _XMMATRIX +#endif +{ + union + { + XMVECTOR r[4]; + struct + { + FLOAT _11, _12, _13, _14; + FLOAT _21, _22, _23, _24; + FLOAT _31, _32, _33, _34; + FLOAT _41, _42, _43, _44; + }; + FLOAT m[4][4]; + }; + +#ifdef __cplusplus + + _XMMATRIX() {}; + _XMMATRIX(FXMVECTOR R0, FXMVECTOR R1, FXMVECTOR R2, CXMVECTOR R3); + _XMMATRIX(FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03, + FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13, + FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23, + FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33); + _XMMATRIX(CONST FLOAT *pArray); + + FLOAT operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; } + FLOAT& operator() (UINT Row, UINT Column) { return m[Row][Column]; } + + _XMMATRIX& operator= (CONST _XMMATRIX& M); + +#ifndef XM_NO_OPERATOR_OVERLOADS + _XMMATRIX& operator*= (CONST _XMMATRIX& M); + _XMMATRIX operator* (CONST _XMMATRIX& M) CONST; +#endif // !XM_NO_OPERATOR_OVERLOADS + +#endif // __cplusplus + +} XMMATRIX; + +// Fix-up for XMMATRIX parameters to pass in-register on Xbox 360, by reference otherwise +#if defined(_XM_VMX128_INTRINSICS_) +typedef const XMMATRIX CXMMATRIX; +#elif defined(__cplusplus) +typedef const XMMATRIX& CXMMATRIX; +#else +typedef const XMMATRIX CXMMATRIX; +#endif + +// 16 bit floating point number consisting of a sign bit, a 5 bit biased +// exponent, and a 10 bit mantissa +//typedef WORD HALF; +typedef USHORT HALF; + +// 2D Vector; 32 bit floating point components +typedef struct _XMFLOAT2 +{ + FLOAT x; + FLOAT y; + +#ifdef __cplusplus + + _XMFLOAT2() {}; + _XMFLOAT2(FLOAT _x, FLOAT _y) : x(_x), y(_y) {}; + _XMFLOAT2(CONST FLOAT *pArray); + + _XMFLOAT2& operator= (CONST _XMFLOAT2& Float2); + +#endif // __cplusplus + +} XMFLOAT2; + +// 2D Vector; 32 bit floating point components aligned on a 16 byte boundary +#ifdef __cplusplus +__declspec(align(16)) struct XMFLOAT2A : public XMFLOAT2 +{ + XMFLOAT2A() : XMFLOAT2() {}; + XMFLOAT2A(FLOAT _x, FLOAT _y) : XMFLOAT2(_x, _y) {}; + XMFLOAT2A(CONST FLOAT *pArray) : XMFLOAT2(pArray) {}; + + XMFLOAT2A& operator= (CONST XMFLOAT2A& Float2); +}; +#else +typedef __declspec(align(16)) XMFLOAT2 XMFLOAT2A; +#endif // __cplusplus + +// 2D Vector; 16 bit floating point components +typedef struct _XMHALF2 +{ + HALF x; + HALF y; + +#ifdef __cplusplus + + _XMHALF2() {}; + _XMHALF2(HALF _x, HALF _y) : x(_x), y(_y) {}; + _XMHALF2(CONST HALF *pArray); + _XMHALF2(FLOAT _x, FLOAT _y); + _XMHALF2(CONST FLOAT *pArray); + + _XMHALF2& operator= (CONST _XMHALF2& Half2); + +#endif // __cplusplus + +} XMHALF2; + +// 2D Vector; 16 bit signed normalized integer components +typedef struct _XMSHORTN2 +{ + SHORT x; + SHORT y; + +#ifdef __cplusplus + + _XMSHORTN2() {}; + _XMSHORTN2(SHORT _x, SHORT _y) : x(_x), y(_y) {}; + _XMSHORTN2(CONST SHORT *pArray); + _XMSHORTN2(FLOAT _x, FLOAT _y); + _XMSHORTN2(CONST FLOAT *pArray); + + _XMSHORTN2& operator= (CONST _XMSHORTN2& ShortN2); + +#endif // __cplusplus + +} XMSHORTN2; + +// 2D Vector; 16 bit signed integer components +typedef struct _XMSHORT2 +{ + SHORT x; + SHORT y; + +#ifdef __cplusplus + + _XMSHORT2() {}; + _XMSHORT2(SHORT _x, SHORT _y) : x(_x), y(_y) {}; + _XMSHORT2(CONST SHORT *pArray); + _XMSHORT2(FLOAT _x, FLOAT _y); + _XMSHORT2(CONST FLOAT *pArray); + + _XMSHORT2& operator= (CONST _XMSHORT2& Short2); + +#endif // __cplusplus + +} XMSHORT2; + +// 2D Vector; 16 bit unsigned normalized integer components +typedef struct _XMUSHORTN2 +{ + USHORT x; + USHORT y; + +#ifdef __cplusplus + + _XMUSHORTN2() {}; + _XMUSHORTN2(USHORT _x, USHORT _y) : x(_x), y(_y) {}; + _XMUSHORTN2(CONST USHORT *pArray); + _XMUSHORTN2(FLOAT _x, FLOAT _y); + _XMUSHORTN2(CONST FLOAT *pArray); + + _XMUSHORTN2& operator= (CONST _XMUSHORTN2& UShortN2); + +#endif // __cplusplus + +} XMUSHORTN2; + +// 2D Vector; 16 bit unsigned integer components +typedef struct _XMUSHORT2 +{ + USHORT x; + USHORT y; + +#ifdef __cplusplus + + _XMUSHORT2() {}; + _XMUSHORT2(USHORT _x, USHORT _y) : x(_x), y(_y) {}; + _XMUSHORT2(CONST USHORT *pArray); + _XMUSHORT2(FLOAT _x, FLOAT _y); + _XMUSHORT2(CONST FLOAT *pArray); + + _XMUSHORT2& operator= (CONST _XMUSHORT2& UShort2); + +#endif // __cplusplus + +} XMUSHORT2; + +// 3D Vector; 32 bit floating point components +typedef struct _XMFLOAT3 +{ + FLOAT x; + FLOAT y; + FLOAT z; + +#ifdef __cplusplus + + _XMFLOAT3() {}; + _XMFLOAT3(FLOAT _x, FLOAT _y, FLOAT _z) : x(_x), y(_y), z(_z) {}; + _XMFLOAT3(CONST FLOAT *pArray); + + _XMFLOAT3& operator= (CONST _XMFLOAT3& Float3); + +#endif // __cplusplus + +} XMFLOAT3; + +// 3D Vector; 32 bit floating point components aligned on a 16 byte boundary +#ifdef __cplusplus +__declspec(align(16)) struct XMFLOAT3A : public XMFLOAT3 +{ + XMFLOAT3A() : XMFLOAT3() {}; + XMFLOAT3A(FLOAT _x, FLOAT _y, FLOAT _z) : XMFLOAT3(_x, _y, _z) {}; + XMFLOAT3A(CONST FLOAT *pArray) : XMFLOAT3(pArray) {}; + + XMFLOAT3A& operator= (CONST XMFLOAT3A& Float3); +}; +#else +typedef __declspec(align(16)) XMFLOAT3 XMFLOAT3A; +#endif // __cplusplus + +// 3D Vector; 11-11-10 bit normalized components packed into a 32 bit integer +// The normalized 3D Vector is packed into 32 bits as follows: a 10 bit signed, +// normalized integer for the z component and 11 bit signed, normalized +// integers for the x and y components. The z component is stored in the +// most significant bits and the x component in the least significant bits +// (Z10Y11X11): [32] zzzzzzzz zzyyyyyy yyyyyxxx xxxxxxxx [0] +typedef struct _XMHENDN3 +{ + union + { + struct + { + INT x : 11; // -1023/1023 to 1023/1023 + INT y : 11; // -1023/1023 to 1023/1023 + INT z : 10; // -511/511 to 511/511 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMHENDN3() {}; + _XMHENDN3(UINT Packed) : v(Packed) {}; + _XMHENDN3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMHENDN3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMHENDN3& operator= (CONST _XMHENDN3& HenDN3); + _XMHENDN3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMHENDN3; + +// 3D Vector; 11-11-10 bit components packed into a 32 bit integer +// The 3D Vector is packed into 32 bits as follows: a 10 bit signed, +// integer for the z component and 11 bit signed integers for the +// x and y components. The z component is stored in the +// most significant bits and the x component in the least significant bits +// (Z10Y11X11): [32] zzzzzzzz zzyyyyyy yyyyyxxx xxxxxxxx [0] +typedef struct _XMHEND3 +{ + union + { + struct + { + INT x : 11; // -1023 to 1023 + INT y : 11; // -1023 to 1023 + INT z : 10; // -511 to 511 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMHEND3() {}; + _XMHEND3(UINT Packed) : v(Packed) {}; + _XMHEND3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMHEND3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMHEND3& operator= (CONST _XMHEND3& HenD3); + _XMHEND3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMHEND3; + +// 3D Vector; 11-11-10 bit normalized components packed into a 32 bit integer +// The normalized 3D Vector is packed into 32 bits as follows: a 10 bit unsigned, +// normalized integer for the z component and 11 bit unsigned, normalized +// integers for the x and y components. The z component is stored in the +// most significant bits and the x component in the least significant bits +// (Z10Y11X11): [32] zzzzzzzz zzyyyyyy yyyyyxxx xxxxxxxx [0] +typedef struct _XMUHENDN3 +{ + union + { + struct + { + UINT x : 11; // 0/2047 to 2047/2047 + UINT y : 11; // 0/2047 to 2047/2047 + UINT z : 10; // 0/1023 to 1023/1023 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUHENDN3() {}; + _XMUHENDN3(UINT Packed) : v(Packed) {}; + _XMUHENDN3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMUHENDN3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMUHENDN3& operator= (CONST _XMUHENDN3& UHenDN3); + _XMUHENDN3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMUHENDN3; + +// 3D Vector; 11-11-10 bit components packed into a 32 bit integer +// The 3D Vector is packed into 32 bits as follows: a 10 bit unsigned +// integer for the z component and 11 bit unsigned integers +// for the x and y components. The z component is stored in the +// most significant bits and the x component in the least significant bits +// (Z10Y11X11): [32] zzzzzzzz zzyyyyyy yyyyyxxx xxxxxxxx [0] +typedef struct _XMUHEND3 +{ + union + { + struct + { + UINT x : 11; // 0 to 2047 + UINT y : 11; // 0 to 2047 + UINT z : 10; // 0 to 1023 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUHEND3() {}; + _XMUHEND3(UINT Packed) : v(Packed) {}; + _XMUHEND3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMUHEND3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMUHEND3& operator= (CONST _XMUHEND3& UHenD3); + _XMUHEND3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMUHEND3; + +// 3D Vector; 10-11-11 bit normalized components packed into a 32 bit integer +// The normalized 3D Vector is packed into 32 bits as follows: a 10 bit signed, +// normalized integer for the x component and 11 bit signed, normalized +// integers for the y and z components. The z component is stored in the +// most significant bits and the x component in the least significant bits +// (Z11Y11X10): [32] zzzzzzzz zzzyyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMDHENN3 +{ + union + { + struct + { + INT x : 10; // -511/511 to 511/511 + INT y : 11; // -1023/1023 to 1023/1023 + INT z : 11; // -1023/1023 to 1023/1023 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMDHENN3() {}; + _XMDHENN3(UINT Packed) : v(Packed) {}; + _XMDHENN3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMDHENN3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMDHENN3& operator= (CONST _XMDHENN3& DHenN3); + _XMDHENN3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMDHENN3; + +// 3D Vector; 10-11-11 bit components packed into a 32 bit integer +// The 3D Vector is packed into 32 bits as follows: a 10 bit signed, +// integer for the x component and 11 bit signed integers for the +// y and z components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (Z11Y11X10): [32] zzzzzzzz zzzyyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMDHEN3 +{ + union + { + struct + { + INT x : 10; // -511 to 511 + INT y : 11; // -1023 to 1023 + INT z : 11; // -1023 to 1023 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMDHEN3() {}; + _XMDHEN3(UINT Packed) : v(Packed) {}; + _XMDHEN3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMDHEN3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMDHEN3& operator= (CONST _XMDHEN3& DHen3); + _XMDHEN3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMDHEN3; + +// 3D Vector; 10-11-11 bit normalized components packed into a 32 bit integer +// The normalized 3D Vector is packed into 32 bits as follows: a 10 bit unsigned, +// normalized integer for the x component and 11 bit unsigned, normalized +// integers for the y and z components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (Z11Y11X10): [32] zzzzzzzz zzzyyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMUDHENN3 +{ + union + { + struct + { + UINT x : 10; // 0/1023 to 1023/1023 + UINT y : 11; // 0/2047 to 2047/2047 + UINT z : 11; // 0/2047 to 2047/2047 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUDHENN3() {}; + _XMUDHENN3(UINT Packed) : v(Packed) {}; + _XMUDHENN3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMUDHENN3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMUDHENN3& operator= (CONST _XMUDHENN3& UDHenN3); + _XMUDHENN3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMUDHENN3; + +// 3D Vector; 10-11-11 bit components packed into a 32 bit integer +// The 3D Vector is packed into 32 bits as follows: a 10 bit unsigned, +// integer for the x component and 11 bit unsigned integers +// for the y and z components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (Z11Y11X10): [32] zzzzzzzz zzzyyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMUDHEN3 +{ + union + { + struct + { + UINT x : 10; // 0 to 1023 + UINT y : 11; // 0 to 2047 + UINT z : 11; // 0 to 2047 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUDHEN3() {}; + _XMUDHEN3(UINT Packed) : v(Packed) {}; + _XMUDHEN3(FLOAT _x, FLOAT _y, FLOAT _z); + _XMUDHEN3(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMUDHEN3& operator= (CONST _XMUDHEN3& UDHen3); + _XMUDHEN3& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMUDHEN3; + +// 3D vector: 5/6/5 unsigned integer components +typedef struct _XMU565 +{ + union + { + struct + { + USHORT x : 5; + USHORT y : 6; + USHORT z : 5; + }; + USHORT v; + }; + +#ifdef __cplusplus + + _XMU565() {}; + _XMU565(USHORT Packed) : v(Packed) {}; + _XMU565(CHAR _x, CHAR _y, CHAR _z) : x(_x), y(_y), z(_z) {}; + _XMU565(CONST CHAR *pArray); + _XMU565(FLOAT _x, FLOAT _y, FLOAT _z); + _XMU565(CONST FLOAT *pArray); + + operator USHORT () { return v; } + + _XMU565& operator= (CONST _XMU565& U565); + _XMU565& operator= (CONST USHORT Packed); + +#endif // __cplusplus + +} XMU565; + +// 3D vector: 11/11/10 floating-point components +// The 3D vector is packed into 32 bits as follows: a 5-bit biased exponent +// and 6-bit mantissa for x component, a 5-bit biased exponent and +// 6-bit mantissa for y component, a 5-bit biased exponent and a 5-bit +// mantissa for z. The z component is stored in the most significant bits +// and the x component in the least significant bits. No sign bits so +// all partial-precision numbers are positive. +// (Z10Y11X11): [32] ZZZZZzzz zzzYYYYY yyyyyyXX XXXxxxxx [0] +typedef struct _XMFLOAT3PK +{ + union + { + struct + { + UINT xm : 6; + UINT xe : 5; + UINT ym : 6; + UINT ye : 5; + UINT zm : 5; + UINT ze : 5; + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMFLOAT3PK() {}; + _XMFLOAT3PK(UINT Packed) : v(Packed) {}; + _XMFLOAT3PK(FLOAT _x, FLOAT _y, FLOAT _z); + _XMFLOAT3PK(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMFLOAT3PK& operator= (CONST _XMFLOAT3PK& float3pk); + _XMFLOAT3PK& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMFLOAT3PK; + +// 3D vector: 9/9/9 floating-point components with shared 5-bit exponent +// The 3D vector is packed into 32 bits as follows: a 5-bit biased exponent +// with 9-bit mantissa for the x, y, and z component. The shared exponent +// is stored in the most significant bits and the x component mantissa is in +// the least significant bits. No sign bits so all partial-precision numbers +// are positive. +// (E5Z9Y9X9): [32] EEEEEzzz zzzzzzyy yyyyyyyx xxxxxxxx [0] +typedef struct _XMFLOAT3SE +{ + union + { + struct + { + UINT xm : 9; + UINT ym : 9; + UINT zm : 9; + UINT e : 5; + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMFLOAT3SE() {}; + _XMFLOAT3SE(UINT Packed) : v(Packed) {}; + _XMFLOAT3SE(FLOAT _x, FLOAT _y, FLOAT _z); + _XMFLOAT3SE(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMFLOAT3SE& operator= (CONST _XMFLOAT3SE& float3se); + _XMFLOAT3SE& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMFLOAT3SE; + +// 4D Vector; 32 bit floating point components +typedef struct _XMFLOAT4 +{ + FLOAT x; + FLOAT y; + FLOAT z; + FLOAT w; + +#ifdef __cplusplus + + _XMFLOAT4() {}; + _XMFLOAT4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMFLOAT4(CONST FLOAT *pArray); + + _XMFLOAT4& operator= (CONST _XMFLOAT4& Float4); + +#endif // __cplusplus + +} XMFLOAT4; + +// 4D Vector; 32 bit floating point components aligned on a 16 byte boundary +#ifdef __cplusplus +__declspec(align(16)) struct XMFLOAT4A : public XMFLOAT4 +{ + XMFLOAT4A() : XMFLOAT4() {}; + XMFLOAT4A(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w) : XMFLOAT4(_x, _y, _z, _w) {}; + XMFLOAT4A(CONST FLOAT *pArray) : XMFLOAT4(pArray) {}; + + XMFLOAT4A& operator= (CONST XMFLOAT4A& Float4); +}; +#else +typedef __declspec(align(16)) XMFLOAT4 XMFLOAT4A; +#endif // __cplusplus + +// 4D Vector; 16 bit floating point components +typedef struct _XMHALF4 +{ + HALF x; + HALF y; + HALF z; + HALF w; + +#ifdef __cplusplus + + _XMHALF4() {}; + _XMHALF4(HALF _x, HALF _y, HALF _z, HALF _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMHALF4(CONST HALF *pArray); + _XMHALF4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMHALF4(CONST FLOAT *pArray); + + _XMHALF4& operator= (CONST _XMHALF4& Half4); + +#endif // __cplusplus + +} XMHALF4; + +// 4D Vector; 16 bit signed normalized integer components +typedef struct _XMSHORTN4 +{ + SHORT x; + SHORT y; + SHORT z; + SHORT w; + +#ifdef __cplusplus + + _XMSHORTN4() {}; + _XMSHORTN4(SHORT _x, SHORT _y, SHORT _z, SHORT _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMSHORTN4(CONST SHORT *pArray); + _XMSHORTN4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMSHORTN4(CONST FLOAT *pArray); + + _XMSHORTN4& operator= (CONST _XMSHORTN4& ShortN4); + +#endif // __cplusplus + +} XMSHORTN4; + +// 4D Vector; 16 bit signed integer components +typedef struct _XMSHORT4 +{ + SHORT x; + SHORT y; + SHORT z; + SHORT w; + +#ifdef __cplusplus + + _XMSHORT4() {}; + _XMSHORT4(SHORT _x, SHORT _y, SHORT _z, SHORT _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMSHORT4(CONST SHORT *pArray); + _XMSHORT4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMSHORT4(CONST FLOAT *pArray); + + _XMSHORT4& operator= (CONST _XMSHORT4& Short4); + +#endif // __cplusplus + +} XMSHORT4; + +// 4D Vector; 16 bit unsigned normalized integer components +typedef struct _XMUSHORTN4 +{ + USHORT x; + USHORT y; + USHORT z; + USHORT w; + +#ifdef __cplusplus + + _XMUSHORTN4() {}; + _XMUSHORTN4(USHORT _x, USHORT _y, USHORT _z, USHORT _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMUSHORTN4(CONST USHORT *pArray); + _XMUSHORTN4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUSHORTN4(CONST FLOAT *pArray); + + _XMUSHORTN4& operator= (CONST _XMUSHORTN4& UShortN4); + +#endif // __cplusplus + +} XMUSHORTN4; + +// 4D Vector; 16 bit unsigned integer components +typedef struct _XMUSHORT4 +{ + USHORT x; + USHORT y; + USHORT z; + USHORT w; + +#ifdef __cplusplus + + _XMUSHORT4() {}; + _XMUSHORT4(USHORT _x, USHORT _y, USHORT _z, USHORT _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMUSHORT4(CONST USHORT *pArray); + _XMUSHORT4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUSHORT4(CONST FLOAT *pArray); + + _XMUSHORT4& operator= (CONST _XMUSHORT4& UShort4); + +#endif // __cplusplus + +} XMUSHORT4; + +// 4D Vector; 10-10-10-2 bit normalized components packed into a 32 bit integer +// The normalized 4D Vector is packed into 32 bits as follows: a 2 bit unsigned, +// normalized integer for the w component and 10 bit signed, normalized +// integers for the z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W2Z10Y10X10): [32] wwzzzzzz zzzzyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMXDECN4 +{ + union + { + struct + { + INT x : 10; // -511/511 to 511/511 + INT y : 10; // -511/511 to 511/511 + INT z : 10; // -511/511 to 511/511 + UINT w : 2; // 0/3 to 3/3 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMXDECN4() {}; + _XMXDECN4(UINT Packed) : v(Packed) {}; + _XMXDECN4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMXDECN4(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMXDECN4& operator= (CONST _XMXDECN4& XDecN4); + _XMXDECN4& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMXDECN4; + +// 4D Vector; 10-10-10-2 bit components packed into a 32 bit integer +// The normalized 4D Vector is packed into 32 bits as follows: a 2 bit unsigned +// integer for the w component and 10 bit signed integers for the +// z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W2Z10Y10X10): [32] wwzzzzzz zzzzyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMXDEC4 +{ + union + { + struct + { + INT x : 10; // -511 to 511 + INT y : 10; // -511 to 511 + INT z : 10; // -511 to 511 + UINT w : 2; // 0 to 3 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMXDEC4() {}; + _XMXDEC4(UINT Packed) : v(Packed) {}; + _XMXDEC4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMXDEC4(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMXDEC4& operator= (CONST _XMXDEC4& XDec4); + _XMXDEC4& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMXDEC4; + +// 4D Vector; 10-10-10-2 bit normalized components packed into a 32 bit integer +// The normalized 4D Vector is packed into 32 bits as follows: a 2 bit signed, +// normalized integer for the w component and 10 bit signed, normalized +// integers for the z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W2Z10Y10X10): [32] wwzzzzzz zzzzyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMDECN4 +{ + union + { + struct + { + INT x : 10; // -511/511 to 511/511 + INT y : 10; // -511/511 to 511/511 + INT z : 10; // -511/511 to 511/511 + INT w : 2; // -1/1 to 1/1 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMDECN4() {}; + _XMDECN4(UINT Packed) : v(Packed) {}; + _XMDECN4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMDECN4(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMDECN4& operator= (CONST _XMDECN4& DecN4); + _XMDECN4& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMDECN4; + +// 4D Vector; 10-10-10-2 bit components packed into a 32 bit integer +// The 4D Vector is packed into 32 bits as follows: a 2 bit signed, +// integer for the w component and 10 bit signed integers for the +// z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W2Z10Y10X10): [32] wwzzzzzz zzzzyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMDEC4 +{ + union + { + struct + { + INT x : 10; // -511 to 511 + INT y : 10; // -511 to 511 + INT z : 10; // -511 to 511 + INT w : 2; // -1 to 1 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMDEC4() {}; + _XMDEC4(UINT Packed) : v(Packed) {}; + _XMDEC4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMDEC4(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMDEC4& operator= (CONST _XMDEC4& Dec4); + _XMDEC4& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMDEC4; + +// 4D Vector; 10-10-10-2 bit normalized components packed into a 32 bit integer +// The normalized 4D Vector is packed into 32 bits as follows: a 2 bit unsigned, +// normalized integer for the w component and 10 bit unsigned, normalized +// integers for the z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W2Z10Y10X10): [32] wwzzzzzz zzzzyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMUDECN4 +{ + union + { + struct + { + UINT x : 10; // 0/1023 to 1023/1023 + UINT y : 10; // 0/1023 to 1023/1023 + UINT z : 10; // 0/1023 to 1023/1023 + UINT w : 2; // 0/3 to 3/3 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUDECN4() {}; + _XMUDECN4(UINT Packed) : v(Packed) {}; + _XMUDECN4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUDECN4(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMUDECN4& operator= (CONST _XMUDECN4& UDecN4); + _XMUDECN4& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMUDECN4; + +// 4D Vector; 10-10-10-2 bit components packed into a 32 bit integer +// The 4D Vector is packed into 32 bits as follows: a 2 bit unsigned, +// integer for the w component and 10 bit unsigned integers +// for the z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W2Z10Y10X10): [32] wwzzzzzz zzzzyyyy yyyyyyxx xxxxxxxx [0] +typedef struct _XMUDEC4 +{ + union + { + struct + { + UINT x : 10; // 0 to 1023 + UINT y : 10; // 0 to 1023 + UINT z : 10; // 0 to 1023 + UINT w : 2; // 0 to 3 + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUDEC4() {}; + _XMUDEC4(UINT Packed) : v(Packed) {}; + _XMUDEC4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUDEC4(CONST FLOAT *pArray); + + operator UINT () { return v; } + + _XMUDEC4& operator= (CONST _XMUDEC4& UDec4); + _XMUDEC4& operator= (CONST UINT Packed); + +#endif // __cplusplus + +} XMUDEC4; + +// 4D Vector; 20-20-20-4 bit normalized components packed into a 64 bit integer +// The normalized 4D Vector is packed into 64 bits as follows: a 4 bit unsigned, +// normalized integer for the w component and 20 bit signed, normalized +// integers for the z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W4Z20Y20X20): [64] wwwwzzzz zzzzzzzz zzzzzzzz yyyyyyyy yyyyyyyy yyyyxxxx xxxxxxxx xxxxxxxx [0] +typedef struct _XMXICON4 +{ + union + { + struct + { + INT64 x : 20; // -524287/524287 to 524287/524287 + INT64 y : 20; // -524287/524287 to 524287/524287 + INT64 z : 20; // -524287/524287 to 524287/524287 + UINT64 w : 4; // 0/15 to 15/15 + }; + UINT64 v; + }; + +#ifdef __cplusplus + + _XMXICON4() {}; + _XMXICON4(UINT64 Packed) : v(Packed) {}; + _XMXICON4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMXICON4(CONST FLOAT *pArray); + + operator UINT64 () { return v; } + + _XMXICON4& operator= (CONST _XMXICON4& XIcoN4); + _XMXICON4& operator= (CONST UINT64 Packed); + +#endif // __cplusplus + +} XMXICON4; + +// 4D Vector; 20-20-20-4 bit components packed into a 64 bit integer +// The 4D Vector is packed into 64 bits as follows: a 4 bit unsigned +// integer for the w component and 20 bit signed integers for the +// z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W4Z20Y20X20): [64] wwwwzzzz zzzzzzzz zzzzzzzz yyyyyyyy yyyyyyyy yyyyxxxx xxxxxxxx xxxxxxxx [0] +typedef struct _XMXICO4 +{ + union + { + struct + { + INT64 x : 20; // -524287 to 524287 + INT64 y : 20; // -524287 to 524287 + INT64 z : 20; // -524287 to 524287 + UINT64 w : 4; // 0 to 15 + }; + UINT64 v; + }; + +#ifdef __cplusplus + + _XMXICO4() {}; + _XMXICO4(UINT64 Packed) : v(Packed) {}; + _XMXICO4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMXICO4(CONST FLOAT *pArray); + + operator UINT64 () { return v; } + + _XMXICO4& operator= (CONST _XMXICO4& XIco4); + _XMXICO4& operator= (CONST UINT64 Packed); + +#endif // __cplusplus + +} XMXICO4; + +// 4D Vector; 20-20-20-4 bit normalized components packed into a 64 bit integer +// The normalized 4D Vector is packed into 64 bits as follows: a 4 bit signed, +// normalized integer for the w component and 20 bit signed, normalized +// integers for the z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W4Z20Y20X20): [64] wwwwzzzz zzzzzzzz zzzzzzzz yyyyyyyy yyyyyyyy yyyyxxxx xxxxxxxx xxxxxxxx [0] +typedef struct _XMICON4 +{ + union + { + struct + { + INT64 x : 20; // -524287/524287 to 524287/524287 + INT64 y : 20; // -524287/524287 to 524287/524287 + INT64 z : 20; // -524287/524287 to 524287/524287 + INT64 w : 4; // -7/7 to 7/7 + }; + UINT64 v; + }; + +#ifdef __cplusplus + + _XMICON4() {}; + _XMICON4(UINT64 Packed) : v(Packed) {}; + _XMICON4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMICON4(CONST FLOAT *pArray); + + operator UINT64 () { return v; } + + _XMICON4& operator= (CONST _XMICON4& IcoN4); + _XMICON4& operator= (CONST UINT64 Packed); + +#endif // __cplusplus + +} XMICON4; + +// 4D Vector; 20-20-20-4 bit components packed into a 64 bit integer +// The 4D Vector is packed into 64 bits as follows: a 4 bit signed, +// integer for the w component and 20 bit signed integers for the +// z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W4Z20Y20X20): [64] wwwwzzzz zzzzzzzz zzzzzzzz yyyyyyyy yyyyyyyy yyyyxxxx xxxxxxxx xxxxxxxx [0] +typedef struct _XMICO4 +{ + union + { + struct + { + INT64 x : 20; // -524287 to 524287 + INT64 y : 20; // -524287 to 524287 + INT64 z : 20; // -524287 to 524287 + INT64 w : 4; // -7 to 7 + }; + UINT64 v; + }; + +#ifdef __cplusplus + + _XMICO4() {}; + _XMICO4(UINT64 Packed) : v(Packed) {}; + _XMICO4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMICO4(CONST FLOAT *pArray); + + operator UINT64 () { return v; } + + _XMICO4& operator= (CONST _XMICO4& Ico4); + _XMICO4& operator= (CONST UINT64 Packed); + +#endif // __cplusplus + +} XMICO4; + +// 4D Vector; 20-20-20-4 bit normalized components packed into a 64 bit integer +// The normalized 4D Vector is packed into 64 bits as follows: a 4 bit unsigned, +// normalized integer for the w component and 20 bit unsigned, normalized +// integers for the z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W4Z20Y20X20): [64] wwwwzzzz zzzzzzzz zzzzzzzz yyyyyyyy yyyyyyyy yyyyxxxx xxxxxxxx xxxxxxxx [0] +typedef struct _XMUICON4 +{ + union + { + struct + { + UINT64 x : 20; // 0/1048575 to 1048575/1048575 + UINT64 y : 20; // 0/1048575 to 1048575/1048575 + UINT64 z : 20; // 0/1048575 to 1048575/1048575 + UINT64 w : 4; // 0/15 to 15/15 + }; + UINT64 v; + }; + +#ifdef __cplusplus + + _XMUICON4() {}; + _XMUICON4(UINT64 Packed) : v(Packed) {}; + _XMUICON4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUICON4(CONST FLOAT *pArray); + + operator UINT64 () { return v; } + + _XMUICON4& operator= (CONST _XMUICON4& UIcoN4); + _XMUICON4& operator= (CONST UINT64 Packed); + +#endif // __cplusplus + +} XMUICON4; + +// 4D Vector; 20-20-20-4 bit components packed into a 64 bit integer +// The 4D Vector is packed into 64 bits as follows: a 4 bit unsigned +// integer for the w component and 20 bit unsigned integers for the +// z, y, and x components. The w component is stored in the +// most significant bits and the x component in the least significant bits +// (W4Z20Y20X20): [64] wwwwzzzz zzzzzzzz zzzzzzzz yyyyyyyy yyyyyyyy yyyyxxxx xxxxxxxx xxxxxxxx [0] +typedef struct _XMUICO4 +{ + union + { + struct + { + UINT64 x : 20; // 0 to 1048575 + UINT64 y : 20; // 0 to 1048575 + UINT64 z : 20; // 0 to 1048575 + UINT64 w : 4; // 0 to 15 + }; + UINT64 v; + }; + +#ifdef __cplusplus + + _XMUICO4() {}; + _XMUICO4(UINT64 Packed) : v(Packed) {}; + _XMUICO4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUICO4(CONST FLOAT *pArray); + + operator UINT64 () { return v; } + + _XMUICO4& operator= (CONST _XMUICO4& UIco4); + _XMUICO4& operator= (CONST UINT64 Packed); + +#endif // __cplusplus + +} XMUICO4; + +// ARGB Color; 8-8-8-8 bit unsigned normalized integer components packed into +// a 32 bit integer. The normalized color is packed into 32 bits using 8 bit +// unsigned, normalized integers for the alpha, red, green, and blue components. +// The alpha component is stored in the most significant bits and the blue +// component in the least significant bits (A8R8G8B8): +// [32] aaaaaaaa rrrrrrrr gggggggg bbbbbbbb [0] +typedef struct _XMCOLOR +{ + union + { + struct + { + UINT b : 8; // Blue: 0/255 to 255/255 + UINT g : 8; // Green: 0/255 to 255/255 + UINT r : 8; // Red: 0/255 to 255/255 + UINT a : 8; // Alpha: 0/255 to 255/255 + }; + UINT c; + }; + +#ifdef __cplusplus + + _XMCOLOR() {}; + _XMCOLOR(UINT Color) : c(Color) {}; + _XMCOLOR(FLOAT _r, FLOAT _g, FLOAT _b, FLOAT _a); + _XMCOLOR(CONST FLOAT *pArray); + + operator UINT () { return c; } + + _XMCOLOR& operator= (CONST _XMCOLOR& Color); + _XMCOLOR& operator= (CONST UINT Color); + +#endif // __cplusplus + +} XMCOLOR; + +// 4D Vector; 8 bit signed normalized integer components +typedef struct _XMBYTEN4 +{ + union + { + struct + { + CHAR x; + CHAR y; + CHAR z; + CHAR w; + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMBYTEN4() {}; + _XMBYTEN4(CHAR _x, CHAR _y, CHAR _z, CHAR _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMBYTEN4(UINT Packed) : v(Packed) {}; + _XMBYTEN4(CONST CHAR *pArray); + _XMBYTEN4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMBYTEN4(CONST FLOAT *pArray); + + _XMBYTEN4& operator= (CONST _XMBYTEN4& ByteN4); + +#endif // __cplusplus + +} XMBYTEN4; + +// 4D Vector; 8 bit signed integer components +typedef struct _XMBYTE4 +{ + union + { + struct + { + CHAR x; + CHAR y; + CHAR z; + CHAR w; + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMBYTE4() {}; + _XMBYTE4(CHAR _x, CHAR _y, CHAR _z, CHAR _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMBYTE4(UINT Packed) : v(Packed) {}; + _XMBYTE4(CONST CHAR *pArray); + _XMBYTE4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMBYTE4(CONST FLOAT *pArray); + + _XMBYTE4& operator= (CONST _XMBYTE4& Byte4); + +#endif // __cplusplus + +} XMBYTE4; + +// 4D Vector; 8 bit unsigned normalized integer components +typedef struct _XMUBYTEN4 +{ + union + { + struct + { + BYTE x; + BYTE y; + BYTE z; + BYTE w; + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUBYTEN4() {}; + _XMUBYTEN4(BYTE _x, BYTE _y, BYTE _z, BYTE _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMUBYTEN4(UINT Packed) : v(Packed) {}; + _XMUBYTEN4(CONST BYTE *pArray); + _XMUBYTEN4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUBYTEN4(CONST FLOAT *pArray); + + _XMUBYTEN4& operator= (CONST _XMUBYTEN4& UByteN4); + +#endif // __cplusplus + +} XMUBYTEN4; + +// 4D Vector; 8 bit unsigned integer components +typedef struct _XMUBYTE4 +{ + union + { + struct + { + BYTE x; + BYTE y; + BYTE z; + BYTE w; + }; + UINT v; + }; + +#ifdef __cplusplus + + _XMUBYTE4() {}; + _XMUBYTE4(BYTE _x, BYTE _y, BYTE _z, BYTE _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMUBYTE4(UINT Packed) : v(Packed) {}; + _XMUBYTE4(CONST BYTE *pArray); + _XMUBYTE4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUBYTE4(CONST FLOAT *pArray); + + _XMUBYTE4& operator= (CONST _XMUBYTE4& UByte4); + +#endif // __cplusplus + +} XMUBYTE4; + +// 4D vector; 4 bit unsigned integer components +typedef struct _XMUNIBBLE4 +{ + union + { + struct + { + USHORT x : 4; + USHORT y : 4; + USHORT z : 4; + USHORT w : 4; + }; + USHORT v; + }; + +#ifdef __cplusplus + + _XMUNIBBLE4() {}; + _XMUNIBBLE4(USHORT Packed) : v(Packed) {}; + _XMUNIBBLE4(CHAR _x, CHAR _y, CHAR _z, CHAR _w) : x(_x), y(_y), z(_z), w(_w) {}; + _XMUNIBBLE4(CONST CHAR *pArray); + _XMUNIBBLE4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w); + _XMUNIBBLE4(CONST FLOAT *pArray); + + operator USHORT () { return v; } + + _XMUNIBBLE4& operator= (CONST _XMUNIBBLE4& UNibble4); + _XMUNIBBLE4& operator= (CONST USHORT Packed); + +#endif // __cplusplus + +} XMUNIBBLE4; + +// 4D vector: 5/5/5/1 unsigned integer components +typedef struct _XMU555 +{ + union + { + struct + { + USHORT x : 5; + USHORT y : 5; + USHORT z : 5; + USHORT w : 1; + }; + USHORT v; + }; + +#ifdef __cplusplus + + _XMU555() {}; + _XMU555(USHORT Packed) : v(Packed) {}; + _XMU555(CHAR _x, CHAR _y, CHAR _z, BOOL _w) : x(_x), y(_y), z(_z), w(_w ? 0x1 : 0) {}; + _XMU555(CONST CHAR *pArray, BOOL _w); + _XMU555(FLOAT _x, FLOAT _y, FLOAT _z, BOOL _w); + _XMU555(CONST FLOAT *pArray, BOOL _w); + + operator USHORT () { return v; } + + _XMU555& operator= (CONST _XMU555& U555); + _XMU555& operator= (CONST USHORT Packed); + +#endif // __cplusplus + +} XMU555; + +// 3x3 Matrix: 32 bit floating point components +typedef struct _XMFLOAT3X3 +{ + union + { + struct + { + FLOAT _11, _12, _13; + FLOAT _21, _22, _23; + FLOAT _31, _32, _33; + }; + FLOAT m[3][3]; + }; + +#ifdef __cplusplus + + _XMFLOAT3X3() {}; + _XMFLOAT3X3(FLOAT m00, FLOAT m01, FLOAT m02, + FLOAT m10, FLOAT m11, FLOAT m12, + FLOAT m20, FLOAT m21, FLOAT m22); + _XMFLOAT3X3(CONST FLOAT *pArray); + + FLOAT operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; } + FLOAT& operator() (UINT Row, UINT Column) { return m[Row][Column]; } + + _XMFLOAT3X3& operator= (CONST _XMFLOAT3X3& Float3x3); + +#endif // __cplusplus + +} XMFLOAT3X3; + +// 4x3 Matrix: 32 bit floating point components +typedef struct _XMFLOAT4X3 +{ + union + { + struct + { + FLOAT _11, _12, _13; + FLOAT _21, _22, _23; + FLOAT _31, _32, _33; + FLOAT _41, _42, _43; + }; + FLOAT m[4][3]; + }; + +#ifdef __cplusplus + + _XMFLOAT4X3() {}; + _XMFLOAT4X3(FLOAT m00, FLOAT m01, FLOAT m02, + FLOAT m10, FLOAT m11, FLOAT m12, + FLOAT m20, FLOAT m21, FLOAT m22, + FLOAT m30, FLOAT m31, FLOAT m32); + _XMFLOAT4X3(CONST FLOAT *pArray); + + FLOAT operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; } + FLOAT& operator() (UINT Row, UINT Column) { return m[Row][Column]; } + + _XMFLOAT4X3& operator= (CONST _XMFLOAT4X3& Float4x3); + +#endif // __cplusplus + +} XMFLOAT4X3; + +// 4x3 Matrix: 32 bit floating point components aligned on a 16 byte boundary +#ifdef __cplusplus +__declspec(align(16)) struct XMFLOAT4X3A : public XMFLOAT4X3 +{ + XMFLOAT4X3A() : XMFLOAT4X3() {}; + XMFLOAT4X3A(FLOAT m00, FLOAT m01, FLOAT m02, + FLOAT m10, FLOAT m11, FLOAT m12, + FLOAT m20, FLOAT m21, FLOAT m22, + FLOAT m30, FLOAT m31, FLOAT m32) : + XMFLOAT4X3(m00,m01,m02,m10,m11,m12,m20,m21,m22,m30,m31,m32) {}; + XMFLOAT4X3A(CONST FLOAT *pArray) : XMFLOAT4X3(pArray) {} + + FLOAT operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; } + FLOAT& operator() (UINT Row, UINT Column) { return m[Row][Column]; } + + XMFLOAT4X3A& operator= (CONST XMFLOAT4X3A& Float4x3); +}; +#else +typedef __declspec(align(16)) XMFLOAT4X3 XMFLOAT4X3A; +#endif // __cplusplus + +// 4x4 Matrix: 32 bit floating point components +typedef struct _XMFLOAT4X4 +{ + union + { + struct + { + FLOAT _11, _12, _13, _14; + FLOAT _21, _22, _23, _24; + FLOAT _31, _32, _33, _34; + FLOAT _41, _42, _43, _44; + }; + FLOAT m[4][4]; + }; + +#ifdef __cplusplus + + _XMFLOAT4X4() {}; + _XMFLOAT4X4(FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03, + FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13, + FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23, + FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33); + _XMFLOAT4X4(CONST FLOAT *pArray); + + FLOAT operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; } + FLOAT& operator() (UINT Row, UINT Column) { return m[Row][Column]; } + + _XMFLOAT4X4& operator= (CONST _XMFLOAT4X4& Float4x4); + +#endif // __cplusplus + +} XMFLOAT4X4; + +// 4x4 Matrix: 32 bit floating point components aligned on a 16 byte boundary +#ifdef __cplusplus +__declspec(align(16)) struct XMFLOAT4X4A : public XMFLOAT4X4 +{ + XMFLOAT4X4A() : XMFLOAT4X4() {}; + XMFLOAT4X4A(FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03, + FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13, + FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23, + FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33) + : XMFLOAT4X4(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33) {}; + XMFLOAT4X4A(CONST FLOAT *pArray) : XMFLOAT4X4(pArray) {} + + FLOAT operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; } + FLOAT& operator() (UINT Row, UINT Column) { return m[Row][Column]; } + + XMFLOAT4X4A& operator= (CONST XMFLOAT4X4A& Float4x4); +}; +#else +typedef __declspec(align(16)) XMFLOAT4X4 XMFLOAT4X4A; +#endif // __cplusplus + +#if !defined(_XM_X86_) && !defined(_XM_X64_) +#pragma bitfield_order(pop) +#endif // !_XM_X86_ && !_XM_X64_ + +#pragma warning(pop) + + +/**************************************************************************** + * + * Data conversion operations + * + ****************************************************************************/ + +#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_VMX128_INTRINSICS_) +#else +XMVECTOR XMConvertVectorIntToFloat(FXMVECTOR VInt, UINT DivExponent); +XMVECTOR XMConvertVectorFloatToInt(FXMVECTOR VFloat, UINT MulExponent); +XMVECTOR XMConvertVectorUIntToFloat(FXMVECTOR VUInt, UINT DivExponent); +XMVECTOR XMConvertVectorFloatToUInt(FXMVECTOR VFloat, UINT MulExponent); +#endif + +FLOAT XMConvertHalfToFloat(HALF Value); +FLOAT* XMConvertHalfToFloatStream(_Out_bytecap_x_(sizeof(FLOAT)+OutputStride*(HalfCount-1)) FLOAT* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(HALF)+InputStride*(HalfCount-1)) CONST HALF* pInputStream, + _In_ UINT InputStride, _In_ UINT HalfCount); +HALF XMConvertFloatToHalf(FLOAT Value); +HALF* XMConvertFloatToHalfStream(_Out_bytecap_x_(sizeof(HALF)+OutputStride*(FloatCount-1)) HALF* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(FLOAT)+InputStride*(FloatCount-1)) CONST FLOAT* pInputStream, + _In_ UINT InputStride, _In_ UINT FloatCount); + +#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_VMX128_INTRINSICS_) +#else +XMVECTOR XMVectorSetBinaryConstant(UINT C0, UINT C1, UINT C2, UINT C3); +XMVECTOR XMVectorSplatConstant(INT IntConstant, UINT DivExponent); +XMVECTOR XMVectorSplatConstantInt(INT IntConstant); +#endif + +/**************************************************************************** + * + * Load operations + * + ****************************************************************************/ + +XMVECTOR XMLoadInt(_In_ CONST UINT* pSource); +XMVECTOR XMLoadFloat(_In_ CONST FLOAT* pSource); + +XMVECTOR XMLoadInt2(_In_count_c_(2) CONST UINT* pSource); +XMVECTOR XMLoadInt2A(_In_count_c_(2) CONST UINT* PSource); +XMVECTOR XMLoadFloat2(_In_ CONST XMFLOAT2* pSource); +XMVECTOR XMLoadFloat2A(_In_ CONST XMFLOAT2A* pSource); +XMVECTOR XMLoadHalf2(_In_ CONST XMHALF2* pSource); +XMVECTOR XMLoadShortN2(_In_ CONST XMSHORTN2* pSource); +XMVECTOR XMLoadShort2(_In_ CONST XMSHORT2* pSource); +XMVECTOR XMLoadUShortN2(_In_ CONST XMUSHORTN2* pSource); +XMVECTOR XMLoadUShort2(_In_ CONST XMUSHORT2* pSource); + +XMVECTOR XMLoadInt3(_In_count_c_(3) CONST UINT* pSource); +XMVECTOR XMLoadInt3A(_In_count_c_(3) CONST UINT* pSource); +XMVECTOR XMLoadFloat3(_In_ CONST XMFLOAT3* pSource); +XMVECTOR XMLoadFloat3A(_In_ CONST XMFLOAT3A* pSource); +XMVECTOR XMLoadHenDN3(_In_ CONST XMHENDN3* pSource); +XMVECTOR XMLoadHenD3(_In_ CONST XMHEND3* pSource); +XMVECTOR XMLoadUHenDN3(_In_ CONST XMUHENDN3* pSource); +XMVECTOR XMLoadUHenD3(_In_ CONST XMUHEND3* pSource); +XMVECTOR XMLoadDHenN3(_In_ CONST XMDHENN3* pSource); +XMVECTOR XMLoadDHen3(_In_ CONST XMDHEN3* pSource); +XMVECTOR XMLoadUDHenN3(_In_ CONST XMUDHENN3* pSource); +XMVECTOR XMLoadUDHen3(_In_ CONST XMUDHEN3* pSource); +XMVECTOR XMLoadU565(_In_ CONST XMU565* pSource); +XMVECTOR XMLoadFloat3PK(_In_ CONST XMFLOAT3PK* pSource); +XMVECTOR XMLoadFloat3SE(_In_ CONST XMFLOAT3SE* pSource); + +XMVECTOR XMLoadInt4(_In_count_c_(4) CONST UINT* pSource); +XMVECTOR XMLoadInt4A(_In_count_c_(4) CONST UINT* pSource); +XMVECTOR XMLoadFloat4(_In_ CONST XMFLOAT4* pSource); +XMVECTOR XMLoadFloat4A(_In_ CONST XMFLOAT4A* pSource); +XMVECTOR XMLoadHalf4(_In_ CONST XMHALF4* pSource); +XMVECTOR XMLoadShortN4(_In_ CONST XMSHORTN4* pSource); +XMVECTOR XMLoadShort4(_In_ CONST XMSHORT4* pSource); +XMVECTOR XMLoadUShortN4(_In_ CONST XMUSHORTN4* pSource); +XMVECTOR XMLoadUShort4(_In_ CONST XMUSHORT4* pSource); +XMVECTOR XMLoadXIcoN4(_In_ CONST XMXICON4* pSource); +XMVECTOR XMLoadXIco4(_In_ CONST XMXICO4* pSource); +XMVECTOR XMLoadIcoN4(_In_ CONST XMICON4* pSource); +XMVECTOR XMLoadIco4(_In_ CONST XMICO4* pSource); +XMVECTOR XMLoadUIcoN4(_In_ CONST XMUICON4* pSource); +XMVECTOR XMLoadUIco4(_In_ CONST XMUICO4* pSource); +XMVECTOR XMLoadXDecN4(_In_ CONST XMXDECN4* pSource); +XMVECTOR XMLoadXDec4(_In_ CONST XMXDEC4* pSource); +XMVECTOR XMLoadDecN4(_In_ CONST XMDECN4* pSource); +XMVECTOR XMLoadDec4(_In_ CONST XMDEC4* pSource); +XMVECTOR XMLoadUDecN4(_In_ CONST XMUDECN4* pSource); +XMVECTOR XMLoadUDec4(_In_ CONST XMUDEC4* pSource); +XMVECTOR XMLoadByteN4(_In_ CONST XMBYTEN4* pSource); +XMVECTOR XMLoadByte4(_In_ CONST XMBYTE4* pSource); +XMVECTOR XMLoadUByteN4(_In_ CONST XMUBYTEN4* pSource); +XMVECTOR XMLoadUByte4(_In_ CONST XMUBYTE4* pSource); +XMVECTOR XMLoadUNibble4(_In_ CONST XMUNIBBLE4* pSource); +XMVECTOR XMLoadU555(_In_ CONST XMU555* pSource); +XMVECTOR XMLoadColor(_In_ CONST XMCOLOR* pSource); + +XMMATRIX XMLoadFloat3x3(_In_ CONST XMFLOAT3X3* pSource); +XMMATRIX XMLoadFloat4x3(_In_ CONST XMFLOAT4X3* pSource); +XMMATRIX XMLoadFloat4x3A(_In_ CONST XMFLOAT4X3A* pSource); +XMMATRIX XMLoadFloat4x4(_In_ CONST XMFLOAT4X4* pSource); +XMMATRIX XMLoadFloat4x4A(_In_ CONST XMFLOAT4X4A* pSource); + +/**************************************************************************** + * + * Store operations + * + ****************************************************************************/ + +VOID XMStoreInt(_Out_ UINT* pDestination, FXMVECTOR V); +VOID XMStoreFloat(_Out_ FLOAT* pDestination, FXMVECTOR V); + +VOID XMStoreInt2(_Out_cap_c_(2) UINT* pDestination, FXMVECTOR V); +VOID XMStoreInt2A(_Out_cap_c_(2) UINT* pDestination, FXMVECTOR V); +VOID XMStoreFloat2(_Out_ XMFLOAT2* pDestination, FXMVECTOR V); +VOID XMStoreFloat2A(_Out_ XMFLOAT2A* pDestination, FXMVECTOR V); +VOID XMStoreHalf2(_Out_ XMHALF2* pDestination, FXMVECTOR V); +VOID XMStoreShortN2(_Out_ XMSHORTN2* pDestination, FXMVECTOR V); +VOID XMStoreShort2(_Out_ XMSHORT2* pDestination, FXMVECTOR V); +VOID XMStoreUShortN2(_Out_ XMUSHORTN2* pDestination, FXMVECTOR V); +VOID XMStoreUShort2(_Out_ XMUSHORT2* pDestination, FXMVECTOR V); + +VOID XMStoreInt3(_Out_cap_c_(3) UINT* pDestination, FXMVECTOR V); +VOID XMStoreInt3A(_Out_cap_c_(3) UINT* pDestination, FXMVECTOR V); +VOID XMStoreFloat3(_Out_ XMFLOAT3* pDestination, FXMVECTOR V); +VOID XMStoreFloat3A(_Out_ XMFLOAT3A* pDestination, FXMVECTOR V); +VOID XMStoreHenDN3(_Out_ XMHENDN3* pDestination, FXMVECTOR V); +VOID XMStoreHenD3(_Out_ XMHEND3* pDestination, FXMVECTOR V); +VOID XMStoreUHenDN3(_Out_ XMUHENDN3* pDestination, FXMVECTOR V); +VOID XMStoreUHenD3(_Out_ XMUHEND3* pDestination, FXMVECTOR V); +VOID XMStoreDHenN3(_Out_ XMDHENN3* pDestination, FXMVECTOR V); +VOID XMStoreDHen3(_Out_ XMDHEN3* pDestination, FXMVECTOR V); +VOID XMStoreUDHenN3(_Out_ XMUDHENN3* pDestination, FXMVECTOR V); +VOID XMStoreUDHen3(_Out_ XMUDHEN3* pDestination, FXMVECTOR V); +VOID XMStoreU565(_Out_ XMU565* pDestination, FXMVECTOR V); +VOID XMStoreFloat3PK(_Out_ XMFLOAT3PK* pDestination, FXMVECTOR V); +VOID XMStoreFloat3SE(_Out_ XMFLOAT3SE* pDestination, FXMVECTOR V); + +VOID XMStoreInt4(_Out_cap_c_(4) UINT* pDestination, FXMVECTOR V); +VOID XMStoreInt4A(_Out_cap_c_(4) UINT* pDestination, FXMVECTOR V); +VOID XMStoreInt4NC(_Out_ UINT* pDestination, FXMVECTOR V); +VOID XMStoreFloat4(_Out_ XMFLOAT4* pDestination, FXMVECTOR V); +VOID XMStoreFloat4A(_Out_ XMFLOAT4A* pDestination, FXMVECTOR V); +VOID XMStoreFloat4NC(_Out_ XMFLOAT4* pDestination, FXMVECTOR V); +VOID XMStoreHalf4(_Out_ XMHALF4* pDestination, FXMVECTOR V); +VOID XMStoreShortN4(_Out_ XMSHORTN4* pDestination, FXMVECTOR V); +VOID XMStoreShort4(_Out_ XMSHORT4* pDestination, FXMVECTOR V); +VOID XMStoreUShortN4(_Out_ XMUSHORTN4* pDestination, FXMVECTOR V); +VOID XMStoreUShort4(_Out_ XMUSHORT4* pDestination, FXMVECTOR V); +VOID XMStoreXIcoN4(_Out_ XMXICON4* pDestination, FXMVECTOR V); +VOID XMStoreXIco4(_Out_ XMXICO4* pDestination, FXMVECTOR V); +VOID XMStoreIcoN4(_Out_ XMICON4* pDestination, FXMVECTOR V); +VOID XMStoreIco4(_Out_ XMICO4* pDestination, FXMVECTOR V); +VOID XMStoreUIcoN4(_Out_ XMUICON4* pDestination, FXMVECTOR V); +VOID XMStoreUIco4(_Out_ XMUICO4* pDestination, FXMVECTOR V); +VOID XMStoreXDecN4(_Out_ XMXDECN4* pDestination, FXMVECTOR V); +VOID XMStoreXDec4(_Out_ XMXDEC4* pDestination, FXMVECTOR V); +VOID XMStoreDecN4(_Out_ XMDECN4* pDestination, FXMVECTOR V); +VOID XMStoreDec4(_Out_ XMDEC4* pDestination, FXMVECTOR V); +VOID XMStoreUDecN4(_Out_ XMUDECN4* pDestination, FXMVECTOR V); +VOID XMStoreUDec4(_Out_ XMUDEC4* pDestination, FXMVECTOR V); +VOID XMStoreByteN4(_Out_ XMBYTEN4* pDestination, FXMVECTOR V); +VOID XMStoreByte4(_Out_ XMBYTE4* pDestination, FXMVECTOR V); +VOID XMStoreUByteN4(_Out_ XMUBYTEN4* pDestination, FXMVECTOR V); +VOID XMStoreUByte4(_Out_ XMUBYTE4* pDestination, FXMVECTOR V); +VOID XMStoreUNibble4(_Out_ XMUNIBBLE4* pDestination, FXMVECTOR V); +VOID XMStoreU555(_Out_ XMU555* pDestination, FXMVECTOR V); +VOID XMStoreColor(_Out_ XMCOLOR* pDestination, FXMVECTOR V); + +VOID XMStoreFloat3x3(_Out_ XMFLOAT3X3* pDestination, CXMMATRIX M); +VOID XMStoreFloat3x3NC(_Out_ XMFLOAT3X3* pDestination, CXMMATRIX M); +VOID XMStoreFloat4x3(_Out_ XMFLOAT4X3* pDestination, CXMMATRIX M); +VOID XMStoreFloat4x3A(_Out_ XMFLOAT4X3A* pDestination, CXMMATRIX M); +VOID XMStoreFloat4x3NC(_Out_ XMFLOAT4X3* pDestination, CXMMATRIX M); +VOID XMStoreFloat4x4(_Out_ XMFLOAT4X4* pDestination, CXMMATRIX M); +VOID XMStoreFloat4x4A(_Out_ XMFLOAT4X4A* pDestination, CXMMATRIX M); +VOID XMStoreFloat4x4NC(_Out_ XMFLOAT4X4* pDestination, CXMMATRIX M); + +/**************************************************************************** + * + * General vector operations + * + ****************************************************************************/ + +XMVECTOR XMVectorZero(); +XMVECTOR XMVectorSet(FLOAT x, FLOAT y, FLOAT z, FLOAT w); +XMVECTOR XMVectorSetInt(UINT x, UINT y, UINT z, UINT w); +XMVECTOR XMVectorReplicate(FLOAT Value); +XMVECTOR XMVectorReplicatePtr(_In_ CONST FLOAT *pValue); +XMVECTOR XMVectorReplicateInt(UINT Value); +XMVECTOR XMVectorReplicateIntPtr(_In_ CONST UINT *pValue); +XMVECTOR XMVectorTrueInt(); +XMVECTOR XMVectorFalseInt(); +XMVECTOR XMVectorSplatX(FXMVECTOR V); +XMVECTOR XMVectorSplatY(FXMVECTOR V); +XMVECTOR XMVectorSplatZ(FXMVECTOR V); +XMVECTOR XMVectorSplatW(FXMVECTOR V); +XMVECTOR XMVectorSplatOne(); +XMVECTOR XMVectorSplatInfinity(); +XMVECTOR XMVectorSplatQNaN(); +XMVECTOR XMVectorSplatEpsilon(); +XMVECTOR XMVectorSplatSignMask(); + +FLOAT XMVectorGetByIndex(FXMVECTOR V,UINT i); +FLOAT XMVectorGetX(FXMVECTOR V); +FLOAT XMVectorGetY(FXMVECTOR V); +FLOAT XMVectorGetZ(FXMVECTOR V); +FLOAT XMVectorGetW(FXMVECTOR V); + +VOID XMVectorGetByIndexPtr(_Out_ FLOAT *f, FXMVECTOR V, UINT i); +VOID XMVectorGetXPtr(_Out_ FLOAT *x, FXMVECTOR V); +VOID XMVectorGetYPtr(_Out_ FLOAT *y, FXMVECTOR V); +VOID XMVectorGetZPtr(_Out_ FLOAT *z, FXMVECTOR V); +VOID XMVectorGetWPtr(_Out_ FLOAT *w, FXMVECTOR V); + +UINT XMVectorGetIntByIndex(FXMVECTOR V,UINT i); +UINT XMVectorGetIntX(FXMVECTOR V); +UINT XMVectorGetIntY(FXMVECTOR V); +UINT XMVectorGetIntZ(FXMVECTOR V); +UINT XMVectorGetIntW(FXMVECTOR V); + +VOID XMVectorGetIntByIndexPtr(_Out_ UINT *x,FXMVECTOR V, UINT i); +VOID XMVectorGetIntXPtr(_Out_ UINT *x, FXMVECTOR V); +VOID XMVectorGetIntYPtr(_Out_ UINT *y, FXMVECTOR V); +VOID XMVectorGetIntZPtr(_Out_ UINT *z, FXMVECTOR V); +VOID XMVectorGetIntWPtr(_Out_ UINT *w, FXMVECTOR V); + +XMVECTOR XMVectorSetByIndex(FXMVECTOR V,FLOAT f,UINT i); +XMVECTOR XMVectorSetX(FXMVECTOR V, FLOAT x); +XMVECTOR XMVectorSetY(FXMVECTOR V, FLOAT y); +XMVECTOR XMVectorSetZ(FXMVECTOR V, FLOAT z); +XMVECTOR XMVectorSetW(FXMVECTOR V, FLOAT w); + +XMVECTOR XMVectorSetByIndexPtr(FXMVECTOR V, _In_ CONST FLOAT *f, UINT i); +XMVECTOR XMVectorSetXPtr(FXMVECTOR V, _In_ CONST FLOAT *x); +XMVECTOR XMVectorSetYPtr(FXMVECTOR V, _In_ CONST FLOAT *y); +XMVECTOR XMVectorSetZPtr(FXMVECTOR V, _In_ CONST FLOAT *z); +XMVECTOR XMVectorSetWPtr(FXMVECTOR V, _In_ CONST FLOAT *w); + +XMVECTOR XMVectorSetIntByIndex(FXMVECTOR V, UINT x,UINT i); +XMVECTOR XMVectorSetIntX(FXMVECTOR V, UINT x); +XMVECTOR XMVectorSetIntY(FXMVECTOR V, UINT y); +XMVECTOR XMVectorSetIntZ(FXMVECTOR V, UINT z); +XMVECTOR XMVectorSetIntW(FXMVECTOR V, UINT w); + +XMVECTOR XMVectorSetIntByIndexPtr(FXMVECTOR V, _In_ CONST UINT *x, UINT i); +XMVECTOR XMVectorSetIntXPtr(FXMVECTOR V, _In_ CONST UINT *x); +XMVECTOR XMVectorSetIntYPtr(FXMVECTOR V, _In_ CONST UINT *y); +XMVECTOR XMVectorSetIntZPtr(FXMVECTOR V, _In_ CONST UINT *z); +XMVECTOR XMVectorSetIntWPtr(FXMVECTOR V, _In_ CONST UINT *w); + +XMVECTOR XMVectorPermuteControl(UINT ElementIndex0, UINT ElementIndex1, UINT ElementIndex2, UINT ElementIndex3); +XMVECTOR XMVectorPermute(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR Control); +XMVECTOR XMVectorSelectControl(UINT VectorIndex0, UINT VectorIndex1, UINT VectorIndex2, UINT VectorIndex3); +XMVECTOR XMVectorSelect(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR Control); +XMVECTOR XMVectorMergeXY(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorMergeZW(FXMVECTOR V1, FXMVECTOR V2); + +#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_VMX128_INTRINSICS_) +#else +XMVECTOR XMVectorShiftLeft(FXMVECTOR V1, FXMVECTOR V2, UINT Elements); +XMVECTOR XMVectorRotateLeft(FXMVECTOR V, UINT Elements); +XMVECTOR XMVectorRotateRight(FXMVECTOR V, UINT Elements); +XMVECTOR XMVectorSwizzle(FXMVECTOR V, UINT E0, UINT E1, UINT E2, UINT E3); +XMVECTOR XMVectorInsert(FXMVECTOR VD, FXMVECTOR VS, UINT VSLeftRotateElements, + UINT Select0, UINT Select1, UINT Select2, UINT Select3); +#endif + +XMVECTOR XMVectorEqual(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorEqualR(_Out_ UINT* pCR, FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorEqualInt(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorEqualIntR(_Out_ UINT* pCR, FXMVECTOR V, FXMVECTOR V2); +XMVECTOR XMVectorNearEqual(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR Epsilon); +XMVECTOR XMVectorNotEqual(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorNotEqualInt(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorGreater(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorGreaterR(_Out_ UINT* pCR, FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorGreaterOrEqual(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorGreaterOrEqualR(_Out_ UINT* pCR, FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorLess(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorLessOrEqual(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorInBounds(FXMVECTOR V, FXMVECTOR Bounds); +XMVECTOR XMVectorInBoundsR(_Out_ UINT* pCR, FXMVECTOR V, FXMVECTOR Bounds); + +XMVECTOR XMVectorIsNaN(FXMVECTOR V); +XMVECTOR XMVectorIsInfinite(FXMVECTOR V); + +XMVECTOR XMVectorMin(FXMVECTOR V1,FXMVECTOR V2); +XMVECTOR XMVectorMax(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorRound(FXMVECTOR V); +XMVECTOR XMVectorTruncate(FXMVECTOR V); +XMVECTOR XMVectorFloor(FXMVECTOR V); +XMVECTOR XMVectorCeiling(FXMVECTOR V); +XMVECTOR XMVectorClamp(FXMVECTOR V, FXMVECTOR Min, FXMVECTOR Max); +XMVECTOR XMVectorSaturate(FXMVECTOR V); + +XMVECTOR XMVectorAndInt(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorAndCInt(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorOrInt(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorNorInt(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorXorInt(FXMVECTOR V1, FXMVECTOR V2); + +XMVECTOR XMVectorNegate(FXMVECTOR V); +XMVECTOR XMVectorAdd(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorAddAngles(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorSubtract(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorSubtractAngles(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorMultiply(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorMultiplyAdd(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR V3); +XMVECTOR XMVectorDivide(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorNegativeMultiplySubtract(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR V3); +XMVECTOR XMVectorScale(FXMVECTOR V, FLOAT ScaleFactor); +XMVECTOR XMVectorReciprocalEst(FXMVECTOR V); +XMVECTOR XMVectorReciprocal(FXMVECTOR V); +XMVECTOR XMVectorSqrtEst(FXMVECTOR V); +XMVECTOR XMVectorSqrt(FXMVECTOR V); +XMVECTOR XMVectorReciprocalSqrtEst(FXMVECTOR V); +XMVECTOR XMVectorReciprocalSqrt(FXMVECTOR V); +XMVECTOR XMVectorExpEst(FXMVECTOR V); +XMVECTOR XMVectorExp(FXMVECTOR V); +XMVECTOR XMVectorLogEst(FXMVECTOR V); +XMVECTOR XMVectorLog(FXMVECTOR V); +XMVECTOR XMVectorPowEst(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorPow(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorAbs(FXMVECTOR V); +XMVECTOR XMVectorMod(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVectorModAngles(FXMVECTOR Angles); +XMVECTOR XMVectorSin(FXMVECTOR V); +XMVECTOR XMVectorSinEst(FXMVECTOR V); +XMVECTOR XMVectorCos(FXMVECTOR V); +XMVECTOR XMVectorCosEst(FXMVECTOR V); +VOID XMVectorSinCos(_Out_ XMVECTOR* pSin, _Out_ XMVECTOR* pCos, FXMVECTOR V); +VOID XMVectorSinCosEst(_Out_ XMVECTOR* pSin, _Out_ XMVECTOR* pCos, FXMVECTOR V); +XMVECTOR XMVectorTan(FXMVECTOR V); +XMVECTOR XMVectorTanEst(FXMVECTOR V); +XMVECTOR XMVectorSinH(FXMVECTOR V); +XMVECTOR XMVectorSinHEst(FXMVECTOR V); +XMVECTOR XMVectorCosH(FXMVECTOR V); +XMVECTOR XMVectorCosHEst(FXMVECTOR V); +XMVECTOR XMVectorTanH(FXMVECTOR V); +XMVECTOR XMVectorTanHEst(FXMVECTOR V); +XMVECTOR XMVectorASin(FXMVECTOR V); +XMVECTOR XMVectorASinEst(FXMVECTOR V); +XMVECTOR XMVectorACos(FXMVECTOR V); +XMVECTOR XMVectorACosEst(FXMVECTOR V); +XMVECTOR XMVectorATan(FXMVECTOR V); +XMVECTOR XMVectorATanEst(FXMVECTOR V); +XMVECTOR XMVectorATan2(FXMVECTOR Y, FXMVECTOR X); +XMVECTOR XMVectorATan2Est(FXMVECTOR Y, FXMVECTOR X); +XMVECTOR XMVectorLerp(FXMVECTOR V0, FXMVECTOR V1, FLOAT t); +XMVECTOR XMVectorLerpV(FXMVECTOR V0, FXMVECTOR V1, FXMVECTOR T); +XMVECTOR XMVectorHermite(FXMVECTOR Position0, FXMVECTOR Tangent0, FXMVECTOR Position1, CXMVECTOR Tangent1, FLOAT t); +XMVECTOR XMVectorHermiteV(FXMVECTOR Position0, FXMVECTOR Tangent0, FXMVECTOR Position1, CXMVECTOR Tangent1, CXMVECTOR T); +XMVECTOR XMVectorCatmullRom(FXMVECTOR Position0, FXMVECTOR Position1, FXMVECTOR Position2, CXMVECTOR Position3, FLOAT t); +XMVECTOR XMVectorCatmullRomV(FXMVECTOR Position0, FXMVECTOR Position1, FXMVECTOR Position2, CXMVECTOR Position3, CXMVECTOR T); +XMVECTOR XMVectorBaryCentric(FXMVECTOR Position0, FXMVECTOR Position1, FXMVECTOR Position2, FLOAT f, FLOAT g); +XMVECTOR XMVectorBaryCentricV(FXMVECTOR Position0, FXMVECTOR Position1, FXMVECTOR Position2, CXMVECTOR F, CXMVECTOR G); + +/**************************************************************************** + * + * 2D vector operations + * + ****************************************************************************/ + + +BOOL XMVector2Equal(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector2EqualR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2EqualInt(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector2EqualIntR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2NearEqual(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR Epsilon); +BOOL XMVector2NotEqual(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2NotEqualInt(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2Greater(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector2GreaterR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2GreaterOrEqual(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector2GreaterOrEqualR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2Less(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2LessOrEqual(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector2InBounds(FXMVECTOR V, FXMVECTOR Bounds); +UINT XMVector2InBoundsR(FXMVECTOR V, FXMVECTOR Bounds); + +BOOL XMVector2IsNaN(FXMVECTOR V); +BOOL XMVector2IsInfinite(FXMVECTOR V); + +XMVECTOR XMVector2Dot(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector2Cross(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector2LengthSq(FXMVECTOR V); +XMVECTOR XMVector2ReciprocalLengthEst(FXMVECTOR V); +XMVECTOR XMVector2ReciprocalLength(FXMVECTOR V); +XMVECTOR XMVector2LengthEst(FXMVECTOR V); +XMVECTOR XMVector2Length(FXMVECTOR V); +XMVECTOR XMVector2NormalizeEst(FXMVECTOR V); +XMVECTOR XMVector2Normalize(FXMVECTOR V); +XMVECTOR XMVector2ClampLength(FXMVECTOR V, FLOAT LengthMin, FLOAT LengthMax); +XMVECTOR XMVector2ClampLengthV(FXMVECTOR V, FXMVECTOR LengthMin, FXMVECTOR LengthMax); +XMVECTOR XMVector2Reflect(FXMVECTOR Incident, FXMVECTOR Normal); +XMVECTOR XMVector2Refract(FXMVECTOR Incident, FXMVECTOR Normal, FLOAT RefractionIndex); +XMVECTOR XMVector2RefractV(FXMVECTOR Incident, FXMVECTOR Normal, FXMVECTOR RefractionIndex); +XMVECTOR XMVector2Orthogonal(FXMVECTOR V); +XMVECTOR XMVector2AngleBetweenNormalsEst(FXMVECTOR N1, FXMVECTOR N2); +XMVECTOR XMVector2AngleBetweenNormals(FXMVECTOR N1, FXMVECTOR N2); +XMVECTOR XMVector2AngleBetweenVectors(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector2LinePointDistance(FXMVECTOR LinePoint1, FXMVECTOR LinePoint2, FXMVECTOR Point); +XMVECTOR XMVector2IntersectLine(FXMVECTOR Line1Point1, FXMVECTOR Line1Point2, FXMVECTOR Line2Point1, CXMVECTOR Line2Point2); +XMVECTOR XMVector2Transform(FXMVECTOR V, CXMMATRIX M); +XMFLOAT4* XMVector2TransformStream(_Out_bytecap_x_(sizeof(XMFLOAT4)+OutputStride*(VectorCount-1)) XMFLOAT4* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT2)+InputStride*(VectorCount-1)) CONST XMFLOAT2* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); +XMFLOAT4* XMVector2TransformStreamNC(_Out_bytecap_x_(sizeof(XMFLOAT4)+OutputStride*(VectorCount-1)) XMFLOAT4* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT2)+InputStride*(VectorCount-1)) CONST XMFLOAT2* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); +XMVECTOR XMVector2TransformCoord(FXMVECTOR V, CXMMATRIX M); +XMFLOAT2* XMVector2TransformCoordStream(_Out_bytecap_x_(sizeof(XMFLOAT2)+OutputStride*(VectorCount-1)) XMFLOAT2* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT2)+InputStride*(VectorCount-1)) CONST XMFLOAT2* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); +XMVECTOR XMVector2TransformNormal(FXMVECTOR V, CXMMATRIX M); +XMFLOAT2* XMVector2TransformNormalStream(_Out_bytecap_x_(sizeof(XMFLOAT2)+OutputStride*(VectorCount-1)) XMFLOAT2* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT2)+InputStride*(VectorCount-1)) CONST XMFLOAT2* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); + +/**************************************************************************** + * + * 3D vector operations + * + ****************************************************************************/ + + +BOOL XMVector3Equal(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector3EqualR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3EqualInt(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector3EqualIntR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3NearEqual(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR Epsilon); +BOOL XMVector3NotEqual(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3NotEqualInt(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3Greater(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector3GreaterR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3GreaterOrEqual(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector3GreaterOrEqualR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3Less(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3LessOrEqual(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector3InBounds(FXMVECTOR V, FXMVECTOR Bounds); +UINT XMVector3InBoundsR(FXMVECTOR V, FXMVECTOR Bounds); + +BOOL XMVector3IsNaN(FXMVECTOR V); +BOOL XMVector3IsInfinite(FXMVECTOR V); + +XMVECTOR XMVector3Dot(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector3Cross(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector3LengthSq(FXMVECTOR V); +XMVECTOR XMVector3ReciprocalLengthEst(FXMVECTOR V); +XMVECTOR XMVector3ReciprocalLength(FXMVECTOR V); +XMVECTOR XMVector3LengthEst(FXMVECTOR V); +XMVECTOR XMVector3Length(FXMVECTOR V); +XMVECTOR XMVector3NormalizeEst(FXMVECTOR V); +XMVECTOR XMVector3Normalize(FXMVECTOR V); +XMVECTOR XMVector3ClampLength(FXMVECTOR V, FLOAT LengthMin, FLOAT LengthMax); +XMVECTOR XMVector3ClampLengthV(FXMVECTOR V, FXMVECTOR LengthMin, FXMVECTOR LengthMax); +XMVECTOR XMVector3Reflect(FXMVECTOR Incident, FXMVECTOR Normal); +XMVECTOR XMVector3Refract(FXMVECTOR Incident, FXMVECTOR Normal, FLOAT RefractionIndex); +XMVECTOR XMVector3RefractV(FXMVECTOR Incident, FXMVECTOR Normal, FXMVECTOR RefractionIndex); +XMVECTOR XMVector3Orthogonal(FXMVECTOR V); +XMVECTOR XMVector3AngleBetweenNormalsEst(FXMVECTOR N1, FXMVECTOR N2); +XMVECTOR XMVector3AngleBetweenNormals(FXMVECTOR N1, FXMVECTOR N2); +XMVECTOR XMVector3AngleBetweenVectors(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector3LinePointDistance(FXMVECTOR LinePoint1, FXMVECTOR LinePoint2, FXMVECTOR Point); +VOID XMVector3ComponentsFromNormal(_Out_ XMVECTOR* pParallel, _Out_ XMVECTOR* pPerpendicular, FXMVECTOR V, FXMVECTOR Normal); +XMVECTOR XMVector3Rotate(FXMVECTOR V, FXMVECTOR RotationQuaternion); +XMVECTOR XMVector3InverseRotate(FXMVECTOR V, FXMVECTOR RotationQuaternion); +XMVECTOR XMVector3Transform(FXMVECTOR V, CXMMATRIX M); +XMFLOAT4* XMVector3TransformStream(_Out_bytecap_x_(sizeof(XMFLOAT4)+OutputStride*(VectorCount-1)) XMFLOAT4* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) CONST XMFLOAT3* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); +XMFLOAT4* XMVector3TransformStreamNC(_Out_bytecap_x_(sizeof(XMFLOAT4)+OutputStride*(VectorCount-1)) XMFLOAT4* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) CONST XMFLOAT3* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); +XMVECTOR XMVector3TransformCoord(FXMVECTOR V, CXMMATRIX M); +XMFLOAT3* XMVector3TransformCoordStream(_Out_bytecap_x_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) CONST XMFLOAT3* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); +XMVECTOR XMVector3TransformNormal(FXMVECTOR V, CXMMATRIX M); +XMFLOAT3* XMVector3TransformNormalStream(_Out_bytecap_x_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) CONST XMFLOAT3* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); +XMVECTOR XMVector3Project(FXMVECTOR V, FLOAT ViewportX, FLOAT ViewportY, FLOAT ViewportWidth, FLOAT ViewportHeight, FLOAT ViewportMinZ, FLOAT ViewportMaxZ, + CXMMATRIX Projection, CXMMATRIX View, CXMMATRIX World); +XMFLOAT3* XMVector3ProjectStream(_Out_bytecap_x_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) CONST XMFLOAT3* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, + FLOAT ViewportX, FLOAT ViewportY, FLOAT ViewportWidth, FLOAT ViewportHeight, FLOAT ViewportMinZ, FLOAT ViewportMaxZ, + CXMMATRIX Projection, CXMMATRIX View, CXMMATRIX World); +XMVECTOR XMVector3Unproject(FXMVECTOR V, FLOAT ViewportX, FLOAT ViewportY, FLOAT ViewportWidth, FLOAT ViewportHeight, FLOAT ViewportMinZ, FLOAT ViewportMaxZ, + CXMMATRIX Projection, CXMMATRIX View, CXMMATRIX World); +XMFLOAT3* XMVector3UnprojectStream(_Out_bytecap_x_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) CONST XMFLOAT3* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, + FLOAT ViewportX, FLOAT ViewportY, FLOAT ViewportWidth, FLOAT ViewportHeight, FLOAT ViewportMinZ, FLOAT ViewportMaxZ, + CXMMATRIX Projection, CXMMATRIX View, CXMMATRIX World); + +/**************************************************************************** + * + * 4D vector operations + * + ****************************************************************************/ + +BOOL XMVector4Equal(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector4EqualR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4EqualInt(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector4EqualIntR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4NearEqual(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR Epsilon); +BOOL XMVector4NotEqual(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4NotEqualInt(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4Greater(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector4GreaterR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4GreaterOrEqual(FXMVECTOR V1, FXMVECTOR V2); +UINT XMVector4GreaterOrEqualR(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4Less(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4LessOrEqual(FXMVECTOR V1, FXMVECTOR V2); +BOOL XMVector4InBounds(FXMVECTOR V, FXMVECTOR Bounds); +UINT XMVector4InBoundsR(FXMVECTOR V, FXMVECTOR Bounds); + +BOOL XMVector4IsNaN(FXMVECTOR V); +BOOL XMVector4IsInfinite(FXMVECTOR V); + +XMVECTOR XMVector4Dot(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector4Cross(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR V3); +XMVECTOR XMVector4LengthSq(FXMVECTOR V); +XMVECTOR XMVector4ReciprocalLengthEst(FXMVECTOR V); +XMVECTOR XMVector4ReciprocalLength(FXMVECTOR V); +XMVECTOR XMVector4LengthEst(FXMVECTOR V); +XMVECTOR XMVector4Length(FXMVECTOR V); +XMVECTOR XMVector4NormalizeEst(FXMVECTOR V); +XMVECTOR XMVector4Normalize(FXMVECTOR V); +XMVECTOR XMVector4ClampLength(FXMVECTOR V, FLOAT LengthMin, FLOAT LengthMax); +XMVECTOR XMVector4ClampLengthV(FXMVECTOR V, FXMVECTOR LengthMin, FXMVECTOR LengthMax); +XMVECTOR XMVector4Reflect(FXMVECTOR Incident, FXMVECTOR Normal); +XMVECTOR XMVector4Refract(FXMVECTOR Incident, FXMVECTOR Normal, FLOAT RefractionIndex); +XMVECTOR XMVector4RefractV(FXMVECTOR Incident, FXMVECTOR Normal, FXMVECTOR RefractionIndex); +XMVECTOR XMVector4Orthogonal(FXMVECTOR V); +XMVECTOR XMVector4AngleBetweenNormalsEst(FXMVECTOR N1, FXMVECTOR N2); +XMVECTOR XMVector4AngleBetweenNormals(FXMVECTOR N1, FXMVECTOR N2); +XMVECTOR XMVector4AngleBetweenVectors(FXMVECTOR V1, FXMVECTOR V2); +XMVECTOR XMVector4Transform(FXMVECTOR V, CXMMATRIX M); +XMFLOAT4* XMVector4TransformStream(_Out_bytecap_x_(sizeof(XMFLOAT4)+OutputStride*(VectorCount-1)) XMFLOAT4* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT4)+InputStride*(VectorCount-1)) CONST XMFLOAT4* pInputStream, + _In_ UINT InputStride, _In_ UINT VectorCount, CXMMATRIX M); + +/**************************************************************************** + * + * Matrix operations + * + ****************************************************************************/ + +BOOL XMMatrixIsNaN(CXMMATRIX M); +BOOL XMMatrixIsInfinite(CXMMATRIX M); +BOOL XMMatrixIsIdentity(CXMMATRIX M); + +XMMATRIX XMMatrixMultiply(CXMMATRIX M1, CXMMATRIX M2); +XMMATRIX XMMatrixMultiplyTranspose(CXMMATRIX M1, CXMMATRIX M2); +XMMATRIX XMMatrixTranspose(CXMMATRIX M); +XMMATRIX XMMatrixInverse(_Out_ XMVECTOR* pDeterminant, CXMMATRIX M); +XMVECTOR XMMatrixDeterminant(CXMMATRIX M); +BOOL XMMatrixDecompose(_Out_ XMVECTOR *outScale, _Out_ XMVECTOR *outRotQuat, _Out_ XMVECTOR *outTrans, CXMMATRIX M); + +XMMATRIX XMMatrixIdentity(); +XMMATRIX XMMatrixSet(FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03, + FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13, + FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23, + FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33); +XMMATRIX XMMatrixTranslation(FLOAT OffsetX, FLOAT OffsetY, FLOAT OffsetZ); +XMMATRIX XMMatrixTranslationFromVector(FXMVECTOR Offset); +XMMATRIX XMMatrixScaling(FLOAT ScaleX, FLOAT ScaleY, FLOAT ScaleZ); +XMMATRIX XMMatrixScalingFromVector(FXMVECTOR Scale); +XMMATRIX XMMatrixRotationX(FLOAT Angle); +XMMATRIX XMMatrixRotationY(FLOAT Angle); +XMMATRIX XMMatrixRotationZ(FLOAT Angle); +XMMATRIX XMMatrixRotationRollPitchYaw(FLOAT Pitch, FLOAT Yaw, FLOAT Roll); +XMMATRIX XMMatrixRotationRollPitchYawFromVector(FXMVECTOR Angles); +XMMATRIX XMMatrixRotationNormal(FXMVECTOR NormalAxis, FLOAT Angle); +XMMATRIX XMMatrixRotationAxis(FXMVECTOR Axis, FLOAT Angle); +XMMATRIX XMMatrixRotationQuaternion(FXMVECTOR Quaternion); +XMMATRIX XMMatrixTransformation2D(FXMVECTOR ScalingOrigin, FLOAT ScalingOrientation, FXMVECTOR Scaling, + FXMVECTOR RotationOrigin, FLOAT Rotation, CXMVECTOR Translation); +XMMATRIX XMMatrixTransformation(FXMVECTOR ScalingOrigin, FXMVECTOR ScalingOrientationQuaternion, FXMVECTOR Scaling, + CXMVECTOR RotationOrigin, CXMVECTOR RotationQuaternion, CXMVECTOR Translation); +XMMATRIX XMMatrixAffineTransformation2D(FXMVECTOR Scaling, FXMVECTOR RotationOrigin, FLOAT Rotation, FXMVECTOR Translation); +XMMATRIX XMMatrixAffineTransformation(FXMVECTOR Scaling, FXMVECTOR RotationOrigin, FXMVECTOR RotationQuaternion, CXMVECTOR Translation); +XMMATRIX XMMatrixReflect(FXMVECTOR ReflectionPlane); +XMMATRIX XMMatrixShadow(FXMVECTOR ShadowPlane, FXMVECTOR LightPosition); + +XMMATRIX XMMatrixLookAtLH(FXMVECTOR EyePosition, FXMVECTOR FocusPosition, FXMVECTOR UpDirection); +XMMATRIX XMMatrixLookAtRH(FXMVECTOR EyePosition, FXMVECTOR FocusPosition, FXMVECTOR UpDirection); +XMMATRIX XMMatrixLookToLH(FXMVECTOR EyePosition, FXMVECTOR EyeDirection, FXMVECTOR UpDirection); +XMMATRIX XMMatrixLookToRH(FXMVECTOR EyePosition, FXMVECTOR EyeDirection, FXMVECTOR UpDirection); +XMMATRIX XMMatrixPerspectiveLH(FLOAT ViewWidth, FLOAT ViewHeight, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixPerspectiveRH(FLOAT ViewWidth, FLOAT ViewHeight, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixPerspectiveFovLH(FLOAT FovAngleY, FLOAT AspectHByW, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixPerspectiveFovRH(FLOAT FovAngleY, FLOAT AspectHByW, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixPerspectiveOffCenterLH(FLOAT ViewLeft, FLOAT ViewRight, FLOAT ViewBottom, FLOAT ViewTop, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixPerspectiveOffCenterRH(FLOAT ViewLeft, FLOAT ViewRight, FLOAT ViewBottom, FLOAT ViewTop, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixOrthographicLH(FLOAT ViewWidth, FLOAT ViewHeight, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixOrthographicRH(FLOAT ViewWidth, FLOAT ViewHeight, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixOrthographicOffCenterLH(FLOAT ViewLeft, FLOAT ViewRight, FLOAT ViewBottom, FLOAT ViewTop, FLOAT NearZ, FLOAT FarZ); +XMMATRIX XMMatrixOrthographicOffCenterRH(FLOAT ViewLeft, FLOAT ViewRight, FLOAT ViewBottom, FLOAT ViewTop, FLOAT NearZ, FLOAT FarZ); + +/**************************************************************************** + * + * Quaternion operations + * + ****************************************************************************/ + +BOOL XMQuaternionEqual(FXMVECTOR Q1, FXMVECTOR Q2); +BOOL XMQuaternionNotEqual(FXMVECTOR Q1, FXMVECTOR Q2); + +BOOL XMQuaternionIsNaN(FXMVECTOR Q); +BOOL XMQuaternionIsInfinite(FXMVECTOR Q); +BOOL XMQuaternionIsIdentity(FXMVECTOR Q); + +XMVECTOR XMQuaternionDot(FXMVECTOR Q1, FXMVECTOR Q2); +XMVECTOR XMQuaternionMultiply(FXMVECTOR Q1, FXMVECTOR Q2); +XMVECTOR XMQuaternionLengthSq(FXMVECTOR Q); +XMVECTOR XMQuaternionReciprocalLength(FXMVECTOR Q); +XMVECTOR XMQuaternionLength(FXMVECTOR Q); +XMVECTOR XMQuaternionNormalizeEst(FXMVECTOR Q); +XMVECTOR XMQuaternionNormalize(FXMVECTOR Q); +XMVECTOR XMQuaternionConjugate(FXMVECTOR Q); +XMVECTOR XMQuaternionInverse(FXMVECTOR Q); +XMVECTOR XMQuaternionLn(FXMVECTOR Q); +XMVECTOR XMQuaternionExp(FXMVECTOR Q); +XMVECTOR XMQuaternionSlerp(FXMVECTOR Q0, FXMVECTOR Q1, FLOAT t); +XMVECTOR XMQuaternionSlerpV(FXMVECTOR Q0, FXMVECTOR Q1, FXMVECTOR T); +XMVECTOR XMQuaternionSquad(FXMVECTOR Q0, FXMVECTOR Q1, FXMVECTOR Q2, CXMVECTOR Q3, FLOAT t); +XMVECTOR XMQuaternionSquadV(FXMVECTOR Q0, FXMVECTOR Q1, FXMVECTOR Q2, CXMVECTOR Q3, CXMVECTOR T); +VOID XMQuaternionSquadSetup(_Out_ XMVECTOR* pA, _Out_ XMVECTOR* pB, _Out_ XMVECTOR* pC, FXMVECTOR Q0, FXMVECTOR Q1, FXMVECTOR Q2, CXMVECTOR Q3); +XMVECTOR XMQuaternionBaryCentric(FXMVECTOR Q0, FXMVECTOR Q1, FXMVECTOR Q2, FLOAT f, FLOAT g); +XMVECTOR XMQuaternionBaryCentricV(FXMVECTOR Q0, FXMVECTOR Q1, FXMVECTOR Q2, CXMVECTOR F, CXMVECTOR G); + +XMVECTOR XMQuaternionIdentity(); +XMVECTOR XMQuaternionRotationRollPitchYaw(FLOAT Pitch, FLOAT Yaw, FLOAT Roll); +XMVECTOR XMQuaternionRotationRollPitchYawFromVector(FXMVECTOR Angles); +XMVECTOR XMQuaternionRotationNormal(FXMVECTOR NormalAxis, FLOAT Angle); +XMVECTOR XMQuaternionRotationAxis(FXMVECTOR Axis, FLOAT Angle); +XMVECTOR XMQuaternionRotationMatrix(CXMMATRIX M); + +VOID XMQuaternionToAxisAngle(_Out_ XMVECTOR* pAxis, _Out_ FLOAT* pAngle, FXMVECTOR Q); + +/**************************************************************************** + * + * Plane operations + * + ****************************************************************************/ + +BOOL XMPlaneEqual(FXMVECTOR P1, FXMVECTOR P2); +BOOL XMPlaneNearEqual(FXMVECTOR P1, FXMVECTOR P2, FXMVECTOR Epsilon); +BOOL XMPlaneNotEqual(FXMVECTOR P1, FXMVECTOR P2); + +BOOL XMPlaneIsNaN(FXMVECTOR P); +BOOL XMPlaneIsInfinite(FXMVECTOR P); + +XMVECTOR XMPlaneDot(FXMVECTOR P, FXMVECTOR V); +XMVECTOR XMPlaneDotCoord(FXMVECTOR P, FXMVECTOR V); +XMVECTOR XMPlaneDotNormal(FXMVECTOR P, FXMVECTOR V); +XMVECTOR XMPlaneNormalizeEst(FXMVECTOR P); +XMVECTOR XMPlaneNormalize(FXMVECTOR P); +XMVECTOR XMPlaneIntersectLine(FXMVECTOR P, FXMVECTOR LinePoint1, FXMVECTOR LinePoint2); +VOID XMPlaneIntersectPlane(_Out_ XMVECTOR* pLinePoint1, _Out_ XMVECTOR* pLinePoint2, FXMVECTOR P1, FXMVECTOR P2); +XMVECTOR XMPlaneTransform(FXMVECTOR P, CXMMATRIX M); +XMFLOAT4* XMPlaneTransformStream(_Out_bytecap_x_(sizeof(XMFLOAT4)+OutputStride*(PlaneCount-1)) XMFLOAT4* pOutputStream, + _In_ UINT OutputStride, + _In_bytecount_x_(sizeof(XMFLOAT4)+InputStride*(PlaneCount-1)) CONST XMFLOAT4* pInputStream, + _In_ UINT InputStride, _In_ UINT PlaneCount, CXMMATRIX M); + +XMVECTOR XMPlaneFromPointNormal(FXMVECTOR Point, FXMVECTOR Normal); +XMVECTOR XMPlaneFromPoints(FXMVECTOR Point1, FXMVECTOR Point2, FXMVECTOR Point3); + +/**************************************************************************** + * + * Color operations + * + ****************************************************************************/ + +BOOL XMColorEqual(FXMVECTOR C1, FXMVECTOR C2); +BOOL XMColorNotEqual(FXMVECTOR C1, FXMVECTOR C2); +BOOL XMColorGreater(FXMVECTOR C1, FXMVECTOR C2); +BOOL XMColorGreaterOrEqual(FXMVECTOR C1, FXMVECTOR C2); +BOOL XMColorLess(FXMVECTOR C1, FXMVECTOR C2); +BOOL XMColorLessOrEqual(FXMVECTOR C1, FXMVECTOR C2); + +BOOL XMColorIsNaN(FXMVECTOR C); +BOOL XMColorIsInfinite(FXMVECTOR C); + +XMVECTOR XMColorNegative(FXMVECTOR C); +XMVECTOR XMColorModulate(FXMVECTOR C1, FXMVECTOR C2); +XMVECTOR XMColorAdjustSaturation(FXMVECTOR C, FLOAT Saturation); +XMVECTOR XMColorAdjustContrast(FXMVECTOR C, FLOAT Contrast); + +/**************************************************************************** + * + * Miscellaneous operations + * + ****************************************************************************/ + +BOOL XMVerifyCPUSupport(); + +VOID XMAssert(_In_z_ CONST CHAR* pExpression, _In_z_ CONST CHAR* pFileName, UINT LineNumber); + +XMVECTOR XMFresnelTerm(FXMVECTOR CosIncidentAngle, FXMVECTOR RefractionIndex); + +BOOL XMScalarNearEqual(FLOAT S1, FLOAT S2, FLOAT Epsilon); +FLOAT XMScalarModAngle(FLOAT Value); +FLOAT XMScalarSin(FLOAT Value); +FLOAT XMScalarCos(FLOAT Value); +VOID XMScalarSinCos(_Out_ FLOAT* pSin, _Out_ FLOAT* pCos, FLOAT Value); +FLOAT XMScalarASin(FLOAT Value); +FLOAT XMScalarACos(FLOAT Value); +FLOAT XMScalarSinEst(FLOAT Value); +FLOAT XMScalarCosEst(FLOAT Value); +VOID XMScalarSinCosEst(_Out_ FLOAT* pSin, _Out_ FLOAT* pCos, FLOAT Value); +FLOAT XMScalarASinEst(FLOAT Value); +FLOAT XMScalarACosEst(FLOAT Value); + +/**************************************************************************** + * + * Globals + * + ****************************************************************************/ + +// The purpose of the following global constants is to prevent redundant +// reloading of the constants when they are referenced by more than one +// separate inline math routine called within the same function. Declaring +// a constant locally within a routine is sufficient to prevent redundant +// reloads of that constant when that single routine is called multiple +// times in a function, but if the constant is used (and declared) in a +// separate math routine it would be reloaded. + +#define XMGLOBALCONST extern CONST __declspec(selectany) + +XMGLOBALCONST XMVECTORF32 g_XMSinCoefficients0 = {1.0f, -0.166666667f, 8.333333333e-3f, -1.984126984e-4f}; +XMGLOBALCONST XMVECTORF32 g_XMSinCoefficients1 = {2.755731922e-6f, -2.505210839e-8f, 1.605904384e-10f, -7.647163732e-13f}; +XMGLOBALCONST XMVECTORF32 g_XMSinCoefficients2 = {2.811457254e-15f, -8.220635247e-18f, 1.957294106e-20f, -3.868170171e-23f}; +XMGLOBALCONST XMVECTORF32 g_XMCosCoefficients0 = {1.0f, -0.5f, 4.166666667e-2f, -1.388888889e-3f}; +XMGLOBALCONST XMVECTORF32 g_XMCosCoefficients1 = {2.480158730e-5f, -2.755731922e-7f, 2.087675699e-9f, -1.147074560e-11f}; +XMGLOBALCONST XMVECTORF32 g_XMCosCoefficients2 = {4.779477332e-14f, -1.561920697e-16f, 4.110317623e-19f, -8.896791392e-22f}; +XMGLOBALCONST XMVECTORF32 g_XMTanCoefficients0 = {1.0f, 0.333333333f, 0.133333333f, 5.396825397e-2f}; +XMGLOBALCONST XMVECTORF32 g_XMTanCoefficients1 = {2.186948854e-2f, 8.863235530e-3f, 3.592128167e-3f, 1.455834485e-3f}; +XMGLOBALCONST XMVECTORF32 g_XMTanCoefficients2 = {5.900274264e-4f, 2.391290764e-4f, 9.691537707e-5f, 3.927832950e-5f}; +XMGLOBALCONST XMVECTORF32 g_XMASinCoefficients0 = {-0.05806367563904f, -0.41861972469416f, 0.22480114791621f, 2.17337241360606f}; +XMGLOBALCONST XMVECTORF32 g_XMASinCoefficients1 = {0.61657275907170f, 4.29696498283455f, -1.18942822255452f, -6.53784832094831f}; +XMGLOBALCONST XMVECTORF32 g_XMASinCoefficients2 = {-1.36926553863413f, -4.48179294237210f, 1.41810672941833f, 5.48179257935713f}; +XMGLOBALCONST XMVECTORF32 g_XMATanCoefficients0 = {1.0f, 0.333333334f, 0.2f, 0.142857143f}; +XMGLOBALCONST XMVECTORF32 g_XMATanCoefficients1 = {1.111111111e-1f, 9.090909091e-2f, 7.692307692e-2f, 6.666666667e-2f}; +XMGLOBALCONST XMVECTORF32 g_XMATanCoefficients2 = {5.882352941e-2f, 5.263157895e-2f, 4.761904762e-2f, 4.347826087e-2f}; +XMGLOBALCONST XMVECTORF32 g_XMSinEstCoefficients = {1.0f, -1.66521856991541e-1f, 8.199913018755e-3f, -1.61475937228e-4f}; +XMGLOBALCONST XMVECTORF32 g_XMCosEstCoefficients = {1.0f, -4.95348008918096e-1f, 3.878259962881e-2f, -9.24587976263e-4f}; +XMGLOBALCONST XMVECTORF32 g_XMTanEstCoefficients = {2.484f, -1.954923183e-1f, 2.467401101f, XM_1DIVPI}; +XMGLOBALCONST XMVECTORF32 g_XMATanEstCoefficients = {7.689891418951e-1f, 1.104742493348f, 8.661844266006e-1f, XM_PIDIV2}; +XMGLOBALCONST XMVECTORF32 g_XMASinEstCoefficients = {-1.36178272886711f, 2.37949493464538f, -8.08228565650486e-1f, 2.78440142746736e-1f}; +XMGLOBALCONST XMVECTORF32 g_XMASinEstConstants = {1.00000011921f, XM_PIDIV2, 0.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMPiConstants0 = {XM_PI, XM_2PI, XM_1DIVPI, XM_1DIV2PI}; +XMGLOBALCONST XMVECTORF32 g_XMIdentityR0 = {1.0f, 0.0f, 0.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMIdentityR1 = {0.0f, 1.0f, 0.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMIdentityR2 = {0.0f, 0.0f, 1.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMIdentityR3 = {0.0f, 0.0f, 0.0f, 1.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegIdentityR0 = {-1.0f,0.0f, 0.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegIdentityR1 = {0.0f,-1.0f, 0.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegIdentityR2 = {0.0f, 0.0f,-1.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegIdentityR3 = {0.0f, 0.0f, 0.0f,-1.0f}; +XMGLOBALCONST XMVECTORI32 g_XMNegativeZero = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; +XMGLOBALCONST XMVECTORI32 g_XMNegate3 = {0x80000000, 0x80000000, 0x80000000, 0x00000000}; +XMGLOBALCONST XMVECTORI32 g_XMMask3 = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000}; +XMGLOBALCONST XMVECTORI32 g_XMMaskX = {0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000}; +XMGLOBALCONST XMVECTORI32 g_XMMaskY = {0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000}; +XMGLOBALCONST XMVECTORI32 g_XMMaskZ = {0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000}; +XMGLOBALCONST XMVECTORI32 g_XMMaskW = {0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF}; +XMGLOBALCONST XMVECTORF32 g_XMOne = { 1.0f, 1.0f, 1.0f, 1.0f}; +XMGLOBALCONST XMVECTORF32 g_XMOne3 = { 1.0f, 1.0f, 1.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMZero = { 0.0f, 0.0f, 0.0f, 0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegativeOne = {-1.0f,-1.0f,-1.0f,-1.0f}; +XMGLOBALCONST XMVECTORF32 g_XMOneHalf = { 0.5f, 0.5f, 0.5f, 0.5f}; +XMGLOBALCONST XMVECTORF32 g_XMNegativeOneHalf = {-0.5f,-0.5f,-0.5f,-0.5f}; +XMGLOBALCONST XMVECTORF32 g_XMNegativeTwoPi = {-XM_2PI, -XM_2PI, -XM_2PI, -XM_2PI}; +XMGLOBALCONST XMVECTORF32 g_XMNegativePi = {-XM_PI, -XM_PI, -XM_PI, -XM_PI}; +XMGLOBALCONST XMVECTORF32 g_XMHalfPi = {XM_PIDIV2, XM_PIDIV2, XM_PIDIV2, XM_PIDIV2}; +XMGLOBALCONST XMVECTORF32 g_XMPi = {XM_PI, XM_PI, XM_PI, XM_PI}; +XMGLOBALCONST XMVECTORF32 g_XMReciprocalPi = {XM_1DIVPI, XM_1DIVPI, XM_1DIVPI, XM_1DIVPI}; +XMGLOBALCONST XMVECTORF32 g_XMTwoPi = {XM_2PI, XM_2PI, XM_2PI, XM_2PI}; +XMGLOBALCONST XMVECTORF32 g_XMReciprocalTwoPi = {XM_1DIV2PI, XM_1DIV2PI, XM_1DIV2PI, XM_1DIV2PI}; +XMGLOBALCONST XMVECTORF32 g_XMEpsilon = {1.192092896e-7f, 1.192092896e-7f, 1.192092896e-7f, 1.192092896e-7f}; +XMGLOBALCONST XMVECTORI32 g_XMInfinity = {0x7F800000, 0x7F800000, 0x7F800000, 0x7F800000}; +XMGLOBALCONST XMVECTORI32 g_XMQNaN = {0x7FC00000, 0x7FC00000, 0x7FC00000, 0x7FC00000}; +XMGLOBALCONST XMVECTORI32 g_XMQNaNTest = {0x007FFFFF, 0x007FFFFF, 0x007FFFFF, 0x007FFFFF}; +XMGLOBALCONST XMVECTORI32 g_XMAbsMask = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}; +XMGLOBALCONST XMVECTORI32 g_XMFltMin = {0x00800000, 0x00800000, 0x00800000, 0x00800000}; +XMGLOBALCONST XMVECTORI32 g_XMFltMax = {0x7F7FFFFF, 0x7F7FFFFF, 0x7F7FFFFF, 0x7F7FFFFF}; +XMGLOBALCONST XMVECTORI32 g_XMNegOneMask = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; +XMGLOBALCONST XMVECTORI32 g_XMMaskA8R8G8B8 = {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}; +XMGLOBALCONST XMVECTORI32 g_XMFlipA8R8G8B8 = {0x00000000, 0x00000000, 0x00000000, 0x80000000}; +XMGLOBALCONST XMVECTORF32 g_XMFixAA8R8G8B8 = {0.0f,0.0f,0.0f,(float)(0x80000000U)}; +XMGLOBALCONST XMVECTORF32 g_XMNormalizeA8R8G8B8 = {1.0f/(255.0f*(float)(0x10000)),1.0f/(255.0f*(float)(0x100)),1.0f/255.0f,1.0f/(255.0f*(float)(0x1000000))}; +XMGLOBALCONST XMVECTORI32 g_XMMaskA2B10G10R10 = {0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000}; +XMGLOBALCONST XMVECTORI32 g_XMFlipA2B10G10R10 = {0x00000200, 0x00080000, 0x20000000, 0x80000000}; +XMGLOBALCONST XMVECTORF32 g_XMFixAA2B10G10R10 = {-512.0f,-512.0f*(float)(0x400),-512.0f*(float)(0x100000),(float)(0x80000000U)}; +XMGLOBALCONST XMVECTORF32 g_XMNormalizeA2B10G10R10 = {1.0f/511.0f,1.0f/(511.0f*(float)(0x400)),1.0f/(511.0f*(float)(0x100000)),1.0f/(3.0f*(float)(0x40000000))}; +XMGLOBALCONST XMVECTORI32 g_XMMaskX16Y16 = {0x0000FFFF, 0xFFFF0000, 0x00000000, 0x00000000}; +XMGLOBALCONST XMVECTORI32 g_XMFlipX16Y16 = {0x00008000, 0x00000000, 0x00000000, 0x00000000}; +XMGLOBALCONST XMVECTORF32 g_XMFixX16Y16 = {-32768.0f,0.0f,0.0f,0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNormalizeX16Y16 = {1.0f/32767.0f,1.0f/(32767.0f*65536.0f),0.0f,0.0f}; +XMGLOBALCONST XMVECTORI32 g_XMMaskX16Y16Z16W16 = {0x0000FFFF, 0x0000FFFF, 0xFFFF0000, 0xFFFF0000}; +XMGLOBALCONST XMVECTORI32 g_XMFlipX16Y16Z16W16 = {0x00008000, 0x00008000, 0x00000000, 0x00000000}; +XMGLOBALCONST XMVECTORF32 g_XMFixX16Y16Z16W16 = {-32768.0f,-32768.0f,0.0f,0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNormalizeX16Y16Z16W16 = {1.0f/32767.0f,1.0f/32767.0f,1.0f/(32767.0f*65536.0f),1.0f/(32767.0f*65536.0f)}; +XMGLOBALCONST XMVECTORF32 g_XMNoFraction = {8388608.0f,8388608.0f,8388608.0f,8388608.0f}; +XMGLOBALCONST XMVECTORI32 g_XMMaskByte = {0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF}; +XMGLOBALCONST XMVECTORF32 g_XMNegateX = {-1.0f, 1.0f, 1.0f, 1.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegateY = { 1.0f,-1.0f, 1.0f, 1.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegateZ = { 1.0f, 1.0f,-1.0f, 1.0f}; +XMGLOBALCONST XMVECTORF32 g_XMNegateW = { 1.0f, 1.0f, 1.0f,-1.0f}; +XMGLOBALCONST XMVECTORI32 g_XMSelect0101 = {XM_SELECT_0, XM_SELECT_1, XM_SELECT_0, XM_SELECT_1}; +XMGLOBALCONST XMVECTORI32 g_XMSelect1010 = {XM_SELECT_1, XM_SELECT_0, XM_SELECT_1, XM_SELECT_0}; +XMGLOBALCONST XMVECTORI32 g_XMOneHalfMinusEpsilon = { 0x3EFFFFFD, 0x3EFFFFFD, 0x3EFFFFFD, 0x3EFFFFFD}; +XMGLOBALCONST XMVECTORI32 g_XMSelect1000 = {XM_SELECT_1, XM_SELECT_0, XM_SELECT_0, XM_SELECT_0}; +XMGLOBALCONST XMVECTORI32 g_XMSelect1100 = {XM_SELECT_1, XM_SELECT_1, XM_SELECT_0, XM_SELECT_0}; +XMGLOBALCONST XMVECTORI32 g_XMSelect1110 = {XM_SELECT_1, XM_SELECT_1, XM_SELECT_1, XM_SELECT_0}; +XMGLOBALCONST XMVECTORI32 g_XMSwizzleXYXY = {XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0X, XM_PERMUTE_0Y}; +XMGLOBALCONST XMVECTORI32 g_XMSwizzleXYZX = {XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0X}; +XMGLOBALCONST XMVECTORI32 g_XMSwizzleYXZW = {XM_PERMUTE_0Y, XM_PERMUTE_0X, XM_PERMUTE_0Z, XM_PERMUTE_0W}; +XMGLOBALCONST XMVECTORI32 g_XMSwizzleYZXW = {XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0X, XM_PERMUTE_0W}; +XMGLOBALCONST XMVECTORI32 g_XMSwizzleZXYW = {XM_PERMUTE_0Z, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0W}; +XMGLOBALCONST XMVECTORI32 g_XMPermute0X0Y1X1Y = {XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_1X, XM_PERMUTE_1Y}; +XMGLOBALCONST XMVECTORI32 g_XMPermute0Z0W1Z1W = {XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_1Z, XM_PERMUTE_1W}; +XMGLOBALCONST XMVECTORF32 g_XMFixupY16 = {1.0f,1.0f/65536.0f,0.0f,0.0f}; +XMGLOBALCONST XMVECTORF32 g_XMFixupY16W16 = {1.0f,1.0f,1.0f/65536.0f,1.0f/65536.0f}; +XMGLOBALCONST XMVECTORI32 g_XMFlipY = {0,0x80000000,0,0}; +XMGLOBALCONST XMVECTORI32 g_XMFlipZ = {0,0,0x80000000,0}; +XMGLOBALCONST XMVECTORI32 g_XMFlipW = {0,0,0,0x80000000}; +XMGLOBALCONST XMVECTORI32 g_XMFlipYZ = {0,0x80000000,0x80000000,0}; +XMGLOBALCONST XMVECTORI32 g_XMFlipZW = {0,0,0x80000000,0x80000000}; +XMGLOBALCONST XMVECTORI32 g_XMFlipYW = {0,0x80000000,0,0x80000000}; +XMGLOBALCONST XMVECTORI32 g_XMMaskHenD3 = {0x7FF,0x7ff<<11,0x3FF<<22,0}; +XMGLOBALCONST XMVECTORI32 g_XMMaskDHen3 = {0x3FF,0x7ff<<10,0x7FF<<21,0}; +XMGLOBALCONST XMVECTORF32 g_XMAddUHenD3 = {0,0,32768.0f*65536.0f,0}; +XMGLOBALCONST XMVECTORF32 g_XMAddHenD3 = {-1024.0f,-1024.0f*2048.0f,0,0}; +XMGLOBALCONST XMVECTORF32 g_XMAddDHen3 = {-512.0f,-1024.0f*1024.0f,0,0}; +XMGLOBALCONST XMVECTORF32 g_XMMulHenD3 = {1.0f,1.0f/2048.0f,1.0f/(2048.0f*2048.0f),0}; +XMGLOBALCONST XMVECTORF32 g_XMMulDHen3 = {1.0f,1.0f/1024.0f,1.0f/(1024.0f*2048.0f),0}; +XMGLOBALCONST XMVECTORI32 g_XMXorHenD3 = {0x400,0x400<<11,0,0}; +XMGLOBALCONST XMVECTORI32 g_XMXorDHen3 = {0x200,0x400<<10,0,0}; +XMGLOBALCONST XMVECTORI32 g_XMMaskIco4 = {0xFFFFF,0xFFFFF000,0xFFFFF,0xF0000000}; +XMGLOBALCONST XMVECTORI32 g_XMXorXIco4 = {0x80000,0,0x80000,0x80000000}; +XMGLOBALCONST XMVECTORI32 g_XMXorIco4 = {0x80000,0,0x80000,0}; +XMGLOBALCONST XMVECTORF32 g_XMAddXIco4 = {-8.0f*65536.0f,0,-8.0f*65536.0f,32768.0f*65536.0f}; +XMGLOBALCONST XMVECTORF32 g_XMAddUIco4 = {0,32768.0f*65536.0f,0,32768.0f*65536.0f}; +XMGLOBALCONST XMVECTORF32 g_XMAddIco4 = {-8.0f*65536.0f,0,-8.0f*65536.0f,0}; +XMGLOBALCONST XMVECTORF32 g_XMMulIco4 = {1.0f,1.0f/4096.0f,1.0f,1.0f/(4096.0f*65536.0f)}; +XMGLOBALCONST XMVECTORI32 g_XMMaskDec4 = {0x3FF,0x3FF<<10,0x3FF<<20,0x3<<30}; +XMGLOBALCONST XMVECTORI32 g_XMXorDec4 = {0x200,0x200<<10,0x200<<20,0}; +XMGLOBALCONST XMVECTORF32 g_XMAddUDec4 = {0,0,0,32768.0f*65536.0f}; +XMGLOBALCONST XMVECTORF32 g_XMAddDec4 = {-512.0f,-512.0f*1024.0f,-512.0f*1024.0f*1024.0f,0}; +XMGLOBALCONST XMVECTORF32 g_XMMulDec4 = {1.0f,1.0f/1024.0f,1.0f/(1024.0f*1024.0f),1.0f/(1024.0f*1024.0f*1024.0f)}; +XMGLOBALCONST XMVECTORI32 g_XMMaskByte4 = {0xFF,0xFF00,0xFF0000,0xFF000000}; +XMGLOBALCONST XMVECTORI32 g_XMXorByte4 = {0x80,0x8000,0x800000,0x00000000}; +XMGLOBALCONST XMVECTORF32 g_XMAddByte4 = {-128.0f,-128.0f*256.0f,-128.0f*65536.0f,0}; + +/**************************************************************************** + * + * Implementation + * + ****************************************************************************/ + +#pragma warning(push) +#pragma warning(disable:4214 4204 4365 4616 6001) + +#if !defined(__cplusplus) && !defined(_XBOX) && defined(_XM_ISVS2005_) + +/* Work around VC 2005 bug where math.h defines logf with a semicolon at the end. + * Note this is fixed as of Visual Studio 2005 Service Pack 1 + */ + +#undef logf +#define logf(x) ((float)log((double)(x))) + +#endif // !defined(__cplusplus) && !defined(_XBOX) && defined(_XM_ISVS2005_) + +//------------------------------------------------------------------------------ + +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) + +XMFINLINE XMVECTOR XMVectorSetBinaryConstant(UINT C0, UINT C1, UINT C2, UINT C3) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTORU32 vResult; + vResult.u[0] = (0-(C0&1)) & 0x3F800000; + vResult.u[1] = (0-(C1&1)) & 0x3F800000; + vResult.u[2] = (0-(C2&1)) & 0x3F800000; + vResult.u[3] = (0-(C3&1)) & 0x3F800000; + return vResult.v; +#else // XM_SSE_INTRINSICS_ + static const XMVECTORU32 g_vMask1 = {1,1,1,1}; + // Move the parms to a vector + __m128i vTemp = _mm_set_epi32(C3,C2,C1,C0); + // Mask off the low bits + vTemp = _mm_and_si128(vTemp,g_vMask1); + // 0xFFFFFFFF on true bits + vTemp = _mm_cmpeq_epi32(vTemp,g_vMask1); + // 0xFFFFFFFF -> 1.0f, 0x00000000 -> 0.0f + vTemp = _mm_and_si128(vTemp,g_XMOne); + return reinterpret_cast(&vTemp)[0]; +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSplatConstant(INT IntConstant, UINT DivExponent) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT( IntConstant >= -16 && IntConstant <= 15 ); + XMASSERT(DivExponent<32); + { + XMVECTORI32 V = { IntConstant, IntConstant, IntConstant, IntConstant }; + return XMConvertVectorIntToFloat( V.v, DivExponent); + } +#else // XM_SSE_INTRINSICS_ + XMASSERT( IntConstant >= -16 && IntConstant <= 15 ); + XMASSERT(DivExponent<32); + // Splat the int + __m128i vScale = _mm_set1_epi32(IntConstant); + // Convert to a float + XMVECTOR vResult = _mm_cvtepi32_ps(vScale); + // Convert DivExponent into 1.0f/(1<(&vScale)[0]); + return vResult; +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSplatConstantInt(INT IntConstant) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT( IntConstant >= -16 && IntConstant <= 15 ); + { + XMVECTORI32 V = { IntConstant, IntConstant, IntConstant, IntConstant }; + return V.v; + } +#else // XM_SSE_INTRINSICS_ + XMASSERT( IntConstant >= -16 && IntConstant <= 15 ); + __m128i V = _mm_set1_epi32( IntConstant ); + return reinterpret_cast<__m128 *>(&V)[0]; +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorShiftLeft(FXMVECTOR V1, FXMVECTOR V2, UINT Elements) +{ + return XMVectorPermute(V1, V2, XMVectorPermuteControl((Elements), ((Elements) + 1), ((Elements) + 2), ((Elements) + 3))); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorRotateLeft(FXMVECTOR V, UINT Elements) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT( Elements < 4 ); + { + XMVECTORF32 vResult = { V.vector4_f32[Elements & 3], V.vector4_f32[(Elements + 1) & 3], + V.vector4_f32[(Elements + 2) & 3], V.vector4_f32[(Elements + 3) & 3] }; + return vResult.v; + } +#else // XM_SSE_INTRINSICS_ + FLOAT fx = XMVectorGetByIndex(V,(Elements) & 3); + FLOAT fy = XMVectorGetByIndex(V,((Elements) + 1) & 3); + FLOAT fz = XMVectorGetByIndex(V,((Elements) + 2) & 3); + FLOAT fw = XMVectorGetByIndex(V,((Elements) + 3) & 3); + return _mm_set_ps( fw, fz, fy, fx ); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorRotateRight(FXMVECTOR V, UINT Elements) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT( Elements < 4 ); + { + XMVECTORF32 vResult = { V.vector4_f32[(4 - (Elements)) & 3], V.vector4_f32[(5 - (Elements)) & 3], + V.vector4_f32[(6 - (Elements)) & 3], V.vector4_f32[(7 - (Elements)) & 3] }; + return vResult.v; + } +#else // XM_SSE_INTRINSICS_ + FLOAT fx = XMVectorGetByIndex(V,(4 - (Elements)) & 3); + FLOAT fy = XMVectorGetByIndex(V,(5 - (Elements)) & 3); + FLOAT fz = XMVectorGetByIndex(V,(6 - (Elements)) & 3); + FLOAT fw = XMVectorGetByIndex(V,(7 - (Elements)) & 3); + return _mm_set_ps( fw, fz, fy, fx ); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSwizzle(FXMVECTOR V, UINT E0, UINT E1, UINT E2, UINT E3) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT( (E0 < 4) && (E1 < 4) && (E2 < 4) && (E3 < 4) ); + { + XMVECTORF32 vResult = { V.vector4_f32[E0], V.vector4_f32[E1], V.vector4_f32[E2], V.vector4_f32[E3] }; + return vResult.v; + } +#else // XM_SSE_INTRINSICS_ + FLOAT fx = XMVectorGetByIndex(V,E0); + FLOAT fy = XMVectorGetByIndex(V,E1); + FLOAT fz = XMVectorGetByIndex(V,E2); + FLOAT fw = XMVectorGetByIndex(V,E3); + return _mm_set_ps( fw, fz, fy, fx ); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorInsert(FXMVECTOR VD, FXMVECTOR VS, UINT VSLeftRotateElements, + UINT Select0, UINT Select1, UINT Select2, UINT Select3) +{ + XMVECTOR Control = XMVectorSelectControl(Select0&1, Select1&1, Select2&1, Select3&1); + return XMVectorSelect( VD, XMVectorRotateLeft(VS, VSLeftRotateElements), Control ); +} + +// Implemented for VMX128 intrinsics as #defines aboves +#endif _XM_NO_INTRINSICS_ || _XM_SSE_INTRINSICS_ + +//------------------------------------------------------------------------------ + +#include "xnamathconvert.inl" +#include "xnamathvector.inl" +#include "xnamathmatrix.inl" +#include "xnamathmisc.inl" + +#pragma warning(pop) + +#endif // __XNAMATH_H__ + diff --git a/dxsdk/Include/xnamathconvert.inl b/dxsdk/Include/xnamathconvert.inl new file mode 100644 index 0000000..370d27d --- /dev/null +++ b/dxsdk/Include/xnamathconvert.inl @@ -0,0 +1,5785 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + xnamathconvert.inl + +Abstract: + + XNA math library for Windows and Xbox 360: Conversion, loading, and storing functions. +--*/ + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __XNAMATHCONVERT_INL__ +#define __XNAMATHCONVERT_INL__ + +#define XM_PACK_FACTOR (FLOAT)(1 << 22) +#define XM_UNPACK_FACTOR_UNSIGNED (FLOAT)(1 << 23) +#define XM_UNPACK_FACTOR_SIGNED XM_PACK_FACTOR + +#define XM_UNPACK_UNSIGNEDN_OFFSET(BitsX, BitsY, BitsZ, BitsW) \ + {-XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsX)) - 1), \ + -XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsY)) - 1), \ + -XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsZ)) - 1), \ + -XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsW)) - 1)} + +#define XM_UNPACK_UNSIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \ + {XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsX)) - 1), \ + XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsY)) - 1), \ + XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsZ)) - 1), \ + XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsW)) - 1)} + +#define XM_UNPACK_SIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \ + {-XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsX) - 1)) - 1), \ + -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsY) - 1)) - 1), \ + -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsZ) - 1)) - 1), \ + -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsW) - 1)) - 1)} + +//#define XM_UNPACK_SIGNEDN_OFFSET(BitsX, BitsY, BitsZ, BitsW) \ +// {-XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsX) - 1)) - 1) * 3.0f, \ +// -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsY) - 1)) - 1) * 3.0f, \ +// -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsZ) - 1)) - 1) * 3.0f, \ +// -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsW) - 1)) - 1) * 3.0f} + +#define XM_PACK_UNSIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \ + {-(FLOAT)((1 << (BitsX)) - 1) / XM_PACK_FACTOR, \ + -(FLOAT)((1 << (BitsY)) - 1) / XM_PACK_FACTOR, \ + -(FLOAT)((1 << (BitsZ)) - 1) / XM_PACK_FACTOR, \ + -(FLOAT)((1 << (BitsW)) - 1) / XM_PACK_FACTOR} + +#define XM_PACK_SIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \ + {-(FLOAT)((1 << ((BitsX) - 1)) - 1) / XM_PACK_FACTOR, \ + -(FLOAT)((1 << ((BitsY) - 1)) - 1) / XM_PACK_FACTOR, \ + -(FLOAT)((1 << ((BitsZ) - 1)) - 1) / XM_PACK_FACTOR, \ + -(FLOAT)((1 << ((BitsW) - 1)) - 1) / XM_PACK_FACTOR} + +#define XM_PACK_OFFSET XMVectorSplatConstant(3, 0) +//#define XM_UNPACK_OFFSET XM_PACK_OFFSET + +/**************************************************************************** + * + * Data conversion + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE FLOAT XMConvertHalfToFloat +( + HALF Value +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) + + UINT Mantissa; + UINT Exponent; + UINT Result; + + Mantissa = (UINT)(Value & 0x03FF); + + if ((Value & 0x7C00) != 0) // The value is normalized + { + Exponent = (UINT)((Value >> 10) & 0x1F); + } + else if (Mantissa != 0) // The value is denormalized + { + // Normalize the value in the resulting float + Exponent = 1; + + do + { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x0400) == 0); + + Mantissa &= 0x03FF; + } + else // The value is zero + { + Exponent = (UINT)-112; + } + + Result = ((Value & 0x8000) << 16) | // Sign + ((Exponent + 112) << 23) | // Exponent + (Mantissa << 13); // Mantissa + + return *(FLOAT*)&Result; + +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif +} + +//------------------------------------------------------------------------------ + +XMINLINE FLOAT* XMConvertHalfToFloatStream +( + FLOAT* pOutputStream, + UINT OutputStride, + CONST HALF* pInputStream, + UINT InputStride, + UINT HalfCount +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) + + UINT i; + BYTE* pHalf = (BYTE*)pInputStream; + BYTE* pFloat = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < HalfCount; i++) + { + *(FLOAT*)pFloat = XMConvertHalfToFloat(*(HALF*)pHalf); + pHalf += InputStride; + pFloat += OutputStride; + } + + return pOutputStream; + +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE HALF XMConvertFloatToHalf +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) + UINT Result; + + UINT IValue = ((UINT *)(&Value))[0]; + UINT Sign = (IValue & 0x80000000U) >> 16U; + IValue = IValue & 0x7FFFFFFFU; // Hack off the sign + + if (IValue > 0x47FFEFFFU) + { + // The number is too large to be represented as a half. Saturate to infinity. + Result = 0x7FFFU; + } + else + { + if (IValue < 0x38800000U) + { + // The number is too small to be represented as a normalized half. + // Convert it to a denormalized value. + UINT Shift = 113U - (IValue >> 23U); + IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift; + } + else + { + // Rebias the exponent to represent the value as a normalized half. + IValue += 0xC8000000U; + } + + Result = ((IValue + 0x0FFFU + ((IValue >> 13U) & 1U)) >> 13U)&0x7FFFU; + } + return (HALF)(Result|Sign); + +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif +} + +//------------------------------------------------------------------------------ + +XMINLINE HALF* XMConvertFloatToHalfStream +( + HALF* pOutputStream, + UINT OutputStride, + CONST FLOAT* pInputStream, + UINT InputStride, + UINT FloatCount +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) + + UINT i; + BYTE* pFloat = (BYTE*)pInputStream; + BYTE* pHalf = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < FloatCount; i++) + { + *(HALF*)pHalf = XMConvertFloatToHalf(*(FLOAT*)pFloat); + pFloat += InputStride; + pHalf += OutputStride; + } + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) +// For VMX128, these routines are all defines in the main header + +#pragma warning(push) +#pragma warning(disable:4701) // Prevent warnings about 'Result' potentially being used without having been initialized + +XMINLINE XMVECTOR XMConvertVectorIntToFloat +( + FXMVECTOR VInt, + UINT DivExponent +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ElementIndex; + FLOAT fScale; + XMVECTOR Result; + XMASSERT(DivExponent<32); + fScale = 1.0f / (FLOAT)(1U << DivExponent); + ElementIndex = 0; + do { + INT iTemp = (INT)VInt.vector4_u32[ElementIndex]; + Result.vector4_f32[ElementIndex] = ((FLOAT)iTemp) * fScale; + } while (++ElementIndex<4); + return Result; +#else // _XM_SSE_INTRINSICS_ + XMASSERT(DivExponent<32); + // Convert to floats + XMVECTOR vResult = _mm_cvtepi32_ps(reinterpret_cast(&VInt)[0]); + // Convert DivExponent into 1.0f/(1<(&vScale)[0]); + return vResult; +#endif +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMConvertVectorFloatToInt +( + FXMVECTOR VFloat, + UINT MulExponent +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ElementIndex; + XMVECTOR Result; + FLOAT fScale; + XMASSERT(MulExponent<32); + // Get the scalar factor. + fScale = (FLOAT)(1U << MulExponent); + ElementIndex = 0; + do { + INT iResult; + FLOAT fTemp = VFloat.vector4_f32[ElementIndex]*fScale; + if (fTemp <= -(65536.0f*32768.0f)) { + iResult = (-0x7FFFFFFF)-1; + } else if (fTemp > (65536.0f*32768.0f)-128.0f) { + iResult = 0x7FFFFFFF; + } else { + iResult = (INT)fTemp; + } + Result.vector4_u32[ElementIndex] = (UINT)iResult; + } while (++ElementIndex<4); + return Result; +#else // _XM_SSE_INTRINSICS_ + XMASSERT(MulExponent<32); + static const XMVECTORF32 MaxInt = {65536.0f*32768.0f-128.0f,65536.0f*32768.0f-128.0f,65536.0f*32768.0f-128.0f,65536.0f*32768.0f-128.0f}; + XMVECTOR vResult = _mm_set_ps1((FLOAT)(1U << MulExponent)); + vResult = _mm_mul_ps(vResult,VFloat); + // In case of positive overflow, detect it + XMVECTOR vOverflow = _mm_cmpgt_ps(vResult,MaxInt); + // Float to int conversion + __m128i vResulti = _mm_cvttps_epi32(vResult); + // If there was positive overflow, set to 0x7FFFFFFF + vResult = _mm_and_ps(vOverflow,g_XMAbsMask); + vOverflow = _mm_andnot_ps(vOverflow,reinterpret_cast(&vResulti)[0]); + vOverflow = _mm_or_ps(vOverflow,vResult); + return vOverflow; +#endif +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMConvertVectorUIntToFloat +( + FXMVECTOR VUInt, + UINT DivExponent +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ElementIndex; + FLOAT fScale; + XMVECTOR Result; + XMASSERT(DivExponent<32); + fScale = 1.0f / (FLOAT)(1U << DivExponent); + ElementIndex = 0; + do { + Result.vector4_f32[ElementIndex] = (FLOAT)VUInt.vector4_u32[ElementIndex] * fScale; + } while (++ElementIndex<4); + return Result; +#else // _XM_SSE_INTRINSICS_ + XMASSERT(DivExponent<32); + static const XMVECTORF32 FixUnsigned = {32768.0f*65536.0f,32768.0f*65536.0f,32768.0f*65536.0f,32768.0f*65536.0f}; + // For the values that are higher than 0x7FFFFFFF, a fixup is needed + // Determine which ones need the fix. + XMVECTOR vMask = _mm_and_ps(VUInt,g_XMNegativeZero); + // Force all values positive + XMVECTOR vResult = _mm_xor_ps(VUInt,vMask); + // Convert to floats + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert 0x80000000 -> 0xFFFFFFFF + __m128i iMask = _mm_srai_epi32(reinterpret_cast(&vMask)[0],31); + // For only the ones that are too big, add the fixup + vMask = _mm_and_ps(reinterpret_cast(&iMask)[0],FixUnsigned); + vResult = _mm_add_ps(vResult,vMask); + // Convert DivExponent into 1.0f/(1<(&iMask)[0]); + return vResult; +#endif +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMConvertVectorFloatToUInt +( + FXMVECTOR VFloat, + UINT MulExponent +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ElementIndex; + XMVECTOR Result; + FLOAT fScale; + XMASSERT(MulExponent<32); + // Get the scalar factor. + fScale = (FLOAT)(1U << MulExponent); + ElementIndex = 0; + do { + UINT uResult; + FLOAT fTemp = VFloat.vector4_f32[ElementIndex]*fScale; + if (fTemp <= 0.0f) { + uResult = 0; + } else if (fTemp >= (65536.0f*65536.0f)) { + uResult = 0xFFFFFFFFU; + } else { + uResult = (UINT)fTemp; + } + Result.vector4_u32[ElementIndex] = uResult; + } while (++ElementIndex<4); + return Result; +#else // _XM_SSE_INTRINSICS_ + XMASSERT(MulExponent<32); + static const XMVECTORF32 MaxUInt = {65536.0f*65536.0f-256.0f,65536.0f*65536.0f-256.0f,65536.0f*65536.0f-256.0f,65536.0f*65536.0f-256.0f}; + static const XMVECTORF32 UnsignedFix = {32768.0f*65536.0f,32768.0f*65536.0f,32768.0f*65536.0f,32768.0f*65536.0f}; + XMVECTOR vResult = _mm_set_ps1(static_cast(1U << MulExponent)); + vResult = _mm_mul_ps(vResult,VFloat); + // Clamp to >=0 + vResult = _mm_max_ps(vResult,g_XMZero); + // Any numbers that are too big, set to 0xFFFFFFFFU + XMVECTOR vOverflow = _mm_cmpgt_ps(vResult,MaxUInt); + XMVECTOR vValue = UnsignedFix; + // Too large for a signed integer? + XMVECTOR vMask = _mm_cmpge_ps(vResult,vValue); + // Zero for number's lower than 0x80000000, 32768.0f*65536.0f otherwise + vValue = _mm_and_ps(vValue,vMask); + // Perform fixup only on numbers too large (Keeps low bit precision) + vResult = _mm_sub_ps(vResult,vValue); + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Convert from signed to unsigned pnly if greater than 0x80000000 + vMask = _mm_and_ps(vMask,g_XMNegativeZero); + vResult = _mm_xor_ps(reinterpret_cast(&vResulti)[0],vMask); + // On those that are too large, set to 0xFFFFFFFF + vResult = _mm_or_ps(vResult,vOverflow); + return vResult; +#endif +} + +#pragma warning(pop) + +#endif // _XM_NO_INTRINSICS_ || _XM_SSE_INTRINSICS_ + +/**************************************************************************** + * + * Vector and matrix load operations + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadInt(CONST UINT* pSource) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 3) == 0); + + V.vector4_u32[0] = *pSource; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 3) == 0); + + return _mm_load_ss( (const float*)pSource ); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat(CONST FLOAT* pSource) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 3) == 0); + + V.vector4_f32[0] = *pSource; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 3) == 0); + + return _mm_load_ss( pSource ); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadInt2 +( + CONST UINT* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_u32[0] = pSource[0]; + V.vector4_u32[1] = pSource[1]; + + return V; +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pSource); + + __m128 x = _mm_load_ss( (const float*)pSource ); + __m128 y = _mm_load_ss( (const float*)(pSource+1) ); + return _mm_unpacklo_ps( x, y ); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadInt2A +( + CONST UINT* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + V.vector4_u32[0] = pSource[0]; + V.vector4_u32[1] = pSource[1]; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + __m128i V = _mm_loadl_epi64( (const __m128i*)pSource ); + return reinterpret_cast<__m128 *>(&V)[0]; + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat2 +( + CONST XMFLOAT2* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR V; + XMASSERT(pSource); + + ((UINT *)(&V.vector4_f32[0]))[0] = ((const UINT *)(&pSource->x))[0]; + ((UINT *)(&V.vector4_f32[1]))[0] = ((const UINT *)(&pSource->y))[0]; + return V; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + + __m128 x = _mm_load_ss( &pSource->x ); + __m128 y = _mm_load_ss( &pSource->y ); + return _mm_unpacklo_ps( x, y ); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat2A +( + CONST XMFLOAT2A* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + V.vector4_f32[0] = pSource->x; + V.vector4_f32[1] = pSource->y; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + __m128i V = _mm_loadl_epi64( (const __m128i*)pSource ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadHalf2 +( + CONST XMHALF2* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT(pSource); + { + XMVECTOR vResult = { + XMConvertHalfToFloat(pSource->x), + XMConvertHalfToFloat(pSource->y), + 0.0f, + 0.0f + }; + return vResult; + } +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMVECTOR vResult = { + XMConvertHalfToFloat(pSource->x), + XMConvertHalfToFloat(pSource->y), + 0.0f, + 0.0f + }; + return vResult; + +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadShortN2 +( + CONST XMSHORTN2* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + { + XMVECTOR vResult = { + (FLOAT)pSource->x * (1.0f/32767.0f), + (FLOAT)pSource->y * (1.0f/32767.0f), + 0.0f, + 0.0f + }; + return vResult; + } + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + // Splat the two shorts in all four entries (WORD alignment okay, + // DWORD alignment preferred) + __m128 vTemp = _mm_load_ps1(reinterpret_cast(&pSource->x)); + // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0 + vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16); + // x needs to be sign extended + vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x - 0x8000 to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16); + // Convert 0-32767 to 0.0f-1.0f + return _mm_mul_ps(vTemp,g_XMNormalizeX16Y16); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadShort2 +( + CONST XMSHORT2* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + + V.vector4_f32[0] = (FLOAT)pSource->x; + V.vector4_f32[1] = (FLOAT)pSource->y; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + // Splat the two shorts in all four entries (WORD alignment okay, + // DWORD alignment preferred) + __m128 vTemp = _mm_load_ps1(reinterpret_cast(&pSource->x)); + // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0 + vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16); + // x needs to be sign extended + vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x - 0x8000 to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16); + // Y is 65536 too large + return _mm_mul_ps(vTemp,g_XMFixupY16); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUShortN2 +( + CONST XMUSHORTN2* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)pSource->x / 65535.0f; + V.vector4_f32[1] = (FLOAT)pSource->y / 65535.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 FixupY16 = {1.0f/65535.0f,1.0f/(65535.0f*65536.0f),0.0f,0.0f}; + static const XMVECTORF32 FixaddY16 = {0,32768.0f*65536.0f,0,0}; + XMASSERT(pSource); + // Splat the two shorts in all four entries (WORD alignment okay, + // DWORD alignment preferred) + __m128 vTemp = _mm_load_ps1(reinterpret_cast(&pSource->x)); + // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0 + vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16); + // y needs to be sign flipped + vTemp = _mm_xor_ps(vTemp,g_XMFlipY); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // y + 0x8000 to undo the signed order. + vTemp = _mm_add_ps(vTemp,FixaddY16); + // Y is 65536 times too large + vTemp = _mm_mul_ps(vTemp,FixupY16); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUShort2 +( + CONST XMUSHORT2* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)pSource->x; + V.vector4_f32[1] = (FLOAT)pSource->y; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 FixaddY16 = {0,32768.0f,0,0}; + XMASSERT(pSource); + // Splat the two shorts in all four entries (WORD alignment okay, + // DWORD alignment preferred) + __m128 vTemp = _mm_load_ps1(reinterpret_cast(&pSource->x)); + // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0 + vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16); + // y needs to be sign flipped + vTemp = _mm_xor_ps(vTemp,g_XMFlipY); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // Y is 65536 times too large + vTemp = _mm_mul_ps(vTemp,g_XMFixupY16); + // y + 0x8000 to undo the signed order. + vTemp = _mm_add_ps(vTemp,FixaddY16); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadInt3 +( + CONST UINT* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_u32[0] = pSource[0]; + V.vector4_u32[1] = pSource[1]; + V.vector4_u32[2] = pSource[2]; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + +#ifdef _XM_ISVS2005_ + __m128i V = _mm_set_epi32( 0, *(pSource+2), *(pSource+1), *pSource ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else + __m128 x = _mm_load_ss( (const float*)pSource ); + __m128 y = _mm_load_ss( (const float*)(pSource+1) ); + __m128 z = _mm_load_ss( (const float*)(pSource+2) ); + __m128 xy = _mm_unpacklo_ps( x, y ); + return _mm_movelh_ps( xy, z ); +#endif // !_XM_ISVS2005_ +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadInt3A +( + CONST UINT* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + V.vector4_u32[0] = pSource[0]; + V.vector4_u32[1] = pSource[1]; + V.vector4_u32[2] = pSource[2]; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + + // Reads an extra integer that is 'undefined' + + __m128i V = _mm_load_si128( (const __m128i*)pSource ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat3 +( + CONST XMFLOAT3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR V; + XMASSERT(pSource); + + ((UINT *)(&V.vector4_f32[0]))[0] = ((const UINT *)(&pSource->x))[0]; + ((UINT *)(&V.vector4_f32[1]))[0] = ((const UINT *)(&pSource->y))[0]; + ((UINT *)(&V.vector4_f32[2]))[0] = ((const UINT *)(&pSource->z))[0]; + return V; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + +#ifdef _XM_ISVS2005_ + // This reads 1 floats past the memory that should be ignored. + // Need to continue to do this for VS 2005 due to compiler issue but prefer new method + // to avoid triggering issues with memory debug tools (like AV) + return _mm_loadu_ps( &pSource->x ); +#else + __m128 x = _mm_load_ss( &pSource->x ); + __m128 y = _mm_load_ss( &pSource->y ); + __m128 z = _mm_load_ss( &pSource->z ); + __m128 xy = _mm_unpacklo_ps( x, y ); + return _mm_movelh_ps( xy, z ); +#endif // !_XM_ISVS2005_ +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat3A +( + CONST XMFLOAT3A* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + V.vector4_f32[0] = pSource->x; + V.vector4_f32[1] = pSource->y; + V.vector4_f32[2] = pSource->z; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + // This reads 1 floats past the memory that should be ignored. + return _mm_load_ps( &pSource->x ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUHenDN3 +( + CONST XMUHENDN3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x7FF; + V.vector4_f32[0] = (FLOAT)Element / 2047.0f; + Element = (pSource->v >> 11) & 0x7FF; + V.vector4_f32[1] = (FLOAT)Element / 2047.0f; + Element = (pSource->v >> 22) & 0x3FF; + V.vector4_f32[2] = (FLOAT)Element / 1023.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 UHenDN3Mul = {1.0f/2047.0f,1.0f/(2047.0f*2048.0f),1.0f/(1023.0f*2048.0f*2048.0f),0}; + XMASSERT(pSource); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskHenD3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMFlipZ); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddUHenD3); + // Normalize x,y and z to -1.0f-1.0f + vResult = _mm_mul_ps(vResult,UHenDN3Mul); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUHenD3 +( + CONST XMUHEND3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x7FF; + V.vector4_f32[0] = (FLOAT)Element; + Element = (pSource->v >> 11) & 0x7FF; + V.vector4_f32[1] = (FLOAT)Element; + Element = (pSource->v >> 22) & 0x3FF; + V.vector4_f32[2] = (FLOAT)Element; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskHenD3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMFlipZ); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddUHenD3); + // Normalize x and y to -1024-1023.0f and z to -512-511.0f + vResult = _mm_mul_ps(vResult,g_XMMulHenD3); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadHenDN3 +( + CONST XMHENDN3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtendXY[] = {0x00000000, 0xFFFFF800}; + static CONST UINT SignExtendZ[] = {0x00000000, 0xFFFFFC00}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200); + + Element = pSource->v & 0x7FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]) / 1023.0f; + Element = (pSource->v >> 11) & 0x7FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]) / 1023.0f; + Element = (pSource->v >> 22) & 0x3FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendZ[Element >> 9]) / 511.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 HenDN3Mul = {1.0f/1023.0f,1.0f/(1023.0f*2048.0f),1.0f/(511.0f*2048.0f*2048.0f),0}; + XMASSERT(pSource); + XMASSERT((pSource->v & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskHenD3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMXorHenD3); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddHenD3); + // Normalize x,y and z to -1.0f-1.0f + vResult = _mm_mul_ps(vResult,HenDN3Mul); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadHenD3 +( + CONST XMHEND3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtendXY[] = {0x00000000, 0xFFFFF800}; + static CONST UINT SignExtendZ[] = {0x00000000, 0xFFFFFC00}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200); + + Element = pSource->v & 0x7FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]); + Element = (pSource->v >> 11) & 0x7FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]); + Element = (pSource->v >> 22) & 0x3FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendZ[Element >> 9]); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT((pSource->v & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskHenD3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMXorHenD3); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddHenD3); + // Normalize x and y to -1024-1023.0f and z to -512-511.0f + vResult = _mm_mul_ps(vResult,g_XMMulHenD3); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUDHenN3 +( + CONST XMUDHENN3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)Element / 1023.0f; + Element = (pSource->v >> 10) & 0x7FF; + V.vector4_f32[1] = (FLOAT)Element / 2047.0f; + Element = (pSource->v >> 21) & 0x7FF; + V.vector4_f32[2] = (FLOAT)Element / 2047.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 UDHenN3Mul = {1.0f/1023.0f,1.0f/(2047.0f*1024.0f),1.0f/(2047.0f*1024.0f*2048.0f),0}; + XMASSERT(pSource); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskDHen3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMFlipZ); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddUHenD3); + // Normalize x,y and z to -1.0f-1.0f + vResult = _mm_mul_ps(vResult,UDHenN3Mul); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUDHen3 +( + CONST XMUDHEN3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)Element; + Element = (pSource->v >> 10) & 0x7FF; + V.vector4_f32[1] = (FLOAT)Element; + Element = (pSource->v >> 21) & 0x7FF; + V.vector4_f32[2] = (FLOAT)Element; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskDHen3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMFlipZ); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddUHenD3); + // Normalize x to 0-1023.0f and y and z to 0-2047.0f + vResult = _mm_mul_ps(vResult,g_XMMulDHen3); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadDHenN3 +( + CONST XMDHENN3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtendX[] = {0x00000000, 0xFFFFFC00}; + static CONST UINT SignExtendYZ[] = {0x00000000, 0xFFFFF800}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendX[Element >> 9]) / 511.0f; + Element = (pSource->v >> 10) & 0x7FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]) / 1023.0f; + Element = (pSource->v >> 21) & 0x7FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]) / 1023.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 DHenN3Mul = {1.0f/511.0f,1.0f/(1023.0f*1024.0f),1.0f/(1023.0f*1024.0f*2048.0f),0}; + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskDHen3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMXorDHen3); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddDHen3); + // Normalize x,y and z to -1.0f-1.0f + vResult = _mm_mul_ps(vResult,DHenN3Mul); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadDHen3 +( + CONST XMDHEN3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtendX[] = {0x00000000, 0xFFFFFC00}; + static CONST UINT SignExtendYZ[] = {0x00000000, 0xFFFFF800}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendX[Element >> 9]); + Element = (pSource->v >> 10) & 0x7FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]); + Element = (pSource->v >> 21) & 0x7FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400); + XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,g_XMMaskDHen3); + // Convert x and y to unsigned + vResult = _mm_xor_ps(vResult,g_XMXorDHen3); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Convert x and y back to signed + vResult = _mm_add_ps(vResult,g_XMAddDHen3); + // Normalize x to -210-511.0f and y and z to -1024-1023.0f + vResult = _mm_mul_ps(vResult,g_XMMulDHen3); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadU565 +( + CONST XMU565* pSource +) +{ +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + static const XMVECTORI32 U565And = {0x1F,0x3F<<5,0x1F<<11,0}; + static const XMVECTORF32 U565Mul = {1.0f,1.0f/32.0f,1.0f/2048.f,0}; + XMASSERT(pSource); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,U565And); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Normalize x, y, and z + vResult = _mm_mul_ps(vResult,U565Mul); + return vResult; +#else + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x1F; + V.vector4_f32[0] = (FLOAT)Element; + Element = (pSource->v >> 5) & 0x3F; + V.vector4_f32[1] = (FLOAT)Element; + Element = (pSource->v >> 11) & 0x1F; + V.vector4_f32[2] = (FLOAT)Element; + + return V; +#endif // !_XM_SSE_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat3PK +( + CONST XMFLOAT3PK* pSource +) +{ + _DECLSPEC_ALIGN_16_ UINT Result[4]; + UINT Mantissa; + UINT Exponent; + + XMASSERT(pSource); + + // X Channel (6-bit mantissa) + Mantissa = pSource->xm; + + if ( pSource->xe == 0x1f ) // INF or NAN + { + Result[0] = 0x7f800000 | (pSource->xm << 17); + } + else + { + if ( pSource->xe != 0 ) // The value is normalized + { + Exponent = pSource->xe; + } + else if (Mantissa != 0) // The value is denormalized + { + // Normalize the value in the resulting float + Exponent = 1; + + do + { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x40) == 0); + + Mantissa &= 0x3F; + } + else // The value is zero + { + Exponent = (UINT)-112; + } + + Result[0] = ((Exponent + 112) << 23) | (Mantissa << 17); + } + + // Y Channel (6-bit mantissa) + Mantissa = pSource->ym; + + if ( pSource->ye == 0x1f ) // INF or NAN + { + Result[1] = 0x7f800000 | (pSource->ym << 17); + } + else + { + if ( pSource->ye != 0 ) // The value is normalized + { + Exponent = pSource->ye; + } + else if (Mantissa != 0) // The value is denormalized + { + // Normalize the value in the resulting float + Exponent = 1; + + do + { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x40) == 0); + + Mantissa &= 0x3F; + } + else // The value is zero + { + Exponent = (UINT)-112; + } + + Result[1] = ((Exponent + 112) << 23) | (Mantissa << 17); + } + + // Z Channel (5-bit mantissa) + Mantissa = pSource->zm; + + if ( pSource->ze == 0x1f ) // INF or NAN + { + Result[2] = 0x7f800000 | (pSource->zm << 17); + } + else + { + if ( pSource->ze != 0 ) // The value is normalized + { + Exponent = pSource->ze; + } + else if (Mantissa != 0) // The value is denormalized + { + // Normalize the value in the resulting float + Exponent = 1; + + do + { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x20) == 0); + + Mantissa &= 0x1F; + } + else // The value is zero + { + Exponent = (UINT)-112; + } + + Result[2] = ((Exponent + 112) << 23) | (Mantissa << 18); + } + + return XMLoadFloat3A( (XMFLOAT3A*)&Result ); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat3SE +( + CONST XMFLOAT3SE* pSource +) +{ + _DECLSPEC_ALIGN_16_ UINT Result[4]; + UINT Mantissa; + UINT Exponent, ExpBits; + + XMASSERT(pSource); + + if ( pSource->e == 0x1f ) // INF or NAN + { + Result[0] = 0x7f800000 | (pSource->xm << 14); + Result[1] = 0x7f800000 | (pSource->ym << 14); + Result[2] = 0x7f800000 | (pSource->zm << 14); + } + else if ( pSource->e != 0 ) // The values are all normalized + { + Exponent = pSource->e; + + ExpBits = (Exponent + 112) << 23; + + Mantissa = pSource->xm; + Result[0] = ExpBits | (Mantissa << 14); + + Mantissa = pSource->ym; + Result[1] = ExpBits | (Mantissa << 14); + + Mantissa = pSource->zm; + Result[2] = ExpBits | (Mantissa << 14); + } + else + { + // X Channel + Mantissa = pSource->xm; + + if (Mantissa != 0) // The value is denormalized + { + // Normalize the value in the resulting float + Exponent = 1; + + do + { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x200) == 0); + + Mantissa &= 0x1FF; + } + else // The value is zero + { + Exponent = (UINT)-112; + } + + Result[0] = ((Exponent + 112) << 23) | (Mantissa << 14); + + // Y Channel + Mantissa = pSource->ym; + + if (Mantissa != 0) // The value is denormalized + { + // Normalize the value in the resulting float + Exponent = 1; + + do + { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x200) == 0); + + Mantissa &= 0x1FF; + } + else // The value is zero + { + Exponent = (UINT)-112; + } + + Result[1] = ((Exponent + 112) << 23) | (Mantissa << 14); + + // Z Channel + Mantissa = pSource->zm; + + if (Mantissa != 0) // The value is denormalized + { + // Normalize the value in the resulting float + Exponent = 1; + + do + { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x200) == 0); + + Mantissa &= 0x1FF; + } + else // The value is zero + { + Exponent = (UINT)-112; + } + + Result[2] = ((Exponent + 112) << 23) | (Mantissa << 14); + } + + return XMLoadFloat3A( (XMFLOAT3A*)&Result ); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadInt4 +( + CONST UINT* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_u32[0] = pSource[0]; + V.vector4_u32[1] = pSource[1]; + V.vector4_u32[2] = pSource[2]; + V.vector4_u32[3] = pSource[3]; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pSource); + + __m128i V = _mm_loadu_si128( (const __m128i*)pSource ); + return reinterpret_cast<__m128 *>(&V)[0]; + +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadInt4A +( + CONST UINT* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + V.vector4_u32[0] = pSource[0]; + V.vector4_u32[1] = pSource[1]; + V.vector4_u32[2] = pSource[2]; + V.vector4_u32[3] = pSource[3]; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + __m128i V = _mm_load_si128( (const __m128i*)pSource ); + return reinterpret_cast<__m128 *>(&V)[0]; + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat4 +( + CONST XMFLOAT4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR V; + XMASSERT(pSource); + + ((UINT *)(&V.vector4_f32[0]))[0] = ((const UINT *)(&pSource->x))[0]; + ((UINT *)(&V.vector4_f32[1]))[0] = ((const UINT *)(&pSource->y))[0]; + ((UINT *)(&V.vector4_f32[2]))[0] = ((const UINT *)(&pSource->z))[0]; + ((UINT *)(&V.vector4_f32[3]))[0] = ((const UINT *)(&pSource->w))[0]; + return V; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + + return _mm_loadu_ps( &pSource->x ); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadFloat4A +( + CONST XMFLOAT4A* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + V.vector4_f32[0] = pSource->x; + V.vector4_f32[1] = pSource->y; + V.vector4_f32[2] = pSource->z; + V.vector4_f32[3] = pSource->w; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + return _mm_load_ps( &pSource->x ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadHalf4 +( + CONST XMHALF4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT(pSource); + { + XMVECTOR vResult = { + XMConvertHalfToFloat(pSource->x), + XMConvertHalfToFloat(pSource->y), + XMConvertHalfToFloat(pSource->z), + XMConvertHalfToFloat(pSource->w) + }; + return vResult; + } +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMVECTOR vResult = { + XMConvertHalfToFloat(pSource->x), + XMConvertHalfToFloat(pSource->y), + XMConvertHalfToFloat(pSource->z), + XMConvertHalfToFloat(pSource->w) + }; + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadShortN4 +( + CONST XMSHORTN4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + XMASSERT(pSource->z != -32768); + XMASSERT(pSource->w != -32768); + { + XMVECTOR vResult = { + (FLOAT)pSource->x * (1.0f/32767.0f), + (FLOAT)pSource->y * (1.0f/32767.0f), + (FLOAT)pSource->z * (1.0f/32767.0f), + (FLOAT)pSource->w * (1.0f/32767.0f) + }; + return vResult; + } +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + XMASSERT(pSource->z != -32768); + XMASSERT(pSource->w != -32768); + // Splat the color in all four entries (x,z,y,w) + __m128d vIntd = _mm_load1_pd(reinterpret_cast(&pSource->x)); + // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000 + __m128 vTemp = _mm_and_ps(reinterpret_cast(&vIntd)[0],g_XMMaskX16Y16Z16W16); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16Z16W16); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x8000 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16Z16W16); + // Convert -32767-32767 to -1.0f-1.0f + vTemp = _mm_mul_ps(vTemp,g_XMNormalizeX16Y16Z16W16); + // Very important! The entries are x,z,y,w, flip it to x,y,z,w + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0)); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadShort4 +( + CONST XMSHORT4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + XMASSERT(pSource->z != -32768); + XMASSERT(pSource->w != -32768); + + V.vector4_f32[0] = (FLOAT)pSource->x; + V.vector4_f32[1] = (FLOAT)pSource->y; + V.vector4_f32[2] = (FLOAT)pSource->z; + V.vector4_f32[3] = (FLOAT)pSource->w; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT(pSource->x != -32768); + XMASSERT(pSource->y != -32768); + XMASSERT(pSource->z != -32768); + XMASSERT(pSource->w != -32768); + // Splat the color in all four entries (x,z,y,w) + __m128d vIntd = _mm_load1_pd(reinterpret_cast(&pSource->x)); + // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000 + __m128 vTemp = _mm_and_ps(reinterpret_cast(&vIntd)[0],g_XMMaskX16Y16Z16W16); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16Z16W16); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x8000 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16Z16W16); + // Fix y and w because they are 65536 too large + vTemp = _mm_mul_ps(vTemp,g_XMFixupY16W16); + // Very important! The entries are x,z,y,w, flip it to x,y,z,w + return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0)); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUShortN4 +( + CONST XMUSHORTN4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)pSource->x / 65535.0f; + V.vector4_f32[1] = (FLOAT)pSource->y / 65535.0f; + V.vector4_f32[2] = (FLOAT)pSource->z / 65535.0f; + V.vector4_f32[3] = (FLOAT)pSource->w / 65535.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + static const XMVECTORF32 FixupY16W16 = {1.0f/65535.0f,1.0f/65535.0f,1.0f/(65535.0f*65536.0f),1.0f/(65535.0f*65536.0f)}; + static const XMVECTORF32 FixaddY16W16 = {0,0,32768.0f*65536.0f,32768.0f*65536.0f}; + XMASSERT(pSource); + // Splat the color in all four entries (x,z,y,w) + __m128d vIntd = _mm_load1_pd(reinterpret_cast(&pSource->x)); + // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000 + __m128 vTemp = _mm_and_ps(reinterpret_cast(&vIntd)[0],g_XMMaskX16Y16Z16W16); + // y and w are signed! Flip the bits to convert the order to unsigned + vTemp = _mm_xor_ps(vTemp,g_XMFlipZW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // y and w + 0x8000 to complete the conversion + vTemp = _mm_add_ps(vTemp,FixaddY16W16); + // Fix y and w because they are 65536 too large + vTemp = _mm_mul_ps(vTemp,FixupY16W16); + // Very important! The entries are x,z,y,w, flip it to x,y,z,w + return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0)); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUShort4 +( + CONST XMUSHORT4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)pSource->x; + V.vector4_f32[1] = (FLOAT)pSource->y; + V.vector4_f32[2] = (FLOAT)pSource->z; + V.vector4_f32[3] = (FLOAT)pSource->w; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + static const XMVECTORF32 FixaddY16W16 = {0,0,32768.0f,32768.0f}; + XMASSERT(pSource); + // Splat the color in all four entries (x,z,y,w) + __m128d vIntd = _mm_load1_pd(reinterpret_cast(&pSource->x)); + // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000 + __m128 vTemp = _mm_and_ps(reinterpret_cast(&vIntd)[0],g_XMMaskX16Y16Z16W16); + // y and w are signed! Flip the bits to convert the order to unsigned + vTemp = _mm_xor_ps(vTemp,g_XMFlipZW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // Fix y and w because they are 65536 too large + vTemp = _mm_mul_ps(vTemp,g_XMFixupY16W16); + // y and w + 0x8000 to complete the conversion + vTemp = _mm_add_ps(vTemp,FixaddY16W16); + // Very important! The entries are x,z,y,w, flip it to x,y,z,w + return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0)); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadXIcoN4 +( + CONST XMXICON4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull); + + Element = (UINT)(pSource->v & 0xFFFFF); + V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f; + Element = (UINT)((pSource->v >> 20) & 0xFFFFF); + V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f; + Element = (UINT)((pSource->v >> 40) & 0xFFFFF); + V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f; + V.vector4_f32[3] = (FLOAT)(pSource->v >> 60) / 15.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull); + static const XMVECTORF32 LoadXIcoN4Mul = {1.0f/524287.0f,1.0f/(524287.0f*4096.0f),1.0f/524287.0f,1.0f/(15.0f*4096.0f*65536.0f)}; + XMASSERT(pSource); + // Grab the 64 bit structure + __m128d vResultd = _mm_load_sd(reinterpret_cast(&pSource->v)); + // By shifting down 8 bits, y and z are in seperate 32 bit elements + __m128i vResulti = _mm_srli_si128(reinterpret_cast(&vResultd)[0],8/8); + // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z + XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast(&vResultd)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(1,0,1,0)); + // Fix the entries to x,y,z,w + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0)); + // Mask x,y,z and w + vTemp = _mm_and_ps(vTemp,g_XMMaskIco4); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorXIco4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddXIco4); + // Fix y and w because they are too large + vTemp = _mm_mul_ps(vTemp,LoadXIcoN4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadXIco4 +( + CONST XMXICO4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull); + + Element = (UINT)(pSource->v & 0xFFFFF); + V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]); + Element = (UINT)((pSource->v >> 20) & 0xFFFFF); + V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]); + Element = (UINT)((pSource->v >> 40) & 0xFFFFF); + V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]); + V.vector4_f32[3] = (FLOAT)(pSource->v >> 60); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull); + XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull); + XMASSERT(pSource); + // Grab the 64 bit structure + __m128d vResultd = _mm_load_sd(reinterpret_cast(&pSource->v)); + // By shifting down 8 bits, y and z are in seperate 32 bit elements + __m128i vResulti = _mm_srli_si128(reinterpret_cast(&vResultd)[0],8/8); + // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z + XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast(&vResultd)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(1,0,1,0)); + // Fix the entries to x,y,z,w + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0)); + // Mask x,y,z and w + vTemp = _mm_and_ps(vTemp,g_XMMaskIco4); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorXIco4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddXIco4); + // Fix y and w because they are too large + vTemp = _mm_mul_ps(vTemp,g_XMMulIco4); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUIcoN4 +( + CONST XMUICON4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)(pSource->v & 0xFFFFF) / 1048575.0f; + V.vector4_f32[1] = (FLOAT)((pSource->v >> 20) & 0xFFFFF) / 1048575.0f; + V.vector4_f32[2] = (FLOAT)((pSource->v >> 40) & 0xFFFFF) / 1048575.0f; + V.vector4_f32[3] = (FLOAT)(pSource->v >> 60) / 15.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 LoadUIcoN4Mul = {1.0f/1048575.0f,1.0f/(1048575.0f*4096.0f),1.0f/1048575.0f,1.0f/(15.0f*4096.0f*65536.0f)}; + XMASSERT(pSource); + // Grab the 64 bit structure + __m128d vResultd = _mm_load_sd(reinterpret_cast(&pSource->v)); + // By shifting down 8 bits, y and z are in seperate 32 bit elements + __m128i vResulti = _mm_srli_si128(reinterpret_cast(&vResultd)[0],8/8); + // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z + XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast(&vResultd)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(1,0,1,0)); + // Fix the entries to x,y,z,w + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0)); + // Mask x,y,z and w + vTemp = _mm_and_ps(vTemp,g_XMMaskIco4); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMFlipYW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddUIco4); + // Fix y and w because they are too large + vTemp = _mm_mul_ps(vTemp,LoadUIcoN4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUIco4 +( + CONST XMUICO4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)(pSource->v & 0xFFFFF); + V.vector4_f32[1] = (FLOAT)((pSource->v >> 20) & 0xFFFFF); + V.vector4_f32[2] = (FLOAT)((pSource->v >> 40) & 0xFFFFF); + V.vector4_f32[3] = (FLOAT)(pSource->v >> 60); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Grab the 64 bit structure + __m128d vResultd = _mm_load_sd(reinterpret_cast(&pSource->v)); + // By shifting down 8 bits, y and z are in seperate 32 bit elements + __m128i vResulti = _mm_srli_si128(reinterpret_cast(&vResultd)[0],8/8); + // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z + XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast(&vResultd)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(1,0,1,0)); + // Fix the entries to x,y,z,w + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0)); + // Mask x,y,z and w + vTemp = _mm_and_ps(vTemp,g_XMMaskIco4); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMFlipYW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddUIco4); + // Fix y and w because they are too large + vTemp = _mm_mul_ps(vTemp,g_XMMulIco4); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadIcoN4 +( + CONST XMICON4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000}; + static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFF0}; + + XMASSERT(pSource); + + Element = (UINT)(pSource->v & 0xFFFFF); + V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f; + Element = (UINT)((pSource->v >> 20) & 0xFFFFF); + V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f; + Element = (UINT)((pSource->v >> 40) & 0xFFFFF); + V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f; + Element = (UINT)(pSource->v >> 60); + V.vector4_f32[3] = (FLOAT)(INT)(Element | SignExtendW[Element >> 3]) / 7.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 LoadIcoN4Mul = {1.0f/524287.0f,1.0f/(524287.0f*4096.0f),1.0f/524287.0f,1.0f/(7.0f*4096.0f*65536.0f)}; + XMASSERT(pSource); + // Grab the 64 bit structure + __m128d vResultd = _mm_load_sd(reinterpret_cast(&pSource->v)); + // By shifting down 8 bits, y and z are in seperate 32 bit elements + __m128i vResulti = _mm_srli_si128(reinterpret_cast(&vResultd)[0],8/8); + // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z + XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast(&vResultd)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(1,0,1,0)); + // Fix the entries to x,y,z,w + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0)); + // Mask x,y,z and w + vTemp = _mm_and_ps(vTemp,g_XMMaskIco4); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorIco4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddIco4); + // Fix y and w because they are too large + vTemp = _mm_mul_ps(vTemp,LoadIcoN4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadIco4 +( + CONST XMICO4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000}; + static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFF0}; + + XMASSERT(pSource); + + Element = (UINT)(pSource->v & 0xFFFFF); + V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]); + Element = (UINT)((pSource->v >> 20) & 0xFFFFF); + V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]); + Element = (UINT)((pSource->v >> 40) & 0xFFFFF); + V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]); + Element = (UINT)(pSource->v >> 60); + V.vector4_f32[3] = (FLOAT)(INT)(Element | SignExtendW[Element >> 3]); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Grab the 64 bit structure + __m128d vResultd = _mm_load_sd(reinterpret_cast(&pSource->v)); + // By shifting down 8 bits, y and z are in seperate 32 bit elements + __m128i vResulti = _mm_srli_si128(reinterpret_cast(&vResultd)[0],8/8); + // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z + XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast(&vResultd)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(1,0,1,0)); + // Fix the entries to x,y,z,w + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0)); + // Mask x,y,z and w + vTemp = _mm_and_ps(vTemp,g_XMMaskIco4); + // x and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorIco4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddIco4); + // Fix y and w because they are too large + vTemp = _mm_mul_ps(vTemp,g_XMMulIco4); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadXDecN4 +( + CONST XMXDECN4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f; + Element = (pSource->v >> 10) & 0x3FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f; + Element = (pSource->v >> 20) & 0x3FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f; + V.vector4_f32[3] = (FLOAT)(pSource->v >> 30) / 3.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Splat the color in all four entries + __m128 vTemp = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskA2B10G10R10); + // a is unsigned! Flip the bit to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMFlipA2B10G10R10); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // RGB + 0, A + 0x80000000.f to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMFixAA2B10G10R10); + // Convert 0-255 to 0.0f-1.0f + return _mm_mul_ps(vTemp,g_XMNormalizeA2B10G10R10); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadXDec4 +( + CONST XMXDEC4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]); + Element = (pSource->v >> 10) & 0x3FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]); + Element = (pSource->v >> 20) & 0x3FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]); + V.vector4_f32[3] = (FLOAT)(pSource->v >> 30); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200); + static const XMVECTORI32 XDec4Xor = {0x200, 0x200<<10, 0x200<<20, 0x80000000}; + static const XMVECTORF32 XDec4Add = {-512.0f,-512.0f*1024.0f,-512.0f*1024.0f*1024.0f,32768*65536.0f}; + XMASSERT(pSource); + // Splat the color in all four entries + XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskDec4); + // a is unsigned! Flip the bit to convert the order to signed + vTemp = _mm_xor_ps(vTemp,XDec4Xor); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // RGB + 0, A + 0x80000000.f to undo the signed order. + vTemp = _mm_add_ps(vTemp,XDec4Add); + // Convert 0-255 to 0.0f-1.0f + vTemp = _mm_mul_ps(vTemp,g_XMMulDec4); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUDecN4 +( + CONST XMUDECN4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)Element / 1023.0f; + Element = (pSource->v >> 10) & 0x3FF; + V.vector4_f32[1] = (FLOAT)Element / 1023.0f; + Element = (pSource->v >> 20) & 0x3FF; + V.vector4_f32[2] = (FLOAT)Element / 1023.0f; + V.vector4_f32[3] = (FLOAT)(pSource->v >> 30) / 3.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + static const XMVECTORF32 UDecN4Mul = {1.0f/1023.0f,1.0f/(1023.0f*1024.0f),1.0f/(1023.0f*1024.0f*1024.0f),1.0f/(3.0f*1024.0f*1024.0f*1024.0f)}; + // Splat the color in all four entries + XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskDec4); + // a is unsigned! Flip the bit to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMFlipW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // RGB + 0, A + 0x80000000.f to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMAddUDec4); + // Convert 0-255 to 0.0f-1.0f + vTemp = _mm_mul_ps(vTemp,UDecN4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUDec4 +( + CONST XMUDEC4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)Element; + Element = (pSource->v >> 10) & 0x3FF; + V.vector4_f32[1] = (FLOAT)Element; + Element = (pSource->v >> 20) & 0x3FF; + V.vector4_f32[2] = (FLOAT)Element; + V.vector4_f32[3] = (FLOAT)(pSource->v >> 30); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Splat the color in all four entries + XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskDec4); + // a is unsigned! Flip the bit to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMFlipW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // RGB + 0, A + 0x80000000.f to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMAddUDec4); + // Convert 0-255 to 0.0f-1.0f + vTemp = _mm_mul_ps(vTemp,g_XMMulDec4); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadDecN4 +( + CONST XMDECN4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00}; + static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFFC}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 30) & 0x3) != 0x2); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f; + Element = (pSource->v >> 10) & 0x3FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f; + Element = (pSource->v >> 20) & 0x3FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f; + Element = pSource->v >> 30; + V.vector4_f32[3] = (FLOAT)(SHORT)(Element | SignExtendW[Element >> 1]); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 30) & 0x3) != 0x2); + static const XMVECTORF32 DecN4Mul = {1.0f/511.0f,1.0f/(511.0f*1024.0f),1.0f/(511.0f*1024.0f*1024.0f),1.0f/(1024.0f*1024.0f*1024.0f)}; + // Splat the color in all four entries + XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskDec4); + // a is unsigned! Flip the bit to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorDec4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // RGB + 0, A + 0x80000000.f to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMAddDec4); + // Convert 0-255 to 0.0f-1.0f + vTemp = _mm_mul_ps(vTemp,DecN4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadDec4 +( + CONST XMDEC4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + UINT Element; + static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00}; + static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFFC}; + + XMASSERT(pSource); + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 30) & 0x3) != 0x2); + + Element = pSource->v & 0x3FF; + V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]); + Element = (pSource->v >> 10) & 0x3FF; + V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]); + Element = (pSource->v >> 20) & 0x3FF; + V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]); + Element = pSource->v >> 30; + V.vector4_f32[3] = (FLOAT)(SHORT)(Element | SignExtendW[Element >> 1]); + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT((pSource->v & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200); + XMASSERT(((pSource->v >> 30) & 0x3) != 0x2); + XMASSERT(pSource); + // Splat the color in all four entries + XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskDec4); + // a is unsigned! Flip the bit to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorDec4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // RGB + 0, A + 0x80000000.f to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMAddDec4); + // Convert 0-255 to 0.0f-1.0f + vTemp = _mm_mul_ps(vTemp,g_XMMulDec4); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUByteN4 +( + CONST XMUBYTEN4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)pSource->x / 255.0f; + V.vector4_f32[1] = (FLOAT)pSource->y / 255.0f; + V.vector4_f32[2] = (FLOAT)pSource->z / 255.0f; + V.vector4_f32[3] = (FLOAT)pSource->w / 255.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 LoadUByteN4Mul = {1.0f/255.0f,1.0f/(255.0f*256.0f),1.0f/(255.0f*65536.0f),1.0f/(255.0f*65536.0f*256.0f)}; + XMASSERT(pSource); + // Splat the color in all four entries (x,z,y,w) + XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast(&pSource->x)); + // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskByte4); + // w is signed! Flip the bits to convert the order to unsigned + vTemp = _mm_xor_ps(vTemp,g_XMFlipW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // w + 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddUDec4); + // Fix y, z and w because they are too large + vTemp = _mm_mul_ps(vTemp,LoadUByteN4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUByte4 +( + CONST XMUBYTE4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + + V.vector4_f32[0] = (FLOAT)pSource->x; + V.vector4_f32[1] = (FLOAT)pSource->y; + V.vector4_f32[2] = (FLOAT)pSource->z; + V.vector4_f32[3] = (FLOAT)pSource->w; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 LoadUByte4Mul = {1.0f,1.0f/256.0f,1.0f/65536.0f,1.0f/(65536.0f*256.0f)}; + XMASSERT(pSource); + // Splat the color in all four entries (x,z,y,w) + XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast(&pSource->x)); + // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskByte4); + // w is signed! Flip the bits to convert the order to unsigned + vTemp = _mm_xor_ps(vTemp,g_XMFlipW); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // w + 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddUDec4); + // Fix y, z and w because they are too large + vTemp = _mm_mul_ps(vTemp,LoadUByte4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadByteN4 +( + CONST XMBYTEN4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(pSource->x != -128); + XMASSERT(pSource->y != -128); + XMASSERT(pSource->z != -128); + XMASSERT(pSource->w != -128); + + V.vector4_f32[0] = (FLOAT)pSource->x / 127.0f; + V.vector4_f32[1] = (FLOAT)pSource->y / 127.0f; + V.vector4_f32[2] = (FLOAT)pSource->z / 127.0f; + V.vector4_f32[3] = (FLOAT)pSource->w / 127.0f; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 LoadByteN4Mul = {1.0f/127.0f,1.0f/(127.0f*256.0f),1.0f/(127.0f*65536.0f),1.0f/(127.0f*65536.0f*256.0f)}; + XMASSERT(pSource); + XMASSERT(pSource->x != -128); + XMASSERT(pSource->y != -128); + XMASSERT(pSource->z != -128); + XMASSERT(pSource->w != -128); + // Splat the color in all four entries (x,z,y,w) + XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast(&pSource->x)); + // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskByte4); + // x,y and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorByte4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x, y and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddByte4); + // Fix y, z and w because they are too large + vTemp = _mm_mul_ps(vTemp,LoadByteN4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadByte4 +( + CONST XMBYTE4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + + XMASSERT(pSource); + XMASSERT(pSource->x != -128); + XMASSERT(pSource->y != -128); + XMASSERT(pSource->z != -128); + XMASSERT(pSource->w != -128); + + V.vector4_f32[0] = (FLOAT)pSource->x; + V.vector4_f32[1] = (FLOAT)pSource->y; + V.vector4_f32[2] = (FLOAT)pSource->z; + V.vector4_f32[3] = (FLOAT)pSource->w; + + return V; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 LoadByte4Mul = {1.0f,1.0f/256.0f,1.0f/65536.0f,1.0f/(65536.0f*256.0f)}; + XMASSERT(pSource); + XMASSERT(pSource->x != -128); + XMASSERT(pSource->y != -128); + XMASSERT(pSource->z != -128); + XMASSERT(pSource->w != -128); + // Splat the color in all four entries (x,z,y,w) + XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast(&pSource->x)); + // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000 + vTemp = _mm_and_ps(vTemp,g_XMMaskByte4); + // x,y and z are unsigned! Flip the bits to convert the order to signed + vTemp = _mm_xor_ps(vTemp,g_XMXorByte4); + // Convert to floating point numbers + vTemp = _mm_cvtepi32_ps(reinterpret_cast(&vTemp)[0]); + // x, y and z - 0x80 to complete the conversion + vTemp = _mm_add_ps(vTemp,g_XMAddByte4); + // Fix y, z and w because they are too large + vTemp = _mm_mul_ps(vTemp,LoadByte4Mul); + return vTemp; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadUNibble4 +( + CONST XMUNIBBLE4* pSource +) +{ +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + static const XMVECTORI32 UNibble4And = {0xF,0xF0,0xF00,0xF000}; + static const XMVECTORF32 UNibble4Mul = {1.0f,1.0f/16.f,1.0f/256.f,1.0f/4096.f}; + XMASSERT(pSource); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,UNibble4And); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Normalize x, y, and z + vResult = _mm_mul_ps(vResult,UNibble4Mul); + return vResult; +#else + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0xF; + V.vector4_f32[0] = (FLOAT)Element; + Element = (pSource->v >> 4) & 0xF; + V.vector4_f32[1] = (FLOAT)Element; + Element = (pSource->v >> 8) & 0xF; + V.vector4_f32[2] = (FLOAT)Element; + Element = (pSource->v >> 12) & 0xF; + V.vector4_f32[3] = (FLOAT)Element; + + return V; +#endif // !_XM_SSE_INTRISICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadU555 +( + CONST XMU555* pSource +) +{ +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + static const XMVECTORI32 U555And = {0x1F,0x1F<<5,0x1F<<10,0x8000}; + static const XMVECTORF32 U555Mul = {1.0f,1.0f/32.f,1.0f/1024.f,1.0f/32768.f}; + XMASSERT(pSource); + // Get the 32 bit value and splat it + XMVECTOR vResult = _mm_load_ps1(reinterpret_cast(&pSource->v)); + // Mask off x, y and z + vResult = _mm_and_ps(vResult,U555And); + // Convert to float + vResult = _mm_cvtepi32_ps(reinterpret_cast(&vResult)[0]); + // Normalize x, y, and z + vResult = _mm_mul_ps(vResult,U555Mul); + return vResult; +#else + XMVECTOR V; + UINT Element; + + XMASSERT(pSource); + + Element = pSource->v & 0x1F; + V.vector4_f32[0] = (FLOAT)Element; + Element = (pSource->v >> 5) & 0x1F; + V.vector4_f32[1] = (FLOAT)Element; + Element = (pSource->v >> 10) & 0x1F; + V.vector4_f32[2] = (FLOAT)Element; + Element = (pSource->v >> 15) & 0x1; + V.vector4_f32[3] = (FLOAT)Element; + + return V; +#endif // !_XM_SSE_INTRISICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMLoadColor +( + CONST XMCOLOR* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMASSERT(pSource); + { + // INT -> Float conversions are done in one instruction. + // UINT -> Float calls a runtime function. Keep in INT + INT iColor = (INT)(pSource->c); + XMVECTOR vColor = { + (FLOAT)((iColor >> 16) & 0xFF) * (1.0f/255.0f), + (FLOAT)((iColor >> 8) & 0xFF) * (1.0f/255.0f), + (FLOAT)(iColor & 0xFF) * (1.0f/255.0f), + (FLOAT)((iColor >> 24) & 0xFF) * (1.0f/255.0f) + }; + return vColor; + } +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Splat the color in all four entries + __m128i vInt = _mm_set1_epi32(pSource->c); + // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000 + vInt = _mm_and_si128(vInt,g_XMMaskA8R8G8B8); + // a is unsigned! Flip the bit to convert the order to signed + vInt = _mm_xor_si128(vInt,g_XMFlipA8R8G8B8); + // Convert to floating point numbers + XMVECTOR vTemp = _mm_cvtepi32_ps(vInt); + // RGB + 0, A + 0x80000000.f to undo the signed order. + vTemp = _mm_add_ps(vTemp,g_XMFixAA8R8G8B8); + // Convert 0-255 to 0.0f-1.0f + return _mm_mul_ps(vTemp,g_XMNormalizeA8R8G8B8); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMLoadFloat3x3 +( + CONST XMFLOAT3X3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + + XMASSERT(pSource); + + M.r[0].vector4_f32[0] = pSource->m[0][0]; + M.r[0].vector4_f32[1] = pSource->m[0][1]; + M.r[0].vector4_f32[2] = pSource->m[0][2]; + M.r[0].vector4_f32[3] = 0.0f; + + M.r[1].vector4_f32[0] = pSource->m[1][0]; + M.r[1].vector4_f32[1] = pSource->m[1][1]; + M.r[1].vector4_f32[2] = pSource->m[1][2]; + M.r[1].vector4_f32[3] = 0.0f; + + M.r[2].vector4_f32[0] = pSource->m[2][0]; + M.r[2].vector4_f32[1] = pSource->m[2][1]; + M.r[2].vector4_f32[2] = pSource->m[2][2]; + M.r[2].vector4_f32[3] = 0.0f; + + M.r[3].vector4_f32[0] = 0.0f; + M.r[3].vector4_f32[1] = 0.0f; + M.r[3].vector4_f32[2] = 0.0f; + M.r[3].vector4_f32[3] = 1.0f; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + XMVECTOR V1, V2, V3, Z, T1, T2, T3, T4, T5; + + Z = _mm_setzero_ps(); + + XMASSERT(pSource); + + V1 = _mm_loadu_ps( &pSource->m[0][0] ); + V2 = _mm_loadu_ps( &pSource->m[1][1] ); + V3 = _mm_load_ss( &pSource->m[2][2] ); + + T1 = _mm_unpackhi_ps( V1, Z ); + T2 = _mm_unpacklo_ps( V2, Z ); + T3 = _mm_shuffle_ps( V3, T2, _MM_SHUFFLE( 0, 1, 0, 0 ) ); + T4 = _mm_movehl_ps( T2, T3 ); + T5 = _mm_movehl_ps( Z, T1 ); + + M.r[0] = _mm_movelh_ps( V1, T1 ); + M.r[1] = _mm_add_ps( T4, T5 ); + M.r[2] = _mm_shuffle_ps( V2, V3, _MM_SHUFFLE(1, 0, 3, 2) ); + M.r[3] = g_XMIdentityR3; + + return M; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMLoadFloat4x3 +( + CONST XMFLOAT4X3* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX M; + XMASSERT(pSource); + + ((UINT *)(&M.r[0].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[0][0]))[0]; + ((UINT *)(&M.r[0].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[0][1]))[0]; + ((UINT *)(&M.r[0].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[0][2]))[0]; + M.r[0].vector4_f32[3] = 0.0f; + + ((UINT *)(&M.r[1].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[1][0]))[0]; + ((UINT *)(&M.r[1].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[1][1]))[0]; + ((UINT *)(&M.r[1].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[1][2]))[0]; + M.r[1].vector4_f32[3] = 0.0f; + + ((UINT *)(&M.r[2].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[2][0]))[0]; + ((UINT *)(&M.r[2].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[2][1]))[0]; + ((UINT *)(&M.r[2].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[2][2]))[0]; + M.r[2].vector4_f32[3] = 0.0f; + + ((UINT *)(&M.r[3].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[3][0]))[0]; + ((UINT *)(&M.r[3].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[3][1]))[0]; + ((UINT *)(&M.r[3].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[3][2]))[0]; + M.r[3].vector4_f32[3] = 1.0f; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Use unaligned load instructions to + // load the 12 floats + // vTemp1 = x1,y1,z1,x2 + XMVECTOR vTemp1 = _mm_loadu_ps(&pSource->m[0][0]); + // vTemp2 = y2,z2,x3,y3 + XMVECTOR vTemp2 = _mm_loadu_ps(&pSource->m[1][1]); + // vTemp4 = z3,x4,y4,z4 + XMVECTOR vTemp4 = _mm_loadu_ps(&pSource->m[2][2]); + // vTemp3 = x3,y3,z3,z3 + XMVECTOR vTemp3 = _mm_shuffle_ps(vTemp2,vTemp4,_MM_SHUFFLE(0,0,3,2)); + // vTemp2 = y2,z2,x2,x2 + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp1,_MM_SHUFFLE(3,3,1,0)); + // vTemp2 = x2,y2,z2,z2 + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp2,_MM_SHUFFLE(1,1,0,2)); + // vTemp1 = x1,y1,z1,0 + vTemp1 = _mm_and_ps(vTemp1,g_XMMask3); + // vTemp2 = x2,y2,z2,0 + vTemp2 = _mm_and_ps(vTemp2,g_XMMask3); + // vTemp3 = x3,y3,z3,0 + vTemp3 = _mm_and_ps(vTemp3,g_XMMask3); + // vTemp4i = x4,y4,z4,0 + __m128i vTemp4i = _mm_srli_si128(reinterpret_cast(&vTemp4)[0],32/8); + // vTemp4i = x4,y4,z4,1.0f + vTemp4i = _mm_or_si128(vTemp4i,g_XMIdentityR3); + XMMATRIX M(vTemp1, + vTemp2, + vTemp3, + reinterpret_cast(&vTemp4i)[0]); + return M; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMLoadFloat4x3A +( + CONST XMFLOAT4X3A* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + M.r[0].vector4_f32[0] = pSource->m[0][0]; + M.r[0].vector4_f32[1] = pSource->m[0][1]; + M.r[0].vector4_f32[2] = pSource->m[0][2]; + M.r[0].vector4_f32[3] = 0.0f; + + M.r[1].vector4_f32[0] = pSource->m[1][0]; + M.r[1].vector4_f32[1] = pSource->m[1][1]; + M.r[1].vector4_f32[2] = pSource->m[1][2]; + M.r[1].vector4_f32[3] = 0.0f; + + M.r[2].vector4_f32[0] = pSource->m[2][0]; + M.r[2].vector4_f32[1] = pSource->m[2][1]; + M.r[2].vector4_f32[2] = pSource->m[2][2]; + M.r[2].vector4_f32[3] = 0.0f; + + M.r[3].vector4_f32[0] = pSource->m[3][0]; + M.r[3].vector4_f32[1] = pSource->m[3][1]; + M.r[3].vector4_f32[2] = pSource->m[3][2]; + M.r[3].vector4_f32[3] = 1.0f; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + // Use aligned load instructions to + // load the 12 floats + // vTemp1 = x1,y1,z1,x2 + XMVECTOR vTemp1 = _mm_load_ps(&pSource->m[0][0]); + // vTemp2 = y2,z2,x3,y3 + XMVECTOR vTemp2 = _mm_load_ps(&pSource->m[1][1]); + // vTemp4 = z3,x4,y4,z4 + XMVECTOR vTemp4 = _mm_load_ps(&pSource->m[2][2]); + // vTemp3 = x3,y3,z3,z3 + XMVECTOR vTemp3 = _mm_shuffle_ps(vTemp2,vTemp4,_MM_SHUFFLE(0,0,3,2)); + // vTemp2 = y2,z2,x2,x2 + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp1,_MM_SHUFFLE(3,3,1,0)); + // vTemp2 = x2,y2,z2,z2 + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp2,_MM_SHUFFLE(1,1,0,2)); + // vTemp1 = x1,y1,z1,0 + vTemp1 = _mm_and_ps(vTemp1,g_XMMask3); + // vTemp2 = x2,y2,z2,0 + vTemp2 = _mm_and_ps(vTemp2,g_XMMask3); + // vTemp3 = x3,y3,z3,0 + vTemp3 = _mm_and_ps(vTemp3,g_XMMask3); + // vTemp4i = x4,y4,z4,0 + __m128i vTemp4i = _mm_srli_si128(reinterpret_cast(&vTemp4)[0],32/8); + // vTemp4i = x4,y4,z4,1.0f + vTemp4i = _mm_or_si128(vTemp4i,g_XMIdentityR3); + XMMATRIX M(vTemp1, + vTemp2, + vTemp3, + reinterpret_cast(&vTemp4i)[0]); + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMLoadFloat4x4 +( + CONST XMFLOAT4X4* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX M; + XMASSERT(pSource); + + ((UINT *)(&M.r[0].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[0][0]))[0]; + ((UINT *)(&M.r[0].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[0][1]))[0]; + ((UINT *)(&M.r[0].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[0][2]))[0]; + ((UINT *)(&M.r[0].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[0][3]))[0]; + + ((UINT *)(&M.r[1].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[1][0]))[0]; + ((UINT *)(&M.r[1].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[1][1]))[0]; + ((UINT *)(&M.r[1].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[1][2]))[0]; + ((UINT *)(&M.r[1].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[1][3]))[0]; + + ((UINT *)(&M.r[2].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[2][0]))[0]; + ((UINT *)(&M.r[2].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[2][1]))[0]; + ((UINT *)(&M.r[2].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[2][2]))[0]; + ((UINT *)(&M.r[2].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[2][3]))[0]; + + ((UINT *)(&M.r[3].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[3][0]))[0]; + ((UINT *)(&M.r[3].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[3][1]))[0]; + ((UINT *)(&M.r[3].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[3][2]))[0]; + ((UINT *)(&M.r[3].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[3][3]))[0]; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSource); + XMMATRIX M; + + M.r[0] = _mm_loadu_ps( &pSource->_11 ); + M.r[1] = _mm_loadu_ps( &pSource->_21 ); + M.r[2] = _mm_loadu_ps( &pSource->_31 ); + M.r[3] = _mm_loadu_ps( &pSource->_41 ); + + return M; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMLoadFloat4x4A +( + CONST XMFLOAT4X4A* pSource +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + + XMASSERT(pSource); + XMASSERT(((UINT_PTR)pSource & 0xF) == 0); + + M.r[0].vector4_f32[0] = pSource->m[0][0]; + M.r[0].vector4_f32[1] = pSource->m[0][1]; + M.r[0].vector4_f32[2] = pSource->m[0][2]; + M.r[0].vector4_f32[3] = pSource->m[0][3]; + + M.r[1].vector4_f32[0] = pSource->m[1][0]; + M.r[1].vector4_f32[1] = pSource->m[1][1]; + M.r[1].vector4_f32[2] = pSource->m[1][2]; + M.r[1].vector4_f32[3] = pSource->m[1][3]; + + M.r[2].vector4_f32[0] = pSource->m[2][0]; + M.r[2].vector4_f32[1] = pSource->m[2][1]; + M.r[2].vector4_f32[2] = pSource->m[2][2]; + M.r[2].vector4_f32[3] = pSource->m[2][3]; + + M.r[3].vector4_f32[0] = pSource->m[3][0]; + M.r[3].vector4_f32[1] = pSource->m[3][1]; + M.r[3].vector4_f32[2] = pSource->m[3][2]; + M.r[3].vector4_f32[3] = pSource->m[3][3]; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + + XMASSERT(pSource); + + M.r[0] = _mm_load_ps( &pSource->_11 ); + M.r[1] = _mm_load_ps( &pSource->_21 ); + M.r[2] = _mm_load_ps( &pSource->_31 ); + M.r[3] = _mm_load_ps( &pSource->_41 ); + + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +/**************************************************************************** + * + * Vector and matrix store operations + * + ****************************************************************************/ + +XMFINLINE VOID XMStoreInt +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + *pDestination = XMVectorGetIntX( V ); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + _mm_store_ss( (float*)pDestination, V ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat +( + FLOAT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + *pDestination = XMVectorGetX( V ); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + _mm_store_ss( pDestination, V ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreInt2 +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + pDestination[0] = V.vector4_u32[0]; + pDestination[1] = V.vector4_u32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + XMVECTOR T = _mm_shuffle_ps( V, V, _MM_SHUFFLE( 1, 1, 1, 1 ) ); + _mm_store_ss( (float*)&pDestination[0], V ); + _mm_store_ss( (float*)&pDestination[1], T ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreInt2A +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination[0] = V.vector4_u32[0]; + pDestination[1] = V.vector4_u32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast(&V)[0] ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat2 +( + XMFLOAT2* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + pDestination->x = V.vector4_f32[0]; + pDestination->y = V.vector4_f32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + XMVECTOR T = _mm_shuffle_ps( V, V, _MM_SHUFFLE( 1, 1, 1, 1 ) ); + _mm_store_ss( &pDestination->x, V ); + _mm_store_ss( &pDestination->y, T ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat2A +( + XMFLOAT2A* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination->x = V.vector4_f32[0]; + pDestination->y = V.vector4_f32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast(&V)[0] ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreHalf2 +( + XMHALF2* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + + pDestination->x = XMConvertFloatToHalf(V.vector4_f32[0]); + pDestination->y = XMConvertFloatToHalf(V.vector4_f32[1]); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + pDestination->x = XMConvertFloatToHalf(XMVectorGetX(V)); + pDestination->y = XMConvertFloatToHalf(XMVectorGetY(V)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreShortN2 +( + XMSHORTN2* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + N = XMVectorRound(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + + XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + vResult = _mm_mul_ps(vResult,Scale); + __m128i vResulti = _mm_cvtps_epi32(vResult); + vResulti = _mm_packs_epi32(vResulti,vResulti); + _mm_store_ss(reinterpret_cast(&pDestination->x),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreShort2 +( + XMSHORT2* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f}; + static CONST XMVECTOR Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + N = XMVectorRound(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f}; + static CONST XMVECTORF32 Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,Min); + vResult = _mm_min_ps(vResult,Max); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // Pack the ints into shorts + vInt = _mm_packs_epi32(vInt,vInt); + _mm_store_ss(reinterpret_cast(&pDestination->x),reinterpret_cast(&vInt)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUShortN2 +( + XMUSHORTN2* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), g_XMOne.v); + N = XMVectorMultiplyAdd(N, Scale.v, g_XMOneHalf.v); + N = XMVectorTruncate(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + vResult = _mm_mul_ps(vResult,Scale); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // Since the SSE pack instruction clamps using signed rules, + // manually extract the values to store them to memory + pDestination->x = static_cast(_mm_extract_epi16(vInt,0)); + pDestination->y = static_cast(_mm_extract_epi16(vInt,2)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUShort2 +( + XMUSHORT2* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max); + N = XMVectorRound(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,Max); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // Since the SSE pack instruction clamps using signed rules, + // manually extract the values to store them to memory + pDestination->x = static_cast(_mm_extract_epi16(vInt,0)); + pDestination->y = static_cast(_mm_extract_epi16(vInt,2)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreInt3 +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + pDestination[0] = V.vector4_u32[0]; + pDestination[1] = V.vector4_u32[1]; + pDestination[2] = V.vector4_u32[2]; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + XMVECTOR T1 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR T2 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + _mm_store_ss( (float*)pDestination, V ); + _mm_store_ss( (float*)&pDestination[1], T1 ); + _mm_store_ss( (float*)&pDestination[2], T2 ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreInt3A +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination[0] = V.vector4_u32[0]; + pDestination[1] = V.vector4_u32[1]; + pDestination[2] = V.vector4_u32[2]; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + XMVECTOR T = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast(&V)[0] ); + _mm_store_ss( (float*)&pDestination[2], T ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat3 +( + XMFLOAT3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + pDestination->x = V.vector4_f32[0]; + pDestination->y = V.vector4_f32[1]; + pDestination->z = V.vector4_f32[2]; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + XMVECTOR T1 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR T2 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + _mm_store_ss( &pDestination->x, V ); + _mm_store_ss( &pDestination->y, T1 ); + _mm_store_ss( &pDestination->z, T2 ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat3A +( + XMFLOAT3A* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination->x = V.vector4_f32[0]; + pDestination->y = V.vector4_f32[1]; + pDestination->z = V.vector4_f32[2]; + +#elif defined(_XM_SSE_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + XMVECTOR T = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast(&V)[0] ); + _mm_store_ss( &pDestination->z, T ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUHenDN3 +( + XMUHENDN3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {2047.0f, 2047.0f, 1023.0f, 0.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + + pDestination->v = (((UINT)N.vector4_f32[2] & 0x3FF) << 22) | + (((UINT)N.vector4_f32[1] & 0x7FF) << 11) | + (((UINT)N.vector4_f32[0] & 0x7FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleUHenDN3 = {2047.0f, 2047.0f*2048.0f,1023.0f*(2048.0f*2048.0f)/2.0f,1.0f}; + static const XMVECTORI32 MaskUHenDN3 = {0x7FF,0x7FF<<11,0x3FF<<(22-1),0}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUHenDN3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUHenDN3); + // Do a horizontal or of 3 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1)); + // i = x|y + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1)); + // Add Z to itself to perform a single bit left shift + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUHenD3 +( + XMUHEND3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Max = {2047.0f, 2047.0f, 1023.0f, 0.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max); + + pDestination->v = (((UINT)N.vector4_f32[2] & 0x3FF) << 22) | + (((UINT)N.vector4_f32[1] & 0x7FF) << 11) | + (((UINT)N.vector4_f32[0] & 0x7FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MaxUHenD3 = { 2047.0f, 2047.0f, 1023.0f, 1.0f}; + static const XMVECTORF32 ScaleUHenD3 = {1.0f, 2048.0f,(2048.0f*2048.0f)/2.0f,1.0f}; + static const XMVECTORI32 MaskUHenD3 = {0x7FF,0x7FF<<11,0x3FF<<(22-1),0}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,MaxUHenD3); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUHenD3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUHenD3); + // Do a horizontal or of 3 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1)); + // i = x|y + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1)); + // Add Z to itself to perform a single bit left shift + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreHenDN3 +( + XMHENDN3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {1023.0f, 1023.0f, 511.0f, 1.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + + pDestination->v = (((INT)N.vector4_f32[2] & 0x3FF) << 22) | + (((INT)N.vector4_f32[1] & 0x7FF) << 11) | + (((INT)N.vector4_f32[0] & 0x7FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleHenDN3 = {1023.0f, 1023.0f*2048.0f,511.0f*(2048.0f*2048.0f),1.0f}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleHenDN3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,g_XMMaskHenD3); + // Do a horizontal or of all 4 entries + vResult = _mm_shuffle_ps(reinterpret_cast(&vResulti)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreHenD3 +( + XMHEND3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-1023.0f, -1023.0f, -511.0f, -1.0f}; + static CONST XMVECTOR Max = {1023.0f, 1023.0f, 511.0f, 1.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + + pDestination->v = (((INT)N.vector4_f32[2] & 0x3FF) << 22) | + (((INT)N.vector4_f32[1] & 0x7FF) << 11) | + (((INT)N.vector4_f32[0] & 0x7FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MinHenD3 = {-1023.0f,-1023.0f,-511.0f,-1.0f}; + static const XMVECTORF32 MaxHenD3 = { 1023.0f, 1023.0f, 511.0f, 1.0f}; + static const XMVECTORF32 ScaleHenD3 = {1.0f, 2048.0f,(2048.0f*2048.0f),1.0f}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,MinHenD3); + vResult = _mm_min_ps(vResult,MaxHenD3); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleHenD3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,g_XMMaskHenD3); + // Do a horizontal or of all 4 entries + vResult = _mm_shuffle_ps(reinterpret_cast(&vResulti)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUDHenN3 +( + XMUDHENN3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {1023.0f, 2047.0f, 2047.0f, 0.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + + pDestination->v = (((UINT)N.vector4_f32[2] & 0x7FF) << 21) | + (((UINT)N.vector4_f32[1] & 0x7FF) << 10) | + (((UINT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleUDHenN3 = {1023.0f,2047.0f*1024.0f,2047.0f*(1024.0f*2048.0f)/2.0f,1.0f}; + static const XMVECTORI32 MaskUDHenN3 = {0x3FF,0x7FF<<10,0x7FF<<(21-1),0}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUDHenN3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUDHenN3); + // Do a horizontal or of 3 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1)); + // i = x|y + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1)); + // Add Z to itself to perform a single bit left shift + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUDHen3 +( + XMUDHEN3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Max = {1023.0f, 2047.0f, 2047.0f, 0.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max); + + pDestination->v = (((UINT)N.vector4_f32[2] & 0x7FF) << 21) | + (((UINT)N.vector4_f32[1] & 0x7FF) << 10) | + (((UINT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MaxUDHen3 = { 1023.0f, 2047.0f, 2047.0f, 1.0f}; + static const XMVECTORF32 ScaleUDHen3 = {1.0f, 1024.0f,(1024.0f*2048.0f)/2.0f,1.0f}; + static const XMVECTORI32 MaskUDHen3 = {0x3FF,0x7FF<<10,0x7FF<<(21-1),0}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,MaxUDHen3); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUDHen3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUDHen3); + // Do a horizontal or of 3 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1)); + // i = x|y + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1)); + // Add Z to itself to perform a single bit left shift + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreDHenN3 +( + XMDHENN3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {511.0f, 1023.0f, 1023.0f, 1.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + + pDestination->v = (((INT)N.vector4_f32[2] & 0x7FF) << 21) | + (((INT)N.vector4_f32[1] & 0x7FF) << 10) | + (((INT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleDHenN3 = {511.0f, 1023.0f*1024.0f,1023.0f*(1024.0f*2048.0f),1.0f}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleDHenN3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,g_XMMaskDHen3); + // Do a horizontal or of all 4 entries + vResult = _mm_shuffle_ps(reinterpret_cast(&vResulti)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreDHen3 +( + XMDHEN3* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-511.0f, -1023.0f, -1023.0f, -1.0f}; + static CONST XMVECTOR Max = {511.0f, 1023.0f, 1023.0f, 1.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + + pDestination->v = (((INT)N.vector4_f32[2] & 0x7FF) << 21) | + (((INT)N.vector4_f32[1] & 0x7FF) << 10) | + (((INT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MinDHen3 = {-511.0f,-1023.0f,-1023.0f,-1.0f}; + static const XMVECTORF32 MaxDHen3 = { 511.0f, 1023.0f, 1023.0f, 1.0f}; + static const XMVECTORF32 ScaleDHen3 = {1.0f, 1024.0f,(1024.0f*2048.0f),1.0f}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,MinDHen3); + vResult = _mm_min_ps(vResult,MaxDHen3); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleDHen3); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,g_XMMaskDHen3); + // Do a horizontal or of all 4 entries + vResult = _mm_shuffle_ps(reinterpret_cast(&vResulti)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreU565 +( + XMU565* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Max = {31.0f, 63.0f, 31.0f, 0.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,Max); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // No SSE operations will write to 16-bit values, so we have to extract them manually + USHORT x = static_cast(_mm_extract_epi16(vInt,0)); + USHORT y = static_cast(_mm_extract_epi16(vInt,2)); + USHORT z = static_cast(_mm_extract_epi16(vInt,4)); + pDestination->v = ((z & 0x1F) << 11) | + ((y & 0x3F) << 5) | + ((x & 0x1F)); +#else + XMVECTOR N; + static CONST XMVECTORF32 Max = {31.0f, 63.0f, 31.0f, 0.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max.v); + N = XMVectorRound(N); + + pDestination->v = (((USHORT)N.vector4_f32[2] & 0x1F) << 11) | + (((USHORT)N.vector4_f32[1] & 0x3F) << 5) | + (((USHORT)N.vector4_f32[0] & 0x1F)); +#endif !_XM_SSE_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat3PK +( + XMFLOAT3PK* pDestination, + FXMVECTOR V +) +{ + _DECLSPEC_ALIGN_16_ UINT IValue[4]; + UINT I, Sign, j; + UINT Result[3]; + + XMASSERT(pDestination); + + XMStoreFloat3A( (XMFLOAT3A*)&IValue, V ); + + // X & Y Channels (5-bit exponent, 6-bit mantissa) + for(j=0; j < 2; ++j) + { + Sign = IValue[j] & 0x80000000; + I = IValue[j] & 0x7FFFFFFF; + + if ((I & 0x7F800000) == 0x7F800000) + { + // INF or NAN + Result[j] = 0x7c0; + if (( I & 0x7FFFFF ) != 0) + { + Result[j] = 0x7c0 | (((I>>17)|(I>11)|(I>>6)|(I))&0x3f); + } + else if ( Sign ) + { + // -INF is clamped to 0 since 3PK is positive only + Result[j] = 0; + } + } + else if ( Sign ) + { + // 3PK is positive only, so clamp to zero + Result[j] = 0; + } + else if (I > 0x477E0000U) + { + // The number is too large to be represented as a float11, set to max + Result[j] = 0x7BF; + } + else + { + if (I < 0x38800000U) + { + // The number is too small to be represented as a normalized float11 + // Convert it to a denormalized value. + UINT Shift = 113U - (I >> 23U); + I = (0x800000U | (I & 0x7FFFFFU)) >> Shift; + } + else + { + // Rebias the exponent to represent the value as a normalized float11 + I += 0xC8000000U; + } + + Result[j] = ((I + 0xFFFFU + ((I >> 17U) & 1U)) >> 17U)&0x7ffU; + } + } + + // Z Channel (5-bit exponent, 5-bit mantissa) + Sign = IValue[2] & 0x80000000; + I = IValue[2] & 0x7FFFFFFF; + + if ((I & 0x7F800000) == 0x7F800000) + { + // INF or NAN + Result[2] = 0x3e0; + if ( I & 0x7FFFFF ) + { + Result[2] = 0x3e0 | (((I>>18)|(I>13)|(I>>3)|(I))&0x1f); + } + else if ( Sign ) + { + // -INF is clamped to 0 since 3PK is positive only + Result[2] = 0; + } + } + else if ( Sign ) + { + // 3PK is positive only, so clamp to zero + Result[2] = 0; + } + else if (I > 0x477C0000U) + { + // The number is too large to be represented as a float10, set to max + Result[2] = 0x3df; + } + else + { + if (I < 0x38800000U) + { + // The number is too small to be represented as a normalized float10 + // Convert it to a denormalized value. + UINT Shift = 113U - (I >> 23U); + I = (0x800000U | (I & 0x7FFFFFU)) >> Shift; + } + else + { + // Rebias the exponent to represent the value as a normalized float10 + I += 0xC8000000U; + } + + Result[2] = ((I + 0x1FFFFU + ((I >> 18U) & 1U)) >> 18U)&0x3ffU; + } + + // Pack Result into memory + pDestination->v = (Result[0] & 0x7ff) + | ( (Result[1] & 0x7ff) << 11 ) + | ( (Result[2] & 0x3ff) << 22 ); +} + + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat3SE +( + XMFLOAT3SE* pDestination, + FXMVECTOR V +) +{ + _DECLSPEC_ALIGN_16_ UINT IValue[4]; + UINT I, Sign, j, T; + UINT Frac[3]; + UINT Exp[3]; + + + XMASSERT(pDestination); + + XMStoreFloat3A( (XMFLOAT3A*)&IValue, V ); + + // X, Y, Z Channels (5-bit exponent, 9-bit mantissa) + for(j=0; j < 3; ++j) + { + Sign = IValue[j] & 0x80000000; + I = IValue[j] & 0x7FFFFFFF; + + if ((I & 0x7F800000) == 0x7F800000) + { + // INF or NAN + Exp[j] = 0x1f; + if (( I & 0x7FFFFF ) != 0) + { + Frac[j] = ((I>>14)|(I>5)|(I))&0x1ff; + } + else if ( Sign ) + { + // -INF is clamped to 0 since 3SE is positive only + Exp[j] = Frac[j] = 0; + } + } + else if ( Sign ) + { + // 3SE is positive only, so clamp to zero + Exp[j] = Frac[j] = 0; + } + else if (I > 0x477FC000U) + { + // The number is too large, set to max + Exp[j] = 0x1e; + Frac[j] = 0x1ff; + } + else + { + if (I < 0x38800000U) + { + // The number is too small to be represented as a normalized float11 + // Convert it to a denormalized value. + UINT Shift = 113U - (I >> 23U); + I = (0x800000U | (I & 0x7FFFFFU)) >> Shift; + } + else + { + // Rebias the exponent to represent the value as a normalized float11 + I += 0xC8000000U; + } + + T = ((I + 0x1FFFU + ((I >> 14U) & 1U)) >> 14U)&0x3fffU; + + Exp[j] = (T & 0x3E00) >> 9; + Frac[j] = T & 0x1ff; + } + } + + // Adjust to a shared exponent + T = XMMax( Exp[0], XMMax( Exp[1], Exp[2] ) ); + + Frac[0] = Frac[0] >> (T - Exp[0]); + Frac[1] = Frac[1] >> (T - Exp[1]); + Frac[2] = Frac[2] >> (T - Exp[2]); + + // Store packed into memory + pDestination->xm = Frac[0]; + pDestination->ym = Frac[1]; + pDestination->zm = Frac[2]; + pDestination->e = T; +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreInt4 +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + + pDestination[0] = V.vector4_u32[0]; + pDestination[1] = V.vector4_u32[1]; + pDestination[2] = V.vector4_u32[2]; + pDestination[3] = V.vector4_u32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + + _mm_storeu_si128( (__m128i*)pDestination, reinterpret_cast(&V)[0] ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreInt4A +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination[0] = V.vector4_u32[0]; + pDestination[1] = V.vector4_u32[1]; + pDestination[2] = V.vector4_u32[2]; + pDestination[3] = V.vector4_u32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + _mm_store_si128( (__m128i*)pDestination, reinterpret_cast(&V)[0] ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreInt4NC +( + UINT* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + pDestination[0] = V.vector4_u32[0]; + pDestination[1] = V.vector4_u32[1]; + pDestination[2] = V.vector4_u32[2]; + pDestination[3] = V.vector4_u32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + _mm_storeu_si128( (__m128i*)pDestination, reinterpret_cast(&V)[0] ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4 +( + XMFLOAT4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + + pDestination->x = V.vector4_f32[0]; + pDestination->y = V.vector4_f32[1]; + pDestination->z = V.vector4_f32[2]; + pDestination->w = V.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + + _mm_storeu_ps( &pDestination->x, V ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4A +( + XMFLOAT4A* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination->x = V.vector4_f32[0]; + pDestination->y = V.vector4_f32[1]; + pDestination->z = V.vector4_f32[2]; + pDestination->w = V.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + _mm_store_ps( &pDestination->x, V ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4NC +( + XMFLOAT4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + pDestination->x = V.vector4_f32[0]; + pDestination->y = V.vector4_f32[1]; + pDestination->z = V.vector4_f32[2]; + pDestination->w = V.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 3) == 0); + + _mm_storeu_ps( &pDestination->x, V ); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreHalf4 +( + XMHALF4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + + pDestination->x = XMConvertFloatToHalf(V.vector4_f32[0]); + pDestination->y = XMConvertFloatToHalf(V.vector4_f32[1]); + pDestination->z = XMConvertFloatToHalf(V.vector4_f32[2]); + pDestination->w = XMConvertFloatToHalf(V.vector4_f32[3]); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + pDestination->x = XMConvertFloatToHalf(XMVectorGetX(V)); + pDestination->y = XMConvertFloatToHalf(XMVectorGetY(V)); + pDestination->z = XMConvertFloatToHalf(XMVectorGetZ(V)); + pDestination->w = XMConvertFloatToHalf(XMVectorGetW(V)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreShortN4 +( + XMSHORTN4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + N = XMVectorRound(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + pDestination->z = (SHORT)N.vector4_f32[2]; + pDestination->w = (SHORT)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + + XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + vResult = _mm_mul_ps(vResult,Scale); + __m128i vResulti = _mm_cvtps_epi32(vResult); + vResulti = _mm_packs_epi32(vResulti,vResulti); + _mm_store_sd(reinterpret_cast(&pDestination->x),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreShort4 +( + XMSHORT4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f}; + static CONST XMVECTOR Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + N = XMVectorRound(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + pDestination->z = (SHORT)N.vector4_f32[2]; + pDestination->w = (SHORT)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f}; + static CONST XMVECTORF32 Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,Min); + vResult = _mm_min_ps(vResult,Max); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // Pack the ints into shorts + vInt = _mm_packs_epi32(vInt,vInt); + _mm_store_sd(reinterpret_cast(&pDestination->x),reinterpret_cast(&vInt)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUShortN4 +( + XMUSHORTN4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), g_XMOne.v); + N = XMVectorMultiplyAdd(N, Scale.v, g_XMOneHalf.v); + N = XMVectorTruncate(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + pDestination->z = (SHORT)N.vector4_f32[2]; + pDestination->w = (SHORT)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + vResult = _mm_mul_ps(vResult,Scale); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // Since the SSE pack instruction clamps using signed rules, + // manually extract the values to store them to memory + pDestination->x = static_cast(_mm_extract_epi16(vInt,0)); + pDestination->y = static_cast(_mm_extract_epi16(vInt,2)); + pDestination->z = static_cast(_mm_extract_epi16(vInt,4)); + pDestination->w = static_cast(_mm_extract_epi16(vInt,6)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUShort4 +( + XMUSHORT4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max); + N = XMVectorRound(N); + + pDestination->x = (SHORT)N.vector4_f32[0]; + pDestination->y = (SHORT)N.vector4_f32[1]; + pDestination->z = (SHORT)N.vector4_f32[2]; + pDestination->w = (SHORT)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,Max); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // Since the SSE pack instruction clamps using signed rules, + // manually extract the values to store them to memory + pDestination->x = static_cast(_mm_extract_epi16(vInt,0)); + pDestination->y = static_cast(_mm_extract_epi16(vInt,2)); + pDestination->z = static_cast(_mm_extract_epi16(vInt,4)); + pDestination->w = static_cast(_mm_extract_epi16(vInt,6)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreXIcoN4 +( + XMXICON4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Min = {-1.0f, -1.0f, -1.0f, 0.0f}; + static CONST XMVECTORF32 Scale = {524287.0f, 524287.0f, 524287.0f, 15.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min.v, g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + N = XMVectorRound(N); + + pDestination->v = ((UINT64)N.vector4_f32[3] << 60) | + (((INT64)N.vector4_f32[2] & 0xFFFFF) << 40) | + (((INT64)N.vector4_f32[1] & 0xFFFFF) << 20) | + (((INT64)N.vector4_f32[0] & 0xFFFFF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + // Note: Masks are x,w,y and z + static const XMVECTORF32 MinXIcoN4 = {-1.0f, 0.0f,-1.0f,-1.0f}; + static const XMVECTORF32 ScaleXIcoN4 = {524287.0f,15.0f*4096.0f*65536.0f*0.5f,524287.0f*4096.0f,524287.0f}; + static const XMVECTORI32 MaskXIcoN4 = {0xFFFFF,0xF<<((60-32)-1),0xFFFFF000,0xFFFFF}; + + // Clamp to bounds + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0)); + vResult = _mm_max_ps(vResult,MinXIcoN4); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleXIcoN4); + // Convert to integer (w is unsigned) + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off unused bits + vResulti = _mm_and_si128(vResulti,MaskXIcoN4); + // Isolate Y + __m128i vResulti2 = _mm_and_si128(vResulti,g_XMMaskY); + // Double Y (Really W) to fixup for unsigned conversion + vResulti = _mm_add_epi32(vResulti,vResulti2); + // Shift y and z to straddle the 32-bit boundary + vResulti2 = _mm_srli_si128(vResulti,(64+12)/8); + // Shift it into place + vResulti2 = _mm_slli_si128(vResulti2,20/8); + // i = x|y<<20|z<<40|w<<60 + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_sd(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreXIco4 +( + XMXICO4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Min = {-524287.0f, -524287.0f, -524287.0f, 0.0f}; + static CONST XMVECTORF32 Max = {524287.0f, 524287.0f, 524287.0f, 15.0f}; + + XMASSERT(pDestination); + N = XMVectorClamp(V, Min.v, Max.v); + pDestination->v = ((UINT64)N.vector4_f32[3] << 60) | + (((INT64)N.vector4_f32[2] & 0xFFFFF) << 40) | + (((INT64)N.vector4_f32[1] & 0xFFFFF) << 20) | + (((INT64)N.vector4_f32[0] & 0xFFFFF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + // Note: Masks are x,w,y and z + static const XMVECTORF32 MinXIco4 = {-524287.0f, 0.0f,-524287.0f,-524287.0f}; + static const XMVECTORF32 MaxXIco4 = { 524287.0f,15.0f, 524287.0f, 524287.0f}; + static const XMVECTORF32 ScaleXIco4 = {1.0f,4096.0f*65536.0f*0.5f,4096.0f,1.0f}; + static const XMVECTORI32 MaskXIco4 = {0xFFFFF,0xF<<((60-1)-32),0xFFFFF000,0xFFFFF}; + // Clamp to bounds + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0)); + vResult = _mm_max_ps(vResult,MinXIco4); + vResult = _mm_min_ps(vResult,MaxXIco4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleXIco4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskXIco4); + // Isolate Y + __m128i vResulti2 = _mm_and_si128(vResulti,g_XMMaskY); + // Double Y (Really W) to fixup for unsigned conversion + vResulti = _mm_add_epi32(vResulti,vResulti2); + // Shift y and z to straddle the 32-bit boundary + vResulti2 = _mm_srli_si128(vResulti,(64+12)/8); + // Shift it into place + vResulti2 = _mm_slli_si128(vResulti2,20/8); + // i = x|y<<20|z<<40|w<<60 + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_sd(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUIcoN4 +( + XMUICON4* pDestination, + FXMVECTOR V +) +{ + #define XM_URange ((FLOAT)(1 << 20)) + #define XM_URangeDiv2 ((FLOAT)(1 << 19)) + #define XM_UMaxXYZ ((FLOAT)((1 << 20) - 1)) + #define XM_UMaxW ((FLOAT)((1 << 4) - 1)) + #define XM_ScaleXYZ (-(FLOAT)((1 << 20) - 1) / XM_PACK_FACTOR) + #define XM_ScaleW (-(FLOAT)((1 << 4) - 1) / XM_PACK_FACTOR) + #define XM_Scale (-1.0f / XM_PACK_FACTOR) + #define XM_Offset (3.0f) + +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {1048575.0f, 1048575.0f, 1048575.0f, 15.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), g_XMOne.v); + N = XMVectorMultiplyAdd(N, Scale.v, g_XMOneHalf.v); + + pDestination->v = ((UINT64)N.vector4_f32[3] << 60) | + (((UINT64)N.vector4_f32[2] & 0xFFFFF) << 40) | + (((UINT64)N.vector4_f32[1] & 0xFFFFF) << 20) | + (((UINT64)N.vector4_f32[0] & 0xFFFFF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + // Note: Masks are x,w,y and z + static const XMVECTORF32 ScaleUIcoN4 = {1048575.0f,15.0f*4096.0f*65536.0f,1048575.0f*4096.0f,1048575.0f}; + static const XMVECTORI32 MaskUIcoN4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF}; + static const XMVECTORF32 AddUIcoN4 = {0.0f,-32768.0f*65536.0f,-32768.0f*65536.0f,0.0f}; + // Clamp to bounds + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0)); + vResult = _mm_max_ps(vResult,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUIcoN4); + // Adjust for unsigned entries + vResult = _mm_add_ps(vResult,AddUIcoN4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Fix the signs on the unsigned entries + vResulti = _mm_xor_si128(vResulti,g_XMFlipYZ); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUIcoN4); + // Shift y and z to straddle the 32-bit boundary + __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8); + // Shift it into place + vResulti2 = _mm_slli_si128(vResulti2,20/8); + // i = x|y<<20|z<<40|w<<60 + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_sd(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ + + #undef XM_URange + #undef XM_URangeDiv2 + #undef XM_UMaxXYZ + #undef XM_UMaxW + #undef XM_ScaleXYZ + #undef XM_ScaleW + #undef XM_Scale + #undef XM_Offset +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUIco4 +( + XMUICO4* pDestination, + FXMVECTOR V +) +{ + #define XM_Scale (-1.0f / XM_PACK_FACTOR) + #define XM_URange ((FLOAT)(1 << 20)) + #define XM_URangeDiv2 ((FLOAT)(1 << 19)) + +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Max = {1048575.0f, 1048575.0f, 1048575.0f, 15.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max); + N = XMVectorRound(N); + + pDestination->v = ((UINT64)N.vector4_f32[3] << 60) | + (((UINT64)N.vector4_f32[2] & 0xFFFFF) << 40) | + (((UINT64)N.vector4_f32[1] & 0xFFFFF) << 20) | + (((UINT64)N.vector4_f32[0] & 0xFFFFF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + // Note: Masks are x,w,y and z + static const XMVECTORF32 MaxUIco4 = { 1048575.0f, 15.0f, 1048575.0f, 1048575.0f}; + static const XMVECTORF32 ScaleUIco4 = {1.0f,4096.0f*65536.0f,4096.0f,1.0f}; + static const XMVECTORI32 MaskUIco4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF}; + static const XMVECTORF32 AddUIco4 = {0.0f,-32768.0f*65536.0f,-32768.0f*65536.0f,0.0f}; + // Clamp to bounds + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0)); + vResult = _mm_max_ps(vResult,g_XMZero); + vResult = _mm_min_ps(vResult,MaxUIco4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUIco4); + vResult = _mm_add_ps(vResult,AddUIco4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + vResulti = _mm_xor_si128(vResulti,g_XMFlipYZ); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUIco4); + // Shift y and z to straddle the 32-bit boundary + __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8); + // Shift it into place + vResulti2 = _mm_slli_si128(vResulti2,20/8); + // i = x|y<<20|z<<40|w<<60 + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_sd(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ + + #undef XM_Scale + #undef XM_URange + #undef XM_URangeDiv2 +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreIcoN4 +( + XMICON4* pDestination, + FXMVECTOR V +) +{ + #define XM_Scale (-1.0f / XM_PACK_FACTOR) + #define XM_URange ((FLOAT)(1 << 4)) + #define XM_Offset (3.0f) + #define XM_UMaxXYZ ((FLOAT)((1 << (20 - 1)) - 1)) + #define XM_UMaxW ((FLOAT)((1 << (4 - 1)) - 1)) + +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {524287.0f, 524287.0f, 524287.0f, 7.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v); + N = XMVectorMultiplyAdd(N, Scale.v, g_XMNegativeZero.v); + N = XMVectorRound(N); + + pDestination->v = ((UINT64)N.vector4_f32[3] << 60) | + (((UINT64)N.vector4_f32[2] & 0xFFFFF) << 40) | + (((UINT64)N.vector4_f32[1] & 0xFFFFF) << 20) | + (((UINT64)N.vector4_f32[0] & 0xFFFFF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + // Note: Masks are x,w,y and z + static const XMVECTORF32 ScaleIcoN4 = {524287.0f,7.0f*4096.0f*65536.0f,524287.0f*4096.0f,524287.0f}; + static const XMVECTORI32 MaskIcoN4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF}; + // Clamp to bounds + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0)); + vResult = _mm_max_ps(vResult,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleIcoN4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskIcoN4); + // Shift y and z to straddle the 32-bit boundary + __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8); + // Shift it into place + vResulti2 = _mm_slli_si128(vResulti2,20/8); + // i = x|y<<20|z<<40|w<<60 + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_sd(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ + + #undef XM_Scale + #undef XM_URange + #undef XM_Offset + #undef XM_UMaxXYZ + #undef XM_UMaxW +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreIco4 +( + XMICO4* pDestination, + FXMVECTOR V +) +{ + #define XM_Scale (-1.0f / XM_PACK_FACTOR) + #define XM_URange ((FLOAT)(1 << 4)) + #define XM_Offset (3.0f) + +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-524287.0f, -524287.0f, -524287.0f, -7.0f}; + static CONST XMVECTOR Max = {524287.0f, 524287.0f, 524287.0f, 7.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + N = XMVectorRound(N); + + pDestination->v = ((INT64)N.vector4_f32[3] << 60) | + (((INT64)N.vector4_f32[2] & 0xFFFFF) << 40) | + (((INT64)N.vector4_f32[1] & 0xFFFFF) << 20) | + (((INT64)N.vector4_f32[0] & 0xFFFFF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + // Note: Masks are x,w,y and z + static const XMVECTORF32 MinIco4 = {-524287.0f,-7.0f,-524287.0f,-524287.0f}; + static const XMVECTORF32 MaxIco4 = { 524287.0f, 7.0f, 524287.0f, 524287.0f}; + static const XMVECTORF32 ScaleIco4 = {1.0f,4096.0f*65536.0f,4096.0f,1.0f}; + static const XMVECTORI32 MaskIco4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF}; + // Clamp to bounds + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0)); + vResult = _mm_max_ps(vResult,MinIco4); + vResult = _mm_min_ps(vResult,MaxIco4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleIco4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskIco4); + // Shift y and z to straddle the 32-bit boundary + __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8); + // Shift it into place + vResulti2 = _mm_slli_si128(vResulti2,20/8); + // i = x|y<<20|z<<40|w<<60 + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_sd(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ + + #undef XM_Scale + #undef XM_URange + #undef XM_Offset +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreXDecN4 +( + XMXDECN4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Min = {-1.0f, -1.0f, -1.0f, 0.0f}; + static CONST XMVECTORF32 Scale = {511.0f, 511.0f, 511.0f, 3.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min.v, g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + N = XMVectorRound(N); + + pDestination->v = ((UINT)N.vector4_f32[3] << 30) | + (((INT)N.vector4_f32[2] & 0x3FF) << 20) | + (((INT)N.vector4_f32[1] & 0x3FF) << 10) | + (((INT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 Min = {-1.0f, -1.0f, -1.0f, 0.0f}; + static const XMVECTORF32 Scale = {511.0f, 511.0f*1024.0f, 511.0f*1048576.0f,3.0f*536870912.0f}; + static const XMVECTORI32 ScaleMask = {0x3FF,0x3FF<<10,0x3FF<<20,0x3<<29}; + XMASSERT(pDestination); + XMVECTOR vResult = _mm_max_ps(V,Min); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,Scale); + // Convert to int (W is unsigned) + __m128i vResulti = _mm_cvtps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,ScaleMask); + // To fix W, add itself to shift it up to <<30 instead of <<29 + __m128i vResultw = _mm_and_si128(vResulti,g_XMMaskW); + vResulti = _mm_add_epi32(vResulti,vResultw); + // Do a horizontal or of all 4 entries + vResult = _mm_shuffle_ps(reinterpret_cast(&vResulti)[0],reinterpret_cast(&vResulti)[0],_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + vResulti = _mm_or_si128(vResulti,reinterpret_cast(&vResult)[0]); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreXDec4 +( + XMXDEC4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-511.0f, -511.0f, -511.0f, 0.0f}; + static CONST XMVECTOR Max = {511.0f, 511.0f, 511.0f, 3.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + + pDestination->v = ((UINT)N.vector4_f32[3] << 30) | + (((INT)N.vector4_f32[2] & 0x3FF) << 20) | + (((INT)N.vector4_f32[1] & 0x3FF) << 10) | + (((INT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MinXDec4 = {-511.0f,-511.0f,-511.0f, 0.0f}; + static const XMVECTORF32 MaxXDec4 = { 511.0f, 511.0f, 511.0f, 3.0f}; + static const XMVECTORF32 ScaleXDec4 = {1.0f,1024.0f/2.0f,1024.0f*1024.0f,1024.0f*1024.0f*1024.0f/2.0f}; + static const XMVECTORI32 MaskXDec4= {0x3FF,0x3FF<<(10-1),0x3FF<<20,0x3<<(30-1)}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,MinXDec4); + vResult = _mm_min_ps(vResult,MaxXDec4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleXDec4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskXDec4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // Perform a single bit left shift on y|w + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUDecN4 +( + XMUDECN4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {1023.0f, 1023.0f, 1023.0f, 3.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + + pDestination->v = ((UINT)N.vector4_f32[3] << 30) | + (((UINT)N.vector4_f32[2] & 0x3FF) << 20) | + (((UINT)N.vector4_f32[1] & 0x3FF) << 10) | + (((UINT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleUDecN4 = {1023.0f,1023.0f*1024.0f*0.5f,1023.0f*1024.0f*1024.0f,3.0f*1024.0f*1024.0f*1024.0f*0.5f}; + static const XMVECTORI32 MaskUDecN4= {0x3FF,0x3FF<<(10-1),0x3FF<<20,0x3<<(30-1)}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUDecN4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUDecN4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // Perform a left shift by one bit on y|w + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUDec4 +( + XMUDEC4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Max = {1023.0f, 1023.0f, 1023.0f, 3.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max); + + pDestination->v = ((UINT)N.vector4_f32[3] << 30) | + (((UINT)N.vector4_f32[2] & 0x3FF) << 20) | + (((UINT)N.vector4_f32[1] & 0x3FF) << 10) | + (((UINT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MaxUDec4 = { 1023.0f, 1023.0f, 1023.0f, 3.0f}; + static const XMVECTORF32 ScaleUDec4 = {1.0f,1024.0f/2.0f,1024.0f*1024.0f,1024.0f*1024.0f*1024.0f/2.0f}; + static const XMVECTORI32 MaskUDec4= {0x3FF,0x3FF<<(10-1),0x3FF<<20,0x3<<(30-1)}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,MaxUDec4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUDec4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUDec4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // Perform a left shift by one bit on y|w + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreDecN4 +( + XMDECN4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {511.0f, 511.0f, 511.0f, 1.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v); + N = XMVectorMultiply(N, Scale.v); + + pDestination->v = ((INT)N.vector4_f32[3] << 30) | + (((INT)N.vector4_f32[2] & 0x3FF) << 20) | + (((INT)N.vector4_f32[1] & 0x3FF) << 10) | + (((INT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleDecN4 = {511.0f,511.0f*1024.0f,511.0f*1024.0f*1024.0f,1.0f*1024.0f*1024.0f*1024.0f}; + static const XMVECTORI32 MaskDecN4= {0x3FF,0x3FF<<10,0x3FF<<20,0x3<<30}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleDecN4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskDecN4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreDec4 +( + XMDEC4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-511.0f, -511.0f, -511.0f, -1.0f}; + static CONST XMVECTOR Max = {511.0f, 511.0f, 511.0f, 1.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + + pDestination->v = ((INT)N.vector4_f32[3] << 30) | + (((INT)N.vector4_f32[2] & 0x3FF) << 20) | + (((INT)N.vector4_f32[1] & 0x3FF) << 10) | + (((INT)N.vector4_f32[0] & 0x3FF)); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MinDec4 = {-511.0f,-511.0f,-511.0f,-1.0f}; + static const XMVECTORF32 MaxDec4 = { 511.0f, 511.0f, 511.0f, 1.0f}; + static const XMVECTORF32 ScaleDec4 = {1.0f,1024.0f,1024.0f*1024.0f,1024.0f*1024.0f*1024.0f}; + static const XMVECTORI32 MaskDec4= {0x3FF,0x3FF<<10,0x3FF<<20,0x3<<30}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,MinDec4); + vResult = _mm_min_ps(vResult,MaxDec4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleDec4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskDec4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUByteN4 +( + XMUBYTEN4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {255.0f, 255.0f, 255.0f, 255.0f}; + + XMASSERT(pDestination); + + N = XMVectorSaturate(V); + N = XMVectorMultiply(N, Scale.v); + N = XMVectorRound(N); + + pDestination->x = (BYTE)N.vector4_f32[0]; + pDestination->y = (BYTE)N.vector4_f32[1]; + pDestination->z = (BYTE)N.vector4_f32[2]; + pDestination->w = (BYTE)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleUByteN4 = {255.0f,255.0f*256.0f*0.5f,255.0f*256.0f*256.0f,255.0f*256.0f*256.0f*256.0f*0.5f}; + static const XMVECTORI32 MaskUByteN4 = {0xFF,0xFF<<(8-1),0xFF<<16,0xFF<<(24-1)}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUByteN4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUByteN4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // Perform a single bit left shift to fix y|w + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUByte4 +( + XMUBYTE4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Max = {255.0f, 255.0f, 255.0f, 255.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max); + N = XMVectorRound(N); + + pDestination->x = (BYTE)N.vector4_f32[0]; + pDestination->y = (BYTE)N.vector4_f32[1]; + pDestination->z = (BYTE)N.vector4_f32[2]; + pDestination->w = (BYTE)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MaxUByte4 = { 255.0f, 255.0f, 255.0f, 255.0f}; + static const XMVECTORF32 ScaleUByte4 = {1.0f,256.0f*0.5f,256.0f*256.0f,256.0f*256.0f*256.0f*0.5f}; + static const XMVECTORI32 MaskUByte4 = {0xFF,0xFF<<(8-1),0xFF<<16,0xFF<<(24-1)}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,MaxUByte4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleUByte4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskUByte4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // Perform a single bit left shift to fix y|w + vResulti2 = _mm_add_epi32(vResulti2,vResulti2); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreByteN4 +( + XMBYTEN4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {127.0f, 127.0f, 127.0f, 127.0f}; + + XMASSERT(pDestination); + + N = XMVectorMultiply(V, Scale.v); + N = XMVectorRound(N); + + pDestination->x = (CHAR)N.vector4_f32[0]; + pDestination->y = (CHAR)N.vector4_f32[1]; + pDestination->z = (CHAR)N.vector4_f32[2]; + pDestination->w = (CHAR)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 ScaleByteN4 = {127.0f,127.0f*256.0f,127.0f*256.0f*256.0f,127.0f*256.0f*256.0f*256.0f}; + static const XMVECTORI32 MaskByteN4 = {0xFF,0xFF<<8,0xFF<<16,0xFF<<24}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleByteN4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskByteN4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreByte4 +( + XMBYTE4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTOR Min = {-127.0f, -127.0f, -127.0f, -127.0f}; + static CONST XMVECTOR Max = {127.0f, 127.0f, 127.0f, 127.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, Min, Max); + N = XMVectorRound(N); + + pDestination->x = (CHAR)N.vector4_f32[0]; + pDestination->y = (CHAR)N.vector4_f32[1]; + pDestination->z = (CHAR)N.vector4_f32[2]; + pDestination->w = (CHAR)N.vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static const XMVECTORF32 MinByte4 = {-127.0f,-127.0f,-127.0f,-127.0f}; + static const XMVECTORF32 MaxByte4 = { 127.0f, 127.0f, 127.0f, 127.0f}; + static const XMVECTORF32 ScaleByte4 = {1.0f,256.0f,256.0f*256.0f,256.0f*256.0f*256.0f}; + static const XMVECTORI32 MaskByte4 = {0xFF,0xFF<<8,0xFF<<16,0xFF<<24}; + // Clamp to bounds + XMVECTOR vResult = _mm_max_ps(V,MinByte4); + vResult = _mm_min_ps(vResult,MaxByte4); + // Scale by multiplication + vResult = _mm_mul_ps(vResult,ScaleByte4); + // Convert to int + __m128i vResulti = _mm_cvttps_epi32(vResult); + // Mask off any fraction + vResulti = _mm_and_si128(vResulti,MaskByte4); + // Do a horizontal or of 4 entries + __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2)); + // x = x|z, y = y|w + vResulti = _mm_or_si128(vResulti,vResulti2); + // Move Z to the x position + vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1)); + // i = x|y|z|w + vResulti = _mm_or_si128(vResulti,vResulti2); + _mm_store_ss(reinterpret_cast(&pDestination->v),reinterpret_cast(&vResulti)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreUNibble4 +( + XMUNIBBLE4* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Max = {15.0f,15.0f,15.0f,15.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,Max); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // No SSE operations will write to 16-bit values, so we have to extract them manually + USHORT x = static_cast(_mm_extract_epi16(vInt,0)); + USHORT y = static_cast(_mm_extract_epi16(vInt,2)); + USHORT z = static_cast(_mm_extract_epi16(vInt,4)); + USHORT w = static_cast(_mm_extract_epi16(vInt,6)); + pDestination->v = ((w & 0xF) << 12) | + ((z & 0xF) << 8) | + ((y & 0xF) << 4) | + ((x & 0xF)); +#else + XMVECTOR N; + static CONST XMVECTORF32 Max = {15.0f,15.0f,15.0f,15.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max.v); + N = XMVectorRound(N); + + pDestination->v = (((USHORT)N.vector4_f32[3] & 0xF) << 12) | + (((USHORT)N.vector4_f32[2] & 0xF) << 8) | + (((USHORT)N.vector4_f32[1] & 0xF) << 4) | + (((USHORT)N.vector4_f32[0] & 0xF)); +#endif !_XM_SSE_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreU555( + XMU555* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Max = {31.0f, 31.0f, 31.0f, 1.0f}; + // Bounds check + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + vResult = _mm_min_ps(vResult,Max); + // Convert to int with rounding + __m128i vInt = _mm_cvtps_epi32(vResult); + // No SSE operations will write to 16-bit values, so we have to extract them manually + USHORT x = static_cast(_mm_extract_epi16(vInt,0)); + USHORT y = static_cast(_mm_extract_epi16(vInt,2)); + USHORT z = static_cast(_mm_extract_epi16(vInt,4)); + USHORT w = static_cast(_mm_extract_epi16(vInt,6)); + pDestination->v = ((w) ? 0x8000 : 0) | + ((z & 0x1F) << 10) | + ((y & 0x1F) << 5) | + ((x & 0x1F)); +#else + XMVECTOR N; + static CONST XMVECTORF32 Max = {31.0f, 31.0f, 31.0f, 1.0f}; + + XMASSERT(pDestination); + + N = XMVectorClamp(V, XMVectorZero(), Max.v); + N = XMVectorRound(N); + + pDestination->v = ((N.vector4_f32[3] > 0.f) ? 0x8000 : 0) | + (((USHORT)N.vector4_f32[2] & 0x1F) << 10) | + (((USHORT)N.vector4_f32[1] & 0x1F) << 5) | + (((USHORT)N.vector4_f32[0] & 0x1F)); +#endif !_XM_SSE_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreColor +( + XMCOLOR* pDestination, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + static CONST XMVECTORF32 Scale = {255.0f, 255.0f, 255.0f, 255.0f}; + + XMASSERT(pDestination); + + N = XMVectorSaturate(V); + N = XMVectorMultiply(N, Scale.v); + N = XMVectorRound(N); + + pDestination->c = ((UINT)N.vector4_f32[3] << 24) | + ((UINT)N.vector4_f32[0] << 16) | + ((UINT)N.vector4_f32[1] << 8) | + ((UINT)N.vector4_f32[2]); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + static CONST XMVECTORF32 Scale = {255.0f,255.0f,255.0f,255.0f}; + // Set <0 to 0 + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + // Set>1 to 1 + vResult = _mm_min_ps(vResult,g_XMOne); + // Convert to 0-255 + vResult = _mm_mul_ps(vResult,Scale); + // Shuffle RGBA to ARGB + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,0,1,2)); + // Convert to int + __m128i vInt = _mm_cvtps_epi32(vResult); + // Mash to shorts + vInt = _mm_packs_epi32(vInt,vInt); + // Mash to bytes + vInt = _mm_packus_epi16(vInt,vInt); + // Store the color + _mm_store_ss(reinterpret_cast(&pDestination->c),reinterpret_cast<__m128 *>(&vInt)[0]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat3x3 +( + XMFLOAT3X3* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) || defined(_XM_SSE_INTRINSICS_) + + XMStoreFloat3x3NC(pDestination, M); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat3x3NC +( + XMFLOAT3X3* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + + pDestination->m[0][0] = M.r[0].vector4_f32[0]; + pDestination->m[0][1] = M.r[0].vector4_f32[1]; + pDestination->m[0][2] = M.r[0].vector4_f32[2]; + + pDestination->m[1][0] = M.r[1].vector4_f32[0]; + pDestination->m[1][1] = M.r[1].vector4_f32[1]; + pDestination->m[1][2] = M.r[1].vector4_f32[2]; + + pDestination->m[2][0] = M.r[2].vector4_f32[0]; + pDestination->m[2][1] = M.r[2].vector4_f32[1]; + pDestination->m[2][2] = M.r[2].vector4_f32[2]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMVECTOR vTemp1 = M.r[0]; + XMVECTOR vTemp2 = M.r[1]; + XMVECTOR vTemp3 = M.r[2]; + XMVECTOR vWork = _mm_shuffle_ps(vTemp1,vTemp2,_MM_SHUFFLE(0,0,2,2)); + vTemp1 = _mm_shuffle_ps(vTemp1,vWork,_MM_SHUFFLE(2,0,1,0)); + _mm_storeu_ps(&pDestination->m[0][0],vTemp1); + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp3,_MM_SHUFFLE(1,0,2,1)); + _mm_storeu_ps(&pDestination->m[1][1],vTemp2); + vTemp3 = _mm_shuffle_ps(vTemp3,vTemp3,_MM_SHUFFLE(2,2,2,2)); + _mm_store_ss(&pDestination->m[2][2],vTemp3); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4x3 +( + XMFLOAT4X3* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) || defined(_XM_SSE_INTRINSICS_) + + XMStoreFloat4x3NC(pDestination, M); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4x3A +( + XMFLOAT4X3A* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination->m[0][0] = M.r[0].vector4_f32[0]; + pDestination->m[0][1] = M.r[0].vector4_f32[1]; + pDestination->m[0][2] = M.r[0].vector4_f32[2]; + + pDestination->m[1][0] = M.r[1].vector4_f32[0]; + pDestination->m[1][1] = M.r[1].vector4_f32[1]; + pDestination->m[1][2] = M.r[1].vector4_f32[2]; + + pDestination->m[2][0] = M.r[2].vector4_f32[0]; + pDestination->m[2][1] = M.r[2].vector4_f32[1]; + pDestination->m[2][2] = M.r[2].vector4_f32[2]; + + pDestination->m[3][0] = M.r[3].vector4_f32[0]; + pDestination->m[3][1] = M.r[3].vector4_f32[1]; + pDestination->m[3][2] = M.r[3].vector4_f32[2]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + // x1,y1,z1,w1 + XMVECTOR vTemp1 = M.r[0]; + // x2,y2,z2,w2 + XMVECTOR vTemp2 = M.r[1]; + // x3,y3,z3,w3 + XMVECTOR vTemp3 = M.r[2]; + // x4,y4,z4,w4 + XMVECTOR vTemp4 = M.r[3]; + // z1,z1,x2,y2 + XMVECTOR vTemp = _mm_shuffle_ps(vTemp1,vTemp2,_MM_SHUFFLE(1,0,2,2)); + // y2,z2,x3,y3 (Final) + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp3,_MM_SHUFFLE(1,0,2,1)); + // x1,y1,z1,x2 (Final) + vTemp1 = _mm_shuffle_ps(vTemp1,vTemp,_MM_SHUFFLE(2,0,1,0)); + // z3,z3,x4,x4 + vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(0,0,2,2)); + // z3,x4,y4,z4 (Final) + vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(2,1,2,0)); + // Store in 3 operations + _mm_store_ps(&pDestination->m[0][0],vTemp1); + _mm_store_ps(&pDestination->m[1][1],vTemp2); + _mm_store_ps(&pDestination->m[2][2],vTemp3); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4x3NC +( + XMFLOAT4X3* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + + pDestination->m[0][0] = M.r[0].vector4_f32[0]; + pDestination->m[0][1] = M.r[0].vector4_f32[1]; + pDestination->m[0][2] = M.r[0].vector4_f32[2]; + + pDestination->m[1][0] = M.r[1].vector4_f32[0]; + pDestination->m[1][1] = M.r[1].vector4_f32[1]; + pDestination->m[1][2] = M.r[1].vector4_f32[2]; + + pDestination->m[2][0] = M.r[2].vector4_f32[0]; + pDestination->m[2][1] = M.r[2].vector4_f32[1]; + pDestination->m[2][2] = M.r[2].vector4_f32[2]; + + pDestination->m[3][0] = M.r[3].vector4_f32[0]; + pDestination->m[3][1] = M.r[3].vector4_f32[1]; + pDestination->m[3][2] = M.r[3].vector4_f32[2]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + XMVECTOR vTemp1 = M.r[0]; + XMVECTOR vTemp2 = M.r[1]; + XMVECTOR vTemp3 = M.r[2]; + XMVECTOR vTemp4 = M.r[3]; + XMVECTOR vTemp2x = _mm_shuffle_ps(vTemp2,vTemp3,_MM_SHUFFLE(1,0,2,1)); + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp1,_MM_SHUFFLE(2,2,0,0)); + vTemp1 = _mm_shuffle_ps(vTemp1,vTemp2,_MM_SHUFFLE(0,2,1,0)); + vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(0,0,2,2)); + vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(2,1,2,0)); + _mm_storeu_ps(&pDestination->m[0][0],vTemp1); + _mm_storeu_ps(&pDestination->m[1][1],vTemp2x); + _mm_storeu_ps(&pDestination->m[2][2],vTemp3); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4x4 +( + XMFLOAT4X4* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) + + XMStoreFloat4x4NC(pDestination, M); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + + _mm_storeu_ps( &pDestination->_11, M.r[0] ); + _mm_storeu_ps( &pDestination->_21, M.r[1] ); + _mm_storeu_ps( &pDestination->_31, M.r[2] ); + _mm_storeu_ps( &pDestination->_41, M.r[3] ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4x4A +( + XMFLOAT4X4A* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + XMASSERT(((UINT_PTR)pDestination & 0xF) == 0); + + pDestination->m[0][0] = M.r[0].vector4_f32[0]; + pDestination->m[0][1] = M.r[0].vector4_f32[1]; + pDestination->m[0][2] = M.r[0].vector4_f32[2]; + pDestination->m[0][3] = M.r[0].vector4_f32[3]; + + pDestination->m[1][0] = M.r[1].vector4_f32[0]; + pDestination->m[1][1] = M.r[1].vector4_f32[1]; + pDestination->m[1][2] = M.r[1].vector4_f32[2]; + pDestination->m[1][3] = M.r[1].vector4_f32[3]; + + pDestination->m[2][0] = M.r[2].vector4_f32[0]; + pDestination->m[2][1] = M.r[2].vector4_f32[1]; + pDestination->m[2][2] = M.r[2].vector4_f32[2]; + pDestination->m[2][3] = M.r[2].vector4_f32[3]; + + pDestination->m[3][0] = M.r[3].vector4_f32[0]; + pDestination->m[3][1] = M.r[3].vector4_f32[1]; + pDestination->m[3][2] = M.r[3].vector4_f32[2]; + pDestination->m[3][3] = M.r[3].vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + + _mm_store_ps( &pDestination->_11, M.r[0] ); + _mm_store_ps( &pDestination->_21, M.r[1] ); + _mm_store_ps( &pDestination->_31, M.r[2] ); + _mm_store_ps( &pDestination->_41, M.r[3] ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMStoreFloat4x4NC +( + XMFLOAT4X4* pDestination, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMASSERT(pDestination); + + pDestination->m[0][0] = M.r[0].vector4_f32[0]; + pDestination->m[0][1] = M.r[0].vector4_f32[1]; + pDestination->m[0][2] = M.r[0].vector4_f32[2]; + pDestination->m[0][3] = M.r[0].vector4_f32[3]; + + pDestination->m[1][0] = M.r[1].vector4_f32[0]; + pDestination->m[1][1] = M.r[1].vector4_f32[1]; + pDestination->m[1][2] = M.r[1].vector4_f32[2]; + pDestination->m[1][3] = M.r[1].vector4_f32[3]; + + pDestination->m[2][0] = M.r[2].vector4_f32[0]; + pDestination->m[2][1] = M.r[2].vector4_f32[1]; + pDestination->m[2][2] = M.r[2].vector4_f32[2]; + pDestination->m[2][3] = M.r[2].vector4_f32[3]; + + pDestination->m[3][0] = M.r[3].vector4_f32[0]; + pDestination->m[3][1] = M.r[3].vector4_f32[1]; + pDestination->m[3][2] = M.r[3].vector4_f32[2]; + pDestination->m[3][3] = M.r[3].vector4_f32[3]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDestination); + _mm_storeu_ps(&pDestination->m[0][0],M.r[0]); + _mm_storeu_ps(&pDestination->m[1][0],M.r[1]); + _mm_storeu_ps(&pDestination->m[2][0],M.r[2]); + _mm_storeu_ps(&pDestination->m[3][0],M.r[3]); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +#endif // __XNAMATHCONVERT_INL__ + diff --git a/dxsdk/Include/xnamathmatrix.inl b/dxsdk/Include/xnamathmatrix.inl new file mode 100644 index 0000000..7ce4c1f --- /dev/null +++ b/dxsdk/Include/xnamathmatrix.inl @@ -0,0 +1,3254 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + xnamathmatrix.inl + +Abstract: + + XNA math library for Windows and Xbox 360: Matrix functions +--*/ + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __XNAMATHMATRIX_INL__ +#define __XNAMATHMATRIX_INL__ + +/**************************************************************************** + * + * Matrix + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +// Return TRUE if any entry in the matrix is NaN +XMFINLINE BOOL XMMatrixIsNaN +( + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT i, uTest; + const UINT *pWork; + + i = 16; + pWork = (const UINT *)(&M.m[0][0]); + do { + // Fetch value into integer unit + uTest = pWork[0]; + // Remove sign + uTest &= 0x7FFFFFFFU; + // NaN is 0x7F800001 through 0x7FFFFFFF inclusive + uTest -= 0x7F800001U; + if (uTest<0x007FFFFFU) { + break; // NaN found + } + ++pWork; // Next entry + } while (--i); + return (i!=0); // i == 0 if nothing matched +#elif defined(_XM_SSE_INTRINSICS_) + // Load in registers + XMVECTOR vX = M.r[0]; + XMVECTOR vY = M.r[1]; + XMVECTOR vZ = M.r[2]; + XMVECTOR vW = M.r[3]; + // Test themselves to check for NaN + vX = _mm_cmpneq_ps(vX,vX); + vY = _mm_cmpneq_ps(vY,vY); + vZ = _mm_cmpneq_ps(vZ,vZ); + vW = _mm_cmpneq_ps(vW,vW); + // Or all the results + vX = _mm_or_ps(vX,vZ); + vY = _mm_or_ps(vY,vW); + vX = _mm_or_ps(vX,vY); + // If any tested true, return true + return (_mm_movemask_ps(vX)!=0); +#else +#endif +} + +//------------------------------------------------------------------------------ + +// Return TRUE if any entry in the matrix is +/-INF +XMFINLINE BOOL XMMatrixIsInfinite +( + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT i, uTest; + const UINT *pWork; + + i = 16; + pWork = (const UINT *)(&M.m[0][0]); + do { + // Fetch value into integer unit + uTest = pWork[0]; + // Remove sign + uTest &= 0x7FFFFFFFU; + // INF is 0x7F800000 + if (uTest==0x7F800000U) { + break; // INF found + } + ++pWork; // Next entry + } while (--i); + return (i!=0); // i == 0 if nothing matched +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the sign bits + XMVECTOR vTemp1 = _mm_and_ps(M.r[0],g_XMAbsMask); + XMVECTOR vTemp2 = _mm_and_ps(M.r[1],g_XMAbsMask); + XMVECTOR vTemp3 = _mm_and_ps(M.r[2],g_XMAbsMask); + XMVECTOR vTemp4 = _mm_and_ps(M.r[3],g_XMAbsMask); + // Compare to infinity + vTemp1 = _mm_cmpeq_ps(vTemp1,g_XMInfinity); + vTemp2 = _mm_cmpeq_ps(vTemp2,g_XMInfinity); + vTemp3 = _mm_cmpeq_ps(vTemp3,g_XMInfinity); + vTemp4 = _mm_cmpeq_ps(vTemp4,g_XMInfinity); + // Or the answers together + vTemp1 = _mm_or_ps(vTemp1,vTemp2); + vTemp3 = _mm_or_ps(vTemp3,vTemp4); + vTemp1 = _mm_or_ps(vTemp1,vTemp3); + // If any are infinity, the signs are true. + return (_mm_movemask_ps(vTemp1)!=0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Return TRUE if the XMMatrix is equal to identity +XMFINLINE BOOL XMMatrixIsIdentity +( + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + unsigned int uOne, uZero; + const unsigned int *pWork; + + // Use the integer pipeline to reduce branching to a minimum + pWork = (const unsigned int*)(&M.m[0][0]); + // Convert 1.0f to zero and or them together + uOne = pWork[0]^0x3F800000U; + // Or all the 0.0f entries together + uZero = pWork[1]; + uZero |= pWork[2]; + uZero |= pWork[3]; + // 2nd row + uZero |= pWork[4]; + uOne |= pWork[5]^0x3F800000U; + uZero |= pWork[6]; + uZero |= pWork[7]; + // 3rd row + uZero |= pWork[8]; + uZero |= pWork[9]; + uOne |= pWork[10]^0x3F800000U; + uZero |= pWork[11]; + // 4th row + uZero |= pWork[12]; + uZero |= pWork[13]; + uZero |= pWork[14]; + uOne |= pWork[15]^0x3F800000U; + // If all zero entries are zero, the uZero==0 + uZero &= 0x7FFFFFFF; // Allow -0.0f + // If all 1.0f entries are 1.0f, then uOne==0 + uOne |= uZero; + return (uOne==0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp1 = _mm_cmpeq_ps(M.r[0],g_XMIdentityR0); + XMVECTOR vTemp2 = _mm_cmpeq_ps(M.r[1],g_XMIdentityR1); + XMVECTOR vTemp3 = _mm_cmpeq_ps(M.r[2],g_XMIdentityR2); + XMVECTOR vTemp4 = _mm_cmpeq_ps(M.r[3],g_XMIdentityR3); + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + vTemp3 = _mm_and_ps(vTemp3,vTemp4); + vTemp1 = _mm_and_ps(vTemp1,vTemp3); + return (_mm_movemask_ps(vTemp1)==0x0f); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Perform a 4x4 matrix multiply by a 4x4 matrix +XMFINLINE XMMATRIX XMMatrixMultiply +( + CXMMATRIX M1, + CXMMATRIX M2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX mResult; + // Cache the invariants in registers + float x = M1.m[0][0]; + float y = M1.m[0][1]; + float z = M1.m[0][2]; + float w = M1.m[0][3]; + // Perform the operation on the first row + mResult.m[0][0] = (M2.m[0][0]*x)+(M2.m[1][0]*y)+(M2.m[2][0]*z)+(M2.m[3][0]*w); + mResult.m[0][1] = (M2.m[0][1]*x)+(M2.m[1][1]*y)+(M2.m[2][1]*z)+(M2.m[3][1]*w); + mResult.m[0][2] = (M2.m[0][2]*x)+(M2.m[1][2]*y)+(M2.m[2][2]*z)+(M2.m[3][2]*w); + mResult.m[0][3] = (M2.m[0][3]*x)+(M2.m[1][3]*y)+(M2.m[2][3]*z)+(M2.m[3][3]*w); + // Repeat for all the other rows + x = M1.m[1][0]; + y = M1.m[1][1]; + z = M1.m[1][2]; + w = M1.m[1][3]; + mResult.m[1][0] = (M2.m[0][0]*x)+(M2.m[1][0]*y)+(M2.m[2][0]*z)+(M2.m[3][0]*w); + mResult.m[1][1] = (M2.m[0][1]*x)+(M2.m[1][1]*y)+(M2.m[2][1]*z)+(M2.m[3][1]*w); + mResult.m[1][2] = (M2.m[0][2]*x)+(M2.m[1][2]*y)+(M2.m[2][2]*z)+(M2.m[3][2]*w); + mResult.m[1][3] = (M2.m[0][3]*x)+(M2.m[1][3]*y)+(M2.m[2][3]*z)+(M2.m[3][3]*w); + x = M1.m[2][0]; + y = M1.m[2][1]; + z = M1.m[2][2]; + w = M1.m[2][3]; + mResult.m[2][0] = (M2.m[0][0]*x)+(M2.m[1][0]*y)+(M2.m[2][0]*z)+(M2.m[3][0]*w); + mResult.m[2][1] = (M2.m[0][1]*x)+(M2.m[1][1]*y)+(M2.m[2][1]*z)+(M2.m[3][1]*w); + mResult.m[2][2] = (M2.m[0][2]*x)+(M2.m[1][2]*y)+(M2.m[2][2]*z)+(M2.m[3][2]*w); + mResult.m[2][3] = (M2.m[0][3]*x)+(M2.m[1][3]*y)+(M2.m[2][3]*z)+(M2.m[3][3]*w); + x = M1.m[3][0]; + y = M1.m[3][1]; + z = M1.m[3][2]; + w = M1.m[3][3]; + mResult.m[3][0] = (M2.m[0][0]*x)+(M2.m[1][0]*y)+(M2.m[2][0]*z)+(M2.m[3][0]*w); + mResult.m[3][1] = (M2.m[0][1]*x)+(M2.m[1][1]*y)+(M2.m[2][1]*z)+(M2.m[3][1]*w); + mResult.m[3][2] = (M2.m[0][2]*x)+(M2.m[1][2]*y)+(M2.m[2][2]*z)+(M2.m[3][2]*w); + mResult.m[3][3] = (M2.m[0][3]*x)+(M2.m[1][3]*y)+(M2.m[2][3]*z)+(M2.m[3][3]*w); + return mResult; +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX mResult; + // Use vW to hold the original row + XMVECTOR vW = M1.r[0]; + // Splat the component X,Y,Z then W + XMVECTOR vX = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(0,0,0,0)); + XMVECTOR vY = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR vZ = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(2,2,2,2)); + vW = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(3,3,3,3)); + // Perform the opertion on the first row + vX = _mm_mul_ps(vX,M2.r[0]); + vY = _mm_mul_ps(vY,M2.r[1]); + vZ = _mm_mul_ps(vZ,M2.r[2]); + vW = _mm_mul_ps(vW,M2.r[3]); + // Perform a binary add to reduce cumulative errors + vX = _mm_add_ps(vX,vZ); + vY = _mm_add_ps(vY,vW); + vX = _mm_add_ps(vX,vY); + mResult.r[0] = vX; + // Repeat for the other 3 rows + vW = M1.r[1]; + vX = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(0,0,0,0)); + vY = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(1,1,1,1)); + vZ = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(2,2,2,2)); + vW = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(3,3,3,3)); + vX = _mm_mul_ps(vX,M2.r[0]); + vY = _mm_mul_ps(vY,M2.r[1]); + vZ = _mm_mul_ps(vZ,M2.r[2]); + vW = _mm_mul_ps(vW,M2.r[3]); + vX = _mm_add_ps(vX,vZ); + vY = _mm_add_ps(vY,vW); + vX = _mm_add_ps(vX,vY); + mResult.r[1] = vX; + vW = M1.r[2]; + vX = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(0,0,0,0)); + vY = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(1,1,1,1)); + vZ = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(2,2,2,2)); + vW = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(3,3,3,3)); + vX = _mm_mul_ps(vX,M2.r[0]); + vY = _mm_mul_ps(vY,M2.r[1]); + vZ = _mm_mul_ps(vZ,M2.r[2]); + vW = _mm_mul_ps(vW,M2.r[3]); + vX = _mm_add_ps(vX,vZ); + vY = _mm_add_ps(vY,vW); + vX = _mm_add_ps(vX,vY); + mResult.r[2] = vX; + vW = M1.r[3]; + vX = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(0,0,0,0)); + vY = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(1,1,1,1)); + vZ = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(2,2,2,2)); + vW = _mm_shuffle_ps(vW,vW,_MM_SHUFFLE(3,3,3,3)); + vX = _mm_mul_ps(vX,M2.r[0]); + vY = _mm_mul_ps(vY,M2.r[1]); + vZ = _mm_mul_ps(vZ,M2.r[2]); + vW = _mm_mul_ps(vW,M2.r[3]); + vX = _mm_add_ps(vX,vZ); + vY = _mm_add_ps(vY,vW); + vX = _mm_add_ps(vX,vY); + mResult.r[3] = vX; + return mResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixMultiplyTranspose +( + CXMMATRIX M1, + CXMMATRIX M2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX mResult; + // Cache the invariants in registers + float x = M2.m[0][0]; + float y = M2.m[1][0]; + float z = M2.m[2][0]; + float w = M2.m[3][0]; + // Perform the operation on the first row + mResult.m[0][0] = (M1.m[0][0]*x)+(M1.m[0][1]*y)+(M1.m[0][2]*z)+(M1.m[0][3]*w); + mResult.m[0][1] = (M1.m[1][0]*x)+(M1.m[1][1]*y)+(M1.m[1][2]*z)+(M1.m[1][3]*w); + mResult.m[0][2] = (M1.m[2][0]*x)+(M1.m[2][1]*y)+(M1.m[2][2]*z)+(M1.m[2][3]*w); + mResult.m[0][3] = (M1.m[3][0]*x)+(M1.m[3][1]*y)+(M1.m[3][2]*z)+(M1.m[3][3]*w); + // Repeat for all the other rows + x = M2.m[0][1]; + y = M2.m[1][1]; + z = M2.m[2][1]; + w = M2.m[3][1]; + mResult.m[1][0] = (M1.m[0][0]*x)+(M1.m[0][1]*y)+(M1.m[0][2]*z)+(M1.m[0][3]*w); + mResult.m[1][1] = (M1.m[1][0]*x)+(M1.m[1][1]*y)+(M1.m[1][2]*z)+(M1.m[1][3]*w); + mResult.m[1][2] = (M1.m[2][0]*x)+(M1.m[2][1]*y)+(M1.m[2][2]*z)+(M1.m[2][3]*w); + mResult.m[1][3] = (M1.m[3][0]*x)+(M1.m[3][1]*y)+(M1.m[3][2]*z)+(M1.m[3][3]*w); + x = M2.m[0][2]; + y = M2.m[1][2]; + z = M2.m[2][2]; + w = M2.m[3][2]; + mResult.m[2][0] = (M1.m[0][0]*x)+(M1.m[0][1]*y)+(M1.m[0][2]*z)+(M1.m[0][3]*w); + mResult.m[2][1] = (M1.m[1][0]*x)+(M1.m[1][1]*y)+(M1.m[1][2]*z)+(M1.m[1][3]*w); + mResult.m[2][2] = (M1.m[2][0]*x)+(M1.m[2][1]*y)+(M1.m[2][2]*z)+(M1.m[2][3]*w); + mResult.m[2][3] = (M1.m[3][0]*x)+(M1.m[3][1]*y)+(M1.m[3][2]*z)+(M1.m[3][3]*w); + x = M2.m[0][3]; + y = M2.m[1][3]; + z = M2.m[2][3]; + w = M2.m[3][3]; + mResult.m[3][0] = (M1.m[0][0]*x)+(M1.m[0][1]*y)+(M1.m[0][2]*z)+(M1.m[0][3]*w); + mResult.m[3][1] = (M1.m[1][0]*x)+(M1.m[1][1]*y)+(M1.m[1][2]*z)+(M1.m[1][3]*w); + mResult.m[3][2] = (M1.m[2][0]*x)+(M1.m[2][1]*y)+(M1.m[2][2]*z)+(M1.m[2][3]*w); + mResult.m[3][3] = (M1.m[3][0]*x)+(M1.m[3][1]*y)+(M1.m[3][2]*z)+(M1.m[3][3]*w); + return mResult; +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX Product; + XMMATRIX Result; + Product = XMMatrixMultiply(M1, M2); + Result = XMMatrixTranspose(Product); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixTranspose +( + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX P; + XMMATRIX MT; + + // Original matrix: + // + // m00m01m02m03 + // m10m11m12m13 + // m20m21m22m23 + // m30m31m32m33 + + P.r[0] = XMVectorMergeXY(M.r[0], M.r[2]); // m00m20m01m21 + P.r[1] = XMVectorMergeXY(M.r[1], M.r[3]); // m10m30m11m31 + P.r[2] = XMVectorMergeZW(M.r[0], M.r[2]); // m02m22m03m23 + P.r[3] = XMVectorMergeZW(M.r[1], M.r[3]); // m12m32m13m33 + + MT.r[0] = XMVectorMergeXY(P.r[0], P.r[1]); // m00m10m20m30 + MT.r[1] = XMVectorMergeZW(P.r[0], P.r[1]); // m01m11m21m31 + MT.r[2] = XMVectorMergeXY(P.r[2], P.r[3]); // m02m12m22m32 + MT.r[3] = XMVectorMergeZW(P.r[2], P.r[3]); // m03m13m23m33 + + return MT; + +#elif defined(_XM_SSE_INTRINSICS_) + // x.x,x.y,y.x,y.y + XMVECTOR vTemp1 = _mm_shuffle_ps(M.r[0],M.r[1],_MM_SHUFFLE(1,0,1,0)); + // x.z,x.w,y.z,y.w + XMVECTOR vTemp3 = _mm_shuffle_ps(M.r[0],M.r[1],_MM_SHUFFLE(3,2,3,2)); + // z.x,z.y,w.x,w.y + XMVECTOR vTemp2 = _mm_shuffle_ps(M.r[2],M.r[3],_MM_SHUFFLE(1,0,1,0)); + // z.z,z.w,w.z,w.w + XMVECTOR vTemp4 = _mm_shuffle_ps(M.r[2],M.r[3],_MM_SHUFFLE(3,2,3,2)); + XMMATRIX mResult; + + // x.x,y.x,z.x,w.x + mResult.r[0] = _mm_shuffle_ps(vTemp1, vTemp2,_MM_SHUFFLE(2,0,2,0)); + // x.y,y.y,z.y,w.y + mResult.r[1] = _mm_shuffle_ps(vTemp1, vTemp2,_MM_SHUFFLE(3,1,3,1)); + // x.z,y.z,z.z,w.z + mResult.r[2] = _mm_shuffle_ps(vTemp3, vTemp4,_MM_SHUFFLE(2,0,2,0)); + // x.w,y.w,z.w,w.w + mResult.r[3] = _mm_shuffle_ps(vTemp3, vTemp4,_MM_SHUFFLE(3,1,3,1)); + return mResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return the inverse and the determinant of a 4x4 matrix +XMINLINE XMMATRIX XMMatrixInverse +( + XMVECTOR* pDeterminant, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX R; + XMMATRIX MT; + XMVECTOR D0, D1, D2; + XMVECTOR C0, C1, C2, C3, C4, C5, C6, C7; + XMVECTOR V0[4], V1[4]; + XMVECTOR Determinant; + XMVECTOR Reciprocal; + XMMATRIX Result; + static CONST XMVECTORU32 SwizzleXXYY = {XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0Y}; + static CONST XMVECTORU32 SwizzleZWZW = {XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_0Z, XM_PERMUTE_0W}; + static CONST XMVECTORU32 SwizzleYZXY = {XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0X, XM_PERMUTE_0Y}; + static CONST XMVECTORU32 SwizzleZWYZ = {XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_0Y, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 SwizzleWXWX = {XM_PERMUTE_0W, XM_PERMUTE_0X, XM_PERMUTE_0W, XM_PERMUTE_0X}; + static CONST XMVECTORU32 SwizzleZXYX = {XM_PERMUTE_0Z, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0X}; + static CONST XMVECTORU32 SwizzleYWXZ = {XM_PERMUTE_0Y, XM_PERMUTE_0W, XM_PERMUTE_0X, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 SwizzleWZWY = {XM_PERMUTE_0W, XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_0Y}; + static CONST XMVECTORU32 Permute0X0Z1X1Z = {XM_PERMUTE_0X, XM_PERMUTE_0Z, XM_PERMUTE_1X, XM_PERMUTE_1Z}; + static CONST XMVECTORU32 Permute0Y0W1Y1W = {XM_PERMUTE_0Y, XM_PERMUTE_0W, XM_PERMUTE_1Y, XM_PERMUTE_1W}; + static CONST XMVECTORU32 Permute1Y0Y0W0X = {XM_PERMUTE_1Y, XM_PERMUTE_0Y, XM_PERMUTE_0W, XM_PERMUTE_0X}; + static CONST XMVECTORU32 Permute0W0X0Y1X = {XM_PERMUTE_0W, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_1X}; + static CONST XMVECTORU32 Permute0Z1Y1X0Z = {XM_PERMUTE_0Z, XM_PERMUTE_1Y, XM_PERMUTE_1X, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 Permute0W1Y0Y0Z = {XM_PERMUTE_0W, XM_PERMUTE_1Y, XM_PERMUTE_0Y, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 Permute0Z0Y1X0X = {XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_1X, XM_PERMUTE_0X}; + static CONST XMVECTORU32 Permute1Y0X0W1X = {XM_PERMUTE_1Y, XM_PERMUTE_0X, XM_PERMUTE_0W, XM_PERMUTE_1X}; + static CONST XMVECTORU32 Permute1W0Y0W0X = {XM_PERMUTE_1W, XM_PERMUTE_0Y, XM_PERMUTE_0W, XM_PERMUTE_0X}; + static CONST XMVECTORU32 Permute0W0X0Y1Z = {XM_PERMUTE_0W, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_1Z}; + static CONST XMVECTORU32 Permute0Z1W1Z0Z = {XM_PERMUTE_0Z, XM_PERMUTE_1W, XM_PERMUTE_1Z, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 Permute0W1W0Y0Z = {XM_PERMUTE_0W, XM_PERMUTE_1W, XM_PERMUTE_0Y, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 Permute0Z0Y1Z0X = {XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_1Z, XM_PERMUTE_0X}; + static CONST XMVECTORU32 Permute1W0X0W1Z = {XM_PERMUTE_1W, XM_PERMUTE_0X, XM_PERMUTE_0W, XM_PERMUTE_1Z}; + + XMASSERT(pDeterminant); + + MT = XMMatrixTranspose(M); + + V0[0] = XMVectorPermute(MT.r[2], MT.r[2], SwizzleXXYY.v); + V1[0] = XMVectorPermute(MT.r[3], MT.r[3], SwizzleZWZW.v); + V0[1] = XMVectorPermute(MT.r[0], MT.r[0], SwizzleXXYY.v); + V1[1] = XMVectorPermute(MT.r[1], MT.r[1], SwizzleZWZW.v); + V0[2] = XMVectorPermute(MT.r[2], MT.r[0], Permute0X0Z1X1Z.v); + V1[2] = XMVectorPermute(MT.r[3], MT.r[1], Permute0Y0W1Y1W.v); + + D0 = XMVectorMultiply(V0[0], V1[0]); + D1 = XMVectorMultiply(V0[1], V1[1]); + D2 = XMVectorMultiply(V0[2], V1[2]); + + V0[0] = XMVectorPermute(MT.r[2], MT.r[2], SwizzleZWZW.v); + V1[0] = XMVectorPermute(MT.r[3], MT.r[3], SwizzleXXYY.v); + V0[1] = XMVectorPermute(MT.r[0], MT.r[0], SwizzleZWZW.v); + V1[1] = XMVectorPermute(MT.r[1], MT.r[1], SwizzleXXYY.v); + V0[2] = XMVectorPermute(MT.r[2], MT.r[0], Permute0Y0W1Y1W.v); + V1[2] = XMVectorPermute(MT.r[3], MT.r[1], Permute0X0Z1X1Z.v); + + D0 = XMVectorNegativeMultiplySubtract(V0[0], V1[0], D0); + D1 = XMVectorNegativeMultiplySubtract(V0[1], V1[1], D1); + D2 = XMVectorNegativeMultiplySubtract(V0[2], V1[2], D2); + + V0[0] = XMVectorPermute(MT.r[1], MT.r[1], SwizzleYZXY.v); + V1[0] = XMVectorPermute(D0, D2, Permute1Y0Y0W0X.v); + V0[1] = XMVectorPermute(MT.r[0], MT.r[0], SwizzleZXYX.v); + V1[1] = XMVectorPermute(D0, D2, Permute0W1Y0Y0Z.v); + V0[2] = XMVectorPermute(MT.r[3], MT.r[3], SwizzleYZXY.v); + V1[2] = XMVectorPermute(D1, D2, Permute1W0Y0W0X.v); + V0[3] = XMVectorPermute(MT.r[2], MT.r[2], SwizzleZXYX.v); + V1[3] = XMVectorPermute(D1, D2, Permute0W1W0Y0Z.v); + + C0 = XMVectorMultiply(V0[0], V1[0]); + C2 = XMVectorMultiply(V0[1], V1[1]); + C4 = XMVectorMultiply(V0[2], V1[2]); + C6 = XMVectorMultiply(V0[3], V1[3]); + + V0[0] = XMVectorPermute(MT.r[1], MT.r[1], SwizzleZWYZ.v); + V1[0] = XMVectorPermute(D0, D2, Permute0W0X0Y1X.v); + V0[1] = XMVectorPermute(MT.r[0], MT.r[0], SwizzleWZWY.v); + V1[1] = XMVectorPermute(D0, D2, Permute0Z0Y1X0X.v); + V0[2] = XMVectorPermute(MT.r[3], MT.r[3], SwizzleZWYZ.v); + V1[2] = XMVectorPermute(D1, D2, Permute0W0X0Y1Z.v); + V0[3] = XMVectorPermute(MT.r[2], MT.r[2], SwizzleWZWY.v); + V1[3] = XMVectorPermute(D1, D2, Permute0Z0Y1Z0X.v); + + C0 = XMVectorNegativeMultiplySubtract(V0[0], V1[0], C0); + C2 = XMVectorNegativeMultiplySubtract(V0[1], V1[1], C2); + C4 = XMVectorNegativeMultiplySubtract(V0[2], V1[2], C4); + C6 = XMVectorNegativeMultiplySubtract(V0[3], V1[3], C6); + + V0[0] = XMVectorPermute(MT.r[1], MT.r[1], SwizzleWXWX.v); + V1[0] = XMVectorPermute(D0, D2, Permute0Z1Y1X0Z.v); + V0[1] = XMVectorPermute(MT.r[0], MT.r[0], SwizzleYWXZ.v); + V1[1] = XMVectorPermute(D0, D2, Permute1Y0X0W1X.v); + V0[2] = XMVectorPermute(MT.r[3], MT.r[3], SwizzleWXWX.v); + V1[2] = XMVectorPermute(D1, D2, Permute0Z1W1Z0Z.v); + V0[3] = XMVectorPermute(MT.r[2], MT.r[2], SwizzleYWXZ.v); + V1[3] = XMVectorPermute(D1, D2, Permute1W0X0W1Z.v); + + C1 = XMVectorNegativeMultiplySubtract(V0[0], V1[0], C0); + C0 = XMVectorMultiplyAdd(V0[0], V1[0], C0); + C3 = XMVectorMultiplyAdd(V0[1], V1[1], C2); + C2 = XMVectorNegativeMultiplySubtract(V0[1], V1[1], C2); + C5 = XMVectorNegativeMultiplySubtract(V0[2], V1[2], C4); + C4 = XMVectorMultiplyAdd(V0[2], V1[2], C4); + C7 = XMVectorMultiplyAdd(V0[3], V1[3], C6); + C6 = XMVectorNegativeMultiplySubtract(V0[3], V1[3], C6); + + R.r[0] = XMVectorSelect(C0, C1, g_XMSelect0101.v); + R.r[1] = XMVectorSelect(C2, C3, g_XMSelect0101.v); + R.r[2] = XMVectorSelect(C4, C5, g_XMSelect0101.v); + R.r[3] = XMVectorSelect(C6, C7, g_XMSelect0101.v); + + Determinant = XMVector4Dot(R.r[0], MT.r[0]); + + *pDeterminant = Determinant; + + Reciprocal = XMVectorReciprocal(Determinant); + + Result.r[0] = XMVectorMultiply(R.r[0], Reciprocal); + Result.r[1] = XMVectorMultiply(R.r[1], Reciprocal); + Result.r[2] = XMVectorMultiply(R.r[2], Reciprocal); + Result.r[3] = XMVectorMultiply(R.r[3], Reciprocal); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pDeterminant); + XMMATRIX MT = XMMatrixTranspose(M); + XMVECTOR V00 = _mm_shuffle_ps(MT.r[2], MT.r[2],_MM_SHUFFLE(1,1,0,0)); + XMVECTOR V10 = _mm_shuffle_ps(MT.r[3], MT.r[3],_MM_SHUFFLE(3,2,3,2)); + XMVECTOR V01 = _mm_shuffle_ps(MT.r[0], MT.r[0],_MM_SHUFFLE(1,1,0,0)); + XMVECTOR V11 = _mm_shuffle_ps(MT.r[1], MT.r[1],_MM_SHUFFLE(3,2,3,2)); + XMVECTOR V02 = _mm_shuffle_ps(MT.r[2], MT.r[0],_MM_SHUFFLE(2,0,2,0)); + XMVECTOR V12 = _mm_shuffle_ps(MT.r[3], MT.r[1],_MM_SHUFFLE(3,1,3,1)); + + XMVECTOR D0 = _mm_mul_ps(V00,V10); + XMVECTOR D1 = _mm_mul_ps(V01,V11); + XMVECTOR D2 = _mm_mul_ps(V02,V12); + + V00 = _mm_shuffle_ps(MT.r[2],MT.r[2],_MM_SHUFFLE(3,2,3,2)); + V10 = _mm_shuffle_ps(MT.r[3],MT.r[3],_MM_SHUFFLE(1,1,0,0)); + V01 = _mm_shuffle_ps(MT.r[0],MT.r[0],_MM_SHUFFLE(3,2,3,2)); + V11 = _mm_shuffle_ps(MT.r[1],MT.r[1],_MM_SHUFFLE(1,1,0,0)); + V02 = _mm_shuffle_ps(MT.r[2],MT.r[0],_MM_SHUFFLE(3,1,3,1)); + V12 = _mm_shuffle_ps(MT.r[3],MT.r[1],_MM_SHUFFLE(2,0,2,0)); + + V00 = _mm_mul_ps(V00,V10); + V01 = _mm_mul_ps(V01,V11); + V02 = _mm_mul_ps(V02,V12); + D0 = _mm_sub_ps(D0,V00); + D1 = _mm_sub_ps(D1,V01); + D2 = _mm_sub_ps(D2,V02); + // V11 = D0Y,D0W,D2Y,D2Y + V11 = _mm_shuffle_ps(D0,D2,_MM_SHUFFLE(1,1,3,1)); + V00 = _mm_shuffle_ps(MT.r[1], MT.r[1],_MM_SHUFFLE(1,0,2,1)); + V10 = _mm_shuffle_ps(V11,D0,_MM_SHUFFLE(0,3,0,2)); + V01 = _mm_shuffle_ps(MT.r[0], MT.r[0],_MM_SHUFFLE(0,1,0,2)); + V11 = _mm_shuffle_ps(V11,D0,_MM_SHUFFLE(2,1,2,1)); + // V13 = D1Y,D1W,D2W,D2W + XMVECTOR V13 = _mm_shuffle_ps(D1,D2,_MM_SHUFFLE(3,3,3,1)); + V02 = _mm_shuffle_ps(MT.r[3], MT.r[3],_MM_SHUFFLE(1,0,2,1)); + V12 = _mm_shuffle_ps(V13,D1,_MM_SHUFFLE(0,3,0,2)); + XMVECTOR V03 = _mm_shuffle_ps(MT.r[2], MT.r[2],_MM_SHUFFLE(0,1,0,2)); + V13 = _mm_shuffle_ps(V13,D1,_MM_SHUFFLE(2,1,2,1)); + + XMVECTOR C0 = _mm_mul_ps(V00,V10); + XMVECTOR C2 = _mm_mul_ps(V01,V11); + XMVECTOR C4 = _mm_mul_ps(V02,V12); + XMVECTOR C6 = _mm_mul_ps(V03,V13); + + // V11 = D0X,D0Y,D2X,D2X + V11 = _mm_shuffle_ps(D0,D2,_MM_SHUFFLE(0,0,1,0)); + V00 = _mm_shuffle_ps(MT.r[1], MT.r[1],_MM_SHUFFLE(2,1,3,2)); + V10 = _mm_shuffle_ps(D0,V11,_MM_SHUFFLE(2,1,0,3)); + V01 = _mm_shuffle_ps(MT.r[0], MT.r[0],_MM_SHUFFLE(1,3,2,3)); + V11 = _mm_shuffle_ps(D0,V11,_MM_SHUFFLE(0,2,1,2)); + // V13 = D1X,D1Y,D2Z,D2Z + V13 = _mm_shuffle_ps(D1,D2,_MM_SHUFFLE(2,2,1,0)); + V02 = _mm_shuffle_ps(MT.r[3], MT.r[3],_MM_SHUFFLE(2,1,3,2)); + V12 = _mm_shuffle_ps(D1,V13,_MM_SHUFFLE(2,1,0,3)); + V03 = _mm_shuffle_ps(MT.r[2], MT.r[2],_MM_SHUFFLE(1,3,2,3)); + V13 = _mm_shuffle_ps(D1,V13,_MM_SHUFFLE(0,2,1,2)); + + V00 = _mm_mul_ps(V00,V10); + V01 = _mm_mul_ps(V01,V11); + V02 = _mm_mul_ps(V02,V12); + V03 = _mm_mul_ps(V03,V13); + C0 = _mm_sub_ps(C0,V00); + C2 = _mm_sub_ps(C2,V01); + C4 = _mm_sub_ps(C4,V02); + C6 = _mm_sub_ps(C6,V03); + + V00 = _mm_shuffle_ps(MT.r[1],MT.r[1],_MM_SHUFFLE(0,3,0,3)); + // V10 = D0Z,D0Z,D2X,D2Y + V10 = _mm_shuffle_ps(D0,D2,_MM_SHUFFLE(1,0,2,2)); + V10 = _mm_shuffle_ps(V10,V10,_MM_SHUFFLE(0,2,3,0)); + V01 = _mm_shuffle_ps(MT.r[0],MT.r[0],_MM_SHUFFLE(2,0,3,1)); + // V11 = D0X,D0W,D2X,D2Y + V11 = _mm_shuffle_ps(D0,D2,_MM_SHUFFLE(1,0,3,0)); + V11 = _mm_shuffle_ps(V11,V11,_MM_SHUFFLE(2,1,0,3)); + V02 = _mm_shuffle_ps(MT.r[3],MT.r[3],_MM_SHUFFLE(0,3,0,3)); + // V12 = D1Z,D1Z,D2Z,D2W + V12 = _mm_shuffle_ps(D1,D2,_MM_SHUFFLE(3,2,2,2)); + V12 = _mm_shuffle_ps(V12,V12,_MM_SHUFFLE(0,2,3,0)); + V03 = _mm_shuffle_ps(MT.r[2],MT.r[2],_MM_SHUFFLE(2,0,3,1)); + // V13 = D1X,D1W,D2Z,D2W + V13 = _mm_shuffle_ps(D1,D2,_MM_SHUFFLE(3,2,3,0)); + V13 = _mm_shuffle_ps(V13,V13,_MM_SHUFFLE(2,1,0,3)); + + V00 = _mm_mul_ps(V00,V10); + V01 = _mm_mul_ps(V01,V11); + V02 = _mm_mul_ps(V02,V12); + V03 = _mm_mul_ps(V03,V13); + XMVECTOR C1 = _mm_sub_ps(C0,V00); + C0 = _mm_add_ps(C0,V00); + XMVECTOR C3 = _mm_add_ps(C2,V01); + C2 = _mm_sub_ps(C2,V01); + XMVECTOR C5 = _mm_sub_ps(C4,V02); + C4 = _mm_add_ps(C4,V02); + XMVECTOR C7 = _mm_add_ps(C6,V03); + C6 = _mm_sub_ps(C6,V03); + + C0 = _mm_shuffle_ps(C0,C1,_MM_SHUFFLE(3,1,2,0)); + C2 = _mm_shuffle_ps(C2,C3,_MM_SHUFFLE(3,1,2,0)); + C4 = _mm_shuffle_ps(C4,C5,_MM_SHUFFLE(3,1,2,0)); + C6 = _mm_shuffle_ps(C6,C7,_MM_SHUFFLE(3,1,2,0)); + C0 = _mm_shuffle_ps(C0,C0,_MM_SHUFFLE(3,1,2,0)); + C2 = _mm_shuffle_ps(C2,C2,_MM_SHUFFLE(3,1,2,0)); + C4 = _mm_shuffle_ps(C4,C4,_MM_SHUFFLE(3,1,2,0)); + C6 = _mm_shuffle_ps(C6,C6,_MM_SHUFFLE(3,1,2,0)); + // Get the determinate + XMVECTOR vTemp = XMVector4Dot(C0,MT.r[0]); + *pDeterminant = vTemp; + vTemp = _mm_div_ps(g_XMOne,vTemp); + XMMATRIX mResult; + mResult.r[0] = _mm_mul_ps(C0,vTemp); + mResult.r[1] = _mm_mul_ps(C2,vTemp); + mResult.r[2] = _mm_mul_ps(C4,vTemp); + mResult.r[3] = _mm_mul_ps(C6,vTemp); + return mResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMMatrixDeterminant +( + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V0, V1, V2, V3, V4, V5; + XMVECTOR P0, P1, P2, R, S; + XMVECTOR Result; + static CONST XMVECTORU32 SwizzleYXXX = {XM_PERMUTE_0Y, XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0X}; + static CONST XMVECTORU32 SwizzleZZYY = {XM_PERMUTE_0Z, XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_0Y}; + static CONST XMVECTORU32 SwizzleWWWZ = {XM_PERMUTE_0W, XM_PERMUTE_0W, XM_PERMUTE_0W, XM_PERMUTE_0Z}; + static CONST XMVECTOR Sign = {1.0f, -1.0f, 1.0f, -1.0f}; + + V0 = XMVectorPermute(M.r[2], M.r[2], SwizzleYXXX.v); + V1 = XMVectorPermute(M.r[3], M.r[3], SwizzleZZYY.v); + V2 = XMVectorPermute(M.r[2], M.r[2], SwizzleYXXX.v); + V3 = XMVectorPermute(M.r[3], M.r[3], SwizzleWWWZ.v); + V4 = XMVectorPermute(M.r[2], M.r[2], SwizzleZZYY.v); + V5 = XMVectorPermute(M.r[3], M.r[3], SwizzleWWWZ.v); + + P0 = XMVectorMultiply(V0, V1); + P1 = XMVectorMultiply(V2, V3); + P2 = XMVectorMultiply(V4, V5); + + V0 = XMVectorPermute(M.r[2], M.r[2], SwizzleZZYY.v); + V1 = XMVectorPermute(M.r[3], M.r[3], SwizzleYXXX.v); + V2 = XMVectorPermute(M.r[2], M.r[2], SwizzleWWWZ.v); + V3 = XMVectorPermute(M.r[3], M.r[3], SwizzleYXXX.v); + V4 = XMVectorPermute(M.r[2], M.r[2], SwizzleWWWZ.v); + V5 = XMVectorPermute(M.r[3], M.r[3], SwizzleZZYY.v); + + P0 = XMVectorNegativeMultiplySubtract(V0, V1, P0); + P1 = XMVectorNegativeMultiplySubtract(V2, V3, P1); + P2 = XMVectorNegativeMultiplySubtract(V4, V5, P2); + + V0 = XMVectorPermute(M.r[1], M.r[1], SwizzleWWWZ.v); + V1 = XMVectorPermute(M.r[1], M.r[1], SwizzleZZYY.v); + V2 = XMVectorPermute(M.r[1], M.r[1], SwizzleYXXX.v); + + S = XMVectorMultiply(M.r[0], Sign); + R = XMVectorMultiply(V0, P0); + R = XMVectorNegativeMultiplySubtract(V1, P1, R); + R = XMVectorMultiplyAdd(V2, P2, R); + + Result = XMVector4Dot(S, R); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V0, V1, V2, V3, V4, V5; + XMVECTOR P0, P1, P2, R, S; + XMVECTOR Result; + static CONST XMVECTORU32 SwizzleYXXX = {XM_PERMUTE_0Y, XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0X}; + static CONST XMVECTORU32 SwizzleZZYY = {XM_PERMUTE_0Z, XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_0Y}; + static CONST XMVECTORU32 SwizzleWWWZ = {XM_PERMUTE_0W, XM_PERMUTE_0W, XM_PERMUTE_0W, XM_PERMUTE_0Z}; + static CONST XMVECTORF32 Sign = {1.0f, -1.0f, 1.0f, -1.0f}; + + V0 = XMVectorPermute(M.r[2], M.r[2], SwizzleYXXX); + V1 = XMVectorPermute(M.r[3], M.r[3], SwizzleZZYY); + V2 = XMVectorPermute(M.r[2], M.r[2], SwizzleYXXX); + V3 = XMVectorPermute(M.r[3], M.r[3], SwizzleWWWZ); + V4 = XMVectorPermute(M.r[2], M.r[2], SwizzleZZYY); + V5 = XMVectorPermute(M.r[3], M.r[3], SwizzleWWWZ); + + P0 = _mm_mul_ps(V0, V1); + P1 = _mm_mul_ps(V2, V3); + P2 = _mm_mul_ps(V4, V5); + + V0 = XMVectorPermute(M.r[2], M.r[2], SwizzleZZYY); + V1 = XMVectorPermute(M.r[3], M.r[3], SwizzleYXXX); + V2 = XMVectorPermute(M.r[2], M.r[2], SwizzleWWWZ); + V3 = XMVectorPermute(M.r[3], M.r[3], SwizzleYXXX); + V4 = XMVectorPermute(M.r[2], M.r[2], SwizzleWWWZ); + V5 = XMVectorPermute(M.r[3], M.r[3], SwizzleZZYY); + + P0 = XMVectorNegativeMultiplySubtract(V0, V1, P0); + P1 = XMVectorNegativeMultiplySubtract(V2, V3, P1); + P2 = XMVectorNegativeMultiplySubtract(V4, V5, P2); + + V0 = XMVectorPermute(M.r[1], M.r[1], SwizzleWWWZ); + V1 = XMVectorPermute(M.r[1], M.r[1], SwizzleZZYY); + V2 = XMVectorPermute(M.r[1], M.r[1], SwizzleYXXX); + + S = _mm_mul_ps(M.r[0], Sign); + R = _mm_mul_ps(V0, P0); + R = XMVectorNegativeMultiplySubtract(V1, P1, R); + R = XMVectorMultiplyAdd(V2, P2, R); + + Result = XMVector4Dot(S, R); + + return Result; + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +#define XMRANKDECOMPOSE(a, b, c, x, y, z) \ + if((x) < (y)) \ + { \ + if((y) < (z)) \ + { \ + (a) = 2; \ + (b) = 1; \ + (c) = 0; \ + } \ + else \ + { \ + (a) = 1; \ + \ + if((x) < (z)) \ + { \ + (b) = 2; \ + (c) = 0; \ + } \ + else \ + { \ + (b) = 0; \ + (c) = 2; \ + } \ + } \ + } \ + else \ + { \ + if((x) < (z)) \ + { \ + (a) = 2; \ + (b) = 0; \ + (c) = 1; \ + } \ + else \ + { \ + (a) = 0; \ + \ + if((y) < (z)) \ + { \ + (b) = 2; \ + (c) = 1; \ + } \ + else \ + { \ + (b) = 1; \ + (c) = 2; \ + } \ + } \ + } + +#define XM_DECOMP_EPSILON 0.0001f + +XMINLINE BOOL XMMatrixDecompose( XMVECTOR *outScale, XMVECTOR *outRotQuat, XMVECTOR *outTrans, CXMMATRIX M ) +{ + FLOAT fDet; + FLOAT *pfScales; + XMVECTOR *ppvBasis[3]; + XMMATRIX matTemp; + UINT a, b, c; + static const XMVECTOR *pvCanonicalBasis[3] = { + &g_XMIdentityR0.v, + &g_XMIdentityR1.v, + &g_XMIdentityR2.v + }; + + // Get the translation + outTrans[0] = M.r[3]; + + ppvBasis[0] = &matTemp.r[0]; + ppvBasis[1] = &matTemp.r[1]; + ppvBasis[2] = &matTemp.r[2]; + + matTemp.r[0] = M.r[0]; + matTemp.r[1] = M.r[1]; + matTemp.r[2] = M.r[2]; + matTemp.r[3] = g_XMIdentityR3.v; + + pfScales = (FLOAT *)outScale; + + XMVectorGetXPtr(&pfScales[0],XMVector3Length(ppvBasis[0][0])); + XMVectorGetXPtr(&pfScales[1],XMVector3Length(ppvBasis[1][0])); + XMVectorGetXPtr(&pfScales[2],XMVector3Length(ppvBasis[2][0])); + + XMRANKDECOMPOSE(a, b, c, pfScales[0], pfScales[1], pfScales[2]) + + if(pfScales[a] < XM_DECOMP_EPSILON) + { + ppvBasis[a][0] = pvCanonicalBasis[a][0]; + } + ppvBasis[a][0] = XMVector3Normalize(ppvBasis[a][0]); + + if(pfScales[b] < XM_DECOMP_EPSILON) + { + UINT aa, bb, cc; + FLOAT fAbsX, fAbsY, fAbsZ; + + fAbsX = fabsf(XMVectorGetX(ppvBasis[a][0])); + fAbsY = fabsf(XMVectorGetY(ppvBasis[a][0])); + fAbsZ = fabsf(XMVectorGetZ(ppvBasis[a][0])); + + XMRANKDECOMPOSE(aa, bb, cc, fAbsX, fAbsY, fAbsZ) + + ppvBasis[b][0] = XMVector3Cross(ppvBasis[a][0],pvCanonicalBasis[cc][0]); + } + + ppvBasis[b][0] = XMVector3Normalize(ppvBasis[b][0]); + + if(pfScales[c] < XM_DECOMP_EPSILON) + { + ppvBasis[c][0] = XMVector3Cross(ppvBasis[a][0],ppvBasis[b][0]); + } + + ppvBasis[c][0] = XMVector3Normalize(ppvBasis[c][0]); + + fDet = XMVectorGetX(XMMatrixDeterminant(matTemp)); + + // use Kramer's rule to check for handedness of coordinate system + if(fDet < 0.0f) + { + // switch coordinate system by negating the scale and inverting the basis vector on the x-axis + pfScales[a] = -pfScales[a]; + ppvBasis[a][0] = XMVectorNegate(ppvBasis[a][0]); + + fDet = -fDet; + } + + fDet -= 1.0f; + fDet *= fDet; + + if(XM_DECOMP_EPSILON < fDet) + { +// Non-SRT matrix encountered + return FALSE; + } + + // generate the quaternion from the matrix + outRotQuat[0] = XMQuaternionRotationMatrix(matTemp); + return TRUE; +} + +//------------------------------------------------------------------------------ +// Transformation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixIdentity() +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + M.r[0] = g_XMIdentityR0.v; + M.r[1] = g_XMIdentityR1.v; + M.r[2] = g_XMIdentityR2.v; + M.r[3] = g_XMIdentityR3.v; + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + M.r[0] = g_XMIdentityR0; + M.r[1] = g_XMIdentityR1; + M.r[2] = g_XMIdentityR2; + M.r[3] = g_XMIdentityR3; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixSet +( + FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03, + FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13, + FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23, + FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33 +) +{ + XMMATRIX M; + + M.r[0] = XMVectorSet(m00, m01, m02, m03); + M.r[1] = XMVectorSet(m10, m11, m12, m13); + M.r[2] = XMVectorSet(m20, m21, m22, m23); + M.r[3] = XMVectorSet(m30, m31, m32, m33); + + return M; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixTranslation +( + FLOAT OffsetX, + FLOAT OffsetY, + FLOAT OffsetZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + + M.m[0][0] = 1.0f; + M.m[0][1] = 0.0f; + M.m[0][2] = 0.0f; + M.m[0][3] = 0.0f; + + M.m[1][0] = 0.0f; + M.m[1][1] = 1.0f; + M.m[1][2] = 0.0f; + M.m[1][3] = 0.0f; + + M.m[2][0] = 0.0f; + M.m[2][1] = 0.0f; + M.m[2][2] = 1.0f; + M.m[2][3] = 0.0f; + + M.m[3][0] = OffsetX; + M.m[3][1] = OffsetY; + M.m[3][2] = OffsetZ; + M.m[3][3] = 1.0f; + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + M.r[0] = g_XMIdentityR0; + M.r[1] = g_XMIdentityR1; + M.r[2] = g_XMIdentityR2; + M.r[3] = _mm_set_ps(1.0f,OffsetZ,OffsetY,OffsetX); + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixTranslationFromVector +( + FXMVECTOR Offset +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + M.m[0][0] = 1.0f; + M.m[0][1] = 0.0f; + M.m[0][2] = 0.0f; + M.m[0][3] = 0.0f; + + M.m[1][0] = 0.0f; + M.m[1][1] = 1.0f; + M.m[1][2] = 0.0f; + M.m[1][3] = 0.0f; + + M.m[2][0] = 0.0f; + M.m[2][1] = 0.0f; + M.m[2][2] = 1.0f; + M.m[2][3] = 0.0f; + + M.m[3][0] = Offset.vector4_f32[0]; + M.m[3][1] = Offset.vector4_f32[1]; + M.m[3][2] = Offset.vector4_f32[2]; + M.m[3][3] = 1.0f; + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_and_ps(Offset,g_XMMask3); + vTemp = _mm_or_ps(vTemp,g_XMIdentityR3); + XMMATRIX M; + M.r[0] = g_XMIdentityR0; + M.r[1] = g_XMIdentityR1; + M.r[2] = g_XMIdentityR2; + M.r[3] = vTemp; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixScaling +( + FLOAT ScaleX, + FLOAT ScaleY, + FLOAT ScaleZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + + M.r[0] = XMVectorSet(ScaleX, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, ScaleY, 0.0f, 0.0f); + M.r[2] = XMVectorSet(0.0f, 0.0f, ScaleZ, 0.0f); + + M.r[3] = g_XMIdentityR3.v; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + M.r[0] = _mm_set_ps( 0, 0, 0, ScaleX ); + M.r[1] = _mm_set_ps( 0, 0, ScaleY, 0 ); + M.r[2] = _mm_set_ps( 0, ScaleZ, 0, 0 ); + M.r[3] = g_XMIdentityR3; + return M; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixScalingFromVector +( + FXMVECTOR Scale +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX M; + M.m[0][0] = Scale.vector4_f32[0]; + M.m[0][1] = 0.0f; + M.m[0][2] = 0.0f; + M.m[0][3] = 0.0f; + + M.m[1][0] = 0.0f; + M.m[1][1] = Scale.vector4_f32[1]; + M.m[1][2] = 0.0f; + M.m[1][3] = 0.0f; + + M.m[2][0] = 0.0f; + M.m[2][1] = 0.0f; + M.m[2][2] = Scale.vector4_f32[2]; + M.m[2][3] = 0.0f; + + M.m[3][0] = 0.0f; + M.m[3][1] = 0.0f; + M.m[3][2] = 0.0f; + M.m[3][3] = 1.0f; + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + M.r[0] = _mm_and_ps(Scale,g_XMMaskX); + M.r[1] = _mm_and_ps(Scale,g_XMMaskY); + M.r[2] = _mm_and_ps(Scale,g_XMMaskZ); + M.r[3] = g_XMIdentityR3; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixRotationX +( + FLOAT Angle +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX M; + + FLOAT fSinAngle = sinf(Angle); + FLOAT fCosAngle = cosf(Angle); + + M.m[0][0] = 1.0f; + M.m[0][1] = 0.0f; + M.m[0][2] = 0.0f; + M.m[0][3] = 0.0f; + + M.m[1][0] = 0.0f; + M.m[1][1] = fCosAngle; + M.m[1][2] = fSinAngle; + M.m[1][3] = 0.0f; + + M.m[2][0] = 0.0f; + M.m[2][1] = -fSinAngle; + M.m[2][2] = fCosAngle; + M.m[2][3] = 0.0f; + + M.m[3][0] = 0.0f; + M.m[3][1] = 0.0f; + M.m[3][2] = 0.0f; + M.m[3][3] = 1.0f; + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + FLOAT SinAngle = sinf(Angle); + FLOAT CosAngle = cosf(Angle); + + XMVECTOR vSin = _mm_set_ss(SinAngle); + XMVECTOR vCos = _mm_set_ss(CosAngle); + // x = 0,y = cos,z = sin, w = 0 + vCos = _mm_shuffle_ps(vCos,vSin,_MM_SHUFFLE(3,0,0,3)); + XMMATRIX M; + M.r[0] = g_XMIdentityR0; + M.r[1] = vCos; + // x = 0,y = sin,z = cos, w = 0 + vCos = _mm_shuffle_ps(vCos,vCos,_MM_SHUFFLE(3,1,2,0)); + // x = 0,y = -sin,z = cos, w = 0 + vCos = _mm_mul_ps(vCos,g_XMNegateY); + M.r[2] = vCos; + M.r[3] = g_XMIdentityR3; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixRotationY +( + FLOAT Angle +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX M; + + FLOAT fSinAngle = sinf(Angle); + FLOAT fCosAngle = cosf(Angle); + + M.m[0][0] = fCosAngle; + M.m[0][1] = 0.0f; + M.m[0][2] = -fSinAngle; + M.m[0][3] = 0.0f; + + M.m[1][0] = 0.0f; + M.m[1][1] = 1.0f; + M.m[1][2] = 0.0f; + M.m[1][3] = 0.0f; + + M.m[2][0] = fSinAngle; + M.m[2][1] = 0.0f; + M.m[2][2] = fCosAngle; + M.m[2][3] = 0.0f; + + M.m[3][0] = 0.0f; + M.m[3][1] = 0.0f; + M.m[3][2] = 0.0f; + M.m[3][3] = 1.0f; + return M; +#elif defined(_XM_SSE_INTRINSICS_) + FLOAT SinAngle = sinf(Angle); + FLOAT CosAngle = cosf(Angle); + + XMVECTOR vSin = _mm_set_ss(SinAngle); + XMVECTOR vCos = _mm_set_ss(CosAngle); + // x = sin,y = 0,z = cos, w = 0 + vSin = _mm_shuffle_ps(vSin,vCos,_MM_SHUFFLE(3,0,3,0)); + XMMATRIX M; + M.r[2] = vSin; + M.r[1] = g_XMIdentityR1; + // x = cos,y = 0,z = sin, w = 0 + vSin = _mm_shuffle_ps(vSin,vSin,_MM_SHUFFLE(3,0,1,2)); + // x = cos,y = 0,z = -sin, w = 0 + vSin = _mm_mul_ps(vSin,g_XMNegateZ); + M.r[0] = vSin; + M.r[3] = g_XMIdentityR3; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixRotationZ +( + FLOAT Angle +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMMATRIX M; + + FLOAT fSinAngle = sinf(Angle); + FLOAT fCosAngle = cosf(Angle); + + M.m[0][0] = fCosAngle; + M.m[0][1] = fSinAngle; + M.m[0][2] = 0.0f; + M.m[0][3] = 0.0f; + + M.m[1][0] = -fSinAngle; + M.m[1][1] = fCosAngle; + M.m[1][2] = 0.0f; + M.m[1][3] = 0.0f; + + M.m[2][0] = 0.0f; + M.m[2][1] = 0.0f; + M.m[2][2] = 1.0f; + M.m[2][3] = 0.0f; + + M.m[3][0] = 0.0f; + M.m[3][1] = 0.0f; + M.m[3][2] = 0.0f; + M.m[3][3] = 1.0f; + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + FLOAT SinAngle = sinf(Angle); + FLOAT CosAngle = cosf(Angle); + + XMVECTOR vSin = _mm_set_ss(SinAngle); + XMVECTOR vCos = _mm_set_ss(CosAngle); + // x = cos,y = sin,z = 0, w = 0 + vCos = _mm_unpacklo_ps(vCos,vSin); + XMMATRIX M; + M.r[0] = vCos; + // x = sin,y = cos,z = 0, w = 0 + vCos = _mm_shuffle_ps(vCos,vCos,_MM_SHUFFLE(3,2,0,1)); + // x = cos,y = -sin,z = 0, w = 0 + vCos = _mm_mul_ps(vCos,g_XMNegateX); + M.r[1] = vCos; + M.r[2] = g_XMIdentityR2; + M.r[3] = g_XMIdentityR3; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixRotationRollPitchYaw +( + FLOAT Pitch, + FLOAT Yaw, + FLOAT Roll +) +{ + XMVECTOR Angles; + XMMATRIX M; + + Angles = XMVectorSet(Pitch, Yaw, Roll, 0.0f); + M = XMMatrixRotationRollPitchYawFromVector(Angles); + + return M; +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixRotationRollPitchYawFromVector +( + FXMVECTOR Angles // +) +{ + XMVECTOR Q; + XMMATRIX M; + + Q = XMQuaternionRotationRollPitchYawFromVector(Angles); + M = XMMatrixRotationQuaternion(Q); + + return M; +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixRotationNormal +( + FXMVECTOR NormalAxis, + FLOAT Angle +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR A; + XMVECTOR N0, N1; + XMVECTOR V0, V1, V2; + XMVECTOR R0, R1, R2; + XMVECTOR C0, C1, C2; + XMMATRIX M; + static CONST XMVECTORU32 SwizzleYZXW = {XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0X, XM_PERMUTE_0W}; + static CONST XMVECTORU32 SwizzleZXYW = {XM_PERMUTE_0Z, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute0Z1Y1Z0X = {XM_PERMUTE_0Z, XM_PERMUTE_1Y, XM_PERMUTE_1Z, XM_PERMUTE_0X}; + static CONST XMVECTORU32 Permute0Y1X0Y1X = {XM_PERMUTE_0Y, XM_PERMUTE_1X, XM_PERMUTE_0Y, XM_PERMUTE_1X}; + static CONST XMVECTORU32 Permute0X1X1Y0W = {XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_1Y, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute1Z0Y1W0W = {XM_PERMUTE_1Z, XM_PERMUTE_0Y, XM_PERMUTE_1W, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute1X1Y0Z0W = {XM_PERMUTE_1X, XM_PERMUTE_1Y, XM_PERMUTE_0Z, XM_PERMUTE_0W}; + + FLOAT fSinAngle = sinf(Angle); + FLOAT fCosAngle = cosf(Angle); + + A = XMVectorSet(fSinAngle, fCosAngle, 1.0f - fCosAngle, 0.0f); + + C2 = XMVectorSplatZ(A); + C1 = XMVectorSplatY(A); + C0 = XMVectorSplatX(A); + + N0 = XMVectorPermute(NormalAxis, NormalAxis, SwizzleYZXW.v); + N1 = XMVectorPermute(NormalAxis, NormalAxis, SwizzleZXYW.v); + + V0 = XMVectorMultiply(C2, N0); + V0 = XMVectorMultiply(V0, N1); + + R0 = XMVectorMultiply(C2, NormalAxis); + R0 = XMVectorMultiplyAdd(R0, NormalAxis, C1); + + R1 = XMVectorMultiplyAdd(C0, NormalAxis, V0); + R2 = XMVectorNegativeMultiplySubtract(C0, NormalAxis, V0); + + V0 = XMVectorSelect(A, R0, g_XMSelect1110.v); + V1 = XMVectorPermute(R1, R2, Permute0Z1Y1Z0X.v); + V2 = XMVectorPermute(R1, R2, Permute0Y1X0Y1X.v); + + M.r[0] = XMVectorPermute(V0, V1, Permute0X1X1Y0W.v); + M.r[1] = XMVectorPermute(V0, V1, Permute1Z0Y1W0W.v); + M.r[2] = XMVectorPermute(V0, V2, Permute1X1Y0Z0W.v); + M.r[3] = g_XMIdentityR3.v; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR N0, N1; + XMVECTOR V0, V1, V2; + XMVECTOR R0, R1, R2; + XMVECTOR C0, C1, C2; + XMMATRIX M; + + FLOAT fSinAngle = sinf(Angle); + FLOAT fCosAngle = cosf(Angle); + + C2 = _mm_set_ps1(1.0f - fCosAngle); + C1 = _mm_set_ps1(fCosAngle); + C0 = _mm_set_ps1(fSinAngle); + + N0 = _mm_shuffle_ps(NormalAxis,NormalAxis,_MM_SHUFFLE(3,0,2,1)); +// N0 = XMVectorPermute(NormalAxis, NormalAxis, SwizzleYZXW); + N1 = _mm_shuffle_ps(NormalAxis,NormalAxis,_MM_SHUFFLE(3,1,0,2)); +// N1 = XMVectorPermute(NormalAxis, NormalAxis, SwizzleZXYW); + + V0 = _mm_mul_ps(C2, N0); + V0 = _mm_mul_ps(V0, N1); + + R0 = _mm_mul_ps(C2, NormalAxis); + R0 = _mm_mul_ps(R0, NormalAxis); + R0 = _mm_add_ps(R0, C1); + + R1 = _mm_mul_ps(C0, NormalAxis); + R1 = _mm_add_ps(R1, V0); + R2 = _mm_mul_ps(C0, NormalAxis); + R2 = _mm_sub_ps(V0,R2); + + V0 = _mm_and_ps(R0,g_XMMask3); +// V0 = XMVectorSelect(A, R0, g_XMSelect1110); + V1 = _mm_shuffle_ps(R1,R2,_MM_SHUFFLE(2,1,2,0)); + V1 = _mm_shuffle_ps(V1,V1,_MM_SHUFFLE(0,3,2,1)); +// V1 = XMVectorPermute(R1, R2, Permute0Z1Y1Z0X); + V2 = _mm_shuffle_ps(R1,R2,_MM_SHUFFLE(0,0,1,1)); + V2 = _mm_shuffle_ps(V2,V2,_MM_SHUFFLE(2,0,2,0)); +// V2 = XMVectorPermute(R1, R2, Permute0Y1X0Y1X); + + R2 = _mm_shuffle_ps(V0,V1,_MM_SHUFFLE(1,0,3,0)); + R2 = _mm_shuffle_ps(R2,R2,_MM_SHUFFLE(1,3,2,0)); + M.r[0] = R2; +// M.r[0] = XMVectorPermute(V0, V1, Permute0X1X1Y0W); + R2 = _mm_shuffle_ps(V0,V1,_MM_SHUFFLE(3,2,3,1)); + R2 = _mm_shuffle_ps(R2,R2,_MM_SHUFFLE(1,3,0,2)); + M.r[1] = R2; +// M.r[1] = XMVectorPermute(V0, V1, Permute1Z0Y1W0W); + V2 = _mm_shuffle_ps(V2,V0,_MM_SHUFFLE(3,2,1,0)); +// R2 = _mm_shuffle_ps(R2,R2,_MM_SHUFFLE(3,2,1,0)); + M.r[2] = V2; +// M.r[2] = XMVectorPermute(V0, V2, Permute1X1Y0Z0W); + M.r[3] = g_XMIdentityR3; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixRotationAxis +( + FXMVECTOR Axis, + FLOAT Angle +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Normal; + XMMATRIX M; + + XMASSERT(!XMVector3Equal(Axis, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(Axis)); + + Normal = XMVector3Normalize(Axis); + M = XMMatrixRotationNormal(Normal, Angle); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMVector3Equal(Axis, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(Axis)); + XMVECTOR Normal = XMVector3Normalize(Axis); + XMMATRIX M = XMMatrixRotationNormal(Normal, Angle); + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixRotationQuaternion +( + FXMVECTOR Quaternion +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + XMVECTOR Q0, Q1; + XMVECTOR V0, V1, V2; + XMVECTOR R0, R1, R2; + static CONST XMVECTOR Constant1110 = {1.0f, 1.0f, 1.0f, 0.0f}; + static CONST XMVECTORU32 SwizzleXXYW = {XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0W}; + static CONST XMVECTORU32 SwizzleZYZW = {XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0W}; + static CONST XMVECTORU32 SwizzleYZXW = {XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0X, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute0Y0X0X1W = {XM_PERMUTE_0Y, XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_1W}; + static CONST XMVECTORU32 Permute0Z0Z0Y1W = {XM_PERMUTE_0Z, XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_1W}; + static CONST XMVECTORU32 Permute0Y1X1Y0Z = {XM_PERMUTE_0Y, XM_PERMUTE_1X, XM_PERMUTE_1Y, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 Permute0X1Z0X1Z = {XM_PERMUTE_0X, XM_PERMUTE_1Z, XM_PERMUTE_0X, XM_PERMUTE_1Z}; + static CONST XMVECTORU32 Permute0X1X1Y0W = {XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_1Y, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute1Z0Y1W0W = {XM_PERMUTE_1Z, XM_PERMUTE_0Y, XM_PERMUTE_1W, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute1X1Y0Z0W = {XM_PERMUTE_1X, XM_PERMUTE_1Y, XM_PERMUTE_0Z, XM_PERMUTE_0W}; + + Q0 = XMVectorAdd(Quaternion, Quaternion); + Q1 = XMVectorMultiply(Quaternion, Q0); + + V0 = XMVectorPermute(Q1, Constant1110, Permute0Y0X0X1W.v); + V1 = XMVectorPermute(Q1, Constant1110, Permute0Z0Z0Y1W.v); + R0 = XMVectorSubtract(Constant1110, V0); + R0 = XMVectorSubtract(R0, V1); + + V0 = XMVectorPermute(Quaternion, Quaternion, SwizzleXXYW.v); + V1 = XMVectorPermute(Q0, Q0, SwizzleZYZW.v); + V0 = XMVectorMultiply(V0, V1); + + V1 = XMVectorSplatW(Quaternion); + V2 = XMVectorPermute(Q0, Q0, SwizzleYZXW.v); + V1 = XMVectorMultiply(V1, V2); + + R1 = XMVectorAdd(V0, V1); + R2 = XMVectorSubtract(V0, V1); + + V0 = XMVectorPermute(R1, R2, Permute0Y1X1Y0Z.v); + V1 = XMVectorPermute(R1, R2, Permute0X1Z0X1Z.v); + + M.r[0] = XMVectorPermute(R0, V0, Permute0X1X1Y0W.v); + M.r[1] = XMVectorPermute(R0, V0, Permute1Z0Y1W0W.v); + M.r[2] = XMVectorPermute(R0, V1, Permute1X1Y0Z0W.v); + M.r[3] = g_XMIdentityR3.v; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + XMVECTOR Q0, Q1; + XMVECTOR V0, V1, V2; + XMVECTOR R0, R1, R2; + static CONST XMVECTORF32 Constant1110 = {1.0f, 1.0f, 1.0f, 0.0f}; + + Q0 = _mm_add_ps(Quaternion,Quaternion); + Q1 = _mm_mul_ps(Quaternion,Q0); + + V0 = _mm_shuffle_ps(Q1,Q1,_MM_SHUFFLE(3,0,0,1)); + V0 = _mm_and_ps(V0,g_XMMask3); +// V0 = XMVectorPermute(Q1, Constant1110,Permute0Y0X0X1W); + V1 = _mm_shuffle_ps(Q1,Q1,_MM_SHUFFLE(3,1,2,2)); + V1 = _mm_and_ps(V1,g_XMMask3); +// V1 = XMVectorPermute(Q1, Constant1110,Permute0Z0Z0Y1W); + R0 = _mm_sub_ps(Constant1110,V0); + R0 = _mm_sub_ps(R0, V1); + + V0 = _mm_shuffle_ps(Quaternion,Quaternion,_MM_SHUFFLE(3,1,0,0)); +// V0 = XMVectorPermute(Quaternion, Quaternion,SwizzleXXYW); + V1 = _mm_shuffle_ps(Q0,Q0,_MM_SHUFFLE(3,2,1,2)); +// V1 = XMVectorPermute(Q0, Q0,SwizzleZYZW); + V0 = _mm_mul_ps(V0, V1); + + V1 = _mm_shuffle_ps(Quaternion,Quaternion,_MM_SHUFFLE(3,3,3,3)); +// V1 = XMVectorSplatW(Quaternion); + V2 = _mm_shuffle_ps(Q0,Q0,_MM_SHUFFLE(3,0,2,1)); +// V2 = XMVectorPermute(Q0, Q0,SwizzleYZXW); + V1 = _mm_mul_ps(V1, V2); + + R1 = _mm_add_ps(V0, V1); + R2 = _mm_sub_ps(V0, V1); + + V0 = _mm_shuffle_ps(R1,R2,_MM_SHUFFLE(1,0,2,1)); + V0 = _mm_shuffle_ps(V0,V0,_MM_SHUFFLE(1,3,2,0)); +// V0 = XMVectorPermute(R1, R2,Permute0Y1X1Y0Z); + V1 = _mm_shuffle_ps(R1,R2,_MM_SHUFFLE(2,2,0,0)); + V1 = _mm_shuffle_ps(V1,V1,_MM_SHUFFLE(2,0,2,0)); +// V1 = XMVectorPermute(R1, R2,Permute0X1Z0X1Z); + + Q1 = _mm_shuffle_ps(R0,V0,_MM_SHUFFLE(1,0,3,0)); + Q1 = _mm_shuffle_ps(Q1,Q1,_MM_SHUFFLE(1,3,2,0)); + M.r[0] = Q1; +// M.r[0] = XMVectorPermute(R0, V0,Permute0X1X1Y0W); + Q1 = _mm_shuffle_ps(R0,V0,_MM_SHUFFLE(3,2,3,1)); + Q1 = _mm_shuffle_ps(Q1,Q1,_MM_SHUFFLE(1,3,0,2)); + M.r[1] = Q1; +// M.r[1] = XMVectorPermute(R0, V0,Permute1Z0Y1W0W); + Q1 = _mm_shuffle_ps(V1,R0,_MM_SHUFFLE(3,2,1,0)); + M.r[2] = Q1; +// M.r[2] = XMVectorPermute(R0, V1,Permute1X1Y0Z0W); + M.r[3] = g_XMIdentityR3; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixTransformation2D +( + FXMVECTOR ScalingOrigin, + FLOAT ScalingOrientation, + FXMVECTOR Scaling, + FXMVECTOR RotationOrigin, + FLOAT Rotation, + CXMVECTOR Translation +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + XMVECTOR VScaling; + XMVECTOR NegScalingOrigin; + XMVECTOR VScalingOrigin; + XMMATRIX MScalingOriginI; + XMMATRIX MScalingOrientation; + XMMATRIX MScalingOrientationT; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + + // M = Inverse(MScalingOrigin) * Transpose(MScalingOrientation) * MScaling * MScalingOrientation * + // MScalingOrigin * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + + VScalingOrigin = XMVectorSelect(g_XMSelect1100.v, ScalingOrigin, g_XMSelect1100.v); + NegScalingOrigin = XMVectorNegate(VScalingOrigin); + + MScalingOriginI = XMMatrixTranslationFromVector(NegScalingOrigin); + MScalingOrientation = XMMatrixRotationZ(ScalingOrientation); + MScalingOrientationT = XMMatrixTranspose(MScalingOrientation); + VScaling = XMVectorSelect(g_XMOne.v, Scaling, g_XMSelect1100.v); + MScaling = XMMatrixScalingFromVector(VScaling); + VRotationOrigin = XMVectorSelect(g_XMSelect1100.v, RotationOrigin, g_XMSelect1100.v); + MRotation = XMMatrixRotationZ(Rotation); + VTranslation = XMVectorSelect(g_XMSelect1100.v, Translation,g_XMSelect1100.v); + + M = XMMatrixMultiply(MScalingOriginI, MScalingOrientationT); + M = XMMatrixMultiply(M, MScaling); + M = XMMatrixMultiply(M, MScalingOrientation); + M.r[3] = XMVectorAdd(M.r[3], VScalingOrigin); + M.r[3] = XMVectorSubtract(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = XMVectorAdd(M.r[3], VRotationOrigin); + M.r[3] = XMVectorAdd(M.r[3], VTranslation); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + XMVECTOR VScaling; + XMVECTOR NegScalingOrigin; + XMVECTOR VScalingOrigin; + XMMATRIX MScalingOriginI; + XMMATRIX MScalingOrientation; + XMMATRIX MScalingOrientationT; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + + // M = Inverse(MScalingOrigin) * Transpose(MScalingOrientation) * MScaling * MScalingOrientation * + // MScalingOrigin * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + static const XMVECTORU32 Mask2 = {0xFFFFFFFF,0xFFFFFFFF,0,0}; + static const XMVECTORF32 ZWOne = {0,0,1.0f,1.0f}; + + VScalingOrigin = _mm_and_ps(ScalingOrigin, Mask2); + NegScalingOrigin = XMVectorNegate(VScalingOrigin); + + MScalingOriginI = XMMatrixTranslationFromVector(NegScalingOrigin); + MScalingOrientation = XMMatrixRotationZ(ScalingOrientation); + MScalingOrientationT = XMMatrixTranspose(MScalingOrientation); + VScaling = _mm_and_ps(Scaling, Mask2); + VScaling = _mm_or_ps(VScaling,ZWOne); + MScaling = XMMatrixScalingFromVector(VScaling); + VRotationOrigin = _mm_and_ps(RotationOrigin, Mask2); + MRotation = XMMatrixRotationZ(Rotation); + VTranslation = _mm_and_ps(Translation, Mask2); + + M = XMMatrixMultiply(MScalingOriginI, MScalingOrientationT); + M = XMMatrixMultiply(M, MScaling); + M = XMMatrixMultiply(M, MScalingOrientation); + M.r[3] = XMVectorAdd(M.r[3], VScalingOrigin); + M.r[3] = XMVectorSubtract(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = XMVectorAdd(M.r[3], VRotationOrigin); + M.r[3] = XMVectorAdd(M.r[3], VTranslation); + + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixTransformation +( + FXMVECTOR ScalingOrigin, + FXMVECTOR ScalingOrientationQuaternion, + FXMVECTOR Scaling, + CXMVECTOR RotationOrigin, + CXMVECTOR RotationQuaternion, + CXMVECTOR Translation +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + XMVECTOR NegScalingOrigin; + XMVECTOR VScalingOrigin; + XMMATRIX MScalingOriginI; + XMMATRIX MScalingOrientation; + XMMATRIX MScalingOrientationT; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + + // M = Inverse(MScalingOrigin) * Transpose(MScalingOrientation) * MScaling * MScalingOrientation * + // MScalingOrigin * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + + VScalingOrigin = XMVectorSelect(g_XMSelect1110.v, ScalingOrigin, g_XMSelect1110.v); + NegScalingOrigin = XMVectorNegate(ScalingOrigin); + + MScalingOriginI = XMMatrixTranslationFromVector(NegScalingOrigin); + MScalingOrientation = XMMatrixRotationQuaternion(ScalingOrientationQuaternion); + MScalingOrientationT = XMMatrixTranspose(MScalingOrientation); + MScaling = XMMatrixScalingFromVector(Scaling); + VRotationOrigin = XMVectorSelect(g_XMSelect1110.v, RotationOrigin, g_XMSelect1110.v); + MRotation = XMMatrixRotationQuaternion(RotationQuaternion); + VTranslation = XMVectorSelect(g_XMSelect1110.v, Translation, g_XMSelect1110.v); + + M = XMMatrixMultiply(MScalingOriginI, MScalingOrientationT); + M = XMMatrixMultiply(M, MScaling); + M = XMMatrixMultiply(M, MScalingOrientation); + M.r[3] = XMVectorAdd(M.r[3], VScalingOrigin); + M.r[3] = XMVectorSubtract(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = XMVectorAdd(M.r[3], VRotationOrigin); + M.r[3] = XMVectorAdd(M.r[3], VTranslation); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + XMVECTOR NegScalingOrigin; + XMVECTOR VScalingOrigin; + XMMATRIX MScalingOriginI; + XMMATRIX MScalingOrientation; + XMMATRIX MScalingOrientationT; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + + // M = Inverse(MScalingOrigin) * Transpose(MScalingOrientation) * MScaling * MScalingOrientation * + // MScalingOrigin * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + + VScalingOrigin = _mm_and_ps(ScalingOrigin,g_XMMask3); + NegScalingOrigin = XMVectorNegate(ScalingOrigin); + + MScalingOriginI = XMMatrixTranslationFromVector(NegScalingOrigin); + MScalingOrientation = XMMatrixRotationQuaternion(ScalingOrientationQuaternion); + MScalingOrientationT = XMMatrixTranspose(MScalingOrientation); + MScaling = XMMatrixScalingFromVector(Scaling); + VRotationOrigin = _mm_and_ps(RotationOrigin,g_XMMask3); + MRotation = XMMatrixRotationQuaternion(RotationQuaternion); + VTranslation = _mm_and_ps(Translation,g_XMMask3); + + M = XMMatrixMultiply(MScalingOriginI, MScalingOrientationT); + M = XMMatrixMultiply(M, MScaling); + M = XMMatrixMultiply(M, MScalingOrientation); + M.r[3] = XMVectorAdd(M.r[3], VScalingOrigin); + M.r[3] = XMVectorSubtract(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = XMVectorAdd(M.r[3], VRotationOrigin); + M.r[3] = XMVectorAdd(M.r[3], VTranslation); + + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixAffineTransformation2D +( + FXMVECTOR Scaling, + FXMVECTOR RotationOrigin, + FLOAT Rotation, + FXMVECTOR Translation +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + XMVECTOR VScaling; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + + // M = MScaling * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + + VScaling = XMVectorSelect(g_XMOne.v, Scaling, g_XMSelect1100.v); + MScaling = XMMatrixScalingFromVector(VScaling); + VRotationOrigin = XMVectorSelect(g_XMSelect1100.v, RotationOrigin, g_XMSelect1100.v); + MRotation = XMMatrixRotationZ(Rotation); + VTranslation = XMVectorSelect(g_XMSelect1100.v, Translation,g_XMSelect1100.v); + + M = MScaling; + M.r[3] = XMVectorSubtract(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = XMVectorAdd(M.r[3], VRotationOrigin); + M.r[3] = XMVectorAdd(M.r[3], VTranslation); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + XMVECTOR VScaling; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + static const XMVECTORU32 Mask2 = {0xFFFFFFFFU,0xFFFFFFFFU,0,0}; + static const XMVECTORF32 ZW1 = {0,0,1.0f,1.0f}; + + // M = MScaling * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + + VScaling = _mm_and_ps(Scaling, Mask2); + VScaling = _mm_or_ps(VScaling, ZW1); + MScaling = XMMatrixScalingFromVector(VScaling); + VRotationOrigin = _mm_and_ps(RotationOrigin, Mask2); + MRotation = XMMatrixRotationZ(Rotation); + VTranslation = _mm_and_ps(Translation, Mask2); + + M = MScaling; + M.r[3] = _mm_sub_ps(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = _mm_add_ps(M.r[3], VRotationOrigin); + M.r[3] = _mm_add_ps(M.r[3], VTranslation); + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixAffineTransformation +( + FXMVECTOR Scaling, + FXMVECTOR RotationOrigin, + FXMVECTOR RotationQuaternion, + CXMVECTOR Translation +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + + // M = MScaling * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + + MScaling = XMMatrixScalingFromVector(Scaling); + VRotationOrigin = XMVectorSelect(g_XMSelect1110.v, RotationOrigin,g_XMSelect1110.v); + MRotation = XMMatrixRotationQuaternion(RotationQuaternion); + VTranslation = XMVectorSelect(g_XMSelect1110.v, Translation,g_XMSelect1110.v); + + M = MScaling; + M.r[3] = XMVectorSubtract(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = XMVectorAdd(M.r[3], VRotationOrigin); + M.r[3] = XMVectorAdd(M.r[3], VTranslation); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + XMMATRIX MScaling; + XMVECTOR VRotationOrigin; + XMMATRIX MRotation; + XMVECTOR VTranslation; + + // M = MScaling * Inverse(MRotationOrigin) * MRotation * MRotationOrigin * MTranslation; + + MScaling = XMMatrixScalingFromVector(Scaling); + VRotationOrigin = _mm_and_ps(RotationOrigin,g_XMMask3); + MRotation = XMMatrixRotationQuaternion(RotationQuaternion); + VTranslation = _mm_and_ps(Translation,g_XMMask3); + + M = MScaling; + M.r[3] = _mm_sub_ps(M.r[3], VRotationOrigin); + M = XMMatrixMultiply(M, MRotation); + M.r[3] = _mm_add_ps(M.r[3], VRotationOrigin); + M.r[3] = _mm_add_ps(M.r[3], VTranslation); + + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixReflect +( + FXMVECTOR ReflectionPlane +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR P; + XMVECTOR S; + XMVECTOR A, B, C, D; + XMMATRIX M; + static CONST XMVECTOR NegativeTwo = {-2.0f, -2.0f, -2.0f, 0.0f}; + + XMASSERT(!XMVector3Equal(ReflectionPlane, XMVectorZero())); + XMASSERT(!XMPlaneIsInfinite(ReflectionPlane)); + + P = XMPlaneNormalize(ReflectionPlane); + S = XMVectorMultiply(P, NegativeTwo); + + A = XMVectorSplatX(P); + B = XMVectorSplatY(P); + C = XMVectorSplatZ(P); + D = XMVectorSplatW(P); + + M.r[0] = XMVectorMultiplyAdd(A, S, g_XMIdentityR0.v); + M.r[1] = XMVectorMultiplyAdd(B, S, g_XMIdentityR1.v); + M.r[2] = XMVectorMultiplyAdd(C, S, g_XMIdentityR2.v); + M.r[3] = XMVectorMultiplyAdd(D, S, g_XMIdentityR3.v); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + static CONST XMVECTORF32 NegativeTwo = {-2.0f, -2.0f, -2.0f, 0.0f}; + + XMASSERT(!XMVector3Equal(ReflectionPlane, XMVectorZero())); + XMASSERT(!XMPlaneIsInfinite(ReflectionPlane)); + + XMVECTOR P = XMPlaneNormalize(ReflectionPlane); + XMVECTOR S = _mm_mul_ps(P,NegativeTwo); + XMVECTOR X = _mm_shuffle_ps(P,P,_MM_SHUFFLE(0,0,0,0)); + XMVECTOR Y = _mm_shuffle_ps(P,P,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR Z = _mm_shuffle_ps(P,P,_MM_SHUFFLE(2,2,2,2)); + P = _mm_shuffle_ps(P,P,_MM_SHUFFLE(3,3,3,3)); + X = _mm_mul_ps(X,S); + Y = _mm_mul_ps(Y,S); + Z = _mm_mul_ps(Z,S); + P = _mm_mul_ps(P,S); + X = _mm_add_ps(X,g_XMIdentityR0); + Y = _mm_add_ps(Y,g_XMIdentityR1); + Z = _mm_add_ps(Z,g_XMIdentityR2); + P = _mm_add_ps(P,g_XMIdentityR3); + M.r[0] = X; + M.r[1] = Y; + M.r[2] = Z; + M.r[3] = P; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixShadow +( + FXMVECTOR ShadowPlane, + FXMVECTOR LightPosition +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR P; + XMVECTOR Dot; + XMVECTOR A, B, C, D; + XMMATRIX M; + static CONST XMVECTORU32 Select0001 = {XM_SELECT_0, XM_SELECT_0, XM_SELECT_0, XM_SELECT_1}; + + XMASSERT(!XMVector3Equal(ShadowPlane, XMVectorZero())); + XMASSERT(!XMPlaneIsInfinite(ShadowPlane)); + + P = XMPlaneNormalize(ShadowPlane); + Dot = XMPlaneDot(P, LightPosition); + P = XMVectorNegate(P); + D = XMVectorSplatW(P); + C = XMVectorSplatZ(P); + B = XMVectorSplatY(P); + A = XMVectorSplatX(P); + Dot = XMVectorSelect(Select0001.v, Dot, Select0001.v); + M.r[3] = XMVectorMultiplyAdd(D, LightPosition, Dot); + Dot = XMVectorRotateLeft(Dot, 1); + M.r[2] = XMVectorMultiplyAdd(C, LightPosition, Dot); + Dot = XMVectorRotateLeft(Dot, 1); + M.r[1] = XMVectorMultiplyAdd(B, LightPosition, Dot); + Dot = XMVectorRotateLeft(Dot, 1); + M.r[0] = XMVectorMultiplyAdd(A, LightPosition, Dot); + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + XMASSERT(!XMVector3Equal(ShadowPlane, XMVectorZero())); + XMASSERT(!XMPlaneIsInfinite(ShadowPlane)); + XMVECTOR P = XMPlaneNormalize(ShadowPlane); + XMVECTOR Dot = XMPlaneDot(P,LightPosition); + // Negate + P = _mm_mul_ps(P,g_XMNegativeOne); + XMVECTOR X = _mm_shuffle_ps(P,P,_MM_SHUFFLE(0,0,0,0)); + XMVECTOR Y = _mm_shuffle_ps(P,P,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR Z = _mm_shuffle_ps(P,P,_MM_SHUFFLE(2,2,2,2)); + P = _mm_shuffle_ps(P,P,_MM_SHUFFLE(3,3,3,3)); + Dot = _mm_and_ps(Dot,g_XMMaskW); + X = _mm_mul_ps(X,LightPosition); + Y = _mm_mul_ps(Y,LightPosition); + Z = _mm_mul_ps(Z,LightPosition); + P = _mm_mul_ps(P,LightPosition); + P = _mm_add_ps(P,Dot); + Dot = _mm_shuffle_ps(Dot,Dot,_MM_SHUFFLE(0,3,2,1)); + Z = _mm_add_ps(Z,Dot); + Dot = _mm_shuffle_ps(Dot,Dot,_MM_SHUFFLE(0,3,2,1)); + Y = _mm_add_ps(Y,Dot); + Dot = _mm_shuffle_ps(Dot,Dot,_MM_SHUFFLE(0,3,2,1)); + X = _mm_add_ps(X,Dot); + // Store the resulting matrix + M.r[0] = X; + M.r[1] = Y; + M.r[2] = Z; + M.r[3] = P; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// View and projection initialization operations +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixLookAtLH +( + FXMVECTOR EyePosition, + FXMVECTOR FocusPosition, + FXMVECTOR UpDirection +) +{ + XMVECTOR EyeDirection; + XMMATRIX M; + + EyeDirection = XMVectorSubtract(FocusPosition, EyePosition); + M = XMMatrixLookToLH(EyePosition, EyeDirection, UpDirection); + + return M; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixLookAtRH +( + FXMVECTOR EyePosition, + FXMVECTOR FocusPosition, + FXMVECTOR UpDirection +) +{ + XMVECTOR NegEyeDirection; + XMMATRIX M; + + NegEyeDirection = XMVectorSubtract(EyePosition, FocusPosition); + M = XMMatrixLookToLH(EyePosition, NegEyeDirection, UpDirection); + + return M; +} + +//------------------------------------------------------------------------------ + +XMINLINE XMMATRIX XMMatrixLookToLH +( + FXMVECTOR EyePosition, + FXMVECTOR EyeDirection, + FXMVECTOR UpDirection +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR NegEyePosition; + XMVECTOR D0, D1, D2; + XMVECTOR R0, R1, R2; + XMMATRIX M; + + XMASSERT(!XMVector3Equal(EyeDirection, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(EyeDirection)); + XMASSERT(!XMVector3Equal(UpDirection, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(UpDirection)); + + R2 = XMVector3Normalize(EyeDirection); + + R0 = XMVector3Cross(UpDirection, R2); + R0 = XMVector3Normalize(R0); + + R1 = XMVector3Cross(R2, R0); + + NegEyePosition = XMVectorNegate(EyePosition); + + D0 = XMVector3Dot(R0, NegEyePosition); + D1 = XMVector3Dot(R1, NegEyePosition); + D2 = XMVector3Dot(R2, NegEyePosition); + + M.r[0] = XMVectorSelect(D0, R0, g_XMSelect1110.v); + M.r[1] = XMVectorSelect(D1, R1, g_XMSelect1110.v); + M.r[2] = XMVectorSelect(D2, R2, g_XMSelect1110.v); + M.r[3] = g_XMIdentityR3.v; + + M = XMMatrixTranspose(M); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + + XMASSERT(!XMVector3Equal(EyeDirection, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(EyeDirection)); + XMASSERT(!XMVector3Equal(UpDirection, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(UpDirection)); + + XMVECTOR R2 = XMVector3Normalize(EyeDirection); + XMVECTOR R0 = XMVector3Cross(UpDirection, R2); + R0 = XMVector3Normalize(R0); + XMVECTOR R1 = XMVector3Cross(R2,R0); + XMVECTOR NegEyePosition = _mm_mul_ps(EyePosition,g_XMNegativeOne); + XMVECTOR D0 = XMVector3Dot(R0,NegEyePosition); + XMVECTOR D1 = XMVector3Dot(R1,NegEyePosition); + XMVECTOR D2 = XMVector3Dot(R2,NegEyePosition); + R0 = _mm_and_ps(R0,g_XMMask3); + R1 = _mm_and_ps(R1,g_XMMask3); + R2 = _mm_and_ps(R2,g_XMMask3); + D0 = _mm_and_ps(D0,g_XMMaskW); + D1 = _mm_and_ps(D1,g_XMMaskW); + D2 = _mm_and_ps(D2,g_XMMaskW); + D0 = _mm_or_ps(D0,R0); + D1 = _mm_or_ps(D1,R1); + D2 = _mm_or_ps(D2,R2); + M.r[0] = D0; + M.r[1] = D1; + M.r[2] = D2; + M.r[3] = g_XMIdentityR3; + M = XMMatrixTranspose(M); + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixLookToRH +( + FXMVECTOR EyePosition, + FXMVECTOR EyeDirection, + FXMVECTOR UpDirection +) +{ + XMVECTOR NegEyeDirection; + XMMATRIX M; + + NegEyeDirection = XMVectorNegate(EyeDirection); + M = XMMatrixLookToLH(EyePosition, NegEyeDirection, UpDirection); + + return M; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixPerspectiveLH +( + FLOAT ViewWidth, + FLOAT ViewHeight, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT TwoNearZ, fRange; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + TwoNearZ = NearZ + NearZ; + fRange = FarZ / (FarZ - NearZ); + M.m[0][0] = TwoNearZ / ViewWidth; + M.m[0][1] = 0.0f; + M.m[0][2] = 0.0f; + M.m[0][3] = 0.0f; + + M.m[1][0] = 0.0f; + M.m[1][1] = TwoNearZ / ViewHeight; + M.m[1][2] = 0.0f; + M.m[1][3] = 0.0f; + + M.m[2][0] = 0.0f; + M.m[2][1] = 0.0f; + M.m[2][2] = fRange; + M.m[2][3] = 1.0f; + + M.m[3][0] = 0.0f; + M.m[3][1] = 0.0f; + M.m[3][2] = -fRange * NearZ; + M.m[3][3] = 0.0f; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + XMMATRIX M; + FLOAT TwoNearZ = NearZ + NearZ; + FLOAT fRange = FarZ / (FarZ - NearZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + TwoNearZ / ViewWidth, + TwoNearZ / ViewHeight, + fRange, + -fRange * NearZ + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // TwoNearZ / ViewWidth,0,0,0 + M.r[0] = vTemp; + // 0,TwoNearZ / ViewHeight,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // x=fRange,y=-fRange * NearZ,0,1.0f + vValues = _mm_shuffle_ps(vValues,g_XMIdentityR3,_MM_SHUFFLE(3,2,3,2)); + // 0,0,fRange,1.0f + vTemp = _mm_setzero_ps(); + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(3,0,0,0)); + M.r[2] = vTemp; + // 0,0,-fRange * NearZ,0 + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(2,1,0,0)); + M.r[3] = vTemp; + + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixPerspectiveRH +( + FLOAT ViewWidth, + FLOAT ViewHeight, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT TwoNearZ, fRange; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + TwoNearZ = NearZ + NearZ; + fRange = FarZ / (NearZ - FarZ); + M.m[0][0] = TwoNearZ / ViewWidth; + M.m[0][1] = 0.0f; + M.m[0][2] = 0.0f; + M.m[0][3] = 0.0f; + + M.m[1][0] = 0.0f; + M.m[1][1] = TwoNearZ / ViewHeight; + M.m[1][2] = 0.0f; + M.m[1][3] = 0.0f; + + M.m[2][0] = 0.0f; + M.m[2][1] = 0.0f; + M.m[2][2] = fRange; + M.m[2][3] = -1.0f; + + M.m[3][0] = 0.0f; + M.m[3][1] = 0.0f; + M.m[3][2] = fRange * NearZ; + M.m[3][3] = 0.0f; + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + XMMATRIX M; + FLOAT TwoNearZ = NearZ + NearZ; + FLOAT fRange = FarZ / (NearZ-FarZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + TwoNearZ / ViewWidth, + TwoNearZ / ViewHeight, + fRange, + fRange * NearZ + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // TwoNearZ / ViewWidth,0,0,0 + M.r[0] = vTemp; + // 0,TwoNearZ / ViewHeight,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // x=fRange,y=-fRange * NearZ,0,-1.0f + vValues = _mm_shuffle_ps(vValues,g_XMNegIdentityR3,_MM_SHUFFLE(3,2,3,2)); + // 0,0,fRange,-1.0f + vTemp = _mm_setzero_ps(); + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(3,0,0,0)); + M.r[2] = vTemp; + // 0,0,-fRange * NearZ,0 + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(2,1,0,0)); + M.r[3] = vTemp; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixPerspectiveFovLH +( + FLOAT FovAngleY, + FLOAT AspectRatio, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT SinFov; + FLOAT CosFov; + FLOAT Height; + FLOAT Width; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f)); + XMASSERT(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + XMScalarSinCos(&SinFov, &CosFov, 0.5f * FovAngleY); + + Height = CosFov / SinFov; + Width = Height / AspectRatio; + + M.r[0] = XMVectorSet(Width, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, Height, 0.0f, 0.0f); + M.r[2] = XMVectorSet(0.0f, 0.0f, FarZ / (FarZ - NearZ), 1.0f); + M.r[3] = XMVectorSet(0.0f, 0.0f, -M.r[2].vector4_f32[2] * NearZ, 0.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f)); + XMASSERT(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + XMMATRIX M; + FLOAT SinFov; + FLOAT CosFov; + XMScalarSinCos(&SinFov, &CosFov, 0.5f * FovAngleY); + FLOAT fRange = FarZ / (FarZ-NearZ); + // Note: This is recorded on the stack + FLOAT Height = CosFov / SinFov; + XMVECTOR rMem = { + Height / AspectRatio, + Height, + fRange, + -fRange * NearZ + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // CosFov / SinFov,0,0,0 + M.r[0] = vTemp; + // 0,Height / AspectRatio,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // x=fRange,y=-fRange * NearZ,0,1.0f + vTemp = _mm_setzero_ps(); + vValues = _mm_shuffle_ps(vValues,g_XMIdentityR3,_MM_SHUFFLE(3,2,3,2)); + // 0,0,fRange,1.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(3,0,0,0)); + M.r[2] = vTemp; + // 0,0,-fRange * NearZ,0.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(2,1,0,0)); + M.r[3] = vTemp; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixPerspectiveFovRH +( + FLOAT FovAngleY, + FLOAT AspectRatio, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT SinFov; + FLOAT CosFov; + FLOAT Height; + FLOAT Width; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f)); + XMASSERT(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + XMScalarSinCos(&SinFov, &CosFov, 0.5f * FovAngleY); + + Height = CosFov / SinFov; + Width = Height / AspectRatio; + + M.r[0] = XMVectorSet(Width, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, Height, 0.0f, 0.0f); + M.r[2] = XMVectorSet(0.0f, 0.0f, FarZ / (NearZ - FarZ), -1.0f); + M.r[3] = XMVectorSet(0.0f, 0.0f, M.r[2].vector4_f32[2] * NearZ, 0.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f)); + XMASSERT(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + XMMATRIX M; + FLOAT SinFov; + FLOAT CosFov; + XMScalarSinCos(&SinFov, &CosFov, 0.5f * FovAngleY); + FLOAT fRange = FarZ / (NearZ-FarZ); + // Note: This is recorded on the stack + FLOAT Height = CosFov / SinFov; + XMVECTOR rMem = { + Height / AspectRatio, + Height, + fRange, + fRange * NearZ + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // CosFov / SinFov,0,0,0 + M.r[0] = vTemp; + // 0,Height / AspectRatio,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // x=fRange,y=-fRange * NearZ,0,-1.0f + vTemp = _mm_setzero_ps(); + vValues = _mm_shuffle_ps(vValues,g_XMNegIdentityR3,_MM_SHUFFLE(3,2,3,2)); + // 0,0,fRange,-1.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(3,0,0,0)); + M.r[2] = vTemp; + // 0,0,fRange * NearZ,0.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(2,1,0,0)); + M.r[3] = vTemp; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixPerspectiveOffCenterLH +( + FLOAT ViewLeft, + FLOAT ViewRight, + FLOAT ViewBottom, + FLOAT ViewTop, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT TwoNearZ; + FLOAT ReciprocalWidth; + FLOAT ReciprocalHeight; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewRight, ViewLeft, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewTop, ViewBottom, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + TwoNearZ = NearZ + NearZ; + ReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + ReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + + M.r[0] = XMVectorSet(TwoNearZ * ReciprocalWidth, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, TwoNearZ * ReciprocalHeight, 0.0f, 0.0f); + M.r[2] = XMVectorSet(-(ViewLeft + ViewRight) * ReciprocalWidth, + -(ViewTop + ViewBottom) * ReciprocalHeight, + FarZ / (FarZ - NearZ), + 1.0f); + M.r[3] = XMVectorSet(0.0f, 0.0f, -M.r[2].vector4_f32[2] * NearZ, 0.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(ViewRight, ViewLeft, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewTop, ViewBottom, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + XMMATRIX M; + FLOAT TwoNearZ = NearZ+NearZ; + FLOAT ReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + FLOAT ReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + FLOAT fRange = FarZ / (FarZ-NearZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + TwoNearZ*ReciprocalWidth, + TwoNearZ*ReciprocalHeight, + -fRange * NearZ, + 0 + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // TwoNearZ*ReciprocalWidth,0,0,0 + M.r[0] = vTemp; + // 0,TwoNearZ*ReciprocalHeight,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // 0,0,fRange,1.0f + M.m[2][0] = -(ViewLeft + ViewRight) * ReciprocalWidth; + M.m[2][1] = -(ViewTop + ViewBottom) * ReciprocalHeight; + M.m[2][2] = fRange; + M.m[2][3] = 1.0f; + // 0,0,-fRange * NearZ,0.0f + vValues = _mm_and_ps(vValues,g_XMMaskZ); + M.r[3] = vValues; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixPerspectiveOffCenterRH +( + FLOAT ViewLeft, + FLOAT ViewRight, + FLOAT ViewBottom, + FLOAT ViewTop, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT TwoNearZ; + FLOAT ReciprocalWidth; + FLOAT ReciprocalHeight; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewRight, ViewLeft, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewTop, ViewBottom, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + TwoNearZ = NearZ + NearZ; + ReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + ReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + + M.r[0] = XMVectorSet(TwoNearZ * ReciprocalWidth, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, TwoNearZ * ReciprocalHeight, 0.0f, 0.0f); + M.r[2] = XMVectorSet((ViewLeft + ViewRight) * ReciprocalWidth, + (ViewTop + ViewBottom) * ReciprocalHeight, + FarZ / (NearZ - FarZ), + -1.0f); + M.r[3] = XMVectorSet(0.0f, 0.0f, M.r[2].vector4_f32[2] * NearZ, 0.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(ViewRight, ViewLeft, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewTop, ViewBottom, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + XMMATRIX M; + FLOAT TwoNearZ = NearZ+NearZ; + FLOAT ReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + FLOAT ReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + FLOAT fRange = FarZ / (NearZ-FarZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + TwoNearZ*ReciprocalWidth, + TwoNearZ*ReciprocalHeight, + fRange * NearZ, + 0 + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // TwoNearZ*ReciprocalWidth,0,0,0 + M.r[0] = vTemp; + // 0,TwoNearZ*ReciprocalHeight,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // 0,0,fRange,1.0f + M.m[2][0] = (ViewLeft + ViewRight) * ReciprocalWidth; + M.m[2][1] = (ViewTop + ViewBottom) * ReciprocalHeight; + M.m[2][2] = fRange; + M.m[2][3] = -1.0f; + // 0,0,-fRange * NearZ,0.0f + vValues = _mm_and_ps(vValues,g_XMMaskZ); + M.r[3] = vValues; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixOrthographicLH +( + FLOAT ViewWidth, + FLOAT ViewHeight, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT fRange; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + fRange = 1.0f / (FarZ-NearZ); + M.r[0] = XMVectorSet(2.0f / ViewWidth, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, 2.0f / ViewHeight, 0.0f, 0.0f); + M.r[2] = XMVectorSet(0.0f, 0.0f, fRange, 0.0f); + M.r[3] = XMVectorSet(0.0f, 0.0f, -fRange * NearZ, 1.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + XMMATRIX M; + FLOAT fRange = 1.0f / (FarZ-NearZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + 2.0f / ViewWidth, + 2.0f / ViewHeight, + fRange, + -fRange * NearZ + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // 2.0f / ViewWidth,0,0,0 + M.r[0] = vTemp; + // 0,2.0f / ViewHeight,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // x=fRange,y=-fRange * NearZ,0,1.0f + vTemp = _mm_setzero_ps(); + vValues = _mm_shuffle_ps(vValues,g_XMIdentityR3,_MM_SHUFFLE(3,2,3,2)); + // 0,0,fRange,0.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(2,0,0,0)); + M.r[2] = vTemp; + // 0,0,-fRange * NearZ,1.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(3,1,0,0)); + M.r[3] = vTemp; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixOrthographicRH +( + FLOAT ViewWidth, + FLOAT ViewHeight, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + M.r[0] = XMVectorSet(2.0f / ViewWidth, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, 2.0f / ViewHeight, 0.0f, 0.0f); + M.r[2] = XMVectorSet(0.0f, 0.0f, 1.0f / (NearZ - FarZ), 0.0f); + M.r[3] = XMVectorSet(0.0f, 0.0f, M.r[2].vector4_f32[2] * NearZ, 1.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(!XMScalarNearEqual(ViewWidth, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewHeight, 0.0f, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + XMMATRIX M; + FLOAT fRange = 1.0f / (NearZ-FarZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + 2.0f / ViewWidth, + 2.0f / ViewHeight, + fRange, + fRange * NearZ + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // 2.0f / ViewWidth,0,0,0 + M.r[0] = vTemp; + // 0,2.0f / ViewHeight,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + M.r[1] = vTemp; + // x=fRange,y=fRange * NearZ,0,1.0f + vTemp = _mm_setzero_ps(); + vValues = _mm_shuffle_ps(vValues,g_XMIdentityR3,_MM_SHUFFLE(3,2,3,2)); + // 0,0,fRange,0.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(2,0,0,0)); + M.r[2] = vTemp; + // 0,0,fRange * NearZ,1.0f + vTemp = _mm_shuffle_ps(vTemp,vValues,_MM_SHUFFLE(3,1,0,0)); + M.r[3] = vTemp; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixOrthographicOffCenterLH +( + FLOAT ViewLeft, + FLOAT ViewRight, + FLOAT ViewBottom, + FLOAT ViewTop, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT ReciprocalWidth; + FLOAT ReciprocalHeight; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewRight, ViewLeft, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewTop, ViewBottom, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + ReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + ReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + + M.r[0] = XMVectorSet(ReciprocalWidth + ReciprocalWidth, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, ReciprocalHeight + ReciprocalHeight, 0.0f, 0.0f); + M.r[2] = XMVectorSet(0.0f, 0.0f, 1.0f / (FarZ - NearZ), 0.0f); + M.r[3] = XMVectorSet(-(ViewLeft + ViewRight) * ReciprocalWidth, + -(ViewTop + ViewBottom) * ReciprocalHeight, + -M.r[2].vector4_f32[2] * NearZ, + 1.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + FLOAT fReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + FLOAT fReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + FLOAT fRange = 1.0f / (FarZ-NearZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + fReciprocalWidth, + fReciprocalHeight, + fRange, + 1.0f + }; + XMVECTOR rMem2 = { + -(ViewLeft + ViewRight), + -(ViewTop + ViewBottom), + -NearZ, + 1.0f + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // fReciprocalWidth*2,0,0,0 + vTemp = _mm_add_ss(vTemp,vTemp); + M.r[0] = vTemp; + // 0,fReciprocalHeight*2,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + vTemp = _mm_add_ps(vTemp,vTemp); + M.r[1] = vTemp; + // 0,0,fRange,0.0f + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskZ); + M.r[2] = vTemp; + // -(ViewLeft + ViewRight)*fReciprocalWidth,-(ViewTop + ViewBottom)*fReciprocalHeight,fRange*-NearZ,1.0f + vValues = _mm_mul_ps(vValues,rMem2); + M.r[3] = vValues; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMMATRIX XMMatrixOrthographicOffCenterRH +( + FLOAT ViewLeft, + FLOAT ViewRight, + FLOAT ViewBottom, + FLOAT ViewTop, + FLOAT NearZ, + FLOAT FarZ +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT ReciprocalWidth; + FLOAT ReciprocalHeight; + XMMATRIX M; + + XMASSERT(!XMScalarNearEqual(ViewRight, ViewLeft, 0.00001f)); + XMASSERT(!XMScalarNearEqual(ViewTop, ViewBottom, 0.00001f)); + XMASSERT(!XMScalarNearEqual(FarZ, NearZ, 0.00001f)); + + ReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + ReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + + M.r[0] = XMVectorSet(ReciprocalWidth + ReciprocalWidth, 0.0f, 0.0f, 0.0f); + M.r[1] = XMVectorSet(0.0f, ReciprocalHeight + ReciprocalHeight, 0.0f, 0.0f); + M.r[2] = XMVectorSet(0.0f, 0.0f, 1.0f / (NearZ - FarZ), 0.0f); + M.r[3] = XMVectorSet(-(ViewLeft + ViewRight) * ReciprocalWidth, + -(ViewTop + ViewBottom) * ReciprocalHeight, + M.r[2].vector4_f32[2] * NearZ, + 1.0f); + + return M; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX M; + FLOAT fReciprocalWidth = 1.0f / (ViewRight - ViewLeft); + FLOAT fReciprocalHeight = 1.0f / (ViewTop - ViewBottom); + FLOAT fRange = 1.0f / (NearZ-FarZ); + // Note: This is recorded on the stack + XMVECTOR rMem = { + fReciprocalWidth, + fReciprocalHeight, + fRange, + 1.0f + }; + XMVECTOR rMem2 = { + -(ViewLeft + ViewRight), + -(ViewTop + ViewBottom), + NearZ, + 1.0f + }; + // Copy from memory to SSE register + XMVECTOR vValues = rMem; + XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp,vValues); + // fReciprocalWidth*2,0,0,0 + vTemp = _mm_add_ss(vTemp,vTemp); + M.r[0] = vTemp; + // 0,fReciprocalHeight*2,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskY); + vTemp = _mm_add_ps(vTemp,vTemp); + M.r[1] = vTemp; + // 0,0,fRange,0.0f + vTemp = vValues; + vTemp = _mm_and_ps(vTemp,g_XMMaskZ); + M.r[2] = vTemp; + // -(ViewLeft + ViewRight)*fReciprocalWidth,-(ViewTop + ViewBottom)*fReciprocalHeight,fRange*-NearZ,1.0f + vValues = _mm_mul_ps(vValues,rMem2); + M.r[3] = vValues; + return M; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +#ifdef __cplusplus + +/**************************************************************************** + * + * XMMATRIX operators and methods + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMMATRIX::_XMMATRIX +( + FXMVECTOR R0, + FXMVECTOR R1, + FXMVECTOR R2, + CXMVECTOR R3 +) +{ + r[0] = R0; + r[1] = R1; + r[2] = R2; + r[3] = R3; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMMATRIX::_XMMATRIX +( + FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03, + FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13, + FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23, + FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33 +) +{ + r[0] = XMVectorSet(m00, m01, m02, m03); + r[1] = XMVectorSet(m10, m11, m12, m13); + r[2] = XMVectorSet(m20, m21, m22, m23); + r[3] = XMVectorSet(m30, m31, m32, m33); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMMATRIX::_XMMATRIX +( + CONST FLOAT* pArray +) +{ + r[0] = XMLoadFloat4((XMFLOAT4*)pArray); + r[1] = XMLoadFloat4((XMFLOAT4*)(pArray + 4)); + r[2] = XMLoadFloat4((XMFLOAT4*)(pArray + 8)); + r[3] = XMLoadFloat4((XMFLOAT4*)(pArray + 12)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMMATRIX& _XMMATRIX::operator= +( + CONST _XMMATRIX& M +) +{ + r[0] = M.r[0]; + r[1] = M.r[1]; + r[2] = M.r[2]; + r[3] = M.r[3]; + return *this; +} + +//------------------------------------------------------------------------------ + +#ifndef XM_NO_OPERATOR_OVERLOADS + +#if !defined(_XBOX_VER) && defined(_XM_ISVS2005_) && defined(_XM_X64_) +#pragma warning(push) +#pragma warning(disable : 4328) +#endif + +XMFINLINE _XMMATRIX& _XMMATRIX::operator*= +( + CONST _XMMATRIX& M +) +{ + *this = XMMatrixMultiply(*this, M); + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMMATRIX _XMMATRIX::operator* +( + CONST _XMMATRIX& M +) CONST +{ + return XMMatrixMultiply(*this, M); +} + +#if !defined(_XBOX_VER) && defined(_XM_ISVS2005_) && defined(_XM_X64_) +#pragma warning(pop) +#endif + +#endif // !XM_NO_OPERATOR_OVERLOADS + +/**************************************************************************** + * + * XMFLOAT3X3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT3X3::_XMFLOAT3X3 +( + FLOAT m00, FLOAT m01, FLOAT m02, + FLOAT m10, FLOAT m11, FLOAT m12, + FLOAT m20, FLOAT m21, FLOAT m22 +) +{ + m[0][0] = m00; + m[0][1] = m01; + m[0][2] = m02; + + m[1][0] = m10; + m[1][1] = m11; + m[1][2] = m12; + + m[2][0] = m20; + m[2][1] = m21; + m[2][2] = m22; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT3X3::_XMFLOAT3X3 +( + CONST FLOAT* pArray +) +{ + UINT Row; + UINT Column; + + for (Row = 0; Row < 3; Row++) + { + for (Column = 0; Column < 3; Column++) + { + m[Row][Column] = pArray[Row * 3 + Column]; + } + } +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT3X3& _XMFLOAT3X3::operator= +( + CONST _XMFLOAT3X3& Float3x3 +) +{ + _11 = Float3x3._11; + _12 = Float3x3._12; + _13 = Float3x3._13; + _21 = Float3x3._21; + _22 = Float3x3._22; + _23 = Float3x3._23; + _31 = Float3x3._31; + _32 = Float3x3._32; + _33 = Float3x3._33; + + return *this; +} + +/**************************************************************************** + * + * XMFLOAT4X3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4X3::_XMFLOAT4X3 +( + FLOAT m00, FLOAT m01, FLOAT m02, + FLOAT m10, FLOAT m11, FLOAT m12, + FLOAT m20, FLOAT m21, FLOAT m22, + FLOAT m30, FLOAT m31, FLOAT m32 +) +{ + m[0][0] = m00; + m[0][1] = m01; + m[0][2] = m02; + + m[1][0] = m10; + m[1][1] = m11; + m[1][2] = m12; + + m[2][0] = m20; + m[2][1] = m21; + m[2][2] = m22; + + m[3][0] = m30; + m[3][1] = m31; + m[3][2] = m32; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4X3::_XMFLOAT4X3 +( + CONST FLOAT* pArray +) +{ + UINT Row; + UINT Column; + + for (Row = 0; Row < 4; Row++) + { + for (Column = 0; Column < 3; Column++) + { + m[Row][Column] = pArray[Row * 3 + Column]; + } + } +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4X3& _XMFLOAT4X3::operator= +( + CONST _XMFLOAT4X3& Float4x3 +) +{ + XMVECTOR V1 = XMLoadFloat4((XMFLOAT4*)&Float4x3._11); + XMVECTOR V2 = XMLoadFloat4((XMFLOAT4*)&Float4x3._22); + XMVECTOR V3 = XMLoadFloat4((XMFLOAT4*)&Float4x3._33); + + XMStoreFloat4((XMFLOAT4*)&_11, V1); + XMStoreFloat4((XMFLOAT4*)&_22, V2); + XMStoreFloat4((XMFLOAT4*)&_33, V3); + + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMFLOAT4X3A& XMFLOAT4X3A::operator= +( + CONST XMFLOAT4X3A& Float4x3 +) +{ + XMVECTOR V1 = XMLoadFloat4A((XMFLOAT4A*)&Float4x3._11); + XMVECTOR V2 = XMLoadFloat4A((XMFLOAT4A*)&Float4x3._22); + XMVECTOR V3 = XMLoadFloat4A((XMFLOAT4A*)&Float4x3._33); + + XMStoreFloat4A((XMFLOAT4A*)&_11, V1); + XMStoreFloat4A((XMFLOAT4A*)&_22, V2); + XMStoreFloat4A((XMFLOAT4A*)&_33, V3); + + return *this; +} + +/**************************************************************************** + * + * XMFLOAT4X4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4X4::_XMFLOAT4X4 +( + FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03, + FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13, + FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23, + FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33 +) +{ + m[0][0] = m00; + m[0][1] = m01; + m[0][2] = m02; + m[0][3] = m03; + + m[1][0] = m10; + m[1][1] = m11; + m[1][2] = m12; + m[1][3] = m13; + + m[2][0] = m20; + m[2][1] = m21; + m[2][2] = m22; + m[2][3] = m23; + + m[3][0] = m30; + m[3][1] = m31; + m[3][2] = m32; + m[3][3] = m33; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4X4::_XMFLOAT4X4 +( + CONST FLOAT* pArray +) +{ + UINT Row; + UINT Column; + + for (Row = 0; Row < 4; Row++) + { + for (Column = 0; Column < 4; Column++) + { + m[Row][Column] = pArray[Row * 4 + Column]; + } + } +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4X4& _XMFLOAT4X4::operator= +( + CONST _XMFLOAT4X4& Float4x4 +) +{ + XMVECTOR V1 = XMLoadFloat4((XMFLOAT4*)&Float4x4._11); + XMVECTOR V2 = XMLoadFloat4((XMFLOAT4*)&Float4x4._21); + XMVECTOR V3 = XMLoadFloat4((XMFLOAT4*)&Float4x4._31); + XMVECTOR V4 = XMLoadFloat4((XMFLOAT4*)&Float4x4._41); + + XMStoreFloat4((XMFLOAT4*)&_11, V1); + XMStoreFloat4((XMFLOAT4*)&_21, V2); + XMStoreFloat4((XMFLOAT4*)&_31, V3); + XMStoreFloat4((XMFLOAT4*)&_41, V4); + + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMFLOAT4X4A& XMFLOAT4X4A::operator= +( + CONST XMFLOAT4X4A& Float4x4 +) +{ + XMVECTOR V1 = XMLoadFloat4A((XMFLOAT4A*)&Float4x4._11); + XMVECTOR V2 = XMLoadFloat4A((XMFLOAT4A*)&Float4x4._21); + XMVECTOR V3 = XMLoadFloat4A((XMFLOAT4A*)&Float4x4._31); + XMVECTOR V4 = XMLoadFloat4A((XMFLOAT4A*)&Float4x4._41); + + XMStoreFloat4A((XMFLOAT4A*)&_11, V1); + XMStoreFloat4A((XMFLOAT4A*)&_21, V2); + XMStoreFloat4A((XMFLOAT4A*)&_31, V3); + XMStoreFloat4A((XMFLOAT4A*)&_41, V4); + + return *this; +} + +#endif // __cplusplus + +#endif // __XNAMATHMATRIX_INL__ + diff --git a/dxsdk/Include/xnamathmisc.inl b/dxsdk/Include/xnamathmisc.inl new file mode 100644 index 0000000..c937ee1 --- /dev/null +++ b/dxsdk/Include/xnamathmisc.inl @@ -0,0 +1,2464 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + xnamathmisc.inl + +Abstract: + + XNA math library for Windows and Xbox 360: Quaternion, plane, and color functions. +--*/ + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __XNAMATHMISC_INL__ +#define __XNAMATHMISC_INL__ + +/**************************************************************************** + * + * Quaternion + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMQuaternionEqual +( + FXMVECTOR Q1, + FXMVECTOR Q2 +) +{ + return XMVector4Equal(Q1, Q2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMQuaternionNotEqual +( + FXMVECTOR Q1, + FXMVECTOR Q2 +) +{ + return XMVector4NotEqual(Q1, Q2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMQuaternionIsNaN +( + FXMVECTOR Q +) +{ + return XMVector4IsNaN(Q); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMQuaternionIsInfinite +( + FXMVECTOR Q +) +{ + return XMVector4IsInfinite(Q); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMQuaternionIsIdentity +( + FXMVECTOR Q +) +{ +#if defined(_XM_NO_INTRINSICS_) + + return XMVector4Equal(Q, g_XMIdentityR3.v); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(Q,g_XMIdentityR3); + return (_mm_movemask_ps(vTemp)==0x0f) ? true : false; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionDot +( + FXMVECTOR Q1, + FXMVECTOR Q2 +) +{ + return XMVector4Dot(Q1, Q2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionMultiply +( + FXMVECTOR Q1, + FXMVECTOR Q2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR NegativeQ1; + XMVECTOR Q2X; + XMVECTOR Q2Y; + XMVECTOR Q2Z; + XMVECTOR Q2W; + XMVECTOR Q1WZYX; + XMVECTOR Q1ZWXY; + XMVECTOR Q1YXWZ; + XMVECTOR Result; + CONST XMVECTORU32 ControlWZYX = {XM_PERMUTE_0W, XM_PERMUTE_1Z, XM_PERMUTE_0Y, XM_PERMUTE_1X}; + CONST XMVECTORU32 ControlZWXY = {XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_1X, XM_PERMUTE_1Y}; + CONST XMVECTORU32 ControlYXWZ = {XM_PERMUTE_1Y, XM_PERMUTE_0X, XM_PERMUTE_0W, XM_PERMUTE_1Z}; + + NegativeQ1 = XMVectorNegate(Q1); + + Q2W = XMVectorSplatW(Q2); + Q2X = XMVectorSplatX(Q2); + Q2Y = XMVectorSplatY(Q2); + Q2Z = XMVectorSplatZ(Q2); + + Q1WZYX = XMVectorPermute(Q1, NegativeQ1, ControlWZYX.v); + Q1ZWXY = XMVectorPermute(Q1, NegativeQ1, ControlZWXY.v); + Q1YXWZ = XMVectorPermute(Q1, NegativeQ1, ControlYXWZ.v); + + Result = XMVectorMultiply(Q1, Q2W); + Result = XMVectorMultiplyAdd(Q1WZYX, Q2X, Result); + Result = XMVectorMultiplyAdd(Q1ZWXY, Q2Y, Result); + Result = XMVectorMultiplyAdd(Q1YXWZ, Q2Z, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 ControlWZYX = { 1.0f,-1.0f, 1.0f,-1.0f}; + static CONST XMVECTORF32 ControlZWXY = { 1.0f, 1.0f,-1.0f,-1.0f}; + static CONST XMVECTORF32 ControlYXWZ = {-1.0f, 1.0f, 1.0f,-1.0f}; + // Copy to SSE registers and use as few as possible for x86 + XMVECTOR Q2X = Q2; + XMVECTOR Q2Y = Q2; + XMVECTOR Q2Z = Q2; + XMVECTOR vResult = Q2; + // Splat with one instruction + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,3,3,3)); + Q2X = _mm_shuffle_ps(Q2X,Q2X,_MM_SHUFFLE(0,0,0,0)); + Q2Y = _mm_shuffle_ps(Q2Y,Q2Y,_MM_SHUFFLE(1,1,1,1)); + Q2Z = _mm_shuffle_ps(Q2Z,Q2Z,_MM_SHUFFLE(2,2,2,2)); + // Retire Q1 and perform Q1*Q2W + vResult = _mm_mul_ps(vResult,Q1); + XMVECTOR Q1Shuffle = Q1; + // Shuffle the copies of Q1 + Q1Shuffle = _mm_shuffle_ps(Q1Shuffle,Q1Shuffle,_MM_SHUFFLE(0,1,2,3)); + // Mul by Q1WZYX + Q2X = _mm_mul_ps(Q2X,Q1Shuffle); + Q1Shuffle = _mm_shuffle_ps(Q1Shuffle,Q1Shuffle,_MM_SHUFFLE(2,3,0,1)); + // Flip the signs on y and z + Q2X = _mm_mul_ps(Q2X,ControlWZYX); + // Mul by Q1ZWXY + Q2Y = _mm_mul_ps(Q2Y,Q1Shuffle); + Q1Shuffle = _mm_shuffle_ps(Q1Shuffle,Q1Shuffle,_MM_SHUFFLE(0,1,2,3)); + // Flip the signs on z and w + Q2Y = _mm_mul_ps(Q2Y,ControlZWXY); + // Mul by Q1YXWZ + Q2Z = _mm_mul_ps(Q2Z,Q1Shuffle); + vResult = _mm_add_ps(vResult,Q2X); + // Flip the signs on x and w + Q2Z = _mm_mul_ps(Q2Z,ControlYXWZ); + Q2Y = _mm_add_ps(Q2Y,Q2Z); + vResult = _mm_add_ps(vResult,Q2Y); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionLengthSq +( + FXMVECTOR Q +) +{ + return XMVector4LengthSq(Q); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionReciprocalLength +( + FXMVECTOR Q +) +{ + return XMVector4ReciprocalLength(Q); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionLength +( + FXMVECTOR Q +) +{ + return XMVector4Length(Q); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionNormalizeEst +( + FXMVECTOR Q +) +{ + return XMVector4NormalizeEst(Q); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionNormalize +( + FXMVECTOR Q +) +{ + return XMVector4Normalize(Q); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionConjugate +( + FXMVECTOR Q +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result = { + -Q.vector4_f32[0], + -Q.vector4_f32[1], + -Q.vector4_f32[2], + Q.vector4_f32[3] + }; + return Result; +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 NegativeOne3 = {-1.0f,-1.0f,-1.0f,1.0f}; + XMVECTOR Result = _mm_mul_ps(Q,NegativeOne3); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionInverse +( + FXMVECTOR Q +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Conjugate; + XMVECTOR L; + XMVECTOR Control; + XMVECTOR Result; + CONST XMVECTOR Zero = XMVectorZero(); + + L = XMVector4LengthSq(Q); + Conjugate = XMQuaternionConjugate(Q); + + Control = XMVectorLessOrEqual(L, g_XMEpsilon.v); + + L = XMVectorReciprocal(L); + Result = XMVectorMultiply(Conjugate, L); + + Result = XMVectorSelect(Result, Zero, Control); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Conjugate; + XMVECTOR L; + XMVECTOR Control; + XMVECTOR Result; + XMVECTOR Zero = XMVectorZero(); + + L = XMVector4LengthSq(Q); + Conjugate = XMQuaternionConjugate(Q); + Control = XMVectorLessOrEqual(L, g_XMEpsilon); + Result = _mm_div_ps(Conjugate,L); + Result = XMVectorSelect(Result, Zero, Control); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionLn +( + FXMVECTOR Q +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Q0; + XMVECTOR QW; + XMVECTOR Theta; + XMVECTOR SinTheta; + XMVECTOR S; + XMVECTOR ControlW; + XMVECTOR Result; + static CONST XMVECTOR OneMinusEpsilon = {1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f}; + + QW = XMVectorSplatW(Q); + Q0 = XMVectorSelect(g_XMSelect1110.v, Q, g_XMSelect1110.v); + + ControlW = XMVectorInBounds(QW, OneMinusEpsilon); + + Theta = XMVectorACos(QW); + SinTheta = XMVectorSin(Theta); + + S = XMVectorReciprocal(SinTheta); + S = XMVectorMultiply(Theta, S); + + Result = XMVectorMultiply(Q0, S); + + Result = XMVectorSelect(Q0, Result, ControlW); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 OneMinusEpsilon = {1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f}; + static CONST XMVECTORF32 NegOneMinusEpsilon = {-(1.0f - 0.00001f), -(1.0f - 0.00001f),-(1.0f - 0.00001f),-(1.0f - 0.00001f)}; + // Get W only + XMVECTOR QW = _mm_shuffle_ps(Q,Q,_MM_SHUFFLE(3,3,3,3)); + // W = 0 + XMVECTOR Q0 = _mm_and_ps(Q,g_XMMask3); + // Use W if within bounds + XMVECTOR ControlW = _mm_cmple_ps(QW,OneMinusEpsilon); + XMVECTOR vTemp2 = _mm_cmpge_ps(QW,NegOneMinusEpsilon); + ControlW = _mm_and_ps(ControlW,vTemp2); + // Get theta + XMVECTOR vTheta = XMVectorACos(QW); + // Get Sine of theta + vTemp2 = XMVectorSin(vTheta); + // theta/sine of theta + vTheta = _mm_div_ps(vTheta,vTemp2); + // Here's the answer + vTheta = _mm_mul_ps(vTheta,Q0); + // Was W in bounds? If not, return input as is + vTheta = XMVectorSelect(Q0,vTheta,ControlW); + return vTheta; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionExp +( + FXMVECTOR Q +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Theta; + XMVECTOR SinTheta; + XMVECTOR CosTheta; + XMVECTOR S; + XMVECTOR Control; + XMVECTOR Zero; + XMVECTOR Result; + + Theta = XMVector3Length(Q); + XMVectorSinCos(&SinTheta, &CosTheta, Theta); + + S = XMVectorReciprocal(Theta); + S = XMVectorMultiply(SinTheta, S); + + Result = XMVectorMultiply(Q, S); + + Zero = XMVectorZero(); + Control = XMVectorNearEqual(Theta, Zero, g_XMEpsilon.v); + Result = XMVectorSelect(Result, Q, Control); + + Result = XMVectorSelect(CosTheta, Result, g_XMSelect1110.v); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Theta; + XMVECTOR SinTheta; + XMVECTOR CosTheta; + XMVECTOR S; + XMVECTOR Control; + XMVECTOR Zero; + XMVECTOR Result; + Theta = XMVector3Length(Q); + XMVectorSinCos(&SinTheta, &CosTheta, Theta); + S = _mm_div_ps(SinTheta,Theta); + Result = _mm_mul_ps(Q, S); + Zero = XMVectorZero(); + Control = XMVectorNearEqual(Theta, Zero, g_XMEpsilon); + Result = XMVectorSelect(Result,Q,Control); + Result = _mm_and_ps(Result,g_XMMask3); + CosTheta = _mm_and_ps(CosTheta,g_XMMaskW); + Result = _mm_or_ps(Result,CosTheta); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMQuaternionSlerp +( + FXMVECTOR Q0, + FXMVECTOR Q1, + FLOAT t +) +{ + XMVECTOR T = XMVectorReplicate(t); + return XMQuaternionSlerpV(Q0, Q1, T); +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMQuaternionSlerpV +( + FXMVECTOR Q0, + FXMVECTOR Q1, + FXMVECTOR T +) +{ +#if defined(_XM_NO_INTRINSICS_) + + // Result = Q0 * sin((1.0 - t) * Omega) / sin(Omega) + Q1 * sin(t * Omega) / sin(Omega) + XMVECTOR Omega; + XMVECTOR CosOmega; + XMVECTOR SinOmega; + XMVECTOR InvSinOmega; + XMVECTOR V01; + XMVECTOR C1000; + XMVECTOR SignMask; + XMVECTOR S0; + XMVECTOR S1; + XMVECTOR Sign; + XMVECTOR Control; + XMVECTOR Result; + XMVECTOR Zero; + CONST XMVECTOR OneMinusEpsilon = {1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f}; + + XMASSERT((T.vector4_f32[1] == T.vector4_f32[0]) && (T.vector4_f32[2] == T.vector4_f32[0]) && (T.vector4_f32[3] == T.vector4_f32[0])); + + CosOmega = XMQuaternionDot(Q0, Q1); + + Zero = XMVectorZero(); + Control = XMVectorLess(CosOmega, Zero); + Sign = XMVectorSelect(g_XMOne.v, g_XMNegativeOne.v, Control); + + CosOmega = XMVectorMultiply(CosOmega, Sign); + + Control = XMVectorLess(CosOmega, OneMinusEpsilon); + + SinOmega = XMVectorNegativeMultiplySubtract(CosOmega, CosOmega, g_XMOne.v); + SinOmega = XMVectorSqrt(SinOmega); + + Omega = XMVectorATan2(SinOmega, CosOmega); + + SignMask = XMVectorSplatSignMask(); + C1000 = XMVectorSetBinaryConstant(1, 0, 0, 0); + V01 = XMVectorShiftLeft(T, Zero, 2); + SignMask = XMVectorShiftLeft(SignMask, Zero, 3); + V01 = XMVectorXorInt(V01, SignMask); + V01 = XMVectorAdd(C1000, V01); + + InvSinOmega = XMVectorReciprocal(SinOmega); + + S0 = XMVectorMultiply(V01, Omega); + S0 = XMVectorSin(S0); + S0 = XMVectorMultiply(S0, InvSinOmega); + + S0 = XMVectorSelect(V01, S0, Control); + + S1 = XMVectorSplatY(S0); + S0 = XMVectorSplatX(S0); + + S1 = XMVectorMultiply(S1, Sign); + + Result = XMVectorMultiply(Q0, S0); + Result = XMVectorMultiplyAdd(Q1, S1, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Result = Q0 * sin((1.0 - t) * Omega) / sin(Omega) + Q1 * sin(t * Omega) / sin(Omega) + XMVECTOR Omega; + XMVECTOR CosOmega; + XMVECTOR SinOmega; + XMVECTOR V01; + XMVECTOR S0; + XMVECTOR S1; + XMVECTOR Sign; + XMVECTOR Control; + XMVECTOR Result; + XMVECTOR Zero; + static const XMVECTORF32 OneMinusEpsilon = {1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f}; + static const XMVECTORI32 SignMask2 = {0x80000000,0x00000000,0x00000000,0x00000000}; + static const XMVECTORI32 MaskXY = {0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000}; + + XMASSERT((XMVectorGetY(T) == XMVectorGetX(T)) && (XMVectorGetZ(T) == XMVectorGetX(T)) && (XMVectorGetW(T) == XMVectorGetX(T))); + + CosOmega = XMQuaternionDot(Q0, Q1); + + Zero = XMVectorZero(); + Control = XMVectorLess(CosOmega, Zero); + Sign = XMVectorSelect(g_XMOne, g_XMNegativeOne, Control); + + CosOmega = _mm_mul_ps(CosOmega, Sign); + + Control = XMVectorLess(CosOmega, OneMinusEpsilon); + + SinOmega = _mm_mul_ps(CosOmega,CosOmega); + SinOmega = _mm_sub_ps(g_XMOne,SinOmega); + SinOmega = _mm_sqrt_ps(SinOmega); + + Omega = XMVectorATan2(SinOmega, CosOmega); + + V01 = _mm_shuffle_ps(T,T,_MM_SHUFFLE(2,3,0,1)); + V01 = _mm_and_ps(V01,MaskXY); + V01 = _mm_xor_ps(V01,SignMask2); + V01 = _mm_add_ps(g_XMIdentityR0, V01); + + S0 = _mm_mul_ps(V01, Omega); + S0 = XMVectorSin(S0); + S0 = _mm_div_ps(S0, SinOmega); + + S0 = XMVectorSelect(V01, S0, Control); + + S1 = XMVectorSplatY(S0); + S0 = XMVectorSplatX(S0); + + S1 = _mm_mul_ps(S1, Sign); + Result = _mm_mul_ps(Q0, S0); + S1 = _mm_mul_ps(S1, Q1); + Result = _mm_add_ps(Result,S1); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionSquad +( + FXMVECTOR Q0, + FXMVECTOR Q1, + FXMVECTOR Q2, + CXMVECTOR Q3, + FLOAT t +) +{ + XMVECTOR T = XMVectorReplicate(t); + return XMQuaternionSquadV(Q0, Q1, Q2, Q3, T); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionSquadV +( + FXMVECTOR Q0, + FXMVECTOR Q1, + FXMVECTOR Q2, + CXMVECTOR Q3, + CXMVECTOR T +) +{ + XMVECTOR Q03; + XMVECTOR Q12; + XMVECTOR TP; + XMVECTOR Two; + XMVECTOR Result; + + XMASSERT( (XMVectorGetY(T) == XMVectorGetX(T)) && (XMVectorGetZ(T) == XMVectorGetX(T)) && (XMVectorGetW(T) == XMVectorGetX(T)) ); + + TP = T; + Two = XMVectorSplatConstant(2, 0); + + Q03 = XMQuaternionSlerpV(Q0, Q3, T); + Q12 = XMQuaternionSlerpV(Q1, Q2, T); + + TP = XMVectorNegativeMultiplySubtract(TP, TP, TP); + TP = XMVectorMultiply(TP, Two); + + Result = XMQuaternionSlerpV(Q03, Q12, TP); + + return Result; + +} + +//------------------------------------------------------------------------------ + +XMINLINE VOID XMQuaternionSquadSetup +( + XMVECTOR* pA, + XMVECTOR* pB, + XMVECTOR* pC, + FXMVECTOR Q0, + FXMVECTOR Q1, + FXMVECTOR Q2, + CXMVECTOR Q3 +) +{ + XMVECTOR SQ0, SQ2, SQ3; + XMVECTOR InvQ1, InvQ2; + XMVECTOR LnQ0, LnQ1, LnQ2, LnQ3; + XMVECTOR ExpQ02, ExpQ13; + XMVECTOR LS01, LS12, LS23; + XMVECTOR LD01, LD12, LD23; + XMVECTOR Control0, Control1, Control2; + XMVECTOR NegativeOneQuarter; + + XMASSERT(pA); + XMASSERT(pB); + XMASSERT(pC); + + LS12 = XMQuaternionLengthSq(XMVectorAdd(Q1, Q2)); + LD12 = XMQuaternionLengthSq(XMVectorSubtract(Q1, Q2)); + SQ2 = XMVectorNegate(Q2); + + Control1 = XMVectorLess(LS12, LD12); + SQ2 = XMVectorSelect(Q2, SQ2, Control1); + + LS01 = XMQuaternionLengthSq(XMVectorAdd(Q0, Q1)); + LD01 = XMQuaternionLengthSq(XMVectorSubtract(Q0, Q1)); + SQ0 = XMVectorNegate(Q0); + + LS23 = XMQuaternionLengthSq(XMVectorAdd(SQ2, Q3)); + LD23 = XMQuaternionLengthSq(XMVectorSubtract(SQ2, Q3)); + SQ3 = XMVectorNegate(Q3); + + Control0 = XMVectorLess(LS01, LD01); + Control2 = XMVectorLess(LS23, LD23); + + SQ0 = XMVectorSelect(Q0, SQ0, Control0); + SQ3 = XMVectorSelect(Q3, SQ3, Control2); + + InvQ1 = XMQuaternionInverse(Q1); + InvQ2 = XMQuaternionInverse(SQ2); + + LnQ0 = XMQuaternionLn(XMQuaternionMultiply(InvQ1, SQ0)); + LnQ2 = XMQuaternionLn(XMQuaternionMultiply(InvQ1, SQ2)); + LnQ1 = XMQuaternionLn(XMQuaternionMultiply(InvQ2, Q1)); + LnQ3 = XMQuaternionLn(XMQuaternionMultiply(InvQ2, SQ3)); + + NegativeOneQuarter = XMVectorSplatConstant(-1, 2); + + ExpQ02 = XMVectorMultiply(XMVectorAdd(LnQ0, LnQ2), NegativeOneQuarter); + ExpQ13 = XMVectorMultiply(XMVectorAdd(LnQ1, LnQ3), NegativeOneQuarter); + ExpQ02 = XMQuaternionExp(ExpQ02); + ExpQ13 = XMQuaternionExp(ExpQ13); + + *pA = XMQuaternionMultiply(Q1, ExpQ02); + *pB = XMQuaternionMultiply(SQ2, ExpQ13); + *pC = SQ2; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionBaryCentric +( + FXMVECTOR Q0, + FXMVECTOR Q1, + FXMVECTOR Q2, + FLOAT f, + FLOAT g +) +{ + XMVECTOR Q01; + XMVECTOR Q02; + FLOAT s; + XMVECTOR Result; + + s = f + g; + + if ((s < 0.00001f) && (s > -0.00001f)) + { + Result = Q0; + } + else + { + Q01 = XMQuaternionSlerp(Q0, Q1, s); + Q02 = XMQuaternionSlerp(Q0, Q2, s); + + Result = XMQuaternionSlerp(Q01, Q02, g / s); + } + + return Result; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionBaryCentricV +( + FXMVECTOR Q0, + FXMVECTOR Q1, + FXMVECTOR Q2, + CXMVECTOR F, + CXMVECTOR G +) +{ + XMVECTOR Q01; + XMVECTOR Q02; + XMVECTOR S, GS; + XMVECTOR Epsilon; + XMVECTOR Result; + + XMASSERT( (XMVectorGetY(F) == XMVectorGetX(F)) && (XMVectorGetZ(F) == XMVectorGetX(F)) && (XMVectorGetW(F) == XMVectorGetX(F)) ); + XMASSERT( (XMVectorGetY(G) == XMVectorGetX(G)) && (XMVectorGetZ(G) == XMVectorGetX(G)) && (XMVectorGetW(G) == XMVectorGetX(G)) ); + + Epsilon = XMVectorSplatConstant(1, 16); + + S = XMVectorAdd(F, G); + + if (XMVector4InBounds(S, Epsilon)) + { + Result = Q0; + } + else + { + Q01 = XMQuaternionSlerpV(Q0, Q1, S); + Q02 = XMQuaternionSlerpV(Q0, Q2, S); + GS = XMVectorReciprocal(S); + GS = XMVectorMultiply(G, GS); + + Result = XMQuaternionSlerpV(Q01, Q02, GS); + } + + return Result; +} + +//------------------------------------------------------------------------------ +// Transformation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionIdentity() +{ +#if defined(_XM_NO_INTRINSICS_) + return g_XMIdentityR3.v; +#elif defined(_XM_SSE_INTRINSICS_) + return g_XMIdentityR3; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionRotationRollPitchYaw +( + FLOAT Pitch, + FLOAT Yaw, + FLOAT Roll +) +{ + XMVECTOR Angles; + XMVECTOR Q; + + Angles = XMVectorSet(Pitch, Yaw, Roll, 0.0f); + Q = XMQuaternionRotationRollPitchYawFromVector(Angles); + + return Q; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionRotationRollPitchYawFromVector +( + FXMVECTOR Angles // +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Q, Q0, Q1; + XMVECTOR P0, P1, Y0, Y1, R0, R1; + XMVECTOR HalfAngles; + XMVECTOR SinAngles, CosAngles; + static CONST XMVECTORU32 ControlPitch = {XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_1X, XM_PERMUTE_1X}; + static CONST XMVECTORU32 ControlYaw = {XM_PERMUTE_1Y, XM_PERMUTE_0Y, XM_PERMUTE_1Y, XM_PERMUTE_1Y}; + static CONST XMVECTORU32 ControlRoll = {XM_PERMUTE_1Z, XM_PERMUTE_1Z, XM_PERMUTE_0Z, XM_PERMUTE_1Z}; + static CONST XMVECTOR Sign = {1.0f, -1.0f, -1.0f, 1.0f}; + + HalfAngles = XMVectorMultiply(Angles, g_XMOneHalf.v); + XMVectorSinCos(&SinAngles, &CosAngles, HalfAngles); + + P0 = XMVectorPermute(SinAngles, CosAngles, ControlPitch.v); + Y0 = XMVectorPermute(SinAngles, CosAngles, ControlYaw.v); + R0 = XMVectorPermute(SinAngles, CosAngles, ControlRoll.v); + P1 = XMVectorPermute(CosAngles, SinAngles, ControlPitch.v); + Y1 = XMVectorPermute(CosAngles, SinAngles, ControlYaw.v); + R1 = XMVectorPermute(CosAngles, SinAngles, ControlRoll.v); + + Q1 = XMVectorMultiply(P1, Sign); + Q0 = XMVectorMultiply(P0, Y0); + Q1 = XMVectorMultiply(Q1, Y1); + Q0 = XMVectorMultiply(Q0, R0); + Q = XMVectorMultiplyAdd(Q1, R1, Q0); + + return Q; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Q, Q0, Q1; + XMVECTOR P0, P1, Y0, Y1, R0, R1; + XMVECTOR HalfAngles; + XMVECTOR SinAngles, CosAngles; + static CONST XMVECTORI32 ControlPitch = {XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_1X, XM_PERMUTE_1X}; + static CONST XMVECTORI32 ControlYaw = {XM_PERMUTE_1Y, XM_PERMUTE_0Y, XM_PERMUTE_1Y, XM_PERMUTE_1Y}; + static CONST XMVECTORI32 ControlRoll = {XM_PERMUTE_1Z, XM_PERMUTE_1Z, XM_PERMUTE_0Z, XM_PERMUTE_1Z}; + static CONST XMVECTORF32 Sign = {1.0f, -1.0f, -1.0f, 1.0f}; + + HalfAngles = _mm_mul_ps(Angles, g_XMOneHalf); + XMVectorSinCos(&SinAngles, &CosAngles, HalfAngles); + + P0 = XMVectorPermute(SinAngles, CosAngles, ControlPitch); + Y0 = XMVectorPermute(SinAngles, CosAngles, ControlYaw); + R0 = XMVectorPermute(SinAngles, CosAngles, ControlRoll); + P1 = XMVectorPermute(CosAngles, SinAngles, ControlPitch); + Y1 = XMVectorPermute(CosAngles, SinAngles, ControlYaw); + R1 = XMVectorPermute(CosAngles, SinAngles, ControlRoll); + + Q1 = _mm_mul_ps(P1, Sign); + Q0 = _mm_mul_ps(P0, Y0); + Q1 = _mm_mul_ps(Q1, Y1); + Q0 = _mm_mul_ps(Q0, R0); + Q = _mm_mul_ps(Q1, R1); + Q = _mm_add_ps(Q,Q0); + return Q; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionRotationNormal +( + FXMVECTOR NormalAxis, + FLOAT Angle +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Q; + XMVECTOR N; + XMVECTOR Scale; + + N = XMVectorSelect(g_XMOne.v, NormalAxis, g_XMSelect1110.v); + + XMScalarSinCos(&Scale.vector4_f32[2], &Scale.vector4_f32[3], 0.5f * Angle); + + Scale.vector4_f32[0] = Scale.vector4_f32[1] = Scale.vector4_f32[2]; + + Q = XMVectorMultiply(N, Scale); + + return Q; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR N = _mm_and_ps(NormalAxis,g_XMMask3); + N = _mm_or_ps(N,g_XMIdentityR3); + XMVECTOR Scale = _mm_set_ps1(0.5f * Angle); + XMVECTOR vSine; + XMVECTOR vCosine; + XMVectorSinCos(&vSine,&vCosine,Scale); + Scale = _mm_and_ps(vSine,g_XMMask3); + vCosine = _mm_and_ps(vCosine,g_XMMaskW); + Scale = _mm_or_ps(Scale,vCosine); + N = _mm_mul_ps(N,Scale); + return N; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMQuaternionRotationAxis +( + FXMVECTOR Axis, + FLOAT Angle +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Normal; + XMVECTOR Q; + + XMASSERT(!XMVector3Equal(Axis, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(Axis)); + + Normal = XMVector3Normalize(Axis); + Q = XMQuaternionRotationNormal(Normal, Angle); + + return Q; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Normal; + XMVECTOR Q; + + XMASSERT(!XMVector3Equal(Axis, XMVectorZero())); + XMASSERT(!XMVector3IsInfinite(Axis)); + + Normal = XMVector3Normalize(Axis); + Q = XMQuaternionRotationNormal(Normal, Angle); + return Q; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMQuaternionRotationMatrix +( + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) + + XMVECTOR Q0, Q1, Q2; + XMVECTOR M00, M11, M22; + XMVECTOR CQ0, CQ1, C; + XMVECTOR CX, CY, CZ, CW; + XMVECTOR SQ1, Scale; + XMVECTOR Rsq, Sqrt, VEqualsNaN; + XMVECTOR A, B, P; + XMVECTOR PermuteSplat, PermuteSplatT; + XMVECTOR SignB, SignBT; + XMVECTOR PermuteControl, PermuteControlT; + XMVECTOR Result; + static CONST XMVECTORF32 OneQuarter = {0.25f, 0.25f, 0.25f, 0.25f}; + static CONST XMVECTORF32 SignPNNP = {1.0f, -1.0f, -1.0f, 1.0f}; + static CONST XMVECTORF32 SignNPNP = {-1.0f, 1.0f, -1.0f, 1.0f}; + static CONST XMVECTORF32 SignNNPP = {-1.0f, -1.0f, 1.0f, 1.0f}; + static CONST XMVECTORF32 SignPNPP = {1.0f, -1.0f, 1.0f, 1.0f}; + static CONST XMVECTORF32 SignPPNP = {1.0f, 1.0f, -1.0f, 1.0f}; + static CONST XMVECTORF32 SignNPPP = {-1.0f, 1.0f, 1.0f, 1.0f}; + static CONST XMVECTORU32 Permute0X0X0Y0W = {XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0Y, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute0Y0Z0Z1W = {XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0Z, XM_PERMUTE_1W}; + static CONST XMVECTORU32 SplatX = {XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0X}; + static CONST XMVECTORU32 SplatY = {XM_PERMUTE_0Y, XM_PERMUTE_0Y, XM_PERMUTE_0Y, XM_PERMUTE_0Y}; + static CONST XMVECTORU32 SplatZ = {XM_PERMUTE_0Z, XM_PERMUTE_0Z, XM_PERMUTE_0Z, XM_PERMUTE_0Z}; + static CONST XMVECTORU32 SplatW = {XM_PERMUTE_0W, XM_PERMUTE_0W, XM_PERMUTE_0W, XM_PERMUTE_0W}; + static CONST XMVECTORU32 PermuteC = {XM_PERMUTE_0X, XM_PERMUTE_0Z, XM_PERMUTE_1X, XM_PERMUTE_1Y}; + static CONST XMVECTORU32 PermuteA = {XM_PERMUTE_0Y, XM_PERMUTE_1Y, XM_PERMUTE_1Z, XM_PERMUTE_0W}; + static CONST XMVECTORU32 PermuteB = {XM_PERMUTE_1X, XM_PERMUTE_1W, XM_PERMUTE_0Z, XM_PERMUTE_0W}; + static CONST XMVECTORU32 Permute0 = {XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_1Z, XM_PERMUTE_1Y}; + static CONST XMVECTORU32 Permute1 = {XM_PERMUTE_1X, XM_PERMUTE_0Y, XM_PERMUTE_1Y, XM_PERMUTE_1Z}; + static CONST XMVECTORU32 Permute2 = {XM_PERMUTE_1Z, XM_PERMUTE_1Y, XM_PERMUTE_0Z, XM_PERMUTE_1X}; + static CONST XMVECTORU32 Permute3 = {XM_PERMUTE_1Y, XM_PERMUTE_1Z, XM_PERMUTE_1X, XM_PERMUTE_0W}; + + M00 = XMVectorSplatX(M.r[0]); + M11 = XMVectorSplatY(M.r[1]); + M22 = XMVectorSplatZ(M.r[2]); + + Q0 = XMVectorMultiply(SignPNNP.v, M00); + Q0 = XMVectorMultiplyAdd(SignNPNP.v, M11, Q0); + Q0 = XMVectorMultiplyAdd(SignNNPP.v, M22, Q0); + + Q1 = XMVectorAdd(Q0, g_XMOne.v); + + Rsq = XMVectorReciprocalSqrt(Q1); + VEqualsNaN = XMVectorIsNaN(Rsq); + Sqrt = XMVectorMultiply(Q1, Rsq); + Q1 = XMVectorSelect(Sqrt, Q1, VEqualsNaN); + + Q1 = XMVectorMultiply(Q1, g_XMOneHalf.v); + + SQ1 = XMVectorMultiply(Rsq, g_XMOneHalf.v); + + CQ0 = XMVectorPermute(Q0, Q0, Permute0X0X0Y0W.v); + CQ1 = XMVectorPermute(Q0, g_XMEpsilon.v, Permute0Y0Z0Z1W.v); + C = XMVectorGreaterOrEqual(CQ0, CQ1); + + CX = XMVectorSplatX(C); + CY = XMVectorSplatY(C); + CZ = XMVectorSplatZ(C); + CW = XMVectorSplatW(C); + + PermuteSplat = XMVectorSelect(SplatZ.v, SplatY.v, CZ); + SignB = XMVectorSelect(SignNPPP.v, SignPPNP.v, CZ); + PermuteControl = XMVectorSelect(Permute2.v, Permute1.v, CZ); + + PermuteSplat = XMVectorSelect(PermuteSplat, SplatZ.v, CX); + SignB = XMVectorSelect(SignB, SignNPPP.v, CX); + PermuteControl = XMVectorSelect(PermuteControl, Permute2.v, CX); + + PermuteSplatT = XMVectorSelect(PermuteSplat,SplatX.v, CY); + SignBT = XMVectorSelect(SignB, SignPNPP.v, CY); + PermuteControlT = XMVectorSelect(PermuteControl,Permute0.v, CY); + + PermuteSplat = XMVectorSelect(PermuteSplat, PermuteSplatT, CX); + SignB = XMVectorSelect(SignB, SignBT, CX); + PermuteControl = XMVectorSelect(PermuteControl, PermuteControlT, CX); + + PermuteSplat = XMVectorSelect(PermuteSplat,SplatW.v, CW); + SignB = XMVectorSelect(SignB, g_XMNegativeOne.v, CW); + PermuteControl = XMVectorSelect(PermuteControl,Permute3.v, CW); + + Scale = XMVectorPermute(SQ1, SQ1, PermuteSplat); + + P = XMVectorPermute(M.r[1], M.r[2],PermuteC.v); // {M10, M12, M20, M21} + A = XMVectorPermute(M.r[0], P, PermuteA.v); // {M01, M12, M20, M03} + B = XMVectorPermute(M.r[0], P, PermuteB.v); // {M10, M21, M02, M03} + + Q2 = XMVectorMultiplyAdd(SignB, B, A); + Q2 = XMVectorMultiply(Q2, Scale); + + Result = XMVectorPermute(Q1, Q2, PermuteControl); + + return Result; + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Conversion operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMQuaternionToAxisAngle +( + XMVECTOR* pAxis, + FLOAT* pAngle, + FXMVECTOR Q +) +{ + XMASSERT(pAxis); + XMASSERT(pAngle); + + *pAxis = Q; + +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + *pAngle = 2.0f * acosf(XMVectorGetW(Q)); +#else + *pAngle = 2.0f * XMScalarACos(XMVectorGetW(Q)); +#endif +} + +/**************************************************************************** + * + * Plane + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMPlaneEqual +( + FXMVECTOR P1, + FXMVECTOR P2 +) +{ + return XMVector4Equal(P1, P2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMPlaneNearEqual +( + FXMVECTOR P1, + FXMVECTOR P2, + FXMVECTOR Epsilon +) +{ + XMVECTOR NP1 = XMPlaneNormalize(P1); + XMVECTOR NP2 = XMPlaneNormalize(P2); + return XMVector4NearEqual(NP1, NP2, Epsilon); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMPlaneNotEqual +( + FXMVECTOR P1, + FXMVECTOR P2 +) +{ + return XMVector4NotEqual(P1, P2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMPlaneIsNaN +( + FXMVECTOR P +) +{ + return XMVector4IsNaN(P); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMPlaneIsInfinite +( + FXMVECTOR P +) +{ + return XMVector4IsInfinite(P); +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneDot +( + FXMVECTOR P, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + return XMVector4Dot(P, V); + +#elif defined(_XM_SSE_INTRINSICS_) + __m128 vTemp2 = V; + __m128 vTemp = _mm_mul_ps(P,vTemp2); + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp,_MM_SHUFFLE(1,0,0,0)); // Copy X to the Z position and Y to the W position + vTemp2 = _mm_add_ps(vTemp2,vTemp); // Add Z = X+Z; W = Y+W; + vTemp = _mm_shuffle_ps(vTemp,vTemp2,_MM_SHUFFLE(0,3,0,0)); // Copy W to the Z position + vTemp = _mm_add_ps(vTemp,vTemp2); // Add Z and W together + return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(2,2,2,2)); // Splat Z and return +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneDotCoord +( + FXMVECTOR P, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V3; + XMVECTOR Result; + + // Result = P[0] * V[0] + P[1] * V[1] + P[2] * V[2] + P[3] + V3 = XMVectorSelect(g_XMOne.v, V, g_XMSelect1110.v); + Result = XMVector4Dot(P, V3); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp2 = _mm_and_ps(V,g_XMMask3); + vTemp2 = _mm_or_ps(vTemp2,g_XMIdentityR3); + XMVECTOR vTemp = _mm_mul_ps(P,vTemp2); + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp,_MM_SHUFFLE(1,0,0,0)); // Copy X to the Z position and Y to the W position + vTemp2 = _mm_add_ps(vTemp2,vTemp); // Add Z = X+Z; W = Y+W; + vTemp = _mm_shuffle_ps(vTemp,vTemp2,_MM_SHUFFLE(0,3,0,0)); // Copy W to the Z position + vTemp = _mm_add_ps(vTemp,vTemp2); // Add Z and W together + return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(2,2,2,2)); // Splat Z and return +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneDotNormal +( + FXMVECTOR P, + FXMVECTOR V +) +{ + return XMVector3Dot(P, V); +} + +//------------------------------------------------------------------------------ +// XMPlaneNormalizeEst uses a reciprocal estimate and +// returns QNaN on zero and infinite vectors. + +XMFINLINE XMVECTOR XMPlaneNormalizeEst +( + FXMVECTOR P +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result = XMVector3ReciprocalLength(P); + Result = XMVectorMultiply(P, Result); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product + XMVECTOR vDot = _mm_mul_ps(P,P); + // x=Dot.y, y=Dot.z + XMVECTOR vTemp = _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(2,1,2,1)); + // Result.x = x+y + vDot = _mm_add_ss(vDot,vTemp); + // x=Dot.z + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + // Result.x = (x+y)+z + vDot = _mm_add_ss(vDot,vTemp); + // Splat x + vDot = _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(0,0,0,0)); + // Get the reciprocal + vDot = _mm_rsqrt_ps(vDot); + // Get the reciprocal + vDot = _mm_mul_ps(vDot,P); + return vDot; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneNormalize +( + FXMVECTOR P +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fLengthSq = sqrtf((P.vector4_f32[0]*P.vector4_f32[0])+(P.vector4_f32[1]*P.vector4_f32[1])+(P.vector4_f32[2]*P.vector4_f32[2])); + // Prevent divide by zero + if (fLengthSq) { + fLengthSq = 1.0f/fLengthSq; + } + { + XMVECTOR vResult = { + P.vector4_f32[0]*fLengthSq, + P.vector4_f32[1]*fLengthSq, + P.vector4_f32[2]*fLengthSq, + P.vector4_f32[3]*fLengthSq + }; + return vResult; + } +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y and z only + XMVECTOR vLengthSq = _mm_mul_ps(P,P); + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,1,2,1)); + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + // Prepare for the division + XMVECTOR vResult = _mm_sqrt_ps(vLengthSq); + // Failsafe on zero (Or epsilon) length planes + // If the length is infinity, set the elements to zero + vLengthSq = _mm_cmpneq_ps(vLengthSq,g_XMInfinity); + // Reciprocal mul to perform the normalization + vResult = _mm_div_ps(P,vResult); + // Any that are infinity, set to zero + vResult = _mm_and_ps(vResult,vLengthSq); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneIntersectLine +( + FXMVECTOR P, + FXMVECTOR LinePoint1, + FXMVECTOR LinePoint2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1; + XMVECTOR V2; + XMVECTOR D; + XMVECTOR ReciprocalD; + XMVECTOR VT; + XMVECTOR Point; + XMVECTOR Zero; + XMVECTOR Control; + XMVECTOR Result; + + V1 = XMVector3Dot(P, LinePoint1); + V2 = XMVector3Dot(P, LinePoint2); + D = XMVectorSubtract(V1, V2); + + ReciprocalD = XMVectorReciprocal(D); + VT = XMPlaneDotCoord(P, LinePoint1); + VT = XMVectorMultiply(VT, ReciprocalD); + + Point = XMVectorSubtract(LinePoint2, LinePoint1); + Point = XMVectorMultiplyAdd(Point, VT, LinePoint1); + + Zero = XMVectorZero(); + Control = XMVectorNearEqual(D, Zero, g_XMEpsilon.v); + + Result = XMVectorSelect(Point, g_XMQNaN.v, Control); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V1; + XMVECTOR V2; + XMVECTOR D; + XMVECTOR VT; + XMVECTOR Point; + XMVECTOR Zero; + XMVECTOR Control; + XMVECTOR Result; + + V1 = XMVector3Dot(P, LinePoint1); + V2 = XMVector3Dot(P, LinePoint2); + D = _mm_sub_ps(V1, V2); + + VT = XMPlaneDotCoord(P, LinePoint1); + VT = _mm_div_ps(VT, D); + + Point = _mm_sub_ps(LinePoint2, LinePoint1); + Point = _mm_mul_ps(Point,VT); + Point = _mm_add_ps(Point,LinePoint1); + Zero = XMVectorZero(); + Control = XMVectorNearEqual(D, Zero, g_XMEpsilon); + Result = XMVectorSelect(Point, g_XMQNaN, Control); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE VOID XMPlaneIntersectPlane +( + XMVECTOR* pLinePoint1, + XMVECTOR* pLinePoint2, + FXMVECTOR P1, + FXMVECTOR P2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1; + XMVECTOR V2; + XMVECTOR V3; + XMVECTOR LengthSq; + XMVECTOR RcpLengthSq; + XMVECTOR Point; + XMVECTOR P1W; + XMVECTOR P2W; + XMVECTOR Control; + XMVECTOR LinePoint1; + XMVECTOR LinePoint2; + + XMASSERT(pLinePoint1); + XMASSERT(pLinePoint2); + + V1 = XMVector3Cross(P2, P1); + + LengthSq = XMVector3LengthSq(V1); + + V2 = XMVector3Cross(P2, V1); + + P1W = XMVectorSplatW(P1); + Point = XMVectorMultiply(V2, P1W); + + V3 = XMVector3Cross(V1, P1); + + P2W = XMVectorSplatW(P2); + Point = XMVectorMultiplyAdd(V3, P2W, Point); + + RcpLengthSq = XMVectorReciprocal(LengthSq); + LinePoint1 = XMVectorMultiply(Point, RcpLengthSq); + + LinePoint2 = XMVectorAdd(LinePoint1, V1); + + Control = XMVectorLessOrEqual(LengthSq, g_XMEpsilon.v); + *pLinePoint1 = XMVectorSelect(LinePoint1,g_XMQNaN.v, Control); + *pLinePoint2 = XMVectorSelect(LinePoint2,g_XMQNaN.v, Control); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pLinePoint1); + XMASSERT(pLinePoint2); + XMVECTOR V1; + XMVECTOR V2; + XMVECTOR V3; + XMVECTOR LengthSq; + XMVECTOR Point; + XMVECTOR P1W; + XMVECTOR P2W; + XMVECTOR Control; + XMVECTOR LinePoint1; + XMVECTOR LinePoint2; + + V1 = XMVector3Cross(P2, P1); + + LengthSq = XMVector3LengthSq(V1); + + V2 = XMVector3Cross(P2, V1); + + P1W = _mm_shuffle_ps(P1,P1,_MM_SHUFFLE(3,3,3,3)); + Point = _mm_mul_ps(V2, P1W); + + V3 = XMVector3Cross(V1, P1); + + P2W = _mm_shuffle_ps(P2,P2,_MM_SHUFFLE(3,3,3,3)); + V3 = _mm_mul_ps(V3,P2W); + Point = _mm_add_ps(Point,V3); + LinePoint1 = _mm_div_ps(Point,LengthSq); + + LinePoint2 = _mm_add_ps(LinePoint1, V1); + + Control = XMVectorLessOrEqual(LengthSq, g_XMEpsilon); + *pLinePoint1 = XMVectorSelect(LinePoint1,g_XMQNaN, Control); + *pLinePoint2 = XMVectorSelect(LinePoint2,g_XMQNaN, Control); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneTransform +( + FXMVECTOR P, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR W; + XMVECTOR Result; + + W = XMVectorSplatW(P); + Z = XMVectorSplatZ(P); + Y = XMVectorSplatY(P); + X = XMVectorSplatX(P); + + Result = XMVectorMultiply(W, M.r[3]); + Result = XMVectorMultiplyAdd(Z, M.r[2], Result); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR X = _mm_shuffle_ps(P,P,_MM_SHUFFLE(0,0,0,0)); + XMVECTOR Y = _mm_shuffle_ps(P,P,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR Z = _mm_shuffle_ps(P,P,_MM_SHUFFLE(2,2,2,2)); + XMVECTOR W = _mm_shuffle_ps(P,P,_MM_SHUFFLE(3,3,3,3)); + X = _mm_mul_ps(X, M.r[0]); + Y = _mm_mul_ps(Y, M.r[1]); + Z = _mm_mul_ps(Z, M.r[2]); + W = _mm_mul_ps(W, M.r[3]); + X = _mm_add_ps(X,Z); + Y = _mm_add_ps(Y,W); + X = _mm_add_ps(X,Y); + return X; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMFLOAT4* XMPlaneTransformStream +( + XMFLOAT4* pOutputStream, + UINT OutputStride, + CONST XMFLOAT4* pInputStream, + UINT InputStride, + UINT PlaneCount, + CXMMATRIX M +) +{ + return XMVector4TransformStream(pOutputStream, + OutputStride, + pInputStream, + InputStride, + PlaneCount, + M); +} + +//------------------------------------------------------------------------------ +// Conversion operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneFromPointNormal +( + FXMVECTOR Point, + FXMVECTOR Normal +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR W; + XMVECTOR Result; + + W = XMVector3Dot(Point, Normal); + W = XMVectorNegate(W); + Result = XMVectorSelect(W, Normal, g_XMSelect1110.v); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR W; + XMVECTOR Result; + W = XMVector3Dot(Point,Normal); + W = _mm_mul_ps(W,g_XMNegativeOne); + Result = _mm_and_ps(Normal,g_XMMask3); + W = _mm_and_ps(W,g_XMMaskW); + Result = _mm_or_ps(Result,W); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMPlaneFromPoints +( + FXMVECTOR Point1, + FXMVECTOR Point2, + FXMVECTOR Point3 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR N; + XMVECTOR D; + XMVECTOR V21; + XMVECTOR V31; + XMVECTOR Result; + + V21 = XMVectorSubtract(Point1, Point2); + V31 = XMVectorSubtract(Point1, Point3); + + N = XMVector3Cross(V21, V31); + N = XMVector3Normalize(N); + + D = XMPlaneDotNormal(N, Point1); + D = XMVectorNegate(D); + + Result = XMVectorSelect(D, N, g_XMSelect1110.v); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR N; + XMVECTOR D; + XMVECTOR V21; + XMVECTOR V31; + XMVECTOR Result; + + V21 = _mm_sub_ps(Point1, Point2); + V31 = _mm_sub_ps(Point1, Point3); + + N = XMVector3Cross(V21, V31); + N = XMVector3Normalize(N); + + D = XMPlaneDotNormal(N, Point1); + D = _mm_mul_ps(D,g_XMNegativeOne); + N = _mm_and_ps(N,g_XMMask3); + D = _mm_and_ps(D,g_XMMaskW); + Result = _mm_or_ps(D,N); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +/**************************************************************************** + * + * Color + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorEqual +( + FXMVECTOR C1, + FXMVECTOR C2 +) +{ + return XMVector4Equal(C1, C2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorNotEqual +( + FXMVECTOR C1, + FXMVECTOR C2 +) +{ + return XMVector4NotEqual(C1, C2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorGreater +( + FXMVECTOR C1, + FXMVECTOR C2 +) +{ + return XMVector4Greater(C1, C2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorGreaterOrEqual +( + FXMVECTOR C1, + FXMVECTOR C2 +) +{ + return XMVector4GreaterOrEqual(C1, C2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorLess +( + FXMVECTOR C1, + FXMVECTOR C2 +) +{ + return XMVector4Less(C1, C2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorLessOrEqual +( + FXMVECTOR C1, + FXMVECTOR C2 +) +{ + return XMVector4LessOrEqual(C1, C2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorIsNaN +( + FXMVECTOR C +) +{ + return XMVector4IsNaN(C); +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMColorIsInfinite +( + FXMVECTOR C +) +{ + return XMVector4IsInfinite(C); +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMColorNegative +( + FXMVECTOR vColor +) +{ +#if defined(_XM_NO_INTRINSICS_) +// XMASSERT(XMVector4GreaterOrEqual(C, XMVectorReplicate(0.0f))); +// XMASSERT(XMVector4LessOrEqual(C, XMVectorReplicate(1.0f))); + XMVECTOR vResult = { + 1.0f - vColor.vector4_f32[0], + 1.0f - vColor.vector4_f32[1], + 1.0f - vColor.vector4_f32[2], + vColor.vector4_f32[3] + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + // Negate only x,y and z. + XMVECTOR vTemp = _mm_xor_ps(vColor,g_XMNegate3); + // Add 1,1,1,0 to -x,-y,-z,w + return _mm_add_ps(vTemp,g_XMOne3); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMColorModulate +( + FXMVECTOR C1, + FXMVECTOR C2 +) +{ + return XMVectorMultiply(C1, C2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMColorAdjustSaturation +( + FXMVECTOR vColor, + FLOAT fSaturation +) +{ +#if defined(_XM_NO_INTRINSICS_) + CONST XMVECTOR gvLuminance = {0.2125f, 0.7154f, 0.0721f, 0.0f}; + + // Luminance = 0.2125f * C[0] + 0.7154f * C[1] + 0.0721f * C[2]; + // Result = (C - Luminance) * Saturation + Luminance; + + FLOAT fLuminance = (vColor.vector4_f32[0]*gvLuminance.vector4_f32[0])+(vColor.vector4_f32[1]*gvLuminance.vector4_f32[1])+(vColor.vector4_f32[2]*gvLuminance.vector4_f32[2]); + XMVECTOR vResult = { + ((vColor.vector4_f32[0] - fLuminance)*fSaturation)+fLuminance, + ((vColor.vector4_f32[1] - fLuminance)*fSaturation)+fLuminance, + ((vColor.vector4_f32[2] - fLuminance)*fSaturation)+fLuminance, + vColor.vector4_f32[3]}; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 gvLuminance = {0.2125f, 0.7154f, 0.0721f, 0.0f}; +// Mul RGB by intensity constants + XMVECTOR vLuminance = _mm_mul_ps(vColor,gvLuminance); +// vResult.x = vLuminance.y, vResult.y = vLuminance.y, +// vResult.z = vLuminance.z, vResult.w = vLuminance.z + XMVECTOR vResult = vLuminance; + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(2,2,1,1)); +// vLuminance.x += vLuminance.y + vLuminance = _mm_add_ss(vLuminance,vResult); +// Splat vLuminance.z + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(2,2,2,2)); +// vLuminance.x += vLuminance.z (Dot product) + vLuminance = _mm_add_ss(vLuminance,vResult); +// Splat vLuminance + vLuminance = _mm_shuffle_ps(vLuminance,vLuminance,_MM_SHUFFLE(0,0,0,0)); +// Splat fSaturation + XMVECTOR vSaturation = _mm_set_ps1(fSaturation); +// vResult = ((vColor-vLuminance)*vSaturation)+vLuminance; + vResult = _mm_sub_ps(vColor,vLuminance); + vResult = _mm_mul_ps(vResult,vSaturation); + vResult = _mm_add_ps(vResult,vLuminance); +// Retain w from the source color + vLuminance = _mm_shuffle_ps(vResult,vColor,_MM_SHUFFLE(3,2,2,2)); // x = vResult.z,y = vResult.z,z = vColor.z,w=vColor.w + vResult = _mm_shuffle_ps(vResult,vLuminance,_MM_SHUFFLE(3,0,1,0)); // x = vResult.x,y = vResult.y,z = vResult.z,w=vColor.w + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMColorAdjustContrast +( + FXMVECTOR vColor, + FLOAT fContrast +) +{ +#if defined(_XM_NO_INTRINSICS_) + // Result = (vColor - 0.5f) * fContrast + 0.5f; + XMVECTOR vResult = { + ((vColor.vector4_f32[0]-0.5f) * fContrast) + 0.5f, + ((vColor.vector4_f32[1]-0.5f) * fContrast) + 0.5f, + ((vColor.vector4_f32[2]-0.5f) * fContrast) + 0.5f, + vColor.vector4_f32[3] // Leave W untouched + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vScale = _mm_set_ps1(fContrast); // Splat the scale + XMVECTOR vResult = _mm_sub_ps(vColor,g_XMOneHalf); // Subtract 0.5f from the source (Saving source) + vResult = _mm_mul_ps(vResult,vScale); // Mul by scale + vResult = _mm_add_ps(vResult,g_XMOneHalf); // Add 0.5f +// Retain w from the source color + vScale = _mm_shuffle_ps(vResult,vColor,_MM_SHUFFLE(3,2,2,2)); // x = vResult.z,y = vResult.z,z = vColor.z,w=vColor.w + vResult = _mm_shuffle_ps(vResult,vScale,_MM_SHUFFLE(3,0,1,0)); // x = vResult.x,y = vResult.y,z = vResult.z,w=vColor.w + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +/**************************************************************************** + * + * Miscellaneous + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMINLINE BOOL XMVerifyCPUSupport() +{ +#if defined(_XM_NO_INTRINSICS_) || !defined(_XM_SSE_INTRINSICS_) + return TRUE; +#else // _XM_SSE_INTRINSICS_ + // Note that on Windows 2000 or older, SSE2 detection is not supported so this will always fail + // Detecting SSE2 on older versions of Windows would require using cpuid directly + return ( IsProcessorFeaturePresent( PF_XMMI_INSTRUCTIONS_AVAILABLE ) && IsProcessorFeaturePresent( PF_XMMI64_INSTRUCTIONS_AVAILABLE ) ); +#endif +} + + +//------------------------------------------------------------------------------ + +#define XMASSERT_LINE_STRING_SIZE 16 + +XMINLINE VOID XMAssert +( + CONST CHAR* pExpression, + CONST CHAR* pFileName, + UINT LineNumber +) +{ + CHAR aLineString[XMASSERT_LINE_STRING_SIZE]; + CHAR* pLineString; + UINT Line; + + aLineString[XMASSERT_LINE_STRING_SIZE - 2] = '0'; + aLineString[XMASSERT_LINE_STRING_SIZE - 1] = '\0'; + for (Line = LineNumber, pLineString = aLineString + XMASSERT_LINE_STRING_SIZE - 2; + Line != 0 && pLineString >= aLineString; + Line /= 10, pLineString--) + { + *pLineString = (CHAR)('0' + (Line % 10)); + } + +#ifndef NO_OUTPUT_DEBUG_STRING + OutputDebugStringA("Assertion failed: "); + OutputDebugStringA(pExpression); + OutputDebugStringA(", file "); + OutputDebugStringA(pFileName); + OutputDebugStringA(", line "); + OutputDebugStringA(pLineString + 1); + OutputDebugStringA("\r\n"); +#else + DbgPrint("Assertion failed: %s, file %s, line %d\r\n", pExpression, pFileName, LineNumber); +#endif + + __debugbreak(); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMFresnelTerm +( + FXMVECTOR CosIncidentAngle, + FXMVECTOR RefractionIndex +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR G; + XMVECTOR D, S; + XMVECTOR V0, V1, V2, V3; + XMVECTOR Result; + + // Result = 0.5f * (g - c)^2 / (g + c)^2 * ((c * (g + c) - 1)^2 / (c * (g - c) + 1)^2 + 1) where + // c = CosIncidentAngle + // g = sqrt(c^2 + RefractionIndex^2 - 1) + + XMASSERT(!XMVector4IsInfinite(CosIncidentAngle)); + + G = XMVectorMultiplyAdd(RefractionIndex, RefractionIndex, g_XMNegativeOne.v); + G = XMVectorMultiplyAdd(CosIncidentAngle, CosIncidentAngle, G); + G = XMVectorAbs(G); + G = XMVectorSqrt(G); + + S = XMVectorAdd(G, CosIncidentAngle); + D = XMVectorSubtract(G, CosIncidentAngle); + + V0 = XMVectorMultiply(D, D); + V1 = XMVectorMultiply(S, S); + V1 = XMVectorReciprocal(V1); + V0 = XMVectorMultiply(g_XMOneHalf.v, V0); + V0 = XMVectorMultiply(V0, V1); + + V2 = XMVectorMultiplyAdd(CosIncidentAngle, S, g_XMNegativeOne.v); + V3 = XMVectorMultiplyAdd(CosIncidentAngle, D, g_XMOne.v); + V2 = XMVectorMultiply(V2, V2); + V3 = XMVectorMultiply(V3, V3); + V3 = XMVectorReciprocal(V3); + V2 = XMVectorMultiplyAdd(V2, V3, g_XMOne.v); + + Result = XMVectorMultiply(V0, V2); + + Result = XMVectorSaturate(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Result = 0.5f * (g - c)^2 / (g + c)^2 * ((c * (g + c) - 1)^2 / (c * (g - c) + 1)^2 + 1) where + // c = CosIncidentAngle + // g = sqrt(c^2 + RefractionIndex^2 - 1) + + XMASSERT(!XMVector4IsInfinite(CosIncidentAngle)); + + // G = sqrt(abs((RefractionIndex^2-1) + CosIncidentAngle^2)) + XMVECTOR G = _mm_mul_ps(RefractionIndex,RefractionIndex); + XMVECTOR vTemp = _mm_mul_ps(CosIncidentAngle,CosIncidentAngle); + G = _mm_sub_ps(G,g_XMOne); + vTemp = _mm_add_ps(vTemp,G); + // max((0-vTemp),vTemp) == abs(vTemp) + // The abs is needed to deal with refraction and cosine being zero + G = _mm_setzero_ps(); + G = _mm_sub_ps(G,vTemp); + G = _mm_max_ps(G,vTemp); + // Last operation, the sqrt() + G = _mm_sqrt_ps(G); + + // Calc G-C and G+C + XMVECTOR GAddC = _mm_add_ps(G,CosIncidentAngle); + XMVECTOR GSubC = _mm_sub_ps(G,CosIncidentAngle); + // Perform the term (0.5f *(g - c)^2) / (g + c)^2 + XMVECTOR vResult = _mm_mul_ps(GSubC,GSubC); + vTemp = _mm_mul_ps(GAddC,GAddC); + vResult = _mm_mul_ps(vResult,g_XMOneHalf); + vResult = _mm_div_ps(vResult,vTemp); + // Perform the term ((c * (g + c) - 1)^2 / (c * (g - c) + 1)^2 + 1) + GAddC = _mm_mul_ps(GAddC,CosIncidentAngle); + GSubC = _mm_mul_ps(GSubC,CosIncidentAngle); + GAddC = _mm_sub_ps(GAddC,g_XMOne); + GSubC = _mm_add_ps(GSubC,g_XMOne); + GAddC = _mm_mul_ps(GAddC,GAddC); + GSubC = _mm_mul_ps(GSubC,GSubC); + GAddC = _mm_div_ps(GAddC,GSubC); + GAddC = _mm_add_ps(GAddC,g_XMOne); + // Multiply the two term parts + vResult = _mm_mul_ps(vResult,GAddC); + // Clamp to 0.0 - 1.0f + vResult = _mm_max_ps(vResult,g_XMZero); + vResult = _mm_min_ps(vResult,g_XMOne); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMScalarNearEqual +( + FLOAT S1, + FLOAT S2, + FLOAT Epsilon +) +{ + FLOAT Delta = S1 - S2; +#if defined(_XM_NO_INTRINSICS_) + UINT AbsDelta = *(UINT*)&Delta & 0x7FFFFFFF; + return (*(FLOAT*)&AbsDelta <= Epsilon); +#elif defined(_XM_SSE_INTRINSICS_) + return (fabsf(Delta) <= Epsilon); +#else + return (__fabs(Delta) <= Epsilon); +#endif +} + +//------------------------------------------------------------------------------ +// Modulo the range of the given angle such that -XM_PI <= Angle < XM_PI +XMFINLINE FLOAT XMScalarModAngle +( + FLOAT Angle +) +{ + // Note: The modulo is performed with unsigned math only to work + // around a precision error on numbers that are close to PI + float fTemp; +#if defined(_XM_NO_INTRINSICS_) || !defined(_XM_VMX128_INTRINSICS_) + // Normalize the range from 0.0f to XM_2PI + Angle = Angle + XM_PI; + // Perform the modulo, unsigned + fTemp = fabsf(Angle); + fTemp = fTemp - (XM_2PI * (FLOAT)((INT)(fTemp/XM_2PI))); + // Restore the number to the range of -XM_PI to XM_PI-epsilon + fTemp = fTemp - XM_PI; + // If the modulo'd value was negative, restore negation + if (Angle<0.0f) { + fTemp = -fTemp; + } + return fTemp; +#else +#endif +} + +//------------------------------------------------------------------------------ + +XMINLINE FLOAT XMScalarSin +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT ValueMod; + FLOAT ValueSq; + XMVECTOR V0123, V0246, V1357, V9111315, V17192123; + XMVECTOR V1, V7, V8; + XMVECTOR R0, R1, R2; + + ValueMod = XMScalarModAngle(Value); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - V^15 / 15! + + // V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + + ValueSq = ValueMod * ValueMod; + + V0123 = XMVectorSet(1.0f, ValueMod, ValueSq, ValueSq * ValueMod); + V1 = XMVectorSplatY(V0123); + V0246 = XMVectorMultiply(V0123, V0123); + V1357 = XMVectorMultiply(V0246, V1); + V7 = XMVectorSplatW(V1357); + V8 = XMVectorMultiply(V7, V1); + V9111315 = XMVectorMultiply(V1357, V8); + V17192123 = XMVectorMultiply(V9111315, V8); + + R0 = XMVector4Dot(V1357, g_XMSinCoefficients0.v); + R1 = XMVector4Dot(V9111315, g_XMSinCoefficients1.v); + R2 = XMVector4Dot(V17192123, g_XMSinCoefficients2.v); + + return R0.vector4_f32[0] + R1.vector4_f32[0] + R2.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + return sinf( Value ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE FLOAT XMScalarCos +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT ValueMod; + FLOAT ValueSq; + XMVECTOR V0123, V0246, V8101214, V16182022; + XMVECTOR V2, V6, V8; + XMVECTOR R0, R1, R2; + + ValueMod = XMScalarModAngle(Value); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + + // V^12 / 12! - V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + + ValueSq = ValueMod * ValueMod; + + V0123 = XMVectorSet(1.0f, ValueMod, ValueSq, ValueSq * ValueMod); + V0246 = XMVectorMultiply(V0123, V0123); + + V2 = XMVectorSplatZ(V0123); + V6 = XMVectorSplatW(V0246); + V8 = XMVectorMultiply(V6, V2); + + V8101214 = XMVectorMultiply(V0246, V8); + V16182022 = XMVectorMultiply(V8101214, V8); + + R0 = XMVector4Dot(V0246, g_XMCosCoefficients0.v); + R1 = XMVector4Dot(V8101214, g_XMCosCoefficients1.v); + R2 = XMVector4Dot(V16182022, g_XMCosCoefficients2.v); + + return R0.vector4_f32[0] + R1.vector4_f32[0] + R2.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + return cosf(Value); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE VOID XMScalarSinCos +( + FLOAT* pSin, + FLOAT* pCos, + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT ValueMod; + FLOAT ValueSq; + XMVECTOR V0123, V0246, V1357, V8101214, V9111315, V16182022, V17192123; + XMVECTOR V1, V2, V6, V8; + XMVECTOR S0, S1, S2, C0, C1, C2; + + XMASSERT(pSin); + XMASSERT(pCos); + + ValueMod = XMScalarModAngle(Value); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - V^15 / 15! + + // V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + + // V^12 / 12! - V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + + ValueSq = ValueMod * ValueMod; + + V0123 = XMVectorSet(1.0f, ValueMod, ValueSq, ValueSq * ValueMod); + + V1 = XMVectorSplatY(V0123); + V2 = XMVectorSplatZ(V0123); + + V0246 = XMVectorMultiply(V0123, V0123); + V1357 = XMVectorMultiply(V0246, V1); + + V6 = XMVectorSplatW(V0246); + V8 = XMVectorMultiply(V6, V2); + + V8101214 = XMVectorMultiply(V0246, V8); + V9111315 = XMVectorMultiply(V1357, V8); + V16182022 = XMVectorMultiply(V8101214, V8); + V17192123 = XMVectorMultiply(V9111315, V8); + + C0 = XMVector4Dot(V0246, g_XMCosCoefficients0.v); + S0 = XMVector4Dot(V1357, g_XMSinCoefficients0.v); + C1 = XMVector4Dot(V8101214, g_XMCosCoefficients1.v); + S1 = XMVector4Dot(V9111315, g_XMSinCoefficients1.v); + C2 = XMVector4Dot(V16182022, g_XMCosCoefficients2.v); + S2 = XMVector4Dot(V17192123, g_XMSinCoefficients2.v); + + *pCos = C0.vector4_f32[0] + C1.vector4_f32[0] + C2.vector4_f32[0]; + *pSin = S0.vector4_f32[0] + S1.vector4_f32[0] + S2.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSin); + XMASSERT(pCos); + + *pSin = sinf(Value); + *pCos = cosf(Value); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE FLOAT XMScalarASin +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT AbsValue, Value2, Value3, D; + XMVECTOR AbsV, R0, R1, Result; + XMVECTOR V3; + + *(UINT*)&AbsValue = *(UINT*)&Value & 0x7FFFFFFF; + + Value2 = Value * AbsValue; + Value3 = Value * Value2; + D = (Value - Value2) / sqrtf(1.00000011921f - AbsValue); + + AbsV = XMVectorReplicate(AbsValue); + + V3.vector4_f32[0] = Value3; + V3.vector4_f32[1] = 1.0f; + V3.vector4_f32[2] = Value3; + V3.vector4_f32[3] = 1.0f; + + R1 = XMVectorSet(D, D, Value, Value); + R1 = XMVectorMultiply(R1, V3); + + R0 = XMVectorMultiplyAdd(AbsV, g_XMASinCoefficients0.v, g_XMASinCoefficients1.v); + R0 = XMVectorMultiplyAdd(AbsV, R0, g_XMASinCoefficients2.v); + + Result = XMVector4Dot(R0, R1); + + return Result.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + return asinf(Value); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE FLOAT XMScalarACos +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + return XM_PIDIV2 - XMScalarASin(Value); + +#elif defined(_XM_SSE_INTRINSICS_) + return acosf(Value); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE FLOAT XMScalarSinEst +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT ValueSq; + XMVECTOR V; + XMVECTOR Y; + XMVECTOR Result; + + XMASSERT(Value >= -XM_PI); + XMASSERT(Value < XM_PI); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! (for -PI <= V < PI) + + ValueSq = Value * Value; + + V = XMVectorSet(1.0f, Value, ValueSq, ValueSq * Value); + Y = XMVectorSplatY(V); + V = XMVectorMultiply(V, V); + V = XMVectorMultiply(V, Y); + + Result = XMVector4Dot(V, g_XMSinEstCoefficients.v); + + return Result.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(Value >= -XM_PI); + XMASSERT(Value < XM_PI); + float ValueSq = Value*Value; + XMVECTOR vValue = _mm_set_ps1(Value); + XMVECTOR vTemp = _mm_set_ps(ValueSq * Value,ValueSq,Value,1.0f); + vTemp = _mm_mul_ps(vTemp,vTemp); + vTemp = _mm_mul_ps(vTemp,vValue); + // vTemp = Value,Value^3,Value^5,Value^7 + vTemp = _mm_mul_ps(vTemp,g_XMSinEstCoefficients); + vValue = _mm_shuffle_ps(vValue,vTemp,_MM_SHUFFLE(1,0,0,0)); // Copy X to the Z position and Y to the W position + vValue = _mm_add_ps(vValue,vTemp); // Add Z = X+Z; W = Y+W; + vTemp = _mm_shuffle_ps(vTemp,vValue,_MM_SHUFFLE(0,3,0,0)); // Copy W to the Z position + vTemp = _mm_add_ps(vTemp,vValue); // Add Z and W together + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(2,2,2,2)); // Splat Z and return +#if defined(_MSC_VER) && (_MSC_VER>=1500) + return _mm_cvtss_f32(vTemp); +#else + return vTemp.m128_f32[0]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE FLOAT XMScalarCosEst +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT ValueSq; + XMVECTOR V; + XMVECTOR Result; + XMASSERT(Value >= -XM_PI); + XMASSERT(Value < XM_PI); + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! (for -PI <= V < PI) + ValueSq = Value * Value; + V = XMVectorSet(1.0f, Value, ValueSq, ValueSq * Value); + V = XMVectorMultiply(V, V); + Result = XMVector4Dot(V, g_XMCosEstCoefficients.v); + return Result.vector4_f32[0]; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(Value >= -XM_PI); + XMASSERT(Value < XM_PI); + float ValueSq = Value*Value; + XMVECTOR vValue = _mm_setzero_ps(); + XMVECTOR vTemp = _mm_set_ps(ValueSq * Value,ValueSq,Value,1.0f); + vTemp = _mm_mul_ps(vTemp,vTemp); + // vTemp = 1.0f,Value^2,Value^4,Value^6 + vTemp = _mm_mul_ps(vTemp,g_XMCosEstCoefficients); + vValue = _mm_shuffle_ps(vValue,vTemp,_MM_SHUFFLE(1,0,0,0)); // Copy X to the Z position and Y to the W position + vValue = _mm_add_ps(vValue,vTemp); // Add Z = X+Z; W = Y+W; + vTemp = _mm_shuffle_ps(vTemp,vValue,_MM_SHUFFLE(0,3,0,0)); // Copy W to the Z position + vTemp = _mm_add_ps(vTemp,vValue); // Add Z and W together + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(2,2,2,2)); // Splat Z and return +#if defined(_MSC_VER) && (_MSC_VER>=1500) + return _mm_cvtss_f32(vTemp); +#else + return vTemp.m128_f32[0]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMScalarSinCosEst +( + FLOAT* pSin, + FLOAT* pCos, + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT ValueSq; + XMVECTOR V, Sin, Cos; + XMVECTOR Y; + + XMASSERT(pSin); + XMASSERT(pCos); + XMASSERT(Value >= -XM_PI); + XMASSERT(Value < XM_PI); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! (for -PI <= V < PI) + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! (for -PI <= V < PI) + + ValueSq = Value * Value; + V = XMVectorSet(1.0f, Value, ValueSq, Value * ValueSq); + Y = XMVectorSplatY(V); + Cos = XMVectorMultiply(V, V); + Sin = XMVectorMultiply(Cos, Y); + + Cos = XMVector4Dot(Cos, g_XMCosEstCoefficients.v); + Sin = XMVector4Dot(Sin, g_XMSinEstCoefficients.v); + + *pCos = Cos.vector4_f32[0]; + *pSin = Sin.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSin); + XMASSERT(pCos); + XMASSERT(Value >= -XM_PI); + XMASSERT(Value < XM_PI); + float ValueSq = Value * Value; + XMVECTOR Cos = _mm_set_ps(Value * ValueSq,ValueSq,Value,1.0f); + XMVECTOR Sin = _mm_set_ps1(Value); + Cos = _mm_mul_ps(Cos,Cos); + Sin = _mm_mul_ps(Sin,Cos); + // Cos = 1.0f,Value^2,Value^4,Value^6 + Cos = XMVector4Dot(Cos,g_XMCosEstCoefficients); + _mm_store_ss(pCos,Cos); + // Sin = Value,Value^3,Value^5,Value^7 + Sin = XMVector4Dot(Sin, g_XMSinEstCoefficients); + _mm_store_ss(pSin,Sin); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE FLOAT XMScalarASinEst +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR VR, CR, CS; + XMVECTOR Result; + FLOAT AbsV, V2, D; + CONST FLOAT OnePlusEps = 1.00000011921f; + + *(UINT*)&AbsV = *(UINT*)&Value & 0x7FFFFFFF; + V2 = Value * AbsV; + D = OnePlusEps - AbsV; + + CS = XMVectorSet(Value, 1.0f, 1.0f, V2); + VR = XMVectorSet(sqrtf(D), Value, V2, D * AbsV); + CR = XMVectorMultiply(CS, g_XMASinEstCoefficients.v); + + Result = XMVector4Dot(VR, CR); + + return Result.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + CONST FLOAT OnePlusEps = 1.00000011921f; + FLOAT AbsV = fabsf(Value); + FLOAT V2 = Value * AbsV; // Square with sign retained + FLOAT D = OnePlusEps - AbsV; + + XMVECTOR Result = _mm_set_ps(V2,1.0f,1.0f,Value); + XMVECTOR VR = _mm_set_ps(D * AbsV,V2,Value,sqrtf(D)); + Result = _mm_mul_ps(Result, g_XMASinEstCoefficients); + Result = XMVector4Dot(VR,Result); +#if defined(_MSC_VER) && (_MSC_VER>=1500) + return _mm_cvtss_f32(Result); +#else + return Result.m128_f32[0]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE FLOAT XMScalarACosEst +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR VR, CR, CS; + XMVECTOR Result; + FLOAT AbsV, V2, D; + CONST FLOAT OnePlusEps = 1.00000011921f; + + // return XM_PIDIV2 - XMScalarASin(Value); + + *(UINT*)&AbsV = *(UINT*)&Value & 0x7FFFFFFF; + V2 = Value * AbsV; + D = OnePlusEps - AbsV; + + CS = XMVectorSet(Value, 1.0f, 1.0f, V2); + VR = XMVectorSet(sqrtf(D), Value, V2, D * AbsV); + CR = XMVectorMultiply(CS, g_XMASinEstCoefficients.v); + + Result = XMVector4Dot(VR, CR); + + return XM_PIDIV2 - Result.vector4_f32[0]; + +#elif defined(_XM_SSE_INTRINSICS_) + CONST FLOAT OnePlusEps = 1.00000011921f; + FLOAT AbsV = fabsf(Value); + FLOAT V2 = Value * AbsV; // Value^2 retaining sign + FLOAT D = OnePlusEps - AbsV; + XMVECTOR Result = _mm_set_ps(V2,1.0f,1.0f,Value); + XMVECTOR VR = _mm_set_ps(D * AbsV,V2,Value,sqrtf(D)); + Result = _mm_mul_ps(Result,g_XMASinEstCoefficients); + Result = XMVector4Dot(VR,Result); +#if defined(_MSC_VER) && (_MSC_VER>=1500) + return XM_PIDIV2 - _mm_cvtss_f32(Result); +#else + return XM_PIDIV2 - Result.m128_f32[0]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +#endif // __XNAMATHMISC_INL__ + diff --git a/dxsdk/Include/xnamathvector.inl b/dxsdk/Include/xnamathvector.inl new file mode 100644 index 0000000..bfea1d0 --- /dev/null +++ b/dxsdk/Include/xnamathvector.inl @@ -0,0 +1,13279 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + xnamathvector.inl + +Abstract: + + XNA math library for Windows and Xbox 360: Vector functions +--*/ + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __XNAMATHVECTOR_INL__ +#define __XNAMATHVECTOR_INL__ + +#if defined(_XM_NO_INTRINSICS_) +#define XMISNAN(x) ((*(UINT*)&(x) & 0x7F800000) == 0x7F800000 && (*(UINT*)&(x) & 0x7FFFFF) != 0) +#define XMISINF(x) ((*(UINT*)&(x) & 0x7FFFFFFF) == 0x7F800000) +#endif + +/**************************************************************************** + * + * General Vector + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Assignment operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Return a vector with all elements equaling zero +XMFINLINE XMVECTOR XMVectorZero() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult = {0.0f,0.0f,0.0f,0.0f}; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_setzero_ps(); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with four floating point values +XMFINLINE XMVECTOR XMVectorSet +( + FLOAT x, + FLOAT y, + FLOAT z, + FLOAT w +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTORF32 vResult = {x,y,z,w}; + return vResult.v; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_set_ps( w, z, y, x ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with four integer values +XMFINLINE XMVECTOR XMVectorSetInt +( + UINT x, + UINT y, + UINT z, + UINT w +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTORU32 vResult = {x,y,z,w}; + return vResult.v; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_set_epi32( w, z, y, x ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with a replicated floating point value +XMFINLINE XMVECTOR XMVectorReplicate +( + FLOAT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) + XMVECTORF32 vResult = {Value,Value,Value,Value}; + return vResult.v; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_set_ps1( Value ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with a replicated floating point value passed by pointer +XMFINLINE XMVECTOR XMVectorReplicatePtr +( + CONST FLOAT *pValue +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) + FLOAT Value = pValue[0]; + XMVECTORF32 vResult = {Value,Value,Value,Value}; + return vResult.v; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_load_ps1( pValue ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with a replicated integer value +XMFINLINE XMVECTOR XMVectorReplicateInt +( + UINT Value +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) + XMVECTORU32 vResult = {Value,Value,Value,Value}; + return vResult.v; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_set1_epi32( Value ); + return reinterpret_cast(&vTemp)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with a replicated integer value passed by pointer +XMFINLINE XMVECTOR XMVectorReplicateIntPtr +( + CONST UINT *pValue +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) + UINT Value = pValue[0]; + XMVECTORU32 vResult = {Value,Value,Value,Value}; + return vResult.v; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_load_ps1(reinterpret_cast(pValue)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with all bits set (true mask) +XMFINLINE XMVECTOR XMVectorTrueInt() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTORU32 vResult = {0xFFFFFFFFU,0xFFFFFFFFU,0xFFFFFFFFU,0xFFFFFFFFU}; + return vResult.v; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_set1_epi32(-1); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Initialize a vector with all bits clear (false mask) +XMFINLINE XMVECTOR XMVectorFalseInt() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult = {0.0f,0.0f,0.0f,0.0f}; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_setzero_ps(); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Replicate the x component of the vector +XMFINLINE XMVECTOR XMVectorSplatX +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_f32[0] = + vResult.vector4_f32[1] = + vResult.vector4_f32[2] = + vResult.vector4_f32[3] = V.vector4_f32[0]; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_shuffle_ps( V, V, _MM_SHUFFLE(0, 0, 0, 0) ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Replicate the y component of the vector +XMFINLINE XMVECTOR XMVectorSplatY +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_f32[0] = + vResult.vector4_f32[1] = + vResult.vector4_f32[2] = + vResult.vector4_f32[3] = V.vector4_f32[1]; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_shuffle_ps( V, V, _MM_SHUFFLE(1, 1, 1, 1) ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Replicate the z component of the vector +XMFINLINE XMVECTOR XMVectorSplatZ +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_f32[0] = + vResult.vector4_f32[1] = + vResult.vector4_f32[2] = + vResult.vector4_f32[3] = V.vector4_f32[2]; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_shuffle_ps( V, V, _MM_SHUFFLE(2, 2, 2, 2) ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Replicate the w component of the vector +XMFINLINE XMVECTOR XMVectorSplatW +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_f32[0] = + vResult.vector4_f32[1] = + vResult.vector4_f32[2] = + vResult.vector4_f32[3] = V.vector4_f32[3]; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_shuffle_ps( V, V, _MM_SHUFFLE(3, 3, 3, 3) ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return a vector of 1.0f,1.0f,1.0f,1.0f +XMFINLINE XMVECTOR XMVectorSplatOne() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_f32[0] = + vResult.vector4_f32[1] = + vResult.vector4_f32[2] = + vResult.vector4_f32[3] = 1.0f; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return g_XMOne; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return a vector of INF,INF,INF,INF +XMFINLINE XMVECTOR XMVectorSplatInfinity() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_u32[0] = + vResult.vector4_u32[1] = + vResult.vector4_u32[2] = + vResult.vector4_u32[3] = 0x7F800000; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return g_XMInfinity; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return a vector of Q_NAN,Q_NAN,Q_NAN,Q_NAN +XMFINLINE XMVECTOR XMVectorSplatQNaN() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_u32[0] = + vResult.vector4_u32[1] = + vResult.vector4_u32[2] = + vResult.vector4_u32[3] = 0x7FC00000; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return g_XMQNaN; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return a vector of 1.192092896e-7f,1.192092896e-7f,1.192092896e-7f,1.192092896e-7f +XMFINLINE XMVECTOR XMVectorSplatEpsilon() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_u32[0] = + vResult.vector4_u32[1] = + vResult.vector4_u32[2] = + vResult.vector4_u32[3] = 0x34000000; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + return g_XMEpsilon; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return a vector of -0.0f (0x80000000),-0.0f,-0.0f,-0.0f +XMFINLINE XMVECTOR XMVectorSplatSignMask() +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult; + vResult.vector4_u32[0] = + vResult.vector4_u32[1] = + vResult.vector4_u32[2] = + vResult.vector4_u32[3] = 0x80000000U; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_set1_epi32( 0x80000000 ); + return reinterpret_cast<__m128*>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return a floating point value via an index. This is not a recommended +// function to use due to performance loss. +XMFINLINE FLOAT XMVectorGetByIndex(FXMVECTOR V,UINT i) +{ + XMASSERT( i <= 3 ); +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_f32[i]; +#elif defined(_XM_SSE_INTRINSICS_) + return V.m128_f32[i]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return the X component in an FPU register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE FLOAT XMVectorGetX(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_f32[0]; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_MSC_VER) && (_MSC_VER>=1500) + return _mm_cvtss_f32(V); +#else + return V.m128_f32[0]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Return the Y component in an FPU register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE FLOAT XMVectorGetY(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_f32[1]; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_MSC_VER) && (_MSC_VER>=1500) + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + return _mm_cvtss_f32(vTemp); +#else + return V.m128_f32[1]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Return the Z component in an FPU register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE FLOAT XMVectorGetZ(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_f32[2]; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_MSC_VER) && (_MSC_VER>=1500) + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + return _mm_cvtss_f32(vTemp); +#else + return V.m128_f32[2]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Return the W component in an FPU register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE FLOAT XMVectorGetW(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_f32[3]; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_MSC_VER) && (_MSC_VER>=1500) + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,3,3,3)); + return _mm_cvtss_f32(vTemp); +#else + return V.m128_f32[3]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Store a component indexed by i into a 32 bit float location in memory. +// This causes Load/Hit/Store on VMX targets +XMFINLINE VOID XMVectorGetByIndexPtr(FLOAT *f,FXMVECTOR V,UINT i) +{ + XMASSERT( f != 0 ); + XMASSERT( i < 4 ); +#if defined(_XM_NO_INTRINSICS_) + *f = V.vector4_f32[i]; +#elif defined(_XM_SSE_INTRINSICS_) + *f = V.m128_f32[i]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Store the X component into a 32 bit float location in memory. +XMFINLINE VOID XMVectorGetXPtr(FLOAT *x,FXMVECTOR V) +{ + XMASSERT( x != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *x = V.vector4_f32[0]; +#elif defined(_XM_SSE_INTRINSICS_) + _mm_store_ss(x,V); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Store the Y component into a 32 bit float location in memory. +XMFINLINE VOID XMVectorGetYPtr(FLOAT *y,FXMVECTOR V) +{ + XMASSERT( y != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *y = V.vector4_f32[1]; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + _mm_store_ss(y,vResult); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Store the Z component into a 32 bit float location in memory. +XMFINLINE VOID XMVectorGetZPtr(FLOAT *z,FXMVECTOR V) +{ + XMASSERT( z != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *z = V.vector4_f32[2]; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + _mm_store_ss(z,vResult); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Store the W component into a 32 bit float location in memory. +XMFINLINE VOID XMVectorGetWPtr(FLOAT *w,FXMVECTOR V) +{ + XMASSERT( w != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *w = V.vector4_f32[3]; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,3,3,3)); + _mm_store_ss(w,vResult); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Return an integer value via an index. This is not a recommended +// function to use due to performance loss. +XMFINLINE UINT XMVectorGetIntByIndex(FXMVECTOR V, UINT i) +{ + XMASSERT( i < 4 ); +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_u32[i]; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_MSC_VER) && (_MSC_VER<1400) + XMVECTORU32 tmp; + tmp.v = V; + return tmp.u[i]; +#else + return V.m128_u32[i]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Return the X component in an integer register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE UINT XMVectorGetIntX(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_u32[0]; +#elif defined(_XM_SSE_INTRINSICS_) + return static_cast(_mm_cvtsi128_si32(reinterpret_cast(&V)[0])); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Return the Y component in an integer register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE UINT XMVectorGetIntY(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_u32[1]; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vResulti = _mm_shuffle_epi32(reinterpret_cast(&V)[0],_MM_SHUFFLE(1,1,1,1)); + return static_cast(_mm_cvtsi128_si32(vResulti)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Return the Z component in an integer register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE UINT XMVectorGetIntZ(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_u32[2]; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vResulti = _mm_shuffle_epi32(reinterpret_cast(&V)[0],_MM_SHUFFLE(2,2,2,2)); + return static_cast(_mm_cvtsi128_si32(vResulti)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Return the W component in an integer register. +// This causes Load/Hit/Store on VMX targets +XMFINLINE UINT XMVectorGetIntW(FXMVECTOR V) +{ +#if defined(_XM_NO_INTRINSICS_) + return V.vector4_u32[3]; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vResulti = _mm_shuffle_epi32(reinterpret_cast(&V)[0],_MM_SHUFFLE(3,3,3,3)); + return static_cast(_mm_cvtsi128_si32(vResulti)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Store a component indexed by i into a 32 bit integer location in memory. +// This causes Load/Hit/Store on VMX targets +XMFINLINE VOID XMVectorGetIntByIndexPtr(UINT *x,FXMVECTOR V,UINT i) +{ + XMASSERT( x != 0 ); + XMASSERT( i < 4 ); +#if defined(_XM_NO_INTRINSICS_) + *x = V.vector4_u32[i]; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_MSC_VER) && (_MSC_VER<1400) + XMVECTORU32 tmp; + tmp.v = V; + *x = tmp.u[i]; +#else + *x = V.m128_u32[i]; +#endif +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Store the X component into a 32 bit integer location in memory. +XMFINLINE VOID XMVectorGetIntXPtr(UINT *x,FXMVECTOR V) +{ + XMASSERT( x != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *x = V.vector4_u32[0]; +#elif defined(_XM_SSE_INTRINSICS_) + _mm_store_ss(reinterpret_cast(x),V); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Store the Y component into a 32 bit integer location in memory. +XMFINLINE VOID XMVectorGetIntYPtr(UINT *y,FXMVECTOR V) +{ + XMASSERT( y != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *y = V.vector4_u32[1]; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + _mm_store_ss(reinterpret_cast(y),vResult); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Store the Z component into a 32 bit integer locaCantion in memory. +XMFINLINE VOID XMVectorGetIntZPtr(UINT *z,FXMVECTOR V) +{ + XMASSERT( z != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *z = V.vector4_u32[2]; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + _mm_store_ss(reinterpret_cast(z),vResult); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Store the W component into a 32 bit integer location in memory. +XMFINLINE VOID XMVectorGetIntWPtr(UINT *w,FXMVECTOR V) +{ + XMASSERT( w != 0 ); +#if defined(_XM_NO_INTRINSICS_) + *w = V.vector4_u32[3]; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,3,3,3)); + _mm_store_ss(reinterpret_cast(w),vResult); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Set a single indexed floating point component +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetByIndex(FXMVECTOR V, FLOAT f,UINT i) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( i <= 3 ); + U = V; + U.vector4_f32[i] = f; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( i <= 3 ); + XMVECTOR U = V; + U.m128_f32[i] = f; + return U; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Sets the X component of a vector to a passed floating point value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetX(FXMVECTOR V, FLOAT x) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_f32[0] = x; + U.vector4_f32[1] = V.vector4_f32[1]; + U.vector4_f32[2] = V.vector4_f32[2]; + U.vector4_f32[3] = V.vector4_f32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_f32[0] = x; + return vResult; +#else + XMVECTOR vResult = _mm_set_ss(x); + vResult = _mm_move_ss(V,vResult); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the Y component of a vector to a passed floating point value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetY(FXMVECTOR V, FLOAT y) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_f32[0] = V.vector4_f32[0]; + U.vector4_f32[1] = y; + U.vector4_f32[2] = V.vector4_f32[2]; + U.vector4_f32[3] = V.vector4_f32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_f32[1] = y; + return vResult; +#else + // Swap y and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,2,0,1)); + // Convert input to vector + XMVECTOR vTemp = _mm_set_ss(y); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap y and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,2,0,1)); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} +// Sets the Z component of a vector to a passed floating point value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetZ(FXMVECTOR V, FLOAT z) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_f32[0] = V.vector4_f32[0]; + U.vector4_f32[1] = V.vector4_f32[1]; + U.vector4_f32[2] = z; + U.vector4_f32[3] = V.vector4_f32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_f32[2] = z; + return vResult; +#else + // Swap z and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,0,1,2)); + // Convert input to vector + XMVECTOR vTemp = _mm_set_ss(z); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap z and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,0,1,2)); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the W component of a vector to a passed floating point value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetW(FXMVECTOR V, FLOAT w) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_f32[0] = V.vector4_f32[0]; + U.vector4_f32[1] = V.vector4_f32[1]; + U.vector4_f32[2] = V.vector4_f32[2]; + U.vector4_f32[3] = w; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_f32[3] = w; + return vResult; +#else + // Swap w and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,2,1,3)); + // Convert input to vector + XMVECTOR vTemp = _mm_set_ss(w); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap w and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,2,1,3)); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Sets a component of a vector to a floating point value passed by pointer +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetByIndexPtr(FXMVECTOR V,CONST FLOAT *f,UINT i) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( f != 0 ); + XMASSERT( i <= 3 ); + U = V; + U.vector4_f32[i] = *f; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( f != 0 ); + XMASSERT( i <= 3 ); + XMVECTOR U = V; + U.m128_f32[i] = *f; + return U; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Sets the X component of a vector to a floating point value passed by pointer +XMFINLINE XMVECTOR XMVectorSetXPtr(FXMVECTOR V,CONST FLOAT *x) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( x != 0 ); + U.vector4_f32[0] = *x; + U.vector4_f32[1] = V.vector4_f32[1]; + U.vector4_f32[2] = V.vector4_f32[2]; + U.vector4_f32[3] = V.vector4_f32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( x != 0 ); + XMVECTOR vResult = _mm_load_ss(x); + vResult = _mm_move_ss(V,vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the Y component of a vector to a floating point value passed by pointer +XMFINLINE XMVECTOR XMVectorSetYPtr(FXMVECTOR V,CONST FLOAT *y) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( y != 0 ); + U.vector4_f32[0] = V.vector4_f32[0]; + U.vector4_f32[1] = *y; + U.vector4_f32[2] = V.vector4_f32[2]; + U.vector4_f32[3] = V.vector4_f32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( y != 0 ); + // Swap y and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,2,0,1)); + // Convert input to vector + XMVECTOR vTemp = _mm_load_ss(y); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap y and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,2,0,1)); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the Z component of a vector to a floating point value passed by pointer +XMFINLINE XMVECTOR XMVectorSetZPtr(FXMVECTOR V,CONST FLOAT *z) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( z != 0 ); + U.vector4_f32[0] = V.vector4_f32[0]; + U.vector4_f32[1] = V.vector4_f32[1]; + U.vector4_f32[2] = *z; + U.vector4_f32[3] = V.vector4_f32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( z != 0 ); + // Swap z and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,0,1,2)); + // Convert input to vector + XMVECTOR vTemp = _mm_load_ss(z); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap z and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,0,1,2)); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the W component of a vector to a floating point value passed by pointer +XMFINLINE XMVECTOR XMVectorSetWPtr(FXMVECTOR V,CONST FLOAT *w) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( w != 0 ); + U.vector4_f32[0] = V.vector4_f32[0]; + U.vector4_f32[1] = V.vector4_f32[1]; + U.vector4_f32[2] = V.vector4_f32[2]; + U.vector4_f32[3] = *w; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( w != 0 ); + // Swap w and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,2,1,3)); + // Convert input to vector + XMVECTOR vTemp = _mm_load_ss(w); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap w and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,2,1,3)); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Sets a component of a vector to an integer passed by value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetIntByIndex(FXMVECTOR V, UINT x, UINT i) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( i <= 3 ); + U = V; + U.vector4_u32[i] = x; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( i <= 3 ); + XMVECTORU32 tmp; + tmp.v = V; + tmp.u[i] = x; + return tmp; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Sets the X component of a vector to an integer passed by value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetIntX(FXMVECTOR V, UINT x) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_u32[0] = x; + U.vector4_u32[1] = V.vector4_u32[1]; + U.vector4_u32[2] = V.vector4_u32[2]; + U.vector4_u32[3] = V.vector4_u32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_i32[0] = x; + return vResult; +#else + __m128i vTemp = _mm_cvtsi32_si128(x); + XMVECTOR vResult = _mm_move_ss(V,reinterpret_cast(&vTemp)[0]); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the Y component of a vector to an integer passed by value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetIntY(FXMVECTOR V, UINT y) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_u32[0] = V.vector4_u32[0]; + U.vector4_u32[1] = y; + U.vector4_u32[2] = V.vector4_u32[2]; + U.vector4_u32[3] = V.vector4_u32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_i32[1] = y; + return vResult; +#else // Swap y and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,2,0,1)); + // Convert input to vector + __m128i vTemp = _mm_cvtsi32_si128(y); + // Replace the x component + vResult = _mm_move_ss(vResult,reinterpret_cast(&vTemp)[0]); + // Swap y and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,2,0,1)); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the Z component of a vector to an integer passed by value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetIntZ(FXMVECTOR V, UINT z) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_u32[0] = V.vector4_u32[0]; + U.vector4_u32[1] = V.vector4_u32[1]; + U.vector4_u32[2] = z; + U.vector4_u32[3] = V.vector4_u32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_i32[2] = z; + return vResult; +#else + // Swap z and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,0,1,2)); + // Convert input to vector + __m128i vTemp = _mm_cvtsi32_si128(z); + // Replace the x component + vResult = _mm_move_ss(vResult,reinterpret_cast(&vTemp)[0]); + // Swap z and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,0,1,2)); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the W component of a vector to an integer passed by value +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetIntW(FXMVECTOR V, UINT w) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + U.vector4_u32[0] = V.vector4_u32[0]; + U.vector4_u32[1] = V.vector4_u32[1]; + U.vector4_u32[2] = V.vector4_u32[2]; + U.vector4_u32[3] = w; + return U; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_XM_ISVS2005_) + XMVECTOR vResult = V; + vResult.m128_i32[3] = w; + return vResult; +#else + // Swap w and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,2,1,3)); + // Convert input to vector + __m128i vTemp = _mm_cvtsi32_si128(w); + // Replace the x component + vResult = _mm_move_ss(vResult,reinterpret_cast(&vTemp)[0]); + // Swap w and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,2,1,3)); + return vResult; +#endif // _XM_ISVS2005_ +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Sets a component of a vector to an integer value passed by pointer +// This causes Load/Hit/Store on VMX targets +XMFINLINE XMVECTOR XMVectorSetIntByIndexPtr(FXMVECTOR V, CONST UINT *x,UINT i) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( x != 0 ); + XMASSERT( i <= 3 ); + U = V; + U.vector4_u32[i] = *x; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( x != 0 ); + XMASSERT( i <= 3 ); + XMVECTORU32 tmp; + tmp.v = V; + tmp.u[i] = *x; + return tmp; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Sets the X component of a vector to an integer value passed by pointer +XMFINLINE XMVECTOR XMVectorSetIntXPtr(FXMVECTOR V,CONST UINT *x) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( x != 0 ); + U.vector4_u32[0] = *x; + U.vector4_u32[1] = V.vector4_u32[1]; + U.vector4_u32[2] = V.vector4_u32[2]; + U.vector4_u32[3] = V.vector4_u32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( x != 0 ); + XMVECTOR vTemp = _mm_load_ss(reinterpret_cast(x)); + XMVECTOR vResult = _mm_move_ss(V,vTemp); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the Y component of a vector to an integer value passed by pointer +XMFINLINE XMVECTOR XMVectorSetIntYPtr(FXMVECTOR V,CONST UINT *y) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( y != 0 ); + U.vector4_u32[0] = V.vector4_u32[0]; + U.vector4_u32[1] = *y; + U.vector4_u32[2] = V.vector4_u32[2]; + U.vector4_u32[3] = V.vector4_u32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( y != 0 ); + // Swap y and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,2,0,1)); + // Convert input to vector + XMVECTOR vTemp = _mm_load_ss(reinterpret_cast(y)); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap y and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,2,0,1)); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the Z component of a vector to an integer value passed by pointer +XMFINLINE XMVECTOR XMVectorSetIntZPtr(FXMVECTOR V,CONST UINT *z) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( z != 0 ); + U.vector4_u32[0] = V.vector4_u32[0]; + U.vector4_u32[1] = V.vector4_u32[1]; + U.vector4_u32[2] = *z; + U.vector4_u32[3] = V.vector4_u32[3]; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( z != 0 ); + // Swap z and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,0,1,2)); + // Convert input to vector + XMVECTOR vTemp = _mm_load_ss(reinterpret_cast(z)); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap z and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,0,1,2)); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +// Sets the W component of a vector to an integer value passed by pointer +XMFINLINE XMVECTOR XMVectorSetIntWPtr(FXMVECTOR V,CONST UINT *w) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR U; + XMASSERT( w != 0 ); + U.vector4_u32[0] = V.vector4_u32[0]; + U.vector4_u32[1] = V.vector4_u32[1]; + U.vector4_u32[2] = V.vector4_u32[2]; + U.vector4_u32[3] = *w; + return U; +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( w != 0 ); + // Swap w and x + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,2,1,3)); + // Convert input to vector + XMVECTOR vTemp = _mm_load_ss(reinterpret_cast(w)); + // Replace the x component + vResult = _mm_move_ss(vResult,vTemp); + // Swap w and x again + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,2,1,3)); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Define a control vector to be used in XMVectorPermute +// operations. Visualize the two vectors V1 and V2 given +// in a permute as arranged back to back in a linear fashion, +// such that they form an array of 8 floating point values. +// The four integers specified in XMVectorPermuteControl +// will serve as indices into the array to select components +// from the two vectors. ElementIndex0 is used to select +// an element from the vectors to be placed in the first +// component of the resulting vector, ElementIndex1 is used +// to select an element for the second component, etc. + +XMFINLINE XMVECTOR XMVectorPermuteControl +( + UINT ElementIndex0, + UINT ElementIndex1, + UINT ElementIndex2, + UINT ElementIndex3 +) +{ +#if defined(_XM_SSE_INTRINSICS_) || defined(_XM_NO_INTRINSICS_) + XMVECTORU32 vControl; + static CONST UINT ControlElement[] = { + XM_PERMUTE_0X, + XM_PERMUTE_0Y, + XM_PERMUTE_0Z, + XM_PERMUTE_0W, + XM_PERMUTE_1X, + XM_PERMUTE_1Y, + XM_PERMUTE_1Z, + XM_PERMUTE_1W + }; + XMASSERT(ElementIndex0 < 8); + XMASSERT(ElementIndex1 < 8); + XMASSERT(ElementIndex2 < 8); + XMASSERT(ElementIndex3 < 8); + + vControl.u[0] = ControlElement[ElementIndex0]; + vControl.u[1] = ControlElement[ElementIndex1]; + vControl.u[2] = ControlElement[ElementIndex2]; + vControl.u[3] = ControlElement[ElementIndex3]; + return vControl.v; +#else +#endif +} + +//------------------------------------------------------------------------------ + +// Using a control vector made up of 16 bytes from 0-31, remap V1 and V2's byte +// entries into a single 16 byte vector and return it. Index 0-15 = V1, +// 16-31 = V2 +XMFINLINE XMVECTOR XMVectorPermute +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR Control +) +{ +#if defined(_XM_NO_INTRINSICS_) + const BYTE *aByte[2]; + XMVECTOR Result; + UINT i, uIndex, VectorIndex; + const BYTE *pControl; + BYTE *pWork; + + // Indices must be in range from 0 to 31 + XMASSERT((Control.vector4_u32[0] & 0xE0E0E0E0) == 0); + XMASSERT((Control.vector4_u32[1] & 0xE0E0E0E0) == 0); + XMASSERT((Control.vector4_u32[2] & 0xE0E0E0E0) == 0); + XMASSERT((Control.vector4_u32[3] & 0xE0E0E0E0) == 0); + + // 0-15 = V1, 16-31 = V2 + aByte[0] = (const BYTE*)(&V1); + aByte[1] = (const BYTE*)(&V2); + i = 16; + pControl = (const BYTE *)(&Control); + pWork = (BYTE *)(&Result); + do { + // Get the byte to map from + uIndex = pControl[0]; + ++pControl; + VectorIndex = (uIndex>>4)&1; + uIndex &= 0x0F; +#if defined(_XM_LITTLEENDIAN_) + uIndex ^= 3; // Swap byte ordering on little endian machines +#endif + pWork[0] = aByte[VectorIndex][uIndex]; + ++pWork; + } while (--i); + return Result; +#elif defined(_XM_SSE_INTRINSICS_) +#if defined(_PREFAST_) || defined(XMDEBUG) + // Indices must be in range from 0 to 31 + static const XMVECTORI32 PremuteTest = {0xE0E0E0E0,0xE0E0E0E0,0xE0E0E0E0,0xE0E0E0E0}; + XMVECTOR vAssert = _mm_and_ps(Control,PremuteTest); + __m128i vAsserti = _mm_cmpeq_epi32(reinterpret_cast(&vAssert)[0],g_XMZero); + XMASSERT(_mm_movemask_ps(*reinterpret_cast(&vAsserti)) == 0xf); +#endif + // Store the vectors onto local memory on the stack + XMVECTOR Array[2]; + Array[0] = V1; + Array[1] = V2; + // Output vector, on the stack + XMVECTORU8 vResult; + // Get pointer to the two vectors on the stack + const BYTE *pInput = reinterpret_cast(Array); + // Store the Control vector on the stack to access the bytes + // don't use Control, it can cause a register variable to spill on the stack. + XMVECTORU8 vControl; + vControl.v = Control; // Write to memory + UINT i = 0; + do { + UINT ComponentIndex = vControl.u[i] & 0x1FU; + ComponentIndex ^= 3; // Swap byte ordering + vResult.u[i] = pInput[ComponentIndex]; + } while (++i<16); + return vResult; +#else // _XM_SSE_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Define a control vector to be used in XMVectorSelect +// operations. The four integers specified in XMVectorSelectControl +// serve as indices to select between components in two vectors. +// The first index controls selection for the first component of +// the vectors involved in a select operation, the second index +// controls selection for the second component etc. A value of +// zero for an index causes the corresponding component from the first +// vector to be selected whereas a one causes the component from the +// second vector to be selected instead. + +XMFINLINE XMVECTOR XMVectorSelectControl +( + UINT VectorIndex0, + UINT VectorIndex1, + UINT VectorIndex2, + UINT VectorIndex3 +) +{ +#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_) + // x=Index0,y=Index1,z=Index2,w=Index3 + __m128i vTemp = _mm_set_epi32(VectorIndex3,VectorIndex2,VectorIndex1,VectorIndex0); + // Any non-zero entries become 0xFFFFFFFF else 0 + vTemp = _mm_cmpgt_epi32(vTemp,g_XMZero); + return reinterpret_cast<__m128 *>(&vTemp)[0]; +#else + XMVECTOR ControlVector; + CONST UINT ControlElement[] = + { + XM_SELECT_0, + XM_SELECT_1 + }; + + XMASSERT(VectorIndex0 < 2); + XMASSERT(VectorIndex1 < 2); + XMASSERT(VectorIndex2 < 2); + XMASSERT(VectorIndex3 < 2); + + ControlVector.vector4_u32[0] = ControlElement[VectorIndex0]; + ControlVector.vector4_u32[1] = ControlElement[VectorIndex1]; + ControlVector.vector4_u32[2] = ControlElement[VectorIndex2]; + ControlVector.vector4_u32[3] = ControlElement[VectorIndex3]; + + return ControlVector; + +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSelect +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR Control +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = (V1.vector4_u32[0] & ~Control.vector4_u32[0]) | (V2.vector4_u32[0] & Control.vector4_u32[0]); + Result.vector4_u32[1] = (V1.vector4_u32[1] & ~Control.vector4_u32[1]) | (V2.vector4_u32[1] & Control.vector4_u32[1]); + Result.vector4_u32[2] = (V1.vector4_u32[2] & ~Control.vector4_u32[2]) | (V2.vector4_u32[2] & Control.vector4_u32[2]); + Result.vector4_u32[3] = (V1.vector4_u32[3] & ~Control.vector4_u32[3]) | (V2.vector4_u32[3] & Control.vector4_u32[3]); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp1 = _mm_andnot_ps(Control,V1); + XMVECTOR vTemp2 = _mm_and_ps(V2,Control); + return _mm_or_ps(vTemp1,vTemp2); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorMergeXY +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = V1.vector4_u32[0]; + Result.vector4_u32[1] = V2.vector4_u32[0]; + Result.vector4_u32[2] = V1.vector4_u32[1]; + Result.vector4_u32[3] = V2.vector4_u32[1]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_unpacklo_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorMergeZW +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = V1.vector4_u32[2]; + Result.vector4_u32[1] = V2.vector4_u32[2]; + Result.vector4_u32[2] = V1.vector4_u32[3]; + Result.vector4_u32[3] = V2.vector4_u32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_unpackhi_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + + Control.vector4_u32[0] = (V1.vector4_f32[0] == V2.vector4_f32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V1.vector4_f32[1] == V2.vector4_f32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V1.vector4_f32[2] == V2.vector4_f32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V1.vector4_f32[3] == V2.vector4_f32[3]) ? 0xFFFFFFFF : 0; + + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_cmpeq_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorEqualR +( + UINT* pCR, + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ux, uy, uz, uw, CR; + XMVECTOR Control; + + XMASSERT( pCR ); + + ux = (V1.vector4_f32[0] == V2.vector4_f32[0]) ? 0xFFFFFFFFU : 0; + uy = (V1.vector4_f32[1] == V2.vector4_f32[1]) ? 0xFFFFFFFFU : 0; + uz = (V1.vector4_f32[2] == V2.vector4_f32[2]) ? 0xFFFFFFFFU : 0; + uw = (V1.vector4_f32[3] == V2.vector4_f32[3]) ? 0xFFFFFFFFU : 0; + CR = 0; + if (ux&uy&uz&uw) + { + // All elements are greater + CR = XM_CRMASK_CR6TRUE; + } + else if (!(ux|uy|uz|uw)) + { + // All elements are not greater + CR = XM_CRMASK_CR6FALSE; + } + *pCR = CR; + Control.vector4_u32[0] = ux; + Control.vector4_u32[1] = uy; + Control.vector4_u32[2] = uz; + Control.vector4_u32[3] = uw; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( pCR ); + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); + UINT CR = 0; + int iTest = _mm_movemask_ps(vTemp); + if (iTest==0xf) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + // All elements are not greater + CR = XM_CRMASK_CR6FALSE; + } + *pCR = CR; + return vTemp; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Treat the components of the vectors as unsigned integers and +// compare individual bits between the two. This is useful for +// comparing control vectors and result vectors returned from +// other comparison operations. + +XMFINLINE XMVECTOR XMVectorEqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + + Control.vector4_u32[0] = (V1.vector4_u32[0] == V2.vector4_u32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V1.vector4_u32[1] == V2.vector4_u32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V1.vector4_u32[2] == V2.vector4_u32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V1.vector4_u32[3] == V2.vector4_u32[3]) ? 0xFFFFFFFF : 0; + + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_cmpeq_epi32( reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0] ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorEqualIntR +( + UINT* pCR, + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + + XMASSERT(pCR); + + Control = XMVectorEqualInt(V1, V2); + + *pCR = 0; + + if (XMVector4EqualInt(Control, XMVectorTrueInt())) + { + // All elements are equal + *pCR |= XM_CRMASK_CR6TRUE; + } + else if (XMVector4EqualInt(Control, XMVectorFalseInt())) + { + // All elements are not equal + *pCR |= XM_CRMASK_CR6FALSE; + } + + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pCR); + __m128i V = _mm_cmpeq_epi32( reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0] ); + int iTemp = _mm_movemask_ps(reinterpret_cast(&V)[0]); + UINT CR = 0; + if (iTemp==0x0F) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTemp) + { + CR = XM_CRMASK_CR6FALSE; + } + *pCR = CR; + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorNearEqual +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR Epsilon +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT fDeltax, fDeltay, fDeltaz, fDeltaw; + XMVECTOR Control; + + fDeltax = V1.vector4_f32[0]-V2.vector4_f32[0]; + fDeltay = V1.vector4_f32[1]-V2.vector4_f32[1]; + fDeltaz = V1.vector4_f32[2]-V2.vector4_f32[2]; + fDeltaw = V1.vector4_f32[3]-V2.vector4_f32[3]; + + fDeltax = fabsf(fDeltax); + fDeltay = fabsf(fDeltay); + fDeltaz = fabsf(fDeltaz); + fDeltaw = fabsf(fDeltaw); + + Control.vector4_u32[0] = (fDeltax <= Epsilon.vector4_f32[0]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[1] = (fDeltay <= Epsilon.vector4_f32[1]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[2] = (fDeltaz <= Epsilon.vector4_f32[2]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[3] = (fDeltaw <= Epsilon.vector4_f32[3]) ? 0xFFFFFFFFU : 0; + + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + // Get the difference + XMVECTOR vDelta = _mm_sub_ps(V1,V2); + // Get the absolute value of the difference + XMVECTOR vTemp = _mm_setzero_ps(); + vTemp = _mm_sub_ps(vTemp,vDelta); + vTemp = _mm_max_ps(vTemp,vDelta); + vTemp = _mm_cmple_ps(vTemp,Epsilon); + return vTemp; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorNotEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = (V1.vector4_f32[0] != V2.vector4_f32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V1.vector4_f32[1] != V2.vector4_f32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V1.vector4_f32[2] != V2.vector4_f32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V1.vector4_f32[3] != V2.vector4_f32[3]) ? 0xFFFFFFFF : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_cmpneq_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorNotEqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = (V1.vector4_u32[0] != V2.vector4_u32[0]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[1] = (V1.vector4_u32[1] != V2.vector4_u32[1]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[2] = (V1.vector4_u32[2] != V2.vector4_u32[2]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[3] = (V1.vector4_u32[3] != V2.vector4_u32[3]) ? 0xFFFFFFFFU : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_cmpeq_epi32( reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0] ); + return _mm_xor_ps(reinterpret_cast<__m128 *>(&V)[0],g_XMNegOneMask); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorGreater +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = (V1.vector4_f32[0] > V2.vector4_f32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V1.vector4_f32[1] > V2.vector4_f32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V1.vector4_f32[2] > V2.vector4_f32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V1.vector4_f32[3] > V2.vector4_f32[3]) ? 0xFFFFFFFF : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_cmpgt_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorGreaterR +( + UINT* pCR, + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ux, uy, uz, uw, CR; + XMVECTOR Control; + + XMASSERT( pCR ); + + ux = (V1.vector4_f32[0] > V2.vector4_f32[0]) ? 0xFFFFFFFFU : 0; + uy = (V1.vector4_f32[1] > V2.vector4_f32[1]) ? 0xFFFFFFFFU : 0; + uz = (V1.vector4_f32[2] > V2.vector4_f32[2]) ? 0xFFFFFFFFU : 0; + uw = (V1.vector4_f32[3] > V2.vector4_f32[3]) ? 0xFFFFFFFFU : 0; + CR = 0; + if (ux&uy&uz&uw) + { + // All elements are greater + CR = XM_CRMASK_CR6TRUE; + } + else if (!(ux|uy|uz|uw)) + { + // All elements are not greater + CR = XM_CRMASK_CR6FALSE; + } + *pCR = CR; + Control.vector4_u32[0] = ux; + Control.vector4_u32[1] = uy; + Control.vector4_u32[2] = uz; + Control.vector4_u32[3] = uw; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( pCR ); + XMVECTOR vTemp = _mm_cmpgt_ps(V1,V2); + UINT CR = 0; + int iTest = _mm_movemask_ps(vTemp); + if (iTest==0xf) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + // All elements are not greater + CR = XM_CRMASK_CR6FALSE; + } + *pCR = CR; + return vTemp; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorGreaterOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = (V1.vector4_f32[0] >= V2.vector4_f32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V1.vector4_f32[1] >= V2.vector4_f32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V1.vector4_f32[2] >= V2.vector4_f32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V1.vector4_f32[3] >= V2.vector4_f32[3]) ? 0xFFFFFFFF : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_cmpge_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorGreaterOrEqualR +( + UINT* pCR, + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ux, uy, uz, uw, CR; + XMVECTOR Control; + + XMASSERT( pCR ); + + ux = (V1.vector4_f32[0] >= V2.vector4_f32[0]) ? 0xFFFFFFFFU : 0; + uy = (V1.vector4_f32[1] >= V2.vector4_f32[1]) ? 0xFFFFFFFFU : 0; + uz = (V1.vector4_f32[2] >= V2.vector4_f32[2]) ? 0xFFFFFFFFU : 0; + uw = (V1.vector4_f32[3] >= V2.vector4_f32[3]) ? 0xFFFFFFFFU : 0; + CR = 0; + if (ux&uy&uz&uw) + { + // All elements are greater + CR = XM_CRMASK_CR6TRUE; + } + else if (!(ux|uy|uz|uw)) + { + // All elements are not greater + CR = XM_CRMASK_CR6FALSE; + } + *pCR = CR; + Control.vector4_u32[0] = ux; + Control.vector4_u32[1] = uy; + Control.vector4_u32[2] = uz; + Control.vector4_u32[3] = uw; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( pCR ); + XMVECTOR vTemp = _mm_cmpge_ps(V1,V2); + UINT CR = 0; + int iTest = _mm_movemask_ps(vTemp); + if (iTest==0xf) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + // All elements are not greater + CR = XM_CRMASK_CR6FALSE; + } + *pCR = CR; + return vTemp; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorLess +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = (V1.vector4_f32[0] < V2.vector4_f32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V1.vector4_f32[1] < V2.vector4_f32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V1.vector4_f32[2] < V2.vector4_f32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V1.vector4_f32[3] < V2.vector4_f32[3]) ? 0xFFFFFFFF : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_cmplt_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorLessOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = (V1.vector4_f32[0] <= V2.vector4_f32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V1.vector4_f32[1] <= V2.vector4_f32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V1.vector4_f32[2] <= V2.vector4_f32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V1.vector4_f32[3] <= V2.vector4_f32[3]) ? 0xFFFFFFFF : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_cmple_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorInBounds +( + FXMVECTOR V, + FXMVECTOR Bounds +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = (V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[1] = (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[2] = (V.vector4_f32[2] <= Bounds.vector4_f32[2] && V.vector4_f32[2] >= -Bounds.vector4_f32[2]) ? 0xFFFFFFFF : 0; + Control.vector4_u32[3] = (V.vector4_f32[3] <= Bounds.vector4_f32[3] && V.vector4_f32[3] >= -Bounds.vector4_f32[3]) ? 0xFFFFFFFF : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + return vTemp1; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorInBoundsR +( + UINT* pCR, + FXMVECTOR V, + FXMVECTOR Bounds +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT ux, uy, uz, uw, CR; + XMVECTOR Control; + + XMASSERT( pCR != 0 ); + + ux = (V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) ? 0xFFFFFFFFU : 0; + uy = (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1]) ? 0xFFFFFFFFU : 0; + uz = (V.vector4_f32[2] <= Bounds.vector4_f32[2] && V.vector4_f32[2] >= -Bounds.vector4_f32[2]) ? 0xFFFFFFFFU : 0; + uw = (V.vector4_f32[3] <= Bounds.vector4_f32[3] && V.vector4_f32[3] >= -Bounds.vector4_f32[3]) ? 0xFFFFFFFFU : 0; + + CR = 0; + + if (ux&uy&uz&uw) + { + // All elements are in bounds + CR = XM_CRMASK_CR6BOUNDS; + } + *pCR = CR; + Control.vector4_u32[0] = ux; + Control.vector4_u32[1] = uy; + Control.vector4_u32[2] = uz; + Control.vector4_u32[3] = uw; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT( pCR != 0 ); + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + + UINT CR = 0; + if (_mm_movemask_ps(vTemp1)==0xf) { + // All elements are in bounds + CR = XM_CRMASK_CR6BOUNDS; + } + *pCR = CR; + return vTemp1; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorIsNaN +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = XMISNAN(V.vector4_f32[0]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[1] = XMISNAN(V.vector4_f32[1]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[2] = XMISNAN(V.vector4_f32[2]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[3] = XMISNAN(V.vector4_f32[3]) ? 0xFFFFFFFFU : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the exponent + __m128i vTempInf = _mm_and_si128(reinterpret_cast(&V)[0],g_XMInfinity); + // Mask off the mantissa + __m128i vTempNan = _mm_and_si128(reinterpret_cast(&V)[0],g_XMQNaNTest); + // Are any of the exponents == 0x7F800000? + vTempInf = _mm_cmpeq_epi32(vTempInf,g_XMInfinity); + // Are any of the mantissa's zero? (SSE2 doesn't have a neq test) + vTempNan = _mm_cmpeq_epi32(vTempNan,g_XMZero); + // Perform a not on the NaN test to be true on NON-zero mantissas + vTempNan = _mm_andnot_si128(vTempNan,vTempInf); + // If any are NaN, the signs are true after the merge above + return reinterpret_cast(&vTempNan)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorIsInfinite +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Control; + Control.vector4_u32[0] = XMISINF(V.vector4_f32[0]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[1] = XMISINF(V.vector4_f32[1]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[2] = XMISINF(V.vector4_f32[2]) ? 0xFFFFFFFFU : 0; + Control.vector4_u32[3] = XMISINF(V.vector4_f32[3]) ? 0xFFFFFFFFU : 0; + return Control; + +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the sign bit + __m128 vTemp = _mm_and_ps(V,g_XMAbsMask); + // Compare to infinity + vTemp = _mm_cmpeq_ps(vTemp,g_XMInfinity); + // If any are infinity, the signs are true. + return vTemp; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Rounding and clamping operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorMin +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result.vector4_f32[0] = (V1.vector4_f32[0] < V2.vector4_f32[0]) ? V1.vector4_f32[0] : V2.vector4_f32[0]; + Result.vector4_f32[1] = (V1.vector4_f32[1] < V2.vector4_f32[1]) ? V1.vector4_f32[1] : V2.vector4_f32[1]; + Result.vector4_f32[2] = (V1.vector4_f32[2] < V2.vector4_f32[2]) ? V1.vector4_f32[2] : V2.vector4_f32[2]; + Result.vector4_f32[3] = (V1.vector4_f32[3] < V2.vector4_f32[3]) ? V1.vector4_f32[3] : V2.vector4_f32[3]; + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_min_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorMax +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result.vector4_f32[0] = (V1.vector4_f32[0] > V2.vector4_f32[0]) ? V1.vector4_f32[0] : V2.vector4_f32[0]; + Result.vector4_f32[1] = (V1.vector4_f32[1] > V2.vector4_f32[1]) ? V1.vector4_f32[1] : V2.vector4_f32[1]; + Result.vector4_f32[2] = (V1.vector4_f32[2] > V2.vector4_f32[2]) ? V1.vector4_f32[2] : V2.vector4_f32[2]; + Result.vector4_f32[3] = (V1.vector4_f32[3] > V2.vector4_f32[3]) ? V1.vector4_f32[3] : V2.vector4_f32[3]; + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_max_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorRound +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + XMVECTOR Bias; + CONST XMVECTOR Zero = XMVectorZero(); + CONST XMVECTOR BiasPos = XMVectorReplicate(0.5f); + CONST XMVECTOR BiasNeg = XMVectorReplicate(-0.5f); + + Bias = XMVectorLess(V, Zero); + Bias = XMVectorSelect(BiasPos, BiasNeg, Bias); + Result = XMVectorAdd(V, Bias); + Result = XMVectorTruncate(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // To handle NAN, INF and numbers greater than 8388608, use masking + // Get the abs value + __m128i vTest = _mm_and_si128(reinterpret_cast(&V)[0],g_XMAbsMask); + // Test for greater than 8388608 (All floats with NO fractionals, NAN and INF + vTest = _mm_cmplt_epi32(vTest,g_XMNoFraction); + // Convert to int and back to float for rounding + __m128i vInt = _mm_cvtps_epi32(V); + // Convert back to floats + XMVECTOR vResult = _mm_cvtepi32_ps(vInt); + // All numbers less than 8388608 will use the round to int + vResult = _mm_and_ps(vResult,reinterpret_cast(&vTest)[0]); + // All others, use the ORIGINAL value + vTest = _mm_andnot_si128(vTest,reinterpret_cast(&V)[0]); + vResult = _mm_or_ps(vResult,reinterpret_cast(&vTest)[0]); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorTruncate +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Result; + UINT i; + + // Avoid C4701 + Result.vector4_f32[0] = 0.0f; + + for (i = 0; i < 4; i++) + { + if (XMISNAN(V.vector4_f32[i])) + { + Result.vector4_u32[i] = 0x7FC00000; + } + else if (fabsf(V.vector4_f32[i]) < 8388608.0f) + { + Result.vector4_f32[i] = (FLOAT)((INT)V.vector4_f32[i]); + } + else + { + Result.vector4_f32[i] = V.vector4_f32[i]; + } + } + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // To handle NAN, INF and numbers greater than 8388608, use masking + // Get the abs value + __m128i vTest = _mm_and_si128(reinterpret_cast(&V)[0],g_XMAbsMask); + // Test for greater than 8388608 (All floats with NO fractionals, NAN and INF + vTest = _mm_cmplt_epi32(vTest,g_XMNoFraction); + // Convert to int and back to float for rounding with truncation + __m128i vInt = _mm_cvttps_epi32(V); + // Convert back to floats + XMVECTOR vResult = _mm_cvtepi32_ps(vInt); + // All numbers less than 8388608 will use the round to int + vResult = _mm_and_ps(vResult,reinterpret_cast(&vTest)[0]); + // All others, use the ORIGINAL value + vTest = _mm_andnot_si128(vTest,reinterpret_cast(&V)[0]); + vResult = _mm_or_ps(vResult,reinterpret_cast(&vTest)[0]); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorFloor +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR vResult = { + floorf(V.vector4_f32[0]), + floorf(V.vector4_f32[1]), + floorf(V.vector4_f32[2]), + floorf(V.vector4_f32[3]) + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_sub_ps(V,g_XMOneHalfMinusEpsilon); + __m128i vInt = _mm_cvtps_epi32(vResult); + vResult = _mm_cvtepi32_ps(vInt); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorCeiling +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult = { + ceilf(V.vector4_f32[0]), + ceilf(V.vector4_f32[1]), + ceilf(V.vector4_f32[2]), + ceilf(V.vector4_f32[3]) + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_add_ps(V,g_XMOneHalfMinusEpsilon); + __m128i vInt = _mm_cvtps_epi32(vResult); + vResult = _mm_cvtepi32_ps(vInt); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorClamp +( + FXMVECTOR V, + FXMVECTOR Min, + FXMVECTOR Max +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + XMASSERT(XMVector4LessOrEqual(Min, Max)); + + Result = XMVectorMax(Min, V); + Result = XMVectorMin(Max, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult; + XMASSERT(XMVector4LessOrEqual(Min, Max)); + vResult = _mm_max_ps(Min,V); + vResult = _mm_min_ps(vResult,Max); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSaturate +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + CONST XMVECTOR Zero = XMVectorZero(); + + return XMVectorClamp(V, Zero, g_XMOne.v); + +#elif defined(_XM_SSE_INTRINSICS_) + // Set <0 to 0 + XMVECTOR vResult = _mm_max_ps(V,g_XMZero); + // Set>1 to 1 + return _mm_min_ps(vResult,g_XMOne); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Bitwise logical operations +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorAndInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = V1.vector4_u32[0] & V2.vector4_u32[0]; + Result.vector4_u32[1] = V1.vector4_u32[1] & V2.vector4_u32[1]; + Result.vector4_u32[2] = V1.vector4_u32[2] & V2.vector4_u32[2]; + Result.vector4_u32[3] = V1.vector4_u32[3] & V2.vector4_u32[3]; + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_and_ps(V1,V2); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorAndCInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = V1.vector4_u32[0] & ~V2.vector4_u32[0]; + Result.vector4_u32[1] = V1.vector4_u32[1] & ~V2.vector4_u32[1]; + Result.vector4_u32[2] = V1.vector4_u32[2] & ~V2.vector4_u32[2]; + Result.vector4_u32[3] = V1.vector4_u32[3] & ~V2.vector4_u32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_andnot_si128( reinterpret_cast(&V2)[0], reinterpret_cast(&V1)[0] ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorOrInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = V1.vector4_u32[0] | V2.vector4_u32[0]; + Result.vector4_u32[1] = V1.vector4_u32[1] | V2.vector4_u32[1]; + Result.vector4_u32[2] = V1.vector4_u32[2] | V2.vector4_u32[2]; + Result.vector4_u32[3] = V1.vector4_u32[3] | V2.vector4_u32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_or_si128( reinterpret_cast(&V1)[0], reinterpret_cast(&V2)[0] ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorNorInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = ~(V1.vector4_u32[0] | V2.vector4_u32[0]); + Result.vector4_u32[1] = ~(V1.vector4_u32[1] | V2.vector4_u32[1]); + Result.vector4_u32[2] = ~(V1.vector4_u32[2] | V2.vector4_u32[2]); + Result.vector4_u32[3] = ~(V1.vector4_u32[3] | V2.vector4_u32[3]); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i Result; + Result = _mm_or_si128( reinterpret_cast(&V1)[0], reinterpret_cast(&V2)[0] ); + Result = _mm_andnot_si128( Result,g_XMNegOneMask); + return reinterpret_cast<__m128 *>(&Result)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorXorInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_u32[0] = V1.vector4_u32[0] ^ V2.vector4_u32[0]; + Result.vector4_u32[1] = V1.vector4_u32[1] ^ V2.vector4_u32[1]; + Result.vector4_u32[2] = V1.vector4_u32[2] ^ V2.vector4_u32[2]; + Result.vector4_u32[3] = V1.vector4_u32[3] ^ V2.vector4_u32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i V = _mm_xor_si128( reinterpret_cast(&V1)[0], reinterpret_cast(&V2)[0] ); + return reinterpret_cast<__m128 *>(&V)[0]; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorNegate +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_f32[0] = -V.vector4_f32[0]; + Result.vector4_f32[1] = -V.vector4_f32[1]; + Result.vector4_f32[2] = -V.vector4_f32[2]; + Result.vector4_f32[3] = -V.vector4_f32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Z; + + Z = _mm_setzero_ps(); + + return _mm_sub_ps( Z, V ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorAdd +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_f32[0] = V1.vector4_f32[0] + V2.vector4_f32[0]; + Result.vector4_f32[1] = V1.vector4_f32[1] + V2.vector4_f32[1]; + Result.vector4_f32[2] = V1.vector4_f32[2] + V2.vector4_f32[2]; + Result.vector4_f32[3] = V1.vector4_f32[3] + V2.vector4_f32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_add_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorAddAngles +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Mask; + XMVECTOR Offset; + XMVECTOR Result; + CONST XMVECTOR Zero = XMVectorZero(); + + // Add the given angles together. If the range of V1 is such + // that -Pi <= V1 < Pi and the range of V2 is such that + // -2Pi <= V2 <= 2Pi, then the range of the resulting angle + // will be -Pi <= Result < Pi. + Result = XMVectorAdd(V1, V2); + + Mask = XMVectorLess(Result, g_XMNegativePi.v); + Offset = XMVectorSelect(Zero, g_XMTwoPi.v, Mask); + + Mask = XMVectorGreaterOrEqual(Result, g_XMPi.v); + Offset = XMVectorSelect(Offset, g_XMNegativeTwoPi.v, Mask); + + Result = XMVectorAdd(Result, Offset); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Adjust the angles + XMVECTOR vResult = _mm_add_ps(V1,V2); + // Less than Pi? + XMVECTOR vOffset = _mm_cmplt_ps(vResult,g_XMNegativePi); + vOffset = _mm_and_ps(vOffset,g_XMTwoPi); + // Add 2Pi to all entries less than -Pi + vResult = _mm_add_ps(vResult,vOffset); + // Greater than or equal to Pi? + vOffset = _mm_cmpge_ps(vResult,g_XMPi); + vOffset = _mm_and_ps(vOffset,g_XMTwoPi); + // Sub 2Pi to all entries greater than Pi + vResult = _mm_sub_ps(vResult,vOffset); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSubtract +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_f32[0] = V1.vector4_f32[0] - V2.vector4_f32[0]; + Result.vector4_f32[1] = V1.vector4_f32[1] - V2.vector4_f32[1]; + Result.vector4_f32[2] = V1.vector4_f32[2] - V2.vector4_f32[2]; + Result.vector4_f32[3] = V1.vector4_f32[3] - V2.vector4_f32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_sub_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSubtractAngles +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Mask; + XMVECTOR Offset; + XMVECTOR Result; + CONST XMVECTOR Zero = XMVectorZero(); + + // Subtract the given angles. If the range of V1 is such + // that -Pi <= V1 < Pi and the range of V2 is such that + // -2Pi <= V2 <= 2Pi, then the range of the resulting angle + // will be -Pi <= Result < Pi. + Result = XMVectorSubtract(V1, V2); + + Mask = XMVectorLess(Result, g_XMNegativePi.v); + Offset = XMVectorSelect(Zero, g_XMTwoPi.v, Mask); + + Mask = XMVectorGreaterOrEqual(Result, g_XMPi.v); + Offset = XMVectorSelect(Offset, g_XMNegativeTwoPi.v, Mask); + + Result = XMVectorAdd(Result, Offset); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Adjust the angles + XMVECTOR vResult = _mm_sub_ps(V1,V2); + // Less than Pi? + XMVECTOR vOffset = _mm_cmplt_ps(vResult,g_XMNegativePi); + vOffset = _mm_and_ps(vOffset,g_XMTwoPi); + // Add 2Pi to all entries less than -Pi + vResult = _mm_add_ps(vResult,vOffset); + // Greater than or equal to Pi? + vOffset = _mm_cmpge_ps(vResult,g_XMPi); + vOffset = _mm_and_ps(vOffset,g_XMTwoPi); + // Sub 2Pi to all entries greater than Pi + vResult = _mm_sub_ps(vResult,vOffset); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorMultiply +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Result = { + V1.vector4_f32[0] * V2.vector4_f32[0], + V1.vector4_f32[1] * V2.vector4_f32[1], + V1.vector4_f32[2] * V2.vector4_f32[2], + V1.vector4_f32[3] * V2.vector4_f32[3] + }; + return Result; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_mul_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorMultiplyAdd +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR V3 +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult = { + (V1.vector4_f32[0] * V2.vector4_f32[0]) + V3.vector4_f32[0], + (V1.vector4_f32[1] * V2.vector4_f32[1]) + V3.vector4_f32[1], + (V1.vector4_f32[2] * V2.vector4_f32[2]) + V3.vector4_f32[2], + (V1.vector4_f32[3] * V2.vector4_f32[3]) + V3.vector4_f32[3] + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_mul_ps( V1, V2 ); + return _mm_add_ps(vResult, V3 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorDivide +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Result; + Result.vector4_f32[0] = V1.vector4_f32[0] / V2.vector4_f32[0]; + Result.vector4_f32[1] = V1.vector4_f32[1] / V2.vector4_f32[1]; + Result.vector4_f32[2] = V1.vector4_f32[2] / V2.vector4_f32[2]; + Result.vector4_f32[3] = V1.vector4_f32[3] / V2.vector4_f32[3]; + return Result; +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_div_ps( V1, V2 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorNegativeMultiplySubtract +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR V3 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR vResult = { + V3.vector4_f32[0] - (V1.vector4_f32[0] * V2.vector4_f32[0]), + V3.vector4_f32[1] - (V1.vector4_f32[1] * V2.vector4_f32[1]), + V3.vector4_f32[2] - (V1.vector4_f32[2] * V2.vector4_f32[2]), + V3.vector4_f32[3] - (V1.vector4_f32[3] * V2.vector4_f32[3]) + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR R = _mm_mul_ps( V1, V2 ); + return _mm_sub_ps( V3, R ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorScale +( + FXMVECTOR V, + FLOAT ScaleFactor +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult = { + V.vector4_f32[0] * ScaleFactor, + V.vector4_f32[1] * ScaleFactor, + V.vector4_f32[2] * ScaleFactor, + V.vector4_f32[3] * ScaleFactor + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_set_ps1(ScaleFactor); + return _mm_mul_ps(vResult,V); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorReciprocalEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Result; + UINT i; + + // Avoid C4701 + Result.vector4_f32[0] = 0.0f; + + for (i = 0; i < 4; i++) + { + if (XMISNAN(V.vector4_f32[i])) + { + Result.vector4_u32[i] = 0x7FC00000; + } + else if (V.vector4_f32[i] == 0.0f || V.vector4_f32[i] == -0.0f) + { + Result.vector4_u32[i] = 0x7F800000 | (V.vector4_u32[i] & 0x80000000); + } + else + { + Result.vector4_f32[i] = 1.f / V.vector4_f32[i]; + } + } + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_rcp_ps(V); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorReciprocal +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + return XMVectorReciprocalEst(V); + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_div_ps(g_XMOne,V); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Return an estimated square root +XMFINLINE XMVECTOR XMVectorSqrtEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Select; + + // if (x == +Infinity) sqrt(x) = +Infinity + // if (x == +0.0f) sqrt(x) = +0.0f + // if (x == -0.0f) sqrt(x) = -0.0f + // if (x < 0.0f) sqrt(x) = QNaN + + XMVECTOR Result = XMVectorReciprocalSqrtEst(V); + XMVECTOR Zero = XMVectorZero(); + XMVECTOR VEqualsInfinity = XMVectorEqualInt(V, g_XMInfinity.v); + XMVECTOR VEqualsZero = XMVectorEqual(V, Zero); + Result = XMVectorMultiply(V, Result); + Select = XMVectorEqualInt(VEqualsInfinity, VEqualsZero); + Result = XMVectorSelect(V, Result, Select); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_sqrt_ps(V); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSqrt +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Zero; + XMVECTOR VEqualsInfinity, VEqualsZero; + XMVECTOR Select; + XMVECTOR Result; + + // if (x == +Infinity) sqrt(x) = +Infinity + // if (x == +0.0f) sqrt(x) = +0.0f + // if (x == -0.0f) sqrt(x) = -0.0f + // if (x < 0.0f) sqrt(x) = QNaN + + Result = XMVectorReciprocalSqrt(V); + Zero = XMVectorZero(); + VEqualsInfinity = XMVectorEqualInt(V, g_XMInfinity.v); + VEqualsZero = XMVectorEqual(V, Zero); + Result = XMVectorMultiply(V, Result); + Select = XMVectorEqualInt(VEqualsInfinity, VEqualsZero); + Result = XMVectorSelect(V, Result, Select); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_sqrt_ps(V); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorReciprocalSqrtEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + // if (x == +Infinity) rsqrt(x) = 0 + // if (x == +0.0f) rsqrt(x) = +Infinity + // if (x == -0.0f) rsqrt(x) = -Infinity + // if (x < 0.0f) rsqrt(x) = QNaN + + XMVECTOR Result; + UINT i; + + // Avoid C4701 + Result.vector4_f32[0] = 0.0f; + + for (i = 0; i < 4; i++) + { + if (XMISNAN(V.vector4_f32[i])) + { + Result.vector4_u32[i] = 0x7FC00000; + } + else if (V.vector4_f32[i] == 0.0f || V.vector4_f32[i] == -0.0f) + { + Result.vector4_u32[i] = 0x7F800000 | (V.vector4_u32[i] & 0x80000000); + } + else if (V.vector4_f32[i] < 0.0f) + { + Result.vector4_u32[i] = 0x7FFFFFFF; + } + else if (XMISINF(V.vector4_f32[i])) + { + Result.vector4_f32[i] = 0.0f; + } + else + { + Result.vector4_f32[i] = 1.0f / sqrtf(V.vector4_f32[i]); + } + } + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + return _mm_rsqrt_ps(V); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorReciprocalSqrt +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + return XMVectorReciprocalSqrtEst(V); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_sqrt_ps(V); + vResult = _mm_div_ps(g_XMOne,vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorExpEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result.vector4_f32[0] = powf(2.0f, V.vector4_f32[0]); + Result.vector4_f32[1] = powf(2.0f, V.vector4_f32[1]); + Result.vector4_f32[2] = powf(2.0f, V.vector4_f32[2]); + Result.vector4_f32[3] = powf(2.0f, V.vector4_f32[3]); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_setr_ps( + powf(2.0f,XMVectorGetX(V)), + powf(2.0f,XMVectorGetY(V)), + powf(2.0f,XMVectorGetZ(V)), + powf(2.0f,XMVectorGetW(V))); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorExp +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR E, S; + XMVECTOR R, R2, R3, R4; + XMVECTOR V0, V1; + XMVECTOR C0X, C0Y, C0Z, C0W; + XMVECTOR C1X, C1Y, C1Z, C1W; + XMVECTOR Result; + static CONST XMVECTOR C0 = {1.0f, -6.93147182e-1f, 2.40226462e-1f, -5.55036440e-2f}; + static CONST XMVECTOR C1 = {9.61597636e-3f, -1.32823968e-3f, 1.47491097e-4f, -1.08635004e-5f}; + + R = XMVectorFloor(V); + E = XMVectorExpEst(R); + R = XMVectorSubtract(V, R); + R2 = XMVectorMultiply(R, R); + R3 = XMVectorMultiply(R, R2); + R4 = XMVectorMultiply(R2, R2); + + C0X = XMVectorSplatX(C0); + C0Y = XMVectorSplatY(C0); + C0Z = XMVectorSplatZ(C0); + C0W = XMVectorSplatW(C0); + + C1X = XMVectorSplatX(C1); + C1Y = XMVectorSplatY(C1); + C1Z = XMVectorSplatZ(C1); + C1W = XMVectorSplatW(C1); + + V0 = XMVectorMultiplyAdd(R, C0Y, C0X); + V0 = XMVectorMultiplyAdd(R2, C0Z, V0); + V0 = XMVectorMultiplyAdd(R3, C0W, V0); + + V1 = XMVectorMultiplyAdd(R, C1Y, C1X); + V1 = XMVectorMultiplyAdd(R2, C1Z, V1); + V1 = XMVectorMultiplyAdd(R3, C1W, V1); + + S = XMVectorMultiplyAdd(R4, V1, V0); + + S = XMVectorReciprocal(S); + Result = XMVectorMultiply(E, S); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 C0 = {1.0f, -6.93147182e-1f, 2.40226462e-1f, -5.55036440e-2f}; + static CONST XMVECTORF32 C1 = {9.61597636e-3f, -1.32823968e-3f, 1.47491097e-4f, -1.08635004e-5f}; + + // Get the integer of the input + XMVECTOR R = XMVectorFloor(V); + // Get the exponent estimate + XMVECTOR E = XMVectorExpEst(R); + // Get the fractional only + R = _mm_sub_ps(V,R); + // Get R^2 + XMVECTOR R2 = _mm_mul_ps(R,R); + // And R^3 + XMVECTOR R3 = _mm_mul_ps(R,R2); + + XMVECTOR V0 = _mm_load_ps1(&C0.f[1]); + V0 = _mm_mul_ps(V0,R); + XMVECTOR vConstants = _mm_load_ps1(&C0.f[0]); + V0 = _mm_add_ps(V0,vConstants); + vConstants = _mm_load_ps1(&C0.f[2]); + vConstants = _mm_mul_ps(vConstants,R2); + V0 = _mm_add_ps(V0,vConstants); + vConstants = _mm_load_ps1(&C0.f[3]); + vConstants = _mm_mul_ps(vConstants,R3); + V0 = _mm_add_ps(V0,vConstants); + + XMVECTOR V1 = _mm_load_ps1(&C1.f[1]); + V1 = _mm_mul_ps(V1,R); + vConstants = _mm_load_ps1(&C1.f[0]); + V1 = _mm_add_ps(V1,vConstants); + vConstants = _mm_load_ps1(&C1.f[2]); + vConstants = _mm_mul_ps(vConstants,R2); + V1 = _mm_add_ps(V1,vConstants); + vConstants = _mm_load_ps1(&C1.f[3]); + vConstants = _mm_mul_ps(vConstants,R3); + V1 = _mm_add_ps(V1,vConstants); + // R2 = R^4 + R2 = _mm_mul_ps(R2,R2); + R2 = _mm_mul_ps(R2,V1); + R2 = _mm_add_ps(R2,V0); + E = _mm_div_ps(E,R2); + return E; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorLogEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + FLOAT fScale = (1.0f / logf(2.0f)); + XMVECTOR Result; + + Result.vector4_f32[0] = logf(V.vector4_f32[0])*fScale; + Result.vector4_f32[1] = logf(V.vector4_f32[1])*fScale; + Result.vector4_f32[2] = logf(V.vector4_f32[2])*fScale; + Result.vector4_f32[3] = logf(V.vector4_f32[3])*fScale; + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vScale = _mm_set_ps1(1.0f / logf(2.0f)); + XMVECTOR vResult = _mm_setr_ps( + logf(XMVectorGetX(V)), + logf(XMVectorGetY(V)), + logf(XMVectorGetZ(V)), + logf(XMVectorGetW(V))); + vResult = _mm_mul_ps(vResult,vScale); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorLog +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fScale = (1.0f / logf(2.0f)); + XMVECTOR Result; + + Result.vector4_f32[0] = logf(V.vector4_f32[0])*fScale; + Result.vector4_f32[1] = logf(V.vector4_f32[1])*fScale; + Result.vector4_f32[2] = logf(V.vector4_f32[2])*fScale; + Result.vector4_f32[3] = logf(V.vector4_f32[3])*fScale; + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vScale = _mm_set_ps1(1.0f / logf(2.0f)); + XMVECTOR vResult = _mm_setr_ps( + logf(XMVectorGetX(V)), + logf(XMVectorGetY(V)), + logf(XMVectorGetZ(V)), + logf(XMVectorGetW(V))); + vResult = _mm_mul_ps(vResult,vScale); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorPowEst +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_f32[0] = powf(V1.vector4_f32[0], V2.vector4_f32[0]); + Result.vector4_f32[1] = powf(V1.vector4_f32[1], V2.vector4_f32[1]); + Result.vector4_f32[2] = powf(V1.vector4_f32[2], V2.vector4_f32[2]); + Result.vector4_f32[3] = powf(V1.vector4_f32[3], V2.vector4_f32[3]); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_setr_ps( + powf(XMVectorGetX(V1),XMVectorGetX(V2)), + powf(XMVectorGetY(V1),XMVectorGetY(V2)), + powf(XMVectorGetZ(V1),XMVectorGetZ(V2)), + powf(XMVectorGetW(V1),XMVectorGetW(V2))); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorPow +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_) + + return XMVectorPowEst(V1, V2); + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorAbs +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult = { + fabsf(V.vector4_f32[0]), + fabsf(V.vector4_f32[1]), + fabsf(V.vector4_f32[2]), + fabsf(V.vector4_f32[3]) + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_setzero_ps(); + vResult = _mm_sub_ps(vResult,V); + vResult = _mm_max_ps(vResult,V); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorMod +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Reciprocal; + XMVECTOR Quotient; + XMVECTOR Result; + + // V1 % V2 = V1 - V2 * truncate(V1 / V2) + Reciprocal = XMVectorReciprocal(V2); + Quotient = XMVectorMultiply(V1, Reciprocal); + Quotient = XMVectorTruncate(Quotient); + Result = XMVectorNegativeMultiplySubtract(V2, Quotient, V1); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_div_ps(V1, V2); + vResult = XMVectorTruncate(vResult); + vResult = _mm_mul_ps(vResult,V2); + vResult = _mm_sub_ps(V1,vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorModAngles +( + FXMVECTOR Angles +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR Result; + + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + V = XMVectorMultiply(Angles, g_XMReciprocalTwoPi.v); + V = XMVectorRound(V); + Result = XMVectorNegativeMultiplySubtract(g_XMTwoPi.v, V, Angles); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Modulo the range of the given angles such that -XM_PI <= Angles < XM_PI + XMVECTOR vResult = _mm_mul_ps(Angles,g_XMReciprocalTwoPi); + // Use the inline function due to complexity for rounding + vResult = XMVectorRound(vResult); + vResult = _mm_mul_ps(vResult,g_XMTwoPi); + vResult = _mm_sub_ps(Angles,vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorSin +( + FXMVECTOR V +) +{ + +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2, V3, V5, V7, V9, V11, V13, V15, V17, V19, V21, V23; + XMVECTOR S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + XMVECTOR Result; + + V1 = XMVectorModAngles(V); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + V2 = XMVectorMultiply(V1, V1); + V3 = XMVectorMultiply(V2, V1); + V5 = XMVectorMultiply(V3, V2); + V7 = XMVectorMultiply(V5, V2); + V9 = XMVectorMultiply(V7, V2); + V11 = XMVectorMultiply(V9, V2); + V13 = XMVectorMultiply(V11, V2); + V15 = XMVectorMultiply(V13, V2); + V17 = XMVectorMultiply(V15, V2); + V19 = XMVectorMultiply(V17, V2); + V21 = XMVectorMultiply(V19, V2); + V23 = XMVectorMultiply(V21, V2); + + S1 = XMVectorSplatY(g_XMSinCoefficients0.v); + S2 = XMVectorSplatZ(g_XMSinCoefficients0.v); + S3 = XMVectorSplatW(g_XMSinCoefficients0.v); + S4 = XMVectorSplatX(g_XMSinCoefficients1.v); + S5 = XMVectorSplatY(g_XMSinCoefficients1.v); + S6 = XMVectorSplatZ(g_XMSinCoefficients1.v); + S7 = XMVectorSplatW(g_XMSinCoefficients1.v); + S8 = XMVectorSplatX(g_XMSinCoefficients2.v); + S9 = XMVectorSplatY(g_XMSinCoefficients2.v); + S10 = XMVectorSplatZ(g_XMSinCoefficients2.v); + S11 = XMVectorSplatW(g_XMSinCoefficients2.v); + + Result = XMVectorMultiplyAdd(S1, V3, V1); + Result = XMVectorMultiplyAdd(S2, V5, Result); + Result = XMVectorMultiplyAdd(S3, V7, Result); + Result = XMVectorMultiplyAdd(S4, V9, Result); + Result = XMVectorMultiplyAdd(S5, V11, Result); + Result = XMVectorMultiplyAdd(S6, V13, Result); + Result = XMVectorMultiplyAdd(S7, V15, Result); + Result = XMVectorMultiplyAdd(S8, V17, Result); + Result = XMVectorMultiplyAdd(S9, V19, Result); + Result = XMVectorMultiplyAdd(S10, V21, Result); + Result = XMVectorMultiplyAdd(S11, V23, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Force the value within the bounds of pi + XMVECTOR vResult = XMVectorModAngles(V); + // Each on is V to the "num" power + // V2 = V1^2 + XMVECTOR V2 = _mm_mul_ps(vResult,vResult); + // V1^3 + XMVECTOR vPower = _mm_mul_ps(vResult,V2); + XMVECTOR vConstants = _mm_load_ps1(&g_XMSinCoefficients0.f[1]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^5 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients0.f[2]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^7 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients0.f[3]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^9 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients1.f[0]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^11 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients1.f[1]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^13 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients1.f[2]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^15 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients1.f[3]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^17 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients2.f[0]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^19 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients2.f[1]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^21 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients2.f[2]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^23 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMSinCoefficients2.f[3]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorCos +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2, V4, V6, V8, V10, V12, V14, V16, V18, V20, V22; + XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + XMVECTOR Result; + + V1 = XMVectorModAngles(V); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + V2 = XMVectorMultiply(V1, V1); + V4 = XMVectorMultiply(V2, V2); + V6 = XMVectorMultiply(V4, V2); + V8 = XMVectorMultiply(V4, V4); + V10 = XMVectorMultiply(V6, V4); + V12 = XMVectorMultiply(V6, V6); + V14 = XMVectorMultiply(V8, V6); + V16 = XMVectorMultiply(V8, V8); + V18 = XMVectorMultiply(V10, V8); + V20 = XMVectorMultiply(V10, V10); + V22 = XMVectorMultiply(V12, V10); + + C1 = XMVectorSplatY(g_XMCosCoefficients0.v); + C2 = XMVectorSplatZ(g_XMCosCoefficients0.v); + C3 = XMVectorSplatW(g_XMCosCoefficients0.v); + C4 = XMVectorSplatX(g_XMCosCoefficients1.v); + C5 = XMVectorSplatY(g_XMCosCoefficients1.v); + C6 = XMVectorSplatZ(g_XMCosCoefficients1.v); + C7 = XMVectorSplatW(g_XMCosCoefficients1.v); + C8 = XMVectorSplatX(g_XMCosCoefficients2.v); + C9 = XMVectorSplatY(g_XMCosCoefficients2.v); + C10 = XMVectorSplatZ(g_XMCosCoefficients2.v); + C11 = XMVectorSplatW(g_XMCosCoefficients2.v); + + Result = XMVectorMultiplyAdd(C1, V2, g_XMOne.v); + Result = XMVectorMultiplyAdd(C2, V4, Result); + Result = XMVectorMultiplyAdd(C3, V6, Result); + Result = XMVectorMultiplyAdd(C4, V8, Result); + Result = XMVectorMultiplyAdd(C5, V10, Result); + Result = XMVectorMultiplyAdd(C6, V12, Result); + Result = XMVectorMultiplyAdd(C7, V14, Result); + Result = XMVectorMultiplyAdd(C8, V16, Result); + Result = XMVectorMultiplyAdd(C9, V18, Result); + Result = XMVectorMultiplyAdd(C10, V20, Result); + Result = XMVectorMultiplyAdd(C11, V22, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Force the value within the bounds of pi + XMVECTOR V2 = XMVectorModAngles(V); + // Each on is V to the "num" power + // V2 = V1^2 + V2 = _mm_mul_ps(V2,V2); + // V^2 + XMVECTOR vConstants = _mm_load_ps1(&g_XMCosCoefficients0.f[1]); + vConstants = _mm_mul_ps(vConstants,V2); + XMVECTOR vResult = _mm_add_ps(vConstants,g_XMOne); + + // V^4 + XMVECTOR vPower = _mm_mul_ps(V2,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients0.f[2]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^6 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients0.f[3]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^8 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients1.f[0]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^10 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients1.f[1]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^12 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients1.f[2]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^14 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients1.f[3]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^16 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients2.f[0]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^18 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients2.f[1]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^20 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients2.f[2]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + + // V^22 + vPower = _mm_mul_ps(vPower,V2); + vConstants = _mm_load_ps1(&g_XMCosCoefficients2.f[3]); + vConstants = _mm_mul_ps(vConstants,vPower); + vResult = _mm_add_ps(vResult,vConstants); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE VOID XMVectorSinCos +( + XMVECTOR* pSin, + XMVECTOR* pCos, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13; + XMVECTOR V14, V15, V16, V17, V18, V19, V20, V21, V22, V23; + XMVECTOR S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + XMVECTOR Sin, Cos; + + XMASSERT(pSin); + XMASSERT(pCos); + + V1 = XMVectorModAngles(V); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + + V2 = XMVectorMultiply(V1, V1); + V3 = XMVectorMultiply(V2, V1); + V4 = XMVectorMultiply(V2, V2); + V5 = XMVectorMultiply(V3, V2); + V6 = XMVectorMultiply(V3, V3); + V7 = XMVectorMultiply(V4, V3); + V8 = XMVectorMultiply(V4, V4); + V9 = XMVectorMultiply(V5, V4); + V10 = XMVectorMultiply(V5, V5); + V11 = XMVectorMultiply(V6, V5); + V12 = XMVectorMultiply(V6, V6); + V13 = XMVectorMultiply(V7, V6); + V14 = XMVectorMultiply(V7, V7); + V15 = XMVectorMultiply(V8, V7); + V16 = XMVectorMultiply(V8, V8); + V17 = XMVectorMultiply(V9, V8); + V18 = XMVectorMultiply(V9, V9); + V19 = XMVectorMultiply(V10, V9); + V20 = XMVectorMultiply(V10, V10); + V21 = XMVectorMultiply(V11, V10); + V22 = XMVectorMultiply(V11, V11); + V23 = XMVectorMultiply(V12, V11); + + S1 = XMVectorSplatY(g_XMSinCoefficients0.v); + S2 = XMVectorSplatZ(g_XMSinCoefficients0.v); + S3 = XMVectorSplatW(g_XMSinCoefficients0.v); + S4 = XMVectorSplatX(g_XMSinCoefficients1.v); + S5 = XMVectorSplatY(g_XMSinCoefficients1.v); + S6 = XMVectorSplatZ(g_XMSinCoefficients1.v); + S7 = XMVectorSplatW(g_XMSinCoefficients1.v); + S8 = XMVectorSplatX(g_XMSinCoefficients2.v); + S9 = XMVectorSplatY(g_XMSinCoefficients2.v); + S10 = XMVectorSplatZ(g_XMSinCoefficients2.v); + S11 = XMVectorSplatW(g_XMSinCoefficients2.v); + + C1 = XMVectorSplatY(g_XMCosCoefficients0.v); + C2 = XMVectorSplatZ(g_XMCosCoefficients0.v); + C3 = XMVectorSplatW(g_XMCosCoefficients0.v); + C4 = XMVectorSplatX(g_XMCosCoefficients1.v); + C5 = XMVectorSplatY(g_XMCosCoefficients1.v); + C6 = XMVectorSplatZ(g_XMCosCoefficients1.v); + C7 = XMVectorSplatW(g_XMCosCoefficients1.v); + C8 = XMVectorSplatX(g_XMCosCoefficients2.v); + C9 = XMVectorSplatY(g_XMCosCoefficients2.v); + C10 = XMVectorSplatZ(g_XMCosCoefficients2.v); + C11 = XMVectorSplatW(g_XMCosCoefficients2.v); + + Sin = XMVectorMultiplyAdd(S1, V3, V1); + Sin = XMVectorMultiplyAdd(S2, V5, Sin); + Sin = XMVectorMultiplyAdd(S3, V7, Sin); + Sin = XMVectorMultiplyAdd(S4, V9, Sin); + Sin = XMVectorMultiplyAdd(S5, V11, Sin); + Sin = XMVectorMultiplyAdd(S6, V13, Sin); + Sin = XMVectorMultiplyAdd(S7, V15, Sin); + Sin = XMVectorMultiplyAdd(S8, V17, Sin); + Sin = XMVectorMultiplyAdd(S9, V19, Sin); + Sin = XMVectorMultiplyAdd(S10, V21, Sin); + Sin = XMVectorMultiplyAdd(S11, V23, Sin); + + Cos = XMVectorMultiplyAdd(C1, V2, g_XMOne.v); + Cos = XMVectorMultiplyAdd(C2, V4, Cos); + Cos = XMVectorMultiplyAdd(C3, V6, Cos); + Cos = XMVectorMultiplyAdd(C4, V8, Cos); + Cos = XMVectorMultiplyAdd(C5, V10, Cos); + Cos = XMVectorMultiplyAdd(C6, V12, Cos); + Cos = XMVectorMultiplyAdd(C7, V14, Cos); + Cos = XMVectorMultiplyAdd(C8, V16, Cos); + Cos = XMVectorMultiplyAdd(C9, V18, Cos); + Cos = XMVectorMultiplyAdd(C10, V20, Cos); + Cos = XMVectorMultiplyAdd(C11, V22, Cos); + + *pSin = Sin; + *pCos = Cos; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSin); + XMASSERT(pCos); + XMVECTOR V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13; + XMVECTOR V14, V15, V16, V17, V18, V19, V20, V21, V22, V23; + XMVECTOR S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11; + XMVECTOR C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + XMVECTOR Sin, Cos; + + V1 = XMVectorModAngles(V); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + + V2 = XMVectorMultiply(V1, V1); + V3 = XMVectorMultiply(V2, V1); + V4 = XMVectorMultiply(V2, V2); + V5 = XMVectorMultiply(V3, V2); + V6 = XMVectorMultiply(V3, V3); + V7 = XMVectorMultiply(V4, V3); + V8 = XMVectorMultiply(V4, V4); + V9 = XMVectorMultiply(V5, V4); + V10 = XMVectorMultiply(V5, V5); + V11 = XMVectorMultiply(V6, V5); + V12 = XMVectorMultiply(V6, V6); + V13 = XMVectorMultiply(V7, V6); + V14 = XMVectorMultiply(V7, V7); + V15 = XMVectorMultiply(V8, V7); + V16 = XMVectorMultiply(V8, V8); + V17 = XMVectorMultiply(V9, V8); + V18 = XMVectorMultiply(V9, V9); + V19 = XMVectorMultiply(V10, V9); + V20 = XMVectorMultiply(V10, V10); + V21 = XMVectorMultiply(V11, V10); + V22 = XMVectorMultiply(V11, V11); + V23 = XMVectorMultiply(V12, V11); + + S1 = _mm_load_ps1(&g_XMSinCoefficients0.f[1]); + S2 = _mm_load_ps1(&g_XMSinCoefficients0.f[2]); + S3 = _mm_load_ps1(&g_XMSinCoefficients0.f[3]); + S4 = _mm_load_ps1(&g_XMSinCoefficients1.f[0]); + S5 = _mm_load_ps1(&g_XMSinCoefficients1.f[1]); + S6 = _mm_load_ps1(&g_XMSinCoefficients1.f[2]); + S7 = _mm_load_ps1(&g_XMSinCoefficients1.f[3]); + S8 = _mm_load_ps1(&g_XMSinCoefficients2.f[0]); + S9 = _mm_load_ps1(&g_XMSinCoefficients2.f[1]); + S10 = _mm_load_ps1(&g_XMSinCoefficients2.f[2]); + S11 = _mm_load_ps1(&g_XMSinCoefficients2.f[3]); + + C1 = _mm_load_ps1(&g_XMCosCoefficients0.f[1]); + C2 = _mm_load_ps1(&g_XMCosCoefficients0.f[2]); + C3 = _mm_load_ps1(&g_XMCosCoefficients0.f[3]); + C4 = _mm_load_ps1(&g_XMCosCoefficients1.f[0]); + C5 = _mm_load_ps1(&g_XMCosCoefficients1.f[1]); + C6 = _mm_load_ps1(&g_XMCosCoefficients1.f[2]); + C7 = _mm_load_ps1(&g_XMCosCoefficients1.f[3]); + C8 = _mm_load_ps1(&g_XMCosCoefficients2.f[0]); + C9 = _mm_load_ps1(&g_XMCosCoefficients2.f[1]); + C10 = _mm_load_ps1(&g_XMCosCoefficients2.f[2]); + C11 = _mm_load_ps1(&g_XMCosCoefficients2.f[3]); + + S1 = _mm_mul_ps(S1,V3); + Sin = _mm_add_ps(S1,V1); + Sin = XMVectorMultiplyAdd(S2, V5, Sin); + Sin = XMVectorMultiplyAdd(S3, V7, Sin); + Sin = XMVectorMultiplyAdd(S4, V9, Sin); + Sin = XMVectorMultiplyAdd(S5, V11, Sin); + Sin = XMVectorMultiplyAdd(S6, V13, Sin); + Sin = XMVectorMultiplyAdd(S7, V15, Sin); + Sin = XMVectorMultiplyAdd(S8, V17, Sin); + Sin = XMVectorMultiplyAdd(S9, V19, Sin); + Sin = XMVectorMultiplyAdd(S10, V21, Sin); + Sin = XMVectorMultiplyAdd(S11, V23, Sin); + + Cos = _mm_mul_ps(C1,V2); + Cos = _mm_add_ps(Cos,g_XMOne); + Cos = XMVectorMultiplyAdd(C2, V4, Cos); + Cos = XMVectorMultiplyAdd(C3, V6, Cos); + Cos = XMVectorMultiplyAdd(C4, V8, Cos); + Cos = XMVectorMultiplyAdd(C5, V10, Cos); + Cos = XMVectorMultiplyAdd(C6, V12, Cos); + Cos = XMVectorMultiplyAdd(C7, V14, Cos); + Cos = XMVectorMultiplyAdd(C8, V16, Cos); + Cos = XMVectorMultiplyAdd(C9, V18, Cos); + Cos = XMVectorMultiplyAdd(C10, V20, Cos); + Cos = XMVectorMultiplyAdd(C11, V22, Cos); + + *pSin = Sin; + *pCos = Cos; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorTan +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + // Cody and Waite algorithm to compute tangent. + + XMVECTOR VA, VB, VC, VC2; + XMVECTOR T0, T1, T2, T3, T4, T5, T6, T7; + XMVECTOR C0, C1, TwoDivPi, Epsilon; + XMVECTOR N, D; + XMVECTOR R0, R1; + XMVECTOR VIsZero, VCNearZero, VBIsEven; + XMVECTOR Zero; + XMVECTOR Result; + UINT i; + static CONST XMVECTOR TanCoefficients0 = {1.0f, -4.667168334e-1f, 2.566383229e-2f, -3.118153191e-4f}; + static CONST XMVECTOR TanCoefficients1 = {4.981943399e-7f, -1.333835001e-1f, 3.424887824e-3f, -1.786170734e-5f}; + static CONST XMVECTOR TanConstants = {1.570796371f, 6.077100628e-11f, 0.000244140625f, 2.0f / XM_PI}; + static CONST XMVECTORU32 Mask = {0x1, 0x1, 0x1, 0x1}; + + TwoDivPi = XMVectorSplatW(TanConstants); + + Zero = XMVectorZero(); + + C0 = XMVectorSplatX(TanConstants); + C1 = XMVectorSplatY(TanConstants); + Epsilon = XMVectorSplatZ(TanConstants); + + VA = XMVectorMultiply(V, TwoDivPi); + + VA = XMVectorRound(VA); + + VC = XMVectorNegativeMultiplySubtract(VA, C0, V); + + VB = XMVectorAbs(VA); + + VC = XMVectorNegativeMultiplySubtract(VA, C1, VC); + + for (i = 0; i < 4; i++) + { + VB.vector4_u32[i] = (UINT)VB.vector4_f32[i]; + } + + VC2 = XMVectorMultiply(VC, VC); + + T7 = XMVectorSplatW(TanCoefficients1); + T6 = XMVectorSplatZ(TanCoefficients1); + T4 = XMVectorSplatX(TanCoefficients1); + T3 = XMVectorSplatW(TanCoefficients0); + T5 = XMVectorSplatY(TanCoefficients1); + T2 = XMVectorSplatZ(TanCoefficients0); + T1 = XMVectorSplatY(TanCoefficients0); + T0 = XMVectorSplatX(TanCoefficients0); + + VBIsEven = XMVectorAndInt(VB, Mask.v); + VBIsEven = XMVectorEqualInt(VBIsEven, Zero); + + N = XMVectorMultiplyAdd(VC2, T7, T6); + D = XMVectorMultiplyAdd(VC2, T4, T3); + N = XMVectorMultiplyAdd(VC2, N, T5); + D = XMVectorMultiplyAdd(VC2, D, T2); + N = XMVectorMultiply(VC2, N); + D = XMVectorMultiplyAdd(VC2, D, T1); + N = XMVectorMultiplyAdd(VC, N, VC); + VCNearZero = XMVectorInBounds(VC, Epsilon); + D = XMVectorMultiplyAdd(VC2, D, T0); + + N = XMVectorSelect(N, VC, VCNearZero); + D = XMVectorSelect(D, g_XMOne.v, VCNearZero); + + R0 = XMVectorNegate(N); + R1 = XMVectorReciprocal(D); + R0 = XMVectorReciprocal(R0); + R1 = XMVectorMultiply(N, R1); + R0 = XMVectorMultiply(D, R0); + + VIsZero = XMVectorEqual(V, Zero); + + Result = XMVectorSelect(R0, R1, VBIsEven); + + Result = XMVectorSelect(Result, Zero, VIsZero); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Cody and Waite algorithm to compute tangent. + + XMVECTOR VA, VB, VC, VC2; + XMVECTOR T0, T1, T2, T3, T4, T5, T6, T7; + XMVECTOR C0, C1, TwoDivPi, Epsilon; + XMVECTOR N, D; + XMVECTOR R0, R1; + XMVECTOR VIsZero, VCNearZero, VBIsEven; + XMVECTOR Zero; + XMVECTOR Result; + static CONST XMVECTORF32 TanCoefficients0 = {1.0f, -4.667168334e-1f, 2.566383229e-2f, -3.118153191e-4f}; + static CONST XMVECTORF32 TanCoefficients1 = {4.981943399e-7f, -1.333835001e-1f, 3.424887824e-3f, -1.786170734e-5f}; + static CONST XMVECTORF32 TanConstants = {1.570796371f, 6.077100628e-11f, 0.000244140625f, 2.0f / XM_PI}; + static CONST XMVECTORI32 Mask = {0x1, 0x1, 0x1, 0x1}; + + TwoDivPi = XMVectorSplatW(TanConstants); + + Zero = XMVectorZero(); + + C0 = XMVectorSplatX(TanConstants); + C1 = XMVectorSplatY(TanConstants); + Epsilon = XMVectorSplatZ(TanConstants); + + VA = XMVectorMultiply(V, TwoDivPi); + + VA = XMVectorRound(VA); + + VC = XMVectorNegativeMultiplySubtract(VA, C0, V); + + VB = XMVectorAbs(VA); + + VC = XMVectorNegativeMultiplySubtract(VA, C1, VC); + + reinterpret_cast<__m128i *>(&VB)[0] = _mm_cvttps_epi32(VB); + + VC2 = XMVectorMultiply(VC, VC); + + T7 = XMVectorSplatW(TanCoefficients1); + T6 = XMVectorSplatZ(TanCoefficients1); + T4 = XMVectorSplatX(TanCoefficients1); + T3 = XMVectorSplatW(TanCoefficients0); + T5 = XMVectorSplatY(TanCoefficients1); + T2 = XMVectorSplatZ(TanCoefficients0); + T1 = XMVectorSplatY(TanCoefficients0); + T0 = XMVectorSplatX(TanCoefficients0); + + VBIsEven = XMVectorAndInt(VB,Mask); + VBIsEven = XMVectorEqualInt(VBIsEven, Zero); + + N = XMVectorMultiplyAdd(VC2, T7, T6); + D = XMVectorMultiplyAdd(VC2, T4, T3); + N = XMVectorMultiplyAdd(VC2, N, T5); + D = XMVectorMultiplyAdd(VC2, D, T2); + N = XMVectorMultiply(VC2, N); + D = XMVectorMultiplyAdd(VC2, D, T1); + N = XMVectorMultiplyAdd(VC, N, VC); + VCNearZero = XMVectorInBounds(VC, Epsilon); + D = XMVectorMultiplyAdd(VC2, D, T0); + + N = XMVectorSelect(N, VC, VCNearZero); + D = XMVectorSelect(D, g_XMOne, VCNearZero); + R0 = XMVectorNegate(N); + R1 = _mm_div_ps(N,D); + R0 = _mm_div_ps(D,R0); + VIsZero = XMVectorEqual(V, Zero); + Result = XMVectorSelect(R0, R1, VBIsEven); + Result = XMVectorSelect(Result, Zero, VIsZero); + + return Result; + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorSinH +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTORF32 Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = XMVectorMultiplyAdd(V, Scale.v, g_XMNegativeOne.v); + V2 = XMVectorNegativeMultiplySubtract(V, Scale.v, g_XMNegativeOne.v); + + E1 = XMVectorExp(V1); + E2 = XMVectorExp(V2); + + Result = XMVectorSubtract(E1, E2); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTORF32 Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = _mm_mul_ps(V, Scale); + V1 = _mm_add_ps(V1,g_XMNegativeOne); + V2 = _mm_mul_ps(V, Scale); + V2 = _mm_sub_ps(g_XMNegativeOne,V2); + E1 = XMVectorExp(V1); + E2 = XMVectorExp(V2); + + Result = _mm_sub_ps(E1, E2); + + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorCosH +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTOR Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = XMVectorMultiplyAdd(V, Scale, g_XMNegativeOne.v); + V2 = XMVectorNegativeMultiplySubtract(V, Scale, g_XMNegativeOne.v); + + E1 = XMVectorExp(V1); + E2 = XMVectorExp(V2); + + Result = XMVectorAdd(E1, E2); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTORF32 Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = _mm_mul_ps(V,Scale); + V1 = _mm_add_ps(V1,g_XMNegativeOne); + V2 = _mm_mul_ps(V, Scale); + V2 = _mm_sub_ps(g_XMNegativeOne,V2); + E1 = XMVectorExp(V1); + E2 = XMVectorExp(V2); + Result = _mm_add_ps(E1, E2); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorTanH +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR E; + XMVECTOR Result; + static CONST XMVECTORF32 Scale = {2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f}; // 2.0f / ln(2.0f) + + E = XMVectorMultiply(V, Scale.v); + E = XMVectorExp(E); + E = XMVectorMultiplyAdd(E, g_XMOneHalf.v, g_XMOneHalf.v); + E = XMVectorReciprocal(E); + + Result = XMVectorSubtract(g_XMOne.v, E); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 Scale = {2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f}; // 2.0f / ln(2.0f) + + XMVECTOR E = _mm_mul_ps(V, Scale); + E = XMVectorExp(E); + E = _mm_mul_ps(E,g_XMOneHalf); + E = _mm_add_ps(E,g_XMOneHalf); + E = XMVectorReciprocal(E); + E = _mm_sub_ps(g_XMOne, E); + return E; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorASin +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V2, V3, AbsV; + XMVECTOR C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + XMVECTOR R0, R1, R2, R3, R4; + XMVECTOR OneMinusAbsV; + XMVECTOR Rsq; + XMVECTOR Result; + static CONST XMVECTOR OnePlusEpsilon = {1.00000011921f, 1.00000011921f, 1.00000011921f, 1.00000011921f}; + + // asin(V) = V * (C0 + C1 * V + C2 * V^2 + C3 * V^3 + C4 * V^4 + C5 * V^5) + (1 - V) * rsq(1 - V) * + // V * (C6 + C7 * V + C8 * V^2 + C9 * V^3 + C10 * V^4 + C11 * V^5) + + AbsV = XMVectorAbs(V); + + V2 = XMVectorMultiply(V, V); + V3 = XMVectorMultiply(V2, AbsV); + + R4 = XMVectorNegativeMultiplySubtract(AbsV, V, V); + + OneMinusAbsV = XMVectorSubtract(OnePlusEpsilon, AbsV); + Rsq = XMVectorReciprocalSqrt(OneMinusAbsV); + + C0 = XMVectorSplatX(g_XMASinCoefficients0.v); + C1 = XMVectorSplatY(g_XMASinCoefficients0.v); + C2 = XMVectorSplatZ(g_XMASinCoefficients0.v); + C3 = XMVectorSplatW(g_XMASinCoefficients0.v); + + C4 = XMVectorSplatX(g_XMASinCoefficients1.v); + C5 = XMVectorSplatY(g_XMASinCoefficients1.v); + C6 = XMVectorSplatZ(g_XMASinCoefficients1.v); + C7 = XMVectorSplatW(g_XMASinCoefficients1.v); + + C8 = XMVectorSplatX(g_XMASinCoefficients2.v); + C9 = XMVectorSplatY(g_XMASinCoefficients2.v); + C10 = XMVectorSplatZ(g_XMASinCoefficients2.v); + C11 = XMVectorSplatW(g_XMASinCoefficients2.v); + + R0 = XMVectorMultiplyAdd(C3, AbsV, C7); + R1 = XMVectorMultiplyAdd(C1, AbsV, C5); + R2 = XMVectorMultiplyAdd(C2, AbsV, C6); + R3 = XMVectorMultiplyAdd(C0, AbsV, C4); + + R0 = XMVectorMultiplyAdd(R0, AbsV, C11); + R1 = XMVectorMultiplyAdd(R1, AbsV, C9); + R2 = XMVectorMultiplyAdd(R2, AbsV, C10); + R3 = XMVectorMultiplyAdd(R3, AbsV, C8); + + R0 = XMVectorMultiplyAdd(R2, V3, R0); + R1 = XMVectorMultiplyAdd(R3, V3, R1); + + R0 = XMVectorMultiply(V, R0); + R1 = XMVectorMultiply(R4, R1); + + Result = XMVectorMultiplyAdd(R1, Rsq, R0); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 OnePlusEpsilon = {1.00000011921f, 1.00000011921f, 1.00000011921f, 1.00000011921f}; + + // asin(V) = V * (C0 + C1 * V + C2 * V^2 + C3 * V^3 + C4 * V^4 + C5 * V^5) + (1 - V) * rsq(1 - V) * + // V * (C6 + C7 * V + C8 * V^2 + C9 * V^3 + C10 * V^4 + C11 * V^5) + // Get abs(V) + XMVECTOR vAbsV = _mm_setzero_ps(); + vAbsV = _mm_sub_ps(vAbsV,V); + vAbsV = _mm_max_ps(vAbsV,V); + + XMVECTOR R0 = vAbsV; + XMVECTOR vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[3]); + R0 = _mm_mul_ps(R0,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[3]); + R0 = _mm_add_ps(R0,vConstants); + + XMVECTOR R1 = vAbsV; + vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[1]); + R1 = _mm_mul_ps(R1,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[1]); + R1 = _mm_add_ps(R1, vConstants); + + XMVECTOR R2 = vAbsV; + vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[2]); + R2 = _mm_mul_ps(R2,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[2]); + R2 = _mm_add_ps(R2, vConstants); + + XMVECTOR R3 = vAbsV; + vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[0]); + R3 = _mm_mul_ps(R3,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[0]); + R3 = _mm_add_ps(R3, vConstants); + + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[3]); + R0 = _mm_mul_ps(R0,vAbsV); + R0 = _mm_add_ps(R0,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[1]); + R1 = _mm_mul_ps(R1,vAbsV); + R1 = _mm_add_ps(R1,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[2]); + R2 = _mm_mul_ps(R2,vAbsV); + R2 = _mm_add_ps(R2,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[0]); + R3 = _mm_mul_ps(R3,vAbsV); + R3 = _mm_add_ps(R3,vConstants); + + // V3 = V^3 + vConstants = _mm_mul_ps(V,V); + vConstants = _mm_mul_ps(vConstants, vAbsV); + // Mul by V^3 + R2 = _mm_mul_ps(R2,vConstants); + R3 = _mm_mul_ps(R3,vConstants); + // Merge the results + R0 = _mm_add_ps(R0,R2); + R1 = _mm_add_ps(R1,R3); + + R0 = _mm_mul_ps(R0,V); + // vConstants = V-(V^2 retaining sign) + vConstants = _mm_mul_ps(vAbsV, V); + vConstants = _mm_sub_ps(V,vConstants); + R1 = _mm_mul_ps(R1,vConstants); + vConstants = _mm_sub_ps(OnePlusEpsilon,vAbsV); + // Do NOT use rsqrt/mul. This needs the precision + vConstants = _mm_sqrt_ps(vConstants); + R1 = _mm_div_ps(R1,vConstants); + R0 = _mm_add_ps(R0,R1); + return R0; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorACos +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V2, V3, AbsV; + XMVECTOR C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11; + XMVECTOR R0, R1, R2, R3, R4; + XMVECTOR OneMinusAbsV; + XMVECTOR Rsq; + XMVECTOR Result; + static CONST XMVECTOR OnePlusEpsilon = {1.00000011921f, 1.00000011921f, 1.00000011921f, 1.00000011921f}; + + // acos(V) = PI / 2 - asin(V) + + AbsV = XMVectorAbs(V); + + V2 = XMVectorMultiply(V, V); + V3 = XMVectorMultiply(V2, AbsV); + + R4 = XMVectorNegativeMultiplySubtract(AbsV, V, V); + + OneMinusAbsV = XMVectorSubtract(OnePlusEpsilon, AbsV); + Rsq = XMVectorReciprocalSqrt(OneMinusAbsV); + + C0 = XMVectorSplatX(g_XMASinCoefficients0.v); + C1 = XMVectorSplatY(g_XMASinCoefficients0.v); + C2 = XMVectorSplatZ(g_XMASinCoefficients0.v); + C3 = XMVectorSplatW(g_XMASinCoefficients0.v); + + C4 = XMVectorSplatX(g_XMASinCoefficients1.v); + C5 = XMVectorSplatY(g_XMASinCoefficients1.v); + C6 = XMVectorSplatZ(g_XMASinCoefficients1.v); + C7 = XMVectorSplatW(g_XMASinCoefficients1.v); + + C8 = XMVectorSplatX(g_XMASinCoefficients2.v); + C9 = XMVectorSplatY(g_XMASinCoefficients2.v); + C10 = XMVectorSplatZ(g_XMASinCoefficients2.v); + C11 = XMVectorSplatW(g_XMASinCoefficients2.v); + + R0 = XMVectorMultiplyAdd(C3, AbsV, C7); + R1 = XMVectorMultiplyAdd(C1, AbsV, C5); + R2 = XMVectorMultiplyAdd(C2, AbsV, C6); + R3 = XMVectorMultiplyAdd(C0, AbsV, C4); + + R0 = XMVectorMultiplyAdd(R0, AbsV, C11); + R1 = XMVectorMultiplyAdd(R1, AbsV, C9); + R2 = XMVectorMultiplyAdd(R2, AbsV, C10); + R3 = XMVectorMultiplyAdd(R3, AbsV, C8); + + R0 = XMVectorMultiplyAdd(R2, V3, R0); + R1 = XMVectorMultiplyAdd(R3, V3, R1); + + R0 = XMVectorMultiply(V, R0); + R1 = XMVectorMultiply(R4, R1); + + Result = XMVectorMultiplyAdd(R1, Rsq, R0); + + Result = XMVectorSubtract(g_XMHalfPi.v, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 OnePlusEpsilon = {1.00000011921f, 1.00000011921f, 1.00000011921f, 1.00000011921f}; + // Uses only 6 registers for good code on x86 targets + // acos(V) = PI / 2 - asin(V) + // Get abs(V) + XMVECTOR vAbsV = _mm_setzero_ps(); + vAbsV = _mm_sub_ps(vAbsV,V); + vAbsV = _mm_max_ps(vAbsV,V); + // Perform the series in precision groups to + // retain precision across 20 bits. (3 bits of imprecision due to operations) + XMVECTOR R0 = vAbsV; + XMVECTOR vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[3]); + R0 = _mm_mul_ps(R0,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[3]); + R0 = _mm_add_ps(R0,vConstants); + R0 = _mm_mul_ps(R0,vAbsV); + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[3]); + R0 = _mm_add_ps(R0,vConstants); + + XMVECTOR R1 = vAbsV; + vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[1]); + R1 = _mm_mul_ps(R1,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[1]); + R1 = _mm_add_ps(R1,vConstants); + R1 = _mm_mul_ps(R1, vAbsV); + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[1]); + R1 = _mm_add_ps(R1,vConstants); + + XMVECTOR R2 = vAbsV; + vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[2]); + R2 = _mm_mul_ps(R2,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[2]); + R2 = _mm_add_ps(R2,vConstants); + R2 = _mm_mul_ps(R2, vAbsV); + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[2]); + R2 = _mm_add_ps(R2,vConstants); + + XMVECTOR R3 = vAbsV; + vConstants = _mm_load_ps1(&g_XMASinCoefficients0.f[0]); + R3 = _mm_mul_ps(R3,vConstants); + vConstants = _mm_load_ps1(&g_XMASinCoefficients1.f[0]); + R3 = _mm_add_ps(R3,vConstants); + R3 = _mm_mul_ps(R3, vAbsV); + vConstants = _mm_load_ps1(&g_XMASinCoefficients2.f[0]); + R3 = _mm_add_ps(R3,vConstants); + + // vConstants = V^3 + vConstants = _mm_mul_ps(V,V); + vConstants = _mm_mul_ps(vConstants,vAbsV); + R2 = _mm_mul_ps(R2,vConstants); + R3 = _mm_mul_ps(R3,vConstants); + // Add the pair of values together here to retain + // as much precision as possible + R0 = _mm_add_ps(R0,R2); + R1 = _mm_add_ps(R1,R3); + + R0 = _mm_mul_ps(R0,V); + // vConstants = V-(V*abs(V)) + vConstants = _mm_mul_ps(V,vAbsV); + vConstants = _mm_sub_ps(V,vConstants); + R1 = _mm_mul_ps(R1,vConstants); + // Episilon exists to allow 1.0 as an answer + vConstants = _mm_sub_ps(OnePlusEpsilon, vAbsV); + // Use sqrt instead of rsqrt for precision + vConstants = _mm_sqrt_ps(vConstants); + R1 = _mm_div_ps(R1,vConstants); + R1 = _mm_add_ps(R1,R0); + vConstants = _mm_sub_ps(g_XMHalfPi,R1); + return vConstants; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorATan +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + // Cody and Waite algorithm to compute inverse tangent. + + XMVECTOR N, D; + XMVECTOR VF, G, ReciprocalF, AbsF, FA, FB; + XMVECTOR Sqrt3, Sqrt3MinusOne, TwoMinusSqrt3; + XMVECTOR HalfPi, OneThirdPi, OneSixthPi, Epsilon, MinV, MaxV; + XMVECTOR Zero; + XMVECTOR NegativeHalfPi; + XMVECTOR Angle1, Angle2; + XMVECTOR F_GT_One, F_GT_TwoMinusSqrt3, AbsF_LT_Epsilon, V_LT_Zero, V_GT_MaxV, V_LT_MinV; + XMVECTOR NegativeResult, Result; + XMVECTOR P0, P1, P2, P3, Q0, Q1, Q2, Q3; + static CONST XMVECTOR ATanConstants0 = {-1.3688768894e+1f, -2.0505855195e+1f, -8.4946240351f, -8.3758299368e-1f}; + static CONST XMVECTOR ATanConstants1 = {4.1066306682e+1f, 8.6157349597e+1f, 5.9578436142e+1f, 1.5024001160e+1f}; + static CONST XMVECTOR ATanConstants2 = {1.732050808f, 7.320508076e-1f, 2.679491924e-1f, 0.000244140625f}; // + static CONST XMVECTOR ATanConstants3 = {XM_PIDIV2, XM_PI / 3.0f, XM_PI / 6.0f, 8.507059173e+37f}; // + + Zero = XMVectorZero(); + + P0 = XMVectorSplatX(ATanConstants0); + P1 = XMVectorSplatY(ATanConstants0); + P2 = XMVectorSplatZ(ATanConstants0); + P3 = XMVectorSplatW(ATanConstants0); + + Q0 = XMVectorSplatX(ATanConstants1); + Q1 = XMVectorSplatY(ATanConstants1); + Q2 = XMVectorSplatZ(ATanConstants1); + Q3 = XMVectorSplatW(ATanConstants1); + + Sqrt3 = XMVectorSplatX(ATanConstants2); + Sqrt3MinusOne = XMVectorSplatY(ATanConstants2); + TwoMinusSqrt3 = XMVectorSplatZ(ATanConstants2); + Epsilon = XMVectorSplatW(ATanConstants2); + + HalfPi = XMVectorSplatX(ATanConstants3); + OneThirdPi = XMVectorSplatY(ATanConstants3); + OneSixthPi = XMVectorSplatZ(ATanConstants3); + MaxV = XMVectorSplatW(ATanConstants3); + + VF = XMVectorAbs(V); + ReciprocalF = XMVectorReciprocal(VF); + + F_GT_One = XMVectorGreater(VF, g_XMOne.v); + + VF = XMVectorSelect(VF, ReciprocalF, F_GT_One); + Angle1 = XMVectorSelect(Zero, HalfPi, F_GT_One); + Angle2 = XMVectorSelect(OneSixthPi, OneThirdPi, F_GT_One); + + F_GT_TwoMinusSqrt3 = XMVectorGreater(VF, TwoMinusSqrt3); + + FA = XMVectorMultiplyAdd(Sqrt3MinusOne, VF, VF); + FA = XMVectorAdd(FA, g_XMNegativeOne.v); + FB = XMVectorAdd(VF, Sqrt3); + FB = XMVectorReciprocal(FB); + FA = XMVectorMultiply(FA, FB); + + VF = XMVectorSelect(VF, FA, F_GT_TwoMinusSqrt3); + Angle1 = XMVectorSelect(Angle1, Angle2, F_GT_TwoMinusSqrt3); + + AbsF = XMVectorAbs(VF); + AbsF_LT_Epsilon = XMVectorLess(AbsF, Epsilon); + + G = XMVectorMultiply(VF, VF); + + D = XMVectorAdd(G, Q3); + D = XMVectorMultiplyAdd(D, G, Q2); + D = XMVectorMultiplyAdd(D, G, Q1); + D = XMVectorMultiplyAdd(D, G, Q0); + D = XMVectorReciprocal(D); + + N = XMVectorMultiplyAdd(P3, G, P2); + N = XMVectorMultiplyAdd(N, G, P1); + N = XMVectorMultiplyAdd(N, G, P0); + N = XMVectorMultiply(N, G); + Result = XMVectorMultiply(N, D); + + Result = XMVectorMultiplyAdd(Result, VF, VF); + + Result = XMVectorSelect(Result, VF, AbsF_LT_Epsilon); + + NegativeResult = XMVectorNegate(Result); + Result = XMVectorSelect(Result, NegativeResult, F_GT_One); + + Result = XMVectorAdd(Result, Angle1); + + V_LT_Zero = XMVectorLess(V, Zero); + NegativeResult = XMVectorNegate(Result); + Result = XMVectorSelect(Result, NegativeResult, V_LT_Zero); + + MinV = XMVectorNegate(MaxV); + NegativeHalfPi = XMVectorNegate(HalfPi); + V_GT_MaxV = XMVectorGreater(V, MaxV); + V_LT_MinV = XMVectorLess(V, MinV); + Result = XMVectorSelect(Result, g_XMHalfPi.v, V_GT_MaxV); + Result = XMVectorSelect(Result, NegativeHalfPi, V_LT_MinV); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 ATanConstants0 = {-1.3688768894e+1f, -2.0505855195e+1f, -8.4946240351f, -8.3758299368e-1f}; + static CONST XMVECTORF32 ATanConstants1 = {4.1066306682e+1f, 8.6157349597e+1f, 5.9578436142e+1f, 1.5024001160e+1f}; + static CONST XMVECTORF32 ATanConstants2 = {1.732050808f, 7.320508076e-1f, 2.679491924e-1f, 0.000244140625f}; // + static CONST XMVECTORF32 ATanConstants3 = {XM_PIDIV2, XM_PI / 3.0f, XM_PI / 6.0f, 8.507059173e+37f}; // + + XMVECTOR VF = XMVectorAbs(V); + XMVECTOR F_GT_One = _mm_cmpgt_ps(VF,g_XMOne); + XMVECTOR ReciprocalF = XMVectorReciprocal(VF); + VF = XMVectorSelect(VF, ReciprocalF, F_GT_One); + XMVECTOR Zero = XMVectorZero(); + XMVECTOR HalfPi = _mm_load_ps1(&ATanConstants3.f[0]); + XMVECTOR Angle1 = XMVectorSelect(Zero, HalfPi, F_GT_One); + // Pi/3 + XMVECTOR vConstants = _mm_load_ps1(&ATanConstants3.f[1]); + // Pi/6 + XMVECTOR Angle2 = _mm_load_ps1(&ATanConstants3.f[2]); + Angle2 = XMVectorSelect(Angle2, vConstants, F_GT_One); + + // 1-sqrt(3) + XMVECTOR FA = _mm_load_ps1(&ATanConstants2.f[1]); + FA = _mm_mul_ps(FA,VF); + FA = _mm_add_ps(FA,VF); + FA = _mm_add_ps(FA,g_XMNegativeOne); + // sqrt(3) + vConstants = _mm_load_ps1(&ATanConstants2.f[0]); + vConstants = _mm_add_ps(vConstants,VF); + FA = _mm_div_ps(FA,vConstants); + + // 2-sqrt(3) + vConstants = _mm_load_ps1(&ATanConstants2.f[2]); + // >2-sqrt(3)? + vConstants = _mm_cmpgt_ps(VF,vConstants); + VF = XMVectorSelect(VF, FA, vConstants); + Angle1 = XMVectorSelect(Angle1, Angle2, vConstants); + + XMVECTOR AbsF = XMVectorAbs(VF); + + XMVECTOR G = _mm_mul_ps(VF,VF); + XMVECTOR D = _mm_load_ps1(&ATanConstants1.f[3]); + D = _mm_add_ps(D,G); + D = _mm_mul_ps(D,G); + vConstants = _mm_load_ps1(&ATanConstants1.f[2]); + D = _mm_add_ps(D,vConstants); + D = _mm_mul_ps(D,G); + vConstants = _mm_load_ps1(&ATanConstants1.f[1]); + D = _mm_add_ps(D,vConstants); + D = _mm_mul_ps(D,G); + vConstants = _mm_load_ps1(&ATanConstants1.f[0]); + D = _mm_add_ps(D,vConstants); + + XMVECTOR N = _mm_load_ps1(&ATanConstants0.f[3]); + N = _mm_mul_ps(N,G); + vConstants = _mm_load_ps1(&ATanConstants0.f[2]); + N = _mm_add_ps(N,vConstants); + N = _mm_mul_ps(N,G); + vConstants = _mm_load_ps1(&ATanConstants0.f[1]); + N = _mm_add_ps(N,vConstants); + N = _mm_mul_ps(N,G); + vConstants = _mm_load_ps1(&ATanConstants0.f[0]); + N = _mm_add_ps(N,vConstants); + N = _mm_mul_ps(N,G); + XMVECTOR Result = _mm_div_ps(N,D); + + Result = _mm_mul_ps(Result,VF); + Result = _mm_add_ps(Result,VF); + // Epsilon + vConstants = _mm_load_ps1(&ATanConstants2.f[3]); + vConstants = _mm_cmpge_ps(vConstants,AbsF); + Result = XMVectorSelect(Result,VF,vConstants); + + XMVECTOR NegativeResult = _mm_mul_ps(Result,g_XMNegativeOne); + Result = XMVectorSelect(Result,NegativeResult,F_GT_One); + Result = _mm_add_ps(Result,Angle1); + + Zero = _mm_cmpge_ps(Zero,V); + NegativeResult = _mm_mul_ps(Result,g_XMNegativeOne); + Result = XMVectorSelect(Result,NegativeResult,Zero); + + XMVECTOR MaxV = _mm_load_ps1(&ATanConstants3.f[3]); + XMVECTOR MinV = _mm_mul_ps(MaxV,g_XMNegativeOne); + // Negate HalfPi + HalfPi = _mm_mul_ps(HalfPi,g_XMNegativeOne); + MaxV = _mm_cmple_ps(MaxV,V); + MinV = _mm_cmpge_ps(MinV,V); + Result = XMVectorSelect(Result,g_XMHalfPi,MaxV); + // HalfPi = -HalfPi + Result = XMVectorSelect(Result,HalfPi,MinV); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVectorATan2 +( + FXMVECTOR Y, + FXMVECTOR X +) +{ +#if defined(_XM_NO_INTRINSICS_) + + // Return the inverse tangent of Y / X in the range of -Pi to Pi with the following exceptions: + + // Y == 0 and X is Negative -> Pi with the sign of Y + // y == 0 and x is positive -> 0 with the sign of y + // Y != 0 and X == 0 -> Pi / 2 with the sign of Y + // Y != 0 and X is Negative -> atan(y/x) + (PI with the sign of Y) + // X == -Infinity and Finite Y -> Pi with the sign of Y + // X == +Infinity and Finite Y -> 0 with the sign of Y + // Y == Infinity and X is Finite -> Pi / 2 with the sign of Y + // Y == Infinity and X == -Infinity -> 3Pi / 4 with the sign of Y + // Y == Infinity and X == +Infinity -> Pi / 4 with the sign of Y + + XMVECTOR Reciprocal; + XMVECTOR V; + XMVECTOR YSign; + XMVECTOR Pi, PiOverTwo, PiOverFour, ThreePiOverFour; + XMVECTOR YEqualsZero, XEqualsZero, XIsPositive, YEqualsInfinity, XEqualsInfinity; + XMVECTOR ATanResultValid; + XMVECTOR R0, R1, R2, R3, R4, R5; + XMVECTOR Zero; + XMVECTOR Result; + static CONST XMVECTOR ATan2Constants = {XM_PI, XM_PIDIV2, XM_PIDIV4, XM_PI * 3.0f / 4.0f}; + + Zero = XMVectorZero(); + ATanResultValid = XMVectorTrueInt(); + + Pi = XMVectorSplatX(ATan2Constants); + PiOverTwo = XMVectorSplatY(ATan2Constants); + PiOverFour = XMVectorSplatZ(ATan2Constants); + ThreePiOverFour = XMVectorSplatW(ATan2Constants); + + YEqualsZero = XMVectorEqual(Y, Zero); + XEqualsZero = XMVectorEqual(X, Zero); + XIsPositive = XMVectorAndInt(X, g_XMNegativeZero.v); + XIsPositive = XMVectorEqualInt(XIsPositive, Zero); + YEqualsInfinity = XMVectorIsInfinite(Y); + XEqualsInfinity = XMVectorIsInfinite(X); + + YSign = XMVectorAndInt(Y, g_XMNegativeZero.v); + Pi = XMVectorOrInt(Pi, YSign); + PiOverTwo = XMVectorOrInt(PiOverTwo, YSign); + PiOverFour = XMVectorOrInt(PiOverFour, YSign); + ThreePiOverFour = XMVectorOrInt(ThreePiOverFour, YSign); + + R1 = XMVectorSelect(Pi, YSign, XIsPositive); + R2 = XMVectorSelect(ATanResultValid, PiOverTwo, XEqualsZero); + R3 = XMVectorSelect(R2, R1, YEqualsZero); + R4 = XMVectorSelect(ThreePiOverFour, PiOverFour, XIsPositive); + R5 = XMVectorSelect(PiOverTwo, R4, XEqualsInfinity); + Result = XMVectorSelect(R3, R5, YEqualsInfinity); + ATanResultValid = XMVectorEqualInt(Result, ATanResultValid); + + Reciprocal = XMVectorReciprocal(X); + V = XMVectorMultiply(Y, Reciprocal); + R0 = XMVectorATan(V); + + R1 = XMVectorSelect( Pi, Zero, XIsPositive ); + R2 = XMVectorAdd(R0, R1); + + Result = XMVectorSelect(Result, R2, ATanResultValid); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 ATan2Constants = {XM_PI, XM_PIDIV2, XM_PIDIV4, XM_PI * 3.0f / 4.0f}; + + // Mask if Y>0 && Y!=INF + XMVECTOR YEqualsInfinity = XMVectorIsInfinite(Y); + // Get the sign of (Y&0x80000000) + XMVECTOR YSign = _mm_and_ps(Y, g_XMNegativeZero); + // Get the sign bits of X + XMVECTOR XIsPositive = _mm_and_ps(X,g_XMNegativeZero); + // Change them to masks + XIsPositive = XMVectorEqualInt(XIsPositive,g_XMZero); + // Get Pi + XMVECTOR Pi = _mm_load_ps1(&ATan2Constants.f[0]); + // Copy the sign of Y + Pi = _mm_or_ps(Pi,YSign); + XMVECTOR R1 = XMVectorSelect(Pi,YSign,XIsPositive); + // Mask for X==0 + XMVECTOR vConstants = _mm_cmpeq_ps(X,g_XMZero); + // Get Pi/2 with with sign of Y + XMVECTOR PiOverTwo = _mm_load_ps1(&ATan2Constants.f[1]); + PiOverTwo = _mm_or_ps(PiOverTwo,YSign); + XMVECTOR R2 = XMVectorSelect(g_XMNegOneMask,PiOverTwo,vConstants); + // Mask for Y==0 + vConstants = _mm_cmpeq_ps(Y,g_XMZero); + R2 = XMVectorSelect(R2,R1,vConstants); + // Get Pi/4 with sign of Y + XMVECTOR PiOverFour = _mm_load_ps1(&ATan2Constants.f[2]); + PiOverFour = _mm_or_ps(PiOverFour,YSign); + // Get (Pi*3)/4 with sign of Y + XMVECTOR ThreePiOverFour = _mm_load_ps1(&ATan2Constants.f[3]); + ThreePiOverFour = _mm_or_ps(ThreePiOverFour,YSign); + vConstants = XMVectorSelect(ThreePiOverFour, PiOverFour, XIsPositive); + XMVECTOR XEqualsInfinity = XMVectorIsInfinite(X); + vConstants = XMVectorSelect(PiOverTwo,vConstants,XEqualsInfinity); + + XMVECTOR vResult = XMVectorSelect(R2,vConstants,YEqualsInfinity); + vConstants = XMVectorSelect(R1,vResult,YEqualsInfinity); + // At this point, any entry that's zero will get the result + // from XMVectorATan(), otherwise, return the failsafe value + vResult = XMVectorSelect(vResult,vConstants,XEqualsInfinity); + // Any entries not 0xFFFFFFFF, are considered precalculated + XMVECTOR ATanResultValid = XMVectorEqualInt(vResult,g_XMNegOneMask); + // Let's do the ATan2 function + vConstants = _mm_div_ps(Y,X); + vConstants = XMVectorATan(vConstants); + // Discard entries that have been declared void + + XMVECTOR R3 = XMVectorSelect( Pi, g_XMZero, XIsPositive ); + vConstants = _mm_add_ps( vConstants, R3 ); + + vResult = XMVectorSelect(vResult,vConstants,ATanResultValid); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSinEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V2, V3, V5, V7; + XMVECTOR S1, S2, S3; + XMVECTOR Result; + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! (for -PI <= V < PI) + V2 = XMVectorMultiply(V, V); + V3 = XMVectorMultiply(V2, V); + V5 = XMVectorMultiply(V3, V2); + V7 = XMVectorMultiply(V5, V2); + + S1 = XMVectorSplatY(g_XMSinEstCoefficients.v); + S2 = XMVectorSplatZ(g_XMSinEstCoefficients.v); + S3 = XMVectorSplatW(g_XMSinEstCoefficients.v); + + Result = XMVectorMultiplyAdd(S1, V3, V); + Result = XMVectorMultiplyAdd(S2, V5, Result); + Result = XMVectorMultiplyAdd(S3, V7, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! (for -PI <= V < PI) + XMVECTOR V2 = _mm_mul_ps(V,V); + XMVECTOR V3 = _mm_mul_ps(V2,V); + XMVECTOR vResult = _mm_load_ps1(&g_XMSinEstCoefficients.f[1]); + vResult = _mm_mul_ps(vResult,V3); + vResult = _mm_add_ps(vResult,V); + XMVECTOR vConstants = _mm_load_ps1(&g_XMSinEstCoefficients.f[2]); + // V^5 + V3 = _mm_mul_ps(V3,V2); + vConstants = _mm_mul_ps(vConstants,V3); + vResult = _mm_add_ps(vResult,vConstants); + vConstants = _mm_load_ps1(&g_XMSinEstCoefficients.f[3]); + // V^7 + V3 = _mm_mul_ps(V3,V2); + vConstants = _mm_mul_ps(vConstants,V3); + vResult = _mm_add_ps(vResult,vConstants); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorCosEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V2, V4, V6; + XMVECTOR C0, C1, C2, C3; + XMVECTOR Result; + + V2 = XMVectorMultiply(V, V); + V4 = XMVectorMultiply(V2, V2); + V6 = XMVectorMultiply(V4, V2); + + C0 = XMVectorSplatX(g_XMCosEstCoefficients.v); + C1 = XMVectorSplatY(g_XMCosEstCoefficients.v); + C2 = XMVectorSplatZ(g_XMCosEstCoefficients.v); + C3 = XMVectorSplatW(g_XMCosEstCoefficients.v); + + Result = XMVectorMultiplyAdd(C1, V2, C0); + Result = XMVectorMultiplyAdd(C2, V4, Result); + Result = XMVectorMultiplyAdd(C3, V6, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Get V^2 + XMVECTOR V2 = _mm_mul_ps(V,V); + XMVECTOR vResult = _mm_load_ps1(&g_XMCosEstCoefficients.f[1]); + vResult = _mm_mul_ps(vResult,V2); + XMVECTOR vConstants = _mm_load_ps1(&g_XMCosEstCoefficients.f[0]); + vResult = _mm_add_ps(vResult,vConstants); + vConstants = _mm_load_ps1(&g_XMCosEstCoefficients.f[2]); + // Get V^4 + XMVECTOR V4 = _mm_mul_ps(V2, V2); + vConstants = _mm_mul_ps(vConstants,V4); + vResult = _mm_add_ps(vResult,vConstants); + vConstants = _mm_load_ps1(&g_XMCosEstCoefficients.f[3]); + // It's really V^6 + V4 = _mm_mul_ps(V4,V2); + vConstants = _mm_mul_ps(vConstants,V4); + vResult = _mm_add_ps(vResult,vConstants); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMVectorSinCosEst +( + XMVECTOR* pSin, + XMVECTOR* pCos, + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V2, V3, V4, V5, V6, V7; + XMVECTOR S1, S2, S3; + XMVECTOR C0, C1, C2, C3; + XMVECTOR Sin, Cos; + + XMASSERT(pSin); + XMASSERT(pCos); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! (for -PI <= V < PI) + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! (for -PI <= V < PI) + V2 = XMVectorMultiply(V, V); + V3 = XMVectorMultiply(V2, V); + V4 = XMVectorMultiply(V2, V2); + V5 = XMVectorMultiply(V3, V2); + V6 = XMVectorMultiply(V3, V3); + V7 = XMVectorMultiply(V4, V3); + + S1 = XMVectorSplatY(g_XMSinEstCoefficients.v); + S2 = XMVectorSplatZ(g_XMSinEstCoefficients.v); + S3 = XMVectorSplatW(g_XMSinEstCoefficients.v); + + C0 = XMVectorSplatX(g_XMCosEstCoefficients.v); + C1 = XMVectorSplatY(g_XMCosEstCoefficients.v); + C2 = XMVectorSplatZ(g_XMCosEstCoefficients.v); + C3 = XMVectorSplatW(g_XMCosEstCoefficients.v); + + Sin = XMVectorMultiplyAdd(S1, V3, V); + Sin = XMVectorMultiplyAdd(S2, V5, Sin); + Sin = XMVectorMultiplyAdd(S3, V7, Sin); + + Cos = XMVectorMultiplyAdd(C1, V2, C0); + Cos = XMVectorMultiplyAdd(C2, V4, Cos); + Cos = XMVectorMultiplyAdd(C3, V6, Cos); + + *pSin = Sin; + *pCos = Cos; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pSin); + XMASSERT(pCos); + XMVECTOR V2, V3, V4, V5, V6, V7; + XMVECTOR S1, S2, S3; + XMVECTOR C0, C1, C2, C3; + XMVECTOR Sin, Cos; + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! (for -PI <= V < PI) + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! (for -PI <= V < PI) + V2 = XMVectorMultiply(V, V); + V3 = XMVectorMultiply(V2, V); + V4 = XMVectorMultiply(V2, V2); + V5 = XMVectorMultiply(V3, V2); + V6 = XMVectorMultiply(V3, V3); + V7 = XMVectorMultiply(V4, V3); + + S1 = _mm_load_ps1(&g_XMSinEstCoefficients.f[1]); + S2 = _mm_load_ps1(&g_XMSinEstCoefficients.f[2]); + S3 = _mm_load_ps1(&g_XMSinEstCoefficients.f[3]); + + C0 = _mm_load_ps1(&g_XMCosEstCoefficients.f[0]); + C1 = _mm_load_ps1(&g_XMCosEstCoefficients.f[1]); + C2 = _mm_load_ps1(&g_XMCosEstCoefficients.f[2]); + C3 = _mm_load_ps1(&g_XMCosEstCoefficients.f[3]); + + Sin = XMVectorMultiplyAdd(S1, V3, V); + Sin = XMVectorMultiplyAdd(S2, V5, Sin); + Sin = XMVectorMultiplyAdd(S3, V7, Sin); + + Cos = XMVectorMultiplyAdd(C1, V2, C0); + Cos = XMVectorMultiplyAdd(C2, V4, Cos); + Cos = XMVectorMultiplyAdd(C3, V6, Cos); + + *pSin = Sin; + *pCos = Cos; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorTanEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2, V1T0, V1T1, V2T2; + XMVECTOR T0, T1, T2; + XMVECTOR N, D; + XMVECTOR OneOverPi; + XMVECTOR Result; + + OneOverPi = XMVectorSplatW(g_XMTanEstCoefficients.v); + + V1 = XMVectorMultiply(V, OneOverPi); + V1 = XMVectorRound(V1); + + V1 = XMVectorNegativeMultiplySubtract(g_XMPi.v, V1, V); + + T0 = XMVectorSplatX(g_XMTanEstCoefficients.v); + T1 = XMVectorSplatY(g_XMTanEstCoefficients.v); + T2 = XMVectorSplatZ(g_XMTanEstCoefficients.v); + + V2T2 = XMVectorNegativeMultiplySubtract(V1, V1, T2); + V2 = XMVectorMultiply(V1, V1); + V1T0 = XMVectorMultiply(V1, T0); + V1T1 = XMVectorMultiply(V1, T1); + + D = XMVectorReciprocalEst(V2T2); + N = XMVectorMultiplyAdd(V2, V1T1, V1T0); + + Result = XMVectorMultiply(N, D); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V1, V2, V1T0, V1T1, V2T2; + XMVECTOR T0, T1, T2; + XMVECTOR N, D; + XMVECTOR OneOverPi; + XMVECTOR Result; + + OneOverPi = XMVectorSplatW(g_XMTanEstCoefficients); + + V1 = XMVectorMultiply(V, OneOverPi); + V1 = XMVectorRound(V1); + + V1 = XMVectorNegativeMultiplySubtract(g_XMPi, V1, V); + + T0 = XMVectorSplatX(g_XMTanEstCoefficients); + T1 = XMVectorSplatY(g_XMTanEstCoefficients); + T2 = XMVectorSplatZ(g_XMTanEstCoefficients); + + V2T2 = XMVectorNegativeMultiplySubtract(V1, V1, T2); + V2 = XMVectorMultiply(V1, V1); + V1T0 = XMVectorMultiply(V1, T0); + V1T1 = XMVectorMultiply(V1, T1); + + D = XMVectorReciprocalEst(V2T2); + N = XMVectorMultiplyAdd(V2, V1T1, V1T0); + + Result = XMVectorMultiply(N, D); + + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorSinHEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTORF32 Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = XMVectorMultiplyAdd(V, Scale.v, g_XMNegativeOne.v); + V2 = XMVectorNegativeMultiplySubtract(V, Scale.v, g_XMNegativeOne.v); + + E1 = XMVectorExpEst(V1); + E2 = XMVectorExpEst(V2); + + Result = XMVectorSubtract(E1, E2); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTORF32 Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = _mm_mul_ps(V,Scale); + V1 = _mm_add_ps(V1,g_XMNegativeOne); + V2 = _mm_mul_ps(V,Scale); + V2 = _mm_sub_ps(g_XMNegativeOne,V2); + E1 = XMVectorExpEst(V1); + E2 = XMVectorExpEst(V2); + Result = _mm_sub_ps(E1, E2); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorCosHEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTOR Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = XMVectorMultiplyAdd(V, Scale, g_XMNegativeOne.v); + V2 = XMVectorNegativeMultiplySubtract(V, Scale, g_XMNegativeOne.v); + + E1 = XMVectorExpEst(V1); + E2 = XMVectorExpEst(V2); + + Result = XMVectorAdd(E1, E2); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V1, V2; + XMVECTOR E1, E2; + XMVECTOR Result; + static CONST XMVECTORF32 Scale = {1.442695040888963f, 1.442695040888963f, 1.442695040888963f, 1.442695040888963f}; // 1.0f / ln(2.0f) + + V1 = _mm_mul_ps(V,Scale); + V1 = _mm_add_ps(V1,g_XMNegativeOne); + V2 = _mm_mul_ps(V, Scale); + V2 = _mm_sub_ps(g_XMNegativeOne,V2); + E1 = XMVectorExpEst(V1); + E2 = XMVectorExpEst(V2); + Result = _mm_add_ps(E1, E2); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorTanHEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR E; + XMVECTOR Result; + static CONST XMVECTOR Scale = {2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f}; // 2.0f / ln(2.0f) + + E = XMVectorMultiply(V, Scale); + E = XMVectorExpEst(E); + E = XMVectorMultiplyAdd(E, g_XMOneHalf.v, g_XMOneHalf.v); + E = XMVectorReciprocalEst(E); + + Result = XMVectorSubtract(g_XMOne.v, E); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 Scale = {2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f, 2.8853900817779268f}; // 2.0f / ln(2.0f) + + XMVECTOR E = _mm_mul_ps(V, Scale); + E = XMVectorExpEst(E); + E = _mm_mul_ps(E,g_XMOneHalf); + E = _mm_add_ps(E,g_XMOneHalf); + E = XMVectorReciprocalEst(E); + E = _mm_sub_ps(g_XMOne, E); + return E; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorASinEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR AbsV, V2, VD, VC0, V2C3; + XMVECTOR C0, C1, C2, C3; + XMVECTOR D, Rsq, SqrtD; + XMVECTOR OnePlusEps; + XMVECTOR Result; + + AbsV = XMVectorAbs(V); + + OnePlusEps = XMVectorSplatX(g_XMASinEstConstants.v); + + C0 = XMVectorSplatX(g_XMASinEstCoefficients.v); + C1 = XMVectorSplatY(g_XMASinEstCoefficients.v); + C2 = XMVectorSplatZ(g_XMASinEstCoefficients.v); + C3 = XMVectorSplatW(g_XMASinEstCoefficients.v); + + D = XMVectorSubtract(OnePlusEps, AbsV); + + Rsq = XMVectorReciprocalSqrtEst(D); + SqrtD = XMVectorMultiply(D, Rsq); + + V2 = XMVectorMultiply(V, AbsV); + V2C3 = XMVectorMultiply(V2, C3); + VD = XMVectorMultiply(D, AbsV); + VC0 = XMVectorMultiply(V, C0); + + Result = XMVectorMultiply(V, C1); + Result = XMVectorMultiplyAdd(V2, C2, Result); + Result = XMVectorMultiplyAdd(V2C3, VD, Result); + Result = XMVectorMultiplyAdd(VC0, SqrtD, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Get abs(V) + XMVECTOR vAbsV = _mm_setzero_ps(); + vAbsV = _mm_sub_ps(vAbsV,V); + vAbsV = _mm_max_ps(vAbsV,V); + + XMVECTOR D = _mm_load_ps1(&g_XMASinEstConstants.f[0]); + D = _mm_sub_ps(D,vAbsV); + // Since this is an estimate, rqsrt is okay + XMVECTOR vConstants = _mm_rsqrt_ps(D); + XMVECTOR SqrtD = _mm_mul_ps(D,vConstants); + // V2 = V^2 retaining sign + XMVECTOR V2 = _mm_mul_ps(V,vAbsV); + D = _mm_mul_ps(D,vAbsV); + + XMVECTOR vResult = _mm_load_ps1(&g_XMASinEstCoefficients.f[1]); + vResult = _mm_mul_ps(vResult,V); + vConstants = _mm_load_ps1(&g_XMASinEstCoefficients.f[2]); + vConstants = _mm_mul_ps(vConstants,V2); + vResult = _mm_add_ps(vResult,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinEstCoefficients.f[3]); + vConstants = _mm_mul_ps(vConstants,V2); + vConstants = _mm_mul_ps(vConstants,D); + vResult = _mm_add_ps(vResult,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinEstCoefficients.f[0]); + vConstants = _mm_mul_ps(vConstants,V); + vConstants = _mm_mul_ps(vConstants,SqrtD); + vResult = _mm_add_ps(vResult,vConstants); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorACosEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR AbsV, V2, VD, VC0, V2C3; + XMVECTOR C0, C1, C2, C3; + XMVECTOR D, Rsq, SqrtD; + XMVECTOR OnePlusEps, HalfPi; + XMVECTOR Result; + + // acos(V) = PI / 2 - asin(V) + + AbsV = XMVectorAbs(V); + + OnePlusEps = XMVectorSplatX(g_XMASinEstConstants.v); + HalfPi = XMVectorSplatY(g_XMASinEstConstants.v); + + C0 = XMVectorSplatX(g_XMASinEstCoefficients.v); + C1 = XMVectorSplatY(g_XMASinEstCoefficients.v); + C2 = XMVectorSplatZ(g_XMASinEstCoefficients.v); + C3 = XMVectorSplatW(g_XMASinEstCoefficients.v); + + D = XMVectorSubtract(OnePlusEps, AbsV); + + Rsq = XMVectorReciprocalSqrtEst(D); + SqrtD = XMVectorMultiply(D, Rsq); + + V2 = XMVectorMultiply(V, AbsV); + V2C3 = XMVectorMultiply(V2, C3); + VD = XMVectorMultiply(D, AbsV); + VC0 = XMVectorMultiply(V, C0); + + Result = XMVectorMultiply(V, C1); + Result = XMVectorMultiplyAdd(V2, C2, Result); + Result = XMVectorMultiplyAdd(V2C3, VD, Result); + Result = XMVectorMultiplyAdd(VC0, SqrtD, Result); + Result = XMVectorSubtract(HalfPi, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // acos(V) = PI / 2 - asin(V) + // Get abs(V) + XMVECTOR vAbsV = _mm_setzero_ps(); + vAbsV = _mm_sub_ps(vAbsV,V); + vAbsV = _mm_max_ps(vAbsV,V); + // Calc D + XMVECTOR D = _mm_load_ps1(&g_XMASinEstConstants.f[0]); + D = _mm_sub_ps(D,vAbsV); + // SqrtD = sqrt(D-abs(V)) estimated + XMVECTOR vConstants = _mm_rsqrt_ps(D); + XMVECTOR SqrtD = _mm_mul_ps(D,vConstants); + // V2 = V^2 while retaining sign + XMVECTOR V2 = _mm_mul_ps(V, vAbsV); + // Drop vAbsV here. D = (Const-abs(V))*abs(V) + D = _mm_mul_ps(D, vAbsV); + + XMVECTOR vResult = _mm_load_ps1(&g_XMASinEstCoefficients.f[1]); + vResult = _mm_mul_ps(vResult,V); + vConstants = _mm_load_ps1(&g_XMASinEstCoefficients.f[2]); + vConstants = _mm_mul_ps(vConstants,V2); + vResult = _mm_add_ps(vResult,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinEstCoefficients.f[3]); + vConstants = _mm_mul_ps(vConstants,V2); + vConstants = _mm_mul_ps(vConstants,D); + vResult = _mm_add_ps(vResult,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinEstCoefficients.f[0]); + vConstants = _mm_mul_ps(vConstants,V); + vConstants = _mm_mul_ps(vConstants,SqrtD); + vResult = _mm_add_ps(vResult,vConstants); + + vConstants = _mm_load_ps1(&g_XMASinEstConstants.f[1]); + vResult = _mm_sub_ps(vConstants,vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorATanEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR AbsV, V2S2, N, D; + XMVECTOR S0, S1, S2; + XMVECTOR HalfPi; + XMVECTOR Result; + + S0 = XMVectorSplatX(g_XMATanEstCoefficients.v); + S1 = XMVectorSplatY(g_XMATanEstCoefficients.v); + S2 = XMVectorSplatZ(g_XMATanEstCoefficients.v); + HalfPi = XMVectorSplatW(g_XMATanEstCoefficients.v); + + AbsV = XMVectorAbs(V); + + V2S2 = XMVectorMultiplyAdd(V, V, S2); + N = XMVectorMultiplyAdd(AbsV, HalfPi, S0); + D = XMVectorMultiplyAdd(AbsV, S1, V2S2); + N = XMVectorMultiply(N, V); + D = XMVectorReciprocalEst(D); + + Result = XMVectorMultiply(N, D); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Get abs(V) + XMVECTOR vAbsV = _mm_setzero_ps(); + vAbsV = _mm_sub_ps(vAbsV,V); + vAbsV = _mm_max_ps(vAbsV,V); + + XMVECTOR vResult = _mm_load_ps1(&g_XMATanEstCoefficients.f[3]); + vResult = _mm_mul_ps(vResult,vAbsV); + XMVECTOR vConstants = _mm_load_ps1(&g_XMATanEstCoefficients.f[0]); + vResult = _mm_add_ps(vResult,vConstants); + vResult = _mm_mul_ps(vResult,V); + + XMVECTOR D = _mm_mul_ps(V,V); + vConstants = _mm_load_ps1(&g_XMATanEstCoefficients.f[2]); + D = _mm_add_ps(D,vConstants); + vConstants = _mm_load_ps1(&g_XMATanEstCoefficients.f[1]); + vConstants = _mm_mul_ps(vConstants,vAbsV); + D = _mm_add_ps(D,vConstants); + vResult = _mm_div_ps(vResult,D); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorATan2Est +( + FXMVECTOR Y, + FXMVECTOR X +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Reciprocal; + XMVECTOR V; + XMVECTOR YSign; + XMVECTOR Pi, PiOverTwo, PiOverFour, ThreePiOverFour; + XMVECTOR YEqualsZero, XEqualsZero, XIsPositive, YEqualsInfinity, XEqualsInfinity; + XMVECTOR ATanResultValid; + XMVECTOR R0, R1, R2, R3, R4, R5; + XMVECTOR Zero; + XMVECTOR Result; + static CONST XMVECTOR ATan2Constants = {XM_PI, XM_PIDIV2, XM_PIDIV4, XM_PI * 3.0f / 4.0f}; + + Zero = XMVectorZero(); + ATanResultValid = XMVectorTrueInt(); + + Pi = XMVectorSplatX(ATan2Constants); + PiOverTwo = XMVectorSplatY(ATan2Constants); + PiOverFour = XMVectorSplatZ(ATan2Constants); + ThreePiOverFour = XMVectorSplatW(ATan2Constants); + + YEqualsZero = XMVectorEqual(Y, Zero); + XEqualsZero = XMVectorEqual(X, Zero); + XIsPositive = XMVectorAndInt(X, g_XMNegativeZero.v); + XIsPositive = XMVectorEqualInt(XIsPositive, Zero); + YEqualsInfinity = XMVectorIsInfinite(Y); + XEqualsInfinity = XMVectorIsInfinite(X); + + YSign = XMVectorAndInt(Y, g_XMNegativeZero.v); + Pi = XMVectorOrInt(Pi, YSign); + PiOverTwo = XMVectorOrInt(PiOverTwo, YSign); + PiOverFour = XMVectorOrInt(PiOverFour, YSign); + ThreePiOverFour = XMVectorOrInt(ThreePiOverFour, YSign); + + R1 = XMVectorSelect(Pi, YSign, XIsPositive); + R2 = XMVectorSelect(ATanResultValid, PiOverTwo, XEqualsZero); + R3 = XMVectorSelect(R2, R1, YEqualsZero); + R4 = XMVectorSelect(ThreePiOverFour, PiOverFour, XIsPositive); + R5 = XMVectorSelect(PiOverTwo, R4, XEqualsInfinity); + Result = XMVectorSelect(R3, R5, YEqualsInfinity); + ATanResultValid = XMVectorEqualInt(Result, ATanResultValid); + + Reciprocal = XMVectorReciprocalEst(X); + V = XMVectorMultiply(Y, Reciprocal); + R0 = XMVectorATanEst(V); + + R1 = XMVectorSelect( Pi, Zero, XIsPositive ); + R2 = XMVectorAdd(R0, R1); + + Result = XMVectorSelect(Result, R2, ATanResultValid); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static CONST XMVECTORF32 ATan2Constants = {XM_PI, XM_PIDIV2, XM_PIDIV4, XM_PI * 3.0f / 4.0f}; + + // Mask if Y>0 && Y!=INF + XMVECTOR YEqualsInfinity = XMVectorIsInfinite(Y); + // Get the sign of (Y&0x80000000) + XMVECTOR YSign = _mm_and_ps(Y, g_XMNegativeZero); + // Get the sign bits of X + XMVECTOR XIsPositive = _mm_and_ps(X,g_XMNegativeZero); + // Change them to masks + XIsPositive = XMVectorEqualInt(XIsPositive,g_XMZero); + // Get Pi + XMVECTOR Pi = _mm_load_ps1(&ATan2Constants.f[0]); + // Copy the sign of Y + Pi = _mm_or_ps(Pi,YSign); + XMVECTOR R1 = XMVectorSelect(Pi,YSign,XIsPositive); + // Mask for X==0 + XMVECTOR vConstants = _mm_cmpeq_ps(X,g_XMZero); + // Get Pi/2 with with sign of Y + XMVECTOR PiOverTwo = _mm_load_ps1(&ATan2Constants.f[1]); + PiOverTwo = _mm_or_ps(PiOverTwo,YSign); + XMVECTOR R2 = XMVectorSelect(g_XMNegOneMask,PiOverTwo,vConstants); + // Mask for Y==0 + vConstants = _mm_cmpeq_ps(Y,g_XMZero); + R2 = XMVectorSelect(R2,R1,vConstants); + // Get Pi/4 with sign of Y + XMVECTOR PiOverFour = _mm_load_ps1(&ATan2Constants.f[2]); + PiOverFour = _mm_or_ps(PiOverFour,YSign); + // Get (Pi*3)/4 with sign of Y + XMVECTOR ThreePiOverFour = _mm_load_ps1(&ATan2Constants.f[3]); + ThreePiOverFour = _mm_or_ps(ThreePiOverFour,YSign); + vConstants = XMVectorSelect(ThreePiOverFour, PiOverFour, XIsPositive); + XMVECTOR XEqualsInfinity = XMVectorIsInfinite(X); + vConstants = XMVectorSelect(PiOverTwo,vConstants,XEqualsInfinity); + + XMVECTOR vResult = XMVectorSelect(R2,vConstants,YEqualsInfinity); + vConstants = XMVectorSelect(R1,vResult,YEqualsInfinity); + // At this point, any entry that's zero will get the result + // from XMVectorATan(), otherwise, return the failsafe value + vResult = XMVectorSelect(vResult,vConstants,XEqualsInfinity); + // Any entries not 0xFFFFFFFF, are considered precalculated + XMVECTOR ATanResultValid = XMVectorEqualInt(vResult,g_XMNegOneMask); + // Let's do the ATan2 function + XMVECTOR Reciprocal = _mm_rcp_ps(X); + vConstants = _mm_mul_ps(Y, Reciprocal); + vConstants = XMVectorATanEst(vConstants); + // Discard entries that have been declared void + + XMVECTOR R3 = XMVectorSelect( Pi, g_XMZero, XIsPositive ); + vConstants = _mm_add_ps( vConstants, R3 ); + + vResult = XMVectorSelect(vResult,vConstants,ATanResultValid); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorLerp +( + FXMVECTOR V0, + FXMVECTOR V1, + FLOAT t +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Scale; + XMVECTOR Length; + XMVECTOR Result; + + // V0 + t * (V1 - V0) + Scale = XMVectorReplicate(t); + Length = XMVectorSubtract(V1, V0); + Result = XMVectorMultiplyAdd(Length, Scale, V0); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR L, S; + XMVECTOR Result; + + L = _mm_sub_ps( V1, V0 ); + + S = _mm_set_ps1( t ); + + Result = _mm_mul_ps( L, S ); + + return _mm_add_ps( Result, V0 ); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorLerpV +( + FXMVECTOR V0, + FXMVECTOR V1, + FXMVECTOR T +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Length; + XMVECTOR Result; + + // V0 + T * (V1 - V0) + Length = XMVectorSubtract(V1, V0); + Result = XMVectorMultiplyAdd(Length, T, V0); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Length; + XMVECTOR Result; + + Length = _mm_sub_ps( V1, V0 ); + + Result = _mm_mul_ps( Length, T ); + + return _mm_add_ps( Result, V0 ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorHermite +( + FXMVECTOR Position0, + FXMVECTOR Tangent0, + FXMVECTOR Position1, + CXMVECTOR Tangent1, + FLOAT t +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR P0; + XMVECTOR T0; + XMVECTOR P1; + XMVECTOR T1; + XMVECTOR Result; + FLOAT t2; + FLOAT t3; + + // Result = (2 * t^3 - 3 * t^2 + 1) * Position0 + + // (t^3 - 2 * t^2 + t) * Tangent0 + + // (-2 * t^3 + 3 * t^2) * Position1 + + // (t^3 - t^2) * Tangent1 + t2 = t * t; + t3 = t * t2; + + P0 = XMVectorReplicate(2.0f * t3 - 3.0f * t2 + 1.0f); + T0 = XMVectorReplicate(t3 - 2.0f * t2 + t); + P1 = XMVectorReplicate(-2.0f * t3 + 3.0f * t2); + T1 = XMVectorReplicate(t3 - t2); + + Result = XMVectorMultiply(P0, Position0); + Result = XMVectorMultiplyAdd(T0, Tangent0, Result); + Result = XMVectorMultiplyAdd(P1, Position1, Result); + Result = XMVectorMultiplyAdd(T1, Tangent1, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + FLOAT t2 = t * t; + FLOAT t3 = t * t2; + + XMVECTOR P0 = _mm_set_ps1(2.0f * t3 - 3.0f * t2 + 1.0f); + XMVECTOR T0 = _mm_set_ps1(t3 - 2.0f * t2 + t); + XMVECTOR P1 = _mm_set_ps1(-2.0f * t3 + 3.0f * t2); + XMVECTOR T1 = _mm_set_ps1(t3 - t2); + + XMVECTOR vResult = _mm_mul_ps(P0, Position0); + XMVECTOR vTemp = _mm_mul_ps(T0, Tangent0); + vResult = _mm_add_ps(vResult,vTemp); + vTemp = _mm_mul_ps(P1, Position1); + vResult = _mm_add_ps(vResult,vTemp); + vTemp = _mm_mul_ps(T1, Tangent1); + vResult = _mm_add_ps(vResult,vTemp); + return vResult; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorHermiteV +( + FXMVECTOR Position0, + FXMVECTOR Tangent0, + FXMVECTOR Position1, + CXMVECTOR Tangent1, + CXMVECTOR T +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR P0; + XMVECTOR T0; + XMVECTOR P1; + XMVECTOR T1; + XMVECTOR Result; + XMVECTOR T2; + XMVECTOR T3; + + // Result = (2 * t^3 - 3 * t^2 + 1) * Position0 + + // (t^3 - 2 * t^2 + t) * Tangent0 + + // (-2 * t^3 + 3 * t^2) * Position1 + + // (t^3 - t^2) * Tangent1 + T2 = XMVectorMultiply(T, T); + T3 = XMVectorMultiply(T , T2); + + P0 = XMVectorReplicate(2.0f * T3.vector4_f32[0] - 3.0f * T2.vector4_f32[0] + 1.0f); + T0 = XMVectorReplicate(T3.vector4_f32[1] - 2.0f * T2.vector4_f32[1] + T.vector4_f32[1]); + P1 = XMVectorReplicate(-2.0f * T3.vector4_f32[2] + 3.0f * T2.vector4_f32[2]); + T1 = XMVectorReplicate(T3.vector4_f32[3] - T2.vector4_f32[3]); + + Result = XMVectorMultiply(P0, Position0); + Result = XMVectorMultiplyAdd(T0, Tangent0, Result); + Result = XMVectorMultiplyAdd(P1, Position1, Result); + Result = XMVectorMultiplyAdd(T1, Tangent1, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 CatMulT2 = {-3.0f,-2.0f,3.0f,-1.0f}; + static const XMVECTORF32 CatMulT3 = {2.0f,1.0f,-2.0f,1.0f}; + + // Result = (2 * t^3 - 3 * t^2 + 1) * Position0 + + // (t^3 - 2 * t^2 + t) * Tangent0 + + // (-2 * t^3 + 3 * t^2) * Position1 + + // (t^3 - t^2) * Tangent1 + XMVECTOR T2 = _mm_mul_ps(T,T); + XMVECTOR T3 = _mm_mul_ps(T,T2); + // Mul by the constants against t^2 + T2 = _mm_mul_ps(T2,CatMulT2); + // Mul by the constants against t^3 + T3 = _mm_mul_ps(T3,CatMulT3); + // T3 now has the pre-result. + T3 = _mm_add_ps(T3,T2); + // I need to add t.y only + T2 = _mm_and_ps(T,g_XMMaskY); + T3 = _mm_add_ps(T3,T2); + // Add 1.0f to x + T3 = _mm_add_ps(T3,g_XMIdentityR0); + // Now, I have the constants created + // Mul the x constant to Position0 + XMVECTOR vResult = _mm_shuffle_ps(T3,T3,_MM_SHUFFLE(0,0,0,0)); + vResult = _mm_mul_ps(vResult,Position0); + // Mul the y constant to Tangent0 + T2 = _mm_shuffle_ps(T3,T3,_MM_SHUFFLE(1,1,1,1)); + T2 = _mm_mul_ps(T2,Tangent0); + vResult = _mm_add_ps(vResult,T2); + // Mul the z constant to Position1 + T2 = _mm_shuffle_ps(T3,T3,_MM_SHUFFLE(2,2,2,2)); + T2 = _mm_mul_ps(T2,Position1); + vResult = _mm_add_ps(vResult,T2); + // Mul the w constant to Tangent1 + T3 = _mm_shuffle_ps(T3,T3,_MM_SHUFFLE(3,3,3,3)); + T3 = _mm_mul_ps(T3,Tangent1); + vResult = _mm_add_ps(vResult,T3); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorCatmullRom +( + FXMVECTOR Position0, + FXMVECTOR Position1, + FXMVECTOR Position2, + CXMVECTOR Position3, + FLOAT t +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR P0; + XMVECTOR P1; + XMVECTOR P2; + XMVECTOR P3; + XMVECTOR Result; + FLOAT t2; + FLOAT t3; + + // Result = ((-t^3 + 2 * t^2 - t) * Position0 + + // (3 * t^3 - 5 * t^2 + 2) * Position1 + + // (-3 * t^3 + 4 * t^2 + t) * Position2 + + // (t^3 - t^2) * Position3) * 0.5 + t2 = t * t; + t3 = t * t2; + + P0 = XMVectorReplicate((-t3 + 2.0f * t2 - t) * 0.5f); + P1 = XMVectorReplicate((3.0f * t3 - 5.0f * t2 + 2.0f) * 0.5f); + P2 = XMVectorReplicate((-3.0f * t3 + 4.0f * t2 + t) * 0.5f); + P3 = XMVectorReplicate((t3 - t2) * 0.5f); + + Result = XMVectorMultiply(P0, Position0); + Result = XMVectorMultiplyAdd(P1, Position1, Result); + Result = XMVectorMultiplyAdd(P2, Position2, Result); + Result = XMVectorMultiplyAdd(P3, Position3, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + FLOAT t2 = t * t; + FLOAT t3 = t * t2; + + XMVECTOR P0 = _mm_set_ps1((-t3 + 2.0f * t2 - t) * 0.5f); + XMVECTOR P1 = _mm_set_ps1((3.0f * t3 - 5.0f * t2 + 2.0f) * 0.5f); + XMVECTOR P2 = _mm_set_ps1((-3.0f * t3 + 4.0f * t2 + t) * 0.5f); + XMVECTOR P3 = _mm_set_ps1((t3 - t2) * 0.5f); + + P0 = _mm_mul_ps(P0, Position0); + P1 = _mm_mul_ps(P1, Position1); + P2 = _mm_mul_ps(P2, Position2); + P3 = _mm_mul_ps(P3, Position3); + P0 = _mm_add_ps(P0,P1); + P2 = _mm_add_ps(P2,P3); + P0 = _mm_add_ps(P0,P2); + return P0; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorCatmullRomV +( + FXMVECTOR Position0, + FXMVECTOR Position1, + FXMVECTOR Position2, + CXMVECTOR Position3, + CXMVECTOR T +) +{ +#if defined(_XM_NO_INTRINSICS_) + float fx = T.vector4_f32[0]; + float fy = T.vector4_f32[1]; + float fz = T.vector4_f32[2]; + float fw = T.vector4_f32[3]; + XMVECTOR vResult = { + 0.5f*((-fx*fx*fx+2*fx*fx-fx)*Position0.vector4_f32[0]+ + (3*fx*fx*fx-5*fx*fx+2)*Position1.vector4_f32[0]+ + (-3*fx*fx*fx+4*fx*fx+fx)*Position2.vector4_f32[0]+ + (fx*fx*fx-fx*fx)*Position3.vector4_f32[0]), + 0.5f*((-fy*fy*fy+2*fy*fy-fy)*Position0.vector4_f32[1]+ + (3*fy*fy*fy-5*fy*fy+2)*Position1.vector4_f32[1]+ + (-3*fy*fy*fy+4*fy*fy+fy)*Position2.vector4_f32[1]+ + (fy*fy*fy-fy*fy)*Position3.vector4_f32[1]), + 0.5f*((-fz*fz*fz+2*fz*fz-fz)*Position0.vector4_f32[2]+ + (3*fz*fz*fz-5*fz*fz+2)*Position1.vector4_f32[2]+ + (-3*fz*fz*fz+4*fz*fz+fz)*Position2.vector4_f32[2]+ + (fz*fz*fz-fz*fz)*Position3.vector4_f32[2]), + 0.5f*((-fw*fw*fw+2*fw*fw-fw)*Position0.vector4_f32[3]+ + (3*fw*fw*fw-5*fw*fw+2)*Position1.vector4_f32[3]+ + (-3*fw*fw*fw+4*fw*fw+fw)*Position2.vector4_f32[3]+ + (fw*fw*fw-fw*fw)*Position3.vector4_f32[3]) + }; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 Catmul2 = {2.0f,2.0f,2.0f,2.0f}; + static const XMVECTORF32 Catmul3 = {3.0f,3.0f,3.0f,3.0f}; + static const XMVECTORF32 Catmul4 = {4.0f,4.0f,4.0f,4.0f}; + static const XMVECTORF32 Catmul5 = {5.0f,5.0f,5.0f,5.0f}; + // Cache T^2 and T^3 + XMVECTOR T2 = _mm_mul_ps(T,T); + XMVECTOR T3 = _mm_mul_ps(T,T2); + // Perform the Position0 term + XMVECTOR vResult = _mm_add_ps(T2,T2); + vResult = _mm_sub_ps(vResult,T); + vResult = _mm_sub_ps(vResult,T3); + vResult = _mm_mul_ps(vResult,Position0); + // Perform the Position1 term and add + XMVECTOR vTemp = _mm_mul_ps(T3,Catmul3); + XMVECTOR vTemp2 = _mm_mul_ps(T2,Catmul5); + vTemp = _mm_sub_ps(vTemp,vTemp2); + vTemp = _mm_add_ps(vTemp,Catmul2); + vTemp = _mm_mul_ps(vTemp,Position1); + vResult = _mm_add_ps(vResult,vTemp); + // Perform the Position2 term and add + vTemp = _mm_mul_ps(T2,Catmul4); + vTemp2 = _mm_mul_ps(T3,Catmul3); + vTemp = _mm_sub_ps(vTemp,vTemp2); + vTemp = _mm_add_ps(vTemp,T); + vTemp = _mm_mul_ps(vTemp,Position2); + vResult = _mm_add_ps(vResult,vTemp); + // Position3 is the last term + T3 = _mm_sub_ps(T3,T2); + T3 = _mm_mul_ps(T3,Position3); + vResult = _mm_add_ps(vResult,T3); + // Multiply by 0.5f and exit + vResult = _mm_mul_ps(vResult,g_XMOneHalf); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorBaryCentric +( + FXMVECTOR Position0, + FXMVECTOR Position1, + FXMVECTOR Position2, + FLOAT f, + FLOAT g +) +{ +#if defined(_XM_NO_INTRINSICS_) + + // Result = Position0 + f * (Position1 - Position0) + g * (Position2 - Position0) + XMVECTOR P10; + XMVECTOR P20; + XMVECTOR ScaleF; + XMVECTOR ScaleG; + XMVECTOR Result; + + P10 = XMVectorSubtract(Position1, Position0); + ScaleF = XMVectorReplicate(f); + + P20 = XMVectorSubtract(Position2, Position0); + ScaleG = XMVectorReplicate(g); + + Result = XMVectorMultiplyAdd(P10, ScaleF, Position0); + Result = XMVectorMultiplyAdd(P20, ScaleG, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR R1 = _mm_sub_ps(Position1,Position0); + XMVECTOR SF = _mm_set_ps1(f); + XMVECTOR R2 = _mm_sub_ps(Position2,Position0); + XMVECTOR SG = _mm_set_ps1(g); + R1 = _mm_mul_ps(R1,SF); + R2 = _mm_mul_ps(R2,SG); + R1 = _mm_add_ps(R1,Position0); + R1 = _mm_add_ps(R1,R2); + return R1; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVectorBaryCentricV +( + FXMVECTOR Position0, + FXMVECTOR Position1, + FXMVECTOR Position2, + CXMVECTOR F, + CXMVECTOR G +) +{ +#if defined(_XM_NO_INTRINSICS_) + + // Result = Position0 + f * (Position1 - Position0) + g * (Position2 - Position0) + XMVECTOR P10; + XMVECTOR P20; + XMVECTOR Result; + + P10 = XMVectorSubtract(Position1, Position0); + P20 = XMVectorSubtract(Position2, Position0); + + Result = XMVectorMultiplyAdd(P10, F, Position0); + Result = XMVectorMultiplyAdd(P20, G, Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR R1 = _mm_sub_ps(Position1,Position0); + XMVECTOR R2 = _mm_sub_ps(Position2,Position0); + R1 = _mm_mul_ps(R1,F); + R2 = _mm_mul_ps(R2,G); + R1 = _mm_add_ps(R1,Position0); + R1 = _mm_add_ps(R1,R2); + return R1; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +/**************************************************************************** + * + * 2D Vector + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2Equal +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] == V2.vector4_f32[0]) && (V1.vector4_f32[1] == V2.vector4_f32[1])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); +// z and w are don't care + return (((_mm_movemask_ps(vTemp)&3)==3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector2EqualR(V1, V2)); +#endif +} + + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector2EqualR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + UINT CR = 0; + + if ((V1.vector4_f32[0] == V2.vector4_f32[0]) && + (V1.vector4_f32[1] == V2.vector4_f32[1])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] != V2.vector4_f32[0]) && + (V1.vector4_f32[1] != V2.vector4_f32[1])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); +// z and w are don't care + int iTest = _mm_movemask_ps(vTemp)&3; + UINT CR = 0; + if (iTest==3) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2EqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_u32[0] == V2.vector4_u32[0]) && (V1.vector4_u32[1] == V2.vector4_u32[1])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + return (((_mm_movemask_ps(reinterpret_cast(&vTemp)[0])&3)==3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector2EqualIntR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector2EqualIntR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + UINT CR = 0; + if ((V1.vector4_u32[0] == V2.vector4_u32[0]) && + (V1.vector4_u32[1] == V2.vector4_u32[1])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_u32[0] != V2.vector4_u32[0]) && + (V1.vector4_u32[1] != V2.vector4_u32[1])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + int iTest = _mm_movemask_ps(reinterpret_cast(&vTemp)[0])&3; + UINT CR = 0; + if (iTest==3) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2NearEqual +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR Epsilon +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT dx, dy; + dx = fabsf(V1.vector4_f32[0]-V2.vector4_f32[0]); + dy = fabsf(V1.vector4_f32[1]-V2.vector4_f32[1]); + return ((dx <= Epsilon.vector4_f32[0]) && + (dy <= Epsilon.vector4_f32[1])); +#elif defined(_XM_SSE_INTRINSICS_) + // Get the difference + XMVECTOR vDelta = _mm_sub_ps(V1,V2); + // Get the absolute value of the difference + XMVECTOR vTemp = _mm_setzero_ps(); + vTemp = _mm_sub_ps(vTemp,vDelta); + vTemp = _mm_max_ps(vTemp,vDelta); + vTemp = _mm_cmple_ps(vTemp,Epsilon); + // z and w are don't care + return (((_mm_movemask_ps(vTemp)&3)==0x3) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2NotEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] != V2.vector4_f32[0]) || (V1.vector4_f32[1] != V2.vector4_f32[1])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); +// z and w are don't care + return (((_mm_movemask_ps(vTemp)&3)!=3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAnyFalse(XMVector2EqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2NotEqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_u32[0] != V2.vector4_u32[0]) || (V1.vector4_u32[1] != V2.vector4_u32[1])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + return (((_mm_movemask_ps(reinterpret_cast(&vTemp)[0])&3)!=3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAnyFalse(XMVector2EqualIntR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2Greater +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] > V2.vector4_f32[0]) && (V1.vector4_f32[1] > V2.vector4_f32[1])) != 0); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpgt_ps(V1,V2); +// z and w are don't care + return (((_mm_movemask_ps(vTemp)&3)==3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector2GreaterR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector2GreaterR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + UINT CR = 0; + if ((V1.vector4_f32[0] > V2.vector4_f32[0]) && + (V1.vector4_f32[1] > V2.vector4_f32[1])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] <= V2.vector4_f32[0]) && + (V1.vector4_f32[1] <= V2.vector4_f32[1])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpgt_ps(V1,V2); + int iTest = _mm_movemask_ps(vTemp)&3; + UINT CR = 0; + if (iTest==3) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2GreaterOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] >= V2.vector4_f32[0]) && (V1.vector4_f32[1] >= V2.vector4_f32[1])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpge_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&3)==3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector2GreaterOrEqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector2GreaterOrEqualR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if ((V1.vector4_f32[0] >= V2.vector4_f32[0]) && + (V1.vector4_f32[1] >= V2.vector4_f32[1])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] < V2.vector4_f32[0]) && + (V1.vector4_f32[1] < V2.vector4_f32[1])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpge_ps(V1,V2); + int iTest = _mm_movemask_ps(vTemp)&3; + UINT CR = 0; + if (iTest == 3) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2Less +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] < V2.vector4_f32[0]) && (V1.vector4_f32[1] < V2.vector4_f32[1])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmplt_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&3)==3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector2GreaterR(V2, V1)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2LessOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] <= V2.vector4_f32[0]) && (V1.vector4_f32[1] <= V2.vector4_f32[1])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmple_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&3)==3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector2GreaterOrEqualR(V2, V1)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2InBounds +( + FXMVECTOR V, + FXMVECTOR Bounds +) +{ + #if defined(_XM_NO_INTRINSICS_) + return (((V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) && + (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1])) != 0); + #elif defined(_XM_SSE_INTRINSICS_) + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + // x and y in bounds? (z and w are don't care) + return (((_mm_movemask_ps(vTemp1)&0x3)==0x3) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllInBounds(XMVector2InBoundsR(V, Bounds)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector2InBoundsR +( + FXMVECTOR V, + FXMVECTOR Bounds +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if ((V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) && + (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1])) + { + CR = XM_CRMASK_CR6BOUNDS; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + // x and y in bounds? (z and w are don't care) + return ((_mm_movemask_ps(vTemp1)&0x3)==0x3) ? XM_CRMASK_CR6BOUNDS : 0; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2IsNaN +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (XMISNAN(V.vector4_f32[0]) || + XMISNAN(V.vector4_f32[1])); +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the exponent + __m128i vTempInf = _mm_and_si128(reinterpret_cast(&V)[0],g_XMInfinity); + // Mask off the mantissa + __m128i vTempNan = _mm_and_si128(reinterpret_cast(&V)[0],g_XMQNaNTest); + // Are any of the exponents == 0x7F800000? + vTempInf = _mm_cmpeq_epi32(vTempInf,g_XMInfinity); + // Are any of the mantissa's zero? (SSE2 doesn't have a neq test) + vTempNan = _mm_cmpeq_epi32(vTempNan,g_XMZero); + // Perform a not on the NaN test to be true on NON-zero mantissas + vTempNan = _mm_andnot_si128(vTempNan,vTempInf); + // If x or y are NaN, the signs are true after the merge above + return ((_mm_movemask_ps(reinterpret_cast(&vTempNan)[0])&3) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector2IsInfinite +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + return (XMISINF(V.vector4_f32[0]) || + XMISINF(V.vector4_f32[1])); +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the sign bit + __m128 vTemp = _mm_and_ps(V,g_XMAbsMask); + // Compare to infinity + vTemp = _mm_cmpeq_ps(vTemp,g_XMInfinity); + // If x or z are infinity, the signs are true. + return ((_mm_movemask_ps(vTemp)&3) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Dot +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_f32[0] = + Result.vector4_f32[1] = + Result.vector4_f32[2] = + Result.vector4_f32[3] = V1.vector4_f32[0] * V2.vector4_f32[0] + V1.vector4_f32[1] * V2.vector4_f32[1]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y + XMVECTOR vLengthSq = _mm_mul_ps(V1,V2); + // vTemp has y splatted + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + // x+y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Cross +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fCross = (V1.vector4_f32[0] * V2.vector4_f32[1]) - (V1.vector4_f32[1] * V2.vector4_f32[0]); + XMVECTOR vResult = { + fCross, + fCross, + fCross, + fCross + }; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + // Swap x and y + XMVECTOR vResult = _mm_shuffle_ps(V2,V2,_MM_SHUFFLE(0,1,0,1)); + // Perform the muls + vResult = _mm_mul_ps(vResult,V1); + // Splat y + XMVECTOR vTemp = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(1,1,1,1)); + // Sub the values + vResult = _mm_sub_ss(vResult,vTemp); + // Splat the cross product + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,0,0,0)); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2LengthSq +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + return XMVector2Dot(V, V); +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has y splatted + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + // x+y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + return vLengthSq; +#else + return XMVector2Dot(V, V); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2ReciprocalLengthEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector2LengthSq(V); + Result = XMVectorReciprocalSqrtEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has y splatted + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + // x+y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_rsqrt_ss(vLengthSq); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2ReciprocalLength +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector2LengthSq(V); + Result = XMVectorReciprocalSqrt(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has y splatted + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + // x+y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_sqrt_ss(vLengthSq); + vLengthSq = _mm_div_ss(g_XMOne,vLengthSq); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2LengthEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Result; + Result = XMVector2LengthSq(V); + Result = XMVectorSqrtEst(Result); + return Result; +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has y splatted + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + // x+y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_sqrt_ss(vLengthSq); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Length +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result = XMVector2LengthSq(V); + Result = XMVectorSqrt(Result); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has y splatted + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + // x+y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + vLengthSq = _mm_sqrt_ps(vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// XMVector2NormalizeEst uses a reciprocal estimate and +// returns QNaN on zero and infinite vectors. + +XMFINLINE XMVECTOR XMVector2NormalizeEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result = XMVector2ReciprocalLength(V); + Result = XMVectorMultiply(V, Result); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has y splatted + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + // x+y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_rsqrt_ss(vLengthSq); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + vLengthSq = _mm_mul_ps(vLengthSq,V); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Normalize +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fLength; + XMVECTOR vResult; + + vResult = XMVector2Length( V ); + fLength = vResult.vector4_f32[0]; + + // Prevent divide by zero + if (fLength > 0) { + fLength = 1.0f/fLength; + } + + vResult.vector4_f32[0] = V.vector4_f32[0]*fLength; + vResult.vector4_f32[1] = V.vector4_f32[1]*fLength; + vResult.vector4_f32[2] = V.vector4_f32[2]*fLength; + vResult.vector4_f32[3] = V.vector4_f32[3]*fLength; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x and y only + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,1,1,1)); + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + // Prepare for the division + XMVECTOR vResult = _mm_sqrt_ps(vLengthSq); + // Create zero with a single instruction + XMVECTOR vZeroMask = _mm_setzero_ps(); + // Test for a divide by zero (Must be FP to detect -0.0) + vZeroMask = _mm_cmpneq_ps(vZeroMask,vResult); + // Failsafe on zero (Or epsilon) length planes + // If the length is infinity, set the elements to zero + vLengthSq = _mm_cmpneq_ps(vLengthSq,g_XMInfinity); + // Reciprocal mul to perform the normalization + vResult = _mm_div_ps(V,vResult); + // Any that are infinity, set to zero + vResult = _mm_and_ps(vResult,vZeroMask); + // Select qnan or result based on infinite length + XMVECTOR vTemp1 = _mm_andnot_ps(vLengthSq,g_XMQNaN); + XMVECTOR vTemp2 = _mm_and_ps(vResult,vLengthSq); + vResult = _mm_or_ps(vTemp1,vTemp2); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2ClampLength +( + FXMVECTOR V, + FLOAT LengthMin, + FLOAT LengthMax +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR ClampMax; + XMVECTOR ClampMin; + + ClampMax = XMVectorReplicate(LengthMax); + ClampMin = XMVectorReplicate(LengthMin); + + return XMVector2ClampLengthV(V, ClampMin, ClampMax); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR ClampMax = _mm_set_ps1(LengthMax); + XMVECTOR ClampMin = _mm_set_ps1(LengthMin); + return XMVector2ClampLengthV(V, ClampMin, ClampMax); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2ClampLengthV +( + FXMVECTOR V, + FXMVECTOR LengthMin, + FXMVECTOR LengthMax +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR ClampLength; + XMVECTOR LengthSq; + XMVECTOR RcpLength; + XMVECTOR Length; + XMVECTOR Normal; + XMVECTOR Zero; + XMVECTOR InfiniteLength; + XMVECTOR ZeroLength; + XMVECTOR Select; + XMVECTOR ControlMax; + XMVECTOR ControlMin; + XMVECTOR Control; + XMVECTOR Result; + + XMASSERT((LengthMin.vector4_f32[1] == LengthMin.vector4_f32[0])); + XMASSERT((LengthMax.vector4_f32[1] == LengthMax.vector4_f32[0])); + XMASSERT(XMVector2GreaterOrEqual(LengthMin, XMVectorZero())); + XMASSERT(XMVector2GreaterOrEqual(LengthMax, XMVectorZero())); + XMASSERT(XMVector2GreaterOrEqual(LengthMax, LengthMin)); + + LengthSq = XMVector2LengthSq(V); + + Zero = XMVectorZero(); + + RcpLength = XMVectorReciprocalSqrt(LengthSq); + + InfiniteLength = XMVectorEqualInt(LengthSq, g_XMInfinity.v); + ZeroLength = XMVectorEqual(LengthSq, Zero); + + Length = XMVectorMultiply(LengthSq, RcpLength); + + Normal = XMVectorMultiply(V, RcpLength); + + Select = XMVectorEqualInt(InfiniteLength, ZeroLength); + Length = XMVectorSelect(LengthSq, Length, Select); + Normal = XMVectorSelect(LengthSq, Normal, Select); + + ControlMax = XMVectorGreater(Length, LengthMax); + ControlMin = XMVectorLess(Length, LengthMin); + + ClampLength = XMVectorSelect(Length, LengthMax, ControlMax); + ClampLength = XMVectorSelect(ClampLength, LengthMin, ControlMin); + + Result = XMVectorMultiply(Normal, ClampLength); + + // Preserve the original vector (with no precision loss) if the length falls within the given range + Control = XMVectorEqualInt(ControlMax, ControlMin); + Result = XMVectorSelect(Result, V, Control); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR ClampLength; + XMVECTOR LengthSq; + XMVECTOR RcpLength; + XMVECTOR Length; + XMVECTOR Normal; + XMVECTOR InfiniteLength; + XMVECTOR ZeroLength; + XMVECTOR Select; + XMVECTOR ControlMax; + XMVECTOR ControlMin; + XMVECTOR Control; + XMVECTOR Result; + + XMASSERT((XMVectorGetY(LengthMin) == XMVectorGetX(LengthMin))); + XMASSERT((XMVectorGetY(LengthMax) == XMVectorGetX(LengthMax))); + XMASSERT(XMVector2GreaterOrEqual(LengthMin, g_XMZero)); + XMASSERT(XMVector2GreaterOrEqual(LengthMax, g_XMZero)); + XMASSERT(XMVector2GreaterOrEqual(LengthMax, LengthMin)); + LengthSq = XMVector2LengthSq(V); + RcpLength = XMVectorReciprocalSqrt(LengthSq); + InfiniteLength = XMVectorEqualInt(LengthSq, g_XMInfinity); + ZeroLength = XMVectorEqual(LengthSq, g_XMZero); + Length = _mm_mul_ps(LengthSq, RcpLength); + Normal = _mm_mul_ps(V, RcpLength); + Select = XMVectorEqualInt(InfiniteLength, ZeroLength); + Length = XMVectorSelect(LengthSq, Length, Select); + Normal = XMVectorSelect(LengthSq, Normal, Select); + ControlMax = XMVectorGreater(Length, LengthMax); + ControlMin = XMVectorLess(Length, LengthMin); + ClampLength = XMVectorSelect(Length, LengthMax, ControlMax); + ClampLength = XMVectorSelect(ClampLength, LengthMin, ControlMin); + Result = _mm_mul_ps(Normal, ClampLength); + // Preserve the original vector (with no precision loss) if the length falls within the given range + Control = XMVectorEqualInt(ControlMax, ControlMin); + Result = XMVectorSelect(Result, V, Control); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Reflect +( + FXMVECTOR Incident, + FXMVECTOR Normal +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + // Result = Incident - (2 * dot(Incident, Normal)) * Normal + Result = XMVector2Dot(Incident, Normal); + Result = XMVectorAdd(Result, Result); + Result = XMVectorNegativeMultiplySubtract(Result, Normal, Incident); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Result = Incident - (2 * dot(Incident, Normal)) * Normal + XMVECTOR Result = XMVector2Dot(Incident,Normal); + Result = _mm_add_ps(Result, Result); + Result = _mm_mul_ps(Result, Normal); + Result = _mm_sub_ps(Incident,Result); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Refract +( + FXMVECTOR Incident, + FXMVECTOR Normal, + FLOAT RefractionIndex +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Index; + Index = XMVectorReplicate(RefractionIndex); + return XMVector2RefractV(Incident, Normal, Index); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Index = _mm_set_ps1(RefractionIndex); + return XMVector2RefractV(Incident,Normal,Index); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +// Return the refraction of a 2D vector +XMFINLINE XMVECTOR XMVector2RefractV +( + FXMVECTOR Incident, + FXMVECTOR Normal, + FXMVECTOR RefractionIndex +) +{ +#if defined(_XM_NO_INTRINSICS_) + float IDotN; + float RX,RY; + XMVECTOR vResult; + // Result = RefractionIndex * Incident - Normal * (RefractionIndex * dot(Incident, Normal) + + // sqrt(1 - RefractionIndex * RefractionIndex * (1 - dot(Incident, Normal) * dot(Incident, Normal)))) + IDotN = (Incident.vector4_f32[0]*Normal.vector4_f32[0])+(Incident.vector4_f32[1]*Normal.vector4_f32[1]); + // R = 1.0f - RefractionIndex * RefractionIndex * (1.0f - IDotN * IDotN) + RY = 1.0f-(IDotN*IDotN); + RX = 1.0f-(RY*RefractionIndex.vector4_f32[0]*RefractionIndex.vector4_f32[0]); + RY = 1.0f-(RY*RefractionIndex.vector4_f32[1]*RefractionIndex.vector4_f32[1]); + if (RX>=0.0f) { + RX = (RefractionIndex.vector4_f32[0]*Incident.vector4_f32[0])-(Normal.vector4_f32[0]*((RefractionIndex.vector4_f32[0]*IDotN)+sqrtf(RX))); + } else { + RX = 0.0f; + } + if (RY>=0.0f) { + RY = (RefractionIndex.vector4_f32[1]*Incident.vector4_f32[1])-(Normal.vector4_f32[1]*((RefractionIndex.vector4_f32[1]*IDotN)+sqrtf(RY))); + } else { + RY = 0.0f; + } + vResult.vector4_f32[0] = RX; + vResult.vector4_f32[1] = RY; + vResult.vector4_f32[2] = 0.0f; + vResult.vector4_f32[3] = 0.0f; + return vResult; +#elif defined(_XM_SSE_INTRINSICS_) + // Result = RefractionIndex * Incident - Normal * (RefractionIndex * dot(Incident, Normal) + + // sqrt(1 - RefractionIndex * RefractionIndex * (1 - dot(Incident, Normal) * dot(Incident, Normal)))) + // Get the 2D Dot product of Incident-Normal + XMVECTOR IDotN = _mm_mul_ps(Incident,Normal); + XMVECTOR vTemp = _mm_shuffle_ps(IDotN,IDotN,_MM_SHUFFLE(1,1,1,1)); + IDotN = _mm_add_ss(IDotN,vTemp); + IDotN = _mm_shuffle_ps(IDotN,IDotN,_MM_SHUFFLE(0,0,0,0)); + // vTemp = 1.0f - RefractionIndex * RefractionIndex * (1.0f - IDotN * IDotN) + vTemp = _mm_mul_ps(IDotN,IDotN); + vTemp = _mm_sub_ps(g_XMOne,vTemp); + vTemp = _mm_mul_ps(vTemp,RefractionIndex); + vTemp = _mm_mul_ps(vTemp,RefractionIndex); + vTemp = _mm_sub_ps(g_XMOne,vTemp); + // If any terms are <=0, sqrt() will fail, punt to zero + XMVECTOR vMask = _mm_cmpgt_ps(vTemp,g_XMZero); + // R = RefractionIndex * IDotN + sqrt(R) + vTemp = _mm_sqrt_ps(vTemp); + XMVECTOR vResult = _mm_mul_ps(RefractionIndex,IDotN); + vTemp = _mm_add_ps(vTemp,vResult); + // Result = RefractionIndex * Incident - Normal * R + vResult = _mm_mul_ps(RefractionIndex,Incident); + vTemp = _mm_mul_ps(vTemp,Normal); + vResult = _mm_sub_ps(vResult,vTemp); + vResult = _mm_and_ps(vResult,vMask); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Orthogonal +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_f32[0] = -V.vector4_f32[1]; + Result.vector4_f32[1] = V.vector4_f32[0]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,2,0,1)); + vResult = _mm_mul_ps(vResult,g_XMNegateX); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2AngleBetweenNormalsEst +( + FXMVECTOR N1, + FXMVECTOR N2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR NegativeOne; + XMVECTOR One; + XMVECTOR Result; + + Result = XMVector2Dot(N1, N2); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + Result = XMVectorClamp(Result, NegativeOne, One); + Result = XMVectorACosEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = XMVector2Dot(N1,N2); + // Clamp to -1.0f to 1.0f + vResult = _mm_max_ps(vResult,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne);; + vResult = XMVectorACosEst(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2AngleBetweenNormals +( + FXMVECTOR N1, + FXMVECTOR N2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR NegativeOne; + XMVECTOR One; + XMVECTOR Result; + + Result = XMVector2Dot(N1, N2); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + Result = XMVectorClamp(Result, NegativeOne, One); + Result = XMVectorACos(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = XMVector2Dot(N1,N2); + // Clamp to -1.0f to 1.0f + vResult = _mm_max_ps(vResult,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne);; + vResult = XMVectorACos(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2AngleBetweenVectors +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR L1; + XMVECTOR L2; + XMVECTOR Dot; + XMVECTOR CosAngle; + XMVECTOR NegativeOne; + XMVECTOR One; + XMVECTOR Result; + + L1 = XMVector2ReciprocalLength(V1); + L2 = XMVector2ReciprocalLength(V2); + + Dot = XMVector2Dot(V1, V2); + + L1 = XMVectorMultiply(L1, L2); + + CosAngle = XMVectorMultiply(Dot, L1); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + CosAngle = XMVectorClamp(CosAngle, NegativeOne, One); + + Result = XMVectorACos(CosAngle); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR L1; + XMVECTOR L2; + XMVECTOR Dot; + XMVECTOR CosAngle; + XMVECTOR Result; + L1 = XMVector2ReciprocalLength(V1); + L2 = XMVector2ReciprocalLength(V2); + Dot = XMVector2Dot(V1, V2); + L1 = _mm_mul_ps(L1, L2); + CosAngle = _mm_mul_ps(Dot, L1); + CosAngle = XMVectorClamp(CosAngle, g_XMNegativeOne,g_XMOne); + Result = XMVectorACos(CosAngle); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2LinePointDistance +( + FXMVECTOR LinePoint1, + FXMVECTOR LinePoint2, + FXMVECTOR Point +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR PointVector; + XMVECTOR LineVector; + XMVECTOR ReciprocalLengthSq; + XMVECTOR PointProjectionScale; + XMVECTOR DistanceVector; + XMVECTOR Result; + + // Given a vector PointVector from LinePoint1 to Point and a vector + // LineVector from LinePoint1 to LinePoint2, the scaled distance + // PointProjectionScale from LinePoint1 to the perpendicular projection + // of PointVector onto the line is defined as: + // + // PointProjectionScale = dot(PointVector, LineVector) / LengthSq(LineVector) + + PointVector = XMVectorSubtract(Point, LinePoint1); + LineVector = XMVectorSubtract(LinePoint2, LinePoint1); + + ReciprocalLengthSq = XMVector2LengthSq(LineVector); + ReciprocalLengthSq = XMVectorReciprocal(ReciprocalLengthSq); + + PointProjectionScale = XMVector2Dot(PointVector, LineVector); + PointProjectionScale = XMVectorMultiply(PointProjectionScale, ReciprocalLengthSq); + + DistanceVector = XMVectorMultiply(LineVector, PointProjectionScale); + DistanceVector = XMVectorSubtract(PointVector, DistanceVector); + + Result = XMVector2Length(DistanceVector); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR PointVector = _mm_sub_ps(Point,LinePoint1); + XMVECTOR LineVector = _mm_sub_ps(LinePoint2,LinePoint1); + XMVECTOR ReciprocalLengthSq = XMVector2LengthSq(LineVector); + XMVECTOR vResult = XMVector2Dot(PointVector,LineVector); + vResult = _mm_div_ps(vResult,ReciprocalLengthSq); + vResult = _mm_mul_ps(vResult,LineVector); + vResult = _mm_sub_ps(PointVector,vResult); + vResult = XMVector2Length(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2IntersectLine +( + FXMVECTOR Line1Point1, + FXMVECTOR Line1Point2, + FXMVECTOR Line2Point1, + CXMVECTOR Line2Point2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V1; + XMVECTOR V2; + XMVECTOR V3; + XMVECTOR C1; + XMVECTOR C2; + XMVECTOR Result; + CONST XMVECTOR Zero = XMVectorZero(); + + V1 = XMVectorSubtract(Line1Point2, Line1Point1); + V2 = XMVectorSubtract(Line2Point2, Line2Point1); + V3 = XMVectorSubtract(Line1Point1, Line2Point1); + + C1 = XMVector2Cross(V1, V2); + C2 = XMVector2Cross(V2, V3); + + if (XMVector2NearEqual(C1, Zero, g_XMEpsilon.v)) + { + if (XMVector2NearEqual(C2, Zero, g_XMEpsilon.v)) + { + // Coincident + Result = g_XMInfinity.v; + } + else + { + // Parallel + Result = g_XMQNaN.v; + } + } + else + { + // Intersection point = Line1Point1 + V1 * (C2 / C1) + XMVECTOR Scale; + Scale = XMVectorReciprocal(C1); + Scale = XMVectorMultiply(C2, Scale); + Result = XMVectorMultiplyAdd(V1, Scale, Line1Point1); + } + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR V1 = _mm_sub_ps(Line1Point2, Line1Point1); + XMVECTOR V2 = _mm_sub_ps(Line2Point2, Line2Point1); + XMVECTOR V3 = _mm_sub_ps(Line1Point1, Line2Point1); + // Generate the cross products + XMVECTOR C1 = XMVector2Cross(V1, V2); + XMVECTOR C2 = XMVector2Cross(V2, V3); + // If C1 is not close to epsilon, use the calculated value + XMVECTOR vResultMask = _mm_setzero_ps(); + vResultMask = _mm_sub_ps(vResultMask,C1); + vResultMask = _mm_max_ps(vResultMask,C1); + // 0xFFFFFFFF if the calculated value is to be used + vResultMask = _mm_cmpgt_ps(vResultMask,g_XMEpsilon); + // If C1 is close to epsilon, which fail type is it? INFINITY or NAN? + XMVECTOR vFailMask = _mm_setzero_ps(); + vFailMask = _mm_sub_ps(vFailMask,C2); + vFailMask = _mm_max_ps(vFailMask,C2); + vFailMask = _mm_cmple_ps(vFailMask,g_XMEpsilon); + XMVECTOR vFail = _mm_and_ps(vFailMask,g_XMInfinity); + vFailMask = _mm_andnot_ps(vFailMask,g_XMQNaN); + // vFail is NAN or INF + vFail = _mm_or_ps(vFail,vFailMask); + // Intersection point = Line1Point1 + V1 * (C2 / C1) + XMVECTOR vResult = _mm_div_ps(C2,C1); + vResult = _mm_mul_ps(vResult,V1); + vResult = _mm_add_ps(vResult,Line1Point1); + // Use result, or failure value + vResult = _mm_and_ps(vResult,vResultMask); + vResultMask = _mm_andnot_ps(vResultMask,vFail); + vResult = _mm_or_ps(vResult,vResultMask); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2Transform +( + FXMVECTOR V, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Result; + + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); + + Result = XMVectorMultiplyAdd(Y, M.r[1], M.r[3]); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,0,0,0)); + vResult = _mm_mul_ps(vResult,M.r[0]); + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + vTemp = _mm_mul_ps(vTemp,M.r[1]); + vResult = _mm_add_ps(vResult,vTemp); + vResult = _mm_add_ps(vResult,M.r[3]); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT4* XMVector2TransformStream +( + XMFLOAT4* pOutputStream, + UINT OutputStride, + CONST XMFLOAT2* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat2((XMFLOAT2*)pInputVector); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); +// Y = XMVectorReplicate(((XMFLOAT2*)pInputVector)->y); +// X = XMVectorReplicate(((XMFLOAT2*)pInputVector)->x); + + Result = XMVectorMultiplyAdd(Y, M.r[1], M.r[3]); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + XMStoreFloat4((XMFLOAT4*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + UINT i; + const BYTE* pInputVector = (const BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + for (i = 0; i < VectorCount; i++) + { + XMVECTOR X = _mm_load_ps1(&reinterpret_cast(pInputVector)->x); + XMVECTOR vResult = _mm_load_ps1(&reinterpret_cast(pInputVector)->y); + vResult = _mm_mul_ps(vResult,M.r[1]); + vResult = _mm_add_ps(vResult,M.r[3]); + X = _mm_mul_ps(X,M.r[0]); + vResult = _mm_add_ps(vResult,X); + _mm_storeu_ps(reinterpret_cast(pOutputVector),vResult); + pInputVector += InputStride; + pOutputVector += OutputStride; + } + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT4* XMVector2TransformStreamNC +( + XMFLOAT4* pOutputStream, + UINT OutputStride, + CONST XMFLOAT2* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) || defined(_XM_SSE_INTRINSICS_) + return XMVector2TransformStream( pOutputStream, OutputStride, pInputStream, InputStride, VectorCount, M ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2TransformCoord +( + FXMVECTOR V, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR X; + XMVECTOR Y; + XMVECTOR InverseW; + XMVECTOR Result; + + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); + + Result = XMVectorMultiplyAdd(Y, M.r[1], M.r[3]); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + InverseW = XMVectorSplatW(Result); + InverseW = XMVectorReciprocal(InverseW); + + Result = XMVectorMultiply(Result, InverseW); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,0,0,0)); + vResult = _mm_mul_ps(vResult,M.r[0]); + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + vTemp = _mm_mul_ps(vTemp,M.r[1]); + vResult = _mm_add_ps(vResult,vTemp); + vResult = _mm_add_ps(vResult,M.r[3]); + vTemp = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,3,3,3)); + vResult = _mm_div_ps(vResult,vTemp); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT2* XMVector2TransformCoordStream +( + XMFLOAT2* pOutputStream, + UINT OutputStride, + CONST XMFLOAT2* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR X; + XMVECTOR Y; + XMVECTOR InverseW; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat2((XMFLOAT2*)pInputVector); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); +// Y = XMVectorReplicate(((XMFLOAT2*)pInputVector)->y); +// X = XMVectorReplicate(((XMFLOAT2*)pInputVector)->x); + + Result = XMVectorMultiplyAdd(Y, M.r[1], M.r[3]); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + InverseW = XMVectorSplatW(Result); + InverseW = XMVectorReciprocal(InverseW); + + Result = XMVectorMultiply(Result, InverseW); + + XMStoreFloat2((XMFLOAT2*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + UINT i; + const BYTE *pInputVector = (BYTE*)pInputStream; + BYTE *pOutputVector = (BYTE*)pOutputStream; + + for (i = 0; i < VectorCount; i++) + { + XMVECTOR X = _mm_load_ps1(&reinterpret_cast(pInputVector)->x); + XMVECTOR vResult = _mm_load_ps1(&reinterpret_cast(pInputVector)->y); + vResult = _mm_mul_ps(vResult,M.r[1]); + vResult = _mm_add_ps(vResult,M.r[3]); + X = _mm_mul_ps(X,M.r[0]); + vResult = _mm_add_ps(vResult,X); + X = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,3,3,3)); + vResult = _mm_div_ps(vResult,X); + _mm_store_sd(reinterpret_cast(pOutputVector),reinterpret_cast<__m128d *>(&vResult)[0]); + pInputVector += InputStride; + pOutputVector += OutputStride; + } + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector2TransformNormal +( + FXMVECTOR V, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Result; + + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); + + Result = XMVectorMultiply(Y, M.r[1]); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,0,0,0)); + vResult = _mm_mul_ps(vResult,M.r[0]); + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + vTemp = _mm_mul_ps(vTemp,M.r[1]); + vResult = _mm_add_ps(vResult,vTemp); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT2* XMVector2TransformNormalStream +( + XMFLOAT2* pOutputStream, + UINT OutputStride, + CONST XMFLOAT2* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat2((XMFLOAT2*)pInputVector); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); +// Y = XMVectorReplicate(((XMFLOAT2*)pInputVector)->y); +// X = XMVectorReplicate(((XMFLOAT2*)pInputVector)->x); + + Result = XMVectorMultiply(Y, M.r[1]); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + XMStoreFloat2((XMFLOAT2*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + UINT i; + const BYTE*pInputVector = (const BYTE*)pInputStream; + BYTE *pOutputVector = (BYTE*)pOutputStream; + for (i = 0; i < VectorCount; i++) + { + XMVECTOR X = _mm_load_ps1(&reinterpret_cast(pInputVector)->x); + XMVECTOR vResult = _mm_load_ps1(&reinterpret_cast(pInputVector)->y); + vResult = _mm_mul_ps(vResult,M.r[1]); + X = _mm_mul_ps(X,M.r[0]); + vResult = _mm_add_ps(vResult,X); + _mm_store_sd(reinterpret_cast(pOutputVector),reinterpret_cast(&vResult)[0]); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +/**************************************************************************** + * + * 3D Vector + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3Equal +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] == V2.vector4_f32[0]) && (V1.vector4_f32[1] == V2.vector4_f32[1]) && (V1.vector4_f32[2] == V2.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&7)==7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector3EqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector3EqualR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if ((V1.vector4_f32[0] == V2.vector4_f32[0]) && + (V1.vector4_f32[1] == V2.vector4_f32[1]) && + (V1.vector4_f32[2] == V2.vector4_f32[2])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] != V2.vector4_f32[0]) && + (V1.vector4_f32[1] != V2.vector4_f32[1]) && + (V1.vector4_f32[2] != V2.vector4_f32[2])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); + int iTest = _mm_movemask_ps(vTemp)&7; + UINT CR = 0; + if (iTest==7) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3EqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_u32[0] == V2.vector4_u32[0]) && (V1.vector4_u32[1] == V2.vector4_u32[1]) && (V1.vector4_u32[2] == V2.vector4_u32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + return (((_mm_movemask_ps(reinterpret_cast(&vTemp)[0])&7)==7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector3EqualIntR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector3EqualIntR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if ((V1.vector4_u32[0] == V2.vector4_u32[0]) && + (V1.vector4_u32[1] == V2.vector4_u32[1]) && + (V1.vector4_u32[2] == V2.vector4_u32[2])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_u32[0] != V2.vector4_u32[0]) && + (V1.vector4_u32[1] != V2.vector4_u32[1]) && + (V1.vector4_u32[2] != V2.vector4_u32[2])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + int iTemp = _mm_movemask_ps(reinterpret_cast(&vTemp)[0])&7; + UINT CR = 0; + if (iTemp==7) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTemp) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3NearEqual +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR Epsilon +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT dx, dy, dz; + + dx = fabsf(V1.vector4_f32[0]-V2.vector4_f32[0]); + dy = fabsf(V1.vector4_f32[1]-V2.vector4_f32[1]); + dz = fabsf(V1.vector4_f32[2]-V2.vector4_f32[2]); + return (((dx <= Epsilon.vector4_f32[0]) && + (dy <= Epsilon.vector4_f32[1]) && + (dz <= Epsilon.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + // Get the difference + XMVECTOR vDelta = _mm_sub_ps(V1,V2); + // Get the absolute value of the difference + XMVECTOR vTemp = _mm_setzero_ps(); + vTemp = _mm_sub_ps(vTemp,vDelta); + vTemp = _mm_max_ps(vTemp,vDelta); + vTemp = _mm_cmple_ps(vTemp,Epsilon); + // w is don't care + return (((_mm_movemask_ps(vTemp)&7)==0x7) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3NotEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] != V2.vector4_f32[0]) || (V1.vector4_f32[1] != V2.vector4_f32[1]) || (V1.vector4_f32[2] != V2.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&7)!=7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAnyFalse(XMVector3EqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3NotEqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_u32[0] != V2.vector4_u32[0]) || (V1.vector4_u32[1] != V2.vector4_u32[1]) || (V1.vector4_u32[2] != V2.vector4_u32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + return (((_mm_movemask_ps(reinterpret_cast(&vTemp)[0])&7)!=7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAnyFalse(XMVector3EqualIntR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3Greater +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] > V2.vector4_f32[0]) && (V1.vector4_f32[1] > V2.vector4_f32[1]) && (V1.vector4_f32[2] > V2.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpgt_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&7)==7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector3GreaterR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector3GreaterR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if ((V1.vector4_f32[0] > V2.vector4_f32[0]) && + (V1.vector4_f32[1] > V2.vector4_f32[1]) && + (V1.vector4_f32[2] > V2.vector4_f32[2])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] <= V2.vector4_f32[0]) && + (V1.vector4_f32[1] <= V2.vector4_f32[1]) && + (V1.vector4_f32[2] <= V2.vector4_f32[2])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpgt_ps(V1,V2); + UINT CR = 0; + int iTest = _mm_movemask_ps(vTemp)&7; + if (iTest==7) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3GreaterOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] >= V2.vector4_f32[0]) && (V1.vector4_f32[1] >= V2.vector4_f32[1]) && (V1.vector4_f32[2] >= V2.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpge_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&7)==7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector3GreaterOrEqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector3GreaterOrEqualR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + UINT CR = 0; + if ((V1.vector4_f32[0] >= V2.vector4_f32[0]) && + (V1.vector4_f32[1] >= V2.vector4_f32[1]) && + (V1.vector4_f32[2] >= V2.vector4_f32[2])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] < V2.vector4_f32[0]) && + (V1.vector4_f32[1] < V2.vector4_f32[1]) && + (V1.vector4_f32[2] < V2.vector4_f32[2])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpge_ps(V1,V2); + UINT CR = 0; + int iTest = _mm_movemask_ps(vTemp)&7; + if (iTest==7) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3Less +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] < V2.vector4_f32[0]) && (V1.vector4_f32[1] < V2.vector4_f32[1]) && (V1.vector4_f32[2] < V2.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmplt_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&7)==7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector3GreaterR(V2, V1)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3LessOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] <= V2.vector4_f32[0]) && (V1.vector4_f32[1] <= V2.vector4_f32[1]) && (V1.vector4_f32[2] <= V2.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmple_ps(V1,V2); + return (((_mm_movemask_ps(vTemp)&7)==7) != 0); +#else // _XM_VMX128_INTRINSICS_ + return XMComparisonAllTrue(XMVector3GreaterOrEqualR(V2, V1)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3InBounds +( + FXMVECTOR V, + FXMVECTOR Bounds +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) && + (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1]) && + (V.vector4_f32[2] <= Bounds.vector4_f32[2] && V.vector4_f32[2] >= -Bounds.vector4_f32[2])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + // x,y and z in bounds? (w is don't care) + return (((_mm_movemask_ps(vTemp1)&0x7)==0x7) != 0); +#else + return XMComparisonAllInBounds(XMVector3InBoundsR(V, Bounds)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector3InBoundsR +( + FXMVECTOR V, + FXMVECTOR Bounds +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if ((V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) && + (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1]) && + (V.vector4_f32[2] <= Bounds.vector4_f32[2] && V.vector4_f32[2] >= -Bounds.vector4_f32[2])) + { + CR = XM_CRMASK_CR6BOUNDS; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + // x,y and z in bounds? (w is don't care) + return ((_mm_movemask_ps(vTemp1)&0x7)==0x7) ? XM_CRMASK_CR6BOUNDS : 0; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3IsNaN +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + return (XMISNAN(V.vector4_f32[0]) || + XMISNAN(V.vector4_f32[1]) || + XMISNAN(V.vector4_f32[2])); + +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the exponent + __m128i vTempInf = _mm_and_si128(reinterpret_cast(&V)[0],g_XMInfinity); + // Mask off the mantissa + __m128i vTempNan = _mm_and_si128(reinterpret_cast(&V)[0],g_XMQNaNTest); + // Are any of the exponents == 0x7F800000? + vTempInf = _mm_cmpeq_epi32(vTempInf,g_XMInfinity); + // Are any of the mantissa's zero? (SSE2 doesn't have a neq test) + vTempNan = _mm_cmpeq_epi32(vTempNan,g_XMZero); + // Perform a not on the NaN test to be true on NON-zero mantissas + vTempNan = _mm_andnot_si128(vTempNan,vTempInf); + // If x, y or z are NaN, the signs are true after the merge above + return ((_mm_movemask_ps(reinterpret_cast(&vTempNan)[0])&7) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector3IsInfinite +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (XMISINF(V.vector4_f32[0]) || + XMISINF(V.vector4_f32[1]) || + XMISINF(V.vector4_f32[2])); +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the sign bit + __m128 vTemp = _mm_and_ps(V,g_XMAbsMask); + // Compare to infinity + vTemp = _mm_cmpeq_ps(vTemp,g_XMInfinity); + // If x,y or z are infinity, the signs are true. + return ((_mm_movemask_ps(vTemp)&7) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Dot +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fValue = V1.vector4_f32[0] * V2.vector4_f32[0] + V1.vector4_f32[1] * V2.vector4_f32[1] + V1.vector4_f32[2] * V2.vector4_f32[2]; + XMVECTOR vResult = { + fValue, + fValue, + fValue, + fValue + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product + XMVECTOR vDot = _mm_mul_ps(V1,V2); + // x=Dot.vector4_f32[1], y=Dot.vector4_f32[2] + XMVECTOR vTemp = _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(2,1,2,1)); + // Result.vector4_f32[0] = x+y + vDot = _mm_add_ss(vDot,vTemp); + // x=Dot.vector4_f32[2] + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + // Result.vector4_f32[0] = (x+y)+z + vDot = _mm_add_ss(vDot,vTemp); + // Splat x + return _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(0,0,0,0)); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Cross +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR vResult = { + (V1.vector4_f32[1] * V2.vector4_f32[2]) - (V1.vector4_f32[2] * V2.vector4_f32[1]), + (V1.vector4_f32[2] * V2.vector4_f32[0]) - (V1.vector4_f32[0] * V2.vector4_f32[2]), + (V1.vector4_f32[0] * V2.vector4_f32[1]) - (V1.vector4_f32[1] * V2.vector4_f32[0]), + 0.0f + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + // y1,z1,x1,w1 + XMVECTOR vTemp1 = _mm_shuffle_ps(V1,V1,_MM_SHUFFLE(3,0,2,1)); + // z2,x2,y2,w2 + XMVECTOR vTemp2 = _mm_shuffle_ps(V2,V2,_MM_SHUFFLE(3,1,0,2)); + // Perform the left operation + XMVECTOR vResult = _mm_mul_ps(vTemp1,vTemp2); + // z1,x1,y1,w1 + vTemp1 = _mm_shuffle_ps(vTemp1,vTemp1,_MM_SHUFFLE(3,0,2,1)); + // y2,z2,x2,w2 + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp2,_MM_SHUFFLE(3,1,0,2)); + // Perform the right operation + vTemp1 = _mm_mul_ps(vTemp1,vTemp2); + // Subract the right from left, and return answer + vResult = _mm_sub_ps(vResult,vTemp1); + // Set w to zero + return _mm_and_ps(vResult,g_XMMask3); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3LengthSq +( + FXMVECTOR V +) +{ + return XMVector3Dot(V, V); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3ReciprocalLengthEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector3LengthSq(V); + Result = XMVectorReciprocalSqrtEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y and z + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and y + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,2,1,2)); + // x+z, y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + // y,y,y,y + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + // x+z+y,??,??,?? + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + // Splat the length squared + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + // Get the reciprocal + vLengthSq = _mm_rsqrt_ps(vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3ReciprocalLength +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector3LengthSq(V); + Result = XMVectorReciprocalSqrt(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product + XMVECTOR vDot = _mm_mul_ps(V,V); + // x=Dot.y, y=Dot.z + XMVECTOR vTemp = _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(2,1,2,1)); + // Result.x = x+y + vDot = _mm_add_ss(vDot,vTemp); + // x=Dot.z + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + // Result.x = (x+y)+z + vDot = _mm_add_ss(vDot,vTemp); + // Splat x + vDot = _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(0,0,0,0)); + // Get the reciprocal + vDot = _mm_sqrt_ps(vDot); + // Get the reciprocal + vDot = _mm_div_ps(g_XMOne,vDot); + return vDot; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3LengthEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector3LengthSq(V); + Result = XMVectorSqrtEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y and z + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and y + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,2,1,2)); + // x+z, y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + // y,y,y,y + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + // x+z+y,??,??,?? + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + // Splat the length squared + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + // Get the length + vLengthSq = _mm_sqrt_ps(vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Length +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector3LengthSq(V); + Result = XMVectorSqrt(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y and z + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and y + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,2,1,2)); + // x+z, y + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + // y,y,y,y + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + // x+z+y,??,??,?? + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + // Splat the length squared + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + // Get the length + vLengthSq = _mm_sqrt_ps(vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// XMVector3NormalizeEst uses a reciprocal estimate and +// returns QNaN on zero and infinite vectors. + +XMFINLINE XMVECTOR XMVector3NormalizeEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result = XMVector3ReciprocalLength(V); + Result = XMVectorMultiply(V, Result); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product + XMVECTOR vDot = _mm_mul_ps(V,V); + // x=Dot.y, y=Dot.z + XMVECTOR vTemp = _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(2,1,2,1)); + // Result.x = x+y + vDot = _mm_add_ss(vDot,vTemp); + // x=Dot.z + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + // Result.x = (x+y)+z + vDot = _mm_add_ss(vDot,vTemp); + // Splat x + vDot = _mm_shuffle_ps(vDot,vDot,_MM_SHUFFLE(0,0,0,0)); + // Get the reciprocal + vDot = _mm_rsqrt_ps(vDot); + // Perform the normalization + vDot = _mm_mul_ps(vDot,V); + return vDot; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Normalize +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fLength; + XMVECTOR vResult; + + vResult = XMVector3Length( V ); + fLength = vResult.vector4_f32[0]; + + // Prevent divide by zero + if (fLength > 0) { + fLength = 1.0f/fLength; + } + + vResult.vector4_f32[0] = V.vector4_f32[0]*fLength; + vResult.vector4_f32[1] = V.vector4_f32[1]*fLength; + vResult.vector4_f32[2] = V.vector4_f32[2]*fLength; + vResult.vector4_f32[3] = V.vector4_f32[3]*fLength; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y and z only + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,1,2,1)); + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,1,1,1)); + vLengthSq = _mm_add_ss(vLengthSq,vTemp); + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(0,0,0,0)); + // Prepare for the division + XMVECTOR vResult = _mm_sqrt_ps(vLengthSq); + // Create zero with a single instruction + XMVECTOR vZeroMask = _mm_setzero_ps(); + // Test for a divide by zero (Must be FP to detect -0.0) + vZeroMask = _mm_cmpneq_ps(vZeroMask,vResult); + // Failsafe on zero (Or epsilon) length planes + // If the length is infinity, set the elements to zero + vLengthSq = _mm_cmpneq_ps(vLengthSq,g_XMInfinity); + // Divide to perform the normalization + vResult = _mm_div_ps(V,vResult); + // Any that are infinity, set to zero + vResult = _mm_and_ps(vResult,vZeroMask); + // Select qnan or result based on infinite length + XMVECTOR vTemp1 = _mm_andnot_ps(vLengthSq,g_XMQNaN); + XMVECTOR vTemp2 = _mm_and_ps(vResult,vLengthSq); + vResult = _mm_or_ps(vTemp1,vTemp2); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3ClampLength +( + FXMVECTOR V, + FLOAT LengthMin, + FLOAT LengthMax +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR ClampMax; + XMVECTOR ClampMin; + + ClampMax = XMVectorReplicate(LengthMax); + ClampMin = XMVectorReplicate(LengthMin); + + return XMVector3ClampLengthV(V, ClampMin, ClampMax); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR ClampMax = _mm_set_ps1(LengthMax); + XMVECTOR ClampMin = _mm_set_ps1(LengthMin); + return XMVector3ClampLengthV(V,ClampMin,ClampMax); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3ClampLengthV +( + FXMVECTOR V, + FXMVECTOR LengthMin, + FXMVECTOR LengthMax +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR ClampLength; + XMVECTOR LengthSq; + XMVECTOR RcpLength; + XMVECTOR Length; + XMVECTOR Normal; + XMVECTOR Zero; + XMVECTOR InfiniteLength; + XMVECTOR ZeroLength; + XMVECTOR Select; + XMVECTOR ControlMax; + XMVECTOR ControlMin; + XMVECTOR Control; + XMVECTOR Result; + + XMASSERT((LengthMin.vector4_f32[1] == LengthMin.vector4_f32[0]) && (LengthMin.vector4_f32[2] == LengthMin.vector4_f32[0])); + XMASSERT((LengthMax.vector4_f32[1] == LengthMax.vector4_f32[0]) && (LengthMax.vector4_f32[2] == LengthMax.vector4_f32[0])); + XMASSERT(XMVector3GreaterOrEqual(LengthMin, XMVectorZero())); + XMASSERT(XMVector3GreaterOrEqual(LengthMax, XMVectorZero())); + XMASSERT(XMVector3GreaterOrEqual(LengthMax, LengthMin)); + + LengthSq = XMVector3LengthSq(V); + + Zero = XMVectorZero(); + + RcpLength = XMVectorReciprocalSqrt(LengthSq); + + InfiniteLength = XMVectorEqualInt(LengthSq, g_XMInfinity.v); + ZeroLength = XMVectorEqual(LengthSq, Zero); + + Normal = XMVectorMultiply(V, RcpLength); + + Length = XMVectorMultiply(LengthSq, RcpLength); + + Select = XMVectorEqualInt(InfiniteLength, ZeroLength); + Length = XMVectorSelect(LengthSq, Length, Select); + Normal = XMVectorSelect(LengthSq, Normal, Select); + + ControlMax = XMVectorGreater(Length, LengthMax); + ControlMin = XMVectorLess(Length, LengthMin); + + ClampLength = XMVectorSelect(Length, LengthMax, ControlMax); + ClampLength = XMVectorSelect(ClampLength, LengthMin, ControlMin); + + Result = XMVectorMultiply(Normal, ClampLength); + + // Preserve the original vector (with no precision loss) if the length falls within the given range + Control = XMVectorEqualInt(ControlMax, ControlMin); + Result = XMVectorSelect(Result, V, Control); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR ClampLength; + XMVECTOR LengthSq; + XMVECTOR RcpLength; + XMVECTOR Length; + XMVECTOR Normal; + XMVECTOR InfiniteLength; + XMVECTOR ZeroLength; + XMVECTOR Select; + XMVECTOR ControlMax; + XMVECTOR ControlMin; + XMVECTOR Control; + XMVECTOR Result; + + XMASSERT((XMVectorGetY(LengthMin) == XMVectorGetX(LengthMin)) && (XMVectorGetZ(LengthMin) == XMVectorGetX(LengthMin))); + XMASSERT((XMVectorGetY(LengthMax) == XMVectorGetX(LengthMax)) && (XMVectorGetZ(LengthMax) == XMVectorGetX(LengthMax))); + XMASSERT(XMVector3GreaterOrEqual(LengthMin, g_XMZero)); + XMASSERT(XMVector3GreaterOrEqual(LengthMax, g_XMZero)); + XMASSERT(XMVector3GreaterOrEqual(LengthMax, LengthMin)); + + LengthSq = XMVector3LengthSq(V); + RcpLength = XMVectorReciprocalSqrt(LengthSq); + InfiniteLength = XMVectorEqualInt(LengthSq, g_XMInfinity); + ZeroLength = XMVectorEqual(LengthSq,g_XMZero); + Normal = _mm_mul_ps(V, RcpLength); + Length = _mm_mul_ps(LengthSq, RcpLength); + Select = XMVectorEqualInt(InfiniteLength, ZeroLength); + Length = XMVectorSelect(LengthSq, Length, Select); + Normal = XMVectorSelect(LengthSq, Normal, Select); + ControlMax = XMVectorGreater(Length, LengthMax); + ControlMin = XMVectorLess(Length, LengthMin); + ClampLength = XMVectorSelect(Length, LengthMax, ControlMax); + ClampLength = XMVectorSelect(ClampLength, LengthMin, ControlMin); + Result = _mm_mul_ps(Normal, ClampLength); + // Preserve the original vector (with no precision loss) if the length falls within the given range + Control = XMVectorEqualInt(ControlMax, ControlMin); + Result = XMVectorSelect(Result, V, Control); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Reflect +( + FXMVECTOR Incident, + FXMVECTOR Normal +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + // Result = Incident - (2 * dot(Incident, Normal)) * Normal + Result = XMVector3Dot(Incident, Normal); + Result = XMVectorAdd(Result, Result); + Result = XMVectorNegativeMultiplySubtract(Result, Normal, Incident); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Result = Incident - (2 * dot(Incident, Normal)) * Normal + XMVECTOR Result = XMVector3Dot(Incident, Normal); + Result = _mm_add_ps(Result, Result); + Result = _mm_mul_ps(Result, Normal); + Result = _mm_sub_ps(Incident,Result); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Refract +( + FXMVECTOR Incident, + FXMVECTOR Normal, + FLOAT RefractionIndex +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Index; + Index = XMVectorReplicate(RefractionIndex); + return XMVector3RefractV(Incident, Normal, Index); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Index = _mm_set_ps1(RefractionIndex); + return XMVector3RefractV(Incident,Normal,Index); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3RefractV +( + FXMVECTOR Incident, + FXMVECTOR Normal, + FXMVECTOR RefractionIndex +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR IDotN; + XMVECTOR R; + CONST XMVECTOR Zero = XMVectorZero(); + + // Result = RefractionIndex * Incident - Normal * (RefractionIndex * dot(Incident, Normal) + + // sqrt(1 - RefractionIndex * RefractionIndex * (1 - dot(Incident, Normal) * dot(Incident, Normal)))) + + IDotN = XMVector3Dot(Incident, Normal); + + // R = 1.0f - RefractionIndex * RefractionIndex * (1.0f - IDotN * IDotN) + R = XMVectorNegativeMultiplySubtract(IDotN, IDotN, g_XMOne.v); + R = XMVectorMultiply(R, RefractionIndex); + R = XMVectorNegativeMultiplySubtract(R, RefractionIndex, g_XMOne.v); + + if (XMVector4LessOrEqual(R, Zero)) + { + // Total internal reflection + return Zero; + } + else + { + XMVECTOR Result; + + // R = RefractionIndex * IDotN + sqrt(R) + R = XMVectorSqrt(R); + R = XMVectorMultiplyAdd(RefractionIndex, IDotN, R); + + // Result = RefractionIndex * Incident - Normal * R + Result = XMVectorMultiply(RefractionIndex, Incident); + Result = XMVectorNegativeMultiplySubtract(Normal, R, Result); + + return Result; + } + +#elif defined(_XM_SSE_INTRINSICS_) + // Result = RefractionIndex * Incident - Normal * (RefractionIndex * dot(Incident, Normal) + + // sqrt(1 - RefractionIndex * RefractionIndex * (1 - dot(Incident, Normal) * dot(Incident, Normal)))) + XMVECTOR IDotN = XMVector3Dot(Incident, Normal); + // R = 1.0f - RefractionIndex * RefractionIndex * (1.0f - IDotN * IDotN) + XMVECTOR R = _mm_mul_ps(IDotN, IDotN); + R = _mm_sub_ps(g_XMOne,R); + R = _mm_mul_ps(R, RefractionIndex); + R = _mm_mul_ps(R, RefractionIndex); + R = _mm_sub_ps(g_XMOne,R); + + XMVECTOR vResult = _mm_cmple_ps(R,g_XMZero); + if (_mm_movemask_ps(vResult)==0x0f) + { + // Total internal reflection + vResult = g_XMZero; + } + else + { + // R = RefractionIndex * IDotN + sqrt(R) + R = _mm_sqrt_ps(R); + vResult = _mm_mul_ps(RefractionIndex,IDotN); + R = _mm_add_ps(R,vResult); + // Result = RefractionIndex * Incident - Normal * R + vResult = _mm_mul_ps(RefractionIndex, Incident); + R = _mm_mul_ps(R,Normal); + vResult = _mm_sub_ps(vResult,R); + } + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Orthogonal +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR NegativeV; + XMVECTOR Z, YZYY; + XMVECTOR ZIsNegative, YZYYIsNegative; + XMVECTOR S, D; + XMVECTOR R0, R1; + XMVECTOR Select; + XMVECTOR Zero; + XMVECTOR Result; + static CONST XMVECTORU32 Permute1X0X0X0X = {XM_PERMUTE_1X, XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0X}; + static CONST XMVECTORU32 Permute0Y0Z0Y0Y= {XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_0Y}; + + Zero = XMVectorZero(); + Z = XMVectorSplatZ(V); + YZYY = XMVectorPermute(V, V, Permute0Y0Z0Y0Y.v); + + NegativeV = XMVectorSubtract(Zero, V); + + ZIsNegative = XMVectorLess(Z, Zero); + YZYYIsNegative = XMVectorLess(YZYY, Zero); + + S = XMVectorAdd(YZYY, Z); + D = XMVectorSubtract(YZYY, Z); + + Select = XMVectorEqualInt(ZIsNegative, YZYYIsNegative); + + R0 = XMVectorPermute(NegativeV, S, Permute1X0X0X0X.v); + R1 = XMVectorPermute(V, D, Permute1X0X0X0X.v); + + Result = XMVectorSelect(R1, R0, Select); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR NegativeV; + XMVECTOR Z, YZYY; + XMVECTOR ZIsNegative, YZYYIsNegative; + XMVECTOR S, D; + XMVECTOR R0, R1; + XMVECTOR Select; + XMVECTOR Zero; + XMVECTOR Result; + static CONST XMVECTORI32 Permute1X0X0X0X = {XM_PERMUTE_1X, XM_PERMUTE_0X, XM_PERMUTE_0X, XM_PERMUTE_0X}; + static CONST XMVECTORI32 Permute0Y0Z0Y0Y= {XM_PERMUTE_0Y, XM_PERMUTE_0Z, XM_PERMUTE_0Y, XM_PERMUTE_0Y}; + + Zero = XMVectorZero(); + Z = XMVectorSplatZ(V); + YZYY = XMVectorPermute(V, V, Permute0Y0Z0Y0Y); + + NegativeV = _mm_sub_ps(Zero, V); + + ZIsNegative = XMVectorLess(Z, Zero); + YZYYIsNegative = XMVectorLess(YZYY, Zero); + + S = _mm_add_ps(YZYY, Z); + D = _mm_sub_ps(YZYY, Z); + + Select = XMVectorEqualInt(ZIsNegative, YZYYIsNegative); + + R0 = XMVectorPermute(NegativeV, S, Permute1X0X0X0X); + R1 = XMVectorPermute(V, D,Permute1X0X0X0X); + Result = XMVectorSelect(R1, R0, Select); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3AngleBetweenNormalsEst +( + FXMVECTOR N1, + FXMVECTOR N2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + XMVECTOR NegativeOne; + XMVECTOR One; + + Result = XMVector3Dot(N1, N2); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + Result = XMVectorClamp(Result, NegativeOne, One); + Result = XMVectorACosEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = XMVector3Dot(N1,N2); + // Clamp to -1.0f to 1.0f + vResult = _mm_max_ps(vResult,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + vResult = XMVectorACosEst(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3AngleBetweenNormals +( + FXMVECTOR N1, + FXMVECTOR N2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + XMVECTOR NegativeOne; + XMVECTOR One; + + Result = XMVector3Dot(N1, N2); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + Result = XMVectorClamp(Result, NegativeOne, One); + Result = XMVectorACos(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = XMVector3Dot(N1,N2); + // Clamp to -1.0f to 1.0f + vResult = _mm_max_ps(vResult,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne); + vResult = XMVectorACos(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3AngleBetweenVectors +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR L1; + XMVECTOR L2; + XMVECTOR Dot; + XMVECTOR CosAngle; + XMVECTOR NegativeOne; + XMVECTOR One; + XMVECTOR Result; + + L1 = XMVector3ReciprocalLength(V1); + L2 = XMVector3ReciprocalLength(V2); + + Dot = XMVector3Dot(V1, V2); + + L1 = XMVectorMultiply(L1, L2); + + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + + CosAngle = XMVectorMultiply(Dot, L1); + + CosAngle = XMVectorClamp(CosAngle, NegativeOne, One); + + Result = XMVectorACos(CosAngle); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR L1; + XMVECTOR L2; + XMVECTOR Dot; + XMVECTOR CosAngle; + XMVECTOR Result; + + L1 = XMVector3ReciprocalLength(V1); + L2 = XMVector3ReciprocalLength(V2); + Dot = XMVector3Dot(V1, V2); + L1 = _mm_mul_ps(L1, L2); + CosAngle = _mm_mul_ps(Dot, L1); + CosAngle = XMVectorClamp(CosAngle,g_XMNegativeOne,g_XMOne); + Result = XMVectorACos(CosAngle); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3LinePointDistance +( + FXMVECTOR LinePoint1, + FXMVECTOR LinePoint2, + FXMVECTOR Point +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR PointVector; + XMVECTOR LineVector; + XMVECTOR ReciprocalLengthSq; + XMVECTOR PointProjectionScale; + XMVECTOR DistanceVector; + XMVECTOR Result; + + // Given a vector PointVector from LinePoint1 to Point and a vector + // LineVector from LinePoint1 to LinePoint2, the scaled distance + // PointProjectionScale from LinePoint1 to the perpendicular projection + // of PointVector onto the line is defined as: + // + // PointProjectionScale = dot(PointVector, LineVector) / LengthSq(LineVector) + + PointVector = XMVectorSubtract(Point, LinePoint1); + LineVector = XMVectorSubtract(LinePoint2, LinePoint1); + + ReciprocalLengthSq = XMVector3LengthSq(LineVector); + ReciprocalLengthSq = XMVectorReciprocal(ReciprocalLengthSq); + + PointProjectionScale = XMVector3Dot(PointVector, LineVector); + PointProjectionScale = XMVectorMultiply(PointProjectionScale, ReciprocalLengthSq); + + DistanceVector = XMVectorMultiply(LineVector, PointProjectionScale); + DistanceVector = XMVectorSubtract(PointVector, DistanceVector); + + Result = XMVector3Length(DistanceVector); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR PointVector = _mm_sub_ps(Point,LinePoint1); + XMVECTOR LineVector = _mm_sub_ps(LinePoint2,LinePoint1); + XMVECTOR ReciprocalLengthSq = XMVector3LengthSq(LineVector); + XMVECTOR vResult = XMVector3Dot(PointVector,LineVector); + vResult = _mm_div_ps(vResult,ReciprocalLengthSq); + vResult = _mm_mul_ps(vResult,LineVector); + vResult = _mm_sub_ps(PointVector,vResult); + vResult = XMVector3Length(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE VOID XMVector3ComponentsFromNormal +( + XMVECTOR* pParallel, + XMVECTOR* pPerpendicular, + FXMVECTOR V, + FXMVECTOR Normal +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Parallel; + XMVECTOR Scale; + + XMASSERT(pParallel); + XMASSERT(pPerpendicular); + + Scale = XMVector3Dot(V, Normal); + + Parallel = XMVectorMultiply(Normal, Scale); + + *pParallel = Parallel; + *pPerpendicular = XMVectorSubtract(V, Parallel); + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pParallel); + XMASSERT(pPerpendicular); + XMVECTOR Scale = XMVector3Dot(V, Normal); + XMVECTOR Parallel = _mm_mul_ps(Normal,Scale); + *pParallel = Parallel; + *pPerpendicular = _mm_sub_ps(V,Parallel); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Transform a vector using a rotation expressed as a unit quaternion + +XMFINLINE XMVECTOR XMVector3Rotate +( + FXMVECTOR V, + FXMVECTOR RotationQuaternion +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR A; + XMVECTOR Q; + XMVECTOR Result; + + A = XMVectorSelect(g_XMSelect1110.v, V, g_XMSelect1110.v); + Q = XMQuaternionConjugate(RotationQuaternion); + Result = XMQuaternionMultiply(Q, A); + Result = XMQuaternionMultiply(Result, RotationQuaternion); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR A; + XMVECTOR Q; + XMVECTOR Result; + + A = _mm_and_ps(V,g_XMMask3); + Q = XMQuaternionConjugate(RotationQuaternion); + Result = XMQuaternionMultiply(Q, A); + Result = XMQuaternionMultiply(Result, RotationQuaternion); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Transform a vector using the inverse of a rotation expressed as a unit quaternion + +XMFINLINE XMVECTOR XMVector3InverseRotate +( + FXMVECTOR V, + FXMVECTOR RotationQuaternion +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR A; + XMVECTOR Q; + XMVECTOR Result; + + A = XMVectorSelect(g_XMSelect1110.v, V, g_XMSelect1110.v); + Result = XMQuaternionMultiply(RotationQuaternion, A); + Q = XMQuaternionConjugate(RotationQuaternion); + Result = XMQuaternionMultiply(Result, Q); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR A; + XMVECTOR Q; + XMVECTOR Result; + A = _mm_and_ps(V,g_XMMask3); + Result = XMQuaternionMultiply(RotationQuaternion, A); + Q = XMQuaternionConjugate(RotationQuaternion); + Result = XMQuaternionMultiply(Result, Q); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Transform +( + FXMVECTOR V, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR Result; + + Z = XMVectorSplatZ(V); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); + + Result = XMVectorMultiplyAdd(Z, M.r[2], M.r[3]); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,0,0,0)); + vResult = _mm_mul_ps(vResult,M.r[0]); + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + vTemp = _mm_mul_ps(vTemp,M.r[1]); + vResult = _mm_add_ps(vResult,vTemp); + vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + vTemp = _mm_mul_ps(vTemp,M.r[2]); + vResult = _mm_add_ps(vResult,vTemp); + vResult = _mm_add_ps(vResult,M.r[3]); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT4* XMVector3TransformStream +( + XMFLOAT4* pOutputStream, + UINT OutputStride, + CONST XMFLOAT3* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat3((XMFLOAT3*)pInputVector); + Z = XMVectorSplatZ(V); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); + + Result = XMVectorMultiplyAdd(Z, M.r[2], M.r[3]); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + XMStoreFloat4((XMFLOAT4*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + UINT i; + const BYTE* pInputVector = (const BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + for (i = 0; i < VectorCount; i++) + { + XMVECTOR X = _mm_load_ps1(&reinterpret_cast(pInputVector)->x); + XMVECTOR Y = _mm_load_ps1(&reinterpret_cast(pInputVector)->y); + XMVECTOR vResult = _mm_load_ps1(&reinterpret_cast(pInputVector)->z); + vResult = _mm_mul_ps(vResult,M.r[2]); + vResult = _mm_add_ps(vResult,M.r[3]); + Y = _mm_mul_ps(Y,M.r[1]); + vResult = _mm_add_ps(vResult,Y); + X = _mm_mul_ps(X,M.r[0]); + vResult = _mm_add_ps(vResult,X); + _mm_storeu_ps(reinterpret_cast(pOutputVector),vResult); + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT4* XMVector3TransformStreamNC +( + XMFLOAT4* pOutputStream, + UINT OutputStride, + CONST XMFLOAT3* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) || defined(_XM_SSE_INTRINSICS_) + return XMVector3TransformStream( pOutputStream, OutputStride, pInputStream, InputStride, VectorCount, M ); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3TransformCoord +( + FXMVECTOR V, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR InverseW; + XMVECTOR Result; + + Z = XMVectorSplatZ(V); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); + + Result = XMVectorMultiplyAdd(Z, M.r[2], M.r[3]); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + InverseW = XMVectorSplatW(Result); + InverseW = XMVectorReciprocal(InverseW); + + Result = XMVectorMultiply(Result, InverseW); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,0,0,0)); + vResult = _mm_mul_ps(vResult,M.r[0]); + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + vTemp = _mm_mul_ps(vTemp,M.r[1]); + vResult = _mm_add_ps(vResult,vTemp); + vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + vTemp = _mm_mul_ps(vTemp,M.r[2]); + vResult = _mm_add_ps(vResult,vTemp); + vResult = _mm_add_ps(vResult,M.r[3]); + vTemp = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,3,3,3)); + vResult = _mm_div_ps(vResult,vTemp); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT3* XMVector3TransformCoordStream +( + XMFLOAT3* pOutputStream, + UINT OutputStride, + CONST XMFLOAT3* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR InverseW; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat3((XMFLOAT3*)pInputVector); + Z = XMVectorSplatZ(V); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); +// Z = XMVectorReplicate(((XMFLOAT3*)pInputVector)->z); +// Y = XMVectorReplicate(((XMFLOAT3*)pInputVector)->y); +// X = XMVectorReplicate(((XMFLOAT3*)pInputVector)->x); + + Result = XMVectorMultiplyAdd(Z, M.r[2], M.r[3]); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + InverseW = XMVectorSplatW(Result); + InverseW = XMVectorReciprocal(InverseW); + + Result = XMVectorMultiply(Result, InverseW); + + XMStoreFloat3((XMFLOAT3*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + UINT i; + const BYTE *pInputVector = (BYTE*)pInputStream; + BYTE *pOutputVector = (BYTE*)pOutputStream; + + for (i = 0; i < VectorCount; i++) + { + XMVECTOR X = _mm_load_ps1(&reinterpret_cast(pInputVector)->x); + XMVECTOR Y = _mm_load_ps1(&reinterpret_cast(pInputVector)->y); + XMVECTOR vResult = _mm_load_ps1(&reinterpret_cast(pInputVector)->z); + vResult = _mm_mul_ps(vResult,M.r[2]); + vResult = _mm_add_ps(vResult,M.r[3]); + Y = _mm_mul_ps(Y,M.r[1]); + vResult = _mm_add_ps(vResult,Y); + X = _mm_mul_ps(X,M.r[0]); + vResult = _mm_add_ps(vResult,X); + + X = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,3,3,3)); + vResult = _mm_div_ps(vResult,X); + _mm_store_ss(&reinterpret_cast(pOutputVector)->x,vResult); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + _mm_store_ss(&reinterpret_cast(pOutputVector)->y,vResult); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + _mm_store_ss(&reinterpret_cast(pOutputVector)->z,vResult); + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3TransformNormal +( + FXMVECTOR V, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR Result; + + Z = XMVectorSplatZ(V); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); + + Result = XMVectorMultiply(Z, M.r[2]); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,0,0,0)); + vResult = _mm_mul_ps(vResult,M.r[0]); + XMVECTOR vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + vTemp = _mm_mul_ps(vTemp,M.r[1]); + vResult = _mm_add_ps(vResult,vTemp); + vTemp = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + vTemp = _mm_mul_ps(vTemp,M.r[2]); + vResult = _mm_add_ps(vResult,vTemp); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT3* XMVector3TransformNormalStream +( + XMFLOAT3* pOutputStream, + UINT OutputStride, + CONST XMFLOAT3* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat3((XMFLOAT3*)pInputVector); + Z = XMVectorSplatZ(V); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); +// Z = XMVectorReplicate(((XMFLOAT3*)pInputVector)->z); +// Y = XMVectorReplicate(((XMFLOAT3*)pInputVector)->y); +// X = XMVectorReplicate(((XMFLOAT3*)pInputVector)->x); + + Result = XMVectorMultiply(Z, M.r[2]); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + XMStoreFloat3((XMFLOAT3*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + UINT i; + const BYTE *pInputVector = (BYTE*)pInputStream; + BYTE *pOutputVector = (BYTE*)pOutputStream; + + for (i = 0; i < VectorCount; i++) + { + XMVECTOR X = _mm_load_ps1(&reinterpret_cast(pInputVector)->x); + XMVECTOR Y = _mm_load_ps1(&reinterpret_cast(pInputVector)->y); + XMVECTOR vResult = _mm_load_ps1(&reinterpret_cast(pInputVector)->z); + vResult = _mm_mul_ps(vResult,M.r[2]); + Y = _mm_mul_ps(Y,M.r[1]); + vResult = _mm_add_ps(vResult,Y); + X = _mm_mul_ps(X,M.r[0]); + vResult = _mm_add_ps(vResult,X); + _mm_store_ss(&reinterpret_cast(pOutputVector)->x,vResult); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + _mm_store_ss(&reinterpret_cast(pOutputVector)->y,vResult); + vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1)); + _mm_store_ss(&reinterpret_cast(pOutputVector)->z,vResult); + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMVECTOR XMVector3Project +( + FXMVECTOR V, + FLOAT ViewportX, + FLOAT ViewportY, + FLOAT ViewportWidth, + FLOAT ViewportHeight, + FLOAT ViewportMinZ, + FLOAT ViewportMaxZ, + CXMMATRIX Projection, + CXMMATRIX View, + CXMMATRIX World +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX Transform; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR Result; + FLOAT HalfViewportWidth = ViewportWidth * 0.5f; + FLOAT HalfViewportHeight = ViewportHeight * 0.5f; + + Scale = XMVectorSet(HalfViewportWidth, + -HalfViewportHeight, + ViewportMaxZ - ViewportMinZ, + 0.0f); + + Offset = XMVectorSet(ViewportX + HalfViewportWidth, + ViewportY + HalfViewportHeight, + ViewportMinZ, + 0.0f); + + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + + Result = XMVector3TransformCoord(V, Transform); + + Result = XMVectorMultiplyAdd(Result, Scale, Offset); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX Transform; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR Result; + FLOAT HalfViewportWidth = ViewportWidth * 0.5f; + FLOAT HalfViewportHeight = ViewportHeight * 0.5f; + + Scale = XMVectorSet(HalfViewportWidth, + -HalfViewportHeight, + ViewportMaxZ - ViewportMinZ, + 0.0f); + + Offset = XMVectorSet(ViewportX + HalfViewportWidth, + ViewportY + HalfViewportHeight, + ViewportMinZ, + 0.0f); + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + Result = XMVector3TransformCoord(V, Transform); + Result = _mm_mul_ps(Result,Scale); + Result = _mm_add_ps(Result,Offset); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT3* XMVector3ProjectStream +( + XMFLOAT3* pOutputStream, + UINT OutputStride, + CONST XMFLOAT3* pInputStream, + UINT InputStride, + UINT VectorCount, + FLOAT ViewportX, + FLOAT ViewportY, + FLOAT ViewportWidth, + FLOAT ViewportHeight, + FLOAT ViewportMinZ, + FLOAT ViewportMaxZ, + CXMMATRIX Projection, + CXMMATRIX View, + CXMMATRIX World +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX Transform; + XMVECTOR V; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR Result; + UINT i; + FLOAT HalfViewportWidth = ViewportWidth * 0.5f; + FLOAT HalfViewportHeight = ViewportHeight * 0.5f; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + Scale = XMVectorSet(HalfViewportWidth, + -HalfViewportHeight, + ViewportMaxZ - ViewportMinZ, + 1.0f); + + Offset = XMVectorSet(ViewportX + HalfViewportWidth, + ViewportY + HalfViewportHeight, + ViewportMinZ, + 0.0f); + + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat3((XMFLOAT3*)pInputVector); + + Result = XMVector3TransformCoord(V, Transform); + + Result = XMVectorMultiplyAdd(Result, Scale, Offset); + + XMStoreFloat3((XMFLOAT3*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + XMMATRIX Transform; + XMVECTOR V; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR Result; + UINT i; + FLOAT HalfViewportWidth = ViewportWidth * 0.5f; + FLOAT HalfViewportHeight = ViewportHeight * 0.5f; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + Scale = XMVectorSet(HalfViewportWidth, + -HalfViewportHeight, + ViewportMaxZ - ViewportMinZ, + 1.0f); + + Offset = XMVectorSet(ViewportX + HalfViewportWidth, + ViewportY + HalfViewportHeight, + ViewportMinZ, + 0.0f); + + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat3((XMFLOAT3*)pInputVector); + + Result = XMVector3TransformCoord(V, Transform); + + Result = _mm_mul_ps(Result,Scale); + Result = _mm_add_ps(Result,Offset); + XMStoreFloat3((XMFLOAT3*)pOutputVector, Result); + pInputVector += InputStride; + pOutputVector += OutputStride; + } + return pOutputStream; + +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector3Unproject +( + FXMVECTOR V, + FLOAT ViewportX, + FLOAT ViewportY, + FLOAT ViewportWidth, + FLOAT ViewportHeight, + FLOAT ViewportMinZ, + FLOAT ViewportMaxZ, + CXMMATRIX Projection, + CXMMATRIX View, + CXMMATRIX World +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX Transform; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR Determinant; + XMVECTOR Result; + CONST XMVECTOR D = XMVectorSet(-1.0f, 1.0f, 0.0f, 0.0f); + + Scale = XMVectorSet(ViewportWidth * 0.5f, + -ViewportHeight * 0.5f, + ViewportMaxZ - ViewportMinZ, + 1.0f); + Scale = XMVectorReciprocal(Scale); + + Offset = XMVectorSet(-ViewportX, + -ViewportY, + -ViewportMinZ, + 0.0f); + Offset = XMVectorMultiplyAdd(Scale, Offset, D); + + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + Transform = XMMatrixInverse(&Determinant, Transform); + + Result = XMVectorMultiplyAdd(V, Scale, Offset); + + Result = XMVector3TransformCoord(Result, Transform); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMMATRIX Transform; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR Determinant; + XMVECTOR Result; + CONST XMVECTORF32 D = {-1.0f, 1.0f, 0.0f, 0.0f}; + + Scale = XMVectorSet(ViewportWidth * 0.5f, + -ViewportHeight * 0.5f, + ViewportMaxZ - ViewportMinZ, + 1.0f); + Scale = XMVectorReciprocal(Scale); + + Offset = XMVectorSet(-ViewportX, + -ViewportY, + -ViewportMinZ, + 0.0f); + Offset = _mm_mul_ps(Offset,Scale); + Offset = _mm_add_ps(Offset,D); + + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + Transform = XMMatrixInverse(&Determinant, Transform); + + Result = _mm_mul_ps(V,Scale); + Result = _mm_add_ps(Result,Offset); + + Result = XMVector3TransformCoord(Result, Transform); + + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT3* XMVector3UnprojectStream +( + XMFLOAT3* pOutputStream, + UINT OutputStride, + CONST XMFLOAT3* pInputStream, + UINT InputStride, + UINT VectorCount, + FLOAT ViewportX, + FLOAT ViewportY, + FLOAT ViewportWidth, + FLOAT ViewportHeight, + FLOAT ViewportMinZ, + FLOAT ViewportMaxZ, + CXMMATRIX Projection, + CXMMATRIX View, + CXMMATRIX World) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMMATRIX Transform; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR V; + XMVECTOR Determinant; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + CONST XMVECTOR D = XMVectorSet(-1.0f, 1.0f, 0.0f, 0.0f); + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + Scale = XMVectorSet(ViewportWidth * 0.5f, + -ViewportHeight * 0.5f, + ViewportMaxZ - ViewportMinZ, + 1.0f); + Scale = XMVectorReciprocal(Scale); + + Offset = XMVectorSet(-ViewportX, + -ViewportY, + -ViewportMinZ, + 0.0f); + Offset = XMVectorMultiplyAdd(Scale, Offset, D); + + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + Transform = XMMatrixInverse(&Determinant, Transform); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat3((XMFLOAT3*)pInputVector); + + Result = XMVectorMultiplyAdd(V, Scale, Offset); + + Result = XMVector3TransformCoord(Result, Transform); + + XMStoreFloat3((XMFLOAT3*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + XMMATRIX Transform; + XMVECTOR Scale; + XMVECTOR Offset; + XMVECTOR V; + XMVECTOR Determinant; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + CONST XMVECTORF32 D = {-1.0f, 1.0f, 0.0f, 0.0f}; + + Scale = XMVectorSet(ViewportWidth * 0.5f, + -ViewportHeight * 0.5f, + ViewportMaxZ - ViewportMinZ, + 1.0f); + Scale = XMVectorReciprocal(Scale); + + Offset = XMVectorSet(-ViewportX, + -ViewportY, + -ViewportMinZ, + 0.0f); + Offset = _mm_mul_ps(Offset,Scale); + Offset = _mm_add_ps(Offset,D); + + Transform = XMMatrixMultiply(World, View); + Transform = XMMatrixMultiply(Transform, Projection); + Transform = XMMatrixInverse(&Determinant, Transform); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat3((XMFLOAT3*)pInputVector); + + Result = XMVectorMultiplyAdd(V, Scale, Offset); + + Result = XMVector3TransformCoord(Result, Transform); + + XMStoreFloat3((XMFLOAT3*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +/**************************************************************************** + * + * 4D Vector + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparison operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4Equal +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] == V2.vector4_f32[0]) && (V1.vector4_f32[1] == V2.vector4_f32[1]) && (V1.vector4_f32[2] == V2.vector4_f32[2]) && (V1.vector4_f32[3] == V2.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); + return ((_mm_movemask_ps(vTemp)==0x0f) != 0); +#else + return XMComparisonAllTrue(XMVector4EqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector4EqualR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + UINT CR = 0; + + if ((V1.vector4_f32[0] == V2.vector4_f32[0]) && + (V1.vector4_f32[1] == V2.vector4_f32[1]) && + (V1.vector4_f32[2] == V2.vector4_f32[2]) && + (V1.vector4_f32[3] == V2.vector4_f32[3])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] != V2.vector4_f32[0]) && + (V1.vector4_f32[1] != V2.vector4_f32[1]) && + (V1.vector4_f32[2] != V2.vector4_f32[2]) && + (V1.vector4_f32[3] != V2.vector4_f32[3])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpeq_ps(V1,V2); + int iTest = _mm_movemask_ps(vTemp); + UINT CR = 0; + if (iTest==0xf) // All equal? + { + CR = XM_CRMASK_CR6TRUE; + } + else if (iTest==0) // All not equal? + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4EqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_u32[0] == V2.vector4_u32[0]) && (V1.vector4_u32[1] == V2.vector4_u32[1]) && (V1.vector4_u32[2] == V2.vector4_u32[2]) && (V1.vector4_u32[3] == V2.vector4_u32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + return ((_mm_movemask_ps(reinterpret_cast(&vTemp)[0])==0xf) != 0); +#else + return XMComparisonAllTrue(XMVector4EqualIntR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector4EqualIntR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if (V1.vector4_u32[0] == V2.vector4_u32[0] && + V1.vector4_u32[1] == V2.vector4_u32[1] && + V1.vector4_u32[2] == V2.vector4_u32[2] && + V1.vector4_u32[3] == V2.vector4_u32[3]) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (V1.vector4_u32[0] != V2.vector4_u32[0] && + V1.vector4_u32[1] != V2.vector4_u32[1] && + V1.vector4_u32[2] != V2.vector4_u32[2] && + V1.vector4_u32[3] != V2.vector4_u32[3]) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + int iTest = _mm_movemask_ps(reinterpret_cast(&vTemp)[0]); + UINT CR = 0; + if (iTest==0xf) // All equal? + { + CR = XM_CRMASK_CR6TRUE; + } + else if (iTest==0) // All not equal? + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +XMFINLINE BOOL XMVector4NearEqual +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR Epsilon +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT dx, dy, dz, dw; + + dx = fabsf(V1.vector4_f32[0]-V2.vector4_f32[0]); + dy = fabsf(V1.vector4_f32[1]-V2.vector4_f32[1]); + dz = fabsf(V1.vector4_f32[2]-V2.vector4_f32[2]); + dw = fabsf(V1.vector4_f32[3]-V2.vector4_f32[3]); + return (((dx <= Epsilon.vector4_f32[0]) && + (dy <= Epsilon.vector4_f32[1]) && + (dz <= Epsilon.vector4_f32[2]) && + (dw <= Epsilon.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + // Get the difference + XMVECTOR vDelta = _mm_sub_ps(V1,V2); + // Get the absolute value of the difference + XMVECTOR vTemp = _mm_setzero_ps(); + vTemp = _mm_sub_ps(vTemp,vDelta); + vTemp = _mm_max_ps(vTemp,vDelta); + vTemp = _mm_cmple_ps(vTemp,Epsilon); + return ((_mm_movemask_ps(vTemp)==0xf) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4NotEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] != V2.vector4_f32[0]) || (V1.vector4_f32[1] != V2.vector4_f32[1]) || (V1.vector4_f32[2] != V2.vector4_f32[2]) || (V1.vector4_f32[3] != V2.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpneq_ps(V1,V2); + return ((_mm_movemask_ps(vTemp)) != 0); +#else + return XMComparisonAnyFalse(XMVector4EqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4NotEqualInt +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_u32[0] != V2.vector4_u32[0]) || (V1.vector4_u32[1] != V2.vector4_u32[1]) || (V1.vector4_u32[2] != V2.vector4_u32[2]) || (V1.vector4_u32[3] != V2.vector4_u32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + __m128i vTemp = _mm_cmpeq_epi32(reinterpret_cast(&V1)[0],reinterpret_cast(&V2)[0]); + return ((_mm_movemask_ps(reinterpret_cast(&vTemp)[0])!=0xF) != 0); +#else + return XMComparisonAnyFalse(XMVector4EqualIntR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4Greater +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] > V2.vector4_f32[0]) && (V1.vector4_f32[1] > V2.vector4_f32[1]) && (V1.vector4_f32[2] > V2.vector4_f32[2]) && (V1.vector4_f32[3] > V2.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpgt_ps(V1,V2); + return ((_mm_movemask_ps(vTemp)==0x0f) != 0); +#else + return XMComparisonAllTrue(XMVector4GreaterR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector4GreaterR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if (V1.vector4_f32[0] > V2.vector4_f32[0] && + V1.vector4_f32[1] > V2.vector4_f32[1] && + V1.vector4_f32[2] > V2.vector4_f32[2] && + V1.vector4_f32[3] > V2.vector4_f32[3]) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (V1.vector4_f32[0] <= V2.vector4_f32[0] && + V1.vector4_f32[1] <= V2.vector4_f32[1] && + V1.vector4_f32[2] <= V2.vector4_f32[2] && + V1.vector4_f32[3] <= V2.vector4_f32[3]) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + UINT CR = 0; + XMVECTOR vTemp = _mm_cmpgt_ps(V1,V2); + int iTest = _mm_movemask_ps(vTemp); + if (iTest==0xf) { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4GreaterOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] >= V2.vector4_f32[0]) && (V1.vector4_f32[1] >= V2.vector4_f32[1]) && (V1.vector4_f32[2] >= V2.vector4_f32[2]) && (V1.vector4_f32[3] >= V2.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmpge_ps(V1,V2); + return ((_mm_movemask_ps(vTemp)==0x0f) != 0); +#else + return XMComparisonAllTrue(XMVector4GreaterOrEqualR(V1, V2)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector4GreaterOrEqualR +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + UINT CR = 0; + if ((V1.vector4_f32[0] >= V2.vector4_f32[0]) && + (V1.vector4_f32[1] >= V2.vector4_f32[1]) && + (V1.vector4_f32[2] >= V2.vector4_f32[2]) && + (V1.vector4_f32[3] >= V2.vector4_f32[3])) + { + CR = XM_CRMASK_CR6TRUE; + } + else if ((V1.vector4_f32[0] < V2.vector4_f32[0]) && + (V1.vector4_f32[1] < V2.vector4_f32[1]) && + (V1.vector4_f32[2] < V2.vector4_f32[2]) && + (V1.vector4_f32[3] < V2.vector4_f32[3])) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + UINT CR = 0; + XMVECTOR vTemp = _mm_cmpge_ps(V1,V2); + int iTest = _mm_movemask_ps(vTemp); + if (iTest==0x0f) + { + CR = XM_CRMASK_CR6TRUE; + } + else if (!iTest) + { + CR = XM_CRMASK_CR6FALSE; + } + return CR; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4Less +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] < V2.vector4_f32[0]) && (V1.vector4_f32[1] < V2.vector4_f32[1]) && (V1.vector4_f32[2] < V2.vector4_f32[2]) && (V1.vector4_f32[3] < V2.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmplt_ps(V1,V2); + return ((_mm_movemask_ps(vTemp)==0x0f) != 0); +#else + return XMComparisonAllTrue(XMVector4GreaterR(V2, V1)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4LessOrEqual +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V1.vector4_f32[0] <= V2.vector4_f32[0]) && (V1.vector4_f32[1] <= V2.vector4_f32[1]) && (V1.vector4_f32[2] <= V2.vector4_f32[2]) && (V1.vector4_f32[3] <= V2.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp = _mm_cmple_ps(V1,V2); + return ((_mm_movemask_ps(vTemp)==0x0f) != 0); +#else + return XMComparisonAllTrue(XMVector4GreaterOrEqualR(V2, V1)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4InBounds +( + FXMVECTOR V, + FXMVECTOR Bounds +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (((V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) && + (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1]) && + (V.vector4_f32[2] <= Bounds.vector4_f32[2] && V.vector4_f32[2] >= -Bounds.vector4_f32[2]) && + (V.vector4_f32[3] <= Bounds.vector4_f32[3] && V.vector4_f32[3] >= -Bounds.vector4_f32[3])) != 0); +#elif defined(_XM_SSE_INTRINSICS_) + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + // All in bounds? + return ((_mm_movemask_ps(vTemp1)==0x0f) != 0); +#else + return XMComparisonAllInBounds(XMVector4InBoundsR(V, Bounds)); +#endif +} + +//------------------------------------------------------------------------------ + +XMFINLINE UINT XMVector4InBoundsR +( + FXMVECTOR V, + FXMVECTOR Bounds +) +{ +#if defined(_XM_NO_INTRINSICS_) + + UINT CR = 0; + if ((V.vector4_f32[0] <= Bounds.vector4_f32[0] && V.vector4_f32[0] >= -Bounds.vector4_f32[0]) && + (V.vector4_f32[1] <= Bounds.vector4_f32[1] && V.vector4_f32[1] >= -Bounds.vector4_f32[1]) && + (V.vector4_f32[2] <= Bounds.vector4_f32[2] && V.vector4_f32[2] >= -Bounds.vector4_f32[2]) && + (V.vector4_f32[3] <= Bounds.vector4_f32[3] && V.vector4_f32[3] >= -Bounds.vector4_f32[3])) + { + CR = XM_CRMASK_CR6BOUNDS; + } + return CR; + +#elif defined(_XM_SSE_INTRINSICS_) + // Test if less than or equal + XMVECTOR vTemp1 = _mm_cmple_ps(V,Bounds); + // Negate the bounds + XMVECTOR vTemp2 = _mm_mul_ps(Bounds,g_XMNegativeOne); + // Test if greater or equal (Reversed) + vTemp2 = _mm_cmple_ps(vTemp2,V); + // Blend answers + vTemp1 = _mm_and_ps(vTemp1,vTemp2); + // All in bounds? + return (_mm_movemask_ps(vTemp1)==0x0f) ? XM_CRMASK_CR6BOUNDS : 0; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4IsNaN +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + return (XMISNAN(V.vector4_f32[0]) || + XMISNAN(V.vector4_f32[1]) || + XMISNAN(V.vector4_f32[2]) || + XMISNAN(V.vector4_f32[3])); +#elif defined(_XM_SSE_INTRINSICS_) + // Test against itself. NaN is always not equal + XMVECTOR vTempNan = _mm_cmpneq_ps(V,V); + // If any are NaN, the mask is non-zero + return (_mm_movemask_ps(vTempNan)!=0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE BOOL XMVector4IsInfinite +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + return (XMISINF(V.vector4_f32[0]) || + XMISINF(V.vector4_f32[1]) || + XMISINF(V.vector4_f32[2]) || + XMISINF(V.vector4_f32[3])); + +#elif defined(_XM_SSE_INTRINSICS_) + // Mask off the sign bit + XMVECTOR vTemp = _mm_and_ps(V,g_XMAbsMask); + // Compare to infinity + vTemp = _mm_cmpeq_ps(vTemp,g_XMInfinity); + // If any are infinity, the signs are true. + return (_mm_movemask_ps(vTemp) != 0); +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// Computation operations +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Dot +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result.vector4_f32[0] = + Result.vector4_f32[1] = + Result.vector4_f32[2] = + Result.vector4_f32[3] = V1.vector4_f32[0] * V2.vector4_f32[0] + V1.vector4_f32[1] * V2.vector4_f32[1] + V1.vector4_f32[2] * V2.vector4_f32[2] + V1.vector4_f32[3] * V2.vector4_f32[3]; + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vTemp2 = V2; + XMVECTOR vTemp = _mm_mul_ps(V1,vTemp2); + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp,_MM_SHUFFLE(1,0,0,0)); // Copy X to the Z position and Y to the W position + vTemp2 = _mm_add_ps(vTemp2,vTemp); // Add Z = X+Z; W = Y+W; + vTemp = _mm_shuffle_ps(vTemp,vTemp2,_MM_SHUFFLE(0,3,0,0)); // Copy W to the Z position + vTemp = _mm_add_ps(vTemp,vTemp2); // Add Z and W together + return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(2,2,2,2)); // Splat Z and return +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Cross +( + FXMVECTOR V1, + FXMVECTOR V2, + FXMVECTOR V3 +) +{ +#if defined(_XM_NO_INTRINSICS_) + XMVECTOR Result; + + Result.vector4_f32[0] = (((V2.vector4_f32[2]*V3.vector4_f32[3])-(V2.vector4_f32[3]*V3.vector4_f32[2]))*V1.vector4_f32[1])-(((V2.vector4_f32[1]*V3.vector4_f32[3])-(V2.vector4_f32[3]*V3.vector4_f32[1]))*V1.vector4_f32[2])+(((V2.vector4_f32[1]*V3.vector4_f32[2])-(V2.vector4_f32[2]*V3.vector4_f32[1]))*V1.vector4_f32[3]); + Result.vector4_f32[1] = (((V2.vector4_f32[3]*V3.vector4_f32[2])-(V2.vector4_f32[2]*V3.vector4_f32[3]))*V1.vector4_f32[0])-(((V2.vector4_f32[3]*V3.vector4_f32[0])-(V2.vector4_f32[0]*V3.vector4_f32[3]))*V1.vector4_f32[2])+(((V2.vector4_f32[2]*V3.vector4_f32[0])-(V2.vector4_f32[0]*V3.vector4_f32[2]))*V1.vector4_f32[3]); + Result.vector4_f32[2] = (((V2.vector4_f32[1]*V3.vector4_f32[3])-(V2.vector4_f32[3]*V3.vector4_f32[1]))*V1.vector4_f32[0])-(((V2.vector4_f32[0]*V3.vector4_f32[3])-(V2.vector4_f32[3]*V3.vector4_f32[0]))*V1.vector4_f32[1])+(((V2.vector4_f32[0]*V3.vector4_f32[1])-(V2.vector4_f32[1]*V3.vector4_f32[0]))*V1.vector4_f32[3]); + Result.vector4_f32[3] = (((V2.vector4_f32[2]*V3.vector4_f32[1])-(V2.vector4_f32[1]*V3.vector4_f32[2]))*V1.vector4_f32[0])-(((V2.vector4_f32[2]*V3.vector4_f32[0])-(V2.vector4_f32[0]*V3.vector4_f32[2]))*V1.vector4_f32[1])+(((V2.vector4_f32[1]*V3.vector4_f32[0])-(V2.vector4_f32[0]*V3.vector4_f32[1]))*V1.vector4_f32[2]); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // V2zwyz * V3wzwy + XMVECTOR vResult = _mm_shuffle_ps(V2,V2,_MM_SHUFFLE(2,1,3,2)); + XMVECTOR vTemp3 = _mm_shuffle_ps(V3,V3,_MM_SHUFFLE(1,3,2,3)); + vResult = _mm_mul_ps(vResult,vTemp3); + // - V2wzwy * V3zwyz + XMVECTOR vTemp2 = _mm_shuffle_ps(V2,V2,_MM_SHUFFLE(1,3,2,3)); + vTemp3 = _mm_shuffle_ps(vTemp3,vTemp3,_MM_SHUFFLE(1,3,0,1)); + vTemp2 = _mm_mul_ps(vTemp2,vTemp3); + vResult = _mm_sub_ps(vResult,vTemp2); + // term1 * V1yxxx + XMVECTOR vTemp1 = _mm_shuffle_ps(V1,V1,_MM_SHUFFLE(0,0,0,1)); + vResult = _mm_mul_ps(vResult,vTemp1); + + // V2ywxz * V3wxwx + vTemp2 = _mm_shuffle_ps(V2,V2,_MM_SHUFFLE(2,0,3,1)); + vTemp3 = _mm_shuffle_ps(V3,V3,_MM_SHUFFLE(0,3,0,3)); + vTemp3 = _mm_mul_ps(vTemp3,vTemp2); + // - V2wxwx * V3ywxz + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp2,_MM_SHUFFLE(2,1,2,1)); + vTemp1 = _mm_shuffle_ps(V3,V3,_MM_SHUFFLE(2,0,3,1)); + vTemp2 = _mm_mul_ps(vTemp2,vTemp1); + vTemp3 = _mm_sub_ps(vTemp3,vTemp2); + // vResult - temp * V1zzyy + vTemp1 = _mm_shuffle_ps(V1,V1,_MM_SHUFFLE(1,1,2,2)); + vTemp1 = _mm_mul_ps(vTemp1,vTemp3); + vResult = _mm_sub_ps(vResult,vTemp1); + + // V2yzxy * V3zxyx + vTemp2 = _mm_shuffle_ps(V2,V2,_MM_SHUFFLE(1,0,2,1)); + vTemp3 = _mm_shuffle_ps(V3,V3,_MM_SHUFFLE(0,1,0,2)); + vTemp3 = _mm_mul_ps(vTemp3,vTemp2); + // - V2zxyx * V3yzxy + vTemp2 = _mm_shuffle_ps(vTemp2,vTemp2,_MM_SHUFFLE(2,0,2,1)); + vTemp1 = _mm_shuffle_ps(V3,V3,_MM_SHUFFLE(1,0,2,1)); + vTemp1 = _mm_mul_ps(vTemp1,vTemp2); + vTemp3 = _mm_sub_ps(vTemp3,vTemp1); + // vResult + term * V1wwwz + vTemp1 = _mm_shuffle_ps(V1,V1,_MM_SHUFFLE(2,3,3,3)); + vTemp3 = _mm_mul_ps(vTemp3,vTemp1); + vResult = _mm_add_ps(vResult,vTemp3); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4LengthSq +( + FXMVECTOR V +) +{ + return XMVector4Dot(V, V); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4ReciprocalLengthEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector4LengthSq(V); + Result = XMVectorReciprocalSqrtEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y,z and w + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and w + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(3,2,3,2)); + // x+z, y+w + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // x+z,x+z,x+z,y+w + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,0,0,0)); + // ??,??,y+w,y+w + vTemp = _mm_shuffle_ps(vTemp,vLengthSq,_MM_SHUFFLE(3,3,0,0)); + // ??,??,x+z+y+w,?? + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // Splat the length + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,2,2,2)); + // Get the reciprocal + vLengthSq = _mm_rsqrt_ps(vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4ReciprocalLength +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector4LengthSq(V); + Result = XMVectorReciprocalSqrt(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y,z and w + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and w + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(3,2,3,2)); + // x+z, y+w + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // x+z,x+z,x+z,y+w + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,0,0,0)); + // ??,??,y+w,y+w + vTemp = _mm_shuffle_ps(vTemp,vLengthSq,_MM_SHUFFLE(3,3,0,0)); + // ??,??,x+z+y+w,?? + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // Splat the length + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,2,2,2)); + // Get the reciprocal + vLengthSq = _mm_sqrt_ps(vLengthSq); + // Accurate! + vLengthSq = _mm_div_ps(g_XMOne,vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4LengthEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector4LengthSq(V); + Result = XMVectorSqrtEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y,z and w + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and w + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(3,2,3,2)); + // x+z, y+w + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // x+z,x+z,x+z,y+w + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,0,0,0)); + // ??,??,y+w,y+w + vTemp = _mm_shuffle_ps(vTemp,vLengthSq,_MM_SHUFFLE(3,3,0,0)); + // ??,??,x+z+y+w,?? + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // Splat the length + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,2,2,2)); + // Prepare for the division + vLengthSq = _mm_sqrt_ps(vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Length +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + Result = XMVector4LengthSq(V); + Result = XMVectorSqrt(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y,z and w + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and w + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(3,2,3,2)); + // x+z, y+w + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // x+z,x+z,x+z,y+w + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,0,0,0)); + // ??,??,y+w,y+w + vTemp = _mm_shuffle_ps(vTemp,vLengthSq,_MM_SHUFFLE(3,3,0,0)); + // ??,??,x+z+y+w,?? + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // Splat the length + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,2,2,2)); + // Prepare for the division + vLengthSq = _mm_sqrt_ps(vLengthSq); + return vLengthSq; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ +// XMVector4NormalizeEst uses a reciprocal estimate and +// returns QNaN on zero and infinite vectors. + +XMFINLINE XMVECTOR XMVector4NormalizeEst +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result = XMVector4ReciprocalLength(V); + Result = XMVectorMultiply(V, Result); + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y,z and w + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and w + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(3,2,3,2)); + // x+z, y+w + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // x+z,x+z,x+z,y+w + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,0,0,0)); + // ??,??,y+w,y+w + vTemp = _mm_shuffle_ps(vTemp,vLengthSq,_MM_SHUFFLE(3,3,0,0)); + // ??,??,x+z+y+w,?? + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // Splat the length + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,2,2,2)); + // Get the reciprocal + XMVECTOR vResult = _mm_rsqrt_ps(vLengthSq); + // Reciprocal mul to perform the normalization + vResult = _mm_mul_ps(vResult,V); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Normalize +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fLength; + XMVECTOR vResult; + + vResult = XMVector4Length( V ); + fLength = vResult.vector4_f32[0]; + + // Prevent divide by zero + if (fLength > 0) { + fLength = 1.0f/fLength; + } + + vResult.vector4_f32[0] = V.vector4_f32[0]*fLength; + vResult.vector4_f32[1] = V.vector4_f32[1]*fLength; + vResult.vector4_f32[2] = V.vector4_f32[2]*fLength; + vResult.vector4_f32[3] = V.vector4_f32[3]*fLength; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + // Perform the dot product on x,y,z and w + XMVECTOR vLengthSq = _mm_mul_ps(V,V); + // vTemp has z and w + XMVECTOR vTemp = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(3,2,3,2)); + // x+z, y+w + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // x+z,x+z,x+z,y+w + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(1,0,0,0)); + // ??,??,y+w,y+w + vTemp = _mm_shuffle_ps(vTemp,vLengthSq,_MM_SHUFFLE(3,3,0,0)); + // ??,??,x+z+y+w,?? + vLengthSq = _mm_add_ps(vLengthSq,vTemp); + // Splat the length + vLengthSq = _mm_shuffle_ps(vLengthSq,vLengthSq,_MM_SHUFFLE(2,2,2,2)); + // Prepare for the division + XMVECTOR vResult = _mm_sqrt_ps(vLengthSq); + // Create zero with a single instruction + XMVECTOR vZeroMask = _mm_setzero_ps(); + // Test for a divide by zero (Must be FP to detect -0.0) + vZeroMask = _mm_cmpneq_ps(vZeroMask,vResult); + // Failsafe on zero (Or epsilon) length planes + // If the length is infinity, set the elements to zero + vLengthSq = _mm_cmpneq_ps(vLengthSq,g_XMInfinity); + // Divide to perform the normalization + vResult = _mm_div_ps(V,vResult); + // Any that are infinity, set to zero + vResult = _mm_and_ps(vResult,vZeroMask); + // Select qnan or result based on infinite length + XMVECTOR vTemp1 = _mm_andnot_ps(vLengthSq,g_XMQNaN); + XMVECTOR vTemp2 = _mm_and_ps(vResult,vLengthSq); + vResult = _mm_or_ps(vTemp1,vTemp2); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4ClampLength +( + FXMVECTOR V, + FLOAT LengthMin, + FLOAT LengthMax +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR ClampMax; + XMVECTOR ClampMin; + + ClampMax = XMVectorReplicate(LengthMax); + ClampMin = XMVectorReplicate(LengthMin); + + return XMVector4ClampLengthV(V, ClampMin, ClampMax); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR ClampMax = _mm_set_ps1(LengthMax); + XMVECTOR ClampMin = _mm_set_ps1(LengthMin); + return XMVector4ClampLengthV(V, ClampMin, ClampMax); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4ClampLengthV +( + FXMVECTOR V, + FXMVECTOR LengthMin, + FXMVECTOR LengthMax +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR ClampLength; + XMVECTOR LengthSq; + XMVECTOR RcpLength; + XMVECTOR Length; + XMVECTOR Normal; + XMVECTOR Zero; + XMVECTOR InfiniteLength; + XMVECTOR ZeroLength; + XMVECTOR Select; + XMVECTOR ControlMax; + XMVECTOR ControlMin; + XMVECTOR Control; + XMVECTOR Result; + + XMASSERT((LengthMin.vector4_f32[1] == LengthMin.vector4_f32[0]) && (LengthMin.vector4_f32[2] == LengthMin.vector4_f32[0]) && (LengthMin.vector4_f32[3] == LengthMin.vector4_f32[0])); + XMASSERT((LengthMax.vector4_f32[1] == LengthMax.vector4_f32[0]) && (LengthMax.vector4_f32[2] == LengthMax.vector4_f32[0]) && (LengthMax.vector4_f32[3] == LengthMax.vector4_f32[0])); + XMASSERT(XMVector4GreaterOrEqual(LengthMin, XMVectorZero())); + XMASSERT(XMVector4GreaterOrEqual(LengthMax, XMVectorZero())); + XMASSERT(XMVector4GreaterOrEqual(LengthMax, LengthMin)); + + LengthSq = XMVector4LengthSq(V); + + Zero = XMVectorZero(); + + RcpLength = XMVectorReciprocalSqrt(LengthSq); + + InfiniteLength = XMVectorEqualInt(LengthSq, g_XMInfinity.v); + ZeroLength = XMVectorEqual(LengthSq, Zero); + + Normal = XMVectorMultiply(V, RcpLength); + + Length = XMVectorMultiply(LengthSq, RcpLength); + + Select = XMVectorEqualInt(InfiniteLength, ZeroLength); + Length = XMVectorSelect(LengthSq, Length, Select); + Normal = XMVectorSelect(LengthSq, Normal, Select); + + ControlMax = XMVectorGreater(Length, LengthMax); + ControlMin = XMVectorLess(Length, LengthMin); + + ClampLength = XMVectorSelect(Length, LengthMax, ControlMax); + ClampLength = XMVectorSelect(ClampLength, LengthMin, ControlMin); + + Result = XMVectorMultiply(Normal, ClampLength); + + // Preserve the original vector (with no precision loss) if the length falls within the given range + Control = XMVectorEqualInt(ControlMax, ControlMin); + Result = XMVectorSelect(Result, V, Control); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR ClampLength; + XMVECTOR LengthSq; + XMVECTOR RcpLength; + XMVECTOR Length; + XMVECTOR Normal; + XMVECTOR Zero; + XMVECTOR InfiniteLength; + XMVECTOR ZeroLength; + XMVECTOR Select; + XMVECTOR ControlMax; + XMVECTOR ControlMin; + XMVECTOR Control; + XMVECTOR Result; + + XMASSERT((XMVectorGetY(LengthMin) == XMVectorGetX(LengthMin)) && (XMVectorGetZ(LengthMin) == XMVectorGetX(LengthMin)) && (XMVectorGetW(LengthMin) == XMVectorGetX(LengthMin))); + XMASSERT((XMVectorGetY(LengthMax) == XMVectorGetX(LengthMax)) && (XMVectorGetZ(LengthMax) == XMVectorGetX(LengthMax)) && (XMVectorGetW(LengthMax) == XMVectorGetX(LengthMax))); + XMASSERT(XMVector4GreaterOrEqual(LengthMin, g_XMZero)); + XMASSERT(XMVector4GreaterOrEqual(LengthMax, g_XMZero)); + XMASSERT(XMVector4GreaterOrEqual(LengthMax, LengthMin)); + + LengthSq = XMVector4LengthSq(V); + Zero = XMVectorZero(); + RcpLength = XMVectorReciprocalSqrt(LengthSq); + InfiniteLength = XMVectorEqualInt(LengthSq, g_XMInfinity); + ZeroLength = XMVectorEqual(LengthSq, Zero); + Normal = _mm_mul_ps(V, RcpLength); + Length = _mm_mul_ps(LengthSq, RcpLength); + Select = XMVectorEqualInt(InfiniteLength, ZeroLength); + Length = XMVectorSelect(LengthSq, Length, Select); + Normal = XMVectorSelect(LengthSq, Normal, Select); + ControlMax = XMVectorGreater(Length, LengthMax); + ControlMin = XMVectorLess(Length, LengthMin); + ClampLength = XMVectorSelect(Length, LengthMax, ControlMax); + ClampLength = XMVectorSelect(ClampLength, LengthMin, ControlMin); + Result = _mm_mul_ps(Normal, ClampLength); + // Preserve the original vector (with no precision loss) if the length falls within the given range + Control = XMVectorEqualInt(ControlMax,ControlMin); + Result = XMVectorSelect(Result,V,Control); + return Result; + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Reflect +( + FXMVECTOR Incident, + FXMVECTOR Normal +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + + // Result = Incident - (2 * dot(Incident, Normal)) * Normal + Result = XMVector4Dot(Incident, Normal); + Result = XMVectorAdd(Result, Result); + Result = XMVectorNegativeMultiplySubtract(Result, Normal, Incident); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + // Result = Incident - (2 * dot(Incident, Normal)) * Normal + XMVECTOR Result = XMVector4Dot(Incident,Normal); + Result = _mm_add_ps(Result,Result); + Result = _mm_mul_ps(Result,Normal); + Result = _mm_sub_ps(Incident,Result); + return Result; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Refract +( + FXMVECTOR Incident, + FXMVECTOR Normal, + FLOAT RefractionIndex +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Index; + Index = XMVectorReplicate(RefractionIndex); + return XMVector4RefractV(Incident, Normal, Index); + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR Index = _mm_set_ps1(RefractionIndex); + return XMVector4RefractV(Incident,Normal,Index); +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4RefractV +( + FXMVECTOR Incident, + FXMVECTOR Normal, + FXMVECTOR RefractionIndex +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR IDotN; + XMVECTOR R; + CONST XMVECTOR Zero = XMVectorZero(); + + // Result = RefractionIndex * Incident - Normal * (RefractionIndex * dot(Incident, Normal) + + // sqrt(1 - RefractionIndex * RefractionIndex * (1 - dot(Incident, Normal) * dot(Incident, Normal)))) + + IDotN = XMVector4Dot(Incident, Normal); + + // R = 1.0f - RefractionIndex * RefractionIndex * (1.0f - IDotN * IDotN) + R = XMVectorNegativeMultiplySubtract(IDotN, IDotN, g_XMOne.v); + R = XMVectorMultiply(R, RefractionIndex); + R = XMVectorNegativeMultiplySubtract(R, RefractionIndex, g_XMOne.v); + + if (XMVector4LessOrEqual(R, Zero)) + { + // Total internal reflection + return Zero; + } + else + { + XMVECTOR Result; + + // R = RefractionIndex * IDotN + sqrt(R) + R = XMVectorSqrt(R); + R = XMVectorMultiplyAdd(RefractionIndex, IDotN, R); + + // Result = RefractionIndex * Incident - Normal * R + Result = XMVectorMultiply(RefractionIndex, Incident); + Result = XMVectorNegativeMultiplySubtract(Normal, R, Result); + + return Result; + } + +#elif defined(_XM_SSE_INTRINSICS_) + // Result = RefractionIndex * Incident - Normal * (RefractionIndex * dot(Incident, Normal) + + // sqrt(1 - RefractionIndex * RefractionIndex * (1 - dot(Incident, Normal) * dot(Incident, Normal)))) + + XMVECTOR IDotN = XMVector4Dot(Incident,Normal); + + // R = 1.0f - RefractionIndex * RefractionIndex * (1.0f - IDotN * IDotN) + XMVECTOR R = _mm_mul_ps(IDotN,IDotN); + R = _mm_sub_ps(g_XMOne,R); + R = _mm_mul_ps(R, RefractionIndex); + R = _mm_mul_ps(R, RefractionIndex); + R = _mm_sub_ps(g_XMOne,R); + + XMVECTOR vResult = _mm_cmple_ps(R,g_XMZero); + if (_mm_movemask_ps(vResult)==0x0f) + { + // Total internal reflection + vResult = g_XMZero; + } + else + { + // R = RefractionIndex * IDotN + sqrt(R) + R = _mm_sqrt_ps(R); + vResult = _mm_mul_ps(RefractionIndex, IDotN); + R = _mm_add_ps(R,vResult); + // Result = RefractionIndex * Incident - Normal * R + vResult = _mm_mul_ps(RefractionIndex, Incident); + R = _mm_mul_ps(R,Normal); + vResult = _mm_sub_ps(vResult,R); + } + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Orthogonal +( + FXMVECTOR V +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR Result; + Result.vector4_f32[0] = V.vector4_f32[2]; + Result.vector4_f32[1] = V.vector4_f32[3]; + Result.vector4_f32[2] = -V.vector4_f32[0]; + Result.vector4_f32[3] = -V.vector4_f32[1]; + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + static const XMVECTORF32 FlipZW = {1.0f,1.0f,-1.0f,-1.0f}; + XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,0,3,2)); + vResult = _mm_mul_ps(vResult,FlipZW); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4AngleBetweenNormalsEst +( + FXMVECTOR N1, + FXMVECTOR N2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR NegativeOne; + XMVECTOR One; + XMVECTOR Result; + + Result = XMVector4Dot(N1, N2); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + Result = XMVectorClamp(Result, NegativeOne, One); + Result = XMVectorACosEst(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = XMVector4Dot(N1,N2); + // Clamp to -1.0f to 1.0f + vResult = _mm_max_ps(vResult,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne);; + vResult = XMVectorACosEst(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4AngleBetweenNormals +( + FXMVECTOR N1, + FXMVECTOR N2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR NegativeOne; + XMVECTOR One; + XMVECTOR Result; + + Result = XMVector4Dot(N1, N2); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + Result = XMVectorClamp(Result, NegativeOne, One); + Result = XMVectorACos(Result); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR vResult = XMVector4Dot(N1,N2); + // Clamp to -1.0f to 1.0f + vResult = _mm_max_ps(vResult,g_XMNegativeOne); + vResult = _mm_min_ps(vResult,g_XMOne);; + vResult = XMVectorACos(vResult); + return vResult; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4AngleBetweenVectors +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR L1; + XMVECTOR L2; + XMVECTOR Dot; + XMVECTOR CosAngle; + XMVECTOR NegativeOne; + XMVECTOR One; + XMVECTOR Result; + + L1 = XMVector4ReciprocalLength(V1); + L2 = XMVector4ReciprocalLength(V2); + + Dot = XMVector4Dot(V1, V2); + + L1 = XMVectorMultiply(L1, L2); + + CosAngle = XMVectorMultiply(Dot, L1); + NegativeOne = XMVectorSplatConstant(-1, 0); + One = XMVectorSplatOne(); + CosAngle = XMVectorClamp(CosAngle, NegativeOne, One); + + Result = XMVectorACos(CosAngle); + + return Result; + +#elif defined(_XM_SSE_INTRINSICS_) + XMVECTOR L1; + XMVECTOR L2; + XMVECTOR Dot; + XMVECTOR CosAngle; + XMVECTOR Result; + + L1 = XMVector4ReciprocalLength(V1); + L2 = XMVector4ReciprocalLength(V2); + Dot = XMVector4Dot(V1, V2); + L1 = _mm_mul_ps(L1,L2); + CosAngle = _mm_mul_ps(Dot,L1); + CosAngle = XMVectorClamp(CosAngle, g_XMNegativeOne, g_XMOne); + Result = XMVectorACos(CosAngle); + return Result; + +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR XMVector4Transform +( + FXMVECTOR V, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + FLOAT fX = (M.m[0][0]*V.vector4_f32[0])+(M.m[1][0]*V.vector4_f32[1])+(M.m[2][0]*V.vector4_f32[2])+(M.m[3][0]*V.vector4_f32[3]); + FLOAT fY = (M.m[0][1]*V.vector4_f32[0])+(M.m[1][1]*V.vector4_f32[1])+(M.m[2][1]*V.vector4_f32[2])+(M.m[3][1]*V.vector4_f32[3]); + FLOAT fZ = (M.m[0][2]*V.vector4_f32[0])+(M.m[1][2]*V.vector4_f32[1])+(M.m[2][2]*V.vector4_f32[2])+(M.m[3][2]*V.vector4_f32[3]); + FLOAT fW = (M.m[0][3]*V.vector4_f32[0])+(M.m[1][3]*V.vector4_f32[1])+(M.m[2][3]*V.vector4_f32[2])+(M.m[3][3]*V.vector4_f32[3]); + XMVECTOR vResult = { + fX, + fY, + fZ, + fW + }; + return vResult; + +#elif defined(_XM_SSE_INTRINSICS_) + // Splat x,y,z and w + XMVECTOR vTempX = _mm_shuffle_ps(V,V,_MM_SHUFFLE(0,0,0,0)); + XMVECTOR vTempY = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR vTempZ = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2)); + XMVECTOR vTempW = _mm_shuffle_ps(V,V,_MM_SHUFFLE(3,3,3,3)); + // Mul by the matrix + vTempX = _mm_mul_ps(vTempX,M.r[0]); + vTempY = _mm_mul_ps(vTempY,M.r[1]); + vTempZ = _mm_mul_ps(vTempZ,M.r[2]); + vTempW = _mm_mul_ps(vTempW,M.r[3]); + // Add them all together + vTempX = _mm_add_ps(vTempX,vTempY); + vTempZ = _mm_add_ps(vTempZ,vTempW); + vTempX = _mm_add_ps(vTempX,vTempZ); + return vTempX; +#else // _XM_VMX128_INTRINSICS_ +#endif // _XM_VMX128_INTRINSICS_ +} + +//------------------------------------------------------------------------------ + +XMINLINE XMFLOAT4* XMVector4TransformStream +( + XMFLOAT4* pOutputStream, + UINT OutputStride, + CONST XMFLOAT4* pInputStream, + UINT InputStride, + UINT VectorCount, + CXMMATRIX M +) +{ +#if defined(_XM_NO_INTRINSICS_) + + XMVECTOR V; + XMVECTOR X; + XMVECTOR Y; + XMVECTOR Z; + XMVECTOR W; + XMVECTOR Result; + UINT i; + BYTE* pInputVector = (BYTE*)pInputStream; + BYTE* pOutputVector = (BYTE*)pOutputStream; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + for (i = 0; i < VectorCount; i++) + { + V = XMLoadFloat4((XMFLOAT4*)pInputVector); + W = XMVectorSplatW(V); + Z = XMVectorSplatZ(V); + Y = XMVectorSplatY(V); + X = XMVectorSplatX(V); +// W = XMVectorReplicate(((XMFLOAT4*)pInputVector)->w); +// Z = XMVectorReplicate(((XMFLOAT4*)pInputVector)->z); +// Y = XMVectorReplicate(((XMFLOAT4*)pInputVector)->y); +// X = XMVectorReplicate(((XMFLOAT4*)pInputVector)->x); + + Result = XMVectorMultiply(W, M.r[3]); + Result = XMVectorMultiplyAdd(Z, M.r[2], Result); + Result = XMVectorMultiplyAdd(Y, M.r[1], Result); + Result = XMVectorMultiplyAdd(X, M.r[0], Result); + + XMStoreFloat4((XMFLOAT4*)pOutputVector, Result); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + + return pOutputStream; + +#elif defined(_XM_SSE_INTRINSICS_) + UINT i; + + XMASSERT(pOutputStream); + XMASSERT(pInputStream); + + const BYTE*pInputVector = reinterpret_cast(pInputStream); + BYTE* pOutputVector = reinterpret_cast(pOutputStream); + for (i = 0; i < VectorCount; i++) + { + // Fetch the row and splat it + XMVECTOR vTempx = _mm_loadu_ps(reinterpret_cast(pInputVector)); + XMVECTOR vTempy = _mm_shuffle_ps(vTempx,vTempx,_MM_SHUFFLE(1,1,1,1)); + XMVECTOR vTempz = _mm_shuffle_ps(vTempx,vTempx,_MM_SHUFFLE(2,2,2,2)); + XMVECTOR vTempw = _mm_shuffle_ps(vTempx,vTempx,_MM_SHUFFLE(3,3,3,3)); + vTempx = _mm_shuffle_ps(vTempx,vTempx,_MM_SHUFFLE(0,0,0,0)); + vTempx = _mm_mul_ps(vTempx,M.r[0]); + vTempy = _mm_mul_ps(vTempy,M.r[1]); + vTempz = _mm_mul_ps(vTempz,M.r[2]); + vTempw = _mm_mul_ps(vTempw,M.r[3]); + vTempx = _mm_add_ps(vTempx,vTempy); + vTempw = _mm_add_ps(vTempw,vTempz); + vTempw = _mm_add_ps(vTempw,vTempx); + // Store the transformed vector + _mm_storeu_ps(reinterpret_cast(pOutputVector),vTempw); + + pInputVector += InputStride; + pOutputVector += OutputStride; + } + return pOutputStream; +#elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS) +#endif // _XM_VMX128_INTRINSICS_ +} + +#ifdef __cplusplus + +/**************************************************************************** + * + * XMVECTOR operators + * + ****************************************************************************/ + +#ifndef XM_NO_OPERATOR_OVERLOADS + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator+ (FXMVECTOR V) +{ + return V; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator- (FXMVECTOR V) +{ + return XMVectorNegate(V); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR& operator+= +( + XMVECTOR& V1, + FXMVECTOR V2 +) +{ + V1 = XMVectorAdd(V1, V2); + return V1; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR& operator-= +( + XMVECTOR& V1, + FXMVECTOR V2 +) +{ + V1 = XMVectorSubtract(V1, V2); + return V1; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR& operator*= +( + XMVECTOR& V1, + FXMVECTOR V2 +) +{ + V1 = XMVectorMultiply(V1, V2); + return V1; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR& operator/= +( + XMVECTOR& V1, + FXMVECTOR V2 +) +{ + V1 = XMVectorDivide(V1,V2); + return V1; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR& operator*= +( + XMVECTOR& V, + CONST FLOAT S +) +{ + V = XMVectorScale(V, S); + return V; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR& operator/= +( + XMVECTOR& V, + CONST FLOAT S +) +{ + V = XMVectorScale(V, 1.0f / S); + return V; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator+ +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ + return XMVectorAdd(V1, V2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator- +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ + return XMVectorSubtract(V1, V2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator* +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ + return XMVectorMultiply(V1, V2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator/ +( + FXMVECTOR V1, + FXMVECTOR V2 +) +{ + return XMVectorDivide(V1,V2); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator* +( + FXMVECTOR V, + CONST FLOAT S +) +{ + return XMVectorScale(V, S); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator/ +( + FXMVECTOR V, + CONST FLOAT S +) +{ + return XMVectorScale(V, 1.0f / S); +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMVECTOR operator* +( + FLOAT S, + FXMVECTOR V +) +{ + return XMVectorScale(V, S); +} + +#endif // !XM_NO_OPERATOR_OVERLOADS + +/**************************************************************************** + * + * XMFLOAT2 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT2::_XMFLOAT2 +( + CONST FLOAT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT2& _XMFLOAT2::operator= +( + CONST _XMFLOAT2& Float2 +) +{ + x = Float2.x; + y = Float2.y; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMFLOAT2A& XMFLOAT2A::operator= +( + CONST XMFLOAT2A& Float2 +) +{ + x = Float2.x; + y = Float2.y; + return *this; +} + +/**************************************************************************** + * + * XMHALF2 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF2::_XMHALF2 +( + CONST HALF* pArray +) +{ + x = pArray[0]; + y = pArray[1]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF2::_XMHALF2 +( + FLOAT _x, + FLOAT _y +) +{ + x = XMConvertFloatToHalf(_x); + y = XMConvertFloatToHalf(_y); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF2::_XMHALF2 +( + CONST FLOAT* pArray +) +{ + x = XMConvertFloatToHalf(pArray[0]); + y = XMConvertFloatToHalf(pArray[1]); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF2& _XMHALF2::operator= +( + CONST _XMHALF2& Half2 +) +{ + x = Half2.x; + y = Half2.y; + return *this; +} + +/**************************************************************************** + * + * XMSHORTN2 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN2::_XMSHORTN2 +( + CONST SHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN2::_XMSHORTN2 +( + FLOAT _x, + FLOAT _y +) +{ + XMStoreShortN2(this, XMVectorSet(_x, _y, 0.0f, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN2::_XMSHORTN2 +( + CONST FLOAT* pArray +) +{ + XMStoreShortN2(this, XMLoadFloat2((XMFLOAT2*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN2& _XMSHORTN2::operator= +( + CONST _XMSHORTN2& ShortN2 +) +{ + x = ShortN2.x; + y = ShortN2.y; + return *this; +} + +/**************************************************************************** + * + * XMSHORT2 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT2::_XMSHORT2 +( + CONST SHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT2::_XMSHORT2 +( + FLOAT _x, + FLOAT _y +) +{ + XMStoreShort2(this, XMVectorSet(_x, _y, 0.0f, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT2::_XMSHORT2 +( + CONST FLOAT* pArray +) +{ + XMStoreShort2(this, XMLoadFloat2((XMFLOAT2*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT2& _XMSHORT2::operator= +( + CONST _XMSHORT2& Short2 +) +{ + x = Short2.x; + y = Short2.y; + return *this; +} + +/**************************************************************************** + * + * XMUSHORTN2 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN2::_XMUSHORTN2 +( + CONST USHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN2::_XMUSHORTN2 +( + FLOAT _x, + FLOAT _y +) +{ + XMStoreUShortN2(this, XMVectorSet(_x, _y, 0.0f, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN2::_XMUSHORTN2 +( + CONST FLOAT* pArray +) +{ + XMStoreUShortN2(this, XMLoadFloat2((XMFLOAT2*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN2& _XMUSHORTN2::operator= +( + CONST _XMUSHORTN2& UShortN2 +) +{ + x = UShortN2.x; + y = UShortN2.y; + return *this; +} + +/**************************************************************************** + * + * XMUSHORT2 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT2::_XMUSHORT2 +( + CONST USHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT2::_XMUSHORT2 +( + FLOAT _x, + FLOAT _y +) +{ + XMStoreUShort2(this, XMVectorSet(_x, _y, 0.0f, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT2::_XMUSHORT2 +( + CONST FLOAT* pArray +) +{ + XMStoreUShort2(this, XMLoadFloat2((XMFLOAT2*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT2& _XMUSHORT2::operator= +( + CONST _XMUSHORT2& UShort2 +) +{ + x = UShort2.x; + y = UShort2.y; + return *this; +} + +/**************************************************************************** + * + * XMFLOAT3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT3::_XMFLOAT3 +( + CONST FLOAT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT3& _XMFLOAT3::operator= +( + CONST _XMFLOAT3& Float3 +) +{ + x = Float3.x; + y = Float3.y; + z = Float3.z; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMFLOAT3A& XMFLOAT3A::operator= +( + CONST XMFLOAT3A& Float3 +) +{ + x = Float3.x; + y = Float3.y; + z = Float3.z; + return *this; +} + +/**************************************************************************** + * + * XMHENDN3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHENDN3::_XMHENDN3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreHenDN3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHENDN3::_XMHENDN3 +( + CONST FLOAT* pArray +) +{ + XMStoreHenDN3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHENDN3& _XMHENDN3::operator= +( + CONST _XMHENDN3& HenDN3 +) +{ + v = HenDN3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHENDN3& _XMHENDN3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMHEND3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHEND3::_XMHEND3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreHenD3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHEND3::_XMHEND3 +( + CONST FLOAT* pArray +) +{ + XMStoreHenD3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHEND3& _XMHEND3::operator= +( + CONST _XMHEND3& HenD3 +) +{ + v = HenD3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHEND3& _XMHEND3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUHENDN3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHENDN3::_XMUHENDN3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreUHenDN3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHENDN3::_XMUHENDN3 +( + CONST FLOAT* pArray +) +{ + XMStoreUHenDN3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHENDN3& _XMUHENDN3::operator= +( + CONST _XMUHENDN3& UHenDN3 +) +{ + v = UHenDN3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHENDN3& _XMUHENDN3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUHEND3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHEND3::_XMUHEND3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreUHenD3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHEND3::_XMUHEND3 +( + CONST FLOAT* pArray +) +{ + XMStoreUHenD3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHEND3& _XMUHEND3::operator= +( + CONST _XMUHEND3& UHenD3 +) +{ + v = UHenD3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUHEND3& _XMUHEND3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMDHENN3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHENN3::_XMDHENN3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreDHenN3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHENN3::_XMDHENN3 +( + CONST FLOAT* pArray +) +{ + XMStoreDHenN3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHENN3& _XMDHENN3::operator= +( + CONST _XMDHENN3& DHenN3 +) +{ + v = DHenN3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHENN3& _XMDHENN3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMDHEN3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHEN3::_XMDHEN3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreDHen3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHEN3::_XMDHEN3 +( + CONST FLOAT* pArray +) +{ + XMStoreDHen3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHEN3& _XMDHEN3::operator= +( + CONST _XMDHEN3& DHen3 +) +{ + v = DHen3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDHEN3& _XMDHEN3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUDHENN3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHENN3::_XMUDHENN3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreUDHenN3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHENN3::_XMUDHENN3 +( + CONST FLOAT* pArray +) +{ + XMStoreUDHenN3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHENN3& _XMUDHENN3::operator= +( + CONST _XMUDHENN3& UDHenN3 +) +{ + v = UDHenN3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHENN3& _XMUDHENN3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUDHEN3 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHEN3::_XMUDHEN3 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreUDHen3(this, XMVectorSet(_x, _y, _z, 0.0f)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHEN3::_XMUDHEN3 +( + CONST FLOAT* pArray +) +{ + XMStoreUDHen3(this, XMLoadFloat3((XMFLOAT3*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHEN3& _XMUDHEN3::operator= +( + CONST _XMUDHEN3& UDHen3 +) +{ + v = UDHen3.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDHEN3& _XMUDHEN3::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMU565 operators + * + ****************************************************************************/ + +XMFINLINE _XMU565::_XMU565 +( + CONST CHAR *pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; +} + +XMFINLINE _XMU565::_XMU565 +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreU565(this, XMVectorSet( _x, _y, _z, 0.0f )); +} + +XMFINLINE _XMU565::_XMU565 +( + CONST FLOAT *pArray +) +{ + XMStoreU565(this, XMLoadFloat3((XMFLOAT3*)pArray )); +} + +XMFINLINE _XMU565& _XMU565::operator= +( + CONST _XMU565& U565 +) +{ + v = U565.v; + return *this; +} + +XMFINLINE _XMU565& _XMU565::operator= +( + CONST USHORT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMFLOAT3PK operators + * + ****************************************************************************/ + +XMFINLINE _XMFLOAT3PK::_XMFLOAT3PK +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreFloat3PK(this, XMVectorSet( _x, _y, _z, 0.0f )); +} + +XMFINLINE _XMFLOAT3PK::_XMFLOAT3PK +( + CONST FLOAT *pArray +) +{ + XMStoreFloat3PK(this, XMLoadFloat3((XMFLOAT3*)pArray )); +} + +XMFINLINE _XMFLOAT3PK& _XMFLOAT3PK::operator= +( + CONST _XMFLOAT3PK& float3pk +) +{ + v = float3pk.v; + return *this; +} + +XMFINLINE _XMFLOAT3PK& _XMFLOAT3PK::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMFLOAT3SE operators + * + ****************************************************************************/ + +XMFINLINE _XMFLOAT3SE::_XMFLOAT3SE +( + FLOAT _x, + FLOAT _y, + FLOAT _z +) +{ + XMStoreFloat3SE(this, XMVectorSet( _x, _y, _z, 0.0f )); +} + +XMFINLINE _XMFLOAT3SE::_XMFLOAT3SE +( + CONST FLOAT *pArray +) +{ + XMStoreFloat3SE(this, XMLoadFloat3((XMFLOAT3*)pArray )); +} + +XMFINLINE _XMFLOAT3SE& _XMFLOAT3SE::operator= +( + CONST _XMFLOAT3SE& float3se +) +{ + v = float3se.v; + return *this; +} + +XMFINLINE _XMFLOAT3SE& _XMFLOAT3SE::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMFLOAT4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4::_XMFLOAT4 +( + CONST FLOAT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMFLOAT4& _XMFLOAT4::operator= +( + CONST _XMFLOAT4& Float4 +) +{ + x = Float4.x; + y = Float4.y; + z = Float4.z; + w = Float4.w; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE XMFLOAT4A& XMFLOAT4A::operator= +( + CONST XMFLOAT4A& Float4 +) +{ + x = Float4.x; + y = Float4.y; + z = Float4.z; + w = Float4.w; + return *this; +} + +/**************************************************************************** + * + * XMHALF4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF4::_XMHALF4 +( + CONST HALF* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF4::_XMHALF4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + x = XMConvertFloatToHalf(_x); + y = XMConvertFloatToHalf(_y); + z = XMConvertFloatToHalf(_z); + w = XMConvertFloatToHalf(_w); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF4::_XMHALF4 +( + CONST FLOAT* pArray +) +{ + XMConvertFloatToHalfStream(&x, sizeof(HALF), pArray, sizeof(FLOAT), 4); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMHALF4& _XMHALF4::operator= +( + CONST _XMHALF4& Half4 +) +{ + x = Half4.x; + y = Half4.y; + z = Half4.z; + w = Half4.w; + return *this; +} + +/**************************************************************************** + * + * XMSHORTN4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN4::_XMSHORTN4 +( + CONST SHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN4::_XMSHORTN4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreShortN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN4::_XMSHORTN4 +( + CONST FLOAT* pArray +) +{ + XMStoreShortN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORTN4& _XMSHORTN4::operator= +( + CONST _XMSHORTN4& ShortN4 +) +{ + x = ShortN4.x; + y = ShortN4.y; + z = ShortN4.z; + w = ShortN4.w; + return *this; +} + +/**************************************************************************** + * + * XMSHORT4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT4::_XMSHORT4 +( + CONST SHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT4::_XMSHORT4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreShort4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT4::_XMSHORT4 +( + CONST FLOAT* pArray +) +{ + XMStoreShort4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMSHORT4& _XMSHORT4::operator= +( + CONST _XMSHORT4& Short4 +) +{ + x = Short4.x; + y = Short4.y; + z = Short4.z; + w = Short4.w; + return *this; +} + +/**************************************************************************** + * + * XMUSHORTN4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN4::_XMUSHORTN4 +( + CONST USHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN4::_XMUSHORTN4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUShortN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN4::_XMUSHORTN4 +( + CONST FLOAT* pArray +) +{ + XMStoreUShortN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORTN4& _XMUSHORTN4::operator= +( + CONST _XMUSHORTN4& UShortN4 +) +{ + x = UShortN4.x; + y = UShortN4.y; + z = UShortN4.z; + w = UShortN4.w; + return *this; +} + +/**************************************************************************** + * + * XMUSHORT4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT4::_XMUSHORT4 +( + CONST USHORT* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT4::_XMUSHORT4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUShort4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT4::_XMUSHORT4 +( + CONST FLOAT* pArray +) +{ + XMStoreUShort4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUSHORT4& _XMUSHORT4::operator= +( + CONST _XMUSHORT4& UShort4 +) +{ + x = UShort4.x; + y = UShort4.y; + z = UShort4.z; + w = UShort4.w; + return *this; +} + +/**************************************************************************** + * + * XMXDECN4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDECN4::_XMXDECN4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreXDecN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDECN4::_XMXDECN4 +( + CONST FLOAT* pArray +) +{ + XMStoreXDecN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDECN4& _XMXDECN4::operator= +( + CONST _XMXDECN4& XDecN4 +) +{ + v = XDecN4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDECN4& _XMXDECN4::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMXDEC4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDEC4::_XMXDEC4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreXDec4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDEC4::_XMXDEC4 +( + CONST FLOAT* pArray +) +{ + XMStoreXDec4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDEC4& _XMXDEC4::operator= +( + CONST _XMXDEC4& XDec4 +) +{ + v = XDec4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXDEC4& _XMXDEC4::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMDECN4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDECN4::_XMDECN4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreDecN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDECN4::_XMDECN4 +( + CONST FLOAT* pArray +) +{ + XMStoreDecN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDECN4& _XMDECN4::operator= +( + CONST _XMDECN4& DecN4 +) +{ + v = DecN4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDECN4& _XMDECN4::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMDEC4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDEC4::_XMDEC4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreDec4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDEC4::_XMDEC4 +( + CONST FLOAT* pArray +) +{ + XMStoreDec4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDEC4& _XMDEC4::operator= +( + CONST _XMDEC4& Dec4 +) +{ + v = Dec4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMDEC4& _XMDEC4::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUDECN4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDECN4::_XMUDECN4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUDecN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDECN4::_XMUDECN4 +( + CONST FLOAT* pArray +) +{ + XMStoreUDecN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDECN4& _XMUDECN4::operator= +( + CONST _XMUDECN4& UDecN4 +) +{ + v = UDecN4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDECN4& _XMUDECN4::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUDEC4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDEC4::_XMUDEC4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUDec4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDEC4::_XMUDEC4 +( + CONST FLOAT* pArray +) +{ + XMStoreUDec4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDEC4& _XMUDEC4::operator= +( + CONST _XMUDEC4& UDec4 +) +{ + v = UDec4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUDEC4& _XMUDEC4::operator= +( + CONST UINT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMXICON4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICON4::_XMXICON4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreXIcoN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICON4::_XMXICON4 +( + CONST FLOAT* pArray +) +{ + XMStoreXIcoN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICON4& _XMXICON4::operator= +( + CONST _XMXICON4& XIcoN4 +) +{ + v = XIcoN4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICON4& _XMXICON4::operator= +( + CONST UINT64 Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMXICO4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICO4::_XMXICO4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreXIco4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICO4::_XMXICO4 +( + CONST FLOAT* pArray +) +{ + XMStoreXIco4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICO4& _XMXICO4::operator= +( + CONST _XMXICO4& XIco4 +) +{ + v = XIco4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMXICO4& _XMXICO4::operator= +( + CONST UINT64 Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMICON4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICON4::_XMICON4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreIcoN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICON4::_XMICON4 +( + CONST FLOAT* pArray +) +{ + XMStoreIcoN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICON4& _XMICON4::operator= +( + CONST _XMICON4& IcoN4 +) +{ + v = IcoN4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICON4& _XMICON4::operator= +( + CONST UINT64 Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMICO4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICO4::_XMICO4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreIco4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICO4::_XMICO4 +( + CONST FLOAT* pArray +) +{ + XMStoreIco4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICO4& _XMICO4::operator= +( + CONST _XMICO4& Ico4 +) +{ + v = Ico4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMICO4& _XMICO4::operator= +( + CONST UINT64 Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUICON4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICON4::_XMUICON4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUIcoN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICON4::_XMUICON4 +( + CONST FLOAT* pArray +) +{ + XMStoreUIcoN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICON4& _XMUICON4::operator= +( + CONST _XMUICON4& UIcoN4 +) +{ + v = UIcoN4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICON4& _XMUICON4::operator= +( + CONST UINT64 Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMUICO4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICO4::_XMUICO4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUIco4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICO4::_XMUICO4 +( + CONST FLOAT* pArray +) +{ + XMStoreUIco4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICO4& _XMUICO4::operator= +( + CONST _XMUICO4& UIco4 +) +{ + v = UIco4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUICO4& _XMUICO4::operator= +( + CONST UINT64 Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMCOLOR4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMCOLOR::_XMCOLOR +( + FLOAT _r, + FLOAT _g, + FLOAT _b, + FLOAT _a +) +{ + XMStoreColor(this, XMVectorSet(_r, _g, _b, _a)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMCOLOR::_XMCOLOR +( + CONST FLOAT* pArray +) +{ + XMStoreColor(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMCOLOR& _XMCOLOR::operator= +( + CONST _XMCOLOR& Color +) +{ + c = Color.c; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMCOLOR& _XMCOLOR::operator= +( + CONST UINT Color +) +{ + c = Color; + return *this; +} + +/**************************************************************************** + * + * XMBYTEN4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTEN4::_XMBYTEN4 +( + CONST CHAR* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTEN4::_XMBYTEN4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreByteN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTEN4::_XMBYTEN4 +( + CONST FLOAT* pArray +) +{ + XMStoreByteN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTEN4& _XMBYTEN4::operator= +( + CONST _XMBYTEN4& ByteN4 +) +{ + x = ByteN4.x; + y = ByteN4.y; + z = ByteN4.z; + w = ByteN4.w; + return *this; +} + +/**************************************************************************** + * + * XMBYTE4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTE4::_XMBYTE4 +( + CONST CHAR* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTE4::_XMBYTE4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreByte4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTE4::_XMBYTE4 +( + CONST FLOAT* pArray +) +{ + XMStoreByte4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMBYTE4& _XMBYTE4::operator= +( + CONST _XMBYTE4& Byte4 +) +{ + x = Byte4.x; + y = Byte4.y; + z = Byte4.z; + w = Byte4.w; + return *this; +} + +/**************************************************************************** + * + * XMUBYTEN4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTEN4::_XMUBYTEN4 +( + CONST BYTE* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTEN4::_XMUBYTEN4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUByteN4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTEN4::_XMUBYTEN4 +( + CONST FLOAT* pArray +) +{ + XMStoreUByteN4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTEN4& _XMUBYTEN4::operator= +( + CONST _XMUBYTEN4& UByteN4 +) +{ + x = UByteN4.x; + y = UByteN4.y; + z = UByteN4.z; + w = UByteN4.w; + return *this; +} + +/**************************************************************************** + * + * XMUBYTE4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTE4::_XMUBYTE4 +( + CONST BYTE* pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTE4::_XMUBYTE4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUByte4(this, XMVectorSet(_x, _y, _z, _w)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTE4::_XMUBYTE4 +( + CONST FLOAT* pArray +) +{ + XMStoreUByte4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUBYTE4& _XMUBYTE4::operator= +( + CONST _XMUBYTE4& UByte4 +) +{ + x = UByte4.x; + y = UByte4.y; + z = UByte4.z; + w = UByte4.w; + return *this; +} + +/**************************************************************************** + * + * XMUNIBBLE4 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUNIBBLE4::_XMUNIBBLE4 +( + CONST CHAR *pArray +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = pArray[3]; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUNIBBLE4::_XMUNIBBLE4 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + FLOAT _w +) +{ + XMStoreUNibble4(this, XMVectorSet( _x, _y, _z, _w )); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUNIBBLE4::_XMUNIBBLE4 +( + CONST FLOAT *pArray +) +{ + XMStoreUNibble4(this, XMLoadFloat4((XMFLOAT4*)pArray)); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUNIBBLE4& _XMUNIBBLE4::operator= +( + CONST _XMUNIBBLE4& UNibble4 +) +{ + v = UNibble4.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMUNIBBLE4& _XMUNIBBLE4::operator= +( + CONST USHORT Packed +) +{ + v = Packed; + return *this; +} + +/**************************************************************************** + * + * XMU555 operators + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ + +XMFINLINE _XMU555::_XMU555 +( + CONST CHAR *pArray, + BOOL _w +) +{ + x = pArray[0]; + y = pArray[1]; + z = pArray[2]; + w = _w; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMU555::_XMU555 +( + FLOAT _x, + FLOAT _y, + FLOAT _z, + BOOL _w +) +{ + XMStoreU555(this, XMVectorSet(_x, _y, _z, ((_w) ? 1.0f : 0.0f) )); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMU555::_XMU555 +( + CONST FLOAT *pArray, + BOOL _w +) +{ + XMVECTOR V = XMLoadFloat3((XMFLOAT3*)pArray); + XMStoreU555(this, XMVectorSetW(V, ((_w) ? 1.0f : 0.0f) )); +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMU555& _XMU555::operator= +( + CONST _XMU555& U555 +) +{ + v = U555.v; + return *this; +} + +//------------------------------------------------------------------------------ + +XMFINLINE _XMU555& _XMU555::operator= +( + CONST USHORT Packed +) +{ + v = Packed; + return *this; +} + +#endif // __cplusplus + +#if defined(_XM_NO_INTRINSICS_) +#undef XMISNAN +#undef XMISINF +#endif + +#endif // __XNAMATHVECTOR_INL__ + diff --git a/dxsdk/Lib/x64/D3DCSX.lib b/dxsdk/Lib/x64/D3DCSX.lib new file mode 100644 index 0000000..8e2f059 Binary files /dev/null and b/dxsdk/Lib/x64/D3DCSX.lib differ diff --git a/dxsdk/Lib/x64/D3DCSXd.lib b/dxsdk/Lib/x64/D3DCSXd.lib new file mode 100644 index 0000000..6735a4d Binary files /dev/null and b/dxsdk/Lib/x64/D3DCSXd.lib differ diff --git a/dxsdk/Lib/x64/DxErr.lib b/dxsdk/Lib/x64/DxErr.lib new file mode 100644 index 0000000..a4fb226 Binary files /dev/null and b/dxsdk/Lib/x64/DxErr.lib differ diff --git a/dxsdk/Lib/x64/X3DAudio.lib b/dxsdk/Lib/x64/X3DAudio.lib new file mode 100644 index 0000000..3f73021 Binary files /dev/null and b/dxsdk/Lib/x64/X3DAudio.lib differ diff --git a/dxsdk/Lib/x64/XAPOFX.lib b/dxsdk/Lib/x64/XAPOFX.lib new file mode 100644 index 0000000..02a6525 Binary files /dev/null and b/dxsdk/Lib/x64/XAPOFX.lib differ diff --git a/dxsdk/Lib/x64/XInput.lib b/dxsdk/Lib/x64/XInput.lib new file mode 100644 index 0000000..5545d28 Binary files /dev/null and b/dxsdk/Lib/x64/XInput.lib differ diff --git a/dxsdk/Lib/x64/d2d1.lib b/dxsdk/Lib/x64/d2d1.lib new file mode 100644 index 0000000..505e6d7 Binary files /dev/null and b/dxsdk/Lib/x64/d2d1.lib differ diff --git a/dxsdk/Lib/x64/d3d10.lib b/dxsdk/Lib/x64/d3d10.lib new file mode 100644 index 0000000..2b08450 Binary files /dev/null and b/dxsdk/Lib/x64/d3d10.lib differ diff --git a/dxsdk/Lib/x64/d3d10_1.lib b/dxsdk/Lib/x64/d3d10_1.lib new file mode 100644 index 0000000..4b2ef62 Binary files /dev/null and b/dxsdk/Lib/x64/d3d10_1.lib differ diff --git a/dxsdk/Lib/x64/d3d11.lib b/dxsdk/Lib/x64/d3d11.lib new file mode 100644 index 0000000..441d85b Binary files /dev/null and b/dxsdk/Lib/x64/d3d11.lib differ diff --git a/dxsdk/Lib/x64/d3d9.lib b/dxsdk/Lib/x64/d3d9.lib new file mode 100644 index 0000000..62b3f75 Binary files /dev/null and b/dxsdk/Lib/x64/d3d9.lib differ diff --git a/dxsdk/Lib/x64/d3dcompiler.lib b/dxsdk/Lib/x64/d3dcompiler.lib new file mode 100644 index 0000000..15c8301 Binary files /dev/null and b/dxsdk/Lib/x64/d3dcompiler.lib differ diff --git a/dxsdk/Lib/x64/d3dx10.lib b/dxsdk/Lib/x64/d3dx10.lib new file mode 100644 index 0000000..cfd7b9f Binary files /dev/null and b/dxsdk/Lib/x64/d3dx10.lib differ diff --git a/dxsdk/Lib/x64/d3dx10d.lib b/dxsdk/Lib/x64/d3dx10d.lib new file mode 100644 index 0000000..c4b45a7 Binary files /dev/null and b/dxsdk/Lib/x64/d3dx10d.lib differ diff --git a/dxsdk/Lib/x64/d3dx11.lib b/dxsdk/Lib/x64/d3dx11.lib new file mode 100644 index 0000000..92a666f Binary files /dev/null and b/dxsdk/Lib/x64/d3dx11.lib differ diff --git a/dxsdk/Lib/x64/d3dx11d.lib b/dxsdk/Lib/x64/d3dx11d.lib new file mode 100644 index 0000000..2b116fe Binary files /dev/null and b/dxsdk/Lib/x64/d3dx11d.lib differ diff --git a/dxsdk/Lib/x64/d3dx9.lib b/dxsdk/Lib/x64/d3dx9.lib new file mode 100644 index 0000000..8587d5b Binary files /dev/null and b/dxsdk/Lib/x64/d3dx9.lib differ diff --git a/dxsdk/Lib/x64/d3dx9d.lib b/dxsdk/Lib/x64/d3dx9d.lib new file mode 100644 index 0000000..2f3ebf7 Binary files /dev/null and b/dxsdk/Lib/x64/d3dx9d.lib differ diff --git a/dxsdk/Lib/x64/d3dxof.lib b/dxsdk/Lib/x64/d3dxof.lib new file mode 100644 index 0000000..66dbd30 Binary files /dev/null and b/dxsdk/Lib/x64/d3dxof.lib differ diff --git a/dxsdk/Lib/x64/dinput8.lib b/dxsdk/Lib/x64/dinput8.lib new file mode 100644 index 0000000..fcd91e1 Binary files /dev/null and b/dxsdk/Lib/x64/dinput8.lib differ diff --git a/dxsdk/Lib/x64/dsound.lib b/dxsdk/Lib/x64/dsound.lib new file mode 100644 index 0000000..a85fc86 Binary files /dev/null and b/dxsdk/Lib/x64/dsound.lib differ diff --git a/dxsdk/Lib/x64/dwrite.lib b/dxsdk/Lib/x64/dwrite.lib new file mode 100644 index 0000000..15416c6 Binary files /dev/null and b/dxsdk/Lib/x64/dwrite.lib differ diff --git a/dxsdk/Lib/x64/dxgi.lib b/dxsdk/Lib/x64/dxgi.lib new file mode 100644 index 0000000..83639be Binary files /dev/null and b/dxsdk/Lib/x64/dxgi.lib differ diff --git a/dxsdk/Lib/x64/dxguid.lib b/dxsdk/Lib/x64/dxguid.lib new file mode 100644 index 0000000..f3994f9 Binary files /dev/null and b/dxsdk/Lib/x64/dxguid.lib differ diff --git a/dxsdk/Lib/x64/xapobase.lib b/dxsdk/Lib/x64/xapobase.lib new file mode 100644 index 0000000..9a1bbcb Binary files /dev/null and b/dxsdk/Lib/x64/xapobase.lib differ diff --git a/dxsdk/Lib/x64/xapobased.lib b/dxsdk/Lib/x64/xapobased.lib new file mode 100644 index 0000000..63fd474 Binary files /dev/null and b/dxsdk/Lib/x64/xapobased.lib differ diff --git a/dxsdk/Lib/x86/D3DCSX.lib b/dxsdk/Lib/x86/D3DCSX.lib new file mode 100644 index 0000000..fd2c502 Binary files /dev/null and b/dxsdk/Lib/x86/D3DCSX.lib differ diff --git a/dxsdk/Lib/x86/D3DCSXd.lib b/dxsdk/Lib/x86/D3DCSXd.lib new file mode 100644 index 0000000..f637815 Binary files /dev/null and b/dxsdk/Lib/x86/D3DCSXd.lib differ diff --git a/dxsdk/Lib/x86/DxErr.lib b/dxsdk/Lib/x86/DxErr.lib new file mode 100644 index 0000000..8c7651e Binary files /dev/null and b/dxsdk/Lib/x86/DxErr.lib differ diff --git a/dxsdk/Lib/x86/X3DAudio.lib b/dxsdk/Lib/x86/X3DAudio.lib new file mode 100644 index 0000000..ffef84d Binary files /dev/null and b/dxsdk/Lib/x86/X3DAudio.lib differ diff --git a/dxsdk/Lib/x86/XAPOFX.lib b/dxsdk/Lib/x86/XAPOFX.lib new file mode 100644 index 0000000..53a5f0c Binary files /dev/null and b/dxsdk/Lib/x86/XAPOFX.lib differ diff --git a/dxsdk/Lib/x86/XInput.lib b/dxsdk/Lib/x86/XInput.lib new file mode 100644 index 0000000..4d3bd7c Binary files /dev/null and b/dxsdk/Lib/x86/XInput.lib differ diff --git a/dxsdk/Lib/x86/d2d1.lib b/dxsdk/Lib/x86/d2d1.lib new file mode 100644 index 0000000..751c67f Binary files /dev/null and b/dxsdk/Lib/x86/d2d1.lib differ diff --git a/dxsdk/Lib/x86/d3d10.lib b/dxsdk/Lib/x86/d3d10.lib new file mode 100644 index 0000000..df8ed19 Binary files /dev/null and b/dxsdk/Lib/x86/d3d10.lib differ diff --git a/dxsdk/Lib/x86/d3d10_1.lib b/dxsdk/Lib/x86/d3d10_1.lib new file mode 100644 index 0000000..80645d6 Binary files /dev/null and b/dxsdk/Lib/x86/d3d10_1.lib differ diff --git a/dxsdk/Lib/x86/d3d11.lib b/dxsdk/Lib/x86/d3d11.lib new file mode 100644 index 0000000..9200898 Binary files /dev/null and b/dxsdk/Lib/x86/d3d11.lib differ diff --git a/dxsdk/Lib/x86/d3d9.lib b/dxsdk/Lib/x86/d3d9.lib new file mode 100644 index 0000000..f6eddc6 Binary files /dev/null and b/dxsdk/Lib/x86/d3d9.lib differ diff --git a/dxsdk/Lib/x86/d3dcompiler.lib b/dxsdk/Lib/x86/d3dcompiler.lib new file mode 100644 index 0000000..36cc5d4 Binary files /dev/null and b/dxsdk/Lib/x86/d3dcompiler.lib differ diff --git a/dxsdk/Lib/x86/d3dx10.lib b/dxsdk/Lib/x86/d3dx10.lib new file mode 100644 index 0000000..a397032 Binary files /dev/null and b/dxsdk/Lib/x86/d3dx10.lib differ diff --git a/dxsdk/Lib/x86/d3dx10d.lib b/dxsdk/Lib/x86/d3dx10d.lib new file mode 100644 index 0000000..5c28adf Binary files /dev/null and b/dxsdk/Lib/x86/d3dx10d.lib differ diff --git a/dxsdk/Lib/x86/d3dx11.lib b/dxsdk/Lib/x86/d3dx11.lib new file mode 100644 index 0000000..904d157 Binary files /dev/null and b/dxsdk/Lib/x86/d3dx11.lib differ diff --git a/dxsdk/Lib/x86/d3dx11d.lib b/dxsdk/Lib/x86/d3dx11d.lib new file mode 100644 index 0000000..c1c756a Binary files /dev/null and b/dxsdk/Lib/x86/d3dx11d.lib differ diff --git a/dxsdk/Lib/x86/d3dx9.lib b/dxsdk/Lib/x86/d3dx9.lib new file mode 100644 index 0000000..11853bf Binary files /dev/null and b/dxsdk/Lib/x86/d3dx9.lib differ diff --git a/dxsdk/Lib/x86/d3dx9d.lib b/dxsdk/Lib/x86/d3dx9d.lib new file mode 100644 index 0000000..15ed743 Binary files /dev/null and b/dxsdk/Lib/x86/d3dx9d.lib differ diff --git a/dxsdk/Lib/x86/d3dxof.lib b/dxsdk/Lib/x86/d3dxof.lib new file mode 100644 index 0000000..bf3cde4 Binary files /dev/null and b/dxsdk/Lib/x86/d3dxof.lib differ diff --git a/dxsdk/Lib/x86/dinput8.lib b/dxsdk/Lib/x86/dinput8.lib new file mode 100644 index 0000000..c870a09 Binary files /dev/null and b/dxsdk/Lib/x86/dinput8.lib differ diff --git a/dxsdk/Lib/x86/dsetup.lib b/dxsdk/Lib/x86/dsetup.lib new file mode 100644 index 0000000..a3cfdc7 Binary files /dev/null and b/dxsdk/Lib/x86/dsetup.lib differ diff --git a/dxsdk/Lib/x86/dsound.lib b/dxsdk/Lib/x86/dsound.lib new file mode 100644 index 0000000..c07fe85 Binary files /dev/null and b/dxsdk/Lib/x86/dsound.lib differ diff --git a/dxsdk/Lib/x86/dwrite.lib b/dxsdk/Lib/x86/dwrite.lib new file mode 100644 index 0000000..aa13636 Binary files /dev/null and b/dxsdk/Lib/x86/dwrite.lib differ diff --git a/dxsdk/Lib/x86/dxgi.lib b/dxsdk/Lib/x86/dxgi.lib new file mode 100644 index 0000000..011c928 Binary files /dev/null and b/dxsdk/Lib/x86/dxgi.lib differ diff --git a/dxsdk/Lib/x86/dxguid.lib b/dxsdk/Lib/x86/dxguid.lib new file mode 100644 index 0000000..82835ab Binary files /dev/null and b/dxsdk/Lib/x86/dxguid.lib differ diff --git a/dxsdk/Lib/x86/xapobase.lib b/dxsdk/Lib/x86/xapobase.lib new file mode 100644 index 0000000..531c06b Binary files /dev/null and b/dxsdk/Lib/x86/xapobase.lib differ diff --git a/dxsdk/Lib/x86/xapobased.lib b/dxsdk/Lib/x86/xapobased.lib new file mode 100644 index 0000000..900734f Binary files /dev/null and b/dxsdk/Lib/x86/xapobased.lib differ diff --git a/objconv.exe b/objconv.exe new file mode 100644 index 0000000..561c0db Binary files /dev/null and b/objconv.exe differ